2025-11-11 15:34:04 +01:00

171 lines
5.8 KiB
Python

"""
Alignment operations mixin for pyPhotoAlbum
"""
from pyPhotoAlbum.decorators import ribbon_action
from pyPhotoAlbum.alignment import AlignmentManager
from pyPhotoAlbum.commands import AlignElementsCommand, ResizeElementsCommand
class AlignmentOperationsMixin:
"""Mixin providing element alignment operations"""
def _get_selected_elements_list(self):
"""Get list of selected elements for alignment operations"""
return list(self.gl_widget.selected_elements) if self.gl_widget.selected_elements else []
@ribbon_action(
label="Align Left",
tooltip="Align selected elements to the left",
tab="Arrange",
group="Align",
requires_selection=True,
min_selection=2
)
def align_left(self):
"""Align selected elements to the left"""
elements = self._get_selected_elements_list()
if not self.require_selection(min_count=2):
return
changes = AlignmentManager.align_left(elements)
if changes:
cmd = AlignElementsCommand(changes)
self.project.history.execute(cmd)
self.update_view()
self.show_status(f"Aligned {len(elements)} elements to left", 2000)
@ribbon_action(
label="Align Right",
tooltip="Align selected elements to the right",
tab="Arrange",
group="Align",
requires_selection=True,
min_selection=2
)
def align_right(self):
"""Align selected elements to the right"""
elements = self._get_selected_elements_list()
if not self.require_selection(min_count=2):
return
changes = AlignmentManager.align_right(elements)
if changes:
cmd = AlignElementsCommand(changes)
self.project.history.execute(cmd)
self.update_view()
self.show_status(f"Aligned {len(elements)} elements to right", 2000)
@ribbon_action(
label="Align Top",
tooltip="Align selected elements to the top",
tab="Arrange",
group="Align",
requires_selection=True,
min_selection=2
)
def align_top(self):
"""Align selected elements to the top"""
elements = self._get_selected_elements_list()
if not self.require_selection(min_count=2):
return
changes = AlignmentManager.align_top(elements)
if changes:
cmd = AlignElementsCommand(changes)
self.project.history.execute(cmd)
self.update_view()
self.show_status(f"Aligned {len(elements)} elements to top", 2000)
@ribbon_action(
label="Align Bottom",
tooltip="Align selected elements to the bottom",
tab="Arrange",
group="Align",
requires_selection=True,
min_selection=2
)
def align_bottom(self):
"""Align selected elements to the bottom"""
elements = self._get_selected_elements_list()
if not self.require_selection(min_count=2):
return
changes = AlignmentManager.align_bottom(elements)
if changes:
cmd = AlignElementsCommand(changes)
self.project.history.execute(cmd)
self.update_view()
self.show_status(f"Aligned {len(elements)} elements to bottom", 2000)
@ribbon_action(
label="Align H-Center",
tooltip="Align selected elements to horizontal center",
tab="Arrange",
group="Align",
requires_selection=True,
min_selection=2
)
def align_horizontal_center(self):
"""Align selected elements to horizontal center"""
elements = self._get_selected_elements_list()
if not self.require_selection(min_count=2):
return
changes = AlignmentManager.align_horizontal_center(elements)
if changes:
cmd = AlignElementsCommand(changes)
self.project.history.execute(cmd)
self.update_view()
self.show_status(f"Aligned {len(elements)} elements to horizontal center", 2000)
@ribbon_action(
label="Align V-Center",
tooltip="Align selected elements to vertical center",
tab="Arrange",
group="Align",
requires_selection=True,
min_selection=2
)
def align_vertical_center(self):
"""Align selected elements to vertical center"""
elements = self._get_selected_elements_list()
if not self.require_selection(min_count=2):
return
changes = AlignmentManager.align_vertical_center(elements)
if changes:
cmd = AlignElementsCommand(changes)
self.project.history.execute(cmd)
self.update_view()
self.show_status(f"Aligned {len(elements)} elements to vertical center", 2000)
@ribbon_action(
label="Maximize Pattern",
tooltip="Maximize selected elements using crystal growth algorithm",
tab="Arrange",
group="Size",
requires_selection=True,
min_selection=1
)
def maximize_pattern(self):
"""Maximize selected elements until they are close to borders or each other"""
elements = self._get_selected_elements_list()
if not self.require_selection(min_count=1):
return
# Get page size from current page
page = self.get_current_page()
if not page:
self.show_warning("No Page", "Please create a page first.")
return
page_size = page.layout.size
changes = AlignmentManager.maximize_pattern(elements, page_size)
if changes:
cmd = ResizeElementsCommand(changes)
self.project.history.execute(cmd)
self.update_view()
self.show_status(f"Maximized {len(elements)} element(s) using pattern growth", 2000)