pyPhotoAlbum/pyPhotoAlbum/gl_widget.py
2025-11-11 15:34:04 +01:00

98 lines
3.3 KiB
Python

"""
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)