JCDock


NameJCDock JSON
Version 1.1.0 PyPI version JSON
download
home_pageNone
SummaryA flexible and customizable docking framework for PySide6 applications.
upload_time2025-08-06 13:42:36
maintainerNone
docs_urlNone
authorNone
requires_pythonNone
licenseMIT License Copyright (c) 2025 Justin Cook Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
keywords pyside qt docking gui widget
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # JCDock

A flexible and customizable docking framework for PySide6 applications, inspired by modern IDEs.

JCDock allows you to create complex user interfaces where widgets can be docked into containers, undocked into floating windows, and rearranged dynamically by the user through an intuitive drag-and-drop interface.

## Features

For detailed API documentation, see the [wiki/](wiki/) directory.

* **Advanced Docking**: Dock widgets to the top, bottom, left, right, or center of other widgets and containers with visual overlay guides.
* **Floating Windows**: Undock any widget or group of widgets into its own floating window with native-like appearance including drop shadows and proper window management.
* **Tearable Tabs**: Users can tear individual tabs away from a tab group to instantly create new floating windows with smooth visual feedback.
* **Persistent Layouts**: Save and restore complete application layouts with automatic widget recreation through the registry system.
* **Nested Splitters**: Automatically create and manage complex nested horizontal and vertical splitter layouts.
* **Multi-Monitor Support**: Full support for dragging and docking across multiple monitors with proper coordinate handling.
* **Performance Optimized**: Built-in caching systems for icons and hit-testing to ensure smooth performance even with complex layouts.
* **Customizable Appearance**: Easily customize title bar colors, widget styling, and visual effects.
* **Signal System**: Comprehensive event system to track widget docking, undocking, and layout changes.
* **Enhanced Toolbar Support**: Full QMainWindow-style toolbar system with multi-area support (top, bottom, left, right), breaks for row/column organization, precise insertion control, and automatic persistence across sessions.
* **Multi-Area Layout**: Support for complex layouts with multiple independent docking areas.

***
## Installation

JCDock is available on PyPI and can be installed using pip. Choose the installation method that best fits your needs:

### Option 1: Install from PyPI (Recommended for Users)

For most users who want to use JCDock in their applications:

```bash
pip install JCDock
```

This installs the latest stable release directly from PyPI.

### Option 2: Install from Source (For Development)

For developers who want to contribute to JCDock or need the latest development features:

```bash
# 1. Clone the repository from GitHub
git clone https://github.com/JustiSoft/JCDock.git

# 2. Navigate into the cloned directory
cd JCDock

# 3. Install in "editable" mode
pip install -e .
```

Using the `-e` or `--editable` flag is recommended for development. It installs the package by creating a link to the source code, so any changes you make to the code will be immediately reflected in your environment.

***
## Simplified Architecture

JCDock uses a **streamlined, single-method architecture** that eliminates complexity while providing full docking capabilities.

### Universal API Design
**One method handles all scenarios:**
```python
manager = DockingManager()

# Main windows, floating widgets, persistent widgets - all use the same method
window = manager.create_window(
    content=widget,      # Any QWidget (optional for main windows)
    title="My Window",
    is_main_window=True, # For main application window
    persist=True,        # For layout persistence
    x=100, y=100, width=400, height=300
)
```

### Key Architecture Benefits
1. **Single Entry Point**: `create_window()` replaces multiple creation methods
2. **Automatic Management**: DockPanel wrapping and DockContainer creation handled internally
3. **Persistent by Design**: `@persistable` decorator + `persist=True` enables layout restoration
4. **User-Friendly**: No need to understand internal component relationships

### Implementation Components (Internal)
- **DockingManager**: Public API facade and central coordinator
- **DockPanel**: Automatic wrapper for making widgets dockable
- **DockContainer**: Internal container implementation for windows
- **Widget Registry**: Automatic widget type management via `@persistable`

### Specialized Systems

### Why This Architecture?

**Before:** Multiple complex methods, manual component management
```python
# Old complex approach (deprecated)
container, panel = manager.create_simple_floating_widget(...)
other_container = manager.create_floating_widget_from_key(...)
manager.register_widget(...)
# Multiple methods, complex relationships
```

**Now:** Single universal method, automatic management
```python
# New streamlined approach
window = manager.create_window(content=widget, title="Widget", persist=True)
# One method, automatic internal management
```

### Internal System Overview (Advanced)
The simplified API is built on a sophisticated internal architecture:

- **State Management**: Coordinated state machine prevents conflicts
- **Performance Optimization**: Automatic caching and throttling systems
- **Layout Persistence**: Binary serialization with widget state preservation
- **Drag & Drop**: Visual overlay system with smooth interactions
- **Multi-Platform**: Native window effects and cross-platform compatibility

### Development Philosophy

JCDock prioritizes **developer experience** over architectural exposure:

1. **Simple API Surface**: One creation method vs. many specialized methods
2. **Automatic Lifecycle**: Internal components managed transparently  
3. **Sensible Defaults**: Minimal configuration required for common scenarios
4. **Progressive Enhancement**: Advanced features available when needed
5. **Future-Proof**: Internal changes don't break application code

## Basic Usage

Here's the simplest possible example showing how to create a floating dockable widget:

```python
import sys
from PySide6.QtWidgets import QApplication, QLabel
from PySide6.QtCore import Qt

from JCDock import DockingManager

if __name__ == "__main__":
    app = QApplication(sys.argv)

    # 1. Create the Docking Manager
    manager = DockingManager()
    
    # 2. Create content and make it a floating dockable widget
    content = QLabel("Hello, JCDock!")
    content.setAlignment(Qt.AlignCenter)
    
    window = manager.create_window(
        content=content,
        title="My Widget",
        persist=True
    )
    window.show()

    sys.exit(app.exec())
```

### Creating a Main Window with Docking

For a more complete application with a main window and multiple dockable widgets:

```python
import sys
from PySide6.QtWidgets import QApplication, QLabel, QTextEdit
from PySide6.QtCore import Qt

from JCDock import DockingManager

if __name__ == "__main__":
    app = QApplication(sys.argv)

    # 1. Create the Docking Manager
    manager = DockingManager()
    
    # 2. Create a main window
    main_window = manager.create_window(
        title="My Application",
        is_main_window=True,
        persist=True,
        x=100,
        y=100,
        width=1000,
        height=600
    )

    # 3. Create widget content
    project_content = QLabel("Project Explorer")
    editor_content = QTextEdit("Your code here...")
    
    # 4. Register widgets with manager
    manager.register_widget(project_content)
    manager.register_widget(editor_content)

    # 5. Dock widgets to create layout
    manager.dock_widget(project_content, main_window, "left")
    manager.dock_widget(editor_content, main_window, "center")

    main_window.show()

    sys.exit(app.exec())
```

### Toolbar Integration Example

JCDock provides comprehensive toolbar support with automatic persistence:

```python
import sys
from PySide6.QtWidgets import QApplication, QTextEdit, QToolBar, QAction
from PySide6.QtCore import Qt

from JCDock import DockingManager

if __name__ == "__main__":
    app = QApplication(sys.argv)

    # 1. Create the Docking Manager
    manager = DockingManager()
    
    # 2. Create main window with toolbar support
    main_window = manager.create_window(
        title="Text Editor with Toolbars",
        is_main_window=True,
        persist=True,
        width=1000,
        height=600
    )
    
    # 3. Create editor content
    editor = QTextEdit("Start typing...")
    manager.register_widget(editor)
    manager.dock_widget(editor, main_window, "center")
    
    # 4. Add comprehensive toolbar layout
    
    # File operations toolbar
    file_toolbar = main_window.addToolBar("File")
    file_toolbar.addAction("New")
    file_toolbar.addAction("Open")
    file_toolbar.addAction("Save")
    
    # Edit operations toolbar (same row)
    edit_toolbar = main_window.addToolBar("Edit")  
    edit_toolbar.addAction("Cut")
    edit_toolbar.addAction("Copy")
    edit_toolbar.addAction("Paste")
    
    # Create toolbar break for new row
    main_window.addToolBarBreak()
    
    # Format toolbar (new row)
    format_toolbar = main_window.addToolBar("Format")
    format_toolbar.addAction("Bold")
    format_toolbar.addAction("Italic")
    format_toolbar.addAction("Underline")
    
    # Status toolbar at bottom
    status_toolbar = main_window.addToolBar("Status", Qt.BottomToolBarArea)
    status_toolbar.addAction("Status: Ready")
    
    # 5. Demonstrate dynamic toolbar insertion
    # Insert priority toolbar before edit toolbar
    priority_toolbar = main_window.insertToolBar(edit_toolbar, "Priority")
    priority_toolbar.addAction("Important Action")
    
    # Add break before priority toolbar to reorganize layout
    main_window.insertToolBarBreak(priority_toolbar)
    
    main_window.show()

    # Toolbar state is automatically saved/restored with layout
    sys.exit(app.exec())
```

This example demonstrates:
- **Multi-area toolbar support**: Top and bottom toolbar areas
- **Toolbar breaks**: Creating rows/columns within areas  
- **Dynamic insertion**: Adding toolbars between existing ones
- **Automatic persistence**: Toolbar layouts saved with application state

## Complete Examples and Testing

### Comprehensive Test Suite

