From 1dfbae1aa41bb2b3b95fa841e0c1707fab52ca8b Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sun, 11 Oct 2015 16:39:18 -0400 Subject: [PATCH] Add GtkShortcutsWindow This is a toplevel window that is tailored towards showing help for shortcuts in an application. The implementation closely follows this design: https://wiki.gnome.org/Design/OS/HelpOverlay This implementation is inspired by earlier work in gnome-builder, thanks to Christian Hergert. https://bugzilla.gnome.org/show_bug.cgi?id=756428 --- docs/reference/gtk/Makefile.am | 5 +- docs/reference/gtk/gtk-docs.sgml | 9 + docs/reference/gtk/gtk3-sections.txt | 71 ++ docs/reference/gtk/gtk3.types.in | 7 +- .../gtk/images/builder-shortcuts.png | Bin 0 -> 74526 bytes .../reference/gtk/images/clocks-shortcuts.png | Bin 0 -> 26017 bytes docs/reference/gtk/images/gedit-shortcuts.png | Bin 0 -> 62962 bytes gtk/Makefile.am | 14 + gtk/gtk.h | 5 + gtk/gtkshortcutlabel.c | 314 +++++++ gtk/gtkshortcutlabelprivate.h | 47 + gtk/gtkshortcutsgesture.c | 311 ++++++ gtk/gtkshortcutsgesture.h | 42 + gtk/gtkshortcutsgroup.c | 306 ++++++ gtk/gtkshortcutsgroup.h | 42 + gtk/gtkshortcutssection.c | 716 ++++++++++++++ gtk/gtkshortcutssection.h | 43 + gtk/gtkshortcutsshortcut.c | 264 ++++++ gtk/gtkshortcutsshortcut.h | 43 + gtk/gtkshortcutswindow.c | 882 ++++++++++++++++++ gtk/gtkshortcutswindow.h | 57 ++ 21 files changed, 3176 insertions(+), 2 deletions(-) create mode 100644 docs/reference/gtk/images/builder-shortcuts.png create mode 100644 docs/reference/gtk/images/clocks-shortcuts.png create mode 100644 docs/reference/gtk/images/gedit-shortcuts.png create mode 100644 gtk/gtkshortcutlabel.c create mode 100644 gtk/gtkshortcutlabelprivate.h create mode 100644 gtk/gtkshortcutsgesture.c create mode 100644 gtk/gtkshortcutsgesture.h create mode 100644 gtk/gtkshortcutsgroup.c create mode 100644 gtk/gtkshortcutsgroup.h create mode 100644 gtk/gtkshortcutssection.c create mode 100644 gtk/gtkshortcutssection.h create mode 100644 gtk/gtkshortcutsshortcut.c create mode 100644 gtk/gtkshortcutsshortcut.h create mode 100644 gtk/gtkshortcutswindow.c create mode 100644 gtk/gtkshortcutswindow.h diff --git a/docs/reference/gtk/Makefile.am b/docs/reference/gtk/Makefile.am index 63cd349c72..ce6d6e2533 100644 --- a/docs/reference/gtk/Makefile.am +++ b/docs/reference/gtk/Makefile.am @@ -470,7 +470,10 @@ HTML_IMAGES = \ $(srcdir)/images/getting-started-app10.png \ $(srcdir)/images/exampleapp.png \ $(srcdir)/images/flow-box.png \ - $(srcdir)/images/inspector.png + $(srcdir)/images/inspector.png \ + $(srcdir)/images/gedit-shortcuts.png \ + $(srcdir)/images/clocks-shortcuts.png \ + $(srcdir)/images/builder-shortcuts.png if ENABLE_DOC_CROSS_REFERENCES # Extra options to supply to gtkdoc-fixref diff --git a/docs/reference/gtk/gtk-docs.sgml b/docs/reference/gtk/gtk-docs.sgml index 9194c4722d..3b975641be 100644 --- a/docs/reference/gtk/gtk-docs.sgml +++ b/docs/reference/gtk/gtk-docs.sgml @@ -239,6 +239,15 @@ + + Shortcuts Overview + + + + + + + Miscellaneous diff --git a/docs/reference/gtk/gtk3-sections.txt b/docs/reference/gtk/gtk3-sections.txt index 60d3eb8449..f4482e1378 100644 --- a/docs/reference/gtk/gtk3-sections.txt +++ b/docs/reference/gtk/gtk3-sections.txt @@ -8422,3 +8422,74 @@ GTK_IS_GL_AREA_CLASS gtk_gl_area_get_type + +
+gtkshortcutswindow +GtkShortcutsWindow + +GTK_TYPE_SHORTCUTS_WINDOW +GTK_SHORTCUTS_WINDOW +GTK_IS_SHORTCUTS_WINDOW +GTK_SHORTCUTS_WINDOW_CLASS +GTK_IS_SHORTCUTS_WINDOW_CLASS +GTK_GET_SHORTCUTS_WINDOW_CLASS + +gtk_shortcuts_window_get_type +
+ +
+gtkshortcutssection +GtkShortcutsSection + +GTK_TYPE_SHORTCUTS_SECTION +GTK_SHORTCUTS_SECTION +GTK_IS_SHORTCUTS_SECTION +GTK_SHORTCUTS_SECTION_CLASS +GTK_IS_SHORTCUTS_SECTION_CLASS +GTK_GET_SHORTCUTS_SECTION_CLASS + +gtk_shortcuts_section_get_type +
+ +
+gtkshortcutsgroup +GtkShortcutsGroup + +GTK_TYPE_SHORTCUTS_GROUP +GTK_SHORTCUTS_GROUP +GTK_IS_SHORTCUTS_GROUP +GTK_SHORTCUTS_GROUP_CLASS +GTK_IS_SHORTCUTS_GROUP_CLASS +GTK_GET_SHORTCUTS_GROUP_CLASS + +gtk_shortcuts_group_get_type +
+ +
+gtkshortcutsshortcut +GtkShortcutsShortcut + +GTK_TYPE_SHORTCUTS_SHORTCUT +GTK_SHORTCUTS_SHORTCUT +GTK_IS_SHORTCUTS_SHORTCUT +GTK_SHORTCUTS_SHORTCUT_CLASS +GTK_IS_SHORTCUTS_SHORTCUT_CLASS +GTK_GET_SHORTCUTS_SHORTCUT_CLASS + + +gtk_shortcuts_shortcut_get_type +
+ +
+gtkshortcutsgesture +GtkShortcutsGesture + +GTK_TYPE_SHORTCUTS_GESTURE +GTK_SHORTCUTS_GESTURE +GTK_IS_SHORTCUTS_GESTURE +GTK_SHORTCUTS_GESTURE_CLASS +GTK_IS_SHORTCUTS_GESTURE_CLASS +GTK_GET_SHORTCUTS_GESTURE_CLASS + +gtk_shortcuts_gesture_get_type +
diff --git a/docs/reference/gtk/gtk3.types.in b/docs/reference/gtk/gtk3.types.in index 4b206223e8..93e42dcc12 100644 --- a/docs/reference/gtk/gtk3.types.in +++ b/docs/reference/gtk/gtk3.types.in @@ -173,12 +173,17 @@ gtk_separator_get_type gtk_separator_menu_item_get_type gtk_separator_tool_item_get_type gtk_settings_get_type -gtk_stack_sidebar_get_type +gtk_shortcuts_window_get_type +gtk_shortcuts_section_get_type +gtk_shortcuts_group_get_type +gtk_shortcuts_shortcut_get_type +gtk_shortcuts_gesture_get_type gtk_size_group_get_type @ENABLE_ON_X11@gtk_socket_get_type gtk_spin_button_get_type gtk_spinner_get_type gtk_stack_get_type +gtk_stack_sidebar_get_type gtk_stack_switcher_get_type gtk_statusbar_get_type gtk_status_icon_get_type diff --git a/docs/reference/gtk/images/builder-shortcuts.png b/docs/reference/gtk/images/builder-shortcuts.png new file mode 100644 index 0000000000000000000000000000000000000000..639a1d3c372812ccf6823cfae08863919812c780 GIT binary patch literal 74526 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 HrI`dv5`t9${ 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Ƿ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

(Y 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≫?@NhJ@kvu5sUbdfR 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 T&u7a*Ze2`B`g!KlS0DceB!WvV literal 0 HcmV?d00001 diff --git a/docs/reference/gtk/images/clocks-shortcuts.png b/docs/reference/gtk/images/clocks-shortcuts.png new file mode 100644 index 0000000000000000000000000000000000000000..9ab2d5a71f3b72bbcac5e6ea67978ce306741c1a GIT binary patch literal 26017 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

B#ZXY4?4Rb;|Q9a7BIb+@vXL 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 literal 0 HcmV?d00001 diff --git a/docs/reference/gtk/images/gedit-shortcuts.png b/docs/reference/gtk/images/gedit-shortcuts.png new file mode 100644 index 0000000000000000000000000000000000000000..5d566ff8baf287ccaf054b1192465d396bb84888 GIT binary patch literal 62962 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

Rb=!pR0Xj2djgZ+-gULgA3*U5ALLo=z9e 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

nKY1F^70`q0-S*rHj88 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�wd`hiBKGWS&MJ*RrA)LKeYscs(1We_n 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 #include #include +#include +#include +#include +#include +#include #include #include #include diff --git a/gtk/gtkshortcutlabel.c b/gtk/gtkshortcutlabel.c new file mode 100644 index 0000000000..7140142133 --- /dev/null +++ b/gtk/gtkshortcutlabel.c @@ -0,0 +1,314 @@ +/* gtkshortcutlabel.c + * + * Copyright (C) 2015 Christian Hergert + * + * 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. + * + * This library 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. + * + * You should have received a copy of the GNU Library General Public + * License along with this library. If not, see . + */ + +#include "config.h" + +#include "gtkshortcutlabelprivate.h" +#include "gtklabel.h" +#include "gtkframe.h" +#include "gtkstylecontext.h" +#include "gtkprivate.h" +#include "gtkintl.h" + +struct _GtkShortcutLabel +{ + GtkBox parent_instance; + gchar *accelerator; +}; + +struct _GtkShortcutLabelClass +{ + GtkBoxClass parent_class; +}; + +G_DEFINE_TYPE (GtkShortcutLabel, gtk_shortcut_label, GTK_TYPE_BOX) + +enum { + PROP_0, + PROP_ACCELERATOR, + LAST_PROP +}; + +static GParamSpec *properties[LAST_PROP]; + +static gchar ** +get_labels (guint key, GdkModifierType modifier, guint *n_mods) +{ + const gchar *labels[16]; + gchar key_label[6]; + gchar *tmp; + gunichar ch; + gint i = 0; + + if (modifier & GDK_SHIFT_MASK) + labels[i++] = C_("keyboard label", "Shift"); + if (modifier & GDK_CONTROL_MASK) + labels[i++] = C_("keyboard label", "Ctrl"); + if (modifier & GDK_MOD1_MASK) + labels[i++] = C_("keyboard label", "Alt"); + if (modifier & GDK_MOD2_MASK) + labels[i++] = "Mod2"; + if (modifier & GDK_MOD3_MASK) + labels[i++] = "Mod3"; + if (modifier & GDK_MOD4_MASK) + labels[i++] = "Mod4"; + if (modifier & GDK_MOD5_MASK) + labels[i++] = "Mod5"; + if (modifier & GDK_SUPER_MASK) + labels[i++] = C_("keyboard label", "Super"); + if (modifier & GDK_HYPER_MASK) + labels[i++] = C_("keyboard label", "Hyper"); + if (modifier & GDK_META_MASK) + labels[i++] = C_("keyboard label", "Meta"); + + *n_mods = i; + + ch = gdk_keyval_to_unicode (key); + if (ch && ch < 0x80 && g_unichar_isgraph (ch)) + { + switch (ch) + { + case '\\': + labels[i++] = C_("keyboard label", "Backslash"); + break; + default: + memset (key_label, 0, 6); + g_unichar_to_utf8 (g_unichar_toupper (ch), key_label); + labels[i++] = key_label; + break; + } + } + else + { + switch (key) + { + case GDK_KEY_Left: + labels[i++] = "\xe2\x86\x90"; + break; + case GDK_KEY_Up: + labels[i++] = "\xe2\x86\x91"; + break; + case GDK_KEY_Right: + labels[i++] = "\xe2\x86\x92"; + break; + case GDK_KEY_Down: + labels[i++] = "\xe2\x86\x93"; + break; + case GDK_KEY_space: + labels[i++] = "\xe2\x90\xa3"; + break; + case GDK_KEY_Return: + labels[i++] = "\xe2\x8f\x8e"; + break; + case GDK_KEY_Page_Up: + labels[i++] = C_("keyboard label", "Page_Up"); + break; + case GDK_KEY_Page_Down: + labels[i++] = C_("keyboard label", "Page_Down"); + break; + default: + tmp = gdk_keyval_name (gdk_keyval_to_lower (key)); + if (tmp != NULL) + { + if (tmp[0] != 0 && tmp[1] == 0) + { + key_label[0] = g_ascii_toupper (tmp[0]); + key_label[1] = '\0'; + labels[i++] = key_label; + } + else + { + labels[i++] = g_dpgettext2 (GETTEXT_PACKAGE, "keyboard label", tmp); + } + } + } + } + + labels[i] = NULL; + + return g_strdupv ((gchar **)labels); +} + +static GtkWidget * +dim_label (const gchar *text) +{ + GtkWidget *label; + + label = gtk_label_new (text); + gtk_widget_show (label); + gtk_style_context_add_class (gtk_widget_get_style_context (label), "dim-label"); + + return label; +} + +static void +gtk_shortcut_label_rebuild (GtkShortcutLabel *self) +{ + gchar **accels = NULL; + gchar **keys = NULL; + GdkModifierType modifier = 0; + guint key = 0; + guint i, k; + guint n_mods; + + gtk_container_foreach (GTK_CONTAINER (self), (GtkCallback)gtk_widget_destroy, NULL); + + if (self->accelerator == NULL) + return; + + accels = g_strsplit (self->accelerator, " ", 0); + for (k = 0; accels[k]; k++) + { + gtk_accelerator_parse (accels[k], &key, &modifier); + if ((key == 0) && (modifier == 0)) + { + g_warning ("Failed to parse accelerator '%s'", self->accelerator); + goto out; + } + + if (k > 0) + gtk_container_add (GTK_CONTAINER (self), dim_label ("/")); + + keys = get_labels (key, modifier, &n_mods); + for (i = 0; keys[i]; i++) + { + GtkWidget *frame; + GtkWidget *disp; + + if (i > 0) + gtk_container_add (GTK_CONTAINER (self), dim_label ("+")); + + frame = gtk_frame_new (NULL); + gtk_widget_show (frame); + gtk_container_add (GTK_CONTAINER (self), frame); + + if (i < n_mods) + gtk_widget_set_size_request (frame, 50, -1); + + disp = gtk_label_new (keys[i]); + gtk_widget_show (disp); + gtk_container_add (GTK_CONTAINER (frame), disp); + } + g_strfreev (keys); + } + +out: + g_strfreev (accels); +} + +static void +gtk_shortcut_label_finalize (GObject *object) +{ + GtkShortcutLabel *self = (GtkShortcutLabel *)object; + + g_free (self->accelerator); + + G_OBJECT_CLASS (gtk_shortcut_label_parent_class)->finalize (object); +} + +static void +gtk_shortcut_label_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GtkShortcutLabel *self = GTK_SHORTCUT_LABEL (object); + + switch (prop_id) + { + case PROP_ACCELERATOR: + g_value_set_string (value, gtk_shortcut_label_get_accelerator (self)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +gtk_shortcut_label_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GtkShortcutLabel *self = GTK_SHORTCUT_LABEL (object); + + switch (prop_id) + { + case PROP_ACCELERATOR: + gtk_shortcut_label_set_accelerator (self, g_value_get_string (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +gtk_shortcut_label_class_init (GtkShortcutLabelClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = gtk_shortcut_label_finalize; + object_class->get_property = gtk_shortcut_label_get_property; + object_class->set_property = gtk_shortcut_label_set_property; + + properties[PROP_ACCELERATOR] = + g_param_spec_string ("accelerator", P_("Accelerator"), P_("Accelerator"), + NULL, + (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_properties (object_class, LAST_PROP, properties); +} + +static void +gtk_shortcut_label_init (GtkShortcutLabel *self) +{ + gtk_box_set_spacing (GTK_BOX (self), 6); +} + +GtkWidget * +gtk_shortcut_label_new (const gchar *accelerator) +{ + return g_object_new (GTK_TYPE_SHORTCUT_LABEL, + "accelerator", accelerator, + NULL); +} + +const gchar * +gtk_shortcut_label_get_accelerator (GtkShortcutLabel *self) +{ + g_return_val_if_fail (GTK_IS_SHORTCUT_LABEL (self), NULL); + + return self->accelerator; +} + +void +gtk_shortcut_label_set_accelerator (GtkShortcutLabel *self, + const gchar *accelerator) +{ + g_return_if_fail (GTK_IS_SHORTCUT_LABEL (self)); + + if (g_strcmp0 (accelerator, self->accelerator) != 0) + { + g_free (self->accelerator); + self->accelerator = g_strdup (accelerator); + gtk_shortcut_label_rebuild (self); + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ACCELERATOR]); + } +} diff --git a/gtk/gtkshortcutlabelprivate.h b/gtk/gtkshortcutlabelprivate.h new file mode 100644 index 0000000000..4f5096c449 --- /dev/null +++ b/gtk/gtkshortcutlabelprivate.h @@ -0,0 +1,47 @@ +/* gtkshortcutlabelprivate.h + * + * Copyright (C) 2015 Christian Hergert + * + * 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. + * + * This library 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. + * + * You should have received a copy of the GNU Library General Public + * License along with this library. If not, see . + */ + +#ifndef __GTK_SHORTCUT_LABEL_H__ +#define __GTK_SHORTCUT_LABEL_H__ + +#include + +G_BEGIN_DECLS + +#define GTK_TYPE_SHORTCUT_LABEL (gtk_shortcut_label_get_type()) +#define GTK_SHORTCUT_LABEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_SHORTCUT_LABEL, GtkShortcutLabel)) +#define GTK_SHORTCUT_LABEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_SHORTCUT_LABEL, GtkShortcutLabelClass)) +#define GTK_IS_SHORTCUT_LABEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_SHORTCUT_LABEL)) +#define GTK_IS_SHORTCUT_LABEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_SHORTCUT_LABEL)) +#define GTK_SHORTCUT_LABEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_SHORTCUT_LABEL, GtkShortcutLabelClass)) + + +typedef struct _GtkShortcutLabel GtkShortcutLabel; +typedef struct _GtkShortcutLabelClass GtkShortcutLabelClass; + + +GType gtk_shortcut_label_get_type (void) G_GNUC_CONST; + +GtkWidget *gtk_shortcut_label_new (const gchar *accelerator); +const gchar *gtk_shortcut_label_get_accelerator (GtkShortcutLabel *self); +void gtk_shortcut_label_set_accelerator (GtkShortcutLabel *self, + const gchar *accelerator); + +G_END_DECLS + +#endif /* __GTK_SHORTCUT_LABEL_H__ */ diff --git a/gtk/gtkshortcutsgesture.c b/gtk/gtkshortcutsgesture.c new file mode 100644 index 0000000000..0889da66c8 --- /dev/null +++ b/gtk/gtkshortcutsgesture.c @@ -0,0 +1,311 @@ + /* gtkshortcutsgesture.c + * + * Copyright (C) 2015 Christian Hergert + * + * 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. + * + * This library 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. + * + * You should have received a copy of the GNU Library General Public + * License along with this library. If not, see . + */ + +#include "config.h" + +#include "gtkshortcutsgesture.h" +#include "gtkimage.h" +#include "gtklabel.h" +#include "gtksizegroup.h" +#include "gtkorientable.h" +#include "gtkstylecontext.h" +#include "gtkprivate.h" +#include "gtkintl.h" + +/** + * SECTION:gtkshortcutsgesture + * @Title: GtkShortcutsGesture + * @Short_description: Represents a gesture in a GtkShortcutsWindow + * + * A GtkShortcutsGesture represents a single gesture with an image + * an a short text. + * + * This widget is only meant to be used with #GtkShortcutsWindow. + */ +struct _GtkShortcutsGesture +{ + GtkBox parent_instance; + + GtkImage *image; + GtkLabel *title; + GtkLabel *subtitle; + GtkBox *title_box; + + GtkSizeGroup *title_size_group; + GtkSizeGroup *icon_size_group; +}; + +struct _GtkShortcutsGestureClass +{ + GtkBoxClass parent_class; +}; + +G_DEFINE_TYPE (GtkShortcutsGesture, gtk_shortcuts_gesture, GTK_TYPE_BOX) + +enum { + PROP_0, + PROP_ICON, + PROP_TITLE, + PROP_SUBTITLE, + PROP_ICON_SIZE_GROUP, + PROP_TITLE_SIZE_GROUP, + LAST_PROP +}; + +static GParamSpec *properties[LAST_PROP]; + +static void +gtk_shortcuts_gesture_set_title_size_group (GtkShortcutsGesture *self, + GtkSizeGroup *group) +{ + if (self->title_size_group) + gtk_size_group_remove_widget (self->title_size_group, GTK_WIDGET (self->title_box)); + if (group) + gtk_size_group_add_widget (group, GTK_WIDGET (self->title_box)); + + g_set_object (&self->title_size_group, group); +} + +static void +gtk_shortcuts_gesture_set_icon_size_group (GtkShortcutsGesture *self, + GtkSizeGroup *group) +{ + if (self->icon_size_group) + gtk_size_group_remove_widget (self->icon_size_group, GTK_WIDGET (self->image)); + if (group) + gtk_size_group_add_widget (group, GTK_WIDGET (self->image)); + + g_set_object (&self->icon_size_group, group); +} + +static void +gtk_shortcuts_gesture_set_icon (GtkShortcutsGesture *self, + GIcon *gicon) +{ + gtk_image_set_from_gicon (self->image, gicon, GTK_ICON_SIZE_DIALOG); +} + +static void +gtk_shortcuts_gesture_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GtkShortcutsGesture *self = GTK_SHORTCUTS_GESTURE (object); + + switch (prop_id) + { + case PROP_ICON: + { + GIcon *icon; + + gtk_image_get_gicon (self->image, &icon, NULL); + g_value_set_object (value, icon); + } + break; + + case PROP_TITLE: + g_value_set_string (value, gtk_label_get_label (self->title)); + break; + + case PROP_SUBTITLE: + g_value_set_string (value, gtk_label_get_label (self->subtitle)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +gtk_shortcuts_gesture_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GtkShortcutsGesture *self = GTK_SHORTCUTS_GESTURE (object); + + switch (prop_id) + { + case PROP_ICON: + gtk_shortcuts_gesture_set_icon (self, g_value_get_object (value)); + break; + + case PROP_TITLE: + gtk_label_set_label (self->title, g_value_get_string (value)); + break; + + case PROP_SUBTITLE: + gtk_label_set_label (self->subtitle, g_value_get_string (value)); + break; + + case PROP_TITLE_SIZE_GROUP: + gtk_shortcuts_gesture_set_title_size_group (self, GTK_SIZE_GROUP (g_value_get_object (value))); + break; + + case PROP_ICON_SIZE_GROUP: + gtk_shortcuts_gesture_set_icon_size_group (self, GTK_SIZE_GROUP (g_value_get_object (value))); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +gtk_shortcuts_gesture_finalize (GObject *object) +{ + GtkShortcutsGesture *self = GTK_SHORTCUTS_GESTURE (object); + + g_clear_object (&self->title_size_group); + g_clear_object (&self->icon_size_group); + + G_OBJECT_CLASS (gtk_shortcuts_gesture_parent_class)->finalize (object); +} + +static void +gtk_shortcuts_gesture_add (GtkContainer *container, + GtkWidget *widget) +{ + g_warning ("Can't add children to %s", G_OBJECT_TYPE_NAME (container)); +} + +static GType +gtk_shortcuts_gesture_child_type (GtkContainer *container) +{ + return G_TYPE_NONE; +} + +static void +gtk_shortcuts_gesture_class_init (GtkShortcutsGestureClass *klass) +{ + GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = gtk_shortcuts_gesture_finalize; + object_class->get_property = gtk_shortcuts_gesture_get_property; + object_class->set_property = gtk_shortcuts_gesture_set_property; + + container_class->add = gtk_shortcuts_gesture_add; + container_class->child_type = gtk_shortcuts_gesture_child_type; + + /** + * GtkShortcutsGesture:icon: + * + * The icon used to represent the gesture. + */ + properties[PROP_ICON] = + g_param_spec_object ("icon", + P_("Icon"), + P_("Icon"), + G_TYPE_ICON, + (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GtkShortcutsGesture:title: + * + * The title for the gesture. + * + * This should be a short, one-line text that describes the action + * associated with the gesture. + */ + properties[PROP_TITLE] = + g_param_spec_string ("title", + P_("Title"), + P_("Title"), + NULL, + (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GtkShortcutsGesture:subtitle: + * + * The subtitle for the gesture. + * + * This should be a short, one-line text that describes the gesture + * itself, e.g. "Two-finger swipe". + */ + properties[PROP_SUBTITLE] = + g_param_spec_string ("subtitle", + P_("Subtitle"), + P_("Subtitle"), + NULL, + (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GtkShortcutsGesture:title-size-group: + * + * The size group for the textual portion of this gesture. + * + * This is used internally by GTK+, and must not be modified by applications. + */ + properties[PROP_TITLE_SIZE_GROUP] = + g_param_spec_object ("title-size-group", + P_("Title Size Group"), + P_("Title Size Group"), + GTK_TYPE_SIZE_GROUP, + (G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS)); + + /** + * GtkShortcutsShortcut:icon-size-group: + * + * The size group for the image portion of this gesture. + * + * This is used internally by GTK+, and must not be modified by applications. + */ + properties[PROP_ICON_SIZE_GROUP] = + g_param_spec_object ("icon-size-group", + P_("Icon Size Group"), + P_("Icon Size Group"), + GTK_TYPE_SIZE_GROUP, + (G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_properties (object_class, LAST_PROP, properties); +} + +static void +gtk_shortcuts_gesture_init (GtkShortcutsGesture *self) +{ + gtk_orientable_set_orientation (GTK_ORIENTABLE (self), GTK_ORIENTATION_HORIZONTAL); + gtk_box_set_spacing (GTK_BOX (self), 12); + + self->image = g_object_new (GTK_TYPE_IMAGE, + "visible", TRUE, + NULL); + GTK_CONTAINER_CLASS (gtk_shortcuts_gesture_parent_class)->add (GTK_CONTAINER (self), GTK_WIDGET (self->image)); + + self->title_box = g_object_new (GTK_TYPE_BOX, + "hexpand", TRUE, + "orientation", GTK_ORIENTATION_VERTICAL, + "visible", TRUE, + NULL); + GTK_CONTAINER_CLASS (gtk_shortcuts_gesture_parent_class)->add (GTK_CONTAINER (self), GTK_WIDGET (self->title_box)); + + self->title = g_object_new (GTK_TYPE_LABEL, + "visible", TRUE, + "xalign", 0.0f, + NULL); + gtk_container_add (GTK_CONTAINER (self->title_box), GTK_WIDGET (self->title)); + + self->subtitle = g_object_new (GTK_TYPE_LABEL, + "visible", TRUE, + "xalign", 0.0f, + NULL); + gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (self->subtitle)), + "dim-label"); + gtk_container_add (GTK_CONTAINER (self->title_box), GTK_WIDGET (self->subtitle)); +} diff --git a/gtk/gtkshortcutsgesture.h b/gtk/gtkshortcutsgesture.h new file mode 100644 index 0000000000..0b60b39840 --- /dev/null +++ b/gtk/gtkshortcutsgesture.h @@ -0,0 +1,42 @@ +/* gtkshortcutsgestureprivate.h + * + * Copyright (C) 2015 Christian Hergert + * + * 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. + * + * This library 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. + * + * You should have received a copy of the GNU Library General Public + * License along with this library. If not, see . + */ + +#ifndef __GTK_SHORTCUTS_GESTURE_H__ +#define __GTK_SHORTCUTS_GESTURE_H__ + +#include + +G_BEGIN_DECLS + +#define GTK_TYPE_SHORTCUTS_GESTURE (gtk_shortcuts_gesture_get_type()) +#define GTK_SHORTCUTS_GESTURE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_SHORTCUTS_GESTURE, GtkShortcutsGesture)) +#define GTK_SHORTCUTS_GESTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_SHORTCUTS_GESTURE, GtkShortcutsGestureClass)) +#define GTK_IS_SHORTCUTS_GESTURE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_SHORTCUTS_GESTURE)) +#define GTK_IS_SHORTCUTS_GESTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_SHORTCUTS_GESTURE)) +#define GTK_SHORTCUTS_GESTURE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_SHORTCUTS_GESTURE, GtkShortcutsGestureClass)) + + +typedef struct _GtkShortcutsGesture GtkShortcutsGesture; +typedef struct _GtkShortcutsGestureClass GtkShortcutsGestureClass; + +GDK_AVAILABLE_IN_3_20 +GType gtk_shortcuts_gesture_get_type (void) G_GNUC_CONST; + +G_END_DECLS + +#endif /* __GTK_SHORTCUTS_GESTURE_H__ */ diff --git a/gtk/gtkshortcutsgroup.c b/gtk/gtkshortcutsgroup.c new file mode 100644 index 0000000000..1ac3fc5276 --- /dev/null +++ b/gtk/gtkshortcutsgroup.c @@ -0,0 +1,306 @@ +/* gtkshortcutsgroup.c + * + * Copyright (C) 2015 Christian Hergert + * + * 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. + * + * This library 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. + * + * You should have received a copy of the GNU Library General Public + * License along with this library. If not, see . + */ + +#include "config.h" + +#include "gtkshortcutsgroup.h" + +#include "gtkshortcutsshortcut.h" +#include "gtkshortcutsgesture.h" +#include "gtklabel.h" +#include "gtkorientable.h" +#include "gtksizegroup.h" +#include "gtkprivate.h" +#include "gtkintl.h" + +/** + * SECTION:gtkshortcutsgroup + * @Title: GtkShortcutsGroup + * @Short_description: Represents a group of shortcuts in a GtkShortcutsWindow + * + * A GtkShortcutsGroup represents a group of related keyboard shortcuts + * or gestures. The group has a title. It may optionally be associated with + * a view of the application, which can be used to show only relevant shortcuts + * depending on the application context. + * + * This widget is only meant to be used with #GtkShortcutsWindow. + */ + +struct _GtkShortcutsGroup +{ + GtkBox parent_instance; + + GtkLabel *title; + gchar *view; + guint height; +}; + +struct _GtkShortcutsGroupClass +{ + GtkBoxClass parent_class; +}; + +G_DEFINE_TYPE (GtkShortcutsGroup, gtk_shortcuts_group, GTK_TYPE_BOX) + +enum { + PROP_0, + PROP_TITLE, + PROP_VIEW, + PROP_ACCEL_SIZE_GROUP, + PROP_TITLE_SIZE_GROUP, + PROP_HEIGHT, + LAST_PROP +}; + +static GParamSpec *properties[LAST_PROP]; + +static void +gtk_shortcuts_group_set_accel_size_group (GtkShortcutsGroup *group, + GtkSizeGroup *size_group) +{ + GList *children, *l; + + children = gtk_container_get_children (GTK_CONTAINER (group)); + for (l = children; l; l = l->next) + { + if (GTK_IS_SHORTCUTS_SHORTCUT (l->data)) + g_object_set (l->data, "accel-size-group", size_group, NULL); + else if (GTK_IS_SHORTCUTS_GESTURE (l->data)) + g_object_set (l->data, "icon-size-group", size_group, NULL); + } + g_list_free (children); +} + +static void +gtk_shortcuts_group_set_title_size_group (GtkShortcutsGroup *group, + GtkSizeGroup *size_group) +{ + GList *children, *l; + + children = gtk_container_get_children (GTK_CONTAINER (group)); + for (l = children; l; l = l->next) + { + if (GTK_IS_SHORTCUTS_SHORTCUT (l->data)) + g_object_set (l->data, "title-size-group", size_group, NULL); + else if (GTK_IS_SHORTCUTS_GESTURE (l->data)) + g_object_set (l->data, "title-size-group", size_group, NULL); + } + g_list_free (children); +} + +static guint +gtk_shortcuts_group_get_height (GtkShortcutsGroup *group) +{ + GList *children, *l; + guint height; + + height = 1; + + children = gtk_container_get_children (GTK_CONTAINER (group)); + for (l = children; l; l = l->next) + { + if (GTK_IS_SHORTCUTS_SHORTCUT (l->data)) + height += 1; + else if (GTK_IS_SHORTCUTS_GESTURE (l->data)) + height += 2; + } + g_list_free (children); + + return height; +} + +static void +gtk_shortcuts_group_add (GtkContainer *container, + GtkWidget *widget) +{ + if (GTK_IS_SHORTCUTS_SHORTCUT (widget) || + GTK_IS_SHORTCUTS_GESTURE (widget)) + GTK_CONTAINER_CLASS (gtk_shortcuts_group_parent_class)->add (container, widget); + else + g_warning ("Can't add children of type %s to %s", + G_OBJECT_TYPE_NAME (widget), + G_OBJECT_TYPE_NAME (container)); +} + +static void +gtk_shortcuts_group_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GtkShortcutsGroup *self = GTK_SHORTCUTS_GROUP (object); + + switch (prop_id) + { + case PROP_TITLE: + g_value_set_string (value, gtk_label_get_label (self->title)); + break; + + case PROP_VIEW: + g_value_set_string (value, self->view); + break; + + case PROP_HEIGHT: + g_value_set_uint (value, gtk_shortcuts_group_get_height (self)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +gtk_shortcuts_group_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GtkShortcutsGroup *self = GTK_SHORTCUTS_GROUP (object); + + switch (prop_id) + { + case PROP_TITLE: + gtk_label_set_label (self->title, g_value_get_string (value)); + break; + + case PROP_VIEW: + g_free (self->view); + self->view = g_value_dup_string (value); + break; + + case PROP_ACCEL_SIZE_GROUP: + gtk_shortcuts_group_set_accel_size_group (self, GTK_SIZE_GROUP (g_value_get_object (value))); + break; + + case PROP_TITLE_SIZE_GROUP: + gtk_shortcuts_group_set_title_size_group (self, GTK_SIZE_GROUP (g_value_get_object (value))); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +gtk_shortcuts_group_finalize (GObject *object) +{ + GtkShortcutsGroup *self = GTK_SHORTCUTS_GROUP (object); + + g_free (self->view); + + G_OBJECT_CLASS (gtk_shortcuts_group_parent_class)->finalize (object); +} + +static void +gtk_shortcuts_group_class_init (GtkShortcutsGroupClass *klass) +{ + GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = gtk_shortcuts_group_finalize; + object_class->get_property = gtk_shortcuts_group_get_property; + object_class->set_property = gtk_shortcuts_group_set_property; + + container_class->add = gtk_shortcuts_group_add; + + /** + * GtkShortcutsGroup:title: + * + * The title for this group of shortcuts. + */ + properties[PROP_TITLE] = + g_param_spec_string ("title", P_("Title"), P_("Title"), + NULL, + (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GtkShortcutsGroup:view: + * + * An optional view that the shortcuts in this group are relevant for. + * The group will be hidden if the #GtkShortcutsWindow:view-name property + * does not match the view of this group. + * + * Set this to %NULL to make the group always visible. + */ + properties[PROP_VIEW] = + g_param_spec_string ("view", P_("View"), P_("View"), + NULL, + (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GtkShortcutsGroup:accel-size-group: + * + * The size group for the accelerator portion of shortcuts in this group. + * + * This is used internally by GTK+, and must not be modified by applications. + */ + properties[PROP_ACCEL_SIZE_GROUP] = + g_param_spec_object ("accel-size-group", + P_("Accelerator Size Group"), + P_("Accelerator Size Group"), + GTK_TYPE_SIZE_GROUP, + (G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS)); + + /** + * GtkShortcutsGroup:title-size-group: + * + * The size group for the textual portion of shortcuts in this group. + * + * This is used internally by GTK+, and must not be modified by applications. + */ + properties[PROP_TITLE_SIZE_GROUP] = + g_param_spec_object ("title-size-group", + P_("Title Size Group"), + P_("Title Size Group"), + GTK_TYPE_SIZE_GROUP, + (G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS)); + + /** + * GtkShortcutsGroup:height: + * + * A rough measure for the number of lines in this group. + * + * This is used internally by GTK+, and is not useful for applications. + */ + properties[PROP_HEIGHT] = + g_param_spec_uint ("height", P_("Height"), P_("Height"), + 0, G_MAXUINT, 0, + (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_properties (object_class, LAST_PROP, properties); +} + +static void +gtk_shortcuts_group_init (GtkShortcutsGroup *self) +{ + PangoAttrList *attrs; + + gtk_orientable_set_orientation (GTK_ORIENTABLE (self), GTK_ORIENTATION_VERTICAL); + gtk_box_set_spacing (GTK_BOX (self), 10); + + attrs = pango_attr_list_new (); + pango_attr_list_insert (attrs, pango_attr_weight_new (PANGO_WEIGHT_BOLD)); + self->title = g_object_new (GTK_TYPE_LABEL, + "attributes", attrs, + "visible", TRUE, + "xalign", 0.0f, + NULL); + pango_attr_list_unref (attrs); + + GTK_CONTAINER_CLASS (gtk_shortcuts_group_parent_class)->add (GTK_CONTAINER (self), GTK_WIDGET (self->title)); +} diff --git a/gtk/gtkshortcutsgroup.h b/gtk/gtkshortcutsgroup.h new file mode 100644 index 0000000000..790d60a855 --- /dev/null +++ b/gtk/gtkshortcutsgroup.h @@ -0,0 +1,42 @@ +/* gtkshortcutsgroupprivate.h + * + * Copyright (C) 2015 Christian Hergert + * + * 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. + * + * This library 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. + * + * You should have received a copy of the GNU Library General Public + * License along with this library. If not, see . + */ + +#ifndef __GTK_SHORTCUTS_GROUP_H__ +#define __GTK_SHORTCUTS_GROUP_H__ + +#include + +G_BEGIN_DECLS + +#define GTK_TYPE_SHORTCUTS_GROUP (gtk_shortcuts_group_get_type ()) +#define GTK_SHORTCUTS_GROUP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_SHORTCUTS_GROUP, GtkShortcutsGroup)) +#define GTK_SHORTCUTS_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_SHORTCUTS_GROUP, GtkShortcutsGroupClass)) +#define GTK_IS_SHORTCUTS_GROUP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_SHORTCUTS_GROUP)) +#define GTK_IS_SHORTCUTS_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_SHORTCUTS_GROUP)) +#define GTK_SHORTCUTS_GROUP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_SHORTCUTS_GROUP, GtkShortcutsGroupClass)) + + +typedef struct _GtkShortcutsGroup GtkShortcutsGroup; +typedef struct _GtkShortcutsGroupClass GtkShortcutsGroupClass; + +GDK_AVAILABLE_IN_3_20 +GType gtk_shortcuts_group_get_type (void) G_GNUC_CONST; + +G_END_DECLS + +#endif /* __GTK_SHORTCUTS_GROUP_H__ */ diff --git a/gtk/gtkshortcutssection.c b/gtk/gtkshortcutssection.c new file mode 100644 index 0000000000..9941e131cb --- /dev/null +++ b/gtk/gtkshortcutssection.c @@ -0,0 +1,716 @@ +/* gtkshortcutssection.c + * + * Copyright (C) 2015 Christian Hergert + * + * 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. + * + * This library 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. + * + * You should have received a copy of the GNU Library General Public + * License along with this library. If not, see . + */ + +#include "config.h" + +#include "gtkshortcutssection.h" + +#include "gtkshortcutsgroup.h" +#include "gtkbutton.h" +#include "gtklabel.h" +#include "gtkstack.h" +#include "gtkstackswitcher.h" +#include "gtkstylecontext.h" +#include "gtkorientable.h" +#include "gtksizegroup.h" +#include "gtkwidget.h" +#include "gtkbindings.h" +#include "gtkprivate.h" +#include "gtkmarshalers.h" +#include "gtkgesturepan.h" +#include "gtkintl.h" + +/** + * SECTION:gtkshortcutssection + * @Title: GtkShortcutsSection + * @Short_description: Represents an application mode in a GtkShortcutsWindow + * + * A GtkShortcutsSection collects all the keyboard shortcuts and gestures + * for a major application mode. If your application needs multiple sections, + * you should give each section a unique #GtkShortcutsSection:section-name and + * a #GtkShortcutsSection:title that can be shown in the section selector of + * the GtkShortcutsWindow. + * + * The #GtkShortcutsSection:max-height property can be used to influence how + * the groups in the section are distributed over pages and columns. + * + * This widget is only meant to be used with #GtkShortcutsWindow. + */ + +struct _GtkShortcutsSection +{ + GtkBox parent_instance; + + gchar *name; + gchar *title; + gchar *view_name; + guint max_height; + + GtkStack *stack; + GtkStackSwitcher *switcher; + GtkWidget *show_all; + + gboolean has_filtered_group; + gboolean need_reflow; + + GtkGesture *pan_gesture; +}; + +struct _GtkShortcutsSectionClass +{ + GtkBoxClass parent_class; + + gboolean (* change_current_page) (GtkShortcutsSection *self, + gint offset); + +}; + +G_DEFINE_TYPE (GtkShortcutsSection, gtk_shortcuts_section, GTK_TYPE_BOX) + +enum { + PROP_0, + PROP_TITLE, + PROP_SECTION_NAME, + PROP_VIEW_NAME, + PROP_MAX_HEIGHT, + LAST_PROP +}; + +enum { + CHANGE_CURRENT_PAGE, + LAST_SIGNAL +}; + +static GParamSpec *properties[LAST_PROP]; +static guint signals[LAST_SIGNAL]; + +static void gtk_shortcuts_section_set_view_name (GtkShortcutsSection *self, + const gchar *view_name); +static void gtk_shortcuts_section_add_group (GtkShortcutsSection *self, + GtkShortcutsGroup *group); + +static void gtk_shortcuts_section_show_all (GtkShortcutsSection *self); +static void gtk_shortcuts_section_filter_groups (GtkShortcutsSection *self); +static void gtk_shortcuts_section_reflow_groups (GtkShortcutsSection *self); +static void gtk_shortcuts_section_maybe_reflow (GtkShortcutsSection *self); + +static gboolean gtk_shortcuts_section_change_current_page (GtkShortcutsSection *self, + gint offset); + +static void gtk_shortcuts_section_pan_gesture_pan (GtkGesturePan *gesture, + GtkPanDirection direction, + gdouble offset, + GtkShortcutsSection *self); + +static void +gtk_shortcuts_section_map (GtkWidget *widget) +{ + GtkShortcutsSection *self = GTK_SHORTCUTS_SECTION (widget); + + if (self->need_reflow) + gtk_shortcuts_section_reflow_groups (self); + + GTK_WIDGET_CLASS (gtk_shortcuts_section_parent_class)->map (widget); +} + +static void +gtk_shortcuts_section_add (GtkContainer *container, + GtkWidget *child) +{ + GtkShortcutsSection *self = GTK_SHORTCUTS_SECTION (container); + + if (GTK_IS_SHORTCUTS_GROUP (child)) + gtk_shortcuts_section_add_group (self, GTK_SHORTCUTS_GROUP (child)); + else + g_warning ("Can't add children of type %s to %s", + G_OBJECT_TYPE_NAME (child), + G_OBJECT_TYPE_NAME (container)); +} + +static void +gtk_shortcuts_section_finalize (GObject *object) +{ + GtkShortcutsSection *self = (GtkShortcutsSection *)object; + + g_clear_pointer (&self->name, g_free); + g_clear_pointer (&self->title, g_free); + g_clear_object (&self->pan_gesture); + + G_OBJECT_CLASS (gtk_shortcuts_section_parent_class)->finalize (object); +} + +static void +gtk_shortcuts_section_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GtkShortcutsSection *self = (GtkShortcutsSection *)object; + + switch (prop_id) + { + case PROP_SECTION_NAME: + g_value_set_string (value, self->name); + break; + + case PROP_VIEW_NAME: + g_value_set_string (value, self->view_name); + break; + + case PROP_TITLE: + g_value_set_string (value, self->title); + break; + + case PROP_MAX_HEIGHT: + g_value_set_uint (value, self->max_height); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +gtk_shortcuts_section_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GtkShortcutsSection *self = (GtkShortcutsSection *)object; + + switch (prop_id) + { + case PROP_SECTION_NAME: + g_free (self->name); + self->name = g_value_dup_string (value); + break; + + case PROP_VIEW_NAME: + gtk_shortcuts_section_set_view_name (self, g_value_get_string (value)); + break; + + case PROP_TITLE: + g_free (self->title); + self->title = g_value_dup_string (value); + break; + + case PROP_MAX_HEIGHT: + self->max_height = g_value_get_uint (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static GType +gtk_shortcuts_section_child_type (GtkContainer *container) +{ + return GTK_TYPE_SHORTCUTS_GROUP; +} + +static void +gtk_shortcuts_section_class_init (GtkShortcutsSectionClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass); + GtkBindingSet *binding_set; + + object_class->finalize = gtk_shortcuts_section_finalize; + object_class->get_property = gtk_shortcuts_section_get_property; + object_class->set_property = gtk_shortcuts_section_set_property; + + widget_class->map = gtk_shortcuts_section_map; + + container_class->add = gtk_shortcuts_section_add; + container_class->child_type = gtk_shortcuts_section_child_type; + + klass->change_current_page = gtk_shortcuts_section_change_current_page; + + /** + * GtkShortcutsSection:section-name: + * + * A unique name to identify this section among the sections + * added to the GtkShortcutsWindow. Setting the #GtkShortcutsWindow:section-name + * property to this string will make this section shown in the + * GtkShortcutsWindow. + */ + properties[PROP_SECTION_NAME] = + g_param_spec_string ("section-name", P_("Section Name"), P_("Section Name"), + NULL, + (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GtkShortcutsSection:view-name: + * + * A view name to filter the groups in this section by. + * See #GtkShortcutsGroup:view. + * + * Applications are expected to use the #GtkShortcutsWindow:view-name + * property for this purpose. + */ + properties[PROP_VIEW_NAME] = + g_param_spec_string ("view-name", P_("View Name"), P_("View Name"), + NULL, + (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GtkShortcutsSection:title: + * + * The string to show in the section selector of the GtkShortcutsWindow + * for this section. If there is only one section, you don't need to + * set a title, since the section selector will not be shown in this case. + */ + properties[PROP_TITLE] = + g_param_spec_string ("title", P_("Title"), P_("Title"), + NULL, + (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GtkShortcutsSection:max-height: + * + * The maximum number of lines to allow per column. This property can + * be used to influence how the groups in this section are distributed + * across pages and columns. The default value of 15 should work in + * for most cases. + */ + properties[PROP_MAX_HEIGHT] = + g_param_spec_uint ("max-height", P_("Maximum Height"), P_("Maximum Height"), + 0, G_MAXUINT, 15, + (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_properties (object_class, LAST_PROP, properties); + + signals[CHANGE_CURRENT_PAGE] = + g_signal_new (I_("change-current-page"), + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (GtkShortcutsSectionClass, change_current_page), + NULL, NULL, + _gtk_marshal_BOOLEAN__INT, + G_TYPE_BOOLEAN, 1, + G_TYPE_INT); + + binding_set = gtk_binding_set_by_class (klass); + gtk_binding_entry_add_signal (binding_set, + GDK_KEY_Page_Up, 0, + "change-current-page", 1, + G_TYPE_INT, -1); + gtk_binding_entry_add_signal (binding_set, + GDK_KEY_Page_Down, 0, + "change-current-page", 1, + G_TYPE_INT, 1); + gtk_binding_entry_add_signal (binding_set, + GDK_KEY_Page_Up, GDK_CONTROL_MASK, + "change-current-page", 1, + G_TYPE_INT, -1); + gtk_binding_entry_add_signal (binding_set, + GDK_KEY_Page_Down, GDK_CONTROL_MASK, + "change-current-page", 1, + G_TYPE_INT, 1); +} + +static void +gtk_shortcuts_section_init (GtkShortcutsSection *self) +{ + GtkWidget *box; + + self->max_height = 15; + + gtk_orientable_set_orientation (GTK_ORIENTABLE (self), GTK_ORIENTATION_VERTICAL); + gtk_box_set_homogeneous (GTK_BOX (self), FALSE); + gtk_box_set_spacing (GTK_BOX (self), 22); + gtk_container_set_border_width (GTK_CONTAINER (self), 24); + + self->stack = g_object_new (GTK_TYPE_STACK, + "homogeneous", TRUE, + "transition-type", GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT_RIGHT, + "vexpand", TRUE, + "visible", TRUE, + NULL); + GTK_CONTAINER_CLASS (gtk_shortcuts_section_parent_class)->add (GTK_CONTAINER (self), GTK_WIDGET (self->stack)); + + self->switcher = g_object_new (GTK_TYPE_STACK_SWITCHER, + "halign", GTK_ALIGN_CENTER, + "stack", self->stack, + "spacing", 12, + "no-show-all", TRUE, + NULL); + gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (self->switcher)), "round"); + gtk_style_context_remove_class (gtk_widget_get_style_context (GTK_WIDGET (self->switcher)), "linked"); + + self->show_all = gtk_button_new_with_mnemonic (_("_Show All")); + gtk_widget_set_no_show_all (self->show_all, TRUE); + g_signal_connect_swapped (self->show_all, "clicked", + G_CALLBACK (gtk_shortcuts_section_show_all), self); + + box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 20); + GTK_CONTAINER_CLASS (gtk_shortcuts_section_parent_class)->add (GTK_CONTAINER (self), box); + + gtk_box_set_center_widget (GTK_BOX (box), GTK_WIDGET (self->switcher)); + gtk_box_pack_end (GTK_BOX (box), self->show_all, TRUE, TRUE, 0); + gtk_widget_set_halign (self->show_all, GTK_ALIGN_END); + + self->pan_gesture = gtk_gesture_pan_new (GTK_WIDGET (self->stack), GTK_ORIENTATION_HORIZONTAL); + g_signal_connect (self->pan_gesture, "pan", + G_CALLBACK (gtk_shortcuts_section_pan_gesture_pan), self); +} + +static void +gtk_shortcuts_section_set_view_name (GtkShortcutsSection *self, + const gchar *view_name) +{ + g_return_if_fail (GTK_IS_SHORTCUTS_SECTION (self)); + + if (g_strcmp0 (self->view_name, view_name) == 0) + return; + + g_free (self->view_name); + self->view_name = g_strdup (view_name); + + gtk_shortcuts_section_filter_groups (self); + gtk_shortcuts_section_reflow_groups (self); + + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_VIEW_NAME]); +} + +static void +gtk_shortcuts_section_add_group (GtkShortcutsSection *self, + GtkShortcutsGroup *group) +{ + GList *children; + GtkWidget *page, *column; + + g_return_if_fail (GTK_IS_SHORTCUTS_SECTION (self)); + g_return_if_fail (GTK_IS_SHORTCUTS_GROUP (group)); + + children = gtk_container_get_children (GTK_CONTAINER (self->stack)); + if (children) + page = children->data; + else + { + page = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 22); + gtk_stack_add_named (self->stack, page, "1"); + } + g_list_free (children); + children = gtk_container_get_children (GTK_CONTAINER (page)); + if (children) + column = children->data; + else + { + column = gtk_box_new (GTK_ORIENTATION_VERTICAL, 22); + gtk_container_add (GTK_CONTAINER (page), column); + } + g_list_free (children); + + gtk_container_add (GTK_CONTAINER (column), GTK_WIDGET (group)); + + gtk_shortcuts_section_maybe_reflow (self); +} + +static void +gtk_shortcuts_section_show_all (GtkShortcutsSection *self) +{ + gtk_shortcuts_section_set_view_name (self, NULL); +} + +static void +update_group_visibility (GtkWidget *child, gpointer data) +{ + GtkShortcutsSection *self = data; + + if (GTK_IS_SHORTCUTS_GROUP (child)) + { + gchar *view; + gboolean match; + + g_object_get (child, "view", &view, NULL); + match = view == NULL || + self->view_name == NULL || + strcmp (view, self->view_name) == 0; + + gtk_widget_set_visible (child, match); + self->has_filtered_group |= !match; + + g_free (view); + } + else if (GTK_IS_CONTAINER (child)) + { + gtk_container_foreach (GTK_CONTAINER (child), update_group_visibility, data); + } +} + +static void +gtk_shortcuts_section_filter_groups (GtkShortcutsSection *self) +{ + self->has_filtered_group = FALSE; + + gtk_container_foreach (GTK_CONTAINER (self), update_group_visibility, self); + + gtk_widget_set_visible (GTK_WIDGET (self->show_all), self->has_filtered_group); + gtk_widget_set_visible (gtk_widget_get_parent (GTK_WIDGET (self->show_all)), + gtk_widget_get_visible (GTK_WIDGET (self->show_all)) || + gtk_widget_get_visible (GTK_WIDGET (self->switcher))); +} + +static void +gtk_shortcuts_section_maybe_reflow (GtkShortcutsSection *self) +{ + if (gtk_widget_get_mapped (GTK_WIDGET (self))) + gtk_shortcuts_section_reflow_groups (self); + else + self->need_reflow = TRUE; +} + +static void +adjust_page_buttons (GtkWidget *widget, + gpointer data) +{ + GtkWidget *label; + + /* + * TODO: This is a hack to get the GtkStackSwitcher radio + * buttons to look how we want. However, it's very + * much font size specific. + */ + gtk_widget_set_size_request (widget, 34, 34); + + label = gtk_bin_get_child (GTK_BIN (widget)); + gtk_label_set_use_underline (GTK_LABEL (label), TRUE); +} + +static void +gtk_shortcuts_section_reflow_groups (GtkShortcutsSection *self) +{ + GList *pages, *p; + GList *columns, *c; + GList *groups, *g; + GList *children; + guint n_rows; + guint n_columns; + guint n_pages; + GtkWidget *current_page, *current_column; + + /* collect all groups from the current pages */ + groups = NULL; + pages = gtk_container_get_children (GTK_CONTAINER (self->stack)); + for (p = pages; p; p = p->next) + { + columns = gtk_container_get_children (GTK_CONTAINER (p->data)); + for (c = columns; c; c = c->next) + { + children = gtk_container_get_children (GTK_CONTAINER (c->data)); + groups = g_list_concat (groups, children); + } + g_list_free (columns); + } + g_list_free (pages); + + /* create new pages */ + current_page = NULL; + current_column = NULL; + pages = NULL; + n_rows = 0; + n_columns = 0; + n_pages = 0; + for (g = groups; g; g = g->next) + { + GtkShortcutsGroup *group = g->data; + guint height; + gboolean visible; + + g_object_get (group, + "visible", &visible, + "height", &height, + NULL); + if (!visible) + height = 0; + + if (n_rows == 0 || n_rows + height > self->max_height) + { + GtkWidget *column; + + column = gtk_box_new (GTK_ORIENTATION_VERTICAL, 22); + gtk_widget_show (column); + + g_object_set_data_full (G_OBJECT (column), "accel-size-group", gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL), g_object_unref); + g_object_set_data_full (G_OBJECT (column), "title-size-group", gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL), g_object_unref); + + if (n_columns % 2 == 0) + { + GtkWidget *page; + + page = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 22); + gtk_widget_show (page); + + pages = g_list_append (pages, page); + current_page = page; + } + + gtk_container_add (GTK_CONTAINER (current_page), column); + current_column = column; + n_columns += 1; + n_rows = 0; + } + + n_rows += height; + + g_object_set (group, + "accel-size-group", g_object_get_data (G_OBJECT (current_column), "accel-size-group"), + "title-size-group", g_object_get_data (G_OBJECT (current_column), "title-size-group"), + NULL); + + g_object_ref (group); + gtk_container_remove (GTK_CONTAINER (gtk_widget_get_parent (GTK_WIDGET (group))), GTK_WIDGET (group)); + gtk_container_add (GTK_CONTAINER (current_column), GTK_WIDGET (group)); + g_object_unref (group); + } + + /* balance the last page */ + if (n_columns % 2 == 1) + { + GtkWidget *column; + GList *content; + guint n; + + column = gtk_box_new (GTK_ORIENTATION_VERTICAL, 22); + gtk_widget_show (column); + + g_object_set_data_full (G_OBJECT (column), "accel-size-group", gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL), g_object_unref); + g_object_set_data_full (G_OBJECT (column), "title-size-group", gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL), g_object_unref); + + gtk_container_add (GTK_CONTAINER (current_page), column); + + content = gtk_container_get_children (GTK_CONTAINER (current_column)); + n = 0; + + for (g = g_list_last (content); g; g = g->prev) + { + GtkShortcutsGroup *group = g->data; + guint height; + gboolean visible; + + g_object_get (group, + "visible", &visible, + "height", &height, + NULL); + if (!visible) + height = 0; + + if (n_rows - height == 0) + break; + if (ABS (n_rows - n) < ABS ((n_rows - height) - (n + height))) + break; + + n_rows -= height; + n += height; + } + + for (g = g->next; g; g = g->next) + { + GtkShortcutsGroup *group = g->data; + + g_object_set (group, + "accel-size-group", g_object_get_data (G_OBJECT (column), "accel-size-group"), + "title-size-group", g_object_get_data (G_OBJECT (column), "title-size-group"), + NULL); + + g_object_ref (group); + gtk_container_remove (GTK_CONTAINER (current_column), GTK_WIDGET (group)); + gtk_container_add (GTK_CONTAINER (column), GTK_WIDGET (group)); + g_object_unref (group); + } + + g_list_free (content); + } + + /* replace the current pages with the new pages */ + children = gtk_container_get_children (GTK_CONTAINER (self->stack)); + g_list_free_full (children, (GDestroyNotify)gtk_widget_destroy); + + for (p = pages, n_pages = 0; p; p = p->next, n_pages++) + { + GtkWidget *page = p->data; + gchar *title; + + title = g_strdup_printf ("_%u", n_pages + 1); + gtk_stack_add_titled (self->stack, page, title, title); + g_free (title); + } + + /* fix up stack switcher */ + gtk_container_foreach (GTK_CONTAINER (self->switcher), adjust_page_buttons, NULL); + gtk_widget_set_visible (GTK_WIDGET (self->switcher), (n_pages > 1)); + gtk_widget_set_visible (gtk_widget_get_parent (GTK_WIDGET (self->switcher)), + gtk_widget_get_visible (GTK_WIDGET (self->show_all)) || + gtk_widget_get_visible (GTK_WIDGET (self->switcher))); + + /* clean up */ + g_list_free (groups); + g_list_free (pages); + + self->need_reflow = FALSE; +} + +static gboolean +gtk_shortcuts_section_change_current_page (GtkShortcutsSection *self, + gint offset) +{ + GtkWidget *child; + GList *children, *l; + + child = gtk_stack_get_visible_child (self->stack); + children = gtk_container_get_children (GTK_CONTAINER (self->stack)); + l = g_list_find (children, child); + + if (offset == 1) + l = l->next; + else if (offset == -1) + l = l->prev; + else + g_assert_not_reached (); + + if (l) + gtk_stack_set_visible_child (self->stack, GTK_WIDGET (l->data)); + else + gtk_widget_error_bell (GTK_WIDGET (self)); + + g_list_free (children); + + return TRUE; +} + +static void +gtk_shortcuts_section_pan_gesture_pan (GtkGesturePan *gesture, + GtkPanDirection direction, + gdouble offset, + GtkShortcutsSection *self) +{ + if (offset < 50) + return; + + if (direction == GTK_PAN_DIRECTION_LEFT) + gtk_shortcuts_section_change_current_page (self, 1); + else if (direction == GTK_PAN_DIRECTION_RIGHT) + gtk_shortcuts_section_change_current_page (self, -1); + else + g_assert_not_reached (); + + gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_DENIED); +} diff --git a/gtk/gtkshortcutssection.h b/gtk/gtkshortcutssection.h new file mode 100644 index 0000000000..9d8b5cc432 --- /dev/null +++ b/gtk/gtkshortcutssection.h @@ -0,0 +1,43 @@ +/* gtkshortcutssection.h + * + * Copyright (C) 2015 Christian Hergert + * + * 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. + * + * This library 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. + * + * You should have received a copy of the GNU Library General Public + * License along with this library. If not, see . + */ + +#ifndef __GTK_SHORTCUTS_SECTION_H__ +#define __GTK_SHORTCUTS_SECTION_H__ + +#include +#include + +G_BEGIN_DECLS + +#define GTK_TYPE_SHORTCUTS_SECTION (gtk_shortcuts_section_get_type ()) +#define GTK_SHORTCUTS_SECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_SHORTCUTS_SECTION, GtkShortcutsSection)) +#define GTK_SHORTCUTS_SECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_SHORTCUTS_SECTION, GtkShortcutsSectionClass)) +#define GTK_IS_SHORTCUTS_SECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_SHORTCUTS_SECTION)) +#define GTK_IS_SHORTCUTS_SECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_SHORTCUTS_SECTION)) +#define GTK_SHORTCUTS_SECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_SHORTCUTS_SECTION, GtkShortcutsSectionClass)) + + +typedef struct _GtkShortcutsSection GtkShortcutsSection; +typedef struct _GtkShortcutsSectionClass GtkShortcutsSectionClass; + +GDK_AVAILABLE_IN_3_20 +GType gtk_shortcuts_section_get_type (void) G_GNUC_CONST; + +G_END_DECLS + +#endif /* __GTK_SHORTCUTS_SECTION_H__ */ diff --git a/gtk/gtkshortcutsshortcut.c b/gtk/gtkshortcutsshortcut.c new file mode 100644 index 0000000000..c14eb0a455 --- /dev/null +++ b/gtk/gtkshortcutsshortcut.c @@ -0,0 +1,264 @@ +/* gtkshortcutsshortcut.c + * + * Copyright (C) 2015 Christian Hergert + * + * 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. + * + * This library 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. + * + * You should have received a copy of the GNU Library General Public + * License along with this library. If not, see . + */ + +#include "config.h" + +#include "gtkshortcutsshortcut.h" + +#include "gtkshortcutlabelprivate.h" +#include "gtkprivate.h" +#include "gtkintl.h" + +/** + * SECTION:gtkshortcutsshortcut + * @Title: GtkShortcutsShortcut + * @Short_description: Represents a keyboard shortcut in a GtkShortcutsWindow + * + * A GtkShortcutsShortcut represents a single keyboard shortcut with + * a short text. This widget is only meant to be used with + * #GtkShortcutsWindow. + */ + +struct _GtkShortcutsShortcut +{ + GtkBox parent_instance; + + GtkShortcutLabel *accelerator; + GtkLabel *title; + + GtkSizeGroup *accel_size_group; + GtkSizeGroup *title_size_group; +}; + +struct _GtkShortcutsShortcutClass +{ + GtkBoxClass parent_class; +}; + +G_DEFINE_TYPE (GtkShortcutsShortcut, gtk_shortcuts_shortcut, GTK_TYPE_BOX) + +enum { + PROP_0, + PROP_ACCELERATOR, + PROP_TITLE, + PROP_ACCEL_SIZE_GROUP, + PROP_TITLE_SIZE_GROUP, + LAST_PROP +}; + +static GParamSpec *properties[LAST_PROP]; + +static void +gtk_shortcuts_shortcut_set_accel_size_group (GtkShortcutsShortcut *self, + GtkSizeGroup *group) +{ + if (self->accel_size_group) + gtk_size_group_remove_widget (self->accel_size_group, GTK_WIDGET (self->accelerator)); + if (group) + gtk_size_group_add_widget (group, GTK_WIDGET (self->accelerator)); + + g_set_object (&self->accel_size_group, group); +} + +static void +gtk_shortcuts_shortcut_set_title_size_group (GtkShortcutsShortcut *self, + GtkSizeGroup *group) +{ + if (self->title_size_group) + gtk_size_group_remove_widget (self->title_size_group, GTK_WIDGET (self->title)); + if (group) + gtk_size_group_add_widget (group, GTK_WIDGET (self->title)); + + g_set_object (&self->title_size_group, group); +} + +static void +gtk_shortcuts_shortcut_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GtkShortcutsShortcut *self = GTK_SHORTCUTS_SHORTCUT (object); + + switch (prop_id) + { + case PROP_TITLE: + g_value_set_string (value, gtk_label_get_label (self->title)); + break; + + case PROP_ACCELERATOR: + g_value_set_string (value, gtk_shortcut_label_get_accelerator (self->accelerator)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +gtk_shortcuts_shortcut_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GtkShortcutsShortcut *self = GTK_SHORTCUTS_SHORTCUT (object); + + switch (prop_id) + { + case PROP_ACCELERATOR: + gtk_shortcut_label_set_accelerator (self->accelerator, g_value_get_string (value)); + break; + + case PROP_ACCEL_SIZE_GROUP: + gtk_shortcuts_shortcut_set_accel_size_group (self, GTK_SIZE_GROUP (g_value_get_object (value))); + break; + + case PROP_TITLE: + gtk_label_set_label (self->title, g_value_get_string (value)); + break; + + case PROP_TITLE_SIZE_GROUP: + gtk_shortcuts_shortcut_set_title_size_group (self, GTK_SIZE_GROUP (g_value_get_object (value))); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gtk_shortcuts_shortcut_finalize (GObject *object) +{ + GtkShortcutsShortcut *self = GTK_SHORTCUTS_SHORTCUT (object); + + g_clear_object (&self->accel_size_group); + g_clear_object (&self->title_size_group); + + G_OBJECT_CLASS (gtk_shortcuts_shortcut_parent_class)->finalize (object); +} + +static void +gtk_shortcuts_shortcut_add (GtkContainer *container, + GtkWidget *widget) +{ + g_warning ("Can't add children to %s", G_OBJECT_TYPE_NAME (container)); +} + +static GType +gtk_shortcuts_shortcut_child_type (GtkContainer *container) +{ + return G_TYPE_NONE; +} + +static void +gtk_shortcuts_shortcut_class_init (GtkShortcutsShortcutClass *klass) +{ + GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = gtk_shortcuts_shortcut_finalize; + object_class->get_property = gtk_shortcuts_shortcut_get_property; + object_class->set_property = gtk_shortcuts_shortcut_set_property; + + container_class->add = gtk_shortcuts_shortcut_add; + container_class->child_type = gtk_shortcuts_shortcut_child_type; + + /** + * GtkShortcutsShortcut:accelerator: + * + * The accelerator(s) represented by this object, in the syntax + * understood by gtk_accelerator_parse(). Multiple accelerators + * can be specified by separating them with a space, but keep in + * mind that the available width is limited. + * + * Here is an example: ? F1 + * + * Note that < and > need to escaped as < and > when used + * in .ui files. + */ + properties[PROP_ACCELERATOR] = + g_param_spec_string ("accelerator", + P_("Accelerator"), + P_("Accelerator"), + NULL, + (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GtkShortcutsShortcut:title: + * + * The textual description for the accelerators represented by + * this object. This should be a short string that can fit in + * a single line. + */ + properties[PROP_TITLE] = + g_param_spec_string ("title", + P_("Title"), + P_("Title"), + NULL, + (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GtkShortcutsShortcut:accel-size-group: + * + * The size group for the accelerator portion of this shortcut. + * + * This is used internally by GTK+, and must not be modified by applications. + */ + properties[PROP_ACCEL_SIZE_GROUP] = + g_param_spec_object ("accel-size-group", + P_("Accelerator Size Group"), + P_("Accelerator Size Group"), + GTK_TYPE_SIZE_GROUP, + (G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS)); + + /** + * GtkShortcutsShortcut:title-size-group: + * + * The size group for the textual portion of this shortcut. + * + * This is used internally by GTK+, and must not be modified by applications. + */ + properties[PROP_TITLE_SIZE_GROUP] = + g_param_spec_object ("title-size-group", + P_("Title Size Group"), + P_("Title Size Group"), + GTK_TYPE_SIZE_GROUP, + (G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_properties (object_class, LAST_PROP, properties); +} + +static void +gtk_shortcuts_shortcut_init (GtkShortcutsShortcut *self) +{ + gtk_orientable_set_orientation (GTK_ORIENTABLE (self), GTK_ORIENTATION_HORIZONTAL); + gtk_box_set_spacing (GTK_BOX (self), 12); + + self->accelerator = g_object_new (GTK_TYPE_SHORTCUT_LABEL, + "visible", TRUE, + NULL); + GTK_CONTAINER_CLASS (gtk_shortcuts_shortcut_parent_class)->add (GTK_CONTAINER (self), GTK_WIDGET (self->accelerator)); + + self->title = g_object_new (GTK_TYPE_LABEL, + "hexpand", TRUE, + "visible", TRUE, + "xalign", 0.0f, + NULL); + GTK_CONTAINER_CLASS (gtk_shortcuts_shortcut_parent_class)->add (GTK_CONTAINER (self), GTK_WIDGET (self->title)); +} diff --git a/gtk/gtkshortcutsshortcut.h b/gtk/gtkshortcutsshortcut.h new file mode 100644 index 0000000000..57d76ad60e --- /dev/null +++ b/gtk/gtkshortcutsshortcut.h @@ -0,0 +1,43 @@ +/* gtkshortcutsshortcutprivate.h + * + * Copyright (C) 2015 Christian Hergert + * + * 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. + * + * This library 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. + * + * You should have received a copy of the GNU Library General Public + * License along with this library. If not, see . + */ + +#ifndef GTK_SHORTCUTS_SHORTCUT_H +#define GTK_SHORTCUTS_SHORTCUT_H + +#include + +G_BEGIN_DECLS + +#define GTK_TYPE_SHORTCUTS_SHORTCUT (gtk_shortcuts_shortcut_get_type()) +#define GTK_SHORTCUTS_SHORTCUT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_SHORTCUTS_SHORTCUT, GtkShortcutsShortcut)) +#define GTK_SHORTCUTS_SHORTCUT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_SHORTCUTS_SHORTCUT, GtkShortcutsShortcutClass)) +#define GTK_IS_SHORTCUTS_SHORTCUT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_SHORTCUTS_SHORTCUT)) +#define GTK_IS_SHORTCUTS_SHORTCUT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_SHORTCUTS_SHORTCUT)) +#define GTK_SHORTCUTS_SHORTCUT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_SHORTCUTS_SHORTCUT, GtkShortcutsShortcutClass)) + + +typedef struct _GtkShortcutsShortcut GtkShortcutsShortcut; +typedef struct _GtkShortcutsShortcutClass GtkShortcutsShortcutClass; + + +GDK_AVAILABLE_IN_3_20 +GType gtk_shortcuts_shortcut_get_type (void) G_GNUC_CONST; + +G_END_DECLS + +#endif /* GTK_SHORTCUTS_SHORTCUT_H */ diff --git a/gtk/gtkshortcutswindow.c b/gtk/gtkshortcutswindow.c new file mode 100644 index 0000000000..5e274ec1b6 --- /dev/null +++ b/gtk/gtkshortcutswindow.c @@ -0,0 +1,882 @@ +/* gtkshortcutswindow.c + * + * Copyright (C) 2015 Christian Hergert + * + * 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. + * + * This library 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. + * + * You should have received a copy of the GNU Library General Public + * License along with this library. If not, see . + */ + +#include "config.h" + +#include "gtkshortcutswindow.h" +#include "gtkscrolledwindow.h" +#include "gtkshortcutssection.h" +#include "gtkshortcutsgroup.h" +#include "gtkshortcutsgesture.h" +#include "gtkshortcutsshortcut.h" +#include "gtksearchbar.h" +#include "gtksearchentry.h" +#include "gtkprivate.h" +#include "gtkintl.h" + +/** + * SECTION:gtkshortcutswindow + * @Title: GtkShortcutsWindow + * @Short_description: Toplevel which shows help for shortcuts + * + * A GtkShortcutsWindow shows brief information about the keyboard shortcuts + * and gestures of an application. The shortcuts can be grouped, and you can + * have multiple sections in this window, corresponding to the major modes of + * your application. + * + * Additionally, the shortcuts can be filtered by the current view, to avoid + * showing information that is not relevant in the current application context. + * + * The recommended way to construct a GtkShortcutsWindow is with GtkBuilder, + * by populating a #GtkShortcutsWindow with one or more #GtkShortcutsSection + * objects, which contain #GtkShortcutsGroups that in turn contain objects of + * class #GtkShortcutsShortcut or #GtkShortcutsGesture. + * + * # A simple example: + * + * ![](gedit-shortcuts.png) + * + * This example has as single section. As you can see, the shortcut groups + * are arranged in columns, and spread across several pages if there are too + * many to find on a single page. + * + * The .ui file for this example can be found [here](https://git.gnome.org/browse/gtk+/tree/demos/gtk-demo/shortcuts-gedit.ui). + * + * # An example with multiple views: + * + * ![](clocks-shortcuts.png) + * + * This example shows a #GtkShortcutsWindow that has been configured to show only + * the shortcuts relevant to the "stopwatch" view. + * + * The .ui file for this example can be found [here](https://git.gnome.org/browse/gtk+/tree/demos/gtk-demo/shortcuts-clocks.ui). + * + * # An example with multiple sections: + * + * ![](builder-shortcuts.png) + * + * This example shows a #GtkShortcutsWindow with two sections, "Editor Shortcuts" + * and "Terminal Shortcuts". + * + * The .ui file for this example can be found [here](https://git.gnome.org/browse/gtk+/tree/demos/gtk-demo/shortcuts-clocks.ui). + */ + +typedef struct +{ + GHashTable *keywords; + gchar *initial_section; + gchar *last_section_name; + gchar *view_name; + GtkSizeGroup *search_text_group; + GtkSizeGroup *search_image_group; + GHashTable *search_items_hash; + + GtkStack *stack; + GtkStack *title_stack; + GtkMenuButton *menu_button; + GtkLabel *menu_label; + GtkSearchBar *search_bar; + GtkSearchEntry *search_entry; + GtkHeaderBar *header_bar; + GtkPopover *popover; + GtkListBox *list_box; + GtkBox *search_gestures; + GtkBox *search_shortcuts; +} GtkShortcutsWindowPrivate; + +typedef struct +{ + GtkShortcutsWindow *self; + GtkBuilder *builder; + GQueue *stack; + gchar *property_name; + guint translatable : 1; +} ViewsParserData; + + +G_DEFINE_TYPE_WITH_PRIVATE (GtkShortcutsWindow, gtk_shortcuts_window, GTK_TYPE_WINDOW) + + +enum { + CLOSE, + SEARCH, + LAST_SIGNAL +}; + +enum { + PROP_0, + PROP_SECTION_NAME, + PROP_VIEW_NAME, + LAST_PROP +}; + +static GParamSpec *properties[LAST_PROP]; +static guint signals[LAST_SIGNAL]; + + +static gint +number_of_children (GtkContainer *container) +{ + GList *children; + gint n; + + children = gtk_container_get_children (container); + n = g_list_length (children); + g_list_free (children); + + return n; +} + +static void +update_title_stack (GtkShortcutsWindow *self) +{ + GtkShortcutsWindowPrivate *priv = gtk_shortcuts_window_get_instance_private (self); + GtkWidget *visible_child; + + visible_child = gtk_stack_get_visible_child (priv->stack); + + if (GTK_IS_SHORTCUTS_SECTION (visible_child)) + { + if (number_of_children (GTK_CONTAINER (priv->stack)) > 3) + { + gchar *title; + + gtk_stack_set_visible_child_name (priv->title_stack, "sections"); + g_object_get (visible_child, "title", &title, NULL); + gtk_label_set_label (priv->menu_label, title); + g_free (title); + } + else + { + gtk_stack_set_visible_child_name (priv->title_stack, "title"); + } + } + else if (visible_child != NULL) + { + gtk_stack_set_visible_child_name (priv->title_stack, "search"); + } +} + +static void +gtk_shortcuts_window_add_search_item (GtkWidget *child, gpointer data) +{ + GtkShortcutsWindow *self = data; + GtkShortcutsWindowPrivate *priv = gtk_shortcuts_window_get_instance_private (self); + GtkWidget *item; + gchar *subtitle = NULL; + gchar *accelerator = NULL; + gchar *title = NULL; + gchar *hash_key = NULL; + GIcon *icon = NULL; + gchar *str; + gchar *keywords; + + if (GTK_IS_SHORTCUTS_SHORTCUT (child)) + { + g_object_get (child, + "accelerator", &accelerator, + "title", &title, + NULL); + + hash_key = g_strdup_printf ("%s-%s", title, accelerator); + if (g_hash_table_contains (priv->search_items_hash, hash_key)) + { + g_free (hash_key); + g_free (title); + g_free (accelerator); + return; + } + + g_hash_table_insert (priv->search_items_hash, hash_key, GINT_TO_POINTER (1)); + + item = g_object_new (GTK_TYPE_SHORTCUTS_SHORTCUT, + "visible", TRUE, + "accelerator", accelerator, + "title", title, + "accel-size-group", priv->search_image_group, + "title-size-group", priv->search_text_group, + NULL); + + str = g_strdup_printf ("%s %s", accelerator, title); + keywords = g_utf8_strdown (str, -1); + + g_hash_table_insert (priv->keywords, item, keywords); + gtk_container_add (GTK_CONTAINER (priv->search_shortcuts), item); + + g_free (title); + g_free (accelerator); + g_free (str); + } + else if (GTK_IS_SHORTCUTS_GESTURE (child)) + { + g_object_get (child, + "title", &title, + "subtitle", &subtitle, + "icon", &icon, + NULL); + + hash_key = g_strdup_printf ("%s-%s", title, subtitle); + if (g_hash_table_contains (priv->search_items_hash, hash_key)) + { + g_free (subtitle); + g_free (title); + g_free (hash_key); + g_clear_object (&icon); + return; + } + + g_hash_table_insert (priv->search_items_hash, hash_key, GINT_TO_POINTER (1)); + + item = g_object_new (GTK_TYPE_SHORTCUTS_GESTURE, + "visible", TRUE, + "title", title, + "subtitle", subtitle, + "icon", icon, + "icon-size-group", priv->search_image_group, + "title-size-group", priv->search_text_group, + NULL); + + str = g_strdup_printf ("%s %s", title, subtitle); + keywords = g_utf8_strdown (str, -1); + + g_hash_table_insert (priv->keywords, item, keywords); + gtk_container_add (GTK_CONTAINER (priv->search_gestures), item); + + g_free (subtitle); + g_free (title); + g_clear_object (&icon); + g_free (str); + } + else if (GTK_IS_CONTAINER (child)) + { + gtk_container_foreach (GTK_CONTAINER (child), gtk_shortcuts_window_add_search_item, self); + } +} + +static void +gtk_shortcuts_window_add_section (GtkShortcutsWindow *self, + GtkShortcutsSection *section) +{ + GtkShortcutsWindowPrivate *priv = gtk_shortcuts_window_get_instance_private (self); + GtkListBoxRow *row; + gchar *title; + gchar *name; + const gchar *visible_section; + GtkWidget *label; + + gtk_container_foreach (GTK_CONTAINER (section), gtk_shortcuts_window_add_search_item, self); + + g_object_get (section, + "section-name", &name, + "title", &title, + NULL); + + if (name == NULL) + name = g_strdup ("shortcuts"); + + gtk_stack_add_titled (priv->stack, GTK_WIDGET (section), name, title); + + visible_section = gtk_stack_get_visible_child_name (priv->stack); + if (strcmp (visible_section, "internal-search") == 0 || + (priv->initial_section && strcmp (priv->initial_section, visible_section) == 0)) + gtk_stack_set_visible_child (priv->stack, GTK_WIDGET (section)); + + row = g_object_new (GTK_TYPE_LIST_BOX_ROW, + "visible", TRUE, + NULL); + g_object_set_data_full (G_OBJECT (row), "GTK_SHORTCUTS_SECTION_NAME", g_strdup (name), g_free); + label = g_object_new (GTK_TYPE_LABEL, + "margin", 6, + "label", title, + "xalign", 0.5f, + "visible", TRUE, + NULL); + gtk_container_add (GTK_CONTAINER (row), GTK_WIDGET (label)); + gtk_container_add (GTK_CONTAINER (priv->list_box), GTK_WIDGET (row)); + + update_title_stack (self); + + g_free (name); + g_free (title); +} + +static void +gtk_shortcuts_window_add (GtkContainer *container, + GtkWidget *widget) +{ + GtkShortcutsWindow *self = (GtkShortcutsWindow *)container; + + if (GTK_IS_SHORTCUTS_SECTION (widget)) + gtk_shortcuts_window_add_section (self, GTK_SHORTCUTS_SECTION (widget)); + else + g_warning ("Can't add children of type %s to %s", + G_OBJECT_TYPE_NAME (widget), + G_OBJECT_TYPE_NAME (container)); +} + +static void +gtk_shortcuts_window_set_view_name (GtkShortcutsWindow *self, + const gchar *view_name) +{ + GtkShortcutsWindowPrivate *priv = gtk_shortcuts_window_get_instance_private (self); + GList *sections, *l; + + g_free (priv->view_name); + priv->view_name = g_strdup (view_name); + + sections = gtk_container_get_children (GTK_CONTAINER (priv->stack)); + for (l = sections; l; l = l->next) + { + GtkShortcutsSection *section = l->data; + + if (GTK_IS_SHORTCUTS_SECTION (section)) + g_object_set (section, "view-name", priv->view_name, NULL); + } + g_list_free (sections); +} + +static void +gtk_shortcuts_window_set_section_name (GtkShortcutsWindow *self, + const gchar *section_name) +{ + GtkShortcutsWindowPrivate *priv = gtk_shortcuts_window_get_instance_private (self); + GtkWidget *section; + + g_free (priv->initial_section); + priv->initial_section = g_strdup (section_name); + + section = gtk_stack_get_child_by_name (priv->stack, section_name); + if (section) + gtk_stack_set_visible_child (priv->stack, section); +} + +static void +gtk_shortcuts_window__list_box__row_activated (GtkShortcutsWindow *self, + GtkListBoxRow *row, + GtkListBox *list_box) +{ + GtkShortcutsWindowPrivate *priv = gtk_shortcuts_window_get_instance_private (self); + const gchar *name; + + name = g_object_get_data (G_OBJECT (row), "GTK_SHORTCUTS_SECTION_NAME"); + gtk_stack_set_visible_child_name (priv->stack, name); + gtk_widget_hide (GTK_WIDGET (priv->popover)); +} + +static void +gtk_shortcuts_window__entry__changed (GtkShortcutsWindow *self, + GtkSearchEntry *search_entry) +{ + GtkShortcutsWindowPrivate *priv = gtk_shortcuts_window_get_instance_private (self); + gchar *downcase = NULL; + GHashTableIter iter; + const gchar *text; + const gchar *last_section_name; + gpointer key; + gpointer value; + gboolean has_result; + + text = gtk_entry_get_text (GTK_ENTRY (search_entry)); + + if (!text || !*text) + { + if (priv->last_section_name != NULL) + { + gtk_stack_set_visible_child_name (priv->stack, priv->last_section_name); + return; + } + } + + last_section_name = gtk_stack_get_visible_child_name (priv->stack); + + if (g_strcmp0 (last_section_name, "internal-search") != 0 && + g_strcmp0 (last_section_name, "no-search-results") != 0) + { + g_free (priv->last_section_name); + priv->last_section_name = g_strdup (last_section_name); + } + + downcase = g_utf8_strdown (text, -1); + + g_hash_table_iter_init (&iter, priv->keywords); + + has_result = FALSE; + while (g_hash_table_iter_next (&iter, &key, &value)) + { + GtkWidget *widget = key; + const gchar *keywords = value; + gboolean match; + + match = strstr (keywords, downcase) != NULL; + gtk_widget_set_visible (widget, match); + has_result |= match; + } + + g_free (downcase); + + if (has_result) + gtk_stack_set_visible_child_name (priv->stack, "internal-search"); + else + gtk_stack_set_visible_child_name (priv->stack, "no-search-results"); +} + +static void +gtk_shortcuts_window__search_mode__changed (GtkShortcutsWindow *self) +{ + GtkShortcutsWindowPrivate *priv = gtk_shortcuts_window_get_instance_private (self); + + if (!gtk_search_bar_get_search_mode (priv->search_bar)) + { + if (priv->last_section_name != NULL) + gtk_stack_set_visible_child_name (priv->stack, priv->last_section_name); + } +} + +static void +gtk_shortcuts_window_close (GtkShortcutsWindow *self) +{ + gtk_window_close (GTK_WINDOW (self)); +} + +static void +gtk_shortcuts_window_search (GtkShortcutsWindow *self) +{ + GtkShortcutsWindowPrivate *priv = gtk_shortcuts_window_get_instance_private (self); + + gtk_search_bar_set_search_mode (priv->search_bar, TRUE); +} + +static void +gtk_shortcuts_window_constructed (GObject *object) +{ + GtkShortcutsWindow *self = (GtkShortcutsWindow *)object; + GtkShortcutsWindowPrivate *priv = gtk_shortcuts_window_get_instance_private (self); + + G_OBJECT_CLASS (gtk_shortcuts_window_parent_class)->constructed (object); + + if (priv->initial_section != NULL) + gtk_stack_set_visible_child_name (priv->stack, priv->initial_section); +} + +static void +gtk_shortcuts_window_finalize (GObject *object) +{ + GtkShortcutsWindow *self = (GtkShortcutsWindow *)object; + GtkShortcutsWindowPrivate *priv = gtk_shortcuts_window_get_instance_private (self); + + g_clear_pointer (&priv->keywords, g_hash_table_unref); + g_clear_pointer (&priv->initial_section, g_free); + g_clear_pointer (&priv->view_name, g_free); + g_clear_pointer (&priv->last_section_name, g_free); + g_clear_pointer (&priv->search_items_hash, g_hash_table_unref); + + g_clear_object (&priv->search_image_group); + g_clear_object (&priv->search_text_group); + + G_OBJECT_CLASS (gtk_shortcuts_window_parent_class)->finalize (object); +} + +static void +gtk_shortcuts_window_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GtkShortcutsWindow *self = (GtkShortcutsWindow *)object; + GtkShortcutsWindowPrivate *priv = gtk_shortcuts_window_get_instance_private (self); + + switch (prop_id) + { + case PROP_SECTION_NAME: + { + GtkWidget *child = gtk_stack_get_visible_child (priv->stack); + + if (child != NULL) + { + gchar *name = NULL; + + gtk_container_child_get (GTK_CONTAINER (priv->stack), child, + "name", &name, + NULL); + g_value_take_string (value, name); + } + } + break; + + case PROP_VIEW_NAME: + g_value_set_string (value, priv->view_name); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +gtk_shortcuts_window_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GtkShortcutsWindow *self = (GtkShortcutsWindow *)object; + + switch (prop_id) + { + case PROP_SECTION_NAME: + gtk_shortcuts_window_set_section_name (self, g_value_get_string (value)); + break; + + case PROP_VIEW_NAME: + gtk_shortcuts_window_set_view_name (self, g_value_get_string (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +gtk_shortcuts_window_unmap (GtkWidget *widget) +{ + GtkShortcutsWindow *self = (GtkShortcutsWindow *)widget; + GtkShortcutsWindowPrivate *priv = gtk_shortcuts_window_get_instance_private (self); + + gtk_search_bar_set_search_mode (priv->search_bar, FALSE); + + GTK_WIDGET_CLASS (gtk_shortcuts_window_parent_class)->unmap (widget); +} + +static GType +gtk_shortcuts_window_child_type (GtkContainer *container) +{ + return GTK_TYPE_SHORTCUTS_SECTION; +} + +static void +gtk_shortcuts_window_class_init (GtkShortcutsWindowClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass); + GtkBindingSet *binding_set = gtk_binding_set_by_class (klass); + + object_class->constructed = gtk_shortcuts_window_constructed; + object_class->finalize = gtk_shortcuts_window_finalize; + object_class->get_property = gtk_shortcuts_window_get_property; + object_class->set_property = gtk_shortcuts_window_set_property; + + widget_class->unmap = gtk_shortcuts_window_unmap; + container_class->add = gtk_shortcuts_window_add; + container_class->child_type = gtk_shortcuts_window_child_type; + + klass->close = gtk_shortcuts_window_close; + klass->search = gtk_shortcuts_window_search; + + /** + * GtkShortcutsWindow:section-name: + * + * The name of the section to show. + * + * This should be the section-name of one of the #GtkShortcutsSection + * objects that are in this shortcuts window. + */ + properties[PROP_SECTION_NAME] = + g_param_spec_string ("section-name", P_("Section Name"), P_("Section Name"), + NULL, + (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /** + * GtkShortcutsWindow:view-name: + * + * The view name by which to filter the contents. + * + * This should correspond to the #GtkShortcutsGroup:view property of some of + * the #GtkShortcutsGroup objects that are inside this shortcuts window. + * + * Set this to %NULL to show all groups. + */ + properties[PROP_VIEW_NAME] = + g_param_spec_string ("view-name", P_("View Name"), P_("View Name"), + NULL, + (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + g_object_class_install_properties (object_class, LAST_PROP, properties); + + /** + * GtkShortcutsWindow::close: + * + * The ::close signal is a + * [keybinding signal][GtkBindingSignal] + * which gets emitted when the user uses a keybinding to close + * the window. + * + * The default binding for this signal is the Escape key. + */ + signals[CLOSE] = g_signal_new (I_("close"), + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (GtkShortcutsWindowClass, close), + NULL, NULL, NULL, + G_TYPE_NONE, + 0); + + /** + * GtkShortcutsWindow::search: + * + * The ::search signal is a + * [keybinding signal][GtkBindingSignal] + * which gets emitted when the user uses a keybinding to start a search. + * + * The default binding for this signal is Control-F. + */ + signals[SEARCH] = g_signal_new (I_("search"), + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (GtkShortcutsWindowClass, search), + NULL, NULL, NULL, + G_TYPE_NONE, + 0); + + gtk_binding_entry_add_signal (binding_set, GDK_KEY_Escape, 0, "close", 0); + gtk_binding_entry_add_signal (binding_set, GDK_KEY_f, GDK_CONTROL_MASK, "search", 0); + + g_type_ensure (GTK_TYPE_SHORTCUTS_GROUP); + g_type_ensure (GTK_TYPE_SHORTCUTS_GROUP); + g_type_ensure (GTK_TYPE_SHORTCUTS_GESTURE); + g_type_ensure (GTK_TYPE_SHORTCUTS_SHORTCUT); +} + +static gboolean +window_key_press_event_cb (GtkWidget *window, + GdkEvent *event, + gpointer data) +{ + GtkShortcutsWindow *self = GTK_SHORTCUTS_WINDOW (window); + GtkShortcutsWindowPrivate *priv = gtk_shortcuts_window_get_instance_private (self); + + return gtk_search_bar_handle_event (priv->search_bar, event); +} + +static void +gtk_shortcuts_window_init (GtkShortcutsWindow *self) +{ + GtkShortcutsWindowPrivate *priv = gtk_shortcuts_window_get_instance_private (self); + GtkToggleButton *search_button; + GtkBox *main_box; + GtkBox *menu_box; + GtkBox *box; + GtkArrow *arrow; + GtkWidget *scroller; + GtkWidget *label; + GtkWidget *empty; + PangoAttrList *attributes; + + gtk_window_set_resizable (GTK_WINDOW (self), FALSE); + gtk_window_set_type_hint (GTK_WINDOW (self), GDK_WINDOW_TYPE_HINT_DIALOG); + + g_signal_connect (self, "key-press-event", + G_CALLBACK (window_key_press_event_cb), NULL); + + priv->keywords = g_hash_table_new_full (NULL, NULL, NULL, g_free); + priv->search_items_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + + priv->search_text_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); + priv->search_image_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); + + priv->header_bar = g_object_new (GTK_TYPE_HEADER_BAR, + "show-close-button", TRUE, + "visible", TRUE, + NULL); + gtk_window_set_titlebar (GTK_WINDOW (self), GTK_WIDGET (priv->header_bar)); + + search_button = g_object_new (GTK_TYPE_TOGGLE_BUTTON, + "child", g_object_new (GTK_TYPE_IMAGE, + "visible", TRUE, + "icon-name", "edit-find-symbolic", + NULL), + "visible", TRUE, + NULL); + gtk_container_add (GTK_CONTAINER (priv->header_bar), GTK_WIDGET (search_button)); + + main_box = g_object_new (GTK_TYPE_BOX, + "orientation", GTK_ORIENTATION_VERTICAL, + "visible", TRUE, + NULL); + GTK_CONTAINER_CLASS (gtk_shortcuts_window_parent_class)->add (GTK_CONTAINER (self), GTK_WIDGET (main_box)); + + priv->search_bar = g_object_new (GTK_TYPE_SEARCH_BAR, + "visible", TRUE, + NULL); + g_object_bind_property (priv->search_bar, "search-mode-enabled", + search_button, "active", + G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL); + gtk_container_add (GTK_CONTAINER (main_box), GTK_WIDGET (priv->search_bar)); + + priv->stack = g_object_new (GTK_TYPE_STACK, + "expand", TRUE, + "homogeneous", TRUE, + "transition-type", GTK_STACK_TRANSITION_TYPE_CROSSFADE, + "visible", TRUE, + NULL); + gtk_container_add (GTK_CONTAINER (main_box), GTK_WIDGET (priv->stack)); + + priv->title_stack = g_object_new (GTK_TYPE_STACK, + "visible", TRUE, + NULL); + gtk_header_bar_set_custom_title (priv->header_bar, GTK_WIDGET (priv->title_stack)); + + label = gtk_label_new (_("Shortcuts")); + gtk_widget_show (label); + gtk_style_context_add_class (gtk_widget_get_style_context (label), "title"); + gtk_stack_add_named (priv->title_stack, label, "title"); + + label = gtk_label_new (_("Search Results")); + gtk_widget_show (label); + gtk_style_context_add_class (gtk_widget_get_style_context (label), "title"); + gtk_stack_add_named (priv->title_stack, label, "search"); + + priv->menu_button = g_object_new (GTK_TYPE_MENU_BUTTON, + "focus-on-click", FALSE, + "visible", TRUE, + NULL); + gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (priv->menu_button)), "flat"); + gtk_stack_add_named (priv->title_stack, GTK_WIDGET (priv->menu_button), "sections"); + + menu_box = g_object_new (GTK_TYPE_BOX, + "orientation", GTK_ORIENTATION_HORIZONTAL, + "spacing", 6, + "visible", TRUE, + NULL); + gtk_container_add (GTK_CONTAINER (priv->menu_button), GTK_WIDGET (menu_box)); + + priv->menu_label = g_object_new (GTK_TYPE_LABEL, + "visible", TRUE, + NULL); + gtk_container_add (GTK_CONTAINER (menu_box), GTK_WIDGET (priv->menu_label)); + + G_GNUC_BEGIN_IGNORE_DEPRECATIONS; + arrow = g_object_new (GTK_TYPE_ARROW, + "arrow-type", GTK_ARROW_DOWN, + "visible", TRUE, + NULL); + gtk_container_add (GTK_CONTAINER (menu_box), GTK_WIDGET (arrow)); + G_GNUC_END_IGNORE_DEPRECATIONS; + + priv->popover = g_object_new (GTK_TYPE_POPOVER, + "border-width", 6, + "relative-to", priv->menu_button, + "position", GTK_POS_BOTTOM, + NULL); + gtk_menu_button_set_popover (priv->menu_button, GTK_WIDGET (priv->popover)); + + priv->list_box = g_object_new (GTK_TYPE_LIST_BOX, + "selection-mode", GTK_SELECTION_NONE, + "visible", TRUE, + NULL); + g_signal_connect_object (priv->list_box, + "row-activated", + G_CALLBACK (gtk_shortcuts_window__list_box__row_activated), + self, + G_CONNECT_SWAPPED); + gtk_container_add (GTK_CONTAINER (priv->popover), GTK_WIDGET (priv->list_box)); + + priv->search_entry = GTK_SEARCH_ENTRY (gtk_search_entry_new ()); + gtk_widget_show (GTK_WIDGET (priv->search_entry)); + gtk_container_add (GTK_CONTAINER (priv->search_bar), GTK_WIDGET (priv->search_entry)); + g_object_set (priv->search_entry, + "placeholder-text", _("Search Shortcuts"), + "width-chars", 40, + NULL); + g_signal_connect_object (priv->search_entry, + "search-changed", + G_CALLBACK (gtk_shortcuts_window__entry__changed), + self, + G_CONNECT_SWAPPED); + g_signal_connect_object (priv->search_bar, + "notify::search-mode-enabled", + G_CALLBACK (gtk_shortcuts_window__search_mode__changed), + self, + G_CONNECT_SWAPPED); + + g_signal_connect_object (priv->stack, "notify::visible-child", + G_CALLBACK (update_title_stack), self, G_CONNECT_SWAPPED); + + scroller = g_object_new (GTK_TYPE_SCROLLED_WINDOW, + "visible", TRUE, + NULL); + box = g_object_new (GTK_TYPE_BOX, + "border-width", 24, + "halign", GTK_ALIGN_CENTER, + "spacing", 24, + "orientation", GTK_ORIENTATION_VERTICAL, + "visible", TRUE, + NULL); + gtk_container_add (GTK_CONTAINER (scroller), GTK_WIDGET (box)); + gtk_stack_add_named (priv->stack, scroller, "internal-search"); + + priv->search_shortcuts = g_object_new (GTK_TYPE_BOX, + "halign", GTK_ALIGN_CENTER, + "spacing", 6, + "orientation", GTK_ORIENTATION_VERTICAL, + "visible", TRUE, + NULL); + gtk_container_add (GTK_CONTAINER (box), GTK_WIDGET (priv->search_shortcuts)); + + priv->search_gestures = g_object_new (GTK_TYPE_BOX, + "halign", GTK_ALIGN_CENTER, + "spacing", 6, + "orientation", GTK_ORIENTATION_VERTICAL, + "visible", TRUE, + NULL); + gtk_container_add (GTK_CONTAINER (box), GTK_WIDGET (priv->search_gestures)); + + empty = g_object_new (GTK_TYPE_GRID, + "visible", TRUE, + "row-spacing", 12, + "margin", 12, + "hexpand", TRUE, + "vexpand", TRUE, + "halign", GTK_ALIGN_CENTER, + "valign", GTK_ALIGN_CENTER, + NULL); + gtk_style_context_add_class (gtk_widget_get_style_context (empty), "dim-label"); + gtk_grid_attach (GTK_GRID (empty), + g_object_new (GTK_TYPE_IMAGE, + "visible", TRUE, + "icon-name", "edit-find-symbolic", + "pixel-size", 72, + NULL), + 0, 0, 1, 1); + attributes = pango_attr_list_new (); + pango_attr_list_insert (attributes, pango_attr_weight_new (PANGO_WEIGHT_BOLD)); + pango_attr_list_insert (attributes, pango_attr_scale_new (1.44)); + label = g_object_new (GTK_TYPE_LABEL, + "visible", TRUE, + "label", _("No Results Found"), + "attributes", attributes, + NULL); + pango_attr_list_unref (attributes); + gtk_grid_attach (GTK_GRID (empty), label, 0, 1, 1, 1); + label = g_object_new (GTK_TYPE_LABEL, + "visible", TRUE, + "label", _("Try a different search"), + NULL); + gtk_grid_attach (GTK_GRID (empty), label, 0, 2, 1, 1); + + gtk_stack_add_named (priv->stack, empty, "no-search-results"); +} diff --git a/gtk/gtkshortcutswindow.h b/gtk/gtkshortcutswindow.h new file mode 100644 index 0000000000..ca2ded8317 --- /dev/null +++ b/gtk/gtkshortcutswindow.h @@ -0,0 +1,57 @@ +/* gtkshortcutswindow.h + * + * Copyright (C) 2015 Christian Hergert + * + * 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. + * + * This library 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. + * + * You should have received a copy of the GNU Library General Public + * License along with this library. If not, see . + */ + +#ifndef __GTK_SHORTCUTS_WINDOW_H__ +#define __GTK_SHORTCUTS_WINDOW_H__ + +#include + +G_BEGIN_DECLS + +#define GTK_TYPE_SHORTCUTS_WINDOW (gtk_shortcuts_window_get_type ()) +#define GTK_SHORTCUTS_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_SHORTCUTS_WINDOW, GtkShortcutsWindow)) +#define GTK_SHORTCUTS_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_SHORTCUTS_WINDOW, GtkShortcutsWindowClass)) +#define GTK_IS_SHORTCUTS_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_SHORTCUTS_WINDOW)) +#define GTK_IS_SHORTCUTS_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_SHORTCUTS_WINDOW)) +#define GTK_SHORTCUTS_WINDOW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_SHORTCUTS_WINDOW, GtkShortcutsWindowClass)) + + +typedef struct _GtkShortcutsWindow GtkShortcutsWindow; +typedef struct _GtkShortcutsWindowClass GtkShortcutsWindowClass; + + +struct _GtkShortcutsWindow +{ + GtkWindow window; +}; + +struct _GtkShortcutsWindowClass +{ + GtkWindowClass parent_class; + + void (*close) (GtkShortcutsWindow *self); + void (*search) (GtkShortcutsWindow *self); +}; + +GDK_AVAILABLE_IN_3_20 +GType gtk_shortcuts_window_get_type (void) G_GNUC_CONST; + + +G_END_DECLS + +#endif /* GTK_SHORTCUTS_WINDOW _H */