Squash bugs in Pushbutton and ScaleLog widgets.

pull/8/head
Peter Hinch 2021-07-08 13:18:05 +01:00
rodzic a75eda8e85
commit ccaa1d1797
5 zmienionych plików z 26 dodań i 31 usunięć

Wyświetl plik

@ -1,9 +1,12 @@
# micropython-micro-gui
This is a lightweight, portable, MicroPython GUI library for displays with
drivers subclassed from `framebuf`. It allows input via pushbuttons or via a
switch joystick. Written in Python it runs under a standard MicroPython
firmware build.
This is a lightweight, portable, MicroPython GUI library for displays having
drivers subclassed from `framebuf`. Written in Python it runs under a standard
MicroPython firmware build. Options for data input comprise
* Via from two to five pushbuttons depending on the application.
* Via a switch-based navigation joystick.
* Via two pushbuttons and a rotary encoder such as
[this one](https://www.adafruit.com/product/377).
It is larger and more complex than `nano-gui` owing to the support for input.
It enables switching between screens and launching modal windows. In addition
@ -19,9 +22,6 @@ to a wide range of displays. It is also portable between hosts.
![Image](./images/ttgo.JPG) TTGO T-Display. Add a joystick switch and an SIL
resistor for a simple, inexpensive, WiFi capable system.
An alternative interface consists of two pushbuttons and an encoder such as
[this one](https://www.adafruit.com/product/377).
# Rationale
Touch GUI's have many advantages, however they have drawbacks, principally cost
@ -30,7 +30,7 @@ and the need for calibration (although the
factory calibrated). Another problem is that there are various types of touch
controller, magnifying the difficulty of writing a portable GUI.
Pushbutton input works well and yields astonishingly low cost solutions. A
The input options work well and yield astonishingly low cost solutions. A
network-connected board with a 135x240 color display can be built for under £20
($20?) using the
[TTGO T-Display](http://www.lilygo.cn/prod_view.aspx?TypeId=50044&Id=1126). The

Wyświetl plik

@ -539,7 +539,8 @@ class Widget:
self.draw = True # Signals that obect must be redrawn
self._value = value
# Current colors
# Set colors. Writer colors cannot be None:
# bg == 0, fg == 1 are ultimate (monochrome) defaults.
if fgcolor is None:
fgcolor = writer.fgcolor
if bgcolor is None:

Wyświetl plik

@ -25,9 +25,10 @@ from gui.core.colors import *
class BaseScreen(Screen):
def __init__(self):
def btncb(btn, reg, low, high):
def btncb(btn, reg, low, high): # Button callbck
reg.adjust(low, high)
def rats(btn, ts, reg):
def delete_alarm(btn, ts, reg):
ts.del_region(reg)
super().__init__()
@ -39,7 +40,7 @@ class BaseScreen(Screen):
legends=('0.0', '0.5', '1.0'))
self.ts = Tstat(wri, row, sl.mcol + 5, divisions = 4, ptcolor=YELLOW, height=100, width=15,
style=Tstat.BAR, legends=('0.0', '0.5', '1.0'))
reg = Region(self.ts, 0.4, 0.6, MAGENTA, self.ts_cb)
reg = Region(self.ts, 0.4, 0.55, MAGENTA, self.ts_cb)
al = Region(self.ts, 0.9, 1.0, RED, self.al_cb)
col = self.ts.mcol + 5
self.lbl = Label(wri, row, col, 35, bdcolor=RED, bgcolor=BLACK)
@ -48,14 +49,14 @@ class BaseScreen(Screen):
self.grn = LED(wri, self.led.mrow + 5, col, height=20, color=GREEN, bdcolor=BLACK)
col = self.lbl.mcol + 5
btn = Button(wri, row + 30, col, width=0,
text='down', litcolor=RED, bgcolor=DARKGREEN,
text='down', litcolor=RED,
callback=btncb, args=(reg, 0.2, 0.3))
btn1 = Button(wri, btn.mrow + 5, col, width=btn.width,
text='up', litcolor=RED, bgcolor=DARKGREEN,
text='up', litcolor=RED,
callback=btncb, args=(reg, 0.5, 0.6))
Button(wri, btn1.mrow + 5, col, width=btn.width,
text='del', litcolor=RED, bgcolor=DARKGREEN,
callback=rats, args=(self.ts, al))
text='del', litcolor=RED,
callback=delete_alarm, args=(self.ts, al))
CloseButton(wri)
def after_open(self):

Wyświetl plik

@ -25,18 +25,14 @@ class Button(Widget):
super().__init__(writer, row, col, height, width, fgcolor, bgcolor, bdcolor, False, True)
self.shape = shape
self.radius = height // 2
self.fill = bgcolor is not None # Draw background if color specified
self.litcolor = litcolor
self.textcolor = self.fgcolor if textcolor is None else textcolor
self.orig_fgcolor = self.fgcolor
self.orig_bgcolor = self.bgcolor
self.text = text
self.callback = callback
self.callback_args = args
self.onrelease = onrelease
if self.litcolor is not None:
self.delay = Delay_ms(self.shownormal)
self.litcolor = litcolor if self.fgcolor is not None else None
def show(self):
if self.screen is not Screen.current_screen:
@ -53,8 +49,7 @@ class Button(Widget):
if self.shape == CIRCLE: # Button coords are of top left corner of bounding box
x += self.radius
y += self.radius
if self.fill:
display.fillcircle(x, y, self.radius, self.bgcolor)
display.fillcircle(x, y, self.radius, self.bgcolor)
display.circle(x, y, self.radius, self.fgcolor)
if len(self.text):
display.print_centred(self.writer, x, y, self.text, self.textcolor, self.bgcolor)
@ -62,14 +57,12 @@ class Button(Widget):
xc = x + w // 2
yc = y + h // 2
if self.shape == RECTANGLE: # rectangle
if self.fill:
display.fill_rect(x, y, w, h, self.bgcolor)
display.fill_rect(x, y, w, h, self.bgcolor)
display.rect(x, y, w, h, self.fgcolor)
if len(self.text):
display.print_centred(self.writer, xc, yc, self.text, self.textcolor, self.bgcolor)
elif self.shape == CLIPPED_RECT: # clipped rectangle
if self.fill:
display.fill_clip_rect(x, y, w, h, self.bgcolor)
display.fill_clip_rect(x, y, w, h, self.bgcolor)
display.clip_rect(x, y, w, h, self.fgcolor)
if len(self.text):
display.print_centred(self.writer, xc, yc, self.text, self.textcolor, self.bgcolor)
@ -80,7 +73,7 @@ class Button(Widget):
# control caused a screen change while timer running.
while self.screen is not Screen.current_screen:
await asyncio.sleep_ms(500)
self.bgcolor = self.orig_bgcolor
self.bgcolor = self.def_bgcolor
self.draw = True # Redisplay
def do_sel(self): # Select was pushed
@ -186,7 +179,7 @@ class RadioButtons:
self.lstbuttons.append(button)
button.callback = self._callback
active = len(self.lstbuttons) == self.selected + 1
button.bgcolor = self.highlight if active else button.orig_bgcolor
button.bgcolor = self.highlight if active else button.def_bgcolor
if active:
self.current = button
return button
@ -209,6 +202,6 @@ class RadioButtons:
but.bgcolor = self.highlight
self.current = button
else:
but.bgcolor = but.orig_bgcolor
but.bgcolor = but.def_bgcolor
but.draw = True
self.user_callback(button, *args) # user gets button with args they specified

Wyświetl plik

@ -147,8 +147,8 @@ class ScaleLog(LinearIO):
if isinstance(button, int): # Using an encoder
delta = self.delta * self.encoder_rate * 0.1 if self.precision else self.delta * self.encoder_rate
self.value(self.value() * (1 + delta)**val)
else:
asyncio.create_task(self.btnhan(button, val, d))
else: # val == 1 or -1
asyncio.create_task(self.btnhan(button, val))
async def btnhan(self, button, up):
up = up == 1