summaryrefslogtreecommitdiffstats
path: root/src/widgets
diff options
context:
space:
mode:
Diffstat (limited to 'src/widgets')
-rw-r--r--src/widgets/gradient-selector.cpp293
-rw-r--r--src/widgets/gradient-selector.h54
-rw-r--r--src/widgets/gradient-vector.cpp191
-rw-r--r--src/widgets/gradient-vector.h12
-rw-r--r--src/widgets/swatch-selector.cpp2
5 files changed, 374 insertions, 178 deletions
diff --git a/src/widgets/gradient-selector.cpp b/src/widgets/gradient-selector.cpp
index 3a8caa28c..2095179ae 100644
--- a/src/widgets/gradient-selector.cpp
+++ b/src/widgets/gradient-selector.cpp
@@ -21,13 +21,19 @@
#include "document.h"
#include "../document-private.h"
#include "../gradient-chemistry.h"
+#include "inkscape.h"
+#include "verbs.h"
+#include "helper/action.h"
+#include "preferences.h"
#include <glibmm/i18n.h>
#include <xml/repr.h>
#include "gradient-vector.h"
-
#include "gradient-selector.h"
+#include "paint-selector.h"
+#include "style.h"
+#include "id-clash.h"
enum {
GRABBED,
@@ -37,6 +43,7 @@ enum {
LAST_SIGNAL
};
+
static void sp_gradient_selector_class_init (SPGradientSelectorClass *klass);
static void sp_gradient_selector_init (SPGradientSelector *selector);
static void sp_gradient_selector_dispose(GObject *object);
@@ -45,7 +52,6 @@ static void sp_gradient_selector_dispose(GObject *object);
static void sp_gradient_selector_vector_set (SPGradientVectorSelector *gvs, SPGradient *gr, SPGradientSelector *sel);
static void sp_gradient_selector_edit_vector_clicked (GtkWidget *w, SPGradientSelector *sel);
static void sp_gradient_selector_add_vector_clicked (GtkWidget *w, SPGradientSelector *sel);
-static void sp_gradient_selector_spread_changed (GtkComboBox *widget, SPGradientSelector *sel);
static GtkVBoxClass *parent_class;
static guint signals[LAST_SIGNAL] = {0};
@@ -116,6 +122,7 @@ static void sp_gradient_selector_class_init(SPGradientSelectorClass *klass)
static void sp_gradient_selector_init(SPGradientSelector *sel)
{
sel->safelyInit = true;
+ sel->blocked = false;
new (&sel->nonsolid) std::vector<GtkWidget*>();
sel->mode = SPGradientSelector::MODE_LINEAR;
@@ -125,78 +132,89 @@ static void sp_gradient_selector_init(SPGradientSelector *sel)
/* Vectors */
sel->vectors = sp_gradient_vector_selector_new (NULL, NULL);
- gtk_widget_show (sel->vectors);
- gtk_box_pack_start (GTK_BOX (sel), sel->vectors, FALSE, FALSE, 0);
- g_signal_connect (G_OBJECT (sel->vectors), "vector_set", G_CALLBACK (sp_gradient_selector_vector_set), sel);
+ SPGradientVectorSelector *gvs = SP_GRADIENT_VECTOR_SELECTOR(sel->vectors);
+ sel->store = gvs->store;
+ sel->columns = gvs->columns;
+
+ sel->treeview = Gtk::manage(new Gtk::TreeView());
+ sel->treeview->set_model(gvs->store);
+ sel->treeview->set_headers_clickable (true);
+ sel->treeview->set_search_column(1);
+ sel->icon_renderer = Gtk::manage(new Gtk::CellRendererPixbuf());
+ sel->text_renderer = Gtk::manage(new Gtk::CellRendererText());
+
+ sel->treeview->append_column("Gradient", *sel->icon_renderer);
+ Gtk::TreeView::Column* icon_column = sel->treeview->get_column(0);
+ icon_column->add_attribute(sel->icon_renderer->property_pixbuf(), sel->columns->pixbuf);
+ icon_column->set_sort_column(sel->columns->color);
+ icon_column->set_clickable(true);
+
+ sel->treeview->append_column("Name", *sel->text_renderer);
+ Gtk::TreeView::Column* name_column = sel->treeview->get_column(1);
+ sel->text_renderer->property_editable() = true;
+ name_column->add_attribute(sel->text_renderer->property_text(), sel->columns->name);
+ name_column->set_min_width(200);
+ name_column->set_clickable(true);
+ name_column->set_resizable(true);
+
+ sel->treeview->append_column("#", sel->columns->refcount);
+ Gtk::TreeView::Column* count_column = sel->treeview->get_column(2);
+ count_column->set_clickable(true);
+ count_column->set_resizable(true);
+
+ sel->treeview->show();
+
+ icon_column->signal_clicked().connect( sigc::mem_fun(*sel, &SPGradientSelector::onTreeColorColClick) );
+ name_column->signal_clicked().connect( sigc::mem_fun(*sel, &SPGradientSelector::onTreeNameColClick) );
+ count_column->signal_clicked().connect( sigc::mem_fun(*sel, &SPGradientSelector::onTreeCountColClick) );
+
+ gvs->tree_select_connection = sel->treeview->get_selection()->signal_changed().connect( sigc::mem_fun(*sel, &SPGradientSelector::onTreeSelection) );
+ sel->text_renderer->signal_edited().connect( sigc::mem_fun(*sel, &SPGradientSelector::onTreeEdited) );
+
+ sel->scrolled_window = Gtk::manage(new Gtk::ScrolledWindow());
+ sel->scrolled_window->add(*sel->treeview);
+ sel->scrolled_window->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
+ sel->scrolled_window->set_shadow_type(Gtk::SHADOW_IN);
+ sel->scrolled_window->set_size_request(0, 150);
+ sel->scrolled_window->show();
+
+ gtk_box_pack_start (GTK_BOX (sel), GTK_WIDGET(sel->scrolled_window->gobj()), TRUE, TRUE, 4);
+
/* Create box for buttons */
#if GTK_CHECK_VERSION(3,0,0)
GtkWidget *hb = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
gtk_box_set_homogeneous(GTK_BOX(hb), FALSE);
#else
- GtkWidget *hb = gtk_hbox_new( FALSE, 0 );
+ GtkWidget *hb = gtk_hbox_new( FALSE, 2 );
#endif
sel->nonsolid.push_back(hb);
gtk_box_pack_start( GTK_BOX(sel), hb, FALSE, FALSE, 0 );
- sel->add = gtk_button_new_with_label (_("Duplicate"));
+ sel->add = gtk_button_new ();
+ gtk_button_set_image((GtkButton*)sel->add , gtk_image_new_from_stock ( GTK_STOCK_ADD, GTK_ICON_SIZE_SMALL_TOOLBAR ) );
+
sel->nonsolid.push_back(sel->add);
- gtk_box_pack_start (GTK_BOX (hb), sel->add, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (hb), sel->add, FALSE, FALSE, 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);
+ gtk_button_set_relief(GTK_BUTTON(sel->add), GTK_RELIEF_NONE);
+ gtk_widget_set_tooltip_text( sel->add, _("Create a duplicate gradient"));
+
+ sel->edit = gtk_button_new ();
+ gtk_button_set_image((GtkButton*)sel->edit , gtk_image_new_from_stock ( GTK_STOCK_EDIT, GTK_ICON_SIZE_SMALL_TOOLBAR ) );
- 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);
+ gtk_box_pack_start (GTK_BOX (hb), sel->edit, FALSE, FALSE, 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_button_set_relief(GTK_BUTTON(sel->edit), GTK_RELIEF_NONE);
+ gtk_widget_set_tooltip_text( sel->edit, _("Edit gradient"));
gtk_widget_show_all(hb);
- /* Spread selector */
-#if GTK_CHECK_VERSION(3,0,0)
- hb = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
- gtk_box_set_homogeneous(GTK_BOX(hb), FALSE);
-#else
- hb = gtk_hbox_new( FALSE, 0 );
-#endif
- sel->nonsolid.push_back(hb);
- gtk_widget_show(hb);
- gtk_box_pack_start( GTK_BOX(sel), hb, FALSE, FALSE, 0 );
-
-// The GtkComboBoxText API only appeared in Gtk 2.24 but Inkscape supports
-// builds for Gtk >= 2.20.
-// Older versions need to use now-deprecated parts of
-// the GtkComboBox API instead.
-#if GTK_CHECK_VERSION(2,24,0)
- sel->spread = gtk_combo_box_text_new ();
- gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (sel->spread), _("none"));
- gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (sel->spread), _("reflected"));
- gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (sel->spread), _("direct"));
-#else
- sel->spread = gtk_combo_box_new_text ();
- gtk_combo_box_append_text (GTK_COMBO_BOX (sel->spread), _("none"));
- gtk_combo_box_append_text (GTK_COMBO_BOX (sel->spread), _("reflected"));
- gtk_combo_box_append_text (GTK_COMBO_BOX (sel->spread), _("direct"));
-#endif
- sel->nonsolid.push_back(sel->spread);
- gtk_widget_show(sel->spread);
- gtk_box_pack_end( GTK_BOX(hb), sel->spread, FALSE, FALSE, 0 );
- gtk_widget_set_tooltip_text( 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\")"));
-
- g_signal_connect (G_OBJECT (sel->spread), "changed",
- G_CALLBACK (sp_gradient_selector_spread_changed), sel);
-
- 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_dispose(GObject *object)
@@ -209,11 +227,27 @@ static void sp_gradient_selector_dispose(GObject *object)
sel->nonsolid.~vector<GtkWidget*>();
}
+ if (sel->icon_renderer) {
+ delete sel->icon_renderer;
+ sel->icon_renderer = NULL;
+ }
+ if (sel->text_renderer) {
+ delete sel->text_renderer;
+ sel->text_renderer = NULL;
+ }
+
if (((GObjectClass *) (parent_class))->dispose) {
(* ((GObjectClass *) (parent_class))->dispose) (object);
}
}
+void SPGradientSelector::setSpread(SPGradientSpread spread)
+{
+ gradientSpread = spread;
+ //gtk_combo_box_set_active (GTK_COMBO_BOX(this->spread), gradientSpread);
+}
+
+
GtkWidget *
sp_gradient_selector_new (void)
{
@@ -245,12 +279,6 @@ void SPGradientSelector::setUnits(SPGradientUnits units)
gradientUnits = units;
}
-void SPGradientSelector::setSpread(SPGradientSpread spread)
-{
- gradientSpread = spread;
- gtk_combo_box_set_active (GTK_COMBO_BOX(this->spread), gradientSpread);
-}
-
SPGradientUnits SPGradientSelector::getUnits()
{
return gradientUnits;
@@ -261,6 +289,92 @@ SPGradientSpread SPGradientSelector::getSpread()
return gradientSpread;
}
+void SPGradientSelector::onTreeEdited( const Glib::ustring& path_string, const Glib::ustring& new_text)
+{
+ Gtk::TreePath path(path_string);
+ Gtk::TreeModel::iterator iter = store->get_iter(path);
+
+ if( iter )
+ {
+ Gtk::TreeModel::Row row = *iter;
+ if ( row ) {
+ SPObject* obj = row[columns->data];
+ if ( obj ) {
+ if (!new_text.empty() && new_text != row[columns->name]) {
+ rename_id(obj, new_text );
+ }
+ row[columns->name] = gr_prepare_label(obj);
+ }
+ }
+ }
+}
+
+void SPGradientSelector::onTreeColorColClick() {
+ Gtk::TreeView::Column* column = treeview->get_column(0);
+ column->set_sort_column(columns->color);
+}
+
+void SPGradientSelector::onTreeNameColClick() {
+ Gtk::TreeView::Column* column = treeview->get_column(1);
+ column->set_sort_column(columns->name);
+}
+
+
+void SPGradientSelector::onTreeCountColClick() {
+ Gtk::TreeView::Column* column = treeview->get_column(2);
+ column->set_sort_column(columns->refcount);
+}
+
+
+void SPGradientSelector::onTreeSelection()
+{
+ if (!treeview) {
+ return;
+ }
+
+ if (blocked) {
+ return;
+ }
+
+ const Glib::RefPtr<Gtk::TreeSelection> sel = treeview->get_selection();
+ if (!sel) {
+ return;
+ }
+
+ SPGradient *obj = NULL;
+ /* Single selection */
+ Gtk::TreeModel::iterator iter = sel->get_selected();
+ if ( iter ) {
+ Gtk::TreeModel::Row row = *iter;
+ obj = row[columns->data];
+ }
+
+ if (obj) {
+ sp_gradient_selector_vector_set (NULL, (SPGradient*)obj, this);
+ }
+}
+
+bool SPGradientSelector::_checkForSelected(const Gtk::TreePath &path, const Gtk::TreeIter& iter, SPGradient *vector)
+{
+ bool found = false;
+
+ Gtk::TreeModel::Row row = *iter;
+ if ( vector == row[columns->data] )
+ {
+ treeview->scroll_to_row(path, 0.5);
+ Glib::RefPtr<Gtk::TreeSelection> select = treeview->get_selection();
+ select->select(iter);
+ found = true;
+ }
+
+ return found;
+}
+
+void SPGradientSelector::selectGradientInTree(SPGradient *vector)
+{
+ store->foreach( sigc::bind<SPGradient*>(sigc::mem_fun(*this, &SPGradientSelector::_checkForSelected), vector) );
+}
+
void SPGradientSelector::setVector(SPDocument *doc, SPGradient *vector)
{
g_return_if_fail(!vector || SP_IS_GRADIENT(vector));
@@ -272,6 +386,8 @@ void SPGradientSelector::setVector(SPDocument *doc, SPGradient *vector)
sp_gradient_vector_selector_set_gradient(SP_GRADIENT_VECTOR_SELECTOR(vectors), doc, vector);
+ selectGradientInTree(vector);
+
if (vector) {
if ( (mode == MODE_SWATCH) && vector->isSwatch() ) {
if ( vector->isSolid() ) {
@@ -309,42 +425,51 @@ SPGradient *SPGradientSelector::getVector()
return SP_GRADIENT_VECTOR_SELECTOR(vectors)->gr;
}
+
static void
-sp_gradient_selector_vector_set (SPGradientVectorSelector */*gvs*/, SPGradient *gr, SPGradientSelector *sel)
+sp_gradient_selector_vector_set (SPGradientVectorSelector *gvs, SPGradient *gr, SPGradientSelector *sel)
{
- static gboolean blocked = FALSE;
- if (!blocked) {
- blocked = TRUE;
+ if (!sel->blocked) {
+ sel->blocked = TRUE;
gr = sp_gradient_ensure_vector_normalized (gr);
sel->setVector((gr) ? gr->document : 0, gr);
g_signal_emit (G_OBJECT (sel), signals[CHANGED], 0, gr);
- blocked = FALSE;
+ sel->blocked = FALSE;
+
}
}
static void
sp_gradient_selector_edit_vector_clicked (GtkWidget */*w*/, SPGradientSelector *sel)
{
- GtkWidget *dialog;
-
- /* fixme: */
- dialog = sp_gradient_vector_editor_new (SP_GRADIENT_VECTOR_SELECTOR (sel->vectors)->gr);
-
- gtk_widget_show (dialog);
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ if (prefs->getBool("/dialogs/gradienteditor/showlegacy", true)) {
+ // Legacy gradient dialog
+ GtkWidget *dialog;
+ dialog = sp_gradient_vector_editor_new (SP_GRADIENT_VECTOR_SELECTOR (sel->vectors)->gr);
+ gtk_widget_show (dialog);
+ } else {
+ // Invoke the gradient tool
+ Inkscape::Verb *verb = Inkscape::Verb::get( SP_VERB_CONTEXT_GRADIENT );
+ if ( verb ) {
+ SPAction *action = verb->get_action( ( Inkscape::UI::View::View * ) SP_ACTIVE_DESKTOP);
+ if ( action ) {
+ sp_action_perform( action, NULL );
+ }
+ }
+ }
}
static void
sp_gradient_selector_add_vector_clicked (GtkWidget */*w*/, SPGradientSelector *sel)
{
- SPDocument *doc = sp_gradient_vector_selector_get_document (
- SP_GRADIENT_VECTOR_SELECTOR (sel->vectors));
+ SPDocument *doc = sp_gradient_vector_selector_get_document (SP_GRADIENT_VECTOR_SELECTOR (sel->vectors));
if (!doc)
return;
- SPGradient *gr = sp_gradient_vector_selector_get_gradient(
- SP_GRADIENT_VECTOR_SELECTOR (sel->vectors));
+ SPGradient *gr = sp_gradient_vector_selector_get_gradient( SP_GRADIENT_VECTOR_SELECTOR (sel->vectors));
Inkscape::XML::Document *xml_doc = doc->getReprDoc();
Inkscape::XML::Node *repr = NULL;
@@ -367,18 +492,18 @@ sp_gradient_selector_add_vector_clicked (GtkWidget */*w*/, SPGradientSelector *s
doc->getDefs()->getRepr()->addChild(repr, NULL);
- gr = static_cast<SPGradient *>(doc->getObjectByRepr(repr));
- sp_gradient_vector_selector_set_gradient(
- SP_GRADIENT_VECTOR_SELECTOR (sel->vectors), doc, gr);
+ Glib::ustring old_id = gr->getId();
- Inkscape::GC::release(repr);
-}
+ gr = (SPGradient *) doc->getObjectByRepr(repr);
-static void
-sp_gradient_selector_spread_changed (GtkComboBox *widget, SPGradientSelector *sel)
-{
- sel->gradientSpread = (SPGradientSpread) gtk_combo_box_get_active (GTK_COMBO_BOX(widget));
- g_signal_emit (G_OBJECT (sel), signals[CHANGED], 0);
+ // Rename the new gradients id to be similar to the cloned gradients
+ rename_id(gr, old_id);
+
+ sp_gradient_vector_selector_set_gradient( SP_GRADIENT_VECTOR_SELECTOR (sel->vectors), doc, gr);
+
+ sel->selectGradientInTree(gr);
+
+ Inkscape::GC::release(repr);
}
/*
diff --git a/src/widgets/gradient-selector.h b/src/widgets/gradient-selector.h
index d957f7baf..f7cc3cc14 100644
--- a/src/widgets/gradient-selector.h
+++ b/src/widgets/gradient-selector.h
@@ -17,10 +17,19 @@
#include <glib.h>
#include <gtk/gtk.h>
+
+#include <gtkmm/entry.h>
+#include <gtkmm/label.h>
+#include <gtkmm/table.h>
+#include <gtkmm/liststore.h>
+#include <gtkmm/treeview.h>
+#include <gtkmm/scrolledwindow.h>
+
#include <vector>
#include "sp-gradient.h"
#include "sp-gradient-spread.h"
#include "sp-gradient-units.h"
+#include "gradient-image.h"
class SPGradient;
@@ -49,24 +58,61 @@ struct SPGradientSelector {
/* Vector selector */
GtkWidget *vectors;
+ /* Tree */
+ bool _checkForSelected(const Gtk::TreePath& path, const Gtk::TreeIter& iter, SPGradient *vector);
+ void onTreeSelection();
+ void onTreeEdited( const Glib::ustring& path_string, const Glib::ustring& new_text);
+ void onTreeNameColClick();
+ void onTreeColorColClick();
+ void onTreeCountColClick();
+
+ Gtk::TreeView *treeview;
+ Gtk::ScrolledWindow *scrolled_window;
+ class ModelColumns : public Gtk::TreeModel::ColumnRecord
+ {
+ public:
+ ModelColumns()
+ {
+ add(name);
+ add(refcount);
+ add(color);
+ add(data);
+ add(pixbuf);
+ }
+ virtual ~ModelColumns() {}
+
+ Gtk::TreeModelColumn<Glib::ustring> name;
+ Gtk::TreeModelColumn<unsigned long> color;
+ Gtk::TreeModelColumn<gint> refcount;
+ Gtk::TreeModelColumn<SPGradient*> data;
+ Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf> > pixbuf;
+
+ };
+
+ ModelColumns *columns;
+ Glib::RefPtr<Gtk::ListStore> store;
+ Gtk::CellRendererPixbuf* icon_renderer;
+ Gtk::CellRendererText* text_renderer;
+
/* Editing buttons */
GtkWidget *edit;
GtkWidget *add;
+ GtkWidget *merge;
/* Position widget */
GtkWidget *position;
- /* Spread selector */
- GtkWidget *spread;
- GtkWidget *spreadLbl;
-
bool safelyInit;
+ bool blocked;
+
std::vector<GtkWidget*> nonsolid;
void setMode(SelectorMode mode);
void setUnits(SPGradientUnits units);
void setSpread(SPGradientSpread spread);
void setVector(SPDocument *doc, SPGradient *vector);
+ void selectGradientInTree(SPGradient *vector);
+
SPGradientUnits getUnits();
SPGradientSpread getSpread();
SPGradient *getVector();
diff --git a/src/widgets/gradient-vector.cpp b/src/widgets/gradient-vector.cpp
index c875ab61c..db8c76b9b 100644
--- a/src/widgets/gradient-vector.cpp
+++ b/src/widgets/gradient-vector.cpp
@@ -30,11 +30,13 @@
#include <gtk/gtk.h>
#include "macros.h"
#include <glibmm/i18n.h>
+#include <set>
#include "../widgets/gradient-image.h"
#include "../inkscape.h"
#include "../document-private.h"
#include "../gradient-chemistry.h"
#include "../helper/window.h"
+#include "io/resource.h"
#include "xml/repr.h"
@@ -42,6 +44,12 @@
#include "../preferences.h"
#include "svg/css-ostringstream.h"
#include "sp-stop.h"
+#include "selection-chemistry.h"
+#include "style.h"
+#include "sp-linear-gradient.h"
+#include "sp-radial-gradient.h"
+#include "desktop.h"
+#include "layer-manager.h"
#include <sigc++/functors/ptr_fun.h>
#include <sigc++/adaptors/bind.h>
@@ -68,8 +76,9 @@ static void sp_gvs_defs_release(SPObject *defs, SPGradientVectorSelector *gvs);
static void sp_gvs_defs_modified(SPObject *defs, guint flags, SPGradientVectorSelector *gvs);
static void sp_gvs_rebuild_gui_full(SPGradientVectorSelector *gvs);
-static void gr_combo_box_changed (GtkComboBox *widget, SPGradientVectorSelector *gvs);
static SPStop *get_selected_stop( GtkWidget *vb);
+void gr_get_usage_counts(SPDocument *doc, std::map<SPGradient *, gint> *mapUsageCount );
+unsigned long sp_gradient_to_hhssll(SPGradient *gr);
static GtkVBoxClass *parent_class;
static guint signals[LAST_SIGNAL] = {0};
@@ -141,22 +150,9 @@ static void sp_gradient_vector_selector_init(SPGradientVectorSelector *gvs)
new (&gvs->defs_release_connection) sigc::connection();
new (&gvs->defs_modified_connection) sigc::connection();
- gvs->store = gtk_list_store_new (3, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_POINTER);
- gvs->combo_box = gtk_combo_box_new_with_model (GTK_TREE_MODEL (gvs->store));
- gvs->combo_connection = g_signal_connect (G_OBJECT (gvs->combo_box), "changed", G_CALLBACK (gr_combo_box_changed), gvs);
-
- GtkCellRenderer *renderer = gtk_cell_renderer_pixbuf_new ();
- gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (gvs->combo_box), renderer, FALSE);
- gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (gvs->combo_box), renderer, "pixbuf", 0, NULL);
- gtk_cell_renderer_set_padding(renderer, 5, 0);
-
- renderer = gtk_cell_renderer_text_new ();
- gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (gvs->combo_box), renderer, TRUE);
- gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (gvs->combo_box), renderer, "text", 1, NULL);
- gtk_cell_renderer_set_padding(renderer, 0, 0);
-
- gtk_widget_show(gvs->combo_box);
- gtk_box_pack_start(GTK_BOX(gvs), gvs->combo_box, TRUE, TRUE, 0);
+ gvs->columns = new SPGradientSelector::ModelColumns();
+ gvs->store = Gtk::ListStore::create(*gvs->columns);
+ new (&gvs->tree_select_connection) sigc::connection();
}
@@ -170,6 +166,7 @@ static void sp_gradient_vector_selector_destroy(GtkObject *object)
if (gvs->gr) {
gvs->gradient_release_connection.disconnect();
+ gvs->tree_select_connection.disconnect();
gvs->gr = NULL;
}
@@ -182,6 +179,7 @@ static void sp_gradient_vector_selector_destroy(GtkObject *object)
gvs->gradient_release_connection.~connection();
gvs->defs_release_connection.~connection();
gvs->defs_modified_connection.~connection();
+ gvs->tree_select_connection.~connection();
#if GTK_CHECK_VERSION(3,0,0)
if ((reinterpret_cast<GtkWidgetClass *>(parent_class))->destroy) {
@@ -281,9 +279,13 @@ SPGradient *sp_gradient_vector_selector_get_gradient(SPGradientVectorSelector *g
Glib::ustring gr_prepare_label (SPObject *obj)
{
- const gchar *id = obj->defaultLabel();
- if (strlen(id) > 15 && (!strncmp (id, "#linearGradient", 15) || !strncmp (id, "#radialGradient", 15)))
- return gr_ellipsize_text (g_strdup_printf ("#%s", id+15), 35);
+ const gchar *id = obj->label() ? obj->label() : obj->getId();
+ if (!id) {
+ id = obj->getRepr()->name();
+ }
+
+ if (strlen(id) > 14 && (!strncmp (id, "linearGradient", 14) || !strncmp (id, "radialGradient", 14)))
+ return gr_ellipsize_text (g_strdup_printf ("%s", id+14), 35);
return gr_ellipsize_text (id, 35);
}
@@ -303,9 +305,11 @@ Glib::ustring gr_ellipsize_text(Glib::ustring const &src, size_t maxlen)
static void sp_gvs_rebuild_gui_full(SPGradientVectorSelector *gvs)
{
+
+ gvs->tree_select_connection.block();
+
/* Clear old list, if there is any */
- gtk_list_store_clear(gvs->store);
- GtkTreeIter iter;
+ gvs->store->clear();
/* Pick up all gradients with vectors */
GSList *gl = NULL;
@@ -320,102 +324,124 @@ static void sp_gvs_rebuild_gui_full(SPGradientVectorSelector *gvs)
}
gl = g_slist_reverse(gl);
- gint pos = 0;
+ /* Get usage count of all the gradients */
+ std::map<SPGradient *, gint> usageCount;
+ gr_get_usage_counts(gvs->doc, &usageCount);
if (!gvs->doc) {
- gtk_list_store_append (gvs->store, &iter);
- gtk_list_store_set (gvs->store, &iter, 0, NULL, 1, _("No document selected"), 2, NULL, -1);
- gtk_widget_set_sensitive (gvs->combo_box, FALSE);
+ Gtk::TreeModel::Row row = *(gvs->store->append());
+ row[gvs->columns->name] = _("No document selected");
} else if (!gl) {
- gtk_list_store_append (gvs->store, &iter);
- gtk_list_store_set (gvs->store, &iter, 0, NULL, 1, _("No gradients in document"), 2, NULL, -1);
- gtk_widget_set_sensitive (gvs->combo_box, FALSE);
+ Gtk::TreeModel::Row row = *(gvs->store->append());
+ row[gvs->columns->name] = _("No gradients in document");
} else if (!gvs->gr) {
- gtk_list_store_append (gvs->store, &iter);
- gtk_list_store_set (gvs->store, &iter, 0, NULL, 1, _("No gradient selected"), 2, NULL, -1);
- gtk_widget_set_sensitive (gvs->combo_box, FALSE);
+ Gtk::TreeModel::Row row = *(gvs->store->append());
+ row[gvs->columns->name] = _("No gradient selected");
} else {
- gint idx = 0;
while (gl) {
SPGradient *gr;
gr = SP_GRADIENT(gl->data);
gl = g_slist_remove(gl, gr);
- /* We have to know: */
- /* Gradient destroy */
- /* Gradient name change */
-
- Glib::ustring label = gr_prepare_label(gr);
+ unsigned long hhssll = sp_gradient_to_hhssll(gr);
GdkPixbuf *pixb = sp_gradient_to_pixbuf (gr, 64, 18);
- gtk_list_store_append (gvs->store, &iter);
- gtk_list_store_set (gvs->store, &iter, 0, pixb, 1, label.c_str(), 2, gr, -1);
+ Glib::ustring label = gr_prepare_label(gr);
+
+ Gtk::TreeModel::Row row = *(gvs->store->append());
+ row[gvs->columns->name] = label.c_str();
+ row[gvs->columns->color] = hhssll;
+ row[gvs->columns->refcount] = usageCount[gr];
+ row[gvs->columns->data] = gr;
+ row[gvs->columns->pixbuf] = Glib::wrap(pixb);
- if (gr == gvs->gr) {
- pos = idx;
- }
- idx += 1;
}
- gtk_widget_set_sensitive (gvs->combo_box, TRUE);
}
- /* Block signal to prevent recursive loop */
- g_signal_handler_block(G_OBJECT (gvs->combo_box), gvs->combo_connection);
+ gvs->tree_select_connection.unblock();
- /* Set selected */
- gtk_combo_box_set_active (GTK_COMBO_BOX(gvs->combo_box) , pos);
+}
+
+/*
+ * Return a "HHSSLL" version of the first stop color so we can sort by it
+ */
+unsigned long sp_gradient_to_hhssll(SPGradient *gr)
+{
+ SPStop *stop = gr->getFirstStop();
+ unsigned long rgba = sp_stop_get_rgba32(stop);
+ float hsl[3];
+ sp_color_rgb_to_hsl_floatv (hsl, SP_RGBA32_R_F(rgba), SP_RGBA32_G_F(rgba), SP_RGBA32_B_F(rgba));
- g_signal_handler_unblock(G_OBJECT (gvs->combo_box), gvs->combo_connection);
+ return ((int)(hsl[0]*100 * 10000)) + ((int)(hsl[1]*100 * 100)) + ((int)(hsl[2]*100 * 1));
}
-static void gr_combo_box_changed (GtkComboBox *widget, SPGradientVectorSelector *gvs)
+GSList *get_all_doc_items(GSList *list, SPObject *from, bool onlyvisible, bool onlysensitive, bool ingroups, GSList const *exclude)
{
- GtkTreeIter iter;
- if (!gtk_combo_box_get_active_iter (widget, &iter)) {
- return;
+ for ( SPObject *child = from->firstChild() ; child; child = child->getNext() ) {
+ if (SP_IS_ITEM(child)) {
+ list = g_slist_prepend(list, SP_ITEM(child));
+ }
+
+ if (ingroups || SP_IS_ITEM(child)) {
+ list = get_all_doc_items(list, child, onlyvisible, onlysensitive, ingroups, exclude);
+ }
}
- SPGradient *gr = NULL;
- gtk_tree_model_get (GTK_TREE_MODEL(gvs->store), &iter, 2, &gr, -1);
+ return list;
+}
- if (gr) {
+/*
+ * Return a SPItem's gradient
+ */
+static SPGradient * gr_item_get_gradient(SPItem *item, gboolean fillorstroke)
+{
+ SPIPaint *item_paint = (fillorstroke) ? &(item->style->fill) : &(item->style->stroke);
+ if (item_paint->isPaintserver()) {
- SPGradient *norm = sp_gradient_ensure_vector_normalized(gr);
- if (norm != gr) {
- //g_print("SPGradientVectorSelector: become %s after normalization\n", norm->getId());
- /* But be careful that we do not have gradient saved anywhere else */
- //g_object_set_data(G_OBJECT(mi), "gradient", norm);
- gtk_list_store_set (gvs->store, &iter, 2, norm, -1);
- }
+ SPPaintServer *item_server = (fillorstroke) ?
+ item->style->getFillPaintServer() : item->style->getStrokePaintServer();
- /* fixme: Really we would want to use _set_vector */
- /* Detach old */
- if (gvs->gr) {
- gvs->gradient_release_connection.disconnect();
- gvs->gr = NULL;
- }
- /* Attach new */
- if (norm) {
- gvs->gradient_release_connection = norm->connectRelease(sigc::bind<1>(sigc::ptr_fun(&sp_gvs_gradient_release), gvs));
- gvs->gr = norm;
+ if (SP_IS_LINEARGRADIENT(item_server) || SP_IS_RADIALGRADIENT(item_server) ||
+ (SP_IS_GRADIENT(item_server) && SP_GRADIENT(item_server)->getVector()->isSwatch())) {
+
+ return SP_GRADIENT(item_server)->getVector();
}
+ }
- g_signal_emit(G_OBJECT(gvs), signals[VECTOR_SET], 0, norm);
+ return NULL;
+}
- if (norm != gr) {
- /* We do extra undo push here */
- /* If handler has already done it, it is just NOP */
- // FIXME: looks like this is never a valid undo step, consider removing this
- DocumentUndo::done(norm->document, SP_VERB_CONTEXT_GRADIENT,
- /* TODO: annotate */ "gradient-vector.cpp:350");
- }
+/*
+ * Map each gradient to its usage count for both fill and stroke styles
+ */
+void gr_get_usage_counts(SPDocument *doc, std::map<SPGradient *, gint> *mapUsageCount )
+{
+ if (!doc)
+ return;
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ bool onlyvisible = prefs->getBool("/options/kbselection/onlyvisible", true);
+ bool onlysensitive = prefs->getBool("/options/kbselection/onlysensitive", true);
+ bool ingroups = TRUE;
+ GSList *all_list = get_all_doc_items(NULL, doc->getRoot(), onlyvisible, onlysensitive, ingroups, NULL);
+ for (GSList *i = all_list; i != NULL; i = i->next) {
+ SPItem *item = SP_ITEM(i->data);
+ SPGradient *gr = NULL;
+ gr = gr_item_get_gradient(item, true); // fill
+ if (gr) {
+ mapUsageCount->count(gr) > 0 ? (*mapUsageCount)[gr] += 1 : (*mapUsageCount)[gr] = 1;
+ }
+ gr = gr_item_get_gradient(item, false); // stroke
+ if (gr) {
+ mapUsageCount->count(gr) > 0 ? (*mapUsageCount)[gr] += 1 : (*mapUsageCount)[gr] = 1;
+ }
}
}
+
static void sp_gvs_gradient_release(SPObject */*obj*/, SPGradientVectorSelector *gvs)
{
/* Disconnect gradient */
@@ -448,7 +474,6 @@ static void sp_gvs_defs_release(SPObject */*defs*/, SPGradientVectorSelector *gv
static void sp_gvs_defs_modified(SPObject */*defs*/, guint /*flags*/, SPGradientVectorSelector *gvs)
{
/* fixme: We probably have to check some flags here (Lauris) */
-
sp_gvs_rebuild_gui_full(gvs);
}
diff --git a/src/widgets/gradient-vector.h b/src/widgets/gradient-vector.h
index 9a26ab046..1ed6c6c46 100644
--- a/src/widgets/gradient-vector.h
+++ b/src/widgets/gradient-vector.h
@@ -16,11 +16,13 @@
*/
#include <glib.h>
+#include <gtkmm/liststore.h>
#include <stddef.h>
#include <sigc++/connection.h>
#include <gtk/gtk.h>
+#include "gradient-selector.h"
#define SP_TYPE_GRADIENT_VECTOR_SELECTOR (sp_gradient_vector_selector_get_type ())
#define SP_GRADIENT_VECTOR_SELECTOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SP_TYPE_GRADIENT_VECTOR_SELECTOR, SPGradientVectorSelector))
@@ -43,16 +45,14 @@ struct SPGradientVectorSelector {
SPDocument *doc;
SPGradient *gr;
- /* ComboBox of gradient vectors */
- GtkWidget *combo_box;
- GtkListStore *store;
+ /* Gradient vectors store */
+ Glib::RefPtr<Gtk::ListStore> store;
+ SPGradientSelector::ModelColumns *columns;
sigc::connection gradient_release_connection;
sigc::connection defs_release_connection;
sigc::connection defs_modified_connection;
-
- gulong combo_connection;
-
+ sigc::connection tree_select_connection;
void setSwatched();
};
diff --git a/src/widgets/swatch-selector.cpp b/src/widgets/swatch-selector.cpp
index 5de71c95e..524072cf0 100644
--- a/src/widgets/swatch-selector.cpp
+++ b/src/widgets/swatch-selector.cpp
@@ -182,7 +182,7 @@ void SwatchSelector::setVector(SPDocument */*doc*/, SPGradient *vector)
_csel->base->setColor( color );
gtk_widget_show_all( GTK_WIDGET(_csel) );
} else {
- gtk_widget_hide( GTK_WIDGET(_csel) );
+ //gtk_widget_hide( GTK_WIDGET(_csel) );
}
/*