SXXXXXXX_PyMsc/pymsc/gui/docking/dock_frame.py

139 lines
4.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# -*- coding: utf-8 -*-
"""
DockFrame: Base class for dockable panels in Tkinter.
Provides minimize, maximize, and close functionality.
"""
import tkinter as tk
from tkinter import ttk
from typing import Optional, Callable
class DockFrame(ttk.Frame):
"""
Base class for dockable panels in the ARTOS GUI.
Features:
- Title bar with controls (minimize/maximize/close)
- Content area for child widgets
- State management (visible/hidden/minimized)
- Callbacks for dock events
"""
def __init__(self, parent: tk.Widget, title: str,
on_close: Optional[Callable] = None,
closable: bool = True,
**kwargs):
"""
Args:
parent: Parent widget
title: Dock window title
on_close: Optional callback when dock is closed
closable: Whether the dock can be closed
**kwargs: Additional Frame options
"""
super().__init__(parent, **kwargs)
self.title = title
self.on_close_callback = on_close
self.closable = closable
self.is_minimized = False
self.is_visible = True
self._create_ui()
def _create_ui(self):
"""Create the dock frame UI components."""
# Title bar
self.title_bar = ttk.Frame(self, relief=tk.RAISED, borderwidth=1)
self.title_bar.pack(side=tk.TOP, fill=tk.X)
# Title label
self.title_label = ttk.Label(
self.title_bar,
text=self.title,
font=('Arial', 10, 'bold'),
padding=(5, 2)
)
self.title_label.pack(side=tk.LEFT)
# Control buttons frame
btn_frame = ttk.Frame(self.title_bar)
btn_frame.pack(side=tk.RIGHT)
# Minimize button
self.min_btn = ttk.Button(
btn_frame,
text="",
width=3,
command=self.toggle_minimize
)
self.min_btn.pack(side=tk.LEFT, padx=1)
# Close button (if closable)
if self.closable:
self.close_btn = ttk.Button(
btn_frame,
text="",
width=3,
command=self.close
)
self.close_btn.pack(side=tk.LEFT, padx=1)
# Separator
ttk.Separator(self, orient=tk.HORIZONTAL).pack(side=tk.TOP, fill=tk.X)
# Content area - subclasses will populate this
self.content_frame = ttk.Frame(self, padding=5)
self.content_frame.pack(side=tk.TOP, fill=tk.BOTH, expand=True)
def toggle_minimize(self):
"""Toggle between minimized and normal state."""
if self.is_minimized:
self.restore()
else:
self.minimize()
def minimize(self):
"""Minimize the dock (hide content, keep title bar)."""
if not self.is_minimized:
self.content_frame.pack_forget()
self.is_minimized = True
self.min_btn.configure(text="")
def restore(self):
"""Restore from minimized state."""
if self.is_minimized:
self.content_frame.pack(side=tk.TOP, fill=tk.BOTH, expand=True)
self.is_minimized = False
self.min_btn.configure(text="")
def close(self):
"""Close the dock (hide completely)."""
if self.closable:
self.pack_forget()
self.is_visible = False
if self.on_close_callback:
self.on_close_callback(self)
def show(self):
"""Show the dock if hidden."""
if not self.is_visible:
self.pack(side=tk.TOP, fill=tk.BOTH, expand=True)
self.is_visible = True
if self.is_minimized:
self.restore()
def set_title(self, new_title: str):
"""Update the dock title."""
self.title = new_title
self.title_label.configure(text=new_title)
# Override this in subclasses to populate content
def populate_content(self):
"""
Override this method in subclasses to add widgets to content_frame.
Called after the dock is initialized.
"""
pass