JCDock


NameJCDock JSON
Version 1.0.1 PyPI version JSON
download
home_pageNone
SummaryA flexible and customizable docking framework for PySide6 applications.
upload_time2025-07-26 00:15:06
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

* **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.
* **Floating Dock Roots**: Create multiple independent floating windows that can act as primary docking targets.

***
## 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.

***
## Architecture Overview

JCDock uses a unified window model where all floating windows are `DockContainer` instances. The architecture is built around a central state machine with specialized components:

### Core Components
- **DockingManager**: Central orchestrator managing all docking operations, widget registration, and layout persistence
- **DockingState**: State machine defining operational states (IDLE, RENDERING, DRAGGING_WINDOW, RESIZING_WINDOW, DRAGGING_TAB)
- **DockPanel**: Wrapper for any QWidget to make it dockable with title bars and controls  
- **DockContainer**: Advanced host containers with drag-and-drop capabilities and tab/splitter management
- **MainDockWindow**: Main application window with built-in central dock area
- **TearableTabWidget**: Enhanced tab widget supporting drag-out operations with visual feedback

### Specialized Systems

#### Core (`core/`)
- **WidgetRegistry**: Registry system for widget types enabling automatic layout persistence
- **DockingState**: State machine enum defining operational states

#### Model (`model/`)
- **LayoutSerializer**: Handles serialization and deserialization of dock layout state
- **LayoutRenderer**: Handles layout rendering and state transitions
- **LayoutModel**: Core data structures for layout representation

#### Interaction (`interaction/`)
- **DragDropController**: Manages drag-and-drop operations and visual feedback
- **OverlayManager**: Manages visual overlay system during drag operations
- **DockingOverlay**: Visual feedback overlays for drop zones

#### Factories (`factories/`)
- **WidgetFactory**: Creates and manages widget instances
- **WindowManager**: Handles window creation and management
- **ModelUpdateEngine**: Manages model state updates

#### Utils (`utils/`)
- **HitTestCache**: Performance optimization for overlay hit-testing during drag operations
- **IconCache**: LRU cache system for icon rendering performance optimization

## 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)
    manager.create_simple_floating_widget(content, "My Widget")

    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
from JCDock.widgets.main_dock_window import MainDockWindow

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

    # 1. Create the Docking Manager
    manager = DockingManager()
    
    # 2. Create the Main Window (automatically handles registration)
    main_window = MainDockWindow(manager)

    # 3. Create simple floating widgets
    project_content = QLabel("Project Explorer")
    _, project_panel = manager.create_simple_floating_widget(project_content, "Project")

    editor_content = QTextEdit("Your code here...")
    _, editor_panel = manager.create_simple_floating_widget(editor_content, "Editor")

    # 4. Dock widgets to create layout
    manager.dock_widget(project_panel, main_window.dock_area, "left")
    manager.dock_widget(editor_panel, project_panel, "right")

    main_window.setGeometry(100, 100, 1000, 600)
    main_window.show()

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

## Complete Examples

For a comprehensive demonstration of JCDock's capabilities and different API usage patterns, refer to the complete example script at `src/JCDock/Examples/dock_test.py`. This script showcases:

- **Registry-based widget creation** using `@dockable` decorators
- **Both API paths**: "By Type" (registry-based) and "By Instance" (existing widgets)
- **Layout persistence** with save/load functionality
- **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

This example serves as both a testing framework and a reference implementation, showing various ways to integrate JCDock into your applications.

## Advanced Features

### Layout Persistence

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

```python
from JCDock import dockable

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

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

# Create widgets using registry keys
manager.create_floating_widget_from_key("project_explorer")
manager.create_floating_widget_from_key("code_editor")

# 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

***
## 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/dd/bd/61cdf3282c425b2192e9ef3c43a19ede40e42faf91edc8eca687b79faea9/jcdock-1.0.1.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\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* **Floating Dock Roots**: Create multiple independent floating windows that can act as primary docking targets.\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## Architecture Overview\r\n\r\nJCDock uses a unified window model where all floating windows are `DockContainer` instances. The architecture is built around a central state machine with specialized components:\r\n\r\n### Core Components\r\n- **DockingManager**: Central orchestrator managing all docking operations, widget registration, and layout persistence\r\n- **DockingState**: State machine defining operational states (IDLE, RENDERING, DRAGGING_WINDOW, RESIZING_WINDOW, DRAGGING_TAB)\r\n- **DockPanel**: Wrapper for any QWidget to make it dockable with title bars and controls  \r\n- **DockContainer**: Advanced host containers with drag-and-drop capabilities and tab/splitter management\r\n- **MainDockWindow**: Main application window with built-in central dock area\r\n- **TearableTabWidget**: Enhanced tab widget supporting drag-out operations with visual feedback\r\n\r\n### Specialized Systems\r\n\r\n#### Core (`core/`)\r\n- **WidgetRegistry**: Registry system for widget types enabling automatic layout persistence\r\n- **DockingState**: State machine enum defining operational states\r\n\r\n#### Model (`model/`)\r\n- **LayoutSerializer**: Handles serialization and deserialization of dock layout state\r\n- **LayoutRenderer**: Handles layout rendering and state transitions\r\n- **LayoutModel**: Core data structures for layout representation\r\n\r\n#### Interaction (`interaction/`)\r\n- **DragDropController**: Manages drag-and-drop operations and visual feedback\r\n- **OverlayManager**: Manages visual overlay system during drag operations\r\n- **DockingOverlay**: Visual feedback overlays for drop zones\r\n\r\n#### Factories (`factories/`)\r\n- **WidgetFactory**: Creates and manages widget instances\r\n- **WindowManager**: Handles window creation and management\r\n- **ModelUpdateEngine**: Manages model state updates\r\n\r\n#### Utils (`utils/`)\r\n- **HitTestCache**: Performance optimization for overlay hit-testing during drag operations\r\n- **IconCache**: LRU cache system for icon rendering performance optimization\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    manager.create_simple_floating_widget(content, \"My Widget\")\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\nfrom JCDock.widgets.main_dock_window import MainDockWindow\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 the Main Window (automatically handles registration)\r\n    main_window = MainDockWindow(manager)\r\n\r\n    # 3. Create simple floating widgets\r\n    project_content = QLabel(\"Project Explorer\")\r\n    _, project_panel = manager.create_simple_floating_widget(project_content, \"Project\")\r\n\r\n    editor_content = QTextEdit(\"Your code here...\")\r\n    _, editor_panel = manager.create_simple_floating_widget(editor_content, \"Editor\")\r\n\r\n    # 4. Dock widgets to create layout\r\n    manager.dock_widget(project_panel, main_window.dock_area, \"left\")\r\n    manager.dock_widget(editor_panel, project_panel, \"right\")\r\n\r\n    main_window.setGeometry(100, 100, 1000, 600)\r\n    main_window.show()\r\n\r\n    sys.exit(app.exec())\r\n```\r\n\r\n## Complete Examples\r\n\r\nFor a comprehensive demonstration of JCDock's capabilities and different API usage patterns, refer to the complete example script at `src/JCDock/Examples/dock_test.py`. This script showcases:\r\n\r\n- **Registry-based widget creation** using `@dockable` decorators\r\n- **Both API paths**: \"By Type\" (registry-based) and \"By Instance\" (existing widgets)\r\n- **Layout persistence** with save/load functionality\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\r\nThis example serves as both a testing framework and a reference implementation, showing various ways to integrate JCDock into your applications.\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 `@dockable` decorated widgets:\r\n\r\n```python\r\nfrom JCDock import dockable\r\n\r\n# Register widget types for automatic layout persistence\r\n@dockable(\"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@dockable(\"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 registry keys\r\nmanager.create_floating_widget_from_key(\"project_explorer\")\r\nmanager.create_floating_widget_from_key(\"code_editor\")\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\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.0.1",
    "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": "6f9d8498ec0cc4cf6c4292c89ce4c447725b6d8196000a5b8a5f16b144c9a43e",
                "md5": "89a767bed806654b7bd4b27ad932c792",
                "sha256": "a212ff8e2ee7c8016c6c5ddd3db5e59872ceb8cd48022e287f435c665670d4f8"
            },
            "downloads": -1,
            "filename": "jcdock-1.0.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "89a767bed806654b7bd4b27ad932c792",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": null,
            "size": 80048,
            "upload_time": "2025-07-26T00:15:05",
            "upload_time_iso_8601": "2025-07-26T00:15:05.346617Z",
            "url": "https://files.pythonhosted.org/packages/6f/9d/8498ec0cc4cf6c4292c89ce4c447725b6d8196000a5b8a5f16b144c9a43e/jcdock-1.0.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "ddbd61cdf3282c425b2192e9ef3c43a19ede40e42faf91edc8eca687b79faea9",
                "md5": "995cf71056f39f5c1c7345df8753d3e5",
                "sha256": "e247adbce32db01ce9abf731bfcf2e0118fb53ebee442ee3b89c9593f8885a66"
            },
            "downloads": -1,
            "filename": "jcdock-1.0.1.tar.gz",
            "has_sig": false,
            "md5_digest": "995cf71056f39f5c1c7345df8753d3e5",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 72438,
            "upload_time": "2025-07-26T00:15:06",
            "upload_time_iso_8601": "2025-07-26T00:15:06.654170Z",
            "url": "https://files.pythonhosted.org/packages/dd/bd/61cdf3282c425b2192e9ef3c43a19ede40e42faf91edc8eca687b79faea9/jcdock-1.0.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-07-26 00:15:06",
    "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.03401s