[gtk/wip/otte/listview: 35/38] demo: Add a file browser demo



commit db6cabd169a44635a79c803811f13f1f50110c95
Author: Benjamin Otte <otte redhat com>
Date:   Fri Oct 18 20:47:48 2019 +0200

    demo: Add a file browser demo

 demos/gtk-demo/demo.gresource.xml      |   4 +
 demos/gtk-demo/listview_filebrowser.c  | 210 +++++++++++++++++++++++++++++++++
 demos/gtk-demo/listview_filebrowser.ui | 196 ++++++++++++++++++++++++++++++
 demos/gtk-demo/meson.build             |   1 +
 4 files changed, 411 insertions(+)
---
diff --git a/demos/gtk-demo/demo.gresource.xml b/demos/gtk-demo/demo.gresource.xml
index 7d94e0462b..3781f72d3a 100644
--- a/demos/gtk-demo/demo.gresource.xml
+++ b/demos/gtk-demo/demo.gresource.xml
@@ -118,6 +118,9 @@
     <file>gnome-fs-directory.png</file>
     <file>gnome-fs-regular.png</file>
   </gresource>
+  <gresource prefix="/listview_filebrowser">
+    <file>listview_filebrowser.ui</file>
+  </gresource>
   <gresource prefix="/listview_weather">
     <file compressed="true">listview_weather.txt</file>
   </gresource>
@@ -200,6 +203,7 @@
     <file>infobar.c</file>
     <file>links.c</file>
     <file>listbox.c</file>
+    <file>listview_filebrowser.c</file>
     <file>listview_settings.c</file>
     <file>listview_weather.c</file>
     <file>list_store.c</file>
diff --git a/demos/gtk-demo/listview_filebrowser.c b/demos/gtk-demo/listview_filebrowser.c
new file mode 100644
index 0000000000..2e9dede012
--- /dev/null
+++ b/demos/gtk-demo/listview_filebrowser.c
@@ -0,0 +1,210 @@
+/* Lists/File browser
+ *
+ * This demo shows off the different layouts that are quickly achievable
+ * with GtkGridView by implementing a file browser with different views.
+ */
+
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+
+static GtkWidget *window = NULL;
+
+/* Create a simple object that holds the data for the different views */
+typedef struct _FileBrowserView FileBrowserView;
+struct _FileBrowserView
+{
+  GObject parent_instance;
+
+  GtkListItemFactory *factory;
+  char *icon_name;
+  GtkOrientation orientation;
+};
+
+enum {
+  PROP_0,
+  PROP_FACTORY,
+  PROP_ICON_NAME,
+  PROP_ORIENTATION,
+
+  N_PROPS
+};
+
+#define FILE_BROWSER_TYPE_VIEW (file_browser_view_get_type ())
+G_DECLARE_FINAL_TYPE (FileBrowserView, file_browser_view, FILE_BROWSER, VIEW, GObject);
+
+G_DEFINE_TYPE (FileBrowserView, file_browser_view, G_TYPE_OBJECT);
+static GParamSpec *properties[N_PROPS] = { NULL, };
+
+static void
+file_browser_view_get_property (GObject    *object,
+                                guint       property_id,
+                                GValue     *value,
+                                GParamSpec *pspec)
+{
+  FileBrowserView *self = FILE_BROWSER_VIEW (object);
+
+  switch (property_id)
+    {
+    case PROP_FACTORY:
+      g_value_set_object (value, self->factory);
+      break;
+
+    case PROP_ICON_NAME:
+      g_value_set_string (value, self->icon_name);
+      break;
+
+    case PROP_ORIENTATION:
+      g_value_set_enum (value, self->orientation);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+    }
+}
+
+static void
+file_browser_view_set_property (GObject      *object,
+                                guint         prop_id,
+                                const GValue *value,
+                                GParamSpec   *pspec)
+{
+  FileBrowserView *self = FILE_BROWSER_VIEW (object);
+
+  switch (prop_id)
+    {
+    case PROP_FACTORY:
+      g_set_object (&self->factory, g_value_get_object (value));
+      break;
+
+    case PROP_ICON_NAME:
+      g_free (self->icon_name);
+      self->icon_name = g_value_dup_string (value);
+      break;
+
+    case PROP_ORIENTATION:
+      self->orientation = g_value_get_enum (value);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+file_browser_view_finalize (GObject *object)
+{
+  FileBrowserView *self = FILE_BROWSER_VIEW (object);
+
+  g_object_unref (self->factory);
+  g_free (self->icon_name);
+
+  G_OBJECT_CLASS (file_browser_view_parent_class)->dispose (object);
+}
+
+static void
+file_browser_view_class_init (FileBrowserViewClass *klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+  gobject_class->get_property = file_browser_view_get_property;
+  gobject_class->set_property = file_browser_view_set_property;
+  gobject_class->finalize = file_browser_view_finalize;
+
+  properties[PROP_FACTORY] =
+    g_param_spec_object ("factory",
+                         "factory",
+                         "factory to use in the main view",
+                         GTK_TYPE_LIST_ITEM_FACTORY,
+                         G_PARAM_READWRITE);
+  properties[PROP_ICON_NAME] =
+    g_param_spec_string ("icon-name",
+                         "icon name",
+                         "icon to display for selecting this view",
+                         NULL,
+                         G_PARAM_READWRITE);
+  properties[PROP_ORIENTATION] =
+    g_param_spec_enum ("orientation",
+                       "orientation",
+                       "orientation of the view",
+                       GTK_TYPE_ORIENTATION,
+                       GTK_ORIENTATION_VERTICAL,
+                       G_PARAM_READWRITE);
+
+  g_object_class_install_properties (gobject_class, N_PROPS, properties);
+}
+
+static void file_browser_view_init (FileBrowserView *self)
+{
+}
+
+static void
+up_clicked_cb (GtkButton        *button,
+               GtkDirectoryList *list)
+{
+  GFile *file;
+
+  file = g_file_get_parent (gtk_directory_list_get_file (list));
+  if (file == NULL)
+    return;
+
+  gtk_directory_list_set_file (list, file);
+}
+
+static void
+view_activated_cb (GtkGridView      *view,
+                   guint             pos,
+                   GtkDirectoryList *list)
+{
+  GFileInfo *info;
+
+  info = g_list_model_get_item (gtk_grid_view_get_model (view), pos);
+  if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY)
+    gtk_directory_list_set_file (list, G_FILE (g_file_info_get_attribute_object (info, "standard::file")));
+
+  g_object_unref (info);
+}
+
+GtkWidget *
+do_listview_filebrowser (GtkWidget *do_widget)
+{
+  if (!window)
+    {
+      GtkWidget *view;
+      GtkBuilder *builder;
+      GtkDirectoryList *dirlist;
+      GFile *file;
+
+      builder = gtk_builder_new_from_resource ("/listview_filebrowser/listview_filebrowser.ui");
+      gtk_builder_add_callback_symbols (builder,
+                                        "up_clicked_cb", G_CALLBACK (up_clicked_cb),
+                                        "view_activated_cb", G_CALLBACK (view_activated_cb),
+                                        NULL);
+      gtk_builder_connect_signals (builder, NULL);
+      window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
+      gtk_window_set_display (GTK_WINDOW (window),
+                              gtk_widget_get_display (do_widget));
+      g_signal_connect (window, "destroy",
+                        G_CALLBACK (gtk_widget_destroyed), &window);
+
+      /* Create the model and fill it with the contents of the current directory */
+      file = g_file_new_for_path (g_get_current_dir ());
+      dirlist = GTK_DIRECTORY_LIST (gtk_builder_get_object (builder, "dirlist"));
+      gtk_directory_list_set_file (dirlist, file);
+      g_object_unref (file);
+
+      /* grab focus in the view */
+      view = GTK_WIDGET (gtk_builder_get_object (builder, "view"));
+      gtk_widget_grab_focus (view);
+
+      g_object_unref (builder);
+    }
+
+  if (!gtk_widget_get_visible (window))
+    gtk_widget_show (window);
+  else
+    gtk_widget_destroy (window);
+
+  return window;
+}
diff --git a/demos/gtk-demo/listview_filebrowser.ui b/demos/gtk-demo/listview_filebrowser.ui
new file mode 100644
index 0000000000..bb8a3c136b
--- /dev/null
+++ b/demos/gtk-demo/listview_filebrowser.ui
@@ -0,0 +1,196 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <object class="GListStore" id="viewlist">
+    <property name="item-type">FileBrowserView</property>
+    <child>
+      <object class="FileBrowserView">
+        <property name="factory">
+          <object class="GtkBuilderListItemFactory">
+            <property name="bytes"><![CDATA[
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <template class="GtkListItem">
+    <child>
+      <object class="GtkBox">
+        <child>
+          <object class="GtkImage">
+            <binding name="gicon">file-info(GtkListItem.item:GFileInfo, "standard::icon", 
object):GIcon</binding>
+          </object>
+        </child>
+        <child>
+          <object class="GtkLabel">
+            <property name="halign">start</property>
+            <binding name="label">file-info(GtkListItem.item:GFileInfo, "standard::display-name", 
string)</binding>
+          </object>
+        </child>
+      </object>
+    </child>
+  </template>
+</interface>
+            ]]></property>
+          </object>
+        </property>
+        <property name="icon-name">view-list-symbolic</property>
+        <property name="orientation">horizontal</property>
+      </object>
+    </child>
+    <child>
+      <object class="FileBrowserView">
+        <property name="icon-name">view-grid-symbolic</property>
+        <property name="factory">
+          <object class="GtkBuilderListItemFactory">
+            <property name="bytes"><![CDATA[
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <template class="GtkListItem">
+    <child>
+      <object class="GtkBox">
+        <property name="orientation">vertical</property>
+        <child>
+          <object class="GtkImage">
+            <property name="icon-size">large</property>
+            <binding name="gicon">file-info(GtkListItem.item:GFileInfo, "standard::icon", 
object):GIcon</binding>
+          </object>
+        </child>
+        <child>
+          <object class="GtkLabel">
+            <property name="wrap">1</property>
+            <property name="wrap-mode">word-char</property>
+            <property name="lines">2</property>
+            <property name="ellipsize">end</property>
+            <property name="width-chars">10</property>
+            <property name="max-width-chars">30</property>
+            <binding name="label">file-info(GtkListItem.item:GFileInfo, "standard::display-name", 
string)</binding>
+          </object>
+        </child>
+      </object>
+    </child>
+  </template>
+</interface>
+            ]]></property>
+          </object>
+        </property>
+        <property name="orientation">vertical</property>
+      </object>
+    </child>
+    <child>
+      <object class="FileBrowserView">
+        <property name="icon-name">view-paged-symbolic</property>
+        <property name="factory">
+          <object class="GtkBuilderListItemFactory">
+            <property name="bytes"><![CDATA[
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <template class="GtkListItem">
+    <child>
+      <object class="GtkBox">
+        <child>
+          <object class="GtkImage">
+            <property name="icon-size">large</property>
+            <binding name="gicon">file-info(GtkListItem.item:GFileInfo, "standard::icon", 
object):GIcon</binding>
+          </object>
+        </child>
+        <child>
+          <object class="GtkBox">
+            <property name="orientation">vertical</property>
+            <child>
+              <object class="GtkLabel">
+                <property name="halign">start</property>
+                <binding name="label">file-info(GtkListItem.item:GFileInfo, "standard::display-name", 
string)</binding>
+              </object>
+            </child>
+            <child>
+              <object class="GtkLabel">
+                <property name="halign">start</property>
+                <binding name="label">file-info(GtkListItem.item:GFileInfo, "standard::size", uint64) + " 
bytes"</binding>
+                <style>
+                  <class name="dim-label"/>
+                </style>
+              </object>
+            </child>
+            <child>
+              <object class="GtkLabel">
+                <property name="halign">start</property>
+                <binding name="label">file-info(GtkListItem.item:GFileInfo, "standard::content-type", 
string)</binding>
+                <style>
+                  <class name="dim-label"/>
+                </style>
+              </object>
+            </child>
+          </object>
+        </child>
+      </object>
+    </child>
+  </template>
+</interface>
+            ]]></property>
+          </object>
+        </property>
+        <property name="orientation">horizontal</property>
+      </object>
+    </child>
+  </object>
+  <object class="GtkDirectoryList" id="dirlist">
+    <property 
name="attributes">standard::name,standard::display-name,standard::icon,standard::size,standard::content-type</property>
+  </object>
+  <object class="GtkWindow" id="window">
+    <property name="title" translatable="yes">File browser</property>
+    <property name="default-width">600</property>
+    <property name="default-height">400</property>
+    <child type="titlebar">
+      <object class="GtkHeaderBar" id="">
+        <property name="show-title-buttons">1</property>
+        <child>
+          <object class="GtkButton">
+            <property name="icon-name">go-up</property>
+            <signal name="clicked" handler="up_clicked_cb" object="dirlist" swapped="no"/>
+          </object>
+        </child>
+        <child type="end">
+          <object class="GtkListView">
+            <property name="valign">center</property>
+            <property name="orientation">horizontal</property>
+            <style>
+              <class name="linked"/>
+            </style>
+            <property name="model">
+              <object class="GtkSingleSelection" id="selected-view">
+                <property name="model">viewlist</property>
+              </object>
+            </property>
+            <property name="factory">
+              <object class="GtkBuilderListItemFactory">
+                <property name="bytes"><![CDATA[
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <template class="GtkListItem">
+    <child>
+      <object class="GtkImage">
+        <binding name="icon-name">GtkListItem.item:FileBrowserView.icon-name</binding>
+      </object>
+    </child>
+  </template>
+</interface>
+                ]]></property>
+              </object>
+            </property>
+          </object>
+        </child>
+      </object>
+    </child>
+    <child>
+      <object class="GtkScrolledWindow">
+        <property name="can-focus">1</property>
+        <child>
+          <object class="GtkGridView" id="view">
+            <property name="model">dirlist</property>
+            <property name="max-columns">15</property>
+            <binding name="factory">selected-view.selected-item:FileBrowserView.factory</binding>
+            <binding name="orientation">selected-view.selected-item:FileBrowserView.orientation</binding>
+            <signal name="activate" handler="view_activated_cb" object="dirlist" swapped="no"/>
+          </object>
+        </child>
+      </object>
+    </child>
+  </object>
+</interface>
diff --git a/demos/gtk-demo/meson.build b/demos/gtk-demo/meson.build
index 6db5774c41..410d26d202 100644
--- a/demos/gtk-demo/meson.build
+++ b/demos/gtk-demo/meson.build
@@ -44,6 +44,7 @@ demos = files([
   'listbox.c',
   'flowbox.c',
   'list_store.c',
+  'listview_filebrowser.c',
   'listview_settings.c',
   'listview_weather.c',
   'markup.c',


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