selected-style.cpp revision 4d79affe53b5c0e7dbc67014aee9be5251dc56df
/**
* \brief Selected style indicator (fill, stroke, opacity)
*
* Author:
* buliabyak@gmail.com
*
* Copyright (C) 2005 author
*
* Released under GNU GPL. Read the file 'COPYING' for more information.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "selected-style.h"
#include "widgets/spw-utilities.h"
#include "ui/widget/color-preview.h"
#include "selection.h"
#include "desktop-handles.h"
#include "style.h"
#include "desktop-style.h"
#include "sp-linear-gradient-fns.h"
#include "sp-radial-gradient-fns.h"
#include "sp-pattern.h"
#include "dialogs/object-properties.h"
#include "document.h"
#include "widgets/widget-sizes.h"
#include "widgets/spinbutton-events.h"
#include "widgets/gradient-image.h"
#include "sp-gradient.h"
#include "svg/svg-color.h"
#include "svg/css-ostringstream.h"
#include "verbs.h"
#include <display/sp-canvas.h>
static gdouble const _sw_presets[] = { 32 , 16 , 10 , 8 , 6 , 4 , 3 , 2 , 1.5 , 1 , 0.75 , 0.5 , 0.25 , 0.1 };
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"};
static void
{
}
static void
{
}
static void
{
}
namespace Inkscape {
namespace UI {
namespace Widget {
typedef struct {
int item;
} DropTracker;
/* Drag and Drop */
typedef enum {
static GtkTargetEntry ui_drop_target_entries [] = {
{"application/x-color", 0, APP_X_COLOR}
};
#define ENTRIES_SIZE(n) sizeof(n)/sizeof(n[0])
_fill_label (_("Fill:")),
_stroke_label (_("Stroke:")),
_opacity_label (_("O:")),
_fill_place (),
_stroke_place (),
_fill_flag_place (),
_opacity_place (),
_opacity_sb (0.02, 0),
_stroke (),
_stroke_width (""),
_opacity_blocked (false),
_tooltips ()
{
_fill_label.set_padding(0, 0);
_stroke_label.set_padding(0, 0);
_opacity_label.set_padding(0, 0);
_table.set_row_spacings (0);
__na[i] = (_("Nothing selected"));
_lgradient[i].show_all();
_gradient_box_l[i].show_all();
_rgradient[i].show_all();
_gradient_box_r[i].show_all();
// TRANSLATOR COMMENT: A means "Averaged"
__averaged[i] = (i == SS_FILL)? (_("Fill is averaged over selected objects")) : (_("Stroke is averaged over selected objects"));
// TRANSLATOR COMMENT: M means "Multiple"
__multiple[i] = (i == SS_FILL)? (_("Multiple selected objects have the same fill")) : (_("Multiple selected objects have the same stroke"));
_popup_edit[i].add(*(new Gtk::Label((i == SS_FILL)? _("Edit fill...") : _("Edit stroke..."), 0.0, 0.5)));
_popup_opaque[i].add(*(new Gtk::Label((i == SS_FILL)? _("Make fill opaque") : _("Make stroke opaque"), 0.0, 0.5)));
//TRANSLATORS COMMENT: unset is a verb here
_popup_unset[i].add(*(new Gtk::Label((i == SS_FILL)? _("Unset fill") : _("Unset stroke"), 0.0, 0.5)));
_popup_remove[i].add(*(new Gtk::Label((i == SS_FILL)? _("Remove fill") : _("Remove stroke"), 0.0, 0.5)));
_popup_copy[i].set_sensitive(false);
}
{
mi->signal_activate().connect(sigc::bind<int>(sigc::mem_fun(*this, &SelectedStyle::on_popup_preset), i));
}
}
_fill_place.signal_button_press_event().connect(sigc::mem_fun(*this, &SelectedStyle::on_fill_click));
_stroke_place.signal_button_press_event().connect(sigc::mem_fun(*this, &SelectedStyle::on_stroke_click));
_opacity_place.signal_button_press_event().connect(sigc::mem_fun(*this, &SelectedStyle::on_opacity_click));
_stroke_width_place.signal_button_press_event().connect(sigc::mem_fun(*this, &SelectedStyle::on_sw_click));
_opacity_sb.signal_value_changed().connect(sigc::mem_fun(*this, &SelectedStyle::on_opacity_changed));
_opacity_sb.set_sensitive (false);
"drag_data_received",
"drag_data_received",
}
{
delete selection_changed_connection;
delete selection_modified_connection;
delete subselection_changed_connection;
delete _color_preview[i];
// FIXME: do we need this? the destroy methods are not exported
//sp_gradient_image_destroy(GTK_OBJECT(_gradient_preview_l[i]));
//sp_gradient_image_destroy(GTK_OBJECT(_gradient_preview_r[i]));
}
}
void
{
this )
));
this )
));
this )
));
//_sw_unit = (SPUnit *) sp_desktop_namedview(desktop)->doc_units;
}
{
case SS_FILL:
case SS_STROKE:
{
gchar c[64];
// Careful about endian issues.
sp_svg_write_color( c, 64,
0xff // can't have transparency in the color itself
//0x0ff & (data->data[3] >> 8),
));
_("Drop color"));
}
}
break;
}
}
void SelectedStyle::on_fill_remove() {
_("Remove fill"));
}
void SelectedStyle::on_stroke_remove() {
_("Remove stroke"));
}
void SelectedStyle::on_fill_unset() {
_("Unset fill"));
}
void SelectedStyle::on_stroke_unset() {
_("Unset stroke"));
}
void SelectedStyle::on_fill_opaque() {
_("Make fill opaque"));
}
void SelectedStyle::on_stroke_opaque() {
_("Make fill opaque"));
}
void SelectedStyle::on_fill_lastused() {
gchar c[64];
_("Apply last set color to fill"));
}
void SelectedStyle::on_stroke_lastused() {
gchar c[64];
_("Apply last set color to stroke"));
}
void SelectedStyle::on_fill_lastselected() {
gchar c[64];
_("Apply last selected color to fill"));
}
void SelectedStyle::on_stroke_lastselected() {
gchar c[64];
_("Apply last selected color to stroke"));
}
void SelectedStyle::on_fill_invert() {
gchar c[64];
sp_svg_write_color (c, 64,
)
);
_("Invert fill"));
}
void SelectedStyle::on_stroke_invert() {
gchar c[64];
sp_svg_write_color (c, 64,
)
);
_("Invert stroke"));
}
void SelectedStyle::on_fill_white() {
gchar c[64];
_("White fill"));
}
void SelectedStyle::on_stroke_white() {
gchar c[64];
_("White stroke"));
}
void SelectedStyle::on_fill_black() {
gchar c[64];
_("Black fill"));
}
void SelectedStyle::on_stroke_black() {
gchar c[64];
_("Black stroke"));
}
void SelectedStyle::on_fill_copy() {
gchar c[64];
text += c;
}
}
}
void SelectedStyle::on_stroke_copy() {
gchar c[64];
text += c;
}
}
}
void SelectedStyle::on_fill_paste() {
guint32 color = sp_svg_read_color(text.c_str(), 0x000000ff); // impossible value, as SVG color cannot have opacity
return;
_("Paste fill"));
}
}
void SelectedStyle::on_stroke_paste() {
guint32 color = sp_svg_read_color(text.c_str(), 0x000000ff); // impossible value, as SVG color cannot have opacity
return;
_("Paste stroke"));
}
}
void SelectedStyle::on_fillstroke_swap() {
case SS_NA:
case SS_MANY:
break;
case SS_NONE:
break;
case SS_UNSET:
break;
case SS_COLOR:
gchar c[64];
break;
case SS_LGRADIENT:
case SS_RGRADIENT:
case SS_PATTERN:
break;
}
case SS_NA:
case SS_MANY:
break;
case SS_NONE:
break;
case SS_UNSET:
break;
case SS_COLOR:
gchar c[64];
break;
case SS_LGRADIENT:
case SS_RGRADIENT:
case SS_PATTERN:
break;
}
_("Swap fill and stroke"));
}
void SelectedStyle::on_fill_edit() {
}
void SelectedStyle::on_stroke_edit() {
}
bool
{
} else {
}
}
return true;
}
bool
{
} else {
}
}
return true;
}
bool
{
//
}
return true;
}
bool
{
const char* opacity = _opacity_sb.get_value() < 50? "0.5" : (_opacity_sb.get_value() == 100? "0" : "1");
_("Change opacity"));
return true;
}
return false;
}
void SelectedStyle::on_popup_px() {
update();
}
void SelectedStyle::on_popup_pt() {
update();
}
void SelectedStyle::on_popup_mm() {
update();
}
void SelectedStyle::on_popup_preset(int i) {
gdouble w;
if (_sw_unit) {
} else {
w = _sw_presets[i];
}
os << w;
// FIXME: update dash patterns!
_("Change stroke width"));
}
void
{
return;
// create temporary style
flag_place->remove();
_paintserver_id[i].clear();
_popup_copy[i].set_sensitive(false);
// query style from desktop. This returns a result flag and fills query with the style of subselection, if any, or selection
switch (result) {
case QUERY_STYLE_NOTHING:
if ( _dropEnabled[i] ) {
_dropEnabled[i] = false;
}
break;
case QUERY_STYLE_SINGLE:
if ( !_dropEnabled[i] ) {
_dropEnabled[i] = true;
}
if (i == SS_FILL) {
} else {
}
_lastselected[i] = _thisselected[i];
_color_preview[i]->show_all();
_popup_copy[i].set_sensitive(true);
SPPaintServer *server = (i == SS_FILL)? SP_STYLE_FILL_SERVER (query) : SP_STYLE_STROKE_SERVER (query);
if ( server ) {
_paintserver_id[i] += "url(#";
_paintserver_id[i] += ")";
if (SP_IS_LINEARGRADIENT (server)) {
_mode[i] = SS_LGRADIENT;
} else if (SP_IS_RADIALGRADIENT (server)) {
_mode[i] = SS_RGRADIENT;
} else if (SP_IS_PATTERN (server)) {
_mode[i] = SS_PATTERN;
}
} else {
}
}
if (result == QUERY_STYLE_MULTIPLE_AVERAGED) {
} else if (result == QUERY_STYLE_MULTIPLE_SAME) {
}
break;
break;
default:
break;
}
}
// Now query opacity
switch (result) {
case QUERY_STYLE_NOTHING:
_opacity_sb.set_sensitive(false);
break;
case QUERY_STYLE_SINGLE:
if (_opacity_blocked) break;
_opacity_blocked = true;
_opacity_sb.set_sensitive(true);
_opacity_blocked = false;
break;
}
// Now query stroke_width
switch (result_sw) {
case QUERY_STYLE_NOTHING:
break;
case QUERY_STYLE_SINGLE:
{
double w;
if (_sw_unit) {
} else {
}
{
}
{
w,
_(" (averaged)") : "");
}
break;
}
default:
break;
}
}
for (Glib::ListHandle<Gtk::Widget *>::iterator iter = children.begin(); iter != children.end(); iter++) {
}
{
}
{
}
{
}
{
}
{
}
}
void SelectedStyle::on_opacity_changed () {
if (_opacity_blocked)
return;
_opacity_blocked = true;
// FIXME: workaround for GTK breakage: display interruptibility sometimes results in GTK
// sending multiple value-changed events. As if when Inkscape interrupts redraw for main loop
// iterations, GTK discovers that this callback hasn't finished yet, and for some weird reason
// decides to add yet another value-changed event to the queue. Totally braindead if you ask
// me. As a result, scrolling the spinbutton once results in runaway change until it hits 1.0
// or 0.0. (And no, this is not a race with ::update, I checked that.)
// Sigh. So we disable interruptibility while we're setting the new value.
sp_document_maybe_done (sp_desktop_document (_desktop), "fillstroke:opacity", SP_VERB_DIALOG_FILL_STROKE,
_("Change opacity"));
// resume interruptibility
_opacity_blocked = false;
}
} // namespace Widget
} // namespace UI
} // namespace Inkscape
/*
Local Variables:
mode:c++
c-file-style:"stroustrup"
c-file-offsets:((innamespace . 0)(inline-open . 0))
indent-tabs-mode:nil
fill-column:99
End:
*/
// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :