justified test and two finger scrolling
All checks were successful
Python CI / test (push) Successful in 1m27s
Lint / lint (push) Successful in 1m6s
Tests / test (3.11) (push) Successful in 1m42s
Tests / test (3.12) (push) Successful in 1m43s
Tests / test (3.13) (push) Successful in 1m37s
Tests / test (3.14) (push) Successful in 1m16s
All checks were successful
Python CI / test (push) Successful in 1m27s
Lint / lint (push) Successful in 1m6s
Tests / test (3.11) (push) Successful in 1m42s
Tests / test (3.12) (push) Successful in 1m43s
Tests / test (3.13) (push) Successful in 1m37s
Tests / test (3.14) (push) Successful in 1m16s
This commit is contained in:
parent
80d7d291f3
commit
8f1e906884
@ -77,6 +77,12 @@ class GLWidget(
|
||||
self.setFocusPolicy(Qt.FocusPolicy.StrongFocus)
|
||||
self.setFocus()
|
||||
|
||||
# Enable gesture support for pinch-to-zoom
|
||||
self.grabGesture(Qt.GestureType.PinchGesture)
|
||||
|
||||
# Track pinch gesture state
|
||||
self._pinch_scale_factor = 1.0
|
||||
|
||||
def window(self):
|
||||
"""Override window() to return stored main_window reference.
|
||||
|
||||
@ -154,3 +160,183 @@ class GLWidget(
|
||||
|
||||
else:
|
||||
super().keyPressEvent(event)
|
||||
|
||||
def event(self, event):
|
||||
"""Handle gesture events for pinch-to-zoom"""
|
||||
from PyQt6.QtCore import QEvent, Qt as QtCore
|
||||
from PyQt6.QtWidgets import QPinchGesture
|
||||
from PyQt6.QtGui import QNativeGestureEvent
|
||||
|
||||
# Handle native touchpad gestures (Linux, macOS)
|
||||
if event.type() == QEvent.Type.NativeGesture:
|
||||
native_event = event
|
||||
gesture_type = native_event.gestureType()
|
||||
|
||||
print(f"DEBUG: Native gesture detected - type: {gesture_type}")
|
||||
|
||||
# Check for zoom/pinch gesture
|
||||
if gesture_type == QtCore.NativeGestureType.ZoomNativeGesture:
|
||||
# Get zoom value (typically a delta around 0)
|
||||
value = native_event.value()
|
||||
print(f"DEBUG: Zoom value: {value}")
|
||||
|
||||
# Convert to scale factor (value is typically small, like -0.1 to 0.1)
|
||||
# Positive value = zoom in, negative = zoom out
|
||||
scale_factor = 1.0 + value
|
||||
|
||||
# Get the position of the gesture
|
||||
pos = native_event.position()
|
||||
mouse_x = pos.x()
|
||||
mouse_y = pos.y()
|
||||
|
||||
self._apply_zoom_at_point(mouse_x, mouse_y, scale_factor)
|
||||
return True
|
||||
|
||||
# Check for pan gesture (two-finger drag)
|
||||
elif gesture_type == QtCore.NativeGestureType.PanNativeGesture:
|
||||
# Get the pan delta
|
||||
delta = native_event.delta()
|
||||
dx = delta.x()
|
||||
dy = delta.y()
|
||||
|
||||
print(f"DEBUG: Pan delta: dx={dx}, dy={dy}")
|
||||
|
||||
# Apply pan
|
||||
self.pan_offset[0] += dx
|
||||
self.pan_offset[1] += dy
|
||||
|
||||
# Clamp pan offset to content bounds
|
||||
if hasattr(self, "clamp_pan_offset"):
|
||||
self.clamp_pan_offset()
|
||||
|
||||
self.update()
|
||||
|
||||
# Update scrollbars if available
|
||||
main_window = self.window()
|
||||
if hasattr(main_window, "update_scrollbars"):
|
||||
main_window.update_scrollbars()
|
||||
|
||||
return True
|
||||
|
||||
# Handle Qt gesture events (fallback for other platforms)
|
||||
elif event.type() == QEvent.Type.Gesture:
|
||||
print("DEBUG: Qt Gesture event detected")
|
||||
gesture_event = event
|
||||
pinch = gesture_event.gesture(Qt.GestureType.PinchGesture)
|
||||
|
||||
if pinch:
|
||||
print(f"DEBUG: Pinch gesture detected - state: {pinch.state()}, scale: {pinch.totalScaleFactor()}")
|
||||
self._handle_pinch_gesture(pinch)
|
||||
return True
|
||||
|
||||
return super().event(event)
|
||||
|
||||
def _handle_pinch_gesture(self, pinch):
|
||||
"""Handle pinch gesture for zooming"""
|
||||
from PyQt6.QtCore import Qt as QtCore
|
||||
|
||||
# Check gesture state
|
||||
state = pinch.state()
|
||||
|
||||
if state == QtCore.GestureState.GestureStarted:
|
||||
# Reset scale factor at gesture start
|
||||
self._pinch_scale_factor = 1.0
|
||||
return
|
||||
|
||||
elif state == QtCore.GestureState.GestureUpdated:
|
||||
# Get current total scale factor
|
||||
current_scale = pinch.totalScaleFactor()
|
||||
|
||||
# Calculate incremental change from last update
|
||||
if current_scale > 0:
|
||||
scale_change = current_scale / self._pinch_scale_factor
|
||||
self._pinch_scale_factor = current_scale
|
||||
|
||||
# Get the center point of the pinch gesture
|
||||
center_point = pinch.centerPoint()
|
||||
mouse_x = center_point.x()
|
||||
mouse_y = center_point.y()
|
||||
|
||||
# Calculate world coordinates at the pinch center
|
||||
world_x = (mouse_x - self.pan_offset[0]) / self.zoom_level
|
||||
world_y = (mouse_y - self.pan_offset[1]) / self.zoom_level
|
||||
|
||||
# Apply incremental zoom change
|
||||
new_zoom = self.zoom_level * scale_change
|
||||
|
||||
# Clamp zoom level to reasonable bounds
|
||||
if 0.1 <= new_zoom <= 5.0:
|
||||
old_pan_x = self.pan_offset[0]
|
||||
old_pan_y = self.pan_offset[1]
|
||||
|
||||
self.zoom_level = new_zoom
|
||||
|
||||
# Adjust pan offset to keep the pinch center point fixed
|
||||
self.pan_offset[0] = mouse_x - world_x * self.zoom_level
|
||||
self.pan_offset[1] = mouse_y - world_y * self.zoom_level
|
||||
|
||||
# If dragging, adjust drag_start_pos to account for pan_offset change
|
||||
if hasattr(self, 'is_dragging') and self.is_dragging and hasattr(self, 'drag_start_pos') and self.drag_start_pos:
|
||||
pan_delta_x = self.pan_offset[0] - old_pan_x
|
||||
pan_delta_y = self.pan_offset[1] - old_pan_y
|
||||
self.drag_start_pos = (self.drag_start_pos[0] + pan_delta_x, self.drag_start_pos[1] + pan_delta_y)
|
||||
|
||||
# Clamp pan offset to content bounds
|
||||
if hasattr(self, "clamp_pan_offset"):
|
||||
self.clamp_pan_offset()
|
||||
|
||||
self.update()
|
||||
|
||||
# Update status bar
|
||||
main_window = self.window()
|
||||
if hasattr(main_window, "status_bar"):
|
||||
main_window.status_bar.showMessage(f"Zoom: {int(self.zoom_level * 100)}%", 2000)
|
||||
|
||||
# Update scrollbars if available
|
||||
if hasattr(main_window, "update_scrollbars"):
|
||||
main_window.update_scrollbars()
|
||||
|
||||
elif state == QtCore.GestureState.GestureFinished or state == QtCore.GestureState.GestureCanceled:
|
||||
# Reset on gesture end
|
||||
self._pinch_scale_factor = 1.0
|
||||
|
||||
def _apply_zoom_at_point(self, mouse_x, mouse_y, scale_factor):
|
||||
"""Apply zoom centered at a specific point"""
|
||||
# Calculate world coordinates at the zoom center
|
||||
world_x = (mouse_x - self.pan_offset[0]) / self.zoom_level
|
||||
world_y = (mouse_y - self.pan_offset[1]) / self.zoom_level
|
||||
|
||||
# Apply zoom
|
||||
new_zoom = self.zoom_level * scale_factor
|
||||
|
||||
# Clamp zoom level to reasonable bounds
|
||||
if 0.1 <= new_zoom <= 5.0:
|
||||
old_pan_x = self.pan_offset[0]
|
||||
old_pan_y = self.pan_offset[1]
|
||||
|
||||
self.zoom_level = new_zoom
|
||||
|
||||
# Adjust pan offset to keep the zoom center point fixed
|
||||
self.pan_offset[0] = mouse_x - world_x * self.zoom_level
|
||||
self.pan_offset[1] = mouse_y - world_y * self.zoom_level
|
||||
|
||||
# If dragging, adjust drag_start_pos to account for pan_offset change
|
||||
if hasattr(self, 'is_dragging') and self.is_dragging and hasattr(self, 'drag_start_pos') and self.drag_start_pos:
|
||||
pan_delta_x = self.pan_offset[0] - old_pan_x
|
||||
pan_delta_y = self.pan_offset[1] - old_pan_y
|
||||
self.drag_start_pos = (self.drag_start_pos[0] + pan_delta_x, self.drag_start_pos[1] + pan_delta_y)
|
||||
|
||||
# Clamp pan offset to content bounds
|
||||
if hasattr(self, "clamp_pan_offset"):
|
||||
self.clamp_pan_offset()
|
||||
|
||||
self.update()
|
||||
|
||||
# Update status bar
|
||||
main_window = self.window()
|
||||
if hasattr(main_window, "status_bar"):
|
||||
main_window.status_bar.showMessage(f"Zoom: {int(self.zoom_level * 100)}%", 2000)
|
||||
|
||||
# Update scrollbars if available
|
||||
if hasattr(main_window, "update_scrollbars"):
|
||||
main_window.update_scrollbars()
|
||||
|
||||
@ -281,6 +281,8 @@ class RenderingMixin:
|
||||
alignment = Qt.AlignmentFlag.AlignHCenter | Qt.AlignmentFlag.AlignTop
|
||||
elif element.alignment == "right":
|
||||
alignment = Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignTop
|
||||
elif element.alignment == "justify":
|
||||
alignment = Qt.AlignmentFlag.AlignJustify | Qt.AlignmentFlag.AlignTop
|
||||
|
||||
text_flags = Qt.TextFlag.TextWordWrap
|
||||
|
||||
|
||||
@ -10,7 +10,7 @@ from reportlab.pdfgen import canvas
|
||||
from reportlab.lib.utils import ImageReader
|
||||
from reportlab.platypus import Paragraph
|
||||
from reportlab.lib.styles import ParagraphStyle
|
||||
from reportlab.lib.enums import TA_LEFT, TA_CENTER, TA_RIGHT
|
||||
from reportlab.lib.enums import TA_LEFT, TA_CENTER, TA_RIGHT, TA_JUSTIFY
|
||||
from PIL import Image
|
||||
import math
|
||||
from pyPhotoAlbum.models import ImageData, TextBoxData, PlaceholderData
|
||||
@ -575,6 +575,7 @@ class PDFExporter:
|
||||
"left": TA_LEFT,
|
||||
"center": TA_CENTER,
|
||||
"right": TA_RIGHT,
|
||||
"justify": TA_JUSTIFY,
|
||||
}
|
||||
text_alignment = alignment_map.get(text_element.alignment, TA_LEFT)
|
||||
|
||||
|
||||
@ -74,7 +74,7 @@ class TextEditDialog(QDialog):
|
||||
alignment_layout = QHBoxLayout()
|
||||
alignment_layout.addWidget(QLabel("Alignment:"))
|
||||
self.alignment_combo = QComboBox()
|
||||
self.alignment_combo.addItems(["left", "center", "right"])
|
||||
self.alignment_combo.addItems(["left", "center", "right", "justify"])
|
||||
alignment_layout.addWidget(self.alignment_combo)
|
||||
alignment_layout.addStretch()
|
||||
layout.addLayout(alignment_layout)
|
||||
|
||||
@ -496,7 +496,7 @@ class TestRenderTextOverlays:
|
||||
qtbot.addWidget(widget)
|
||||
widget.resize(1000, 800)
|
||||
|
||||
for alignment in ["left", "center", "right"]:
|
||||
for alignment in ["left", "center", "right", "justify"]:
|
||||
# Create text element with alignment
|
||||
text_element = TextBoxData(
|
||||
x=50, y=50, width=200, height=100,
|
||||
|
||||
@ -178,6 +178,7 @@ class TestTextEditDialogUI:
|
||||
assert "left" in options
|
||||
assert "center" in options
|
||||
assert "right" in options
|
||||
assert "justify" in options
|
||||
|
||||
def test_font_options(self, qtbot):
|
||||
"""Test that font combo has expected fonts"""
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user