Fix hover on scale areas for narrows items

This commit is contained in:
Rebecca Breu 2021-07-29 20:41:13 +02:00
parent 4453f2bbc3
commit 1b14e18658
5 changed files with 76 additions and 83 deletions

View file

@ -13,6 +13,11 @@ Changed
* Make debug log file less verbose
Fixed
-----
* Hovering over the scale handles of very narrow items now displays correct cursor
0.1.1 - 2021-07-18
==================

View file

@ -46,7 +46,7 @@ To get the current delevopment version, you need to have a working Python 3 envi
Then run ``beeref`` or ``beeref filename.bee``.
If there are issues starting the application, run it with the environment varibale ``QT_DEBUG_PLUGINS`` set to 1, for example from a Linux shell::
If there are issues starting the application, run it with the environment variable ``QT_DEBUG_PLUGINS`` set to 1, for example from a Linux shell::
QT_DEBUG_PLUGINS=1 beeref

View file

@ -333,16 +333,7 @@ class SelectableMixin(BaseItemMixin):
for corner in self.corners:
# See if we need to change the cursor for interactable areas
if self.get_scale_bounds(corner).contains(event.pos()):
self.event_anchor = self.center_scene_coords
angle = self.get_rotate_angle(self.mapToScene(corner))
if abs(angle) >= 157.5 or abs(angle) <= 22.5:
self.setCursor(Qt.CursorShape.SizeVerCursor)
elif 112.5 <= angle <= 157.5 or -67.5 <= angle <= -22.5:
self.setCursor(Qt.CursorShape.SizeFDiagCursor)
elif 67.5 <= abs(angle) <= 112.5:
self.setCursor(Qt.CursorShape.SizeHorCursor)
else:
self.setCursor(Qt.CursorShape.SizeBDiagCursor)
self.setCursor(self.get_corner_scale_cursor(corner))
return
elif self.get_rotate_bounds(corner).contains(event.pos()):
self.setCursor(BeeAssets().cursor_rotate)
@ -450,9 +441,39 @@ class SelectableMixin(BaseItemMixin):
return delta
def get_corner_scale_cursor(self, corner):
"""Gets the scale cursor for the given corner."""
rotation = self.rotation() % 180
flipped = self.flip() == -1
if corner in (QtCore.QPointF(0, 0),
QtCore.QPointF(self.width, self.height)):
if 22.5 < rotation < 67.5:
return Qt.CursorShape.SizeVerCursor
elif 67.5 < rotation < 112.5:
return (Qt.CursorShape.SizeFDiagCursor if flipped
else Qt.CursorShape.SizeBDiagCursor)
elif 112.5 < rotation < 157.5:
return Qt.CursorShape.SizeHorCursor
else:
return (Qt.CursorShape.SizeBDiagCursor if flipped
else Qt.CursorShape.SizeFDiagCursor)
else:
if 22.5 < rotation < 67.5:
return Qt.CursorShape.SizeHorCursor
elif 67.5 < rotation < 112.5:
return (Qt.CursorShape.SizeBDiagCursor if flipped
else Qt.CursorShape.SizeFDiagCursor)
elif 112.5 < rotation < 157.5:
return Qt.CursorShape.SizeVerCursor
else:
return (Qt.CursorShape.SizeFDiagCursor if flipped
else Qt.CursorShape.SizeBDiagCursor)
def get_edge_flips_v(self, edge):
"""Returns ``True`` if the given edge invokes a horizontal flip,
``False`` if it invokes a vertacal flip."""
``False`` if it invokes a vertical flip."""
if 45 < self.rotation() < 135 or 225 < self.rotation() < 315:
return not edge['flip_v']

View file

@ -125,7 +125,6 @@ class BeeGraphicsView(QtWidgets.QGraphicsView, ActionsMixin):
for f in cls.supportedImageFormats():
string = f'*.{f.data().decode()}'
formats.extend((string, string.upper()))
print(formats)
return ' '.join(formats)
def get_view_center(self):

View file

@ -556,87 +556,55 @@ def test_hover_move_event_no_selection(view, item):
item.setCursor.assert_not_called()
def test_hover_move_event_topleft_scale(view, item):
@mark.parametrize('pos,flipped,rotation, expected',
[((0, 0), False, 0, 'SizeFDiagCursor'),
((100, 80), False, 0, 'SizeFDiagCursor'),
((100, 0), False, 0, 'SizeBDiagCursor'),
((0, 0), False, 90, 'SizeBDiagCursor'),
((0, 0), False, 45, 'SizeVerCursor'),
((0, 0), False, 135, 'SizeHorCursor'),
((0, 80), False, 45, 'SizeHorCursor'),
((0, 80), False, 90, 'SizeFDiagCursor'),
((0, 80), False, 135, 'SizeVerCursor'),
((0, 80), True, 0, 'SizeFDiagCursor'),
((100, 0), True, 0, 'SizeFDiagCursor'),
((100, 80), True, 0, 'SizeBDiagCursor'),
((0, 80), True, 90, 'SizeBDiagCursor'),
((0, 80), True, 45, 'SizeHorCursor'),
((0, 0), True, 135, 'SizeHorCursor'),
((0, 0), True, 45, 'SizeVerCursor'),
((0, 0), True, 90, 'SizeFDiagCursor'),
((0, 0), True, 135, 'SizeHorCursor')])
def test_hover_move_event_topleft_scale(
pos, flipped, rotation, expected, view, item):
view.scene.addItem(item)
item.setSelected(True)
if flipped:
item.do_flip()
item.setRotation(rotation)
event = MagicMock()
event.pos.return_value = QtCore.QPointF(0, 0)
event.pos.return_value = QtCore.QPointF(*pos)
with patch('beeref.items.BeePixmapItem.width',
new_callable=PropertyMock, return_value=100):
with patch('beeref.items.BeePixmapItem.height',
new_callable=PropertyMock, return_value=80):
item.hoverMoveEvent(event)
assert item.cursor() == getattr(Qt.CursorShape, expected)
def test_hover_move_event_bottomright_scale_very_wide_item(view, item):
view.scene.addItem(item)
item.setSelected(True)
event = MagicMock()
event.pos.return_value = QtCore.QPointF(1000, 100)
with patch('beeref.items.BeePixmapItem.width',
new_callable=PropertyMock, return_value=1000):
with patch('beeref.items.BeePixmapItem.height',
new_callable=PropertyMock, return_value=100):
item.hoverMoveEvent(event)
assert item.cursor() == Qt.CursorShape.SizeFDiagCursor
def test_hover_move_event_bottomright_scale(view, item):
view.scene.addItem(item)
item.setSelected(True)
event = MagicMock()
event.pos.return_value = QtCore.QPointF(100, 80)
with patch('beeref.items.BeePixmapItem.width',
new_callable=PropertyMock, return_value=100):
with patch('beeref.items.BeePixmapItem.height',
new_callable=PropertyMock, return_value=80):
item.hoverMoveEvent(event)
assert item.cursor() == Qt.CursorShape.SizeFDiagCursor
def test_hover_move_event_topright_scale(view, item):
view.scene.addItem(item)
item.setSelected(True)
event = MagicMock()
event.pos.return_value = QtCore.QPointF(100, 0)
with patch('beeref.items.BeePixmapItem.width',
new_callable=PropertyMock, return_value=100):
with patch('beeref.items.BeePixmapItem.height',
new_callable=PropertyMock, return_value=80):
item.hoverMoveEvent(event)
assert item.cursor() == Qt.CursorShape.SizeBDiagCursor
def test_hover_move_event_topright_scale_rotated_90(view, item):
view.scene.addItem(item)
item.setRotation(90)
item.setSelected(True)
event = MagicMock()
event.pos.return_value = QtCore.QPointF(0, 0)
with patch('beeref.items.BeePixmapItem.width',
new_callable=PropertyMock, return_value=100):
with patch('beeref.items.BeePixmapItem.height',
new_callable=PropertyMock, return_value=80):
item.hoverMoveEvent(event)
assert item.cursor() == Qt.CursorShape.SizeBDiagCursor
def test_hover_move_event_top_scale_rotated_45(view, item):
view.scene.addItem(item)
item.setRotation(45)
item.setSelected(True)
event = MagicMock()
event.pos.return_value = QtCore.QPointF(0, 0)
with patch('beeref.items.BeePixmapItem.width',
new_callable=PropertyMock, return_value=100):
with patch('beeref.items.BeePixmapItem.height',
new_callable=PropertyMock, return_value=80):
item.hoverMoveEvent(event)
assert item.cursor() == Qt.CursorShape.SizeVerCursor
def test_hover_move_event_left_scale_rotated_45(view, item):
view.scene.addItem(item)
item.setRotation(45)
item.setSelected(True)
event = MagicMock()
event.pos.return_value = QtCore.QPointF(0, 80)
with patch('beeref.items.BeePixmapItem.width',
new_callable=PropertyMock, return_value=100):
with patch('beeref.items.BeePixmapItem.height',
new_callable=PropertyMock, return_value=80):
item.hoverMoveEvent(event)
assert item.cursor() == Qt.CursorShape.SizeHorCursor
def test_hover_move_event_rotate(view, item):
view.scene.addItem(item)
item.setSelected(True)