[gtk+] Getting started: Add an example for property actions



commit 15453349eac598fa6c7a37809bd2c189c65b4841
Author: Matthias Clasen <mclasen redhat com>
Date:   Wed Jul 24 01:13:06 2013 -0400

    Getting started: Add an example for property actions
    
    This example demonstrates property actions and object binding.

 configure.ac                                       |    1 +
 examples/Makefile.am                               |    2 +-
 examples/application9/Makefile.am                  |   48 +++
 examples/application9/app-menu.ui                  |   19 ++
 examples/application9/exampleapp.c                 |  115 +++++++
 examples/application9/exampleapp.gresource.xml     |    9 +
 examples/application9/exampleapp.h                 |   19 ++
 examples/application9/exampleappprefs.c            |   75 +++++
 examples/application9/exampleappprefs.h            |   20 ++
 examples/application9/exampleappwin.c              |  335 ++++++++++++++++++++
 examples/application9/exampleappwin.h              |   22 ++
 examples/application9/gears-menu.ui                |   16 +
 examples/application9/main.c                       |   15 +
 .../application9/org.gtk.exampleapp.gschema.xml    |   25 ++
 examples/application9/prefs.ui                     |   82 +++++
 examples/application9/window.ui                    |  113 +++++++
 16 files changed, 915 insertions(+), 1 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 133da31..954e43c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1804,6 +1804,7 @@ examples/application5/Makefile
 examples/application6/Makefile
 examples/application7/Makefile
 examples/application8/Makefile
+examples/application9/Makefile
 tests/Makefile
 tests/visuals/Makefile
 testsuite/Makefile
diff --git a/examples/Makefile.am b/examples/Makefile.am
index f2fc8c4..88166b5 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -1,7 +1,7 @@
 SUBDIRS = \
        application1 application2 application3 \
        application4 application5 application6 \
-       application7 application8
+       application7 application8 application9
 
 AM_CPPFLAGS = \
        -I$(top_srcdir)                         \
diff --git a/examples/application9/Makefile.am b/examples/application9/Makefile.am
new file mode 100644
index 0000000..a7d82f6
--- /dev/null
+++ b/examples/application9/Makefile.am
@@ -0,0 +1,48 @@
+AM_CPPFLAGS = \
+       -I$(top_srcdir)                 \
+       -I$(top_srcdir)/gdk             \
+       -I$(top_builddir)/gdk           \
+       $(GTK_DEBUG_FLAGS)              \
+       $(GTK_DEP_CFLAGS)
+
+LDADD = \
+        $(top_builddir)/gtk/libgtk-3.la \
+        $(top_builddir)/gdk/libgdk-3.la \
+        $(GTK_DEP_LIBS)
+
+
+noinst_PROGRAMS = exampleapp
+
+exampleapp_SOURCES = \
+       main.c \
+       exampleapp.c exampleapp.h \
+       exampleappwin.c exampleappwin.h \
+       exampleappprefs.c exampleappprefs.h \
+       resources.c
+
+BUILT_SOURCES = \
+       resources.c \
+       gschemas.compiled
+
+resources.c: exampleapp.gresource.xml $(shell $(GLIB_COMPILE_RESOURCES) --sourcedir=$(srcdir) 
--generate-dependencies $(srcdir)/exampleapp.gresource.xml)
+       $(AM_V_GEN) $(GLIB_COMPILE_RESOURCES) $(srcdir)/exampleapp.gresource.xml \
+               --target=$@ --sourcedir=$(srcdir) --generate-source
+
+gsettings_SCHEMAS = \
+       org.gtk.exampleapp.gschema.xml
+
+ GSETTINGS_RULES@
+
+gschemas.compiled: org.gtk.exampleapp.gschema.xml
+       $(GLIB_COMPILE_SCHEMAS) .
+
+EXTRA_DIST = \
+       window.ui \
+       app-menu.ui \
+       prefs.ui \
+       gears-menu.ui \
+       exampleapp.gresource.xml \
+       org.gtk.exampleapp.gschema.xml
+
+CLEANFILES = \
+       gschemas.compiled
diff --git a/examples/application9/app-menu.ui b/examples/application9/app-menu.ui
new file mode 100644
index 0000000..b0eddb6
--- /dev/null
+++ b/examples/application9/app-menu.ui
@@ -0,0 +1,19 @@
+<?xml version="1.0"?>
+<interface>
+  <!-- interface-requires gtk+ 3.0 -->
+  <menu id="appmenu">
+    <section>
+      <item>
+        <attribute name="label" translatable="yes">_Preferences</attribute>
+        <attribute name="action">app.preferences</attribute>
+      </item>
+    </section>
+    <section>
+      <item>
+        <attribute name="label" translatable="yes">_Quit</attribute>
+        <attribute name="action">app.quit</attribute>
+        <attribute name="accel"><![CDATA[<Ctrl>Q]]></attribute>
+      </item>
+    </section>
+  </menu>
+</interface>
diff --git a/examples/application9/exampleapp.c b/examples/application9/exampleapp.c
new file mode 100644
index 0000000..1bc6ce8
--- /dev/null
+++ b/examples/application9/exampleapp.c
@@ -0,0 +1,115 @@
+#include <gtk/gtk.h>
+
+#include "exampleapp.h"
+#include "exampleappwin.h"
+#include "exampleappprefs.h"
+
+struct _ExampleApp
+{
+  GtkApplication parent;
+};
+
+struct _ExampleAppClass
+{
+  GtkApplicationClass parent_class;
+};
+
+G_DEFINE_TYPE(ExampleApp, example_app, GTK_TYPE_APPLICATION);
+
+static void
+example_app_init (ExampleApp *app)
+{
+}
+
+static void
+preferences_activated (GSimpleAction *action,
+                       GVariant      *parameter,
+                       gpointer       app)
+{
+  ExampleAppPrefs *prefs;
+  GtkWindow *win;
+
+  win = gtk_application_get_active_window (GTK_APPLICATION (app));
+  prefs = example_app_prefs_new (EXAMPLE_APP_WINDOW (win));
+  gtk_window_present (GTK_WINDOW (prefs));
+}
+
+static void
+quit_activated (GSimpleAction *action,
+                GVariant      *parameter,
+                gpointer       app)
+{
+  g_application_quit (G_APPLICATION (app));
+}
+
+static GActionEntry app_entries[] =
+{
+  { "preferences", preferences_activated, NULL, NULL, NULL },
+  { "quit", quit_activated, NULL, NULL, NULL }
+};
+
+static void
+example_app_startup (GApplication *app)
+{
+  GtkBuilder *builder;
+  GMenuModel *app_menu;
+
+  G_APPLICATION_CLASS (example_app_parent_class)->startup (app);
+
+  g_action_map_add_action_entries (G_ACTION_MAP (app),
+                                   app_entries, G_N_ELEMENTS (app_entries),
+                                   app);
+
+  builder = gtk_builder_new_from_resource ("/org/gtk/exampleapp/app-menu.ui");
+  app_menu = G_MENU_MODEL (gtk_builder_get_object (builder, "appmenu"));
+  gtk_application_set_app_menu (GTK_APPLICATION (app), app_menu);
+  g_object_unref (builder);
+}
+
+static void
+example_app_activate (GApplication *app)
+{
+  ExampleAppWindow *win;
+
+  win = example_app_window_new (EXAMPLE_APP (app));
+  gtk_window_present (GTK_WINDOW (win));
+}
+
+static void
+example_app_open (GApplication  *app,
+                  GFile        **files,
+                  gint           n_files,
+                  const gchar   *hint)
+{
+  GList *windows;
+  ExampleAppWindow *win;
+  int i;
+
+  windows = gtk_application_get_windows (GTK_APPLICATION (app));
+  if (windows)
+    win = EXAMPLE_APP_WINDOW (windows->data);
+  else
+    win = example_app_window_new (EXAMPLE_APP (app));
+
+  for (i = 0; i < n_files; i++)
+    example_app_window_open (win, files[i]);
+
+  gtk_window_present (GTK_WINDOW (win));
+}
+
+static void
+example_app_class_init (ExampleAppClass *class)
+{
+  G_APPLICATION_CLASS (class)->startup = example_app_startup;
+  G_APPLICATION_CLASS (class)->activate = example_app_activate;
+  G_APPLICATION_CLASS (class)->open = example_app_open;
+}
+
+ExampleApp *
+example_app_new (void)
+{
+  return g_object_new (EXAMPLE_APP_TYPE,
+                       "application-id", "org.gtk.exampleapp",
+                       "flags", G_APPLICATION_HANDLES_OPEN,
+                       NULL);
+}
diff --git a/examples/application9/exampleapp.gresource.xml b/examples/application9/exampleapp.gresource.xml
new file mode 100644
index 0000000..ace59c8
--- /dev/null
+++ b/examples/application9/exampleapp.gresource.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<gresources>
+  <gresource prefix="/org/gtk/exampleapp">
+    <file preprocess="xml-stripblanks">window.ui</file>
+    <file preprocess="xml-stripblanks">app-menu.ui</file>
+    <file preprocess="xml-stripblanks">gears-menu.ui</file>
+    <file preprocess="xml-stripblanks">prefs.ui</file>
+  </gresource>
+</gresources>
diff --git a/examples/application9/exampleapp.h b/examples/application9/exampleapp.h
new file mode 100644
index 0000000..824049d
--- /dev/null
+++ b/examples/application9/exampleapp.h
@@ -0,0 +1,19 @@
+#ifndef __EXAMPLEAPP_H
+#define __EXAMPLEAPP_H
+
+#include <gtk/gtk.h>
+
+
+#define EXAMPLE_APP_TYPE (example_app_get_type ())
+#define EXAMPLE_APP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EXAMPLE_APP_TYPE, ExampleApp))
+
+
+typedef struct _ExampleApp       ExampleApp;
+typedef struct _ExampleAppClass  ExampleAppClass;
+
+
+GType           example_app_get_type    (void);
+ExampleApp     *example_app_new         (void);
+
+
+#endif /* __EXAMPLEAPP_H */
diff --git a/examples/application9/exampleappprefs.c b/examples/application9/exampleappprefs.c
new file mode 100644
index 0000000..5dcd4ca
--- /dev/null
+++ b/examples/application9/exampleappprefs.c
@@ -0,0 +1,75 @@
+#include <gtk/gtk.h>
+
+#include "exampleapp.h"
+#include "exampleappwin.h"
+#include "exampleappprefs.h"
+
+struct _ExampleAppPrefs
+{
+  GtkDialog parent;
+};
+
+struct _ExampleAppPrefsClass
+{
+  GtkDialogClass parent_class;
+};
+
+typedef struct _ExampleAppPrefsPrivate ExampleAppPrefsPrivate;
+
+struct _ExampleAppPrefsPrivate
+{
+  GSettings *settings;
+  GtkWidget *font;
+  GtkWidget *transition;
+  GtkWidget *close;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE(ExampleAppPrefs, example_app_prefs, GTK_TYPE_DIALOG)
+
+static void
+example_app_prefs_init (ExampleAppPrefs *prefs)
+{
+  ExampleAppPrefsPrivate *priv;
+
+  priv = example_app_prefs_get_instance_private (prefs);
+  gtk_widget_init_template (GTK_WIDGET (prefs));
+  priv->settings = g_settings_new ("org.gtk.exampleapp");
+
+  g_settings_bind (priv->settings, "font",
+                   priv->font, "font",
+                   G_SETTINGS_BIND_DEFAULT);
+  g_settings_bind (priv->settings, "transition",
+                   priv->transition, "active-id",
+                   G_SETTINGS_BIND_DEFAULT);
+  g_signal_connect_swapped (priv->close, "clicked",
+                            G_CALLBACK (gtk_widget_destroy), prefs);
+}
+
+static void
+example_app_prefs_dispose (GObject *object)
+{
+  ExampleAppPrefsPrivate *priv;
+
+  priv = example_app_prefs_get_instance_private (EXAMPLE_APP_PREFS (object));
+  g_clear_object (&priv->settings);
+
+  G_OBJECT_CLASS (example_app_prefs_parent_class)->dispose (object);
+}
+
+static void
+example_app_prefs_class_init (ExampleAppPrefsClass *class)
+{
+  G_OBJECT_CLASS (class)->dispose = example_app_prefs_dispose;
+
+  gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
+                                               "/org/gtk/exampleapp/prefs.ui");
+  gtk_widget_class_bind_child (GTK_WIDGET_CLASS (class), ExampleAppPrefsPrivate, font);
+  gtk_widget_class_bind_child (GTK_WIDGET_CLASS (class), ExampleAppPrefsPrivate, transition);
+  gtk_widget_class_bind_child (GTK_WIDGET_CLASS (class), ExampleAppPrefsPrivate, close);
+}
+
+ExampleAppPrefs *
+example_app_prefs_new (ExampleAppWindow *win)
+{
+  return g_object_new (EXAMPLE_APP_PREFS_TYPE, "transient-for", win, NULL);
+}
diff --git a/examples/application9/exampleappprefs.h b/examples/application9/exampleappprefs.h
new file mode 100644
index 0000000..c684889
--- /dev/null
+++ b/examples/application9/exampleappprefs.h
@@ -0,0 +1,20 @@
+#ifndef __EXAMPLEAPPPREFS_H
+#define __EXAMPLEAPPPREFS_H
+
+#include <gtk/gtk.h>
+#include "exampleappwin.h"
+
+
+#define EXAMPLE_APP_PREFS_TYPE (example_app_prefs_get_type ())
+#define EXAMPLE_APP_PREFS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EXAMPLE_APP_PREFS_TYPE, ExampleAppPrefs))
+
+
+typedef struct _ExampleAppPrefs          ExampleAppPrefs;
+typedef struct _ExampleAppPrefsClass     ExampleAppPrefsClass;
+
+
+GType                   example_app_prefs_get_type     (void);
+ExampleAppPrefs        *example_app_prefs_new          (ExampleAppWindow *win);
+
+
+#endif /* __EXAMPLEAPPPREFS_H */
diff --git a/examples/application9/exampleappwin.c b/examples/application9/exampleappwin.c
new file mode 100644
index 0000000..2d68824
--- /dev/null
+++ b/examples/application9/exampleappwin.c
@@ -0,0 +1,335 @@
+#include "exampleapp.h"
+#include "exampleappwin.h"
+#include <gtk/gtk.h>
+
+struct _ExampleAppWindow
+{
+  GtkApplicationWindow parent;
+};
+
+struct _ExampleAppWindowClass
+{
+  GtkApplicationWindowClass parent_class;
+};
+
+typedef struct _ExampleAppWindowPrivate ExampleAppWindowPrivate;
+
+struct _ExampleAppWindowPrivate
+{
+  GSettings *settings;
+  GtkWidget *stack;
+  GtkWidget *search;
+  GtkWidget *searchbar;
+  GtkWidget *searchentry;
+  GtkWidget *gears;
+  GtkWidget *sidebar;
+  GtkWidget *words;
+  GtkWidget *lines;
+  GtkWidget *lines_label;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE(ExampleAppWindow, example_app_window, GTK_TYPE_APPLICATION_WINDOW);
+
+static void
+search_text_changed (GtkEntry         *entry,
+                     ExampleAppWindow *win)
+{
+  ExampleAppWindowPrivate *priv;
+  const gchar *text;
+  GtkWidget *tab;
+  GtkWidget *view;
+  GtkTextBuffer *buffer;
+  GtkTextIter start, match_start, match_end;
+
+  text = gtk_entry_get_text (entry);
+
+  if (text[0] == '\0')
+    return;
+
+  priv = example_app_window_get_instance_private (win);
+
+  tab = gtk_stack_get_visible_child (GTK_STACK (priv->stack));
+  view = gtk_bin_get_child (GTK_BIN (tab));
+  buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
+
+  /* Very simple-minded search implementation */
+  gtk_text_buffer_get_start_iter (buffer, &start);
+  if (gtk_text_iter_forward_search (&start, text, GTK_TEXT_SEARCH_CASE_INSENSITIVE,
+                                    &match_start, &match_end, NULL))
+    {
+      gtk_text_buffer_select_range (buffer, &match_start, &match_end);
+      gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (view), &match_start,
+                                    0.0, FALSE, 0.0, 0.0);
+    }
+}
+
+static void
+find_word (GtkButton        *button,
+           ExampleAppWindow *win)
+{
+  ExampleAppWindowPrivate *priv;
+  const gchar *word;
+
+  priv = example_app_window_get_instance_private (win);
+
+  word = gtk_button_get_label (button);
+  gtk_entry_set_text (GTK_ENTRY (priv->searchentry), word);
+}
+
+static void
+update_words (ExampleAppWindow *win)
+{
+  ExampleAppWindowPrivate *priv;
+  GHashTable *strings;
+  GHashTableIter iter;
+  GtkWidget *tab, *view, *row;
+  GtkTextBuffer *buffer;
+  GtkTextIter start, end;
+  GList *children, *l;
+  gchar *word, *key;
+
+  priv = example_app_window_get_instance_private (win);
+
+  tab = gtk_stack_get_visible_child (GTK_STACK (priv->stack));
+
+  if (tab == NULL)
+    return;
+
+  view = gtk_bin_get_child (GTK_BIN (tab));
+  buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
+
+  strings = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+
+  gtk_text_buffer_get_start_iter (buffer, &start);
+  while (!gtk_text_iter_is_end (&start))
+    {
+      while (!gtk_text_iter_starts_word (&start))
+        {
+          if (!gtk_text_iter_forward_char (&start))
+            goto done;
+        }
+      end = start;
+      if (!gtk_text_iter_forward_word_end (&end))
+        goto done;
+      word = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
+      g_hash_table_add (strings, g_utf8_strdown (word, -1));
+      g_free (word);
+      start = end;
+    }
+
+done:
+  children = gtk_container_get_children (GTK_CONTAINER (priv->words));
+  for (l = children; l; l = l->next)
+    gtk_container_remove (GTK_CONTAINER (priv->words), GTK_WIDGET (l->data));
+  g_list_free (children);
+
+  g_hash_table_iter_init (&iter, strings);
+  while (g_hash_table_iter_next (&iter, (gpointer *)&key, NULL))
+    {
+      row = gtk_button_new_with_label (key);
+      g_signal_connect (row, "clicked",
+                        G_CALLBACK (find_word), win);
+      gtk_widget_show (row);
+      gtk_container_add (GTK_CONTAINER (priv->words), row);
+    }
+
+  g_hash_table_unref (strings);
+}
+
+static void
+update_lines (ExampleAppWindow *win)
+{
+  ExampleAppWindowPrivate *priv;
+  GtkWidget *tab, *view;
+  GtkTextBuffer *buffer;
+  GtkTextIter iter;
+  int count;
+  gchar *lines;
+
+  priv = example_app_window_get_instance_private (win);
+
+  tab = gtk_stack_get_visible_child (GTK_STACK (priv->stack));
+
+  if (tab == NULL)
+    return;
+
+  view = gtk_bin_get_child (GTK_BIN (tab));
+  buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
+
+  count = 0;
+
+  gtk_text_buffer_get_start_iter (buffer, &iter);
+  while (!gtk_text_iter_is_end (&iter))
+    {
+      count++;
+      if (!gtk_text_iter_forward_line (&iter))
+        break;
+    }
+
+  lines = g_strdup_printf ("%d", count);
+  gtk_label_set_text (GTK_LABEL (priv->lines), lines);
+  g_free (lines);
+}
+
+static void
+visible_child_changed (GObject          *stack,
+                       GParamSpec       *pspec,
+                       ExampleAppWindow *win)
+{
+  ExampleAppWindowPrivate *priv;
+
+  if (gtk_widget_in_destruction (GTK_WIDGET (win)))
+    return;
+
+  priv = example_app_window_get_instance_private (win);
+  gtk_search_bar_set_search_mode (GTK_SEARCH_BAR (priv->searchbar), FALSE);
+  update_words (win);
+  update_lines (win);
+}
+
+static void
+words_changed (GObject          *sidebar,
+               GParamSpec       *pspec,
+               ExampleAppWindow *win)
+{
+  update_words (win);
+}
+
+static void
+example_app_window_init (ExampleAppWindow *win)
+{
+  ExampleAppWindowPrivate *priv;
+  GtkBuilder *builder;
+  GMenuModel *menu;
+  GAction *action;
+
+  priv = example_app_window_get_instance_private (win);
+  gtk_widget_init_template (GTK_WIDGET (win));
+  priv->settings = g_settings_new ("org.gtk.exampleapp");
+
+  g_settings_bind (priv->settings, "transition",
+                   priv->stack, "transition-type",
+                   G_SETTINGS_BIND_DEFAULT);
+
+  g_settings_bind (priv->settings, "show-words",
+                   priv->sidebar, "reveal-child",
+                   G_SETTINGS_BIND_DEFAULT);
+
+  g_object_bind_property (priv->search, "active",
+                          priv->searchbar, "search-mode-enabled",
+                          G_BINDING_BIDIRECTIONAL);
+
+  g_signal_connect (priv->searchentry, "changed",
+                    G_CALLBACK (search_text_changed), win);
+  g_signal_connect (priv->stack, "notify::visible-child",
+                    G_CALLBACK (visible_child_changed), win);
+  g_signal_connect (priv->sidebar, "notify::reveal-child",
+                    G_CALLBACK (words_changed), win);
+
+  builder = gtk_builder_new_from_resource ("/org/gtk/exampleapp/gears-menu.ui");
+  menu = G_MENU_MODEL (gtk_builder_get_object (builder, "menu"));
+  gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (priv->gears), menu);
+  g_object_unref (builder);
+
+  action = g_settings_create_action (priv->settings, "show-words");
+  g_action_map_add_action (G_ACTION_MAP (win), action);
+  g_object_unref (action);
+
+  action = (GAction*) g_property_action_new ("show-lines", priv->lines, "visible");
+  g_action_map_add_action (G_ACTION_MAP (win), action);
+  g_object_unref (action);
+
+  g_object_bind_property (priv->lines, "visible",
+                          priv->lines_label, "visible",
+                          G_BINDING_DEFAULT);
+}
+
+static void
+example_app_window_dispose (GObject *object)
+{
+  ExampleAppWindow *win;
+  ExampleAppWindowPrivate *priv;
+
+  win = EXAMPLE_APP_WINDOW (object);
+  priv = example_app_window_get_instance_private (win);
+
+  g_clear_object (&priv->settings);
+
+  G_OBJECT_CLASS (example_app_window_parent_class)->dispose (object);
+}
+
+static void
+example_app_window_class_init (ExampleAppWindowClass *class)
+{
+  G_OBJECT_CLASS (class)->dispose = example_app_window_dispose;
+
+  gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
+                                               "/org/gtk/exampleapp/window.ui");
+  gtk_widget_class_bind_child (GTK_WIDGET_CLASS (class), ExampleAppWindowPrivate, stack);
+  gtk_widget_class_bind_child (GTK_WIDGET_CLASS (class), ExampleAppWindowPrivate, search);
+  gtk_widget_class_bind_child (GTK_WIDGET_CLASS (class), ExampleAppWindowPrivate, searchbar);
+  gtk_widget_class_bind_child (GTK_WIDGET_CLASS (class), ExampleAppWindowPrivate, searchentry);
+  gtk_widget_class_bind_child (GTK_WIDGET_CLASS (class), ExampleAppWindowPrivate, gears);
+  gtk_widget_class_bind_child (GTK_WIDGET_CLASS (class), ExampleAppWindowPrivate, words);
+  gtk_widget_class_bind_child (GTK_WIDGET_CLASS (class), ExampleAppWindowPrivate, sidebar);
+  gtk_widget_class_bind_child (GTK_WIDGET_CLASS (class), ExampleAppWindowPrivate, lines);
+  gtk_widget_class_bind_child (GTK_WIDGET_CLASS (class), ExampleAppWindowPrivate, lines_label);
+}
+
+ExampleAppWindow *
+example_app_window_new (ExampleApp *app)
+{
+  return g_object_new (EXAMPLE_APP_WINDOW_TYPE, "application", app, NULL);
+}
+
+void
+example_app_window_open (ExampleAppWindow *win,
+                         GFile            *file)
+{
+  ExampleAppWindowPrivate *priv;
+  gchar *basename;
+  GtkWidget *scrolled, *view;
+  gchar *contents;
+  gsize length;
+  GtkTextBuffer *buffer;
+  GtkTextTag *tag;
+  GtkTextIter start_iter, end_iter;
+
+  priv = example_app_window_get_instance_private (win);
+  basename = g_file_get_basename (file);
+
+  scrolled = gtk_scrolled_window_new (NULL, NULL);
+  gtk_widget_show (scrolled);
+  gtk_widget_set_hexpand (scrolled, TRUE);
+  gtk_widget_set_vexpand (scrolled, TRUE);
+  view = gtk_text_view_new ();
+  gtk_text_view_set_editable (GTK_TEXT_VIEW (view), FALSE);
+  gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (view), FALSE);
+  gtk_widget_show (view);
+  gtk_container_add (GTK_CONTAINER (scrolled), view);
+  gtk_stack_add_titled (GTK_STACK (priv->stack), scrolled, basename, basename);
+
+  buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
+
+  if (g_file_load_contents (file, NULL, &contents, &length, NULL, NULL))
+    {
+      gtk_text_buffer_set_text (buffer, contents, length);
+      g_free (contents);
+    }
+
+  tag = gtk_text_buffer_create_tag (buffer, NULL, NULL);
+  g_settings_bind (priv->settings, "font",
+                   tag, "font",
+                   G_SETTINGS_BIND_DEFAULT);
+
+  gtk_text_buffer_get_start_iter (buffer, &start_iter);
+  gtk_text_buffer_get_end_iter (buffer, &end_iter);
+  gtk_text_buffer_apply_tag (buffer, tag, &start_iter, &end_iter);
+
+  g_free (basename);
+
+  gtk_widget_set_sensitive (priv->search, TRUE);
+
+  update_words (win);
+  update_lines (win);
+}
diff --git a/examples/application9/exampleappwin.h b/examples/application9/exampleappwin.h
new file mode 100644
index 0000000..ed4b34f
--- /dev/null
+++ b/examples/application9/exampleappwin.h
@@ -0,0 +1,22 @@
+#ifndef __EXAMPLEAPPWIN_H
+#define __EXAMPLEAPPWIN_H
+
+#include <gtk/gtk.h>
+#include "exampleapp.h"
+
+
+#define EXAMPLE_APP_WINDOW_TYPE (example_app_window_get_type ())
+#define EXAMPLE_APP_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EXAMPLE_APP_WINDOW_TYPE, 
ExampleAppWindow))
+
+
+typedef struct _ExampleAppWindow         ExampleAppWindow;
+typedef struct _ExampleAppWindowClass    ExampleAppWindowClass;
+
+
+GType                   example_app_window_get_type     (void);
+ExampleAppWindow       *example_app_window_new          (ExampleApp *app);
+void                    example_app_window_open         (ExampleAppWindow *win,
+                                                         GFile            *file);
+
+
+#endif /* __EXAMPLEAPPWIN_H */
diff --git a/examples/application9/gears-menu.ui b/examples/application9/gears-menu.ui
new file mode 100644
index 0000000..fb0e929
--- /dev/null
+++ b/examples/application9/gears-menu.ui
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<interface>
+  <!-- interface-requires gtk+ 3.0 -->
+  <menu id="menu">
+    <section>
+      <item>
+        <attribute name="label" translatable="yes">_Words</attribute>
+        <attribute name="action">win.show-words</attribute>
+      </item>
+      <item>
+        <attribute name="label" translatable="yes">_Lines</attribute>
+        <attribute name="action">win.show-lines</attribute>
+      </item>
+    </section>
+  </menu>
+</interface>
diff --git a/examples/application9/main.c b/examples/application9/main.c
new file mode 100644
index 0000000..546d923
--- /dev/null
+++ b/examples/application9/main.c
@@ -0,0 +1,15 @@
+#include <gtk/gtk.h>
+#include <exampleapp.h>
+
+int
+main (int argc, char *argv[])
+{
+  /* Since this example is running uninstalled,
+   * we have to help it find its schema. This
+   * is *not* necessary in properly installed
+   * application.
+   */
+  g_setenv ("GSETTINGS_SCHEMA_DIR", ".", FALSE);
+
+  return g_application_run (G_APPLICATION (example_app_new ()), argc, argv);
+}
diff --git a/examples/application9/org.gtk.exampleapp.gschema.xml 
b/examples/application9/org.gtk.exampleapp.gschema.xml
new file mode 100644
index 0000000..a6929a8
--- /dev/null
+++ b/examples/application9/org.gtk.exampleapp.gschema.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schemalist>
+  <schema path="/org/gtk/exampleapp/" id="org.gtk.exampleapp">
+    <key name="font" type="s">
+      <default>'Monospace 12'</default>
+      <summary>Font</summary>
+      <description>The font to be used for content.</description>
+    </key>
+    <key name="transition" type="s">
+      <choices>
+        <choice value='none'/>
+        <choice value='crossfade'/>
+        <choice value='slide-left-right'/>
+      </choices>
+      <default>'none'</default>
+      <summary>Transition</summary>
+      <description>The transition to use when switching tabs.</description>
+    </key>
+    <key name="show-words" type="b">
+      <default>false</default>
+      <summary>Show words</summary>
+      <description>Whether to show a word list in the sidebar</description>
+    </key>
+  </schema>
+</schemalist>
diff --git a/examples/application9/prefs.ui b/examples/application9/prefs.ui
new file mode 100644
index 0000000..4e846b8
--- /dev/null
+++ b/examples/application9/prefs.ui
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <!-- interface-requires gtk+ 3.8 -->
+  <template class="ExampleAppPrefs" parent="GtkDialog">
+    <property name="title" translatable="yes">Preferences</property>
+    <property name="resizable">False</property>
+    <property name="modal">True</property>
+    <child internal-child="vbox">
+      <object class="GtkBox" id="vbox">
+        <child>
+          <object class="GtkGrid" id="grid">
+            <property name="visible">True</property>
+            <property name="margin">6</property>
+            <property name="row-spacing">12</property>
+            <property name="column-spacing">6</property>
+            <child>
+              <object class="GtkLabel" id="fontlabel">
+                <property name="visible">True</property>
+                <property name="label">_Font:</property>
+                <property name="use-underline">True</property>
+                <property name="mnemonic-widget">font</property>
+                <property name="xalign">1</property>
+              </object>
+              <packing>
+                <property name="left-attach">0</property>
+                <property name="top-attach">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkFontButton" id="font">
+                <property name="visible">True</property>
+              </object>
+              <packing>
+                <property name="left-attach">1</property>
+                <property name="top-attach">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkLabel" id="transitionlabel">
+                <property name="visible">True</property>
+                <property name="label">_Transition:</property>
+                <property name="use-underline">True</property>
+                <property name="mnemonic-widget">transition</property>
+                <property name="xalign">1</property>
+              </object>
+              <packing>
+                <property name="left-attach">0</property>
+                <property name="top-attach">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkComboBoxText" id="transition">
+                <property name="visible">True</property>
+                <items>
+                  <item translatable="yes" id="none">None</item>
+                  <item translatable="yes" id="crossfade">Fade</item>
+                  <item translatable="yes" id="slide-left-right">Slide</item>
+                </items>
+              </object>
+              <packing>
+                <property name="left-attach">1</property>
+                <property name="top-attach">1</property>
+              </packing>
+            </child>
+          </object>
+        </child>
+        <child internal-child="action_area">
+          <object class="GtkButtonBox" id="action_area">
+            <property name="visible">True</property>
+            <child>
+              <object class="GtkButton" id="close">
+                <property name="visible">True</property>
+                <property name="label">_Close</property>
+                <property name="use-underline">True</property>
+              </object>
+            </child>
+          </object>
+        </child>
+      </object>
+    </child>
+  </template>
+</interface>
diff --git a/examples/application9/window.ui b/examples/application9/window.ui
new file mode 100644
index 0000000..915dac6
--- /dev/null
+++ b/examples/application9/window.ui
@@ -0,0 +1,113 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <!-- interface-requires gtk+ 3.8 -->
+  <template class="ExampleAppWindow" parent="GtkApplicationWindow">
+    <property name="title" translatable="yes">Example Application</property>
+    <property name="default-width">600</property>
+    <property name="default-height">400</property>
+    <child>
+      <object class="GtkBox" id="content_box">
+        <property name="visible">True</property>
+        <property name="orientation">vertical</property>
+        <child>
+          <object class="GtkHeaderBar" id="header">
+            <property name="visible">True</property>
+            <child>
+              <object class="GtkLabel" id="lines_label">
+                <property name="visible">False</property>
+                <property name="label" translatable="yes">Lines:</property>
+              </object>
+              <packing>
+                <property name="pack-type">start</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkLabel" id="lines">
+                <property name="visible">False</property>
+              </object>
+              <packing>
+                <property name="pack-type">start</property>
+              </packing>
+            </child>
+            <child type="title">
+              <object class="GtkStackSwitcher" id="tabs">
+                <property name="visible">True</property>
+                <property name="stack">stack</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkToggleButton" id="search">
+                <property name="visible">True</property>
+                <property name="sensitive">False</property>
+                <child>
+                  <object class="GtkImage" id="search-icon">
+                    <property name="visible">True</property>
+                    <property name="icon-name">edit-find-symbolic</property>
+                    <property name="icon-size">1</property>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="pack-type">end</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkMenuButton" id="gears">
+                <property name="visible">True</property>
+                <child>
+                  <object class="GtkImage" id="gears-icon">
+                    <property name="visible">True</property>
+                    <property name="icon-name">emblem-system-symbolic</property>
+                    <property name="icon-size">1</property>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="pack-type">end</property>
+              </packing>
+            </child>
+          </object>
+        </child>
+        <child>
+          <object class="GtkSearchBar" id="searchbar">
+            <property name="visible">True</property>
+            <child>
+              <object class="GtkSearchEntry" id="searchentry">
+                <property name="visible">True</property>
+              </object>
+            </child>
+          </object>
+        </child>
+        <child>
+          <object class="GtkBox" id="hbox">
+            <property name="visible">True</property>
+            <child>
+              <object class="GtkRevealer" id="sidebar">
+                <property name="visible">True</property>
+                <property name="transition-type">slide-right</property>
+                <child>
+                 <object class="GtkScrolledWindow" id="sidebar-sw">
+                   <property name="visible">True</property>
+                   <property name="hscrollbar-policy">never</property>
+                   <property name="vscrollbar-policy">automatic</property>
+                   <child>
+                     <object class="GtkListBox" id="words">
+                       <property name="visible">True</property>
+                       <property name="selection-mode">none</property>
+                     </object>
+                   </child>
+                 </object>
+                </child>
+              </object>
+            </child>
+            <child>
+              <object class="GtkStack" id="stack">
+                <property name="visible">True</property>
+              </object>
+            </child>
+          </object>
+        </child>
+      </object>
+    </child>
+  </template>
+</interface>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]