From: Jon A. Cruz Date: Mon, 29 Mar 2010 05:00:58 +0000 (-0700) Subject: Purge use of SP_ACTIVE_* and encapsulate by moving 'active' desktop tracking out... X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=c82bca234e1bfd13063a8752a42f650e99d3738b;p=inkscape.git Purge use of SP_ACTIVE_* and encapsulate by moving 'active' desktop tracking out of lower-level panels. Fixes bug #270623. --- diff --git a/src/ui/dialog/fill-and-stroke.cpp b/src/ui/dialog/fill-and-stroke.cpp index fe63c6e24..fae2e873c 100644 --- a/src/ui/dialog/fill-and-stroke.cpp +++ b/src/ui/dialog/fill-and-stroke.cpp @@ -6,8 +6,10 @@ /* Authors: * Bryce W. Harrington * Gustav Broberg + * Jon A. Cruz * * Copyright (C) 2004--2007 Authors + * Copyright (C) 2010 Jon A. Cruz * * Released under GNU GPL. Read the file 'COPYING' for more information. */ @@ -29,6 +31,8 @@ #include "widgets/stroke-style.h" #include "xml/repr.h" +#include "ui/view/view-widget.h" + namespace Inkscape { namespace UI { namespace Dialog { @@ -38,7 +42,12 @@ FillAndStroke::FillAndStroke() _page_fill(1, 1, true, true), _page_stroke_paint(1, 1, true, true), _page_stroke_style(1, 1, true, true), - _composite_settings(SP_VERB_DIALOG_FILL_STROKE, "fillstroke", SimpleFilterModifier::BLUR) + _composite_settings(SP_VERB_DIALOG_FILL_STROKE, "fillstroke", SimpleFilterModifier::BLUR), + hierID(0), + trackActive(false), + targetDesktop(0), + fillWdgt(0), + strokeWdgt(0) { Gtk::Box *contents = _getContents(); contents->set_spacing(0); @@ -58,25 +67,75 @@ FillAndStroke::FillAndStroke() show_all_children(); _composite_settings.setSubject(&_subject); + + // Use C/gobject callbacks to avoid gtkmm rewrap-during-destruct issues: + hierID = g_signal_connect( G_OBJECT(gobj()), "hierarchy-changed", G_CALLBACK(hierarchyChangeCB), this ); + + g_signal_connect( G_OBJECT(INKSCAPE), "activate_desktop", G_CALLBACK( activateDesktopCB ), this ); } FillAndStroke::~FillAndStroke() { _composite_settings.setSubject(NULL); + if (hierID) { + g_signal_handler_disconnect(G_OBJECT(gobj()), hierID); + hierID = 0; + } +} + +gboolean FillAndStroke::activateDesktopCB(Inkscape::Application */*inkscape*/, SPDesktop *desktop, FillAndStroke *self ) +{ + if (self && self->trackActive) { + self->setTargetDesktop(desktop); + } + return FALSE; +} + +bool FillAndStroke::hierarchyChangeCB(GtkWidget *widget, GtkWidget* /*prev*/, FillAndStroke *self) +{ + if (self) { + GtkWidget *ww = gtk_widget_get_ancestor(widget, SP_TYPE_VIEW_WIDGET); + bool newFlag = (ww == 0); + if (newFlag != self->trackActive) { + self->trackActive = newFlag; + if (self->trackActive) { + self->setTargetDesktop(SP_ACTIVE_DESKTOP); + } else { + self->setTargetDesktop(self->getDesktop()); + } + } + } + return false; +} + +void FillAndStroke::setDesktop(SPDesktop *desktop) +{ + Panel::setDesktop(desktop); + setTargetDesktop(desktop); +} + +void FillAndStroke::setTargetDesktop(SPDesktop *desktop) +{ + if (fillWdgt) { + sp_fill_style_widget_set_desktop(fillWdgt, desktop); + } + if (strokeWdgt) { + sp_stroke_style_widget_set_desktop(strokeWdgt, desktop); + } } void FillAndStroke::_layoutPageFill() { - Gtk::Widget *fs = manage(Glib::wrap(sp_fill_style_widget_new())); - _page_fill.table().attach(*fs, 0, 1, 0, 1); + fillWdgt = manage(sp_fill_style_widget_new()); + _page_fill.table().attach(*fillWdgt, 0, 1, 0, 1); } void FillAndStroke::_layoutPageStrokePaint() { - Gtk::Widget *ssp = manage(Glib::wrap(sp_stroke_style_paint_widget_new())); - _page_stroke_paint.table().attach(*ssp, 0, 1, 0, 1); + strokeWdgt = manage(sp_stroke_style_paint_widget_new()); + _page_stroke_paint.table().attach(*strokeWdgt, 0, 1, 0, 1); } void diff --git a/src/ui/dialog/fill-and-stroke.h b/src/ui/dialog/fill-and-stroke.h index 7dc892fea..f0d68ced8 100644 --- a/src/ui/dialog/fill-and-stroke.h +++ b/src/ui/dialog/fill-and-stroke.h @@ -4,8 +4,10 @@ /* Authors: * Bryce W. Harrington * Gustav Broberg + * Jon A. Cruz * * Copyright (C) 2004--2007 Authors + * Copyright (C) 2010 Jon A. Cruz * * Released under GNU GPL. Read the file 'COPYING' for more information. */ @@ -37,6 +39,12 @@ public: static FillAndStroke &getInstance() { return *new FillAndStroke(); } + + virtual void setDesktop(SPDesktop *desktop); + + // temporary work-around until panel dialog itself tracks 'focus' properly. + virtual void setTargetDesktop(SPDesktop *desktop); + void selectionChanged(Inkscape::Application *inkscape, Inkscape::Selection *selection); @@ -54,7 +62,7 @@ protected: StyleSubject::Selection _subject; ObjectCompositeSettings _composite_settings; - Gtk::HBox &_createPageTabLabel(const Glib::ustring &label, + Gtk::HBox &_createPageTabLabel(const Glib::ustring &label, const char *label_image); void _layoutPageFill(); @@ -64,6 +72,15 @@ protected: private: FillAndStroke(FillAndStroke const &d); FillAndStroke& operator=(FillAndStroke const &d); + + static gboolean activateDesktopCB(Inkscape::Application *inkscape, SPDesktop *desktop, FillAndStroke *self ); + static bool hierarchyChangeCB(GtkWidget *widget, GtkWidget* prev, FillAndStroke *self); + + gulong hierID; + bool trackActive; + SPDesktop *targetDesktop; + Gtk::Widget *fillWdgt; + Gtk::Widget *strokeWdgt; }; } // namespace Dialog diff --git a/src/widgets/fill-n-stroke-factory.h b/src/widgets/fill-n-stroke-factory.h index 14cbd6a58..74339a07f 100644 --- a/src/widgets/fill-n-stroke-factory.h +++ b/src/widgets/fill-n-stroke-factory.h @@ -10,12 +10,14 @@ #include "fill-or-stroke.h" -typedef struct _GtkWidget GtkWidget; +namespace Gtk { +class Widget; +} namespace Inkscape { namespace Widgets { -GtkWidget *createStyleWidget( FillOrStroke kind ); +Gtk::Widget *createStyleWidget( FillOrStroke kind ); } // namespace Widgets } // namespace Inkscape diff --git a/src/widgets/fill-style.cpp b/src/widgets/fill-style.cpp index 552668a88..63def4c87 100644 --- a/src/widgets/fill-style.cpp +++ b/src/widgets/fill-style.cpp @@ -24,6 +24,8 @@ #include #include +#include "desktop.h" +#include "selection.h" #include "desktop-handles.h" #include "desktop-style.h" #include "display/sp-canvas.h" @@ -49,6 +51,13 @@ /* Fill */ +Gtk::Widget *sp_fill_style_widget_new(void) +{ + return Inkscape::Widgets::createStyleWidget( FILL ); +} + + +namespace Inkscape { class FillNStroke : public Gtk::VBox { @@ -58,6 +67,8 @@ public: void setFillrule( SPPaintSelector::FillRule mode ); + void setDesktop(SPDesktop *desktop); + private: static void paintModeChangeCB(SPPaintSelector *psel, SPPaintSelector::Mode mode, FillNStroke *self); static void paintChangedCB(SPPaintSelector *psel, FillNStroke *self); @@ -65,8 +76,7 @@ private: 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 selectionModifiedCB(guint flags); void dragFromPaint(); void updateFromPaint(); @@ -74,33 +84,47 @@ private: void performUpdate(); FillOrStroke kind; + SPDesktop *desktop; SPPaintSelector *psel; bool update; bool local; + sigc::connection selectChangedConn; + sigc::connection subselChangedConn; + sigc::connection selectModifiedConn; }; +} // namespace Inkscape -GtkWidget *sp_fill_style_widget_new(void) +void sp_fill_style_widget_set_desktop(Gtk::Widget *widget, SPDesktop *desktop) { - return Inkscape::Widgets::createStyleWidget( FILL ); + Inkscape::FillNStroke *fs = dynamic_cast(widget); + if (fs) { + fs->setDesktop(desktop); + } } +namespace Inkscape { + /** * Create the fill or stroke style widget, and hook up all the signals. */ -GtkWidget *Inkscape::Widgets::createStyleWidget( FillOrStroke kind ) +Gtk::Widget *Inkscape::Widgets::createStyleWidget( FillOrStroke kind ) { - FillNStroke *filler = Gtk::manage(new FillNStroke(kind)); + FillNStroke *filler = new FillNStroke(kind); - return GTK_WIDGET(filler->gobj()); + return filler; } FillNStroke::FillNStroke( FillOrStroke kind ) : Gtk::VBox(), kind(kind), + desktop(0), psel(0), update(false), - local(false) + local(false), + selectChangedConn(), + subselChangedConn(), + selectModifiedConn() { // Add and connect up the paint selector widget: psel = sp_paint_selector_new(kind); @@ -123,58 +147,50 @@ FillNStroke::FillNStroke( FillOrStroke kind ) : this ); } - // 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 ); - - performUpdate(); } FillNStroke::~FillNStroke() { psel = 0; + selectModifiedConn.disconnect(); + subselChangedConn.disconnect(); + selectChangedConn.disconnect(); } /** * On signal modified, invokes an update of the fill or stroke style paint object. */ -void FillNStroke::selectionModifiedCB( Inkscape::Application * /*inkscape*/, - Inkscape::Selection */*selection*/, - guint flags, - FillNStroke *self ) +void FillNStroke::selectionModifiedCB( guint flags ) { - if (self && - (flags & ( SP_OBJECT_MODIFIED_FLAG | + if (flags & ( SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_PARENT_MODIFIED_FLAG | - SP_OBJECT_STYLE_MODIFIED_FLAG) ) ) { + SP_OBJECT_STYLE_MODIFIED_FLAG) ) { #ifdef SP_FS_VERBOSE - g_message("selectionModifiedCB(%p)", self); + g_message("selectionModifiedCB(%d) on %p", flags, this); #endif - self->performUpdate(); + performUpdate(); } } -/** - * On signal selection changed or subselection changed, invokes an update of the fill or stroke style paint object. - */ -void FillNStroke::selectionChangedCB( Inkscape::Application * /*inkscape*/, - void * /*data*/, - FillNStroke *self ) +void FillNStroke::setDesktop(SPDesktop *desktop) { - if (self) { - self->performUpdate(); + if (this->desktop != desktop) { + if (this->desktop) { + selectModifiedConn.disconnect(); + subselChangedConn.disconnect(); + selectChangedConn.disconnect(); + } + this->desktop = desktop; + if (desktop && desktop->selection) { + selectChangedConn = desktop->selection->connectChanged(sigc::hide(sigc::mem_fun(*this, &FillNStroke::performUpdate))); + subselChangedConn = desktop->connectToolSubselectionChanged(sigc::hide(sigc::mem_fun(*this, &FillNStroke::performUpdate))); + + // Must check flags, so can't call performUpdate() directly. + selectModifiedConn = desktop->selection->connectModified(sigc::hide<0>(sigc::mem_fun(*this, &FillNStroke::selectionModifiedCB))); + + } + performUpdate(); } } @@ -186,7 +202,7 @@ void FillNStroke::selectionChangedCB( Inkscape::Application * /*inkscape*/, */ void FillNStroke::performUpdate() { - if ( update ) { + if ( update || !desktop ) { return; } @@ -201,10 +217,10 @@ void FillNStroke::performUpdate() update = true; // create temporary style - SPStyle *query = sp_style_new(SP_ACTIVE_DOCUMENT); + SPStyle *query = sp_style_new(desktop->doc()); // query style from desktop into it. This returns a result flag and fills query with the style of subselection, if any, or selection - int result = sp_desktop_query_style(SP_ACTIVE_DESKTOP, query, (kind == FILL) ? QUERY_STYLE_PROPERTY_FILL : QUERY_STYLE_PROPERTY_STROKE); + int result = sp_desktop_query_style(desktop, query, (kind == FILL) ? QUERY_STYLE_PROPERTY_FILL : QUERY_STYLE_PROPERTY_STROKE); SPIPaint &targPaint = (kind == FILL) ? query->fill : query->stroke; SPIScale24 &targOpacity = (kind == FILL) ? query->fill_opacity : query->stroke_opacity; @@ -298,9 +314,7 @@ void FillNStroke::fillruleChangedCB( SPPaintSelector * /*psel*/, void FillNStroke::setFillrule( SPPaintSelector::FillRule mode ) { - if (!update) { - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - + if (!update && desktop) { SPCSSAttr *css = sp_repr_css_attr_new(); sp_repr_css_set_property(css, "fill-rule", (mode == SPPaintSelector::FILLRULE_EVENODD) ? "evenodd":"nonzero"); @@ -309,7 +323,7 @@ void FillNStroke::setFillrule( SPPaintSelector::FillRule mode ) sp_repr_css_attr_unref(css); css = 0; - sp_document_done(SP_ACTIVE_DOCUMENT, SP_VERB_DIALOG_FILL_STROKE, + sp_document_done(desktop->doc(), SP_VERB_DIALOG_FILL_STROKE, _("Change fill rule")); } } @@ -342,7 +356,7 @@ void FillNStroke::paintDraggedCB(SPPaintSelector * /*psel*/, FillNStroke *self) */ void FillNStroke::dragFromPaint() { - if (!INKSCAPE || update) { + if (!desktop || update) { return; } @@ -361,8 +375,8 @@ void FillNStroke::dragFromPaint() case SPPaintSelector::MODE_COLOR_RGB: case SPPaintSelector::MODE_COLOR_CMYK: { - psel->setFlatColor( SP_ACTIVE_DESKTOP, (kind == FILL) ? "fill" : "stroke", (kind == FILL) ? "fill-opacity" : "stroke-opacity" ); - sp_document_maybe_done(sp_desktop_document(SP_ACTIVE_DESKTOP), (kind == FILL) ? undo_F_label : undo_S_label, SP_VERB_DIALOG_FILL_STROKE, + psel->setFlatColor( desktop, (kind == FILL) ? "fill" : "stroke", (kind == FILL) ? "fill-opacity" : "stroke-opacity" ); + sp_document_maybe_done(desktop->doc(), (kind == FILL) ? undo_F_label : undo_S_label, SP_VERB_DIALOG_FILL_STROKE, (kind == FILL) ? _("Set fill color") : _("Set stroke color")); if (kind == FILL) { local = true; // local change, do not update from selection @@ -397,7 +411,6 @@ void FillNStroke::paintChangedCB( SPPaintSelector * /*psel*/, FillNStroke *self void FillNStroke::updateFromPaint() { - SPDesktop *desktop = SP_ACTIVE_DESKTOP; if (!desktop) { return; } @@ -484,7 +497,7 @@ void FillNStroke::updateFromPaint() if (!vector) { /* No vector in paint selector should mean that we just changed mode */ - SPStyle *query = sp_style_new(SP_ACTIVE_DOCUMENT); + SPStyle *query = sp_style_new(desktop->doc()); int result = objects_query_fillstroke(const_cast(items), query, kind == FILL); SPIPaint &targPaint = (kind == FILL) ? query->fill : query->stroke; guint32 common_rgb = 0; @@ -635,6 +648,7 @@ void FillNStroke::updateFromPaint() update = false; } +} // namespace Inkscape /* Local Variables: diff --git a/src/widgets/fill-style.h b/src/widgets/fill-style.h index ea97bd486..ef19d7788 100644 --- a/src/widgets/fill-style.h +++ b/src/widgets/fill-style.h @@ -14,9 +14,15 @@ #ifndef SEEN_DIALOGS_SP_FILL_STYLE_H #define SEEN_DIALOGS_SP_FILL_STYLE_H -typedef struct _GtkWidget GtkWidget; +namespace Gtk { +class Widget; +} -GtkWidget *sp_fill_style_widget_new(void); +class SPDesktop; + +Gtk::Widget *sp_fill_style_widget_new(void); + +void sp_fill_style_widget_set_desktop(Gtk::Widget *widget, SPDesktop *desktop); #endif // SEEN_DIALOGS_SP_FILL_STYLE_H diff --git a/src/widgets/stroke-style.cpp b/src/widgets/stroke-style.cpp index d6a38f978..f020b0c3a 100644 --- a/src/widgets/stroke-style.cpp +++ b/src/widgets/stroke-style.cpp @@ -56,6 +56,7 @@ #include "xml/repr.h" #include "stroke-style.h" +#include "fill-style.h" // to get sp_fill_style_widget_set_desktop #include "fill-n-stroke-factory.h" /** Marker selection option menus */ @@ -72,11 +73,17 @@ static void ink_markers_menu_update(Gtk::Container* spw, SPMarkerLoc const static Inkscape::UI::Cache::SvgPreview svg_preview_cache; -GtkWidget *sp_stroke_style_paint_widget_new(void) +Gtk::Widget *sp_stroke_style_paint_widget_new(void) { return Inkscape::Widgets::createStyleWidget( STROKE ); } +void sp_stroke_style_widget_set_desktop(Gtk::Widget *widget, SPDesktop *desktop) +{ + sp_fill_style_widget_set_desktop(widget, desktop); +} + + /* Line */ diff --git a/src/widgets/stroke-style.h b/src/widgets/stroke-style.h index 9ed7e2a92..72dc5449a 100644 --- a/src/widgets/stroke-style.h +++ b/src/widgets/stroke-style.h @@ -14,13 +14,16 @@ #ifndef SEEN_DIALOGS_STROKE_STYLE_H #define SEEN_DIALOGS_STROKE_STYLE_H -#include +namespace Gtk { +class Widget; +class Container; +} -typedef struct _GtkWidget GtkWidget; - -GtkWidget *sp_stroke_style_paint_widget_new(void); +Gtk::Widget *sp_stroke_style_paint_widget_new(void); Gtk::Container *sp_stroke_style_line_widget_new(void); +void sp_stroke_style_widget_set_desktop(Gtk::Widget *widget, SPDesktop *desktop); + #endif // SEEN_DIALOGS_STROKE_STYLE_H /*