diff --git a/src/control/tools/ArrowHandler.cpp b/src/control/tools/ArrowHandler.cpp index c01ce2b4..bbed8532 100644 --- a/src/control/tools/ArrowHandler.cpp +++ b/src/control/tools/ArrowHandler.cpp @@ -18,7 +18,7 @@ ArrowHandler::~ArrowHandler() XOJ_RELEASE_TYPE(ArrowHandler); } -void ArrowHandler::drawShape(Point& c) +void ArrowHandler::drawShape(Point& c, bool shiftDown) { int count = stroke->getPointCount(); diff --git a/src/control/tools/ArrowHandler.h b/src/control/tools/ArrowHandler.h index 199b4fc8..d1a06911 100644 --- a/src/control/tools/ArrowHandler.h +++ b/src/control/tools/ArrowHandler.h @@ -20,7 +20,7 @@ public: virtual ~ArrowHandler(); private: - virtual void drawShape(Point& currentPoint); + virtual void drawShape(Point& currentPoint, bool shiftDown); private: XOJ_TYPE_ATTRIB; diff --git a/src/control/tools/BaseStrokeHandler.cpp b/src/control/tools/BaseStrokeHandler.cpp index f6d984b7..a406d82d 100644 --- a/src/control/tools/BaseStrokeHandler.cpp +++ b/src/control/tools/BaseStrokeHandler.cpp @@ -27,7 +27,7 @@ void BaseStrokeHandler::draw(cairo_t* cr) view.drawStroke(cr, stroke, 0); } -bool BaseStrokeHandler::onMotionNotifyEvent(GdkEventMotion* event) +bool BaseStrokeHandler::onMotionNotifyEvent(GdkEventMotion* event, bool shiftDown) { XOJ_CHECK_TYPE(BaseStrokeHandler); @@ -55,7 +55,7 @@ bool BaseStrokeHandler::onMotionNotifyEvent(GdkEventMotion* event) this->redrawable->repaintRect(stroke->getX(), stroke->getY(), stroke->getElementWidth(), stroke->getElementHeight()); - drawShape(currentPoint); + drawShape(currentPoint, shiftDown); rect.add(stroke->boundingRect()); double w = stroke->getWidth(); diff --git a/src/control/tools/BaseStrokeHandler.h b/src/control/tools/BaseStrokeHandler.h index 9a584d9a..21eb9db9 100644 --- a/src/control/tools/BaseStrokeHandler.h +++ b/src/control/tools/BaseStrokeHandler.h @@ -25,12 +25,12 @@ public: void draw(cairo_t* cr); - bool onMotionNotifyEvent(GdkEventMotion* event); + bool onMotionNotifyEvent(GdkEventMotion* event, bool shiftDown); void onButtonReleaseEvent(GdkEventButton* event); void onButtonPressEvent(GdkEventButton* event); private: - virtual void drawShape(Point& currentPoint) = 0; + virtual void drawShape(Point& currentPoint, bool shiftDown) = 0; protected: XOJ_TYPE_ATTRIB; diff --git a/src/control/tools/CircleHandler.cpp b/src/control/tools/CircleHandler.cpp index a9d0afca..579b788a 100644 --- a/src/control/tools/CircleHandler.cpp +++ b/src/control/tools/CircleHandler.cpp @@ -18,7 +18,7 @@ CircleHandler::~CircleHandler() XOJ_RELEASE_TYPE(CircleHandler); } -void CircleHandler::drawShape(Point& c) +void CircleHandler::drawShape(Point& c, bool shiftDown) { int count = stroke->getPointCount(); diff --git a/src/control/tools/CircleHandler.h b/src/control/tools/CircleHandler.h index cb352805..96a6338c 100644 --- a/src/control/tools/CircleHandler.h +++ b/src/control/tools/CircleHandler.h @@ -20,7 +20,7 @@ public: virtual ~CircleHandler(); private: - virtual void drawShape(Point& currentPoint); + virtual void drawShape(Point& currentPoint, bool shiftDown); private: XOJ_TYPE_ATTRIB; diff --git a/src/control/tools/InputHandler.h b/src/control/tools/InputHandler.h index 75a6610e..7d528c03 100644 --- a/src/control/tools/InputHandler.h +++ b/src/control/tools/InputHandler.h @@ -53,7 +53,7 @@ public: * structures and queue repaints of the XojPageView * if necessary */ - virtual bool onMotionNotifyEvent(GdkEventMotion* event) = 0; + virtual bool onMotionNotifyEvent(GdkEventMotion* event, bool shiftDown) = 0; /** * The current input device for stroken, do not react on other devices (linke mices) diff --git a/src/control/tools/RectangleHandler.cpp b/src/control/tools/RectangleHandler.cpp index b3af85ca..a5c8771a 100644 --- a/src/control/tools/RectangleHandler.cpp +++ b/src/control/tools/RectangleHandler.cpp @@ -17,7 +17,7 @@ RectangleHandler::~RectangleHandler() XOJ_RELEASE_TYPE(RectangleHandler); } -void RectangleHandler::drawShape(Point& c) +void RectangleHandler::drawShape(Point& c, bool shiftDown) { int count = stroke->getPointCount(); @@ -25,16 +25,30 @@ void RectangleHandler::drawShape(Point& c) { stroke->addPoint(c); } - else + else if (shiftDown) { + // Draw square if shift is pressed Point p = stroke->getPoint(0); - if (count > 3) + + stroke->deletePointsFrom(1); + + int size = MAX(ABS(c.x - p.x), ABS(c.y - p.y)); + + if (c.x - p.x < 0 || c.y - p.y < 0) { - stroke->deletePoint(4); - stroke->deletePoint(3); - stroke->deletePoint(2); - stroke->deletePoint(1); + size = -size; } + + stroke->addPoint(Point(p.x, p.y + size)); + stroke->addPoint(Point(p.x + size, p.y + size)); + stroke->addPoint(Point(p.x + size, p.y)); + stroke->addPoint(p); + } + else + { + Point p = stroke->getPoint(0); + stroke->deletePointsFrom(1); + stroke->addPoint(Point(c.x, p.y)); stroke->addPoint(c); stroke->addPoint(Point(p.x, c.y)); diff --git a/src/control/tools/RectangleHandler.h b/src/control/tools/RectangleHandler.h index 2d1938bd..fc51cbca 100644 --- a/src/control/tools/RectangleHandler.h +++ b/src/control/tools/RectangleHandler.h @@ -20,7 +20,7 @@ public: virtual ~RectangleHandler(); private: - virtual void drawShape(Point& currentPoint); + virtual void drawShape(Point& currentPoint, bool shiftDown); private: XOJ_TYPE_ATTRIB; diff --git a/src/control/tools/RulerHandler.cpp b/src/control/tools/RulerHandler.cpp index a10108b0..b05571aa 100644 --- a/src/control/tools/RulerHandler.cpp +++ b/src/control/tools/RulerHandler.cpp @@ -18,7 +18,7 @@ RulerHandler::~RulerHandler() XOJ_RELEASE_TYPE(RulerHandler); } -void RulerHandler::drawShape(Point& currentPoint) +void RulerHandler::drawShape(Point& currentPoint, bool shiftDown) { int count = stroke->getPointCount(); @@ -26,6 +26,10 @@ void RulerHandler::drawShape(Point& currentPoint) { stroke->addPoint(currentPoint); } + else if (shiftDown) + { + stroke->setLastPoint(currentPoint.x, currentPoint.y); + } else { double x = currentPoint.x; diff --git a/src/control/tools/RulerHandler.h b/src/control/tools/RulerHandler.h index 3edfb803..4375c0e8 100644 --- a/src/control/tools/RulerHandler.h +++ b/src/control/tools/RulerHandler.h @@ -20,7 +20,7 @@ public: virtual ~RulerHandler(); private: - virtual void drawShape(Point& currentPoint); + virtual void drawShape(Point& currentPoint, bool shiftDown); private: XOJ_TYPE_ATTRIB; diff --git a/src/control/tools/StrokeHandler.cpp b/src/control/tools/StrokeHandler.cpp index fc39d93a..14a35e62 100644 --- a/src/control/tools/StrokeHandler.cpp +++ b/src/control/tools/StrokeHandler.cpp @@ -42,7 +42,7 @@ void StrokeHandler::draw(cairo_t* cr) cairo_mask_surface(cr, surfMask, visRect.x, visRect.y); } -bool StrokeHandler::onMotionNotifyEvent(GdkEventMotion* event) +bool StrokeHandler::onMotionNotifyEvent(GdkEventMotion* event, bool shiftDown) { XOJ_CHECK_TYPE(StrokeHandler); diff --git a/src/control/tools/StrokeHandler.h b/src/control/tools/StrokeHandler.h index 3936f5b5..b4824c70 100644 --- a/src/control/tools/StrokeHandler.h +++ b/src/control/tools/StrokeHandler.h @@ -34,7 +34,7 @@ public: void draw(cairo_t* cr); - bool onMotionNotifyEvent(GdkEventMotion* event); + bool onMotionNotifyEvent(GdkEventMotion* event, bool shiftDown); void onButtonReleaseEvent(GdkEventButton* event); void onButtonPressEvent(GdkEventButton* event); diff --git a/src/gui/PageView.cpp b/src/gui/PageView.cpp index 8d1b015f..53ba994d 100644 --- a/src/gui/PageView.cpp +++ b/src/gui/PageView.cpp @@ -587,7 +587,7 @@ void XojPageView::resetShapeRecognizer() } } -bool XojPageView::onMotionNotifyEvent(GtkWidget* widget, GdkEventMotion* event) +bool XojPageView::onMotionNotifyEvent(GtkWidget* widget, GdkEventMotion* event, bool shiftDown) { XOJ_CHECK_TYPE(XojPageView); @@ -599,7 +599,7 @@ bool XojPageView::onMotionNotifyEvent(GtkWidget* widget, GdkEventMotion* event) if (containsPoint(x, y, true) && this->inputHandler && - this->inputHandler->onMotionNotifyEvent(event)) + this->inputHandler->onMotionNotifyEvent(event, shiftDown)) { //input handler used this event } diff --git a/src/gui/PageView.h b/src/gui/PageView.h index b0968aca..76630671 100644 --- a/src/gui/PageView.h +++ b/src/gui/PageView.h @@ -139,7 +139,7 @@ public: public: // event handler bool onButtonPressEvent(GtkWidget* widget, GdkEventButton* event); bool onButtonReleaseEvent(GtkWidget* widget, GdkEventButton* event); - bool onMotionNotifyEvent(GtkWidget* widget, GdkEventMotion* event); + bool onMotionNotifyEvent(GtkWidget* widget, GdkEventMotion* event, bool shiftDown); void translateEvent(GdkEvent* event, int xOffset, int yOffset); /** diff --git a/src/gui/widgets/XournalWidget.cpp b/src/gui/widgets/XournalWidget.cpp index 8ffe3637..5b3b0d21 100644 --- a/src/gui/widgets/XournalWidget.cpp +++ b/src/gui/widgets/XournalWidget.cpp @@ -111,6 +111,7 @@ GtkWidget* gtk_xournal_new(XournalView* view, GtkScrollable* parent) xoj->inScrolling = false; xoj->selection = NULL; + xoj->shiftDown = false; return GTK_WIDGET(xoj); } @@ -137,8 +138,7 @@ static void gtk_xournal_class_init(GtkXournalClass* klass) widget_class->destroy = gtk_xournal_destroy; } -static gboolean gtk_xournal_key_press_event(GtkWidget* widget, - GdkEventKey* event) +static gboolean gtk_xournal_key_press_event(GtkWidget* widget, GdkEventKey* event) { g_return_val_if_fail(widget != NULL, FALSE); g_return_val_if_fail(GTK_IS_XOURNAL(widget), FALSE); @@ -146,6 +146,12 @@ static gboolean gtk_xournal_key_press_event(GtkWidget* widget, GtkXournal* xournal = GTK_XOURNAL(widget); + // Shift alone pressed. Is there a constant? + if (event->is_modifier && (event->keyval == 0xFFE1)) + { + xournal->shiftDown = true; + } + EditSelection* selection = xournal->selection; if (selection) { @@ -153,7 +159,7 @@ static gboolean gtk_xournal_key_press_event(GtkWidget* widget, if ((event->state & GDK_MOD1_MASK) || (event->state & GDK_SHIFT_MASK)) { - if ( event->state & GDK_MOD1_MASK ) + if (event->state & GDK_MOD1_MASK) { d = 1; } @@ -196,6 +202,11 @@ static gboolean gtk_xournal_key_release_event(GtkWidget* widget, GdkEventKey* ev GtkXournal* xournal = GTK_XOURNAL(widget); + if (event->is_modifier && (event->state & GDK_SHIFT_MASK)) + { + xournal->shiftDown = false; + } + return xournal->view->onKeyReleaseEvent(event); } @@ -248,8 +259,7 @@ bool gtk_xournal_scroll_callback(GtkXournal* xournal) return false; } -static void gtk_xournal_scroll_mouse_event(GtkXournal* xournal, - GdkEventMotion* event) +static void gtk_xournal_scroll_mouse_event(GtkXournal* xournal, GdkEventMotion* event) { // use root coordinates as reference point because //scrolling changes window relative coordinates @@ -498,17 +508,15 @@ gboolean gtk_xournal_button_release_event(GtkWidget* widget, GdkEventButton* eve return res; } -gboolean gtk_xournal_motion_notify_event(GtkWidget* widget, - GdkEventMotion* event) +gboolean gtk_xournal_motion_notify_event(GtkWidget* widget, GdkEventMotion* event) { GtkXournal* xournal = GTK_XOURNAL(widget); ToolHandler* h = xournal->view->getControl()->getToolHandler(); - if (xournal->view->zoom_gesture_active) - { - return TRUE; - } - + if (xournal->view->zoom_gesture_active) + { + return TRUE; + } if (h->getToolType() == TOOL_HAND) { @@ -533,8 +541,7 @@ gboolean gtk_xournal_motion_notify_event(GtkWidget* widget, } else { - CursorSelectionType selType = selection->getSelectionTypeForPos(ev.x, ev.y, - xournal->view->getZoom()); + CursorSelectionType selType = selection->getSelectionTypeForPos(ev.x, ev.y, xournal->view->getZoom()); xournal->view->getCursor()->setMouseSelectionType(selType); } return true; @@ -559,7 +566,7 @@ gboolean gtk_xournal_motion_notify_event(GtkWidget* widget, if (xournal->currentInputPage == NULL || pv == xournal->currentInputPage) { pv->translateEvent((GdkEvent*) event, xournal->x, xournal->y); - return pv->onMotionNotifyEvent(widget, event); + return pv->onMotionNotifyEvent(widget, event, xournal->shiftDown); } } diff --git a/src/gui/widgets/XournalWidget.h b/src/gui/widgets/XournalWidget.h index 824cc427..258cb7e7 100644 --- a/src/gui/widgets/XournalWidget.h +++ b/src/gui/widgets/XournalWidget.h @@ -65,6 +65,11 @@ struct _GtkXournal * Selected content, if any */ EditSelection* selection; + + /** + * Shift is currently pressed + */ + bool shiftDown; }; struct _GtkXournalClass