From 039408dbad2877c3b75d08f66dddaff17fe3dcf3 Mon Sep 17 00:00:00 2001 From: Alexander Valavanis Date: Sun, 17 Jun 2018 17:00:04 +0100 Subject: Move toolbars to ui/toolbar --- src/ui/CMakeLists.txt | 49 +- src/ui/toolbar/arc-toolbar.cpp | 614 ++++++++ src/ui/toolbar/arc-toolbar.h | 37 + src/ui/toolbar/box3d-toolbar.cpp | 444 ++++++ src/ui/toolbar/box3d-toolbar.h | 38 + src/ui/toolbar/calligraphy-toolbar.cpp | 623 ++++++++ src/ui/toolbar/calligraphy-toolbar.h | 38 + src/ui/toolbar/connector-toolbar.cpp | 450 ++++++ src/ui/toolbar/connector-toolbar.h | 37 + src/ui/toolbar/dropper-toolbar.cpp | 127 ++ src/ui/toolbar/dropper-toolbar.h | 37 + src/ui/toolbar/eraser-toolbar.cpp | 318 ++++ src/ui/toolbar/eraser-toolbar.h | 37 + src/ui/toolbar/gradient-toolbar.cpp | 1274 +++++++++++++++ src/ui/toolbar/gradient-toolbar.h | 22 + src/ui/toolbar/lpe-toolbar.cpp | 452 ++++++ src/ui/toolbar/lpe-toolbar.h | 37 + src/ui/toolbar/measure-toolbar.cpp | 477 ++++++ src/ui/toolbar/measure-toolbar.h | 37 + src/ui/toolbar/mesh-toolbar.cpp | 668 ++++++++ src/ui/toolbar/mesh-toolbar.h | 24 + src/ui/toolbar/node-toolbar.cpp | 656 ++++++++ src/ui/toolbar/node-toolbar.h | 37 + src/ui/toolbar/paintbucket-toolbar.cpp | 260 +++ src/ui/toolbar/paintbucket-toolbar.h | 37 + src/ui/toolbar/pencil-toolbar.cpp | 639 ++++++++ src/ui/toolbar/pencil-toolbar.h | 38 + src/ui/toolbar/rect-toolbar.cpp | 436 ++++++ src/ui/toolbar/rect-toolbar.h | 37 + src/ui/toolbar/select-toolbar.cpp | 616 ++++++++ src/ui/toolbar/select-toolbar.h | 36 + src/ui/toolbar/spiral-toolbar.cpp | 319 ++++ src/ui/toolbar/spiral-toolbar.h | 37 + src/ui/toolbar/spray-toolbar.cpp | 629 ++++++++ src/ui/toolbar/spray-toolbar.h | 37 + src/ui/toolbar/star-toolbar.cpp | 626 ++++++++ src/ui/toolbar/star-toolbar.h | 37 + src/ui/toolbar/text-toolbar.cpp | 2603 ++++++++++++++++++++++++++++++ src/ui/toolbar/text-toolbar.h | 37 + src/ui/toolbar/tweak-toolbar.cpp | 387 +++++ src/ui/toolbar/tweak-toolbar.h | 37 + src/ui/toolbar/zoom-toolbar.cpp | 51 + src/ui/toolbar/zoom-toolbar.h | 37 + src/ui/widget/font-selector-toolbar.cpp | 2 +- src/widgets/CMakeLists.txt | 52 - src/widgets/arc-toolbar.cpp | 615 -------- src/widgets/arc-toolbar.h | 37 - src/widgets/box3d-toolbar.cpp | 444 ------ src/widgets/box3d-toolbar.h | 38 - src/widgets/calligraphy-toolbar.cpp | 623 -------- src/widgets/calligraphy-toolbar.h | 38 - src/widgets/connector-toolbar.cpp | 450 ------ src/widgets/connector-toolbar.h | 37 - src/widgets/dropper-toolbar.cpp | 127 -- src/widgets/dropper-toolbar.h | 37 - src/widgets/eraser-toolbar.cpp | 320 ---- src/widgets/eraser-toolbar.h | 37 - src/widgets/gradient-toolbar.cpp | 1275 --------------- src/widgets/gradient-toolbar.h | 22 - src/widgets/lpe-toolbar.cpp | 453 ------ src/widgets/lpe-toolbar.h | 37 - src/widgets/measure-toolbar.cpp | 477 ------ src/widgets/measure-toolbar.h | 37 - src/widgets/mesh-toolbar.cpp | 669 -------- src/widgets/mesh-toolbar.h | 24 - src/widgets/node-toolbar.cpp | 656 -------- src/widgets/node-toolbar.h | 37 - src/widgets/paintbucket-toolbar.cpp | 260 --- src/widgets/paintbucket-toolbar.h | 37 - src/widgets/pencil-toolbar.cpp | 640 -------- src/widgets/pencil-toolbar.h | 38 - src/widgets/rect-toolbar.cpp | 436 ------ src/widgets/rect-toolbar.h | 37 - src/widgets/select-toolbar.cpp | 616 -------- src/widgets/select-toolbar.h | 36 - src/widgets/spiral-toolbar.cpp | 319 ---- src/widgets/spiral-toolbar.h | 37 - src/widgets/spray-toolbar.cpp | 630 -------- src/widgets/spray-toolbar.h | 37 - src/widgets/star-toolbar.cpp | 627 -------- src/widgets/star-toolbar.h | 37 - src/widgets/text-toolbar.cpp | 2604 ------------------------------- src/widgets/text-toolbar.h | 37 - src/widgets/toolbox.cpp | 42 +- src/widgets/tweak-toolbar.cpp | 387 ----- src/widgets/tweak-toolbar.h | 37 - src/widgets/zoom-toolbar.cpp | 51 - src/widgets/zoom-toolbar.h | 37 - 88 files changed, 13488 insertions(+), 13507 deletions(-) create mode 100644 src/ui/toolbar/arc-toolbar.cpp create mode 100644 src/ui/toolbar/arc-toolbar.h create mode 100644 src/ui/toolbar/box3d-toolbar.cpp create mode 100644 src/ui/toolbar/box3d-toolbar.h create mode 100644 src/ui/toolbar/calligraphy-toolbar.cpp create mode 100644 src/ui/toolbar/calligraphy-toolbar.h create mode 100644 src/ui/toolbar/connector-toolbar.cpp create mode 100644 src/ui/toolbar/connector-toolbar.h create mode 100644 src/ui/toolbar/dropper-toolbar.cpp create mode 100644 src/ui/toolbar/dropper-toolbar.h create mode 100644 src/ui/toolbar/eraser-toolbar.cpp create mode 100644 src/ui/toolbar/eraser-toolbar.h create mode 100644 src/ui/toolbar/gradient-toolbar.cpp create mode 100644 src/ui/toolbar/gradient-toolbar.h create mode 100644 src/ui/toolbar/lpe-toolbar.cpp create mode 100644 src/ui/toolbar/lpe-toolbar.h create mode 100644 src/ui/toolbar/measure-toolbar.cpp create mode 100644 src/ui/toolbar/measure-toolbar.h create mode 100644 src/ui/toolbar/mesh-toolbar.cpp create mode 100644 src/ui/toolbar/mesh-toolbar.h create mode 100644 src/ui/toolbar/node-toolbar.cpp create mode 100644 src/ui/toolbar/node-toolbar.h create mode 100644 src/ui/toolbar/paintbucket-toolbar.cpp create mode 100644 src/ui/toolbar/paintbucket-toolbar.h create mode 100644 src/ui/toolbar/pencil-toolbar.cpp create mode 100644 src/ui/toolbar/pencil-toolbar.h create mode 100644 src/ui/toolbar/rect-toolbar.cpp create mode 100644 src/ui/toolbar/rect-toolbar.h create mode 100644 src/ui/toolbar/select-toolbar.cpp create mode 100644 src/ui/toolbar/select-toolbar.h create mode 100644 src/ui/toolbar/spiral-toolbar.cpp create mode 100644 src/ui/toolbar/spiral-toolbar.h create mode 100644 src/ui/toolbar/spray-toolbar.cpp create mode 100644 src/ui/toolbar/spray-toolbar.h create mode 100644 src/ui/toolbar/star-toolbar.cpp create mode 100644 src/ui/toolbar/star-toolbar.h create mode 100644 src/ui/toolbar/text-toolbar.cpp create mode 100644 src/ui/toolbar/text-toolbar.h create mode 100644 src/ui/toolbar/tweak-toolbar.cpp create mode 100644 src/ui/toolbar/tweak-toolbar.h create mode 100644 src/ui/toolbar/zoom-toolbar.cpp create mode 100644 src/ui/toolbar/zoom-toolbar.h delete mode 100644 src/widgets/arc-toolbar.cpp delete mode 100644 src/widgets/arc-toolbar.h delete mode 100644 src/widgets/box3d-toolbar.cpp delete mode 100644 src/widgets/box3d-toolbar.h delete mode 100644 src/widgets/calligraphy-toolbar.cpp delete mode 100644 src/widgets/calligraphy-toolbar.h delete mode 100644 src/widgets/connector-toolbar.cpp delete mode 100644 src/widgets/connector-toolbar.h delete mode 100644 src/widgets/dropper-toolbar.cpp delete mode 100644 src/widgets/dropper-toolbar.h delete mode 100644 src/widgets/eraser-toolbar.cpp delete mode 100644 src/widgets/eraser-toolbar.h delete mode 100644 src/widgets/gradient-toolbar.cpp delete mode 100644 src/widgets/gradient-toolbar.h delete mode 100644 src/widgets/lpe-toolbar.cpp delete mode 100644 src/widgets/lpe-toolbar.h delete mode 100644 src/widgets/measure-toolbar.cpp delete mode 100644 src/widgets/measure-toolbar.h delete mode 100644 src/widgets/mesh-toolbar.cpp delete mode 100644 src/widgets/mesh-toolbar.h delete mode 100644 src/widgets/node-toolbar.cpp delete mode 100644 src/widgets/node-toolbar.h delete mode 100644 src/widgets/paintbucket-toolbar.cpp delete mode 100644 src/widgets/paintbucket-toolbar.h delete mode 100644 src/widgets/pencil-toolbar.cpp delete mode 100644 src/widgets/pencil-toolbar.h delete mode 100644 src/widgets/rect-toolbar.cpp delete mode 100644 src/widgets/rect-toolbar.h delete mode 100644 src/widgets/select-toolbar.cpp delete mode 100644 src/widgets/select-toolbar.h delete mode 100644 src/widgets/spiral-toolbar.cpp delete mode 100644 src/widgets/spiral-toolbar.h delete mode 100644 src/widgets/spray-toolbar.cpp delete mode 100644 src/widgets/spray-toolbar.h delete mode 100644 src/widgets/star-toolbar.cpp delete mode 100644 src/widgets/star-toolbar.h delete mode 100644 src/widgets/text-toolbar.cpp delete mode 100644 src/widgets/text-toolbar.h delete mode 100644 src/widgets/tweak-toolbar.cpp delete mode 100644 src/widgets/tweak-toolbar.h delete mode 100644 src/widgets/zoom-toolbar.cpp delete mode 100644 src/widgets/zoom-toolbar.h (limited to 'src') diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt index 41c640c68..0374fad15 100644 --- a/src/ui/CMakeLists.txt +++ b/src/ui/CMakeLists.txt @@ -30,6 +30,27 @@ set(ui_SRC tool/selector.cpp tool/transform-handle-set.cpp + toolbar/arc-toolbar.cpp + toolbar/box3d-toolbar.cpp + toolbar/calligraphy-toolbar.cpp + toolbar/connector-toolbar.cpp + toolbar/dropper-toolbar.cpp + toolbar/eraser-toolbar.cpp + toolbar/gradient-toolbar.cpp + toolbar/lpe-toolbar.cpp + toolbar/measure-toolbar.cpp + toolbar/mesh-toolbar.cpp + toolbar/node-toolbar.cpp + toolbar/pencil-toolbar.cpp + toolbar/rect-toolbar.cpp + toolbar/select-toolbar.cpp + toolbar/spiral-toolbar.cpp + toolbar/spray-toolbar.cpp + toolbar/star-toolbar.cpp + toolbar/text-toolbar.cpp + toolbar/tweak-toolbar.cpp + toolbar/zoom-toolbar.cpp + tools/arc-tool.cpp tools/box3d-tool.cpp tools/calligraphic-tool.cpp @@ -117,7 +138,7 @@ set(ui_SRC dialog/transformation.cpp dialog/undo-history.cpp dialog/xml-tree.cpp - dialog/save-template-dialog.cpp + dialog/save-template-dialog.cpp widget/addtoicon.cpp widget/alignment-selector.cpp @@ -271,7 +292,7 @@ set(ui_SRC dialog/transformation.h dialog/undo-history.h dialog/xml-tree.h - dialog/save-template-dialog.h + dialog/save-template-dialog.h tool/commit-events.h tool/control-point-selection.h @@ -289,6 +310,27 @@ set(ui_SRC tool/shape-record.h tool/transform-handle-set.h + toolbar/arc-toolbar.h + toolbar/box3d-toolbar.h + toolbar/calligraphy-toolbar.h + toolbar/connector-toolbar.h + toolbar/dropper-toolbar.h + toolbar/eraser-toolbar.h + toolbar/gradient-toolbar.h + toolbar/lpe-toolbar.h + toolbar/measure-toolbar.h + toolbar/mesh-toolbar.h + toolbar/node-toolbar.h + toolbar/pencil-toolbar.h + toolbar/rect-toolbar.h + toolbar/select-toolbar.h + toolbar/spiral-toolbar.h + toolbar/spray-toolbar.h + toolbar/star-toolbar.h + toolbar/text-toolbar.h + toolbar/tweak-toolbar.h + toolbar/zoom-toolbar.h + tools/arc-tool.h tools/box3d-tool.h tools/calligraphic-tool.h @@ -387,7 +429,6 @@ if(WIN32) ) endif() -# add_inkscape_lib(ui_LIB "${ui_SRC}") add_inkscape_source("${ui_SRC}") set ( ui_flood_and_trace_SRC @@ -395,6 +436,8 @@ set ( ui_flood_and_trace_SRC tools/flood-tool.cpp dialog/tracedialog.cpp dialog/tracedialog.h + toolbar/paintbucket-toolbar.cpp + toolbar/paintbucket-toolbar.h ) if ("${HAVE_POTRACE}") diff --git a/src/ui/toolbar/arc-toolbar.cpp b/src/ui/toolbar/arc-toolbar.cpp new file mode 100644 index 000000000..ad1b70a6c --- /dev/null +++ b/src/ui/toolbar/arc-toolbar.cpp @@ -0,0 +1,614 @@ +/** + * @file + * Arc aux toolbar + */ +/* Authors: + * MenTaLguY + * Lauris Kaplinski + * bulia byak + * Frank Felfe + * John Cliff + * David Turner + * Josh Andler + * Jon A. Cruz + * Maximilian Albert + * Tavmjong Bah + * Abhishek Sharma + * Kris De Gussem + * + * Copyright (C) 2004 David Turner + * Copyright (C) 2003 MenTaLguY + * Copyright (C) 1999-2011 authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "arc-toolbar.h" + +#include + +#include "desktop.h" +#include "document-undo.h" +#include "widgets/ink-action.h" +#include "widgets/toolbox.h" +#include "mod360.h" +#include "selection.h" +#include "verbs.h" + +#include "object/sp-ellipse.h" + +#include "ui/icon-names.h" +#include "ui/tools/arc-tool.h" +#include "ui/uxmanager.h" +#include "ui/widget/ink-select-one-action.h" +#include "ui/widget/unit-tracker.h" + +#include "widgets/ege-adjustment-action.h" +#include "widgets/ege-output-action.h" +#include "widgets/spinbutton-events.h" +#include "widgets/widget-sizes.h" + +#include "xml/node-event-vector.h" + +using Inkscape::UI::Widget::UnitTracker; +using Inkscape::UI::UXManager; +using Inkscape::DocumentUndo; +using Inkscape::UI::ToolboxFactory; +using Inkscape::UI::PrefPusher; +using Inkscape::Util::Quantity; +using Inkscape::Util::unit_table; + +//######################## +//## Circle / Arc ## +//######################## + +static void sp_arctb_sensitivize( GObject *tbl, double v1, double v2 ) +{ + Gtk::Action *ocb = static_cast( g_object_get_data( tbl, "type_action" ) ); + GtkAction *make_whole = GTK_ACTION( g_object_get_data( tbl, "make_whole" ) ); + + if (v1 == 0 && v2 == 0) { + if (g_object_get_data( tbl, "single" )) { // only for a single selected ellipse (for now) + ocb->set_sensitive(false); + gtk_action_set_sensitive( make_whole, FALSE ); + } + } else { + ocb->set_sensitive(true); + gtk_action_set_sensitive( make_whole, TRUE ); + } +} + +static void sp_arctb_value_changed(GtkAdjustment *adj, GObject *tbl, gchar const *value_name) +{ + // Per SVG spec "a [radius] value of zero disables rendering of the element". + // However our implementation does not allow a setting of zero in the UI (not even in the XML editor) + // and ugly things happen if it's forced here, so better leave the properties untouched. + if (!gtk_adjustment_get_value(adj)) { + return; + } + + SPDesktop *desktop = static_cast(g_object_get_data( tbl, "desktop" )); + + UnitTracker* tracker = reinterpret_cast(g_object_get_data( tbl, "tracker" )); + Unit const *unit = tracker->getActiveUnit(); + g_return_if_fail(unit != NULL); + + SPDocument* document = desktop->getDocument(); + Geom::Scale scale = document->getDocumentScale(); + + if (DocumentUndo::getUndoSensitive(document)) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble(Glib::ustring("/tools/shapes/arc/") + value_name, + Quantity::convert(gtk_adjustment_get_value(adj), unit, "px")); + } + + // quit if run by the attr_changed listener + if (g_object_get_data( tbl, "freeze" ) || tracker->isUpdating()) { + return; + } + + // in turn, prevent listener from responding + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE)); + + bool modmade = false; + Inkscape::Selection *selection = desktop->getSelection(); + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ + SPItem *item = *i; + if (SP_IS_GENERICELLIPSE(item)) { + + SPGenericEllipse *ge = SP_GENERICELLIPSE(item); + + if (!strcmp(value_name, "rx")) { + ge->setVisibleRx(Quantity::convert(gtk_adjustment_get_value(adj), unit, "px")); + } else { + ge->setVisibleRy(Quantity::convert(gtk_adjustment_get_value(adj), unit, "px")); + } + + ge->normalize(); + (SP_OBJECT(ge))->updateRepr(); + (SP_OBJECT(ge))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + + modmade = true; + } + } + + if (modmade) { + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_ARC, + _("Ellipse: Change radius")); + } + + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); +} + +static void sp_arctb_rx_value_changed(GtkAdjustment *adj, GObject *tbl) +{ + sp_arctb_value_changed(adj, tbl, "rx"); +} + +static void sp_arctb_ry_value_changed(GtkAdjustment *adj, GObject *tbl) +{ + sp_arctb_value_changed(adj, tbl, "ry"); +} + +static void +sp_arctb_startend_value_changed(GtkAdjustment *adj, GObject *tbl, gchar const *value_name, gchar const *other_name) +{ + SPDesktop *desktop = static_cast(g_object_get_data( tbl, "desktop" )); + + if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble(Glib::ustring("/tools/shapes/arc/") + value_name, gtk_adjustment_get_value(adj)); + } + + // quit if run by the attr_changed listener + if (g_object_get_data( tbl, "freeze" )) { + return; + } + + // in turn, prevent listener from responding + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); + + gchar* namespaced_name = g_strconcat("sodipodi:", value_name, NULL); + + bool modmade = false; + auto itemlist= desktop->getSelection()->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ + SPItem *item = *i; + if (SP_IS_GENERICELLIPSE(item)) { + + SPGenericEllipse *ge = SP_GENERICELLIPSE(item); + + if (!strcmp(value_name, "start")) { + ge->start = (gtk_adjustment_get_value(adj) * M_PI)/ 180; + } else { + ge->end = (gtk_adjustment_get_value(adj) * M_PI)/ 180; + } + + ge->normalize(); + (SP_OBJECT(ge))->updateRepr(); + (SP_OBJECT(ge))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + + modmade = true; + } + } + + g_free(namespaced_name); + + GtkAdjustment *other = GTK_ADJUSTMENT( g_object_get_data( tbl, other_name ) ); + + sp_arctb_sensitivize( tbl, gtk_adjustment_get_value(adj), gtk_adjustment_get_value(other) ); + + if (modmade) { + DocumentUndo::maybeDone(desktop->getDocument(), value_name, SP_VERB_CONTEXT_ARC, + _("Arc: Change start/end")); + } + + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); +} + + +static void sp_arctb_start_value_changed(GtkAdjustment *adj, GObject *tbl) +{ + sp_arctb_startend_value_changed(adj, tbl, "start", "end"); +} + +static void sp_arctb_end_value_changed(GtkAdjustment *adj, GObject *tbl) +{ + sp_arctb_startend_value_changed(adj, tbl, "end", "start"); +} + + +static void sp_arctb_type_changed( GObject *tbl, int type ) +{ + SPDesktop *desktop = static_cast(g_object_get_data( tbl, "desktop" )); + if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setInt("/tools/shapes/arc/arc_type", type); + } + + // quit if run by the attr_changed listener + if (g_object_get_data( tbl, "freeze" )) { + return; + } + + // in turn, prevent listener from responding + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); + + Glib::ustring arc_type = "slice"; + bool open = false; + switch (type) { + case 0: + arc_type = "slice"; + open = false; + break; + case 1: + arc_type = "arc"; + open = true; + break; + case 2: + arc_type = "chord"; + open = true; // For backward compat, not truly open but chord most like arc. + break; + default: + std::cerr << "sp_arctb_type_changed: bad arc type: " << type << std::endl; + } + + bool modmade = false; + auto itemlist= desktop->getSelection()->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ + SPItem *item = *i; + if (SP_IS_GENERICELLIPSE(item)) { + Inkscape::XML::Node *repr = item->getRepr(); + repr->setAttribute("sodipodi:open", (open?"true":NULL) ); + repr->setAttribute("sodipodi:arc-type", arc_type.c_str()); + item->updateRepr(); + modmade = true; + } + } + + if (modmade) { + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_ARC, + _("Arc: Changed arc type")); + } + + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); +} + +static void sp_arctb_defaults(GtkWidget *, GObject *obj) +{ + GtkAdjustment *adj; + + adj = GTK_ADJUSTMENT( g_object_get_data(obj, "start") ); + gtk_adjustment_set_value(adj, 0.0); + +#if !GTK_CHECK_VERSION(3,18,0) + gtk_adjustment_value_changed(adj); +#endif + + adj = GTK_ADJUSTMENT( g_object_get_data(obj, "end") ); + gtk_adjustment_set_value(adj, 0.0); + +#if !GTK_CHECK_VERSION(3,18,0) + gtk_adjustment_value_changed(adj); +#endif + + spinbutton_defocus(GTK_WIDGET(obj)); +} + +static void arc_tb_event_attr_changed(Inkscape::XML::Node *repr, gchar const * /*name*/, + gchar const * /*old_value*/, gchar const * /*new_value*/, + bool /*is_interactive*/, gpointer data) +{ + GObject *tbl = G_OBJECT(data); + + // quit if run by the _changed callbacks + if (g_object_get_data( tbl, "freeze" )) { + return; + } + + // in turn, prevent callbacks from responding + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); + + gpointer item = g_object_get_data( tbl, "item" ); + if (item && SP_IS_GENERICELLIPSE(item)) { + SPGenericEllipse *ge = SP_GENERICELLIPSE(item); + + UnitTracker* tracker = reinterpret_cast( g_object_get_data( tbl, "tracker" ) ); + Unit const *unit = tracker->getActiveUnit(); + g_return_if_fail(unit != NULL); + + GtkAdjustment *adj; + adj = GTK_ADJUSTMENT( g_object_get_data(tbl, "rx") ); + gdouble rx = ge->getVisibleRx(); + gtk_adjustment_set_value(adj, Quantity::convert(rx, "px", unit)); + +#if !GTK_CHECK_VERSION(3,18,0) + gtk_adjustment_value_changed(adj); +#endif + + adj = GTK_ADJUSTMENT( g_object_get_data(tbl, "ry") ); + gdouble ry = ge->getVisibleRy(); + gtk_adjustment_set_value(adj, Quantity::convert(ry, "px", unit)); + +#if !GTK_CHECK_VERSION(3,18,0) + gtk_adjustment_value_changed(adj); +#endif + } + + gdouble start = 0.; + gdouble end = 0.; + sp_repr_get_double(repr, "sodipodi:start", &start); + sp_repr_get_double(repr, "sodipodi:end", &end); + + GtkAdjustment *adj1,*adj2; + adj1 = GTK_ADJUSTMENT( g_object_get_data( tbl, "start" ) ); + gtk_adjustment_set_value(adj1, mod360((start * 180)/M_PI)); + adj2 = GTK_ADJUSTMENT( g_object_get_data( tbl, "end" ) ); + gtk_adjustment_set_value(adj2, mod360((end * 180)/M_PI)); + + sp_arctb_sensitivize( tbl, gtk_adjustment_get_value(adj1), gtk_adjustment_get_value(adj2) ); + + char const *arctypestr = NULL; + arctypestr = repr->attribute("sodipodi:arc-type"); + if (!arctypestr) { // For old files. + char const *openstr = NULL; + openstr = repr->attribute("sodipodi:open"); + arctypestr = (openstr ? "arc" : "slice"); + } + + InkSelectOneAction *typeAction = + static_cast( g_object_get_data( tbl, "type_action" ) ); + + if (!strcmp(arctypestr,"slice")) { + typeAction->set_active( 0 ); + } else if (!strcmp(arctypestr,"arc")) { + typeAction->set_active( 1 ); + } else { + typeAction->set_active( 2 ); + } + + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); +} + +static Inkscape::XML::NodeEventVector arc_tb_repr_events = { + NULL, /* child_added */ + NULL, /* child_removed */ + arc_tb_event_attr_changed, + NULL, /* content_changed */ + NULL /* order_changed */ +}; + + +static void sp_arc_toolbox_selection_changed(Inkscape::Selection *selection, GObject *tbl) +{ + int n_selected = 0; + Inkscape::XML::Node *repr = NULL; + SPItem *item = NULL; + + if ( g_object_get_data( tbl, "repr" ) ) { + g_object_set_data( tbl, "item", NULL ); + } + purge_repr_listener( tbl, tbl ); + + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ + if (SP_IS_GENERICELLIPSE(*i)) { + n_selected++; + item = *i; + repr = item->getRepr(); + } + } + + EgeOutputAction* act = EGE_OUTPUT_ACTION( g_object_get_data( tbl, "mode_action" ) ); + + g_object_set_data( tbl, "single", GINT_TO_POINTER(FALSE) ); + if (n_selected == 0) { + g_object_set( G_OBJECT(act), "label", _("New:"), NULL ); + } else if (n_selected == 1) { + g_object_set_data( tbl, "single", GINT_TO_POINTER(TRUE) ); + g_object_set( G_OBJECT(act), "label", _("Change:"), NULL ); + + GtkAction* rx = GTK_ACTION( g_object_get_data( tbl, "rx_action" ) ); + gtk_action_set_sensitive(rx, TRUE); + GtkAction* ry = GTK_ACTION( g_object_get_data( tbl, "ry_action" ) ); + gtk_action_set_sensitive(ry, TRUE); + + if (repr) { + g_object_set_data( tbl, "repr", repr ); + g_object_set_data( tbl, "item", item ); + Inkscape::GC::anchor(repr); + sp_repr_add_listener(repr, &arc_tb_repr_events, tbl); + sp_repr_synthesize_events(repr, &arc_tb_repr_events, tbl); + } + } else { + // FIXME: implement averaging of all parameters for multiple selected + //gtk_label_set_markup(GTK_LABEL(l), _("Average:")); + g_object_set( G_OBJECT(act), "label", _("Change:"), NULL ); + sp_arctb_sensitivize( tbl, 1, 0 ); + } +} + +static void arc_toolbox_check_ec(SPDesktop* dt, Inkscape::UI::Tools::ToolBase* ec, GObject* holder); + +void sp_arc_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + + EgeAdjustmentAction* eact = 0; + GtkIconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1); + + UnitTracker* tracker = new UnitTracker(Inkscape::Util::UNIT_TYPE_LINEAR); + tracker->setActiveUnit(unit_table.getUnit("px")); + g_object_set_data( holder, "tracker", tracker ); + + { + EgeOutputAction* act = ege_output_action_new( "ArcStateAction", _("New:"), "", 0 ); + ege_output_action_set_use_markup( act, TRUE ); + gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); + g_object_set_data( holder, "mode_action", act ); + } + + /* Radius X */ + { + gchar const* labels[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + gdouble values[] = {1, 2, 3, 5, 10, 20, 50, 100, 200, 500}; + eact = create_adjustment_action( "ArcRadiusXAction", + _("Horizontal radius"), _("Rx:"), _("Horizontal radius of the circle, ellipse, or arc"), + "/tools/shapes/arc/rx", 0, + GTK_WIDGET(desktop->canvas), holder, TRUE, "altx-arc", + 0, 1e6, SPIN_STEP, SPIN_PAGE_STEP, + labels, values, G_N_ELEMENTS(labels), + sp_arctb_rx_value_changed, tracker); + g_object_set_data( holder, "rx_action", eact ); + gtk_action_set_sensitive( GTK_ACTION(eact), FALSE ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + } + + /* Radius Y */ + { + gchar const* labels[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + gdouble values[] = {1, 2, 3, 5, 10, 20, 50, 100, 200, 500}; + eact = create_adjustment_action( "ArcRadiusYAction", + _("Vertical radius"), _("Ry:"), _("Vertical radius of the circle, ellipse, or arc"), + "/tools/shapes/arc/ry", 0, + GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, + 0, 1e6, SPIN_STEP, SPIN_PAGE_STEP, + labels, values, G_N_ELEMENTS(labels), + sp_arctb_ry_value_changed, tracker); + g_object_set_data( holder, "ry_action", eact ); + gtk_action_set_sensitive( GTK_ACTION(eact), FALSE ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + } + + // add the units menu + { + Gtk::Action* act = tracker->createAction( "ArcUnitsAction", _("Units"), ("") ); + gtk_action_group_add_action( mainActions, act->gobj() ); + } + + /* Start */ + { + eact = create_adjustment_action( "ArcStartAction", + _("Start"), _("Start:"), + _("The angle (in degrees) from the horizontal to the arc's start point"), + "/tools/shapes/arc/start", 0.0, + GTK_WIDGET(desktop->canvas), holder, TRUE, "altx-arc", + -360.0, 360.0, 1.0, 10.0, + 0, 0, 0, + sp_arctb_start_value_changed); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + } + + /* End */ + { + eact = create_adjustment_action( "ArcEndAction", + _("End"), _("End:"), + _("The angle (in degrees) from the horizontal to the arc's end point"), + "/tools/shapes/arc/end", 0.0, + GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, + -360.0, 360.0, 1.0, 10.0, + 0, 0, 0, + sp_arctb_end_value_changed); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + } + + /* Arc: Slice, Arc, Chord */ + { + InkSelectOneActionColumns columns; + + Glib::RefPtr store = Gtk::ListStore::create(columns); + + Gtk::TreeModel::Row row; + + row = *(store->append()); + row[columns.col_label ] = _("Slice"); + row[columns.col_tooltip ] = _("Switch to slice (closed shape with two radii)"), + row[columns.col_icon ] = INKSCAPE_ICON("draw-ellipse-segment"); + row[columns.col_sensitive] = true; + + row = *(store->append()); + row[columns.col_label ] = _("Arc (Open)"); + row[columns.col_tooltip ] = _("Switch to arc (unclosed shape)"); + row[columns.col_icon ] = INKSCAPE_ICON("draw-ellipse-arc"); + row[columns.col_sensitive] = true; + + row = *(store->append()); + row[columns.col_label ] = _("Chord"); + row[columns.col_tooltip ] = _("Switch to chord (closed shape)"), + row[columns.col_icon ] = INKSCAPE_ICON("draw-ellipse-chord"); + row[columns.col_sensitive] = true; + + InkSelectOneAction* act = + InkSelectOneAction::create( "ArcTypeAction", // Name + "", // Label + "", // Tooltip + "Not Used", // Icon + store ); // Tree store + + act->use_radio( true ); + act->use_group_label( false ); + gint type = prefs->getInt("/tools/shapes/arc/arc_type", 0); + act->set_active( type ); + + gtk_action_group_add_action( mainActions, GTK_ACTION( act->gobj() )); + g_object_set_data( holder, "type_action", act ); + + act->signal_changed().connect(sigc::bind<0>(sigc::ptr_fun(&sp_arctb_type_changed), holder)); + } + + /* Make Whole */ + { + InkAction* inky = ink_action_new( "ArcResetAction", + _("Make whole"), + _("Make the shape a whole ellipse, not arc or segment"), + INKSCAPE_ICON("draw-ellipse-whole"), + secondarySize ); + g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_arctb_defaults), holder ); + gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); + gtk_action_set_sensitive( GTK_ACTION(inky), TRUE ); + g_object_set_data( holder, "make_whole", inky ); + } + + g_object_set_data( G_OBJECT(holder), "single", GINT_TO_POINTER(TRUE) ); + // sensitivize make whole and open checkbox + { + GtkAdjustment *adj1 = GTK_ADJUSTMENT( g_object_get_data( holder, "start" ) ); + GtkAdjustment *adj2 = GTK_ADJUSTMENT( g_object_get_data( holder, "end" ) ); + sp_arctb_sensitivize( holder, gtk_adjustment_get_value(adj1), gtk_adjustment_get_value(adj2) ); + } + + desktop->connectEventContextChanged(sigc::bind(sigc::ptr_fun(arc_toolbox_check_ec), holder)); + g_signal_connect( holder, "destroy", G_CALLBACK(purge_repr_listener), holder ); +} + +static void arc_toolbox_check_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolBase* ec, GObject* holder) +{ + static sigc::connection changed; + + if (SP_IS_ARC_CONTEXT(ec)) { + changed = desktop->getSelection()->connectChanged(sigc::bind(sigc::ptr_fun(sp_arc_toolbox_selection_changed), holder)); + sp_arc_toolbox_selection_changed(desktop->getSelection(), holder); + } else { + if (changed) { + changed.disconnect(); + purge_repr_listener(NULL, holder); + } + } +} + +/* + 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:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/toolbar/arc-toolbar.h b/src/ui/toolbar/arc-toolbar.h new file mode 100644 index 000000000..ca1319631 --- /dev/null +++ b/src/ui/toolbar/arc-toolbar.h @@ -0,0 +1,37 @@ +#ifndef SEEN_ARC_TOOLBAR_H +#define SEEN_ARC_TOOLBAR_H + +/** + * @file + * 3d box aux toolbar + */ +/* Authors: + * MenTaLguY + * Lauris Kaplinski + * bulia byak + * Frank Felfe + * John Cliff + * David Turner + * Josh Andler + * Jon A. Cruz + * Maximilian Albert + * Tavmjong Bah + * Abhishek Sharma + * Kris De Gussem + * + * Copyright (C) 2004 David Turner + * Copyright (C) 2003 MenTaLguY + * Copyright (C) 1999-2011 authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +class SPDesktop; + +typedef struct _GtkActionGroup GtkActionGroup; +typedef struct _GObject GObject; + +void sp_arc_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); + +#endif /* !SEEN_ARC_TOOLBAR_H */ diff --git a/src/ui/toolbar/box3d-toolbar.cpp b/src/ui/toolbar/box3d-toolbar.cpp new file mode 100644 index 000000000..846aea59d --- /dev/null +++ b/src/ui/toolbar/box3d-toolbar.cpp @@ -0,0 +1,444 @@ +/** + * @file + * 3d box aux toolbar + */ +/* Authors: + * MenTaLguY + * Lauris Kaplinski + * bulia byak + * Frank Felfe + * John Cliff + * David Turner + * Josh Andler + * Jon A. Cruz + * Maximilian Albert + * Tavmjong Bah + * Abhishek Sharma + * Kris De Gussem + * + * Copyright (C) 2004 David Turner + * Copyright (C) 2003 MenTaLguY + * Copyright (C) 1999-2011 authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +#include "box3d-toolbar.h" + +#include "desktop.h" +#include "document-undo.h" +#include "document.h" +#include "inkscape.h" +#include "widgets/toolbox.h" +#include "verbs.h" + +#include "object/box3d.h" +#include "object/persp3d.h" + +#include "ui/icon-names.h" +#include "ui/tools/box3d-tool.h" +#include "ui/uxmanager.h" + +#include "widgets/ege-adjustment-action.h" +#include "widgets/ink-toggle-action.h" + +#include "xml/node-event-vector.h" + +using Inkscape::UI::UXManager; +using Inkscape::DocumentUndo; +using Inkscape::UI::ToolboxFactory; +using Inkscape::UI::PrefPusher; + +//######################## +//## 3D Box ## +//######################## + +// normalize angle so that it lies in the interval [0,360] +static double box3d_normalize_angle (double a) { + double angle = a + ((int) (a/360.0))*360; + if (angle < 0) { + angle += 360.0; + } + return angle; +} + +static void box3d_set_button_and_adjustment(Persp3D *persp, + Proj::Axis axis, + GtkAdjustment *adj, + GtkAction *act, + GtkToggleAction *tact) +{ + // TODO: Take all selected perspectives into account but don't touch the state button if not all of them + // have the same state (otherwise a call to box3d_vp_z_state_changed() is triggered and the states + // are reset). + bool is_infinite = !persp3d_VP_is_finite(persp->perspective_impl, axis); + + if (is_infinite) { + gtk_toggle_action_set_active(tact, TRUE); + gtk_action_set_sensitive(act, TRUE); + + double angle = persp3d_get_infinite_angle(persp, axis); + if (angle != Geom::infinity()) { // FIXME: We should catch this error earlier (don't show the spinbutton at all) + gtk_adjustment_set_value(adj, box3d_normalize_angle(angle)); + } + } else { + gtk_toggle_action_set_active(tact, FALSE); + gtk_action_set_sensitive(act, FALSE); + } +} + +static void box3d_resync_toolbar(Inkscape::XML::Node *persp_repr, GObject *data) +{ + if (!persp_repr) { + g_print ("No perspective given to box3d_resync_toolbar().\n"); + return; + } + + GtkWidget *tbl = GTK_WIDGET(data); + GtkAdjustment *adj = 0; + GtkAction *act = 0; + GtkToggleAction *tact = 0; + Persp3D *persp = persp3d_get_from_repr(persp_repr); + if (!persp) { + // Hmm, is it an error if this happens? + return; + } + { + adj = GTK_ADJUSTMENT(g_object_get_data(G_OBJECT(tbl), "box3d_angle_x")); + act = GTK_ACTION(g_object_get_data(G_OBJECT(tbl), "box3d_angle_x_action")); + tact = &INK_TOGGLE_ACTION(g_object_get_data(G_OBJECT(tbl), "box3d_vp_x_state_action"))->action; + + box3d_set_button_and_adjustment(persp, Proj::X, adj, act, tact); + } + { + adj = GTK_ADJUSTMENT(g_object_get_data(G_OBJECT(tbl), "box3d_angle_y")); + act = GTK_ACTION(g_object_get_data(G_OBJECT(tbl), "box3d_angle_y_action")); + tact = &INK_TOGGLE_ACTION(g_object_get_data(G_OBJECT(tbl), "box3d_vp_y_state_action"))->action; + + box3d_set_button_and_adjustment(persp, Proj::Y, adj, act, tact); + } + { + adj = GTK_ADJUSTMENT(g_object_get_data(G_OBJECT(tbl), "box3d_angle_z")); + act = GTK_ACTION(g_object_get_data(G_OBJECT(tbl), "box3d_angle_z_action")); + tact = &INK_TOGGLE_ACTION(g_object_get_data(G_OBJECT(tbl), "box3d_vp_z_state_action"))->action; + + box3d_set_button_and_adjustment(persp, Proj::Z, adj, act, tact); + } +} + +static void box3d_persp_tb_event_attr_changed(Inkscape::XML::Node *repr, + gchar const * /*name*/, + gchar const * /*old_value*/, + gchar const * /*new_value*/, + bool /*is_interactive*/, + gpointer data) +{ + GtkWidget *tbl = GTK_WIDGET(data); + + // quit if run by the attr_changed or selection changed listener + if (g_object_get_data(G_OBJECT(tbl), "freeze")) { + return; + } + + // set freeze so that it can be caught in box3d_angle_z_value_changed() (to avoid calling + // SPDocumentUndo::maybeDone() when the document is undo insensitive) + g_object_set_data(G_OBJECT(tbl), "freeze", GINT_TO_POINTER(TRUE)); + + // TODO: Only update the appropriate part of the toolbar +// if (!strcmp(name, "inkscape:vp_z")) { + box3d_resync_toolbar(repr, G_OBJECT(tbl)); +// } + + Persp3D *persp = persp3d_get_from_repr(repr); + persp3d_update_box_reprs(persp); + + g_object_set_data(G_OBJECT(tbl), "freeze", GINT_TO_POINTER(FALSE)); +} + +static Inkscape::XML::NodeEventVector box3d_persp_tb_repr_events = +{ + NULL, /* child_added */ + NULL, /* child_removed */ + box3d_persp_tb_event_attr_changed, + NULL, /* content_changed */ + NULL /* order_changed */ +}; + +/** + * \param selection Should not be NULL. + */ +// FIXME: This should rather be put into persp3d-reference.cpp or something similar so that it reacts upon each +// Change of the perspective, and not of the current selection (but how to refer to the toolbar then?) +static void box3d_toolbox_selection_changed(Inkscape::Selection *selection, GObject *tbl) +{ + // Here the following should be done: If all selected boxes have finite VPs in a certain direction, + // disable the angle entry fields for this direction (otherwise entering a value in them should only + // update the perspectives with infinite VPs and leave the other ones untouched). + + Inkscape::XML::Node *persp_repr = NULL; + purge_repr_listener(tbl, tbl); + + SPItem *item = selection->singleItem(); + SPBox3D *box = dynamic_cast(item); + if (box) { + // FIXME: Also deal with multiple selected boxes + Persp3D *persp = box3d_get_perspective(box); + persp_repr = persp->getRepr(); + if (persp_repr) { + g_object_set_data(tbl, "repr", persp_repr); + Inkscape::GC::anchor(persp_repr); + sp_repr_add_listener(persp_repr, &box3d_persp_tb_repr_events, tbl); + sp_repr_synthesize_events(persp_repr, &box3d_persp_tb_repr_events, tbl); + + SP_ACTIVE_DOCUMENT->setCurrentPersp3D(persp3d_get_from_repr(persp_repr)); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setString("/tools/shapes/3dbox/persp", persp_repr->attribute("id")); + + g_object_set_data(tbl, "freeze", GINT_TO_POINTER(TRUE)); + box3d_resync_toolbar(persp_repr, tbl); + g_object_set_data(tbl, "freeze", GINT_TO_POINTER(FALSE)); + } + } +} + +static void box3d_angle_value_changed(GtkAdjustment *adj, GObject *dataKludge, Proj::Axis axis) +{ + SPDesktop *desktop = static_cast(g_object_get_data( dataKludge, "desktop" )); + SPDocument *document = desktop->getDocument(); + + // quit if run by the attr_changed or selection changed listener + if (g_object_get_data( dataKludge, "freeze" )) { + return; + } + + // in turn, prevent listener from responding + g_object_set_data(dataKludge, "freeze", GINT_TO_POINTER(TRUE)); + + std::list sel_persps = desktop->getSelection()->perspList(); + if (sel_persps.empty()) { + // this can happen when the document is created; we silently ignore it + return; + } + Persp3D *persp = sel_persps.front(); + + persp->perspective_impl->tmat.set_infinite_direction (axis, + gtk_adjustment_get_value(adj)); + persp->updateRepr(); + + // TODO: use the correct axis here, too + DocumentUndo::maybeDone(document, "perspangle", SP_VERB_CONTEXT_3DBOX, _("3D Box: Change perspective (angle of infinite axis)")); + + g_object_set_data( dataKludge, "freeze", GINT_TO_POINTER(FALSE) ); +} + + +static void box3d_angle_x_value_changed(GtkAdjustment *adj, GObject *dataKludge) +{ + box3d_angle_value_changed(adj, dataKludge, Proj::X); +} + +static void box3d_angle_y_value_changed(GtkAdjustment *adj, GObject *dataKludge) +{ + box3d_angle_value_changed(adj, dataKludge, Proj::Y); +} + +static void box3d_angle_z_value_changed(GtkAdjustment *adj, GObject *dataKludge) +{ + box3d_angle_value_changed(adj, dataKludge, Proj::Z); +} + + +static void box3d_vp_state_changed( GtkToggleAction *act, GtkAction * /*box3d_angle*/, Proj::Axis axis ) +{ + // TODO: Take all selected perspectives into account + std::list sel_persps = SP_ACTIVE_DESKTOP->getSelection()->perspList(); + if (sel_persps.empty()) { + // this can happen when the document is created; we silently ignore it + return; + } + Persp3D *persp = sel_persps.front(); + + bool set_infinite = gtk_toggle_action_get_active(act); + persp3d_set_VP_state (persp, axis, set_infinite ? Proj::VP_INFINITE : Proj::VP_FINITE); +} + +static void box3d_vp_x_state_changed( GtkToggleAction *act, GtkAction *box3d_angle ) +{ + box3d_vp_state_changed(act, box3d_angle, Proj::X); +} + +static void box3d_vp_y_state_changed( GtkToggleAction *act, GtkAction *box3d_angle ) +{ + box3d_vp_state_changed(act, box3d_angle, Proj::Y); +} + +static void box3d_vp_z_state_changed( GtkToggleAction *act, GtkAction *box3d_angle ) +{ + box3d_vp_state_changed(act, box3d_angle, Proj::Z); +} + +static void box3d_toolbox_check_ec(SPDesktop* dt, Inkscape::UI::Tools::ToolBase* ec, GObject* holder); + +void box3d_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + EgeAdjustmentAction* eact = 0; + SPDocument *document = desktop->getDocument(); + Persp3DImpl *persp_impl = document->getCurrentPersp3DImpl(); + + EgeAdjustmentAction* box3d_angle_x = 0; + EgeAdjustmentAction* box3d_angle_y = 0; + EgeAdjustmentAction* box3d_angle_z = 0; + + /* Angle X */ + { + gchar const* labels[] = { 0, 0, 0, 0, 0, 0, 0 }; + gdouble values[] = {-90, -60, -30, 0, 30, 60, 90}; + eact = create_adjustment_action( "3DBoxAngleXAction", + _("Angle in X direction"), _("Angle X:"), + // Translators: PL is short for 'perspective line' + _("Angle of PLs in X direction"), + "/tools/shapes/3dbox/box3d_angle_x", 30, + GTK_WIDGET(desktop->canvas), holder, TRUE, "altx-box3d", + -360.0, 360.0, 1.0, 10.0, + labels, values, G_N_ELEMENTS(labels), + box3d_angle_x_value_changed ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + g_object_set_data( holder, "box3d_angle_x_action", eact ); + box3d_angle_x = eact; + } + + if (!persp_impl || !persp3d_VP_is_finite(persp_impl, Proj::X)) { + gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); + } else { + gtk_action_set_sensitive( GTK_ACTION(eact), FALSE ); + } + + + /* VP X state */ + { + InkToggleAction* act = ink_toggle_action_new( "3DBoxVPXStateAction", + // Translators: VP is short for 'vanishing point' + _("State of VP in X direction"), + _("Toggle VP in X direction between 'finite' and 'infinite' (=parallel)"), + INKSCAPE_ICON("perspective-parallel"), + GTK_ICON_SIZE_MENU ); + gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); + g_object_set_data( holder, "box3d_vp_x_state_action", act ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(box3d_vp_x_state_changed), box3d_angle_x ); + gtk_action_set_sensitive( GTK_ACTION(box3d_angle_x), !prefs->getBool("/tools/shapes/3dbox/vp_x_state", true) ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/shapes/3dbox/vp_x_state", true) ); + } + + /* Angle Y */ + { + gchar const* labels[] = { 0, 0, 0, 0, 0, 0, 0 }; + gdouble values[] = {-90, -60, -30, 0, 30, 60, 90}; + eact = create_adjustment_action( "3DBoxAngleYAction", + _("Angle in Y direction"), _("Angle Y:"), + // Translators: PL is short for 'perspective line' + _("Angle of PLs in Y direction"), + "/tools/shapes/3dbox/box3d_angle_y", 30, + GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, + -360.0, 360.0, 1.0, 10.0, + labels, values, G_N_ELEMENTS(labels), + box3d_angle_y_value_changed ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + g_object_set_data( holder, "box3d_angle_y_action", eact ); + box3d_angle_y = eact; + } + + if (!persp_impl || !persp3d_VP_is_finite(persp_impl, Proj::Y)) { + gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); + } else { + gtk_action_set_sensitive( GTK_ACTION(eact), FALSE ); + } + + /* VP Y state */ + { + InkToggleAction* act = ink_toggle_action_new( "3DBoxVPYStateAction", + // Translators: VP is short for 'vanishing point' + _("State of VP in Y direction"), + _("Toggle VP in Y direction between 'finite' and 'infinite' (=parallel)"), + INKSCAPE_ICON("perspective-parallel"), + GTK_ICON_SIZE_MENU ); + gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); + g_object_set_data( holder, "box3d_vp_y_state_action", act ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(box3d_vp_y_state_changed), box3d_angle_y ); + gtk_action_set_sensitive( GTK_ACTION(box3d_angle_y), !prefs->getBool("/tools/shapes/3dbox/vp_y_state", true) ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/shapes/3dbox/vp_y_state", true) ); + } + + /* Angle Z */ + { + gchar const* labels[] = { 0, 0, 0, 0, 0, 0, 0 }; + gdouble values[] = {-90, -60, -30, 0, 30, 60, 90}; + eact = create_adjustment_action( "3DBoxAngleZAction", + _("Angle in Z direction"), _("Angle Z:"), + // Translators: PL is short for 'perspective line' + _("Angle of PLs in Z direction"), + "/tools/shapes/3dbox/box3d_angle_z", 30, + GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, + -360.0, 360.0, 1.0, 10.0, + labels, values, G_N_ELEMENTS(labels), + box3d_angle_z_value_changed ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + g_object_set_data( holder, "box3d_angle_z_action", eact ); + box3d_angle_z = eact; + } + + if (!persp_impl || !persp3d_VP_is_finite(persp_impl, Proj::Z)) { + gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); + } else { + gtk_action_set_sensitive( GTK_ACTION(eact), FALSE ); + } + + /* VP Z state */ + { + InkToggleAction* act = ink_toggle_action_new( "3DBoxVPZStateAction", + // Translators: VP is short for 'vanishing point' + _("State of VP in Z direction"), + _("Toggle VP in Z direction between 'finite' and 'infinite' (=parallel)"), + INKSCAPE_ICON("perspective-parallel"), + GTK_ICON_SIZE_MENU ); + gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); + g_object_set_data( holder, "box3d_vp_z_state_action", act ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(box3d_vp_z_state_changed), box3d_angle_z ); + gtk_action_set_sensitive( GTK_ACTION(box3d_angle_z), !prefs->getBool("/tools/shapes/3dbox/vp_z_state", true) ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/shapes/3dbox/vp_z_state", true) ); + } + + desktop->connectEventContextChanged(sigc::bind(sigc::ptr_fun(box3d_toolbox_check_ec), holder)); + g_signal_connect(holder, "destroy", G_CALLBACK(purge_repr_listener), holder); +} + +static void box3d_toolbox_check_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolBase* ec, GObject* holder) +{ + static sigc::connection changed; + if (SP_IS_BOX3D_CONTEXT(ec)) { + changed = desktop->getSelection()->connectChanged(sigc::bind(sigc::ptr_fun(box3d_toolbox_selection_changed), holder)); + box3d_toolbox_selection_changed(desktop->getSelection(), holder); + } else { + if (changed) + changed.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:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/toolbar/box3d-toolbar.h b/src/ui/toolbar/box3d-toolbar.h new file mode 100644 index 000000000..cba9ca2d8 --- /dev/null +++ b/src/ui/toolbar/box3d-toolbar.h @@ -0,0 +1,38 @@ +#ifndef SEEN_BOX3D_TOOLBAR_H +#define SEEN_BOX3D_TOOLBAR_H + +/** + * @file + * 3d box aux toolbar + */ +/* Authors: + * MenTaLguY + * Lauris Kaplinski + * bulia byak + * Frank Felfe + * John Cliff + * David Turner + * Josh Andler + * Jon A. Cruz + * Maximilian Albert + * Tavmjong Bah + * Abhishek Sharma + * Kris De Gussem + * + * Copyright (C) 2004 David Turner + * Copyright (C) 2003 MenTaLguY + * Copyright (C) 1999-2011 authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + + +class SPDesktop; + +typedef struct _GtkActionGroup GtkActionGroup; +typedef struct _GObject GObject; + +void box3d_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); + +#endif /* !SEEN_BOX3D_TOOLBAR_H */ diff --git a/src/ui/toolbar/calligraphy-toolbar.cpp b/src/ui/toolbar/calligraphy-toolbar.cpp new file mode 100644 index 000000000..44271531e --- /dev/null +++ b/src/ui/toolbar/calligraphy-toolbar.cpp @@ -0,0 +1,623 @@ +/** + * @file + * Calligraphy aux toolbar + */ +/* Authors: + * MenTaLguY + * Lauris Kaplinski + * bulia byak + * Frank Felfe + * John Cliff + * David Turner + * Josh Andler + * Jon A. Cruz + * Maximilian Albert + * Tavmjong Bah + * Abhishek Sharma + * Kris De Gussem + * + * Copyright (C) 2004 David Turner + * Copyright (C) 2003 MenTaLguY + * Copyright (C) 1999-2011 authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "ui/dialog/calligraphic-profile-rename.h" +#include +#include "calligraphy-toolbar.h" + +#include "desktop.h" +#include "document-undo.h" +#include "widgets/ege-adjustment-action.h" +#include "widgets/ink-action.h" +#include "widgets/ink-toggle-action.h" +#include "widgets/toolbox.h" +#include "ui/icon-names.h" +#include "ui/uxmanager.h" +#include "ui/widget/ink-select-one-action.h" + +using Inkscape::UI::UXManager; +using Inkscape::DocumentUndo; +using Inkscape::UI::ToolboxFactory; +using Inkscape::UI::PrefPusher; + + +//######################## +//## Calligraphy ## +//######################## + +std::vector get_presets_list() { + + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + + std::vector presets = prefs->getAllDirs("/tools/calligraphic/preset"); + + return presets; +} + +void update_presets_list(GObject *tbl) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + if (g_object_get_data(tbl, "presets_blocked")) { + return; + } + + InkSelectOneAction *act = static_cast(g_object_get_data(tbl, "profile_selector")); + + std::vector presets = get_presets_list(); + + int index = 1; // 0 is for no preset. + for (std::vector::iterator i = presets.begin(); i != presets.end(); ++i, ++index) { + bool match = true; + + std::vector preset = prefs->getAllEntries(*i); + for (std::vector::iterator j = preset.begin(); j != preset.end(); ++j) { + Glib::ustring entry_name = j->getEntryName(); + if (entry_name == "id" || entry_name == "name") { + continue; + } + + void *widget = g_object_get_data(tbl, entry_name.data()); + if (widget) { + if (GTK_IS_ADJUSTMENT(widget)) { + double v = j->getDouble(); + GtkAdjustment* adj = static_cast(widget); + //std::cout << "compared adj " << attr_name << gtk_adjustment_get_value(adj) << " to " << v << "\n"; + if (fabs(gtk_adjustment_get_value(adj) - v) > 1e-6) { + match = false; + break; + } + } else if (GTK_IS_TOGGLE_ACTION(widget)) { + bool v = j->getBool(); + GtkToggleAction* toggle = static_cast(widget); + //std::cout << "compared toggle " << attr_name << gtk_toggle_action_get_active(toggle) << " to " << v << "\n"; + if ( static_cast(gtk_toggle_action_get_active(toggle)) != v ) { + match = false; + break; + } + } + } + } + + if (match) { + // newly added item is at the same index as the + // save command, so we need to change twice for it to take effect + act->set_active(0); + act->set_active(index); + return; + } + } + + // no match found + act->set_active(0); +} + +static void sp_ddc_mass_value_changed( GtkAdjustment *adj, GObject* tbl ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble( "/tools/calligraphic/mass", gtk_adjustment_get_value(adj) ); + update_presets_list(tbl); +} + +static void sp_ddc_wiggle_value_changed( GtkAdjustment *adj, GObject* tbl ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble( "/tools/calligraphic/wiggle", gtk_adjustment_get_value(adj) ); + update_presets_list(tbl); +} + +static void sp_ddc_angle_value_changed( GtkAdjustment *adj, GObject* tbl ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble( "/tools/calligraphic/angle", gtk_adjustment_get_value(adj) ); + update_presets_list(tbl); +} + +static void sp_ddc_width_value_changed( GtkAdjustment *adj, GObject *tbl ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble( "/tools/calligraphic/width", gtk_adjustment_get_value(adj) ); + update_presets_list(tbl); +} + +static void sp_ddc_velthin_value_changed( GtkAdjustment *adj, GObject* tbl ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble("/tools/calligraphic/thinning", gtk_adjustment_get_value(adj) ); + update_presets_list(tbl); +} + +static void sp_ddc_flatness_value_changed( GtkAdjustment *adj, GObject* tbl ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble( "/tools/calligraphic/flatness", gtk_adjustment_get_value(adj) ); + update_presets_list(tbl); +} + +static void sp_ddc_tremor_value_changed( GtkAdjustment *adj, GObject* tbl ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble( "/tools/calligraphic/tremor", gtk_adjustment_get_value(adj) ); + update_presets_list(tbl); +} + +static void sp_ddc_cap_rounding_value_changed( GtkAdjustment *adj, GObject* tbl ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble( "/tools/calligraphic/cap_rounding", gtk_adjustment_get_value(adj) ); + update_presets_list(tbl); +} + +static void sp_ddc_tilt_state_changed( GtkToggleAction *act, GObject* tbl ) +{ + // TODO merge into PrefPusher + GtkAction * calligraphy_angle = static_cast (g_object_get_data(tbl,"angle_action")); + if (calligraphy_angle ) { + gtk_action_set_sensitive( calligraphy_angle, !gtk_toggle_action_get_active( act ) ); + } +} + + +static gchar const *const widget_names[] = { + "width", + "mass", + "wiggle", + "angle", + "thinning", + "tremor", + "flatness", + "cap_rounding", + "usepressure", + "tracebackground", + "usetilt" +}; + + +static void sp_dcc_build_presets_list(GObject *tbl) +{ + g_object_set_data(tbl, "presets_blocked", GINT_TO_POINTER(TRUE)); + + InkSelectOneAction* act = static_cast(g_object_get_data(tbl, "profile_selector")); + + Glib::RefPtr store = act->get_store(); + store->clear(); + + InkSelectOneActionColumns columns; + + Gtk::TreeModel::Row row; + + row = *(store->append()); + row[columns.col_label ] = _("No preset"); + row[columns.col_sensitive] = true; + + // iterate over all presets to populate the list + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + std::vector presets = get_presets_list(); + int ii=1; + + for (std::vector::iterator i = presets.begin(); i != presets.end(); ++i) { + GtkTreeIter iter; + Glib::ustring preset_name = prefs->getString(*i + "/name"); + + if (!preset_name.empty()) { + row = *(store->append()); + row[columns.col_label ] = _(preset_name.data()); + row[columns.col_sensitive] = true; + } + } + + g_object_set_data(tbl, "presets_blocked", GINT_TO_POINTER(FALSE)); + + update_presets_list (tbl); +} + +static void sp_dcc_save_profile(GtkWidget * /*widget*/, GObject *tbl) +{ + using Inkscape::UI::Dialog::CalligraphicProfileRename; + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + SPDesktop *desktop = static_cast(g_object_get_data(tbl, "desktop" )); + if (! desktop) { + return; + } + + if (g_object_get_data(tbl, "presets_blocked")) { + return; + } + + InkSelectOneAction *act = static_cast(g_object_get_data(tbl, "profile_selector")); + + Glib::ustring current_profile_name = act->get_active_text(); + + if (current_profile_name == _("No preset")) { + current_profile_name = ""; + } + + CalligraphicProfileRename::show(desktop, current_profile_name); + if ( !CalligraphicProfileRename::applied()) { + // dialog cancelled + update_presets_list (tbl); + return; + } + Glib::ustring new_profile_name = CalligraphicProfileRename::getProfileName(); + + if (new_profile_name.empty()) { + // empty name entered + update_presets_list (tbl); + return; + } + + g_object_set_data(tbl, "presets_blocked", GINT_TO_POINTER(TRUE)); + + // If there's a preset with the given name, find it and set save_path appropriately + std::vector presets = get_presets_list(); + int total_presets = presets.size(); + int new_index = -1; + Glib::ustring save_path; // profile pref path without a trailing slash + + int temp_index = 0; + for (std::vector::iterator i = presets.begin(); i != presets.end(); ++i, ++temp_index) { + Glib::ustring name = prefs->getString(*i + "/name"); + if (!name.empty() && (new_profile_name == name || current_profile_name == name)) { + new_index = temp_index; + save_path = *i; + break; + } + } + + + if ( CalligraphicProfileRename::deleted() && new_index != -1) { + prefs->remove(save_path); + g_object_set_data(tbl, "presets_blocked", GINT_TO_POINTER(FALSE)); + sp_dcc_build_presets_list (tbl); + return; + } + + if (new_index == -1) { + // no preset with this name, create + new_index = total_presets + 1; + gchar *profile_id = g_strdup_printf("/dcc%d", new_index); + save_path = Glib::ustring("/tools/calligraphic/preset") + profile_id; + g_free(profile_id); + } + + for (unsigned i = 0; i < G_N_ELEMENTS(widget_names); ++i) { + gchar const *const widget_name = widget_names[i]; + void *widget = g_object_get_data(tbl, widget_name); + if (widget) { + if (GTK_IS_ADJUSTMENT(widget)) { + GtkAdjustment* adj = static_cast(widget); + prefs->setDouble(save_path + "/" + widget_name, gtk_adjustment_get_value(adj)); + //std::cout << "wrote adj " << widget_name << ": " << v << "\n"; + } else if (GTK_IS_TOGGLE_ACTION(widget)) { + GtkToggleAction* toggle = static_cast(widget); + prefs->setBool(save_path + "/" + widget_name, gtk_toggle_action_get_active(toggle)); + //std::cout << "wrote tog " << widget_name << ": " << v << "\n"; + } else { + g_warning("Unknown widget type for preset: %s\n", widget_name); + } + } else { + g_warning("Bad key when writing preset: %s\n", widget_name); + } + } + prefs->setString(save_path + "/name", new_profile_name); + + g_object_set_data(tbl, "presets_blocked", GINT_TO_POINTER(FALSE)); + sp_dcc_build_presets_list (tbl); +} + + +static void sp_ddc_change_profile(GObject* tbl, int mode) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + + if (g_object_get_data(tbl, "presets_blocked")) { + return; + } + + // mode is one-based so we subtract 1 + std::vector presets = get_presets_list(); + + Glib::ustring preset_path = ""; + if (mode - 1 < presets.size()) { + preset_path = presets.at(mode - 1); + } + + if (!preset_path.empty()) { + g_object_set_data(tbl, "presets_blocked", GINT_TO_POINTER(TRUE)); //temporarily block the selector so no one will updadte it while we're reading it + + std::vector preset = prefs->getAllEntries(preset_path); + + // Shouldn't this be std::map? + for (std::vector::iterator i = preset.begin(); i != preset.end(); ++i) { + Glib::ustring entry_name = i->getEntryName(); + if (entry_name == "id" || entry_name == "name") { + continue; + } + void *widget = g_object_get_data(tbl, entry_name.data()); + if (widget) { + if (GTK_IS_ADJUSTMENT(widget)) { + GtkAdjustment* adj = static_cast(widget); + gtk_adjustment_set_value(adj, i->getDouble()); + //std::cout << "set adj " << attr_name << " to " << v << "\n"; + } else if (GTK_IS_TOGGLE_ACTION(widget)) { + GtkToggleAction* toggle = static_cast(widget); + gtk_toggle_action_set_active(toggle, i->getBool()); + //std::cout << "set toggle " << attr_name << " to " << v << "\n"; + } else { + g_warning("Unknown widget type for preset: %s\n", entry_name.data()); + } + } else { + g_warning("Bad key found in a preset record: %s\n", entry_name.data()); + } + } + g_object_set_data(tbl, "presets_blocked", GINT_TO_POINTER(FALSE)); + } +} + +static void sp_ddc_edit_profile(GtkAction * /*act*/, GObject* tbl) +{ + sp_dcc_save_profile(NULL, tbl); +} + +void sp_calligraphy_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + { + g_object_set_data(holder, "presets_blocked", GINT_TO_POINTER(TRUE)); + + EgeAdjustmentAction* calligraphy_angle = 0; + + { + /* Width */ + gchar const* labels[] = {_("(hairline)"), 0, 0, 0, _("(default)"), 0, 0, 0, 0, _("(broad stroke)")}; + gdouble values[] = {1, 3, 5, 10, 15, 20, 30, 50, 75, 100}; + EgeAdjustmentAction *eact = create_adjustment_action( "CalligraphyWidthAction", + _("Pen Width"), _("Width:"), + _("The width of the calligraphic pen (relative to the visible canvas area)"), + "/tools/calligraphic/width", 15, + GTK_WIDGET(desktop->canvas), holder, TRUE, "altx-calligraphy", + 1, 100, 1.0, 10.0, + labels, values, G_N_ELEMENTS(labels), + sp_ddc_width_value_changed, NULL /*unit tracker*/, 1, 0 ); + ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); + } + + { + /* Thinning */ + gchar const* labels[] = {_("(speed blows up stroke)"), 0, 0, _("(slight widening)"), _("(constant width)"), _("(slight thinning, default)"), 0, 0, _("(speed deflates stroke)")}; + gdouble values[] = {-100, -40, -20, -10, 0, 10, 20, 40, 100}; + EgeAdjustmentAction* eact = create_adjustment_action( "ThinningAction", + _("Stroke Thinning"), _("Thinning:"), + _("How much velocity thins the stroke (> 0 makes fast strokes thinner, < 0 makes them broader, 0 makes width independent of velocity)"), + "/tools/calligraphic/thinning", 10, + GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, + -100, 100, 1, 10.0, + labels, values, G_N_ELEMENTS(labels), + sp_ddc_velthin_value_changed, NULL /*unit tracker*/, 1, 0); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); + } + + { + /* Angle */ + gchar const* labels[] = {_("(left edge up)"), 0, 0, _("(horizontal)"), _("(default)"), 0, _("(right edge up)")}; + gdouble values[] = {-90, -60, -30, 0, 30, 60, 90}; + EgeAdjustmentAction* eact = create_adjustment_action( "AngleAction", + _("Pen Angle"), _("Angle:"), + _("The angle of the pen's nib (in degrees; 0 = horizontal; has no effect if fixation = 0)"), + "/tools/calligraphic/angle", 30, + GTK_WIDGET(desktop->canvas), holder, TRUE, "calligraphy-angle", + -90.0, 90.0, 1.0, 10.0, + labels, values, G_N_ELEMENTS(labels), + sp_ddc_angle_value_changed, NULL /*unit tracker*/, 1, 0 ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + g_object_set_data( holder, "angle_action", eact ); + gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); + calligraphy_angle = eact; + } + + { + /* Fixation */ + gchar const* labels[] = {_("(perpendicular to stroke, \"brush\")"), 0, 0, 0, _("(almost fixed, default)"), _("(fixed by Angle, \"pen\")")}; + gdouble values[] = {0, 20, 40, 60, 90, 100}; + EgeAdjustmentAction* eact = create_adjustment_action( "FixationAction", + _("Fixation"), _("Fixation:"), + _("Angle behavior (0 = nib always perpendicular to stroke direction, 100 = fixed angle)"), + "/tools/calligraphic/flatness", 90, + GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, + 0.0, 100, 1.0, 10.0, + labels, values, G_N_ELEMENTS(labels), + sp_ddc_flatness_value_changed, NULL /*unit tracker*/, 1, 0); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); + } + + { + /* Cap Rounding */ + gchar const* labels[] = {_("(blunt caps, default)"), _("(slightly bulging)"), 0, 0, _("(approximately round)"), _("(long protruding caps)")}; + gdouble values[] = {0, 0.3, 0.5, 1.0, 1.4, 5.0}; + // TRANSLATORS: "cap" means "end" (both start and finish) here + EgeAdjustmentAction* eact = create_adjustment_action( "CapRoundingAction", + _("Cap rounding"), _("Caps:"), + _("Increase to make caps at the ends of strokes protrude more (0 = no caps, 1 = round caps)"), + "/tools/calligraphic/cap_rounding", 0.0, + GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, + 0.0, 5.0, 0.01, 0.1, + labels, values, G_N_ELEMENTS(labels), + sp_ddc_cap_rounding_value_changed, NULL /*unit tracker*/, 0.01, 2 ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); + } + + { + /* Tremor */ + gchar const* labels[] = {_("(smooth line)"), _("(slight tremor)"), _("(noticeable tremor)"), 0, 0, _("(maximum tremor)")}; + gdouble values[] = {0, 10, 20, 40, 60, 100}; + EgeAdjustmentAction* eact = create_adjustment_action( "TremorAction", + _("Stroke Tremor"), _("Tremor:"), + _("Increase to make strokes rugged and trembling"), + "/tools/calligraphic/tremor", 0.0, + GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, + 0.0, 100, 1, 10.0, + labels, values, G_N_ELEMENTS(labels), + sp_ddc_tremor_value_changed, NULL /*unit tracker*/, 1, 0); + + ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); + } + + { + /* Wiggle */ + gchar const* labels[] = {_("(no wiggle)"), _("(slight deviation)"), 0, 0, _("(wild waves and curls)")}; + gdouble values[] = {0, 20, 40, 60, 100}; + EgeAdjustmentAction* eact = create_adjustment_action( "WiggleAction", + _("Pen Wiggle"), _("Wiggle:"), + _("Increase to make the pen waver and wiggle"), + "/tools/calligraphic/wiggle", 0.0, + GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, + 0.0, 100, 1, 10.0, + labels, values, G_N_ELEMENTS(labels), + sp_ddc_wiggle_value_changed, NULL /*unit tracker*/, 1, 0); + ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); + } + + { + /* Mass */ + gchar const* labels[] = {_("(no inertia)"), _("(slight smoothing, default)"), _("(noticeable lagging)"), 0, 0, _("(maximum inertia)")}; + gdouble values[] = {0.0, 2, 10, 20, 50, 100}; + EgeAdjustmentAction* eact = create_adjustment_action( "MassAction", + _("Pen Mass"), _("Mass:"), + _("Increase to make the pen drag behind, as if slowed by inertia"), + "/tools/calligraphic/mass", 2.0, + GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, + 0.0, 100, 1, 10.0, + labels, values, G_N_ELEMENTS(labels), + sp_ddc_mass_value_changed, NULL /*unit tracker*/, 1, 0); + ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); + } + + + /* Trace Background button */ + { + InkToggleAction* act = ink_toggle_action_new( "TraceAction", + _("Trace Background"), + _("Trace the lightness of the background by the width of the pen (white - minimum width, black - maximum width)"), + INKSCAPE_ICON("draw-trace-background"), + GTK_ICON_SIZE_MENU ); + gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); + PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(act), "/tools/calligraphic/tracebackground", update_presets_list, holder); + g_signal_connect( holder, "destroy", G_CALLBACK(delete_prefspusher), pusher); + g_object_set_data( holder, "tracebackground", act ); + } + + /* Use Pressure button */ + { + InkToggleAction* act = ink_toggle_action_new( "PressureAction", + _("Pressure"), + _("Use the pressure of the input device to alter the width of the pen"), + INKSCAPE_ICON("draw-use-pressure"), + GTK_ICON_SIZE_MENU ); + gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); + PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(act), "/tools/calligraphic/usepressure", update_presets_list, holder); + g_signal_connect( holder, "destroy", G_CALLBACK(delete_prefspusher), pusher); + g_object_set_data( holder, "usepressure", act ); + } + + /* Use Tilt button */ + { + InkToggleAction* act = ink_toggle_action_new( "TiltAction", + _("Tilt"), + _("Use the tilt of the input device to alter the angle of the pen's nib"), + INKSCAPE_ICON("draw-use-tilt"), + GTK_ICON_SIZE_MENU ); + gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); + PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(act), "/tools/calligraphic/usetilt", update_presets_list, holder); + g_signal_connect( holder, "destroy", G_CALLBACK(delete_prefspusher), pusher); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_ddc_tilt_state_changed), holder ); + gtk_action_set_sensitive( GTK_ACTION(calligraphy_angle), !prefs->getBool("/tools/calligraphic/usetilt", true) ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/calligraphic/usetilt", true) ); + g_object_set_data( holder, "usetilt", act ); + } + + /*calligraphic profile */ + { + InkSelectOneActionColumns columns; + + Glib::RefPtr store = Gtk::ListStore::create(columns); + + InkSelectOneAction* act = + InkSelectOneAction::create( "SetProfileAction", // Name + "", // Label + _("Choose a preset"), // Tooltip + "NotUsed", // Icon + store ); // Tree store + act->use_radio( false ); + act->use_label( true ); + + g_object_set_data (holder, "profile_selector", act); + + sp_dcc_build_presets_list (holder); + + gtk_action_group_add_action(mainActions, GTK_ACTION( act->gobj() )); + + act->signal_changed().connect(sigc::bind<0>(sigc::ptr_fun(&sp_ddc_change_profile), holder)); + } + + /*calligraphic profile editor */ + { + InkAction* inky = ink_action_new( "ProfileEditAction", + _("Add/Edit Profile"), + _("Add or edit calligraphic profile"), + INKSCAPE_ICON("document-properties"), + GTK_ICON_SIZE_MENU ); + g_object_set( inky, "short_label", _("Edit"), NULL ); + g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_ddc_edit_profile), (GObject*)holder ); + gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); + } + } +} + + +/* + 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:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/toolbar/calligraphy-toolbar.h b/src/ui/toolbar/calligraphy-toolbar.h new file mode 100644 index 000000000..e3caa19ee --- /dev/null +++ b/src/ui/toolbar/calligraphy-toolbar.h @@ -0,0 +1,38 @@ +#ifndef SEEN_CALLIGRAPHY_TOOLBAR_H +#define SEEN_CALLIGRAPHY_TOOLBAR_H + +/** + * @file + * Calligraphy aux toolbar + */ +/* Authors: + * MenTaLguY + * Lauris Kaplinski + * bulia byak + * Frank Felfe + * John Cliff + * David Turner + * Josh Andler + * Jon A. Cruz + * Maximilian Albert + * Tavmjong Bah + * Abhishek Sharma + * Kris De Gussem + * + * Copyright (C) 2004 David Turner + * Copyright (C) 2003 MenTaLguY + * Copyright (C) 1999-2011 authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +class SPDesktop; + +typedef struct _GtkActionGroup GtkActionGroup; +typedef struct _GObject GObject; + +void sp_calligraphy_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); +void update_presets_list(GObject *tbl); + +#endif /* !SEEN_CALLIGRAPHY_TOOLBAR_H */ diff --git a/src/ui/toolbar/connector-toolbar.cpp b/src/ui/toolbar/connector-toolbar.cpp new file mode 100644 index 000000000..2709c700e --- /dev/null +++ b/src/ui/toolbar/connector-toolbar.cpp @@ -0,0 +1,450 @@ +/** + * @file + * Connector aux toolbar + */ +/* Authors: + * MenTaLguY + * Lauris Kaplinski + * bulia byak + * Frank Felfe + * John Cliff + * David Turner + * Josh Andler + * Jon A. Cruz + * Maximilian Albert + * Tavmjong Bah + * Abhishek Sharma + * Kris De Gussem + * + * Copyright (C) 2004 David Turner + * Copyright (C) 2003 MenTaLguY + * Copyright (C) 1999-2011 authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include "connector-toolbar.h" +#include "conn-avoid-ref.h" + +#include "desktop.h" +#include "document-undo.h" +#include "enums.h" +#include "graphlayout.h" +#include "widgets/ink-action.h" +#include "widgets/ink-toggle-action.h" +#include "widgets/toolbox.h" +#include "inkscape.h" +#include "verbs.h" + +#include "object/sp-namedview.h" +#include "object/sp-path.h" + +#include "ui/icon-names.h" +#include "ui/tools/connector-tool.h" +#include "ui/uxmanager.h" + +#include "widgets/ege-adjustment-action.h" +#include "widgets/spinbutton-events.h" + +#include "xml/node-event-vector.h" + +using Inkscape::UI::UXManager; +using Inkscape::DocumentUndo; +using Inkscape::UI::ToolboxFactory; +using Inkscape::UI::PrefPusher; + +//######################### +//## Connector ## +//######################### + +static void sp_connector_path_set_avoid(void) +{ + Inkscape::UI::Tools::cc_selection_set_avoid(true); +} + + +static void sp_connector_path_set_ignore(void) +{ + Inkscape::UI::Tools::cc_selection_set_avoid(false); +} + +static void sp_connector_orthogonal_toggled( GtkToggleAction* act, GObject *tbl ) +{ + SPDesktop *desktop = static_cast(g_object_get_data( tbl, "desktop" )); + SPDocument *doc = desktop->getDocument(); + + if (!DocumentUndo::getUndoSensitive(doc)) { + return; + } + + + // quit if run by the _changed callbacks + if (g_object_get_data( tbl, "freeze" )) { + return; + } + + // in turn, prevent callbacks from responding + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); + + bool is_orthog = gtk_toggle_action_get_active( act ); + gchar orthog_str[] = "orthogonal"; + gchar polyline_str[] = "polyline"; + gchar *value = is_orthog ? orthog_str : polyline_str ; + + bool modmade = false; + auto itemlist= desktop->getSelection()->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ + SPItem *item = *i; + + if (Inkscape::UI::Tools::cc_item_is_connector(item)) { + item->setAttribute( "inkscape:connector-type", + value, NULL); + item->avoidRef->handleSettingChange(); + modmade = true; + } + } + + if (!modmade) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setBool("/tools/connector/orthogonal", is_orthog); + } else { + + DocumentUndo::done(doc, SP_VERB_CONTEXT_CONNECTOR, + is_orthog ? _("Set connector type: orthogonal"): _("Set connector type: polyline")); + } + + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); +} + +static void connector_curvature_changed(GtkAdjustment *adj, GObject* tbl) +{ + SPDesktop *desktop = static_cast(g_object_get_data( tbl, "desktop" )); + SPDocument *doc = desktop->getDocument(); + + if (!DocumentUndo::getUndoSensitive(doc)) { + return; + } + + + // quit if run by the _changed callbacks + if (g_object_get_data( tbl, "freeze" )) { + return; + } + + // in turn, prevent callbacks from responding + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); + + gdouble newValue = gtk_adjustment_get_value(adj); + gchar value[G_ASCII_DTOSTR_BUF_SIZE]; + g_ascii_dtostr(value, G_ASCII_DTOSTR_BUF_SIZE, newValue); + + bool modmade = false; + auto itemlist= desktop->getSelection()->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ + SPItem *item = *i; + + if (Inkscape::UI::Tools::cc_item_is_connector(item)) { + item->setAttribute( "inkscape:connector-curvature", + value, NULL); + item->avoidRef->handleSettingChange(); + modmade = true; + } + } + + if (!modmade) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble(Glib::ustring("/tools/connector/curvature"), newValue); + } + else { + DocumentUndo::done(doc, SP_VERB_CONTEXT_CONNECTOR, + _("Change connector curvature")); + } + + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); +} + + +static void connector_spacing_changed(GtkAdjustment *adj, GObject* tbl) +{ + SPDesktop *desktop = static_cast(g_object_get_data( tbl, "desktop" )); + SPDocument *doc = desktop->getDocument(); + + if (!DocumentUndo::getUndoSensitive(doc)) { + return; + } + + Inkscape::XML::Node *repr = desktop->namedview->getRepr(); + + if ( !repr->attribute("inkscape:connector-spacing") && + ( gtk_adjustment_get_value(adj) == defaultConnSpacing )) { + // Don't need to update the repr if the attribute doesn't + // exist and it is being set to the default value -- as will + // happen at startup. + return; + } + + // quit if run by the attr_changed listener + if (g_object_get_data( tbl, "freeze" )) { + return; + } + + // in turn, prevent listener from responding + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE)); + + sp_repr_set_css_double(repr, "inkscape:connector-spacing", gtk_adjustment_get_value(adj)); + desktop->namedview->updateRepr(); + bool modmade = false; + + std::vector items; + items = get_avoided_items(items, desktop->currentRoot(), desktop); + for (std::vector::const_iterator iter = items.begin(); iter != items.end(); ++iter ) { + SPItem *item = *iter; + Geom::Affine m = Geom::identity(); + avoid_item_move(&m, item); + modmade = true; + } + + if(modmade) { + DocumentUndo::done(doc, SP_VERB_CONTEXT_CONNECTOR, + _("Change connector spacing")); + } + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); +} + +static void sp_connector_graph_layout(void) +{ + if (!SP_ACTIVE_DESKTOP) { + return; + } + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + + // hack for clones, see comment in align-and-distribute.cpp + int saved_compensation = prefs->getInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED); + prefs->setInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED); + + auto tmp = SP_ACTIVE_DESKTOP->getSelection()->items(); + std::vector vec(tmp.begin(), tmp.end()); + graphlayout(vec); + + prefs->setInt("/options/clonecompensation/value", saved_compensation); + + DocumentUndo::done(SP_ACTIVE_DESKTOP->getDocument(), SP_VERB_DIALOG_ALIGN_DISTRIBUTE, _("Arrange connector network")); +} + +static void sp_directed_graph_layout_toggled( GtkToggleAction* act, GObject * /*tbl*/ ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setBool("/tools/connector/directedlayout", + gtk_toggle_action_get_active( act )); +} + +static void sp_nooverlaps_graph_layout_toggled( GtkToggleAction* act, GObject * /*tbl*/ ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setBool("/tools/connector/avoidoverlaplayout", + gtk_toggle_action_get_active( act )); +} + + +static void connector_length_changed(GtkAdjustment *adj, GObject* /*tbl*/) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble("/tools/connector/length", gtk_adjustment_get_value(adj)); +} + +static void connector_tb_event_attr_changed(Inkscape::XML::Node *repr, + gchar const *name, gchar const * /*old_value*/, gchar const * /*new_value*/, + bool /*is_interactive*/, gpointer data) +{ + GtkWidget *tbl = GTK_WIDGET(data); + + if ( !g_object_get_data(G_OBJECT(tbl), "freeze") + && (strcmp(name, "inkscape:connector-spacing") == 0) ) { + GtkAdjustment *adj = static_cast(g_object_get_data(G_OBJECT(tbl), "spacing")); + gdouble spacing = defaultConnSpacing; + sp_repr_get_double(repr, "inkscape:connector-spacing", &spacing); + + gtk_adjustment_set_value(adj, spacing); + +#if !GTK_CHECK_VERSION(3,18,0) + gtk_adjustment_value_changed(adj); +#endif + + spinbutton_defocus(tbl); + } +} + +static Inkscape::XML::NodeEventVector connector_tb_repr_events = { + NULL, /* child_added */ + NULL, /* child_removed */ + connector_tb_event_attr_changed, + NULL, /* content_changed */ + NULL /* order_changed */ +}; + +static void sp_connector_toolbox_selection_changed(Inkscape::Selection *selection, GObject *tbl) +{ + GtkAdjustment *adj = GTK_ADJUSTMENT( g_object_get_data( tbl, "curvature" ) ); + GtkToggleAction *act = GTK_TOGGLE_ACTION( g_object_get_data( tbl, "orthogonal" ) ); + SPItem *item = selection->singleItem(); + if (SP_IS_PATH(item)) + { + gdouble curvature = SP_PATH(item)->connEndPair.getCurvature(); + bool is_orthog = SP_PATH(item)->connEndPair.isOrthogonal(); + gtk_toggle_action_set_active(act, is_orthog); + gtk_adjustment_set_value(adj, curvature); + } + +} + +void sp_connector_toolbox_prep( SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + GtkIconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1); + + { + InkAction* inky = ink_action_new( "ConnectorAvoidAction", + _("Avoid"), + _("Make connectors avoid selected objects"), + INKSCAPE_ICON("connector-avoid"), + secondarySize ); + g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_connector_path_set_avoid), holder ); + gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); + } + + { + InkAction* inky = ink_action_new( "ConnectorIgnoreAction", + _("Ignore"), + _("Make connectors ignore selected objects"), + INKSCAPE_ICON("connector-ignore"), + secondarySize ); + g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_connector_path_set_ignore), holder ); + gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); + } + + // Orthogonal connectors toggle button + { + InkToggleAction* act = ink_toggle_action_new( "ConnectorOrthogonalAction", + _("Orthogonal"), + _("Make connector orthogonal or polyline"), + INKSCAPE_ICON("connector-orthogonal"), + GTK_ICON_SIZE_MENU ); + gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); + + bool tbuttonstate = prefs->getBool("/tools/connector/orthogonal"); + gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act), ( tbuttonstate ? TRUE : FALSE )); + g_object_set_data( holder, "orthogonal", act ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_connector_orthogonal_toggled), holder ); + } + + EgeAdjustmentAction* eact = 0; + // Curvature spinbox + eact = create_adjustment_action( "ConnectorCurvatureAction", + _("Connector Curvature"), _("Curvature:"), + _("The amount of connectors curvature"), + "/tools/connector/curvature", defaultConnCurvature, + GTK_WIDGET(desktop->canvas), holder, TRUE, "inkscape:connector-curvature", + 0, 100, 1.0, 10.0, + 0, 0, 0, + connector_curvature_changed, NULL /*unit tracker*/, 1, 0 ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + + // Spacing spinbox + eact = create_adjustment_action( "ConnectorSpacingAction", + _("Connector Spacing"), _("Spacing:"), + _("The amount of space left around objects by auto-routing connectors"), + "/tools/connector/spacing", defaultConnSpacing, + GTK_WIDGET(desktop->canvas), holder, TRUE, "inkscape:connector-spacing", + 0, 100, 1.0, 10.0, + 0, 0, 0, + connector_spacing_changed, NULL /*unit tracker*/, 1, 0 ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + + // Graph (connector network) layout + { + InkAction* inky = ink_action_new( "ConnectorGraphAction", + _("Graph"), + _("Nicely arrange selected connector network"), + INKSCAPE_ICON("distribute-graph"), + secondarySize ); + g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_connector_graph_layout), holder ); + gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); + } + + // Default connector length spinbox + eact = create_adjustment_action( "ConnectorLengthAction", + _("Connector Length"), _("Length:"), + _("Ideal length for connectors when layout is applied"), + "/tools/connector/length", 100, + GTK_WIDGET(desktop->canvas), holder, TRUE, "inkscape:connector-length", + 10, 1000, 10.0, 100.0, + 0, 0, 0, + connector_length_changed, NULL /*unit tracker*/, 1, 0 ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + + + // Directed edges toggle button + { + InkToggleAction* act = ink_toggle_action_new( "ConnectorDirectedAction", + _("Downwards"), + _("Make connectors with end-markers (arrows) point downwards"), + INKSCAPE_ICON("distribute-graph-directed"), + GTK_ICON_SIZE_MENU ); + gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); + + bool tbuttonstate = prefs->getBool("/tools/connector/directedlayout"); + gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act), ( tbuttonstate ? TRUE : FALSE )); + + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_directed_graph_layout_toggled), holder ); + desktop->getSelection()->connectChanged(sigc::bind(sigc::ptr_fun(sp_connector_toolbox_selection_changed), holder)); + } + + // Avoid overlaps toggle button + { + InkToggleAction* act = ink_toggle_action_new( "ConnectorOverlapAction", + _("Remove overlaps"), + _("Do not allow overlapping shapes"), + INKSCAPE_ICON("distribute-remove-overlaps"), + GTK_ICON_SIZE_MENU ); + gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); + + bool tbuttonstate = prefs->getBool("/tools/connector/avoidoverlaplayout"); + gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act), (tbuttonstate ? TRUE : FALSE )); + + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_nooverlaps_graph_layout_toggled), holder ); + } + + + // Code to watch for changes to the connector-spacing attribute in + // the XML. + Inkscape::XML::Node *repr = desktop->namedview->getRepr(); + g_assert(repr != NULL); + + purge_repr_listener( holder, holder ); + + if (repr) { + g_object_set_data( holder, "repr", repr ); + Inkscape::GC::anchor(repr); + sp_repr_add_listener( repr, &connector_tb_repr_events, holder ); + sp_repr_synthesize_events( repr, &connector_tb_repr_events, holder ); + } +} // end of sp_connector_toolbox_prep() + + +/* + 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:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/toolbar/connector-toolbar.h b/src/ui/toolbar/connector-toolbar.h new file mode 100644 index 000000000..180c11e0f --- /dev/null +++ b/src/ui/toolbar/connector-toolbar.h @@ -0,0 +1,37 @@ +#ifndef SEEN_CONNECTOR_TOOLBAR_H +#define SEEN_CONNECTOR_TOOLBAR_H + +/** + * @file + * Connector aux toolbar + */ +/* Authors: + * MenTaLguY + * Lauris Kaplinski + * bulia byak + * Frank Felfe + * John Cliff + * David Turner + * Josh Andler + * Jon A. Cruz + * Maximilian Albert + * Tavmjong Bah + * Abhishek Sharma + * Kris De Gussem + * + * Copyright (C) 2004 David Turner + * Copyright (C) 2003 MenTaLguY + * Copyright (C) 1999-2011 authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +class SPDesktop; + +typedef struct _GtkActionGroup GtkActionGroup; +typedef struct _GObject GObject; + +void sp_connector_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); + +#endif /* !SEEN_CONNECTOR_TOOLBAR_H */ diff --git a/src/ui/toolbar/dropper-toolbar.cpp b/src/ui/toolbar/dropper-toolbar.cpp new file mode 100644 index 000000000..ba3c9037c --- /dev/null +++ b/src/ui/toolbar/dropper-toolbar.cpp @@ -0,0 +1,127 @@ +/** + * @file + * Dropper aux toolbar + */ +/* Authors: + * MenTaLguY + * Lauris Kaplinski + * bulia byak + * Frank Felfe + * John Cliff + * David Turner + * Josh Andler + * Jon A. Cruz + * Maximilian Albert + * Tavmjong Bah + * Abhishek Sharma + * Kris De Gussem + * + * Copyright (C) 2004 David Turner + * Copyright (C) 2003 MenTaLguY + * Copyright (C) 1999-2011 authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include "dropper-toolbar.h" +#include "document-undo.h" +#include "widgets/ege-output-action.h" +#include "widgets/ink-toggle-action.h" +#include "preferences.h" +#include "widgets/spinbutton-events.h" + +using Inkscape::DocumentUndo; + +//######################## +//## Dropper ## +//######################## + +static void toggle_dropper_pick_alpha( GtkToggleAction* act, gpointer tbl ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setInt( "/tools/dropper/pick", gtk_toggle_action_get_active( act ) ); + GtkAction* set_action = GTK_ACTION( g_object_get_data(G_OBJECT(tbl), "set_action") ); + if ( set_action ) { + if ( gtk_toggle_action_get_active( act ) ) { + gtk_action_set_sensitive( set_action, TRUE ); + } else { + gtk_action_set_sensitive( set_action, FALSE ); + } + } + + spinbutton_defocus(GTK_WIDGET(tbl)); +} + +static void toggle_dropper_set_alpha( GtkToggleAction* act, gpointer tbl ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setBool( "/tools/dropper/setalpha", gtk_toggle_action_get_active( act ) ); + spinbutton_defocus(GTK_WIDGET(tbl)); +} + + +/** + * Dropper auxiliary toolbar construction and setup. + * + * TODO: Would like to add swatch of current color. + * TODO: Add queue of last 5 or so colors selected with new swatches so that + * can drag and drop places. Will provide a nice mixing palette. + */ +void sp_dropper_toolbox_prep(SPDesktop * /*desktop*/, GtkActionGroup* mainActions, GObject* holder) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + gint pickAlpha = prefs->getInt( "/tools/dropper/pick", 1 ); + + { + EgeOutputAction* act = ege_output_action_new( "DropperOpacityAction", _("Opacity:"), "", 0 ); + ege_output_action_set_use_markup( act, TRUE ); + gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); + } + + { + InkToggleAction* act = ink_toggle_action_new( "DropperPickAlphaAction", + _("Pick opacity"), + _("Pick both the color and the alpha (transparency) under cursor; otherwise, pick only the visible color premultiplied by alpha"), + NULL, + GTK_ICON_SIZE_MENU ); + g_object_set( act, "short_label", _("Pick"), NULL ); + gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); + g_object_set_data( holder, "pick_action", act ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), pickAlpha ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_dropper_pick_alpha), holder ); + } + + { + InkToggleAction* act = ink_toggle_action_new( "DropperSetAlphaAction", + _("Assign opacity"), + _("If alpha was picked, assign it to selection as fill or stroke transparency"), + NULL, + GTK_ICON_SIZE_MENU ); + g_object_set( act, "short_label", _("Assign"), NULL ); + gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); + g_object_set_data( holder, "set_action", act ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool( "/tools/dropper/setalpha", true) ); + // make sure it's disabled if we're not picking alpha + gtk_action_set_sensitive( GTK_ACTION(act), pickAlpha ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_dropper_set_alpha), holder ); + } +} + + +/* + 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:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/toolbar/dropper-toolbar.h b/src/ui/toolbar/dropper-toolbar.h new file mode 100644 index 000000000..8d5ea2d0a --- /dev/null +++ b/src/ui/toolbar/dropper-toolbar.h @@ -0,0 +1,37 @@ +#ifndef SEEN_DROPPER_TOOLBAR_H +#define SEEN_DROPPER_TOOLBAR_H + +/** + * @file + * Dropper aux toolbar + */ +/* Authors: + * MenTaLguY + * Lauris Kaplinski + * bulia byak + * Frank Felfe + * John Cliff + * David Turner + * Josh Andler + * Jon A. Cruz + * Maximilian Albert + * Tavmjong Bah + * Abhishek Sharma + * Kris De Gussem + * + * Copyright (C) 2004 David Turner + * Copyright (C) 2003 MenTaLguY + * Copyright (C) 1999-2011 authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +class SPDesktop; + +typedef struct _GtkActionGroup GtkActionGroup; +typedef struct _GObject GObject; + +void sp_dropper_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); + +#endif /* !SEEN_DROPPER_TOOLBAR_H */ diff --git a/src/ui/toolbar/eraser-toolbar.cpp b/src/ui/toolbar/eraser-toolbar.cpp new file mode 100644 index 000000000..26ff3a654 --- /dev/null +++ b/src/ui/toolbar/eraser-toolbar.cpp @@ -0,0 +1,318 @@ +/** + * @file + * Erasor aux toolbar + */ +/* Authors: + * MenTaLguY + * Lauris Kaplinski + * bulia byak + * Frank Felfe + * John Cliff + * David Turner + * Josh Andler + * Jon A. Cruz + * Maximilian Albert + * Tavmjong Bah + * Abhishek Sharma + * Kris De Gussem + * + * Copyright (C) 2004 David Turner + * Copyright (C) 2003 MenTaLguY + * Copyright (C) 1999-2011 authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include "eraser-toolbar.h" + +#include + +#include "desktop.h" +#include "document-undo.h" +#include "widgets/ege-adjustment-action.h" +#include "widgets/ink-toggle-action.h" +#include "widgets/toolbox.h" +#include "ui/widget/ink-select-one-action.h" +#include "ui/icon-names.h" +#include "ui/tools/eraser-tool.h" + +using Inkscape::DocumentUndo; +using Inkscape::UI::ToolboxFactory; +using Inkscape::UI::PrefPusher; + +//######################## +//## Eraser ## +//######################## + +// A dummy function for PrefPusher. +// The code was calling the update_presets_list function in the calligraphy tool +// which was immediately returning. TODO: Investigate this further. +void eraser_update_presets_list(GObject *tbl) +{ + return; +} + +static void sp_erc_width_value_changed( GtkAdjustment *adj, GObject *tbl ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble( "/tools/eraser/width", gtk_adjustment_get_value(adj) ); +} + +static void sp_erc_mass_value_changed( GtkAdjustment *adj, GObject* tbl ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble( "/tools/eraser/mass", gtk_adjustment_get_value(adj) ); +} + +static void sp_erc_velthin_value_changed( GtkAdjustment *adj, GObject* tbl ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble("/tools/eraser/thinning", gtk_adjustment_get_value(adj) ); +} + +static void sp_erc_cap_rounding_value_changed( GtkAdjustment *adj, GObject* tbl ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble( "/tools/eraser/cap_rounding", gtk_adjustment_get_value(adj) ); +} + +static void sp_erc_tremor_value_changed( GtkAdjustment *adj, GObject* tbl ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble( "/tools/eraser/tremor", gtk_adjustment_get_value(adj) ); +} + +static void sp_set_tbl_eraser_mode_visibility(GObject *const tbl, const guint eraser_mode) +{ + gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "split") ), (eraser_mode == ERASER_MODE_CUT)); + + const gboolean visibility = (eraser_mode != ERASER_MODE_DELETE); + const std::array arr = {"cap_rounding", "mass", "thinning", "tremor", "usepressure", "width"}; + for (const gchar * str : arr) { + gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, str) ), visibility ); + } +} + +static void sp_erasertb_mode_changed( GObject *tbl, int mode ) +{ + SPDesktop *desktop = static_cast(g_object_get_data( tbl, "desktop" )); + if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setInt( "/tools/eraser/mode", mode ); + } + sp_set_tbl_eraser_mode_visibility(tbl, mode); + + // only take action if run by the attr_changed listener + if (!g_object_get_data( tbl, "freeze" )) { + // in turn, prevent listener from responding + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); + + /* + if ( eraser_mode != ERASER_MODE_DELETE ) { + } else { + } + */ + // TODO finish implementation + + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); + } +} + +static void sp_toggle_break_apart( GtkToggleAction* act, gpointer data ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + gboolean active = gtk_toggle_action_get_active(act); + prefs->setBool("/tools/eraser/break_apart", active); +} + +void sp_eraser_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) +{ + GtkIconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + gint eraser_mode = ERASER_MODE_DELETE; + + { + InkSelectOneActionColumns columns; + + Glib::RefPtr store = Gtk::ListStore::create(columns); + + Gtk::TreeModel::Row row; + + row = *(store->append()); + row[columns.col_label ] = _("Delete"); + row[columns.col_tooltip ] = _("Delete objects touched by eraser"); + row[columns.col_icon ] = INKSCAPE_ICON("draw-eraser-delete-objects"); + row[columns.col_sensitive] = true; + + row = *(store->append()); + row[columns.col_label ] = _("Cut"); + row[columns.col_tooltip ] = _("Cut out from paths and shapes"); + row[columns.col_icon ] = INKSCAPE_ICON("path-difference"); + row[columns.col_sensitive] = true; + + row = *(store->append()); + row[columns.col_label ] = _("Clip"); + row[columns.col_tooltip ] = _("Clip from objects"); + row[columns.col_icon ] = INKSCAPE_ICON("path-intersection"); + row[columns.col_sensitive] = true; + + InkSelectOneAction* act = + InkSelectOneAction::create( "EraserModeAction", // Name + _("Mode"), // Label + "", // Tooltip + "Not Used", // Icon + store ); // Tree store + act->use_radio( true ); + act->use_group_label( true ); + eraser_mode = prefs->getInt("/tools/eraser/mode", ERASER_MODE_CLIP); // Used at end + act->set_active( eraser_mode ); + + gtk_action_group_add_action( mainActions, GTK_ACTION( act->gobj() )); + g_object_set_data( holder, "EraserModeAction", act ); + + act->signal_changed().connect(sigc::bind<0>(sigc::ptr_fun(&sp_erasertb_mode_changed), holder)); + } + + + /* Width */ + { + gchar const* labels[] = {_("(no width)"),_("(hairline)"), 0, 0, 0, _("(default)"), 0, 0, 0, 0, _("(broad stroke)")}; + gdouble values[] = {0, 1, 3, 5, 10, 15, 20, 30, 50, 75, 100}; + EgeAdjustmentAction *eact = create_adjustment_action( "EraserWidthAction", + _("Pen Width"), _("Width:"), + _("The width of the eraser pen (relative to the visible canvas area)"), + "/tools/eraser/width", 15, + GTK_WIDGET(desktop->canvas), holder, TRUE, "altx-eraser", + 0, 100, 1.0, 10.0, + labels, values, G_N_ELEMENTS(labels), + sp_erc_width_value_changed, NULL /*unit tracker*/, 1, 0); + ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + g_object_set_data( holder, "width", eact ); + gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); + } + + + /* Use Pressure button */ + { + InkToggleAction* act = ink_toggle_action_new( "EraserPressureAction", + _("Eraser Pressure"), + _("Use the pressure of the input device to alter the width of the pen"), + INKSCAPE_ICON("draw-use-pressure"), + GTK_ICON_SIZE_MENU ); + gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); + PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(act), "/tools/eraser/usepressure", eraser_update_presets_list, holder); + g_signal_connect( holder, "destroy", G_CALLBACK(delete_prefspusher), pusher); + g_object_set_data( holder, "usepressure", act ); + } + + + /* Thinning */ + { + gchar const* labels[] = {_("(speed blows up stroke)"), 0, 0, _("(slight widening)"), _("(constant width)"), _("(slight thinning, default)"), 0, 0, _("(speed deflates stroke)")}; + gdouble values[] = {-100, -40, -20, -10, 0, 10, 20, 40, 100}; + EgeAdjustmentAction* eact = create_adjustment_action( "EraserThinningAction", + _("Eraser Stroke Thinning"), _("Thinning:"), + _("How much velocity thins the stroke (> 0 makes fast strokes thinner, < 0 makes them broader, 0 makes width independent of velocity)"), + "/tools/eraser/thinning", 10, + GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, + -100, 100, 1, 10.0, + labels, values, G_N_ELEMENTS(labels), + sp_erc_velthin_value_changed, NULL /*unit tracker*/, 1, 0); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + g_object_set_data( holder, "thinning", eact ); + gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); + } + + + /* Cap Rounding */ + { + gchar const* labels[] = {_("(blunt caps, default)"), _("(slightly bulging)"), 0, 0, _("(approximately round)"), _("(long protruding caps)")}; + gdouble values[] = {0, 0.3, 0.5, 1.0, 1.4, 5.0}; + // TRANSLATORS: "cap" means "end" (both start and finish) here + EgeAdjustmentAction* eact = create_adjustment_action( "EraserCapRoundingAction", + _("Eraser Cap rounding"), _("Caps:"), + _("Increase to make caps at the ends of strokes protrude more (0 = no caps, 1 = round caps)"), + "/tools/eraser/cap_rounding", 0.0, + GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, + 0.0, 5.0, 0.01, 0.1, + labels, values, G_N_ELEMENTS(labels), + sp_erc_cap_rounding_value_changed, NULL /*unit tracker*/, 0.01, 2 ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + g_object_set_data( holder, "cap_rounding", eact ); + gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); + } + + + /* Tremor */ + { + gchar const* labels[] = {_("(smooth line)"), _("(slight tremor)"), _("(noticeable tremor)"), 0, 0, _("(maximum tremor)")}; + gdouble values[] = {0, 10, 20, 40, 60, 100}; + EgeAdjustmentAction* eact = create_adjustment_action( "EraserTremorAction", + _("EraserStroke Tremor"), _("Tremor:"), + _("Increase to make strokes rugged and trembling"), + "/tools/eraser/tremor", 0.0, + GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, + 0.0, 100, 1, 10.0, + labels, values, G_N_ELEMENTS(labels), + sp_erc_tremor_value_changed, NULL /*unit tracker*/, 1, 0); + + ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); + g_object_set_data( holder, "tremor", eact ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); + } + + + /* Mass */ + { + gchar const* labels[] = {_("(no inertia)"), _("(slight smoothing, default)"), _("(noticeable lagging)"), 0, 0, _("(maximum inertia)")}; + gdouble values[] = {0.0, 2, 10, 20, 50, 100}; + EgeAdjustmentAction* eact = create_adjustment_action( "EraserMassAction", + _("Eraser Mass"), _("Mass:"), + _("Increase to make the eraser drag behind, as if slowed by inertia"), + "/tools/eraser/mass", 10.0, + GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, + 0.0, 100, 1, 10.0, + labels, values, G_N_ELEMENTS(labels), + sp_erc_mass_value_changed, NULL /*unit tracker*/, 1, 0); + ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); + g_object_set_data( holder, "mass", eact ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); + } + + + /* Overlap */ + { + InkToggleAction* act = ink_toggle_action_new( "EraserBreakAppart", + _("Break apart cut items"), + _("Break apart cut items"), + INKSCAPE_ICON("distribute-randomize"), + secondarySize ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/eraser/break_apart", false) ); + g_object_set_data( holder, "split", act ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_break_apart), holder) ; + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + } + + sp_set_tbl_eraser_mode_visibility(holder, eraser_mode); +} + +/* + 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:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/toolbar/eraser-toolbar.h b/src/ui/toolbar/eraser-toolbar.h new file mode 100644 index 000000000..3c88d344e --- /dev/null +++ b/src/ui/toolbar/eraser-toolbar.h @@ -0,0 +1,37 @@ +#ifndef SEEN_ERASOR_TOOLBAR_H +#define SEEN_ERASOR_TOOLBAR_H + +/** + * @file + * Erasor aux toolbar + */ +/* Authors: + * MenTaLguY + * Lauris Kaplinski + * bulia byak + * Frank Felfe + * John Cliff + * David Turner + * Josh Andler + * Jon A. Cruz + * Maximilian Albert + * Tavmjong Bah + * Abhishek Sharma + * Kris De Gussem + * + * Copyright (C) 2004 David Turner + * Copyright (C) 2003 MenTaLguY + * Copyright (C) 1999-2011 authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +class SPDesktop; + +typedef struct _GtkActionGroup GtkActionGroup; +typedef struct _GObject GObject; + +void sp_eraser_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); + +#endif /* !SEEN_ERASOR_TOOLBAR_H */ diff --git a/src/ui/toolbar/gradient-toolbar.cpp b/src/ui/toolbar/gradient-toolbar.cpp new file mode 100644 index 000000000..38724aca4 --- /dev/null +++ b/src/ui/toolbar/gradient-toolbar.cpp @@ -0,0 +1,1274 @@ +/* + * Gradient aux toolbar + * + * Authors: + * bulia byak + * Johan Engelen + * 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 +#endif + +#include + + +#include "desktop.h" +#include "document-undo.h" +#include "document.h" +#include "gradient-chemistry.h" +#include "gradient-drag.h" +#include "gradient-toolbar.h" +#include "widgets/ink-action.h" +#include "widgets/ink-toggle-action.h" +#include "widgets/toolbox.h" +#include "macros.h" +#include "selection.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(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::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 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 gl; + std::vector gradients = document->getResourceList( "gradient" ); + for (std::vector::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::const_iterator it = gl.begin(); it != gl.end(); ++it) { + SPGradient *gradient = SP_GRADIENT(*it); + + Glib::ustring label = gr_prepare_label(gradient); + Glib::RefPtr 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::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(g_object_get_data(data, "gradient_stop_action")); + + int active = act->get_active(); + + Glib::RefPtr store = act->get_store(); + Gtk::TreeModel::Row row = store->children()[active]; + InkSelectOneActionColumns columns; + void* pointer = row[columns.col_data]; + SPStop *stop = static_cast(pointer); + + return stop; +} + +/* Add stop to gradient */ +static void gr_add_stop(GtkWidget * /*button*/, GObject *data) +{ + SPDesktop *desktop = static_cast(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(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(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(g_object_get_data(data, "gradient_stop_action")); + Glib::RefPtr 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 pixbuf = sp_gradstop_to_pixbuf_ref (stop, 32, 16); + + Inkscape::XML::Node *repr = reinterpret_cast(&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(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 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(g_object_get_data(data, "gradient_select_action")); + + int active = act->get_active(); + + Glib::RefPtr store = act->get_store(); + Gtk::TreeModel::Row row = store->children()[active]; + InkSelectOneActionColumns columns; + + void* pointer = row[columns.col_data]; + SPGradient *gr = static_cast(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(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(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(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(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 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 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 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 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 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(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(g_object_get_data(data, "gradient_select_action")); + Glib::RefPtr 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(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 : diff --git a/src/ui/toolbar/gradient-toolbar.h b/src/ui/toolbar/gradient-toolbar.h new file mode 100644 index 000000000..38afb743b --- /dev/null +++ b/src/ui/toolbar/gradient-toolbar.h @@ -0,0 +1,22 @@ +#ifndef SEEN_GRADIENT_TOOLBAR_H +#define SEEN_GRADIENT_TOOLBAR_H + +/* + * Gradient aux toolbar + * + * Authors: + * bulia byak + * + * Copyright (C) 2005 authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +class SPDesktop; + +typedef struct _GtkActionGroup GtkActionGroup; +typedef struct _GObject GObject; + +void sp_gradient_toolbox_prep(SPDesktop * /*desktop*/, GtkActionGroup* mainActions, GObject* holder); + +#endif /* !SEEN_GRADIENT_TOOLBAR_H */ diff --git a/src/ui/toolbar/lpe-toolbar.cpp b/src/ui/toolbar/lpe-toolbar.cpp new file mode 100644 index 000000000..bed5ed4bf --- /dev/null +++ b/src/ui/toolbar/lpe-toolbar.cpp @@ -0,0 +1,452 @@ +/** + * @file + * LPE aux toolbar + */ +/* Authors: + * MenTaLguY + * Lauris Kaplinski + * bulia byak + * Frank Felfe + * John Cliff + * David Turner + * Josh Andler + * Jon A. Cruz + * Maximilian Albert + * Tavmjong Bah + * Abhishek Sharma + * Kris De Gussem + * + * Copyright (C) 2004 David Turner + * Copyright (C) 2003 MenTaLguY + * Copyright (C) 1999-2011 authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "live_effects/lpe-line_segment.h" +#include "lpe-toolbar.h" + +#include "helper/action-context.h" +#include "helper/action.h" + +#include "widgets/ink-toggle-action.h" + +#include "ui/tools-switch.h" +#include "ui/tools/lpe-tool.h" +#include "ui/widget/ink-select-one-action.h" +#include "ui/widget/unit-tracker.h" + +using Inkscape::UI::Widget::UnitTracker; +using Inkscape::Util::Unit; +using Inkscape::Util::Quantity; +using Inkscape::DocumentUndo; +using Inkscape::UI::Tools::ToolBase; +using Inkscape::UI::Tools::LpeTool; + + +//######################## +//## LPETool ## +//######################## + +// the subtools from which the toolbar is built automatically are listed in lpe-tool-context.h + +// this is called when the mode is changed via the toolbar (i.e., one of the subtool buttons is pressed) +static void sp_lpetool_mode_changed(GObject *tbl, int mode) +{ + using namespace Inkscape::LivePathEffect; + + SPDesktop *desktop = static_cast(g_object_get_data(tbl, "desktop")); + ToolBase *ec = desktop->event_context; + if (!SP_IS_LPETOOL_CONTEXT(ec)) { + return; + } + + // only take action if run by the attr_changed listener + if (!g_object_get_data(tbl, "freeze")) { + // in turn, prevent listener from responding + g_object_set_data(tbl, "freeze", GINT_TO_POINTER(TRUE)); + + EffectType type = lpesubtools[mode].type; + + LpeTool *lc = SP_LPETOOL_CONTEXT(desktop->event_context); + bool success = lpetool_try_construction(lc, type); + if (success) { + // since the construction was already performed, we set the state back to inactive + InkSelectOneAction* act = + static_cast( g_object_get_data( tbl, "lpetool_mode_action" ) ); + act->set_active(0); + mode = 0; + } else { + // switch to the chosen subtool + SP_LPETOOL_CONTEXT(desktop->event_context)->mode = type; + } + + if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setInt( "/tools/lpetool/mode", mode ); + } + + g_object_set_data(tbl, "freeze", GINT_TO_POINTER(FALSE)); + } +} + +static void sp_lpetool_toolbox_sel_modified(Inkscape::Selection *selection, guint /*flags*/, GObject * /*tbl*/) +{ + ToolBase *ec = selection->desktop()->event_context; + if (SP_IS_LPETOOL_CONTEXT(ec)) { + lpetool_update_measuring_items(SP_LPETOOL_CONTEXT(ec)); + } +} + +static void sp_lpetool_toolbox_sel_changed(Inkscape::Selection *selection, GObject *tbl) +{ + using namespace Inkscape::LivePathEffect; + ToolBase *ec = selection->desktop()->event_context; + if (!SP_IS_LPETOOL_CONTEXT(ec)) { + return; + } + LpeTool *lc = SP_LPETOOL_CONTEXT(ec); + + lpetool_delete_measuring_items(lc); + lpetool_create_measuring_items(lc, selection); + + // activate line segment combo box if a single item with LPELineSegment is selected + InkSelectOneAction* act = + static_cast( g_object_get_data( tbl, "lpetool_line_segment_action" ) ); + + SPItem *item = selection->singleItem(); + if (item && SP_IS_LPE_ITEM(item) && lpetool_item_has_construction(lc, item)) { + + SPLPEItem *lpeitem = SP_LPE_ITEM(item); + Effect* lpe = lpeitem->getCurrentLPE(); + if (lpe && lpe->effectType() == LINE_SEGMENT) { + LPELineSegment *lpels = static_cast(lpe); + g_object_set_data(tbl, "currentlpe", lpe); + g_object_set_data(tbl, "currentlpeitem", lpeitem); + act->set_sensitive(true); + act->set_active( lpels->end_type.get_value() ); + } else { + g_object_set_data(tbl, "currentlpe", NULL); + g_object_set_data(tbl, "currentlpeitem", NULL); + act->set_sensitive(false); + } + + } else { + g_object_set_data(tbl, "currentlpe", NULL); + g_object_set_data(tbl, "currentlpeitem", NULL); + act->set_sensitive(false); + } +} + +static void lpetool_toggle_show_bbox(GtkToggleAction *act, gpointer data) { + SPDesktop *desktop = static_cast(data); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + + bool show = gtk_toggle_action_get_active( act ); + prefs->setBool("/tools/lpetool/show_bbox", show); + + if (tools_isactive(desktop, TOOLS_LPETOOL)) { + LpeTool *lc = SP_LPETOOL_CONTEXT(desktop->event_context); + lpetool_context_reset_limiting_bbox(lc); + } +} + +static void lpetool_toggle_show_measuring_info(GtkToggleAction *act, GObject *tbl) +{ + SPDesktop *desktop = static_cast(g_object_get_data(tbl, "desktop")); + if (!tools_isactive(desktop, TOOLS_LPETOOL)) { + return; + } + + bool show = gtk_toggle_action_get_active( act ); + + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setBool("/tools/lpetool/show_measuring_info", show); + + LpeTool *lc = SP_LPETOOL_CONTEXT(desktop->event_context); + lpetool_show_measuring_info(lc, show); + + InkSelectOneAction* unitact = + static_cast(g_object_get_data(tbl, "lpetool_units_action")); + unitact->set_sensitive( show ); +} + +static void lpetool_unit_changed(GObject* tbl, int /* NotUsed */) +{ + UnitTracker* tracker = reinterpret_cast(g_object_get_data(tbl, "tracker")); + Unit const *unit = tracker->getActiveUnit(); + g_return_if_fail(unit != NULL); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setString("/tools/lpetool/unit", unit->abbr); + + SPDesktop *desktop = static_cast(g_object_get_data( tbl, "desktop" )); + if (SP_IS_LPETOOL_CONTEXT(desktop->event_context)) { + LpeTool *lc = SP_LPETOOL_CONTEXT(desktop->event_context); + lpetool_delete_measuring_items(lc); + lpetool_create_measuring_items(lc); + } +} + +static void lpetool_toggle_set_bbox(GtkToggleAction *act, gpointer data) +{ + SPDesktop *desktop = static_cast(data); + Inkscape::Selection *selection = desktop->selection; + + Geom::OptRect bbox = selection->visualBounds(); + + if (bbox) { + Geom::Point A(bbox->min()); + Geom::Point B(bbox->max()); + + A *= desktop->doc2dt(); + B *= desktop->doc2dt(); + + // TODO: should we provide a way to store points in prefs? + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble("/tools/lpetool/bbox_upperleftx", A[Geom::X]); + prefs->setDouble("/tools/lpetool/bbox_upperlefty", A[Geom::Y]); + prefs->setDouble("/tools/lpetool/bbox_lowerrightx", B[Geom::X]); + prefs->setDouble("/tools/lpetool/bbox_lowerrighty", B[Geom::Y]); + + lpetool_context_reset_limiting_bbox(SP_LPETOOL_CONTEXT(desktop->event_context)); + } + + gtk_toggle_action_set_active(act, false); +} + +static void sp_lpetool_change_line_segment_type(GObject* tbl, int mode) +{ + using namespace Inkscape::LivePathEffect; + + // quit if run by the attr_changed listener + if (g_object_get_data(tbl, "freeze")) { + return; + } + + // in turn, prevent listener from responding + g_object_set_data(tbl, "freeze", GINT_TO_POINTER(TRUE)); + + LPELineSegment *lpe = static_cast(g_object_get_data(tbl, "currentlpe")); + SPLPEItem *lpeitem = static_cast(g_object_get_data(tbl, "currentlpeitem")); + if (lpeitem) { + SPLPEItem *lpeitem = static_cast(g_object_get_data(tbl, "currentlpeitem")); + lpe->end_type.param_set_value(static_cast(mode)); + sp_lpe_item_update_patheffect(lpeitem, true, true); + } + + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); +} + +static void lpetool_open_lpe_dialog(GtkToggleAction *act, gpointer data) +{ + SPDesktop *desktop = static_cast(data); + + if (tools_isactive(desktop, TOOLS_LPETOOL)) { + sp_action_perform(Inkscape::Verb::get(SP_VERB_DIALOG_LIVE_PATH_EFFECT)->get_action(Inkscape::ActionContext(desktop)), NULL); + } + gtk_toggle_action_set_active(act, false); +} + +static void lpetool_toolbox_watch_ec(SPDesktop* dt, Inkscape::UI::Tools::ToolBase* ec, GObject* holder); + +void sp_lpetool_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) +{ + UnitTracker* tracker = new UnitTracker(Inkscape::Util::UNIT_TYPE_LINEAR); + tracker->setActiveUnit(desktop->getNamedView()->display_units); + g_object_set_data(holder, "tracker", tracker); + Unit const *unit = tracker->getActiveUnit(); + g_return_if_fail(unit != NULL); + + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setString("/tools/lpetool/unit", unit->abbr); + + /** Automatically create a list of LPEs that get added to the toolbar **/ + { + InkSelectOneActionColumns columns; + + Glib::RefPtr store = Gtk::ListStore::create(columns); + + Gtk::TreeModel::Row row; + + // The first toggle button represents the state that no subtool is active. + row = *(store->append()); + row[columns.col_label ] = _("All inactive"); + row[columns.col_tooltip ] = _("No geometric tool is active"); + row[columns.col_icon ] = "draw-geometry-inactive"; + row[columns.col_sensitive] = true; + + Inkscape::LivePathEffect::EffectType type; + for (int i = 1; i < num_subtools; ++i) { // i == 0 ia INVALIDE_LPE. + + type = lpesubtools[i].type; + + row = *(store->append()); + row[columns.col_label ] = Inkscape::LivePathEffect::LPETypeConverter.get_label(type); + row[columns.col_tooltip ] = _(Inkscape::LivePathEffect::LPETypeConverter.get_label(type).c_str()); + row[columns.col_icon ] = lpesubtools[i].icon_name; + row[columns.col_sensitive] = true; + } + + InkSelectOneAction* act = + InkSelectOneAction::create( "LPEToolModeAction", // Name + (""), // Label + (""), // Tooltip + "Not Used", // Icon + store ); // Tree store + + act->use_radio( true ); + act->use_icon( true ); + act->use_label( false ); + int mode = prefs->getInt("/tools/lpetool/mode", 0); + act->set_active( mode ); + + gtk_action_group_add_action( mainActions, act->gobj() ); + g_object_set_data( holder, "lpetool_mode_action", act ); + + act->signal_changed().connect(sigc::bind<0>(sigc::ptr_fun(&sp_lpetool_mode_changed), holder)); + } + + /* Show limiting bounding box */ + { + InkToggleAction* act = ink_toggle_action_new( "LPEShowBBoxAction", + _("Show limiting bounding box"), + _("Show bounding box (used to cut infinite lines)"), + "show-bounding-box", + GTK_ICON_SIZE_MENU ); + gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(lpetool_toggle_show_bbox), desktop ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool( "/tools/lpetool/show_bbox", true ) ); + } + + /* Set limiting bounding box to bbox of current selection */ + { + InkToggleAction* act = ink_toggle_action_new( "LPEBBoxFromSelectionAction", + _("Get limiting bounding box from selection"), + _("Set limiting bounding box (used to cut infinite lines) to the bounding box of current selection"), + "draw-geometry-set-bounding-box", + GTK_ICON_SIZE_MENU ); + gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(lpetool_toggle_set_bbox), desktop ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), FALSE ); + } + + + /* Combo box to choose line segment type */ + { + InkSelectOneActionColumns columns; + + Glib::RefPtr store = Gtk::ListStore::create(columns); + + Gtk::TreeModel::Row row; + + row = *(store->append()); + row[columns.col_label ] = _("Closed"); + row[columns.col_tooltip ] = (""); + row[columns.col_icon ] = "NotUsed"; + row[columns.col_sensitive] = true; + + row = *(store->append()); + row[columns.col_label ] = _("Open start"); + row[columns.col_tooltip ] = (""); + row[columns.col_icon ] = "NotUsed"; + row[columns.col_sensitive] = true; + + row = *(store->append()); + row[columns.col_label ] = _("Open end"); + row[columns.col_tooltip ] = (""); + row[columns.col_icon ] = "NotUsed"; + row[columns.col_sensitive] = true; + + row = *(store->append()); + row[columns.col_label ] = _("Open both"); + row[columns.col_tooltip ] = (""); + row[columns.col_icon ] = "NotUsed"; + row[columns.col_sensitive] = true; + + InkSelectOneAction* act = + InkSelectOneAction::create( "LPELineSegmentAction", // Name + (""), // Label + _("Choose a line segment type"), // Tooltip + "Not Used", // Icon + store ); // Tree store + + act->use_radio( false ); + act->use_icon( false ); + act->use_label( true ); + act->set_sensitive( false ); + + gtk_action_group_add_action( mainActions, GTK_ACTION( act->gobj() )); + g_object_set_data (holder, "lpetool_line_segment_action", act ); + + act->signal_changed().connect(sigc::bind<0>(sigc::ptr_fun(sp_lpetool_change_line_segment_type), holder)); + } + + /* Display measuring info for selected items */ + { + InkToggleAction* act = ink_toggle_action_new( "LPEMeasuringAction", + _("Display measuring info"), + _("Display measuring info for selected items"), + "draw-geometry-show-measuring-info", + GTK_ICON_SIZE_MENU ); + gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(lpetool_toggle_show_measuring_info), holder ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool( "/tools/lpetool/show_measuring_info", true ) ); + } + + // Add the units menu + { + InkSelectOneAction* act = tracker->createAction( "LPEToolUnitsAction", _("Units"), ("") ); + gtk_action_group_add_action( mainActions, act->gobj() ); + act->signal_changed_after().connect(sigc::bind<0>(sigc::ptr_fun(&lpetool_unit_changed), holder)); + g_object_set_data(holder, "lpetool_units_action", act); + act->set_sensitive( prefs->getBool("/tools/lpetool/show_measuring_info", true)); + } + + /* Open LPE dialog (to adapt parameters numerically) */ + { + InkToggleAction* act = ink_toggle_action_new( "LPEOpenLPEDialogAction", + _("Open LPE dialog"), + _("Open LPE dialog (to adapt parameters numerically)"), + "dialog-geometry", + GTK_ICON_SIZE_MENU ); + gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(lpetool_open_lpe_dialog), desktop ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), FALSE ); + } + + desktop->connectEventContextChanged(sigc::bind(sigc::ptr_fun(lpetool_toolbox_watch_ec), holder)); +} + +static void lpetool_toolbox_watch_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolBase* ec, GObject* holder) +{ + static sigc::connection c_selection_modified; + static sigc::connection c_selection_changed; + + if (SP_IS_LPETOOL_CONTEXT(ec)) { + // Watch selection + c_selection_modified = desktop->getSelection()->connectModified(sigc::bind(sigc::ptr_fun(sp_lpetool_toolbox_sel_modified), holder)); + c_selection_changed = desktop->getSelection()->connectChanged(sigc::bind(sigc::ptr_fun(sp_lpetool_toolbox_sel_changed), holder)); + sp_lpetool_toolbox_sel_changed(desktop->getSelection(), holder); + } else { + if (c_selection_modified) + c_selection_modified.disconnect(); + if (c_selection_changed) + c_selection_changed.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:fileencoding=utf-8 : diff --git a/src/ui/toolbar/lpe-toolbar.h b/src/ui/toolbar/lpe-toolbar.h new file mode 100644 index 000000000..3db2bcb65 --- /dev/null +++ b/src/ui/toolbar/lpe-toolbar.h @@ -0,0 +1,37 @@ +#ifndef SEEN_LPE_TOOLBAR_H +#define SEEN_LPE_TOOLBAR_H + +/** + * @file + * LPE aux toolbar + */ +/* Authors: + * MenTaLguY + * Lauris Kaplinski + * bulia byak + * Frank Felfe + * John Cliff + * David Turner + * Josh Andler + * Jon A. Cruz + * Maximilian Albert + * Tavmjong Bah + * Abhishek Sharma + * Kris De Gussem + * + * Copyright (C) 2004 David Turner + * Copyright (C) 2003 MenTaLguY + * Copyright (C) 1999-2011 authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +class SPDesktop; + +typedef struct _GtkActionGroup GtkActionGroup; +typedef struct _GObject GObject; + +void sp_lpetool_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); + +#endif /* !SEEN_LPE_TOOLBAR_H */ diff --git a/src/ui/toolbar/measure-toolbar.cpp b/src/ui/toolbar/measure-toolbar.cpp new file mode 100644 index 000000000..ec9cffe25 --- /dev/null +++ b/src/ui/toolbar/measure-toolbar.cpp @@ -0,0 +1,477 @@ +/** + * @file + * Measure aux toolbar + */ +/* Authors: + * MenTaLguY + * Lauris Kaplinski + * bulia byak + * Frank Felfe + * John Cliff + * David Turner + * Josh Andler + * Jon A. Cruz + * Maximilian Albert + * Tavmjong Bah + * Abhishek Sharma + * Kris De Gussem + * + * Copyright (C) 2004 David Turner + * Copyright (C) 2003 MenTaLguY + * Copyright (C) 1999-2011 authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include "measure-toolbar.h" + +#include "desktop.h" +#include "document-undo.h" +#include "widgets/ink-action.h" +#include "widgets/ink-toggle-action.h" +#include "widgets/toolbox.h" +#include "inkscape.h" +#include "message-stack.h" + +#include "ui/icon-names.h" +#include "ui/tools/measure-tool.h" +#include "ui/widget/ink-select-one-action.h" +#include "ui/widget/unit-tracker.h" + +#include "widgets/ege-adjustment-action.h" +#include "widgets/ege-output-action.h" + +using Inkscape::UI::Widget::UnitTracker; +using Inkscape::Util::Unit; +using Inkscape::DocumentUndo; +using Inkscape::UI::ToolboxFactory; +using Inkscape::UI::PrefPusher; +using Inkscape::UI::Tools::MeasureTool; + +//######################## +//## Measure Toolbox ## +//######################## + +/** Temporary hack: Returns the node tool in the active desktop. + * Will go away during tool refactoring. */ +static MeasureTool *get_measure_tool() +{ + MeasureTool *tool = 0; + if (SP_ACTIVE_DESKTOP ) { + Inkscape::UI::Tools::ToolBase *ec = SP_ACTIVE_DESKTOP->event_context; + if (SP_IS_MEASURE_CONTEXT(ec)) { + tool = static_cast(ec); + } + } + return tool; +} + +static void +sp_measure_fontsize_value_changed(GtkAdjustment *adj, GObject *tbl) +{ + SPDesktop *desktop = static_cast(g_object_get_data( tbl, "desktop" )); + + if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble(Glib::ustring("/tools/measure/fontsize"), + gtk_adjustment_get_value(adj)); + MeasureTool *mt = get_measure_tool(); + if (mt) { + mt->showCanvasItems(); + } + } +} + +static void +sp_measure_offset_value_changed(GtkAdjustment *adj, GObject *tbl) +{ + SPDesktop *desktop = static_cast(g_object_get_data( tbl, "desktop" )); + + if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble(Glib::ustring("/tools/measure/offset"), + gtk_adjustment_get_value(adj)); + MeasureTool *mt = get_measure_tool(); + if (mt) { + mt->showCanvasItems(); + } + } +} + +static void sp_measure_scale_value_changed(GtkAdjustment *adj, GObject *tbl) +{ + SPDesktop *desktop = static_cast(g_object_get_data( tbl, "desktop" )); + + if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble(Glib::ustring("/tools/measure/scale"), + gtk_adjustment_get_value(adj)); + MeasureTool *mt = get_measure_tool(); + if (mt) { + mt->showCanvasItems(); + } + } +} + +static void +sp_measure_precision_value_changed(GtkAdjustment *adj, GObject *tbl) +{ + SPDesktop *desktop = static_cast(g_object_get_data( tbl, "desktop" )); + + if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setInt(Glib::ustring("/tools/measure/precision"), + gtk_adjustment_get_value(adj)); + MeasureTool *mt = get_measure_tool(); + if (mt) { + mt->showCanvasItems(); + } + } +} + +static void +sp_measure_unit_changed(GObject* tbl, int /* notUsed */) +{ + UnitTracker* tracker = reinterpret_cast(g_object_get_data(tbl, "tracker")); + Glib::ustring const unit = tracker->getActiveUnit()->abbr; + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setString("/tools/measure/unit", unit); + MeasureTool *mt = get_measure_tool(); + if (mt) { + mt->showCanvasItems(); + } +} + +static void +sp_toggle_ignore_1st_and_last( GtkToggleAction* act, gpointer data ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + gboolean active = gtk_toggle_action_get_active(act); + prefs->setBool("/tools/measure/ignore_1st_and_last", active); + SPDesktop *desktop = static_cast(data); + if ( active ) { + desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Start and end measures inactive.")); + } else { + desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Start and end measures active.")); + } + MeasureTool *mt = get_measure_tool(); + if (mt) { + mt->showCanvasItems(); + } +} + +static void +sp_toggle_only_selected( GtkToggleAction* act, gpointer data ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + gboolean active = gtk_toggle_action_get_active(act); + prefs->setBool("/tools/measure/only_selected", active); + SPDesktop *desktop = static_cast(data); + if ( active ) { + desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Measures only selected.")); + } else { + desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Measure all.")); + } + MeasureTool *mt = get_measure_tool(); + if (mt) { + mt->showCanvasItems(); + } +} + +static void +sp_toggle_show_hidden( GtkToggleAction* act, gpointer data ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + gboolean active = gtk_toggle_action_get_active(act); + prefs->setBool("/tools/measure/show_hidden", active); + SPDesktop *desktop = static_cast(data); + if ( active ) { + desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Show all crossings.")); + } else { + desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Show visible crossings.")); + } + MeasureTool *mt = get_measure_tool(); + if (mt) { + mt->showCanvasItems(); + } +} + +static void +sp_toggle_all_layers( GtkToggleAction* act, gpointer data ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + gboolean active = gtk_toggle_action_get_active(act); + prefs->setBool("/tools/measure/all_layers", active); + SPDesktop *desktop = static_cast(data); + if ( active ) { + desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Use all layers in the measure.")); + } else { + desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Use current layer in the measure.")); + } + MeasureTool *mt = get_measure_tool(); + if (mt) { + mt->showCanvasItems(); + } +} + +static void +sp_toggle_show_in_between( GtkToggleAction* act, gpointer data ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + gboolean active = gtk_toggle_action_get_active(act); + prefs->setBool("/tools/measure/show_in_between", active); + SPDesktop *desktop = static_cast(data); + if ( active ) { + desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Compute all elements.")); + } else { + desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Compute max length.")); + } + MeasureTool *mt = get_measure_tool(); + if (mt) { + mt->showCanvasItems(); + } +} +static void +sp_reverse_knots(void){ + MeasureTool *mt = get_measure_tool(); + if (mt) { + mt->reverseKnots(); + } +} + +static void +sp_to_mark_dimension(void){ + MeasureTool *mt = get_measure_tool(); + if (mt) { + mt->toMarkDimension(); + } +} + +static void +sp_to_guides(void){ + MeasureTool *mt = get_measure_tool(); + if (mt) { + mt->toGuides(); + } +} + +static void +sp_to_phantom(void){ + MeasureTool *mt = get_measure_tool(); + if (mt) { + mt->toPhantom(); + } +} + +static void +sp_to_item(void){ + MeasureTool *mt = get_measure_tool(); + if (mt) { + mt->toItem(); + } +} + +void sp_measure_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, GObject* holder) +{ + UnitTracker* tracker = new UnitTracker(Inkscape::Util::UNIT_TYPE_LINEAR); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + tracker->setActiveUnitByAbbr(prefs->getString("/tools/measure/unit").c_str()); + + g_object_set_data( holder, "tracker", tracker ); + + EgeAdjustmentAction *eact = 0; + GtkIconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1); + + /* Font Size */ + { + eact = create_adjustment_action( "MeasureFontSizeAction", + _("Font Size"), _("Font Size:"), + _("The font size to be used in the measurement labels"), + "/tools/measure/fontsize", 10.0, + GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, + 1.0, 36.0, 1.0, 4.0, + 0, 0, 0, + sp_measure_fontsize_value_changed, NULL, 0 , 2); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact)); + } + + /* units label */ + { + EgeOutputAction* act = ege_output_action_new( "measure_units_label", _("Units:"), _("The units to be used for the measurements"), 0 ); + ege_output_action_set_use_markup( act, TRUE ); + g_object_set( act, "visible-overflown", FALSE, NULL ); + gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); + } + + /* units menu */ + { + InkSelectOneAction* act = tracker->createAction( "MeasureUnitsAction", _("Units:"), _("The units to be used for the measurements") ); + act->signal_changed_after().connect(sigc::bind<0>(sigc::ptr_fun(&sp_measure_unit_changed), holder)); + gtk_action_group_add_action( mainActions, act->gobj() ); + } + + /* Precision */ + { + eact = create_adjustment_action( "MeasurePrecisionAction", + _("Precision"), _("Precision:"), + _("Decimal precision of measure"), + "/tools/measure/precision", 2, + GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, + 0, 10, 1, 0, + 0, 0, 0, + sp_measure_precision_value_changed, NULL, 0 ,0); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact)); + } + + /* Scale */ + { + eact = create_adjustment_action( "MeasureScaleAction", + _("Scale %"), _("Scale %:"), + _("Scale the results"), + "/tools/measure/scale", 100.0, + GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, + 0.0, 90000.0, 1.0, 4.0, + 0, 0, 0, + sp_measure_scale_value_changed, NULL, 0 , 3); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + } + + /* Offset */ + { + eact = create_adjustment_action( "MeasureOffsetAction", + _("Offset"), _("Offset:"), + _("Mark dimension offset"), + "/tools/measure/offset", 5.0, + GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, + 0.0, 90000.0, 1.0, 4.0, + 0, 0, 0, + sp_measure_offset_value_changed, NULL, 0 , 2); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + } + + /* measure only selected */ + { + InkToggleAction* act = ink_toggle_action_new( "MeasureOnlySelected", + _("Measure only selected"), + _("Measure only selected"), + INKSCAPE_ICON("snap-bounding-box-center"), + secondarySize ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/measure/only_selected", false) ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_only_selected), desktop) ; + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + } + + /* ignore_1st_and_last */ + { + InkToggleAction* act = ink_toggle_action_new( "MeasureIgnore1stAndLast", + _("Ignore first and last"), + _("Ignore first and last"), + INKSCAPE_ICON("draw-geometry-line-segment"), + secondarySize ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/measure/ignore_1st_and_last", true) ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_ignore_1st_and_last), desktop) ; + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + } + /* only visible */ + { + InkToggleAction* act = ink_toggle_action_new( "MeasureShowHidden", + _("Show hidden intersections"), + _("Show hidden intersections"), + INKSCAPE_ICON("object-hidden"), + secondarySize ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/measure/show_hidden", true) ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_show_hidden), desktop) ; + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + } + /* measure imbetweens */ + { + InkToggleAction* act = ink_toggle_action_new( "MeasureInBettween", + _("Show measures between items"), + _("Show measures between items"), + INKSCAPE_ICON("distribute-randomize"), + secondarySize ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/measure/show_in_between", true) ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_show_in_between), desktop) ; + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + } + /* measure only current layer */ + { + InkToggleAction* act = ink_toggle_action_new( "MeasureAllLayers", + _("Measure all layers"), + _("Measure all layers"), + INKSCAPE_ICON("dialog-layers"), + secondarySize ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/measure/all_layers", true) ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_all_layers), desktop) ; + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + } + /* toggle start end */ + { + InkAction* act = ink_action_new( "MeasureReverse", + _("Reverse measure"), + _("Reverse measure"), + INKSCAPE_ICON("draw-geometry-mirror"), + secondarySize ); + g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(sp_reverse_knots), 0 ); + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + } + /* phantom measure */ + { + InkAction* act = ink_action_new( "MeasureToPhantom", + _("Phantom measure"), + _("Phantom measure"), + INKSCAPE_ICON("selection-make-bitmap-copy"), + secondarySize ); + g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(sp_to_phantom), 0 ); + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + } + /* to guides */ + { + InkAction* act = ink_action_new( "MeasureToGuides", + _("To guides"), + _("To guides"), + INKSCAPE_ICON("guides"), + secondarySize ); + g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(sp_to_guides), 0 ); + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + } + /* to mark dimensions */ + { + InkAction* act = ink_action_new( "MeasureMarkDimension", + _("Mark Dimension"), + _("Mark Dimension"), + INKSCAPE_ICON("tool-pointer"), + secondarySize ); + g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(sp_to_mark_dimension), 0 ); + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + } + /* to item */ + { + InkAction* act = ink_action_new( "MeasureToItem", + _("Convert to item"), + _("Convert to item"), + INKSCAPE_ICON("path-reverse"), + secondarySize ); + g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(sp_to_item), 0 ); + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + } +} // end of sp_measure_toolbox_prep() + + +/* + 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:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/toolbar/measure-toolbar.h b/src/ui/toolbar/measure-toolbar.h new file mode 100644 index 000000000..aff0a209b --- /dev/null +++ b/src/ui/toolbar/measure-toolbar.h @@ -0,0 +1,37 @@ +#ifndef SEEN_MEASURE_TOOLBAR_H +#define SEEN_MEASURE_TOOLBAR_H + +/** + * @file + * Measue aux toolbar + */ +/* Authors: + * MenTaLguY + * Lauris Kaplinski + * bulia byak + * Frank Felfe + * John Cliff + * David Turner + * Josh Andler + * Jon A. Cruz + * Maximilian Albert + * Tavmjong Bah + * Abhishek Sharma + * Kris De Gussem + * + * Copyright (C) 2004 David Turner + * Copyright (C) 2003 MenTaLguY + * Copyright (C) 1999-2011 authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +class SPDesktop; + +typedef struct _GtkActionGroup GtkActionGroup; +typedef struct _GObject GObject; + +void sp_measure_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); + +#endif /* !SEEN_MEASURE_TOOLBAR_H */ diff --git a/src/ui/toolbar/mesh-toolbar.cpp b/src/ui/toolbar/mesh-toolbar.cpp new file mode 100644 index 000000000..fdeb736e6 --- /dev/null +++ b/src/ui/toolbar/mesh-toolbar.cpp @@ -0,0 +1,668 @@ +/* + * Gradient aux toolbar + * + * Authors: + * bulia byak + * Johan Engelen + * Abhishek Sharma + * Tavmjong Bah + * + * Copyright (C) 2012 Tavmjong Bah + * 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 +#endif + +#include +#include + +#include "mesh-toolbar.h" + +#include "desktop-style.h" +#include "desktop.h" +#include "document-private.h" +#include "document-undo.h" +#include "gradient-chemistry.h" +#include "gradient-drag.h" +#include "widgets/ink-action.h" +#include "widgets/ink-toggle-action.h" +#include "inkscape.h" +#include "widgets/toolbox.h" +#include "verbs.h" + +#include "object/sp-defs.h" +#include "object/sp-mesh-gradient.h" +#include "object/sp-stop.h" +#include "style.h" + +#include "svg/css-ostringstream.h" + +#include "ui/icon-names.h" +#include "ui/tools/gradient-tool.h" +#include "ui/tools/mesh-tool.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/spinbutton-events.h" + +using Inkscape::DocumentUndo; +using Inkscape::UI::ToolboxFactory; +using Inkscape::UI::PrefPusher; +using Inkscape::UI::Tools::MeshTool; + +static bool blocked = false; + +//######################## +//## Mesh ## +//######################## + + +// Get a list of selected meshes taking into account fill/stroke toggles +std::vector ms_get_dt_selected_gradients(Inkscape::Selection *selection) +{ + std::vector ms_selected; + + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + bool edit_fill = prefs->getBool("/tools/mesh/edit_fill", true); + bool edit_stroke = prefs->getBool("/tools/mesh/edit_stroke", true); + + 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; + + if (style) { + + + if (edit_fill && style->fill.isPaintserver()) { + SPPaintServer *server = item->style->getFillPaintServer(); + SPMeshGradient *mesh = dynamic_cast(server); + if (mesh) { + ms_selected.push_back(mesh); + } + } + + if (edit_stroke && style->stroke.isPaintserver()) { + SPPaintServer *server = item->style->getStrokePaintServer(); + SPMeshGradient *mesh = dynamic_cast(server); + if (mesh) { + ms_selected.push_back(mesh); + } + } + } + + } + return ms_selected; +} + + +/* + * Get the current selection status from the desktop + */ +void ms_read_selection( Inkscape::Selection *selection, + SPMeshGradient *&ms_selected, + bool &ms_selected_multi, + SPMeshType &ms_type, + bool &ms_type_multi ) +{ + ms_selected = NULL; + ms_selected_multi = false; + ms_type = SP_MESH_TYPE_COONS; + ms_type_multi = false; + + bool first = true; + + // Read desktop selection, taking into account fill/stroke toggles + std::vector meshes = ms_get_dt_selected_gradients( selection ); + for (auto i = meshes.begin(); i != meshes.end(); ++i) { + if (first) { + ms_selected = (*i); + ms_type = (*i)->type; + first = false; + } else { + if (ms_selected != (*i)) { + ms_selected_multi = true; + } + if (ms_type != (*i)->type) { + ms_type_multi = true; + } + } + } +} + +/* + * Core function, setup all the widgets whenever something changes on the desktop + */ +static void ms_tb_selection_changed(Inkscape::Selection * /*selection*/, gpointer data) +{ + + // std::cout << "ms_tb_selection_changed" << std::endl; + + if (blocked) + return; + + SPDesktop *desktop = static_cast(g_object_get_data(G_OBJECT(data), "desktop")); + if (!desktop) { + return; + } + + Inkscape::Selection *selection = desktop->getSelection(); // take from desktop, not from args + if (selection) { + // ToolBase *ev = sp_desktop_event_context(desktop); + // GrDrag *drag = NULL; + // if (ev) { + // drag = ev->get_drag(); + // // Hide/show handles? + // } + + SPMeshGradient *ms_selected = 0; + SPMeshType ms_type = SP_MESH_TYPE_COONS; + bool ms_selected_multi = false; + bool ms_type_multi = false; + ms_read_selection( selection, ms_selected, ms_selected_multi, ms_type, ms_type_multi ); + // std::cout << " type: " << ms_type << std::endl; + + InkSelectOneAction* type = static_cast (g_object_get_data(G_OBJECT(data), "mesh_select_type_action")); + if (type) { + type->set_sensitive(!ms_type_multi); + blocked = TRUE; + type->set_active(ms_type); + blocked = FALSE; + } + } +} + + +static void ms_tb_selection_modified(Inkscape::Selection *selection, guint /*flags*/, gpointer data) +{ + ms_tb_selection_changed(selection, data); +} + +static void ms_drag_selection_changed(gpointer /*dragger*/, gpointer data) +{ + ms_tb_selection_changed(NULL, data); + +} + +static void ms_defs_release(SPObject * /*defs*/, GObject *widget) +{ + ms_tb_selection_changed(NULL, widget); +} + +static void ms_defs_modified(SPObject * /*defs*/, guint /*flags*/, GObject *widget) +{ + ms_tb_selection_changed(NULL, widget); +} + +/* + * Callback functions for user actions + */ + +static void ms_new_geometry_changed( GObject * /*tbl*/, int mode ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setInt("/tools/mesh/mesh_geometry", mode); +} + +static void ms_new_fillstroke_changed( GObject * /*tbl*/, int mode ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setInt("/tools/mesh/newfillorstroke", mode); +} + +static void ms_row_changed(GtkAdjustment *adj, GObject * /*tbl*/ ) +{ + if (blocked) { + return; + } + + blocked = TRUE; + + int rows = gtk_adjustment_get_value(adj); + + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + + prefs->setInt("/tools/mesh/mesh_rows", rows); + + blocked = FALSE; +} + +static void ms_col_changed(GtkAdjustment *adj, GObject * /*tbl*/ ) +{ + if (blocked) { + return; + } + + blocked = TRUE; + + int cols = gtk_adjustment_get_value(adj); + + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + + prefs->setInt("/tools/mesh/mesh_cols", cols); + + blocked = FALSE; +} + +/** + * Sets mesh type: Coons, Bicubic + */ +static void ms_type_changed( GObject *tbl, int mode ) +{ + if (blocked) { + return; + } + + SPDesktop *desktop = static_cast(g_object_get_data(tbl, "desktop")); + Inkscape::Selection *selection = desktop->getSelection(); + std::vector meshes = ms_get_dt_selected_gradients(selection); + + SPMeshType type = (SPMeshType) mode; + for (auto i = meshes.begin(); i != meshes.end(); ++i) { + (*i)->type = type; + (*i)->type_set = true; + (*i)->updateRepr(); + } + if (!meshes.empty() ) { + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_MESH,_("Set mesh type")); + } +} + +/** Temporary hack: Returns the mesh tool in the active desktop. + * Will go away during tool refactoring. */ +static MeshTool *get_mesh_tool() +{ + MeshTool *tool = 0; + if (SP_ACTIVE_DESKTOP ) { + Inkscape::UI::Tools::ToolBase *ec = SP_ACTIVE_DESKTOP->event_context; + if (SP_IS_MESH_CONTEXT(ec)) { + tool = static_cast(ec); + } + } + return tool; +} + +static void ms_toggle_sides(void) +{ + MeshTool *mt = get_mesh_tool(); + if (mt) { + sp_mesh_context_corner_operation( mt, MG_CORNER_SIDE_TOGGLE ); + } +} + +static void ms_make_elliptical(void) +{ + MeshTool *mt = get_mesh_tool(); + if (mt) { + sp_mesh_context_corner_operation( mt, MG_CORNER_SIDE_ARC ); + } +} + +static void ms_pick_colors(void) +{ + MeshTool *mt = get_mesh_tool(); + if (mt) { + sp_mesh_context_corner_operation( mt, MG_CORNER_COLOR_PICK ); + } +} + +static void ms_fit_mesh(void) +{ + MeshTool *mt = get_mesh_tool(); + if (mt) { + sp_mesh_context_fit_mesh_in_bbox( mt ); + } +} + +static void ms_toggle_handles(void) +{ + MeshTool *mt = get_mesh_tool(); + if (mt) { + GrDrag *drag = mt->_grdrag; + drag->refreshDraggers(); + } +} + +static void ms_toggle_fill_stroke(InkToggleAction * /*act*/, gpointer data) +{ + MeshTool *mt = get_mesh_tool(); + if (mt) { + GrDrag *drag = mt->_grdrag; + drag->updateDraggers(); + drag->updateLines(); + drag->updateLevels(); + ms_tb_selection_changed(NULL, data); // Need to update Type widget + } +} + +static void ms_warning_popup(void) +{ + char *msg = _("Mesh gradients are part of SVG 2:\n" + "* Syntax may change.\n" + "* Web browser implementation is not guaranteed.\n" + "\n" + "For web: convert to bitmap (Edit->Make bitmap copy).\n" + "For print: export to PDF."); + Gtk::MessageDialog dialog(msg, false, Gtk::MESSAGE_WARNING, + Gtk::BUTTONS_OK, true); + dialog.run(); + +} + +static void mesh_toolbox_watch_ec(SPDesktop* dt, Inkscape::UI::Tools::ToolBase* ec, GObject* holder); + +/** + * Mesh auxiliary toolbar construction and setup. + * Don't forget to add to XML in widgets/toolbox.cpp! + * + */ +void sp_mesh_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, GObject* holder) +{ + GtkIconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1); + + EgeAdjustmentAction* eact = 0; + + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + + /* New mesh: normal or conical */ + { + InkSelectOneActionColumns columns; + + Glib::RefPtr store = Gtk::ListStore::create(columns); + + Gtk::TreeModel::Row row; + + row = *(store->append()); + row[columns.col_label ] = _("normal"); + row[columns.col_tooltip ] = _("Create mesh gradient"); + row[columns.col_icon ] = INKSCAPE_ICON("paint-gradient-mesh"); + row[columns.col_sensitive] = true; + + row = *(store->append()); + row[columns.col_label ] = _("conical"); + row[columns.col_tooltip ] = _("Create conical gradient"); + row[columns.col_icon ] = INKSCAPE_ICON("paint-gradient-conical"); + row[columns.col_sensitive] = true; + + InkSelectOneAction* act = + InkSelectOneAction::create( "MeshNewTypeAction", // Name + _("New:"), // Label + "", // Tooltip + "Not Used", // Icon + store ); // Tree store + + act->use_radio( true ); + act->use_group_label( true ); + gint mode = prefs->getInt("/tools/mesh/mesh_geometry", SP_MESH_GEOMETRY_NORMAL); + act->set_active( mode ); + + gtk_action_group_add_action( mainActions, GTK_ACTION( act->gobj() )); + g_object_set_data( holder, "mesh_new_type_mode", act ); + + act->signal_changed().connect(sigc::bind<0>(sigc::ptr_fun(&ms_new_geometry_changed), holder)); + } + + /* New gradient on fill or stroke*/ + { + InkSelectOneActionColumns columns; + + Glib::RefPtr 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( "MeshNewFillStrokeAction", // Name + "", // Label + "", // Tooltip + "Not Used", // Icon + store ); // Tree store + + act->use_radio( true ); + act->use_group_label( false ); + gint mode = prefs->getInt("/tools/mesh/newfillorstroke"); + act->set_active( mode ); + + gtk_action_group_add_action( mainActions, GTK_ACTION( act->gobj() )); + g_object_set_data( holder, "mesh_new_type_mode", act ); + + act->signal_changed().connect(sigc::bind<0>(sigc::ptr_fun(&ms_new_fillstroke_changed), holder)); + } + + /* Number of mesh rows */ + { + gchar const** labels = NULL; + gdouble values[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + eact = create_adjustment_action( "MeshRowAction", + _("Rows"), _("Rows:"), _("Number of rows in new mesh"), + "/tools/mesh/mesh_rows", 1, + GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, + 1, 20, 1, 1, + labels, values, 0, + ms_row_changed, NULL /*unit tracker*/, + 1.0, 0 ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); + } + + /* Number of mesh columns */ + { + gchar const** labels = NULL; + gdouble values[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + eact = create_adjustment_action( "MeshColumnAction", + _("Columns"), _("Columns:"), _("Number of columns in new mesh"), + "/tools/mesh/mesh_cols", 1, + GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, + 1, 20, 1, 1, + labels, values, 0, + ms_col_changed, NULL /*unit tracker*/, + 1.0, 0 ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); + } + + /* Edit fill mesh */ + { + InkToggleAction* act = ink_toggle_action_new( "MeshEditFillAction", + _("Edit Fill"), + _("Edit fill mesh"), + INKSCAPE_ICON("object-fill"), + secondarySize ); + gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); + PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(act), "/tools/mesh/edit_fill"); + g_signal_connect( holder, "destroy", G_CALLBACK(delete_prefspusher), pusher); + g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(ms_toggle_fill_stroke), holder); + } + + /* Edit stroke mesh */ + { + InkToggleAction* act = ink_toggle_action_new( "MeshEditStrokeAction", + _("Edit Stroke"), + _("Edit stroke mesh"), + INKSCAPE_ICON("object-stroke"), + secondarySize ); + gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); + PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(act), "/tools/mesh/edit_stroke"); + g_signal_connect( holder, "destroy", G_CALLBACK(delete_prefspusher), pusher); + g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(ms_toggle_fill_stroke), holder); + } + + /* Show/hide side and tensor handles */ + { + InkToggleAction* act = ink_toggle_action_new( "MeshShowHandlesAction", + _("Show Handles"), + _("Show handles"), + INKSCAPE_ICON("show-node-handles"), + secondarySize ); + gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); + PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(act), "/tools/mesh/show_handles"); + g_signal_connect( holder, "destroy", G_CALLBACK(delete_prefspusher), pusher); + g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(ms_toggle_handles), 0); + } + + g_object_set_data(holder, "desktop", desktop); + + desktop->connectEventContextChanged(sigc::bind(sigc::ptr_fun(mesh_toolbox_watch_ec), holder)); + + /* Warning */ + { + InkAction* act = ink_action_new( "MeshWarningAction", + _("WARNING: Mesh SVG Syntax Subject to Change"), + _("WARNING: Mesh SVG Syntax Subject to Change"), + INKSCAPE_ICON("dialog-warning"), + secondarySize ); + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(ms_warning_popup), holder ); + gtk_action_set_sensitive( GTK_ACTION(act), TRUE ); + } + + /* Type */ + { + InkSelectOneActionColumns columns; + + Glib::RefPtr store = Gtk::ListStore::create(columns); + + Gtk::TreeModel::Row row; + + row = *(store->append()); + row[columns.col_label ] = C_("Type", "Coons"); + row[columns.col_tooltip ] = ""; + row[columns.col_icon ] = "NotUsed"; + row[columns.col_sensitive] = true; + + row = *(store->append()); + row[columns.col_label ] = _("Bicubic"); + row[columns.col_tooltip ] = ""; + row[columns.col_icon ] = "NotUsed"; + row[columns.col_sensitive] = true; + + // TRANSLATORS: Type of Smoothing. See https://en.wikipedia.org/wiki/Coons_patch + InkSelectOneAction* act = + InkSelectOneAction::create( "MeshSmoothAction", // Name + _("Smoothing"), // Label + _("Coons: no smothing. Bicubic: smothing across patch boundaries."), // Tooltip + "Not Used", // Icon + store ); // Tree store + + act->use_radio( false ); + act->use_label( true ); + act->use_icon( false ); + act->use_group_label( true ); + act->set_sensitive( false ); + act->set_active( 0 ); + + gtk_action_group_add_action( mainActions, GTK_ACTION( act->gobj() )); + g_object_set_data( holder, "mesh_select_type_action", act ); + + act->signal_changed().connect(sigc::bind<0>(sigc::ptr_fun(&ms_type_changed), holder)); + } + + { + InkAction* act = ink_action_new( "MeshToggleSidesAction", + _("Toggle Sides"), + _("Toggle selected sides between Beziers and lines."), + INKSCAPE_ICON("node-segment-line"), + secondarySize ); + g_object_set( act, "short_label", _("Toggle side:"), NULL ); + g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(ms_toggle_sides), 0 ); + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + } + + { + InkAction* act = ink_action_new( "MeshMakeEllipticalAction", + _("Make elliptical"), + _("Make selected sides elliptical by changing length of handles. Works best if handles already approximate ellipse."), + INKSCAPE_ICON("node-segment-curve"), + secondarySize ); + g_object_set( act, "short_label", _("Make elliptical:"), NULL ); + g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(ms_make_elliptical), 0 ); + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + } + + { + InkAction* act = ink_action_new( "MeshPickColorsAction", + _("Pick colors:"), + _("Pick colors for selected corner nodes from underneath mesh."), + INKSCAPE_ICON("color-picker"), + secondarySize ); + g_object_set( act, "short_label", _("Pick Color"), NULL ); + g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(ms_pick_colors), 0 ); + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + } + + + { + InkAction* act = ink_action_new( "MeshFitInBoundingBoxAction", + _("Scale mesh to bounding box:"), + _("Scale mesh to fit inside bounding box."), + INKSCAPE_ICON("mesh-gradient-fit"), + secondarySize ); + g_object_set( act, "short_label", _("Fit mesh"), NULL ); + g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(ms_fit_mesh), 0 ); + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + } + +} + +static void mesh_toolbox_watch_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolBase* ec, GObject* holder) +{ + static sigc::connection c_selection_changed; + static sigc::connection c_selection_modified; + static sigc::connection c_subselection_changed; + static sigc::connection c_defs_release; + static sigc::connection c_defs_modified; + + if (SP_IS_MESH_CONTEXT(ec)) { + // connect to selection modified and changed signals + Inkscape::Selection *selection = desktop->getSelection(); + SPDocument *document = desktop->getDocument(); + + c_selection_changed = selection->connectChanged(sigc::bind(sigc::ptr_fun(&ms_tb_selection_changed), holder)); + c_selection_modified = selection->connectModified(sigc::bind(sigc::ptr_fun(&ms_tb_selection_modified), holder)); + c_subselection_changed = desktop->connectToolSubselectionChanged(sigc::bind(sigc::ptr_fun(&ms_drag_selection_changed), holder)); + + c_defs_release = document->getDefs()->connectRelease(sigc::bind<1>(sigc::ptr_fun(&ms_defs_release), holder)); + c_defs_modified = document->getDefs()->connectModified(sigc::bind<2>(sigc::ptr_fun(&ms_defs_modified), holder)); + ms_tb_selection_changed(selection, holder); + } else { + if (c_selection_changed) + c_selection_changed.disconnect(); + if (c_selection_modified) + c_selection_modified.disconnect(); + if (c_subselection_changed) + c_subselection_changed.disconnect(); + if (c_defs_release) + c_defs_release.disconnect(); + if (c_defs_modified) + c_defs_modified.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 : diff --git a/src/ui/toolbar/mesh-toolbar.h b/src/ui/toolbar/mesh-toolbar.h new file mode 100644 index 000000000..fd3f4b4b7 --- /dev/null +++ b/src/ui/toolbar/mesh-toolbar.h @@ -0,0 +1,24 @@ +#ifndef SEEN_MESH_TOOLBAR_H +#define SEEN_MESH_TOOLBAR_H + +/* + * Mesh aux toolbar + * + * Authors: + * bulia byak + * Tavmjong Bah + * + * Copyright (C) 2012 authors + * Copyright (C) 2005 authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +class SPDesktop; + +typedef struct _GtkActionGroup GtkActionGroup; +typedef struct _GObject GObject; + +void sp_mesh_toolbox_prep( SPDesktop * /*desktop*/, GtkActionGroup* mainActions, GObject* holder); + +#endif /* !SEEN_MESH_TOOLBAR_H */ diff --git a/src/ui/toolbar/node-toolbar.cpp b/src/ui/toolbar/node-toolbar.cpp new file mode 100644 index 000000000..a5e6a68ad --- /dev/null +++ b/src/ui/toolbar/node-toolbar.cpp @@ -0,0 +1,656 @@ +/** + * @file + * Node aux toolbar + */ +/* Authors: + * MenTaLguY + * Lauris Kaplinski + * bulia byak + * Frank Felfe + * John Cliff + * David Turner + * Josh Andler + * Jon A. Cruz + * Maximilian Albert + * Tavmjong Bah + * Abhishek Sharma + * Kris De Gussem + * + * Copyright (C) 2004 David Turner + * Copyright (C) 2003 MenTaLguY + * Copyright (C) 1999-2011 authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + + +#include "desktop.h" +#include "document-undo.h" +#include "widgets/ink-toggle-action.h" +#include "widgets/ink-tool-menu-action.h" +#include "widgets/toolbox.h" +#include "inkscape.h" +#include "node-toolbar.h" +#include "selection-chemistry.h" +#include "verbs.h" + +#include "object/sp-namedview.h" + +#include "ui/icon-names.h" +#include "ui/tool/control-point-selection.h" +#include "ui/tool/multi-path-manipulator.h" +#include "ui/tools/node-tool.h" +#include "ui/widget/ink-select-one-action.h" +#include "ui/widget/unit-tracker.h" + +#include "widgets/ege-adjustment-action.h" +#include "widgets/widget-sizes.h" + +using Inkscape::UI::Widget::UnitTracker; +using Inkscape::Util::Unit; +using Inkscape::Util::Quantity; +using Inkscape::DocumentUndo; +using Inkscape::UI::ToolboxFactory; +using Inkscape::UI::PrefPusher; +using Inkscape::Util::unit_table; +using Inkscape::UI::Tools::NodeTool; + +//#################################### +//# node editing callbacks +//#################################### + +/** Temporary hack: Returns the node tool in the active desktop. + * Will go away during tool refactoring. */ +static NodeTool *get_node_tool() +{ + NodeTool *tool = 0; + if (SP_ACTIVE_DESKTOP ) { + Inkscape::UI::Tools::ToolBase *ec = SP_ACTIVE_DESKTOP->event_context; + if (INK_IS_NODE_TOOL(ec)) { + tool = static_cast(ec); + } + } + return tool; +} + +static void sp_node_path_edit_add(void) +{ + NodeTool *nt = get_node_tool(); + if (nt) { + nt->_multipath->insertNodes(); + } +} + +static void sp_node_path_edit_add_min_x(void) +{ + NodeTool *nt = get_node_tool(); + if (nt) { + nt->_multipath->insertNodesAtExtrema(Inkscape::UI::PointManipulator::EXTR_MIN_X); + } +} +static void sp_node_path_edit_add_max_x(void) +{ + NodeTool *nt = get_node_tool(); + if (nt) { + nt->_multipath->insertNodesAtExtrema(Inkscape::UI::PointManipulator::EXTR_MAX_X); + } +} +static void sp_node_path_edit_add_min_y(void) +{ + NodeTool *nt = get_node_tool(); + if (nt) { + nt->_multipath->insertNodesAtExtrema(Inkscape::UI::PointManipulator::EXTR_MIN_Y); + } +} +static void sp_node_path_edit_add_max_y(void) +{ + NodeTool *nt = get_node_tool(); + if (nt) { + nt->_multipath->insertNodesAtExtrema(Inkscape::UI::PointManipulator::EXTR_MAX_Y); + } +} + +static void sp_node_path_edit_delete(void) +{ + NodeTool *nt = get_node_tool(); + if (nt) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + nt->_multipath->deleteNodes(prefs->getBool("/tools/nodes/delete_preserves_shape", true)); + } +} + +static void sp_node_path_edit_delete_segment(void) +{ + NodeTool *nt = get_node_tool(); + if (nt) { + nt->_multipath->deleteSegments(); + } +} + +static void sp_node_path_edit_break(void) +{ + NodeTool *nt = get_node_tool(); + if (nt) { + nt->_multipath->breakNodes(); + } +} + +static void sp_node_path_edit_join(void) +{ + NodeTool *nt = get_node_tool(); + if (nt) { + nt->_multipath->joinNodes(); + } +} + +static void sp_node_path_edit_join_segment(void) +{ + NodeTool *nt = get_node_tool(); + if (nt) { + nt->_multipath->joinSegments(); + } +} + +static void sp_node_path_edit_toline(void) +{ + NodeTool *nt = get_node_tool(); + if (nt) { + nt->_multipath->setSegmentType(Inkscape::UI::SEGMENT_STRAIGHT); + } +} + +static void sp_node_path_edit_tocurve(void) +{ + NodeTool *nt = get_node_tool(); + if (nt) { + nt->_multipath->setSegmentType(Inkscape::UI::SEGMENT_CUBIC_BEZIER); + } +} + +static void sp_node_path_edit_cusp(void) +{ + NodeTool *nt = get_node_tool(); + if (nt) { + nt->_multipath->setNodeType(Inkscape::UI::NODE_CUSP); + } +} + +static void sp_node_path_edit_smooth(void) +{ + NodeTool *nt = get_node_tool(); + if (nt) { + nt->_multipath->setNodeType(Inkscape::UI::NODE_SMOOTH); + } +} + +static void sp_node_path_edit_symmetrical(void) +{ + NodeTool *nt = get_node_tool(); + if (nt) { + nt->_multipath->setNodeType(Inkscape::UI::NODE_SYMMETRIC); + } +} + +static void sp_node_path_edit_auto(void) +{ + NodeTool *nt = get_node_tool(); + if (nt) { + nt->_multipath->setNodeType(Inkscape::UI::NODE_AUTO); + } +} + +static void sp_node_path_edit_nextLPEparam(GtkAction * /*act*/, gpointer data) { + sp_selection_next_patheffect_param( reinterpret_cast(data) ); +} + +/* is called when the node selection is modified */ +static void sp_node_toolbox_coord_changed(gpointer /*shape_editor*/, GObject *tbl) +{ + GtkAction* xact = GTK_ACTION( g_object_get_data( tbl, "nodes_x_action" ) ); + GtkAction* yact = GTK_ACTION( g_object_get_data( tbl, "nodes_y_action" ) ); + GtkAdjustment *xadj = ege_adjustment_action_get_adjustment(EGE_ADJUSTMENT_ACTION(xact)); + GtkAdjustment *yadj = ege_adjustment_action_get_adjustment(EGE_ADJUSTMENT_ACTION(yact)); + + // quit if run by the attr_changed listener + if (g_object_get_data( tbl, "freeze" )) { + return; + } + + // in turn, prevent listener from responding + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE)); + + UnitTracker* tracker = reinterpret_cast( g_object_get_data( tbl, "tracker" ) ); + if (!tracker) { + return; + } + Unit const *unit = tracker->getActiveUnit(); + g_return_if_fail(unit != NULL); + + NodeTool *nt = get_node_tool(); + if (!nt || !(nt->_selected_nodes) ||nt->_selected_nodes->empty()) { + // no path selected + gtk_action_set_sensitive(xact, FALSE); + gtk_action_set_sensitive(yact, FALSE); + } else { + gtk_action_set_sensitive(xact, TRUE); + gtk_action_set_sensitive(yact, TRUE); + Geom::Coord oldx = Quantity::convert(gtk_adjustment_get_value(xadj), unit, "px"); + Geom::Coord oldy = Quantity::convert(gtk_adjustment_get_value(yadj), unit, "px"); + Geom::Point mid = nt->_selected_nodes->pointwiseBounds()->midpoint(); + + if (oldx != mid[Geom::X]) { + gtk_adjustment_set_value(xadj, Quantity::convert(mid[Geom::X], "px", unit)); + } + if (oldy != mid[Geom::Y]) { + gtk_adjustment_set_value(yadj, Quantity::convert(mid[Geom::Y], "px", unit)); + } + } + + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); +} + +static void sp_node_path_value_changed(GtkAdjustment *adj, GObject *tbl, Geom::Dim2 d) +{ + SPDesktop *desktop = static_cast(g_object_get_data( tbl, "desktop" )); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + + UnitTracker* tracker = reinterpret_cast(g_object_get_data( tbl, "tracker" )); + if (!tracker) { + return; + } + Unit const *unit = tracker->getActiveUnit(); + + if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { + prefs->setDouble(Glib::ustring("/tools/nodes/") + (d == Geom::X ? "x" : "y"), + Quantity::convert(gtk_adjustment_get_value(adj), unit, "px")); + } + + // quit if run by the attr_changed listener + if (g_object_get_data( tbl, "freeze" ) || tracker->isUpdating()) { + return; + } + + // in turn, prevent listener from responding + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE)); + + NodeTool *nt = get_node_tool(); + if (nt && !nt->_selected_nodes->empty()) { + double val = Quantity::convert(gtk_adjustment_get_value(adj), unit, "px"); + double oldval = nt->_selected_nodes->pointwiseBounds()->midpoint()[d]; + Geom::Point delta(0,0); + delta[d] = val - oldval; + nt->_multipath->move(delta); + } + + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); +} + +static void sp_node_path_x_value_changed(GtkAdjustment *adj, GObject *tbl) +{ + sp_node_path_value_changed(adj, tbl, Geom::X); +} + +static void sp_node_path_y_value_changed(GtkAdjustment *adj, GObject *tbl) +{ + sp_node_path_value_changed(adj, tbl, Geom::Y); +} + +static void sp_node_toolbox_sel_changed(Inkscape::Selection *selection, GObject *tbl) +{ + { + GtkAction* w = GTK_ACTION( g_object_get_data( tbl, "nodes_lpeedit" ) ); + SPItem *item = selection->singleItem(); + if (item && SP_IS_LPE_ITEM(item)) { + if (SP_LPE_ITEM(item)->hasPathEffect()) { + gtk_action_set_sensitive(w, TRUE); + } else { + gtk_action_set_sensitive(w, FALSE); + } + } else { + gtk_action_set_sensitive(w, FALSE); + } + } +} + +static void sp_node_toolbox_sel_modified(Inkscape::Selection *selection, guint /*flags*/, GObject *tbl) +{ + sp_node_toolbox_sel_changed (selection, tbl); +} + +static void node_toolbox_watch_ec(SPDesktop* dt, Inkscape::UI::Tools::ToolBase* ec, GObject* holder); + +//################################ +//## Node Editing Toolbox ## +//################################ + +void sp_node_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) +{ + UnitTracker* tracker = new UnitTracker(Inkscape::Util::UNIT_TYPE_LINEAR); + Unit doc_units = *desktop->getNamedView()->display_units; + tracker->setActiveUnit(&doc_units); + g_object_set_data( holder, "tracker", tracker ); + + GtkIconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1); + + { + InkToolMenuAction* inky = ink_tool_menu_action_new( "NodeInsertAction", + _("Insert node"), + _("Insert new nodes into selected segments"), + INKSCAPE_ICON("node-add"), + secondarySize ); + g_object_set( INK_ACTION(inky), "short_label", _("Insert"), NULL ); + g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_add), 0 ); + gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); + GtkToolItem *menu_tool_button = gtk_menu_tool_button_new (NULL, NULL); + gtk_activatable_set_related_action (GTK_ACTIVATABLE (menu_tool_button), GTK_ACTION(inky)); + // also create dummy menu action: + gtk_action_group_add_action( mainActions, gtk_action_new("NodeInsertActionMenu", NULL, NULL, NULL) ); + } + + { + InkAction* inky = ink_action_new( "NodeInsertActionMinX", + _("Insert node at min X"), + _("Insert new nodes at min X into selected segments"), + INKSCAPE_ICON("node_insert_min_x"), + secondarySize ); + g_object_set( inky, "short_label", _("Insert min X"), NULL ); + g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_add_min_x), 0 ); + gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); + } + { + InkAction* inky = ink_action_new( "NodeInsertActionMaxX", + _("Insert node at max X"), + _("Insert new nodes at max X into selected segments"), + INKSCAPE_ICON("node_insert_max_x"), + secondarySize ); + g_object_set( inky, "short_label", _("Insert max X"), NULL ); + g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_add_max_x), 0 ); + gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); + } + { + InkAction* inky = ink_action_new( "NodeInsertActionMinY", + _("Insert node at min Y"), + _("Insert new nodes at min Y into selected segments"), + INKSCAPE_ICON("node_insert_min_y"), + secondarySize ); + g_object_set( inky, "short_label", _("Insert min Y"), NULL ); + g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_add_min_y), 0 ); + gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); + } + { + InkAction* inky = ink_action_new( "NodeInsertActionMaxY", + _("Insert node at max Y"), + _("Insert new nodes at max Y into selected segments"), + INKSCAPE_ICON("node_insert_max_y"), + secondarySize ); + g_object_set( inky, "short_label", _("Insert max Y"), NULL ); + g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_add_max_y), 0 ); + gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); + } + + { + InkAction* inky = ink_action_new( "NodeDeleteAction", + _("Delete node"), + _("Delete selected nodes"), + INKSCAPE_ICON("node-delete"), + secondarySize ); + g_object_set( inky, "short_label", _("Delete"), NULL ); + g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_delete), 0 ); + gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); + } + + { + InkAction* inky = ink_action_new( "NodeJoinAction", + _("Join nodes"), + _("Join selected nodes"), + INKSCAPE_ICON("node-join"), + secondarySize ); + g_object_set( inky, "short_label", _("Join"), NULL ); + g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_join), 0 ); + gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); + } + + { + InkAction* inky = ink_action_new( "NodeBreakAction", + _("Break nodes"), + _("Break path at selected nodes"), + INKSCAPE_ICON("node-break"), + secondarySize ); + g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_break), 0 ); + gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); + } + + + { + InkAction* inky = ink_action_new( "NodeJoinSegmentAction", + _("Join with segment"), + _("Join selected endnodes with a new segment"), + INKSCAPE_ICON("node-join-segment"), + secondarySize ); + g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_join_segment), 0 ); + gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); + } + + { + InkAction* inky = ink_action_new( "NodeDeleteSegmentAction", + _("Delete segment"), + _("Delete segment between two non-endpoint nodes"), + INKSCAPE_ICON("node-delete-segment"), + secondarySize ); + g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_delete_segment), 0 ); + gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); + } + + { + InkAction* inky = ink_action_new( "NodeCuspAction", + _("Node Cusp"), + _("Make selected nodes corner"), + INKSCAPE_ICON("node-type-cusp"), + secondarySize ); + g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_cusp), 0 ); + gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); + } + + { + InkAction* inky = ink_action_new( "NodeSmoothAction", + _("Node Smooth"), + _("Make selected nodes smooth"), + INKSCAPE_ICON("node-type-smooth"), + secondarySize ); + g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_smooth), 0 ); + gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); + } + + { + InkAction* inky = ink_action_new( "NodeSymmetricAction", + _("Node Symmetric"), + _("Make selected nodes symmetric"), + INKSCAPE_ICON("node-type-symmetric"), + secondarySize ); + g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_symmetrical), 0 ); + gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); + } + + { + InkAction* inky = ink_action_new( "NodeAutoAction", + _("Node Auto"), + _("Make selected nodes auto-smooth"), + INKSCAPE_ICON("node-type-auto-smooth"), + secondarySize ); + g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_auto), 0 ); + gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); + } + + { + InkAction* inky = ink_action_new( "NodeLineAction", + _("Node Line"), + _("Make selected segments lines"), + INKSCAPE_ICON("node-segment-line"), + secondarySize ); + g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_toline), 0 ); + gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); + } + + { + InkAction* inky = ink_action_new( "NodeCurveAction", + _("Node Curve"), + _("Make selected segments curves"), + INKSCAPE_ICON("node-segment-curve"), + secondarySize ); + g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_tocurve), 0 ); + gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); + } + + { + InkToggleAction* act = ink_toggle_action_new( "NodesShowTransformHandlesAction", + _("Show Transform Handles"), + _("Show transformation handles for selected nodes"), + "node-transform", + secondarySize ); + gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); + PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(act), "/tools/nodes/show_transform_handles"); + g_signal_connect( holder, "destroy", G_CALLBACK(delete_prefspusher), pusher); + } + + { + InkToggleAction* act = ink_toggle_action_new( "NodesShowHandlesAction", + _("Show Handles"), + _("Show Bezier handles of selected nodes"), + INKSCAPE_ICON("show-node-handles"), + secondarySize ); + gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); + PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(act), "/tools/nodes/show_handles"); + g_signal_connect( holder, "destroy", G_CALLBACK(delete_prefspusher), pusher); + } + + { + InkToggleAction* act = ink_toggle_action_new( "NodesShowHelperpath", + _("Show Outline"), + _("Show path outline (without path effects)"), + INKSCAPE_ICON("show-path-outline"), + secondarySize ); + gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); + PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(act), "/tools/nodes/show_outline"); + g_signal_connect( holder, "destroy", G_CALLBACK(delete_prefspusher), pusher); + } + + { + Inkscape::Verb* verb = Inkscape::Verb::get(SP_VERB_EDIT_NEXT_PATHEFFECT_PARAMETER); + InkAction* inky = ink_action_new( verb->get_id(), + verb->get_name(), + verb->get_tip(), + INKSCAPE_ICON("path-effect-parameter-next"), + secondarySize ); + g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_nextLPEparam), desktop ); + gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); + g_object_set_data( holder, "nodes_lpeedit", inky); + } + + { + InkToggleAction* inky = ink_toggle_action_new( "ObjectEditClipPathAction", + _("Edit clipping paths"), + _("Show clipping path(s) of selected object(s)"), + INKSCAPE_ICON("path-clip-edit"), + secondarySize ); + gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); + PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(inky), "/tools/nodes/edit_clipping_paths"); + g_signal_connect( holder, "destroy", G_CALLBACK(delete_prefspusher), pusher); + } + + { + InkToggleAction* inky = ink_toggle_action_new( "ObjectEditMaskPathAction", + _("Edit masks"), + _("Show mask(s) of selected object(s)"), + INKSCAPE_ICON("path-mask-edit"), + secondarySize ); + gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); + PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(inky), "/tools/nodes/edit_masks"); + g_signal_connect( holder, "destroy", G_CALLBACK(delete_prefspusher), pusher); + } + + /* X coord of selected node(s) */ + { + EgeAdjustmentAction* eact = 0; + gchar const* labels[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + gdouble values[] = {1, 2, 3, 5, 10, 20, 50, 100, 200, 500}; + eact = create_adjustment_action( "NodeXAction", + _("X coordinate:"), _("X:"), _("X coordinate of selected node(s)"), + "/tools/nodes/Xcoord", 0, + GTK_WIDGET(desktop->canvas), holder, TRUE, "altx-nodes", + -1e6, 1e6, SPIN_STEP, SPIN_PAGE_STEP, + labels, values, G_N_ELEMENTS(labels), + sp_node_path_x_value_changed, tracker ); + g_object_set_data( holder, "nodes_x_action", eact ); + gtk_action_set_sensitive( GTK_ACTION(eact), FALSE ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + } + + /* Y coord of selected node(s) */ + { + EgeAdjustmentAction* eact = 0; + gchar const* labels[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + gdouble values[] = {1, 2, 3, 5, 10, 20, 50, 100, 200, 500}; + eact = create_adjustment_action( "NodeYAction", + _("Y coordinate:"), _("Y:"), _("Y coordinate of selected node(s)"), + "/tools/nodes/Ycoord", 0, + GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, + -1e6, 1e6, SPIN_STEP, SPIN_PAGE_STEP, + labels, values, G_N_ELEMENTS(labels), + sp_node_path_y_value_changed, tracker ); + g_object_set_data( holder, "nodes_y_action", eact ); + gtk_action_set_sensitive( GTK_ACTION(eact), FALSE ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + } + + // add the units menu + { + InkSelectOneAction* act = tracker->createAction( "NodeUnitsAction", _("Units"), ("") ); + gtk_action_group_add_action( mainActions, act->gobj() ); + } + + sp_node_toolbox_sel_changed(desktop->getSelection(), holder); + desktop->connectEventContextChanged(sigc::bind(sigc::ptr_fun(node_toolbox_watch_ec), holder)); + +} // end of sp_node_toolbox_prep() + +static void node_toolbox_watch_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolBase* ec, GObject* holder) +{ + static sigc::connection c_selection_changed; + static sigc::connection c_selection_modified; + static sigc::connection c_subselection_changed; + + if (INK_IS_NODE_TOOL(ec)) { + // watch selection + c_selection_changed = desktop->getSelection()->connectChanged(sigc::bind(sigc::ptr_fun(sp_node_toolbox_sel_changed), holder)); + c_selection_modified = desktop->getSelection()->connectModified(sigc::bind(sigc::ptr_fun(sp_node_toolbox_sel_modified), holder)); + c_subselection_changed = desktop->connectToolSubselectionChanged(sigc::bind(sigc::ptr_fun(sp_node_toolbox_coord_changed), holder)); + + sp_node_toolbox_sel_changed(desktop->getSelection(), holder); + } else { + if (c_selection_changed) + c_selection_changed.disconnect(); + if (c_selection_modified) + c_selection_modified.disconnect(); + if (c_subselection_changed) + c_subselection_changed.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:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/toolbar/node-toolbar.h b/src/ui/toolbar/node-toolbar.h new file mode 100644 index 000000000..1f2a3f6b7 --- /dev/null +++ b/src/ui/toolbar/node-toolbar.h @@ -0,0 +1,37 @@ +#ifndef SEEN_NODE_TOOLBAR_H +#define SEEN_NODE_TOOLBAR_H + +/** + * @file + * Node aux toolbar + */ +/* Authors: + * MenTaLguY + * Lauris Kaplinski + * bulia byak + * Frank Felfe + * John Cliff + * David Turner + * Josh Andler + * Jon A. Cruz + * Maximilian Albert + * Tavmjong Bah + * Abhishek Sharma + * Kris De Gussem + * + * Copyright (C) 2004 David Turner + * Copyright (C) 2003 MenTaLguY + * Copyright (C) 1999-2011 authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +class SPDesktop; + +typedef struct _GtkActionGroup GtkActionGroup; +typedef struct _GObject GObject; + +void sp_node_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); + +#endif /* !SEEN_SELECT_TOOLBAR_H */ diff --git a/src/ui/toolbar/paintbucket-toolbar.cpp b/src/ui/toolbar/paintbucket-toolbar.cpp new file mode 100644 index 000000000..280cf0eb1 --- /dev/null +++ b/src/ui/toolbar/paintbucket-toolbar.cpp @@ -0,0 +1,260 @@ +/** + * @file + * Paint bucket aux toolbar + */ +/* Authors: + * MenTaLguY + * Lauris Kaplinski + * bulia byak + * Frank Felfe + * John Cliff + * David Turner + * Josh Andler + * Jon A. Cruz + * Maximilian Albert + * Tavmjong Bah + * Abhishek Sharma + * Kris De Gussem + * + * Copyright (C) 2004 David Turner + * Copyright (C) 2003 MenTaLguY + * Copyright (C) 1999-2011 authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include "paintbucket-toolbar.h" +#include "desktop.h" +#include "document-undo.h" + +#include "ui/icon-names.h" +#include "ui/tools/flood-tool.h" +#include "ui/uxmanager.h" +#include "ui/widget/ink-select-one-action.h" +#include "ui/widget/unit-tracker.h" + +#include "widgets/ink-action.h" +#include "widgets/ege-adjustment-action.h" +#include "widgets/toolbox.h" + +using Inkscape::UI::Widget::UnitTracker; +using Inkscape::UI::UXManager; +using Inkscape::DocumentUndo; +using Inkscape::UI::ToolboxFactory; +using Inkscape::UI::PrefPusher; +using Inkscape::Util::unit_table; + + +//######################### +//## Paintbucket ## +//######################### + +static void paintbucket_channels_changed(GObject* /*tbl*/, int channels) +{ + Inkscape::UI::Tools::FloodTool::set_channels(channels); +} + +static void paintbucket_threshold_changed(GtkAdjustment *adj, GObject * /*tbl*/) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setInt("/tools/paintbucket/threshold", (gint)gtk_adjustment_get_value(adj)); +} + +static void paintbucket_autogap_changed(GObject * /*tbl*/, int autogap) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setInt("/tools/paintbucket/autogap", autogap); +} + +static void paintbucket_offset_changed(GtkAdjustment *adj, GObject *tbl) +{ + UnitTracker* tracker = static_cast(g_object_get_data( tbl, "tracker" )); + Unit const *unit = tracker->getActiveUnit(); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + + // Don't adjust the offset value because we're saving the + // unit and it'll be correctly handled on load. + prefs->setDouble("/tools/paintbucket/offset", (gdouble)gtk_adjustment_get_value(adj)); + + g_return_if_fail(unit != NULL); + prefs->setString("/tools/paintbucket/offsetunits", unit->abbr); +} + +static void paintbucket_defaults(GtkWidget *, GObject *tbl) +{ + // FIXME: make defaults settable via Inkscape Options + struct KeyValue { + char const *key; + double value; + } const key_values[] = { + {"threshold", 15}, + {"offset", 0.0} + }; + + for (unsigned i = 0; i < G_N_ELEMENTS(key_values); ++i) { + KeyValue const &kv = key_values[i]; + GtkAdjustment* adj = static_cast(g_object_get_data(tbl, kv.key)); + if ( adj ) { + gtk_adjustment_set_value(adj, kv.value); + } + } + + InkSelectOneAction* channels_action = + static_cast( g_object_get_data( tbl, "channels_action" ) ); + channels_action->set_active( Inkscape::UI::Tools::FLOOD_CHANNELS_RGB ); + + InkSelectOneAction* autogap_action = + static_cast( g_object_get_data( tbl, "autogap_action" ) ); + autogap_action->set_active( 0 ); +} + +void sp_paintbucket_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) +{ + EgeAdjustmentAction* eact = 0; + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + + // Channel + { + InkSelectOneActionColumns columns; + + Glib::RefPtr store = Gtk::ListStore::create(columns); + + Gtk::TreeModel::Row row; + + for (auto item: Inkscape::UI::Tools::FloodTool::channel_list) { + row = *(store->append()); + row[columns.col_label ] = item; + row[columns.col_tooltip ] = (""); + row[columns.col_icon ] = "NotUsed"; + row[columns.col_sensitive] = true; + } + + InkSelectOneAction* act = + InkSelectOneAction::create( "ChannelsAction", // Name + _("Fill by"), // Label + (""), // Tooltip + "Not Used", // Icon + store ); // Tree store + + act->use_radio( false ); + act->use_icon( false ); + act->use_label( true ); + act->use_group_label( true ); + int channels = prefs->getInt("/tools/paintbucket/channels", 0); + act->set_active( channels ); + + gtk_action_group_add_action( mainActions, GTK_ACTION( act->gobj() )); + g_object_set_data( holder, "channels_action", act ); + + act->signal_changed().connect(sigc::bind<0>(sigc::ptr_fun(&paintbucket_channels_changed), holder)); + } + + // Spacing spinbox + { + eact = create_adjustment_action( + "ThresholdAction", + _("Fill Threshold"), _("Threshold:"), + _("The maximum allowed difference between the clicked pixel and the neighboring pixels to be counted in the fill"), + "/tools/paintbucket/threshold", 5, GTK_WIDGET(desktop->canvas), holder, TRUE, + "inkscape:paintbucket-threshold", 0, 100.0, 1.0, 10.0, + 0, 0, 0, + paintbucket_threshold_changed, NULL /*unit tracker*/, 1, 0 ); + + ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + } + + // Create the units menu. + UnitTracker* tracker = new UnitTracker(Inkscape::Util::UNIT_TYPE_LINEAR); + Glib::ustring stored_unit = prefs->getString("/tools/paintbucket/offsetunits"); + if (!stored_unit.empty()) { + Unit const *u = unit_table.getUnit(stored_unit); + tracker->setActiveUnit(u); + } + g_object_set_data( holder, "tracker", tracker ); + + { + InkSelectOneAction* act = tracker->createAction( "PaintbucketUnitsAction", _("Units"), ("") ); + gtk_action_group_add_action( mainActions, act->gobj() ); + } + + // Offset spinbox + { + eact = create_adjustment_action( + "OffsetAction", + _("Grow/shrink by"), _("Grow/shrink by:"), + _("The amount to grow (positive) or shrink (negative) the created fill path"), + "/tools/paintbucket/offset", 0, GTK_WIDGET(desktop->canvas), holder, TRUE, + "inkscape:paintbucket-offset", -1e4, 1e4, 0.1, 0.5, + 0, 0, 0, + paintbucket_offset_changed, tracker, 1, 2); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + } + + /* Auto Gap */ + { + InkSelectOneActionColumns columns; + + Glib::RefPtr store = Gtk::ListStore::create(columns); + + Gtk::TreeModel::Row row; + + for (auto item: Inkscape::UI::Tools::FloodTool::gap_list) { + row = *(store->append()); + row[columns.col_label ] = item; + row[columns.col_tooltip ] = (""); + row[columns.col_icon ] = "NotUsed"; + row[columns.col_sensitive] = true; + } + + InkSelectOneAction* act = + InkSelectOneAction::create( "AutoGapAction", // Name + _("Close gaps"), // Label + (""), // Tooltip + "Not Used", // Icon + store ); // Tree store + + act->use_radio( false ); + act->use_icon( false ); + act->use_label( true ); + act->use_group_label( true ); + int autogap = prefs->getInt("/tools/paintbucket/autogap"); + act->set_active( autogap ); + + gtk_action_group_add_action( mainActions, GTK_ACTION( act->gobj() )); + g_object_set_data( holder, "autogap_action", act ); + + act->signal_changed().connect(sigc::bind<0>(sigc::ptr_fun(&paintbucket_autogap_changed), holder)); + } + + /* Reset */ + { + InkAction* inky = ink_action_new( "PaintbucketResetAction", + _("Defaults"), + _("Reset paint bucket parameters to defaults (use Inkscape Preferences > Tools to change defaults)"), + INKSCAPE_ICON("edit-clear"), + GTK_ICON_SIZE_SMALL_TOOLBAR); + g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(paintbucket_defaults), holder ); + gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); + gtk_action_set_sensitive( GTK_ACTION(inky), TRUE ); + } + +} + +/* + 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:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/toolbar/paintbucket-toolbar.h b/src/ui/toolbar/paintbucket-toolbar.h new file mode 100644 index 000000000..9e6d6194a --- /dev/null +++ b/src/ui/toolbar/paintbucket-toolbar.h @@ -0,0 +1,37 @@ +#ifndef SEEN_PAINTBUCKET_TOOLBAR_H +#define SEEN_PAINTBUCKET_TOOLBAR_H + +/** + * @file + * Paintbucket aux toolbar + */ +/* Authors: + * MenTaLguY + * Lauris Kaplinski + * bulia byak + * Frank Felfe + * John Cliff + * David Turner + * Josh Andler + * Jon A. Cruz + * Maximilian Albert + * Tavmjong Bah + * Abhishek Sharma + * Kris De Gussem + * + * Copyright (C) 2004 David Turner + * Copyright (C) 2003 MenTaLguY + * Copyright (C) 1999-2011 authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +class SPDesktop; + +typedef struct _GtkActionGroup GtkActionGroup; +typedef struct _GObject GObject; + +void sp_paintbucket_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); + +#endif /* !SEEN_PAINTBUCKET_TOOLBAR_H */ diff --git a/src/ui/toolbar/pencil-toolbar.cpp b/src/ui/toolbar/pencil-toolbar.cpp new file mode 100644 index 000000000..6391af394 --- /dev/null +++ b/src/ui/toolbar/pencil-toolbar.cpp @@ -0,0 +1,639 @@ +/** + * @file + * Pencil aux toolbar + */ +/* Authors: + * MenTaLguY + * Lauris Kaplinski + * bulia byak + * Frank Felfe + * John Cliff + * David Turner + * Josh Andler + * Jon A. Cruz + * Maximilian Albert + * Tavmjong Bah + * Abhishek Sharma + * Kris De Gussem + * + * Copyright (C) 2004 David Turner + * Copyright (C) 2003 MenTaLguY + * Copyright (C) 1999-2011 authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +#include "pencil-toolbar.h" + +#include "desktop.h" +#include "selection.h" + +#include "widgets/ink-action.h" +#include "widgets/ink-toggle-action.h" +#include "widgets/toolbox.h" + +#include "live_effects/lpe-bspline.h" +#include "live_effects/lpe-powerstroke.h" +#include "live_effects/lpe-simplify.h" +#include "live_effects/lpe-spiro.h" +#include "live_effects/lpeobject-reference.h" +#include "live_effects/lpeobject.h" + +#include "display/curve.h" + +#include "object/sp-shape.h" + +#include "ui/icon-names.h" +#include "ui/tools-switch.h" +#include "ui/tools/pen-tool.h" +#include "ui/uxmanager.h" +#include "ui/widget/ink-select-one-action.h" + +#include "widgets/ege-adjustment-action.h" +#include "widgets/spinbutton-events.h" + + +using Inkscape::UI::UXManager; +using Inkscape::UI::ToolboxFactory; +using Inkscape::UI::PrefPusher; + +//######################## +//## Pen/Pencil ## +//######################## +static void sp_flatten_spiro_bspline(GtkWidget * /*widget*/, GObject *obj); +/* This is used in generic functions below to share large portions of code between pen and pencil tool */ +static Glib::ustring const freehand_tool_name(GObject *dataKludge) +{ + SPDesktop *desktop = static_cast(g_object_get_data(dataKludge, "desktop")); + return ( tools_isactive(desktop, TOOLS_FREEHAND_PEN) + ? "/tools/freehand/pen" + : "/tools/freehand/pencil" ); +} + +static void freehand_mode_changed(GObject* tbl, int mode) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setInt(freehand_tool_name(tbl) + "/freehand-mode", mode); + + if (mode == 1 || mode == 2) { + gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "flatten_spiro_bspline") ), true ); + } else { + gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "flatten_spiro_bspline") ), false ); + } + if (mode == 2) { + gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "flatten_simplify") ), false ); + gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "simplify") ), false ); + } else { + gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "flatten_simplify") ), true ); + gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "simplify") ), true ); + } +} + +static void use_pencil_pressure(InkToggleAction* itact, GObject *dataKludge) { + bool pressure = gtk_toggle_action_get_active( GTK_TOGGLE_ACTION(itact) ); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setBool(freehand_tool_name(dataKludge) + "/pressure", pressure); + if (pressure) { + gtk_action_set_visible( GTK_ACTION( g_object_get_data(dataKludge, "minpressure") ), true ); + gtk_action_set_visible( GTK_ACTION( g_object_get_data(dataKludge, "maxpressure") ), true ); + InkSelectOneAction* act = + static_cast( g_object_get_data( dataKludge, "shape_action" ) ); + act->set_visible (false); + } else { + gtk_action_set_visible( GTK_ACTION( g_object_get_data(dataKludge, "minpressure") ), false ); + gtk_action_set_visible( GTK_ACTION( g_object_get_data(dataKludge, "maxpressure") ), false ); + InkSelectOneAction* act = + static_cast( g_object_get_data( dataKludge, "shape_action" ) ); + act->set_visible (true); + } +} + +static void sp_add_freehand_mode_toggle(GtkActionGroup* mainActions, GObject* holder, bool tool_is_pencil) +{ + /* Freehand mode toggle buttons */ + + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + guint freehandMode = prefs->getInt(( tool_is_pencil ? + "/tools/freehand/pencil/freehand-mode" : + "/tools/freehand/pen/freehand-mode" ), 0); + GtkIconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1); + + InkSelectOneActionColumns columns; + + Glib::RefPtr store = Gtk::ListStore::create(columns); + + Gtk::TreeModel::Row row; + + row = *(store->append()); + row[columns.col_label ] = _("Bezier"); + row[columns.col_tooltip ] = _("Create regular Bezier path"); + row[columns.col_icon ] = INKSCAPE_ICON("path-mode-bezier"); + row[columns.col_sensitive] = true; + + row = *(store->append()); + row[columns.col_label ] = _("Spiro"); + row[columns.col_tooltip ] = _("Create Spiro path"); + row[columns.col_icon ] = INKSCAPE_ICON("path-mode-spiro"); + row[columns.col_sensitive] = true; + + row = *(store->append()); + row[columns.col_label ] = _("BSpline"); + row[columns.col_tooltip ] = _("Create BSpline path"); + row[columns.col_icon ] = INKSCAPE_ICON("path-mode-bspline"); + row[columns.col_sensitive] = true; + + if (!tool_is_pencil) { + row = *(store->append()); + row[columns.col_label ] = _("Zigzag"); + row[columns.col_tooltip ] = _("Create a sequence of straight line segments"); + row[columns.col_icon ] = INKSCAPE_ICON("path-mode-polyline"); + row[columns.col_sensitive] = true; + + row = *(store->append()); + row[columns.col_label ] = _("Paraxial"); + row[columns.col_tooltip ] = _("Create a sequence of paraxial line segments"); + row[columns.col_icon ] = INKSCAPE_ICON("path-mode-polyline-paraxial"); + row[columns.col_sensitive] = true; + } + + InkSelectOneAction* act = + InkSelectOneAction::create( tool_is_pencil ? + "FreehandModeActionPencil" : + "FreehandModeActionPen", + _("Mode"), // Label + _("Mode of new lines drawn by this tool"), // Tooltip + "Not Used", // Icon + store ); // Tree store + act->use_radio( true ); + act->use_label( true ); + act->set_active( freehandMode ); + + gtk_action_group_add_action( mainActions, GTK_ACTION( act->gobj() )); + // g_object_set_data( dataKludge, "flat_action", act ); + + act->signal_changed().connect(sigc::bind<0>(sigc::ptr_fun(&freehand_mode_changed), holder)); + + /* LPE bspline spiro flatten */ + InkAction* inky = ink_action_new( tool_is_pencil ? "FlattenSpiroBsplinePencil" : + "FlattenSpiroBsplinePen", + _("LPE spiro or bspline flatten"), + _("LPE spiro or bspline flatten"), + INKSCAPE_ICON("flatten"), + GTK_ICON_SIZE_SMALL_TOOLBAR ); + g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_flatten_spiro_bspline), holder ); + gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); + g_object_set_data( holder, "flatten_spiro_bspline", inky ); + if (freehandMode == 1 || freehandMode == 2) { + gtk_action_set_visible( GTK_ACTION( g_object_get_data(holder, "flatten_spiro_bspline") ), true ); + } else { + gtk_action_set_visible( GTK_ACTION( g_object_get_data(holder, "flatten_spiro_bspline") ), false ); + } +} + +static void freehand_change_shape(GObject *dataKludge, int shape) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setInt(freehand_tool_name(dataKludge) + "/shape", shape); +} + +static void freehand_simplify_lpe(InkToggleAction* itact, GObject *dataKludge) { + bool simplify = gtk_toggle_action_get_active( GTK_TOGGLE_ACTION(itact) ); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setBool(freehand_tool_name(dataKludge) + "/simplify", simplify); + gtk_action_set_visible( GTK_ACTION( g_object_get_data(dataKludge, "flatten_simplify") ), simplify ); + if (simplify) { + gtk_action_set_visible( GTK_ACTION( g_object_get_data(dataKludge, "flatten_simplify") ), true ); + } else { + gtk_action_set_visible( GTK_ACTION( g_object_get_data(dataKludge, "flatten_simplify") ), false ); + } +} + +static void freehand_add_advanced_shape_options(GtkActionGroup* mainActions, GObject* holder, bool tool_is_pencil) +{ + /*advanced shape options */ + + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + + std::vector freehand_shape_dropdown_items_list = { + const_cast(C_("Freehand shape", "None")), + _("Triangle in"), + _("Triangle out"), + _("Ellipse"), + _("From clipboard"), + _("Bend from clipboard"), + _("Last applied") + }; + + InkSelectOneActionColumns columns; + + Glib::RefPtr store = Gtk::ListStore::create(columns); + + Gtk::TreeModel::Row row; + + for (auto item:freehand_shape_dropdown_items_list) { + + row = *(store->append()); + row[columns.col_label ] = item; + row[columns.col_tooltip ] = (""); + row[columns.col_icon ] = "NotUsed"; + row[columns.col_sensitive] = true; + } + + InkSelectOneAction* act = + InkSelectOneAction::create( tool_is_pencil ? + "SetPencilShapeAction" : + "SetPenShapeAction", // Name + _("Shape"), // Label + _("Shape of new paths drawn by this tool"), // Tooltip + "Not Used", // Icon + store ); // Tree store + + act->use_radio( false ); + act->use_icon( false ); + act->use_label( true ); + act->use_group_label( true ); + int shape = prefs->getInt( (tool_is_pencil ? + "/tools/freehand/pencil/shape" : + "/tools/freehand/pen/shape" ), 0); + act->set_active( shape ); + + gtk_action_group_add_action( mainActions, GTK_ACTION( act->gobj() )); + g_object_set_data( holder, "shape_action", act ); + + bool hide = prefs->getInt("/tools/freehand/pencil/freehand-mode", 0) == 3 || + (tool_is_pencil && prefs->getBool("/tools/freehand/pencil/pressure", false)); + act->set_visible( !hide ); + + act->signal_changed().connect(sigc::bind<0>(sigc::ptr_fun(&freehand_change_shape), holder)); +} + +void sp_pen_toolbox_prep(SPDesktop * /*desktop*/, GtkActionGroup* mainActions, GObject* holder) +{ + sp_add_freehand_mode_toggle(mainActions, holder, false); + freehand_add_advanced_shape_options(mainActions, holder, false); +} + + +static void sp_pencil_tb_defaults(GtkWidget * /*widget*/, GObject *obj) +{ + GtkWidget *tbl = GTK_WIDGET(obj); + + GtkAdjustment *adj; + + // fixme: make settable + gdouble tolerance = 4; + + adj = GTK_ADJUSTMENT(g_object_get_data(obj, "tolerance")); + gtk_adjustment_set_value(adj, tolerance); + +#if !GTK_CHECK_VERSION(3,18,0) + gtk_adjustment_value_changed(adj); +#endif + + spinbutton_defocus(tbl); +} + +static void sp_flatten_spiro_bspline(GtkWidget * /*widget*/, GObject *obj) +{ + SPDesktop *desktop = static_cast(g_object_get_data(obj, "desktop")); + auto selected = desktop->getSelection()->items(); + SPLPEItem* lpeitem = NULL; + for (auto it(selected.begin()); it != selected.end(); ++it){ + lpeitem = dynamic_cast(*it); + if (lpeitem && lpeitem->hasPathEffect()){ + PathEffectList lpelist = lpeitem->getEffectList(); + PathEffectList::iterator i; + for (i = lpelist.begin(); i != lpelist.end(); ++i) { + LivePathEffectObject *lpeobj = (*i)->lpeobject; + if (lpeobj) { + Inkscape::LivePathEffect::Effect *lpe = lpeobj->get_lpe(); + if (dynamic_cast(lpe) || + dynamic_cast(lpe)) + { + SPShape * shape = dynamic_cast(lpeitem); + if(shape){ + SPCurve * c = shape->getCurveForEdit(); + lpe->doEffect(c); + lpeitem->setCurrentPathEffect(*i); + if (lpelist.size() > 1){ + lpeitem->removeCurrentPathEffect(true); + shape->setCurveBeforeLPE(c); + } else { + lpeitem->removeCurrentPathEffect(false); + shape->setCurve(c, false); + } + break; + } + } + } + } + } + } + if (lpeitem) { + desktop->getSelection()->remove(lpeitem->getRepr()); + desktop->getSelection()->add(lpeitem->getRepr()); + sp_lpe_item_update_patheffect(lpeitem, false, false); + } +} + +static void sp_simplify_flatten(GtkWidget * /*widget*/, GObject *obj) +{ + SPDesktop *desktop = static_cast(g_object_get_data(obj, "desktop")); + auto selected = desktop->getSelection()->items(); + SPLPEItem* lpeitem = NULL; + for (auto it(selected.begin()); it != selected.end(); ++it){ + lpeitem = dynamic_cast(*it); + if (lpeitem && lpeitem->hasPathEffect()){ + PathEffectList lpelist = lpeitem->getEffectList(); + PathEffectList::iterator i; + for (i = lpelist.begin(); i != lpelist.end(); ++i) { + LivePathEffectObject *lpeobj = (*i)->lpeobject; + if (lpeobj) { + Inkscape::LivePathEffect::Effect *lpe = lpeobj->get_lpe(); + if (dynamic_cast(lpe)) { + SPShape * shape = dynamic_cast(lpeitem); + if(shape){ + SPCurve * c = shape->getCurveForEdit(); + lpe->doEffect(c); + lpeitem->setCurrentPathEffect(*i); + if (lpelist.size() > 1){ + lpeitem->removeCurrentPathEffect(true); + shape->setCurveBeforeLPE(c); + } else { + lpeitem->removeCurrentPathEffect(false); + shape->setCurve(c, false); + } + break; + } + } + } + } + } + } + if (lpeitem) { + desktop->getSelection()->remove(lpeitem->getRepr()); + desktop->getSelection()->add(lpeitem->getRepr()); + sp_lpe_item_update_patheffect(lpeitem, false, false); + } +} + +static void sp_minpressure_value_changed(GtkAdjustment *adj, GObject *tbl) +{ + // quit if run by the attr_changed listener + if (g_object_get_data( tbl, "freeze" )) { + return; + } + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble( "/tools/freehand/pencil/minpressure", gtk_adjustment_get_value(adj)); +} + +static void sp_maxpressure_value_changed(GtkAdjustment *adj, GObject *tbl) +{ + // quit if run by the attr_changed listener + if (g_object_get_data( tbl, "freeze" )) { + return; + } + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble( "/tools/freehand/pencil/maxpressure", gtk_adjustment_get_value(adj)); +} + +static void sp_pencil_tb_tolerance_value_changed(GtkAdjustment *adj, GObject *tbl) +{ + // quit if run by the attr_changed listener + if (g_object_get_data( tbl, "freeze" )) { + return; + } + // in turn, prevent listener from responding + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); + prefs->setDouble("/tools/freehand/pencil/tolerance", + gtk_adjustment_get_value(adj)); + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); + SPDesktop *desktop = static_cast(g_object_get_data(tbl, "desktop")); + auto selected = desktop->getSelection()->items(); + for (auto it(selected.begin()); it != selected.end(); ++it){ + SPLPEItem* lpeitem = dynamic_cast(*it); + if (lpeitem && lpeitem->hasPathEffect()){ + Inkscape::LivePathEffect::Effect* simplify = lpeitem->getPathEffectOfType(Inkscape::LivePathEffect::SIMPLIFY); + if(simplify){ + Inkscape::LivePathEffect::LPESimplify *lpe_simplify = dynamic_cast(simplify->getLPEObj()->get_lpe()); + if (lpe_simplify) { + double tol = prefs->getDoubleLimited("/tools/freehand/pencil/tolerance", 10.0, 1.0, 100.0); + tol = tol/(100.0*(102.0-tol)); + std::ostringstream ss; + ss << tol; + Inkscape::LivePathEffect::Effect* powerstroke = lpeitem->getPathEffectOfType(Inkscape::LivePathEffect::POWERSTROKE); + bool simplified = false; + if(powerstroke){ + Inkscape::LivePathEffect::LPEPowerStroke *lpe_powerstroke = dynamic_cast(powerstroke->getLPEObj()->get_lpe()); + if(lpe_powerstroke){ + lpe_powerstroke->getRepr()->setAttribute("is_visible", "false"); + sp_lpe_item_update_patheffect(lpeitem, false, false); + SPShape *sp_shape = dynamic_cast(lpeitem); + if (sp_shape) { + guint previous_curve_length = sp_shape->getCurve()->get_segment_count(); + lpe_simplify->getRepr()->setAttribute("threshold", ss.str()); + sp_lpe_item_update_patheffect(lpeitem, false, false); + simplified = true; + guint curve_length = sp_shape->getCurve()->get_segment_count(); + std::vector ts = lpe_powerstroke->offset_points.data(); + double factor = (double)curve_length/ (double)previous_curve_length; + for (size_t i = 0; i < ts.size(); i++) { + ts[i][Geom::X] = ts[i][Geom::X] * factor; + } + lpe_powerstroke->offset_points.param_setValue(ts); + } + lpe_powerstroke->getRepr()->setAttribute("is_visible", "true"); + sp_lpe_item_update_patheffect(lpeitem, false, false); + } + } + if(!simplified){ + lpe_simplify->getRepr()->setAttribute("threshold", ss.str()); + } + } + } + } + } +} + +/* +class PencilToleranceObserver : public Inkscape::Preferences::Observer { +public: + PencilToleranceObserver(Glib::ustring const &path, GObject *x) : Observer(path), _obj(x) + { + g_object_set_data(_obj, "prefobserver", this); + } + virtual ~PencilToleranceObserver() { + if (g_object_get_data(_obj, "prefobserver") == this) { + g_object_set_data(_obj, "prefobserver", NULL); + } + } + virtual void notify(Inkscape::Preferences::Entry const &val) { + GObject* tbl = _obj; + if (g_object_get_data( tbl, "freeze" )) { + return; + } + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); + + GtkAdjustment * adj = GTK_ADJUSTMENT(g_object_get_data(tbl, "tolerance")); + + double v = val.getDouble(adj->value); + gtk_adjustment_set_value(adj, v); + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); + } +private: + GObject *_obj; +}; +*/ + +void sp_pencil_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) +{ + sp_add_freehand_mode_toggle(mainActions, holder, true); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + EgeAdjustmentAction* eact = 0; + + + /* min pressure */ + { + eact = create_adjustment_action( "MinPressureAction", + _("Min pressure"), _("Min:"), _("Min percent of pressure"), + "/tools/freehand/pencil/minpressure", 0, + GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, + 0, 100, 1, 0, + 0, 0, 0, + sp_minpressure_value_changed, NULL, 0 ,0); + + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + g_object_set_data( holder, "minpressure", eact ); + if (prefs->getInt("/tools/freehand/pencil/freehand-mode", 0) == 3) { + gtk_action_set_visible( GTK_ACTION(eact), true ); + } else { + gtk_action_set_visible( GTK_ACTION(eact), false ); + } + } + /* max pressure */ + { + eact = create_adjustment_action( "MaxPressureAction", + _("Max pressure"), _("Max:"), _("Max percent of pressure"), + "/tools/freehand/pencil/maxpressure", 100, + GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, + 0, 100, 1, 0, + 0, 0, 0, + sp_maxpressure_value_changed, NULL, 0 ,0); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + g_object_set_data( holder, "maxpressure", eact ); + if (prefs->getInt("/tools/freehand/pencil/freehand-mode", 0) == 3) { + gtk_action_set_visible( GTK_ACTION(eact), true ); + } else { + gtk_action_set_visible( GTK_ACTION(eact), false ); + } + } + /* Use pressure */ + { + InkToggleAction* itact = ink_toggle_action_new( "PencilPressureAction", + _("Use pressure input"), + _("Use pressure input"), + INKSCAPE_ICON("draw-use-pressure"), + GTK_ICON_SIZE_SMALL_TOOLBAR ); + bool pressure = prefs->getBool(freehand_tool_name(holder) + "/pressure", false); + gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(itact), pressure ); + g_signal_connect_after( G_OBJECT(itact), "toggled", G_CALLBACK(use_pencil_pressure), holder) ; + gtk_action_group_add_action( mainActions, GTK_ACTION(itact) ); + if (pressure) { + gtk_action_set_visible( GTK_ACTION( g_object_get_data(holder, "minpressure") ), true ); + gtk_action_set_visible( GTK_ACTION( g_object_get_data(holder, "maxpressure") ), true ); + } else { + gtk_action_set_visible( GTK_ACTION( g_object_get_data(holder, "minpressure") ), false ); + gtk_action_set_visible( GTK_ACTION( g_object_get_data(holder, "maxpressure") ), false ); + } + } + /* Tolerance */ + { + gchar const* labels[] = {_("(many nodes, rough)"), _("(default)"), 0, 0, 0, 0, _("(few nodes, smooth)")}; + gdouble values[] = {1, 10, 20, 30, 50, 75, 100}; + eact = create_adjustment_action( "PencilToleranceAction", + _("Smoothing:"), _("Smoothing: "), + _("How much smoothing (simplifying) is applied to the line"), + "/tools/freehand/pencil/tolerance", + 3.0, + GTK_WIDGET(desktop->canvas), + holder, TRUE, "altx-pencil", + 1, 100.0, 0.5, 1.0, + labels, values, G_N_ELEMENTS(labels), + sp_pencil_tb_tolerance_value_changed, + NULL /*unit tracker*/, + 1, 2); + ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + } + + /* advanced shape options */ + freehand_add_advanced_shape_options(mainActions, holder, true); + + /* Reset */ + { + InkAction* inky = ink_action_new( "PencilResetAction", + _("Defaults"), + _("Reset pencil parameters to defaults (use Inkscape Preferences > Tools to change defaults)"), + INKSCAPE_ICON("edit-clear"), + GTK_ICON_SIZE_SMALL_TOOLBAR ); + g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_pencil_tb_defaults), holder ); + gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); + } + /* LPE simplify based tolerance */ + { + InkToggleAction* itact = ink_toggle_action_new( "PencilLpeSimplify", + _("LPE based interactive simplify"), + _("LPE based interactive simplify"), + INKSCAPE_ICON("interactive_simplify"), + GTK_ICON_SIZE_SMALL_TOOLBAR ); + gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(itact), prefs->getInt("/tools/freehand/pencil/simplify", 0) ); + g_object_set_data( holder, "simplify", itact ); + g_signal_connect_after( G_OBJECT(itact), "toggled", G_CALLBACK(freehand_simplify_lpe), holder) ; + gtk_action_group_add_action( mainActions, GTK_ACTION(itact) ); + guint freehandMode = prefs->getInt("/tools/freehand/pencil/freehand-mode", 0); + if (freehandMode == 2) { + gtk_action_set_visible( GTK_ACTION( g_object_get_data(holder, "simplify") ), false ); + } else { + gtk_action_set_visible( GTK_ACTION( g_object_get_data(holder, "simplify") ), true ); + } + } + /* LPE simplify flatten */ + { + InkAction* inky = ink_action_new( "PencilLpeSimplifyFlatten", + _("LPE simplify flatten"), + _("LPE simplify flatten"), + INKSCAPE_ICON("flatten"), + GTK_ICON_SIZE_SMALL_TOOLBAR ); + g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_simplify_flatten), holder ); + gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); + g_object_set_data( holder, "flatten_simplify", inky ); + guint freehandMode = prefs->getInt("/tools/freehand/pencil/freehand-mode", 0); + if (freehandMode == 2 || !prefs->getInt("/tools/freehand/pencil/simplify", 0)) { + gtk_action_set_visible( GTK_ACTION( g_object_get_data(holder, "flatten_simplify") ), false ); + } else { + gtk_action_set_visible( GTK_ACTION( g_object_get_data(holder, "flatten_simplify") ), true ); + } + } + + g_signal_connect( holder, "destroy", G_CALLBACK(purge_repr_listener), holder ); + +} + +/* + 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:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/toolbar/pencil-toolbar.h b/src/ui/toolbar/pencil-toolbar.h new file mode 100644 index 000000000..c01b7d591 --- /dev/null +++ b/src/ui/toolbar/pencil-toolbar.h @@ -0,0 +1,38 @@ +#ifndef SEEN_PENCIL_TOOLBAR_H +#define SEEN_PENCIL_TOOLBAR_H + +/** + * @file + * Pencil aux toolbar + */ +/* Authors: + * MenTaLguY + * Lauris Kaplinski + * bulia byak + * Frank Felfe + * John Cliff + * David Turner + * Josh Andler + * Jon A. Cruz + * Maximilian Albert + * Tavmjong Bah + * Abhishek Sharma + * Kris De Gussem + * + * Copyright (C) 2004 David Turner + * Copyright (C) 2003 MenTaLguY + * Copyright (C) 1999-2011 authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +class SPDesktop; + +typedef struct _GtkActionGroup GtkActionGroup; +typedef struct _GObject GObject; + +void sp_pencil_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); +void sp_pen_toolbox_prep(SPDesktop * /*desktop*/, GtkActionGroup* mainActions, GObject* holder); + +#endif /* !SEEN_PENCIL_TOOLBAR_H */ diff --git a/src/ui/toolbar/rect-toolbar.cpp b/src/ui/toolbar/rect-toolbar.cpp new file mode 100644 index 000000000..420c3410e --- /dev/null +++ b/src/ui/toolbar/rect-toolbar.cpp @@ -0,0 +1,436 @@ +/** + * @file + * Rect aux toolbar + */ +/* Authors: + * MenTaLguY + * Lauris Kaplinski + * bulia byak + * Frank Felfe + * John Cliff + * David Turner + * Josh Andler + * Jon A. Cruz + * Maximilian Albert + * Tavmjong Bah + * Abhishek Sharma + * Kris De Gussem + * + * Copyright (C) 2004 David Turner + * Copyright (C) 2003 MenTaLguY + * Copyright (C) 1999-2011 authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +#include "rect-toolbar.h" + +#include "desktop.h" +#include "document-undo.h" +#include "inkscape.h" +#include "widgets/toolbox.h" +#include "verbs.h" + +#include "object/sp-namedview.h" +#include "object/sp-rect.h" + +#include "ui/icon-names.h" +#include "ui/tools/rect-tool.h" +#include "ui/uxmanager.h" +#include "ui/widget/ink-select-one-action.h" +#include "ui/widget/unit-tracker.h" + +#include "widgets/ege-adjustment-action.h" +#include "widgets/ege-output-action.h" +#include "widgets/ink-action.h" +#include "widgets/widget-sizes.h" + +#include "xml/node-event-vector.h" + +using Inkscape::UI::Widget::UnitTracker; +using Inkscape::UI::UXManager; +using Inkscape::DocumentUndo; +using Inkscape::UI::ToolboxFactory; +using Inkscape::UI::PrefPusher; +using Inkscape::Util::Unit; +using Inkscape::Util::Quantity; +using Inkscape::Util::unit_table; + + +//######################## +//## Rect ## +//######################## + +static void sp_rtb_sensitivize( GObject *tbl ) +{ + GtkAdjustment *adj1 = GTK_ADJUSTMENT( g_object_get_data(tbl, "rx") ); + GtkAdjustment *adj2 = GTK_ADJUSTMENT( g_object_get_data(tbl, "ry") ); + GtkAction* not_rounded = GTK_ACTION( g_object_get_data(tbl, "not_rounded") ); + + if (gtk_adjustment_get_value(adj1) == 0 && gtk_adjustment_get_value(adj2) == 0 && g_object_get_data(tbl, "single")) { // only for a single selected rect (for now) + gtk_action_set_sensitive( not_rounded, FALSE ); + } else { + gtk_action_set_sensitive( not_rounded, TRUE ); + } +} + + +static void sp_rtb_value_changed(GtkAdjustment *adj, GObject *tbl, gchar const *value_name, + void (SPRect::*setter)(gdouble)) +{ + SPDesktop *desktop = static_cast(g_object_get_data( tbl, "desktop" )); + + UnitTracker* tracker = reinterpret_cast(g_object_get_data( tbl, "tracker" )); + Unit const *unit = tracker->getActiveUnit(); + g_return_if_fail(unit != NULL); + + if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble(Glib::ustring("/tools/shapes/rect/") + value_name, + Quantity::convert(gtk_adjustment_get_value(adj), unit, "px")); + } + + // quit if run by the attr_changed listener + if (g_object_get_data( tbl, "freeze" ) || tracker->isUpdating()) { + return; + } + + // in turn, prevent listener from responding + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE)); + + bool modmade = false; + Inkscape::Selection *selection = desktop->getSelection(); + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ + if (SP_IS_RECT(*i)) { + if (gtk_adjustment_get_value(adj) != 0) { + (SP_RECT(*i)->*setter)(Quantity::convert(gtk_adjustment_get_value(adj), unit, "px")); + } else { + (*i)->getRepr()->setAttribute(value_name, NULL); + } + modmade = true; + } + } + + sp_rtb_sensitivize( tbl ); + + if (modmade) { + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_RECT, + _("Change rectangle")); + } + + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); +} + +static void sp_rtb_rx_value_changed(GtkAdjustment *adj, GObject *tbl) +{ + sp_rtb_value_changed(adj, tbl, "rx", &SPRect::setVisibleRx); +} + +static void sp_rtb_ry_value_changed(GtkAdjustment *adj, GObject *tbl) +{ + sp_rtb_value_changed(adj, tbl, "ry", &SPRect::setVisibleRy); +} + +static void sp_rtb_width_value_changed(GtkAdjustment *adj, GObject *tbl) +{ + sp_rtb_value_changed(adj, tbl, "width", &SPRect::setVisibleWidth); +} + +static void sp_rtb_height_value_changed(GtkAdjustment *adj, GObject *tbl) +{ + sp_rtb_value_changed(adj, tbl, "height", &SPRect::setVisibleHeight); +} + + + +static void sp_rtb_defaults( GtkWidget * /*widget*/, GObject *obj) +{ + GtkAdjustment *adj = 0; + + adj = GTK_ADJUSTMENT( g_object_get_data(obj, "rx") ); + gtk_adjustment_set_value(adj, 0.0); + +#if !GTK_CHECK_VERSION(3,18,0) + // this is necessary if the previous value was 0, but we still need to run the callback to change all selected objects + gtk_adjustment_value_changed(adj); +#endif + + adj = GTK_ADJUSTMENT( g_object_get_data(obj, "ry") ); + gtk_adjustment_set_value(adj, 0.0); + +#if !GTK_CHECK_VERSION(3,18,0) + gtk_adjustment_value_changed(adj); +#endif + + sp_rtb_sensitivize( obj ); +} + +static void rect_tb_event_attr_changed(Inkscape::XML::Node * /*repr*/, gchar const * /*name*/, + gchar const * /*old_value*/, gchar const * /*new_value*/, + bool /*is_interactive*/, gpointer data) +{ + GObject *tbl = G_OBJECT(data); + + // quit if run by the _changed callbacks + if (g_object_get_data( tbl, "freeze" )) { + return; + } + + // in turn, prevent callbacks from responding + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); + + UnitTracker* tracker = reinterpret_cast( g_object_get_data( tbl, "tracker" ) ); + Unit const *unit = tracker->getActiveUnit(); + g_return_if_fail(unit != NULL); + + gpointer item = g_object_get_data( tbl, "item" ); + if (item && SP_IS_RECT(item)) { + { + GtkAdjustment *adj = GTK_ADJUSTMENT( g_object_get_data( tbl, "rx" ) ); + + gdouble rx = SP_RECT(item)->getVisibleRx(); + gtk_adjustment_set_value(adj, Quantity::convert(rx, "px", unit)); + } + + { + GtkAdjustment *adj = GTK_ADJUSTMENT( g_object_get_data( tbl, "ry" ) ); + + gdouble ry = SP_RECT(item)->getVisibleRy(); + gtk_adjustment_set_value(adj, Quantity::convert(ry, "px", unit)); + } + + { + GtkAdjustment *adj = GTK_ADJUSTMENT( g_object_get_data( tbl, "width" ) ); + + gdouble width = SP_RECT(item)->getVisibleWidth(); + gtk_adjustment_set_value(adj, Quantity::convert(width, "px", unit)); + } + + { + GtkAdjustment *adj = GTK_ADJUSTMENT( g_object_get_data( tbl, "height" ) ); + + gdouble height = SP_RECT(item)->getVisibleHeight(); + gtk_adjustment_set_value(adj, Quantity::convert(height, "px", unit)); + } + } + + sp_rtb_sensitivize( tbl ); + + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); +} + + +static Inkscape::XML::NodeEventVector rect_tb_repr_events = { + NULL, /* child_added */ + NULL, /* child_removed */ + rect_tb_event_attr_changed, + NULL, /* content_changed */ + NULL /* order_changed */ +}; + +/** + * \param selection should not be NULL. + */ +static void sp_rect_toolbox_selection_changed(Inkscape::Selection *selection, GObject *tbl) +{ + int n_selected = 0; + Inkscape::XML::Node *repr = NULL; + SPItem *item = NULL; + + if ( g_object_get_data( tbl, "repr" ) ) { + g_object_set_data( tbl, "item", NULL ); + } + purge_repr_listener( tbl, tbl ); + + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ + if (SP_IS_RECT(*i)) { + n_selected++; + item = *i; + repr = item->getRepr(); + } + } + + EgeOutputAction* act = EGE_OUTPUT_ACTION( g_object_get_data( tbl, "mode_action" ) ); + + g_object_set_data( tbl, "single", GINT_TO_POINTER(FALSE) ); + + if (n_selected == 0) { + g_object_set( G_OBJECT(act), "label", _("New:"), NULL ); + + GtkAction* w = GTK_ACTION( g_object_get_data( tbl, "width_action" ) ); + gtk_action_set_sensitive(w, FALSE); + GtkAction* h = GTK_ACTION( g_object_get_data( tbl, "height_action" ) ); + gtk_action_set_sensitive(h, FALSE); + + } else if (n_selected == 1) { + g_object_set( G_OBJECT(act), "label", _("Change:"), NULL ); + g_object_set_data( tbl, "single", GINT_TO_POINTER(TRUE) ); + + GtkAction* w = GTK_ACTION( g_object_get_data( tbl, "width_action" ) ); + gtk_action_set_sensitive(w, TRUE); + GtkAction* h = GTK_ACTION( g_object_get_data( tbl, "height_action" ) ); + gtk_action_set_sensitive(h, TRUE); + + if (repr) { + g_object_set_data( tbl, "repr", repr ); + g_object_set_data( tbl, "item", item ); + Inkscape::GC::anchor(repr); + sp_repr_add_listener(repr, &rect_tb_repr_events, tbl); + sp_repr_synthesize_events(repr, &rect_tb_repr_events, tbl); + } + } else { + // FIXME: implement averaging of all parameters for multiple selected + //gtk_label_set_markup(GTK_LABEL(l), _("Average:")); + g_object_set( G_OBJECT(act), "label", _("Change:"), NULL ); + sp_rtb_sensitivize( tbl ); + } +} + +static void rect_toolbox_watch_ec(SPDesktop* dt, Inkscape::UI::Tools::ToolBase* ec, GObject* holder); + +void sp_rect_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) +{ + EgeAdjustmentAction* eact = 0; + GtkIconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1); + + { + EgeOutputAction* act = ege_output_action_new( "RectStateAction", _("New:"), "", 0 ); + ege_output_action_set_use_markup( act, TRUE ); + gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); + g_object_set_data( holder, "mode_action", act ); + } + + // rx/ry units menu: create + UnitTracker* tracker = new UnitTracker(Inkscape::Util::UNIT_TYPE_LINEAR); + //tracker->addUnit( SP_UNIT_PERCENT, 0 ); + // fixme: add % meaning per cent of the width/height + tracker->setActiveUnit(unit_table.getUnit("px")); + g_object_set_data( holder, "tracker", tracker ); + + /* W */ + { + gchar const* labels[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + gdouble values[] = {1, 2, 3, 5, 10, 20, 50, 100, 200, 500}; + eact = create_adjustment_action( "RectWidthAction", + _("Width"), _("W:"), _("Width of rectangle"), + "/tools/shapes/rect/width", 0, + GTK_WIDGET(desktop->canvas), holder, TRUE, "altx-rect", + 0, 1e6, SPIN_STEP, SPIN_PAGE_STEP, + labels, values, G_N_ELEMENTS(labels), + sp_rtb_width_value_changed, tracker); + g_object_set_data( holder, "width_action", eact ); + gtk_action_set_sensitive( GTK_ACTION(eact), FALSE ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + } + + /* H */ + { + gchar const* labels[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + gdouble values[] = {1, 2, 3, 5, 10, 20, 50, 100, 200, 500}; + eact = create_adjustment_action( "RectHeightAction", + _("Height"), _("H:"), _("Height of rectangle"), + "/tools/shapes/rect/height", 0, + GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, + 0, 1e6, SPIN_STEP, SPIN_PAGE_STEP, + labels, values, G_N_ELEMENTS(labels), + sp_rtb_height_value_changed, tracker); + g_object_set_data( holder, "height_action", eact ); + gtk_action_set_sensitive( GTK_ACTION(eact), FALSE ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + } + + /* rx */ + { + gchar const* labels[] = {_("not rounded"), 0, 0, 0, 0, 0, 0, 0, 0}; + gdouble values[] = {0.5, 1, 2, 3, 5, 10, 20, 50, 100}; + eact = create_adjustment_action( "RadiusXAction", + _("Horizontal radius"), _("Rx:"), _("Horizontal radius of rounded corners"), + "/tools/shapes/rect/rx", 0, + GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, + 0, 1e6, SPIN_STEP, SPIN_PAGE_STEP, + labels, values, G_N_ELEMENTS(labels), + sp_rtb_rx_value_changed, tracker); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + } + + /* ry */ + { + gchar const* labels[] = {_("not rounded"), 0, 0, 0, 0, 0, 0, 0, 0}; + gdouble values[] = {0.5, 1, 2, 3, 5, 10, 20, 50, 100}; + eact = create_adjustment_action( "RadiusYAction", + _("Vertical radius"), _("Ry:"), _("Vertical radius of rounded corners"), + "/tools/shapes/rect/ry", 0, + GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, + 0, 1e6, SPIN_STEP, SPIN_PAGE_STEP, + labels, values, G_N_ELEMENTS(labels), + sp_rtb_ry_value_changed, tracker); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + } + + // add the units menu + { + InkSelectOneAction* act = tracker->createAction( "RectUnitsAction", _("Units"), ("") ); + gtk_action_group_add_action( mainActions, act->gobj() ); + } + + /* Reset */ + { + InkAction* inky = ink_action_new( "RectResetAction", + _("Not rounded"), + _("Make corners sharp"), + INKSCAPE_ICON("rectangle-make-corners-sharp"), + secondarySize ); + g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_rtb_defaults), holder ); + gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); + gtk_action_set_sensitive( GTK_ACTION(inky), TRUE ); + g_object_set_data( holder, "not_rounded", inky ); + } + + g_object_set_data( holder, "single", GINT_TO_POINTER(TRUE) ); + sp_rtb_sensitivize( holder ); + + desktop->connectEventContextChanged(sigc::bind(sigc::ptr_fun(rect_toolbox_watch_ec), holder)); + g_signal_connect( holder, "destroy", G_CALLBACK(purge_repr_listener), holder ); +} + +static void rect_toolbox_watch_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolBase* ec, GObject* holder) +{ + static sigc::connection changed; + + // use of dynamic_cast<> seems wrong here -- we just need to check the current tool + + if (dynamic_cast(ec)) { + Inkscape::Selection *sel = desktop->getSelection(); + + changed = sel->connectChanged(sigc::bind(sigc::ptr_fun(sp_rect_toolbox_selection_changed), holder)); + + // Synthesize an emission to trigger the update + sp_rect_toolbox_selection_changed(sel, holder); + } else { + if (changed) { + changed.disconnect(); + purge_repr_listener(NULL, holder); + } + } +} + +/* + 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:fileencoding=utf-8 : diff --git a/src/ui/toolbar/rect-toolbar.h b/src/ui/toolbar/rect-toolbar.h new file mode 100644 index 000000000..f89903c6c --- /dev/null +++ b/src/ui/toolbar/rect-toolbar.h @@ -0,0 +1,37 @@ +#ifndef SEEN_RECT_TOOLBAR_H +#define SEEN_RECT_TOOLBAR_H + +/** + * @file + * Rect aux toolbar + */ +/* Authors: + * MenTaLguY + * Lauris Kaplinski + * bulia byak + * Frank Felfe + * John Cliff + * David Turner + * Josh Andler + * Jon A. Cruz + * Maximilian Albert + * Tavmjong Bah + * Abhishek Sharma + * Kris De Gussem + * + * Copyright (C) 2004 David Turner + * Copyright (C) 2003 MenTaLguY + * Copyright (C) 1999-2011 authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +class SPDesktop; + +typedef struct _GtkActionGroup GtkActionGroup; +typedef struct _GObject GObject; + +void sp_rect_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); + +#endif /* !SEEN_RECT_TOOLBAR_H */ diff --git a/src/ui/toolbar/select-toolbar.cpp b/src/ui/toolbar/select-toolbar.cpp new file mode 100644 index 000000000..47a9b9ed7 --- /dev/null +++ b/src/ui/toolbar/select-toolbar.cpp @@ -0,0 +1,616 @@ +/* + * Selector aux toolbar + * + * Authors: + * Lauris Kaplinski + * bulia byak + * Jon A. Cruz + * Abhishek Sharma + * + * Copyright (C) 2003-2005 authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include <2geom/rect.h> + +#include "select-toolbar.h" + +#include "desktop.h" +#include "document-undo.h" +#include "document.h" +#include "widgets/ink-action.h" +#include "widgets/ink-toggle-action.h" +#include "widgets/toolbox.h" +#include "inkscape.h" +#include "message-stack.h" +#include "selection-chemistry.h" +#include "verbs.h" + +#include "display/sp-canvas.h" + +#include "helper/action-context.h" +#include "helper/action.h" + +#include "object/sp-item-transform.h" +#include "object/sp-namedview.h" + +#include "ui/icon-names.h" +#include "ui/widget/ink-select-one-action.h" +#include "ui/widget/spinbutton.h" +#include "ui/widget/unit-tracker.h" + +#include "widgets/ege-adjustment-action.h" +#include "widgets/sp-widget.h" +#include "widgets/widget-sizes.h" + +using Inkscape::UI::Widget::UnitTracker; +using Inkscape::Util::Unit; +using Inkscape::Util::Quantity; +using Inkscape::DocumentUndo; +using Inkscape::Util::unit_table; + +static void +sp_selection_layout_widget_update(SPWidget *spw, Inkscape::Selection *sel) +{ + if (g_object_get_data(G_OBJECT(spw), "update")) { + return; + } + + g_object_set_data(G_OBJECT(spw), "update", GINT_TO_POINTER(TRUE)); + + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + using Geom::X; + using Geom::Y; + if ( sel && !sel->isEmpty() ) { + int prefs_bbox = prefs->getInt("/tools/bounding_box", 0); + SPItem::BBoxType bbox_type = (prefs_bbox ==0)? + SPItem::VISUAL_BBOX : SPItem::GEOMETRIC_BBOX; + Geom::OptRect const bbox(sel->bounds(bbox_type)); + if ( bbox ) { + UnitTracker *tracker = reinterpret_cast(g_object_get_data(G_OBJECT(spw), "tracker")); + Unit const *unit = tracker->getActiveUnit(); + g_return_if_fail(unit != NULL); + + struct { char const *key; double val; } const keyval[] = { + { "X", bbox->min()[X] }, + { "Y", bbox->min()[Y] }, + { "width", bbox->dimensions()[X] }, + { "height", bbox->dimensions()[Y] } + }; + + if (unit->type == Inkscape::Util::UNIT_TYPE_DIMENSIONLESS) { + double const val = unit->factor * 100; + for (unsigned i = 0; i < G_N_ELEMENTS(keyval); ++i) { + GtkAdjustment *a = GTK_ADJUSTMENT(g_object_get_data(G_OBJECT(spw), keyval[i].key)); + gtk_adjustment_set_value(a, val); + tracker->setFullVal( a, keyval[i].val ); + } + } else { + for (unsigned i = 0; i < G_N_ELEMENTS(keyval); ++i) { + GtkAdjustment *a = GTK_ADJUSTMENT(g_object_get_data(G_OBJECT(spw), keyval[i].key)); + gtk_adjustment_set_value(a, Quantity::convert(keyval[i].val, "px", unit)); + } + } + } + } + + g_object_set_data(G_OBJECT(spw), "update", GINT_TO_POINTER(FALSE)); +} + + +static void +sp_selection_layout_widget_modify_selection(SPWidget *spw, Inkscape::Selection *selection, guint flags, gpointer data) +{ + SPDesktop *desktop = static_cast(data); + if ((desktop->getSelection() == selection) // only respond to changes in our desktop + && (flags & (SP_OBJECT_MODIFIED_FLAG | + SP_OBJECT_PARENT_MODIFIED_FLAG | + SP_OBJECT_CHILD_MODIFIED_FLAG ))) + { + sp_selection_layout_widget_update(spw, selection); + } +} + +static void +sp_selection_layout_widget_change_selection(SPWidget *spw, Inkscape::Selection *selection, gpointer data) +{ + SPDesktop *desktop = static_cast(data); + if (desktop->getSelection() == selection) { // only respond to changes in our desktop + gboolean setActive = (selection && !selection->isEmpty()); + std::vector *contextActions = reinterpret_cast *>(g_object_get_data(G_OBJECT(spw), "contextActions")); + if ( contextActions ) { + for ( std::vector::iterator iter = contextActions->begin(); + iter != contextActions->end(); ++iter) { + if ( setActive != gtk_action_is_sensitive(*iter) ) { + gtk_action_set_sensitive( *iter, setActive ); + } + } + } + + sp_selection_layout_widget_update(spw, selection); + } +} + +static void +sp_object_layout_any_value_changed(GtkAdjustment *adj, GObject *tbl) +{ + if (g_object_get_data(tbl, "update")) { + return; + } + + UnitTracker *tracker = reinterpret_cast(g_object_get_data(tbl, "tracker")); + if ( !tracker || tracker->isUpdating() ) { + /* + * When only units are being changed, don't treat changes + * to adjuster values as object changes. + */ + return; + } + g_object_set_data(tbl, "update", GINT_TO_POINTER(TRUE)); + + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + Inkscape::Selection *selection = desktop->getSelection(); + SPDocument *document = desktop->getDocument(); + + document->ensureUpToDate (); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + + Geom::OptRect bbox_vis = selection->visualBounds(); + Geom::OptRect bbox_geom = selection->geometricBounds(); + + int prefs_bbox = prefs->getInt("/tools/bounding_box"); + SPItem::BBoxType bbox_type = (prefs_bbox == 0)? + SPItem::VISUAL_BBOX : SPItem::GEOMETRIC_BBOX; + Geom::OptRect bbox_user = selection->bounds(bbox_type); + + if ( !bbox_user ) { + g_object_set_data(tbl, "update", GINT_TO_POINTER(FALSE)); + return; + } + + gdouble x0 = 0; + gdouble y0 = 0; + gdouble x1 = 0; + gdouble y1 = 0; + gdouble xrel = 0; + gdouble yrel = 0; + Unit const *unit = tracker->getActiveUnit(); + g_return_if_fail(unit != NULL); + + GtkAdjustment* a_x = GTK_ADJUSTMENT( g_object_get_data( tbl, "X" ) ); + GtkAdjustment* a_y = GTK_ADJUSTMENT( g_object_get_data( tbl, "Y" ) ); + GtkAdjustment* a_w = GTK_ADJUSTMENT( g_object_get_data( tbl, "width" ) ); + GtkAdjustment* a_h = GTK_ADJUSTMENT( g_object_get_data( tbl, "height" ) ); + + if (unit->type == Inkscape::Util::UNIT_TYPE_LINEAR) { + x0 = Quantity::convert(gtk_adjustment_get_value(a_x), unit, "px"); + y0 = Quantity::convert(gtk_adjustment_get_value(a_y), unit, "px"); + x1 = x0 + Quantity::convert(gtk_adjustment_get_value(a_w), unit, "px"); + xrel = Quantity::convert(gtk_adjustment_get_value(a_w), unit, "px") / bbox_user->dimensions()[Geom::X]; + y1 = y0 + Quantity::convert(gtk_adjustment_get_value(a_h), unit, "px");; + yrel = Quantity::convert(gtk_adjustment_get_value(a_h), unit, "px") / bbox_user->dimensions()[Geom::Y]; + } else { + double const x0_propn = gtk_adjustment_get_value (a_x) / 100 / unit->factor; + x0 = bbox_user->min()[Geom::X] * x0_propn; + double const y0_propn = gtk_adjustment_get_value (a_y) / 100 / unit->factor; + y0 = y0_propn * bbox_user->min()[Geom::Y]; + xrel = gtk_adjustment_get_value (a_w) / (100 / unit->factor); + x1 = x0 + xrel * bbox_user->dimensions()[Geom::X]; + yrel = gtk_adjustment_get_value (a_h) / (100 / unit->factor); + y1 = y0 + yrel * bbox_user->dimensions()[Geom::Y]; + } + + // Keep proportions if lock is on + GtkToggleAction *lock = GTK_TOGGLE_ACTION( g_object_get_data(tbl, "lock") ); + if ( gtk_toggle_action_get_active(lock) ) { + if (adj == a_h) { + x1 = x0 + yrel * bbox_user->dimensions()[Geom::X]; + } else if (adj == a_w) { + y1 = y0 + xrel * bbox_user->dimensions()[Geom::Y]; + } + } + + // scales and moves, in px + double mh = fabs(x0 - bbox_user->min()[Geom::X]); + double sh = fabs(x1 - bbox_user->max()[Geom::X]); + double mv = fabs(y0 - bbox_user->min()[Geom::Y]); + double sv = fabs(y1 - bbox_user->max()[Geom::Y]); + + // unless the unit is %, convert the scales and moves to the unit + if (unit->type == Inkscape::Util::UNIT_TYPE_LINEAR) { + mh = Quantity::convert(mh, "px", unit); + sh = Quantity::convert(sh, "px", unit); + mv = Quantity::convert(mv, "px", unit); + sv = Quantity::convert(sv, "px", unit); + } + + // do the action only if one of the scales/moves is greater than half the last significant + // digit in the spinbox (currently spinboxes have 3 fractional digits, so that makes 0.0005). If + // the value was changed by the user, the difference will be at least that much; otherwise it's + // just rounding difference between the spinbox value and actual value, so no action is + // performed + char const * const actionkey = ( mh > 5e-4 ? "selector:toolbar:move:horizontal" : + sh > 5e-4 ? "selector:toolbar:scale:horizontal" : + mv > 5e-4 ? "selector:toolbar:move:vertical" : + sv > 5e-4 ? "selector:toolbar:scale:vertical" : NULL ); + + if (actionkey != NULL) { + + // FIXME: fix for GTK breakage, see comment in SelectedStyle::on_opacity_changed + desktop->getCanvas()->forceFullRedrawAfterInterruptions(0); + + bool transform_stroke = prefs->getBool("/options/transform/stroke", true); + bool preserve = prefs->getBool("/options/preservetransform/value", false); + + Geom::Affine scaler; + if (bbox_type == SPItem::VISUAL_BBOX) { + scaler = get_scale_transform_for_variable_stroke (*bbox_vis, *bbox_geom, transform_stroke, preserve, x0, y0, x1, y1); + } else { + // 1) We could have use the newer get_scale_transform_for_variable_stroke() here, but to avoid regressions + // we'll just use the old get_scale_transform_for_uniform_stroke() for now. + // 2) get_scale_transform_for_uniform_stroke() is intended for visual bounding boxes, not geometrical ones! + // we'll trick it into using a geometric bounding box though, by setting the stroke width to zero + scaler = get_scale_transform_for_uniform_stroke (*bbox_geom, 0, 0, false, false, x0, y0, x1, y1); + } + + selection->applyAffine(scaler); + DocumentUndo::maybeDone(document, actionkey, SP_VERB_CONTEXT_SELECT, + _("Transform by toolbar")); + + // resume interruptibility + desktop->getCanvas()->endForcedFullRedraws(); + } + + g_object_set_data(tbl, "update", GINT_TO_POINTER(FALSE)); +} + +// toggle button callbacks and updaters + +static void toggle_stroke( GtkToggleAction* act, gpointer data ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + gboolean active = gtk_toggle_action_get_active(act); + prefs->setBool("/options/transform/stroke", active); + SPDesktop *desktop = static_cast(data); + if ( active ) { + desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Now stroke width is scaled when objects are scaled.")); + } else { + desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Now stroke width is not scaled when objects are scaled.")); + } +} + +static void toggle_corners( GtkToggleAction* act, gpointer data) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + gboolean active = gtk_toggle_action_get_active(act); + prefs->setBool("/options/transform/rectcorners", active); + SPDesktop *desktop = static_cast(data); + if ( active ) { + desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Now rounded rectangle corners are scaled when rectangles are scaled.")); + } else { + desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Now rounded rectangle corners are not scaled when rectangles are scaled.")); + } +} + +static void toggle_gradient( GtkToggleAction *act, gpointer data ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + gboolean active = gtk_toggle_action_get_active(act); + prefs->setBool("/options/transform/gradient", active); + SPDesktop *desktop = static_cast(data); + if ( active ) { + desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Now gradients are transformed along with their objects when those are transformed (moved, scaled, rotated, or skewed).")); + } else { + desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Now gradients remain fixed when objects are transformed (moved, scaled, rotated, or skewed).")); + } +} + +static void toggle_pattern( GtkToggleAction* act, gpointer data ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + gboolean active = gtk_toggle_action_get_active(act); + prefs->setInt("/options/transform/pattern", active); + SPDesktop *desktop = static_cast(data); + if ( active ) { + desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Now patterns are transformed along with their objects when those are transformed (moved, scaled, rotated, or skewed).")); + } else { + desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Now patterns remain fixed when objects are transformed (moved, scaled, rotated, or skewed).")); + } +} + +static void toggle_lock( 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 ); + } +} + +static void destroy_tracker( GObject* obj, gpointer /*user_data*/ ) +{ + UnitTracker *tracker = reinterpret_cast(g_object_get_data(obj, "tracker")); + if ( tracker ) { + delete tracker; + g_object_set_data( obj, "tracker", 0 ); + } +} + +static void trigger_sp_action( GtkAction* /*act*/, gpointer user_data ) +{ + SPAction* targetAction = SP_ACTION(user_data); + if ( targetAction ) { + sp_action_perform( targetAction, NULL ); + } +} + +static GtkAction* create_action_for_verb( Inkscape::Verb* verb, Inkscape::UI::View::View* view, GtkIconSize size ) +{ + GtkAction* act = 0; + + SPAction* targetAction = verb->get_action(Inkscape::ActionContext(view)); + InkAction* inky = ink_action_new( verb->get_id(), verb->get_name(), verb->get_tip(), verb->get_image(), size ); + act = GTK_ACTION(inky); + + g_signal_connect( G_OBJECT(inky), "activate", G_CALLBACK(trigger_sp_action), targetAction ); + + return act; +} + +void sp_select_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) +{ + Inkscape::UI::View::View *view = desktop; + GtkIconSize secondarySize = Inkscape::UI::ToolboxFactory::prefToSize("/toolbox/secondary", 1); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + + GtkAction* act = 0; + + GtkActionGroup* selectionActions = mainActions; // temporary + std::vector* contextActions = new std::vector(); + + act = create_action_for_verb( Inkscape::Verb::get(SP_VERB_EDIT_SELECT_ALL), view, secondarySize ); + gtk_action_group_add_action( selectionActions, act ); + act = create_action_for_verb( Inkscape::Verb::get(SP_VERB_EDIT_SELECT_ALL_IN_ALL_LAYERS), view, secondarySize ); + gtk_action_group_add_action( selectionActions, act ); + act = create_action_for_verb( Inkscape::Verb::get(SP_VERB_EDIT_DESELECT), view, secondarySize ); + gtk_action_group_add_action( selectionActions, act ); + contextActions->push_back( act ); + + act = create_action_for_verb( Inkscape::Verb::get(SP_VERB_OBJECT_ROTATE_90_CCW), view, secondarySize ); + gtk_action_group_add_action( selectionActions, act ); + contextActions->push_back( act ); + act = create_action_for_verb( Inkscape::Verb::get(SP_VERB_OBJECT_ROTATE_90_CW), view, secondarySize ); + gtk_action_group_add_action( selectionActions, act ); + contextActions->push_back( act ); + act = create_action_for_verb( Inkscape::Verb::get(SP_VERB_OBJECT_FLIP_HORIZONTAL), view, secondarySize ); + gtk_action_group_add_action( selectionActions, act ); + contextActions->push_back( act ); + act = create_action_for_verb( Inkscape::Verb::get(SP_VERB_OBJECT_FLIP_VERTICAL), view, secondarySize ); + gtk_action_group_add_action( selectionActions, act ); + contextActions->push_back( act ); + + act = create_action_for_verb( Inkscape::Verb::get(SP_VERB_SELECTION_TO_BACK), view, secondarySize ); + gtk_action_group_add_action( selectionActions, act ); + contextActions->push_back( act ); + act = create_action_for_verb( Inkscape::Verb::get(SP_VERB_SELECTION_LOWER), view, secondarySize ); + gtk_action_group_add_action( selectionActions, act ); + contextActions->push_back( act ); + act = create_action_for_verb( Inkscape::Verb::get(SP_VERB_SELECTION_RAISE), view, secondarySize ); + gtk_action_group_add_action( selectionActions, act ); + contextActions->push_back( act ); + act = create_action_for_verb( Inkscape::Verb::get(SP_VERB_SELECTION_TO_FRONT), view, secondarySize ); + gtk_action_group_add_action( selectionActions, act ); + contextActions->push_back( act ); + + // Create the parent widget for x y w h tracker. + GtkWidget *spw = sp_widget_new_global(); + + // Remember the desktop's canvas widget, to be used for defocusing. + g_object_set_data(G_OBJECT(spw), "dtw", desktop->getCanvas()); + + // The vb frame holds all other widgets and is used to set sensitivity depending on selection state. + auto vb = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); + gtk_box_set_homogeneous(GTK_BOX(vb), FALSE); + gtk_widget_show(vb); + gtk_container_add(GTK_CONTAINER(spw), vb); + + // Create the units menu. + UnitTracker* tracker = new UnitTracker(Inkscape::Util::UNIT_TYPE_LINEAR); + tracker->addUnit(unit_table.getUnit("%")); + tracker->setActiveUnit( desktop->getNamedView()->display_units ); + + g_object_set_data( G_OBJECT(spw), "tracker", tracker ); + g_signal_connect( G_OBJECT(spw), "destroy", G_CALLBACK(destroy_tracker), spw ); + + EgeAdjustmentAction* eact = 0; + + // four spinbuttons + + eact = create_adjustment_action( + "XAction", /* name */ + C_("Select toolbar", "X position"), /* label */ + C_("Select toolbar", "X:"), /* shortLabel */ + C_("Select toolbar", "Horizontal coordinate of selection"), /* tooltip */ + "/tools/select/X", /* path */ + 0.0, /* def(default) */ + GTK_WIDGET(desktop->canvas), /* focusTarget */ + G_OBJECT(spw), /* dataKludge */ + TRUE, "altx", /* altx, altx_mark */ + -1e6, 1e6, SPIN_STEP, SPIN_PAGE_STEP, /* lower, upper, step, page */ + 0, 0, 0, /* descrLabels, descrValues, descrCount */ + sp_object_layout_any_value_changed, /* callback */ + tracker, /* unit_tracker */ + SPIN_STEP, 3, 1); /* climb, digits, factor */ + + gtk_action_group_add_action( selectionActions, GTK_ACTION(eact) ); + contextActions->push_back( GTK_ACTION(eact) ); + + eact = create_adjustment_action( + "YAction", /* name */ + C_("Select toolbar", "Y position"), /* label */ + C_("Select toolbar", "Y:"), /* shortLabel */ + C_("Select toolbar", "Vertical coordinate of selection"), /* tooltip */ + "/tools/select/Y", /* path */ + 0.0, /* def(default) */ + GTK_WIDGET(desktop->canvas), /* focusTarget */ + G_OBJECT(spw), /* dataKludge */ + TRUE, "altx", /* altx, altx_mark */ + -1e6, 1e6, SPIN_STEP, SPIN_PAGE_STEP, /* lower, upper, step, page */ + 0, 0, 0, /* descrLabels, descrValues, descrCount */ + sp_object_layout_any_value_changed, /* callback */ + tracker, /* unit_tracker */ + SPIN_STEP, 3, 1); /* climb, digits, factor */ + + gtk_action_group_add_action( selectionActions, GTK_ACTION(eact) ); + contextActions->push_back( GTK_ACTION(eact) ); + + eact = create_adjustment_action( + "WidthAction", /* name */ + C_("Select toolbar", "Width"), /* label */ + C_("Select toolbar", "W:"), /* shortLabel */ + C_("Select toolbar", "Width of selection"), /* tooltip */ + "/tools/select/width", /* path */ + 0.0, /* def(default) */ + GTK_WIDGET(desktop->canvas), /* focusTarget */ + G_OBJECT(spw), /* dataKludge */ + TRUE, "altx", /* altx, altx_mark */ + 0.0, 1e6, SPIN_STEP, SPIN_PAGE_STEP, /* lower, upper, step, page */ + 0, 0, 0, /* descrLabels, descrValues, descrCount */ + sp_object_layout_any_value_changed, /* callback */ + tracker, /* unit_tracker */ + SPIN_STEP, 3, 1); /* climb, digits, factor */ + + gtk_action_group_add_action( selectionActions, GTK_ACTION(eact) ); + contextActions->push_back( GTK_ACTION(eact) ); + + // lock toggle + { + InkToggleAction* itact = ink_toggle_action_new( "LockAction", + _("Lock width and height"), + _("When locked, change both width and height by the same proportion"), + INKSCAPE_ICON("object-unlocked"), + GTK_ICON_SIZE_MENU ); + g_object_set( itact, "short_label", "Lock", NULL ); + g_object_set_data( G_OBJECT(spw), "lock", itact ); + g_signal_connect_after( G_OBJECT(itact), "toggled", G_CALLBACK(toggle_lock), desktop) ; + gtk_action_group_add_action( mainActions, GTK_ACTION(itact) ); + } + + eact = create_adjustment_action( + "HeightAction", /* name */ + C_("Select toolbar", "Height"), /* label */ + C_("Select toolbar", "H:"), /* shortLabel */ + C_("Select toolbar", "Height of selection"), /* tooltip */ + "/tools/select/height", /* path */ + 0.0, /* def(default) */ + GTK_WIDGET(desktop->canvas), /* focusTarget */ + G_OBJECT(spw), /* dataKludge */ + TRUE, "altx", /* altx, altx_mark */ + 0.0, 1e6, SPIN_STEP, SPIN_PAGE_STEP, /* lower, upper, step, page */ + 0, 0, 0, /* descrLabels, descrValues, descrCount */ + sp_object_layout_any_value_changed, /* callback */ + tracker, /* unit_tracker */ + SPIN_STEP, 3, 1); /* climb, digits, factor */ + + + gtk_action_group_add_action( selectionActions, GTK_ACTION(eact) ); + contextActions->push_back( GTK_ACTION(eact) ); + + // Add the units menu. + { + InkSelectOneAction* act = tracker->createAction( "UnitsAction", _("Units"), ("") ); + gtk_action_group_add_action( selectionActions, act->gobj() ); + } + + g_object_set_data( G_OBJECT(spw), "selectionActions", selectionActions ); + g_object_set_data( G_OBJECT(spw), "contextActions", contextActions ); + + // Force update when selection changes. + g_signal_connect(G_OBJECT(spw), "modify_selection", G_CALLBACK(sp_selection_layout_widget_modify_selection), desktop); + g_signal_connect(G_OBJECT(spw), "change_selection", G_CALLBACK(sp_selection_layout_widget_change_selection), desktop); + + // Update now. + sp_selection_layout_widget_update(SP_WIDGET(spw), SP_ACTIVE_DESKTOP ? SP_ACTIVE_DESKTOP->getSelection() : NULL); + + for ( std::vector::iterator iter = contextActions->begin(); + iter != contextActions->end(); ++iter) { + if ( gtk_action_is_sensitive(*iter) ) { + gtk_action_set_sensitive( *iter, FALSE ); + } + } + + // Insert spw into the toolbar. + if ( GTK_IS_BOX(holder) ) { + gtk_box_pack_start(GTK_BOX(holder), spw, FALSE, FALSE, 0); + } else if ( GTK_IS_TOOLBAR(holder) ) { + GtkToolItem *spw_toolitem = gtk_tool_item_new(); + gtk_container_add(GTK_CONTAINER(spw_toolitem), spw); + gtk_toolbar_insert(GTK_TOOLBAR(holder), spw_toolitem, -1); + } else { + g_warning("Unexpected holder type"); + } + // "Transform with object" buttons + { + + InkToggleAction* itact = ink_toggle_action_new( "transform_stroke", + _("Scale stroke width"), + _("When scaling objects, scale the stroke width by the same proportion"), + "transform-affect-stroke", + secondarySize ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(itact), prefs->getBool("/options/transform/stroke", true) ); + g_signal_connect_after( G_OBJECT(itact), "toggled", G_CALLBACK(toggle_stroke), desktop) ; + gtk_action_group_add_action( mainActions, GTK_ACTION(itact) ); + } + + { + InkToggleAction* itact = ink_toggle_action_new( "transform_corners", + _("Scale rounded corners"), + _("When scaling rectangles, scale the radii of rounded corners"), + "transform-affect-rounded-corners", + secondarySize ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(itact), prefs->getBool("/options/transform/rectcorners", true) ); + g_signal_connect_after( G_OBJECT(itact), "toggled", G_CALLBACK(toggle_corners), desktop) ; + gtk_action_group_add_action( mainActions, GTK_ACTION(itact) ); + } + + { + InkToggleAction* itact = ink_toggle_action_new( "transform_gradient", + _("Move gradients"), + _("Move gradients (in fill or stroke) along with the objects"), + "transform-affect-gradient", + secondarySize ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(itact), prefs->getBool("/options/transform/gradient", true) ); + g_signal_connect_after( G_OBJECT(itact), "toggled", G_CALLBACK(toggle_gradient), desktop) ; + gtk_action_group_add_action( mainActions, GTK_ACTION(itact) ); + } + + { + InkToggleAction* itact = ink_toggle_action_new( "transform_pattern", + _("Move patterns"), + _("Move patterns (in fill or stroke) along with the objects"), + "transform-affect-pattern", + secondarySize ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(itact), prefs->getBool("/options/transform/pattern", true) ); + g_signal_connect_after( G_OBJECT(itact), "toggled", G_CALLBACK(toggle_pattern), desktop) ; + gtk_action_group_add_action( mainActions, GTK_ACTION(itact) ); + } +} + + +/* + 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 : diff --git a/src/ui/toolbar/select-toolbar.h b/src/ui/toolbar/select-toolbar.h new file mode 100644 index 000000000..b900a0615 --- /dev/null +++ b/src/ui/toolbar/select-toolbar.h @@ -0,0 +1,36 @@ +#ifndef SEEN_SELECT_TOOLBAR_H +#define SEEN_SELECT_TOOLBAR_H + +/** \file + * Selector aux toolbar + */ +/* + * Authors: + * Lauris Kaplinski + * bulia byak + * + * Copyright (C) 2003 authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +class SPDesktop; + +typedef struct _GtkActionGroup GtkActionGroup; +typedef struct _GObject GObject; + +void sp_select_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); + + +#endif /* !SEEN_SELECT_TOOLBAR_H */ + +/* + 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:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/toolbar/spiral-toolbar.cpp b/src/ui/toolbar/spiral-toolbar.cpp new file mode 100644 index 000000000..c5c87755d --- /dev/null +++ b/src/ui/toolbar/spiral-toolbar.cpp @@ -0,0 +1,319 @@ +/** + * @file + * Spiral aux toolbar + */ +/* Authors: + * MenTaLguY + * Lauris Kaplinski + * bulia byak + * Frank Felfe + * John Cliff + * David Turner + * Josh Andler + * Jon A. Cruz + * Maximilian Albert + * Tavmjong Bah + * Abhishek Sharma + * Kris De Gussem + * + * Copyright (C) 2004 David Turner + * Copyright (C) 2003 MenTaLguY + * Copyright (C) 1999-2011 authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +#include "spiral-toolbar.h" + +#include "desktop.h" +#include "document-undo.h" +#include "selection.h" +#include "widgets/toolbox.h" +#include "verbs.h" + +#include "object/sp-spiral.h" + +#include "ui/icon-names.h" +#include "ui/uxmanager.h" + +#include "widgets/ege-adjustment-action.h" +#include "widgets/ege-output-action.h" +#include "widgets/ink-action.h" +#include "widgets/spinbutton-events.h" + +#include "xml/node-event-vector.h" + +using Inkscape::UI::UXManager; +using Inkscape::DocumentUndo; +using Inkscape::UI::ToolboxFactory; +using Inkscape::UI::PrefPusher; + +//######################## +//## Spiral ## +//######################## + +static void sp_spl_tb_value_changed(GtkAdjustment *adj, GObject *tbl, Glib::ustring const &value_name) +{ + SPDesktop *desktop = static_cast(g_object_get_data( tbl, "desktop" )); + + if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble("/tools/shapes/spiral/" + value_name, + gtk_adjustment_get_value(adj)); + } + + // quit if run by the attr_changed listener + if (g_object_get_data( tbl, "freeze" )) { + return; + } + + // in turn, prevent listener from responding + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); + + gchar* namespaced_name = g_strconcat("sodipodi:", value_name.data(), NULL); + + bool modmade = false; + auto itemlist= desktop->getSelection()->items(); + for(auto i=itemlist.begin();i!=itemlist.end(); ++i){ + SPItem *item = *i; + if (SP_IS_SPIRAL(item)) { + Inkscape::XML::Node *repr = item->getRepr(); + sp_repr_set_svg_double( repr, namespaced_name, + gtk_adjustment_get_value(adj) ); + item->updateRepr(); + modmade = true; + } + } + + g_free(namespaced_name); + + if (modmade) { + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_SPIRAL, + _("Change spiral")); + } + + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); +} + +static void sp_spl_tb_revolution_value_changed(GtkAdjustment *adj, GObject *tbl) +{ + sp_spl_tb_value_changed(adj, tbl, "revolution"); +} + +static void sp_spl_tb_expansion_value_changed(GtkAdjustment *adj, GObject *tbl) +{ + sp_spl_tb_value_changed(adj, tbl, "expansion"); +} + +static void sp_spl_tb_t0_value_changed(GtkAdjustment *adj, GObject *tbl) +{ + sp_spl_tb_value_changed(adj, tbl, "t0"); +} + +static void sp_spl_tb_defaults(GtkWidget * /*widget*/, GObject *obj) +{ + GtkWidget *tbl = GTK_WIDGET(obj); + + GtkAdjustment *adj; + + // fixme: make settable + gdouble rev = 3; + gdouble exp = 1.0; + gdouble t0 = 0.0; + + adj = GTK_ADJUSTMENT(g_object_get_data(obj, "revolution")); + gtk_adjustment_set_value(adj, rev); + +#if !GTK_CHECK_VERSION(3,18,0) + gtk_adjustment_value_changed(adj); +#endif + + adj = GTK_ADJUSTMENT(g_object_get_data(obj, "expansion")); + gtk_adjustment_set_value(adj, exp); + gtk_adjustment_value_changed(adj); + + adj = GTK_ADJUSTMENT(g_object_get_data(obj, "t0")); + gtk_adjustment_set_value(adj, t0); + +#if !GTK_CHECK_VERSION(3,18,0) + gtk_adjustment_value_changed(adj); +#endif + + spinbutton_defocus(tbl); +} + + +static void spiral_tb_event_attr_changed(Inkscape::XML::Node *repr, + gchar const * /*name*/, + gchar const * /*old_value*/, + gchar const * /*new_value*/, + bool /*is_interactive*/, + gpointer data) +{ + GtkWidget *tbl = GTK_WIDGET(data); + + // quit if run by the _changed callbacks + if (g_object_get_data(G_OBJECT(tbl), "freeze")) { + return; + } + + // in turn, prevent callbacks from responding + g_object_set_data(G_OBJECT(tbl), "freeze", GINT_TO_POINTER(TRUE)); + + GtkAdjustment *adj; + adj = GTK_ADJUSTMENT(g_object_get_data(G_OBJECT(tbl), "revolution")); + double revolution = 3.0; + sp_repr_get_double(repr, "sodipodi:revolution", &revolution); + gtk_adjustment_set_value(adj, revolution); + + adj = GTK_ADJUSTMENT(g_object_get_data(G_OBJECT(tbl), "expansion")); + double expansion = 1.0; + sp_repr_get_double(repr, "sodipodi:expansion", &expansion); + gtk_adjustment_set_value(adj, expansion); + + adj = GTK_ADJUSTMENT(g_object_get_data(G_OBJECT(tbl), "t0")); + double t0 = 0.0; + sp_repr_get_double(repr, "sodipodi:t0", &t0); + gtk_adjustment_set_value(adj, t0); + + g_object_set_data(G_OBJECT(tbl), "freeze", GINT_TO_POINTER(FALSE)); +} + + +static Inkscape::XML::NodeEventVector spiral_tb_repr_events = { + NULL, /* child_added */ + NULL, /* child_removed */ + spiral_tb_event_attr_changed, + NULL, /* content_changed */ + NULL /* order_changed */ +}; + +static void sp_spiral_toolbox_selection_changed(Inkscape::Selection *selection, GObject *tbl) +{ + int n_selected = 0; + Inkscape::XML::Node *repr = NULL; + + purge_repr_listener( tbl, tbl ); + + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end(); ++i){ + SPItem *item = *i; + if (SP_IS_SPIRAL(item)) { + n_selected++; + repr = item->getRepr(); + } + } + + EgeOutputAction* act = EGE_OUTPUT_ACTION( g_object_get_data( tbl, "mode_action" ) ); + + if (n_selected == 0) { + g_object_set( G_OBJECT(act), "label", _("New:"), NULL ); + } else if (n_selected == 1) { + g_object_set( G_OBJECT(act), "label", _("Change:"), NULL ); + + if (repr) { + g_object_set_data( tbl, "repr", repr ); + Inkscape::GC::anchor(repr); + sp_repr_add_listener(repr, &spiral_tb_repr_events, tbl); + sp_repr_synthesize_events(repr, &spiral_tb_repr_events, tbl); + } + } else { + // FIXME: implement averaging of all parameters for multiple selected + //gtk_label_set_markup(GTK_LABEL(l), _("Average:")); + g_object_set( G_OBJECT(act), "label", _("Change:"), NULL ); + } +} + + +void sp_spiral_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) +{ + EgeAdjustmentAction* eact = 0; + GtkIconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1); + + { + EgeOutputAction* act = ege_output_action_new( "SpiralStateAction", _("New:"), "", 0 ); + ege_output_action_set_use_markup( act, TRUE ); + gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); + g_object_set_data( holder, "mode_action", act ); + } + + /* Revolution */ + { + gchar const* labels[] = {_("just a curve"), 0, _("one full revolution"), 0, 0, 0, 0, 0, 0}; + gdouble values[] = {0.01, 0.5, 1, 2, 3, 5, 10, 20, 50, 100}; + eact = create_adjustment_action( "SpiralRevolutionAction", + _("Number of turns"), _("Turns:"), _("Number of revolutions"), + "/tools/shapes/spiral/revolution", 3.0, + GTK_WIDGET(desktop->canvas), holder, TRUE, "altx-spiral", + 0.01, 1024.0, 0.1, 1.0, + labels, values, G_N_ELEMENTS(labels), + sp_spl_tb_revolution_value_changed, NULL /*unit tracker*/, 1, 2); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + } + + /* Expansion */ + { + gchar const* labels[] = {_("circle"), _("edge is much denser"), _("edge is denser"), _("even"), _("center is denser"), _("center is much denser"), 0}; + gdouble values[] = {0, 0.1, 0.5, 1, 1.5, 5, 20}; + eact = create_adjustment_action( "SpiralExpansionAction", + _("Divergence"), _("Divergence:"), _("How much denser/sparser are outer revolutions; 1 = uniform"), + "/tools/shapes/spiral/expansion", 1.0, + GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, + 0.0, 1000.0, 0.01, 1.0, + labels, values, G_N_ELEMENTS(labels), + sp_spl_tb_expansion_value_changed); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + } + + /* T0 */ + { + gchar const* labels[] = {_("starts from center"), _("starts mid-way"), _("starts near edge")}; + gdouble values[] = {0, 0.5, 0.9}; + eact = create_adjustment_action( "SpiralT0Action", + _("Inner radius"), _("Inner radius:"), _("Radius of the innermost revolution (relative to the spiral size)"), + "/tools/shapes/spiral/t0", 0.0, + GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, + 0.0, 0.999, 0.01, 1.0, + labels, values, G_N_ELEMENTS(labels), + sp_spl_tb_t0_value_changed); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + } + + /* Reset */ + { + InkAction* inky = ink_action_new( "SpiralResetAction", + _("Defaults"), + _("Reset shape parameters to defaults (use Inkscape Preferences > Tools to change defaults)"), + INKSCAPE_ICON("edit-clear"), + secondarySize ); + g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_spl_tb_defaults), holder ); + gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); + } + + + sigc::connection *connection = new sigc::connection( + desktop->getSelection()->connectChanged(sigc::bind(sigc::ptr_fun(sp_spiral_toolbox_selection_changed), holder)) + ); + g_signal_connect( holder, "destroy", G_CALLBACK(delete_connection), connection ); + g_signal_connect( holder, "destroy", G_CALLBACK(purge_repr_listener), holder ); +} + + +/* + 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:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/toolbar/spiral-toolbar.h b/src/ui/toolbar/spiral-toolbar.h new file mode 100644 index 000000000..3372ea224 --- /dev/null +++ b/src/ui/toolbar/spiral-toolbar.h @@ -0,0 +1,37 @@ +#ifndef SEEN_SPIRAL_TOOLBAR_H +#define SEEN_SPIRAL_TOOLBAR_H + +/** + * @file + * Spiral aux toolbar + */ +/* Authors: + * MenTaLguY + * Lauris Kaplinski + * bulia byak + * Frank Felfe + * John Cliff + * David Turner + * Josh Andler + * Jon A. Cruz + * Maximilian Albert + * Tavmjong Bah + * Abhishek Sharma + * Kris De Gussem + * + * Copyright (C) 2004 David Turner + * Copyright (C) 2003 MenTaLguY + * Copyright (C) 1999-2011 authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +class SPDesktop; + +typedef struct _GtkActionGroup GtkActionGroup; +typedef struct _GObject GObject; + +void sp_spiral_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); + +#endif /* !SEEN_SPIRAL_TOOLBAR_H */ diff --git a/src/ui/toolbar/spray-toolbar.cpp b/src/ui/toolbar/spray-toolbar.cpp new file mode 100644 index 000000000..f44e61051 --- /dev/null +++ b/src/ui/toolbar/spray-toolbar.cpp @@ -0,0 +1,629 @@ +/** + * @file + * Spray aux toolbar + */ +/* Authors: + * MenTaLguY + * Lauris Kaplinski + * bulia byak + * Frank Felfe + * John Cliff + * David Turner + * Josh Andler + * Jon A. Cruz + * Maximilian Albert + * Tavmjong Bah + * Abhishek Sharma + * Kris De Gussem + * Jabiertxo Arraiza + * + * Copyright (C) 2004 David Turner + * Copyright (C) 2003 MenTaLguY + * Copyright (C) 1999-2015 authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include "spray-toolbar.h" +#include "desktop.h" +#include "inkscape.h" +#include "widgets/ege-adjustment-action.h" +#include "widgets/ink-toggle-action.h" +#include "widgets/toolbox.h" +#include "ui/dialog/clonetiler.h" +#include "ui/dialog/dialog-manager.h" +#include "ui/dialog/panel-dialog.h" +#include "ui/widget/ink-select-one-action.h" +#include "ui/icon-names.h" + +#include + +using Inkscape::UI::ToolboxFactory; +using Inkscape::UI::PrefPusher; + +// Disabled in 0.91 because of Bug #1274831 (crash, spraying an object +// with the mode: spray object in single path) +// Please enable again when working on 1.0 +#define ENABLE_SPRAY_MODE_SINGLE_PATH + +//######################## +//## Spray ## +//######################## + +static void sp_stb_update_widgets( GObject *tbl ) +{ + GtkAction* offset = GTK_ACTION( g_object_get_data(tbl, "offset") ); + GtkAction* spray_scale = GTK_ACTION( g_object_get_data(tbl, "spray_scale") ); + GtkAdjustment *adj_offset = ege_adjustment_action_get_adjustment( EGE_ADJUSTMENT_ACTION(offset) ); + GtkAdjustment *adj_scale = ege_adjustment_action_get_adjustment( EGE_ADJUSTMENT_ACTION(spray_scale) ); + GtkAction *no_overlap_action = GTK_ACTION( g_object_get_data(tbl, "no_overlap") ); + GtkToggleAction *no_overlap = GTK_TOGGLE_ACTION( g_object_get_data(tbl, "no_overlap") ); + GtkAction *picker_action = GTK_ACTION( g_object_get_data(tbl, "picker") ); + GtkToggleAction *picker = GTK_TOGGLE_ACTION( g_object_get_data(tbl, "picker") ); + GtkToggleAction *usepressurescale = GTK_TOGGLE_ACTION( g_object_get_data(tbl, "usepressurescale") ); + GtkAction *pick_fill = GTK_ACTION( g_object_get_data(tbl, "pick_fill") ); + GtkAction *pick_stroke = GTK_ACTION( g_object_get_data(tbl, "pick_stroke") ); + GtkAction *pick_inverse_value = GTK_ACTION( g_object_get_data(tbl, "pick_inverse_value") ); + GtkAction *pick_center = GTK_ACTION( g_object_get_data(tbl, "pick_center") ); + gtk_adjustment_set_value( adj_offset, 100.0 ); + if (gtk_toggle_action_get_active(no_overlap) && gtk_action_get_visible(no_overlap_action)) { + gtk_action_set_visible( offset, true ); + } else { + gtk_action_set_visible( offset, false ); + } + if (gtk_toggle_action_get_active(usepressurescale)) { + gtk_adjustment_set_value( adj_scale, 0.0 ); + gtk_action_set_sensitive( spray_scale, false ); + } else { + gtk_action_set_sensitive( spray_scale, true ); + } + if(gtk_toggle_action_get_active(picker) && gtk_action_get_visible(picker_action)){ + gtk_action_set_visible( pick_fill, true ); + gtk_action_set_visible( pick_stroke, true ); + gtk_action_set_visible( pick_inverse_value, true ); + gtk_action_set_visible( pick_center, true ); + } else { + gtk_action_set_visible( pick_fill, false ); + gtk_action_set_visible( pick_stroke, false ); + gtk_action_set_visible( pick_inverse_value, false ); + gtk_action_set_visible( pick_center, false ); + } +} + +static void sp_spray_init( GObject *tbl){ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + int mode = prefs->getInt("/tools/spray/mode", 0); + + bool show = true; + if(mode == 3 || mode == 2){ + show = false; + } + gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "no_overlap") ), show ); + gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "over_no_transparent") ), show ); + gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "over_transparent") ), show ); + gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "pick_no_overlap") ), show ); + gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "pick_stroke") ), show ); + gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "pick_fill") ), show ); + gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "pick_inverse_value") ), show ); + gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "pick_center") ), show ); + gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "picker") ), show ); + gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "offset") ), show ); + gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "pick_fill") ), show ); + gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "pick_stroke") ), show ); + gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "pick_inverse_value") ), show ); + gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "pick_center") ), show ); + if(mode == 2){ + show = true; + } + gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "spray_rotation") ), show ); + sp_stb_update_widgets( tbl ); +} + +Inkscape::UI::Dialog::CloneTiler *get_clone_tiler_panel(SPDesktop *desktop) +{ + if (Inkscape::UI::Dialog::PanelDialogBase *panel_dialog = + dynamic_cast(desktop->_dlg_mgr->getDialog("CloneTiler"))) { + try { + Inkscape::UI::Dialog::CloneTiler &clone_tiler = + dynamic_cast(panel_dialog->getPanel()); + return &clone_tiler; + } catch (std::exception &e) { } + } + + return 0; +} + +static void sp_spray_width_value_changed( GtkAdjustment *adj, GObject * /*tbl*/ ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble( "/tools/spray/width", + gtk_adjustment_get_value(adj)); +} + +static void sp_spray_mean_value_changed( GtkAdjustment *adj, GObject * /*tbl*/ ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble( "/tools/spray/mean", + gtk_adjustment_get_value(adj)); +} + +static void sp_spray_standard_deviation_value_changed( GtkAdjustment *adj, GObject * /*tbl*/ ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble( "/tools/spray/standard_deviation", + gtk_adjustment_get_value(adj)); +} + +static void sp_spray_mode_changed( GObject *tbl, int mode ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setInt("/tools/spray/mode", mode); + sp_spray_init(tbl); +} + +static void sp_spray_population_value_changed( GtkAdjustment *adj, GObject * /*tbl*/ ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble( "/tools/spray/population", + gtk_adjustment_get_value(adj)); +} + +static void sp_spray_rotation_value_changed( GtkAdjustment *adj, GObject * /*tbl*/ ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble( "/tools/spray/rotation_variation", + gtk_adjustment_get_value(adj)); +} + +static void sp_spray_scale_value_changed( GtkAdjustment *adj, GObject * /*tbl*/ ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble( "/tools/spray/scale_variation", + gtk_adjustment_get_value(adj)); +} + +static void sp_spray_offset_value_changed( GtkAdjustment *adj, GObject * /*tbl*/ ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble( "/tools/spray/offset", + gtk_adjustment_get_value(adj)); +} + +static void sp_toggle_no_overlap( GtkToggleAction* act, gpointer data) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + gboolean active = gtk_toggle_action_get_active(act); + prefs->setBool("/tools/spray/no_overlap", active); + GObject *tbl = G_OBJECT(data); + sp_stb_update_widgets(tbl); +} + +static void sp_toggle_pressure_scale( GtkToggleAction* act, gpointer data) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + gboolean active = gtk_toggle_action_get_active(act); + prefs->setBool("/tools/spray/usepressurescale", active); + if(active){ + prefs->setDouble("/tools/spray/scale_variation", 0); + } + GObject *tbl = G_OBJECT(data); + sp_stb_update_widgets( tbl ); +} + +static void sp_toggle_over_no_transparent( GtkToggleAction* act, gpointer data) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + gboolean active = gtk_toggle_action_get_active(act); + prefs->setBool("/tools/spray/over_no_transparent", active); +} + +static void sp_toggle_over_transparent( GtkToggleAction* act, gpointer data) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + gboolean active = gtk_toggle_action_get_active(act); + prefs->setBool("/tools/spray/over_transparent", active); +} + + +static void sp_toggle_picker( GtkToggleAction* act, gpointer data ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + gboolean active = gtk_toggle_action_get_active(act); + prefs->setBool("/tools/spray/picker", active); + if(active){ + prefs->setBool("/dialogs/clonetiler/dotrace", false); + SPDesktop *dt = SP_ACTIVE_DESKTOP; + if (Inkscape::UI::Dialog::CloneTiler *ct = get_clone_tiler_panel(dt)){ + dt->_dlg_mgr->showDialog("CloneTiler"); + ct->show_page_trace(); + } + } + GObject *tbl = G_OBJECT(data); + sp_stb_update_widgets(tbl); +} + +static void sp_toggle_pick_center( GtkToggleAction* act, gpointer data ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + gboolean active = gtk_toggle_action_get_active(act); + prefs->setBool("/tools/spray/pick_center", active); +} + +static void sp_toggle_pick_fill( GtkToggleAction* act, gpointer data ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + gboolean active = gtk_toggle_action_get_active(act); + prefs->setBool("/tools/spray/pick_fill", active); +} + +static void sp_toggle_pick_stroke( GtkToggleAction* act, gpointer data ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + gboolean active = gtk_toggle_action_get_active(act); + prefs->setBool("/tools/spray/pick_stroke", active); +} + +static void sp_toggle_pick_no_overlap( GtkToggleAction* act, gpointer data ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + gboolean active = gtk_toggle_action_get_active(act); + prefs->setBool("/tools/spray/pick_no_overlap", active); +} + +static void sp_toggle_pick_inverse_value( GtkToggleAction* act, gpointer data ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + gboolean active = gtk_toggle_action_get_active(act); + prefs->setBool("/tools/spray/pick_inverse_value", active); +} + +void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) +{ + GtkIconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + { + /* Width */ + gchar const* labels[] = {_("(narrow spray)"), 0, 0, 0, _("(default)"), 0, 0, 0, 0, _("(broad spray)")}; + gdouble values[] = {1, 3, 5, 10, 15, 20, 30, 50, 75, 100}; + EgeAdjustmentAction *eact = create_adjustment_action( "SprayWidthAction", + _("Width"), _("Width:"), _("The width of the spray area (relative to the visible canvas area)"), + "/tools/spray/width", 15, + GTK_WIDGET(desktop->canvas), holder, true, "altx-spray", + 1, 100, 1.0, 10.0, + labels, values, G_N_ELEMENTS(labels), + sp_spray_width_value_changed, NULL /*unit tracker*/, 1, 0 ); + ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + gtk_action_set_sensitive( GTK_ACTION(eact), true ); + } + + /* Use Pressure Width button */ + { + InkToggleAction* act = ink_toggle_action_new( "SprayPressureWidthAction", + _("Pressure"), + _("Use the pressure of the input device to alter the width of spray area"), + INKSCAPE_ICON("draw-use-pressure"), + GTK_ICON_SIZE_MENU ); + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(act), "/tools/spray/usepressurewidth"); + g_signal_connect(holder, "destroy", G_CALLBACK(delete_prefspusher), pusher); + + } + + { + /* Mean */ + gchar const* labels[] = {_("(default)"), 0, 0, 0, 0, 0, 0, _("(maximum mean)")}; + gdouble values[] = {0, 5, 10, 20, 30, 50, 70, 100}; + EgeAdjustmentAction *eact = create_adjustment_action( "SprayMeanAction", + _("Focus"), _("Focus:"), _("0 to spray a spot; increase to enlarge the ring radius"), + "/tools/spray/mean", 0, + GTK_WIDGET(desktop->canvas), holder, true, "spray-mean", + 0, 100, 1.0, 10.0, + labels, values, G_N_ELEMENTS(labels), + sp_spray_mean_value_changed, NULL /*unit tracker*/, 1, 0 ); + ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + gtk_action_set_sensitive( GTK_ACTION(eact), true ); + } + + { + /* Standard_deviation */ + gchar const* labels[] = {_("(minimum scatter)"), 0, 0, 0, 0, 0, _("(default)"), _("(maximum scatter)")}; + gdouble values[] = {1, 5, 10, 20, 30, 50, 70, 100}; + EgeAdjustmentAction *eact = create_adjustment_action( "SprayStandard_deviationAction", + C_("Spray tool", "Scatter"), C_("Spray tool", "Scatter:"), _("Increase to scatter sprayed objects"), + "/tools/spray/standard_deviation", 70, + GTK_WIDGET(desktop->canvas), holder, true, "spray-standard_deviation", + 1, 100, 1.0, 10.0, + labels, values, G_N_ELEMENTS(labels), + sp_spray_standard_deviation_value_changed, NULL /*unit tracker*/, 1, 0 ); + ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + gtk_action_set_sensitive( GTK_ACTION(eact), true ); + } + + /* Mode */ + { + InkSelectOneActionColumns columns; + + Glib::RefPtr store = Gtk::ListStore::create(columns); + + Gtk::TreeModel::Row row; + + row = *(store->append()); + row[columns.col_label ] = _("Spray with copies"); + row[columns.col_tooltip ] = _("Spray copies of the initial selection"); + row[columns.col_icon ] = INKSCAPE_ICON("spray-mode-copy"); + row[columns.col_sensitive] = true; + + row = *(store->append()); + row[columns.col_label ] = _("Spray with clones"); + row[columns.col_tooltip ] = _("Spray clones of the initial selection"); + row[columns.col_icon ] = INKSCAPE_ICON("spray-mode-clone"); + row[columns.col_sensitive] = true; + +#ifdef ENABLE_SPRAY_MODE_SINGLE_PATH + row = *(store->append()); + row[columns.col_label ] = _("Spray single path"); + row[columns.col_tooltip ] = _("Spray objects in a single path"); + row[columns.col_icon ] = INKSCAPE_ICON("spray-mode-union"); + row[columns.col_sensitive] = true; +#endif + + row = *(store->append()); + row[columns.col_label ] = _("Delete sprayed items"); + row[columns.col_tooltip ] = _("Delete sprayed items from selection"); + row[columns.col_icon ] = INKSCAPE_ICON("draw-eraser"); + row[columns.col_sensitive] = true; + + InkSelectOneAction* act = + InkSelectOneAction::create( "SprayModeAction", // Name + _("Mode"), // Label + "", // Tooltip + "Not Used", // Icon + store ); // Tree store + + act->use_radio( true ); + act->use_group_label( true ); + gint mode = prefs->getInt("/tools/spray/mode", 1); + act->set_active( mode ); + + gtk_action_group_add_action( mainActions, GTK_ACTION( act->gobj() )); + g_object_set_data( holder, "spray_tool_mode", act ); + + act->signal_changed().connect(sigc::bind<0>(sigc::ptr_fun(&sp_spray_mode_changed), holder)); + } + + { /* Population */ + gchar const* labels[] = {_("(low population)"), 0, 0, 0, _("(default)"), 0, _("(high population)")}; + gdouble values[] = {5, 20, 35, 50, 70, 85, 100}; + EgeAdjustmentAction *eact = create_adjustment_action( "SprayPopulationAction", + _("Amount"), _("Amount:"), + _("Adjusts the number of items sprayed per click"), + "/tools/spray/population", 70, + GTK_WIDGET(desktop->canvas), holder, true, "spray-population", + 1, 100, 1.0, 10.0, + labels, values, G_N_ELEMENTS(labels), + sp_spray_population_value_changed, NULL /*unit tracker*/, 1, 0 ); + ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + gtk_action_set_sensitive( GTK_ACTION(eact), true ); + g_object_set_data( holder, "spray_population", eact ); + } + + /* Use Pressure Population button */ + { + InkToggleAction* act = ink_toggle_action_new( "SprayPressurePopulationAction", + _("Pressure"), + _("Use the pressure of the input device to alter the amount of sprayed objects"), + INKSCAPE_ICON("draw-use-pressure"), + GTK_ICON_SIZE_MENU ); + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(act), "/tools/spray/usepressurepopulation"); + g_signal_connect(holder, "destroy", G_CALLBACK(delete_prefspusher), pusher); + + } + + { /* Rotation */ + gchar const* labels[] = {_("(default)"), 0, 0, 0, 0, 0, 0, _("(high rotation variation)")}; + gdouble values[] = {0, 10, 25, 35, 50, 60, 80, 100}; + EgeAdjustmentAction *eact = create_adjustment_action( "SprayRotationAction", + _("Rotation"), _("Rotation:"), + // xgettext:no-c-format + _("Variation of the rotation of the sprayed objects; 0% for the same rotation than the original object"), + "/tools/spray/rotation_variation", 0, + GTK_WIDGET(desktop->canvas), holder, true, "spray-rotation", + 0, 100, 1.0, 10.0, + labels, values, G_N_ELEMENTS(labels), + sp_spray_rotation_value_changed, NULL /*unit tracker*/, 1, 0 ); + ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + gtk_action_set_sensitive( GTK_ACTION(eact), true ); + g_object_set_data( holder, "spray_rotation", eact ); + } + + { /* Scale */ + gchar const* labels[] = {_("(default)"), 0, 0, 0, 0, 0, 0, _("(high scale variation)")}; + gdouble values[] = {0, 10, 25, 35, 50, 60, 80, 100}; + EgeAdjustmentAction *eact = create_adjustment_action( "SprayScaleAction", + C_("Spray tool", "Scale"), C_("Spray tool", "Scale:"), + // xgettext:no-c-format + _("Variation in the scale of the sprayed objects; 0% for the same scale than the original object"), + "/tools/spray/scale_variation", 0, + GTK_WIDGET(desktop->canvas), holder, true, "spray-scale", + 0, 100, 1.0, 10.0, + labels, values, G_N_ELEMENTS(labels), + sp_spray_scale_value_changed, NULL /*unit tracker*/, 1, 0 ); + ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + gtk_action_set_sensitive( GTK_ACTION(eact), true ); + g_object_set_data( holder, "spray_scale", eact ); + } + + /* Use Pressure Scale button */ + { + InkToggleAction* act = ink_toggle_action_new( "SprayPressureScaleAction", + _("Pressure"), + _("Use the pressure of the input device to alter the scale of new items"), + INKSCAPE_ICON("draw-use-pressure"), + GTK_ICON_SIZE_MENU); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/usepressurescale", false) ); + g_object_set_data( holder, "usepressurescale", act ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_pressure_scale), holder) ; + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + } + + /* Picker */ + { + InkToggleAction* act = ink_toggle_action_new( "SprayPickColorAction", + _("Pick color from the drawing. You can use clonetiler trace dialog for advanced effects. In clone mode original fill or stroke colors must be unset."), + _("Pick color from the drawing. You can use clonetiler trace dialog for advanced effects. In clone mode original fill or stroke colors must be unset."), + INKSCAPE_ICON("color-picker"), + secondarySize ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/picker", false) ); + g_object_set_data( holder, "picker", act ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_picker), holder) ; + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + } + + /* Pick from center */ + { + InkToggleAction* act = ink_toggle_action_new( "SprayPickCenterAction", + _("Pick from center instead average area."), + _("Pick from center instead average area."), + INKSCAPE_ICON("snap-bounding-box-center"), + secondarySize ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/pick_center", true) ); + g_object_set_data( holder, "pick_center", act ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_pick_center), holder) ; + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + } + + /* Inverse Value Size */ + { + InkToggleAction* act = ink_toggle_action_new( "SprayPickInverseValueAction", + _("Inverted pick value, retaining color in advanced trace mode"), + _("Inverted pick value, retaining color in advanced trace mode"), + INKSCAPE_ICON("object-tweak-shrink"), + secondarySize ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/pick_inverse_value", false) ); + g_object_set_data( holder, "pick_inverse_value", act ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_pick_inverse_value), holder) ; + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + } + + /* Pick Fill */ + { + InkToggleAction* act = ink_toggle_action_new( "SprayPickFillAction", + _("Apply picked color to fill"), + _("Apply picked color to fill"), + INKSCAPE_ICON("paint-solid"), + secondarySize ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/pick_fill", false) ); + g_object_set_data( holder, "pick_fill", act ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_pick_fill), holder) ; + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + } + + /* Pick Stroke */ + { + InkToggleAction* act = ink_toggle_action_new( "SprayPickStrokeAction", + _("Apply picked color to stroke"), + _("Apply picked color to stroke"), + INKSCAPE_ICON("no-marker"), + secondarySize ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/pick_stroke", false) ); + g_object_set_data( holder, "pick_stroke", act ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_pick_stroke), holder) ; + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + } + + /* Pick No Overlap */ + { + InkToggleAction* act = ink_toggle_action_new( "SprayPickNoOverlapAction", + _("No overlap between colors"), + _("No overlap between colors"), + INKSCAPE_ICON("symbol-bigger"), + secondarySize ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/pick_no_overlap", false) ); + g_object_set_data( holder, "pick_no_overlap", act ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_pick_no_overlap), holder) ; + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + } + + /* Over Transparent */ + { + InkToggleAction* act = ink_toggle_action_new( "SprayOverTransparentAction", + _("Apply over transparent areas"), + _("Apply over transparent areas"), + INKSCAPE_ICON("object-hidden"), + secondarySize ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/over_transparent", true) ); + g_object_set_data( holder, "over_transparent", act ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_over_transparent), holder) ; + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + } + + /* Over No Transparent */ + { + InkToggleAction* act = ink_toggle_action_new( "SprayOverNoTransparentAction", + _("Apply over no transparent areas"), + _("Apply over no transparent areas"), + INKSCAPE_ICON("object-visible"), + secondarySize ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/over_no_transparent", true) ); + g_object_set_data( holder, "over_no_transparent", act ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_over_no_transparent), holder) ; + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + } + + /* Overlap */ + { + InkToggleAction* act = ink_toggle_action_new( "SprayNoOverlapAction", + _("Prevent overlapping objects"), + _("Prevent overlapping objects"), + INKSCAPE_ICON("distribute-randomize"), + secondarySize ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/no_overlap", false) ); + g_object_set_data( holder, "no_overlap", act ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_no_overlap), holder) ; + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + } + + /* Offset */ + { + gchar const* labels[] = {_("(minimum offset)"), 0, 0, 0, _("(default)"), 0, 0, _("(maximum offset)")}; + gdouble values[] = {0, 25, 50, 75, 100, 150, 200, 1000}; + EgeAdjustmentAction *eact = create_adjustment_action( "SprayToolOffsetAction", + _("Offset %"), _("Offset %:"), + _("Increase to segregate objects more (value in percent)"), + "/tools/spray/offset", 100, + GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, + 0, 1000, 1, 4, + labels, values, G_N_ELEMENTS(labels), + sp_spray_offset_value_changed, NULL, 0 , 0); + g_object_set_data( holder, "offset", eact ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + } + sp_spray_init(holder); +} + + + +/* + 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:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/toolbar/spray-toolbar.h b/src/ui/toolbar/spray-toolbar.h new file mode 100644 index 000000000..30d8233ca --- /dev/null +++ b/src/ui/toolbar/spray-toolbar.h @@ -0,0 +1,37 @@ +#ifndef SEEN_SPRAY_TOOLBAR_H +#define SEEN_SPRAY_TOOLBAR_H + +/** + * @file + * Spray aux toolbar + */ +/* Authors: + * MenTaLguY + * Lauris Kaplinski + * bulia byak + * Frank Felfe + * John Cliff + * David Turner + * Josh Andler + * Jon A. Cruz + * Maximilian Albert + * Tavmjong Bah + * Abhishek Sharma + * Kris De Gussem + * + * Copyright (C) 2004 David Turner + * Copyright (C) 2003 MenTaLguY + * Copyright (C) 1999-2015 authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +class SPDesktop; + +typedef struct _GtkActionGroup GtkActionGroup; +typedef struct _GObject GObject; + +void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); + +#endif /* !SEEN_SELECT_TOOLBAR_H */ diff --git a/src/ui/toolbar/star-toolbar.cpp b/src/ui/toolbar/star-toolbar.cpp new file mode 100644 index 000000000..1c5745273 --- /dev/null +++ b/src/ui/toolbar/star-toolbar.cpp @@ -0,0 +1,626 @@ +/** + * @file + * Star aux toolbar + */ +/* Authors: + * MenTaLguY + * Lauris Kaplinski + * bulia byak + * Frank Felfe + * John Cliff + * David Turner + * Josh Andler + * Jon A. Cruz + * Maximilian Albert + * Tavmjong Bah + * Abhishek Sharma + * Kris De Gussem + * + * Copyright (C) 2004 David Turner + * Copyright (C) 2003 MenTaLguY + * Copyright (C) 1999-2011 authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include "star-toolbar.h" + +#include "desktop.h" +#include "document-undo.h" +#include "widgets/ink-action.h" +#include "widgets/toolbox.h" +#include "selection.h" +#include "verbs.h" + +#include "object/sp-star.h" + +#include "ui/icon-names.h" +#include "ui/tools/star-tool.h" +#include "ui/uxmanager.h" +#include "ui/widget/ink-select-one-action.h" + +#include "widgets/ege-adjustment-action.h" +#include "widgets/ege-output-action.h" + +#include "xml/node-event-vector.h" + +using Inkscape::UI::UXManager; +using Inkscape::DocumentUndo; +using Inkscape::UI::ToolboxFactory; +using Inkscape::UI::PrefPusher; + + +//######################## +//## Star ## +//######################## + +static void sp_star_magnitude_value_changed( GtkAdjustment *adj, GObject *dataKludge ) +{ + SPDesktop *desktop = static_cast(g_object_get_data( dataKludge, "desktop" )); + + if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { + // do not remember prefs if this call is initiated by an undo change, because undoing object + // creation sets bogus values to its attributes before it is deleted + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setInt("/tools/shapes/star/magnitude", + (gint)gtk_adjustment_get_value(adj)); + } + + // quit if run by the attr_changed listener + if (g_object_get_data( dataKludge, "freeze" )) { + return; + } + + // in turn, prevent listener from responding + g_object_set_data( dataKludge, "freeze", GINT_TO_POINTER(TRUE) ); + + bool modmade = false; + + Inkscape::Selection *selection = desktop->getSelection(); + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ + SPItem *item = *i; + if (SP_IS_STAR(item)) { + Inkscape::XML::Node *repr = item->getRepr(); + sp_repr_set_int(repr,"sodipodi:sides", + (gint)gtk_adjustment_get_value(adj)); + double arg1 = 0.5; + sp_repr_get_double(repr, "sodipodi:arg1", &arg1); + sp_repr_set_svg_double(repr, "sodipodi:arg2", + (arg1 + M_PI / (gint)gtk_adjustment_get_value(adj))); + item->updateRepr(); + modmade = true; + } + } + if (modmade) { + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_STAR, + _("Star: Change number of corners")); + } + + g_object_set_data( dataKludge, "freeze", GINT_TO_POINTER(FALSE) ); +} + +static void sp_star_proportion_value_changed( GtkAdjustment *adj, GObject *dataKludge ) +{ + SPDesktop *desktop = static_cast(g_object_get_data( dataKludge, "desktop" )); + + if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { + if (!IS_NAN(gtk_adjustment_get_value(adj))) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble("/tools/shapes/star/proportion", + gtk_adjustment_get_value(adj)); + } + } + + // quit if run by the attr_changed listener + if (g_object_get_data( dataKludge, "freeze" )) { + return; + } + + // in turn, prevent listener from responding + g_object_set_data( dataKludge, "freeze", GINT_TO_POINTER(TRUE) ); + + bool modmade = false; + Inkscape::Selection *selection = desktop->getSelection(); + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ + SPItem *item = *i; + if (SP_IS_STAR(item)) { + Inkscape::XML::Node *repr = item->getRepr(); + + gdouble r1 = 1.0; + gdouble r2 = 1.0; + sp_repr_get_double(repr, "sodipodi:r1", &r1); + sp_repr_get_double(repr, "sodipodi:r2", &r2); + if (r2 < r1) { + sp_repr_set_svg_double(repr, "sodipodi:r2", + r1*gtk_adjustment_get_value(adj)); + } else { + sp_repr_set_svg_double(repr, "sodipodi:r1", + r2*gtk_adjustment_get_value(adj)); + } + + item->updateRepr(); + modmade = true; + } + } + + if (modmade) { + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_STAR, + _("Star: Change spoke ratio")); + } + + g_object_set_data( dataKludge, "freeze", GINT_TO_POINTER(FALSE) ); +} + +static void sp_star_side_mode_changed( GObject *dataKludge, int mode ) +{ + bool flat = (mode == 0); + + SPDesktop *desktop = static_cast(g_object_get_data( dataKludge, "desktop" )); + + if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setBool( "/tools/shapes/star/isflatsided", flat ); + } + + // quit if run by the attr_changed listener + if (g_object_get_data( dataKludge, "freeze" )) { + return; + } + + // in turn, prevent listener from responding + g_object_set_data( dataKludge, "freeze", GINT_TO_POINTER(TRUE) ); + + Inkscape::Selection *selection = desktop->getSelection(); + GtkAction* prop_action = GTK_ACTION( g_object_get_data( dataKludge, "prop_action" ) ); + bool modmade = false; + + if ( prop_action ) { + gtk_action_set_visible( prop_action, !flat ); + } + + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ + SPItem *item = *i; + if (SP_IS_STAR(item)) { + Inkscape::XML::Node *repr = item->getRepr(); + repr->setAttribute("inkscape:flatsided", flat ? "true" : "false" ); + item->updateRepr(); + modmade = true; + } + } + + if (modmade) { + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_STAR, + flat ? _("Make polygon") : _("Make star")); + } + + g_object_set_data( dataKludge, "freeze", GINT_TO_POINTER(FALSE) ); +} + +static void sp_star_rounded_value_changed( GtkAdjustment *adj, GObject *dataKludge ) +{ + SPDesktop *desktop = static_cast(g_object_get_data( dataKludge, "desktop" )); + + if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble("/tools/shapes/star/rounded", (gdouble) gtk_adjustment_get_value(adj)); + } + + // quit if run by the attr_changed listener + if (g_object_get_data( dataKludge, "freeze" )) { + return; + } + + // in turn, prevent listener from responding + g_object_set_data( dataKludge, "freeze", GINT_TO_POINTER(TRUE) ); + + bool modmade = false; + + Inkscape::Selection *selection = desktop->getSelection(); + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ + SPItem *item = *i; + if (SP_IS_STAR(item)) { + Inkscape::XML::Node *repr = item->getRepr(); + sp_repr_set_svg_double(repr, "inkscape:rounded", + (gdouble) gtk_adjustment_get_value(adj)); + item->updateRepr(); + modmade = true; + } + } + if (modmade) { + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_STAR, + _("Star: Change rounding")); + } + + g_object_set_data( dataKludge, "freeze", GINT_TO_POINTER(FALSE) ); +} + +static void sp_star_randomized_value_changed( GtkAdjustment *adj, GObject *dataKludge ) +{ + SPDesktop *desktop = static_cast(g_object_get_data( dataKludge, "desktop" )); + + if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble("/tools/shapes/star/randomized", + (gdouble) gtk_adjustment_get_value(adj)); + } + + // quit if run by the attr_changed listener + if (g_object_get_data( dataKludge, "freeze" )) { + return; + } + + // in turn, prevent listener from responding + g_object_set_data( dataKludge, "freeze", GINT_TO_POINTER(TRUE) ); + + bool modmade = false; + + Inkscape::Selection *selection = desktop->getSelection(); + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ + SPItem *item = *i; + if (SP_IS_STAR(item)) { + Inkscape::XML::Node *repr = item->getRepr(); + sp_repr_set_svg_double(repr, "inkscape:randomized", + (gdouble) gtk_adjustment_get_value(adj)); + item->updateRepr(); + modmade = true; + } + } + if (modmade) { + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_STAR, + _("Star: Change randomization")); + } + + g_object_set_data( dataKludge, "freeze", GINT_TO_POINTER(FALSE) ); +} + + +static void star_tb_event_attr_changed(Inkscape::XML::Node *repr, gchar const *name, + gchar const * /*old_value*/, gchar const * /*new_value*/, + bool /*is_interactive*/, gpointer dataPointer) +{ + GObject *dataKludge = G_OBJECT( dataPointer ); + + // quit if run by the _changed callbacks + if (g_object_get_data(dataKludge, "freeze")) { + return; + } + + // in turn, prevent callbacks from responding + g_object_set_data(dataKludge, "freeze", GINT_TO_POINTER(TRUE)); + + GtkAdjustment *adj = 0; + + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + bool isFlatSided = prefs->getBool("/tools/shapes/star/isflatsided", true); + + if (!strcmp(name, "inkscape:randomized")) { + + adj = GTK_ADJUSTMENT( g_object_get_data(dataKludge, "randomized") ); + double randomized = 0.0; + sp_repr_get_double(repr, "inkscape:randomized", &randomized); + gtk_adjustment_set_value(adj, randomized); + + } else if (!strcmp(name, "inkscape:rounded")) { + + adj = GTK_ADJUSTMENT( g_object_get_data(dataKludge, "rounded") ); + double rounded = 0.0; + sp_repr_get_double(repr, "inkscape:rounded", &rounded); + gtk_adjustment_set_value(adj, rounded); + + } else if (!strcmp(name, "inkscape:flatsided")) { + + GtkAction* prop_action = GTK_ACTION( g_object_get_data(dataKludge, "prop_action") ); + char const *flatsides = repr->attribute("inkscape:flatsided"); + + InkSelectOneAction* flat_action = + static_cast(g_object_get_data( dataKludge, "flat_action" ) ); + if ( flatsides && !strcmp(flatsides,"false") ) { + flat_action->set_active(1); + gtk_action_set_visible( prop_action, TRUE ); + } else { + flat_action->set_active(0); + gtk_action_set_visible( prop_action, FALSE ); + } + + } else if ((!strcmp(name, "sodipodi:r1") || !strcmp(name, "sodipodi:r2")) && (!isFlatSided) ) { + + adj = GTK_ADJUSTMENT(g_object_get_data(dataKludge, "proportion")); + gdouble r1 = 1.0; + gdouble r2 = 1.0; + sp_repr_get_double(repr, "sodipodi:r1", &r1); + sp_repr_get_double(repr, "sodipodi:r2", &r2); + if (r2 < r1) { + gtk_adjustment_set_value(adj, r2/r1); + } else { + gtk_adjustment_set_value(adj, r1/r2); + } + + } else if (!strcmp(name, "sodipodi:sides")) { + + adj = GTK_ADJUSTMENT(g_object_get_data(dataKludge, "magnitude")); + int sides = 0; + sp_repr_get_int(repr, "sodipodi:sides", &sides); + gtk_adjustment_set_value(adj, sides); + } + + g_object_set_data(dataKludge, "freeze", GINT_TO_POINTER(FALSE)); +} + + +static Inkscape::XML::NodeEventVector star_tb_repr_events = +{ + NULL, /* child_added */ + NULL, /* child_removed */ + star_tb_event_attr_changed, + NULL, /* content_changed */ + NULL /* order_changed */ +}; + + +/** + * \param selection Should not be NULL. + */ +static void +sp_star_toolbox_selection_changed(Inkscape::Selection *selection, GObject *dataKludge) +{ + int n_selected = 0; + Inkscape::XML::Node *repr = NULL; + + purge_repr_listener( dataKludge, dataKludge ); + + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ + SPItem *item = *i; + if (SP_IS_STAR(item)) { + n_selected++; + repr = item->getRepr(); + } + } + + EgeOutputAction* act = EGE_OUTPUT_ACTION( g_object_get_data( dataKludge, "mode_action" ) ); + + if (n_selected == 0) { + g_object_set( G_OBJECT(act), "label", _("New:"), NULL ); + } else if (n_selected == 1) { + g_object_set( G_OBJECT(act), "label", _("Change:"), NULL ); + + if (repr) { + g_object_set_data( dataKludge, "repr", repr ); + Inkscape::GC::anchor(repr); + sp_repr_add_listener(repr, &star_tb_repr_events, dataKludge); + sp_repr_synthesize_events(repr, &star_tb_repr_events, dataKludge); + } + } else { + // FIXME: implement averaging of all parameters for multiple selected stars + //gtk_label_set_markup(GTK_LABEL(l), _("Average:")); + //gtk_label_set_markup(GTK_LABEL(l), _("Change:")); + } +} + + +static void sp_star_defaults( GtkWidget * /*widget*/, GObject *dataKludge ) +{ + // FIXME: in this and all other _default functions, set some flag telling the value_changed + // callbacks to lump all the changes for all selected objects in one undo step + + GtkAdjustment *adj = 0; + + // fixme: make settable in prefs! + gint mag = 5; + gdouble prop = 0.5; + gboolean flat = FALSE; + gdouble randomized = 0; + gdouble rounded = 0; + + InkSelectOneAction* flat_action = + static_cast(g_object_get_data( dataKludge, "flat_action" ) ); + flat_action->set_active ( flat ? 0 : 1 ); + + GtkAction* sb2 = GTK_ACTION( g_object_get_data( dataKludge, "prop_action" ) ); + gtk_action_set_visible( sb2, !flat ); + + adj = GTK_ADJUSTMENT( g_object_get_data( dataKludge, "magnitude" ) ); + gtk_adjustment_set_value(adj, mag); + +#if !GTK_CHECK_VERSION(3,18,0) + gtk_adjustment_value_changed(adj); +#endif + + adj = GTK_ADJUSTMENT( g_object_get_data( dataKludge, "proportion" ) ); + gtk_adjustment_set_value(adj, prop); + +#if !GTK_CHECK_VERSION(3,18,0) + gtk_adjustment_value_changed(adj); +#endif + + adj = GTK_ADJUSTMENT( g_object_get_data( dataKludge, "rounded" ) ); + gtk_adjustment_set_value(adj, rounded); + +#if !GTK_CHECK_VERSION(3,18,0) + gtk_adjustment_value_changed(adj); +#endif + + adj = GTK_ADJUSTMENT( g_object_get_data( dataKludge, "randomized" ) ); + gtk_adjustment_set_value(adj, randomized); + +#if !GTK_CHECK_VERSION(3,18,0) + gtk_adjustment_value_changed(adj); +#endif +} + +static void star_toolbox_watch_ec(SPDesktop* dt, Inkscape::UI::Tools::ToolBase* ec, GObject* dataKludge); + +void sp_star_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* dataKludge) +{ + GtkIconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1); + + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + bool isFlatSided = prefs->getBool("/tools/shapes/star/isflatsided", true); + + EgeAdjustmentAction* eact = 0; + + { + EgeOutputAction* act = ege_output_action_new( "StarStateAction", _("New:"), "", 0 ); + ege_output_action_set_use_markup( act, TRUE ); + gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); + g_object_set_data( dataKludge, "mode_action", act ); + } + + /* Flatsided checkbox */ + { + InkSelectOneActionColumns columns; + + Glib::RefPtr store = Gtk::ListStore::create(columns); + + Gtk::TreeModel::Row row; + + row = *(store->append()); + row[columns.col_label ] = _("Polygon"); + row[columns.col_tooltip ] = _("Regular polygon (with one handle) instead of a star"); + row[columns.col_icon ] = INKSCAPE_ICON("draw-polygon"); + row[columns.col_sensitive] = true; + + row = *(store->append()); + row[columns.col_label ] = _("Star"); + row[columns.col_tooltip ] = _("Star instead of a regular polygon (with one handle)"); + row[columns.col_icon ] = INKSCAPE_ICON("draw-star"); + row[columns.col_sensitive] = true; + + InkSelectOneAction* act = + InkSelectOneAction::create( "FlatAction", // Name + (""), // Label + (""), // Tooltip + "Not Used", // Icon + store ); // Tree store + act->use_radio( true ); + act->use_label( false ); + act->set_active( isFlatSided ? 0 : 1 ); + + gtk_action_group_add_action( mainActions, GTK_ACTION( act->gobj() )); + g_object_set_data( dataKludge, "flat_action", act ); + + act->signal_changed().connect(sigc::bind<0>(sigc::ptr_fun(&sp_star_side_mode_changed), dataKludge)); + } + + /* Magnitude */ + { + gchar const* labels[] = {_("triangle/tri-star"), _("square/quad-star"), _("pentagon/five-pointed star"), _("hexagon/six-pointed star"), 0, 0, 0, 0, 0}; + gdouble values[] = {3, 4, 5, 6, 7, 8, 10, 12, 20}; + eact = create_adjustment_action( "MagnitudeAction", + _("Corners"), _("Corners:"), _("Number of corners of a polygon or star"), + "/tools/shapes/star/magnitude", 3, + GTK_WIDGET(desktop->canvas), dataKludge, FALSE, NULL, + 3, 1024, 1, 5, + labels, values, G_N_ELEMENTS(labels), + sp_star_magnitude_value_changed, NULL /*unit tracker*/, + 1.0, 0 ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); + } + + /* Spoke ratio */ + { + gchar const* labels[] = {_("thin-ray star"), 0, _("pentagram"), _("hexagram"), _("heptagram"), _("octagram"), _("regular polygon")}; + gdouble values[] = {0.01, 0.2, 0.382, 0.577, 0.692, 0.765, 1}; + eact = create_adjustment_action( "SpokeAction", + _("Spoke ratio"), _("Spoke ratio:"), + // TRANSLATORS: Tip radius of a star is the distance from the center to the farthest handle. + // Base radius is the same for the closest handle. + _("Base radius to tip radius ratio"), + "/tools/shapes/star/proportion", 0.5, + GTK_WIDGET(desktop->canvas), dataKludge, FALSE, NULL, + 0.01, 1.0, 0.01, 0.1, + labels, values, G_N_ELEMENTS(labels), + sp_star_proportion_value_changed ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + g_object_set_data( dataKludge, "prop_action", eact ); + + if ( !isFlatSided ) { + gtk_action_set_visible( GTK_ACTION(eact), TRUE ); + } else { + gtk_action_set_visible( GTK_ACTION(eact), FALSE ); + } + } + + /* Roundedness */ + { + gchar const* labels[] = {_("stretched"), _("twisted"), _("slightly pinched"), _("NOT rounded"), _("slightly rounded"), + _("visibly rounded"), _("well rounded"), _("amply rounded"), 0, _("stretched"), _("blown up")}; + gdouble values[] = {-1, -0.2, -0.03, 0, 0.05, 0.1, 0.2, 0.3, 0.5, 1, 10}; + eact = create_adjustment_action( "RoundednessAction", + _("Rounded"), _("Rounded:"), _("How much rounded are the corners (0 for sharp)"), + "/tools/shapes/star/rounded", 0.0, + GTK_WIDGET(desktop->canvas), dataKludge, FALSE, NULL, + -10.0, 10.0, 0.01, 0.1, + labels, values, G_N_ELEMENTS(labels), + sp_star_rounded_value_changed ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); + } + + /* Randomization */ + { + gchar const* labels[] = {_("NOT randomized"), _("slightly irregular"), _("visibly randomized"), _("strongly randomized"), _("blown up")}; + gdouble values[] = {0, 0.01, 0.1, 0.5, 10}; + eact = create_adjustment_action( "RandomizationAction", + _("Randomized"), _("Randomized:"), _("Scatter randomly the corners and angles"), + "/tools/shapes/star/randomized", 0.0, + GTK_WIDGET(desktop->canvas), dataKludge, FALSE, NULL, + -10.0, 10.0, 0.001, 0.01, + labels, values, G_N_ELEMENTS(labels), + sp_star_randomized_value_changed, NULL /*unit tracker*/, 0.1, 3 ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); + } + + /* Reset */ + { + InkAction* inky = ink_action_new( "StarResetAction", + _("Defaults"), + _("Reset shape parameters to defaults (use Inkscape Preferences > Tools to change defaults)"), + INKSCAPE_ICON("edit-clear"), + GTK_ICON_SIZE_SMALL_TOOLBAR); + g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_star_defaults), dataKludge ); + gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); + gtk_action_set_sensitive( GTK_ACTION(inky), TRUE ); + } + + desktop->connectEventContextChanged(sigc::bind(sigc::ptr_fun(star_toolbox_watch_ec), dataKludge)); + g_signal_connect(dataKludge, "destroy", G_CALLBACK(purge_repr_listener), dataKludge); +} + +static void star_toolbox_watch_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolBase* ec, GObject* dataKludge) +{ + static sigc::connection changed; + + if (dynamic_cast(ec) != NULL) { + changed = desktop->getSelection()->connectChanged(sigc::bind(sigc::ptr_fun(sp_star_toolbox_selection_changed), dataKludge)); + sp_star_toolbox_selection_changed(desktop->getSelection(), dataKludge); + } else { + if (changed) + changed.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:fileencoding=utf-8 : diff --git a/src/ui/toolbar/star-toolbar.h b/src/ui/toolbar/star-toolbar.h new file mode 100644 index 000000000..aa0db785c --- /dev/null +++ b/src/ui/toolbar/star-toolbar.h @@ -0,0 +1,37 @@ +#ifndef SEEN_STAR_TOOLBAR_H +#define SEEN_STAR_TOOLBAR_H + +/** + * @file + * Star aux toolbar + */ +/* Authors: + * MenTaLguY + * Lauris Kaplinski + * bulia byak + * Frank Felfe + * John Cliff + * David Turner + * Josh Andler + * Jon A. Cruz + * Maximilian Albert + * Tavmjong Bah + * Abhishek Sharma + * Kris De Gussem + * + * Copyright (C) 2004 David Turner + * Copyright (C) 2003 MenTaLguY + * Copyright (C) 1999-2011 authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +class SPDesktop; + +typedef struct _GtkActionGroup GtkActionGroup; +typedef struct _GObject GObject; + +void sp_star_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); + +#endif /* !SEEN_SELECT_TOOLBAR_H */ diff --git a/src/ui/toolbar/text-toolbar.cpp b/src/ui/toolbar/text-toolbar.cpp new file mode 100644 index 000000000..4f532fa3d --- /dev/null +++ b/src/ui/toolbar/text-toolbar.cpp @@ -0,0 +1,2603 @@ +/** + * @file + * Text aux toolbar + */ +/* Authors: + * MenTaLguY + * Lauris Kaplinski + * bulia byak + * Frank Felfe + * John Cliff + * David Turner + * Josh Andler + * Jon A. Cruz + * Maximilian Albert + * Tavmjong Bah + * Abhishek Sharma + * Kris De Gussem + * Tavmjong Bah + * + * Copyright (C) 2004 David Turner + * Copyright (C) 2003 MenTaLguY + * Copyright (C) 2001-2002 Ximian, Inc. + * Copyright (C) 1999-2013 authors + * Copyright (C) 2017 Tavmjong Bah + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include "text-toolbar.h" + +#include "desktop-style.h" +#include "desktop.h" +#include "document-undo.h" +#include "document.h" +#include "widgets/ink-toggle-action.h" +#include "widgets/toolbox.h" +#include "inkscape.h" +#include "selection-chemistry.h" +#include "text-editing.h" +#include "verbs.h" + +#include "libnrtype/font-lister.h" + +#include "object/sp-flowdiv.h" +#include "object/sp-flowtext.h" +#include "object/sp-root.h" +#include "object/sp-text.h" +#include "object/sp-tspan.h" +#include "style.h" + +#include "svg/css-ostringstream.h" + +#include "ui/icon-names.h" +#include "ui/tools/text-tool.h" +#include "ui/widget/ink-select-one-action.h" +#include "ui/widget/unit-tracker.h" + +#include "widgets/ege-adjustment-action.h" +#include "widgets/ink-comboboxentry-action.h" +#include "widgets/style-utils.h" + +using Inkscape::DocumentUndo; +using Inkscape::UI::ToolboxFactory; +using Inkscape::UI::PrefPusher; +using Inkscape::Util::Unit; +using Inkscape::Util::Quantity; +using Inkscape::Util::unit_table; +using Inkscape::UI::Widget::UnitTracker; + +//#define DEBUG_TEXT + +//######################## +//## Text Toolbox ## +//######################## + +// Functions for debugging: +#ifdef DEBUG_TEXT + +static void sp_print_font( SPStyle *query ) { + + bool family_set = query->font_family.set; + bool style_set = query->font_style.set; + bool fontspec_set = query->font_specification.set; + + std::cout << " Family set? " << family_set + << " Style set? " << style_set + << " FontSpec set? " << fontspec_set + << std::endl; + std::cout << " Family: " + << (query->font_family.value ? query->font_family.value : "No value") + << " Style: " << query->font_style.computed + << " Weight: " << query->font_weight.computed + << " FontSpec: " + << (query->font_specification.value ? query->font_specification.value : "No value") + << std::endl; + std::cout << " LineHeight: " << query->line_height.computed + << " WordSpacing: " << query->word_spacing.computed + << " LetterSpacing: " << query->letter_spacing.computed + << std::endl; +} + +static void sp_print_fontweight( SPStyle *query ) { + const gchar* names[] = {"100", "200", "300", "400", "500", "600", "700", "800", "900", + "NORMAL", "BOLD", "LIGHTER", "BOLDER", "Out of range"}; + // Missing book = 380 + int index = query->font_weight.computed; + if( index < 0 || index > 13 ) index = 13; + std::cout << " Weight: " << names[ index ] + << " (" << query->font_weight.computed << ")" << std::endl; + +} + +static void sp_print_fontstyle( SPStyle *query ) { + + const gchar* names[] = {"NORMAL", "ITALIC", "OBLIQUE", "Out of range"}; + int index = query->font_style.computed; + if( index < 0 || index > 3 ) index = 3; + std::cout << " Style: " << names[ index ] << std::endl; + +} +#endif + +static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/, GObject *tbl, bool subselection = false); + +// Font family +static void sp_text_fontfamily_value_changed( Ink_ComboBoxEntry_Action *act, GObject *tbl ) +{ +#ifdef DEBUG_TEXT + std::cout << std::endl; + std::cout << "MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" << std::endl; + std::cout << "sp_text_fontfamily_value_changed: " << std::endl; +#endif + + // quit if run by the _changed callbacks + if (g_object_get_data(G_OBJECT(tbl), "freeze")) { +#ifdef DEBUG_TEXT + std::cout << "sp_text_fontfamily_value_changed: frozen... return" << std::endl; + std::cout << "MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM\n" << std::endl; +#endif + return; + } + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); + + Glib::ustring new_family = ink_comboboxentry_action_get_active_text( act ); + css_font_family_unquote( new_family ); // Remove quotes around font family names. + + // TODO: Think about how to handle handle multiple selections. While + // the font-family may be the same for all, the styles might be different. + // See: TextEdit::onApply() for example of looping over selected items. + Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance(); +#ifdef DEBUG_TEXT + std::cout << " Old family: " << fontlister->get_font_family() << std::endl; + std::cout << " New family: " << new_family << std::endl; + std::cout << " Old active: " << fontlister->get_font_family_row() << std::endl; + std::cout << " New active: " << act->active << std::endl; +#endif + if( new_family.compare( fontlister->get_font_family() ) != 0 ) { + // Changed font-family + + if( act->active == -1 ) { + // New font-family, not in document, not on system (could be fallback list) + fontlister->insert_font_family( new_family ); + act->active = 0; // New family is always at top of list. + } + + fontlister->set_font_family( act->active ); + // active text set in sp_text_toolbox_selection_changed() + + SPCSSAttr *css = sp_repr_css_attr_new (); + fontlister->fill_css( css ); + + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if( desktop->getSelection()->isEmpty() ) { + // Update default + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->mergeStyle("/tools/text/style", css); + } else { + // If there is a selection, update + sp_desktop_set_style (desktop, css, true, true); // Results in selection change called twice. + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_TEXT, + _("Text: Change font family")); + } + sp_repr_css_attr_unref (css); + } + + // unfreeze + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); + +#ifdef DEBUG_TEXT + std::cout << "sp_text_toolbox_fontfamily_changes: exit" << std::endl; + std::cout << "MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" << std::endl; + std::cout << std::endl; +#endif +} + +// Font size +static void sp_text_fontsize_value_changed( Ink_ComboBoxEntry_Action *act, GObject *tbl ) +{ + // quit if run by the _changed callbacks + if (g_object_get_data(G_OBJECT(tbl), "freeze")) { + return; + } + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); + + gchar *text = ink_comboboxentry_action_get_active_text( act ); + gchar *endptr; + gdouble size = g_strtod( text, &endptr ); + if (endptr == text) { // Conversion failed, non-numeric input. + g_warning( "Conversion of size text to double failed, input: %s\n", text ); + g_free( text ); + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); + return; + } + g_free( text ); + + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + int max_size = prefs->getInt("/dialogs/textandfont/maxFontSize", 10000); // somewhat arbitrary, but text&font preview freezes with too huge fontsizes + + if (size > max_size) + size = max_size; + + // Set css font size. + SPCSSAttr *css = sp_repr_css_attr_new (); + Inkscape::CSSOStringStream osfs; + int unit = prefs->getInt("/options/font/unitType", SP_CSS_UNIT_PT); + if (prefs->getBool("/options/font/textOutputPx", true)) { + osfs << sp_style_css_size_units_to_px(size, unit) << sp_style_get_css_unit_string(SP_CSS_UNIT_PX); + } else { + osfs << size << sp_style_get_css_unit_string(unit); + } + sp_repr_css_set_property (css, "font-size", osfs.str().c_str()); + + // Apply font size to selected objects. + // Calling sp_desktop_set_style will result in a call to TextTool::_styleSet() which + // will set the style on selected text inside the element. If we want to set + // the style on the outer objects we need to bypass this call. + bool outer = prefs->getInt("/tools/text/outer_style", false); + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if (outer) { + Inkscape::Selection *selection = desktop->getSelection(); + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end(); ++i){ + if (dynamic_cast(*i) || dynamic_cast(*i)) { + SPItem *item = *i; + + // Scale by inverse of accumulated parent transform + SPCSSAttr *css_set = sp_repr_css_attr_new(); + sp_repr_css_merge(css_set, css); + Geom::Affine const local(item->i2doc_affine()); + double const ex(local.descrim()); + if ( (ex != 0.0) && (ex != 1.0) ) { + sp_css_attr_scale(css_set, 1/ex); + } + + item->changeCSS(css_set,"style"); + + sp_repr_css_attr_unref(css_set); + } + } + } else { + sp_desktop_set_style (desktop, css, true, true); + } + + // If no selected objects, set default. + SPStyle query(SP_ACTIVE_DOCUMENT); + int result_numbers = + sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS); + if (result_numbers == QUERY_STYLE_NOTHING) + { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->mergeStyle("/tools/text/style", css); + } else { + // Save for undo + DocumentUndo::maybeDone(SP_ACTIVE_DESKTOP->getDocument(), "ttb:size", SP_VERB_NONE, + _("Text: Change font size")); + } + + sp_repr_css_attr_unref (css); + + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); +} + +/* + * Font style + */ +static void sp_text_fontstyle_value_changed( Ink_ComboBoxEntry_Action *act, GObject *tbl ) +{ + // quit if run by the _changed callbacks + if (g_object_get_data(G_OBJECT(tbl), "freeze")) { + return; + } + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); + + Glib::ustring new_style = ink_comboboxentry_action_get_active_text( act ); + + Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance(); + + if( new_style.compare( fontlister->get_font_style() ) != 0 ) { + + fontlister->set_font_style( new_style ); + // active text set in sp_text_toolbox_seletion_changed() + + SPCSSAttr *css = sp_repr_css_attr_new (); + fontlister->fill_css( css ); + + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + sp_desktop_set_style (desktop, css, true, true); + + + // If no selected objects, set default. + SPStyle query(SP_ACTIVE_DOCUMENT); + int result_style = + sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTSTYLE); + if (result_style == QUERY_STYLE_NOTHING) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->mergeStyle("/tools/text/style", css); + } else { + // Save for undo + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_TEXT, + _("Text: Change font style")); + } + + sp_repr_css_attr_unref (css); + + } + + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); +} + +// Changes selection to only text outer elements. +static void sp_text_outer_style_changed( InkToggleAction*act, GObject *tbl ) +{ + bool outer = gtk_toggle_action_get_active( GTK_TOGGLE_ACTION(act) ); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setInt("/tools/text/outer_style", outer); + + // Update widgets to reflect new state of Text Outer Style button. + sp_text_toolbox_selection_changed( NULL, tbl ); +} + +// Unset line height on selection's inner text objects (tspan, etc.). +static void sp_text_lineheight_unset_changed( InkToggleAction*act, GObject *tbl ) +{ + // quit if run by the _changed callbacks + if (g_object_get_data(G_OBJECT(tbl), "freeze")) { + return; + } + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); + + SPCSSAttr *css = sp_repr_css_attr_new(); + sp_repr_css_unset_property(css, "line-height"); + + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + sp_desktop_set_style (desktop, css); + + sp_repr_css_attr_unref(css); + + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_TEXT, + _("Text: Unset line height.")); + + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); +} + +// Handles both Superscripts and Subscripts +static void sp_text_script_changed( InkToggleAction* act, GObject *tbl ) +{ + // quit if run by the _changed callbacks + if (g_object_get_data(G_OBJECT(tbl), "freeze")) { + return; + } + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); + + // Called by Superscript or Subscript button? + const gchar* name = gtk_action_get_name( GTK_ACTION( act ) ); + gint prop = (strcmp(name, "TextSuperscriptAction") == 0) ? 0 : 1; + +#ifdef DEBUG_TEXT + std::cout << "sp_text_script_changed: " << prop << std::endl; +#endif + + // Query baseline + SPStyle query(SP_ACTIVE_DOCUMENT); + int result_baseline = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_BASELINES); + + bool setSuper = false; + bool setSub = false; + + if (Inkscape::is_query_style_updateable(result_baseline)) { + // If not set or mixed, turn on superscript or subscript + if( prop == 0 ) { + setSuper = true; + } else { + setSub = true; + } + } else { + // Superscript + gboolean superscriptSet = (query.baseline_shift.set && + query.baseline_shift.type == SP_BASELINE_SHIFT_LITERAL && + query.baseline_shift.literal == SP_CSS_BASELINE_SHIFT_SUPER ); + + // Subscript + gboolean subscriptSet = (query.baseline_shift.set && + query.baseline_shift.type == SP_BASELINE_SHIFT_LITERAL && + query.baseline_shift.literal == SP_CSS_BASELINE_SHIFT_SUB ); + + setSuper = !superscriptSet && prop == 0; + setSub = !subscriptSet && prop == 1; + } + + // Set css properties + SPCSSAttr *css = sp_repr_css_attr_new (); + if( setSuper || setSub ) { + // Openoffice 2.3 and Adobe use 58%, Microsoft Word 2002 uses 65%, LaTex about 70%. + // 58% looks too small to me, especially if a superscript is placed on a superscript. + // If you make a change here, consider making a change to baseline-shift amount + // in style.cpp. + sp_repr_css_set_property (css, "font-size", "65%"); + } else { + sp_repr_css_set_property (css, "font-size", ""); + } + if( setSuper ) { + sp_repr_css_set_property (css, "baseline-shift", "super"); + } else if( setSub ) { + sp_repr_css_set_property (css, "baseline-shift", "sub"); + } else { + sp_repr_css_set_property (css, "baseline-shift", "baseline"); + } + + // Apply css to selected objects. + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + sp_desktop_set_style (desktop, css, true, false); + + // Save for undo + if(result_baseline != QUERY_STYLE_NOTHING) { + DocumentUndo::maybeDone(SP_ACTIVE_DESKTOP->getDocument(), "ttb:script", SP_VERB_NONE, + _("Text: Change superscript or subscript")); + } + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); +} + +static void sp_text_align_mode_changed( GObject *tbl, int mode ) +{ + // quit if run by the _changed callbacks + if (g_object_get_data(G_OBJECT(tbl), "freeze")) { + return; + } + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); + + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setInt("/tools/text/align_mode", mode); + + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + + // move the x of all texts to preserve the same bbox + Inkscape::Selection *selection = desktop->getSelection(); + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end(); ++i){ + if (SP_IS_TEXT(*i)) { + SPItem *item = *i; + + unsigned writing_mode = item->style->writing_mode.value; + // below, variable names suggest horizontal move, but we check the writing direction + // and move in the corresponding axis + Geom::Dim2 axis; + if (writing_mode == SP_CSS_WRITING_MODE_LR_TB || writing_mode == SP_CSS_WRITING_MODE_RL_TB) { + axis = Geom::X; + } else { + axis = Geom::Y; + } + + Geom::OptRect bbox = item->geometricBounds(); + if (!bbox) + continue; + double width = bbox->dimensions()[axis]; + // If you want to align within some frame, other than the text's own bbox, calculate + // the left and right (or top and bottom for tb text) slacks of the text inside that + // frame (currently unused) + double left_slack = 0; + double right_slack = 0; + unsigned old_align = item->style->text_align.value; + double move = 0; + if (old_align == SP_CSS_TEXT_ALIGN_START || old_align == SP_CSS_TEXT_ALIGN_LEFT) { + switch (mode) { + case 0: + move = -left_slack; + break; + case 1: + move = width/2 + (right_slack - left_slack)/2; + break; + case 2: + move = width + right_slack; + break; + } + } else if (old_align == SP_CSS_TEXT_ALIGN_CENTER) { + switch (mode) { + case 0: + move = -width/2 - left_slack; + break; + case 1: + move = (right_slack - left_slack)/2; + break; + case 2: + move = width/2 + right_slack; + break; + } + } else if (old_align == SP_CSS_TEXT_ALIGN_END || old_align == SP_CSS_TEXT_ALIGN_RIGHT) { + switch (mode) { + case 0: + move = -width - left_slack; + break; + case 1: + move = -width/2 + (right_slack - left_slack)/2; + break; + case 2: + move = right_slack; + break; + } + } + Geom::Point XY = SP_TEXT(item)->attributes.firstXY(); + if (axis == Geom::X) { + XY = XY + Geom::Point (move, 0); + } else { + XY = XY + Geom::Point (0, move); + } + SP_TEXT(item)->attributes.setFirstXY(XY); + item->updateRepr(); + item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + } + } + + SPCSSAttr *css = sp_repr_css_attr_new (); + switch (mode) + { + case 0: + { + sp_repr_css_set_property (css, "text-anchor", "start"); + sp_repr_css_set_property (css, "text-align", "start"); + break; + } + case 1: + { + sp_repr_css_set_property (css, "text-anchor", "middle"); + sp_repr_css_set_property (css, "text-align", "center"); + break; + } + + case 2: + { + sp_repr_css_set_property (css, "text-anchor", "end"); + sp_repr_css_set_property (css, "text-align", "end"); + break; + } + + case 3: + { + sp_repr_css_set_property (css, "text-anchor", "start"); + sp_repr_css_set_property (css, "text-align", "justify"); + break; + } + } + + SPStyle query(SP_ACTIVE_DOCUMENT); + int result_numbers = + sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS); + + // If querying returned nothing, update default style. + if (result_numbers == QUERY_STYLE_NOTHING) + { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->mergeStyle("/tools/text/style", css); + } + + sp_desktop_set_style (desktop, css, true, true); + if (result_numbers != QUERY_STYLE_NOTHING) + { + DocumentUndo::done(SP_ACTIVE_DESKTOP->getDocument(), SP_VERB_CONTEXT_TEXT, + _("Text: Change alignment")); + } + sp_repr_css_attr_unref (css); + + gtk_widget_grab_focus (GTK_WIDGET(SP_ACTIVE_DESKTOP->canvas)); + + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); +} + +static bool is_relative( Unit const *unit ) { + return (unit->abbr == "" || unit->abbr == "em" || unit->abbr == "ex" || unit->abbr == "%"); +} + +// Set property for object, but unset all descendents +// Should probably be moved to desktop_style.cpp +static void recursively_set_properties( SPObject* object, SPCSSAttr *css ) { + object->changeCSS (css, "style"); + + SPCSSAttr *css_unset = sp_repr_css_attr_unset_all( css ); + std::vector children = object->childList(false); + for (auto i: children) { + recursively_set_properties (i, css_unset); + } + sp_repr_css_attr_unref (css_unset); +} + +// Apply line height changes (line-height value changed or line-height unit changed) +static void set_lineheight (SPCSSAttr *css) { + + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + bool outer = prefs->getInt("/tools/text/outer_style", false); + gint mode = prefs->getInt("/tools/text/line_spacing_mode", 0); + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + + // Calling sp_desktop_set_style will result in a call to TextTool::_styleSet() which + // will set the style on selected text inside the element. If we want to set + // the style on the outer objects we need to bypass this call. + if ( mode == 3 && !outer ) { + // This will call sp_te_apply_style via signal + sp_desktop_set_style (desktop, css, true, true); + } else { + Inkscape::Selection *selection = desktop->getSelection(); + auto itemlist= selection->items(); + for (auto i: itemlist) { + + if (dynamic_cast(i) || dynamic_cast(i)) { + SPItem *item = i; + + // Scale by inverse of accumulated parent transform + SPCSSAttr *css_set = sp_repr_css_attr_new(); + sp_repr_css_merge(css_set, css); + Geom::Affine const local(item->i2doc_affine()); + double const ex(local.descrim()); + if ( (ex != 0.0) && (ex != 1.0) ) { + sp_css_attr_scale(css_set, 1/ex); + } + + if ( mode == 1 || mode == 2 || mode == 3) { // Minimum, Even, or Adjustable w/ outer. + // We change only outer style + item->changeCSS(css_set,"style"); + } else { + // We change only inner style (Adaptive). + for (auto child: item->childList(false)) { + child->changeCSS(css_set,"style"); + } + } + } + } + } +} + +static void sp_text_lineheight_value_changed( GtkAdjustment *adj, GObject *tbl ) +{ + // quit if run by the _changed callbacks + if (g_object_get_data(G_OBJECT(tbl), "freeze")) { + return; + } + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); + + + // Get user selected unit and save as preference + UnitTracker *tracker = reinterpret_cast(g_object_get_data(tbl, "tracker")); + Unit const *unit = tracker->getActiveUnit(); + g_return_if_fail(unit != NULL); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + + + // This nonsense is to get SP_CSS_UNIT_xx value corresponding to unit so + // we can save it (allows us to adjust line height value when unit changes). + SPILength temp_length; + Inkscape::CSSOStringStream temp_stream; + temp_stream << 1 << unit->abbr; + temp_length.read(temp_stream.str().c_str()); + prefs->setInt("/tools/text/lineheight/display_unit", temp_length.unit); + g_object_set_data( tbl, "lineheight_unit", GINT_TO_POINTER(temp_length.unit)); + + // Set css line height. + SPCSSAttr *css = sp_repr_css_attr_new (); + Inkscape::CSSOStringStream osfs; + if ( is_relative(unit) ) { + osfs << gtk_adjustment_get_value(adj) << unit->abbr; + } else { + // Inside SVG file, always use "px" for absolute units. + osfs << Quantity::convert(gtk_adjustment_get_value(adj), unit, "px") << "px"; + } + sp_repr_css_set_property (css, "line-height", osfs.str().c_str()); + + // Internal function to set line-height which is spacing mode dependent. + set_lineheight (css); + + // Only need to save for undo if a text item has been changed. + Inkscape::Selection *selection = SP_ACTIVE_DESKTOP->getSelection(); + bool modmade = false; + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end(); ++i){ + if (dynamic_cast(*i) || dynamic_cast(*i)) { + modmade = true; + } + } + + // Save for undo + if (modmade) { + // Call ensureUpToDate() causes rebuild of text layout (with all proper style + // cascading, etc.). For multi-line text with sodipodi::role="line", we must explicitly + // save new 'x' and 'y' attribute values by calling updateRepr(). + // Partial fix for bug #1590141. + SP_ACTIVE_DESKTOP->getDocument()->ensureUpToDate(); + for(auto i=itemlist.begin();i!=itemlist.end(); ++i){ + if (dynamic_cast(*i) || dynamic_cast(*i)) { + (*i)->updateRepr(); + } + } + DocumentUndo::maybeDone(SP_ACTIVE_DESKTOP->getDocument(), "ttb:line-height", SP_VERB_NONE, + _("Text: Change line-height")); + } + + // If no selected objects, set default. + SPStyle query(SP_ACTIVE_DOCUMENT); + int result_numbers = + sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS); + if (result_numbers == QUERY_STYLE_NOTHING) + { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->mergeStyle("/tools/text/style", css); + } + + sp_repr_css_attr_unref (css); + + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); +} + + +static void sp_text_lineheight_unit_changed( GObject *tbl, int /* Not Used */ ) +{ + // quit if run by the _changed callbacks + if (g_object_get_data(G_OBJECT(tbl), "freeze")) { + return; + } + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); + + // Get old saved unit + int old_unit = GPOINTER_TO_INT( g_object_get_data(tbl, "lineheight_unit")); + + // Get user selected unit and save as preference + UnitTracker *tracker = reinterpret_cast(g_object_get_data(tbl, "tracker")); + Unit const *unit = tracker->getActiveUnit(); + g_return_if_fail(unit != NULL); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + + // This nonsense is to get SP_CSS_UNIT_xx value corresponding to unit. + SPILength temp_length; + Inkscape::CSSOStringStream temp_stream; + temp_stream << 1 << unit->abbr; + temp_length.read(temp_stream.str().c_str()); + prefs->setInt("/tools/text/lineheight/display_unit", temp_length.unit); + g_object_set_data( tbl, "lineheight_unit", GINT_TO_POINTER(temp_length.unit)); + + // Read current line height value + EgeAdjustmentAction *line_height_act = + reinterpret_cast(g_object_get_data(tbl, "TextLineHeightAction")); + GtkAdjustment *line_height_adj = ege_adjustment_action_get_adjustment( line_height_act ); + double line_height = gtk_adjustment_get_value(line_height_adj); + + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + Inkscape::Selection *selection = desktop->getSelection(); + auto itemlist = selection->items(); + + // Convert between units + if ((unit->abbr == "" || unit->abbr == "em") && + (old_unit == SP_CSS_UNIT_NONE || old_unit == SP_CSS_UNIT_EM)) { + // Do nothing + } else if ((unit->abbr == "" || unit->abbr == "em") && old_unit == SP_CSS_UNIT_EX) { + line_height *= 0.5; + } else if ((unit->abbr) == "ex" && (old_unit == SP_CSS_UNIT_EM || old_unit == SP_CSS_UNIT_NONE) ) { + line_height *= 2.0; + } else if ((unit->abbr == "" || unit->abbr == "em") && old_unit == SP_CSS_UNIT_PERCENT) { + line_height /= 100.0; + } else if ((unit->abbr) == "%" && (old_unit == SP_CSS_UNIT_EM || old_unit == SP_CSS_UNIT_NONE) ) { + line_height *= 100; + } else if ((unit->abbr) == "ex" && old_unit == SP_CSS_UNIT_PERCENT) { + line_height /= 50.0; + } else if ((unit->abbr) == "%" && old_unit == SP_CSS_UNIT_EX) { + line_height *= 50; + } else if (is_relative(unit)) { + // Convert absolute to relative... for the moment use average font-size + double font_size = 0; + int count = 0; + for(auto i=itemlist.begin();i!=itemlist.end(); ++i){ + if (SP_IS_TEXT (*i) || SP_IS_FLOWTEXT(*i)) { + double doc_scale = Geom::Affine((*i)->i2dt_affine()).descrim(); + font_size += (*i)->style->font_size.computed * doc_scale; + ++count; + } + } + if (count > 0) { + font_size /= count; + } else { + font_size = 20; + } + + if (old_unit == SP_CSS_UNIT_NONE) old_unit = SP_CSS_UNIT_EM; + line_height = Quantity::convert(line_height, sp_style_get_css_unit_string(old_unit), "px"); + + if (font_size > 0) { + line_height /= font_size; + } + if ((unit->abbr) == "%") { + line_height *= 100; + } else if ((unit->abbr) == "ex") { + line_height *= 2; + } + } else if (old_unit==SP_CSS_UNIT_NONE || old_unit==SP_CSS_UNIT_PERCENT || + old_unit==SP_CSS_UNIT_EM || old_unit==SP_CSS_UNIT_EX) { + // Convert relative to absolute... for the moment use average font-size + double font_size = 0; + int count = 0; + for(auto i=itemlist.begin();i!=itemlist.end(); ++i){ + if (SP_IS_TEXT (*i) || SP_IS_FLOWTEXT (*i)) { + double doc_scale = Geom::Affine((*i)->i2dt_affine()).descrim(); + font_size += (*i)->style->font_size.computed * doc_scale; + ++count; + } + } + if (count > 0) { + font_size /= count; + } else { + font_size = 20; + } + + if (old_unit == SP_CSS_UNIT_PERCENT) { + line_height /= 100.0; + } else if (old_unit == SP_CSS_UNIT_EX) { + line_height /= 2.0; + } + line_height *= font_size; + line_height = Quantity::convert(line_height, "px", unit); + } else { + // Convert between different absolute units (only used in GUI) + line_height = Quantity::convert(line_height, sp_style_get_css_unit_string(old_unit), unit); + } + + // Set css line height. + SPCSSAttr *css = sp_repr_css_attr_new (); + Inkscape::CSSOStringStream osfs; + if ( is_relative(unit) ) { + osfs << line_height << unit->abbr; + } else { + osfs << Quantity::convert(line_height, unit, "px") << "px"; + } + sp_repr_css_set_property (css, "line-height", osfs.str().c_str()); + + // Update GUI with line_height value. + gtk_adjustment_set_value(line_height_adj, line_height); + + // Update "climb rate" The custom action has a step property but no way to set it. + if (unit->abbr == "%") { + gtk_adjustment_set_step_increment (line_height_adj, 1.0); + gtk_adjustment_set_page_increment (line_height_adj, 10.0); + } else { + gtk_adjustment_set_step_increment (line_height_adj, 0.1); + gtk_adjustment_set_page_increment (line_height_adj, 1.0); + } + + // Internal function to set line-height which is spacing mode dependent. + set_lineheight (css); + + // Only need to save for undo if a text item has been changed. + bool modmade = false; + for(auto i=itemlist.begin();i!=itemlist.end(); ++i){ + if (dynamic_cast(*i) || dynamic_cast(*i)) { + modmade = true; + } + } + + // Save for undo + if(modmade) { + DocumentUndo::maybeDone(SP_ACTIVE_DESKTOP->getDocument(), "ttb:line-height", SP_VERB_NONE, + _("Text: Change line-height unit")); + } + + // If no selected objects, set default. + SPStyle query(SP_ACTIVE_DOCUMENT); + int result_numbers = + sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS); + if (result_numbers == QUERY_STYLE_NOTHING) + { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->mergeStyle("/tools/text/style", css); + } + + sp_repr_css_attr_unref (css); + + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); +} + +// +static void sp_text_line_spacing_mode_changed( GObject *tbl, int mode ) +{ + + // quit if run by the _changed callbacks + if (g_object_get_data(G_OBJECT(tbl), "freeze")) { + return; + } + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); + + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setInt("/tools/text/line_spacing_mode", mode); + + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + + // Note: only and text elements are in selection! + // (No need to worry about , , ...) + Inkscape::Selection *selection = desktop->getSelection(); + std::vector vec(selection->items().begin(), selection->items().end()); + + for (auto i: vec) { + + // Only and , => SPFlowtext + if (dynamic_cast(i) || dynamic_cast(i)) { + SPStyle* text_style = i->style; + + // Make list of , , children + std::vector children = i->childList(false); + std::vector children_item; + for (auto j: children) { + if (dynamic_cast(j)) { + children_item.push_back( dynamic_cast(j) ); + } + } + + SPStyle tspans; // Also flowPara/flowSpan + int result_numbers = sp_desktop_query_style_from_list (children_item, &tspans, QUERY_STYLE_PROPERTY_FONTNUMBERS); + + Inkscape::CSSOStringStream osfs; + if (text_style->line_height.computed != 0 || text_style->line_height.normal) { + + if (mode != 1 || text_style->line_height.unit == SP_CSS_UNIT_NONE || text_style->line_height.normal) { + Glib::ustring line_height_string = text_style->line_height.write( SP_STYLE_FLAG_ALWAYS ); + line_height_string.erase(0, 12); // erase 'line-height:' + osfs << line_height_string; + } else { + // Convert to unitless value + double line_height_value = text_style->line_height.value; + // Percent values are stored as value/100; + if (text_style->line_height.unit == SP_CSS_UNIT_PERCENT) { + line_height_value *= 100; + } + osfs << sp_style_css_size_units_to_px( line_height_value, + text_style->line_height.unit, + text_style->font_size.computed) / + text_style->font_size.computed; + } + + } else { + + if (mode != 1 || tspans.line_height.unit == SP_CSS_UNIT_NONE || tspans.line_height.normal) { + Glib::ustring line_height_string = tspans.line_height.write( SP_STYLE_FLAG_ALWAYS ); + line_height_string.erase(0, 12); // erase 'line-height:' + osfs << line_height_string; + } else { + // Convert to unitless value + double line_height_value = tspans.line_height.value; + // Percent values are stored as value/100; + if (tspans.line_height.unit == SP_CSS_UNIT_PERCENT) { + line_height_value *= 100; + } + osfs << sp_style_css_size_units_to_px( line_height_value, + tspans.line_height.unit, + tspans.font_size.computed) / + tspans.font_size.computed; + } + } + + SPCSSAttr *css_text = sp_repr_css_attr_new(); + SPCSSAttr *css_tspan = sp_repr_css_attr_new(); + + sp_repr_css_set_property (css_text, "line-height", osfs.str().c_str()); + + switch (mode) { + case 0: // Adaptive + // : Zero text + sp_repr_css_set_property (css_text, "line-height", "0"); + // : Old text value. + sp_repr_css_set_property (css_tspan, "line-height", osfs.str().c_str()); + break; + + case 1: // Minimum + // : Set to old text (unitless) or if old text zero, set to old tspan. + sp_repr_css_set_property (css_text, "line-height", osfs.str().c_str()); + // : Unset + sp_repr_css_unset_property (css_tspan, "line-height"); + break; + + case 2: // Even + // : Set to old text or if old text zero, set to old tspan. + sp_repr_css_set_property (css_text, "line-height", osfs.str().c_str()); + // : Set to zero + sp_repr_css_set_property (css_tspan, "line-height", "0"); + break; + + case 3: // Adjustable + // Do nothing ☠ + break; + } + + if (mode != 3) { + i->changeCSS (css_text, "style"); + for (auto j: children) { + recursively_set_properties (j, css_tspan); + //j->changeCSS (css_tspan, "style"); + } + } + + sp_repr_css_attr_unref (css_text); + sp_repr_css_attr_unref (css_tspan); + } + } + + // Set "Outer Style" toggle to match mode. + InkToggleAction* outerStyle = INK_TOGGLE_ACTION(g_object_get_data (tbl, "TextOuterStyleAction")); + + switch (mode) { + case 0: // Adaptive + gtk_toggle_action_set_active( &(outerStyle->action), false ); + prefs->setInt("/tools/text/outer_style", false); + break; + + case 1: // Minimum + case 2: // Even + gtk_toggle_action_set_active( &(outerStyle->action), true ); + prefs->setInt("/tools/text/outer_style", true); + break; + + case 3: // Adjustable + break; + } + + // Outer style toggle set per mode so that line height widget should be enabled. + GtkAction* lineHeightAction = GTK_ACTION( g_object_get_data( tbl, "TextLineHeightAction" ) ); + gtk_action_set_sensitive (lineHeightAction, true); + + // Update "climb rate" + EgeAdjustmentAction *line_height_act = + reinterpret_cast(g_object_get_data(tbl, "TextLineHeightAction")); + GtkAdjustment *line_height_adj = ege_adjustment_action_get_adjustment( line_height_act ); + UnitTracker *tracker = reinterpret_cast(g_object_get_data(tbl, "tracker")); + Unit const *unit = tracker->getActiveUnit(); + + if (unit->abbr == "%") { + gtk_adjustment_set_step_increment (line_height_adj, 1.0); + gtk_adjustment_set_page_increment (line_height_adj, 10.0); + } else { + gtk_adjustment_set_step_increment (line_height_adj, 0.1); + gtk_adjustment_set_page_increment (line_height_adj, 1.0); + } + + DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_TEXT, + _("Text: Change line spacing mode")); + + gtk_widget_grab_focus (GTK_WIDGET(desktop->canvas)); + + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); +} + +static void sp_text_wordspacing_value_changed( GtkAdjustment *adj, GObject *tbl ) +{ + // quit if run by the _changed callbacks + if (g_object_get_data(G_OBJECT(tbl), "freeze")) { + return; + } + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); + + // At the moment this handles only numerical values (i.e. no em unit). + // Set css word-spacing + SPCSSAttr *css = sp_repr_css_attr_new (); + Inkscape::CSSOStringStream osfs; + osfs << gtk_adjustment_get_value(adj) << "px"; // For now always use px + sp_repr_css_set_property (css, "word-spacing", osfs.str().c_str()); + + // Apply word-spacing to selected objects. + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + sp_desktop_set_style (desktop, css, true, false); + + // If no selected objects, set default. + SPStyle query(SP_ACTIVE_DOCUMENT); + int result_numbers = + sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS); + if (result_numbers == QUERY_STYLE_NOTHING) + { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->mergeStyle("/tools/text/style", css); + } else { + // Save for undo + DocumentUndo::maybeDone(SP_ACTIVE_DESKTOP->getDocument(), "ttb:word-spacing", SP_VERB_NONE, + _("Text: Change word-spacing")); + } + + sp_repr_css_attr_unref (css); + + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); +} + +static void sp_text_letterspacing_value_changed( GtkAdjustment *adj, GObject *tbl ) +{ + // quit if run by the _changed callbacks + if (g_object_get_data(G_OBJECT(tbl), "freeze")) { + return; + } + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); + + // At the moment this handles only numerical values (i.e. no em unit). + // Set css letter-spacing + SPCSSAttr *css = sp_repr_css_attr_new (); + Inkscape::CSSOStringStream osfs; + osfs << gtk_adjustment_get_value(adj) << "px"; // For now always use px + sp_repr_css_set_property (css, "letter-spacing", osfs.str().c_str()); + + // Apply letter-spacing to selected objects. + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + sp_desktop_set_style (desktop, css, true, false); + + // If no selected objects, set default. + SPStyle query(SP_ACTIVE_DOCUMENT); + int result_numbers = + sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS); + if (result_numbers == QUERY_STYLE_NOTHING) + { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->mergeStyle("/tools/text/style", css); + } + else + { + // Save for undo + DocumentUndo::maybeDone(SP_ACTIVE_DESKTOP->getDocument(), "ttb:letter-spacing", SP_VERB_NONE, + _("Text: Change letter-spacing")); + } + + sp_repr_css_attr_unref (css); + + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); +} + + +static void sp_text_dx_value_changed( GtkAdjustment *adj, GObject *tbl ) +{ + // quit if run by the _changed callbacks + if (g_object_get_data(G_OBJECT(tbl), "freeze")) { + return; + } + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); + + gdouble new_dx = gtk_adjustment_get_value(adj); + bool modmade = false; + + if( SP_IS_TEXT_CONTEXT((SP_ACTIVE_DESKTOP)->event_context) ) { + Inkscape::UI::Tools::TextTool *const tc = SP_TEXT_CONTEXT((SP_ACTIVE_DESKTOP)->event_context); + if( tc ) { + unsigned char_index = -1; + TextTagAttributes *attributes = + text_tag_attributes_at_position( tc->text, std::min(tc->text_sel_start, tc->text_sel_end), &char_index ); + if( attributes ) { + double old_dx = attributes->getDx( char_index ); + double delta_dx = new_dx - old_dx; + sp_te_adjust_dx( tc->text, tc->text_sel_start, tc->text_sel_end, SP_ACTIVE_DESKTOP, delta_dx ); + modmade = true; + } + } + } + + if(modmade) { + // Save for undo + DocumentUndo::maybeDone(SP_ACTIVE_DESKTOP->getDocument(), "ttb:dx", SP_VERB_NONE, + _("Text: Change dx (kern)")); + } + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); +} + +static void sp_text_dy_value_changed( GtkAdjustment *adj, GObject *tbl ) +{ + // quit if run by the _changed callbacks + if (g_object_get_data(G_OBJECT(tbl), "freeze")) { + return; + } + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); + + gdouble new_dy = gtk_adjustment_get_value(adj); + bool modmade = false; + + if( SP_IS_TEXT_CONTEXT((SP_ACTIVE_DESKTOP)->event_context) ) { + Inkscape::UI::Tools::TextTool *const tc = SP_TEXT_CONTEXT((SP_ACTIVE_DESKTOP)->event_context); + if( tc ) { + unsigned char_index = -1; + TextTagAttributes *attributes = + text_tag_attributes_at_position( tc->text, std::min(tc->text_sel_start, tc->text_sel_end), &char_index ); + if( attributes ) { + double old_dy = attributes->getDy( char_index ); + double delta_dy = new_dy - old_dy; + sp_te_adjust_dy( tc->text, tc->text_sel_start, tc->text_sel_end, SP_ACTIVE_DESKTOP, delta_dy ); + modmade = true; + } + } + } + + if(modmade) { + // Save for undo + DocumentUndo::maybeDone(SP_ACTIVE_DESKTOP->getDocument(), "ttb:dy", SP_VERB_NONE, + _("Text: Change dy")); + } + + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); +} + +static void sp_text_rotation_value_changed( GtkAdjustment *adj, GObject *tbl ) +{ + // quit if run by the _changed callbacks + if (g_object_get_data(G_OBJECT(tbl), "freeze")) { + return; + } + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); + + gdouble new_degrees = gtk_adjustment_get_value(adj); + + bool modmade = false; + if( SP_IS_TEXT_CONTEXT((SP_ACTIVE_DESKTOP)->event_context) ) { + Inkscape::UI::Tools::TextTool *const tc = SP_TEXT_CONTEXT((SP_ACTIVE_DESKTOP)->event_context); + if( tc ) { + unsigned char_index = -1; + TextTagAttributes *attributes = + text_tag_attributes_at_position( tc->text, std::min(tc->text_sel_start, tc->text_sel_end), &char_index ); + if( attributes ) { + double old_degrees = attributes->getRotate( char_index ); + double delta_deg = new_degrees - old_degrees; + sp_te_adjust_rotation( tc->text, tc->text_sel_start, tc->text_sel_end, SP_ACTIVE_DESKTOP, delta_deg ); + modmade = true; + } + } + } + + // Save for undo + if(modmade) { + DocumentUndo::maybeDone(SP_ACTIVE_DESKTOP->getDocument(), "ttb:rotate", SP_VERB_NONE, + _("Text: Change rotate")); + } + + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); +} + +static void sp_writing_mode_changed( GObject* tbl, int mode ) +{ + // quit if run by the _changed callbacks + if (g_object_get_data(G_OBJECT(tbl), "freeze")) { + return; + } + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); + + SPCSSAttr *css = sp_repr_css_attr_new (); + switch (mode) + { + case 0: + { + sp_repr_css_set_property (css, "writing-mode", "lr-tb"); + break; + } + + case 1: + { + sp_repr_css_set_property (css, "writing-mode", "tb-rl"); + break; + } + + case 2: + { + sp_repr_css_set_property (css, "writing-mode", "vertical-lr"); + break; + } +} + + SPStyle query(SP_ACTIVE_DOCUMENT); + int result_numbers = + sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_WRITINGMODES); + + // If querying returned nothing, update default style. + if (result_numbers == QUERY_STYLE_NOTHING) + { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->mergeStyle("/tools/text/style", css); + } + + sp_desktop_set_style (SP_ACTIVE_DESKTOP, css, true, true); + if(result_numbers != QUERY_STYLE_NOTHING) + { + DocumentUndo::done(SP_ACTIVE_DESKTOP->getDocument(), SP_VERB_CONTEXT_TEXT, + _("Text: Change writing mode")); + } + sp_repr_css_attr_unref (css); + + gtk_widget_grab_focus (GTK_WIDGET(SP_ACTIVE_DESKTOP->canvas)); + + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); +} + +static void sp_text_orientation_changed( GObject* tbl, int mode ) +{ + // quit if run by the _changed callbacks + if (g_object_get_data(G_OBJECT(tbl), "freeze")) { + return; + } + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); + + SPCSSAttr *css = sp_repr_css_attr_new (); + switch (mode) + { + case 0: + { + sp_repr_css_set_property (css, "text-orientation", "auto"); + break; + } + + case 1: + { + sp_repr_css_set_property (css, "text-orientation", "upright"); + break; + } + + case 2: + { + sp_repr_css_set_property (css, "text-orientation", "sideways"); + break; + } + } + + SPStyle query(SP_ACTIVE_DOCUMENT); + int result_numbers = + sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_WRITINGMODES); + + // If querying returned nothing, update default style. + if (result_numbers == QUERY_STYLE_NOTHING) + { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->mergeStyle("/tools/text/style", css); + } + + sp_desktop_set_style (SP_ACTIVE_DESKTOP, css, true, true); + if(result_numbers != QUERY_STYLE_NOTHING) + { + DocumentUndo::done(SP_ACTIVE_DESKTOP->getDocument(), SP_VERB_CONTEXT_TEXT, + _("Text: Change orientation")); + } + sp_repr_css_attr_unref (css); + + gtk_widget_grab_focus (GTK_WIDGET(SP_ACTIVE_DESKTOP->canvas)); + + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); +} + +static void sp_text_direction_changed( GObject *tbl, int mode ) +{ + // quit if run by the _changed callbacks + if (g_object_get_data(G_OBJECT(tbl), "freeze")) { + return; + } + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); + + SPCSSAttr *css = sp_repr_css_attr_new (); + switch (mode) + { + case 0: + { + sp_repr_css_set_property (css, "direction", "ltr"); + break; + } + + case 1: + { + sp_repr_css_set_property (css, "direction", "rtl"); + break; + } + } + + SPStyle query(SP_ACTIVE_DOCUMENT); + int result_numbers = + sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_WRITINGMODES); + + // If querying returned nothing, update default style. + if (result_numbers == QUERY_STYLE_NOTHING) + { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->mergeStyle("/tools/text/style", css); + } + + sp_desktop_set_style (SP_ACTIVE_DESKTOP, css, true, true); + if(result_numbers != QUERY_STYLE_NOTHING) + { + DocumentUndo::done(SP_ACTIVE_DESKTOP->getDocument(), SP_VERB_CONTEXT_TEXT, + _("Text: Change direction")); + } + sp_repr_css_attr_unref (css); + + gtk_widget_grab_focus (GTK_WIDGET(SP_ACTIVE_DESKTOP->canvas)); + + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); +} + +/* + * Set the default list of font sizes, scaled to the users preferred unit + */ +static void sp_text_set_sizes(GtkListStore* model_size, int unit) +{ + gtk_list_store_clear(model_size); + + // List of font sizes for drop-down menu + int sizes[] = { + 4, 6, 8, 9, 10, 11, 12, 13, 14, 16, 18, 20, 22, 24, 28, + 32, 36, 40, 48, 56, 64, 72, 144 + }; + + // Array must be same length as SPCSSUnit in style.h + float ratios[] = {1, 1, 1, 10, 4, 40, 100, 16, 8, 0.16}; + + for( unsigned int i = 0; i < G_N_ELEMENTS(sizes); ++i ) { + GtkTreeIter iter; + Glib::ustring size = Glib::ustring::format(sizes[i] / (float)ratios[unit]); + gtk_list_store_append( model_size, &iter ); + gtk_list_store_set( model_size, &iter, 0, size.c_str(), -1 ); + } +} + + +/* + * This function sets up the text-tool tool-controls, setting the entry boxes + * etc. to the values from the current selection or the default if no selection. + * It is called whenever a text selection is changed, including stepping cursor + * through text, or setting focus to text. + */ +static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/, GObject *tbl, bool subselection) // don't bother to update font list if subsel changed +{ + +#ifdef DEBUG_TEXT + static int count = 0; + ++count; + std::cout << std::endl; + std::cout << "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&" << std::endl; + std::cout << "sp_text_toolbox_selection_changed: start " << count << std::endl; + + Inkscape::Selection *selection = (SP_ACTIVE_DESKTOP)->getSelection(); + auto itemlist0= selection->items(); + for(auto i=itemlist0.begin();i!=itemlist0.end(); ++i) { + const gchar* id = (*i)->getId(); + std::cout << " " << id << std::endl; + } + Glib::ustring selected_text = sp_text_get_selected_text((SP_ACTIVE_DESKTOP)->event_context); + std::cout << " Selected text: |" << selected_text << "|" << std::endl; +#endif + + // quit if run by the _changed callbacks + if (g_object_get_data(G_OBJECT(tbl), "freeze")) { +#ifdef DEBUG_TEXT + std::cout << " Frozen, returning" << std::endl; + std::cout << "sp_text_toolbox_selection_changed: exit " << count << std::endl; + std::cout << "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&" << std::endl; + std::cout << std::endl; +#endif + return; + } + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); + + Ink_ComboBoxEntry_Action* fontFamilyAction = + INK_COMBOBOXENTRY_ACTION( g_object_get_data( tbl, "TextFontFamilyAction" ) ); + Ink_ComboBoxEntry_Action* fontStyleAction = + INK_COMBOBOXENTRY_ACTION( g_object_get_data( tbl, "TextFontStyleAction" ) ); + + Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance(); + fontlister->update_font_list (SP_ACTIVE_DESKTOP->getDocument()); + fontlister->selection_update(); + + // Update font list, but only if widget already created. + if( fontFamilyAction->combobox != NULL ) { + ink_comboboxentry_action_set_active_text( fontFamilyAction, fontlister->get_font_family().c_str(), fontlister->get_font_family_row() ); + ink_comboboxentry_action_set_active_text( fontStyleAction, fontlister->get_font_style().c_str() ); + } + + // Only flowed text can be justified, only normal text can be kerned... + // Find out if we have flowed text now so we can use it several places + gboolean isFlow = false; + auto itemlist= SP_ACTIVE_DESKTOP->getSelection()->items(); + for(auto i=itemlist.begin();i!=itemlist.end(); ++i){ + // std::cout << " " << ((*i)->getId()?(*i)->getId():"null") << std::endl; + if( SP_IS_FLOWTEXT(*i)) { + isFlow = true; + // std::cout << " Found flowed text" << std::endl; + break; + } + } + + /* + * Query from current selection: + * Font family (font-family) + * Style (font-weight, font-style, font-stretch, font-variant, font-align) + * Numbers (font-size, letter-spacing, word-spacing, line-height, text-anchor, writing-mode) + * Font specification (Inkscape private attribute) + */ + SPStyle query(SP_ACTIVE_DOCUMENT); + int result_family = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTFAMILY); + int result_style = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTSTYLE); + int result_baseline = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_BASELINES); + int result_wmode = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_WRITINGMODES); + + // Calling sp_desktop_query_style will result in a call to TextTool::_styleQueried(). + // This returns the style of the selected text inside the element... which + // is often the style of one or more s. If we want the style of the outer + // objects then we need to bypass the call to TextTool::_styleQueried(). + // The desktop selection never includes the elements inside the element. + int result_numbers = 0; + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + bool outer = prefs->getInt("/tools/text/outer_style", false); + if (outer) { + Inkscape::Selection *selection = desktop->getSelection(); + std::vector vec(selection->items().begin(), selection->items().end()); + result_numbers = sp_desktop_query_style_from_list (vec, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS); + } else { + result_numbers = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS); + } + + /* + * If no text in selection (querying returned nothing), read the style from + * the /tools/text preferencess (default style for new texts). Return if + * tool bar already set to these preferences. + */ + if (result_family == QUERY_STYLE_NOTHING || + result_style == QUERY_STYLE_NOTHING || + result_numbers == QUERY_STYLE_NOTHING || + result_wmode == QUERY_STYLE_NOTHING ) { + // There are no texts in selection, read from preferences. + query.readFromPrefs("/tools/text"); +#ifdef DEBUG_TEXT + std::cout << " read style from prefs:" << std::endl; + sp_print_font( &query ); +#endif + if (g_object_get_data(tbl, "text_style_from_prefs")) { + // Do not reset the toolbar style from prefs if we already did it last time + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); +#ifdef DEBUG_TEXT + std::cout << " text_style_from_prefs: toolbar already set" << std:: endl; + std::cout << "sp_text_toolbox_selection_changed: exit " << count << std::endl; + std::cout << "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&" << std::endl; + std::cout << std::endl; +#endif + return; + } + + // To ensure the value of the combobox is properly set on start-up, only mark + // the prefs set if the combobox has already been constructed. + if( fontFamilyAction->combobox != NULL ) { + g_object_set_data(tbl, "text_style_from_prefs", GINT_TO_POINTER(TRUE)); + } + } else { + g_object_set_data(tbl, "text_style_from_prefs", GINT_TO_POINTER(FALSE)); + } + + // If we have valid query data for text (font-family, font-specification) set toolbar accordingly. + { + // Size (average of text selected) + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + int unit = prefs->getInt("/options/font/unitType", SP_CSS_UNIT_PT); + double size = sp_style_css_size_px_to_units(query.font_size.computed, unit); + + //gchar size_text[G_ASCII_DTOSTR_BUF_SIZE]; + //g_ascii_dtostr (size_text, sizeof (size_text), size); + + Inkscape::CSSOStringStream os; + os << size; + + Ink_ComboBoxEntry_Action* fontSizeAction = + INK_COMBOBOXENTRY_ACTION( g_object_get_data( tbl, "TextFontSizeAction" ) ); + + // Freeze to ignore callbacks. + //g_object_freeze_notify( G_OBJECT( fontSizeAction->combobox ) ); + sp_text_set_sizes(GTK_LIST_STORE(ink_comboboxentry_action_get_model(fontSizeAction)), unit); + //g_object_thaw_notify( G_OBJECT( fontSizeAction->combobox ) ); + + ink_comboboxentry_action_set_active_text( fontSizeAction, os.str().c_str() ); + + Glib::ustring tooltip = Glib::ustring::format(_("Font size"), " (", sp_style_get_css_unit_string(unit), ")"); + ink_comboboxentry_action_set_tooltip ( fontSizeAction, tooltip.c_str()); + + // Superscript + gboolean superscriptSet = + ((result_baseline == QUERY_STYLE_SINGLE || result_baseline == QUERY_STYLE_MULTIPLE_SAME ) && + query.baseline_shift.set && + query.baseline_shift.type == SP_BASELINE_SHIFT_LITERAL && + query.baseline_shift.literal == SP_CSS_BASELINE_SHIFT_SUPER ); + + InkToggleAction* textSuperscriptAction = INK_TOGGLE_ACTION( g_object_get_data( tbl, "TextSuperscriptAction" ) ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(textSuperscriptAction), superscriptSet ); + + + // Subscript + gboolean subscriptSet = + ((result_baseline == QUERY_STYLE_SINGLE || result_baseline == QUERY_STYLE_MULTIPLE_SAME ) && + query.baseline_shift.set && + query.baseline_shift.type == SP_BASELINE_SHIFT_LITERAL && + query.baseline_shift.literal == SP_CSS_BASELINE_SHIFT_SUB ); + + InkToggleAction* textSubscriptAction = INK_TOGGLE_ACTION( g_object_get_data( tbl, "TextSubscriptAction" ) ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(textSubscriptAction), subscriptSet ); + + + // Alignment + InkSelectOneAction* textAlignAction = + static_cast( g_object_get_data( tbl, "TextAlignAction" ) ); + + // Note: SVG 1.1 doesn't include text-align, SVG 1.2 Tiny doesn't include text-align="justify" + // text-align="justify" was a draft SVG 1.2 item (along with flowed text). + // Only flowed text can be left and right justified at the same time. + // Disable button if we don't have flowed text. + + Glib::RefPtr store = textAlignAction->get_store(); + Gtk::TreeModel::Row row = *(store->get_iter("3")); // Justify entry + InkSelectOneActionColumns columns; + row[columns.col_sensitive] = isFlow; + + int activeButton = 0; + if (query.text_align.computed == SP_CSS_TEXT_ALIGN_JUSTIFY) + { + activeButton = 3; + } else { + // This should take 'direction' into account + if (query.text_anchor.computed == SP_CSS_TEXT_ANCHOR_START) activeButton = 0; + if (query.text_anchor.computed == SP_CSS_TEXT_ANCHOR_MIDDLE) activeButton = 1; + if (query.text_anchor.computed == SP_CSS_TEXT_ANCHOR_END) activeButton = 2; + } + textAlignAction->set_active( activeButton ); + + // Line height (spacing) and line height unit + double height; + int line_height_unit = -1; + if (query.line_height.normal) { + height = Inkscape::Text::Layout::LINE_HEIGHT_NORMAL; + line_height_unit = SP_CSS_UNIT_NONE; + } else { + height = query.line_height.value; + line_height_unit = query.line_height.unit; + } + + switch (line_height_unit) { + case SP_CSS_UNIT_NONE: + case SP_CSS_UNIT_EM: + case SP_CSS_UNIT_EX: + break; + case SP_CSS_UNIT_PERCENT: + height *= 100.0; // Inkscape store % as fraction in .value + break; + case SP_CSS_UNIT_PX: + // If unit is set to 'px', use the preferred display unit (if absolute). + line_height_unit = + prefs->getInt("/tools/text/lineheight/display_unit", SP_CSS_UNIT_PT); + // But not if preferred unit is relative + if (line_height_unit != SP_CSS_UNIT_NONE && + line_height_unit != SP_CSS_UNIT_EM && + line_height_unit != SP_CSS_UNIT_EX && + line_height_unit != SP_CSS_UNIT_PERCENT) { + height = + Quantity::convert(height, "px", sp_style_get_css_unit_string(line_height_unit)); + } else { + line_height_unit = SP_CSS_UNIT_PX; + } + break; + default: + // If unit has been set by an external program to something other than 'px', use + // that unit. But height is average of computed values (px) so we need to convert + // back. + height = + Quantity::convert(height, "px", sp_style_get_css_unit_string(line_height_unit)); + } + + GtkAction* lineHeightAction = GTK_ACTION( g_object_get_data( tbl, "TextLineHeightAction" ) ); + GtkAdjustment *lineHeightAdjustment = + ege_adjustment_action_get_adjustment(EGE_ADJUSTMENT_ACTION( lineHeightAction )); + gtk_adjustment_set_value( lineHeightAdjustment, height ); + + // Update "climb rate" + if (line_height_unit == SP_CSS_UNIT_PERCENT) { + gtk_adjustment_set_step_increment (lineHeightAdjustment, 1.0); + gtk_adjustment_set_page_increment (lineHeightAdjustment, 10.0); + } else { + gtk_adjustment_set_step_increment (lineHeightAdjustment, 0.1); + gtk_adjustment_set_page_increment (lineHeightAdjustment, 1.0); + } + + UnitTracker* tracker = reinterpret_cast( g_object_get_data( tbl, "tracker" ) ); + if( line_height_unit == SP_CSS_UNIT_NONE ) { + // Function 'sp_style_get_css_unit_string' returns 'px' for unit none. + // We need to avoid this. + tracker->setActiveUnitByAbbr(""); + } else { + tracker->setActiveUnitByAbbr(sp_style_get_css_unit_string(line_height_unit)); + } + // Save unit so we can do conversions between new/old units. + g_object_set_data( tbl, "lineheight_unit", GINT_TO_POINTER(line_height_unit)); + + // Enable and turn on only if selection includes an object with line height set. + InkToggleAction* lineHeightUnset = + INK_TOGGLE_ACTION( g_object_get_data( tbl, "TextLineHeightUnsetAction")); + gtk_action_set_sensitive(GTK_ACTION(lineHeightUnset), query.line_height.set ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(lineHeightUnset), query.line_height.set ); + + + // Line spacing mode: requires calculating mode for each element and the s within. + Inkscape::Selection *selection = desktop->getSelection(); + std::vector vec(selection->items().begin(), selection->items().end()); + int mode[4] = {0, 0, 0, 0}; + for (auto i: vec) { + if (dynamic_cast(i) || dynamic_cast(i) ) { + bool text_line_height_set = false; + bool text_line_height_zero = false; + bool text_line_height_has_units = false; + bool tspan_line_height_all_unset = true; + bool tspan_line_height_all_zero = true; + bool tspan_line_height_all_non_zero = true; + if (i->style && i->style->line_height.set) { + text_line_height_set = true; + if (i->style->line_height.computed == 0 && !(i->style->line_height.normal)) { + text_line_height_zero = true; + } + if (i->style->line_height.unit != SP_CSS_UNIT_NONE && !(i->style->line_height.normal)) { + text_line_height_has_units = true; + } + } + // TO DO: recursively check children + std::vector children = i->childList(false); + for (auto j: children) { + if (dynamic_cast(j) || dynamic_cast(j) || dynamic_cast(j) ) { + if (j->style && j->style->line_height.set) { + tspan_line_height_all_unset = false; + if (j->style->line_height.computed != 0 || j->style->line_height.normal) { + tspan_line_height_all_zero = false; + } else { + tspan_line_height_all_non_zero = false; + } + } + } + } + + if ( text_line_height_zero && tspan_line_height_all_non_zero) mode[0]++; + else if (!text_line_height_has_units && tspan_line_height_all_unset) mode[1]++; + else if ( text_line_height_has_units && tspan_line_height_all_unset) mode[3]++; + else if ( tspan_line_height_all_zero ) mode[2]++; + else mode[3]++; + } + } + + int activeButtonLS = 3; + if (mode[0] > 0 && mode[1] == 0 && mode[2] == 0 && mode[3] == 0) activeButtonLS = 0; + if (mode[0] == 0 && mode[1] > 0 && mode[2] == 0 && mode[3] == 0) activeButtonLS = 1; + if (mode[0] == 0 && mode[1] == 0 && mode[2] > 0 && mode[3] == 0) activeButtonLS = 2; + // std::cout << " modes: " << mode[0] + // << ", "<< mode[1] + // << ", "<< mode[2] + // << ", "<< mode[3] << std::endl; + InkSelectOneAction* textLineSpacingAction = + static_cast( g_object_get_data( tbl, "TextLineSpacingAction" ) ); + textLineSpacingAction->set_active( activeButtonLS ); + + // Enable/disable line height widget based on mode and Outer Style toggle. + if ( (activeButtonLS == 0 && outer) || // Adaptive + (activeButtonLS == 1 && !outer) || // Minimum + (activeButtonLS == 2 && !outer) // Even + ) { + gtk_action_set_sensitive (lineHeightAction, false); + } else { + gtk_action_set_sensitive (lineHeightAction, true); + } + + // In Minimum and Adaptive modes, don't allow unit change (must remain unitless). + InkSelectOneAction* textLineHeightUnitsAction = + static_cast(g_object_get_data( tbl, "TextLineHeightUnitsAction") ); + if (activeButtonLS == 0 || (activeButtonLS == 1 && outer)) { + textLineHeightUnitsAction->set_sensitive(false); + } else { + textLineHeightUnitsAction->set_sensitive(true); + } + + // Word spacing + double wordSpacing; + if (query.word_spacing.normal) wordSpacing = 0.0; + else wordSpacing = query.word_spacing.computed; // Assume no units (change in desktop-style.cpp) + + GtkAction* wordSpacingAction = GTK_ACTION( g_object_get_data( tbl, "TextWordSpacingAction" ) ); + GtkAdjustment *wordSpacingAdjustment = + ege_adjustment_action_get_adjustment(EGE_ADJUSTMENT_ACTION( wordSpacingAction )); + gtk_adjustment_set_value( wordSpacingAdjustment, wordSpacing ); + + + // Letter spacing + double letterSpacing; + if (query.letter_spacing.normal) letterSpacing = 0.0; + else letterSpacing = query.letter_spacing.computed; // Assume no units (change in desktop-style.cpp) + + GtkAction* letterSpacingAction = GTK_ACTION( g_object_get_data( tbl, "TextLetterSpacingAction" ) ); + GtkAdjustment *letterSpacingAdjustment = + ege_adjustment_action_get_adjustment(EGE_ADJUSTMENT_ACTION( letterSpacingAction )); + gtk_adjustment_set_value( letterSpacingAdjustment, letterSpacing ); + + + // Writing mode + int activeButton2 = 0; + if (query.writing_mode.computed == SP_CSS_WRITING_MODE_LR_TB) activeButton2 = 0; + if (query.writing_mode.computed == SP_CSS_WRITING_MODE_TB_RL) activeButton2 = 1; + if (query.writing_mode.computed == SP_CSS_WRITING_MODE_TB_LR) activeButton2 = 2; + + InkSelectOneAction* writingModeAction = + static_cast( g_object_get_data( tbl, "TextWritingModeAction" ) ); + writingModeAction->set_active( activeButton2 ); + + // Orientation + int activeButton3 = 0; + if (query.text_orientation.computed == SP_CSS_TEXT_ORIENTATION_MIXED ) activeButton3 = 0; + if (query.text_orientation.computed == SP_CSS_TEXT_ORIENTATION_UPRIGHT ) activeButton3 = 1; + if (query.text_orientation.computed == SP_CSS_TEXT_ORIENTATION_SIDEWAYS) activeButton3 = 2; + + InkSelectOneAction* textOrientationAction = + static_cast( g_object_get_data( tbl, "TextOrientationAction" ) ); + textOrientationAction->set_active( activeButton3 ); + + // Disable text orientation for horizontal text... + textOrientationAction->set_sensitive( activeButton2 != 0 ); + + // Direction + int activeButton4 = 0; + if (query.direction.computed == SP_CSS_DIRECTION_LTR ) activeButton4 = 0; + if (query.direction.computed == SP_CSS_DIRECTION_RTL ) activeButton4 = 1; + InkSelectOneAction* textDirectionAction = + static_cast( g_object_get_data( tbl, "TextDirectionAction" ) ); + textDirectionAction->set_active( activeButton4 ); + } + +#ifdef DEBUG_TEXT + std::cout << " GUI: fontfamily.value: " + << (query.font_family.value ? query.font_family.value : "No value") + << std::endl; + std::cout << " GUI: font_size.computed: " << query.font_size.computed << std::endl; + std::cout << " GUI: font_weight.computed: " << query.font_weight.computed << std::endl; + std::cout << " GUI: font_style.computed: " << query.font_style.computed << std::endl; + std::cout << " GUI: text_anchor.computed: " << query.text_anchor.computed << std::endl; + std::cout << " GUI: text_align.computed: " << query.text_align.computed << std::endl; + std::cout << " GUI: line_height.computed: " << query.line_height.computed + << " line_height.value: " << query.line_height.value + << " line_height.unit: " << query.line_height.unit << std::endl; + std::cout << " GUI: word_spacing.computed: " << query.word_spacing.computed + << " word_spacing.value: " << query.word_spacing.value + << " word_spacing.unit: " << query.word_spacing.unit << std::endl; + std::cout << " GUI: letter_spacing.computed: " << query.letter_spacing.computed + << " letter_spacing.value: " << query.letter_spacing.value + << " letter_spacing.unit: " << query.letter_spacing.unit << std::endl; + std::cout << " GUI: writing_mode.computed: " << query.writing_mode.computed << std::endl; +#endif + + // Kerning (xshift), yshift, rotation. NB: These are not CSS attributes. + if( SP_IS_TEXT_CONTEXT((SP_ACTIVE_DESKTOP)->event_context) ) { + Inkscape::UI::Tools::TextTool *const tc = SP_TEXT_CONTEXT((SP_ACTIVE_DESKTOP)->event_context); + if( tc ) { + unsigned char_index = -1; + TextTagAttributes *attributes = + text_tag_attributes_at_position( tc->text, std::min(tc->text_sel_start, tc->text_sel_end), &char_index ); + if( attributes ) { + + // Dx + double dx = attributes->getDx( char_index ); + GtkAction* dxAction = GTK_ACTION( g_object_get_data( tbl, "TextDxAction" )); + GtkAdjustment *dxAdjustment = + ege_adjustment_action_get_adjustment(EGE_ADJUSTMENT_ACTION( dxAction )); + gtk_adjustment_set_value( dxAdjustment, dx ); + + // Dy + double dy = attributes->getDy( char_index ); + GtkAction* dyAction = GTK_ACTION( g_object_get_data( tbl, "TextDyAction" )); + GtkAdjustment *dyAdjustment = + ege_adjustment_action_get_adjustment(EGE_ADJUSTMENT_ACTION( dyAction )); + gtk_adjustment_set_value( dyAdjustment, dy ); + + // Rotation + double rotation = attributes->getRotate( char_index ); + /* SVG value is between 0 and 360 but we're using -180 to 180 in widget */ + if( rotation > 180.0 ) rotation -= 360.0; + GtkAction* rotationAction = GTK_ACTION( g_object_get_data( tbl, "TextRotationAction" )); + GtkAdjustment *rotationAdjustment = + ege_adjustment_action_get_adjustment(EGE_ADJUSTMENT_ACTION( rotationAction )); + gtk_adjustment_set_value( rotationAdjustment, rotation ); + +#ifdef DEBUG_TEXT + std::cout << " GUI: Dx: " << dx << std::endl; + std::cout << " GUI: Dy: " << dy << std::endl; + std::cout << " GUI: Rotation: " << rotation << std::endl; +#endif + } + } + } + + { + // Set these here as we don't always have kerning/rotating attributes + GtkAction* dxAction = GTK_ACTION( g_object_get_data( tbl, "TextDxAction" )); + gtk_action_set_sensitive( GTK_ACTION(dxAction), !isFlow ); + + GtkAction* dyAction = GTK_ACTION( g_object_get_data( tbl, "TextDyAction" )); + gtk_action_set_sensitive( GTK_ACTION(dyAction), !isFlow ); + + GtkAction* rotationAction = GTK_ACTION( g_object_get_data( tbl, "TextRotationAction" )); + gtk_action_set_sensitive( GTK_ACTION(rotationAction), !isFlow ); + } + +#ifdef DEBUG_TEXT + std::cout << "sp_text_toolbox_selection_changed: exit " << count << std::endl; + std::cout << "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&" << std::endl; + std::cout << std::endl; +#endif + + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); +} + +static void sp_text_toolbox_selection_modified(Inkscape::Selection *selection, guint /*flags*/, GObject *tbl) +{ + sp_text_toolbox_selection_changed (selection, tbl); +} + +static void +sp_text_toolbox_subselection_changed (gpointer /*tc*/, GObject *tbl) +{ + sp_text_toolbox_selection_changed (NULL, tbl, true); +} + +// TODO: possibly share with font-selector by moving most code to font-lister (passing family name) +static void sp_text_toolbox_select_cb( GtkEntry* entry, GtkEntryIconPosition /*position*/, GdkEvent /*event*/, gpointer /*data*/ ) { + + Glib::ustring family = gtk_entry_get_text ( entry ); + //std::cout << "text_toolbox_missing_font_cb: selecting: " << family << std::endl; + + // Get all items with matching font-family set (not inherited!). + std::vector selectList; + + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + SPDocument *document = desktop->getDocument(); + std::vector x,y; + std::vector allList = get_all_items(x, document->getRoot(), desktop, false, false, true, y); + for(std::vector::const_reverse_iterator i=allList.rbegin();i!=allList.rend(); ++i){ + SPItem *item = *i; + SPStyle *style = item->style; + + if (style) { + + Glib::ustring family_style; + if (style->font_family.set) { + family_style = style->font_family.value; + //std::cout << " family style from font_family: " << family_style << std::endl; + } + else if (style->font_specification.set) { + family_style = style->font_specification.value; + //std::cout << " family style from font_spec: " << family_style << std::endl; + } + + if (family_style.compare( family ) == 0 ) { + //std::cout << " found: " << item->getId() << std::endl; + selectList.push_back(item); + } + } + } + + // Update selection + Inkscape::Selection *selection = desktop->getSelection(); + selection->clear(); + //std::cout << " list length: " << g_slist_length ( selectList ) << std::endl; + selection->setList(selectList); +} + +static void text_toolbox_watch_ec(SPDesktop* dt, Inkscape::UI::Tools::ToolBase* ec, GObject* holder); + +// Define all the "widgets" in the toolbar. +void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + GtkIconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1); + + /* Font family */ + { + // Font list + Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance(); + fontlister->update_font_list( SP_ACTIVE_DESKTOP->getDocument()); + Glib::RefPtr store = fontlister->get_font_list(); + GtkListStore* model = store->gobj(); + + Ink_ComboBoxEntry_Action* act = + ink_comboboxentry_action_new( "TextFontFamilyAction", + _("Font Family"), + _("Select Font Family (Alt-X to access)"), + NULL, + GTK_TREE_MODEL(model), + -1, // Entry width + 50, // Extra list width + (gpointer)font_lister_cell_data_func2, // Cell layout + (gpointer)font_lister_separator_func2, + GTK_WIDGET(desktop->canvas)); // Focus widget + ink_comboboxentry_action_popup_enable( act ); // Enable entry completion + + gchar *const info = _("Select all text with this font-family"); + ink_comboboxentry_action_set_info( act, info ); // Show selection icon + ink_comboboxentry_action_set_info_cb( act, (gpointer)sp_text_toolbox_select_cb ); + + gchar *const warning = _("Font not found on system"); + ink_comboboxentry_action_set_warning( act, warning ); // Show icon w/ tooltip if font missing + ink_comboboxentry_action_set_warning_cb( act, (gpointer)sp_text_toolbox_select_cb ); + + //ink_comboboxentry_action_set_warning_callback( act, sp_text_fontfamily_select_all ); + ink_comboboxentry_action_set_altx_name( act, "altx-text" ); // Set Alt-X keyboard shortcut + g_signal_connect( G_OBJECT(act), "changed", G_CALLBACK(sp_text_fontfamily_value_changed), holder ); + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + g_object_set_data( holder, "TextFontFamilyAction", act ); + + // Change style of drop-down from menu to list + auto css_provider = gtk_css_provider_new(); + gtk_css_provider_load_from_data(css_provider, + "#TextFontFamilyAction_combobox {\n" + " -GtkComboBox-appears-as-list: true;\n" + "}\n", + -1, NULL); + + auto screen = gdk_screen_get_default(); + gtk_style_context_add_provider_for_screen(screen, + GTK_STYLE_PROVIDER(css_provider), + GTK_STYLE_PROVIDER_PRIORITY_USER); + } + + /* Font size */ + { + // List of font sizes for drop-down menu + GtkListStore* model_size = gtk_list_store_new( 1, G_TYPE_STRING ); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + int unit = prefs->getInt("/options/font/unitType", SP_CSS_UNIT_PT); + + sp_text_set_sizes(model_size, unit); + + Glib::ustring tooltip = Glib::ustring::format(_("Font size"), " (", sp_style_get_css_unit_string(unit), ")"); + + Ink_ComboBoxEntry_Action* act = ink_comboboxentry_action_new( "TextFontSizeAction", + _("Font Size"), + _(tooltip.c_str()), + NULL, + GTK_TREE_MODEL(model_size), + 8, // Width in characters + 0, // Extra list width + NULL, // Cell layout + NULL, // Separator + GTK_WIDGET(desktop->canvas)); // Focus widget + + g_signal_connect( G_OBJECT(act), "changed", G_CALLBACK(sp_text_fontsize_value_changed), holder ); + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + g_object_set_data( holder, "TextFontSizeAction", act ); + } + + /* Font styles */ + { + Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance(); + Glib::RefPtr store = fontlister->get_style_list(); + GtkListStore* model_style = store->gobj(); + + Ink_ComboBoxEntry_Action* act = ink_comboboxentry_action_new( "TextFontStyleAction", + _("Font Style"), + _("Font style"), + NULL, + GTK_TREE_MODEL(model_style), + 12, // Width in characters + 0, // Extra list width + NULL, // Cell layout + NULL, // Separator + GTK_WIDGET(desktop->canvas)); // Focus widget + + g_signal_connect( G_OBJECT(act), "changed", G_CALLBACK(sp_text_fontstyle_value_changed), holder ); + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + g_object_set_data( holder, "TextFontStyleAction", act ); + } + + /* Style - Superscript */ + { + InkToggleAction* act = ink_toggle_action_new( "TextSuperscriptAction", // Name + _("Toggle Superscript"), // Label + _("Toggle superscript"), // Tooltip + "text_superscript", // Icon (inkId) + secondarySize ); // Icon size + gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_text_script_changed), holder ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/text/super", false) ); + g_object_set_data( holder, "TextSuperscriptAction", act ); + } + + /* Style - Subscript */ + { + InkToggleAction* act = ink_toggle_action_new( "TextSubscriptAction", // Name + _("Toggle Subscript"), // Label + _("Toggle subscript"), // Tooltip + "text_subscript", // Icon (inkId) + secondarySize ); // Icon size + gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_text_script_changed), holder ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/text/sub", false) ); + g_object_set_data( holder, "TextSubscriptAction", act ); + } + + /* Alignment */ + { + InkSelectOneActionColumns columns; + + Glib::RefPtr store = Gtk::ListStore::create(columns); + + Gtk::TreeModel::Row row; + + row = *(store->append()); + row[columns.col_label ] = _("Align left"); + row[columns.col_tooltip ] = _("Align left"); + row[columns.col_icon ] = INKSCAPE_ICON("format-justify-left"); + row[columns.col_sensitive] = true; + + row = *(store->append()); + row[columns.col_label ] = _("Align center"); + row[columns.col_tooltip ] = _("Align center"); + row[columns.col_icon ] = INKSCAPE_ICON("format-justify-center"); + row[columns.col_sensitive] = true; + + row = *(store->append()); + row[columns.col_label ] = _("Align right"); + row[columns.col_tooltip ] = _("Align right"); + row[columns.col_icon ] = INKSCAPE_ICON("format-justify-right"); + row[columns.col_sensitive] = true; + + row = *(store->append()); + row[columns.col_label ] = _("Justify"); + row[columns.col_tooltip ] = _("Justify (only flowed text)"); + row[columns.col_icon ] = INKSCAPE_ICON("format-justify-fill"); + row[columns.col_sensitive] = false; + + InkSelectOneAction* act = + InkSelectOneAction::create( "TextAlignAction", // Name + _("Alignment"), // Label + _("Text alignment"), // Tooltip + "Not Used", // Icon + store ); // Tree store + act->use_radio( false ); + act->use_label( false ); + gint mode = prefs->getInt("/tools/text/align_mode", 0); + act->set_active( mode ); + + gtk_action_group_add_action( mainActions, GTK_ACTION( act->gobj() )); + g_object_set_data( holder, "TextAlignAction", act ); + + act->signal_changed().connect(sigc::bind<0>(sigc::ptr_fun(&sp_text_align_mode_changed), holder)); + } + + /* Writing mode (Horizontal, Vertical-LR, Vertical-RL) */ + { + InkSelectOneActionColumns columns; + + Glib::RefPtr store = Gtk::ListStore::create(columns); + + Gtk::TreeModel::Row row; + + row = *(store->append()); + row[columns.col_label ] = _("Horizontal"); + row[columns.col_tooltip ] = _("Horizontal text"); + row[columns.col_icon ] = INKSCAPE_ICON("format-text-direction-horizontal"); + row[columns.col_sensitive] = true; + + row = *(store->append()); + row[columns.col_label ] = _("Vertical — RL"); + row[columns.col_tooltip ] = _("Vertical text — lines: right to left"); + row[columns.col_icon ] = INKSCAPE_ICON("format-text-direction-vertical"); + row[columns.col_sensitive] = true; + + row = *(store->append()); + row[columns.col_label ] = _("Vertical — LR"); + row[columns.col_tooltip ] = _("Vertical text — lines: left to right"); + row[columns.col_icon ] = INKSCAPE_ICON("format-text-direction-vertical-lr"); + row[columns.col_sensitive] = true; + + InkSelectOneAction* act = + InkSelectOneAction::create( "TextWritingModeAction", // Name + _("Writing mode"), // Label + _("Block progression"), // Tooltip + "Not Used", // Icon + store ); // Tree store + act->use_radio( false ); + act->use_label( false ); + gint mode = prefs->getInt("/tools/text/writing_mode", 0); + act->set_active( mode ); + + gtk_action_group_add_action( mainActions, GTK_ACTION( act->gobj() )); + g_object_set_data( holder, "TextWritingModeAction", act ); + + act->signal_changed().connect(sigc::bind<0>(sigc::ptr_fun(&sp_writing_mode_changed), holder)); + } + + /* Text (glyph) orientation (Auto (mixed), Upright, Sideways) */ + { + InkSelectOneActionColumns columns; + + Glib::RefPtr store = Gtk::ListStore::create(columns); + + Gtk::TreeModel::Row row; + + row = *(store->append()); + row[columns.col_label ] = _("Auto"); + row[columns.col_tooltip ] = _("Auto glyph orientation"); + row[columns.col_icon ] = INKSCAPE_ICON("text-orientation-auto"); + row[columns.col_sensitive] = true; + + row = *(store->append()); + row[columns.col_label ] = _("Upright"); + row[columns.col_tooltip ] = _("Upright glyph orientation"); + row[columns.col_icon ] = INKSCAPE_ICON("text-orientation-upright"); + row[columns.col_sensitive] = true; + + row = *(store->append()); + row[columns.col_label ] = _("Sideways"); + row[columns.col_tooltip ] = _("Sideways glyph orientation"); + row[columns.col_icon ] = INKSCAPE_ICON("text-orientation-sideways"); + row[columns.col_sensitive] = true; + + InkSelectOneAction* act = + InkSelectOneAction::create( "TextOrientationAction", // Name + _("Text orientation"), // Label + _("Text (glyph) orientation in vertical text."), // Tooltip + "Not Used", // Icon + store ); // List store + act->use_radio( false ); + act->use_label( false ); + gint mode = prefs->getInt("/tools/text/text_orientation", 0); + act->set_active( mode ); + + gtk_action_group_add_action( mainActions, GTK_ACTION( act->gobj() )); + g_object_set_data( holder, "TextOrientationAction", act ); + + act->signal_changed().connect(sigc::bind<0>(sigc::ptr_fun(&sp_text_orientation_changed), holder)); + } + + + // Text direction (predominant direction of horizontal text). + { + InkSelectOneActionColumns columns; + + Glib::RefPtr store = Gtk::ListStore::create(columns); + + Gtk::TreeModel::Row row; + + row = *(store->append()); + row[columns.col_label ] = _("LTR"); + row[columns.col_tooltip ] = _("Left to right text"); + row[columns.col_icon ] = INKSCAPE_ICON("format-text-direction-horizontal"); + row[columns.col_sensitive] = true; + + row = *(store->append()); + row[columns.col_label ] = _("RTL"); + row[columns.col_tooltip ] = _("Right to left text"); + row[columns.col_icon ] = INKSCAPE_ICON("format-text-direction-r2l"); + row[columns.col_sensitive] = true; + + InkSelectOneAction* act = + InkSelectOneAction::create( "TextDirectionAction", // Name + _("Text direction"), // Label + _("Text direction for normally horizontal text."), // Tooltip + "Not Used", // Icon + store ); // List store + act->use_radio( false ); + act->use_label( false ); + gint mode = prefs->getInt("/tools/text/text_direction", 0); + act->set_active( mode ); + + gtk_action_group_add_action( mainActions, GTK_ACTION( act->gobj() )); + g_object_set_data( holder, "TextDirectionAction", act ); + + act->signal_changed_after().connect(sigc::bind<0>(sigc::ptr_fun(&sp_text_direction_changed), holder)); + } + + /* Line height unit tracker */ + UnitTracker* tracker = new UnitTracker(Inkscape::Util::UNIT_TYPE_LINEAR); + tracker->prependUnit(unit_table.getUnit("")); // No unit + tracker->addUnit(unit_table.getUnit("%")); + tracker->addUnit(unit_table.getUnit("em")); + tracker->addUnit(unit_table.getUnit("ex")); + tracker->setActiveUnit(unit_table.getUnit("%")); + g_object_set_data( holder, "tracker", tracker ); + + /* Line height */ + { + // Drop down menu + gchar const* labels[] = {_("Smaller spacing"), 0, 0, 0, 0, C_("Text tool", "Normal"), 0, 0, 0, 0, 0, _("Larger spacing")}; + gdouble values[] = { 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1,2, 1.3, 1.4, 1.5, 2.0}; + + EgeAdjustmentAction *eact = create_adjustment_action( + "TextLineHeightAction", /* name */ + _("Line Height"), /* label */ + _("Line:"), /* short label */ + _("Spacing between baselines"), /* tooltip */ + "/tools/text/lineheight", /* preferences path */ + 0.0, /* default */ + GTK_WIDGET(desktop->canvas), /* focusTarget */ + holder, /* dataKludge */ + FALSE, /* set alt-x keyboard shortcut? */ + NULL, /* altx_mark */ + 0.0, 1000.0, 0.1, 1.0, /* lower, upper, step (arrow up/down), page up/down */ + labels, values, G_N_ELEMENTS(labels), /* drop down menu */ + sp_text_lineheight_value_changed, /* callback */ + NULL, // tracker, /* unit tracker */ + 0.1, /* step (used?) */ + 2, /* digits to show */ + 1.0 /* factor (multiplies default) */ + ); + //tracker->addAdjustment( ege_adjustment_action_get_adjustment(eact) ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); + g_object_set_data( holder, "TextLineHeightAction", eact ); + g_object_set( G_OBJECT(eact), "iconId", "text_line_spacing", NULL ); + } + + /* Line height units */ + { + InkSelectOneAction* act = tracker->createAction( "TextLineHeightUnitsAction", _("Units"), ("") ); + gtk_action_group_add_action( mainActions, act->gobj() ); + act->signal_changed_after().connect(sigc::bind<0>(sigc::ptr_fun(&sp_text_lineheight_unit_changed), holder)); + g_object_set_data( holder, "TextLineHeightUnitsAction", act ); + } + + /* Line spacing mode */ + { + InkSelectOneActionColumns columns; + + Glib::RefPtr store = Gtk::ListStore::create(columns); + + Gtk::TreeModel::Row row; + + row = *(store->append()); + row[columns.col_label ] = _("Adaptive"); + row[columns.col_tooltip ] = _("Line spacing adapts to font size."); + row[columns.col_icon ] = INKSCAPE_ICON("text_line_spacing"); + row[columns.col_sensitive] = true; + + row = *(store->append()); + row[columns.col_label ] = _("Minimum"); + row[columns.col_tooltip ] = _("Line spacing adapts to fonts size with set minimum spacing."); + row[columns.col_icon ] = INKSCAPE_ICON("text_line_spacing"); + row[columns.col_sensitive] = true; + row = *(store->append()); + row[columns.col_label ] = _("Even"); + row[columns.col_tooltip ] = _("Lines evenly spaced."); + row[columns.col_icon ] = INKSCAPE_ICON("text_line_spacing"); + row[columns.col_sensitive] = true; + + row = *(store->append()); + row[columns.col_label ] = _("Adjustable ☠"); + row[columns.col_tooltip ] = _("Line spacing fully adjustable"); + row[columns.col_icon ] = INKSCAPE_ICON("text_line_spacing"); + row[columns.col_sensitive] = true; + + InkSelectOneAction* act = + InkSelectOneAction::create( "TextLineSpacingAction", // Name + _("Line Spacing Mode"), // Label + _("How should multiple baselines be spaced?\n Adaptive: Line spacing adapts to font size.\n Minimum: Like Adaptive, but with a set minimum.\n Even: Evenly spaced.\n Adjustable: No restrictions."), // Tooltip + "Not Used", // Icon + store ); // Tree store + act->use_radio( false ); + act->use_label( true ); + gint mode = prefs->getInt("/tools/text/line_spacing_mode", 0); + act->set_active( mode ); + + gtk_action_group_add_action( mainActions, GTK_ACTION( act->gobj() )); + g_object_set_data( holder, "TextLineSpacingAction", act ); + + act->signal_changed().connect(sigc::bind<0>(sigc::ptr_fun(&sp_text_line_spacing_mode_changed), holder)); + } + + /* Word spacing */ + { + // Drop down menu + gchar const* labels[] = {_("Negative spacing"), 0, 0, 0, C_("Text tool", "Normal"), 0, 0, 0, 0, 0, 0, 0, _("Positive spacing")}; + gdouble values[] = {-2.0, -1.5, -1.0, -0.5, 0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 4.0, 5.0}; + + EgeAdjustmentAction *eact = create_adjustment_action( + "TextWordSpacingAction", /* name */ + _("Word spacing"), /* label */ + _("Word:"), /* short label */ + _("Spacing between words (px)"), /* tooltip */ + "/tools/text/wordspacing", /* preferences path */ + 0.0, /* default */ + GTK_WIDGET(desktop->canvas), /* focusTarget */ + holder, /* dataKludge */ + FALSE, /* set alt-x keyboard shortcut? */ + NULL, /* altx_mark */ + -100.0, 100.0, 0.01, 0.10, /* lower, upper, step (arrow up/down), page up/down */ + labels, values, G_N_ELEMENTS(labels), /* drop down menu */ + sp_text_wordspacing_value_changed, /* callback */ + NULL, /* unit tracker */ + 0.1, /* step (used?) */ + 2, /* digits to show */ + 1.0 /* factor (multiplies default) */ + ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); + g_object_set_data( holder, "TextWordSpacingAction", eact ); + g_object_set( G_OBJECT(eact), "iconId", "text_word_spacing", NULL ); + } + + /* Letter spacing */ + { + // Drop down menu + gchar const* labels[] = {_("Negative spacing"), 0, 0, 0, C_("Text tool", "Normal"), 0, 0, 0, 0, 0, 0, 0, _("Positive spacing")}; + gdouble values[] = {-2.0, -1.5, -1.0, -0.5, 0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 4.0, 5.0}; + + EgeAdjustmentAction *eact = create_adjustment_action( + "TextLetterSpacingAction", /* name */ + _("Letter spacing"), /* label */ + _("Letter:"), /* short label */ + _("Spacing between letters (px)"), /* tooltip */ + "/tools/text/letterspacing", /* preferences path */ + 0.0, /* default */ + GTK_WIDGET(desktop->canvas), /* focusTarget */ + holder, /* dataKludge */ + FALSE, /* set alt-x keyboard shortcut? */ + NULL, /* altx_mark */ + -100.0, 100.0, 0.01, 0.10, /* lower, upper, step (arrow up/down), page up/down */ + labels, values, G_N_ELEMENTS(labels), /* drop down menu */ + sp_text_letterspacing_value_changed, /* callback */ + NULL, /* unit tracker */ + 0.1, /* step (used?) */ + 2, /* digits to show */ + 1.0 /* factor (multiplies default) */ + ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); + g_object_set_data( holder, "TextLetterSpacingAction", eact ); + g_object_set( G_OBJECT(eact), "iconId", "text_letter_spacing", NULL ); + } + + /* Character kerning (horizontal shift) */ + { + // Drop down menu + gchar const* labels[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + gdouble values[] = { -2.0, -1.5, -1.0, -0.5, 0, 0.5, 1.0, 1.5, 2.0, 2.5 }; + + EgeAdjustmentAction *eact = create_adjustment_action( + "TextDxAction", /* name */ + _("Kerning"), /* label */ + _("Kern:"), /* short label */ + _("Horizontal kerning (px)"), /* tooltip */ + "/tools/text/dx", /* preferences path */ + 0.0, /* default */ + GTK_WIDGET(desktop->canvas), /* focusTarget */ + holder, /* dataKludge */ + FALSE, /* set alt-x keyboard shortcut? */ + NULL, /* altx_mark */ + -100.0, 100.0, 0.01, 0.1, /* lower, upper, step (arrow up/down), page up/down */ + labels, values, G_N_ELEMENTS(labels), /* drop down menu */ + sp_text_dx_value_changed, /* callback */ + NULL, /* unit tracker */ + 0.1, /* step (used?) */ + 2, /* digits to show */ + 1.0 /* factor (multiplies default) */ + ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); + g_object_set_data( holder, "TextDxAction", eact ); + g_object_set( G_OBJECT(eact), "iconId", "text_horz_kern", NULL ); + } + + /* Character vertical shift */ + { + // Drop down menu + gchar const* labels[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + gdouble values[] = { -2.0, -1.5, -1.0, -0.5, 0, 0.5, 1.0, 1.5, 2.0, 2.5 }; + + EgeAdjustmentAction *eact = create_adjustment_action( + "TextDyAction", /* name */ + _("Vertical Shift"), /* label */ + _("Vert:"), /* short label */ + _("Vertical shift (px)"), /* tooltip */ + "/tools/text/dy", /* preferences path */ + 0.0, /* default */ + GTK_WIDGET(desktop->canvas), /* focusTarget */ + holder, /* dataKludge */ + FALSE, /* set alt-x keyboard shortcut? */ + NULL, /* altx_mark */ + -100.0, 100.0, 0.01, 0.1, /* lower, upper, step (arrow up/down), page up/down */ + labels, values, G_N_ELEMENTS(labels), /* drop down menu */ + sp_text_dy_value_changed, /* callback */ + NULL, /* unit tracker */ + 0.1, /* step (used?) */ + 2, /* digits to show */ + 1.0 /* factor (multiplies default) */ + ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); + g_object_set_data( holder, "TextDyAction", eact ); + g_object_set( G_OBJECT(eact), "iconId", "text_vert_kern", NULL ); + } + + /* Character rotation */ + { + // Drop down menu + gchar const* labels[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + gdouble values[] = { -90, -45, -30, -15, 0, 15, 30, 45, 90, 180 }; + + EgeAdjustmentAction *eact = create_adjustment_action( + "TextRotationAction", /* name */ + _("Letter rotation"), /* label */ + _("Rot:"), /* short label */ + _("Character rotation (degrees)"), /* tooltip */ + "/tools/text/rotation", /* preferences path */ + 0.0, /* default */ + GTK_WIDGET(desktop->canvas), /* focusTarget */ + holder, /* dataKludge */ + FALSE, /* set alt-x keyboard shortcut? */ + NULL, /* altx_mark */ + -180.0, 180.0, 0.1, 1.0, /* lower, upper, step (arrow up/down), page up/down */ + labels, values, G_N_ELEMENTS(labels), /* drop down menu */ + sp_text_rotation_value_changed, /* callback */ + NULL, /* unit tracker */ + 0.1, /* step (used?) */ + 2, /* digits to show */ + 1.0 /* factor (multiplies default) */ + ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); + g_object_set_data( holder, "TextRotationAction", eact ); + g_object_set( G_OBJECT(eact), "iconId", "text_rotation", NULL ); + } + + /* Text line height unset */ + { + InkToggleAction* act = ink_toggle_action_new( "TextLineHeightUnsetAction", // Name + _("Unset line height"), // Label + _("If enabled, line height is set on part of selection. Click to unset."), + INKSCAPE_ICON("paint-unknown"), + secondarySize ); // Icon size + gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_text_lineheight_unset_changed), holder ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/text/line_height_unset", false) ); + g_object_set_data( holder, "TextLineHeightUnsetAction", act ); + } + + /* Text outer style */ + { + InkToggleAction* act = ink_toggle_action_new( "TextOuterStyleAction", // Name + _("Show outer style"), // Label + _("Show style of outermost text element. The 'font-size' and 'line-height' values of the outermost text element determine the minimum line spacing in the block."), + INKSCAPE_ICON("text_outer_style"), + secondarySize ); // Icon size + gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_text_outer_style_changed), holder ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/text/outer_style", false) ); + g_object_set_data( holder, "TextOuterStyleAction", act ); + } + + // Is this necessary to call? Shouldn't hurt. + sp_text_toolbox_selection_changed(desktop->getSelection(), holder); + + desktop->connectEventContextChanged(sigc::bind(sigc::ptr_fun(text_toolbox_watch_ec), holder)); + + g_signal_connect( holder, "destroy", G_CALLBACK(purge_repr_listener), holder ); + +} + +static void text_toolbox_watch_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolBase* ec, GObject* holder) { + using sigc::connection; + using sigc::bind; + using sigc::ptr_fun; + + static connection c_selection_changed; + static connection c_selection_modified; + static connection c_subselection_changed; + + if (SP_IS_TEXT_CONTEXT(ec)) { + // Watch selection + + // Ensure FontLister is updated here first.................. VVVVV + c_selection_changed = desktop->getSelection()->connectChangedFirst(bind(ptr_fun(sp_text_toolbox_selection_changed), holder, false)); + c_selection_modified = desktop->getSelection()->connectModifiedFirst(bind(ptr_fun(sp_text_toolbox_selection_modified), holder)); + c_subselection_changed = desktop->connectToolSubselectionChanged(bind(ptr_fun(sp_text_toolbox_subselection_changed), holder)); + } else { + if (c_selection_changed) + c_selection_changed.disconnect(); + if (c_selection_modified) + c_selection_modified.disconnect(); + if (c_subselection_changed) + c_subselection_changed.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:fileencoding=utf-8 : diff --git a/src/ui/toolbar/text-toolbar.h b/src/ui/toolbar/text-toolbar.h new file mode 100644 index 000000000..86a1cad21 --- /dev/null +++ b/src/ui/toolbar/text-toolbar.h @@ -0,0 +1,37 @@ +#ifndef SEEN_TEXT_TOOLBAR_H +#define SEEN_TEXT_TOOLBAR_H + +/** + * @file + * Text aux toolbar + */ +/* Authors: + * MenTaLguY + * Lauris Kaplinski + * bulia byak + * Frank Felfe + * John Cliff + * David Turner + * Josh Andler + * Jon A. Cruz + * Maximilian Albert + * Tavmjong Bah + * Abhishek Sharma + * Kris De Gussem + * + * Copyright (C) 2004 David Turner + * Copyright (C) 2003 MenTaLguY + * Copyright (C) 1999-2011 authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +class SPDesktop; + +typedef struct _GtkActionGroup GtkActionGroup; +typedef struct _GObject GObject; + +void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); + +#endif /* !SEEN_TEXT_TOOLBAR_H */ diff --git a/src/ui/toolbar/tweak-toolbar.cpp b/src/ui/toolbar/tweak-toolbar.cpp new file mode 100644 index 000000000..173e99479 --- /dev/null +++ b/src/ui/toolbar/tweak-toolbar.cpp @@ -0,0 +1,387 @@ +/** + * @file + * Tweak aux toolbar + */ +/* Authors: + * MenTaLguY + * Lauris Kaplinski + * bulia byak + * Frank Felfe + * John Cliff + * David Turner + * Josh Andler + * Jon A. Cruz + * Maximilian Albert + * Tavmjong Bah + * Abhishek Sharma + * Kris De Gussem + * + * Copyright (C) 2004 David Turner + * Copyright (C) 2003 MenTaLguY + * Copyright (C) 1999-2011 authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "tweak-toolbar.h" + +#include "desktop.h" +#include "document-undo.h" + +#include "ui/icon-names.h" +#include "ui/tools/tweak-tool.h" +#include "ui/widget/ink-select-one-action.h" +#include "ui/widget/spinbutton.h" + +#include "widgets/ege-adjustment-action.h" +#include "widgets/ege-output-action.h" +#include "widgets/ink-radio-action.h" +#include "widgets/ink-toggle-action.h" +#include "widgets/toolbox.h" + +using Inkscape::DocumentUndo; +using Inkscape::UI::ToolboxFactory; +using Inkscape::UI::PrefPusher; + + +//######################## +//## Tweak ## +//######################## + +static void sp_tweak_width_value_changed( GtkAdjustment *adj, GObject * /*tbl*/ ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble( "/tools/tweak/width", + gtk_adjustment_get_value(adj) * 0.01 ); +} + +static void sp_tweak_force_value_changed( GtkAdjustment *adj, GObject * /*tbl*/ ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble( "/tools/tweak/force", + gtk_adjustment_get_value(adj) * 0.01 ); +} + +static void sp_tweak_pressure_state_changed( GtkToggleAction *act, gpointer /*data*/ ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setBool("/tools/tweak/usepressure", gtk_toggle_action_get_active(act)); +} + +static void sp_tweak_mode_changed( GObject *tbl, int mode ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setInt("/tools/tweak/mode", mode); + + static gchar const* names[] = {"tweak_doh", "tweak_dos", "tweak_dol", "tweak_doo", "tweak_channels_label"}; + bool flag = ((mode == Inkscape::UI::Tools::TWEAK_MODE_COLORPAINT) || + (mode == Inkscape::UI::Tools::TWEAK_MODE_COLORJITTER)); + for (size_t i = 0; i < G_N_ELEMENTS(names); ++i) { + GtkAction *act = GTK_ACTION(g_object_get_data( tbl, names[i] )); + if (act) { + gtk_action_set_visible(act, flag); + } + } + GtkAction *fid = GTK_ACTION(g_object_get_data( tbl, "tweak_fidelity")); + if (fid) { + gtk_action_set_visible(fid, !flag); + } +} + +static void sp_tweak_fidelity_value_changed( GtkAdjustment *adj, GObject * /*tbl*/ ) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble( "/tools/tweak/fidelity", + gtk_adjustment_get_value(adj) * 0.01 ); +} + +static void tweak_toggle_doh(GtkToggleAction *act, gpointer /*data*/) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setBool("/tools/tweak/doh", gtk_toggle_action_get_active(act)); +} +static void tweak_toggle_dos(GtkToggleAction *act, gpointer /*data*/) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setBool("/tools/tweak/dos", gtk_toggle_action_get_active(act)); +} +static void tweak_toggle_dol(GtkToggleAction *act, gpointer /*data*/) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setBool("/tools/tweak/dol", gtk_toggle_action_get_active(act)); +} +static void tweak_toggle_doo(GtkToggleAction *act, gpointer /*data*/) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setBool("/tools/tweak/doo", gtk_toggle_action_get_active(act)); +} + +void sp_tweak_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) +{ + GtkIconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + + { + /* Width */ + gchar const* labels[] = {_("(pinch tweak)"), 0, 0, 0, _("(default)"), 0, 0, 0, 0, _("(broad tweak)")}; + gdouble values[] = {1, 3, 5, 10, 15, 20, 30, 50, 75, 100}; + EgeAdjustmentAction *eact = create_adjustment_action( "TweakWidthAction", + _("Width"), _("Width:"), _("The width of the tweak area (relative to the visible canvas area)"), + "/tools/tweak/width", 15, + GTK_WIDGET(desktop->canvas), holder, TRUE, "altx-tweak", + 1, 100, 1.0, 10.0, + labels, values, G_N_ELEMENTS(labels), + sp_tweak_width_value_changed, NULL /*unit tracker*/, 0.01, 0, 100 ); + ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); + } + + + { + /* Force */ + gchar const* labels[] = {_("(minimum force)"), 0, 0, _("(default)"), 0, 0, 0, _("(maximum force)")}; + gdouble values[] = {1, 5, 10, 20, 30, 50, 70, 100}; + EgeAdjustmentAction *eact = create_adjustment_action( "TweakForceAction", + _("Force"), _("Force:"), _("The force of the tweak action"), + "/tools/tweak/force", 20, + GTK_WIDGET(desktop->canvas), holder, TRUE, "tweak-force", + 1, 100, 1.0, 10.0, + labels, values, G_N_ELEMENTS(labels), + sp_tweak_force_value_changed, NULL /*unit tracker*/, 0.01, 0, 100 ); + ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); + } + + /* Mode */ + { + InkSelectOneActionColumns columns; + + Glib::RefPtr store = Gtk::ListStore::create(columns); + + Gtk::TreeModel::Row row; + + row = *(store->append()); + row[columns.col_label ] = _("Move mode"); + row[columns.col_tooltip ] = _("Move objects in any direction"); + row[columns.col_icon ] = INKSCAPE_ICON("object-tweak-push"); + row[columns.col_sensitive] = true; + + row = *(store->append()); + row[columns.col_label ] = _("Move in/out mode"); + row[columns.col_tooltip ] = _("Move objects towards cursor; with Shift from cursor"); + row[columns.col_icon ] = INKSCAPE_ICON("object-tweak-attract"); + row[columns.col_sensitive] = true; + + row = *(store->append()); + row[columns.col_label ] = _("Move jitter mode"); + row[columns.col_tooltip ] = _("Move objects in random directions"); + row[columns.col_icon ] = INKSCAPE_ICON("object-tweak-randomize"); + row[columns.col_sensitive] = true; + + row = *(store->append()); + row[columns.col_label ] = _("Scale mode"); + row[columns.col_tooltip ] = _("Shrink objects, with Shift enlarge"); + row[columns.col_icon ] = INKSCAPE_ICON("object-tweak-shrink"); + row[columns.col_sensitive] = true; + + row = *(store->append()); + row[columns.col_label ] = _("Rotate mode"); + row[columns.col_tooltip ] = _("Rotate objects, with Shift counterclockwise"); + row[columns.col_icon ] = INKSCAPE_ICON("object-tweak-rotate"); + row[columns.col_sensitive] = true; + + row = *(store->append()); + row[columns.col_label ] = _("Duplicate/delete mode"); + row[columns.col_tooltip ] = _("Duplicate objects, with Shift delete"); + row[columns.col_icon ] = INKSCAPE_ICON("object-tweak-duplicate"); + row[columns.col_sensitive] = true; + + row = *(store->append()); + row[columns.col_label ] = _("Push mode"); + row[columns.col_tooltip ] = _("Push parts of paths in any direction"); + row[columns.col_icon ] = INKSCAPE_ICON("path-tweak-push"); + row[columns.col_sensitive] = true; + + row = *(store->append()); + row[columns.col_label ] = _("Shrink/grow mode"); + row[columns.col_tooltip ] = _("Shrink (inset) parts of paths; with Shift grow (outset)"); + row[columns.col_icon ] = INKSCAPE_ICON("path-tweak-shrink"); + row[columns.col_sensitive] = true; + + row = *(store->append()); + row[columns.col_label ] = _("Attract/repel mode"); + row[columns.col_tooltip ] = _("Attract parts of paths towards cursor; with Shift from cursor"); + row[columns.col_icon ] = INKSCAPE_ICON("path-tweak-attract"); + row[columns.col_sensitive] = true; + + row = *(store->append()); + row[columns.col_label ] = _("Roughen mode"); + row[columns.col_tooltip ] = _("Roughen parts of paths"); + row[columns.col_icon ] = INKSCAPE_ICON("path-tweak-roughen"); + row[columns.col_sensitive] = true; + + row = *(store->append()); + row[columns.col_label ] = _("Color paint mode"); + row[columns.col_tooltip ] = _("Paint the tool's color upon selected objects"); + row[columns.col_icon ] = INKSCAPE_ICON("object-tweak-paint"); + row[columns.col_sensitive] = true; + + row = *(store->append()); + row[columns.col_label ] = _("Color jitter mode"); + row[columns.col_tooltip ] = _("Jitter the colors of selected objects"); + row[columns.col_icon ] = INKSCAPE_ICON("object-tweak-jitter-color"); + row[columns.col_sensitive] = true; + + row = *(store->append()); + row[columns.col_label ] = _("Blur mode"); + row[columns.col_tooltip ] = _("Blur selected objects more; with Shift, blur less"); + row[columns.col_icon ] = INKSCAPE_ICON("object-tweak-blur"); + row[columns.col_sensitive] = true; + + InkSelectOneAction* act = + InkSelectOneAction::create( "TweakModeAction", // Name + _("Mode"), // Label + (""), // Tooltip + "Not Used", // Icon + store ); // Tree store + + act->use_radio( true ); + act->use_icon( true ); + act->use_label( false ); + act->use_group_label( true ); + int mode = prefs->getInt("/tools/tweak/mode", 0); + act->set_active( mode ); + + gtk_action_group_add_action( mainActions, GTK_ACTION( act->gobj() )); + g_object_set_data( holder, "tweak_tool_mode", act ); + + act->signal_changed().connect(sigc::bind<0>(sigc::ptr_fun(&sp_tweak_mode_changed), holder)); + } + + guint mode = prefs->getInt("/tools/tweak/mode", 0); + + { + EgeOutputAction* act = ege_output_action_new( "TweakChannelsLabel", _("Channels:"), "", 0 ); + ege_output_action_set_use_markup( act, TRUE ); + gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); + if (mode != Inkscape::UI::Tools::TWEAK_MODE_COLORPAINT && mode != Inkscape::UI::Tools::TWEAK_MODE_COLORJITTER) { + gtk_action_set_visible (GTK_ACTION(act), FALSE); + } + g_object_set_data( holder, "tweak_channels_label", act); + } + + { + InkToggleAction* act = ink_toggle_action_new( "TweakDoH", + _("Hue"), + _("In color mode, act on objects' hue"), + NULL, + GTK_ICON_SIZE_MENU ); + //TRANSLATORS: "H" here stands for hue + g_object_set( act, "short_label", C_("Hue", "H"), NULL ); + gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(tweak_toggle_doh), desktop ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/tweak/doh", true) ); + if (mode != Inkscape::UI::Tools::TWEAK_MODE_COLORPAINT && mode != Inkscape::UI::Tools::TWEAK_MODE_COLORJITTER) { + gtk_action_set_visible (GTK_ACTION(act), FALSE); + } + g_object_set_data( holder, "tweak_doh", act); + } + { + InkToggleAction* act = ink_toggle_action_new( "TweakDoS", + _("Saturation"), + _("In color mode, act on objects' saturation"), + NULL, + GTK_ICON_SIZE_MENU ); + //TRANSLATORS: "S" here stands for Saturation + g_object_set( act, "short_label", C_("Saturation", "S"), NULL ); + gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(tweak_toggle_dos), desktop ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/tweak/dos", true) ); + if (mode != Inkscape::UI::Tools::TWEAK_MODE_COLORPAINT && mode != Inkscape::UI::Tools::TWEAK_MODE_COLORJITTER) { + gtk_action_set_visible (GTK_ACTION(act), FALSE); + } + g_object_set_data( holder, "tweak_dos", act ); + } + { + InkToggleAction* act = ink_toggle_action_new( "TweakDoL", + _("Lightness"), + _("In color mode, act on objects' lightness"), + NULL, + GTK_ICON_SIZE_MENU ); + //TRANSLATORS: "L" here stands for Lightness + g_object_set( act, "short_label", C_("Lightness", "L"), NULL ); + gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(tweak_toggle_dol), desktop ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/tweak/dol", true) ); + if (mode != Inkscape::UI::Tools::TWEAK_MODE_COLORPAINT && mode != Inkscape::UI::Tools::TWEAK_MODE_COLORJITTER) { + gtk_action_set_visible (GTK_ACTION(act), FALSE); + } + g_object_set_data( holder, "tweak_dol", act ); + } + { + InkToggleAction* act = ink_toggle_action_new( "TweakDoO", + _("Opacity"), + _("In color mode, act on objects' opacity"), + NULL, + GTK_ICON_SIZE_MENU ); + //TRANSLATORS: "O" here stands for Opacity + g_object_set( act, "short_label", C_("Opacity", "O"), NULL ); + gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(tweak_toggle_doo), desktop ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/tweak/doo", true) ); + if (mode != Inkscape::UI::Tools::TWEAK_MODE_COLORPAINT && mode != Inkscape::UI::Tools::TWEAK_MODE_COLORJITTER) { + gtk_action_set_visible (GTK_ACTION(act), FALSE); + } + g_object_set_data( holder, "tweak_doo", act ); + } + + { /* Fidelity */ + gchar const* labels[] = {_("(rough, simplified)"), 0, 0, _("(default)"), 0, 0, _("(fine, but many nodes)")}; + gdouble values[] = {10, 25, 35, 50, 60, 80, 100}; + EgeAdjustmentAction *eact = create_adjustment_action( "TweakFidelityAction", + _("Fidelity"), _("Fidelity:"), + _("Low fidelity simplifies paths; high fidelity preserves path features but may generate a lot of new nodes"), + "/tools/tweak/fidelity", 50, + GTK_WIDGET(desktop->canvas), holder, TRUE, "tweak-fidelity", + 1, 100, 1.0, 10.0, + labels, values, G_N_ELEMENTS(labels), + sp_tweak_fidelity_value_changed, NULL /*unit tracker*/, 0.01, 0, 100 ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + gtk_action_set_visible( GTK_ACTION(eact), TRUE ); + if (mode == Inkscape::UI::Tools::TWEAK_MODE_COLORPAINT || mode == Inkscape::UI::Tools::TWEAK_MODE_COLORJITTER) { + gtk_action_set_visible (GTK_ACTION(eact), FALSE); + } + g_object_set_data( holder, "tweak_fidelity", eact ); + } + + + /* Use Pressure button */ + { + InkToggleAction* act = ink_toggle_action_new( "TweakPressureAction", + _("Pressure"), + _("Use the pressure of the input device to alter the force of tweak action"), + INKSCAPE_ICON("draw-use-pressure"), + GTK_ICON_SIZE_MENU ); + gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_tweak_pressure_state_changed), NULL); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/tweak/usepressure", true) ); + } + +} + + +/* + 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:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/toolbar/tweak-toolbar.h b/src/ui/toolbar/tweak-toolbar.h new file mode 100644 index 000000000..1a65a0844 --- /dev/null +++ b/src/ui/toolbar/tweak-toolbar.h @@ -0,0 +1,37 @@ +#ifndef SEEN_TWEAK_TOOLBAR_H +#define SEEN_TWEAK_TOOLBAR_H + +/** + * @file + * Tweak aux toolbar + */ +/* Authors: + * MenTaLguY + * Lauris Kaplinski + * bulia byak + * Frank Felfe + * John Cliff + * David Turner + * Josh Andler + * Jon A. Cruz + * Maximilian Albert + * Tavmjong Bah + * Abhishek Sharma + * Kris De Gussem + * + * Copyright (C) 2004 David Turner + * Copyright (C) 2003 MenTaLguY + * Copyright (C) 1999-2011 authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +class SPDesktop; + +typedef struct _GtkActionGroup GtkActionGroup; +typedef struct _GObject GObject; + +void sp_tweak_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); + +#endif /* !SEEN_SELECT_TOOLBAR_H */ diff --git a/src/ui/toolbar/zoom-toolbar.cpp b/src/ui/toolbar/zoom-toolbar.cpp new file mode 100644 index 000000000..a961c0061 --- /dev/null +++ b/src/ui/toolbar/zoom-toolbar.cpp @@ -0,0 +1,51 @@ +/** + * @file + * Zoom aux toolbar + */ +/* Authors: + * MenTaLguY + * Lauris Kaplinski + * bulia byak + * Frank Felfe + * John Cliff + * David Turner + * Josh Andler + * Jon A. Cruz + * Maximilian Albert + * Tavmjong Bah + * Abhishek Sharma + * Kris De Gussem + * + * Copyright (C) 2004 David Turner + * Copyright (C) 2003 MenTaLguY + * Copyright (C) 1999-2011 authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "zoom-toolbar.h" + +//######################## +//## Zoom Toolbox ## +//######################## + +void sp_zoom_toolbox_prep(SPDesktop * /*desktop*/, GtkActionGroup* /*mainActions*/, GObject* /*holder*/) +{ + // no custom GtkAction setup needed +} // end of sp_zoom_toolbox_prep() + +/* + 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:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/toolbar/zoom-toolbar.h b/src/ui/toolbar/zoom-toolbar.h new file mode 100644 index 000000000..45d979066 --- /dev/null +++ b/src/ui/toolbar/zoom-toolbar.h @@ -0,0 +1,37 @@ +#ifndef SEEN_ZOOM_TOOLBAR_H +#define SEEN_ZOOM_TOOLBAR_H + +/** + * @file + * Zoom aux toolbar + */ +/* Authors: + * MenTaLguY + * Lauris Kaplinski + * bulia byak + * Frank Felfe + * John Cliff + * David Turner + * Josh Andler + * Jon A. Cruz + * Maximilian Albert + * Tavmjong Bah + * Abhishek Sharma + * Kris De Gussem + * + * Copyright (C) 2004 David Turner + * Copyright (C) 2003 MenTaLguY + * Copyright (C) 1999-2011 authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +class SPDesktop; + +typedef struct _GtkActionGroup GtkActionGroup; +typedef struct _GObject GObject; + +void sp_zoom_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); + +#endif /* !SEEN_ZOOM_TOOLBAR_H */ diff --git a/src/ui/widget/font-selector-toolbar.cpp b/src/ui/widget/font-selector-toolbar.cpp index 4f951fa62..87dadf211 100644 --- a/src/ui/widget/font-selector-toolbar.cpp +++ b/src/ui/widget/font-selector-toolbar.cpp @@ -28,7 +28,7 @@ #include "object/sp-text.h" // TEMP TEMP TEMP -#include "widgets/text-toolbar.h" +#include "ui/toolbar/text-toolbar.h" /* To do: * Fix altx. Need to store diff --git a/src/widgets/CMakeLists.txt b/src/widgets/CMakeLists.txt index d9a5c2922..052e82347 100644 --- a/src/widgets/CMakeLists.txt +++ b/src/widgets/CMakeLists.txt @@ -1,37 +1,23 @@ add_subdirectory(gimp) set(widgets_SRC - arc-toolbar.cpp - box3d-toolbar.cpp button.cpp - calligraphy-toolbar.cpp - connector-toolbar.cpp dash-selector.cpp desktop-widget.cpp - dropper-toolbar.cpp eek-preview.cpp ege-adjustment-action.cpp ege-output-action.cpp ege-paint-def.cpp - eraser-toolbar.cpp fill-style.cpp gradient-image.cpp gradient-selector.cpp - gradient-toolbar.cpp gradient-vector.cpp ink-action.cpp ink-comboboxentry-action.cpp ink-radio-action.cpp ink-toggle-action.cpp ink-tool-menu-action.cpp - lpe-toolbar.cpp - measure-toolbar.cpp - mesh-toolbar.cpp - node-toolbar.cpp paint-selector.cpp - pencil-toolbar.cpp - rect-toolbar.cpp - select-toolbar.cpp sp-attribute-widget.cpp sp-color-selector.cpp sp-widget.cpp @@ -39,53 +25,32 @@ set(widgets_SRC sp-xmlview-content.cpp sp-xmlview-tree.cpp spinbutton-events.cpp - spiral-toolbar.cpp - spray-toolbar.cpp spw-utilities.cpp - star-toolbar.cpp stroke-marker-selector.cpp stroke-style.cpp swatch-selector.cpp - text-toolbar.cpp toolbox.cpp - tweak-toolbar.cpp - zoom-toolbar.cpp - # ------- # Headers - arc-toolbar.h - box3d-toolbar.h button.h - calligraphy-toolbar.h - connector-toolbar.h dash-selector.h desktop-widget.h - dropper-toolbar.h eek-preview.h ege-adjustment-action.h ege-output-action.h ege-paint-def.h - eraser-toolbar.h fill-n-stroke-factory.h fill-style.h gradient-image.h gradient-selector.h - gradient-toolbar.h gradient-vector.h ink-action.h ink-comboboxentry-action.h ink-radio-action.h ink-toggle-action.h ink-tool-menu-action.h - lpe-toolbar.h - measure-toolbar.h - mesh-toolbar.h - node-toolbar.h paint-selector.h - pencil-toolbar.h - rect-toolbar.h - select-toolbar.h sp-attribute-widget.h sp-color-selector.h sp-widget.h @@ -93,29 +58,12 @@ set(widgets_SRC sp-xmlview-content.h sp-xmlview-tree.h spinbutton-events.h - spiral-toolbar.h - spray-toolbar.h spw-utilities.h - star-toolbar.h stroke-marker-selector.h stroke-style.h swatch-selector.h - text-toolbar.h toolbox.h - tweak-toolbar.h widget-sizes.h - zoom-toolbar.h ) -# add_inkscape_lib(widgets_LIB "${widgets_SRC}") add_inkscape_source("${widgets_SRC}") - -set(widgets_paintbucket_SRC - paintbucket-toolbar.cpp - paintbucket-toolbar.h -) - -if ("${HAVE_POTRACE}") - add_inkscape_source("${widgets_paintbucket_SRC}") -endif() - diff --git a/src/widgets/arc-toolbar.cpp b/src/widgets/arc-toolbar.cpp deleted file mode 100644 index 8b779ca6a..000000000 --- a/src/widgets/arc-toolbar.cpp +++ /dev/null @@ -1,615 +0,0 @@ -/** - * @file - * Arc aux toolbar - */ -/* Authors: - * MenTaLguY - * Lauris Kaplinski - * bulia byak - * Frank Felfe - * John Cliff - * David Turner - * Josh Andler - * Jon A. Cruz - * Maximilian Albert - * Tavmjong Bah - * Abhishek Sharma - * Kris De Gussem - * - * Copyright (C) 2004 David Turner - * Copyright (C) 2003 MenTaLguY - * Copyright (C) 1999-2011 authors - * Copyright (C) 2001-2002 Ximian, Inc. - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "arc-toolbar.h" - -#include - -#include "desktop.h" -#include "document-undo.h" -#include "ink-action.h" -#include "ink-radio-action.h" -#include "mod360.h" -#include "selection.h" -#include "toolbox.h" -#include "verbs.h" - -#include "object/sp-ellipse.h" - -#include "ui/icon-names.h" -#include "ui/tools/arc-tool.h" -#include "ui/uxmanager.h" -#include "ui/widget/ink-select-one-action.h" -#include "ui/widget/unit-tracker.h" - -#include "widgets/ege-adjustment-action.h" -#include "widgets/ege-output-action.h" -#include "widgets/spinbutton-events.h" -#include "widgets/widget-sizes.h" - -#include "xml/node-event-vector.h" - -using Inkscape::UI::Widget::UnitTracker; -using Inkscape::UI::UXManager; -using Inkscape::DocumentUndo; -using Inkscape::UI::ToolboxFactory; -using Inkscape::UI::PrefPusher; -using Inkscape::Util::Quantity; -using Inkscape::Util::unit_table; - -//######################## -//## Circle / Arc ## -//######################## - -static void sp_arctb_sensitivize( GObject *tbl, double v1, double v2 ) -{ - Gtk::Action *ocb = static_cast( g_object_get_data( tbl, "type_action" ) ); - GtkAction *make_whole = GTK_ACTION( g_object_get_data( tbl, "make_whole" ) ); - - if (v1 == 0 && v2 == 0) { - if (g_object_get_data( tbl, "single" )) { // only for a single selected ellipse (for now) - ocb->set_sensitive(false); - gtk_action_set_sensitive( make_whole, FALSE ); - } - } else { - ocb->set_sensitive(true); - gtk_action_set_sensitive( make_whole, TRUE ); - } -} - -static void sp_arctb_value_changed(GtkAdjustment *adj, GObject *tbl, gchar const *value_name) -{ - // Per SVG spec "a [radius] value of zero disables rendering of the element". - // However our implementation does not allow a setting of zero in the UI (not even in the XML editor) - // and ugly things happen if it's forced here, so better leave the properties untouched. - if (!gtk_adjustment_get_value(adj)) { - return; - } - - SPDesktop *desktop = static_cast(g_object_get_data( tbl, "desktop" )); - - UnitTracker* tracker = reinterpret_cast(g_object_get_data( tbl, "tracker" )); - Unit const *unit = tracker->getActiveUnit(); - g_return_if_fail(unit != NULL); - - SPDocument* document = desktop->getDocument(); - Geom::Scale scale = document->getDocumentScale(); - - if (DocumentUndo::getUndoSensitive(document)) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble(Glib::ustring("/tools/shapes/arc/") + value_name, - Quantity::convert(gtk_adjustment_get_value(adj), unit, "px")); - } - - // quit if run by the attr_changed listener - if (g_object_get_data( tbl, "freeze" ) || tracker->isUpdating()) { - return; - } - - // in turn, prevent listener from responding - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE)); - - bool modmade = false; - Inkscape::Selection *selection = desktop->getSelection(); - auto itemlist= selection->items(); - for(auto i=itemlist.begin();i!=itemlist.end();++i){ - SPItem *item = *i; - if (SP_IS_GENERICELLIPSE(item)) { - - SPGenericEllipse *ge = SP_GENERICELLIPSE(item); - - if (!strcmp(value_name, "rx")) { - ge->setVisibleRx(Quantity::convert(gtk_adjustment_get_value(adj), unit, "px")); - } else { - ge->setVisibleRy(Quantity::convert(gtk_adjustment_get_value(adj), unit, "px")); - } - - ge->normalize(); - (SP_OBJECT(ge))->updateRepr(); - (SP_OBJECT(ge))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - - modmade = true; - } - } - - if (modmade) { - DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_ARC, - _("Ellipse: Change radius")); - } - - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -} - -static void sp_arctb_rx_value_changed(GtkAdjustment *adj, GObject *tbl) -{ - sp_arctb_value_changed(adj, tbl, "rx"); -} - -static void sp_arctb_ry_value_changed(GtkAdjustment *adj, GObject *tbl) -{ - sp_arctb_value_changed(adj, tbl, "ry"); -} - -static void -sp_arctb_startend_value_changed(GtkAdjustment *adj, GObject *tbl, gchar const *value_name, gchar const *other_name) -{ - SPDesktop *desktop = static_cast(g_object_get_data( tbl, "desktop" )); - - if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble(Glib::ustring("/tools/shapes/arc/") + value_name, gtk_adjustment_get_value(adj)); - } - - // quit if run by the attr_changed listener - if (g_object_get_data( tbl, "freeze" )) { - return; - } - - // in turn, prevent listener from responding - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - - gchar* namespaced_name = g_strconcat("sodipodi:", value_name, NULL); - - bool modmade = false; - auto itemlist= desktop->getSelection()->items(); - for(auto i=itemlist.begin();i!=itemlist.end();++i){ - SPItem *item = *i; - if (SP_IS_GENERICELLIPSE(item)) { - - SPGenericEllipse *ge = SP_GENERICELLIPSE(item); - - if (!strcmp(value_name, "start")) { - ge->start = (gtk_adjustment_get_value(adj) * M_PI)/ 180; - } else { - ge->end = (gtk_adjustment_get_value(adj) * M_PI)/ 180; - } - - ge->normalize(); - (SP_OBJECT(ge))->updateRepr(); - (SP_OBJECT(ge))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - - modmade = true; - } - } - - g_free(namespaced_name); - - GtkAdjustment *other = GTK_ADJUSTMENT( g_object_get_data( tbl, other_name ) ); - - sp_arctb_sensitivize( tbl, gtk_adjustment_get_value(adj), gtk_adjustment_get_value(other) ); - - if (modmade) { - DocumentUndo::maybeDone(desktop->getDocument(), value_name, SP_VERB_CONTEXT_ARC, - _("Arc: Change start/end")); - } - - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -} - - -static void sp_arctb_start_value_changed(GtkAdjustment *adj, GObject *tbl) -{ - sp_arctb_startend_value_changed(adj, tbl, "start", "end"); -} - -static void sp_arctb_end_value_changed(GtkAdjustment *adj, GObject *tbl) -{ - sp_arctb_startend_value_changed(adj, tbl, "end", "start"); -} - - -static void sp_arctb_type_changed( GObject *tbl, int type ) -{ - SPDesktop *desktop = static_cast(g_object_get_data( tbl, "desktop" )); - if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setInt("/tools/shapes/arc/arc_type", type); - } - - // quit if run by the attr_changed listener - if (g_object_get_data( tbl, "freeze" )) { - return; - } - - // in turn, prevent listener from responding - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - - Glib::ustring arc_type = "slice"; - bool open = false; - switch (type) { - case 0: - arc_type = "slice"; - open = false; - break; - case 1: - arc_type = "arc"; - open = true; - break; - case 2: - arc_type = "chord"; - open = true; // For backward compat, not truly open but chord most like arc. - break; - default: - std::cerr << "sp_arctb_type_changed: bad arc type: " << type << std::endl; - } - - bool modmade = false; - auto itemlist= desktop->getSelection()->items(); - for(auto i=itemlist.begin();i!=itemlist.end();++i){ - SPItem *item = *i; - if (SP_IS_GENERICELLIPSE(item)) { - Inkscape::XML::Node *repr = item->getRepr(); - repr->setAttribute("sodipodi:open", (open?"true":NULL) ); - repr->setAttribute("sodipodi:arc-type", arc_type.c_str()); - item->updateRepr(); - modmade = true; - } - } - - if (modmade) { - DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_ARC, - _("Arc: Changed arc type")); - } - - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -} - -static void sp_arctb_defaults(GtkWidget *, GObject *obj) -{ - GtkAdjustment *adj; - - adj = GTK_ADJUSTMENT( g_object_get_data(obj, "start") ); - gtk_adjustment_set_value(adj, 0.0); - -#if !GTK_CHECK_VERSION(3,18,0) - gtk_adjustment_value_changed(adj); -#endif - - adj = GTK_ADJUSTMENT( g_object_get_data(obj, "end") ); - gtk_adjustment_set_value(adj, 0.0); - -#if !GTK_CHECK_VERSION(3,18,0) - gtk_adjustment_value_changed(adj); -#endif - - spinbutton_defocus(GTK_WIDGET(obj)); -} - -static void arc_tb_event_attr_changed(Inkscape::XML::Node *repr, gchar const * /*name*/, - gchar const * /*old_value*/, gchar const * /*new_value*/, - bool /*is_interactive*/, gpointer data) -{ - GObject *tbl = G_OBJECT(data); - - // quit if run by the _changed callbacks - if (g_object_get_data( tbl, "freeze" )) { - return; - } - - // in turn, prevent callbacks from responding - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - - gpointer item = g_object_get_data( tbl, "item" ); - if (item && SP_IS_GENERICELLIPSE(item)) { - SPGenericEllipse *ge = SP_GENERICELLIPSE(item); - - UnitTracker* tracker = reinterpret_cast( g_object_get_data( tbl, "tracker" ) ); - Unit const *unit = tracker->getActiveUnit(); - g_return_if_fail(unit != NULL); - - GtkAdjustment *adj; - adj = GTK_ADJUSTMENT( g_object_get_data(tbl, "rx") ); - gdouble rx = ge->getVisibleRx(); - gtk_adjustment_set_value(adj, Quantity::convert(rx, "px", unit)); - -#if !GTK_CHECK_VERSION(3,18,0) - gtk_adjustment_value_changed(adj); -#endif - - adj = GTK_ADJUSTMENT( g_object_get_data(tbl, "ry") ); - gdouble ry = ge->getVisibleRy(); - gtk_adjustment_set_value(adj, Quantity::convert(ry, "px", unit)); - -#if !GTK_CHECK_VERSION(3,18,0) - gtk_adjustment_value_changed(adj); -#endif - } - - gdouble start = 0.; - gdouble end = 0.; - sp_repr_get_double(repr, "sodipodi:start", &start); - sp_repr_get_double(repr, "sodipodi:end", &end); - - GtkAdjustment *adj1,*adj2; - adj1 = GTK_ADJUSTMENT( g_object_get_data( tbl, "start" ) ); - gtk_adjustment_set_value(adj1, mod360((start * 180)/M_PI)); - adj2 = GTK_ADJUSTMENT( g_object_get_data( tbl, "end" ) ); - gtk_adjustment_set_value(adj2, mod360((end * 180)/M_PI)); - - sp_arctb_sensitivize( tbl, gtk_adjustment_get_value(adj1), gtk_adjustment_get_value(adj2) ); - - char const *arctypestr = NULL; - arctypestr = repr->attribute("sodipodi:arc-type"); - if (!arctypestr) { // For old files. - char const *openstr = NULL; - openstr = repr->attribute("sodipodi:open"); - arctypestr = (openstr ? "arc" : "slice"); - } - - InkSelectOneAction *typeAction = - static_cast( g_object_get_data( tbl, "type_action" ) ); - - if (!strcmp(arctypestr,"slice")) { - typeAction->set_active( 0 ); - } else if (!strcmp(arctypestr,"arc")) { - typeAction->set_active( 1 ); - } else { - typeAction->set_active( 2 ); - } - - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -} - -static Inkscape::XML::NodeEventVector arc_tb_repr_events = { - NULL, /* child_added */ - NULL, /* child_removed */ - arc_tb_event_attr_changed, - NULL, /* content_changed */ - NULL /* order_changed */ -}; - - -static void sp_arc_toolbox_selection_changed(Inkscape::Selection *selection, GObject *tbl) -{ - int n_selected = 0; - Inkscape::XML::Node *repr = NULL; - SPItem *item = NULL; - - if ( g_object_get_data( tbl, "repr" ) ) { - g_object_set_data( tbl, "item", NULL ); - } - purge_repr_listener( tbl, tbl ); - - auto itemlist= selection->items(); - for(auto i=itemlist.begin();i!=itemlist.end();++i){ - if (SP_IS_GENERICELLIPSE(*i)) { - n_selected++; - item = *i; - repr = item->getRepr(); - } - } - - EgeOutputAction* act = EGE_OUTPUT_ACTION( g_object_get_data( tbl, "mode_action" ) ); - - g_object_set_data( tbl, "single", GINT_TO_POINTER(FALSE) ); - if (n_selected == 0) { - g_object_set( G_OBJECT(act), "label", _("New:"), NULL ); - } else if (n_selected == 1) { - g_object_set_data( tbl, "single", GINT_TO_POINTER(TRUE) ); - g_object_set( G_OBJECT(act), "label", _("Change:"), NULL ); - - GtkAction* rx = GTK_ACTION( g_object_get_data( tbl, "rx_action" ) ); - gtk_action_set_sensitive(rx, TRUE); - GtkAction* ry = GTK_ACTION( g_object_get_data( tbl, "ry_action" ) ); - gtk_action_set_sensitive(ry, TRUE); - - if (repr) { - g_object_set_data( tbl, "repr", repr ); - g_object_set_data( tbl, "item", item ); - Inkscape::GC::anchor(repr); - sp_repr_add_listener(repr, &arc_tb_repr_events, tbl); - sp_repr_synthesize_events(repr, &arc_tb_repr_events, tbl); - } - } else { - // FIXME: implement averaging of all parameters for multiple selected - //gtk_label_set_markup(GTK_LABEL(l), _("Average:")); - g_object_set( G_OBJECT(act), "label", _("Change:"), NULL ); - sp_arctb_sensitivize( tbl, 1, 0 ); - } -} - -static void arc_toolbox_check_ec(SPDesktop* dt, Inkscape::UI::Tools::ToolBase* ec, GObject* holder); - -void sp_arc_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - - EgeAdjustmentAction* eact = 0; - GtkIconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1); - - UnitTracker* tracker = new UnitTracker(Inkscape::Util::UNIT_TYPE_LINEAR); - tracker->setActiveUnit(unit_table.getUnit("px")); - g_object_set_data( holder, "tracker", tracker ); - - { - EgeOutputAction* act = ege_output_action_new( "ArcStateAction", _("New:"), "", 0 ); - ege_output_action_set_use_markup( act, TRUE ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - g_object_set_data( holder, "mode_action", act ); - } - - /* Radius X */ - { - gchar const* labels[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - gdouble values[] = {1, 2, 3, 5, 10, 20, 50, 100, 200, 500}; - eact = create_adjustment_action( "ArcRadiusXAction", - _("Horizontal radius"), _("Rx:"), _("Horizontal radius of the circle, ellipse, or arc"), - "/tools/shapes/arc/rx", 0, - GTK_WIDGET(desktop->canvas), holder, TRUE, "altx-arc", - 0, 1e6, SPIN_STEP, SPIN_PAGE_STEP, - labels, values, G_N_ELEMENTS(labels), - sp_arctb_rx_value_changed, tracker); - g_object_set_data( holder, "rx_action", eact ); - gtk_action_set_sensitive( GTK_ACTION(eact), FALSE ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - } - - /* Radius Y */ - { - gchar const* labels[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - gdouble values[] = {1, 2, 3, 5, 10, 20, 50, 100, 200, 500}; - eact = create_adjustment_action( "ArcRadiusYAction", - _("Vertical radius"), _("Ry:"), _("Vertical radius of the circle, ellipse, or arc"), - "/tools/shapes/arc/ry", 0, - GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, - 0, 1e6, SPIN_STEP, SPIN_PAGE_STEP, - labels, values, G_N_ELEMENTS(labels), - sp_arctb_ry_value_changed, tracker); - g_object_set_data( holder, "ry_action", eact ); - gtk_action_set_sensitive( GTK_ACTION(eact), FALSE ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - } - - // add the units menu - { - Gtk::Action* act = tracker->createAction( "ArcUnitsAction", _("Units"), ("") ); - gtk_action_group_add_action( mainActions, act->gobj() ); - } - - /* Start */ - { - eact = create_adjustment_action( "ArcStartAction", - _("Start"), _("Start:"), - _("The angle (in degrees) from the horizontal to the arc's start point"), - "/tools/shapes/arc/start", 0.0, - GTK_WIDGET(desktop->canvas), holder, TRUE, "altx-arc", - -360.0, 360.0, 1.0, 10.0, - 0, 0, 0, - sp_arctb_start_value_changed); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - } - - /* End */ - { - eact = create_adjustment_action( "ArcEndAction", - _("End"), _("End:"), - _("The angle (in degrees) from the horizontal to the arc's end point"), - "/tools/shapes/arc/end", 0.0, - GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, - -360.0, 360.0, 1.0, 10.0, - 0, 0, 0, - sp_arctb_end_value_changed); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - } - - /* Arc: Slice, Arc, Chord */ - { - InkSelectOneActionColumns columns; - - Glib::RefPtr store = Gtk::ListStore::create(columns); - - Gtk::TreeModel::Row row; - - row = *(store->append()); - row[columns.col_label ] = _("Slice"); - row[columns.col_tooltip ] = _("Switch to slice (closed shape with two radii)"), - row[columns.col_icon ] = INKSCAPE_ICON("draw-ellipse-segment"); - row[columns.col_sensitive] = true; - - row = *(store->append()); - row[columns.col_label ] = _("Arc (Open)"); - row[columns.col_tooltip ] = _("Switch to arc (unclosed shape)"); - row[columns.col_icon ] = INKSCAPE_ICON("draw-ellipse-arc"); - row[columns.col_sensitive] = true; - - row = *(store->append()); - row[columns.col_label ] = _("Chord"); - row[columns.col_tooltip ] = _("Switch to chord (closed shape)"), - row[columns.col_icon ] = INKSCAPE_ICON("draw-ellipse-chord"); - row[columns.col_sensitive] = true; - - InkSelectOneAction* act = - InkSelectOneAction::create( "ArcTypeAction", // Name - "", // Label - "", // Tooltip - "Not Used", // Icon - store ); // Tree store - - act->use_radio( true ); - act->use_group_label( false ); - gint type = prefs->getInt("/tools/shapes/arc/arc_type", 0); - act->set_active( type ); - - gtk_action_group_add_action( mainActions, GTK_ACTION( act->gobj() )); - g_object_set_data( holder, "type_action", act ); - - act->signal_changed().connect(sigc::bind<0>(sigc::ptr_fun(&sp_arctb_type_changed), holder)); - } - - /* Make Whole */ - { - InkAction* inky = ink_action_new( "ArcResetAction", - _("Make whole"), - _("Make the shape a whole ellipse, not arc or segment"), - INKSCAPE_ICON("draw-ellipse-whole"), - secondarySize ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_arctb_defaults), holder ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - gtk_action_set_sensitive( GTK_ACTION(inky), TRUE ); - g_object_set_data( holder, "make_whole", inky ); - } - - g_object_set_data( G_OBJECT(holder), "single", GINT_TO_POINTER(TRUE) ); - // sensitivize make whole and open checkbox - { - GtkAdjustment *adj1 = GTK_ADJUSTMENT( g_object_get_data( holder, "start" ) ); - GtkAdjustment *adj2 = GTK_ADJUSTMENT( g_object_get_data( holder, "end" ) ); - sp_arctb_sensitivize( holder, gtk_adjustment_get_value(adj1), gtk_adjustment_get_value(adj2) ); - } - - desktop->connectEventContextChanged(sigc::bind(sigc::ptr_fun(arc_toolbox_check_ec), holder)); - g_signal_connect( holder, "destroy", G_CALLBACK(purge_repr_listener), holder ); -} - -static void arc_toolbox_check_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolBase* ec, GObject* holder) -{ - static sigc::connection changed; - - if (SP_IS_ARC_CONTEXT(ec)) { - changed = desktop->getSelection()->connectChanged(sigc::bind(sigc::ptr_fun(sp_arc_toolbox_selection_changed), holder)); - sp_arc_toolbox_selection_changed(desktop->getSelection(), holder); - } else { - if (changed) { - changed.disconnect(); - purge_repr_listener(NULL, holder); - } - } -} - -/* - 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:fileencoding=utf-8:textwidth=99 : diff --git a/src/widgets/arc-toolbar.h b/src/widgets/arc-toolbar.h deleted file mode 100644 index ca1319631..000000000 --- a/src/widgets/arc-toolbar.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef SEEN_ARC_TOOLBAR_H -#define SEEN_ARC_TOOLBAR_H - -/** - * @file - * 3d box aux toolbar - */ -/* Authors: - * MenTaLguY - * Lauris Kaplinski - * bulia byak - * Frank Felfe - * John Cliff - * David Turner - * Josh Andler - * Jon A. Cruz - * Maximilian Albert - * Tavmjong Bah - * Abhishek Sharma - * Kris De Gussem - * - * Copyright (C) 2004 David Turner - * Copyright (C) 2003 MenTaLguY - * Copyright (C) 1999-2011 authors - * Copyright (C) 2001-2002 Ximian, Inc. - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -class SPDesktop; - -typedef struct _GtkActionGroup GtkActionGroup; -typedef struct _GObject GObject; - -void sp_arc_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); - -#endif /* !SEEN_ARC_TOOLBAR_H */ diff --git a/src/widgets/box3d-toolbar.cpp b/src/widgets/box3d-toolbar.cpp deleted file mode 100644 index 4b944314d..000000000 --- a/src/widgets/box3d-toolbar.cpp +++ /dev/null @@ -1,444 +0,0 @@ -/** - * @file - * 3d box aux toolbar - */ -/* Authors: - * MenTaLguY - * Lauris Kaplinski - * bulia byak - * Frank Felfe - * John Cliff - * David Turner - * Josh Andler - * Jon A. Cruz - * Maximilian Albert - * Tavmjong Bah - * Abhishek Sharma - * Kris De Gussem - * - * Copyright (C) 2004 David Turner - * Copyright (C) 2003 MenTaLguY - * Copyright (C) 1999-2011 authors - * Copyright (C) 2001-2002 Ximian, Inc. - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include - -#include "box3d-toolbar.h" - -#include "desktop.h" -#include "document-undo.h" -#include "document.h" -#include "inkscape.h" -#include "toolbox.h" -#include "verbs.h" - -#include "object/box3d.h" -#include "object/persp3d.h" - -#include "ui/icon-names.h" -#include "ui/tools/box3d-tool.h" -#include "ui/uxmanager.h" - -#include "widgets/ege-adjustment-action.h" -#include "widgets/ink-toggle-action.h" - -#include "xml/node-event-vector.h" - -using Inkscape::UI::UXManager; -using Inkscape::DocumentUndo; -using Inkscape::UI::ToolboxFactory; -using Inkscape::UI::PrefPusher; - -//######################## -//## 3D Box ## -//######################## - -// normalize angle so that it lies in the interval [0,360] -static double box3d_normalize_angle (double a) { - double angle = a + ((int) (a/360.0))*360; - if (angle < 0) { - angle += 360.0; - } - return angle; -} - -static void box3d_set_button_and_adjustment(Persp3D *persp, - Proj::Axis axis, - GtkAdjustment *adj, - GtkAction *act, - GtkToggleAction *tact) -{ - // TODO: Take all selected perspectives into account but don't touch the state button if not all of them - // have the same state (otherwise a call to box3d_vp_z_state_changed() is triggered and the states - // are reset). - bool is_infinite = !persp3d_VP_is_finite(persp->perspective_impl, axis); - - if (is_infinite) { - gtk_toggle_action_set_active(tact, TRUE); - gtk_action_set_sensitive(act, TRUE); - - double angle = persp3d_get_infinite_angle(persp, axis); - if (angle != Geom::infinity()) { // FIXME: We should catch this error earlier (don't show the spinbutton at all) - gtk_adjustment_set_value(adj, box3d_normalize_angle(angle)); - } - } else { - gtk_toggle_action_set_active(tact, FALSE); - gtk_action_set_sensitive(act, FALSE); - } -} - -static void box3d_resync_toolbar(Inkscape::XML::Node *persp_repr, GObject *data) -{ - if (!persp_repr) { - g_print ("No perspective given to box3d_resync_toolbar().\n"); - return; - } - - GtkWidget *tbl = GTK_WIDGET(data); - GtkAdjustment *adj = 0; - GtkAction *act = 0; - GtkToggleAction *tact = 0; - Persp3D *persp = persp3d_get_from_repr(persp_repr); - if (!persp) { - // Hmm, is it an error if this happens? - return; - } - { - adj = GTK_ADJUSTMENT(g_object_get_data(G_OBJECT(tbl), "box3d_angle_x")); - act = GTK_ACTION(g_object_get_data(G_OBJECT(tbl), "box3d_angle_x_action")); - tact = &INK_TOGGLE_ACTION(g_object_get_data(G_OBJECT(tbl), "box3d_vp_x_state_action"))->action; - - box3d_set_button_and_adjustment(persp, Proj::X, adj, act, tact); - } - { - adj = GTK_ADJUSTMENT(g_object_get_data(G_OBJECT(tbl), "box3d_angle_y")); - act = GTK_ACTION(g_object_get_data(G_OBJECT(tbl), "box3d_angle_y_action")); - tact = &INK_TOGGLE_ACTION(g_object_get_data(G_OBJECT(tbl), "box3d_vp_y_state_action"))->action; - - box3d_set_button_and_adjustment(persp, Proj::Y, adj, act, tact); - } - { - adj = GTK_ADJUSTMENT(g_object_get_data(G_OBJECT(tbl), "box3d_angle_z")); - act = GTK_ACTION(g_object_get_data(G_OBJECT(tbl), "box3d_angle_z_action")); - tact = &INK_TOGGLE_ACTION(g_object_get_data(G_OBJECT(tbl), "box3d_vp_z_state_action"))->action; - - box3d_set_button_and_adjustment(persp, Proj::Z, adj, act, tact); - } -} - -static void box3d_persp_tb_event_attr_changed(Inkscape::XML::Node *repr, - gchar const * /*name*/, - gchar const * /*old_value*/, - gchar const * /*new_value*/, - bool /*is_interactive*/, - gpointer data) -{ - GtkWidget *tbl = GTK_WIDGET(data); - - // quit if run by the attr_changed or selection changed listener - if (g_object_get_data(G_OBJECT(tbl), "freeze")) { - return; - } - - // set freeze so that it can be caught in box3d_angle_z_value_changed() (to avoid calling - // SPDocumentUndo::maybeDone() when the document is undo insensitive) - g_object_set_data(G_OBJECT(tbl), "freeze", GINT_TO_POINTER(TRUE)); - - // TODO: Only update the appropriate part of the toolbar -// if (!strcmp(name, "inkscape:vp_z")) { - box3d_resync_toolbar(repr, G_OBJECT(tbl)); -// } - - Persp3D *persp = persp3d_get_from_repr(repr); - persp3d_update_box_reprs(persp); - - g_object_set_data(G_OBJECT(tbl), "freeze", GINT_TO_POINTER(FALSE)); -} - -static Inkscape::XML::NodeEventVector box3d_persp_tb_repr_events = -{ - NULL, /* child_added */ - NULL, /* child_removed */ - box3d_persp_tb_event_attr_changed, - NULL, /* content_changed */ - NULL /* order_changed */ -}; - -/** - * \param selection Should not be NULL. - */ -// FIXME: This should rather be put into persp3d-reference.cpp or something similar so that it reacts upon each -// Change of the perspective, and not of the current selection (but how to refer to the toolbar then?) -static void box3d_toolbox_selection_changed(Inkscape::Selection *selection, GObject *tbl) -{ - // Here the following should be done: If all selected boxes have finite VPs in a certain direction, - // disable the angle entry fields for this direction (otherwise entering a value in them should only - // update the perspectives with infinite VPs and leave the other ones untouched). - - Inkscape::XML::Node *persp_repr = NULL; - purge_repr_listener(tbl, tbl); - - SPItem *item = selection->singleItem(); - SPBox3D *box = dynamic_cast(item); - if (box) { - // FIXME: Also deal with multiple selected boxes - Persp3D *persp = box3d_get_perspective(box); - persp_repr = persp->getRepr(); - if (persp_repr) { - g_object_set_data(tbl, "repr", persp_repr); - Inkscape::GC::anchor(persp_repr); - sp_repr_add_listener(persp_repr, &box3d_persp_tb_repr_events, tbl); - sp_repr_synthesize_events(persp_repr, &box3d_persp_tb_repr_events, tbl); - - SP_ACTIVE_DOCUMENT->setCurrentPersp3D(persp3d_get_from_repr(persp_repr)); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setString("/tools/shapes/3dbox/persp", persp_repr->attribute("id")); - - g_object_set_data(tbl, "freeze", GINT_TO_POINTER(TRUE)); - box3d_resync_toolbar(persp_repr, tbl); - g_object_set_data(tbl, "freeze", GINT_TO_POINTER(FALSE)); - } - } -} - -static void box3d_angle_value_changed(GtkAdjustment *adj, GObject *dataKludge, Proj::Axis axis) -{ - SPDesktop *desktop = static_cast(g_object_get_data( dataKludge, "desktop" )); - SPDocument *document = desktop->getDocument(); - - // quit if run by the attr_changed or selection changed listener - if (g_object_get_data( dataKludge, "freeze" )) { - return; - } - - // in turn, prevent listener from responding - g_object_set_data(dataKludge, "freeze", GINT_TO_POINTER(TRUE)); - - std::list sel_persps = desktop->getSelection()->perspList(); - if (sel_persps.empty()) { - // this can happen when the document is created; we silently ignore it - return; - } - Persp3D *persp = sel_persps.front(); - - persp->perspective_impl->tmat.set_infinite_direction (axis, - gtk_adjustment_get_value(adj)); - persp->updateRepr(); - - // TODO: use the correct axis here, too - DocumentUndo::maybeDone(document, "perspangle", SP_VERB_CONTEXT_3DBOX, _("3D Box: Change perspective (angle of infinite axis)")); - - g_object_set_data( dataKludge, "freeze", GINT_TO_POINTER(FALSE) ); -} - - -static void box3d_angle_x_value_changed(GtkAdjustment *adj, GObject *dataKludge) -{ - box3d_angle_value_changed(adj, dataKludge, Proj::X); -} - -static void box3d_angle_y_value_changed(GtkAdjustment *adj, GObject *dataKludge) -{ - box3d_angle_value_changed(adj, dataKludge, Proj::Y); -} - -static void box3d_angle_z_value_changed(GtkAdjustment *adj, GObject *dataKludge) -{ - box3d_angle_value_changed(adj, dataKludge, Proj::Z); -} - - -static void box3d_vp_state_changed( GtkToggleAction *act, GtkAction * /*box3d_angle*/, Proj::Axis axis ) -{ - // TODO: Take all selected perspectives into account - std::list sel_persps = SP_ACTIVE_DESKTOP->getSelection()->perspList(); - if (sel_persps.empty()) { - // this can happen when the document is created; we silently ignore it - return; - } - Persp3D *persp = sel_persps.front(); - - bool set_infinite = gtk_toggle_action_get_active(act); - persp3d_set_VP_state (persp, axis, set_infinite ? Proj::VP_INFINITE : Proj::VP_FINITE); -} - -static void box3d_vp_x_state_changed( GtkToggleAction *act, GtkAction *box3d_angle ) -{ - box3d_vp_state_changed(act, box3d_angle, Proj::X); -} - -static void box3d_vp_y_state_changed( GtkToggleAction *act, GtkAction *box3d_angle ) -{ - box3d_vp_state_changed(act, box3d_angle, Proj::Y); -} - -static void box3d_vp_z_state_changed( GtkToggleAction *act, GtkAction *box3d_angle ) -{ - box3d_vp_state_changed(act, box3d_angle, Proj::Z); -} - -static void box3d_toolbox_check_ec(SPDesktop* dt, Inkscape::UI::Tools::ToolBase* ec, GObject* holder); - -void box3d_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - EgeAdjustmentAction* eact = 0; - SPDocument *document = desktop->getDocument(); - Persp3DImpl *persp_impl = document->getCurrentPersp3DImpl(); - - EgeAdjustmentAction* box3d_angle_x = 0; - EgeAdjustmentAction* box3d_angle_y = 0; - EgeAdjustmentAction* box3d_angle_z = 0; - - /* Angle X */ - { - gchar const* labels[] = { 0, 0, 0, 0, 0, 0, 0 }; - gdouble values[] = {-90, -60, -30, 0, 30, 60, 90}; - eact = create_adjustment_action( "3DBoxAngleXAction", - _("Angle in X direction"), _("Angle X:"), - // Translators: PL is short for 'perspective line' - _("Angle of PLs in X direction"), - "/tools/shapes/3dbox/box3d_angle_x", 30, - GTK_WIDGET(desktop->canvas), holder, TRUE, "altx-box3d", - -360.0, 360.0, 1.0, 10.0, - labels, values, G_N_ELEMENTS(labels), - box3d_angle_x_value_changed ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - g_object_set_data( holder, "box3d_angle_x_action", eact ); - box3d_angle_x = eact; - } - - if (!persp_impl || !persp3d_VP_is_finite(persp_impl, Proj::X)) { - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - } else { - gtk_action_set_sensitive( GTK_ACTION(eact), FALSE ); - } - - - /* VP X state */ - { - InkToggleAction* act = ink_toggle_action_new( "3DBoxVPXStateAction", - // Translators: VP is short for 'vanishing point' - _("State of VP in X direction"), - _("Toggle VP in X direction between 'finite' and 'infinite' (=parallel)"), - INKSCAPE_ICON("perspective-parallel"), - GTK_ICON_SIZE_MENU ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - g_object_set_data( holder, "box3d_vp_x_state_action", act ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(box3d_vp_x_state_changed), box3d_angle_x ); - gtk_action_set_sensitive( GTK_ACTION(box3d_angle_x), !prefs->getBool("/tools/shapes/3dbox/vp_x_state", true) ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/shapes/3dbox/vp_x_state", true) ); - } - - /* Angle Y */ - { - gchar const* labels[] = { 0, 0, 0, 0, 0, 0, 0 }; - gdouble values[] = {-90, -60, -30, 0, 30, 60, 90}; - eact = create_adjustment_action( "3DBoxAngleYAction", - _("Angle in Y direction"), _("Angle Y:"), - // Translators: PL is short for 'perspective line' - _("Angle of PLs in Y direction"), - "/tools/shapes/3dbox/box3d_angle_y", 30, - GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, - -360.0, 360.0, 1.0, 10.0, - labels, values, G_N_ELEMENTS(labels), - box3d_angle_y_value_changed ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - g_object_set_data( holder, "box3d_angle_y_action", eact ); - box3d_angle_y = eact; - } - - if (!persp_impl || !persp3d_VP_is_finite(persp_impl, Proj::Y)) { - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - } else { - gtk_action_set_sensitive( GTK_ACTION(eact), FALSE ); - } - - /* VP Y state */ - { - InkToggleAction* act = ink_toggle_action_new( "3DBoxVPYStateAction", - // Translators: VP is short for 'vanishing point' - _("State of VP in Y direction"), - _("Toggle VP in Y direction between 'finite' and 'infinite' (=parallel)"), - INKSCAPE_ICON("perspective-parallel"), - GTK_ICON_SIZE_MENU ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - g_object_set_data( holder, "box3d_vp_y_state_action", act ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(box3d_vp_y_state_changed), box3d_angle_y ); - gtk_action_set_sensitive( GTK_ACTION(box3d_angle_y), !prefs->getBool("/tools/shapes/3dbox/vp_y_state", true) ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/shapes/3dbox/vp_y_state", true) ); - } - - /* Angle Z */ - { - gchar const* labels[] = { 0, 0, 0, 0, 0, 0, 0 }; - gdouble values[] = {-90, -60, -30, 0, 30, 60, 90}; - eact = create_adjustment_action( "3DBoxAngleZAction", - _("Angle in Z direction"), _("Angle Z:"), - // Translators: PL is short for 'perspective line' - _("Angle of PLs in Z direction"), - "/tools/shapes/3dbox/box3d_angle_z", 30, - GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, - -360.0, 360.0, 1.0, 10.0, - labels, values, G_N_ELEMENTS(labels), - box3d_angle_z_value_changed ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - g_object_set_data( holder, "box3d_angle_z_action", eact ); - box3d_angle_z = eact; - } - - if (!persp_impl || !persp3d_VP_is_finite(persp_impl, Proj::Z)) { - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - } else { - gtk_action_set_sensitive( GTK_ACTION(eact), FALSE ); - } - - /* VP Z state */ - { - InkToggleAction* act = ink_toggle_action_new( "3DBoxVPZStateAction", - // Translators: VP is short for 'vanishing point' - _("State of VP in Z direction"), - _("Toggle VP in Z direction between 'finite' and 'infinite' (=parallel)"), - INKSCAPE_ICON("perspective-parallel"), - GTK_ICON_SIZE_MENU ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - g_object_set_data( holder, "box3d_vp_z_state_action", act ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(box3d_vp_z_state_changed), box3d_angle_z ); - gtk_action_set_sensitive( GTK_ACTION(box3d_angle_z), !prefs->getBool("/tools/shapes/3dbox/vp_z_state", true) ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/shapes/3dbox/vp_z_state", true) ); - } - - desktop->connectEventContextChanged(sigc::bind(sigc::ptr_fun(box3d_toolbox_check_ec), holder)); - g_signal_connect(holder, "destroy", G_CALLBACK(purge_repr_listener), holder); -} - -static void box3d_toolbox_check_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolBase* ec, GObject* holder) -{ - static sigc::connection changed; - if (SP_IS_BOX3D_CONTEXT(ec)) { - changed = desktop->getSelection()->connectChanged(sigc::bind(sigc::ptr_fun(box3d_toolbox_selection_changed), holder)); - box3d_toolbox_selection_changed(desktop->getSelection(), holder); - } else { - if (changed) - changed.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:fileencoding=utf-8:textwidth=99 : diff --git a/src/widgets/box3d-toolbar.h b/src/widgets/box3d-toolbar.h deleted file mode 100644 index cba9ca2d8..000000000 --- a/src/widgets/box3d-toolbar.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef SEEN_BOX3D_TOOLBAR_H -#define SEEN_BOX3D_TOOLBAR_H - -/** - * @file - * 3d box aux toolbar - */ -/* Authors: - * MenTaLguY - * Lauris Kaplinski - * bulia byak - * Frank Felfe - * John Cliff - * David Turner - * Josh Andler - * Jon A. Cruz - * Maximilian Albert - * Tavmjong Bah - * Abhishek Sharma - * Kris De Gussem - * - * Copyright (C) 2004 David Turner - * Copyright (C) 2003 MenTaLguY - * Copyright (C) 1999-2011 authors - * Copyright (C) 2001-2002 Ximian, Inc. - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - - -class SPDesktop; - -typedef struct _GtkActionGroup GtkActionGroup; -typedef struct _GObject GObject; - -void box3d_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); - -#endif /* !SEEN_BOX3D_TOOLBAR_H */ diff --git a/src/widgets/calligraphy-toolbar.cpp b/src/widgets/calligraphy-toolbar.cpp deleted file mode 100644 index ed9779f1a..000000000 --- a/src/widgets/calligraphy-toolbar.cpp +++ /dev/null @@ -1,623 +0,0 @@ -/** - * @file - * Calligraphy aux toolbar - */ -/* Authors: - * MenTaLguY - * Lauris Kaplinski - * bulia byak - * Frank Felfe - * John Cliff - * David Turner - * Josh Andler - * Jon A. Cruz - * Maximilian Albert - * Tavmjong Bah - * Abhishek Sharma - * Kris De Gussem - * - * Copyright (C) 2004 David Turner - * Copyright (C) 2003 MenTaLguY - * Copyright (C) 1999-2011 authors - * Copyright (C) 2001-2002 Ximian, Inc. - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "ui/dialog/calligraphic-profile-rename.h" -#include -#include "calligraphy-toolbar.h" - -#include "desktop.h" -#include "document-undo.h" -#include "widgets/ege-adjustment-action.h" -#include "widgets/ink-action.h" -#include "widgets/ink-toggle-action.h" -#include "toolbox.h" -#include "ui/icon-names.h" -#include "ui/uxmanager.h" -#include "ui/widget/ink-select-one-action.h" - -using Inkscape::UI::UXManager; -using Inkscape::DocumentUndo; -using Inkscape::UI::ToolboxFactory; -using Inkscape::UI::PrefPusher; - - -//######################## -//## Calligraphy ## -//######################## - -std::vector get_presets_list() { - - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - - std::vector presets = prefs->getAllDirs("/tools/calligraphic/preset"); - - return presets; -} - -void update_presets_list(GObject *tbl) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - if (g_object_get_data(tbl, "presets_blocked")) { - return; - } - - InkSelectOneAction *act = static_cast(g_object_get_data(tbl, "profile_selector")); - - std::vector presets = get_presets_list(); - - int index = 1; // 0 is for no preset. - for (std::vector::iterator i = presets.begin(); i != presets.end(); ++i, ++index) { - bool match = true; - - std::vector preset = prefs->getAllEntries(*i); - for (std::vector::iterator j = preset.begin(); j != preset.end(); ++j) { - Glib::ustring entry_name = j->getEntryName(); - if (entry_name == "id" || entry_name == "name") { - continue; - } - - void *widget = g_object_get_data(tbl, entry_name.data()); - if (widget) { - if (GTK_IS_ADJUSTMENT(widget)) { - double v = j->getDouble(); - GtkAdjustment* adj = static_cast(widget); - //std::cout << "compared adj " << attr_name << gtk_adjustment_get_value(adj) << " to " << v << "\n"; - if (fabs(gtk_adjustment_get_value(adj) - v) > 1e-6) { - match = false; - break; - } - } else if (GTK_IS_TOGGLE_ACTION(widget)) { - bool v = j->getBool(); - GtkToggleAction* toggle = static_cast(widget); - //std::cout << "compared toggle " << attr_name << gtk_toggle_action_get_active(toggle) << " to " << v << "\n"; - if ( static_cast(gtk_toggle_action_get_active(toggle)) != v ) { - match = false; - break; - } - } - } - } - - if (match) { - // newly added item is at the same index as the - // save command, so we need to change twice for it to take effect - act->set_active(0); - act->set_active(index); - return; - } - } - - // no match found - act->set_active(0); -} - -static void sp_ddc_mass_value_changed( GtkAdjustment *adj, GObject* tbl ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble( "/tools/calligraphic/mass", gtk_adjustment_get_value(adj) ); - update_presets_list(tbl); -} - -static void sp_ddc_wiggle_value_changed( GtkAdjustment *adj, GObject* tbl ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble( "/tools/calligraphic/wiggle", gtk_adjustment_get_value(adj) ); - update_presets_list(tbl); -} - -static void sp_ddc_angle_value_changed( GtkAdjustment *adj, GObject* tbl ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble( "/tools/calligraphic/angle", gtk_adjustment_get_value(adj) ); - update_presets_list(tbl); -} - -static void sp_ddc_width_value_changed( GtkAdjustment *adj, GObject *tbl ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble( "/tools/calligraphic/width", gtk_adjustment_get_value(adj) ); - update_presets_list(tbl); -} - -static void sp_ddc_velthin_value_changed( GtkAdjustment *adj, GObject* tbl ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble("/tools/calligraphic/thinning", gtk_adjustment_get_value(adj) ); - update_presets_list(tbl); -} - -static void sp_ddc_flatness_value_changed( GtkAdjustment *adj, GObject* tbl ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble( "/tools/calligraphic/flatness", gtk_adjustment_get_value(adj) ); - update_presets_list(tbl); -} - -static void sp_ddc_tremor_value_changed( GtkAdjustment *adj, GObject* tbl ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble( "/tools/calligraphic/tremor", gtk_adjustment_get_value(adj) ); - update_presets_list(tbl); -} - -static void sp_ddc_cap_rounding_value_changed( GtkAdjustment *adj, GObject* tbl ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble( "/tools/calligraphic/cap_rounding", gtk_adjustment_get_value(adj) ); - update_presets_list(tbl); -} - -static void sp_ddc_tilt_state_changed( GtkToggleAction *act, GObject* tbl ) -{ - // TODO merge into PrefPusher - GtkAction * calligraphy_angle = static_cast (g_object_get_data(tbl,"angle_action")); - if (calligraphy_angle ) { - gtk_action_set_sensitive( calligraphy_angle, !gtk_toggle_action_get_active( act ) ); - } -} - - -static gchar const *const widget_names[] = { - "width", - "mass", - "wiggle", - "angle", - "thinning", - "tremor", - "flatness", - "cap_rounding", - "usepressure", - "tracebackground", - "usetilt" -}; - - -static void sp_dcc_build_presets_list(GObject *tbl) -{ - g_object_set_data(tbl, "presets_blocked", GINT_TO_POINTER(TRUE)); - - InkSelectOneAction* act = static_cast(g_object_get_data(tbl, "profile_selector")); - - Glib::RefPtr store = act->get_store(); - store->clear(); - - InkSelectOneActionColumns columns; - - Gtk::TreeModel::Row row; - - row = *(store->append()); - row[columns.col_label ] = _("No preset"); - row[columns.col_sensitive] = true; - - // iterate over all presets to populate the list - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - std::vector presets = get_presets_list(); - int ii=1; - - for (std::vector::iterator i = presets.begin(); i != presets.end(); ++i) { - GtkTreeIter iter; - Glib::ustring preset_name = prefs->getString(*i + "/name"); - - if (!preset_name.empty()) { - row = *(store->append()); - row[columns.col_label ] = _(preset_name.data()); - row[columns.col_sensitive] = true; - } - } - - g_object_set_data(tbl, "presets_blocked", GINT_TO_POINTER(FALSE)); - - update_presets_list (tbl); -} - -static void sp_dcc_save_profile(GtkWidget * /*widget*/, GObject *tbl) -{ - using Inkscape::UI::Dialog::CalligraphicProfileRename; - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - SPDesktop *desktop = static_cast(g_object_get_data(tbl, "desktop" )); - if (! desktop) { - return; - } - - if (g_object_get_data(tbl, "presets_blocked")) { - return; - } - - InkSelectOneAction *act = static_cast(g_object_get_data(tbl, "profile_selector")); - - Glib::ustring current_profile_name = act->get_active_text(); - - if (current_profile_name == _("No preset")) { - current_profile_name = ""; - } - - CalligraphicProfileRename::show(desktop, current_profile_name); - if ( !CalligraphicProfileRename::applied()) { - // dialog cancelled - update_presets_list (tbl); - return; - } - Glib::ustring new_profile_name = CalligraphicProfileRename::getProfileName(); - - if (new_profile_name.empty()) { - // empty name entered - update_presets_list (tbl); - return; - } - - g_object_set_data(tbl, "presets_blocked", GINT_TO_POINTER(TRUE)); - - // If there's a preset with the given name, find it and set save_path appropriately - std::vector presets = get_presets_list(); - int total_presets = presets.size(); - int new_index = -1; - Glib::ustring save_path; // profile pref path without a trailing slash - - int temp_index = 0; - for (std::vector::iterator i = presets.begin(); i != presets.end(); ++i, ++temp_index) { - Glib::ustring name = prefs->getString(*i + "/name"); - if (!name.empty() && (new_profile_name == name || current_profile_name == name)) { - new_index = temp_index; - save_path = *i; - break; - } - } - - - if ( CalligraphicProfileRename::deleted() && new_index != -1) { - prefs->remove(save_path); - g_object_set_data(tbl, "presets_blocked", GINT_TO_POINTER(FALSE)); - sp_dcc_build_presets_list (tbl); - return; - } - - if (new_index == -1) { - // no preset with this name, create - new_index = total_presets + 1; - gchar *profile_id = g_strdup_printf("/dcc%d", new_index); - save_path = Glib::ustring("/tools/calligraphic/preset") + profile_id; - g_free(profile_id); - } - - for (unsigned i = 0; i < G_N_ELEMENTS(widget_names); ++i) { - gchar const *const widget_name = widget_names[i]; - void *widget = g_object_get_data(tbl, widget_name); - if (widget) { - if (GTK_IS_ADJUSTMENT(widget)) { - GtkAdjustment* adj = static_cast(widget); - prefs->setDouble(save_path + "/" + widget_name, gtk_adjustment_get_value(adj)); - //std::cout << "wrote adj " << widget_name << ": " << v << "\n"; - } else if (GTK_IS_TOGGLE_ACTION(widget)) { - GtkToggleAction* toggle = static_cast(widget); - prefs->setBool(save_path + "/" + widget_name, gtk_toggle_action_get_active(toggle)); - //std::cout << "wrote tog " << widget_name << ": " << v << "\n"; - } else { - g_warning("Unknown widget type for preset: %s\n", widget_name); - } - } else { - g_warning("Bad key when writing preset: %s\n", widget_name); - } - } - prefs->setString(save_path + "/name", new_profile_name); - - g_object_set_data(tbl, "presets_blocked", GINT_TO_POINTER(FALSE)); - sp_dcc_build_presets_list (tbl); -} - - -static void sp_ddc_change_profile(GObject* tbl, int mode) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - - if (g_object_get_data(tbl, "presets_blocked")) { - return; - } - - // mode is one-based so we subtract 1 - std::vector presets = get_presets_list(); - - Glib::ustring preset_path = ""; - if (mode - 1 < presets.size()) { - preset_path = presets.at(mode - 1); - } - - if (!preset_path.empty()) { - g_object_set_data(tbl, "presets_blocked", GINT_TO_POINTER(TRUE)); //temporarily block the selector so no one will updadte it while we're reading it - - std::vector preset = prefs->getAllEntries(preset_path); - - // Shouldn't this be std::map? - for (std::vector::iterator i = preset.begin(); i != preset.end(); ++i) { - Glib::ustring entry_name = i->getEntryName(); - if (entry_name == "id" || entry_name == "name") { - continue; - } - void *widget = g_object_get_data(tbl, entry_name.data()); - if (widget) { - if (GTK_IS_ADJUSTMENT(widget)) { - GtkAdjustment* adj = static_cast(widget); - gtk_adjustment_set_value(adj, i->getDouble()); - //std::cout << "set adj " << attr_name << " to " << v << "\n"; - } else if (GTK_IS_TOGGLE_ACTION(widget)) { - GtkToggleAction* toggle = static_cast(widget); - gtk_toggle_action_set_active(toggle, i->getBool()); - //std::cout << "set toggle " << attr_name << " to " << v << "\n"; - } else { - g_warning("Unknown widget type for preset: %s\n", entry_name.data()); - } - } else { - g_warning("Bad key found in a preset record: %s\n", entry_name.data()); - } - } - g_object_set_data(tbl, "presets_blocked", GINT_TO_POINTER(FALSE)); - } -} - -static void sp_ddc_edit_profile(GtkAction * /*act*/, GObject* tbl) -{ - sp_dcc_save_profile(NULL, tbl); -} - -void sp_calligraphy_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - { - g_object_set_data(holder, "presets_blocked", GINT_TO_POINTER(TRUE)); - - EgeAdjustmentAction* calligraphy_angle = 0; - - { - /* Width */ - gchar const* labels[] = {_("(hairline)"), 0, 0, 0, _("(default)"), 0, 0, 0, 0, _("(broad stroke)")}; - gdouble values[] = {1, 3, 5, 10, 15, 20, 30, 50, 75, 100}; - EgeAdjustmentAction *eact = create_adjustment_action( "CalligraphyWidthAction", - _("Pen Width"), _("Width:"), - _("The width of the calligraphic pen (relative to the visible canvas area)"), - "/tools/calligraphic/width", 15, - GTK_WIDGET(desktop->canvas), holder, TRUE, "altx-calligraphy", - 1, 100, 1.0, 10.0, - labels, values, G_N_ELEMENTS(labels), - sp_ddc_width_value_changed, NULL /*unit tracker*/, 1, 0 ); - ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - } - - { - /* Thinning */ - gchar const* labels[] = {_("(speed blows up stroke)"), 0, 0, _("(slight widening)"), _("(constant width)"), _("(slight thinning, default)"), 0, 0, _("(speed deflates stroke)")}; - gdouble values[] = {-100, -40, -20, -10, 0, 10, 20, 40, 100}; - EgeAdjustmentAction* eact = create_adjustment_action( "ThinningAction", - _("Stroke Thinning"), _("Thinning:"), - _("How much velocity thins the stroke (> 0 makes fast strokes thinner, < 0 makes them broader, 0 makes width independent of velocity)"), - "/tools/calligraphic/thinning", 10, - GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, - -100, 100, 1, 10.0, - labels, values, G_N_ELEMENTS(labels), - sp_ddc_velthin_value_changed, NULL /*unit tracker*/, 1, 0); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - } - - { - /* Angle */ - gchar const* labels[] = {_("(left edge up)"), 0, 0, _("(horizontal)"), _("(default)"), 0, _("(right edge up)")}; - gdouble values[] = {-90, -60, -30, 0, 30, 60, 90}; - EgeAdjustmentAction* eact = create_adjustment_action( "AngleAction", - _("Pen Angle"), _("Angle:"), - _("The angle of the pen's nib (in degrees; 0 = horizontal; has no effect if fixation = 0)"), - "/tools/calligraphic/angle", 30, - GTK_WIDGET(desktop->canvas), holder, TRUE, "calligraphy-angle", - -90.0, 90.0, 1.0, 10.0, - labels, values, G_N_ELEMENTS(labels), - sp_ddc_angle_value_changed, NULL /*unit tracker*/, 1, 0 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - g_object_set_data( holder, "angle_action", eact ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - calligraphy_angle = eact; - } - - { - /* Fixation */ - gchar const* labels[] = {_("(perpendicular to stroke, \"brush\")"), 0, 0, 0, _("(almost fixed, default)"), _("(fixed by Angle, \"pen\")")}; - gdouble values[] = {0, 20, 40, 60, 90, 100}; - EgeAdjustmentAction* eact = create_adjustment_action( "FixationAction", - _("Fixation"), _("Fixation:"), - _("Angle behavior (0 = nib always perpendicular to stroke direction, 100 = fixed angle)"), - "/tools/calligraphic/flatness", 90, - GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, - 0.0, 100, 1.0, 10.0, - labels, values, G_N_ELEMENTS(labels), - sp_ddc_flatness_value_changed, NULL /*unit tracker*/, 1, 0); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - } - - { - /* Cap Rounding */ - gchar const* labels[] = {_("(blunt caps, default)"), _("(slightly bulging)"), 0, 0, _("(approximately round)"), _("(long protruding caps)")}; - gdouble values[] = {0, 0.3, 0.5, 1.0, 1.4, 5.0}; - // TRANSLATORS: "cap" means "end" (both start and finish) here - EgeAdjustmentAction* eact = create_adjustment_action( "CapRoundingAction", - _("Cap rounding"), _("Caps:"), - _("Increase to make caps at the ends of strokes protrude more (0 = no caps, 1 = round caps)"), - "/tools/calligraphic/cap_rounding", 0.0, - GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, - 0.0, 5.0, 0.01, 0.1, - labels, values, G_N_ELEMENTS(labels), - sp_ddc_cap_rounding_value_changed, NULL /*unit tracker*/, 0.01, 2 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - } - - { - /* Tremor */ - gchar const* labels[] = {_("(smooth line)"), _("(slight tremor)"), _("(noticeable tremor)"), 0, 0, _("(maximum tremor)")}; - gdouble values[] = {0, 10, 20, 40, 60, 100}; - EgeAdjustmentAction* eact = create_adjustment_action( "TremorAction", - _("Stroke Tremor"), _("Tremor:"), - _("Increase to make strokes rugged and trembling"), - "/tools/calligraphic/tremor", 0.0, - GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, - 0.0, 100, 1, 10.0, - labels, values, G_N_ELEMENTS(labels), - sp_ddc_tremor_value_changed, NULL /*unit tracker*/, 1, 0); - - ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - } - - { - /* Wiggle */ - gchar const* labels[] = {_("(no wiggle)"), _("(slight deviation)"), 0, 0, _("(wild waves and curls)")}; - gdouble values[] = {0, 20, 40, 60, 100}; - EgeAdjustmentAction* eact = create_adjustment_action( "WiggleAction", - _("Pen Wiggle"), _("Wiggle:"), - _("Increase to make the pen waver and wiggle"), - "/tools/calligraphic/wiggle", 0.0, - GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, - 0.0, 100, 1, 10.0, - labels, values, G_N_ELEMENTS(labels), - sp_ddc_wiggle_value_changed, NULL /*unit tracker*/, 1, 0); - ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - } - - { - /* Mass */ - gchar const* labels[] = {_("(no inertia)"), _("(slight smoothing, default)"), _("(noticeable lagging)"), 0, 0, _("(maximum inertia)")}; - gdouble values[] = {0.0, 2, 10, 20, 50, 100}; - EgeAdjustmentAction* eact = create_adjustment_action( "MassAction", - _("Pen Mass"), _("Mass:"), - _("Increase to make the pen drag behind, as if slowed by inertia"), - "/tools/calligraphic/mass", 2.0, - GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, - 0.0, 100, 1, 10.0, - labels, values, G_N_ELEMENTS(labels), - sp_ddc_mass_value_changed, NULL /*unit tracker*/, 1, 0); - ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - } - - - /* Trace Background button */ - { - InkToggleAction* act = ink_toggle_action_new( "TraceAction", - _("Trace Background"), - _("Trace the lightness of the background by the width of the pen (white - minimum width, black - maximum width)"), - INKSCAPE_ICON("draw-trace-background"), - GTK_ICON_SIZE_MENU ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(act), "/tools/calligraphic/tracebackground", update_presets_list, holder); - g_signal_connect( holder, "destroy", G_CALLBACK(delete_prefspusher), pusher); - g_object_set_data( holder, "tracebackground", act ); - } - - /* Use Pressure button */ - { - InkToggleAction* act = ink_toggle_action_new( "PressureAction", - _("Pressure"), - _("Use the pressure of the input device to alter the width of the pen"), - INKSCAPE_ICON("draw-use-pressure"), - GTK_ICON_SIZE_MENU ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(act), "/tools/calligraphic/usepressure", update_presets_list, holder); - g_signal_connect( holder, "destroy", G_CALLBACK(delete_prefspusher), pusher); - g_object_set_data( holder, "usepressure", act ); - } - - /* Use Tilt button */ - { - InkToggleAction* act = ink_toggle_action_new( "TiltAction", - _("Tilt"), - _("Use the tilt of the input device to alter the angle of the pen's nib"), - INKSCAPE_ICON("draw-use-tilt"), - GTK_ICON_SIZE_MENU ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(act), "/tools/calligraphic/usetilt", update_presets_list, holder); - g_signal_connect( holder, "destroy", G_CALLBACK(delete_prefspusher), pusher); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_ddc_tilt_state_changed), holder ); - gtk_action_set_sensitive( GTK_ACTION(calligraphy_angle), !prefs->getBool("/tools/calligraphic/usetilt", true) ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/calligraphic/usetilt", true) ); - g_object_set_data( holder, "usetilt", act ); - } - - /*calligraphic profile */ - { - InkSelectOneActionColumns columns; - - Glib::RefPtr store = Gtk::ListStore::create(columns); - - InkSelectOneAction* act = - InkSelectOneAction::create( "SetProfileAction", // Name - "", // Label - _("Choose a preset"), // Tooltip - "NotUsed", // Icon - store ); // Tree store - act->use_radio( false ); - act->use_label( true ); - - g_object_set_data (holder, "profile_selector", act); - - sp_dcc_build_presets_list (holder); - - gtk_action_group_add_action(mainActions, GTK_ACTION( act->gobj() )); - - act->signal_changed().connect(sigc::bind<0>(sigc::ptr_fun(&sp_ddc_change_profile), holder)); - } - - /*calligraphic profile editor */ - { - InkAction* inky = ink_action_new( "ProfileEditAction", - _("Add/Edit Profile"), - _("Add or edit calligraphic profile"), - INKSCAPE_ICON("document-properties"), - GTK_ICON_SIZE_MENU ); - g_object_set( inky, "short_label", _("Edit"), NULL ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_ddc_edit_profile), (GObject*)holder ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - } - } -} - - -/* - 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:fileencoding=utf-8:textwidth=99 : diff --git a/src/widgets/calligraphy-toolbar.h b/src/widgets/calligraphy-toolbar.h deleted file mode 100644 index e3caa19ee..000000000 --- a/src/widgets/calligraphy-toolbar.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef SEEN_CALLIGRAPHY_TOOLBAR_H -#define SEEN_CALLIGRAPHY_TOOLBAR_H - -/** - * @file - * Calligraphy aux toolbar - */ -/* Authors: - * MenTaLguY - * Lauris Kaplinski - * bulia byak - * Frank Felfe - * John Cliff - * David Turner - * Josh Andler - * Jon A. Cruz - * Maximilian Albert - * Tavmjong Bah - * Abhishek Sharma - * Kris De Gussem - * - * Copyright (C) 2004 David Turner - * Copyright (C) 2003 MenTaLguY - * Copyright (C) 1999-2011 authors - * Copyright (C) 2001-2002 Ximian, Inc. - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -class SPDesktop; - -typedef struct _GtkActionGroup GtkActionGroup; -typedef struct _GObject GObject; - -void sp_calligraphy_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); -void update_presets_list(GObject *tbl); - -#endif /* !SEEN_CALLIGRAPHY_TOOLBAR_H */ diff --git a/src/widgets/connector-toolbar.cpp b/src/widgets/connector-toolbar.cpp deleted file mode 100644 index 2030e7acb..000000000 --- a/src/widgets/connector-toolbar.cpp +++ /dev/null @@ -1,450 +0,0 @@ -/** - * @file - * Connector aux toolbar - */ -/* Authors: - * MenTaLguY - * Lauris Kaplinski - * bulia byak - * Frank Felfe - * John Cliff - * David Turner - * Josh Andler - * Jon A. Cruz - * Maximilian Albert - * Tavmjong Bah - * Abhishek Sharma - * Kris De Gussem - * - * Copyright (C) 2004 David Turner - * Copyright (C) 2003 MenTaLguY - * Copyright (C) 1999-2011 authors - * Copyright (C) 2001-2002 Ximian, Inc. - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include - -#include "connector-toolbar.h" -#include "conn-avoid-ref.h" - -#include "desktop.h" -#include "document-undo.h" -#include "enums.h" -#include "graphlayout.h" -#include "ink-action.h" -#include "ink-toggle-action.h" -#include "inkscape.h" -#include "toolbox.h" -#include "verbs.h" - -#include "object/sp-namedview.h" -#include "object/sp-path.h" - -#include "ui/icon-names.h" -#include "ui/tools/connector-tool.h" -#include "ui/uxmanager.h" - -#include "widgets/ege-adjustment-action.h" -#include "widgets/spinbutton-events.h" - -#include "xml/node-event-vector.h" - -using Inkscape::UI::UXManager; -using Inkscape::DocumentUndo; -using Inkscape::UI::ToolboxFactory; -using Inkscape::UI::PrefPusher; - -//######################### -//## Connector ## -//######################### - -static void sp_connector_path_set_avoid(void) -{ - Inkscape::UI::Tools::cc_selection_set_avoid(true); -} - - -static void sp_connector_path_set_ignore(void) -{ - Inkscape::UI::Tools::cc_selection_set_avoid(false); -} - -static void sp_connector_orthogonal_toggled( GtkToggleAction* act, GObject *tbl ) -{ - SPDesktop *desktop = static_cast(g_object_get_data( tbl, "desktop" )); - SPDocument *doc = desktop->getDocument(); - - if (!DocumentUndo::getUndoSensitive(doc)) { - return; - } - - - // quit if run by the _changed callbacks - if (g_object_get_data( tbl, "freeze" )) { - return; - } - - // in turn, prevent callbacks from responding - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - - bool is_orthog = gtk_toggle_action_get_active( act ); - gchar orthog_str[] = "orthogonal"; - gchar polyline_str[] = "polyline"; - gchar *value = is_orthog ? orthog_str : polyline_str ; - - bool modmade = false; - auto itemlist= desktop->getSelection()->items(); - for(auto i=itemlist.begin();i!=itemlist.end();++i){ - SPItem *item = *i; - - if (Inkscape::UI::Tools::cc_item_is_connector(item)) { - item->setAttribute( "inkscape:connector-type", - value, NULL); - item->avoidRef->handleSettingChange(); - modmade = true; - } - } - - if (!modmade) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setBool("/tools/connector/orthogonal", is_orthog); - } else { - - DocumentUndo::done(doc, SP_VERB_CONTEXT_CONNECTOR, - is_orthog ? _("Set connector type: orthogonal"): _("Set connector type: polyline")); - } - - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -} - -static void connector_curvature_changed(GtkAdjustment *adj, GObject* tbl) -{ - SPDesktop *desktop = static_cast(g_object_get_data( tbl, "desktop" )); - SPDocument *doc = desktop->getDocument(); - - if (!DocumentUndo::getUndoSensitive(doc)) { - return; - } - - - // quit if run by the _changed callbacks - if (g_object_get_data( tbl, "freeze" )) { - return; - } - - // in turn, prevent callbacks from responding - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - - gdouble newValue = gtk_adjustment_get_value(adj); - gchar value[G_ASCII_DTOSTR_BUF_SIZE]; - g_ascii_dtostr(value, G_ASCII_DTOSTR_BUF_SIZE, newValue); - - bool modmade = false; - auto itemlist= desktop->getSelection()->items(); - for(auto i=itemlist.begin();i!=itemlist.end();++i){ - SPItem *item = *i; - - if (Inkscape::UI::Tools::cc_item_is_connector(item)) { - item->setAttribute( "inkscape:connector-curvature", - value, NULL); - item->avoidRef->handleSettingChange(); - modmade = true; - } - } - - if (!modmade) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble(Glib::ustring("/tools/connector/curvature"), newValue); - } - else { - DocumentUndo::done(doc, SP_VERB_CONTEXT_CONNECTOR, - _("Change connector curvature")); - } - - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -} - - -static void connector_spacing_changed(GtkAdjustment *adj, GObject* tbl) -{ - SPDesktop *desktop = static_cast(g_object_get_data( tbl, "desktop" )); - SPDocument *doc = desktop->getDocument(); - - if (!DocumentUndo::getUndoSensitive(doc)) { - return; - } - - Inkscape::XML::Node *repr = desktop->namedview->getRepr(); - - if ( !repr->attribute("inkscape:connector-spacing") && - ( gtk_adjustment_get_value(adj) == defaultConnSpacing )) { - // Don't need to update the repr if the attribute doesn't - // exist and it is being set to the default value -- as will - // happen at startup. - return; - } - - // quit if run by the attr_changed listener - if (g_object_get_data( tbl, "freeze" )) { - return; - } - - // in turn, prevent listener from responding - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE)); - - sp_repr_set_css_double(repr, "inkscape:connector-spacing", gtk_adjustment_get_value(adj)); - desktop->namedview->updateRepr(); - bool modmade = false; - - std::vector items; - items = get_avoided_items(items, desktop->currentRoot(), desktop); - for (std::vector::const_iterator iter = items.begin(); iter != items.end(); ++iter ) { - SPItem *item = *iter; - Geom::Affine m = Geom::identity(); - avoid_item_move(&m, item); - modmade = true; - } - - if(modmade) { - DocumentUndo::done(doc, SP_VERB_CONTEXT_CONNECTOR, - _("Change connector spacing")); - } - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -} - -static void sp_connector_graph_layout(void) -{ - if (!SP_ACTIVE_DESKTOP) { - return; - } - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - - // hack for clones, see comment in align-and-distribute.cpp - int saved_compensation = prefs->getInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED); - prefs->setInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED); - - auto tmp = SP_ACTIVE_DESKTOP->getSelection()->items(); - std::vector vec(tmp.begin(), tmp.end()); - graphlayout(vec); - - prefs->setInt("/options/clonecompensation/value", saved_compensation); - - DocumentUndo::done(SP_ACTIVE_DESKTOP->getDocument(), SP_VERB_DIALOG_ALIGN_DISTRIBUTE, _("Arrange connector network")); -} - -static void sp_directed_graph_layout_toggled( GtkToggleAction* act, GObject * /*tbl*/ ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setBool("/tools/connector/directedlayout", - gtk_toggle_action_get_active( act )); -} - -static void sp_nooverlaps_graph_layout_toggled( GtkToggleAction* act, GObject * /*tbl*/ ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setBool("/tools/connector/avoidoverlaplayout", - gtk_toggle_action_get_active( act )); -} - - -static void connector_length_changed(GtkAdjustment *adj, GObject* /*tbl*/) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble("/tools/connector/length", gtk_adjustment_get_value(adj)); -} - -static void connector_tb_event_attr_changed(Inkscape::XML::Node *repr, - gchar const *name, gchar const * /*old_value*/, gchar const * /*new_value*/, - bool /*is_interactive*/, gpointer data) -{ - GtkWidget *tbl = GTK_WIDGET(data); - - if ( !g_object_get_data(G_OBJECT(tbl), "freeze") - && (strcmp(name, "inkscape:connector-spacing") == 0) ) { - GtkAdjustment *adj = static_cast(g_object_get_data(G_OBJECT(tbl), "spacing")); - gdouble spacing = defaultConnSpacing; - sp_repr_get_double(repr, "inkscape:connector-spacing", &spacing); - - gtk_adjustment_set_value(adj, spacing); - -#if !GTK_CHECK_VERSION(3,18,0) - gtk_adjustment_value_changed(adj); -#endif - - spinbutton_defocus(tbl); - } -} - -static Inkscape::XML::NodeEventVector connector_tb_repr_events = { - NULL, /* child_added */ - NULL, /* child_removed */ - connector_tb_event_attr_changed, - NULL, /* content_changed */ - NULL /* order_changed */ -}; - -static void sp_connector_toolbox_selection_changed(Inkscape::Selection *selection, GObject *tbl) -{ - GtkAdjustment *adj = GTK_ADJUSTMENT( g_object_get_data( tbl, "curvature" ) ); - GtkToggleAction *act = GTK_TOGGLE_ACTION( g_object_get_data( tbl, "orthogonal" ) ); - SPItem *item = selection->singleItem(); - if (SP_IS_PATH(item)) - { - gdouble curvature = SP_PATH(item)->connEndPair.getCurvature(); - bool is_orthog = SP_PATH(item)->connEndPair.isOrthogonal(); - gtk_toggle_action_set_active(act, is_orthog); - gtk_adjustment_set_value(adj, curvature); - } - -} - -void sp_connector_toolbox_prep( SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - GtkIconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1); - - { - InkAction* inky = ink_action_new( "ConnectorAvoidAction", - _("Avoid"), - _("Make connectors avoid selected objects"), - INKSCAPE_ICON("connector-avoid"), - secondarySize ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_connector_path_set_avoid), holder ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - } - - { - InkAction* inky = ink_action_new( "ConnectorIgnoreAction", - _("Ignore"), - _("Make connectors ignore selected objects"), - INKSCAPE_ICON("connector-ignore"), - secondarySize ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_connector_path_set_ignore), holder ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - } - - // Orthogonal connectors toggle button - { - InkToggleAction* act = ink_toggle_action_new( "ConnectorOrthogonalAction", - _("Orthogonal"), - _("Make connector orthogonal or polyline"), - INKSCAPE_ICON("connector-orthogonal"), - GTK_ICON_SIZE_MENU ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - - bool tbuttonstate = prefs->getBool("/tools/connector/orthogonal"); - gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act), ( tbuttonstate ? TRUE : FALSE )); - g_object_set_data( holder, "orthogonal", act ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_connector_orthogonal_toggled), holder ); - } - - EgeAdjustmentAction* eact = 0; - // Curvature spinbox - eact = create_adjustment_action( "ConnectorCurvatureAction", - _("Connector Curvature"), _("Curvature:"), - _("The amount of connectors curvature"), - "/tools/connector/curvature", defaultConnCurvature, - GTK_WIDGET(desktop->canvas), holder, TRUE, "inkscape:connector-curvature", - 0, 100, 1.0, 10.0, - 0, 0, 0, - connector_curvature_changed, NULL /*unit tracker*/, 1, 0 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - - // Spacing spinbox - eact = create_adjustment_action( "ConnectorSpacingAction", - _("Connector Spacing"), _("Spacing:"), - _("The amount of space left around objects by auto-routing connectors"), - "/tools/connector/spacing", defaultConnSpacing, - GTK_WIDGET(desktop->canvas), holder, TRUE, "inkscape:connector-spacing", - 0, 100, 1.0, 10.0, - 0, 0, 0, - connector_spacing_changed, NULL /*unit tracker*/, 1, 0 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - - // Graph (connector network) layout - { - InkAction* inky = ink_action_new( "ConnectorGraphAction", - _("Graph"), - _("Nicely arrange selected connector network"), - INKSCAPE_ICON("distribute-graph"), - secondarySize ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_connector_graph_layout), holder ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - } - - // Default connector length spinbox - eact = create_adjustment_action( "ConnectorLengthAction", - _("Connector Length"), _("Length:"), - _("Ideal length for connectors when layout is applied"), - "/tools/connector/length", 100, - GTK_WIDGET(desktop->canvas), holder, TRUE, "inkscape:connector-length", - 10, 1000, 10.0, 100.0, - 0, 0, 0, - connector_length_changed, NULL /*unit tracker*/, 1, 0 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - - - // Directed edges toggle button - { - InkToggleAction* act = ink_toggle_action_new( "ConnectorDirectedAction", - _("Downwards"), - _("Make connectors with end-markers (arrows) point downwards"), - INKSCAPE_ICON("distribute-graph-directed"), - GTK_ICON_SIZE_MENU ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - - bool tbuttonstate = prefs->getBool("/tools/connector/directedlayout"); - gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act), ( tbuttonstate ? TRUE : FALSE )); - - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_directed_graph_layout_toggled), holder ); - desktop->getSelection()->connectChanged(sigc::bind(sigc::ptr_fun(sp_connector_toolbox_selection_changed), holder)); - } - - // Avoid overlaps toggle button - { - InkToggleAction* act = ink_toggle_action_new( "ConnectorOverlapAction", - _("Remove overlaps"), - _("Do not allow overlapping shapes"), - INKSCAPE_ICON("distribute-remove-overlaps"), - GTK_ICON_SIZE_MENU ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - - bool tbuttonstate = prefs->getBool("/tools/connector/avoidoverlaplayout"); - gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act), (tbuttonstate ? TRUE : FALSE )); - - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_nooverlaps_graph_layout_toggled), holder ); - } - - - // Code to watch for changes to the connector-spacing attribute in - // the XML. - Inkscape::XML::Node *repr = desktop->namedview->getRepr(); - g_assert(repr != NULL); - - purge_repr_listener( holder, holder ); - - if (repr) { - g_object_set_data( holder, "repr", repr ); - Inkscape::GC::anchor(repr); - sp_repr_add_listener( repr, &connector_tb_repr_events, holder ); - sp_repr_synthesize_events( repr, &connector_tb_repr_events, holder ); - } -} // end of sp_connector_toolbox_prep() - - -/* - 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:fileencoding=utf-8:textwidth=99 : diff --git a/src/widgets/connector-toolbar.h b/src/widgets/connector-toolbar.h deleted file mode 100644 index 180c11e0f..000000000 --- a/src/widgets/connector-toolbar.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef SEEN_CONNECTOR_TOOLBAR_H -#define SEEN_CONNECTOR_TOOLBAR_H - -/** - * @file - * Connector aux toolbar - */ -/* Authors: - * MenTaLguY - * Lauris Kaplinski - * bulia byak - * Frank Felfe - * John Cliff - * David Turner - * Josh Andler - * Jon A. Cruz - * Maximilian Albert - * Tavmjong Bah - * Abhishek Sharma - * Kris De Gussem - * - * Copyright (C) 2004 David Turner - * Copyright (C) 2003 MenTaLguY - * Copyright (C) 1999-2011 authors - * Copyright (C) 2001-2002 Ximian, Inc. - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -class SPDesktop; - -typedef struct _GtkActionGroup GtkActionGroup; -typedef struct _GObject GObject; - -void sp_connector_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); - -#endif /* !SEEN_CONNECTOR_TOOLBAR_H */ diff --git a/src/widgets/dropper-toolbar.cpp b/src/widgets/dropper-toolbar.cpp deleted file mode 100644 index 7a9cf1779..000000000 --- a/src/widgets/dropper-toolbar.cpp +++ /dev/null @@ -1,127 +0,0 @@ -/** - * @file - * Dropper aux toolbar - */ -/* Authors: - * MenTaLguY - * Lauris Kaplinski - * bulia byak - * Frank Felfe - * John Cliff - * David Turner - * Josh Andler - * Jon A. Cruz - * Maximilian Albert - * Tavmjong Bah - * Abhishek Sharma - * Kris De Gussem - * - * Copyright (C) 2004 David Turner - * Copyright (C) 2003 MenTaLguY - * Copyright (C) 1999-2011 authors - * Copyright (C) 2001-2002 Ximian, Inc. - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include - -#include "dropper-toolbar.h" -#include "document-undo.h" -#include "widgets/ege-output-action.h" -#include "ink-toggle-action.h" -#include "preferences.h" -#include "widgets/spinbutton-events.h" - -using Inkscape::DocumentUndo; - -//######################## -//## Dropper ## -//######################## - -static void toggle_dropper_pick_alpha( GtkToggleAction* act, gpointer tbl ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setInt( "/tools/dropper/pick", gtk_toggle_action_get_active( act ) ); - GtkAction* set_action = GTK_ACTION( g_object_get_data(G_OBJECT(tbl), "set_action") ); - if ( set_action ) { - if ( gtk_toggle_action_get_active( act ) ) { - gtk_action_set_sensitive( set_action, TRUE ); - } else { - gtk_action_set_sensitive( set_action, FALSE ); - } - } - - spinbutton_defocus(GTK_WIDGET(tbl)); -} - -static void toggle_dropper_set_alpha( GtkToggleAction* act, gpointer tbl ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setBool( "/tools/dropper/setalpha", gtk_toggle_action_get_active( act ) ); - spinbutton_defocus(GTK_WIDGET(tbl)); -} - - -/** - * Dropper auxiliary toolbar construction and setup. - * - * TODO: Would like to add swatch of current color. - * TODO: Add queue of last 5 or so colors selected with new swatches so that - * can drag and drop places. Will provide a nice mixing palette. - */ -void sp_dropper_toolbox_prep(SPDesktop * /*desktop*/, GtkActionGroup* mainActions, GObject* holder) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - gint pickAlpha = prefs->getInt( "/tools/dropper/pick", 1 ); - - { - EgeOutputAction* act = ege_output_action_new( "DropperOpacityAction", _("Opacity:"), "", 0 ); - ege_output_action_set_use_markup( act, TRUE ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - } - - { - InkToggleAction* act = ink_toggle_action_new( "DropperPickAlphaAction", - _("Pick opacity"), - _("Pick both the color and the alpha (transparency) under cursor; otherwise, pick only the visible color premultiplied by alpha"), - NULL, - GTK_ICON_SIZE_MENU ); - g_object_set( act, "short_label", _("Pick"), NULL ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - g_object_set_data( holder, "pick_action", act ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), pickAlpha ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_dropper_pick_alpha), holder ); - } - - { - InkToggleAction* act = ink_toggle_action_new( "DropperSetAlphaAction", - _("Assign opacity"), - _("If alpha was picked, assign it to selection as fill or stroke transparency"), - NULL, - GTK_ICON_SIZE_MENU ); - g_object_set( act, "short_label", _("Assign"), NULL ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - g_object_set_data( holder, "set_action", act ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool( "/tools/dropper/setalpha", true) ); - // make sure it's disabled if we're not picking alpha - gtk_action_set_sensitive( GTK_ACTION(act), pickAlpha ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_dropper_set_alpha), holder ); - } -} - - -/* - 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:fileencoding=utf-8:textwidth=99 : diff --git a/src/widgets/dropper-toolbar.h b/src/widgets/dropper-toolbar.h deleted file mode 100644 index 8d5ea2d0a..000000000 --- a/src/widgets/dropper-toolbar.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef SEEN_DROPPER_TOOLBAR_H -#define SEEN_DROPPER_TOOLBAR_H - -/** - * @file - * Dropper aux toolbar - */ -/* Authors: - * MenTaLguY - * Lauris Kaplinski - * bulia byak - * Frank Felfe - * John Cliff - * David Turner - * Josh Andler - * Jon A. Cruz - * Maximilian Albert - * Tavmjong Bah - * Abhishek Sharma - * Kris De Gussem - * - * Copyright (C) 2004 David Turner - * Copyright (C) 2003 MenTaLguY - * Copyright (C) 1999-2011 authors - * Copyright (C) 2001-2002 Ximian, Inc. - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -class SPDesktop; - -typedef struct _GtkActionGroup GtkActionGroup; -typedef struct _GObject GObject; - -void sp_dropper_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); - -#endif /* !SEEN_DROPPER_TOOLBAR_H */ diff --git a/src/widgets/eraser-toolbar.cpp b/src/widgets/eraser-toolbar.cpp deleted file mode 100644 index 3f6dd6b12..000000000 --- a/src/widgets/eraser-toolbar.cpp +++ /dev/null @@ -1,320 +0,0 @@ -/** - * @file - * Erasor aux toolbar - */ -/* Authors: - * MenTaLguY - * Lauris Kaplinski - * bulia byak - * Frank Felfe - * John Cliff - * David Turner - * Josh Andler - * Jon A. Cruz - * Maximilian Albert - * Tavmjong Bah - * Abhishek Sharma - * Kris De Gussem - * - * Copyright (C) 2004 David Turner - * Copyright (C) 2003 MenTaLguY - * Copyright (C) 1999-2011 authors - * Copyright (C) 2001-2002 Ximian, Inc. - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include - -#include "eraser-toolbar.h" - -#include - -#include "desktop.h" -#include "document-undo.h" -#include "widgets/ege-adjustment-action.h" -#include "ink-action.h" -#include "ink-radio-action.h" -#include "ink-toggle-action.h" -#include "toolbox.h" -#include "ui/widget/ink-select-one-action.h" -#include "ui/icon-names.h" -#include "ui/tools/eraser-tool.h" - -using Inkscape::DocumentUndo; -using Inkscape::UI::ToolboxFactory; -using Inkscape::UI::PrefPusher; - -//######################## -//## Eraser ## -//######################## - -// A dummy function for PrefPusher. -// The code was calling the update_presets_list function in the calligraphy tool -// which was immediately returning. TODO: Investigate this further. -void eraser_update_presets_list(GObject *tbl) -{ - return; -} - -static void sp_erc_width_value_changed( GtkAdjustment *adj, GObject *tbl ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble( "/tools/eraser/width", gtk_adjustment_get_value(adj) ); -} - -static void sp_erc_mass_value_changed( GtkAdjustment *adj, GObject* tbl ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble( "/tools/eraser/mass", gtk_adjustment_get_value(adj) ); -} - -static void sp_erc_velthin_value_changed( GtkAdjustment *adj, GObject* tbl ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble("/tools/eraser/thinning", gtk_adjustment_get_value(adj) ); -} - -static void sp_erc_cap_rounding_value_changed( GtkAdjustment *adj, GObject* tbl ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble( "/tools/eraser/cap_rounding", gtk_adjustment_get_value(adj) ); -} - -static void sp_erc_tremor_value_changed( GtkAdjustment *adj, GObject* tbl ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble( "/tools/eraser/tremor", gtk_adjustment_get_value(adj) ); -} - -static void sp_set_tbl_eraser_mode_visibility(GObject *const tbl, const guint eraser_mode) -{ - gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "split") ), (eraser_mode == ERASER_MODE_CUT)); - - const gboolean visibility = (eraser_mode != ERASER_MODE_DELETE); - const std::array arr = {"cap_rounding", "mass", "thinning", "tremor", "usepressure", "width"}; - for (const gchar * str : arr) { - gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, str) ), visibility ); - } -} - -static void sp_erasertb_mode_changed( GObject *tbl, int mode ) -{ - SPDesktop *desktop = static_cast(g_object_get_data( tbl, "desktop" )); - if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setInt( "/tools/eraser/mode", mode ); - } - sp_set_tbl_eraser_mode_visibility(tbl, mode); - - // only take action if run by the attr_changed listener - if (!g_object_get_data( tbl, "freeze" )) { - // in turn, prevent listener from responding - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - - /* - if ( eraser_mode != ERASER_MODE_DELETE ) { - } else { - } - */ - // TODO finish implementation - - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); - } -} - -static void sp_toggle_break_apart( GtkToggleAction* act, gpointer data ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - gboolean active = gtk_toggle_action_get_active(act); - prefs->setBool("/tools/eraser/break_apart", active); -} - -void sp_eraser_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) -{ - GtkIconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - gint eraser_mode = ERASER_MODE_DELETE; - - { - InkSelectOneActionColumns columns; - - Glib::RefPtr store = Gtk::ListStore::create(columns); - - Gtk::TreeModel::Row row; - - row = *(store->append()); - row[columns.col_label ] = _("Delete"); - row[columns.col_tooltip ] = _("Delete objects touched by eraser"); - row[columns.col_icon ] = INKSCAPE_ICON("draw-eraser-delete-objects"); - row[columns.col_sensitive] = true; - - row = *(store->append()); - row[columns.col_label ] = _("Cut"); - row[columns.col_tooltip ] = _("Cut out from paths and shapes"); - row[columns.col_icon ] = INKSCAPE_ICON("path-difference"); - row[columns.col_sensitive] = true; - - row = *(store->append()); - row[columns.col_label ] = _("Clip"); - row[columns.col_tooltip ] = _("Clip from objects"); - row[columns.col_icon ] = INKSCAPE_ICON("path-intersection"); - row[columns.col_sensitive] = true; - - InkSelectOneAction* act = - InkSelectOneAction::create( "EraserModeAction", // Name - _("Mode"), // Label - "", // Tooltip - "Not Used", // Icon - store ); // Tree store - act->use_radio( true ); - act->use_group_label( true ); - eraser_mode = prefs->getInt("/tools/eraser/mode", ERASER_MODE_CLIP); // Used at end - act->set_active( eraser_mode ); - - gtk_action_group_add_action( mainActions, GTK_ACTION( act->gobj() )); - g_object_set_data( holder, "EraserModeAction", act ); - - act->signal_changed().connect(sigc::bind<0>(sigc::ptr_fun(&sp_erasertb_mode_changed), holder)); - } - - - /* Width */ - { - gchar const* labels[] = {_("(no width)"),_("(hairline)"), 0, 0, 0, _("(default)"), 0, 0, 0, 0, _("(broad stroke)")}; - gdouble values[] = {0, 1, 3, 5, 10, 15, 20, 30, 50, 75, 100}; - EgeAdjustmentAction *eact = create_adjustment_action( "EraserWidthAction", - _("Pen Width"), _("Width:"), - _("The width of the eraser pen (relative to the visible canvas area)"), - "/tools/eraser/width", 15, - GTK_WIDGET(desktop->canvas), holder, TRUE, "altx-eraser", - 0, 100, 1.0, 10.0, - labels, values, G_N_ELEMENTS(labels), - sp_erc_width_value_changed, NULL /*unit tracker*/, 1, 0); - ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - g_object_set_data( holder, "width", eact ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - } - - - /* Use Pressure button */ - { - InkToggleAction* act = ink_toggle_action_new( "EraserPressureAction", - _("Eraser Pressure"), - _("Use the pressure of the input device to alter the width of the pen"), - INKSCAPE_ICON("draw-use-pressure"), - GTK_ICON_SIZE_MENU ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(act), "/tools/eraser/usepressure", eraser_update_presets_list, holder); - g_signal_connect( holder, "destroy", G_CALLBACK(delete_prefspusher), pusher); - g_object_set_data( holder, "usepressure", act ); - } - - - /* Thinning */ - { - gchar const* labels[] = {_("(speed blows up stroke)"), 0, 0, _("(slight widening)"), _("(constant width)"), _("(slight thinning, default)"), 0, 0, _("(speed deflates stroke)")}; - gdouble values[] = {-100, -40, -20, -10, 0, 10, 20, 40, 100}; - EgeAdjustmentAction* eact = create_adjustment_action( "EraserThinningAction", - _("Eraser Stroke Thinning"), _("Thinning:"), - _("How much velocity thins the stroke (> 0 makes fast strokes thinner, < 0 makes them broader, 0 makes width independent of velocity)"), - "/tools/eraser/thinning", 10, - GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, - -100, 100, 1, 10.0, - labels, values, G_N_ELEMENTS(labels), - sp_erc_velthin_value_changed, NULL /*unit tracker*/, 1, 0); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - g_object_set_data( holder, "thinning", eact ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - } - - - /* Cap Rounding */ - { - gchar const* labels[] = {_("(blunt caps, default)"), _("(slightly bulging)"), 0, 0, _("(approximately round)"), _("(long protruding caps)")}; - gdouble values[] = {0, 0.3, 0.5, 1.0, 1.4, 5.0}; - // TRANSLATORS: "cap" means "end" (both start and finish) here - EgeAdjustmentAction* eact = create_adjustment_action( "EraserCapRoundingAction", - _("Eraser Cap rounding"), _("Caps:"), - _("Increase to make caps at the ends of strokes protrude more (0 = no caps, 1 = round caps)"), - "/tools/eraser/cap_rounding", 0.0, - GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, - 0.0, 5.0, 0.01, 0.1, - labels, values, G_N_ELEMENTS(labels), - sp_erc_cap_rounding_value_changed, NULL /*unit tracker*/, 0.01, 2 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - g_object_set_data( holder, "cap_rounding", eact ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - } - - - /* Tremor */ - { - gchar const* labels[] = {_("(smooth line)"), _("(slight tremor)"), _("(noticeable tremor)"), 0, 0, _("(maximum tremor)")}; - gdouble values[] = {0, 10, 20, 40, 60, 100}; - EgeAdjustmentAction* eact = create_adjustment_action( "EraserTremorAction", - _("EraserStroke Tremor"), _("Tremor:"), - _("Increase to make strokes rugged and trembling"), - "/tools/eraser/tremor", 0.0, - GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, - 0.0, 100, 1, 10.0, - labels, values, G_N_ELEMENTS(labels), - sp_erc_tremor_value_changed, NULL /*unit tracker*/, 1, 0); - - ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); - g_object_set_data( holder, "tremor", eact ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - } - - - /* Mass */ - { - gchar const* labels[] = {_("(no inertia)"), _("(slight smoothing, default)"), _("(noticeable lagging)"), 0, 0, _("(maximum inertia)")}; - gdouble values[] = {0.0, 2, 10, 20, 50, 100}; - EgeAdjustmentAction* eact = create_adjustment_action( "EraserMassAction", - _("Eraser Mass"), _("Mass:"), - _("Increase to make the eraser drag behind, as if slowed by inertia"), - "/tools/eraser/mass", 10.0, - GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, - 0.0, 100, 1, 10.0, - labels, values, G_N_ELEMENTS(labels), - sp_erc_mass_value_changed, NULL /*unit tracker*/, 1, 0); - ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); - g_object_set_data( holder, "mass", eact ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - } - - - /* Overlap */ - { - InkToggleAction* act = ink_toggle_action_new( "EraserBreakAppart", - _("Break apart cut items"), - _("Break apart cut items"), - INKSCAPE_ICON("distribute-randomize"), - secondarySize ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/eraser/break_apart", false) ); - g_object_set_data( holder, "split", act ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_break_apart), holder) ; - gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); - } - - sp_set_tbl_eraser_mode_visibility(holder, eraser_mode); -} - -/* - 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:fileencoding=utf-8:textwidth=99 : diff --git a/src/widgets/eraser-toolbar.h b/src/widgets/eraser-toolbar.h deleted file mode 100644 index 3c88d344e..000000000 --- a/src/widgets/eraser-toolbar.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef SEEN_ERASOR_TOOLBAR_H -#define SEEN_ERASOR_TOOLBAR_H - -/** - * @file - * Erasor aux toolbar - */ -/* Authors: - * MenTaLguY - * Lauris Kaplinski - * bulia byak - * Frank Felfe - * John Cliff - * David Turner - * Josh Andler - * Jon A. Cruz - * Maximilian Albert - * Tavmjong Bah - * Abhishek Sharma - * Kris De Gussem - * - * Copyright (C) 2004 David Turner - * Copyright (C) 2003 MenTaLguY - * Copyright (C) 1999-2011 authors - * Copyright (C) 2001-2002 Ximian, Inc. - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -class SPDesktop; - -typedef struct _GtkActionGroup GtkActionGroup; -typedef struct _GObject GObject; - -void sp_eraser_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); - -#endif /* !SEEN_ERASOR_TOOLBAR_H */ 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 - * Johan Engelen - * 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 -#endif - -#include - - -#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(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::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 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 gl; - std::vector gradients = document->getResourceList( "gradient" ); - for (std::vector::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::const_iterator it = gl.begin(); it != gl.end(); ++it) { - SPGradient *gradient = SP_GRADIENT(*it); - - Glib::ustring label = gr_prepare_label(gradient); - Glib::RefPtr 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::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(g_object_get_data(data, "gradient_stop_action")); - - int active = act->get_active(); - - Glib::RefPtr store = act->get_store(); - Gtk::TreeModel::Row row = store->children()[active]; - InkSelectOneActionColumns columns; - void* pointer = row[columns.col_data]; - SPStop *stop = static_cast(pointer); - - return stop; -} - -/* Add stop to gradient */ -static void gr_add_stop(GtkWidget * /*button*/, GObject *data) -{ - SPDesktop *desktop = static_cast(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(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(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(g_object_get_data(data, "gradient_stop_action")); - Glib::RefPtr 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 pixbuf = sp_gradstop_to_pixbuf_ref (stop, 32, 16); - - Inkscape::XML::Node *repr = reinterpret_cast(&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(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 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(g_object_get_data(data, "gradient_select_action")); - - int active = act->get_active(); - - Glib::RefPtr store = act->get_store(); - Gtk::TreeModel::Row row = store->children()[active]; - InkSelectOneActionColumns columns; - - void* pointer = row[columns.col_data]; - SPGradient *gr = static_cast(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(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(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(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(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 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 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 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 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 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(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(g_object_get_data(data, "gradient_select_action")); - Glib::RefPtr 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(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 : diff --git a/src/widgets/gradient-toolbar.h b/src/widgets/gradient-toolbar.h deleted file mode 100644 index 38afb743b..000000000 --- a/src/widgets/gradient-toolbar.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef SEEN_GRADIENT_TOOLBAR_H -#define SEEN_GRADIENT_TOOLBAR_H - -/* - * Gradient aux toolbar - * - * Authors: - * bulia byak - * - * Copyright (C) 2005 authors - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -class SPDesktop; - -typedef struct _GtkActionGroup GtkActionGroup; -typedef struct _GObject GObject; - -void sp_gradient_toolbox_prep(SPDesktop * /*desktop*/, GtkActionGroup* mainActions, GObject* holder); - -#endif /* !SEEN_GRADIENT_TOOLBAR_H */ diff --git a/src/widgets/lpe-toolbar.cpp b/src/widgets/lpe-toolbar.cpp deleted file mode 100644 index 3e3a2e95c..000000000 --- a/src/widgets/lpe-toolbar.cpp +++ /dev/null @@ -1,453 +0,0 @@ -/** - * @file - * LPE aux toolbar - */ -/* Authors: - * MenTaLguY - * Lauris Kaplinski - * bulia byak - * Frank Felfe - * John Cliff - * David Turner - * Josh Andler - * Jon A. Cruz - * Maximilian Albert - * Tavmjong Bah - * Abhishek Sharma - * Kris De Gussem - * - * Copyright (C) 2004 David Turner - * Copyright (C) 2003 MenTaLguY - * Copyright (C) 1999-2011 authors - * Copyright (C) 2001-2002 Ximian, Inc. - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "live_effects/lpe-line_segment.h" -#include "lpe-toolbar.h" - -#include "helper/action-context.h" -#include "helper/action.h" - -#include "ink-radio-action.h" -#include "ink-toggle-action.h" - -#include "ui/tools-switch.h" -#include "ui/tools/lpe-tool.h" -#include "ui/widget/ink-select-one-action.h" -#include "ui/widget/unit-tracker.h" - -using Inkscape::UI::Widget::UnitTracker; -using Inkscape::Util::Unit; -using Inkscape::Util::Quantity; -using Inkscape::DocumentUndo; -using Inkscape::UI::Tools::ToolBase; -using Inkscape::UI::Tools::LpeTool; - - -//######################## -//## LPETool ## -//######################## - -// the subtools from which the toolbar is built automatically are listed in lpe-tool-context.h - -// this is called when the mode is changed via the toolbar (i.e., one of the subtool buttons is pressed) -static void sp_lpetool_mode_changed(GObject *tbl, int mode) -{ - using namespace Inkscape::LivePathEffect; - - SPDesktop *desktop = static_cast(g_object_get_data(tbl, "desktop")); - ToolBase *ec = desktop->event_context; - if (!SP_IS_LPETOOL_CONTEXT(ec)) { - return; - } - - // only take action if run by the attr_changed listener - if (!g_object_get_data(tbl, "freeze")) { - // in turn, prevent listener from responding - g_object_set_data(tbl, "freeze", GINT_TO_POINTER(TRUE)); - - EffectType type = lpesubtools[mode].type; - - LpeTool *lc = SP_LPETOOL_CONTEXT(desktop->event_context); - bool success = lpetool_try_construction(lc, type); - if (success) { - // since the construction was already performed, we set the state back to inactive - InkSelectOneAction* act = - static_cast( g_object_get_data( tbl, "lpetool_mode_action" ) ); - act->set_active(0); - mode = 0; - } else { - // switch to the chosen subtool - SP_LPETOOL_CONTEXT(desktop->event_context)->mode = type; - } - - if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setInt( "/tools/lpetool/mode", mode ); - } - - g_object_set_data(tbl, "freeze", GINT_TO_POINTER(FALSE)); - } -} - -static void sp_lpetool_toolbox_sel_modified(Inkscape::Selection *selection, guint /*flags*/, GObject * /*tbl*/) -{ - ToolBase *ec = selection->desktop()->event_context; - if (SP_IS_LPETOOL_CONTEXT(ec)) { - lpetool_update_measuring_items(SP_LPETOOL_CONTEXT(ec)); - } -} - -static void sp_lpetool_toolbox_sel_changed(Inkscape::Selection *selection, GObject *tbl) -{ - using namespace Inkscape::LivePathEffect; - ToolBase *ec = selection->desktop()->event_context; - if (!SP_IS_LPETOOL_CONTEXT(ec)) { - return; - } - LpeTool *lc = SP_LPETOOL_CONTEXT(ec); - - lpetool_delete_measuring_items(lc); - lpetool_create_measuring_items(lc, selection); - - // activate line segment combo box if a single item with LPELineSegment is selected - InkSelectOneAction* act = - static_cast( g_object_get_data( tbl, "lpetool_line_segment_action" ) ); - - SPItem *item = selection->singleItem(); - if (item && SP_IS_LPE_ITEM(item) && lpetool_item_has_construction(lc, item)) { - - SPLPEItem *lpeitem = SP_LPE_ITEM(item); - Effect* lpe = lpeitem->getCurrentLPE(); - if (lpe && lpe->effectType() == LINE_SEGMENT) { - LPELineSegment *lpels = static_cast(lpe); - g_object_set_data(tbl, "currentlpe", lpe); - g_object_set_data(tbl, "currentlpeitem", lpeitem); - act->set_sensitive(true); - act->set_active( lpels->end_type.get_value() ); - } else { - g_object_set_data(tbl, "currentlpe", NULL); - g_object_set_data(tbl, "currentlpeitem", NULL); - act->set_sensitive(false); - } - - } else { - g_object_set_data(tbl, "currentlpe", NULL); - g_object_set_data(tbl, "currentlpeitem", NULL); - act->set_sensitive(false); - } -} - -static void lpetool_toggle_show_bbox(GtkToggleAction *act, gpointer data) { - SPDesktop *desktop = static_cast(data); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - - bool show = gtk_toggle_action_get_active( act ); - prefs->setBool("/tools/lpetool/show_bbox", show); - - if (tools_isactive(desktop, TOOLS_LPETOOL)) { - LpeTool *lc = SP_LPETOOL_CONTEXT(desktop->event_context); - lpetool_context_reset_limiting_bbox(lc); - } -} - -static void lpetool_toggle_show_measuring_info(GtkToggleAction *act, GObject *tbl) -{ - SPDesktop *desktop = static_cast(g_object_get_data(tbl, "desktop")); - if (!tools_isactive(desktop, TOOLS_LPETOOL)) { - return; - } - - bool show = gtk_toggle_action_get_active( act ); - - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setBool("/tools/lpetool/show_measuring_info", show); - - LpeTool *lc = SP_LPETOOL_CONTEXT(desktop->event_context); - lpetool_show_measuring_info(lc, show); - - InkSelectOneAction* unitact = - static_cast(g_object_get_data(tbl, "lpetool_units_action")); - unitact->set_sensitive( show ); -} - -static void lpetool_unit_changed(GObject* tbl, int /* NotUsed */) -{ - UnitTracker* tracker = reinterpret_cast(g_object_get_data(tbl, "tracker")); - Unit const *unit = tracker->getActiveUnit(); - g_return_if_fail(unit != NULL); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setString("/tools/lpetool/unit", unit->abbr); - - SPDesktop *desktop = static_cast(g_object_get_data( tbl, "desktop" )); - if (SP_IS_LPETOOL_CONTEXT(desktop->event_context)) { - LpeTool *lc = SP_LPETOOL_CONTEXT(desktop->event_context); - lpetool_delete_measuring_items(lc); - lpetool_create_measuring_items(lc); - } -} - -static void lpetool_toggle_set_bbox(GtkToggleAction *act, gpointer data) -{ - SPDesktop *desktop = static_cast(data); - Inkscape::Selection *selection = desktop->selection; - - Geom::OptRect bbox = selection->visualBounds(); - - if (bbox) { - Geom::Point A(bbox->min()); - Geom::Point B(bbox->max()); - - A *= desktop->doc2dt(); - B *= desktop->doc2dt(); - - // TODO: should we provide a way to store points in prefs? - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble("/tools/lpetool/bbox_upperleftx", A[Geom::X]); - prefs->setDouble("/tools/lpetool/bbox_upperlefty", A[Geom::Y]); - prefs->setDouble("/tools/lpetool/bbox_lowerrightx", B[Geom::X]); - prefs->setDouble("/tools/lpetool/bbox_lowerrighty", B[Geom::Y]); - - lpetool_context_reset_limiting_bbox(SP_LPETOOL_CONTEXT(desktop->event_context)); - } - - gtk_toggle_action_set_active(act, false); -} - -static void sp_lpetool_change_line_segment_type(GObject* tbl, int mode) -{ - using namespace Inkscape::LivePathEffect; - - // quit if run by the attr_changed listener - if (g_object_get_data(tbl, "freeze")) { - return; - } - - // in turn, prevent listener from responding - g_object_set_data(tbl, "freeze", GINT_TO_POINTER(TRUE)); - - LPELineSegment *lpe = static_cast(g_object_get_data(tbl, "currentlpe")); - SPLPEItem *lpeitem = static_cast(g_object_get_data(tbl, "currentlpeitem")); - if (lpeitem) { - SPLPEItem *lpeitem = static_cast(g_object_get_data(tbl, "currentlpeitem")); - lpe->end_type.param_set_value(static_cast(mode)); - sp_lpe_item_update_patheffect(lpeitem, true, true); - } - - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -} - -static void lpetool_open_lpe_dialog(GtkToggleAction *act, gpointer data) -{ - SPDesktop *desktop = static_cast(data); - - if (tools_isactive(desktop, TOOLS_LPETOOL)) { - sp_action_perform(Inkscape::Verb::get(SP_VERB_DIALOG_LIVE_PATH_EFFECT)->get_action(Inkscape::ActionContext(desktop)), NULL); - } - gtk_toggle_action_set_active(act, false); -} - -static void lpetool_toolbox_watch_ec(SPDesktop* dt, Inkscape::UI::Tools::ToolBase* ec, GObject* holder); - -void sp_lpetool_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) -{ - UnitTracker* tracker = new UnitTracker(Inkscape::Util::UNIT_TYPE_LINEAR); - tracker->setActiveUnit(desktop->getNamedView()->display_units); - g_object_set_data(holder, "tracker", tracker); - Unit const *unit = tracker->getActiveUnit(); - g_return_if_fail(unit != NULL); - - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setString("/tools/lpetool/unit", unit->abbr); - - /** Automatically create a list of LPEs that get added to the toolbar **/ - { - InkSelectOneActionColumns columns; - - Glib::RefPtr store = Gtk::ListStore::create(columns); - - Gtk::TreeModel::Row row; - - // The first toggle button represents the state that no subtool is active. - row = *(store->append()); - row[columns.col_label ] = _("All inactive"); - row[columns.col_tooltip ] = _("No geometric tool is active"); - row[columns.col_icon ] = "draw-geometry-inactive"; - row[columns.col_sensitive] = true; - - Inkscape::LivePathEffect::EffectType type; - for (int i = 1; i < num_subtools; ++i) { // i == 0 ia INVALIDE_LPE. - - type = lpesubtools[i].type; - - row = *(store->append()); - row[columns.col_label ] = Inkscape::LivePathEffect::LPETypeConverter.get_label(type); - row[columns.col_tooltip ] = _(Inkscape::LivePathEffect::LPETypeConverter.get_label(type).c_str()); - row[columns.col_icon ] = lpesubtools[i].icon_name; - row[columns.col_sensitive] = true; - } - - InkSelectOneAction* act = - InkSelectOneAction::create( "LPEToolModeAction", // Name - (""), // Label - (""), // Tooltip - "Not Used", // Icon - store ); // Tree store - - act->use_radio( true ); - act->use_icon( true ); - act->use_label( false ); - int mode = prefs->getInt("/tools/lpetool/mode", 0); - act->set_active( mode ); - - gtk_action_group_add_action( mainActions, act->gobj() ); - g_object_set_data( holder, "lpetool_mode_action", act ); - - act->signal_changed().connect(sigc::bind<0>(sigc::ptr_fun(&sp_lpetool_mode_changed), holder)); - } - - /* Show limiting bounding box */ - { - InkToggleAction* act = ink_toggle_action_new( "LPEShowBBoxAction", - _("Show limiting bounding box"), - _("Show bounding box (used to cut infinite lines)"), - "show-bounding-box", - GTK_ICON_SIZE_MENU ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(lpetool_toggle_show_bbox), desktop ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool( "/tools/lpetool/show_bbox", true ) ); - } - - /* Set limiting bounding box to bbox of current selection */ - { - InkToggleAction* act = ink_toggle_action_new( "LPEBBoxFromSelectionAction", - _("Get limiting bounding box from selection"), - _("Set limiting bounding box (used to cut infinite lines) to the bounding box of current selection"), - "draw-geometry-set-bounding-box", - GTK_ICON_SIZE_MENU ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(lpetool_toggle_set_bbox), desktop ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), FALSE ); - } - - - /* Combo box to choose line segment type */ - { - InkSelectOneActionColumns columns; - - Glib::RefPtr store = Gtk::ListStore::create(columns); - - Gtk::TreeModel::Row row; - - row = *(store->append()); - row[columns.col_label ] = _("Closed"); - row[columns.col_tooltip ] = (""); - row[columns.col_icon ] = "NotUsed"; - row[columns.col_sensitive] = true; - - row = *(store->append()); - row[columns.col_label ] = _("Open start"); - row[columns.col_tooltip ] = (""); - row[columns.col_icon ] = "NotUsed"; - row[columns.col_sensitive] = true; - - row = *(store->append()); - row[columns.col_label ] = _("Open end"); - row[columns.col_tooltip ] = (""); - row[columns.col_icon ] = "NotUsed"; - row[columns.col_sensitive] = true; - - row = *(store->append()); - row[columns.col_label ] = _("Open both"); - row[columns.col_tooltip ] = (""); - row[columns.col_icon ] = "NotUsed"; - row[columns.col_sensitive] = true; - - InkSelectOneAction* act = - InkSelectOneAction::create( "LPELineSegmentAction", // Name - (""), // Label - _("Choose a line segment type"), // Tooltip - "Not Used", // Icon - store ); // Tree store - - act->use_radio( false ); - act->use_icon( false ); - act->use_label( true ); - act->set_sensitive( false ); - - gtk_action_group_add_action( mainActions, GTK_ACTION( act->gobj() )); - g_object_set_data (holder, "lpetool_line_segment_action", act ); - - act->signal_changed().connect(sigc::bind<0>(sigc::ptr_fun(sp_lpetool_change_line_segment_type), holder)); - } - - /* Display measuring info for selected items */ - { - InkToggleAction* act = ink_toggle_action_new( "LPEMeasuringAction", - _("Display measuring info"), - _("Display measuring info for selected items"), - "draw-geometry-show-measuring-info", - GTK_ICON_SIZE_MENU ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(lpetool_toggle_show_measuring_info), holder ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool( "/tools/lpetool/show_measuring_info", true ) ); - } - - // Add the units menu - { - InkSelectOneAction* act = tracker->createAction( "LPEToolUnitsAction", _("Units"), ("") ); - gtk_action_group_add_action( mainActions, act->gobj() ); - act->signal_changed_after().connect(sigc::bind<0>(sigc::ptr_fun(&lpetool_unit_changed), holder)); - g_object_set_data(holder, "lpetool_units_action", act); - act->set_sensitive( prefs->getBool("/tools/lpetool/show_measuring_info", true)); - } - - /* Open LPE dialog (to adapt parameters numerically) */ - { - InkToggleAction* act = ink_toggle_action_new( "LPEOpenLPEDialogAction", - _("Open LPE dialog"), - _("Open LPE dialog (to adapt parameters numerically)"), - "dialog-geometry", - GTK_ICON_SIZE_MENU ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(lpetool_open_lpe_dialog), desktop ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), FALSE ); - } - - desktop->connectEventContextChanged(sigc::bind(sigc::ptr_fun(lpetool_toolbox_watch_ec), holder)); -} - -static void lpetool_toolbox_watch_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolBase* ec, GObject* holder) -{ - static sigc::connection c_selection_modified; - static sigc::connection c_selection_changed; - - if (SP_IS_LPETOOL_CONTEXT(ec)) { - // Watch selection - c_selection_modified = desktop->getSelection()->connectModified(sigc::bind(sigc::ptr_fun(sp_lpetool_toolbox_sel_modified), holder)); - c_selection_changed = desktop->getSelection()->connectChanged(sigc::bind(sigc::ptr_fun(sp_lpetool_toolbox_sel_changed), holder)); - sp_lpetool_toolbox_sel_changed(desktop->getSelection(), holder); - } else { - if (c_selection_modified) - c_selection_modified.disconnect(); - if (c_selection_changed) - c_selection_changed.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:fileencoding=utf-8 : diff --git a/src/widgets/lpe-toolbar.h b/src/widgets/lpe-toolbar.h deleted file mode 100644 index 3db2bcb65..000000000 --- a/src/widgets/lpe-toolbar.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef SEEN_LPE_TOOLBAR_H -#define SEEN_LPE_TOOLBAR_H - -/** - * @file - * LPE aux toolbar - */ -/* Authors: - * MenTaLguY - * Lauris Kaplinski - * bulia byak - * Frank Felfe - * John Cliff - * David Turner - * Josh Andler - * Jon A. Cruz - * Maximilian Albert - * Tavmjong Bah - * Abhishek Sharma - * Kris De Gussem - * - * Copyright (C) 2004 David Turner - * Copyright (C) 2003 MenTaLguY - * Copyright (C) 1999-2011 authors - * Copyright (C) 2001-2002 Ximian, Inc. - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -class SPDesktop; - -typedef struct _GtkActionGroup GtkActionGroup; -typedef struct _GObject GObject; - -void sp_lpetool_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); - -#endif /* !SEEN_LPE_TOOLBAR_H */ diff --git a/src/widgets/measure-toolbar.cpp b/src/widgets/measure-toolbar.cpp deleted file mode 100644 index d06e3df1e..000000000 --- a/src/widgets/measure-toolbar.cpp +++ /dev/null @@ -1,477 +0,0 @@ -/** - * @file - * Measure aux toolbar - */ -/* Authors: - * MenTaLguY - * Lauris Kaplinski - * bulia byak - * Frank Felfe - * John Cliff - * David Turner - * Josh Andler - * Jon A. Cruz - * Maximilian Albert - * Tavmjong Bah - * Abhishek Sharma - * Kris De Gussem - * - * Copyright (C) 2004 David Turner - * Copyright (C) 2003 MenTaLguY - * Copyright (C) 1999-2011 authors - * Copyright (C) 2001-2002 Ximian, Inc. - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include - -#include "measure-toolbar.h" - -#include "desktop.h" -#include "document-undo.h" -#include "ink-action.h" -#include "ink-toggle-action.h" -#include "inkscape.h" -#include "message-stack.h" -#include "toolbox.h" - -#include "ui/icon-names.h" -#include "ui/tools/measure-tool.h" -#include "ui/widget/ink-select-one-action.h" -#include "ui/widget/unit-tracker.h" - -#include "widgets/ege-adjustment-action.h" -#include "widgets/ege-output-action.h" - -using Inkscape::UI::Widget::UnitTracker; -using Inkscape::Util::Unit; -using Inkscape::DocumentUndo; -using Inkscape::UI::ToolboxFactory; -using Inkscape::UI::PrefPusher; -using Inkscape::UI::Tools::MeasureTool; - -//######################## -//## Measure Toolbox ## -//######################## - -/** Temporary hack: Returns the node tool in the active desktop. - * Will go away during tool refactoring. */ -static MeasureTool *get_measure_tool() -{ - MeasureTool *tool = 0; - if (SP_ACTIVE_DESKTOP ) { - Inkscape::UI::Tools::ToolBase *ec = SP_ACTIVE_DESKTOP->event_context; - if (SP_IS_MEASURE_CONTEXT(ec)) { - tool = static_cast(ec); - } - } - return tool; -} - -static void -sp_measure_fontsize_value_changed(GtkAdjustment *adj, GObject *tbl) -{ - SPDesktop *desktop = static_cast(g_object_get_data( tbl, "desktop" )); - - if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble(Glib::ustring("/tools/measure/fontsize"), - gtk_adjustment_get_value(adj)); - MeasureTool *mt = get_measure_tool(); - if (mt) { - mt->showCanvasItems(); - } - } -} - -static void -sp_measure_offset_value_changed(GtkAdjustment *adj, GObject *tbl) -{ - SPDesktop *desktop = static_cast(g_object_get_data( tbl, "desktop" )); - - if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble(Glib::ustring("/tools/measure/offset"), - gtk_adjustment_get_value(adj)); - MeasureTool *mt = get_measure_tool(); - if (mt) { - mt->showCanvasItems(); - } - } -} - -static void sp_measure_scale_value_changed(GtkAdjustment *adj, GObject *tbl) -{ - SPDesktop *desktop = static_cast(g_object_get_data( tbl, "desktop" )); - - if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble(Glib::ustring("/tools/measure/scale"), - gtk_adjustment_get_value(adj)); - MeasureTool *mt = get_measure_tool(); - if (mt) { - mt->showCanvasItems(); - } - } -} - -static void -sp_measure_precision_value_changed(GtkAdjustment *adj, GObject *tbl) -{ - SPDesktop *desktop = static_cast(g_object_get_data( tbl, "desktop" )); - - if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setInt(Glib::ustring("/tools/measure/precision"), - gtk_adjustment_get_value(adj)); - MeasureTool *mt = get_measure_tool(); - if (mt) { - mt->showCanvasItems(); - } - } -} - -static void -sp_measure_unit_changed(GObject* tbl, int /* notUsed */) -{ - UnitTracker* tracker = reinterpret_cast(g_object_get_data(tbl, "tracker")); - Glib::ustring const unit = tracker->getActiveUnit()->abbr; - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setString("/tools/measure/unit", unit); - MeasureTool *mt = get_measure_tool(); - if (mt) { - mt->showCanvasItems(); - } -} - -static void -sp_toggle_ignore_1st_and_last( GtkToggleAction* act, gpointer data ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - gboolean active = gtk_toggle_action_get_active(act); - prefs->setBool("/tools/measure/ignore_1st_and_last", active); - SPDesktop *desktop = static_cast(data); - if ( active ) { - desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Start and end measures inactive.")); - } else { - desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Start and end measures active.")); - } - MeasureTool *mt = get_measure_tool(); - if (mt) { - mt->showCanvasItems(); - } -} - -static void -sp_toggle_only_selected( GtkToggleAction* act, gpointer data ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - gboolean active = gtk_toggle_action_get_active(act); - prefs->setBool("/tools/measure/only_selected", active); - SPDesktop *desktop = static_cast(data); - if ( active ) { - desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Measures only selected.")); - } else { - desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Measure all.")); - } - MeasureTool *mt = get_measure_tool(); - if (mt) { - mt->showCanvasItems(); - } -} - -static void -sp_toggle_show_hidden( GtkToggleAction* act, gpointer data ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - gboolean active = gtk_toggle_action_get_active(act); - prefs->setBool("/tools/measure/show_hidden", active); - SPDesktop *desktop = static_cast(data); - if ( active ) { - desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Show all crossings.")); - } else { - desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Show visible crossings.")); - } - MeasureTool *mt = get_measure_tool(); - if (mt) { - mt->showCanvasItems(); - } -} - -static void -sp_toggle_all_layers( GtkToggleAction* act, gpointer data ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - gboolean active = gtk_toggle_action_get_active(act); - prefs->setBool("/tools/measure/all_layers", active); - SPDesktop *desktop = static_cast(data); - if ( active ) { - desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Use all layers in the measure.")); - } else { - desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Use current layer in the measure.")); - } - MeasureTool *mt = get_measure_tool(); - if (mt) { - mt->showCanvasItems(); - } -} - -static void -sp_toggle_show_in_between( GtkToggleAction* act, gpointer data ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - gboolean active = gtk_toggle_action_get_active(act); - prefs->setBool("/tools/measure/show_in_between", active); - SPDesktop *desktop = static_cast(data); - if ( active ) { - desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Compute all elements.")); - } else { - desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Compute max length.")); - } - MeasureTool *mt = get_measure_tool(); - if (mt) { - mt->showCanvasItems(); - } -} -static void -sp_reverse_knots(void){ - MeasureTool *mt = get_measure_tool(); - if (mt) { - mt->reverseKnots(); - } -} - -static void -sp_to_mark_dimension(void){ - MeasureTool *mt = get_measure_tool(); - if (mt) { - mt->toMarkDimension(); - } -} - -static void -sp_to_guides(void){ - MeasureTool *mt = get_measure_tool(); - if (mt) { - mt->toGuides(); - } -} - -static void -sp_to_phantom(void){ - MeasureTool *mt = get_measure_tool(); - if (mt) { - mt->toPhantom(); - } -} - -static void -sp_to_item(void){ - MeasureTool *mt = get_measure_tool(); - if (mt) { - mt->toItem(); - } -} - -void sp_measure_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, GObject* holder) -{ - UnitTracker* tracker = new UnitTracker(Inkscape::Util::UNIT_TYPE_LINEAR); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - tracker->setActiveUnitByAbbr(prefs->getString("/tools/measure/unit").c_str()); - - g_object_set_data( holder, "tracker", tracker ); - - EgeAdjustmentAction *eact = 0; - GtkIconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1); - - /* Font Size */ - { - eact = create_adjustment_action( "MeasureFontSizeAction", - _("Font Size"), _("Font Size:"), - _("The font size to be used in the measurement labels"), - "/tools/measure/fontsize", 10.0, - GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, - 1.0, 36.0, 1.0, 4.0, - 0, 0, 0, - sp_measure_fontsize_value_changed, NULL, 0 , 2); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact)); - } - - /* units label */ - { - EgeOutputAction* act = ege_output_action_new( "measure_units_label", _("Units:"), _("The units to be used for the measurements"), 0 ); - ege_output_action_set_use_markup( act, TRUE ); - g_object_set( act, "visible-overflown", FALSE, NULL ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - } - - /* units menu */ - { - InkSelectOneAction* act = tracker->createAction( "MeasureUnitsAction", _("Units:"), _("The units to be used for the measurements") ); - act->signal_changed_after().connect(sigc::bind<0>(sigc::ptr_fun(&sp_measure_unit_changed), holder)); - gtk_action_group_add_action( mainActions, act->gobj() ); - } - - /* Precision */ - { - eact = create_adjustment_action( "MeasurePrecisionAction", - _("Precision"), _("Precision:"), - _("Decimal precision of measure"), - "/tools/measure/precision", 2, - GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, - 0, 10, 1, 0, - 0, 0, 0, - sp_measure_precision_value_changed, NULL, 0 ,0); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact)); - } - - /* Scale */ - { - eact = create_adjustment_action( "MeasureScaleAction", - _("Scale %"), _("Scale %:"), - _("Scale the results"), - "/tools/measure/scale", 100.0, - GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, - 0.0, 90000.0, 1.0, 4.0, - 0, 0, 0, - sp_measure_scale_value_changed, NULL, 0 , 3); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - } - - /* Offset */ - { - eact = create_adjustment_action( "MeasureOffsetAction", - _("Offset"), _("Offset:"), - _("Mark dimension offset"), - "/tools/measure/offset", 5.0, - GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, - 0.0, 90000.0, 1.0, 4.0, - 0, 0, 0, - sp_measure_offset_value_changed, NULL, 0 , 2); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - } - - /* measure only selected */ - { - InkToggleAction* act = ink_toggle_action_new( "MeasureOnlySelected", - _("Measure only selected"), - _("Measure only selected"), - INKSCAPE_ICON("snap-bounding-box-center"), - secondarySize ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/measure/only_selected", false) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_only_selected), desktop) ; - gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); - } - - /* ignore_1st_and_last */ - { - InkToggleAction* act = ink_toggle_action_new( "MeasureIgnore1stAndLast", - _("Ignore first and last"), - _("Ignore first and last"), - INKSCAPE_ICON("draw-geometry-line-segment"), - secondarySize ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/measure/ignore_1st_and_last", true) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_ignore_1st_and_last), desktop) ; - gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); - } - /* only visible */ - { - InkToggleAction* act = ink_toggle_action_new( "MeasureShowHidden", - _("Show hidden intersections"), - _("Show hidden intersections"), - INKSCAPE_ICON("object-hidden"), - secondarySize ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/measure/show_hidden", true) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_show_hidden), desktop) ; - gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); - } - /* measure imbetweens */ - { - InkToggleAction* act = ink_toggle_action_new( "MeasureInBettween", - _("Show measures between items"), - _("Show measures between items"), - INKSCAPE_ICON("distribute-randomize"), - secondarySize ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/measure/show_in_between", true) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_show_in_between), desktop) ; - gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); - } - /* measure only current layer */ - { - InkToggleAction* act = ink_toggle_action_new( "MeasureAllLayers", - _("Measure all layers"), - _("Measure all layers"), - INKSCAPE_ICON("dialog-layers"), - secondarySize ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/measure/all_layers", true) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_all_layers), desktop) ; - gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); - } - /* toggle start end */ - { - InkAction* act = ink_action_new( "MeasureReverse", - _("Reverse measure"), - _("Reverse measure"), - INKSCAPE_ICON("draw-geometry-mirror"), - secondarySize ); - g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(sp_reverse_knots), 0 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); - } - /* phantom measure */ - { - InkAction* act = ink_action_new( "MeasureToPhantom", - _("Phantom measure"), - _("Phantom measure"), - INKSCAPE_ICON("selection-make-bitmap-copy"), - secondarySize ); - g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(sp_to_phantom), 0 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); - } - /* to guides */ - { - InkAction* act = ink_action_new( "MeasureToGuides", - _("To guides"), - _("To guides"), - INKSCAPE_ICON("guides"), - secondarySize ); - g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(sp_to_guides), 0 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); - } - /* to mark dimensions */ - { - InkAction* act = ink_action_new( "MeasureMarkDimension", - _("Mark Dimension"), - _("Mark Dimension"), - INKSCAPE_ICON("tool-pointer"), - secondarySize ); - g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(sp_to_mark_dimension), 0 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); - } - /* to item */ - { - InkAction* act = ink_action_new( "MeasureToItem", - _("Convert to item"), - _("Convert to item"), - INKSCAPE_ICON("path-reverse"), - secondarySize ); - g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(sp_to_item), 0 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); - } -} // end of sp_measure_toolbox_prep() - - -/* - 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:fileencoding=utf-8:textwidth=99 : diff --git a/src/widgets/measure-toolbar.h b/src/widgets/measure-toolbar.h deleted file mode 100644 index aff0a209b..000000000 --- a/src/widgets/measure-toolbar.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef SEEN_MEASURE_TOOLBAR_H -#define SEEN_MEASURE_TOOLBAR_H - -/** - * @file - * Measue aux toolbar - */ -/* Authors: - * MenTaLguY - * Lauris Kaplinski - * bulia byak - * Frank Felfe - * John Cliff - * David Turner - * Josh Andler - * Jon A. Cruz - * Maximilian Albert - * Tavmjong Bah - * Abhishek Sharma - * Kris De Gussem - * - * Copyright (C) 2004 David Turner - * Copyright (C) 2003 MenTaLguY - * Copyright (C) 1999-2011 authors - * Copyright (C) 2001-2002 Ximian, Inc. - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -class SPDesktop; - -typedef struct _GtkActionGroup GtkActionGroup; -typedef struct _GObject GObject; - -void sp_measure_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); - -#endif /* !SEEN_MEASURE_TOOLBAR_H */ diff --git a/src/widgets/mesh-toolbar.cpp b/src/widgets/mesh-toolbar.cpp deleted file mode 100644 index fb5e5428a..000000000 --- a/src/widgets/mesh-toolbar.cpp +++ /dev/null @@ -1,669 +0,0 @@ -/* - * Gradient aux toolbar - * - * Authors: - * bulia byak - * Johan Engelen - * Abhishek Sharma - * Tavmjong Bah - * - * Copyright (C) 2012 Tavmjong Bah - * 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 -#endif - -#include -#include - -#include "mesh-toolbar.h" - -#include "desktop-style.h" -#include "desktop.h" -#include "document-private.h" -#include "document-undo.h" -#include "gradient-chemistry.h" -#include "gradient-drag.h" -#include "ink-action.h" -#include "ink-radio-action.h" -#include "ink-toggle-action.h" -#include "inkscape.h" -#include "toolbox.h" -#include "verbs.h" - -#include "object/sp-defs.h" -#include "object/sp-mesh-gradient.h" -#include "object/sp-stop.h" -#include "style.h" - -#include "svg/css-ostringstream.h" - -#include "ui/icon-names.h" -#include "ui/tools/gradient-tool.h" -#include "ui/tools/mesh-tool.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/spinbutton-events.h" - -using Inkscape::DocumentUndo; -using Inkscape::UI::ToolboxFactory; -using Inkscape::UI::PrefPusher; -using Inkscape::UI::Tools::MeshTool; - -static bool blocked = false; - -//######################## -//## Mesh ## -//######################## - - -// Get a list of selected meshes taking into account fill/stroke toggles -std::vector ms_get_dt_selected_gradients(Inkscape::Selection *selection) -{ - std::vector ms_selected; - - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - bool edit_fill = prefs->getBool("/tools/mesh/edit_fill", true); - bool edit_stroke = prefs->getBool("/tools/mesh/edit_stroke", true); - - 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; - - if (style) { - - - if (edit_fill && style->fill.isPaintserver()) { - SPPaintServer *server = item->style->getFillPaintServer(); - SPMeshGradient *mesh = dynamic_cast(server); - if (mesh) { - ms_selected.push_back(mesh); - } - } - - if (edit_stroke && style->stroke.isPaintserver()) { - SPPaintServer *server = item->style->getStrokePaintServer(); - SPMeshGradient *mesh = dynamic_cast(server); - if (mesh) { - ms_selected.push_back(mesh); - } - } - } - - } - return ms_selected; -} - - -/* - * Get the current selection status from the desktop - */ -void ms_read_selection( Inkscape::Selection *selection, - SPMeshGradient *&ms_selected, - bool &ms_selected_multi, - SPMeshType &ms_type, - bool &ms_type_multi ) -{ - ms_selected = NULL; - ms_selected_multi = false; - ms_type = SP_MESH_TYPE_COONS; - ms_type_multi = false; - - bool first = true; - - // Read desktop selection, taking into account fill/stroke toggles - std::vector meshes = ms_get_dt_selected_gradients( selection ); - for (auto i = meshes.begin(); i != meshes.end(); ++i) { - if (first) { - ms_selected = (*i); - ms_type = (*i)->type; - first = false; - } else { - if (ms_selected != (*i)) { - ms_selected_multi = true; - } - if (ms_type != (*i)->type) { - ms_type_multi = true; - } - } - } -} - -/* - * Core function, setup all the widgets whenever something changes on the desktop - */ -static void ms_tb_selection_changed(Inkscape::Selection * /*selection*/, gpointer data) -{ - - // std::cout << "ms_tb_selection_changed" << std::endl; - - if (blocked) - return; - - SPDesktop *desktop = static_cast(g_object_get_data(G_OBJECT(data), "desktop")); - if (!desktop) { - return; - } - - Inkscape::Selection *selection = desktop->getSelection(); // take from desktop, not from args - if (selection) { - // ToolBase *ev = sp_desktop_event_context(desktop); - // GrDrag *drag = NULL; - // if (ev) { - // drag = ev->get_drag(); - // // Hide/show handles? - // } - - SPMeshGradient *ms_selected = 0; - SPMeshType ms_type = SP_MESH_TYPE_COONS; - bool ms_selected_multi = false; - bool ms_type_multi = false; - ms_read_selection( selection, ms_selected, ms_selected_multi, ms_type, ms_type_multi ); - // std::cout << " type: " << ms_type << std::endl; - - InkSelectOneAction* type = static_cast (g_object_get_data(G_OBJECT(data), "mesh_select_type_action")); - if (type) { - type->set_sensitive(!ms_type_multi); - blocked = TRUE; - type->set_active(ms_type); - blocked = FALSE; - } - } -} - - -static void ms_tb_selection_modified(Inkscape::Selection *selection, guint /*flags*/, gpointer data) -{ - ms_tb_selection_changed(selection, data); -} - -static void ms_drag_selection_changed(gpointer /*dragger*/, gpointer data) -{ - ms_tb_selection_changed(NULL, data); - -} - -static void ms_defs_release(SPObject * /*defs*/, GObject *widget) -{ - ms_tb_selection_changed(NULL, widget); -} - -static void ms_defs_modified(SPObject * /*defs*/, guint /*flags*/, GObject *widget) -{ - ms_tb_selection_changed(NULL, widget); -} - -/* - * Callback functions for user actions - */ - -static void ms_new_geometry_changed( GObject * /*tbl*/, int mode ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setInt("/tools/mesh/mesh_geometry", mode); -} - -static void ms_new_fillstroke_changed( GObject * /*tbl*/, int mode ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setInt("/tools/mesh/newfillorstroke", mode); -} - -static void ms_row_changed(GtkAdjustment *adj, GObject * /*tbl*/ ) -{ - if (blocked) { - return; - } - - blocked = TRUE; - - int rows = gtk_adjustment_get_value(adj); - - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - - prefs->setInt("/tools/mesh/mesh_rows", rows); - - blocked = FALSE; -} - -static void ms_col_changed(GtkAdjustment *adj, GObject * /*tbl*/ ) -{ - if (blocked) { - return; - } - - blocked = TRUE; - - int cols = gtk_adjustment_get_value(adj); - - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - - prefs->setInt("/tools/mesh/mesh_cols", cols); - - blocked = FALSE; -} - -/** - * Sets mesh type: Coons, Bicubic - */ -static void ms_type_changed( GObject *tbl, int mode ) -{ - if (blocked) { - return; - } - - SPDesktop *desktop = static_cast(g_object_get_data(tbl, "desktop")); - Inkscape::Selection *selection = desktop->getSelection(); - std::vector meshes = ms_get_dt_selected_gradients(selection); - - SPMeshType type = (SPMeshType) mode; - for (auto i = meshes.begin(); i != meshes.end(); ++i) { - (*i)->type = type; - (*i)->type_set = true; - (*i)->updateRepr(); - } - if (!meshes.empty() ) { - DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_MESH,_("Set mesh type")); - } -} - -/** Temporary hack: Returns the mesh tool in the active desktop. - * Will go away during tool refactoring. */ -static MeshTool *get_mesh_tool() -{ - MeshTool *tool = 0; - if (SP_ACTIVE_DESKTOP ) { - Inkscape::UI::Tools::ToolBase *ec = SP_ACTIVE_DESKTOP->event_context; - if (SP_IS_MESH_CONTEXT(ec)) { - tool = static_cast(ec); - } - } - return tool; -} - -static void ms_toggle_sides(void) -{ - MeshTool *mt = get_mesh_tool(); - if (mt) { - sp_mesh_context_corner_operation( mt, MG_CORNER_SIDE_TOGGLE ); - } -} - -static void ms_make_elliptical(void) -{ - MeshTool *mt = get_mesh_tool(); - if (mt) { - sp_mesh_context_corner_operation( mt, MG_CORNER_SIDE_ARC ); - } -} - -static void ms_pick_colors(void) -{ - MeshTool *mt = get_mesh_tool(); - if (mt) { - sp_mesh_context_corner_operation( mt, MG_CORNER_COLOR_PICK ); - } -} - -static void ms_fit_mesh(void) -{ - MeshTool *mt = get_mesh_tool(); - if (mt) { - sp_mesh_context_fit_mesh_in_bbox( mt ); - } -} - -static void ms_toggle_handles(void) -{ - MeshTool *mt = get_mesh_tool(); - if (mt) { - GrDrag *drag = mt->_grdrag; - drag->refreshDraggers(); - } -} - -static void ms_toggle_fill_stroke(InkToggleAction * /*act*/, gpointer data) -{ - MeshTool *mt = get_mesh_tool(); - if (mt) { - GrDrag *drag = mt->_grdrag; - drag->updateDraggers(); - drag->updateLines(); - drag->updateLevels(); - ms_tb_selection_changed(NULL, data); // Need to update Type widget - } -} - -static void ms_warning_popup(void) -{ - char *msg = _("Mesh gradients are part of SVG 2:\n" - "* Syntax may change.\n" - "* Web browser implementation is not guaranteed.\n" - "\n" - "For web: convert to bitmap (Edit->Make bitmap copy).\n" - "For print: export to PDF."); - Gtk::MessageDialog dialog(msg, false, Gtk::MESSAGE_WARNING, - Gtk::BUTTONS_OK, true); - dialog.run(); - -} - -static void mesh_toolbox_watch_ec(SPDesktop* dt, Inkscape::UI::Tools::ToolBase* ec, GObject* holder); - -/** - * Mesh auxiliary toolbar construction and setup. - * Don't forget to add to XML in widgets/toolbox.cpp! - * - */ -void sp_mesh_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, GObject* holder) -{ - GtkIconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1); - - EgeAdjustmentAction* eact = 0; - - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - - /* New mesh: normal or conical */ - { - InkSelectOneActionColumns columns; - - Glib::RefPtr store = Gtk::ListStore::create(columns); - - Gtk::TreeModel::Row row; - - row = *(store->append()); - row[columns.col_label ] = _("normal"); - row[columns.col_tooltip ] = _("Create mesh gradient"); - row[columns.col_icon ] = INKSCAPE_ICON("paint-gradient-mesh"); - row[columns.col_sensitive] = true; - - row = *(store->append()); - row[columns.col_label ] = _("conical"); - row[columns.col_tooltip ] = _("Create conical gradient"); - row[columns.col_icon ] = INKSCAPE_ICON("paint-gradient-conical"); - row[columns.col_sensitive] = true; - - InkSelectOneAction* act = - InkSelectOneAction::create( "MeshNewTypeAction", // Name - _("New:"), // Label - "", // Tooltip - "Not Used", // Icon - store ); // Tree store - - act->use_radio( true ); - act->use_group_label( true ); - gint mode = prefs->getInt("/tools/mesh/mesh_geometry", SP_MESH_GEOMETRY_NORMAL); - act->set_active( mode ); - - gtk_action_group_add_action( mainActions, GTK_ACTION( act->gobj() )); - g_object_set_data( holder, "mesh_new_type_mode", act ); - - act->signal_changed().connect(sigc::bind<0>(sigc::ptr_fun(&ms_new_geometry_changed), holder)); - } - - /* New gradient on fill or stroke*/ - { - InkSelectOneActionColumns columns; - - Glib::RefPtr 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( "MeshNewFillStrokeAction", // Name - "", // Label - "", // Tooltip - "Not Used", // Icon - store ); // Tree store - - act->use_radio( true ); - act->use_group_label( false ); - gint mode = prefs->getInt("/tools/mesh/newfillorstroke"); - act->set_active( mode ); - - gtk_action_group_add_action( mainActions, GTK_ACTION( act->gobj() )); - g_object_set_data( holder, "mesh_new_type_mode", act ); - - act->signal_changed().connect(sigc::bind<0>(sigc::ptr_fun(&ms_new_fillstroke_changed), holder)); - } - - /* Number of mesh rows */ - { - gchar const** labels = NULL; - gdouble values[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; - eact = create_adjustment_action( "MeshRowAction", - _("Rows"), _("Rows:"), _("Number of rows in new mesh"), - "/tools/mesh/mesh_rows", 1, - GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, - 1, 20, 1, 1, - labels, values, 0, - ms_row_changed, NULL /*unit tracker*/, - 1.0, 0 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - } - - /* Number of mesh columns */ - { - gchar const** labels = NULL; - gdouble values[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; - eact = create_adjustment_action( "MeshColumnAction", - _("Columns"), _("Columns:"), _("Number of columns in new mesh"), - "/tools/mesh/mesh_cols", 1, - GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, - 1, 20, 1, 1, - labels, values, 0, - ms_col_changed, NULL /*unit tracker*/, - 1.0, 0 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - } - - /* Edit fill mesh */ - { - InkToggleAction* act = ink_toggle_action_new( "MeshEditFillAction", - _("Edit Fill"), - _("Edit fill mesh"), - INKSCAPE_ICON("object-fill"), - secondarySize ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(act), "/tools/mesh/edit_fill"); - g_signal_connect( holder, "destroy", G_CALLBACK(delete_prefspusher), pusher); - g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(ms_toggle_fill_stroke), holder); - } - - /* Edit stroke mesh */ - { - InkToggleAction* act = ink_toggle_action_new( "MeshEditStrokeAction", - _("Edit Stroke"), - _("Edit stroke mesh"), - INKSCAPE_ICON("object-stroke"), - secondarySize ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(act), "/tools/mesh/edit_stroke"); - g_signal_connect( holder, "destroy", G_CALLBACK(delete_prefspusher), pusher); - g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(ms_toggle_fill_stroke), holder); - } - - /* Show/hide side and tensor handles */ - { - InkToggleAction* act = ink_toggle_action_new( "MeshShowHandlesAction", - _("Show Handles"), - _("Show handles"), - INKSCAPE_ICON("show-node-handles"), - secondarySize ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(act), "/tools/mesh/show_handles"); - g_signal_connect( holder, "destroy", G_CALLBACK(delete_prefspusher), pusher); - g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(ms_toggle_handles), 0); - } - - g_object_set_data(holder, "desktop", desktop); - - desktop->connectEventContextChanged(sigc::bind(sigc::ptr_fun(mesh_toolbox_watch_ec), holder)); - - /* Warning */ - { - InkAction* act = ink_action_new( "MeshWarningAction", - _("WARNING: Mesh SVG Syntax Subject to Change"), - _("WARNING: Mesh SVG Syntax Subject to Change"), - INKSCAPE_ICON("dialog-warning"), - secondarySize ); - gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); - g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(ms_warning_popup), holder ); - gtk_action_set_sensitive( GTK_ACTION(act), TRUE ); - } - - /* Type */ - { - InkSelectOneActionColumns columns; - - Glib::RefPtr store = Gtk::ListStore::create(columns); - - Gtk::TreeModel::Row row; - - row = *(store->append()); - row[columns.col_label ] = C_("Type", "Coons"); - row[columns.col_tooltip ] = ""; - row[columns.col_icon ] = "NotUsed"; - row[columns.col_sensitive] = true; - - row = *(store->append()); - row[columns.col_label ] = _("Bicubic"); - row[columns.col_tooltip ] = ""; - row[columns.col_icon ] = "NotUsed"; - row[columns.col_sensitive] = true; - - // TRANSLATORS: Type of Smoothing. See https://en.wikipedia.org/wiki/Coons_patch - InkSelectOneAction* act = - InkSelectOneAction::create( "MeshSmoothAction", // Name - _("Smoothing"), // Label - _("Coons: no smothing. Bicubic: smothing across patch boundaries."), // Tooltip - "Not Used", // Icon - store ); // Tree store - - act->use_radio( false ); - act->use_label( true ); - act->use_icon( false ); - act->use_group_label( true ); - act->set_sensitive( false ); - act->set_active( 0 ); - - gtk_action_group_add_action( mainActions, GTK_ACTION( act->gobj() )); - g_object_set_data( holder, "mesh_select_type_action", act ); - - act->signal_changed().connect(sigc::bind<0>(sigc::ptr_fun(&ms_type_changed), holder)); - } - - { - InkAction* act = ink_action_new( "MeshToggleSidesAction", - _("Toggle Sides"), - _("Toggle selected sides between Beziers and lines."), - INKSCAPE_ICON("node-segment-line"), - secondarySize ); - g_object_set( act, "short_label", _("Toggle side:"), NULL ); - g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(ms_toggle_sides), 0 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); - } - - { - InkAction* act = ink_action_new( "MeshMakeEllipticalAction", - _("Make elliptical"), - _("Make selected sides elliptical by changing length of handles. Works best if handles already approximate ellipse."), - INKSCAPE_ICON("node-segment-curve"), - secondarySize ); - g_object_set( act, "short_label", _("Make elliptical:"), NULL ); - g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(ms_make_elliptical), 0 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); - } - - { - InkAction* act = ink_action_new( "MeshPickColorsAction", - _("Pick colors:"), - _("Pick colors for selected corner nodes from underneath mesh."), - INKSCAPE_ICON("color-picker"), - secondarySize ); - g_object_set( act, "short_label", _("Pick Color"), NULL ); - g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(ms_pick_colors), 0 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); - } - - - { - InkAction* act = ink_action_new( "MeshFitInBoundingBoxAction", - _("Scale mesh to bounding box:"), - _("Scale mesh to fit inside bounding box."), - INKSCAPE_ICON("mesh-gradient-fit"), - secondarySize ); - g_object_set( act, "short_label", _("Fit mesh"), NULL ); - g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(ms_fit_mesh), 0 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); - } - -} - -static void mesh_toolbox_watch_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolBase* ec, GObject* holder) -{ - static sigc::connection c_selection_changed; - static sigc::connection c_selection_modified; - static sigc::connection c_subselection_changed; - static sigc::connection c_defs_release; - static sigc::connection c_defs_modified; - - if (SP_IS_MESH_CONTEXT(ec)) { - // connect to selection modified and changed signals - Inkscape::Selection *selection = desktop->getSelection(); - SPDocument *document = desktop->getDocument(); - - c_selection_changed = selection->connectChanged(sigc::bind(sigc::ptr_fun(&ms_tb_selection_changed), holder)); - c_selection_modified = selection->connectModified(sigc::bind(sigc::ptr_fun(&ms_tb_selection_modified), holder)); - c_subselection_changed = desktop->connectToolSubselectionChanged(sigc::bind(sigc::ptr_fun(&ms_drag_selection_changed), holder)); - - c_defs_release = document->getDefs()->connectRelease(sigc::bind<1>(sigc::ptr_fun(&ms_defs_release), holder)); - c_defs_modified = document->getDefs()->connectModified(sigc::bind<2>(sigc::ptr_fun(&ms_defs_modified), holder)); - ms_tb_selection_changed(selection, holder); - } else { - if (c_selection_changed) - c_selection_changed.disconnect(); - if (c_selection_modified) - c_selection_modified.disconnect(); - if (c_subselection_changed) - c_subselection_changed.disconnect(); - if (c_defs_release) - c_defs_release.disconnect(); - if (c_defs_modified) - c_defs_modified.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 : diff --git a/src/widgets/mesh-toolbar.h b/src/widgets/mesh-toolbar.h deleted file mode 100644 index fd3f4b4b7..000000000 --- a/src/widgets/mesh-toolbar.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef SEEN_MESH_TOOLBAR_H -#define SEEN_MESH_TOOLBAR_H - -/* - * Mesh aux toolbar - * - * Authors: - * bulia byak - * Tavmjong Bah - * - * Copyright (C) 2012 authors - * Copyright (C) 2005 authors - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -class SPDesktop; - -typedef struct _GtkActionGroup GtkActionGroup; -typedef struct _GObject GObject; - -void sp_mesh_toolbox_prep( SPDesktop * /*desktop*/, GtkActionGroup* mainActions, GObject* holder); - -#endif /* !SEEN_MESH_TOOLBAR_H */ diff --git a/src/widgets/node-toolbar.cpp b/src/widgets/node-toolbar.cpp deleted file mode 100644 index 2e80b77d8..000000000 --- a/src/widgets/node-toolbar.cpp +++ /dev/null @@ -1,656 +0,0 @@ -/** - * @file - * Node aux toolbar - */ -/* Authors: - * MenTaLguY - * Lauris Kaplinski - * bulia byak - * Frank Felfe - * John Cliff - * David Turner - * Josh Andler - * Jon A. Cruz - * Maximilian Albert - * Tavmjong Bah - * Abhishek Sharma - * Kris De Gussem - * - * Copyright (C) 2004 David Turner - * Copyright (C) 2003 MenTaLguY - * Copyright (C) 1999-2011 authors - * Copyright (C) 2001-2002 Ximian, Inc. - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include - - -#include "desktop.h" -#include "document-undo.h" -#include "ink-toggle-action.h" -#include "ink-tool-menu-action.h" -#include "inkscape.h" -#include "node-toolbar.h" -#include "selection-chemistry.h" -#include "toolbox.h" -#include "verbs.h" - -#include "object/sp-namedview.h" - -#include "ui/icon-names.h" -#include "ui/tool/control-point-selection.h" -#include "ui/tool/multi-path-manipulator.h" -#include "ui/tools/node-tool.h" -#include "ui/widget/ink-select-one-action.h" -#include "ui/widget/unit-tracker.h" - -#include "widgets/ege-adjustment-action.h" -#include "widgets/widget-sizes.h" - -using Inkscape::UI::Widget::UnitTracker; -using Inkscape::Util::Unit; -using Inkscape::Util::Quantity; -using Inkscape::DocumentUndo; -using Inkscape::UI::ToolboxFactory; -using Inkscape::UI::PrefPusher; -using Inkscape::Util::unit_table; -using Inkscape::UI::Tools::NodeTool; - -//#################################### -//# node editing callbacks -//#################################### - -/** Temporary hack: Returns the node tool in the active desktop. - * Will go away during tool refactoring. */ -static NodeTool *get_node_tool() -{ - NodeTool *tool = 0; - if (SP_ACTIVE_DESKTOP ) { - Inkscape::UI::Tools::ToolBase *ec = SP_ACTIVE_DESKTOP->event_context; - if (INK_IS_NODE_TOOL(ec)) { - tool = static_cast(ec); - } - } - return tool; -} - -static void sp_node_path_edit_add(void) -{ - NodeTool *nt = get_node_tool(); - if (nt) { - nt->_multipath->insertNodes(); - } -} - -static void sp_node_path_edit_add_min_x(void) -{ - NodeTool *nt = get_node_tool(); - if (nt) { - nt->_multipath->insertNodesAtExtrema(Inkscape::UI::PointManipulator::EXTR_MIN_X); - } -} -static void sp_node_path_edit_add_max_x(void) -{ - NodeTool *nt = get_node_tool(); - if (nt) { - nt->_multipath->insertNodesAtExtrema(Inkscape::UI::PointManipulator::EXTR_MAX_X); - } -} -static void sp_node_path_edit_add_min_y(void) -{ - NodeTool *nt = get_node_tool(); - if (nt) { - nt->_multipath->insertNodesAtExtrema(Inkscape::UI::PointManipulator::EXTR_MIN_Y); - } -} -static void sp_node_path_edit_add_max_y(void) -{ - NodeTool *nt = get_node_tool(); - if (nt) { - nt->_multipath->insertNodesAtExtrema(Inkscape::UI::PointManipulator::EXTR_MAX_Y); - } -} - -static void sp_node_path_edit_delete(void) -{ - NodeTool *nt = get_node_tool(); - if (nt) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - nt->_multipath->deleteNodes(prefs->getBool("/tools/nodes/delete_preserves_shape", true)); - } -} - -static void sp_node_path_edit_delete_segment(void) -{ - NodeTool *nt = get_node_tool(); - if (nt) { - nt->_multipath->deleteSegments(); - } -} - -static void sp_node_path_edit_break(void) -{ - NodeTool *nt = get_node_tool(); - if (nt) { - nt->_multipath->breakNodes(); - } -} - -static void sp_node_path_edit_join(void) -{ - NodeTool *nt = get_node_tool(); - if (nt) { - nt->_multipath->joinNodes(); - } -} - -static void sp_node_path_edit_join_segment(void) -{ - NodeTool *nt = get_node_tool(); - if (nt) { - nt->_multipath->joinSegments(); - } -} - -static void sp_node_path_edit_toline(void) -{ - NodeTool *nt = get_node_tool(); - if (nt) { - nt->_multipath->setSegmentType(Inkscape::UI::SEGMENT_STRAIGHT); - } -} - -static void sp_node_path_edit_tocurve(void) -{ - NodeTool *nt = get_node_tool(); - if (nt) { - nt->_multipath->setSegmentType(Inkscape::UI::SEGMENT_CUBIC_BEZIER); - } -} - -static void sp_node_path_edit_cusp(void) -{ - NodeTool *nt = get_node_tool(); - if (nt) { - nt->_multipath->setNodeType(Inkscape::UI::NODE_CUSP); - } -} - -static void sp_node_path_edit_smooth(void) -{ - NodeTool *nt = get_node_tool(); - if (nt) { - nt->_multipath->setNodeType(Inkscape::UI::NODE_SMOOTH); - } -} - -static void sp_node_path_edit_symmetrical(void) -{ - NodeTool *nt = get_node_tool(); - if (nt) { - nt->_multipath->setNodeType(Inkscape::UI::NODE_SYMMETRIC); - } -} - -static void sp_node_path_edit_auto(void) -{ - NodeTool *nt = get_node_tool(); - if (nt) { - nt->_multipath->setNodeType(Inkscape::UI::NODE_AUTO); - } -} - -static void sp_node_path_edit_nextLPEparam(GtkAction * /*act*/, gpointer data) { - sp_selection_next_patheffect_param( reinterpret_cast(data) ); -} - -/* is called when the node selection is modified */ -static void sp_node_toolbox_coord_changed(gpointer /*shape_editor*/, GObject *tbl) -{ - GtkAction* xact = GTK_ACTION( g_object_get_data( tbl, "nodes_x_action" ) ); - GtkAction* yact = GTK_ACTION( g_object_get_data( tbl, "nodes_y_action" ) ); - GtkAdjustment *xadj = ege_adjustment_action_get_adjustment(EGE_ADJUSTMENT_ACTION(xact)); - GtkAdjustment *yadj = ege_adjustment_action_get_adjustment(EGE_ADJUSTMENT_ACTION(yact)); - - // quit if run by the attr_changed listener - if (g_object_get_data( tbl, "freeze" )) { - return; - } - - // in turn, prevent listener from responding - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE)); - - UnitTracker* tracker = reinterpret_cast( g_object_get_data( tbl, "tracker" ) ); - if (!tracker) { - return; - } - Unit const *unit = tracker->getActiveUnit(); - g_return_if_fail(unit != NULL); - - NodeTool *nt = get_node_tool(); - if (!nt || !(nt->_selected_nodes) ||nt->_selected_nodes->empty()) { - // no path selected - gtk_action_set_sensitive(xact, FALSE); - gtk_action_set_sensitive(yact, FALSE); - } else { - gtk_action_set_sensitive(xact, TRUE); - gtk_action_set_sensitive(yact, TRUE); - Geom::Coord oldx = Quantity::convert(gtk_adjustment_get_value(xadj), unit, "px"); - Geom::Coord oldy = Quantity::convert(gtk_adjustment_get_value(yadj), unit, "px"); - Geom::Point mid = nt->_selected_nodes->pointwiseBounds()->midpoint(); - - if (oldx != mid[Geom::X]) { - gtk_adjustment_set_value(xadj, Quantity::convert(mid[Geom::X], "px", unit)); - } - if (oldy != mid[Geom::Y]) { - gtk_adjustment_set_value(yadj, Quantity::convert(mid[Geom::Y], "px", unit)); - } - } - - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -} - -static void sp_node_path_value_changed(GtkAdjustment *adj, GObject *tbl, Geom::Dim2 d) -{ - SPDesktop *desktop = static_cast(g_object_get_data( tbl, "desktop" )); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - - UnitTracker* tracker = reinterpret_cast(g_object_get_data( tbl, "tracker" )); - if (!tracker) { - return; - } - Unit const *unit = tracker->getActiveUnit(); - - if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { - prefs->setDouble(Glib::ustring("/tools/nodes/") + (d == Geom::X ? "x" : "y"), - Quantity::convert(gtk_adjustment_get_value(adj), unit, "px")); - } - - // quit if run by the attr_changed listener - if (g_object_get_data( tbl, "freeze" ) || tracker->isUpdating()) { - return; - } - - // in turn, prevent listener from responding - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE)); - - NodeTool *nt = get_node_tool(); - if (nt && !nt->_selected_nodes->empty()) { - double val = Quantity::convert(gtk_adjustment_get_value(adj), unit, "px"); - double oldval = nt->_selected_nodes->pointwiseBounds()->midpoint()[d]; - Geom::Point delta(0,0); - delta[d] = val - oldval; - nt->_multipath->move(delta); - } - - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -} - -static void sp_node_path_x_value_changed(GtkAdjustment *adj, GObject *tbl) -{ - sp_node_path_value_changed(adj, tbl, Geom::X); -} - -static void sp_node_path_y_value_changed(GtkAdjustment *adj, GObject *tbl) -{ - sp_node_path_value_changed(adj, tbl, Geom::Y); -} - -static void sp_node_toolbox_sel_changed(Inkscape::Selection *selection, GObject *tbl) -{ - { - GtkAction* w = GTK_ACTION( g_object_get_data( tbl, "nodes_lpeedit" ) ); - SPItem *item = selection->singleItem(); - if (item && SP_IS_LPE_ITEM(item)) { - if (SP_LPE_ITEM(item)->hasPathEffect()) { - gtk_action_set_sensitive(w, TRUE); - } else { - gtk_action_set_sensitive(w, FALSE); - } - } else { - gtk_action_set_sensitive(w, FALSE); - } - } -} - -static void sp_node_toolbox_sel_modified(Inkscape::Selection *selection, guint /*flags*/, GObject *tbl) -{ - sp_node_toolbox_sel_changed (selection, tbl); -} - -static void node_toolbox_watch_ec(SPDesktop* dt, Inkscape::UI::Tools::ToolBase* ec, GObject* holder); - -//################################ -//## Node Editing Toolbox ## -//################################ - -void sp_node_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) -{ - UnitTracker* tracker = new UnitTracker(Inkscape::Util::UNIT_TYPE_LINEAR); - Unit doc_units = *desktop->getNamedView()->display_units; - tracker->setActiveUnit(&doc_units); - g_object_set_data( holder, "tracker", tracker ); - - GtkIconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1); - - { - InkToolMenuAction* inky = ink_tool_menu_action_new( "NodeInsertAction", - _("Insert node"), - _("Insert new nodes into selected segments"), - INKSCAPE_ICON("node-add"), - secondarySize ); - g_object_set( INK_ACTION(inky), "short_label", _("Insert"), NULL ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_add), 0 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - GtkToolItem *menu_tool_button = gtk_menu_tool_button_new (NULL, NULL); - gtk_activatable_set_related_action (GTK_ACTIVATABLE (menu_tool_button), GTK_ACTION(inky)); - // also create dummy menu action: - gtk_action_group_add_action( mainActions, gtk_action_new("NodeInsertActionMenu", NULL, NULL, NULL) ); - } - - { - InkAction* inky = ink_action_new( "NodeInsertActionMinX", - _("Insert node at min X"), - _("Insert new nodes at min X into selected segments"), - INKSCAPE_ICON("node_insert_min_x"), - secondarySize ); - g_object_set( inky, "short_label", _("Insert min X"), NULL ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_add_min_x), 0 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - } - { - InkAction* inky = ink_action_new( "NodeInsertActionMaxX", - _("Insert node at max X"), - _("Insert new nodes at max X into selected segments"), - INKSCAPE_ICON("node_insert_max_x"), - secondarySize ); - g_object_set( inky, "short_label", _("Insert max X"), NULL ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_add_max_x), 0 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - } - { - InkAction* inky = ink_action_new( "NodeInsertActionMinY", - _("Insert node at min Y"), - _("Insert new nodes at min Y into selected segments"), - INKSCAPE_ICON("node_insert_min_y"), - secondarySize ); - g_object_set( inky, "short_label", _("Insert min Y"), NULL ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_add_min_y), 0 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - } - { - InkAction* inky = ink_action_new( "NodeInsertActionMaxY", - _("Insert node at max Y"), - _("Insert new nodes at max Y into selected segments"), - INKSCAPE_ICON("node_insert_max_y"), - secondarySize ); - g_object_set( inky, "short_label", _("Insert max Y"), NULL ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_add_max_y), 0 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - } - - { - InkAction* inky = ink_action_new( "NodeDeleteAction", - _("Delete node"), - _("Delete selected nodes"), - INKSCAPE_ICON("node-delete"), - secondarySize ); - g_object_set( inky, "short_label", _("Delete"), NULL ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_delete), 0 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - } - - { - InkAction* inky = ink_action_new( "NodeJoinAction", - _("Join nodes"), - _("Join selected nodes"), - INKSCAPE_ICON("node-join"), - secondarySize ); - g_object_set( inky, "short_label", _("Join"), NULL ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_join), 0 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - } - - { - InkAction* inky = ink_action_new( "NodeBreakAction", - _("Break nodes"), - _("Break path at selected nodes"), - INKSCAPE_ICON("node-break"), - secondarySize ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_break), 0 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - } - - - { - InkAction* inky = ink_action_new( "NodeJoinSegmentAction", - _("Join with segment"), - _("Join selected endnodes with a new segment"), - INKSCAPE_ICON("node-join-segment"), - secondarySize ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_join_segment), 0 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - } - - { - InkAction* inky = ink_action_new( "NodeDeleteSegmentAction", - _("Delete segment"), - _("Delete segment between two non-endpoint nodes"), - INKSCAPE_ICON("node-delete-segment"), - secondarySize ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_delete_segment), 0 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - } - - { - InkAction* inky = ink_action_new( "NodeCuspAction", - _("Node Cusp"), - _("Make selected nodes corner"), - INKSCAPE_ICON("node-type-cusp"), - secondarySize ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_cusp), 0 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - } - - { - InkAction* inky = ink_action_new( "NodeSmoothAction", - _("Node Smooth"), - _("Make selected nodes smooth"), - INKSCAPE_ICON("node-type-smooth"), - secondarySize ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_smooth), 0 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - } - - { - InkAction* inky = ink_action_new( "NodeSymmetricAction", - _("Node Symmetric"), - _("Make selected nodes symmetric"), - INKSCAPE_ICON("node-type-symmetric"), - secondarySize ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_symmetrical), 0 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - } - - { - InkAction* inky = ink_action_new( "NodeAutoAction", - _("Node Auto"), - _("Make selected nodes auto-smooth"), - INKSCAPE_ICON("node-type-auto-smooth"), - secondarySize ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_auto), 0 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - } - - { - InkAction* inky = ink_action_new( "NodeLineAction", - _("Node Line"), - _("Make selected segments lines"), - INKSCAPE_ICON("node-segment-line"), - secondarySize ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_toline), 0 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - } - - { - InkAction* inky = ink_action_new( "NodeCurveAction", - _("Node Curve"), - _("Make selected segments curves"), - INKSCAPE_ICON("node-segment-curve"), - secondarySize ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_tocurve), 0 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - } - - { - InkToggleAction* act = ink_toggle_action_new( "NodesShowTransformHandlesAction", - _("Show Transform Handles"), - _("Show transformation handles for selected nodes"), - "node-transform", - secondarySize ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(act), "/tools/nodes/show_transform_handles"); - g_signal_connect( holder, "destroy", G_CALLBACK(delete_prefspusher), pusher); - } - - { - InkToggleAction* act = ink_toggle_action_new( "NodesShowHandlesAction", - _("Show Handles"), - _("Show Bezier handles of selected nodes"), - INKSCAPE_ICON("show-node-handles"), - secondarySize ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(act), "/tools/nodes/show_handles"); - g_signal_connect( holder, "destroy", G_CALLBACK(delete_prefspusher), pusher); - } - - { - InkToggleAction* act = ink_toggle_action_new( "NodesShowHelperpath", - _("Show Outline"), - _("Show path outline (without path effects)"), - INKSCAPE_ICON("show-path-outline"), - secondarySize ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(act), "/tools/nodes/show_outline"); - g_signal_connect( holder, "destroy", G_CALLBACK(delete_prefspusher), pusher); - } - - { - Inkscape::Verb* verb = Inkscape::Verb::get(SP_VERB_EDIT_NEXT_PATHEFFECT_PARAMETER); - InkAction* inky = ink_action_new( verb->get_id(), - verb->get_name(), - verb->get_tip(), - INKSCAPE_ICON("path-effect-parameter-next"), - secondarySize ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_nextLPEparam), desktop ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - g_object_set_data( holder, "nodes_lpeedit", inky); - } - - { - InkToggleAction* inky = ink_toggle_action_new( "ObjectEditClipPathAction", - _("Edit clipping paths"), - _("Show clipping path(s) of selected object(s)"), - INKSCAPE_ICON("path-clip-edit"), - secondarySize ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(inky), "/tools/nodes/edit_clipping_paths"); - g_signal_connect( holder, "destroy", G_CALLBACK(delete_prefspusher), pusher); - } - - { - InkToggleAction* inky = ink_toggle_action_new( "ObjectEditMaskPathAction", - _("Edit masks"), - _("Show mask(s) of selected object(s)"), - INKSCAPE_ICON("path-mask-edit"), - secondarySize ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(inky), "/tools/nodes/edit_masks"); - g_signal_connect( holder, "destroy", G_CALLBACK(delete_prefspusher), pusher); - } - - /* X coord of selected node(s) */ - { - EgeAdjustmentAction* eact = 0; - gchar const* labels[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - gdouble values[] = {1, 2, 3, 5, 10, 20, 50, 100, 200, 500}; - eact = create_adjustment_action( "NodeXAction", - _("X coordinate:"), _("X:"), _("X coordinate of selected node(s)"), - "/tools/nodes/Xcoord", 0, - GTK_WIDGET(desktop->canvas), holder, TRUE, "altx-nodes", - -1e6, 1e6, SPIN_STEP, SPIN_PAGE_STEP, - labels, values, G_N_ELEMENTS(labels), - sp_node_path_x_value_changed, tracker ); - g_object_set_data( holder, "nodes_x_action", eact ); - gtk_action_set_sensitive( GTK_ACTION(eact), FALSE ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - } - - /* Y coord of selected node(s) */ - { - EgeAdjustmentAction* eact = 0; - gchar const* labels[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - gdouble values[] = {1, 2, 3, 5, 10, 20, 50, 100, 200, 500}; - eact = create_adjustment_action( "NodeYAction", - _("Y coordinate:"), _("Y:"), _("Y coordinate of selected node(s)"), - "/tools/nodes/Ycoord", 0, - GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, - -1e6, 1e6, SPIN_STEP, SPIN_PAGE_STEP, - labels, values, G_N_ELEMENTS(labels), - sp_node_path_y_value_changed, tracker ); - g_object_set_data( holder, "nodes_y_action", eact ); - gtk_action_set_sensitive( GTK_ACTION(eact), FALSE ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - } - - // add the units menu - { - InkSelectOneAction* act = tracker->createAction( "NodeUnitsAction", _("Units"), ("") ); - gtk_action_group_add_action( mainActions, act->gobj() ); - } - - sp_node_toolbox_sel_changed(desktop->getSelection(), holder); - desktop->connectEventContextChanged(sigc::bind(sigc::ptr_fun(node_toolbox_watch_ec), holder)); - -} // end of sp_node_toolbox_prep() - -static void node_toolbox_watch_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolBase* ec, GObject* holder) -{ - static sigc::connection c_selection_changed; - static sigc::connection c_selection_modified; - static sigc::connection c_subselection_changed; - - if (INK_IS_NODE_TOOL(ec)) { - // watch selection - c_selection_changed = desktop->getSelection()->connectChanged(sigc::bind(sigc::ptr_fun(sp_node_toolbox_sel_changed), holder)); - c_selection_modified = desktop->getSelection()->connectModified(sigc::bind(sigc::ptr_fun(sp_node_toolbox_sel_modified), holder)); - c_subselection_changed = desktop->connectToolSubselectionChanged(sigc::bind(sigc::ptr_fun(sp_node_toolbox_coord_changed), holder)); - - sp_node_toolbox_sel_changed(desktop->getSelection(), holder); - } else { - if (c_selection_changed) - c_selection_changed.disconnect(); - if (c_selection_modified) - c_selection_modified.disconnect(); - if (c_subselection_changed) - c_subselection_changed.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:fileencoding=utf-8:textwidth=99 : diff --git a/src/widgets/node-toolbar.h b/src/widgets/node-toolbar.h deleted file mode 100644 index 1f2a3f6b7..000000000 --- a/src/widgets/node-toolbar.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef SEEN_NODE_TOOLBAR_H -#define SEEN_NODE_TOOLBAR_H - -/** - * @file - * Node aux toolbar - */ -/* Authors: - * MenTaLguY - * Lauris Kaplinski - * bulia byak - * Frank Felfe - * John Cliff - * David Turner - * Josh Andler - * Jon A. Cruz - * Maximilian Albert - * Tavmjong Bah - * Abhishek Sharma - * Kris De Gussem - * - * Copyright (C) 2004 David Turner - * Copyright (C) 2003 MenTaLguY - * Copyright (C) 1999-2011 authors - * Copyright (C) 2001-2002 Ximian, Inc. - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -class SPDesktop; - -typedef struct _GtkActionGroup GtkActionGroup; -typedef struct _GObject GObject; - -void sp_node_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); - -#endif /* !SEEN_SELECT_TOOLBAR_H */ diff --git a/src/widgets/paintbucket-toolbar.cpp b/src/widgets/paintbucket-toolbar.cpp deleted file mode 100644 index 280cf0eb1..000000000 --- a/src/widgets/paintbucket-toolbar.cpp +++ /dev/null @@ -1,260 +0,0 @@ -/** - * @file - * Paint bucket aux toolbar - */ -/* Authors: - * MenTaLguY - * Lauris Kaplinski - * bulia byak - * Frank Felfe - * John Cliff - * David Turner - * Josh Andler - * Jon A. Cruz - * Maximilian Albert - * Tavmjong Bah - * Abhishek Sharma - * Kris De Gussem - * - * Copyright (C) 2004 David Turner - * Copyright (C) 2003 MenTaLguY - * Copyright (C) 1999-2011 authors - * Copyright (C) 2001-2002 Ximian, Inc. - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include - -#include "paintbucket-toolbar.h" -#include "desktop.h" -#include "document-undo.h" - -#include "ui/icon-names.h" -#include "ui/tools/flood-tool.h" -#include "ui/uxmanager.h" -#include "ui/widget/ink-select-one-action.h" -#include "ui/widget/unit-tracker.h" - -#include "widgets/ink-action.h" -#include "widgets/ege-adjustment-action.h" -#include "widgets/toolbox.h" - -using Inkscape::UI::Widget::UnitTracker; -using Inkscape::UI::UXManager; -using Inkscape::DocumentUndo; -using Inkscape::UI::ToolboxFactory; -using Inkscape::UI::PrefPusher; -using Inkscape::Util::unit_table; - - -//######################### -//## Paintbucket ## -//######################### - -static void paintbucket_channels_changed(GObject* /*tbl*/, int channels) -{ - Inkscape::UI::Tools::FloodTool::set_channels(channels); -} - -static void paintbucket_threshold_changed(GtkAdjustment *adj, GObject * /*tbl*/) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setInt("/tools/paintbucket/threshold", (gint)gtk_adjustment_get_value(adj)); -} - -static void paintbucket_autogap_changed(GObject * /*tbl*/, int autogap) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setInt("/tools/paintbucket/autogap", autogap); -} - -static void paintbucket_offset_changed(GtkAdjustment *adj, GObject *tbl) -{ - UnitTracker* tracker = static_cast(g_object_get_data( tbl, "tracker" )); - Unit const *unit = tracker->getActiveUnit(); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - - // Don't adjust the offset value because we're saving the - // unit and it'll be correctly handled on load. - prefs->setDouble("/tools/paintbucket/offset", (gdouble)gtk_adjustment_get_value(adj)); - - g_return_if_fail(unit != NULL); - prefs->setString("/tools/paintbucket/offsetunits", unit->abbr); -} - -static void paintbucket_defaults(GtkWidget *, GObject *tbl) -{ - // FIXME: make defaults settable via Inkscape Options - struct KeyValue { - char const *key; - double value; - } const key_values[] = { - {"threshold", 15}, - {"offset", 0.0} - }; - - for (unsigned i = 0; i < G_N_ELEMENTS(key_values); ++i) { - KeyValue const &kv = key_values[i]; - GtkAdjustment* adj = static_cast(g_object_get_data(tbl, kv.key)); - if ( adj ) { - gtk_adjustment_set_value(adj, kv.value); - } - } - - InkSelectOneAction* channels_action = - static_cast( g_object_get_data( tbl, "channels_action" ) ); - channels_action->set_active( Inkscape::UI::Tools::FLOOD_CHANNELS_RGB ); - - InkSelectOneAction* autogap_action = - static_cast( g_object_get_data( tbl, "autogap_action" ) ); - autogap_action->set_active( 0 ); -} - -void sp_paintbucket_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) -{ - EgeAdjustmentAction* eact = 0; - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - - // Channel - { - InkSelectOneActionColumns columns; - - Glib::RefPtr store = Gtk::ListStore::create(columns); - - Gtk::TreeModel::Row row; - - for (auto item: Inkscape::UI::Tools::FloodTool::channel_list) { - row = *(store->append()); - row[columns.col_label ] = item; - row[columns.col_tooltip ] = (""); - row[columns.col_icon ] = "NotUsed"; - row[columns.col_sensitive] = true; - } - - InkSelectOneAction* act = - InkSelectOneAction::create( "ChannelsAction", // Name - _("Fill by"), // Label - (""), // Tooltip - "Not Used", // Icon - store ); // Tree store - - act->use_radio( false ); - act->use_icon( false ); - act->use_label( true ); - act->use_group_label( true ); - int channels = prefs->getInt("/tools/paintbucket/channels", 0); - act->set_active( channels ); - - gtk_action_group_add_action( mainActions, GTK_ACTION( act->gobj() )); - g_object_set_data( holder, "channels_action", act ); - - act->signal_changed().connect(sigc::bind<0>(sigc::ptr_fun(&paintbucket_channels_changed), holder)); - } - - // Spacing spinbox - { - eact = create_adjustment_action( - "ThresholdAction", - _("Fill Threshold"), _("Threshold:"), - _("The maximum allowed difference between the clicked pixel and the neighboring pixels to be counted in the fill"), - "/tools/paintbucket/threshold", 5, GTK_WIDGET(desktop->canvas), holder, TRUE, - "inkscape:paintbucket-threshold", 0, 100.0, 1.0, 10.0, - 0, 0, 0, - paintbucket_threshold_changed, NULL /*unit tracker*/, 1, 0 ); - - ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - } - - // Create the units menu. - UnitTracker* tracker = new UnitTracker(Inkscape::Util::UNIT_TYPE_LINEAR); - Glib::ustring stored_unit = prefs->getString("/tools/paintbucket/offsetunits"); - if (!stored_unit.empty()) { - Unit const *u = unit_table.getUnit(stored_unit); - tracker->setActiveUnit(u); - } - g_object_set_data( holder, "tracker", tracker ); - - { - InkSelectOneAction* act = tracker->createAction( "PaintbucketUnitsAction", _("Units"), ("") ); - gtk_action_group_add_action( mainActions, act->gobj() ); - } - - // Offset spinbox - { - eact = create_adjustment_action( - "OffsetAction", - _("Grow/shrink by"), _("Grow/shrink by:"), - _("The amount to grow (positive) or shrink (negative) the created fill path"), - "/tools/paintbucket/offset", 0, GTK_WIDGET(desktop->canvas), holder, TRUE, - "inkscape:paintbucket-offset", -1e4, 1e4, 0.1, 0.5, - 0, 0, 0, - paintbucket_offset_changed, tracker, 1, 2); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - } - - /* Auto Gap */ - { - InkSelectOneActionColumns columns; - - Glib::RefPtr store = Gtk::ListStore::create(columns); - - Gtk::TreeModel::Row row; - - for (auto item: Inkscape::UI::Tools::FloodTool::gap_list) { - row = *(store->append()); - row[columns.col_label ] = item; - row[columns.col_tooltip ] = (""); - row[columns.col_icon ] = "NotUsed"; - row[columns.col_sensitive] = true; - } - - InkSelectOneAction* act = - InkSelectOneAction::create( "AutoGapAction", // Name - _("Close gaps"), // Label - (""), // Tooltip - "Not Used", // Icon - store ); // Tree store - - act->use_radio( false ); - act->use_icon( false ); - act->use_label( true ); - act->use_group_label( true ); - int autogap = prefs->getInt("/tools/paintbucket/autogap"); - act->set_active( autogap ); - - gtk_action_group_add_action( mainActions, GTK_ACTION( act->gobj() )); - g_object_set_data( holder, "autogap_action", act ); - - act->signal_changed().connect(sigc::bind<0>(sigc::ptr_fun(&paintbucket_autogap_changed), holder)); - } - - /* Reset */ - { - InkAction* inky = ink_action_new( "PaintbucketResetAction", - _("Defaults"), - _("Reset paint bucket parameters to defaults (use Inkscape Preferences > Tools to change defaults)"), - INKSCAPE_ICON("edit-clear"), - GTK_ICON_SIZE_SMALL_TOOLBAR); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(paintbucket_defaults), holder ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - gtk_action_set_sensitive( GTK_ACTION(inky), TRUE ); - } - -} - -/* - 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:fileencoding=utf-8:textwidth=99 : diff --git a/src/widgets/paintbucket-toolbar.h b/src/widgets/paintbucket-toolbar.h deleted file mode 100644 index 9e6d6194a..000000000 --- a/src/widgets/paintbucket-toolbar.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef SEEN_PAINTBUCKET_TOOLBAR_H -#define SEEN_PAINTBUCKET_TOOLBAR_H - -/** - * @file - * Paintbucket aux toolbar - */ -/* Authors: - * MenTaLguY - * Lauris Kaplinski - * bulia byak - * Frank Felfe - * John Cliff - * David Turner - * Josh Andler - * Jon A. Cruz - * Maximilian Albert - * Tavmjong Bah - * Abhishek Sharma - * Kris De Gussem - * - * Copyright (C) 2004 David Turner - * Copyright (C) 2003 MenTaLguY - * Copyright (C) 1999-2011 authors - * Copyright (C) 2001-2002 Ximian, Inc. - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -class SPDesktop; - -typedef struct _GtkActionGroup GtkActionGroup; -typedef struct _GObject GObject; - -void sp_paintbucket_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); - -#endif /* !SEEN_PAINTBUCKET_TOOLBAR_H */ diff --git a/src/widgets/pencil-toolbar.cpp b/src/widgets/pencil-toolbar.cpp deleted file mode 100644 index d2939c720..000000000 --- a/src/widgets/pencil-toolbar.cpp +++ /dev/null @@ -1,640 +0,0 @@ -/** - * @file - * Pencil aux toolbar - */ -/* Authors: - * MenTaLguY - * Lauris Kaplinski - * bulia byak - * Frank Felfe - * John Cliff - * David Turner - * Josh Andler - * Jon A. Cruz - * Maximilian Albert - * Tavmjong Bah - * Abhishek Sharma - * Kris De Gussem - * - * Copyright (C) 2004 David Turner - * Copyright (C) 2003 MenTaLguY - * Copyright (C) 1999-2011 authors - * Copyright (C) 2001-2002 Ximian, Inc. - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include - -#include "pencil-toolbar.h" - -#include "desktop.h" -#include "selection.h" -#include "toolbox.h" - -#include "ink-action.h" -#include "ink-radio-action.h" -#include "ink-toggle-action.h" - -#include "live_effects/lpe-bspline.h" -#include "live_effects/lpe-powerstroke.h" -#include "live_effects/lpe-simplify.h" -#include "live_effects/lpe-spiro.h" -#include "live_effects/lpeobject-reference.h" -#include "live_effects/lpeobject.h" - -#include "display/curve.h" - -#include "object/sp-shape.h" - -#include "ui/icon-names.h" -#include "ui/tools-switch.h" -#include "ui/tools/pen-tool.h" -#include "ui/uxmanager.h" -#include "ui/widget/ink-select-one-action.h" - -#include "widgets/ege-adjustment-action.h" -#include "widgets/spinbutton-events.h" - - -using Inkscape::UI::UXManager; -using Inkscape::UI::ToolboxFactory; -using Inkscape::UI::PrefPusher; - -//######################## -//## Pen/Pencil ## -//######################## -static void sp_flatten_spiro_bspline(GtkWidget * /*widget*/, GObject *obj); -/* This is used in generic functions below to share large portions of code between pen and pencil tool */ -static Glib::ustring const freehand_tool_name(GObject *dataKludge) -{ - SPDesktop *desktop = static_cast(g_object_get_data(dataKludge, "desktop")); - return ( tools_isactive(desktop, TOOLS_FREEHAND_PEN) - ? "/tools/freehand/pen" - : "/tools/freehand/pencil" ); -} - -static void freehand_mode_changed(GObject* tbl, int mode) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setInt(freehand_tool_name(tbl) + "/freehand-mode", mode); - - if (mode == 1 || mode == 2) { - gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "flatten_spiro_bspline") ), true ); - } else { - gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "flatten_spiro_bspline") ), false ); - } - if (mode == 2) { - gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "flatten_simplify") ), false ); - gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "simplify") ), false ); - } else { - gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "flatten_simplify") ), true ); - gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "simplify") ), true ); - } -} - -static void use_pencil_pressure(InkToggleAction* itact, GObject *dataKludge) { - bool pressure = gtk_toggle_action_get_active( GTK_TOGGLE_ACTION(itact) ); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setBool(freehand_tool_name(dataKludge) + "/pressure", pressure); - if (pressure) { - gtk_action_set_visible( GTK_ACTION( g_object_get_data(dataKludge, "minpressure") ), true ); - gtk_action_set_visible( GTK_ACTION( g_object_get_data(dataKludge, "maxpressure") ), true ); - InkSelectOneAction* act = - static_cast( g_object_get_data( dataKludge, "shape_action" ) ); - act->set_visible (false); - } else { - gtk_action_set_visible( GTK_ACTION( g_object_get_data(dataKludge, "minpressure") ), false ); - gtk_action_set_visible( GTK_ACTION( g_object_get_data(dataKludge, "maxpressure") ), false ); - InkSelectOneAction* act = - static_cast( g_object_get_data( dataKludge, "shape_action" ) ); - act->set_visible (true); - } -} - -static void sp_add_freehand_mode_toggle(GtkActionGroup* mainActions, GObject* holder, bool tool_is_pencil) -{ - /* Freehand mode toggle buttons */ - - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - guint freehandMode = prefs->getInt(( tool_is_pencil ? - "/tools/freehand/pencil/freehand-mode" : - "/tools/freehand/pen/freehand-mode" ), 0); - GtkIconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1); - - InkSelectOneActionColumns columns; - - Glib::RefPtr store = Gtk::ListStore::create(columns); - - Gtk::TreeModel::Row row; - - row = *(store->append()); - row[columns.col_label ] = _("Bezier"); - row[columns.col_tooltip ] = _("Create regular Bezier path"); - row[columns.col_icon ] = INKSCAPE_ICON("path-mode-bezier"); - row[columns.col_sensitive] = true; - - row = *(store->append()); - row[columns.col_label ] = _("Spiro"); - row[columns.col_tooltip ] = _("Create Spiro path"); - row[columns.col_icon ] = INKSCAPE_ICON("path-mode-spiro"); - row[columns.col_sensitive] = true; - - row = *(store->append()); - row[columns.col_label ] = _("BSpline"); - row[columns.col_tooltip ] = _("Create BSpline path"); - row[columns.col_icon ] = INKSCAPE_ICON("path-mode-bspline"); - row[columns.col_sensitive] = true; - - if (!tool_is_pencil) { - row = *(store->append()); - row[columns.col_label ] = _("Zigzag"); - row[columns.col_tooltip ] = _("Create a sequence of straight line segments"); - row[columns.col_icon ] = INKSCAPE_ICON("path-mode-polyline"); - row[columns.col_sensitive] = true; - - row = *(store->append()); - row[columns.col_label ] = _("Paraxial"); - row[columns.col_tooltip ] = _("Create a sequence of paraxial line segments"); - row[columns.col_icon ] = INKSCAPE_ICON("path-mode-polyline-paraxial"); - row[columns.col_sensitive] = true; - } - - InkSelectOneAction* act = - InkSelectOneAction::create( tool_is_pencil ? - "FreehandModeActionPencil" : - "FreehandModeActionPen", - _("Mode"), // Label - _("Mode of new lines drawn by this tool"), // Tooltip - "Not Used", // Icon - store ); // Tree store - act->use_radio( true ); - act->use_label( true ); - act->set_active( freehandMode ); - - gtk_action_group_add_action( mainActions, GTK_ACTION( act->gobj() )); - // g_object_set_data( dataKludge, "flat_action", act ); - - act->signal_changed().connect(sigc::bind<0>(sigc::ptr_fun(&freehand_mode_changed), holder)); - - /* LPE bspline spiro flatten */ - InkAction* inky = ink_action_new( tool_is_pencil ? "FlattenSpiroBsplinePencil" : - "FlattenSpiroBsplinePen", - _("LPE spiro or bspline flatten"), - _("LPE spiro or bspline flatten"), - INKSCAPE_ICON("flatten"), - GTK_ICON_SIZE_SMALL_TOOLBAR ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_flatten_spiro_bspline), holder ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - g_object_set_data( holder, "flatten_spiro_bspline", inky ); - if (freehandMode == 1 || freehandMode == 2) { - gtk_action_set_visible( GTK_ACTION( g_object_get_data(holder, "flatten_spiro_bspline") ), true ); - } else { - gtk_action_set_visible( GTK_ACTION( g_object_get_data(holder, "flatten_spiro_bspline") ), false ); - } -} - -static void freehand_change_shape(GObject *dataKludge, int shape) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setInt(freehand_tool_name(dataKludge) + "/shape", shape); -} - -static void freehand_simplify_lpe(InkToggleAction* itact, GObject *dataKludge) { - bool simplify = gtk_toggle_action_get_active( GTK_TOGGLE_ACTION(itact) ); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setBool(freehand_tool_name(dataKludge) + "/simplify", simplify); - gtk_action_set_visible( GTK_ACTION( g_object_get_data(dataKludge, "flatten_simplify") ), simplify ); - if (simplify) { - gtk_action_set_visible( GTK_ACTION( g_object_get_data(dataKludge, "flatten_simplify") ), true ); - } else { - gtk_action_set_visible( GTK_ACTION( g_object_get_data(dataKludge, "flatten_simplify") ), false ); - } -} - -static void freehand_add_advanced_shape_options(GtkActionGroup* mainActions, GObject* holder, bool tool_is_pencil) -{ - /*advanced shape options */ - - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - - std::vector freehand_shape_dropdown_items_list = { - const_cast(C_("Freehand shape", "None")), - _("Triangle in"), - _("Triangle out"), - _("Ellipse"), - _("From clipboard"), - _("Bend from clipboard"), - _("Last applied") - }; - - InkSelectOneActionColumns columns; - - Glib::RefPtr store = Gtk::ListStore::create(columns); - - Gtk::TreeModel::Row row; - - for (auto item:freehand_shape_dropdown_items_list) { - - row = *(store->append()); - row[columns.col_label ] = item; - row[columns.col_tooltip ] = (""); - row[columns.col_icon ] = "NotUsed"; - row[columns.col_sensitive] = true; - } - - InkSelectOneAction* act = - InkSelectOneAction::create( tool_is_pencil ? - "SetPencilShapeAction" : - "SetPenShapeAction", // Name - _("Shape"), // Label - _("Shape of new paths drawn by this tool"), // Tooltip - "Not Used", // Icon - store ); // Tree store - - act->use_radio( false ); - act->use_icon( false ); - act->use_label( true ); - act->use_group_label( true ); - int shape = prefs->getInt( (tool_is_pencil ? - "/tools/freehand/pencil/shape" : - "/tools/freehand/pen/shape" ), 0); - act->set_active( shape ); - - gtk_action_group_add_action( mainActions, GTK_ACTION( act->gobj() )); - g_object_set_data( holder, "shape_action", act ); - - bool hide = prefs->getInt("/tools/freehand/pencil/freehand-mode", 0) == 3 || - (tool_is_pencil && prefs->getBool("/tools/freehand/pencil/pressure", false)); - act->set_visible( !hide ); - - act->signal_changed().connect(sigc::bind<0>(sigc::ptr_fun(&freehand_change_shape), holder)); -} - -void sp_pen_toolbox_prep(SPDesktop * /*desktop*/, GtkActionGroup* mainActions, GObject* holder) -{ - sp_add_freehand_mode_toggle(mainActions, holder, false); - freehand_add_advanced_shape_options(mainActions, holder, false); -} - - -static void sp_pencil_tb_defaults(GtkWidget * /*widget*/, GObject *obj) -{ - GtkWidget *tbl = GTK_WIDGET(obj); - - GtkAdjustment *adj; - - // fixme: make settable - gdouble tolerance = 4; - - adj = GTK_ADJUSTMENT(g_object_get_data(obj, "tolerance")); - gtk_adjustment_set_value(adj, tolerance); - -#if !GTK_CHECK_VERSION(3,18,0) - gtk_adjustment_value_changed(adj); -#endif - - spinbutton_defocus(tbl); -} - -static void sp_flatten_spiro_bspline(GtkWidget * /*widget*/, GObject *obj) -{ - SPDesktop *desktop = static_cast(g_object_get_data(obj, "desktop")); - auto selected = desktop->getSelection()->items(); - SPLPEItem* lpeitem = NULL; - for (auto it(selected.begin()); it != selected.end(); ++it){ - lpeitem = dynamic_cast(*it); - if (lpeitem && lpeitem->hasPathEffect()){ - PathEffectList lpelist = lpeitem->getEffectList(); - PathEffectList::iterator i; - for (i = lpelist.begin(); i != lpelist.end(); ++i) { - LivePathEffectObject *lpeobj = (*i)->lpeobject; - if (lpeobj) { - Inkscape::LivePathEffect::Effect *lpe = lpeobj->get_lpe(); - if (dynamic_cast(lpe) || - dynamic_cast(lpe)) - { - SPShape * shape = dynamic_cast(lpeitem); - if(shape){ - SPCurve * c = shape->getCurveForEdit(); - lpe->doEffect(c); - lpeitem->setCurrentPathEffect(*i); - if (lpelist.size() > 1){ - lpeitem->removeCurrentPathEffect(true); - shape->setCurveBeforeLPE(c); - } else { - lpeitem->removeCurrentPathEffect(false); - shape->setCurve(c, false); - } - break; - } - } - } - } - } - } - if (lpeitem) { - desktop->getSelection()->remove(lpeitem->getRepr()); - desktop->getSelection()->add(lpeitem->getRepr()); - sp_lpe_item_update_patheffect(lpeitem, false, false); - } -} - -static void sp_simplify_flatten(GtkWidget * /*widget*/, GObject *obj) -{ - SPDesktop *desktop = static_cast(g_object_get_data(obj, "desktop")); - auto selected = desktop->getSelection()->items(); - SPLPEItem* lpeitem = NULL; - for (auto it(selected.begin()); it != selected.end(); ++it){ - lpeitem = dynamic_cast(*it); - if (lpeitem && lpeitem->hasPathEffect()){ - PathEffectList lpelist = lpeitem->getEffectList(); - PathEffectList::iterator i; - for (i = lpelist.begin(); i != lpelist.end(); ++i) { - LivePathEffectObject *lpeobj = (*i)->lpeobject; - if (lpeobj) { - Inkscape::LivePathEffect::Effect *lpe = lpeobj->get_lpe(); - if (dynamic_cast(lpe)) { - SPShape * shape = dynamic_cast(lpeitem); - if(shape){ - SPCurve * c = shape->getCurveForEdit(); - lpe->doEffect(c); - lpeitem->setCurrentPathEffect(*i); - if (lpelist.size() > 1){ - lpeitem->removeCurrentPathEffect(true); - shape->setCurveBeforeLPE(c); - } else { - lpeitem->removeCurrentPathEffect(false); - shape->setCurve(c, false); - } - break; - } - } - } - } - } - } - if (lpeitem) { - desktop->getSelection()->remove(lpeitem->getRepr()); - desktop->getSelection()->add(lpeitem->getRepr()); - sp_lpe_item_update_patheffect(lpeitem, false, false); - } -} - -static void sp_minpressure_value_changed(GtkAdjustment *adj, GObject *tbl) -{ - // quit if run by the attr_changed listener - if (g_object_get_data( tbl, "freeze" )) { - return; - } - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble( "/tools/freehand/pencil/minpressure", gtk_adjustment_get_value(adj)); -} - -static void sp_maxpressure_value_changed(GtkAdjustment *adj, GObject *tbl) -{ - // quit if run by the attr_changed listener - if (g_object_get_data( tbl, "freeze" )) { - return; - } - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble( "/tools/freehand/pencil/maxpressure", gtk_adjustment_get_value(adj)); -} - -static void sp_pencil_tb_tolerance_value_changed(GtkAdjustment *adj, GObject *tbl) -{ - // quit if run by the attr_changed listener - if (g_object_get_data( tbl, "freeze" )) { - return; - } - // in turn, prevent listener from responding - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - prefs->setDouble("/tools/freehand/pencil/tolerance", - gtk_adjustment_get_value(adj)); - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); - SPDesktop *desktop = static_cast(g_object_get_data(tbl, "desktop")); - auto selected = desktop->getSelection()->items(); - for (auto it(selected.begin()); it != selected.end(); ++it){ - SPLPEItem* lpeitem = dynamic_cast(*it); - if (lpeitem && lpeitem->hasPathEffect()){ - Inkscape::LivePathEffect::Effect* simplify = lpeitem->getPathEffectOfType(Inkscape::LivePathEffect::SIMPLIFY); - if(simplify){ - Inkscape::LivePathEffect::LPESimplify *lpe_simplify = dynamic_cast(simplify->getLPEObj()->get_lpe()); - if (lpe_simplify) { - double tol = prefs->getDoubleLimited("/tools/freehand/pencil/tolerance", 10.0, 1.0, 100.0); - tol = tol/(100.0*(102.0-tol)); - std::ostringstream ss; - ss << tol; - Inkscape::LivePathEffect::Effect* powerstroke = lpeitem->getPathEffectOfType(Inkscape::LivePathEffect::POWERSTROKE); - bool simplified = false; - if(powerstroke){ - Inkscape::LivePathEffect::LPEPowerStroke *lpe_powerstroke = dynamic_cast(powerstroke->getLPEObj()->get_lpe()); - if(lpe_powerstroke){ - lpe_powerstroke->getRepr()->setAttribute("is_visible", "false"); - sp_lpe_item_update_patheffect(lpeitem, false, false); - SPShape *sp_shape = dynamic_cast(lpeitem); - if (sp_shape) { - guint previous_curve_length = sp_shape->getCurve()->get_segment_count(); - lpe_simplify->getRepr()->setAttribute("threshold", ss.str()); - sp_lpe_item_update_patheffect(lpeitem, false, false); - simplified = true; - guint curve_length = sp_shape->getCurve()->get_segment_count(); - std::vector ts = lpe_powerstroke->offset_points.data(); - double factor = (double)curve_length/ (double)previous_curve_length; - for (size_t i = 0; i < ts.size(); i++) { - ts[i][Geom::X] = ts[i][Geom::X] * factor; - } - lpe_powerstroke->offset_points.param_setValue(ts); - } - lpe_powerstroke->getRepr()->setAttribute("is_visible", "true"); - sp_lpe_item_update_patheffect(lpeitem, false, false); - } - } - if(!simplified){ - lpe_simplify->getRepr()->setAttribute("threshold", ss.str()); - } - } - } - } - } -} - -/* -class PencilToleranceObserver : public Inkscape::Preferences::Observer { -public: - PencilToleranceObserver(Glib::ustring const &path, GObject *x) : Observer(path), _obj(x) - { - g_object_set_data(_obj, "prefobserver", this); - } - virtual ~PencilToleranceObserver() { - if (g_object_get_data(_obj, "prefobserver") == this) { - g_object_set_data(_obj, "prefobserver", NULL); - } - } - virtual void notify(Inkscape::Preferences::Entry const &val) { - GObject* tbl = _obj; - if (g_object_get_data( tbl, "freeze" )) { - return; - } - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - - GtkAdjustment * adj = GTK_ADJUSTMENT(g_object_get_data(tbl, "tolerance")); - - double v = val.getDouble(adj->value); - gtk_adjustment_set_value(adj, v); - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); - } -private: - GObject *_obj; -}; -*/ - -void sp_pencil_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) -{ - sp_add_freehand_mode_toggle(mainActions, holder, true); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - EgeAdjustmentAction* eact = 0; - - - /* min pressure */ - { - eact = create_adjustment_action( "MinPressureAction", - _("Min pressure"), _("Min:"), _("Min percent of pressure"), - "/tools/freehand/pencil/minpressure", 0, - GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, - 0, 100, 1, 0, - 0, 0, 0, - sp_minpressure_value_changed, NULL, 0 ,0); - - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - g_object_set_data( holder, "minpressure", eact ); - if (prefs->getInt("/tools/freehand/pencil/freehand-mode", 0) == 3) { - gtk_action_set_visible( GTK_ACTION(eact), true ); - } else { - gtk_action_set_visible( GTK_ACTION(eact), false ); - } - } - /* max pressure */ - { - eact = create_adjustment_action( "MaxPressureAction", - _("Max pressure"), _("Max:"), _("Max percent of pressure"), - "/tools/freehand/pencil/maxpressure", 100, - GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, - 0, 100, 1, 0, - 0, 0, 0, - sp_maxpressure_value_changed, NULL, 0 ,0); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - g_object_set_data( holder, "maxpressure", eact ); - if (prefs->getInt("/tools/freehand/pencil/freehand-mode", 0) == 3) { - gtk_action_set_visible( GTK_ACTION(eact), true ); - } else { - gtk_action_set_visible( GTK_ACTION(eact), false ); - } - } - /* Use pressure */ - { - InkToggleAction* itact = ink_toggle_action_new( "PencilPressureAction", - _("Use pressure input"), - _("Use pressure input"), - INKSCAPE_ICON("draw-use-pressure"), - GTK_ICON_SIZE_SMALL_TOOLBAR ); - bool pressure = prefs->getBool(freehand_tool_name(holder) + "/pressure", false); - gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(itact), pressure ); - g_signal_connect_after( G_OBJECT(itact), "toggled", G_CALLBACK(use_pencil_pressure), holder) ; - gtk_action_group_add_action( mainActions, GTK_ACTION(itact) ); - if (pressure) { - gtk_action_set_visible( GTK_ACTION( g_object_get_data(holder, "minpressure") ), true ); - gtk_action_set_visible( GTK_ACTION( g_object_get_data(holder, "maxpressure") ), true ); - } else { - gtk_action_set_visible( GTK_ACTION( g_object_get_data(holder, "minpressure") ), false ); - gtk_action_set_visible( GTK_ACTION( g_object_get_data(holder, "maxpressure") ), false ); - } - } - /* Tolerance */ - { - gchar const* labels[] = {_("(many nodes, rough)"), _("(default)"), 0, 0, 0, 0, _("(few nodes, smooth)")}; - gdouble values[] = {1, 10, 20, 30, 50, 75, 100}; - eact = create_adjustment_action( "PencilToleranceAction", - _("Smoothing:"), _("Smoothing: "), - _("How much smoothing (simplifying) is applied to the line"), - "/tools/freehand/pencil/tolerance", - 3.0, - GTK_WIDGET(desktop->canvas), - holder, TRUE, "altx-pencil", - 1, 100.0, 0.5, 1.0, - labels, values, G_N_ELEMENTS(labels), - sp_pencil_tb_tolerance_value_changed, - NULL /*unit tracker*/, - 1, 2); - ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - } - - /* advanced shape options */ - freehand_add_advanced_shape_options(mainActions, holder, true); - - /* Reset */ - { - InkAction* inky = ink_action_new( "PencilResetAction", - _("Defaults"), - _("Reset pencil parameters to defaults (use Inkscape Preferences > Tools to change defaults)"), - INKSCAPE_ICON("edit-clear"), - GTK_ICON_SIZE_SMALL_TOOLBAR ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_pencil_tb_defaults), holder ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - } - /* LPE simplify based tolerance */ - { - InkToggleAction* itact = ink_toggle_action_new( "PencilLpeSimplify", - _("LPE based interactive simplify"), - _("LPE based interactive simplify"), - INKSCAPE_ICON("interactive_simplify"), - GTK_ICON_SIZE_SMALL_TOOLBAR ); - gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(itact), prefs->getInt("/tools/freehand/pencil/simplify", 0) ); - g_object_set_data( holder, "simplify", itact ); - g_signal_connect_after( G_OBJECT(itact), "toggled", G_CALLBACK(freehand_simplify_lpe), holder) ; - gtk_action_group_add_action( mainActions, GTK_ACTION(itact) ); - guint freehandMode = prefs->getInt("/tools/freehand/pencil/freehand-mode", 0); - if (freehandMode == 2) { - gtk_action_set_visible( GTK_ACTION( g_object_get_data(holder, "simplify") ), false ); - } else { - gtk_action_set_visible( GTK_ACTION( g_object_get_data(holder, "simplify") ), true ); - } - } - /* LPE simplify flatten */ - { - InkAction* inky = ink_action_new( "PencilLpeSimplifyFlatten", - _("LPE simplify flatten"), - _("LPE simplify flatten"), - INKSCAPE_ICON("flatten"), - GTK_ICON_SIZE_SMALL_TOOLBAR ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_simplify_flatten), holder ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - g_object_set_data( holder, "flatten_simplify", inky ); - guint freehandMode = prefs->getInt("/tools/freehand/pencil/freehand-mode", 0); - if (freehandMode == 2 || !prefs->getInt("/tools/freehand/pencil/simplify", 0)) { - gtk_action_set_visible( GTK_ACTION( g_object_get_data(holder, "flatten_simplify") ), false ); - } else { - gtk_action_set_visible( GTK_ACTION( g_object_get_data(holder, "flatten_simplify") ), true ); - } - } - - g_signal_connect( holder, "destroy", G_CALLBACK(purge_repr_listener), holder ); - -} - -/* - 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:fileencoding=utf-8:textwidth=99 : diff --git a/src/widgets/pencil-toolbar.h b/src/widgets/pencil-toolbar.h deleted file mode 100644 index c01b7d591..000000000 --- a/src/widgets/pencil-toolbar.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef SEEN_PENCIL_TOOLBAR_H -#define SEEN_PENCIL_TOOLBAR_H - -/** - * @file - * Pencil aux toolbar - */ -/* Authors: - * MenTaLguY - * Lauris Kaplinski - * bulia byak - * Frank Felfe - * John Cliff - * David Turner - * Josh Andler - * Jon A. Cruz - * Maximilian Albert - * Tavmjong Bah - * Abhishek Sharma - * Kris De Gussem - * - * Copyright (C) 2004 David Turner - * Copyright (C) 2003 MenTaLguY - * Copyright (C) 1999-2011 authors - * Copyright (C) 2001-2002 Ximian, Inc. - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -class SPDesktop; - -typedef struct _GtkActionGroup GtkActionGroup; -typedef struct _GObject GObject; - -void sp_pencil_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); -void sp_pen_toolbox_prep(SPDesktop * /*desktop*/, GtkActionGroup* mainActions, GObject* holder); - -#endif /* !SEEN_PENCIL_TOOLBAR_H */ diff --git a/src/widgets/rect-toolbar.cpp b/src/widgets/rect-toolbar.cpp deleted file mode 100644 index afa090ba7..000000000 --- a/src/widgets/rect-toolbar.cpp +++ /dev/null @@ -1,436 +0,0 @@ -/** - * @file - * Rect aux toolbar - */ -/* Authors: - * MenTaLguY - * Lauris Kaplinski - * bulia byak - * Frank Felfe - * John Cliff - * David Turner - * Josh Andler - * Jon A. Cruz - * Maximilian Albert - * Tavmjong Bah - * Abhishek Sharma - * Kris De Gussem - * - * Copyright (C) 2004 David Turner - * Copyright (C) 2003 MenTaLguY - * Copyright (C) 1999-2011 authors - * Copyright (C) 2001-2002 Ximian, Inc. - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include - -#include "rect-toolbar.h" - -#include "desktop.h" -#include "document-undo.h" -#include "inkscape.h" -#include "toolbox.h" -#include "verbs.h" - -#include "object/sp-namedview.h" -#include "object/sp-rect.h" - -#include "ui/icon-names.h" -#include "ui/tools/rect-tool.h" -#include "ui/uxmanager.h" -#include "ui/widget/ink-select-one-action.h" -#include "ui/widget/unit-tracker.h" - -#include "widgets/ege-adjustment-action.h" -#include "widgets/ege-output-action.h" -#include "widgets/ink-action.h" -#include "widgets/widget-sizes.h" - -#include "xml/node-event-vector.h" - -using Inkscape::UI::Widget::UnitTracker; -using Inkscape::UI::UXManager; -using Inkscape::DocumentUndo; -using Inkscape::UI::ToolboxFactory; -using Inkscape::UI::PrefPusher; -using Inkscape::Util::Unit; -using Inkscape::Util::Quantity; -using Inkscape::Util::unit_table; - - -//######################## -//## Rect ## -//######################## - -static void sp_rtb_sensitivize( GObject *tbl ) -{ - GtkAdjustment *adj1 = GTK_ADJUSTMENT( g_object_get_data(tbl, "rx") ); - GtkAdjustment *adj2 = GTK_ADJUSTMENT( g_object_get_data(tbl, "ry") ); - GtkAction* not_rounded = GTK_ACTION( g_object_get_data(tbl, "not_rounded") ); - - if (gtk_adjustment_get_value(adj1) == 0 && gtk_adjustment_get_value(adj2) == 0 && g_object_get_data(tbl, "single")) { // only for a single selected rect (for now) - gtk_action_set_sensitive( not_rounded, FALSE ); - } else { - gtk_action_set_sensitive( not_rounded, TRUE ); - } -} - - -static void sp_rtb_value_changed(GtkAdjustment *adj, GObject *tbl, gchar const *value_name, - void (SPRect::*setter)(gdouble)) -{ - SPDesktop *desktop = static_cast(g_object_get_data( tbl, "desktop" )); - - UnitTracker* tracker = reinterpret_cast(g_object_get_data( tbl, "tracker" )); - Unit const *unit = tracker->getActiveUnit(); - g_return_if_fail(unit != NULL); - - if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble(Glib::ustring("/tools/shapes/rect/") + value_name, - Quantity::convert(gtk_adjustment_get_value(adj), unit, "px")); - } - - // quit if run by the attr_changed listener - if (g_object_get_data( tbl, "freeze" ) || tracker->isUpdating()) { - return; - } - - // in turn, prevent listener from responding - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE)); - - bool modmade = false; - Inkscape::Selection *selection = desktop->getSelection(); - auto itemlist= selection->items(); - for(auto i=itemlist.begin();i!=itemlist.end();++i){ - if (SP_IS_RECT(*i)) { - if (gtk_adjustment_get_value(adj) != 0) { - (SP_RECT(*i)->*setter)(Quantity::convert(gtk_adjustment_get_value(adj), unit, "px")); - } else { - (*i)->getRepr()->setAttribute(value_name, NULL); - } - modmade = true; - } - } - - sp_rtb_sensitivize( tbl ); - - if (modmade) { - DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_RECT, - _("Change rectangle")); - } - - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -} - -static void sp_rtb_rx_value_changed(GtkAdjustment *adj, GObject *tbl) -{ - sp_rtb_value_changed(adj, tbl, "rx", &SPRect::setVisibleRx); -} - -static void sp_rtb_ry_value_changed(GtkAdjustment *adj, GObject *tbl) -{ - sp_rtb_value_changed(adj, tbl, "ry", &SPRect::setVisibleRy); -} - -static void sp_rtb_width_value_changed(GtkAdjustment *adj, GObject *tbl) -{ - sp_rtb_value_changed(adj, tbl, "width", &SPRect::setVisibleWidth); -} - -static void sp_rtb_height_value_changed(GtkAdjustment *adj, GObject *tbl) -{ - sp_rtb_value_changed(adj, tbl, "height", &SPRect::setVisibleHeight); -} - - - -static void sp_rtb_defaults( GtkWidget * /*widget*/, GObject *obj) -{ - GtkAdjustment *adj = 0; - - adj = GTK_ADJUSTMENT( g_object_get_data(obj, "rx") ); - gtk_adjustment_set_value(adj, 0.0); - -#if !GTK_CHECK_VERSION(3,18,0) - // this is necessary if the previous value was 0, but we still need to run the callback to change all selected objects - gtk_adjustment_value_changed(adj); -#endif - - adj = GTK_ADJUSTMENT( g_object_get_data(obj, "ry") ); - gtk_adjustment_set_value(adj, 0.0); - -#if !GTK_CHECK_VERSION(3,18,0) - gtk_adjustment_value_changed(adj); -#endif - - sp_rtb_sensitivize( obj ); -} - -static void rect_tb_event_attr_changed(Inkscape::XML::Node * /*repr*/, gchar const * /*name*/, - gchar const * /*old_value*/, gchar const * /*new_value*/, - bool /*is_interactive*/, gpointer data) -{ - GObject *tbl = G_OBJECT(data); - - // quit if run by the _changed callbacks - if (g_object_get_data( tbl, "freeze" )) { - return; - } - - // in turn, prevent callbacks from responding - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - - UnitTracker* tracker = reinterpret_cast( g_object_get_data( tbl, "tracker" ) ); - Unit const *unit = tracker->getActiveUnit(); - g_return_if_fail(unit != NULL); - - gpointer item = g_object_get_data( tbl, "item" ); - if (item && SP_IS_RECT(item)) { - { - GtkAdjustment *adj = GTK_ADJUSTMENT( g_object_get_data( tbl, "rx" ) ); - - gdouble rx = SP_RECT(item)->getVisibleRx(); - gtk_adjustment_set_value(adj, Quantity::convert(rx, "px", unit)); - } - - { - GtkAdjustment *adj = GTK_ADJUSTMENT( g_object_get_data( tbl, "ry" ) ); - - gdouble ry = SP_RECT(item)->getVisibleRy(); - gtk_adjustment_set_value(adj, Quantity::convert(ry, "px", unit)); - } - - { - GtkAdjustment *adj = GTK_ADJUSTMENT( g_object_get_data( tbl, "width" ) ); - - gdouble width = SP_RECT(item)->getVisibleWidth(); - gtk_adjustment_set_value(adj, Quantity::convert(width, "px", unit)); - } - - { - GtkAdjustment *adj = GTK_ADJUSTMENT( g_object_get_data( tbl, "height" ) ); - - gdouble height = SP_RECT(item)->getVisibleHeight(); - gtk_adjustment_set_value(adj, Quantity::convert(height, "px", unit)); - } - } - - sp_rtb_sensitivize( tbl ); - - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -} - - -static Inkscape::XML::NodeEventVector rect_tb_repr_events = { - NULL, /* child_added */ - NULL, /* child_removed */ - rect_tb_event_attr_changed, - NULL, /* content_changed */ - NULL /* order_changed */ -}; - -/** - * \param selection should not be NULL. - */ -static void sp_rect_toolbox_selection_changed(Inkscape::Selection *selection, GObject *tbl) -{ - int n_selected = 0; - Inkscape::XML::Node *repr = NULL; - SPItem *item = NULL; - - if ( g_object_get_data( tbl, "repr" ) ) { - g_object_set_data( tbl, "item", NULL ); - } - purge_repr_listener( tbl, tbl ); - - auto itemlist= selection->items(); - for(auto i=itemlist.begin();i!=itemlist.end();++i){ - if (SP_IS_RECT(*i)) { - n_selected++; - item = *i; - repr = item->getRepr(); - } - } - - EgeOutputAction* act = EGE_OUTPUT_ACTION( g_object_get_data( tbl, "mode_action" ) ); - - g_object_set_data( tbl, "single", GINT_TO_POINTER(FALSE) ); - - if (n_selected == 0) { - g_object_set( G_OBJECT(act), "label", _("New:"), NULL ); - - GtkAction* w = GTK_ACTION( g_object_get_data( tbl, "width_action" ) ); - gtk_action_set_sensitive(w, FALSE); - GtkAction* h = GTK_ACTION( g_object_get_data( tbl, "height_action" ) ); - gtk_action_set_sensitive(h, FALSE); - - } else if (n_selected == 1) { - g_object_set( G_OBJECT(act), "label", _("Change:"), NULL ); - g_object_set_data( tbl, "single", GINT_TO_POINTER(TRUE) ); - - GtkAction* w = GTK_ACTION( g_object_get_data( tbl, "width_action" ) ); - gtk_action_set_sensitive(w, TRUE); - GtkAction* h = GTK_ACTION( g_object_get_data( tbl, "height_action" ) ); - gtk_action_set_sensitive(h, TRUE); - - if (repr) { - g_object_set_data( tbl, "repr", repr ); - g_object_set_data( tbl, "item", item ); - Inkscape::GC::anchor(repr); - sp_repr_add_listener(repr, &rect_tb_repr_events, tbl); - sp_repr_synthesize_events(repr, &rect_tb_repr_events, tbl); - } - } else { - // FIXME: implement averaging of all parameters for multiple selected - //gtk_label_set_markup(GTK_LABEL(l), _("Average:")); - g_object_set( G_OBJECT(act), "label", _("Change:"), NULL ); - sp_rtb_sensitivize( tbl ); - } -} - -static void rect_toolbox_watch_ec(SPDesktop* dt, Inkscape::UI::Tools::ToolBase* ec, GObject* holder); - -void sp_rect_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) -{ - EgeAdjustmentAction* eact = 0; - GtkIconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1); - - { - EgeOutputAction* act = ege_output_action_new( "RectStateAction", _("New:"), "", 0 ); - ege_output_action_set_use_markup( act, TRUE ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - g_object_set_data( holder, "mode_action", act ); - } - - // rx/ry units menu: create - UnitTracker* tracker = new UnitTracker(Inkscape::Util::UNIT_TYPE_LINEAR); - //tracker->addUnit( SP_UNIT_PERCENT, 0 ); - // fixme: add % meaning per cent of the width/height - tracker->setActiveUnit(unit_table.getUnit("px")); - g_object_set_data( holder, "tracker", tracker ); - - /* W */ - { - gchar const* labels[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - gdouble values[] = {1, 2, 3, 5, 10, 20, 50, 100, 200, 500}; - eact = create_adjustment_action( "RectWidthAction", - _("Width"), _("W:"), _("Width of rectangle"), - "/tools/shapes/rect/width", 0, - GTK_WIDGET(desktop->canvas), holder, TRUE, "altx-rect", - 0, 1e6, SPIN_STEP, SPIN_PAGE_STEP, - labels, values, G_N_ELEMENTS(labels), - sp_rtb_width_value_changed, tracker); - g_object_set_data( holder, "width_action", eact ); - gtk_action_set_sensitive( GTK_ACTION(eact), FALSE ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - } - - /* H */ - { - gchar const* labels[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - gdouble values[] = {1, 2, 3, 5, 10, 20, 50, 100, 200, 500}; - eact = create_adjustment_action( "RectHeightAction", - _("Height"), _("H:"), _("Height of rectangle"), - "/tools/shapes/rect/height", 0, - GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, - 0, 1e6, SPIN_STEP, SPIN_PAGE_STEP, - labels, values, G_N_ELEMENTS(labels), - sp_rtb_height_value_changed, tracker); - g_object_set_data( holder, "height_action", eact ); - gtk_action_set_sensitive( GTK_ACTION(eact), FALSE ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - } - - /* rx */ - { - gchar const* labels[] = {_("not rounded"), 0, 0, 0, 0, 0, 0, 0, 0}; - gdouble values[] = {0.5, 1, 2, 3, 5, 10, 20, 50, 100}; - eact = create_adjustment_action( "RadiusXAction", - _("Horizontal radius"), _("Rx:"), _("Horizontal radius of rounded corners"), - "/tools/shapes/rect/rx", 0, - GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, - 0, 1e6, SPIN_STEP, SPIN_PAGE_STEP, - labels, values, G_N_ELEMENTS(labels), - sp_rtb_rx_value_changed, tracker); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - } - - /* ry */ - { - gchar const* labels[] = {_("not rounded"), 0, 0, 0, 0, 0, 0, 0, 0}; - gdouble values[] = {0.5, 1, 2, 3, 5, 10, 20, 50, 100}; - eact = create_adjustment_action( "RadiusYAction", - _("Vertical radius"), _("Ry:"), _("Vertical radius of rounded corners"), - "/tools/shapes/rect/ry", 0, - GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, - 0, 1e6, SPIN_STEP, SPIN_PAGE_STEP, - labels, values, G_N_ELEMENTS(labels), - sp_rtb_ry_value_changed, tracker); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - } - - // add the units menu - { - InkSelectOneAction* act = tracker->createAction( "RectUnitsAction", _("Units"), ("") ); - gtk_action_group_add_action( mainActions, act->gobj() ); - } - - /* Reset */ - { - InkAction* inky = ink_action_new( "RectResetAction", - _("Not rounded"), - _("Make corners sharp"), - INKSCAPE_ICON("rectangle-make-corners-sharp"), - secondarySize ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_rtb_defaults), holder ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - gtk_action_set_sensitive( GTK_ACTION(inky), TRUE ); - g_object_set_data( holder, "not_rounded", inky ); - } - - g_object_set_data( holder, "single", GINT_TO_POINTER(TRUE) ); - sp_rtb_sensitivize( holder ); - - desktop->connectEventContextChanged(sigc::bind(sigc::ptr_fun(rect_toolbox_watch_ec), holder)); - g_signal_connect( holder, "destroy", G_CALLBACK(purge_repr_listener), holder ); -} - -static void rect_toolbox_watch_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolBase* ec, GObject* holder) -{ - static sigc::connection changed; - - // use of dynamic_cast<> seems wrong here -- we just need to check the current tool - - if (dynamic_cast(ec)) { - Inkscape::Selection *sel = desktop->getSelection(); - - changed = sel->connectChanged(sigc::bind(sigc::ptr_fun(sp_rect_toolbox_selection_changed), holder)); - - // Synthesize an emission to trigger the update - sp_rect_toolbox_selection_changed(sel, holder); - } else { - if (changed) { - changed.disconnect(); - purge_repr_listener(NULL, holder); - } - } -} - -/* - 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:fileencoding=utf-8 : diff --git a/src/widgets/rect-toolbar.h b/src/widgets/rect-toolbar.h deleted file mode 100644 index f89903c6c..000000000 --- a/src/widgets/rect-toolbar.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef SEEN_RECT_TOOLBAR_H -#define SEEN_RECT_TOOLBAR_H - -/** - * @file - * Rect aux toolbar - */ -/* Authors: - * MenTaLguY - * Lauris Kaplinski - * bulia byak - * Frank Felfe - * John Cliff - * David Turner - * Josh Andler - * Jon A. Cruz - * Maximilian Albert - * Tavmjong Bah - * Abhishek Sharma - * Kris De Gussem - * - * Copyright (C) 2004 David Turner - * Copyright (C) 2003 MenTaLguY - * Copyright (C) 1999-2011 authors - * Copyright (C) 2001-2002 Ximian, Inc. - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -class SPDesktop; - -typedef struct _GtkActionGroup GtkActionGroup; -typedef struct _GObject GObject; - -void sp_rect_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); - -#endif /* !SEEN_RECT_TOOLBAR_H */ diff --git a/src/widgets/select-toolbar.cpp b/src/widgets/select-toolbar.cpp deleted file mode 100644 index 53191fc37..000000000 --- a/src/widgets/select-toolbar.cpp +++ /dev/null @@ -1,616 +0,0 @@ -/* - * Selector aux toolbar - * - * Authors: - * Lauris Kaplinski - * bulia byak - * Jon A. Cruz - * Abhishek Sharma - * - * Copyright (C) 2003-2005 authors - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include - -#include <2geom/rect.h> - -#include "select-toolbar.h" - -#include "desktop.h" -#include "document-undo.h" -#include "document.h" -#include "ink-action.h" -#include "ink-toggle-action.h" -#include "inkscape.h" -#include "message-stack.h" -#include "selection-chemistry.h" -#include "toolbox.h" -#include "verbs.h" - -#include "display/sp-canvas.h" - -#include "helper/action-context.h" -#include "helper/action.h" - -#include "object/sp-item-transform.h" -#include "object/sp-namedview.h" - -#include "ui/icon-names.h" -#include "ui/widget/ink-select-one-action.h" -#include "ui/widget/spinbutton.h" -#include "ui/widget/unit-tracker.h" - -#include "widgets/ege-adjustment-action.h" -#include "widgets/sp-widget.h" -#include "widgets/widget-sizes.h" - -using Inkscape::UI::Widget::UnitTracker; -using Inkscape::Util::Unit; -using Inkscape::Util::Quantity; -using Inkscape::DocumentUndo; -using Inkscape::Util::unit_table; - -static void -sp_selection_layout_widget_update(SPWidget *spw, Inkscape::Selection *sel) -{ - if (g_object_get_data(G_OBJECT(spw), "update")) { - return; - } - - g_object_set_data(G_OBJECT(spw), "update", GINT_TO_POINTER(TRUE)); - - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - using Geom::X; - using Geom::Y; - if ( sel && !sel->isEmpty() ) { - int prefs_bbox = prefs->getInt("/tools/bounding_box", 0); - SPItem::BBoxType bbox_type = (prefs_bbox ==0)? - SPItem::VISUAL_BBOX : SPItem::GEOMETRIC_BBOX; - Geom::OptRect const bbox(sel->bounds(bbox_type)); - if ( bbox ) { - UnitTracker *tracker = reinterpret_cast(g_object_get_data(G_OBJECT(spw), "tracker")); - Unit const *unit = tracker->getActiveUnit(); - g_return_if_fail(unit != NULL); - - struct { char const *key; double val; } const keyval[] = { - { "X", bbox->min()[X] }, - { "Y", bbox->min()[Y] }, - { "width", bbox->dimensions()[X] }, - { "height", bbox->dimensions()[Y] } - }; - - if (unit->type == Inkscape::Util::UNIT_TYPE_DIMENSIONLESS) { - double const val = unit->factor * 100; - for (unsigned i = 0; i < G_N_ELEMENTS(keyval); ++i) { - GtkAdjustment *a = GTK_ADJUSTMENT(g_object_get_data(G_OBJECT(spw), keyval[i].key)); - gtk_adjustment_set_value(a, val); - tracker->setFullVal( a, keyval[i].val ); - } - } else { - for (unsigned i = 0; i < G_N_ELEMENTS(keyval); ++i) { - GtkAdjustment *a = GTK_ADJUSTMENT(g_object_get_data(G_OBJECT(spw), keyval[i].key)); - gtk_adjustment_set_value(a, Quantity::convert(keyval[i].val, "px", unit)); - } - } - } - } - - g_object_set_data(G_OBJECT(spw), "update", GINT_TO_POINTER(FALSE)); -} - - -static void -sp_selection_layout_widget_modify_selection(SPWidget *spw, Inkscape::Selection *selection, guint flags, gpointer data) -{ - SPDesktop *desktop = static_cast(data); - if ((desktop->getSelection() == selection) // only respond to changes in our desktop - && (flags & (SP_OBJECT_MODIFIED_FLAG | - SP_OBJECT_PARENT_MODIFIED_FLAG | - SP_OBJECT_CHILD_MODIFIED_FLAG ))) - { - sp_selection_layout_widget_update(spw, selection); - } -} - -static void -sp_selection_layout_widget_change_selection(SPWidget *spw, Inkscape::Selection *selection, gpointer data) -{ - SPDesktop *desktop = static_cast(data); - if (desktop->getSelection() == selection) { // only respond to changes in our desktop - gboolean setActive = (selection && !selection->isEmpty()); - std::vector *contextActions = reinterpret_cast *>(g_object_get_data(G_OBJECT(spw), "contextActions")); - if ( contextActions ) { - for ( std::vector::iterator iter = contextActions->begin(); - iter != contextActions->end(); ++iter) { - if ( setActive != gtk_action_is_sensitive(*iter) ) { - gtk_action_set_sensitive( *iter, setActive ); - } - } - } - - sp_selection_layout_widget_update(spw, selection); - } -} - -static void -sp_object_layout_any_value_changed(GtkAdjustment *adj, GObject *tbl) -{ - if (g_object_get_data(tbl, "update")) { - return; - } - - UnitTracker *tracker = reinterpret_cast(g_object_get_data(tbl, "tracker")); - if ( !tracker || tracker->isUpdating() ) { - /* - * When only units are being changed, don't treat changes - * to adjuster values as object changes. - */ - return; - } - g_object_set_data(tbl, "update", GINT_TO_POINTER(TRUE)); - - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - Inkscape::Selection *selection = desktop->getSelection(); - SPDocument *document = desktop->getDocument(); - - document->ensureUpToDate (); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - - Geom::OptRect bbox_vis = selection->visualBounds(); - Geom::OptRect bbox_geom = selection->geometricBounds(); - - int prefs_bbox = prefs->getInt("/tools/bounding_box"); - SPItem::BBoxType bbox_type = (prefs_bbox == 0)? - SPItem::VISUAL_BBOX : SPItem::GEOMETRIC_BBOX; - Geom::OptRect bbox_user = selection->bounds(bbox_type); - - if ( !bbox_user ) { - g_object_set_data(tbl, "update", GINT_TO_POINTER(FALSE)); - return; - } - - gdouble x0 = 0; - gdouble y0 = 0; - gdouble x1 = 0; - gdouble y1 = 0; - gdouble xrel = 0; - gdouble yrel = 0; - Unit const *unit = tracker->getActiveUnit(); - g_return_if_fail(unit != NULL); - - GtkAdjustment* a_x = GTK_ADJUSTMENT( g_object_get_data( tbl, "X" ) ); - GtkAdjustment* a_y = GTK_ADJUSTMENT( g_object_get_data( tbl, "Y" ) ); - GtkAdjustment* a_w = GTK_ADJUSTMENT( g_object_get_data( tbl, "width" ) ); - GtkAdjustment* a_h = GTK_ADJUSTMENT( g_object_get_data( tbl, "height" ) ); - - if (unit->type == Inkscape::Util::UNIT_TYPE_LINEAR) { - x0 = Quantity::convert(gtk_adjustment_get_value(a_x), unit, "px"); - y0 = Quantity::convert(gtk_adjustment_get_value(a_y), unit, "px"); - x1 = x0 + Quantity::convert(gtk_adjustment_get_value(a_w), unit, "px"); - xrel = Quantity::convert(gtk_adjustment_get_value(a_w), unit, "px") / bbox_user->dimensions()[Geom::X]; - y1 = y0 + Quantity::convert(gtk_adjustment_get_value(a_h), unit, "px");; - yrel = Quantity::convert(gtk_adjustment_get_value(a_h), unit, "px") / bbox_user->dimensions()[Geom::Y]; - } else { - double const x0_propn = gtk_adjustment_get_value (a_x) / 100 / unit->factor; - x0 = bbox_user->min()[Geom::X] * x0_propn; - double const y0_propn = gtk_adjustment_get_value (a_y) / 100 / unit->factor; - y0 = y0_propn * bbox_user->min()[Geom::Y]; - xrel = gtk_adjustment_get_value (a_w) / (100 / unit->factor); - x1 = x0 + xrel * bbox_user->dimensions()[Geom::X]; - yrel = gtk_adjustment_get_value (a_h) / (100 / unit->factor); - y1 = y0 + yrel * bbox_user->dimensions()[Geom::Y]; - } - - // Keep proportions if lock is on - GtkToggleAction *lock = GTK_TOGGLE_ACTION( g_object_get_data(tbl, "lock") ); - if ( gtk_toggle_action_get_active(lock) ) { - if (adj == a_h) { - x1 = x0 + yrel * bbox_user->dimensions()[Geom::X]; - } else if (adj == a_w) { - y1 = y0 + xrel * bbox_user->dimensions()[Geom::Y]; - } - } - - // scales and moves, in px - double mh = fabs(x0 - bbox_user->min()[Geom::X]); - double sh = fabs(x1 - bbox_user->max()[Geom::X]); - double mv = fabs(y0 - bbox_user->min()[Geom::Y]); - double sv = fabs(y1 - bbox_user->max()[Geom::Y]); - - // unless the unit is %, convert the scales and moves to the unit - if (unit->type == Inkscape::Util::UNIT_TYPE_LINEAR) { - mh = Quantity::convert(mh, "px", unit); - sh = Quantity::convert(sh, "px", unit); - mv = Quantity::convert(mv, "px", unit); - sv = Quantity::convert(sv, "px", unit); - } - - // do the action only if one of the scales/moves is greater than half the last significant - // digit in the spinbox (currently spinboxes have 3 fractional digits, so that makes 0.0005). If - // the value was changed by the user, the difference will be at least that much; otherwise it's - // just rounding difference between the spinbox value and actual value, so no action is - // performed - char const * const actionkey = ( mh > 5e-4 ? "selector:toolbar:move:horizontal" : - sh > 5e-4 ? "selector:toolbar:scale:horizontal" : - mv > 5e-4 ? "selector:toolbar:move:vertical" : - sv > 5e-4 ? "selector:toolbar:scale:vertical" : NULL ); - - if (actionkey != NULL) { - - // FIXME: fix for GTK breakage, see comment in SelectedStyle::on_opacity_changed - desktop->getCanvas()->forceFullRedrawAfterInterruptions(0); - - bool transform_stroke = prefs->getBool("/options/transform/stroke", true); - bool preserve = prefs->getBool("/options/preservetransform/value", false); - - Geom::Affine scaler; - if (bbox_type == SPItem::VISUAL_BBOX) { - scaler = get_scale_transform_for_variable_stroke (*bbox_vis, *bbox_geom, transform_stroke, preserve, x0, y0, x1, y1); - } else { - // 1) We could have use the newer get_scale_transform_for_variable_stroke() here, but to avoid regressions - // we'll just use the old get_scale_transform_for_uniform_stroke() for now. - // 2) get_scale_transform_for_uniform_stroke() is intended for visual bounding boxes, not geometrical ones! - // we'll trick it into using a geometric bounding box though, by setting the stroke width to zero - scaler = get_scale_transform_for_uniform_stroke (*bbox_geom, 0, 0, false, false, x0, y0, x1, y1); - } - - selection->applyAffine(scaler); - DocumentUndo::maybeDone(document, actionkey, SP_VERB_CONTEXT_SELECT, - _("Transform by toolbar")); - - // resume interruptibility - desktop->getCanvas()->endForcedFullRedraws(); - } - - g_object_set_data(tbl, "update", GINT_TO_POINTER(FALSE)); -} - -// toggle button callbacks and updaters - -static void toggle_stroke( GtkToggleAction* act, gpointer data ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - gboolean active = gtk_toggle_action_get_active(act); - prefs->setBool("/options/transform/stroke", active); - SPDesktop *desktop = static_cast(data); - if ( active ) { - desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Now stroke width is scaled when objects are scaled.")); - } else { - desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Now stroke width is not scaled when objects are scaled.")); - } -} - -static void toggle_corners( GtkToggleAction* act, gpointer data) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - gboolean active = gtk_toggle_action_get_active(act); - prefs->setBool("/options/transform/rectcorners", active); - SPDesktop *desktop = static_cast(data); - if ( active ) { - desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Now rounded rectangle corners are scaled when rectangles are scaled.")); - } else { - desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Now rounded rectangle corners are not scaled when rectangles are scaled.")); - } -} - -static void toggle_gradient( GtkToggleAction *act, gpointer data ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - gboolean active = gtk_toggle_action_get_active(act); - prefs->setBool("/options/transform/gradient", active); - SPDesktop *desktop = static_cast(data); - if ( active ) { - desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Now gradients are transformed along with their objects when those are transformed (moved, scaled, rotated, or skewed).")); - } else { - desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Now gradients remain fixed when objects are transformed (moved, scaled, rotated, or skewed).")); - } -} - -static void toggle_pattern( GtkToggleAction* act, gpointer data ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - gboolean active = gtk_toggle_action_get_active(act); - prefs->setInt("/options/transform/pattern", active); - SPDesktop *desktop = static_cast(data); - if ( active ) { - desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Now patterns are transformed along with their objects when those are transformed (moved, scaled, rotated, or skewed).")); - } else { - desktop->messageStack()->flash(Inkscape::INFORMATION_MESSAGE, _("Now patterns remain fixed when objects are transformed (moved, scaled, rotated, or skewed).")); - } -} - -static void toggle_lock( 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 ); - } -} - -static void destroy_tracker( GObject* obj, gpointer /*user_data*/ ) -{ - UnitTracker *tracker = reinterpret_cast(g_object_get_data(obj, "tracker")); - if ( tracker ) { - delete tracker; - g_object_set_data( obj, "tracker", 0 ); - } -} - -static void trigger_sp_action( GtkAction* /*act*/, gpointer user_data ) -{ - SPAction* targetAction = SP_ACTION(user_data); - if ( targetAction ) { - sp_action_perform( targetAction, NULL ); - } -} - -static GtkAction* create_action_for_verb( Inkscape::Verb* verb, Inkscape::UI::View::View* view, GtkIconSize size ) -{ - GtkAction* act = 0; - - SPAction* targetAction = verb->get_action(Inkscape::ActionContext(view)); - InkAction* inky = ink_action_new( verb->get_id(), verb->get_name(), verb->get_tip(), verb->get_image(), size ); - act = GTK_ACTION(inky); - - g_signal_connect( G_OBJECT(inky), "activate", G_CALLBACK(trigger_sp_action), targetAction ); - - return act; -} - -void sp_select_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) -{ - Inkscape::UI::View::View *view = desktop; - GtkIconSize secondarySize = Inkscape::UI::ToolboxFactory::prefToSize("/toolbox/secondary", 1); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - - GtkAction* act = 0; - - GtkActionGroup* selectionActions = mainActions; // temporary - std::vector* contextActions = new std::vector(); - - act = create_action_for_verb( Inkscape::Verb::get(SP_VERB_EDIT_SELECT_ALL), view, secondarySize ); - gtk_action_group_add_action( selectionActions, act ); - act = create_action_for_verb( Inkscape::Verb::get(SP_VERB_EDIT_SELECT_ALL_IN_ALL_LAYERS), view, secondarySize ); - gtk_action_group_add_action( selectionActions, act ); - act = create_action_for_verb( Inkscape::Verb::get(SP_VERB_EDIT_DESELECT), view, secondarySize ); - gtk_action_group_add_action( selectionActions, act ); - contextActions->push_back( act ); - - act = create_action_for_verb( Inkscape::Verb::get(SP_VERB_OBJECT_ROTATE_90_CCW), view, secondarySize ); - gtk_action_group_add_action( selectionActions, act ); - contextActions->push_back( act ); - act = create_action_for_verb( Inkscape::Verb::get(SP_VERB_OBJECT_ROTATE_90_CW), view, secondarySize ); - gtk_action_group_add_action( selectionActions, act ); - contextActions->push_back( act ); - act = create_action_for_verb( Inkscape::Verb::get(SP_VERB_OBJECT_FLIP_HORIZONTAL), view, secondarySize ); - gtk_action_group_add_action( selectionActions, act ); - contextActions->push_back( act ); - act = create_action_for_verb( Inkscape::Verb::get(SP_VERB_OBJECT_FLIP_VERTICAL), view, secondarySize ); - gtk_action_group_add_action( selectionActions, act ); - contextActions->push_back( act ); - - act = create_action_for_verb( Inkscape::Verb::get(SP_VERB_SELECTION_TO_BACK), view, secondarySize ); - gtk_action_group_add_action( selectionActions, act ); - contextActions->push_back( act ); - act = create_action_for_verb( Inkscape::Verb::get(SP_VERB_SELECTION_LOWER), view, secondarySize ); - gtk_action_group_add_action( selectionActions, act ); - contextActions->push_back( act ); - act = create_action_for_verb( Inkscape::Verb::get(SP_VERB_SELECTION_RAISE), view, secondarySize ); - gtk_action_group_add_action( selectionActions, act ); - contextActions->push_back( act ); - act = create_action_for_verb( Inkscape::Verb::get(SP_VERB_SELECTION_TO_FRONT), view, secondarySize ); - gtk_action_group_add_action( selectionActions, act ); - contextActions->push_back( act ); - - // Create the parent widget for x y w h tracker. - GtkWidget *spw = sp_widget_new_global(); - - // Remember the desktop's canvas widget, to be used for defocusing. - g_object_set_data(G_OBJECT(spw), "dtw", desktop->getCanvas()); - - // The vb frame holds all other widgets and is used to set sensitivity depending on selection state. - auto vb = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); - gtk_box_set_homogeneous(GTK_BOX(vb), FALSE); - gtk_widget_show(vb); - gtk_container_add(GTK_CONTAINER(spw), vb); - - // Create the units menu. - UnitTracker* tracker = new UnitTracker(Inkscape::Util::UNIT_TYPE_LINEAR); - tracker->addUnit(unit_table.getUnit("%")); - tracker->setActiveUnit( desktop->getNamedView()->display_units ); - - g_object_set_data( G_OBJECT(spw), "tracker", tracker ); - g_signal_connect( G_OBJECT(spw), "destroy", G_CALLBACK(destroy_tracker), spw ); - - EgeAdjustmentAction* eact = 0; - - // four spinbuttons - - eact = create_adjustment_action( - "XAction", /* name */ - C_("Select toolbar", "X position"), /* label */ - C_("Select toolbar", "X:"), /* shortLabel */ - C_("Select toolbar", "Horizontal coordinate of selection"), /* tooltip */ - "/tools/select/X", /* path */ - 0.0, /* def(default) */ - GTK_WIDGET(desktop->canvas), /* focusTarget */ - G_OBJECT(spw), /* dataKludge */ - TRUE, "altx", /* altx, altx_mark */ - -1e6, 1e6, SPIN_STEP, SPIN_PAGE_STEP, /* lower, upper, step, page */ - 0, 0, 0, /* descrLabels, descrValues, descrCount */ - sp_object_layout_any_value_changed, /* callback */ - tracker, /* unit_tracker */ - SPIN_STEP, 3, 1); /* climb, digits, factor */ - - gtk_action_group_add_action( selectionActions, GTK_ACTION(eact) ); - contextActions->push_back( GTK_ACTION(eact) ); - - eact = create_adjustment_action( - "YAction", /* name */ - C_("Select toolbar", "Y position"), /* label */ - C_("Select toolbar", "Y:"), /* shortLabel */ - C_("Select toolbar", "Vertical coordinate of selection"), /* tooltip */ - "/tools/select/Y", /* path */ - 0.0, /* def(default) */ - GTK_WIDGET(desktop->canvas), /* focusTarget */ - G_OBJECT(spw), /* dataKludge */ - TRUE, "altx", /* altx, altx_mark */ - -1e6, 1e6, SPIN_STEP, SPIN_PAGE_STEP, /* lower, upper, step, page */ - 0, 0, 0, /* descrLabels, descrValues, descrCount */ - sp_object_layout_any_value_changed, /* callback */ - tracker, /* unit_tracker */ - SPIN_STEP, 3, 1); /* climb, digits, factor */ - - gtk_action_group_add_action( selectionActions, GTK_ACTION(eact) ); - contextActions->push_back( GTK_ACTION(eact) ); - - eact = create_adjustment_action( - "WidthAction", /* name */ - C_("Select toolbar", "Width"), /* label */ - C_("Select toolbar", "W:"), /* shortLabel */ - C_("Select toolbar", "Width of selection"), /* tooltip */ - "/tools/select/width", /* path */ - 0.0, /* def(default) */ - GTK_WIDGET(desktop->canvas), /* focusTarget */ - G_OBJECT(spw), /* dataKludge */ - TRUE, "altx", /* altx, altx_mark */ - 0.0, 1e6, SPIN_STEP, SPIN_PAGE_STEP, /* lower, upper, step, page */ - 0, 0, 0, /* descrLabels, descrValues, descrCount */ - sp_object_layout_any_value_changed, /* callback */ - tracker, /* unit_tracker */ - SPIN_STEP, 3, 1); /* climb, digits, factor */ - - gtk_action_group_add_action( selectionActions, GTK_ACTION(eact) ); - contextActions->push_back( GTK_ACTION(eact) ); - - // lock toggle - { - InkToggleAction* itact = ink_toggle_action_new( "LockAction", - _("Lock width and height"), - _("When locked, change both width and height by the same proportion"), - INKSCAPE_ICON("object-unlocked"), - GTK_ICON_SIZE_MENU ); - g_object_set( itact, "short_label", "Lock", NULL ); - g_object_set_data( G_OBJECT(spw), "lock", itact ); - g_signal_connect_after( G_OBJECT(itact), "toggled", G_CALLBACK(toggle_lock), desktop) ; - gtk_action_group_add_action( mainActions, GTK_ACTION(itact) ); - } - - eact = create_adjustment_action( - "HeightAction", /* name */ - C_("Select toolbar", "Height"), /* label */ - C_("Select toolbar", "H:"), /* shortLabel */ - C_("Select toolbar", "Height of selection"), /* tooltip */ - "/tools/select/height", /* path */ - 0.0, /* def(default) */ - GTK_WIDGET(desktop->canvas), /* focusTarget */ - G_OBJECT(spw), /* dataKludge */ - TRUE, "altx", /* altx, altx_mark */ - 0.0, 1e6, SPIN_STEP, SPIN_PAGE_STEP, /* lower, upper, step, page */ - 0, 0, 0, /* descrLabels, descrValues, descrCount */ - sp_object_layout_any_value_changed, /* callback */ - tracker, /* unit_tracker */ - SPIN_STEP, 3, 1); /* climb, digits, factor */ - - - gtk_action_group_add_action( selectionActions, GTK_ACTION(eact) ); - contextActions->push_back( GTK_ACTION(eact) ); - - // Add the units menu. - { - InkSelectOneAction* act = tracker->createAction( "UnitsAction", _("Units"), ("") ); - gtk_action_group_add_action( selectionActions, act->gobj() ); - } - - g_object_set_data( G_OBJECT(spw), "selectionActions", selectionActions ); - g_object_set_data( G_OBJECT(spw), "contextActions", contextActions ); - - // Force update when selection changes. - g_signal_connect(G_OBJECT(spw), "modify_selection", G_CALLBACK(sp_selection_layout_widget_modify_selection), desktop); - g_signal_connect(G_OBJECT(spw), "change_selection", G_CALLBACK(sp_selection_layout_widget_change_selection), desktop); - - // Update now. - sp_selection_layout_widget_update(SP_WIDGET(spw), SP_ACTIVE_DESKTOP ? SP_ACTIVE_DESKTOP->getSelection() : NULL); - - for ( std::vector::iterator iter = contextActions->begin(); - iter != contextActions->end(); ++iter) { - if ( gtk_action_is_sensitive(*iter) ) { - gtk_action_set_sensitive( *iter, FALSE ); - } - } - - // Insert spw into the toolbar. - if ( GTK_IS_BOX(holder) ) { - gtk_box_pack_start(GTK_BOX(holder), spw, FALSE, FALSE, 0); - } else if ( GTK_IS_TOOLBAR(holder) ) { - GtkToolItem *spw_toolitem = gtk_tool_item_new(); - gtk_container_add(GTK_CONTAINER(spw_toolitem), spw); - gtk_toolbar_insert(GTK_TOOLBAR(holder), spw_toolitem, -1); - } else { - g_warning("Unexpected holder type"); - } - // "Transform with object" buttons - { - - InkToggleAction* itact = ink_toggle_action_new( "transform_stroke", - _("Scale stroke width"), - _("When scaling objects, scale the stroke width by the same proportion"), - "transform-affect-stroke", - secondarySize ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(itact), prefs->getBool("/options/transform/stroke", true) ); - g_signal_connect_after( G_OBJECT(itact), "toggled", G_CALLBACK(toggle_stroke), desktop) ; - gtk_action_group_add_action( mainActions, GTK_ACTION(itact) ); - } - - { - InkToggleAction* itact = ink_toggle_action_new( "transform_corners", - _("Scale rounded corners"), - _("When scaling rectangles, scale the radii of rounded corners"), - "transform-affect-rounded-corners", - secondarySize ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(itact), prefs->getBool("/options/transform/rectcorners", true) ); - g_signal_connect_after( G_OBJECT(itact), "toggled", G_CALLBACK(toggle_corners), desktop) ; - gtk_action_group_add_action( mainActions, GTK_ACTION(itact) ); - } - - { - InkToggleAction* itact = ink_toggle_action_new( "transform_gradient", - _("Move gradients"), - _("Move gradients (in fill or stroke) along with the objects"), - "transform-affect-gradient", - secondarySize ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(itact), prefs->getBool("/options/transform/gradient", true) ); - g_signal_connect_after( G_OBJECT(itact), "toggled", G_CALLBACK(toggle_gradient), desktop) ; - gtk_action_group_add_action( mainActions, GTK_ACTION(itact) ); - } - - { - InkToggleAction* itact = ink_toggle_action_new( "transform_pattern", - _("Move patterns"), - _("Move patterns (in fill or stroke) along with the objects"), - "transform-affect-pattern", - secondarySize ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(itact), prefs->getBool("/options/transform/pattern", true) ); - g_signal_connect_after( G_OBJECT(itact), "toggled", G_CALLBACK(toggle_pattern), desktop) ; - gtk_action_group_add_action( mainActions, GTK_ACTION(itact) ); - } -} - - -/* - 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 : diff --git a/src/widgets/select-toolbar.h b/src/widgets/select-toolbar.h deleted file mode 100644 index b900a0615..000000000 --- a/src/widgets/select-toolbar.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef SEEN_SELECT_TOOLBAR_H -#define SEEN_SELECT_TOOLBAR_H - -/** \file - * Selector aux toolbar - */ -/* - * Authors: - * Lauris Kaplinski - * bulia byak - * - * Copyright (C) 2003 authors - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -class SPDesktop; - -typedef struct _GtkActionGroup GtkActionGroup; -typedef struct _GObject GObject; - -void sp_select_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); - - -#endif /* !SEEN_SELECT_TOOLBAR_H */ - -/* - 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:fileencoding=utf-8:textwidth=99 : diff --git a/src/widgets/spiral-toolbar.cpp b/src/widgets/spiral-toolbar.cpp deleted file mode 100644 index 79ea30e8e..000000000 --- a/src/widgets/spiral-toolbar.cpp +++ /dev/null @@ -1,319 +0,0 @@ -/** - * @file - * Spiral aux toolbar - */ -/* Authors: - * MenTaLguY - * Lauris Kaplinski - * bulia byak - * Frank Felfe - * John Cliff - * David Turner - * Josh Andler - * Jon A. Cruz - * Maximilian Albert - * Tavmjong Bah - * Abhishek Sharma - * Kris De Gussem - * - * Copyright (C) 2004 David Turner - * Copyright (C) 2003 MenTaLguY - * Copyright (C) 1999-2011 authors - * Copyright (C) 2001-2002 Ximian, Inc. - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include - -#include "spiral-toolbar.h" - -#include "desktop.h" -#include "document-undo.h" -#include "selection.h" -#include "toolbox.h" -#include "verbs.h" - -#include "object/sp-spiral.h" - -#include "ui/icon-names.h" -#include "ui/uxmanager.h" - -#include "widgets/ege-adjustment-action.h" -#include "widgets/ege-output-action.h" -#include "widgets/ink-action.h" -#include "widgets/spinbutton-events.h" - -#include "xml/node-event-vector.h" - -using Inkscape::UI::UXManager; -using Inkscape::DocumentUndo; -using Inkscape::UI::ToolboxFactory; -using Inkscape::UI::PrefPusher; - -//######################## -//## Spiral ## -//######################## - -static void sp_spl_tb_value_changed(GtkAdjustment *adj, GObject *tbl, Glib::ustring const &value_name) -{ - SPDesktop *desktop = static_cast(g_object_get_data( tbl, "desktop" )); - - if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble("/tools/shapes/spiral/" + value_name, - gtk_adjustment_get_value(adj)); - } - - // quit if run by the attr_changed listener - if (g_object_get_data( tbl, "freeze" )) { - return; - } - - // in turn, prevent listener from responding - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - - gchar* namespaced_name = g_strconcat("sodipodi:", value_name.data(), NULL); - - bool modmade = false; - auto itemlist= desktop->getSelection()->items(); - for(auto i=itemlist.begin();i!=itemlist.end(); ++i){ - SPItem *item = *i; - if (SP_IS_SPIRAL(item)) { - Inkscape::XML::Node *repr = item->getRepr(); - sp_repr_set_svg_double( repr, namespaced_name, - gtk_adjustment_get_value(adj) ); - item->updateRepr(); - modmade = true; - } - } - - g_free(namespaced_name); - - if (modmade) { - DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_SPIRAL, - _("Change spiral")); - } - - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -} - -static void sp_spl_tb_revolution_value_changed(GtkAdjustment *adj, GObject *tbl) -{ - sp_spl_tb_value_changed(adj, tbl, "revolution"); -} - -static void sp_spl_tb_expansion_value_changed(GtkAdjustment *adj, GObject *tbl) -{ - sp_spl_tb_value_changed(adj, tbl, "expansion"); -} - -static void sp_spl_tb_t0_value_changed(GtkAdjustment *adj, GObject *tbl) -{ - sp_spl_tb_value_changed(adj, tbl, "t0"); -} - -static void sp_spl_tb_defaults(GtkWidget * /*widget*/, GObject *obj) -{ - GtkWidget *tbl = GTK_WIDGET(obj); - - GtkAdjustment *adj; - - // fixme: make settable - gdouble rev = 3; - gdouble exp = 1.0; - gdouble t0 = 0.0; - - adj = GTK_ADJUSTMENT(g_object_get_data(obj, "revolution")); - gtk_adjustment_set_value(adj, rev); - -#if !GTK_CHECK_VERSION(3,18,0) - gtk_adjustment_value_changed(adj); -#endif - - adj = GTK_ADJUSTMENT(g_object_get_data(obj, "expansion")); - gtk_adjustment_set_value(adj, exp); - gtk_adjustment_value_changed(adj); - - adj = GTK_ADJUSTMENT(g_object_get_data(obj, "t0")); - gtk_adjustment_set_value(adj, t0); - -#if !GTK_CHECK_VERSION(3,18,0) - gtk_adjustment_value_changed(adj); -#endif - - spinbutton_defocus(tbl); -} - - -static void spiral_tb_event_attr_changed(Inkscape::XML::Node *repr, - gchar const * /*name*/, - gchar const * /*old_value*/, - gchar const * /*new_value*/, - bool /*is_interactive*/, - gpointer data) -{ - GtkWidget *tbl = GTK_WIDGET(data); - - // quit if run by the _changed callbacks - if (g_object_get_data(G_OBJECT(tbl), "freeze")) { - return; - } - - // in turn, prevent callbacks from responding - g_object_set_data(G_OBJECT(tbl), "freeze", GINT_TO_POINTER(TRUE)); - - GtkAdjustment *adj; - adj = GTK_ADJUSTMENT(g_object_get_data(G_OBJECT(tbl), "revolution")); - double revolution = 3.0; - sp_repr_get_double(repr, "sodipodi:revolution", &revolution); - gtk_adjustment_set_value(adj, revolution); - - adj = GTK_ADJUSTMENT(g_object_get_data(G_OBJECT(tbl), "expansion")); - double expansion = 1.0; - sp_repr_get_double(repr, "sodipodi:expansion", &expansion); - gtk_adjustment_set_value(adj, expansion); - - adj = GTK_ADJUSTMENT(g_object_get_data(G_OBJECT(tbl), "t0")); - double t0 = 0.0; - sp_repr_get_double(repr, "sodipodi:t0", &t0); - gtk_adjustment_set_value(adj, t0); - - g_object_set_data(G_OBJECT(tbl), "freeze", GINT_TO_POINTER(FALSE)); -} - - -static Inkscape::XML::NodeEventVector spiral_tb_repr_events = { - NULL, /* child_added */ - NULL, /* child_removed */ - spiral_tb_event_attr_changed, - NULL, /* content_changed */ - NULL /* order_changed */ -}; - -static void sp_spiral_toolbox_selection_changed(Inkscape::Selection *selection, GObject *tbl) -{ - int n_selected = 0; - Inkscape::XML::Node *repr = NULL; - - purge_repr_listener( tbl, tbl ); - - auto itemlist= selection->items(); - for(auto i=itemlist.begin();i!=itemlist.end(); ++i){ - SPItem *item = *i; - if (SP_IS_SPIRAL(item)) { - n_selected++; - repr = item->getRepr(); - } - } - - EgeOutputAction* act = EGE_OUTPUT_ACTION( g_object_get_data( tbl, "mode_action" ) ); - - if (n_selected == 0) { - g_object_set( G_OBJECT(act), "label", _("New:"), NULL ); - } else if (n_selected == 1) { - g_object_set( G_OBJECT(act), "label", _("Change:"), NULL ); - - if (repr) { - g_object_set_data( tbl, "repr", repr ); - Inkscape::GC::anchor(repr); - sp_repr_add_listener(repr, &spiral_tb_repr_events, tbl); - sp_repr_synthesize_events(repr, &spiral_tb_repr_events, tbl); - } - } else { - // FIXME: implement averaging of all parameters for multiple selected - //gtk_label_set_markup(GTK_LABEL(l), _("Average:")); - g_object_set( G_OBJECT(act), "label", _("Change:"), NULL ); - } -} - - -void sp_spiral_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) -{ - EgeAdjustmentAction* eact = 0; - GtkIconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1); - - { - EgeOutputAction* act = ege_output_action_new( "SpiralStateAction", _("New:"), "", 0 ); - ege_output_action_set_use_markup( act, TRUE ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - g_object_set_data( holder, "mode_action", act ); - } - - /* Revolution */ - { - gchar const* labels[] = {_("just a curve"), 0, _("one full revolution"), 0, 0, 0, 0, 0, 0}; - gdouble values[] = {0.01, 0.5, 1, 2, 3, 5, 10, 20, 50, 100}; - eact = create_adjustment_action( "SpiralRevolutionAction", - _("Number of turns"), _("Turns:"), _("Number of revolutions"), - "/tools/shapes/spiral/revolution", 3.0, - GTK_WIDGET(desktop->canvas), holder, TRUE, "altx-spiral", - 0.01, 1024.0, 0.1, 1.0, - labels, values, G_N_ELEMENTS(labels), - sp_spl_tb_revolution_value_changed, NULL /*unit tracker*/, 1, 2); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - } - - /* Expansion */ - { - gchar const* labels[] = {_("circle"), _("edge is much denser"), _("edge is denser"), _("even"), _("center is denser"), _("center is much denser"), 0}; - gdouble values[] = {0, 0.1, 0.5, 1, 1.5, 5, 20}; - eact = create_adjustment_action( "SpiralExpansionAction", - _("Divergence"), _("Divergence:"), _("How much denser/sparser are outer revolutions; 1 = uniform"), - "/tools/shapes/spiral/expansion", 1.0, - GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, - 0.0, 1000.0, 0.01, 1.0, - labels, values, G_N_ELEMENTS(labels), - sp_spl_tb_expansion_value_changed); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - } - - /* T0 */ - { - gchar const* labels[] = {_("starts from center"), _("starts mid-way"), _("starts near edge")}; - gdouble values[] = {0, 0.5, 0.9}; - eact = create_adjustment_action( "SpiralT0Action", - _("Inner radius"), _("Inner radius:"), _("Radius of the innermost revolution (relative to the spiral size)"), - "/tools/shapes/spiral/t0", 0.0, - GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, - 0.0, 0.999, 0.01, 1.0, - labels, values, G_N_ELEMENTS(labels), - sp_spl_tb_t0_value_changed); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - } - - /* Reset */ - { - InkAction* inky = ink_action_new( "SpiralResetAction", - _("Defaults"), - _("Reset shape parameters to defaults (use Inkscape Preferences > Tools to change defaults)"), - INKSCAPE_ICON("edit-clear"), - secondarySize ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_spl_tb_defaults), holder ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - } - - - sigc::connection *connection = new sigc::connection( - desktop->getSelection()->connectChanged(sigc::bind(sigc::ptr_fun(sp_spiral_toolbox_selection_changed), holder)) - ); - g_signal_connect( holder, "destroy", G_CALLBACK(delete_connection), connection ); - g_signal_connect( holder, "destroy", G_CALLBACK(purge_repr_listener), holder ); -} - - -/* - 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:fileencoding=utf-8:textwidth=99 : diff --git a/src/widgets/spiral-toolbar.h b/src/widgets/spiral-toolbar.h deleted file mode 100644 index 3372ea224..000000000 --- a/src/widgets/spiral-toolbar.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef SEEN_SPIRAL_TOOLBAR_H -#define SEEN_SPIRAL_TOOLBAR_H - -/** - * @file - * Spiral aux toolbar - */ -/* Authors: - * MenTaLguY - * Lauris Kaplinski - * bulia byak - * Frank Felfe - * John Cliff - * David Turner - * Josh Andler - * Jon A. Cruz - * Maximilian Albert - * Tavmjong Bah - * Abhishek Sharma - * Kris De Gussem - * - * Copyright (C) 2004 David Turner - * Copyright (C) 2003 MenTaLguY - * Copyright (C) 1999-2011 authors - * Copyright (C) 2001-2002 Ximian, Inc. - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -class SPDesktop; - -typedef struct _GtkActionGroup GtkActionGroup; -typedef struct _GObject GObject; - -void sp_spiral_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); - -#endif /* !SEEN_SPIRAL_TOOLBAR_H */ diff --git a/src/widgets/spray-toolbar.cpp b/src/widgets/spray-toolbar.cpp deleted file mode 100644 index 361364992..000000000 --- a/src/widgets/spray-toolbar.cpp +++ /dev/null @@ -1,630 +0,0 @@ -/** - * @file - * Spray aux toolbar - */ -/* Authors: - * MenTaLguY - * Lauris Kaplinski - * bulia byak - * Frank Felfe - * John Cliff - * David Turner - * Josh Andler - * Jon A. Cruz - * Maximilian Albert - * Tavmjong Bah - * Abhishek Sharma - * Kris De Gussem - * Jabiertxo Arraiza - * - * Copyright (C) 2004 David Turner - * Copyright (C) 2003 MenTaLguY - * Copyright (C) 1999-2015 authors - * Copyright (C) 2001-2002 Ximian, Inc. - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include - -#include "spray-toolbar.h" -#include "desktop.h" -#include "inkscape.h" -#include "widgets/ege-adjustment-action.h" -#include "ink-radio-action.h" -#include "ink-toggle-action.h" -#include "toolbox.h" -#include "ui/dialog/clonetiler.h" -#include "ui/dialog/dialog-manager.h" -#include "ui/dialog/panel-dialog.h" -#include "ui/widget/ink-select-one-action.h" -#include "ui/icon-names.h" - -#include - -using Inkscape::UI::ToolboxFactory; -using Inkscape::UI::PrefPusher; - -// Disabled in 0.91 because of Bug #1274831 (crash, spraying an object -// with the mode: spray object in single path) -// Please enable again when working on 1.0 -#define ENABLE_SPRAY_MODE_SINGLE_PATH - -//######################## -//## Spray ## -//######################## - -static void sp_stb_update_widgets( GObject *tbl ) -{ - GtkAction* offset = GTK_ACTION( g_object_get_data(tbl, "offset") ); - GtkAction* spray_scale = GTK_ACTION( g_object_get_data(tbl, "spray_scale") ); - GtkAdjustment *adj_offset = ege_adjustment_action_get_adjustment( EGE_ADJUSTMENT_ACTION(offset) ); - GtkAdjustment *adj_scale = ege_adjustment_action_get_adjustment( EGE_ADJUSTMENT_ACTION(spray_scale) ); - GtkAction *no_overlap_action = GTK_ACTION( g_object_get_data(tbl, "no_overlap") ); - GtkToggleAction *no_overlap = GTK_TOGGLE_ACTION( g_object_get_data(tbl, "no_overlap") ); - GtkAction *picker_action = GTK_ACTION( g_object_get_data(tbl, "picker") ); - GtkToggleAction *picker = GTK_TOGGLE_ACTION( g_object_get_data(tbl, "picker") ); - GtkToggleAction *usepressurescale = GTK_TOGGLE_ACTION( g_object_get_data(tbl, "usepressurescale") ); - GtkAction *pick_fill = GTK_ACTION( g_object_get_data(tbl, "pick_fill") ); - GtkAction *pick_stroke = GTK_ACTION( g_object_get_data(tbl, "pick_stroke") ); - GtkAction *pick_inverse_value = GTK_ACTION( g_object_get_data(tbl, "pick_inverse_value") ); - GtkAction *pick_center = GTK_ACTION( g_object_get_data(tbl, "pick_center") ); - gtk_adjustment_set_value( adj_offset, 100.0 ); - if (gtk_toggle_action_get_active(no_overlap) && gtk_action_get_visible(no_overlap_action)) { - gtk_action_set_visible( offset, true ); - } else { - gtk_action_set_visible( offset, false ); - } - if (gtk_toggle_action_get_active(usepressurescale)) { - gtk_adjustment_set_value( adj_scale, 0.0 ); - gtk_action_set_sensitive( spray_scale, false ); - } else { - gtk_action_set_sensitive( spray_scale, true ); - } - if(gtk_toggle_action_get_active(picker) && gtk_action_get_visible(picker_action)){ - gtk_action_set_visible( pick_fill, true ); - gtk_action_set_visible( pick_stroke, true ); - gtk_action_set_visible( pick_inverse_value, true ); - gtk_action_set_visible( pick_center, true ); - } else { - gtk_action_set_visible( pick_fill, false ); - gtk_action_set_visible( pick_stroke, false ); - gtk_action_set_visible( pick_inverse_value, false ); - gtk_action_set_visible( pick_center, false ); - } -} - -static void sp_spray_init( GObject *tbl){ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - int mode = prefs->getInt("/tools/spray/mode", 0); - - bool show = true; - if(mode == 3 || mode == 2){ - show = false; - } - gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "no_overlap") ), show ); - gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "over_no_transparent") ), show ); - gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "over_transparent") ), show ); - gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "pick_no_overlap") ), show ); - gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "pick_stroke") ), show ); - gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "pick_fill") ), show ); - gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "pick_inverse_value") ), show ); - gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "pick_center") ), show ); - gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "picker") ), show ); - gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "offset") ), show ); - gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "pick_fill") ), show ); - gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "pick_stroke") ), show ); - gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "pick_inverse_value") ), show ); - gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "pick_center") ), show ); - if(mode == 2){ - show = true; - } - gtk_action_set_visible( GTK_ACTION( g_object_get_data(tbl, "spray_rotation") ), show ); - sp_stb_update_widgets( tbl ); -} - -Inkscape::UI::Dialog::CloneTiler *get_clone_tiler_panel(SPDesktop *desktop) -{ - if (Inkscape::UI::Dialog::PanelDialogBase *panel_dialog = - dynamic_cast(desktop->_dlg_mgr->getDialog("CloneTiler"))) { - try { - Inkscape::UI::Dialog::CloneTiler &clone_tiler = - dynamic_cast(panel_dialog->getPanel()); - return &clone_tiler; - } catch (std::exception &e) { } - } - - return 0; -} - -static void sp_spray_width_value_changed( GtkAdjustment *adj, GObject * /*tbl*/ ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble( "/tools/spray/width", - gtk_adjustment_get_value(adj)); -} - -static void sp_spray_mean_value_changed( GtkAdjustment *adj, GObject * /*tbl*/ ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble( "/tools/spray/mean", - gtk_adjustment_get_value(adj)); -} - -static void sp_spray_standard_deviation_value_changed( GtkAdjustment *adj, GObject * /*tbl*/ ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble( "/tools/spray/standard_deviation", - gtk_adjustment_get_value(adj)); -} - -static void sp_spray_mode_changed( GObject *tbl, int mode ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setInt("/tools/spray/mode", mode); - sp_spray_init(tbl); -} - -static void sp_spray_population_value_changed( GtkAdjustment *adj, GObject * /*tbl*/ ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble( "/tools/spray/population", - gtk_adjustment_get_value(adj)); -} - -static void sp_spray_rotation_value_changed( GtkAdjustment *adj, GObject * /*tbl*/ ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble( "/tools/spray/rotation_variation", - gtk_adjustment_get_value(adj)); -} - -static void sp_spray_scale_value_changed( GtkAdjustment *adj, GObject * /*tbl*/ ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble( "/tools/spray/scale_variation", - gtk_adjustment_get_value(adj)); -} - -static void sp_spray_offset_value_changed( GtkAdjustment *adj, GObject * /*tbl*/ ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble( "/tools/spray/offset", - gtk_adjustment_get_value(adj)); -} - -static void sp_toggle_no_overlap( GtkToggleAction* act, gpointer data) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - gboolean active = gtk_toggle_action_get_active(act); - prefs->setBool("/tools/spray/no_overlap", active); - GObject *tbl = G_OBJECT(data); - sp_stb_update_widgets(tbl); -} - -static void sp_toggle_pressure_scale( GtkToggleAction* act, gpointer data) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - gboolean active = gtk_toggle_action_get_active(act); - prefs->setBool("/tools/spray/usepressurescale", active); - if(active){ - prefs->setDouble("/tools/spray/scale_variation", 0); - } - GObject *tbl = G_OBJECT(data); - sp_stb_update_widgets( tbl ); -} - -static void sp_toggle_over_no_transparent( GtkToggleAction* act, gpointer data) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - gboolean active = gtk_toggle_action_get_active(act); - prefs->setBool("/tools/spray/over_no_transparent", active); -} - -static void sp_toggle_over_transparent( GtkToggleAction* act, gpointer data) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - gboolean active = gtk_toggle_action_get_active(act); - prefs->setBool("/tools/spray/over_transparent", active); -} - - -static void sp_toggle_picker( GtkToggleAction* act, gpointer data ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - gboolean active = gtk_toggle_action_get_active(act); - prefs->setBool("/tools/spray/picker", active); - if(active){ - prefs->setBool("/dialogs/clonetiler/dotrace", false); - SPDesktop *dt = SP_ACTIVE_DESKTOP; - if (Inkscape::UI::Dialog::CloneTiler *ct = get_clone_tiler_panel(dt)){ - dt->_dlg_mgr->showDialog("CloneTiler"); - ct->show_page_trace(); - } - } - GObject *tbl = G_OBJECT(data); - sp_stb_update_widgets(tbl); -} - -static void sp_toggle_pick_center( GtkToggleAction* act, gpointer data ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - gboolean active = gtk_toggle_action_get_active(act); - prefs->setBool("/tools/spray/pick_center", active); -} - -static void sp_toggle_pick_fill( GtkToggleAction* act, gpointer data ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - gboolean active = gtk_toggle_action_get_active(act); - prefs->setBool("/tools/spray/pick_fill", active); -} - -static void sp_toggle_pick_stroke( GtkToggleAction* act, gpointer data ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - gboolean active = gtk_toggle_action_get_active(act); - prefs->setBool("/tools/spray/pick_stroke", active); -} - -static void sp_toggle_pick_no_overlap( GtkToggleAction* act, gpointer data ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - gboolean active = gtk_toggle_action_get_active(act); - prefs->setBool("/tools/spray/pick_no_overlap", active); -} - -static void sp_toggle_pick_inverse_value( GtkToggleAction* act, gpointer data ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - gboolean active = gtk_toggle_action_get_active(act); - prefs->setBool("/tools/spray/pick_inverse_value", active); -} - -void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) -{ - GtkIconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - { - /* Width */ - gchar const* labels[] = {_("(narrow spray)"), 0, 0, 0, _("(default)"), 0, 0, 0, 0, _("(broad spray)")}; - gdouble values[] = {1, 3, 5, 10, 15, 20, 30, 50, 75, 100}; - EgeAdjustmentAction *eact = create_adjustment_action( "SprayWidthAction", - _("Width"), _("Width:"), _("The width of the spray area (relative to the visible canvas area)"), - "/tools/spray/width", 15, - GTK_WIDGET(desktop->canvas), holder, true, "altx-spray", - 1, 100, 1.0, 10.0, - labels, values, G_N_ELEMENTS(labels), - sp_spray_width_value_changed, NULL /*unit tracker*/, 1, 0 ); - ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), true ); - } - - /* Use Pressure Width button */ - { - InkToggleAction* act = ink_toggle_action_new( "SprayPressureWidthAction", - _("Pressure"), - _("Use the pressure of the input device to alter the width of spray area"), - INKSCAPE_ICON("draw-use-pressure"), - GTK_ICON_SIZE_MENU ); - gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); - PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(act), "/tools/spray/usepressurewidth"); - g_signal_connect(holder, "destroy", G_CALLBACK(delete_prefspusher), pusher); - - } - - { - /* Mean */ - gchar const* labels[] = {_("(default)"), 0, 0, 0, 0, 0, 0, _("(maximum mean)")}; - gdouble values[] = {0, 5, 10, 20, 30, 50, 70, 100}; - EgeAdjustmentAction *eact = create_adjustment_action( "SprayMeanAction", - _("Focus"), _("Focus:"), _("0 to spray a spot; increase to enlarge the ring radius"), - "/tools/spray/mean", 0, - GTK_WIDGET(desktop->canvas), holder, true, "spray-mean", - 0, 100, 1.0, 10.0, - labels, values, G_N_ELEMENTS(labels), - sp_spray_mean_value_changed, NULL /*unit tracker*/, 1, 0 ); - ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), true ); - } - - { - /* Standard_deviation */ - gchar const* labels[] = {_("(minimum scatter)"), 0, 0, 0, 0, 0, _("(default)"), _("(maximum scatter)")}; - gdouble values[] = {1, 5, 10, 20, 30, 50, 70, 100}; - EgeAdjustmentAction *eact = create_adjustment_action( "SprayStandard_deviationAction", - C_("Spray tool", "Scatter"), C_("Spray tool", "Scatter:"), _("Increase to scatter sprayed objects"), - "/tools/spray/standard_deviation", 70, - GTK_WIDGET(desktop->canvas), holder, true, "spray-standard_deviation", - 1, 100, 1.0, 10.0, - labels, values, G_N_ELEMENTS(labels), - sp_spray_standard_deviation_value_changed, NULL /*unit tracker*/, 1, 0 ); - ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), true ); - } - - /* Mode */ - { - InkSelectOneActionColumns columns; - - Glib::RefPtr store = Gtk::ListStore::create(columns); - - Gtk::TreeModel::Row row; - - row = *(store->append()); - row[columns.col_label ] = _("Spray with copies"); - row[columns.col_tooltip ] = _("Spray copies of the initial selection"); - row[columns.col_icon ] = INKSCAPE_ICON("spray-mode-copy"); - row[columns.col_sensitive] = true; - - row = *(store->append()); - row[columns.col_label ] = _("Spray with clones"); - row[columns.col_tooltip ] = _("Spray clones of the initial selection"); - row[columns.col_icon ] = INKSCAPE_ICON("spray-mode-clone"); - row[columns.col_sensitive] = true; - -#ifdef ENABLE_SPRAY_MODE_SINGLE_PATH - row = *(store->append()); - row[columns.col_label ] = _("Spray single path"); - row[columns.col_tooltip ] = _("Spray objects in a single path"); - row[columns.col_icon ] = INKSCAPE_ICON("spray-mode-union"); - row[columns.col_sensitive] = true; -#endif - - row = *(store->append()); - row[columns.col_label ] = _("Delete sprayed items"); - row[columns.col_tooltip ] = _("Delete sprayed items from selection"); - row[columns.col_icon ] = INKSCAPE_ICON("draw-eraser"); - row[columns.col_sensitive] = true; - - InkSelectOneAction* act = - InkSelectOneAction::create( "SprayModeAction", // Name - _("Mode"), // Label - "", // Tooltip - "Not Used", // Icon - store ); // Tree store - - act->use_radio( true ); - act->use_group_label( true ); - gint mode = prefs->getInt("/tools/spray/mode", 1); - act->set_active( mode ); - - gtk_action_group_add_action( mainActions, GTK_ACTION( act->gobj() )); - g_object_set_data( holder, "spray_tool_mode", act ); - - act->signal_changed().connect(sigc::bind<0>(sigc::ptr_fun(&sp_spray_mode_changed), holder)); - } - - { /* Population */ - gchar const* labels[] = {_("(low population)"), 0, 0, 0, _("(default)"), 0, _("(high population)")}; - gdouble values[] = {5, 20, 35, 50, 70, 85, 100}; - EgeAdjustmentAction *eact = create_adjustment_action( "SprayPopulationAction", - _("Amount"), _("Amount:"), - _("Adjusts the number of items sprayed per click"), - "/tools/spray/population", 70, - GTK_WIDGET(desktop->canvas), holder, true, "spray-population", - 1, 100, 1.0, 10.0, - labels, values, G_N_ELEMENTS(labels), - sp_spray_population_value_changed, NULL /*unit tracker*/, 1, 0 ); - ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), true ); - g_object_set_data( holder, "spray_population", eact ); - } - - /* Use Pressure Population button */ - { - InkToggleAction* act = ink_toggle_action_new( "SprayPressurePopulationAction", - _("Pressure"), - _("Use the pressure of the input device to alter the amount of sprayed objects"), - INKSCAPE_ICON("draw-use-pressure"), - GTK_ICON_SIZE_MENU ); - gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); - PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(act), "/tools/spray/usepressurepopulation"); - g_signal_connect(holder, "destroy", G_CALLBACK(delete_prefspusher), pusher); - - } - - { /* Rotation */ - gchar const* labels[] = {_("(default)"), 0, 0, 0, 0, 0, 0, _("(high rotation variation)")}; - gdouble values[] = {0, 10, 25, 35, 50, 60, 80, 100}; - EgeAdjustmentAction *eact = create_adjustment_action( "SprayRotationAction", - _("Rotation"), _("Rotation:"), - // xgettext:no-c-format - _("Variation of the rotation of the sprayed objects; 0% for the same rotation than the original object"), - "/tools/spray/rotation_variation", 0, - GTK_WIDGET(desktop->canvas), holder, true, "spray-rotation", - 0, 100, 1.0, 10.0, - labels, values, G_N_ELEMENTS(labels), - sp_spray_rotation_value_changed, NULL /*unit tracker*/, 1, 0 ); - ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), true ); - g_object_set_data( holder, "spray_rotation", eact ); - } - - { /* Scale */ - gchar const* labels[] = {_("(default)"), 0, 0, 0, 0, 0, 0, _("(high scale variation)")}; - gdouble values[] = {0, 10, 25, 35, 50, 60, 80, 100}; - EgeAdjustmentAction *eact = create_adjustment_action( "SprayScaleAction", - C_("Spray tool", "Scale"), C_("Spray tool", "Scale:"), - // xgettext:no-c-format - _("Variation in the scale of the sprayed objects; 0% for the same scale than the original object"), - "/tools/spray/scale_variation", 0, - GTK_WIDGET(desktop->canvas), holder, true, "spray-scale", - 0, 100, 1.0, 10.0, - labels, values, G_N_ELEMENTS(labels), - sp_spray_scale_value_changed, NULL /*unit tracker*/, 1, 0 ); - ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), true ); - g_object_set_data( holder, "spray_scale", eact ); - } - - /* Use Pressure Scale button */ - { - InkToggleAction* act = ink_toggle_action_new( "SprayPressureScaleAction", - _("Pressure"), - _("Use the pressure of the input device to alter the scale of new items"), - INKSCAPE_ICON("draw-use-pressure"), - GTK_ICON_SIZE_MENU); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/usepressurescale", false) ); - g_object_set_data( holder, "usepressurescale", act ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_pressure_scale), holder) ; - gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); - } - - /* Picker */ - { - InkToggleAction* act = ink_toggle_action_new( "SprayPickColorAction", - _("Pick color from the drawing. You can use clonetiler trace dialog for advanced effects. In clone mode original fill or stroke colors must be unset."), - _("Pick color from the drawing. You can use clonetiler trace dialog for advanced effects. In clone mode original fill or stroke colors must be unset."), - INKSCAPE_ICON("color-picker"), - secondarySize ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/picker", false) ); - g_object_set_data( holder, "picker", act ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_picker), holder) ; - gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); - } - - /* Pick from center */ - { - InkToggleAction* act = ink_toggle_action_new( "SprayPickCenterAction", - _("Pick from center instead average area."), - _("Pick from center instead average area."), - INKSCAPE_ICON("snap-bounding-box-center"), - secondarySize ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/pick_center", true) ); - g_object_set_data( holder, "pick_center", act ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_pick_center), holder) ; - gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); - } - - /* Inverse Value Size */ - { - InkToggleAction* act = ink_toggle_action_new( "SprayPickInverseValueAction", - _("Inverted pick value, retaining color in advanced trace mode"), - _("Inverted pick value, retaining color in advanced trace mode"), - INKSCAPE_ICON("object-tweak-shrink"), - secondarySize ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/pick_inverse_value", false) ); - g_object_set_data( holder, "pick_inverse_value", act ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_pick_inverse_value), holder) ; - gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); - } - - /* Pick Fill */ - { - InkToggleAction* act = ink_toggle_action_new( "SprayPickFillAction", - _("Apply picked color to fill"), - _("Apply picked color to fill"), - INKSCAPE_ICON("paint-solid"), - secondarySize ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/pick_fill", false) ); - g_object_set_data( holder, "pick_fill", act ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_pick_fill), holder) ; - gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); - } - - /* Pick Stroke */ - { - InkToggleAction* act = ink_toggle_action_new( "SprayPickStrokeAction", - _("Apply picked color to stroke"), - _("Apply picked color to stroke"), - INKSCAPE_ICON("no-marker"), - secondarySize ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/pick_stroke", false) ); - g_object_set_data( holder, "pick_stroke", act ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_pick_stroke), holder) ; - gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); - } - - /* Pick No Overlap */ - { - InkToggleAction* act = ink_toggle_action_new( "SprayPickNoOverlapAction", - _("No overlap between colors"), - _("No overlap between colors"), - INKSCAPE_ICON("symbol-bigger"), - secondarySize ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/pick_no_overlap", false) ); - g_object_set_data( holder, "pick_no_overlap", act ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_pick_no_overlap), holder) ; - gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); - } - - /* Over Transparent */ - { - InkToggleAction* act = ink_toggle_action_new( "SprayOverTransparentAction", - _("Apply over transparent areas"), - _("Apply over transparent areas"), - INKSCAPE_ICON("object-hidden"), - secondarySize ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/over_transparent", true) ); - g_object_set_data( holder, "over_transparent", act ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_over_transparent), holder) ; - gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); - } - - /* Over No Transparent */ - { - InkToggleAction* act = ink_toggle_action_new( "SprayOverNoTransparentAction", - _("Apply over no transparent areas"), - _("Apply over no transparent areas"), - INKSCAPE_ICON("object-visible"), - secondarySize ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/over_no_transparent", true) ); - g_object_set_data( holder, "over_no_transparent", act ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_over_no_transparent), holder) ; - gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); - } - - /* Overlap */ - { - InkToggleAction* act = ink_toggle_action_new( "SprayNoOverlapAction", - _("Prevent overlapping objects"), - _("Prevent overlapping objects"), - INKSCAPE_ICON("distribute-randomize"), - secondarySize ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/no_overlap", false) ); - g_object_set_data( holder, "no_overlap", act ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_toggle_no_overlap), holder) ; - gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); - } - - /* Offset */ - { - gchar const* labels[] = {_("(minimum offset)"), 0, 0, 0, _("(default)"), 0, 0, _("(maximum offset)")}; - gdouble values[] = {0, 25, 50, 75, 100, 150, 200, 1000}; - EgeAdjustmentAction *eact = create_adjustment_action( "SprayToolOffsetAction", - _("Offset %"), _("Offset %:"), - _("Increase to segregate objects more (value in percent)"), - "/tools/spray/offset", 100, - GTK_WIDGET(desktop->canvas), holder, FALSE, NULL, - 0, 1000, 1, 4, - labels, values, G_N_ELEMENTS(labels), - sp_spray_offset_value_changed, NULL, 0 , 0); - g_object_set_data( holder, "offset", eact ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - } - sp_spray_init(holder); -} - - - -/* - 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:fileencoding=utf-8:textwidth=99 : diff --git a/src/widgets/spray-toolbar.h b/src/widgets/spray-toolbar.h deleted file mode 100644 index 30d8233ca..000000000 --- a/src/widgets/spray-toolbar.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef SEEN_SPRAY_TOOLBAR_H -#define SEEN_SPRAY_TOOLBAR_H - -/** - * @file - * Spray aux toolbar - */ -/* Authors: - * MenTaLguY - * Lauris Kaplinski - * bulia byak - * Frank Felfe - * John Cliff - * David Turner - * Josh Andler - * Jon A. Cruz - * Maximilian Albert - * Tavmjong Bah - * Abhishek Sharma - * Kris De Gussem - * - * Copyright (C) 2004 David Turner - * Copyright (C) 2003 MenTaLguY - * Copyright (C) 1999-2015 authors - * Copyright (C) 2001-2002 Ximian, Inc. - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -class SPDesktop; - -typedef struct _GtkActionGroup GtkActionGroup; -typedef struct _GObject GObject; - -void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); - -#endif /* !SEEN_SELECT_TOOLBAR_H */ diff --git a/src/widgets/star-toolbar.cpp b/src/widgets/star-toolbar.cpp deleted file mode 100644 index 7a8a4da2e..000000000 --- a/src/widgets/star-toolbar.cpp +++ /dev/null @@ -1,627 +0,0 @@ -/** - * @file - * Star aux toolbar - */ -/* Authors: - * MenTaLguY - * Lauris Kaplinski - * bulia byak - * Frank Felfe - * John Cliff - * David Turner - * Josh Andler - * Jon A. Cruz - * Maximilian Albert - * Tavmjong Bah - * Abhishek Sharma - * Kris De Gussem - * - * Copyright (C) 2004 David Turner - * Copyright (C) 2003 MenTaLguY - * Copyright (C) 1999-2011 authors - * Copyright (C) 2001-2002 Ximian, Inc. - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include - -#include "star-toolbar.h" - -#include "desktop.h" -#include "document-undo.h" -#include "ink-action.h" -#include "ink-radio-action.h" -#include "selection.h" -#include "toolbox.h" -#include "verbs.h" - -#include "object/sp-star.h" - -#include "ui/icon-names.h" -#include "ui/tools/star-tool.h" -#include "ui/uxmanager.h" -#include "ui/widget/ink-select-one-action.h" - -#include "widgets/ege-adjustment-action.h" -#include "widgets/ege-output-action.h" - -#include "xml/node-event-vector.h" - -using Inkscape::UI::UXManager; -using Inkscape::DocumentUndo; -using Inkscape::UI::ToolboxFactory; -using Inkscape::UI::PrefPusher; - - -//######################## -//## Star ## -//######################## - -static void sp_star_magnitude_value_changed( GtkAdjustment *adj, GObject *dataKludge ) -{ - SPDesktop *desktop = static_cast(g_object_get_data( dataKludge, "desktop" )); - - if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { - // do not remember prefs if this call is initiated by an undo change, because undoing object - // creation sets bogus values to its attributes before it is deleted - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setInt("/tools/shapes/star/magnitude", - (gint)gtk_adjustment_get_value(adj)); - } - - // quit if run by the attr_changed listener - if (g_object_get_data( dataKludge, "freeze" )) { - return; - } - - // in turn, prevent listener from responding - g_object_set_data( dataKludge, "freeze", GINT_TO_POINTER(TRUE) ); - - bool modmade = false; - - Inkscape::Selection *selection = desktop->getSelection(); - auto itemlist= selection->items(); - for(auto i=itemlist.begin();i!=itemlist.end();++i){ - SPItem *item = *i; - if (SP_IS_STAR(item)) { - Inkscape::XML::Node *repr = item->getRepr(); - sp_repr_set_int(repr,"sodipodi:sides", - (gint)gtk_adjustment_get_value(adj)); - double arg1 = 0.5; - sp_repr_get_double(repr, "sodipodi:arg1", &arg1); - sp_repr_set_svg_double(repr, "sodipodi:arg2", - (arg1 + M_PI / (gint)gtk_adjustment_get_value(adj))); - item->updateRepr(); - modmade = true; - } - } - if (modmade) { - DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_STAR, - _("Star: Change number of corners")); - } - - g_object_set_data( dataKludge, "freeze", GINT_TO_POINTER(FALSE) ); -} - -static void sp_star_proportion_value_changed( GtkAdjustment *adj, GObject *dataKludge ) -{ - SPDesktop *desktop = static_cast(g_object_get_data( dataKludge, "desktop" )); - - if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { - if (!IS_NAN(gtk_adjustment_get_value(adj))) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble("/tools/shapes/star/proportion", - gtk_adjustment_get_value(adj)); - } - } - - // quit if run by the attr_changed listener - if (g_object_get_data( dataKludge, "freeze" )) { - return; - } - - // in turn, prevent listener from responding - g_object_set_data( dataKludge, "freeze", GINT_TO_POINTER(TRUE) ); - - bool modmade = false; - Inkscape::Selection *selection = desktop->getSelection(); - auto itemlist= selection->items(); - for(auto i=itemlist.begin();i!=itemlist.end();++i){ - SPItem *item = *i; - if (SP_IS_STAR(item)) { - Inkscape::XML::Node *repr = item->getRepr(); - - gdouble r1 = 1.0; - gdouble r2 = 1.0; - sp_repr_get_double(repr, "sodipodi:r1", &r1); - sp_repr_get_double(repr, "sodipodi:r2", &r2); - if (r2 < r1) { - sp_repr_set_svg_double(repr, "sodipodi:r2", - r1*gtk_adjustment_get_value(adj)); - } else { - sp_repr_set_svg_double(repr, "sodipodi:r1", - r2*gtk_adjustment_get_value(adj)); - } - - item->updateRepr(); - modmade = true; - } - } - - if (modmade) { - DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_STAR, - _("Star: Change spoke ratio")); - } - - g_object_set_data( dataKludge, "freeze", GINT_TO_POINTER(FALSE) ); -} - -static void sp_star_side_mode_changed( GObject *dataKludge, int mode ) -{ - bool flat = (mode == 0); - - SPDesktop *desktop = static_cast(g_object_get_data( dataKludge, "desktop" )); - - if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setBool( "/tools/shapes/star/isflatsided", flat ); - } - - // quit if run by the attr_changed listener - if (g_object_get_data( dataKludge, "freeze" )) { - return; - } - - // in turn, prevent listener from responding - g_object_set_data( dataKludge, "freeze", GINT_TO_POINTER(TRUE) ); - - Inkscape::Selection *selection = desktop->getSelection(); - GtkAction* prop_action = GTK_ACTION( g_object_get_data( dataKludge, "prop_action" ) ); - bool modmade = false; - - if ( prop_action ) { - gtk_action_set_visible( prop_action, !flat ); - } - - auto itemlist= selection->items(); - for(auto i=itemlist.begin();i!=itemlist.end();++i){ - SPItem *item = *i; - if (SP_IS_STAR(item)) { - Inkscape::XML::Node *repr = item->getRepr(); - repr->setAttribute("inkscape:flatsided", flat ? "true" : "false" ); - item->updateRepr(); - modmade = true; - } - } - - if (modmade) { - DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_STAR, - flat ? _("Make polygon") : _("Make star")); - } - - g_object_set_data( dataKludge, "freeze", GINT_TO_POINTER(FALSE) ); -} - -static void sp_star_rounded_value_changed( GtkAdjustment *adj, GObject *dataKludge ) -{ - SPDesktop *desktop = static_cast(g_object_get_data( dataKludge, "desktop" )); - - if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble("/tools/shapes/star/rounded", (gdouble) gtk_adjustment_get_value(adj)); - } - - // quit if run by the attr_changed listener - if (g_object_get_data( dataKludge, "freeze" )) { - return; - } - - // in turn, prevent listener from responding - g_object_set_data( dataKludge, "freeze", GINT_TO_POINTER(TRUE) ); - - bool modmade = false; - - Inkscape::Selection *selection = desktop->getSelection(); - auto itemlist= selection->items(); - for(auto i=itemlist.begin();i!=itemlist.end();++i){ - SPItem *item = *i; - if (SP_IS_STAR(item)) { - Inkscape::XML::Node *repr = item->getRepr(); - sp_repr_set_svg_double(repr, "inkscape:rounded", - (gdouble) gtk_adjustment_get_value(adj)); - item->updateRepr(); - modmade = true; - } - } - if (modmade) { - DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_STAR, - _("Star: Change rounding")); - } - - g_object_set_data( dataKludge, "freeze", GINT_TO_POINTER(FALSE) ); -} - -static void sp_star_randomized_value_changed( GtkAdjustment *adj, GObject *dataKludge ) -{ - SPDesktop *desktop = static_cast(g_object_get_data( dataKludge, "desktop" )); - - if (DocumentUndo::getUndoSensitive(desktop->getDocument())) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble("/tools/shapes/star/randomized", - (gdouble) gtk_adjustment_get_value(adj)); - } - - // quit if run by the attr_changed listener - if (g_object_get_data( dataKludge, "freeze" )) { - return; - } - - // in turn, prevent listener from responding - g_object_set_data( dataKludge, "freeze", GINT_TO_POINTER(TRUE) ); - - bool modmade = false; - - Inkscape::Selection *selection = desktop->getSelection(); - auto itemlist= selection->items(); - for(auto i=itemlist.begin();i!=itemlist.end();++i){ - SPItem *item = *i; - if (SP_IS_STAR(item)) { - Inkscape::XML::Node *repr = item->getRepr(); - sp_repr_set_svg_double(repr, "inkscape:randomized", - (gdouble) gtk_adjustment_get_value(adj)); - item->updateRepr(); - modmade = true; - } - } - if (modmade) { - DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_STAR, - _("Star: Change randomization")); - } - - g_object_set_data( dataKludge, "freeze", GINT_TO_POINTER(FALSE) ); -} - - -static void star_tb_event_attr_changed(Inkscape::XML::Node *repr, gchar const *name, - gchar const * /*old_value*/, gchar const * /*new_value*/, - bool /*is_interactive*/, gpointer dataPointer) -{ - GObject *dataKludge = G_OBJECT( dataPointer ); - - // quit if run by the _changed callbacks - if (g_object_get_data(dataKludge, "freeze")) { - return; - } - - // in turn, prevent callbacks from responding - g_object_set_data(dataKludge, "freeze", GINT_TO_POINTER(TRUE)); - - GtkAdjustment *adj = 0; - - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - bool isFlatSided = prefs->getBool("/tools/shapes/star/isflatsided", true); - - if (!strcmp(name, "inkscape:randomized")) { - - adj = GTK_ADJUSTMENT( g_object_get_data(dataKludge, "randomized") ); - double randomized = 0.0; - sp_repr_get_double(repr, "inkscape:randomized", &randomized); - gtk_adjustment_set_value(adj, randomized); - - } else if (!strcmp(name, "inkscape:rounded")) { - - adj = GTK_ADJUSTMENT( g_object_get_data(dataKludge, "rounded") ); - double rounded = 0.0; - sp_repr_get_double(repr, "inkscape:rounded", &rounded); - gtk_adjustment_set_value(adj, rounded); - - } else if (!strcmp(name, "inkscape:flatsided")) { - - GtkAction* prop_action = GTK_ACTION( g_object_get_data(dataKludge, "prop_action") ); - char const *flatsides = repr->attribute("inkscape:flatsided"); - - InkSelectOneAction* flat_action = - static_cast(g_object_get_data( dataKludge, "flat_action" ) ); - if ( flatsides && !strcmp(flatsides,"false") ) { - flat_action->set_active(1); - gtk_action_set_visible( prop_action, TRUE ); - } else { - flat_action->set_active(0); - gtk_action_set_visible( prop_action, FALSE ); - } - - } else if ((!strcmp(name, "sodipodi:r1") || !strcmp(name, "sodipodi:r2")) && (!isFlatSided) ) { - - adj = GTK_ADJUSTMENT(g_object_get_data(dataKludge, "proportion")); - gdouble r1 = 1.0; - gdouble r2 = 1.0; - sp_repr_get_double(repr, "sodipodi:r1", &r1); - sp_repr_get_double(repr, "sodipodi:r2", &r2); - if (r2 < r1) { - gtk_adjustment_set_value(adj, r2/r1); - } else { - gtk_adjustment_set_value(adj, r1/r2); - } - - } else if (!strcmp(name, "sodipodi:sides")) { - - adj = GTK_ADJUSTMENT(g_object_get_data(dataKludge, "magnitude")); - int sides = 0; - sp_repr_get_int(repr, "sodipodi:sides", &sides); - gtk_adjustment_set_value(adj, sides); - } - - g_object_set_data(dataKludge, "freeze", GINT_TO_POINTER(FALSE)); -} - - -static Inkscape::XML::NodeEventVector star_tb_repr_events = -{ - NULL, /* child_added */ - NULL, /* child_removed */ - star_tb_event_attr_changed, - NULL, /* content_changed */ - NULL /* order_changed */ -}; - - -/** - * \param selection Should not be NULL. - */ -static void -sp_star_toolbox_selection_changed(Inkscape::Selection *selection, GObject *dataKludge) -{ - int n_selected = 0; - Inkscape::XML::Node *repr = NULL; - - purge_repr_listener( dataKludge, dataKludge ); - - auto itemlist= selection->items(); - for(auto i=itemlist.begin();i!=itemlist.end();++i){ - SPItem *item = *i; - if (SP_IS_STAR(item)) { - n_selected++; - repr = item->getRepr(); - } - } - - EgeOutputAction* act = EGE_OUTPUT_ACTION( g_object_get_data( dataKludge, "mode_action" ) ); - - if (n_selected == 0) { - g_object_set( G_OBJECT(act), "label", _("New:"), NULL ); - } else if (n_selected == 1) { - g_object_set( G_OBJECT(act), "label", _("Change:"), NULL ); - - if (repr) { - g_object_set_data( dataKludge, "repr", repr ); - Inkscape::GC::anchor(repr); - sp_repr_add_listener(repr, &star_tb_repr_events, dataKludge); - sp_repr_synthesize_events(repr, &star_tb_repr_events, dataKludge); - } - } else { - // FIXME: implement averaging of all parameters for multiple selected stars - //gtk_label_set_markup(GTK_LABEL(l), _("Average:")); - //gtk_label_set_markup(GTK_LABEL(l), _("Change:")); - } -} - - -static void sp_star_defaults( GtkWidget * /*widget*/, GObject *dataKludge ) -{ - // FIXME: in this and all other _default functions, set some flag telling the value_changed - // callbacks to lump all the changes for all selected objects in one undo step - - GtkAdjustment *adj = 0; - - // fixme: make settable in prefs! - gint mag = 5; - gdouble prop = 0.5; - gboolean flat = FALSE; - gdouble randomized = 0; - gdouble rounded = 0; - - InkSelectOneAction* flat_action = - static_cast(g_object_get_data( dataKludge, "flat_action" ) ); - flat_action->set_active ( flat ? 0 : 1 ); - - GtkAction* sb2 = GTK_ACTION( g_object_get_data( dataKludge, "prop_action" ) ); - gtk_action_set_visible( sb2, !flat ); - - adj = GTK_ADJUSTMENT( g_object_get_data( dataKludge, "magnitude" ) ); - gtk_adjustment_set_value(adj, mag); - -#if !GTK_CHECK_VERSION(3,18,0) - gtk_adjustment_value_changed(adj); -#endif - - adj = GTK_ADJUSTMENT( g_object_get_data( dataKludge, "proportion" ) ); - gtk_adjustment_set_value(adj, prop); - -#if !GTK_CHECK_VERSION(3,18,0) - gtk_adjustment_value_changed(adj); -#endif - - adj = GTK_ADJUSTMENT( g_object_get_data( dataKludge, "rounded" ) ); - gtk_adjustment_set_value(adj, rounded); - -#if !GTK_CHECK_VERSION(3,18,0) - gtk_adjustment_value_changed(adj); -#endif - - adj = GTK_ADJUSTMENT( g_object_get_data( dataKludge, "randomized" ) ); - gtk_adjustment_set_value(adj, randomized); - -#if !GTK_CHECK_VERSION(3,18,0) - gtk_adjustment_value_changed(adj); -#endif -} - -static void star_toolbox_watch_ec(SPDesktop* dt, Inkscape::UI::Tools::ToolBase* ec, GObject* dataKludge); - -void sp_star_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* dataKludge) -{ - GtkIconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1); - - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - bool isFlatSided = prefs->getBool("/tools/shapes/star/isflatsided", true); - - EgeAdjustmentAction* eact = 0; - - { - EgeOutputAction* act = ege_output_action_new( "StarStateAction", _("New:"), "", 0 ); - ege_output_action_set_use_markup( act, TRUE ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - g_object_set_data( dataKludge, "mode_action", act ); - } - - /* Flatsided checkbox */ - { - InkSelectOneActionColumns columns; - - Glib::RefPtr store = Gtk::ListStore::create(columns); - - Gtk::TreeModel::Row row; - - row = *(store->append()); - row[columns.col_label ] = _("Polygon"); - row[columns.col_tooltip ] = _("Regular polygon (with one handle) instead of a star"); - row[columns.col_icon ] = INKSCAPE_ICON("draw-polygon"); - row[columns.col_sensitive] = true; - - row = *(store->append()); - row[columns.col_label ] = _("Star"); - row[columns.col_tooltip ] = _("Star instead of a regular polygon (with one handle)"); - row[columns.col_icon ] = INKSCAPE_ICON("draw-star"); - row[columns.col_sensitive] = true; - - InkSelectOneAction* act = - InkSelectOneAction::create( "FlatAction", // Name - (""), // Label - (""), // Tooltip - "Not Used", // Icon - store ); // Tree store - act->use_radio( true ); - act->use_label( false ); - act->set_active( isFlatSided ? 0 : 1 ); - - gtk_action_group_add_action( mainActions, GTK_ACTION( act->gobj() )); - g_object_set_data( dataKludge, "flat_action", act ); - - act->signal_changed().connect(sigc::bind<0>(sigc::ptr_fun(&sp_star_side_mode_changed), dataKludge)); - } - - /* Magnitude */ - { - gchar const* labels[] = {_("triangle/tri-star"), _("square/quad-star"), _("pentagon/five-pointed star"), _("hexagon/six-pointed star"), 0, 0, 0, 0, 0}; - gdouble values[] = {3, 4, 5, 6, 7, 8, 10, 12, 20}; - eact = create_adjustment_action( "MagnitudeAction", - _("Corners"), _("Corners:"), _("Number of corners of a polygon or star"), - "/tools/shapes/star/magnitude", 3, - GTK_WIDGET(desktop->canvas), dataKludge, FALSE, NULL, - 3, 1024, 1, 5, - labels, values, G_N_ELEMENTS(labels), - sp_star_magnitude_value_changed, NULL /*unit tracker*/, - 1.0, 0 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - } - - /* Spoke ratio */ - { - gchar const* labels[] = {_("thin-ray star"), 0, _("pentagram"), _("hexagram"), _("heptagram"), _("octagram"), _("regular polygon")}; - gdouble values[] = {0.01, 0.2, 0.382, 0.577, 0.692, 0.765, 1}; - eact = create_adjustment_action( "SpokeAction", - _("Spoke ratio"), _("Spoke ratio:"), - // TRANSLATORS: Tip radius of a star is the distance from the center to the farthest handle. - // Base radius is the same for the closest handle. - _("Base radius to tip radius ratio"), - "/tools/shapes/star/proportion", 0.5, - GTK_WIDGET(desktop->canvas), dataKludge, FALSE, NULL, - 0.01, 1.0, 0.01, 0.1, - labels, values, G_N_ELEMENTS(labels), - sp_star_proportion_value_changed ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - g_object_set_data( dataKludge, "prop_action", eact ); - - if ( !isFlatSided ) { - gtk_action_set_visible( GTK_ACTION(eact), TRUE ); - } else { - gtk_action_set_visible( GTK_ACTION(eact), FALSE ); - } - } - - /* Roundedness */ - { - gchar const* labels[] = {_("stretched"), _("twisted"), _("slightly pinched"), _("NOT rounded"), _("slightly rounded"), - _("visibly rounded"), _("well rounded"), _("amply rounded"), 0, _("stretched"), _("blown up")}; - gdouble values[] = {-1, -0.2, -0.03, 0, 0.05, 0.1, 0.2, 0.3, 0.5, 1, 10}; - eact = create_adjustment_action( "RoundednessAction", - _("Rounded"), _("Rounded:"), _("How much rounded are the corners (0 for sharp)"), - "/tools/shapes/star/rounded", 0.0, - GTK_WIDGET(desktop->canvas), dataKludge, FALSE, NULL, - -10.0, 10.0, 0.01, 0.1, - labels, values, G_N_ELEMENTS(labels), - sp_star_rounded_value_changed ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - } - - /* Randomization */ - { - gchar const* labels[] = {_("NOT randomized"), _("slightly irregular"), _("visibly randomized"), _("strongly randomized"), _("blown up")}; - gdouble values[] = {0, 0.01, 0.1, 0.5, 10}; - eact = create_adjustment_action( "RandomizationAction", - _("Randomized"), _("Randomized:"), _("Scatter randomly the corners and angles"), - "/tools/shapes/star/randomized", 0.0, - GTK_WIDGET(desktop->canvas), dataKludge, FALSE, NULL, - -10.0, 10.0, 0.001, 0.01, - labels, values, G_N_ELEMENTS(labels), - sp_star_randomized_value_changed, NULL /*unit tracker*/, 0.1, 3 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - } - - /* Reset */ - { - InkAction* inky = ink_action_new( "StarResetAction", - _("Defaults"), - _("Reset shape parameters to defaults (use Inkscape Preferences > Tools to change defaults)"), - INKSCAPE_ICON("edit-clear"), - GTK_ICON_SIZE_SMALL_TOOLBAR); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_star_defaults), dataKludge ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - gtk_action_set_sensitive( GTK_ACTION(inky), TRUE ); - } - - desktop->connectEventContextChanged(sigc::bind(sigc::ptr_fun(star_toolbox_watch_ec), dataKludge)); - g_signal_connect(dataKludge, "destroy", G_CALLBACK(purge_repr_listener), dataKludge); -} - -static void star_toolbox_watch_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolBase* ec, GObject* dataKludge) -{ - static sigc::connection changed; - - if (dynamic_cast(ec) != NULL) { - changed = desktop->getSelection()->connectChanged(sigc::bind(sigc::ptr_fun(sp_star_toolbox_selection_changed), dataKludge)); - sp_star_toolbox_selection_changed(desktop->getSelection(), dataKludge); - } else { - if (changed) - changed.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:fileencoding=utf-8 : diff --git a/src/widgets/star-toolbar.h b/src/widgets/star-toolbar.h deleted file mode 100644 index aa0db785c..000000000 --- a/src/widgets/star-toolbar.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef SEEN_STAR_TOOLBAR_H -#define SEEN_STAR_TOOLBAR_H - -/** - * @file - * Star aux toolbar - */ -/* Authors: - * MenTaLguY - * Lauris Kaplinski - * bulia byak - * Frank Felfe - * John Cliff - * David Turner - * Josh Andler - * Jon A. Cruz - * Maximilian Albert - * Tavmjong Bah - * Abhishek Sharma - * Kris De Gussem - * - * Copyright (C) 2004 David Turner - * Copyright (C) 2003 MenTaLguY - * Copyright (C) 1999-2011 authors - * Copyright (C) 2001-2002 Ximian, Inc. - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -class SPDesktop; - -typedef struct _GtkActionGroup GtkActionGroup; -typedef struct _GObject GObject; - -void sp_star_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); - -#endif /* !SEEN_SELECT_TOOLBAR_H */ diff --git a/src/widgets/text-toolbar.cpp b/src/widgets/text-toolbar.cpp deleted file mode 100644 index bbb457472..000000000 --- a/src/widgets/text-toolbar.cpp +++ /dev/null @@ -1,2604 +0,0 @@ -/** - * @file - * Text aux toolbar - */ -/* Authors: - * MenTaLguY - * Lauris Kaplinski - * bulia byak - * Frank Felfe - * John Cliff - * David Turner - * Josh Andler - * Jon A. Cruz - * Maximilian Albert - * Tavmjong Bah - * Abhishek Sharma - * Kris De Gussem - * Tavmjong Bah - * - * Copyright (C) 2004 David Turner - * Copyright (C) 2003 MenTaLguY - * Copyright (C) 2001-2002 Ximian, Inc. - * Copyright (C) 1999-2013 authors - * Copyright (C) 2017 Tavmjong Bah - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include - -#include "text-toolbar.h" - -#include "desktop-style.h" -#include "desktop.h" -#include "document-undo.h" -#include "document.h" -#include "ink-radio-action.h" -#include "ink-toggle-action.h" -#include "inkscape.h" -#include "selection-chemistry.h" -#include "text-editing.h" -#include "toolbox.h" -#include "verbs.h" - -#include "libnrtype/font-lister.h" - -#include "object/sp-flowdiv.h" -#include "object/sp-flowtext.h" -#include "object/sp-root.h" -#include "object/sp-text.h" -#include "object/sp-tspan.h" -#include "style.h" - -#include "svg/css-ostringstream.h" - -#include "ui/icon-names.h" -#include "ui/tools/text-tool.h" -#include "ui/widget/ink-select-one-action.h" -#include "ui/widget/unit-tracker.h" - -#include "widgets/ege-adjustment-action.h" -#include "widgets/ink-comboboxentry-action.h" -#include "widgets/style-utils.h" - -using Inkscape::DocumentUndo; -using Inkscape::UI::ToolboxFactory; -using Inkscape::UI::PrefPusher; -using Inkscape::Util::Unit; -using Inkscape::Util::Quantity; -using Inkscape::Util::unit_table; -using Inkscape::UI::Widget::UnitTracker; - -//#define DEBUG_TEXT - -//######################## -//## Text Toolbox ## -//######################## - -// Functions for debugging: -#ifdef DEBUG_TEXT - -static void sp_print_font( SPStyle *query ) { - - bool family_set = query->font_family.set; - bool style_set = query->font_style.set; - bool fontspec_set = query->font_specification.set; - - std::cout << " Family set? " << family_set - << " Style set? " << style_set - << " FontSpec set? " << fontspec_set - << std::endl; - std::cout << " Family: " - << (query->font_family.value ? query->font_family.value : "No value") - << " Style: " << query->font_style.computed - << " Weight: " << query->font_weight.computed - << " FontSpec: " - << (query->font_specification.value ? query->font_specification.value : "No value") - << std::endl; - std::cout << " LineHeight: " << query->line_height.computed - << " WordSpacing: " << query->word_spacing.computed - << " LetterSpacing: " << query->letter_spacing.computed - << std::endl; -} - -static void sp_print_fontweight( SPStyle *query ) { - const gchar* names[] = {"100", "200", "300", "400", "500", "600", "700", "800", "900", - "NORMAL", "BOLD", "LIGHTER", "BOLDER", "Out of range"}; - // Missing book = 380 - int index = query->font_weight.computed; - if( index < 0 || index > 13 ) index = 13; - std::cout << " Weight: " << names[ index ] - << " (" << query->font_weight.computed << ")" << std::endl; - -} - -static void sp_print_fontstyle( SPStyle *query ) { - - const gchar* names[] = {"NORMAL", "ITALIC", "OBLIQUE", "Out of range"}; - int index = query->font_style.computed; - if( index < 0 || index > 3 ) index = 3; - std::cout << " Style: " << names[ index ] << std::endl; - -} -#endif - -static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/, GObject *tbl, bool subselection = false); - -// Font family -static void sp_text_fontfamily_value_changed( Ink_ComboBoxEntry_Action *act, GObject *tbl ) -{ -#ifdef DEBUG_TEXT - std::cout << std::endl; - std::cout << "MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" << std::endl; - std::cout << "sp_text_fontfamily_value_changed: " << std::endl; -#endif - - // quit if run by the _changed callbacks - if (g_object_get_data(G_OBJECT(tbl), "freeze")) { -#ifdef DEBUG_TEXT - std::cout << "sp_text_fontfamily_value_changed: frozen... return" << std::endl; - std::cout << "MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM\n" << std::endl; -#endif - return; - } - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - - Glib::ustring new_family = ink_comboboxentry_action_get_active_text( act ); - css_font_family_unquote( new_family ); // Remove quotes around font family names. - - // TODO: Think about how to handle handle multiple selections. While - // the font-family may be the same for all, the styles might be different. - // See: TextEdit::onApply() for example of looping over selected items. - Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance(); -#ifdef DEBUG_TEXT - std::cout << " Old family: " << fontlister->get_font_family() << std::endl; - std::cout << " New family: " << new_family << std::endl; - std::cout << " Old active: " << fontlister->get_font_family_row() << std::endl; - std::cout << " New active: " << act->active << std::endl; -#endif - if( new_family.compare( fontlister->get_font_family() ) != 0 ) { - // Changed font-family - - if( act->active == -1 ) { - // New font-family, not in document, not on system (could be fallback list) - fontlister->insert_font_family( new_family ); - act->active = 0; // New family is always at top of list. - } - - fontlister->set_font_family( act->active ); - // active text set in sp_text_toolbox_selection_changed() - - SPCSSAttr *css = sp_repr_css_attr_new (); - fontlister->fill_css( css ); - - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - if( desktop->getSelection()->isEmpty() ) { - // Update default - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->mergeStyle("/tools/text/style", css); - } else { - // If there is a selection, update - sp_desktop_set_style (desktop, css, true, true); // Results in selection change called twice. - DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_TEXT, - _("Text: Change font family")); - } - sp_repr_css_attr_unref (css); - } - - // unfreeze - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); - -#ifdef DEBUG_TEXT - std::cout << "sp_text_toolbox_fontfamily_changes: exit" << std::endl; - std::cout << "MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" << std::endl; - std::cout << std::endl; -#endif -} - -// Font size -static void sp_text_fontsize_value_changed( Ink_ComboBoxEntry_Action *act, GObject *tbl ) -{ - // quit if run by the _changed callbacks - if (g_object_get_data(G_OBJECT(tbl), "freeze")) { - return; - } - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - - gchar *text = ink_comboboxentry_action_get_active_text( act ); - gchar *endptr; - gdouble size = g_strtod( text, &endptr ); - if (endptr == text) { // Conversion failed, non-numeric input. - g_warning( "Conversion of size text to double failed, input: %s\n", text ); - g_free( text ); - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); - return; - } - g_free( text ); - - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - int max_size = prefs->getInt("/dialogs/textandfont/maxFontSize", 10000); // somewhat arbitrary, but text&font preview freezes with too huge fontsizes - - if (size > max_size) - size = max_size; - - // Set css font size. - SPCSSAttr *css = sp_repr_css_attr_new (); - Inkscape::CSSOStringStream osfs; - int unit = prefs->getInt("/options/font/unitType", SP_CSS_UNIT_PT); - if (prefs->getBool("/options/font/textOutputPx", true)) { - osfs << sp_style_css_size_units_to_px(size, unit) << sp_style_get_css_unit_string(SP_CSS_UNIT_PX); - } else { - osfs << size << sp_style_get_css_unit_string(unit); - } - sp_repr_css_set_property (css, "font-size", osfs.str().c_str()); - - // Apply font size to selected objects. - // Calling sp_desktop_set_style will result in a call to TextTool::_styleSet() which - // will set the style on selected text inside the element. If we want to set - // the style on the outer objects we need to bypass this call. - bool outer = prefs->getInt("/tools/text/outer_style", false); - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - if (outer) { - Inkscape::Selection *selection = desktop->getSelection(); - auto itemlist= selection->items(); - for(auto i=itemlist.begin();i!=itemlist.end(); ++i){ - if (dynamic_cast(*i) || dynamic_cast(*i)) { - SPItem *item = *i; - - // Scale by inverse of accumulated parent transform - SPCSSAttr *css_set = sp_repr_css_attr_new(); - sp_repr_css_merge(css_set, css); - Geom::Affine const local(item->i2doc_affine()); - double const ex(local.descrim()); - if ( (ex != 0.0) && (ex != 1.0) ) { - sp_css_attr_scale(css_set, 1/ex); - } - - item->changeCSS(css_set,"style"); - - sp_repr_css_attr_unref(css_set); - } - } - } else { - sp_desktop_set_style (desktop, css, true, true); - } - - // If no selected objects, set default. - SPStyle query(SP_ACTIVE_DOCUMENT); - int result_numbers = - sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS); - if (result_numbers == QUERY_STYLE_NOTHING) - { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->mergeStyle("/tools/text/style", css); - } else { - // Save for undo - DocumentUndo::maybeDone(SP_ACTIVE_DESKTOP->getDocument(), "ttb:size", SP_VERB_NONE, - _("Text: Change font size")); - } - - sp_repr_css_attr_unref (css); - - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -} - -/* - * Font style - */ -static void sp_text_fontstyle_value_changed( Ink_ComboBoxEntry_Action *act, GObject *tbl ) -{ - // quit if run by the _changed callbacks - if (g_object_get_data(G_OBJECT(tbl), "freeze")) { - return; - } - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - - Glib::ustring new_style = ink_comboboxentry_action_get_active_text( act ); - - Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance(); - - if( new_style.compare( fontlister->get_font_style() ) != 0 ) { - - fontlister->set_font_style( new_style ); - // active text set in sp_text_toolbox_seletion_changed() - - SPCSSAttr *css = sp_repr_css_attr_new (); - fontlister->fill_css( css ); - - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - sp_desktop_set_style (desktop, css, true, true); - - - // If no selected objects, set default. - SPStyle query(SP_ACTIVE_DOCUMENT); - int result_style = - sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTSTYLE); - if (result_style == QUERY_STYLE_NOTHING) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->mergeStyle("/tools/text/style", css); - } else { - // Save for undo - DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_TEXT, - _("Text: Change font style")); - } - - sp_repr_css_attr_unref (css); - - } - - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -} - -// Changes selection to only text outer elements. -static void sp_text_outer_style_changed( InkToggleAction*act, GObject *tbl ) -{ - bool outer = gtk_toggle_action_get_active( GTK_TOGGLE_ACTION(act) ); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setInt("/tools/text/outer_style", outer); - - // Update widgets to reflect new state of Text Outer Style button. - sp_text_toolbox_selection_changed( NULL, tbl ); -} - -// Unset line height on selection's inner text objects (tspan, etc.). -static void sp_text_lineheight_unset_changed( InkToggleAction*act, GObject *tbl ) -{ - // quit if run by the _changed callbacks - if (g_object_get_data(G_OBJECT(tbl), "freeze")) { - return; - } - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - - SPCSSAttr *css = sp_repr_css_attr_new(); - sp_repr_css_unset_property(css, "line-height"); - - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - sp_desktop_set_style (desktop, css); - - sp_repr_css_attr_unref(css); - - DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_TEXT, - _("Text: Unset line height.")); - - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -} - -// Handles both Superscripts and Subscripts -static void sp_text_script_changed( InkToggleAction* act, GObject *tbl ) -{ - // quit if run by the _changed callbacks - if (g_object_get_data(G_OBJECT(tbl), "freeze")) { - return; - } - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - - // Called by Superscript or Subscript button? - const gchar* name = gtk_action_get_name( GTK_ACTION( act ) ); - gint prop = (strcmp(name, "TextSuperscriptAction") == 0) ? 0 : 1; - -#ifdef DEBUG_TEXT - std::cout << "sp_text_script_changed: " << prop << std::endl; -#endif - - // Query baseline - SPStyle query(SP_ACTIVE_DOCUMENT); - int result_baseline = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_BASELINES); - - bool setSuper = false; - bool setSub = false; - - if (Inkscape::is_query_style_updateable(result_baseline)) { - // If not set or mixed, turn on superscript or subscript - if( prop == 0 ) { - setSuper = true; - } else { - setSub = true; - } - } else { - // Superscript - gboolean superscriptSet = (query.baseline_shift.set && - query.baseline_shift.type == SP_BASELINE_SHIFT_LITERAL && - query.baseline_shift.literal == SP_CSS_BASELINE_SHIFT_SUPER ); - - // Subscript - gboolean subscriptSet = (query.baseline_shift.set && - query.baseline_shift.type == SP_BASELINE_SHIFT_LITERAL && - query.baseline_shift.literal == SP_CSS_BASELINE_SHIFT_SUB ); - - setSuper = !superscriptSet && prop == 0; - setSub = !subscriptSet && prop == 1; - } - - // Set css properties - SPCSSAttr *css = sp_repr_css_attr_new (); - if( setSuper || setSub ) { - // Openoffice 2.3 and Adobe use 58%, Microsoft Word 2002 uses 65%, LaTex about 70%. - // 58% looks too small to me, especially if a superscript is placed on a superscript. - // If you make a change here, consider making a change to baseline-shift amount - // in style.cpp. - sp_repr_css_set_property (css, "font-size", "65%"); - } else { - sp_repr_css_set_property (css, "font-size", ""); - } - if( setSuper ) { - sp_repr_css_set_property (css, "baseline-shift", "super"); - } else if( setSub ) { - sp_repr_css_set_property (css, "baseline-shift", "sub"); - } else { - sp_repr_css_set_property (css, "baseline-shift", "baseline"); - } - - // Apply css to selected objects. - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - sp_desktop_set_style (desktop, css, true, false); - - // Save for undo - if(result_baseline != QUERY_STYLE_NOTHING) { - DocumentUndo::maybeDone(SP_ACTIVE_DESKTOP->getDocument(), "ttb:script", SP_VERB_NONE, - _("Text: Change superscript or subscript")); - } - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -} - -static void sp_text_align_mode_changed( GObject *tbl, int mode ) -{ - // quit if run by the _changed callbacks - if (g_object_get_data(G_OBJECT(tbl), "freeze")) { - return; - } - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setInt("/tools/text/align_mode", mode); - - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - - // move the x of all texts to preserve the same bbox - Inkscape::Selection *selection = desktop->getSelection(); - auto itemlist= selection->items(); - for(auto i=itemlist.begin();i!=itemlist.end(); ++i){ - if (SP_IS_TEXT(*i)) { - SPItem *item = *i; - - unsigned writing_mode = item->style->writing_mode.value; - // below, variable names suggest horizontal move, but we check the writing direction - // and move in the corresponding axis - Geom::Dim2 axis; - if (writing_mode == SP_CSS_WRITING_MODE_LR_TB || writing_mode == SP_CSS_WRITING_MODE_RL_TB) { - axis = Geom::X; - } else { - axis = Geom::Y; - } - - Geom::OptRect bbox = item->geometricBounds(); - if (!bbox) - continue; - double width = bbox->dimensions()[axis]; - // If you want to align within some frame, other than the text's own bbox, calculate - // the left and right (or top and bottom for tb text) slacks of the text inside that - // frame (currently unused) - double left_slack = 0; - double right_slack = 0; - unsigned old_align = item->style->text_align.value; - double move = 0; - if (old_align == SP_CSS_TEXT_ALIGN_START || old_align == SP_CSS_TEXT_ALIGN_LEFT) { - switch (mode) { - case 0: - move = -left_slack; - break; - case 1: - move = width/2 + (right_slack - left_slack)/2; - break; - case 2: - move = width + right_slack; - break; - } - } else if (old_align == SP_CSS_TEXT_ALIGN_CENTER) { - switch (mode) { - case 0: - move = -width/2 - left_slack; - break; - case 1: - move = (right_slack - left_slack)/2; - break; - case 2: - move = width/2 + right_slack; - break; - } - } else if (old_align == SP_CSS_TEXT_ALIGN_END || old_align == SP_CSS_TEXT_ALIGN_RIGHT) { - switch (mode) { - case 0: - move = -width - left_slack; - break; - case 1: - move = -width/2 + (right_slack - left_slack)/2; - break; - case 2: - move = right_slack; - break; - } - } - Geom::Point XY = SP_TEXT(item)->attributes.firstXY(); - if (axis == Geom::X) { - XY = XY + Geom::Point (move, 0); - } else { - XY = XY + Geom::Point (0, move); - } - SP_TEXT(item)->attributes.setFirstXY(XY); - item->updateRepr(); - item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - } - } - - SPCSSAttr *css = sp_repr_css_attr_new (); - switch (mode) - { - case 0: - { - sp_repr_css_set_property (css, "text-anchor", "start"); - sp_repr_css_set_property (css, "text-align", "start"); - break; - } - case 1: - { - sp_repr_css_set_property (css, "text-anchor", "middle"); - sp_repr_css_set_property (css, "text-align", "center"); - break; - } - - case 2: - { - sp_repr_css_set_property (css, "text-anchor", "end"); - sp_repr_css_set_property (css, "text-align", "end"); - break; - } - - case 3: - { - sp_repr_css_set_property (css, "text-anchor", "start"); - sp_repr_css_set_property (css, "text-align", "justify"); - break; - } - } - - SPStyle query(SP_ACTIVE_DOCUMENT); - int result_numbers = - sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS); - - // If querying returned nothing, update default style. - if (result_numbers == QUERY_STYLE_NOTHING) - { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->mergeStyle("/tools/text/style", css); - } - - sp_desktop_set_style (desktop, css, true, true); - if (result_numbers != QUERY_STYLE_NOTHING) - { - DocumentUndo::done(SP_ACTIVE_DESKTOP->getDocument(), SP_VERB_CONTEXT_TEXT, - _("Text: Change alignment")); - } - sp_repr_css_attr_unref (css); - - gtk_widget_grab_focus (GTK_WIDGET(SP_ACTIVE_DESKTOP->canvas)); - - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -} - -static bool is_relative( Unit const *unit ) { - return (unit->abbr == "" || unit->abbr == "em" || unit->abbr == "ex" || unit->abbr == "%"); -} - -// Set property for object, but unset all descendents -// Should probably be moved to desktop_style.cpp -static void recursively_set_properties( SPObject* object, SPCSSAttr *css ) { - object->changeCSS (css, "style"); - - SPCSSAttr *css_unset = sp_repr_css_attr_unset_all( css ); - std::vector children = object->childList(false); - for (auto i: children) { - recursively_set_properties (i, css_unset); - } - sp_repr_css_attr_unref (css_unset); -} - -// Apply line height changes (line-height value changed or line-height unit changed) -static void set_lineheight (SPCSSAttr *css) { - - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - bool outer = prefs->getInt("/tools/text/outer_style", false); - gint mode = prefs->getInt("/tools/text/line_spacing_mode", 0); - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - - // Calling sp_desktop_set_style will result in a call to TextTool::_styleSet() which - // will set the style on selected text inside the element. If we want to set - // the style on the outer objects we need to bypass this call. - if ( mode == 3 && !outer ) { - // This will call sp_te_apply_style via signal - sp_desktop_set_style (desktop, css, true, true); - } else { - Inkscape::Selection *selection = desktop->getSelection(); - auto itemlist= selection->items(); - for (auto i: itemlist) { - - if (dynamic_cast(i) || dynamic_cast(i)) { - SPItem *item = i; - - // Scale by inverse of accumulated parent transform - SPCSSAttr *css_set = sp_repr_css_attr_new(); - sp_repr_css_merge(css_set, css); - Geom::Affine const local(item->i2doc_affine()); - double const ex(local.descrim()); - if ( (ex != 0.0) && (ex != 1.0) ) { - sp_css_attr_scale(css_set, 1/ex); - } - - if ( mode == 1 || mode == 2 || mode == 3) { // Minimum, Even, or Adjustable w/ outer. - // We change only outer style - item->changeCSS(css_set,"style"); - } else { - // We change only inner style (Adaptive). - for (auto child: item->childList(false)) { - child->changeCSS(css_set,"style"); - } - } - } - } - } -} - -static void sp_text_lineheight_value_changed( GtkAdjustment *adj, GObject *tbl ) -{ - // quit if run by the _changed callbacks - if (g_object_get_data(G_OBJECT(tbl), "freeze")) { - return; - } - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - - - // Get user selected unit and save as preference - UnitTracker *tracker = reinterpret_cast(g_object_get_data(tbl, "tracker")); - Unit const *unit = tracker->getActiveUnit(); - g_return_if_fail(unit != NULL); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - - - // This nonsense is to get SP_CSS_UNIT_xx value corresponding to unit so - // we can save it (allows us to adjust line height value when unit changes). - SPILength temp_length; - Inkscape::CSSOStringStream temp_stream; - temp_stream << 1 << unit->abbr; - temp_length.read(temp_stream.str().c_str()); - prefs->setInt("/tools/text/lineheight/display_unit", temp_length.unit); - g_object_set_data( tbl, "lineheight_unit", GINT_TO_POINTER(temp_length.unit)); - - // Set css line height. - SPCSSAttr *css = sp_repr_css_attr_new (); - Inkscape::CSSOStringStream osfs; - if ( is_relative(unit) ) { - osfs << gtk_adjustment_get_value(adj) << unit->abbr; - } else { - // Inside SVG file, always use "px" for absolute units. - osfs << Quantity::convert(gtk_adjustment_get_value(adj), unit, "px") << "px"; - } - sp_repr_css_set_property (css, "line-height", osfs.str().c_str()); - - // Internal function to set line-height which is spacing mode dependent. - set_lineheight (css); - - // Only need to save for undo if a text item has been changed. - Inkscape::Selection *selection = SP_ACTIVE_DESKTOP->getSelection(); - bool modmade = false; - auto itemlist= selection->items(); - for(auto i=itemlist.begin();i!=itemlist.end(); ++i){ - if (dynamic_cast(*i) || dynamic_cast(*i)) { - modmade = true; - } - } - - // Save for undo - if (modmade) { - // Call ensureUpToDate() causes rebuild of text layout (with all proper style - // cascading, etc.). For multi-line text with sodipodi::role="line", we must explicitly - // save new 'x' and 'y' attribute values by calling updateRepr(). - // Partial fix for bug #1590141. - SP_ACTIVE_DESKTOP->getDocument()->ensureUpToDate(); - for(auto i=itemlist.begin();i!=itemlist.end(); ++i){ - if (dynamic_cast(*i) || dynamic_cast(*i)) { - (*i)->updateRepr(); - } - } - DocumentUndo::maybeDone(SP_ACTIVE_DESKTOP->getDocument(), "ttb:line-height", SP_VERB_NONE, - _("Text: Change line-height")); - } - - // If no selected objects, set default. - SPStyle query(SP_ACTIVE_DOCUMENT); - int result_numbers = - sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS); - if (result_numbers == QUERY_STYLE_NOTHING) - { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->mergeStyle("/tools/text/style", css); - } - - sp_repr_css_attr_unref (css); - - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -} - - -static void sp_text_lineheight_unit_changed( GObject *tbl, int /* Not Used */ ) -{ - // quit if run by the _changed callbacks - if (g_object_get_data(G_OBJECT(tbl), "freeze")) { - return; - } - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - - // Get old saved unit - int old_unit = GPOINTER_TO_INT( g_object_get_data(tbl, "lineheight_unit")); - - // Get user selected unit and save as preference - UnitTracker *tracker = reinterpret_cast(g_object_get_data(tbl, "tracker")); - Unit const *unit = tracker->getActiveUnit(); - g_return_if_fail(unit != NULL); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - - // This nonsense is to get SP_CSS_UNIT_xx value corresponding to unit. - SPILength temp_length; - Inkscape::CSSOStringStream temp_stream; - temp_stream << 1 << unit->abbr; - temp_length.read(temp_stream.str().c_str()); - prefs->setInt("/tools/text/lineheight/display_unit", temp_length.unit); - g_object_set_data( tbl, "lineheight_unit", GINT_TO_POINTER(temp_length.unit)); - - // Read current line height value - EgeAdjustmentAction *line_height_act = - reinterpret_cast(g_object_get_data(tbl, "TextLineHeightAction")); - GtkAdjustment *line_height_adj = ege_adjustment_action_get_adjustment( line_height_act ); - double line_height = gtk_adjustment_get_value(line_height_adj); - - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - Inkscape::Selection *selection = desktop->getSelection(); - auto itemlist = selection->items(); - - // Convert between units - if ((unit->abbr == "" || unit->abbr == "em") && - (old_unit == SP_CSS_UNIT_NONE || old_unit == SP_CSS_UNIT_EM)) { - // Do nothing - } else if ((unit->abbr == "" || unit->abbr == "em") && old_unit == SP_CSS_UNIT_EX) { - line_height *= 0.5; - } else if ((unit->abbr) == "ex" && (old_unit == SP_CSS_UNIT_EM || old_unit == SP_CSS_UNIT_NONE) ) { - line_height *= 2.0; - } else if ((unit->abbr == "" || unit->abbr == "em") && old_unit == SP_CSS_UNIT_PERCENT) { - line_height /= 100.0; - } else if ((unit->abbr) == "%" && (old_unit == SP_CSS_UNIT_EM || old_unit == SP_CSS_UNIT_NONE) ) { - line_height *= 100; - } else if ((unit->abbr) == "ex" && old_unit == SP_CSS_UNIT_PERCENT) { - line_height /= 50.0; - } else if ((unit->abbr) == "%" && old_unit == SP_CSS_UNIT_EX) { - line_height *= 50; - } else if (is_relative(unit)) { - // Convert absolute to relative... for the moment use average font-size - double font_size = 0; - int count = 0; - for(auto i=itemlist.begin();i!=itemlist.end(); ++i){ - if (SP_IS_TEXT (*i) || SP_IS_FLOWTEXT(*i)) { - double doc_scale = Geom::Affine((*i)->i2dt_affine()).descrim(); - font_size += (*i)->style->font_size.computed * doc_scale; - ++count; - } - } - if (count > 0) { - font_size /= count; - } else { - font_size = 20; - } - - if (old_unit == SP_CSS_UNIT_NONE) old_unit = SP_CSS_UNIT_EM; - line_height = Quantity::convert(line_height, sp_style_get_css_unit_string(old_unit), "px"); - - if (font_size > 0) { - line_height /= font_size; - } - if ((unit->abbr) == "%") { - line_height *= 100; - } else if ((unit->abbr) == "ex") { - line_height *= 2; - } - } else if (old_unit==SP_CSS_UNIT_NONE || old_unit==SP_CSS_UNIT_PERCENT || - old_unit==SP_CSS_UNIT_EM || old_unit==SP_CSS_UNIT_EX) { - // Convert relative to absolute... for the moment use average font-size - double font_size = 0; - int count = 0; - for(auto i=itemlist.begin();i!=itemlist.end(); ++i){ - if (SP_IS_TEXT (*i) || SP_IS_FLOWTEXT (*i)) { - double doc_scale = Geom::Affine((*i)->i2dt_affine()).descrim(); - font_size += (*i)->style->font_size.computed * doc_scale; - ++count; - } - } - if (count > 0) { - font_size /= count; - } else { - font_size = 20; - } - - if (old_unit == SP_CSS_UNIT_PERCENT) { - line_height /= 100.0; - } else if (old_unit == SP_CSS_UNIT_EX) { - line_height /= 2.0; - } - line_height *= font_size; - line_height = Quantity::convert(line_height, "px", unit); - } else { - // Convert between different absolute units (only used in GUI) - line_height = Quantity::convert(line_height, sp_style_get_css_unit_string(old_unit), unit); - } - - // Set css line height. - SPCSSAttr *css = sp_repr_css_attr_new (); - Inkscape::CSSOStringStream osfs; - if ( is_relative(unit) ) { - osfs << line_height << unit->abbr; - } else { - osfs << Quantity::convert(line_height, unit, "px") << "px"; - } - sp_repr_css_set_property (css, "line-height", osfs.str().c_str()); - - // Update GUI with line_height value. - gtk_adjustment_set_value(line_height_adj, line_height); - - // Update "climb rate" The custom action has a step property but no way to set it. - if (unit->abbr == "%") { - gtk_adjustment_set_step_increment (line_height_adj, 1.0); - gtk_adjustment_set_page_increment (line_height_adj, 10.0); - } else { - gtk_adjustment_set_step_increment (line_height_adj, 0.1); - gtk_adjustment_set_page_increment (line_height_adj, 1.0); - } - - // Internal function to set line-height which is spacing mode dependent. - set_lineheight (css); - - // Only need to save for undo if a text item has been changed. - bool modmade = false; - for(auto i=itemlist.begin();i!=itemlist.end(); ++i){ - if (dynamic_cast(*i) || dynamic_cast(*i)) { - modmade = true; - } - } - - // Save for undo - if(modmade) { - DocumentUndo::maybeDone(SP_ACTIVE_DESKTOP->getDocument(), "ttb:line-height", SP_VERB_NONE, - _("Text: Change line-height unit")); - } - - // If no selected objects, set default. - SPStyle query(SP_ACTIVE_DOCUMENT); - int result_numbers = - sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS); - if (result_numbers == QUERY_STYLE_NOTHING) - { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->mergeStyle("/tools/text/style", css); - } - - sp_repr_css_attr_unref (css); - - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -} - -// -static void sp_text_line_spacing_mode_changed( GObject *tbl, int mode ) -{ - - // quit if run by the _changed callbacks - if (g_object_get_data(G_OBJECT(tbl), "freeze")) { - return; - } - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setInt("/tools/text/line_spacing_mode", mode); - - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - - // Note: only and text elements are in selection! - // (No need to worry about , , ...) - Inkscape::Selection *selection = desktop->getSelection(); - std::vector vec(selection->items().begin(), selection->items().end()); - - for (auto i: vec) { - - // Only and , => SPFlowtext - if (dynamic_cast(i) || dynamic_cast(i)) { - SPStyle* text_style = i->style; - - // Make list of , , children - std::vector children = i->childList(false); - std::vector children_item; - for (auto j: children) { - if (dynamic_cast(j)) { - children_item.push_back( dynamic_cast(j) ); - } - } - - SPStyle tspans; // Also flowPara/flowSpan - int result_numbers = sp_desktop_query_style_from_list (children_item, &tspans, QUERY_STYLE_PROPERTY_FONTNUMBERS); - - Inkscape::CSSOStringStream osfs; - if (text_style->line_height.computed != 0 || text_style->line_height.normal) { - - if (mode != 1 || text_style->line_height.unit == SP_CSS_UNIT_NONE || text_style->line_height.normal) { - Glib::ustring line_height_string = text_style->line_height.write( SP_STYLE_FLAG_ALWAYS ); - line_height_string.erase(0, 12); // erase 'line-height:' - osfs << line_height_string; - } else { - // Convert to unitless value - double line_height_value = text_style->line_height.value; - // Percent values are stored as value/100; - if (text_style->line_height.unit == SP_CSS_UNIT_PERCENT) { - line_height_value *= 100; - } - osfs << sp_style_css_size_units_to_px( line_height_value, - text_style->line_height.unit, - text_style->font_size.computed) / - text_style->font_size.computed; - } - - } else { - - if (mode != 1 || tspans.line_height.unit == SP_CSS_UNIT_NONE || tspans.line_height.normal) { - Glib::ustring line_height_string = tspans.line_height.write( SP_STYLE_FLAG_ALWAYS ); - line_height_string.erase(0, 12); // erase 'line-height:' - osfs << line_height_string; - } else { - // Convert to unitless value - double line_height_value = tspans.line_height.value; - // Percent values are stored as value/100; - if (tspans.line_height.unit == SP_CSS_UNIT_PERCENT) { - line_height_value *= 100; - } - osfs << sp_style_css_size_units_to_px( line_height_value, - tspans.line_height.unit, - tspans.font_size.computed) / - tspans.font_size.computed; - } - } - - SPCSSAttr *css_text = sp_repr_css_attr_new(); - SPCSSAttr *css_tspan = sp_repr_css_attr_new(); - - sp_repr_css_set_property (css_text, "line-height", osfs.str().c_str()); - - switch (mode) { - case 0: // Adaptive - // : Zero text - sp_repr_css_set_property (css_text, "line-height", "0"); - // : Old text value. - sp_repr_css_set_property (css_tspan, "line-height", osfs.str().c_str()); - break; - - case 1: // Minimum - // : Set to old text (unitless) or if old text zero, set to old tspan. - sp_repr_css_set_property (css_text, "line-height", osfs.str().c_str()); - // : Unset - sp_repr_css_unset_property (css_tspan, "line-height"); - break; - - case 2: // Even - // : Set to old text or if old text zero, set to old tspan. - sp_repr_css_set_property (css_text, "line-height", osfs.str().c_str()); - // : Set to zero - sp_repr_css_set_property (css_tspan, "line-height", "0"); - break; - - case 3: // Adjustable - // Do nothing ☠ - break; - } - - if (mode != 3) { - i->changeCSS (css_text, "style"); - for (auto j: children) { - recursively_set_properties (j, css_tspan); - //j->changeCSS (css_tspan, "style"); - } - } - - sp_repr_css_attr_unref (css_text); - sp_repr_css_attr_unref (css_tspan); - } - } - - // Set "Outer Style" toggle to match mode. - InkToggleAction* outerStyle = INK_TOGGLE_ACTION(g_object_get_data (tbl, "TextOuterStyleAction")); - - switch (mode) { - case 0: // Adaptive - gtk_toggle_action_set_active( &(outerStyle->action), false ); - prefs->setInt("/tools/text/outer_style", false); - break; - - case 1: // Minimum - case 2: // Even - gtk_toggle_action_set_active( &(outerStyle->action), true ); - prefs->setInt("/tools/text/outer_style", true); - break; - - case 3: // Adjustable - break; - } - - // Outer style toggle set per mode so that line height widget should be enabled. - GtkAction* lineHeightAction = GTK_ACTION( g_object_get_data( tbl, "TextLineHeightAction" ) ); - gtk_action_set_sensitive (lineHeightAction, true); - - // Update "climb rate" - EgeAdjustmentAction *line_height_act = - reinterpret_cast(g_object_get_data(tbl, "TextLineHeightAction")); - GtkAdjustment *line_height_adj = ege_adjustment_action_get_adjustment( line_height_act ); - UnitTracker *tracker = reinterpret_cast(g_object_get_data(tbl, "tracker")); - Unit const *unit = tracker->getActiveUnit(); - - if (unit->abbr == "%") { - gtk_adjustment_set_step_increment (line_height_adj, 1.0); - gtk_adjustment_set_page_increment (line_height_adj, 10.0); - } else { - gtk_adjustment_set_step_increment (line_height_adj, 0.1); - gtk_adjustment_set_page_increment (line_height_adj, 1.0); - } - - DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_TEXT, - _("Text: Change line spacing mode")); - - gtk_widget_grab_focus (GTK_WIDGET(desktop->canvas)); - - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -} - -static void sp_text_wordspacing_value_changed( GtkAdjustment *adj, GObject *tbl ) -{ - // quit if run by the _changed callbacks - if (g_object_get_data(G_OBJECT(tbl), "freeze")) { - return; - } - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - - // At the moment this handles only numerical values (i.e. no em unit). - // Set css word-spacing - SPCSSAttr *css = sp_repr_css_attr_new (); - Inkscape::CSSOStringStream osfs; - osfs << gtk_adjustment_get_value(adj) << "px"; // For now always use px - sp_repr_css_set_property (css, "word-spacing", osfs.str().c_str()); - - // Apply word-spacing to selected objects. - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - sp_desktop_set_style (desktop, css, true, false); - - // If no selected objects, set default. - SPStyle query(SP_ACTIVE_DOCUMENT); - int result_numbers = - sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS); - if (result_numbers == QUERY_STYLE_NOTHING) - { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->mergeStyle("/tools/text/style", css); - } else { - // Save for undo - DocumentUndo::maybeDone(SP_ACTIVE_DESKTOP->getDocument(), "ttb:word-spacing", SP_VERB_NONE, - _("Text: Change word-spacing")); - } - - sp_repr_css_attr_unref (css); - - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -} - -static void sp_text_letterspacing_value_changed( GtkAdjustment *adj, GObject *tbl ) -{ - // quit if run by the _changed callbacks - if (g_object_get_data(G_OBJECT(tbl), "freeze")) { - return; - } - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - - // At the moment this handles only numerical values (i.e. no em unit). - // Set css letter-spacing - SPCSSAttr *css = sp_repr_css_attr_new (); - Inkscape::CSSOStringStream osfs; - osfs << gtk_adjustment_get_value(adj) << "px"; // For now always use px - sp_repr_css_set_property (css, "letter-spacing", osfs.str().c_str()); - - // Apply letter-spacing to selected objects. - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - sp_desktop_set_style (desktop, css, true, false); - - // If no selected objects, set default. - SPStyle query(SP_ACTIVE_DOCUMENT); - int result_numbers = - sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS); - if (result_numbers == QUERY_STYLE_NOTHING) - { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->mergeStyle("/tools/text/style", css); - } - else - { - // Save for undo - DocumentUndo::maybeDone(SP_ACTIVE_DESKTOP->getDocument(), "ttb:letter-spacing", SP_VERB_NONE, - _("Text: Change letter-spacing")); - } - - sp_repr_css_attr_unref (css); - - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -} - - -static void sp_text_dx_value_changed( GtkAdjustment *adj, GObject *tbl ) -{ - // quit if run by the _changed callbacks - if (g_object_get_data(G_OBJECT(tbl), "freeze")) { - return; - } - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - - gdouble new_dx = gtk_adjustment_get_value(adj); - bool modmade = false; - - if( SP_IS_TEXT_CONTEXT((SP_ACTIVE_DESKTOP)->event_context) ) { - Inkscape::UI::Tools::TextTool *const tc = SP_TEXT_CONTEXT((SP_ACTIVE_DESKTOP)->event_context); - if( tc ) { - unsigned char_index = -1; - TextTagAttributes *attributes = - text_tag_attributes_at_position( tc->text, std::min(tc->text_sel_start, tc->text_sel_end), &char_index ); - if( attributes ) { - double old_dx = attributes->getDx( char_index ); - double delta_dx = new_dx - old_dx; - sp_te_adjust_dx( tc->text, tc->text_sel_start, tc->text_sel_end, SP_ACTIVE_DESKTOP, delta_dx ); - modmade = true; - } - } - } - - if(modmade) { - // Save for undo - DocumentUndo::maybeDone(SP_ACTIVE_DESKTOP->getDocument(), "ttb:dx", SP_VERB_NONE, - _("Text: Change dx (kern)")); - } - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -} - -static void sp_text_dy_value_changed( GtkAdjustment *adj, GObject *tbl ) -{ - // quit if run by the _changed callbacks - if (g_object_get_data(G_OBJECT(tbl), "freeze")) { - return; - } - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - - gdouble new_dy = gtk_adjustment_get_value(adj); - bool modmade = false; - - if( SP_IS_TEXT_CONTEXT((SP_ACTIVE_DESKTOP)->event_context) ) { - Inkscape::UI::Tools::TextTool *const tc = SP_TEXT_CONTEXT((SP_ACTIVE_DESKTOP)->event_context); - if( tc ) { - unsigned char_index = -1; - TextTagAttributes *attributes = - text_tag_attributes_at_position( tc->text, std::min(tc->text_sel_start, tc->text_sel_end), &char_index ); - if( attributes ) { - double old_dy = attributes->getDy( char_index ); - double delta_dy = new_dy - old_dy; - sp_te_adjust_dy( tc->text, tc->text_sel_start, tc->text_sel_end, SP_ACTIVE_DESKTOP, delta_dy ); - modmade = true; - } - } - } - - if(modmade) { - // Save for undo - DocumentUndo::maybeDone(SP_ACTIVE_DESKTOP->getDocument(), "ttb:dy", SP_VERB_NONE, - _("Text: Change dy")); - } - - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -} - -static void sp_text_rotation_value_changed( GtkAdjustment *adj, GObject *tbl ) -{ - // quit if run by the _changed callbacks - if (g_object_get_data(G_OBJECT(tbl), "freeze")) { - return; - } - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - - gdouble new_degrees = gtk_adjustment_get_value(adj); - - bool modmade = false; - if( SP_IS_TEXT_CONTEXT((SP_ACTIVE_DESKTOP)->event_context) ) { - Inkscape::UI::Tools::TextTool *const tc = SP_TEXT_CONTEXT((SP_ACTIVE_DESKTOP)->event_context); - if( tc ) { - unsigned char_index = -1; - TextTagAttributes *attributes = - text_tag_attributes_at_position( tc->text, std::min(tc->text_sel_start, tc->text_sel_end), &char_index ); - if( attributes ) { - double old_degrees = attributes->getRotate( char_index ); - double delta_deg = new_degrees - old_degrees; - sp_te_adjust_rotation( tc->text, tc->text_sel_start, tc->text_sel_end, SP_ACTIVE_DESKTOP, delta_deg ); - modmade = true; - } - } - } - - // Save for undo - if(modmade) { - DocumentUndo::maybeDone(SP_ACTIVE_DESKTOP->getDocument(), "ttb:rotate", SP_VERB_NONE, - _("Text: Change rotate")); - } - - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -} - -static void sp_writing_mode_changed( GObject* tbl, int mode ) -{ - // quit if run by the _changed callbacks - if (g_object_get_data(G_OBJECT(tbl), "freeze")) { - return; - } - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - - SPCSSAttr *css = sp_repr_css_attr_new (); - switch (mode) - { - case 0: - { - sp_repr_css_set_property (css, "writing-mode", "lr-tb"); - break; - } - - case 1: - { - sp_repr_css_set_property (css, "writing-mode", "tb-rl"); - break; - } - - case 2: - { - sp_repr_css_set_property (css, "writing-mode", "vertical-lr"); - break; - } -} - - SPStyle query(SP_ACTIVE_DOCUMENT); - int result_numbers = - sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_WRITINGMODES); - - // If querying returned nothing, update default style. - if (result_numbers == QUERY_STYLE_NOTHING) - { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->mergeStyle("/tools/text/style", css); - } - - sp_desktop_set_style (SP_ACTIVE_DESKTOP, css, true, true); - if(result_numbers != QUERY_STYLE_NOTHING) - { - DocumentUndo::done(SP_ACTIVE_DESKTOP->getDocument(), SP_VERB_CONTEXT_TEXT, - _("Text: Change writing mode")); - } - sp_repr_css_attr_unref (css); - - gtk_widget_grab_focus (GTK_WIDGET(SP_ACTIVE_DESKTOP->canvas)); - - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -} - -static void sp_text_orientation_changed( GObject* tbl, int mode ) -{ - // quit if run by the _changed callbacks - if (g_object_get_data(G_OBJECT(tbl), "freeze")) { - return; - } - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - - SPCSSAttr *css = sp_repr_css_attr_new (); - switch (mode) - { - case 0: - { - sp_repr_css_set_property (css, "text-orientation", "auto"); - break; - } - - case 1: - { - sp_repr_css_set_property (css, "text-orientation", "upright"); - break; - } - - case 2: - { - sp_repr_css_set_property (css, "text-orientation", "sideways"); - break; - } - } - - SPStyle query(SP_ACTIVE_DOCUMENT); - int result_numbers = - sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_WRITINGMODES); - - // If querying returned nothing, update default style. - if (result_numbers == QUERY_STYLE_NOTHING) - { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->mergeStyle("/tools/text/style", css); - } - - sp_desktop_set_style (SP_ACTIVE_DESKTOP, css, true, true); - if(result_numbers != QUERY_STYLE_NOTHING) - { - DocumentUndo::done(SP_ACTIVE_DESKTOP->getDocument(), SP_VERB_CONTEXT_TEXT, - _("Text: Change orientation")); - } - sp_repr_css_attr_unref (css); - - gtk_widget_grab_focus (GTK_WIDGET(SP_ACTIVE_DESKTOP->canvas)); - - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -} - -static void sp_text_direction_changed( GObject *tbl, int mode ) -{ - // quit if run by the _changed callbacks - if (g_object_get_data(G_OBJECT(tbl), "freeze")) { - return; - } - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - - SPCSSAttr *css = sp_repr_css_attr_new (); - switch (mode) - { - case 0: - { - sp_repr_css_set_property (css, "direction", "ltr"); - break; - } - - case 1: - { - sp_repr_css_set_property (css, "direction", "rtl"); - break; - } - } - - SPStyle query(SP_ACTIVE_DOCUMENT); - int result_numbers = - sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_WRITINGMODES); - - // If querying returned nothing, update default style. - if (result_numbers == QUERY_STYLE_NOTHING) - { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->mergeStyle("/tools/text/style", css); - } - - sp_desktop_set_style (SP_ACTIVE_DESKTOP, css, true, true); - if(result_numbers != QUERY_STYLE_NOTHING) - { - DocumentUndo::done(SP_ACTIVE_DESKTOP->getDocument(), SP_VERB_CONTEXT_TEXT, - _("Text: Change direction")); - } - sp_repr_css_attr_unref (css); - - gtk_widget_grab_focus (GTK_WIDGET(SP_ACTIVE_DESKTOP->canvas)); - - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -} - -/* - * Set the default list of font sizes, scaled to the users preferred unit - */ -static void sp_text_set_sizes(GtkListStore* model_size, int unit) -{ - gtk_list_store_clear(model_size); - - // List of font sizes for drop-down menu - int sizes[] = { - 4, 6, 8, 9, 10, 11, 12, 13, 14, 16, 18, 20, 22, 24, 28, - 32, 36, 40, 48, 56, 64, 72, 144 - }; - - // Array must be same length as SPCSSUnit in style.h - float ratios[] = {1, 1, 1, 10, 4, 40, 100, 16, 8, 0.16}; - - for( unsigned int i = 0; i < G_N_ELEMENTS(sizes); ++i ) { - GtkTreeIter iter; - Glib::ustring size = Glib::ustring::format(sizes[i] / (float)ratios[unit]); - gtk_list_store_append( model_size, &iter ); - gtk_list_store_set( model_size, &iter, 0, size.c_str(), -1 ); - } -} - - -/* - * This function sets up the text-tool tool-controls, setting the entry boxes - * etc. to the values from the current selection or the default if no selection. - * It is called whenever a text selection is changed, including stepping cursor - * through text, or setting focus to text. - */ -static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/, GObject *tbl, bool subselection) // don't bother to update font list if subsel changed -{ - -#ifdef DEBUG_TEXT - static int count = 0; - ++count; - std::cout << std::endl; - std::cout << "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&" << std::endl; - std::cout << "sp_text_toolbox_selection_changed: start " << count << std::endl; - - Inkscape::Selection *selection = (SP_ACTIVE_DESKTOP)->getSelection(); - auto itemlist0= selection->items(); - for(auto i=itemlist0.begin();i!=itemlist0.end(); ++i) { - const gchar* id = (*i)->getId(); - std::cout << " " << id << std::endl; - } - Glib::ustring selected_text = sp_text_get_selected_text((SP_ACTIVE_DESKTOP)->event_context); - std::cout << " Selected text: |" << selected_text << "|" << std::endl; -#endif - - // quit if run by the _changed callbacks - if (g_object_get_data(G_OBJECT(tbl), "freeze")) { -#ifdef DEBUG_TEXT - std::cout << " Frozen, returning" << std::endl; - std::cout << "sp_text_toolbox_selection_changed: exit " << count << std::endl; - std::cout << "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&" << std::endl; - std::cout << std::endl; -#endif - return; - } - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - - Ink_ComboBoxEntry_Action* fontFamilyAction = - INK_COMBOBOXENTRY_ACTION( g_object_get_data( tbl, "TextFontFamilyAction" ) ); - Ink_ComboBoxEntry_Action* fontStyleAction = - INK_COMBOBOXENTRY_ACTION( g_object_get_data( tbl, "TextFontStyleAction" ) ); - - Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance(); - fontlister->update_font_list (SP_ACTIVE_DESKTOP->getDocument()); - fontlister->selection_update(); - - // Update font list, but only if widget already created. - if( fontFamilyAction->combobox != NULL ) { - ink_comboboxentry_action_set_active_text( fontFamilyAction, fontlister->get_font_family().c_str(), fontlister->get_font_family_row() ); - ink_comboboxentry_action_set_active_text( fontStyleAction, fontlister->get_font_style().c_str() ); - } - - // Only flowed text can be justified, only normal text can be kerned... - // Find out if we have flowed text now so we can use it several places - gboolean isFlow = false; - auto itemlist= SP_ACTIVE_DESKTOP->getSelection()->items(); - for(auto i=itemlist.begin();i!=itemlist.end(); ++i){ - // std::cout << " " << ((*i)->getId()?(*i)->getId():"null") << std::endl; - if( SP_IS_FLOWTEXT(*i)) { - isFlow = true; - // std::cout << " Found flowed text" << std::endl; - break; - } - } - - /* - * Query from current selection: - * Font family (font-family) - * Style (font-weight, font-style, font-stretch, font-variant, font-align) - * Numbers (font-size, letter-spacing, word-spacing, line-height, text-anchor, writing-mode) - * Font specification (Inkscape private attribute) - */ - SPStyle query(SP_ACTIVE_DOCUMENT); - int result_family = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTFAMILY); - int result_style = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTSTYLE); - int result_baseline = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_BASELINES); - int result_wmode = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_WRITINGMODES); - - // Calling sp_desktop_query_style will result in a call to TextTool::_styleQueried(). - // This returns the style of the selected text inside the element... which - // is often the style of one or more s. If we want the style of the outer - // objects then we need to bypass the call to TextTool::_styleQueried(). - // The desktop selection never includes the elements inside the element. - int result_numbers = 0; - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - bool outer = prefs->getInt("/tools/text/outer_style", false); - if (outer) { - Inkscape::Selection *selection = desktop->getSelection(); - std::vector vec(selection->items().begin(), selection->items().end()); - result_numbers = sp_desktop_query_style_from_list (vec, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS); - } else { - result_numbers = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_FONTNUMBERS); - } - - /* - * If no text in selection (querying returned nothing), read the style from - * the /tools/text preferencess (default style for new texts). Return if - * tool bar already set to these preferences. - */ - if (result_family == QUERY_STYLE_NOTHING || - result_style == QUERY_STYLE_NOTHING || - result_numbers == QUERY_STYLE_NOTHING || - result_wmode == QUERY_STYLE_NOTHING ) { - // There are no texts in selection, read from preferences. - query.readFromPrefs("/tools/text"); -#ifdef DEBUG_TEXT - std::cout << " read style from prefs:" << std::endl; - sp_print_font( &query ); -#endif - if (g_object_get_data(tbl, "text_style_from_prefs")) { - // Do not reset the toolbar style from prefs if we already did it last time - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -#ifdef DEBUG_TEXT - std::cout << " text_style_from_prefs: toolbar already set" << std:: endl; - std::cout << "sp_text_toolbox_selection_changed: exit " << count << std::endl; - std::cout << "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&" << std::endl; - std::cout << std::endl; -#endif - return; - } - - // To ensure the value of the combobox is properly set on start-up, only mark - // the prefs set if the combobox has already been constructed. - if( fontFamilyAction->combobox != NULL ) { - g_object_set_data(tbl, "text_style_from_prefs", GINT_TO_POINTER(TRUE)); - } - } else { - g_object_set_data(tbl, "text_style_from_prefs", GINT_TO_POINTER(FALSE)); - } - - // If we have valid query data for text (font-family, font-specification) set toolbar accordingly. - { - // Size (average of text selected) - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - int unit = prefs->getInt("/options/font/unitType", SP_CSS_UNIT_PT); - double size = sp_style_css_size_px_to_units(query.font_size.computed, unit); - - //gchar size_text[G_ASCII_DTOSTR_BUF_SIZE]; - //g_ascii_dtostr (size_text, sizeof (size_text), size); - - Inkscape::CSSOStringStream os; - os << size; - - Ink_ComboBoxEntry_Action* fontSizeAction = - INK_COMBOBOXENTRY_ACTION( g_object_get_data( tbl, "TextFontSizeAction" ) ); - - // Freeze to ignore callbacks. - //g_object_freeze_notify( G_OBJECT( fontSizeAction->combobox ) ); - sp_text_set_sizes(GTK_LIST_STORE(ink_comboboxentry_action_get_model(fontSizeAction)), unit); - //g_object_thaw_notify( G_OBJECT( fontSizeAction->combobox ) ); - - ink_comboboxentry_action_set_active_text( fontSizeAction, os.str().c_str() ); - - Glib::ustring tooltip = Glib::ustring::format(_("Font size"), " (", sp_style_get_css_unit_string(unit), ")"); - ink_comboboxentry_action_set_tooltip ( fontSizeAction, tooltip.c_str()); - - // Superscript - gboolean superscriptSet = - ((result_baseline == QUERY_STYLE_SINGLE || result_baseline == QUERY_STYLE_MULTIPLE_SAME ) && - query.baseline_shift.set && - query.baseline_shift.type == SP_BASELINE_SHIFT_LITERAL && - query.baseline_shift.literal == SP_CSS_BASELINE_SHIFT_SUPER ); - - InkToggleAction* textSuperscriptAction = INK_TOGGLE_ACTION( g_object_get_data( tbl, "TextSuperscriptAction" ) ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(textSuperscriptAction), superscriptSet ); - - - // Subscript - gboolean subscriptSet = - ((result_baseline == QUERY_STYLE_SINGLE || result_baseline == QUERY_STYLE_MULTIPLE_SAME ) && - query.baseline_shift.set && - query.baseline_shift.type == SP_BASELINE_SHIFT_LITERAL && - query.baseline_shift.literal == SP_CSS_BASELINE_SHIFT_SUB ); - - InkToggleAction* textSubscriptAction = INK_TOGGLE_ACTION( g_object_get_data( tbl, "TextSubscriptAction" ) ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(textSubscriptAction), subscriptSet ); - - - // Alignment - InkSelectOneAction* textAlignAction = - static_cast( g_object_get_data( tbl, "TextAlignAction" ) ); - - // Note: SVG 1.1 doesn't include text-align, SVG 1.2 Tiny doesn't include text-align="justify" - // text-align="justify" was a draft SVG 1.2 item (along with flowed text). - // Only flowed text can be left and right justified at the same time. - // Disable button if we don't have flowed text. - - Glib::RefPtr store = textAlignAction->get_store(); - Gtk::TreeModel::Row row = *(store->get_iter("3")); // Justify entry - InkSelectOneActionColumns columns; - row[columns.col_sensitive] = isFlow; - - int activeButton = 0; - if (query.text_align.computed == SP_CSS_TEXT_ALIGN_JUSTIFY) - { - activeButton = 3; - } else { - // This should take 'direction' into account - if (query.text_anchor.computed == SP_CSS_TEXT_ANCHOR_START) activeButton = 0; - if (query.text_anchor.computed == SP_CSS_TEXT_ANCHOR_MIDDLE) activeButton = 1; - if (query.text_anchor.computed == SP_CSS_TEXT_ANCHOR_END) activeButton = 2; - } - textAlignAction->set_active( activeButton ); - - // Line height (spacing) and line height unit - double height; - int line_height_unit = -1; - if (query.line_height.normal) { - height = Inkscape::Text::Layout::LINE_HEIGHT_NORMAL; - line_height_unit = SP_CSS_UNIT_NONE; - } else { - height = query.line_height.value; - line_height_unit = query.line_height.unit; - } - - switch (line_height_unit) { - case SP_CSS_UNIT_NONE: - case SP_CSS_UNIT_EM: - case SP_CSS_UNIT_EX: - break; - case SP_CSS_UNIT_PERCENT: - height *= 100.0; // Inkscape store % as fraction in .value - break; - case SP_CSS_UNIT_PX: - // If unit is set to 'px', use the preferred display unit (if absolute). - line_height_unit = - prefs->getInt("/tools/text/lineheight/display_unit", SP_CSS_UNIT_PT); - // But not if preferred unit is relative - if (line_height_unit != SP_CSS_UNIT_NONE && - line_height_unit != SP_CSS_UNIT_EM && - line_height_unit != SP_CSS_UNIT_EX && - line_height_unit != SP_CSS_UNIT_PERCENT) { - height = - Quantity::convert(height, "px", sp_style_get_css_unit_string(line_height_unit)); - } else { - line_height_unit = SP_CSS_UNIT_PX; - } - break; - default: - // If unit has been set by an external program to something other than 'px', use - // that unit. But height is average of computed values (px) so we need to convert - // back. - height = - Quantity::convert(height, "px", sp_style_get_css_unit_string(line_height_unit)); - } - - GtkAction* lineHeightAction = GTK_ACTION( g_object_get_data( tbl, "TextLineHeightAction" ) ); - GtkAdjustment *lineHeightAdjustment = - ege_adjustment_action_get_adjustment(EGE_ADJUSTMENT_ACTION( lineHeightAction )); - gtk_adjustment_set_value( lineHeightAdjustment, height ); - - // Update "climb rate" - if (line_height_unit == SP_CSS_UNIT_PERCENT) { - gtk_adjustment_set_step_increment (lineHeightAdjustment, 1.0); - gtk_adjustment_set_page_increment (lineHeightAdjustment, 10.0); - } else { - gtk_adjustment_set_step_increment (lineHeightAdjustment, 0.1); - gtk_adjustment_set_page_increment (lineHeightAdjustment, 1.0); - } - - UnitTracker* tracker = reinterpret_cast( g_object_get_data( tbl, "tracker" ) ); - if( line_height_unit == SP_CSS_UNIT_NONE ) { - // Function 'sp_style_get_css_unit_string' returns 'px' for unit none. - // We need to avoid this. - tracker->setActiveUnitByAbbr(""); - } else { - tracker->setActiveUnitByAbbr(sp_style_get_css_unit_string(line_height_unit)); - } - // Save unit so we can do conversions between new/old units. - g_object_set_data( tbl, "lineheight_unit", GINT_TO_POINTER(line_height_unit)); - - // Enable and turn on only if selection includes an object with line height set. - InkToggleAction* lineHeightUnset = - INK_TOGGLE_ACTION( g_object_get_data( tbl, "TextLineHeightUnsetAction")); - gtk_action_set_sensitive(GTK_ACTION(lineHeightUnset), query.line_height.set ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(lineHeightUnset), query.line_height.set ); - - - // Line spacing mode: requires calculating mode for each element and the s within. - Inkscape::Selection *selection = desktop->getSelection(); - std::vector vec(selection->items().begin(), selection->items().end()); - int mode[4] = {0, 0, 0, 0}; - for (auto i: vec) { - if (dynamic_cast(i) || dynamic_cast(i) ) { - bool text_line_height_set = false; - bool text_line_height_zero = false; - bool text_line_height_has_units = false; - bool tspan_line_height_all_unset = true; - bool tspan_line_height_all_zero = true; - bool tspan_line_height_all_non_zero = true; - if (i->style && i->style->line_height.set) { - text_line_height_set = true; - if (i->style->line_height.computed == 0 && !(i->style->line_height.normal)) { - text_line_height_zero = true; - } - if (i->style->line_height.unit != SP_CSS_UNIT_NONE && !(i->style->line_height.normal)) { - text_line_height_has_units = true; - } - } - // TO DO: recursively check children - std::vector children = i->childList(false); - for (auto j: children) { - if (dynamic_cast(j) || dynamic_cast(j) || dynamic_cast(j) ) { - if (j->style && j->style->line_height.set) { - tspan_line_height_all_unset = false; - if (j->style->line_height.computed != 0 || j->style->line_height.normal) { - tspan_line_height_all_zero = false; - } else { - tspan_line_height_all_non_zero = false; - } - } - } - } - - if ( text_line_height_zero && tspan_line_height_all_non_zero) mode[0]++; - else if (!text_line_height_has_units && tspan_line_height_all_unset) mode[1]++; - else if ( text_line_height_has_units && tspan_line_height_all_unset) mode[3]++; - else if ( tspan_line_height_all_zero ) mode[2]++; - else mode[3]++; - } - } - - int activeButtonLS = 3; - if (mode[0] > 0 && mode[1] == 0 && mode[2] == 0 && mode[3] == 0) activeButtonLS = 0; - if (mode[0] == 0 && mode[1] > 0 && mode[2] == 0 && mode[3] == 0) activeButtonLS = 1; - if (mode[0] == 0 && mode[1] == 0 && mode[2] > 0 && mode[3] == 0) activeButtonLS = 2; - // std::cout << " modes: " << mode[0] - // << ", "<< mode[1] - // << ", "<< mode[2] - // << ", "<< mode[3] << std::endl; - InkSelectOneAction* textLineSpacingAction = - static_cast( g_object_get_data( tbl, "TextLineSpacingAction" ) ); - textLineSpacingAction->set_active( activeButtonLS ); - - // Enable/disable line height widget based on mode and Outer Style toggle. - if ( (activeButtonLS == 0 && outer) || // Adaptive - (activeButtonLS == 1 && !outer) || // Minimum - (activeButtonLS == 2 && !outer) // Even - ) { - gtk_action_set_sensitive (lineHeightAction, false); - } else { - gtk_action_set_sensitive (lineHeightAction, true); - } - - // In Minimum and Adaptive modes, don't allow unit change (must remain unitless). - InkSelectOneAction* textLineHeightUnitsAction = - static_cast(g_object_get_data( tbl, "TextLineHeightUnitsAction") ); - if (activeButtonLS == 0 || (activeButtonLS == 1 && outer)) { - textLineHeightUnitsAction->set_sensitive(false); - } else { - textLineHeightUnitsAction->set_sensitive(true); - } - - // Word spacing - double wordSpacing; - if (query.word_spacing.normal) wordSpacing = 0.0; - else wordSpacing = query.word_spacing.computed; // Assume no units (change in desktop-style.cpp) - - GtkAction* wordSpacingAction = GTK_ACTION( g_object_get_data( tbl, "TextWordSpacingAction" ) ); - GtkAdjustment *wordSpacingAdjustment = - ege_adjustment_action_get_adjustment(EGE_ADJUSTMENT_ACTION( wordSpacingAction )); - gtk_adjustment_set_value( wordSpacingAdjustment, wordSpacing ); - - - // Letter spacing - double letterSpacing; - if (query.letter_spacing.normal) letterSpacing = 0.0; - else letterSpacing = query.letter_spacing.computed; // Assume no units (change in desktop-style.cpp) - - GtkAction* letterSpacingAction = GTK_ACTION( g_object_get_data( tbl, "TextLetterSpacingAction" ) ); - GtkAdjustment *letterSpacingAdjustment = - ege_adjustment_action_get_adjustment(EGE_ADJUSTMENT_ACTION( letterSpacingAction )); - gtk_adjustment_set_value( letterSpacingAdjustment, letterSpacing ); - - - // Writing mode - int activeButton2 = 0; - if (query.writing_mode.computed == SP_CSS_WRITING_MODE_LR_TB) activeButton2 = 0; - if (query.writing_mode.computed == SP_CSS_WRITING_MODE_TB_RL) activeButton2 = 1; - if (query.writing_mode.computed == SP_CSS_WRITING_MODE_TB_LR) activeButton2 = 2; - - InkSelectOneAction* writingModeAction = - static_cast( g_object_get_data( tbl, "TextWritingModeAction" ) ); - writingModeAction->set_active( activeButton2 ); - - // Orientation - int activeButton3 = 0; - if (query.text_orientation.computed == SP_CSS_TEXT_ORIENTATION_MIXED ) activeButton3 = 0; - if (query.text_orientation.computed == SP_CSS_TEXT_ORIENTATION_UPRIGHT ) activeButton3 = 1; - if (query.text_orientation.computed == SP_CSS_TEXT_ORIENTATION_SIDEWAYS) activeButton3 = 2; - - InkSelectOneAction* textOrientationAction = - static_cast( g_object_get_data( tbl, "TextOrientationAction" ) ); - textOrientationAction->set_active( activeButton3 ); - - // Disable text orientation for horizontal text... - textOrientationAction->set_sensitive( activeButton2 != 0 ); - - // Direction - int activeButton4 = 0; - if (query.direction.computed == SP_CSS_DIRECTION_LTR ) activeButton4 = 0; - if (query.direction.computed == SP_CSS_DIRECTION_RTL ) activeButton4 = 1; - InkSelectOneAction* textDirectionAction = - static_cast( g_object_get_data( tbl, "TextDirectionAction" ) ); - textDirectionAction->set_active( activeButton4 ); - } - -#ifdef DEBUG_TEXT - std::cout << " GUI: fontfamily.value: " - << (query.font_family.value ? query.font_family.value : "No value") - << std::endl; - std::cout << " GUI: font_size.computed: " << query.font_size.computed << std::endl; - std::cout << " GUI: font_weight.computed: " << query.font_weight.computed << std::endl; - std::cout << " GUI: font_style.computed: " << query.font_style.computed << std::endl; - std::cout << " GUI: text_anchor.computed: " << query.text_anchor.computed << std::endl; - std::cout << " GUI: text_align.computed: " << query.text_align.computed << std::endl; - std::cout << " GUI: line_height.computed: " << query.line_height.computed - << " line_height.value: " << query.line_height.value - << " line_height.unit: " << query.line_height.unit << std::endl; - std::cout << " GUI: word_spacing.computed: " << query.word_spacing.computed - << " word_spacing.value: " << query.word_spacing.value - << " word_spacing.unit: " << query.word_spacing.unit << std::endl; - std::cout << " GUI: letter_spacing.computed: " << query.letter_spacing.computed - << " letter_spacing.value: " << query.letter_spacing.value - << " letter_spacing.unit: " << query.letter_spacing.unit << std::endl; - std::cout << " GUI: writing_mode.computed: " << query.writing_mode.computed << std::endl; -#endif - - // Kerning (xshift), yshift, rotation. NB: These are not CSS attributes. - if( SP_IS_TEXT_CONTEXT((SP_ACTIVE_DESKTOP)->event_context) ) { - Inkscape::UI::Tools::TextTool *const tc = SP_TEXT_CONTEXT((SP_ACTIVE_DESKTOP)->event_context); - if( tc ) { - unsigned char_index = -1; - TextTagAttributes *attributes = - text_tag_attributes_at_position( tc->text, std::min(tc->text_sel_start, tc->text_sel_end), &char_index ); - if( attributes ) { - - // Dx - double dx = attributes->getDx( char_index ); - GtkAction* dxAction = GTK_ACTION( g_object_get_data( tbl, "TextDxAction" )); - GtkAdjustment *dxAdjustment = - ege_adjustment_action_get_adjustment(EGE_ADJUSTMENT_ACTION( dxAction )); - gtk_adjustment_set_value( dxAdjustment, dx ); - - // Dy - double dy = attributes->getDy( char_index ); - GtkAction* dyAction = GTK_ACTION( g_object_get_data( tbl, "TextDyAction" )); - GtkAdjustment *dyAdjustment = - ege_adjustment_action_get_adjustment(EGE_ADJUSTMENT_ACTION( dyAction )); - gtk_adjustment_set_value( dyAdjustment, dy ); - - // Rotation - double rotation = attributes->getRotate( char_index ); - /* SVG value is between 0 and 360 but we're using -180 to 180 in widget */ - if( rotation > 180.0 ) rotation -= 360.0; - GtkAction* rotationAction = GTK_ACTION( g_object_get_data( tbl, "TextRotationAction" )); - GtkAdjustment *rotationAdjustment = - ege_adjustment_action_get_adjustment(EGE_ADJUSTMENT_ACTION( rotationAction )); - gtk_adjustment_set_value( rotationAdjustment, rotation ); - -#ifdef DEBUG_TEXT - std::cout << " GUI: Dx: " << dx << std::endl; - std::cout << " GUI: Dy: " << dy << std::endl; - std::cout << " GUI: Rotation: " << rotation << std::endl; -#endif - } - } - } - - { - // Set these here as we don't always have kerning/rotating attributes - GtkAction* dxAction = GTK_ACTION( g_object_get_data( tbl, "TextDxAction" )); - gtk_action_set_sensitive( GTK_ACTION(dxAction), !isFlow ); - - GtkAction* dyAction = GTK_ACTION( g_object_get_data( tbl, "TextDyAction" )); - gtk_action_set_sensitive( GTK_ACTION(dyAction), !isFlow ); - - GtkAction* rotationAction = GTK_ACTION( g_object_get_data( tbl, "TextRotationAction" )); - gtk_action_set_sensitive( GTK_ACTION(rotationAction), !isFlow ); - } - -#ifdef DEBUG_TEXT - std::cout << "sp_text_toolbox_selection_changed: exit " << count << std::endl; - std::cout << "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&" << std::endl; - std::cout << std::endl; -#endif - - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -} - -static void sp_text_toolbox_selection_modified(Inkscape::Selection *selection, guint /*flags*/, GObject *tbl) -{ - sp_text_toolbox_selection_changed (selection, tbl); -} - -static void -sp_text_toolbox_subselection_changed (gpointer /*tc*/, GObject *tbl) -{ - sp_text_toolbox_selection_changed (NULL, tbl, true); -} - -// TODO: possibly share with font-selector by moving most code to font-lister (passing family name) -static void sp_text_toolbox_select_cb( GtkEntry* entry, GtkEntryIconPosition /*position*/, GdkEvent /*event*/, gpointer /*data*/ ) { - - Glib::ustring family = gtk_entry_get_text ( entry ); - //std::cout << "text_toolbox_missing_font_cb: selecting: " << family << std::endl; - - // Get all items with matching font-family set (not inherited!). - std::vector selectList; - - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - SPDocument *document = desktop->getDocument(); - std::vector x,y; - std::vector allList = get_all_items(x, document->getRoot(), desktop, false, false, true, y); - for(std::vector::const_reverse_iterator i=allList.rbegin();i!=allList.rend(); ++i){ - SPItem *item = *i; - SPStyle *style = item->style; - - if (style) { - - Glib::ustring family_style; - if (style->font_family.set) { - family_style = style->font_family.value; - //std::cout << " family style from font_family: " << family_style << std::endl; - } - else if (style->font_specification.set) { - family_style = style->font_specification.value; - //std::cout << " family style from font_spec: " << family_style << std::endl; - } - - if (family_style.compare( family ) == 0 ) { - //std::cout << " found: " << item->getId() << std::endl; - selectList.push_back(item); - } - } - } - - // Update selection - Inkscape::Selection *selection = desktop->getSelection(); - selection->clear(); - //std::cout << " list length: " << g_slist_length ( selectList ) << std::endl; - selection->setList(selectList); -} - -static void text_toolbox_watch_ec(SPDesktop* dt, Inkscape::UI::Tools::ToolBase* ec, GObject* holder); - -// Define all the "widgets" in the toolbar. -void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - GtkIconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1); - - /* Font family */ - { - // Font list - Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance(); - fontlister->update_font_list( SP_ACTIVE_DESKTOP->getDocument()); - Glib::RefPtr store = fontlister->get_font_list(); - GtkListStore* model = store->gobj(); - - Ink_ComboBoxEntry_Action* act = - ink_comboboxentry_action_new( "TextFontFamilyAction", - _("Font Family"), - _("Select Font Family (Alt-X to access)"), - NULL, - GTK_TREE_MODEL(model), - -1, // Entry width - 50, // Extra list width - (gpointer)font_lister_cell_data_func2, // Cell layout - (gpointer)font_lister_separator_func2, - GTK_WIDGET(desktop->canvas)); // Focus widget - ink_comboboxentry_action_popup_enable( act ); // Enable entry completion - - gchar *const info = _("Select all text with this font-family"); - ink_comboboxentry_action_set_info( act, info ); // Show selection icon - ink_comboboxentry_action_set_info_cb( act, (gpointer)sp_text_toolbox_select_cb ); - - gchar *const warning = _("Font not found on system"); - ink_comboboxentry_action_set_warning( act, warning ); // Show icon w/ tooltip if font missing - ink_comboboxentry_action_set_warning_cb( act, (gpointer)sp_text_toolbox_select_cb ); - - //ink_comboboxentry_action_set_warning_callback( act, sp_text_fontfamily_select_all ); - ink_comboboxentry_action_set_altx_name( act, "altx-text" ); // Set Alt-X keyboard shortcut - g_signal_connect( G_OBJECT(act), "changed", G_CALLBACK(sp_text_fontfamily_value_changed), holder ); - gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); - g_object_set_data( holder, "TextFontFamilyAction", act ); - - // Change style of drop-down from menu to list - auto css_provider = gtk_css_provider_new(); - gtk_css_provider_load_from_data(css_provider, - "#TextFontFamilyAction_combobox {\n" - " -GtkComboBox-appears-as-list: true;\n" - "}\n", - -1, NULL); - - auto screen = gdk_screen_get_default(); - gtk_style_context_add_provider_for_screen(screen, - GTK_STYLE_PROVIDER(css_provider), - GTK_STYLE_PROVIDER_PRIORITY_USER); - } - - /* Font size */ - { - // List of font sizes for drop-down menu - GtkListStore* model_size = gtk_list_store_new( 1, G_TYPE_STRING ); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - int unit = prefs->getInt("/options/font/unitType", SP_CSS_UNIT_PT); - - sp_text_set_sizes(model_size, unit); - - Glib::ustring tooltip = Glib::ustring::format(_("Font size"), " (", sp_style_get_css_unit_string(unit), ")"); - - Ink_ComboBoxEntry_Action* act = ink_comboboxentry_action_new( "TextFontSizeAction", - _("Font Size"), - _(tooltip.c_str()), - NULL, - GTK_TREE_MODEL(model_size), - 8, // Width in characters - 0, // Extra list width - NULL, // Cell layout - NULL, // Separator - GTK_WIDGET(desktop->canvas)); // Focus widget - - g_signal_connect( G_OBJECT(act), "changed", G_CALLBACK(sp_text_fontsize_value_changed), holder ); - gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); - g_object_set_data( holder, "TextFontSizeAction", act ); - } - - /* Font styles */ - { - Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance(); - Glib::RefPtr store = fontlister->get_style_list(); - GtkListStore* model_style = store->gobj(); - - Ink_ComboBoxEntry_Action* act = ink_comboboxentry_action_new( "TextFontStyleAction", - _("Font Style"), - _("Font style"), - NULL, - GTK_TREE_MODEL(model_style), - 12, // Width in characters - 0, // Extra list width - NULL, // Cell layout - NULL, // Separator - GTK_WIDGET(desktop->canvas)); // Focus widget - - g_signal_connect( G_OBJECT(act), "changed", G_CALLBACK(sp_text_fontstyle_value_changed), holder ); - gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); - g_object_set_data( holder, "TextFontStyleAction", act ); - } - - /* Style - Superscript */ - { - InkToggleAction* act = ink_toggle_action_new( "TextSuperscriptAction", // Name - _("Toggle Superscript"), // Label - _("Toggle superscript"), // Tooltip - "text_superscript", // Icon (inkId) - secondarySize ); // Icon size - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_text_script_changed), holder ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/text/super", false) ); - g_object_set_data( holder, "TextSuperscriptAction", act ); - } - - /* Style - Subscript */ - { - InkToggleAction* act = ink_toggle_action_new( "TextSubscriptAction", // Name - _("Toggle Subscript"), // Label - _("Toggle subscript"), // Tooltip - "text_subscript", // Icon (inkId) - secondarySize ); // Icon size - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_text_script_changed), holder ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/text/sub", false) ); - g_object_set_data( holder, "TextSubscriptAction", act ); - } - - /* Alignment */ - { - InkSelectOneActionColumns columns; - - Glib::RefPtr store = Gtk::ListStore::create(columns); - - Gtk::TreeModel::Row row; - - row = *(store->append()); - row[columns.col_label ] = _("Align left"); - row[columns.col_tooltip ] = _("Align left"); - row[columns.col_icon ] = INKSCAPE_ICON("format-justify-left"); - row[columns.col_sensitive] = true; - - row = *(store->append()); - row[columns.col_label ] = _("Align center"); - row[columns.col_tooltip ] = _("Align center"); - row[columns.col_icon ] = INKSCAPE_ICON("format-justify-center"); - row[columns.col_sensitive] = true; - - row = *(store->append()); - row[columns.col_label ] = _("Align right"); - row[columns.col_tooltip ] = _("Align right"); - row[columns.col_icon ] = INKSCAPE_ICON("format-justify-right"); - row[columns.col_sensitive] = true; - - row = *(store->append()); - row[columns.col_label ] = _("Justify"); - row[columns.col_tooltip ] = _("Justify (only flowed text)"); - row[columns.col_icon ] = INKSCAPE_ICON("format-justify-fill"); - row[columns.col_sensitive] = false; - - InkSelectOneAction* act = - InkSelectOneAction::create( "TextAlignAction", // Name - _("Alignment"), // Label - _("Text alignment"), // Tooltip - "Not Used", // Icon - store ); // Tree store - act->use_radio( false ); - act->use_label( false ); - gint mode = prefs->getInt("/tools/text/align_mode", 0); - act->set_active( mode ); - - gtk_action_group_add_action( mainActions, GTK_ACTION( act->gobj() )); - g_object_set_data( holder, "TextAlignAction", act ); - - act->signal_changed().connect(sigc::bind<0>(sigc::ptr_fun(&sp_text_align_mode_changed), holder)); - } - - /* Writing mode (Horizontal, Vertical-LR, Vertical-RL) */ - { - InkSelectOneActionColumns columns; - - Glib::RefPtr store = Gtk::ListStore::create(columns); - - Gtk::TreeModel::Row row; - - row = *(store->append()); - row[columns.col_label ] = _("Horizontal"); - row[columns.col_tooltip ] = _("Horizontal text"); - row[columns.col_icon ] = INKSCAPE_ICON("format-text-direction-horizontal"); - row[columns.col_sensitive] = true; - - row = *(store->append()); - row[columns.col_label ] = _("Vertical — RL"); - row[columns.col_tooltip ] = _("Vertical text — lines: right to left"); - row[columns.col_icon ] = INKSCAPE_ICON("format-text-direction-vertical"); - row[columns.col_sensitive] = true; - - row = *(store->append()); - row[columns.col_label ] = _("Vertical — LR"); - row[columns.col_tooltip ] = _("Vertical text — lines: left to right"); - row[columns.col_icon ] = INKSCAPE_ICON("format-text-direction-vertical-lr"); - row[columns.col_sensitive] = true; - - InkSelectOneAction* act = - InkSelectOneAction::create( "TextWritingModeAction", // Name - _("Writing mode"), // Label - _("Block progression"), // Tooltip - "Not Used", // Icon - store ); // Tree store - act->use_radio( false ); - act->use_label( false ); - gint mode = prefs->getInt("/tools/text/writing_mode", 0); - act->set_active( mode ); - - gtk_action_group_add_action( mainActions, GTK_ACTION( act->gobj() )); - g_object_set_data( holder, "TextWritingModeAction", act ); - - act->signal_changed().connect(sigc::bind<0>(sigc::ptr_fun(&sp_writing_mode_changed), holder)); - } - - /* Text (glyph) orientation (Auto (mixed), Upright, Sideways) */ - { - InkSelectOneActionColumns columns; - - Glib::RefPtr store = Gtk::ListStore::create(columns); - - Gtk::TreeModel::Row row; - - row = *(store->append()); - row[columns.col_label ] = _("Auto"); - row[columns.col_tooltip ] = _("Auto glyph orientation"); - row[columns.col_icon ] = INKSCAPE_ICON("text-orientation-auto"); - row[columns.col_sensitive] = true; - - row = *(store->append()); - row[columns.col_label ] = _("Upright"); - row[columns.col_tooltip ] = _("Upright glyph orientation"); - row[columns.col_icon ] = INKSCAPE_ICON("text-orientation-upright"); - row[columns.col_sensitive] = true; - - row = *(store->append()); - row[columns.col_label ] = _("Sideways"); - row[columns.col_tooltip ] = _("Sideways glyph orientation"); - row[columns.col_icon ] = INKSCAPE_ICON("text-orientation-sideways"); - row[columns.col_sensitive] = true; - - InkSelectOneAction* act = - InkSelectOneAction::create( "TextOrientationAction", // Name - _("Text orientation"), // Label - _("Text (glyph) orientation in vertical text."), // Tooltip - "Not Used", // Icon - store ); // List store - act->use_radio( false ); - act->use_label( false ); - gint mode = prefs->getInt("/tools/text/text_orientation", 0); - act->set_active( mode ); - - gtk_action_group_add_action( mainActions, GTK_ACTION( act->gobj() )); - g_object_set_data( holder, "TextOrientationAction", act ); - - act->signal_changed().connect(sigc::bind<0>(sigc::ptr_fun(&sp_text_orientation_changed), holder)); - } - - - // Text direction (predominant direction of horizontal text). - { - InkSelectOneActionColumns columns; - - Glib::RefPtr store = Gtk::ListStore::create(columns); - - Gtk::TreeModel::Row row; - - row = *(store->append()); - row[columns.col_label ] = _("LTR"); - row[columns.col_tooltip ] = _("Left to right text"); - row[columns.col_icon ] = INKSCAPE_ICON("format-text-direction-horizontal"); - row[columns.col_sensitive] = true; - - row = *(store->append()); - row[columns.col_label ] = _("RTL"); - row[columns.col_tooltip ] = _("Right to left text"); - row[columns.col_icon ] = INKSCAPE_ICON("format-text-direction-r2l"); - row[columns.col_sensitive] = true; - - InkSelectOneAction* act = - InkSelectOneAction::create( "TextDirectionAction", // Name - _("Text direction"), // Label - _("Text direction for normally horizontal text."), // Tooltip - "Not Used", // Icon - store ); // List store - act->use_radio( false ); - act->use_label( false ); - gint mode = prefs->getInt("/tools/text/text_direction", 0); - act->set_active( mode ); - - gtk_action_group_add_action( mainActions, GTK_ACTION( act->gobj() )); - g_object_set_data( holder, "TextDirectionAction", act ); - - act->signal_changed_after().connect(sigc::bind<0>(sigc::ptr_fun(&sp_text_direction_changed), holder)); - } - - /* Line height unit tracker */ - UnitTracker* tracker = new UnitTracker(Inkscape::Util::UNIT_TYPE_LINEAR); - tracker->prependUnit(unit_table.getUnit("")); // No unit - tracker->addUnit(unit_table.getUnit("%")); - tracker->addUnit(unit_table.getUnit("em")); - tracker->addUnit(unit_table.getUnit("ex")); - tracker->setActiveUnit(unit_table.getUnit("%")); - g_object_set_data( holder, "tracker", tracker ); - - /* Line height */ - { - // Drop down menu - gchar const* labels[] = {_("Smaller spacing"), 0, 0, 0, 0, C_("Text tool", "Normal"), 0, 0, 0, 0, 0, _("Larger spacing")}; - gdouble values[] = { 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1,2, 1.3, 1.4, 1.5, 2.0}; - - EgeAdjustmentAction *eact = create_adjustment_action( - "TextLineHeightAction", /* name */ - _("Line Height"), /* label */ - _("Line:"), /* short label */ - _("Spacing between baselines"), /* tooltip */ - "/tools/text/lineheight", /* preferences path */ - 0.0, /* default */ - GTK_WIDGET(desktop->canvas), /* focusTarget */ - holder, /* dataKludge */ - FALSE, /* set alt-x keyboard shortcut? */ - NULL, /* altx_mark */ - 0.0, 1000.0, 0.1, 1.0, /* lower, upper, step (arrow up/down), page up/down */ - labels, values, G_N_ELEMENTS(labels), /* drop down menu */ - sp_text_lineheight_value_changed, /* callback */ - NULL, // tracker, /* unit tracker */ - 0.1, /* step (used?) */ - 2, /* digits to show */ - 1.0 /* factor (multiplies default) */ - ); - //tracker->addAdjustment( ege_adjustment_action_get_adjustment(eact) ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - g_object_set_data( holder, "TextLineHeightAction", eact ); - g_object_set( G_OBJECT(eact), "iconId", "text_line_spacing", NULL ); - } - - /* Line height units */ - { - InkSelectOneAction* act = tracker->createAction( "TextLineHeightUnitsAction", _("Units"), ("") ); - gtk_action_group_add_action( mainActions, act->gobj() ); - act->signal_changed_after().connect(sigc::bind<0>(sigc::ptr_fun(&sp_text_lineheight_unit_changed), holder)); - g_object_set_data( holder, "TextLineHeightUnitsAction", act ); - } - - /* Line spacing mode */ - { - InkSelectOneActionColumns columns; - - Glib::RefPtr store = Gtk::ListStore::create(columns); - - Gtk::TreeModel::Row row; - - row = *(store->append()); - row[columns.col_label ] = _("Adaptive"); - row[columns.col_tooltip ] = _("Line spacing adapts to font size."); - row[columns.col_icon ] = INKSCAPE_ICON("text_line_spacing"); - row[columns.col_sensitive] = true; - - row = *(store->append()); - row[columns.col_label ] = _("Minimum"); - row[columns.col_tooltip ] = _("Line spacing adapts to fonts size with set minimum spacing."); - row[columns.col_icon ] = INKSCAPE_ICON("text_line_spacing"); - row[columns.col_sensitive] = true; - row = *(store->append()); - row[columns.col_label ] = _("Even"); - row[columns.col_tooltip ] = _("Lines evenly spaced."); - row[columns.col_icon ] = INKSCAPE_ICON("text_line_spacing"); - row[columns.col_sensitive] = true; - - row = *(store->append()); - row[columns.col_label ] = _("Adjustable ☠"); - row[columns.col_tooltip ] = _("Line spacing fully adjustable"); - row[columns.col_icon ] = INKSCAPE_ICON("text_line_spacing"); - row[columns.col_sensitive] = true; - - InkSelectOneAction* act = - InkSelectOneAction::create( "TextLineSpacingAction", // Name - _("Line Spacing Mode"), // Label - _("How should multiple baselines be spaced?\n Adaptive: Line spacing adapts to font size.\n Minimum: Like Adaptive, but with a set minimum.\n Even: Evenly spaced.\n Adjustable: No restrictions."), // Tooltip - "Not Used", // Icon - store ); // Tree store - act->use_radio( false ); - act->use_label( true ); - gint mode = prefs->getInt("/tools/text/line_spacing_mode", 0); - act->set_active( mode ); - - gtk_action_group_add_action( mainActions, GTK_ACTION( act->gobj() )); - g_object_set_data( holder, "TextLineSpacingAction", act ); - - act->signal_changed().connect(sigc::bind<0>(sigc::ptr_fun(&sp_text_line_spacing_mode_changed), holder)); - } - - /* Word spacing */ - { - // Drop down menu - gchar const* labels[] = {_("Negative spacing"), 0, 0, 0, C_("Text tool", "Normal"), 0, 0, 0, 0, 0, 0, 0, _("Positive spacing")}; - gdouble values[] = {-2.0, -1.5, -1.0, -0.5, 0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 4.0, 5.0}; - - EgeAdjustmentAction *eact = create_adjustment_action( - "TextWordSpacingAction", /* name */ - _("Word spacing"), /* label */ - _("Word:"), /* short label */ - _("Spacing between words (px)"), /* tooltip */ - "/tools/text/wordspacing", /* preferences path */ - 0.0, /* default */ - GTK_WIDGET(desktop->canvas), /* focusTarget */ - holder, /* dataKludge */ - FALSE, /* set alt-x keyboard shortcut? */ - NULL, /* altx_mark */ - -100.0, 100.0, 0.01, 0.10, /* lower, upper, step (arrow up/down), page up/down */ - labels, values, G_N_ELEMENTS(labels), /* drop down menu */ - sp_text_wordspacing_value_changed, /* callback */ - NULL, /* unit tracker */ - 0.1, /* step (used?) */ - 2, /* digits to show */ - 1.0 /* factor (multiplies default) */ - ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - g_object_set_data( holder, "TextWordSpacingAction", eact ); - g_object_set( G_OBJECT(eact), "iconId", "text_word_spacing", NULL ); - } - - /* Letter spacing */ - { - // Drop down menu - gchar const* labels[] = {_("Negative spacing"), 0, 0, 0, C_("Text tool", "Normal"), 0, 0, 0, 0, 0, 0, 0, _("Positive spacing")}; - gdouble values[] = {-2.0, -1.5, -1.0, -0.5, 0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 4.0, 5.0}; - - EgeAdjustmentAction *eact = create_adjustment_action( - "TextLetterSpacingAction", /* name */ - _("Letter spacing"), /* label */ - _("Letter:"), /* short label */ - _("Spacing between letters (px)"), /* tooltip */ - "/tools/text/letterspacing", /* preferences path */ - 0.0, /* default */ - GTK_WIDGET(desktop->canvas), /* focusTarget */ - holder, /* dataKludge */ - FALSE, /* set alt-x keyboard shortcut? */ - NULL, /* altx_mark */ - -100.0, 100.0, 0.01, 0.10, /* lower, upper, step (arrow up/down), page up/down */ - labels, values, G_N_ELEMENTS(labels), /* drop down menu */ - sp_text_letterspacing_value_changed, /* callback */ - NULL, /* unit tracker */ - 0.1, /* step (used?) */ - 2, /* digits to show */ - 1.0 /* factor (multiplies default) */ - ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - g_object_set_data( holder, "TextLetterSpacingAction", eact ); - g_object_set( G_OBJECT(eact), "iconId", "text_letter_spacing", NULL ); - } - - /* Character kerning (horizontal shift) */ - { - // Drop down menu - gchar const* labels[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - gdouble values[] = { -2.0, -1.5, -1.0, -0.5, 0, 0.5, 1.0, 1.5, 2.0, 2.5 }; - - EgeAdjustmentAction *eact = create_adjustment_action( - "TextDxAction", /* name */ - _("Kerning"), /* label */ - _("Kern:"), /* short label */ - _("Horizontal kerning (px)"), /* tooltip */ - "/tools/text/dx", /* preferences path */ - 0.0, /* default */ - GTK_WIDGET(desktop->canvas), /* focusTarget */ - holder, /* dataKludge */ - FALSE, /* set alt-x keyboard shortcut? */ - NULL, /* altx_mark */ - -100.0, 100.0, 0.01, 0.1, /* lower, upper, step (arrow up/down), page up/down */ - labels, values, G_N_ELEMENTS(labels), /* drop down menu */ - sp_text_dx_value_changed, /* callback */ - NULL, /* unit tracker */ - 0.1, /* step (used?) */ - 2, /* digits to show */ - 1.0 /* factor (multiplies default) */ - ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - g_object_set_data( holder, "TextDxAction", eact ); - g_object_set( G_OBJECT(eact), "iconId", "text_horz_kern", NULL ); - } - - /* Character vertical shift */ - { - // Drop down menu - gchar const* labels[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - gdouble values[] = { -2.0, -1.5, -1.0, -0.5, 0, 0.5, 1.0, 1.5, 2.0, 2.5 }; - - EgeAdjustmentAction *eact = create_adjustment_action( - "TextDyAction", /* name */ - _("Vertical Shift"), /* label */ - _("Vert:"), /* short label */ - _("Vertical shift (px)"), /* tooltip */ - "/tools/text/dy", /* preferences path */ - 0.0, /* default */ - GTK_WIDGET(desktop->canvas), /* focusTarget */ - holder, /* dataKludge */ - FALSE, /* set alt-x keyboard shortcut? */ - NULL, /* altx_mark */ - -100.0, 100.0, 0.01, 0.1, /* lower, upper, step (arrow up/down), page up/down */ - labels, values, G_N_ELEMENTS(labels), /* drop down menu */ - sp_text_dy_value_changed, /* callback */ - NULL, /* unit tracker */ - 0.1, /* step (used?) */ - 2, /* digits to show */ - 1.0 /* factor (multiplies default) */ - ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - g_object_set_data( holder, "TextDyAction", eact ); - g_object_set( G_OBJECT(eact), "iconId", "text_vert_kern", NULL ); - } - - /* Character rotation */ - { - // Drop down menu - gchar const* labels[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - gdouble values[] = { -90, -45, -30, -15, 0, 15, 30, 45, 90, 180 }; - - EgeAdjustmentAction *eact = create_adjustment_action( - "TextRotationAction", /* name */ - _("Letter rotation"), /* label */ - _("Rot:"), /* short label */ - _("Character rotation (degrees)"), /* tooltip */ - "/tools/text/rotation", /* preferences path */ - 0.0, /* default */ - GTK_WIDGET(desktop->canvas), /* focusTarget */ - holder, /* dataKludge */ - FALSE, /* set alt-x keyboard shortcut? */ - NULL, /* altx_mark */ - -180.0, 180.0, 0.1, 1.0, /* lower, upper, step (arrow up/down), page up/down */ - labels, values, G_N_ELEMENTS(labels), /* drop down menu */ - sp_text_rotation_value_changed, /* callback */ - NULL, /* unit tracker */ - 0.1, /* step (used?) */ - 2, /* digits to show */ - 1.0 /* factor (multiplies default) */ - ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - g_object_set_data( holder, "TextRotationAction", eact ); - g_object_set( G_OBJECT(eact), "iconId", "text_rotation", NULL ); - } - - /* Text line height unset */ - { - InkToggleAction* act = ink_toggle_action_new( "TextLineHeightUnsetAction", // Name - _("Unset line height"), // Label - _("If enabled, line height is set on part of selection. Click to unset."), - INKSCAPE_ICON("paint-unknown"), - secondarySize ); // Icon size - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_text_lineheight_unset_changed), holder ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/text/line_height_unset", false) ); - g_object_set_data( holder, "TextLineHeightUnsetAction", act ); - } - - /* Text outer style */ - { - InkToggleAction* act = ink_toggle_action_new( "TextOuterStyleAction", // Name - _("Show outer style"), // Label - _("Show style of outermost text element. The 'font-size' and 'line-height' values of the outermost text element determine the minimum line spacing in the block."), - INKSCAPE_ICON("text_outer_style"), - secondarySize ); // Icon size - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_text_outer_style_changed), holder ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/text/outer_style", false) ); - g_object_set_data( holder, "TextOuterStyleAction", act ); - } - - // Is this necessary to call? Shouldn't hurt. - sp_text_toolbox_selection_changed(desktop->getSelection(), holder); - - desktop->connectEventContextChanged(sigc::bind(sigc::ptr_fun(text_toolbox_watch_ec), holder)); - - g_signal_connect( holder, "destroy", G_CALLBACK(purge_repr_listener), holder ); - -} - -static void text_toolbox_watch_ec(SPDesktop* desktop, Inkscape::UI::Tools::ToolBase* ec, GObject* holder) { - using sigc::connection; - using sigc::bind; - using sigc::ptr_fun; - - static connection c_selection_changed; - static connection c_selection_modified; - static connection c_subselection_changed; - - if (SP_IS_TEXT_CONTEXT(ec)) { - // Watch selection - - // Ensure FontLister is updated here first.................. VVVVV - c_selection_changed = desktop->getSelection()->connectChangedFirst(bind(ptr_fun(sp_text_toolbox_selection_changed), holder, false)); - c_selection_modified = desktop->getSelection()->connectModifiedFirst(bind(ptr_fun(sp_text_toolbox_selection_modified), holder)); - c_subselection_changed = desktop->connectToolSubselectionChanged(bind(ptr_fun(sp_text_toolbox_subselection_changed), holder)); - } else { - if (c_selection_changed) - c_selection_changed.disconnect(); - if (c_selection_modified) - c_selection_modified.disconnect(); - if (c_subselection_changed) - c_subselection_changed.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:fileencoding=utf-8 : diff --git a/src/widgets/text-toolbar.h b/src/widgets/text-toolbar.h deleted file mode 100644 index 86a1cad21..000000000 --- a/src/widgets/text-toolbar.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef SEEN_TEXT_TOOLBAR_H -#define SEEN_TEXT_TOOLBAR_H - -/** - * @file - * Text aux toolbar - */ -/* Authors: - * MenTaLguY - * Lauris Kaplinski - * bulia byak - * Frank Felfe - * John Cliff - * David Turner - * Josh Andler - * Jon A. Cruz - * Maximilian Albert - * Tavmjong Bah - * Abhishek Sharma - * Kris De Gussem - * - * Copyright (C) 2004 David Turner - * Copyright (C) 2003 MenTaLguY - * Copyright (C) 1999-2011 authors - * Copyright (C) 2001-2002 Ximian, Inc. - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -class SPDesktop; - -typedef struct _GtkActionGroup GtkActionGroup; -typedef struct _GObject GObject; - -void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); - -#endif /* !SEEN_TEXT_TOOLBAR_H */ diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index 5894391ff..af2fcf26f 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -69,31 +69,31 @@ #include "xml/attribute-record.h" #include "xml/node-event-vector.h" -#include "arc-toolbar.h" -#include "box3d-toolbar.h" -#include "calligraphy-toolbar.h" -#include "connector-toolbar.h" -#include "dropper-toolbar.h" -#include "eraser-toolbar.h" -#include "gradient-toolbar.h" -#include "lpe-toolbar.h" -#include "mesh-toolbar.h" -#include "measure-toolbar.h" -#include "node-toolbar.h" -#include "rect-toolbar.h" +#include "ui/toolbar/arc-toolbar.h" +#include "ui/toolbar/box3d-toolbar.h" +#include "ui/toolbar/calligraphy-toolbar.h" +#include "ui/toolbar/connector-toolbar.h" +#include "ui/toolbar/dropper-toolbar.h" +#include "ui/toolbar/eraser-toolbar.h" +#include "ui/toolbar/gradient-toolbar.h" +#include "ui/toolbar/lpe-toolbar.h" +#include "ui/toolbar/mesh-toolbar.h" +#include "ui/toolbar/measure-toolbar.h" +#include "ui/toolbar/node-toolbar.h" +#include "ui/toolbar/rect-toolbar.h" #if HAVE_POTRACE -# include "paintbucket-toolbar.h" +# include "ui/toolbar/paintbucket-toolbar.h" #endif -#include "pencil-toolbar.h" -#include "select-toolbar.h" -#include "spray-toolbar.h" -#include "spiral-toolbar.h" -#include "star-toolbar.h" -#include "tweak-toolbar.h" -#include "text-toolbar.h" -#include "zoom-toolbar.h" +#include "ui/toolbar/pencil-toolbar.h" +#include "ui/toolbar/select-toolbar.h" +#include "ui/toolbar/spray-toolbar.h" +#include "ui/toolbar/spiral-toolbar.h" +#include "ui/toolbar/star-toolbar.h" +#include "ui/toolbar/tweak-toolbar.h" +#include "ui/toolbar/text-toolbar.h" +#include "ui/toolbar/zoom-toolbar.h" #include "toolbox.h" diff --git a/src/widgets/tweak-toolbar.cpp b/src/widgets/tweak-toolbar.cpp deleted file mode 100644 index 173e99479..000000000 --- a/src/widgets/tweak-toolbar.cpp +++ /dev/null @@ -1,387 +0,0 @@ -/** - * @file - * Tweak aux toolbar - */ -/* Authors: - * MenTaLguY - * Lauris Kaplinski - * bulia byak - * Frank Felfe - * John Cliff - * David Turner - * Josh Andler - * Jon A. Cruz - * Maximilian Albert - * Tavmjong Bah - * Abhishek Sharma - * Kris De Gussem - * - * Copyright (C) 2004 David Turner - * Copyright (C) 2003 MenTaLguY - * Copyright (C) 1999-2011 authors - * Copyright (C) 2001-2002 Ximian, Inc. - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include "tweak-toolbar.h" - -#include "desktop.h" -#include "document-undo.h" - -#include "ui/icon-names.h" -#include "ui/tools/tweak-tool.h" -#include "ui/widget/ink-select-one-action.h" -#include "ui/widget/spinbutton.h" - -#include "widgets/ege-adjustment-action.h" -#include "widgets/ege-output-action.h" -#include "widgets/ink-radio-action.h" -#include "widgets/ink-toggle-action.h" -#include "widgets/toolbox.h" - -using Inkscape::DocumentUndo; -using Inkscape::UI::ToolboxFactory; -using Inkscape::UI::PrefPusher; - - -//######################## -//## Tweak ## -//######################## - -static void sp_tweak_width_value_changed( GtkAdjustment *adj, GObject * /*tbl*/ ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble( "/tools/tweak/width", - gtk_adjustment_get_value(adj) * 0.01 ); -} - -static void sp_tweak_force_value_changed( GtkAdjustment *adj, GObject * /*tbl*/ ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble( "/tools/tweak/force", - gtk_adjustment_get_value(adj) * 0.01 ); -} - -static void sp_tweak_pressure_state_changed( GtkToggleAction *act, gpointer /*data*/ ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setBool("/tools/tweak/usepressure", gtk_toggle_action_get_active(act)); -} - -static void sp_tweak_mode_changed( GObject *tbl, int mode ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setInt("/tools/tweak/mode", mode); - - static gchar const* names[] = {"tweak_doh", "tweak_dos", "tweak_dol", "tweak_doo", "tweak_channels_label"}; - bool flag = ((mode == Inkscape::UI::Tools::TWEAK_MODE_COLORPAINT) || - (mode == Inkscape::UI::Tools::TWEAK_MODE_COLORJITTER)); - for (size_t i = 0; i < G_N_ELEMENTS(names); ++i) { - GtkAction *act = GTK_ACTION(g_object_get_data( tbl, names[i] )); - if (act) { - gtk_action_set_visible(act, flag); - } - } - GtkAction *fid = GTK_ACTION(g_object_get_data( tbl, "tweak_fidelity")); - if (fid) { - gtk_action_set_visible(fid, !flag); - } -} - -static void sp_tweak_fidelity_value_changed( GtkAdjustment *adj, GObject * /*tbl*/ ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble( "/tools/tweak/fidelity", - gtk_adjustment_get_value(adj) * 0.01 ); -} - -static void tweak_toggle_doh(GtkToggleAction *act, gpointer /*data*/) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setBool("/tools/tweak/doh", gtk_toggle_action_get_active(act)); -} -static void tweak_toggle_dos(GtkToggleAction *act, gpointer /*data*/) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setBool("/tools/tweak/dos", gtk_toggle_action_get_active(act)); -} -static void tweak_toggle_dol(GtkToggleAction *act, gpointer /*data*/) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setBool("/tools/tweak/dol", gtk_toggle_action_get_active(act)); -} -static void tweak_toggle_doo(GtkToggleAction *act, gpointer /*data*/) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setBool("/tools/tweak/doo", gtk_toggle_action_get_active(act)); -} - -void sp_tweak_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) -{ - GtkIconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - - { - /* Width */ - gchar const* labels[] = {_("(pinch tweak)"), 0, 0, 0, _("(default)"), 0, 0, 0, 0, _("(broad tweak)")}; - gdouble values[] = {1, 3, 5, 10, 15, 20, 30, 50, 75, 100}; - EgeAdjustmentAction *eact = create_adjustment_action( "TweakWidthAction", - _("Width"), _("Width:"), _("The width of the tweak area (relative to the visible canvas area)"), - "/tools/tweak/width", 15, - GTK_WIDGET(desktop->canvas), holder, TRUE, "altx-tweak", - 1, 100, 1.0, 10.0, - labels, values, G_N_ELEMENTS(labels), - sp_tweak_width_value_changed, NULL /*unit tracker*/, 0.01, 0, 100 ); - ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - } - - - { - /* Force */ - gchar const* labels[] = {_("(minimum force)"), 0, 0, _("(default)"), 0, 0, 0, _("(maximum force)")}; - gdouble values[] = {1, 5, 10, 20, 30, 50, 70, 100}; - EgeAdjustmentAction *eact = create_adjustment_action( "TweakForceAction", - _("Force"), _("Force:"), _("The force of the tweak action"), - "/tools/tweak/force", 20, - GTK_WIDGET(desktop->canvas), holder, TRUE, "tweak-force", - 1, 100, 1.0, 10.0, - labels, values, G_N_ELEMENTS(labels), - sp_tweak_force_value_changed, NULL /*unit tracker*/, 0.01, 0, 100 ); - ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - } - - /* Mode */ - { - InkSelectOneActionColumns columns; - - Glib::RefPtr store = Gtk::ListStore::create(columns); - - Gtk::TreeModel::Row row; - - row = *(store->append()); - row[columns.col_label ] = _("Move mode"); - row[columns.col_tooltip ] = _("Move objects in any direction"); - row[columns.col_icon ] = INKSCAPE_ICON("object-tweak-push"); - row[columns.col_sensitive] = true; - - row = *(store->append()); - row[columns.col_label ] = _("Move in/out mode"); - row[columns.col_tooltip ] = _("Move objects towards cursor; with Shift from cursor"); - row[columns.col_icon ] = INKSCAPE_ICON("object-tweak-attract"); - row[columns.col_sensitive] = true; - - row = *(store->append()); - row[columns.col_label ] = _("Move jitter mode"); - row[columns.col_tooltip ] = _("Move objects in random directions"); - row[columns.col_icon ] = INKSCAPE_ICON("object-tweak-randomize"); - row[columns.col_sensitive] = true; - - row = *(store->append()); - row[columns.col_label ] = _("Scale mode"); - row[columns.col_tooltip ] = _("Shrink objects, with Shift enlarge"); - row[columns.col_icon ] = INKSCAPE_ICON("object-tweak-shrink"); - row[columns.col_sensitive] = true; - - row = *(store->append()); - row[columns.col_label ] = _("Rotate mode"); - row[columns.col_tooltip ] = _("Rotate objects, with Shift counterclockwise"); - row[columns.col_icon ] = INKSCAPE_ICON("object-tweak-rotate"); - row[columns.col_sensitive] = true; - - row = *(store->append()); - row[columns.col_label ] = _("Duplicate/delete mode"); - row[columns.col_tooltip ] = _("Duplicate objects, with Shift delete"); - row[columns.col_icon ] = INKSCAPE_ICON("object-tweak-duplicate"); - row[columns.col_sensitive] = true; - - row = *(store->append()); - row[columns.col_label ] = _("Push mode"); - row[columns.col_tooltip ] = _("Push parts of paths in any direction"); - row[columns.col_icon ] = INKSCAPE_ICON("path-tweak-push"); - row[columns.col_sensitive] = true; - - row = *(store->append()); - row[columns.col_label ] = _("Shrink/grow mode"); - row[columns.col_tooltip ] = _("Shrink (inset) parts of paths; with Shift grow (outset)"); - row[columns.col_icon ] = INKSCAPE_ICON("path-tweak-shrink"); - row[columns.col_sensitive] = true; - - row = *(store->append()); - row[columns.col_label ] = _("Attract/repel mode"); - row[columns.col_tooltip ] = _("Attract parts of paths towards cursor; with Shift from cursor"); - row[columns.col_icon ] = INKSCAPE_ICON("path-tweak-attract"); - row[columns.col_sensitive] = true; - - row = *(store->append()); - row[columns.col_label ] = _("Roughen mode"); - row[columns.col_tooltip ] = _("Roughen parts of paths"); - row[columns.col_icon ] = INKSCAPE_ICON("path-tweak-roughen"); - row[columns.col_sensitive] = true; - - row = *(store->append()); - row[columns.col_label ] = _("Color paint mode"); - row[columns.col_tooltip ] = _("Paint the tool's color upon selected objects"); - row[columns.col_icon ] = INKSCAPE_ICON("object-tweak-paint"); - row[columns.col_sensitive] = true; - - row = *(store->append()); - row[columns.col_label ] = _("Color jitter mode"); - row[columns.col_tooltip ] = _("Jitter the colors of selected objects"); - row[columns.col_icon ] = INKSCAPE_ICON("object-tweak-jitter-color"); - row[columns.col_sensitive] = true; - - row = *(store->append()); - row[columns.col_label ] = _("Blur mode"); - row[columns.col_tooltip ] = _("Blur selected objects more; with Shift, blur less"); - row[columns.col_icon ] = INKSCAPE_ICON("object-tweak-blur"); - row[columns.col_sensitive] = true; - - InkSelectOneAction* act = - InkSelectOneAction::create( "TweakModeAction", // Name - _("Mode"), // Label - (""), // Tooltip - "Not Used", // Icon - store ); // Tree store - - act->use_radio( true ); - act->use_icon( true ); - act->use_label( false ); - act->use_group_label( true ); - int mode = prefs->getInt("/tools/tweak/mode", 0); - act->set_active( mode ); - - gtk_action_group_add_action( mainActions, GTK_ACTION( act->gobj() )); - g_object_set_data( holder, "tweak_tool_mode", act ); - - act->signal_changed().connect(sigc::bind<0>(sigc::ptr_fun(&sp_tweak_mode_changed), holder)); - } - - guint mode = prefs->getInt("/tools/tweak/mode", 0); - - { - EgeOutputAction* act = ege_output_action_new( "TweakChannelsLabel", _("Channels:"), "", 0 ); - ege_output_action_set_use_markup( act, TRUE ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - if (mode != Inkscape::UI::Tools::TWEAK_MODE_COLORPAINT && mode != Inkscape::UI::Tools::TWEAK_MODE_COLORJITTER) { - gtk_action_set_visible (GTK_ACTION(act), FALSE); - } - g_object_set_data( holder, "tweak_channels_label", act); - } - - { - InkToggleAction* act = ink_toggle_action_new( "TweakDoH", - _("Hue"), - _("In color mode, act on objects' hue"), - NULL, - GTK_ICON_SIZE_MENU ); - //TRANSLATORS: "H" here stands for hue - g_object_set( act, "short_label", C_("Hue", "H"), NULL ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(tweak_toggle_doh), desktop ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/tweak/doh", true) ); - if (mode != Inkscape::UI::Tools::TWEAK_MODE_COLORPAINT && mode != Inkscape::UI::Tools::TWEAK_MODE_COLORJITTER) { - gtk_action_set_visible (GTK_ACTION(act), FALSE); - } - g_object_set_data( holder, "tweak_doh", act); - } - { - InkToggleAction* act = ink_toggle_action_new( "TweakDoS", - _("Saturation"), - _("In color mode, act on objects' saturation"), - NULL, - GTK_ICON_SIZE_MENU ); - //TRANSLATORS: "S" here stands for Saturation - g_object_set( act, "short_label", C_("Saturation", "S"), NULL ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(tweak_toggle_dos), desktop ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/tweak/dos", true) ); - if (mode != Inkscape::UI::Tools::TWEAK_MODE_COLORPAINT && mode != Inkscape::UI::Tools::TWEAK_MODE_COLORJITTER) { - gtk_action_set_visible (GTK_ACTION(act), FALSE); - } - g_object_set_data( holder, "tweak_dos", act ); - } - { - InkToggleAction* act = ink_toggle_action_new( "TweakDoL", - _("Lightness"), - _("In color mode, act on objects' lightness"), - NULL, - GTK_ICON_SIZE_MENU ); - //TRANSLATORS: "L" here stands for Lightness - g_object_set( act, "short_label", C_("Lightness", "L"), NULL ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(tweak_toggle_dol), desktop ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/tweak/dol", true) ); - if (mode != Inkscape::UI::Tools::TWEAK_MODE_COLORPAINT && mode != Inkscape::UI::Tools::TWEAK_MODE_COLORJITTER) { - gtk_action_set_visible (GTK_ACTION(act), FALSE); - } - g_object_set_data( holder, "tweak_dol", act ); - } - { - InkToggleAction* act = ink_toggle_action_new( "TweakDoO", - _("Opacity"), - _("In color mode, act on objects' opacity"), - NULL, - GTK_ICON_SIZE_MENU ); - //TRANSLATORS: "O" here stands for Opacity - g_object_set( act, "short_label", C_("Opacity", "O"), NULL ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(tweak_toggle_doo), desktop ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/tweak/doo", true) ); - if (mode != Inkscape::UI::Tools::TWEAK_MODE_COLORPAINT && mode != Inkscape::UI::Tools::TWEAK_MODE_COLORJITTER) { - gtk_action_set_visible (GTK_ACTION(act), FALSE); - } - g_object_set_data( holder, "tweak_doo", act ); - } - - { /* Fidelity */ - gchar const* labels[] = {_("(rough, simplified)"), 0, 0, _("(default)"), 0, 0, _("(fine, but many nodes)")}; - gdouble values[] = {10, 25, 35, 50, 60, 80, 100}; - EgeAdjustmentAction *eact = create_adjustment_action( "TweakFidelityAction", - _("Fidelity"), _("Fidelity:"), - _("Low fidelity simplifies paths; high fidelity preserves path features but may generate a lot of new nodes"), - "/tools/tweak/fidelity", 50, - GTK_WIDGET(desktop->canvas), holder, TRUE, "tweak-fidelity", - 1, 100, 1.0, 10.0, - labels, values, G_N_ELEMENTS(labels), - sp_tweak_fidelity_value_changed, NULL /*unit tracker*/, 0.01, 0, 100 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_visible( GTK_ACTION(eact), TRUE ); - if (mode == Inkscape::UI::Tools::TWEAK_MODE_COLORPAINT || mode == Inkscape::UI::Tools::TWEAK_MODE_COLORJITTER) { - gtk_action_set_visible (GTK_ACTION(eact), FALSE); - } - g_object_set_data( holder, "tweak_fidelity", eact ); - } - - - /* Use Pressure button */ - { - InkToggleAction* act = ink_toggle_action_new( "TweakPressureAction", - _("Pressure"), - _("Use the pressure of the input device to alter the force of tweak action"), - INKSCAPE_ICON("draw-use-pressure"), - GTK_ICON_SIZE_MENU ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_tweak_pressure_state_changed), NULL); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/tweak/usepressure", true) ); - } - -} - - -/* - 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:fileencoding=utf-8:textwidth=99 : diff --git a/src/widgets/tweak-toolbar.h b/src/widgets/tweak-toolbar.h deleted file mode 100644 index 1a65a0844..000000000 --- a/src/widgets/tweak-toolbar.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef SEEN_TWEAK_TOOLBAR_H -#define SEEN_TWEAK_TOOLBAR_H - -/** - * @file - * Tweak aux toolbar - */ -/* Authors: - * MenTaLguY - * Lauris Kaplinski - * bulia byak - * Frank Felfe - * John Cliff - * David Turner - * Josh Andler - * Jon A. Cruz - * Maximilian Albert - * Tavmjong Bah - * Abhishek Sharma - * Kris De Gussem - * - * Copyright (C) 2004 David Turner - * Copyright (C) 2003 MenTaLguY - * Copyright (C) 1999-2011 authors - * Copyright (C) 2001-2002 Ximian, Inc. - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -class SPDesktop; - -typedef struct _GtkActionGroup GtkActionGroup; -typedef struct _GObject GObject; - -void sp_tweak_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); - -#endif /* !SEEN_SELECT_TOOLBAR_H */ diff --git a/src/widgets/zoom-toolbar.cpp b/src/widgets/zoom-toolbar.cpp deleted file mode 100644 index a961c0061..000000000 --- a/src/widgets/zoom-toolbar.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/** - * @file - * Zoom aux toolbar - */ -/* Authors: - * MenTaLguY - * Lauris Kaplinski - * bulia byak - * Frank Felfe - * John Cliff - * David Turner - * Josh Andler - * Jon A. Cruz - * Maximilian Albert - * Tavmjong Bah - * Abhishek Sharma - * Kris De Gussem - * - * Copyright (C) 2004 David Turner - * Copyright (C) 2003 MenTaLguY - * Copyright (C) 1999-2011 authors - * Copyright (C) 2001-2002 Ximian, Inc. - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "zoom-toolbar.h" - -//######################## -//## Zoom Toolbox ## -//######################## - -void sp_zoom_toolbox_prep(SPDesktop * /*desktop*/, GtkActionGroup* /*mainActions*/, GObject* /*holder*/) -{ - // no custom GtkAction setup needed -} // end of sp_zoom_toolbox_prep() - -/* - 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:fileencoding=utf-8:textwidth=99 : diff --git a/src/widgets/zoom-toolbar.h b/src/widgets/zoom-toolbar.h deleted file mode 100644 index 45d979066..000000000 --- a/src/widgets/zoom-toolbar.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef SEEN_ZOOM_TOOLBAR_H -#define SEEN_ZOOM_TOOLBAR_H - -/** - * @file - * Zoom aux toolbar - */ -/* Authors: - * MenTaLguY - * Lauris Kaplinski - * bulia byak - * Frank Felfe - * John Cliff - * David Turner - * Josh Andler - * Jon A. Cruz - * Maximilian Albert - * Tavmjong Bah - * Abhishek Sharma - * Kris De Gussem - * - * Copyright (C) 2004 David Turner - * Copyright (C) 2003 MenTaLguY - * Copyright (C) 1999-2011 authors - * Copyright (C) 2001-2002 Ximian, Inc. - * - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -class SPDesktop; - -typedef struct _GtkActionGroup GtkActionGroup; -typedef struct _GObject GObject; - -void sp_zoom_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); - -#endif /* !SEEN_ZOOM_TOOLBAR_H */ -- cgit v1.2.3