Porównaj commity

...

2 Commity

Autor SHA1 Wiadomość Data
peterhinch 310957e518 Fix epaper demo initial refresh. 2023-06-01 12:16:35 +01:00
peterhinch d886989f7e Simplfy calendar demo. Fix Label where text is None. 2023-06-01 08:48:52 +01:00
5 zmienionych plików z 65 dodań i 67 usunięć

Wyświetl plik

@ -3090,26 +3090,40 @@ connecting to any host. The hardware_setup.py should be copied or adapted from
`setup_examples/pico_epaper_42_pico.py`. If using the socket, default args may
be used (see code comment).
After an initial refresh to clear the screen the driver is put into partial
mode. This provides a reasonably quick and visually satisfactory response to
user inputs such as button events. See the
Some attention to detail is required to handle the refresh characteristics.
The application must wait for the initial full refresh (which occurs
automatically) before putting the display into partial mode. This is done by
the screen constructor issuing
```python
asyncio.create_task(set_partial())
```
to run
```python
async def set_partial(): # Ensure 1st refresh is a full refresh
await Screen.rfsh_done.wait() # Wait for first refresh to end
ssd.set_partial()
```
The application then runs in partial mode with a reasonably quick and visually
satisfactory response to user inputs such as button events. See the
[epaper demo](https://github.com/peterhinch/micropython-micro-gui/blob/main/gui/demos/epaper.py).
This provides for a full refresh via the `reset` button. Provision of full
refresh is application dependent. It should be done as follows:
It is likely that applications will provide a full refresh method to clear any
ghosting. The demo provides for a full refresh via the `reset` button. A full
refresh should be done as follows:
```python
async def full_refresh():
Screen.rfsh_done.clear() # Enable completion flag
await Screen.rfsh_done.wait() # Wait for a refresh to end
ssd.set_full()
Screen.rfsh_done.clear() # Enable completion flag
Screen.rfsh_done.clear() # Re-enable completion flag
await Screen.rfsh_done.wait() # Wait for a single full refresh to end
ssd.set_partial()
ssd.set_partial() # Subsequent refreshes are partial
```
The driver for the supported display uses 1-bit color mapping: this means that
greying-out has no visible effect. Greyed-out controls cannot accept the focus
and are therefore disabled but appearance is unchanged.
and are therefore disabled but appearance is unchanged. `nano-gui` has a 2-bit
driver which supports greyscales, but there is no partial support so this is
unsuitable for `micro_gui`.
###### [Contents](./README.md#0-contents)

Wyświetl plik

@ -28,6 +28,8 @@ class BaseScreen(Screen):
row = 2
rows = 6
cols = 7
self.ncells = cols * (rows - 1) # Row 0 has day labels
self.last_cell = cols * rows
colwidth = 35
self.lbl = Label(wri, row, col, text = (colwidth + 4) * cols, justify=Label.CENTRE)
row = self.lbl.mrow
@ -72,49 +74,28 @@ class BaseScreen(Screen):
d.now()
self.update()
def update(self):
def cell():
if cur.year == today.year and cur.month == today.month and mday == today.mday: # Today
d["fgcolor"] = RED
elif mday == cur.mday: # Currency
d["fgcolor"] = YELLOW
elif mday in sundays:
d["fgcolor"] = BLUE
else:
d["fgcolor"] = GREEN
d["text"] = str(mday)
self.grid[idx] = d
def days(self, month_length): # Produce content for every cell
for n in range(self.ncells + 1):
yield str(n + 1) if n < month_length else ""
today = DateCal()
def update(self):
grid = self.grid
cur = self.date # Currency
self.lbl.value(f"{DateCal.months[cur.month - 1]} {cur.year}")
d = {} # Args for Label.value
wday = 0
wday_1 = cur.wday_n(1) # Weekday of 1st of month
mday = 1
seek = True
sundays = cur.mday_list(6)
for idx in range(7, self.grid.ncells):
if seek: # Find column for 1st of month
if wday < wday_1:
self.grid[idx] = ""
wday += 1
else:
seek = False
if not seek:
if mday <= cur.month_length:
cell()
mday += 1
else:
self.grid[idx] = ""
idx = 7 # Where another row would be needed, roll over to top few cells.
while mday <= cur.month_length:
cell()
idx += 1
mday += 1
# Populate day number cells
values = self.days(cur.month_length) # Instantiate generator
idx_1 = 7 + cur.wday_n(1) # Index of 1st of month
grid[idx_1 : self.last_cell] = values # Populate from mday 1 to last cell
grid[7 : idx_1] = values # Populate cells before 1st of month
# Color cells of Sunday, today and currency. In collisions (e.g. today==Sun)
# last color applied is effective
grid[1:6, 6] = {"fgcolor": BLUE} # Sunday color
grid[idx_1 + cur.mday - 1] = {"fgcolor": YELLOW} # Currency
today = DateCal()
if cur.year == today.year and cur.month == today.month: # Today is in current month
grid[idx_1 + today.mday - 1] = {"fgcolor": RED}
self.lblnow.value(f"{today.day_str} {today.mday} {today.month_str} {today.year}")
def test():
print('Calendar demo.')
Screen.change(BaseScreen) # A class is passed here, not an instance.

Wyświetl plik

@ -47,6 +47,9 @@ async def full_refresh():
await Screen.rfsh_done.wait() # Wait for a single full refresh to end
ssd.set_partial()
async def set_partial(): # Ensure 1st refresh is a full refresh
await Screen.rfsh_done.wait() # Wait for first refresh to end
ssd.set_partial()
class FooScreen(Screen):
def __init__(self):
@ -161,6 +164,7 @@ class FooScreen(Screen):
Label(wri_large, lbl.mrow + 5, col, "y = sinc(x)")
CloseButton(wri, bgcolor=BLACK)
asyncio.create_task(set_partial()) # After 1st full refresh
asyncio.create_task(run(dial, lbltim, m0, scale))
def callback(self, button, buttons, val):
@ -186,7 +190,6 @@ class FooScreen(Screen):
x += 0.05
Curve(self.graph, None, populate())
asyncio.create_task(full_refresh())
async def run(dial, lbltim, m0, scale):

Wyświetl plik

@ -28,24 +28,25 @@ class Label(Widget):
self.value(text, invert)
def value(self, text=None, invert=False, fgcolor=None, bgcolor=None, bdcolor=None, justify=None):
sl = self.writer.stringlen(text)
if justify is None:
justify = self.justify
self.tcol = self.col # Default is left justify
if sl > self.width: # Clip
font = self.writer.font
pos = 0
n = 0
for ch in text:
pos += font.get_ch(ch)[2] # width of current char
if pos > self.width:
break
n += 1
text = text[: n]
elif justify == 1: # Centre
self.tcol = self.col + (self.width - sl) // 2
elif justify == 2: # Right
self.tcol = self.col + self.width - sl
if text is not None:
sl = self.writer.stringlen(text)
if justify is None:
justify = self.justify
self.tcol = self.col # Default is left justify
if sl > self.width: # Clip
font = self.writer.font
pos = 0
n = 0
for ch in text:
pos += font.get_ch(ch)[2] # width of current char
if pos > self.width:
break
n += 1
text = text[: n]
elif justify == 1: # Centre
self.tcol = self.col + (self.width - sl) // 2
elif justify == 2: # Right
self.tcol = self.col + self.width - sl
txt = super().value(text)
self.draw = True # Redraw unconditionally: colors may have changed.

Wyświetl plik

@ -56,4 +56,3 @@ decrease = Pin(17, Pin.IN, Pin.PULL_UP) # Decrease control's value
# display = Display(ssd, nxt, sel, prev) # 3-button mode
display = Display(ssd, nxt, sel, prev, increase, decrease) # 5-button mode
ssd.wait_until_ready() # Blocking wait
ssd.set_partial() # Subsequent refreshes are partial