summaryrefslogtreecommitdiff
path: root/endless/application.c
diff options
context:
space:
mode:
authorP. F. Chimento <philip.chimento@gmail.com>2013-04-15 18:04:27 +0200
committerP. F. Chimento <philip.chimento@gmail.com>2013-04-24 14:48:15 +0200
commit096c63f7ed002b99a995c35a407483a0bfa161c5 (patch)
treecf324aae1bce4f5cb9edf42e68bc9c7cb4da0964 /endless/application.c
parent7fc4090461ad888612491814e5a44aaf7e52d7ff (diff)
Application class
Add an EosApplication class. Functionality: - present main application window when activated - warn if more than one application window is added Also add a stub EosWindow class that overrides GtkWindow's "application" property to be a construct-only property. [#4]
Diffstat (limited to 'endless/application.c')
-rw-r--r--endless/application.c165
1 files changed, 165 insertions, 0 deletions
diff --git a/endless/application.c b/endless/application.c
new file mode 100644
index 0000000..ef93e13
--- /dev/null
+++ b/endless/application.c
@@ -0,0 +1,165 @@
+/* Copyright 2013 Endless Mobile, Inc. */
+
+#include "config.h"
+#include "application.h"
+
+#include <gtk/gtk.h>
+
+#include "window.h"
+
+/**
+ * SECTION:application
+ * @short_description: Start here with your application
+ * @title: Applications
+ *
+ * The #EosApplication class is where you start when programming your
+ * application.
+ * You should create a class that extends #EosApplication.
+ *
+ * You also need to think up an application ID.
+ * This takes the form of a reverse domain name, and it should be unique.
+ * This ID is used to make sure that only one copy of your application is
+ * running at any time; if a user tries to start a second copy, then the first
+ * copy is brought to the front.
+ *
+ * To set up your application's data and window, override the
+ * #GApplication::startup function, like this example do-nothing application,
+ * <quote>Smoke Grinder</quote>:
+ * |[
+ * const Lang = imports.lang;
+ * const Endless = imports.gi.Endless;
+ *
+ * const SmokeGrinder = new Lang.Class ({
+ * Name: 'SmokeGrinder',
+ * Extends: Endless.Application,
+ *
+ * vfunc_startup: function() {
+ * this.parent();
+ * this._window = new Endless.Window({application: this});
+ * this._window.show_all();
+ * },
+ * });
+ *
+ * let app = new SmokeGrinder({ application_id: "com.example.smokegrinder",
+ * flags: 0 });
+ * app.run(ARGV);
+ * ]|
+ */
+
+G_DEFINE_TYPE (EosApplication, eos_application, GTK_TYPE_APPLICATION)
+
+#define APPLICATION_PRIVATE(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), EOS_TYPE_APPLICATION, EosApplicationPrivate))
+
+struct _EosApplicationPrivate
+{
+ EosWindow *main_application_window;
+};
+
+static void
+eos_application_activate (GApplication *application)
+{
+ EosApplication *self = EOS_APPLICATION (application);
+
+ G_APPLICATION_CLASS (eos_application_parent_class)->activate (application);
+
+ /* Raise the main application window if it is iconified. This behavior will
+ be default in GTK at some future point, in which case the following
+ paragraph can be removed. */
+ if (self->priv->main_application_window)
+ {
+ gtk_window_present (GTK_WINDOW (self->priv->main_application_window));
+ }
+
+ /* TODO: Should it be required to override activate() as in GApplication? */
+}
+
+static void
+eos_application_window_added (GtkApplication *application,
+ GtkWindow *window)
+{
+ EosApplication *self = EOS_APPLICATION (application);
+
+ GTK_APPLICATION_CLASS (eos_application_parent_class)->window_added (
+ application, window);
+
+ /* If the new window is an EosWindow, then it is our main application window;
+ it should be raised when the application is activated */
+ if (EOS_IS_WINDOW (window))
+ {
+ if (self->priv->main_application_window != NULL)
+ {
+ g_error ("You should not add more than one application window.");
+ }
+ g_object_ref (window);
+ self->priv->main_application_window = EOS_WINDOW (window);
+ }
+}
+
+static void
+eos_application_window_removed (GtkApplication *application,
+ GtkWindow *window)
+{
+ EosApplication *self = EOS_APPLICATION (application);
+
+ GTK_APPLICATION_CLASS (eos_application_parent_class)->window_removed (
+ application, window);
+
+ if (EOS_IS_WINDOW (window))
+ {
+ if (self->priv->main_application_window == NULL)
+ {
+ g_warning ("EosWindow is being removed from EosApplication, although "
+ "none was added.");
+ return;
+ }
+ if (self->priv->main_application_window != EOS_WINDOW (window))
+ g_warning ("A different EosWindow is being removed from EosApplication "
+ "than the one that was added.");
+ g_object_unref (window);
+ self->priv->main_application_window = NULL;
+ }
+}
+
+static void
+eos_application_class_init (EosApplicationClass *klass)
+{
+ GApplicationClass *g_application_class = G_APPLICATION_CLASS (klass);
+ GtkApplicationClass *gtk_application_class = GTK_APPLICATION_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (EosApplicationPrivate));
+
+ g_application_class->activate = eos_application_activate;
+ gtk_application_class->window_added = eos_application_window_added;
+ gtk_application_class->window_removed = eos_application_window_removed;
+}
+
+static void
+eos_application_init (EosApplication *self)
+{
+ self->priv = APPLICATION_PRIVATE (self);
+}
+
+/* Public API */
+
+/**
+ * eos_application_new:
+ * @application_id: a unique identifier for the application, for example a
+ * reverse domain name.
+ * @flags: flags to apply to the application; see #GApplicationFlags.
+ *
+ * Create a new application. For the application ID, use a reverse domain name,
+ * such as <code>com.endlessm.weather</code>. See g_application_id_is_valid()
+ * for the full rules for application IDs.
+ *
+ * Returns: a pointer to the application.
+ */
+EosApplication *
+eos_application_new (const gchar *application_id,
+ GApplicationFlags flags)
+{
+ return g_object_new (EOS_TYPE_APPLICATION,
+ "application-id", application_id,
+ "flags", flags,
+ NULL);
+}