Ankerseite: Werte über Tastatur änderbar
This commit is contained in:
		
							parent
							
								
									986d222a98
								
							
						
					
					
						commit
						dafcfaca6b
					
				
							
								
								
									
										110
									
								
								cfgmenu.py
								
								
								
								
							
							
						
						
									
										110
									
								
								cfgmenu.py
								
								
								
								
							|  | @ -5,44 +5,94 @@ Menüsystem für Konfiguration(en) | ||||||
| 
 | 
 | ||||||
| class MenuItem(): | class MenuItem(): | ||||||
| 
 | 
 | ||||||
|     def __init__(self, itmname): |     def __init__(self, valtype, label, value=None, unit=''): | ||||||
|         self.name = itmname |         validtypes = ('int', 'bool') | ||||||
|         self.label = None |         valtype = valtype.lower() # Groß- und Kleinschreibung lassen wir gemischt zu | ||||||
|         self.value = None |         if valtype not in validtypes: | ||||||
|         self.steps = (1,) |             raise TypeError(f"Invalid value type: '{valtype}'. Only supported: {validtypes}") | ||||||
|  |         self.label = label # Anzeigetext des Menüeintrag | ||||||
|  |         self.value = value # Zugeordneter Wert für diesen Eintrag | ||||||
|  |         self.unit = unit | ||||||
|  |         self._type = valtype | ||||||
|  |         self._min = 0 | ||||||
|  |         self._max = 99999 | ||||||
|  |         self.steps = (1, 10, 100, 1000) # Sprungmöglichkeiten für +/- Tasten | ||||||
|  |         self.step = 0 # index into tuple above | ||||||
|  |         self.position = None # Menüposition gezählt von 0 an | ||||||
|  | 
 | ||||||
|  |     def setRange(self, valmin, valmax, steps): | ||||||
|  |         self.min = valmin | ||||||
|  |         self.max = valmax | ||||||
|  |         self.steps = steps | ||||||
| 
 | 
 | ||||||
|     def setValue(self, val): |     def setValue(self, val): | ||||||
|         self.value = val |         if self._type == 'int': | ||||||
|  |             if val >= self._min and val <= self._max: | ||||||
|  |                 self.value = val | ||||||
|  |                 return True | ||||||
|  |         elif self.type == 'bool': | ||||||
|  |             self.value = val | ||||||
|  |             return True | ||||||
|  |         return False | ||||||
| 
 | 
 | ||||||
| class Menu(): | class Menu(): | ||||||
| 
 | 
 | ||||||
|     def __init__(self): |     def __init__(self, title, x, y): | ||||||
|         title = None |         self.title = title | ||||||
|         x = 0 |         self.items = {} # Items über Schlüssel zugreifbar  | ||||||
|         y = 0 |         self.activeitem = -1 # Noch nichts aktiv | ||||||
|         w = 100 |         self._x = x | ||||||
|         h = 20 |         self._y = y | ||||||
|         items = [] |         self._w = 100 | ||||||
|         itm_active = -1 # nothing activated |         self._h = 20 | ||||||
|         self._index = -1 |         self._index = [] # Mapping zwischen Index(Position) und Schlüssel | ||||||
| 
 |         self._iter_index = 0 | ||||||
|     def addItem(self, label): |  | ||||||
|         itm = MenuItem(label) |  | ||||||
|         items.append(itm) |  | ||||||
| 
 |  | ||||||
| class MenuIter(): |  | ||||||
| 
 |  | ||||||
|     def __init__(self, menu): |  | ||||||
|         self._items = menu.items |  | ||||||
|         self._class_size = len(self._items) |  | ||||||
|         self._index = 0 |  | ||||||
| 
 | 
 | ||||||
|     def __iter__(self): |     def __iter__(self): | ||||||
|         return self |         return self | ||||||
| 
 | 
 | ||||||
|     def __next__(self): |     def __next__(self): | ||||||
|         if self._index < self._class_size: |         if self._iter_index < len(self.items): | ||||||
|             itm = items[self._index] |             itm = self.items[self._index[self._iter_index]] | ||||||
|             self._index += 1 |             self._iter_index += 1 | ||||||
|             return itm |             return itm | ||||||
|         raise StopIteration  |         self._iter_index = 0 | ||||||
|  |         raise StopIteration | ||||||
|  | 
 | ||||||
