Skip to content

Commit a1ebe25

Browse files
committed
Implement a drop-down box for CDI value maps.
1 parent fe39568 commit a1ebe25

2 files changed

Lines changed: 72 additions & 2 deletions

File tree

examples/tkexamples/cdiform.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,15 +198,24 @@ def onTreeSelect(self, event: tk.Event):
198198
cdivar = cm.toCDIVar()
199199
tkvar = None
200200
v_widget = None
201-
if cdivar.max:
201+
mapToValue = cm.valueMap()
202+
self.mapToValue = mapToValue
203+
if mapToValue:
204+
tkvar = tk.StringVar(self.root)
205+
v_widget = ttk.Combobox(self.cdiSettingFrame,
206+
textvariable=tkvar,
207+
values=list(mapToValue.keys()))
208+
v_widget.mapToValue = mapToValue
209+
elif cdivar.max:
202210
if cdivar.className == "int":
203211
tkvar = tk.IntVar(self.root)
204212
elif cdivar.className == "float":
205213
tkvar = tk.DoubleVar(self.root)
206214
else:
207215
raise TypeError("Device should not specify max for {}"
208216
.format(cdivar.className))
209-
v_widget = ttk.LabeledScale(self.cdiSettingFrame, variable=tkvar)
217+
v_widget = ttk.LabeledScale(self.cdiSettingFrame,
218+
variable=tkvar)
210219
# ^ widget.scale is ttk.Scale, widget.label is ttk.Label
211220
# ^ a.k.a. Slider (if not using Tk)
212221
v_widget.scale.cdivar = cdivar

openlcb/cdimemo.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,67 @@ def toXMLEnd(self):
277277
memoRepr += ">"
278278
return memoRepr
279279

280+
def valueMap(self):
281+
# type: () -> Union[dict, None]
282+
"""Map each relation in a dict.
283+
Property and value are swapped to make the result a lookup
284+
table where the key is the user-facing caption.
285+
"""
286+
mapMemo = self.getChildByTag("map")
287+
if mapMemo is None:
288+
return None
289+
results = OrderedDict()
290+
for childRelation in mapMemo.children:
291+
if childRelation.tag != "relation":
292+
logger.warning(f"expected relation got {childRelation.tag}")
293+
continue
294+
keyMemo = childRelation.getChildByTag("property")
295+
valueMemo = childRelation.getChildByTag("value")
296+
if not keyMemo:
297+
logger.warning("expected property in relation for"
298+
f" {self.getChildContent('name')}")
299+
continue
300+
if not valueMemo:
301+
logger.warning("expected value in relation for"
302+
f" {self.getChildContent('name')}")
303+
continue
304+
prop = keyMemo.content.strip() if keyMemo.content else None
305+
value = valueMemo.content.strip() if valueMemo.content else None
306+
if not prop:
307+
logger.warning("expected content for property in relation for"
308+
f" {self.getChildContent('name')}")
309+
continue
310+
if not value:
311+
logger.warning("expected content for value in relation for"
312+
f" {self.getChildContent('name')}")
313+
continue
314+
if value in results:
315+
logger.warning(f"expected only one value {repr(value)}"
316+
f" (property {repr(prop)}) in relation for"
317+
f" {self.getChildContent('name')}")
318+
results[value] = prop # reverse to make it a lookup by caption
319+
return results
320+
321+
def keyMap(self):
322+
# type: () -> Union[dict, None]
323+
"""Map each relation in a dict where property is key.
324+
NOTE: As per CDI, value is the visible caption.
325+
"""
326+
tmp = self.valueMap()
327+
if not tmp:
328+
return None
329+
results = OrderedDict()
330+
for k, v in tmp.items():
331+
results[v] = k
332+
return results
333+
334+
def getChildByTag(self, tag):
335+
# type: (str) -> Union[CDIMemo, None]
336+
for child in self.children:
337+
if child.tag == tag:
338+
return child
339+
return None
340+
280341
def toCDIVar(self):
281342
# type: () -> CDIVar
282343
"""Create a CDIVar from descriptors (child elements of self).

0 commit comments

Comments
 (0)