Skip to content

Main classes: Widget and Control #5

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

Merged
merged 42 commits into from
Mar 3, 2021
Merged
Show file tree
Hide file tree
Changes from 34 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
4dfdce6
Initial commit with Widget, Control and WidgetLabel class definitions…
kmatch98 Feb 2, 2021
a7eced3
Ran black, somehow failed for widget_label.py
kmatch98 Feb 2, 2021
ff05592
Add orientation and flip to switch, simplify animation functions with…
kmatch98 Feb 3, 2021
634f91c
Ran black and pylint, some cleanup
kmatch98 Feb 3, 2021
14303c8
Update widget name to SwitchRound
kmatch98 Feb 3, 2021
7272941
Change filename of example to remove _horizontal_
kmatch98 Feb 3, 2021
adb2dc0
Use .hidden property of TileGrid to handle text 0/1 display control
kmatch98 Feb 7, 2021
57eb704
Arrange folders to match library standard organization
kmatch98 Feb 7, 2021
bdc1f34
Update example to conform to correct directory structure
kmatch98 Feb 7, 2021
3158d43
Added resize function for compatibility with grid_layout
kmatch98 Feb 9, 2021
8072bb4
Some pylint fixes, delete debug print statements
kmatch98 Feb 9, 2021
bc24846
Initial commit of WidgetAnnotation
kmatch98 Feb 12, 2021
14b2543
Add Dial widget, add example for Switch, Dial and WidgetAnnotation an…
kmatch98 Feb 13, 2021
90c443e
Initial commit with Widget, Control and WidgetLabel class definitions…
kmatch98 Feb 2, 2021
3d6d443
Ran black, somehow failed for widget_label.py
kmatch98 Feb 2, 2021
4e2cfec
Merge branch 'main' of https://github.com/kmatch98/Adafruit_CircuitPy…
kmatch98 Feb 13, 2021
7582f2e
Initial commit with Widget, Control and WidgetLabel class definitions…
kmatch98 Feb 2, 2021
4daff4d
Merge branch 'main' of https://github.com/kmatch98/Adafruit_CircuitPy…
kmatch98 Feb 13, 2021
b8de020
Bring up to date with latest main upstream branch
kmatch98 Feb 13, 2021
4245291
Update to include merged changes from upstream
kmatch98 Feb 13, 2021
57fa93b
Ran black on widgets
kmatch98 Feb 13, 2021
7e4e3a4
Add comments to switch_round, add simpletest switch examples
kmatch98 Feb 14, 2021
e3cd623
Add font option for switch_round WidgetLabel
kmatch98 Feb 14, 2021
7aa9902
Add flip_input widget
kmatch98 Feb 15, 2021
759248d
Add flip_input example
kmatch98 Feb 15, 2021
8c5c397
add font file
kmatch98 Feb 15, 2021
4f62512
Streamline animation for flip_input, adapt to script fonts
kmatch98 Feb 16, 2021
c050b9a
Add easing animations for flip_input
kmatch98 Feb 18, 2021
dac960d
Updated animation redraws to allow springy animations
kmatch98 Feb 19, 2021
a0649d6
Add sphinx docs
kmatch98 Feb 19, 2021
5fd70e8
remove unnecessary files for this PR
kmatch98 Feb 19, 2021
a23dab9
restore examples
kmatch98 Feb 19, 2021
b8e8df7
pylint fixes
kmatch98 Feb 19, 2021
6f426d8
end of line to api.rst
kmatch98 Feb 19, 2021
faf2588
Update Widget and Control class definitions, add documentation includ…
kmatch98 Feb 22, 2021
a2fdcca
Update Widget, Control definitions per review feedback, added documen…
kmatch98 Feb 22, 2021
4a6a2c9
add license file
kmatch98 Feb 22, 2021
acb0695
Add default values to Widget x,y
kmatch98 Feb 23, 2021
1a2ed2f
Minor doc tweak
kmatch98 Feb 24, 2021
18e9cf5
Minor doc tweak
kmatch98 Feb 24, 2021
312ccf7
Merge branch 'main_classes' of https://github.com/kmatch98/Adafruit_C…
kmatch98 Mar 3, 2021
db17f9e
Update api.rst
kmatch98 Mar 3, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 108 additions & 0 deletions adafruit_displayio_layout/widgets/control.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# SPDX-FileCopyrightText: 2021 Kevin Matocha
#
# SPDX-License-Identifier: MIT

"""
`control`
================================================================================
CircuitPython GUI Control Class for touch-related elements

* Author(s): Kevin Matocha

Implementation Notes
--------------------

**Hardware:**

**Software and Dependencies:**

* Adafruit CircuitPython firmware for the supported boards:
https://github.com/adafruit/circuitpython/releases

"""

# pylint: disable=unnecessary-pass

__version__ = "0.0.0-auto.0"
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_DisplayIO_Layout.git"


class Control:
"""A Control class for responsive elements, including several response functions,
including for touch response.

**IMPORTANT**: The *touch_point* for all functions should be in local coordinates for this item.
That means, any widget should adjust for self.x and self.y before passing
the touchpoint up to this superclass function.

"""

def __init__(
self,
):
self.touch_boundary = (
None # `self.touch_boundary` should be updated by the subclass
)

def contains(self, touch_point):
# pylint: disable=unsubscriptable-object

