Code

Reworked internals of color and drag-n-drop.
authorjoncruz <joncruz@users.sourceforge.net>
Sun, 8 Mar 2009 09:30:53 +0000 (09:30 +0000)
committerjoncruz <joncruz@users.sourceforge.net>
Sun, 8 Mar 2009 09:30:53 +0000 (09:30 +0000)
src/gradient-drag.cpp
src/gradient-drag.h
src/interface.cpp
src/ui/dialog/swatches.cpp
src/widgets/eek-color-def.cpp
src/widgets/eek-color-def.h

index 6d8815938af690f41a91d1aecc85c80cd9ae5f16..4758d27bf3472b2641f98348e874af865ff163cf 100644 (file)
@@ -358,7 +358,7 @@ GrDrag::addStopNearPoint (SPItem *item, Geom::Point mouse_p, double tolerance)
 
 
 bool
-GrDrag::dropColor(SPItem */*item*/, gchar *c, Geom::Point p)
+GrDrag::dropColor(SPItem */*item*/, gchar const *c, Geom::Point p)
 {
     // first, see if we can drop onto one of the existing draggers
     for (GList *i = draggers; i != NULL; i = i->next) { // for all draggables of dragger
index 974bba4deb1411dcd092753ec8710d510b4a7b7d..a53acffe6fc0997bf703d41ca20f9bcf6ff0bf5f 100644 (file)
@@ -124,7 +124,7 @@ public: // FIXME: make more of this private!
     void selectByCoords(std::vector<Geom::Point> coords);
     void selectRect(Geom::Rect const &r);
 
-    bool dropColor(SPItem *item, gchar *c, Geom::Point p);
+    bool dropColor(SPItem *item, gchar const *c, Geom::Point p);
 
     SPStop *addStopNearPoint (SPItem *item, Geom::Point mouse_p, double tolerance);
 
index e542a19445f95386c740e0602718ade821e8498a..8379cd0e23c9e48aa9ea1fe7091f87a902e5355c 100644 (file)
@@ -61,6 +61,7 @@
 #include "style.h"
 #include "event-context.h"
 #include "gradient-drag.h"
+#include "widgets/eek-color-def.h"
 
 // Include Mac OS X menu synchronization on native OSX build
 #ifdef GDK_WINDOWING_QUARTZ
@@ -77,8 +78,7 @@ typedef enum {
     IMAGE_DATA,
     APP_X_INKY_COLOR,
     APP_X_COLOR,
-    APP_X_NOCOLOR,
-    APP_X_XCOLOR
+    APP_OSWB_COLOR,
 } ui_drop_target_info;
 
 static GtkTargetEntry ui_drop_target_entries [] = {
@@ -90,7 +90,7 @@ static GtkTargetEntry ui_drop_target_entries [] = {
 #if ENABLE_MAGIC_COLORS
     {(gchar *)"application/x-inkscape-color", 0, APP_X_INKY_COLOR},
 #endif // ENABLE_MAGIC_COLORS
-    {(gchar *)"application/x-oswb-nocolor",   0, APP_X_NOCOLOR     },
+    {(gchar *)"application/x-oswb-color",     0, APP_OSWB_COLOR  },
     {(gchar *)"application/x-color",          0, APP_X_COLOR     }
 };
 
@@ -1165,10 +1165,10 @@ sp_ui_drag_data_received(GtkWidget *widget,
             Geom::Point const button_doc(desktop->dt2doc(button_dt));
 
             if ( data->length == 8 ) {
-                gchar c[64] = {0};
+                gchar colorspec[64] = {0};
                 // Careful about endian issues.
                 guint16* dataVals = (guint16*)data->data;
-                sp_svg_write_color( c, 64,
+                sp_svg_write_color( colorspec, sizeof(colorspec),
                                     SP_RGBA32_U_COMPOSE(
                                         0x0ff & (dataVals[0] >> 8),
                                         0x0ff & (dataVals[1] >> 8),
@@ -1181,7 +1181,7 @@ sp_ui_drag_data_received(GtkWidget *widget,
 
                 bool consumed = false;
                 if (desktop->event_context && desktop->event_context->get_drag()) {
-                    consumed = desktop->event_context->get_drag()->dropColor(item, c, button_dt);
+                    consumed = desktop->event_context->get_drag()->dropColor(item, colorspec, button_dt);
                     if (consumed) {
                         sp_document_done( doc , SP_VERB_NONE, _("Drop color on gradient"));
                         desktop->event_context->get_drag()->updateDraggers();
@@ -1224,7 +1224,7 @@ sp_ui_drag_data_received(GtkWidget *widget,
                     }
 
                     SPCSSAttr *css = sp_repr_css_attr_new();
-                    sp_repr_css_set_property( css, fillnotstroke ? "fill":"stroke", c );
+                    sp_repr_css_set_property( css, fillnotstroke ? "fill":"stroke", colorspec );
 
                     sp_desktop_apply_css_recursive( item, css, true );
                     item->updateRepr();
@@ -1236,66 +1236,85 @@ sp_ui_drag_data_received(GtkWidget *widget,
         }
         break;
 
-        case APP_X_NOCOLOR:
-        case APP_X_XCOLOR:
+        case APP_OSWB_COLOR:
         {
-            gchar* c = g_strdup("none"); // temp
-            int destX = 0;
-            int destY = 0;
-            gtk_widget_translate_coordinates( widget, &(desktop->canvas->widget), x, y, &destX, &destY );
-            Geom::Point where( sp_canvas_window_to_world( desktop->canvas, Geom::Point( destX, destY ) ) );
-            Geom::Point const button_dt(desktop->w2d(where));
-            Geom::Point const button_doc(desktop->dt2doc(button_dt));
+            bool worked = false;
+            Glib::ustring colorspec;
+            if ( data->format == 8 ) {
+                eek::ColorDef color;
+                worked = color.fromMIMEData("application/x-oswb-color",
+                                            reinterpret_cast<char*>(data->data),
+                                            data->length,
+                                            data->format);
+                if ( worked ) {
+                    if ( color.getType() == eek::ColorDef::CLEAR ) {
+                        colorspec = ""; // TODO check if this is sufficient
+                    } else if ( color.getType() == eek::ColorDef::NONE ) {
+                        colorspec = "none";
+                    } else {                        
+                        gchar* tmp = g_strdup_printf("#%02x%02x%02x", color.getR(), color.getG(), color.getB());
+                        colorspec = tmp;
+                        g_free(tmp);
+                    }
+                }
+            }
+            if ( worked ) {
+                int destX = 0;
+                int destY = 0;
+                gtk_widget_translate_coordinates( widget, &(desktop->canvas->widget), x, y, &destX, &destY );
+                Geom::Point where( sp_canvas_window_to_world( desktop->canvas, Geom::Point( destX, destY ) ) );
+                Geom::Point const button_dt(desktop->w2d(where));
+                Geom::Point const button_doc(desktop->dt2doc(button_dt));
 
-            SPItem *item = desktop->item_at_point( where, true );
+                SPItem *item = desktop->item_at_point( where, true );
 
-            bool consumed = false;
-            if (desktop->event_context && desktop->event_context->get_drag()) {
-                consumed = desktop->event_context->get_drag()->dropColor(item, c, button_dt);
-                if (consumed) {
-                    sp_document_done( doc , SP_VERB_NONE, _("Drop color on gradient"));
-                    desktop->event_context->get_drag()->updateDraggers();
+                bool consumed = false;
+                if (desktop->event_context && desktop->event_context->get_drag()) {
+                    consumed = desktop->event_context->get_drag()->dropColor(item, colorspec.c_str(), button_dt);
+                    if (consumed) {
+                        sp_document_done( doc , SP_VERB_NONE, _("Drop color on gradient"));
+                        desktop->event_context->get_drag()->updateDraggers();
+                    }
                 }
-            }
 
-            if (!consumed && item) {
-                bool fillnotstroke = (drag_context->action != GDK_ACTION_MOVE);
-                if (fillnotstroke &&
-                    (SP_IS_SHAPE(item) || SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item))) {
-                    Path *livarot_path = Path_for_item(item, true, true);
-                    livarot_path->ConvertWithBackData(0.04);
-
-                    boost::optional<Path::cut_position> position = get_nearest_position_on_Path(livarot_path, button_doc);
-                    if (position) {
-                        Geom::Point nearest = get_point_on_Path(livarot_path, position->piece, position->t);
-                        Geom::Point delta = nearest - button_doc;
-                        Inkscape::Preferences *prefs = Inkscape::Preferences::get();
-                        delta = desktop->d2w(delta);
-                        double stroke_tolerance =
-                            ( !SP_OBJECT_STYLE(item)->stroke.isNone() ?
-                              desktop->current_zoom() *
-                              SP_OBJECT_STYLE (item)->stroke_width.computed *
-                              to_2geom(sp_item_i2d_affine(item)).descrim() * 0.5
-                              : 0.0)
-                            + prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100);
-
-                        if (Geom::L2 (delta) < stroke_tolerance) {
-                            fillnotstroke = false;
+                if (!consumed && item) {
+                    bool fillnotstroke = (drag_context->action != GDK_ACTION_MOVE);
+                    if (fillnotstroke &&
+                        (SP_IS_SHAPE(item) || SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item))) {
+                        Path *livarot_path = Path_for_item(item, true, true);
+                        livarot_path->ConvertWithBackData(0.04);
+
+                        boost::optional<Path::cut_position> position = get_nearest_position_on_Path(livarot_path, button_doc);
+                        if (position) {
+                            Geom::Point nearest = get_point_on_Path(livarot_path, position->piece, position->t);
+                            Geom::Point delta = nearest - button_doc;
+                            Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+                            delta = desktop->d2w(delta);
+                            double stroke_tolerance =
+                                ( !SP_OBJECT_STYLE(item)->stroke.isNone() ?
+                                  desktop->current_zoom() *
+                                  SP_OBJECT_STYLE (item)->stroke_width.computed *
+                                  to_2geom(sp_item_i2d_affine(item)).descrim() * 0.5
+                                  : 0.0)
+                                + prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100);
+
+                            if (Geom::L2 (delta) < stroke_tolerance) {
+                                fillnotstroke = false;
+                            }
                         }
+                        delete livarot_path;
                     }
-                    delete livarot_path;
-                }
 
-                SPCSSAttr *css = sp_repr_css_attr_new();
-                sp_repr_css_set_property( css, fillnotstroke ? "fill":"stroke", c );
+                    SPCSSAttr *css = sp_repr_css_attr_new();
+                    sp_repr_css_set_property( css, fillnotstroke ? "fill":"stroke", colorspec.c_str() );
 
-                sp_desktop_apply_css_recursive( item, css, true );
-                item->updateRepr();
+                    sp_desktop_apply_css_recursive( item, css, true );
+                    item->updateRepr();
 
-                sp_document_done( doc , SP_VERB_NONE,
-                                  _("Drop color"));
+                    sp_document_done( doc , SP_VERB_NONE,
+                                      _("Drop color"));
+                }
             }
-            g_free(c);
         }
         break;
 
index ecd54be39b9d215bbf3e49a2fb5d3b1efe1a6aa2..f1d6c6816e05dd9397a480a0cdcdb0433d24aa51 100644 (file)
@@ -100,24 +100,8 @@ public:
 static std::vector<JustForNow*> possible;
 
 
-
-typedef enum {
-    APP_X_INKY_COLOR_ID = 0,
-    APP_X_INKY_COLOR = 0,
-    APP_X_COLOR,
-    APP_X_NOCOLOR,
-    APP_X_XCOLOR,
-    TEXT_DATA
-} colorFlavorType;
-
-std::map<std::string, guint> mimeToInt;
-std::map<guint, std::string> intToMime;
-
-#if ENABLE_MAGIC_COLORS
-//    {"application/x-inkscape-color-id", GTK_TARGET_SAME_APP, APP_X_INKY_COLOR_ID},
-//    {"application/x-inkscape-color", 0, APP_X_INKY_COLOR},
-#endif // ENABLE_MAGIC_COLORS
-
+static std::vector<std::string> mimeStrings;
+static std::map<std::string, guint> mimeToInt;
 
 void ColorItem::_dragGetColorData( GtkWidget */*widget*/,
                                    GdkDragContext */*drag_context*/,
@@ -128,12 +112,10 @@ void ColorItem::_dragGetColorData( GtkWidget */*widget*/,
 {
     ColorItem* item = reinterpret_cast<ColorItem*>(user_data);
     std::string key;
-    if ( info == TEXT_DATA ) {
-        key = "text/plain";
-    } else if ( (info == APP_X_NOCOLOR) || (info == APP_X_XCOLOR) ) {
-        key = "application/x-oswb-nocolor";
+    if ( info < mimeStrings.size() ) {
+        key = mimeStrings[info];
     } else {
-        key = "application/x-color";
+        g_warning("ERROR: unknown value (%d)", info);
     }
 
     if ( !key.empty() ) {
@@ -297,20 +279,6 @@ static void dieDieDie( GtkObject *obj, gpointer user_data )
     g_message("die die die %p  %p", obj, user_data );
 }
 
-//TODO: warning: deprecated conversion from string constant to ‘gchar*’
-//
-//Turn out to be warnings that we should probably leave in place. The
-// pointers/types used need to be read-only. So until we correct the using
-// code, those warnings are actually desired. They say "Hey! Fix this". We
-// definitely don't want to hide/ignore them. --JonCruz
-static const GtkTargetEntry destColorTargets[] = {
-#if ENABLE_MAGIC_COLORS
-//    {"application/x-inkscape-color-id", GTK_TARGET_SAME_APP, APP_X_INKY_COLOR_ID},
-    {"application/x-inkscape-color", 0, APP_X_INKY_COLOR},
-#endif // ENABLE_MAGIC_COLORS
-    {"application/x-color", 0, APP_X_COLOR},
-};
-
 #include "color.h" // for SP_RGBA32_U_COMPOSE
 
 void ColorItem::_dropDataIn( GtkWidget */*widget*/,
@@ -321,58 +289,6 @@ void ColorItem::_dropDataIn( GtkWidget */*widget*/,
                              guint /*event_time*/,
                              gpointer user_data)
 {
-//     g_message("    droppy droppy   %d", info);
-     switch (info) {
-         case APP_X_INKY_COLOR:
-         {
-             if ( data->length >= 8 ) {
-                 // Careful about endian issues.
-                 guint16* dataVals = (guint16*)data->data;
-                 if ( user_data ) {
-                     ColorItem* item = reinterpret_cast<ColorItem*>(user_data);
-                     if ( item->def.isEditable() ) {
-                         // Shove on in the new value
-                         item->def.setRGB( 0x0ff & (dataVals[0] >> 8), 0x0ff & (dataVals[1] >> 8), 0x0ff & (dataVals[2] >> 8) );
-                     }
-                 }
-             }
-             break;
-         }
-         case APP_X_NOCOLOR:
-         case APP_X_XCOLOR:
-         {
-//              g_message("APP_X_NOCOLOR dropping through to x-color");
-         }
-         case APP_X_COLOR:
-         {
-             if ( data->length == 8 ) {
-                 // Careful about endian issues.
-                 guint16* dataVals = (guint16*)data->data;
-//                  {
-//                      gchar c[64] = {0};
-//                      sp_svg_write_color( c, 64,
-//                                          SP_RGBA32_U_COMPOSE(
-//                                              0x0ff & (dataVals[0] >> 8),
-//                                              0x0ff & (dataVals[1] >> 8),
-//                                              0x0ff & (dataVals[2] >> 8),
-//                                              0xff // can't have transparency in the color itself
-//                                              //0x0ff & (data->data[3] >> 8),
-//                                              ));
-//                  }
-                 if ( user_data ) {
-                     ColorItem* item = reinterpret_cast<ColorItem*>(user_data);
-                     if ( item->def.isEditable() ) {
-                         // Shove on in the new value
-                         item->def.setRGB( 0x0ff & (dataVals[0] >> 8), 0x0ff & (dataVals[1] >> 8), 0x0ff & (dataVals[2] >> 8) );
-                     }
-                 }
-             }
-             break;
-         }
-         default:
-             g_message("unknown drop type");
-     }
-
 }
 
 static bool bruteForce( SPDocument* document, Inkscape::XML::Node* node, Glib::ustring const& match, int r, int g, int b )
@@ -505,17 +421,6 @@ void ColorItem::_colorDefChanged(void* data)
 
 Gtk::Widget* ColorItem::getPreview(PreviewStyle style, ViewType view, ::PreviewSize size, guint ratio)
 {
-    if (mimeToInt.empty()) {
-        mimeToInt["application/x-inkscape-nocolor"] = APP_X_NOCOLOR;
-        intToMime[APP_X_NOCOLOR] = "application/x-inkscape-nocolor";
-
-        mimeToInt["application/x-color"] = APP_X_COLOR;
-        intToMime[APP_X_COLOR] = "application/x-color";
-
-        mimeToInt["text/plain"] = TEXT_DATA;
-        intToMime[TEXT_DATA] = "text/plain";
-    }
-
     Gtk::Widget* widget = 0;
     if ( style == PREVIEW_STYLE_BLURB) {
         Gtk::Label *lbl = new Gtk::Label(def.descr);
@@ -607,6 +512,11 @@ Gtk::Widget* ColorItem::getPreview(PreviewStyle style, ViewType view, ::PreviewS
             for ( std::vector<std::string>::iterator it = listing.begin(); it != listing.end(); ++it ) {
                 curr->target = g_strdup(it->c_str());
                 curr->flags = 0;
+                if ( mimeToInt.find(*it) == mimeToInt.end() ){
+                    // these next lines are order-dependent:
+                    mimeToInt[*it] = mimeStrings.size();
+                    mimeStrings.push_back(*it);
+                }
                 curr->info = mimeToInt[curr->target];
                 curr++;
             }
@@ -647,17 +557,17 @@ Gtk::Widget* ColorItem::getPreview(PreviewStyle style, ViewType view, ::PreviewS
 
         if ( def.isEditable() )
         {
-            gtk_drag_dest_set( GTK_WIDGET(newBlot->gobj()),
-                               GTK_DEST_DEFAULT_ALL,
-                               destColorTargets,
-                               G_N_ELEMENTS(destColorTargets),
-                               GdkDragAction(GDK_ACTION_COPY | GDK_ACTION_MOVE) );
+//             gtk_drag_dest_set( GTK_WIDGET(newBlot->gobj()),
+//                                GTK_DEST_DEFAULT_ALL,
+//                                destColorTargets,
+//                                G_N_ELEMENTS(destColorTargets),
+//                                GdkDragAction(GDK_ACTION_COPY | GDK_ACTION_MOVE) );
 
 
-            g_signal_connect( G_OBJECT(newBlot->gobj()),
-                              "drag-data-received",
-                              G_CALLBACK(_dropDataIn),
-                              this );
+//             g_signal_connect( G_OBJECT(newBlot->gobj()),
+//                               "drag-data-received",
+//                               G_CALLBACK(_dropDataIn),
+//                               this );
         }
 
         g_signal_connect( G_OBJECT(newBlot->gobj()),
index 8c8d240c6054552cb163803545d8968777d77f9a..fb0eeeb5e5d5d656ed44ef5a2fade9cec4a38664 100644 (file)
 #endif
 
 #include <stdint.h>
+#include <string>
+#include <iostream>
+#include <sstream>
+#include <stdlib.h>
+#include <string.h>
 
 #if !defined(_)
 #define _(s) gettext(s)
 namespace eek
 {
 
+static std::string mimeTEXT("text/plain");
+static std::string mimeX_COLOR("application/x-color");
+static std::string mimeOSWB_COLOR("application/x-oswb-color");
+
+static std::string doubleToStr(double d);
+
 ColorDef::ColorDef() :
     descr(_("none")),
     type(NONE),
@@ -131,23 +142,21 @@ public:
 std::vector<std::string> ColorDef::getMIMETypes()
 {
     std::vector<std::string> listing;
-    if ( getType() != eek::ColorDef::RGB ) {
-        listing.push_back("application/x-oswb-nocolor");
-    }
-    listing.push_back("application/x-color");
-    listing.push_back("text/plain");
+    listing.push_back(mimeOSWB_COLOR);
+    listing.push_back(mimeX_COLOR);
+    listing.push_back(mimeTEXT);
     return listing;
 }
 
 void ColorDef::getMIMEData(std::string const & type, char*& dest, int& len, int& format)
 {
-    if ( type == "text/plain" ) {
+    if ( type == mimeTEXT ) {
         dest = new char[8];
         snprintf( dest, 8, "#%02x%02x%02x", getR(), getG(), getB() );
         dest[7] = 0;
         len = 8;
         format = 8;
-    } else if ( (type == "application/x-color") || (type == "application/x-oswb-nocolor") ) {
+    } else if ( type == mimeX_COLOR ) {
         uint16_t* tmp = new uint16_t[4];
         tmp[0] = (getR() << 8) | getR();
         tmp[1] = (getG() << 8) | getG();
@@ -156,6 +165,38 @@ void ColorDef::getMIMEData(std::string const & type, char*& dest, int& len, int&
         dest = reinterpret_cast<char*>(tmp);
         len = 8;
         format = 16;
+    } else if ( type == mimeOSWB_COLOR ) {
+        std::string tmp("<paint>");
+        switch ( getType() ) {
+            case eek::ColorDef::NONE:
+            {
+                tmp += "<nocolor/>";
+            }
+            break;
+            case eek::ColorDef::CLEAR:
+            {
+                tmp += "<clear/>";
+            }
+            break;
+            default:
+            {
+                tmp += std::string("<color name=\"") + descr + "\">";
+                tmp += "<sRGB r=\"";
+                tmp += doubleToStr(getR()/255.0);
+                tmp += "\" g=\"";
+                tmp += doubleToStr(getG()/255.0);
+                tmp += "\" b=\"";
+                tmp += doubleToStr(getB()/255.0);
+                tmp += "\"/>";
+                tmp += "</color>";
+            }
+        }
+        tmp += "</paint>";
+        len = tmp.size();
+        dest = new char[len];
+        // Note that this is not null-terminated:
+        memcpy(dest, tmp.c_str(), len);
+        format = 8;
     } else {
         // nothing
         dest = 0;
@@ -163,6 +204,68 @@ void ColorDef::getMIMEData(std::string const & type, char*& dest, int& len, int&
     }
 }
 
+bool ColorDef::fromMIMEData(std::string const & type, char const * data, int len, int /*format*/)
+{
+    bool worked = false;
+    bool changed = false;
+    if ( type == mimeTEXT ) {
+    } else if ( type == mimeX_COLOR ) {
+    } else if ( type == mimeOSWB_COLOR ) {
+        std::string xml(data, len);
+        if ( xml.find("<nocolor/>") != std::string::npos ) {
+            if ( (this->type != eek::ColorDef::NONE)
+                 || (this->r != 0)
+                 || (this->g != 0)
+                 || (this->b != 0) ) {
+                this->type = eek::ColorDef::NONE;
+                this->r = 0;
+                this->g = 0;
+                this->b = 0;
+                changed = true;
+            }
+            worked = true;
+        } else {
+            size_t pos = xml.find("<sRGB");
+            if ( pos != std::string::npos ) {
+                size_t endPos = xml.find(">", pos);
+                std::string srgb = xml.substr(pos, endPos);
+                this->type = eek::ColorDef::RGB;
+                size_t numPos = srgb.find("r=");
+                if (numPos != std::string::npos) {
+                    char* endPtr = 0;
+                    double dbl = strtod(srgb.c_str() + numPos + 3, &endPtr);
+                    this->r = static_cast<int>(255 * dbl);
+                }
+                numPos = srgb.find("g=");
+                if (numPos != std::string::npos) {
+                    char* endPtr = 0;
+                    double dbl = strtod(srgb.c_str() + numPos + 3, &endPtr);
+                    this->g = static_cast<int>(255 * dbl);
+                }
+                numPos = srgb.find("b=");
+                if (numPos != std::string::npos) {
+                    char* endPtr = 0;
+                    double dbl = strtod(srgb.c_str() + numPos + 3, &endPtr);
+                    this->b = static_cast<int>(255 * dbl);
+                }
+                changed = true;
+                worked = true;
+            }
+        }
+    }
+    if ( changed ) {
+        // beware of callbacks changing things
+        for ( std::vector<HookData*>::iterator it = _listeners.begin(); it != _listeners.end(); ++it )
+        {
+            if ( (*it)->_cb )
+            {
+                (*it)->_cb( (*it)->_data );
+            }
+        }
+    }
+    return worked;
+}
+
 void ColorDef::setRGB( unsigned int r, unsigned int g, unsigned int b )
 {
     if ( r != this->r || g != this->g || b != this->b ) {
@@ -186,10 +289,16 @@ void ColorDef::addCallback( ColorCallback cb, void* data )
     _listeners.push_back( new HookData(cb, data) );
 }
 
-void ColorDef::removeCallback( ColorCallback cb, void* data )
+void ColorDef::removeCallback( ColorCallback /*cb*/, void* /*data*/ )
+{
+}
+
+static std::string doubleToStr(double d)
 {
-    (void)cb;
-    (void)data;
+    // TODO ensure "." is used for decimal separator.
+    std::stringstream out;
+    out << d;
+    return out.str();
 }
 
 } // namespace eek
index 39d69d5d122bab2b9e4db190251992e78d69a737..2f6117d54ed7f77a81af96a585ce090d7df1e34b 100644 (file)
@@ -66,6 +66,7 @@ public:
 
     std::vector<std::string> getMIMETypes();
     void getMIMEData(std::string const & type, char*& dest, int& len, int& format);
+    bool fromMIMEData(std::string const & type, char const * data, int len, int format);
 
     void setRGB( unsigned int r, unsigned int g, unsigned int b );
     unsigned int getR() const { return r; }