README update. Remove redundant code.

pull/8/head
Peter Hinch 2021-06-10 13:23:18 +01:00
rodzic 64d75fe273
commit 2a802793b4
8 zmienionych plików z 1348 dodań i 181 usunięć

1374
README.md

Plik diff jest za duży Load Diff

Wyświetl plik

@ -241,8 +241,8 @@ class Screen:
cs_old = cls.current_screen
if cs_old is not None: # Leaving an existing screen
for entry in cls.current_screen.tasklist:
if entry[1]: # To be cancelled on screen change
entry[0].cancel()
if entry[1] or not forward: # To be cancelled on screen change
entry[0].cancel() # or on closing the screen
cs_old.on_hide() # Optional method in subclass
if forward:
if isinstance(cls_new_screen, type):
@ -530,7 +530,7 @@ class Widget:
if fgcolor is None:
fgcolor = writer.fgcolor
if bgcolor is None:
bgcolor = BGCOLOR
bgcolor = writer.bgcolor
if bdcolor is None:
bdcolor = fgcolor
self.fgcolor = fgcolor
@ -549,9 +549,6 @@ class Widget:
def warning(self):
print('Warning: attempt to create {} outside screen dimensions.'.format(self.__class__.__name__))
def greyed_out(self):
return self._greyed_out # Subclass may be greyed out
def value(self, val=None): # User method to get or set value
if val is not None:
if type(val) is float:

Wyświetl plik

@ -1,4 +1,4 @@
# vtest.py Test/demo of VectorDial for micro-gui
# vtest.py Test/demo of Dial for micro-gui
# Released under the MIT License (MIT). See LICENSE.
# Copyright (c) 2021 Peter Hinch
@ -18,7 +18,7 @@ from gui.core.colors import *
# Widgets
from gui.widgets.label import Label
from gui.widgets.buttons import Button, CloseButton
from gui.widgets.vectors import Pointer, VectorDial
from gui.widgets.dial import Pointer, Dial
def fwdbutton(wri, row, col, cls_screen, text='Next'):
@ -94,13 +94,13 @@ class VScreen(Screen):
fwdbutton(wri, 200, 2, BackScreen, 'Forward')
CloseButton(wri)
# Set up random vector display with two pointers
dial = VectorDial(wri, 2, 2, height = 100, ticks = 12, fgcolor = YELLOW, arrow = True)
dial = Dial(wri, 2, 2, height = 100, ticks = 12, fgcolor = YELLOW, style=Dial.COMPASS)
self.reg_task(ptr_test(dial))
self.reg_task(ptr_test(dial))
# Set up clock display: instantiate labels
lbldate = Label(wri, 110, 2, 200, **labels)
lbltim = Label(wri, 150, 2, 80, **labels)
dial = VectorDial(wri, 2, 120, height = 100, ticks = 12, fgcolor = GREEN, pip = GREEN)
dial = Dial(wri, 2, 120, height = 100, ticks = 12, fgcolor = GREEN, pip = GREEN)
self.reg_task(aclock(dial, lbldate, lbltim))
def test():

Wyświetl plik

@ -13,10 +13,9 @@ dolittle = lambda *_ : None
class Button(Widget):
lit_time = 1000
long_press_time = 1000
def __init__(self, writer, row, col, *, shape=RECTANGLE, height=20, width=50,
fgcolor=None, bgcolor=None, bdcolor=False, textcolor=None, litcolor=None, text='',
callback=dolittle, args=[], onrelease=False, lp_callback=dolittle, lp_args=[]):
callback=dolittle, args=[], onrelease=False):
sl = writer.stringlen(text)
if shape == CIRCLE: # Only height need be specified
width = max(sl, height)
@ -35,8 +34,6 @@ class Button(Widget):
self.callback = callback
self.callback_args = args
self.onrelease = onrelease
self.lp_callback = lp_callback
self.lp_args = lp_args
if self.litcolor is not None:
self.delay = Delay_ms(self.shownormal)
self.litcolor = litcolor if self.fgcolor is not None else None
@ -98,9 +95,6 @@ class Button(Widget):
if self.onrelease:
self.callback(self, *self.callback_args) # Callback not a bound method so pass self
def longsel(self): # Select was long pressed
self.lp_callback(self, *self.lp_args)
# Preferred way to close a screen or dialog. Produces an X button at the top RHS.
# Note that if the bottom screen is closed, the application terminates.
class CloseButton(Button):

Wyświetl plik

@ -35,7 +35,7 @@ def arrow(display, origin, vec, lc, color, ccw=cmath.exp(3j * cmath.pi/4), cw=cm
polar(display, origin + conj(start), chev*cw*uv, color)
class Pointer():
class Pointer:
def __init__(self, dial):
self.dial = dial
dial.vectors.add(self)
@ -59,7 +59,7 @@ class Pointer():
class Dial(Widget):
CLOCK = 0
COMPASS = 1
def __init__(self, writer, row, col, *, height=50,
def __init__(self, writer, row, col, *, height=100,
fgcolor=None, bgcolor=None, bdcolor=False, ticks=4,
label=None, style=0, pip=None):
super().__init__(writer, row, col, height, height, fgcolor, bgcolor, bdcolor)

Wyświetl plik

@ -177,7 +177,7 @@ class Graph(Widget):
return super().show() # Draw or erase border
class CartesianGraph(Graph):
def __init__(self, writer, row, col, *, height=90, width = 120, fgcolor=None, bgcolor=None, bdcolor=None,
def __init__(self, writer, row, col, *, height=90, width=120, fgcolor=None, bgcolor=None, bdcolor=None,
gridcolor=None, xdivs=10, ydivs=10, xorigin=5, yorigin=5):
super().__init__(writer, row, col, height, width, fgcolor, bgcolor, bdcolor, gridcolor)
self.xdivs = xdivs

Wyświetl plik

@ -11,14 +11,12 @@ from gui.widgets.label import Label
dolittle = lambda *_ : None
# *********** SLIDER CLASSES ***********
# A slider's text items lie outside its bounding box (area sensitive to touch)
# A slider's text items lie outside its bounding box.
_SLIDE_DEPTH = const(6) # Must be divisible by 2
_TICK_VISIBLE = const(3) # No. of tick pixels visible either side of slider
_HALF_SLOT_WIDTH = const(2) # Width of slot /2
# Slider ontrols have been rewritten to avoid the need for reading back framebuffer
# contents as this is unreliable on RA8875.
class Slider(LinearIO):
def __init__(self, writer, row, col, *,
height=100, width=20, divisions=10, legends=None,

Wyświetl plik

@ -1,120 +0,0 @@
# vectors.py Extension to ugui providing vector display
# Released under the MIT License (MIT). See LICENSE.
# Copyright (c) 2021 Peter Hinch
# VectorDial class is display-only: no practical way to perform
# input on multiple vectors
from micropython import const
from gui.core.ugui import Screen, Widget, display
from gui.widgets.label import Label
from gui.core.colors import *
import cmath
conj = lambda v : v.real - v.imag * 1j # Complex conjugate
# Draw a vector in complex coordinates. Origin and end are complex.
# End is relative to origin.
def pline(origin, vec, color):
xs, ys = origin.real, origin.imag
display.line(round(xs), round(ys), round(xs + vec.real), round(ys - vec.imag), color)
# Draw an arrow; origin and vec are complex, scalar lc defines length of chevron.
# cw and ccw are unit vectors of +-3pi/4 radians for chevrons.
def arrow(origin, vec, lc, color):
ccw = cmath.exp(3j * cmath.pi/4) # Unit vectors
cw = cmath.exp(-3j * cmath.pi/4)
length, theta = cmath.polar(vec)
uv = cmath.rect(1, theta) # Unit rotation vector
start = -vec
if length > 3 * lc: # If line is long
ds = cmath.rect(lc, theta)
start += ds # shorten to allow for length of tail chevrons
chev = lc + 0j
pline(origin, vec, color) # Origin to tip
pline(origin, start, color) # Origin to tail
pline(origin + conj(vec), chev*ccw*uv, color) # Tip chevron
pline(origin + conj(vec), chev*cw*uv, color)
if length > lc: # Confusing appearance of very short vectors with tail chevron
pline(origin + conj(start), chev*ccw*uv, color) # Tail chevron
pline(origin + conj(start), chev*cw*uv, color)
# Vector display
class Pointer:
def __init__(self, dial):
dial.vectors.add(self)
self.dial = dial
self.color = WHITE
self.val = 0j
def value(self, v=None, color=None):
if color is not None:
self.color = color
if v is not None:
if isinstance(v, complex):
l = cmath.polar(v)[0]
newval = v / l if l > 1 else v # Max length = 1.0
else:
raise ValueError('Pointer value must be complex.')
if v != self.val and self.dial.screen is Screen.current_screen:
self.show(newval)
self.val = newval
return self.val
def show(self, newval=None):
v = self.val if newval is None else newval
dial = self.dial
color = self.color
vor = dial.vor # Dial's origin as a vector
r = dial.radius * (1 - dial.TICKLEN)
if dial.arrow:
arrow(vor, r * v, 5, color)
else:
pline(vor, r * v, color)
self.dial.draw = True # Mark dial as dirty
class VectorDial(Widget):
TICKLEN = 0.1
def __init__(self, writer, row, col, *,
height=100, fgcolor=None, bgcolor=None, bdcolor=None,
ticks=4, arrow=False, pip=None):
super().__init__(writer, row, col, height, height,
fgcolor, bgcolor, bdcolor, 0, False) # Display only
self.arrow = arrow
self.pip = self.fgcolor if pip is None else pip
radius = height / 2
self.radius = radius
self.ticks = ticks
self.xorigin = col + radius
self.yorigin = row + radius
self.vor = self.xorigin + 1j * self.yorigin # Origin as a vector
self.vectors = set()
self.draw = True
def show(self):
if super().show():
# cache bound variables
ticks = self.ticks
radius = self.radius
xo = self.xorigin
yo = self.yorigin
vor = self.vor
vtstart = (1 - self.TICKLEN) * radius + 0j # start of tick
vtick = self.TICKLEN * radius + 0j # tick
vrot = cmath.exp(2j * cmath.pi/ticks) # unit rotation
for _ in range(ticks):
pline(vor + conj(vtstart), vtick, self.fgcolor)
vtick *= vrot
vtstart *= vrot
display.circle(xo, yo, radius, self.fgcolor)
vshort = 1000 # Length of shortest vector
for v in self.vectors:
val = v.value() * radius # val is complex
vshort = min(vshort, cmath.polar(val)[0])
v.show()
if isinstance(self.pip, tuple) and vshort > 9:
display.fillcircle(xo, yo, 3, self.pip)
self.draw = False