SXXXXXXX_PyMsc/pymsc/gui/docking/README.md

9.7 KiB

ARTOS Docking System

Tkinter-based Modular GUI Framework

Status: First iteration complete
Created: 2026-01-09
Version: 0.1.0


Overview

Custom docking system for ARTOS built with Tkinter, providing a modular GUI where each subsystem (MCS, Navigation, IRST, etc.) lives in its own dockable panel.

Key Features

  • Dockable panels with title bars
  • Minimize/maximize/close controls
  • Resizable splits (PanedWindow)
  • Save/load workspace layouts (JSON)
  • Zero external dependencies (stdlib only)
  • Dark theme using ttk 'clam' style

Architecture

pymsc/gui/docking/
├── __init__.py              # Package exports
├── dock_frame.py            # Base class for dockable panels
├── workspace_manager.py     # Layout and lifecycle management
├── mcs_dock.py              # MCS module dock (full implementation)
├── placeholder_dock.py      # Generic placeholder for future modules
└── main_docking_window.py   # Main application window

Class Hierarchy

DockFrame (base)
├── title_bar (Frame)
│   ├── title_label
│   └── buttons (minimize, close)
└── content_frame (to be populated by subclasses)

MCSDock (DockFrame)
└── content_frame
    └── Notebook (tabs)
        ├── Page01 (Command)
        ├── Page02 (Radar Settings)
        ├── ...
        └── Page07 (Advanced)

PlaceholderDock (DockFrame)
└── content_frame
    └── Label ("Not yet implemented")

Usage

Quick Start

# Activate venv
.venv\Scripts\Activate.ps1

# Launch docking GUI
python scripts\launch_docking_gui.py

Layout Structure

┌─────────────┬──────────────────────────┐
│             │  Right Top               │
│             │  ┌────────────────────┐  │
│   MCS       │  │  Navigation        │  │
│   Dock      │  │  (Placeholder)     │  │
│             │  └────────────────────┘  │
│             │  ┌────────────────────┐  │
│             │  │  IRST Module       │  │
│             │  │  (Placeholder)     │  │
│             │  └────────────────────┘  │
│             ├──────────────────────────┤
│             │  Right Bottom            │
│             │  ┌────────────────────┐  │
│             │  │  Logger & Status   │  │
│             │  │  (Placeholder)     │  │
│             │  └────────────────────┘  │
└─────────────┴──────────────────────────┘

Creating a New Dock

Step 1: Subclass DockFrame

from pymsc.gui.docking import DockFrame
import tkinter as tk
from tkinter import ttk

class MyModuleDock(DockFrame):
    def __init__(self, parent, my_data, **kwargs):
        self.my_data = my_data
        super().__init__(parent, title="My Module", **kwargs)
    
    def populate_content(self):
        """Called after __init__ to populate content_frame."""
        label = ttk.Label(self.content_frame, text="My module content")
        label.pack()

Step 2: Register in MainDockingWindow

# In main_docking_window.py -> _create_docks()
my_dock = MyModuleDock(
    self.workspace.left_container,
    my_data=some_data
)
self.workspace.add_dock('my_module', my_dock, position='left')

Step 3: Add View menu entry

# In _create_menu()
view_menu.add_command(
    label="Toggle My Module",
    command=lambda: self.workspace.toggle_dock_visibility('my_module')
)

Configuration

Workspace Layouts

Layouts are saved in layouts/ directory as JSON files:

{
  "main_sash_position": [400, 0],
  "right_sash_position": [0, 600],
  "docks": {
    "mcs": {
      "visible": true,
      "minimized": false
    },
    "nav": {
      "visible": true,
      "minimized": true
    }
  }
}

Saving/Loading

  • Save: File → Save Layout
  • Load: File → Load Layout
  • Default: layouts/user_layout.json

API Reference

DockFrame

Base class for all dockable panels.

Constructor:

DockFrame(parent, title, on_close=None, closable=True, **kwargs)

Methods:

  • populate_content() - Override to add widgets to content_frame
  • minimize() - Hide content, keep title bar
  • restore() - Restore from minimized state
  • close() - Hide entire dock
  • show() - Show dock if hidden
  • set_title(new_title) - Update dock title

Attributes:

  • content_frame - ttk.Frame for dock content
  • is_minimized - bool
  • is_visible - bool

