summaryrefslogtreecommitdiffstats
path: root/src/widgets/gradient-toolbar.cpp
diff options
context:
space:
mode:
authorJohn Smith <john.smith7545@yahoo.com>2012-04-01 01:52:46 +0000
committerJohn Smith <removethis.john.q.public@bigmail.com>2012-04-01 01:52:46 +0000
commite76b6481c69c9a84decea8bcf345a26a4a408462 (patch)
treef68bbc50a72d26f0e4daad8cb10148be16f50279 /src/widgets/gradient-toolbar.cpp
parentapply essentials of patch by zcgucas (diff)
downloadinkscape-e76b6481c69c9a84decea8bcf345a26a4a408462.tar.gz
inkscape-e76b6481c69c9a84decea8bcf345a26a4a408462.zip
Fix for 950677 : Add stops and repeat controls to the gradient toolbar
(bzr r11134)
Diffstat (limited to 'src/widgets/gradient-toolbar.cpp')
-rw-r--r--src/widgets/gradient-toolbar.cpp1174
1 files changed, 912 insertions, 262 deletions
diff --git a/src/widgets/gradient-toolbar.cpp b/src/widgets/gradient-toolbar.cpp
index 2e7d6b89d..465c426fc 100644
--- a/src/widgets/gradient-toolbar.cpp
+++ b/src/widgets/gradient-toolbar.cpp
@@ -40,43 +40,51 @@
#include "sp-linear-gradient.h"
#include "sp-radial-gradient.h"
#include "gradient-chemistry.h"
+#include "gradient-selector.h"
#include "selection.h"
#include "ui/icon-names.h"
+#include "../ege-adjustment-action.h"
+#include "../ege-output-action.h"
+#include "../ege-select-one-action.h"
+#include "../ink-action.h"
+#include "../ink-comboboxentry-action.h"
+
+#include "sp-stop.h"
+#include "ui/widget/color-preview.h"
+#include "svg/css-ostringstream.h"
+#include "svg/svg-color.h"
+#include "desktop-style.h"
+#include "gradient-context.h"
+
#include "toolbox.h"
using Inkscape::DocumentUndo;
+using Inkscape::UI::ToolboxFactory;
+
+void gr_apply_gradient_to_item( SPItem *item, SPGradient *gr, SPGradientType new_type, guint new_fill, bool do_fill, bool do_stroke );
+void gr_apply_gradient (Inkscape::Selection *selection, GrDrag *drag, SPGradient *gr);
+gboolean gr_vector_list(GtkWidget *combo_box, SPDesktop *desktop, bool selection_empty, SPGradient *gr_selected, bool gr_multi);
+void gr_get_dt_selected_gradient (Inkscape::Selection *selection, SPGradient *&gr_selected);
+void gr_read_selection( Inkscape::Selection *selection, GrDrag *drag, SPGradient *&gr_selected, bool &gr_multi, SPGradientSpread &spr_selected, bool &spr_multi );
+static gboolean update_stop_list( GtkWidget *stop_combo, SPGradient *gradient, SPStop *new_stop, GtkWidget *widget, bool gr_multi);
+static void sp_gradient_vector_widget_load_gradient(GtkWidget *widget, SPGradient *gradient);
+static void select_stop_in_list( GtkWidget *combo_box, SPGradient *gradient, SPStop *new_stop, GtkWidget *data, gboolean block);
+static void select_stop_by_drag( GtkWidget *combo_box, SPGradient *gradient, SPEventContext *ev, GtkWidget *data);
+static void select_drag_by_stop( GtkWidget *combo_box, SPGradient *gradient, SPEventContext *ev);
+static SPGradient *gr_get_selected_gradient (GtkWidget *widget);
+static void gr_stop_set_offset (GtkComboBox *widget, GtkWidget *data);
+void add_toolbar_widget(GtkWidget *tbl, GtkWidget *widget);
+static GtkWidget * gr_ege_select_one_get_combo(GtkWidget *widget, const gchar *name);
+void check_renderer(GtkWidget *combo);
+static void gr_tb_selection_changed(Inkscape::Selection *selection, gpointer data);
+
+static gboolean blocked = FALSE;
//########################
//## Gradient ##
//########################
-static void gr_toggle_type (GtkWidget *button, gpointer data) {
- Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- GtkWidget *linear = (GtkWidget *) g_object_get_data (G_OBJECT(data), "linear");
- GtkWidget *radial = (GtkWidget *) g_object_get_data (G_OBJECT(data), "radial");
- if (button == linear && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (linear))) {
- prefs->setInt("/tools/gradient/newgradient", SP_GRADIENT_TYPE_LINEAR);
- if (radial) gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radial), FALSE);
- } else if (button == radial && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (radial))) {
- prefs->setInt("/tools/gradient/newgradient", SP_GRADIENT_TYPE_RADIAL);
- if (linear) gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (linear), FALSE);
- }
-}
-
-static void gr_toggle_fillstroke (GtkWidget *button, gpointer data) {
- Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- GtkWidget *fill = (GtkWidget *) g_object_get_data (G_OBJECT(data), "fill");
- GtkWidget *stroke = (GtkWidget *) g_object_get_data (G_OBJECT(data), "stroke");
- if (button == fill && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (fill))) {
- prefs->setBool("/tools/gradient/newfillorstroke", true);
- if (stroke) gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (stroke), FALSE);
- } else if (button == stroke && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (stroke))) {
- prefs->setBool("/tools/gradient/newfillorstroke", false);
- if (fill) gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fill), FALSE);
- }
-}
-
void gr_apply_gradient_to_item( SPItem *item, SPGradient *gr, SPGradientType new_type, guint new_fill, bool do_fill, bool do_stroke )
{
SPStyle *style = item->style;
@@ -122,7 +130,6 @@ void gr_apply_gradient (Inkscape::Selection *selection, GrDrag *drag, SPGradient
SPGradientType new_type = static_cast<SPGradientType>(prefs->getInt("/tools/gradient/newgradient", SP_GRADIENT_TYPE_LINEAR));
guint new_fill = prefs->getBool("/tools/gradient/newfillorstroke", true);
-
// GRADIENTFIXME: make this work for multiple selected draggers.
// First try selected dragger
@@ -141,54 +148,22 @@ void gr_apply_gradient (Inkscape::Selection *selection, GrDrag *drag, SPGradient
}
}
-void gr_combo_box_changed (GtkComboBox *widget, gpointer data)
+gboolean gr_vector_list(GtkWidget *combo_box, SPDesktop *desktop, bool selection_empty, SPGradient *gr_selected, bool gr_multi)
{
- GtkTreeIter iter;
- if (!gtk_combo_box_get_active_iter (widget, &iter)) {
- return;
- }
-
- GtkTreeModel *model = gtk_combo_box_get_model (widget);
- SPGradient *gr = NULL;
- gtk_tree_model_get (model, &iter, 2, &gr, -1);
-
- if (gr) {
- gr = sp_gradient_ensure_vector_normalized(gr);
-
- SPDesktop *desktop = static_cast<SPDesktop *>(data);
- Inkscape::Selection *selection = sp_desktop_selection (desktop);
- SPEventContext *ev = sp_desktop_event_context (desktop);
-
- gr_apply_gradient (selection, ev? ev->get_drag() : NULL, gr);
-
- DocumentUndo::done(sp_desktop_document (desktop), SP_VERB_CONTEXT_GRADIENT,
- _("Assign gradient to object"));
+ gboolean sensitive = FALSE;
+ if (blocked) {
+ return sensitive;
}
-}
-
-
-
-GtkWidget *gr_vector_list(SPDesktop *desktop, bool selection_empty, SPGradient *gr_selected, bool gr_multi)
-{
SPDocument *document = sp_desktop_document (desktop);
- GtkListStore *store;
GtkTreeIter iter;
- GtkCellRenderer *renderer;
- GtkWidget *combo_box;
-
- store = gtk_list_store_new (3, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_POINTER);
- combo_box = gtk_combo_box_new_with_model (GTK_TREE_MODEL (store));
+ GtkListStore *store = (GtkListStore *)gtk_combo_box_get_model (GTK_COMBO_BOX(combo_box));
- renderer = gtk_cell_renderer_pixbuf_new ();
- gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo_box), renderer, FALSE);
- gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo_box), renderer, "pixbuf", 0, NULL);
- gtk_cell_renderer_set_padding(renderer, 5, 0);
+ blocked = TRUE;
- renderer = gtk_cell_renderer_text_new ();
- gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo_box), renderer, TRUE);
- gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo_box), renderer, "text", 1, NULL);
+ /* Clear old list, if there is any */
+ gtk_list_store_clear(store);
GSList *gl = NULL;
const GSList *gradients = document->getResourceList("gradient");
@@ -206,31 +181,29 @@ GtkWidget *gr_vector_list(SPDesktop *desktop, bool selection_empty, SPGradient *
if (!gl) {
// The document has no gradients
gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter, 0, NULL, 1, _("No gradients"), 2, NULL, -1);
- gtk_widget_set_sensitive (combo_box, FALSE);
+ gtk_list_store_set (store, &iter, 0, _("No gradient"), 1, NULL, 2, NULL, -1);
+ sensitive = FALSE;
} else if (selection_empty) {
// Document has gradients, but nothing is currently selected.
gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter, 0, NULL, 1, _("Nothing selected"), 2, NULL, -1);
- gtk_widget_set_sensitive (combo_box, FALSE);
+ gtk_list_store_set (store, &iter, 0, _("Nothing selected"), 1, NULL, 2, NULL, -1);
+ sensitive = FALSE;
} else {
if (gr_selected == NULL) {
gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter, 0, NULL, 1, _("No gradient"), 2, NULL, -1);
- gtk_widget_set_sensitive (combo_box, FALSE);
-
+ gtk_list_store_set (store, &iter, 0, _("No gradient"), 1, NULL, 2, NULL, -1);
+ sensitive = FALSE;
}
if (gr_multi) {
gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter, 0, NULL, 1, _("Multiple gradients"), 2, NULL, -1);
- gtk_widget_set_sensitive (combo_box, FALSE);
-
+ gtk_list_store_set (store, &iter, 0, _("Multiple gradients"), 1, NULL, 2, NULL, -1);
+ sensitive = FALSE;
}
while (gl) {
@@ -238,9 +211,9 @@ GtkWidget *gr_vector_list(SPDesktop *desktop, bool selection_empty, SPGradient *
gl = g_slist_remove (gl, gradient);
gchar *label = gr_prepare_label(gradient);
- GdkPixbuf *pixb = sp_gradient_to_pixbuf (gradient, 64, 18);
+ GdkPixbuf *pixb = sp_gradient_to_pixbuf (gradient, 64, 16);
gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter, 0, pixb, 1, label, 2, gradient, -1);
+ gtk_list_store_set (store, &iter, 0, label, 1, pixb, 2, gradient, -1);
g_free (label);
if (gradient == gr_selected) {
@@ -248,7 +221,8 @@ GtkWidget *gr_vector_list(SPDesktop *desktop, bool selection_empty, SPGradient *
}
idx ++;
}
- gtk_widget_set_sensitive (combo_box, TRUE);
+ sensitive = TRUE;
+
}
/* Select the current gradient, or the Multi/Nothing line */
@@ -259,14 +233,47 @@ GtkWidget *gr_vector_list(SPDesktop *desktop, bool selection_empty, SPGradient *
gtk_combo_box_set_active (GTK_COMBO_BOX(combo_box) , pos);
}
- sp_set_font_size_smaller(combo_box);
+ blocked = FALSE;
+ return sensitive;
+}
- g_signal_connect (G_OBJECT (combo_box), "changed", G_CALLBACK (gr_combo_box_changed), desktop);
+/*
+ * 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;
- return combo_box;
-}
+ for (GSList const* i = selection->itemList(); i; i = i->next) {
+ SPItem *item = SP_ITEM(i->data); // 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,
@@ -364,63 +371,109 @@ void gr_read_selection( Inkscape::Selection *selection,
}
}
+/*
+ * Core function, setup all the widgets whenever something changes on the desktop
+ */
static void gr_tb_selection_changed(Inkscape::Selection * /*selection*/, gpointer data)
{
+ if (blocked)
+ return;
+
GtkWidget *widget = GTK_WIDGET(data);
SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data(G_OBJECT(widget), "desktop"));
- if (desktop) {
- Inkscape::Selection *selection = sp_desktop_selection(desktop); // take from desktop, not from args
- if (selection) {
- SPEventContext *ev = sp_desktop_event_context(desktop);
-
- GtkWidget *combo_box = (GtkWidget *) g_object_get_data(G_OBJECT(widget), "combobox");
- if (combo_box) {
- gtk_widget_destroy(combo_box);
- combo_box = 0;
- }
+ if (!desktop) {
+ return;
+ }
+
+ Inkscape::Selection *selection = sp_desktop_selection(desktop); // take from desktop, not from args
+ if (selection) {
+ SPEventContext *ev = sp_desktop_event_context(desktop);
+ GrDrag *drag = NULL;
+ if (ev) {
+ drag = ev->get_drag();
+ }
+
+ SPGradient *gr_selected = 0;
+ SPGradientSpread spr_selected = static_cast<SPGradientSpread>(INT_MAX); // meaning undefined
+ bool gr_multi = false;
+ bool spr_multi = false;
+
+ gr_read_selection(selection, drag, gr_selected, gr_multi, spr_selected, spr_multi);
+
+ GtkWidget *gradient_combo = gr_ege_select_one_get_combo(widget, "gradient_select_combo_action");
+ if ( gradient_combo ) {
+ check_renderer(gradient_combo);
+ gboolean sensitive = gr_vector_list(gradient_combo, desktop, selection->isEmpty(), gr_selected, gr_multi);
+
+ EgeSelectOneAction *gradient_action = (EgeSelectOneAction *) g_object_get_data(G_OBJECT(widget), "gradient_select_combo_action");
+ gtk_action_set_sensitive( GTK_ACTION(gradient_action), sensitive );
+ }
- SPGradient *gr_selected = 0;
- bool gr_multi = false;
+ EgeSelectOneAction* spread = (EgeSelectOneAction *) g_object_get_data(G_OBJECT(widget), "gradient_select_repeat_action");
+ gtk_action_set_sensitive( GTK_ACTION(spread), (gr_selected && !gr_multi) );
+ if (gr_selected) {
+ blocked = TRUE;
+ ege_select_one_action_set_active( spread, spr_selected);
+ blocked = FALSE;
+ }
- SPGradientSpread spr_selected = static_cast<SPGradientSpread>(INT_MAX); // meaning undefined
- bool spr_multi = false;
+ InkAction *add = (InkAction *) g_object_get_data(G_OBJECT(widget), "gradient_stops_add_action");
+ gtk_action_set_sensitive(GTK_ACTION(add), (gr_selected && !gr_multi && drag && drag->selected));
- gr_read_selection(selection, ev ? ev->get_drag() : 0, gr_selected, gr_multi, spr_selected, spr_multi);
+ InkAction *del = (InkAction *) g_object_get_data(G_OBJECT(widget), "gradient_stops_delete_action");
+ gtk_action_set_sensitive(GTK_ACTION(del), (gr_selected && !gr_multi && drag && drag->selected));
- combo_box = gr_vector_list(desktop, selection->isEmpty(), gr_selected, gr_multi);
- g_object_set_data(G_OBJECT(widget), "combobox", combo_box);
+ InkAction *reverse = (InkAction *) g_object_get_data(G_OBJECT(widget), "gradient_stops_reverse_action");
+ gtk_action_set_sensitive(GTK_ACTION(reverse), (gr_selected!= NULL));
- GtkWidget *buttons = (GtkWidget *) g_object_get_data(G_OBJECT(widget), "buttons");
- gtk_widget_set_sensitive(buttons, (gr_selected && !gr_multi));
+ EgeSelectOneAction *stops_action = (EgeSelectOneAction *) g_object_get_data(G_OBJECT(widget), "gradient_stops_combo_action");
+ gtk_action_set_sensitive( GTK_ACTION(stops_action), (gr_selected && !gr_multi) );
- gtk_box_pack_start(GTK_BOX(widget), combo_box, TRUE, TRUE, 0);
+ GtkWidget *stops_combo = gr_ege_select_one_get_combo(widget, "gradient_stops_combo_action");
+ if ( stops_combo ) {
- gtk_widget_show_all(widget);
+ check_renderer(stops_combo);
+ update_stop_list(stops_combo, gr_selected, NULL, widget, gr_multi);
+ select_stop_by_drag(stops_combo, gr_selected, ev, widget);
}
+
+ //sp_gradient_vector_widget_load_gradient(widget, gr_selected);
+
}
+
}
-static void
-gr_tb_selection_modified (Inkscape::Selection *selection, guint /*flags*/, gpointer data)
+static GtkWidget * gr_ege_select_one_get_combo(GtkWidget *widget, const gchar *name)
+{
+ GtkWidget *combo_box = 0;
+ EgeSelectOneAction *act1 = (EgeSelectOneAction *)g_object_get_data( G_OBJECT(widget), name);
+ if (act1) {
+ gpointer combodata = g_object_get_data( G_OBJECT(act1), "ege-combo-box" );
+ if ( GTK_IS_COMBO_BOX(combodata) ) {
+ combo_box = GTK_WIDGET(combodata);
+ }
+ }
+ return combo_box;
+}
+
+static void gr_tb_selection_modified (Inkscape::Selection *selection, guint /*flags*/, gpointer data)
{
gr_tb_selection_changed (selection, data);
}
-static void
-gr_drag_selection_changed (gpointer /*dragger*/, gpointer data)
+static void gr_drag_selection_changed (gpointer /*dragger*/, gpointer data)
{
gr_tb_selection_changed (NULL, data);
+
}
-static void
-gr_defs_release (SPObject */*defs*/, GtkWidget *widget)
+static void gr_defs_release (SPObject */*defs*/, GtkWidget *widget)
{
gr_tb_selection_changed (NULL, (gpointer) widget);
}
-static void
-gr_defs_modified (SPObject */*defs*/, guint /*flags*/, GtkWidget *widget)
+static void gr_defs_modified (SPObject */*defs*/, guint /*flags*/, GtkWidget *widget)
{
gr_tb_selection_changed (NULL, (gpointer) widget);
}
@@ -430,220 +483,817 @@ static void gr_disconnect_sigc (GObject */*obj*/, sigc::connection *connection)
delete connection;
}
-static void
-gr_edit (GtkWidget */*button*/, GtkWidget *widget)
+static SPStop *get_selected_stop( GtkWidget *vb)
{
- GtkWidget *combo_box = (GtkWidget *) g_object_get_data (G_OBJECT(widget), "combobox");
-
- spinbutton_defocus(GTK_OBJECT(widget));
+ SPStop *stop = NULL;
- if (combo_box) {
+ GtkWidget *cb = gr_ege_select_one_get_combo(vb, "gradient_stops_combo_action");
+ if ( cb ) {
GtkTreeIter iter;
- if (!gtk_combo_box_get_active_iter (GTK_COMBO_BOX(combo_box), &iter)) {
- return;
+ if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX(cb), &iter)) {
+ GtkListStore *store = (GtkListStore *)gtk_combo_box_get_model (GTK_COMBO_BOX(cb));
+ gtk_tree_model_get (GTK_TREE_MODEL(store), &iter, 2, &stop, -1);
}
+ }
- GtkTreeModel *model = gtk_combo_box_get_model (GTK_COMBO_BOX(combo_box));
- SPGradient *gr = NULL;
- gtk_tree_model_get (model, &iter, 2, &gr, -1);
+ return stop;
+}
- if (gr) {
- GtkWidget *dialog = sp_gradient_vector_editor_new (gr);
- gtk_widget_show (dialog);
+
+static void sp_gradient_vector_gradient_release(SPObject */*object*/, GtkWidget *widget)
+{
+ sp_gradient_vector_widget_load_gradient(widget, NULL);
+}
+
+static void sp_gradient_vector_gradient_modified(SPObject *object, guint /*flags*/, GtkWidget *widget)
+{
+ SPGradient *gradient=SP_GRADIENT(object);
+ if (!blocked) {
+ blocked = TRUE;
+ sp_gradient_vector_widget_load_gradient(widget, gradient);
+ blocked = FALSE;
+ }
+}
+
+static void sp_gradient_vector_widget_load_gradient(GtkWidget *widget, SPGradient *gradient)
+{
+ blocked = TRUE;
+
+ SPGradient *old = gr_get_selected_gradient(widget);
+
+ if (old != gradient) {
+
+ g_message("Load gradient");
+
+ sigc::connection *release_connection;
+ sigc::connection *modified_connection;
+
+ release_connection = (sigc::connection *)g_object_get_data(G_OBJECT(widget), "gradient_release_connection");
+ modified_connection = (sigc::connection *)g_object_get_data(G_OBJECT(widget), "gradient_modified_connection");
+
+ if (old) {
+ g_assert( release_connection != NULL );
+ g_assert( modified_connection != NULL );
+ release_connection->disconnect();
+ modified_connection->disconnect();
+ sp_signal_disconnect_by_data(old, widget);
+ }
+
+ if (gradient) {
+ if (!release_connection) {
+ release_connection = new sigc::connection();
+ }
+ if (!modified_connection) {
+ modified_connection = new sigc::connection();
+ }
+ *release_connection = gradient->connectRelease(sigc::bind<1>(sigc::ptr_fun(&sp_gradient_vector_gradient_release), widget));
+ *modified_connection = gradient->connectModified(sigc::bind<2>(sigc::ptr_fun(&sp_gradient_vector_gradient_modified), widget));
+ } else {
+ if (release_connection) {
+ delete release_connection;
+ release_connection = NULL;
+ }
+ if (modified_connection) {
+ delete modified_connection;
+ modified_connection = NULL;
+ }
+ }
+
+ g_object_set_data(G_OBJECT(widget), "gradient_release_connection", release_connection);
+ g_object_set_data(G_OBJECT(widget), "gradient_modified_connection", modified_connection);
+ }
+
+ if (gradient) {
+ gtk_widget_set_sensitive(widget, TRUE);
+
+ gradient->ensureVector();
+
+ SPStop *stop = get_selected_stop(widget);
+ if (!stop) {
+ return;
}
+
+ // Once the user edits a gradient, it stops being auto-collectable
+ if (gradient->getRepr()->attribute("inkscape:collect")) {
+ SPDocument *document = gradient->document;
+ bool saved = DocumentUndo::getUndoSensitive(document);
+ DocumentUndo::setUndoSensitive(document, false);
+ gradient->getRepr()->setAttribute("inkscape:collect", NULL);
+ DocumentUndo::setUndoSensitive(document, saved);
+ }
+ } else { // no gradient, disable everything
+ gtk_widget_set_sensitive(widget, FALSE);
}
+
+ blocked = FALSE;
}
-GtkWidget * gr_change_widget(SPDesktop *desktop)
+static void
+gr_add_stop (GtkWidget */*button*/,GtkWidget *vb)
{
+ SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data(G_OBJECT(vb), "desktop"));
+ if (!desktop) {
+ return;
+ }
+
+ Inkscape::Selection *selection = sp_desktop_selection(desktop);
+ if (!selection) {
+ return;
+ }
+
+ SPEventContext *ev = sp_desktop_event_context(desktop);
+ SPGradientContext *rc = SP_GRADIENT_CONTEXT(ev);
+
+ if (rc) {
+ sp_gradient_context_add_stops_between_selected_stops (rc);
+ }
+
+}
+
+static void
+gr_remove_stop (GtkWidget */*button*/, GtkWidget *vb)
+{
+
+ SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data(G_OBJECT(vb), "desktop"));
+ if (!desktop) {
+ return;
+ }
+
+ Inkscape::Selection *selection = sp_desktop_selection(desktop); // take from desktop, not from args
+ if (!selection) {
+ return;
+ }
+
+ SPEventContext *ev = sp_desktop_event_context(desktop);
+ GrDrag *drag = NULL;
+ if (ev) {
+ drag = ev->get_drag();
+ }
+
+ if (drag) {
+ drag->deleteSelected();
+ }
+
+}
+
+static void
+gr_reverse (GtkWidget */*button*/, gpointer data)
+{
+ SPDesktop *desktop = static_cast<SPDesktop *>(data);
Inkscape::Selection *selection = sp_desktop_selection (desktop);
- SPDocument *document = sp_desktop_document (desktop);
SPEventContext *ev = sp_desktop_event_context (desktop);
- SPGradient *gr_selected = NULL;
- bool gr_multi = false;
+ if (!ev) {
+ return;
+ }
- SPGradientSpread spr_selected = (SPGradientSpread) INT_MAX; // meaning undefined
- bool spr_multi = false;
+ GrDrag *drag = ev->get_drag();
- gr_read_selection (selection, ev? ev->get_drag() : 0, gr_selected, gr_multi, spr_selected, spr_multi);
+ // First try selected dragger
+ if (drag && drag->selected) {
+ drag->selected_reverse_vector();
+ } else { // If no drag or no dragger selected, act on selection (both fill and stroke gradients)
+ for (GSList const* i = selection->itemList(); i != NULL; i = i->next) {
+ sp_item_gradient_reverse_vector (SP_ITEM(i->data), true);
+ sp_item_gradient_reverse_vector (SP_ITEM(i->data), false);
+ }
+ }
+ // we did an undoable action
+ DocumentUndo::done(sp_desktop_document (desktop), SP_VERB_CONTEXT_GRADIENT,
+ _("Invert gradient"));
+}
- GtkWidget *widget = gtk_hbox_new(FALSE, FALSE);
- g_object_set_data(G_OBJECT(widget), "dtw", desktop->canvas);
- g_object_set_data (G_OBJECT (widget), "desktop", desktop);
+/*
+ * Change desktop drag selection to this stop
+ */
+static void select_drag_by_stop( GtkWidget *data, SPGradient *gradient, SPEventContext *ev)
+{
+ if (blocked || !ev || !gradient)
+ return;
+
+ GrDrag *drag = ev->get_drag();
+ if (!drag) {
+ return;
+ }
- GtkWidget *combo_box = gr_vector_list(desktop, selection->isEmpty(), gr_selected, gr_multi);
- g_object_set_data(G_OBJECT(widget), "combobox", combo_box);
+ SPStop *stop = get_selected_stop(data);
- gtk_box_pack_start (GTK_BOX (widget), combo_box, TRUE, TRUE, 0);
- {
- GtkWidget *buttons = gtk_hbox_new(FALSE, 1);
+ SPStop *stop_iter;
+ GList *i;
- /* Edit... */
- {
- GtkWidget *hb = gtk_hbox_new(FALSE, 1);
- GtkWidget *b = gtk_button_new_with_label(_("Edit..."));
- gtk_widget_set_tooltip_text(b, _("Edit the stops of the gradient"));
- gtk_widget_show(b);
- gtk_container_add(GTK_CONTAINER(hb), b);
- g_signal_connect(G_OBJECT(b), "clicked", G_CALLBACK(gr_edit), widget);
- gtk_box_pack_start (GTK_BOX(buttons), hb, FALSE, FALSE, 0);
+ // Walk thru the draggers and the gradient stops at the same time
+ for (i = drag->draggers, stop_iter = gradient->getFirstStop();
+ i != NULL && stop_iter && SP_IS_STOP(stop_iter);
+ i = i->next, stop_iter = SP_STOP(stop_iter->getNext())) {
+
+ if (stop == stop_iter) {
+ GrDragger *d = (GrDragger *) i->data;
+ drag->setSelected(d, false, true);
+ blocked = FALSE;
+ return;
+ }
}
+}
+
+static void select_stop_by_drag(GtkWidget *combo_box, SPGradient *gradient, SPEventContext *ev, GtkWidget *data)
+{
+ if (blocked || !ev || !gradient)
+ return;
+
+ GrDrag *drag = ev->get_drag();
- gtk_box_pack_end (GTK_BOX(widget), buttons, FALSE, FALSE, 0);
- g_object_set_data (G_OBJECT(widget), "buttons", buttons);
- gtk_widget_set_sensitive (buttons, (gr_selected && !gr_multi));
+ if (!drag || !drag->selected) {
+ blocked = TRUE;
+ gtk_combo_box_set_active (GTK_COMBO_BOX(combo_box) , 0);
+ gr_stop_set_offset(GTK_COMBO_BOX(combo_box), data);
+ blocked = FALSE;
+ return;
}
- // connect to selection modified and changed signals
- sigc::connection *conn1 = new sigc::connection (selection->connectChanged(
- sigc::bind (
- sigc::ptr_fun(&gr_tb_selection_changed),
- (gpointer)widget )
- ));
- sigc::connection *conn2 = new sigc::connection (selection->connectModified(
- sigc::bind (
- sigc::ptr_fun(&gr_tb_selection_modified),
- (gpointer)widget )
- ));
-
- sigc::connection *conn3 = new sigc::connection (desktop->connectToolSubselectionChanged(
- sigc::bind (
- sigc::ptr_fun(&gr_drag_selection_changed),
- (gpointer)widget )
- ));
-
- // when widget is destroyed, disconnect
- g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_sigc), conn1);
- g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_sigc), conn2);
- g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_sigc), conn3);
-
- // connect to release and modified signals of the defs (i.e. when someone changes gradient)
- sigc::connection *release_connection = new sigc::connection();
- *release_connection = document->getDefs()->connectRelease(sigc::bind<1>(sigc::ptr_fun(&gr_defs_release), widget));
- sigc::connection *modified_connection = new sigc::connection();
- *modified_connection = document->getDefs()->connectModified(sigc::bind<2>(sigc::ptr_fun(&gr_defs_modified), widget));
+ gint n = 0;
+
+ // for all selected draggers
+ for (GList *i = drag->selected; i != NULL; i = i->next) {
+ GrDragger *dragger = (GrDragger *) i->data;
+ // for all draggables of dragger
+ for (GSList const* j = dragger->draggables; j != NULL; j = j->next) {
+ GrDraggable *draggable = (GrDraggable *) j->data;
+
+ if (draggable->point_type != POINT_RG_FOCUS) {
+ n++;
+ }
+ if (n > 1) {
- // when widget is destroyed, disconnect
- g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_sigc), release_connection);
- g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_sigc), modified_connection);
+ // Mulitple stops selected
+ GtkListStore *store = (GtkListStore *)gtk_combo_box_get_model (GTK_COMBO_BOX(combo_box));
+ if (!store) {
+ return;
+ }
+ GtkTreeIter iter;
+ gtk_list_store_prepend (store, &iter);
+ gtk_list_store_set (store, &iter, 0, _("Multiple stops"), 1, NULL, 2, NULL, -1);
+ gtk_combo_box_set_active (GTK_COMBO_BOX(combo_box) , 0);
+
+ EgeAdjustmentAction* act = (EgeAdjustmentAction *)g_object_get_data( G_OBJECT(data), "offset_action");
+ if (act) {
+ gtk_action_set_sensitive( GTK_ACTION(act), FALSE);
+ }
+
+ return;
+ }
+
+
+ SPGradient *vector = gradient->getVector();
+ if (!vector)
+ return;
+
+ SPStop *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;
+ }
+
+ select_stop_in_list( combo_box, gradient, stop, data, TRUE);
+ }
+ }
+}
+
+static void select_stop_in_list( GtkWidget *combo_box, SPGradient *gradient, SPStop *new_stop, GtkWidget *data, gboolean block)
+{
+ int i = 0;
+ for ( SPObject *ochild = gradient->firstChild() ; ochild ; ochild = ochild->getNext() ) {
+ if (SP_IS_STOP(ochild)) {
+ if (ochild == new_stop) {
+ blocked = block;
+ gtk_combo_box_set_active (GTK_COMBO_BOX(combo_box) , i);
+ gr_stop_set_offset(GTK_COMBO_BOX(combo_box), data);
+ blocked = FALSE;
+ return;
+ }
+ i++;
+ }
+ }
+}
+
+static gboolean update_stop_list( GtkWidget *stop_combo, SPGradient *gradient, SPStop *new_stop, GtkWidget *widget, bool gr_multi)
+{
+ gboolean sensitive = FALSE;
+
+ if (!stop_combo) {
+ return sensitive;
+ }
+
+ GtkListStore *store = (GtkListStore *)gtk_combo_box_get_model (GTK_COMBO_BOX(stop_combo));
+ if (!store) {
+ return sensitive;
+ }
+
+ blocked = TRUE;
+
+ /* Clear old list, if there is any */
+ gtk_list_store_clear(store);
+ GtkTreeIter iter;
+
+ if (!SP_IS_GRADIENT(gradient)) {
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter, 0, _("No gradient"), 1, NULL, 2, NULL, -1);
+ gtk_combo_box_set_active (GTK_COMBO_BOX(stop_combo) , 0);
+ sensitive = FALSE;
+ blocked = FALSE;
+ return sensitive;
+ }
+
+ /* Populate the combobox store */
+ GSList *sl = NULL;
+ if ( gradient->hasStops() ) {
+ for ( SPObject *ochild = gradient->firstChild() ; ochild ; ochild = ochild->getNext() ) {
+ if (SP_IS_STOP(ochild)) {
+ sl = g_slist_append(sl, ochild);
+ }
+ }
+ }
+ if (!sl) {
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter, 0, _("No stops in gradient"), 1, NULL, 2, NULL, -1);
+ sensitive = FALSE;
+
+ } else {
+
+ for (; sl != NULL; sl = sl->next){
+ if (SP_IS_STOP(sl->data)){
+ SPStop *stop = SP_STOP(sl->data);
+ Inkscape::XML::Node *repr = reinterpret_cast<SPItem *>(sl->data)->getRepr();
+ Inkscape::UI::Widget::ColorPreview *cpv = Gtk::manage(new Inkscape::UI::Widget::ColorPreview(sp_stop_get_rgba32(stop)));
+ GdkPixbuf *pb = cpv->toPixbuf(32, 16);
+
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter, 0, repr->attribute("id"), 1, pb, 2, stop, -1);
+ sensitive = FALSE;
+ }
+ }
+
+ sensitive = TRUE;
+ }
+
+ if (gr_multi) {
+ sensitive = FALSE;
+ }
+
+ if (new_stop == NULL) {
+ gtk_combo_box_set_active (GTK_COMBO_BOX(stop_combo) , 0);
+ } else {
+ select_stop_in_list(stop_combo, gradient, new_stop, widget, TRUE);
+ }
+
+ blocked = FALSE;
+
+ return sensitive;
+}
+
+static SPGradient *gr_get_selected_gradient (GtkWidget *widget)
+{
+ SPGradient *gr = NULL;
+ EgeSelectOneAction* act1 = (EgeSelectOneAction *)g_object_get_data( G_OBJECT(widget), "gradient_select_combo_action");
+ if (act1) {
+ gint n = ege_select_one_action_get_active(act1);
+ GtkTreeModel *model = ege_select_one_action_get_model(act1);
+ GtkTreeIter iter;
+ if (gtk_tree_model_iter_nth_child (model ,&iter, NULL, n)) {
+ gtk_tree_model_get (model, &iter, 2, &gr, -1);
+ return gr;
+ }
+ }
+
+ return gr;
+}
+
+/*static void
+gr_edit (GtkWidget *button, GtkWidget *widget)
+{
+ SPGradient *gr = gr_get_selected_gradient(widget);
+ if (gr) {
+ GtkWidget *dialog = sp_gradient_vector_editor_new (gr);
+ gtk_widget_show (dialog);
+ }
+}*/
+
+static void gr_stop_set_offset (GtkComboBox */*widget*/, GtkWidget *data)
+{
+ SPStop *stop = get_selected_stop(data);
+ if (!stop) {
+ return;
+ }
+
+ EgeAdjustmentAction* act = (EgeAdjustmentAction *)g_object_get_data( G_OBJECT(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);
+ }
+
+ blocked = TRUE;
+ gtk_adjustment_set_value(adj, stop->offset);
+ gtk_action_set_sensitive( GTK_ACTION(act), !isEndStop );
+ gtk_adjustment_changed(adj);
+ blocked = FALSE;
- gtk_widget_show_all (widget);
- return widget;
}
-GtkWidget *
-sp_gradient_toolbox_new(SPDesktop *desktop)
+
+/*
+ * Callback functions for user actions
+ */
+
+static void gr_new_type_changed( EgeSelectOneAction *act, GObject *tbl )
{
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- GtkWidget *tbl = gtk_toolbar_new();
+ gint typemode = ege_select_one_action_get_active( act ) == 0 ? SP_GRADIENT_TYPE_LINEAR : SP_GRADIENT_TYPE_RADIAL;
+ prefs->setInt("/tools/gradient/newgradient", typemode);
+}
- g_object_set_data(G_OBJECT(tbl), "dtw", desktop->canvas);
- g_object_set_data(G_OBJECT(tbl), "desktop", desktop);
+static void gr_new_fillstroke_changed( EgeSelectOneAction *act, GObject *tbl )
+{
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ bool fillmode = ege_select_one_action_get_active( act ) == 0;
+ prefs->setBool("/tools/gradient/newfillorstroke", fillmode);
+}
- sp_toolbox_add_label(tbl, _("<b>New:</b>"));
+/*
+ * User selected a gradient from the combobox
+ */
+void gr_gradient_combo_changed (EgeSelectOneAction *act, gpointer data)
+{
+ if (blocked) {
+ return;
+ }
- // TODO replace aux_toolbox_space(tbl, AUX_SPACING);
+ SPGradient *gr = NULL;
+ gint n = ege_select_one_action_get_active(act);
+ GtkTreeModel *model = ege_select_one_action_get_model(act);
+ GtkTreeIter iter;
+ if (gtk_tree_model_iter_nth_child (model ,&iter, NULL, n)) {
+ gtk_tree_model_get (model, &iter, 2, &gr, -1);
+ }
- {
- GtkWidget *cvbox = gtk_vbox_new (FALSE, 0);
- GtkWidget *cbox = gtk_hbox_new (FALSE, 0);
+ if (gr) {
+ gr = sp_gradient_ensure_vector_normalized(gr);
- {
- GtkWidget *button = sp_button_new_from_data( Inkscape::ICON_SIZE_DECORATION,
- SP_BUTTON_TYPE_TOGGLE,
- NULL,
- INKSCAPE_ICON("paint-gradient-linear"),
- _("Create linear gradient") );
- g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (gr_toggle_type), tbl);
- g_object_set_data(G_OBJECT(tbl), "linear", button);
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
- prefs->getInt("/tools/gradient/newgradient", SP_GRADIENT_TYPE_LINEAR) == SP_GRADIENT_TYPE_LINEAR);
- gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0);
+ SPDesktop *desktop = static_cast<SPDesktop *>(data);
+ Inkscape::Selection *selection = sp_desktop_selection (desktop);
+ SPEventContext *ev = sp_desktop_event_context (desktop);
+
+ gr_apply_gradient (selection, ev? ev->get_drag() : NULL, gr);
+
+ DocumentUndo::done(sp_desktop_document (desktop), SP_VERB_CONTEXT_GRADIENT,
+ _("Assign gradient to object"));
}
- {
- GtkWidget *button = sp_button_new_from_data( Inkscape::ICON_SIZE_DECORATION,
- SP_BUTTON_TYPE_TOGGLE,
- NULL,
- INKSCAPE_ICON("paint-gradient-radial"),
- _("Create radial (elliptic or circular) gradient"));
- g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (gr_toggle_type), tbl);
- g_object_set_data(G_OBJECT(tbl), "radial", button);
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
- prefs->getInt("/tools/gradient/newgradient", SP_GRADIENT_TYPE_LINEAR) == SP_GRADIENT_TYPE_RADIAL);
- gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0);
+}
+
+void gr_spread_change (EgeSelectOneAction *act, GtkWidget *widget)
+{
+ if (blocked) {
+ return;
}
- gtk_box_pack_start(GTK_BOX(cvbox), cbox, TRUE, FALSE, 0);
- GtkToolItem *cvbox_toolitem = gtk_tool_item_new();
- gtk_container_add(GTK_CONTAINER(cvbox_toolitem), cvbox);
- gtk_toolbar_insert(GTK_TOOLBAR(tbl), cvbox_toolitem, -1);
+ SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data(G_OBJECT(widget), "desktop"));
+ Inkscape::Selection *selection = sp_desktop_selection (desktop);
+ SPGradient *gradient = 0;
+ gr_get_dt_selected_gradient(selection, gradient);
+
+ if (gradient) {
+ SPGradientSpread spread = (SPGradientSpread) ege_select_one_action_get_active (act);
+ gradient->setSpread(spread);
+ gradient->updateRepr();
+
+ DocumentUndo::done(sp_desktop_document (desktop), SP_VERB_CONTEXT_GRADIENT,
+ _("Set gradient repeat"));
+ }
+}
+
+
+/*
+ * User selected a stop from the combobox
+ */
+static void gr_stop_combo_changed (GtkComboBox *widget, GtkWidget *data)
+{
+ if (blocked) {
+ return;
+ }
+
+ SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data(G_OBJECT(data), "desktop"));
+ SPEventContext *ev = sp_desktop_event_context (desktop);
+ SPGradient *gr = gr_get_selected_gradient(data);
+
+ select_drag_by_stop(data, gr, ev);
+}
+
+/*
+ * User changed the offset
+ */
+static void gr_stop_offset_adjustment_changed(GtkAdjustment *adj, GObject *tbl)
+{
+ if (blocked) {
+ return;
}
- // TODO replace aux_toolbox_space(tbl, AUX_SPACING);
+ blocked = TRUE;
- sp_toolbox_add_label(tbl, _("on"), false);
+ SPStop *stop = get_selected_stop(GTK_WIDGET(tbl));
+ if (stop) {
+ stop->offset = gtk_adjustment_get_value (adj);
+ sp_repr_set_css_double(stop->getRepr(), "offset", stop->offset);
- // TODO replace aux_toolbox_space(tbl, AUX_SPACING);
+ DocumentUndo::maybeDone(stop->document, "gradient:stop:offset", SP_VERB_CONTEXT_GRADIENT,
+ _("Change gradient stop offset"));
+ }
+
+ blocked = FALSE;
+}
+
+/*
+ * Change the combobox to show the icon/image on the left of the text
+ */
+void check_renderer(GtkWidget *combo)
+{
+ gpointer rendered = g_object_get_data( G_OBJECT(combo), "renderers" );
+ if (!rendered) {
+
+ gtk_cell_layout_clear(GTK_CELL_LAYOUT (combo));
+
+ GtkCellRenderer *renderer = gtk_cell_renderer_pixbuf_new ();
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, FALSE);
+ gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), renderer, "pixbuf", 1, NULL);
+ gtk_cell_renderer_set_padding(renderer, 5, 0);
+
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE);
+ gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), renderer, "text", 0, NULL);
+
+ g_object_set_data(G_OBJECT(combo), "renderers", renderer);
+ }
+}
+/**
+ * Gradient auxiliary toolbar construction and setup.
+ *
+ */
+void sp_gradient_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, GObject* holder)
+{
+ Inkscape::IconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1);
+
+ /* New gradient linear or radial */
{
- GtkWidget *cvbox = gtk_vbox_new (FALSE, 0);
- GtkWidget *cbox = gtk_hbox_new (FALSE, 0);
+ GtkListStore* model = gtk_list_store_new( 3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING );
+
+ GtkTreeIter iter;
+ gtk_list_store_append( model, &iter );
+ gtk_list_store_set( model, &iter,
+ 0, _("linear"), 1, _("Create linear gradient"), 2, INKSCAPE_ICON("paint-gradient-linear"), -1 );
+
+ gtk_list_store_append( model, &iter );
+ gtk_list_store_set( model, &iter,
+ 0, _("radial"), 1, _("Create radial (elliptic or circular) gradient"), 2, INKSCAPE_ICON("paint-gradient-radial"), -1 );
+
+ EgeSelectOneAction* act = ege_select_one_action_new( "GradientNewTypeAction", (""), (""), NULL, GTK_TREE_MODEL(model) );
+ g_object_set( act, "short_label", _("New:"), NULL );
+ gtk_action_group_add_action( mainActions, GTK_ACTION(act) );
+ g_object_set_data( holder, "gradient_new_type_action", act );
+
+ ege_select_one_action_set_appearance( act, "full" );
+ ege_select_one_action_set_radio_action_type( act, INK_RADIO_ACTION_TYPE );
+ g_object_set( G_OBJECT(act), "icon-property", "iconId", NULL );
+ ege_select_one_action_set_icon_column( act, 2 );
+ ege_select_one_action_set_tooltip_column( act, 1 );
+
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ gint mode = prefs->getInt("/tools/gradient/newgradient", SP_GRADIENT_TYPE_LINEAR) != SP_GRADIENT_TYPE_LINEAR;
+ ege_select_one_action_set_active( act, mode );
+ g_signal_connect_after( G_OBJECT(act), "changed", G_CALLBACK(gr_new_type_changed), holder );
+ }
+ /* New gradient on fill or stroke*/
{
- GtkWidget *button = sp_button_new_from_data( Inkscape::ICON_SIZE_DECORATION,
- SP_BUTTON_TYPE_TOGGLE,
- NULL,
- INKSCAPE_ICON("object-fill"),
- _("Create gradient in the fill"));
- g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (gr_toggle_fillstroke), tbl);
- g_object_set_data(G_OBJECT(tbl), "fill", button);
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
- prefs->getBool("/tools/gradient/newfillorstroke", true));
- gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0);
+ GtkListStore* model = gtk_list_store_new( 3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING );
+
+ GtkTreeIter iter;
+ gtk_list_store_append( model, &iter );
+ gtk_list_store_set( model, &iter,
+ 0, _("fill"), 1, _("Create gradient in the fill"), 2, INKSCAPE_ICON("object-fill"), -1 );
+
+ gtk_list_store_append( model, &iter );
+ gtk_list_store_set( model, &iter,
+ 0, _("stroke"), 1, _("Create gradient in the stroke"), 2, INKSCAPE_ICON("object-stroke"), -1 );
+
+ EgeSelectOneAction* act = ege_select_one_action_new( "GradientNewFillStrokeAction", (""), (""), NULL, GTK_TREE_MODEL(model) );
+ g_object_set( act, "short_label", _("on:"), NULL );
+ gtk_action_group_add_action( mainActions, GTK_ACTION(act) );
+ g_object_set_data( holder, "gradient_new_fillstroke_action", act );
+
+ ege_select_one_action_set_appearance( act, "full" );
+ ege_select_one_action_set_radio_action_type( act, INK_RADIO_ACTION_TYPE );
+ g_object_set( G_OBJECT(act), "icon-property", "iconId", NULL );
+ ege_select_one_action_set_icon_column( act, 2 );
+ ege_select_one_action_set_tooltip_column( act, 1 );
+
+ /// @todo Convert to boolean?
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ bool fillstrokemode = !prefs->getBool("/tools/gradient/newfillorstroke", true);
+ ege_select_one_action_set_active( act, fillstrokemode );
+ g_signal_connect_after( G_OBJECT(act), "changed", G_CALLBACK(gr_new_fillstroke_changed), holder );
}
+
+ /* Gradient Select list*/
{
- GtkWidget *button = sp_button_new_from_data( Inkscape::ICON_SIZE_DECORATION,
- SP_BUTTON_TYPE_TOGGLE,
- NULL,
- INKSCAPE_ICON("object-stroke"),
- _("Create gradient in the stroke"));
- g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (gr_toggle_fillstroke), tbl);
- g_object_set_data(G_OBJECT(tbl), "stroke", button);
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
- !prefs->getBool("/tools/gradient/newfillorstroke", true));
- gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0);
+ GtkListStore *store = gtk_list_store_new (3, G_TYPE_STRING, GDK_TYPE_PIXBUF, G_TYPE_POINTER);
+
+ GtkTreeIter iter;
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter, 0, _("No gradient"), 1, NULL, 2, NULL, -1);
+
+ EgeSelectOneAction* act1 = ege_select_one_action_new( "GradientSelectGradientAction", _("Select"), ("Choose a gradient"), NULL, GTK_TREE_MODEL(store) );
+ g_object_set( act1, "short_label", _("Select:"), NULL );
+ ege_select_one_action_set_appearance( act1, "compact" );
+ gtk_action_set_sensitive( GTK_ACTION(act1), FALSE );
+ g_signal_connect( G_OBJECT(act1), "changed", G_CALLBACK(gr_gradient_combo_changed), desktop );
+ gtk_action_group_add_action( mainActions, GTK_ACTION(act1) );
+ g_object_set_data( holder, "gradient_select_combo_action", act1 );
+
}
- gtk_box_pack_start(GTK_BOX(cvbox), cbox, TRUE, TRUE, 3);
- GtkToolItem *cvbox_toolitem = gtk_tool_item_new();
- gtk_container_add(GTK_CONTAINER(cvbox_toolitem), cvbox);
- gtk_toolbar_insert(GTK_TOOLBAR(tbl), cvbox_toolitem, -1);
+ // Gradient Repeat type
+ {
+ GtkListStore* model = gtk_list_store_new( 2, G_TYPE_STRING, G_TYPE_INT );
+
+ GtkTreeIter iter;
+ gtk_list_store_append( model, &iter );
+ gtk_list_store_set( model, &iter, 0, _("none"), 1, SP_GRADIENT_SPREAD_PAD, -1 );
+
+ gtk_list_store_append( model, &iter );
+ gtk_list_store_set( model, &iter, 0, _("reflected"), 1, SP_GRADIENT_SPREAD_REFLECT, -1 );
+
+ gtk_list_store_append( model, &iter );
+ gtk_list_store_set( model, &iter, 0, _("direct"), 1, SP_GRADIENT_SPREAD_REPEAT, -1 );
+
+ EgeSelectOneAction* act1 = ege_select_one_action_new( "GradientSelectRepeatAction", _("Repeat"),
+ (// 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, GTK_TREE_MODEL(model) );
+ g_object_set( act1, "short_label", _("Repeat:"), NULL );
+ ege_select_one_action_set_appearance( act1, "compact" );
+ gtk_action_set_sensitive( GTK_ACTION(act1), FALSE );
+ g_signal_connect( G_OBJECT(act1), "changed", G_CALLBACK(gr_spread_change), holder );
+ gtk_action_group_add_action( mainActions, GTK_ACTION(act1) );
+ g_object_set_data( holder, "gradient_select_repeat_action", act1 );
}
+ /* Gradient Stop list */
+ {
+ GtkListStore *store = gtk_list_store_new (3, G_TYPE_STRING, GDK_TYPE_PIXBUF, G_TYPE_POINTER);
- sp_toolbox_add_label(tbl, _("<b>Change:</b>"));
+ GtkTreeIter iter;
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter, 0, _("No gradient"), 1, NULL, 2, NULL, -1);
+
+ EgeSelectOneAction* act1 = ege_select_one_action_new( "GradientEditStopsAction", _("Stops"), _("Select a stop for the current gradient"), NULL, GTK_TREE_MODEL(store) );
+ g_object_set( act1, "short_label", _("Edit:"), NULL );
+ ege_select_one_action_set_appearance( act1, "compact" );
+ gtk_action_set_sensitive( GTK_ACTION(act1), FALSE );
+ g_signal_connect( G_OBJECT(act1), "changed", G_CALLBACK(gr_stop_combo_changed), holder );
+ gtk_action_group_add_action( mainActions, GTK_ACTION(act1) );
+ g_object_set_data( holder, "gradient_stops_combo_action", act1 );
+ }
- // TODO replace aux_toolbox_space(tbl, AUX_SPACING);
+ /* Offset */
+ {
+ EgeAdjustmentAction* eact = 0;
+ eact = create_adjustment_action( "GradientEditOffsetAction",
+ _("Offset"), _("Offset:"), _("Offset of selected stop"),
+ "/tools/gradient/stopoffset", 0,
+ GTK_WIDGET(desktop->canvas), NULL/*us*/, holder, FALSE, NULL,
+ 0.0, 1.0, 0.01, 0.1,
+ 0, 0, 0,
+ gr_stop_offset_adjustment_changed
+ , 0.01, 2, 1.0);
+
+ gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
+ g_object_set_data( holder, "offset_action", eact );
+ gtk_action_set_sensitive( GTK_ACTION(eact), FALSE );
+ }
+
+ /* Add stop */
{
- GtkWidget *vectors = gr_change_widget (desktop);
- GtkToolItem *vectors_toolitem = gtk_tool_item_new();
- gtk_container_add(GTK_CONTAINER(vectors_toolitem), vectors);
- gtk_toolbar_insert(GTK_TOOLBAR(tbl), vectors_toolitem, -1);
+ 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), holder );
+ gtk_action_group_add_action( mainActions, GTK_ACTION(inky) );
+ gtk_action_set_sensitive( GTK_ACTION(inky), FALSE );
+ g_object_set_data( holder, "gradient_stops_add_action", inky );
}
- gtk_widget_show_all(tbl);
- sp_set_font_size_smaller (tbl);
+ /* 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), holder );
+ gtk_action_group_add_action( mainActions, GTK_ACTION(inky) );
+ gtk_action_set_sensitive( GTK_ACTION(inky), FALSE );
+ g_object_set_data( holder, "gradient_stops_delete_action", inky );
+ }
- return tbl;
-}
+ /* 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( holder, "gradient_stops_reverse_action", inky );
+
+ }
+ Inkscape::Selection *selection = sp_desktop_selection (desktop);
+ SPDocument *document = sp_desktop_document (desktop);
+ g_object_set_data(holder, "desktop", desktop);
+ // connect to selection modified and changed signals
+ sigc::connection *conn1 = new sigc::connection(
+ selection->connectChanged(sigc::bind(sigc::ptr_fun(&gr_tb_selection_changed), (gpointer) holder)));
+ sigc::connection *conn2 = new sigc::connection(
+ selection->connectModified(sigc::bind(sigc::ptr_fun(&gr_tb_selection_modified), (gpointer) holder)));
+ sigc::connection *conn3 = new sigc::connection(
+ desktop->connectToolSubselectionChanged( sigc::bind(sigc::ptr_fun(&gr_drag_selection_changed), (gpointer) holder)));
+
+ // when holder is destroyed, disconnect
+ g_signal_connect(G_OBJECT(holder), "destroy", G_CALLBACK(gr_disconnect_sigc), conn1);
+ g_signal_connect(G_OBJECT(holder), "destroy", G_CALLBACK(gr_disconnect_sigc), conn2);
+ g_signal_connect(G_OBJECT(holder), "destroy", G_CALLBACK(gr_disconnect_sigc), conn3);
+
+ // connect to release and modified signals of the defs (i.e. when someone changes gradient)
+ sigc::connection *release_connection = new sigc::connection();
+ *release_connection = document->getDefs()->connectRelease(sigc::bind<1>(sigc::ptr_fun(&gr_defs_release), GTK_WIDGET(holder)));
+ sigc::connection *modified_connection = new sigc::connection();
+ *modified_connection = document->getDefs()->connectModified(sigc::bind<2>(sigc::ptr_fun(&gr_defs_modified), GTK_WIDGET(holder)));
+
+ // when holder is destroyed, disconnect
+ g_signal_connect(G_OBJECT(holder), "destroy", G_CALLBACK(gr_disconnect_sigc), release_connection);
+ g_signal_connect(G_OBJECT(holder), "destroy", G_CALLBACK(gr_disconnect_sigc), modified_connection);
+
+}
/*
Local Variables: