/** * uni_image_view_set_pixbuf: * @view: A #UniImageView. * @pixbuf: The pixbuf to display. * @reset_fit: Whether to reset fitting or not. * * Sets the @pixbuf to display, or %NULL to not display any pixbuf. * Normally, @reset_fit should be %TRUE which enables fitting. Which * means that, initially, the whole pixbuf will be shown. * * Sometimes, the fit mode should not be reset. For example, if * UniImageView is showing an animation, it would be bad to reset the * fit mode for each new frame. The parameter should then be %FALSE * which leaves the fit mode of the view untouched. * * This method should not be used if merely the contents of the pixbuf * has changed. See uni_image_view_damage_pixels() for that. * * If @reset_fit is %TRUE, the ::zoom-changed signal is emitted, * otherwise not. The ::pixbuf-changed signal is also emitted. * * The default pixbuf is %NULL. **/ void uni_image_view_set_pixbuf (UniImageView * view, GdkPixbuf * pixbuf, gboolean reset_fit) { if (view->pixbuf != pixbuf) { if (view->pixbuf) g_object_unref (view->pixbuf); view->pixbuf = pixbuf; if (view->pixbuf) g_object_ref (pixbuf); } if (reset_fit) uni_image_view_set_fitting (view, UNI_FITTING_NORMAL); else { /* If the size of the pixbuf changes, the offset might point to pixels outside it so we use uni_image_view_scroll_to() to make it valid again. And if the size is different, naturally we must also update the adjustments. */ uni_image_view_scroll_to (view, view->offset_x, view->offset_y, FALSE, FALSE); uni_image_view_update_adjustments (view); gtk_widget_queue_draw (GTK_WIDGET (view)); } g_signal_emit (G_OBJECT (view), uni_image_view_signals[PIXBUF_CHANGED], 0); uni_dragger_pixbuf_changed (UNI_DRAGGER(view->tool), reset_fit, NULL); }
static int uni_image_view_motion_notify (GtkWidget * widget, GdkEventMotion * ev) { UniImageView *view = UNI_IMAGE_VIEW (widget); if (view->is_rendering) return FALSE; return uni_dragger_motion_notify (UNI_DRAGGER(view->tool), ev); }
static void uni_dragger_finalize (GObject * object) { UniDragger *dragger = UNI_DRAGGER (object); uni_pixbuf_draw_cache_free (dragger->cache); /* Chain up */ G_OBJECT_CLASS (uni_dragger_parent_class)->finalize (object); }
static int uni_image_view_button_press (GtkWidget * widget, GdkEventButton * ev) { gtk_widget_grab_focus(widget); UniImageView *view = UNI_IMAGE_VIEW (widget); VnrWindow *vnr_win = VNR_WINDOW(gtk_widget_get_toplevel(widget)); g_assert(gtk_widget_is_toplevel(GTK_WIDGET(vnr_win))); if(ev->type == GDK_2BUTTON_PRESS && ev->button == 1 && vnr_win->prefs->behavior_click == VNR_PREFS_CLICK_FULLSCREEN) { vnr_window_toggle_fullscreen(vnr_win); return 1; } else if(ev->type == GDK_2BUTTON_PRESS && ev->button == 1 && vnr_win->prefs->behavior_click == VNR_PREFS_CLICK_NEXT) { int width; gdk_drawable_get_size(GDK_DRAWABLE(widget->window), &width, NULL); if(ev->x/width < 0.5) vnr_window_prev(vnr_win); else vnr_window_next(vnr_win, TRUE); return 1; } else if (ev->type == GDK_BUTTON_PRESS && ev->button == 1) { return uni_dragger_button_press (UNI_DRAGGER(view->tool), ev); } else if (ev->type == GDK_2BUTTON_PRESS && ev->button == 1) { if (view->fitting == UNI_FITTING_FULL || (view->fitting == UNI_FITTING_NORMAL && view->zoom != 1.0)) uni_image_view_set_zoom_with_center (view, 1., ev->x, ev->y, FALSE); else uni_image_view_set_fitting (view, UNI_FITTING_FULL); return 1; } else if(ev->type == GDK_BUTTON_PRESS && ev->button == 3) { gtk_menu_popup(GTK_MENU(VNR_WINDOW(gtk_widget_get_toplevel (widget))->popup_menu), NULL, NULL, NULL, NULL, ev->button, gtk_get_current_event_time()); } else if(ev->type == GDK_BUTTON_PRESS && ev->button == 8) { vnr_window_prev(vnr_win); } else if(ev->type == GDK_BUTTON_PRESS && ev->button == 9) { vnr_window_next(vnr_win, TRUE); } return 0; }
/** * uni_dragger_new: * @view: a #UniImageView * @returns: a new #UniDragger * * Creates and returns a new dragger tool. **/ UniDragger * uni_dragger_new (GtkWidget * view) { g_return_val_if_fail (view != NULL, NULL); UniDragger *data; data = UNI_DRAGGER (g_object_new (UNI_TYPE_DRAGGER, "view", view, NULL)); return data; }
/** * uni_image_view_repaint_area: * @paint_rect: The rectangle on the widget that needs to be redrawn. * * Redraws the porition of the widget defined by @paint_rect. **/ static int uni_image_view_repaint_area (UniImageView * view, GdkRectangle * paint_rect) { if (view->is_rendering) return FALSE; // Do not draw zero size rectangles. if (!paint_rect->width || !paint_rect->height) return FALSE; view->is_rendering = TRUE; // Image area is the area on the widget occupied by the pixbuf. GdkRectangle image_area; Size alloc = uni_image_view_get_allocated_size (view); uni_image_view_get_draw_rect (view, &image_area); if (image_area.x > 0 || image_area.y > 0 || image_area.width < alloc.width || image_area.height < alloc.height) { uni_image_view_draw_background (view, &image_area, alloc); } GtkWidget *widget = GTK_WIDGET (view); // Paint area is the area on the widget that should be redrawn. GdkRectangle paint_area; gboolean intersects = gdk_rectangle_intersect (&image_area, paint_rect, &paint_area); if (intersects && view->pixbuf) { int src_x = (int) ((view->offset_x + (gdouble) paint_area.x - (gdouble) image_area.x) + 0.5); int src_y = (int) ((view->offset_y + (gdouble) paint_area.y - (gdouble) image_area.y) + 0.5); UniPixbufDrawOpts opts = { view->zoom, (GdkRectangle) { src_x, src_y, paint_area.width, paint_area.height }, paint_area.x, paint_area.y, view->interp, view->pixbuf }; uni_dragger_paint_image (UNI_DRAGGER(view->tool), &opts, widget->window); } view->is_rendering = FALSE; return TRUE; }
static void uni_dragger_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { UniDragger *dragger = UNI_DRAGGER (object); if (prop_id == PROP_IMAGE_VIEW) dragger->view = g_value_get_object (value); else G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); }
static int uni_image_view_button_release (GtkWidget * widget, GdkEventButton * ev) { UniImageView *view = UNI_IMAGE_VIEW (widget); return uni_dragger_button_release (UNI_DRAGGER(view->tool), ev); }