diff options
author | nirav <nirav@teisuu.com> | 2018-09-05 00:35:24 +0530 |
---|---|---|
committer | Dandelion <nirav@teisuu.com> | 2018-09-07 21:16:09 +0530 |
commit | 02f7a54e67260ee7995c6cd9bf40ae784b60203d (patch) | |
tree | d8bb663f273f4adf1d737ea39f19e5154c9ac07c | |
parent | 28e58ba0dbf30a4a28465f460c67e1c4337bd3a4 (diff) | |
download | im-02f7a54e67260ee7995c6cd9bf40ae784b60203d.tar.gz im-02f7a54e67260ee7995c6cd9bf40ae784b60203d.zip |
Added image panning support, refactoring
-rw-r--r-- | file.c | 6 | ||||
-rw-r--r-- | image.c | 12 | ||||
-rw-r--r-- | image.h | 4 | ||||
-rw-r--r-- | input.c | 146 | ||||
-rw-r--r-- | input.h | 13 | ||||
-rw-r--r-- | main.c | 161 | ||||
-rw-r--r-- | makefile | 2 | ||||
-rw-r--r-- | window.c | 98 | ||||
-rw-r--r-- | window.h | 11 |
9 files changed, 291 insertions, 162 deletions
@@ -1,5 +1,6 @@ #include "file.h" #include <dirent.h> +#include <gtk-3.0/gtk/gtk.h> #include <libgen.h> #include <stdio.h> #include <stdlib.h> @@ -27,7 +28,6 @@ int scan(const char *file_name) { struct dirent **name_list; char *dir_name = dirname(strdup(file_name)); - size_t dir_name_len = strlen(dir_name); file_list_count = scandir(dir_name, &name_list, image_filter, alphasort); if (file_list_count < 0) { return -1; @@ -39,9 +39,7 @@ int scan(const char *file_name) while (i < file_list_count) { if (!strcmp(file_basename, name_list[i]->d_name)) curr_file_index = i; - file_list[i] = malloc( - (strlen(name_list[i]->d_name) + dir_name_len + 2) * sizeof(char *)); - sprintf(file_list[i], "%s/%s", dir_name, name_list[i]->d_name); + file_list[i] = g_build_filename(dir_name, name_list[i]->d_name, NULL); free(name_list[i]); i++; } @@ -1,4 +1,5 @@ #include "image.h" +#include "window.h" #include <gtk-3.0/gtk/gtk.h> GtkWidget *new_image() @@ -7,9 +8,8 @@ GtkWidget *new_image() return image; } -int load_image(char *file_name, int win_width, int win_height) +int load_image(char *file_name) { - printf("loading: %s\n", file_name); GError *error = NULL; if (pixbuf != NULL) g_object_unref(pixbuf); @@ -21,7 +21,7 @@ int load_image(char *file_name, int win_width, int win_height) gdk_pixbuf_get_height(GDK_PIXBUF(pixbuf)); aspect_ratio = (double)pixbuf_width / (double)pixbuf_height; curr_zoom = 1.0; - fit_image(win_width, win_height); + fit_image(); return 1; } @@ -37,8 +37,11 @@ void update_pixbuf() gtk_image_set_from_pixbuf(GTK_IMAGE(image), GDK_PIXBUF(curr_pixbuf)); } -void fit_image(int win_width, int win_height) +void fit_image() { + gint win_width, win_height; + get_curr_win_size(&win_width, &win_height); + curr_scale_mod = fit; if (pixbuf == NULL || win_width < 1 || win_height < 1) return; if (win_width < pixbuf_width && win_height > pixbuf_height) { @@ -69,6 +72,7 @@ void fit_image(int win_width, int win_height) void zoom(int type) { + curr_scale_mod = zoomed; if (pixbuf == NULL) return; if (type == 0) { @@ -18,8 +18,8 @@ double aspect_ratio; double curr_zoom; GtkWidget *new_image(); -int load_image(char *file_name, int win_width, int win_height); -void fit_image(int win_width, int win_height); +int load_image(char *file_name); +void fit_image(); void zoom(int type); void print_supported_formats(); @@ -0,0 +1,146 @@ +#include "input.h" +#include "file.h" +#include "image.h" +#include "window.h" +#include <gtk-3.0/gtk/gtk.h> + +#define TIMEOUT 20 + +int grabbed = 0; +gdouble start_x, start_y; + +void next() +{ + char *name; + if ((name = get_next_file()) != NULL) + load_image(name); +} + +void prev() +{ + char *name; + if ((name = get_prev_file()) != NULL) + load_image(name); +} + +void first() +{ + char *name; + if ((name = get_first_file()) != NULL) + load_image(name); +} + +void last() +{ + char *name; + if ((name = get_last_file()) != NULL) + load_image(name); +} + +void handle_key_press(GdkEventKey key) +{ + switch (key.keyval) { + case GDK_KEY_q: + quit(); + case GDK_KEY_w: + fit_image(); + break; + case GDK_KEY_plus: + case GDK_KEY_KP_Add: + zoom(1); + break; + case GDK_KEY_minus: + case GDK_KEY_KP_Subtract: + zoom(-1); + break; + case GDK_KEY_equal: + zoom(0); + break; + case GDK_KEY_n: + case GDK_KEY_j: + case GDK_KEY_Right: + next(); + break; + case GDK_KEY_p: + case GDK_KEY_k: + case GDK_KEY_Left: + prev(); + break; + case GDK_KEY_g: + case GDK_KEY_Home: + first(); + break; + case GDK_KEY_G: + case GDK_KEY_End: + last(); + break; + default: + break; + } +} + +void handle_button_press(GdkEvent *event) +{ + grabbed = 1; + start_x = event->motion.x; + start_y = event->motion.y; +} + +void handle_button_release() +{ + grabbed = 0; +} + +void handle_mouse_move(gdouble x, gdouble y) +{ + if (grabbed) { + gdouble diff_x = start_x - x; + gdouble diff_y = start_y - y; + start_x = x; + start_y = y; + scroll_window(diff_x, diff_y); + } +} + +void handle_scroll(GdkEvent *event) +{ + GdkModifierType state; + gdk_event_get_state(event, &state); + + switch (event->scroll.direction) { + case GDK_SCROLL_UP: + if (state & GDK_CONTROL_MASK) { + zoom(1); + } else { + prev(); + } + break; + case GDK_SCROLL_DOWN: + if (state & GDK_CONTROL_MASK) { + zoom(-1); + } else { + next(); + } + break; + default: + break; + } +} + +gboolean resize_done(gpointer data) +{ + guint *id = data; + *id = 0; + fit_image(); + return FALSE; +} + +void handle_resize() +{ + if (curr_scale_mod != fit) + return; + static guint id = 0; + if (id) + g_source_remove(id); + id = g_timeout_add(TIMEOUT, resize_done, &id); +} @@ -0,0 +1,13 @@ +#ifndef __INPUT_H +#define __INPUT_H + +#include <gtk-3.0/gtk/gtk.h> + +void handle_key_press(GdkEventKey key); +void handle_button_press(GdkEvent *event); +void handle_button_release(); +void handle_mouse_move(gdouble x, gdouble y); +void handle_scroll(GdkEvent *event); +void handle_resize(); + +#endif @@ -1,178 +1,37 @@ #include "file.h" #include "image.h" -#include <dirent.h> +#include "input.h" +#include "window.h" #include <gtk-3.0/gtk/gtk.h> -#include <libgen.h> -#include <stdlib.h> -#include <string.h> -#define TIMEOUT 20 - -GtkWidget *window; -gint win_width, win_height; -GError *error = NULL; - -void next() -{ - char *name; - if ((name = get_next_file()) != NULL) - load_image(name, win_width, win_height); -} - -void prev() -{ - char *name; - if ((name = get_prev_file()) != NULL) - load_image(name, win_width, win_height); -} - -void first() -{ - char *name; - if ((name = get_first_file()) != NULL) - load_image(name, win_width, win_height); -} - -void last() -{ - char *name; - if ((name = get_last_file()) != NULL) - load_image(name, win_width, win_height); -} - -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_w: - curr_scale_mod = fit; - fit_image(win_width, win_height); - return FALSE; - case GDK_KEY_plus: - case GDK_KEY_KP_Add: - zoom(1); - return FALSE; - case GDK_KEY_minus: - case GDK_KEY_KP_Subtract: - zoom(-1); - return FALSE; - case GDK_KEY_equal: - zoom(0); - return FALSE; - case GDK_KEY_n: - case GDK_KEY_j: - case GDK_KEY_Right: - next(); - return FALSE; - case GDK_KEY_p: - case GDK_KEY_k: - case GDK_KEY_Left: - prev(); - return FALSE; - case GDK_KEY_g: - case GDK_KEY_Home: - first(); - return FALSE; - case GDK_KEY_G: - case GDK_KEY_End: - last(); - return FALSE; - default: - return TRUE; - } -} - -gboolean scroll_callback(GtkWindow *window, GdkEvent *event, gpointer data) -{ - GdkModifierType state; - gdk_event_get_state(event, &state); - - switch (event->scroll.direction) { - case GDK_SCROLL_UP: - if (state & GDK_CONTROL_MASK) { - zoom(1); - curr_scale_mod = zoomed; - } else { - next(); - } - return FALSE; - break; - case GDK_SCROLL_DOWN: - if (state & GDK_CONTROL_MASK) { - zoom(-1); - curr_scale_mod = zoomed; - } else { - prev(); - } - return FALSE; - break; - default: - break; - } - return TRUE; -} - -gboolean resize_done(gpointer data) +void print_help() { - guint *id = data; - *id = 0; - gtk_window_get_size(GTK_WINDOW(window), &win_width, &win_height); - fit_image(win_width, win_height); - return FALSE; -} - -gboolean configure_callback(GtkWindow *window, GdkEvent *event, gpointer data) -{ - if (curr_scale_mod != fit) { - return FALSE; - } - static guint id = 0; - if (id) - g_source_remove(id); - id = g_timeout_add(TIMEOUT, resize_done, &id); - return FALSE; + printf("usage: qwe [filename]\n"); } static void activate(GtkApplication *app, gpointer user_data) { + print_help(); } static void open(GApplication *app, GFile **files, gint n_files, const gchar *hint) { if (n_files != 1) { + print_help(); return; } - window = gtk_application_window_new(GTK_APPLICATION(app)); - gtk_window_set_title(GTK_WINDOW(window), "qwe"); - gtk_window_set_default_size(GTK_WINDOW(window), 800, 600); - 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); - char *curr_filename = g_file_get_path(files[0]); + create_main_window(app); + char *curr_filename = g_file_get_path(files[0]); int i = scan(curr_filename); if (i < 0) { - printf("scan() error %d\n", i); + printf("failed to load file"); return; } - 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(new_image())); - gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(scrolled_window)); - gtk_widget_show_all(GTK_WIDGET(window)); - - load_image(curr_filename, win_width, win_height); + load_image(curr_filename); } int main(int argc, char *argv[]) @@ -6,7 +6,7 @@ LDFLAGS=$(shell pkg-config --libs gtk+-3.0) PREFIX=/usr BINDIR=$(PREFIX)/bin -OBJECTS=main.o file.o image.o +OBJECTS=main.o file.o image.o input.o window.o all: qwe diff --git a/window.c b/window.c new file mode 100644 index 0000000..2d095c6 --- /dev/null +++ b/window.c @@ -0,0 +1,98 @@ +#include "window.h" +#include "image.h" +#include "input.h" +#include <gtk-3.0/gtk/gtk.h> + +GtkWidget *window; +GtkWidget *scrolled_window; + +static gboolean key_press(GtkWindow *window, GdkEvent *event, gpointer data) +{ + handle_key_press(event->key); + return FALSE; +} + +static gboolean button_press(GtkWindow *window, GdkEvent *event, gpointer data) +{ + handle_button_press(event); + return TRUE; +} + +static gboolean button_release(GtkWindow *window, GdkEvent *event, + gpointer data) +{ + handle_button_release(); + return TRUE; +} + +static gboolean motion_notify(GtkWindow *window, GdkEvent *event, gpointer data) +{ + handle_mouse_move(event->motion.x, event->motion.y); + return TRUE; +} + +static gboolean scroll_callback(GtkWindow *window, GdkEvent *event, + gpointer data) +{ + handle_scroll(event); + return TRUE; +} + +static gboolean configure_callback(GtkWindow *window, GdkEvent *event, + gpointer data) +{ + handle_resize(); + return TRUE; +} + +void create_main_window(GApplication *app) +{ + window = gtk_application_window_new(GTK_APPLICATION(app)); + gtk_window_set_title(GTK_WINDOW(window), "qwe"); + gtk_window_set_default_size(GTK_WINDOW(window), 800, 600); + 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); + g_signal_connect(G_OBJECT(window), "button-press-event", + G_CALLBACK(button_press), NULL); + g_signal_connect(G_OBJECT(window), "button-release-event", + G_CALLBACK(button_release), NULL); + g_signal_connect(G_OBJECT(window), "motion-notify-event", + G_CALLBACK(motion_notify), NULL); + gtk_widget_add_events(GTK_WIDGET(window), GDK_SCROLL_MASK); + g_signal_connect(G_OBJECT(window), "scroll-event", + G_CALLBACK(scroll_callback), NULL); + + 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(new_image())); + gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(scrolled_window)); + gtk_widget_show_all(GTK_WIDGET(window)); +} + +void scroll_window(gdouble x, gdouble y) +{ + GtkAdjustment *h_adj = gtk_scrolled_window_get_hadjustment( + GTK_SCROLLED_WINDOW(scrolled_window)); + GtkAdjustment *v_adj = gtk_scrolled_window_get_vadjustment( + GTK_SCROLLED_WINDOW(scrolled_window)); + gtk_adjustment_set_value(h_adj, gtk_adjustment_get_value(h_adj) + x); + gtk_adjustment_set_value(v_adj, gtk_adjustment_get_value(v_adj) + y); + gtk_scrolled_window_set_hadjustment(GTK_SCROLLED_WINDOW(scrolled_window), + h_adj); + gtk_scrolled_window_set_vadjustment(GTK_SCROLLED_WINDOW(scrolled_window), + v_adj); +} + +void get_curr_win_size(gint *width, gint *height) +{ + gtk_window_get_size(GTK_WINDOW(window), width, height); +} + +void quit() +{ + g_application_quit( + G_APPLICATION(gtk_window_get_application(GTK_WINDOW(window)))); +} diff --git a/window.h b/window.h new file mode 100644 index 0000000..5d5f272 --- /dev/null +++ b/window.h @@ -0,0 +1,11 @@ +#ifndef __WINDOW_H +#define __WINDOW_H + +#include <gtk-3.0/gtk/gtk.h> + +void create_main_window(GApplication *app); +void get_curr_win_size(gint *width, gint *height); +void scroll_window(gdouble x, gdouble y); +void quit(); + +#endif |