Add Raise to Top/Lower to Bottom actions

This commit is contained in:
Rebecca Breu 2021-07-05 18:03:47 +02:00
parent e5b37ab44d
commit b8dfbf0747
7 changed files with 120 additions and 37 deletions

View file

@ -85,6 +85,20 @@ actions = [
'callback': 'on_action_delete_items',
'group': 'active_when_selection',
},
{
'id': 'raise_to_top',
'text': '&Raise to Top',
'shortcuts': ['PgUp'],
'callback': 'on_action_raise_to_top',
'group': 'active_when_selection',
},
{
'id': 'lower_to_bottom',
'text': 'Lower to Bottom',
'shortcuts': ['PgDown'],
'callback': 'on_action_lower_to_bottom',
'group': 'active_when_selection',
},
{
'id': 'normalize_height',
'text': '&Height',

View file

@ -45,6 +45,9 @@ menu_structure = [
'copy',
'paste',
'delete',
MENU_SEPARATOR,
'raise_to_top',
'lower_to_bottom',
],
},
{

View file

@ -37,6 +37,8 @@ class BeeGraphicsScene(QtWidgets.QGraphicsScene):
self.rubberband_active = False
self.undo_stack = undo_stack
self.max_z = 0
self.min_z = 0
self.Z_STEP = 0.001
self.multi_select_item = MultiSelectItem()
self.rubberband_item = RubberbandItem()
self.selectionChanged.connect(self.on_selection_change)
@ -65,6 +67,23 @@ class BeeGraphicsScene(QtWidgets.QGraphicsScene):
copies.append(copy)
self.undo_stack.push(commands.InsertItems(self, copies, position))
def raise_to_top(self):
items = self.selectedItems(user_only=True)
z_values = map(lambda i: i.zValue(), items)
delta = self.max_z + self.Z_STEP - min(z_values)
logger.debug(f'Raise to top, delta: {delta}')
for item in items:
item.setZValue(item.zValue() + delta)
def lower_to_bottom(self):
items = self.selectedItems(user_only=True)
z_values = map(lambda i: i.zValue(), items)
delta = self.min_z - self.Z_STEP - max(z_values)
logger.debug(f'Lower to bottom, delta: {delta}')
for item in items:
item.setZValue(item.zValue() + delta)
def normalize_width_or_height(self, mode):
"""Scale the selected images to have the same width or height, as
specified by ``mode``.
@ -377,3 +396,4 @@ class BeeGraphicsScene(QtWidgets.QGraphicsScene):
item.setSelected(True)
item.bring_to_front()
self.max_z = max(self.max_z, item.zValue())
self.min_z = min(self.min_z, item.zValue())

View file

@ -74,9 +74,10 @@ class BaseItemMixin:
super().setZValue(value)
if self.scene():
self.scene().max_z = max(self.scene().max_z, value)
self.scene().min_z = min(self.scene().min_z, value)
def bring_to_front(self):
self.setZValue(self.scene().max_z + 0.001)
self.setZValue(self.scene().max_z + self.scene().Z_STEP)
@with_anchor
def setRotation(self, value):

View file

@ -232,6 +232,12 @@ class BeeGraphicsView(QtWidgets.QGraphicsView, ActionsMixin):
commands.DeleteItems(
self.scene, self.scene.selectedItems(user_only=True)))
def on_action_raise_to_top(self):
self.scene.raise_to_top()
def on_action_lower_to_bottom(self):
self.scene.lower_to_bottom()
def on_action_normalize_height(self):
self.scene.normalize_height()

View file

@ -36,14 +36,15 @@ def test_set_zvalue_sets_new_max(view, item):
item.setZValue(1.1)
assert item.zValue() == 1.1
assert view.scene.max_z == 1.1
assert view.scene.min_z == 0
def test_set_zvalue_keeps_old_max(view, item):
def test_set_zvalue_sets_new_min(view, item):
view.scene.addItem(item)
view.scene.max_z = 3.3
item.setZValue(1.1)
assert item.zValue() == 1.1
assert view.scene.max_z == 3.3
item.setZValue(-1.1)
assert item.zValue() == -1.1
assert view.scene.max_z == 0
assert view.scene.min_z == -1.1
def test_bring_to_front(view, item):

View file

@ -17,6 +17,75 @@ def test_add_remove_item(view, item):
assert view.scene.items() == []
def test_copy_selection_to_internal_clipboard(view):
item1 = BeePixmapItem(QtGui.QImage())
view.scene.addItem(item1)
item1.setSelected(True)
item2 = BeePixmapItem(QtGui.QImage())
view.scene.addItem(item2)
item2.setSelected(True)
item3 = BeePixmapItem(QtGui.QImage())
view.scene.addItem(item3)
view.scene.copy_selection_to_internal_clipboard()
assert set(view.scene.internal_clipboard) == {item1, item2}
assert set(view.scene.items_for_save()) == {item1, item2, item3}
def test_paste_from_internal_clipboard(view):
item1 = BeePixmapItem(QtGui.QImage())
view.scene.addItem(item1)
item1.setSelected(True)
item2 = BeePixmapItem(QtGui.QImage())
item2.setScale(3.3)
view.scene.internal_clipboard = [item2]
view.scene.paste_from_internal_clipboard(None)
assert len(list(view.scene.items_for_save())) == 2
assert item1.isSelected() is False
new_item = view.scene.selectedItems(user_only=True)[0]
assert new_item.scale() == 3.3
assert new_item is not item2
def test_raise_to_top(view):
item1 = BeePixmapItem(QtGui.QImage())
view.scene.addItem(item1)
item1.setSelected(True)
item1.setZValue(0.06)
item2 = BeePixmapItem(QtGui.QImage())
view.scene.addItem(item2)
item2.setSelected(True)
item2.setZValue(0.02)
item3 = BeePixmapItem(QtGui.QImage())
view.scene.addItem(item3)
item3.setZValue(0.07)
view.scene.raise_to_top()
assert item1.zValue() == 0.11 + view.scene.Z_STEP
assert item2.zValue() == 0.07 + view.scene.Z_STEP
assert item3.zValue() == 0.07
def test_lower_to_bottom(view):
item1 = BeePixmapItem(QtGui.QImage())
view.scene.addItem(item1)
item1.setSelected(True)
item1.setZValue(-0.06)
item2 = BeePixmapItem(QtGui.QImage())
view.scene.addItem(item2)
item2.setSelected(True)
item2.setZValue(-0.02)
item3 = BeePixmapItem(QtGui.QImage())
view.scene.addItem(item3)
item3.setZValue(-0.07)
view.scene.lower_to_bottom()
assert item1.zValue() == -0.11 - view.scene.Z_STEP
assert item2.zValue() == -0.07 - view.scene.Z_STEP
assert item3.zValue() == -0.07
def test_normalize_height(view):
item1 = BeePixmapItem(QtGui.QImage())
view.scene.addItem(item1)
@ -897,34 +966,3 @@ def test_add_queued_items_selected(view, item):
def test_add_queued_items_when_no_items(view):
view.scene.add_queued_items()
assert view.scene.items() == []
def test_copy_selection_to_internal_clipboard(view):
item1 = BeePixmapItem(QtGui.QImage())
view.scene.addItem(item1)
item1.setSelected(True)
item2 = BeePixmapItem(QtGui.QImage())
view.scene.addItem(item2)
item2.setSelected(True)
item3 = BeePixmapItem(QtGui.QImage())
view.scene.addItem(item3)
view.scene.copy_selection_to_internal_clipboard()
assert set(view.scene.internal_clipboard) == {item1, item2}
assert set(view.scene.items_for_save()) == {item1, item2, item3}
def test_paste_from_internal_clipboard(view):
item1 = BeePixmapItem(QtGui.QImage())
view.scene.addItem(item1)
item1.setSelected(True)
item2 = BeePixmapItem(QtGui.QImage())
item2.setScale(3.3)
view.scene.internal_clipboard = [item2]
view.scene.paste_from_internal_clipboard(None)
assert len(list(view.scene.items_for_save())) == 2
assert item1.isSelected() is False
new_item = view.scene.selectedItems(user_only=True)[0]
assert new_item.scale() == 3.3
assert new_item is not item2