Skip to content

Commit

Permalink
Implement scrollbar thumb scaling
Browse files Browse the repository at this point in the history
Affects: #14
Affects: #13
  • Loading branch information
io7m committed Nov 25, 2023
1 parent ef2f5f5 commit 8110cca
Show file tree
Hide file tree
Showing 15 changed files with 291 additions and 66 deletions.
Expand Up @@ -26,6 +26,7 @@
import com.io7m.jsycamore.api.visibility.SyVisibleReadableType;
import com.io7m.jsycamore.api.windows.SyWindowReadableType;
import com.io7m.jtensors.core.parameterized.vectors.PVector2I;
import com.io7m.jtensors.core.parameterized.vectors.PVectors2I;

import java.util.Objects;
import java.util.Optional;
Expand Down Expand Up @@ -184,4 +185,27 @@ default PVector2I<SySpaceViewportType> viewportPositionOf(
windowPosition.y() + y
);
}

/**
* Determine the parent-relative position of the given viewport position
* for component. The method will fail if this component is not attached to
* a window.
*
* @param position The source position
*
* @return The viewport position
*/

default PVector2I<SySpaceParentRelativeType> relativePositionOf(
final PVector2I<SySpaceViewportType> position)
{
Objects.requireNonNull(position, "position");

final var base =
this.viewportPositionOf(PVectors2I.zero());
final var delta =
PVectors2I.subtract(position, base);

return PVector2I.of(delta.x(), delta.y());
}
}
Expand Up @@ -72,36 +72,4 @@ public interface SyScrollBarHorizontalType
*/

void removeOnThumbDragListener();

/**
* Set the scroll position in the range {@code [0, 1]}.
*
* @param position The position
*/

void setScrollPosition(double position);

/**
* Set the scroll position snapping value in the range {@code [0, 1]}. The
* given fraction is used to determine how many divisions will be used within
* the scrolling space. For example, a value of {@code 1.0 / 4.0} will yield
* four possible snapped position values.
*
* @param fraction The fraction
*/

void setScrollPositionSnapping(double fraction);

/**
* Scrollbars are typically used to scroll a visible portion of some larger
* structure. Some implementations might want to scale the scrollbar thumb
* based on the portion of the visible space that is visible. A value of
* {@code 0.0} means that an infinitely small piece of the larger structure
* is visible. A value of {@code 1.0} means that the entirety of the larger
* structure is visible.
*
* @param amount The amount shown
*/

void setScrollAmountShown(double amount);
}
@@ -0,0 +1,39 @@
/*
* Copyright © 2023 Mark Raynsford <code@io7m.com> https://www.io7m.com
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/


package com.io7m.jsycamore.api.components;

/**
* The presence policy for scrollbars.
*/

public enum SyScrollBarPresencePolicy
{
/**
* The scrollbar should always be present and enabled.
*/

ALWAYS_ENABLED,

/**
* The scrollbar is disabled if the entire range is shown.
*
* @see SyScrollBarType#setScrollAmountShown(double)
*/

DISABLED_IF_ENTIRE_RANGE_SHOWN
}
Expand Up @@ -16,6 +16,8 @@

package com.io7m.jsycamore.api.components;

import com.io7m.jattribute.core.AttributeReadableType;

/**
* Read-only access to scrollbars.
*/
Expand All @@ -30,7 +32,6 @@ public interface SyScrollBarReadableType
SyComponentReadableType thumb();

/**
*
* @return The scrollbar track
*/

Expand All @@ -47,4 +48,10 @@ public interface SyScrollBarReadableType
*/

double scrollPositionSnapping();

/**
* @return The scrollbar presence policy
*/

AttributeReadableType<SyScrollBarPresencePolicy> presencePolicy();
}
Expand Up @@ -16,12 +16,47 @@

package com.io7m.jsycamore.api.components;

import com.io7m.jattribute.core.AttributeType;

/**
* Write access to scrollbars.
*/

public interface SyScrollBarType
extends SyScrollBarReadableType, SyComponentType
{
@Override
AttributeType<SyScrollBarPresencePolicy> presencePolicy();

/**
* Set the scroll position in the range {@code [0, 1]}.
*
* @param position The position
*/

void setScrollPosition(double position);

/**
* Set the scroll position snapping value in the range {@code [0, 1]}. The
* given fraction is used to determine how many divisions will be used within
* the scrolling space. For example, a value of {@code 1.0 / 4.0} will yield
* four possible snapped position values.
*
* @param fraction The fraction
*/

void setScrollPositionSnapping(double fraction);

/**
* Scrollbars are typically used to scroll a visible portion of some larger
* structure. Some implementations might want to scale the scrollbar thumb
* based on the portion of the visible space that is visible. A value of
* {@code 0.0} means that an infinitely small piece of the larger structure
* is visible. A value of {@code 1.0} means that the entirety of the larger
* structure is visible.
*
* @param amount The amount shown
*/

void setScrollAmountShown(double amount);
}
4 changes: 4 additions & 0 deletions com.io7m.jsycamore.components.standard/pom.xml
Expand Up @@ -24,6 +24,10 @@
<version>${project.version}</version>
</dependency>

<dependency>
<groupId>com.io7m.jinterp</groupId>
<artifactId>com.io7m.jinterp.core</artifactId>
</dependency>
<dependency>
<groupId>com.io7m.jaffirm</groupId>
<artifactId>com.io7m.jaffirm.core</artifactId>
Expand Down
Expand Up @@ -236,21 +236,24 @@ public PAreaSizeI<SySpaceParentRelativeType> layout(
protected SyEventConsumed onEvent(
final SyEventType event)
{
if (event instanceof SyMouseEventOnPressed) {
this.menuBar.menuChangeSelection(this);
return EVENT_CONSUMED;
}

if (event instanceof SyMouseEventOnOver) {
if (this.menuBar.menuAnySelected()) {
if (!this.menuBar.menuIsSelected(this)) {
this.menuBar.menuChangeSelection(this);
return EVENT_CONSUMED;
return switch (event) {
case final SyMouseEventOnPressed e -> {
this.menuBar.menuChangeSelection(this);
yield EVENT_CONSUMED;
}
case final SyMouseEventOnOver e -> {
if (this.menuBar.menuAnySelected()) {
if (!this.menuBar.menuIsSelected(this)) {
this.menuBar.menuChangeSelection(this);
yield EVENT_CONSUMED;
}
}
yield EVENT_NOT_CONSUMED;
}
}

return EVENT_NOT_CONSUMED;
default -> {
yield EVENT_NOT_CONSUMED;
}
};
}

@Override
Expand Down
Expand Up @@ -19,7 +19,7 @@

import com.io7m.jsycamore.api.components.SyScrollBarHorizontalType;
import com.io7m.jsycamore.api.themes.SyThemeClassNameType;
import com.io7m.jsycamore.components.standard.internal.scrollbars.SyScrollBarHorizontalBasic;
import com.io7m.jsycamore.components.standard.internal.scrollbars.SyScrollBarH;

import java.util.List;

Expand All @@ -45,7 +45,7 @@ private SyScrollBarsHorizontal()
public static SyScrollBarHorizontalType create(
final List<SyThemeClassNameType> themeClassesExtra)
{
return new SyScrollBarHorizontalBasic(themeClassesExtra);
return new SyScrollBarH(themeClassesExtra);
}

/**
Expand Down
Expand Up @@ -17,31 +17,37 @@

package com.io7m.jsycamore.components.standard.internal.scrollbars;

import com.io7m.jattribute.core.AttributeType;
import com.io7m.jregions.core.parameterized.areas.PAreasI;
import com.io7m.jregions.core.parameterized.sizes.PAreaSizeI;
import com.io7m.jsycamore.api.components.SyButtonReadableType;
import com.io7m.jsycamore.api.components.SyComponentReadableType;
import com.io7m.jsycamore.api.components.SyConstraints;
import com.io7m.jsycamore.api.components.SyScrollBarDrag;
import com.io7m.jsycamore.api.components.SyScrollBarHorizontalType;
import com.io7m.jsycamore.api.components.SyScrollBarPresencePolicy;
import com.io7m.jsycamore.api.events.SyEventConsumed;
import com.io7m.jsycamore.api.events.SyEventType;
import com.io7m.jsycamore.api.layout.SyLayoutContextType;
import com.io7m.jsycamore.api.spaces.SySpaceParentRelativeType;
import com.io7m.jsycamore.api.themes.SyThemeClassNameType;
import com.io7m.jsycamore.components.standard.SyComponentAbstract;
import com.io7m.jsycamore.components.standard.SyComponentAttributes;
import com.io7m.jtensors.core.parameterized.vectors.PVector2I;

import java.util.List;
import java.util.function.Consumer;

import static com.io7m.jsycamore.api.active.SyActive.ACTIVE;
import static com.io7m.jsycamore.api.active.SyActive.INACTIVE;
import static com.io7m.jsycamore.api.components.SyScrollBarPresencePolicy.DISABLED_IF_ENTIRE_RANGE_SHOWN;
import static com.io7m.jsycamore.api.events.SyEventConsumed.EVENT_NOT_CONSUMED;

/**
* A horizontal scrollbar.
*/

public final class SyScrollBarHorizontalBasic
public final class SyScrollBarH
extends SyComponentAbstract
implements SyScrollBarHorizontalType
{
Expand All @@ -51,18 +57,22 @@ public final class SyScrollBarHorizontalBasic
private final SyScrollBarHButtonLeft buttonLeft;
private final SyScrollBarHButtonRight buttonRight;
private final SyScrollBarHTrack track;
private final AttributeType<SyScrollBarPresencePolicy> presencePolicy;

/**
* A horizontal scrollbar.
*
* @param inThemeClassesExtra The extra theme classes, if any
*/

public SyScrollBarHorizontalBasic(
public SyScrollBarH(
final List<SyThemeClassNameType> inThemeClassesExtra)
{
super(inThemeClassesExtra);

this.presencePolicy =
SyComponentAttributes.get().create(DISABLED_IF_ENTIRE_RANGE_SHOWN);

this.buttonLeft =
new SyScrollBarHButtonLeft();
this.buttonRight =
Expand Down Expand Up @@ -265,6 +275,22 @@ public void setScrollAmountShown(
final double amount)
{
this.track.setScrollAmountShown(amount);

switch (this.presencePolicy.get()) {
case ALWAYS_ENABLED -> {
final var active = ACTIVE;
this.buttonLeft.setActive(active);
this.buttonRight.setActive(active);
this.track.setActive(active);
}
case DISABLED_IF_ENTIRE_RANGE_SHOWN -> {
final var active =
this.track.scrollAmountShown() >= 1.0 ? INACTIVE : ACTIVE;
this.buttonLeft.setActive(active);
this.buttonRight.setActive(active);
this.track.setActive(active);
}
}
}

@Override
Expand Down Expand Up @@ -302,4 +328,10 @@ public double scrollPositionSnapping()
{
return this.track.scrollPositionSnapping();
}

@Override
public AttributeType<SyScrollBarPresencePolicy> presencePolicy()
{
return this.presencePolicy;
}
}

0 comments on commit 8110cca

Please sign in to comment.