summaryrefslogtreecommitdiff
path: root/window_main.c
diff options
context:
space:
mode:
authorJon Bergli Heier <snakebite@jvnv.net>2010-02-18 00:46:12 +0100
committerJon Bergli Heier <snakebite@jvnv.net>2010-02-18 00:46:12 +0100
commitb13140f726ee9c3c8fbcc870d673dbfa37ffb23e (patch)
tree8b9245ba5bb4aeb3d0454201e75b1435db05ebff /window_main.c
parent956ac944c435a0a116fae2fe664b0af7210802be (diff)
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.
Diffstat (limited to 'window_main.c')
-rw-r--r--window_main.c140
1 files changed, 132 insertions, 8 deletions
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));