Code

Merge and cleanup of GSoC C++-ification project.
[inkscape.git] / src / widgets / gradient-selector.cpp
index f24a6781b134509b05ebf494edff50d73ebee6a2..49549de1c51d49e19a7b26122e1b671757774f93 100644 (file)
@@ -4,9 +4,11 @@
  * Authors:
  *   Lauris Kaplinski <lauris@kaplinski.com>
  *   bulia byak <buliabyak@users.sf.net>
+ *   Jon A. Cruz <jon@joncruz.org>
  *
  * Copyright (C) 2001-2002 Lauris Kaplinski
  * Copyright (C) 2001 Ximian, Inc.
+ * Copyright (C) 2010 Jon A. Cruz
  *
  * Released under GNU GPL, read the file 'COPYING' for more information
  */
@@ -115,12 +117,12 @@ sp_gradient_selector_class_init (SPGradientSelectorClass *klass)
     object_class->destroy = sp_gradient_selector_destroy;
 }
 
-static void
-sp_gradient_selector_init (SPGradientSelector *sel)
+static void sp_gradient_selector_init(SPGradientSelector *sel)
 {
-    GtkWidget *hb, *l, *m, *mi;
+    sel->safelyInit = true;
+    new (&sel->nonsolid) std::vector<GtkWidget*>();
 
-    sel->mode = SP_GRADIENT_SELECTOR_MODE_LINEAR;
+    sel->mode = SPGradientSelector::MODE_LINEAR;
 
     sel->gradientUnits = SP_GRADIENT_UNITS_USERSPACEONUSE;
     sel->gradientSpread = SP_GRADIENT_SPREAD_PAD;
@@ -132,39 +134,44 @@ sp_gradient_selector_init (SPGradientSelector *sel)
     g_signal_connect (G_OBJECT (sel->vectors), "vector_set", G_CALLBACK (sp_gradient_selector_vector_set), sel);
 
     /* Create box for buttons */
-    hb = gtk_hbox_new (FALSE, 0);
-    gtk_box_pack_start (GTK_BOX (sel), hb, FALSE, FALSE, 0);
+    GtkWidget *hb = gtk_hbox_new( FALSE, 0 );
+    sel->nonsolid.push_back(hb);
+    gtk_box_pack_start( GTK_BOX(sel), hb, FALSE, FALSE, 0 );
     GtkTooltips *ttips = gtk_tooltips_new ();
 
     sel->add = gtk_button_new_with_label (_("Duplicate"));
+    sel->nonsolid.push_back(sel->add);
     gtk_box_pack_start (GTK_BOX (hb), sel->add, TRUE, TRUE, 0);
     g_signal_connect (G_OBJECT (sel->add), "clicked", G_CALLBACK (sp_gradient_selector_add_vector_clicked), sel);
     gtk_widget_set_sensitive (sel->add, FALSE);
 
     sel->edit = gtk_button_new_with_label (_("Edit..."));
+    sel->nonsolid.push_back(sel->edit);
     gtk_box_pack_start (GTK_BOX (hb), sel->edit, TRUE, TRUE, 0);
     g_signal_connect (G_OBJECT (sel->edit), "clicked", G_CALLBACK (sp_gradient_selector_edit_vector_clicked), sel);
     gtk_widget_set_sensitive (sel->edit, FALSE);
 
-    gtk_widget_show_all (hb);
+    gtk_widget_show_all(hb);
 
     /* Spread selector */
-    hb = gtk_hbox_new (FALSE, 0);
-    gtk_widget_show (hb);
-    gtk_box_pack_start (GTK_BOX (sel), hb, FALSE, FALSE, 0);
-
-    sel->spread = gtk_option_menu_new ();
-    gtk_widget_show (sel->spread);
-    gtk_box_pack_end (GTK_BOX (hb), sel->spread, FALSE, FALSE, 0);
-    gtk_tooltips_set_tip (ttips, sel->spread,
+    hb = gtk_hbox_new( FALSE, 0 );
+    sel->nonsolid.push_back(hb);
+    gtk_widget_show(hb);
+    gtk_box_pack_start( GTK_BOX(sel), hb, FALSE, FALSE, 0 );
+
+    sel->spread = gtk_option_menu_new();
+    sel->nonsolid.push_back(sel->spread);
+    gtk_widget_show(sel->spread);
+    gtk_box_pack_end( GTK_BOX(hb), sel->spread, FALSE, FALSE, 0 );
+    gtk_tooltips_set_tip( ttips, sel->spread,
                           // TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/pservers.html#LinearGradientSpreadMethodAttribute
                           _("Whether to fill with flat color beyond the ends of the gradient vector "
                             "(spreadMethod=\"pad\"), or repeat the gradient in the same direction "
                             "(spreadMethod=\"repeat\"), or repeat the gradient in alternating opposite "
                             "directions (spreadMethod=\"reflect\")"), NULL);
 
-    m = gtk_menu_new ();
-    mi = gtk_menu_item_new_with_label (_("none"));
+    GtkWidget *m = gtk_menu_new();
+    GtkWidget *mi = gtk_menu_item_new_with_label(_("none"));
     gtk_menu_append (GTK_MENU (m), mi);
     g_object_set_data (G_OBJECT (mi), "gradientSpread", GUINT_TO_POINTER (SP_GRADIENT_SPREAD_PAD));
     g_signal_connect (G_OBJECT (mi), "activate", G_CALLBACK (sp_gradient_selector_spread_activate), sel);
@@ -178,22 +185,27 @@ sp_gradient_selector_init (SPGradientSelector *sel)
     gtk_menu_append (GTK_MENU (m), mi);
     gtk_widget_show_all (m);
 
-    gtk_option_menu_set_menu (GTK_OPTION_MENU (sel->spread), m);
+    gtk_option_menu_set_menu( GTK_OPTION_MENU(sel->spread), m );
 
-    l = gtk_label_new (_("Repeat:"));
-    gtk_widget_show (l);
-    gtk_box_pack_end (GTK_BOX (hb), l, FALSE, FALSE, 4);
+    sel->spreadLbl = gtk_label_new( _("Repeat:") );
+    sel->nonsolid.push_back(sel->spreadLbl);
+    gtk_widget_show( sel->spreadLbl );
+    gtk_box_pack_end( GTK_BOX(hb), sel->spreadLbl, FALSE, FALSE, 4 );
 }
 
-static void
-sp_gradient_selector_destroy (GtkObject *object)
+static void sp_gradient_selector_destroy(GtkObject *object)
 {
-    SPGradientSelector *sel;
+    SPGradientSelector *sel = SP_GRADIENT_SELECTOR( object );
 
-    sel = SP_GRADIENT_SELECTOR (object);
+    if ( sel->safelyInit ) {
+        sel->safelyInit = false;
+        using std::vector;
+        sel->nonsolid.~vector<GtkWidget*>();
+    }
 
-    if (((GtkObjectClass *) (parent_class))->destroy)
+    if (((GtkObjectClass *) (parent_class))->destroy) {
         (* ((GtkObjectClass *) (parent_class))->destroy) (object);
+    }
 }
 
 GtkWidget *
@@ -206,77 +218,90 @@ sp_gradient_selector_new (void)
     return (GtkWidget *) sel;
 }
 
