kopia lustrzana https://github.com/peterhinch/micropython-micro-gui
Squash bugs in Pushbutton and ScaleLog widgets.
rodzic
a75eda8e85
commit
ccaa1d1797
16
README.md
16
README.md
|
@ -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.
|
|||
 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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Ładowanie…
Reference in New Issue