WorkspaceManager

Manages dock lifecycle and layout.

Constructor:

WorkspaceManager(root, layouts_dir="layouts")

Methods:

  • add_dock(dock_id, dock, position) - Register and place dock
    • Positions: 'left', 'right_top', 'right_bottom'
  • get_dock(dock_id) - Retrieve dock by ID
  • remove_dock(dock_id) - Unregister dock
  • toggle_dock_visibility(dock_id) - Show/hide dock
  • save_layout(name) - Save layout to JSON
  • load_layout(name) - Load layout from JSON

Attributes:

  • docks - Dict[str, DockFrame]
  • main_pane - tk.PanedWindow (horizontal split)
  • right_pane - tk.PanedWindow (vertical split)

Current Modules

Dock ID Title Status Position
mcs Mission Control System Full implementation Left
nav Navigation System 🔲 Placeholder Right Top
irst IRST Module 🔲 Placeholder Right Top
logger System Logger & Status 🔲 Placeholder Right Bottom

Planned Modules (Future Phases)

Phase 3: Navigation & Algorithms

  • Navigation Dock: Real-time navigation algorithms and data processing
  • Trajectory Dock: Track prediction and analysis

Phase 4: Video & IRST

  • Video Dock: Camera feeds with PIL/Pillow rendering
  • IRST Dock: Infrared search and track visualization

Phase 5: Test Execution

  • Test Control Dock: Script selection and execution
  • Report Viewer Dock: Real-time test results and logs

Theming

Current Theme

The GUI uses Tkinter's native 'clam' theme with custom dark color scheme:

  • Background: Dark blue-grey (#2b3e50)
  • Text: Light grey (#ecf0f1)
  • Accent: Blue (#3498db)

Changing Colors

Edit main_docking_window.py in __init__():

# Dark theme configuration
bg_dark = '#2b3e50'        # Main background
bg_darker = '#1a252f'      # Darker backgrounds
fg_light = '#ecf0f1'       # Text color
accent = '#3498db'         # Accent color (buttons)

Alternative Themes

You can use other ttk themes by changing:

style.theme_use('clam')  # Options: clam, alt, default, classic

Known Issues & Limitations

Current Limitations

  • ⚠️ Docks cannot be dragged between positions (fixed slots)
  • ⚠️ No floating/undocked panels
  • ⚠️ Sash positions are absolute pixels (not percentages)

Future Improvements

  • Drag-and-drop dock repositioning
  • Floating window support
  • Tabbed docking (multiple docks in same slot)
  • Dock state persistence per user
  • Keyboard shortcuts for dock operations

Testing

Manual Testing

  1. Launch GUI: python scripts\launch_docking_gui.py
  2. Verify MCS tabs load (Page 01-07)
  3. Test minimize buttons on each dock
  4. Test close/restore via View menu
  5. Resize splitters (drag sash)
  6. Save layout (File → Save Layout)
  7. Close and relaunch
  8. Load layout (File → Load Layout)

Unit Tests (TODO)

pytest tests/test_docking_system.py

Migration Guide

From old main_window.py to docking system

Old approach:

# All tabs in one Notebook
notebook = ttk.Notebook(root)
page01 = Page01(notebook, bus_module)
notebook.add(page01, text="Command")

New approach:

# MCS dock with tabs
mcs_dock = MCSDock(parent, bus_module)
workspace.add_dock('mcs', mcs_dock, position='left')

Benefits:

  • Independent refresh loops per dock
  • Each module can be hidden/minimized independently
  • Easier parallel development (one developer per dock)
  • Better separation of concerns

Contributing

Adding a New Dock Module

  1. Create pymsc/gui/docking/my_module_dock.py
  2. Subclass DockFrame
  3. Implement populate_content()
  4. Register in MainDockingWindow._create_docks()
  5. Add View menu toggle
  6. Update this README with dock info

Code Style


References


Changelog

v0.1.0 - 2026-01-09

  • Initial docking system implementation
  • DockFrame base class with minimize/close
  • WorkspaceManager with PanedWindow layouts
  • MCSDock with Control and Mission pages
  • PlaceholderDock for future modules
  • MainDockingWindow with menu system
  • Save/load layout functionality
  • Dark theme using ttk 'clam' style (zero external dependencies)

License

© 2025 - Internal project