[nautilus/wip/antoniof/flow-box-preparation: 4/4] view-icon-controller: Implement captions




commit a777e312097638bb770e5e2905209f4e0807e5f9
Author: António Fernandes <antoniof gnome org>
Date:   Fri Dec 10 20:30:39 2021 +0000

    view-icon-controller: Implement captions
    
    For feature parity with the canvas view.

 src/nautilus-view-icon-controller.c            | 68 +++++++++++++++++++++++++-
 src/nautilus-view-icon-item-ui.c               | 45 +++++++++++++++++
 src/nautilus-view-icon-item-ui.h               | 10 ++++
 src/resources/ui/nautilus-view-icon-item-ui.ui | 42 ++++++++++++++++
 4 files changed, 164 insertions(+), 1 deletion(-)
---
diff --git a/src/nautilus-view-icon-controller.c b/src/nautilus-view-icon-controller.c
index 7cb150e7c..58d71b7d9 100644
--- a/src/nautilus-view-icon-controller.c
+++ b/src/nautilus-view-icon-controller.c
@@ -19,6 +19,7 @@ struct _NautilusViewIconController
     GIcon *view_icon;
     GActionGroup *action_group;
     gint zoom_level;
+    GQuark caption_attributes[NAUTILUS_VIEW_ICON_N_CAPTIONS];
 
     gboolean single_click_mode;
     gboolean activate_on_release;
@@ -562,6 +563,44 @@ get_default_zoom_level (void)
     return default_zoom_level;
 }
 
+static void
+set_captions_from_preferences (NautilusViewIconController *self)
+{
+    g_auto (GStrv) value = NULL;
+    gint n_captions_for_zoom_level;
+
+    value = g_settings_get_strv (nautilus_icon_view_preferences,
+                                 NAUTILUS_PREFERENCES_ICON_VIEW_CAPTIONS);
+
+    /* Set a celling on the number of captions depending on the zoom level. */
+    n_captions_for_zoom_level = G_N_ELEMENTS (self->caption_attributes);
+    if (self->zoom_level < NAUTILUS_CANVAS_ZOOM_LEVEL_LARGE)
+    {
+        n_captions_for_zoom_level = MIN (1, n_captions_for_zoom_level);
+    }
+    else if (self->zoom_level == NAUTILUS_CANVAS_ZOOM_LEVEL_LARGE)
+    {
+        n_captions_for_zoom_level = MIN (2, n_captions_for_zoom_level);
+    }
+
+    /* Reset array to zeros beforehand, as we may not refill all elements. */
+    memset (&self->caption_attributes, 0, sizeof (self->caption_attributes));
+    for (gint i = 0, quark_i = 0;
+         value[i] != NULL && quark_i < n_captions_for_zoom_level;
+         i++)
+    {
+        if (g_strcmp0 (value[i], "none") == 0)
+        {
+            continue;
+        }
+
+        /* Convert to quarks in advance, otherwise each NautilusFile attribute
+         * getter would call g_quark_from_string() once for each file. */
+        self->caption_attributes[quark_i] = g_quark_from_string (value[i]);
+        quark_i++;
+    }
+}
+
 static void
 set_icon_size (NautilusViewIconController *self,
                gint                        icon_size)
@@ -583,6 +622,11 @@ set_zoom_level (NautilusViewIconController *self,
 {
     self->zoom_level = new_level;
 
+    /* The zoom level may change how many captions are allowed. Update it before
+     * setting the icon size, under the assumption that NautilusViewIconItemUi
+     * updates captions whenever the icon size is set*/
+    set_captions_from_preferences (self);
+
     set_icon_size (self, get_icon_size_for_zoom_level (new_level));
 
     nautilus_files_view_update_toolbar_menus (NAUTILUS_FILES_VIEW (self));
@@ -1134,6 +1178,16 @@ action_zoom_to_level (GSimpleAction *action,
     }
 }
 
+static void
+on_captions_preferences_changed (NautilusViewIconController *self)
+{
+    set_captions_from_preferences (self);
+
+    /* Hack: this relies on the assumption that NautilusViewIconItemUi updates
+     * captions whenever the icon size is set (even if it's the same value). */
+    set_icon_size (self, get_icon_size_for_zoom_level (self->zoom_level));
+}
+
 static void
 on_default_sort_order_changed (NautilusViewIconController *self)
 {
@@ -1223,7 +1277,13 @@ static void
 setup_item_ui (GtkWidget **child,
                gpointer    user_data)
 {
-    *child = GTK_WIDGET (nautilus_view_icon_item_ui_new ());
+    NautilusViewIconController *self = NAUTILUS_VIEW_ICON_CONTROLLER (user_data);
+    NautilusViewIconItemUi *item_ui;
+
+    item_ui = nautilus_view_icon_item_ui_new ();
+    nautilus_view_item_ui_set_caption_attributes (item_ui, self->caption_attributes);
+
+    *child = GTK_WIDGET (item_ui);
     gtk_widget_show_all (*child);
 }
 
@@ -1400,6 +1460,12 @@ nautilus_view_icon_controller_init (NautilusViewIconController *self)
                               "changed::" NAUTILUS_PREFERENCES_DEFAULT_SORT_IN_REVERSE_ORDER,
                               G_CALLBACK (on_default_sort_order_changed),
                               self);
+
+    set_captions_from_preferences (self);
+    g_signal_connect_swapped (nautilus_icon_view_preferences,
+                              "changed::" NAUTILUS_PREFERENCES_ICON_VIEW_CAPTIONS,
+                              G_CALLBACK (on_captions_preferences_changed),
+                              self);
 }
 
 NautilusViewIconController *
diff --git a/src/nautilus-view-icon-item-ui.c b/src/nautilus-view-icon-item-ui.c
index 8b8c4a73d..db9c88f12 100644
--- a/src/nautilus-view-icon-item-ui.c
+++ b/src/nautilus-view-icon-item-ui.c
@@ -8,10 +8,14 @@ struct _NautilusViewIconItemUi
     GtkFlowBoxChild parent_instance;
 
     NautilusViewItemModel *model;
+    GQuark *caption_attributes;
 
     GtkWidget *fixed_height_box;
     GtkWidget *icon;
     GtkWidget *label;
+    GtkWidget *first_caption;
+    GtkWidget *second_caption;
+    GtkWidget *third_caption;
 };
 
 G_DEFINE_TYPE (NautilusViewIconItemUi, nautilus_view_icon_item_ui, GTK_TYPE_FLOW_BOX_CHILD)
@@ -58,6 +62,34 @@ update_icon (NautilusViewIconItemUi *self)
     }
 }
 
+static void
+update_captions (NautilusViewIconItemUi *self)
+{
+    NautilusFile *file;
+    GtkWidget * const caption_labels[] = {
+        self->first_caption,
+        self->second_caption,
+        self->third_caption
+    };
+    G_STATIC_ASSERT (G_N_ELEMENTS (caption_labels) == NAUTILUS_VIEW_ICON_N_CAPTIONS);
+
+    file = nautilus_view_item_model_get_file (self->model);
+    for (guint i = 0; i < NAUTILUS_VIEW_ICON_N_CAPTIONS; i++)
+    {
+        GQuark attribute_q = self->caption_attributes[i];
+        gboolean show_caption;
+
+        show_caption = (attribute_q != 0);
+        gtk_widget_set_visible (caption_labels[i], show_caption);
+        if (show_caption)
+        {
+            g_autofree gchar *string = NULL;
+            string = nautilus_file_get_string_attribute_q (file, attribute_q);
+            gtk_label_set_text (GTK_LABEL (caption_labels[i]), string);
+        }
+    }
+}
+
 static void
 on_file_changed (NautilusViewIconItemUi *self)
 {
@@ -69,6 +101,7 @@ on_file_changed (NautilusViewIconItemUi *self)
 
     gtk_label_set_text (GTK_LABEL (self->label),
                         nautilus_file_get_display_name (file));
+    update_captions (self);
 }
 
 static void
@@ -79,6 +112,7 @@ on_view_item_size_changed (GObject    *object,
     NautilusViewIconItemUi *self = NAUTILUS_VIEW_ICON_ITEM_UI (user_data);
 
     update_icon (self);
+    update_captions (self);
 }
 
 static void
@@ -144,6 +178,7 @@ set_model (NautilusViewIconItemUi *self,
     update_icon (self);
     gtk_label_set_text (GTK_LABEL (self->label),
                         nautilus_file_get_display_name (file));
+    update_captions (self);
 
     g_signal_connect (self->model, "notify::icon-size",
                       (GCallback) on_view_item_size_changed, self);
@@ -195,6 +230,9 @@ nautilus_view_icon_item_ui_class_init (NautilusViewIconItemUiClass *klass)
     gtk_widget_class_bind_template_child (widget_class, NautilusViewIconItemUi, fixed_height_box);
     gtk_widget_class_bind_template_child (widget_class, NautilusViewIconItemUi, icon);
     gtk_widget_class_bind_template_child (widget_class, NautilusViewIconItemUi, label);
+    gtk_widget_class_bind_template_child (widget_class, NautilusViewIconItemUi, first_caption);
+    gtk_widget_class_bind_template_child (widget_class, NautilusViewIconItemUi, second_caption);
+    gtk_widget_class_bind_template_child (widget_class, NautilusViewIconItemUi, third_caption);
 }
 
 static void
@@ -228,3 +266,10 @@ nautilus_view_icon_item_ui_set_model (NautilusViewIconItemUi *self,
 {
     g_object_set (self, "model", model, NULL);
 }
+
+void
+nautilus_view_item_ui_set_caption_attributes (NautilusViewIconItemUi *self,
+                                              GQuark                 *attrs)
+{
+    self->caption_attributes = attrs;
+}
diff --git a/src/nautilus-view-icon-item-ui.h b/src/nautilus-view-icon-item-ui.h
index 5eeea61e6..5caed4700 100644
--- a/src/nautilus-view-icon-item-ui.h
+++ b/src/nautilus-view-icon-item-ui.h
@@ -7,6 +7,14 @@
 
 G_BEGIN_DECLS
 
+enum
+{
+    NAUTILUS_VIEW_ICON_FIRST_CAPTION,
+    NAUTILUS_VIEW_ICON_SECOND_CAPTION,
+    NAUTILUS_VIEW_ICON_THIRD_CAPTION,
+    NAUTILUS_VIEW_ICON_N_CAPTIONS
+};
+
 #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)
@@ -14,5 +22,7 @@ G_DECLARE_FINAL_TYPE (NautilusViewIconItemUi, nautilus_view_icon_item_ui, NAUTIL
 NautilusViewIconItemUi * nautilus_view_icon_item_ui_new (void);
 void nautilus_view_icon_item_ui_set_model (NautilusViewIconItemUi *self,
                                            NautilusViewItemModel  *model);
+void nautilus_view_item_ui_set_caption_attributes (NautilusViewIconItemUi *self,
+                                                   GQuark                 *attrs);
 
 G_END_DECLS
diff --git a/src/resources/ui/nautilus-view-icon-item-ui.ui b/src/resources/ui/nautilus-view-icon-item-ui.ui
index 4a8b7cd22..ba76d24c2 100644
--- a/src/resources/ui/nautilus-view-icon-item-ui.ui
+++ b/src/resources/ui/nautilus-view-icon-item-ui.ui
@@ -44,6 +44,48 @@
                 </attributes>
               </object>
             </child>
+            <child>
+              <object class="GtkLabel" id="first_caption">
+                <property name="ellipsize">end</property>
+                <property name="justify">center</property>
+                <property name="lines">2</property>
+                <property name="max-width-chars">0</property>
+                <property name="wrap">True</property>
+                <property name="wrap-mode">word-char</property>
+                <property name="valign">start</property>
+                <style>
+                  <class name="dim-label"/>
+                </style>
+              </object>
+            </child>
+            <child>
+              <object class="GtkLabel" id="second_caption">
+                <property name="ellipsize">end</property>
+                <property name="justify">center</property>
+                <property name="lines">2</property>
+                <property name="max-width-chars">0</property>
+                <property name="wrap">True</property>
+                <property name="wrap-mode">word-char</property>
+                <property name="valign">start</property>
+                <style>
+                  <class name="dim-label"/>
+                </style>
+              </object>
+            </child>
+            <child>
+              <object class="GtkLabel" id="third_caption">
+                <property name="ellipsize">end</property>
+                <property name="justify">center</property>
+                <property name="lines">2</property>
+                <property name="max-width-chars">0</property>
+                <property name="wrap">True</property>
+                <property name="wrap-mode">word-char</property>
+                <property name="valign">start</property>
+                <style>
+                  <class name="dim-label"/>
+                </style>
+              </object>
+            </child>
           </object>
         </child>
       </object>


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