Skip to content

Commit

Permalink
Initial horizontal scroll bars
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 c225d6f commit ef2f5f5
Show file tree
Hide file tree
Showing 101 changed files with 2,375 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@
import java.util.Optional;
import java.util.function.Predicate;

import static java.lang.Math.min;

/**
* The type of components.
*/
Expand Down Expand Up @@ -81,22 +79,39 @@ default PAreaSizeI<SySpaceParentRelativeType> layout(
Objects.requireNonNull(layoutContext, "layoutContext");
Objects.requireNonNull(constraints, "constraints");

/*
* First, consult the theme to see if there are size constraints specified
* for this component. Derive a new set of constraints that try to
* satisfy the theme whilst also satisfying the passed in constraints.
*/

var limitedConstraints =
layoutContext.deriveThemeConstraints(constraints, this);

/*
* Then, limit the derived constraints further by the component's size
* limit.
*/

final var sizeLimit =
this.sizeUpperLimit().get();

final var limitedConstraints =
new SyConstraints(
constraints.sizeMinimumX(),
constraints.sizeMinimumY(),
min(constraints.sizeMaximumX(), sizeLimit.sizeX()),
min(constraints.sizeMaximumY(), sizeLimit.sizeY())
);
limitedConstraints = limitedConstraints.deriveLimitedBy(sizeLimit);

/*
* Now, lay out all child components according to the derived constraints.
*/

final var childNodes = this.node().children();
for (final var childNode : childNodes) {
childNode.value().layout(layoutContext, limitedConstraints);
}

/*
* Finally, resize this component to the maximum size allowed by the
* constraints.
*/

final PAreaSizeI<SySpaceParentRelativeType> newSize =
limitedConstraints.sizeMaximum();
this.setSize(newSize);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,10 +146,10 @@ public boolean isSatisfiedBy(
{
final var xOk =
size.sizeX() >= this.sizeMinimumX
&& size.sizeX() <= this.sizeMaximumX;
&& size.sizeX() <= this.sizeMaximumX;
final var yOk =
size.sizeY() >= this.sizeMinimumY
&& size.sizeY() <= this.sizeMaximumY;
&& size.sizeY() <= this.sizeMaximumY;
return xOk && yOk;
}

Expand All @@ -166,4 +166,24 @@ public SyConstraints withoutMinimum()
this.sizeMaximumY
);
}

/**
* Derive a new set of constraints that obey the current constraints whilst
* attempting to constrain to the given size.
*
* @param size The size
*
* @return A new set of constraints
*/

public SyConstraints deriveLimitedBy(
final PAreaSizeI<?> size)
{
return new SyConstraints(
this.sizeMinimumX(),
this.sizeMinimumY(),
min(this.sizeMaximumX(), size.sizeX()),
min(this.sizeMaximumY(), size.sizeY())
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,28 @@ public interface SyImageViewType

@Override
AttributeType<Optional<URI>> imageURI();

/**
* A convenience method to set the image URI.
*
* @param uri The image URI
*/

default void setImageURI(
final URI uri)
{
this.imageURI().set(Optional.of(uri));
}

/**
* A convenience method to set the image URI.
*
* @param uri The image URI
*/

default void setImageURI(
final String uri)
{
this.setImageURI(URI.create(uri));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* Copyright © 2023 Mark Raynsford <[email protected]> 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;

import java.util.Objects;

import static java.lang.StrictMath.clamp;

/**
* A drag operation being performed on a scrollbar.
*
* @param dragKind The kind of operation
* @param dragStart The scroll position at the start of the operation
* @param dragNow The scroll position now
*/

public record SyScrollBarDrag(
Kind dragKind,
double dragStart,
double dragNow)
{
/**
* The kind of drag operation.
*/

public enum Kind
{
/**
* Dragging just started.
*/

DRAG_STARTED,

/**
* Dragging is being continued.
*/

DRAG_CONTINUED,

/**
* Dragging just ended.
*/

DRAG_ENDED
}

/**
* A drag operation being performed on a scrollbar.
*
* @param dragKind The kind of operation
* @param dragStart The scroll position at the start of the operation
* @param dragNow The scroll position now
*/

public SyScrollBarDrag
{
Objects.requireNonNull(dragKind, "dragKind");

dragStart = clamp(dragStart, 0.0, 1.0);
dragNow = clamp(dragNow, 0.0, 1.0);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,30 @@

import java.util.List;

import static com.io7m.jsycamore.api.themes.SyThemeClassNameStandard.SCROLLBAR;
import static com.io7m.jsycamore.api.themes.SyThemeClassNameStandard.SCROLLBAR_HORIZONTAL;

/**
* Read-only access to scrollbars.
*/

public interface SyScrollbarReadableType
extends SyComponentReadableType
public interface SyScrollBarHorizontalReadableType
extends SyScrollBarReadableType
{
@Override
default List<SyThemeClassNameType> themeClassesDefaultForComponent()
{
return List.of(SCROLLBAR);
return List.of(SCROLLBAR_HORIZONTAL);
}

/**
* @return The scrollbar left button
*/

SyButtonReadableType buttonLeft();

/**
* @return The scrollbar right button
*/

SyButtonReadableType buttonRight();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/*
* Copyright © 2021 Mark Raynsford <[email protected]> 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;

import java.util.function.Consumer;

/**
* Write access to scrollbars.
*/

public interface SyScrollBarHorizontalType
extends SyScrollBarHorizontalReadableType, SyScrollBarType
{
/**
* Set a listener that will be executed when the left scroll button is clicked.
*
* @param runnable The listener
*/

void setOnClickLeftListener(Runnable runnable);

/**
* Remove any listeners that are executed when the left button is clicked.
*
* @see #setOnClickLeftListener(Runnable)
*/

void removeOnClickLeftListener();

/**
* Set a listener that will be executed when the right scroll button is clicked.
*
* @param runnable The listener
*/

void setOnClickRightListener(Runnable runnable);

/**
* Remove any listeners that are executed when the right button is clicked.
*
* @see #setOnClickRightListener(Runnable)
*/

void removeOnClickRightListener();

/**
* Set a listener that will be executed when the left scroll button is clicked.
*
* @param listener The listener
*/

void setOnThumbDragListener(Consumer<SyScrollBarDrag> listener);

/**
* Remove any listeners that are executed when the left button is clicked.
*
* @see #setOnThumbDragListener(Consumer)
*/

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,50 @@
/*
* Copyright © 2021 Mark Raynsford <[email protected]> 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;

/**
* Read-only access to scrollbars.
*/

public interface SyScrollBarReadableType
extends SyComponentReadableType
{
/**
* @return The scrollbar thumb
*/

SyComponentReadableType thumb();

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

SyComponentReadableType track();

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

double scrollPosition();

/**
* @return The scroll position snapping value in the range {@code [0, 1]}
*/

double scrollPositionSnapping();
}
Loading

0 comments on commit ef2f5f5

Please sign in to comment.