diff --git a/toonz/sources/include/toonzqt/schematicviewer.h b/toonz/sources/include/toonzqt/schematicviewer.h index 52c6a16..8ba1807 100644 --- a/toonz/sources/include/toonzqt/schematicviewer.h +++ b/toonz/sources/include/toonzqt/schematicviewer.h @@ -12,6 +12,7 @@ // Qt includes #include #include +#include #include @@ -51,8 +52,13 @@ class TApplication; class QToolBar; class QToolButton; class QAction; +class QTouchEvent; +class QGestureEvent; //==================================================== +namespace { +enum CursorMode { Select, Zoom, Hand }; +} //================================================================== // @@ -102,14 +108,39 @@ protected slots: class DVAPI SchematicSceneViewer final : public QGraphicsView { Q_OBJECT + bool m_tabletEvent, m_tabletMove; + enum TabletState { + None = 0, + Touched, + StartStroke, // this state is to detect the first call + // of TabletMove just after TabletPress + OnStroke, + Released + } m_tabletState = None; + + bool m_touchActive = false; + + bool m_gestureActive = false; + QTouchDevice::DeviceType m_touchDevice = QTouchDevice::TouchScreen; + bool m_zooming = false; + bool m_panning = false; + double m_scaleFactor; // used for zoom gesture + + bool m_stylusUsed = false; + + CursorMode m_cursorMode; + public: SchematicSceneViewer(QWidget *parent); ~SchematicSceneViewer(); void zoomQt(bool zoomin, bool resetView); + void panQt(const QPointF &delta); QPointF getOldScenePos() { return m_oldScenePos; } + void setCursorMode(CursorMode mode); + protected: void mousePressEvent(QMouseEvent *me) override; void mouseMoveEvent(QMouseEvent *me) override; @@ -117,6 +148,15 @@ protected: void keyPressEvent(QKeyEvent *ke) override; void wheelEvent(QWheelEvent *me) override; void showEvent(QShowEvent *se) override; + void enterEvent(QEvent *e) override; + void leaveEvent(QEvent *e) override; + void mouseDoubleClickEvent(QMouseEvent *event); + + void tabletEvent(QTabletEvent *e); + void touchEvent(QTouchEvent *e, int type); + void gestureEvent(QGestureEvent *e); + + bool event(QEvent *event) override; protected slots: @@ -132,6 +172,8 @@ private: Qt::MouseButton m_buttonState; QPoint m_oldWinPos; QPointF m_oldScenePos; + QPointF m_firstPanPoint, m_mousePanPoint; + QPoint m_zoomPoint; bool m_firstShowing; private: @@ -454,6 +496,8 @@ public: QColor getSelectedNodeTextColor(); + void setCursorMode(CursorMode mode); + public slots: void updateSchematic(); @@ -474,6 +518,10 @@ protected slots: void updateScenes(); void changeNodeSize(); + void selectModeEnabled(); + void zoomModeEnabled(); + void handModeEnabled(); + private: SchematicSceneViewer *m_viewer; StageSchematicScene *m_stageScene; @@ -484,10 +532,12 @@ private: QToolBar *m_stageToolbar, *m_commonToolbar, *m_fxToolbar, *m_swapToolbar; QAction *m_fitSchematic, *m_centerOn, *m_reorder, *m_normalize, *m_nodeSize, - *m_changeScene; + *m_changeScene, *m_selectMode, *m_zoomMode, *m_handMode; bool m_fullSchematic, m_maximizedNode; + CursorMode m_cursorMode; + private: void createToolbars(); void createActions(); diff --git a/toonz/sources/tnztools/cursormanager.cpp b/toonz/sources/tnztools/cursormanager.cpp index f0c0640..40a56c7 100644 --- a/toonz/sources/tnztools/cursormanager.cpp +++ b/toonz/sources/tnztools/cursormanager.cpp @@ -4,7 +4,11 @@ #include "tools/tool.h" #include "tools/cursors.h" +#ifdef TOONZQT_EXPORTS +#include "toonz/preferences.h" +#else #include "../toonz/preferences.h" +#endif #include #include diff --git a/toonz/sources/toonz/sceneviewerevents.cpp b/toonz/sources/toonz/sceneviewerevents.cpp index 28396ba..853bb43 100644 --- a/toonz/sources/toonz/sceneviewerevents.cpp +++ b/toonz/sources/toonz/sceneviewerevents.cpp @@ -911,6 +911,7 @@ void SceneViewer::wheelEvent(QWheelEvent *event) { m_touchDevice == QTouchDevice::TouchScreen) || m_gestureActive == false) { zoomQt(event->pos() * getDevPixRatio(), exp(0.001 * delta)); + m_panning = false; } } event->accept(); @@ -929,6 +930,8 @@ void SceneViewer::gestureEvent(QGestureEvent *e) { QPinchGesture *gesture = static_cast(pinch); QPinchGesture::ChangeFlags changeFlags = gesture->changeFlags(); QPoint firstCenter = gesture->centerPoint().toPoint(); + if (m_touchDevice == QTouchDevice::TouchScreen) + firstCenter = mapFromGlobal(firstCenter); if (gesture->state() == Qt::GestureStarted) { m_gestureActive = true; @@ -961,6 +964,7 @@ void SceneViewer::gestureEvent(QGestureEvent *e) { } if (m_zooming) { zoomQt(firstCenter * getDevPixRatio(), scaleFactor); + m_panning = false; } m_gestureActive = true; } diff --git a/toonz/sources/toonzqt/CMakeLists.txt b/toonz/sources/toonzqt/CMakeLists.txt index c86d517..3c1a329 100644 --- a/toonz/sources/toonzqt/CMakeLists.txt +++ b/toonz/sources/toonzqt/CMakeLists.txt @@ -72,6 +72,7 @@ set(MOC_HEADERS set(HEADERS ${MOC_HEADERS} + ../include/tools/cursormanager.h docklayout.h functionpaneltools.h fxdata.h @@ -103,6 +104,7 @@ set(HEADERS ) set(SOURCES + ../tnztools/cursormanager.cpp checkbox.cpp colorfield.cpp docklayout.cpp diff --git a/toonz/sources/toonzqt/Resources/schematic_hand_mode_off.svg b/toonz/sources/toonzqt/Resources/schematic_hand_mode_off.svg new file mode 100644 index 0000000..b4a7ce1 --- /dev/null +++ b/toonz/sources/toonzqt/Resources/schematic_hand_mode_off.svg @@ -0,0 +1,76 @@ + + + + + + + + + + + + + +]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/toonz/sources/toonzqt/Resources/schematic_hand_mode_on.svg b/toonz/sources/toonzqt/Resources/schematic_hand_mode_on.svg new file mode 100644 index 0000000..286ecfb --- /dev/null +++ b/toonz/sources/toonzqt/Resources/schematic_hand_mode_on.svg @@ -0,0 +1,80 @@ + + + + + + + + + + + + + +]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/toonz/sources/toonzqt/Resources/schematic_selection_mode_off.svg b/toonz/sources/toonzqt/Resources/schematic_selection_mode_off.svg new file mode 100644 index 0000000..d4ef818 --- /dev/null +++ b/toonz/sources/toonzqt/Resources/schematic_selection_mode_off.svg @@ -0,0 +1,37 @@ + + + + + + + + + + + + + +]> + + + + + + + + + + + + + + + + + + diff --git a/toonz/sources/toonzqt/Resources/schematic_selection_mode_on.svg b/toonz/sources/toonzqt/Resources/schematic_selection_mode_on.svg new file mode 100644 index 0000000..aa441b2 --- /dev/null +++ b/toonz/sources/toonzqt/Resources/schematic_selection_mode_on.svg @@ -0,0 +1,37 @@ + + + + + + + + + + + + + +]> + + + + + + + + + + + + + + + + + + diff --git a/toonz/sources/toonzqt/Resources/schematic_zoom_mode_off.svg b/toonz/sources/toonzqt/Resources/schematic_zoom_mode_off.svg new file mode 100644 index 0000000..3b64096 --- /dev/null +++ b/toonz/sources/toonzqt/Resources/schematic_zoom_mode_off.svg @@ -0,0 +1,49 @@ + + + + + + + + + + + + + +]> + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/toonz/sources/toonzqt/Resources/schematic_zoom_mode_on.svg b/toonz/sources/toonzqt/Resources/schematic_zoom_mode_on.svg new file mode 100644 index 0000000..2b98d53 --- /dev/null +++ b/toonz/sources/toonzqt/Resources/schematic_zoom_mode_on.svg @@ -0,0 +1,49 @@ + + + + + + + + + + + + + +]> + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/toonz/sources/toonzqt/schematicviewer.cpp b/toonz/sources/toonzqt/schematicviewer.cpp index 080723e..eaa4590 100644 --- a/toonz/sources/toonzqt/schematicviewer.cpp +++ b/toonz/sources/toonzqt/schematicviewer.cpp @@ -1,5 +1,4 @@ - #include "toonzqt/schematicviewer.h" // TnzQt includes @@ -30,6 +29,11 @@ #include "toonz/tscenehandle.h" #include "toonz/txshleveltypes.h" +#include "../toonz/menubarcommandids.h" + +#include "tools/cursormanager.h" +#include "tools/cursors.h" + // Qt includes #include #include @@ -41,6 +45,9 @@ #include #include #include +#include + +#include // STD includes #include "assert.h" @@ -206,6 +213,11 @@ SchematicSceneViewer::SchematicSceneViewer(QWidget *parent) setInteractive(true); setViewportUpdateMode(QGraphicsView::SmartViewportUpdate); show(); + + setAttribute(Qt::WA_AcceptTouchEvents); + grabGesture(Qt::SwipeGesture); + grabGesture(Qt::PanGesture); + grabGesture(Qt::PinchGesture); } //------------------------------------------------------------------ @@ -217,10 +229,33 @@ SchematicSceneViewer::~SchematicSceneViewer() {} /*! Reimplemets the QGraphicsView::mousePressEvent() */ void SchematicSceneViewer::mousePressEvent(QMouseEvent *me) { + // qDebug() << "[mousePressEvent]"; + if (m_gestureActive && m_touchDevice == QTouchDevice::TouchScreen && + !m_stylusUsed) { + return; + } + m_buttonState = me->button(); m_oldWinPos = me->pos(); m_oldScenePos = mapToScene(m_oldWinPos); + if (m_buttonState == Qt::LeftButton) { + if (m_cursorMode == CursorMode::Zoom) { + m_zoomPoint = me->pos(); + m_zooming = true; + return; + } else if (m_cursorMode == CursorMode::Hand) { + m_mousePanPoint = m_touchDevice == QTouchDevice::TouchScreen + ? mapToScene(me->pos()) + : me->pos() * getDevPixRatio(); + m_panning = true; + return; + } + } else if (m_buttonState == Qt::MidButton) { + m_mousePanPoint = m_touchDevice == QTouchDevice::TouchScreen + ? mapToScene(me->pos()) + : me->pos() * getDevPixRatio(); + } bool drawRect = true; QList pointedItems = items(me->pos()); int i; @@ -243,22 +278,33 @@ void SchematicSceneViewer::mousePressEvent(QMouseEvent *me) { /*! Reimplemets the QGraphicsView::mouseMoveEvent() */ void SchematicSceneViewer::mouseMoveEvent(QMouseEvent *me) { + if (m_gestureActive && m_touchDevice == QTouchDevice::TouchScreen && + !m_stylusUsed) { + return; + } + QPoint currWinPos = me->pos(); QPointF currScenePos = mapToScene(currWinPos); - if (m_buttonState == Qt::MidButton) { - // Panning - setInteractive(false); - // I need to disable QGraphicsView event handling to avoid the generation of - // 'virtual' mouseMoveEvent - QPointF delta = currScenePos - m_oldScenePos; - translate(delta.x(), delta.y()); - currScenePos = mapToScene(currWinPos); - // translate has changed the matrix affecting the mapToScene() method. I - // have to recompute currScenePos - setInteractive(true); - } - m_oldWinPos = currWinPos; - m_oldScenePos = currScenePos; + if ((m_cursorMode == CursorMode::Hand && m_panning) || + m_buttonState == Qt::MidButton) { + QPointF usePos = m_touchDevice == QTouchDevice::TouchScreen + ? mapToScene(me->pos()) + : me->pos() * getDevPixRatio(); + QPointF deltaPoint = usePos - m_mousePanPoint; + panQt(deltaPoint); + m_mousePanPoint = m_touchDevice == QTouchDevice::TouchScreen + ? mapToScene(me->pos()) + : me->pos() * getDevPixRatio(); + } else { + if (m_cursorMode == CursorMode::Zoom && m_zooming) { + int deltaY = (m_oldWinPos.y() - me->pos().y()) * 10; + double factorY = exp(deltaY * 0.001); + changeScale(m_zoomPoint, factorY); + m_panning = false; + } + m_oldWinPos = currWinPos; + m_oldScenePos = currScenePos; + } QGraphicsView::mouseMoveEvent(me); } @@ -267,6 +313,13 @@ void SchematicSceneViewer::mouseMoveEvent(QMouseEvent *me) { /*! Reimplemets the QGraphicsView::mouseReleaseEvent() */ void SchematicSceneViewer::mouseReleaseEvent(QMouseEvent *me) { + // qDebug() << "[mouseReleaseEvent]"; + m_gestureActive = false; + m_zooming = false; + m_panning = false; + m_stylusUsed = false; + m_scaleFactor = 0.0; + m_buttonState = Qt::NoButton; QGraphicsView::mouseReleaseEvent(me); setDragMode(QGraphicsView::NoDrag); @@ -275,6 +328,25 @@ void SchematicSceneViewer::mouseReleaseEvent(QMouseEvent *me) { //------------------------------------------------------------------ +void SchematicSceneViewer::mouseDoubleClickEvent(QMouseEvent *event) { + // qDebug() << "[mouseDoubleClickEvent]"; + if (m_gestureActive && !m_stylusUsed) { + m_gestureActive = false; + QGraphicsItem *item = + scene()->itemAt(mapToScene(event->pos()), QTransform()); + if (!item) { + fitScene(); + return; + } + + mousePressEvent(event); + } + + QGraphicsView::mouseDoubleClickEvent(event); +} + +//------------------------------------------------------------------ + void SchematicSceneViewer::keyPressEvent(QKeyEvent *ke) { ke->ignore(); QGraphicsView::keyPressEvent(ke); @@ -286,9 +358,51 @@ void SchematicSceneViewer::keyPressEvent(QKeyEvent *ke) { /*! Reimplemets the QGraphicsView::wheelEvent() */ void SchematicSceneViewer::wheelEvent(QWheelEvent *me) { + // qDebug() << "[wheelEvent]"; + + int delta = 0; + switch (me->source()) { + case Qt::MouseEventNotSynthesized: { + if (me->modifiers() & Qt::AltModifier) + delta = me->angleDelta().x(); + else + delta = me->angleDelta().y(); + break; + } + + case Qt::MouseEventSynthesizedBySystem: { + QPoint numPixels = me->pixelDelta(); + QPoint numDegrees = me->angleDelta() / 8; + if (!numPixels.isNull()) { + delta = me->pixelDelta().y(); + } else if (!numDegrees.isNull()) { + QPoint numSteps = numDegrees / 15; + delta = numSteps.y(); + } + break; + } + + default: // Qt::MouseEventSynthesizedByQt, + // Qt::MouseEventSynthesizedByApplication + { + std::cout << "not supported event: Qt::MouseEventSynthesizedByQt, " + "Qt::MouseEventSynthesizedByApplication" + << std::endl; + break; + } + + } // end switch + + if (abs(delta) > 0) { + if ((m_gestureActive == true && + m_touchDevice == QTouchDevice::TouchScreen) || + m_gestureActive == false) { + double factor = exp(delta * 0.001); + changeScale(me->pos(), factor); + m_panning = false; + } + } me->accept(); - double factor = exp(me->delta() * 0.001); - changeScale(me->pos(), factor); } //------------------------------------------------------------------ @@ -372,6 +486,16 @@ void SchematicSceneViewer::normalizeScene() { } //------------------------------------------------------------------ +void SchematicSceneViewer::panQt(const QPointF &delta) { + if (delta == QPointF()) return; + setInteractive(false); + // I need to disable QGraphicsView event handling to avoid the generation of + // 'virtual' mouseMoveEvent + translate(delta.x(), delta.y()); + // translate has changed the matrix affecting the mapToScene() method. I + // have to recompute currScenePos + setInteractive(true); +} void SchematicSceneViewer::showEvent(QShowEvent *se) { QGraphicsView::showEvent(se); @@ -383,6 +507,209 @@ void SchematicSceneViewer::showEvent(QShowEvent *se) { } } +//------------------------------------------------------------------ + +void SchematicSceneViewer::enterEvent(QEvent *e) { + switch (m_cursorMode) { + case CursorMode::Hand: + setToolCursor(this, ToolCursor::PanCursor); + break; + case CursorMode::Zoom: + setToolCursor(this, ToolCursor::ZoomCursor); + break; + default: + setToolCursor(this, ToolCursor::StrokeSelectCursor); + break; + } +} + +//------------------------------------------------------------------ + +void SchematicSceneViewer::leaveEvent(QEvent *e) { setCursor(Qt::ArrowCursor); } + +//------------------------------------------------------------------ + +void SchematicSceneViewer::tabletEvent(QTabletEvent *e) { + // qDebug() << "[tabletEvent]"; + if (e->type() == QTabletEvent::TabletPress) { + m_stylusUsed = e->pointerType() ? true : false; + } else if (e->type() == QTabletEvent::TabletRelease) { + m_stylusUsed = false; + } + + e->accept(); +} + +//------------------------------------------------------------------ + +void SchematicSceneViewer::gestureEvent(QGestureEvent *e) { + // qDebug() << "[gestureEvent]"; + m_gestureActive = false; + if (QGesture *swipe = e->gesture(Qt::SwipeGesture)) { + m_gestureActive = true; + } else if (QGesture *pan = e->gesture(Qt::PanGesture)) { + m_gestureActive = true; + } + if (QGesture *pinch = e->gesture(Qt::PinchGesture)) { + QPinchGesture *gesture = static_cast(pinch); + QPinchGesture::ChangeFlags changeFlags = gesture->changeFlags(); + QPoint firstCenter = gesture->centerPoint().toPoint(); + if (m_touchDevice == QTouchDevice::TouchScreen) + firstCenter = mapFromGlobal(firstCenter); + + if (gesture->state() == Qt::GestureStarted) { + m_gestureActive = true; + } else if (gesture->state() == Qt::GestureFinished) { + m_gestureActive = false; + m_zooming = false; + m_scaleFactor = 0.0; + } else { + if (changeFlags & QPinchGesture::ScaleFactorChanged) { + double scaleFactor = gesture->scaleFactor(); + // the scale factor makes for too sensitive scaling + // divide the change in half + if (scaleFactor > 1) { + double decimalValue = scaleFactor - 1; + decimalValue /= 1.5; + scaleFactor = 1 + decimalValue; + } else if (scaleFactor < 1) { + double decimalValue = 1 - scaleFactor; + decimalValue /= 1.5; + scaleFactor = 1 - decimalValue; + } + if (!m_zooming) { + double delta = scaleFactor - 1; + m_scaleFactor += delta; + if (m_scaleFactor > .2 || m_scaleFactor < -.2) { + m_zooming = true; + } + } + if (m_zooming) { + changeScale(firstCenter, scaleFactor); + m_panning = false; + } + m_gestureActive = true; + } + + if (changeFlags & QPinchGesture::CenterPointChanged) { + QPointF centerDelta = (gesture->centerPoint() * getDevPixRatio()) - + (gesture->lastCenterPoint() * getDevPixRatio()); + if (centerDelta.manhattanLength() > 1) { + // panQt(centerDelta.toPoint()); + } + m_gestureActive = true; + } + } + } + e->accept(); +} + +void SchematicSceneViewer::touchEvent(QTouchEvent *e, int type) { + // qDebug() << "[touchEvent]"; + if (type == QEvent::TouchBegin) { + m_touchActive = true; + m_firstPanPoint = e->touchPoints().at(0).pos(); + // obtain device type + m_touchDevice = e->device()->type(); + } else if (m_touchActive) { + // touchpads must have 2 finger panning for tools and navigation to be + // functional on other devices, 1 finger panning is preferred + if ((e->touchPoints().count() == 2 && + m_touchDevice == QTouchDevice::TouchPad) || + (e->touchPoints().count() == 1 && + m_touchDevice == QTouchDevice::TouchScreen)) { + QTouchEvent::TouchPoint panPoint = e->touchPoints().at(0); + if (!m_panning) { + QPointF deltaPoint = panPoint.pos() - m_firstPanPoint; + // minimize accidental and jerky zooming/rotating during 2 finger + // panning + if ((deltaPoint.manhattanLength() > 100) && !m_zooming) { + m_panning = true; + } + } + if (m_panning) { + QPointF curPos = + m_touchDevice == QTouchDevice::TouchScreen + ? mapToScene(panPoint.pos().toPoint()) + : mapToScene(panPoint.pos().toPoint()) * getDevPixRatio(); + QPointF lastPos = + m_touchDevice == QTouchDevice::TouchScreen + ? mapToScene(panPoint.lastPos().toPoint()) + : mapToScene(panPoint.lastPos().toPoint()) * getDevPixRatio(); + QPointF centerDelta = curPos - lastPos; + panQt(centerDelta); + } + } + } + if (type == QEvent::TouchEnd || type == QEvent::TouchCancel) { + m_touchActive = false; + m_panning = false; + } + e->accept(); +} + +bool SchematicSceneViewer::event(QEvent *e) { + /* + switch (e->type()) { + case QEvent::TabletPress: { + QTabletEvent *te = static_cast(e); + qDebug() << "[event] TabletPress: pointerType(" << te->pointerType() + << ") device(" << te->device() << ")"; + } break; + case QEvent::TabletRelease: + qDebug() << "[event] TabletRelease"; + break; + case QEvent::TouchBegin: + qDebug() << "[event] TouchBegin"; + break; + case QEvent::TouchEnd: + qDebug() << "[event] TouchEnd"; + break; + case QEvent::TouchCancel: + qDebug() << "[event] TouchCancel"; + break; + case QEvent::MouseButtonPress: + qDebug() << "[event] MouseButtonPress"; + break; + case QEvent::MouseButtonDblClick: + qDebug() << "[event] MouseButtonDblClick"; + break; + case QEvent::MouseButtonRelease: + qDebug() << "[event] MouseButtonRelease"; + break; + case QEvent::Gesture: + qDebug() << "[event] Gesture"; + break; + default: + break; + } + */ + + if (e->type() == QEvent::Gesture && + CommandManager::instance() + ->getAction(MI_TouchGestureControl) + ->isChecked()) { + gestureEvent(static_cast(e)); + return true; + } + if ((e->type() == QEvent::TouchBegin || e->type() == QEvent::TouchEnd || + e->type() == QEvent::TouchCancel || e->type() == QEvent::TouchUpdate) && + CommandManager::instance() + ->getAction(MI_TouchGestureControl) + ->isChecked()) { + touchEvent(static_cast(e), e->type()); + m_gestureActive = true; + return true; + } + return QGraphicsView::event(e); +} + +//------------------------------------------------------------------ + +void SchematicSceneViewer::setCursorMode(CursorMode cursorMode) { + m_cursorMode = cursorMode; +} + //================================================================== // // SchematicViewer @@ -393,7 +720,8 @@ SchematicViewer::SchematicViewer(QWidget *parent) : QWidget(parent) , m_fullSchematic(true) , m_maximizedNode(false) - , m_sceneHandle(0) { + , m_sceneHandle(0) + , m_cursorMode(CursorMode::Select) { m_viewer = new SchematicSceneViewer(this); m_stageScene = new StageSchematicScene(this); m_fxScene = new FxSchematicScene(this); @@ -604,6 +932,24 @@ void SchematicViewer::createActions() { m_commonToolbar); connect(m_nodeSize, SIGNAL(triggered()), this, SLOT(changeNodeSize())); + QIcon selectModeIcon = createQIconOnOff("schematic_selection_mode", false); + m_selectMode = + new QAction(selectModeIcon, tr("&Selection Mode"), m_commonToolbar); + m_selectMode->setCheckable(true); + connect(m_selectMode, SIGNAL(triggered()), this, SLOT(selectModeEnabled())); + + QIcon zoomModeIcon = createQIconOnOff("schematic_zoom_mode", false); + m_zoomMode = new QAction(zoomModeIcon, tr("&Zoom Mode"), m_commonToolbar); + m_zoomMode->setCheckable(true); + connect(m_zoomMode, SIGNAL(triggered()), this, SLOT(zoomModeEnabled())); + + QIcon handModeIcon = createQIconOnOff("schematic_hand_mode", false); + m_handMode = new QAction(handModeIcon, tr("&Hand Mode"), m_commonToolbar); + m_handMode->setCheckable(true); + connect(m_handMode, SIGNAL(triggered()), this, SLOT(handModeEnabled())); + + setCursorMode(m_cursorMode); + if (m_fullSchematic) { // AddPegbar addPegbar = new QAction(tr("&New Pegbar"), m_stageToolbar); @@ -676,6 +1022,10 @@ void SchematicViewer::createActions() { m_commonToolbar->addAction(m_reorder); m_commonToolbar->addAction(m_centerOn); m_commonToolbar->addAction(m_fitSchematic); + m_commonToolbar->addSeparator(); + m_commonToolbar->addAction(m_handMode); + m_commonToolbar->addAction(m_zoomMode); + m_commonToolbar->addAction(m_selectMode); if (m_fullSchematic) { m_stageToolbar->addSeparator(); @@ -833,3 +1183,26 @@ QColor SchematicViewer::getSelectedNodeTextColor() { (int)currentColumnPixel.b, 255); return currentColumnColor; } + +//------------------------------------------------------------------ + +void SchematicViewer::setCursorMode(CursorMode cursorMode) { + m_cursorMode = cursorMode; + m_viewer->setCursorMode(m_cursorMode); + + m_selectMode->setChecked((m_cursorMode == CursorMode::Select)); + m_zoomMode->setChecked((m_cursorMode == CursorMode::Zoom)); + m_handMode->setChecked((m_cursorMode == CursorMode::Hand)); +} + +//------------------------------------------------------------------ + +void SchematicViewer::selectModeEnabled() { setCursorMode(CursorMode::Select); } + +//------------------------------------------------------------------ + +void SchematicViewer::zoomModeEnabled() { setCursorMode(CursorMode::Zoom); } + +//------------------------------------------------------------------ + +void SchematicViewer::handModeEnabled() { setCursorMode(CursorMode::Hand); } diff --git a/toonz/sources/toonzqt/toonzqt.qrc b/toonz/sources/toonzqt/toonzqt.qrc index ad87e11..d2256d3 100644 --- a/toonz/sources/toonzqt/toonzqt.qrc +++ b/toonz/sources/toonzqt/toonzqt.qrc @@ -317,5 +317,11 @@ Resources/iconifynodes_on.svg Resources/iconifynodes_off.svg Resources/iconifynodes_over.svg + Resources/schematic_selection_mode_on.svg + Resources/schematic_selection_mode_off.svg + Resources/schematic_zoom_mode_on.svg + Resources/schematic_zoom_mode_off.svg + Resources/schematic_hand_mode_on.svg + Resources/schematic_hand_mode_off.svg