diff --git a/Grinder/Grinder.pro b/Grinder/Grinder.pro index 23c2b83e9dfdfe258d2995aee9e729df300152b9..e2ac016705b3b84c9b327e0c921d7ada15a93b2e 100644 --- a/Grinder/Grinder.pro +++ b/Grinder/Grinder.pro @@ -227,7 +227,8 @@ SOURCES += \ image/draftitems/PixelsDraftItem.cpp \ image/renderers/PixelsDraftItemRenderer.cpp \ ui/image/draftitems/PixelsDraftItemNode.cpp \ - ui/visscene/RubberBandNode.cpp + ui/visscene/RubberBandNode.cpp \ + ui/image/tools/ZoomTool.cpp HEADERS += \ ui/mainwnd/GrinderWindow.h \ @@ -498,7 +499,8 @@ HEADERS += \ image/draftitems/PixelsDraftItem.h \ image/renderers/PixelsDraftItemRenderer.h \ ui/image/draftitems/PixelsDraftItemNode.h \ - ui/visscene/RubberBandNode.h + ui/visscene/RubberBandNode.h \ + ui/image/tools/ZoomTool.h FORMS += \ ui/mainwnd/GrinderWindow.ui \ diff --git a/Grinder/Version.h b/Grinder/Version.h index 358ef6d993991c202c28415dbeb1174df6cdaff7..29df668af388b0cbd078f82337a8b372579f05b0 100644 --- a/Grinder/Version.h +++ b/Grinder/Version.h @@ -10,14 +10,14 @@ #define GRNDR_INFO_TITLE "Grinder" #define GRNDR_INFO_COPYRIGHT "Copyright (c) WWU Muenster" -#define GRNDR_INFO_DATE "02.06.2018" +#define GRNDR_INFO_DATE "05.06.2018" #define GRNDR_INFO_COMPANY "WWU Muenster" #define GRNDR_INFO_WEBSITE "http://www.uni-muenster.de" #define GRNDR_VERSION_MAJOR 0 -#define GRNDR_VERSION_MINOR 4 +#define GRNDR_VERSION_MINOR 5 #define GRNDR_VERSION_REVISION 0 -#define GRNDR_VERSION_BUILD 176 +#define GRNDR_VERSION_BUILD 177 namespace grndr { diff --git a/Grinder/res/Grinder.qrc b/Grinder/res/Grinder.qrc index f893cb0fc7fafee7a55a063aee2d38e3bf9d499d..fb4a86ac2df2872f56c0d91ebbdc3cb44ca59e25 100644 --- a/Grinder/res/Grinder.qrc +++ b/Grinder/res/Grinder.qrc @@ -47,6 +47,7 @@ <file>icons/painting/eraser.png</file> <file>icons/painting/paint-brush.png</file> <file>icons/painting/051-vector-1.png</file> + <file>icons/zoom.png</file> </qresource> <qresource prefix="/"> <file>css/global.css</file> @@ -65,5 +66,6 @@ <file>cursors/picker-cursor.png</file> <file>cursors/paintbrush-cursor.png</file> <file>cursors/eraser-cursor.png</file> + <file>cursors/zoom-cursor.png</file> </qresource> </RCC> diff --git a/Grinder/res/Resources.h b/Grinder/res/Resources.h index 90ebfd6b6fda4a92953f5b498d3eb04b93576635..07eaede3eee74630df9abde0731cfbb467e710ab 100644 --- a/Grinder/res/Resources.h +++ b/Grinder/res/Resources.h @@ -62,6 +62,7 @@ #define FILE_ICON_EDITOR_CONVERTTOITEMS ":/icons/icons/painting/051-vector-1.png" #define FILE_ICON_EDITOR_PAINTBRUSH ":/icons/icons/painting/paint-brush.png" #define FILE_ICON_EDITOR_ERASER ":/icons/icons/painting/eraser.png" +#define FILE_ICON_EDITOR_ZOOM ":/icons/icons/zoom.png" /* Cursors */ @@ -70,5 +71,6 @@ #define FILE_CURSOR_EDITOR_COLORPICKER ":/cursors/cursors/picker-cursor.png" #define FILE_CURSOR_EDITOR_PAINTBRUSH ":/cursors/cursors/paintbrush-cursor.png" #define FILE_CURSOR_EDITOR_ERASER ":/cursors/cursors/eraser-cursor.png" +#define FILE_CURSOR_EDITOR_ZOOM ":/cursors/cursors/zoom-cursor.png" #endif diff --git a/Grinder/res/cursors/zoom-cursor.png b/Grinder/res/cursors/zoom-cursor.png new file mode 100644 index 0000000000000000000000000000000000000000..e97b4f46f4d0530dca3282014057c74833ad17df Binary files /dev/null and b/Grinder/res/cursors/zoom-cursor.png differ diff --git a/Grinder/res/icons/zoom.png b/Grinder/res/icons/zoom.png new file mode 100644 index 0000000000000000000000000000000000000000..76b36008ffa446dddc839f04c7ffbeab75799806 Binary files /dev/null and b/Grinder/res/icons/zoom.png differ diff --git a/Grinder/ui/image/ImageEditorToolList.cpp b/Grinder/ui/image/ImageEditorToolList.cpp index 48ac27213d37d222d0a50089a1be228af0534548..98b4ec9c25acfde6f5138037970c3300790c9b72 100644 --- a/Grinder/ui/image/ImageEditorToolList.cpp +++ b/Grinder/ui/image/ImageEditorToolList.cpp @@ -15,6 +15,7 @@ #include "tools/ColorPickerTool.h" #include "tools/PaintbrushTool.h" #include "tools/EraserTool.h" +#include "tools/ZoomTool.h" const char* ImageEditorToolList::Serialization_Group = "Tools"; const char* ImageEditorToolList::Serialization_Element = "Tool"; @@ -30,6 +31,7 @@ ImageEditorToolList::ImageEditorToolList(ImageEditor* imageEditor) : ImageEditor _tools.push_back(ToolEntry{createTool<LineDraftItemTool>(imageEditor), nullptr}); _tools.push_back(ToolEntry{createTool<PaintbrushTool>(imageEditor), nullptr}); _tools.push_back(ToolEntry{createTool<EraserTool>(imageEditor), nullptr}); + _tools.push_back(ToolEntry{createTool<ZoomTool>(imageEditor), nullptr}); } void ImageEditorToolList::assignUiComponents(QWidget* actionOwner) diff --git a/Grinder/ui/image/tools/EraserTool.cpp b/Grinder/ui/image/tools/EraserTool.cpp index 03ff7ab6d733d500c38672591d451db3721499a7..835d7108bb8f47af6ac0ea80e5a6251b0f3c86e2 100644 --- a/Grinder/ui/image/tools/EraserTool.cpp +++ b/Grinder/ui/image/tools/EraserTool.cpp @@ -28,18 +28,19 @@ void EraserTool::createProperties() VisualSceneInputHandler::InputEventResult EraserTool::rightMousePressed(const QGraphicsSceneMouseEvent* event) { - // Create a rubber band for selecting a region to erase createRubberBand(event->scenePos()); - return InputEventResult::Process; } VisualSceneInputHandler::InputEventResult EraserTool::rightMouseMoved(const QGraphicsSceneMouseEvent* event) { if (_rubberBandNode) + { _rubberBandNode->move(event->scenePos()); - - return InputEventResult::Process; + return InputEventResult::Process; + } + else + return InputEventResult::Ignore; } VisualSceneInputHandler::InputEventResult EraserTool::rightMouseReleased(const QGraphicsSceneMouseEvent* event) @@ -60,11 +61,11 @@ VisualSceneInputHandler::InputEventResult EraserTool::rightMouseReleased(const Q _imageEditor->controller().paintPixels(nullptr, QColor{}, points); - // Remove the rubber band removeRubberBand(); - } - return InputEventResult::Process; + } + else + return InputEventResult::Ignore; } void EraserTool::createRubberBand(QPointF pos) diff --git a/Grinder/ui/image/tools/EraserTool.h b/Grinder/ui/image/tools/EraserTool.h index 5453889ef6981983febf9ab54da518d269e9c16a..eaa5914aea5fb7836d4888e0d3e0bda4588e9646 100644 --- a/Grinder/ui/image/tools/EraserTool.h +++ b/Grinder/ui/image/tools/EraserTool.h @@ -6,8 +6,6 @@ #ifndef ERASERTOOL_H #define ERASERTOOL_H -#include <QGraphicsProxyWidget> - #include "PaintbrushTool.h" #include "ui/visscene/RubberBandNode.h" diff --git a/Grinder/ui/image/tools/ZoomTool.cpp b/Grinder/ui/image/tools/ZoomTool.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5b872935c75c0e7ab985eecbf036b6489bf62fa8 --- /dev/null +++ b/Grinder/ui/image/tools/ZoomTool.cpp @@ -0,0 +1,74 @@ +/****************************************************************************** + * File: ZoomTool.cpp + * Date: 05.6.2018 + *****************************************************************************/ + +#include "Grinder.h" +#include "ZoomTool.h" +#include "ui/image/ImageEditor.h" +#include "res/Resources.h" + +const char* ZoomTool::tool_type = "ZoomTool"; + +ZoomTool::ZoomTool(ImageEditor* imageEditor) : ImageEditorTool(imageEditor, "Zoom", FILE_ICON_EDITOR_ZOOM, "Z", QCursor{QPixmap{FILE_CURSOR_EDITOR_ZOOM}, 7, 7}) +{ + +} + +VisualSceneInputHandler::InputEventResult ZoomTool::mousePressed(const QGraphicsSceneMouseEvent* event) +{ + createRubberBand(event->scenePos()); + return InputEventResult::Process; +} + +VisualSceneInputHandler::InputEventResult ZoomTool::mouseMoved(const QGraphicsSceneMouseEvent* event) +{ + if (_rubberBandNode) + { + _rubberBandNode->move(event->scenePos()); + return InputEventResult::Process; + } + else + return InputEventResult::Ignore; +} + +VisualSceneInputHandler::InputEventResult ZoomTool::mouseReleased(const QGraphicsSceneMouseEvent* event) +{ + Q_UNUSED(event); + + if (_rubberBandNode) + { + // Zoom into the rubber band rectangle + if (auto scene = _imageEditor->controller().activeScene()) + scene->view()->zoomToRect(_rubberBandNode->getRect()); + + removeRubberBand(); + return InputEventResult::Process; + } + else + return InputEventResult::Ignore; +} + +void ZoomTool::createRubberBand(QPointF pos) +{ + if (!_rubberBandNode) + { + if (auto scene = _imageEditor->controller().activeScene()) + _rubberBandNode = new RubberBandNode{scene, pos}; + } +} + +void ZoomTool::removeRubberBand() +{ + if (_rubberBandNode) + { + delete _rubberBandNode; + _rubberBandNode = nullptr; + + if (auto scene = _imageEditor->controller().activeScene()) + { + scene->view()->setDragMode(QGraphicsView::ScrollHandDrag); + scene->view()->setDragMode(QGraphicsView::RubberBandDrag); + } + } +} diff --git a/Grinder/ui/image/tools/ZoomTool.h b/Grinder/ui/image/tools/ZoomTool.h new file mode 100644 index 0000000000000000000000000000000000000000..8928e3d6cf22a1965487a9e547bda27dc6bf2f51 --- /dev/null +++ b/Grinder/ui/image/tools/ZoomTool.h @@ -0,0 +1,42 @@ +/****************************************************************************** + * File: ZoomTool.h + * Date: 05.6.2018 + *****************************************************************************/ + +#ifndef ZOOMTOOL_H +#define ZOOMTOOL_H + +#include "ui/image/ImageEditorTool.h" +#include "ui/visscene/RubberBandNode.h" + +namespace grndr +{ + class ZoomTool : public ImageEditorTool + { + public: + static const char* tool_type; + + public: + ZoomTool(ImageEditor* imageEditor); + + public: + virtual QString getToolType() const override { return tool_type; } + + public: + virtual void toolDeactivated(ImageEditorTool* nextTool) override { Q_UNUSED(nextTool); removeRubberBand(); } + + protected: + virtual InputEventResult mousePressed(const QGraphicsSceneMouseEvent* event) override; + virtual InputEventResult mouseMoved(const QGraphicsSceneMouseEvent* event) override; + virtual InputEventResult mouseReleased(const QGraphicsSceneMouseEvent* event) override; + + private: + void createRubberBand(QPointF pos); + void removeRubberBand(); + + private: + RubberBandNode* _rubberBandNode{nullptr}; + }; +} + +#endif diff --git a/Grinder/ui/visscene/RubberBandNode.cpp b/Grinder/ui/visscene/RubberBandNode.cpp index 2e1d047cd49f9f24da913f4cbeb63da06567573a..fe306f5798e419c2108faa1c515d5264109848ed 100644 --- a/Grinder/ui/visscene/RubberBandNode.cpp +++ b/Grinder/ui/visscene/RubberBandNode.cpp @@ -7,7 +7,7 @@ #include "RubberBandNode.h" RubberBandNode::RubberBandNode(QGraphicsScene* scene, QPointF pos) : QObject(scene), - _startPosition{pos} + _scene{scene}, _startPosition{pos} { _rubberBand = new QRubberBand{QRubberBand::Rectangle}; _rubberBand->move(pos.toPoint()); @@ -20,6 +20,17 @@ RubberBandNode::RubberBandNode(QGraphicsScene* scene, QPointF pos) : QObject(sce RubberBandNode::~RubberBandNode() { + if (_scene) + { + for (auto& view : _scene->views()) + { + // Fix Qt's cursor hell + auto dragMode = view->dragMode(); + view->setDragMode(QGraphicsView::ScrollHandDrag); + view->setDragMode(dragMode); + } + } + if (_rubberBandNode) delete _rubberBandNode; } diff --git a/Grinder/ui/visscene/RubberBandNode.h b/Grinder/ui/visscene/RubberBandNode.h index 56e51cacde0da35fb3d3b22ceee116e30e701182..8aaf3f5572a863e4ab8aab71a87a8a46d4eae617 100644 --- a/Grinder/ui/visscene/RubberBandNode.h +++ b/Grinder/ui/visscene/RubberBandNode.h @@ -26,6 +26,8 @@ namespace grndr QRect getRect() const { if (_rubberBand) return _rubberBand->geometry(); else return QRect{}; } private: + QGraphicsScene* _scene{nullptr}; + QRubberBand* _rubberBand{nullptr}; QGraphicsProxyWidget* _rubberBandNode{nullptr}; diff --git a/Grinder/ui/visscene/VisualSceneView.cpp b/Grinder/ui/visscene/VisualSceneView.cpp index e615afbf283ebda43c3c3b543d3ebe96eb3e0663..c3140f69c157cc63a95953ba2bd36628fb050a60 100644 --- a/Grinder/ui/visscene/VisualSceneView.cpp +++ b/Grinder/ui/visscene/VisualSceneView.cpp @@ -80,22 +80,6 @@ void VisualSceneView::updateActions() _zoomFullAction->setEnabled(_scene && (zoom != 1.0)); } -void VisualSceneView::fitToWindow(QGraphicsItem* item) -{ - if (item) - { - fitInView(item, Qt::KeepAspectRatio); - } - else - { - if (_scene) - fitInView(_scene->sceneRect(), Qt::KeepAspectRatio); - } - - emit zoomChanged(getZoom()); - updateActions(); -} - void VisualSceneView::selectAllItems() const { if (_scene) @@ -114,10 +98,34 @@ void VisualSceneView::moveSelectedItems(QPoint delta) } } +void VisualSceneView::zoomToRect(QRect rect) +{ + fitInView(rect, Qt::KeepAspectRatio); + + emit zoomChanged(getZoom()); + updateActions(); +} + +void VisualSceneView::fitToWindow(QGraphicsItem* item) +{ + if (item) + { + fitInView(item, Qt::KeepAspectRatio); + } + else + { + if (_scene) + fitInView(_scene->sceneRect(), Qt::KeepAspectRatio); + } + + emit zoomChanged(getZoom()); + updateActions(); +} + void VisualSceneView::wheelEvent(QWheelEvent* event) { // Only zoom if CTRL is pressed - if (!(event->modifiers() & Qt::ControlModifier)) + if (!event->modifiers().testFlag(Qt::ControlModifier)) { QGraphicsView::wheelEvent(event); return; diff --git a/Grinder/ui/visscene/VisualSceneView.h b/Grinder/ui/visscene/VisualSceneView.h index 30fb47fd9c6bd1ffe382942db85034879ff7d87a..cd120c8374a408cca661ddc4b925441412969fe6 100644 --- a/Grinder/ui/visscene/VisualSceneView.h +++ b/Grinder/ui/visscene/VisualSceneView.h @@ -35,6 +35,7 @@ namespace grndr void zoomIn() { zoom(sceneStyle().getViewStyle().zoomFactor); } void zoomOut() { zoom(1.0 / sceneStyle().getViewStyle().zoomFactor); } void zoomFull() { setZoom(1.0); } + void zoomToRect(QRect rect); void fitToWindow(QGraphicsItem* item = nullptr); public: