[nautilus/wip/csoriano/flow] MVC pattern



commit 6c0f5aff53bddc90fbbab4471ed861875faf0121
Author: Carlos Soriano <csoriano gnome org>
Date:   Tue Dec 6 17:32:34 2016 +0100

    MVC pattern

 src/Makefile.am                                    |   12 +-
 src/nautilus-canvas-view.c                         |    2 +-
 src/nautilus-container-max-width.c                 |    2 -
 src/nautilus-files-view.c                          |    4 +-
 src/nautilus-icon-view-item.c                      |  274 ----------
 src/nautilus-icon-view-item.h                      |   29 --
 src/nautilus-icon-view.c                           |  530 --------------------
 src/nautilus-view-icon-controller.c                |  505 +++++++++++++++++++
 src/nautilus-view-icon-controller.h                |   23 +
 src/nautilus-view-icon-item-ui.c                   |  261 ++++++++++
 src/nautilus-view-icon-item-ui.h                   |   22 +
 src/nautilus-view-icon-ui.c                        |  110 ++++
 ...autilus-icon-view.h => nautilus-view-icon-ui.h} |   21 +-
 src/nautilus-view-item-model.c                     |  165 ++++++
 src/nautilus-view-item-model.h                     |   31 ++
 15 files changed, 1135 insertions(+), 856 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 8cd7d54..d98a2c8 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -168,10 +168,6 @@ nautilus_no_main_sources = \
        nautilus-floating-bar.h                 \
        nautilus-freedesktop-dbus.c             \
        nautilus-freedesktop-dbus.h             \
-       nautilus-icon-view.c                    \
-       nautilus-icon-view.h                    \
-       nautilus-icon-view-item.c               \
-       nautilus-icon-view-item.h               \
        nautilus-image-properties-page.c        \
        nautilus-image-properties-page.h        \
        nautilus-list-model.c                   \
@@ -218,6 +214,14 @@ nautilus_no_main_sources = \
        nautilus-trash-bar.h                    \
        nautilus-view.c                         \
        nautilus-view.h                         \
+       nautilus-view-icon-controller.c         \
+       nautilus-view-icon-controller.h         \
+       nautilus-view-icon-item-ui.c            \
+       nautilus-view-icon-item-ui.h            \
+       nautilus-view-icon-ui.c                 \
+       nautilus-view-icon-ui.h                 \
+       nautilus-view-item-model.c              \
+       nautilus-view-item-model.h              \
        nautilus-window-slot.c                  \
        nautilus-window-slot.h                  \
        nautilus-window-slot-dnd.c              \
diff --git a/src/nautilus-canvas-view.c b/src/nautilus-canvas-view.c
index 87d1181..da15d72 100644
--- a/src/nautilus-canvas-view.c
+++ b/src/nautilus-canvas-view.c
@@ -101,7 +101,7 @@ struct NautilusCanvasViewDetails
     gboolean supports_scaling;
     gboolean supports_keep_aligned;
 
-    /* Needed for async operations. Suposedly we would use cancellable and gtask,
+    /* FIXME: Needed for async operations. Suposedly we would use cancellable and gtask,
      * sadly gtkclipboard doesn't support that.
      * We follow this pattern for checking validity of the object in the views.
      * Ideally we would connect to a weak reference and do a cancellable.
diff --git a/src/nautilus-container-max-width.c b/src/nautilus-container-max-width.c
index 67134e9..690a935 100644
--- a/src/nautilus-container-max-width.c
+++ b/src/nautilus-container-max-width.c
@@ -147,8 +147,6 @@ get_preferred_height (GtkWidget *widget,
                                    &padding);
     *minimum_size += padding.top + padding.bottom;
     *natural_size += padding.top + padding.bottom;
-
-    g_print ("preferred height %d %d\n", *minimum_size, *natural_size);
 }
 
 static void
diff --git a/src/nautilus-files-view.c b/src/nautilus-files-view.c
index 758d8ee..e7a5f5e 100644
--- a/src/nautilus-files-view.c
+++ b/src/nautilus-files-view.c
@@ -35,7 +35,7 @@
 #include "nautilus-error-reporting.h"
 #include "nautilus-file-undo-manager.h"
 #include "nautilus-floating-bar.h"
-#include "nautilus-icon-view.h"
+#include "nautilus-view-icon-controller.h"
 #include "nautilus-list-view.h"
 #include "nautilus-canvas-view.h"
 #include "nautilus-mime-actions.h"
@@ -9284,7 +9284,7 @@ nautilus_files_view_new (guint               id,
     {
         case NAUTILUS_VIEW_GRID_ID:
         {
-            view = nautilus_icon_view_new (slot);
+            view = nautilus_view_icon_controller_new (slot);
         }
         break;
 
diff --git a/src/nautilus-view-icon-controller.c b/src/nautilus-view-icon-controller.c
new file mode 100644
index 0000000..9b1781a
--- /dev/null
+++ b/src/nautilus-view-icon-controller.c
@@ -0,0 +1,505 @@
+#include "nautilus-view-icon-controller.h"
+#include "nautilus-view-icon-ui.h"
+#include "nautilus-view-item-model.h"
+#include "nautilus-files-view.h"
+#include "nautilus-file.h"
+#include "nautilus-window-slot.h"
+#include "nautilus-directory.h"
+#include "nautilus-global-preferences.h"
+
+struct _NautilusViewIconController
+{
+    NautilusFilesView parent_instance;
+
+    NautilusViewIconUi *view_ui;
+    GListModel *model;
+
+    GtkWidget *view_icon;
+    GActionGroup *action_group;
+    gint zoom_level;
+};
+
+G_DEFINE_TYPE (NautilusViewIconController, nautilus_view_icon_controller, NAUTILUS_TYPE_FILES_VIEW)
+
+enum {
+  PROP_0,
+  N_PROPS
+};
+
+static GParamSpec *properties [N_PROPS];
+
+static gint
+get_default_zoom_level ()
+{
+    NautilusCanvasZoomLevel default_zoom_level;
+
+    default_zoom_level = g_settings_get_enum (nautilus_icon_view_preferences,
+                                              NAUTILUS_PREFERENCES_ICON_VIEW_DEFAULT_ZOOM_LEVEL);
+
+    return NAUTILUS_CANVAS_ZOOM_LEVEL_LARGE;
+}
+
+static void
+set_sort_order_from_metadata_and_preferences (NautilusViewIconController *self)
+{
+
+}
+
+static void
+real_begin_loading (NautilusFilesView *files_view)
+{
+    NautilusViewIconController *self = NAUTILUS_VIEW_ICON_CONTROLLER (files_view);
+
+    set_sort_order_from_metadata_and_preferences (self);
+}
+
+static void
+real_clear (NautilusFilesView *files_view)
+{
+    NautilusViewIconController *self = NAUTILUS_VIEW_ICON_CONTROLLER (files_view);
+
+    g_list_store_remove_all (G_LIST_STORE (self->model));
+}
+
+
+static void
+real_file_changed (NautilusFilesView *files_view,
+                   NautilusFile      *file,
+                   NautilusDirectory *directory)
+{
+}
+
+static GList *
+real_get_selection (NautilusFilesView *files_view)
+{
+    return NULL;
+}
+
+
+static GList *
+real_get_selection_for_file_transfer (NautilusFilesView *files_view)
+{
+    return NULL;
+}
+
+static gboolean
+real_is_empty (NautilusFilesView *files_view)
+{
+    NautilusViewIconController *self = NAUTILUS_VIEW_ICON_CONTROLLER (files_view);
+
+    return g_list_model_get_n_items (self->model) == 0;
+}
+
+static void
+real_end_file_changes (NautilusFilesView *files_view)
+{
+}
+
+static void
+real_remove_file (NautilusFilesView *files_view,
+                  NautilusFile      *file,
+                  NautilusDirectory *directory)
+{
+    NautilusViewIconController *self = NAUTILUS_VIEW_ICON_CONTROLLER (files_view);
+    NautilusFile *current_file;
+    NautilusViewItemModel *current_item_model;
+    guint i = 0;
+
+    while ((current_item_model = NAUTILUS_VIEW_ITEM_MODEL (g_list_model_get_item (self->model, i))))
+    {
+        current_file = nautilus_view_item_model_get_file (current_item_model);
+        if (current_file == file)
+        {
+            g_list_store_remove (G_LIST_STORE (self->model), i);
+            break;
+        }
+        i++;
+    }
+}
+
+static void
+real_set_selection (NautilusFilesView *files_view,
+                    GList             *selection)
+{
+    nautilus_files_view_notify_selection_changed (files_view);
+}
+
+static void
+real_select_all (NautilusFilesView *files_view)
+{
+}
+
+static void
+real_reveal_selection (NautilusFilesView *files_view)
+{
+}
+
+static void
+real_update_actions_state (NautilusFilesView *files_view)
+{
+    NAUTILUS_FILES_VIEW_CLASS (nautilus_view_icon_controller_parent_class)->update_actions_state 
(files_view);
+}
+
+static void
+real_bump_zoom_level (NautilusFilesView *files_view,
+                      int                zoom_increment)
+{
+    NautilusViewIconController *self = NAUTILUS_VIEW_ICON_CONTROLLER (files_view);
+    NautilusCanvasZoomLevel new_level;
+
+    new_level = self->zoom_level + zoom_increment;
+
+    if (new_level >= NAUTILUS_CANVAS_ZOOM_LEVEL_SMALL &&
+        new_level <= NAUTILUS_CANVAS_ZOOM_LEVEL_LARGER)
+    {
+        g_action_group_change_action_state (self->action_group,
+                                            "zoom-to-level",
+                                            g_variant_new_int32 (new_level));
+    }
+}
+
+static guint
+real_get_zoom_level (NautilusFilesView *files_view)
+{
+    NautilusViewIconController *self = NAUTILUS_VIEW_ICON_CONTROLLER (files_view);
+
+    return self->zoom_level;
+}
+
+static guint
+get_icon_size_for_zoom_level (NautilusCanvasZoomLevel zoom_level)
+{
+    switch (zoom_level)
+    {
+        case NAUTILUS_CANVAS_ZOOM_LEVEL_SMALL:
+        {
+            return NAUTILUS_CANVAS_ICON_SIZE_SMALL;
+        }
+        break;
+
+        case NAUTILUS_CANVAS_ZOOM_LEVEL_STANDARD:
+        {
+            return NAUTILUS_CANVAS_ICON_SIZE_STANDARD;
+        }
+        break;
+
+        case NAUTILUS_CANVAS_ZOOM_LEVEL_LARGE:
+        {
+            return NAUTILUS_CANVAS_ICON_SIZE_LARGE;
+        }
+        break;
+
+        case NAUTILUS_CANVAS_ZOOM_LEVEL_LARGER:
+        {
+            return NAUTILUS_CANVAS_ICON_SIZE_LARGER;
+        }
+        break;
+    }
+    g_return_val_if_reached (NAUTILUS_CANVAS_ICON_SIZE_STANDARD);
+}
+
+static void
+set_icon_size (NautilusViewIconController *self,
+               gint                        icon_size)
+{
+    NautilusViewItemModel *current_item_model;
+
+    guint i = 0;
+
+    while (current_item_model = NAUTILUS_VIEW_ITEM_MODEL (g_list_model_get_item (self->model, i)))
+    {
+        nautilus_view_item_model_set_icon_size (current_item_model,
+                                                get_icon_size_for_zoom_level (self->zoom_level));
+    }
+}
+
+static void
+set_zoom_level (NautilusViewIconController *self,
+                guint                       new_level)
+{
+    self->zoom_level = new_level;
+
+    set_icon_size (self, get_icon_size_for_zoom_level (new_level));
+}
+static void
+real_zoom_to_level (NautilusFilesView *files_view,
+                    guint              new_level)
+{
+}
+
+static void
+real_restore_standard_zoom_level (NautilusFilesView *files_view)
+{
+}
+
+static gfloat
+real_get_zoom_level_percentage (NautilusFilesView *files_view)
+{
+    NautilusViewIconController *self = NAUTILUS_VIEW_ICON_CONTROLLER (files_view);
+
+    return (gfloat) get_icon_size_for_zoom_level (self->zoom_level) /
+           NAUTILUS_CANVAS_ICON_SIZE_LARGE;
+}
+
+static gboolean
+real_can_zoom_in (NautilusFilesView *files_view)
+{
+    return TRUE;
+}
+
+static gboolean
+real_can_zoom_out (NautilusFilesView *files_view)
+{
+    return TRUE;
+}
+
+static void
+real_click_policy_changed (NautilusFilesView *files_view)
+{
+}
+
+static int
+real_compare_files (NautilusFilesView *files_view,
+                    NautilusFile      *file1,
+                    NautilusFile      *file2)
+{
+    if (file1 < file2)
+    {
+        return -1;
+    }
+
+    if (file1 > file2)
+    {
+        return +1;
+    }
+
+    return 0;
+}
+
+static gboolean
+real_using_manual_layout (NautilusFilesView *files_view)
+{
+    return FALSE;
+}
+
+static void
+real_end_loading (NautilusFilesView *files_view,
+                  gboolean           all_files_seen)
+{
+}
+
+static char *
+real_get_first_visible_file (NautilusFilesView *files_view)
+{
+    return NULL;
+}
+
+static void
+real_scroll_to_file (NautilusFilesView *files_view,
+                     const char        *uri)
+{
+}
+
+static void
+real_sort_directories_first_changed (NautilusFilesView *files_view)
+{
+}
+
+static gpointer *
+convert_glist_to_array (GList *list)
+{
+    gpointer *array;
+    GList *l;
+    int i = 0;
+
+    g_return_val_if_fail (list != NULL, NULL);
+
+    array = g_malloc (g_list_length (list) * sizeof (list->data));
+
+    for (l = list; l != NULL; l = l->next, i++)
+    {
+        array[i] = l->data;
+    }
+
+    return array;
+}
+
+static void
+real_add_files (NautilusFilesView *files_view,
+                GList             *files,
+                NautilusDirectory *directory)
+{
+    NautilusViewIconController *self = NAUTILUS_VIEW_ICON_CONTROLLER (files_view);
+    g_autofree gpointer *array = NULL;
+
+    clock_t start = clock ();
+
+    g_print ("add files %d\n", g_list_length (files));
+    array = convert_glist_to_array (files);
+    g_list_store_splice (G_LIST_STORE (self->model),
+                         g_list_model_get_n_items (self->model),
+                         0, array, g_list_length (files));
+    clock_t end = clock ();
+    double elapsed_time = (end - start) / (double) CLOCKS_PER_SEC;
+    g_print ("add file finished %d %f\n", g_list_model_get_n_items (self->model), elapsed_time);
+}
+
+
+static guint
+real_get_view_id (NautilusFilesView *files_view)
+{
+    return NAUTILUS_VIEW_GRID_ID;
+}
+
+static GIcon *
+real_get_icon (NautilusFilesView *files_view)
+{
+    NautilusViewIconController *self = NAUTILUS_VIEW_ICON_CONTROLLER (files_view);
+
+    return self->view_icon;
+}
+
+static void
+real_select_first (NautilusFilesView *files_view)
+{
+}
+
+static void
+action_zoom_to_level (GSimpleAction *action,
+                      GVariant      *state,
+                      gpointer       user_data)
+{
+    NautilusViewIconUi *self = NAUTILUS_VIEW_ICON_CONTROLLER (user_data);
+
+    set_zoom_level (self, g_variant_get_int32 (state));
+    g_simple_action_set_state (G_SIMPLE_ACTION (action), state);
+}
+
+static void
+finalize (GObject *object)
+{
+  NautilusViewIconController *self = (NautilusViewIconController *)object;
+
+  G_OBJECT_CLASS (nautilus_view_icon_controller_parent_class)->finalize (object);
+}
+
+static void
+get_property (GObject    *object,
+              guint       prop_id,
+              GValue     *value,
+              GParamSpec *pspec)
+{
+  NautilusViewIconController *self = NAUTILUS_VIEW_ICON_CONTROLLER (object);
+
+  switch (prop_id)
+    {
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+set_property (GObject      *object,
+              guint         prop_id,
+              const GValue *value,
+              GParamSpec   *pspec)
+{
+  NautilusViewIconController *self = NAUTILUS_VIEW_ICON_CONTROLLER (object);
+
+  switch (prop_id)
+    {
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+const GActionEntry view_icon_ui_entries[] =
+{
+    { "zoom-to-level", NULL, NULL, "3", action_zoom_to_level }
+};
+
+static void
+constructed (NautilusViewIconController *self)
+{
+    GtkWidget *content_widget;
+
+    self->action_group = nautilus_files_view_get_action_group (NAUTILUS_FILES_VIEW (self));
+    g_action_map_add_action_entries (G_ACTION_MAP (self->action_group),
+                                     view_icon_ui_entries,
+                                     G_N_ELEMENTS (view_icon_ui_entries),
+                                     self);
+    self->zoom_level = get_default_zoom_level ();
+    g_action_group_change_action_state (self->action_group,
+                                        "zoom-to-level",
+                                        g_variant_new_int32 (self->zoom_level));
+
+    self->view_ui = nautilus_view_icon_ui_new ();
+    gtk_widget_show (self->view_ui);
+    self->model = g_list_store_new (NAUTILUS_TYPE_VIEW_ITEM_MODEL);
+    self->view_icon = g_themed_icon_new ("view-grid-symbolic");
+    gtk_widget_show (self->view_icon);
+
+    content_widget = nautilus_files_view_get_content_widget (NAUTILUS_FILES_VIEW (self));
+    gtk_container_add (GTK_CONTAINER (content_widget), self->view_ui);
+}
+
+static void
+nautilus_view_icon_controller_class_init (NautilusViewIconControllerClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  NautilusFilesViewClass *files_view_class = NAUTILUS_FILES_VIEW_CLASS (klass);
+
+  object_class->finalize = finalize;
+  object_class->get_property = get_property;
+  object_class->set_property = set_property;
+  object_class->constructed = constructed;
+
+    files_view_class->add_files = real_add_files;
+    files_view_class->begin_loading = real_begin_loading;
+    files_view_class->bump_zoom_level = real_bump_zoom_level;
+    files_view_class->can_zoom_in = real_can_zoom_in;
+    files_view_class->can_zoom_out = real_can_zoom_out;
+    files_view_class->click_policy_changed = real_click_policy_changed;
+    files_view_class->clear = real_clear;
+    files_view_class->file_changed = real_file_changed;
+    files_view_class->get_selection = real_get_selection;
+    files_view_class->get_selection_for_file_transfer = real_get_selection_for_file_transfer;
+    files_view_class->is_empty = real_is_empty;
+    files_view_class->remove_file = real_remove_file;
+    files_view_class->update_actions_state = real_update_actions_state;
+    files_view_class->reveal_selection = real_reveal_selection;
+    files_view_class->select_all = real_select_all;
+    files_view_class->set_selection = real_set_selection;
+    files_view_class->compare_files = real_compare_files;
+    files_view_class->sort_directories_first_changed = real_sort_directories_first_changed;
+    files_view_class->end_file_changes = real_end_file_changes;
+    files_view_class->using_manual_layout = real_using_manual_layout;
+    files_view_class->end_loading = real_end_loading;
+    files_view_class->get_view_id = real_get_view_id;
+    files_view_class->get_first_visible_file = real_get_first_visible_file;
+    files_view_class->scroll_to_file = real_scroll_to_file;
+    files_view_class->get_icon = real_get_icon;
+    files_view_class->select_first = real_select_first;
+    files_view_class->restore_standard_zoom_level = real_restore_standard_zoom_level;
+    files_view_class->get_zoom_level_percentage = real_get_zoom_level_percentage;
+}
+
+static void
+nautilus_view_icon_controller_init (NautilusViewIconController *self)
+{
+}
+
+NautilusViewIconController *
+nautilus_view_icon_controller_new (NautilusWindowSlot *slot)
+{
+  return g_object_new (NAUTILUS_TYPE_VIEW_ICON_CONTROLLER,
+                       "window-slot", slot,
+                       NULL);
+}
+
+GListModel *
+nautilus_view_icon_controller_get_model (NautilusViewIconController *self)
+{
+    return self->model;
+}
+
diff --git a/src/nautilus-view-icon-controller.h b/src/nautilus-view-icon-controller.h
new file mode 100644
index 0000000..c713633
--- /dev/null
+++ b/src/nautilus-view-icon-controller.h
@@ -0,0 +1,23 @@
+#ifndef NAUTILUS_VIEW_ICON_CONTROLLER_H
+#define NAUTILUS_VIEW_ICON_CONTROLLER_H
+
+#include <glib.h>
+#include <gtk/gtk.h>
+
+#include "nautilus-files-view.h"
+#include "nautilus-window-slot.h"
+
+G_BEGIN_DECLS
+
+#define NAUTILUS_TYPE_VIEW_ICON_CONTROLLER (nautilus_view_icon_controller_get_type())
+
+G_DECLARE_FINAL_TYPE (NautilusViewIconController, nautilus_view_icon_controller, NAUTILUS, 
VIEW_ICON_CONTROLLER, NautilusFilesView)
+
+NautilusViewIconController *nautilus_view_icon_controller_new (NautilusWindowSlot *slot);
+
+GListModel * nautilus_view_icon_controller_get_model (NautilusViewIconController *self);
+
+G_END_DECLS
+
+#endif /* NAUTILUS_VIEW_ICON_CONTROLLER_H */
+
diff --git a/src/nautilus-view-icon-item-ui.c b/src/nautilus-view-icon-item-ui.c
new file mode 100644
index 0000000..82bf88d
--- /dev/null
+++ b/src/nautilus-view-icon-item-ui.c
@@ -0,0 +1,261 @@
+#include "nautilus-view-icon-item-ui.h"
+#include "nautilus-view-item-model.h"
+#include "nautilus-container-max-width.h"
+
+struct _NautilusViewIconItemUi
+{
+  GtkFlowBoxChild parent_instance;
+
+  NautilusViewItemModel *model;
+
+  NautilusContainerMaxWidth *item_container;
+  GtkBox *icon;
+  GtkLabel *label;
+};
+
+G_DEFINE_TYPE (NautilusViewIconItemUi, nautilus_view_icon_item_ui, GTK_TYPE_FLOW_BOX_CHILD)
+
+enum {
+  PROP_0,
+  PROP_MODEL,
+  N_PROPS
+};
+
+static GParamSpec *properties [N_PROPS];
+
+static GtkWidget *
+create_icon (NautilusViewIconItemUi *self)
+{
+    NautilusFileIconFlags flags;
+    g_autoptr (GdkPixbuf) icon_pixbuf;
+    GtkImage *icon;
+    GtkWidget *fixed_height_box;
+    GtkStyleContext *style_context;
+    NautilusFile *file;
+    guint icon_size;
+
+    file = nautilus_view_item_model_get_file (self->model);
+    icon_size = nautilus_view_item_model_get_icon_size (self->model);
+    flags = NAUTILUS_FILE_ICON_FLAGS_USE_THUMBNAILS |
+            NAUTILUS_FILE_ICON_FLAGS_FORCE_THUMBNAIL_SIZE |
+            NAUTILUS_FILE_ICON_FLAGS_USE_EMBLEMS |
+            NAUTILUS_FILE_ICON_FLAGS_USE_ONE_EMBLEM;
+
+    icon_pixbuf = nautilus_file_get_icon_pixbuf (file, icon_size,
+                                                 TRUE, 1, flags);
+    icon = gtk_image_new_from_pixbuf (icon_pixbuf);
+    gtk_widget_set_hexpand (icon, TRUE);
+    gtk_widget_set_vexpand (icon, TRUE);
+    gtk_widget_set_valign (icon, GTK_ALIGN_CENTER);
+    gtk_widget_set_halign (icon, GTK_ALIGN_CENTER);
+
+    fixed_height_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+    gtk_widget_set_valign (fixed_height_box, GTK_ALIGN_CENTER);
+    gtk_widget_set_halign (fixed_height_box, GTK_ALIGN_CENTER);
+    gtk_widget_set_size_request (fixed_height_box, icon_size, icon_size);
+
+    if (nautilus_can_thumbnail (file) &&
+        nautilus_file_should_show_thumbnail (file))
+    {
+        style_context = gtk_widget_get_style_context (fixed_height_box);
+        gtk_style_context_add_class (style_context, "icon-background");
+    }
+
+    gtk_box_pack_start (fixed_height_box, icon, FALSE, FALSE, 0);
+
+    return fixed_height_box;
+}
+
+static void
+update_icon (NautilusViewIconItemUi *self)
+{
+    GtkWidget *box;
+    NautilusFile *file;
+    guint icon_size;
+
+    icon_size = nautilus_view_item_get_icon_size (self->model);
+    nautilus_container_max_width_set_max_width (NAUTILUS_CONTAINER_MAX_WIDTH (self->item_container),
+                                                icon_size);
+    box = gtk_bin_get_child (GTK_BIN (self->item_container));
+    if (self->icon)
+    {
+        gtk_container_remove (GTK_CONTAINER (box), self->icon);
+    }
+    self->icon = create_icon (self);
+    gtk_widget_show_all (self->icon);
+    gtk_box_pack_start (box, self->icon, FALSE, FALSE, 0);
+}
+
+static void
+on_view_item_file_changed (GObject    *object,
+                           GParamSpec *pspec,
+                           gpointer    user_data)
+{
+  NautilusViewIconItemUi *self = NAUTILUS_VIEW_ICON_ITEM_UI (user_data);
+  NautilusFile *file;
+
+  file = nautilus_view_item_get_file (self->model);
+
+  if (self->icon)
+  {
+    update_icon (self);
+  }
+
+  if (self->label)
+  {
+      gtk_label_set_text (self->label,
+                          nautilus_file_get_display_name (file));
+  }
+}
+
+static void
+on_view_item_size_changed (GObject    *object,
+                           GParamSpec *pspec,
+                           gpointer    user_data)
+{
+  NautilusViewIconItemUi *self = NAUTILUS_VIEW_ICON_ITEM_UI (user_data);
+
+  if (self->icon)
+  {
+    update_icon (self);
+  }
+}
+
+static void
+constructed (NautilusViewIconItemUi *self)
+{
+    GtkBox *container;
+    NautilusContainerMaxWidth *item_container;
+    GtkLabel *label;
+    GtkWidget *icon;
+    GtkStyleContext *style_context;
+    NautilusFile *file;
+    guint *icon_size;
+
+    file = nautilus_view_item_model_get_file (self->model);
+    icon_size = nautilus_view_item_model_get_icon_size (self->model);
+    container = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+    self->item_container = nautilus_container_max_width_new ();
+
+    self->icon = create_icon (self);
+    gtk_box_pack_start (container, self->icon, FALSE, FALSE, 0);
+
+    label = gtk_label_new (nautilus_file_get_display_name (file));
+    gtk_widget_show (label);
+    gtk_label_set_ellipsize (label, PANGO_ELLIPSIZE_END);
+    gtk_label_set_line_wrap (label, TRUE);
+    gtk_label_set_line_wrap_mode (label, PANGO_WRAP_WORD_CHAR);
+    gtk_label_set_lines (label, 4);
+    gtk_label_set_justify (label, GTK_JUSTIFY_CENTER);
+    gtk_widget_set_valign (GTK_WIDGET (label), GTK_ALIGN_START);
+    gtk_box_pack_end (container, label, TRUE, TRUE, 0);
+
+    style_context = gtk_widget_get_style_context (container);
+    gtk_style_context_add_class (style_context, "icon-item-background");
+
+    gtk_widget_set_valign (container, GTK_ALIGN_START);
+    gtk_widget_set_halign (container, GTK_ALIGN_CENTER);
+
+    gtk_container_add (self->item_container, container);
+    nautilus_container_max_width_set_max_width (NAUTILUS_CONTAINER_MAX_WIDTH (self->item_container),
+                                                icon_size);
+
+    gtk_container_add (GTK_CONTAINER (self), self->item_container);
+    gtk_widget_show_all (self->item_container);
+
+    g_signal_connect (self->model, "notify::icon-size",
+                      on_view_item_size_changed, self);
+    g_signal_connect (self->model, "notify::file",
+                      on_view_item_file_changed, self);
+}
+
+static void
+nautilus_view_icon_item_ui_finalize (GObject *object)
+{
+  NautilusViewIconItemUi *self = (NautilusViewIconItemUi *)object;
+
+  G_OBJECT_CLASS (nautilus_view_icon_item_ui_parent_class)->finalize (object);
+}
+
+static void
+nautilus_view_icon_item_ui_get_property (GObject    *object,
+                                         guint       prop_id,
+                                         GValue     *value,
+                                         GParamSpec *pspec)
+{
+  NautilusViewIconItemUi *self = NAUTILUS_VIEW_ICON_ITEM_UI (object);
+
+  switch (prop_id)
+    {
+        case PROP_MODEL:
+        {
+            g_value_set_object (value, self->model);
+        }
+        break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+set_model (NautilusViewIconItemUi *self,
+           NautilusViewItemModel  *model)
+{
+    self->model = g_object_ref (model);
+}
+
+static void
+nautilus_view_icon_item_ui_set_property (GObject      *object,
+                                         guint         prop_id,
+                                         const GValue *value,
+                                         GParamSpec   *pspec)
+{
+  NautilusViewIconItemUi *self = NAUTILUS_VIEW_ICON_ITEM_UI (object);
+
+  switch (prop_id)
+    {
+        case PROP_MODEL:
+        {
+            set_model (self, g_value_get_object (value));
+        }
+        break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+nautilus_view_icon_item_ui_class_init (NautilusViewIconItemUiClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->finalize = nautilus_view_icon_item_ui_finalize;
+  object_class->get_property = nautilus_view_icon_item_ui_get_property;
+  object_class->set_property = nautilus_view_icon_item_ui_set_property;
+
+    g_object_class_install_property (object_class,
+                                     PROP_MODEL,
+                                     g_param_spec_object ("model",
+                                                          "Item model",
+                                                          "The item model that this UI reprensents",
+                                                          NAUTILUS_TYPE_VIEW_ITEM_MODEL,
+                                                          G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+}
+
+static void
+nautilus_view_icon_item_ui_init (NautilusViewIconItemUi *self)
+{
+}
+
+NautilusViewIconItemUi *
+nautilus_view_icon_item_ui_new (NautilusViewItemModel *model)
+{
+  return g_object_new (NAUTILUS_TYPE_VIEW_ICON_ITEM_UI,
+                       "model", model);
+}
+
+NautilusViewItemModel *
+nautilus_view_icon_item_ui_get_model (NautilusViewIconItemUi *self)
+{
+    return self->model;
+}
diff --git a/src/nautilus-view-icon-item-ui.h b/src/nautilus-view-icon-item-ui.h
new file mode 100644
index 0000000..064e9a9
--- /dev/null
+++ b/src/nautilus-view-icon-item-ui.h
@@ -0,0 +1,22 @@
+#ifndef NAUTILUS_VIEW_ICON_ITEM_UI_H
+#define NAUTILUS_VIEW_ICON_ITEM_UI_H
+
+#include <glib.h>
+#include <gtk/gtk.h>
+
+#include "nautilus-view-item-model.h"
+
+G_BEGIN_DECLS
+
+#define NAUTILUS_TYPE_VIEW_ICON_ITEM_UI (nautilus_view_icon_item_ui_get_type())
+
+G_DECLARE_FINAL_TYPE (NautilusViewIconItemUi, nautilus_view_icon_item_ui, NAUTILUS, VIEW_ICON_ITEM_UI, 
GtkFlowBoxChild)
+
+NautilusViewIconItemUi *nautilus_view_icon_item_ui_new (NautilusViewItemModel *item_model);
+
+NautilusViewItemModel *nautilus_view_icon_item_ui_get_model (NautilusViewIconItemUi *self);
+
+G_END_DECLS
+
+#endif /* NAUTILUS_VIEW_ICON_ITEM_UI_H */
+
diff --git a/src/nautilus-view-icon-ui.c b/src/nautilus-view-icon-ui.c
new file mode 100644
index 0000000..88c2401
--- /dev/null
+++ b/src/nautilus-view-icon-ui.c
@@ -0,0 +1,110 @@
+/* nautilus-view-icon-ui.c
+ *
+ * Copyright (C) 2016 Carlos Soriano <csoriano gnome org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <glib.h>
+
+#include "nautilus-view-icon-ui.h"
+#include "nautilus-view-icon-item-ui.h"
+#include "nautilus-view-icon-controller.h"
+#include "nautilus-files-view.h"
+#include "nautilus-file.h"
+#include "nautilus-directory.h"
+#include "nautilus-global-preferences.h"
+
+struct _NautilusViewIconUi
+{
+    GtkWidget *flow_box;
+
+    NautilusViewIconController *controller;
+} ;
+
+G_DEFINE_TYPE (NautilusViewIconUi, nautilus_view_icon_ui, GTK_TYPE_FLOW_BOX)
+
+static GtkWidget *
+create_widget_func (gpointer item,
+                    gpointer user_data)
+{
+    NautilusViewIconUi *self = NAUTILUS_VIEW_ICON_UI (user_data);
+    NautilusViewItemModel *item_model = NAUTILUS_VIEW_ITEM_MODEL (item);
+    NautilusViewIconItemUi *child;
+
+    child = nautilus_view_icon_item_ui_new (item_model);
+    gtk_widget_show (child);
+
+    return GTK_WIDGET (child);
+}
+
+static void
+on_child_activated (GtkFlowBox      *flow_box,
+                    GtkFlowBoxChild *child,
+                    gpointer         user_data)
+{
+    NautilusViewIconUi *self = NAUTILUS_VIEW_ICON_UI (user_data);
+    NautilusViewItemModel *item_model;
+    NautilusFile *file;
+    g_autoptr (GList) list = NULL;
+
+    item_model = nautilus_view_icon_item_ui_get_model (child);
+    file = nautilus_view_item_model_get_file (item_model);
+    list = g_list_append (list, file);
+
+    nautilus_files_view_activate_files (NAUTILUS_FILES_VIEW (self->controller), list, 0, TRUE);
+}
+
+NautilusViewIconUi *
+nautilus_view_icon_ui_new (void)
+{
+    return g_object_new (NAUTILUS_TYPE_VIEW_ICON_UI, NULL);
+}
+
+static void
+nautilus_view_icon_ui_finalize (GObject *object)
+{
+    G_OBJECT_CLASS (nautilus_view_icon_ui_parent_class)->finalize (object);
+}
+
+static void
+nautilus_view_icon_ui_class_init (NautilusViewIconUiClass *klass)
+{
+    GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+    object_class->finalize = nautilus_view_icon_ui_finalize;
+}
+
+static void
+nautilus_view_icon_ui_init (NautilusViewIconUi *self)
+{
+    gtk_flow_box_set_activate_on_single_click (GTK_FLOW_BOX (self), FALSE);
+    gtk_flow_box_set_max_children_per_line (GTK_FLOW_BOX (self), 20);
+    gtk_flow_box_set_selection_mode (GTK_FLOW_BOX (self), GTK_SELECTION_MULTIPLE);
+    gtk_flow_box_set_homogeneous (GTK_FLOW_BOX (self), FALSE);
+    gtk_flow_box_set_row_spacing (GTK_FLOW_BOX (self), 4);
+    gtk_flow_box_set_column_spacing (GTK_FLOW_BOX (self), 8);
+    gtk_widget_set_valign (GTK_WIDGET (self), GTK_ALIGN_START);
+    gtk_widget_set_margin_top (GTK_WIDGET (self), 10);
+    gtk_widget_set_margin_start (GTK_WIDGET (self), 10);
+    gtk_widget_set_margin_bottom (GTK_WIDGET (self), 10);
+    gtk_widget_set_margin_end (GTK_WIDGET (self), 10);
+
+    gtk_flow_box_bind_model (GTK_FLOW_BOX (self),
+                             nautilus_view_icon_controller_get_model (self->controller),
+                             create_widget_func, self, NULL);
+
+    g_signal_connect (self, "child-activated", (GCallback) on_child_activated, self);
+}
diff --git a/src/nautilus-icon-view.h b/src/nautilus-view-icon-ui.h
similarity index 61%
rename from src/nautilus-icon-view.h
rename to src/nautilus-view-icon-ui.h
index 7063ba2..cb64f8b 100644
--- a/src/nautilus-icon-view.h
+++ b/src/nautilus-view-icon-ui.h
@@ -1,4 +1,4 @@
-/* nautilus-icon-view.h
+/* nautilus-view-icon-ui.h
  *
  * Copyright (C) 2016 Carlos Soriano <csoriano gnome org>
  *
@@ -15,28 +15,21 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
-#ifndef NAUTILUS_ICON_VIEW_H
-#define NAUTILUS_ICON_VIEW_H
+#ifndef NAUTILUS_VIEW_ICON_UI_H
+#define NAUTILUS_VIEW_ICON_UI_H
 
 #include <glib.h>
 #include <gtk/gtk.h>
-#include "nautilus-files-view.h"
-#include "nautilus-window-slot.h"
 
 G_BEGIN_DECLS
 
-#define NAUTILUS_TYPE_ICON_VIEW (nautilus_icon_view_get_type())
+#define NAUTILUS_TYPE_VIEW_ICON_UI (nautilus_view_icon_ui_get_type())
 
-G_DECLARE_DERIVABLE_TYPE (NautilusIconView, nautilus_icon_view, NAUTILUS, ICON_VIEW, NautilusFilesView)
+G_DECLARE_FINAL_TYPE (NautilusViewIconUi, nautilus_view_icon_ui, NAUTILUS, VIEW_ICON_UI, GtkFlowBox)
 
-struct _NautilusIconViewClass
-{
-  NautilusFilesViewClass parent;
-};
-
-NautilusIconView *nautilus_icon_view_new (NautilusWindowSlot *slot);
+NautilusViewIconUi *nautilus_view_icon_ui_new (void);
 
 G_END_DECLS
 
-#endif /* NAUTILUS_ICON_VIEW_H */
+#endif /* NAUTILUS_VIEW_ICON_UI_H */
 
diff --git a/src/nautilus-view-item-model.c b/src/nautilus-view-item-model.c
new file mode 100644
index 0000000..da90125
--- /dev/null
+++ b/src/nautilus-view-item-model.c
@@ -0,0 +1,165 @@
+#include "nautilus-view-item-model.h"
+#include "nautilus-file.h"
+
+struct _NautilusViewItemModel
+{
+    GObject parent_instance;
+    guint icon_size;
+    NautilusFile *file;
+    GtkLabel *label;
+};
+
+G_DEFINE_TYPE (NautilusViewItemModel, nautilus_view_item_model, G_TYPE_OBJECT)
+
+enum
+{
+    PROP_0,
+    PROP_FILE,
+    PROP_ICON_SIZE,
+    N_PROPS
+};
+
+static void
+nautilus_view_item_model_finalize (GObject *object)
+{
+    G_OBJECT_CLASS (nautilus_view_item_model_parent_class)->finalize (object);
+}
+
+static void
+nautilus_view_item_model_get_property (GObject    *object,
+                                      guint       prop_id,
+                                      GValue     *value,
+                                      GParamSpec *pspec)
+{
+    NautilusViewItemModel *self = NAUTILUS_VIEW_ITEM_MODEL (object);
+
+    switch (prop_id)
+    {
+        case PROP_FILE:
+        {
+            g_value_set_object (value, self->file);
+        }
+        break;
+
+        case PROP_ICON_SIZE:
+        {
+            g_value_set_int (value, self->icon_size);
+        }
+        break;
+
+        default:
+        {
+            G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        }
+    }
+}
+
+static void
+nautilus_view_item_model_set_property (GObject      *object,
+                                      guint         prop_id,
+                                      const GValue *value,
+                                      GParamSpec   *pspec)
+{
+    NautilusViewItemModel *self = NAUTILUS_VIEW_ITEM_MODEL (object);
+
+    switch (prop_id)
+    {
+        case PROP_FILE:
+        {
+            nautilus_view_item_model_set_file (self, g_value_get_object (value));
+        }
+        break;
+
+        case PROP_ICON_SIZE:
+        {
+            nautilus_view_item_model_set_icon_size (self, g_value_get_int (value));
+        }
+        break;
+
+        default:
+        {
+            G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        }
+    }
+}
+
+static void
+nautilus_view_item_model_init (NautilusViewItemModel *self)
+{
+}
+
+static void
+nautilus_view_item_model_class_init (NautilusViewItemModelClass *klass)
+{
+    GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+    object_class->finalize = nautilus_view_item_model_finalize;
+    object_class->get_property = nautilus_view_item_model_get_property;
+    object_class->set_property = nautilus_view_item_model_set_property;
+
+    g_object_class_install_property (object_class,
+                                     PROP_ICON_SIZE,
+                                     g_param_spec_int ("icon-size",
+                                                       "Icon size",
+                                                       "The size in pixels of the icon",
+                                                       NAUTILUS_CANVAS_ICON_SIZE_SMALL,
+                                                       NAUTILUS_CANVAS_ICON_SIZE_LARGER,
+                                                       NAUTILUS_CANVAS_ICON_SIZE_LARGE,
+                                                       G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+    g_object_class_install_property (object_class,
+                                     PROP_FILE,
+                                     g_param_spec_object ("file",
+                                                          "File",
+                                                          "The file the icon item represents",
+                                                          NAUTILUS_TYPE_FILE,
+                                                          G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+}
+
+NautilusViewItemModel *
+nautilus_view_item_model_new (NautilusFile *file,
+                             guint         icon_size)
+{
+    return g_object_new (NAUTILUS_TYPE_VIEW_ITEM_MODEL,
+                         "file", file,
+                         "icon-size", icon_size,
+                         NULL);
+}
+
+guint
+nautilus_view_item_model_get_icon_size (NautilusViewItemModel *self)
+{
+    g_return_if_fail (NAUTILUS_IS_VIEW_ITEM_MODEL (self));
+
+    return self->icon_size;
+}
+
+void
+nautilus_view_item_model_set_icon_size (NautilusViewItemModel *self,
+                                       guint                 icon_size)
+{
+  g_return_if_fail (NAUTILUS_IS_VIEW_ITEM_MODEL (self));
+
+  self->icon_size = icon_size;
+
+  g_object_notify (G_OBJECT (self), "icon-size");
+}
+
+NautilusFile *
+nautilus_view_item_model_get_file (NautilusViewItemModel *self)
+{
+    g_return_if_fail (NAUTILUS_IS_VIEW_ITEM_MODEL (self));
+
+    return self->file;
+}
+
+void
+nautilus_view_item_model_set_file (NautilusViewItemModel *self,
+                                  NautilusFile         *file)
+{
+  g_return_if_fail (NAUTILUS_IS_VIEW_ITEM_MODEL (self));
+
+  g_clear_object (&self->file);
+  self->file = g_object_ref (file);
+
+  g_object_notify (G_OBJECT (self), "file");
+}
diff --git a/src/nautilus-view-item-model.h b/src/nautilus-view-item-model.h
new file mode 100644
index 0000000..71558a5
--- /dev/null
+++ b/src/nautilus-view-item-model.h
@@ -0,0 +1,31 @@
+#ifndef NAUTILUS_VIEW_ITEM_MODEL_H
+#define NAUTILUS_VIEW_ITEM_MODEL_H
+
+#include <glib.h>
+#include <gtk/gtk.h>
+
+#include "nautilus-file.h"
+
+G_BEGIN_DECLS
+
+#define NAUTILUS_TYPE_VIEW_ITEM_MODEL (nautilus_view_item_model_get_type())
+
+G_DECLARE_FINAL_TYPE (NautilusViewItemModel, nautilus_view_item_model, NAUTILUS, VIEW_ITEM_MODEL, GObject)
+
+NautilusViewItemModel * nautilus_view_item_model_new (NautilusFile *file,
+                                                      guint         icon_size);
+
+void nautilus_view_item_model_set_icon_size (NautilusViewItemModel *item,
+                                             guint                 icon_size);
+
+guint nautilus_view_item_model_get_icon_size (NautilusViewItemModel *self);
+
+void nautilus_view_item_model_set_file (NautilusViewItemModel *item,
+                                        NautilusFile         *file);
+
+NautilusFile * nautilus_view_item_model_get_file (NautilusViewItemModel *item);
+
+G_END_DECLS
+
+#endif /* NAUTILUS_VIEW_ITEM_MODEL_H */
+



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]