101 lines
4.3 KiB
Python
101 lines
4.3 KiB
Python
"""Details pane widget: encapsulates the Details LabelFrame, scrollable canvas,
|
|
Treeview and editable form container. Assigns key attributes onto the parent
|
|
MonitorApp so existing code in `monitor.py` can keep referencing
|
|
`self.detail_tree`, `self.detail_form_container`, etc.
|
|
"""
|
|
import tkinter as tk
|
|
from tkinter import ttk
|
|
|
|
class DetailsPane:
|
|
def __init__(self, parent, app, width=520, height=540, title='Details'):
|
|
self.app = app
|
|
self.parent = parent
|
|
self.frame = tk.LabelFrame(parent, text=title)
|
|
self.frame.pack(side=tk.RIGHT, fill=tk.Y, expand=False, padx=6)
|
|
self.frame.config(width=width, height=height)
|
|
try:
|
|
self.frame.pack_propagate(False)
|
|
except Exception:
|
|
pass
|
|
|
|
tk.Label(self.frame, text="Message details:").pack(anchor=tk.W)
|
|
|
|
# canvas + scrollbars
|
|
self._details_canvas = tk.Canvas(self.frame, highlightthickness=0)
|
|
self._details_canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=(6,0), pady=6)
|
|
|
|
vsb = ttk.Scrollbar(self.frame, orient=tk.VERTICAL, command=self._details_canvas.yview)
|
|
hsb = ttk.Scrollbar(self.frame, orient=tk.HORIZONTAL, command=self._details_canvas.xview)
|
|
self._details_canvas.configure(yscrollcommand=vsb.set, xscrollcommand=hsb.set)
|
|
vsb.pack(side=tk.RIGHT, fill=tk.Y)
|
|
hsb.pack(side=tk.BOTTOM, fill=tk.X)
|
|
|
|
self._details_canvas_frame = tk.Frame(self._details_canvas)
|
|
self._details_canvas_window = self._details_canvas.create_window((0, 0), window=self._details_canvas_frame, anchor='nw')
|
|
|
|
def _on_frame_configure(event):
|
|
try:
|
|
self._details_canvas.configure(scrollregion=self._details_canvas.bbox('all'))
|
|
except Exception:
|
|
pass
|
|
def _on_canvas_configure(event):
|
|
try:
|
|
canvas_width = event.width
|
|
self._details_canvas.itemconfigure(self._details_canvas_window, width=canvas_width)
|
|
except Exception:
|
|
pass
|
|
self._details_canvas_frame.bind('<Configure>', _on_frame_configure)
|
|
self._details_canvas.bind('<Configure>', _on_canvas_configure)
|
|
|
|
# details Treeview
|
|
self.detail_tree = ttk.Treeview(self._details_canvas_frame, columns=("param", "value"), show="headings", height=18)
|
|
self.detail_tree.heading("param", text="Parameter")
|
|
self.detail_tree.heading("value", text="Value")
|
|
self.detail_tree.column("param", width=260)
|
|
self.detail_tree.column("value", width=420)
|
|
try:
|
|
self.detail_tree.configure() # placeholder to satisfy possible callers
|
|
except Exception:
|
|
pass
|
|
self.detail_tree.pack(side=tk.TOP, fill=tk.BOTH, expand=False, padx=2, pady=2)
|
|
|
|
# form container in the interior frame so it scrolls with canvas
|
|
self.detail_form_container = tk.Frame(self._details_canvas_frame)
|
|
|
|
# assign attributes onto the app so existing MonitorApp code works
|
|
setattr(app, 'detail_tree', self.detail_tree)
|
|
setattr(app, '_details_canvas', self._details_canvas)
|
|
setattr(app, '_details_canvas_frame', self._details_canvas_frame)
|
|
setattr(app, '_details_canvas_window', self._details_canvas_window)
|
|
setattr(app, 'detail_form_container', self.detail_form_container)
|
|
# default holders
|
|
setattr(app, 'form_widgets', {})
|
|
setattr(app, 'current_form_label', None)
|
|
setattr(app, 'current_msg_wrapper', None)
|
|
setattr(app, 'detail_rows', {})
|
|
setattr(app, 'detail_selected_label', None)
|
|
setattr(app, 'detail_accessors', {})
|
|
setattr(app, '_flash_items', {})
|
|
setattr(app, '_last_detail_update', 0.0)
|
|
|
|
# bind double-click to parent's handler if present
|
|
try:
|
|
if hasattr(app, 'on_detail_double_click'):
|
|
self.detail_tree.bind('<Double-1>', app.on_detail_double_click)
|
|
except Exception:
|
|
pass
|
|
|
|
# expose convenience attributes
|
|
self.vsb = vsb
|
|
self.hsb = hsb
|
|
|
|
# small helper to pack the form container when needed
|
|
def show_form_container(self):
|
|
try:
|
|
self.detail_form_container.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
|
|
except Exception:
|
|
pass
|
|
|
|
|
|
__all__ = ['DetailsPane']
|