98 lines
3.3 KiB
Python
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)
|