|  |     def addItem(self, key, label, valtype, value=None, unit=''): | ||||||
|  |         if key in self.items.keys(): | ||||||
|  |             raise KeyError(f"Duplicate menu item key: '{key}'") | ||||||
|  |         itm = MenuItem(valtype, label, value, unit) | ||||||
|  |         self.items[key] = itm | ||||||
|  |         self._index.append(key) | ||||||
|  |         itm.position = self._index.index(key) | ||||||
|  |         return itm | ||||||
|  | 
 | ||||||
|  |     def setItemActive(self, key): | ||||||
|  |         self.activeitem = self._index.index(key) | ||||||
|  | 
 | ||||||
|  |     def getActiveItem(self): | ||||||
|  |         return self.items[self._index[self.activeitem]] | ||||||
|  | 
 | ||||||
|  |     def getItemByIndex(self, index): | ||||||
|  |         return self.items[self._index[index]] | ||||||
|  | 
 | ||||||
|  |     def getItemByKey(self, key): | ||||||
|  |         return self.items[key] | ||||||
|  | 
 | ||||||
|  |     def getItemCount(self): | ||||||
|  |         return len(self.items) | ||||||
|  | 
 | ||||||
|  |     def setItemDimension(self, w, h): | ||||||
|  |         self._w = w | ||||||
|  |         self._h = h | ||||||
|  | 
 | ||||||
|  |     def getXY(self): | ||||||
|  |         return (self._x, self._y) | ||||||
|  | 
 | ||||||
|  |     def getRect(self): | ||||||
|  |         return (self._x, self._y, self._w, self._h * len(self.items)) | ||||||
|  | 
 | ||||||
|  |     def getItemRect(self, index): | ||||||
|  |         y = self._y + index * self._h | ||||||
|  |         return (self._x, y, self._w, self._h) | ||||||
|  |  | ||||||
							
								
								
									
										100
									
								
								pages/anchor.py
								
								
								
								
							
							
						
						
									
										100
									
								
								pages/anchor.py
								
								
								
								
							|  | @ -69,21 +69,19 @@ class Anchor(Page): | ||||||
|         self.wind_angle = -1 |         self.wind_angle = -1 | ||||||
| 
 | 
 | ||||||
|         # Menüsteuerung für Konfiguration |         # Menüsteuerung für Konfiguration | ||||||
|         self._mnu = { |         self._menu = Menu("Options", 20, 80) | ||||||
|             # Lfd. Name, curr unit steps type: numeric, on/off |         self._menu.setItemDimension(120, 20) | ||||||
|             # TODO Das sollte eine Klasse werden! |         newitem = self._menu.addItem("chain", "Chain out", "int", 0, "m") | ||||||
|             'chain': [1, "Chain out", 0, "m", (1, 5, 10), (0, 200)], |         newitem.setRange(0, 200, (1, 5, 10)) | ||||||
|             'chainmax': [2, "Chain max", 0, "m", (1, 5, 10), (0, 200)], |         newitem = self._menu.addItem("chainmax", "Chain max", "int", self.chain_length, "m") | ||||||
|             'zoom': [3, "Zoom", 50, "", (1,), (1, 8)], |         newitem.setRange(0, 200, (1, 5, 10)) | ||||||
|             'range': [4, "Alarm range", 35, "m", (1, 5, 10), (0, 200)] |         newitem = self._menu.addItem("zoom", "Zoom", "int", 2) | ||||||
|         } |         newitem.setRange(1, 8, (1,)) | ||||||
|         self._mnu_title = "Options" |         newitem = self._menu.addItem("range", "Alarm range", "int", 40, "m") | ||||||
|         self._mnu_x = 20 |         newitem.setRange(1, 200, (1, 5, 10)) | ||||||
|         self._mnu_y = 80 |         self._menu.setItemActive("chain") | ||||||
|         self._mnu_w = 120 | 
 | ||||||
|         self._mnu_h = 20 |         self._test = 0 | ||||||
|         self._mnu_sel = 1 |  | ||||||
|         self.mnu_step = 1 |  | ||||||
| 
 | 
 | ||||||
|     def handle_key(self, buttonid): |     def handle_key(self, buttonid): | ||||||
|         if buttonid == 1: |         if buttonid == 1: | ||||||
|  | @ -91,8 +89,10 @@ class Anchor(Page): | ||||||
|                 self.mode = 'C' |                 self.mode = 'C' | ||||||
|                 self.buttonlabel[2] = '#UP' |                 self.buttonlabel[2] = '#UP' | ||||||
|                 self.buttonlabel[3] = '#DOWN' |                 self.buttonlabel[3] = '#DOWN' | ||||||
|                 self.buttonlabel[4] = '[ - ]' |                 itm = self._menu.getActiveItem() | ||||||
|                 self.buttonlabel[5] = '[ + ]' |                 stepwidth = itm.steps[itm.step] | ||||||
|  |                 self.buttonlabel[4] = f"-{stepwidth}" | ||||||
|  |                 self.buttonlabel[5] = f"+{stepwidth}" | ||||||
|                 self.buttonlabel[6] = 'STEP' |                 self.buttonlabel[6] = 'STEP' | ||||||
|             else: |             else: | ||||||
|                 self.mode = 'N' |                 self.mode = 'N' | ||||||
|  | @ -134,16 +134,35 @@ class Anchor(Page): | ||||||
|                 return True |                 return True | ||||||
|         else: |         else: | ||||||
|             # Konfiguration |             # Konfiguration | ||||||
|  |             itm = self._menu.getActiveItem() | ||||||
|             if buttonid == 2: |             if buttonid == 2: | ||||||
|                 if self._mnu_sel == 1: |                 if self._menu.activeitem == 0: | ||||||
|                     self._mnu_sel = len(self._mnu) |                     self._menu.activeitem = self._menu.getItemCount() - 1 | ||||||
|                 else: |                 else: | ||||||
|                     self._mnu_sel -= 1 |                     self._menu.activeitem -= 1 | ||||||
|             elif buttonid == 3: |             elif buttonid == 3: | ||||||
|                 if self._mnu_sel == len(self._mnu): |                 if self._menu.activeitem == self._menu.getItemCount() - 1: | ||||||
|                     self._mnu_sel = 1 |                     self._menu.activeitem = 0 | ||||||
|                 else: |                 else: | ||||||
|                     self._mnu_sel += 1 |                     self._menu.activeitem += 1 | ||||||
|  |             elif buttonid == 4: | ||||||
|  |                 # decrease value by step | ||||||
|  |                 stepwidth = itm.steps[itm.step] | ||||||
|  |                 itm.setValue(itm.value - stepwidth) | ||||||
|  |             elif buttonid == 5: | ||||||
|  |                 # increase value by step | ||||||
|  |                 stepwidth = itm.steps[itm.step] | ||||||
|  |                 itm.setValue(itm.value + stepwidth) | ||||||
|  |             elif buttonid == 6: | ||||||
|  |                 ns = len(itm.steps) | ||||||
|  |                 if ns > 1: | ||||||
|  |                     if itm.step < ns - 1: | ||||||
|  |                         itm.step += 1 | ||||||
|  |                     else: | ||||||
|  |                         itm.step = 0 | ||||||
|  |             stepwidth = itm.steps[itm.step] | ||||||
|  |             self.buttonlabel[4] = f"-{stepwidth}" | ||||||
|  |             self.buttonlabel[5] = f"+{stepwidth}" | ||||||
|             return True |             return True | ||||||
|         return False |         return False | ||||||
| 
 | 
 | ||||||
|  | @ -260,22 +279,31 @@ class Anchor(Page): | ||||||
|         ctx.move_to(2, 50) |         ctx.move_to(2, 50) | ||||||
|         ctx.show_text("Anchor configuration") |         ctx.show_text("Anchor configuration") | ||||||
| 
 | 
 | ||||||
