Skip to content

Commit

Permalink
ScrollComponent: Add a limitScrollBarGripHeight option
Browse files Browse the repository at this point in the history
This will ensure that the vertical scroll bar grip is at least a
minimum height, making it easier to grab when there is a lot of
content within the ScrollComponent.
  • Loading branch information
caoimhebyrne committed Jul 12, 2024
1 parent 91c492f commit 93a8aa9
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 7 deletions.
22 changes: 19 additions & 3 deletions api/Elementa.api
Original file line number Diff line number Diff line change
Expand Up @@ -343,16 +343,18 @@ public final class gg/essential/elementa/components/ScrollComponent : gg/essenti
public fun <init> (Ljava/lang/String;)V
public fun <init> (Ljava/lang/String;F)V
public fun <init> (Ljava/lang/String;FLjava/awt/Color;)V
public fun <init> (Ljava/lang/String;FLjava/awt/Color;Lgg/essential/elementa/components/ScrollComponent$Direction;ZZFFLgg/essential/elementa/UIComponent;Z)V
public synthetic fun <init> (Ljava/lang/String;FLjava/awt/Color;Lgg/essential/elementa/components/ScrollComponent$Direction;ZZFFLgg/essential/elementa/UIComponent;ZILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun <init> (Ljava/lang/String;FLjava/awt/Color;Lgg/essential/elementa/components/ScrollComponent$Direction;ZZFFLgg/essential/elementa/UIComponent;ZZ)V
public synthetic fun <init> (Ljava/lang/String;FLjava/awt/Color;Lgg/essential/elementa/components/ScrollComponent$Direction;ZZFFLgg/essential/elementa/UIComponent;ZZILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun <init> (Ljava/lang/String;FLjava/awt/Color;Z)V
public fun <init> (Ljava/lang/String;FLjava/awt/Color;ZZ)V
public fun <init> (Ljava/lang/String;FLjava/awt/Color;ZZZ)V
public fun <init> (Ljava/lang/String;FLjava/awt/Color;ZZZZ)V
public fun <init> (Ljava/lang/String;FLjava/awt/Color;ZZZZF)V
public fun <init> (Ljava/lang/String;FLjava/awt/Color;ZZZZFF)V
public fun <init> (Ljava/lang/String;FLjava/awt/Color;ZZZZFFLgg/essential/elementa/UIComponent;)V
public synthetic fun <init> (Ljava/lang/String;FLjava/awt/Color;ZZZZFFLgg/essential/elementa/UIComponent;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun <init> (Ljava/lang/String;FLjava/awt/Color;ZZZZFFLgg/essential/elementa/UIComponent;Z)V
public fun <init> (Ljava/lang/String;FLjava/awt/Color;ZZZZFFLgg/essential/elementa/UIComponent;ZZ)V
public synthetic fun <init> (Ljava/lang/String;FLjava/awt/Color;ZZZZFFLgg/essential/elementa/UIComponent;ZZILkotlin/jvm/internal/DefaultConstructorMarker;)V
public synthetic fun addChild (Lgg/essential/elementa/UIComponent;)Lgg/essential/elementa/UIComponent;
public fun addChild (Lgg/essential/elementa/UIComponent;)Lgg/essential/elementa/components/ScrollComponent;
public final fun addScrollAdjustEvent (ZLkotlin/jvm/functions/Function2;)V
Expand Down Expand Up @@ -426,6 +428,20 @@ public final class gg/essential/elementa/components/ScrollComponent$Direction :
public static fun values ()[Lgg/essential/elementa/components/ScrollComponent$Direction;
}

public final class gg/essential/elementa/components/ScrollComponent$ScrollBarGripMinHeightConstraint : gg/essential/elementa/constraints/HeightConstraint {
public fun <init> (Lgg/essential/elementa/components/ScrollComponent;Lgg/essential/elementa/constraints/HeightConstraint;)V
public fun getCachedValue ()Ljava/lang/Float;
public synthetic fun getCachedValue ()Ljava/lang/Object;
public fun getConstrainTo ()Lgg/essential/elementa/UIComponent;
public fun getHeightImpl (Lgg/essential/elementa/UIComponent;)F
public fun getRecalculate ()Z
public fun setCachedValue (F)V
public synthetic fun setCachedValue (Ljava/lang/Object;)V
public fun setConstrainTo (Lgg/essential/elementa/UIComponent;)V
public fun setRecalculate (Z)V
public fun visitImpl (Lgg/essential/elementa/constraints/resolution/ConstraintVisitor;Lgg/essential/elementa/constraints/ConstraintType;)V
}

public final class gg/essential/elementa/components/ScrollComponent$ScrollChildConstraint : gg/essential/elementa/constraints/HeightConstraint, gg/essential/elementa/constraints/WidthConstraint {
public fun <init> (Lgg/essential/elementa/components/ScrollComponent;F)V
public synthetic fun <init> (Lgg/essential/elementa/components/ScrollComponent;FILkotlin/jvm/internal/DefaultConstructorMarker;)V
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ class ScrollComponent constructor(
private val pixelsPerScroll: Float = 15f,
private val scrollAcceleration: Float = 1.0f,
customScissorBoundingBox: UIComponent? = null,
private val passthroughScroll: Boolean = true
private val passthroughScroll: Boolean = true,
private val limitScrollBarGripHeight: Boolean = false,
) : UIContainer() {
@JvmOverloads constructor(
emptyString: String = "",
Expand All @@ -44,7 +45,9 @@ class ScrollComponent constructor(
verticalScrollOpposite: Boolean = false,
pixelsPerScroll: Float = 15f,
scrollAcceleration: Float = 1.0f,
customScissorBoundingBox: UIComponent? = null
customScissorBoundingBox: UIComponent? = null,
passthroughScroll: Boolean = true,
limitScrollBarGripHeight: Boolean = false,
) : this (
emptyString,
innerPadding,
Expand All @@ -59,7 +62,9 @@ class ScrollComponent constructor(
verticalScrollOpposite,
pixelsPerScroll,
scrollAcceleration,
customScissorBoundingBox
customScissorBoundingBox,
passthroughScroll,
limitScrollBarGripHeight,
)

private val primaryScrollDirection
Expand Down Expand Up @@ -469,7 +474,8 @@ class ScrollComponent constructor(
if (isHorizontal) {
component.setWidth(RelativeConstraint(clampedPercentage))
} else {
component.setHeight(RelativeConstraint(clampedPercentage))
val heightConstraint = RelativeConstraint(clampedPercentage)
component.setHeight(if (limitScrollBarGripHeight) ScrollBarGripMinHeightConstraint(heightConstraint) else heightConstraint)
}

component.animate {
Expand Down Expand Up @@ -800,6 +806,30 @@ class ScrollComponent constructor(

}

/**
* Constraints the scrollbar grip's height to be a certain minimum height, or the [desiredHeight].
* This is the default constraint for vertical scrollbar grips if [limitScrollBarGripHeight] is enabled.
*
* @param desiredHeight The intended height for the scrollbar grip.
*/
inner class ScrollBarGripMinHeightConstraint(
private val desiredHeight: HeightConstraint
) : HeightConstraint {
override var cachedValue: Float = 0f
override var recalculate: Boolean = true
override var constrainTo: UIComponent? = null

override fun getHeightImpl(component: UIComponent): Float {
val parent = component.parent
val minimumHeight = if (parent.getHeight() < 200) { 15.percent } else { 10.percent }
return desiredHeight.coerceAtLeast(minimumHeight).getHeight(component)
}

override fun visitImpl(visitor: ConstraintVisitor, type: ConstraintType) {
if (type == ConstraintType.HEIGHT) visitor.visitChildren(type)
}
}

enum class Direction {
Vertical,
Horizontal,
Expand Down

0 comments on commit 93a8aa9

Please sign in to comment.