-
Notifications
You must be signed in to change notification settings - Fork 15
Draft proposal of standard parameters and functions for DisplayIO Widgets #3
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
Comments
What if all of these widgets used a "Control" or "Widget" superclass rather than directly deriving from Group and the superclass handled these standard events? |
@kmatch98 this is a really great start! Thanks for taking the time to get all of this down. I am in agreement with the majority of what you've laid out. I'll list only the things I might add to or suggest different below. I am thinking the same as Melissa as well about putting these things into a class and then having the specific widgets extend this instead of Group. I'll refer to it as "Control" here, I do like that name, but open to other ideas still as well. For the response functions I wonder if there may be a way to leverage the Widget naming - I don't think a widget_label option should be done at the Control level. I do see the usefulness of this construct, but I think the way to go about it is making a specific widget / layout. Like LabeledThing class (hopefully better name) and it has a
Coordinate scheme - This is an awesome illustration! Would love to see diagrams like this find a home in the documentation or learn guide. |
Thanks for the encouragement. I’m not sure I follow the difference in purpose or function between a Right now, the only thing that can be displayed using If y’all can sketch a block diagram of your proposal that will help me understand better. @FoamyGuy thanks for the comments on the variables, I think some variables should be categorized as “mandatory” (so things like grid_layout can operate on them) and other variables as “optional”. And anytime we can use meaningful reuse of variable names that will probably make life easier, even for optional variables. Also I like your idea about the labeling of a widget. I struggled to make sense of a good way of doing that, but I think you are on a good track about having a separate “thing” that does any labeling. I’m also thinking of the best way of putting text inside of a widget, like numbers on a dial and how it can use a common way of laying them out. Maybe that is the same as a “grid layout” task, but used inside a widget. Regarding widget orientation, taking the example of a switch I could imagine someone wanting it to switch right/left (horizontal) or up/down (vertical with ON is up), then next someone will want eventually want the mirror image of that (vertical but ON being down), so I thought maybe “flip” would be a way to describe the mirror image orientation. (I think I saw that lingo used some other library, maybe for setting up matrix display?). Another example, if someone wants a Sparkline to scroll in the opposite direction, they could “flip” it. I was thinking the individual widget drawing routine could be designed to handle dealing with the orientations (if that feature is desired). Thanks again for the feedback. I’ll do some more cleanup on the slider switch widget example (better color handling) and post it somewhere for general consumption. |
The main reason for Control existing is that |
Ah I think I see what you mean with flip, its more conceptual and the specifics can be up to each widget, not necessarily strictly mirroring the pixels. I do think that is a nice option to have. Orientation I think I understand what you mean better as well. But I do think it can live on each widget that wants to have it. Doesn't need to be on Control |
In the initial code I have a |
That's the great thing about using a superclass. The subclasses can override any functions from the superclass for any specific implementation details. |
I agree with @makermelissa and @FoamyGuy on separating a "Control" or "Interactable" base widget. It also makes that functionality opt-in as opposed to required for every "Group", might be a ram/space saver on some of the more ram tight m4 boards (like the Nrf). Also groups don’t have dimensions where as Controls do is a great point. There may be a be advantages to separating controls further? Not all widgets may need control. It could be something like Group -> Widget -> Control. Widget adds dimension and Control adds, well, control. If I may add in two cents to the original post. Might I suggest that 'x' and 'y' be specified together as 'coord=', a tuple of (x, y). Same thing for width and height as (width, height) as 'dims='. For the data/control interface I'd suggest separating selection from pressing from updating scroll coordinates, etc. Another useful debug widget may be frame, something to draw the exact borders around a widget. |
I'm trying to digest y'all's inputs so I made a chart to see if I'm getting it right. Also, I'm unsure how generic the Here are some questions: Specifically regarding touch_screen related control functions, it seems like touch_screen capabilities differ a lot depending upon the type. The current Adafruit_CircuitPython_Touchscreen Library for the resistive touch screen seems to only provide single touch response. But I guess there could be added wrappers to provide One more question about As I'm fairly new to all of this, so I'm mixing up a lot of questions and concepts between the class structure and the event loop handling, so I appreciate your patience. Also, I'm sure this has been done before, so if you have a suggested reference design, please fire it over. |
As I have this on hand, Here is an event loop I've implemented. It scans through all the widgets that have certain control functionalities and then informs them of what to do. That way the widgets don’t have to parse raw data* in this design widgets' control functionality is defined by the presence of specific methods but I could easily be defined as subclasses with overrides. [*] scrolling is not finished, so the update coord does have to for now https://github.com/TG-Techie/TG-Gui-Std-CircuitPython/blob/main/tg_gui_std/event_loops.py |
I updated the sliding switch widget now with classes as laid out in the diagram above. Here are the main updates: Demo files are here, along with a pyPortal example. To Clarify:
This is my first time making a more complicated set of interacting Python classes, so I welcome any suggestions that you have to improve this. It took me quite a bit of trial and error to figure out the use of I appreciate your inputs! The diagram above captures the general Class design. But here it is in a list, along with a few comments.
|
I submitted a draft pull request with the initial version of the proposed class definitions and an example. Feedback is welcome. |
This is superseded by the PRs and other discussions so I’m closing this. |
The DisplayIO_Layout library will rely on having several standard parameters for any "widgets" so this function can place them in the desired layout. Additionally, for any touch-related objects, it is useful to have standard response functions.
The starting point for this proposal was the Adafruit_CircuitPython_Display_Text library with the label item along with the Adafruit_CircuitPython_Display_Button library with the button item.
I'd especially like proposals on the standardized "Response functions" for widgets.
Proposed widget parameters and naming:
x
,y
: upper left corner of the widget, in display pixel coordinates (see diagram)anchor_point
: (a, b) two values between 0 and 1. Widget placement usinganchor_point
andanchored_position
should operate the same as display_text.Label (see candy hearts example: https://learn.adafruit.com/circuit-python-tft-gizmo-candy-hearts/how-it-works)anchored_position
: (C,D) in pixels (seeanchor_point
description above)width
: in pixelsheight
: in pixelsbounding_box
: (x, y, width, height), *getter onlytouch_padding
: in pixels, additional space around thebounding_box
that accept touch input (alternately, modifytouch_boundary
directly)touch_boundary
: (x, y, width, height) region that will accept touch inputcontains(touch_point)
: responds True if touch-point is within the widget’stouch_boundary
selected(touch_point)
: widget was just touched, reaction to selection will depend upon the widget’s needsstill_touched(touch_point)
: widget remains touched (***?)released(touch_point)
: widget is released (***?)value
: type will depend upon the widget (getter/setter required)label
: text label to describe the buttondisplay_label
: Boolean, setTrue
to display the name of the widgetlabel_font
: fontlabel_anchor_point_on_widget
: proposed (*need to add description and diagram)label_anchor_point_on_label
: proposed (*need to add description and diagram)_color
: use as many parameters as needed for fill and outline colors for the widget structures, prefer to include_color
somewhere in the parameter name. Should accommodate hex 0xFFFFFF 8-bit RGB color codes, but prefer to also support tuples (R, G, B)._stroke
: this is the width in pixels of outline features. Use as many as needed, prefer to include_stroke
in the parameter name.animation_time
: in seconds, the time required for the widget’s animation. For example, for a switch, the time allotted for switching from off to on and vise versa. Preferably, the widget will check the elapsed animation time and redraw accordingly, so that the response time is the approximately the same even when run on different processors and systems. (see example in switch_round_horizontal.py, seeselected
function)orientation
:horizontal
orvertical
flip
: Boolean, default is False. Set True if mirror image is desired.Coordinate scheme
Here is a graphic with a proposal of some of the naming of the pixel coordinate schemes:

Draft code snippet: Switch widget
Here is a code snippet of the
__init__
function for a draft of a switch widget that runs on the Adafruit PyPortal:Widget positioning
As described above, the widget position on the screen can be defined directly by

widget.x
andwidget.y
or by the combination ofwidget.anchor_point
andwidget.anchored_position
.Here is a reference image for the usage of
anchor_point
andanchored_position
as snipped from the Adafruit Learn guide's Candy Hearts Example:The text was updated successfully, but these errors were encountered: