Code

Objects will now change when their linked colors change.
authorjoncruz <joncruz@users.sourceforge.net>
Tue, 28 Mar 2006 10:39:18 +0000 (10:39 +0000)
committerjoncruz <joncruz@users.sourceforge.net>
Tue, 28 Mar 2006 10:39:18 +0000 (10:39 +0000)
ChangeLog
src/dialogs/swatches.cpp
src/interface.cpp

index b31801278348124bb950911bbb261caa58010c22..8f85a016ebde242a0122cab5aa80d94ef7d218c3 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2006-03-28  Jon A. Cruz  <jon@joncruz.org>
+
+       * src/interface.cpp, src/dialogs/swatches.cpp:
+
+         Objects now change when linked colors change.
+       
 2006-03-28  Jon A. Cruz  <jon@joncruz.org>
 
        * src/dialogs/eek-color-def.h, src/dialogs/eek-color-def.cpp,
index 757a15d25244e92fbadc180ad13f5c1468f415c6..1d429603d571fb168f86c6f9b00cb6a8e709beee 100644 (file)
@@ -29,6 +29,7 @@
 #include "io/sys.h"
 #include "path-prefix.h"
 #include "swatches.h"
+#include "sp-item.h"
 
 #include "eek-preview.h"
 
@@ -72,6 +73,21 @@ ColorItem &ColorItem::operator=(ColorItem const &other)
     return *this;
 }
 
