#include #include #include "window_main.h" #include "walls_ui.h" #include "db.h" #include "walls_model.h" GdkPixbuf *orig_pixbuf = NULL; gint last_width = 0, last_height = 0, last_pos = 0; GtkImage *image = NULL; GtkWidget *layout = NULL; void on_filetree_selection_changed(GtkTreeSelection *treeselection, gpointer user_data); inline static void filetree_create_model(GtkTreeView *filetree) { GtkTreeModel *tree_model; tree_model = GTK_TREE_MODEL(walls_model_new()); gtk_tree_view_set_model(filetree, GTK_TREE_MODEL(tree_model)); } inline static void filetree_init(GtkTreeView *filetree) { GtkTreeViewColumn *col1, *col2, *col3, *col4; GtkCellRenderer *renderer; GtkTreeSelection *selection; col1 = gtk_tree_view_column_new(); gtk_tree_view_column_set_title(col1, "Name"); gtk_tree_view_append_column(filetree, col1); col2 = gtk_tree_view_column_new(); gtk_tree_view_column_set_title(col2, "Size"); gtk_tree_view_append_column(filetree, col2); col3 = gtk_tree_view_column_new(); gtk_tree_view_column_set_title(col3, "Width"); gtk_tree_view_append_column(filetree, col3); col4 = gtk_tree_view_column_new(); gtk_tree_view_column_set_title(col4, "Height"); gtk_tree_view_append_column(filetree, col4); renderer = gtk_cell_renderer_text_new(); gtk_tree_view_column_pack_start(col1, renderer, TRUE); gtk_tree_view_column_add_attribute(col1, renderer, "text", 0); renderer = gtk_cell_renderer_text_new(); gtk_tree_view_column_pack_start(col2, renderer, TRUE); gtk_tree_view_column_add_attribute(col2, renderer, "text", 1); renderer = gtk_cell_renderer_text_new(); gtk_tree_view_column_pack_start(col3, renderer, TRUE); gtk_tree_view_column_add_attribute(col3, renderer, "text", 2); renderer = gtk_cell_renderer_text_new(); gtk_tree_view_column_pack_start(col4, renderer, TRUE); gtk_tree_view_column_add_attribute(col4, renderer, "text", 3); filetree_create_model(filetree); selection = gtk_tree_view_get_selection(filetree); g_signal_connect(selection, "changed", G_CALLBACK(on_filetree_selection_changed), filetree); } static void resize_pixbuf() { GdkPixbuf *pb; GdkWindow *window; gint win_width, win_height, img_width, img_height, width, height; gdouble scalex, scaley, width_ratio, height_ratio, max_ratio; window = gtk_widget_get_window(layout); gdk_drawable_get_size(window, &win_width, &win_height); gtk_layout_set_size(GTK_LAYOUT(layout), win_width, win_height); img_width = gdk_pixbuf_get_width(orig_pixbuf); img_height = gdk_pixbuf_get_height(orig_pixbuf); /* do we need to resize? */ if(img_width > win_width || img_height > win_height) { /* resize by width */ width_ratio = (gdouble)img_width / (gdouble)win_width; height_ratio = (gdouble)img_height / (gdouble)win_height; if(width_ratio > height_ratio) { width = win_width; height = (gint)(1.0 / width_ratio * img_height); scalex = (gdouble)width / (gdouble)img_width; scaley = (gdouble)height / (gdouble)img_height; } else { /* resize by height */ height = win_height; width = (gint)(1.0 / height_ratio * img_width); scalex = (gdouble)width / (gdouble)img_width; scaley = (gdouble)height / (gdouble)img_height; } pb = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, width, height); gdk_pixbuf_scale(orig_pixbuf, pb, 0, 0, width, height, 0, 0, scalex, scaley, GDK_INTERP_BILINEAR); } else { width = img_width; height = img_height; pb = gdk_pixbuf_copy(orig_pixbuf); } 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); gdk_pixbuf_unref(pb); } void on_window_size_allocate(GtkWidget *widget, GtkAllocation *allocation, gpointer user_data) { if(orig_pixbuf && (allocation->width != last_width || allocation->height != last_height)) { resize_pixbuf(); last_width = allocation->width; last_height = allocation->height; } } void on_window_hpane_resized(GObject *gobject, GParamSpec *pspec, gpointer user_data) { gint pos; pos = gtk_paned_get_position(GTK_PANED(gobject)); if(orig_pixbuf && pos != last_pos) { resize_pixbuf(); last_pos = pos; } } static void load_pixbuf(struct wallpaper_t *wall) { GdkPixbuf *pb; GError *error = NULL; GdkWindow *window; gint win_width, win_height, img_width, img_height, width, height; gdouble scalex, scaley, width_ratio, height_ratio, max_ratio; if(orig_pixbuf) gdk_pixbuf_unref(orig_pixbuf); orig_pixbuf = gdk_pixbuf_new_from_file(wall->filepath, &error); if(!orig_pixbuf) { g_warning("%s", error->message); g_free(error); return; } resize_pixbuf(); } void on_filetree_selection_changed(GtkTreeSelection *treeselection, gpointer user_data) { GtkTreeModel *model; GtkTreeIter iter; struct wallpaper_t *wall; if(gtk_tree_selection_get_selected(treeselection, &model, &iter)) { if(walls_model_get_record_type(model, &iter) == WALLS_MODEL_TYPE_WALL) { walls_model_get_wall_record(model, &iter, &wall); load_pixbuf(wall); } } } int gui_main(int argc, char **argv) { GtkWidget *window; GtkWidget *filetree; GtkWidget *window_hpane; GtkBuilder *builder ; GError *error = NULL; if(!db_open()) return 1; gtk_init(&argc, &argv); builder = gtk_builder_new(); if(!gtk_builder_add_from_string(builder, ui_string, -1, &error)) { g_warning("%s", error->message); g_free(error); return 1; } window = GTK_WIDGET(gtk_builder_get_object(builder, "window")); gtk_window_set_title(GTK_WINDOW(window), "walls"); filetree = GTK_WIDGET(gtk_builder_get_object(builder, "filetree")); filetree_init(GTK_TREE_VIEW(filetree)); image = GTK_IMAGE(gtk_builder_get_object(builder, "image")); layout = GTK_WIDGET(gtk_builder_get_object(builder, "layout")); 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); gtk_builder_connect_signals(builder, NULL); g_object_unref(G_OBJECT(builder)); gtk_widget_show_all(window); gtk_main(); db_close(); return 0; }