Skip to content

Add Widget, Control and WidgetLabel class definitions, along with sliding switch and PyPortal example #4

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

Closed
wants to merge 38 commits into from

Conversation

kmatch98
Copy link
Contributor

@kmatch98 kmatch98 commented Feb 2, 2021

Here is a first draft of the proposed definition of the main classes for the Widget, Control and WidgetLabel.

As an example of using these classes, I created a round, sliding switch with an optional label. I include a PyPortal example that shows five switches, along with one labeled switch.

To do: Class definition

  • Confirm the key parameters that define each Class and the interactions and usage of each.
  • Confirm that Control has the appropriate response functions defined, including any required for near-term expansion.

To do: Sliding switch widget

  • Make the animation function more generic to be reused for other custom widgets and arbitrary orientations.
  • Add input parameters to define the switch label position.

Class structure

The structure of the Classes is roughly as shown in the diagram below:
Widget and Control Structure v1

@kmatch98
Copy link
Contributor Author

kmatch98 commented Feb 3, 2021

For the switch element:

  • Added a more general animation function called _get_offset_position that can be modified to adjust the motion behavior of any moving elements, including translation and rotation.

  • Added input parameters for the switch label positioning.

To do:

  • Test this out with the grid layout library.

One other thing that came to mind:

Some widgets may not have full independent control of the height and width parameters. For example the sliding switch wouldn't look right as a square. For interactions with the automated Grid Layout tool, the widget's width and height may need to be constrained somehow.

@kmatch98
Copy link
Contributor Author

kmatch98 commented Feb 7, 2021

Per @FoamyGuy ‘s livestream working on this, I need to revise the directory structure and update the import statements to conform to the standard way the libraries are setup.

So far I have just been dumping the files into the root directory of my PyPortal and have ignored any of the details of how the libraries normally work. I need to understand the file layout, then fix this and recommit.

He made a good suggestion related to the WidgetLabel. He recommended that the Switch shouldn’t import Widget_Label at all if no labels are used. This would save memory from having imported label or bitmap_label functions. In retrospect, maybe the option to display a label should reside up in the Widget class anyway rather than down in the Switch class? It suspect y’all may have other suggestions of how to handle this better than I’m currently doing in the Switch example.

Also he found some oddities with BliNka and how palette color getter works (returns dict instead of integer or tuple). Also in BliNka there was a strange crash when repositioning an item (the “0” text element). I think it crashed when the “0” circle was removed from the group and then the “1” item was added. That happens when the switch is at its halfway point.

Just wanted to get these down on paper so I wouldn’t forget them.

Copy link
Contributor

@FoamyGuy FoamyGuy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tested the newest version of this tonight and it's looking pretty good to me. Only a few things jumping out at me at the moment, a few docstrings in widget can be updated.

The other is I think we may need account for the widget_label within the width for the switch. I tried loading up a grid like this (albeit a bit haphazardly):
image

the bottom left switch has a name of "vertical" but much of it gets cut off. I'm not certain but I think it's because the grid_layout is trying to position it based on it's width which isn't accounting for the widget_label's size.

:param int width: width of the switch in pixels, set to ``None`` to auto-size
relative to the height
:param int height: height of the switch in pixels
:param str name: name of the switch
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some of these docstrings still reference switch instead of widget

@kmatch98
Copy link
Contributor Author

kmatch98 commented Feb 12, 2021

Thanks for the feedback. At minimum, I’m especially glad you got it to run now.

I am still struggling on how best to use Widget_Label. Thanks for the feedback on the sizing with a label added. I’m interested to hear your thoughts. Should a Widget always have the option for displaying a Widget_Label?

When it comes to resizing using grid_layout, it gets more complicated when you have to include the size of the Widget_Label in addition to the Widget parts. This gets even further complicated when you have to deal with the various placement options using anchor position of the Widget_Label.

I’m eager to hear what ideas you have, particularly when it comes to the interactions with grid_layout.

