From 57d3751b0ba8edd7de311aabc3f7bd5b311d9287 Mon Sep 17 00:00:00 2001 From: Andreas Butti Date: Sat, 15 Dec 2018 11:55:29 +0100 Subject: [PATCH] Input Handling --- src/gui/inputdevices/AbstractInputDevice.cpp | 47 ----- src/gui/inputdevices/InputSequence.cpp | 201 ++++++++++++------- src/gui/inputdevices/InputSequence.h | 16 +- src/gui/inputdevices/NewGtkInputDevice.cpp | 50 ----- src/gui/inputdevices/NewGtkInputDevice.h | 16 -- 5 files changed, 146 insertions(+), 184 deletions(-) diff --git a/src/gui/inputdevices/AbstractInputDevice.cpp b/src/gui/inputdevices/AbstractInputDevice.cpp index 9a99dc07..4233c664 100644 --- a/src/gui/inputdevices/AbstractInputDevice.cpp +++ b/src/gui/inputdevices/AbstractInputDevice.cpp @@ -9,53 +9,6 @@ #include "gui/XournalView.h" -bool gtk_xournal_scroll_callback(GtkXournal* xournal) -{ - xournal->layout->scrollRelativ(xournal->scrollOffsetX, xournal->scrollOffsetY); - - // Scrolling done, so reset our counters - xournal->scrollOffsetX = 0; - xournal->scrollOffsetY = 0; - - return false; -} - -static void gtk_xournal_scroll_mouse_event(GtkXournal* xournal, GdkEventMotion* event) -{ - // use root coordinates as reference point because - // scrolling changes window relative coordinates - // see github Gnome/evince@1adce5486b10e763bed869 - int x_root = event->x_root; - int y_root = event->y_root; - - if (xournal->lastMousePositionX - x_root == 0 && xournal->lastMousePositionY - y_root == 0) - { - return; - } - - if (xournal->scrollOffsetX == 0 && xournal->scrollOffsetY == 0) - { - xournal->scrollOffsetX = xournal->lastMousePositionX - x_root; - xournal->scrollOffsetY = xournal->lastMousePositionY - y_root; - - g_idle_add((GSourceFunc) gtk_xournal_scroll_callback, xournal); - //gtk_xournal_scroll_callback(xournal); - xournal->lastMousePositionX = x_root; - xournal->lastMousePositionY = y_root; - } -} - -XojPageView* gtk_xournal_get_page_view_for_pos_cached(GtkXournal* xournal, int x, int y) -{ - x += xournal->x; - y += xournal->y; - - PagePositionHandler* pph = xournal->view->getPagePositionHandler(); - - return pph->getViewAt(x, y, xournal->pagePositionCache); -} - - AbstractInputDevice::AbstractInputDevice(GtkWidget* widget, XournalView* view) : widget(widget), view(view) diff --git a/src/gui/inputdevices/InputSequence.cpp b/src/gui/inputdevices/InputSequence.cpp index 2c49f2a6..a14d5013 100644 --- a/src/gui/inputdevices/InputSequence.cpp +++ b/src/gui/inputdevices/InputSequence.cpp @@ -6,10 +6,51 @@ #include "control/tools/EditSelection.h" #include "control/ToolHandler.h" #include "gui/Cursor.h" +#include "gui/pageposition/PagePositionHandler.h" #include "gui/PageView.h" #include "gui/XournalView.h" + +/* +bool gtk_xournal_scroll_callback(GtkXournal* xournal) +{ + xournal->layout->scrollRelativ(xournal->scrollOffsetX, xournal->scrollOffsetY); + + // Scrolling done, so reset our counters + xournal->scrollOffsetX = 0; + xournal->scrollOffsetY = 0; + + return false; +} + +static void gtk_xournal_scroll_mouse_event(GtkXournal* xournal, GdkEventMotion* event) +{ + // use root coordinates as reference point because + // scrolling changes window relative coordinates + // see github Gnome/evince@1adce5486b10e763bed869 + int x_root = event->x_root; + int y_root = event->y_root; + + if (xournal->lastMousePositionX - x_root == 0 && xournal->lastMousePositionY - y_root == 0) + { + return; + } + + if (xournal->scrollOffsetX == 0 && xournal->scrollOffsetY == 0) + { + xournal->scrollOffsetX = xournal->lastMousePositionX - x_root; + xournal->scrollOffsetY = xournal->lastMousePositionY - y_root; + + g_idle_add((GSourceFunc) gtk_xournal_scroll_callback, xournal); + //gtk_xournal_scroll_callback(xournal); + xournal->lastMousePositionX = x_root; + xournal->lastMousePositionY = y_root; + } +}*/ + + + InputSequence::InputSequence(NewGtkInputDevice* inputHandler) : inputHandler(inputHandler), current_view(NULL), @@ -20,6 +61,8 @@ InputSequence::InputSequence(NewGtkInputDevice* inputHandler) y(-1) { XOJ_INIT_TYPE(InputSequence); + + this->presureSensitivity = inputHandler->getSettings()->isPresureSensitivity(); } InputSequence::~InputSequence() @@ -86,6 +129,25 @@ void InputSequence::setCurrentPosition(double x, double y) this->y = y; } +/** + * Get Page at current position + * + * @return page or NULL if none + */ +XojPageView* InputSequence::getPageAtCurrentPosition() +{ + XOJ_CHECK_TYPE(InputSequence); + + GtkXournal* xournal = inputHandler->getXournal(); + + double x = this->x + xournal->x; + double y = this->y + xournal->y; + + PagePositionHandler* pph = xournal->view->getPagePositionHandler(); + + return pph->getViewAt(x, y, xournal->pagePositionCache); +} + /** * Mouse / Pen / Touch move */ @@ -108,7 +170,7 @@ bool InputSequence::actionMoved() { if (xournal->inScrolling) { -//TODO gtk_xournal_scroll_mouse_event(xournal, event); + // TODO gtk_xournal_scroll_mouse_event(xournal, event); return true; } return false; @@ -141,7 +203,7 @@ bool InputSequence::actionMoved() } else { - pv = gtk_xournal_get_page_view_for_pos_cached(xournal, x, y); + pv = getPageAtCurrentPosition(); } xournal->view->getCursor()->setInsidePage(pv != NULL); @@ -151,7 +213,8 @@ bool InputSequence::actionMoved() // allow events only to a single page! if (currentInputPage == NULL || pv == currentInputPage) { - return motionEvent(pv, event); + PositionInputData pos = getInputDataRelativeToCurrentPage(pv); + return pv->onMotionNotifyEvent(pos, xournal->shiftDown); } } @@ -161,95 +224,90 @@ bool InputSequence::actionMoved() /** * Mouse / Pen down / touch start */ -void InputSequence::actionStart() +bool InputSequence::actionStart() { XOJ_CHECK_TYPE(InputSequence); inputHandler->focusWidget(); - printf("actionStart %s\n", gdk_device_get_name(device)); -} - -/* - - GtkXournal* xournal = GTK_XOURNAL(widget); - // none button release event was sent, send one now - if (xournal->currentInputPage) + // only for this device, other devices may still have unfinished input + if (currentInputPage) { - GdkEventButton ev = *event; - xournal->currentInputPage->translateEvent((GdkEvent*) &ev, xournal->x, xournal->y); - xournal->currentInputPage->onButtonReleaseEvent(widget, &ev); + PositionInputData pos = getInputDataRelativeToCurrentPage(currentInputPage); + currentInputPage->onButtonReleaseEvent(pos); + currentInputPage->onButtonReleaseEvent(pos); } - ToolHandler* h = xournal->view->getControl()->getToolHandler(); + ToolHandler* h = inputHandler->getToolHandler(); // Change the tool depending on the key or device - if (changeTool(event)) + // TODO Button + if (changeTool(0)) { return true; } + GtkXournal* xournal = inputHandler->getXournal(); + // hand tool don't change the selection, so you can scroll e.g. // with your touchscreen without remove the selection if (h->getToolType() == TOOL_HAND) { - Cursor* cursor = xournal->view->getCursor(); - cursor->setMouseDown(true); - xournal->inScrolling = true; - //set reference - xournal->lastMousePositionX = event->x_root; - xournal->lastMousePositionY = event->y_root; - - return TRUE; +// Cursor* cursor = xournal->view->getCursor(); +// cursor->setMouseDown(true); +// xournal->inScrolling = true; +// //set reference +// xournal->lastMousePositionX = event->x_root; +// xournal->lastMousePositionY = event->y_root; +// +// return TRUE; } else if (xournal->selection) { - EditSelection* selection = xournal->selection; - - XojPageView* view = selection->getView(); - GdkEventButton ev = *event; - view->translateEvent((GdkEvent*) &ev, xournal->x, xournal->y); - CursorSelectionType selType = selection->getSelectionTypeForPos(ev.x, ev.y, xournal->view->getZoom()); - if (selType) - { - - if (selType == CURSOR_SELECTION_MOVE && event->button == 3) - { - selection->copySelection(); - } - - xournal->view->getCursor()->setMouseDown(true); - xournal->selection->mouseDown(selType, ev.x, ev.y); - return true; - } - else - { - xournal->view->clearSelection(); - if (changeTool(event)) - { - return true; - } - } +// EditSelection* selection = xournal->selection; +// +// XojPageView* view = selection->getView(); +// GdkEventButton ev = *event; +// view->translateEvent((GdkEvent*) &ev, xournal->x, xournal->y); +// CursorSelectionType selType = selection->getSelectionTypeForPos(ev.x, ev.y, xournal->view->getZoom()); +// if (selType) +// { +// +// if (selType == CURSOR_SELECTION_MOVE && event->button == 3) +// { +// selection->copySelection(); +// } +// +// xournal->view->getCursor()->setMouseDown(true); +// xournal->selection->mouseDown(selType, ev.x, ev.y); +// return true; +// } +// else +// { +// xournal->view->clearSelection(); +// if (changeTool(event)) +// { +// return true; +// } +// } } - XojPageView* pv = gtk_xournal_get_page_view_for_pos_cached(xournal, event->x, event->y); + XojPageView* pv = getPageAtCurrentPosition(); current_view = pv; if (pv) { - xournal->currentInputPage = pv; - pv->translateEvent((GdkEvent*) event, xournal->x, xournal->y); + currentInputPage = pv; - xournal->view->getDocument()->indexOf(pv->getPage()); - return pv->onButtonPressEvent(widget, event); + PositionInputData pos = getInputDataRelativeToCurrentPage(pv); + return pv->onButtonPressEvent(pos); } - return FALSE; // not handled - - - */ + // not handled + return false; +} /** * Mouse / Pen up / touch end @@ -280,8 +338,8 @@ void InputSequence::actionEnd() if (currentInputPage) { - PositionInputData in = getInputDataRelativeToCurrentPage(); - currentInputPage->onButtonReleaseEvent(in); + PositionInputData pos = getInputDataRelativeToCurrentPage(currentInputPage); + currentInputPage->onButtonReleaseEvent(pos); currentInputPage = NULL; } @@ -300,21 +358,26 @@ void InputSequence::actionEnd() /** * Get input data relative to current input page */ -PositionInputData InputSequence::getInputDataRelativeToCurrentPage() +PositionInputData InputSequence::getInputDataRelativeToCurrentPage(XojPageView* page) { XOJ_CHECK_TYPE(InputSequence); GtkXournal* xournal = inputHandler->getXournal(); - PositionInputData in; - in.x -= currentInputPage->getX() - xournal->x; - in.y -= currentInputPage->getY() - xournal->y; - in.pressure = 1.0; + PositionInputData pos; + pos.x -= page->getX() - xournal->x; + pos.y -= page->getY() - xournal->y; + pos.pressure = 1.0; + + if (presureSensitivity) + { + gdk_device_get_axis(device, axes, GDK_AXIS_PRESSURE, &pos.pressure); + } // TODO Key event - in.state = 0; + pos.state = 0; - return in; + return pos; } /** diff --git a/src/gui/inputdevices/InputSequence.h b/src/gui/inputdevices/InputSequence.h index 3b18904a..558057cb 100644 --- a/src/gui/inputdevices/InputSequence.h +++ b/src/gui/inputdevices/InputSequence.h @@ -36,7 +36,7 @@ public: /** * Mouse / Pen down / touch start */ - void actionStart(); + bool actionStart(); /** * Mouse / Pen up / touch end @@ -71,6 +71,13 @@ public: */ void setCurrentPosition(double x, double y); + /** + * Get Page at current position + * + * @return page or NULL if none + */ + XojPageView* getPageAtCurrentPosition(); + public: /** * Free an input sequence, used as callback for GTK @@ -88,7 +95,7 @@ private: /** * Get input data relative to current input page */ - PositionInputData getInputDataRelativeToCurrentPage(); + PositionInputData getInputDataRelativeToCurrentPage(XojPageView* page); private: XOJ_TYPE_ATTRIB; @@ -118,6 +125,11 @@ private: */ gdouble* axes; + /** + * Pressure sensitivity enabled + */ + bool presureSensitivity; + /** * Position X */ diff --git a/src/gui/inputdevices/NewGtkInputDevice.cpp b/src/gui/inputdevices/NewGtkInputDevice.cpp index 3cb35bf7..a8cc5024 100644 --- a/src/gui/inputdevices/NewGtkInputDevice.cpp +++ b/src/gui/inputdevices/NewGtkInputDevice.cpp @@ -191,54 +191,4 @@ bool NewGtkInputDevice::eventHandler(GdkEvent* event) return true; } -/** - * Mouse / pen moved event - */ -bool NewGtkInputDevice::motionEvent(XojPageView* pageView, GdkEventMotion* event) -{ - XOJ_CHECK_TYPE(NewGtkInputDevice); - - return true; -} - -/** - * Read pressure and position of the pen, if a pen is active - */ -void NewGtkInputDevice::readPositionAndPressure(GdkEventMotion* event, double& x, double& y, double& pressure) -{ - XOJ_CHECK_TYPE(NewGtkInputDevice); - - x = event->x; - y = event->y; - - bool presureSensitivity = view->getControl()->getSettings()->isPresureSensitivity(); - - if (presureSensitivity) - { - return; - } - - ToolHandler* h = view->getControl()->getToolHandler(); - - if (h->getToolType() != TOOL_PEN) - { - return; - } - - if (!getPressureMultiplier((GdkEvent*) event, pressure)) - { - pressure = Point::NO_PRESURE; - } -} - -/** - * Read Pressure over GTK - */ -bool NewGtkInputDevice::getPressureMultiplier(GdkEvent* event, double& pressure) -{ - XOJ_CHECK_TYPE(NewGtkInputDevice); - - return true; -} - diff --git a/src/gui/inputdevices/NewGtkInputDevice.h b/src/gui/inputdevices/NewGtkInputDevice.h index fc7f1875..2fb5e022 100644 --- a/src/gui/inputdevices/NewGtkInputDevice.h +++ b/src/gui/inputdevices/NewGtkInputDevice.h @@ -40,27 +40,11 @@ public: GtkXournal* getXournal(); protected: - /** - * Mouse / pen moved event - */ - bool motionEvent(XojPageView* pageView, GdkEventMotion* event); - /** * Handle all GTK Events */ bool eventHandler(GdkEvent* event); -protected: - /** - * Read Pressure over GTK - */ - bool getPressureMultiplier(GdkEvent* event, double& presure); - - /** - * Read pressure and position of the pen, if a pen is active - */ - void readPositionAndPressure(GdkEventMotion* event, double& x, double& y, double& pressure); - private: static bool event_cb(GtkWidget* widget, GdkEvent* event, NewGtkInputDevice* self);