stroke-style.cpp revision 3deb9b5ce0f058530cd0749009464b5afe8cf09c
/* Authors:
* Lauris Kaplinski <lauris@kaplinski.com>
* Bryce Harrington <brycehar@bryceharrington.org>
* bulia byak <buliabyak@users.sf.net>
* Maximilian Albert <maximilian.albert@gmail.com>
* Josh Andler <scislac@users.sf.net>
* Jon A. Cruz <jon@joncruz.org>
* Abhishek Sharma
*
* Copyright (C) 2001-2005 authors
* Copyright (C) 2001 Ximian, Inc.
* Copyright (C) 2004 John Cliff
* Copyright (C) 2008 Maximilian Albert (gtkmm-ification)
*
* Released under GNU GPL, read the file 'COPYING' for more information
*/
#define noSP_SS_VERBOSE
#include "widgets/dash-selector.h"
#include <gtkmm/radiobutton.h>
#include "desktop-handles.h"
#include "desktop-style.h"
#include "dialogs/dialog-events.h"
#include "display/canvas-bpath.h" // for SP_STROKE_LINEJOIN_*
#include "document-private.h"
#include "document-undo.h"
#include "gradient-chemistry.h"
#include "helper/stock-items.h"
#include "helper/unit-menu.h"
#include "inkscape.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/paint-selector.h"
#include "widgets/sp-widget.h"
#include "widgets/spw-utilities.h"
#include "ui/widget/spinbutton.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;
{
}
{
}
/* Line */
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);
/**
* Helper function for creating radio buttons. This should probably be re-thought out
* when reimplementing this with Gtkmm.
*/
static Gtk::RadioButton *
{
} else {
}
return tb;
}
/**
* Handles when user selects one of the markers from the marker combobox.
* Gets the marker uri string and applies it to all selected
* items in the current desktop.
*/
static void
{
return;
}
if (!document) {
return;
}
/* Get Marker */
// 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);
if (!SP_IS_SHAPE(item) || SP_IS_RECT(item)) { // can't set marker to rect, until it's converted to using <path>
continue;
}
if (selrepr) {
}
}
css = 0;
_("Set markers"));
};
static void
switch (which) {
case SP_MARKER_LOC_START:
break;
case SP_MARKER_LOC_MID:
break;
case SP_MARKER_LOC_END:
break;
default:
}
}
/**
* Sets the stroke width units for all selected items.
* Also handles absolute and dimensionless units.
*/
{
return FALSE;
}
if (!desktop) {
return FALSE;
}
return FALSE;
/* Absolute to percentage */
return FALSE;
return TRUE;
/* Percentage to absolute */
return TRUE;
}
return FALSE;
}
/**
* Creates a new widget for the line stroke style.
*/
{
f->show();
t->show();
t->set_border_width(4);
t->set_row_spacings(4);
f->add(*t);
gint i = 0;
//spw_label(t, C_("Stroke width", "_Width:"), 0, 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
#else
#endif
if (desktop)
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".
// 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).
// 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).
// 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).
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);
#if WITH_GTKMM_3_0
#else
#endif
a->signal_value_changed().connect(sigc::bind(sigc::ptr_fun(&sp_stroke_style_miterlimit_changed), spw));
i++;
/* Cap type */
// TRANSLATORS: cap type specifies the shape for the ends of lines
//spw_label(t, _("_Cap:"), 0, i);
// TRANSLATORS: Butt cap: the line shape does not extend beyond the end point
// of the line; the ends of the line are square
// TRANSLATORS: Round cap: the line shape extends beyond the end point of the
// line; the ends of the line are rounded
// TRANSLATORS: Square cap: the line shape extends beyond the end point of the
// line; the ends of the line are square
i++;
/* Dash */
//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?
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->set_tooltip_text(_("Start Markers are drawn on the first node of a path or shape"));
t->attach(*start_marker_combobox, 1, 4, i, i+1, (Gtk::EXPAND | Gtk::FILL), static_cast<Gtk::AttachOptions>(0), 0, 0);
i++;
mid_marker_combobox->set_tooltip_text(_("Mid Markers are drawn on every node of a path or shape except the first and last nodes"));
t->attach(*mid_marker_combobox, 1, 4, i, i+1, (Gtk::EXPAND | Gtk::FILL), static_cast<Gtk::AttachOptions>(0), 0, 0);
i++;
end_marker_combobox->set_tooltip_text(_("End Markers are drawn on the last node of a path or shape"));
t->attach(*end_marker_combobox, 1, 4, i, i+1, (Gtk::EXPAND | Gtk::FILL), static_cast<Gtk::AttachOptions>(0), 0, 0);
i++;
// FIXME: we cheat and still use gtk+ signals
spw);
spw);
return spw;
}
/**
* Callback for when stroke style widget is modified.
* Triggers update action.
*/
static void
{
}
}
/**
* Callback for when stroke style widget is changed.
* Triggers update action.
*/
static void
{
}
/**
* Sets selector widgets' dash style from an SPStyle object.
*/
static void
{
double d[64];
for (int i = 0; i < len; i++) {
else
}
} else {
}
}
/**
* Sets the join type for a line, and updates the stroke style widget's buttons
*/
static void
{
switch (jointype) {
case SP_STROKE_LINEJOIN_MITER:
break;
case SP_STROKE_LINEJOIN_ROUND:
break;
case SP_STROKE_LINEJOIN_BEVEL:
break;
default:
break;
}
}
/**
* Sets the cap type for a line, and updates the stroke style widget's buttons
*/
static void
{
switch (captype) {
case SP_STROKE_LINECAP_BUTT:
break;
case SP_STROKE_LINECAP_ROUND:
break;
case SP_STROKE_LINECAP_SQUARE:
break;
default:
break;
}
}
/**
* Callback for when stroke style widget is updated, including markers, cap type,
* join type, etc.
*/
static void
{
return;
}
// create temporary style
// query into it
int result_sw = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_STROKEWIDTH);
int result_ml = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_STROKEMITERLIMIT);
int result_join = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_STROKEJOIN);
// Nothing selected, grey-out all controls in the stroke-style dialog
sset->set_sensitive(false);
return;
} else {
sset->set_sensitive(true);
if (result_sw == QUERY_STYLE_MULTIPLE_AVERAGED) {
} else {
// same width, or only one object; no sense to keep percent, switch to absolute
}
}
} else {
}
// if none of the selected objects has a stroke, than quite some controls should be disabled
// The markers might still be shown though, so these will not be disabled
/* No objects stroked, set insensitive */
}
if (result_ml != QUERY_STYLE_NOTHING)
if (result_join != QUERY_STYLE_MULTIPLE_DIFFERENT) {
} else {
}
if (result_cap != QUERY_STYLE_MULTIPLE_DIFFERENT) {
} else {
}
return;
/* Markers */
/* Dash */
sset->set_sensitive(true);
}
/**
* Sets a line's dash properties in a CSS style object.
*/
static void
double scale)
{
if (ndash > 0) {
for (int i = 0; i < ndash; i++) {
if (i < (ndash - 1)) {
osarray << ",";
}
}
} else {
}
}
/**
* Sets line properties like width, dashes, markers, etc. on all currently selected items.
*/
static void
{
return;
}
/* TODO: Create some standardized method */
if (items) {
int ndash;
/* Set stroke width */
double width;
} else { // percentage
}
{
}
{
os_ml << miterlimit;
}
/* Set dash */
}
// reset to 100 percent
}
}
// we have already changed the items, so set style without changing selection
// FIXME: move the above stroke-setting stuff, including percentages, to desktop-style
css = 0;
_("Set stroke style"));
}
/**
* Callback for when the stroke style's width changes.
* Causes all line styles to be applied to all selected items.
*/
static void
{
return;
}
}
/**
* Callback for when the stroke style's miterlimit changes.
* Causes all line styles to be applied to all selected items.
*/
static void
{
return;
}
}
/**
* Callback for when the stroke style's dash changes.
* Causes all line styles to be applied to all selected items.
*/
static void
{
return;
}
}
/**
* 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.
*
*/
{
return;
}
if (tb->get_active()) {
if (join) {
}
/* TODO: Create some standardized method */
if (join) {
} else if (cap) {
}
css = 0;
_("Set stroke style"));
}
}
/**
* Updates the join style toggle buttons
*/
static void
{
}
/**
* Updates the cap style toggle buttons
*/
static void
{
}
/**
* Updates the marker combobox to highlight the appropriate marker and scroll to
* that marker.
*/
static void
{
{ "start_marker_combobox", SP_MARKER_LOC_START },
{ "mid_marker_combobox", SP_MARKER_LOC_MID },
{ "end_marker_combobox", SP_MARKER_LOC_END }
};
bool all_texts = true;
if (!SP_IS_TEXT (i->data)) {
all_texts = false;
}
}
for (unsigned i = 0; i < G_N_ELEMENTS(keyloc); ++i) {
// Per SVG spec, text objects cannot have markers; disable combobox if only texts are selected
}
// 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
for (unsigned i = 0; i < G_N_ELEMENTS(keyloc); ++i) {
// For all three marker types,
// find the corresponding combobox item
// Quit if we're in update state
return;
}
// 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);
// Scroll the combobox to that marker
} else {
}
}
}
/**
* 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.
*/
static SPObject*
{
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;
}
b[c] = '\0';
// FIXME: get the document from the object and let the caller pass it in
return marker;
}
/*
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 :