Compare commits

...

6 Commits

Author SHA1 Message Date
Carlos Soriano
dea27ade7c gtkpathbar: minimum size 2016-08-10 22:14:34 +02:00
Carlos Soriano
43486b0d5e f 2016-08-10 09:33:01 +02:00
Carlos Soriano
d486527f1a root management 2016-07-25 17:19:24 +02:00
Carlos Soriano
f81b1ebdec remove tail handling before invert animation 2016-07-21 15:14:38 +02:00
Carlos Soriano
ef6ec2462e tail management testing 2016-07-21 14:15:20 +02:00
Carlos Soriano
2dfc891cb4 Implement new pathbar 2016-07-13 19:57:48 +02:00
24 changed files with 4380 additions and 1885 deletions

View File

@@ -197,6 +197,7 @@ gtk_public_h_sources = \
gtkfilechoosernative.h \
gtkfilechooserwidget.h \
gtkfilefilter.h \
gtkfilespathbar.h \
gtkfixed.h \
gtkflowbox.h \
gtkfontbutton.h \
@@ -252,6 +253,7 @@ gtk_public_h_sources = \
gtkpagesetup.h \
gtkpaned.h \
gtkpapersize.h \
gtkpathbar.h \
gtkplacessidebar.h \
gtkplug.h \
gtkpopover.h \
@@ -518,8 +520,9 @@ gtk_private_h_sources = \
gtkmountoperationprivate.h \
gtknativedialogprivate.h \
gtkorientableprivate.h \
gtkpathbarcontainer.h \
gtkpango.h \
gtkpathbar.h \
gtkpathbarboxprivate.h \
gtkplacessidebarprivate.h \
gtkplacesviewprivate.h \
gtkplacesviewrowprivate.h \
@@ -756,6 +759,7 @@ gtk_base_c_sources = \
gtkfilechooserutils.c \
gtkfilechooserwidget.c \
gtkfilefilter.c \
gtkfilespathbar.c \
gtkfilesystem.c \
gtkfilesystemmodel.c \
gtkfixed.c \
@@ -832,6 +836,8 @@ gtk_base_c_sources = \
gtkpango.c \
gtkpapersize.c \
gtkpathbar.c \
gtkpathbarcontainer.c \
gtkpathbarbox.c \
gtkplacessidebar.c \
gtkplacesview.c \
gtkplacesviewrow.c \

View File

@@ -6,7 +6,6 @@
<glade-widget-classes>
<!-- base GTK+ private widgets -->
<glade-widget-class name="GtkPathBar" generic-name="pathbar" title="Path Bar" icon-name="widget-gtk-toolbar"/>
<glade-widget-class name="GtkColorEditor" generic-name="coloreditor" title="Color Editor" icon-name="widget-gtk-colorselection"/>
<glade-widget-class name="GtkColorSwatch" generic-name="colorswatch" title="Color Swatch" icon-name="widget-gtk-colorselection"/>
<glade-widget-class name="GtkColorPlane" generic-name="colorplane" title="Color Plane" icon-name="widget-gtk-colorselection"/>
@@ -23,7 +22,6 @@
</glade-widget-classes>
<glade-widget-group name="gtk-private" title="Private GTK+ Classes">
<glade-widget-class-ref name="GtkPathBar"/>
<glade-widget-class-ref name="GtkColorEditor"/>
<glade-widget-class-ref name="GtkColorSwatch"/>
<glade-widget-class-ref name="GtkColorPlane"/>

View File

@@ -102,6 +102,7 @@
#include <gtk/gtkfilechoosernative.h>
#include <gtk/gtkfilechooserwidget.h>
#include <gtk/gtkfilefilter.h>
#include <gtk/gtkfilespathbar.h>
#include <gtk/gtkflowbox.h>
#include <gtk/gtkfontbutton.h>
#include <gtk/gtkfontchooser.h>
@@ -120,6 +121,7 @@
#include <gtk/gtkglarea.h>
#include <gtk/gtkgrid.h>
#include <gtk/gtkheaderbar.h>
#include <gtk/gtkpathbarcontainer.h>
#include <gtk/gtkicontheme.h>
#include <gtk/gtkiconview.h>
#include <gtk/gtkimage.h>
@@ -154,6 +156,7 @@
#include <gtk/gtkoverlay.h>
#include <gtk/gtkpagesetup.h>
#include <gtk/gtkpapersize.h>
#include <gtk/gtkpathbar.h>
#include <gtk/gtkpaned.h>
#include <gtk/gtkplacessidebar.h>
#include <gtk/gtkpopover.h>

View File

@@ -479,7 +479,10 @@ count_expand_children (GtkBox *box,
{
*visible_children += 1;
if (child->expand || gtk_widget_compute_expand (child->widget, private->orientation))
{
*expand_children += 1;
}
}
}
}

View File

