200 lines
6.3 KiB
Python
200 lines
6.3 KiB
Python
"""
|
|
Z-order operations mixin for pyPhotoAlbum
|
|
"""
|
|
|
|
from pyPhotoAlbum.decorators import ribbon_action
|
|
from pyPhotoAlbum.commands import ChangeZOrderCommand
|
|
|
|
|
|
class ZOrderOperationsMixin:
|
|
"""Mixin providing z-order/layer control operations"""
|
|
|
|
@ribbon_action(
|
|
label="Bring to Front",
|
|
tooltip="Bring selected element to front",
|
|
tab="Arrange",
|
|
group="Order",
|
|
shortcut="Ctrl+Shift+]",
|
|
requires_selection=True
|
|
)
|
|
def bring_to_front(self):
|
|
"""Bring selected element to front (end of list)"""
|
|
if not self.gl_widget.selected_element:
|
|
return
|
|
|
|
current_page = self.get_current_page()
|
|
if not current_page:
|
|
return
|
|
|
|
element = self.gl_widget.selected_element
|
|
elements = current_page.layout.elements
|
|
|
|
if element not in elements:
|
|
return
|
|
|
|
old_index = elements.index(element)
|
|
new_index = len(elements) - 1
|
|
|
|
if old_index == new_index:
|
|
self.show_status("Element is already at front", 2000)
|
|
return
|
|
|
|
# Create and execute command
|
|
cmd = ChangeZOrderCommand(current_page.layout, element, old_index, new_index)
|
|
self.project.history.execute(cmd)
|
|
|
|
self.update_view()
|
|
self.show_status("Brought element to front (Ctrl+Z to undo)", 2000)
|
|
print(f"Brought element to front: {old_index} → {new_index}")
|
|
|
|
@ribbon_action(
|
|
label="Send to Back",
|
|
tooltip="Send selected element to back",
|
|
tab="Arrange",
|
|
group="Order",
|
|
shortcut="Ctrl+Shift+[",
|
|
requires_selection=True
|
|
)
|
|
def send_to_back(self):
|
|
"""Send selected element to back (start of list)"""
|
|
if not self.gl_widget.selected_element:
|
|
return
|
|
|
|
current_page = self.get_current_page()
|
|
if not current_page:
|
|
return
|
|
|
|
element = self.gl_widget.selected_element
|
|
elements = current_page.layout.elements
|
|
|
|
if element not in elements:
|
|
return
|
|
|
|
old_index = elements.index(element)
|
|
new_index = 0
|
|
|
|
if old_index == new_index:
|
|
self.show_status("Element is already at back", 2000)
|
|
return
|
|
|
|
# Create and execute command
|
|
cmd = ChangeZOrderCommand(current_page.layout, element, old_index, new_index)
|
|
self.project.history.execute(cmd)
|
|
|
|
self.update_view()
|
|
self.show_status("Sent element to back (Ctrl+Z to undo)", 2000)
|
|
print(f"Sent element to back: {old_index} → {new_index}")
|
|
|
|
@ribbon_action(
|
|
label="Bring Forward",
|
|
tooltip="Bring selected element forward one layer",
|
|
tab="Arrange",
|
|
group="Order",
|
|
shortcut="Ctrl+]",
|
|
requires_selection=True
|
|
)
|
|
def bring_forward(self):
|
|
"""Move selected element forward one position in list"""
|
|
if not self.gl_widget.selected_element:
|
|
return
|
|
|
|
current_page = self.get_current_page()
|
|
if not current_page:
|
|
return
|
|
|
|
element = self.gl_widget.selected_element
|
|
elements = current_page.layout.elements
|
|
|
|
if element not in elements:
|
|
return
|
|
|
|
old_index = elements.index(element)
|
|
new_index = old_index + 1
|
|
|
|
if new_index >= len(elements):
|
|
self.show_status("Element is already at front", 2000)
|
|
return
|
|
|
|
# Create and execute command
|
|
cmd = ChangeZOrderCommand(current_page.layout, element, old_index, new_index)
|
|
self.project.history.execute(cmd)
|
|
|
|
self.update_view()
|
|
self.show_status("Brought element forward (Ctrl+Z to undo)", 2000)
|
|
print(f"Brought element forward: {old_index} → {new_index}")
|
|
|
|
@ribbon_action(
|
|
label="Send Backward",
|
|
tooltip="Send selected element backward one layer",
|
|
tab="Arrange",
|
|
group="Order",
|
|
shortcut="Ctrl+[",
|
|
requires_selection=True
|
|
)
|
|
def send_backward(self):
|
|
"""Move selected element backward one position in list"""
|
|
if not self.gl_widget.selected_element:
|
|
return
|
|
|
|
current_page = self.get_current_page()
|
|
if not current_page:
|
|
return
|
|
|
|
element = self.gl_widget.selected_element
|
|
elements = current_page.layout.elements
|
|
|
|
if element not in elements:
|
|
return
|
|
|
|
old_index = elements.index(element)
|
|
new_index = old_index - 1
|
|
|
|
if new_index < 0:
|
|
self.show_status("Element is already at back", 2000)
|
|
return
|
|
|
|
# Create and execute command
|
|
cmd = ChangeZOrderCommand(current_page.layout, element, old_index, new_index)
|
|
self.project.history.execute(cmd)
|
|
|
|
self.update_view()
|
|
self.show_status("Sent element backward (Ctrl+Z to undo)", 2000)
|
|
print(f"Sent element backward: {old_index} → {new_index}")
|
|
|
|
@ribbon_action(
|
|
label="Swap Order",
|
|
tooltip="Swap z-order of two selected elements",
|
|
tab="Arrange",
|
|
group="Order",
|
|
shortcut="Ctrl+Shift+X",
|
|
requires_selection=True,
|
|
min_selection=2
|
|
)
|
|
def swap_order(self):
|
|
"""Swap the z-order of two selected elements"""
|
|
if len(self.gl_widget.selected_elements) != 2:
|
|
self.show_status("Please select exactly 2 elements to swap", 2000)
|
|
return
|
|
|
|
current_page = self.get_current_page()
|
|
if not current_page:
|
|
return
|
|
|
|
elements = current_page.layout.elements
|
|
selected = list(self.gl_widget.selected_elements)
|
|
|
|
# Get indices of both elements
|
|
try:
|
|
index1 = elements.index(selected[0])
|
|
index2 = elements.index(selected[1])
|
|
except ValueError:
|
|
self.show_status("Selected elements not found on current page", 2000)
|
|
return
|
|
|
|
# Swap them in the list
|
|
elements[index1], elements[index2] = elements[index2], elements[index1]
|
|
|
|
self.update_view()
|
|
self.show_status(f"Swapped z-order of elements", 2000)
|
|
print(f"Swapped elements at indices {index1} and {index2}")
|