1 /**
2 * \brief Selected style indicator (fill, stroke, opacity)
3 *
4 * Author:
5 * buliabyak@gmail.com
6 *
7 * Copyright (C) 2005 author
8 *
9 * Released under GNU GPL. Read the file 'COPYING' for more information.
10 */
12 #ifdef HAVE_CONFIG_H
13 # include <config.h>
14 #endif
16 #include <gtk/gtkdnd.h>
18 #include "selected-style.h"
20 #include "widgets/spw-utilities.h"
21 #include "ui/widget/color-preview.h"
23 #include "selection.h"
24 #include "desktop-handles.h"
25 #include "style.h"
26 #include "desktop-style.h"
27 #include "sp-linear-gradient-fns.h"
28 #include "sp-radial-gradient-fns.h"
29 #include "sp-pattern.h"
30 #include "dialogs/object-properties.h"
31 #include "xml/repr.h"
32 #include "document.h"
33 #include "widgets/widget-sizes.h"
34 #include "widgets/spinbutton-events.h"
35 #include "svg/svg-color.h"
36 #include "svg/css-ostringstream.h"
37 #include "helper/units.h"
38 #include "verbs.h"
40 static gdouble const _sw_presets[] = { 32 , 16 , 10 , 8 , 6 , 4 , 3 , 2 , 1.5 , 1 , 0.75 , 0.5 , 0.25 , 0.1 };
41 static gchar* const _sw_presets_str[] = {"32", "16", "10", "8", "6", "4", "3", "2", "1.5", "1", "0.75", "0.5", "0.25", "0.1"};
43 static void
44 ss_selection_changed (Inkscape::Selection *, gpointer data)
45 {
46 Inkscape::UI::Widget::SelectedStyle *ss = (Inkscape::UI::Widget::SelectedStyle *) data;
47 ss->update();
48 }
50 static void
51 ss_selection_modified (Inkscape::Selection *selection, guint flags, gpointer data)
52 {
53 ss_selection_changed (selection, data);
54 }
56 static void
57 ss_subselection_changed (gpointer dragger, gpointer data)
58 {
59 ss_selection_changed (NULL, data);
60 }
62 namespace Inkscape {
63 namespace UI {
64 namespace Widget {
67 typedef struct {
68 SelectedStyle* parent;
69 int item;
70 } DropTracker;
72 /* Drag and Drop */
73 typedef enum {
74 APP_X_COLOR
75 } ui_drop_target_info;
77 static GtkTargetEntry ui_drop_target_entries [] = {
78 {"application/x-color", 0, APP_X_COLOR}
79 };
81 #define ENTRIES_SIZE(n) sizeof(n)/sizeof(n[0])
82 static guint nui_drop_target_entries = ENTRIES_SIZE(ui_drop_target_entries);
85 SelectedStyle::SelectedStyle(bool layout)
86 : _desktop (NULL),
88 _table(2, 6),
89 _fill_label (_("F:")),
90 _stroke_label (_("S:")),
91 _opacity_label (_("O:")),
92 _fill_place (),
93 _stroke_place (),
95 _fill_flag_place (),
96 _stroke_flag_place (),
98 _opacity_place (),
99 _opacity_adjustment (1.0, 0.0, 1.0, 0.01, 0.1),
100 _opacity_sb (0.02, 2),
102 _stroke (),
103 _stroke_width (""),
105 _opacity_blocked (false),
107 _popup_px(_sw_group),
108 _popup_pt(_sw_group),
109 _popup_mm(_sw_group),
111 _sw_unit(NULL),
113 _tooltips ()
115 {
116 _drop[0] = _drop[1] = 0;
117 _dropEnabled[0] = _dropEnabled[1] = false;
119 _fill_label.set_alignment(0.0, 0.5);
120 _fill_label.set_padding(0, 0);
121 _stroke_label.set_alignment(0.0, 0.5);
122 _stroke_label.set_padding(0, 0);
123 _opacity_label.set_alignment(0.0, 0.5);
124 _opacity_label.set_padding(0, 0);
126 _table.set_col_spacings (2);
127 _table.set_row_spacings (0);
129 for (int i = SS_FILL; i <= SS_STROKE; i++) {
131 _na[i].set_markup (_("N/A"));
132 sp_set_font_size_smaller (GTK_WIDGET(_na[i].gobj()));
133 _na[i].show_all();
134 __na[i] = (_("Nothing selected"));
136 _none[i].set_markup (_("None"));
137 sp_set_font_size_smaller (GTK_WIDGET(_none[i].gobj()));
138 _none[i].show_all();
139 __none[i] = (i == SS_FILL)? (_("No fill")) : (_("No stroke"));
141 _pattern[i].set_markup (_("Pattern"));
142 sp_set_font_size_smaller (GTK_WIDGET(_pattern[i].gobj()));
143 _pattern[i].show_all();
144 __pattern[i] = (i == SS_FILL)? (_("Pattern fill")) : (_("Pattern stroke"));
146 _lgradient[i].set_markup (_("L Gradient"));
147 sp_set_font_size_smaller (GTK_WIDGET(_lgradient[i].gobj()));
148 _lgradient[i].show_all();
149 __lgradient[i] = (i == SS_FILL)? (_("Linear gradient fill")) : (_("Linear gradient stroke"));
151 _rgradient[i].set_markup (_("R Gradient"));
152 sp_set_font_size_smaller (GTK_WIDGET(_rgradient[i].gobj()));
153 _rgradient[i].show_all();
154 __rgradient[i] = (i == SS_FILL)? (_("Radial gradient fill")) : (_("Radial gradient stroke"));
156 _many[i].set_markup (_("Different"));
157 sp_set_font_size_smaller (GTK_WIDGET(_many[i].gobj()));
158 _many[i].show_all();
159 __many[i] = (i == SS_FILL)? (_("Different fills")) : (_("Different strokes"));
161 _unset[i].set_markup (_("Unset"));
162 sp_set_font_size_smaller (GTK_WIDGET(_unset[i].gobj()));
163 _unset[i].show_all();
164 __unset[i] = (i == SS_FILL)? (_("Unset fill")) : (_("Unset stroke"));
166 _color_preview[i] = new Inkscape::UI::Widget::ColorPreview (0);
167 __color[i] = (i == SS_FILL)? (_("Flat color fill")) : (_("Flat color stroke"));
169 // TRANSLATOR COMMENT: A means "Averaged"
170 _averaged[i].set_markup (_("<b>a</b>"));
171 sp_set_font_size_smaller (GTK_WIDGET(_averaged[i].gobj()));
172 _averaged[i].show_all();
173 __averaged[i] = (i == SS_FILL)? (_("Fill is averaged over selected objects")) : (_("Stroke is averaged over selected objects"));
175 // TRANSLATOR COMMENT: M means "Multiple"
176 _multiple[i].set_markup (_("<b>m</b>"));
177 sp_set_font_size_smaller (GTK_WIDGET(_multiple[i].gobj()));
178 _multiple[i].show_all();
179 __multiple[i] = (i == SS_FILL)? (_("Multiple selected objects have the same fill")) : (_("Multiple selected objects have the same stroke"));
181 _popup_edit[i].add(*(new Gtk::Label((i == SS_FILL)? _("Edit fill...") : _("Edit stroke..."), 0.0, 0.5)));
182 _popup_edit[i].signal_activate().connect(sigc::mem_fun(*this,
183 (i == SS_FILL)? &SelectedStyle::on_fill_edit : &SelectedStyle::on_stroke_edit ));
185 _popup_lastused[i].add(*(new Gtk::Label(_("Last set color"), 0.0, 0.5)));
186 _popup_lastused[i].signal_activate().connect(sigc::mem_fun(*this,
187 (i == SS_FILL)? &SelectedStyle::on_fill_lastused : &SelectedStyle::on_stroke_lastused ));
189 _popup_lastselected[i].add(*(new Gtk::Label(_("Last selected color"), 0.0, 0.5)));
190 _popup_lastselected[i].signal_activate().connect(sigc::mem_fun(*this,
191 (i == SS_FILL)? &SelectedStyle::on_fill_lastselected : &SelectedStyle::on_stroke_lastselected ));
193 _popup_invert[i].add(*(new Gtk::Label(_("Invert"), 0.0, 0.5)));
194 _popup_invert[i].signal_activate().connect(sigc::mem_fun(*this,
195 (i == SS_FILL)? &SelectedStyle::on_fill_invert : &SelectedStyle::on_stroke_invert ));
197 _popup_white[i].add(*(new Gtk::Label(_("White"), 0.0, 0.5)));
198 _popup_white[i].signal_activate().connect(sigc::mem_fun(*this,
199 (i == SS_FILL)? &SelectedStyle::on_fill_white : &SelectedStyle::on_stroke_white ));
201 _popup_black[i].add(*(new Gtk::Label(_("Black"), 0.0, 0.5)));
202 _popup_black[i].signal_activate().connect(sigc::mem_fun(*this,
203 (i == SS_FILL)? &SelectedStyle::on_fill_black : &SelectedStyle::on_stroke_black ));
205 _popup_copy[i].add(*(new Gtk::Label(_("Copy color"), 0.0, 0.5)));
206 _popup_copy[i].signal_activate().connect(sigc::mem_fun(*this,
207 (i == SS_FILL)? &SelectedStyle::on_fill_copy : &SelectedStyle::on_stroke_copy ));
209 _popup_paste[i].add(*(new Gtk::Label(_("Paste color"), 0.0, 0.5)));
210 _popup_paste[i].signal_activate().connect(sigc::mem_fun(*this,
211 (i == SS_FILL)? &SelectedStyle::on_fill_paste : &SelectedStyle::on_stroke_paste ));
213 _popup_swap[i].add(*(new Gtk::Label(_("Swap fill and stroke"), 0.0, 0.5)));
214 _popup_swap[i].signal_activate().connect(sigc::mem_fun(*this,
215 &SelectedStyle::on_fillstroke_swap));
217 _popup_opaque[i].add(*(new Gtk::Label((i == SS_FILL)? _("Make fill opaque") : _("Make stroke opaque"), 0.0, 0.5)));
218 _popup_opaque[i].signal_activate().connect(sigc::mem_fun(*this,
219 (i == SS_FILL)? &SelectedStyle::on_fill_opaque : &SelectedStyle::on_stroke_opaque ));
221 //TRANSLATORS COMMENT: unset is a verb here
222 _popup_unset[i].add(*(new Gtk::Label((i == SS_FILL)? _("Unset fill") : _("Unset stroke"), 0.0, 0.5)));
223 _popup_unset[i].signal_activate().connect(sigc::mem_fun(*this,
224 (i == SS_FILL)? &SelectedStyle::on_fill_unset : &SelectedStyle::on_stroke_unset ));
226 _popup_remove[i].add(*(new Gtk::Label((i == SS_FILL)? _("Remove fill") : _("Remove stroke"), 0.0, 0.5)));
227 _popup_remove[i].signal_activate().connect(sigc::mem_fun(*this,
228 (i == SS_FILL)? &SelectedStyle::on_fill_remove : &SelectedStyle::on_stroke_remove ));
230 _popup[i].attach(_popup_edit[i], 0,1, 0,1);
231 _popup[i].attach(*(new Gtk::SeparatorMenuItem()), 0,1, 1,2);
232 _popup[i].attach(_popup_lastused[i], 0,1, 2,3);
233 _popup[i].attach(_popup_lastselected[i], 0,1, 3,4);
234 _popup[i].attach(*(new Gtk::SeparatorMenuItem()), 0,1, 4,5);
235 _popup[i].attach(_popup_invert[i], 0,1, 5,6);
236 _popup[i].attach(*(new Gtk::SeparatorMenuItem()), 0,1, 6,7);
237 _popup[i].attach(_popup_white[i], 0,1, 7,8);
238 _popup[i].attach(_popup_black[i], 0,1, 8,9);
239 _popup[i].attach(*(new Gtk::SeparatorMenuItem()), 0,1, 9,10);
240 _popup[i].attach(_popup_copy[i], 0,1, 10,11);
241 _popup_copy[i].set_sensitive(false);
242 _popup[i].attach(_popup_paste[i], 0,1, 11,12);
243 _popup[i].attach(_popup_swap[i], 0,1, 12,13);
244 _popup[i].attach(*(new Gtk::SeparatorMenuItem()), 0,1, 13,14);
245 _popup[i].attach(_popup_opaque[i], 0,1, 14,15);
246 _popup[i].attach(_popup_unset[i], 0,1, 15,16);
247 _popup[i].attach(_popup_remove[i], 0,1, 16,17);
248 _popup[i].show_all();
250 _mode[i] = SS_NA;
251 }
253 {
254 _popup_px.add(*(new Gtk::Label(_("px"), 0.0, 0.5)));
255 _popup_px.signal_activate().connect(sigc::mem_fun(*this, &SelectedStyle::on_popup_px));
256 _popup_sw.attach(_popup_px, 0,1, 0,1);
258 _popup_pt.add(*(new Gtk::Label(_("pt"), 0.0, 0.5)));
259 _popup_pt.signal_activate().connect(sigc::mem_fun(*this, &SelectedStyle::on_popup_pt));
260 _popup_sw.attach(_popup_pt, 0,1, 1,2);
262 _popup_mm.add(*(new Gtk::Label(_("mm"), 0.0, 0.5)));
263 _popup_mm.signal_activate().connect(sigc::mem_fun(*this, &SelectedStyle::on_popup_mm));
264 _popup_sw.attach(_popup_mm, 0,1, 2,3);
266 _popup_sw.attach(*(new Gtk::SeparatorMenuItem()), 0,1, 3,4);
268 for (guint i = 0; i < G_N_ELEMENTS(_sw_presets_str); ++i) {
269 Gtk::MenuItem *mi = Gtk::manage(new Gtk::MenuItem());
270 mi->add(*(new Gtk::Label(_sw_presets_str[i], 0.0, 0.5)));
271 mi->signal_activate().connect(sigc::bind<int>(sigc::mem_fun(*this, &SelectedStyle::on_popup_preset), i));
272 _popup_sw.attach(*mi, 0,1, 4+i, 5+i);
273 }
275 guint i = G_N_ELEMENTS(_sw_presets_str) + 5;
277 _popup_sw.attach(*(new Gtk::SeparatorMenuItem()), 0,1, i,i+1);
279 _popup_sw_remove.add(*(new Gtk::Label(_("Remove"), 0.0, 0.5)));
280 _popup_sw_remove.signal_activate().connect(sigc::mem_fun(*this, &SelectedStyle::on_stroke_remove));
281 _popup_sw.attach(_popup_sw_remove, 0,1, i+1,i+2);
283 _popup_sw.show_all();
284 }
286 _fill_place.signal_button_press_event().connect(sigc::mem_fun(*this, &SelectedStyle::on_fill_click));
287 _stroke_place.signal_button_press_event().connect(sigc::mem_fun(*this, &SelectedStyle::on_stroke_click));
288 _opacity_place.signal_button_press_event().connect(sigc::mem_fun(*this, &SelectedStyle::on_opacity_click));
289 _stroke_width_place.signal_button_press_event().connect(sigc::mem_fun(*this, &SelectedStyle::on_sw_click));
291 _opacity_sb.signal_populate_popup().connect(sigc::mem_fun(*this, &SelectedStyle::on_opacity_menu));
292 _opacity_sb.signal_value_changed().connect(sigc::mem_fun(*this, &SelectedStyle::on_opacity_changed));
294 _fill_place.add(_na[SS_FILL]);
295 _tooltips.set_tip(_fill_place, __na[SS_FILL]);
297 _stroke_place.add(_na[SS_STROKE]);
298 _tooltips.set_tip(_stroke_place, __na[SS_STROKE]);
300 _stroke.pack_start(_stroke_place);
301 _stroke_width_place.add(_stroke_width);
302 _stroke.pack_start(_stroke_width_place, Gtk::PACK_SHRINK);
304 _opacity_sb.set_adjustment(_opacity_adjustment);
305 sp_set_font_size_smaller (GTK_WIDGET(_opacity_sb.gobj()));
306 _opacity_sb.set_size_request (SELECTED_STYLE_SB_WIDTH, -1);
307 _opacity_sb.set_sensitive (false);
309 _table.attach(_fill_label, 0,1, 0,1, Gtk::SHRINK, Gtk::SHRINK);
310 _table.attach(_stroke_label, 0,1, 1,2, Gtk::SHRINK, Gtk::SHRINK);
312 _table.attach(_fill_flag_place, 1,2, 0,1, Gtk::SHRINK, Gtk::SHRINK);
313 _table.attach(_stroke_flag_place, 1,2, 1,2, Gtk::SHRINK, Gtk::SHRINK);
315 _table.attach(_fill_place, 2,3, 0,1);
316 _table.attach(_stroke, 2,3, 1,2);
318 _opacity_place.add(_opacity_label);
319 _table.attach(_opacity_place, 4,5, 0,2, Gtk::SHRINK, Gtk::SHRINK);
320 _table.attach(_opacity_sb, 5,6, 0,2, Gtk::SHRINK, Gtk::SHRINK);
322 pack_start(_table, true, true, 2);
324 set_size_request (SELECTED_STYLE_WIDTH, -1);
326 sp_set_font_size_smaller (GTK_WIDGET(_opacity_label.gobj()));
327 sp_set_font_size_smaller (GTK_WIDGET(_opacity_sb.gobj()));
328 sp_set_font_size_smaller (GTK_WIDGET(_fill_place.gobj()));
329 sp_set_font_size_smaller (GTK_WIDGET(_fill_flag_place.gobj()));
330 sp_set_font_size_smaller (GTK_WIDGET(_stroke_place.gobj()));
331 sp_set_font_size_smaller (GTK_WIDGET(_stroke_flag_place.gobj()));
332 sp_set_font_size_smaller (GTK_WIDGET(_stroke_width.gobj()));
333 sp_set_font_size_smaller (GTK_WIDGET(_fill_label.gobj()));
334 sp_set_font_size_smaller (GTK_WIDGET(_stroke_label.gobj()));
336 _drop[SS_FILL] = new DropTracker();
337 ((DropTracker*)_drop[SS_FILL])->parent = this;
338 ((DropTracker*)_drop[SS_FILL])->item = SS_FILL;
340 _drop[SS_STROKE] = new DropTracker();
341 ((DropTracker*)_drop[SS_STROKE])->parent = this;
342 ((DropTracker*)_drop[SS_STROKE])->item = SS_STROKE;
344 g_signal_connect(_stroke_place.gobj(),
345 "drag_data_received",
346 G_CALLBACK(dragDataReceived),
347 _drop[SS_STROKE]);
349 g_signal_connect(_fill_place.gobj(),
350 "drag_data_received",
351 G_CALLBACK(dragDataReceived),
352 _drop[SS_FILL]);
353 }
355 SelectedStyle::~SelectedStyle()
356 {
357 selection_changed_connection->disconnect();
358 delete selection_changed_connection;
359 selection_modified_connection->disconnect();
360 delete selection_modified_connection;
361 subselection_changed_connection->disconnect();
362 delete subselection_changed_connection;
364 for (int i = SS_FILL; i <= SS_STROKE; i++) {
365 delete _color_preview[i];
366 }
368 delete (DropTracker*)_drop[SS_FILL];
369 delete (DropTracker*)_drop[SS_STROKE];
370 }
372 void
373 SelectedStyle::setDesktop(SPDesktop *desktop)
374 {
375 _desktop = desktop;
376 gtk_object_set_data (GTK_OBJECT(_opacity_sb.gobj()), "dtw", _desktop->canvas);
378 Inkscape::Selection *selection = sp_desktop_selection (desktop);
380 selection_changed_connection = new sigc::connection (selection->connectChanged(
381 sigc::bind (
382 sigc::ptr_fun(&ss_selection_changed),
383 this )
384 ));
385 selection_modified_connection = new sigc::connection (selection->connectModified(
386 sigc::bind (
387 sigc::ptr_fun(&ss_selection_modified),
388 this )
389 ));
390 subselection_changed_connection = new sigc::connection (desktop->connectToolSubselectionChanged(
391 sigc::bind (
392 sigc::ptr_fun(&ss_subselection_changed),
393 this )
394 ));
396 //_sw_unit = (SPUnit *) sp_desktop_namedview(desktop)->doc_units;
397 }
399 void SelectedStyle::dragDataReceived( GtkWidget *widget,
400 GdkDragContext *drag_context,
401 gint x, gint y,
402 GtkSelectionData *data,
403 guint info,
404 guint event_time,
405 gpointer user_data )
406 {
407 DropTracker* tracker = (DropTracker*)user_data;
409 switch ( (int)tracker->item ) {
410 case SS_FILL:
411 case SS_STROKE:
412 {
413 if ( data->length == 8 ) {
414 gchar c[64];
415 // Careful about endian issues.
416 guint16* dataVals = (guint16*)data->data;
417 sp_svg_write_color( c, 64,
418 SP_RGBA32_U_COMPOSE(
419 0x0ff & (dataVals[0] >> 8),
420 0x0ff & (dataVals[1] >> 8),
421 0x0ff & (dataVals[2] >> 8),
422 0xff // can't have transparency in the color itself
423 //0x0ff & (data->data[3] >> 8),
424 ));
425 SPCSSAttr *css = sp_repr_css_attr_new();
426 sp_repr_css_set_property( css, (tracker->item == SS_FILL) ? "fill":"stroke", c );
427 sp_desktop_set_style( tracker->parent->_desktop, css );
428 sp_repr_css_attr_unref( css );
429 sp_document_done( sp_desktop_document(tracker->parent->_desktop) , SP_VERB_NONE,
430 /* TODO: annotate */ "selected-style.cpp:429");
431 }
432 }
433 break;
434 }
435 }
437 void SelectedStyle::on_fill_remove() {
438 SPCSSAttr *css = sp_repr_css_attr_new ();
439 sp_repr_css_set_property (css, "fill", "none");
440 sp_desktop_set_style (_desktop, css, true, true);
441 sp_repr_css_attr_unref (css);
442 sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE,
443 /* TODO: annotate */ "selected-style.cpp:442");
444 }
446 void SelectedStyle::on_stroke_remove() {
447 SPCSSAttr *css = sp_repr_css_attr_new ();
448 sp_repr_css_set_property (css, "stroke", "none");
449 sp_desktop_set_style (_desktop, css, true, true);
450 sp_repr_css_attr_unref (css);
451 sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE,
452 /* TODO: annotate */ "selected-style.cpp:451");
453 }
455 void SelectedStyle::on_fill_unset() {
456 SPCSSAttr *css = sp_repr_css_attr_new ();
457 sp_repr_css_unset_property (css, "fill");
458 sp_desktop_set_style (_desktop, css, true, true);
459 sp_repr_css_attr_unref (css);
460 sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE,
461 /* TODO: annotate */ "selected-style.cpp:460");
462 }
464 void SelectedStyle::on_stroke_unset() {
465 SPCSSAttr *css = sp_repr_css_attr_new ();
466 sp_repr_css_unset_property (css, "stroke");
467 sp_desktop_set_style (_desktop, css, true, true);
468 sp_repr_css_attr_unref (css);
469 sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE,
470 /* TODO: annotate */ "selected-style.cpp:469");
471 }
473 void SelectedStyle::on_fill_opaque() {
474 SPCSSAttr *css = sp_repr_css_attr_new ();
475 sp_repr_css_set_property (css, "fill-opacity", "1");
476 sp_desktop_set_style (_desktop, css, true);
477 sp_repr_css_attr_unref (css);
478 sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE,
479 /* TODO: annotate */ "selected-style.cpp:478");
480 }
482 void SelectedStyle::on_stroke_opaque() {
483 SPCSSAttr *css = sp_repr_css_attr_new ();
484 sp_repr_css_set_property (css, "stroke-opacity", "1");
485 sp_desktop_set_style (_desktop, css, true);
486 sp_repr_css_attr_unref (css);
487 sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE,
488 /* TODO: annotate */ "selected-style.cpp:487");
489 }
491 void SelectedStyle::on_fill_lastused() {
492 SPCSSAttr *css = sp_repr_css_attr_new ();
493 guint32 color = sp_desktop_get_color(_desktop, true);
494 gchar c[64];
495 sp_svg_write_color (c, 64, color);
496 sp_repr_css_set_property (css, "fill", c);
497 sp_desktop_set_style (_desktop, css);
498 sp_repr_css_attr_unref (css);
499 sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE,
500 /* TODO: annotate */ "selected-style.cpp:499");
501 }
503 void SelectedStyle::on_stroke_lastused() {
504 SPCSSAttr *css = sp_repr_css_attr_new ();
505 guint32 color = sp_desktop_get_color(_desktop, false);
506 gchar c[64];
507 sp_svg_write_color (c, 64, color);
508 sp_repr_css_set_property (css, "stroke", c);
509 sp_desktop_set_style (_desktop, css);
510 sp_repr_css_attr_unref (css);
511 sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE,
512 /* TODO: annotate */ "selected-style.cpp:511");
513 }
515 void SelectedStyle::on_fill_lastselected() {
516 SPCSSAttr *css = sp_repr_css_attr_new ();
517 gchar c[64];
518 sp_svg_write_color (c, 64, _lastselected[SS_FILL]);
519 sp_repr_css_set_property (css, "fill", c);
520 sp_desktop_set_style (_desktop, css);
521 sp_repr_css_attr_unref (css);
522 sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE,
523 /* TODO: annotate */ "selected-style.cpp:522");
524 }
526 void SelectedStyle::on_stroke_lastselected() {
527 SPCSSAttr *css = sp_repr_css_attr_new ();
528 gchar c[64];
529 sp_svg_write_color (c, 64, _lastselected[SS_STROKE]);
530 sp_repr_css_set_property (css, "stroke", c);
531 sp_desktop_set_style (_desktop, css);
532 sp_repr_css_attr_unref (css);
533 sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE,
534 /* TODO: annotate */ "selected-style.cpp:533");
535 }
537 void SelectedStyle::on_fill_invert() {
538 SPCSSAttr *css = sp_repr_css_attr_new ();
539 guint32 color = _thisselected[SS_FILL];
540 gchar c[64];
541 if (_mode[SS_FILL] != SS_COLOR) return;
542 sp_svg_write_color (c, 64,
543 SP_RGBA32_U_COMPOSE(
544 (255 - SP_RGBA32_R_U(color)),
545 (255 - SP_RGBA32_G_U(color)),
546 (255 - SP_RGBA32_B_U(color)),
547 SP_RGBA32_A_U(color)
548 )
549 );
550 sp_repr_css_set_property (css, "fill", c);
551 sp_desktop_set_style (_desktop, css);
552 sp_repr_css_attr_unref (css);
553 sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE,
554 /* TODO: annotate */ "selected-style.cpp:553");
555 }
557 void SelectedStyle::on_stroke_invert() {
558 SPCSSAttr *css = sp_repr_css_attr_new ();
559 guint32 color = _thisselected[SS_STROKE];
560 gchar c[64];
561 if (_mode[SS_STROKE] != SS_COLOR) return;
562 sp_svg_write_color (c, 64,
563 SP_RGBA32_U_COMPOSE(
564 (255 - SP_RGBA32_R_U(color)),
565 (255 - SP_RGBA32_G_U(color)),
566 (255 - SP_RGBA32_B_U(color)),
567 SP_RGBA32_A_U(color)
568 )
569 );
570 sp_repr_css_set_property (css, "stroke", c);
571 sp_desktop_set_style (_desktop, css);
572 sp_repr_css_attr_unref (css);
573 sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE,
574 /* TODO: annotate */ "selected-style.cpp:573");
575 }
577 void SelectedStyle::on_fill_white() {
578 SPCSSAttr *css = sp_repr_css_attr_new ();
579 gchar c[64];
580 sp_svg_write_color (c, 64, 0xffffffff);
581 sp_repr_css_set_property (css, "fill", c);
582 sp_repr_css_set_property (css, "fill-opacity", "1");
583 sp_desktop_set_style (_desktop, css);
584 sp_repr_css_attr_unref (css);
585 sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE,
586 /* TODO: annotate */ "selected-style.cpp:585");
587 }
589 void SelectedStyle::on_stroke_white() {
590 SPCSSAttr *css = sp_repr_css_attr_new ();
591 gchar c[64];
592 sp_svg_write_color (c, 64, 0xffffffff);
593 sp_repr_css_set_property (css, "stroke", c);
594 sp_repr_css_set_property (css, "stroke-opacity", "1");
595 sp_desktop_set_style (_desktop, css);
596 sp_repr_css_attr_unref (css);
597 sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE,
598 /* TODO: annotate */ "selected-style.cpp:597");
599 }
601 void SelectedStyle::on_fill_black() {
602 SPCSSAttr *css = sp_repr_css_attr_new ();
603 gchar c[64];
604 sp_svg_write_color (c, 64, 0x000000ff);
605 sp_repr_css_set_property (css, "fill", c);
606 sp_repr_css_set_property (css, "fill-opacity", "1.0");
607 sp_desktop_set_style (_desktop, css);
608 sp_repr_css_attr_unref (css);
609 sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE,
610 /* TODO: annotate */ "selected-style.cpp:609");
611 }
613 void SelectedStyle::on_stroke_black() {
614 SPCSSAttr *css = sp_repr_css_attr_new ();
615 gchar c[64];
616 sp_svg_write_color (c, 64, 0x000000ff);
617 sp_repr_css_set_property (css, "stroke", c);
618 sp_repr_css_set_property (css, "stroke-opacity", "1.0");
619 sp_desktop_set_style (_desktop, css);
620 sp_repr_css_attr_unref (css);
621 sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE,
622 /* TODO: annotate */ "selected-style.cpp:621");
623 }
625 void SelectedStyle::on_fill_copy() {
626 if (_mode[SS_FILL] == SS_COLOR) {
627 gchar c[64];
628 sp_svg_write_color (c, 64, _thisselected[SS_FILL]);
629 Glib::ustring text;
630 text += c;
631 if (!text.empty()) {
632 Glib::RefPtr<Gtk::Clipboard> refClipboard = Gtk::Clipboard::get();
633 refClipboard->set_text(text);
634 }
635 }
636 }
638 void SelectedStyle::on_stroke_copy() {
639 if (_mode[SS_STROKE] == SS_COLOR) {
640 gchar c[64];
641 sp_svg_write_color (c, 64, _thisselected[SS_STROKE]);
642 Glib::ustring text;
643 text += c;
644 if (!text.empty()) {
645 Glib::RefPtr<Gtk::Clipboard> refClipboard = Gtk::Clipboard::get();
646 refClipboard->set_text(text);
647 }
648 }
649 }
651 void SelectedStyle::on_fill_paste() {
652 Glib::RefPtr<Gtk::Clipboard> refClipboard = Gtk::Clipboard::get();
653 Glib::ustring const text = refClipboard->wait_for_text();
655 if (!text.empty()) {
656 guint32 color = sp_svg_read_color(text.c_str(), 0x000000ff); // impossible value, as SVG color cannot have opacity
657 if (color == 0x000000ff) // failed to parse color string
658 return;
660 SPCSSAttr *css = sp_repr_css_attr_new ();
661 sp_repr_css_set_property (css, "fill", text.c_str());
662 sp_desktop_set_style (_desktop, css);
663 sp_repr_css_attr_unref (css);
664 sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE,
665 /* TODO: annotate */ "selected-style.cpp:664");
666 }
667 }
669 void SelectedStyle::on_stroke_paste() {
670 Glib::RefPtr<Gtk::Clipboard> refClipboard = Gtk::Clipboard::get();
671 Glib::ustring const text = refClipboard->wait_for_text();
673 if (!text.empty()) {
674 guint32 color = sp_svg_read_color(text.c_str(), 0x000000ff); // impossible value, as SVG color cannot have opacity
675 if (color == 0x000000ff) // failed to parse color string
676 return;
678 SPCSSAttr *css = sp_repr_css_attr_new ();
679 sp_repr_css_set_property (css, "stroke", text.c_str());
680 sp_desktop_set_style (_desktop, css);
681 sp_repr_css_attr_unref (css);
682 sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE,
683 /* TODO: annotate */ "selected-style.cpp:682");
684 }
685 }
687 void SelectedStyle::on_fillstroke_swap() {
688 SPCSSAttr *css = sp_repr_css_attr_new ();
690 g_message("on_fillstroke_swap()");
692 switch (_mode[SS_FILL]) {
693 case SS_NA:
694 case SS_MANY:
695 break;
696 case SS_NONE:
697 sp_repr_css_set_property (css, "stroke", "none");
698 break;
699 case SS_UNSET:
700 sp_repr_css_unset_property (css, "stroke");
701 break;
702 case SS_COLOR:
703 gchar c[64];
704 sp_svg_write_color (c, 64, _thisselected[SS_FILL]);
705 sp_repr_css_set_property (css, "stroke", c);
706 break;
707 case SS_LGRADIENT:
708 case SS_RGRADIENT:
709 case SS_PATTERN:
710 sp_repr_css_set_property (css, "stroke", _paintserver_id[SS_FILL].c_str());
711 break;
712 }
714 switch (_mode[SS_STROKE]) {
715 case SS_NA:
716 case SS_MANY:
717 break;
718 case SS_NONE:
719 sp_repr_css_set_property (css, "fill", "none");
720 break;
721 case SS_UNSET:
722 sp_repr_css_unset_property (css, "fill");
723 break;
724 case SS_COLOR:
725 gchar c[64];
726 sp_svg_write_color (c, 64, _thisselected[SS_STROKE]);
727 sp_repr_css_set_property (css, "fill", c);
728 break;
729 case SS_LGRADIENT:
730 case SS_RGRADIENT:
731 case SS_PATTERN:
732 sp_repr_css_set_property (css, "fill", _paintserver_id[SS_STROKE].c_str());
733 break;
734 }
736 sp_desktop_set_style (_desktop, css);
737 sp_repr_css_attr_unref (css);
738 sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE,
739 /* TODO: annotate */ "selected-style.cpp:738");
740 }
742 void SelectedStyle::on_fill_edit() {
743 sp_object_properties_fill();
744 }
746 void SelectedStyle::on_stroke_edit() {
747 sp_object_properties_stroke();
748 }
750 bool
751 SelectedStyle::on_fill_click(GdkEventButton *event)
752 {
753 if (event->button == 1) { // click, open fill&stroke
754 sp_object_properties_fill();
755 } else if (event->button == 3) { // right-click, popup menu
756 _popup[SS_FILL].popup(event->button, event->time);
757 } else if (event->button == 2) { // middle click, toggle none/lastcolor
758 if (_mode[SS_FILL] == SS_NONE) {
759 on_fill_lastused();
760 } else {
761 on_fill_remove();
762 }
763 }
764 return true;
765 }
767 bool
768 SelectedStyle::on_stroke_click(GdkEventButton *event)
769 {
770 if (event->button == 1) { // click, open fill&stroke
771 sp_object_properties_stroke();
772 } else if (event->button == 3) { // right-click, popup menu
773 _popup[SS_STROKE].popup(event->button, event->time);
774 } else if (event->button == 2) { // middle click, toggle none/lastcolor
775 if (_mode[SS_STROKE] == SS_NONE) {
776 on_stroke_lastused();
777 } else {
778 on_stroke_remove();
779 }
780 }
781 return true;
782 }
784 bool
785 SelectedStyle::on_sw_click(GdkEventButton *event)
786 {
787 if (event->button == 1) { // click, open fill&stroke
788 sp_object_properties_stroke_style ();
789 } else if (event->button == 3) { // right-click, popup menu
790 _popup_sw.popup(event->button, event->time);
791 } else if (event->button == 2) { // middle click, toggle none/lastwidth?
792 //
793 }
794 return true;
795 }
797 bool
798 SelectedStyle::on_opacity_click(GdkEventButton *event)
799 {
800 if (event->button == 2) { // middle click
801 const char* opacity = _opacity_sb.get_value() < 0.5? "0.5" : (_opacity_sb.get_value() == 1? "0" : "1");
802 SPCSSAttr *css = sp_repr_css_attr_new ();
803 sp_repr_css_set_property (css, "opacity", opacity);
804 sp_desktop_set_style (_desktop, css);
805 sp_repr_css_attr_unref (css);
806 sp_document_done (sp_desktop_document (_desktop), SP_VERB_DIALOG_FILL_STROKE,
807 /* TODO: annotate */ "selected-style.cpp:806");
808 return true;
809 }
811 return false;
812 }
814 void SelectedStyle::on_popup_px() {
815 _sw_unit = (SPUnit *) &(sp_unit_get_by_id(SP_UNIT_PX));
816 update();
817 }
818 void SelectedStyle::on_popup_pt() {
819 _sw_unit = (SPUnit *) &(sp_unit_get_by_id(SP_UNIT_PT));
820 update();
821 }
822 void SelectedStyle::on_popup_mm() {
823 _sw_unit = (SPUnit *) &(sp_unit_get_by_id(SP_UNIT_MM));
824 update();
825 }
827 void SelectedStyle::on_popup_preset(int i) {
828 SPCSSAttr *css = sp_repr_css_attr_new ();
829 gdouble w;
830 if (_sw_unit) {
831 w = sp_units_get_pixels (_sw_presets[i], *_sw_unit);
832 } else {
833 w = _sw_presets[i];
834 }
835 Inkscape::CSSOStringStream os;
836 os << w;
837 sp_repr_css_set_property (css, "stroke-width", os.str().c_str());
838 sp_desktop_set_style (_desktop, css, true);
839 sp_repr_css_attr_unref (css);
840 sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_SWATCHES,
841 /* TODO: annotate */ "selected-style.cpp:840");
842 }
844 void
845 SelectedStyle::update()
846 {
847 if (_desktop == NULL)
848 return;
850 // create temporary style
851 SPStyle *query = sp_style_new ();
853 for (int i = SS_FILL; i <= SS_STROKE; i++) {
854 Gtk::EventBox *place = (i == SS_FILL)? &_fill_place : &_stroke_place;
855 Gtk::EventBox *flag_place = (i == SS_FILL)? &_fill_flag_place : &_stroke_flag_place;
857 place->remove();
858 flag_place->remove();
860 _tooltips.unset_tip(*place);
861 _tooltips.unset_tip(*flag_place);
863 _mode[i] = SS_NA;
864 _paintserver_id[i].clear();
866 _popup_copy[i].set_sensitive(false);
868 // query style from desktop. This returns a result flag and fills query with the style of subselection, if any, or selection
869 int result = sp_desktop_query_style (_desktop, query,
870 (i == SS_FILL)? QUERY_STYLE_PROPERTY_FILL : QUERY_STYLE_PROPERTY_STROKE);
871 switch (result) {
872 case QUERY_STYLE_NOTHING:
873 place->add(_na[i]);
874 _tooltips.set_tip(*place, __na[i]);
875 _mode[i] = SS_NA;
876 if ( _dropEnabled[i] ) {
877 gtk_drag_dest_unset( GTK_WIDGET((i==SS_FILL) ? _fill_place.gobj():_stroke_place.gobj()) );
878 _dropEnabled[i] = false;
879 }
880 break;
881 case QUERY_STYLE_SINGLE:
882 case QUERY_STYLE_MULTIPLE_AVERAGED:
883 case QUERY_STYLE_MULTIPLE_SAME:
884 if ( !_dropEnabled[i] ) {
885 gtk_drag_dest_set( GTK_WIDGET( (i==SS_FILL) ? _fill_place.gobj():_stroke_place.gobj()),
886 GTK_DEST_DEFAULT_ALL,
887 ui_drop_target_entries,
888 nui_drop_target_entries,
889 GdkDragAction(GDK_ACTION_COPY | GDK_ACTION_MOVE) );
890 _dropEnabled[i] = true;
891 }
892 SPIPaint *paint;
893 if (i == SS_FILL) {
894 paint = &(query->fill);
895 } else {
896 paint = &(query->stroke);
897 }
898 if (paint->set && paint->type == SP_PAINT_TYPE_COLOR) {
899 guint32 color = sp_color_get_rgba32_falpha (&(paint->value.color),
900 SP_SCALE24_TO_FLOAT ((i == SS_FILL)? query->fill_opacity.value : query->stroke_opacity.value));
901 _lastselected[i] = _thisselected[i];
902 _thisselected[i] = color | 0xff; // only color, opacity === 1
903 ((Inkscape::UI::Widget::ColorPreview*)_color_preview[i])->setRgba32 (color);
904 _color_preview[i]->show_all();
905 place->add(*_color_preview[i]);
906 gchar c_string[64];
907 g_snprintf (c_string, 64, "%06x/%.3g", color >> 8, SP_RGBA32_A_F(color));
908 _tooltips.set_tip(*place, __color[i] + ": " + c_string);
909 _mode[i] = SS_COLOR;
910 _popup_copy[i].set_sensitive(true);
912 } else if (paint->set && paint->type == SP_PAINT_TYPE_PAINTSERVER) {
913 SPPaintServer *server = (i == SS_FILL)? SP_STYLE_FILL_SERVER (query) : SP_STYLE_STROKE_SERVER (query);
914 if ( server ) {
915 Inkscape::XML::Node *srepr = SP_OBJECT_REPR(server);
916 _paintserver_id[i] += "url(#";
917 _paintserver_id[i] += srepr->attribute("id");
918 _paintserver_id[i] += ")";
920 if (SP_IS_LINEARGRADIENT (server)) {
921 place->add(_lgradient[i]);
922 _tooltips.set_tip(*place, __lgradient[i]);
923 _mode[i] = SS_LGRADIENT;
924 } else if (SP_IS_RADIALGRADIENT (server)) {
925 place->add(_rgradient[i]);
926 _tooltips.set_tip(*place, __rgradient[i]);
927 _mode[i] = SS_RGRADIENT;
928 } else if (SP_IS_PATTERN (server)) {
929 place->add(_pattern[i]);
930 _tooltips.set_tip(*place, __pattern[i]);
931 _mode[i] = SS_PATTERN;
932 }
933 } else {
934 g_warning ("file %s: line %d: Unknown paint server", __FILE__, __LINE__);
935 }
937 } else if (paint->set && paint->type == SP_PAINT_TYPE_NONE) {
938 place->add(_none[i]);
939 _tooltips.set_tip(*place, __none[i]);
940 _mode[i] = SS_NONE;
941 } else if (!paint->set) {
942 place->add(_unset[i]);
943 _tooltips.set_tip(*place, __unset[i]);
944 _mode[i] = SS_UNSET;
945 }
946 if (result == QUERY_STYLE_MULTIPLE_AVERAGED) {
947 flag_place->add(_averaged[i]);
948 _tooltips.set_tip(*flag_place, __averaged[i]);
949 } else if (result == QUERY_STYLE_MULTIPLE_SAME) {
950 flag_place->add(_multiple[i]);
951 _tooltips.set_tip(*flag_place, __multiple[i]);
952 }
953 break;
954 case QUERY_STYLE_MULTIPLE_DIFFERENT:
955 place->add(_many[i]);
956 _tooltips.set_tip(*place, __many[i]);
957 _mode[i] = SS_MANY;
958 break;
959 default:
960 break;
961 }
962 }
964 // Now query opacity
965 _tooltips.unset_tip(_opacity_place);
967 int result = sp_desktop_query_style (_desktop, query, QUERY_STYLE_PROPERTY_MASTEROPACITY);
969 switch (result) {
970 case QUERY_STYLE_NOTHING:
971 _tooltips.set_tip(_opacity_place, _("Nothing selected"));
972 _opacity_sb.set_sensitive(false);
973 break;
974 case QUERY_STYLE_SINGLE:
975 case QUERY_STYLE_MULTIPLE_AVERAGED:
976 case QUERY_STYLE_MULTIPLE_SAME:
977 _tooltips.set_tip(_opacity_place, _("Master opacity"));
978 _opacity_blocked = true;
979 _opacity_sb.set_sensitive(true);
980 _opacity_adjustment.set_value(SP_SCALE24_TO_FLOAT(query->opacity.value));
981 _opacity_blocked = false;
982 break;
983 }
985 // Now query stroke_width
986 int result_sw = sp_desktop_query_style (_desktop, query, QUERY_STYLE_PROPERTY_STROKEWIDTH);
987 switch (result_sw) {
988 case QUERY_STYLE_NOTHING:
989 _stroke_width.set_markup("");
990 break;
991 case QUERY_STYLE_SINGLE:
992 case QUERY_STYLE_MULTIPLE_AVERAGED:
993 case QUERY_STYLE_MULTIPLE_SAME:
994 {
995 double w;
996 if (_sw_unit) {
997 w = sp_pixels_get_units(query->stroke_width.computed, *_sw_unit);
998 } else {
999 w = query->stroke_width.computed;
1000 }
1001 {
1002 gchar *str = g_strdup_printf(" %.3g", w);
1003 _stroke_width.set_markup(str);
1004 g_free (str);
1005 }
1006 {
1007 gchar *str = g_strdup_printf(_("Stroke width: %.5g%s%s"),
1008 w,
1009 _sw_unit? sp_unit_get_abbreviation(_sw_unit) : "px",
1010 (result_sw == QUERY_STYLE_MULTIPLE_AVERAGED)?
1011 _(" (averaged)") : "");
1012 _tooltips.set_tip(_stroke_width_place, str);
1013 g_free (str);
1014 }
1015 break;
1016 }
1017 default:
1018 break;
1019 }
1021 g_free (query);
1022 }
1024 void SelectedStyle::opacity_0(void) {_opacity_sb.set_value(0);}
1025 void SelectedStyle::opacity_025(void) {_opacity_sb.set_value(0.25);}
1026 void SelectedStyle::opacity_05(void) {_opacity_sb.set_value(0.5);}
1027 void SelectedStyle::opacity_075(void) {_opacity_sb.set_value(0.75);}
1028 void SelectedStyle::opacity_1(void) {_opacity_sb.set_value(1.0);}
1030 void SelectedStyle::on_opacity_menu (Gtk::Menu *menu) {
1032 Glib::ListHandle<Gtk::Widget *> children = menu->get_children();
1033 for (Glib::ListHandle<Gtk::Widget *>::iterator iter = children.begin(); iter != children.end(); iter++) {
1034 menu->remove(*(*iter));
1035 }
1037 {
1038 Gtk::MenuItem *item = new Gtk::MenuItem;
1039 item->add(*(new Gtk::Label(_("0 (transparent)"), 0, 0)));
1040 item->signal_activate().connect(sigc::mem_fun(*this, &SelectedStyle::opacity_0 ));
1041 menu->add(*item);
1042 }
1043 {
1044 Gtk::MenuItem *item = new Gtk::MenuItem;
1045 item->add(*(new Gtk::Label("0.25", 0, 0)));
1046 item->signal_activate().connect(sigc::mem_fun(*this, &SelectedStyle::opacity_025 ));
1047 menu->add(*item);
1048 }
1049 {
1050 Gtk::MenuItem *item = new Gtk::MenuItem;
1051 item->add(*(new Gtk::Label("0.5", 0, 0)));
1052 item->signal_activate().connect(sigc::mem_fun(*this, &SelectedStyle::opacity_05 ));
1053 menu->add(*item);
1054 }
1055 {
1056 Gtk::MenuItem *item = new Gtk::MenuItem;
1057 item->add(*(new Gtk::Label("0.75", 0, 0)));
1058 item->signal_activate().connect(sigc::mem_fun(*this, &SelectedStyle::opacity_075 ));
1059 menu->add(*item);
1060 }
1061 {
1062 Gtk::MenuItem *item = new Gtk::MenuItem;
1063 item->add(*(new Gtk::Label(_("1.0 (opaque)"), 0, 0)));
1064 item->signal_activate().connect(sigc::mem_fun(*this, &SelectedStyle::opacity_1 ));
1065 menu->add(*item);
1066 }
1068 menu->show_all();
1069 }
1071 void SelectedStyle::on_opacity_changed () {
1072 if (_opacity_blocked)
1073 return;
1074 _opacity_blocked = true;
1075 SPCSSAttr *css = sp_repr_css_attr_new ();
1076 Inkscape::CSSOStringStream os;
1077 os << CLAMP (_opacity_adjustment.get_value(), 0.0, 1.0);
1078 sp_repr_css_set_property (css, "opacity", os.str().c_str());
1079 sp_desktop_set_style (_desktop, css);
1080 sp_repr_css_attr_unref (css);
1081 sp_document_maybe_done (sp_desktop_document (_desktop), "fillstroke:opacity", SP_VERB_DIALOG_FILL_STROKE,
1082 /* TODO: annotate */ "selected-style.cpp:1082");
1083 spinbutton_defocus(GTK_OBJECT(_opacity_sb.gobj()));
1084 _opacity_blocked = false;
1085 }
1087 } // namespace Widget
1088 } // namespace UI
1089 } // namespace Inkscape
1091 /*
1092 Local Variables:
1093 mode:c++
1094 c-file-style:"stroustrup"
1095 c-file-offsets:((innamespace . 0)(inline-open . 0))
1096 indent-tabs-mode:nil
1097 fill-column:99
1098 End:
1099 */
1100 // vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :