Example #1
0
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;
}
Example #2
0
/**
 * 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();
}
Example #3
0
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;
}
Example #4
0
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();
}
Example #5
0
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());
		}
	}
}
Example #6
0
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;
}
Example #7
0
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));
	}
}
Example #8
0
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;
}
Example #9
0
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();
	}
}
Example #10
0
/**
 * 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;
}
Example #11
0
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
}
Example #12
0
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;
}
Example #13
0
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;
}
Example #14
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;
}
Example #15
0
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;
}
Example #16
0
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
}
Example #17
0
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);
	}
}
Example #18
0
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());
		}
	}
}
Example #19
0
/**
 * 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;
}