kopia lustrzana https://github.com/peterhinch/micropython-micro-gui
Improve greying out of scale classes.
rodzic
4aeaee5312
commit
8001e16aa0
40
README.md
40
README.md
|
@ -1798,4 +1798,42 @@ variable.
|
|||
|
||||
## 23.2 Use of graphics primitives
|
||||
|
||||
(ssd and display objects)
|
||||
These notes are for those wishing to draw directly to the `Screen` instance.
|
||||
This is done by providing the user `Screen` class with an `after_open()` method
|
||||
which issues the display driver calls.
|
||||
|
||||
The following code instantiates two classes:
|
||||
```python
|
||||
from hardware_setup import display, ssd
|
||||
```
|
||||
The `ssd` object is an instance of the object defined in the display driver. It
|
||||
is a requirement that this is a subclass of `framebuf.FrameBuffer`. Hence `ssd`
|
||||
supports all the graphics primitives provided by `FrameBuffer`. These may be
|
||||
used to draw on the `Screen`.
|
||||
|
||||
The `display` object has an `ssd` bound variable which is a reference to the
|
||||
`ssd` device. The `display` has methods with the same names and args as those
|
||||
of `ssd`. These support greying out. So you can write (for example)
|
||||
```python
|
||||
display.rect(10, 10, 50, 50, RED)
|
||||
```
|
||||
To render in the correct colors it is wise ensure that greying out is disabled
|
||||
prior to calling `display` methods. This is done with
|
||||
```python
|
||||
display.usegrey(False)
|
||||
```
|
||||
There is little point in issuing `display.rect` as it confers no advantage over
|
||||
`ssd.rect`. However the `Display` class adds methods not currently available in
|
||||
`framebuf`. These are listed below.
|
||||
|
||||
* `circle(self, x0, y0, r, color, width =1)` Width specifies the line width.
|
||||
* `fillcircle(self, x0, y0, r, color)`
|
||||
* `clip_rect(self, x, y, w, h, color)` Rectangle with clipped corners.
|
||||
* `fill_clip_rect(self, x, y, w, h, color)`
|
||||
* `print_left(self, writer, x, y, txt, fgcolor=None, bgcolor=None, invert=False)`
|
||||
* `print_centred(self, writer, x, y, text, fgcolor=None, bgcolor=None, invert=False)`
|
||||
|
||||
Hopefully these are self explanatory. The `Display` methods use the `framebuf`
|
||||
convention of `x, y` coordinates rather than the `row, col` system used by
|
||||
micro-gui.
|
||||
|
||||
|
|
|
@ -65,15 +65,19 @@ class Display:
|
|||
self._down.close_func(self.do_down)
|
||||
self._is_grey = False # Not greyed-out
|
||||
|
||||
def print_centred(self, writer, x, y, text, fgcolor=None, bgcolor=None):
|
||||
def print_centred(self, writer, x, y, text, fgcolor=None, bgcolor=None, invert=False):
|
||||
sl = writer.stringlen(text)
|
||||
writer.set_textpos(ssd, y - writer.height // 2, x - sl // 2)
|
||||
if self._is_grey:
|
||||
fgcolor = GREY
|
||||
writer.setcolor(fgcolor, bgcolor)
|
||||
writer.printstring(text)
|
||||
writer.printstring(text, invert)
|
||||
writer.setcolor() # Restore defaults
|
||||
|
||||
def print_left(self, writer, x, y, txt, fgcolor=None, bgcolor=None, invert=False):
|
||||
writer.set_textpos(ssd, y, x)
|
||||
if self._is_grey:
|
||||
fgcolor = GREY
|
||||
writer.setcolor(fgcolor, bgcolor)
|
||||
writer.printstring(txt, invert)
|
||||
writer.setcolor() # Restore defaults
|
||||
|
@ -230,7 +234,6 @@ class Screen:
|
|||
def show(cls, force):
|
||||
for obj in cls.current_screen.displaylist:
|
||||
if obj.visible: # In a buttonlist only show visible button
|
||||
# pend signals an obect with changed contents
|
||||
if force or obj.draw:
|
||||
obj.draw_border()
|
||||
obj.show()
|
||||
|
|
|
@ -48,7 +48,7 @@ class CartesianScreen(Screen):
|
|||
self.g = CartesianGraph(wri, 2, 2, yorigin = 2, fgcolor=GREEN,
|
||||
gridcolor=LIGHTGREEN) # Asymmetric y axis
|
||||
Label(wri, 100, 2, 'Asymmetric axes.')
|
||||
fwdbutton(wri, 2, 130, EmptyScreen, 'Forward', GREEN)
|
||||
fwdbutton(wri, 30, 130, EmptyScreen, 'Forward', GREEN)
|
||||
CloseButton(wri)
|
||||
# At this point in time the Screen and graph have been constructed but
|
||||
# not rendered. If we drew the curves now they would be overwritten by
|
||||
|
@ -76,7 +76,7 @@ class PolarScreen(Screen):
|
|||
def __init__(self):
|
||||
super().__init__()
|
||||
self.g = PolarGraph(wri, 2, 2, fgcolor=GREEN, gridcolor=LIGHTGREEN)
|
||||
fwdbutton(wri, 2, 130, EmptyScreen, 'Forward', GREEN)
|
||||
fwdbutton(wri, 30, 130, EmptyScreen, 'Forward', GREEN)
|
||||
CloseButton(wri)
|
||||
|
||||
def after_open(self): # After graph has been drawn
|
||||
|
@ -94,7 +94,7 @@ class Lissajous(Screen):
|
|||
super().__init__()
|
||||
self.g = CartesianGraph(wri, 2, 2, fgcolor=GREEN, gridcolor=LIGHTGREEN)
|
||||
Label(wri, 100, 2, 'Lissajous figure.')
|
||||
fwdbutton(wri, 2, 130, EmptyScreen, 'Forward', GREEN)
|
||||
fwdbutton(wri, 30, 130, EmptyScreen, 'Forward', GREEN)
|
||||
CloseButton(wri)
|
||||
|
||||
def after_open(self): # After graph has been drawn
|
||||
|
@ -111,7 +111,7 @@ class Lemniscate(Screen):
|
|||
super().__init__()
|
||||
self.g = CartesianGraph(wri, 2, 2, height = 75, fgcolor=GREEN, gridcolor=LIGHTGREEN)
|
||||
Label(wri, 82, 2, 'To infinity and beyond...')
|
||||
fwdbutton(wri, 2, 130, EmptyScreen, 'Forward', GREEN)
|
||||
fwdbutton(wri, 30, 130, EmptyScreen, 'Forward', GREEN)
|
||||
CloseButton(wri)
|
||||
|
||||
def after_open(self): # After graph has been drawn
|
||||
|
@ -130,7 +130,7 @@ class PolarClip(Screen):
|
|||
super().__init__()
|
||||
self.g = PolarGraph(wri, 2, 2, fgcolor=GREEN, gridcolor=LIGHTGREEN)
|
||||
Label(wri, 100, 2, 'Clipping of polar data.')
|
||||
fwdbutton(wri, 2, 130, EmptyScreen, 'Forward', GREEN)
|
||||
fwdbutton(wri, 30, 130, EmptyScreen, 'Forward', GREEN)
|
||||
CloseButton(wri)
|
||||
|
||||
def after_open(self): # After graph has been drawn
|
||||
|
@ -148,7 +148,7 @@ class RTPolar(Screen):
|
|||
super().__init__()
|
||||
self.g = PolarGraph(wri, 2, 2, fgcolor=GREEN, gridcolor=LIGHTGREEN)
|
||||
Label(wri, 100, 2, 'Realtime polar data.')
|
||||
fwdbutton(wri, 2, 130, EmptyScreen, 'Forward', GREEN)
|
||||
fwdbutton(wri, 30, 130, EmptyScreen, 'Forward', GREEN)
|
||||
CloseButton(wri)
|
||||
|
||||
def after_open(self): # After graph has been drawn
|
||||
|
@ -168,7 +168,7 @@ class RTRect(Screen):
|
|||
super().__init__()
|
||||
self.g = CartesianGraph(wri, 2, 2, fgcolor=GREEN, gridcolor=LIGHTGREEN)
|
||||
Label(wri, 100, 2, 'Realtime discontinuous data.')
|
||||
fwdbutton(wri, 2, 130, EmptyScreen, 'Forward', GREEN)
|
||||
fwdbutton(wri, 30, 130, EmptyScreen, 'Forward', GREEN)
|
||||
CloseButton(wri)
|
||||
|
||||
def after_open(self): # After graph has been drawn
|
||||
|
@ -198,7 +198,7 @@ class TSeq(Screen):
|
|||
self.g = CartesianGraph(wri, 2, 2, xorigin = 10, fgcolor=GREEN,
|
||||
gridcolor=LIGHTGREEN, bdcolor=False)
|
||||
Label(wri, 100, 2, 'Time sequence.')
|
||||
fwdbutton(wri, 2, 130, EmptyScreen, 'Forward', GREEN)
|
||||
fwdbutton(wri, 30, 130, EmptyScreen, 'Forward', GREEN)
|
||||
CloseButton(wri)
|
||||
|
||||
def after_open(self): # After graph has been drawn
|
||||
|
@ -241,8 +241,8 @@ class BaseScreen(Screen):
|
|||
Screen.change(d[lb.textvalue()])
|
||||
|
||||
def test():
|
||||
if display.height < 240 or display.width < 320:
|
||||
print(' This test requires a display of at least 320x240 pixels.')
|
||||
if display.height < 128 or display.width < 200:
|
||||
print(' This test requires a display of at least 128x200 pixels.')
|
||||
else:
|
||||
print('Testing micro-gui...')
|
||||
Screen.change(BaseScreen)
|
||||
|
|
|
@ -53,15 +53,18 @@ class FooScreen(Screen):
|
|||
self.rb0 = None
|
||||
self.bs0 = None
|
||||
wri = CWriter(ssd, arial10, GREEN, BLACK, verbose=False)
|
||||
lbltim = Label(wri, 50, 85, 'this is a test', bdcolor=RED)
|
||||
lbltim = Label(wri, 65, 100, 'this is a test', bdcolor=RED)
|
||||
|
||||
m0 = Meter(wri, 20, 240, divisions = 4, ptcolor=YELLOW,
|
||||
label='left', style=Meter.LINE, legends=('0.0', '0.5', '1.0'))
|
||||
m0 = Meter(wri, 10, 240, divisions = 4, ptcolor=YELLOW, height=80, width=15,
|
||||
label='Meter example', style=Meter.BAR, legends=('0.0', '0.5', '1.0'))
|
||||
# Instantiate displayable objects. bgcolor forces complete redraw.
|
||||
dial = Dial(wri, 2, 2, height = 75, ticks = 12, bgcolor=BLACK, bdcolor=None, label=120) # Border in fg color
|
||||
scale = Scale(wri, 2, 100, width = 124, tickcb = tickcb,
|
||||
pointercolor=RED, fontcolor=YELLOW, bdcolor=CYAN)
|
||||
|
||||
row = 105
|
||||
col = 2
|
||||
Label(wri, row, col, 'Normal buttons')
|
||||
# Four Button instances
|
||||
row = 120
|
||||
ht = 30
|
||||
|
@ -73,8 +76,9 @@ class FooScreen(Screen):
|
|||
self.bs = ButtonList(self.callback)
|
||||
self.bs0 = None
|
||||
col+= 50
|
||||
Label(wri, row - 15, col, 'ButtonList')
|
||||
for t in table_buttonset: # Buttons overlay each other at same location
|
||||
button = self.bs.add_button(wri, 120, col, shape=RECTANGLE, textcolor=BLUE, height=30, **t)
|
||||
button = self.bs.add_button(wri, row, col, shape=RECTANGLE, textcolor=BLUE, height=30, **t)
|
||||
if self.bs0 is None: # Save for reset button callback
|
||||
self.bs0 = button
|
||||
|
||||
|
@ -82,21 +86,25 @@ class FooScreen(Screen):
|
|||
col+= 60
|
||||
btn = Button(wri, row, col, height=30, callback=self.rstcb, text='reset', litcolor=RED, fgcolor=GREEN, bgcolor=DARKGREEN)
|
||||
|
||||
col = 2
|
||||
row = 170
|
||||
Label(wri, row, col, 'Radio buttons')
|
||||
# Radio buttons
|
||||
col= 2
|
||||
row = 185
|
||||
self.rb = RadioButtons(BLUE, self.rbcb) # color of selected button
|
||||
self.rb0 = None
|
||||
for t in table_radiobuttons:
|
||||
button = self.rb.add_button(wri, 160, col, textcolor = WHITE,
|
||||
button = self.rb.add_button(wri, row, col, textcolor = WHITE,
|
||||
fgcolor = BLUE, bgcolor = DARKBLUE, shape=CIRCLE, height = 30, **t)
|
||||
if self.rb0 is None: # Save for reset button callback
|
||||
self.rb0 = button
|
||||
col+= 35
|
||||
# Checkbox
|
||||
col+= 35
|
||||
Checkbox(wri, 160, col, callback=self.cbcb)
|
||||
Label(wri, row - 15, col, 'Checkbox and LED')
|
||||
Checkbox(wri, row, col, callback=self.cbcb)
|
||||
col+= 40
|
||||
self.led = LED(wri, 160, col, color=YELLOW, bdcolor=GREEN)
|
||||
self.led = LED(wri, row, col, color=YELLOW, bdcolor=GREEN)
|
||||
CloseButton(wri)
|
||||
asyncio.create_task(run(dial, lbltim, m0, scale))
|
||||
|
||||
|
@ -109,7 +117,7 @@ class FooScreen(Screen):
|
|||
|
||||
def rstcb(self, button):
|
||||
print('Reset button: init ButtonList and RadioButtons')
|
||||
self.bs.value(self.bs0) # BUG This is calling ButtonList.value which calls ._update -> Screen.select which changes currency
|
||||
self.bs.value(self.bs0)
|
||||
self.rb.value(self.rb0)
|
||||
|
||||
def cbcb(self, cb):
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# meter.py Extension to ugui providing a linear "meter" widget.
|
||||
|
||||
# Released under the MIT License (MIT). See LICENSE.
|
||||
# Copyright (c) 2019 Peter Hinch
|
||||
# Copyright (c) 2021 Peter Hinch
|
||||
|
||||
from gui.core.ugui import Widget, display
|
||||
from gui.widgets.label import Label
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
from gui.core.ugui import LinearIO, display
|
||||
from hardware_setup import ssd # Display driver for Writer
|
||||
from gui.core.writer import Writer
|
||||
from gui.core.colors import BLACK
|
||||
from gui.core.colors import *
|
||||
|
||||
dolittle = lambda *_ : None
|
||||
|
||||
|
@ -84,6 +84,7 @@ class Scale(LinearIO):
|
|||
# So pixels per unit value == win_width/200
|
||||
win_width: int = x1 - x0
|
||||
ticks: int = self.ticks # Total # of ticks visible and hidden
|
||||
txtcolor = GREY if self.greyed_out() else self.fontcolor
|
||||
while True:
|
||||
x: int = x0 + (fx * win_width) // 200 # Current X position
|
||||
ys: int # Start Y position for tick
|
||||
|
@ -94,7 +95,7 @@ class Scale(LinearIO):
|
|||
txt = self.legendcb(self._fvalue(iv * 10))
|
||||
tlen = wri.stringlen(txt)
|
||||
Writer.set_textpos(ssd, y0, min(x, x1 - tlen))
|
||||
wri.setcolor(self.fontcolor, self.bgcolor)
|
||||
wri.setcolor(txtcolor, self.bgcolor)
|
||||
wri.printstring(txt)
|
||||
wri.setcolor()
|
||||
ys = self.ldy0 # Large tick
|
||||
|
|
|
@ -15,7 +15,7 @@ from math import log10
|
|||
from gui.core.ugui import LinearIO, display
|
||||
from hardware_setup import ssd # Display driver for Writer
|
||||
from gui.core.writer import Writer
|
||||
from gui.core.colors import BLACK
|
||||
from gui.core.colors import *
|
||||
|
||||
# Null function
|
||||
dolittle = lambda *_ : None
|
||||
|
@ -86,6 +86,7 @@ class ScaleLog(LinearIO):
|
|||
vc = self._value # Current value, corresponds to centre of display
|
||||
d = int(log10(vc)) - 1 # 10**d is start of a decade guaranteed to be outside display
|
||||
vs = max(10 ** d, 1.0) # vs: start value of current decade
|
||||
txtcolor = GREY if self.greyed_out() else self.fontcolor
|
||||
while True: # For each decade until we run out of space
|
||||
done = True # Assume completion
|
||||
xs: float = xc - dw * log10(vc / vs) # x location of start of scale
|
||||
|
@ -102,7 +103,7 @@ class ScaleLog(LinearIO):
|
|||
txt = self.legendcb(vt)
|
||||
tlen = wri.stringlen(txt)
|
||||
Writer.set_textpos(ssd, y0, min(x, x1 - tlen))
|
||||
wri.setcolor(self.fontcolor, self.bgcolor)
|
||||
wri.setcolor(txtcolor, self.bgcolor)
|
||||
wri.printstring(txt)
|
||||
ys = self.ldy0 # Large tick
|
||||
yl = self.ldl
|
||||
|
|
Ładowanie…
Reference in New Issue