JCDock includes a modular test suite that demonstrates all framework capabilities and serves as both a testing framework and reference implementation. To run the test suite:

```bash
# From project root directory
cd src/JCDock/Examples
../../../.venv/Scripts/python.exe run_test_suite.py
```

![JCDock Demo](src/JCDock/Examples/sample.png)
*Example of JCDock in action showing floating windows, docked panels, and tearable tabs*

The test suite (`src/JCDock/Examples/test_suite/`), which can be run from the Examples directory: provides comprehensive testing through a modular architecture:

#### Core Components
- **Entry Point**: `main.py` for configuration and execution
- **Application Core**: `app.py` handling test orchestration

#### Specialized Managers
- **Test Manager**: Test execution and validation (`managers/test_manager.py`)
- **UI Manager**: Menu system and interaction (`managers/ui_manager.py`)
- **Layout Manager**: Layout persistence testing (`managers/layout_manager.py`)

#### Test Widgets
- **Base Widgets**: Registry and decorator examples (`widgets/test_widgets.py`)
- **Complex Widgets**: Financial dashboard demos (`widgets/financial_widgets.py`)

#### Testing Features
- **Registry Testing**: `@persistable` decorator and widget registration
- **API Coverage**: Both registry and instance-based operations
- **Layout Testing**: Serialization and state preservation
- **Performance**: Visual feedback and drag operation metrics
- **Event System**: Signal listeners and lifecycle events

#### Key Testing Features
- **Registry-based widget creation** using `@persistable` decorators
- **Both API paths**: "By Type" (registry-based) and "By Instance" (existing widgets)
- **Comprehensive testing functions** for all API methods including widget finding, listing, docking operations, and state management
- **Signal system usage** with event listeners for layout changes
- **Interactive menu system** for testing different features and operations
- **Layout persistence testing** with automatic save/load validation
- **Performance monitoring** and drag operation testing

### Layout Persistence

The test suite demonstrates automatic layout persistence using the standard layout file location:

```
layouts/
└── jcdock_layout.ini  # Automatically saved/loaded layout file
└── toolbar_demo_layout.bin  # Example toolbar layout persistence
```

The layout file preserves:
- **Widget positions** and container hierarchies
- **Window geometry** and multi-monitor positioning
- **Widget state** (custom data via `get_dock_state()`/`set_dock_state()`)
- **Tab ordering** and splitter proportions
- **Toolbar layouts** including breaks, insertion points, and custom item states

## Advanced Features

### Layout Persistence

JCDock automatically supports saving and restoring layouts when you use the registry system with `@persistable` decorated widgets:

```python
from PySide6.QtWidgets import QLabel, QTextEdit
from JCDock import persistable

# Register widget types for automatic layout persistence
@persistable("project_explorer", "Project Explorer")
class ProjectWidget(QLabel):
    def __init__(self):
        super().__init__()
        self.setText("Project Files")

@persistable("code_editor", "Code Editor")
class EditorWidget(QTextEdit):
    def __init__(self):
        super().__init__()
        self.setPlainText("# Your code here")

# Create widgets using registered types
project = ProjectWidget()
editor = EditorWidget()

# Create windows for widgets
project_window = manager.create_window(
    content=project,
    key="project_explorer",
    title="Project Explorer",
    persist=True
)

editor_window = manager.create_window(
    content=editor,
    key="code_editor", 
    title="Code Editor",
    persist=True
)

# Save and restore layouts (binary format)
layout_data = manager.save_layout_to_bytearray()

# Later, restore the exact same layout
manager.load_layout_from_bytearray(layout_data)
```

The registry system automatically handles widget recreation during layout restoration - no manual factory functions needed!

### Signal System

Connect to docking events to respond to layout changes:

```python
# Connect to various signals
manager.signals.widget_docked.connect(lambda widget, container: 
    print(f"Widget '{widget.windowTitle()}' docked"))
    
manager.signals.widget_undocked.connect(lambda widget: 
    print(f"Widget '{widget.windowTitle()}' undocked"))
    
manager.signals.widget_closed.connect(lambda persistent_id: 
    print(f"Widget '{persistent_id}' closed"))

manager.signals.layout_changed.connect(lambda: 
    print("Layout changed - save state, update UI, etc."))
```

**Available Signals:**
- `widget_docked(widget, container)` - Widget docked into a container
- `widget_undocked(widget)` - Widget undocked to floating window  
- `widget_closed(persistent_id)` - Widget closed and removed
- `layout_changed()` - Any layout modification occurred
- `application_closing(layout_data)` - Application closing with current layout data

***
## API Reference

### Public API (Recommended)
The streamlined public API focuses on the universal `create_window()` method:

```python
from JCDock import DockingManager, persistable

manager = DockingManager()
window = manager.create_window(content=widget, title="Title", persist=True)
```

