diff options
author | Jon Bergli Heier <snakebite@jvnv.net> | 2009-12-22 23:08:43 +0100 |
---|---|---|
committer | Jon Bergli Heier <snakebite@jvnv.net> | 2009-12-22 23:08:43 +0100 |
commit | 925fcf201ae850da169516a4c2a9102f1e3a0df4 (patch) | |
tree | d7b2e0851a8ab4131f9bd8e4f47460b425b61ba4 | |
parent | d7427af59c06fe1186b97998df4f0f158e0ef818 (diff) |
Viewing images in the image box now works.
Images are resized to fit in the image box on the right hand side.
No further resizing is currently done unless the image is reloaded.
-rw-r--r-- | walls.ui | 27 | ||||
-rw-r--r-- | walls_model.c | 50 | ||||
-rw-r--r-- | walls_model.h | 4 | ||||
-rw-r--r-- | window_main.c | 73 |
4 files changed, 139 insertions, 15 deletions
@@ -72,7 +72,7 @@ </packing> </child> <child> - <object class="GtkHBox" id="hbox1"> + <object class="GtkHPaned" id="hpaned1"> <property name="visible">True</property> <child> <object class="GtkNotebook" id="left_pages"> @@ -103,20 +103,33 @@ </child> </object> <packing> - <property name="position">0</property> + <property name="resize">False</property> + <property name="shrink">True</property> </packing> </child> <child> - <object class="GtkAspectFrame" id="aspectframe1"> + <object class="GtkScrolledWindow" id="scrolledwindow1"> <property name="visible">True</property> - <property name="label_xalign">0</property> - <property name="shadow_type">none</property> + <property name="can_focus">True</property> + <property name="hscrollbar_policy">automatic</property> + <property name="vscrollbar_policy">automatic</property> <child> - <placeholder/> + <object class="GtkViewport" id="viewport1"> + <property name="visible">True</property> + <property name="resize_mode">queue</property> + <property name="shadow_type">none</property> + <child> + <object class="GtkImage" id="image"> + <property name="visible">True</property> + <property name="stock">gtk-missing-image</property> + </object> + </child> + </object> </child> </object> <packing> - <property name="position">1</property> + <property name="resize">True</property> + <property name="shrink">True</property> </packing> </child> </object> diff --git a/walls_model.c b/walls_model.c index f7f9bb0..c2e7ef6 100644 --- a/walls_model.c +++ b/walls_model.c @@ -154,7 +154,7 @@ inline static void fill_dir(WallsModelRecord *record) { dir = &g_array_index(array, struct directory_t, i); temp.type = WALLS_MODEL_TYPE_DIR; - temp.dir.name = g_path_get_basename(dir->name); + temp.dir.name = g_strdup(dir->name); temp.dir.dirid = dir->dirid; temp.parent = record; temp.children = NULL; @@ -175,7 +175,7 @@ inline static void fill_dir(WallsModelRecord *record) { wall = &g_array_index(array, struct wallpaper_t, i); temp.type = WALLS_MODEL_TYPE_WALL; - temp.wall.filepath = g_path_get_basename(wall->filepath); + temp.wall.filepath = g_strdup(wall->filepath); temp.wall.id = wall->id; temp.wall.size = wall->size; temp.wall.width = wall->width; @@ -260,11 +260,11 @@ static void walls_model_get_value(GtkTreeModel *tree_model, GtkTreeIter *iter, g WallsModelRecord *record; WallsModel *walls_model; - g_return_if_fail(MODEL_IS_WALLS(walls_model)); + g_return_if_fail(MODEL_IS_WALLS(tree_model)); g_return_if_fail(iter != NULL); - g_return_if_fail(column < WALLS_MODEL(walls_model)->n_columns); + g_return_if_fail(column < WALLS_MODEL(tree_model)->n_columns); - g_value_init(value, WALLS_MODEL(walls_model)->column_types[column]); + g_value_init(value, WALLS_MODEL(tree_model)->column_types[column]); walls_model = WALLS_MODEL(tree_model); @@ -277,7 +277,10 @@ static void walls_model_get_value(GtkTreeModel *tree_model, GtkTreeIter *iter, g if(record->type == WALLS_MODEL_TYPE_DIR) { if(column == WALLS_MODEL_COL_NAME) { - g_value_set_string(value, record->dir.name); + if(record->parent == NULL) + g_value_set_string(value, record->dir.name); + else + g_value_set_string_take_ownership(value, g_path_get_basename(record->dir.name)); } else { g_value_set_string(value, ""); } @@ -286,7 +289,7 @@ static void walls_model_get_value(GtkTreeModel *tree_model, GtkTreeIter *iter, g switch(column) { case WALLS_MODEL_COL_NAME: - g_value_set_string(value, record->wall.filepath); + g_value_set_string_take_ownership(value, g_path_get_basename(record->wall.filepath)); break; case WALLS_MODEL_COL_SIZE: g_value_set_string_take_ownership(value, g_strdup_printf("%d", record->wall.size)); @@ -477,3 +480,36 @@ WallsModel *walls_model_new() { return new_walls_model; } + +static void walls_model_get_record(GtkTreeModel *tree_model, GtkTreeIter *iter, void **data) { + WallsModel *walls_model; + WallsModelRecord *record; + + g_assert(MODEL_IS_WALLS(tree_model)); + g_assert(iter != NULL); + + walls_model = WALLS_MODEL(tree_model); + record = (WallsModelRecord*)iter->user_data; + *data = (void*)(&record->dir); +} + +void walls_model_get_dir_record(GtkTreeModel *tree_model, GtkTreeIter *iter, struct directory_t **dir) { + walls_model_get_record(tree_model, iter, (void**)dir); +} + +void walls_model_get_wall_record(GtkTreeModel *tree_model, GtkTreeIter *iter, struct wallpaper_t **wall) { + walls_model_get_record(tree_model, iter, (void**)wall); +} + +guint walls_model_get_record_type(GtkTreeModel *tree_model, GtkTreeIter *iter) { + WallsModel *walls_model; + WallsModelRecord *record; + + g_assert(MODEL_IS_WALLS(tree_model)); + g_assert(iter != NULL); + + walls_model = WALLS_MODEL(tree_model); + record = (WallsModelRecord*)iter->user_data; + + return record->type; +} diff --git a/walls_model.h b/walls_model.h index 4f9f43a..7b73e8d 100644 --- a/walls_model.h +++ b/walls_model.h @@ -57,6 +57,8 @@ struct _WallsModelClass { GType walls_model_get_type(); WallsModel *walls_model_new(); -void walls_model_append_record(WallsModel*, void*); +void walls_model_get_dir_record(GtkTreeModel*, GtkTreeIter*, struct directory_t**); +void walls_model_get_wall_record(GtkTreeModel*, GtkTreeIter*, struct wallpaper_t**); +guint walls_model_get_record_type(GtkTreeModel*, GtkTreeIter*); #endif diff --git a/window_main.c b/window_main.c index bca438a..57c8885 100644 --- a/window_main.c +++ b/window_main.c @@ -1,10 +1,18 @@ #include <string.h> +#include <gdk-pixbuf/gdk-pixbuf.h> + #include "window_main.h" #include "walls_ui.h" #include "db.h" #include "walls_model.h" +GdkPixbuf *pixbuf = NULL; + +GtkImage *image = NULL; + +void on_filetree_selection_changed(GtkTreeSelection *treeselection, gpointer user_data); + inline static void filetree_create_model(GtkTreeView *filetree) { GtkTreeModel *tree_model; @@ -15,6 +23,7 @@ inline static void filetree_create_model(GtkTreeView *filetree) { 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"); @@ -49,6 +58,68 @@ inline static void filetree_init(GtkTreeView *filetree) { 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 load_pixbuf(struct wallpaper_t *wall) { + GdkPixbuf *pb, *pb2; + 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; + + pb = gdk_pixbuf_new_from_file(wall->filepath, &error); + if(!pb) { + g_warning("%s", error->message); + g_free(error); + return; + } + + window = gtk_widget_get_window(GTK_WIDGET(image)); + gdk_drawable_get_size(window, &win_width, &win_height); + img_width = gdk_pixbuf_get_width(pb); + img_height = gdk_pixbuf_get_height(pb); + + /* 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; + } + pb2 = pb; + pb = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, width, height); + gdk_pixbuf_scale(pb2, pb, 0, 0, width, height, 0, 0, scalex, scaley, GDK_INTERP_BILINEAR); + gdk_pixbuf_unref(pb2); + } + + //gtk_image_set_from_file(image, wall->filepath); + gtk_image_set_from_pixbuf(image, pb); + gdk_pixbuf_unref(pb); +} + +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) { @@ -75,6 +146,8 @@ int gui_main(int argc, char **argv) { filetree = GTK_WIDGET(gtk_builder_get_object(builder, "filetree")); filetree_init(GTK_TREE_VIEW(filetree)); + image = GTK_IMAGE(gtk_builder_get_object(builder, "image")); + gtk_builder_connect_signals(builder, NULL); g_object_unref(G_OBJECT(builder)); |