From fc8a6ae43a85b35c01fe620ccc0db7bacb8ba6ab Mon Sep 17 00:00:00 2001 From: "Jon A. Cruz" Date: Sat, 27 Mar 2010 17:42:22 -0700 Subject: [PATCH] Phase 3 - Convert to C++ class, but still using C-style callbacks and signals. --- src/widgets/fill-style.cpp | 270 ++++++++++++++++++--------------- src/widgets/paint-selector.cpp | 15 +- src/widgets/paint-selector.h | 6 +- 3 files changed, 161 insertions(+), 130 deletions(-) diff --git a/src/widgets/fill-style.cpp b/src/widgets/fill-style.cpp index 6ea9f30b5..552668a88 100644 --- a/src/widgets/fill-style.cpp +++ b/src/widgets/fill-style.cpp @@ -5,9 +5,11 @@ * Lauris Kaplinski * Frank Felfe * bulia byak + * Jon A. Cruz * * Copyright (C) 1999-2005 authors * Copyright (C) 2001-2002 Ximian, Inc. + * Copyright (C) 2010 Jon A. Cruz * * Released under GNU GPL, read the file 'COPYING' for more information */ @@ -19,6 +21,7 @@ #endif #include +#include #include #include "desktop-handles.h" @@ -45,17 +48,37 @@ /* Fill */ -static void fillnstroke_fillrule_changed(SPPaintSelector *psel, SPPaintSelector::FillRule mode, GtkWidget *spw); -static void fillnstroke_selection_modified(Inkscape::Application *inkscape, Inkscape::Selection *selection, guint flags, GtkWidget *spw); -static void fillnstroke_selection_changed(Inkscape::Application *inkscape, Inkscape::Selection *selection, GtkWidget *spw); -static void fillnstroke_subselection_changed(Inkscape::Application *inkscape, SPDesktop *desktop, GtkWidget *spw); -static void fillnstroke_paint_mode_changed(SPPaintSelector *psel, SPPaintSelector::Mode mode, GtkWidget *spw); -static void fillnstroke_paint_dragged(SPPaintSelector *psel, GtkWidget *spw); -static void fillnstroke_paint_changed(SPPaintSelector *psel, GtkWidget *spw); +class FillNStroke : public Gtk::VBox +{ +public: + FillNStroke( FillOrStroke kind ); + ~FillNStroke(); + + void setFillrule( SPPaintSelector::FillRule mode ); + +private: + static void paintModeChangeCB(SPPaintSelector *psel, SPPaintSelector::Mode mode, FillNStroke *self); + static void paintChangedCB(SPPaintSelector *psel, FillNStroke *self); + static void paintDraggedCB(SPPaintSelector *psel, FillNStroke *self); + + static void fillruleChangedCB( SPPaintSelector *psel, SPPaintSelector::FillRule mode, FillNStroke *self ); + + static void selectionModifiedCB(Inkscape::Application *inkscape, Inkscape::Selection *selection, guint flags, FillNStroke *self); + static void selectionChangedCB(Inkscape::Application *inkscape, void * data, FillNStroke *self); + + void dragFromPaint(); + void updateFromPaint(); + + void performUpdate(); + + FillOrStroke kind; + SPPaintSelector *psel; + bool update; + bool local; +}; -static void fillnstroke_performUpdate(GtkWidget *spw); GtkWidget *sp_fill_style_widget_new(void) { @@ -67,87 +90,92 @@ GtkWidget *sp_fill_style_widget_new(void) */ GtkWidget *Inkscape::Widgets::createStyleWidget( FillOrStroke kind ) { - Inkscape::Application *appInstance = INKSCAPE; - GtkWidget *spw = gtk_vbox_new(FALSE, 0); - - // with or without fillrule selector - GtkWidget *psel = sp_paint_selector_new(kind == FILL); - gtk_widget_show(psel); - gtk_container_add(GTK_CONTAINER(spw), psel); - g_object_set_data(G_OBJECT(spw), "paint-selector", psel); - g_object_set_data(G_OBJECT(spw), "kind", GINT_TO_POINTER(kind)); - - g_signal_connect( G_OBJECT(appInstance), "modify_selection", - G_CALLBACK(fillnstroke_selection_modified), - spw ); + FillNStroke *filler = Gtk::manage(new FillNStroke(kind)); - g_signal_connect( G_OBJECT(appInstance), "change_selection", - G_CALLBACK(fillnstroke_selection_changed), - spw ); - - g_signal_connect( G_OBJECT(appInstance), "change_subselection", - G_CALLBACK(fillnstroke_subselection_changed), - spw ); + return GTK_WIDGET(filler->gobj()); +} +FillNStroke::FillNStroke( FillOrStroke kind ) : + Gtk::VBox(), + kind(kind), + psel(0), + update(false), + local(false) +{ + // Add and connect up the paint selector widget: + psel = sp_paint_selector_new(kind); + gtk_widget_show(GTK_WIDGET(psel)); + gtk_container_add(GTK_CONTAINER(gobj()), GTK_WIDGET(psel)); g_signal_connect( G_OBJECT(psel), "mode_changed", - G_CALLBACK(fillnstroke_paint_mode_changed), - spw ); + G_CALLBACK(paintModeChangeCB), + this ); g_signal_connect( G_OBJECT(psel), "dragged", - G_CALLBACK(fillnstroke_paint_dragged), - spw ); + G_CALLBACK(paintDraggedCB), + this ); g_signal_connect( G_OBJECT(psel), "changed", - G_CALLBACK(fillnstroke_paint_changed), - spw ); - + G_CALLBACK(paintChangedCB), + this ); if (kind == FILL) { g_signal_connect( G_OBJECT(psel), "fillrule_changed", - G_CALLBACK(fillnstroke_fillrule_changed), - spw ); + G_CALLBACK(fillruleChangedCB), + this ); } - fillnstroke_performUpdate(spw); + // connect to the app instance to get selection notifications. + // TODO FIXME should really get connected to a Desktop instead. + Inkscape::Application *appInstance = INKSCAPE; + g_signal_connect( G_OBJECT(appInstance), "modify_selection", + G_CALLBACK(selectionModifiedCB), + this ); + + g_signal_connect( G_OBJECT(appInstance), "change_selection", + G_CALLBACK(selectionChangedCB), + this ); + + g_signal_connect( G_OBJECT(appInstance), "change_subselection", + G_CALLBACK(selectionChangedCB), + this ); - return spw; + + performUpdate(); +} + +FillNStroke::~FillNStroke() +{ + psel = 0; } /** * On signal modified, invokes an update of the fill or stroke style paint object. */ -void fillnstroke_selection_modified( Inkscape::Application * /*inkscape*/, - Inkscape::Selection * /*selection*/, - guint flags, - GtkWidget *spw ) +void FillNStroke::selectionModifiedCB( Inkscape::Application * /*inkscape*/, + Inkscape::Selection */*selection*/, + guint flags, + FillNStroke *self ) { - if (flags & ( SP_OBJECT_MODIFIED_FLAG | - SP_OBJECT_PARENT_MODIFIED_FLAG | - SP_OBJECT_STYLE_MODIFIED_FLAG) ) { + if (self && + (flags & ( SP_OBJECT_MODIFIED_FLAG | + SP_OBJECT_PARENT_MODIFIED_FLAG | + SP_OBJECT_STYLE_MODIFIED_FLAG) ) ) { #ifdef SP_FS_VERBOSE - g_message("fillnstroke_selection_modified()"); + g_message("selectionModifiedCB(%p)", self); #endif - fillnstroke_performUpdate(spw); + self->performUpdate(); } } /** - * On signal selection changed, invokes an update of the fill or stroke style paint object. - */ -void fillnstroke_selection_changed( Inkscape::Application * /*inkscape*/, - Inkscape::Selection */*selection*/, - GtkWidget *spw ) -{ - fillnstroke_performUpdate(spw); -} - -/** - * On signal change subselection, invoke an update of the fill or stroke style widget. + * On signal selection changed or subselection changed, invokes an update of the fill or stroke style paint object. */ -void fillnstroke_subselection_changed( Inkscape::Application * /*inkscape*/, - SPDesktop * /*desktop*/, - GtkWidget *spw ) +void FillNStroke::selectionChangedCB( Inkscape::Application * /*inkscape*/, + void * /*data*/, + FillNStroke *self ) { - fillnstroke_performUpdate(spw); + if (self) { + self->performUpdate(); + } } /** @@ -156,24 +184,21 @@ void fillnstroke_subselection_changed( Inkscape::Application * /*inkscape*/, * * @param sel Selection to use, or NULL. */ -void fillnstroke_performUpdate( GtkWidget *spw ) +void FillNStroke::performUpdate() { - if ( g_object_get_data(G_OBJECT(spw), "update") ) { + if ( update ) { return; } - FillOrStroke kind = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(spw), "kind")) ? FILL : STROKE; - if (kind == FILL) { - if ( g_object_get_data(G_OBJECT(spw), "local") ) { - g_object_set_data(G_OBJECT(spw), "local", GINT_TO_POINTER(FALSE)); // local change; do nothing, but reset the flag + // TODO check. This probably should happen for stroke as well as fill. + if ( local ) { + local = false; // local change; do nothing, but reset the flag return; } } - g_object_set_data(G_OBJECT(spw), "update", GINT_TO_POINTER(TRUE)); - - SPPaintSelector *psel = SP_PAINT_SELECTOR(g_object_get_data(G_OBJECT(spw), "paint-selector")); + update = true; // create temporary style SPStyle *query = sp_style_new(SP_ACTIVE_DOCUMENT); @@ -196,7 +221,7 @@ void fillnstroke_performUpdate( GtkWidget *spw ) case QUERY_STYLE_MULTIPLE_AVERAGED: // TODO: treat this slightly differently, e.g. display "averaged" somewhere in paint selector case QUERY_STYLE_MULTIPLE_SAME: { - SPPaintSelector::Mode pselmode = SPPaintSelector::getModeForStyle(*query, kind == FILL); + SPPaintSelector::Mode pselmode = SPPaintSelector::getModeForStyle(*query, kind); psel->setMode(pselmode); if (kind == FILL) { @@ -244,51 +269,49 @@ void fillnstroke_performUpdate( GtkWidget *spw ) sp_style_unref(query); - g_object_set_data(G_OBJECT(spw), "update", GINT_TO_POINTER(FALSE)); + update = false; } /** * When the mode is changed, invoke a regular changed handler. */ -void fillnstroke_paint_mode_changed( SPPaintSelector *psel, +void FillNStroke::paintModeChangeCB( SPPaintSelector * /*psel*/, SPPaintSelector::Mode /*mode*/, - GtkWidget *spw ) + FillNStroke *self ) { - if (g_object_get_data(G_OBJECT(spw), "update")) { - return; - } - #ifdef SP_FS_VERBOSE - g_message("fillnstroke_paint_mode_changed(psel:%p, mode, spw:%p)", psel, spw); + g_message("paintModeChangeCB(psel, mode, self:%p)", self); #endif - - /* TODO: Does this work? - * Not really, here we have to get old color back from object - * Instead of relying on paint widget having meaningful colors set - */ - fillnstroke_paint_changed(psel, spw); + if (self && !self->update) { + self->updateFromPaint(); + } } -void fillnstroke_fillrule_changed( SPPaintSelector * /*psel*/, - SPPaintSelector::FillRule mode, - GtkWidget *spw ) +void FillNStroke::fillruleChangedCB( SPPaintSelector * /*psel*/, + SPPaintSelector::FillRule mode, + FillNStroke *self ) { - if (g_object_get_data(G_OBJECT(spw), "update")) { - return; + if (self) { + self->setFillrule(mode); } +} - SPDesktop *desktop = SP_ACTIVE_DESKTOP; +void FillNStroke::setFillrule( SPPaintSelector::FillRule mode ) +{ + if (!update) { + SPDesktop *desktop = SP_ACTIVE_DESKTOP; - SPCSSAttr *css = sp_repr_css_attr_new(); - sp_repr_css_set_property(css, "fill-rule", mode == SPPaintSelector::FILLRULE_EVENODD? "evenodd":"nonzero"); + SPCSSAttr *css = sp_repr_css_attr_new(); + sp_repr_css_set_property(css, "fill-rule", (mode == SPPaintSelector::FILLRULE_EVENODD) ? "evenodd":"nonzero"); - sp_desktop_set_style(desktop, css); + sp_desktop_set_style(desktop, css); - sp_repr_css_attr_unref(css); - css = 0; + sp_repr_css_attr_unref(css); + css = 0; - sp_document_done(SP_ACTIVE_DOCUMENT, SP_VERB_DIALOG_FILL_STROKE, - _("Change fill rule")); + sp_document_done(SP_ACTIVE_DOCUMENT, SP_VERB_DIALOG_FILL_STROKE, + _("Change fill rule")); + } } static gchar const *undo_F_label_1 = "fill:flatcolor:1"; @@ -300,26 +323,31 @@ static gchar const *undo_S_label_2 = "stroke:flatcolor:2"; static gchar const *undo_F_label = undo_F_label_1; static gchar const *undo_S_label = undo_S_label_1; + +void FillNStroke::paintDraggedCB(SPPaintSelector * /*psel*/, FillNStroke *self) +{ +#ifdef SP_FS_VERBOSE + g_message("paintDraggedCB(psel, spw:%p)", self); +#endif + if (self && !self->update) { + self->dragFromPaint(); + } +} + /** * This is called repeatedly while you are dragging a color slider, only for flat color * modes. Previously it set the color in style but did not update the repr for efficiency, however * this was flakey and didn't buy us almost anything. So now it does the same as _changed, except * lumps all its changes for undo. */ -void fillnstroke_paint_dragged(SPPaintSelector *psel, GtkWidget *spw) +void FillNStroke::dragFromPaint() { - if (!INKSCAPE) { + if (!INKSCAPE || update) { return; } - if (g_object_get_data(G_OBJECT(spw), "update")) { - return; - } - - FillOrStroke kind = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(spw), "kind")) ? FILL : STROKE; - if (kind == FILL) { - if (g_object_get_data(G_OBJECT(spw), "local")) { + if (local) { // previous local flag not cleared yet; // this means dragged events come too fast, so we better skip this one to speed up display // (it's safe to do this in any case) @@ -327,7 +355,7 @@ void fillnstroke_paint_dragged(SPPaintSelector *psel, GtkWidget *spw) } } - g_object_set_data(G_OBJECT(spw), "update", GINT_TO_POINTER(TRUE)); + update = true; switch (psel->mode) { case SPPaintSelector::MODE_COLOR_RGB: @@ -337,7 +365,7 @@ void fillnstroke_paint_dragged(SPPaintSelector *psel, GtkWidget *spw) sp_document_maybe_done(sp_desktop_document(SP_ACTIVE_DESKTOP), (kind == FILL) ? undo_F_label : undo_S_label, SP_VERB_DIALOG_FILL_STROKE, (kind == FILL) ? _("Set fill color") : _("Set stroke color")); if (kind == FILL) { - g_object_set_data(G_OBJECT(spw), "local", GINT_TO_POINTER(TRUE)); // local change, do not update from selection + local = true; // local change, do not update from selection } break; } @@ -347,7 +375,7 @@ void fillnstroke_paint_dragged(SPPaintSelector *psel, GtkWidget *spw) __FILE__, __LINE__, psel->mode ); break; } - g_object_set_data(G_OBJECT(spw), "update", GINT_TO_POINTER(FALSE)); + update = false; } /** @@ -357,22 +385,24 @@ This is called (at least) when: 3 you changed a gradient selector parameter (e.g. spread) Must update repr. */ -void fillnstroke_paint_changed( SPPaintSelector *psel, GtkWidget *spw ) +void FillNStroke::paintChangedCB( SPPaintSelector * /*psel*/, FillNStroke *self ) { #ifdef SP_FS_VERBOSE - g_message("fillnstroke_paint_changed(psel:%p, spw:%p)", psel, spw); + g_message("paintChangedCB(psel, spw:%p)", self); #endif - if (g_object_get_data(G_OBJECT(spw), "update")) { - return; + if (self && !self->update) { + self->updateFromPaint(); } - g_object_set_data(G_OBJECT(spw), "update", GINT_TO_POINTER(TRUE)); - - FillOrStroke kind = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(spw), "kind")) ? FILL : STROKE; +} +void FillNStroke::updateFromPaint() +{ SPDesktop *desktop = SP_ACTIVE_DESKTOP; if (!desktop) { return; } + update = true; + SPDocument *document = sp_desktop_document(desktop); Inkscape::Selection *selection = sp_desktop_selection(desktop); @@ -602,7 +632,7 @@ void fillnstroke_paint_changed( SPPaintSelector *psel, GtkWidget *spw ) break; } - g_object_set_data(G_OBJECT(spw), "update", GINT_TO_POINTER(FALSE)); + update = false; } diff --git a/src/widgets/paint-selector.cpp b/src/widgets/paint-selector.cpp index 288764177..d3092669a 100644 --- a/src/widgets/paint-selector.cpp +++ b/src/widgets/paint-selector.cpp @@ -352,8 +352,7 @@ sp_paint_selector_show_fillrule(SPPaintSelector *psel, bool is_fill) } -GtkWidget * -sp_paint_selector_new(bool is_fill) +SPPaintSelector *sp_paint_selector_new(FillOrStroke kind) { SPPaintSelector *psel = static_cast(gtk_type_new(SP_TYPE_PAINT_SELECTOR)); @@ -362,9 +361,9 @@ sp_paint_selector_new(bool is_fill) // This silliness is here because I don't know how to pass a parameter to the // GtkObject "constructor" (sp_paint_selector_init). Remove it when paint_selector // becomes a normal class. - sp_paint_selector_show_fillrule(psel, is_fill); + sp_paint_selector_show_fillrule(psel, kind == FILL); - return GTK_WIDGET(psel); + return psel; } void SPPaintSelector::setMode(Mode mode) @@ -1137,18 +1136,18 @@ void SPPaintSelector::setFlatColor( SPDesktop *desktop, gchar const *color_prope sp_repr_css_attr_unref(css); } -SPPaintSelector::Mode SPPaintSelector::getModeForStyle(SPStyle const & style, bool isfill) +SPPaintSelector::Mode SPPaintSelector::getModeForStyle(SPStyle const & style, FillOrStroke kind) { Mode mode = MODE_UNSET; - SPIPaint const & target = isfill ? style.fill : style.stroke; + SPIPaint const & target = (kind == FILL) ? style.fill : style.stroke; if ( !target.set ) { mode = MODE_UNSET; } else if ( target.isPaintserver() ) { - SPPaintServer const *server = isfill ? style.getFillPaintServer() : style.getStrokePaintServer(); + SPPaintServer const *server = (kind == FILL) ? style.getFillPaintServer() : style.getStrokePaintServer(); #ifdef SP_PS_VERBOSE - g_message("SPPaintSelector::getModeForStyle(%p, %d)", &style, isfill); + g_message("SPPaintSelector::getModeForStyle(%p, %d)", &style, kind); g_message("==== server:%p %s grad:%s swatch:%s", server, server->getId(), (SP_IS_GRADIENT(server)?"Y":"n"), (SP_IS_GRADIENT(server) && SP_GRADIENT(server)->getVector()->isSwatch()?"Y":"n")); #endif // SP_PS_VERBOSE diff --git a/src/widgets/paint-selector.h b/src/widgets/paint-selector.h index a3c4cb973..84209d1da 100644 --- a/src/widgets/paint-selector.h +++ b/src/widgets/paint-selector.h @@ -14,6 +14,8 @@ */ #include + +#include "fill-or-stroke.h" #include "sp-gradient-spread.h" #include "sp-gradient-units.h" @@ -75,7 +77,7 @@ struct SPPaintSelector { SPColor color; float alpha; - static Mode getModeForStyle(SPStyle const & style, bool isfill); + static Mode getModeForStyle(SPStyle const & style, FillOrStroke kind); void setMode( Mode mode ); void setFillrule( FillRule fillrule ); @@ -114,7 +116,7 @@ struct SPPaintSelectorClass { GtkType sp_paint_selector_get_type (void); -GtkWidget *sp_paint_selector_new (bool is_fill); +SPPaintSelector *sp_paint_selector_new(FillOrStroke kind); -- 2.30.2