Render Ox widgets on the Page Editor canvas as the device draws them
The Page Editor canvas now paints widgets WYSIWYG instead of as labelled placeholder boxes, following the ontrolOx draw() code and the R-ION firmware: - text drawn with the device's own bitmap fonts (fontBank .bin / fontBankXL .oxfl), Windows font fallback; alignment, clipping at the box edge, half-size subscript digits, transparent vs filled boxes; the line is centred on the box even when the font is taller - each widget shows the text its `in` selects: NumericLabel formats, lookup items, Boolean true/false text and colours, date and time - images from the local image banks, centred or cropped; missing ones drawn as the device's red/white checker; page background image - 10x10 pixel grid over the page colour, with a Grid toggle - widgets hit-tested by layout box so transparent labels stay clickable; hidden widgets shown as a dashed outline - layout row gets an X/Y/Width/Height dialog - scaled device frame cached per zoom (redraws ~15 ms) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+43
-1
@@ -356,7 +356,7 @@ def build_props(comp):
|
||||
if m.has(*LAYOUT_SLOTS):
|
||||
consumed.update(LAYOUT_SLOTS)
|
||||
rows.append(Prop("layout", "text", lambda: ", ".join(
|
||||
str(m.int(n)) for n in LAYOUT_SLOTS), _layout_writer(m)))
|
||||
str(m.int(n)) for n in LAYOUT_SLOTS), _layout_writer(m), dialog="layout"))
|
||||
|
||||
if m.has(*FONT_SLOTS):
|
||||
consumed.update(FONT_SLOTS)
|
||||
@@ -728,6 +728,9 @@ class OxWidgetPropertiesPanel:
|
||||
|
||||
def _build_text(self, cell, row):
|
||||
prop = row["prop"]
|
||||
if prop.dialog:
|
||||
# Typed in place or edited field by field, as Workbench offers both.
|
||||
self._dots(cell, getattr(self, f"_open_{prop.dialog}_dialog"))
|
||||
if prop.unit:
|
||||
tk.Label(cell, text=prop.unit, font=self._name_font, bg=SHEET_BG,
|
||||
fg=READONLY_FG, padx=4).pack(side=tk.RIGHT)
|
||||
@@ -852,6 +855,45 @@ class OxWidgetPropertiesPanel:
|
||||
dialog.destroy()
|
||||
self.commit(comp, values)
|
||||
|
||||
def _open_layout_dialog(self):
|
||||
"""X, Y, Width and Height, one field each, as Workbench's layout editor has them."""
|
||||
comp = self.comp
|
||||
if comp is None:
|
||||
return
|
||||
self.flush_edits()
|
||||
m = _Model(comp)
|
||||
dialog, body = self._dialog("layout")
|
||||
|
||||
table = tk.Frame(body, bg=GRID_LINE)
|
||||
table.grid(row=0, column=0, sticky="nsew")
|
||||
tk.Label(table, text="", bg=NAME_BG, width=8).grid(row=0, column=0, sticky="nsew",
|
||||
padx=(1, 1), pady=1)
|
||||
tk.Label(table, text="Value", bg=NAME_BG, anchor="w", padx=4, width=16,
|
||||
font=self._name_font).grid(row=0, column=1, sticky="nsew", padx=(0, 1), pady=1)
|
||||
|
||||
variables = {}
|
||||
entries = []
|
||||
for index, (name, label) in enumerate(zip(LAYOUT_SLOTS, ("X", "Y", "Width", "Height"))):
|
||||
tk.Label(table, text=label, bg=SHEET_BG, anchor="w", padx=4,
|
||||
font=self._name_font).grid(row=index + 1, column=0, sticky="nsew",
|
||||
padx=(1, 1), pady=(0, 1))
|
||||
var = tk.StringVar(value=str(m.int(name)))
|
||||
entry = tk.Entry(table, textvariable=var, font=self._name_font, relief=tk.FLAT,
|
||||
bg=SHEET_BG, highlightthickness=1, highlightcolor="#7f9db9",
|
||||
highlightbackground=SHEET_BG, width=16)
|
||||
entry.grid(row=index + 1, column=1, sticky="nsew", padx=(0, 1), pady=(0, 1))
|
||||
variables[name] = var
|
||||
entries.append(entry)
|
||||
|
||||
def apply():
|
||||
text = ", ".join(variables[name].get().strip() or "?" for name in LAYOUT_SLOTS)
|
||||
self._apply_values(dialog, comp, *_layout_writer(m)(text))
|
||||
|
||||
dialog.bind("<Return>", lambda e: apply())
|
||||
self._finish_dialog(dialog, body, 1, apply)
|
||||
entries[0].focus_set()
|
||||
entries[0].select_range(0, tk.END)
|
||||
|
||||
def _open_font_dialog(self):
|
||||
comp = self.comp
|
||||
if comp is None:
|
||||
|
||||
Reference in New Issue
Block a user