mirror of
https://github.com/rbreu/beeref.git
synced 2026-03-11 08:54:28 +00:00
Add Flip action to menu
This commit is contained in:
parent
0d4b5da84b
commit
27813f5bd8
6 changed files with 67 additions and 0 deletions
|
|
@ -98,4 +98,20 @@ actions = [
|
|||
'group': 'active_when_selection',
|
||||
'enabled': False,
|
||||
},
|
||||
{
|
||||
'id': 'flip_horizontally',
|
||||
'text': 'Flip &Horizontally',
|
||||
'shortcuts': ['H'],
|
||||
'callback': 'on_action_flip_horizontally',
|
||||
'group': 'active_when_selection',
|
||||
'enabled': False,
|
||||
},
|
||||
{
|
||||
'id': 'flip_vertically',
|
||||
'text': 'Flip &Vertically',
|
||||
'shortcuts': ['V'],
|
||||
'callback': 'on_action_flip_vertically',
|
||||
'group': 'active_when_selection',
|
||||
'enabled': False,
|
||||
},
|
||||
]
|
||||
|
|
|
|||
|
|
@ -36,6 +36,13 @@ menu_structure = [
|
|||
'delete',
|
||||
],
|
||||
},
|
||||
{
|
||||
'menu': '&Transform',
|
||||
'items': [
|
||||
'flip_horizontally',
|
||||
'flip_vertically',
|
||||
],
|
||||
},
|
||||
{
|
||||
'menu': '&Normalize',
|
||||
'items': [
|
||||
|
|
|
|||
|
|
@ -86,6 +86,13 @@ class BeeGraphicsScene(QtWidgets.QGraphicsScene):
|
|||
self.undo_stack.push(
|
||||
commands.NormalizeItems(self.selectedItems(), scale_factors))
|
||||
|
||||
def flip_items(self, vertical=False):
|
||||
"""Flip selected items."""
|
||||
self.undo_stack.push(
|
||||
commands.FlipItems(self.selectedItems(),
|
||||
self.get_selection_center(),
|
||||
vertical=vertical))
|
||||
|
||||
def has_selection(self):
|
||||
"""Checks whether there are currently items selected."""
|
||||
|
||||
|
|
@ -176,6 +183,10 @@ class BeeGraphicsScene(QtWidgets.QGraphicsScene):
|
|||
QtCore.QPointF(min(x), min(y)),
|
||||
QtCore.QPointF(max(x), max(y)))
|
||||
|
||||
def get_selection_center(self):
|
||||
rect = self.get_selection_rect()
|
||||
return (rect.topLeft() + rect.bottomRight()) / 2
|
||||
|
||||
def on_selection_change(self):
|
||||
if self.has_multi_selection():
|
||||
self.multi_select_item.fit_selection_area(
|
||||
|
|
|
|||
|
|
@ -124,6 +124,12 @@ class BeeGraphicsView(QtWidgets.QGraphicsView, ActionsMixin):
|
|||
def on_action_normalize_size(self):
|
||||
self.scene.normalize_size()
|
||||
|
||||
def on_action_flip_horizontally(self):
|
||||
self.scene.flip_items(vertical=False)
|
||||
|
||||
def on_action_flip_vertically(self):
|
||||
self.scene.flip_items(vertical=True)
|
||||
|
||||
def open_from_file(self, filename):
|
||||
logger.info(f'Opening file {filename}')
|
||||
self.scene.clear()
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ from pytest import approx
|
|||
from PyQt6 import QtCore, QtGui, QtWidgets
|
||||
from PyQt6.QtCore import Qt
|
||||
|
||||
from beeref import commands
|
||||
from beeref.items import BeePixmapItem
|
||||
from beeref.scene import BeeGraphicsScene
|
||||
from .base import BeeTestCase
|
||||
|
|
@ -66,6 +67,21 @@ class BeeGraphicsSceneTestCase(BeeTestCase):
|
|||
def test_normalize_size_when_no_items(self):
|
||||
self.scene.normalize_size()
|
||||
|
||||
def test_flip_items(self):
|
||||
item = BeePixmapItem(QtGui.QImage())
|
||||
self.scene.addItem(item)
|
||||
item.setSelected(True)
|
||||
self.scene.undo_stack = MagicMock(push=MagicMock())
|
||||
with patch('beeref.scene.BeeGraphicsScene.get_selection_rect',
|
||||
return_value=QtCore.QRectF(10, 20, 100, 60)):
|
||||
self.scene.flip_items(vertical=True)
|
||||
args = self.scene.undo_stack.push.call_args_list[0][0]
|
||||
cmd = args[0]
|
||||
isinstance(cmd, commands.FlipItems)
|
||||
assert cmd.items == [item]
|
||||
assert cmd.anchor == QtCore.QPointF(60, 50)
|
||||
assert cmd.vertical is True
|
||||
|
||||
def test_has_selection_when_no_selection(self):
|
||||
item = BeePixmapItem(QtGui.QImage())
|
||||
self.scene.addItem(item)
|
||||
|
|
@ -256,6 +272,7 @@ class BeeGraphicsSceneTestCase(BeeTestCase):
|
|||
self.scene.undo_stack.push.assert_called_once()
|
||||
args = self.scene.undo_stack.push.call_args_list[0][0]
|
||||
cmd = args[0]
|
||||
isinstance(cmd, commands.MoveItemsBy)
|
||||
assert cmd.items == [item]
|
||||
assert cmd.ignore_first_redo is True
|
||||
assert cmd.delta.x() == 10
|
||||
|
|
@ -368,6 +385,12 @@ class BeeGraphicsSceneTestCase(BeeTestCase):
|
|||
assert rect.bottomRight().x() == approx(math.sqrt(2) * 100)
|
||||
assert rect.bottomRight().y() == approx(math.sqrt(2) * 50)
|
||||
|
||||
def test_get_selection_center(self):
|
||||
with patch('beeref.scene.BeeGraphicsScene.get_selection_rect',
|
||||
return_value=QtCore.QRectF(10, 20, 100, 60)):
|
||||
center = self.scene.get_selection_center()
|
||||
assert center == QtCore.QPointF(60, 50)
|
||||
|
||||
def test_on_selection_change_when_multi_selection_new(self):
|
||||
self.scene.has_multi_selection = MagicMock(return_value=True)
|
||||
self.scene.multi_select_item.fit_selection_area = MagicMock()
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ from PyQt6 import QtCore, QtGui
|
|||
from PyQt6.QtCore import Qt
|
||||
|
||||
from beeref.assets import BeeAssets
|
||||
from beeref import commands
|
||||
from beeref.items import BeePixmapItem
|
||||
from beeref.scene import BeeGraphicsScene
|
||||
from beeref.selection import MultiSelectItem, RubberbandItem
|
||||
|
|
@ -780,6 +781,7 @@ class SelectableMixinMouseEventsTestCase(SelectableMixinBaseTestCase):
|
|||
self.scene.undo_stack.push.assert_called_once()
|
||||
args = self.scene.undo_stack.push.call_args_list[0][0]
|
||||
cmd = args[0]
|
||||
isinstance(cmd, commands.ScaleItemsBy)
|
||||
assert cmd.items == [self.item]
|
||||
assert cmd.factor == approx(1.5, 0.01)
|
||||
assert cmd.anchor == QtCore.QPointF(100, 80)
|
||||
|
|
@ -797,6 +799,7 @@ class SelectableMixinMouseEventsTestCase(SelectableMixinBaseTestCase):
|
|||
self.item.mouseReleaseEvent(self.event)
|
||||
args = self.scene.undo_stack.push.call_args_list[0][0]
|
||||
cmd = args[0]
|
||||
isinstance(cmd, commands.RotateItemsBy)
|
||||
assert cmd.items == [self.item]
|
||||
assert cmd.delta == -42
|
||||
assert cmd.anchor == QtCore.QPointF(10, 20)
|
||||
|
|
@ -811,6 +814,7 @@ class SelectableMixinMouseEventsTestCase(SelectableMixinBaseTestCase):
|
|||
self.item.mouseReleaseEvent(self.event)
|
||||
args = self.scene.undo_stack.push.call_args_list[0][0]
|
||||
cmd = args[0]
|
||||
isinstance(cmd, commands.FlipItems)
|
||||
assert cmd.items == [self.item]
|
||||
assert cmd.anchor == QtCore.QPointF(50, 40)
|
||||
assert cmd.vertical is False
|
||||
|
|
|
|||
Loading…
Reference in a new issue