Standard Base Classes/Protocols for Widget Types
- Dominant language
- Python
- Stars
- 5.4k
- Forks
- 827
- Avg merge
- 9h 45m
- Merged PRs (30d)
- 58
Description
### What is the problem or limitation you are having?
When implementing new widgets, there are frequently a lot of boilerplate methods in the interfaces for doing things like getting/setting handlers, values and selections. Often these are reflected in the underlying implementations, as well.
It would be nice to avoid having to copy and paste these methods and instead be able to use an abstract base class as a starting point.
Similarly, there are copy-pasted handler definitions for each class: it seems like a few protocols might help allow a reduction in the number of different implementations.
Standardization of widget interfaces may potentially make it easier for users to learn the APIs: less surprises is good. For example, with containers I constantly get tripped up between `children` arguments (Box) and `content` arguments (everything else).
This came about when looking into what #4470 might look like relative to `Selection`, `Table`, etc.
### Describe the solution you'd like
There are at least four categories of widgets:
- "Containers": widgets which hold other widgets. Examples: `Box`, `ScrollContainer`, `Window`, `OptionContainer`, `SplitContainer`.
- "Inputs", "Editors" or "Fields": widgets which have a `value` which is being edited by the user, and which uses `OnChangeHandler`. In many cases handling focus would make sense, but only `TextInput` currently does this. Examples: `DateInput`, `MultilineTextInput`, `NumberInput`, `Slider`, `Switch`, `TextInput`, `TimeInput`.
- "Selectables": widgets which have a `selection` from a `Source` and which use `OnSelectionHandler`, and may or may not allow multiple selections. Examples: `DetailedList`, `Selection`, `Table`, `Tree`, hypothetical `SegmentedButton`, `RadioGroup`, `CheckboxGroup` etc.
- "Views" or "Displays": which display a thing which the user can't change the value directly, but which may allow other interactions. Examples: `Button`, `ProgressBar`, `Canvas`, `ImageView`, `Label`, `WebView`, `MapView` (this shares a lot of similarities with "Selectables", but with `location` instead of `selection`) and external widgets like `BitmapView` and `Chart`.
There may be some hypothetical widgets, like comboboxes which straddle the categories (both an input and a selectable).
It would be good to create base classes or protocols for the common functionality, in particular for "Inputs" and "Selectables".
In particular:
- "Inputs" have a settable `value` property, and `on_change` handlers. Implementations are expected to implement `get_value` and `set_value`.
- "Selectables" have `multiple_select` and `selection` properties, and `on_select` handlers. It would be good to extend `selection` to be settable on all Selectables, and it would also be good to expose `selected_indices` or something like that. The one awkward thing is that different Selectables currently have different names for their sources (like "data" and "items"). Implementations are expected to implement `get_selection`, `set_selection`, and implement the appropriate `Source` listener API.
### Describe alternatives you've considered
The status quo. It's fine.
### Additional context
I couldn't find an issue with similar discussions, but I'd be surprised if there wasn't one.
Happy to bikeshed on names.
Contributor guide
Research direction
Start by comparing the widget interfaces and implementations named in the issue, especially inputs such as TextInput and selectables such as Selection and Table. Identify the shared APIs and the incompatible source and container naming before proposing base classes or protocols. Done would require an agreed design, consistent interfaces, and coverage of the affected widget categories.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- desktop
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Needs clarification
- Newbie friendliness
- 32/100