]> Pileus Git - ~andy/gtk/commitdiff
Add GtkSelectionWindow
authorCarlos Garnacho <carlos@lanedo.com>
Fri, 11 Jan 2013 16:34:42 +0000 (17:34 +0100)
committerMatthias Clasen <mclasen@redhat.com>
Tue, 5 Mar 2013 21:47:58 +0000 (16:47 -0500)
This is a helper object to provide context-dependent content
edition apt for touch devices.

docs/reference/gtk/gtk-docs.sgml
docs/reference/gtk/gtk3-sections.txt
docs/reference/gtk/gtk3.types.in
gtk/Makefile.am
gtk/gtkselectionwindow.c [new file with mode: 0644]
gtk/gtkselectionwindow.h [new file with mode: 0644]

index c82e8f731c5375726f20c6a7f05a6271b583fd0b..40b5b112f247a3387e948b4f793d3f4eca07e217 100644 (file)
@@ -90,6 +90,7 @@
       <xi:include href="xml/gtkassistant.xml" />
       <xi:include href="xml/gtkoffscreenwindow.xml" />
       <xi:include href="xml/gtkbubblewindow.xml" />
+      <xi:include href="xml/gtkselectionwindow.xml" />
     </chapter>
 
     <chapter id="DisplayWidgets">
index b881cbf1fde5481801c0fcc20717e79969751e82..228bda49c4768cf7171b712c951540630e339b7d 100644 (file)
@@ -7522,3 +7522,26 @@ GTK_BUBBLE_WINDOW_GET_CLASS
 <SUBSECTION Private>
 gtk_bubble_window_get_type
 </SECTION>
+
+<SECTION>
+<FILE>gtkselectionwindow</FILE>
+<TITLE>GtkSelectionWindow</TITLE>
+GtkSelectionWindow
+gtk_selection_window_new
+gtk_selection_window_set_editable
+gtk_selection_window_get_editable
+gtk_selection_window_set_has_selection
+gtk_selection_window_get_has_selection
+gtk_selection_window_get_toolbar
+
+<SUBSECTION Standard>
+GTK_TYPE_SELECTION_WINDOW
+GTK_SELECTION_WINDOW
+GTK_SELECTION_WINDOW_CLASS
+GTK_IS_SELECTION_WINDOW
+GTK_IS_SELECTION_WINDOW_CLASS
+GTK_SELECTION_WINDOW_GET_CLASS
+
+<SUBSECTION Private>
+gtk_selection_window_get_type
+</SECTION>
index 9cc637d575de75db016344c7020d720f683182c8..7abc07d4ddace4e645803081806b5b8e08b149f8 100644 (file)
@@ -147,6 +147,7 @@ gtk_scrollable_get_type
 gtk_scrollbar_get_type
 gtk_scrolled_window_get_type
 gtk_search_entry_get_type
+gtk_selection_window_get_type
 gtk_separator_get_type
 gtk_separator_menu_item_get_type
 gtk_separator_tool_item_get_type
index ef7a7dc56a3becd9cfc14df3875e689a8a0c977e..f9797c5d4f53ef9c4175c9d03a7ddf69f6ad830b 100644 (file)
@@ -320,6 +320,7 @@ gtk_public_h_sources =              \
        gtkscrolledwindow.h     \
        gtksearchentry.h        \
        gtkselection.h          \
+       gtkselectionwindow.h    \
        gtkseparator.h          \
        gtkseparatormenuitem.h  \
        gtkseparatortoolitem.h  \
@@ -811,6 +812,7 @@ gtk_base_c_sources =                \
        gtkscrollbar.c          \
        gtkscrolledwindow.c     \
        gtkselection.c          \
+       gtkselectionwindow.c    \
        gtkseparator.c          \
        gtkseparatormenuitem.c  \
        gtkseparatortoolitem.c  \
