Compare commits
6 Commits
wip/matthi
...
wip/csoria
Author | SHA1 | Date | |
---|---|---|---|
|
dea27ade7c | ||
|
43486b0d5e | ||
|
d486527f1a | ||
|
f81b1ebdec | ||
|
ef6ec2462e | ||
|
2dfc891cb4 |
@@ -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 \
|
||||
|
@@ -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"/>
|
||||
|
@@ -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>
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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
541
gtk/gtkfilespathbar.c
Normal 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
83
gtk/gtkfilespathbar.h
Normal 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__ */
|
2883
gtk/gtkpathbar.c
2883
gtk/gtkpathbar.c
File diff suppressed because it is too large
Load Diff
113
gtk/gtkpathbar.h
113
gtk/gtkpathbar.h
@@ -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
264
gtk/gtkpathbarbox.c
Normal 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);
|
||||
}
|
||||
|
60
gtk/gtkpathbarboxprivate.h
Normal file
60
gtk/gtkpathbarboxprivate.h
Normal 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
1267
gtk/gtkpathbarcontainer.c
Normal file
File diff suppressed because it is too large
Load Diff
131
gtk/gtkpathbarcontainer.h
Normal file
131
gtk/gtkpathbarcontainer.h
Normal 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_ */
|
@@ -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
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -446,6 +446,7 @@ gtk_public_h_sources = \
|
||||
gtkpagesetup.h \
|
||||
gtkpaned.h \
|
||||
gtkpapersize.h \
|
||||
gtkpathbar.h \
|
||||
gtkplug.h \
|
||||
gtkprintcontext.h \
|
||||
gtkprintoperation.h \
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
/**************
|
||||
|
@@ -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 *
|
||||
|
@@ -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 *
|
||||
|
@@ -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>
|
||||
|
@@ -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>
|
||||
|
@@ -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
331
tests/testpathbar.c
Normal 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;
|
||||
}
|
155
tests/testpathbarcontainer.c
Normal file
155
tests/testpathbarcontainer.c
Normal 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;
|
||||
}
|
Reference in New Issue
Block a user