Commit 8748db65 authored by Tristan Van Berkom's avatar Tristan Van Berkom

Added GladeEditorSkeleton

The skeleton supports automatic propagation of loading of it's child
GladePropertyEditors and GladeEditables and implements GtkBuildableIface
in order to load the child editors from builder script.
parent 0b406443
......@@ -87,6 +87,7 @@ libgladeui_2_la_SOURCES = \
glade-editable.c \
glade-editor.c \
glade-editor-property.c \
glade-editor-skeleton.c \
glade-editor-table.c \
glade-id-allocator.c \
glade-id-allocator.h \
......@@ -148,6 +149,7 @@ libgladeuiinclude_HEADERS = \
glade-editable.h \
glade-editor.h \
glade-editor-property.h \
glade-editor-skeleton.h \
glade-editor-table.h \
glade-inspector.h \
glade-name-context.h \
......
/*
* Copyright (C) 2013 Tristan Van Berkom.
*
* 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.1 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 program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Authors:
* Tristan Van Berkom <tvb@gnome.org>
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <glib/gi18n-lib.h>
#include "glade.h"
#include "glade-widget.h"
#include "glade-popup.h"
#include "glade-editable.h"
#include "glade-editor-skeleton.h"
/* GObjectClass */
static void glade_editor_skeleton_dispose (GObject *object);
/* GladeEditableIface */
static void glade_editor_skeleton_editable_init (GladeEditableIface *iface);
/* GtkBuildableIface */
static void glade_editor_skeleton_buildable_init (GtkBuildableIface *iface);
struct _GladeEditorSkeletonPrivate
{
GSList *editors;
};
static GladeEditableIface *parent_editable_iface;
static GtkBuildableIface *parent_buildable_iface;
G_DEFINE_TYPE_WITH_CODE (GladeEditorSkeleton, glade_editor_skeleton, GTK_TYPE_BOX,
G_IMPLEMENT_INTERFACE (GLADE_TYPE_EDITABLE,
glade_editor_skeleton_editable_init)
G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
glade_editor_skeleton_buildable_init));
static void
glade_editor_skeleton_init (GladeEditorSkeleton *skeleton)
{
skeleton->priv =
G_TYPE_INSTANCE_GET_PRIVATE (skeleton,
GLADE_TYPE_EDITOR_SKELETON,
GladeEditorSkeletonPrivate);
}
static void
glade_editor_skeleton_class_init (GladeEditorSkeletonClass *class)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (class);
gobject_class->dispose = glade_editor_skeleton_dispose;
g_type_class_add_private (gobject_class, sizeof (GladeEditorSkeletonPrivate));
}
/***********************************************************
* GObjectClass *
***********************************************************/
static void
glade_editor_skeleton_dispose (GObject *object)
{
GladeEditorSkeleton *skeleton = GLADE_EDITOR_SKELETON (object);
GladeEditorSkeletonPrivate *priv = skeleton->priv;
if (priv->editors)
{
g_slist_free_full (priv->editors, (GDestroyNotify)g_object_unref);
priv->editors = NULL;
}
G_OBJECT_CLASS (glade_editor_skeleton_parent_class)->dispose (object);
}
/*******************************************************************************
* GladeEditableIface *
*******************************************************************************/
static void
glade_editor_skeleton_load (GladeEditable *editable,
GladeWidget *widget)
{
GladeEditorSkeleton *skeleton = GLADE_EDITOR_SKELETON (editable);
GladeEditorSkeletonPrivate *priv = skeleton->priv;
GSList *l;
/* Chain up to default implementation */
parent_editable_iface->load (editable, widget);
for (l = priv->editors; l; l = l->next)
{
GladePropertyEditor *editor = l->data;
glade_property_editor_load (editor, widget);
}
}
static void
glade_editor_skeleton_set_show_name (GladeEditable * editable, gboolean show_name)
{
GladeEditorSkeleton *skeleton = GLADE_EDITOR_SKELETON (editable);
GladeEditorSkeletonPrivate *priv = skeleton->priv;
GSList *l;
for (l = priv->editors; l; l = l->next)
{
GladePropertyEditor *editor = l->data;
if (GLADE_IS_EDITABLE (editor))
glade_editable_set_show_name (GLADE_EDITABLE (editor), show_name);
}
}
static void
glade_editor_skeleton_editable_init (GladeEditableIface * iface)
{
parent_editable_iface = g_type_default_interface_peek (GLADE_TYPE_EDITABLE);
iface->load = glade_editor_skeleton_load;
iface->set_show_name = glade_editor_skeleton_set_show_name;
}
/*******************************************************************************
* GtkBuildableIface *
*******************************************************************************/
typedef struct
{
GSList *editors;
} EditorParserData;
static void
editor_start_element (GMarkupParseContext *context,
const gchar *element_name,
const gchar **names,
const gchar **values,
gpointer user_data,
GError **error)
{
EditorParserData *editor_data = (EditorParserData *)user_data;
gchar *id;
if (strcmp (element_name, "editor") == 0)
{
if (g_markup_collect_attributes (element_name,
names,
values,
error,
G_MARKUP_COLLECT_STRDUP, "id", &id,
G_MARKUP_COLLECT_INVALID))
{
editor_data->editors = g_slist_append (editor_data->editors, id);
}
}
else if (strcmp (element_name, "child-editors") == 0)
;
else
g_warning ("Unsupported tag for GladeEditorSkeleton: %s\n", element_name);
}
static const GMarkupParser editor_parser =
{
editor_start_element,
};
static gboolean
glade_editor_skeleton_custom_tag_start (GtkBuildable *buildable,
GtkBuilder *builder,
GObject *child,
const gchar *tagname,
GMarkupParser *parser,
gpointer *data)
{
if (child)
return FALSE;
if (strcmp (tagname, "child-editors") == 0)
{
EditorParserData *parser_data;
parser_data = g_slice_new0 (EditorParserData);
*parser = editor_parser;
*data = parser_data;
return TRUE;
}
return parent_buildable_iface->custom_tag_start (buildable, builder, child,
tagname, parser, data);
}
static void
glade_editor_skeleton_custom_finished (GtkBuildable *buildable,
GtkBuilder *builder,
GObject *child,
const gchar *tagname,
gpointer user_data)
{
EditorParserData *editor_data = (EditorParserData *)user_data;
GSList *l;
if (strcmp (tagname, "child-editors"))
{
parent_buildable_iface->custom_finished (buildable, builder, child,
tagname, user_data);
return;
}
for (l = editor_data->editors; l; l = l->next)
{
GObject *object;
gchar *id = l->data;
object = gtk_builder_get_object (builder, id);
if (!GLADE_IS_PROPERTY_EDITOR (object))
g_warning ("Object '%s' is not a property editor\n",
object ? G_OBJECT_TYPE_NAME (object) : "(null)");
else
glade_editor_skeleton_add_editor (GLADE_EDITOR_SKELETON (buildable),
GLADE_PROPERTY_EDITOR (object));
}
g_slist_free_full (editor_data->editors, g_free);
g_slice_free (EditorParserData, editor_data);
}
static void
glade_editor_skeleton_buildable_init (GtkBuildableIface *iface)
{
parent_buildable_iface = g_type_interface_peek_parent (iface);
iface->custom_tag_start = glade_editor_skeleton_custom_tag_start;
iface->custom_finished = glade_editor_skeleton_custom_finished;
}
/*******************************************************************************
* API *
*******************************************************************************/
GtkWidget *
glade_editor_skeleton_new (void)
{
return g_object_new (GLADE_TYPE_EDITOR_SKELETON, NULL);
}
void
glade_editor_skeleton_add_editor (GladeEditorSkeleton *skeleton,
GladePropertyEditor *editor)
{
GladeEditorSkeletonPrivate *priv;
g_return_if_fail (GLADE_IS_EDITOR_SKELETON (skeleton));
g_return_if_fail (GLADE_IS_PROPERTY_EDITOR (editor));
priv = skeleton->priv;
g_object_ref (editor);
priv->editors = g_slist_prepend (priv->editors, editor);
}
/*
* Copyright (C) 2013 Tristan Van Berkom.
*
* 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.1 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 program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Authors:
* Tristan Van Berkom <tvb@gnome.org>
*/
#ifndef __GLADE_EDITOR_SKELETON_H__
#define __GLADE_EDITOR_SKELETON_H__
#include <gtk/gtk.h>
#include <gladeui/glade-xml-utils.h>
#include <gladeui/glade-property-editor.h>
G_BEGIN_DECLS
#define GLADE_TYPE_EDITOR_SKELETON (glade_editor_skeleton_get_type ())
#define GLADE_EDITOR_SKELETON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GLADE_TYPE_EDITOR_SKELETON, GladeEditorSkeleton))
#define GLADE_EDITOR_SKELETON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GLADE_TYPE_EDITOR_SKELETON, GladeEditorSkeletonClass))
#define GLADE_IS_EDITOR_SKELETON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GLADE_TYPE_EDITOR_SKELETON))
#define GLADE_IS_EDITOR_SKELETON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GLADE_TYPE_EDITOR_SKELETON))
#define GLADE_EDITOR_SKELETON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GLADE_TYPE_EDITOR_SKELETON, GladeEditorSkeletonClass))
typedef struct _GladeEditorSkeleton GladeEditorSkeleton;
typedef struct _GladeEditorSkeletonClass GladeEditorSkeletonClass;
typedef struct _GladeEditorSkeletonPrivate GladeEditorSkeletonPrivate;
struct _GladeEditorSkeleton
{
/*< private >*/
GtkBox box;
GladeEditorSkeletonPrivate *priv;
};
struct _GladeEditorSkeletonClass
{
GtkBoxClass parent_class;
};
GType glade_editor_skeleton_get_type (void) G_GNUC_CONST;
GtkWidget *glade_editor_skeleton_new (void);
void glade_editor_skeleton_add_editor (GladeEditorSkeleton *skeleton,
GladePropertyEditor *editor);
G_END_DECLS
#endif /* __GLADE_EDITOR_SKELETON_H__ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment