1 /*
2     Scan Tailor - Interactive post-processing tool for scanned pages.
3     Copyright (C) 2007-2009  Joseph Artsimovich <joseph_a@mail.ru>
4 
5     This program is free software: you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation, either version 3 of the License, or
8     (at your option) any later version.
9 
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14 
15     You should have received a copy of the GNU General Public License
16     along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #include "ObjectDragHandler.h"
20 #include <QMouseEvent>
21 
ObjectDragHandler(DraggableObject * obj)22 ObjectDragHandler::ObjectDragHandler(DraggableObject* obj)
23     : m_obj(obj), m_keyboardModifiersSet({Qt::NoModifier}), m_activeKeyboardModifiers(Qt::NoModifier) {
24   setProximityCursor(Qt::OpenHandCursor);
25   setInteractionCursor(Qt::ClosedHandCursor);
26 }
27 
setProximityCursor(const QCursor & cursor)28 void ObjectDragHandler::setProximityCursor(const QCursor& cursor) {
29   m_interaction.setProximityCursor(cursor);
30 }
31 
setInteractionCursor(const QCursor & cursor)32 void ObjectDragHandler::setInteractionCursor(const QCursor& cursor) {
33   m_interaction.setInteractionCursor(cursor);
34 }
35 
setProximityStatusTip(const QString & tip)36 void ObjectDragHandler::setProximityStatusTip(const QString& tip) {
37   m_interaction.setProximityStatusTip(tip);
38 }
39 
setInteractionStatusTip(const QString & tip)40 void ObjectDragHandler::setInteractionStatusTip(const QString& tip) {
41   m_interaction.setInteractionStatusTip(tip);
42 }
43 
interactionInProgress(const InteractionState & interaction) const44 bool ObjectDragHandler::interactionInProgress(const InteractionState& interaction) const {
45   return interaction.capturedBy(m_interaction);
46 }
47 
proximityLeader(const InteractionState & interaction) const48 bool ObjectDragHandler::proximityLeader(const InteractionState& interaction) const {
49   return interaction.proximityLeader(m_interaction);
50 }
51 
forceEnterDragState(InteractionState & interaction,QPoint widget_mouse_pos)52 void ObjectDragHandler::forceEnterDragState(InteractionState& interaction, QPoint widget_mouse_pos) {
53   interaction.capture(m_interaction);
54   m_obj->dragInitiated(QPointF(0.5, 0.5) + widget_mouse_pos);
55 }
56 
onPaint(QPainter & painter,const InteractionState & interaction)57 void ObjectDragHandler::onPaint(QPainter& painter, const InteractionState& interaction) {
58   m_obj->paint(painter, interaction);
59 }
60 
onProximityUpdate(const QPointF & screen_mouse_pos,InteractionState & interaction)61 void ObjectDragHandler::onProximityUpdate(const QPointF& screen_mouse_pos, InteractionState& interaction) {
62   if (m_keyboardModifiersSet.find(m_activeKeyboardModifiers) == m_keyboardModifiersSet.end()) {
63     return;
64   }
65 
66   interaction.updateProximity(m_interaction, m_obj->proximity(screen_mouse_pos), m_obj->proximityPriority(),
67                               m_obj->proximityThreshold(interaction));
68 }
69 
onMousePressEvent(QMouseEvent * event,InteractionState & interaction)70 void ObjectDragHandler::onMousePressEvent(QMouseEvent* event, InteractionState& interaction) {
71   if (interaction.captured() || (event->button() != Qt::LeftButton)
72       || (m_keyboardModifiersSet.find(m_activeKeyboardModifiers) == m_keyboardModifiersSet.end())) {
73     return;
74   }
75 
76   if (interaction.proximityLeader(m_interaction)) {
77     interaction.capture(m_interaction);
78     m_obj->dragInitiated(QPointF(0.5, 0.5) + event->pos());
79   }
80 }
81 
onMouseReleaseEvent(QMouseEvent * event,InteractionState & interaction)82 void ObjectDragHandler::onMouseReleaseEvent(QMouseEvent* event, InteractionState& interaction) {
83   if ((event->button() == Qt::LeftButton) && interaction.capturedBy(m_interaction)) {
84     m_interaction.release();
85     m_obj->dragFinished(QPointF(0.5, 0.5) + event->pos());
86   }
87 }
88 
onMouseMoveEvent(QMouseEvent * event,InteractionState & interaction)89 void ObjectDragHandler::onMouseMoveEvent(QMouseEvent* event, InteractionState& interaction) {
90   if (interaction.capturedBy(m_interaction)) {
91     m_obj->dragContinuation(QPointF(0.5, 0.5) + event->pos(), event->modifiers());
92   }
93 }
94 
setKeyboardModifiers(const std::set<Qt::KeyboardModifiers> & modifiers_set)95 void ObjectDragHandler::setKeyboardModifiers(const std::set<Qt::KeyboardModifiers>& modifiers_set) {
96   m_keyboardModifiersSet = modifiers_set;
97 }
98 
onKeyPressEvent(QKeyEvent * event,InteractionState & interaction)99 void ObjectDragHandler::onKeyPressEvent(QKeyEvent* event, InteractionState& interaction) {
100   m_activeKeyboardModifiers = event->modifiers();
101 }
102 
onKeyReleaseEvent(QKeyEvent * event,InteractionState & interaction)103 void ObjectDragHandler::onKeyReleaseEvent(QKeyEvent* event, InteractionState& interaction) {
104   m_activeKeyboardModifiers = event->modifiers();
105 }
106