diff --git a/gtk/gtkselectionwindow.c b/gtk/gtkselectionwindow.c
new file mode 100644 (file)
index 0000000..62d2a5a
--- /dev/null
@@ -0,0 +1,404 @@
+/* GTK - The GIMP Toolkit
+ * Copyright © 2013 Carlos Garnacho <carlosg@gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * SECTION:gtkselectionwindow
+ * @Short_description: Bubble window for content edition
+ * @Title: GtkSelectionWindow
+ *
+ * GtkSelection widget is a small helper object to implement
+ * touch-friendly content edition. #GtkEntry and #GtkTextView
+ * use this internally to allow text selection edition and
+ * manipulation.
+ */
+
+#include "config.h"
+#include "gtkselectionwindow.h"
+#include "gtkprivate.h"
+#include "gtkintl.h"
+
+#define TOOLBAR_UI                               \
+  "<ui>"                                         \
+  "  <toolbar>"                                  \
+  "    <toolitem name='cut' action='Cut' />"     \
+  "    <toolitem name='copy' action='Copy' />"   \
+  "    <toolitem name='paste' action='Paste' />" \
+  "    <separator />"                            \
+  "  </toolbar>"                                 \
+  "</ui>"
+
+static void _action_cut_cb   (GtkAction          *action,
+                              GtkSelectionWindow *window);
+static void _action_copy_cb  (GtkAction          *action,
+                              GtkSelectionWindow *window);
+static void _action_paste_cb (GtkAction          *action,
+                              GtkSelectionWindow *window);
+
+static GtkActionEntry entries[] = {
+  { "Cut", GTK_STOCK_CUT, NULL, NULL, NULL, G_CALLBACK (_action_cut_cb) },
+  { "Copy", GTK_STOCK_COPY, NULL, NULL, NULL, G_CALLBACK (_action_copy_cb) },
+  { "Paste", GTK_STOCK_PASTE, NULL, NULL, NULL, G_CALLBACK (_action_paste_cb) }
+};
+
+enum {
+  PROP_EDITABLE = 1,
+  PROP_HAS_SELECTION
+};
+
+enum {
+  CUT,
+  COPY,
+  PASTE,
+  N_SIGNALS
+};
+
+static guint signals[N_SIGNALS] = { 0 };
+
+struct _GtkSelectionWindowPrivate
+{
+  GtkUIManager *ui_manager;
+  GtkWidget *toolbar;
+  guint editable      : 1;
+  guint has_selection : 1;
+};
+
+G_DEFINE_TYPE (GtkSelectionWindow, gtk_selection_window, GTK_TYPE_BUBBLE_WINDOW)
+
+static void
+_action_cut_cb (GtkAction          *action,
+                GtkSelectionWindow *window)
+{
+  g_signal_emit (window, signals[CUT], 0);
+}
+
+static void
+_action_copy_cb (GtkAction          *action,
+                 GtkSelectionWindow *window)
+{
+  g_signal_emit (window, signals[COPY], 0);
+}
+
+static void
+_action_paste_cb (GtkAction          *action,
+                  GtkSelectionWindow *window)
+{
+  g_signal_emit (window, signals[PASTE], 0);
+}
+
+static void
+_gtk_selection_window_update_state (GtkSelectionWindow *window)
+{
+  GtkSelectionWindowPrivate *priv;
+  GtkClipboard *clipboard;
+  gboolean text_available;
+  GtkAction *action;
+
+  priv = window->_priv;
+  clipboard = gtk_widget_get_clipboard (GTK_WIDGET (window),
+                                        GDK_SELECTION_CLIPBOARD);
+  text_available = gtk_clipboard_wait_is_text_available (clipboard);
+
+  action = gtk_ui_manager_get_action (priv->ui_manager, "/toolbar/cut");
+  gtk_action_set_sensitive (action, priv->editable && priv->has_selection);
+
+  action = gtk_ui_manager_get_action (priv->ui_manager, "/toolbar/copy");
+  gtk_action_set_sensitive (action, priv->has_selection);
+
+  action = gtk_ui_manager_get_action (priv->ui_manager, "/toolbar/paste");
+  gtk_action_set_sensitive (action, text_available && priv->editable);
+}
+
+static void
+gtk_selection_window_map (GtkWidget *widget)
+{
+  _gtk_selection_window_update_state (GTK_SELECTION_WINDOW (widget));
+  GTK_WIDGET_CLASS (gtk_selection_window_parent_class)->map (widget);
+}
+
+static void
+gtk_selection_window_finalize (GObject *object)
+{
+  GtkSelectionWindowPrivate *priv;
+
+  priv = GTK_SELECTION_WINDOW (object)->_priv;
+  g_object_unref (priv->ui_manager);
+
+  G_OBJECT_CLASS (gtk_selection_window_parent_class)->finalize (object);
+}
+
+static void
+gtk_selection_window_set_property (GObject      *object,
+                                   guint         prop_id,
+                                   const GValue *value,
+                                   GParamSpec   *pspec)
+{
+  switch (prop_id)
+    {
+    case PROP_EDITABLE:
+      gtk_selection_window_set_editable (GTK_SELECTION_WINDOW (object),
+                                         g_value_get_boolean (value));
+      break;
+    case PROP_HAS_SELECTION:
+      gtk_selection_window_set_has_selection (GTK_SELECTION_WINDOW (object),
+                                              g_value_get_boolean (value));
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+gtk_selection_window_get_property (GObject    *object,
+                                   guint       prop_id,
+                                   GValue     *value,
+                                   GParamSpec *pspec)
+{
+  GtkSelectionWindowPrivate *priv;
+
+  priv = GTK_SELECTION_WINDOW (object)->_priv;
+
+  switch (prop_id)
+    {
+    case PROP_EDITABLE:
+      g_value_set_boolean (value, priv->editable);
+      break;
+    case PROP_HAS_SELECTION:
+      g_value_set_boolean (value, priv->has_selection);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+gtk_selection_window_class_init (GtkSelectionWindowClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+  object_class->finalize = gtk_selection_window_finalize;
+  object_class->set_property = gtk_selection_window_set_property;
+  object_class->get_property = gtk_selection_window_get_property;
+
+  widget_class->map = gtk_selection_window_map;
+
+  g_object_class_install_property (object_class,
+                                   PROP_EDITABLE,
+                                   g_param_spec_boolean ("editable",
+                                                         P_("Editable"),
+                                                         P_("Whether content is editable"),
+                                                         TRUE,
+                                                         GTK_PARAM_READWRITE |
+                                                         G_PARAM_CONSTRUCT));
+  g_object_class_install_property (object_class,
+                                   PROP_HAS_SELECTION,
+                                   g_param_spec_boolean ("has-selection",
+                                                         P_("Has selection"),
+                                                         P_("Whether there is any content currently selected"),
+                                                         TRUE,
+                                                         GTK_PARAM_READWRITE |
+                                                         G_PARAM_CONSTRUCT));
+  signals[CUT] =
+    g_signal_new (I_("cut"),
+                 G_OBJECT_CLASS_TYPE (object_class),
+                 G_SIGNAL_RUN_LAST, 0,
+                 NULL, NULL,
+                  g_cclosure_marshal_VOID__VOID,
+                  G_TYPE_NONE, 0);
+  signals[COPY] =
+    g_signal_new (I_("copy"),
+                 G_OBJECT_CLASS_TYPE (object_class),
+                 G_SIGNAL_RUN_LAST, 0,
+                 NULL, NULL,
+                  g_cclosure_marshal_VOID__VOID,
+                  G_TYPE_NONE, 0);
+  signals[PASTE] =
+    g_signal_new (I_("paste"),
+                 G_OBJECT_CLASS_TYPE (object_class),
+                 G_SIGNAL_RUN_LAST, 0,
+                 NULL, NULL,
+                  g_cclosure_marshal_VOID__VOID,
+                  G_TYPE_NONE, 0);
+
+  g_type_class_add_private (klass, sizeof (GtkSelectionWindowPrivate));
+}
+
+static void
+gtk_selection_window_init (GtkSelectionWindow *window)
+{
+  GtkSelectionWindowPrivate *priv;
+  GtkActionGroup *group;
+
+  window->_priv = priv = G_TYPE_INSTANCE_GET_PRIVATE (window,
+                                                      GTK_TYPE_SELECTION_WINDOW,
+                                                      GtkSelectionWindowPrivate);
+
+  group = gtk_action_group_new ("SelectionToolbar");
+  gtk_action_group_add_actions (group, entries, G_N_ELEMENTS (entries), window);
+
+  priv->ui_manager = gtk_ui_manager_new ();
+  gtk_ui_manager_insert_action_group (priv->ui_manager, group, 0);
+  gtk_ui_manager_add_ui_from_string (priv->ui_manager, TOOLBAR_UI, -1, NULL);
+
+  priv->toolbar = gtk_ui_manager_get_widget (priv->ui_manager, "/toolbar");
+  gtk_toolbar_set_show_arrow (GTK_TOOLBAR (priv->toolbar), FALSE);
+  gtk_widget_show_all (priv->toolbar);
+
+  gtk_container_add (GTK_CONTAINER (window), priv->toolbar);
+}
+
+/**
+ * gtk_selection_window_new:
+ *
+ * Creates a new #GtkSelectionWindow
+ *
+ * Returns: a newly created #GtkSelectionWindow
+ **/
+GtkWidget *
+gtk_selection_window_new (void)
+{
+  return g_object_new (GTK_TYPE_SELECTION_WINDOW, NULL);
+}
+
+/**
+ * gtk_selection_window_set_editable:
+ * @window: a #GtkSelectionWindow
+ * @editable: whether the current selection is editable
+ *
+ * Sets whether the current selection is editable. Toolbar options'
+ * sensitivity will change according to this.
+ *
+ * Since: 3.8
+ **/
+void
+gtk_selection_window_set_editable (GtkSelectionWindow *window,
+                                  gboolean            editable)
+{
+  GtkSelectionWindowPrivate *priv;
+  gboolean need_update;
+
+  g_return_if_fail (GTK_IS_SELECTION_WINDOW (window));
+
+  priv = window->_priv;
+  need_update = priv->editable != editable &&
+    gtk_widget_get_visible (GTK_WIDGET (window));
+  priv->editable = editable;
+
+  if (need_update)
+    _gtk_selection_window_update_state (window);
+
+  g_object_notify (G_OBJECT (window), "editable");
+}
+
+/**
+ * gtk_selection_window_get_editable:
+ * @window: a #GtkSelectionWindow
+ *
+ * Returns whether the contents are editable according to @window
+ *
+ * Returns: whether the contents are editable
+ *
+ * Since: 3.8
+ **/
+gboolean
+gtk_selection_window_get_editable (GtkSelectionWindow *window)
+{
+  GtkSelectionWindowPrivate *priv;
+
+  g_return_val_if_fail (GTK_IS_SELECTION_WINDOW (window), FALSE);
+
+  priv = window->_priv;
+
+  return priv->editable;
+}
+
+/**
+ * gtk_selection_window_set_has_selection:
+ * @window: a #GtkSelectionWindow
+ * @has_selection: whether there is currently a selection
+ *
+ * Sets whether there is any selected content. Toolbar options'
+ * sensitivity will change according to this.
+ *
+ * Since: 3.8
+ **/
+void
+gtk_selection_window_set_has_selection (GtkSelectionWindow *window,
+                                        gboolean            has_selection)
+{
+  GtkSelectionWindowPrivate *priv;
+  gboolean need_update;
+
+  g_return_if_fail (GTK_IS_SELECTION_WINDOW (window));
+
+  priv = window->_priv;
+  need_update = priv->has_selection != has_selection &&
+    gtk_widget_get_visible (GTK_WIDGET (window));
+  priv->has_selection = has_selection;
+
+  if (need_update)
+    _gtk_selection_window_update_state (window);
+
+  g_object_notify (G_OBJECT (window), "has-selection");
+}
+
+/**
+ * gtk_selection_window_get_has_selection:
+ * @window: a #GtkSelectionWindow
+ *
+ * Returns whether there any content is selected according to @window
+ *
+ * Returns: whether there is selected content
+ *
+ * Since: 3.8
+ **/
+gboolean
+gtk_selection_window_get_has_selection (GtkSelectionWindow *window)
+{
+  GtkSelectionWindowPrivate *priv;
+
+  g_return_val_if_fail (GTK_IS_SELECTION_WINDOW (window), FALSE);
+
+  priv = window->_priv;
+
+  return priv->has_selection;
+}
+
+/**
+ * gtk_selection_window_get_toolbar:
+ * @window: a #GtkSelectionWindow
+ *
+ * Returns the toolbar contained by @window so e.g. new elements
+ * can be added.
+ *
+ * Returns: the internal toolbar
+ *
+ * Since: 3.8
+ **/
+GtkWidget *
+gtk_selection_window_get_toolbar (GtkSelectionWindow *window)
+{
+  GtkSelectionWindowPrivate *priv;
+
+  g_return_val_if_fail (GTK_IS_SELECTION_WINDOW (window), FALSE);
+
+  priv = window->_priv;
+
+  return priv->toolbar;
+}
diff --git a/gtk/gtkselectionwindow.h b/gtk/gtkselectionwindow.h
new file mode 100644 (file)
index 0000000..edc35e1
--- /dev/null
@@ -0,0 +1,69 @@
+/* GTK - The GIMP Toolkit
+ * Copyright © 2013 Carlos Garnacho <carlosg@gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GTK_SELECTION_WINDOW_H__
+#define __GTK_SELECTION_WINDOW_H__
+
+#include <gtk/gtkbubblewindow.h>
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_SELECTION_WINDOW           (gtk_selection_window_get_type ())
+#define GTK_SELECTION_WINDOW(o)             (G_TYPE_CHECK_INSTANCE_CAST ((o), GTK_TYPE_SELECTION_WINDOW, GtkSelectionWindow))
+#define GTK_SELECTION_WINDOW_CLASS(c)       (G_TYPE_CHECK_CLASS_CAST ((c), GTK_TYPE_SELECTION_WINDOW, GtkSelectionWindowClass))
+#define GTK_IS_SELECTION_WINDOW(o)          (G_TYPE_CHECK_INSTANCE_TYPE ((o), GTK_TYPE_SELECTION_WINDOW))
+#define GTK_IS_SELECTION_WINDOW_CLASS(o)    (G_TYPE_CHECK_CLASS_TYPE ((o), GTK_TYPE_SELECTION_WINDOW))
+#define GTK_SELECTION_WINDOW_GET_CLASS(o)   (G_TYPE_INSTANCE_GET_CLASS ((o), GTK_TYPE_SELECTION_WINDOW, GtkSelectionWindowClass))
+
+typedef struct _GtkSelectionWindow GtkSelectionWindow;
+typedef struct _GtkSelectionWindowClass GtkSelectionWindowClass;
+typedef struct _GtkSelectionWindowPrivate GtkSelectionWindowPrivate;
+
+struct _GtkSelectionWindow
+{
+  GtkBubbleWindow parent_instance;
+
+  /*< private >*/
+  gpointer _priv;
+};
+
+struct _GtkSelectionWindowClass
+{
+  GtkBubbleWindowClass parent_class;
+
+  void (* cut)   (GtkSelectionWindow *window);
+  void (* copy)  (GtkSelectionWindow *window);
+  void (* paste) (GtkSelectionWindow *window);
+};
+
+GType       gtk_selection_window_get_type (void) G_GNUC_CONST;
+
+GtkWidget * gtk_selection_window_new      (void);
+
+void        gtk_selection_window_set_editable      (GtkSelectionWindow *window,
+                                                    gboolean            editable);
+gboolean    gtk_selection_window_get_editable      (GtkSelectionWindow *window);
+void        gtk_selection_window_set_has_selection (GtkSelectionWindow *window,
+                                                    gboolean            has_selection);
+gboolean    gtk_selection_window_get_has_selection (GtkSelectionWindow *window);
+
+GtkWidget * gtk_selection_window_get_toolbar (GtkSelectionWindow *window);
+
+
+G_END_DECLS
+
+#endif /* __GTK_SELECTION_POPUP_H__ */