@@ -49,7 +49,7 @@
#include "gtkmessagedialog.h"
#include "gtkmountoperation.h"
#include "gtkpaned.h"
#include "gtkpathbar.h"
#include "gtkfilespathbar.h"
#include "gtkplacessidebar.h"
#include "gtkplacessidebarprivate.h"
#include "gtkplacesviewprivate.h"
@@ -550,11 +550,9 @@ static void list_row_activated (GtkTreeView *tree_view,
static void list_cursor_changed (GtkTreeView *treeview,
GtkFileChooserWidget *impl);
static void path_bar_clicked (GtkPathBar *path_bar,
GFile *file,
GFile *child,
gboolean child_is_hidden,
GtkFileChooserWidget *impl);
static void on_path_bar_file (GtkFilesPathBar *path_bar,
GParamSpec *pspec,
GtkFileChooserWidget *impl);
static void update_cell_renderer_attributes (GtkFileChooserWidget *impl);
@@ -3034,7 +3032,7 @@ put_recent_folder_in_pathbar (GtkFileChooserWidget *impl, GtkTreeIter *iter)
gtk_tree_model_get (GTK_TREE_MODEL (priv->recent_model), iter,
MODEL_COL_FILE, &file,
-1);
_gtk_path_bar_set_file (GTK_PATH_BAR (priv->browse_path_bar), file, FALSE);
gtk_files_path_bar_set_file (GTK_FILES_PATH_BAR (priv->browse_path_bar), file);
g_object_unref (file);
}
@@ -5482,7 +5480,7 @@ update_current_folder_get_info_cb (GCancellable *cancellable,
if (! _gtk_file_info_consider_as_directory (info))
goto out;
_gtk_path_bar_set_file (GTK_PATH_BAR (priv->browse_path_bar), data->file, data->keep_trail);
gtk_files_path_bar_set_file (GTK_FILES_PATH_BAR (priv->browse_path_bar), data->file);
if (priv->current_folder != data->file)
{
@@ -7845,24 +7843,15 @@ list_row_activated (GtkTreeView *tree_view,
}
static void
path_bar_clicked (GtkPathBar *path_bar,
GFile *file,
GFile *child_file,
gboolean child_is_hidden,
on_path_bar_file (GtkFilesPathBar *path_bar,
GParamSpec *pspec,
GtkFileChooserWidget *impl)
{
if (child_file)
pending_select_files_add (impl, child_file);
GFile *file;
if (!change_folder_and_display_error (impl, file, FALSE))
return;
file = gtk_files_path_bar_get_file (path_bar);
/* Say we have "/foo/bar/[.baz]" and the user clicks on "bar". We should then
* show hidden files so that ".baz" appears in the file list, as it will still
* be shown in the path bar: "/foo/[bar]/.baz"
*/
if (child_is_hidden)
g_object_set (impl, "show-hidden", TRUE, NULL);
change_folder_and_display_error (impl, file, FALSE);
}
static void
@@ -7960,7 +7949,7 @@ up_folder_handler (GtkFileChooserWidget *impl)
{
GtkFileChooserWidgetPrivate *priv = impl->priv;
_gtk_path_bar_up (GTK_PATH_BAR (priv->browse_path_bar));
//_gtk_path_bar_up (GTK_PATH_BAR (priv->browse_path_bar));
}
/* Handler for the "down-folder" keybinding signal */
@@ -7969,7 +7958,7 @@ down_folder_handler (GtkFileChooserWidget *impl)
{
GtkFileChooserWidgetPrivate *priv = impl->priv;
_gtk_path_bar_down (GTK_PATH_BAR (priv->browse_path_bar));
//_gtk_path_bar_down (GTK_PATH_BAR (priv->browse_path_bar));
}
/* Handler for the "home-folder" keybinding signal */
@@ -8498,7 +8487,7 @@ gtk_file_chooser_widget_class_init (GtkFileChooserWidgetClass *class)
gtk_widget_class_bind_template_callback (widget_class, list_selection_changed);
gtk_widget_class_bind_template_callback (widget_class, list_cursor_changed);
gtk_widget_class_bind_template_callback (widget_class, filter_combo_changed);
gtk_widget_class_bind_template_callback (widget_class, path_bar_clicked);
gtk_widget_class_bind_template_callback (widget_class, on_path_bar_file);
gtk_widget_class_bind_template_callback (widget_class, places_sidebar_open_location_cb);
gtk_widget_class_bind_template_callback (widget_class, places_sidebar_show_error_message_cb);
gtk_widget_class_bind_template_callback (widget_class, places_sidebar_show_other_locations_with_flags_cb);
@@ -8564,10 +8553,8 @@ post_process_ui (GtkFileChooserWidget *impl)
g_list_free (cells);
/* Set the GtkPathBar file system backend */
_gtk_path_bar_set_file_system (GTK_PATH_BAR (impl->priv->browse_path_bar), impl->priv->file_system);
file = g_file_new_for_path ("/");
_gtk_path_bar_set_file (GTK_PATH_BAR (impl->priv->browse_path_bar), file, FALSE);
gtk_files_path_bar_set_file (GTK_FILES_PATH_BAR (impl->priv->browse_path_bar), file);
g_object_unref (file);
/* Set the fixed size icon renderer, this requires
@@ -8634,7 +8621,7 @@ gtk_file_chooser_widget_init (GtkFileChooserWidget *impl)
/* Ensure GTK+ private types used by the template
* definition before calling gtk_widget_init_template()
*/
g_type_ensure (GTK_TYPE_PATH_BAR);
g_type_ensure (GTK_TYPE_FILES_PATH_BAR);
g_type_ensure (GTK_TYPE_PLACES_VIEW);
gtk_widget_init_template (GTK_WIDGET (impl));

541
gtk/gtkfilespathbar.c Normal file
View File

@@ -0,0 +1,541 @@
/* gtkfilespathbar.c
*
* Copyright (C) 2015 Red Hat
*
* 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 2 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/>.
*
* Authors: Carlos Soriano <csoriano@gnome.org>
*/
#include "config.h"
#include "gtkfilespathbar.h"
#include "gtkpathbar.h"
#include "gtkpopover.h"
#include "gtkintl.h"
#include "gtkmarshalers.h"
#include "gtktypebuiltins.h"
#define LOCAL_FILESYSTEM_ROOT_URI "file:///"
#define OTHER_LOCATIONS_URI "other-locations:///"
/**
* SECTION:gtkfilespathbar
* @Short_description: Widget that displays a path in UNIX format in a button-like manner
* @Title: GtkFilesPathBar
* @See_also: #GtkPathBar, #GtkFileChooser
*
* #GtkFilesPathBar is a stock widget that displays a path in UNIX format in a way that
* the user can interact with it, selecting part of it or providing menus for
* every part of the path.
*
* Given the usual big lenght of paths, it conveniently manages the overflow of it,
* hiding the parts of the path that doesn't have snouegh space to be displayed
* in a overflow popover
*/
struct _GtkFilesPathBarPrivate
{
GtkWidget *path_bar;
GFile *file;
GCancellable *cancellable;
GFileMonitor *monitor;
};
G_DEFINE_TYPE_WITH_PRIVATE (GtkFilesPathBar, gtk_files_path_bar, GTK_TYPE_BIN)
enum {
POPULATE_POPUP,
LAST_SIGNAL
};
enum {
PROP_0,
PROP_FILE,
LAST_PROP
};
static GParamSpec *files_path_bar_properties[LAST_PROP] = { NULL, };
static guint files_path_bar_signals[LAST_SIGNAL] = { 0 };
typedef struct {
GtkFilesPathBar *path_bar;
GString *display_path;
GFile *root_file;
gchar *root_label;
GIcon *root_icon;
GCancellable *cancellable;
} PathFilesInfo;
static GMount*
get_mounted_mount_for_root (GFile *file)
{
GVolumeMonitor *volume_monitor;
GList *mounts;
GList *l;
GMount *mount;
GMount *result = NULL;
GFile *root = NULL;
GFile *default_location = NULL;
volume_monitor = g_volume_monitor_get ();
mounts = g_volume_monitor_get_mounts (volume_monitor);
for (l = mounts; l != NULL; l = l->next)
{
mount = l->data;
if (g_mount_is_shadowed (mount))
continue;
root = g_mount_get_root (mount);
if (g_file_equal (file, root))
{
result = g_object_ref (mount);
break;
}
default_location = g_mount_get_default_location (mount);
if (!g_file_equal (default_location, root) &&
g_file_equal (file, default_location))
{
result = g_object_ref (mount);
break;
}
}
g_clear_object (&root);
g_clear_object (&default_location);
g_list_free_full (mounts, g_object_unref);
return result;
}
static gboolean
file_is_home_dir (GFile *file)
{
gboolean is_home_dir;
gchar *path;
path = g_file_get_path (file);
is_home_dir = g_strcmp0 (path, g_get_home_dir ()) == 0;
if (path)
g_free (path);
return is_home_dir;
}
static gboolean
file_is_absolute_root (GFile *file)
{
gboolean is_filesystem_root;
gchar *file_basename;
file_basename = g_file_get_basename (file);
is_filesystem_root = g_strcmp0 (file_basename, G_DIR_SEPARATOR_S) == 0;
g_free (file_basename);
return is_filesystem_root;
}
static gboolean
file_is_root (GFile *file)
{
GMount *mount;
gboolean is_root = FALSE;
mount = get_mounted_mount_for_root (file);
is_root = file_is_absolute_root (file) || file_is_home_dir (file) || mount;
g_clear_object (&mount);
return is_root;
}
static GIcon*
get_root_icon (GFile *file)
{
GIcon *icon = NULL;
GFile *local_filesystem_file;
local_filesystem_file = g_file_new_for_uri (LOCAL_FILESYSTEM_ROOT_URI);
if (g_file_equal (file, local_filesystem_file))
icon = g_themed_icon_new ("drive-harddisk");
g_object_unref (local_filesystem_file);
return icon;
}
static gchar*
get_root_label (GFile *file)
{
gchar *label = NULL;
gchar *path;
GMount *mount;
GFile *other_locations;
path = g_file_get_path (file);
mount = get_mounted_mount_for_root (file);
other_locations = g_file_new_for_uri (OTHER_LOCATIONS_URI);
if (g_strcmp0 (path, g_get_home_dir ()) == 0)
label = g_strdup (_("Home"));
else if (g_file_equal (file, other_locations))
label = g_strdup (_("Other Locations"));
else if (mount)
label = g_mount_get_name (mount);
if (path)
g_free (path);
g_clear_object (&mount);
g_object_unref (other_locations);
return label;
}
static void
free_path_files_info (PathFilesInfo *path_files_info)
{
if (path_files_info->display_path)
g_string_free (path_files_info->display_path, TRUE);
if (path_files_info->root_label)
g_free (path_files_info->root_label);
g_clear_object (&path_files_info->cancellable);
g_clear_object (&path_files_info->root_file);
g_clear_object (&path_files_info->root_icon);
g_slice_free (PathFilesInfo, path_files_info);
}
static void
on_all_path_files_info_queried (PathFilesInfo *path_files_info)
{
GtkFilesPathBarPrivate *priv = gtk_files_path_bar_get_instance_private (path_files_info->path_bar);
gchar *root_uri;
root_uri = g_file_get_uri (path_files_info->root_file);
gtk_path_bar_set_path_extended (GTK_PATH_BAR (priv->path_bar),
path_files_info->display_path->str, root_uri,
path_files_info->root_label, path_files_info->root_icon);
g_free (root_uri);
free_path_files_info (path_files_info);
}
static void
on_queried_file_info (GObject *object,
GAsyncResult *result,
gpointer user_data)
{
GFile *file = G_FILE (object);
GError *error = NULL;
PathFilesInfo *path_files_info = (PathFilesInfo *) user_data;
GFileInfo *file_info = NULL;
gchar *uri;
uri = g_file_get_uri (file);
if (g_cancellable_is_cancelled (path_files_info->cancellable))
{
free_path_files_info (path_files_info);
goto out;
}
file_info = g_file_query_info_finish (file, result, &error);
if (!error || g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED))
{
if (file_is_root (file))
{
uri = g_file_get_uri (file);
path_files_info->root_icon = get_root_icon (file);
path_files_info->root_label = get_root_label (file);
path_files_info->root_file = g_object_ref (file);
/* If it is not specific root managed by us, just query display name */
if (!path_files_info->root_label && !path_files_info->root_icon)
{
if (!error)
{
path_files_info->root_label = g_strdup (g_file_info_get_display_name (file_info));
}
else
{
g_warning ("Error trying to get info from %s, location not supported", uri);
free_path_files_info (path_files_info);
goto out;
}
}
g_string_prepend (path_files_info->display_path, uri);
on_all_path_files_info_queried (path_files_info);
}
else
{
GFile *parent;
parent = g_file_get_parent (file);
g_string_prepend (path_files_info->display_path, g_file_info_get_display_name (file_info));
g_string_prepend (path_files_info->display_path, G_DIR_SEPARATOR_S);
g_file_query_info_async (parent,
"standard::display-name",
G_FILE_QUERY_INFO_NONE,
G_PRIORITY_DEFAULT,
path_files_info->cancellable,
on_queried_file_info,
path_files_info);
}
}
else
{
g_warning ("%s", error->message);
free_path_files_info (path_files_info);
}
out:
g_object_unref (file);
g_clear_object (&file_info);
if (error)
g_error_free (error);
g_free (uri);
}
static void
on_path_bar_populate_popup (GtkPathBar *path_bar,
GtkWidget *container,
const gchar *selected_path,
GtkFilesPathBar *self)
{
GFile *file;
file = g_file_new_for_path (selected_path);
g_signal_emit (self, files_path_bar_signals[POPULATE_POPUP], 0,
container, file);
}
static void
on_path_bar_selected_path (GtkPathBar *path_bar,
GParamSpec *pspec,
GtkFilesPathBar *self)
{
GFile *file;
file = g_file_new_for_uri (gtk_path_bar_get_selected_path (path_bar));
gtk_files_path_bar_set_file (self, file);
g_object_unref (file);
}
static void
gtk_files_path_bar_dispose (GObject *object)
{
GtkFilesPathBar *self = (GtkFilesPathBar *)object;
GtkFilesPathBarPrivate *priv = gtk_files_path_bar_get_instance_private (self);
g_cancellable_cancel (priv->cancellable);
g_clear_object (&priv->cancellable);
g_clear_object (&priv->file);
G_OBJECT_CLASS (gtk_files_path_bar_parent_class)->dispose (object);
}
static void
gtk_files_path_bar_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GtkFilesPathBar *self = GTK_FILES_PATH_BAR (object);
GtkFilesPathBarPrivate *priv = gtk_files_path_bar_get_instance_private (self);
switch (prop_id)
{
case PROP_FILE:
g_value_set_object (value, priv->file);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
gtk_files_path_bar_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GtkFilesPathBar *self = GTK_FILES_PATH_BAR (object);
switch (prop_id)
{
case PROP_FILE:
gtk_files_path_bar_set_file (self, g_value_get_object (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
gtk_files_path_bar_class_init (GtkFilesPathBarClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
object_class->dispose = gtk_files_path_bar_dispose;
object_class->get_property = gtk_files_path_bar_get_property;
object_class->set_property = gtk_files_path_bar_set_property;
/**
* GtkFilesPathBar::populate-popup:
* @files_path_bar: the object which received the signal.
* @container: (type Gtk.Widget): a #GtkContainer
* @path: (type const gchar*): string of the path where the user performed a right click.
*
* The path bar emits this signal when the user invokes a contextual
* popup on one of its items. In the signal handler, the application may
* add extra items to the menu as appropriate. For example, a file manager
* may want to add a "Properties" command to the menu.
*
* The @container and all its contents are destroyed after the user
* dismisses the popup. The popup is re-created (and thus, this signal is
* emitted) every time the user activates the contextual menu.
*
* Since: 3.20
*/
files_path_bar_signals [POPULATE_POPUP] =
g_signal_new (I_("populate-popup"),
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GtkFilesPathBarClass, populate_popup),
NULL, NULL,
_gtk_marshal_VOID__OBJECT_STRING,
G_TYPE_NONE, 2,
GTK_TYPE_WIDGET,
G_TYPE_STRING);
files_path_bar_properties[PROP_FILE] =
g_param_spec_object ("file",
P_("File"),
P_("The file set in the path bar."),
G_TYPE_FILE,
G_PARAM_READWRITE);
g_object_class_install_properties (object_class, LAST_PROP, files_path_bar_properties);
gtk_widget_class_set_css_name (widget_class, "files-path-bar");
}
static void
gtk_files_path_bar_init (GtkFilesPathBar *self)
{
GtkFilesPathBarPrivate *priv = gtk_files_path_bar_get_instance_private (self);
g_type_ensure (GTK_TYPE_FILES_PATH_BAR);
priv->path_bar = gtk_path_bar_new ();
gtk_path_bar_set_inverted (GTK_PATH_BAR (priv->path_bar), TRUE);
gtk_widget_show (priv->path_bar);
g_signal_connect (GTK_PATH_BAR (priv->path_bar), "populate-popup",
G_CALLBACK (on_path_bar_populate_popup), self);
g_signal_connect (GTK_PATH_BAR (priv->path_bar), "notify::selected-path",
G_CALLBACK (on_path_bar_selected_path), self);
gtk_container_add (GTK_CONTAINER (self), priv->path_bar);
}
/**
* gtk_files_path_bar_get_file:
* @files_path_bar: a #GtkFilesPathBar
*
* Get the path represented by the files path bar
*
* Returns: (transfer none): The current #GFile.
*
* Since: 3.20
*/
GFile*
gtk_files_path_bar_get_file (GtkFilesPathBar *self)
{
GtkFilesPathBarPrivate *priv;
g_return_val_if_fail (GTK_IS_FILES_PATH_BAR (self), NULL);
priv = gtk_files_path_bar_get_instance_private (GTK_FILES_PATH_BAR (self));
return priv->file;
}
/**
* gtk_files_path_bar_set_file:
* @files_path_bar: a #GtkFilesPathBar
* @file: the #GFile.
*
* Set the #GFile represented by the path bar.
*
* Since: 3.20
*/
void
gtk_files_path_bar_set_file (GtkFilesPathBar *self,
GFile *file)
{
GtkFilesPathBarPrivate *priv;
PathFilesInfo *path_files_info;
g_return_if_fail (GTK_IS_FILES_PATH_BAR (self));
priv = gtk_files_path_bar_get_instance_private (GTK_FILES_PATH_BAR (self));
if (priv->file && g_file_equal (priv->file, file))
return;
g_cancellable_cancel (priv->cancellable);
g_clear_object (&priv->cancellable);
priv->cancellable = g_cancellable_new ();
g_clear_object (&priv->file);
priv->file = g_object_ref (file);
path_files_info = g_slice_new (PathFilesInfo);
path_files_info->path_bar = self;
path_files_info->display_path = g_string_new ("");
path_files_info->root_file = NULL;
path_files_info->root_label = NULL;
path_files_info->root_icon = NULL;
path_files_info->cancellable = g_object_ref (priv->cancellable);
g_file_query_info_async (g_object_ref (file),
"standard::display-name",
G_FILE_QUERY_INFO_NONE,
G_PRIORITY_DEFAULT,
path_files_info->cancellable,
on_queried_file_info,
path_files_info);
g_object_notify_by_pspec (G_OBJECT (self), files_path_bar_properties[PROP_FILE]);
}
GtkWidget *
gtk_files_path_bar_new (void)
{
return g_object_new (GTK_TYPE_FILES_PATH_BAR, NULL);
}

83
gtk/gtkfilespathbar.h Normal file
View File

@@ -0,0 +1,83 @@
/* gtkfilespathbar.h
*
* Copyright (C) 2015 Red Hat
*
* 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 2 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/>.
*
* Authors: Carlos Soriano <csoriano@gnome.org>
*/
#ifndef __GTK_FILES_PATH_BAR_H__
#define __GTK_FILES_PATH_BAR_H__
#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gtk/gtk.h> can be included directly."
#endif
#include <gtk/gtkbin.h>
#include <gio/gio.h>
G_BEGIN_DECLS
#define GTK_TYPE_FILES_PATH_BAR (gtk_files_path_bar_get_type())
#define GTK_FILES_PATH_BAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_FILES_PATH_BAR, GtkFilesPathBar))
#define GTK_FILES_PATH_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_FILES_PATH_BAR, GtkFilesPathBarClass))
#define GTK_IS_FILES_PATH_BAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_FILES_PATH_BAR))
#define GTK_IS_FILES_PATH_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_FILES_PATH_BAR)
#define GTK_FILES_PATH_BAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_FILES_PATH_BAR, GtkFilesPathBarClass))
typedef struct _GtkFilesPathBar GtkFilesPathBar;
typedef struct _GtkFilesPathBarClass GtkFilesPathBarClass;
typedef struct _GtkFilesPathBarPrivate GtkFilesPathBarPrivate;
struct _GtkFilesPathBarClass
{
GtkBinClass parent;
/*< public >*/
void (* populate_popup) (GtkFilesPathBar *files_path_bar,
GFile *selected_file);
/*< private >*/
/* Padding for future expansion */
gpointer reserved[10];
};
struct _GtkFilesPathBar
{
GtkBin parent_instance;
};
GDK_AVAILABLE_IN_3_20
GType gtk_files_path_bar_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_3_20
GtkWidget* gtk_files_path_bar_new (void);
GDK_AVAILABLE_IN_3_20
void gtk_files_path_bar_set_file (GtkFilesPathBar *files_path_bar,
GFile *file);
GDK_AVAILABLE_IN_3_20
GFile* gtk_files_path_bar_get_file (GtkFilesPathBar *files_path_bar);
GDK_AVAILABLE_IN_3_20
gboolean gtk_files_path_bar_get_edit_mode_enabled (GtkFilesPathBar *files_path_bar);
GDK_AVAILABLE_IN_3_20
void gtk_files_path_bar_set_edit_mode_enabled (GtkFilesPathBar *files_path_bar,
gboolean enable);
G_END_DECLS
#endif /* __GTK_FILES_PATH_BAR_H__ */

File diff suppressed because it is too large Load Diff

View File

@@ -1,67 +1,94 @@
/* gtkpathbar.h
* Copyright (C) 2004 Red Hat, Inc., Jonathan Blandford <jrb@gnome.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
* Copyright (C) 2015 Red Hat
*
* This library is distributed in the hope that it will be useful,
* 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 2 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
* Library General Public License for more details.
* 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 Library General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Authors: Carlos Soriano <csoriano@gnome.org>
*/
#ifndef __GTK_PATH_BAR_H__
#define __GTK_PATH_BAR_H__
#include "gtkcontainer.h"
#include "gtkfilesystem.h"
#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gtk/gtk.h> can be included directly."
#endif
#include <gtk/gtkstack.h>
G_BEGIN_DECLS
typedef struct _GtkPathBar GtkPathBar;
typedef struct _GtkPathBarClass GtkPathBarClass;
#define GTK_TYPE_PATH_BAR (gtk_path_bar_get_type())
#define GTK_PATH_BAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_PATH_BAR, GtkPathBar))
#define GTK_PATH_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_PATH_BAR, GtkPathBarClass))
#define GTK_IS_PATH_BAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_PATH_BAR))
#define GTK_IS_PATH_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_PATH_BAR)
#define GTK_PATH_BAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_PATH_BAR, GtkPathBarClass))
typedef struct _GtkPathBar GtkPathBar;
typedef struct _GtkPathBarClass GtkPathBarClass;
typedef struct _GtkPathBarPrivate GtkPathBarPrivate;
#define GTK_TYPE_PATH_BAR (gtk_path_bar_get_type ())
#define GTK_PATH_BAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_PATH_BAR, GtkPathBar))
#define GTK_PATH_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_PATH_BAR, GtkPathBarClass))
#define GTK_IS_PATH_BAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_PATH_BAR))
#define GTK_IS_PATH_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_PATH_BAR))
#define GTK_PATH_BAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_PATH_BAR, GtkPathBarClass))
struct _GtkPathBar
{
GtkContainer parent;
GtkPathBarPrivate *priv;
};
struct _GtkPathBarClass
{
GtkContainerClass parent_class;
GtkStackClass parent;
void (* path_clicked) (GtkPathBar *path_bar,
GFile *file,
GFile *child_file,
gboolean child_is_hidden);
/*< public >*/
void (* populate_popup) (GtkPathBar *path_bar,
const gchar *selected_path);
/*< private >*/
/* Padding for future expansion */
gpointer reserved[10];
};
GDK_AVAILABLE_IN_ALL
GType gtk_path_bar_get_type (void) G_GNUC_CONST;
void _gtk_path_bar_set_file_system (GtkPathBar *path_bar,
GtkFileSystem *file_system);
void _gtk_path_bar_set_file (GtkPathBar *path_bar,
GFile *file,
gboolean keep_trail);
void _gtk_path_bar_up (GtkPathBar *path_bar);
void _gtk_path_bar_down (GtkPathBar *path_bar);
struct _GtkPathBar
{
GtkStack parent_instance;
};
GDK_AVAILABLE_IN_3_20
GType gtk_path_bar_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_3_20
GtkWidget* gtk_path_bar_new (void);
GDK_AVAILABLE_IN_3_20
void gtk_path_bar_set_path (GtkPathBar *path_bar,
const gchar *path);
GDK_AVAILABLE_IN_3_20
const gchar* gtk_path_bar_get_path (GtkPathBar *path_bar);
GDK_AVAILABLE_IN_3_20
void gtk_path_bar_set_path_extended (GtkPathBar *self,
const gchar *path,
const gchar *root_path,
const gchar *root_label,
GIcon *root_icon);
GDK_AVAILABLE_IN_3_20
void gtk_path_bar_set_selected_path (GtkPathBar *path_bar,
const gchar *path);
GDK_AVAILABLE_IN_3_20
const gchar* gtk_path_bar_get_selected_path (GtkPathBar *path_bar);
GDK_AVAILABLE_IN_3_20
void gtk_path_bar_set_inverted (GtkPathBar *path_bar,
gboolean inverted);
GDK_AVAILABLE_IN_3_20
gboolean gtk_path_bar_get_inverted (GtkPathBar *path_bar);
G_END_DECLS
#endif /* __GTK_PATH_BAR_H__ */

264
gtk/gtkpathbarbox.c Normal file
View File

@@ -0,0 +1,264 @@
/*
* Copyright (C) 2016 Carlos Soriano <csoriano@gnome.org>
*
* Licensed under the GNU General Public License Version 2
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "config.h"
#include "glib.h"
#include "gtkpathbarboxprivate.h"
#include "gtkpathbarcontainer.h"
#include "gtkwidgetprivate.h"
#include "gtkintl.h"
#include "gtksizerequest.h"
#include "gtkbuildable.h"
#include "gtkrevealer.h"
struct _GtkPathBarBoxPrivate
{
GList *children;
};
static GtkBuildableIface *parent_buildable_iface;
static void
buildable_init (GtkBuildableIface *iface)
{
parent_buildable_iface = g_type_interface_peek_parent (iface);
}
G_DEFINE_TYPE_WITH_CODE (GtkPathBarBox, gtk_path_bar_box, GTK_TYPE_CONTAINER,
G_ADD_PRIVATE (GtkPathBarBox)
G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE, buildable_init))
static void
gtk_path_bar_box_forall (GtkContainer *container,
gboolean include_internals,
GtkCallback callback,
gpointer callback_data)
{
GtkPathBarBox *self = GTK_PATH_BAR_BOX (container);
GtkPathBarBoxPrivate *priv = gtk_path_bar_box_get_instance_private (self);
GList *child;
for (child = priv->children; child != NULL; child = child->next)
(* callback) (child->data, callback_data);
}
static void
gtk_path_bar_box_add (GtkContainer *container,
GtkWidget *widget)
{
GtkPathBarBox *self = GTK_PATH_BAR_BOX (container);
GtkPathBarBoxPrivate *priv = gtk_path_bar_box_get_instance_private (self);
priv->children = g_list_append (priv->children, widget);
gtk_widget_set_parent (widget, GTK_WIDGET (self));
gtk_widget_queue_resize (GTK_WIDGET (self));
}
static void
gtk_path_bar_box_remove (GtkContainer *container,
GtkWidget *widget)
{
GtkPathBarBox *self = GTK_PATH_BAR_BOX (container);
GtkPathBarBoxPrivate *priv = gtk_path_bar_box_get_instance_private (self);
priv->children = g_list_remove (priv->children, widget);
gtk_widget_unparent (widget);
gtk_widget_queue_resize (GTK_WIDGET (self));
}
static GtkSizeRequestMode
get_request_mode (GtkWidget *self)
{
return GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT;
}
static void
gtk_path_bar_box_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
GtkPathBarBox *self = GTK_PATH_BAR_BOX (widget);
GList *children;
GList *child;
GtkRequisition child_available_size;
GtkRequestedSize *sizes;
GtkAllocation child_allocation;
gint available_size;
gint n_visible_children = 0;
gint current_x = allocation->x;
gint i;
GtkRequisition minimum_size;
GtkRequisition natural_size;
GtkRequisition distributed_size;
gtk_widget_get_preferred_size (widget, &minimum_size, &natural_size);
gtk_widget_set_allocation (widget, allocation);
available_size = allocation->width;
children = gtk_container_get_children (GTK_CONTAINER (self));
sizes = g_newa (GtkRequestedSize, g_list_length (children));
if (children == NULL)
return;
for (child = children, i = 0; child != NULL; child = g_list_next (child), i++)
{
if (!gtk_widget_get_visible (child->data))
continue;
gtk_widget_get_preferred_width_for_height (child->data,
allocation->height,
&sizes[i].minimum_size,
&sizes[i].natural_size);
sizes[i].data = child->data;
available_size -= sizes[i].minimum_size;
n_visible_children++;
}
gtk_distribute_natural_allocation (MAX (0, available_size),
n_visible_children, sizes);
for (child = children, i = 0; child != NULL; child = g_list_next (child), i++)
{
if (!gtk_widget_get_visible (child->data))
continue;
child_available_size.width = sizes[i].minimum_size;
child_available_size.height = allocation->height;
if (GTK_IS_PATH_BAR_CONTAINER (child->data))
{
gtk_path_bar_container_adapt_to_size (GTK_PATH_BAR_CONTAINER (child->data),
&child_available_size);
gtk_path_bar_container_get_preferred_size_for_requisition (GTK_WIDGET (child->data),
&child_available_size,
&minimum_size,
&natural_size,
&distributed_size);
sizes[i].minimum_size = MIN (child_available_size.width, distributed_size.width);
}
child_allocation.x = current_x;
child_allocation.y = allocation->y;
child_allocation.width = sizes[i].minimum_size;
child_allocation.height = allocation->height;
gtk_widget_size_allocate (child->data, &child_allocation);
current_x += sizes[i].minimum_size;
}
}
static void
gtk_path_bar_box_get_preferred_width (GtkWidget *widget,
gint *minimum_width,
gint *natural_width)
{
GtkPathBarBox *self = GTK_PATH_BAR_BOX (widget);
GtkPathBarBoxPrivate *priv = gtk_path_bar_box_get_instance_private (self);
gint child_minimum_width;
gint child_natural_width;
GList *child;
for (child = priv->children; child != NULL; child = child->next)
{
if (!gtk_widget_is_visible (child->data))
continue;
gtk_widget_get_preferred_width (GTK_WIDGET (child->data),
&child_minimum_width,
&child_natural_width);
*minimum_width = MAX (*minimum_width, child_minimum_width);
*natural_width = MAX (*natural_width, child_natural_width);
}
}
static void
gtk_path_bar_box_get_preferred_width_for_height (GtkWidget *widget,
gint height,
gint *minimum_width_out,
gint *natural_width_out)
{
gtk_path_bar_box_get_preferred_width (widget, minimum_width_out, natural_width_out);
}
static void
gtk_path_bar_box_get_preferred_height (GtkWidget *widget,
gint *minimum_height,
gint *natural_height)
{
GtkPathBarBox *self = GTK_PATH_BAR_BOX (widget);
GtkPathBarBoxPrivate *priv = gtk_path_bar_box_get_instance_private (self);
gint child_minimum_height;
gint child_natural_height;
GList *child;
for (child = priv->children; child != NULL; child = child->next)
{
if (!gtk_widget_is_visible (child->data))
continue;
gtk_widget_get_preferred_height (child->data,
&child_minimum_height,
&child_natural_height);
*minimum_height = MAX (*minimum_height, child_minimum_height);
*natural_height = MAX (*natural_height, child_natural_height);
}
}
static void
gtk_path_bar_box_init (GtkPathBarBox *self)
{
GtkPathBarBoxPrivate *priv = gtk_path_bar_box_get_instance_private (self);
gtk_widget_set_has_window (GTK_WIDGET (self), FALSE);
gtk_widget_set_redraw_on_allocate (GTK_WIDGET (self), TRUE);
priv->children = NULL;
}
static void
gtk_path_bar_box_class_init (GtkPathBarBoxClass *class)
{
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
GtkContainerClass *container_class = GTK_CONTAINER_CLASS (class);
widget_class->size_allocate = gtk_path_bar_box_size_allocate;
widget_class->get_request_mode = get_request_mode;
widget_class->get_preferred_width = gtk_path_bar_box_get_preferred_width;
widget_class->get_preferred_height = gtk_path_bar_box_get_preferred_height;
widget_class->get_preferred_width_for_height = gtk_path_bar_box_get_preferred_width_for_height;
container_class->forall = gtk_path_bar_box_forall;
container_class->add = gtk_path_bar_box_add;
container_class->remove = gtk_path_bar_box_remove;
}
GtkWidget *
gtk_path_bar_box_new (void)
{
return g_object_new (GTK_TYPE_PATH_BAR_BOX, NULL);
}

View File

@@ -0,0 +1,60 @@
/* gtkpathbarboxprivate.h
*
* 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/>.
*/
#ifndef __GTK_PATH_BAR_BOX_PRIVATE_H__
#define __GTK_PATH_BAR_BOX_PRIVATE_H__
#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gtk/gtk.h> can be included directly."
#endif
#include "gtkwidget.h"
#include <gtk/gtkcontainer.h>
G_BEGIN_DECLS
#define GTK_TYPE_PATH_BAR_BOX (gtk_path_bar_box_get_type())
#define GTK_PATH_BAR_BOX(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_PATH_BAR_BOX, GtkPathBarBox))
#define GTK_PATH_BAR_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_PATH_BAR_BOX, GtkPathBarBoxClass))
#define GTK_IS_PATH_BAR_BOX(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_PATH_BAR_BOX))
#define GTK_IS_PATH_BAR_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_PATH_BAR_BOX)
#define GTK_PATH_BAR_BOX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_PATH_BAR_BOX, GtkPathBarBoxClass))
typedef struct _GtkPathBarBox GtkPathBarBox;
typedef struct _GtkPathBarBoxClass GtkPathBarBoxClass;
typedef struct _GtkPathBarBoxPrivate GtkPathBarBoxPrivate;
struct _GtkPathBarBoxClass
{
GtkContainerClass parent_class;
/* Padding for future expansion */
gpointer reserved[10];
};
struct _GtkPathBarBox
{
GtkContainer parent_instance;
};
GType gtk_path_bar_box_get_type (void) G_GNUC_CONST;
GtkWidget *gtk_path_bar_box_new (void);
G_END_DECLS
#endif /* GTK_PATH_BAR_BOX_PRIVATE_H_ */

1267
gtk/gtkpathbarcontainer.c Normal file

File diff suppressed because it is too large Load Diff

131
gtk/gtkpathbarcontainer.h Normal file
View File

@@ -0,0 +1,131 @@
/*
* Copyright (C) 2016 Carlos Soriano <csoriano@gnome.org>
*
* Licensed under the GNU General Public License Version 2
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef __GTK_PATH_BAR_CONTAINER_H__
#define __GTK_PATH_BAR_CONTAINER_H__
#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gtk/gtk.h> can be included directly."
#endif
#include <gtk/gtkbin.h>
G_BEGIN_DECLS
#define GTK_TYPE_PATH_BAR_CONTAINER (gtk_path_bar_container_get_type())
#define GTK_PATH_BAR_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_PATH_BAR_CONTAINER, GtkPathBarContainer))
#define GTK_PATH_BAR_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_PATH_BAR_CONTAINER, GtkPathBarContainerClass))
#define GTK_IS_PATH_BAR_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_PATH_BAR_CONTAINER))
#define GTK_IS_PATH_BAR_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_PATH_BAR_CONTAINER)
#define GTK_PATH_BAR_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_PATH_BAR_CONTAINER, GtkPathBarContainerClass))
typedef struct _GtkPathBarContainer GtkPathBarContainer;
typedef struct _GtkPathBarContainerClass GtkPathBarContainerClass;
typedef struct _GtkPathBarContainerPrivate GtkPathBarContainerPrivate;
struct _GtkPathBarContainerClass
{
GtkBinClass parent;
/* Get the preferred size for a specific allocation, assuming the container
* manages overflow. The return value indicates whether the container children
* overflow and the container reports preferred size for the non overflowing
* children or the ones the container consider that are going to be visible
*/
void (* get_preferred_size_for_requisition) (GtkWidget *widget,
GtkRequisition *available_size,
GtkRequisition *minimum_size,
GtkRequisition *natural_size,
GtkRequisition *distributed_size);
void (* invert_animation_done) (GtkPathBarContainer *self);
/* Padding for future expansion */
gpointer reserved[10];
};
struct _GtkPathBarContainer
{
GtkBin parent_instance;
};
GDK_AVAILABLE_IN_3_20
GType gtk_path_bar_container_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_3_20
GtkWidget *gtk_path_bar_container_new (void);
GDK_AVAILABLE_IN_3_20
void gtk_path_bar_container_set_spacing (GtkPathBarContainer *box,
gint spacing);
GDK_AVAILABLE_IN_3_20
gint gtk_path_bar_container_get_spacing (GtkPathBarContainer *box);
GDK_AVAILABLE_IN_3_20
void gtk_path_bar_container_set_inverted (GtkPathBarContainer *box,
gboolean inverted);
GDK_AVAILABLE_IN_3_20
gboolean gtk_path_bar_container_get_inverted (GtkPathBarContainer *box);
GDK_AVAILABLE_IN_3_20
GList *gtk_path_bar_container_get_overflow_children (GtkPathBarContainer *box);
GDK_AVAILABLE_IN_3_20
void gtk_path_bar_container_add (GtkPathBarContainer *self,
GtkWidget *widget,
gboolean animate);
GDK_AVAILABLE_IN_3_20
void gtk_path_bar_container_remove (GtkPathBarContainer *self,
GtkWidget *widget,
gboolean animate);
GDK_AVAILABLE_IN_3_20
void gtk_path_bar_container_remove_all_children (GtkPathBarContainer *self);
GDK_AVAILABLE_IN_3_20
GList* gtk_path_bar_container_get_children (GtkPathBarContainer *self);
GDK_AVAILABLE_IN_3_20
gint gtk_path_bar_container_get_unused_width (GtkPathBarContainer *self);
GDK_AVAILABLE_IN_3_20
void gtk_path_bar_container_get_preferred_size_for_requisition (GtkWidget *widget,
GtkRequisition *available_size,
GtkRequisition *minimum_size,
GtkRequisition *natural_size,
GtkRequisition *distributed_size);
GDK_AVAILABLE_IN_3_20
void gtk_path_bar_container_adapt_to_size (GtkPathBarContainer *self,
GtkRequisition *available_size);
GDK_AVAILABLE_IN_3_20
GList * gtk_path_bar_container_get_shown_children (GtkPathBarContainer *self);
GDK_AVAILABLE_IN_3_20
gboolean gtk_path_bar_container_get_invert_animation (GtkPathBarContainer *self);
GDK_AVAILABLE_IN_3_20
gboolean gtk_path_bar_container_is_overflowing (GtkPathBarContainer *self);
G_END_DECLS
#endif /* GTK_PATH_BAR_CONTAINER_H_ */

View File

@@ -308,9 +308,11 @@ gtk_revealer_get_child_allocation (GtkRevealer *revealer,
GtkAllocation *child_allocation)
{
GtkWidget *child;
GtkRevealerTransitionType transition;
GtkBorder padding;
gint vertical_padding, horizontal_padding;
GtkRequisition minimum_size;
GtkRequisition natural_size;
g_return_if_fail (revealer != NULL);
g_return_if_fail (allocation != NULL);
@@ -327,19 +329,21 @@ gtk_revealer_get_child_allocation (GtkRevealer *revealer,
child = gtk_bin_get_child (GTK_BIN (revealer));
if (child != NULL && gtk_widget_get_visible (child))
{
transition = effective_transition (revealer);
if (transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_LEFT ||
transition == GTK_REVEALER_TRANSITION_TYPE_SLIDE_RIGHT)
gtk_widget_get_preferred_width_for_height (child, MAX (0, allocation->height - vertical_padding), NULL,
&child_allocation->width);
else
gtk_widget_get_preferred_height_for_width (child, MAX (0, allocation->width - horizontal_padding), NULL,
&child_allocation->height);
}
gtk_widget_get_preferred_size (child, &minimum_size, &natural_size);
child_allocation->width = MAX (child_allocation->width, allocation->width - horizontal_padding);
child_allocation->height = MAX (child_allocation->height, allocation->height - vertical_padding);
if (natural_size.width > allocation->width - horizontal_padding)
child_allocation->width = CLAMP (allocation->width - horizontal_padding,
minimum_size.width,
natural_size.width);
else
child_allocation->width = allocation->width - horizontal_padding;
if (natural_size.height > allocation->height - vertical_padding)
child_allocation->height = CLAMP (allocation->height - vertical_padding,
minimum_size.height,
natural_size.height);
else
child_allocation->height = allocation->height - vertical_padding;
}
static void

View File

@@ -6107,7 +6107,8 @@ gtk_window_show (GtkWidget *widget)
_gtk_widget_set_visible_flag (widget, TRUE);
gtk_css_node_validate (gtk_widget_get_css_node (widget));
if (gtk_widget_get_css_node (widget))
gtk_css_node_validate (gtk_widget_get_css_node (widget));
gtk_widget_realize (widget);

View File

@@ -446,6 +446,7 @@ gtk_public_h_sources = \
gtkpagesetup.h \
gtkpaned.h \
gtkpapersize.h \
gtkpathbar.h \
gtkplug.h \
gtkprintcontext.h \
gtkprintoperation.h \

View File

@@ -1574,31 +1574,51 @@ headerbar {
/************
* Pathbars *
************/
.path-bar button {
&.text-button, &.image-button, & {
padding-left: 4px;
padding-right: 4px;
}
&.text-button.image-button label {
padding-left: 0;
padding-right: 0;
}
path-bar button.flat {
background-image: none;
border-radius: 0px;
border-color: transparent;
border-width: 2px 0px 2px 0px;
box-shadow: 0px 0px 0px;
margin: 0px;
opacity: 0.55;
padding: 3px 8px 4px;
background-color: transparent;
&.text-button.image-button, & {
label:last-child { padding-right: 8px; }
label:first-child { padding-left: 8px; }
}
&:checked {
opacity: 1;
}
image {
padding-left: 4px;
padding-right: 4px;
}
&:hover {
border-bottom-color: mix($selected_bg_color, $selected_fg_color, 75%);
}
&.slider-button {
padding-left: 0;
padding-right: 0;
}
&:backdrop, &:backdrop:checked {
background-color: transparent;
border-color: transparent;
background-image: none;
}
.overflow {
padding-right: 0px;
padding-left: 0px;
}
}
.pathbar-opacity-off {
opacity: 0;
transition-duration: 250ms;
}
@keyframes pathbar-opacity-on-keyframes {
from {opacity: 0;}
to {opacity: 1;}
}
.pathbar-opacity-on {
animation-name: pathbar-opacity-on-keyframes;
animation-duration: 250ms;
}
/**************

View File

@@ -2081,22 +2081,40 @@ window.csd > .titlebar:not(headerbar) {
/************
* Pathbars *
************/
.path-bar button.text-button, .path-bar button.image-button, .path-bar button {
padding-left: 4px;
padding-right: 4px; }
.path-bar button.text-button.image-button label {
padding-left: 0;
padding-right: 0; }
.path-bar button.text-button.image-button label:last-child, .path-bar button label:last-child {
padding-right: 8px; }
.path-bar button.text-button.image-button label:first-child, .path-bar button label:first-child {
padding-left: 8px; }
.path-bar button image {
padding-left: 4px;
padding-right: 4px; }
.path-bar button.slider-button {
padding-left: 0;
padding-right: 0; }
path-bar button.flat {
background-image: none;
border-radius: 0px;
border-color: transparent;
border-width: 2px 0px 2px 0px;
box-shadow: 0px 0px 0px;
margin: 0px;
opacity: 0.55;
padding: 3px 8px 4px;
background-color: transparent; }
path-bar button.flat:checked {
opacity: 1; }
path-bar button.flat:hover {
border-bottom-color: #5986b5; }
path-bar button.flat:backdrop, path-bar button.flat:backdrop:checked {
background-color: transparent;
border-color: transparent;
background-image: none; }
path-bar button.flat .overflow {
padding-right: 0px;
padding-left: 0px; }
.pathbar-opacity-off {
opacity: 0;
transition-duration: 250ms; }
@keyframes pathbar-opacity-on-keyframes {
from {
opacity: 0; }
to {
opacity: 1; } }
.pathbar-opacity-on {
animation-name: pathbar-opacity-on-keyframes;
animation-duration: 250ms; }
/**************
* Tree Views *

View File

@@ -2090,22 +2090,40 @@ window.csd > .titlebar:not(headerbar) {
/************
* Pathbars *
************/
.path-bar button.text-button, .path-bar button.image-button, .path-bar button {
padding-left: 4px;
padding-right: 4px; }
.path-bar button.text-button.image-button label {
padding-left: 0;
padding-right: 0; }
.path-bar button.text-button.image-button label:last-child, .path-bar button label:last-child {
padding-right: 8px; }
.path-bar button.text-button.image-button label:first-child, .path-bar button label:first-child {
padding-left: 8px; }
.path-bar button image {
padding-left: 4px;
padding-right: 4px; }
.path-bar button.slider-button {
padding-left: 0;
padding-right: 0; }
path-bar button.flat {
background-image: none;
border-radius: 0px;
border-color: transparent;
border-width: 2px 0px 2px 0px;
box-shadow: 0px 0px 0px;
margin: 0px;
opacity: 0.55;
padding: 3px 8px 4px;
background-color: transparent; }
path-bar button.flat:checked {
opacity: 1; }
path-bar button.flat:hover {
border-bottom-color: #77ace3; }
path-bar button.flat:backdrop, path-bar button.flat:backdrop:checked {
background-color: transparent;
border-color: transparent;
background-image: none; }
path-bar button.flat .overflow {
padding-right: 0px;
padding-left: 0px; }
.pathbar-opacity-off {
opacity: 0;
transition-duration: 250ms; }
@keyframes pathbar-opacity-on-keyframes {
from {
opacity: 0; }
to {
opacity: 1; } }
.pathbar-opacity-on {
animation-name: pathbar-opacity-on-keyframes;
animation-duration: 250ms; }
/**************
* Tree Views *

View File

@@ -56,9 +56,9 @@
<property name="spacing">6</property>
<property name="border-width">6</property>
<child>
<object class="GtkPathBar" id="browse_path_bar">
<object class="GtkFilesPathBar" id="browse_path_bar">
<property name="visible">True</property>
<signal name="path-clicked" handler="path_bar_clicked" after="yes" swapped="no"/>
<signal name="notify::file" handler="on_path_bar_file"/>
</object>
<packing>
<property name="expand">1</property>

View File

@@ -1,54 +1,128 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface domain="gtk30">
<!-- interface-requires gtk+ 3.10 -->
<object class="GtkButton" id="down_slider_button">
<property name="visible">1</property>
<property name="can-focus">1</property>
<property name="receives-default">1</property>
<property name="focus-on-click">0</property>
<child internal-child="accessible">
<object class="AtkObject" id="down_slider_button-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Down Path</property>
</object>
</child>
<signal name="button-press-event" handler="gtk_path_bar_slider_button_press" swapped="no"/>
<signal name="button-release-event" handler="gtk_path_bar_slider_button_release" swapped="no"/>
<signal name="focus-out-event" handler="gtk_path_bar_slider_down_defocus" swapped="no"/>
<signal name="unmap" handler="on_slider_unmap" swapped="no"/>
<interface>
<requires lib="gtk+" version="3.20"/>
<template class="GtkPathBar" parent="GtkStack">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<child>
<object class="GtkImage">
<property name="visible">1</property>
<property name="icon-name">pan-end-symbolic</property>
<property name="icon-size">1</property>
<object class="GtkPathBarBox" id="path_bar_1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkButton" id="path_bar_root_1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<style>
<class name="flat"/>
</style>
</object>
</child>
<child>
<object class="GtkButton" id="path_bar_overflow_root_1">
<property name="label" translatable="yes">//</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<style>
<class name="flat"/>
<class name="overflow"/>
</style>
</object>
</child>
<child>
<object class="GtkPathBarContainer" id="path_bar_container_1">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
</child>
<child>
<object class="GtkButton" id="path_bar_overflow_tail_1">
<property name="label" translatable="yes">//</property>
<property name="visible">False</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<style>
<class name="flat"/>
<class name="overflow"/>
</style>
</object>
</child>
<child>
<object class="GtkButton" id="path_bar_tail_1">
<property name="visible">False</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<style>
<class name="flat"/>
</style>
</object>
</child>
</object>
<packing>
<property name="name">path_bar_stack_page_1</property>
</packing>
</child>
<style>
<class name="slider-button"/>
</style>
</object>
<object class="GtkButton" id="up_slider_button">
<property name="visible">1</property>
<property name="can-focus">1</property>
<property name="receives-default">1</property>
<property name="focus-on-click">0</property>
<child internal-child="accessible">
<object class="AtkObject" id="up_slider_button-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Up Path</property>
</object>
</child>
<signal name="button-press-event" handler="gtk_path_bar_slider_button_press" swapped="no"/>
<signal name="button-release-event" handler="gtk_path_bar_slider_button_release" swapped="no"/>
<signal name="focus-out-event" handler="gtk_path_bar_slider_up_defocus" swapped="no"/>
<signal name="unmap" handler="on_slider_unmap" swapped="no"/>
<child>
<object class="GtkImage">
<property name="visible">1</property>
<property name="icon-name">pan-start-symbolic</property>
<property name="icon-size">1</property>
<object class="GtkPathBarBox" id="path_bar_2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkButton" id="path_bar_root_2">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<style>
<class name="flat"/>
</style>
</object>
</child>
<child>
<object class="GtkButton" id="path_bar_overflow_root_2">
<property name="label" translatable="yes">//</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<style>
<class name="flat"/>
<class name="overflow"/>
</style>
</object>
</child>
<child>
<object class="GtkPathBarContainer" id="path_bar_container_2">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
</child>
<child>
<object class="GtkButton" id="path_bar_overflow_tail_2">
<property name="label" translatable="yes">//</property>
<property name="visible">False</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<style>
<class name="flat"/>
<class name="overflow"/>
</style>
</object>
</child>
<child>
<object class="GtkButton" id="path_bar_tail_2">
<property name="visible">False</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<style>
<class name="flat"/>
</style>
</object>
</child>
</object>
<packing>
<property name="name">path_bar_stack_page_2</property>
<property name="position">1</property>
</packing>
</child>
<style>
<class name="slider-button"/>
</style>
</object>
</template>
</interface>

View File

@@ -86,6 +86,7 @@ noinst_PROGRAMS = $(TEST_PROGS) \
testgtk \
testheaderbar \
testheightforwidth \
testpathbarcontainer \
testiconview \
testiconview-keynav \
testicontheme \
@@ -108,6 +109,7 @@ noinst_PROGRAMS = $(TEST_PROGS) \
testorientable \
testoverlay \
testoverlaystyleclass \
testpathbar \
testprint \
testrecentchooser \
testrecentchoosermenu \
@@ -291,6 +293,8 @@ testanimation_DEPENDENCIES = $(TEST_DEPS)
testpixbuf_save_DEPENDENCIES = $(TEST_DEPS)
testpixbuf_color_DEPENDENCIES = $(TEST_DEPS)
testpixbuf_scale_DEPENDENCIES = $(TEST_DEPS)
testpathbar_DEPENDENCIES = $(TEST_DEPS)
testpathbarcontainer_DEPENDENCIES = $(TEST_DEPS)
testgmenu_DEPENDENCIES = $(TEST_DEPS)
testlogout_DEPENDENCIES = $(TEST_DEPS)
teststack_DEPENDENCIES = $(TEST_DEPS)
@@ -391,6 +395,12 @@ testtoolbar_SOURCES = \
testmenubutton_SOURCES = \
testmenubutton.c
testpathbar_SOURCES = \
testpathbar.c
testpathbarcontainer_SOURCES = \
testpathbarcontainer.c
testprint_SOURCES = \
testprint.c \
testprintfileoperation.h \

331
tests/testpathbar.c Normal file
View File

@@ -0,0 +1,331 @@
#include "config.h"
#include "glib.h"
#include <gtk/gtk.h>
static GActionGroup *action_group;
static GtkWidget *path_bar;
static GtkWidget *path_bar_inverted;
static GtkWidget *path_bar_slash;
static GtkWidget *path_bar_custom_root_label;
static GtkWidget *path_bar_custom_root_icon;
static GtkWidget *files_path_bar_random;
static GtkWidget *files_path_bar_recent;
static const gchar* REAL_LOCATION_RANDOM = "file:///boot/efi/EFI/BOOT";
static const gchar* REAL_LOCATION_RECENT = "recent:///";
static const gchar* ORIGINAL_PATH = "/test/test 2/test 3/asda lkasdl/test/alskd/t/t/test3/tttttt/tast";
static const gchar* ROOT_PATH = "/test/test 2/test 3";
static void
action_menu_1 (GSimpleAction *action,
GVariant *variant,
gpointer user_data)
{
g_print ("Menu 1 action\n");
}
static void
action_menu_2 (GSimpleAction *action,
GVariant *variant,
gpointer user_data)
{
g_print ("Menu 2 action\n");
}
static void
action_special (GSimpleAction *action,
GVariant *variant,
gpointer user_data)
{
g_print ("Special action\n");
}
const GActionEntry entries[] = {
{ "menu_1", action_menu_1 },
{ "menu_2", action_menu_2 },
{ "special", action_special },
};
static void
on_populate_popup (GtkPathBar *path_bar,
GtkWidget *container,
const gchar *selected_path)
{
GtkWidget *menu_item;
menu_item = gtk_model_button_new ();
gtk_actionable_set_action_name (GTK_ACTIONABLE (menu_item),
"action_group.menu_1");
g_object_set (menu_item, "text", "Menu 1", NULL);
gtk_container_add (GTK_CONTAINER (container), menu_item);
menu_item = gtk_model_button_new ();
gtk_actionable_set_action_name (GTK_ACTIONABLE (menu_item),
"action_group.menu_2");
g_object_set (menu_item, "text", "Menu 2", NULL);
gtk_container_add (GTK_CONTAINER (container), menu_item);
if (g_strcmp0 (selected_path, "/test/test 2/test 3") == 0)
{
menu_item = gtk_model_button_new ();
gtk_actionable_set_action_name (GTK_ACTIONABLE (menu_item),
"action_group.special");
g_object_set (menu_item, "text", "Special", NULL);
gtk_container_add (GTK_CONTAINER (container), menu_item);
}
gtk_widget_show_all (container);
g_print ("Populate popup\n");
}
static void
on_path_selected (GtkPathBar *path_bar,
GParamSpec *pspec,
gpointer *user_data)
{
g_print ("Path selected: %s\n", gtk_path_bar_get_selected_path (path_bar));
}
static gchar*
get_display_path_from_selected (const gchar *selected_path)
{
gchar **splitted_path;
gchar **display_splitted_path;
gint i;
GString *display_path;
gchar *display_path_gchar;
splitted_path = g_strsplit (selected_path, "/", -1);
display_splitted_path = g_strsplit (ORIGINAL_PATH, "/", -1);
display_path = g_string_new ("");
/* Skip the first empty split part */
for (i = 1; i < g_strv_length (splitted_path); i++)
{
g_string_append (display_path, "/");
g_string_append (display_path, display_splitted_path[i]);
}
display_path_gchar = display_path->str;
g_string_free (display_path, FALSE);
g_strfreev (splitted_path);
g_strfreev (display_splitted_path);
return display_path_gchar;
}
static void
on_path_selected_set_path (GtkPathBar *path_bar,
GParamSpec *pspec,
gpointer *user_data)
{
gchar *selected_path;
gchar *new_display_path;
selected_path = g_strdup (gtk_path_bar_get_selected_path (path_bar));
new_display_path = get_display_path_from_selected (selected_path);
g_print ("Path selected: %s, setting path to GtkPathBar and new display path %s\n", selected_path, new_display_path);
if (path_bar == GTK_PATH_BAR (path_bar_custom_root_label))
{
gtk_path_bar_set_path_extended (GTK_PATH_BAR (path_bar_custom_root_label),
selected_path, NULL, NULL, NULL);
}
else if (path_bar == GTK_PATH_BAR (path_bar_custom_root_icon))
{
GIcon *icon;
icon = g_themed_icon_new ("drive-harddisk");
gtk_path_bar_set_path_extended (GTK_PATH_BAR (path_bar_custom_root_icon),
selected_path, "/", NULL, icon);
g_object_unref (icon);
}
else
{
gtk_path_bar_set_path (path_bar, selected_path);
}
g_free (selected_path);
g_free (new_display_path);
}
static void
on_file_changed (GtkFilesPathBar *path_bar,
GParamSpec *pspec,
gpointer *user_data)
{
GFile *file;
gchar *uri;
file = gtk_files_path_bar_get_file (path_bar);
uri = g_file_get_uri (file);
g_print ("File selected: %s in GtkFilesPathBar\n", uri);
g_free (uri);
}
static void
connect_path_bar (GtkPathBar *path_bar)
{
g_signal_connect (GTK_PATH_BAR (path_bar), "populate-popup",
G_CALLBACK (on_populate_popup), NULL);
g_signal_connect (GTK_PATH_BAR (path_bar), "notify::selected-path",
G_CALLBACK (on_path_selected), NULL);
}
static void
connect_path_bar_set_path (GtkPathBar *path_bar)
{
g_signal_connect (GTK_PATH_BAR (path_bar), "populate-popup",
G_CALLBACK (on_populate_popup), NULL);
g_signal_connect (GTK_PATH_BAR (path_bar), "notify::selected-path",
G_CALLBACK (on_path_selected_set_path), NULL);
}
static void
connect_files_path_bar (GtkFilesPathBar *files_path_bar)
{
g_signal_connect (GTK_FILES_PATH_BAR (files_path_bar), "populate-popup",
G_CALLBACK (on_populate_popup), NULL);
g_signal_connect (GTK_FILES_PATH_BAR (files_path_bar), "notify::file",
G_CALLBACK (on_file_changed), NULL);
}
static void
on_reset_button_clicked (GtkButton *reset_button)
{
GFile *file;
GIcon *icon;
gtk_path_bar_set_path (GTK_PATH_BAR (path_bar), ORIGINAL_PATH);
gtk_path_bar_set_path (GTK_PATH_BAR (path_bar_inverted), ORIGINAL_PATH);
gtk_path_bar_set_path (GTK_PATH_BAR (path_bar_slash), "/");
gtk_path_bar_set_path_extended (GTK_PATH_BAR (path_bar_custom_root_label),
ORIGINAL_PATH, ROOT_PATH, "This Is A Root", NULL);
icon = g_themed_icon_new ("drive-harddisk");
gtk_path_bar_set_path_extended (GTK_PATH_BAR (path_bar_custom_root_icon),
ORIGINAL_PATH, "/", NULL, icon);
g_object_unref (icon);
file = g_file_new_for_uri (REAL_LOCATION_RANDOM);
gtk_files_path_bar_set_file (GTK_FILES_PATH_BAR (files_path_bar_random), file);
g_object_unref (file);
file = g_file_new_for_uri (REAL_LOCATION_RECENT);
gtk_files_path_bar_set_file (GTK_FILES_PATH_BAR (files_path_bar_recent), file);
g_object_unref (file);
}
int
main (int argc, char *argv[])
{
GtkWidget *window;
GtkWidget *grid;
GtkWidget *reset_button;
GtkWidget *label;
GFile *file = NULL;
GIcon *icon;
gtk_init (&argc, &argv);
window = g_object_connect (g_object_new (gtk_window_get_type (),
"type", GTK_WINDOW_TOPLEVEL,
"title", "Test path bar",
"resizable", TRUE,
"default-height", 200,
NULL),
"signal::destroy", gtk_main_quit, NULL,
NULL);
action_group = G_ACTION_GROUP (g_simple_action_group_new ());
g_action_map_add_action_entries (G_ACTION_MAP (action_group), entries,
G_N_ELEMENTS (entries), window);
gtk_widget_insert_action_group (window, "action_group", action_group);
grid = gtk_grid_new ();
g_type_ensure (GTK_TYPE_PATH_BAR);
label = gtk_label_new ("Generic GtkPathBar tests");
gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 2, 1);
/* ----------------------------------------------------------------------- */
path_bar = gtk_path_bar_new ();
gtk_grid_attach (GTK_GRID (grid), path_bar, 0, 1, 1, 1);
gtk_path_bar_set_path (GTK_PATH_BAR (path_bar), ORIGINAL_PATH);
connect_path_bar (GTK_PATH_BAR (path_bar));
/* ----------------------------------------------------------------------- */
path_bar_inverted = gtk_path_bar_new ();
gtk_path_bar_set_inverted (GTK_PATH_BAR (path_bar_inverted), TRUE);
gtk_path_bar_set_path (GTK_PATH_BAR (path_bar_inverted), ORIGINAL_PATH);
connect_path_bar (GTK_PATH_BAR (path_bar_inverted));
gtk_grid_attach (GTK_GRID (grid), path_bar_inverted, 0, 2, 1, 1);
label = gtk_label_new ("“/” a.k.a root, special case");
gtk_grid_attach (GTK_GRID (grid), label, 0, 3, 2, 1);
/* ----------------------------------------------------------------------- */
path_bar_slash = gtk_path_bar_new ();
gtk_path_bar_set_inverted (GTK_PATH_BAR (path_bar_slash), TRUE);
gtk_path_bar_set_path (GTK_PATH_BAR (path_bar_slash), "/");
connect_path_bar_set_path (GTK_PATH_BAR (path_bar_slash));
gtk_grid_attach (GTK_GRID (grid), path_bar_slash, 0, 4, 1, 1);
label = gtk_label_new ("GtkPathBar with special roots");
gtk_grid_attach (GTK_GRID (grid), label, 0, 5, 2, 1);
/* ----------------------------------------------------------------------- */
path_bar_custom_root_label = gtk_path_bar_new ();
gtk_path_bar_set_inverted (GTK_PATH_BAR (path_bar_custom_root_label), TRUE);
gtk_path_bar_set_path_extended (GTK_PATH_BAR (path_bar_custom_root_label),
ORIGINAL_PATH, NULL, NULL, NULL);
connect_path_bar_set_path (GTK_PATH_BAR (path_bar_custom_root_label));
gtk_grid_attach (GTK_GRID (grid), path_bar_custom_root_label, 0, 6, 1, 1);
#if 0
/* ----------------------------------------------------------------------- */
path_bar_custom_root_icon = gtk_path_bar_new ();
gtk_path_bar_set_inverted (GTK_PATH_BAR (path_bar_custom_root_icon), TRUE);
icon = g_themed_icon_new ("drive-harddisk");
gtk_path_bar_set_path_extended (GTK_PATH_BAR (path_bar_custom_root_icon),
ORIGINAL_PATH, "/", NULL, icon);
g_object_unref (icon);
connect_path_bar_set_path (GTK_PATH_BAR (path_bar_custom_root_icon));
gtk_grid_attach (GTK_GRID (grid), path_bar_custom_root_icon, 0, 7, 1, 1);
/* GtkFilesPathBar tests */
label = gtk_label_new ("GtkFilesPathBar tests");
gtk_grid_attach (GTK_GRID (grid), label, 0, 8, 2, 1);
/* ----------------------------------------------------------------------- */
files_path_bar_random = gtk_files_path_bar_new ();
file = g_file_new_for_uri (REAL_LOCATION_RANDOM);
gtk_files_path_bar_set_file (GTK_FILES_PATH_BAR (files_path_bar_random), file);
connect_files_path_bar (GTK_FILES_PATH_BAR (files_path_bar_random));
gtk_grid_attach (GTK_GRID (grid), files_path_bar_random, 0, 9, 1, 1);
g_clear_object (&file);
files_path_bar_recent = gtk_files_path_bar_new ();
file = g_file_new_for_uri (REAL_LOCATION_RECENT);
gtk_files_path_bar_set_file (GTK_FILES_PATH_BAR (files_path_bar_recent), file);
connect_files_path_bar (GTK_FILES_PATH_BAR (files_path_bar_recent));
gtk_grid_attach (GTK_GRID (grid), files_path_bar_recent, 0, 10, 1, 1);
g_clear_object (&file);
/* Reset button */
reset_button = gtk_button_new_with_label ("Reset State");
gtk_widget_set_hexpand (reset_button, TRUE);
g_signal_connect (GTK_BUTTON (reset_button), "clicked",
G_CALLBACK (on_reset_button_clicked), window);
gtk_grid_attach (GTK_GRID (grid), reset_button, 0, 11, 2, 1);
#endif
gtk_container_add (GTK_CONTAINER (window), grid);
gtk_widget_show_all (window);
gtk_main ();
return 0;
}

View File

@@ -0,0 +1,155 @@
#include "config.h"
#include "glib.h"
#include <gtk/gtk.h>
#define GTK_COMPILATION
#include <gtk/gtkpathbarcontainer.h>
#include <gtk/gtkpathbarcontainer.c>
#include <gtk/gtkpathbarboxprivate.h>
#include <gtk/gtkpathbarbox.c>
#define N_BUTTONS 10
static GtkWidget *path_bar_container;
static GtkWidget *path_bar_box;
static char *lorem_ipsum = "Loremipsumdolorsitamet, consecteturadipisicingelit,";
static char*
get_lorem_ipsum ()
{
static char **lorem_ipsum_split;
static int n_lorem_ipsum_words;
if (!lorem_ipsum_split)
{
lorem_ipsum_split = g_strsplit (lorem_ipsum, " ", -1);
n_lorem_ipsum_words = g_strv_length (lorem_ipsum_split);
}
return lorem_ipsum_split [g_random_int_range (0, n_lorem_ipsum_words)];
}
static void
on_button_clicked (GtkWidget *button,
gpointer user_data)
{
g_print ("button clicked\n");
gtk_path_bar_container_remove (GTK_PATH_BAR_CONTAINER (user_data), button, TRUE);
}
static void
on_reset_button_clicked (GtkButton *reset_button)
{
GtkWidget *button;
gtk_path_bar_container_remove_all_children (GTK_PATH_BAR_CONTAINER (path_bar_container));
for (int i = 0; i < N_BUTTONS; i++)
{
button = gtk_button_new_with_label (get_lorem_ipsum ());
g_signal_connect (button, "clicked", (GCallback) on_button_clicked, path_bar_container);
gtk_path_bar_container_add (GTK_PATH_BAR_CONTAINER (path_bar_container), button, FALSE);
}
gtk_widget_show_all (path_bar_container);
}
static void
on_add_button (gint line)
{
GtkWidget *button;
button = gtk_button_new_with_label (get_lorem_ipsum ());
gtk_widget_show (button);
g_signal_connect (button, "clicked", (GCallback) on_button_clicked, path_bar_container);
gtk_path_bar_container_add (GTK_PATH_BAR_CONTAINER (path_bar_container), button, TRUE);
gtk_container_add (GTK_CONTAINER (path_bar_box), gtk_button_new_with_label ("eeeeoo"));
}
static void
on_remove_button (gint line)
{
GList *children;
GList *last;
children = gtk_path_bar_container_get_children (GTK_PATH_BAR_CONTAINER (path_bar_container));
last = g_list_last (children);
if (last)
gtk_path_bar_container_remove (GTK_PATH_BAR_CONTAINER (path_bar_container),
last->data, TRUE);
g_list_free (children);
}
static void
on_invert_button (gint line)
{
gtk_path_bar_container_set_inverted (GTK_PATH_BAR_CONTAINER (path_bar_container),
!gtk_path_bar_container_get_inverted (GTK_PATH_BAR_CONTAINER (path_bar_container)));
}
int
main (int argc, char *argv[])
{
GtkWidget *window;
GtkWidget *grid;
GtkWidget *reset_button;
GtkWidget *add_button;
GtkWidget *remove_button;
GtkWidget *invert_button;
GtkWidget *label;
gtk_init (&argc, &argv);
window = g_object_connect (g_object_new (gtk_window_get_type (),
"type", GTK_WINDOW_TOPLEVEL,
"title", "Test path bar",
"resizable", TRUE,
"default-height", 200,
NULL),
"signal::destroy", gtk_main_quit, NULL,
NULL);
grid = gtk_grid_new ();
g_type_ensure (GTK_TYPE_PATH_BAR_CONTAINER);
g_type_ensure (GTK_TYPE_PATH_BAR_BOX);
label = gtk_label_new ("Generic GtkPathBar tests");
gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 2, 1);
/* ----------------------------------------------------------------------- */
path_bar_container = gtk_path_bar_container_new ();
path_bar_box = gtk_path_bar_box_new ();
gtk_container_add (GTK_CONTAINER (path_bar_box), path_bar_container);
gtk_grid_attach (GTK_GRID (grid), path_bar_box, 0, 1, 1, 1);
gtk_widget_show_all (path_bar_box);
/* Add/Remove buttons */
add_button = gtk_button_new_with_label ("Add");
gtk_widget_set_halign (add_button, GTK_ALIGN_END);
remove_button = gtk_button_new_with_label ("Remove");
gtk_widget_set_halign (remove_button, GTK_ALIGN_END);
gtk_grid_attach_next_to (GTK_GRID (grid), add_button, path_bar_box, GTK_POS_RIGHT, 1, 1);
g_signal_connect_swapped (add_button, "clicked", (GCallback) on_add_button, GINT_TO_POINTER (0));
gtk_grid_attach_next_to (GTK_GRID (grid), remove_button, add_button, GTK_POS_RIGHT, 1, 1);
g_signal_connect_swapped (remove_button, "clicked", (GCallback) on_remove_button, GINT_TO_POINTER (0));
gtk_widget_show (add_button);
gtk_widget_show (remove_button);
/* Inverted button */
invert_button = gtk_button_new_with_label ("Invert");
gtk_widget_set_halign (invert_button, GTK_ALIGN_END);
gtk_grid_attach_next_to (GTK_GRID (grid), invert_button, remove_button, GTK_POS_RIGHT, 1, 1);
g_signal_connect_swapped (invert_button, "clicked", (GCallback) on_invert_button, GINT_TO_POINTER (0));
/* Reset button */
reset_button = gtk_button_new_with_label ("Reset State");
gtk_widget_set_hexpand (reset_button, TRUE);
g_signal_connect (GTK_BUTTON (reset_button), "clicked",
G_CALLBACK (on_reset_button_clicked), window);
gtk_grid_attach (GTK_GRID (grid), reset_button, 0, 11, 2, 1);
gtk_container_add (GTK_CONTAINER (window), grid);
gtk_widget_show_all (window);
gtk_main ();
return 0;
}