bool PageView::onMotionNotifyEvent(GtkWidget * widget, GdkEventMotion * event) { XOJ_CHECK_TYPE(PageView); double zoom = xournal->getZoom(); double x = event->x / zoom; double y = event->y / zoom; ToolHandler * h = xournal->getControl()->getToolHandler(); if (this->inputHandler->onMotionNotifyEvent(event)) { //input handler used this event } else if (this->selection) { this->selection->currentPos(x, y); } else if (this->verticalSpace) { this->verticalSpace->currentPos(x, y); } else if (this->textEditor) { Cursor * cursor = getXournal()->getCursor(); cursor->setInvisible(false); Text * text = this->textEditor->getText(); this->textEditor->mouseMoved(x - text->getX(), y - text->getY()); } else if (h->getToolType() == TOOL_ERASER && h->getEraserType() != ERASER_TYPE_WHITEOUT && this->inEraser) { this->eraser->erase(x, y); } return false; }
/** * Mouse / Pen up / touch end */ void InputSequence::actionEnd(guint32 time) { XOJ_CHECK_TYPE(InputSequence); if (!inputRunning) { return; } this->eventTime = time; // Mouse button not pressed anymore this->button = 0; current_view = NULL; GtkXournal* xournal = inputHandler->getXournal(); XournalppCursor* cursor = xournal->view->getCursor(); ToolHandler* h = inputHandler->getToolHandler(); if (xournal->view->getControl()->getWindow()->isGestureActive()) { stopInput(); return; } cursor->setMouseDown(false); inScrolling = false; EditSelection* sel = xournal->view->getSelection(); if (sel) { sel->mouseUp(); } if (currentInputPage) { PositionInputData pos = getInputDataRelativeToCurrentPage(currentInputPage); currentInputPage->onButtonReleaseEvent(pos); currentInputPage = NULL; } EditSelection* tmpSelection = xournal->selection; xournal->selection = NULL; h->restoreLastConfig(); // we need this workaround so it's possible to select something with the middle button if (tmpSelection) { xournal->view->setSelection(tmpSelection); } stopInput(); }
gboolean gtk_xournal_button_release_event(GtkWidget* widget, GdkEventButton* event) { #ifdef INPUT_DEBUG gboolean isCore = (event->device == gdk_device_get_core_pointer()); INPUTDBG("ButtonRelease (%s) (x,y)=(%.2f,%.2f), button %d, modifier %x, isCore %i", gdk_device_get_name(event->device), event->x, event->y, event->button, event->state, isCore); #endif XInputUtils::fixXInputCoords((GdkEvent*) event, widget); if (event->button > 3) // scroll wheel events { return true; } current_view = NULL; GtkXournal* xournal = GTK_XOURNAL(widget); Cursor* cursor = xournal->view->getCursor(); ToolHandler* h = xournal->view->getControl()->getToolHandler(); cursor->setMouseDown(false); xournal->inScrolling = false; EditSelection* sel = xournal->view->getSelection(); if (sel) { sel->mouseUp(); } bool res = false; if (xournal->currentInputPage) { xournal->currentInputPage->translateEvent((GdkEvent*) event, xournal->x, xournal->y); res = xournal->currentInputPage->onButtonReleaseEvent(widget, event); xournal->currentInputPage = NULL; } EditSelection* tmpSelection = xournal->selection; xournal->selection = NULL; h->restoreLastConfig(); // we need this workaround so it's possible to select something with the middle button if (tmpSelection) { xournal->view->setSelection(tmpSelection); } return res; }
void InputHandler::addPointToTmpStroke(GdkEventMotion * event) { XOJ_CHECK_TYPE(InputHandler); double zoom = xournal->getZoom(); double x = event->x / zoom; double y = event->y / zoom; bool presureSensitivity = xournal->getControl()->getSettings()->isPresureSensitivity(); if (tmpStroke->getPointCount() > 0) { Point p = tmpStroke->getPoint(tmpStroke->getPointCount() - 1); if (hypot(p.x - x, p.y - y) < PIXEL_MOTION_THRESHOLD) { return; // not a meaningful motion } } ToolHandler * h = xournal->getControl()->getToolHandler(); if (h->isRuler()) { int count = tmpStroke->getPointCount(); if (count < 2) { tmpStroke->addPoint(Point(x, y)); } else { tmpStroke->setLastPoint(x, y); } Point p = tmpStroke->getPoint(0); //Draw the initial stroke or else rerender it //The rerenderelement is bugged up on Debian Squeeze //Until this is fixed just repaint. this->redrawable->rerenderElement(this->tmpStroke); this->redrawable->repaintElement(this->tmpStroke); return; } if (presureSensitivity) { double pressure = Point::NO_PRESURE; if (h->getToolType() == TOOL_PEN) { if (getPressureMultiplier((GdkEvent *) event, pressure)) { pressure = pressure * tmpStroke->getWidth(); } else { pressure = Point::NO_PRESURE; } } tmpStroke->setLastPressure(pressure); } tmpStroke->addPoint(Point(x, y)); drawTmpStroke(); }
void PageView::startText(double x, double y) { XOJ_CHECK_TYPE(PageView); this->xournal->endTextAllPages(this); if (this->textEditor == NULL) { // Is there already a textfield? ListIterator<Element *> eit = this->page.getSelectedLayer()->elementIterator(); Text * text = NULL; while (eit.hasNext()) { Element * e = eit.next(); if (e->getType() == ELEMENT_TEXT) { GdkRectangle matchRect = { x - 10, y - 10, 20, 20 }; if (e->intersectsArea(&matchRect)) { text = (Text *) e; break; } } } bool ownText = false; if (text == NULL) { ToolHandler * h = xournal->getControl()->getToolHandler(); ownText = true; text = new Text(); text->setX(x); text->setY(y); text->setColor(h->getColor()); text->setFont(settings->getFont()); } this->textEditor = new TextEditor(this, xournal->getWidget(), text, ownText); if (!ownText) { this->textEditor->mousePressed(x - text->getX(), y - text->getY()); } rerenderPage(); } else { Text * text = this->textEditor->getText(); GdkRectangle matchRect = { x - 10, y - 10, 20, 20 }; if (!text->intersectsArea(&matchRect)) { endText(); } else { this->textEditor->mousePressed(x - text->getX(), y - text->getY()); } } }
gboolean gtk_xournal_motion_notify_event(GtkWidget * widget, GdkEventMotion * event) { #ifdef INPUT_DEBUG bool is_core = (event->device == gdk_device_get_core_pointer()); INPUTDBG("MotionNotify (%s) (x,y)=(%.2f,%.2f), modifier %x", is_core ? "core" : "xinput", event->x, event->y, event->state); #endif XInputUtils::fixXInputCoords((GdkEvent*) event, widget); GtkXournal * xournal = GTK_XOURNAL(widget); ToolHandler * h = xournal->view->getControl()->getToolHandler(); if (h->getToolType() == TOOL_HAND) { if (xournal->inScrolling) { gtk_xournal_scroll_mouse_event(xournal, event); return true; } return false; } else if (xournal->selection) { EditSelection * selection = xournal->selection; PageView * view = selection->getView(); GdkEventMotion ev = *event; view->translateEvent((GdkEvent*) &ev, xournal->x, xournal->y); if (xournal->selection->isMoving()) { selection->mouseMove(ev.x, ev.y); } else { CursorSelectionType selType = selection->getSelectionTypeForPos(ev.x, ev.y, xournal->view->getZoom()); xournal->view->getCursor()->setMouseSelectionType(selType); } return true; } PageView * pv = gtk_xournal_get_page_view_for_pos_cached(xournal, event->x, event->y); xournal->view->getCursor()->setInsidePage(pv != NULL); if (pv) { // allow events only to a single page! if (xournal->currentInputPage == NULL || pv == xournal->currentInputPage) { pv->translateEvent((GdkEvent*) event, xournal->x, xournal->y); return pv->onMotionNotifyEvent(widget, event);; } } return false; }
void InputHandler::startStroke(GdkEventButton * event, StrokeTool tool, double x, double y) { XOJ_CHECK_TYPE(InputHandler); ToolHandler * h = xournal->getControl()->getToolHandler(); if(event->device == NULL) { g_warning("startStroke: event->device == null"); } if (tmpStroke == NULL) { currentInputDevice = event->device; tmpStroke = new Stroke(); tmpStroke->setWidth(h->getThickness()); tmpStroke->setColor(h->getColor()); tmpStroke->setToolType(tool); tmpStroke->addPoint(Point(x, y)); } }
static bool change_tool(Settings* settings, GdkEventButton* event, GtkXournal* xournal) { ButtonConfig* cfg = NULL; ButtonConfig* cfgTouch = settings->getTouchButtonConfig(); ToolHandler* h = xournal->view->getControl()->getToolHandler(); if (event->button == 2) // Middle Button { cfg = settings->getMiddleButtonConfig(); } else if (event->button == 3 && !xournal->selection) // Right Button { cfg = settings->getRightButtonConfig(); } else if (event->device->source == GDK_SOURCE_ERASER) { cfg = settings->getEraserButtonConfig(); } else if (cfgTouch->device == event->device->name) { cfg = cfgTouch; // If an action is defined we do it, even if it's a drawing action... if (cfg->getDisableDrawing() && cfg->getAction() == TOOL_NONE) { ToolType tool = h->getToolType(); if (tool == TOOL_PEN || tool == TOOL_ERASER || tool == TOOL_HILIGHTER) { printf("ignore touchscreen for drawing!\n"); return true; } } } if (cfg && cfg->getAction() != TOOL_NONE) { h->copyCurrentConfig(); cfg->acceptActions(h); } return false; }
void Cursor::setMouseDown(bool mouseDown) { XOJ_CHECK_TYPE(Cursor); if (this->mouseDown == mouseDown) { return; } this->mouseDown = mouseDown; ToolHandler* handler = control->getToolHandler(); ToolType type = handler->getToolType(); // Not always an update is needed if (type == TOOL_HAND || type == TOOL_VERTICAL_SPACE) { updateCursor(); } }
/** * Change the tool according to the device and button * @return true to ignore event */ bool InputSequence::changeTool() { XOJ_CHECK_TYPE(InputSequence); Settings* settings = inputHandler->getSettings(); ButtonConfig* cfgTouch = settings->getTouchButtonConfig(); ToolHandler* h = inputHandler->getToolHandler(); GtkXournal* xournal = inputHandler->getXournal(); ButtonConfig* cfg = NULL; if (gdk_device_get_source(device) == GDK_SOURCE_PEN) { penDevice = true; if (button == 2) { cfg = settings->getStylusButton1Config(); } else if (button == 3) { cfg = settings->getStylusButton2Config(); } } else if (button == 2 /* Middle Button */ && !xournal->selection) { cfg = settings->getMiddleButtonConfig(); } else if (button == 3 /* Right Button */ && !xournal->selection) { cfg = settings->getRightButtonConfig(); } else if (gdk_device_get_source(device) == GDK_SOURCE_ERASER) { penDevice = true; cfg = settings->getEraserButtonConfig(); } else if (cfgTouch->device == gdk_device_get_name(device)) { cfg = cfgTouch; // If an action is defined we do it, even if it's a drawing action... if (cfg->getDisableDrawing() && cfg->getAction() == TOOL_NONE) { ToolType tool = h->getToolType(); if (tool == TOOL_PEN || tool == TOOL_ERASER || tool == TOOL_HILIGHTER) { g_message("ignore touchscreen for drawing!\n"); return true; } } } if (cfg && cfg->getAction() != TOOL_NONE) { h->copyCurrentConfig(); cfg->acceptActions(h); } else { h->restoreLastConfig(); } return false; }
gboolean gtk_xournal_button_press_event(GtkWidget* widget, GdkEventButton* event) { /** * true: Core event, false: XInput event */ gboolean isCore = (event->device == gdk_device_get_core_pointer()); INPUTDBG("ButtonPress (%s) (x,y)=(%.2f,%.2f), button %d, modifier %x, isCore %i", gdk_device_get_name(event->device), event->x, event->y, event->button, event->state, isCore); GtkXournal* xournal = GTK_XOURNAL(widget); Settings* settings = xournal->view->getControl()->getSettings(); if(isCore && settings->isXinputEnabled() && settings->isIgnoreCoreEvents()) { INPUTDBG2("gtk_xournal_button_press_event return false (ignore core)"); return false; } XInputUtils::fixXInputCoords((GdkEvent*) event, widget); if (event->type != GDK_BUTTON_PRESS) { INPUTDBG2("gtk_xournal_button_press_event return false (event->type != GDK_BUTTON_PRESS)"); return false; // this event is not handled here } if (event->button > 3) // scroll wheel events { XInputUtils::handleScrollEvent(event, widget); INPUTDBG2("gtk_xournal_button_press_event return true handled scroll event"); return true; } gtk_widget_grab_focus(widget); // none button release event was sent, send one now if (xournal->currentInputPage) { INPUTDBG2("gtk_xournal_button_press_event (xournal->currentInputPage != NULL)"); GdkEventButton ev = *event; xournal->currentInputPage->translateEvent((GdkEvent*) &ev, xournal->x, xournal->y); xournal->currentInputPage->onButtonReleaseEvent(widget, &ev); } ToolHandler* h = xournal->view->getControl()->getToolHandler(); // Change the tool depending on the key or device if(change_tool(settings, event, xournal)) return true; // 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->lastMousePositionX = 0; xournal->lastMousePositionY = 0; xournal->inScrolling = true; gtk_widget_get_pointer(widget, &xournal->lastMousePositionX, &xournal->lastMousePositionY); INPUTDBG2("gtk_xournal_button_press_event (h->getToolType() == TOOL_HAND) return true"); return true; } else if (xournal->selection) { EditSelection* selection = xournal->selection; PageView* 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); INPUTDBG2("gtk_xournal_button_press_event (selection) return true"); return true; } else { xournal->view->clearSelection(); if(change_tool(settings, event, xournal)) return true; } } PageView* pv = gtk_xournal_get_page_view_for_pos_cached(xournal, event->x, event->y); current_view = pv; if (pv) { xournal->currentInputPage = pv; pv->translateEvent((GdkEvent*) event, xournal->x, xournal->y); INPUTDBG2("gtk_xournal_button_press_event (pv->onButtonPressEvent) return"); xournal->view->getDocument()->indexOf(pv->getPage()); return pv->onButtonPressEvent(widget, event); } INPUTDBG2("gtk_xournal_button_press_event (not handled) return false"); return false; // not handled }
GdkCursor* Cursor::getPenCursor() { XOJ_CHECK_TYPE(Cursor); ToolHandler* handler = control->getToolHandler(); bool big = control->getSettings()->isShowBigCursor(); int height = 3; int width = 3; if (big) { height = 22; width = 15; } cairo_surface_t* crCursor = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); cairo_t* cr = cairo_create(crCursor); Util::cairo_set_source_rgbi(cr, handler->getColor()); if (big) { cairo_set_source_rgb(cr, 1, 1, 1); cairo_set_line_width(cr, 1.2); cairo_move_to(cr, 1.5, 1.5); cairo_line_to(cr, 2, 19); cairo_line_to(cr, 5.5, 15.5); cairo_line_to(cr, 8.5, 20.5); cairo_line_to(cr, 10.5, 19); cairo_line_to(cr, 8.5, 14); cairo_line_to(cr, 13, 14); cairo_close_path(cr); cairo_fill_preserve(cr); cairo_set_source_rgb(cr, 0, 0, 0); cairo_stroke(cr); Util::cairo_set_source_rgbi(cr, handler->getColor()); cairo_rectangle(cr, 0, 0, 3, 3); cairo_fill(cr); } else { cairo_rectangle(cr, 0, 0, 3, 3); cairo_fill(cr); } cairo_destroy(cr); GdkPixbuf* pixbuf = xoj_pixbuf_get_from_surface(crCursor, 0, 0, width, height); // cairo_surface_write_to_png(crCursor, "/home/andreas/xoj-cursor-orig.png"); // gdk_pixbuf_save(pixbuf, "/home/andreas/xoj-cursor.png", "png", NULL, NULL); cairo_surface_destroy(crCursor); GdkCursor* cursor = gdk_cursor_new_from_pixbuf(gtk_widget_get_display( control->getWindow()->getXournal()->getWidget()), pixbuf, 1, 1); gdk_pixbuf_unref(pixbuf); return cursor; }
void InputHandler::onButtonReleaseEvent(GdkEventButton * event, PageRef page) { XOJ_CHECK_TYPE(InputHandler); if (!this->tmpStroke) { return; } // Backward compatibility and also easier to handle for me;-) // I cannot draw a line with one point, to draw a visible line I need two points, // twice the same Point is also OK if (this->tmpStroke->getPointCount() == 1) { ArrayIterator<Point> it = this->tmpStroke->pointIterator(); if (it.hasNext()) { this->tmpStroke->addPoint(it.next()); } // No pressure sensitivity this->tmpStroke->clearPressure(); } this->tmpStroke->freeUnusedPointItems(); if (page.getSelectedLayerId() < 1) { // This creates a layer if none exists page.getSelectedLayer(); page.setSelectedLayerId(1); xournal->getControl()->getWindow()->updateLayerCombobox(); } Layer * layer = page.getSelectedLayer(); UndoRedoHandler * undo = xournal->getControl()->getUndoRedoHandler(); undo->addUndoAction(new InsertUndoAction(page, layer, this->tmpStroke, this->redrawable)); ToolHandler * h = xournal->getControl()->getToolHandler(); if (h->isShapeRecognizer()) { if (this->reco == NULL) { this->reco = new ShapeRecognizer(); } ShapeRecognizerResult * result = this->reco->recognizePatterns(this->tmpStroke); if (result != NULL) { UndoRedoHandler * undo = xournal->getControl()->getUndoRedoHandler(); Stroke * recognized = result->getRecognized(); RecognizerUndoAction * recognizerUndo = new RecognizerUndoAction(page, this->redrawable, layer, this->tmpStroke, recognized); undo->addUndoAction(recognizerUndo); layer->addElement(result->getRecognized()); Range range(recognized->getX(), recognized->getY()); range.addPoint(recognized->getX() + recognized->getElementWidth(), recognized->getY() + recognized->getElementHeight()); range.addPoint(this->tmpStroke->getX(), this->tmpStroke->getY()); range.addPoint(this->tmpStroke->getX() + this->tmpStroke->getElementWidth(), this->tmpStroke->getY() + this->tmpStroke->getElementHeight()); ListIterator<Stroke *> l = result->getSources(); while (l.hasNext()) { Stroke * s = l.next(); layer->removeElement(s, false); recognizerUndo->addSourceElement(s); range.addPoint(s->getX(), s->getY()); range.addPoint(s->getX() + s->getElementWidth(), s->getY() + s->getElementHeight()); } this->redrawable->rerenderRange(range); // delete the result object, this is not needed anymore, the stroke are not deleted with this delete result; } else { layer->addElement(this->tmpStroke); this->redrawable->rerenderElement(this->tmpStroke); } } else { layer->addElement(this->tmpStroke); this->redrawable->rerenderElement(this->tmpStroke); } this->tmpStroke = NULL; if (currentInputDevice == event->device) { currentInputDevice = NULL; INPUTDBG("currentInputDevice = NULL\n", 0); } this->tmpStrokeDrawElem = 0; }
/** * Mouse / Pen down / touch start */ bool InputSequence::actionStart(guint32 time) { XOJ_CHECK_TYPE(InputSequence); this->eventTime = time; inputHandler->focusWidget(); checkCanStartInput(); if (!inputRunning) { return false; } // none button release event was sent, send one now // only for this device, other devices may still have unfinished input if (currentInputPage) { PositionInputData pos = getInputDataRelativeToCurrentPage(currentInputPage); currentInputPage->onButtonReleaseEvent(pos); } // Change the tool depending on the key or device if (changeTool()) { 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 ToolHandler* h = inputHandler->getToolHandler(); if (h->getToolType() == TOOL_HAND) { XournalppCursor* cursor = xournal->view->getCursor(); cursor->setMouseDown(true); inScrolling = true; // set reference lastMousePositionX = rootX; lastMousePositionY = rootY; return true; } else if (xournal->selection) { EditSelection* selection = xournal->selection; XojPageView* view = selection->getView(); PositionInputData pos = getInputDataRelativeToCurrentPage(view); CursorSelectionType selType = selection->getSelectionTypeForPos(pos.x, pos.y, xournal->view->getZoom()); if (selType) { if (selType == CURSOR_SELECTION_MOVE && button == 3) { selection->copySelection(); } xournal->view->getCursor()->setMouseDown(true); xournal->selection->mouseDown(selType, pos.x, pos.y); return true; } else { xournal->view->clearSelection(); if (changeTool()) { return true; } } } XojPageView* pv = getPageAtCurrentPosition(); current_view = pv; if (pv) { currentInputPage = pv; PositionInputData pos = getInputDataRelativeToCurrentPage(pv); return pv->onButtonPressEvent(pos); } // not handled return false; }
bool PageView::onButtonPressEvent(GtkWidget * widget, GdkEventButton * event) { XOJ_CHECK_TYPE(PageView); if ((event->state & (GDK_CONTROL_MASK | GDK_MOD1_MASK)) != 0) { return false; // not handled here } if (!this->selected) { xournal->getControl()->firePageSelected(this->page); } ToolHandler * h = xournal->getControl()->getToolHandler(); double x = event->x; double y = event->y; if ((x < 0 || y < 0) && !extendedWarningDisplayd && settings->isXinputEnabled()) { GtkWidget * dialog = gtk_message_dialog_new((GtkWindow *) *xournal->getControl()->getWindow(), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_NONE, _("There was a wrong input event, input is not working.\nDo you want to disable \"Extended Input\"?")); gtk_dialog_add_button(GTK_DIALOG(dialog), "Disable \"Extended Input\"", 1); gtk_dialog_add_button(GTK_DIALOG(dialog), "Cancel", 2); this->extendedWarningDisplayd = true; gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(this->xournal->getControl()->getWindow()->getWindow())); if (gtk_dialog_run(GTK_DIALOG(dialog)) == 1) { settings->setXinputEnabled(false); xournal->updateXEvents(); } gtk_widget_destroy(dialog); return true; } double zoom = xournal->getZoom(); x /= zoom; y /= zoom; Cursor * cursor = xournal->getCursor(); cursor->setMouseDown(true); if (h->getToolType() == TOOL_PEN) { this->inputHandler->startStroke(event, STROKE_TOOL_PEN, x, y); } else if (h->getToolType() == TOOL_HILIGHTER) { this->inputHandler->startStroke(event, STROKE_TOOL_HIGHLIGHTER, x, y); } else if (h->getToolType() == TOOL_ERASER) { if (h->getEraserType() == ERASER_TYPE_WHITEOUT) { this->inputHandler->startStroke(event, STROKE_TOOL_ERASER, x, y); this->inputHandler->getTmpStroke()->setColor(0xffffff); // White } else { this->eraser->erase(x, y); this->inEraser = true; } } else if (h->getToolType() == TOOL_VERTICAL_SPACE) { this->verticalSpace = new VerticalToolHandler(this, this->page, y, zoom); } else if (h->getToolType() == TOOL_SELECT_RECT || h->getToolType() == TOOL_SELECT_REGION || h->getToolType() == TOOL_SELECT_OBJECT) { if (h->getToolType() == TOOL_SELECT_RECT) { if (this->selection) { delete this->selection; this->selection = NULL; repaintPage(); } this->selection = new RectSelection(x, y, this); } else if (h->getToolType() == TOOL_SELECT_REGION) { if (this->selection) { delete this->selection; this->selection = NULL; repaintPage(); } this->selection = new RegionSelect(x, y, this); } else if (h->getToolType() == TOOL_SELECT_OBJECT) { selectObjectAt(x, y); } } else if (h->getToolType() == TOOL_TEXT) { startText(x, y); } else if (h->getToolType() == TOOL_IMAGE) { ImageHandler imgHandler(xournal->getControl(), this); imgHandler.insertImage(x, y); } return true; }
gboolean gtk_xournal_button_press_event(GtkWidget * widget, GdkEventButton * event) { /** * true: Core event, false: XInput event */ gboolean isCore = (event->device == gdk_device_get_core_pointer()); INPUTDBG("ButtonPress (%s) (x,y)=(%.2f,%.2f), button %d, modifier %x, isCore %i", gdk_device_get_name(event->device), event->x, event->y, event->button, event->state, isCore); GtkXournal * xournal = GTK_XOURNAL(widget); Settings * settings = xournal->view->getControl()->getSettings(); if(isCore && settings->isXinputEnabled() && settings->isIgnoreCoreEvents()) { INPUTDBG2("gtk_xournal_button_press_event return false (ignore core)"); return false; } XInputUtils::fixXInputCoords((GdkEvent*) event, widget); if (event->type != GDK_BUTTON_PRESS) { INPUTDBG2("gtk_xournal_button_press_event return false (event->type != GDK_BUTTON_PRESS)"); return false; // this event is not handled here } if (event->button > 3) { // scroll wheel events XInputUtils::handleScrollEvent(event, widget); INPUTDBG2("gtk_xournal_button_press_event return true handled scroll event"); return true; } gtk_widget_grab_focus(widget); ToolHandler * h = xournal->view->getControl()->getToolHandler(); // none button release event was sent, send one now if (xournal->currentInputPage) { INPUTDBG2("gtk_xournal_button_press_event (xournal->currentInputPage != NULL)"); GdkEventButton ev = *event; xournal->currentInputPage->translateEvent((GdkEvent*) &ev, xournal->x, xournal->y); xournal->currentInputPage->onButtonReleaseEvent(widget, &ev); } // Change the tool depending on the key or device ButtonConfig * cfg = NULL; ButtonConfig * cfgTouch = settings->getTouchButtonConfig(); if (event->button == 2) { // Middle Button cfg = settings->getMiddleButtonConfig(); } else if (event->button == 3) { // Right Button cfg = settings->getRightButtonConfig(); } else if (event->device->source == GDK_SOURCE_ERASER) { cfg = settings->getEraserButtonConfig(); } else if (cfgTouch->device == event->device->name) { cfg = cfgTouch; // If an action is defined we do it, even if it's a drawing action... if (cfg->getDisableDrawing() && cfg->getAction() == TOOL_NONE) { ToolType tool = h->getToolType(); if (tool == TOOL_PEN || tool == TOOL_ERASER || tool == TOOL_HILIGHTER) { printf("ignore touchscreen for drawing!\n"); return true; } } } if (cfg && cfg->getAction() != TOOL_NONE) { h->copyCurrentConfig(); cfg->acceptActions(h); } // 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->lastMousePositionX = 0; xournal->lastMousePositionY = 0; xournal->inScrolling = true; gtk_widget_get_pointer(widget, &xournal->lastMousePositionX, &xournal->lastMousePositionY); INPUTDBG2("gtk_xournal_button_press_event (h->getToolType() == TOOL_HAND) return true"); return true; } else if (xournal->selection) { EditSelection * selection = xournal->selection; PageView * 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) { xournal->view->getCursor()->setMouseDown(true); xournal->selection->mouseDown(selType, ev.x, ev.y); INPUTDBG2("gtk_xournal_button_press_event (selection) return true"); return true; } else { xournal->view->clearSelection(); } } PageView * pv = gtk_xournal_get_page_view_for_pos_cached(xournal, event->x, event->y); if (pv) { xournal->currentInputPage = pv; pv->translateEvent((GdkEvent*) event, xournal->x, xournal->y); INPUTDBG2("gtk_xournal_button_press_event (pv->onButtonPressEvent) return"); xournal->view->getDocument()->indexOf(pv->getPage()); return pv->onButtonPressEvent(widget, event); } INPUTDBG2("gtk_xournal_button_press_event (not handled) return false"); return false; // not handled }
void Cursor::updateCursor() { XOJ_CHECK_TYPE(Cursor); MainWindow* win = control->getWindow(); if (!win) { return; } XournalView* xournal = win->getXournal(); if (!xournal) { return; } GdkCursor* cursor = NULL; if (this->busy) { cursor = gdk_cursor_new(GDK_WATCH); } else { ToolHandler* handler = control->getToolHandler(); ToolType type = handler->getToolType(); if (type == TOOL_HAND) { if (this->mouseDown) { cursor = gdk_cursor_new(GDK_FLEUR); } else { cursor = gdk_cursor_new(GDK_HAND1); } } else if(!this->insidePage) { // not inside page: so use default cursor } else if (this->selectionType) { switch (this->selectionType) { case CURSOR_SELECTION_MOVE: cursor = gdk_cursor_new(GDK_FLEUR); break; case CURSOR_SELECTION_TOP_LEFT: cursor = gdk_cursor_new(GDK_TOP_LEFT_CORNER); break; case CURSOR_SELECTION_TOP_RIGHT: cursor = gdk_cursor_new(GDK_TOP_RIGHT_CORNER); break; case CURSOR_SELECTION_BOTTOM_LEFT: cursor = gdk_cursor_new(GDK_BOTTOM_LEFT_CORNER); break; case CURSOR_SELECTION_BOTTOM_RIGHT: cursor = gdk_cursor_new(GDK_BOTTOM_RIGHT_CORNER); break; case CURSOR_SELECTION_LEFT: case CURSOR_SELECTION_RIGHT: cursor = gdk_cursor_new(GDK_SB_H_DOUBLE_ARROW); break; case CURSOR_SELECTION_TOP: case CURSOR_SELECTION_BOTTOM: cursor = gdk_cursor_new(GDK_SB_V_DOUBLE_ARROW); break; } } else if (type == TOOL_PEN) { cursor = getPenCursor(); } else if (type == TOOL_ERASER) { GdkColor bg = { 0, 65535, 65535, 65535 }; GdkColor fg = { 0, 0, 0, 0 }; GdkPixmap* source = gdk_bitmap_create_from_data(NULL, (gchar*) CURSOR_HIGLIGHTER_BITS, 16, 16); GdkPixmap* mask = gdk_bitmap_create_from_data(NULL, (gchar*) CURSOR_HILIGHTER_MASK, 16, 16); cursor = gdk_cursor_new_from_pixmap(source, mask, &fg, &bg, 7, 7); gdk_bitmap_unref(source); gdk_bitmap_unref(mask); } else if (type == TOOL_HILIGHTER) { GdkColor fg = { 0, 0, 0, 0 }; GdkColor bg = handler->getGdkColor(); GdkPixmap* source = gdk_bitmap_create_from_data(NULL, (gchar*) CURSOR_HIGLIGHTER_BITS, 16, 16); GdkPixmap* mask = gdk_bitmap_create_from_data(NULL, (gchar*) CURSOR_HILIGHTER_MASK, 16, 16); cursor = gdk_cursor_new_from_pixmap(source, mask, &fg, &bg, 7, 7); gdk_bitmap_unref(source); gdk_bitmap_unref(mask); } else if (type == TOOL_TEXT) { if (this->invisible) { cursor = gdk_cursor_new(GDK_BLANK_CURSOR); } else { cursor = gdk_cursor_new(GDK_XTERM); } } else if (type == TOOL_IMAGE) { // No special cursor needed } else if (type == TOOL_VERTICAL_SPACE) { if (this->mouseDown) { cursor = gdk_cursor_new(GDK_SB_V_DOUBLE_ARROW); } } else if (type != TOOL_SELECT_OBJECT) // other selections are handled before anyway, because you can move a selection with every tool { cursor = gdk_cursor_new(GDK_TCROSS); } } if (gtk_widget_get_window(xournal->getWidget())) { gdk_window_set_cursor(gtk_widget_get_window(xournal->getWidget()), cursor); gtk_widget_set_sensitive(xournal->getWidget(), !this->busy); } gdk_display_sync(gdk_display_get_default()); if (cursor) { gdk_cursor_unref(cursor); } }
void PageView::startText(double x, double y) { XOJ_CHECK_TYPE(PageView); this->xournal->endTextAllPages(this); if (this->textEditor == NULL) { // Is there already a textfield? ListIterator<Element*> eit = this->page->getSelectedLayer()->elementIterator(); Text* text = NULL; while (eit.hasNext()) { Element* e = eit.next(); if (e->getType() == ELEMENT_TEXT) { GdkRectangle matchRect = { gint(x - 10), gint(y - 10), 20, 20 }; if (e->intersectsArea(&matchRect)) { text = (Text*) e; break; } } } bool ownText = false; if (text == NULL) { ToolHandler* h = xournal->getControl()->getToolHandler(); ownText = true; text = new Text(); text->setX(x); text->setY(y); text->setColor(h->getColor()); text->setFont(settings->getFont()); } else { //We can try to add an undo action here. The initial text shows up in this //textEditor element. this->oldtext = text; //text = new Text(*oldtext); //need to clone the old text so that references still work properly. //cloning breaks things a little. do it manually text = new Text(); text->setX(oldtext->getX()); text->setY(oldtext->getY()); text->setColor(oldtext->getColor()); text->setFont(oldtext->getFont()); text->setText(oldtext->getText()); Layer* layer = this->page->getSelectedLayer(); layer->removeElement(this->oldtext, false); layer->addElement(text); //perform the old swap onto the new text drawn. } this->textEditor = new TextEditor(this, xournal->getWidget(), text, ownText); if (!ownText) { this->textEditor->mousePressed(x - text->getX(), y - text->getY()); } this->rerenderPage(); } else { Text* text = this->textEditor->getText(); GdkRectangle matchRect = {gint(x - 10), gint(y - 10), 20, 20 }; if (!text->intersectsArea(&matchRect)) { endText(); } else { this->textEditor->mousePressed(x - text->getX(), y - text->getY()); } } }
/** * Mouse / Pen / Touch move */ bool InputSequence::actionMoved(guint32 time) { XOJ_CHECK_TYPE(InputSequence); GtkXournal* xournal = inputHandler->getXournal(); ToolHandler* h = inputHandler->getToolHandler(); this->eventTime = time; changeTool(); if (xournal->view->getControl()->getWindow()->isGestureActive()) { return false; } if (h->getToolType() == TOOL_HAND) { if (inScrolling) { handleScrollEvent(); return true; } return false; } else if (xournal->selection) { EditSelection* selection = xournal->selection; XojPageView* view = selection->getView(); PositionInputData pos = getInputDataRelativeToCurrentPage(view); if (xournal->selection->isMoving()) { selection->mouseMove(pos.x, pos.y); } else { CursorSelectionType selType = selection->getSelectionTypeForPos(pos.x, pos.y, xournal->view->getZoom()); xournal->view->getCursor()->setMouseSelectionType(selType); } return true; } XojPageView* pv = NULL; if (current_view) { pv = current_view; } else { pv = getPageAtCurrentPosition(); } xournal->view->getCursor()->setInsidePage(pv != NULL); if (pv && inputRunning) { // allow events only to a single page! if (currentInputPage == NULL || pv == currentInputPage) { PositionInputData pos = getInputDataRelativeToCurrentPage(pv); return pv->onMotionNotifyEvent(pos); } } return false; }