diff options
Diffstat (limited to 'src/widgets/gradient-toolbar.cpp')
| -rw-r--r-- | src/widgets/gradient-toolbar.cpp | 1275 |
1 files changed, 0 insertions, 1275 deletions
diff --git a/src/widgets/gradient-toolbar.cpp b/src/widgets/gradient-toolbar.cpp deleted file mode 100644 index 910142bfb..000000000 --- a/src/widgets/gradient-toolbar.cpp +++ /dev/null @@ -1,1275 +0,0 @@ -/* - * Gradient aux toolbar - * - * Authors: - * bulia byak <bulia@dr.com> - * Johan Engelen <j.b.c.engelen@ewi.utwente.nl> - * Abhishek Sharma - * - * Copyright (C) 2007 Johan Engelen - * Copyright (C) 2005 authors - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <glibmm/i18n.h> - - -#include "desktop.h" -#include "document-undo.h" -#include "document.h" -#include "gradient-chemistry.h" -#include "gradient-drag.h" -#include "gradient-toolbar.h" -#include "ink-action.h" -#include "ink-radio-action.h" -#include "ink-toggle-action.h" -#include "macros.h" -#include "selection.h" -#include "toolbox.h" -#include "verbs.h" - -#include "object/sp-defs.h" -#include "object/sp-linear-gradient.h" -#include "object/sp-radial-gradient.h" -#include "object/sp-stop.h" -#include "style.h" - -#include "ui/icon-names.h" -#include "ui/tools/gradient-tool.h" -#include "ui/util.h" -#include "ui/widget/color-preview.h" -#include "ui/widget/ink-select-one-action.h" - -#include "widgets/ege-adjustment-action.h" -#include "widgets/gradient-image.h" -#include "widgets/gradient-vector.h" - -using Inkscape::DocumentUndo; -using Inkscape::UI::ToolboxFactory; -using Inkscape::UI::Tools::ToolBase; - -static bool blocked = false; - -//######################## -//## Gradient ## -//######################## - -void gr_apply_gradient_to_item( SPItem *item, SPGradient *gr, SPGradientType initialType, Inkscape::PaintTarget initialMode, Inkscape::PaintTarget mode ) -{ - SPStyle *style = item->style; - bool isFill = (mode == Inkscape::FOR_FILL); - if (style - && (isFill ? style->fill.isPaintserver() : style->stroke.isPaintserver()) - //&& SP_IS_GRADIENT(isFill ? style->getFillPaintServer() : style->getStrokePaintServer()) ) { - && (isFill ? SP_IS_GRADIENT(style->getFillPaintServer()) : SP_IS_GRADIENT(style->getStrokePaintServer())) ) { - SPPaintServer *server = isFill ? style->getFillPaintServer() : style->getStrokePaintServer(); - if ( SP_IS_LINEARGRADIENT(server) ) { - sp_item_set_gradient(item, gr, SP_GRADIENT_TYPE_LINEAR, mode); - } else if ( SP_IS_RADIALGRADIENT(server) ) { - sp_item_set_gradient(item, gr, SP_GRADIENT_TYPE_RADIAL, mode); - } - } - else if (initialMode == mode) - { - sp_item_set_gradient(item, gr, initialType, mode); - } -} - -/** -Applies gradient vector gr to the gradients attached to the selected dragger of drag, or if none, -to all objects in selection. If there was no previous gradient on an item, uses gradient type and -fill/stroke setting from preferences to create new default (linear: left/right; radial: centered) -gradient. -*/ -void gr_apply_gradient(Inkscape::Selection *selection, GrDrag *drag, SPGradient *gr) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - SPGradientType initialType = static_cast<SPGradientType>(prefs->getInt("/tools/gradient/newgradient", SP_GRADIENT_TYPE_LINEAR)); - Inkscape::PaintTarget initialMode = (prefs->getInt("/tools/gradient/newfillorstroke", 1) != 0) ? Inkscape::FOR_FILL : Inkscape::FOR_STROKE; - - // GRADIENTFIXME: make this work for multiple selected draggers. - - // First try selected dragger - if (drag && !drag->selected.empty()) { - GrDragger *dragger = *(drag->selected.begin()); - for(std::vector<GrDraggable *>::const_iterator i = dragger->draggables.begin(); i != dragger->draggables.end(); ++i) { //for all draggables of dragger - GrDraggable *draggable = *i; - gr_apply_gradient_to_item(draggable->item, gr, initialType, initialMode, draggable->fill_or_stroke); - } - return; - } - - // If no drag or no dragger selected, act on selection - auto itemlist= selection->items(); - for(auto i=itemlist.begin();i!=itemlist.end();++i){ - gr_apply_gradient_to_item(*i, gr, initialType, initialMode, initialMode); - } -} - -int gr_vector_list(Glib::RefPtr<Gtk::ListStore> store, SPDesktop *desktop, - bool selection_empty, SPGradient *gr_selected, bool gr_multi) -{ - int selected = -1; - - if (!blocked) { - std::cerr << "gr_vector_list: should be blocked!" << std::endl; - } - - // Get list of gradients in document. - SPDocument *document = desktop->getDocument(); - std::vector<SPObject *> gl; - std::vector<SPObject *> gradients = document->getResourceList( "gradient" ); - for (std::vector<SPObject *>::const_iterator it = gradients.begin(); it != gradients.end(); ++it) { - SPGradient *grad = SP_GRADIENT(*it); - if ( grad->hasStops() && !grad->isSolid() ) { - gl.push_back(*it); - } - } - - store->clear(); - - InkSelectOneActionColumns columns; - Gtk::TreeModel::Row row; - - if (gl.empty()) { - // The document has no gradients - - row = *(store->append()); - row[columns.col_label ] = _("No gradient"); - row[columns.col_tooltip ] = ""; - row[columns.col_icon ] = "NotUsed"; - row[columns.col_data ] = nullptr; - row[columns.col_sensitive] = true; - - } else if (selection_empty) { - // Document has gradients, but nothing is currently selected. - - row = *(store->append()); - row[columns.col_label ] = _("Nothing Selected"); - row[columns.col_tooltip ] = ""; - row[columns.col_icon ] = "NotUsed"; - row[columns.col_data ] = nullptr; - row[columns.col_sensitive] = true; - - } else { - - if (gr_selected == NULL) { - row = *(store->append()); - row[columns.col_label ] = _("No gradient"); - row[columns.col_tooltip ] = ""; - row[columns.col_icon ] = "NotUsed"; - row[columns.col_data ] = nullptr; - row[columns.col_sensitive] = true; - } - - if (gr_multi) { - row = *(store->append()); - row[columns.col_label ] = _("Multiple gradients"); - row[columns.col_tooltip ] = ""; - row[columns.col_icon ] = "NotUsed"; - row[columns.col_data ] = nullptr; - row[columns.col_sensitive] = true; - } - - int idx = 0; - for (std::vector<SPObject *>::const_iterator it = gl.begin(); it != gl.end(); ++it) { - SPGradient *gradient = SP_GRADIENT(*it); - - Glib::ustring label = gr_prepare_label(gradient); - Glib::RefPtr<Gdk::Pixbuf> pixbuf = sp_gradient_to_pixbuf_ref(gradient, 64, 16); - - row = *(store->append()); - row[columns.col_label ] = label; - row[columns.col_tooltip ] = ""; - row[columns.col_icon ] = "NotUsed"; - row[columns.col_pixbuf ] = pixbuf; - row[columns.col_data ] = gradient; - row[columns.col_sensitive] = true; - - if (gradient == gr_selected) { - selected = idx; - } - idx ++; - } - - if (gr_multi) { - selected = 0; // This will show "Multiple Gradients" - } - } - - return selected; -} - -/* - * Get the gradient of the selected desktop item - * This is gradient containing the repeat settings, not the underlying "getVector" href linked gradient. - */ -void gr_get_dt_selected_gradient(Inkscape::Selection *selection, SPGradient *&gr_selected) -{ - SPGradient *gradient = 0; - - auto itemlist= selection->items(); - for(auto i=itemlist.begin();i!=itemlist.end();++i){ - SPItem *item = *i;// get the items gradient, not the getVector() version - SPStyle *style = item->style; - SPPaintServer *server = 0; - - if (style && (style->fill.isPaintserver())) { - server = item->style->getFillPaintServer(); - } - if (style && (style->stroke.isPaintserver())) { - server = item->style->getStrokePaintServer(); - } - - if ( SP_IS_GRADIENT(server) ) { - gradient = SP_GRADIENT(server); - } - } - - if (gradient && gradient->isSolid()) { - gradient = 0; - } - - if (gradient) { - gr_selected = gradient; - } -} - -/* - * Get the current selection and dragger status from the desktop - */ -void gr_read_selection( Inkscape::Selection *selection, - GrDrag *drag, - SPGradient *&gr_selected, - bool &gr_multi, - SPGradientSpread &spr_selected, - bool &spr_multi ) -{ - if (drag && !drag->selected.empty()) { - // GRADIENTFIXME: make this work for more than one selected dragger? - GrDragger *dragger = *(drag->selected.begin()); - for(std::vector<GrDraggable *>::const_iterator i = dragger->draggables.begin(); i != dragger->draggables.end(); ++i) { //for all draggables of dragger - GrDraggable *draggable = *i; - SPGradient *gradient = sp_item_gradient_get_vector(draggable->item, draggable->fill_or_stroke); - SPGradientSpread spread = sp_item_gradient_get_spread(draggable->item, draggable->fill_or_stroke); - - if (gradient && gradient->isSolid()) { - gradient = 0; - } - - if (gradient && (gradient != gr_selected)) { - if (gr_selected) { - gr_multi = true; - } else { - gr_selected = gradient; - } - } - if (spread != spr_selected) { - if (spr_selected != SP_GRADIENT_SPREAD_UNDEFINED) { - spr_multi = true; - } else { - spr_selected = spread; - } - } - } - return; - } - - // If no selected dragger, read desktop selection - auto itemlist= selection->items(); - for(auto i=itemlist.begin();i!=itemlist.end();++i){ - SPItem *item = *i; - SPStyle *style = item->style; - - if (style && (style->fill.isPaintserver())) { - SPPaintServer *server = item->style->getFillPaintServer(); - if ( SP_IS_GRADIENT(server) ) { - SPGradient *gradient = SP_GRADIENT(server)->getVector(); - SPGradientSpread spread = SP_GRADIENT(server)->fetchSpread(); - - if (gradient && gradient->isSolid()) { - gradient = 0; - } - - if (gradient && (gradient != gr_selected)) { - if (gr_selected) { - gr_multi = true; - } else { - gr_selected = gradient; - } - } - if (spread != spr_selected) { - if (spr_selected != SP_GRADIENT_SPREAD_UNDEFINED) { - spr_multi = true; - } else { - spr_selected = spread; - } - } - } - } - if (style && (style->stroke.isPaintserver())) { - SPPaintServer *server = item->style->getStrokePaintServer(); - if ( SP_IS_GRADIENT(server) ) { - SPGradient *gradient = SP_GRADIENT(server)->getVector(); - SPGradientSpread spread = SP_GRADIENT(server)->fetchSpread(); - - if (gradient && gradient->isSolid()) { - gradient = 0; - } - - if (gradient && (gradient != gr_selected)) { - if (gr_selected) { - gr_multi = true; - } else { - gr_selected = gradient; - } - } - if (spread != spr_selected) { - if (spr_selected != SP_GRADIENT_SPREAD_UNDEFINED) { - spr_multi = true; - } else { - spr_selected = spread; - } - } - } - } - } - } - -/* Get stop selected by menu */ -static SPStop *get_selected_stop( GObject *data) -{ - InkSelectOneAction *act = - static_cast<InkSelectOneAction *>(g_object_get_data(data, "gradient_stop_action")); - - int active = act->get_active(); - - Glib::RefPtr<Gtk::ListStore> store = act->get_store(); - Gtk::TreeModel::Row row = store->children()[active]; - InkSelectOneActionColumns columns; - void* pointer = row[columns.col_data]; - SPStop *stop = static_cast<SPStop *>(pointer); - - return stop; -} - -/* Add stop to gradient */ -static void gr_add_stop(GtkWidget * /*button*/, GObject *data) -{ - SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data(data, "desktop")); - if (!desktop) { - return; - } - - Inkscape::Selection *selection = desktop->getSelection(); - if (!selection) { - return; - } - - ToolBase *ev = desktop->getEventContext(); - Inkscape::UI::Tools::GradientTool *rc = SP_GRADIENT_CONTEXT(ev); - - if (rc) { - sp_gradient_context_add_stops_between_selected_stops(rc); - } - -} - -/* Remove stop from vector */ -static void gr_remove_stop(GtkWidget * /*button*/, GObject *data) -{ - - SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data(data, "desktop")); - if (!desktop) { - return; - } - - Inkscape::Selection *selection = desktop->getSelection(); // take from desktop, not from args - if (!selection) { - return; - } - - ToolBase *ev = desktop->getEventContext(); - GrDrag *drag = NULL; - if (ev) { - drag = ev->get_drag(); - } - - if (drag) { - drag->deleteSelected(); - } - -} - -/* Lock or unlock links */ -static void gr_linked_changed(GtkToggleAction *act, gpointer /*data*/) -{ - gboolean active = gtk_toggle_action_get_active( act ); - if ( active ) { - g_object_set( G_OBJECT(act), "iconId", INKSCAPE_ICON("object-locked"), NULL ); - } else { - g_object_set( G_OBJECT(act), "iconId", INKSCAPE_ICON("object-unlocked"), NULL ); - } - - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setBool("/options/forkgradientvectors/value", !active); -} - -/* Reverse vector */ -static void gr_reverse(GtkWidget * /*button*/, gpointer data) -{ - SPDesktop *desktop = static_cast<SPDesktop *>(data); - sp_gradient_reverse_selected_gradients(desktop); -} - -/* - * Change desktop dragger selection to this stop - */ -/* Set the offset widget value (based on which stop is selected). */ -static void gr_stop_set_offset (GObject *data) -{ - if (!blocked) { - std::cerr << "gr_stop_set_offset: should be blocked!" << std::endl; - } - - SPStop *stop = get_selected_stop(data); - if (!stop) { - // std::cerr << "gr_stop_set_offset: no stop!" << std::endl; - return; - } - - EgeAdjustmentAction* act = (EgeAdjustmentAction *)g_object_get_data( data, "offset_action"); - if (!act) { - return; - } - GtkAdjustment *adj = ege_adjustment_action_get_adjustment(act); - - bool isEndStop = false; - - SPStop *prev = NULL; - prev = stop->getPrevStop(); - if (prev != NULL ) { - gtk_adjustment_set_lower(adj, prev->offset); - } else { - isEndStop = true; - gtk_adjustment_set_lower(adj, 0); - } - - SPStop *next = NULL; - next = stop->getNextStop(); - if (next != NULL ) { - gtk_adjustment_set_upper(adj, next->offset); - } else { - isEndStop = true; - gtk_adjustment_set_upper(adj, 1.0); - } - - gtk_adjustment_set_value(adj, stop->offset); - gtk_action_set_sensitive( GTK_ACTION(act), !isEndStop ); - gtk_adjustment_changed(adj); -} - -static void select_dragger_by_stop( GObject *data, SPGradient *gradient, ToolBase *ev) -{ - if (!blocked) { - std::cerr << "select_dragger_by_stop: should be blocked!" << std::endl; - } - - if (!ev || !gradient) { - return; - } - - GrDrag *drag = ev->get_drag(); - if (!drag) { - return; - } - - SPStop *stop = get_selected_stop(data); - - drag->selectByStop(stop, false, true); - - gr_stop_set_offset(data); -} - -/* Find position of new_stop in menu. */ -static int select_stop_in_list (SPGradient *gradient, SPStop *new_stop, GObject *data) -{ - int i = 0; - for (auto& ochild: gradient->children) { - if (SP_IS_STOP(&ochild)) { - if (&ochild == new_stop) { - return i; - } - i++; - } - } - return -1; -} - -/* Construct stop list */ -static int update_stop_list( SPGradient *gradient, SPStop *new_stop, GObject *data, bool gr_multi) -{ - if (!blocked) { - std::cerr << "update_stop_list should be blocked!" << std::endl; - } - - int selected = -1; - - auto act = static_cast<InkSelectOneAction*>(g_object_get_data(data, "gradient_stop_action")); - Glib::RefPtr<Gtk::ListStore> store = act->get_store(); - - if (!store) { - return selected; - } - - store->clear(); - - InkSelectOneActionColumns columns; - Gtk::TreeModel::Row row; - - if (!SP_IS_GRADIENT(gradient)) { - // No valid gradient - - row = *(store->append()); - row[columns.col_label ] = _("No gradient"); - row[columns.col_tooltip ] = ""; - row[columns.col_icon ] = "NotUsed"; - row[columns.col_data ] = nullptr; - row[columns.col_sensitive] = true; - - } else if (!gradient->hasStops()) { - // Has gradient but it has no stops - - row = *(store->append()); - row[columns.col_label ] = _("No stops in gradient"); - row[columns.col_tooltip ] = ""; - row[columns.col_icon ] = "NotUsed"; - row[columns.col_data ] = nullptr; - row[columns.col_sensitive] = true; - - } else { - // Gradient has stops - - // Get list of stops - for (auto& ochild: gradient->children) { - if (SP_IS_STOP(&ochild)) { - - SPStop *stop = SP_STOP(&ochild); - Glib::RefPtr<Gdk::Pixbuf> pixbuf = sp_gradstop_to_pixbuf_ref (stop, 32, 16); - - Inkscape::XML::Node *repr = reinterpret_cast<SPItem *>(&ochild)->getRepr(); - Glib::ustring label = gr_ellipsize_text(repr->attribute("id"), 25); - - row = *(store->append()); - row[columns.col_label ] = label; - row[columns.col_tooltip ] = ""; - row[columns.col_icon ] = "NotUsed"; - row[columns.col_pixbuf ] = pixbuf; - row[columns.col_data ] = stop; - row[columns.col_sensitive] = true; - } - } - } - - if (new_stop != nullptr) { - selected = select_stop_in_list (gradient, new_stop, data); - } - - return selected; -} - -/* Set stop in menu to match stops selected by draggers. */ -static void select_stop_by_draggers(SPGradient *gradient, ToolBase *ev, GObject *data) -{ - if (!blocked) { - std::cerr << "select_stop_by_draggers should be blocked!" << std::endl; - } - - if (!ev || !gradient) - return; - - SPGradient *vector = gradient->getVector(); - if (!vector) - return; - - InkSelectOneAction *act = - static_cast<InkSelectOneAction *>(g_object_get_data(data, "gradient_stop_action")); - - GrDrag *drag = ev->get_drag(); - - if (!drag || drag->selected.empty()) { - act->set_active(0); - gr_stop_set_offset(data); - return; - } - - gint n = 0; - SPStop *stop = nullptr; - int selected = -1; - - // For all selected draggers - for(auto i = drag->selected.begin(); i != drag->selected.end(); ++i) { - - GrDragger *dragger = *i; - - // For all draggables of dragger - for(auto j = dragger->draggables.begin(); j != dragger->draggables.end(); ++j) { - - GrDraggable *draggable = *j; - - if (draggable->point_type != POINT_RG_FOCUS) { - n++; - if (n > 1) break; - } - - stop = vector->getFirstStop(); - - switch (draggable->point_type) { - case POINT_LG_MID: - case POINT_RG_MID1: - case POINT_RG_MID2: - stop = sp_get_stop_i(vector, draggable->point_i); - break; - case POINT_LG_END: - case POINT_RG_R1: - case POINT_RG_R2: - stop = sp_last_stop(vector); - break; - default: - break; - } - } - if (n > 1) break; - } - - if (n > 1) { - // Multiple stops selected - - EgeAdjustmentAction* offset = (EgeAdjustmentAction *)g_object_get_data( G_OBJECT(data), "offset_action"); - if (offset) { - gtk_action_set_sensitive( GTK_ACTION(offset), FALSE); - } - - // Stop list always updated first... reinsert "Multiple stops" as first entry. - InkSelectOneActionColumns columns; - Glib::RefPtr<Gtk::ListStore> store = act->get_store(); - - Gtk::TreeModel::Row row = *(store->prepend()); - row[columns.col_label ] = _("Multiple stops"); - row[columns.col_tooltip ] = ""; - row[columns.col_icon ] = "NotUsed"; - row[columns.col_sensitive] = true; - selected = 0; - - } else { - selected = select_stop_in_list( gradient, stop, data); - } - - if (selected < 0) { - act->set_active (0); - act->set_sensitive (false); - } else { - act->set_active (selected); - act->set_sensitive (true); - gr_stop_set_offset(data); - } -} - -/* Return gradient selected in menu. */ -static SPGradient *gr_get_selected_gradient(GObject *data) -{ - InkSelectOneAction *act = - static_cast<InkSelectOneAction *>(g_object_get_data(data, "gradient_select_action")); - - int active = act->get_active(); - - Glib::RefPtr<Gtk::ListStore> store = act->get_store(); - Gtk::TreeModel::Row row = store->children()[active]; - InkSelectOneActionColumns columns; - - void* pointer = row[columns.col_data]; - SPGradient *gr = static_cast<SPGradient *>(pointer); - - return gr; -} - -/* - * Callback functions for user actions - */ - -static void gr_new_type_changed( GObject * /*data*/, int mode ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setInt("/tools/gradient/newgradient", - mode == 0 ? SP_GRADIENT_TYPE_LINEAR : SP_GRADIENT_TYPE_RADIAL); -} - -static void gr_new_fillstroke_changed( GObject * /*data*/, int mode ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - Inkscape::PaintTarget fsmode = (mode == 0) ? Inkscape::FOR_FILL : Inkscape::FOR_STROKE; - prefs->setInt("/tools/gradient/newfillorstroke", (fsmode == Inkscape::FOR_FILL) ? 1 : 0); -} - -/* - * User selected a gradient from the combobox - */ -static void gr_gradient_changed( GObject *data, int active ) -{ - if (blocked) { - return; - } - - if (active < 0) { - return; - } - - blocked = true; - - SPGradient *gr = gr_get_selected_gradient (data); - - if (gr) { - gr = sp_gradient_ensure_vector_normalized(gr); - - SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data(data, "desktop")); - Inkscape::Selection *selection = desktop->getSelection(); - ToolBase *ev = desktop->getEventContext(); - - gr_apply_gradient(selection, ev ? ev->get_drag() : NULL, gr); - - DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_GRADIENT, - _("Assign gradient to object")); - } - - blocked = false; -} - -/* - * User selected a spread method from the combobox - */ -static void gr_spread_changed( GObject *data, int active ) -{ - if (blocked) { - return; - } - - blocked = true; - - SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data(data, "desktop")); - Inkscape::Selection *selection = desktop->getSelection(); - SPGradient *gradient = 0; - gr_get_dt_selected_gradient(selection, gradient); - - if (gradient) { - SPGradientSpread spread = (SPGradientSpread) active; - gradient->setSpread(spread); - gradient->updateRepr(); - - DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_GRADIENT, - _("Set gradient repeat")); - } - - blocked = false; -} - -/* - * User selected a stop from the combobox - */ -static void gr_stop_changed( GObject *data, int active ) -{ - if (blocked) { - return; - } - - blocked = true; - - SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data(G_OBJECT(data), "desktop")); - ToolBase *ev = desktop->getEventContext(); - SPGradient *gr = gr_get_selected_gradient(data); - - select_dragger_by_stop(data, gr, ev); - - blocked = false; -} - -/* - * User selected a stop from the combobox - */ -static void gr_stop_combo_changed(GtkComboBox * /*widget*/, GObject *data) -{ - if (blocked) { - return; - } - - blocked = true; - - SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data(G_OBJECT(data), "desktop")); - ToolBase *ev = desktop->getEventContext(); - SPGradient *gr = gr_get_selected_gradient(data); - - select_dragger_by_stop(data, gr, ev); - - blocked = false; -} - -/* - * User changed the offset - */ -static void gr_stop_offset_adjustment_changed(GtkAdjustment *adj, GObject *data) -{ - if (blocked) { - return; - } - - blocked = true; - - SPStop *stop = get_selected_stop(data); - if (stop) { - stop->offset = gtk_adjustment_get_value(adj); - sp_repr_set_css_double(stop->getRepr(), "offset", stop->offset); - - DocumentUndo::maybeDone(stop->document, "gradient:stop:offset", SP_VERB_CONTEXT_GRADIENT, - _("Change gradient stop offset")); - - } - - blocked = false; -} - - -static void gradient_toolbox_check_ec(SPDesktop* dt, Inkscape::UI::Tools::ToolBase* ec, GObject* data); - -/** - * Gradient auxiliary toolbar construction and setup. - * - */ -void sp_gradient_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, GObject* data) -{ - GtkIconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1); - - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - - /* New gradient linear or radial */ - { - InkSelectOneActionColumns columns; - - Glib::RefPtr<Gtk::ListStore> store = Gtk::ListStore::create(columns); - - Gtk::TreeModel::Row row; - - row = *(store->append()); - row[columns.col_label ] = _("linear"); - row[columns.col_tooltip ] = _("Create linear gradient"); - row[columns.col_icon ] = INKSCAPE_ICON("paint-gradient-linear"); - row[columns.col_sensitive] = true; - - row = *(store->append()); - row[columns.col_label ] = _("radial"); - row[columns.col_tooltip ] = _("Create radial (elliptic or circular) gradient"); - row[columns.col_icon ] = INKSCAPE_ICON("paint-gradient-radial"); - row[columns.col_sensitive] = true; - - InkSelectOneAction* act = - InkSelectOneAction::create( "GradientNewTypeAction", // Name - _("New"), // Label - "", // Tooltip - "Not Used", // Icon - store ); // Tree store - - act->use_radio( true ); - act->use_group_label( true ); - gint mode = prefs->getInt("/tools/gradient/newgradient", SP_GRADIENT_TYPE_LINEAR); - act->set_active( mode == SP_GRADIENT_TYPE_LINEAR ? 0 : 1 ); // linear == 1, radial == 2 - - gtk_action_group_add_action( mainActions, GTK_ACTION( act->gobj() )); - g_object_set_data( data, "gradient_new_type_mode", act ); - - act->signal_changed().connect(sigc::bind<0>(sigc::ptr_fun(&gr_new_type_changed), data)); - } - - /* New gradient on fill or stroke*/ - { - InkSelectOneActionColumns columns; - - Glib::RefPtr<Gtk::ListStore> store = Gtk::ListStore::create(columns); - - Gtk::TreeModel::Row row; - - row = *(store->append()); - row[columns.col_label ] = _("fill"); - row[columns.col_tooltip ] = _("Create gradient in the fill"); - row[columns.col_icon ] = INKSCAPE_ICON("object-fill"); - row[columns.col_sensitive] = true; - - row = *(store->append()); - row[columns.col_label ] = _("stroke"); - row[columns.col_tooltip ] = _("Create gradient in the stroke"); - row[columns.col_icon ] = INKSCAPE_ICON("object-stroke"); - row[columns.col_sensitive] = true; - - InkSelectOneAction* act = - InkSelectOneAction::create( "GradientNewFillStrokeAction", // Name - "", // Label - "", // Tooltip - "Not Used", // Icon - store ); // Tree store - - act->use_radio( true ); - act->use_group_label( false ); - Inkscape::PaintTarget fsmode = (prefs->getInt("/tools/gradient/newfillorstroke", 1) != 0) ? Inkscape::FOR_FILL : Inkscape::FOR_STROKE; - act->set_active( fsmode == Inkscape::FOR_FILL ? 0 : 1 ); - - gtk_action_group_add_action( mainActions, GTK_ACTION( act->gobj() )); - g_object_set_data( data, "gradient_new_fillstroke_action", act ); - - act->signal_changed().connect(sigc::bind<0>(sigc::ptr_fun(&gr_new_fillstroke_changed), data)); - } - - /* Gradient Select list*/ - { - InkSelectOneActionColumns columns; - - Glib::RefPtr<Gtk::ListStore> store = Gtk::ListStore::create(columns); - - Gtk::TreeModel::Row row; - - row = *(store->append()); - row[columns.col_label ] = _("No gradient"); - row[columns.col_tooltip ] = ""; - row[columns.col_icon ] = "NotUsed"; - row[columns.col_sensitive] = true; - - InkSelectOneAction* act = - InkSelectOneAction::create( "GradientSelectGradientAction", // Name - _("Select"), // Label - "", // Tooltip - "Not Used", // Icon - store ); // Tree store - - act->use_radio( false ); - act->use_icon( false ); - act->use_pixbuf( true ); - act->use_group_label( true ); - act->set_active( 0 ); - act->set_sensitive( false ); - - gtk_action_group_add_action( mainActions, GTK_ACTION( act->gobj() )); - g_object_set_data( data, "gradient_select_action", act ); - - act->signal_changed().connect(sigc::bind<0>(sigc::ptr_fun(&gr_gradient_changed), data)); - } - - // Gradient Spread type (how a gradient is drawn outside it's nominal area) - { - InkSelectOneActionColumns columns; - - Glib::RefPtr<Gtk::ListStore> store = Gtk::ListStore::create(columns); - - Gtk::TreeModel::Row row; - - row = *(store->append()); - row[columns.col_label ] = C_("Gradient repeat type", "None"); - row[columns.col_tooltip ] = ""; - row[columns.col_icon ] = "NotUsed"; - row[columns.col_sensitive] = true; - - row = *(store->append()); - row[columns.col_label ] = _("Reflected"); - row[columns.col_tooltip ] = ""; - row[columns.col_icon ] = "NotUsed"; - row[columns.col_sensitive] = true; - - row = *(store->append()); - row[columns.col_label ] = _("Direct"); - row[columns.col_tooltip ] = ""; - row[columns.col_icon ] = "NotUsed"; - row[columns.col_sensitive] = true; - - InkSelectOneAction* act = - InkSelectOneAction::create( "GradientSelectSpreadAction", // Name - _("Repeat"), // Label - // 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\")"), // Tooltip - "Not Used", // Icon - store ); // Tree store - - act->use_radio( false ); - act->use_icon( false ); - act->use_group_label( true ); - act->set_sensitive( false ); - - gtk_action_group_add_action( mainActions, GTK_ACTION( act->gobj() )); - g_object_set_data( data, "gradient_spread_action", act ); - - act->signal_changed().connect(sigc::bind<0>(sigc::ptr_fun(&gr_spread_changed), data)); - } - - /* Gradidnt Stop list */ - { - InkSelectOneActionColumns columns; - - Glib::RefPtr<Gtk::ListStore> store = Gtk::ListStore::create(columns); - - Gtk::TreeModel::Row row; - - row = *(store->append()); - row[columns.col_label ] = _("No stops"); - row[columns.col_tooltip ] = ""; - row[columns.col_icon ] = "NotUsed"; - row[columns.col_sensitive] = true; - - InkSelectOneAction* act = - InkSelectOneAction::create( "GradientStopAction", // Name - _("Stops" ), // Label - "", // Tooltip - "Not Used", // Icon - store ); // Tree store - - act->use_radio( false ); - act->use_icon( false ); - act->use_pixbuf( true ); - act->use_group_label( true ); - act->set_active( 0 ); - act->set_sensitive( false ); - - gtk_action_group_add_action( mainActions, GTK_ACTION( act->gobj() )); - g_object_set_data( data, "gradient_stop_action", act ); - - act->signal_changed().connect(sigc::bind<0>(sigc::ptr_fun(&gr_stop_changed), data)); - } - - /* Offset */ - { - EgeAdjustmentAction* eact = 0; - eact = create_adjustment_action( "GradientEditOffsetAction", - _("Offset"), C_("Gradient", "Offset:"), _("Offset of selected stop"), - "/tools/gradient/stopoffset", 0, - GTK_WIDGET(desktop->canvas), data, FALSE, NULL, - 0.0, 1.0, 0.01, 0.1, - 0, 0, 0, - gr_stop_offset_adjustment_changed, - NULL /*unit tracker*/, - 0.01, 2, 1.0); - - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - g_object_set_data( data, "offset_action", eact ); - gtk_action_set_sensitive( GTK_ACTION(eact), FALSE ); - - } - - /* Add stop */ - { - InkAction* inky = ink_action_new( "GradientEditAddAction", - _("Insert new stop"), - _("Insert new stop"), - INKSCAPE_ICON("node-add"), - secondarySize ); - g_object_set( inky, "short_label", _("Delete"), NULL ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(gr_add_stop), data ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - gtk_action_set_sensitive( GTK_ACTION(inky), FALSE ); - g_object_set_data( data, "gradient_stops_add_action", inky ); - } - - /* Delete stop */ - { - InkAction* inky = ink_action_new( "GradientEditDeleteAction", - _("Delete stop"), - _("Delete stop"), - INKSCAPE_ICON("node-delete"), - secondarySize ); - g_object_set( inky, "short_label", _("Delete"), NULL ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(gr_remove_stop), data ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - gtk_action_set_sensitive( GTK_ACTION(inky), FALSE ); - g_object_set_data( data, "gradient_stops_delete_action", inky ); - } - - /* Reverse */ - { - InkAction* inky = ink_action_new( "GradientEditReverseAction", - _("Reverse"), - _("Reverse the direction of the gradient"), - INKSCAPE_ICON("object-flip-horizontal"), - secondarySize ); - g_object_set( inky, "short_label", _("Delete"), NULL ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(gr_reverse), desktop ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - gtk_action_set_sensitive( GTK_ACTION(inky), FALSE ); - g_object_set_data( data, "gradient_stops_reverse_action", inky ); - - } - - // Gradients Linked toggle - { - InkToggleAction* itact = ink_toggle_action_new( "GradientEditLinkAction", - _("Link gradients"), - _("Link gradients to change all related gradients"), - INKSCAPE_ICON("object-unlocked"), - GTK_ICON_SIZE_MENU ); - g_object_set( itact, "short_label", "Lock", NULL ); - g_signal_connect_after( G_OBJECT(itact), "toggled", G_CALLBACK(gr_linked_changed), desktop) ; - gtk_action_group_add_action( mainActions, GTK_ACTION(itact) ); - - bool linkedmode = prefs->getBool("/options/forkgradientvectors/value", true); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(itact), !linkedmode ); - } - - g_object_set_data(data, "desktop", desktop); - - desktop->connectEventContextChanged(sigc::bind(sigc::ptr_fun(&gradient_toolbox_check_ec), data)); -} - - -// =================== Selection Changed Callbacks ======================= // - -/* - * Core function, setup all the widgets whenever something changes on the desktop - */ -static void gr_tb_selection_changed(Inkscape::Selection * /*selection*/, GObject* data) -{ - if (blocked) - return; - - blocked = true; - - SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data(data, "desktop")); - if (!desktop) { - return; - } - - Inkscape::Selection *selection = desktop->getSelection(); // take from desktop, not from args - if (selection) { - - ToolBase *ev = desktop->getEventContext(); - GrDrag *drag = NULL; - if (ev) { - drag = ev->get_drag(); - } - - SPGradient *gr_selected = 0; - SPGradientSpread spr_selected = SP_GRADIENT_SPREAD_UNDEFINED; - bool gr_multi = false; - bool spr_multi = false; - - gr_read_selection(selection, drag, gr_selected, gr_multi, spr_selected, spr_multi); - - // Gradient selection menu - auto sel = static_cast<InkSelectOneAction*>(g_object_get_data(data, "gradient_select_action")); - Glib::RefPtr<Gtk::ListStore> store = sel->get_store(); - int gradient = gr_vector_list (store, desktop, selection->isEmpty(), gr_selected, gr_multi); - - if (gradient < 0) { - // No selection or no gradients - sel->set_active( 0 ); - sel->set_sensitive (false); - } else { - // Single gradient or multiple gradients - sel->set_active( gradient ); - sel->set_sensitive (true); - } - - // Spread menu - auto spread = static_cast<InkSelectOneAction*>(g_object_get_data(data, "gradient_spread_action")); - spread->set_sensitive( gr_selected && !gr_multi ); - spread->set_active( gr_selected ? (int)spr_selected : 0 ); - - InkAction *add = (InkAction *) g_object_get_data(data, "gradient_stops_add_action"); - gtk_action_set_sensitive(GTK_ACTION(add), (gr_selected && !gr_multi && drag && !drag->selected.empty())); - - InkAction *del = (InkAction *) g_object_get_data(data, "gradient_stops_delete_action"); - gtk_action_set_sensitive(GTK_ACTION(del), (gr_selected && !gr_multi && drag && !drag->selected.empty())); - - InkAction *reverse = (InkAction *) g_object_get_data(data, "gradient_stops_reverse_action"); - gtk_action_set_sensitive(GTK_ACTION(reverse), (gr_selected!= NULL)); - - InkSelectOneAction *stops_action = (InkSelectOneAction *) g_object_get_data(data, "gradient_stop_action"); - stops_action->set_sensitive( gr_selected && !gr_multi); - - int stop = update_stop_list (gr_selected, nullptr, data, gr_multi); - select_stop_by_draggers(gr_selected, ev, data); - } - - blocked = false; -} - -static void gr_tb_selection_modified(Inkscape::Selection *selection, guint /*flags*/, GObject* data) -{ - gr_tb_selection_changed(selection, data); -} - -static void gr_drag_selection_changed(gpointer /*dragger*/, GObject* data) -{ - gr_tb_selection_changed(NULL, data); -} - -static void gr_defs_release(SPObject * /*defs*/, GObject* data) -{ - gr_tb_selection_changed(NULL, data); -} - -static void gr_defs_modified(SPObject * /*defs*/, guint /*flags*/, GObject* data) -{ - gr_tb_selection_changed(NULL, data); -} - -// lp:1327267 -/** - * Checks the current tool and connects gradient aux toolbox signals if it happens to be the gradient tool. - * Called every time the current tool changes by signal emission. - */ -static void gradient_toolbox_check_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolBase* ec, GObject* data) -{ - static sigc::connection connChanged; - static sigc::connection connModified; - static sigc::connection connSubselectionChanged; - static sigc::connection connDefsRelease; - static sigc::connection connDefsModified; - - if (SP_IS_GRADIENT_CONTEXT(ec)) { - Inkscape::Selection *selection = desktop->getSelection(); - SPDocument *document = desktop->getDocument(); - - // connect to selection modified and changed signals - connChanged = selection->connectChanged(sigc::bind(sigc::ptr_fun(&gr_tb_selection_changed), data)); - connModified = selection->connectModified(sigc::bind(sigc::ptr_fun(&gr_tb_selection_modified), data)); - connSubselectionChanged = desktop->connectToolSubselectionChanged(sigc::bind(sigc::ptr_fun(&gr_drag_selection_changed), data)); - - // Is this necessary? Couldn't hurt. - gr_tb_selection_changed(selection, data); - - // connect to release and modified signals of the defs (i.e. when someone changes gradient) - connDefsRelease = document->getDefs()->connectRelease( sigc::bind<1>(sigc::ptr_fun(&gr_defs_release), data)); - connDefsModified = document->getDefs()->connectModified(sigc::bind<2>(sigc::ptr_fun(&gr_defs_modified), data)); - } else { - if (connChanged) - connChanged.disconnect(); - if (connModified) - connModified.disconnect(); - if (connSubselectionChanged) - connSubselectionChanged.disconnect(); - if (connDefsRelease) - connDefsRelease.disconnect(); - if (connDefsModified) - connDefsModified.disconnect(); - } -} - -/* - Local Variables: - mode:c++ - c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) - indent-tabs-mode:nil - fill-column:99 - End: -*/ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : |
