Code

Edit single-stop "swatch"/"solid" gradients in-place in the F&S dialog.
authorJon A. Cruz <jon@joncruz.org>
Sun, 21 Mar 2010 18:18:51 +0000 (11:18 -0700)
committerJon A. Cruz <jon@joncruz.org>
Sun, 21 Mar 2010 18:18:51 +0000 (11:18 -0700)
src/widgets/CMakeLists.txt
src/widgets/Makefile_insert
src/widgets/paint-selector.cpp
src/widgets/swatch-selector.cpp [new file with mode: 0644]
src/widgets/swatch-selector.h [new file with mode: 0644]

index 45f013f16da40d8ec2e6d9d4bbb9b1138e54c1d0..9af3259262dcf33b47e565a1b13bb5cdeaa90c98 100644 (file)
@@ -29,8 +29,9 @@ spw-utilities.cpp
 sp-xmlview-attr-list.cpp
 sp-xmlview-content.cpp
 sp-xmlview-tree.cpp
+swatch-selector.cpp
 toolbox.cpp
 )
 ADD_LIBRARY(widgets STATIC ${widgets_SRC})
 TARGET_LINK_LIBRARIES(widgets
-2geom ${INKSCAPE_LIBS})
\ No newline at end of file
+2geom ${INKSCAPE_LIBS})
index 08b2433eafd5fbe2e89e4d6a1110cbfe1337b535..5d327d8a3d1f96e23d6729355c9700e3e2483107 100644 (file)
@@ -67,6 +67,8 @@ ink_common_sources += \
        widgets/sp-xmlview-tree.h       \
        widgets/stroke-style.cpp        \
        widgets/stroke-style.h          \
+       widgets/swatch-selector.cpp     \
+       widgets/swatch-selector.h       \
        widgets/toolbox.cpp             \
        widgets/toolbox.h               \
        widgets/widget-sizes.h
index 5898563a543b9048e3ca4bfd8416ca93f68e3d57..892793543fe59952bbdefedc9ef3307d559ea12f 100644 (file)
@@ -52,6 +52,7 @@
 #include "io/sys.h"
 #include "helper/stock-items.h"
 #include "ui/icon-names.h"
+#include "widgets/swatch-selector.h"
 
 #include "paint-selector.h"
 
@@ -59,6 +60,9 @@
 #include "svg/svg-icc-color.h"
 #endif // SP_PS_VERBOSE
 
+
+using Inkscape::Widgets::SwatchSelector;
+
 enum {
     MODE_CHANGED,
     GRABBED,
@@ -121,6 +125,7 @@ static bool isPaintModeGradient( SPPaintSelectorMode mode )
 
 static SPGradientSelector *getGradientFromData(SPPaintSelector *psel)
 {
+    // TODO g_message("FIXME FIXME");
     gchar const* key = (psel->mode == SP_PAINT_SELECTOR_MODE_SWATCH) ? "swatch-selector" : "gradient-selector";
     SPGradientSelector *grad = reinterpret_cast<SPGradientSelector*>(gtk_object_get_data(GTK_OBJECT(psel->selector), key));
     return grad;
@@ -448,9 +453,10 @@ void sp_paint_selector_set_swatch(SPPaintSelector *psel, SPGradient *vector )
 #endif
     sp_paint_selector_set_mode(psel, SP_PAINT_SELECTOR_MODE_SWATCH);
 
-    SPGradientSelector *gsel = static_cast<SPGradientSelector*>(gtk_object_get_data(GTK_OBJECT(psel->selector), "swatch-selector"));
-
-    gsel->setVector((vector) ? SP_OBJECT_DOCUMENT(vector) : 0, vector);
+    SwatchSelector *swatchsel = static_cast<SwatchSelector*>(gtk_object_get_data(GTK_OBJECT(psel->selector), "swatch-selector"));
+    if (swatchsel) {
+        swatchsel->setVector( (vector) ? SP_OBJECT_DOCUMENT(vector) : 0, vector );
+    }
 }
 
 void
@@ -1102,25 +1108,26 @@ static void sp_paint_selector_set_mode_swatch(SPPaintSelector *psel, SPPaintSele
 
     gtk_widget_set_sensitive(psel->style, TRUE);
 
-    GtkWidget *tbl = 0;
+    SwatchSelector *swatchsel = 0;
 
     if (psel->mode == SP_PAINT_SELECTOR_MODE_SWATCH){
         /* Already have pattern menu */
-        tbl = static_cast<GtkWidget*>(gtk_object_get_data(GTK_OBJECT(psel->selector), "swatch-selector"));
+        swatchsel = static_cast<SwatchSelector*>(g_object_get_data(G_OBJECT(psel->selector), "swatch-selector"));
     } else {
         sp_paint_selector_clear_frame(psel);
         /* Create new gradient selector */
-        GtkWidget *gsel = sp_gradient_selector_new();
-        SP_GRADIENT_SELECTOR(gsel)->setMode(SPGradientSelector::MODE_SWATCH);
-        gtk_widget_show(gsel);
-        gtk_signal_connect(GTK_OBJECT(gsel), "grabbed", GTK_SIGNAL_FUNC(sp_paint_selector_gradient_grabbed), psel);
-        gtk_signal_connect(GTK_OBJECT(gsel), "dragged", GTK_SIGNAL_FUNC(sp_paint_selector_gradient_dragged), psel);
-        gtk_signal_connect(GTK_OBJECT(gsel), "released", GTK_SIGNAL_FUNC(sp_paint_selector_gradient_released), psel);
-        gtk_signal_connect(GTK_OBJECT(gsel), "changed", GTK_SIGNAL_FUNC(sp_paint_selector_gradient_changed), psel);
+        SwatchSelector *swatchsel = new SwatchSelector();
+        swatchsel->show();
+
+        swatchsel->connectGrabbedHandler( G_CALLBACK(sp_paint_selector_gradient_grabbed), psel );
+        swatchsel->connectDraggedHandler( G_CALLBACK(sp_paint_selector_gradient_dragged), psel );
+        swatchsel->connectReleasedHandler( G_CALLBACK(sp_paint_selector_gradient_released), psel );
+        swatchsel->connectchangedHandler( G_CALLBACK(sp_paint_selector_gradient_changed), psel );
+
         // Pack everything to frame
-        gtk_container_add(GTK_CONTAINER(psel->frame), gsel);
-        psel->selector = gsel;
-        gtk_object_set_data(GTK_OBJECT(psel->selector), "swatch-selector", gsel);
+        gtk_container_add(GTK_CONTAINER(psel->frame), GTK_WIDGET(swatchsel->gobj()));
+        psel->selector = GTK_WIDGET(swatchsel->gobj());
+        gtk_object_set_data(GTK_OBJECT(psel->selector), "swatch-selector", swatchsel);
 
         gtk_frame_set_label(GTK_FRAME(psel->frame), _("Swatch fill"));
     }
diff --git a/src/widgets/swatch-selector.cpp b/src/widgets/swatch-selector.cpp
new file mode 100644 (file)
index 0000000..a7bd5ea
--- /dev/null
@@ -0,0 +1,198 @@
+
+
+#include <glibmm/i18n.h>
+
+#include "swatch-selector.h"
+
+#include "document.h"
+#include "gradient-chemistry.h"
+#include "gradient-selector.h"
+#include "sp-color-notebook.h"
+#include "sp-stop.h"
+#include "svg/css-ostringstream.h"
+#include "svg/svg-color.h"
+#include "verbs.h"
+#include "xml/node.h"
+
+namespace Inkscape
+{
+namespace Widgets
+{
+
+SwatchSelector::SwatchSelector() :
+    Gtk::VBox(),
+    _gsel(0),
+    _csel(0)
+{
+    GtkWidget *gsel = sp_gradient_selector_new();
+    _gsel = SP_GRADIENT_SELECTOR(gsel);
+    g_object_set_data( G_OBJECT(gobj()), "base", this );
+    _gsel->setMode(SPGradientSelector::MODE_SWATCH);
+
+    gtk_widget_show(gsel);
+
+    pack_start(*Gtk::manage(Glib::wrap(gsel)));
+
+
+    GtkWidget *csel = sp_color_selector_new( SP_TYPE_COLOR_NOTEBOOK );
+    _csel = SP_COLOR_SELECTOR(csel);
+    Gtk::Widget *wrappedCSel = Glib::wrap(csel);
+    wrappedCSel->show();
+    //gtk_widget_show(csel);
+
+
+    GObject *obj = G_OBJECT(csel);
+
+    g_signal_connect(obj, "grabbed", G_CALLBACK(_grabbedCb), this);
+    g_signal_connect(obj, "dragged", G_CALLBACK(_draggedCb), this);
+    g_signal_connect(obj, "released", G_CALLBACK(_releasedCb), this);
+    g_signal_connect(obj, "changed", G_CALLBACK(_changedCb), this);
+
+    pack_start(*Gtk::manage(wrappedCSel));
+}
+
+SwatchSelector::~SwatchSelector()
+{
+    _csel = 0; // dtor should be handled by Gtk::manage()
+    _gsel = 0;
+}
+
+void SwatchSelector::_grabbedCb(SPColorSelector * /*csel*/, void * /*data*/)
+{
+}
+
+void SwatchSelector::_draggedCb(SPColorSelector * /*csel*/, void *data)
+{
+    if (data) {
+        //SwatchSelector *swsel = reinterpret_cast<SwatchSelector*>(data);
+
+        // TODO might have to block cycles
+
+        // Copied from gradient-vector.cpp, but does not appear to cause visible changes:
+        /*
+        if (swsel->_gsel) {
+            SPGradient *gradient = swsel->_gsel->getVector();
+            SPGradient *ngr = sp_gradient_ensure_vector_normalized(gradient);
+            if (ngr != gradient) {
+                // Our master gradient has changed
+                // TODO replace with proper - sp_gradient_vector_widget_load_gradient(GTK_WIDGET(swsel->_gsel), ngr);
+            }
+
+            sp_gradient_ensure_vector(ngr);
+
+
+            SPStop* stop = ngr->getFirstStop();
+            if (stop) {
+                swsel->_csel->base->getColorAlpha(stop->specified_color, &stop->opacity);
+                stop->currentColor = false;
+                // TODO push refresh
+            }
+        }
+        */
+    }
+}
+
+void SwatchSelector::_releasedCb(SPColorSelector * /*csel*/, void * /*data*/)
+{
+}
+
+void SwatchSelector::_changedCb(SPColorSelector */*csel*/, void *data)
+{
+    if (data) {
+        SwatchSelector *swsel = reinterpret_cast<SwatchSelector*>(data);
+
+        // TODO might have to block cycles
+
+        if (swsel->_gsel) {
+            SPGradient *gradient = swsel->_gsel->getVector();
+            SPGradient *ngr = sp_gradient_ensure_vector_normalized(gradient);
+            if (ngr != gradient) {
+                /* Our master gradient has changed */
+                // TODO replace with proper - sp_gradient_vector_widget_load_gradient(GTK_WIDGET(swsel->_gsel), ngr);
+            }
+
+            sp_gradient_ensure_vector(ngr);
+
+
+            SPStop* stop = ngr->getFirstStop();
+            if (stop) {
+                SPColor color;
+                float alpha = 0;
+                guint32 rgb = 0;
+
+                swsel->_csel->base->getColorAlpha( color, &alpha );
+                rgb = color.toRGBA32( 0x00 );
+
+                // TODO replace with generic shared code that also handles icc-color
+                Inkscape::CSSOStringStream os;
+                gchar c[64];
+                sp_svg_write_color(c, sizeof(c), rgb);
+                os << "stop-color:" << c << ";stop-opacity:" << static_cast<gdouble>(alpha) <<";";
+                SP_OBJECT_REPR(stop)->setAttribute("style", os.str().c_str());
+
+                sp_document_done(SP_OBJECT_DOCUMENT(ngr), SP_VERB_CONTEXT_GRADIENT,
+                                 _("Change swatch color"));
+            }
+        }
+    }
+}
+
+void SwatchSelector::connectGrabbedHandler( GCallback handler, void *data )
+{
+    GObject* obj = G_OBJECT(_gsel);
+    g_signal_connect( obj, "grabbed", handler, data );
+}
+
+void SwatchSelector::connectDraggedHandler( GCallback handler, void *data )
+{
+    GObject* obj = G_OBJECT(_gsel);
+    g_signal_connect( obj, "dragged", handler, data );
+}
+
+void SwatchSelector::connectReleasedHandler( GCallback handler, void *data )
+{
+    GObject* obj = G_OBJECT(_gsel);
+    g_signal_connect( obj, "released", handler, data );
+}
+
+void SwatchSelector::connectchangedHandler( GCallback handler, void *data )
+{
+    GObject* obj = G_OBJECT(_gsel);
+    g_signal_connect( obj, "changed", handler, data );
+}
+
+void SwatchSelector::setVector(SPDocument */*doc*/, SPGradient *vector)
+{
+    //GtkVBox * box = gobj();
+
+    _gsel->setVector((vector) ? SP_OBJECT_DOCUMENT(vector) : 0, vector);
+
+    if (vector) {
+        SPStop* stop = vector->getFirstStop();
+
+        guint32 const colorVal = sp_stop_get_rgba32(stop);
+        _csel->base->setAlpha(SP_RGBA32_A_F(colorVal));
+        SPColor color( SP_RGBA32_R_F(colorVal), SP_RGBA32_G_F(colorVal), SP_RGBA32_B_F(colorVal) );
+        // set its color, from the stored array
+        _csel->base->setColor( color );
+    }
+
+/*
+*/
+}
+
+} // namespace Widgets
+} // namespace Inkscape
+
+
+
+/*
+  Local Variables:
+  mode:c++
+  c-file-style:"stroustrup"
+  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+  indent-tabs-mode:nil
+  fill-column:99
+  End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
diff --git a/src/widgets/swatch-selector.h b/src/widgets/swatch-selector.h
new file mode 100644 (file)
index 0000000..cf1c24d
--- /dev/null
@@ -0,0 +1,57 @@
+#ifndef SEEN_SP_SWATCH_SELECTOR_H
+#define SEEN_SP_SWATCH_SELECTOR_H
+
+
+
+#include <gtkmm/box.h>
+
+class SPDocument;
+class SPGradient;
+class SPColorSelector;
+class SPGradientSelector;
+
+namespace Inkscape
+{
+namespace Widgets
+{
+
+class SwatchSelector : public Gtk::VBox
+{
+public:
+    SwatchSelector();
+    virtual ~SwatchSelector();
+
+    void connectGrabbedHandler( GCallback handler, void *data );
+    void connectDraggedHandler( GCallback handler, void *data );
+    void connectReleasedHandler( GCallback handler, void *data );
+    void connectchangedHandler( GCallback handler, void *data );
+
+    void setVector(SPDocument *doc, SPGradient *vector);
+
+private:
+    static void _grabbedCb(SPColorSelector *csel, void *data);
+    static void _draggedCb(SPColorSelector *csel, void *data);
+    static void _releasedCb(SPColorSelector *csel, void *data);
+    static void _changedCb(SPColorSelector *csel, void *data);
+
+    SPGradientSelector *_gsel;
+    SPColorSelector *_csel;
+};
+
+
+} // namespace Widgets
+} // namespace Inkscape
+
+#endif // SEEN_SP_SWATCH_SELECTOR_H
+
+/*
+  Local Variables:
+  mode:c++
+  c-file-style:"stroustrup"
+  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+  indent-tabs-mode:nil
+  fill-column:99
+  End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+