Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add scroll widgets #157

Merged
merged 3 commits into from
Jan 30, 2025
Merged

Add scroll widgets #157

merged 3 commits into from
Jan 30, 2025

Conversation

reykjalin
Copy link
Contributor

Description

  • Adds a ScrollView widget to vxfw.
  • Adds a ScrollBars widget to vxfw.
  • Adds a scroll example to demonstrate usage.

Known Issues

  1. The view currently does not enforce a maximum width on the content to be able to correctly figure out whether the content can still be scrolled horizontally. This will cause the widget to draw beyond its boundaries horizontally.
  2. When the last widget rendered is taller than a single row the whole widget will be drawn. This will cause the widget to draw beyond its boundaries vertically.

Testing instructions

  1. Run the scroll example with zig build -Dexample=scroll example and check that it behaves as expected.
  2. To see the known issues in action you can add constraints to the draw context passed to the scroll bars and scroll view widgets in the Model and see how the views will draw beyond the constraints.

Keybindings in example

Keybinding Effect
C-c exit
C-w Toggle line wrapping.
C-e Toggle content height estimate.
tab Toggle view cursor.
S-tab Toggle scrollbar.
/C-n/j Scroll view down one line, or move the cursor down one element if the cursor is enabled.
/C-p/k Scroll view up one line, or move the cursor up one element if the cursor is enabled.
C-d Scroll view down by half the current widget size.
C-u Scroll view up by half the current widget size.

The widget will render its children in a container that can be scrolled
both horizontally and vertically. The widget itself does not render any
scroll bars or other indicators of current scroll position.

Since this view is heavily based on the ListView widget it inherits the
same `cursor` functionality to show the current position of a selected
widget.

Known Issues
============

1. The view currently does not enforce a maximum width on the content to
   be able to correctly figure out whether the content can still be
   scrolled horizontally. This will cause the widget to draw beyond its
   boundaries horizontally.
2. When the last widget rendered is taller than a single row the whole
   widget will be drawn. This will cause the widget to draw beyond its
   boundaries vertically.
This widget is intended to wrap a ScrollView widget and show vertical
and horizontal scroll bars as indicators of scroll position in the
ScrollView. It's recommended to provide the estimated content sizes
with as much accuracy as possible for the best user experience and
performance.

If estimated content sizes are not provided the scroll bar sizes and
positions will be estimated using the size of child arrays. This is not
perfect and will cause inconsistencies if the child widgets aren't all
the exact same heights.
This adds an example demonstrating the use of the ScrollView and
ScrollBars widgets. It also includes keybindings to change how the child
widgets are laid out so you can see how that affects how the scroll bars
are rendered.

The content size estimates are deliberately wrong to demonstrate how
that affects the scroll bars. The value is intended to be modified by
whoever is testing the example.
@rockorager
Copy link
Owner

The view currently does not enforce a maximum width on the content to be able to correctly figure out whether the content can still be scrolled horizontally. This will cause the widget to draw beyond its boundaries horizontally.

Is this only true when word wrap is off?

@reykjalin
Copy link
Contributor Author

Is this only true when word wrap is off?

Hmm, sort of? In the example the word wrap is triggered by giving the Text widget a maximum width constraint, which aligns with the available width inside the scroll widget.

It's not the scroll view itself that's enforcing the word wrap 🤔

I guess we could set a max width constraint on children in the scroll view on request when something like a scroll_view.allow_horizontal_scrolling field is set to false. That might be easier than trying to manage the size of the children in the scrollview directly actually 🤔

What do you think?

@rockorager
Copy link
Owner

rockorager commented Jan 30, 2025 via email

@rockorager rockorager merged commit a41d3d8 into rockorager:main Jan 30, 2025
4 checks passed
@reykjalin
Copy link
Contributor Author

Great work! The examples work extremely well.

Thank you ❤️

Despite the known issues, I'll
merge this as is - it's a huge amount of work and we'll get those small bugs
fixed as they crop up for real use cases.

Yeah, that's exactly what I was thinking 🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants