""" OpenGL widget for pyPhotoAlbum rendering - refactored with mixins """ from PyQt6.QtOpenGLWidgets import QOpenGLWidget from PyQt6.QtCore import Qt from OpenGL.GL import * # Import all mixins from pyPhotoAlbum.mixins.viewport import ViewportMixin from pyPhotoAlbum.mixins.rendering import RenderingMixin from pyPhotoAlbum.mixins.asset_drop import AssetDropMixin from pyPhotoAlbum.mixins.page_navigation import PageNavigationMixin from pyPhotoAlbum.mixins.image_pan import ImagePanMixin from pyPhotoAlbum.mixins.element_manipulation import ElementManipulationMixin from pyPhotoAlbum.mixins.element_selection import ElementSelectionMixin from pyPhotoAlbum.mixins.mouse_interaction import MouseInteractionMixin from pyPhotoAlbum.mixins.interaction_undo import UndoableInteractionMixin from pyPhotoAlbum.mixins.async_loading import AsyncLoadingMixin class GLWidget( AsyncLoadingMixin, ViewportMixin, RenderingMixin, AssetDropMixin, PageNavigationMixin, ImagePanMixin, ElementManipulationMixin, ElementSelectionMixin, MouseInteractionMixin, UndoableInteractionMixin, QOpenGLWidget ): """OpenGL widget for pyPhotoAlbum rendering and user interaction This widget orchestrates multiple mixins to provide: - Async image loading (non-blocking) - Viewport control (zoom, pan) - Page rendering (OpenGL) - Element selection and manipulation - Mouse interaction handling - Drag-and-drop asset management - Image panning within frames - Page navigation and ghost pages - Undo/redo integration """ def __init__(self, parent=None): super().__init__(parent) # Initialize async loading system self._init_async_loading() # Initialize OpenGL self.setFormat(self.format()) self.setUpdateBehavior(QOpenGLWidget.UpdateBehavior.NoPartialUpdate) # Enable mouse tracking and drag-drop self.setMouseTracking(True) self.setAcceptDrops(True) def closeEvent(self, event): """Handle widget close event.""" # Cleanup async loading self._cleanup_async_loading() super().closeEvent(event) def keyPressEvent(self, event): """Handle key press events""" if event.key() == Qt.Key.Key_Delete or event.key() == Qt.Key.Key_Backspace: if self.selected_element: main_window = self.window() if hasattr(main_window, 'delete_selected_element'): main_window.delete_selected_element() elif event.key() == Qt.Key.Key_Escape: self.selected_element = None self.rotation_mode = False self.update() elif event.key() == Qt.Key.Key_Tab: # Toggle rotation mode when an element is selected if self.selected_element: self.rotation_mode = not self.rotation_mode main_window = self.window() if hasattr(main_window, 'show_status'): mode_text = "Rotation Mode" if self.rotation_mode else "Move/Resize Mode" main_window.show_status(f"Switched to {mode_text}", 2000) print(f"Rotation mode: {self.rotation_mode}") self.update() event.accept() else: super().keyPressEvent(event) else: super().keyPressEvent(event)