"""Checks if the Control was touched. Returns True if the touch_point is
within the Control's touch_boundary.

:param touch_point: x,y location of the screen, converted to local coordinates.
:return: Boolean

"""
if (self.touch_boundary is not None) and (
(
self.touch_boundary[0]
<= touch_point[0]
<= (self.touch_boundary[0] + self.touch_boundary[2])
)
and (
self.touch_boundary[1]
<= touch_point[1]
<= (self.touch_boundary[1] + self.touch_boundary[3])
)
):
return True
return False

# place holder touch_handler response functions
def selected(self, touch_point):
"""Response function when Control is selected. Should be overridden by subclass.

:param touch_point: x,y location of the screen, converted to local coordinates.
:return: None

"""
pass

def still_touched(self, touch_point): # *** this needs a clearer name
"""Response function when Control remains touched. Should be overridden by subclass.

:param touch_point: x,y location of the screen, converted to local coordinates.
:return: None

"""
pass

def released(self, touch_point):
"""Response function when Control is released. Should be overridden by subclass.

:param touch_point: x,y location of the screen, converted to local coordinates.
:return: None

"""
pass

def gesture_response(self, gesture):
"""Response function to handle gestures (for future expansion). Should be
overridden by subclass.

:param gesture: To be defined
:return: None

"""
pass
164 changes: 164 additions & 0 deletions adafruit_displayio_layout/widgets/widget.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
# SPDX-FileCopyrightText: 2021 Kevin Matocha
#
# SPDX-License-Identifier: MIT
"""

`widget`
================================================================================
CircuitPython GUI Widget Class for visual elements

* Author(s): Kevin Matocha

Implementation Notes
--------------------

**Hardware:**

**Software and Dependencies:**

* Adafruit CircuitPython firmware for the supported boards:
https://github.com/adafruit/circuitpython/releases

"""

import displayio

__version__ = "0.0.0-auto.0"
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_DisplayIO_Layout.git"


class Widget(displayio.Group):
"""
A Widget class definition for graphical display elements.

:param int x: pixel position
:param int y: pixel position
: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
:param float anchor_point: (X,Y) values from 0.0 to 1.0 to define the anchor
point relative to the switch bounding box
:param int anchored_position: (x,y) pixel value for the location
of the anchor_point

"""

def __init__(
self,
width=None,
height=None,
name="",
anchor_point=None,
anchored_position=None,
bounding_box=None, # pixel extent of the widget [x0, y0, width, height]
**kwargs,
):
# pylint: disable=too-many-arguments

super().__init__(**kwargs) # should send x,y and scale (optional) to Group

self._width = width
self._height = height
self.name = name
self._anchor_point = anchor_point
self._anchored_position = anchored_position

# self._bounding_box: pixel extent of the widget [x0, y0, width, height]
# The bounding box should be updated based on the specifics of the widget
if bounding_box is None:
if (width is not None) and (height is not None):
self._bounding_box = [0, 0, width, height]
else:
self._bounding_box = [0, 0, 0, 0]

self._update_position()

def _update_position(self):
"""
Internal Widget class function for updating the x,y position based upon
the `anchor_point` and `anchored_position`.

:return: None
"""

if (self._anchor_point is not None) and (self._anchored_position is not None):
self.x = (
self._anchored_position[0]
- int(self._anchor_point[0] * self._bounding_box[2])
- self._bounding_box[0]
)
self.y = (
self._anchored_position[1]
- int(self._anchor_point[1] * self._bounding_box[3])
- self._bounding_box[1]
)

@property
def anchor_point(self):
"""The anchor point for positioning the widget, works in concert
with `anchored_position` The relative (X,Y) position of the widget where the
anchored_position is placed. For example (0.0, 0.0) is the Widget's upper left corner,
(0.5, 0.5) is the Widget's center point, and (1.0, 1.0) is the Widget's lower right corner.

:param anchor_point: In relative units of the Widget size.
:type anchor_point: Tuple[float, float]"""
return self._anchor_point

@anchor_point.setter
def anchor_point(self, new_anchor_point):
self._anchor_point = new_anchor_point
self._update_position()

@property
def anchored_position(self):
"""The anchored position (in pixels) for positioning the widget, works in concert
with `anchor_point`. The `anchored_position` is the x,y pixel position
for the placement of the Widget's `anchor_point`.

:param anchored_position: The (x,y) pixel position for the anchored_position (in pixels).
:type anchored_position: Tuple[int, int]

"""
return self._anchored_position

@anchored_position.setter
def anchored_position(self, new_anchored_position):
self._anchored_position = new_anchored_position
self._update_position()

@property
def bounding_box(self):
"""The boundary of the widget. [x, y, width, height] in Widget's local
coordinates (in pixels)."""
return self._bounding_box

@property
def width(self):
"""The widget width, in pixels."""
return self._width

@property
def height(self):
"""The widget height, in pixels."""
return self._height

def resize(self, new_width, new_height):
"""Resizes the widget dimensions for use with automated layout functions.

**The `resize` function should be overridden by the subclass definition.**

The width and height are provided together so the subclass `resize`
function can apply any constraints that require consideration of both width
and height (such as maintaining a preferred aspect ratio). The Widget should
be resized to the maximum size that can fit within the dimensions defined by
the requested *new_width* and *new_height*. After resizing, the Widget
`bounding_box` should also be updated.

:param int new_width: target maximum width (in pixels)
:param int new_height: target maximum height (in pixels)
:return: None

"""
self._width = new_width
self._height = new_height
6 changes: 6 additions & 0 deletions docs/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,9 @@

.. automodule:: adafruit_displayio_layout.layouts.grid_layout
:members:

.. automodule:: adafruit_displayio_layout.widgets.widget
:members:

.. automodule:: adafruit_displayio_layout.widgets.control
:members: