diff --git a/CMakeLists.txt b/CMakeLists.txt index e5f4847..bb3f149 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-category-view.c + liblogdiag/ld-category-symbol-view.c liblogdiag/ld-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-category-view.h + liblogdiag/ld-category-symbol-view.h liblogdiag/ld-category.h liblogdiag/ld-symbol.h liblogdiag/ld-lua.h diff --git a/liblogdiag/ld-category-symbol-view.c b/liblogdiag/ld-category-symbol-view.c new file mode 100644 index 0000000..7489668 --- /dev/null +++ b/liblogdiag/ld-category-symbol-view.c @@ -0,0 +1,252 @@ +/* + * ld-category-symbol-view.c + * + * This file is a part of logdiag. + * Copyright Přemysl Janouch 2012. All rights reserved. + * + * See the file LICENSE for licensing information. + * + */ + +#include "liblogdiag.h" +#include "config.h" + + +/** + * SECTION:ld-category-symbol-view + * @short_description: A widget that displays symbols in a category + * @see_also: #LdCategory, #LdDiagramView + * + * #LdCategorySymbolView allows the user to drag symbols from an #LdCategory + * onto #LdDiagramView. + */ + +/* + * LdCategorySymbolViewPrivate: + * @category: a category object assigned as a model. + */ +struct _LdCategorySymbolViewPrivate +{ + LdCategory *category; + guint height_negotiation : 1; +}; + +enum +{ + PROP_0, + PROP_CATEGORY +}; + +static void ld_category_symbol_view_get_property (GObject *object, + guint property_id, GValue *value, GParamSpec *pspec); +static void ld_category_symbol_view_set_property (GObject *object, + guint property_id, const GValue *value, GParamSpec *pspec); +static void ld_category_symbol_view_finalize (GObject *gobject); + +static void on_size_request (GtkWidget *widget, GtkRequisition *requisition, + gpointer user_data); +static void on_size_allocate (GtkWidget *widget, GdkRectangle *allocation, + gpointer user_data); +static gboolean on_expose_event (GtkWidget *widget, GdkEventExpose *event, + gpointer user_data); + + +G_DEFINE_TYPE (LdCategorySymbolView, + ld_category_symbol_view, GTK_TYPE_DRAWING_AREA); + +static void +ld_category_symbol_view_class_init (LdCategorySymbolViewClass *klass) +{ + GObjectClass *object_class; + GParamSpec *pspec; + + object_class = G_OBJECT_CLASS (klass); + object_class->get_property = ld_category_symbol_view_get_property; + object_class->set_property = ld_category_symbol_view_set_property; + object_class->finalize = ld_category_symbol_view_finalize; + +/** + * LdCategorySymbolView:category: + * + * The underlying #LdCategory object of this view. + */ + pspec = g_param_spec_object ("category", "Category", + "The underlying category object of this view.", + LD_TYPE_CATEGORY, G_PARAM_READWRITE); + g_object_class_install_property (object_class, PROP_CATEGORY, pspec); + + g_type_class_add_private (klass, sizeof (LdCategorySymbolViewPrivate)); +} + +static void +ld_category_symbol_view_init (LdCategorySymbolView *self) +{ + self->priv = G_TYPE_INSTANCE_GET_PRIVATE + (self, LD_TYPE_CATEGORY_SYMBOL_VIEW, LdCategorySymbolViewPrivate); + + g_signal_connect (self, "size-allocate", + G_CALLBACK (on_size_allocate), NULL); + g_signal_connect (self, "size-request", + G_CALLBACK (on_size_request), NULL); + g_signal_connect (self, "expose-event", + G_CALLBACK (on_expose_event), NULL); + + gtk_widget_add_events (GTK_WIDGET (self), + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK + | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + | GDK_LEAVE_NOTIFY_MASK); +} + +static void +ld_category_symbol_view_finalize (GObject *gobject) +{ + LdCategorySymbolView *self; + + self = LD_CATEGORY_SYMBOL_VIEW (gobject); + + if (self->priv->category) + g_object_unref (self->priv->category); + + /* Chain up to the parent class. */ + G_OBJECT_CLASS (ld_category_symbol_view_parent_class)->finalize (gobject); +} + +static void +ld_category_symbol_view_get_property (GObject *object, guint property_id, + GValue *value, GParamSpec *pspec) +{ + LdCategorySymbolView *self; + + self = LD_CATEGORY_SYMBOL_VIEW (object); + switch (property_id) + { + case PROP_CATEGORY: + g_value_set_object (value, ld_category_symbol_view_get_category (self)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} + +static void +ld_category_symbol_view_set_property (GObject *object, guint property_id, + const GValue *value, GParamSpec *pspec) +{ + LdCategorySymbolView *self; + + self = LD_CATEGORY_SYMBOL_VIEW (object); + switch (property_id) + { + case PROP_CATEGORY: + ld_category_symbol_view_set_category (self, + LD_CATEGORY (g_value_get_object (value))); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} + +static void +on_size_request (GtkWidget *widget, GtkRequisition *requisition, + gpointer user_data) +{ + LdCategorySymbolView *self; + + self = LD_CATEGORY_SYMBOL_VIEW (widget); + + requisition->width = 10; + + if (self->priv->height_negotiation) + { + GtkAllocation alloc; + + gtk_widget_get_allocation (widget, &alloc); + requisition->height = 5000 / alloc.width; + } + else + requisition->height = 10; +} + +static void +on_size_allocate (GtkWidget *widget, GdkRectangle *allocation, + gpointer user_data) +{ + LdCategorySymbolView *self; + + self = LD_CATEGORY_SYMBOL_VIEW (widget); + + if (self->priv->height_negotiation) + self->priv->height_negotiation = FALSE; + else + { + self->priv->height_negotiation = TRUE; + gtk_widget_queue_resize (widget); + } +} + +static gboolean +on_expose_event (GtkWidget *widget, GdkEventExpose *event, gpointer user_data) +{ + cairo_t *cr; + + cr = gdk_cairo_create (gtk_widget_get_window (widget)); + gdk_cairo_rectangle (cr, &event->area); + cairo_clip (cr); + + gdk_cairo_set_source_color (cr, + >k_widget_get_style (widget)->base[GTK_STATE_NORMAL]); + cairo_paint (cr); + + cairo_destroy (cr); + return FALSE; +} + +/* ===== Generic interface etc. ============================================ */ + +/** + * ld_category_symbol_view_new: + * + * Create an instance. + */ +GtkWidget * +ld_category_symbol_view_new (void) +{ + return g_object_new (LD_TYPE_CATEGORY_SYMBOL_VIEW, NULL); +} + +/** + * ld_category_symbol_view_set_category: + * @self: an #LdCategorySymbolView object. + * @category: the #LdCategory to be assigned to the view. + * + * Assign an #LdCategory object to the view. + */ +void +ld_category_symbol_view_set_category (LdCategorySymbolView *self, + LdCategory *category) +{ + g_return_if_fail (LD_IS_CATEGORY_SYMBOL_VIEW (self)); + g_return_if_fail (LD_IS_CATEGORY (category)); + + if (self->priv->category) + g_object_unref (self->priv->category); + + self->priv->category = category; + g_object_ref (category); + + g_object_notify (G_OBJECT (self), "category"); +} + +/** + * ld_category_symbol_view_get_category: + * @self: an #LdCategorySymbolView object. + * + * Get the #LdCategory object assigned to this view. + * The reference count on the category is not incremented. + */ +LdCategory * +ld_category_symbol_view_get_category (LdCategorySymbolView *self) +{ + g_return_val_if_fail (LD_IS_CATEGORY_SYMBOL_VIEW (self), NULL); + return self->priv->category; +} diff --git a/liblogdiag/ld-category-symbol-view.h b/liblogdiag/ld-category-symbol-view.h new file mode 100644 index 0000000..10da898 --- /dev/null +++ b/liblogdiag/ld-category-symbol-view.h @@ -0,0 +1,63 @@ +/* + * ld-category-symbol-view.h + * + * This file is a part of logdiag. + * Copyright Přemysl Janouch 2012. All rights reserved. + * + * See the file LICENSE for licensing information. + * + */ + +#ifndef __LD_CATEGORY_SYMBOL_VIEW_H__ +#define __LD_CATEGORY_SYMBOL_VIEW_H__ + +G_BEGIN_DECLS + + +#define LD_TYPE_CATEGORY_SYMBOL_VIEW (ld_category_symbol_view_get_type ()) +#define LD_CATEGORY_SYMBOL_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), LD_TYPE_CATEGORY_SYMBOL_VIEW, LdCategorySymbolView)) +#define LD_CATEGORY_SYMBOL_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST \ + ((klass), LD_TYPE_CATEGORY_SYMBOL_VIEW, LdCategorySymbolViewClass)) +#define LD_IS_CATEGORY_SYMBOL_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), LD_TYPE_CATEGORY_SYMBOL_VIEW)) +#define LD_IS_CATEGORY_SYMBOL_VIEW_CLASS(klass) (G_TYPE_CHECK_INSTANCE_TYPE \ + ((klass), LD_TYPE_CATEGORY_SYMBOL_VIEW)) +#define LD_CATEGORY_SYMBOL_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), LD_CATEGORY_SYMBOL_VIEW, LdCategorySymbolViewClass)) + +typedef struct _LdCategorySymbolView LdCategorySymbolView; +typedef struct _LdCategorySymbolViewPrivate LdCategorySymbolViewPrivate; +typedef struct _LdCategorySymbolViewClass LdCategorySymbolViewClass; + + +/** + * LdCategorySymbolView: + */ +struct _LdCategorySymbolView +{ +/*< private >*/ + GtkDrawingArea parent_instance; + LdCategorySymbolViewPrivate *priv; +}; + +struct _LdCategorySymbolViewClass +{ +/*< private >*/ + GtkDrawingAreaClass parent_class; +}; + + +GType ld_category_symbol_view_get_type (void) G_GNUC_CONST; + +GtkWidget *ld_category_symbol_view_new (void); + +void ld_category_symbol_view_set_category + (LdCategorySymbolView *self, LdCategory *category); +LdCategory *ld_category_symbol_view_get_category + (LdCategorySymbolView *self); + + +G_END_DECLS + +#endif /* ! __LD_CATEGORY_SYMBOL_VIEW_H__ */ diff --git a/liblogdiag/ld-category-view.c b/liblogdiag/ld-category-view.c index 75d10f1..5c0d7d4 100644 --- a/liblogdiag/ld-category-view.c +++ b/liblogdiag/ld-category-view.c @@ -263,18 +263,27 @@ reload_category (LdCategoryView *self) if (self->priv->category) { - GSList *children; - - /* TODO: Also show the symbols. */ + GSList *symbols, *children; + symbols = (GSList *) ld_category_get_symbols (self->priv->category); children = (GSList *) ld_category_get_children (self->priv->category); + + if (symbols) + { + GtkWidget *symbol_view; + + symbol_view = ld_category_symbol_view_new (); + ld_category_symbol_view_set_category + (LD_CATEGORY_SYMBOL_VIEW (symbol_view), self->priv->category); + gtk_box_pack_start (GTK_BOX (self), symbol_view, FALSE, FALSE, 0); + } + if (children) { reconstruct_prefix (self); g_slist_foreach (children, load_category_cb, self); } - else - /* TODO: Don't show this if there are any symbols. */ + else if (!symbols) gtk_box_pack_start (GTK_BOX (self), create_empty_label (), FALSE, FALSE, 0); } diff --git a/liblogdiag/liblogdiag.h b/liblogdiag/liblogdiag.h index 97ee308..e3b0d90 100644 --- a/liblogdiag/liblogdiag.h +++ b/liblogdiag/liblogdiag.h @@ -28,6 +28,7 @@ #include "ld-diagram.h" #include "ld-diagram-view.h" +#include "ld-category-symbol-view.h" #include "ld-category-view.h" #include "ld-lua.h"