mirror of
https://github.com/rbreu/beeref.git
synced 2026-03-11 08:54:28 +00:00
Add action "Move window"
This commit is contained in:
parent
55c0e91fb6
commit
723bb5819d
7 changed files with 122 additions and 15 deletions
|
|
@ -10,18 +10,20 @@ Added
|
|||
behaviour can be changed to always use PNG (the former behaviour) or
|
||||
always JPG. To apply this behaviour to already saved images in
|
||||
existing bee files, you can save them as new files.
|
||||
* Enable antialiasing/smoothing. Images that are being displayed at a
|
||||
* Enabled antialiasing/smoothing. Images that are being displayed at a
|
||||
large zoom factor are exempt to make sure that icons, pixel sprites
|
||||
etc can be viewed correctly.
|
||||
* A scene can now be exported to a single image (File -> Export Scene...)
|
||||
* Editing of text items will now be undoable after leaving edit mode
|
||||
* Empty text items will be deleted after leaving edit mode
|
||||
* Text edit mode can now be aborted with Escape
|
||||
* Alternative way to move the BeeRef window without the title bar:
|
||||
View -> Move Window (or press "M")
|
||||
|
||||
|
||||
Changed
|
||||
-------
|
||||
|
||||
* Editing of text items will now be undoable after leaving edit mode
|
||||
* Empty text items will be deleted after leaving edit mode
|
||||
* Text edit mode can now be aborted with Escape
|
||||
* "Save as" will now open pre-select the folder of the currently opened file
|
||||
* "Save" and "Save as" are now inactive when the scene is empty
|
||||
|
||||
|
|
|
|||
|
|
@ -274,6 +274,12 @@ actions = [
|
|||
'checked': True,
|
||||
'callback': 'on_action_show_titlebar',
|
||||
},
|
||||
{
|
||||
'id': 'move_window',
|
||||
'text': 'Move &Window',
|
||||
'shortcuts': ['Ctrl+M'],
|
||||
'callback': 'on_action_move_window',
|
||||
},
|
||||
{
|
||||
'id': 'fullscreen',
|
||||
'text': '&Fullscreen',
|
||||
|
|
|
|||
|
|
@ -62,6 +62,8 @@ menu_structure = [
|
|||
'show_scrollbars',
|
||||
'show_menubar',
|
||||
'show_titlebar',
|
||||
MENU_SEPARATOR,
|
||||
'move_window',
|
||||
],
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ class MainControlsMixin:
|
|||
|
||||
* Right-click menu
|
||||
* Dropping files
|
||||
* Moving the window without title bar
|
||||
"""
|
||||
|
||||
def init_main_controls(self, main_window):
|
||||
|
|
@ -42,6 +43,21 @@ class MainControlsMixin:
|
|||
self.setAcceptDrops(True)
|
||||
self.movewin_active = False
|
||||
|
||||
def enter_movewin_mode(self):
|
||||
logger.debug('Entering movewin mode')
|
||||
self.setMouseTracking(True)
|
||||
self.movewin_active = True
|
||||
self.event_start = QtCore.QPointF(self.cursor().pos())
|
||||
if hasattr(self, 'disable_mouse_events'):
|
||||
self.disable_mouse_events()
|
||||
|
||||
def exit_movewin_mode(self):
|
||||
logger.debug('Exiting movewin mode')
|
||||
self.setMouseTracking(False)
|
||||
self.movewin_active = False
|
||||
if hasattr(self, 'enable_mouse_events'):
|
||||
self.enable_mouse_events()
|
||||
|
||||
def dragEnterEvent(self, event):
|
||||
mimedata = event.mimeData()
|
||||
logger.debug(f'Drag enter event: {mimedata.formats()}')
|
||||
|
|
@ -80,11 +96,14 @@ class MainControlsMixin:
|
|||
logger.info('Drop not an image')
|
||||
|
||||
def mousePressEventMainControls(self, event):
|
||||
if self.movewin_active:
|
||||
self.exit_movewin_mode()
|
||||
event.accept()
|
||||
return True
|
||||
if (event.button() == Qt.MouseButton.LeftButton
|
||||
and event.modifiers() == (Qt.KeyboardModifier.ControlModifier
|
||||
| Qt.KeyboardModifier.AltModifier)):
|
||||
self.movewin_active = True
|
||||
self.event_start = self.mapToGlobal(event.position())
|
||||
self.enter_movewin_mode()
|
||||
event.accept()
|
||||
return True
|
||||
|
||||
|
|
@ -100,6 +119,12 @@ class MainControlsMixin:
|
|||
|
||||
def mouseReleaseEventMainControls(self, event):
|
||||
if self.movewin_active:
|
||||
self.movewin_active = False
|
||||
self.exit_movewin_mode()
|
||||
event.accept()
|
||||
return True
|
||||
|
||||
def keyPressEventMainControls(self, event):
|
||||
if self.movewin_active:
|
||||
self.exit_movewin_mode()
|
||||
event.accept()
|
||||
return True
|
||||
|
|
|
|||
|
|
@ -105,9 +105,13 @@ class BeeGraphicsView(MainControlsMixin,
|
|||
if not self.scene.items():
|
||||
logger.debug('No items in scene')
|
||||
self.setTransform(QtGui.QTransform())
|
||||
self.welcome_overlay.setFocus()
|
||||
self.clearFocus()
|
||||
self.welcome_overlay.show()
|
||||
self.actiongroup_set_enabled('active_when_items_in_scene', False)
|
||||
else:
|
||||
self.setFocus()
|
||||
self.welcome_overlay.clearFocus()
|
||||
self.welcome_overlay.hide()
|
||||
self.actiongroup_set_enabled('active_when_items_in_scene', True)
|
||||
self.recalc_scene_rect()
|
||||
|
|
@ -216,6 +220,12 @@ class BeeGraphicsView(MainControlsMixin,
|
|||
self.parent.create()
|
||||
self.parent.show()
|
||||
|
||||
def on_action_move_window(self):
|
||||
if self.welcome_overlay.isHidden():
|
||||
self.enter_movewin_mode()
|
||||
else:
|
||||
self.welcome_overlay.enter_movewin_mode()
|
||||
|
||||
def on_action_undo(self):
|
||||
logger.debug('Undo: %s' % self.undo_stack.undoText())
|
||||
self.scene.cancel_crop_mode()
|
||||
|
|
@ -662,6 +672,9 @@ class BeeGraphicsView(MainControlsMixin,
|
|||
event.accept()
|
||||
|
||||
def mousePressEvent(self, event):
|
||||
if self.mousePressEventMainControls(event):
|
||||
return
|
||||
|
||||
if (event.button() == Qt.MouseButton.MiddleButton
|
||||
and event.modifiers() == Qt.KeyboardModifier.ControlModifier):
|
||||
self.zoom_active = True
|
||||
|
|
@ -679,8 +692,6 @@ class BeeGraphicsView(MainControlsMixin,
|
|||
event.accept()
|
||||
return
|
||||
|
||||
if self.mousePressEventMainControls(event):
|
||||
return
|
||||
super().mousePressEvent(event)
|
||||
|
||||
def mouseMoveEvent(self, event):
|
||||
|
|
@ -723,3 +734,8 @@ class BeeGraphicsView(MainControlsMixin,
|
|||
super().resizeEvent(event)
|
||||
self.recalc_scene_rect()
|
||||
self.welcome_overlay.resize(self.size())
|
||||
|
||||
def keyPressEvent(self, event):
|
||||
if self.keyPressEventMainControls(event):
|
||||
return
|
||||
super().keyPressEvent(event)
|
||||
|
|
|
|||
|
|
@ -107,12 +107,12 @@ class WelcomeOverlay(MainControlsMixin, QtWidgets.QWidget):
|
|||
self.files_layout.addStretch(50)
|
||||
|
||||
# Help text
|
||||
label = QtWidgets.QLabel(self.txt, self)
|
||||
label.setAlignment(Qt.AlignmentFlag.AlignVCenter
|
||||
| Qt.AlignmentFlag.AlignCenter)
|
||||
self.label = QtWidgets.QLabel(self.txt, self)
|
||||
self.label.setAlignment(Qt.AlignmentFlag.AlignVCenter
|
||||
| Qt.AlignmentFlag.AlignCenter)
|
||||
self.layout = QtWidgets.QHBoxLayout()
|
||||
self.layout.addStretch(50)
|
||||
self.layout.addWidget(label)
|
||||
self.layout.addWidget(self.label)
|
||||
self.layout.addStretch(50)
|
||||
self.setLayout(self.layout)
|
||||
|
||||
|
|
@ -123,6 +123,20 @@ class WelcomeOverlay(MainControlsMixin, QtWidgets.QWidget):
|
|||
self.layout.insertLayout(0, self.files_layout)
|
||||
super().show()
|
||||
|
||||
def disable_mouse_events(self):
|
||||
self.files_view.setAttribute(
|
||||
Qt.WidgetAttribute.WA_TransparentForMouseEvents)
|
||||
self.label.setAttribute(
|
||||
Qt.WidgetAttribute.WA_TransparentForMouseEvents)
|
||||
|
||||
def enable_mouse_events(self):
|
||||
self.files_view.setAttribute(
|
||||
Qt.WidgetAttribute.WA_TransparentForMouseEvents,
|
||||
on=False)
|
||||
self.label.setAttribute(
|
||||
Qt.WidgetAttribute.WA_TransparentForMouseEvents,
|
||||
on=False)
|
||||
|
||||
def mousePressEvent(self, event):
|
||||
if self.mousePressEventMainControls(event):
|
||||
return
|
||||
|
|
@ -138,6 +152,11 @@ class WelcomeOverlay(MainControlsMixin, QtWidgets.QWidget):
|
|||
return
|
||||
super().mouseReleaseEvent(event)
|
||||
|
||||
def keyPressEvent(self, event):
|
||||
if self.keyPressEventMainControls(event):
|
||||
return
|
||||
super().keyPressEvent(event)
|
||||
|
||||
|
||||
class BeeProgressDialog(QtWidgets.QProgressDialog):
|
||||
|
||||
|
|
|
|||
|
|
@ -598,6 +598,25 @@ def test_on_action_show_titlebar_unchecked(
|
|||
create_mock.assert_called_once()
|
||||
|
||||
|
||||
@patch('beeref.widgets.WelcomeOverlay.cursor')
|
||||
def test_on_action_move_window_when_welcome_overlay(cursor_mock, view):
|
||||
cursor_mock.return_value = MagicMock(
|
||||
pos=MagicMock(return_value=QtCore.QPointF(10.0, 20.0)))
|
||||
view.on_action_move_window()
|
||||
assert view.welcome_overlay.movewin_active is True
|
||||
assert view.welcome_overlay.event_start == QtCore.QPointF(10.0, 20.0)
|
||||
|
||||
|
||||
@patch('beeref.view.BeeGraphicsView.cursor')
|
||||
def test_on_action_move_window_when_scene(cursor_mock, view):
|
||||
cursor_mock.return_value = MagicMock(
|
||||
pos=MagicMock(return_value=QtCore.QPointF(10.0, 20.0)))
|
||||
view.welcome_overlay.hide()
|
||||
view.on_action_move_window()
|
||||
assert view.movewin_active is True
|
||||
assert view.event_start == QtCore.QPointF(10.0, 20.0)
|
||||
|
||||
|
||||
def test_on_action_delete_items(view, item):
|
||||
view.scene.cancel_crop_mode = MagicMock()
|
||||
view.scene.addItem(item)
|
||||
|
|
@ -781,9 +800,11 @@ def test_mouse_press_pan_alt_left_drag(mouse_event_mock, view):
|
|||
|
||||
|
||||
@patch('PyQt6.QtWidgets.QGraphicsView.mousePressEvent')
|
||||
def test_mouse_press_move_window(mouse_event_mock, view):
|
||||
@patch('beeref.view.BeeGraphicsView.cursor')
|
||||
def test_mouse_press_move_window(cursor_mock, mouse_event_mock, view):
|
||||
event = MagicMock()
|
||||
event.position.return_value = QtCore.QPointF(10.0, 20.0)
|
||||
cursor_mock.return_value = MagicMock(
|
||||
pos=MagicMock(return_value=QtCore.QPointF(10.0, 20.0)))
|
||||
event.button.return_value = Qt.MouseButton.LeftButton
|
||||
event.modifiers.return_value = (
|
||||
Qt.KeyboardModifier.AltModifier | Qt.KeyboardModifier.ControlModifier)
|
||||
|
|
@ -796,6 +817,22 @@ def test_mouse_press_move_window(mouse_event_mock, view):
|
|||
event.accept.assert_called_once_with()
|
||||
|
||||
|
||||
@patch('PyQt6.QtWidgets.QGraphicsView.mousePressEvent')
|
||||
def test_mouse_press_when_move_window_active(mouse_event_mock, view):
|
||||
view.movewin_active = True
|
||||
view.mousePressEvent(MagicMock())
|
||||
assert view.movewin_active is False
|
||||
mouse_event_mock.assert_not_called()
|
||||
|
||||
|
||||
@patch('PyQt6.QtWidgets.QGraphicsView.keyPressEvent')
|
||||
def test_key_press_when_move_window_active(key_event_mock, view):
|
||||
view.movewin_active = True
|
||||
view.keyPressEvent(MagicMock())
|
||||
assert view.movewin_active is False
|
||||
key_event_mock.assert_not_called()
|
||||
|
||||
|
||||
@patch('PyQt6.QtWidgets.QGraphicsView.mousePressEvent')
|
||||
def test_mouse_press_unhandled(mouse_event_mock, view):
|
||||
event = MagicMock()
|
||||
|
|
|
|||
Loading…
Reference in a new issue