From b6b63a3c51eab072483ac0c7ad07f107bb790788 Mon Sep 17 00:00:00 2001 From: Jon Bergli Heier Date: Tue, 9 Mar 2010 20:31:26 +0100 Subject: Implemented zooming with scrollwheel. This works by holding control down while scrolling up or down. Horizontal scrolling will now also work by holding shift down. --- wallpapers.c | 2 +- wallpapers.h | 1 + walls.ui | 2 ++ window_main.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++----------- 4 files changed, 56 insertions(+), 12 deletions(-) diff --git a/wallpapers.c b/wallpapers.c index 0d37f5e..dbfb8a1 100644 --- a/wallpapers.c +++ b/wallpapers.c @@ -235,6 +235,6 @@ GdkPixbuf *zoom_pixbuf(GdkPixbuf *orig, gdouble zoom) { height = img_height * zoom; pb = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, width, height); gdk_pixbuf_scale(orig, pb, 0, 0, width, height, 0, 0, - (gdouble)width / (gdouble)img_width, (gdouble)height / (gdouble)img_height, GDK_INTERP_BILINEAR); + (gdouble)width / (gdouble)img_width, (gdouble)height / (gdouble)img_height, GDK_INTERP_NEAREST); return pb; } diff --git a/wallpapers.h b/wallpapers.h index d8d832e..fc575b3 100644 --- a/wallpapers.h +++ b/wallpapers.h @@ -9,5 +9,6 @@ gboolean wallpapers_add_dir(const gchar*, sqlite_uint64, GtkStatusbar*, gboolean); void wallpapers_remove_missing(struct directory_t*, GtkStatusbar*, gboolean); GdkPixbuf *resize_pixbuf(GdkPixbuf*, gint, gint, gint*, gint*, gdouble*); +GdkPixbuf *zoom_pixbuf(GdkPixbuf*, gdouble); #endif diff --git a/walls.ui b/walls.ui index cb6f3bd..a355977 100644 --- a/walls.ui +++ b/walls.ui @@ -271,9 +271,11 @@ True + GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK | GDK_SCROLL_MASK + True diff --git a/window_main.c b/window_main.c index bd1de4f..ca3d8dc 100644 --- a/window_main.c +++ b/window_main.c @@ -14,7 +14,8 @@ enum zoom_mode_t { ZOOM_BESTFIT, ZOOM_NORMAL, - ZOOM_CUSTOM, + ZOOM_BESTFIT_CUSTOM, + ZOOM_NORMAL_CUSTOM, }; struct wallpaper_t *cur_wall = NULL; @@ -117,14 +118,14 @@ inline static void tagview_init(GtkTreeView *tagview) { tagview_create_model(tagview); } -static void set_resize_msg(gdouble scale) { +static void set_resize_msg() { gchar *msg; gtk_statusbar_pop(statusbar, image_context); - if(scale == 0) { + if(zoom_factor == 0) { msg = g_strdup(cur_wall_msg); } else { - msg = g_strdup_printf("%s (%d %%)", cur_wall_msg, (gint)(scale * 100.0)); + msg = g_strdup_printf("%s (%d %%)", cur_wall_msg, (gint)(zoom_factor * 100.0)); } gtk_statusbar_push(statusbar, image_context, msg); g_free(msg); @@ -158,7 +159,7 @@ static void layout_center(gint width, gint height) { } static void set_image_pixbuf_normal(GdkPixbuf *pb, gint win_width, gint win_height, gint width, gint height) { - set_resize_msg(0.0); + set_resize_msg(); 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), @@ -185,11 +186,14 @@ static void set_image_pixbuf() { if(!pb) return; + zoom_factor = ratio; + set_image_pixbuf_resized(pb, win_width, win_height, width, height, ratio); g_object_unref(pb); } else if(zoom_mode == ZOOM_NORMAL) { set_image_pixbuf_normal(orig_pixbuf, win_width, win_height, gdk_pixbuf_get_width(orig_pixbuf), gdk_pixbuf_get_height(orig_pixbuf)); - } else if(zoom_mode == ZOOM_CUSTOM) { + zoom_factor = 1.; + } else if(zoom_mode >= ZOOM_BESTFIT_CUSTOM) { pb = zoom_pixbuf(orig_pixbuf, zoom_factor); if(!pb) return; @@ -308,8 +312,10 @@ static void load_pixbuf(const gchar *filepath) { gdk_drawable_get_size(window, &win_width, &win_height); if(zoom_mode == ZOOM_BESTFIT) { + zoom_factor = pt->ratio; set_image_pixbuf_resized(pt->pb, win_width, win_height, pt->width, pt->height, pt->ratio); } else { + zoom_factor = 1.0; 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 @@ -403,6 +409,10 @@ void on_thumbview_selection_changed(GtkIconView *iconview, gpointer user_data) { list = gtk_icon_view_get_selected_items(iconview); if(list) { if(g_list_length(list) == 1) { + if(zoom_mode == ZOOM_BESTFIT_CUSTOM) + zoom_mode = ZOOM_BESTFIT; + else if(zoom_mode == ZOOM_NORMAL_CUSTOM) + zoom_mode = ZOOM_NORMAL; path = g_list_nth_data(list, 0); model = gtk_icon_view_get_model(iconview); gtk_tree_model_get_iter(model, &iter, path); @@ -930,19 +940,25 @@ void on_zoom_mode_toggled(GtkToggleToolButton *toolbutton, gpointer user_data) { zoom_mode = ZOOM_NORMAL; } - if(zoom_mode != ZOOM_CUSTOM) { + if(zoom_mode == ZOOM_BESTFIT || zoom_mode == ZOOM_NORMAL) { set_image_pixbuf(); } } void on_zoom_in_clicked(GtkToolButton *toolbutton, gpointer user_data) { - zoom_mode = ZOOM_CUSTOM; + if(zoom_mode == ZOOM_BESTFIT) + zoom_mode = ZOOM_BESTFIT_CUSTOM; + else if(zoom_mode == ZOOM_NORMAL) + zoom_mode = ZOOM_NORMAL_CUSTOM; zoom_factor *= 1.25; set_image_pixbuf(); } void on_zoom_out_clicked(GtkToolButton *toolbutton, gpointer user_data) { - zoom_mode = ZOOM_CUSTOM; + if(zoom_mode == ZOOM_BESTFIT) + zoom_mode = ZOOM_BESTFIT_CUSTOM; + else if(zoom_mode == ZOOM_NORMAL) + zoom_mode = ZOOM_NORMAL_CUSTOM; zoom_factor *= .80; set_image_pixbuf(); } @@ -970,12 +986,38 @@ gboolean on_layout_button_release_event(GtkWindow *widget, GdkEventButton *event return FALSE; } +gboolean on_layout_scroll_event(GtkWidget *widget, GdkEventScroll *event, gpointer user_data) { + GdkModifierType mask; + gint x, y; + + if(event->type == GDK_SCROLL) { + gdk_window_get_pointer(event->window, &x, &y, &mask); + if(mask & GDK_CONTROL_MASK) { + gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(zoom_bestfit), FALSE); + gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(zoom_normal), FALSE); + if(zoom_mode == ZOOM_BESTFIT) + zoom_mode = ZOOM_BESTFIT_CUSTOM; + else if(zoom_mode == ZOOM_NORMAL) + zoom_mode = ZOOM_NORMAL_CUSTOM; + zoom_factor *= (event->direction == GDK_SCROLL_UP ? 1.25 : .80); + set_image_pixbuf(); + } + if(mask & GDK_SHIFT_MASK) { + if(event->direction == GDK_SCROLL_UP) + event->direction = GDK_SCROLL_LEFT; + else if(event->direction == GDK_SCROLL_DOWN) + event->direction = GDK_SCROLL_RIGHT; + } + } + 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) { + if(layout_dragging && event->type == GDK_MOTION_NOTIFY) { hadj = gtk_layout_get_hadjustment(GTK_LAYOUT(layout)); vadj = gtk_layout_get_vadjustment(GTK_LAYOUT(layout)); @@ -1068,7 +1110,6 @@ 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); -- cgit v1.2.3