-void
-sp_gradient_selector_set_mode (SPGradientSelector *sel, guint mode)
+void SPGradientSelector::setMode(SelectorMode mode)
 {
-    g_return_if_fail (sel != NULL);
-    g_return_if_fail (SP_IS_GRADIENT_SELECTOR (sel));
-
-    sel->mode = mode;
+    if (mode != this->mode) {
+        this->mode = mode;
+        if (mode == MODE_SWATCH) {
+            for (std::vector<GtkWidget*>::iterator it = nonsolid.begin(); it != nonsolid.end(); ++it)
+            {
+                gtk_widget_hide(*it);
+            }
+
+            SPGradientVectorSelector* vs = SP_GRADIENT_VECTOR_SELECTOR(vectors);
+            vs->setSwatched();
+        }
+    }
 }
 
-void
-sp_gradient_selector_set_units (SPGradientSelector *sel, guint units)
+void SPGradientSelector::setUnits(SPGradientUnits units)
 {
-    g_return_if_fail (sel != NULL);
-    g_return_if_fail (SP_IS_GRADIENT_SELECTOR (sel));
-
-    sel->gradientUnits = (SPGradientUnits)units;
+    gradientUnits = units;
 }
 
-void
-sp_gradient_selector_set_spread (SPGradientSelector *sel, guint spread)
+void SPGradientSelector::setSpread(SPGradientSpread spread)
 {
-    g_return_if_fail (sel != NULL);
-    g_return_if_fail (SP_IS_GRADIENT_SELECTOR (sel));
-
-    sel->gradientSpread = (SPGradientSpread)spread;
+    gradientSpread = spread;
 
-    gtk_option_menu_set_history (GTK_OPTION_MENU (sel->spread), sel->gradientSpread);
+    gtk_option_menu_set_history(GTK_OPTION_MENU(this->spread), gradientSpread);
 }
 