**Available Public Imports:**
- `DockingManager` - Central API for all operations
- `persistable` - Decorator for widgets with layout persistence
- `get_registry()` - Access to the global widget registry

### Internal Components
These components are documented for reference but should not be accessed directly:
- `WidgetFactory` - Internal widget creation (use `DockingManager.create_window()`)
- `DockContainer` - Internal container implementation (created by `create_window()`)
- `DockPanel` - Internal widget wrapper (created automatically)
- Various utility classes (caching, performance monitoring, etc.)

### Migration from Older APIs
If you're using older JCDock versions, replace deprecated methods:
- `create_simple_floating_widget()` → `create_window()`
- `create_floating_widget_from_key()` → `create_window()` with registry
- `@dockable` → `@persistable`

***
## Additional Documentation

- **[wiki/](wiki/)** - Comprehensive API documentation and usage guides
- **CLAUDE.md** - Development guidelines and context for development tools

## License

This project is licensed under the MIT License - see the LICENSE file for details.

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "JCDock",
    "maintainer": null,
    "docs_url": null,
    "requires_python": null,
    "maintainer_email": null,
    "keywords": "pyside, qt, docking, gui, widget",
    "author": null,
    "author_email": "Justin Cook <jcook5376@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/8b/d5/11a131a048be85a0ecc8c55402f321546220372958df52e8ae56785b2e4e/jcdock-1.1.0.tar.gz",
    "platform": null,
    "description": "# JCDock\r\n\r\nA flexible and customizable docking framework for PySide6 applications, inspired by modern IDEs.\r\n\r\nJCDock allows you to create complex user interfaces where widgets can be docked into containers, undocked into floating windows, and rearranged dynamically by the user through an intuitive drag-and-drop interface.\r\n\r\n## Features\r\n\r\nFor detailed API documentation, see the [wiki/](wiki/) directory.\r\n\r\n* **Advanced Docking**: Dock widgets to the top, bottom, left, right, or center of other widgets and containers with visual overlay guides.\r\n* **Floating Windows**: Undock any widget or group of widgets into its own floating window with native-like appearance including drop shadows and proper window management.\r\n* **Tearable Tabs**: Users can tear individual tabs away from a tab group to instantly create new floating windows with smooth visual feedback.\r\n* **Persistent Layouts**: Save and restore complete application layouts with automatic widget recreation through the registry system.\r\n* **Nested Splitters**: Automatically create and manage complex nested horizontal and vertical splitter layouts.\r\n* **Multi-Monitor Support**: Full support for dragging and docking across multiple monitors with proper coordinate handling.\r\n* **Performance Optimized**: Built-in caching systems for icons and hit-testing to ensure smooth performance even with complex layouts.\r\n* **Customizable Appearance**: Easily customize title bar colors, widget styling, and visual effects.\r\n* **Signal System**: Comprehensive event system to track widget docking, undocking, and layout changes.\r\n* **Enhanced Toolbar Support**: Full QMainWindow-style toolbar system with multi-area support (top, bottom, left, right), breaks for row/column organization, precise insertion control, and automatic persistence across sessions.\r\n* **Multi-Area Layout**: Support for complex layouts with multiple independent docking areas.\r\n\r\n***\r\n## Installation\r\n\r\nJCDock is available on PyPI and can be installed using pip. Choose the installation method that best fits your needs:\r\n\r\n### Option 1: Install from PyPI (Recommended for Users)\r\n\r\nFor most users who want to use JCDock in their applications:\r\n\r\n```bash\r\npip install JCDock\r\n```\r\n\r\nThis installs the latest stable release directly from PyPI.\r\n\r\n### Option 2: Install from Source (For Development)\r\n\r\nFor developers who want to contribute to JCDock or need the latest development features:\r\n\r\n```bash\r\n# 1. Clone the repository from GitHub\r\ngit clone https://github.com/JustiSoft/JCDock.git\r\n\r\n# 2. Navigate into the cloned directory\r\ncd JCDock\r\n\r\n# 3. Install in \"editable\" mode\r\npip install -e .\r\n```\r\n\r\nUsing the `-e` or `--editable` flag is recommended for development. It installs the package by creating a link to the source code, so any changes you make to the code will be immediately reflected in your environment.\r\n\r\n***\r\n## Simplified Architecture\r\n\r\nJCDock uses a **streamlined, single-method architecture** that eliminates complexity while providing full docking capabilities.\r\n\r\n### Universal API Design\r\n**One method handles all scenarios:**\r\n```python\r\nmanager = DockingManager()\r\n\r\n# Main windows, floating widgets, persistent widgets - all use the same method\r\nwindow = manager.create_window(\r\n    content=widget,      # Any QWidget (optional for main windows)\r\n    title=\"My Window\",\r\n    is_main_window=True, # For main application window\r\n    persist=True,        # For layout persistence\r\n    x=100, y=100, width=400, height=300\r\n)\r\n```\r\n\r\n### Key Architecture Benefits\r\n1. **Single Entry Point**: `create_window()` replaces multiple creation methods\r\n2. **Automatic Management**: DockPanel wrapping and DockContainer creation handled internally\r\n3. **Persistent by Design**: `@persistable` decorator + `persist=True` enables layout restoration\r\n4. **User-Friendly**: No need to understand internal component relationships\r\n\r\n### Implementation Components (Internal)\r\n- **DockingManager**: Public API facade and central coordinator\r\n- **DockPanel**: Automatic wrapper for making widgets dockable\r\n- **DockContainer**: Internal container implementation for windows\r\n- **Widget Registry**: Automatic widget type management via `@persistable`\r\n\r\n### Specialized Systems\r\n\r\n### Why This Architecture?\r\n\r\n**Before:** Multiple complex methods, manual component management\r\n```python\r\n# Old complex approach (deprecated)\r\ncontainer, panel = manager.create_simple_floating_widget(...)\r\nother_container = manager.create_floating_widget_from_key(...)\r\nmanager.register_widget(...)\r\n# Multiple methods, complex relationships\r\n```\r\n\r\n**Now:** Single universal method, automatic management\r\n```python\r\n# New streamlined approach\r\nwindow = manager.create_window(content=widget, title=\"Widget\", persist=True)\r\n# One method, automatic internal management\r\n```\r\n\r\n### Internal System Overview (Advanced)\r\nThe simplified API is built on a sophisticated internal architecture:\r\n\r\n- **State Management**: Coordinated state machine prevents conflicts\r\n- **Performance Optimization**: Automatic caching and throttling systems\r\n- **Layout Persistence**: Binary serialization with widget state preservation\r\n- **Drag & Drop**: Visual overlay system with smooth interactions\r\n- **Multi-Platform**: Native window effects and cross-platform compatibility\r\n\r\n### Development Philosophy\r\n\r\nJCDock prioritizes **developer experience** over architectural exposure:\r\n\r\n1. **Simple API Surface**: One creation method vs. many specialized methods\r\n2. **Automatic Lifecycle**: Internal components managed transparently  \r\n3. **Sensible Defaults**: Minimal configuration required for common scenarios\r\n4. **Progressive Enhancement**: Advanced features available when needed\r\n5. **Future-Proof**: Internal changes don't break application code\r\n\r\n## Basic Usage\r\n\r\nHere's the simplest possible example showing how to create a floating dockable widget:\r\n\r\n```python\r\nimport sys\r\nfrom PySide6.QtWidgets import QApplication, QLabel\r\nfrom PySide6.QtCore import Qt\r\n\r\nfrom JCDock import DockingManager\r\n\r\nif __name__ == \"__main__\":\r\n    app = QApplication(sys.argv)\r\n\r\n    # 1. Create the Docking Manager\r\n    manager = DockingManager()\r\n    \r\n    # 2. Create content and make it a floating dockable widget\r\n    content = QLabel(\"Hello, JCDock!\")\r\n    content.setAlignment(Qt.AlignCenter)\r\n    \r\n    window = manager.create_window(\r\n        content=content,\r\n        title=\"My Widget\",\r\n        persist=True\r\n    )\r\n    window.show()\r\n\r\n    sys.exit(app.exec())\r\n```\r\n\r\n### Creating a Main Window with Docking\r\n\r\nFor a more complete application with a main window and multiple dockable widgets:\r\n\r\n```python\r\nimport sys\r\nfrom PySide6.QtWidgets import QApplication, QLabel, QTextEdit\r\nfrom PySide6.QtCore import Qt\r\n\r\nfrom JCDock import DockingManager\r\n\r\nif __name__ == \"__main__\":\r\n    app = QApplication(sys.argv)\r\n\r\n    # 1. Create the Docking Manager\r\n    manager = DockingManager()\r\n    \r\n    # 2. Create a main window\r\n    main_window = manager.create_window(\r\n        title=\"My Application\",\r\n        is_main_window=True,\r\n        persist=True,\r\n        x=100,\r\n        y=100,\r\n        width=1000,\r\n        height=600\r\n    )\r\n\r\n    # 3. Create widget content\r\n    project_content = QLabel(\"Project Explorer\")\r\n    editor_content = QTextEdit(\"Your code here...\")\r\n    \r\n    # 4. Register widgets with manager\r\n    manager.register_widget(project_content)\r\n    manager.register_widget(editor_content)\r\n\r\n    # 5. Dock widgets to create layout\r\n    manager.dock_widget(project_content, main_window, \"left\")\r\n    manager.dock_widget(editor_content, main_window, \"center\")\r\n\r\n    main_window.show()\r\n\r\n    sys.exit(app.exec())\r\n```\r\n\r\n### Toolbar Integration Example\r\n\r\nJCDock provides comprehensive toolbar support with automatic persistence:\r\n\r\n```python\r\nimport sys\r\nfrom PySide6.QtWidgets import QApplication, QTextEdit, QToolBar, QAction\r\nfrom PySide6.QtCore import Qt\r\n\r\nfrom JCDock import DockingManager\r\n\r\nif __name__ == \"__main__\":\r\n    app = QApplication(sys.argv)\r\n\r\n    # 1. Create the Docking Manager\r\n    manager = DockingManager()\r\n    \r\n    # 2. Create main window with toolbar support\r\n    main_window = manager.create_window(\r\n        title=\"Text Editor with Toolbars\",\r\n        is_main_window=True,\r\n        persist=True,\r\n        width=1000,\r\n        height=600\r\n    )\r\n    \r\n    # 3. Create editor content\r\n    editor = QTextEdit(\"Start typing...\")\r\n    manager.register_widget(editor)\r\n    manager.dock_widget(editor, main_window, \"center\")\r\n    \r\n    # 4. Add comprehensive toolbar layout\r\n    \r\n    # File operations toolbar\r\n    file_toolbar = main_window.addToolBar(\"File\")\r\n    file_toolbar.addAction(\"New\")\r\n    file_toolbar.addAction(\"Open\")\r\n    file_toolbar.addAction(\"Save\")\r\n    \r\n    # Edit operations toolbar (same row)\r\n    edit_toolbar = main_window.addToolBar(\"Edit\")  \r\n    edit_toolbar.addAction(\"Cut\")\r\n    edit_toolbar.addAction(\"Copy\")\r\n    edit_toolbar.addAction(\"Paste\")\r\n    \r\n    # Create toolbar break for new row\r\n    main_window.addToolBarBreak()\r\n    \r\n    # Format toolbar (new row)\r\n    format_toolbar = main_window.addToolBar(\"Format\")\r\n    format_toolbar.addAction(\"Bold\")\r\n    format_toolbar.addAction(\"Italic\")\r\n    format_toolbar.addAction(\"Underline\")\r\n    \r\n    # Status toolbar at bottom\r\n    status_toolbar = main_window.addToolBar(\"Status\", Qt.BottomToolBarArea)\r\n    status_toolbar.addAction(\"Status: Ready\")\r\n    \r\n    # 5. Demonstrate dynamic toolbar insertion\r\n    # Insert priority toolbar before edit toolbar\r\n    priority_toolbar = main_window.insertToolBar(edit_toolbar, \"Priority\")\r\n    priority_toolbar.addAction(\"Important Action\")\r\n    \r\n    # Add break before priority toolbar to reorganize layout\r\n    main_window.insertToolBarBreak(priority_toolbar)\r\n    \r\n    main_window.show()\r\n\r\n    # Toolbar state is automatically saved/restored with layout\r\n    sys.exit(app.exec())\r\n```\r\n\r\nThis example demonstrates:\r\n- **Multi-area toolbar support**: Top and bottom toolbar areas\r\n- **Toolbar breaks**: Creating rows/columns within areas  \r\n- **Dynamic insertion**: Adding toolbars between existing ones\r\n- **Automatic persistence**: Toolbar layouts saved with application state\r\n\r\n## Complete Examples and Testing\r\n\r\n### Comprehensive Test Suite\r\n\r\nJCDock includes a modular test suite that demonstrates all framework capabilities and serves as both a testing framework and reference implementation. To run the test suite:\r\n\r\n```bash\r\n# From project root directory\r\ncd src/JCDock/Examples\r\n../../../.venv/Scripts/python.exe run_test_suite.py\r\n```\r\n\r\n![JCDock Demo](src/JCDock/Examples/sample.png)\r\n*Example of JCDock in action showing floating windows, docked panels, and tearable tabs*\r\n\r\nThe test suite (`src/JCDock/Examples/test_suite/`), which can be run from the Examples directory: provides comprehensive testing through a modular architecture:\r\n\r\n#### Core Components\r\n- **Entry Point**: `main.py` for configuration and execution\r\n- **Application Core**: `app.py` handling test orchestration\r\n\r\n#### Specialized Managers\r\n- **Test Manager**: Test execution and validation (`managers/test_manager.py`)\r\n- **UI Manager**: Menu system and interaction (`managers/ui_manager.py`)\r\n- **Layout Manager**: Layout persistence testing (`managers/layout_manager.py`)\r\n\r\n#### Test Widgets\r\n- **Base Widgets**: Registry and decorator examples (`widgets/test_widgets.py`)\r\n- **Complex Widgets**: Financial dashboard demos (`widgets/financial_widgets.py`)\r\n\r\n#### Testing Features\r\n- **Registry Testing**: `@persistable` decorator and widget registration\r\n- **API Coverage**: Both registry and instance-based operations\r\n- **Layout Testing**: Serialization and state preservation\r\n- **Performance**: Visual feedback and drag operation metrics\r\n- **Event System**: Signal listeners and lifecycle events\r\n\r\n#### Key Testing Features\r\n- **Registry-based widget creation** using `@persistable` decorators\r\n- **Both API paths**: \"By Type\" (registry-based) and \"By Instance\" (existing widgets)\r\n- **Comprehensive testing functions** for all API methods including widget finding, listing, docking operations, and state management\r\n- **Signal system usage** with event listeners for layout changes\r\n- **Interactive menu system** for testing different features and operations\r\n- **Layout persistence testing** with automatic save/load validation\r\n- **Performance monitoring** and drag operation testing\r\n\r\n### Layout Persistence\r\n\r\nThe test suite demonstrates automatic layout persistence using the standard layout file location:\r\n\r\n```\r\nlayouts/\r\n\u2514\u2500\u2500 jcdock_layout.ini  # Automatically saved/loaded layout file\r\n\u2514\u2500\u2500 toolbar_demo_layout.bin  # Example toolbar layout persistence\r\n```\r\n\r\nThe layout file preserves:\r\n- **Widget positions** and container hierarchies\r\n- **Window geometry** and multi-monitor positioning\r\n- **Widget state** (custom data via `get_dock_state()`/`set_dock_state()`)\r\n- **Tab ordering** and splitter proportions\r\n- **Toolbar layouts** including breaks, insertion points, and custom item states\r\n\r\n## Advanced Features\r\n\r\n### Layout Persistence\r\n\r\nJCDock automatically supports saving and restoring layouts when you use the registry system with `@persistable` decorated widgets:\r\n\r\n```python\r\nfrom PySide6.QtWidgets import QLabel, QTextEdit\r\nfrom JCDock import persistable\r\n\r\n# Register widget types for automatic layout persistence\r\n@persistable(\"project_explorer\", \"Project Explorer\")\r\nclass ProjectWidget(QLabel):\r\n    def __init__(self):\r\n        super().__init__()\r\n        self.setText(\"Project Files\")\r\n\r\n@persistable(\"code_editor\", \"Code Editor\")\r\nclass EditorWidget(QTextEdit):\r\n    def __init__(self):\r\n        super().__init__()\r\n        self.setPlainText(\"# Your code here\")\r\n\r\n# Create widgets using registered types\r\nproject = ProjectWidget()\r\neditor = EditorWidget()\r\n\r\n# Create windows for widgets\r\nproject_window = manager.create_window(\r\n    content=project,\r\n    key=\"project_explorer\",\r\n    title=\"Project Explorer\",\r\n    persist=True\r\n)\r\n\r\neditor_window = manager.create_window(\r\n    content=editor,\r\n    key=\"code_editor\", \r\n    title=\"Code Editor\",\r\n    persist=True\r\n)\r\n\r\n# Save and restore layouts (binary format)\r\nlayout_data = manager.save_layout_to_bytearray()\r\n\r\n# Later, restore the exact same layout\r\nmanager.load_layout_from_bytearray(layout_data)\r\n```\r\n\r\nThe registry system automatically handles widget recreation during layout restoration - no manual factory functions needed!\r\n\r\n### Signal System\r\n\r\nConnect to docking events to respond to layout changes:\r\n\r\n```python\r\n# Connect to various signals\r\nmanager.signals.widget_docked.connect(lambda widget, container: \r\n    print(f\"Widget '{widget.windowTitle()}' docked\"))\r\n    \r\nmanager.signals.widget_undocked.connect(lambda widget: \r\n    print(f\"Widget '{widget.windowTitle()}' undocked\"))\r\n    \r\nmanager.signals.widget_closed.connect(lambda persistent_id: \r\n    print(f\"Widget '{persistent_id}' closed\"))\r\n\r\nmanager.signals.layout_changed.connect(lambda: \r\n    print(\"Layout changed - save state, update UI, etc.\"))\r\n```\r\n\r\n**Available Signals:**\r\n- `widget_docked(widget, container)` - Widget docked into a container\r\n- `widget_undocked(widget)` - Widget undocked to floating window  \r\n- `widget_closed(persistent_id)` - Widget closed and removed\r\n- `layout_changed()` - Any layout modification occurred\r\n- `application_closing(layout_data)` - Application closing with current layout data\r\n\r\n***\r\n## API Reference\r\n\r\n### Public API (Recommended)\r\nThe streamlined public API focuses on the universal `create_window()` method:\r\n\r\n```python\r\nfrom JCDock import DockingManager, persistable\r\n\r\nmanager = DockingManager()\r\nwindow = manager.create_window(content=widget, title=\"Title\", persist=True)\r\n```\r\n\r\n**Available Public Imports:**\r\n- `DockingManager` - Central API for all operations\r\n- `persistable` - Decorator for widgets with layout persistence\r\n- `get_registry()` - Access to the global widget registry\r\n\r\n### Internal Components\r\nThese components are documented for reference but should not be accessed directly:\r\n- `WidgetFactory` - Internal widget creation (use `DockingManager.create_window()`)\r\n- `DockContainer` - Internal container implementation (created by `create_window()`)\r\n- `DockPanel` - Internal widget wrapper (created automatically)\r\n- Various utility classes (caching, performance monitoring, etc.)\r\n\r\n### Migration from Older APIs\r\nIf you're using older JCDock versions, replace deprecated methods:\r\n- `create_simple_floating_widget()` \u2192 `create_window()`\r\n- `create_floating_widget_from_key()` \u2192 `create_window()` with registry\r\n- `@dockable` \u2192 `@persistable`\r\n\r\n***\r\n## Additional Documentation\r\n\r\n- **[wiki/](wiki/)** - Comprehensive API documentation and usage guides\r\n- **CLAUDE.md** - Development guidelines and context for development tools\r\n\r\n## License\r\n\r\nThis project is licensed under the MIT License - see the LICENSE file for details.\r\n",
    "bugtrack_url": null,
    "license": "MIT License\r\n        \r\n        Copyright (c) 2025 Justin Cook\r\n        \r\n        Permission is hereby granted, free of charge, to any person obtaining a copy\r\n        of this software and associated documentation files (the \"Software\"), to deal\r\n        in the Software without restriction, including without limitation the rights\r\n        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n        copies of the Software, and to permit persons to whom the Software is\r\n        furnished to do so, subject to the following conditions:\r\n        \r\n        The above copyright notice and this permission notice shall be included in all\r\n        copies or substantial portions of the Software.\r\n        \r\n        THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\n        SOFTWARE.\r\n        ",
    "summary": "A flexible and customizable docking framework for PySide6 applications.",
    "version": "1.1.0",
    "project_urls": {
        "Documentation": "https://github.com/JustiSoft/JCDock#readme",
        "Homepage": "https://github.com/JustiSoft/JCDock",
        "Issues": "https://github.com/JustiSoft/JCDock/issues",
        "Repository": "https://github.com/JustiSoft/JCDock"
    },
    "split_keywords": [
        "pyside",
        " qt",
        " docking",
        " gui",
        " widget"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "aaad4d8663c2e0ae724c39308e32a1181e1cddb70a745e1a761b6576563d1491",
                "md5": "37638c3361554e7041f2eca012b095a9",
                "sha256": "48ba6afb267c2025af23fbc4376aeb8d30d4271b89f4aae947d610d4531b0210"
            },
            "downloads": -1,
            "filename": "jcdock-1.1.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "37638c3361554e7041f2eca012b095a9",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": null,
            "size": 153748,
            "upload_time": "2025-08-06T13:42:35",
            "upload_time_iso_8601": "2025-08-06T13:42:35.509223Z",
            "url": "https://files.pythonhosted.org/packages/aa/ad/4d8663c2e0ae724c39308e32a1181e1cddb70a745e1a761b6576563d1491/jcdock-1.1.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "8bd511a131a048be85a0ecc8c55402f321546220372958df52e8ae56785b2e4e",
                "md5": "96f4e505db79d3176fe14dbd0ee5ef47",
                "sha256": "9a39ac8596ea113020eb5b3f83adb1caf1904e7812706feff734b92d77de64d8"
            },
            "downloads": -1,
            "filename": "jcdock-1.1.0.tar.gz",
            "has_sig": false,
            "md5_digest": "96f4e505db79d3176fe14dbd0ee5ef47",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 134677,
            "upload_time": "2025-08-06T13:42:36",
            "upload_time_iso_8601": "2025-08-06T13:42:36.451625Z",
            "url": "https://files.pythonhosted.org/packages/8b/d5/11a131a048be85a0ecc8c55402f321546220372958df52e8ae56785b2e4e/jcdock-1.1.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-08-06 13:42:36",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "JustiSoft",
    "github_project": "JCDock#readme",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "jcdock"
}
        
Elapsed time: 1.79736s