From fe3827f737c49fe915c1119616e101577c999f18 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Mon, 18 Jun 2012 12:07:21 +0100 Subject: Fix crash in fill and stroke dialog with GTK+ 3 Fixed bugs: - https://launchpad.net/bugs/1011331 (bzr r11504) --- src/widgets/stroke-style.cpp | 107 +++++++++++++++++++++++++++++++++---------- 1 file changed, 83 insertions(+), 24 deletions(-) (limited to 'src/widgets/stroke-style.cpp') diff --git a/src/widgets/stroke-style.cpp b/src/widgets/stroke-style.cpp index 90bd62847..90634fe87 100644 --- a/src/widgets/stroke-style.cpp +++ b/src/widgets/stroke-style.cpp @@ -253,15 +253,24 @@ static gboolean stroke_width_set_unit(SPUnitSelector *, /* Absolute to percentage */ spw->set_data ("update", GUINT_TO_POINTER (TRUE)); +#if WITH_GTKMM_3_0 + Glib::RefPtr *a = static_cast *>(spw->get_data("width")); + float w = sp_units_get_pixels( (*a)->get_value(), *old); +#else Gtk::Adjustment *a = static_cast(spw->get_data("width")); - float w = sp_units_get_pixels (a->get_value(), *old); + float w = sp_units_get_pixels(a->get_value(), *old); +#endif gdouble average = stroke_average_width (objects); if (average == Geom::infinity() || average == 0) return FALSE; - a->set_value (100.0 * w / average); +#if WITH_GTKMM_3_0 + (*a)->set_value(100.0 * w / average); +#else + a->set_value(100.0 * w / average); +#endif spw->set_data ("update", GUINT_TO_POINTER (FALSE)); return TRUE; @@ -272,11 +281,19 @@ static gboolean stroke_width_set_unit(SPUnitSelector *, /* Percentage to absolute */ spw->set_data ("update", GUINT_TO_POINTER (TRUE)); - Gtk::Adjustment *a = static_cast(spw->get_data ("width")); +#if WITH_GTKMM_3_0 + Glib::RefPtr *a = static_cast *>(spw->get_data("width")); +#else + Gtk::Adjustment *a = static_cast(spw->get_data("width")); +#endif gdouble average = stroke_average_width (objects); +#if WITH_GTKMM_3_0 + (*a)->set_value (sp_pixels_get_units (0.01 * (*a)->get_value() * average, *new_units)); +#else a->set_value (sp_pixels_get_units (0.01 * a->get_value() * average, *new_units)); +#endif spw->set_data ("update", GUINT_TO_POINTER (FALSE)); return TRUE; @@ -291,23 +308,18 @@ static gboolean stroke_width_set_unit(SPUnitSelector *, */ Gtk::Container *sp_stroke_style_line_widget_new(void) { - Gtk::Widget *us; - SPDashSelector *ds; - GtkWidget *us_old, *spw_old; - Gtk::Container *spw; - Gtk::Table *t; Inkscape::UI::Widget::SpinButton *sb; Gtk::RadioButton *tb; - Gtk::HBox *f, *hb; + Gtk::HBox *hb; - spw_old = sp_widget_new_global(INKSCAPE); - spw = dynamic_cast(manage(Glib::wrap(spw_old))); + GtkWidget *spw_old = sp_widget_new_global(INKSCAPE); + Gtk::Container *spw = dynamic_cast(manage(Glib::wrap(spw_old))); - f = new Gtk::HBox(false, 0); + Gtk::HBox *f = new Gtk::HBox(false, 0); f->show(); spw->add(*f); - t = new Gtk::Table(3, 6, false); + Gtk::Table *t = new Gtk::Table(3, 6, false); t->show(); t->set_border_width(4); t->set_row_spacings(4); @@ -328,9 +340,9 @@ Gtk::Container *sp_stroke_style_line_widget_new(void) // function in desktop-style. #if WITH_GTKMM_3_0 - Glib::RefPtr a = Gtk::Adjustment::create(1.0, 0.0, 1000.0, 0.1, 10.0, 0.0); - spw->set_data("width", &a); - sb = new Inkscape::UI::Widget::SpinButton(a, 0.1, 3); + Glib::RefPtr *a = new Glib::RefPtr(Gtk::Adjustment::create(1.0, 0.0, 1000.0, 0.1, 10.0, 0.0)); + spw->set_data("width", a); + sb = new Inkscape::UI::Widget::SpinButton(*a, 0.1, 3); #else Gtk::Adjustment *a = new Gtk::Adjustment(1.0, 0.0, 1000.0, 0.1, 10.0, 0.0); spw->set_data("width", a); @@ -343,19 +355,29 @@ Gtk::Container *sp_stroke_style_line_widget_new(void) sp_dialog_defocus_on_enter_cpp(sb); hb->pack_start(*sb, false, false, 0); - us_old = sp_unit_selector_new(SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE); - us = manage(Glib::wrap(us_old)); + GtkWidget *us_old = sp_unit_selector_new(SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE); + Gtk::Widget *us = manage(Glib::wrap(us_old)); SPDesktop *desktop = SP_ACTIVE_DESKTOP; if (desktop) sp_unit_selector_set_unit (SP_UNIT_SELECTOR(us_old), sp_desktop_namedview(desktop)->doc_units); sp_unit_selector_add_unit(SP_UNIT_SELECTOR(us_old), &sp_unit_get_by_id(SP_UNIT_PERCENT), 0); g_signal_connect ( G_OBJECT (us_old), "set_unit", G_CALLBACK (stroke_width_set_unit), spw ); us->show(); + +#if WITH_GTKMM_3_0 + sp_unit_selector_add_adjustment( SP_UNIT_SELECTOR(us_old), GTK_ADJUSTMENT((*a)->gobj()) ); +#else sp_unit_selector_add_adjustment( SP_UNIT_SELECTOR(us_old), GTK_ADJUSTMENT(a->gobj()) ); +#endif + hb->pack_start(*us, FALSE, FALSE, 0); spw->set_data("units", us_old); +#if WITH_GTKMM_3_0 + (*a)->signal_value_changed().connect(sigc::bind(sigc::ptr_fun(&sp_stroke_style_width_changed), spw)); +#else a->signal_value_changed().connect(sigc::bind(sigc::ptr_fun(&sp_stroke_style_width_changed), spw)); +#endif i++; /* Join type */ @@ -410,9 +432,9 @@ Gtk::Container *sp_stroke_style_line_widget_new(void) hb = spw_hbox(t, 3, 1, i); #if WITH_GTKMM_3_0 - a = Gtk::Adjustment::create(4.0, 0.0, 100.0, 0.1, 10.0, 0.0); - spw->set_data("miterlimit", &a); - sb = new Inkscape::UI::Widget::SpinButton(a, 0.1, 2); + a = new Glib::RefPtr(Gtk::Adjustment::create(4.0, 0.0, 100.0, 0.1, 10.0, 0.0)); + spw->set_data("miterlimit", a); + sb = new Inkscape::UI::Widget::SpinButton(*a, 0.1, 2); #else a = new Gtk::Adjustment(4.0, 0.0, 100.0, 0.1, 10.0, 0.0); spw->set_data("miterlimit", a); @@ -427,7 +449,11 @@ Gtk::Container *sp_stroke_style_line_widget_new(void) hb->pack_start(*sb, false, false, 0); +#if WITH_GTKMM_3_0 + (*a)->signal_value_changed().connect(sigc::bind(sigc::ptr_fun(&sp_stroke_style_miterlimit_changed), spw)); +#else a->signal_value_changed().connect(sigc::bind(sigc::ptr_fun(&sp_stroke_style_miterlimit_changed), spw)); +#endif i++; /* Cap type */ @@ -472,7 +498,7 @@ Gtk::Container *sp_stroke_style_line_widget_new(void) // implement a set_mnemonic_source function in the // SPDashSelector class, so that we do not have to // expose any of the underlying widgets? - ds = manage(new SPDashSelector); + SPDashSelector *ds = manage(new SPDashSelector); ds->show(); t->attach(*ds, 1, 4, i, i+1, (Gtk::EXPAND | Gtk::FILL), static_cast(0), 0, 0); @@ -646,8 +672,15 @@ sp_stroke_style_line_update(Gtk::Container *spw, Inkscape::Selection *sel) FillOrStroke kind = GPOINTER_TO_INT(spw->get_data("kind")) ? FILL : STROKE; Gtk::Table *sset = static_cast(spw->get_data("stroke")); + +#if WITH_GTKMM_3_0 + Glib::RefPtr *width = static_cast *>(spw->get_data("width")); + Glib::RefPtr *ml = static_cast *>(spw->get_data("miterlimit")); +#else Gtk::Adjustment *width = static_cast(spw->get_data("width")); Gtk::Adjustment *ml = static_cast(spw->get_data("miterlimit")); +#endif + SPUnitSelector *us = SP_UNIT_SELECTOR(spw->get_data("units")); SPDashSelector *dsel = static_cast(spw->get_data("dash")); @@ -685,9 +718,17 @@ sp_stroke_style_line_update(Gtk::Container *spw, Inkscape::Selection *sel) if (unit->base == SP_UNIT_ABSOLUTE || unit->base == SP_UNIT_DEVICE) { double avgwidth = sp_pixels_get_units (query->stroke_width.computed, *unit); +#if WITH_GTKMM_3_0 + (*width)->set_value(avgwidth); +#else width->set_value(avgwidth); +#endif } else { +#if WITH_GTKMM_3_0 + (*width)->set_value(100); +#else width->set_value(100); +#endif } // if none of the selected objects has a stroke, than quite some controls should be disabled @@ -717,7 +758,11 @@ sp_stroke_style_line_update(Gtk::Container *spw, Inkscape::Selection *sel) } if (result_ml != QUERY_STYLE_NOTHING) +#if WITH_GTKMM_3_0 + (*ml)->set_value(query->stroke_miterlimit.value); // TODO: reflect averagedness? +#else ml->set_value(query->stroke_miterlimit.value); // TODO: reflect averagedness? +#endif if (result_join != QUERY_STYLE_MULTIPLE_DIFFERENT) { sp_jointype_set(spw, query->stroke_linejoin.value); @@ -790,10 +835,16 @@ sp_stroke_style_scale_line(Gtk::Container *spw) spw->set_data("update", GINT_TO_POINTER(TRUE)); +#if WITH_GTKMM_3_0 + Glib::RefPtr *wadj = static_cast *>(spw->get_data("width")); + Glib::RefPtr *ml = static_cast *>(spw->get_data("miterlimit")); +#else Gtk::Adjustment *wadj = static_cast(spw->get_data("width")); + Gtk::Adjustment *ml = static_cast(spw->get_data("miterlimit")); +#endif + SPUnitSelector *us = SP_UNIT_SELECTOR(spw->get_data("units")); SPDashSelector *dsel = static_cast(spw->get_data("dash")); - Gtk::Adjustment *ml = static_cast(spw->get_data("miterlimit")); SPDesktop *desktop = SP_ACTIVE_DESKTOP; SPDocument *document = sp_desktop_document (desktop); @@ -805,9 +856,13 @@ sp_stroke_style_scale_line(Gtk::Container *spw) SPCSSAttr *css = sp_repr_css_attr_new(); if (items) { - +#if WITH_GTKMM_3_0 + double width_typed = (*wadj)->get_value(); + double const miterlimit = (*ml)->get_value(); +#else double width_typed = wadj->get_value(); double const miterlimit = ml->get_value(); +#endif SPUnit const *const unit = sp_unit_selector_get_unit(SP_UNIT_SELECTOR(us)); @@ -847,7 +902,11 @@ sp_stroke_style_scale_line(Gtk::Container *spw) if (unit->base != SP_UNIT_ABSOLUTE && unit->base != SP_UNIT_DEVICE) { // reset to 100 percent +#if WITH_GTKMM_3_0 + (*wadj)->set_value(100.0); +#else wadj->set_value(100.0); +#endif } } -- cgit v1.2.3 From 3105af2e1edcb50e3d2e67f04f859165de2f5951 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sat, 23 Jun 2012 13:55:01 +0100 Subject: Migrate to new device pointer API for GTK+ 3 (bzr r11511) --- src/widgets/stroke-style.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/widgets/stroke-style.cpp') diff --git a/src/widgets/stroke-style.cpp b/src/widgets/stroke-style.cpp index 90634fe87..d6168ca04 100644 --- a/src/widgets/stroke-style.cpp +++ b/src/widgets/stroke-style.cpp @@ -341,13 +341,12 @@ Gtk::Container *sp_stroke_style_line_widget_new(void) #if WITH_GTKMM_3_0 Glib::RefPtr *a = new Glib::RefPtr(Gtk::Adjustment::create(1.0, 0.0, 1000.0, 0.1, 10.0, 0.0)); - spw->set_data("width", a); - sb = new Inkscape::UI::Widget::SpinButton(*a, 0.1, 3); #else Gtk::Adjustment *a = new Gtk::Adjustment(1.0, 0.0, 1000.0, 0.1, 10.0, 0.0); +#endif + spw->set_data("width", a); sb = new Inkscape::UI::Widget::SpinButton(*a, 0.1, 3); -#endif sb->set_tooltip_text(_("Stroke width")); sb->show(); spw_label(t, C_("Stroke width", "_Width:"), 0, i, sb); -- cgit v1.2.3 From 6946c98d961a414b23a056ad15c784ac114f12c8 Mon Sep 17 00:00:00 2001 From: John Smith Date: Sat, 4 Aug 2012 10:55:39 +0900 Subject: Fix for 1032880 : Stroke style panel is mirrored between open windows (bzr r11587) --- src/widgets/stroke-style.cpp | 981 +++++++++++++++++++------------------------ 1 file changed, 434 insertions(+), 547 deletions(-) (limited to 'src/widgets/stroke-style.cpp') diff --git a/src/widgets/stroke-style.cpp b/src/widgets/stroke-style.cpp index d6168ca04..1a1865326 100644 --- a/src/widgets/stroke-style.cpp +++ b/src/widgets/stroke-style.cpp @@ -17,106 +17,309 @@ #define noSP_SS_VERBOSE -#include "widgets/dash-selector.h" -#include -#include -#include - -#include "desktop-handles.h" -#include "desktop-style.h" -#include "dialogs/dialog-events.h" -#include "display/canvas-bpath.h" // for SP_STROKE_LINEJOIN_* -#include "display/drawing.h" -#include "document-private.h" -#include "document-undo.h" -#include "gradient-chemistry.h" -#include "helper/stock-items.h" -#include "helper/unit-menu.h" -#include "helper/units.h" -#include "inkscape.h" -#include "io/sys.h" -#include "marker.h" -#include "path-prefix.h" -#include "selection.h" -#include "sp-linear-gradient.h" -#include "sp-namedview.h" -#include "sp-pattern.h" -#include "sp-radial-gradient.h" -#include "sp-rect.h" -#include "sp-text.h" -#include "style.h" -#include "svg/css-ostringstream.h" -#include "ui/cache/svg_preview_cache.h" -#include "ui/icon-names.h" -#include "widgets/icon.h" -#include "widgets/paint-selector.h" -#include "widgets/sp-widget.h" -#include "widgets/spw-utilities.h" -#include "ui/widget/spinbutton.h" -#include "xml/repr.h" - #include "stroke-style.h" -#include "stroke-marker-selector.h" -#include "fill-style.h" // to get sp_fill_style_widget_set_desktop -#include "fill-n-stroke-factory.h" - -#include "verbs.h" using Inkscape::DocumentUndo; - -static MarkerComboBox *start_marker_combobox = NULL; -static MarkerComboBox *mid_marker_combobox = NULL; -static MarkerComboBox *end_marker_combobox = NULL; - -sigc::connection start_marker_connection; -sigc::connection mid_marker_connection; -sigc::connection end_marker_connection; - -static SPObject *ink_extract_marker_name(gchar const *n, SPDocument *doc); -static void ink_markers_combo_update(Gtk::Container* spw, SPMarkerLoc const which); - +/** + * Creates a new widget for the line stroke paint. + */ Gtk::Widget *sp_stroke_style_paint_widget_new(void) { return Inkscape::Widgets::createStyleWidget( STROKE ); } +/** + * Creates a new widget for the line stroke style. + */ +Gtk::Widget *sp_stroke_style_line_widget_new(void) +{ + return Inkscape::Widgets::createStrokeStyleWidget(); +} + void sp_stroke_style_widget_set_desktop(Gtk::Widget *widget, SPDesktop *desktop) { - sp_fill_style_widget_set_desktop(widget, desktop); + Inkscape::StrokeStyle *ss = dynamic_cast(widget); + if (ss) { + ss->setDesktop(desktop); + } +} + +namespace Inkscape { + +/** + * Create the fill or stroke style widget, and hook up all the signals. + */ +Gtk::Widget *Inkscape::Widgets::createStrokeStyleWidget( ) +{ + StrokeStyle *strokeStyle = new StrokeStyle(); + + return strokeStyle; } -/* Line */ +StrokeStyle::StrokeStyle() : + Gtk::VBox(), + miterLimitSpin(), + widthSpin(), + unitSelector(), + joinMiter(), + joinRound(), + joinBevel(), + capButt(), + capRound(), + capSquare(), + dashSelector(), + update(false), + desktop(0), + selectChangedConn(), + selectModifiedConn(), + startMarkerConn(), + midMarkerConn(), + endMarkerConn() +{ + Gtk::HBox *hb; + Gtk::HBox *f = new Gtk::HBox(false, 0); + f->show(); + add(*f); + + table = new Gtk::Table(3, 6, false); + table->show(); + table->set_border_width(4); + table->set_row_spacings(4); + f->add(*table); -static void sp_stroke_style_line_selection_modified(SPWidget *spw, Inkscape::Selection *selection, guint flags, gpointer data); -static void sp_stroke_style_line_selection_changed(SPWidget *spw, Inkscape::Selection *selection, gpointer data); + gint i = 0; + + //spw_label(t, C_("Stroke width", "_Width:"), 0, i); -static void sp_stroke_style_line_update(Gtk::Container *spw, Inkscape::Selection *sel); + hb = spw_hbox(table, 3, 1, i); -static void sp_stroke_style_set_join_buttons(Gtk::Container *spw, Gtk::ToggleButton *active); +// TODO: when this is gtkmmified, use an Inkscape::UI::Widget::ScalarUnit instead of the separate +// spinbutton and unit selector for stroke width. In sp_stroke_style_line_update, use +// setHundredPercent to remember the averaged width corresponding to 100%. Then the +// stroke_width_set_unit will be removed (because ScalarUnit takes care of conversions itself), and +// with it, the two remaining calls of stroke_average_width, allowing us to get rid of that +// function in desktop-style. -static void sp_stroke_style_set_cap_buttons(Gtk::Container *spw, Gtk::ToggleButton *active); +#if WITH_GTKMM_3_0 + widthAdj = new Glib::RefPtr(Gtk::Adjustment::create(1.0, 0.0, 1000.0, 0.1, 10.0, 0.0)); +#else + widthAdj = new Gtk::Adjustment(1.0, 0.0, 1000.0, 0.1, 10.0, 0.0); +#endif -static void sp_stroke_style_width_changed(Gtk::Container *spw); -static void sp_stroke_style_miterlimit_changed(Gtk::Container *spw); -static void sp_stroke_style_any_toggled(Gtk::ToggleButton *tb, Gtk::Container *spw); -static void sp_stroke_style_line_dash_changed(Gtk::Container *spw); + widthSpin = new Inkscape::UI::Widget::SpinButton(*widthAdj, 0.1, 3); + widthSpin->set_tooltip_text(_("Stroke width")); + widthSpin->show(); + spw_label(table, C_("Stroke width", "_Width:"), 0, i, widthSpin); -static void sp_stroke_style_update_marker_combo(Gtk::Container *spw, GSList const *objects); + sp_dialog_defocus_on_enter_cpp(widthSpin); + + hb->pack_start(*widthSpin, false, false, 0); + unitSelector = sp_unit_selector_new(SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE); + Gtk::Widget *us = manage(Glib::wrap(unitSelector)); + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + + if (desktop) + sp_unit_selector_set_unit (SP_UNIT_SELECTOR(unitSelector), sp_desktop_namedview(desktop)->doc_units); + sp_unit_selector_add_unit(SP_UNIT_SELECTOR(unitSelector), &sp_unit_get_by_id(SP_UNIT_PERCENT), 0); + g_signal_connect ( G_OBJECT (unitSelector), "set_unit", G_CALLBACK (StrokeStyle::setStrokeWidthUnit), this ); + us->show(); + +#if WITH_GTKMM_3_0 + sp_unit_selector_add_adjustment( SP_UNIT_SELECTOR(unitSelector), GTK_ADJUSTMENT((*widthAdj)->gobj()) ); +#else + sp_unit_selector_add_adjustment( SP_UNIT_SELECTOR(unitSelector), GTK_ADJUSTMENT(widthAdj->gobj()) ); +#endif + + hb->pack_start(*us, FALSE, FALSE, 0); + +#if WITH_GTKMM_3_0 + (*widthAdj)->signal_value_changed().connect(sigc::mem_fun(*this, &StrokeStyle::widthChangedCB)); +#else + widthAdj->signal_value_changed().connect(sigc::mem_fun(*this, &StrokeStyle::widthChangedCB)); +#endif + i++; + + /* Join type */ + // TRANSLATORS: The line join style specifies the shape to be used at the + // corners of paths. It can be "miter", "round" or "bevel". + spw_label(table, _("Join:"), 0, i, NULL); + + hb = spw_hbox(table, 3, 1, i); + + //tb = NULL; + + joinMiter = makeRadioButton(NULL, INKSCAPE_ICON("stroke-join-miter"), + hb, "join", "miter"); + // TRANSLATORS: Miter join: joining lines with a sharp (pointed) corner. + // For an example, draw a triangle with a large stroke width and modify the + // "Join" option (in the Fill and Stroke dialog). + joinMiter->set_tooltip_text(_("Miter join")); + + joinRound = makeRadioButton(joinMiter, INKSCAPE_ICON("stroke-join-round"), + hb, "join", "round"); + // TRANSLATORS: Round join: joining lines with a rounded corner. + // For an example, draw a triangle with a large stroke width and modify the + // "Join" option (in the Fill and Stroke dialog). + joinRound->set_tooltip_text(_("Round join")); + + joinBevel = makeRadioButton(joinMiter, INKSCAPE_ICON("stroke-join-bevel"), + hb, "join", "bevel"); + // TRANSLATORS: Bevel join: joining lines with a blunted (flattened) corner. + // For an example, draw a triangle with a large stroke width and modify the + // "Join" option (in the Fill and Stroke dialog). + joinBevel->set_tooltip_text(_("Bevel join")); + + i++; + + /* Miterlimit */ + // TRANSLATORS: Miter limit: only for "miter join", this limits the length + // of the sharp "spike" when the lines connect at too sharp an angle. + // When two line segments meet at a sharp angle, a miter join results in a + // spike that extends well beyond the connection point. The purpose of the + // miter limit is to cut off such spikes (i.e. convert them into bevels) + // when they become too long. + //spw_label(t, _("Miter _limit:"), 0, i); + + hb = spw_hbox(table, 3, 1, i); + +#if WITH_GTKMM_3_0 + miterLimitAdj = new Glib::RefPtr(Gtk::Adjustment::create(4.0, 0.0, 100.0, 0.1, 10.0, 0.0)); + miterLimitSpin = new Inkscape::UI::Widget::SpinButton(*miterLimitAdj, 0.1, 2); +#else + miterLimitAdj = new Gtk::Adjustment(4.0, 0.0, 100.0, 0.1, 10.0, 0.0); + miterLimitSpin = new Inkscape::UI::Widget::SpinButton(*miterLimitAdj, 0.1, 2); +#endif + + miterLimitSpin->set_tooltip_text(_("Maximum length of the miter (in units of stroke width)")); + miterLimitSpin->show(); + spw_label(table, _("Miter _limit:"), 0, i, miterLimitSpin); + sp_dialog_defocus_on_enter_cpp(miterLimitSpin); + + hb->pack_start(*miterLimitSpin, false, false, 0); + +#if WITH_GTKMM_3_0 + (*miterLimitAdj)->signal_value_changed().connect(sigc::mem_fun(*this, &StrokeStyle::miterLimitChangedCB)); + +#else + miterLimitAdj->signal_value_changed().connect(sigc::mem_fun(*this, &StrokeStyle::miterLimitChangedCB)); +#endif + i++; + + /* Cap type */ + // TRANSLATORS: cap type specifies the shape for the ends of lines + //spw_label(t, _("_Cap:"), 0, i); + spw_label(table, _("Cap:"), 0, i, NULL); + + hb = spw_hbox(table, 3, 1, i); + + capButt = makeRadioButton(capButt, INKSCAPE_ICON("stroke-cap-butt"), + hb, "cap", "butt"); + // TRANSLATORS: Butt cap: the line shape does not extend beyond the end point + // of the line; the ends of the line are square + capButt->set_tooltip_text(_("Butt cap")); + + capRound = makeRadioButton(capButt, INKSCAPE_ICON("stroke-cap-round"), + hb, "cap", "round"); + // TRANSLATORS: Round cap: the line shape extends beyond the end point of the + // line; the ends of the line are rounded + capRound->set_tooltip_text(_("Round cap")); + + capSquare = makeRadioButton(capButt, INKSCAPE_ICON("stroke-cap-square"), + hb, "cap", "square"); + // TRANSLATORS: Square cap: the line shape extends beyond the end point of the + // line; the ends of the line are square + capSquare->set_tooltip_text(_("Square cap")); + + i++; + + /* Dash */ + spw_label(table, _("Dashes:"), 0, i, NULL); //no mnemonic for now + //decide what to do: + // implement a set_mnemonic_source function in the + // SPDashSelector class, so that we do not have to + // expose any of the underlying widgets? + dashSelector = manage(new SPDashSelector); + + dashSelector->show(); + table->attach(*dashSelector, 1, 4, i, i+1, (Gtk::EXPAND | Gtk::FILL), static_cast(0), 0, 0); + dashSelector->changed_signal.connect(sigc::mem_fun(*this, &StrokeStyle::lineDashChangedCB)); + + i++; + + /* Drop down marker selectors*/ + // TRANSLATORS: Path markers are an SVG feature that allows you to attach arbitrary shapes + // (arrowheads, bullets, faces, whatever) to the start, end, or middle nodes of a path. + + startMarkerCombo = manage(new MarkerComboBox("marker-start")); + spw_label(table, _("_Start Markers:"), 0, i, startMarkerCombo); + startMarkerCombo->set_tooltip_text(_("Start Markers are drawn on the first node of a path or shape")); + startMarkerConn = startMarkerCombo->signal_changed().connect( + sigc::bind( + sigc::ptr_fun(&StrokeStyle::markerSelectCB), startMarkerCombo, this, SP_MARKER_LOC_START)); + startMarkerCombo->show(); + table->attach(*startMarkerCombo, 1, 4, i, i+1, (Gtk::EXPAND | Gtk::FILL), static_cast(0), 0, 0); + i++; + + midMarkerCombo = manage(new MarkerComboBox("marker-mid")); + spw_label(table, _("_Mid Markers:"), 0, i, midMarkerCombo); + midMarkerCombo->set_tooltip_text(_("Mid Markers are drawn on every node of a path or shape except the first and last nodes")); + midMarkerConn = midMarkerCombo->signal_changed().connect( + sigc::bind( + sigc::ptr_fun(&StrokeStyle::markerSelectCB), midMarkerCombo, this, SP_MARKER_LOC_MID)); + midMarkerCombo->show(); + table->attach(*midMarkerCombo, 1, 4, i, i+1, (Gtk::EXPAND | Gtk::FILL), static_cast(0), 0, 0); + i++; + + endMarkerCombo = manage(new MarkerComboBox("marker-end")); + spw_label(table, _("_End Markers:"), 0, i, endMarkerCombo); + endMarkerCombo->set_tooltip_text(_("End Markers are drawn on the last node of a path or shape")); + endMarkerConn = endMarkerCombo->signal_changed().connect( + sigc::bind( + sigc::ptr_fun(&StrokeStyle::markerSelectCB), endMarkerCombo, this, SP_MARKER_LOC_END)); + endMarkerCombo->show(); + table->attach(*endMarkerCombo, 1, 4, i, i+1, (Gtk::EXPAND | Gtk::FILL), static_cast(0), 0, 0); + i++; + + setDesktop(desktop); + updateLine(); + +} + +StrokeStyle::~StrokeStyle() +{ + selectModifiedConn.disconnect(); + selectChangedConn.disconnect(); +} + +void StrokeStyle::setDesktop(SPDesktop *desktop) +{ + if (this->desktop != desktop) { + + if (this->desktop) { + selectModifiedConn.disconnect(); + selectChangedConn.disconnect(); + } + this->desktop = desktop; + if (desktop && desktop->selection) { + selectChangedConn = desktop->selection->connectChanged(sigc::hide(sigc::mem_fun(*this, &StrokeStyle::selectionChangedCB))); + selectModifiedConn = desktop->selection->connectModified(sigc::hide<0>(sigc::mem_fun(*this, &StrokeStyle::selectionModifiedCB))); + } + updateLine(); + } +} /** * Helper function for creating radio buttons. This should probably be re-thought out * when reimplementing this with Gtkmm. */ -static Gtk::RadioButton * -sp_stroke_radio_button(Gtk::RadioButton *tb, char const *icon, - Gtk::HBox *hb, Gtk::Container *spw, - gchar const *key, gchar const *data) +Gtk::RadioButton * +StrokeStyle::makeRadioButton(Gtk::RadioButton *tb, char const *icon, + Gtk::HBox *hb, gchar const *key, gchar const *data) { g_assert(icon != NULL); g_assert(hb != NULL); - g_assert(spw != NULL); if (tb == NULL) { tb = new Gtk::RadioButton(); @@ -128,10 +331,13 @@ sp_stroke_radio_button(Gtk::RadioButton *tb, char const *icon, tb->show(); tb->set_mode(false); hb->pack_start(*tb, false, false, 0); - spw->set_data(icon, tb); + // TODO + set_data(icon, tb); tb->set_data(key, (gpointer*)data); - tb->signal_toggled().connect(sigc::bind( - sigc::ptr_fun(&sp_stroke_style_any_toggled), tb, spw)); + + tb->signal_toggled().connect(sigc::bind( + sigc::ptr_fun(&StrokeStyle::buttonToggledCB), tb, this)); + Gtk::Widget *px = manage(Glib::wrap(sp_icon_new(Inkscape::ICON_SIZE_LARGE_TOOLBAR, icon))); g_assert(px != NULL); px->show(); @@ -146,15 +352,14 @@ sp_stroke_radio_button(Gtk::RadioButton *tb, char const *icon, * Gets the marker uri string and applies it to all selected * items in the current desktop. */ -static void -sp_marker_select(MarkerComboBox *marker_combo, Gtk::Container *spw, SPMarkerLoc const which) +void +StrokeStyle::markerSelectCB(MarkerComboBox *marker_combo, StrokeStyle *spw, SPMarkerLoc const which) { - if (spw->get_data("update")) { + if (spw->update) { return; } - SPDesktop *desktop = inkscape_active_desktop(); - SPDocument *document = sp_desktop_document(desktop); + SPDocument *document = sp_desktop_document(spw->desktop); if (!document) { return; } @@ -162,7 +367,6 @@ sp_marker_select(MarkerComboBox *marker_combo, Gtk::Container *spw, SPMarkerLoc /* Get Marker */ gchar const *marker = marker_combo->get_active_marker_uri(); - SPCSSAttr *css = sp_repr_css_attr_new(); gchar const *combo_id = marker_combo->get_id(); sp_repr_css_set_property(css, combo_id, marker); @@ -170,9 +374,9 @@ sp_marker_select(MarkerComboBox *marker_combo, Gtk::Container *spw, SPMarkerLoc // Also update the marker combobox, so the document's markers // show up at the top of the combobox // sp_stroke_style_line_update( SP_WIDGET(spw), desktop ? sp_desktop_selection(desktop) : NULL); - ink_markers_combo_update(spw, which); + spw->updateMarkerHist(which); - Inkscape::Selection *selection = sp_desktop_selection(desktop); + Inkscape::Selection *selection = sp_desktop_selection(spw->desktop); GSList const *items = selection->itemList(); for (; items != NULL; items = items->next) { SPItem *item = reinterpret_cast(items->data); @@ -195,26 +399,26 @@ sp_marker_select(MarkerComboBox *marker_combo, Gtk::Container *spw, SPMarkerLoc }; -static void -ink_markers_combo_update(Gtk::Container* /*spw*/, SPMarkerLoc const which) { +void +StrokeStyle::updateMarkerHist(SPMarkerLoc const which) { switch (which) { case SP_MARKER_LOC_START: - start_marker_connection.block(); - start_marker_combobox->set_active_history(); - start_marker_connection.unblock(); + startMarkerConn.block(); + startMarkerCombo->set_active_history(); + startMarkerConn.unblock(); break; case SP_MARKER_LOC_MID: - mid_marker_connection.block(); - mid_marker_combobox->set_active_history(); - mid_marker_connection.unblock(); + midMarkerConn.block(); + midMarkerCombo->set_active_history(); + midMarkerConn.unblock(); break; case SP_MARKER_LOC_END: - end_marker_connection.block(); - end_marker_combobox->set_active_history(); - end_marker_connection.unblock(); + endMarkerConn.block(); + endMarkerCombo->set_active_history(); + endMarkerConn.unblock(); break; default: g_assert_not_reached(); @@ -225,22 +429,20 @@ ink_markers_combo_update(Gtk::Container* /*spw*/, SPMarkerLoc const which) { * Sets the stroke width units for all selected items. * Also handles absolute and dimensionless units. */ -static gboolean stroke_width_set_unit(SPUnitSelector *, +gboolean StrokeStyle::setStrokeWidthUnit(SPUnitSelector *, SPUnit const *old, SPUnit const *new_units, - Gtk::Container *spw) + StrokeStyle *spw) { - if (spw->get_data("update")) { + if (spw->update) { return FALSE; } - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - - if (!desktop) { + if (!spw->desktop) { return FALSE; } - Inkscape::Selection *selection = sp_desktop_selection (desktop); + Inkscape::Selection *selection = sp_desktop_selection (spw->desktop); if (selection->isEmpty()) return FALSE; @@ -251,14 +453,12 @@ static gboolean stroke_width_set_unit(SPUnitSelector *, (new_units->base == SP_UNIT_DIMENSIONLESS)) { /* Absolute to percentage */ - spw->set_data ("update", GUINT_TO_POINTER (TRUE)); + spw->update = true; #if WITH_GTKMM_3_0 - Glib::RefPtr *a = static_cast *>(spw->get_data("width")); - float w = sp_units_get_pixels( (*a)->get_value(), *old); + float w = sp_units_get_pixels( (*spw->widthAdj)->get_value(), *old); #else - Gtk::Adjustment *a = static_cast(spw->get_data("width")); - float w = sp_units_get_pixels(a->get_value(), *old); + float w = sp_units_get_pixels(spw->widthAdj->get_value(), *old); #endif gdouble average = stroke_average_width (objects); @@ -267,330 +467,62 @@ static gboolean stroke_width_set_unit(SPUnitSelector *, return FALSE; #if WITH_GTKMM_3_0 - (*a)->set_value(100.0 * w / average); + (*spw->widthAdj)->set_value(100.0 * w / average); #else - a->set_value(100.0 * w / average); + spw->widthAdj->set_value(100.0 * w / average); #endif - spw->set_data ("update", GUINT_TO_POINTER (FALSE)); + spw->update = false; return TRUE; } else if ((old->base == SP_UNIT_DIMENSIONLESS) && (new_units->base == SP_UNIT_ABSOLUTE || new_units->base == SP_UNIT_DEVICE)) { /* Percentage to absolute */ - spw->set_data ("update", GUINT_TO_POINTER (TRUE)); - -#if WITH_GTKMM_3_0 - Glib::RefPtr *a = static_cast *>(spw->get_data("width")); -#else - Gtk::Adjustment *a = static_cast(spw->get_data("width")); -#endif + spw->update = true; gdouble average = stroke_average_width (objects); #if WITH_GTKMM_3_0 - (*a)->set_value (sp_pixels_get_units (0.01 * (*a)->get_value() * average, *new_units)); + (*spw->widthAdj)->set_value (sp_pixels_get_units (0.01 * (*spw->widthAdj)->get_value() * average, *new_units)); #else - a->set_value (sp_pixels_get_units (0.01 * a->get_value() * average, *new_units)); + spw->widthAdj->set_value (sp_pixels_get_units (0.01 * spw->widthAdj->get_value() * average, *new_units)); #endif - spw->set_data ("update", GUINT_TO_POINTER (FALSE)); + spw->update = false; return TRUE; } return FALSE; } - -/** - * Creates a new widget for the line stroke style. - */ -Gtk::Container *sp_stroke_style_line_widget_new(void) -{ - Inkscape::UI::Widget::SpinButton *sb; - Gtk::RadioButton *tb; - Gtk::HBox *hb; - - GtkWidget *spw_old = sp_widget_new_global(INKSCAPE); - Gtk::Container *spw = dynamic_cast(manage(Glib::wrap(spw_old))); - - Gtk::HBox *f = new Gtk::HBox(false, 0); - f->show(); - spw->add(*f); - - Gtk::Table *t = new Gtk::Table(3, 6, false); - t->show(); - t->set_border_width(4); - t->set_row_spacings(4); - f->add(*t); - spw->set_data("stroke", t); - - gint i = 0; - - //spw_label(t, C_("Stroke width", "_Width:"), 0, i); - - hb = spw_hbox(t, 3, 1, i); - -// TODO: when this is gtkmmified, use an Inkscape::UI::Widget::ScalarUnit instead of the separate -// spinbutton and unit selector for stroke width. In sp_stroke_style_line_update, use -// setHundredPercent to remember the averaged width corresponding to 100%. Then the -// stroke_width_set_unit will be removed (because ScalarUnit takes care of conversions itself), and -// with it, the two remaining calls of stroke_average_width, allowing us to get rid of that -// function in desktop-style. - -#if WITH_GTKMM_3_0 - Glib::RefPtr *a = new Glib::RefPtr(Gtk::Adjustment::create(1.0, 0.0, 1000.0, 0.1, 10.0, 0.0)); -#else - Gtk::Adjustment *a = new Gtk::Adjustment(1.0, 0.0, 1000.0, 0.1, 10.0, 0.0); -#endif - - spw->set_data("width", a); - sb = new Inkscape::UI::Widget::SpinButton(*a, 0.1, 3); - sb->set_tooltip_text(_("Stroke width")); - sb->show(); - spw_label(t, C_("Stroke width", "_Width:"), 0, i, sb); - - sp_dialog_defocus_on_enter_cpp(sb); - - hb->pack_start(*sb, false, false, 0); - GtkWidget *us_old = sp_unit_selector_new(SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE); - Gtk::Widget *us = manage(Glib::wrap(us_old)); - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - if (desktop) - sp_unit_selector_set_unit (SP_UNIT_SELECTOR(us_old), sp_desktop_namedview(desktop)->doc_units); - sp_unit_selector_add_unit(SP_UNIT_SELECTOR(us_old), &sp_unit_get_by_id(SP_UNIT_PERCENT), 0); - g_signal_connect ( G_OBJECT (us_old), "set_unit", G_CALLBACK (stroke_width_set_unit), spw ); - us->show(); - -#if WITH_GTKMM_3_0 - sp_unit_selector_add_adjustment( SP_UNIT_SELECTOR(us_old), GTK_ADJUSTMENT((*a)->gobj()) ); -#else - sp_unit_selector_add_adjustment( SP_UNIT_SELECTOR(us_old), GTK_ADJUSTMENT(a->gobj()) ); -#endif - - hb->pack_start(*us, FALSE, FALSE, 0); - spw->set_data("units", us_old); - -#if WITH_GTKMM_3_0 - (*a)->signal_value_changed().connect(sigc::bind(sigc::ptr_fun(&sp_stroke_style_width_changed), spw)); -#else - a->signal_value_changed().connect(sigc::bind(sigc::ptr_fun(&sp_stroke_style_width_changed), spw)); -#endif - i++; - - /* Join type */ - // TRANSLATORS: The line join style specifies the shape to be used at the - // corners of paths. It can be "miter", "round" or "bevel". - spw_label(t, _("Join:"), 0, i, NULL); - - hb = spw_hbox(t, 3, 1, i); - - tb = NULL; - - tb = sp_stroke_radio_button(tb, INKSCAPE_ICON("stroke-join-miter"), - hb, spw, "join", "miter"); - - // TRANSLATORS: Miter join: joining lines with a sharp (pointed) corner. - // For an example, draw a triangle with a large stroke width and modify the - // "Join" option (in the Fill and Stroke dialog). - tb->set_tooltip_text(_("Miter join")); - spw->set_data("miter join", tb); - - tb = sp_stroke_radio_button(tb, INKSCAPE_ICON("stroke-join-round"), - hb, spw, "join", "round"); - - - // TRANSLATORS: Round join: joining lines with a rounded corner. - // For an example, draw a triangle with a large stroke width and modify the - // "Join" option (in the Fill and Stroke dialog). - tb->set_tooltip_text(_("Round join")); - spw->set_data("round join", tb); - - tb = sp_stroke_radio_button(tb, INKSCAPE_ICON("stroke-join-bevel"), - hb, spw, "join", "bevel"); - - - // TRANSLATORS: Bevel join: joining lines with a blunted (flattened) corner. - // For an example, draw a triangle with a large stroke width and modify the - // "Join" option (in the Fill and Stroke dialog). - tb->set_tooltip_text(_("Bevel join")); - spw->set_data("bevel join", tb); - - i++; - - /* Miterlimit */ - // TRANSLATORS: Miter limit: only for "miter join", this limits the length - // of the sharp "spike" when the lines connect at too sharp an angle. - // When two line segments meet at a sharp angle, a miter join results in a - // spike that extends well beyond the connection point. The purpose of the - // miter limit is to cut off such spikes (i.e. convert them into bevels) - // when they become too long. - //spw_label(t, _("Miter _limit:"), 0, i); - - hb = spw_hbox(t, 3, 1, i); - -#if WITH_GTKMM_3_0 - a = new Glib::RefPtr(Gtk::Adjustment::create(4.0, 0.0, 100.0, 0.1, 10.0, 0.0)); - spw->set_data("miterlimit", a); - sb = new Inkscape::UI::Widget::SpinButton(*a, 0.1, 2); -#else - a = new Gtk::Adjustment(4.0, 0.0, 100.0, 0.1, 10.0, 0.0); - spw->set_data("miterlimit", a); - sb = new Inkscape::UI::Widget::SpinButton(*a, 0.1, 2); -#endif - - sb->set_tooltip_text(_("Maximum length of the miter (in units of stroke width)")); - sb->show(); - spw_label(t, _("Miter _limit:"), 0, i, sb); - spw->set_data("miterlimit_sb", sb); - sp_dialog_defocus_on_enter_cpp(sb); - - hb->pack_start(*sb, false, false, 0); - -#if WITH_GTKMM_3_0 - (*a)->signal_value_changed().connect(sigc::bind(sigc::ptr_fun(&sp_stroke_style_miterlimit_changed), spw)); -#else - a->signal_value_changed().connect(sigc::bind(sigc::ptr_fun(&sp_stroke_style_miterlimit_changed), spw)); -#endif - i++; - - /* Cap type */ - // TRANSLATORS: cap type specifies the shape for the ends of lines - //spw_label(t, _("_Cap:"), 0, i); - spw_label(t, _("Cap:"), 0, i, NULL); - - hb = spw_hbox(t, 3, 1, i); - - tb = NULL; - - tb = sp_stroke_radio_button(tb, INKSCAPE_ICON("stroke-cap-butt"), - hb, spw, "cap", "butt"); - spw->set_data("cap butt", tb); - - // TRANSLATORS: Butt cap: the line shape does not extend beyond the end point - // of the line; the ends of the line are square - tb->set_tooltip_text(_("Butt cap")); - - tb = sp_stroke_radio_button(tb, INKSCAPE_ICON("stroke-cap-round"), - hb, spw, "cap", "round"); - spw->set_data("cap round", tb); - - // TRANSLATORS: Round cap: the line shape extends beyond the end point of the - // line; the ends of the line are rounded - tb->set_tooltip_text(_("Round cap")); - - tb = sp_stroke_radio_button(tb, INKSCAPE_ICON("stroke-cap-square"), - hb, spw, "cap", "square"); - spw->set_data("cap square", tb); - - // TRANSLATORS: Square cap: the line shape extends beyond the end point of the - // line; the ends of the line are square - tb->set_tooltip_text(_("Square cap")); - - i++; - - - /* Dash */ - spw_label(t, _("Dashes:"), 0, i, NULL); //no mnemonic for now - //decide what to do: - // implement a set_mnemonic_source function in the - // SPDashSelector class, so that we do not have to - // expose any of the underlying widgets? - SPDashSelector *ds = manage(new SPDashSelector); - - ds->show(); - t->attach(*ds, 1, 4, i, i+1, (Gtk::EXPAND | Gtk::FILL), static_cast(0), 0, 0); - spw->set_data("dash", ds); - ds->changed_signal.connect(sigc::bind(sigc::ptr_fun(&sp_stroke_style_line_dash_changed), spw)); - i++; - - /* Drop down marker selectors*/ - // TRANSLATORS: Path markers are an SVG feature that allows you to attach arbitrary shapes - // (arrowheads, bullets, faces, whatever) to the start, end, or middle nodes of a path. - - start_marker_combobox = manage(new MarkerComboBox("marker-start")); - spw_label(t, _("_Start Markers:"), 0, i, start_marker_combobox); - start_marker_combobox->set_tooltip_text(_("Start Markers are drawn on the first node of a path or shape")); - start_marker_connection = start_marker_combobox->signal_changed().connect( - sigc::bind( - sigc::ptr_fun(&sp_marker_select), start_marker_combobox, spw, SP_MARKER_LOC_START)); - start_marker_combobox->show(); - t->attach(*start_marker_combobox, 1, 4, i, i+1, (Gtk::EXPAND | Gtk::FILL), static_cast(0), 0, 0); - spw->set_data("start_marker_combobox", start_marker_combobox); - i++; - - mid_marker_combobox = manage(new MarkerComboBox("marker-mid")); - spw_label(t, _("_Mid Markers:"), 0, i, mid_marker_combobox); - mid_marker_combobox->set_tooltip_text(_("Mid Markers are drawn on every node of a path or shape except the first and last nodes")); - mid_marker_connection = mid_marker_combobox->signal_changed().connect( - sigc::bind( - sigc::ptr_fun(&sp_marker_select), mid_marker_combobox, spw, SP_MARKER_LOC_MID)); - mid_marker_combobox->show(); - t->attach(*mid_marker_combobox, 1, 4, i, i+1, (Gtk::EXPAND | Gtk::FILL), static_cast(0), 0, 0); - spw->set_data("mid_marker_combobox", mid_marker_combobox); - i++; - - end_marker_combobox = manage(new MarkerComboBox("marker-end")); - spw_label(t, _("_End Markers:"), 0, i, end_marker_combobox); - end_marker_combobox->set_tooltip_text(_("End Markers are drawn on the last node of a path or shape")); - end_marker_connection = end_marker_combobox->signal_changed().connect( - sigc::bind( - sigc::ptr_fun(&sp_marker_select), end_marker_combobox, spw, SP_MARKER_LOC_END)); - end_marker_combobox->show(); - t->attach(*end_marker_combobox, 1, 4, i, i+1, (Gtk::EXPAND | Gtk::FILL), static_cast(0), 0, 0); - spw->set_data("end_marker_combobox", end_marker_combobox); - i++; - - // FIXME: we cheat and still use gtk+ signals - - g_signal_connect(G_OBJECT(spw_old), "modify_selection", - G_CALLBACK(sp_stroke_style_line_selection_modified), - spw); - g_signal_connect(G_OBJECT(spw_old), "change_selection", - G_CALLBACK(sp_stroke_style_line_selection_changed), - spw); - - sp_stroke_style_line_update(spw, desktop ? sp_desktop_selection(desktop) : NULL); - - return spw; -} - /** * Callback for when stroke style widget is modified. * Triggers update action. */ -static void -sp_stroke_style_line_selection_modified(SPWidget *, - Inkscape::Selection *selection, - guint flags, - gpointer data) +void +StrokeStyle::selectionModifiedCB(guint flags) { - Gtk::Container *spw = static_cast(data); if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_PARENT_MODIFIED_FLAG)) { - sp_stroke_style_line_update(spw, selection); + updateLine(); } - } /** * Callback for when stroke style widget is changed. * Triggers update action. */ -static void -sp_stroke_style_line_selection_changed(SPWidget *, - Inkscape::Selection *selection, - gpointer data) +void +StrokeStyle::selectionChangedCB() { - Gtk::Container *spw = static_cast(data); - sp_stroke_style_line_update(spw, selection); + updateLine(); } /** * Sets selector widgets' dash style from an SPStyle object. */ -static void -sp_dash_selector_set_from_style(SPDashSelector *dsel, SPStyle *style) +void +StrokeStyle::setDashSelectorFromStyle(SPDashSelector *dsel, SPStyle *style) { if (style->stroke_dash.n_dash > 0) { double d[64]; @@ -612,76 +544,66 @@ sp_dash_selector_set_from_style(SPDashSelector *dsel, SPStyle *style) /** * Sets the join type for a line, and updates the stroke style widget's buttons */ -static void -sp_jointype_set (Gtk::Container *spw, unsigned const jointype) +void +StrokeStyle::setJoinType (unsigned const jointype) { Gtk::RadioButton *tb = NULL; switch (jointype) { case SP_STROKE_LINEJOIN_MITER: - tb = static_cast(spw->get_data(INKSCAPE_ICON("stroke-join-miter"))); + tb = joinMiter; break; case SP_STROKE_LINEJOIN_ROUND: - tb = static_cast(spw->get_data(INKSCAPE_ICON("stroke-join-round"))); + tb = joinRound; break; case SP_STROKE_LINEJOIN_BEVEL: - tb = static_cast(spw->get_data(INKSCAPE_ICON("stroke-join-bevel"))); + tb = joinBevel; break; default: break; } - sp_stroke_style_set_join_buttons(spw, tb); + setJoinButtons(tb); } /** * Sets the cap type for a line, and updates the stroke style widget's buttons */ -static void -sp_captype_set (Gtk::Container *spw, unsigned const captype) +void +StrokeStyle::setCapType (unsigned const captype) { Gtk::RadioButton *tb = NULL; switch (captype) { case SP_STROKE_LINECAP_BUTT: - tb = static_cast(spw->get_data(INKSCAPE_ICON("stroke-cap-butt"))); + tb = capButt; break; case SP_STROKE_LINECAP_ROUND: - tb = static_cast(spw->get_data(INKSCAPE_ICON("stroke-cap-round"))); + tb = capRound; break; case SP_STROKE_LINECAP_SQUARE: - tb = static_cast(spw->get_data(INKSCAPE_ICON("stroke-cap-square"))); + tb = capSquare; break; default: break; } - sp_stroke_style_set_cap_buttons(spw, tb); + setCapButtons(tb); } /** * Callback for when stroke style widget is updated, including markers, cap type, * join type, etc. */ -static void -sp_stroke_style_line_update(Gtk::Container *spw, Inkscape::Selection *sel) +void +StrokeStyle::updateLine() { - if (spw->get_data("update")) { + if (update) { return; } - spw->set_data("update", GINT_TO_POINTER(TRUE)); + update = true; - FillOrStroke kind = GPOINTER_TO_INT(spw->get_data("kind")) ? FILL : STROKE; + Inkscape::Selection *sel = desktop ? sp_desktop_selection(desktop) : NULL; - Gtk::Table *sset = static_cast(spw->get_data("stroke")); - -#if WITH_GTKMM_3_0 - Glib::RefPtr *width = static_cast *>(spw->get_data("width")); - Glib::RefPtr *ml = static_cast *>(spw->get_data("miterlimit")); -#else - Gtk::Adjustment *width = static_cast(spw->get_data("width")); - Gtk::Adjustment *ml = static_cast(spw->get_data("miterlimit")); -#endif - - SPUnitSelector *us = SP_UNIT_SELECTOR(spw->get_data("units")); - SPDashSelector *dsel = static_cast(spw->get_data("dash")); + // TODO + FillOrStroke kind = GPOINTER_TO_INT(get_data("kind")) ? FILL : STROKE; // create temporary style SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT); @@ -694,39 +616,39 @@ sp_stroke_style_line_update(Gtk::Container *spw, Inkscape::Selection *sel) if (!sel || sel->isEmpty()) { // Nothing selected, grey-out all controls in the stroke-style dialog - sset->set_sensitive(false); + table->set_sensitive(false); - spw->set_data("update", GINT_TO_POINTER(FALSE)); + update = false; return; } else { - sset->set_sensitive(true); + table->set_sensitive(true); - SPUnit const *unit = sp_unit_selector_get_unit(us); + SPUnit const *unit = sp_unit_selector_get_unit(SP_UNIT_SELECTOR(unitSelector)); if (result_sw == QUERY_STYLE_MULTIPLE_AVERAGED) { - sp_unit_selector_set_unit(us, &sp_unit_get_by_id(SP_UNIT_PERCENT)); + sp_unit_selector_set_unit(SP_UNIT_SELECTOR(unitSelector), &sp_unit_get_by_id(SP_UNIT_PERCENT)); } else { // same width, or only one object; no sense to keep percent, switch to absolute if (unit->base != SP_UNIT_ABSOLUTE && unit->base != SP_UNIT_DEVICE) { - sp_unit_selector_set_unit(us, sp_desktop_namedview(SP_ACTIVE_DESKTOP)->doc_units); + sp_unit_selector_set_unit(SP_UNIT_SELECTOR(unitSelector), sp_desktop_namedview(SP_ACTIVE_DESKTOP)->doc_units); } } - unit = sp_unit_selector_get_unit(us); + unit = sp_unit_selector_get_unit(SP_UNIT_SELECTOR(unitSelector)); if (unit->base == SP_UNIT_ABSOLUTE || unit->base == SP_UNIT_DEVICE) { double avgwidth = sp_pixels_get_units (query->stroke_width.computed, *unit); #if WITH_GTKMM_3_0 - (*width)->set_value(avgwidth); + (*widthAdj)->set_value(avgwidth); #else - width->set_value(avgwidth); + widthAdj->set_value(avgwidth); #endif } else { #if WITH_GTKMM_3_0 - (*width)->set_value(100); + (*widthAdj)->set_value(100); #else - width->set_value(100); + widthAdj->set_value(100); #endif } @@ -734,45 +656,36 @@ sp_stroke_style_line_update(Gtk::Container *spw, Inkscape::Selection *sel) // The markers might still be shown though, so these will not be disabled bool enabled = (result_sw != QUERY_STYLE_NOTHING) && !targPaint.isNoneSet(); /* No objects stroked, set insensitive */ - Gtk::RadioButton *tb = NULL; - tb = static_cast(spw->get_data("miter join")); - tb->set_sensitive(enabled); - tb = static_cast(spw->get_data("round join")); - tb->set_sensitive(enabled); - tb = static_cast(spw->get_data("bevel join")); - tb->set_sensitive(enabled); - - Inkscape::UI::Widget::SpinButton* sb = NULL; - sb = static_cast(spw->get_data("miterlimit_sb")); - sb->set_sensitive(enabled); - - tb = static_cast(spw->get_data("cap butt")); - tb->set_sensitive(enabled); - tb = static_cast(spw->get_data("cap round")); - tb->set_sensitive(enabled); - tb = static_cast(spw->get_data("cap square")); - tb->set_sensitive(enabled); - - dsel->set_sensitive(enabled); + joinMiter->set_sensitive(enabled); + joinRound->set_sensitive(enabled); + joinBevel->set_sensitive(enabled); + + miterLimitSpin->set_sensitive(enabled); + + capButt->set_sensitive(enabled); + capRound->set_sensitive(enabled); + capSquare->set_sensitive(enabled); + + dashSelector->set_sensitive(enabled); } if (result_ml != QUERY_STYLE_NOTHING) #if WITH_GTKMM_3_0 - (*ml)->set_value(query->stroke_miterlimit.value); // TODO: reflect averagedness? + (*miterLimitAdj)->set_value(query->stroke_miterlimit.value); // TODO: reflect averagedness? #else - ml->set_value(query->stroke_miterlimit.value); // TODO: reflect averagedness? + miterLimitAdj->set_value(query->stroke_miterlimit.value); // TODO: reflect averagedness? #endif if (result_join != QUERY_STYLE_MULTIPLE_DIFFERENT) { - sp_jointype_set(spw, query->stroke_linejoin.value); + setJoinType(query->stroke_linejoin.value); } else { - sp_stroke_style_set_join_buttons(spw, NULL); + setJoinButtons(NULL); } if (result_cap != QUERY_STYLE_MULTIPLE_DIFFERENT) { - sp_captype_set (spw, query->stroke_linecap.value); + setCapType (query->stroke_linecap.value); } else { - sp_stroke_style_set_cap_buttons(spw, NULL); + setCapButtons(NULL); } sp_style_unref(query); @@ -785,21 +698,21 @@ sp_stroke_style_line_update(Gtk::Container *spw, Inkscape::Selection *sel) SPStyle * const style = object->style; /* Markers */ - sp_stroke_style_update_marker_combo(spw, objects); // FIXME: make this desktop query too + updateAllMarkers(objects); // FIXME: make this desktop query too /* Dash */ - sp_dash_selector_set_from_style(dsel, style); // FIXME: make this desktop query too + setDashSelectorFromStyle(dashSelector, style); // FIXME: make this desktop query too - sset->set_sensitive(true); + table->set_sensitive(true); - spw->set_data("update", GINT_TO_POINTER(FALSE)); + update = false; } /** * Sets a line's dash properties in a CSS style object. */ -static void -sp_stroke_style_set_scaled_dash(SPCSSAttr *css, +void +StrokeStyle::setScaledDash(SPCSSAttr *css, int ndash, double *dash, double offset, double scale) { @@ -825,27 +738,15 @@ sp_stroke_style_set_scaled_dash(SPCSSAttr *css, /** * Sets line properties like width, dashes, markers, etc. on all currently selected items. */ -static void -sp_stroke_style_scale_line(Gtk::Container *spw) +void +StrokeStyle::scaleLine() { - if (spw->get_data("update")) { + if (update) { return; } - spw->set_data("update", GINT_TO_POINTER(TRUE)); - -#if WITH_GTKMM_3_0 - Glib::RefPtr *wadj = static_cast *>(spw->get_data("width")); - Glib::RefPtr *ml = static_cast *>(spw->get_data("miterlimit")); -#else - Gtk::Adjustment *wadj = static_cast(spw->get_data("width")); - Gtk::Adjustment *ml = static_cast(spw->get_data("miterlimit")); -#endif + update = true; - SPUnitSelector *us = SP_UNIT_SELECTOR(spw->get_data("units")); - SPDashSelector *dsel = static_cast(spw->get_data("dash")); - - SPDesktop *desktop = SP_ACTIVE_DESKTOP; SPDocument *document = sp_desktop_document (desktop); Inkscape::Selection *selection = sp_desktop_selection (desktop); @@ -856,18 +757,18 @@ sp_stroke_style_scale_line(Gtk::Container *spw) if (items) { #if WITH_GTKMM_3_0 - double width_typed = (*wadj)->get_value(); - double const miterlimit = (*ml)->get_value(); + double width_typed = (*widthAdj)->get_value(); + double const miterlimit = (*miterLimitAdj)->get_value(); #else - double width_typed = wadj->get_value(); - double const miterlimit = ml->get_value(); + double width_typed = widthAdj->get_value(); + double const miterlimit = miterLimitAdj->get_value(); #endif - SPUnit const *const unit = sp_unit_selector_get_unit(SP_UNIT_SELECTOR(us)); + SPUnit const *const unit = sp_unit_selector_get_unit(SP_UNIT_SELECTOR(unitSelector)); double *dash, offset; int ndash; - dsel->get_dash(&ndash, &dash, &offset); + dashSelector->get_dash(&ndash, &dash, &offset); for (GSList const *i = items; i != NULL; i = i->next) { /* Set stroke width */ @@ -892,7 +793,7 @@ sp_stroke_style_scale_line(Gtk::Container *spw) } /* Set dash */ - sp_stroke_style_set_scaled_dash(css, ndash, dash, offset, width); + setScaledDash(css, ndash, dash, offset, width); sp_desktop_apply_css_recursive (SP_OBJECT(i->data), css, true); } @@ -902,9 +803,9 @@ sp_stroke_style_scale_line(Gtk::Container *spw) if (unit->base != SP_UNIT_ABSOLUTE && unit->base != SP_UNIT_DEVICE) { // reset to 100 percent #if WITH_GTKMM_3_0 - (*wadj)->set_value(100.0); + (*widthAdj)->set_value(100.0); #else - wadj->set_value(100.0); + widthAdj->set_value(100.0); #endif } @@ -920,35 +821,35 @@ sp_stroke_style_scale_line(Gtk::Container *spw) DocumentUndo::done(document, SP_VERB_DIALOG_FILL_STROKE, _("Set stroke style")); - spw->set_data("update", GINT_TO_POINTER(FALSE)); + update = false; } /** * Callback for when the stroke style's width changes. * Causes all line styles to be applied to all selected items. */ -static void -sp_stroke_style_width_changed(Gtk::Container *spw) +void +StrokeStyle::widthChangedCB() { - if (spw->get_data("update")) { + if (update) { return; } - sp_stroke_style_scale_line(spw); + scaleLine(); } /** * Callback for when the stroke style's miterlimit changes. * Causes all line styles to be applied to all selected items. */ -static void -sp_stroke_style_miterlimit_changed(Gtk::Container *spw) +void +StrokeStyle::miterLimitChangedCB() { - if (spw->get_data("update")) { + if (update) { return; } - sp_stroke_style_scale_line(spw); + scaleLine(); } /** @@ -956,14 +857,14 @@ sp_stroke_style_miterlimit_changed(Gtk::Container *spw) * Causes all line styles to be applied to all selected items. */ -static void -sp_stroke_style_line_dash_changed(Gtk::Container *spw) +void +StrokeStyle::lineDashChangedCB() { - if (spw->get_data("update")) { + if (update) { return; } - sp_stroke_style_scale_line(spw); + scaleLine(); } /** @@ -973,48 +874,45 @@ sp_stroke_style_line_dash_changed(Gtk::Container *spw) * calls the respective routines to update css properties, etc. * */ -static void sp_stroke_style_any_toggled(Gtk::ToggleButton *tb, Gtk::Container *spw) +void StrokeStyle::buttonToggledCB(Gtk::ToggleButton *tb, StrokeStyle *spw) { - if (spw->get_data("update")) { + if (spw->update) { return; } - if (tb->get_active()) { + // TODO gchar const *join = static_cast(tb->get_data("join")); gchar const *cap = static_cast(tb->get_data("cap")); if (join) { - Gtk::SpinButton *ml = static_cast(spw->get_data("miterlimit_sb")); - ml->set_sensitive(!strcmp(join, "miter")); + spw->miterLimitSpin->set_sensitive(!strcmp(join, "miter")); } - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - /* TODO: Create some standardized method */ SPCSSAttr *css = sp_repr_css_attr_new(); if (join) { sp_repr_css_set_property(css, "stroke-linejoin", join); - sp_desktop_set_style (desktop, css); + sp_desktop_set_style (spw->desktop, css); - sp_stroke_style_set_join_buttons(spw, tb); + spw->setJoinButtons(tb); } else if (cap) { sp_repr_css_set_property(css, "stroke-linecap", cap); - sp_desktop_set_style (desktop, css); + sp_desktop_set_style (spw->desktop, css); - sp_stroke_style_set_cap_buttons(spw, tb); + spw->setCapButtons(tb); } sp_repr_css_attr_unref(css); css = 0; - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_DIALOG_FILL_STROKE, + DocumentUndo::done(sp_desktop_document(spw->desktop), SP_VERB_DIALOG_FILL_STROKE, _("Set stroke style")); } } @@ -1022,38 +920,24 @@ static void sp_stroke_style_any_toggled(Gtk::ToggleButton *tb, Gtk::Container *s /** * Updates the join style toggle buttons */ -static void -sp_stroke_style_set_join_buttons(Gtk::Container *spw, Gtk::ToggleButton *active) +void +StrokeStyle::setJoinButtons(Gtk::ToggleButton *active) { - Gtk::RadioButton *tb; - - tb = static_cast(spw->get_data(INKSCAPE_ICON("stroke-join-miter"))); - tb->set_active(active == tb); - - Gtk::SpinButton *ml = static_cast(spw->get_data("miterlimit_sb")); - ml->set_sensitive(active == tb); - - tb = static_cast(spw->get_data(INKSCAPE_ICON("stroke-join-round"))); - tb->set_active(active == tb); - - tb = static_cast(spw->get_data(INKSCAPE_ICON("stroke-join-bevel"))); - tb->set_active(active == tb); + joinMiter->set_active(active == joinMiter); + miterLimitSpin->set_sensitive(active == joinMiter); + joinRound->set_active(active == joinRound); + joinBevel->set_active(active == joinBevel); } /** * Updates the cap style toggle buttons */ -static void -sp_stroke_style_set_cap_buttons(Gtk::Container *spw, Gtk::ToggleButton *active) +void +StrokeStyle::setCapButtons(Gtk::ToggleButton *active) { - Gtk::RadioButton *tb; - - tb = static_cast(spw->get_data(INKSCAPE_ICON("stroke-cap-butt"))); - tb->set_active(active == tb); - tb = static_cast(spw->get_data(INKSCAPE_ICON("stroke-cap-round"))); - tb->set_active(active == tb); - tb = static_cast(spw->get_data(INKSCAPE_ICON("stroke-cap-square"))); - tb->set_active(active == tb); + capButt->set_active(active == capButt); + capRound->set_active(active == capRound); + capSquare->set_active(active == capSquare); } @@ -1061,13 +945,13 @@ sp_stroke_style_set_cap_buttons(Gtk::Container *spw, Gtk::ToggleButton *active) * Updates the marker combobox to highlight the appropriate marker and scroll to * that marker. */ -static void -sp_stroke_style_update_marker_combo(Gtk::Container *spw, GSList const *objects) +void +StrokeStyle::updateAllMarkers(GSList const *objects) { - struct { char const *key; int loc; } const keyloc[] = { - { "start_marker_combobox", SP_MARKER_LOC_START }, - { "mid_marker_combobox", SP_MARKER_LOC_MID }, - { "end_marker_combobox", SP_MARKER_LOC_END } + struct { MarkerComboBox *key; int loc; } const keyloc[] = { + { startMarkerCombo, SP_MARKER_LOC_START }, + { midMarkerCombo, SP_MARKER_LOC_MID }, + { endMarkerCombo, SP_MARKER_LOC_END } }; bool all_texts = true; @@ -1078,7 +962,7 @@ sp_stroke_style_update_marker_combo(Gtk::Container *spw, GSList const *objects) } for (unsigned i = 0; i < G_N_ELEMENTS(keyloc); ++i) { - MarkerComboBox *combo = static_cast(spw->get_data(keyloc[i].key)); + MarkerComboBox *combo = static_cast(keyloc[i].key); // Per SVG spec, text objects cannot have markers; disable combobox if only texts are selected combo->set_sensitive(!all_texts); } @@ -1091,7 +975,7 @@ sp_stroke_style_update_marker_combo(Gtk::Container *spw, GSList const *objects) // For all three marker types, // find the corresponding combobox item - MarkerComboBox *combo = static_cast(spw->get_data(keyloc[i].key)); + MarkerComboBox *combo = static_cast(keyloc[i].key); // Quit if we're in update state if (combo->update()) { @@ -1102,7 +986,7 @@ sp_stroke_style_update_marker_combo(Gtk::Container *spw, GSList const *objects) // If the object has this type of markers, // Extract the name of the marker that the object uses - SPObject *marker = ink_extract_marker_name(object->style->marker[keyloc[i].loc].value, object->document); + SPObject *marker = getMarkerName(object->style->marker[keyloc[i].loc].value, object->document); // Scroll the combobox to that marker combo->set_current(marker); @@ -1120,8 +1004,8 @@ sp_stroke_style_update_marker_combo(Gtk::Container *spw, GSList const *objects) * \return Buffer containing the actual name, allocated from GLib; * the caller should free the buffer when they no longer need it. */ -static SPObject* -ink_extract_marker_name(gchar const *n, SPDocument *doc) +SPObject* +StrokeStyle::getMarkerName(gchar const *n, SPDocument *doc) { gchar const *p = n; while (*p != '\0' && *p != '#') { @@ -1150,6 +1034,9 @@ ink_extract_marker_name(gchar const *n, SPDocument *doc) return marker; } +} // namespace Inkscape + + /* Local Variables: mode:c++ -- cgit v1.2.3 From 8d2e0c37027b55156c81a7733f35338409e37a00 Mon Sep 17 00:00:00 2001 From: John Smith Date: Sat, 4 Aug 2012 11:20:42 +0900 Subject: Fix for 1030239 : Custom markers only added to the list in Stroke Style after reloading the file (bzr r11588) --- src/widgets/stroke-style.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/widgets/stroke-style.cpp') diff --git a/src/widgets/stroke-style.cpp b/src/widgets/stroke-style.cpp index 1a1865326..695c16ced 100644 --- a/src/widgets/stroke-style.cpp +++ b/src/widgets/stroke-style.cpp @@ -982,6 +982,8 @@ StrokeStyle::updateAllMarkers(GSList const *objects) return; } + combo->setDesktop(desktop); + if (object->style->marker[keyloc[i].loc].value != NULL && !all_texts) { // If the object has this type of markers, -- cgit v1.2.3 From e92962ddc609aaba91d1b9781ea044e84bafeb1b Mon Sep 17 00:00:00 2001 From: John Smith Date: Mon, 20 Aug 2012 21:53:17 +0900 Subject: Fix for 165865 : markers must take object's stroke color (bzr r11614) --- src/widgets/stroke-style.cpp | 291 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 251 insertions(+), 40 deletions(-) (limited to 'src/widgets/stroke-style.cpp') diff --git a/src/widgets/stroke-style.cpp b/src/widgets/stroke-style.cpp index 695c16ced..2c39945f7 100644 --- a/src/widgets/stroke-style.cpp +++ b/src/widgets/stroke-style.cpp @@ -18,6 +18,10 @@ #define noSP_SS_VERBOSE #include "stroke-style.h" +#include "../gradient-chemistry.h" +#include "sp-gradient.h" +#include "sp-stop.h" +#include "svg/svg-color.h" using Inkscape::DocumentUndo; @@ -45,6 +49,42 @@ void sp_stroke_style_widget_set_desktop(Gtk::Widget *widget, SPDesktop *desktop) } } + +/** + * Extract the actual name of the link + * e.g. get mTriangle from url(#mTriangle). + * \return Buffer containing the actual name, allocated from GLib; + * the caller should free the buffer when they no longer need it. + */ +SPObject* getMarkerObj(gchar const *n, SPDocument *doc) +{ + gchar const *p = n; + while (*p != '\0' && *p != '#') { + p++; + } + + if (*p == '\0' || p[1] == '\0') { + return NULL; + } + + p++; + int c = 0; + while (p[c] != '\0' && p[c] != ')') { + c++; + } + + if (p[c] == '\0') { + return NULL; + } + + gchar* b = g_strdup(p); + b[c] = '\0'; + + // FIXME: get the document from the object and let the caller pass it in + SPObject *marker = doc->getObjectById(b); + return marker; +} + namespace Inkscape { /** @@ -331,7 +371,6 @@ StrokeStyle::makeRadioButton(Gtk::RadioButton *tb, char const *icon, tb->show(); tb->set_mode(false); hb->pack_start(*tb, false, false, 0); - // TODO set_data(icon, tb); tb->set_data(key, (gpointer*)data); @@ -359,6 +398,8 @@ StrokeStyle::markerSelectCB(MarkerComboBox *marker_combo, StrokeStyle *spw, SPMa return; } + spw->update = true; + SPDocument *document = sp_desktop_document(spw->desktop); if (!document) { return; @@ -367,6 +408,7 @@ StrokeStyle::markerSelectCB(MarkerComboBox *marker_combo, StrokeStyle *spw, SPMa /* Get Marker */ gchar const *marker = marker_combo->get_active_marker_uri(); + SPCSSAttr *css = sp_repr_css_attr_new(); gchar const *combo_id = marker_combo->get_id(); sp_repr_css_set_property(css, combo_id, marker); @@ -374,7 +416,7 @@ StrokeStyle::markerSelectCB(MarkerComboBox *marker_combo, StrokeStyle *spw, SPMa // Also update the marker combobox, so the document's markers // show up at the top of the combobox // sp_stroke_style_line_update( SP_WIDGET(spw), desktop ? sp_desktop_selection(desktop) : NULL); - spw->updateMarkerHist(which); + //spw->updateMarkerHist(which); Inkscape::Selection *selection = sp_desktop_selection(spw->desktop); GSList const *items = selection->itemList(); @@ -386,7 +428,14 @@ StrokeStyle::markerSelectCB(MarkerComboBox *marker_combo, StrokeStyle *spw, SPMa Inkscape::XML::Node *selrepr = item->getRepr(); if (selrepr) { sp_repr_css_change_recursive(selrepr, css, "style"); + SPObject *markerObj = getMarkerObj(marker, document); + if (!marker_combo->isSelectedStock()) { + // If arrow, marker will already be forked + markerObj = spw->forkMarker(item, markerObj, marker_combo); + } + spw->setMarkerColor(item, markerObj, marker_combo); } + item->requestModified(SP_OBJECT_MODIFIED_FLAG); item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); } @@ -397,6 +446,8 @@ StrokeStyle::markerSelectCB(MarkerComboBox *marker_combo, StrokeStyle *spw, SPMa DocumentUndo::done(document, SP_VERB_DIALOG_FILL_STROKE, _("Set markers")); + spw->update = false; + }; void @@ -518,6 +569,191 @@ StrokeStyle::selectionChangedCB() updateLine(); } +/* + * Make a new copy of a marker, set as auto collectable + * Set the referencing items url to the new marker + * Return the new marker + */ +SPObject * +StrokeStyle::forkMarker(SPItem *item, SPObject *marker, MarkerComboBox *marker_combo) +{ + + if (!item || !marker) { + return NULL; + } + + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + gboolean colorStock = prefs->getBool("/options/markers/colorStockMarkers", true); + gboolean colorCustom = prefs->getBool("/options/markers/colorCustomMarkers", false); + const gchar *stock = marker->getRepr()->attribute("inkscape:isstock"); + gboolean isStock = (!stock || !strcmp(stock,"true")); + gchar const *combo_id = marker_combo->get_id(); + + if (isStock ? !colorStock : !colorCustom) { + return marker; + } + + + /* + * Optimization + * If this item already has this marker elsewhere (start/mid or end), + * then we can reuse it and dont need to fork + */ + SPCSSAttr *css = sp_css_attr_from_object(item, SP_STYLE_FLAG_ALWAYS); + Glib::ustring urlId = Glib::ustring::format("url(#", marker->getRepr()->attribute("id"), ")"); + const gchar *markers[3] = { "marker-start", "marker-mid", "marker-end" }; + //gboolean exists = false; + for (int i = 0; i < 3; i++) { + if (!strcmp(marker_combo->get_id(), markers[i])) { + continue; + } + const char *urlMark = sp_repr_css_property(css, markers[i], ""); + if (!strcmp(urlId.c_str(), urlMark)) { + return marker; + } + } + + + SPDocument *doc = SP_ACTIVE_DOCUMENT; + SPDefs *defs = doc->getDefs(); + Inkscape::XML::Document *xml_doc = doc->getReprDoc(); + // Turn off garbage-collectable or it might be collected before we can use it + marker->getRepr()->setAttribute("inkscape:collect", NULL); + Inkscape::XML::Node *mark_repr = marker->getRepr()->duplicate(xml_doc); + defs->getRepr()->addChild(mark_repr, NULL); + gchar const *markid = marker->getRepr()->attribute("inkscape:stockid") ? marker->getRepr()->attribute("inkscape:stockid") : marker->getRepr()->attribute("id"); + mark_repr->setAttribute("inkscape:stockid", markid); + + // Update the items url to new marker + SPCSSAttr *css_item = sp_repr_css_attr_new(); + sp_repr_css_set_property(css_item, combo_id, g_strconcat("url(#", mark_repr->attribute("id"), ")", NULL)); + sp_repr_css_change_recursive(item->getRepr(), css_item, "style"); + + // privates are garbage-collectable + mark_repr->setAttribute("inkscape:collect", "always"); + marker->getRepr()->setAttribute("inkscape:collect", "always"); + + Inkscape::GC::release(mark_repr); + sp_repr_css_attr_unref(css_item); + css_item = 0; + + return doc->getObjectById(mark_repr->attribute("id")); +} + +/** + * Change the color of the marker to match the color of the item. + * Marker stroke color is set to item stroke color. + * Fill color : + * 1. If the item has fill, use that for the marker fill, + * 2. If the marker has same fill and stroke assume its solid, use item stroke for both fill and stroke the line stroke + * 3. If the marker has fill color, use the marker fill color + * + */ +void +StrokeStyle::setMarkerColor(SPItem *item, SPObject *marker, MarkerComboBox *marker_combo) +{ + + if (!item || !marker) { + return; + } + + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + gboolean colorStock = prefs->getBool("/options/markers/colorStockMarkers", true); + gboolean colorCustom = prefs->getBool("/options/markers/colorCustomMarkers", false); + const gchar *stock = marker->getRepr()->attribute("inkscape:isstock"); + gboolean isStock = (stock && !strcmp(stock,"true")); + + if (isStock ? !colorStock : !colorCustom) { + return; + } + + Inkscape::XML::Node *repr = marker->getRepr()->firstChild(); + if (!repr) { + return; + }; + + // Current line style + SPCSSAttr *css_item = sp_css_attr_from_object(item, SP_STYLE_FLAG_ALWAYS); + const char *lstroke = getItemColorForMarker(item, FOR_STROKE, marker_combo); + const char *lstroke_opacity = sp_repr_css_property(css_item, "stroke-opacity", "1"); + const char *lfill = getItemColorForMarker(item, FOR_FILL, marker_combo); + const char *lfill_opacity = sp_repr_css_property(css_item, "fill-opacity", "1"); + + // Current marker style + SPCSSAttr *css_marker = sp_css_attr_from_object(marker->firstChild(), SP_STYLE_FLAG_ALWAYS); + const char *mfill = sp_repr_css_property(css_marker, "fill", "none"); + const char *mstroke = sp_repr_css_property(css_marker, "fill", "none"); + + // Create new marker style with the lines stroke + SPCSSAttr *css = sp_repr_css_attr_new(); + + sp_repr_css_set_property(css, "stroke", lstroke); + sp_repr_css_set_property(css, "stroke-opacity", lstroke_opacity); + + if (strcmp(lfill, "none") ) { + // 1. If the line has fill, use that for the marker fill + sp_repr_css_set_property(css, "fill", lfill); + sp_repr_css_set_property(css, "fill-opacity", lfill_opacity); + } + else if (mfill && mstroke && !strcmp(mfill, mstroke) && mfill[0] == '#' && strcmp(mfill, "#ffffff")) { + // 2. If the marker has same fill and stroke assume its solid. use line stroke for both fill and stroke the line stroke + sp_repr_css_set_property(css, "fill", lstroke); + sp_repr_css_set_property(css, "fill-opacity", lstroke_opacity); + } + else if (mfill && mfill[0] == '#' && strcmp(mfill, "#000000")) { + // 3. If the marker has fill color, use the marker fill color + sp_repr_css_set_property(css, "fill", mfill); + //sp_repr_css_set_property(css, "fill-opacity", mfill_opacity); + } + + sp_repr_css_change_recursive(marker->firstChild()->getRepr(), css, "style"); + + // Tell the combos to update its image cache of this marker + gchar const *mid = marker->getRepr()->attribute("id"); + startMarkerCombo->update_marker_image(mid); + midMarkerCombo->update_marker_image(mid); + endMarkerCombo->update_marker_image(mid); + + sp_repr_css_attr_unref(css); + css = 0; + + +} + +/* + * Get the fill or stroke color of the item + * If its a gradient, then return first or last stop color + */ +const char * +StrokeStyle::getItemColorForMarker(SPItem *item, Inkscape::PaintTarget fill_or_stroke, MarkerComboBox *marker_combo) +{ + SPCSSAttr *css_item = sp_css_attr_from_object(item, SP_STYLE_FLAG_ALWAYS); + const char *color; + if (fill_or_stroke == FOR_FILL) + color = sp_repr_css_property(css_item, "fill", "none"); + else + color = sp_repr_css_property(css_item, "stroke", "none"); + + if (!strncmp (color, "url(", 4)) { + // If the item has a gradient use the first stop color for the marker + SPGradient *grad = getGradient(item, fill_or_stroke); + if (grad) { + SPGradient *vector = grad->getVector(FALSE); + SPStop *stop = vector->getFirstStop(); + if (marker_combo == endMarkerCombo) { + stop = sp_last_stop(vector); + } + if (stop) { + guint32 const c1 = sp_stop_get_rgba32(stop); + gchar c[64]; + sp_svg_write_color(c, sizeof(c), c1); + color = g_strdup(c); + //lstroke_opacity = Glib::ustring::format(stop->opacity).c_str(); + } + } + } + return color; +} /** * Sets selector widgets' dash style from an SPStyle object. */ @@ -602,7 +838,6 @@ StrokeStyle::updateLine() Inkscape::Selection *sel = desktop ? sp_desktop_selection(desktop) : NULL; - // TODO FillOrStroke kind = GPOINTER_TO_INT(get_data("kind")) ? FILL : STROKE; // create temporary style @@ -882,7 +1117,6 @@ void StrokeStyle::buttonToggledCB(Gtk::ToggleButton *tb, StrokeStyle *spw) if (tb->get_active()) { - // TODO gchar const *join = static_cast(tb->get_data("join")); gchar const *cap @@ -988,10 +1222,22 @@ StrokeStyle::updateAllMarkers(GSList const *objects) // If the object has this type of markers, // Extract the name of the marker that the object uses - SPObject *marker = getMarkerName(object->style->marker[keyloc[i].loc].value, object->document); + SPObject *marker = getMarkerObj(object->style->marker[keyloc[i].loc].value, object->document); // Scroll the combobox to that marker combo->set_current(marker); + // Set the marker color + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + gboolean update = prefs->getBool("/options/markers/colorUpdateMarkers", true); + + if (update) { + setMarkerColor(SP_ITEM(object), marker, combo); + + SPDocument *document = sp_desktop_document(desktop); + DocumentUndo::done(document, SP_VERB_DIALOG_FILL_STROKE, + _("Set marker color")); + } + } else { combo->set_current(NULL); } @@ -1000,41 +1246,6 @@ StrokeStyle::updateAllMarkers(GSList const *objects) } -/** - * Extract the actual name of the link - * e.g. get mTriangle from url(#mTriangle). - * \return Buffer containing the actual name, allocated from GLib; - * the caller should free the buffer when they no longer need it. - */ -SPObject* -StrokeStyle::getMarkerName(gchar const *n, SPDocument *doc) -{ - gchar const *p = n; - while (*p != '\0' && *p != '#') { - p++; - } - - if (*p == '\0' || p[1] == '\0') { - return NULL; - } - - p++; - int c = 0; - while (p[c] != '\0' && p[c] != ')') { - c++; - } - - if (p[c] == '\0') { - return NULL; - } - - gchar* b = g_strdup(p); - b[c] = '\0'; - - // FIXME: get the document from the object and let the caller pass it in - SPObject *marker = doc->getObjectById(b); - return marker; -} } // namespace Inkscape -- cgit v1.2.3 From 979d809bbbe2d3ed1fc5a296c8f99f5d8c395f4b Mon Sep 17 00:00:00 2001 From: John Smith Date: Tue, 18 Sep 2012 08:44:30 +0900 Subject: Fix for 165865 : Fix marker color on duplicate (bzr r11671) --- src/widgets/stroke-style.cpp | 86 +++++++++++++++----------------------------- 1 file changed, 29 insertions(+), 57 deletions(-) (limited to 'src/widgets/stroke-style.cpp') diff --git a/src/widgets/stroke-style.cpp b/src/widgets/stroke-style.cpp index 2c39945f7..5f686881f 100644 --- a/src/widgets/stroke-style.cpp +++ b/src/widgets/stroke-style.cpp @@ -291,7 +291,7 @@ StrokeStyle::StrokeStyle() : // TRANSLATORS: Path markers are an SVG feature that allows you to attach arbitrary shapes // (arrowheads, bullets, faces, whatever) to the start, end, or middle nodes of a path. - startMarkerCombo = manage(new MarkerComboBox("marker-start")); + startMarkerCombo = manage(new MarkerComboBox("marker-start", SP_MARKER_LOC_START)); spw_label(table, _("_Start Markers:"), 0, i, startMarkerCombo); startMarkerCombo->set_tooltip_text(_("Start Markers are drawn on the first node of a path or shape")); startMarkerConn = startMarkerCombo->signal_changed().connect( @@ -301,7 +301,7 @@ StrokeStyle::StrokeStyle() : table->attach(*startMarkerCombo, 1, 4, i, i+1, (Gtk::EXPAND | Gtk::FILL), static_cast(0), 0, 0); i++; - midMarkerCombo = manage(new MarkerComboBox("marker-mid")); + midMarkerCombo = manage(new MarkerComboBox("marker-mid", SP_MARKER_LOC_MID)); spw_label(table, _("_Mid Markers:"), 0, i, midMarkerCombo); midMarkerCombo->set_tooltip_text(_("Mid Markers are drawn on every node of a path or shape except the first and last nodes")); midMarkerConn = midMarkerCombo->signal_changed().connect( @@ -311,7 +311,7 @@ StrokeStyle::StrokeStyle() : table->attach(*midMarkerCombo, 1, 4, i, i+1, (Gtk::EXPAND | Gtk::FILL), static_cast(0), 0, 0); i++; - endMarkerCombo = manage(new MarkerComboBox("marker-end")); + endMarkerCombo = manage(new MarkerComboBox("marker-end", SP_MARKER_LOC_END)); spw_label(table, _("_End Markers:"), 0, i, endMarkerCombo); endMarkerCombo->set_tooltip_text(_("End Markers are drawn on the last node of a path or shape")); endMarkerConn = endMarkerCombo->signal_changed().connect( @@ -429,11 +429,7 @@ StrokeStyle::markerSelectCB(MarkerComboBox *marker_combo, StrokeStyle *spw, SPMa if (selrepr) { sp_repr_css_change_recursive(selrepr, css, "style"); SPObject *markerObj = getMarkerObj(marker, document); - if (!marker_combo->isSelectedStock()) { - // If arrow, marker will already be forked - markerObj = spw->forkMarker(item, markerObj, marker_combo); - } - spw->setMarkerColor(item, markerObj, marker_combo); + spw->setMarkerColor(markerObj, marker_combo->get_loc(), item); } item->requestModified(SP_OBJECT_MODIFIED_FLAG); @@ -570,74 +566,46 @@ StrokeStyle::selectionChangedCB() } /* - * Make a new copy of a marker, set as auto collectable - * Set the referencing items url to the new marker + * Fork marker if necessary and set the referencing items url to the new marker * Return the new marker */ SPObject * -StrokeStyle::forkMarker(SPItem *item, SPObject *marker, MarkerComboBox *marker_combo) +StrokeStyle::forkMarker(SPObject *marker, int loc, SPItem *item) { - if (!item || !marker) { return NULL; } - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - gboolean colorStock = prefs->getBool("/options/markers/colorStockMarkers", true); - gboolean colorCustom = prefs->getBool("/options/markers/colorCustomMarkers", false); - const gchar *stock = marker->getRepr()->attribute("inkscape:isstock"); - gboolean isStock = (!stock || !strcmp(stock,"true")); - gchar const *combo_id = marker_combo->get_id(); - - if (isStock ? !colorStock : !colorCustom) { - return marker; - } - + gchar const *marker_id = SPMarkerNames[loc].key; /* - * Optimization - * If this item already has this marker elsewhere (start/mid or end), + * Optimization when all the references to this marker are from this item * then we can reuse it and dont need to fork */ - SPCSSAttr *css = sp_css_attr_from_object(item, SP_STYLE_FLAG_ALWAYS); Glib::ustring urlId = Glib::ustring::format("url(#", marker->getRepr()->attribute("id"), ")"); - const gchar *markers[3] = { "marker-start", "marker-mid", "marker-end" }; - //gboolean exists = false; - for (int i = 0; i < 3; i++) { - if (!strcmp(marker_combo->get_id(), markers[i])) { - continue; - } - const char *urlMark = sp_repr_css_property(css, markers[i], ""); - if (!strcmp(urlId.c_str(), urlMark)) { - return marker; + unsigned int refs = 0; + for (int i = SP_MARKER_LOC_START; i < SP_MARKER_LOC_QTY; i++) { + if (item->style->marker[i].set && !strcmp(urlId.c_str(), item->style->marker[i].value)) { + refs++; } } + if (marker->hrefcount <= refs) { + return marker; + } - - SPDocument *doc = SP_ACTIVE_DOCUMENT; - SPDefs *defs = doc->getDefs(); - Inkscape::XML::Document *xml_doc = doc->getReprDoc(); - // Turn off garbage-collectable or it might be collected before we can use it - marker->getRepr()->setAttribute("inkscape:collect", NULL); - Inkscape::XML::Node *mark_repr = marker->getRepr()->duplicate(xml_doc); - defs->getRepr()->addChild(mark_repr, NULL); - gchar const *markid = marker->getRepr()->attribute("inkscape:stockid") ? marker->getRepr()->attribute("inkscape:stockid") : marker->getRepr()->attribute("id"); - mark_repr->setAttribute("inkscape:stockid", markid); + marker = sp_marker_fork_if_necessary(marker); // Update the items url to new marker + Inkscape::XML::Node *mark_repr = marker->getRepr(); SPCSSAttr *css_item = sp_repr_css_attr_new(); - sp_repr_css_set_property(css_item, combo_id, g_strconcat("url(#", mark_repr->attribute("id"), ")", NULL)); + sp_repr_css_set_property(css_item, marker_id, g_strconcat("url(#", mark_repr->attribute("id"), ")", NULL)); sp_repr_css_change_recursive(item->getRepr(), css_item, "style"); - // privates are garbage-collectable - mark_repr->setAttribute("inkscape:collect", "always"); - marker->getRepr()->setAttribute("inkscape:collect", "always"); - Inkscape::GC::release(mark_repr); sp_repr_css_attr_unref(css_item); css_item = 0; - return doc->getObjectById(mark_repr->attribute("id")); + return marker; } /** @@ -650,7 +618,7 @@ StrokeStyle::forkMarker(SPItem *item, SPObject *marker, MarkerComboBox *marker_c * */ void -StrokeStyle::setMarkerColor(SPItem *item, SPObject *marker, MarkerComboBox *marker_combo) +StrokeStyle::setMarkerColor(SPObject *marker, int loc, SPItem *item) { if (!item || !marker) { @@ -667,6 +635,9 @@ StrokeStyle::setMarkerColor(SPItem *item, SPObject *marker, MarkerComboBox *mark return; } + // Check if we need to fork this marker + marker = forkMarker(marker, loc, item); + Inkscape::XML::Node *repr = marker->getRepr()->firstChild(); if (!repr) { return; @@ -674,9 +645,9 @@ StrokeStyle::setMarkerColor(SPItem *item, SPObject *marker, MarkerComboBox *mark // Current line style SPCSSAttr *css_item = sp_css_attr_from_object(item, SP_STYLE_FLAG_ALWAYS); - const char *lstroke = getItemColorForMarker(item, FOR_STROKE, marker_combo); + const char *lstroke = getItemColorForMarker(item, FOR_STROKE, loc); const char *lstroke_opacity = sp_repr_css_property(css_item, "stroke-opacity", "1"); - const char *lfill = getItemColorForMarker(item, FOR_FILL, marker_combo); + const char *lfill = getItemColorForMarker(item, FOR_FILL, loc); const char *lfill_opacity = sp_repr_css_property(css_item, "fill-opacity", "1"); // Current marker style @@ -725,7 +696,7 @@ StrokeStyle::setMarkerColor(SPItem *item, SPObject *marker, MarkerComboBox *mark * If its a gradient, then return first or last stop color */ const char * -StrokeStyle::getItemColorForMarker(SPItem *item, Inkscape::PaintTarget fill_or_stroke, MarkerComboBox *marker_combo) +StrokeStyle::getItemColorForMarker(SPItem *item, Inkscape::PaintTarget fill_or_stroke, int loc) { SPCSSAttr *css_item = sp_css_attr_from_object(item, SP_STYLE_FLAG_ALWAYS); const char *color; @@ -736,11 +707,12 @@ StrokeStyle::getItemColorForMarker(SPItem *item, Inkscape::PaintTarget fill_or_s if (!strncmp (color, "url(", 4)) { // If the item has a gradient use the first stop color for the marker + SPGradient *grad = getGradient(item, fill_or_stroke); if (grad) { SPGradient *vector = grad->getVector(FALSE); SPStop *stop = vector->getFirstStop(); - if (marker_combo == endMarkerCombo) { + if (loc == SP_MARKER_LOC_END) { stop = sp_last_stop(vector); } if (stop) { @@ -1231,7 +1203,7 @@ StrokeStyle::updateAllMarkers(GSList const *objects) gboolean update = prefs->getBool("/options/markers/colorUpdateMarkers", true); if (update) { - setMarkerColor(SP_ITEM(object), marker, combo); + setMarkerColor(marker, combo->get_loc(), SP_ITEM(object)); SPDocument *document = sp_desktop_document(desktop); DocumentUndo::done(document, SP_VERB_DIALOG_FILL_STROKE, -- cgit v1.2.3 From 8569f055798b87d1bbc074006adc4addf0f43450 Mon Sep 17 00:00:00 2001 From: John Smith Date: Mon, 24 Sep 2012 07:27:49 +0900 Subject: Fix for 165865 : Assert when duplicating markers (bzr r11699) --- src/widgets/stroke-style.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src/widgets/stroke-style.cpp') diff --git a/src/widgets/stroke-style.cpp b/src/widgets/stroke-style.cpp index 5f686881f..832865eae 100644 --- a/src/widgets/stroke-style.cpp +++ b/src/widgets/stroke-style.cpp @@ -601,7 +601,6 @@ StrokeStyle::forkMarker(SPObject *marker, int loc, SPItem *item) sp_repr_css_set_property(css_item, marker_id, g_strconcat("url(#", mark_repr->attribute("id"), ")", NULL)); sp_repr_css_change_recursive(item->getRepr(), css_item, "style"); - Inkscape::GC::release(mark_repr); sp_repr_css_attr_unref(css_item); css_item = 0; -- cgit v1.2.3 From 606276db1921c978abaf15d1abeff96ef37dbe2f Mon Sep 17 00:00:00 2001 From: John Smith Date: Mon, 29 Oct 2012 12:44:15 +0900 Subject: Fix for 165865 : Markers - fix Undo history (bzr r11850) --- src/widgets/stroke-style.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/widgets/stroke-style.cpp') diff --git a/src/widgets/stroke-style.cpp b/src/widgets/stroke-style.cpp index 832865eae..4e8431454 100644 --- a/src/widgets/stroke-style.cpp +++ b/src/widgets/stroke-style.cpp @@ -434,14 +434,13 @@ StrokeStyle::markerSelectCB(MarkerComboBox *marker_combo, StrokeStyle *spw, SPMa item->requestModified(SP_OBJECT_MODIFIED_FLAG); item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); + + DocumentUndo::done(document, SP_VERB_DIALOG_FILL_STROKE, _("Set markers")); } sp_repr_css_attr_unref(css); css = 0; - DocumentUndo::done(document, SP_VERB_DIALOG_FILL_STROKE, - _("Set markers")); - spw->update = false; }; -- cgit v1.2.3 From 73186b30e90fdca666af811ee63b385eeb9740b1 Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sun, 9 Dec 2012 13:57:31 +0000 Subject: Migrate remaining stuff from GtkTable to GtkGrid (bzr r11939) --- src/widgets/stroke-style.cpp | 45 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) (limited to 'src/widgets/stroke-style.cpp') diff --git a/src/widgets/stroke-style.cpp b/src/widgets/stroke-style.cpp index 4e8431454..7912b654a 100644 --- a/src/widgets/stroke-style.cpp +++ b/src/widgets/stroke-style.cpp @@ -122,10 +122,17 @@ StrokeStyle::StrokeStyle() : f->show(); add(*f); +#if WITH_GTKMM_3_0 + table = new Gtk::Grid(); + table->set_border_width(4); + table->set_row_spacing(4); +#else table = new Gtk::Table(3, 6, false); - table->show(); table->set_border_width(4); table->set_row_spacings(4); +#endif + + table->show(); f->add(*table); gint i = 0; @@ -282,7 +289,16 @@ StrokeStyle::StrokeStyle() : dashSelector = manage(new SPDashSelector); dashSelector->show(); + +#if WITH_GTKMM_3_0 + dashSelector->set_hexpand(); + dashSelector->set_halign(Gtk::ALIGN_FILL); + dashSelector->set_valign(Gtk::ALIGN_CENTER); + table->attach(*dashSelector, 1, i, 3, 1); +#else table->attach(*dashSelector, 1, 4, i, i+1, (Gtk::EXPAND | Gtk::FILL), static_cast(0), 0, 0); +#endif + dashSelector->changed_signal.connect(sigc::mem_fun(*this, &StrokeStyle::lineDashChangedCB)); i++; @@ -298,7 +314,16 @@ StrokeStyle::StrokeStyle() : sigc::bind( sigc::ptr_fun(&StrokeStyle::markerSelectCB), startMarkerCombo, this, SP_MARKER_LOC_START)); startMarkerCombo->show(); + +#if WITH_GTKMM_3_0 + startMarkerCombo->set_hexpand(); + startMarkerCombo->set_halign(Gtk::ALIGN_FILL); + startMarkerCombo->set_valign(Gtk::ALIGN_CENTER); + table->attach(*startMarkerCombo, 1, i, 3, 1); +#else table->attach(*startMarkerCombo, 1, 4, i, i+1, (Gtk::EXPAND | Gtk::FILL), static_cast(0), 0, 0); +#endif + i++; midMarkerCombo = manage(new MarkerComboBox("marker-mid", SP_MARKER_LOC_MID)); @@ -308,7 +333,16 @@ StrokeStyle::StrokeStyle() : sigc::bind( sigc::ptr_fun(&StrokeStyle::markerSelectCB), midMarkerCombo, this, SP_MARKER_LOC_MID)); midMarkerCombo->show(); + +#if WITH_GTKMM_3_0 + midMarkerCombo->set_hexpand(); + midMarkerCombo->set_halign(Gtk::ALIGN_FILL); + midMarkerCombo->set_valign(Gtk::ALIGN_CENTER); + table->attach(*midMarkerCombo, 1, i, 3, 1); +#else table->attach(*midMarkerCombo, 1, 4, i, i+1, (Gtk::EXPAND | Gtk::FILL), static_cast(0), 0, 0); +#endif + i++; endMarkerCombo = manage(new MarkerComboBox("marker-end", SP_MARKER_LOC_END)); @@ -318,7 +352,16 @@ StrokeStyle::StrokeStyle() : sigc::bind( sigc::ptr_fun(&StrokeStyle::markerSelectCB), endMarkerCombo, this, SP_MARKER_LOC_END)); endMarkerCombo->show(); + +#if WITH_GTKMM_3_0 + endMarkerCombo->set_hexpand(); + endMarkerCombo->set_halign(Gtk::ALIGN_FILL); + endMarkerCombo->set_valign(Gtk::ALIGN_CENTER); + table->attach(*endMarkerCombo, 1, i, 3, 1); +#else table->attach(*endMarkerCombo, 1, 4, i, i+1, (Gtk::EXPAND | Gtk::FILL), static_cast(0), 0, 0); +#endif + i++; setDesktop(desktop); -- cgit v1.2.3 From cfe9c94712a2ff6849b123672e51b603f20e76ae Mon Sep 17 00:00:00 2001 From: "Jon A. Cruz" Date: Thu, 10 Jan 2013 23:30:09 -0800 Subject: Warning and dead code cleanup. (bzr r12014) --- src/widgets/stroke-style.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'src/widgets/stroke-style.cpp') diff --git a/src/widgets/stroke-style.cpp b/src/widgets/stroke-style.cpp index 7912b654a..ede98a48a 100644 --- a/src/widgets/stroke-style.cpp +++ b/src/widgets/stroke-style.cpp @@ -434,8 +434,7 @@ StrokeStyle::makeRadioButton(Gtk::RadioButton *tb, char const *icon, * Gets the marker uri string and applies it to all selected * items in the current desktop. */ -void -StrokeStyle::markerSelectCB(MarkerComboBox *marker_combo, StrokeStyle *spw, SPMarkerLoc const which) +void StrokeStyle::markerSelectCB(MarkerComboBox *marker_combo, StrokeStyle *spw, SPMarkerLoc const /*which*/) { if (spw->update) { return; @@ -485,12 +484,10 @@ StrokeStyle::markerSelectCB(MarkerComboBox *marker_combo, StrokeStyle *spw, SPMa css = 0; spw->update = false; - }; -void -StrokeStyle::updateMarkerHist(SPMarkerLoc const which) { - +void StrokeStyle::updateMarkerHist(SPMarkerLoc const which) +{ switch (which) { case SP_MARKER_LOC_START: startMarkerConn.block(); -- cgit v1.2.3 From b24b39fd1260fe2f59ccbaeb0742568d89567da4 Mon Sep 17 00:00:00 2001 From: Kris De Gussem Date: Sun, 20 Jan 2013 13:52:07 +0100 Subject: minor fix (do not compare to zero) (bzr r12048) --- src/widgets/stroke-style.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/widgets/stroke-style.cpp') diff --git a/src/widgets/stroke-style.cpp b/src/widgets/stroke-style.cpp index ede98a48a..0f79a609b 100644 --- a/src/widgets/stroke-style.cpp +++ b/src/widgets/stroke-style.cpp @@ -549,8 +549,9 @@ gboolean StrokeStyle::setStrokeWidthUnit(SPUnitSelector *, gdouble average = stroke_average_width (objects); - if (average == Geom::infinity() || average == 0) + if ((average == Geom::infinity()) || (average < 1e-8)){ //less than 1e-8: to campare against zero, while taking numeric accuracy into account return FALSE; + } #if WITH_GTKMM_3_0 (*spw->widthAdj)->set_value(100.0 * w / average); -- cgit v1.2.3 From 4ce710c02e31930664f81c1137e6b24e7297703a Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sat, 23 Mar 2013 13:15:49 +0000 Subject: Use subclass of RadioButton rather than setting gobject data in Stroke Style dialog: fixes cast-align issue. (bzr r12233) --- src/widgets/stroke-style.cpp | 134 +++++++++++++++++++++++++------------------ 1 file changed, 79 insertions(+), 55 deletions(-) (limited to 'src/widgets/stroke-style.cpp') diff --git a/src/widgets/stroke-style.cpp b/src/widgets/stroke-style.cpp index 0f79a609b..c6934f0a6 100644 --- a/src/widgets/stroke-style.cpp +++ b/src/widgets/stroke-style.cpp @@ -87,6 +87,33 @@ SPObject* getMarkerObj(gchar const *n, SPDocument *doc) namespace Inkscape { + +/** + * Construct a stroke-style radio button with a given icon + * + * \param[in] grp The Gtk::RadioButtonGroup to which to add the new button + * \param[in] icon The icon to use for the button + * \param[in] button_type The type of stroke-style radio button (join/cap) + * \param[in] stroke_style The style attribute to associate with the button + */ +StrokeStyle::StrokeStyleButton::StrokeStyleButton(Gtk::RadioButtonGroup &grp, + char const *icon, + StrokeStyleButtonType button_type, + gchar const *stroke_style) + : + Gtk::RadioButton(grp), + button_type(button_type), + stroke_style(stroke_style) +{ + show(); + set_mode(false); + + Gtk::Widget *px = manage(Glib::wrap(sp_icon_new(Inkscape::ICON_SIZE_LARGE_TOOLBAR, icon))); + g_assert(px != NULL); + px->show(); + add(*px); +} + /** * Create the fill or stroke style widget, and hook up all the signals. */ @@ -194,24 +221,27 @@ StrokeStyle::StrokeStyle() : hb = spw_hbox(table, 3, 1, i); - //tb = NULL; + Gtk::RadioButtonGroup joinGrp; + + joinMiter = makeRadioButton(joinGrp, INKSCAPE_ICON("stroke-join-miter"), + hb, STROKE_STYLE_BUTTON_JOIN, "miter"); - joinMiter = makeRadioButton(NULL, INKSCAPE_ICON("stroke-join-miter"), - hb, "join", "miter"); // TRANSLATORS: Miter join: joining lines with a sharp (pointed) corner. // For an example, draw a triangle with a large stroke width and modify the // "Join" option (in the Fill and Stroke dialog). joinMiter->set_tooltip_text(_("Miter join")); - joinRound = makeRadioButton(joinMiter, INKSCAPE_ICON("stroke-join-round"), - hb, "join", "round"); + joinRound = makeRadioButton(joinGrp, INKSCAPE_ICON("stroke-join-round"), + hb, STROKE_STYLE_BUTTON_JOIN, "round"); + // TRANSLATORS: Round join: joining lines with a rounded corner. // For an example, draw a triangle with a large stroke width and modify the // "Join" option (in the Fill and Stroke dialog). joinRound->set_tooltip_text(_("Round join")); - joinBevel = makeRadioButton(joinMiter, INKSCAPE_ICON("stroke-join-bevel"), - hb, "join", "bevel"); + joinBevel = makeRadioButton(joinGrp, INKSCAPE_ICON("stroke-join-bevel"), + hb, STROKE_STYLE_BUTTON_JOIN, "bevel"); + // TRANSLATORS: Bevel join: joining lines with a blunted (flattened) corner. // For an example, draw a triangle with a large stroke width and modify the // "Join" option (in the Fill and Stroke dialog). @@ -260,20 +290,25 @@ StrokeStyle::StrokeStyle() : hb = spw_hbox(table, 3, 1, i); - capButt = makeRadioButton(capButt, INKSCAPE_ICON("stroke-cap-butt"), - hb, "cap", "butt"); + Gtk::RadioButtonGroup capGrp; + + capButt = makeRadioButton(capGrp, INKSCAPE_ICON("stroke-cap-butt"), + hb, STROKE_STYLE_BUTTON_CAP, "butt"); + // TRANSLATORS: Butt cap: the line shape does not extend beyond the end point // of the line; the ends of the line are square capButt->set_tooltip_text(_("Butt cap")); - capRound = makeRadioButton(capButt, INKSCAPE_ICON("stroke-cap-round"), - hb, "cap", "round"); + capRound = makeRadioButton(capGrp, INKSCAPE_ICON("stroke-cap-round"), + hb, STROKE_STYLE_BUTTON_CAP, "round"); + // TRANSLATORS: Round cap: the line shape extends beyond the end point of the // line; the ends of the line are rounded capRound->set_tooltip_text(_("Round cap")); - capSquare = makeRadioButton(capButt, INKSCAPE_ICON("stroke-cap-square"), - hb, "cap", "square"); + capSquare = makeRadioButton(capGrp, INKSCAPE_ICON("stroke-cap-square"), + hb, STROKE_STYLE_BUTTON_CAP, "square"); + // TRANSLATORS: Square cap: the line shape extends beyond the end point of the // line; the ends of the line are square capSquare->set_tooltip_text(_("Square cap")); @@ -394,39 +429,36 @@ void StrokeStyle::setDesktop(SPDesktop *desktop) /** - * Helper function for creating radio buttons. This should probably be re-thought out - * when reimplementing this with Gtkmm. + * Helper function for creating stroke-style radio buttons. + * + * \param[in] grp The Gtk::RadioButtonGroup in which to add the button + * \param[in] icon The icon for the button + * \param[in] hb The Gtk::Box container in which to add the button + * \param[in] button_type The type (join/cap) for the button + * \param[in] stroke_style The style attribute to associate with the button + * + * \details After instantiating the button, it is added to a container box and + * a handler for the toggle event is connected. */ -Gtk::RadioButton * -StrokeStyle::makeRadioButton(Gtk::RadioButton *tb, char const *icon, - Gtk::HBox *hb, gchar const *key, gchar const *data) +StrokeStyle::StrokeStyleButton * +StrokeStyle::makeRadioButton(Gtk::RadioButtonGroup &grp, + char const *icon, + Gtk::HBox *hb, + StrokeStyleButtonType button_type, + gchar const *stroke_style) { g_assert(icon != NULL); g_assert(hb != NULL); - if (tb == NULL) { - tb = new Gtk::RadioButton(); - } else { - Gtk::RadioButtonGroup grp = tb->get_group(); - tb = new Gtk::RadioButton(grp); - } + StrokeStyleButton *tb = new StrokeStyleButton(grp, icon, button_type, stroke_style); - tb->show(); - tb->set_mode(false); hb->pack_start(*tb, false, false, 0); set_data(icon, tb); - tb->set_data(key, (gpointer*)data); - tb->signal_toggled().connect(sigc::bind( + tb->signal_toggled().connect(sigc::bind( sigc::ptr_fun(&StrokeStyle::buttonToggledCB), tb, this)); - Gtk::Widget *px = manage(Glib::wrap(sp_icon_new(Inkscape::ICON_SIZE_LARGE_TOOLBAR, icon))); - g_assert(px != NULL); - px->show(); - tb->add(*px); - return tb; - } /** @@ -1120,38 +1152,30 @@ StrokeStyle::lineDashChangedCB() * calls the respective routines to update css properties, etc. * */ -void StrokeStyle::buttonToggledCB(Gtk::ToggleButton *tb, StrokeStyle *spw) +void StrokeStyle::buttonToggledCB(StrokeStyleButton *tb, StrokeStyle *spw) { if (spw->update) { return; } if (tb->get_active()) { - - gchar const *join - = static_cast(tb->get_data("join")); - gchar const *cap - = static_cast(tb->get_data("cap")); - - if (join) { - spw->miterLimitSpin->set_sensitive(!strcmp(join, "miter")); + if (tb->get_button_type() == STROKE_STYLE_BUTTON_JOIN) { + spw->miterLimitSpin->set_sensitive(!strcmp(tb->get_stroke_style(), "miter")); } /* TODO: Create some standardized method */ SPCSSAttr *css = sp_repr_css_attr_new(); - if (join) { - sp_repr_css_set_property(css, "stroke-linejoin", join); - - sp_desktop_set_style (spw->desktop, css); - - spw->setJoinButtons(tb); - } else if (cap) { - sp_repr_css_set_property(css, "stroke-linecap", cap); - - sp_desktop_set_style (spw->desktop, css); - - spw->setCapButtons(tb); + switch (tb->get_button_type()) { + case STROKE_STYLE_BUTTON_JOIN: + sp_repr_css_set_property(css, "stroke-linejoin", tb->get_stroke_style()); + sp_desktop_set_style (spw->desktop, css); + spw->setJoinButtons(tb); + break; + case STROKE_STYLE_BUTTON_CAP: + sp_repr_css_set_property(css, "stroke-linecap", tb->get_stroke_style()); + sp_desktop_set_style (spw->desktop, css); + spw->setCapButtons(tb); } sp_repr_css_attr_unref(css); -- cgit v1.2.3 From 00904e48823b29873f52854d95b5c2f83b15108b Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Tue, 11 Jun 2013 11:49:46 -0400 Subject: Change marker layout in stroke-widget so they are all on one line. (bzr r12363) --- src/widgets/stroke-style.cpp | 41 ++++++++--------------------------------- 1 file changed, 8 insertions(+), 33 deletions(-) (limited to 'src/widgets/stroke-style.cpp') diff --git a/src/widgets/stroke-style.cpp b/src/widgets/stroke-style.cpp index c6934f0a6..0a5b3781b 100644 --- a/src/widgets/stroke-style.cpp +++ b/src/widgets/stroke-style.cpp @@ -342,62 +342,37 @@ StrokeStyle::StrokeStyle() : // TRANSLATORS: Path markers are an SVG feature that allows you to attach arbitrary shapes // (arrowheads, bullets, faces, whatever) to the start, end, or middle nodes of a path. + spw_label(table, _("Markers:"), 0, i, NULL); + + hb = spw_hbox(table, 1, 1, i); + i++; + startMarkerCombo = manage(new MarkerComboBox("marker-start", SP_MARKER_LOC_START)); - spw_label(table, _("_Start Markers:"), 0, i, startMarkerCombo); startMarkerCombo->set_tooltip_text(_("Start Markers are drawn on the first node of a path or shape")); startMarkerConn = startMarkerCombo->signal_changed().connect( sigc::bind( sigc::ptr_fun(&StrokeStyle::markerSelectCB), startMarkerCombo, this, SP_MARKER_LOC_START)); startMarkerCombo->show(); -#if WITH_GTKMM_3_0 - startMarkerCombo->set_hexpand(); - startMarkerCombo->set_halign(Gtk::ALIGN_FILL); - startMarkerCombo->set_valign(Gtk::ALIGN_CENTER); - table->attach(*startMarkerCombo, 1, i, 3, 1); -#else - table->attach(*startMarkerCombo, 1, 4, i, i+1, (Gtk::EXPAND | Gtk::FILL), static_cast(0), 0, 0); -#endif - - i++; + hb->pack_start(*startMarkerCombo, true, true, 0); midMarkerCombo = manage(new MarkerComboBox("marker-mid", SP_MARKER_LOC_MID)); - spw_label(table, _("_Mid Markers:"), 0, i, midMarkerCombo); midMarkerCombo->set_tooltip_text(_("Mid Markers are drawn on every node of a path or shape except the first and last nodes")); midMarkerConn = midMarkerCombo->signal_changed().connect( sigc::bind( sigc::ptr_fun(&StrokeStyle::markerSelectCB), midMarkerCombo, this, SP_MARKER_LOC_MID)); midMarkerCombo->show(); -#if WITH_GTKMM_3_0 - midMarkerCombo->set_hexpand(); - midMarkerCombo->set_halign(Gtk::ALIGN_FILL); - midMarkerCombo->set_valign(Gtk::ALIGN_CENTER); - table->attach(*midMarkerCombo, 1, i, 3, 1); -#else - table->attach(*midMarkerCombo, 1, 4, i, i+1, (Gtk::EXPAND | Gtk::FILL), static_cast(0), 0, 0); -#endif - - i++; + hb->pack_start(*midMarkerCombo, true, true, 0); endMarkerCombo = manage(new MarkerComboBox("marker-end", SP_MARKER_LOC_END)); - spw_label(table, _("_End Markers:"), 0, i, endMarkerCombo); endMarkerCombo->set_tooltip_text(_("End Markers are drawn on the last node of a path or shape")); endMarkerConn = endMarkerCombo->signal_changed().connect( sigc::bind( sigc::ptr_fun(&StrokeStyle::markerSelectCB), endMarkerCombo, this, SP_MARKER_LOC_END)); endMarkerCombo->show(); -#if WITH_GTKMM_3_0 - endMarkerCombo->set_hexpand(); - endMarkerCombo->set_halign(Gtk::ALIGN_FILL); - endMarkerCombo->set_valign(Gtk::ALIGN_CENTER); - table->attach(*endMarkerCombo, 1, i, 3, 1); -#else - table->attach(*endMarkerCombo, 1, 4, i, i+1, (Gtk::EXPAND | Gtk::FILL), static_cast(0), 0, 0); -#endif - - i++; + hb->pack_start(*endMarkerCombo, true, true, 0); setDesktop(desktop); updateLine(); -- cgit v1.2.3 From 9dc7b786c9ef31060012ea4ae13a8188548b4f62 Mon Sep 17 00:00:00 2001 From: Matthew Petroff Date: Tue, 9 Jul 2013 16:42:04 -0400 Subject: Ported sp-namedview.cpp (todo: fix a bunch of things). (bzr r12380.1.8) --- src/widgets/stroke-style.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/widgets/stroke-style.cpp') diff --git a/src/widgets/stroke-style.cpp b/src/widgets/stroke-style.cpp index 0a5b3781b..17e3984bb 100644 --- a/src/widgets/stroke-style.cpp +++ b/src/widgets/stroke-style.cpp @@ -193,8 +193,8 @@ StrokeStyle::StrokeStyle() : Gtk::Widget *us = manage(Glib::wrap(unitSelector)); SPDesktop *desktop = SP_ACTIVE_DESKTOP; - if (desktop) - sp_unit_selector_set_unit (SP_UNIT_SELECTOR(unitSelector), sp_desktop_namedview(desktop)->doc_units); + //if (desktop) + // sp_unit_selector_set_unit (SP_UNIT_SELECTOR(unitSelector), sp_desktop_namedview(desktop)->doc_units); sp_unit_selector_add_unit(SP_UNIT_SELECTOR(unitSelector), &sp_unit_get_by_id(SP_UNIT_PERCENT), 0); g_signal_connect ( G_OBJECT (unitSelector), "set_unit", G_CALLBACK (StrokeStyle::setStrokeWidthUnit), this ); us->show(); @@ -884,7 +884,7 @@ StrokeStyle::updateLine() } else { // same width, or only one object; no sense to keep percent, switch to absolute if (unit->base != SP_UNIT_ABSOLUTE && unit->base != SP_UNIT_DEVICE) { - sp_unit_selector_set_unit(SP_UNIT_SELECTOR(unitSelector), sp_desktop_namedview(SP_ACTIVE_DESKTOP)->doc_units); + //sp_unit_selector_set_unit(SP_UNIT_SELECTOR(unitSelector), sp_desktop_namedview(SP_ACTIVE_DESKTOP)->doc_units); } } -- cgit v1.2.3 From 08d18ac062f175f893bc7251e39072d0f0d4577c Mon Sep 17 00:00:00 2001 From: Matthew Petroff Date: Sat, 20 Jul 2013 12:30:28 -0400 Subject: Ported "widgets/stroke-style.*". (bzr r12380.1.44) --- src/widgets/stroke-style.cpp | 123 ++++++++++++------------------------------- 1 file changed, 34 insertions(+), 89 deletions(-) (limited to 'src/widgets/stroke-style.cpp') diff --git a/src/widgets/stroke-style.cpp b/src/widgets/stroke-style.cpp index 17e3984bb..e35a8b36b 100644 --- a/src/widgets/stroke-style.cpp +++ b/src/widgets/stroke-style.cpp @@ -22,6 +22,8 @@ #include "sp-gradient.h" #include "sp-stop.h" #include "svg/svg-color.h" +#include "util/units.h" +#include "ui/widget/unit-menu.h" using Inkscape::DocumentUndo; @@ -189,22 +191,23 @@ StrokeStyle::StrokeStyle() : sp_dialog_defocus_on_enter_cpp(widthSpin); hb->pack_start(*widthSpin, false, false, 0); - unitSelector = sp_unit_selector_new(SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE); - Gtk::Widget *us = manage(Glib::wrap(unitSelector)); + unitSelector = new Inkscape::UI::Widget::UnitMenu(); + unitSelector->setUnitType(Inkscape::Util::UNIT_TYPE_LINEAR); + Gtk::Widget *us = manage(unitSelector); SPDesktop *desktop = SP_ACTIVE_DESKTOP; - //if (desktop) - // sp_unit_selector_set_unit (SP_UNIT_SELECTOR(unitSelector), sp_desktop_namedview(desktop)->doc_units); - sp_unit_selector_add_unit(SP_UNIT_SELECTOR(unitSelector), &sp_unit_get_by_id(SP_UNIT_PERCENT), 0); - g_signal_connect ( G_OBJECT (unitSelector), "set_unit", G_CALLBACK (StrokeStyle::setStrokeWidthUnit), this ); + Inkscape::Util::UnitTable unit_table; + unitSelector->addUnit(unit_table.getUnit("%")); + if (desktop) { + unitSelector->setUnit(sp_desktop_namedview(desktop)->doc_units->abbr); + _old_unit = new Inkscape::Util::Unit(*sp_desktop_namedview(desktop)->doc_units); + } + _old_unit = new Inkscape::Util::Unit(unitSelector->getUnit()); + widthSpin->setUnitMenu(unitSelector); + unitChangedConn = unitSelector->signal_changed().connect(sigc::mem_fun(*this, &StrokeStyle::unitChangedCB)); + us->show(); -#if WITH_GTKMM_3_0 - sp_unit_selector_add_adjustment( SP_UNIT_SELECTOR(unitSelector), GTK_ADJUSTMENT((*widthAdj)->gobj()) ); -#else - sp_unit_selector_add_adjustment( SP_UNIT_SELECTOR(unitSelector), GTK_ADJUSTMENT(widthAdj->gobj()) ); -#endif - hb->pack_start(*us, FALSE, FALSE, 0); #if WITH_GTKMM_3_0 @@ -519,75 +522,17 @@ void StrokeStyle::updateMarkerHist(SPMarkerLoc const which) } /** - * Sets the stroke width units for all selected items. - * Also handles absolute and dimensionless units. + * Callback for when UnitMenu widget is modified. + * Triggers update action. */ -gboolean StrokeStyle::setStrokeWidthUnit(SPUnitSelector *, - SPUnit const *old, - SPUnit const *new_units, - StrokeStyle *spw) +void StrokeStyle::unitChangedCB() { - if (spw->update) { - return FALSE; - } - - if (!spw->desktop) { - return FALSE; + Inkscape::Util::Unit new_unit = unitSelector->getUnit(); + if (new_unit.type == Inkscape::Util::UNIT_TYPE_DIMENSIONLESS) { + widthSpin->set_value(100); } - - Inkscape::Selection *selection = sp_desktop_selection (spw->desktop); - - if (selection->isEmpty()) - return FALSE; - - GSList const *objects = selection->itemList(); - - if ((old->base == SP_UNIT_ABSOLUTE || old->base == SP_UNIT_DEVICE) && - (new_units->base == SP_UNIT_DIMENSIONLESS)) { - - /* Absolute to percentage */ - spw->update = true; - -#if WITH_GTKMM_3_0 - float w = sp_units_get_pixels( (*spw->widthAdj)->get_value(), *old); -#else - float w = sp_units_get_pixels(spw->widthAdj->get_value(), *old); -#endif - - gdouble average = stroke_average_width (objects); - - if ((average == Geom::infinity()) || (average < 1e-8)){ //less than 1e-8: to campare against zero, while taking numeric accuracy into account - return FALSE; - } - -#if WITH_GTKMM_3_0 - (*spw->widthAdj)->set_value(100.0 * w / average); -#else - spw->widthAdj->set_value(100.0 * w / average); -#endif - - spw->update = false; - return TRUE; - - } else if ((old->base == SP_UNIT_DIMENSIONLESS) && - (new_units->base == SP_UNIT_ABSOLUTE || new_units->base == SP_UNIT_DEVICE)) { - - /* Percentage to absolute */ - spw->update = true; - - gdouble average = stroke_average_width (objects); - -#if WITH_GTKMM_3_0 - (*spw->widthAdj)->set_value (sp_pixels_get_units (0.01 * (*spw->widthAdj)->get_value() * average, *new_units)); -#else - spw->widthAdj->set_value (sp_pixels_get_units (0.01 * spw->widthAdj->get_value() * average, *new_units)); -#endif - - spw->update = false; - return TRUE; - } - - return FALSE; + widthSpin->set_value(Inkscape::Util::Quantity::convert(widthSpin->get_value(), *_old_unit, new_unit)); + _old_unit = new Inkscape::Util::Unit(new_unit); } /** @@ -877,21 +822,21 @@ StrokeStyle::updateLine() } else { table->set_sensitive(true); - SPUnit const *unit = sp_unit_selector_get_unit(SP_UNIT_SELECTOR(unitSelector)); + Inkscape::Util::Unit const *unit = new Inkscape::Util::Unit(unitSelector->getUnit()); if (result_sw == QUERY_STYLE_MULTIPLE_AVERAGED) { - sp_unit_selector_set_unit(SP_UNIT_SELECTOR(unitSelector), &sp_unit_get_by_id(SP_UNIT_PERCENT)); + unitSelector->setUnit("%"); } else { // same width, or only one object; no sense to keep percent, switch to absolute - if (unit->base != SP_UNIT_ABSOLUTE && unit->base != SP_UNIT_DEVICE) { - //sp_unit_selector_set_unit(SP_UNIT_SELECTOR(unitSelector), sp_desktop_namedview(SP_ACTIVE_DESKTOP)->doc_units); + if (unit->type != Inkscape::Util::UNIT_TYPE_LINEAR) { + unitSelector->setUnit(sp_desktop_namedview(SP_ACTIVE_DESKTOP)->doc_units->abbr); } } - unit = sp_unit_selector_get_unit(SP_UNIT_SELECTOR(unitSelector)); + unit = new Inkscape::Util::Unit(unitSelector->getUnit()); - if (unit->base == SP_UNIT_ABSOLUTE || unit->base == SP_UNIT_DEVICE) { - double avgwidth = sp_pixels_get_units (query->stroke_width.computed, *unit); + if (unit->type == Inkscape::Util::UNIT_TYPE_LINEAR) { + double avgwidth = Inkscape::Util::Quantity::convert(query->stroke_width.computed, "px", *unit); #if WITH_GTKMM_3_0 (*widthAdj)->set_value(avgwidth); #else @@ -1017,7 +962,7 @@ StrokeStyle::scaleLine() double const miterlimit = miterLimitAdj->get_value(); #endif - SPUnit const *const unit = sp_unit_selector_get_unit(SP_UNIT_SELECTOR(unitSelector)); + Inkscape::Util::Unit const *const unit = new Inkscape::Util::Unit(unitSelector->getUnit()); double *dash, offset; int ndash; @@ -1026,8 +971,8 @@ StrokeStyle::scaleLine() for (GSList const *i = items; i != NULL; i = i->next) { /* Set stroke width */ double width; - if (unit->base == SP_UNIT_ABSOLUTE || unit->base == SP_UNIT_DEVICE) { - width = sp_units_get_pixels (width_typed, *unit); + if (unit->type == Inkscape::Util::UNIT_TYPE_LINEAR) { + width = Inkscape::Util::Quantity::convert(width_typed, *unit, "px"); } else { // percentage gdouble old_w = SP_OBJECT(i->data)->style->stroke_width.computed; width = old_w * width_typed / 100; @@ -1053,7 +998,7 @@ StrokeStyle::scaleLine() g_free(dash); - if (unit->base != SP_UNIT_ABSOLUTE && unit->base != SP_UNIT_DEVICE) { + if (unit->type != Inkscape::Util::UNIT_TYPE_LINEAR) { // reset to 100 percent #if WITH_GTKMM_3_0 (*widthAdj)->set_value(100.0); -- cgit v1.2.3 From bf4a1d2d49850170b936c30cfe2b30e798716406 Mon Sep 17 00:00:00 2001 From: Markus Engel Date: Sat, 3 Aug 2013 03:03:43 +0200 Subject: Cleaned up. (bzr r11608.1.117) --- src/widgets/stroke-style.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/widgets/stroke-style.cpp') diff --git a/src/widgets/stroke-style.cpp b/src/widgets/stroke-style.cpp index 0a5b3781b..fc3477471 100644 --- a/src/widgets/stroke-style.cpp +++ b/src/widgets/stroke-style.cpp @@ -762,7 +762,7 @@ StrokeStyle::getItemColorForMarker(SPItem *item, Inkscape::PaintTarget fill_or_s stop = sp_last_stop(vector); } if (stop) { - guint32 const c1 = sp_stop_get_rgba32(stop); + guint32 const c1 = stop->get_rgba32(); gchar c[64]; sp_svg_write_color(c, sizeof(c), c1); color = g_strdup(c); -- cgit v1.2.3 From 6ae6c0bea96eef09907091279e0678aa5f83102d Mon Sep 17 00:00:00 2001 From: Matthew Petroff Date: Sun, 4 Aug 2013 18:01:18 -0400 Subject: Switched to global UnitTable. (bzr r12380.1.62) --- src/widgets/stroke-style.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/widgets/stroke-style.cpp') diff --git a/src/widgets/stroke-style.cpp b/src/widgets/stroke-style.cpp index e35a8b36b..12d4002b8 100644 --- a/src/widgets/stroke-style.cpp +++ b/src/widgets/stroke-style.cpp @@ -26,6 +26,7 @@ #include "ui/widget/unit-menu.h" using Inkscape::DocumentUndo; +using Inkscape::Util::unit_table; /** * Creates a new widget for the line stroke paint. @@ -196,7 +197,6 @@ StrokeStyle::StrokeStyle() : Gtk::Widget *us = manage(unitSelector); SPDesktop *desktop = SP_ACTIVE_DESKTOP; - Inkscape::Util::UnitTable unit_table; unitSelector->addUnit(unit_table.getUnit("%")); if (desktop) { unitSelector->setUnit(sp_desktop_namedview(desktop)->doc_units->abbr); -- cgit v1.2.3 From 729db6f014a96c65417a06d8bf130e6af6737da0 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Mon, 30 Sep 2013 22:05:43 +0200 Subject: fix obvious leak (bzr r12634) --- src/widgets/stroke-style.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/widgets/stroke-style.cpp') diff --git a/src/widgets/stroke-style.cpp b/src/widgets/stroke-style.cpp index 31f4bb2e5..a0b638031 100644 --- a/src/widgets/stroke-style.cpp +++ b/src/widgets/stroke-style.cpp @@ -85,6 +85,8 @@ SPObject* getMarkerObj(gchar const *n, SPDocument *doc) // FIXME: get the document from the object and let the caller pass it in SPObject *marker = doc->getObjectById(b); + + g_free(b); return marker; } -- cgit v1.2.3 From a970dc423d59ea844bdb1af48d5d9419a5e2a287 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Sun, 13 Oct 2013 00:24:05 +0200 Subject: Units: stop newing Unit objects. pass around pointers to "undeletable" Unit objects in the UnitTable. I think we should move to using indexed units, and pass around the index of the unit in the unittable, or smth like that... ? (bzr r12679) --- src/widgets/stroke-style.cpp | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'src/widgets/stroke-style.cpp') diff --git a/src/widgets/stroke-style.cpp b/src/widgets/stroke-style.cpp index a0b638031..d140cfb21 100644 --- a/src/widgets/stroke-style.cpp +++ b/src/widgets/stroke-style.cpp @@ -147,7 +147,8 @@ StrokeStyle::StrokeStyle() : selectModifiedConn(), startMarkerConn(), midMarkerConn(), - endMarkerConn() + endMarkerConn(), + _old_unit(NULL) { Gtk::HBox *hb; Gtk::HBox *f = new Gtk::HBox(false, 0); @@ -199,12 +200,12 @@ StrokeStyle::StrokeStyle() : Gtk::Widget *us = manage(unitSelector); SPDesktop *desktop = SP_ACTIVE_DESKTOP; - unitSelector->addUnit(unit_table.getUnit("%")); + unitSelector->addUnit(*unit_table.getUnit("%")); + _old_unit = unitSelector->getUnit(); if (desktop) { unitSelector->setUnit(sp_desktop_namedview(desktop)->doc_units->abbr); - _old_unit = new Inkscape::Util::Unit(*sp_desktop_namedview(desktop)->doc_units); + _old_unit = sp_desktop_namedview(desktop)->doc_units; } - _old_unit = new Inkscape::Util::Unit(unitSelector->getUnit()); widthSpin->setUnitMenu(unitSelector); unitChangedConn = unitSelector->signal_changed().connect(sigc::mem_fun(*this, &StrokeStyle::unitChangedCB)); @@ -529,12 +530,12 @@ void StrokeStyle::updateMarkerHist(SPMarkerLoc const which) */ void StrokeStyle::unitChangedCB() { - Inkscape::Util::Unit new_unit = unitSelector->getUnit(); - if (new_unit.type == Inkscape::Util::UNIT_TYPE_DIMENSIONLESS) { + Inkscape::Util::Unit const *new_unit = unitSelector->getUnit(); + if (new_unit->type == Inkscape::Util::UNIT_TYPE_DIMENSIONLESS) { widthSpin->set_value(100); } - widthSpin->set_value(Inkscape::Util::Quantity::convert(widthSpin->get_value(), *_old_unit, new_unit)); - _old_unit = new Inkscape::Util::Unit(new_unit); + widthSpin->set_value(Inkscape::Util::Quantity::convert(widthSpin->get_value(), _old_unit, new_unit)); + _old_unit = new_unit; } /** @@ -824,21 +825,20 @@ StrokeStyle::updateLine() } else { table->set_sensitive(true); - Inkscape::Util::Unit const *unit = new Inkscape::Util::Unit(unitSelector->getUnit()); - if (result_sw == QUERY_STYLE_MULTIPLE_AVERAGED) { unitSelector->setUnit("%"); } else { // same width, or only one object; no sense to keep percent, switch to absolute - if (unit->type != Inkscape::Util::UNIT_TYPE_LINEAR) { + Inkscape::Util::Unit const *tempunit = unitSelector->getUnit(); + if (tempunit->type != Inkscape::Util::UNIT_TYPE_LINEAR) { unitSelector->setUnit(sp_desktop_namedview(SP_ACTIVE_DESKTOP)->doc_units->abbr); } } - unit = new Inkscape::Util::Unit(unitSelector->getUnit()); + Inkscape::Util::Unit const *unit = unitSelector->getUnit(); if (unit->type == Inkscape::Util::UNIT_TYPE_LINEAR) { - double avgwidth = Inkscape::Util::Quantity::convert(query->stroke_width.computed, "px", *unit); + double avgwidth = Inkscape::Util::Quantity::convert(query->stroke_width.computed, "px", unit); #if WITH_GTKMM_3_0 (*widthAdj)->set_value(avgwidth); #else @@ -964,7 +964,7 @@ StrokeStyle::scaleLine() double const miterlimit = miterLimitAdj->get_value(); #endif - Inkscape::Util::Unit const *const unit = new Inkscape::Util::Unit(unitSelector->getUnit()); + Inkscape::Util::Unit const *const unit = unitSelector->getUnit(); double *dash, offset; int ndash; @@ -974,7 +974,7 @@ StrokeStyle::scaleLine() /* Set stroke width */ double width; if (unit->type == Inkscape::Util::UNIT_TYPE_LINEAR) { - width = Inkscape::Util::Quantity::convert(width_typed, *unit, "px"); + width = Inkscape::Util::Quantity::convert(width_typed, unit, "px"); } else { // percentage gdouble old_w = SP_OBJECT(i->data)->style->stroke_width.computed; width = old_w * width_typed / 100; -- cgit v1.2.3 From eb89a74bb3f220bba82de3c7ce3a73df951fab77 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Sat, 8 Mar 2014 22:44:03 -0500 Subject: Remove unused includes to tidy up the code. (bzr r13132) --- src/widgets/stroke-style.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/widgets/stroke-style.cpp') diff --git a/src/widgets/stroke-style.cpp b/src/widgets/stroke-style.cpp index d140cfb21..dbfb1bcd2 100644 --- a/src/widgets/stroke-style.cpp +++ b/src/widgets/stroke-style.cpp @@ -24,6 +24,7 @@ #include "svg/svg-color.h" #include "util/units.h" #include "ui/widget/unit-menu.h" +#include "desktop-widget.h" using Inkscape::DocumentUndo; using Inkscape::Util::unit_table; -- cgit v1.2.3 From 1d31728fb7399f48d272560a290dc990b75a197e Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Tue, 11 Mar 2014 15:52:08 +0100 Subject: Change stroke-dasharray and stroke-dashoffset handling to match other properties. Split style.h into more manageable size files. (bzr r13135) --- src/widgets/stroke-style.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src/widgets/stroke-style.cpp') diff --git a/src/widgets/stroke-style.cpp b/src/widgets/stroke-style.cpp index dbfb1bcd2..9567f81ba 100644 --- a/src/widgets/stroke-style.cpp +++ b/src/widgets/stroke-style.cpp @@ -727,18 +727,18 @@ StrokeStyle::getItemColorForMarker(SPItem *item, Inkscape::PaintTarget fill_or_s void StrokeStyle::setDashSelectorFromStyle(SPDashSelector *dsel, SPStyle *style) { - if (style->stroke_dash.n_dash > 0) { + if (!style->stroke_dasharray.values.empty()) { double d[64]; - int len = MIN(style->stroke_dash.n_dash, 64); - for (int i = 0; i < len; i++) { + size_t len = MIN(style->stroke_dasharray.values.size(), 64); + for (unsigned i = 0; i < len; i++) { if (style->stroke_width.computed != 0) - d[i] = style->stroke_dash.dash[i] / style->stroke_width.computed; + d[i] = style->stroke_dasharray.values[i] / style->stroke_width.computed; else - d[i] = style->stroke_dash.dash[i]; // is there a better thing to do for stroke_width==0? + d[i] = style->stroke_dasharray.values[i]; // is there a better thing to do for stroke_width==0? } dsel->set_dash(len, d, style->stroke_width.computed != 0 ? - style->stroke_dash.offset / style->stroke_width.computed : - style->stroke_dash.offset); + style->stroke_dashoffset.value / style->stroke_width.computed : + style->stroke_dashoffset.value); } else { dsel->set_dash(0, NULL, 0.0); } -- cgit v1.2.3