stroke-style.cpp revision fc2e20aa610641335a34aa9b6604c3c4ec0ae7c4
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding/* Authors:
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * Lauris Kaplinski <lauris@kaplinski.com>
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * Bryce Harrington <brycehar@bryceharrington.org>
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * bulia byak <buliabyak@users.sf.net>
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * Maximilian Albert <maximilian.albert@gmail.com>
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * Josh Andler <scislac@users.sf.net>
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * Jon A. Cruz <jon@joncruz.org>
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * Abhishek Sharma
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding *
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * Copyright (C) 2001-2005 authors
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * Copyright (C) 2001 Ximian, Inc.
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * Copyright (C) 2004 John Cliff
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * Copyright (C) 2008 Maximilian Albert (gtkmm-ification)
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding *
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * Released under GNU GPL, read the file 'COPYING' for more information
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding */
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding#define noSP_SS_VERBOSE
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding#include "stroke-style.h"
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding#include "../gradient-chemistry.h"
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding#include "sp-gradient.h"
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding#include "sp-stop.h"
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding#include "svg/svg-color.h"
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding#include "util/units.h"
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding#include "ui/widget/unit-menu.h"
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fieldingusing Inkscape::DocumentUndo;
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fieldingusing Inkscape::Util::unit_table;
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding/**
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * Creates a new widget for the line stroke paint.
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding */
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fieldingGtk::Widget *sp_stroke_style_paint_widget_new(void)
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding{
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding return Inkscape::Widgets::createStyleWidget( STROKE );
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding}
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding/**
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * Creates a new widget for the line stroke style.
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding */
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fieldingGtk::Widget *sp_stroke_style_line_widget_new(void)
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding{
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding return Inkscape::Widgets::createStrokeStyleWidget();
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding}
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fieldingvoid sp_stroke_style_widget_set_desktop(Gtk::Widget *widget, SPDesktop *desktop)
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding{
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding Inkscape::StrokeStyle *ss = dynamic_cast<Inkscape::StrokeStyle*>(widget);
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding if (ss) {
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding ss->setDesktop(desktop);
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding }
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding}
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding/**
ab2c1c1c83ec91415565da5a71fbc15d9685caa6fielding * Extract the actual name of the link
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb * e.g. get mTriangle from url(#mTriangle).
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb * \return Buffer containing the actual name, allocated from GLib;
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb * the caller should free the buffer when they no longer need it.
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb */
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbbSPObject* getMarkerObj(gchar const *n, SPDocument *doc)
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb{
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb gchar const *p = n;
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb while (*p != '\0' && *p != '#') {
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb p++;
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb }
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb if (*p == '\0' || p[1] == '\0') {
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb return NULL;
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb }
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb p++;
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb int c = 0;
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb while (p[c] != '\0' && p[c] != ')') {
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb c++;
b6055b7832a0e4d0818416252fff5925aaebae4brbb }
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb if (p[c] == '\0') {
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb return NULL;
f31dc3b5fa09e42f0f47656ac852da5eb805d436rbb }
f31dc3b5fa09e42f0f47656ac852da5eb805d436rbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb gchar* b = g_strdup(p);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb b[c] = '\0';
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb // FIXME: get the document from the object and let the caller pass it in
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb SPObject *marker = doc->getObjectById(b);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb return marker;
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb}
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbbnamespace Inkscape {
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
d6e78e25e55d4eead29e200c9498479b747af3bdtrawick
d4f1d9c1ff112a8ab9bee31f196973761329b236rbb/**
48d7c43629323c8d5ee9f7bd0d194de0a376b391rbb * Construct a stroke-style radio button with a given icon
48d7c43629323c8d5ee9f7bd0d194de0a376b391rbb *
48d7c43629323c8d5ee9f7bd0d194de0a376b391rbb * \param[in] grp The Gtk::RadioButtonGroup to which to add the new button
f62217781f5eb75b0e52b9074fd21dc20a13b4a3trawick * \param[in] icon The icon to use for the button
f62217781f5eb75b0e52b9074fd21dc20a13b4a3trawick * \param[in] button_type The type of stroke-style radio button (join/cap)
f62217781f5eb75b0e52b9074fd21dc20a13b4a3trawick * \param[in] stroke_style The style attribute to associate with the button
f13986a3b239d6172a2774c436d8e46b1d5d38ectrawick */
f13986a3b239d6172a2774c436d8e46b1d5d38ectrawickStrokeStyle::StrokeStyleButton::StrokeStyleButton(Gtk::RadioButtonGroup &grp,
f13986a3b239d6172a2774c436d8e46b1d5d38ectrawick char const *icon,
56eeb8a683444cc87d7318dda9ea53031b554af5trawick StrokeStyleButtonType button_type,
8eb55224486bbbaff74eb07e59519f96812d3a5atrawick gchar const *stroke_style)
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb :
3d96ee83babeec32482c9082c9426340cee8c44dwrowe Gtk::RadioButton(grp),
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb button_type(button_type),
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm stroke_style(stroke_style)
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb{
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm show();
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb set_mode(false);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb Gtk::Widget *px = manage(Glib::wrap(sp_icon_new(Inkscape::ICON_SIZE_LARGE_TOOLBAR, icon)));
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb g_assert(px != NULL);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb px->show();
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb add(*px);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb}
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb/**
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm * Create the fill or stroke style widget, and hook up all the signals.
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb */
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbbGtk::Widget *Inkscape::Widgets::createStrokeStyleWidget( )
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb{
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb StrokeStyle *strokeStyle = new StrokeStyle();
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb return strokeStyle;
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb}
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbbStrokeStyle::StrokeStyle() :
905a3d840ca9cc2e1adc62db6d6e3683cf89a94agstein Gtk::VBox(),
905a3d840ca9cc2e1adc62db6d6e3683cf89a94agstein miterLimitSpin(),
bdab4bf874b26a09c92bcafb6c286ac316facd7dtrawick widthSpin(),
bdab4bf874b26a09c92bcafb6c286ac316facd7dtrawick unitSelector(),
bdab4bf874b26a09c92bcafb6c286ac316facd7dtrawick joinMiter(),
bdab4bf874b26a09c92bcafb6c286ac316facd7dtrawick joinRound(),
bdab4bf874b26a09c92bcafb6c286ac316facd7dtrawick joinBevel(),
bdab4bf874b26a09c92bcafb6c286ac316facd7dtrawick capButt(),
bdab4bf874b26a09c92bcafb6c286ac316facd7dtrawick capRound(),
bdab4bf874b26a09c92bcafb6c286ac316facd7dtrawick capSquare(),
bdab4bf874b26a09c92bcafb6c286ac316facd7dtrawick dashSelector(),
bdab4bf874b26a09c92bcafb6c286ac316facd7dtrawick update(false),
bdab4bf874b26a09c92bcafb6c286ac316facd7dtrawick desktop(0),
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb selectChangedConn(),
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb selectModifiedConn(),
ebe70c2684539a5fb2d899241d1601710dfa38a4trawick startMarkerConn(),
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb midMarkerConn(),
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb endMarkerConn()
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb{
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb Gtk::HBox *hb;
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb Gtk::HBox *f = new Gtk::HBox(false, 0);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb f->show();
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb add(*f);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb#if WITH_GTKMM_3_0
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb table = new Gtk::Grid();
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb table->set_border_width(4);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb table->set_row_spacing(4);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb#else
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb table = new Gtk::Table(3, 6, false);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb table->set_border_width(4);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb table->set_row_spacings(4);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb#endif
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb table->show();
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb f->add(*table);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb gint i = 0;
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb //spw_label(t, C_("Stroke width", "_Width:"), 0, i);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb hb = spw_hbox(table, 3, 1, i);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb// TODO: when this is gtkmmified, use an Inkscape::UI::Widget::ScalarUnit instead of the separate
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb// spinbutton and unit selector for stroke width. In sp_stroke_style_line_update, use
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb// setHundredPercent to remember the averaged width corresponding to 100%. Then the
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb// stroke_width_set_unit will be removed (because ScalarUnit takes care of conversions itself), and
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb// with it, the two remaining calls of stroke_average_width, allowing us to get rid of that
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb// function in desktop-style.
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb#if WITH_GTKMM_3_0
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb widthAdj = new Glib::RefPtr<Gtk::Adjustment>(Gtk::Adjustment::create(1.0, 0.0, 1000.0, 0.1, 10.0, 0.0));
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm#else
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb widthAdj = new Gtk::Adjustment(1.0, 0.0, 1000.0, 0.1, 10.0, 0.0);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb#endif
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb widthSpin = new Inkscape::UI::Widget::SpinButton(*widthAdj, 0.1, 3);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb widthSpin->set_tooltip_text(_("Stroke width"));
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb widthSpin->show();
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb spw_label(table, C_("Stroke width", "_Width:"), 0, i, widthSpin);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb sp_dialog_defocus_on_enter_cpp(widthSpin);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb hb->pack_start(*widthSpin, false, false, 0);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb unitSelector = new Inkscape::UI::Widget::UnitMenu();
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb unitSelector->setUnitType(Inkscape::Util::UNIT_TYPE_LINEAR);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb Gtk::Widget *us = manage(unitSelector);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb SPDesktop *desktop = SP_ACTIVE_DESKTOP;
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb unitSelector->addUnit(unit_table.getUnit("%"));
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb if (desktop) {
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb unitSelector->setUnit(sp_desktop_namedview(desktop)->doc_units->abbr);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb _old_unit = new Inkscape::Util::Unit(*sp_desktop_namedview(desktop)->doc_units);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb }
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb _old_unit = new Inkscape::Util::Unit(unitSelector->getUnit());
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb widthSpin->setUnitMenu(unitSelector);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb unitChangedConn = unitSelector->signal_changed().connect(sigc::mem_fun(*this, &StrokeStyle::unitChangedCB));
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb us->show();
7e998f3c4d3c22956a1105906169f2c9fdb8e57dtrawick
7e998f3c4d3c22956a1105906169f2c9fdb8e57dtrawick hb->pack_start(*us, FALSE, FALSE, 0);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb#if WITH_GTKMM_3_0
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm (*widthAdj)->signal_value_changed().connect(sigc::mem_fun(*this, &StrokeStyle::widthChangedCB));
39813b8983b16dce75194e7b70184fd68743db90manoj#else
39813b8983b16dce75194e7b70184fd68743db90manoj widthAdj->signal_value_changed().connect(sigc::mem_fun(*this, &StrokeStyle::widthChangedCB));
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb#endif
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb i++;
39813b8983b16dce75194e7b70184fd68743db90manoj
39813b8983b16dce75194e7b70184fd68743db90manoj /* Join type */
39813b8983b16dce75194e7b70184fd68743db90manoj // TRANSLATORS: The line join style specifies the shape to be used at the
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb // corners of paths. It can be "miter", "round" or "bevel".
39813b8983b16dce75194e7b70184fd68743db90manoj spw_label(table, _("Join:"), 0, i, NULL);
39813b8983b16dce75194e7b70184fd68743db90manoj
39813b8983b16dce75194e7b70184fd68743db90manoj hb = spw_hbox(table, 3, 1, i);
39813b8983b16dce75194e7b70184fd68743db90manoj
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb Gtk::RadioButtonGroup joinGrp;
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb joinMiter = makeRadioButton(joinGrp, INKSCAPE_ICON("stroke-join-miter"),
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb hb, STROKE_STYLE_BUTTON_JOIN, "miter");
10a4cdd68ef1ca0e54af296fe1d08ac00150c90bwrowe
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb // TRANSLATORS: Miter join: joining lines with a sharp (pointed) corner.
be0e6ea9b4676d85da9cde63fa9ae443d1560f54stoddard // For an example, draw a triangle with a large stroke width and modify the
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb // "Join" option (in the Fill and Stroke dialog).
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb joinMiter->set_tooltip_text(_("Miter join"));
905a3d840ca9cc2e1adc62db6d6e3683cf89a94agstein
905a3d840ca9cc2e1adc62db6d6e3683cf89a94agstein joinRound = makeRadioButton(joinGrp, INKSCAPE_ICON("stroke-join-round"),
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb hb, STROKE_STYLE_BUTTON_JOIN, "round");
905a3d840ca9cc2e1adc62db6d6e3683cf89a94agstein
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm // TRANSLATORS: Round join: joining lines with a rounded corner.
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb // For an example, draw a triangle with a large stroke width and modify the
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb // "Join" option (in the Fill and Stroke dialog).
905a3d840ca9cc2e1adc62db6d6e3683cf89a94agstein joinRound->set_tooltip_text(_("Round join"));
905a3d840ca9cc2e1adc62db6d6e3683cf89a94agstein
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm joinBevel = makeRadioButton(joinGrp, INKSCAPE_ICON("stroke-join-bevel"),
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb hb, STROKE_STYLE_BUTTON_JOIN, "bevel");
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb // TRANSLATORS: Bevel join: joining lines with a blunted (flattened) corner.
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb // For an example, draw a triangle with a large stroke width and modify the
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb // "Join" option (in the Fill and Stroke dialog).
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb joinBevel->set_tooltip_text(_("Bevel join"));
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb i++;
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb /* Miterlimit */
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb // TRANSLATORS: Miter limit: only for "miter join", this limits the length
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb // of the sharp "spike" when the lines connect at too sharp an angle.
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb // When two line segments meet at a sharp angle, a miter join results in a
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb // spike that extends well beyond the connection point. The purpose of the
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm // miter limit is to cut off such spikes (i.e. convert them into bevels)
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb // when they become too long.
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb //spw_label(t, _("Miter _limit:"), 0, i);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm hb = spw_hbox(table, 3, 1, i);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb#if WITH_GTKMM_3_0
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb miterLimitAdj = new Glib::RefPtr<Gtk::Adjustment>(Gtk::Adjustment::create(4.0, 0.0, 100.0, 0.1, 10.0, 0.0));
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb miterLimitSpin = new Inkscape::UI::Widget::SpinButton(*miterLimitAdj, 0.1, 2);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb#else
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb miterLimitAdj = new Gtk::Adjustment(4.0, 0.0, 100.0, 0.1, 10.0, 0.0);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb miterLimitSpin = new Inkscape::UI::Widget::SpinButton(*miterLimitAdj, 0.1, 2);
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm#endif
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb miterLimitSpin->set_tooltip_text(_("Maximum length of the miter (in units of stroke width)"));
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb miterLimitSpin->show();
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb spw_label(table, _("Miter _limit:"), 0, i, miterLimitSpin);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb sp_dialog_defocus_on_enter_cpp(miterLimitSpin);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb hb->pack_start(*miterLimitSpin, false, false, 0);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb#if WITH_GTKMM_3_0
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb (*miterLimitAdj)->signal_value_changed().connect(sigc::mem_fun(*this, &StrokeStyle::miterLimitChangedCB));
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb#else
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb miterLimitAdj->signal_value_changed().connect(sigc::mem_fun(*this, &StrokeStyle::miterLimitChangedCB));
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb#endif
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb i++;
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb /* Cap type */
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb // TRANSLATORS: cap type specifies the shape for the ends of lines
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb //spw_label(t, _("_Cap:"), 0, i);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb spw_label(table, _("Cap:"), 0, i, NULL);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb hb = spw_hbox(table, 3, 1, i);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb Gtk::RadioButtonGroup capGrp;
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb capButt = makeRadioButton(capGrp, INKSCAPE_ICON("stroke-cap-butt"),
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb hb, STROKE_STYLE_BUTTON_CAP, "butt");
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb // TRANSLATORS: Butt cap: the line shape does not extend beyond the end point
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb // of the line; the ends of the line are square
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb capButt->set_tooltip_text(_("Butt cap"));
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb capRound = makeRadioButton(capGrp, INKSCAPE_ICON("stroke-cap-round"),
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb hb, STROKE_STYLE_BUTTON_CAP, "round");
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb // TRANSLATORS: Round cap: the line shape extends beyond the end point of the
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb // line; the ends of the line are rounded
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb capRound->set_tooltip_text(_("Round cap"));
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb capSquare = makeRadioButton(capGrp, INKSCAPE_ICON("stroke-cap-square"),
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb hb, STROKE_STYLE_BUTTON_CAP, "square");
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb // TRANSLATORS: Square cap: the line shape extends beyond the end point of the
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb // line; the ends of the line are square
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb capSquare->set_tooltip_text(_("Square cap"));
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb i++;
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb /* Dash */
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb spw_label(table, _("Dashes:"), 0, i, NULL); //no mnemonic for now
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb //decide what to do:
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb // implement a set_mnemonic_source function in the
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb // SPDashSelector class, so that we do not have to
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb // expose any of the underlying widgets?
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb dashSelector = manage(new SPDashSelector);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb dashSelector->show();
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb#if WITH_GTKMM_3_0
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm dashSelector->set_hexpand();
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb dashSelector->set_halign(Gtk::ALIGN_FILL);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb dashSelector->set_valign(Gtk::ALIGN_CENTER);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb table->attach(*dashSelector, 1, i, 3, 1);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb#else
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb table->attach(*dashSelector, 1, 4, i, i+1, (Gtk::EXPAND | Gtk::FILL), static_cast<Gtk::AttachOptions>(0), 0, 0);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb#endif
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb dashSelector->changed_signal.connect(sigc::mem_fun(*this, &StrokeStyle::lineDashChangedCB));
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb i++;
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb /* Drop down marker selectors*/
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm // TRANSLATORS: Path markers are an SVG feature that allows you to attach arbitrary shapes
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb // (arrowheads, bullets, faces, whatever) to the start, end, or middle nodes of a path.
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb spw_label(table, _("Markers:"), 0, i, NULL);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb hb = spw_hbox(table, 1, 1, i);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb i++;
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb startMarkerCombo = manage(new MarkerComboBox("marker-start", SP_MARKER_LOC_START));
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb startMarkerCombo->set_tooltip_text(_("Start Markers are drawn on the first node of a path or shape"));
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb startMarkerConn = startMarkerCombo->signal_changed().connect(
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb sigc::bind<MarkerComboBox *, StrokeStyle *, SPMarkerLoc>(
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb sigc::ptr_fun(&StrokeStyle::markerSelectCB), startMarkerCombo, this, SP_MARKER_LOC_START));
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb startMarkerCombo->show();
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb hb->pack_start(*startMarkerCombo, true, true, 0);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb midMarkerCombo = manage(new MarkerComboBox("marker-mid", SP_MARKER_LOC_MID));
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb midMarkerCombo->set_tooltip_text(_("Mid Markers are drawn on every node of a path or shape except the first and last nodes"));
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb midMarkerConn = midMarkerCombo->signal_changed().connect(
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb sigc::bind<MarkerComboBox *, StrokeStyle *, SPMarkerLoc>(
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb sigc::ptr_fun(&StrokeStyle::markerSelectCB), midMarkerCombo, this, SP_MARKER_LOC_MID));
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb midMarkerCombo->show();
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb hb->pack_start(*midMarkerCombo, true, true, 0);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb endMarkerCombo = manage(new MarkerComboBox("marker-end", SP_MARKER_LOC_END));
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb endMarkerCombo->set_tooltip_text(_("End Markers are drawn on the last node of a path or shape"));
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb endMarkerConn = endMarkerCombo->signal_changed().connect(
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb sigc::bind<MarkerComboBox *, StrokeStyle *, SPMarkerLoc>(
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb sigc::ptr_fun(&StrokeStyle::markerSelectCB), endMarkerCombo, this, SP_MARKER_LOC_END));
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb endMarkerCombo->show();
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb hb->pack_start(*endMarkerCombo, true, true, 0);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb setDesktop(desktop);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb updateLine();
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb}
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbbStrokeStyle::~StrokeStyle()
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb{
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb selectModifiedConn.disconnect();
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb selectChangedConn.disconnect();
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb}
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbbvoid StrokeStyle::setDesktop(SPDesktop *desktop)
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb{
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb if (this->desktop != desktop) {
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb if (this->desktop) {
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb selectModifiedConn.disconnect();
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb selectChangedConn.disconnect();
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb }
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb this->desktop = desktop;
de916b564ef781bece2cac6b42c135f467a25b71trawick if (desktop && desktop->selection) {
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb selectChangedConn = desktop->selection->connectChanged(sigc::hide(sigc::mem_fun(*this, &StrokeStyle::selectionChangedCB)));
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb selectModifiedConn = desktop->selection->connectModified(sigc::hide<0>(sigc::mem_fun(*this, &StrokeStyle::selectionModifiedCB)));
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb }
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb updateLine();
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm }
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb}
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm/**
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb * Helper function for creating stroke-style radio buttons.
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb *
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb * \param[in] grp The Gtk::RadioButtonGroup in which to add the button
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb * \param[in] icon The icon for the button
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb * \param[in] hb The Gtk::Box container in which to add the button
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb * \param[in] button_type The type (join/cap) for the button
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb * \param[in] stroke_style The style attribute to associate with the button
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb *
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb * \details After instantiating the button, it is added to a container box and
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb * a handler for the toggle event is connected.
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb */
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbbStrokeStyle::StrokeStyleButton *
c33e53e173268441b12fa3939a189bca3205f8c1trawickStrokeStyle::makeRadioButton(Gtk::RadioButtonGroup &grp,
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb char const *icon,
d6e78e25e55d4eead29e200c9498479b747af3bdtrawick Gtk::HBox *hb,
c33e53e173268441b12fa3939a189bca3205f8c1trawick StrokeStyleButtonType button_type,
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb gchar const *stroke_style)
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb{
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb g_assert(icon != NULL);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb g_assert(hb != NULL);
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm
1f4b45b1cfdced41a18a6f3a2596e749c1c88fbftrawick StrokeStyleButton *tb = new StrokeStyleButton(grp, icon, button_type, stroke_style);
7e998f3c4d3c22956a1105906169f2c9fdb8e57dtrawick
7e998f3c4d3c22956a1105906169f2c9fdb8e57dtrawick hb->pack_start(*tb, false, false, 0);
7e998f3c4d3c22956a1105906169f2c9fdb8e57dtrawick set_data(icon, tb);
7e998f3c4d3c22956a1105906169f2c9fdb8e57dtrawick
7e998f3c4d3c22956a1105906169f2c9fdb8e57dtrawick tb->signal_toggled().connect(sigc::bind<StrokeStyleButton *, StrokeStyle *>(
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb sigc::ptr_fun(&StrokeStyle::buttonToggledCB), tb, this));
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb return tb;
7e998f3c4d3c22956a1105906169f2c9fdb8e57dtrawick}
7e998f3c4d3c22956a1105906169f2c9fdb8e57dtrawick
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb/**
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb * Handles when user selects one of the markers from the marker combobox.
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb * Gets the marker uri string and applies it to all selected
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb * items in the current desktop.
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb */
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbbvoid StrokeStyle::markerSelectCB(MarkerComboBox *marker_combo, StrokeStyle *spw, SPMarkerLoc const /*which*/)
d6e78e25e55d4eead29e200c9498479b747af3bdtrawick{
d6e78e25e55d4eead29e200c9498479b747af3bdtrawick if (spw->update) {
d6e78e25e55d4eead29e200c9498479b747af3bdtrawick return;
d6e78e25e55d4eead29e200c9498479b747af3bdtrawick }
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
7e998f3c4d3c22956a1105906169f2c9fdb8e57dtrawick spw->update = true;
7e998f3c4d3c22956a1105906169f2c9fdb8e57dtrawick
7e998f3c4d3c22956a1105906169f2c9fdb8e57dtrawick SPDocument *document = sp_desktop_document(spw->desktop);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb if (!document) {
bdab4bf874b26a09c92bcafb6c286ac316facd7dtrawick return;
bdab4bf874b26a09c92bcafb6c286ac316facd7dtrawick }
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb /* Get Marker */
7e998f3c4d3c22956a1105906169f2c9fdb8e57dtrawick gchar const *marker = marker_combo->get_active_marker_uri();
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
d6e78e25e55d4eead29e200c9498479b747af3bdtrawick SPCSSAttr *css = sp_repr_css_attr_new();
d6e78e25e55d4eead29e200c9498479b747af3bdtrawick gchar const *combo_id = marker_combo->get_id();
d6e78e25e55d4eead29e200c9498479b747af3bdtrawick sp_repr_css_set_property(css, combo_id, marker);
d6e78e25e55d4eead29e200c9498479b747af3bdtrawick
d6e78e25e55d4eead29e200c9498479b747af3bdtrawick // Also update the marker combobox, so the document's markers
d6e78e25e55d4eead29e200c9498479b747af3bdtrawick // show up at the top of the combobox
d6e78e25e55d4eead29e200c9498479b747af3bdtrawick// sp_stroke_style_line_update( SP_WIDGET(spw), desktop ? sp_desktop_selection(desktop) : NULL);
d6e78e25e55d4eead29e200c9498479b747af3bdtrawick //spw->updateMarkerHist(which);
d6e78e25e55d4eead29e200c9498479b747af3bdtrawick
d6e78e25e55d4eead29e200c9498479b747af3bdtrawick Inkscape::Selection *selection = sp_desktop_selection(spw->desktop);
d6e78e25e55d4eead29e200c9498479b747af3bdtrawick GSList const *items = selection->itemList();
7e998f3c4d3c22956a1105906169f2c9fdb8e57dtrawick for (; items != NULL; items = items->next) {
7e998f3c4d3c22956a1105906169f2c9fdb8e57dtrawick SPItem *item = reinterpret_cast<SPItem *>(items->data);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb if (!SP_IS_SHAPE(item) || SP_IS_RECT(item)) { // can't set marker to rect, until it's converted to using <path>
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb continue;
ec1807360643d980dcd3cb6b8df26ce50045c50dtrawick }
ec1807360643d980dcd3cb6b8df26ce50045c50dtrawick Inkscape::XML::Node *selrepr = item->getRepr();
ec1807360643d980dcd3cb6b8df26ce50045c50dtrawick if (selrepr) {
ec1807360643d980dcd3cb6b8df26ce50045c50dtrawick sp_repr_css_change_recursive(selrepr, css, "style");
ec1807360643d980dcd3cb6b8df26ce50045c50dtrawick SPObject *markerObj = getMarkerObj(marker, document);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb spw->setMarkerColor(markerObj, marker_combo->get_loc(), item);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb }
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb item->requestModified(SP_OBJECT_MODIFIED_FLAG);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb DocumentUndo::done(document, SP_VERB_DIALOG_FILL_STROKE, _("Set markers"));
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb }
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb sp_repr_css_attr_unref(css);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb css = 0;
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb spw->update = false;
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb};
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
1ccd992d37d62c8cb2056126f2234f64ec189bfddougmvoid StrokeStyle::updateMarkerHist(SPMarkerLoc const which)
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb{
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb switch (which) {
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb case SP_MARKER_LOC_START:
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb startMarkerConn.block();
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb startMarkerCombo->set_active_history();
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb startMarkerConn.unblock();
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb break;
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb case SP_MARKER_LOC_MID:
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb midMarkerConn.block();
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb midMarkerCombo->set_active_history();
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb midMarkerConn.unblock();
5cc3fd30d7916e90e8070d63d442f51306b25139trawick break;
5cc3fd30d7916e90e8070d63d442f51306b25139trawick
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb case SP_MARKER_LOC_END:
252b78fe9caba2d99e555dfc19f5c6aa4416e02dtrawick endMarkerConn.block();
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm endMarkerCombo->set_active_history();
5cc3fd30d7916e90e8070d63d442f51306b25139trawick endMarkerConn.unblock();
5827adc4c40ff4b10db9b09cea43f4307c8fc319trawick break;
5827adc4c40ff4b10db9b09cea43f4307c8fc319trawick default:
5827adc4c40ff4b10db9b09cea43f4307c8fc319trawick g_assert_not_reached();
5827adc4c40ff4b10db9b09cea43f4307c8fc319trawick }
5827adc4c40ff4b10db9b09cea43f4307c8fc319trawick}
5827adc4c40ff4b10db9b09cea43f4307c8fc319trawick
5827adc4c40ff4b10db9b09cea43f4307c8fc319trawick/**
5827adc4c40ff4b10db9b09cea43f4307c8fc319trawick * Callback for when UnitMenu widget is modified.
5827adc4c40ff4b10db9b09cea43f4307c8fc319trawick * Triggers update action.
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb */
5827adc4c40ff4b10db9b09cea43f4307c8fc319trawickvoid StrokeStyle::unitChangedCB()
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm{
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb Inkscape::Util::Unit new_unit = unitSelector->getUnit();
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb if (new_unit.type == Inkscape::Util::UNIT_TYPE_DIMENSIONLESS) {
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb widthSpin->set_value(100);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb }
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb widthSpin->set_value(Inkscape::Util::Quantity::convert(widthSpin->get_value(), *_old_unit, new_unit));
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb _old_unit = new Inkscape::Util::Unit(new_unit);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb}
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb/**
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm * Callback for when stroke style widget is modified.
a437779c0ce405a99250e725d7f6ad7533bed96ctrawick * Triggers update action.
a437779c0ce405a99250e725d7f6ad7533bed96ctrawick */
1ccd992d37d62c8cb2056126f2234f64ec189bfddougmvoid
be0e6ea9b4676d85da9cde63fa9ae443d1560f54stoddardStrokeStyle::selectionModifiedCB(guint flags)
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm{
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_PARENT_MODIFIED_FLAG)) {
5cc3fd30d7916e90e8070d63d442f51306b25139trawick updateLine();
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb }
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb}
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb/**
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb * Callback for when stroke style widget is changed.
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm * Triggers update action.
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb */
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbbvoid
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbbStrokeStyle::selectionChangedCB()
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb{
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb updateLine();
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb}
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb/*
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm * Fork marker if necessary and set the referencing items url to the new marker
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb * Return the new marker
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb */
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbbSPObject *
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbbStrokeStyle::forkMarker(SPObject *marker, int loc, SPItem *item)
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb{
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb if (!item || !marker) {
ebe70c2684539a5fb2d899241d1601710dfa38a4trawick return NULL;
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb }
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb gchar const *marker_id = SPMarkerNames[loc].key;
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb /*
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb * Optimization when all the references to this marker are from this item
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb * then we can reuse it and dont need to fork
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb */
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb Glib::ustring urlId = Glib::ustring::format("url(#", marker->getRepr()->attribute("id"), ")");
ebe70c2684539a5fb2d899241d1601710dfa38a4trawick unsigned int refs = 0;
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb for (int i = SP_MARKER_LOC_START; i < SP_MARKER_LOC_QTY; i++) {
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb if (item->style->marker[i].set && !strcmp(urlId.c_str(), item->style->marker[i].value)) {
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb refs++;
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb }
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb }
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb if (marker->hrefcount <= refs) {
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb return marker;
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb }
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
ebe70c2684539a5fb2d899241d1601710dfa38a4trawick marker = sp_marker_fork_if_necessary(marker);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb // Update the items url to new marker
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb Inkscape::XML::Node *mark_repr = marker->getRepr();
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb SPCSSAttr *css_item = sp_repr_css_attr_new();
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb sp_repr_css_set_property(css_item, marker_id, g_strconcat("url(#", mark_repr->attribute("id"), ")", NULL));
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb sp_repr_css_change_recursive(item->getRepr(), css_item, "style");
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb sp_repr_css_attr_unref(css_item);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb css_item = 0;
ebe70c2684539a5fb2d899241d1601710dfa38a4trawick
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb return marker;
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb}
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb/**
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb * Change the color of the marker to match the color of the item.
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb * Marker stroke color is set to item stroke color.
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb * Fill color :
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb * 1. If the item has fill, use that for the marker fill,
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb * 2. If the marker has same fill and stroke assume its solid, use item stroke for both fill and stroke the line stroke
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb * 3. If the marker has fill color, use the marker fill color
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb *
ebe70c2684539a5fb2d899241d1601710dfa38a4trawick */
ebe70c2684539a5fb2d899241d1601710dfa38a4trawickvoid
ebe70c2684539a5fb2d899241d1601710dfa38a4trawickStrokeStyle::setMarkerColor(SPObject *marker, int loc, SPItem *item)
ebe70c2684539a5fb2d899241d1601710dfa38a4trawick{
ebe70c2684539a5fb2d899241d1601710dfa38a4trawick
ebe70c2684539a5fb2d899241d1601710dfa38a4trawick if (!item || !marker) {
ebe70c2684539a5fb2d899241d1601710dfa38a4trawick return;
ebe70c2684539a5fb2d899241d1601710dfa38a4trawick }
ebe70c2684539a5fb2d899241d1601710dfa38a4trawick
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb Inkscape::Preferences *prefs = Inkscape::Preferences::get();
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb gboolean colorStock = prefs->getBool("/options/markers/colorStockMarkers", true);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb gboolean colorCustom = prefs->getBool("/options/markers/colorCustomMarkers", false);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb const gchar *stock = marker->getRepr()->attribute("inkscape:isstock");
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb gboolean isStock = (stock && !strcmp(stock,"true"));
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm if (isStock ? !colorStock : !colorCustom) {
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb return;
9edba918eaca55f72aa97a1b1c641ee2fd237fe6trawick }
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb // Check if we need to fork this marker
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb marker = forkMarker(marker, loc, item);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb Inkscape::XML::Node *repr = marker->getRepr()->firstChild();
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb if (!repr) {
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb return;
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm };
1f961f350a73525fcbac770383b8e6f0d18e8909trawick
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb // Current line style
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb SPCSSAttr *css_item = sp_css_attr_from_object(item, SP_STYLE_FLAG_ALWAYS);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb const char *lstroke = getItemColorForMarker(item, FOR_STROKE, loc);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb const char *lstroke_opacity = sp_repr_css_property(css_item, "stroke-opacity", "1");
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm const char *lfill = getItemColorForMarker(item, FOR_FILL, loc);
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm const char *lfill_opacity = sp_repr_css_property(css_item, "fill-opacity", "1");
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb // Current marker style
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm SPCSSAttr *css_marker = sp_css_attr_from_object(marker->firstChild(), SP_STYLE_FLAG_ALWAYS);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb const char *mfill = sp_repr_css_property(css_marker, "fill", "none");
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm const char *mstroke = sp_repr_css_property(css_marker, "fill", "none");
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm // Create new marker style with the lines stroke
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb SPCSSAttr *css = sp_repr_css_attr_new();
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb sp_repr_css_set_property(css, "stroke", lstroke);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb sp_repr_css_set_property(css, "stroke-opacity", lstroke_opacity);
f31dc3b5fa09e42f0f47656ac852da5eb805d436rbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb if (strcmp(lfill, "none") ) {
10a4cdd68ef1ca0e54af296fe1d08ac00150c90bwrowe // 1. If the line has fill, use that for the marker fill
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm sp_repr_css_set_property(css, "fill", lfill);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb sp_repr_css_set_property(css, "fill-opacity", lfill_opacity);
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm }
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb else if (mfill && mstroke && !strcmp(mfill, mstroke) && mfill[0] == '#' && strcmp(mfill, "#ffffff")) {
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb // 2. If the marker has same fill and stroke assume its solid. use line stroke for both fill and stroke the line stroke
9edba918eaca55f72aa97a1b1c641ee2fd237fe6trawick sp_repr_css_set_property(css, "fill", lstroke);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb sp_repr_css_set_property(css, "fill-opacity", lstroke_opacity);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb }
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb else if (mfill && mfill[0] == '#' && strcmp(mfill, "#000000")) {
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb // 3. If the marker has fill color, use the marker fill color
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm sp_repr_css_set_property(css, "fill", mfill);
1f961f350a73525fcbac770383b8e6f0d18e8909trawick //sp_repr_css_set_property(css, "fill-opacity", mfill_opacity);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb }
f31dc3b5fa09e42f0f47656ac852da5eb805d436rbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb sp_repr_css_change_recursive(marker->firstChild()->getRepr(), css, "style");
1f961f350a73525fcbac770383b8e6f0d18e8909trawick
f31dc3b5fa09e42f0f47656ac852da5eb805d436rbb // Tell the combos to update its image cache of this marker
1f961f350a73525fcbac770383b8e6f0d18e8909trawick gchar const *mid = marker->getRepr()->attribute("id");
1f961f350a73525fcbac770383b8e6f0d18e8909trawick startMarkerCombo->update_marker_image(mid);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb midMarkerCombo->update_marker_image(mid);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb endMarkerCombo->update_marker_image(mid);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb sp_repr_css_attr_unref(css);
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm css = 0;
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb}
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb/*
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm * Get the fill or stroke color of the item
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb * If its a gradient, then return first or last stop color
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb */
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbbconst char *
1ccd992d37d62c8cb2056126f2234f64ec189bfddougmStrokeStyle::getItemColorForMarker(SPItem *item, Inkscape::PaintTarget fill_or_stroke, int loc)
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb{
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb SPCSSAttr *css_item = sp_css_attr_from_object(item, SP_STYLE_FLAG_ALWAYS);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb const char *color;
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm if (fill_or_stroke == FOR_FILL)
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb color = sp_repr_css_property(css_item, "fill", "none");
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb else
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm color = sp_repr_css_property(css_item, "stroke", "none");
10a4cdd68ef1ca0e54af296fe1d08ac00150c90bwrowe
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm if (!strncmp (color, "url(", 4)) {
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb // If the item has a gradient use the first stop color for the marker
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb SPGradient *grad = getGradient(item, fill_or_stroke);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb if (grad) {
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm SPGradient *vector = grad->getVector(FALSE);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb SPStop *stop = vector->getFirstStop();
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb if (loc == SP_MARKER_LOC_END) {
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb stop = sp_last_stop(vector);
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm }
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb if (stop) {
f31dc3b5fa09e42f0f47656ac852da5eb805d436rbb guint32 const c1 = sp_stop_get_rgba32(stop);
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm gchar c[64];
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm sp_svg_write_color(c, sizeof(c), c1);
f31dc3b5fa09e42f0f47656ac852da5eb805d436rbb color = g_strdup(c);
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm //lstroke_opacity = Glib::ustring::format(stop->opacity).c_str();
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm }
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb }
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb }
1f961f350a73525fcbac770383b8e6f0d18e8909trawick return color;
f31dc3b5fa09e42f0f47656ac852da5eb805d436rbb}
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm/**
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm * Sets selector widgets' dash style from an SPStyle object.
f31dc3b5fa09e42f0f47656ac852da5eb805d436rbb */
1ccd992d37d62c8cb2056126f2234f64ec189bfddougmvoid
1ccd992d37d62c8cb2056126f2234f64ec189bfddougmStrokeStyle::setDashSelectorFromStyle(SPDashSelector *dsel, SPStyle *style)
1f961f350a73525fcbac770383b8e6f0d18e8909trawick{
1f961f350a73525fcbac770383b8e6f0d18e8909trawick if (style->stroke_dash.n_dash > 0) {
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb double d[64];
f31dc3b5fa09e42f0f47656ac852da5eb805d436rbb int len = MIN(style->stroke_dash.n_dash, 64);
1f961f350a73525fcbac770383b8e6f0d18e8909trawick for (int i = 0; i < len; i++) {
f31dc3b5fa09e42f0f47656ac852da5eb805d436rbb if (style->stroke_width.computed != 0)
1f961f350a73525fcbac770383b8e6f0d18e8909trawick d[i] = style->stroke_dash.dash[i] / style->stroke_width.computed;
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb else
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm d[i] = style->stroke_dash.dash[i]; // is there a better thing to do for stroke_width==0?
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb }
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb dsel->set_dash(len, d, style->stroke_width.computed != 0 ?
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb style->stroke_dash.offset / style->stroke_width.computed :
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb style->stroke_dash.offset);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb } else {
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb dsel->set_dash(0, NULL, 0.0);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb }
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb}
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb/**
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb * Sets the join type for a line, and updates the stroke style widget's buttons
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb */
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbbvoid
f31dc3b5fa09e42f0f47656ac852da5eb805d436rbbStrokeStyle::setJoinType (unsigned const jointype)
f31dc3b5fa09e42f0f47656ac852da5eb805d436rbb{
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb Gtk::RadioButton *tb = NULL;
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb switch (jointype) {
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb case SP_STROKE_LINEJOIN_MITER:
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb tb = joinMiter;
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb break;
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb case SP_STROKE_LINEJOIN_ROUND:
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb tb = joinRound;
f31dc3b5fa09e42f0f47656ac852da5eb805d436rbb break;
446b877d2ab69d9bbcd9152a2d54814f05f1c00brbb case SP_STROKE_LINEJOIN_BEVEL:
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb tb = joinBevel;
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb break;
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb default:
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb break;
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb }
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb setJoinButtons(tb);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb}
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb/**
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb * Sets the cap type for a line, and updates the stroke style widget's buttons
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb */
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbbvoid
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbbStrokeStyle::setCapType (unsigned const captype)
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb{
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb Gtk::RadioButton *tb = NULL;
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb switch (captype) {
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb case SP_STROKE_LINECAP_BUTT:
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb tb = capButt;
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb break;
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb case SP_STROKE_LINECAP_ROUND:
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb tb = capRound;
000b67449410515eac43e76ef6667915bfd4d2abgstein break;
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb case SP_STROKE_LINECAP_SQUARE:
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb tb = capSquare;
000b67449410515eac43e76ef6667915bfd4d2abgstein break;
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb default:
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb break;
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb }
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb setCapButtons(tb);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb}
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb/**
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb * Callback for when stroke style widget is updated, including markers, cap type,
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm * join type, etc.
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb */
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbbvoid
000b67449410515eac43e76ef6667915bfd4d2abgsteinStrokeStyle::updateLine()
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb{
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb if (update) {
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb return;
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb }
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb update = true;
905a3d840ca9cc2e1adc62db6d6e3683cf89a94agstein
000b67449410515eac43e76ef6667915bfd4d2abgstein Inkscape::Selection *sel = desktop ? sp_desktop_selection(desktop) : NULL;
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb FillOrStroke kind = GPOINTER_TO_INT(get_data("kind")) ? FILL : STROKE;
905a3d840ca9cc2e1adc62db6d6e3683cf89a94agstein
000b67449410515eac43e76ef6667915bfd4d2abgstein // create temporary style
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb // query into it
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb int result_sw = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_STROKEWIDTH);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb int result_ml = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_STROKEMITERLIMIT);
000b67449410515eac43e76ef6667915bfd4d2abgstein int result_cap = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_STROKECAP);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb int result_join = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_STROKEJOIN);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb SPIPaint &targPaint = (kind == FILL) ? query->fill : query->stroke;
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb if (!sel || sel->isEmpty()) {
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb // Nothing selected, grey-out all controls in the stroke-style dialog
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb table->set_sensitive(false);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb update = false;
fbd275d566729dd3019ebc7b41acf7038fac31dftrawick
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb return;
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb } else {
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb table->set_sensitive(true);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb Inkscape::Util::Unit const *unit = new Inkscape::Util::Unit(unitSelector->getUnit());
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb if (result_sw == QUERY_STYLE_MULTIPLE_AVERAGED) {
fbd275d566729dd3019ebc7b41acf7038fac31dftrawick unitSelector->setUnit("%");
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb } else {
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb // same width, or only one object; no sense to keep percent, switch to absolute
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb if (unit->type != Inkscape::Util::UNIT_TYPE_LINEAR) {
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb unitSelector->setUnit(sp_desktop_namedview(SP_ACTIVE_DESKTOP)->doc_units->abbr);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb }
f31dc3b5fa09e42f0f47656ac852da5eb805d436rbb }
f31dc3b5fa09e42f0f47656ac852da5eb805d436rbb
f31dc3b5fa09e42f0f47656ac852da5eb805d436rbb unit = new Inkscape::Util::Unit(unitSelector->getUnit());
de9611fec26d95afd15dc20cd671e70b26f27261trawick
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb if (unit->type == Inkscape::Util::UNIT_TYPE_LINEAR) {
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb double avgwidth = Inkscape::Util::Quantity::convert(query->stroke_width.computed, "px", *unit);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb#if WITH_GTKMM_3_0
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb (*widthAdj)->set_value(avgwidth);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb#else
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb widthAdj->set_value(avgwidth);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb#endif
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb } else {
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb#if WITH_GTKMM_3_0
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb (*widthAdj)->set_value(100);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb#else
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb widthAdj->set_value(100);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb#endif
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb }
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb // if none of the selected objects has a stroke, than quite some controls should be disabled
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb // The markers might still be shown though, so these will not be disabled
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm bool enabled = (result_sw != QUERY_STYLE_NOTHING) && !targPaint.isNoneSet();
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb /* No objects stroked, set insensitive */
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb joinMiter->set_sensitive(enabled);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb joinRound->set_sensitive(enabled);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb joinBevel->set_sensitive(enabled);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb miterLimitSpin->set_sensitive(enabled);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb capButt->set_sensitive(enabled);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb capRound->set_sensitive(enabled);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb capSquare->set_sensitive(enabled);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb dashSelector->set_sensitive(enabled);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb }
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb if (result_ml != QUERY_STYLE_NOTHING)
f31dc3b5fa09e42f0f47656ac852da5eb805d436rbb#if WITH_GTKMM_3_0
f31dc3b5fa09e42f0f47656ac852da5eb805d436rbb (*miterLimitAdj)->set_value(query->stroke_miterlimit.value); // TODO: reflect averagedness?
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb#else
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb miterLimitAdj->set_value(query->stroke_miterlimit.value); // TODO: reflect averagedness?
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb#endif
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb if (result_join != QUERY_STYLE_MULTIPLE_DIFFERENT) {
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb setJoinType(query->stroke_linejoin.value);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb } else {
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb setJoinButtons(NULL);
bc617dd40a5c924bb2dd1549c8b09700510b6367trawick }
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb if (result_cap != QUERY_STYLE_MULTIPLE_DIFFERENT) {
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb setCapType (query->stroke_linecap.value);
f31dc3b5fa09e42f0f47656ac852da5eb805d436rbb } else {
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb setCapButtons(NULL);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb }
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb sp_style_unref(query);
f31dc3b5fa09e42f0f47656ac852da5eb805d436rbb
f31dc3b5fa09e42f0f47656ac852da5eb805d436rbb if (!sel || sel->isEmpty())
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb return;
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm GSList const *objects = sel->itemList();
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb SPObject * const object = SP_OBJECT(objects->data);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb SPStyle * const style = object->style;
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb /* Markers */
f31dc3b5fa09e42f0f47656ac852da5eb805d436rbb updateAllMarkers(objects); // FIXME: make this desktop query too
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb /* Dash */
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb setDashSelectorFromStyle(dashSelector, style); // FIXME: make this desktop query too
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb table->set_sensitive(true);
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb update = false;
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb}
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb/**
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb * Sets a line's dash properties in a CSS style object.
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb */
1ccd992d37d62c8cb2056126f2234f64ec189bfddougmvoid
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbbStrokeStyle::setScaledDash(SPCSSAttr *css,
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb int ndash, double *dash, double offset,
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb double scale)
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb{
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb if (ndash > 0) {
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb Inkscape::CSSOStringStream osarray;
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb for (int i = 0; i < ndash; i++) {
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb osarray << dash[i] * scale;
000b67449410515eac43e76ef6667915bfd4d2abgstein if (i < (ndash - 1)) {
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb osarray << ",";
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb }
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb }
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb sp_repr_css_set_property(css, "stroke-dasharray", osarray.str().c_str());
f31dc3b5fa09e42f0f47656ac852da5eb805d436rbb
f31dc3b5fa09e42f0f47656ac852da5eb805d436rbb Inkscape::CSSOStringStream osoffset;
f31dc3b5fa09e42f0f47656ac852da5eb805d436rbb osoffset << offset * scale;
f31dc3b5fa09e42f0f47656ac852da5eb805d436rbb sp_repr_css_set_property(css, "stroke-dashoffset", osoffset.str().c_str());
f31dc3b5fa09e42f0f47656ac852da5eb805d436rbb } else {
4b86db47932a21da10cd35317b3da737f2b073c4rbb sp_repr_css_set_property(css, "stroke-dasharray", "none");
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb sp_repr_css_set_property(css, "stroke-dashoffset", NULL);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb }
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb}
195913a5dc2a3e53e0bfbfb0894199053617b2a5trawick
f31dc3b5fa09e42f0f47656ac852da5eb805d436rbb/**
f31dc3b5fa09e42f0f47656ac852da5eb805d436rbb * Sets line properties like width, dashes, markers, etc. on all currently selected items.
f31dc3b5fa09e42f0f47656ac852da5eb805d436rbb */
f31dc3b5fa09e42f0f47656ac852da5eb805d436rbbvoid
f31dc3b5fa09e42f0f47656ac852da5eb805d436rbbStrokeStyle::scaleLine()
4b86db47932a21da10cd35317b3da737f2b073c4rbb{
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb if (update) {
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb return;
195913a5dc2a3e53e0bfbfb0894199053617b2a5trawick }
195913a5dc2a3e53e0bfbfb0894199053617b2a5trawick
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb update = true;
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb SPDocument *document = sp_desktop_document (desktop);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb Inkscape::Selection *selection = sp_desktop_selection (desktop);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb GSList const *items = selection->itemList();
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb /* TODO: Create some standardized method */
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb SPCSSAttr *css = sp_repr_css_attr_new();
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb if (items) {
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb#if WITH_GTKMM_3_0
ff72a628571224579194f37cf8db96186ae889a5dougm double width_typed = (*widthAdj)->get_value();
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb double const miterlimit = (*miterLimitAdj)->get_value();
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb#else
3d96ee83babeec32482c9082c9426340cee8c44dwrowe double width_typed = widthAdj->get_value();
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb double const miterlimit = miterLimitAdj->get_value();
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb#endif
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb Inkscape::Util::Unit const *const unit = new Inkscape::Util::Unit(unitSelector->getUnit());
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb double *dash, offset;
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb int ndash;
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb dashSelector->get_dash(&ndash, &dash, &offset);
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb
8877cd6a81e0d6b3c534609c4ebf06a96734dabcrbb for (GSList const *i = items; i != NULL; i = i->next) {
/* Set stroke width */
double width;
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;
}
{
Inkscape::CSSOStringStream os_width;
os_width << width;
sp_repr_css_set_property(css, "stroke-width", os_width.str().c_str());
}
{
Inkscape::CSSOStringStream os_ml;
os_ml << miterlimit;
sp_repr_css_set_property(css, "stroke-miterlimit", os_ml.str().c_str());
}
/* Set dash */
setScaledDash(css, ndash, dash, offset, width);
sp_desktop_apply_css_recursive (SP_OBJECT(i->data), css, true);
}
g_free(dash);
if (unit->type != Inkscape::Util::UNIT_TYPE_LINEAR) {
// reset to 100 percent
#if WITH_GTKMM_3_0
(*widthAdj)->set_value(100.0);
#else
widthAdj->set_value(100.0);
#endif
}
}
// we have already changed the items, so set style without changing selection
// FIXME: move the above stroke-setting stuff, including percentages, to desktop-style
sp_desktop_set_style (desktop, css, false);
sp_repr_css_attr_unref(css);
css = 0;
DocumentUndo::done(document, SP_VERB_DIALOG_FILL_STROKE,
_("Set stroke style"));
update = false;
}
/**
* Callback for when the stroke style's width changes.
* Causes all line styles to be applied to all selected items.
*/
void
StrokeStyle::widthChangedCB()
{
if (update) {
return;
}
scaleLine();
}
/**
* Callback for when the stroke style's miterlimit changes.
* Causes all line styles to be applied to all selected items.
*/
void
StrokeStyle::miterLimitChangedCB()
{
if (update) {
return;
}
scaleLine();
}
/**
* Callback for when the stroke style's dash changes.
* Causes all line styles to be applied to all selected items.
*/
void
StrokeStyle::lineDashChangedCB()
{
if (update) {
return;
}
scaleLine();
}
/**
* This routine handles toggle events for buttons in the stroke style dialog.
*
* When activated, this routine gets the data for the various widgets, and then
* calls the respective routines to update css properties, etc.
*
*/
void StrokeStyle::buttonToggledCB(StrokeStyleButton *tb, StrokeStyle *spw)
{
if (spw->update) {
return;
}
if (tb->get_active()) {
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();
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);
css = 0;
DocumentUndo::done(sp_desktop_document(spw->desktop), SP_VERB_DIALOG_FILL_STROKE,
_("Set stroke style"));
}
}
/**
* Updates the join style toggle buttons
*/
void
StrokeStyle::setJoinButtons(Gtk::ToggleButton *active)
{
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
*/
void
StrokeStyle::setCapButtons(Gtk::ToggleButton *active)
{
capButt->set_active(active == capButt);
capRound->set_active(active == capRound);
capSquare->set_active(active == capSquare);
}
/**
* Updates the marker combobox to highlight the appropriate marker and scroll to
* that marker.
*/
void
StrokeStyle::updateAllMarkers(GSList const *objects)
{
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;
for (GSList *i = (GSList *) objects; i != NULL; i = i->next) {
if (!SP_IS_TEXT (i->data)) {
all_texts = false;
}
}
for (unsigned i = 0; i < G_N_ELEMENTS(keyloc); ++i) {
MarkerComboBox *combo = static_cast<MarkerComboBox *>(keyloc[i].key);
// Per SVG spec, text objects cannot have markers; disable combobox if only texts are selected
combo->set_sensitive(!all_texts);
}
// We show markers of the first object in the list only
// FIXME: use the first in the list that has the marker of each type, if any
SPObject *object = SP_OBJECT(objects->data);
for (unsigned i = 0; i < G_N_ELEMENTS(keyloc); ++i) {
// For all three marker types,
// find the corresponding combobox item
MarkerComboBox *combo = static_cast<MarkerComboBox *>(keyloc[i].key);
// Quit if we're in update state
if (combo->update()) {
return;
}
combo->setDesktop(desktop);
if (object->style->marker[keyloc[i].loc].value != NULL && !all_texts) {
// If the object has this type of markers,
// Extract the name of the marker that the object uses
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(marker, combo->get_loc(), SP_ITEM(object));
SPDocument *document = sp_desktop_document(desktop);
DocumentUndo::done(document, SP_VERB_DIALOG_FILL_STROKE,
_("Set marker color"));
}
} else {
combo->set_current(NULL);
}
}
}
} // namespace Inkscape
/*
Local Variables:
mode:c++
c-file-style:"stroustrup"
c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
indent-tabs-mode:nil
fill-column:99
End:
*/
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :