Add OxPage WYSIWYG editor panel for ontrolOx HMI pages
New ox_page_view.py with OxPageViewPanel: canvas rendering at device resolution (800x480 Orion, 320x240 Rion), RGB565 color conversion, widget tree, selection handles, drag-move, device frame image support. Wired into main.py with context menu, history, panel lifecycle. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -18,6 +18,7 @@ import properties
|
||||
import sax_file
|
||||
import schema
|
||||
import undo
|
||||
import ox_page_view
|
||||
import user_service_view
|
||||
import wiresheet
|
||||
from sax_dom import (find_component_by_path, find_parent_element, get_component_path,
|
||||
@@ -79,6 +80,7 @@ HISTORY_LIMIT = 50
|
||||
VIEW_SHEET = "sheet"
|
||||
VIEW_PROPERTIES = "properties"
|
||||
VIEW_LINKS = "links"
|
||||
VIEW_PAGE = "page"
|
||||
VIEW_USERS = "users"
|
||||
|
||||
# Tk class names of the widgets that own the keyboard while they have focus. Del and
|
||||
@@ -124,6 +126,7 @@ show_left_column_var = None
|
||||
properties_panel = None
|
||||
link_panel = None
|
||||
kits_panel = None
|
||||
ox_page_panel = None
|
||||
user_service_panel = None
|
||||
|
||||
# The sheet to put the tree back on when a sheet change is refused because of unsaved
|
||||
@@ -192,6 +195,12 @@ def refresh_all_views():
|
||||
else:
|
||||
close_editor_panel(force=True)
|
||||
|
||||
if ox_page_panel is not None:
|
||||
if _component_in_document(ox_page_panel.comp):
|
||||
ox_page_panel.refresh()
|
||||
else:
|
||||
close_editor_panel(force=True)
|
||||
|
||||
if user_service_panel is not None:
|
||||
if _component_in_document(user_service_panel.comp):
|
||||
user_service_panel.refresh()
|
||||
@@ -219,7 +228,7 @@ def delete_component(comp):
|
||||
than going through refresh_all_views, so the panel would otherwise be left describing
|
||||
a component the document no longer has.
|
||||
"""
|
||||
panel = properties_panel or link_panel or user_service_panel
|
||||
panel = properties_panel or link_panel or ox_page_panel or user_service_panel
|
||||
showing = panel is not None and panel.comp is comp
|
||||
if sax_file.execute_cascading_deletion(comp) and showing:
|
||||
close_editor_panel(force=True)
|
||||
@@ -228,7 +237,8 @@ def delete_component(comp):
|
||||
def editor_panel_showing():
|
||||
"""Whether something other than the wiresheet has the editor pane."""
|
||||
return (properties_panel is not None or link_panel is not None
|
||||
or kits_panel is not None or user_service_panel is not None)
|
||||
or kits_panel is not None or ox_page_panel is not None
|
||||
or user_service_panel is not None)
|
||||
|
||||
|
||||
def _take_editor_pane():
|
||||
@@ -340,6 +350,38 @@ def dismiss_link_view(restore_canvas=True):
|
||||
_give_editor_pane_back()
|
||||
|
||||
|
||||
def show_ox_page_view(comp):
|
||||
"""Puts the WYSIWYG page editor for an OxPage in the editor pane."""
|
||||
global ox_page_panel
|
||||
if comp is None:
|
||||
return
|
||||
|
||||
if not close_editor_panel():
|
||||
return
|
||||
|
||||
_take_editor_pane()
|
||||
ox_page_panel = ox_page_view.build_ox_page_view_panel(
|
||||
frame_editor, comp, on_change=refresh_all_views,
|
||||
on_close=dismiss_ox_page_view,
|
||||
)
|
||||
ox_page_panel.frame.pack(fill=tk.BOTH, expand=True)
|
||||
record_visit(VIEW_PAGE, comp)
|
||||
app_state.set_status(f"Page Editor: {comp.get('name', '?')}")
|
||||
|
||||
|
||||
def dismiss_ox_page_view(restore_canvas=True):
|
||||
"""Takes the OxPage editor down and gives the pane back."""
|
||||
global ox_page_panel
|
||||
if ox_page_panel is None:
|
||||
return
|
||||
|
||||
ox_page_panel.destroy()
|
||||
ox_page_panel = None
|
||||
|
||||
if restore_canvas:
|
||||
_give_editor_pane_back()
|
||||
|
||||
|
||||
def show_user_service(comp):
|
||||
"""Puts the User Manager for a sys::UserService in the editor pane."""
|
||||
global user_service_panel
|
||||
@@ -420,6 +462,9 @@ def close_editor_panel(force=False):
|
||||
if kits_panel is not None:
|
||||
dismiss_kits()
|
||||
return True
|
||||
if ox_page_panel is not None:
|
||||
dismiss_ox_page_view()
|
||||
return True
|
||||
if user_service_panel is not None:
|
||||
dismiss_user_service()
|
||||
return True
|
||||
@@ -987,6 +1032,9 @@ def on_tree_right_click(event):
|
||||
|
||||
def _open_special_view(comp):
|
||||
"""Opens the type-specific view for a component, or Properties as fallback."""
|
||||
if ox_page_view.is_ox_page(comp):
|
||||
show_ox_page_view(comp)
|
||||
return
|
||||
if user_service_view.is_user_service(comp):
|
||||
show_user_service(comp)
|
||||
return
|
||||
@@ -1288,6 +1336,11 @@ def fill_component_popup(menu, comp):
|
||||
label="Link View",
|
||||
command=lambda: show_link_view(comp),
|
||||
)
|
||||
if ox_page_view.is_ox_page(comp):
|
||||
menu.add_command(
|
||||
label="Page Editor",
|
||||
command=lambda: show_ox_page_view(comp),
|
||||
)
|
||||
if user_service_view.is_user_service(comp):
|
||||
menu.add_command(
|
||||
label="User Manager",
|
||||
@@ -1730,6 +1783,8 @@ def _show_history_entry(position):
|
||||
_show_sheet_entry(element)
|
||||
elif kind == VIEW_PROPERTIES:
|
||||
show_properties(element)
|
||||
elif kind == VIEW_PAGE:
|
||||
show_ox_page_view(element)
|
||||
elif kind == VIEW_USERS:
|
||||
show_user_service(element)
|
||||
else:
|
||||
@@ -1795,7 +1850,7 @@ def on_tree_filled():
|
||||
|
||||
# A different file has no such component, and a rebuild after a delete may have taken
|
||||
# it. Neither is a moment to ask about edits that now have nowhere to go.
|
||||
panel = properties_panel or link_panel or user_service_panel
|
||||
panel = properties_panel or link_panel or ox_page_panel or user_service_panel
|
||||
if panel is not None and not _component_in_document(panel.comp):
|
||||
close_editor_panel(force=True)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user