#include #define TIMEOUT 20 #define ZOOM_FACTOR 0.1 GtkWidget *window; GtkWidget *image; GdkPixbuf *pixbuf; GdkPixbuf *curr_pixbuf; int pixbuf_width, pixbuf_height; double aspect_ratio; double curr_zoom = 1.0; void zoom(int type) { if (type == 0) { if (curr_zoom == 1.0) return; curr_zoom = (double)1.0; } else if (type < 0) { if (curr_zoom < 0.2) return; curr_zoom -= (double)ZOOM_FACTOR; } else if (type > 0) { if (curr_zoom > 2) return; curr_zoom += (double)ZOOM_FACTOR; } if (curr_pixbuf != NULL) g_object_unref(curr_pixbuf); curr_pixbuf = gdk_pixbuf_scale_simple( GDK_PIXBUF(pixbuf), pixbuf_width * curr_zoom, pixbuf_height * curr_zoom, GDK_INTERP_BILINEAR); gtk_image_set_from_pixbuf(GTK_IMAGE(image), GDK_PIXBUF(curr_pixbuf)); } static gboolean key_press(GtkWindow *window, GdkEvent *event, gpointer data) { switch (event->key.keyval) { case GDK_KEY_q: g_application_quit(G_APPLICATION( gtk_window_get_application(GTK_WINDOW(window)))); return FALSE; case GDK_KEY_plus: case GDK_KEY_ScrollUp: zoom(1); return FALSE; case GDK_KEY_minus: case GDK_KEY_ScrollDown: zoom(-1); return FALSE; case GDK_KEY_equal: case GDK_KEY_ScrollClick: zoom(0); return FALSE; default: return TRUE; } } gboolean scroll_callback(GtkWindow *window, GdkEvent *event, gpointer data) { GdkModifierType state; gdk_event_get_state(event, &state); if (state & GDK_CONTROL_MASK && event->scroll.direction == GDK_SCROLL_UP) { zoom(1); return FALSE; } else if (state & GDK_CONTROL_MASK && event->scroll.direction == GDK_SCROLL_DOWN) { zoom(-1); return FALSE; } return TRUE; } gboolean resize_done(gpointer data) { guint *id = data; *id = 0; gint win_width, win_height; gint new_pixbuf_width, new_pixbuf_height; gtk_window_get_size(GTK_WINDOW(window), &win_width, &win_height); if (win_width < pixbuf_width && win_height > pixbuf_height) { new_pixbuf_width = win_width; new_pixbuf_height = (double)new_pixbuf_width / aspect_ratio; } else if (win_width > pixbuf_width && win_height < pixbuf_height) { new_pixbuf_height = win_height; new_pixbuf_width = (double)new_pixbuf_height * aspect_ratio; } else if (win_width < pixbuf_width && win_height < pixbuf_height) { if (((double)win_width / (double)win_height) > aspect_ratio) { new_pixbuf_height = win_height; new_pixbuf_width = ((double)new_pixbuf_height * aspect_ratio); } else { new_pixbuf_width = win_width; new_pixbuf_height = (double)new_pixbuf_width / aspect_ratio; } } else { new_pixbuf_width = pixbuf_width; new_pixbuf_height = pixbuf_height; } if (curr_pixbuf != NULL) g_object_unref(curr_pixbuf); curr_pixbuf = gdk_pixbuf_scale_simple(GDK_PIXBUF(pixbuf), new_pixbuf_width, new_pixbuf_height, GDK_INTERP_BILINEAR); gtk_image_set_from_pixbuf(GTK_IMAGE(image), GDK_PIXBUF(curr_pixbuf)); return FALSE; } gboolean configure_callback(GtkWindow *window, GdkEvent *event, gpointer data) { static guint id = 0; if (id) g_source_remove(id); id = g_timeout_add(TIMEOUT, resize_done, &id); return FALSE; } static void activate(GtkApplication *app, gpointer user_data) { GError *error = NULL; window = gtk_application_window_new(app); gtk_window_set_title(GTK_WINDOW(window), "qwe"); gtk_window_set_default_size(GTK_WINDOW(window), 300, 300); /* g_signal_connect(G_OBJECT(window), "configure-event", */ /* G_CALLBACK(configure_callback), NULL); */ g_signal_connect(G_OBJECT(window), "key-press-event", G_CALLBACK(key_press), NULL); gtk_widget_add_events(GTK_WIDGET(window), GDK_SCROLL_MASK); g_signal_connect(G_OBJECT(window), "scroll-event", G_CALLBACK(scroll_callback), NULL); pixbuf = gdk_pixbuf_new_from_file( "/home/nirav/Downloads/Saved Pictures/bash help shortcuts.png", &error); if (error) { g_warning("gdk_pixbuf_new_from_file() failed with error: %s\n", error->message); g_clear_error(&error); return; } image = gtk_image_new_from_pixbuf(GDK_PIXBUF(pixbuf)); pixbuf_width = gdk_pixbuf_get_width(GDK_PIXBUF(pixbuf)); pixbuf_height = gdk_pixbuf_get_height(GDK_PIXBUF(pixbuf)); aspect_ratio = (double)pixbuf_width / (double)pixbuf_height; GtkWidget *scrolled_window = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_container_add(GTK_CONTAINER(scrolled_window), GTK_WIDGET(image)); gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(scrolled_window)); gtk_widget_show_all(GTK_WIDGET(window)); } int main(int argc, char *argv[]) { GtkApplication *app; int status; app = gtk_application_new("org.gtk.qwe", G_APPLICATION_FLAGS_NONE); g_signal_connect(app, "activate", G_CALLBACK(activate), NULL); status = g_application_run(G_APPLICATION(app), argc, argv); g_object_unref(app); return status; }