diff --git a/CMakeLists.txt b/CMakeLists.txt index c17e1f1..2199f07 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -125,6 +125,7 @@ set (liblogdiag_SOURCES liblogdiag/ld-diagram-view.c liblogdiag/ld-library.c liblogdiag/ld-library-toolbar.c + liblogdiag/ld-library-pane.c liblogdiag/ld-symbol-category.c liblogdiag/ld-symbol.c liblogdiag/ld-lua.c @@ -142,6 +143,7 @@ set (liblogdiag_HEADERS liblogdiag/ld-diagram-view.h liblogdiag/ld-library.h liblogdiag/ld-library-toolbar.h + liblogdiag/ld-library-pane.h liblogdiag/ld-symbol-category.h liblogdiag/ld-symbol.h liblogdiag/ld-lua.h diff --git a/liblogdiag/ld-library-pane.c b/liblogdiag/ld-library-pane.c new file mode 100644 index 0000000..6d4f84e --- /dev/null +++ b/liblogdiag/ld-library-pane.c @@ -0,0 +1,227 @@ +/* + * ld-library-pane.c + * + * This file is a part of logdiag. + * Copyright Přemysl Janouch 2011. All rights reserved. + * + * See the file LICENSE for licensing information. + * + */ + +#include "liblogdiag.h" +#include "config.h" + + +/** + * SECTION:ld-library-pane + * @short_description: A library pane + * @see_also: #LdLibrary + * + * #LdLibraryPane enables the user to drag symbols from an #LdLibrary + * onto #LdDiagramView. + */ + +/* + * LdLibraryPanePrivate: + * @library: a library object assigned as a model. + */ +struct _LdLibraryPanePrivate +{ + LdLibrary *library; +}; + +enum +{ + PROP_0, + PROP_LIBRARY +}; + +static void ld_library_pane_get_property (GObject *object, guint property_id, + GValue *value, GParamSpec *pspec); +static void ld_library_pane_set_property (GObject *object, guint property_id, + const GValue *value, GParamSpec *pspec); +static void ld_library_pane_dispose (GObject *gobject); + +static void reload_library (LdLibraryPane *self); +static void load_category_cb (gpointer data, gpointer user_data); + + +G_DEFINE_TYPE (LdLibraryPane, ld_library_pane, GTK_TYPE_VBOX); + +static void +ld_library_pane_class_init (LdLibraryPaneClass *klass) +{ + GObjectClass *object_class; + GParamSpec *pspec; + + object_class = G_OBJECT_CLASS (klass); + object_class->get_property = ld_library_pane_get_property; + object_class->set_property = ld_library_pane_set_property; + object_class->dispose = ld_library_pane_dispose; + +/** + * LdLibraryPane:library: + * + * The #LdLibrary that this toolbar retrieves symbols from. + */ + pspec = g_param_spec_object ("library", "Library", + "The library that this toolbar retrieves symbols from.", + LD_TYPE_LIBRARY, G_PARAM_READWRITE); + g_object_class_install_property (object_class, PROP_LIBRARY, pspec); + + g_type_class_add_private (klass, sizeof (LdLibraryPanePrivate)); +} + +static void +ld_library_pane_init (LdLibraryPane *self) +{ + self->priv = G_TYPE_INSTANCE_GET_PRIVATE + (self, LD_TYPE_LIBRARY_PANE, LdLibraryPanePrivate); +} + +static void +ld_library_pane_dispose (GObject *gobject) +{ + LdLibraryPane *self; + + self = LD_LIBRARY_PANE (gobject); + + ld_library_pane_set_library (self, NULL); + + /* Chain up to the parent class. */ + G_OBJECT_CLASS (ld_library_pane_parent_class)->dispose (gobject); +} + +static void +ld_library_pane_get_property (GObject *object, guint property_id, + GValue *value, GParamSpec *pspec) +{ + LdLibraryPane *self; + + self = LD_LIBRARY_PANE (object); + switch (property_id) + { + case PROP_LIBRARY: + g_value_set_object (value, ld_library_pane_get_library (self)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} + +static void +ld_library_pane_set_property (GObject *object, guint property_id, + const GValue *value, GParamSpec *pspec) +{ + LdLibraryPane *self; + + self = LD_LIBRARY_PANE (object); + switch (property_id) + { + case PROP_LIBRARY: + ld_library_pane_set_library (self, + LD_LIBRARY (g_value_get_object (value))); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} + + +/** + * ld_library_pane_new: + * + * Create an instance. + */ +GtkWidget * +ld_library_pane_new (void) +{ + return g_object_new (LD_TYPE_LIBRARY_PANE, NULL); +} + +/** + * ld_library_pane_set_library: + * @self: an #LdLibraryPane object. + * @library: (allow-none): the library to be assigned to the pane. + * + * Assign an #LdLibrary object to the pane. + */ +void +ld_library_pane_set_library (LdLibraryPane *self, LdLibrary *library) +{ + g_return_if_fail (LD_IS_LIBRARY_PANE (self)); + g_return_if_fail (LD_IS_LIBRARY (library) || library == NULL); + + if (self->priv->library) + { + g_signal_handlers_disconnect_by_func (self->priv->library, + reload_library, self); + g_object_unref (self->priv->library); + } + + self->priv->library = library; + + if (library) + { + g_signal_connect_data (library, "changed", + G_CALLBACK (reload_library), self, + NULL, G_CONNECT_AFTER | G_CONNECT_SWAPPED); + g_object_ref (library); + } + reload_library (self); + g_object_notify (G_OBJECT (self), "library"); +} + +/** + * ld_library_pane_get_library: + * @self: an #LdLibraryPane object. + * + * Return value: (transfer none): the #LdLibrary object + * assigned to the pane. + */ +LdLibrary * +ld_library_pane_get_library (LdLibraryPane *self) +{ + g_return_val_if_fail (LD_IS_LIBRARY_PANE (self), NULL); + return self->priv->library; +} + +static void +reload_library (LdLibraryPane *self) +{ + g_return_if_fail (LD_IS_LIBRARY_PANE (self)); + + /* Clear the toolbar first, if there was already something in it. */ + gtk_container_foreach (GTK_CONTAINER (self), + (GtkCallback) gtk_widget_destroy, NULL); + + if (self->priv->library) + { + GSList *categories; + + categories = (GSList *) ld_library_get_categories (self->priv->library); + g_slist_foreach (categories, load_category_cb, self); + } +} + +static void +load_category_cb (gpointer data, gpointer user_data) +{ + LdLibraryPane *self; + LdSymbolCategory *cat; + GtkExpander *expander; + const gchar *human_name; + + g_return_if_fail (LD_IS_LIBRARY_PANE (user_data)); + g_return_if_fail (LD_IS_SYMBOL_CATEGORY (data)); + + self = user_data; + cat = data; + + /* TODO: Set a child for the expander, recurse into category children. */ + human_name = ld_symbol_category_get_human_name (cat); + expander = GTK_EXPANDER (gtk_expander_new (human_name)); + + gtk_box_pack_start (GTK_BOX (self), GTK_WIDGET (expander), FALSE, FALSE, 0); +} + diff --git a/liblogdiag/ld-library-pane.h b/liblogdiag/ld-library-pane.h new file mode 100644 index 0000000..3b0c98d --- /dev/null +++ b/liblogdiag/ld-library-pane.h @@ -0,0 +1,61 @@ +/* + * ld-library-pane.h + * + * This file is a part of logdiag. + * Copyright Přemysl Janouch 2011. All rights reserved. + * + * See the file LICENSE for licensing information. + * + */ + +#ifndef __LD_LIBRARY_PANE_H__ +#define __LD_LIBRARY_PANE_H__ + +G_BEGIN_DECLS + + +#define LD_TYPE_LIBRARY_PANE (ld_library_pane_get_type ()) +#define LD_LIBRARY_PANE(obj) (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), LD_TYPE_LIBRARY_PANE, LdLibraryPane)) +#define LD_LIBRARY_PANE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST \ + ((klass), LD_TYPE_LIBRARY_PANE, LdLibraryPaneClass)) +#define LD_IS_LIBRARY_PANE(obj) (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), LD_TYPE_LIBRARY_PANE)) +#define LD_IS_LIBRARY_PANE_CLASS(klass) (G_TYPE_CHECK_INSTANCE_TYPE \ + ((klass), LD_TYPE_LIBRARY_PANE)) +#define LD_LIBRARY_PANE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), LD_LIBRARY_PANE, LdLibraryPaneClass)) + +typedef struct _LdLibraryPane LdLibraryPane; +typedef struct _LdLibraryPanePrivate LdLibraryPanePrivate; +typedef struct _LdLibraryPaneClass LdLibraryPaneClass; + + +/** + * LdLibraryPane: + */ +struct _LdLibraryPane +{ +/*< private >*/ + GtkVBox parent_instance; + LdLibraryPanePrivate *priv; +}; + +struct _LdLibraryPaneClass +{ +/*< private >*/ + GtkVBoxClass parent_class; +}; + + +GType ld_library_pane_get_type (void) G_GNUC_CONST; + +GtkWidget *ld_library_pane_new (void); + +void ld_library_pane_set_library (LdLibraryPane *self, LdLibrary *library); +LdLibrary *ld_library_pane_get_library (LdLibraryPane *self); + + +G_END_DECLS + +#endif /* ! __LD_LIBRARY_PANE_H__ */ diff --git a/liblogdiag/liblogdiag.h b/liblogdiag/liblogdiag.h index 2ec48bc..c60d5da 100644 --- a/liblogdiag/liblogdiag.h +++ b/liblogdiag/liblogdiag.h @@ -29,6 +29,7 @@ #include "ld-diagram-view.h" #include "ld-library-toolbar.h" +#include "ld-library-pane.h" #include "ld-lua.h" #include "ld-lua-symbol.h" diff --git a/src/ld-window-main.c b/src/ld-window-main.c index 9ca680a..2f2559e 100644 --- a/src/ld-window-main.c +++ b/src/ld-window-main.c @@ -27,6 +27,7 @@ struct _LdWindowMainPrivate GtkWidget *menu; GtkWidget *toolbar; GtkWidget *library_toolbar; + GtkWidget *library_pane; LdLibrary *library; @@ -271,6 +272,8 @@ ld_window_main_init (LdWindowMain *self) gtk_toolbar_set_orientation (GTK_TOOLBAR (priv->library_toolbar), GTK_ORIENTATION_VERTICAL); + priv->library_pane = ld_library_pane_new (); + priv->view = LD_DIAGRAM_VIEW (ld_diagram_view_new ()); priv->scrolled_window = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->scrolled_window), @@ -290,6 +293,8 @@ ld_window_main_init (LdWindowMain *self) FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (priv->hbox), priv->scrolled_window, TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (priv->hbox), priv->library_pane, + TRUE, TRUE, 0); priv->vbox = gtk_vbox_new (FALSE, 0); gtk_box_pack_start (GTK_BOX (priv->vbox), priv->menu, FALSE, FALSE, 0); @@ -334,6 +339,9 @@ ld_window_main_init (LdWindowMain *self) ld_library_toolbar_set_view (LD_LIBRARY_TOOLBAR (priv->library_toolbar), priv->view); + ld_library_pane_set_library (LD_LIBRARY_PANE (priv->library_pane), + priv->library); + g_signal_connect_after (priv->library_toolbar, "symbol-selected", G_CALLBACK (on_symbol_selected), self); g_signal_connect_after (priv->library_toolbar, "symbol-deselected",