summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 7c186a9)
raw | patch | inline | side by side (parent: 7c186a9)
author | Jon A. Cruz <jon@joncruz.org> | |
Sun, 28 Mar 2010 00:42:22 +0000 (17:42 -0700) | ||
committer | Jon A. Cruz <jon@joncruz.org> | |
Sun, 28 Mar 2010 00:42:22 +0000 (17:42 -0700) |
src/widgets/fill-style.cpp | patch | blob | history | |
src/widgets/paint-selector.cpp | patch | blob | history | |
src/widgets/paint-selector.h | patch | blob | history |
index 6ea9f30b5fb8e503855bda7e4a50b9b05830c646..552668a885379fabe89b0ad393b61ec509b7a625 100644 (file)
* Lauris Kaplinski <lauris@kaplinski.com>
* Frank Felfe <innerspace@iname.com>
* bulia byak <buliabyak@users.sf.net>
+ * Jon A. Cruz <jon@joncruz.org>
*
* 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
*/
#endif
#include <glibmm/i18n.h>
+#include <gtkmm/box.h>
#include <gtk/gtkvbox.h>
#include "desktop-handles.h"
/* 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)
{
*/
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();
+ }
}
/**
*
* @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);
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) {
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";
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)
}
}
- g_object_set_data(G_OBJECT(spw), "update", GINT_TO_POINTER(TRUE));
+ update = true;
switch (psel->mode) {
case SPPaintSelector::MODE_COLOR_RGB:
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;
}
__FILE__, __LINE__, psel->mode );
break;
}
- g_object_set_data(G_OBJECT(spw), "update", GINT_TO_POINTER(FALSE));
+ update = false;
}
/**
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);
break;
}
- g_object_set_data(G_OBJECT(spw), "update", GINT_TO_POINTER(FALSE));
+ update = false;
}
index 288764177275cf986dc74a734f2233c69aea1a04..d3092669a92ea20d3e37255978b632af27be1492 100644 (file)
}
-GtkWidget *
-sp_paint_selector_new(bool is_fill)
+SPPaintSelector *sp_paint_selector_new(FillOrStroke kind)
{
SPPaintSelector *psel = static_cast<SPPaintSelector*>(gtk_type_new(SP_TYPE_PAINT_SELECTOR));
// 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
index a3c4cb973817fd7b3da9b503a4e1c895787f832d..84209d1da4fae3f467f9655f1fb061fee24641e1 100644 (file)
*/
#include <glib.h>
+
+#include "fill-or-stroke.h"
#include "sp-gradient-spread.h"
#include "sp-gradient-units.h"
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 );
GtkType sp_paint_selector_get_type (void);
-GtkWidget *sp_paint_selector_new (bool is_fill);
+SPPaintSelector *sp_paint_selector_new(FillOrStroke kind);