-SPGradientUnits
-sp_gradient_selector_get_units (SPGradientSelector *sel)
+SPGradientUnits SPGradientSelector::getUnits()
 {
-    return (SPGradientUnits) sel->gradientUnits;
+    return gradientUnits;
 }
 
-SPGradientSpread
-sp_gradient_selector_get_spread (SPGradientSelector *sel)
+SPGradientSpread SPGradientSelector::getSpread()
 {
-    return (SPGradientSpread) sel->gradientSpread;
+    return gradientSpread;
 }
 
-void
-sp_gradient_selector_set_vector (SPGradientSelector *sel, SPDocument *doc, SPGradient *vector)
+void SPGradientSelector::setVector(SPDocument *doc, SPGradient *vector)
 {
-    g_return_if_fail (sel != NULL);
-    g_return_if_fail (SP_IS_GRADIENT_SELECTOR (sel));
-    g_return_if_fail (!vector || SP_IS_GRADIENT (vector));
-    g_return_if_fail (!vector || (SP_OBJECT_DOCUMENT (vector) == doc));
+    g_return_if_fail(!vector || SP_IS_GRADIENT(vector));
+    g_return_if_fail(!vector || (SP_OBJECT_DOCUMENT(vector) == doc));
 
-    if (vector && !SP_GRADIENT_HAS_STOPS (vector))
+    if (vector && !vector->hasStops()) {
         return;
+    }
 
-    sp_gradient_vector_selector_set_gradient (SP_GRADIENT_VECTOR_SELECTOR (sel->vectors), doc, vector);
+    sp_gradient_vector_selector_set_gradient(SP_GRADIENT_VECTOR_SELECTOR(vectors), doc, vector);
 
     if (vector) {
-        gtk_widget_set_sensitive (sel->edit, TRUE);
-        gtk_widget_set_sensitive (sel->add, TRUE);
+        if ( (mode == MODE_SWATCH) && vector->isSwatch() ) {
+            if ( vector->isSolid() ) {
+                for (std::vector<GtkWidget*>::iterator it = nonsolid.begin(); it != nonsolid.end(); ++it)
+                {
+                    gtk_widget_hide(*it);
+                }
+            } else {
+                for (std::vector<GtkWidget*>::iterator it = nonsolid.begin(); it != nonsolid.end(); ++it)
+                {
+                    gtk_widget_show_all(*it);
+                }
+            }
+        }
+
+        if (edit) {
+            gtk_widget_set_sensitive(edit, TRUE);
+        }
+        if (add) {
+            gtk_widget_set_sensitive(add, TRUE);
+        }
     } else {
-        gtk_widget_set_sensitive (sel->edit, FALSE);
-        gtk_widget_set_sensitive (sel->add, (doc != NULL));
+        if (edit) {
+            gtk_widget_set_sensitive(edit, FALSE);
+        }
+        if (add) {
+            gtk_widget_set_sensitive(add, (doc != NULL));
+        }
     }
 }
 
-SPGradient *
-sp_gradient_selector_get_vector (SPGradientSelector *sel)
+SPGradient *SPGradientSelector::getVector()
 {
-    if (sel == NULL || !SP_IS_GRADIENT_SELECTOR (sel))
-        return NULL;
-
     /* fixme: */
-    return SP_GRADIENT_VECTOR_SELECTOR (sel->vectors)->gr;
+    return SP_GRADIENT_VECTOR_SELECTOR(vectors)->gr;
 }
 
 static void
@@ -287,7 +312,7 @@ sp_gradient_selector_vector_set (SPGradientVectorSelector */*gvs*/, SPGradient *
     if (!blocked) {
         blocked = TRUE;
         gr = sp_gradient_ensure_vector_normalized (gr);
-        sp_gradient_selector_set_vector (sel, (gr) ? SP_OBJECT_DOCUMENT (gr) : NULL, gr);
+        sel->setVector((gr) ? SP_OBJECT_DOCUMENT (gr) : 0, gr);
         g_signal_emit (G_OBJECT (sel), signals[CHANGED], 0, gr);
         blocked = FALSE;
     }
@@ -315,7 +340,7 @@ sp_gradient_selector_add_vector_clicked (GtkWidget */*w*/, SPGradientSelector *s
 
     SPGradient *gr = sp_gradient_vector_selector_get_gradient(
                                                               SP_GRADIENT_VECTOR_SELECTOR (sel->vectors));
-    Inkscape::XML::Document *xml_doc = sp_document_repr_doc(doc);
+    Inkscape::XML::Document *xml_doc = doc->getReprDoc();
 
     Inkscape::XML::Node *repr = NULL;