104 lines
4.0 KiB
Python
104 lines
4.0 KiB
Python
import tkinter as tk
|
|
from tkinter import ttk
|
|
from typing import Callable, Optional, Dict, Any
|
|
|
|
|
|
class ConnectionPanel(ttk.LabelFrame):
|
|
"""Reusable connection panel used by MainView.
|
|
|
|
This encapsulates the small UI that shows connection type/summary and
|
|
exposes simple hooks so the outer view can attach handlers for Connect
|
|
and Settings.
|
|
"""
|
|
|
|
def __init__(self, parent, initial_config: Optional[Dict[str, Any]] = None):
|
|
super().__init__(parent, text="Connection")
|
|
|
|
self._on_connect: Optional[Callable[[], None]] = None
|
|
self._on_open_settings: Optional[Callable[[], None]] = None
|
|
|
|
self.conn_type_var = tk.StringVar(value=(initial_config or {}).get("target", {}).get("type", "-"))
|
|
self.conn_info_var = tk.StringVar(value=self._format_summary((initial_config or {}).get("target", {})))
|
|
|
|
ttk.Label(self, text="Type:").pack(side=tk.LEFT, padx=(6, 2))
|
|
ttk.Label(self, textvariable=self.conn_type_var, width=10).pack(side=tk.LEFT)
|
|
ttk.Label(self, textvariable=self.conn_info_var).pack(side=tk.LEFT, padx=(8, 4))
|
|
|
|
# Buttons
|
|
self.connect_button = ttk.Button(self, text="Connect", command=self._handle_connect)
|
|
self.connect_button.pack(side=tk.RIGHT, padx=(4, 6))
|
|
|
|
self.conn_settings_button = ttk.Button(self, text="Settings...", command=self._handle_open_settings)
|
|
self.conn_settings_button.pack(side=tk.RIGHT, padx=(4, 0))
|
|
|
|
def _format_summary(self, cfg: Dict[str, Any]) -> str:
|
|
try:
|
|
t = cfg.get("type")
|
|
if not t:
|
|
return "-"
|
|
if t == "sfp":
|
|
sfp = cfg.get("sfp", {})
|
|
ip = sfp.get("ip") or sfp.get("host") or "?"
|
|
remote = sfp.get("port") or sfp.get("remote_port")
|
|
if isinstance(remote, (list, tuple)):
|
|
remote_str = ",".join(str(int(p)) for p in remote)
|
|
else:
|
|
try:
|
|
remote_str = str(int(remote)) if remote is not None else "?"
|
|
except Exception:
|
|
remote_str = str(remote)
|
|
local = sfp.get("local_port")
|
|
if local is not None:
|
|
try:
|
|
local_str = str(int(local))
|
|
except Exception:
|
|
local_str = str(local)
|
|
return f"{ip} (remote:{remote_str} local:{local_str})"
|
|
return f"{ip} (remote:{remote_str})"
|
|
if t == "serial":
|
|
s = cfg.get("serial", {})
|
|
port = s.get("port") or s.get("device") or "?"
|
|
baud = s.get("baudrate") or s.get("baud") or "?"
|
|
return f"{port} @{baud}"
|
|
if t == "tftp":
|
|
tftp = cfg.get("tftp", {})
|
|
host = tftp.get("host") or tftp.get("server") or "?"
|
|
return f"{host}"
|
|
return "-"
|
|
except Exception:
|
|
return "-"
|
|
|
|
def set_connect_handler(self, cb: Callable[[], None]):
|
|
self._on_connect = cb
|
|
|
|
def set_open_settings_handler(self, cb: Callable[[], None]):
|
|
self._on_open_settings = cb
|
|
|
|
def _handle_connect(self):
|
|
if self._on_connect:
|
|
try:
|
|
self._on_connect()
|
|
except Exception:
|
|
# Handler should manage its own errors
|
|
raise
|
|
|
|
def _handle_open_settings(self):
|
|
if self._on_open_settings:
|
|
try:
|
|
self._on_open_settings()
|
|
except Exception:
|
|
raise
|
|
|
|
def update_summary(self, conn_config: Dict[str, Any]):
|
|
try:
|
|
self.conn_type_var.set((conn_config or {}).get("target", {}).get("type", "-"))
|
|
self.conn_info_var.set(self._format_summary((conn_config or {}).get("target", {})))
|
|
except Exception:
|
|
pass
|
|
|
|
def update_toggle_state(self, is_connected: bool):
|
|
try:
|
|
self.connect_button.config(text="Disconnect" if is_connected else "Connect")
|
|
except Exception:
|
|
pass
|