From b13140f726ee9c3c8fbcc870d673dbfa37ffb23e Mon Sep 17 00:00:00 2001 From: Jon Bergli Heier Date: Thu, 18 Feb 2010 00:46:12 +0100 Subject: Implemented basic zoom modes (best fit and normal) This lets the user switch between best fit and normal zoom modes. Zooming in and out is not yet implemented. --- window_main.c | 140 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 132 insertions(+), 8 deletions(-) (limited to 'window_main.c') diff --git a/window_main.c b/window_main.c index fe2c68d..ff5200f 100644 --- a/window_main.c +++ b/window_main.c @@ -11,19 +11,30 @@ #include "window_tag.h" #include "preload.h" +enum zoom_mode_t { + ZOOM_BESTFIT, + ZOOM_NORMAL, + ZOOM_CUSTOM, +}; + struct wallpaper_t *cur_wall = NULL; GdkPixbuf *orig_pixbuf = NULL; gint last_width = 0, last_height = 0, hpane_last_pos = 0; guint hpane_source_id = 0; +gboolean layout_dragging = FALSE; +gdouble layout_dragx, layout_dragy; + +enum zoom_mode_t zoom_mode = ZOOM_BESTFIT; GtkWindow *window; GtkImage *image = NULL; GtkWidget *layout = NULL; GtkStatusbar *statusbar; GtkIconView *thumbview; -GtkWidget *window_hpane, *window_vpane, *foldtree, *tagview; +GtkWidget *window_hpane, *window_vpane, *foldtree, *tagview, *view_toolbar, + *zoom_toolbar, *zoom_bestfit, *zoom_normal; GThread *wallpaper_thread = NULL; @@ -109,7 +120,11 @@ static void set_resize_msg(gdouble scale) { gchar *msg; gtk_statusbar_pop(statusbar, image_context); - msg = g_strdup_printf("%s (%d %%)", cur_wall_msg, (gint)(scale * 100.0)); + if(scale == 0) { + msg = g_strdup(cur_wall_msg); + } else { + msg = g_strdup_printf("%s (%d %%)", cur_wall_msg, (gint)(scale * 100.0)); + } gtk_statusbar_push(statusbar, image_context, msg); g_free(msg); } @@ -125,6 +140,33 @@ static void set_image_pixbuf_resized(GdkPixbuf *pb, gint win_width, gint win_hei gtk_layout_set_size(GTK_LAYOUT(layout), win_width, win_height); } +static void layout_center(gint width, gint height) { + GtkAdjustment *hadj, *vadj; + gdouble hupper, hpagesize, vupper, vpagesize; + + hadj = gtk_layout_get_hadjustment(GTK_LAYOUT(layout)); + vadj = gtk_layout_get_vadjustment(GTK_LAYOUT(layout)); + + hupper = gtk_adjustment_get_upper(GTK_ADJUSTMENT(hadj)); + hpagesize = gtk_adjustment_get_page_size(GTK_ADJUSTMENT(hadj)); + vupper = gtk_adjustment_get_upper(GTK_ADJUSTMENT(vadj)); + vpagesize = gtk_adjustment_get_page_size(GTK_ADJUSTMENT(vadj)); + + gtk_adjustment_set_value(GTK_ADJUSTMENT(hadj), hupper / 2 - hpagesize / 2); + gtk_adjustment_set_value(GTK_ADJUSTMENT(vadj), vupper / 2 - vpagesize / 2); +} + +static void set_image_pixbuf_normal(GdkPixbuf *pb, gint win_width, gint win_height, gint width, gint height) { + set_resize_msg(0.0); + + gtk_widget_set_size_request(GTK_WIDGET(image), width, height); + gtk_widget_set_uposition(GTK_WIDGET(image), (width < win_width ? win_width / 2 - width / 2 : 0), + (height < win_height ? win_height / 2 - height / 2 : 0)); + gtk_image_set_from_pixbuf(image, pb); + gtk_layout_set_size(GTK_LAYOUT(layout), width, height); + layout_center(width, height); +} + static void set_image_pixbuf() { GdkWindow *window; GdkPixbuf *pb; @@ -137,12 +179,16 @@ static void set_image_pixbuf() { window = gtk_widget_get_window(layout); gdk_drawable_get_size(window, &win_width, &win_height); - pb = resize_pixbuf(orig_pixbuf, win_width, win_height, &width, &height, &ratio); - if(!pb) - return; + if(zoom_mode == ZOOM_BESTFIT) { + pb = resize_pixbuf(orig_pixbuf, win_width, win_height, &width, &height, &ratio); + if(!pb) + return; - set_image_pixbuf_resized(pb, win_width, win_height, width, height, ratio); - g_object_unref(pb); + set_image_pixbuf_resized(pb, win_width, win_height, width, height, ratio); + g_object_unref(pb); + } else if(zoom_mode == ZOOM_NORMAL || zoom_mode == ZOOM_CUSTOM) { + set_image_pixbuf_normal(orig_pixbuf, win_width, win_height, gdk_pixbuf_get_width(orig_pixbuf), gdk_pixbuf_get_height(orig_pixbuf)); + } } void on_window_size_allocate(GtkWidget *widget, GtkAllocation *allocation, gpointer user_data) { @@ -247,7 +293,11 @@ static void load_pixbuf(const gchar *filepath) { window = gtk_widget_get_window(layout); gdk_drawable_get_size(window, &win_width, &win_height); - set_image_pixbuf_resized(pt->pb, win_width, win_height, pt->width, pt->height, pt->ratio); + if(zoom_mode == ZOOM_BESTFIT) { + set_image_pixbuf_resized(pt->pb, win_width, win_height, pt->width, pt->height, pt->ratio); + } else { + set_image_pixbuf_normal(pt->pb_orig, win_width, win_height, gdk_pixbuf_get_width(pt->pb_orig), gdk_pixbuf_get_height(pt->pb_orig)); + } } else set_image_pixbuf(); } @@ -855,6 +905,74 @@ gboolean on_left_pages_switch_page(GtkNotebook *notebook, GtkNotebookTab page, g return TRUE; } +void on_view_activate(GtkMenuItem *menuitem, gpointer user_data) { + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(view_toolbar), gtk_widget_get_visible(zoom_toolbar)); +} + +void on_zoom_mode_toggled(GtkToggleToolButton *toolbutton, gpointer user_data) { + if(gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(zoom_bestfit))) { + zoom_mode = ZOOM_BESTFIT; + } else if(gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(zoom_normal))) { + zoom_mode = ZOOM_NORMAL; + } + + if(zoom_mode != ZOOM_CUSTOM) { + set_image_pixbuf(); + } +} + +gboolean on_layout_button_press_event(GtkWindow *widget, GdkEventButton *event, gpointer user_data) { + GtkAdjustment *hadj, *vadj; + + if(event->button == 1 && zoom_mode != ZOOM_BESTFIT) { + hadj = gtk_layout_get_hadjustment(GTK_LAYOUT(layout)); + vadj = gtk_layout_get_vadjustment(GTK_LAYOUT(layout)); + + layout_dragging = TRUE; + layout_dragx = event->x; + layout_dragy = event->y; + } + + return FALSE; +} + +gboolean on_layout_button_release_event(GtkWindow *widget, GdkEventButton *event, gpointer user_data) { + if(event->button == 1) { + layout_dragging = FALSE; + } + + return FALSE; +} + +gboolean on_layout_motion_notify_event(GtkWidget *widget, GdkEventMotion *event, gpointer user_data) { + GtkAdjustment *hadj, *vadj; + gdouble adjx, adjy; + gdouble hupper, hpagesize, vupper, vpagesize; + + if(layout_dragging) { + hadj = gtk_layout_get_hadjustment(GTK_LAYOUT(layout)); + vadj = gtk_layout_get_vadjustment(GTK_LAYOUT(layout)); + + hupper = gtk_adjustment_get_upper(GTK_ADJUSTMENT(hadj)); + hpagesize = gtk_adjustment_get_page_size(GTK_ADJUSTMENT(hadj)); + vupper = gtk_adjustment_get_upper(GTK_ADJUSTMENT(vadj)); + vpagesize = gtk_adjustment_get_page_size(GTK_ADJUSTMENT(vadj)); + + adjx = gtk_adjustment_get_value(GTK_ADJUSTMENT(hadj)) + (layout_dragx - event->x); + adjy = gtk_adjustment_get_value(GTK_ADJUSTMENT(vadj)) + (layout_dragy - event->y); + + if(adjx > hupper - hpagesize) + adjx = hupper - hpagesize; + if(adjy > vupper - vpagesize) + adjy = vupper - vpagesize; + + gtk_adjustment_set_value(GTK_ADJUSTMENT(hadj), adjx); + gtk_adjustment_set_value(GTK_ADJUSTMENT(vadj), adjy); + } + + return FALSE; +} + static void save_window() { gint width, height; @@ -924,6 +1042,7 @@ int gui_main(int argc, char **argv) { layout = GTK_WIDGET(gtk_builder_get_object(builder, "layout")); if(gdk_color_parse("#000", &color)) gtk_widget_modify_bg(GTK_WIDGET(layout), GTK_STATE_NORMAL, &color); + gtk_widget_add_events(layout, GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK); window_hpane = GTK_WIDGET(gtk_builder_get_object(builder, "window_hpane")); g_signal_connect(window_hpane, "notify::position", G_CALLBACK(on_window_hpane_resized), window_hpane); @@ -932,6 +1051,11 @@ int gui_main(int argc, char **argv) { statusbar = GTK_STATUSBAR(gtk_builder_get_object(builder, "statusbar")); image_context = gtk_statusbar_get_context_id(GTK_STATUSBAR(statusbar), "Image display"); + view_toolbar = GTK_WIDGET(gtk_builder_get_object(builder, "view_toolbar")); + zoom_toolbar = GTK_WIDGET(gtk_builder_get_object(builder, "zoom_toolbar")); + zoom_bestfit = GTK_WIDGET(gtk_builder_get_object(builder, "zoom_bestfit")); + zoom_normal = GTK_WIDGET(gtk_builder_get_object(builder, "zoom_normal")); + gtk_builder_connect_signals(builder, NULL); g_object_unref(G_OBJECT(builder)); -- cgit v1.2.3