diff options
Diffstat (limited to 'src/widgets/stroke-style.cpp')
| -rw-r--r-- | src/widgets/stroke-style.cpp | 225 |
1 files changed, 164 insertions, 61 deletions
diff --git a/src/widgets/stroke-style.cpp b/src/widgets/stroke-style.cpp index d05b3b994..84a6e77ad 100644 --- a/src/widgets/stroke-style.cpp +++ b/src/widgets/stroke-style.cpp @@ -221,6 +221,67 @@ StrokeStyle::StrokeStyle() : #endif 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 = Gtk::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<Gtk::AttachOptions>(0), 0, 0); +#endif + + 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. + + spw_label(table, _("Markers:"), 0, i, NULL); + + hb = spw_hbox(table, 1, 1, i); + i++; + + startMarkerCombo = Gtk::manage(new MarkerComboBox("marker-start", SP_MARKER_LOC_START)); + startMarkerCombo->set_tooltip_text(_("Start Markers are drawn on the first node of a path or shape")); + startMarkerConn = startMarkerCombo->signal_changed().connect( + sigc::bind<MarkerComboBox *, StrokeStyle *, SPMarkerLoc>( + sigc::ptr_fun(&StrokeStyle::markerSelectCB), startMarkerCombo, this, SP_MARKER_LOC_START)); + startMarkerCombo->show(); + + hb->pack_start(*startMarkerCombo, true, true, 0); + + midMarkerCombo = Gtk::manage(new MarkerComboBox("marker-mid", SP_MARKER_LOC_MID)); + 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<MarkerComboBox *, StrokeStyle *, SPMarkerLoc>( + sigc::ptr_fun(&StrokeStyle::markerSelectCB), midMarkerCombo, this, SP_MARKER_LOC_MID)); + midMarkerCombo->show(); + + hb->pack_start(*midMarkerCombo, true, true, 0); + + endMarkerCombo = Gtk::manage(new MarkerComboBox("marker-end", SP_MARKER_LOC_END)); + endMarkerCombo->set_tooltip_text(_("End Markers are drawn on the last node of a path or shape")); + endMarkerConn = endMarkerCombo->signal_changed().connect( + sigc::bind<MarkerComboBox *, StrokeStyle *, SPMarkerLoc>( + sigc::ptr_fun(&StrokeStyle::markerSelectCB), endMarkerCombo, this, SP_MARKER_LOC_END)); + endMarkerCombo->show(); + + hb->pack_start(*endMarkerCombo, true, true, 0); + + 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". @@ -230,14 +291,6 @@ StrokeStyle::StrokeStyle() : Gtk::RadioButtonGroup joinGrp; - joinMiter = makeRadioButton(joinGrp, INKSCAPE_ICON("stroke-join-miter"), - hb, STROKE_STYLE_BUTTON_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(joinGrp, INKSCAPE_ICON("stroke-join-round"), hb, STROKE_STYLE_BUTTON_JOIN, "round"); @@ -254,7 +307,13 @@ StrokeStyle::StrokeStyle() : // "Join" option (in the Fill and Stroke dialog). joinBevel->set_tooltip_text(_("Bevel join")); - i++; + joinMiter = makeRadioButton(joinGrp, INKSCAPE_ICON("stroke-join-miter"), + hb, STROKE_STYLE_BUTTON_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")); /* Miterlimit */ // TRANSLATORS: Miter limit: only for "miter join", this limits the length @@ -265,8 +324,6 @@ StrokeStyle::StrokeStyle() : // 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>(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); @@ -277,7 +334,6 @@ StrokeStyle::StrokeStyle() : 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); @@ -288,6 +344,7 @@ StrokeStyle::StrokeStyle() : #else miterLimitAdj->signal_value_changed().connect(sigc::mem_fun(*this, &StrokeStyle::miterLimitChangedCB)); #endif + i++; /* Cap type */ @@ -322,64 +379,43 @@ StrokeStyle::StrokeStyle() : 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 = Gtk::manage(new SPDashSelector); - - dashSelector->show(); + /* Paint order */ + // TRANSLATORS: Paint order determines the order the 'fill', 'stroke', and 'markers are painted. + spw_label(table, _("Order:"), 0, i, NULL); -#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<Gtk::AttachOptions>(0), 0, 0); -#endif + hb = spw_hbox(table, 4, 1, i); - dashSelector->changed_signal.connect(sigc::mem_fun(*this, &StrokeStyle::lineDashChangedCB)); + Gtk::RadioButtonGroup paintOrderGrp; - i++; + paintOrderFSM = makeRadioButton(paintOrderGrp, INKSCAPE_ICON("paint-order-fsm"), + hb, STROKE_STYLE_BUTTON_ORDER, "normal"); + paintOrderFSM->set_tooltip_text(_("Fill, Stroke, Markers")); - /* 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. + paintOrderSFM = makeRadioButton(paintOrderGrp, INKSCAPE_ICON("paint-order-sfm"), + hb, STROKE_STYLE_BUTTON_ORDER, "stroke fill markers"); + paintOrderSFM->set_tooltip_text(_("Stroke, Fill, Markers")); - spw_label(table, _("Markers:"), 0, i, NULL); + paintOrderFMS = makeRadioButton(paintOrderGrp, INKSCAPE_ICON("paint-order-fms"), + hb, STROKE_STYLE_BUTTON_ORDER, "fill markers stroke"); + paintOrderFMS->set_tooltip_text(_("Fill, Markers, Stroke")); - hb = spw_hbox(table, 1, 1, i); i++; - startMarkerCombo = Gtk::manage(new MarkerComboBox("marker-start", SP_MARKER_LOC_START)); - startMarkerCombo->set_tooltip_text(_("Start Markers are drawn on the first node of a path or shape")); - startMarkerConn = startMarkerCombo->signal_changed().connect( - sigc::bind<MarkerComboBox *, StrokeStyle *, SPMarkerLoc>( - sigc::ptr_fun(&StrokeStyle::markerSelectCB), startMarkerCombo, this, SP_MARKER_LOC_START)); - startMarkerCombo->show(); + hb = spw_hbox(table, 4, 1, i); - hb->pack_start(*startMarkerCombo, true, true, 0); + paintOrderMFS = makeRadioButton(paintOrderGrp, INKSCAPE_ICON("paint-order-mfs"), + hb, STROKE_STYLE_BUTTON_ORDER, "markers fill stroke"); + paintOrderMFS->set_tooltip_text(_("Markers, Fill, Stroke")); - midMarkerCombo = Gtk::manage(new MarkerComboBox("marker-mid", SP_MARKER_LOC_MID)); - 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<MarkerComboBox *, StrokeStyle *, SPMarkerLoc>( - sigc::ptr_fun(&StrokeStyle::markerSelectCB), midMarkerCombo, this, SP_MARKER_LOC_MID)); - midMarkerCombo->show(); + paintOrderSMF = makeRadioButton(paintOrderGrp, INKSCAPE_ICON("paint-order-smf"), + hb, STROKE_STYLE_BUTTON_ORDER, "stroke markers fill"); + paintOrderSMF->set_tooltip_text(_("Stroke, Markers, Fill")); - hb->pack_start(*midMarkerCombo, true, true, 0); + paintOrderMSF = makeRadioButton(paintOrderGrp, INKSCAPE_ICON("paint-order-msf"), + hb, STROKE_STYLE_BUTTON_ORDER, "markers stroke fill"); + paintOrderMSF->set_tooltip_text(_("Markers, Stroke, Fill")); - endMarkerCombo = Gtk::manage(new MarkerComboBox("marker-end", SP_MARKER_LOC_END)); - endMarkerCombo->set_tooltip_text(_("End Markers are drawn on the last node of a path or shape")); - endMarkerConn = endMarkerCombo->signal_changed().connect( - sigc::bind<MarkerComboBox *, StrokeStyle *, SPMarkerLoc>( - sigc::ptr_fun(&StrokeStyle::markerSelectCB), endMarkerCombo, this, SP_MARKER_LOC_END)); - endMarkerCombo->show(); - - hb->pack_start(*endMarkerCombo, true, true, 0); + i++; setDesktop(desktop); updateLine(); @@ -480,7 +516,7 @@ void StrokeStyle::markerSelectCB(MarkerComboBox *marker_combo, StrokeStyle *spw, Inkscape::Selection *selection = spw->desktop->getSelection(); std::vector<SPItem*> itemlist=selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();i++){ + for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ SPItem *item = *i; if (!SP_IS_SHAPE(item) || SP_IS_RECT(item)) { // can't set marker to rect, until it's converted to using <path> continue; @@ -802,6 +838,43 @@ StrokeStyle::setCapType (unsigned const captype) } /** + * Sets the cap type for a line, and updates the stroke style widget's buttons + */ +void +StrokeStyle::setPaintOrder (gchar const *paint_order) +{ + Gtk::RadioButton *tb = paintOrderFSM; + + SPIPaintOrder temp; + temp.read( paint_order ); + + if (temp.layer[0] != SP_CSS_PAINT_ORDER_NORMAL) { + + if (temp.layer[0] == SP_CSS_PAINT_ORDER_FILL) { + if (temp.layer[1] == SP_CSS_PAINT_ORDER_STROKE) { + tb = paintOrderFSM; + } else { + tb = paintOrderFMS; + } + } else if (temp.layer[0] == SP_CSS_PAINT_ORDER_STROKE) { + if (temp.layer[1] == SP_CSS_PAINT_ORDER_FILL) { + tb = paintOrderSFM; + } else { + tb = paintOrderSMF; + } + } else { + if (temp.layer[1] == SP_CSS_PAINT_ORDER_STROKE) { + tb = paintOrderMSF; + } else { + tb = paintOrderMFS; + } + } + + } + setPaintOrderButtons(tb); +} + +/** * Callback for when stroke style widget is updated, including markers, cap type, * join type, etc. */ @@ -825,6 +898,9 @@ StrokeStyle::updateLine() int result_ml = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_STROKEMITERLIMIT); int result_cap = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_STROKECAP); int result_join = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_STROKEJOIN); + + int result_order = sp_desktop_query_style (SP_ACTIVE_DESKTOP, &query, QUERY_STYLE_PROPERTY_PAINTORDER); + SPIPaint &targPaint = (kind == FILL) ? query.fill : query.stroke; if (!sel || sel->isEmpty()) { @@ -902,6 +978,13 @@ StrokeStyle::updateLine() setCapButtons(NULL); } + if (result_order != QUERY_STYLE_MULTIPLE_DIFFERENT && + result_order != QUERY_STYLE_NOTHING ) { + setPaintOrder (query.paint_order.value); + } else { + setPaintOrder (NULL); + } + if (!sel || sel->isEmpty()) return; @@ -981,7 +1064,7 @@ StrokeStyle::scaleLine() int ndash; dashSelector->get_dash(&ndash, &dash, &offset); - for(std::vector<SPItem*>::const_iterator i=items.begin();i!=items.end();i++){ + for(std::vector<SPItem*>::const_iterator i=items.begin();i!=items.end();++i){ /* Set stroke width */ double width; if (unit->type == Inkscape::Util::UNIT_TYPE_LINEAR) { @@ -1109,6 +1192,11 @@ void StrokeStyle::buttonToggledCB(StrokeStyleButton *tb, StrokeStyle *spw) sp_repr_css_set_property(css, "stroke-linecap", tb->get_stroke_style()); sp_desktop_set_style (spw->desktop, css); spw->setCapButtons(tb); + break; + case STROKE_STYLE_BUTTON_ORDER: + sp_repr_css_set_property(css, "paint-order", tb->get_stroke_style()); + sp_desktop_set_style (spw->desktop, css); + //spw->setPaintButtons(tb); } sp_repr_css_attr_unref(css); @@ -1143,6 +1231,21 @@ StrokeStyle::setCapButtons(Gtk::ToggleButton *active) /** + * Updates the paint order style toggle buttons + */ +void +StrokeStyle::setPaintOrderButtons(Gtk::ToggleButton *active) +{ + paintOrderFSM->set_active(active == paintOrderFSM); + paintOrderSFM->set_active(active == paintOrderSFM); + paintOrderFMS->set_active(active == paintOrderFMS); + paintOrderMFS->set_active(active == paintOrderMFS); + paintOrderSMF->set_active(active == paintOrderSMF); + paintOrderMSF->set_active(active == paintOrderMSF); +} + + +/** * Updates the marker combobox to highlight the appropriate marker and scroll to * that marker. */ @@ -1156,7 +1259,7 @@ StrokeStyle::updateAllMarkers(std::vector<SPItem*> const &objects) }; bool all_texts = true; - for(std::vector<SPItem*>::const_iterator i=objects.begin();i!=objects.end();i++){ + for(std::vector<SPItem*>::const_iterator i=objects.begin();i!=objects.end();++i){ if (!SP_IS_TEXT (*i)) { all_texts = false; break; |