Oh one other thing. When I added the vertical orientation option, I have some things to resolve where self._width and self._height remain as if it were still horizontal. That may be rippling through and causing an issue with the label placement. I’ll try to get this sorted out tomorrow.

@FoamyGuy
Copy link
Contributor

Should a Widget always have the option for displaying a Widget_Label?

I'm not fully decided, but I think i lean towards no on this. If the user wants to have the label I think they can make the widget_label and use it. That would keep all of the logic for it outside of switch_round or widget. Maybe if there were widgets that were overwhelmingly likely that the user would want a label then we could create an additional object LabeledSwitch or similar that could combine the two in a single helper object, but I'm not sure if that is needed in all cases.

I will do some more experimenting as well and see if I can come up with a good way to handle the width / grid_layout placement.

@kmatch98
Copy link
Contributor Author

I agree with you with grid_layout. It will get hairy to calculate everything with Widget_Labels and Widgets to fit inside.

But I’m also thinking of folks that just want to freely x,y place a few Widgets. In the case of freeform Widget placement, having a label that’s positioned relative to the widget is a handy feature. That would prevent also having to x,y place a bunch of labels in addition to x,y placing the widgets. (Maybe this is just a time saver to get to my vision of folks making a 5 minute GUI.)

How about we say: A Widget_Label is optional for Widgets, but even if the Widget_Label is present it won’t be calculated in the Widget size when using grid_layout.

@kmatch98
Copy link
Contributor Author

I added a WidgetAnnotation widget that allows for pointing at a widget and adding text.

A widget to be used to annotate other widgets with text and pointer lines.

The annotation position on the widget can be defined by either the anchor_point (in relative dimensions of the size of the widget) or the anchored_position (in raw pixel dimensions relative to the origin of the widget). Also, further fine-tuning can be achieved using the optional position_offset.

@kmatch98
Copy link
Contributor Author

I’m putting a lot of things into this one pull request. Consider this as a draft holding area as we worth out the class definitions for Widget and Control. After the dust settles I can break this into separate PRs for the class definitions and then the separate widgets.

@kmatch98
Copy link
Contributor Author

kmatch98 commented Feb 23, 2021

I added documetation to SwitchRound that gives an overview of how to use the Widget and Control functions.
Also, I added the easing function to give it "springy" switching animation action.

Also, it explains a lot of what is under the hood that makes the Switch work, trying to highlight the commonalities that will be used for other widgets, particularly focused on the motion and animation methods.

I think SwitchRound is ready for others to try out. This works with the latest Widget and Control class definitions in the cleaner pull request.

@kmatch98
Copy link
Contributor Author

kmatch98 commented Mar 1, 2021

I discovered that sphinx can generate Class hierarchy diagrams. I had to install the graphviz software to run this. I'm not sure if this is available in the CircuitPython library builds.

I added this to docs/conf.py:

extensions = [
    "sphinx.ext.autodoc",
    "sphinx.ext.intersphinx",
    "sphinx.ext.napoleon",
    "sphinx.ext.todo",
    "sphinx.ext.inheritance_diagram"
]

inheritance_graph_attrs = dict(rankdir="TB")

Note that the "TB" makes it top-to-bottom. Delete the inheritance_graph_attrs line if you want the inheritance to be shown horizontally.

And this is my addition to docs/api.rst:

.. automodule:: adafruit_displayio_layout.widgets.switch_round
   :members:
   :inherited-members:
   :member-order: bysource

.. inheritance-diagram:: adafruit_displayio_layout.widgets.switch_round

image

Here's a link to some of the documentation:
https://www.sphinx-doc.org/en/master/usage/extensions/inheritance.html

Here is a list of the different settings that can be used to adjust the graph's attributes:
https://graphviz.org/doc/info/attrs.html

@kmatch98
Copy link
Contributor Author

kmatch98 commented Mar 9, 2021

I'm closing this draft PR and will submit individual PRs on each widget.

@kmatch98 kmatch98 closed this Mar 9, 2021
@PaulskPt PaulskPt mentioned this pull request May 16, 2022
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