kopia lustrzana https://github.com/peterhinch/micropython-micro-gui
README update. Remove redundant code.
rodzic
64d75fe273
commit
2a802793b4
|
@ -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:
|
||||
|
|
|
@ -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():
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
Ładowanie…
Reference in New Issue