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

Persisting input state for view widgets #281

Open
4 of 6 tasks
dhardy opened this issue Feb 9, 2022 · 0 comments
Open
4 of 6 tasks

Persisting input state for view widgets #281

dhardy opened this issue Feb 9, 2022 · 0 comments
Labels
discussion Requires analysis/discussion internal API Design of core feature new feature

Comments

@dhardy
Copy link
Collaborator

dhardy commented Feb 9, 2022

Summary: input state (such as text selection range) is stored in widget state. When view widgets are remapped (e.g. --example data-list-view entries are scrolled out of view), this is lost.

Background

Consider examples/data-list-view.rs:

  • ViewList constructs child widgets on-demand to view contents, using enough child widgets to cover all visible entries but not enough to cover everything, making the list scalable to millions of entries (this is the difference from data-list.rs, which uses a backing widget for every entry)
  • In set_rect (after init/resize), additional child widgets are allocated if necessary
  • So long as the child widgets remain visible (and possibly for a short distance outside the visible area) it remains unchanged
  • When a new data-entries becomes visible, ListData::iter_vec_from is used to get the values, and Driver::set assigns these values to existing child widgets, then configure, size_rules and set_rect are called on these child widgets

Now, widgets essentially have three types of state:

  • Data: for example, the text of a string label; this is set by Driver::set
  • Transient state: for example, the widget's identifier and rect; this is set by configure / set_rect, or the "disabled state", set based on some external data
  • Input state: for example, the cursor location and selection of an EditBox, or whether a button is currently depressed

Problem: the child's input state is not persisted when scrolled out of view then scrolled back again.

Current status

Some input state, such as (keyboard) navigation focus and character input focus is stored directly in the window's EventState (recently renamed from event::Manager). Other recent changes (#265, #276) give persistent WidgetId values to data entries not child widgets, thus keyboard navigation focus is persisted properly when a widget is scrolled out of view.

So:

  • The "mouse hover" state is derived from EventState and not stored in widgets
  • The "button depress" state is derived from EventState
  • Navigation focus is stored in EventState
  • Selection status is stored in ListView and MatrixView widgets
  • Undo history of text is stored in the EditField widget (this was a quick hack and really should be external)
  • Selection range / text cursor location is stored in the EditField and ScrollLabel widgets

Proposed changes

Putting selection data in EventState is viable, but requires somehow exposing this to widgets (probably via a getter on EventMgr). (In fact, it may be useful: currently Event::LostSelFocus exists explicitly to clear selection when a different widget makes a selection.)

But what else? What if a user creates a widget with some new type of "input state"? Do we accept inclusion of such things into EventState? Possibly we have to, if we want to support the widget fully as a child of a view widget. (On the other hand, choosing not to support such things may be acceptable.)

@dhardy dhardy added discussion Requires analysis/discussion new feature internal API Design of core feature labels Feb 23, 2022
@dhardy dhardy changed the title View widgets + input state Persisting input state for view widgets Sep 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
discussion Requires analysis/discussion internal API Design of core feature new feature
Projects
None yet
Development

No branches or pull requests

1 participant