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.
Original file line number Diff line number Diff line change
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());
}
}
Original file line number Diff line number Diff line change
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);
}
Original file line number Diff line number Diff line change
@@ -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
}
Original file line number Diff line number Diff line change
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();
}
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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;
}
}
Loading

0 comments on commit 8110cca

Please sign in to comment.