Simplify setup. README fixes (still WIP).

pull/8/head
Peter Hinch 2021-06-20 16:46:14 +01:00
rodzic a9967e79e9
commit 8d3171334c
14 zmienionych plików z 169 dodań i 147 usunięć

225
README.md
Wyświetl plik

@ -195,7 +195,6 @@ prev = Pin(18, Pin.IN, Pin.PULL_UP) # Move to previous control
increase = Pin(20, Pin.IN, Pin.PULL_UP) # Increase control's value
decrease = Pin(17, Pin.IN, Pin.PULL_UP) # Decrease control's value
display = Display(ssd, nxt, sel, prev, increase, decrease)
setup(display)
```
Display drivers are documented
@ -270,6 +269,11 @@ the pushbutton GPIO lines. According to the
[ESP32 gurus](https://randomnerdtutorials.com/esp32-pinout-reference-gpios/)
pins 36-39 do not have pullup support.
On a Pyboard 1.1 with 320x240 ili9341 display it was necessary to use frozen
bytecode: in this configuration running the "various" demo there was 29K of
free RAM. Note that, at 37.5KiB, this display is the worst-case in terms of
RAM usage. A smaller display or a Pyboard D would offer more headroom.
## 1.9 Firmware and dependencies
Firmware should be V1.15 or later. The source tree includes all dependencies.
@ -374,8 +378,8 @@ Note that the import of `hardware_setup.py` is the first line of code. This is
because the frame buffer is created here, with a need for a substantial block
of contiguous RAM.
```python
from hardware_setup import ssd # Instantiate display, setup color LUT (if present)
from gui.core.ugui import Screen
import hardware_setup # Instantiate display, setup color LUT (if present)
from gui.core.ugui import Screen, ssd
from gui.widgets.label import Label
from gui.widgets.buttons import Button, CloseButton
@ -539,6 +543,10 @@ In normal use the following methods only are required:
passing positional and keyword arguments to the constructor of the new, user
defined, screen.
* `back(cls)` Restore previous screen.
* `value(cls, val=None)` The `val` arg can be any Python type. It allows
widgets on a `Screen` to store information in a way which can be accessed from
the calling screen. This typically occurs after the screen has closed and no
longer exists as an instance, hence the use of a classmethod.
These are uncommon:__
* `shutdown(cls)` Clear the screen and shut down the GUI. Normally done by a
@ -663,7 +671,6 @@ Methods:
* `bdcolor=None` Border color. As per above except that if `False` is
passed, no border is displayed. This clears a previously drawn border.
Returns the current text string.
2. `show` No args. (Re)draws the label. Primarily for internal use by GUI.
If populating a label would cause it to extend beyond the screen boundary a
warning is printed at the console. The label may appear at an unexpected place.
@ -728,7 +735,6 @@ Methods:
* `bgcolor=None` Background color, as per foreground.
* `bdcolor=None` Border color. As per above except that if `False` is
passed, no border is displayed. This clears a previously drawn border.
3. `show` No args. (Re)draws the LED. Primarily for internal use by GUI.
###### [Contents](./README.md#0-contents)
@ -763,9 +769,9 @@ Optional keyword only arguments:
* `active=True` By default user input is accepted.
Methods:
* `greyed_out` Optional Boolean argument `val` default `None`. If
`None` returns the current 'greyed out' status of the control. Otherwise, if
the widget is `active`, enables or disables it, showing it in its new state.
* `greyed_out` Optional Boolean argument `val=None`. If `None` returns the
current 'greyed out' status of the control. Otherwise enables or disables it,
showing it in its new state.
* `value` Optional Boolean argument `val`. If the provided value does not
correspond to the control's current value, updates it; the checkbox is
re-drawn and the callback executed. Always returns the control's value.
@ -813,7 +819,7 @@ Optional keyword only arguments:
pushbutton is released otherwise it will occur when pressed.
Method:
* `greyed_out=None` Optional Boolean argument `val`. If `None` returns the
* `greyed_out` Optional Boolean argument `val=None`. If `None` returns the
current 'greyed out' status of the control. Otherwise enables or disables it,
showing it in its new state.
@ -866,7 +872,7 @@ Methods:
* `add_button` Adds a button to the `ButtonList`. Arguments: as per the
`Button` constructor.
Returns the button object.
* `greyed_out=None` Optional Boolean argument `val`. If `None` returns the
* `greyed_out` Optional Boolean argument `val=None`. If `None` returns the
current 'greyed out' status of the control. Otherwise enables or disables it,
showing it in its new state.
* `value` Optional args `button=None`, `new_cb=False`. The `button` arg, if
@ -919,12 +925,12 @@ Constructor positional arguments:
Methods:
* `add_button` Adds a button. Arguments: as per the `Button` constructor.
Returns the Button instance.
* `greyed_out=None` Optional Boolean argument `val`. If `None` returns the
* `greyed_out` Optional Boolean argument `val=None`. If `None` returns the
current 'greyed out' status of the control. Otherwise enables or disables it,
showing it in its new state.
* `value` Optional argument: a button in the set. If supplied, and the
button is not currently active, the currency changes to the supplied button
and its callback is run. Always returns the currently active button.
button is not currently active, the supplied button receives the focus and its
callback is run. Always returns the currently active button.
Typical usage:
```python
@ -950,7 +956,7 @@ for t in table:
# 12. Listbox widget
```python
from gui.widgets.listbox import Listbox, ON_MOVE, ON_LEAVE
from gui.widgets.listbox import Listbox
```
A `Listbox` is an active widget. Its height is determined by the number of
@ -977,29 +983,26 @@ Optional keyword only arguments:
default is used.
* `bdcolor=False` Color of border. If `False` no border will be drawn. If a
color is provided, a border line will be drawn around the control.
* `fontcolor` Text color. Defaults to system text color.
* `select_color` Background color for selected item in list. Default
`LIGHTBLUE`.
* `callback` Callback function which runs when `select` is pressed.
* `args` A list/tuple of arguments for above callback. Default `[]`.
* `also=0` Options are `ON_MOVE` or `ON_LEAVE`. By default the callback runs
only when the `select` button is pressed. The `ON_LEAVE` value meanse that it
will also run when the focus moves from the control if the currently selected
element has been changed. The `ON_MOVE` arg causes the callback to run every
time the highlighted element is changed.
* `fontcolor=None` Text color. Defaults to system text color.
* `select_color=DARKBLUE` Background color for selected item in list.
* `callback=dolittle` Callback function which runs when `select` is pressed.
* `args=[]` A list/tuple of arguments for above callback.
* `also=0` Options are `Listbox.ON_MOVE` or `Listbox.ON_LEAVE`. By default the
callback runs only when the `select` button is pressed. The `ON_LEAVE` value
causes it also to run when the focus moves from the control if the currently
selected element has changed. The `ON_MOVE` arg causes the callback to run
every time the highlighted element is changed.
Methods:
* `greyed_out` Optional boolean argument `val` default `None`. If
`None` returns the current 'greyed out' status of the control. Otherwise
enables or disables it, showing it in its new state.
* `value` Argument `val` default `None`. If the argument is provided
which is a valid index into the list that entry becomes current and the
callback is executed. Always returns the index of the currently active entry.
* `textvalue` Argument `text` a string default `None`. If the argument
is provided and is in the control's list, that item becomes current. Returns
the current string, unless the arg was provided but did not correspond to any
list item. In this event the control's state is not changed and `None` is
returned.
* `greyed_out` Optional Boolean argument `val=None`. If `None` returns the
current 'greyed out' status of the control. Otherwise enables or disables it,
showing it in its new state.
* `value` Argument `val=None`. If a provided argument is a valid index for the list, that entry becomes current and the callback is executed. Always returns
the index of the currently active entry.
* `textvalue` Argument `text=None`. If a string argument is provided and is in
the control's list, that item becomes current. Normally returns the current
string. If a provided arg did not match any list item, the control's state is
not changed and `None` is returned.
The callback's first argument is the listbox instance followed by any args
specified to the constructor. The currently selected item may be retrieved by
@ -1024,7 +1027,8 @@ Open dropdown list.
A dropdown list. The list, when active, is drawn below the control. The height
of the control is determined by the height of the font in use. The height of
the list is determined by the number of entries in it and the font in use.
Scrolling is not supported.
Scrolling is not supported. The dropdown should be placed high enough on the
screen to ensure that the list can be displayed
Constructor mandatory positional args:
1. `writer` The `Writer` instance (defines font) to use.
@ -1038,7 +1042,7 @@ Mandatory keyword only argument:
Optional keyword only arguments:
* `width=None` Control width in pixels. By default this is calculated to
accommodate all elements.
* `value=0` Index of currently selected list item. Default 0.
* `value=0` Index of currently selected list item.
* `fgcolor=None` Color of foreground (the control itself). If `None` the
`Writer` foreground default is used.
* `bgcolor=None` Background color of object. If `None` the `Writer` background
@ -1051,17 +1055,16 @@ Optional keyword only arguments:
* `args=[]` A list/tuple of arguments for above callback.
Methods:
* `greyed_out` Optional boolean argument `val` default `None`. If
`None` returns the current 'greyed out' status of the control. Otherwise
enables or disables it, showing it in its new state.
* `value` Argument `val` default `None`. If the argument is provided
which is a valid index into the list that entry becomes current and the
callback is executed. Always returns the index of the currently active entry.
* `textvalue` Argument `text` a string default `None`. If the argument
is provided and is in the control's list, that item becomes current. Returns
the current string, unless the arg was provided but did not correspond to any
list item. In this event the control's state is not changed and `None` is
returned.
* `greyed_out` Optional Boolean argument `val=None`. If `None` returns the
current 'greyed out' status of the control. Otherwise enables or disables it,
showing it in its new state.
* `value` Argument `val=None`. If a provided arg is a valid index into the
list, that entry becomes current and the callback is executed. Always returns
the index of the currently active entry.
* `textvalue` Argument `text=None`. If a string argument is provided and is in
the control's list, that item becomes current. Normally returns the current
string. If a provided arg did not match any list item, the control's state is
not changed and `None` is returned.
If `select` is pressed when the `Dropdown` has focus, the list is displayed.
The `increase` and `decrease` buttons move the list currency. If `select` is
@ -1091,10 +1094,10 @@ calculated from the strings assigned to the buttons. This ensures that buttons
are evenly spaced and identically sized. Typically used for simple queries such
as "yes/no/cancel".
Constructor mandatory positional args:
Constructor positional args:
1. `writer` The `Writer` instance (defines font) to use.
2. `row` Location on screen.
3. `col`
2. `row=20` Location on screen.
3. `col=20`
Mandatory keyword only arg:
* `elements` A list or tuple of 2-tuples. Each defines the text and color of
@ -1111,16 +1114,18 @@ Optional keyword only args:
* `callback=dolittle`
* `args=[]`
The `DialogBox` is a `Window` subclass. Pressing any button closes the dialog
and sets the `Window` value to the text of the button pressed or "Close" in the
Classmethod (inherited from `Screen`):
* `value(cls, val=None)` The `val` arg can be any Python type.
The `DialogBox` is a `Screen` subclass. Pressing any button closes the dialog
and sets the `Screen` value to the text of the button pressed or "Close" in the
case of the `close` button. The outcome can therefore be tested by running
`Window.value()` or by implementing the callback. The latter receives the
`Screen.value()` or by implementing the callback. The latter receives the
`DialogBox` instance as a first arg, followed by any args supplied to the
constructor.
Note that dialog boxes can also be constructed manually, allowing for more
flexible designs. For example these might have widgets other than pushbuttons.
The approach is to write a user subclass of `Window`. Example code may be found
Note that dialog boxes can also be constructed manually, enabling more flexible designs. For example these might have widgets other than pushbuttons. The
approach is to write a user subclass of `Window`. Example code may be found
in `gui/demos/screens.py`.
###### [Contents](./README.md#0-contents)
@ -1143,12 +1148,12 @@ fonts.
Constructor mandatory positional arguments:
1. `writer` The `Writer` instance (font and screen) to use.
2. `row` Location on screen.
3. `col`
3. `col`
4. `width` Width of the object in pixels.
5. `nlines` Number of lines of text to display. The object's height is
determined from the height of the font:
`height in pixels = nlines*font_height`
As per most widgets the border is drawn two pixels beyond the control's
As per all widgets the border is drawn two pixels beyond the control's
boundary.
Keyword only arguments:
@ -1207,14 +1212,13 @@ Constructor mandatory positional args:
2. `row` Location on screen.
3. `col`
Keyword only args:
Keyword only args:
* `height=50` Height of meter.
* `width=10` Width.
* `fgcolor=None` Color of foreground (the control itself). If `None` the
`Writer` foreground default is used.
* `bgcolor=None` Background color of object. If `None` the `Writer` background
default is used.
* `bgcolor=BLACK` Background color of meter. If `None` the `Writer` background
is used.
* `bdcolor=False` Color of border. If `False` no border will be drawn. If a
color is provided, a border line will be drawn around the control.
* `ptcolor=None` Color of meter pointer or bar. Default is foreground color.
@ -1226,8 +1230,7 @@ Keyword only args:
* `legends=None` If a tuple of strings is passed, `Label` instances will be
displayed to the right hand side of the meter, starting at the bottom. E.G.
`('0.0', '0.5', '1.0')`
* `value=None` Initial value. If `None` the meter will not be drawn until
its `value()` method is called.
* `value=0` Initial value.
Methods:
1. `value` Args: `n=None, color=None`.
@ -1244,7 +1247,6 @@ Methods:
* `bgcolor=None` Background color, as per foreground.
* `bdcolor=None` Border color. As per above except that if `False` is
passed, no border is displayed. This clears a previously drawn border.
3. `show` No args. (Re)draws the meter. Primarily for internal use by GUI.
###### [Contents](./README.md#0-contents)
@ -1274,43 +1276,43 @@ Optional keyword only arguments:
* `height` Dimension of the bounding box. Default 100 pixels (v), 20 (h).
* `width` Dimension of the bounding box. Default 20 pixels (v), 100 (h).
* `divisions=10` Number of graduations on the scale.
* `legends=None` A tuple of strings to display near the slider. These `Label`
instances will be distributed evenly along its length, starting at the bottom
(v) or left (h).
* `legends=None` A tuple of strings to display near the slider. These will be
distributed evenly along its length, starting at the bottom (v) or left (h).
* `fgcolor=None` Color of foreground (the control itself). If `None` the
`Writer` foreground default is used.
* `bgcolor=None` Background color of object. If `None` the `Writer` background
default is used.
* `fontcolor=None` Text color. Defaults to foreground color.
* `bdcolor=False` Color of border. If `False` no border will be drawn. If a
color is provided, a border line will be drawn around the control.
* `prcolor=None` If `active`, in precision mode the white focus border changes
to yellow to for a visual indication. An alternative color can be provided.
`WHITE` will defeat this change.
* `fontcolor=None` Text color. Defaults to foreground color.
* `slotcolor=None` Color for the slot: this is a thin rectangular region in
the centre of the control along which the slider moves. Defaults to the
background color.
* `prcolor=None` If `active`, in precision mode the white focus border changes
to yellow to for a visual indication. An alternative color can be provided.
`WHITE` will defeat this change.
* `callback=dolittle` Callback function which runs whenever the control's
value changes. If the control is `active` it also runs on instantiation. This
enables dynamic color changes. Default is a null function.
* `args=[]` A list/tuple of arguments for above callback.
* `value` The initial value. Default 0.0: slider will be at the bottom (v),
left (h).
* `value=0.0` The initial value: slider will be at the bottom (v), left (h).
* `active=True` Determines whether the control can accept user input.
Methods:
* `greyed_out` Optional argument, boolean or default `val=None`. If
`None` returns the current 'greyed out' status of the control. Otherwise
enables or disables it, showing it in its new state.
* `greyed_out` Optional Boolean argument `val=None`. If `None` returns the
current 'greyed out' status of the control. Otherwise enables or disables it,
showing it in its new state.
* `value=None` Optional float argument. If supplied the slider moves to show
the new value and the callback is triggered. The method constrains the range
to 0.0 to 1.0. The method always returns the control's value.
* `color` Mandatory arg `color` The control is rendered in the selected
color. This supports dynamic color changes.
When the widget has focus, the `increase` and `decrease` buttons adjust the
value. Brief presses make small changes, longer presses cause accelerating
change.
If instantiated as `active`, the floating point widget behaves as per
[section 1.12](./README.md#112-floating-point-widgets). When the widget has
focus, `increase` and `decrease` buttons adjust the value. Brief presses cause
small changes, longer presses cause accelerating change. A long press of
`select` invokes high precision mode.
The callback receives an initial arg being the slider instance followed by any
user supplied args. They can be a bound methods, typically of a `Screen`
@ -1351,12 +1353,12 @@ Constructor mandatory positional args:
2. `row` Location on screen.
3. `col`
Keyword only arguments (all optional):
Optional keyword only arguments:
* `ticks=200` Number of "tick" divisions on scale. Must be divisible by 2.
* `legendcb=None` Callback for populating scale legends (see below).
* `tickcb=None` Callback for setting tick colors (see below).
* `height=0` Pass 0 for a minimum height based on the font height.
* `width=200`
* `width=100`
* `fgcolor=None` Color of foreground (the control itself). If `None` the
`Writer` foreground default is used.
* `bgcolor=None` Background color of object. If `None` the `Writer` background
@ -1368,17 +1370,19 @@ Keyword only arguments (all optional):
`WHITE` will defeat this change.
* `pointercolor=None` Color of pointer. Defaults to `.fgcolor`.
* `fontcolor=None` Color of legends. Default `fgcolor`.
* `callback=dolittle` Callback function which runs whenever the control's
value changes. If the control is `active` it also runs on instantiation. This
enables dynamic color changes. Default is a null function.
* `args=[]` A list/tuple of arguments for above callback.
* `value=0.0` Initial value.
* `active=False` By default the widget is passive. By setting `active=True`
the widget can acquire focus. When current, the value can be changed with the
`increase` and `decrease` buttons. An accelerating algorithm allows rapid
changes with a long button push. Short pushes change the value by a small
amount, currently 0.01.
the widget can acquire focus; its value can then be adjusted with the
`increase` and `decrease` buttons.
Methods:
* `greyed_out` Optional argument, boolean or default `val=None`. If
`None` returns the current 'greyed out' status of the control. Otherwise
enables or disables it, showing it in its new state.
* `greyed_out` Optional Boolean argument `val=None`. If `None` returns the
current 'greyed out' status of the control. Otherwise enables or disables it,
showing it in its new state.
* `value=None` Set or get the current value. Always returns the current value.
A passed `float` is constrained to the range -1.0 <= V <= 1.0 and becomes the
`Scale`'s current value. The `Scale` is updated. Passing `None` enables
@ -1386,6 +1390,12 @@ Methods:
For example code see `gui/demos/active.py`.
If instantiated as `active`, the floating point widget behaves as per
[section 1.12](./README.md#112-floating-point-widgets). When the widget has
focus, `increase` and `decrease` buttons adjust the value. Brief presses cause
small changes, longer presses cause accelerating change. A long press of
`select` invokes high precision mode.
### Callback legendcb
The display window contains 20 ticks comprising two divisions; by default a
@ -1500,8 +1510,7 @@ Keyword only arguments (all optional):
arguments are the `ScaleLog` instance, followed by any user supplied args.
* `value=1.0` Initial value.
* `delta=0.01` This determines the smallest amount of change which can be
achieved with a brief button press. The value is multiplied or divided by
`1+delta`.
achieved with a brief button press. See Control Algorithm below.
* `active=False` Determines whether the widget accepts user input.
Methods:
@ -1509,20 +1518,28 @@ Methods:
A passed `float` is constrained to the range `1.0 <= V <= 10**decades` and
becomes the control's current value. The `ScaleLog` is updated. Always returns
the control's current value. See note below on precision.
* `greyed_out` Optional Boolean argument `val` default `None`. If
`None` returns the current 'greyed out' status of the control. Otherwise
enables or disables it, showing it in its new state.
* `greyed_out` Optional Boolean argument `val=None`. If `None` returns the
current 'greyed out' status of the control. Otherwise enables or disables it,
showing it in its new state.
For example code see `gui/demos/active.py`.
### Control algorithm
When `increase` or `decrease` buttons are briefly pressed, the widget's value
is multiplied or divided by `(1 + delta)`. A long press causes an accelerating
change. This facilitates both small and large changes. The value of `delta`
determines the minimum change possible and hence the level of precision that
the widget can achieve. The choice of `delta` represents a compromise between
precision and usability.
If instantiated as `active`, the floating point widget behaves as per
[section 1.12](./README.md#112-floating-point-widgets). When the widget has
focus, `increase` and `decrease` buttons adjust the value. Brief presses cause
small changes, longer presses cause accelerating change. A long press of
`select` invokes high precision mode.
In normal mode, the amount of change caused by a brief button press is
controlled by the constructor arg `delta`; the choice of this value represents
a compromise between precision and usability.
Owing to the logarithmic nature of the control, a small positive change is
defined by multiplication of the value by `(1 + delta)` and a negative change
corresponds to division by `(1 + delta)`. In precision mode `delta` is
reduced by a factor of 10.
### Callback
@ -1720,9 +1737,9 @@ Optional keyword only arguments:
* `active=True` Enable user input via the `increase` and `decrease` buttons.
Methods:
* `greyed_out` Optional Boolean argument `val` default `None`. If
`None` returns the current 'greyed out' status of the control. Otherwise, if
the widget is `active`, enables or disables it, showing it in its new state.
* `greyed_out` Optional Boolean argument `val=None`. If `None` returns the
current 'greyed out' status of the control. Otherwise enables or disables it,
showing it in its new state.
* `value` Optional argument `val`. If set, adjusts the pointer to
correspond to the new value. The move callback will run. The method constrains
the range to 0.0 to 1.0. Always returns the control's value.

Wyświetl plik

@ -16,6 +16,10 @@ from hardware_setup import ssd
from gui.primitives.delay_ms import Delay_ms
from gui.primitives.switch import Switch
# Globally available singleton objects
display = None # Singleton instance
ssd = None
gc.collect()
__version__ = (0, 1, 0)
@ -26,10 +30,6 @@ async def _g():
pass
type_coro = type(_g())
def setup(d):
global display
display = d
_FIRST = const(0)
_NEXT = const(1)
_PREV = const(2)
@ -38,7 +38,8 @@ _LAST = const(3)
# Wrapper for ssd providing buttons and framebuf compatible methods
class Display:
def __init__(self, ssd, nxt, sel, prev=None, up=None, down=None):
def __init__(self, objssd, nxt, sel, prev=None, up=None, down=None):
global display, ssd
self._next = Switch(nxt)
self._sel = Switch(sel)
self._last = None # Last switch pressed.
@ -48,8 +49,8 @@ class Display:
self._sel.close_func(self._closure, (self._sel, Screen.sel_ctrl))
self._sel.open_func(Screen.unsel)
self.height = ssd.height
self.width = ssd.width
self.height = objssd.height
self.width = objssd.width
# Optional buttons
self._prev = None
@ -66,6 +67,8 @@ class Display:
self._down = Switch(down)
self._down.close_func(self._closure, (self._down, self.do_down))
self._is_grey = False # Not greyed-out
display = self # Populate globals
ssd = objssd
# Reject button presses where a button is already pressed.
# Execute if initialising, if same switch re-pressed or if last switch released
@ -199,6 +202,15 @@ class Display:
class Screen:
current_screen = None
is_shutdown = Event()
_value = None
# Allow a Screen to store an arbitrary object. Retrieval may be
# done by caller, after the Screen instance was deleted
@classmethod
def value(cls, val=None):
if val is not None:
cls._value = val
return cls._value
@classmethod
def next_ctrl(cls):
@ -480,7 +492,7 @@ class Screen:
# Very basic window class. Cuts a rectangular hole in a screen on which content may be drawn
class Window(Screen):
_value = None
def __init__(self, row, col, height, width, *, draw_border=True, bgcolor=None, fgcolor=None):
Screen.__init__(self)
self.row = row
@ -507,12 +519,6 @@ class Window(Screen):
y = self.row
return x, y, x + w, y + h, w, h
@classmethod
def value(cls, val=None): # Mechanism for testing the outcome of a dialog box
if val is not None:
cls._value = val
return cls._value
# Base class for all displayable objects
class Widget:

Wyświetl plik

@ -1,8 +1,8 @@
# active.py micro-gui demo of widgets that respond to user control
# Create SSD instance. Must be done first because of RAM use.
from hardware_setup import ssd
from gui.core.ugui import Screen
import hardware_setup
from gui.core.ugui import Screen, ssd
from gui.core.writer import CWriter
import gui.fonts.arial10 as arial10 # Font for CWriter
from gui.core.colors import *

Wyświetl plik

@ -8,7 +8,7 @@
# Copyright (c) 2021 Peter Hinch
# Create SSD instance. Must be done first because of RAM use.
from hardware_setup import ssd
import hardware_setup
import cmath
import math
@ -16,7 +16,7 @@ import uasyncio as asyncio
from collections import OrderedDict
from gui.core.writer import Writer, CWriter
from gui.core.ugui import Screen
from gui.core.ugui import Screen, ssd
from gui.widgets.graph import PolarGraph, PolarCurve, CartesianGraph, Curve, TSequence
from gui.widgets.label import Label
from gui.widgets.buttons import Button, CloseButton

Wyświetl plik

@ -1,12 +1,12 @@
# screens.py micro-gui demo of multiple screens, dropdowns etc
# Create SSD instance. Must be done first because of RAM use.
from hardware_setup import ssd # Create a display instance
from gui.core.ugui import Screen, Window
import hardware_setup # Create a display instance
from gui.core.ugui import Screen, Window, ssd
from gui.widgets.label import Label
from gui.widgets.buttons import Button, RadioButtons, CloseButton
from gui.widgets.listbox import Listbox, ON_LEAVE
from gui.widgets.listbox import Listbox
from gui.widgets.dropdown import Dropdown
from gui.widgets.dialog import DialogBox
from gui.core.writer import CWriter
@ -80,7 +80,8 @@ class BaseScreen(Screen):
row = 2
Listbox(wri, row, col, callback=lbcb,
elements = ('cat', 'dog', 'aardvark', 'goat', 'pig', 'mouse'),
bdcolor = GREEN, bgcolor = DARKGREEN, also = ON_LEAVE)
bdcolor = GREEN, bgcolor = DARKGREEN,
also = Listbox.ON_LEAVE)
col = 70
Dropdown(wri, row, col, callback=ddcb,
elements = ('hydrogen', 'helium', 'neon', 'xenon', 'new screen'),

Wyświetl plik

@ -1,8 +1,8 @@
# simple.py Minimal micro-gui demo.
# Initialise hardware and framebuf before importing modules.
# Import SSD and Display instances. Must be done first because of RAM use.
from hardware_setup import ssd # Create a display instance
from gui.core.ugui import Screen
import hardware_setup # Create a display instance
from gui.core.ugui import Screen, ssd
from gui.widgets.label import Label
from gui.widgets.buttons import Button, CloseButton

Wyświetl plik

@ -7,9 +7,9 @@
# import gui.demos.tbox
# Initialise hardware and framebuf before importing modules.
from hardware_setup import ssd # Create a display instance
import hardware_setup # Create a display instance
from gui.core.ugui import Screen
from gui.core.ugui import Screen, ssd
from gui.core.writer import CWriter
import uasyncio as asyncio

Wyświetl plik

@ -2,9 +2,9 @@
# Initialise hardware and framebuf before importing modules.
# Create SSD instance. Must be done first because of RAM use.
from hardware_setup import ssd
import hardware_setup
from gui.core.ugui import Screen
from gui.core.ugui import Screen, ssd
from gui.core.writer import CWriter
import gui.fonts.arial10 as arial10 # Font for CWriter
from gui.core.colors import *

Wyświetl plik

@ -4,14 +4,14 @@
# Copyright (c) 2021 Peter Hinch
# Create SSD instance. Must be done first because of RAM use.
from hardware_setup import ssd
import hardware_setup
import urandom
import time
from cmath import rect, pi
import uasyncio as asyncio
from gui.core.ugui import Screen
from gui.core.ugui import Screen, ssd
from gui.core.writer import CWriter
from gui.fonts import font10
from gui.core.colors import *

Wyświetl plik

@ -2,7 +2,6 @@
# Released under the MIT License (MIT). See LICENSE.
# Copyright (c) 2021 Peter Hinch
from micropython import const
from gui.core.ugui import Widget, display
from gui.core.colors import *
@ -11,10 +10,11 @@ dolittle = lambda *_ : None
# Behaviour has issues compared to touch displays because movement between
# entries is sequential. This can affect the choice in when the callback runs.
# It always runs when select is pressed. See 'also' ctor arg.
ON_MOVE = const(1) # Also run whenever the currency moves.
ON_LEAVE = const(2) # Also run on exit from the control.
class Listbox(Widget):
ON_MOVE = 1 # Also run whenever the currency moves.
ON_LEAVE = 2 # Also run on exit from the control.
@staticmethod
def dimensions(writer, elements):
entry_height = writer.height + 2 # Allow a pixel above and below text
@ -81,13 +81,13 @@ class Listbox(Widget):
def do_up(self, _):
if v := self._value:
self.value(v - 1)
if (self.also & ON_MOVE): # Treat as if select pressed
if (self.also & Listbox.ON_MOVE): # Treat as if select pressed
self.do_sel()
def do_down(self, _):
if (v := self._value) < len(self.elements) - 1:
self.value(v + 1)
if (self.also & ON_MOVE):
if (self.also & Listbox.ON_MOVE):
self.do_sel()
# Callback runs if select is pressed. Also (if ON_LEAVE) if user changes
@ -102,5 +102,5 @@ class Listbox(Widget):
self.ev = self._value # Value change detection
def leave(self):
if (self.also & ON_LEAVE) and self._value != self.ev:
if (self.also & Listbox.ON_LEAVE) and self._value != self.ev:
self.do_sel()

Wyświetl plik

@ -16,7 +16,8 @@ import uasyncio as asyncio
# Reason for no tab support in nano-gui/private/reason_for_no_tabs
class Textbox(LinearIO):
def __init__(self, writer, row, col, width, nlines, *, bdcolor=None, fgcolor=None,
def __init__(self, writer, row, col, width, nlines, *,
bdcolor=None, fgcolor=None,
bgcolor=None, clip=True, active=False):
height = nlines * writer.height
devht = writer.device.height

Wyświetl plik

@ -43,7 +43,7 @@ spi = SPI(0, baudrate=30_000_000)
gc.collect() # Precaution before instantiating framebuf
ssd = SSD(spi, pcs, pdc, prst, usd=True)
from gui.core.ugui import Display, setup
from gui.core.ugui import Display
# Create and export a Display instance
# Define control buttons
nxt = Pin(19, Pin.IN, Pin.PULL_UP) # Move to next control
@ -52,4 +52,3 @@ prev = Pin(18, Pin.IN, Pin.PULL_UP) # Move to previous control
increase = Pin(20, Pin.IN, Pin.PULL_UP) # Increase control's value
decrease = Pin(17, Pin.IN, Pin.PULL_UP) # Decrease control's value
display = Display(ssd, nxt, sel, prev, increase, decrease)
setup(display)

Wyświetl plik

@ -43,7 +43,7 @@ spi = SPI(0, baudrate=30_000_000)
gc.collect() # Precaution before instantiating framebuf
ssd = SSD(spi, pcs, pdc, prst, usd=True)
from gui.core.ugui import Display, setup
from gui.core.ugui import Display
# Create and export a Display instance
# Define control buttons
nxt = Pin(19, Pin.IN, Pin.PULL_UP) # Move to next control
@ -52,4 +52,3 @@ prev = Pin(18, Pin.IN, Pin.PULL_UP) # Move to previous control
increase = Pin(20, Pin.IN, Pin.PULL_UP) # Increase control's value
decrease = Pin(17, Pin.IN, Pin.PULL_UP) # Decrease control's value
display = Display(ssd, nxt, sel, prev, increase, decrease)
setup(display)

Wyświetl plik

@ -95,7 +95,7 @@ ssd = SSD(spi, height=135, width=240, dc=pdc, cs=pcs, rst=prst, disp_mode=LANDSC
# Normal portrait display: consistent with TTGO logo at top
# ssd = SSD(spi, height=240, width=135, dc=pdc, cs=pcs, rst=prst, disp_mode=PORTRAIT, display=TDISPLAY)
from gui.core.ugui import Display, setup
from gui.core.ugui import Display
# Create and export a Display instance
# Define control buttons
nxt = Pin(36, Pin.IN, Pin.PULL_UP) # Move to next control
@ -104,7 +104,6 @@ prev = Pin(38, Pin.IN, Pin.PULL_UP) # Move to previous control
increase = Pin(39, Pin.IN, Pin.PULL_UP) # Increase control's value
decrease = Pin(32, Pin.IN, Pin.PULL_UP) # Decrease control's value
display = Display(ssd, nxt, sel, prev, increase, decrease)
setup(display)
# optional
# b1 = Pin(BUTTON1, Pin.IN)