171 lines
5.8 KiB
Python
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)
|