+
+class JustForNow
+{
+public:
+    JustForNow() : _prefWidth(0) {}
+
+    Glib::ustring _name;
+    int _prefWidth;
+    std::vector<ColorItem*> _colors;
+};
+
+static std::vector<JustForNow*> possible;
+
+
+
 typedef enum {
     APP_X_INKY_COLOR_ID = 0,
     APP_X_INKY_COLOR = 0,
@@ -107,6 +123,51 @@ static void dragGetColorData( GtkWidget *widget,
                                 strlen((const char*)tmp) + 1);
         g_free(tmp);
         tmp = 0;
+    } else if ( info == APP_X_INKY_COLOR ) {
+        Glib::ustring paletteName;
+
+        // Find where this thing came from
+        bool found = false;
+        int index = 0;
+        for ( std::vector<JustForNow*>::iterator it = possible.begin(); it != possible.end() && !found; ++it ) {
+            JustForNow* curr = *it;
+            index = 0;
+            for ( std::vector<ColorItem*>::iterator zz = curr->_colors.begin(); zz != curr->_colors.end(); ++zz ) {
+                if ( item == *zz ) {
+                    found = true;
+                    paletteName = curr->_name;
+                    break;
+                } else {
+                    index++;
+                }
+            }
+        }
+
+//         if ( found ) {
+//             g_message("Found the color at entry %d in palette '%s'", index, paletteName.c_str() );
+//         } else {
+//             g_message("Unable to find the color");
+//         }
+        int itemCount = 4 + 1 + 1 + paletteName.length();
+
+        guint16* tmp = new guint16[itemCount]
+;
+        tmp[0] = (item->def.getR() << 8) | item->def.getR();
+        tmp[1] = (item->def.getG() << 8) | item->def.getG();
+        tmp[2] = (item->def.getB() << 8) | item->def.getB();
+        tmp[3] = 0xffff;
+
+        tmp[4] = index;
+        tmp[5] = paletteName.length();
+        for ( unsigned int i = 0; i < paletteName.length(); i++ ) {
+            tmp[6 + i] = paletteName[i];
+        }
+        gtk_selection_data_set( data,
+                                typeXColor,
+                                16, // format
+                                reinterpret_cast<const guchar*>(tmp),
+                                itemCount * 2);
+        delete[] tmp;
     } else {
         guint16 tmp[4];
         tmp[0] = (item->def.getR() << 8) | item->def.getR();
@@ -188,8 +249,18 @@ void ColorItem::_dropDataIn( GtkWidget *widget,
      switch (info) {
          case APP_X_INKY_COLOR:
          {
-//              g_message("inky color");
-             // Fallthrough
+             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_COLOR:
          {
@@ -223,6 +294,50 @@ void ColorItem::_dropDataIn( GtkWidget *widget,
 
 }
 
+static bool bruteForce( SPDocument* document, Inkscape::XML::Node* node, Glib::ustring const& match, int r, int g, int b )
+{
+    bool changed = false;
+
+    if ( node ) {
+        gchar const * val = node->attribute("HOTFill");
+        if ( val  && (match == val) ) {
+            SPObject *obj = document->getObjectByRepr( node );
+
+            gchar c[64] = {0};
+            sp_svg_write_color( c, 64, SP_RGBA32_U_COMPOSE( r, g, b, 0xff ) );
+            SPCSSAttr *css = sp_repr_css_attr_new();
+            sp_repr_css_set_property( css, "fill", c );
+
+            sp_desktop_apply_css_recursive( (SPItem*)obj, css, true );
+            ((SPItem*)obj)->updateRepr();
+
+            changed = true;
+        }
+
+        val = node->attribute("HOTStroke");
+        if ( val  && (match == val) ) {
+            SPObject *obj = document->getObjectByRepr( node );
+
+            gchar c[64] = {0};
+            sp_svg_write_color( c, 64, SP_RGBA32_U_COMPOSE( r, g, b, 0xff ) );
+            SPCSSAttr *css = sp_repr_css_attr_new();
+            sp_repr_css_set_property( css, "stroke", c );
+
+            sp_desktop_apply_css_recursive( (SPItem*)obj, css, true );
+            ((SPItem*)obj)->updateRepr();
+
+            changed = true;
+        }
+
+        Inkscape::XML::Node* first = node->firstChild();
+        changed |= bruteForce( document, first, match, r, g, b );
+
+        changed |= bruteForce( document, node->next(), match, r, g, b );
+    }
+
+    return changed;
+}
+
 void ColorItem::_colorDefChanged(void* data)
 {
     ColorItem* item = reinterpret_cast<ColorItem*>(data);
@@ -236,7 +351,7 @@ void ColorItem::_colorDefChanged(void* data)
                                        (item->def.getG() << 8) | item->def.getG(),
                                        (item->def.getB() << 8) | item->def.getB() );
 
-                eek_preview_set_linked( preview, (item->_linkSrc ? PREVIEW_LINK_IN:0) | (item->_listeners.empty() ? 0:PREVIEW_LINK_OUT) );
+                eek_preview_set_linked( preview, (LinkType)((item->_linkSrc ? PREVIEW_LINK_IN:0) | (item->_listeners.empty() ? 0:PREVIEW_LINK_OUT)) );
 
                 widget->queue_draw();
             }
@@ -259,6 +374,47 @@ void ColorItem::_colorDefChanged(void* data)
 
             (*it)->def.setRGB( r, g, b );
         }
+
+
+        // Look for objects using this color
+        {
+            SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+            if ( desktop ) {
+                SPDocument* document = SP_DT_DOCUMENT( desktop );
+                Inkscape::XML::Node *rroot =  sp_document_repr_root( document );
+                if ( rroot ) {
+
+                    // Find where this thing came from
+                    Glib::ustring paletteName;
+                    bool found = false;
+                    int index = 0;
+                    for ( std::vector<JustForNow*>::iterator it2 = possible.begin(); it2 != possible.end() && !found; ++it2 ) {
+                        JustForNow* curr = *it2;
+                        index = 0;
+                        for ( std::vector<ColorItem*>::iterator zz = curr->_colors.begin(); zz != curr->_colors.end(); ++zz ) {
+                            if ( item == *zz ) {
+                                found = true;
+                                paletteName = curr->_name;
+                                break;
+                            } else {
+                                index++;
+                            }
+                        }
+                    }
+
+                    if ( !paletteName.empty() ) {
+                        gchar* str = g_strdup_printf("%d|", index);
+                        paletteName.insert( 0, str );
+                        g_free(str);
+                        str = 0;
+
+                        if ( bruteForce( document, rroot, paletteName, item->def.getR(), item->def.getG(), item->def.getB() ) ) {
+                            sp_document_done( document );
+                        }
+                    }
+                }
+            }
+        }
     }
 }
 
@@ -283,7 +439,7 @@ Gtk::Widget* ColorItem::getPreview(PreviewStyle style, ViewType view, Gtk::Built
         eek_preview_set_color( preview, (def.getR() << 8) | def.getR(), (def.getG() << 8) | def.getG(), (def.getB() << 8) | def.getB());
 
         eek_preview_set_details( preview, (::PreviewStyle)style, (::ViewType)view, (::GtkIconSize)size );
-        eek_preview_set_linked( preview, (_linkSrc ? PREVIEW_LINK_IN:0) | (_listeners.empty() ? 0:PREVIEW_LINK_OUT) );
+        eek_preview_set_linked( preview, (LinkType)((_linkSrc ? PREVIEW_LINK_IN:0) | (_listeners.empty() ? 0:PREVIEW_LINK_OUT)) );
 
         def.addCallback( _colorDefChanged, this );
 
@@ -425,18 +581,6 @@ bool parseNum( char*& str, int& val ) {
 }
 
 
-class JustForNow
-{
-public:
-    JustForNow() : _prefWidth(0) {}
-
-    Glib::ustring _name;
-    int _prefWidth;
-    std::vector<ColorItem*> _colors;
-};
-
-static std::vector<JustForNow*> possible;
-
 static bool getBlock( std::string& dst, guchar ch, std::string const str )
 {
     bool good = false;
index d332d6cb3575e5feb83352a27b08036666fb4b67..5de76aff170a9bfc6dacf880730887e0e9c825d0 100644 (file)
@@ -75,6 +75,7 @@ typedef enum {
     PNG_DATA,
     JPEG_DATA,
     IMAGE_DATA,
+    APP_X_INKY_COLOR,
     APP_X_COLOR
 } ui_drop_target_info;
 
@@ -84,6 +85,7 @@ static GtkTargetEntry ui_drop_target_entries [] = {
     {"image/svg",     0, SVG_DATA},
     {"image/png",     0, PNG_DATA},
     {"image/jpeg",    0, JPEG_DATA},
+    {"application/x-inkscape-color", 0, APP_X_INKY_COLOR},
     {"application/x-color", 0, APP_X_COLOR}
 };
 
@@ -974,6 +976,65 @@ sp_ui_drag_data_received(GtkWidget *widget,
                          gpointer user_data)
 {
     switch (info) {
+        case APP_X_INKY_COLOR:
+        {
+            SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+            int destX = 0;
+            int destY = 0;
+            gtk_widget_translate_coordinates( widget, &(desktop->canvas->widget), x, y, &destX, &destY );
+            NR::Point where( sp_canvas_window_to_world( desktop->canvas, NR::Point( destX, destY ) ) );
+
+            SPItem *item = desktop->item_at_point( where, true );
+            if ( item )
+            {
+                if ( data->length >= 8 ) {
+                    gchar c[64] = {0};
+                    // Careful about endian issues.
+                    guint16* dataVals = (guint16*)data->data;
+                    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),
+                                            ));
+                    SPCSSAttr *css = sp_repr_css_attr_new();
+                    sp_repr_css_set_property( css, (drag_context->action != GDK_ACTION_MOVE) ? "fill":"stroke", c );
+
+                    sp_desktop_apply_css_recursive( item, css, true );
+                    item->updateRepr();
+
+                    if ( data->length > 12 ) {
+                        // piggie-backed palette entry info
+                        int index = dataVals[4];
+                        Glib::ustring palName;
+                        for ( int i = 0; i < dataVals[5]; i++ ) {
+                            palName += (gunichar)dataVals[6+i];
+                        }
+
+                        // Now hook in a magic tag of some sort.
+                        if ( !palName.empty() ) {
+                            gchar* str = g_strdup_printf("%d|", index);
+                            palName.insert( 0, str );
+                            g_free(str);
+                            str = 0;
+
+                            sp_object_setAttribute( SP_OBJECT(item),
+                                                    (drag_context->action != GDK_ACTION_MOVE) ? "HOTFill":"HOTStroke",
+                                                    palName.c_str(),
+                                                    false );
+                            item->updateRepr();
+                        }
+                    }
+
+                    SPDocument *doc = SP_ACTIVE_DOCUMENT;
+                    sp_document_done( doc );
+                }
+            }
+        }
+        break;
+
         case APP_X_COLOR:
         {
             SPDesktop *desktop = SP_ACTIVE_DESKTOP;