X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fui%2Fwidget%2Fselected-style.cpp;h=520d7f40402ddac306e3ceca4a3341ad2754a3d9;hb=fd5c8954a92eac9af9af21d2a3665e9c673203a2;hp=90efd2da5741259e7aeb5451eec10ecdf7a8b80a;hpb=469c9ea92e7d1cc3fec6a26cc79ac54c6ff5b3df;p=inkscape.git diff --git a/src/ui/widget/selected-style.cpp b/src/ui/widget/selected-style.cpp index 90efd2da5..520d7f404 100644 --- a/src/ui/widget/selected-style.cpp +++ b/src/ui/widget/selected-style.cpp @@ -27,20 +27,32 @@ #include "sp-linear-gradient-fns.h" #include "sp-radial-gradient-fns.h" #include "sp-pattern.h" -#include "dialogs/object-properties.h" +#include "ui/dialog/dialog-manager.h" +#include "ui/dialog/fill-and-stroke.h" +#include "ui/dialog/panel-dialog.h" #include "xml/repr.h" #include "document.h" #include "widgets/widget-sizes.h" #include "widgets/spinbutton-events.h" +#include "widgets/gradient-image.h" +#include "sp-gradient.h" #include "svg/svg-color.h" #include "svg/css-ostringstream.h" #include "helper/units.h" +#include "event-context.h" +#include "message-context.h" #include "verbs.h" +#include "color.h" +#include +#include "pixmaps/cursor-adj-h.xpm" +#include "pixmaps/cursor-adj-s.xpm" +#include "pixmaps/cursor-adj-l.xpm" +#include "sp-cursor.h" static gdouble const _sw_presets[] = { 32 , 16 , 10 , 8 , 6 , 4 , 3 , 2 , 1.5 , 1 , 0.75 , 0.5 , 0.25 , 0.1 }; -static gchar* const _sw_presets_str[] = {"32", "16", "10", "8", "6", "4", "3", "2", "1.5", "1", "0.75", "0.5", "0.25", "0.1"}; +static gchar const *const _sw_presets_str[] = {"32", "16", "10", "8", "6", "4", "3", "2", "1.5", "1", "0.75", "0.5", "0.25", "0.1"}; -static void +static void ss_selection_changed (Inkscape::Selection *, gpointer data) { Inkscape::UI::Widget::SelectedStyle *ss = (Inkscape::UI::Widget::SelectedStyle *) data; @@ -48,13 +60,13 @@ ss_selection_changed (Inkscape::Selection *, gpointer data) } static void -ss_selection_modified (Inkscape::Selection *selection, guint flags, gpointer data) +ss_selection_modified( Inkscape::Selection *selection, guint /*flags*/, gpointer data ) { ss_selection_changed (selection, data); } static void -ss_subselection_changed (gpointer dragger, gpointer data) +ss_subselection_changed( gpointer /*dragger*/, gpointer data ) { ss_selection_changed (NULL, data); } @@ -81,25 +93,32 @@ static GtkTargetEntry ui_drop_target_entries [] = { #define ENTRIES_SIZE(n) sizeof(n)/sizeof(n[0]) static guint nui_drop_target_entries = ENTRIES_SIZE(ui_drop_target_entries); +/* convenience function */ +static Dialog::FillAndStroke *get_fill_and_stroke_panel(SPDesktop *desktop); + +SelectedStyle::SelectedStyle(bool /*layout*/) + : + current_stroke_width(0), -SelectedStyle::SelectedStyle(bool layout) - : _desktop (NULL), + _desktop (NULL), _table(2, 6), - _fill_label (_("F:")), - _stroke_label (_("S:")), + _fill_label (_("Fill:")), + _stroke_label (_("Stroke:")), _opacity_label (_("O:")), - _fill_place (), - _stroke_place (), + + _fill_place (SS_FILL), + _stroke_place (SS_STROKE), _fill_flag_place (), _stroke_flag_place (), _opacity_place (), - _opacity_adjustment (1.0, 0.0, 1.0, 0.01, 0.1), - _opacity_sb (0.02, 2), + _opacity_adjustment (100, 0.0, 100, 1.0, 10.0), + _opacity_sb (0.02, 0), _stroke (), + _stroke_width_place(), _stroke_width (""), _opacity_blocked (false), @@ -115,7 +134,7 @@ SelectedStyle::SelectedStyle(bool layout) { _drop[0] = _drop[1] = 0; _dropEnabled[0] = _dropEnabled[1] = false; - + _fill_label.set_alignment(0.0, 0.5); _fill_label.set_padding(0, 0); _stroke_label.set_alignment(0.0, 0.5); @@ -133,7 +152,7 @@ SelectedStyle::SelectedStyle(bool layout) _na[i].show_all(); __na[i] = (_("Nothing selected")); - _none[i].set_markup (_("None")); + _none[i].set_markup (_("None")); sp_set_font_size_smaller (GTK_WIDGET(_none[i].gobj())); _none[i].show_all(); __none[i] = (i == SS_FILL)? (_("No fill")) : (_("No stroke")); @@ -143,22 +162,32 @@ SelectedStyle::SelectedStyle(bool layout) _pattern[i].show_all(); __pattern[i] = (i == SS_FILL)? (_("Pattern fill")) : (_("Pattern stroke")); - _lgradient[i].set_markup (_("L Gradient")); + _lgradient[i].set_markup (_("L")); sp_set_font_size_smaller (GTK_WIDGET(_lgradient[i].gobj())); _lgradient[i].show_all(); __lgradient[i] = (i == SS_FILL)? (_("Linear gradient fill")) : (_("Linear gradient stroke")); - _rgradient[i].set_markup (_("R Gradient")); + _gradient_preview_l[i] = GTK_WIDGET(sp_gradient_image_new (NULL)); + _gradient_box_l[i].pack_start(_lgradient[i]); + _gradient_box_l[i].pack_start(*(Glib::wrap(_gradient_preview_l[i]))); + _gradient_box_l[i].show_all(); + + _rgradient[i].set_markup (_("R")); sp_set_font_size_smaller (GTK_WIDGET(_rgradient[i].gobj())); _rgradient[i].show_all(); __rgradient[i] = (i == SS_FILL)? (_("Radial gradient fill")) : (_("Radial gradient stroke")); + _gradient_preview_r[i] = GTK_WIDGET(sp_gradient_image_new (NULL)); + _gradient_box_r[i].pack_start(_rgradient[i]); + _gradient_box_r[i].pack_start(*(Glib::wrap(_gradient_preview_r[i]))); + _gradient_box_r[i].show_all(); + _many[i].set_markup (_("Different")); sp_set_font_size_smaller (GTK_WIDGET(_many[i].gobj())); _many[i].show_all(); __many[i] = (i == SS_FILL)? (_("Different fills")) : (_("Different strokes")); - _unset[i].set_markup (_("Unset")); + _unset[i].set_markup (_("Unset")); sp_set_font_size_smaller (GTK_WIDGET(_unset[i].gobj())); _unset[i].show_all(); __unset[i] = (i == SS_FILL)? (_("Unset fill")) : (_("Unset stroke")); @@ -179,52 +208,52 @@ SelectedStyle::SelectedStyle(bool layout) __multiple[i] = (i == SS_FILL)? (_("Multiple selected objects have the same fill")) : (_("Multiple selected objects have the same stroke")); _popup_edit[i].add(*(new Gtk::Label((i == SS_FILL)? _("Edit fill...") : _("Edit stroke..."), 0.0, 0.5))); - _popup_edit[i].signal_activate().connect(sigc::mem_fun(*this, + _popup_edit[i].signal_activate().connect(sigc::mem_fun(*this, (i == SS_FILL)? &SelectedStyle::on_fill_edit : &SelectedStyle::on_stroke_edit )); _popup_lastused[i].add(*(new Gtk::Label(_("Last set color"), 0.0, 0.5))); - _popup_lastused[i].signal_activate().connect(sigc::mem_fun(*this, + _popup_lastused[i].signal_activate().connect(sigc::mem_fun(*this, (i == SS_FILL)? &SelectedStyle::on_fill_lastused : &SelectedStyle::on_stroke_lastused )); _popup_lastselected[i].add(*(new Gtk::Label(_("Last selected color"), 0.0, 0.5))); - _popup_lastselected[i].signal_activate().connect(sigc::mem_fun(*this, + _popup_lastselected[i].signal_activate().connect(sigc::mem_fun(*this, (i == SS_FILL)? &SelectedStyle::on_fill_lastselected : &SelectedStyle::on_stroke_lastselected )); _popup_invert[i].add(*(new Gtk::Label(_("Invert"), 0.0, 0.5))); - _popup_invert[i].signal_activate().connect(sigc::mem_fun(*this, + _popup_invert[i].signal_activate().connect(sigc::mem_fun(*this, (i == SS_FILL)? &SelectedStyle::on_fill_invert : &SelectedStyle::on_stroke_invert )); _popup_white[i].add(*(new Gtk::Label(_("White"), 0.0, 0.5))); - _popup_white[i].signal_activate().connect(sigc::mem_fun(*this, + _popup_white[i].signal_activate().connect(sigc::mem_fun(*this, (i == SS_FILL)? &SelectedStyle::on_fill_white : &SelectedStyle::on_stroke_white )); _popup_black[i].add(*(new Gtk::Label(_("Black"), 0.0, 0.5))); - _popup_black[i].signal_activate().connect(sigc::mem_fun(*this, + _popup_black[i].signal_activate().connect(sigc::mem_fun(*this, (i == SS_FILL)? &SelectedStyle::on_fill_black : &SelectedStyle::on_stroke_black )); _popup_copy[i].add(*(new Gtk::Label(_("Copy color"), 0.0, 0.5))); - _popup_copy[i].signal_activate().connect(sigc::mem_fun(*this, + _popup_copy[i].signal_activate().connect(sigc::mem_fun(*this, (i == SS_FILL)? &SelectedStyle::on_fill_copy : &SelectedStyle::on_stroke_copy )); _popup_paste[i].add(*(new Gtk::Label(_("Paste color"), 0.0, 0.5))); - _popup_paste[i].signal_activate().connect(sigc::mem_fun(*this, + _popup_paste[i].signal_activate().connect(sigc::mem_fun(*this, (i == SS_FILL)? &SelectedStyle::on_fill_paste : &SelectedStyle::on_stroke_paste )); _popup_swap[i].add(*(new Gtk::Label(_("Swap fill and stroke"), 0.0, 0.5))); - _popup_swap[i].signal_activate().connect(sigc::mem_fun(*this, + _popup_swap[i].signal_activate().connect(sigc::mem_fun(*this, &SelectedStyle::on_fillstroke_swap)); _popup_opaque[i].add(*(new Gtk::Label((i == SS_FILL)? _("Make fill opaque") : _("Make stroke opaque"), 0.0, 0.5))); - _popup_opaque[i].signal_activate().connect(sigc::mem_fun(*this, + _popup_opaque[i].signal_activate().connect(sigc::mem_fun(*this, (i == SS_FILL)? &SelectedStyle::on_fill_opaque : &SelectedStyle::on_stroke_opaque )); //TRANSLATORS COMMENT: unset is a verb here _popup_unset[i].add(*(new Gtk::Label((i == SS_FILL)? _("Unset fill") : _("Unset stroke"), 0.0, 0.5))); - _popup_unset[i].signal_activate().connect(sigc::mem_fun(*this, + _popup_unset[i].signal_activate().connect(sigc::mem_fun(*this, (i == SS_FILL)? &SelectedStyle::on_fill_unset : &SelectedStyle::on_stroke_unset )); _popup_remove[i].add(*(new Gtk::Label((i == SS_FILL)? _("Remove fill") : _("Remove stroke"), 0.0, 0.5))); - _popup_remove[i].signal_activate().connect(sigc::mem_fun(*this, + _popup_remove[i].signal_activate().connect(sigc::mem_fun(*this, (i == SS_FILL)? &SelectedStyle::on_fill_remove : &SelectedStyle::on_stroke_remove )); _popup[i].attach(_popup_edit[i], 0,1, 0,1); @@ -241,7 +270,7 @@ SelectedStyle::SelectedStyle(bool layout) _popup_copy[i].set_sensitive(false); _popup[i].attach(_popup_paste[i], 0,1, 11,12); _popup[i].attach(_popup_swap[i], 0,1, 12,13); - _popup[i].attach(*(new Gtk::SeparatorMenuItem()), 0,1, 13,14); + _popup[i].attach(*(new Gtk::SeparatorMenuItem()), 0,1, 13,14); _popup[i].attach(_popup_opaque[i], 0,1, 14,15); _popup[i].attach(_popup_unset[i], 0,1, 15,16); _popup[i].attach(_popup_remove[i], 0,1, 16,17); @@ -283,8 +312,8 @@ SelectedStyle::SelectedStyle(bool layout) _popup_sw.show_all(); } - _fill_place.signal_button_press_event().connect(sigc::mem_fun(*this, &SelectedStyle::on_fill_click)); - _stroke_place.signal_button_press_event().connect(sigc::mem_fun(*this, &SelectedStyle::on_stroke_click)); + _fill_place.signal_button_release_event().connect(sigc::mem_fun(*this, &SelectedStyle::on_fill_click)); + _stroke_place.signal_button_release_event().connect(sigc::mem_fun(*this, &SelectedStyle::on_stroke_click)); _opacity_place.signal_button_press_event().connect(sigc::mem_fun(*this, &SelectedStyle::on_opacity_click)); _stroke_width_place.signal_button_press_event().connect(sigc::mem_fun(*this, &SelectedStyle::on_sw_click)); @@ -306,8 +335,8 @@ SelectedStyle::SelectedStyle(bool layout) _opacity_sb.set_size_request (SELECTED_STYLE_SB_WIDTH, -1); _opacity_sb.set_sensitive (false); - _table.attach(_fill_label, 0,1, 0,1, Gtk::SHRINK, Gtk::SHRINK); - _table.attach(_stroke_label, 0,1, 1,2, Gtk::SHRINK, Gtk::SHRINK); + _table.attach(_fill_label, 0,1, 0,1, Gtk::FILL, Gtk::SHRINK); + _table.attach(_stroke_label, 0,1, 1,2, Gtk::FILL, Gtk::SHRINK); _table.attach(_fill_flag_place, 1,2, 0,1, Gtk::SHRINK, Gtk::SHRINK); _table.attach(_stroke_flag_place, 1,2, 1,2, Gtk::SHRINK, Gtk::SHRINK); @@ -350,6 +379,10 @@ SelectedStyle::SelectedStyle(bool layout) "drag_data_received", G_CALLBACK(dragDataReceived), _drop[SS_FILL]); + + _fill_place.parent = this; + _stroke_place.parent = this; + _stroke_width_place.parent = this; } SelectedStyle::~SelectedStyle() @@ -363,6 +396,9 @@ SelectedStyle::~SelectedStyle() for (int i = SS_FILL; i <= SS_STROKE; i++) { delete _color_preview[i]; + // FIXME: do we need this? the destroy methods are not exported + //sp_gradient_image_destroy(GTK_OBJECT(_gradient_preview_l[i])); + //sp_gradient_image_destroy(GTK_OBJECT(_gradient_preview_r[i])); } delete (DropTracker*)_drop[SS_FILL]; @@ -396,12 +432,12 @@ SelectedStyle::setDesktop(SPDesktop *desktop) //_sw_unit = (SPUnit *) sp_desktop_namedview(desktop)->doc_units; } -void SelectedStyle::dragDataReceived( GtkWidget *widget, - GdkDragContext *drag_context, - gint x, gint y, +void SelectedStyle::dragDataReceived( GtkWidget */*widget*/, + GdkDragContext */*drag_context*/, + gint /*x*/, gint /*y*/, GtkSelectionData *data, - guint info, - guint event_time, + guint /*info*/, + guint /*event_time*/, gpointer user_data ) { DropTracker* tracker = (DropTracker*)user_data; @@ -414,7 +450,7 @@ void SelectedStyle::dragDataReceived( GtkWidget *widget, gchar c[64]; // Careful about endian issues. guint16* dataVals = (guint16*)data->data; - sp_svg_write_color( c, 64, + sp_svg_write_color( c, sizeof(c), SP_RGBA32_U_COMPOSE( 0x0ff & (dataVals[0] >> 8), 0x0ff & (dataVals[1] >> 8), @@ -426,7 +462,7 @@ void SelectedStyle::dragDataReceived( GtkWidget *widget, sp_repr_css_set_property( css, (tracker->item == SS_FILL) ? "fill":"stroke", c ); sp_desktop_set_style( tracker->parent->_desktop, css ); sp_repr_css_attr_unref( css ); - sp_document_done( sp_desktop_document(tracker->parent->_desktop) , SP_VERB_NONE, + sp_document_done( sp_desktop_document(tracker->parent->_desktop) , SP_VERB_NONE, _("Drop color")); } } @@ -437,7 +473,7 @@ void SelectedStyle::dragDataReceived( GtkWidget *widget, void SelectedStyle::on_fill_remove() { SPCSSAttr *css = sp_repr_css_attr_new (); sp_repr_css_set_property (css, "fill", "none"); - sp_desktop_set_style (_desktop, css, true, true); + sp_desktop_set_style (_desktop, css, true, true); sp_repr_css_attr_unref (css); sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, _("Remove fill")); @@ -446,7 +482,7 @@ void SelectedStyle::on_fill_remove() { void SelectedStyle::on_stroke_remove() { SPCSSAttr *css = sp_repr_css_attr_new (); sp_repr_css_set_property (css, "stroke", "none"); - sp_desktop_set_style (_desktop, css, true, true); + sp_desktop_set_style (_desktop, css, true, true); sp_repr_css_attr_unref (css); sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, _("Remove stroke")); @@ -455,7 +491,7 @@ void SelectedStyle::on_stroke_remove() { void SelectedStyle::on_fill_unset() { SPCSSAttr *css = sp_repr_css_attr_new (); sp_repr_css_unset_property (css, "fill"); - sp_desktop_set_style (_desktop, css, true, true); + sp_desktop_set_style (_desktop, css, true, true); sp_repr_css_attr_unref (css); sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, _("Unset fill")); @@ -464,6 +500,13 @@ void SelectedStyle::on_fill_unset() { void SelectedStyle::on_stroke_unset() { SPCSSAttr *css = sp_repr_css_attr_new (); sp_repr_css_unset_property (css, "stroke"); + sp_repr_css_unset_property (css, "stroke-opacity"); + sp_repr_css_unset_property (css, "stroke-width"); + sp_repr_css_unset_property (css, "stroke-miterlimit"); + sp_repr_css_unset_property (css, "stroke-linejoin"); + sp_repr_css_unset_property (css, "stroke-linecap"); + sp_repr_css_unset_property (css, "stroke-dashoffset"); + sp_repr_css_unset_property (css, "stroke-dasharray"); sp_desktop_set_style (_desktop, css, true, true); sp_repr_css_attr_unref (css); sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, @@ -492,11 +535,11 @@ void SelectedStyle::on_fill_lastused() { SPCSSAttr *css = sp_repr_css_attr_new (); guint32 color = sp_desktop_get_color(_desktop, true); gchar c[64]; - sp_svg_write_color (c, 64, color); + sp_svg_write_color (c, sizeof(c), color); sp_repr_css_set_property (css, "fill", c); sp_desktop_set_style (_desktop, css); sp_repr_css_attr_unref (css); - sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, + sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, _("Apply last set color to fill")); } @@ -504,18 +547,18 @@ void SelectedStyle::on_stroke_lastused() { SPCSSAttr *css = sp_repr_css_attr_new (); guint32 color = sp_desktop_get_color(_desktop, false); gchar c[64]; - sp_svg_write_color (c, 64, color); + sp_svg_write_color (c, sizeof(c), color); sp_repr_css_set_property (css, "stroke", c); sp_desktop_set_style (_desktop, css); sp_repr_css_attr_unref (css); - sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, + sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, _("Apply last set color to stroke")); } void SelectedStyle::on_fill_lastselected() { SPCSSAttr *css = sp_repr_css_attr_new (); gchar c[64]; - sp_svg_write_color (c, 64, _lastselected[SS_FILL]); + sp_svg_write_color (c, sizeof(c), _lastselected[SS_FILL]); sp_repr_css_set_property (css, "fill", c); sp_desktop_set_style (_desktop, css); sp_repr_css_attr_unref (css); @@ -526,11 +569,11 @@ void SelectedStyle::on_fill_lastselected() { void SelectedStyle::on_stroke_lastselected() { SPCSSAttr *css = sp_repr_css_attr_new (); gchar c[64]; - sp_svg_write_color (c, 64, _lastselected[SS_STROKE]); + sp_svg_write_color (c, sizeof(c), _lastselected[SS_STROKE]); sp_repr_css_set_property (css, "stroke", c); sp_desktop_set_style (_desktop, css); sp_repr_css_attr_unref (css); - sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, + sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, _("Apply last selected color to stroke")); } @@ -539,7 +582,7 @@ void SelectedStyle::on_fill_invert() { guint32 color = _thisselected[SS_FILL]; gchar c[64]; if (_mode[SS_FILL] != SS_COLOR) return; - sp_svg_write_color (c, 64, + sp_svg_write_color (c, sizeof(c), SP_RGBA32_U_COMPOSE( (255 - SP_RGBA32_R_U(color)), (255 - SP_RGBA32_G_U(color)), @@ -559,7 +602,7 @@ void SelectedStyle::on_stroke_invert() { guint32 color = _thisselected[SS_STROKE]; gchar c[64]; if (_mode[SS_STROKE] != SS_COLOR) return; - sp_svg_write_color (c, 64, + sp_svg_write_color (c, sizeof(c), SP_RGBA32_U_COMPOSE( (255 - SP_RGBA32_R_U(color)), (255 - SP_RGBA32_G_U(color)), @@ -572,12 +615,12 @@ void SelectedStyle::on_stroke_invert() { sp_repr_css_attr_unref (css); sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, _("Invert stroke")); -} +} void SelectedStyle::on_fill_white() { SPCSSAttr *css = sp_repr_css_attr_new (); gchar c[64]; - sp_svg_write_color (c, 64, 0xffffffff); + sp_svg_write_color (c, sizeof(c), 0xffffffff); sp_repr_css_set_property (css, "fill", c); sp_repr_css_set_property (css, "fill-opacity", "1"); sp_desktop_set_style (_desktop, css); @@ -589,43 +632,43 @@ void SelectedStyle::on_fill_white() { void SelectedStyle::on_stroke_white() { SPCSSAttr *css = sp_repr_css_attr_new (); gchar c[64]; - sp_svg_write_color (c, 64, 0xffffffff); + sp_svg_write_color (c, sizeof(c), 0xffffffff); sp_repr_css_set_property (css, "stroke", c); sp_repr_css_set_property (css, "stroke-opacity", "1"); sp_desktop_set_style (_desktop, css); sp_repr_css_attr_unref (css); - sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, + sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, _("White stroke")); } void SelectedStyle::on_fill_black() { SPCSSAttr *css = sp_repr_css_attr_new (); gchar c[64]; - sp_svg_write_color (c, 64, 0x000000ff); + sp_svg_write_color (c, sizeof(c), 0x000000ff); sp_repr_css_set_property (css, "fill", c); sp_repr_css_set_property (css, "fill-opacity", "1.0"); sp_desktop_set_style (_desktop, css); sp_repr_css_attr_unref (css); - sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, + sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, _("Black fill")); } void SelectedStyle::on_stroke_black() { SPCSSAttr *css = sp_repr_css_attr_new (); gchar c[64]; - sp_svg_write_color (c, 64, 0x000000ff); + sp_svg_write_color (c, sizeof(c), 0x000000ff); sp_repr_css_set_property (css, "stroke", c); sp_repr_css_set_property (css, "stroke-opacity", "1.0"); sp_desktop_set_style (_desktop, css); sp_repr_css_attr_unref (css); - sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, + sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, _("Black stroke")); } void SelectedStyle::on_fill_copy() { if (_mode[SS_FILL] == SS_COLOR) { gchar c[64]; - sp_svg_write_color (c, 64, _thisselected[SS_FILL]); + sp_svg_write_color (c, sizeof(c), _thisselected[SS_FILL]); Glib::ustring text; text += c; if (!text.empty()) { @@ -638,7 +681,7 @@ void SelectedStyle::on_fill_copy() { void SelectedStyle::on_stroke_copy() { if (_mode[SS_STROKE] == SS_COLOR) { gchar c[64]; - sp_svg_write_color (c, 64, _thisselected[SS_STROKE]); + sp_svg_write_color (c, sizeof(c), _thisselected[SS_STROKE]); Glib::ustring text; text += c; if (!text.empty()) { @@ -661,7 +704,7 @@ void SelectedStyle::on_fill_paste() { sp_repr_css_set_property (css, "fill", text.c_str()); sp_desktop_set_style (_desktop, css); sp_repr_css_attr_unref (css); - sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, + sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, _("Paste fill")); } } @@ -699,7 +742,7 @@ void SelectedStyle::on_fillstroke_swap() { break; case SS_COLOR: gchar c[64]; - sp_svg_write_color (c, 64, _thisselected[SS_FILL]); + sp_svg_write_color (c, sizeof(c), _thisselected[SS_FILL]); sp_repr_css_set_property (css, "stroke", c); break; case SS_LGRADIENT: @@ -721,7 +764,7 @@ void SelectedStyle::on_fillstroke_swap() { break; case SS_COLOR: gchar c[64]; - sp_svg_write_color (c, 64, _thisselected[SS_STROKE]); + sp_svg_write_color (c, sizeof(c), _thisselected[SS_STROKE]); sp_repr_css_set_property (css, "fill", c); break; case SS_LGRADIENT: @@ -733,23 +776,28 @@ void SelectedStyle::on_fillstroke_swap() { sp_desktop_set_style (_desktop, css); sp_repr_css_attr_unref (css); - sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, + sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, _("Swap fill and stroke")); } void SelectedStyle::on_fill_edit() { - sp_object_properties_fill(); + if (Dialog::FillAndStroke *fs = get_fill_and_stroke_panel(_desktop)) + fs->showPageFill(); } void SelectedStyle::on_stroke_edit() { - sp_object_properties_stroke(); + if (Dialog::FillAndStroke *fs = get_fill_and_stroke_panel(_desktop)) + fs->showPageStrokePaint(); } -bool +bool SelectedStyle::on_fill_click(GdkEventButton *event) { if (event->button == 1) { // click, open fill&stroke - sp_object_properties_fill(); + + if (Dialog::FillAndStroke *fs = get_fill_and_stroke_panel(_desktop)) + fs->showPageFill(); + } else if (event->button == 3) { // right-click, popup menu _popup[SS_FILL].popup(event->button, event->time); } else if (event->button == 2) { // middle click, toggle none/lastcolor @@ -762,11 +810,12 @@ SelectedStyle::on_fill_click(GdkEventButton *event) return true; } -bool +bool SelectedStyle::on_stroke_click(GdkEventButton *event) { if (event->button == 1) { // click, open fill&stroke - sp_object_properties_stroke(); + if (Dialog::FillAndStroke *fs = get_fill_and_stroke_panel(_desktop)) + fs->showPageStrokePaint(); } else if (event->button == 3) { // right-click, popup menu _popup[SS_STROKE].popup(event->button, event->time); } else if (event->button == 2) { // middle click, toggle none/lastcolor @@ -779,11 +828,12 @@ SelectedStyle::on_stroke_click(GdkEventButton *event) return true; } -bool +bool SelectedStyle::on_sw_click(GdkEventButton *event) { if (event->button == 1) { // click, open fill&stroke - sp_object_properties_stroke_style (); + if (Dialog::FillAndStroke *fs = get_fill_and_stroke_panel(_desktop)) + fs->showPageStrokeStyle(); } else if (event->button == 3) { // right-click, popup menu _popup_sw.popup(event->button, event->time); } else if (event->button == 2) { // middle click, toggle none/lastwidth? @@ -792,11 +842,11 @@ SelectedStyle::on_sw_click(GdkEventButton *event) return true; } -bool +bool SelectedStyle::on_opacity_click(GdkEventButton *event) { if (event->button == 2) { // middle click - const char* opacity = _opacity_sb.get_value() < 0.5? "0.5" : (_opacity_sb.get_value() == 1? "0" : "1"); + const char* opacity = _opacity_sb.get_value() < 50? "0.5" : (_opacity_sb.get_value() == 100? "0" : "1"); SPCSSAttr *css = sp_repr_css_attr_new (); sp_repr_css_set_property (css, "opacity", opacity); sp_desktop_set_style (_desktop, css); @@ -833,10 +883,11 @@ void SelectedStyle::on_popup_preset(int i) { Inkscape::CSSOStringStream os; os << w; sp_repr_css_set_property (css, "stroke-width", os.str().c_str()); + // FIXME: update dash patterns! sp_desktop_set_style (_desktop, css, true); sp_repr_css_attr_unref (css); sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_SWATCHES, - _("Change opacity")); + _("Change stroke width")); } void @@ -846,7 +897,7 @@ SelectedStyle::update() return; // create temporary style - SPStyle *query = sp_style_new (); + SPStyle *query = sp_style_new (sp_desktop_document(_desktop)); for (int i = SS_FILL; i <= SS_STROKE; i++) { Gtk::EventBox *place = (i == SS_FILL)? &_fill_place : &_stroke_place; @@ -864,7 +915,7 @@ SelectedStyle::update() _popup_copy[i].set_sensitive(false); // query style from desktop. This returns a result flag and fills query with the style of subselection, if any, or selection - int result = sp_desktop_query_style (_desktop, query, + int result = sp_desktop_query_style (_desktop, query, (i == SS_FILL)? QUERY_STYLE_PROPERTY_FILL : QUERY_STYLE_PROPERTY_STROKE); switch (result) { case QUERY_STYLE_NOTHING: @@ -878,7 +929,7 @@ SelectedStyle::update() break; case QUERY_STYLE_SINGLE: case QUERY_STYLE_MULTIPLE_AVERAGED: - case QUERY_STYLE_MULTIPLE_SAME: + case QUERY_STYLE_MULTIPLE_SAME: if ( !_dropEnabled[i] ) { gtk_drag_dest_set( GTK_WIDGET( (i==SS_FILL) ? _fill_place.gobj():_stroke_place.gobj()), GTK_DEST_DEFAULT_ALL, @@ -893,21 +944,7 @@ SelectedStyle::update() } else { paint = &(query->stroke); } - if (paint->set && paint->type == SP_PAINT_TYPE_COLOR) { - guint32 color = sp_color_get_rgba32_falpha (&(paint->value.color), - SP_SCALE24_TO_FLOAT ((i == SS_FILL)? query->fill_opacity.value : query->stroke_opacity.value)); - _lastselected[i] = _thisselected[i]; - _thisselected[i] = color | 0xff; // only color, opacity === 1 - ((Inkscape::UI::Widget::ColorPreview*)_color_preview[i])->setRgba32 (color); - _color_preview[i]->show_all(); - place->add(*_color_preview[i]); - gchar c_string[64]; - g_snprintf (c_string, 64, "%06x/%.3g", color >> 8, SP_RGBA32_A_F(color)); - _tooltips.set_tip(*place, __color[i] + ": " + c_string); - _mode[i] = SS_COLOR; - _popup_copy[i].set_sensitive(true); - - } else if (paint->set && paint->type == SP_PAINT_TYPE_PAINTSERVER) { + if (paint->set && paint->isPaintserver()) { SPPaintServer *server = (i == SS_FILL)? SP_STYLE_FILL_SERVER (query) : SP_STYLE_STROKE_SERVER (query); if ( server ) { Inkscape::XML::Node *srepr = SP_OBJECT_REPR(server); @@ -916,11 +953,15 @@ SelectedStyle::update() _paintserver_id[i] += ")"; if (SP_IS_LINEARGRADIENT (server)) { - place->add(_lgradient[i]); + SPGradient *vector = sp_gradient_get_vector(SP_GRADIENT(server), false); + sp_gradient_image_set_gradient ((SPGradientImage *) _gradient_preview_l[i], vector); + place->add(_gradient_box_l[i]); _tooltips.set_tip(*place, __lgradient[i]); _mode[i] = SS_LGRADIENT; } else if (SP_IS_RADIALGRADIENT (server)) { - place->add(_rgradient[i]); + SPGradient *vector = sp_gradient_get_vector(SP_GRADIENT(server), false); + sp_gradient_image_set_gradient ((SPGradientImage *) _gradient_preview_r[i], vector); + place->add(_gradient_box_r[i]); _tooltips.set_tip(*place, __rgradient[i]); _mode[i] = SS_RGRADIENT; } else if (SP_IS_PATTERN (server)) { @@ -931,8 +972,21 @@ SelectedStyle::update() } else { g_warning ("file %s: line %d: Unknown paint server", __FILE__, __LINE__); } + } else if (paint->set && paint->isColor()) { + guint32 color = paint->value.color.toRGBA32( + SP_SCALE24_TO_FLOAT ((i == SS_FILL)? query->fill_opacity.value : query->stroke_opacity.value)); + _lastselected[i] = _thisselected[i]; + _thisselected[i] = color | 0xff; // only color, opacity === 1 + ((Inkscape::UI::Widget::ColorPreview*)_color_preview[i])->setRgba32 (color); + _color_preview[i]->show_all(); + place->add(*_color_preview[i]); + gchar c_string[64]; + g_snprintf (c_string, 64, "%06x/%.3g", color >> 8, SP_RGBA32_A_F(color)); + _tooltips.set_tip(*place, __color[i] + ": " + c_string + _(", drag to adjust")); + _mode[i] = SS_COLOR; + _popup_copy[i].set_sensitive(true); - } else if (paint->set && paint->type == SP_PAINT_TYPE_NONE) { + } else if (paint->set && paint->isNone()) { place->add(_none[i]); _tooltips.set_tip(*place, __none[i]); _mode[i] = SS_NONE; @@ -961,21 +1015,25 @@ SelectedStyle::update() // Now query opacity _tooltips.unset_tip(_opacity_place); + _tooltips.unset_tip(_opacity_sb); int result = sp_desktop_query_style (_desktop, query, QUERY_STYLE_PROPERTY_MASTEROPACITY); switch (result) { case QUERY_STYLE_NOTHING: _tooltips.set_tip(_opacity_place, _("Nothing selected")); + _tooltips.set_tip(_opacity_sb, _("Nothing selected")); _opacity_sb.set_sensitive(false); break; case QUERY_STYLE_SINGLE: case QUERY_STYLE_MULTIPLE_AVERAGED: case QUERY_STYLE_MULTIPLE_SAME: - _tooltips.set_tip(_opacity_place, _("Master opacity")); + _tooltips.set_tip(_opacity_place, _("Opacity, %")); + _tooltips.set_tip(_opacity_sb, _("Opacity, %")); + if (_opacity_blocked) break; _opacity_blocked = true; _opacity_sb.set_sensitive(true); - _opacity_adjustment.set_value(SP_SCALE24_TO_FLOAT(query->opacity.value)); + _opacity_adjustment.set_value(SP_SCALE24_TO_FLOAT(query->opacity.value) * 100); _opacity_blocked = false; break; } @@ -985,10 +1043,11 @@ SelectedStyle::update() switch (result_sw) { case QUERY_STYLE_NOTHING: _stroke_width.set_markup(""); + current_stroke_width = 0; break; case QUERY_STYLE_SINGLE: case QUERY_STYLE_MULTIPLE_AVERAGED: - case QUERY_STYLE_MULTIPLE_SAME: + case QUERY_STYLE_MULTIPLE_SAME: { double w; if (_sw_unit) { @@ -996,15 +1055,17 @@ SelectedStyle::update() } else { w = query->stroke_width.computed; } + current_stroke_width = w; + { gchar *str = g_strdup_printf(" %.3g", w); _stroke_width.set_markup(str); g_free (str); } { - gchar *str = g_strdup_printf(_("Stroke width: %.5g%s%s"), - w, - _sw_unit? sp_unit_get_abbreviation(_sw_unit) : "px", + gchar *str = g_strdup_printf(_("Stroke width: %.5g%s%s"), + w, + _sw_unit? sp_unit_get_abbreviation(_sw_unit) : "px", (result_sw == QUERY_STYLE_MULTIPLE_AVERAGED)? _(" (averaged)") : ""); _tooltips.set_tip(_stroke_width_place, str); @@ -1016,14 +1077,14 @@ SelectedStyle::update() break; } - g_free (query); + sp_style_unref(query); } void SelectedStyle::opacity_0(void) {_opacity_sb.set_value(0);} -void SelectedStyle::opacity_025(void) {_opacity_sb.set_value(0.25);} -void SelectedStyle::opacity_05(void) {_opacity_sb.set_value(0.5);} -void SelectedStyle::opacity_075(void) {_opacity_sb.set_value(0.75);} -void SelectedStyle::opacity_1(void) {_opacity_sb.set_value(1.0);} +void SelectedStyle::opacity_025(void) {_opacity_sb.set_value(25);} +void SelectedStyle::opacity_05(void) {_opacity_sb.set_value(50);} +void SelectedStyle::opacity_075(void) {_opacity_sb.set_value(75);} +void SelectedStyle::opacity_1(void) {_opacity_sb.set_value(100);} void SelectedStyle::on_opacity_menu (Gtk::Menu *menu) { @@ -1040,25 +1101,25 @@ void SelectedStyle::on_opacity_menu (Gtk::Menu *menu) { } { Gtk::MenuItem *item = new Gtk::MenuItem; - item->add(*(new Gtk::Label("0.25", 0, 0))); + item->add(*(new Gtk::Label("25%", 0, 0))); item->signal_activate().connect(sigc::mem_fun(*this, &SelectedStyle::opacity_025 )); menu->add(*item); } { Gtk::MenuItem *item = new Gtk::MenuItem; - item->add(*(new Gtk::Label("0.5", 0, 0))); + item->add(*(new Gtk::Label("50%", 0, 0))); item->signal_activate().connect(sigc::mem_fun(*this, &SelectedStyle::opacity_05 )); menu->add(*item); } { Gtk::MenuItem *item = new Gtk::MenuItem; - item->add(*(new Gtk::Label("0.75", 0, 0))); + item->add(*(new Gtk::Label("75%", 0, 0))); item->signal_activate().connect(sigc::mem_fun(*this, &SelectedStyle::opacity_075 )); menu->add(*item); } { Gtk::MenuItem *item = new Gtk::MenuItem; - item->add(*(new Gtk::Label(_("1.0 (opaque)"), 0, 0))); + item->add(*(new Gtk::Label(_("100% (opaque)"), 0, 0))); item->signal_activate().connect(sigc::mem_fun(*this, &SelectedStyle::opacity_1 )); menu->add(*item); } @@ -1072,21 +1133,306 @@ void SelectedStyle::on_opacity_changed () { _opacity_blocked = true; SPCSSAttr *css = sp_repr_css_attr_new (); Inkscape::CSSOStringStream os; - os << CLAMP (_opacity_adjustment.get_value(), 0.0, 1.0); + os << CLAMP ((_opacity_adjustment.get_value() / 100), 0.0, 1.0); sp_repr_css_set_property (css, "opacity", os.str().c_str()); + // FIXME: workaround for GTK breakage: display interruptibility sometimes results in GTK + // sending multiple value-changed events. As if when Inkscape interrupts redraw for main loop + // iterations, GTK discovers that this callback hasn't finished yet, and for some weird reason + // decides to add yet another value-changed event to the queue. Totally braindead if you ask + // me. As a result, scrolling the spinbutton once results in runaway change until it hits 1.0 + // or 0.0. (And no, this is not a race with ::update, I checked that.) + // Sigh. So we disable interruptibility while we're setting the new value. + sp_canvas_force_full_redraw_after_interruptions(sp_desktop_canvas(_desktop), 0); sp_desktop_set_style (_desktop, css); sp_repr_css_attr_unref (css); sp_document_maybe_done (sp_desktop_document (_desktop), "fillstroke:opacity", SP_VERB_DIALOG_FILL_STROKE, _("Change opacity")); + // resume interruptibility + sp_canvas_end_forced_full_redraws(sp_desktop_canvas(_desktop)); spinbutton_defocus(GTK_OBJECT(_opacity_sb.gobj())); _opacity_blocked = false; } +/* ============================================= RotateableSwatch */ + +RotateableSwatch::RotateableSwatch(guint mode) { + fillstroke = mode; + startcolor_set = false; + undokey = "ssrot1"; + cr = NULL; + cr_set = false; +} + +RotateableSwatch::~RotateableSwatch() { +} + +double +RotateableSwatch::color_adjust(float *hsl, double by, guint32 cc, guint modifier) +{ + sp_color_rgb_to_hsl_floatv (hsl, SP_RGBA32_R_F(cc), SP_RGBA32_G_F(cc), SP_RGBA32_B_F(cc)); + + double diff = 0; + if (modifier == 2) { // saturation + double old = hsl[1]; + if (by > 0) { + hsl[1] += by * (1 - hsl[1]); + } else { + hsl[1] += by * (hsl[1]); + } + diff = hsl[1] - old; + } else if (modifier == 1) { // lightness + double old = hsl[2]; + if (by > 0) { + hsl[2] += by * (1 - hsl[2]); + } else { + hsl[2] += by * (hsl[2]); + } + diff = hsl[2] - old; + } else { // hue + double old = hsl[0]; + hsl[0] += by/2; + while (hsl[0] < 0) + hsl[0] += 1; + while (hsl[0] > 1) + hsl[0] -= 1; + diff = hsl[0] - old; + } + + float rgb[3]; + sp_color_hsl_to_rgb_floatv (rgb, hsl[0], hsl[1], hsl[2]); + + gchar c[64]; + sp_svg_write_color (c, sizeof(c), + SP_RGBA32_U_COMPOSE( + (SP_COLOR_F_TO_U(rgb[0])), + (SP_COLOR_F_TO_U(rgb[1])), + (SP_COLOR_F_TO_U(rgb[2])), + 0xff + ) + ); + + SPCSSAttr *css = sp_repr_css_attr_new (); + if (fillstroke == SS_FILL) + sp_repr_css_set_property (css, "fill", c); + else + sp_repr_css_set_property (css, "stroke", c); + sp_desktop_set_style (parent->getDesktop(), css); + sp_repr_css_attr_unref (css); + return diff; +} + +void +RotateableSwatch::do_motion(double by, guint modifier) { + if (parent->_mode[fillstroke] != SS_COLOR) + return; + + if (!cr_set && modifier != 3) { + GtkWidget *w = GTK_WIDGET(gobj()); + + GdkBitmap *bitmap = NULL; + GdkBitmap *mask = NULL; + if (modifier == 2) { // saturation + sp_cursor_bitmap_and_mask_from_xpm(&bitmap, &mask, cursor_adj_s_xpm); + } else if (modifier == 1) { // lightness + sp_cursor_bitmap_and_mask_from_xpm(&bitmap, &mask, cursor_adj_l_xpm); + } else { // hue + sp_cursor_bitmap_and_mask_from_xpm(&bitmap, &mask, cursor_adj_h_xpm); + } + if ((bitmap != NULL) && (mask != NULL)) { + cr = gdk_cursor_new_from_pixmap(bitmap, mask, + &w->style->black, + &w->style->white, + 16, 16); + g_object_unref (bitmap); + g_object_unref (mask); + gdk_window_set_cursor(w->window, cr); + cr_set = true; + } + } + + guint32 cc; + if (!startcolor_set) { + cc = startcolor = parent->_thisselected[fillstroke]; + startcolor_set = true; + } else { + cc = startcolor; + } + + float hsl[3]; + double diff = 0; + if (modifier != 3) { + diff = color_adjust(hsl, by, cc, modifier); + } + + if (modifier == 3) { // Alt, do nothing + + } else if (modifier == 2) { // saturation + sp_document_maybe_done (sp_desktop_document(parent->getDesktop()), undokey, + SP_VERB_DIALOG_FILL_STROKE, (_("Adjust saturation"))); + double ch = hsl[1]; + parent->getDesktop()->event_context->_message_context->setF(Inkscape::IMMEDIATE_MESSAGE, _("Adjusting saturation: was %.3g, now %.3g (diff %.3g); with Ctrl to adjust lightness, without modifiers to adjust hue"), ch - diff, ch, diff); + + } else if (modifier == 1) { // lightness + sp_document_maybe_done (sp_desktop_document(parent->getDesktop()), undokey, + SP_VERB_DIALOG_FILL_STROKE, (_("Adjust lightness"))); + double ch = hsl[2]; + parent->getDesktop()->event_context->_message_context->setF(Inkscape::IMMEDIATE_MESSAGE, _("Adjusting lightness: was %.3g, now %.3g (diff %.3g); with Shift to adjust saturation, without modifiers to adjust hue"), ch - diff, ch, diff); + + } else { // hue + sp_document_maybe_done (sp_desktop_document(parent->getDesktop()), undokey, + SP_VERB_DIALOG_FILL_STROKE, (_("Adjust hue"))); + double ch = hsl[0]; + parent->getDesktop()->event_context->_message_context->setF(Inkscape::IMMEDIATE_MESSAGE, _("Adjusting hue: was %.3g, now %.3g (diff %.3g); with Shift to adjust saturation, with Ctrl to adjust lightness"), ch - diff, ch, diff); + } +} + +void +RotateableSwatch::do_release(double by, guint modifier) { + if (parent->_mode[fillstroke] != SS_COLOR) + return; + + float hsl[3]; + if (modifier != 3) { + color_adjust(hsl, by, startcolor, modifier); + } + + if (cr_set) { + GtkWidget *w = GTK_WIDGET(gobj()); + gdk_window_set_cursor(w->window, NULL); + if (cr) { + gdk_cursor_unref (cr); + cr = NULL; + } + cr_set = false; + } + + if (modifier == 3) { // Alt, do nothing + } else if (modifier == 2) { // saturation + sp_document_maybe_done (sp_desktop_document(parent->getDesktop()), undokey, + SP_VERB_DIALOG_FILL_STROKE, ("Adjust saturation")); + + } else if (modifier == 1) { // lightness + sp_document_maybe_done (sp_desktop_document(parent->getDesktop()), undokey, + SP_VERB_DIALOG_FILL_STROKE, ("Adjust lightness")); + + } else { // hue + sp_document_maybe_done (sp_desktop_document(parent->getDesktop()), undokey, + SP_VERB_DIALOG_FILL_STROKE, ("Adjust hue")); + } + + if (!strcmp(undokey, "ssrot1")) { + undokey = "ssrot2"; + } else { + undokey = "ssrot1"; + } + + parent->getDesktop()->event_context->_message_context->clear(); + startcolor_set = false; +} + +/* ============================================= RotateableStrokeWidth */ + +RotateableStrokeWidth::RotateableStrokeWidth() { + undokey = "swrot1"; + startvalue_set = false; + cr = NULL; + cr_set = false; +} + +RotateableStrokeWidth::~RotateableStrokeWidth() { +} + +double +RotateableStrokeWidth::value_adjust(double current, double by, guint modifier, bool final) +{ + double newval; + // by is -1..1 + if (by < 0) { + // map negative 0..-1 to current..0 + newval = current * (1 + by); + } else { + // map positive 0..1 to current..4*current + newval = current * (1 + by) * (1 + by); + } + + SPCSSAttr *css = sp_repr_css_attr_new (); + if (final && newval < 1e-6) { + // if dragged into zero and this is the final adjust on mouse release, delete stroke; + // if it's not final, leave it a chance to increase again (which is not possible with "none") + sp_repr_css_set_property (css, "stroke", "none"); + } else { + Inkscape::CSSOStringStream os; + os << newval; + sp_repr_css_set_property (css, "stroke-width", os.str().c_str()); + } + + sp_desktop_set_style (parent->getDesktop(), css); + sp_repr_css_attr_unref (css); + return newval - current; +} + +void +RotateableStrokeWidth::do_motion(double by, guint modifier) { + + // if this is the first motion after a mouse grab, remember the current width + if (!startvalue_set) { + startvalue = parent->current_stroke_width; + // if it's 0, adjusting (which uses multiplication) will not be able to change it, so we + // cheat and provide a non-zero value + if (startvalue == 0) + startvalue = 1; + startvalue_set = true; + } + + if (modifier == 3) { // Alt, do nothing + } else { + double diff = value_adjust(startvalue, by, modifier, false); + sp_document_maybe_done (sp_desktop_document(parent->getDesktop()), undokey, + SP_VERB_DIALOG_FILL_STROKE, (_("Adjust stroke width"))); + parent->getDesktop()->event_context->_message_context->setF(Inkscape::IMMEDIATE_MESSAGE, _("Adjusting stroke width: was %.3g, now %.3g (diff %.3g)"), startvalue, startvalue + diff, diff); + } +} + +void +RotateableStrokeWidth::do_release(double by, guint modifier) { + + if (modifier == 3) { // do nothing + + } else { + value_adjust(startvalue, by, modifier, true); + startvalue_set = false; + sp_document_maybe_done (sp_desktop_document(parent->getDesktop()), undokey, + SP_VERB_DIALOG_FILL_STROKE, (_("Adjust stroke width"))); + } + + if (!strcmp(undokey, "swrot1")) { + undokey = "swrot2"; + } else { + undokey = "swrot1"; + } + parent->getDesktop()->event_context->_message_context->clear(); +} + + +Dialog::FillAndStroke *get_fill_and_stroke_panel(SPDesktop *desktop) +{ + if (Dialog::PanelDialogBase *panel_dialog = + dynamic_cast(desktop->_dlg_mgr->getDialog("FillAndStroke"))) { + try { + Dialog::FillAndStroke &fill_and_stroke = + dynamic_cast(panel_dialog->getPanel()); + return &fill_and_stroke; + } catch (std::exception e) { } + } + + return 0; +} + } // namespace Widget } // namespace UI } // namespace Inkscape -/* +/* Local Variables: mode:c++ c-file-style:"stroustrup"