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; }
/** * 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); } }