feat: Enhanced Activity Bar with drag, resize, opacity, and customization
Activity Bar Improvements: - Draggable: Grab left handle to move anywhere on screen - Resizable: Grab right handle to change width (400-1600px) - Background Opacity: Now actually works (20-100%) - Search toggle: Right-click menu to show/hide search box - Clock toggle: Right-click menu to show/hide clock - Reset Position: Right-click menu to reset to default position - Settings dialog: Added opacity slider, width, search/clock toggles Config additions: - x, y: Custom position - width: Bar width (400-1600) - background_opacity: 20-100% - show_search: Toggle search visibility - show_clock: Toggle clock visibility Bug Fixes: - OverlayController now inherits QObject (fixes 'cannot be converted' error) - Activity bar saves position when dragged - Activity bar saves width when resized
This commit is contained in:
parent
159f7a4a05
commit
4b5096a859
|
|
@ -27,11 +27,17 @@ from core.icon_manager import get_icon_manager
|
|||
class ActivityBarConfig:
|
||||
"""Activity bar configuration."""
|
||||
enabled: bool = True
|
||||
position: str = "bottom" # top, bottom
|
||||
position: str = "bottom" # top, bottom, custom
|
||||
x: int = 100 # custom X position
|
||||
y: int = 800 # custom Y position
|
||||
width: int = 800 # custom width
|
||||
icon_size: int = 32
|
||||
auto_hide: bool = True
|
||||
auto_hide: bool = False # Disabled by default for easier use
|
||||
auto_hide_delay: int = 3000 # milliseconds
|
||||
auto_show_on_focus: bool = False # DISABLED by default - causes UI freezing
|
||||
auto_show_on_focus: bool = False
|
||||
background_opacity: int = 90 # 0-100
|
||||
show_search: bool = True
|
||||
show_clock: bool = True
|
||||
pinned_plugins: List[str] = None
|
||||
|
||||
def __post_init__(self):
|
||||
|
|
@ -42,10 +48,16 @@ class ActivityBarConfig:
|
|||
return {
|
||||
'enabled': self.enabled,
|
||||
'position': self.position,
|
||||
'x': self.x,
|
||||
'y': self.y,
|
||||
'width': self.width,
|
||||
'icon_size': self.icon_size,
|
||||
'auto_hide': self.auto_hide,
|
||||
'auto_hide_delay': self.auto_hide_delay,
|
||||
'auto_show_on_focus': self.auto_show_on_focus,
|
||||
'background_opacity': self.background_opacity,
|
||||
'show_search': self.show_search,
|
||||
'show_clock': self.show_clock,
|
||||
'pinned_plugins': self.pinned_plugins
|
||||
}
|
||||
|
||||
|
|
@ -54,9 +66,16 @@ class ActivityBarConfig:
|
|||
return cls(
|
||||
enabled=data.get('enabled', True),
|
||||
position=data.get('position', 'bottom'),
|
||||
x=data.get('x', 100),
|
||||
y=data.get('y', 800),
|
||||
width=data.get('width', 800),
|
||||
icon_size=data.get('icon_size', 32),
|
||||
auto_hide=data.get('auto_hide', True),
|
||||
auto_hide=data.get('auto_hide', False),
|
||||
auto_hide_delay=data.get('auto_hide_delay', 3000),
|
||||
auto_show_on_focus=data.get('auto_show_on_focus', False),
|
||||
background_opacity=data.get('background_opacity', 90),
|
||||
show_search=data.get('show_search', True),
|
||||
show_clock=data.get('show_clock', True),
|
||||
pinned_plugins=data.get('pinned_plugins', [])
|
||||
)
|
||||
|
||||
|
|
@ -115,19 +134,21 @@ class WindowsTaskbar(QFrame):
|
|||
self._drag_offset = QPoint()
|
||||
|
||||
def _setup_ui(self):
|
||||
"""Setup Windows taskbar-style UI."""
|
||||
"""Setup Windows taskbar-style UI with draggable and resizable features."""
|
||||
# Main layout with minimal margins
|
||||
layout = QHBoxLayout(self)
|
||||
layout.setContentsMargins(8, 4, 8, 4)
|
||||
layout.setSpacing(4)
|
||||
self.main_layout = QHBoxLayout(self)
|
||||
self.main_layout.setContentsMargins(8, 4, 8, 4)
|
||||
self.main_layout.setSpacing(4)
|
||||
|
||||
# Style: No background, just floating elements
|
||||
self.setStyleSheet("""
|
||||
WindowsTaskbar {
|
||||
background: transparent;
|
||||
border: none;
|
||||
}
|
||||
""")
|
||||
# Apply opacity from config
|
||||
self._apply_opacity()
|
||||
|
||||
# === DRAG HANDLE (invisible, left side) ===
|
||||
self.drag_handle = QFrame()
|
||||
self.drag_handle.setFixedSize(8, 40)
|
||||
self.drag_handle.setStyleSheet("background: transparent; cursor: move;")
|
||||
self.drag_handle.setToolTip("Drag to move")
|
||||
self.main_layout.addWidget(self.drag_handle)
|
||||
|
||||
# === START BUTTON (Windows-style icon) ===
|
||||
self.start_btn = QPushButton()
|
||||
|
|
@ -150,7 +171,7 @@ class WindowsTaskbar(QFrame):
|
|||
""")
|
||||
self.start_btn.setToolTip("Open App Drawer")
|
||||
self.start_btn.clicked.connect(self._toggle_drawer)
|
||||
layout.addWidget(self.start_btn)
|
||||
self.main_layout.addWidget(self.start_btn)
|
||||
|
||||
# === SEARCH BOX (Windows 11 style) ===
|
||||
self.search_box = QLineEdit()
|
||||
|
|
@ -179,31 +200,39 @@ class WindowsTaskbar(QFrame):
|
|||
""")
|
||||
self.search_box.returnPressed.connect(self._on_search)
|
||||
self.search_box.textChanged.connect(self._on_search_text_changed)
|
||||
layout.addWidget(self.search_box)
|
||||
self.main_layout.addWidget(self.search_box)
|
||||
|
||||
# Search visibility
|
||||
self.search_box.setVisible(self.config.show_search)
|
||||
|
||||
# Separator
|
||||
separator = QFrame()
|
||||
separator.setFixedSize(1, 24)
|
||||
separator.setStyleSheet("background: rgba(255, 255, 255, 0.1);")
|
||||
layout.addWidget(separator)
|
||||
self.main_layout.addWidget(separator)
|
||||
|
||||
# === PINNED PLUGINS AREA (expandable) ===
|
||||
self.pinned_container = QWidget()
|
||||
self.pinned_layout = QHBoxLayout(self.pinned_container)
|
||||
self.pinned_layout.setContentsMargins(0, 0, 0, 0)
|
||||
self.pinned_layout.setSpacing(4)
|
||||
layout.addWidget(self.pinned_container)
|
||||
self.main_layout.addWidget(self.pinned_container)
|
||||
|
||||
# Spacer to push icons together
|
||||
layout.addStretch()
|
||||
self.main_layout.addStretch()
|
||||
|
||||
# === CLOCK AREA ===
|
||||
self.clock_widget = QWidget()
|
||||
clock_layout = QHBoxLayout(self.clock_widget)
|
||||
clock_layout.setContentsMargins(0, 0, 0, 0)
|
||||
clock_layout.setSpacing(4)
|
||||
|
||||
# === SYSTEM TRAY AREA ===
|
||||
# Clock icon
|
||||
self.clock_icon = QLabel()
|
||||
clock_pixmap = self.icon_manager.get_pixmap("clock", size=14)
|
||||
self.clock_icon.setPixmap(clock_pixmap)
|
||||
self.clock_icon.setStyleSheet("padding-right: 4px;")
|
||||
layout.addWidget(self.clock_icon)
|
||||
clock_layout.addWidget(self.clock_icon)
|
||||
|
||||
# Clock time
|
||||
self.clock_label = QLabel("12:00")
|
||||
|
|
@ -213,7 +242,19 @@ class WindowsTaskbar(QFrame):
|
|||
padding: 0 8px;
|
||||
""")
|
||||
self.clock_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
layout.addWidget(self.clock_label)
|
||||
clock_layout.addWidget(self.clock_label)
|
||||
|
||||
self.main_layout.addWidget(self.clock_widget)
|
||||
|
||||
# Clock visibility
|
||||
self.clock_widget.setVisible(self.config.show_clock)
|
||||
|
||||
# === RESIZE HANDLE (right side) ===
|
||||
self.resize_handle = QFrame()
|
||||
self.resize_handle.setFixedSize(8, 40)
|
||||
self.resize_handle.setStyleSheet("background: transparent; cursor: size-hor-cursor;")
|
||||
self.resize_handle.setToolTip("Drag to resize")
|
||||
self.main_layout.addWidget(self.resize_handle)
|
||||
|
||||
# Start clock update timer
|
||||
self.clock_timer = QTimer(self)
|
||||
|
|
@ -228,6 +269,9 @@ class WindowsTaskbar(QFrame):
|
|||
# Refresh pinned plugins
|
||||
self._refresh_pinned_plugins()
|
||||
|
||||
# Set initial size and position
|
||||
self._apply_size_and_position()
|
||||
|
||||
def _create_plugin_button(self, plugin_id: str, plugin_class) -> QPushButton:
|
||||
"""Create a pinned plugin button (taskbar icon style)."""
|
||||
btn = QPushButton()
|
||||
|
|
@ -352,6 +396,83 @@ class WindowsTaskbar(QFrame):
|
|||
plugins_layout.addStretch()
|
||||
layout.addWidget(plugins_widget)
|
||||
|
||||
def mousePressEvent(self, event: QMouseEvent):
|
||||
"""Handle mouse press for dragging."""
|
||||
if event.button() == Qt.MouseButton.LeftButton:
|
||||
# Check if clicking on drag handle
|
||||
if self.drag_handle.geometry().contains(event.pos()):
|
||||
self._dragging = True
|
||||
self._drag_offset = event.globalPosition().toPoint() - self.frameGeometry().topLeft()
|
||||
event.accept()
|
||||
# Check if clicking on resize handle
|
||||
elif self.resize_handle.geometry().contains(event.pos()):
|
||||
self._resizing = True
|
||||
self._resize_start_x = event.globalPosition().x()
|
||||
self._resize_start_width = self.width()
|
||||
event.accept()
|
||||
else:
|
||||
super().mousePressEvent(event)
|
||||
|
||||
def mouseMoveEvent(self, event: QMouseEvent):
|
||||
"""Handle mouse move for dragging and resizing."""
|
||||
if self._dragging:
|
||||
new_pos = event.globalPosition().toPoint() - self._drag_offset
|
||||
self.move(new_pos)
|
||||
# Save position
|
||||
self.config.x = new_pos.x()
|
||||
self.config.y = new_pos.y()
|
||||
self._save_config()
|
||||
event.accept()
|
||||
elif getattr(self, '_resizing', False):
|
||||
delta = event.globalPosition().x() - self._resize_start_x
|
||||
new_width = max(400, self._resize_start_width + delta)
|
||||
self.setFixedWidth(int(new_width))
|
||||
self.config.width = int(new_width)
|
||||
self._save_config()
|
||||
event.accept()
|
||||
else:
|
||||
super().mouseMoveEvent(event)
|
||||
|
||||
def mouseReleaseEvent(self, event: QMouseEvent):
|
||||
"""Handle mouse release."""
|
||||
if event.button() == Qt.MouseButton.LeftButton:
|
||||
self._dragging = False
|
||||
self._resizing = False
|
||||
super().mouseReleaseEvent(event)
|
||||
|
||||
def _apply_opacity(self):
|
||||
"""Apply background opacity from config."""
|
||||
opacity = self.config.background_opacity / 100.0
|
||||
# Create a background widget with opacity
|
||||
bg_color = f"rgba(20, 31, 35, {opacity})"
|
||||
self.setStyleSheet(f"""
|
||||
WindowsTaskbar {{
|
||||
background: {bg_color};
|
||||
border: 1px solid rgba(255, 140, 66, 0.1);
|
||||
border-radius: 12px;
|
||||
}}
|
||||
""")
|
||||
|
||||
def _apply_size_and_position(self):
|
||||
"""Apply saved size and position."""
|
||||
self.setFixedHeight(56)
|
||||
self.setFixedWidth(self.config.width)
|
||||
|
||||
if self.config.position == "custom":
|
||||
self.move(self.config.x, self.config.y)
|
||||
elif self.config.position == "bottom":
|
||||
screen = QApplication.primaryScreen().geometry()
|
||||
self.move(
|
||||
(screen.width() - self.config.width) // 2,
|
||||
screen.height() - 80
|
||||
)
|
||||
elif self.config.position == "top":
|
||||
screen = QApplication.primaryScreen().geometry()
|
||||
self.move(
|
||||
(screen.width() - self.config.width) // 2,
|
||||
20
|
||||
)
|
||||
|
||||
def _create_drawer_item(self, plugin_id: str, plugin_class) -> QPushButton:
|
||||
"""Create a drawer item (like Start menu app)."""
|
||||
icon_name = getattr(plugin_class, 'icon_name', 'grid')
|
||||
|
|
@ -433,16 +554,52 @@ class WindowsTaskbar(QFrame):
|
|||
}
|
||||
""")
|
||||
|
||||
settings_action = menu.addAction("Settings")
|
||||
settings_action.triggered.connect(self._show_settings)
|
||||
# Toggle search
|
||||
search_action = menu.addAction("☑ Search" if self.config.show_search else "☐ Search")
|
||||
search_action.triggered.connect(self._toggle_search)
|
||||
|
||||
# Toggle clock
|
||||
clock_action = menu.addAction("☑ Clock" if self.config.show_clock else "☐ Clock")
|
||||
clock_action.triggered.connect(self._toggle_clock)
|
||||
|
||||
menu.addSeparator()
|
||||
|
||||
# Settings
|
||||
settings_action = menu.addAction("Settings...")
|
||||
settings_action.triggered.connect(self._show_settings)
|
||||
|
||||
# Reset position
|
||||
reset_action = menu.addAction("Reset Position")
|
||||
reset_action.triggered.connect(self._reset_position)
|
||||
|
||||
menu.addSeparator()
|
||||
|
||||
# Hide
|
||||
hide_action = menu.addAction("Hide")
|
||||
hide_action.triggered.connect(self.hide)
|
||||
|
||||
menu.exec(self.mapToGlobal(position))
|
||||
|
||||
def _toggle_search(self):
|
||||
"""Toggle search box visibility."""
|
||||
self.config.show_search = not self.config.show_search
|
||||
self.search_box.setVisible(self.config.show_search)
|
||||
self._save_config()
|
||||
|
||||
def _toggle_clock(self):
|
||||
"""Toggle clock visibility."""
|
||||
self.config.show_clock = not self.config.show_clock
|
||||
self.clock_widget.setVisible(self.config.show_clock)
|
||||
self._save_config()
|
||||
|
||||
def _reset_position(self):
|
||||
"""Reset bar position to default."""
|
||||
self.config.position = "bottom"
|
||||
self.config.x = 100
|
||||
self.config.y = 800
|
||||
self._apply_size_and_position()
|
||||
self._save_config()
|
||||
|
||||
def _show_settings(self):
|
||||
"""Show settings dialog."""
|
||||
dialog = TaskbarSettingsDialog(self.config, self)
|
||||
|
|
@ -457,15 +614,15 @@ class WindowsTaskbar(QFrame):
|
|||
# Set auto-hide timer
|
||||
self.hide_timer.setInterval(self.config.auto_hide_delay)
|
||||
|
||||
# Position bar
|
||||
screen = QApplication.primaryScreen().geometry()
|
||||
if self.config.position == "bottom":
|
||||
self.move((screen.width() - 600) // 2, screen.height() - 60)
|
||||
else: # top
|
||||
self.move((screen.width() - 600) // 2, 10)
|
||||
# Apply opacity
|
||||
self._apply_opacity()
|
||||
|
||||
# Size
|
||||
self.setFixedSize(600, 50)
|
||||
# Apply size and position
|
||||
self._apply_size_and_position()
|
||||
|
||||
# Show/hide search and clock
|
||||
self.search_box.setVisible(self.config.show_search)
|
||||
self.clock_widget.setVisible(self.config.show_clock)
|
||||
|
||||
def _auto_hide(self):
|
||||
"""Auto-hide when mouse leaves."""
|
||||
|
|
@ -484,24 +641,6 @@ class WindowsTaskbar(QFrame):
|
|||
self.hide_timer.start()
|
||||
super().leaveEvent(event)
|
||||
|
||||
def mousePressEvent(self, event: QMouseEvent):
|
||||
"""Start dragging."""
|
||||
if event.button() == Qt.MouseButton.LeftButton:
|
||||
self._dragging = True
|
||||
self._drag_offset = event.globalPosition().toPoint() - self.frameGeometry().topLeft()
|
||||
event.accept()
|
||||
|
||||
def mouseMoveEvent(self, event: QMouseEvent):
|
||||
"""Drag window."""
|
||||
if self._dragging:
|
||||
new_pos = event.globalPosition().toPoint() - self._drag_offset
|
||||
self.move(new_pos)
|
||||
|
||||
def mouseReleaseEvent(self, event: QMouseEvent):
|
||||
"""Stop dragging."""
|
||||
if event.button() == Qt.MouseButton.LeftButton:
|
||||
self._dragging = False
|
||||
|
||||
def _load_config(self) -> ActivityBarConfig:
|
||||
"""Load configuration."""
|
||||
config_path = Path("config/activity_bar.json")
|
||||
|
|
@ -526,36 +665,85 @@ class TaskbarSettingsDialog(QDialog):
|
|||
def __init__(self, config: ActivityBarConfig, parent=None):
|
||||
super().__init__(parent)
|
||||
self.config = config
|
||||
self.setWindowTitle("Taskbar Settings")
|
||||
self.setMinimumSize(350, 300)
|
||||
self.setWindowTitle("Activity Bar Settings")
|
||||
self.setMinimumSize(400, 450)
|
||||
self._setup_ui()
|
||||
|
||||
def _setup_ui(self):
|
||||
"""Setup settings UI."""
|
||||
from PyQt6.QtWidgets import QVBoxLayout, QFormLayout, QDialogButtonBox
|
||||
from PyQt6.QtWidgets import QVBoxLayout, QFormLayout, QDialogButtonBox, QGroupBox
|
||||
|
||||
layout = QVBoxLayout(self)
|
||||
|
||||
form = QFormLayout()
|
||||
# Appearance Group
|
||||
appear_group = QGroupBox("Appearance")
|
||||
appear_form = QFormLayout(appear_group)
|
||||
|
||||
# Auto-hide
|
||||
self.autohide_cb = QCheckBox("Auto-hide when not in use")
|
||||
self.autohide_cb.setChecked(self.config.auto_hide)
|
||||
form.addRow(self.autohide_cb)
|
||||
|
||||
# Position
|
||||
self.position_combo = QComboBox()
|
||||
self.position_combo.addItems(["Bottom", "Top"])
|
||||
self.position_combo.setCurrentText(self.config.position.title())
|
||||
form.addRow("Position:", self.position_combo)
|
||||
# Opacity
|
||||
self.opacity_slider = QSlider(Qt.Orientation.Horizontal)
|
||||
self.opacity_slider.setRange(20, 100)
|
||||
self.opacity_slider.setValue(self.config.background_opacity)
|
||||
self.opacity_label = QLabel(f"{self.config.background_opacity}%")
|
||||
self.opacity_slider.valueChanged.connect(lambda v: self.opacity_label.setText(f"{v}%"))
|
||||
opacity_layout = QHBoxLayout()
|
||||
opacity_layout.addWidget(self.opacity_slider)
|
||||
opacity_layout.addWidget(self.opacity_label)
|
||||
appear_form.addRow("Background Opacity:", opacity_layout)
|
||||
|
||||
# Icon size
|
||||
self.icon_size = QSpinBox()
|
||||
self.icon_size.setRange(24, 48)
|
||||
self.icon_size.setValue(self.config.icon_size)
|
||||
form.addRow("Icon Size:", self.icon_size)
|
||||
appear_form.addRow("Icon Size:", self.icon_size)
|
||||
|
||||
layout.addLayout(form)
|
||||
layout.addWidget(appear_group)
|
||||
|
||||
# Features Group
|
||||
features_group = QGroupBox("Features")
|
||||
features_form = QFormLayout(features_group)
|
||||
|
||||
# Show search
|
||||
self.show_search_cb = QCheckBox("Show search box")
|
||||
self.show_search_cb.setChecked(self.config.show_search)
|
||||
features_form.addRow(self.show_search_cb)
|
||||
|
||||
# Show clock
|
||||
self.show_clock_cb = QCheckBox("Show clock")
|
||||
self.show_clock_cb.setChecked(self.config.show_clock)
|
||||
features_form.addRow(self.show_clock_cb)
|
||||
|
||||
layout.addWidget(features_group)
|
||||
|
||||
# Position Group
|
||||
pos_group = QGroupBox("Position")
|
||||
pos_form = QFormLayout(pos_group)
|
||||
|
||||
# Position
|
||||
self.position_combo = QComboBox()
|
||||
self.position_combo.addItems(["Bottom", "Top", "Custom"])
|
||||
self.position_combo.setCurrentText(self.config.position.title())
|
||||
pos_form.addRow("Position:", self.position_combo)
|
||||
|
||||
# Width
|
||||
self.width_spin = QSpinBox()
|
||||
self.width_spin.setRange(400, 1600)
|
||||
self.width_spin.setValue(self.config.width)
|
||||
pos_form.addRow("Width:", self.width_spin)
|
||||
|
||||
layout.addWidget(pos_group)
|
||||
|
||||
# Behavior Group
|
||||
behav_group = QGroupBox("Behavior")
|
||||
behav_form = QFormLayout(behav_group)
|
||||
|
||||
# Auto-hide
|
||||
self.autohide_cb = QCheckBox("Auto-hide when not in use")
|
||||
self.autohide_cb.setChecked(self.config.auto_hide)
|
||||
behav_form.addRow(self.autohide_cb)
|
||||
|
||||
layout.addWidget(behav_group)
|
||||
|
||||
layout.addStretch()
|
||||
|
||||
# Buttons
|
||||
buttons = QDialogButtonBox(
|
||||
|
|
@ -570,9 +758,16 @@ class TaskbarSettingsDialog(QDialog):
|
|||
return ActivityBarConfig(
|
||||
enabled=True,
|
||||
position=self.position_combo.currentText().lower(),
|
||||
x=self.config.x,
|
||||
y=self.config.y,
|
||||
width=self.width_spin.value(),
|
||||
icon_size=self.icon_size.value(),
|
||||
auto_hide=self.autohide_cb.isChecked(),
|
||||
auto_hide_delay=self.config.auto_hide_delay,
|
||||
auto_show_on_focus=self.config.auto_show_on_focus,
|
||||
background_opacity=self.opacity_slider.value(),
|
||||
show_search=self.show_search_cb.isChecked(),
|
||||
show_clock=self.show_clock_cb.isChecked(),
|
||||
pinned_plugins=self.config.pinned_plugins
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -180,7 +180,8 @@ class EUUtilityApp:
|
|||
# Get overlay controller with window manager
|
||||
self.overlay_controller = get_overlay_controller(
|
||||
self.activity_bar,
|
||||
getattr(self, 'window_manager', None)
|
||||
getattr(self, 'window_manager', None),
|
||||
parent=self.app # Pass QApplication as parent
|
||||
)
|
||||
|
||||
# Set mode from settings (default: game focused - Blish HUD style)
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ Modes:
|
|||
from enum import Enum
|
||||
from dataclasses import dataclass
|
||||
from typing import Optional
|
||||
from PyQt6.QtCore import QTimer, pyqtSignal
|
||||
from PyQt6.QtCore import QTimer, pyqtSignal, QObject
|
||||
|
||||
|
||||
class OverlayMode(Enum):
|
||||
|
|
@ -57,7 +57,7 @@ class OverlayConfig:
|
|||
)
|
||||
|
||||
|
||||
class OverlayController:
|
||||
class OverlayController(QObject):
|
||||
"""
|
||||
Controls activity bar visibility based on selected mode.
|
||||
|
||||
|
|
@ -69,7 +69,8 @@ class OverlayController:
|
|||
|
||||
visibility_changed = pyqtSignal(bool) # is_visible
|
||||
|
||||
def __init__(self, activity_bar, window_manager=None):
|
||||
def __init__(self, activity_bar, window_manager=None, parent=None):
|
||||
super().__init__(parent)
|
||||
self.activity_bar = activity_bar
|
||||
self.window_manager = window_manager
|
||||
self.config = OverlayConfig()
|
||||
|
|
@ -240,11 +241,11 @@ class OverlayController:
|
|||
# Singleton instance
|
||||
_overlay_controller = None
|
||||
|
||||
def get_overlay_controller(activity_bar=None, window_manager=None):
|
||||
def get_overlay_controller(activity_bar=None, window_manager=None, parent=None):
|
||||
"""Get or create the overlay controller singleton."""
|
||||
global _overlay_controller
|
||||
if _overlay_controller is None:
|
||||
if activity_bar is None:
|
||||
raise ValueError("activity_bar required for first initialization")
|
||||
_overlay_controller = OverlayController(activity_bar, window_manager)
|
||||
_overlay_controller = OverlayController(activity_bar, window_manager, parent)
|
||||
return _overlay_controller
|
||||
|
|
|
|||
Loading…
Reference in New Issue