|         # Menüwerte initialisieren |  | ||||||
|         self._mnu["chain"][2] = self.chain |  | ||||||
|         self._mnu["chainmax"][2] = self.chain_length |  | ||||||
| 
 |  | ||||||
|         # Menü zeichnen |         # Menü zeichnen | ||||||
|         ctx.save() |         ctx.save() | ||||||
|         ctx.set_font_size(16) |         ctx.set_font_size(16) | ||||||
|         #ctx.rectangle(100, 100, 50, 50) |         x, y, w, h = self._menu.getRect() | ||||||
|         #ctx.clip() |         ctx.set_line_width(1) | ||||||
|         for m in self._mnu.items(): |         x += 0.5 # Cairo-Fix for single pixel line | ||||||
|             #ctx.move_to(self._mnu_x, self._mnu_y + 24 + m[1][0] * 16) |         y += 0.5 | ||||||
|             #ctx.show_text(m[1][1]) |         ctx.save() | ||||||
|             inverted = (m[1][0] == self._mnu_sel) |         ctx.rectangle(x, y, w, h) | ||||||
|             self.draw_text_boxed(ctx, self._mnu_x, self._mnu_y + self._mnu_h * (m[1][0] - 1), self._mnu_w, self._mnu_h, m[1][1], inverted) |         ctx.clip_preserve() | ||||||
|             ctx.move_to(self._mnu_x + self._mnu_w + 20 , self._mnu_y + self._mnu_h * (m[1][0] - 1)) |         ctx.stroke() | ||||||
|             ctx.show_text(str(m[1][2]) + m[1][3]) |         for m in self._menu: | ||||||
|  |             ix, iy, iw, ih = self._menu.getItemRect(m.position) | ||||||
|  |             inverted = (m.position == self._menu.activeitem) | ||||||
|  |             self.draw_text_boxed(ctx, ix, iy, iw, ih, m.label, inverted, False) | ||||||
|  |         ctx.stroke() | ||||||
|  |         # Werte neben dem Menü | ||||||
|  |         ctx.restore() | ||||||
|  |         ctx.rectangle(0, 20, 400, 360) # new clipping | ||||||
|  |         ctx.clip() | ||||||
|  |         self._test += 1 | ||||||
|  |         for m in self._menu: | ||||||
|  |             ix, iy, iw, ih = self._menu.getItemRect(m.position) | ||||||
|  |             ctx.move_to(ix + iw + 20, iy + ih - 4) # 5 für Unterlängen | ||||||
|  |             ctx.show_text(f"{m.value} {m.unit}") | ||||||
|         ctx.stroke() |         ctx.stroke() | ||||||
|         ctx.restore() |         ctx.restore() | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -279,17 +279,18 @@ class Page(): | ||||||
|         ctx.show_text(content) |         ctx.show_text(content) | ||||||
|         ctx.stroke() |         ctx.stroke() | ||||||
| 
 | 
 | ||||||
|     def draw_text_boxed(self, ctx, x, y, w, h, content, inverted=False): |     def draw_text_boxed(self, ctx, x, y, w, h, content, inverted=False, border=False): | ||||||
|         ctx.set_line_width(1) |         ctx.set_line_width(1) | ||||||
|  |         # Background fill | ||||||
|  |         ctx.set_source_rgb(*self.fgcolor) | ||||||
|         if inverted: |         if inverted: | ||||||
|             ctx.set_source_rgb(*self.fgcolor) |  | ||||||
|             ctx.rectangle(x, y + 0.5, w, h) |             ctx.rectangle(x, y + 0.5, w, h) | ||||||
|             ctx.fill() |             ctx.fill() | ||||||
|         else: |         else: | ||||||
|             ctx.set_source_rgb(*self.bgcolor) |             if border: | ||||||
|             ctx.rectangle(x, y + 0.5, w, h) |                 ctx.rectangle(x + 0.5, y + 0.5, w, h) | ||||||
|             ctx.stroke() |                 ctx.stroke() | ||||||
| 
 |         # Text | ||||||
|         if inverted: |         if inverted: | ||||||
|             ctx.set_source_rgb(*self.bgcolor) |             ctx.set_source_rgb(*self.bgcolor) | ||||||
|         else: |         else: | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue