diff --git a/demos/gtk-demo/demo.gresource.xml b/demos/gtk-demo/demo.gresource.xml index f73721e027..c6ecbf2fa0 100644 --- a/demos/gtk-demo/demo.gresource.xml +++ b/demos/gtk-demo/demo.gresource.xml @@ -118,6 +118,9 @@ gnome-fs-directory.png gnome-fs-regular.png + + listview_filebrowser.ui + listview_settings.ui @@ -203,6 +206,7 @@ infobar.c links.c listbox.c + listview_filebrowser.c listview_settings.c listview_weather.c list_store.c diff --git a/demos/gtk-demo/listview_filebrowser.c b/demos/gtk-demo/listview_filebrowser.c new file mode 100644 index 0000000000..72abd73194 --- /dev/null +++ b/demos/gtk-demo/listview_filebrowser.c @@ -0,0 +1,255 @@ +/* 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 +#include + +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) +{ +} + +char * +filebrowser_get_display_name (GObject *object, + GFileInfo *info) +{ + if (!info) + return NULL; + + return g_strdup (g_file_info_get_attribute_string (info, "standard::display-name")); +} + +char * +filebrowser_get_content_type (GObject *object, + GFileInfo *info) +{ + if (!info) + return NULL; + + return g_strdup (g_file_info_get_attribute_string (info, "standard::content-type")); +} + +char * +filebrowser_get_size (GObject *object, + GFileInfo *info) +{ + if (!info) + return NULL; + + return g_format_size (g_file_info_get_attribute_uint64 (info, "standard::size")); +} + +GIcon * +filebrowser_get_icon (GObject *object, + GFileInfo *info) +{ + GIcon *icon; + + if (info) + icon = G_ICON (g_file_info_get_attribute_object (info, "standard::icon")); + else + icon = NULL; + + if (icon) + g_object_ref (icon); + + return icon; +} + +void +filebrowser_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); +} + +void +filebrowser_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; + char *cwd; + + builder = gtk_builder_new_from_resource ("/listview_filebrowser/listview_filebrowser.ui"); + 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 */ + cwd = g_get_current_dir (); + file = g_file_new_for_path (cwd); + g_free (cwd); + 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..126c1baa02 --- /dev/null +++ b/demos/gtk-demo/listview_filebrowser.ui @@ -0,0 +1,240 @@ + + + + FileBrowserView + + + + + + + + + ]]> + + + view-list-symbolic + horizontal + + + + + view-grid-symbolic + + + + + + + ]]> + + + vertical + + + + + view-paged-symbolic + + + + + + + ]]> + + + horizontal + + + + + standard::name,standard::display-name,standard::icon,standard::size,standard::content-type + + + File browser + 600 + 400 + + + 1 + + + go-up + + + + + + center + horizontal + + + + viewlist + + + + + + + + + ]]> + + + + + + + + + 1 + + + dirlist + 15 + + + selected-view + + + + + selected-view + + + + + + + + + diff --git a/demos/gtk-demo/meson.build b/demos/gtk-demo/meson.build index f1f1ad11df..22de1e1d08 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',