diff options
Diffstat (limited to 'src/widgets/gradient-selector.cpp')
| -rw-r--r-- | src/widgets/gradient-selector.cpp | 293 |
1 files changed, 209 insertions, 84 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); } /* |
