Esempio n. 1
0
/**
 * Change event handling between XInput and Core
 */
void gtk_xournal_update_xevent(GtkWidget* widget)
{
	g_return_if_fail(widget != NULL);
	g_return_if_fail(GTK_IS_XOURNAL(widget));

	GtkXournal* xournal = GTK_XOURNAL(widget);

	Settings* settings = xournal->view->getControl()->getSettings();

	if (!gtk_check_version(2, 17, 0))
	{
		/* GTK+ 2.17 and later: everybody shares a single native window,
		 so we'll never get any core events, and we might as well set
		 extension events the way we're supposed to. Doing so helps solve
		 crasher bugs in 2.17, and prevents us from losing two-button
		 events in 2.18 */
		gtk_widget_set_extension_events(widget,
		                                settings->isUseXInput() ? GDK_EXTENSION_EVENTS_ALL : GDK_EXTENSION_EVENTS_NONE);
	}
	else
	{
		/* GTK+ 2.16 and earlier: we only activate extension events on the
		 PageViews's parent GdkWindow. This allows us to keep receiving core
		 events. */
		gdk_input_set_extension_events(widget->window,
		                               GDK_POINTER_MOTION_MASK | GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK |
		                               GDK_BUTTON_RELEASE_MASK,
		                               settings->isUseXInput() ? GDK_EXTENSION_EVENTS_ALL : GDK_EXTENSION_EVENTS_NONE);
	}

}
Esempio n. 2
0
void gtk_xournal_repaint_area(GtkWidget* widget, int x1, int y1, int x2,
                              int y2)
{
	g_return_if_fail(widget != NULL);
	g_return_if_fail(GTK_IS_XOURNAL(widget));

	GtkXournal* xournal = GTK_XOURNAL(widget);

	x1 -= xournal->x;
	x2 -= xournal->x;
	y1 -= xournal->y;
	y2 -= xournal->y;

	if (x2 < 0 || y2 < 0)
	{
		return; // outside visible area
	}

	GtkAllocation alloc = { 0 };
	gtk_widget_get_allocation(widget, &alloc);

	if (x1 > alloc.width || y1 > alloc.height)
	{
		return; // outside visible area
	}

	gtk_widget_queue_draw_area(widget, x1, y1, x2 - x1, y2 - y1);
}
Esempio n. 3
0
Layout * gtk_xournal_get_layout(GtkWidget * widget) {
	g_return_val_if_fail(widget != NULL, NULL);
	g_return_val_if_fail(GTK_IS_XOURNAL(widget), NULL);

	GtkXournal * xournal = GTK_XOURNAL(widget);
	return xournal->layout;
}
Esempio n. 4
0
static void gtk_xournal_realize(GtkWidget* widget)
{
	GdkWindowAttr attributes;
	guint attributes_mask;

	g_return_if_fail(widget != NULL);
	g_return_if_fail(GTK_IS_XOURNAL(widget));

	GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED);

	attributes.window_type = GDK_WINDOW_CHILD;
	attributes.x = widget->allocation.x;
	attributes.y = widget->allocation.y;
	attributes.width = widget->allocation.width;
	attributes.height = widget->allocation.height;

	attributes.wclass = GDK_INPUT_OUTPUT;
	attributes.event_mask = gtk_widget_get_events(widget) | GDK_EXPOSURE_MASK;

	attributes_mask = GDK_WA_X | GDK_WA_Y;

	widget->window = gdk_window_new(gtk_widget_get_parent_window(widget),
	                                &attributes, attributes_mask);
	gtk_widget_modify_bg(widget, GTK_STATE_NORMAL,
	                     &widget->style->dark[GTK_STATE_NORMAL]);

	gdk_window_set_user_data(widget->window, widget);

	widget->style = gtk_style_attach(widget->style, widget->window);
	gtk_style_set_background(widget->style, widget->window, GTK_STATE_NORMAL);

	gtk_xournal_update_xevent(widget);
}
Esempio n. 5
0
Rectangle * gtk_xournal_get_visible_area(GtkWidget * widget, PageView * p) {
	g_return_val_if_fail(widget != NULL, NULL);
	g_return_val_if_fail(GTK_IS_XOURNAL(widget), NULL);

	GtkXournal * xournal = GTK_XOURNAL(widget);

	GtkAllocation allocation = { 0 };
	gtk_widget_get_allocation(widget, &allocation);
	int viewHeight = allocation.height;
	int viewWidth = allocation.width;

	GdkRectangle r1;
	GdkRectangle r2;
	GdkRectangle r3 = { 0, 0, 0, 0 };

	r1.x = p->getX();
	r1.y = p->getY();
	r1.width = p->getDisplayWidth();
	r1.height = p->getDisplayHeight();

	r2.x = xournal->x;
	r2.y = xournal->y;
	r2.width = viewWidth;
	r2.height = viewHeight;

	gdk_rectangle_intersect(&r1, &r2, &r3);

	if (r3.width == 0 && r3.height == 0) {
		return NULL;
	}

	double zoom = xournal->view->getZoom();

	return new Rectangle(MAX(r3.x, 0) / zoom, MAX(r3.y, 0) / zoom, r3.width / zoom, r3.height / zoom);
}
Esempio n. 6
0
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);
	g_return_val_if_fail(event != NULL, false);

	GtkXournal * xournal = GTK_XOURNAL(widget);

	EditSelection * selection = xournal->selection;
	if (selection) {
		int d = 10;

		if ((event->state & GDK_MOD1_MASK) || (event->state & GDK_SHIFT_MASK)) {
			d = 1;
		}

		if (event->keyval == GDK_Left) {
			selection->moveSelection(-d, 0);
			return true;
		} else if (event->keyval == GDK_Up) {
			selection->moveSelection(0, -d);
			return true;
		} else if (event->keyval == GDK_Right) {
			selection->moveSelection(d, 0);
			return true;
		} else if (event->keyval == GDK_Down) {
			selection->moveSelection(0, d);
			return true;
		}
	}

	return xournal->view->onKeyPressEvent(event);
}
Esempio n. 7
0
// gtk_widget_get_preferred_size()
// the output is the default size on window creation
static void gtk_xournal_size_request(GtkWidget * widget, GtkRequisition * requisition) {
	g_return_if_fail(widget != NULL);
	g_return_if_fail(GTK_IS_XOURNAL(widget));
	g_return_if_fail(requisition != NULL);

	requisition->width = 200;
	requisition->height = 200;
}
Esempio n. 8
0
EditSelection* XournalView::getSelection()
{
	XOJ_CHECK_TYPE(XournalView);

	g_return_val_if_fail(this->widget != NULL, NULL);
	g_return_val_if_fail(GTK_IS_XOURNAL(this->widget), NULL);

	return GTK_XOURNAL(this->widget)->selection;
}
Esempio n. 9
0
static gboolean gtk_xournal_key_release_event(GtkWidget * widget, GdkEventKey * event) {
	g_return_val_if_fail(widget != NULL, false);
	g_return_val_if_fail(GTK_IS_XOURNAL(widget), false);
	g_return_val_if_fail(event != NULL, false);

	GtkXournal * xournal = GTK_XOURNAL(widget);

	return xournal->view->onKeyReleaseEvent(event);
}
Esempio n. 10
0
static void gtk_xournal_size_allocate(GtkWidget * widget, GtkAllocation * allocation) {
	g_return_if_fail(widget != NULL);
	g_return_if_fail(GTK_IS_XOURNAL(widget));
	g_return_if_fail(allocation != NULL);

	widget->allocation = *allocation;

	if (GTK_WIDGET_REALIZED(widget)) {
		gdk_window_move_resize(widget->window, allocation->x, allocation->y, allocation->width, allocation->height);
	}

	GtkXournal * xournal = GTK_XOURNAL(widget);

	xournal->layout->setSize(allocation->width, allocation->height);
}
Esempio n. 11
0
cairo_t * gtk_xournal_create_cairo_for(GtkWidget * widget, PageView * view) {
	g_return_val_if_fail(widget != NULL, FALSE);
	g_return_val_if_fail(GTK_IS_XOURNAL(widget), FALSE);

	GtkXournal * xournal = GTK_XOURNAL(widget);
	double zoom = xournal->view->getZoom();

	// TODO LOW PRIO: stroke draw to this cairo surface look a little different than rendererd to a cairo surface
	cairo_t * cr = gdk_cairo_create(GTK_WIDGET(widget)->window);
	int x = view->getX() - xournal->x;
	int y = view->getY() - xournal->y;
	cairo_translate(cr, x, y);
	cairo_scale(cr, zoom, zoom);

	return cr;
}
Esempio n. 12
0
static void gtk_xournal_destroy(GtkObject * object) {
	g_return_if_fail(object != NULL);
	g_return_if_fail(GTK_IS_XOURNAL(object));

	GtkXournal * xournal = GTK_XOURNAL(object);
	delete xournal->pagePositionCache;
	xournal->pagePositionCache = NULL;

	delete xournal->selection;
	xournal->selection = NULL;

	delete xournal->layout;
	xournal->layout = NULL;

	GtkXournalClass * klass = (GtkXournalClass *) gtk_type_class(gtk_widget_get_type());

	if (GTK_OBJECT_CLASS(klass)->destroy) {
		(*GTK_OBJECT_CLASS(klass)->destroy)(object);
	}
}
Esempio n. 13
0
static gboolean gtk_xournal_expose(GtkWidget* widget, GdkEventExpose* event)
{
	g_return_val_if_fail(widget != NULL, FALSE);
	g_return_val_if_fail(GTK_IS_XOURNAL(widget), FALSE);
	g_return_val_if_fail(event != NULL, FALSE);

	GtkXournal* xournal = GTK_XOURNAL(widget);

	gdk_threads_enter();
	cairo_t* cr = gdk_cairo_create(GTK_WIDGET(widget)->window);

	ArrayIterator<PageView*> it = xournal->view->pageViewIterator();

	GtkAllocation alloc = { 0 };
	gtk_widget_get_allocation(widget, &alloc);
	int lastVisibleX = alloc.width + xournal->x + 10;
	int lastVisibleY = alloc.height + xournal->y + 10; //+10 fix to draw the shadow

	int firstVisibleX = xournal->x - 10;
	int firstVisibleY = xournal->y - 10;

	while (it.hasNext())
	{
		PageView* pv = it.next();

		int px = pv->getX();
		int py = pv->getY();
		int pw = pv->getDisplayWidth();
		int ph = pv->getDisplayHeight();

		// not visible, its on the right side of the visible area
		if (px > lastVisibleX)
		{
			continue;
		}
		// not visible, its on the left side of the visible area
		if (px + pw < firstVisibleX)
		{
			continue;
		}
		// not visible, its on the bottom side of the visible area
		if (py > lastVisibleY)
		{
			continue;
		}
		// not visible, its on the top side of the visible area
		if (py + ph < firstVisibleY)
		{
			continue;
		}

		int x = px - xournal->x;
		int y = py - xournal->y;

		gtk_xournal_draw_shadow(xournal, cr, x, y, pw, ph, pv->isSelected());
		cairo_save(cr);
		cairo_translate(cr, x, y);

		GdkRectangle rect = event->area;
		rect.x -= x;
		rect.y -= y;

		pv->paintPage(cr, &rect);
		cairo_restore(cr);
	}

	if (xournal->selection)
	{
		double zoom = xournal->view->getZoom();

		int px = xournal->selection->getXOnView() * zoom;
		int py = xournal->selection->getYOnView() * zoom;
		//		int pw = xournal->selection->getWidth() * zoom;
		//		int ph = xournal->selection->getHeight() * zoom;

		// not visible, its on the right side of the visible area
		if (px > lastVisibleX)
		{
			printf("Warning: object on right side of visible area.\n");
		}
		else
			// not visible, its on the left side of the visible area

			// TODO LOW PRIO this is not working correct if the zoom is small, xournal->x is never smaller than 0
			//		if (px + pw < firstVisibleX) {
			//			printf("test2\n");
			//		} else
			// not visible, its on the bottom side of the visible area
			if (py > lastVisibleY)
			{
				printf("Warning: object below visible area.\n");
				//		} else
				//		// not visible, its on the top side of the visible area
				//		if (py + ph < firstVisibleY) {
				//			printf("test4 %i:: %i\n", py + ph, firstVisibleY);
			}
			else
			{
				Redrawable* red = xournal->selection->getView();
				cairo_translate(cr, red->getX() - xournal->x, red->getY() - xournal->y);

				xournal->selection->paint(cr, zoom);
			}
	}

	cairo_destroy(cr);
	gdk_threads_leave();

	return true;
}