summaryrefslogtreecommitdiffstats
path: root/src/widgets/sp-widget.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/widgets/sp-widget.cpp')
-rw-r--r--src/widgets/sp-widget.cpp455
1 files changed, 249 insertions, 206 deletions
diff --git a/src/widgets/sp-widget.cpp b/src/widgets/sp-widget.cpp
index 8a3e3d113..eb07a6d52 100644
--- a/src/widgets/sp-widget.cpp
+++ b/src/widgets/sp-widget.cpp
@@ -1,311 +1,354 @@
-#define __SP_WIDGET_C__
-
/*
* Abstract base class for dynamic control widgets
*
* Authors:
* Lauris Kaplinski <lauris@kaplinski.com>
* bulia byak <buliabyak@users.sf.net>
+ * Jon A. Cruz <jon@joncruz.org>
*
* Copyright (C) 1999-2002 Lauris Kaplinski
* Copyright (C) 2000-2001 Ximian, Inc.
+ * Copyright (C) 2012 Authors
*
* Released under GNU GPL, read the file 'COPYING' for more information
*/
#include "macros.h"
-#include "../document.h"
+#include "document.h"
#include "sp-widget.h"
#include "helper/sp-marshal.h"
+using Inkscape::SPWidgetImpl;
+
enum {
- CONSTRUCT,
- MODIFY_SELECTION,
- CHANGE_SELECTION,
- SET_SELECTION,
- LAST_SIGNAL
+ CONSTRUCT,
+ MODIFY_SELECTION,
+ CHANGE_SELECTION,
+ SET_SELECTION,
+ LAST_SIGNAL
};
-static void sp_widget_class_init (SPWidgetClass *klass);
-static void sp_widget_init (SPWidget *widget);
+namespace Inkscape {
-static void sp_widget_dispose(GObject *object);
+class SPWidgetImpl
+{
+public:
+ SPWidgetImpl(SPWidget &target);
+ ~SPWidgetImpl();
+
+ static void classInit(SPWidgetClass *klass);
+ static void init(SPWidget *widget);
+ static void dispose(GObject *object);
+ static void show(GtkWidget *widget);
+ static void hide(GtkWidget *widget);
+ static void sizeRequest(GtkWidget *widget, GtkRequisition *requisition);
+#if GTK_CHECK_VERSION(3,0,0)
+ static void getPreferredWidth(GtkWidget *widget,
+ gint *minimal_width,
+ gint *natural_width);
+
+ static void getPreferredHeight(GtkWidget *widget,
+ gint *minimal_height,
+ gint *natural_height);
+ static gboolean draw(GtkWidget *widget, cairo_t *cr);
+#else
+ static gboolean expose(GtkWidget *widget, GdkEventExpose *event);
+#endif
+ static void sizeAllocate(GtkWidget *widget, GtkAllocation *allocation);
+ static void modifySelectionCB(Application *inkscape, Selection *selection, guint flags, SPWidget *spw);
+ static void changeSelectionCB(Application *inkscape, Selection *selection, SPWidget *spw);
+ static void setSelectionCB(Application *inkscape, Selection *selection, SPWidget *spw);
-static void sp_widget_show (GtkWidget *widget);
-static void sp_widget_hide (GtkWidget *widget);
-static void sp_widget_size_request (GtkWidget *widget, GtkRequisition *requisition);
+ static GtkWidget *constructGlobal(SPWidget *spw, Inkscape::Application *inkscape);
-#if GTK_CHECK_VERSION(3,0,0)
-static void sp_widget_get_preferred_width(GtkWidget *widget,
- gint *minimal_width,
- gint *natural_width);
+ void modifySelection(Application *inkscape, Selection *selection, guint flags);
+ void changeSelection(Application *inkscape, Selection *selection);
+ void setSelection(Application *inkscape, Selection *selection);
-static void sp_widget_get_preferred_height(GtkWidget *widget,
- gint *minimal_height,
- gint *natural_height);
+private:
+ static GtkBinClass *parentClass;
+ static guint signals[LAST_SIGNAL];
-static gboolean sp_widget_draw(GtkWidget *widget, cairo_t *cr);
-#else
-static gboolean sp_widget_expose(GtkWidget *widget, GdkEventExpose *event);
-#endif
+ SPWidget &_target;
+};
-static void sp_widget_size_allocate (GtkWidget *widget, GtkAllocation *allocation);
+GtkBinClass *SPWidgetImpl::parentClass = 0;
+guint SPWidgetImpl::signals[LAST_SIGNAL] = {0};
-static void sp_widget_modify_selection (Inkscape::Application *inkscape, Inkscape::Selection *selection, guint flags, SPWidget *spw);
-static void sp_widget_change_selection (Inkscape::Application *inkscape, Inkscape::Selection *selection, SPWidget *spw);
-static void sp_widget_set_selection (Inkscape::Application *inkscape, Inkscape::Selection *selection, SPWidget *spw);
+} // namespace Inkscape
-static GtkBinClass *parent_class;
-static guint signals[LAST_SIGNAL] = {0};
+GType SPWidget::getType()
+{
+ static GType type = 0;
+ if (!type) {
+ static GTypeInfo const info = {
+ sizeof(SPWidgetClass),
+ NULL, NULL,
+ reinterpret_cast<GClassInitFunc>(SPWidgetImpl::classInit),
+ NULL, NULL,
+ sizeof(SPWidget),
+ 0,
+ reinterpret_cast<GInstanceInitFunc>(SPWidgetImpl::init),
+ NULL
+ };
+ type = g_type_register_static(GTK_TYPE_BIN,
+ "SPWidget",
+ &info,
+ static_cast<GTypeFlags>(0));
+ }
+ return type;
+}
-GType
-sp_widget_get_type (void)
+namespace Inkscape {
+
+SPWidgetImpl::SPWidgetImpl(SPWidget &target) :
+ _target(target)
{
- static GType type = 0;
- if (!type) {
- static const GTypeInfo info = {
- sizeof (SPWidgetClass),
- NULL, NULL,
- (GClassInitFunc) sp_widget_class_init,
- NULL, NULL,
- sizeof (SPWidget),
- 0,
- (GInstanceInitFunc) sp_widget_init,
- NULL
- };
- type = g_type_register_static (GTK_TYPE_BIN,
- "SPWidget",
- &info,
- (GTypeFlags)0);
- }
- return type;
}
-static void sp_widget_class_init(SPWidgetClass *klass)
+SPWidgetImpl::~SPWidgetImpl()
{
- GObjectClass *object_class = (GObjectClass *) klass;
- GtkWidgetClass *widget_class;
-
- widget_class = (GtkWidgetClass *) klass;
-
- parent_class = (GtkBinClass*)g_type_class_peek_parent (klass);
-
- object_class->dispose = sp_widget_dispose;
-
- signals[CONSTRUCT] = g_signal_new ("construct",
- G_TYPE_FROM_CLASS(object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (SPWidgetClass, construct),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
- signals[CHANGE_SELECTION] = g_signal_new ("change_selection",
- G_TYPE_FROM_CLASS(object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (SPWidgetClass, change_selection),
- NULL, NULL,
- g_cclosure_marshal_VOID__POINTER,
- G_TYPE_NONE, 1,
- G_TYPE_POINTER);
- signals[MODIFY_SELECTION] = g_signal_new ("modify_selection",
- G_TYPE_FROM_CLASS(object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (SPWidgetClass, modify_selection),
- NULL, NULL,
- sp_marshal_VOID__POINTER_UINT,
- G_TYPE_NONE, 2,
- G_TYPE_POINTER, G_TYPE_UINT);
- signals[SET_SELECTION] = g_signal_new ("set_selection",
- G_TYPE_FROM_CLASS(object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (SPWidgetClass, set_selection),
- NULL, NULL,
- g_cclosure_marshal_VOID__POINTER,
- G_TYPE_NONE, 1,
- G_TYPE_POINTER);
-
- widget_class->show = sp_widget_show;
- widget_class->hide = sp_widget_hide;
+}
+
+void SPWidgetImpl::classInit(SPWidgetClass *klass)
+{
+ GObjectClass *object_class = reinterpret_cast<GObjectClass *>(klass);
+ GtkWidgetClass *widget_class = reinterpret_cast<GtkWidgetClass *>(klass);
+
+ parentClass = reinterpret_cast<GtkBinClass *>(g_type_class_peek_parent(klass));
+
+ object_class->dispose = SPWidgetImpl::dispose;
+
+ signals[CONSTRUCT] = g_signal_new ("construct",
+ G_TYPE_FROM_CLASS(object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(SPWidgetClass, construct),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[CHANGE_SELECTION] = g_signal_new ("change_selection",
+ G_TYPE_FROM_CLASS(object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(SPWidgetClass, change_selection),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1,
+ G_TYPE_POINTER);
+
+ signals[MODIFY_SELECTION] = g_signal_new ("modify_selection",
+ G_TYPE_FROM_CLASS(object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(SPWidgetClass, modify_selection),
+ NULL, NULL,
+ sp_marshal_VOID__POINTER_UINT,
+ G_TYPE_NONE, 2,
+ G_TYPE_POINTER, G_TYPE_UINT);
+
+ signals[SET_SELECTION] = g_signal_new ("set_selection",
+ G_TYPE_FROM_CLASS(object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(SPWidgetClass, set_selection),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1,
+ G_TYPE_POINTER);
+
+ widget_class->show = SPWidgetImpl::show;
+ widget_class->hide = SPWidgetImpl::hide;
#if GTK_CHECK_VERSION(3,0,0)
- widget_class->get_preferred_width = sp_widget_get_preferred_width;
- widget_class->get_preferred_height = sp_widget_get_preferred_height;
- widget_class->draw = sp_widget_draw;
+ widget_class->get_preferred_width = SPWidgetImpl::getPreferredWidth;
+ widget_class->get_preferred_height = SPWidgetImpl::getPreferredHeight;
+ widget_class->draw = SPWidgetImpl::draw;
#else
- widget_class->size_request = sp_widget_size_request;
- widget_class->expose_event = sp_widget_expose;
+ widget_class->size_request = SPWidgetImpl::sizeRequest;
+ widget_class->expose_event = SPWidgetImpl::expose;
#endif
- widget_class->size_allocate = sp_widget_size_allocate;
+ widget_class->size_allocate = SPWidgetImpl::sizeAllocate;
}
-static void
-sp_widget_init (SPWidget *spw)
+void SPWidgetImpl::init(SPWidget *spw)
{
- spw->inkscape = NULL;
+ spw->inkscape = NULL;
+
+ spw->_impl = new SPWidgetImpl(*spw); // ctor invoked after all other init
}
-static void sp_widget_dispose(GObject *object)
+void SPWidgetImpl::dispose(GObject *object)
{
- SPWidget *spw;
+ SPWidget *spw = reinterpret_cast<SPWidget *>(object);
- spw = (SPWidget *) object;
+ if (spw->inkscape) {
+ // Disconnect signals
- if (spw->inkscape) {
- /* Disconnect signals */
- // the checks are necessary because when destroy is caused by the the program shutting down,
- // the inkscape object may already be (partly?) invalid --bb
- if (G_IS_OBJECT(spw->inkscape) && G_OBJECT_GET_CLASS(G_OBJECT(spw->inkscape)))
- sp_signal_disconnect_by_data (spw->inkscape, spw);
- spw->inkscape = NULL;
- }
+ // the checks are necessary because when destroy is caused by the the program shutting down,
+ // the inkscape object may already be (partly?) invalid --bb
+ if (G_IS_OBJECT(spw->inkscape) && G_OBJECT_GET_CLASS(spw->inkscape)) {
+ sp_signal_disconnect_by_data(spw->inkscape, spw);
+ }
+ spw->inkscape = NULL;
+ }
- if (((GObjectClass *) parent_class)->dispose)
- (* ((GObjectClass *) parent_class)->dispose) (object);
+ delete spw->_impl;
+ spw->_impl = 0;
+
+ if (reinterpret_cast<GObjectClass *>(parentClass)->dispose) {
+ (*reinterpret_cast<GObjectClass *>(parentClass)->dispose)(object);
+ }
}
-static void
-sp_widget_show (GtkWidget *widget)
+void SPWidgetImpl::show(GtkWidget *widget)
{
- SPWidget *spw;
-
- spw = SP_WIDGET (widget);
-
- if (spw->inkscape) {
- /* Connect signals */
- g_signal_connect (G_OBJECT (spw->inkscape), "modify_selection", G_CALLBACK (sp_widget_modify_selection), spw);
- g_signal_connect (G_OBJECT (spw->inkscape), "change_selection", G_CALLBACK (sp_widget_change_selection), spw);
- g_signal_connect (G_OBJECT (spw->inkscape), "set_selection", G_CALLBACK (sp_widget_set_selection), spw);
- }
-
- if (((GtkWidgetClass *) parent_class)->show)
- (* ((GtkWidgetClass *) parent_class)->show) (widget);
+ SPWidget *spw = SP_WIDGET(widget);
+
+ if (spw->inkscape) {
+ // Connect signals
+ g_signal_connect(spw->inkscape, "modify_selection", G_CALLBACK(SPWidgetImpl::modifySelectionCB), spw);
+ g_signal_connect(spw->inkscape, "change_selection", G_CALLBACK(SPWidgetImpl::changeSelectionCB), spw);
+ g_signal_connect(spw->inkscape, "set_selection", G_CALLBACK(SPWidgetImpl::setSelectionCB), spw);
+ }
+
+ if (reinterpret_cast<GtkWidgetClass *>(parentClass)->show) {
+ (*reinterpret_cast<GtkWidgetClass *>(parentClass)->show)(widget);
+ }
}
-static void
-sp_widget_hide (GtkWidget *widget)
+void SPWidgetImpl::hide(GtkWidget *widget)
{
- SPWidget *spw;
-
- spw = SP_WIDGET (widget);
+ SPWidget *spw = SP_WIDGET (widget);
- if (spw->inkscape) {
- /* Disconnect signals */
- sp_signal_disconnect_by_data (spw->inkscape, spw);
- }
+ if (spw->inkscape) {
+ // Disconnect signals
+ sp_signal_disconnect_by_data(spw->inkscape, spw);
+ }
- if (((GtkWidgetClass *) parent_class)->hide)
- (* ((GtkWidgetClass *) parent_class)->hide) (widget);
+ if (reinterpret_cast<GtkWidgetClass *>(parentClass)->hide) {
+ (*reinterpret_cast<GtkWidgetClass *>(parentClass)->hide)(widget);
+ }
}
#if GTK_CHECK_VERSION(3,0,0)
-static gboolean sp_widget_draw(GtkWidget *widget, cairo_t *cr)
+gboolean SPWidgetImpl::draw(GtkWidget *widget, cairo_t *cr)
#else
-static gboolean sp_widget_expose(GtkWidget *widget, GdkEventExpose *event)
+gboolean SPWidgetImpl::expose(GtkWidget *widget, GdkEventExpose *event)
#endif
{
- GtkBin *bin = GTK_BIN (widget);
- GtkWidget *child = gtk_bin_get_child (bin);
+ GtkBin *bin = GTK_BIN(widget);
+ GtkWidget *child = gtk_bin_get_child(bin);
- if (child) {
+ if (child) {
#if GTK_CHECK_VERSION(3,0,0)
- gtk_container_propagate_draw(GTK_CONTAINER(widget), child, cr);
+ gtk_container_propagate_draw(GTK_CONTAINER(widget), child, cr);
#else
- gtk_container_propagate_expose(GTK_CONTAINER(widget), child, event);
+ gtk_container_propagate_expose(GTK_CONTAINER(widget), child, event);
#endif
- }
+ }
- return FALSE;
+ return FALSE;
}
-static void
-sp_widget_size_request (GtkWidget *widget, GtkRequisition *requisition)
+void SPWidgetImpl::sizeRequest(GtkWidget *widget, GtkRequisition *requisition)
{
- GtkBin *bin = GTK_BIN (widget);
- GtkWidget *child = gtk_bin_get_child (bin);
+ GtkBin *bin = GTK_BIN(widget);
+ GtkWidget *child = gtk_bin_get_child(bin);
- if (child)
- gtk_widget_size_request (child, requisition);
+ if (child) {
+ gtk_widget_size_request(child, requisition);
+ }
}
#if GTK_CHECK_VERSION(3,0,0)
-static void sp_widget_get_preferred_width(GtkWidget *widget, gint *minimal_width, gint *natural_width)
+static void SPWidgetImpl::getPreferredWidth(GtkWidget *widget, gint *minimal_width, gint *natural_width)
{
- GtkRequisition requisition;
- sp_widget_size_request(widget, &requisition);
- *minimal_width = *natural_width = requisition.width;
+ GtkRequisition requisition;
+ sizeRequest(widget, &requisition);
+ *minimal_width = requisition.width;
+ *natural_width = requisition.width;
}
-static void sp_widget_get_preferred_height(GtkWidget *widget, gint *minimal_height, gint *natural_height)
+static void SPWidgetImpl::getPreferredHeight(GtkWidget *widget, gint *minimal_height, gint *natural_height)
{
- GtkRequisition requisition;
- sp_widget_size_request(widget, &requisition);
- *minimal_height = *natural_height = requisition.height;
+ GtkRequisition requisition;
+ sizeRequest(widget, &requisition);
+ *minimal_height = requisition.height;
+ *natural_height = requisition.height;
}
#endif
-static void
-sp_widget_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
+void SPWidgetImpl::sizeAllocate(GtkWidget *widget, GtkAllocation *allocation)
{
- GtkBin *bin = GTK_BIN (widget);
- GtkWidget *child = gtk_bin_get_child (bin);
+ gtk_widget_set_allocation(widget, allocation);
- gtk_widget_set_allocation (widget, allocation);
+ GtkBin *bin = GTK_BIN(widget);
+ GtkWidget *child = gtk_bin_get_child(bin);
- if (child)
- gtk_widget_size_allocate (child, allocation);
+ if (child) {
+ gtk_widget_size_allocate(child, allocation);
+ }
}
-/* Methods */
-
-GtkWidget *
-sp_widget_new_global (Inkscape::Application *inkscape)
+GtkWidget *SPWidgetImpl::constructGlobal(SPWidget *spw, Inkscape::Application *inkscape)
{
- SPWidget *spw;
+ g_return_val_if_fail(!spw->inkscape, NULL);
- spw = (SPWidget*)g_object_new (SP_TYPE_WIDGET, NULL);
+ spw->inkscape = inkscape;
+ if (gtk_widget_get_visible(GTK_WIDGET(spw))) {
+ g_signal_connect(inkscape, "modify_selection", G_CALLBACK(SPWidgetImpl::modifySelectionCB), spw);
+ g_signal_connect(inkscape, "change_selection", G_CALLBACK(SPWidgetImpl::changeSelectionCB), spw);
+ g_signal_connect(inkscape, "set_selection", G_CALLBACK(SPWidgetImpl::setSelectionCB), spw);
+ }
- if (!sp_widget_construct_global (spw, inkscape)) {
- g_object_unref (spw);
- return NULL;
- }
+ g_signal_emit(spw, signals[CONSTRUCT], 0);
- return (GtkWidget *) spw;
+ return (GtkWidget *) spw;
}
-GtkWidget *
-sp_widget_construct_global (SPWidget *spw, Inkscape::Application *inkscape)
+void SPWidgetImpl::modifySelectionCB(Application *inkscape, Selection *selection, guint flags, SPWidget *spw)
{
- g_return_val_if_fail (!spw->inkscape, NULL);
+ spw->_impl->modifySelection(inkscape, selection, flags);
+}
- spw->inkscape = inkscape;
- if (gtk_widget_get_visible (GTK_WIDGET(spw))) {
- g_signal_connect (G_OBJECT (inkscape), "modify_selection", G_CALLBACK (sp_widget_modify_selection), spw);
- g_signal_connect (G_OBJECT (inkscape), "change_selection", G_CALLBACK (sp_widget_change_selection), spw);
- g_signal_connect (G_OBJECT (inkscape), "set_selection", G_CALLBACK (sp_widget_set_selection), spw);
- }
+void SPWidgetImpl::changeSelectionCB(Application *inkscape, Selection *selection, SPWidget *spw)
+{
+ spw->_impl->changeSelection(inkscape, selection);
+}
- g_signal_emit (G_OBJECT (spw), signals[CONSTRUCT], 0);
+void SPWidgetImpl::setSelectionCB(Application *inkscape, Selection *selection, SPWidget *spw)
+{
+ spw->_impl->setSelection(inkscape, selection);
+}
- return (GtkWidget *) spw;
+void SPWidgetImpl::modifySelection(Application * /*inkscape*/, Selection *selection, guint flags)
+{
+ g_signal_emit(&_target, signals[MODIFY_SELECTION], 0, selection, flags);
}
-static void
-sp_widget_modify_selection (Inkscape::Application */*inkscape*/, Inkscape::Selection *selection, guint flags, SPWidget *spw)
+void SPWidgetImpl::changeSelection(Application * /*inkscape*/, Selection *selection)
{
- g_signal_emit (G_OBJECT (spw), signals[MODIFY_SELECTION], 0, selection, flags);
+ g_signal_emit(&_target, signals[CHANGE_SELECTION], 0, selection);
}
-static void
-sp_widget_change_selection (Inkscape::Application */*inkscape*/, Inkscape::Selection *selection, SPWidget *spw)
+void SPWidgetImpl::setSelection(Application * /*inkscape*/, Selection *selection)
{
- g_signal_emit (G_OBJECT (spw), signals[CHANGE_SELECTION], 0, selection);
+ // Emit "set_selection" signal
+ g_signal_emit(&_target, signals[SET_SELECTION], 0, selection);
+ // Inkscape will force "change_selection" anyways
}
-static void
-sp_widget_set_selection (Inkscape::Application */*inkscape*/, Inkscape::Selection *selection, SPWidget *spw)
+} // namespace Inkscape
+
+// Methods
+
+GtkWidget *sp_widget_new_global(Inkscape::Application *inkscape)
{
- /* Emit "set_selection" signal */
- g_signal_emit (G_OBJECT (spw), signals[SET_SELECTION], 0, selection);
- /* Inkscape will force "change_selection" anyways */
+ SPWidget *spw = reinterpret_cast<SPWidget*>(g_object_new(SP_TYPE_WIDGET, NULL));
+
+ if (!SPWidgetImpl::constructGlobal(spw, inkscape)) {
+ g_object_unref(spw);
+ spw = 0;
+ }
+
+ return reinterpret_cast<GtkWidget *>(spw);
}
/*