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 cs_old = cls.current_screen
if cs_old is not None: # Leaving an existing screen if cs_old is not None: # Leaving an existing screen
for entry in cls.current_screen.tasklist: for entry in cls.current_screen.tasklist:
if entry[1]: # To be cancelled on screen change if entry[1] or not forward: # To be cancelled on screen change
entry[0].cancel() entry[0].cancel() # or on closing the screen
cs_old.on_hide() # Optional method in subclass cs_old.on_hide() # Optional method in subclass
if forward: if forward:
if isinstance(cls_new_screen, type): if isinstance(cls_new_screen, type):
@ -530,7 +530,7 @@ class Widget:
if fgcolor is None: if fgcolor is None:
fgcolor = writer.fgcolor fgcolor = writer.fgcolor
if bgcolor is None: if bgcolor is None:
bgcolor = BGCOLOR bgcolor = writer.bgcolor
if bdcolor is None: if bdcolor is None:
bdcolor = fgcolor bdcolor = fgcolor
self.fgcolor = fgcolor self.fgcolor = fgcolor
@ -549,9 +549,6 @@ class Widget:
def warning(self): def warning(self):
print('Warning: attempt to create {} outside screen dimensions.'.format(self.__class__.__name__)) 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 def value(self, val=None): # User method to get or set value
if val is not None: if val is not None:
if type(val) is float: 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. # Released under the MIT License (MIT). See LICENSE.
# Copyright (c) 2021 Peter Hinch # Copyright (c) 2021 Peter Hinch
@ -18,7 +18,7 @@ from gui.core.colors import *
# Widgets # Widgets
from gui.widgets.label import Label from gui.widgets.label import Label
from gui.widgets.buttons import Button, CloseButton 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'): def fwdbutton(wri, row, col, cls_screen, text='Next'):
@ -94,13 +94,13 @@ class VScreen(Screen):
fwdbutton(wri, 200, 2, BackScreen, 'Forward') fwdbutton(wri, 200, 2, BackScreen, 'Forward')
CloseButton(wri) CloseButton(wri)
# Set up random vector display with two pointers # 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))
self.reg_task(ptr_test(dial)) self.reg_task(ptr_test(dial))
# Set up clock display: instantiate labels # Set up clock display: instantiate labels
lbldate = Label(wri, 110, 2, 200, **labels) lbldate = Label(wri, 110, 2, 200, **labels)
lbltim = Label(wri, 150, 2, 80, **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)) self.reg_task(aclock(dial, lbldate, lbltim))
def test(): def test():

Wyświetl plik

@ -13,10 +13,9 @@ dolittle = lambda *_ : None
class Button(Widget): class Button(Widget):
lit_time = 1000 lit_time = 1000
long_press_time = 1000
def __init__(self, writer, row, col, *, shape=RECTANGLE, height=20, width=50, def __init__(self, writer, row, col, *, shape=RECTANGLE, height=20, width=50,
fgcolor=None, bgcolor=None, bdcolor=False, textcolor=None, litcolor=None, text='', 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) sl = writer.stringlen(text)
if shape == CIRCLE: # Only height need be specified if shape == CIRCLE: # Only height need be specified
width = max(sl, height) width = max(sl, height)
@ -35,8 +34,6 @@ class Button(Widget):
self.callback = callback self.callback = callback
self.callback_args = args self.callback_args = args
self.onrelease = onrelease self.onrelease = onrelease
self.lp_callback = lp_callback
self.lp_args = lp_args
if self.litcolor is not None: if self.litcolor is not None:
self.delay = Delay_ms(self.shownormal) self.delay = Delay_ms(self.shownormal)
self.litcolor = litcolor if self.fgcolor is not None else None self.litcolor = litcolor if self.fgcolor is not None else None
@ -98,9 +95,6 @@ class Button(Widget):
if self.onrelease: if self.onrelease:
self.callback(self, *self.callback_args) # Callback not a bound method so pass self 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. # 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. # Note that if the bottom screen is closed, the application terminates.
class CloseButton(Button): 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) polar(display, origin + conj(start), chev*cw*uv, color)
class Pointer(): class Pointer:
def __init__(self, dial): def __init__(self, dial):
self.dial = dial self.dial = dial
dial.vectors.add(self) dial.vectors.add(self)
@ -59,7 +59,7 @@ class Pointer():
class Dial(Widget): class Dial(Widget):
CLOCK = 0 CLOCK = 0
COMPASS = 1 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, fgcolor=None, bgcolor=None, bdcolor=False, ticks=4,
label=None, style=0, pip=None): label=None, style=0, pip=None):
super().__init__(writer, row, col, height, height, fgcolor, bgcolor, bdcolor) 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 return super().show() # Draw or erase border
class CartesianGraph(Graph): 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): gridcolor=None, xdivs=10, ydivs=10, xorigin=5, yorigin=5):
super().__init__(writer, row, col, height, width, fgcolor, bgcolor, bdcolor, gridcolor) super().__init__(writer, row, col, height, width, fgcolor, bgcolor, bdcolor, gridcolor)
self.xdivs = xdivs self.xdivs = xdivs

Wyświetl plik

@ -11,14 +11,12 @@ from gui.widgets.label import Label
dolittle = lambda *_ : None dolittle = lambda *_ : None
# *********** SLIDER CLASSES *********** # *********** 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 _SLIDE_DEPTH = const(6) # Must be divisible by 2
_TICK_VISIBLE = const(3) # No. of tick pixels visible either side of slider _TICK_VISIBLE = const(3) # No. of tick pixels visible either side of slider
_HALF_SLOT_WIDTH = const(2) # Width of slot /2 _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): class Slider(LinearIO):
def __init__(self, writer, row, col, *, def __init__(self, writer, row, col, *,
height=100, width=20, divisions=10, legends=None, 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