kopia lustrzana https://github.com/peterhinch/micropython-micro-gui
Listbox dynamic list: OK with simple lists.
rodzic
c2a4e541f0
commit
f756f00f33
|
@ -1,8 +1,9 @@
|
||||||
# listbox.py Extension to ugui providing the Listbox class
|
# listbox.py Extension to ugui providing the Listbox class
|
||||||
|
|
||||||
# Released under the MIT License (MIT). See LICENSE.
|
# Released under the MIT License (MIT). See LICENSE.
|
||||||
# Copyright (c) 2021-2022 Peter Hinch
|
# Copyright (c) 2021-2024 Peter Hinch
|
||||||
|
|
||||||
|
# 11 Sep 24 Support variable list contents.
|
||||||
# 12 Sep 21 Support for scrolling.
|
# 12 Sep 21 Support for scrolling.
|
||||||
|
|
||||||
from gui.core.ugui import Widget, display
|
from gui.core.ugui import Widget, display
|
||||||
|
@ -14,6 +15,7 @@ dolittle = lambda *_ : None
|
||||||
# entries is sequential. This can affect the choice in when the callback runs.
|
# entries is sequential. This can affect the choice in when the callback runs.
|
||||||
# It always runs when select is pressed. See 'also' ctor arg.
|
# It always runs when select is pressed. See 'also' ctor arg.
|
||||||
|
|
||||||
|
|
||||||
class Listbox(Widget):
|
class Listbox(Widget):
|
||||||
ON_MOVE = 1 # Also run whenever the currency moves.
|
ON_MOVE = 1 # Also run whenever the currency moves.
|
||||||
ON_LEAVE = 2 # Also run on exit from the control.
|
ON_LEAVE = 2 # Also run on exit from the control.
|
||||||
|
@ -30,12 +32,25 @@ class Listbox(Widget):
|
||||||
textwidth = max(writer.stringlen(s) for s in elements) + 4
|
textwidth = max(writer.stringlen(s) for s in elements) + 4
|
||||||
return entry_height, height, dlines, textwidth
|
return entry_height, height, dlines, textwidth
|
||||||
|
|
||||||
def __init__(self, writer, row, col, *,
|
def __init__(
|
||||||
|
self,
|
||||||
|
writer,
|
||||||
|
row,
|
||||||
|
col,
|
||||||
|
*,
|
||||||
elements,
|
elements,
|
||||||
dlines=None, width=None, value=0,
|
dlines=None,
|
||||||
fgcolor=None, bgcolor=None, bdcolor=False,
|
width=None,
|
||||||
fontcolor=None, select_color=DARKBLUE,
|
value=0,
|
||||||
callback=dolittle, args=[], also=0):
|
fgcolor=None,
|
||||||
|
bgcolor=None,
|
||||||
|
bdcolor=False,
|
||||||
|
fontcolor=None,
|
||||||
|
select_color=DARKBLUE,
|
||||||
|
callback=dolittle,
|
||||||
|
args=[],
|
||||||
|
also=0
|
||||||
|
):
|
||||||
|
|
||||||
e0 = elements[0]
|
e0 = elements[0]
|
||||||
# Check whether elements specified as (str, str,...) or ([str, callback, args], [...)
|
# Check whether elements specified as (str, str,...) or ([str, callback, args], [...)
|
||||||
|
@ -43,16 +58,15 @@ class Listbox(Widget):
|
||||||
self.els = elements # Retain original for .despatch
|
self.els = elements # Retain original for .despatch
|
||||||
self.elements = [x[0] for x in elements] # Copy text component
|
self.elements = [x[0] for x in elements] # Copy text component
|
||||||
if callback is not dolittle:
|
if callback is not dolittle:
|
||||||
raise ValueError('Cannot specify callback.')
|
raise ValueError("Cannot specify callback.")
|
||||||
self.cb = self.despatch
|
self.cb = self.despatch
|
||||||
else:
|
else:
|
||||||
self.cb = callback
|
self.cb = callback
|
||||||
self.elements = elements
|
self.elements = elements
|
||||||
if any(not isinstance(s, str) for s in self.elements):
|
if any(not isinstance(s, str) for s in self.elements):
|
||||||
raise ValueError('Invalid elements arg.')
|
raise ValueError("Invalid elements arg.")
|
||||||
# Calculate dimensions
|
# Calculate dimensions
|
||||||
self.entry_height, height, self.dlines, tw = self.dimensions(
|
self.entry_height, height, self.dlines, tw = self.dimensions(writer, self.elements, dlines)
|
||||||
writer, self.elements, dlines)
|
|
||||||
if width is None:
|
if width is None:
|
||||||
width = tw # Text width
|
width = tw # Text width
|
||||||
|
|
||||||
|
@ -71,6 +85,13 @@ class Listbox(Widget):
|
||||||
self._value = value # No callback until user selects
|
self._value = value # No callback until user selects
|
||||||
self.ev = value # Value change detection
|
self.ev = value # Value change detection
|
||||||
|
|
||||||
|
def update(self): # Elements list has changed.
|
||||||
|
l = len(self.elements)
|
||||||
|
nl = self.dlines # No. of lines that can fit in window
|
||||||
|
self.ntop = max(0, min(self.ntop, l - nl))
|
||||||
|
self._value = min(self._value, l - 1)
|
||||||
|
self.show()
|
||||||
|
|
||||||
def show(self):
|
def show(self):
|
||||||
if not super().show(False): # Clear to self.bgcolor
|
if not super().show(False): # Clear to self.bgcolor
|
||||||
return
|
return
|
||||||
|
@ -95,7 +116,9 @@ class Listbox(Widget):
|
||||||
text = text[:nch]
|
text = text[:nch]
|
||||||
if n == self._value:
|
if n == self._value:
|
||||||
display.fill_rect(x, y + 1, self.width, eh - 1, self.select_color)
|
display.fill_rect(x, y + 1, self.width, eh - 1, self.select_color)
|
||||||
display.print_left(self.writer, x + 2, y + 1, text, self.fontcolor, self.select_color)
|
display.print_left(
|
||||||
|
self.writer, x + 2, y + 1, text, self.fontcolor, self.select_color
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
display.print_left(self.writer, x + 2, y + 1, text, self.fontcolor, self.bgcolor)
|
display.print_left(self.writer, x + 2, y + 1, text, self.fontcolor, self.bgcolor)
|
||||||
y += eh
|
y += eh
|
||||||
|
@ -112,6 +135,8 @@ class Listbox(Widget):
|
||||||
return self.elements[self._value]
|
return self.elements[self._value]
|
||||||
else: # set value by text
|
else: # set value by text
|
||||||
try:
|
try:
|
||||||
|
# print(text)
|
||||||
|
# print(self.elements.index(text))
|
||||||
v = self.elements.index(text)
|
v = self.elements.index(text)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
v = None
|
v = None
|
||||||
|
@ -127,7 +152,7 @@ class Listbox(Widget):
|
||||||
elif vnew < self.ntop:
|
elif vnew < self.ntop:
|
||||||
self.ntop = vnew
|
self.ntop = vnew
|
||||||
self.value(vnew)
|
self.value(vnew)
|
||||||
if (self.also & Listbox.ON_MOVE): # Treat as if select pressed
|
if self.also & Listbox.ON_MOVE: # Treat as if select pressed
|
||||||
self.do_sel()
|
self.do_sel()
|
||||||
|
|
||||||
def do_adj(self, _, val):
|
def do_adj(self, _, val):
|
||||||
|
|
Ładowanie…
Reference in New Issue