Example #1
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;
}
Example #2
0
/**
 * Check which page should be selected
 */
void Layout::checkSelectedPage()
{

	GtkAllocation allocation = { 0 };
	gtk_widget_get_allocation(this->view->getWidget(), &allocation);

	int scrollY = this->scrollVertical->getValue();
	int scrollX = this->scrollHorizontal->getValue();

	Control* control = this->view->getControl();

	int viewHeight = allocation.height;
	int viewWidth = allocation.width;
	bool twoPages = control->getSettings()->isShowTwoPages();

	if (scrollY < 1)
	{
		if (twoPages && this->view->viewPagesLen > 1 &&
		    this->view->viewPages[1]->isSelected())
		{
			// page 2 already selected
		}
		else
		{
			control->firePageSelected(0);
		}
		return;
	}

	int mostPageNr = 0;
	double mostPagePercent = 0;

	// next four pages are not marked as invisible,
	// because usually you scroll forward

	for (int page = 0; page < this->view->viewPagesLen; page++)
	{
		PageView* p = this->view->viewPages[page];
		int y = p->getY();
		int x = p->getX();

		int pageHeight = p->getDisplayHeight();
		int pageWidth = p->getDisplayWidth();

		if (y > scrollY + viewHeight)
		{
			p->setIsVisible(false);
			for (; page < this->view->viewPagesLen; page++)
			{
				p = this->view->viewPages[page];
				p->setIsVisible(false);
			}

			break;
		}
		if (y + pageHeight >= scrollY)
		{
			int startY = 0;
			int endY = pageHeight;
			if (y <= scrollY)
			{
				startY = scrollY - y;
			}
			if (y + pageHeight > scrollY + viewHeight)
			{
				endY = pageHeight - ((y + pageHeight) - (scrollY + viewHeight));
			}

			int startX = 0;
			int endX = pageWidth;

			if (x <= scrollX)
			{
				startX = scrollX - x;
			}
			if (x + pageWidth > scrollX + viewWidth)
			{
				endX = pageWidth - ((x + pageWidth) - (scrollX + viewWidth));
			}


			double percent = ((double) (endY - startY)) / ((double) pageHeight);
			percent *= ((double) (endX - startX)) / ((double) pageWidth);

			if (percent > mostPagePercent)
			{
				mostPagePercent = percent;
				mostPageNr = page;
			}

			p->setIsVisible(true);
		}
		else
		{
			p->setIsVisible(false);
		}
	}

	if (twoPages && mostPageNr < this->view->viewPagesLen - 1)
	{
		int y1 = this->view->viewPages[mostPageNr]->getY();
		int y2 = this->view->viewPages[mostPageNr + 1]->getY();

		if (y1 != y2 || !this->view->viewPages[mostPageNr + 1]->isSelected())
		{
			// if the second page is selected DON'T select the first page.
			// Only select the first page if none is selected
			control->firePageSelected(mostPageNr);
		}
	}
	else
	{
		control->firePageSelected(mostPageNr);
	}
}