diff options
| author | Tavmjong Bah <tavmjong@free.fr> | 2015-05-18 10:58:20 +0000 |
|---|---|---|
| committer | tavmjong-free <tavmjong@free.fr> | 2015-05-18 10:58:20 +0000 |
| commit | 6c2374a5e4f15e5b6a673a0cfdb856c4b0e86f10 (patch) | |
| tree | 3cc78e5548b5a4fef797803f4a8452d0e3db7587 /src | |
| parent | Latvian translation update (diff) | |
| parent | fixed: color icc selector - extra rows on startup (diff) | |
| download | inkscape-6c2374a5e4f15e5b6a673a0cfdb856c4b0e86f10.tar.gz inkscape-6c2374a5e4f15e5b6a673a0cfdb856c4b0e86f10.zip | |
Merge in Tomasz's fill-n-stroke-cppify branch
after fixing inkscape.pot file and conflicts with adding files.
(bzr r14160)
Diffstat (limited to 'src')
55 files changed, 4776 insertions, 4950 deletions
diff --git a/src/desktop-style.cpp b/src/desktop-style.cpp index f25ce8fa8..3bb0ce71a 100644 --- a/src/desktop-style.cpp +++ b/src/desktop-style.cpp @@ -576,8 +576,8 @@ objects_query_fillstroke (const std::vector<SPItem*> &objects, SPStyle *style_re return QUERY_STYLE_MULTIPLE_DIFFERENT; // different kind of server } - SPPattern *pat = pattern_getroot (pattern); - SPPattern *pat_res = pattern_getroot (pattern_res); + SPPattern *pat = SP_PATTERN (server)->rootPattern(); + SPPattern *pat_res = SP_PATTERN (server_res)->rootPattern(); if (pat_res != pat) { return QUERY_STYLE_MULTIPLE_DIFFERENT; // different pattern roots } diff --git a/src/extension/internal/cairo-render-context.cpp b/src/extension/internal/cairo-render-context.cpp index 27e34dbcf..c3e416184 100644 --- a/src/extension/internal/cairo-render-context.cpp +++ b/src/extension/internal/cairo-render-context.cpp @@ -1008,17 +1008,16 @@ CairoRenderContext::_createPatternPainter(SPPaintServer const *const paintserver ps2user = Geom::identity(); pcs2dev = Geom::identity(); - double x = pattern_x(pat); - double y = pattern_y(pat); - double width = pattern_width(pat); - double height = pattern_height(pat); + double x = pat->x(); + double y = pat->y(); + double width = pat->width(); + double height = pat->height(); double bbox_width_scaler; double bbox_height_scaler; TRACE(("%f x %f pattern\n", width, height)); - if (pbox && pattern_patternUnits(pat) == SP_PATTERN_UNITS_OBJECTBOUNDINGBOX) { - //Geom::Affine bbox2user (pbox->x1 - pbox->x0, 0.0, 0.0, pbox->y1 - pbox->y0, pbox->x0, pbox->y0); + if (pbox && pat->patternUnits() == SPPattern::UNITS_OBJECTBOUNDINGBOX) { bbox_width_scaler = pbox->width(); bbox_height_scaler = pbox->height(); ps2user[4] = x * bbox_width_scaler + pbox->left(); @@ -1031,13 +1030,13 @@ CairoRenderContext::_createPatternPainter(SPPaintServer const *const paintserver } // apply pattern transformation - Geom::Affine pattern_transform(pattern_patternTransform(pat)); + Geom::Affine pattern_transform(pat->getTransform()); ps2user *= pattern_transform; Geom::Point ori (ps2user[4], ps2user[5]); // create pattern contents coordinate system if (pat->viewBox_set) { - Geom::Rect view_box = *pattern_viewBox(pat); + Geom::Rect view_box = *pat->viewbox(); double x, y, w, h; x = 0; @@ -1050,7 +1049,7 @@ CairoRenderContext::_createPatternPainter(SPPaintServer const *const paintserver pcs2dev[3] = h / view_box.height(); pcs2dev[4] = x - view_box.left() * pcs2dev[0]; pcs2dev[5] = y - view_box.top() * pcs2dev[3]; - } else if (pbox && pattern_patternContentUnits(pat) == SP_PATTERN_UNITS_OBJECTBOUNDINGBOX) { + } else if (pbox && pat->patternContentUnits() == SPPattern::UNITS_OBJECTBOUNDINGBOX) { pcs2dev[0] = pbox->width(); pcs2dev[3] = pbox->height(); } diff --git a/src/extension/internal/emf-print.cpp b/src/extension/internal/emf-print.cpp index ed3ae158a..40d0955e3 100644 --- a/src/extension/internal/emf-print.cpp +++ b/src/extension/internal/emf-print.cpp @@ -388,8 +388,8 @@ int PrintEmf::create_brush(SPStyle const *style, PU_COLORREF fcolor) } else if (SP_IS_PATTERN(SP_STYLE_FILL_SERVER(style))) { // must be paint-server SPPaintServer *paintserver = style->fill.value.href->getObject(); SPPattern *pat = SP_PATTERN(paintserver); - double dwidth = pattern_width(pat); - double dheight = pattern_height(pat); + double dwidth = pat->width(); + double dheight = pat->height(); width = dwidth; height = dheight; brush_classify(pat, 0, &pixbuf, &hatchType, &hatchColor, &bkColor); @@ -573,8 +573,8 @@ int PrintEmf::create_pen(SPStyle const *style, const Geom::Affine &transform) if (SP_IS_PATTERN(SP_STYLE_STROKE_SERVER(style))) { // must be paint-server SPPaintServer *paintserver = style->stroke.value.href->getObject(); SPPattern *pat = SP_PATTERN(paintserver); - double dwidth = pattern_width(pat); - double dheight = pattern_height(pat); + double dwidth = pat->width(); + double dheight = pat->height(); width = dwidth; height = dheight; brush_classify(pat, 0, &pixbuf, &hatchType, &hatchColor, &bkColor); diff --git a/src/extension/internal/wmf-print.cpp b/src/extension/internal/wmf-print.cpp index 9fe1a0259..768909173 100644 --- a/src/extension/internal/wmf-print.cpp +++ b/src/extension/internal/wmf-print.cpp @@ -380,8 +380,8 @@ int PrintWmf::create_brush(SPStyle const *style, U_COLORREF *fcolor) } else if (SP_IS_PATTERN(SP_STYLE_FILL_SERVER(style))) { // must be paint-server SPPaintServer *paintserver = style->fill.value.href->getObject(); SPPattern *pat = SP_PATTERN(paintserver); - double dwidth = pattern_width(pat); - double dheight = pattern_height(pat); + double dwidth = pat->width(); + double dheight = pat->height(); width = dwidth; height = dheight; brush_classify(pat, 0, &pixbuf, &hatchType, &hatchColor, &bkColor); diff --git a/src/extension/param/color.cpp b/src/extension/param/color.cpp index b774bac83..3162e8a40 100644 --- a/src/extension/param/color.cpp +++ b/src/extension/param/color.cpp @@ -24,41 +24,37 @@ #include "color.h" #include <color.h> -#include "widgets/sp-color-selector.h" -#include "widgets/sp-color-notebook.h" +#include "ui/widget/color-notebook.h" #include "preferences.h" - namespace Inkscape { namespace Extension { -void sp_color_param_changed(SPColorSelector *csel, GObject *cp); - - ParamColor::~ParamColor(void) { - + _color_changed.disconnect(); } guint32 ParamColor::set( guint32 in, SPDocument * /*doc*/, Inkscape::XML::Node * /*node*/ ) { - _value = in; + _color_changed.block(true); + _color.setValue(in); + _color_changed.block(false); gchar * prefname = this->pref_name(); std::string value; string(value); - + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->setString(extension_pref_root + prefname, value); g_free(prefname); - return _value; + return in; } -ParamColor::ParamColor(const gchar *name, const gchar *guitext, const gchar *desc, const Parameter::_scope_t scope, - bool gui_hidden, const gchar *gui_tip, Inkscape::Extension::Extension *ext, - Inkscape::XML::Node *xml) - : Parameter(name, guitext, desc, scope, gui_hidden, gui_tip, ext), _value(0), _changeSignal(0) +ParamColor::ParamColor (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, bool gui_hidden, const gchar * gui_tip, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml) : + Parameter(name, guitext, desc, scope, gui_hidden, gui_tip, ext), + _changeSignal(0) { const char * defaulthex = NULL; if (xml->firstChild() != NULL) @@ -72,51 +68,46 @@ ParamColor::ParamColor(const gchar *name, const gchar *guitext, const gchar *des if (!paramval.empty()) defaulthex = paramval.data(); - if (defaulthex) - _value = atoi(defaulthex); + if (defaulthex) { + _color.setValue(atoi(defaulthex)); + } + _color_changed = _color.signal_changed.connect(sigc::mem_fun(this, &ParamColor::_onColorChanged)); + } void ParamColor::string(std::string &string) const { char str[16]; - sprintf(str, "%i", _value); + snprintf(str, 16, "%i", _color.value()); string += str; } Gtk::Widget *ParamColor::get_widget( SPDocument * /*doc*/, Inkscape::XML::Node * /*node*/, sigc::signal<void> * changeSignal ) { - if (_gui_hidden) return NULL; + using Inkscape::UI::Widget::ColorNotebook; + + if (_gui_hidden) return NULL; _changeSignal = new sigc::signal<void>(*changeSignal); - Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox(false, 4)); - SPColorSelector* spColorSelector = (SPColorSelector*)sp_color_selector_new(SP_TYPE_COLOR_NOTEBOOK); - ColorSelector* colorSelector = spColorSelector->base; - if (_value < 1) { - _value = 0xFF000000; + if (_color.value() < 1) { + _color_changed.block(true); + _color.setValue(0xFF000000); + _color_changed.block(false); } - SPColor *color = new SPColor( _value ); - float alpha = (_value & 0xff) / 255.0F; - colorSelector->setColorAlpha(*color, alpha); - - hbox->pack_start (*Glib::wrap(&spColorSelector->vbox), true, true, 0); - g_signal_connect(G_OBJECT(spColorSelector), "changed", G_CALLBACK(sp_color_param_changed), (void*)this); - gtk_widget_show(GTK_WIDGET(spColorSelector)); + Gtk::HBox *hbox = Gtk::manage(new Gtk::HBox(false, 4)); + Gtk::Widget *selector = Gtk::manage(new ColorNotebook(_color)); + hbox->pack_start (*selector, true, true, 0); + selector->show(); hbox->show(); - - return dynamic_cast<Gtk::Widget *>(hbox); + return hbox; } -void sp_color_param_changed(SPColorSelector *csel, GObject *obj) +void ParamColor::_onColorChanged() { - const SPColor color = csel->base->getColor(); - float alpha = csel->base->getAlpha(); - - ParamColor* ptr = reinterpret_cast<ParamColor*>(obj); - ptr->set(color.toRGBA32( alpha ), NULL, NULL); - - ptr->_changeSignal->emit(); + if (_changeSignal) + _changeSignal->emit(); } }; /* namespace Extension */ diff --git a/src/extension/param/color.h b/src/extension/param/color.h index 9894965a9..ed2e57ceb 100644 --- a/src/extension/param/color.h +++ b/src/extension/param/color.h @@ -9,6 +9,7 @@ */ #include "parameter.h" +#include "ui/selected-color.h" class SPDocument; @@ -25,14 +26,17 @@ namespace Extension { class ParamColor : public Parameter { private: - guint32 _value; + void _onColorChanged(); + + Inkscape::UI::SelectedColor _color; + sigc::connection _color_changed; public: ParamColor(const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, bool gui_hidden, const gchar * gui_tip, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml); virtual ~ParamColor(void); /** Returns \c _value, with a \i const to protect it. */ - guint32 get( SPDocument const * /*doc*/, Inkscape::XML::Node const * /*node*/ ) const { return _value; } + guint32 get( SPDocument const * /*doc*/, Inkscape::XML::Node const * /*node*/ ) const { return _color.value(); } guint32 set (guint32 in, SPDocument * doc, Inkscape::XML::Node * node); @@ -44,6 +48,7 @@ public: virtual void string (std::string &string) const; sigc::signal<void> * _changeSignal; + }; // class ParamColor } // namespace Extension diff --git a/src/extension/param/parameter.cpp b/src/extension/param/parameter.cpp index 202b8110f..8c99ee55d 100644 --- a/src/extension/param/parameter.cpp +++ b/src/extension/param/parameter.cpp @@ -15,6 +15,10 @@ # include "config.h" #endif +#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H +#include <glibmm/threads.h> +#endif + #ifdef linux // does the dollar sign need escaping when passed as string parameter? # define ESCAPE_DOLLAR_COMMANDLINE #endif @@ -26,8 +30,7 @@ #include "document-private.h" #include "sp-object.h" #include <color.h> -#include "widgets/sp-color-selector.h" -#include "widgets/sp-color-notebook.h" +#include "ui/widget/color-notebook.h" #include "parameter.h" #include "bool.h" diff --git a/src/knot-holder-entity.cpp b/src/knot-holder-entity.cpp index b66156b09..173025920 100644 --- a/src/knot-holder-entity.cpp +++ b/src/knot-holder-entity.cpp @@ -140,19 +140,19 @@ KnotHolderEntity::snap_knot_position_constrained(Geom::Point const &p, Inkscape: static gdouble sp_pattern_extract_theta(SPPattern const *pat) { - Geom::Affine transf = pat->patternTransform; + Geom::Affine transf = pat->getTransform(); return Geom::atan2(transf.xAxis()); } static Geom::Point sp_pattern_extract_scale(SPPattern const *pat) { - Geom::Affine transf = pat->patternTransform; + Geom::Affine transf = pat->getTransform(); return Geom::Point( transf.expansionX(), transf.expansionY() ); } static Geom::Point sp_pattern_extract_trans(SPPattern const *pat) { - return Geom::Point(pat->patternTransform[4], pat->patternTransform[5]); + return Geom::Point(pat->getTransform()[4], pat->getTransform()[5]); } void @@ -191,7 +191,7 @@ PatternKnotHolderEntityAngle::knot_get() const { SPPattern *pat = _fill ? SP_PATTERN(item->style->getFillPaintServer()) : SP_PATTERN(item->style->getStrokePaintServer()); - gdouble x = pattern_width(pat); + gdouble x = pat->width(); gdouble y = 0; Geom::Point delta = Geom::Point(x,y); Geom::Point scale = sp_pattern_extract_scale(pat); @@ -240,8 +240,8 @@ PatternKnotHolderEntityScale::knot_set(Geom::Point const &p, Geom::Point const & // Get the new scale from the position of the knotholder Geom::Point d = p_snapped - sp_pattern_extract_trans(pat); - gdouble pat_x = pattern_width(pat); - gdouble pat_y = pattern_height(pat); + gdouble pat_x = pat->width(); + gdouble pat_y = pat->height(); Geom::Scale scl(1); if ( state & GDK_CONTROL_MASK ) { // if ctrl is pressed: use 1:1 scaling @@ -267,10 +267,10 @@ PatternKnotHolderEntityScale::knot_get() const { SPPattern *pat = _fill ? SP_PATTERN(item->style->getFillPaintServer()) : SP_PATTERN(item->style->getStrokePaintServer()); - gdouble x = pattern_width(pat); - gdouble y = pattern_height(pat); + gdouble x = pat->width(); + gdouble y = pat->height(); Geom::Point delta = Geom::Point(x,y); - Geom::Affine a = pat->patternTransform; + Geom::Affine a = pat->getTransform(); a[4] = 0; a[5] = 0; delta = delta * a; diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index d6e9a1e32..16585413e 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -1963,8 +1963,8 @@ std::vector<SPItem*> sp_get_same_fill_or_stroke_color(SPItem *sel, std::vector<S } } else if (dynamic_cast<SPPattern *>(sel_server) && dynamic_cast<SPPattern *>(iter_server)) { - SPPattern *sel_pat = pattern_getroot(dynamic_cast<SPPattern *>(sel_server)); - SPPattern *iter_pat = pattern_getroot(dynamic_cast<SPPattern *>(iter_server)); + SPPattern *sel_pat = dynamic_cast<SPPattern *>(sel_server)->rootPattern(); + SPPattern *iter_pat = dynamic_cast<SPPattern *>(iter_server)->rootPattern(); if (sel_pat == iter_pat) { match = true; } @@ -3312,7 +3312,7 @@ sp_selection_tile(SPDesktop *desktop, bool apply) int saved_compensation = prefs->getInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED); prefs->setInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED); - gchar const *pat_id = pattern_tile(repr_copies, bbox, doc, + gchar const *pat_id = SPPattern::produce(repr_copies, bbox, doc, ( Geom::Affine(Geom::Translate(desktop->dt2doc(Geom::Point(r->min()[Geom::X], r->max()[Geom::Y])))) * parent_transform.inverse() ), @@ -3390,9 +3390,9 @@ void sp_selection_untile(SPDesktop *desktop) did = true; - SPPattern *pattern = pattern_getroot(basePat); + SPPattern *pattern = basePat->rootPattern(); - Geom::Affine pat_transform = pattern_patternTransform(basePat); + Geom::Affine pat_transform = basePat->getTransform(); pat_transform *= item->transform; for (SPObject *child = pattern->firstChild() ; child != NULL; child = child->next ) { diff --git a/src/sp-item.cpp b/src/sp-item.cpp index 5445be947..410fd9b37 100644 --- a/src/sp-item.cpp +++ b/src/sp-item.cpp @@ -1222,8 +1222,8 @@ void SPItem::adjust_pattern(Geom::Affine const &postmul, bool set, PatternTransf SPObject *server = style->getFillPaintServer(); SPPattern *serverPatt = dynamic_cast<SPPattern *>(server); if ( serverPatt ) { - SPPattern *pattern = sp_pattern_clone_if_necessary(this, serverPatt, "fill"); - sp_pattern_transform_multiply(pattern, postmul, set); + SPPattern *pattern = serverPatt->clone_if_necessary(this, "fill"); + pattern->transform_multiply(postmul, set); } } @@ -1232,8 +1232,8 @@ void SPItem::adjust_pattern(Geom::Affine const &postmul, bool set, PatternTransf SPObject *server = style->getStrokePaintServer(); SPPattern *serverPatt = dynamic_cast<SPPattern *>(server); if ( serverPatt ) { - SPPattern *pattern = sp_pattern_clone_if_necessary(this, serverPatt, "stroke"); - sp_pattern_transform_multiply(pattern, postmul, set); + SPPattern *pattern = serverPatt->clone_if_necessary(this, "stroke"); + pattern->transform_multiply(postmul, set); } } } diff --git a/src/sp-pattern.cpp b/src/sp-pattern.cpp index e89ed77ba..755d3d162 100644 --- a/src/sp-pattern.cpp +++ b/src/sp-pattern.cpp @@ -5,7 +5,7 @@ * Lauris Kaplinski <lauris@kaplinski.com> * bulia byak <buliabyak@users.sf.net> * Jon A. Cruz <jon@joncruz.org> - * Abhishek Sharma + * Abhishek Sharma * * Copyright (C) 2002 Lauris Kaplinski * @@ -13,15 +13,15 @@ */ #ifdef HAVE_CONFIG_H -# include "config.h" +#include "config.h" #endif #include <cstring> #include <string> #include <glibmm.h> #include <2geom/transforms.h> +#include <sigc++/functors/mem_fun.h> -#include "macros.h" #include "svg/svg.h" #include "display/cairo-utils.h" #include "display/drawing-context.h" @@ -34,67 +34,61 @@ #include "style.h" #include "sp-pattern.h" #include "xml/repr.h" -#include "display/grayscale.h" -#include <sigc++/functors/ptr_fun.h> -#include <sigc++/adaptors/bind.h> +#include "sp-factory.h" -/* - * Pattern - */ -static void pattern_ref_changed(SPObject *old_ref, SPObject *ref, SPPattern *pat); -static void pattern_ref_modified (SPObject *ref, guint flags, SPPattern *pattern); - -SPPattern::SPPattern() : SPPaintServer(), SPViewBox() { - this->href = NULL; - - this->ref = new SPPatternReference(this); - this->ref->changedSignal().connect(sigc::bind(sigc::ptr_fun(pattern_ref_changed), this)); +SPPattern::SPPattern() + : SPPaintServer() + , SPViewBox() +{ + this->ref = new SPPatternReference(this); + this->ref->changedSignal().connect(sigc::mem_fun(this, &SPPattern::_onRefChanged)); - this->patternUnits = SP_PATTERN_UNITS_OBJECTBOUNDINGBOX; - this->patternUnits_set = FALSE; + this->_pattern_units = UNITS_OBJECTBOUNDINGBOX; + this->_pattern_units_set = false; - this->patternContentUnits = SP_PATTERN_UNITS_USERSPACEONUSE; - this->patternContentUnits_set = FALSE; + this->_pattern_content_units = UNITS_USERSPACEONUSE; + this->_pattern_content_units_set = false; - this->patternTransform = Geom::identity(); - this->patternTransform_set = FALSE; + this->_pattern_transform = Geom::identity(); + this->_pattern_transform_set = false; - this->x.unset(); - this->y.unset(); - this->width.unset(); - this->height.unset(); + this->_x.unset(); + this->_y.unset(); + this->_width.unset(); + this->_height.unset(); } -SPPattern::~SPPattern() { -} +SPPattern::~SPPattern() {} -void SPPattern::build(SPDocument* doc, Inkscape::XML::Node* repr) { - SPPaintServer::build(doc, repr); - - this->readAttr( "patternUnits" ); - this->readAttr( "patternContentUnits" ); - this->readAttr( "patternTransform" ); - this->readAttr( "x" ); - this->readAttr( "y" ); - this->readAttr( "width" ); - this->readAttr( "height" ); - this->readAttr( "viewBox" ); - this->readAttr( "preserveAspectRatio" ); - this->readAttr( "xlink:href" ); - - /* Register ourselves */ - doc->addResource("pattern", this); +void SPPattern::build(SPDocument *doc, Inkscape::XML::Node *repr) +{ + SPPaintServer::build(doc, repr); + + this->readAttr("patternUnits"); + this->readAttr("patternContentUnits"); + this->readAttr("patternTransform"); + this->readAttr("x"); + this->readAttr("y"); + this->readAttr("width"); + this->readAttr("height"); + this->readAttr("viewBox"); + this->readAttr("preserveAspectRatio"); + this->readAttr("xlink:href"); + + /* Register ourselves */ + doc->addResource("pattern", this); } -void SPPattern::release() { +void SPPattern::release() +{ if (this->document) { // Unregister ourselves this->document->removeResource("pattern", this); } if (this->ref) { - this->modified_connection.disconnect(); + this->_modified_connection.disconnect(); this->ref->detach(); delete this->ref; this->ref = NULL; @@ -103,113 +97,121 @@ void SPPattern::release() { SPPaintServer::release(); } -void SPPattern::set(unsigned int key, const gchar* value) { - switch (key) { - case SP_ATTR_PATTERNUNITS: - if (value) { - if (!strcmp (value, "userSpaceOnUse")) { - this->patternUnits = SP_PATTERN_UNITS_USERSPACEONUSE; - } else { - this->patternUnits = SP_PATTERN_UNITS_OBJECTBOUNDINGBOX; - } - - this->patternUnits_set = TRUE; - } else { - this->patternUnits_set = FALSE; - } - - this->requestModified(SP_OBJECT_MODIFIED_FLAG); - break; - - case SP_ATTR_PATTERNCONTENTUNITS: - if (value) { - if (!strcmp (value, "userSpaceOnUse")) { - this->patternContentUnits = SP_PATTERN_UNITS_USERSPACEONUSE; - } else { - this->patternContentUnits = SP_PATTERN_UNITS_OBJECTBOUNDINGBOX; - } - - this->patternContentUnits_set = TRUE; - } else { - this->patternContentUnits_set = FALSE; - } - - this->requestModified(SP_OBJECT_MODIFIED_FLAG); - break; - - case SP_ATTR_PATTERNTRANSFORM: { - Geom::Affine t; - - if (value && sp_svg_transform_read (value, &t)) { - this->patternTransform = t; - this->patternTransform_set = TRUE; - } else { - this->patternTransform = Geom::identity(); - this->patternTransform_set = FALSE; - } - - this->requestModified(SP_OBJECT_MODIFIED_FLAG); - break; - } - case SP_ATTR_X: - this->x.readOrUnset(value); - this->requestModified(SP_OBJECT_MODIFIED_FLAG); - break; - - case SP_ATTR_Y: - this->y.readOrUnset(value); - this->requestModified(SP_OBJECT_MODIFIED_FLAG); - break; - - case SP_ATTR_WIDTH: - this->width.readOrUnset(value); - this->requestModified(SP_OBJECT_MODIFIED_FLAG); - break; - - case SP_ATTR_HEIGHT: - this->height.readOrUnset(value); - this->requestModified(SP_OBJECT_MODIFIED_FLAG); - break; - - case SP_ATTR_VIEWBOX: - set_viewBox( value ); +void SPPattern::set(unsigned int key, const gchar *value) +{ + switch (key) { + case SP_ATTR_PATTERNUNITS: + if (value) { + if (!strcmp(value, "userSpaceOnUse")) { + this->_pattern_units = UNITS_USERSPACEONUSE; + } + else { + this->_pattern_units = UNITS_OBJECTBOUNDINGBOX; + } + + this->_pattern_units_set = true; + } + else { + this->_pattern_units_set = false; + } + + this->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + + case SP_ATTR_PATTERNCONTENTUNITS: + if (value) { + if (!strcmp(value, "userSpaceOnUse")) { + this->_pattern_content_units = UNITS_USERSPACEONUSE; + } + else { + this->_pattern_content_units = UNITS_OBJECTBOUNDINGBOX; + } + + this->_pattern_content_units_set = true; + } + else { + this->_pattern_content_units_set = false; + } + + this->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + + case SP_ATTR_PATTERNTRANSFORM: { + Geom::Affine t; + + if (value && sp_svg_transform_read(value, &t)) { + this->_pattern_transform = t; + this->_pattern_transform_set = true; + } + else { + this->_pattern_transform = Geom::identity(); + this->_pattern_transform_set = false; + } + + this->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + } + case SP_ATTR_X: + this->_x.readOrUnset(value); + this->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + + case SP_ATTR_Y: + this->_y.readOrUnset(value); + this->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + + case SP_ATTR_WIDTH: + this->_width.readOrUnset(value); + this->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + + case SP_ATTR_HEIGHT: + this->_height.readOrUnset(value); + this->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + + case SP_ATTR_VIEWBOX: + set_viewBox(value); this->requestModified(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG); break; case SP_ATTR_PRESERVEASPECTRATIO: - set_preserveAspectRatio( value ); + set_preserveAspectRatio(value); this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG); break; - case SP_ATTR_XLINK_HREF: - if ( value && this->href && ( strcmp(value, this->href) == 0 ) ) { - /* Href unchanged, do nothing. */ - } else { - g_free(this->href); - this->href = NULL; - - if (value) { - // First, set the href field; it's only used in the "unchanged" check above. - this->href = g_strdup(value); - // Now do the attaching, which emits the changed signal. - if (value) { - try { - this->ref->attach(Inkscape::URI(value)); - } catch (Inkscape::BadURIException &e) { - g_warning("%s", e.what()); - this->ref->detach(); - } - } else { - this->ref->detach(); - } - } - } - break; - - default: - SPPaintServer::set(key, value); - break; - } + case SP_ATTR_XLINK_HREF: + if (value && this->href == value) { + /* Href unchanged, do nothing. */ + } + else { + this->href.clear(); + + if (value) { + // First, set the href field; it's only used in the "unchanged" check above. + this->href = value; + // Now do the attaching, which emits the changed signal. + if (value) { + try { + this->ref->attach(Inkscape::URI(value)); + } + catch (Inkscape::BadURIException &e) { + g_warning("%s", e.what()); + this->ref->detach(); + } + } + else { + this->ref->detach(); + } + } + } + break; + + default: + SPPaintServer::set(key, value); + break; + } } @@ -217,104 +219,90 @@ void SPPattern::set(unsigned int key, const gchar* value) { /* fixme: We need ::order_changed handler too (Lauris) */ -static GSList *pattern_getchildren(SPPattern *pat) +void SPPattern::_getChildren(std::list<SPObject *> &l) { - GSList *l = NULL; - - for (SPPattern *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { + for (SPPattern *pat_i = this; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { if (pat_i->firstChild()) { // find the first one with children - for (SPObject *child = pat->firstChild() ; child ; child = child->getNext() ) { - l = g_slist_prepend (l, child); - } - break; // do not go further up the chain if children are found + for (SPObject *child = pat_i->firstChild(); child; child = child->getNext()) { + l.push_back(child); + } + break; // do not go further up the chain if children are found } } - - return l; } -void SPPattern::update(SPCtx* ctx, unsigned int flags) { - if (flags & SP_OBJECT_MODIFIED_FLAG) { - flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; - } +void SPPattern::update(SPCtx *ctx, unsigned int flags) +{ + typedef std::list<SPObject *>::iterator SPObjectIterator; + + if (flags & SP_OBJECT_MODIFIED_FLAG) { + flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; + } - flags &= SP_OBJECT_MODIFIED_CASCADE; + flags &= SP_OBJECT_MODIFIED_CASCADE; - GSList *l = pattern_getchildren (this); - l = g_slist_reverse (l); + std::list<SPObject *> l; + _getChildren(l); - while (l) { - SPObject *child = SP_OBJECT (l->data); + for (SPObjectIterator it = l.begin(); it != l.end(); it++) { + SPObject *child = *it; - sp_object_ref (child, NULL); - l = g_slist_remove (l, child); + sp_object_ref(child, NULL); - if (flags || (child->mflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { - child->updateDisplay(ctx, flags); - } + if (flags || (child->mflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { + child->updateDisplay(ctx, flags); + } - sp_object_unref (child, NULL); - } + sp_object_unref(child, NULL); + } } -void SPPattern::modified(unsigned int flags) { - if (flags & SP_OBJECT_MODIFIED_FLAG) { - flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; - } +void SPPattern::modified(unsigned int flags) +{ + typedef std::list<SPObject *>::iterator SPObjectIterator; + + if (flags & SP_OBJECT_MODIFIED_FLAG) { + flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; + } - flags &= SP_OBJECT_MODIFIED_CASCADE; + flags &= SP_OBJECT_MODIFIED_CASCADE; - GSList *l = pattern_getchildren (this); - l = g_slist_reverse (l); + std::list<SPObject *> l; + _getChildren(l); - while (l) { - SPObject *child = SP_OBJECT (l->data); + for (SPObjectIterator it = l.begin(); it != l.end(); it++) { + SPObject *child = *it; - sp_object_ref (child, NULL); - l = g_slist_remove (l, child); + sp_object_ref(child, NULL); - if (flags || (child->mflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { - child->emitModified(flags); - } + if (flags || (child->mflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { + child->emitModified(flags); + } - sp_object_unref (child, NULL); - } + sp_object_unref(child, NULL); + } } -/** -Gets called when the pattern is reattached to another <pattern> -*/ -static void -pattern_ref_changed(SPObject *old_ref, SPObject *ref, SPPattern *pat) +void SPPattern::_onRefChanged(SPObject *old_ref, SPObject *ref) { - if (old_ref) { - pat->modified_connection.disconnect(); - } + if (old_ref) { + _modified_connection.disconnect(); + } - if (SP_IS_PATTERN (ref)) { - pat->modified_connection = ref->connectModified(sigc::bind<2>(sigc::ptr_fun(&pattern_ref_modified), pat)); - } + if (SP_IS_PATTERN(ref)) { + _modified_connection = ref->connectModified(sigc::mem_fun(this, &SPPattern::_onRefModified)); + } - pattern_ref_modified (ref, 0, pat); + _onRefModified(ref, 0); } -/** -Gets called when the referenced <pattern> is changed -*/ -static void pattern_ref_modified (SPObject */*ref*/, guint /*flags*/, SPPattern *pattern) +void SPPattern::_onRefModified(SPObject * /*ref*/, guint /*flags*/) { - if ( SP_IS_OBJECT(pattern) ) { - pattern->requestModified(SP_OBJECT_MODIFIED_FLAG); - } + requestModified(SP_OBJECT_MODIFIED_FLAG); // Conditional to avoid causing infinite loop if there's a cycle in the href chain. } - -/** -Count how many times pat is used by the styles of o and its descendants -*/ -static guint -count_pattern_hrefs(SPObject *o, SPPattern *pat) +guint SPPattern::_countHrefs(SPObject *o) const { if (!o) return 1; @@ -322,84 +310,79 @@ count_pattern_hrefs(SPObject *o, SPPattern *pat) guint i = 0; SPStyle *style = o->style; - if (style - && style->fill.isPaintserver() - && SP_IS_PATTERN(SP_STYLE_FILL_SERVER(style)) - && SP_PATTERN(SP_STYLE_FILL_SERVER(style)) == pat) - { - i ++; + if (style && style->fill.isPaintserver() && SP_IS_PATTERN(SP_STYLE_FILL_SERVER(style)) && + SP_PATTERN(SP_STYLE_FILL_SERVER(style)) == this) { + i++; } - if (style - && style->stroke.isPaintserver() - && SP_IS_PATTERN(SP_STYLE_STROKE_SERVER(style)) - && SP_PATTERN(SP_STYLE_STROKE_SERVER(style)) == pat) - { - i ++; + if (style && style->stroke.isPaintserver() && SP_IS_PATTERN(SP_STYLE_STROKE_SERVER(style)) && + SP_PATTERN(SP_STYLE_STROKE_SERVER(style)) == this) { + i++; } - for ( SPObject *child = o->firstChild(); child != NULL; child = child->next ) { - i += count_pattern_hrefs(child, pat); + for (SPObject *child = o->firstChild(); child != NULL; child = child->next) { + i += _countHrefs(child); } return i; } -SPPattern *pattern_chain(SPPattern *pattern) +SPPattern *SPPattern::_chain() const { - SPDocument *document = pattern->document; - Inkscape::XML::Document *xml_doc = document->getReprDoc(); + Inkscape::XML::Document *xml_doc = document->getReprDoc(); Inkscape::XML::Node *defsrepr = document->getDefs()->getRepr(); Inkscape::XML::Node *repr = xml_doc->createElement("svg:pattern"); repr->setAttribute("inkscape:collect", "always"); - gchar *parent_ref = g_strconcat("#", pattern->getRepr()->attribute("id"), NULL); - repr->setAttribute("xlink:href", parent_ref); - g_free (parent_ref); + Glib::ustring parent_ref = Glib::ustring::compose("#%1", getRepr()->attribute("id")); + repr->setAttribute("xlink:href", parent_ref); defsrepr->addChild(repr, NULL); const gchar *child_id = repr->attribute("id"); SPObject *child = document->getObjectById(child_id); - g_assert (SP_IS_PATTERN (child)); + g_assert(SP_IS_PATTERN(child)); - return SP_PATTERN (child); + return SP_PATTERN(child); } -SPPattern * -sp_pattern_clone_if_necessary (SPItem *item, SPPattern *pattern, const gchar *property) +SPPattern *SPPattern::clone_if_necessary(SPItem *item, const gchar *property) { - if (!pattern->href || pattern->hrefcount > count_pattern_hrefs(item, pattern)) { - pattern = pattern_chain (pattern); - gchar *href = g_strconcat("url(#", pattern->getRepr()->attribute("id"), ")", NULL); + SPPattern *pattern = this; + if (pattern->href.empty() || pattern->hrefcount > _countHrefs(item)) { + pattern = _chain(); + Glib::ustring href = Glib::ustring::compose("url(#%1)", pattern->getRepr()->attribute("id")); - SPCSSAttr *css = sp_repr_css_attr_new (); - sp_repr_css_set_property (css, property, href); + SPCSSAttr *css = sp_repr_css_attr_new(); + sp_repr_css_set_property(css, property, href.c_str()); sp_repr_css_change_recursive(item->getRepr(), css, "style"); } return pattern; } -void -sp_pattern_transform_multiply (SPPattern *pattern, Geom::Affine postmul, bool set) +void SPPattern::transform_multiply(Geom::Affine postmul, bool set) { // this formula is for a different interpretation of pattern transforms as described in (*) in sp-pattern.cpp // for it to work, we also need sp_object_read_attr( item, "transform"); - //pattern->patternTransform = premul * item->transform * pattern->patternTransform * item->transform.inverse() * postmul; + // pattern->patternTransform = premul * item->transform * pattern->patternTransform * item->transform.inverse() * + // postmul; // otherwise the formula is much simpler if (set) { - pattern->patternTransform = postmul; - } else { - pattern->patternTransform = pattern_patternTransform(pattern) * postmul; + _pattern_transform = postmul; } - pattern->patternTransform_set = TRUE; + else { + _pattern_transform = getTransform() * postmul; + } + _pattern_transform_set = true; - gchar *c=sp_svg_transform_write(pattern->patternTransform); - pattern->getRepr()->setAttribute("patternTransform", c); - g_free(c); + Glib::ustring c = sp_svg_transform_write(_pattern_transform); + getRepr()->setAttribute("patternTransform", c); } -const gchar *pattern_tile(const std::vector<Inkscape::XML::Node*> &reprs, Geom::Rect bounds, SPDocument *document, Geom::Affine transform, Geom::Affine move) +const gchar *SPPattern::produce(const std::vector<Inkscape::XML::Node *> &reprs, Geom::Rect bounds, + SPDocument *document, Geom::Affine transform, Geom::Affine move) { + typedef std::vector<Inkscape::XML::Node *>::const_iterator NodePtrIterator; + Inkscape::XML::Document *xml_doc = document->getReprDoc(); Inkscape::XML::Node *defsrepr = document->getDefs()->getRepr(); @@ -408,20 +391,19 @@ const gchar *pattern_tile(const std::vector<Inkscape::XML::Node*> &reprs, Geom:: sp_repr_set_svg_double(repr, "width", bounds.dimensions()[Geom::X]); sp_repr_set_svg_double(repr, "height", bounds.dimensions()[Geom::Y]); - gchar *t=sp_svg_transform_write(transform); + Glib::ustring t = sp_svg_transform_write(transform); repr->setAttribute("patternTransform", t); - g_free(t); defsrepr->appendChild(repr); const gchar *pat_id = repr->attribute("id"); SPObject *pat_object = document->getObjectById(pat_id); - for (std::vector<Inkscape::XML::Node*>::const_iterator i=reprs.begin();i!=reprs.end();i++){ + for (NodePtrIterator i = reprs.begin(); i != reprs.end(); i++) { Inkscape::XML::Node *node = *i; SPItem *copy = SP_ITEM(pat_object->appendChildRepr(node)); Geom::Affine dup_transform; - if (!sp_svg_transform_read (node->attribute("transform"), &dup_transform)) + if (!sp_svg_transform_read(node->attribute("transform"), &dup_transform)) dup_transform = Geom::identity(); dup_transform *= move; @@ -432,14 +414,15 @@ const gchar *pattern_tile(const std::vector<Inkscape::XML::Node*> &reprs, Geom:: return pat_id; } -SPPattern *pattern_getroot(SPPattern *pat) +SPPattern *SPPattern::rootPattern() { - for (SPPattern *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { - if ( pat_i->firstChild() ) { // find the first one with children + for (SPPattern *pat_i = this; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { + if (pat_i->firstChild()) { // find the first one with children return pat_i; } } - return pat; // document is broken, we can't get to root; but at least we can return pat which is supposedly a valid pattern + return this; // document is broken, we can't get to root; but at least we can return pat which is supposedly a valid + // pattern } @@ -447,73 +430,73 @@ SPPattern *pattern_getroot(SPPattern *pat) // Access functions that look up fields up the chain of referenced patterns and return the first one which is set // FIXME: all of them must use chase_hrefs the same as in SPGradient, to avoid lockup on circular refs -guint pattern_patternUnits (SPPattern const *pat) +SPPattern::PatternUnits SPPattern::patternUnits() const { - for (SPPattern const *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { - if (pat_i->patternUnits_set) - return pat_i->patternUnits; + for (SPPattern const *pat_i = this; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { + if (pat_i->_pattern_units_set) + return pat_i->_pattern_units; } - return pat->patternUnits; + return _pattern_units; } -guint pattern_patternContentUnits (SPPattern const *pat) +SPPattern::PatternUnits SPPattern::patternContentUnits() const { - for (SPPattern const *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { - if (pat_i->patternContentUnits_set) - return pat_i->patternContentUnits; + for (SPPattern const *pat_i = this; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { + if (pat_i->_pattern_content_units_set) + return pat_i->_pattern_content_units; } - return pat->patternContentUnits; + return _pattern_content_units; } -Geom::Affine const &pattern_patternTransform(SPPattern const *pat) +Geom::Affine const &SPPattern::getTransform() const { - for (SPPattern const *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { - if (pat_i->patternTransform_set) - return pat_i->patternTransform; + for (SPPattern const *pat_i = this; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { + if (pat_i->_pattern_transform_set) + return pat_i->_pattern_transform; } - return pat->patternTransform; + return _pattern_transform; } -gdouble pattern_x (SPPattern const *pat) +gdouble SPPattern::x() const { - for (SPPattern const *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { - if (pat_i->x._set) - return pat_i->x.computed; + for (SPPattern const *pat_i = this; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { + if (pat_i->_x._set) + return pat_i->_x.computed; } return 0; } -gdouble pattern_y (SPPattern const *pat) +gdouble SPPattern::y() const { - for (SPPattern const *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { - if (pat_i->y._set) - return pat_i->y.computed; + for (SPPattern const *pat_i = this; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { + if (pat_i->_y._set) + return pat_i->_y.computed; } return 0; } -gdouble pattern_width (SPPattern const* pat) +gdouble SPPattern::width() const { - for (SPPattern const *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { - if (pat_i->width._set) - return pat_i->width.computed; + for (SPPattern const *pat_i = this; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { + if (pat_i->_width._set) + return pat_i->_width.computed; } return 0; } -gdouble pattern_height (SPPattern const *pat) +gdouble SPPattern::height() const { - for (SPPattern const *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { - if (pat_i->height._set) - return pat_i->height.computed; + for (SPPattern const *pat_i = this; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { + if (pat_i->_height._set) + return pat_i->_height.computed; } return 0; } -Geom::OptRect pattern_viewBox (SPPattern const *pat) +Geom::OptRect SPPattern::viewbox() const { Geom::OptRect viewbox; - for (SPPattern const *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { + for (SPPattern const *pat_i = this; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { if (pat_i->viewBox_set) { viewbox = pat_i->viewBox; break; @@ -522,10 +505,10 @@ Geom::OptRect pattern_viewBox (SPPattern const *pat) return viewbox; } -static bool pattern_hasItemChildren (SPPattern const *pat) +bool SPPattern::_hasItemChildren() const { bool hasChildren = false; - for (SPObject const *child = pat->firstChild() ; child && !hasChildren ; child = child->getNext() ) { + for (SPObject const *child = firstChild(); child && !hasChildren; child = child->getNext()) { if (SP_IS_ITEM(child)) { hasChildren = true; } @@ -535,15 +518,16 @@ static bool pattern_hasItemChildren (SPPattern const *pat) bool SPPattern::isValid() const { - double tile_width = pattern_width(this); - double tile_height = pattern_height(this); + double tile_width = width(); + double tile_height = height(); - if (tile_width <= 0 || tile_height <= 0) - return false; - return true; + if (tile_width <= 0 || tile_height <= 0) + return false; + return true; } -cairo_pattern_t* SPPattern::pattern_new(cairo_t *base_ct, Geom::OptRect const &bbox, double opacity) { +cairo_pattern_t *SPPattern::pattern_new(cairo_t *base_ct, Geom::OptRect const &bbox, double opacity) +{ bool needs_opacity = (1.0 - opacity) >= 1e-3; bool visible = opacity >= 1e-3; @@ -557,28 +541,28 @@ cairo_pattern_t* SPPattern::pattern_new(cairo_t *base_ct, Geom::OptRect const &b for (SPPattern *pat_i = this; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { // find the first one with item children - if (pat_i && SP_IS_OBJECT(pat_i) && pattern_hasItemChildren(pat_i)) { + if (pat_i && SP_IS_OBJECT(pat_i) && pat_i->_hasItemChildren()) { shown = pat_i; break; // do not go further up the chain if children are found } } if (!shown) { - return cairo_pattern_create_rgba(0,0,0,0); + return cairo_pattern_create_rgba(0, 0, 0, 0); } /* Create drawing for rendering */ Inkscape::Drawing drawing; - unsigned int dkey = SPItem::display_key_new (1); + unsigned int dkey = SPItem::display_key_new(1); Inkscape::DrawingGroup *root = new Inkscape::DrawingGroup(drawing); drawing.setRoot(root); - for (SPObject *child = shown->firstChild(); child != NULL; child = child->getNext() ) { - if (SP_IS_ITEM (child)) { + for (SPObject *child = shown->firstChild(); child != NULL; child = child->getNext()) { + if (SP_IS_ITEM(child)) { // for each item in pattern, show it on our drawing, add to the group, // and connect to the release signal in case the item gets deleted Inkscape::DrawingItem *cai; - cai = SP_ITEM(child)->invoke_show (drawing, dkey, SP_ITEM_SHOW_DISPLAY); + cai = SP_ITEM(child)->invoke_show(drawing, dkey, SP_ITEM_SHOW_DISPLAY); root->appendChild(cai); } } @@ -591,40 +575,41 @@ cairo_pattern_t* SPPattern::pattern_new(cairo_t *base_ct, Geom::OptRect const &b // * "x", "y", and "patternTransform" transform tile to user space after tile is generated. // These functions recursively search up the tree to find the values. - double tile_x = pattern_x(this); - double tile_y = pattern_y(this); - double tile_width = pattern_width(this); - double tile_height = pattern_height(this); - if ( bbox && (pattern_patternUnits(this) == SP_PATTERN_UNITS_OBJECTBOUNDINGBOX) ) { - tile_x *= bbox->width(); - tile_y *= bbox->height(); - tile_width *= bbox->width(); + double tile_x = x(); + double tile_y = y(); + double tile_width = width(); + double tile_height = height(); + if (bbox && (patternUnits() == UNITS_OBJECTBOUNDINGBOX)) { + tile_x *= bbox->width(); + tile_y *= bbox->height(); + tile_width *= bbox->width(); tile_height *= bbox->height(); } // Pattern size in pattern space Geom::Rect pattern_tile = Geom::Rect::from_xywh(0, 0, tile_width, tile_height); - + // Content to tile (pattern space) Geom::Affine content2ps; - Geom::OptRect effective_view_box = pattern_viewBox(this); + Geom::OptRect effective_view_box = viewbox(); if (effective_view_box) { - // viewBox to pattern server (using SPViewBox) + // viewBox to pattern server (using SPViewBox) viewBox = *effective_view_box; c2p.setIdentity(); - apply_viewbox( pattern_tile ); + apply_viewbox(pattern_tile); content2ps = c2p; - } else { + } + else { // Content to bbox - if (bbox && (pattern_patternContentUnits(this) == SP_PATTERN_UNITS_OBJECTBOUNDINGBOX) ) { - content2ps = Geom::Affine(bbox->width(), 0.0, 0.0, bbox->height(), 0,0); + if (bbox && (patternContentUnits() == UNITS_OBJECTBOUNDINGBOX)) { + content2ps = Geom::Affine(bbox->width(), 0.0, 0.0, bbox->height(), 0, 0); } } // Tile (pattern space) to user. - Geom::Affine ps2user = Geom::Translate(tile_x,tile_y) * pattern_patternTransform(this); + Geom::Affine ps2user = Geom::Translate(tile_x, tile_y) * getTransform(); // Transform of object with pattern (includes screen scaling) @@ -644,7 +629,7 @@ cairo_pattern_t* SPPattern::pattern_new(cairo_t *base_ct, Geom::OptRect const &b // to find the optimum tile size for rendering // c is number of pixels in buffer x and y. // Scale factor of 1.1 is too small... see bug #1251039 - Geom::Point c(pattern_tile.dimensions()*ps2user.descrim()*full.descrim()*2.0); + Geom::Point c(pattern_tile.dimensions() * ps2user.descrim() * full.descrim() * 2.0); // Create drawing surface with size of pattern tile (in pattern space) but with number of pixels // based on required resolution (c). @@ -660,16 +645,16 @@ cairo_pattern_t* SPPattern::pattern_new(cairo_t *base_ct, Geom::OptRect const &b } // TODO: make sure there are no leaks. - Inkscape::UpdateContext ctx; // UpdateContext is structure with only ctm! + Inkscape::UpdateContext ctx; // UpdateContext is structure with only ctm! ctx.ctm = content2ps * pattern_surface.drawingTransform(); - dc.transform( pattern_surface.drawingTransform().inverse() ); + dc.transform(pattern_surface.drawingTransform().inverse()); drawing.update(Geom::IntRect::infinite(), ctx); // Render drawing to pattern_surface via drawing context, this calls root->render // which is really DrawingItem->render(). drawing.render(dc, one_tile); - for (SPObject *child = shown->firstChild() ; child != NULL; child = child->getNext() ) { - if (SP_IS_ITEM (child)) { + for (SPObject *child = shown->firstChild(); child != NULL; child = child->getNext()) { + if (SP_IS_ITEM(child)) { SP_ITEM(child)->invoke_hide(dkey); } } @@ -685,12 +670,12 @@ cairo_pattern_t* SPPattern::pattern_new(cairo_t *base_ct, Geom::OptRect const &b if (needs_opacity) { dc.popGroupToSource(); // pop raw pattern - dc.paint(opacity); // apply opacity + dc.paint(opacity); // apply opacity } cairo_pattern_t *cp = cairo_pattern_create_for_surface(pattern_surface.raw()); // Apply transformation to user space. Also compensate for oversampling. - ink_cairo_pattern_set_matrix(cp, ps2user.inverse() * pattern_surface.drawingTransform() ); + ink_cairo_pattern_set_matrix(cp, ps2user.inverse() * pattern_surface.drawingTransform()); cairo_pattern_set_extend(cp, CAIRO_EXTEND_REPEAT); diff --git a/src/sp-pattern.h b/src/sp-pattern.h index 34dd5a05b..145bb934e 100644 --- a/src/sp-pattern.h +++ b/src/sp-pattern.h @@ -1,9 +1,6 @@ -#ifndef SEEN_SP_PATTERN_H -#define SEEN_SP_PATTERN_H - -/* +/** @file * SVG <pattern> implementation - * + *//* * Author: * Lauris Kaplinski <lauris@kaplinski.com> * Abhishek Sharma @@ -13,95 +10,131 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#define SP_PATTERN(obj) (dynamic_cast<SPPattern*>((SPObject*)obj)) -#define SP_IS_PATTERN(obj) (dynamic_cast<const SPPattern*>((SPObject*)obj) != NULL) +#ifndef SEEN_SP_PATTERN_H +#define SEEN_SP_PATTERN_H -class SPPatternReference; -class SPItem; -typedef struct _GSList GSList; +#include <list> +#include <stddef.h> +#include <glibmm/ustring.h> +#include <sigc++/connection.h> #include "svg/svg-length.h" #include "sp-paint-server.h" #include "uri-references.h" #include "viewbox.h" -#include <sigc++/connection.h> +class SPPatternReference; +class SPItem; +namespace Inkscape { +namespace XML { + +class Node; +} +} + +#define SP_PATTERN(obj) (dynamic_cast<SPPattern *>((SPObject *)obj)) +#define SP_IS_PATTERN(obj) (dynamic_cast<const SPPattern *>((SPObject *)obj) != NULL) class SPPattern : public SPPaintServer, public SPViewBox { public: - SPPattern(); - virtual ~SPPattern(); + enum PatternUnits { UNITS_USERSPACEONUSE, UNITS_OBJECTBOUNDINGBOX }; + + SPPattern(); + virtual ~SPPattern(); /* Reference (href) */ - char *href; + Glib::ustring href; SPPatternReference *ref; - /* patternUnits and patternContentUnits attribute */ - unsigned int patternUnits : 1; - unsigned int patternUnits_set : 1; - unsigned int patternContentUnits : 1; - unsigned int patternContentUnits_set : 1; - /* patternTransform attribute */ - Geom::Affine patternTransform; - unsigned int patternTransform_set : 1; - /* Tile rectangle */ - SVGLength x; - SVGLength y; - SVGLength width; - SVGLength height; - - sigc::connection modified_connection; + gdouble x() const; + gdouble y() const; + gdouble width() const; + gdouble height() const; + Geom::OptRect viewbox() const; + SPPattern::PatternUnits patternUnits() const; + SPPattern::PatternUnits patternContentUnits() const; + Geom::Affine const &getTransform() const; + SPPattern *rootPattern(); // TODO: const + + SPPattern *clone_if_necessary(SPItem *item, const gchar *property); + void transform_multiply(Geom::Affine postmul, bool set); + + /** + * @brief create a new pattern in XML tree + * @return created pattern id + */ + static const gchar *produce(const std::vector<Inkscape::XML::Node *> &reprs, Geom::Rect bounds, + SPDocument *document, Geom::Affine transform, Geom::Affine move); bool isValid() const; - virtual cairo_pattern_t* pattern_new(cairo_t *ct, Geom::OptRect const &bbox, double opacity); + virtual cairo_pattern_t *pattern_new(cairo_t *ct, Geom::OptRect const &bbox, double opacity); protected: - virtual void build(SPDocument* doc, Inkscape::XML::Node* repr); - virtual void release(); - virtual void set(unsigned int key, const gchar* value); - virtual void update(SPCtx* ctx, unsigned int flags); - virtual void modified(unsigned int flags); + virtual void build(SPDocument *doc, Inkscape::XML::Node *repr); + virtual void release(); + virtual void set(unsigned int key, const gchar *value); + virtual void update(SPCtx *ctx, unsigned int flags); + virtual void modified(unsigned int flags); + +private: + bool _hasItemChildren() const; + void _getChildren(std::list<SPObject *> &l); + SPPattern *_chain() const; + + /** + Count how many times pattern is used by the styles of o and its descendants + */ + guint _countHrefs(SPObject *o) const; + + /** + Gets called when the pattern is reattached to another <pattern> + */ + void _onRefChanged(SPObject *old_ref, SPObject *ref); + + /** + Gets called when the referenced <pattern> is changed + */ + void _onRefModified(SPObject *ref, guint flags); + + /* patternUnits and patternContentUnits attribute */ + PatternUnits _pattern_units : 1; + bool _pattern_units_set : 1; + PatternUnits _pattern_content_units : 1; + bool _pattern_content_units_set : 1; + /* patternTransform attribute */ + Geom::Affine _pattern_transform; + bool _pattern_transform_set : 1; + /* Tile rectangle */ + SVGLength _x; + SVGLength _y; + SVGLength _width; + SVGLength _height; + + sigc::connection _modified_connection; }; class SPPatternReference : public Inkscape::URIReference { public: - SPPatternReference (SPObject *obj) : URIReference(obj) {} - SPPattern *getObject() const { + SPPatternReference(SPObject *obj) + : URIReference(obj) + { + } + + SPPattern *getObject() const + { return reinterpret_cast<SPPattern *>(URIReference::getObject()); } protected: - virtual bool _acceptObject(SPObject *obj) const { - return SP_IS_PATTERN (obj); + virtual bool _acceptObject(SPObject *obj) const + { + return SP_IS_PATTERN(obj); } }; -enum { - SP_PATTERN_UNITS_USERSPACEONUSE, - SP_PATTERN_UNITS_OBJECTBOUNDINGBOX -}; - -unsigned int pattern_users (SPPattern *pattern); -SPPattern *pattern_chain (SPPattern *pattern); -SPPattern *sp_pattern_clone_if_necessary (SPItem *item, SPPattern *pattern, const char *property); -void sp_pattern_transform_multiply (SPPattern *pattern, Geom::Affine postmul, bool set); - -const char *pattern_tile (const std::vector<Inkscape::XML::Node*> &reprs, Geom::Rect bounds, SPDocument *document, Geom::Affine transform, Geom::Affine move); - -SPPattern *pattern_getroot (SPPattern *pat); - -unsigned int pattern_patternUnits (SPPattern const *pat); -unsigned int pattern_patternContentUnits (SPPattern const *pat); -Geom::Affine const &pattern_patternTransform(SPPattern const *pat); -double pattern_x (SPPattern const *pat); -double pattern_y (SPPattern const *pat); -double pattern_width (SPPattern const *pat); -double pattern_height (SPPattern const *pat); -Geom::OptRect pattern_viewBox (SPPattern const *pat); - #endif // SEEN_SP_PATTERN_H /* diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt index 164d74156..fbf25d039 100644 --- a/src/ui/CMakeLists.txt +++ b/src/ui/CMakeLists.txt @@ -6,6 +6,7 @@ set(ui_SRC interface.cpp object-edit.cpp previewholder.cpp + selected-color.cpp shape-editor.cpp tool-factory.cpp tools-switch.cpp @@ -115,8 +116,14 @@ set(ui_SRC widget/anchor-selector.cpp widget/button.cpp widget/clipmaskicon.cpp + widget/color-entry.cpp + widget/color-icc-selector.cpp + widget/color-notebook.cpp widget/color-picker.cpp widget/color-preview.cpp + widget/color-scales.cpp + widget/color-slider.cpp + widget/color-wheel-selector.cpp widget/dock-item.cpp widget/dock.cpp widget/entity-entry.cpp @@ -175,6 +182,7 @@ set(ui_SRC previewable.h previewfillable.h previewholder.h + selected-color.h shape-editor.h tool-factory.h tools-switch.h @@ -288,8 +296,14 @@ set(ui_SRC widget/anchor-selector.h widget/attr-widget.h widget/button.h + widget/color-entry.h + widget/color-icc-selector.h + widget/color-notebook.h widget/color-picker.h widget/color-preview.h + widget/color-scales.h + widget/color-slider.h + widget/color-wheel-selector.h widget/combo-enums.h widget/dock-item.h widget/dock.h diff --git a/src/ui/Makefile_insert b/src/ui/Makefile_insert index f94cba4e9..bbfdb532c 100644 --- a/src/ui/Makefile_insert +++ b/src/ui/Makefile_insert @@ -19,6 +19,8 @@ ink_common_sources += \ ui/previewfillable.h \ ui/previewholder.cpp \ ui/previewholder.h \ + ui/selected-color.h \ + ui/selected-color.cpp \ ui/shape-editor.cpp \ ui/shape-editor.h \ ui/tool-factory.cpp \ diff --git a/src/ui/dialog/objects.cpp b/src/ui/dialog/objects.cpp index 781c6ef93..be04e7149 100644 --- a/src/ui/dialog/objects.cpp +++ b/src/ui/dialog/objects.cpp @@ -45,6 +45,7 @@ #include "style.h" #include "ui/tools-switch.h" #include "ui/icon-names.h" +#include "ui/selected-color.h" #include "ui/widget/imagetoggler.h" #include "ui/widget/layertypeicon.h" #include "ui/widget/insertordericon.h" @@ -53,7 +54,7 @@ #include "ui/tools/node-tool.h" #include "ui/tools/tool-base.h" #include "verbs.h" -#include "widgets/sp-color-notebook.h" +#include "ui/widget/color-notebook.h" #include "widgets/icon.h" #include "xml/node.h" #include "xml/node-observer.h" @@ -928,12 +929,12 @@ bool ObjectsPanel::_handleButtonEvent(GdkEventButton* event) //If the current item is not selected, store only it in the highlight source _storeHighlightTarget(iter); } - if (_colorSelector) + if (_selectedColor) { //Set up the color selector SPColor color; color.set( row[_model->_colHighlight] ); - _colorSelector->base->setColorAlpha(color, SP_RGBA32_A_F(row[_model->_colHighlight])); + _selectedColor->setColorAlpha(color, SP_RGBA32_A_F(row[_model->_colHighlight])); } //Show the color selector dialog _colorSelectorDialog.show(); @@ -1440,17 +1441,16 @@ void ObjectsPanel::_setExpanded(const Gtk::TreeModel::iterator& iter, const Gtk: * @param csel Color selector * @param cp Objects panel */ -void sp_highlight_picker_color_mod(SPColorSelector *csel, GObject * cp) +void ObjectsPanel::_highlightPickerColorMod() { SPColor color; float alpha = 0; - csel->base->getColorAlpha(color, alpha); + _selectedColor->colorAlpha(color, alpha); + guint32 rgba = color.toRGBA32( alpha ); - - ObjectsPanel *ptr = reinterpret_cast<ObjectsPanel *>(cp); //Set the highlight color for all items in the _highlight_target (all selected items) - for (std::vector<SPItem *>::iterator iter = ptr->_highlight_target.begin(); iter != ptr->_highlight_target.end(); ++iter) + for (std::vector<SPItem *>::iterator iter = _highlight_target.begin(); iter != _highlight_target.end(); ++iter) { SPItem * target = *iter; target->setHighlightColor(rgba); @@ -1922,18 +1922,16 @@ ObjectsPanel::ObjectsPanel() : _colorSelectorDialog.set_title (_("Select Highlight Color")); _colorSelectorDialog.set_border_width (4); _colorSelectorDialog.property_modal() = true; - _colorSelector = SP_COLOR_SELECTOR(sp_color_selector_new(SP_TYPE_COLOR_NOTEBOOK)); + _selectedColor.reset(new Inkscape::UI::SelectedColor); + Gtk::Widget *color_selector = Gtk::manage(new Inkscape::UI::Widget::ColorNotebook(*_selectedColor)); _colorSelectorDialog.get_vbox()->pack_start ( - *Glib::wrap(&_colorSelector->vbox), true, true, 0); + *color_selector, true, true, 0); - g_signal_connect(G_OBJECT(_colorSelector), "dragged", - G_CALLBACK(sp_highlight_picker_color_mod), (void *)this); - g_signal_connect(G_OBJECT(_colorSelector), "released", - G_CALLBACK(sp_highlight_picker_color_mod), (void *)this); - g_signal_connect(G_OBJECT(_colorSelector), "changed", - G_CALLBACK(sp_highlight_picker_color_mod), (void *)this); + _selectedColor->signal_dragged.connect(sigc::mem_fun(*this, &ObjectsPanel::_highlightPickerColorMod)); + _selectedColor->signal_released.connect(sigc::mem_fun(*this, &ObjectsPanel::_highlightPickerColorMod)); + _selectedColor->signal_changed.connect(sigc::mem_fun(*this, &ObjectsPanel::_highlightPickerColorMod)); - gtk_widget_show(GTK_WIDGET(_colorSelector)); + color_selector->show(); setDesktop( targetDesktop ); @@ -1951,7 +1949,6 @@ ObjectsPanel::~ObjectsPanel() { //Close the highlight selection dialog _colorSelectorDialog.hide(); - _colorSelector = NULL; //Set the desktop to null, which will disconnect all object watchers setDesktop(NULL); diff --git a/src/ui/dialog/objects.h b/src/ui/dialog/objects.h index 1842fea11..7a826d02e 100644 --- a/src/ui/dialog/objects.h +++ b/src/ui/dialog/objects.h @@ -16,6 +16,7 @@ # include <config.h> #endif +#include <boost/scoped_ptr.hpp> #include <gtkmm/box.h> #include <gtkmm/treeview.h> #include <gtkmm/treestore.h> @@ -36,6 +37,9 @@ struct SPColorSelector; namespace Inkscape { namespace UI { + +class SelectedColor; + namespace Dialog { @@ -166,8 +170,7 @@ private: Gtk::Alignment _blur_alignment; Gtk::Dialog _colorSelectorDialog; - SPColorSelector *_colorSelector; - + boost::scoped_ptr<Inkscape::UI::SelectedColor> _selectedColor; //Methods: @@ -233,7 +236,7 @@ private: void setupDialog(const Glib::ustring &title); - friend void sp_highlight_picker_color_mod(SPColorSelector *csel, GObject *cp); + void _highlightPickerColorMod(); }; diff --git a/src/ui/dialog/tags.cpp b/src/ui/dialog/tags.cpp index ed71c826f..f36e3f18d 100644 --- a/src/ui/dialog/tags.cpp +++ b/src/ui/dialog/tags.cpp @@ -51,7 +51,7 @@ #include "ui/tools/tool-base.h" //"event-context.h" #include "selection.h" //#include "dialogs/dialog-events.h" -#include "widgets/sp-color-notebook.h" +#include "ui/widget/color-notebook.h" #include "style.h" #include "filter-chemistry.h" #include "filters/blend.h" diff --git a/src/ui/selected-color.cpp b/src/ui/selected-color.cpp new file mode 100644 index 000000000..8c37ee7e0 --- /dev/null +++ b/src/ui/selected-color.cpp @@ -0,0 +1,163 @@ +/** @file + * Color selected in color selector widget. + * This file was created during the refactoring of SPColorSelector + *//* + * Authors: + * bulia byak <buliabyak@users.sf.net> + * Jon A. Cruz <jon@joncruz.org> + * Tomasz Boczkowski <penginsbacon@gmail.com> + * + * Copyright (C) 2014 Authors + * Released under GNU GPL, read the file 'COPYING' for more information + */ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <glibmm/ustring.h> +#include <cmath> + +#include "svg/svg-icc-color.h" +#include "ui/selected-color.h" + +namespace Inkscape { +namespace UI { + +double const SelectedColor::_EPSILON = 1e-4; + +SelectedColor::SelectedColor() + : _color(0) + , _alpha(1.0) + , _held(false) + , _virgin(true) + , _updating(false) +{ + +} + +SelectedColor::~SelectedColor() { + +} + +void SelectedColor::setColor(SPColor const &color) +{ + setColorAlpha( color, _alpha); +} + +SPColor SelectedColor::color() const +{ + return _color; +} + +void SelectedColor::setAlpha(gfloat alpha) +{ + g_return_if_fail( ( 0.0 <= alpha ) && ( alpha <= 1.0 ) ); + setColorAlpha( _color, alpha); +} + +gfloat SelectedColor::alpha() const +{ + return _alpha; +} + +void SelectedColor::setValue(guint32 value) +{ + SPColor color(value); + gfloat alpha = SP_RGBA32_A_F(value); + setColorAlpha(color, alpha); +} + +guint32 SelectedColor::value() const +{ + return color().toRGBA32(_alpha); +} + +void SelectedColor::setColorAlpha(SPColor const &color, gfloat alpha, bool emit_signal) +{ +#ifdef DUMP_CHANGE_INFO + g_message("SelectedColor::setColorAlpha( this=%p, %f, %f, %f, %s, %f, %s)", this, color.v.c[0], color.v.c[1], color.v.c[2], (color.icc?color.icc->colorProfile.c_str():"<null>"), alpha, (emit_signal?"YES":"no")); +#endif + g_return_if_fail( ( 0.0 <= alpha ) && ( alpha <= 1.0 ) ); + + if (_updating) { + return; + } + +#ifdef DUMP_CHANGE_INFO + g_message("---- SelectedColor::setColorAlpha virgin:%s !close:%s alpha is:%s", + (_virgin?"YES":"no"), + (!color.isClose( _color, _EPSILON )?"YES":"no"), + ((fabs((_alpha) - (alpha)) >= _EPSILON )?"YES":"no") + ); +#endif + + if ( _virgin || !color.isClose( _color, _EPSILON ) || + (fabs((_alpha) - (alpha)) >= _EPSILON )) { + + _virgin = false; + + _color = color; + _alpha = alpha; + + if (emit_signal) + { + _updating = true; + if (_held) { + signal_dragged.emit(); + } else { + signal_changed.emit(); + } + _updating = false; + } + +#ifdef DUMP_CHANGE_INFO + } else { + g_message("++++ SelectedColor::setColorAlpha color:%08x ==> _color:%08X isClose:%s", color.toRGBA32(alpha), _color.toRGBA32(_alpha), + (color.isClose( _color, _EPSILON )?"YES":"no")); +#endif + } +} + +void SelectedColor::colorAlpha(SPColor &color, gfloat &alpha) const { + color = _color; + alpha = _alpha; +} + +void SelectedColor::setHeld(bool held) { + if (_updating) { + return; + } + bool grabbed = held && !_held; + bool released = !held && _held; + + _held = held; + + _updating = true; + if (grabbed) { + signal_grabbed.emit(); + } + + if (released) { + signal_released.emit(); + signal_changed.emit(); + } + _updating = false; +} + +void SelectedColor::preserveICC() { + _color.icc = _color.icc ? new SVGICCColor(*_color.icc) : 0; +} + +} +} + +/* + 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 : diff --git a/src/ui/selected-color.h b/src/ui/selected-color.h new file mode 100644 index 000000000..e9e702d43 --- /dev/null +++ b/src/ui/selected-color.h @@ -0,0 +1,96 @@ +/** @file + * Color selected in color selector widget. + * This file was created during the refactoring of SPColorSelector + *//* + * Authors: + * bulia byak <buliabyak@users.sf.net> + * Jon A. Cruz <jon@joncruz.org> + * Tomasz Boczkowski <penginsbacon@gmail.com> + * + * Copyright (C) 2014 Authors + * Released under GNU GPL, read the file 'COPYING' for more information + */ +#ifndef SEEN_SELECTED_COLOR +#define SEEN_SELECTED_COLOR + +#include <sigc++/signal.h> +#include "color.h" + +namespace Gtk +{ + class Widget; +} + +namespace Inkscape { +namespace UI { + +class SelectedColor { +public: + SelectedColor(); + virtual ~SelectedColor(); + + void setColor(SPColor const &color); + SPColor color() const; + + void setAlpha(gfloat alpha); + gfloat alpha() const; + + void setValue(guint32 value); + guint32 value() const; + + void setColorAlpha(SPColor const &color, gfloat alpha, bool emit_signal = true); + void colorAlpha(SPColor &color, gfloat &alpha) const; + + void setHeld(bool held); + + void preserveICC(); + + sigc::signal<void> signal_grabbed; + sigc::signal<void> signal_dragged; + sigc::signal<void> signal_released; + sigc::signal<void> signal_changed; +private: + // By default, disallow copy constructor and assignment operator + SelectedColor(SelectedColor const &obj); + SelectedColor& operator=(SelectedColor const &obj); + + SPColor _color; + /** + * Color alpha value guaranteed to be in [0, 1]. + */ + gfloat _alpha; + + bool _held; + /** + * This flag is true if no color is set yet + */ + bool _virgin; + + bool _updating; + + static double const _EPSILON; +}; + +class ColorSelectorFactory { +public: + virtual ~ColorSelectorFactory() { + } + + virtual Gtk::Widget* createWidget(SelectedColor &color) const = 0; + virtual Glib::ustring modeName() const = 0; +}; + +} +} + +#endif +/* + 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 : diff --git a/src/ui/widget/Makefile_insert b/src/ui/widget/Makefile_insert index 305076a9d..eb98e6872 100644 --- a/src/ui/widget/Makefile_insert +++ b/src/ui/widget/Makefile_insert @@ -6,10 +6,22 @@ ink_common_sources += \ ui/widget/attr-widget.h \ ui/widget/button.h \ ui/widget/button.cpp \ + ui/widget/color-entry.cpp \ + ui/widget/color-entry.h \ + ui/widget/color-icc-selector.cpp \ + ui/widget/color-icc-selector.h \ + ui/widget/color-notebook.cpp \ + ui/widget/color-notebook.h \ + ui/widget/color-wheel-selector.cpp \ + ui/widget/color-wheel-selector.h \ ui/widget/color-picker.cpp \ ui/widget/color-picker.h \ ui/widget/color-preview.cpp \ ui/widget/color-preview.h \ + ui/widget/color-slider.cpp \ + ui/widget/color-slider.h \ + ui/widget/color-scales.cpp \ + ui/widget/color-scales.h \ ui/widget/combo-enums.h \ ui/widget/dock.h \ ui/widget/dock.cpp \ diff --git a/src/ui/widget/color-entry.cpp b/src/ui/widget/color-entry.cpp new file mode 100644 index 000000000..473d7de65 --- /dev/null +++ b/src/ui/widget/color-entry.cpp @@ -0,0 +1,104 @@ +/** @file + * Entry widget for typing color value in css form + *//* + * Authors: + * Tomasz Boczkowski <penginsbacon@gmail.com> + * + * Copyright (C) 2014 Authors + * Released under GNU GPL, read the file 'COPYING' for more information + */ +#include <glibmm.h> +#include <glibmm/i18n.h> +#include <iomanip> + +#include "color-entry.h" + +namespace Inkscape { +namespace UI { +namespace Widget { + +ColorEntry::ColorEntry(SelectedColor &color) + : _color(color) + , _updating(false) +{ + _color_changed_connection = color.signal_changed.connect(sigc::mem_fun(this, &ColorEntry::_onColorChanged)); + _color_dragged_connection = color.signal_dragged.connect(sigc::mem_fun(this, &ColorEntry::_onColorChanged)); + _onColorChanged(); + + set_max_length(8); + set_width_chars(8); + set_tooltip_text(_("Hexadecimal RGBA value of the color")); +} + +ColorEntry::~ColorEntry() +{ + _color_changed_connection.disconnect(); + _color_dragged_connection.disconnect(); +} + +void ColorEntry::on_changed() +{ + if (_updating) { + return; + } + + Glib::ustring text = get_text(); + bool changed = false; + + // Coerce the value format to eight hex digits + if (!text.empty() && text[0] == '#') { + changed = true; + text.erase(0, 1); + if (text.size() == 6) { + // it was a standard RGB hex + unsigned int alpha = SP_COLOR_F_TO_U(_color.alpha()); + text += Glib::ustring::format(std::hex, std::setw(2), std::setfill(L'0'), alpha); + } + } + + gchar *str = g_strdup(text.c_str()); + gchar *end = 0; + guint64 rgba = g_ascii_strtoull(str, &end, 16); + if (end != str) { + ptrdiff_t len = end - str; + if (len < 8) { + rgba = rgba << (4 * (8 - len)); + } + if (changed) { + set_text(str); + } + SPColor color(rgba); + _color.setColorAlpha(color, SP_RGBA32_A_F(rgba)); + } + g_free(str); +} + + +void ColorEntry::_onColorChanged() +{ + SPColor color = _color.color(); + gdouble alpha = _color.alpha(); + + guint32 rgba = color.toRGBA32(alpha); + Glib::ustring text = Glib::ustring::format(std::hex, std::setw(8), std::setfill(L'0'), rgba); + + Glib::ustring old_text = get_text(); + if (old_text != text) { + _updating = true; + set_text(text); + _updating = false; + } +} +} +} +} +/* + 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 : diff --git a/src/ui/widget/color-entry.h b/src/ui/widget/color-entry.h new file mode 100644 index 000000000..cd7d6164a --- /dev/null +++ b/src/ui/widget/color-entry.h @@ -0,0 +1,53 @@ +/** @file + * Entry widget for typing color value in css form + *//* + * Authors: + * Tomasz Boczkowski <penginsbacon@gmail.com> + * + * Copyright (C) 2014 Authors + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef SEEN_COLOR_ENTRY_H +#define SEEN_COLOR_ENTRY_H_ + +#include <gtkmm/entry.h> +#include "ui/selected-color.h" + +namespace Inkscape { +namespace UI { +namespace Widget { + +class ColorEntry : public Gtk::Entry +{ +public: + ColorEntry(SelectedColor &color); + virtual ~ColorEntry(); + +protected: + void on_changed(); + +private: + void _onColorChanged(); + + SelectedColor &_color; + sigc::connection _color_changed_connection; + sigc::connection _color_dragged_connection; + bool _updating; +}; + +} +} +} + +#endif +/* + 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 : diff --git a/src/ui/widget/color-icc-selector.cpp b/src/ui/widget/color-icc-selector.cpp new file mode 100644 index 000000000..1c31ae33a --- /dev/null +++ b/src/ui/widget/color-icc-selector.cpp @@ -0,0 +1,1079 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <math.h> +#include <gtkmm/adjustment.h> +#include <glibmm/i18n.h> + +#include <gtk/gtk.h> +#include <map> +#include <set> +#include <vector> + +#include "ui/dialog-events.h" +#include "ui/widget/color-icc-selector.h" +#include "ui/widget/color-scales.h" +#include "ui/widget/color-slider.h" +#include "svg/svg-icc-color.h" +#include "colorspace.h" +#include "document.h" +#include "inkscape.h" +#include "profile-manager.h" +#include "widgets/gradient-vector.h" + +#define noDEBUG_LCMS + +#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) +#include "color-profile.h" +#include "cms-system.h" +#include "color-profile-cms-fns.h" + +#ifdef DEBUG_LCMS +#include "preferences.h" +#endif // DEBUG_LCMS +#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) + +#ifdef DEBUG_LCMS +extern guint update_in_progress; +#define DEBUG_MESSAGE(key, ...) \ + { \ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); \ + bool dump = prefs->getBool("/options/scislac/" #key); \ + bool dumpD = prefs->getBool("/options/scislac/" #key "D"); \ + bool dumpD2 = prefs->getBool("/options/scislac/" #key "D2"); \ + dumpD && = ((update_in_progress == 0) || dumpD2); \ + if (dump) { \ + g_message(__VA_ARGS__); \ + } \ + if (dumpD) { \ + GtkWidget *dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO, \ + GTK_BUTTONS_OK, __VA_ARGS__); \ + g_signal_connect_swapped(dialog, "response", G_CALLBACK(gtk_widget_destroy), dialog); \ + gtk_widget_show_all(dialog); \ + } \ + } +#endif // DEBUG_LCMS + + +#define XPAD 4 +#define YPAD 1 + +namespace { + +size_t maxColorspaceComponentCount = 0; + +#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) + +/** + * Internal variable to track all known colorspaces. + */ +std::set<cmsUInt32Number> knownColorspaces; + +#endif + + +/** + * Simple helper to allow bitwise or on GtkAttachOptions. + */ +GtkAttachOptions operator|(GtkAttachOptions lhs, GtkAttachOptions rhs) +{ + return static_cast<GtkAttachOptions>(static_cast<int>(lhs) | static_cast<int>(rhs)); +} + +/** + * Helper function to handle GTK2/GTK3 attachment #ifdef code. + */ +void attachToGridOrTable(GtkWidget *parent, GtkWidget *child, guint left, guint top, guint width, guint height, + bool hexpand = false, bool centered = false, guint xpadding = XPAD, guint ypadding = YPAD) +{ +#if GTK_CHECK_VERSION(3, 0, 0) + #if GTK_CHECK_VERSION(3, 12, 0) + gtk_widget_set_margin_start(child, xpadding); + gtk_widget_set_margin_end(child, xpadding); + #else + gtk_widget_set_margin_left(child, xpadding); + gtk_widget_set_margin_right(child, xpadding); + #endif + + gtk_widget_set_margin_top(child, ypadding); + gtk_widget_set_margin_bottom(child, ypadding); + if (hexpand) { + gtk_widget_set_hexpand(child, TRUE); + } + if (centered) { + gtk_widget_set_halign(child, GTK_ALIGN_CENTER); + gtk_widget_set_valign(child, GTK_ALIGN_CENTER); + } + gtk_grid_attach(GTK_GRID(parent), child, left, top, width, height); +#else + GtkAttachOptions xoptions = + centered ? static_cast<GtkAttachOptions>(0) : hexpand ? (GTK_EXPAND | GTK_FILL) : GTK_FILL; + GtkAttachOptions yoptions = centered ? static_cast<GtkAttachOptions>(0) : GTK_FILL; + + gtk_table_attach(GTK_TABLE(parent), child, left, left + width, top, top + height, xoptions, yoptions, xpadding, + ypadding); +#endif +} + +} // namespace + +/* +icSigRgbData +icSigCmykData +icSigCmyData +*/ +#define SPACE_ID_RGB 0 +#define SPACE_ID_CMY 1 +#define SPACE_ID_CMYK 2 + + +#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) +static cmsUInt16Number *getScratch() +{ + // bytes per pixel * input channels * width + static cmsUInt16Number *scritch = static_cast<cmsUInt16Number *>(g_new(cmsUInt16Number, 4 * 1024)); + + return scritch; +} + +colorspace::Component::Component() + : name() + , tip() + , scale(1) +{ +} + +colorspace::Component::Component(std::string const &name, std::string const &tip, guint scale) + : name(name) + , tip(tip) + , scale(scale) +{ +} + +std::vector<colorspace::Component> colorspace::getColorSpaceInfo(uint32_t space) +{ + static std::map<cmsUInt32Number, std::vector<Component> > sets; + if (sets.empty()) { + sets[cmsSigXYZData].push_back(Component("_X", "X", 2)); // TYPE_XYZ_16 + sets[cmsSigXYZData].push_back(Component("_Y", "Y", 1)); + sets[cmsSigXYZData].push_back(Component("_Z", "Z", 2)); + + sets[cmsSigLabData].push_back(Component("_L", "L", 100)); // TYPE_Lab_16 + sets[cmsSigLabData].push_back(Component("_a", "a", 256)); + sets[cmsSigLabData].push_back(Component("_b", "b", 256)); + + // cmsSigLuvData + + sets[cmsSigYCbCrData].push_back(Component("_Y", "Y", 1)); // TYPE_YCbCr_16 + sets[cmsSigYCbCrData].push_back(Component("C_b", "Cb", 1)); + sets[cmsSigYCbCrData].push_back(Component("C_r", "Cr", 1)); + + sets[cmsSigYxyData].push_back(Component("_Y", "Y", 1)); // TYPE_Yxy_16 + sets[cmsSigYxyData].push_back(Component("_x", "x", 1)); + sets[cmsSigYxyData].push_back(Component("y", "y", 1)); + + sets[cmsSigRgbData].push_back(Component(_("_R:"), _("Red"), 1)); // TYPE_RGB_16 + sets[cmsSigRgbData].push_back(Component(_("_G:"), _("Green"), 1)); + sets[cmsSigRgbData].push_back(Component(_("_B:"), _("Blue"), 1)); + + sets[cmsSigGrayData].push_back(Component(_("G:"), _("Gray"), 1)); // TYPE_GRAY_16 + + sets[cmsSigHsvData].push_back(Component(_("_H:"), _("Hue"), 360)); // TYPE_HSV_16 + sets[cmsSigHsvData].push_back(Component(_("_S:"), _("Saturation"), 1)); + sets[cmsSigHsvData].push_back(Component("_V:", "Value", 1)); + + sets[cmsSigHlsData].push_back(Component(_("_H:"), _("Hue"), 360)); // TYPE_HLS_16 + sets[cmsSigHlsData].push_back(Component(_("_L:"), _("Lightness"), 1)); + sets[cmsSigHlsData].push_back(Component(_("_S:"), _("Saturation"), 1)); + + sets[cmsSigCmykData].push_back(Component(_("_C:"), _("Cyan"), 1)); // TYPE_CMYK_16 + sets[cmsSigCmykData].push_back(Component(_("_M:"), _("Magenta"), 1)); + sets[cmsSigCmykData].push_back(Component(_("_Y:"), _("Yellow"), 1)); + sets[cmsSigCmykData].push_back(Component(_("_K:"), _("Black"), 1)); + + sets[cmsSigCmyData].push_back(Component(_("_C:"), _("Cyan"), 1)); // TYPE_CMY_16 + sets[cmsSigCmyData].push_back(Component(_("_M:"), _("Magenta"), 1)); + sets[cmsSigCmyData].push_back(Component(_("_Y:"), _("Yellow"), 1)); + + for (std::map<cmsUInt32Number, std::vector<Component> >::iterator it = sets.begin(); it != sets.end(); ++it) { + knownColorspaces.insert(it->first); + maxColorspaceComponentCount = std::max(maxColorspaceComponentCount, it->second.size()); + } + } + + std::vector<Component> target; + + if (sets.find(space) != sets.end()) { + target = sets[space]; + } + return target; +} + + +std::vector<colorspace::Component> colorspace::getColorSpaceInfo(Inkscape::ColorProfile *prof) +{ + return getColorSpaceInfo(asICColorSpaceSig(prof->getColorSpace())); +} + +#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) + +namespace Inkscape { +namespace UI { +namespace Widget { + +/** + * Class containing the parts for a single color component's UI presence. + */ +class ComponentUI { + public: + ComponentUI() + : _component() + , _adj(0) + , _slider(0) + , _btn(0) + , _label(0) + , _map(0) + { + } + + ComponentUI(colorspace::Component const &component) + : _component(component) + , _adj(0) + , _slider(0) + , _btn(0) + , _label(0) + , _map(0) + { + } + + colorspace::Component _component; + GtkAdjustment *_adj; // Component adjustment + Inkscape::UI::Widget::ColorSlider *_slider; + GtkWidget *_btn; // spinbutton + GtkWidget *_label; // Label + guchar *_map; +}; + +/** + * Class that implements the internals of the selector. + */ +class ColorICCSelectorImpl { + public: + ColorICCSelectorImpl(ColorICCSelector *owner, SelectedColor &color); + + ~ColorICCSelectorImpl(); + + static void _adjustmentChanged(GtkAdjustment *adjustment, ColorICCSelectorImpl *cs); + + void _sliderGrabbed(); + void _sliderReleased(); + void _sliderChanged(); + + static void _profileSelected(GtkWidget *src, gpointer data); + static void _fixupHit(GtkWidget *src, gpointer data); + +#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) + void _setProfile(SVGICCColor *profile); + void _switchToProfile(gchar const *name); +#endif + void _updateSliders(gint ignore); + void _profilesChanged(std::string const &name); + + ColorICCSelector *_owner; + SelectedColor &_color; + + gboolean _updating : 1; + gboolean _dragging : 1; + + guint32 _fixupNeeded; + GtkWidget *_fixupBtn; + GtkWidget *_profileSel; + + std::vector<ComponentUI> _compUI; + + GtkAdjustment *_adj; // Channel adjustment + Inkscape::UI::Widget::ColorSlider *_slider; + GtkWidget *_sbtn; // Spinbutton + GtkWidget *_label; // Label + +#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) + std::string _profileName; + Inkscape::ColorProfile *_prof; + guint _profChannelCount; + gulong _profChangedID; +#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) +}; + + + +const gchar *ColorICCSelector::MODE_NAME = N_("CMS"); + +ColorICCSelector::ColorICCSelector(SelectedColor &color) + : _impl(NULL) +{ + _impl = new ColorICCSelectorImpl(this, color); + init(); + color.signal_changed.connect(sigc::mem_fun(this, &ColorICCSelector::_colorChanged)); + // color.signal_dragged.connect(sigc::mem_fun(this, &ColorICCSelector::_colorChanged)); +} + +ColorICCSelector::~ColorICCSelector() +{ + if (_impl) { + delete _impl; + _impl = 0; + } +} + + + +ColorICCSelectorImpl::ColorICCSelectorImpl(ColorICCSelector *owner, SelectedColor &color) + : _owner(owner) + , _color(color) + , _updating(FALSE) + , _dragging(FALSE) + , _fixupNeeded(0) + , _fixupBtn(0) + , _profileSel(0) + , _compUI() + , _adj(0) + , _slider(0) + , _sbtn(0) + , _label(0) +#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) + , _profileName() + , _prof(0) + , _profChannelCount(0) + , _profChangedID(0) +#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) +{ +} + +ColorICCSelectorImpl::~ColorICCSelectorImpl() +{ + _adj = 0; + _sbtn = 0; + _label = 0; +} + +void ColorICCSelector::init() +{ + gint row = 0; + + _impl->_updating = FALSE; + _impl->_dragging = FALSE; + + GtkWidget *t = GTK_WIDGET(gobj()); + + _impl->_compUI.clear(); + + // Create components + row = 0; + + + _impl->_fixupBtn = gtk_button_new_with_label(_("Fix")); + g_signal_connect(G_OBJECT(_impl->_fixupBtn), "clicked", G_CALLBACK(ColorICCSelectorImpl::_fixupHit), + (gpointer)_impl); + gtk_widget_set_sensitive(_impl->_fixupBtn, FALSE); + gtk_widget_set_tooltip_text(_impl->_fixupBtn, _("Fix RGB fallback to match icc-color() value.")); + // gtk_misc_set_alignment( GTK_MISC (_impl->_fixupBtn), 1.0, 0.5 ); + gtk_widget_show(_impl->_fixupBtn); + + attachToGridOrTable(t, _impl->_fixupBtn, 0, row, 1, 1); + + // Combobox and store with 2 columns : label (0) and full name (1) + GtkListStore *store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING); + _impl->_profileSel = gtk_combo_box_new_with_model(GTK_TREE_MODEL(store)); + + GtkCellRenderer *renderer = gtk_cell_renderer_text_new(); + gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(_impl->_profileSel), renderer, TRUE); + gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(_impl->_profileSel), renderer, "text", 0, NULL); + + GtkTreeIter iter; + gtk_list_store_append(store, &iter); + gtk_list_store_set(store, &iter, 0, _("<none>"), 1, _("<none>"), -1); + + gtk_widget_show(_impl->_profileSel); + gtk_combo_box_set_active(GTK_COMBO_BOX(_impl->_profileSel), 0); + + attachToGridOrTable(t, _impl->_profileSel, 1, row, 1, 1); + +#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) + _impl->_profChangedID = g_signal_connect(G_OBJECT(_impl->_profileSel), "changed", + G_CALLBACK(ColorICCSelectorImpl::_profileSelected), (gpointer)_impl); +#else + gtk_widget_set_sensitive(_impl->_profileSel, false); +#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) + + + row++; + +// populate the data for colorspaces and channels: +#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) + std::vector<colorspace::Component> things = colorspace::getColorSpaceInfo(cmsSigRgbData); +#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) + + for (size_t i = 0; i < maxColorspaceComponentCount; i++) { +#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) + if (i < things.size()) { + _impl->_compUI.push_back(ComponentUI(things[i])); + } + else { + _impl->_compUI.push_back(ComponentUI()); + } + + std::string labelStr = (i < things.size()) ? things[i].name.c_str() : ""; +#else + _impl->_compUI.push_back(ComponentUI()); + + std::string labelStr = "."; +#endif + + _impl->_compUI[i]._label = gtk_label_new_with_mnemonic(labelStr.c_str()); + gtk_misc_set_alignment(GTK_MISC(_impl->_compUI[i]._label), 1.0, 0.5); + gtk_widget_show(_impl->_compUI[i]._label); + gtk_widget_set_no_show_all(_impl->_compUI[i]._label, TRUE); + + attachToGridOrTable(t, _impl->_compUI[i]._label, 0, row, 1, 1); + + // Adjustment + guint scaleValue = _impl->_compUI[i]._component.scale; + gdouble step = static_cast<gdouble>(scaleValue) / 100.0; + gdouble page = static_cast<gdouble>(scaleValue) / 10.0; + gint digits = (step > 0.9) ? 0 : 2; + _impl->_compUI[i]._adj = GTK_ADJUSTMENT(gtk_adjustment_new(0.0, 0.0, scaleValue, step, page, page)); + + // Slider + _impl->_compUI[i]._slider = + Gtk::manage(new Inkscape::UI::Widget::ColorSlider(Glib::wrap(_impl->_compUI[i]._adj, true))); +#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) + _impl->_compUI[i]._slider->set_tooltip_text((i < things.size()) ? things[i].tip.c_str() : ""); +#else + _impl->_compUI[i]._slider->set_tooltip_text("."); +#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) + _impl->_compUI[i]._slider->show(); + _impl->_compUI[i]._slider->set_no_show_all(); + + attachToGridOrTable(t, _impl->_compUI[i]._slider->gobj(), 1, row, 1, 1, true); + + _impl->_compUI[i]._btn = gtk_spin_button_new(_impl->_compUI[i]._adj, step, digits); +#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) + gtk_widget_set_tooltip_text(_impl->_compUI[i]._btn, (i < things.size()) ? things[i].tip.c_str() : ""); +#else + gtk_widget_set_tooltip_text(_impl->_compUI[i]._btn, "."); +#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) + sp_dialog_defocus_on_enter(_impl->_compUI[i]._btn); + gtk_label_set_mnemonic_widget(GTK_LABEL(_impl->_compUI[i]._label), _impl->_compUI[i]._btn); + gtk_widget_show(_impl->_compUI[i]._btn); + gtk_widget_set_no_show_all(_impl->_compUI[i]._btn, TRUE); + + attachToGridOrTable(t, _impl->_compUI[i]._btn, 2, row, 1, 1, false, true); + + _impl->_compUI[i]._map = g_new(guchar, 4 * 1024); + memset(_impl->_compUI[i]._map, 0x0ff, 1024 * 4); + + + // Signals + g_signal_connect(G_OBJECT(_impl->_compUI[i]._adj), "value_changed", + G_CALLBACK(ColorICCSelectorImpl::_adjustmentChanged), _impl); + + _impl->_compUI[i]._slider->signal_grabbed.connect(sigc::mem_fun(_impl, &ColorICCSelectorImpl::_sliderGrabbed)); + _impl->_compUI[i]._slider->signal_released.connect( + sigc::mem_fun(_impl, &ColorICCSelectorImpl::_sliderReleased)); + _impl->_compUI[i]._slider->signal_value_changed.connect( + sigc::mem_fun(_impl, &ColorICCSelectorImpl::_sliderChanged)); + + row++; + } + + // Label + _impl->_label = gtk_label_new_with_mnemonic(_("_A:")); + gtk_misc_set_alignment(GTK_MISC(_impl->_label), 1.0, 0.5); + gtk_widget_show(_impl->_label); + + attachToGridOrTable(t, _impl->_label, 0, row, 1, 1); + + // Adjustment + _impl->_adj = GTK_ADJUSTMENT(gtk_adjustment_new(0.0, 0.0, 255.0, 1.0, 10.0, 10.0)); + + // Slider + _impl->_slider = Gtk::manage(new Inkscape::UI::Widget::ColorSlider(Glib::wrap(_impl->_adj, true))); + _impl->_slider->set_tooltip_text(_("Alpha (opacity)")); + _impl->_slider->show(); + + attachToGridOrTable(t, _impl->_slider->gobj(), 1, row, 1, 1, true); + + _impl->_slider->setColors(SP_RGBA32_F_COMPOSE(1.0, 1.0, 1.0, 0.0), SP_RGBA32_F_COMPOSE(1.0, 1.0, 1.0, 0.5), + SP_RGBA32_F_COMPOSE(1.0, 1.0, 1.0, 1.0)); + + + // Spinbutton + _impl->_sbtn = gtk_spin_button_new(GTK_ADJUSTMENT(_impl->_adj), 1.0, 0); + gtk_widget_set_tooltip_text(_impl->_sbtn, _("Alpha (opacity)")); + sp_dialog_defocus_on_enter(_impl->_sbtn); + gtk_label_set_mnemonic_widget(GTK_LABEL(_impl->_label), _impl->_sbtn); + gtk_widget_show(_impl->_sbtn); + + attachToGridOrTable(t, _impl->_sbtn, 2, row, 1, 1, false, true); + + // Signals + g_signal_connect(G_OBJECT(_impl->_adj), "value_changed", G_CALLBACK(ColorICCSelectorImpl::_adjustmentChanged), + _impl); + + _impl->_slider->signal_grabbed.connect(sigc::mem_fun(_impl, &ColorICCSelectorImpl::_sliderGrabbed)); + _impl->_slider->signal_released.connect(sigc::mem_fun(_impl, &ColorICCSelectorImpl::_sliderReleased)); + _impl->_slider->signal_value_changed.connect(sigc::mem_fun(_impl, &ColorICCSelectorImpl::_sliderChanged)); + + gtk_widget_show(t); +} + +void ColorICCSelectorImpl::_fixupHit(GtkWidget * /*src*/, gpointer data) +{ + ColorICCSelectorImpl *self = reinterpret_cast<ColorICCSelectorImpl *>(data); + gtk_widget_set_sensitive(self->_fixupBtn, FALSE); + self->_adjustmentChanged(self->_compUI[0]._adj, self); +} + +#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) +void ColorICCSelectorImpl::_profileSelected(GtkWidget * /*src*/, gpointer data) +{ + ColorICCSelectorImpl *self = reinterpret_cast<ColorICCSelectorImpl *>(data); + + GtkTreeIter iter; + if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(self->_profileSel), &iter)) { + GtkTreeModel *store = gtk_combo_box_get_model(GTK_COMBO_BOX(self->_profileSel)); + gchar *name = 0; + + gtk_tree_model_get(store, &iter, 1, &name, -1); + self->_switchToProfile(name); + gtk_widget_set_tooltip_text(self->_profileSel, name); + + if (name) { + g_free(name); + } + } +} +#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) + +#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) +void ColorICCSelectorImpl::_switchToProfile(gchar const *name) +{ + bool dirty = false; + SPColor tmp(_color.color()); + + if (name) { + if (tmp.icc && tmp.icc->colorProfile == name) { +#ifdef DEBUG_LCMS + g_message("Already at name [%s]", name); +#endif // DEBUG_LCMS + } + else { +#ifdef DEBUG_LCMS + g_message("Need to switch to profile [%s]", name); +#endif // DEBUG_LCMS + if (tmp.icc) { + tmp.icc->colors.clear(); + } + else { + tmp.icc = new SVGICCColor(); + } + tmp.icc->colorProfile = name; + Inkscape::ColorProfile *newProf = SP_ACTIVE_DOCUMENT->profileManager->find(name); + if (newProf) { + cmsHTRANSFORM trans = newProf->getTransfFromSRGB8(); + if (trans) { + guint32 val = _color.color().toRGBA32(0); + guchar pre[4] = { + static_cast<guchar>(SP_RGBA32_R_U(val)), + static_cast<guchar>(SP_RGBA32_G_U(val)), + static_cast<guchar>(SP_RGBA32_B_U(val)), + 255}; +#ifdef DEBUG_LCMS + g_message("Shoving in [%02x] [%02x] [%02x]", pre[0], pre[1], pre[2]); +#endif // DEBUG_LCMS + cmsUInt16Number post[4] = { 0, 0, 0, 0 }; + cmsDoTransform(trans, pre, post, 1); +#ifdef DEBUG_LCMS + g_message("got on out [%04x] [%04x] [%04x] [%04x]", post[0], post[1], post[2], post[3]); +#endif // DEBUG_LCMS +#if HAVE_LIBLCMS1 + guint count = _cmsChannelsOf(asICColorSpaceSig(newProf->getColorSpace())); +#elif HAVE_LIBLCMS2 + guint count = cmsChannelsOf(asICColorSpaceSig(newProf->getColorSpace())); +#endif + + std::vector<colorspace::Component> things = + colorspace::getColorSpaceInfo(asICColorSpaceSig(newProf->getColorSpace())); + + for (guint i = 0; i < count; i++) { + gdouble val = + (((gdouble)post[i]) / 65535.0) * (gdouble)((i < things.size()) ? things[i].scale : 1); +#ifdef DEBUG_LCMS + g_message(" scaled %d by %d to be %f", i, ((i < things.size()) ? things[i].scale : 1), val); +#endif // DEBUG_LCMS + tmp.icc->colors.push_back(val); + } + cmsHTRANSFORM retrans = newProf->getTransfToSRGB8(); + if (retrans) { + cmsDoTransform(retrans, post, pre, 1); +#ifdef DEBUG_LCMS + g_message(" back out [%02x] [%02x] [%02x]", pre[0], pre[1], pre[2]); +#endif // DEBUG_LCMS + tmp.set(SP_RGBA32_U_COMPOSE(pre[0], pre[1], pre[2], 0xff)); + } + } + } + dirty = true; + } + } + else { +#ifdef DEBUG_LCMS + g_message("NUKE THE ICC"); +#endif // DEBUG_LCMS + if (tmp.icc) { + delete tmp.icc; + tmp.icc = 0; + dirty = true; + _fixupHit(0, this); + } + else { +#ifdef DEBUG_LCMS + g_message("No icc to nuke"); +#endif // DEBUG_LCMS + } + } + + if (dirty) { +#ifdef DEBUG_LCMS + g_message("+----------------"); + g_message("+ new color is [%s]", tmp.toString().c_str()); +#endif // DEBUG_LCMS + _setProfile(tmp.icc); + //_adjustmentChanged( _compUI[0]._adj, SP_COLOR_ICC_SELECTOR(_csel) ); + _color.setColor(tmp); +#ifdef DEBUG_LCMS + g_message("+_________________"); +#endif // DEBUG_LCMS + } +} +#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) + +#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) +void ColorICCSelectorImpl::_profilesChanged(std::string const &name) +{ + GtkComboBox *combo = GTK_COMBO_BOX(_profileSel); + + g_signal_handler_block(G_OBJECT(_profileSel), _profChangedID); + + GtkListStore *store = GTK_LIST_STORE(gtk_combo_box_get_model(combo)); + gtk_list_store_clear(store); + + GtkTreeIter iter; + gtk_list_store_append(store, &iter); + gtk_list_store_set(store, &iter, 0, _("<none>"), 1, _("<none>"), -1); + + gtk_combo_box_set_active(combo, 0); + + int index = 1; + const GSList *current = SP_ACTIVE_DOCUMENT->getResourceList("iccprofile"); + while (current) { + SPObject *obj = SP_OBJECT(current->data); + Inkscape::ColorProfile *prof = reinterpret_cast<Inkscape::ColorProfile *>(obj); + + gtk_list_store_append(store, &iter); + gtk_list_store_set(store, &iter, 0, gr_ellipsize_text(prof->name, 25).c_str(), 1, prof->name, -1); + + if (name == prof->name) { + gtk_combo_box_set_active(combo, index); + gtk_widget_set_tooltip_text(_profileSel, prof->name); + } + + index++; + current = g_slist_next(current); + } + + g_signal_handler_unblock(G_OBJECT(_profileSel), _profChangedID); +} +#else +void ColorICCSelectorImpl::_profilesChanged(std::string const & /*name*/) {} +#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) + +void ColorICCSelector::on_show() +{ +#if GTK_CHECK_VERSION(3, 0, 0) + Gtk::Grid::on_show(); +#else + Gtk::Table::on_show(); +#endif + _colorChanged(); +} + +// Helpers for setting color value + +void ColorICCSelector::_colorChanged() +{ + _impl->_updating = TRUE; +// sp_color_icc_set_color( SP_COLOR_ICC( _icc ), &color ); + +#ifdef DEBUG_LCMS + g_message("/^^^^^^^^^ %p::_colorChanged(%08x:%s)", this, _impl->_color.color().toRGBA32(_impl->_color.alpha()), + ((_impl->_color.color().icc) ? _impl->_color.color().icc->colorProfile.c_str() : "<null>")); +#endif // DEBUG_LCMS + +#ifdef DEBUG_LCMS + g_message("FLIPPIES!!!! %p '%s'", _impl->_color.color().icc, + (_impl->_color.color().icc ? _impl->_color.color().icc->colorProfile.c_str() : "<null>")); +#endif // DEBUG_LCMS + + _impl->_profilesChanged((_impl->_color.color().icc) ? _impl->_color.color().icc->colorProfile : std::string("")); + ColorScales::setScaled(_impl->_adj, _impl->_color.alpha()); + +#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) + _impl->_setProfile(_impl->_color.color().icc); + _impl->_fixupNeeded = 0; + gtk_widget_set_sensitive(_impl->_fixupBtn, FALSE); + + if (_impl->_prof) { + if (_impl->_prof->getTransfToSRGB8()) { + cmsUInt16Number tmp[4]; + for (guint i = 0; i < _impl->_profChannelCount; i++) { + gdouble val = 0.0; + if (_impl->_color.color().icc->colors.size() > i) { + if (_impl->_compUI[i]._component.scale == 256) { + val = (_impl->_color.color().icc->colors[i] + 128.0) / + static_cast<gdouble>(_impl->_compUI[i]._component.scale); + } + else { + val = _impl->_color.color().icc->colors[i] / + static_cast<gdouble>(_impl->_compUI[i]._component.scale); + } + } + tmp[i] = val * 0x0ffff; + } + guchar post[4] = { 0, 0, 0, 0 }; + cmsHTRANSFORM trans = _impl->_prof->getTransfToSRGB8(); + if (trans) { + cmsDoTransform(trans, tmp, post, 1); + guint32 other = SP_RGBA32_U_COMPOSE(post[0], post[1], post[2], 255); + if (other != _impl->_color.color().toRGBA32(255)) { + _impl->_fixupNeeded = other; + gtk_widget_set_sensitive(_impl->_fixupBtn, TRUE); +#ifdef DEBUG_LCMS + g_message("Color needs to change 0x%06x to 0x%06x", _color.toRGBA32(255) >> 8, other >> 8); +#endif // DEBUG_LCMS + } + } + } + } +#else +//(void)color; +#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) + _impl->_updateSliders(-1); + + + _impl->_updating = FALSE; +#ifdef DEBUG_LCMS + g_message("\\_________ %p::_colorChanged()", this); +#endif // DEBUG_LCMS +} + +#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) +void ColorICCSelectorImpl::_setProfile(SVGICCColor *profile) +{ +#ifdef DEBUG_LCMS + g_message("/^^^^^^^^^ %p::_setProfile(%s)", this, ((profile) ? profile->colorProfile.c_str() : "<null>")); +#endif // DEBUG_LCMS + bool profChanged = false; + if (_prof && (!profile || (_profileName != profile->colorProfile))) { + // Need to clear out the prior one + profChanged = true; + _profileName.clear(); + _prof = 0; + _profChannelCount = 0; + } + else if (profile && !_prof) { + profChanged = true; + } + + for (size_t i = 0; i < _compUI.size(); i++) { + gtk_widget_hide(_compUI[i]._label); + _compUI[i]._slider->hide(); + gtk_widget_hide(_compUI[i]._btn); + } + + if (profile) { + _prof = SP_ACTIVE_DOCUMENT->profileManager->find(profile->colorProfile.c_str()); + if (_prof && (asICColorProfileClassSig(_prof->getProfileClass()) != cmsSigNamedColorClass)) { +#if HAVE_LIBLCMS1 + _profChannelCount = _cmsChannelsOf(asICColorSpaceSig(_prof->getColorSpace())); +#elif HAVE_LIBLCMS2 + _profChannelCount = cmsChannelsOf(asICColorSpaceSig(_prof->getColorSpace())); +#endif + + if (profChanged) { + std::vector<colorspace::Component> things = + colorspace::getColorSpaceInfo(asICColorSpaceSig(_prof->getColorSpace())); + for (size_t i = 0; (i < things.size()) && (i < _profChannelCount); ++i) { + _compUI[i]._component = things[i]; + } + + for (guint i = 0; i < _profChannelCount; i++) { + gtk_label_set_text_with_mnemonic(GTK_LABEL(_compUI[i]._label), + (i < things.size()) ? things[i].name.c_str() : ""); + + _compUI[i]._slider->set_tooltip_text((i < things.size()) ? things[i].tip.c_str() : ""); + gtk_widget_set_tooltip_text(_compUI[i]._btn, (i < things.size()) ? things[i].tip.c_str() : ""); + + _compUI[i]._slider->setColors(SPColor(0.0, 0.0, 0.0).toRGBA32(0xff), + SPColor(0.5, 0.5, 0.5).toRGBA32(0xff), + SPColor(1.0, 1.0, 1.0).toRGBA32(0xff)); + /* + _compUI[i]._adj = GTK_ADJUSTMENT( gtk_adjustment_new( val, 0.0, _fooScales[i], + step, page, page ) ); + g_signal_connect( G_OBJECT( _compUI[i]._adj ), "value_changed", G_CALLBACK( + _adjustmentChanged ), _csel ); + + sp_color_slider_set_adjustment( SP_COLOR_SLIDER(_compUI[i]._slider), + _compUI[i]._adj ); + gtk_spin_button_set_adjustment( GTK_SPIN_BUTTON(_compUI[i]._btn), + _compUI[i]._adj ); + gtk_spin_button_set_digits( GTK_SPIN_BUTTON(_compUI[i]._btn), digits ); + */ + gtk_widget_show(_compUI[i]._label); + _compUI[i]._slider->show(); + gtk_widget_show(_compUI[i]._btn); + // gtk_adjustment_set_value( _compUI[i]._adj, 0.0 ); + // gtk_adjustment_set_value( _compUI[i]._adj, val ); + } + for (size_t i = _profChannelCount; i < _compUI.size(); i++) { + gtk_widget_hide(_compUI[i]._label); + _compUI[i]._slider->hide(); + gtk_widget_hide(_compUI[i]._btn); + } + } + } + else { + // Give up for now on named colors + _prof = 0; + } + } + +#ifdef DEBUG_LCMS + g_message("\\_________ %p::_setProfile()", this); +#endif // DEBUG_LCMS +} +#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) + +void ColorICCSelectorImpl::_updateSliders(gint ignore) +{ +#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) + if (_color.color().icc) { + for (guint i = 0; i < _profChannelCount; i++) { + gdouble val = 0.0; + if (_color.color().icc->colors.size() > i) { + if (_compUI[i]._component.scale == 256) { + val = (_color.color().icc->colors[i] + 128.0) / static_cast<gdouble>(_compUI[i]._component.scale); + } + else { + val = _color.color().icc->colors[i] / static_cast<gdouble>(_compUI[i]._component.scale); + } + } + gtk_adjustment_set_value(_compUI[i]._adj, val); + } + + if (_prof) { + if (_prof->getTransfToSRGB8()) { + for (guint i = 0; i < _profChannelCount; i++) { + if (static_cast<gint>(i) != ignore) { + cmsUInt16Number *scratch = getScratch(); + cmsUInt16Number filler[4] = { 0, 0, 0, 0 }; + for (guint j = 0; j < _profChannelCount; j++) { + filler[j] = 0x0ffff * ColorScales::getScaled(_compUI[j]._adj); + } + + cmsUInt16Number *p = scratch; + for (guint x = 0; x < 1024; x++) { + for (guint j = 0; j < _profChannelCount; j++) { + if (j == i) { + *p++ = x * 0x0ffff / 1024; + } + else { + *p++ = filler[j]; + } + } + } + + cmsHTRANSFORM trans = _prof->getTransfToSRGB8(); + if (trans) { + cmsDoTransform(trans, scratch, _compUI[i]._map, 1024); + if (_compUI[i]._slider) + { + _compUI[i]._slider->setMap(_compUI[i]._map); + } + } + } + } + } + } + } +#else + (void)ignore; +#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) + + guint32 start = _color.color().toRGBA32(0x00); + guint32 mid = _color.color().toRGBA32(0x7f); + guint32 end = _color.color().toRGBA32(0xff); + + _slider->setColors(start, mid, end); +} + + +void ColorICCSelectorImpl::_adjustmentChanged(GtkAdjustment *adjustment, ColorICCSelectorImpl *cs) +{ +// // TODO check this. It looks questionable: +// // if a value is entered between 0 and 1 exclusive, normalize it to (int) 0..255 or 0..100 +// if (adjustment->value > 0.0 && adjustment->value < 1.0) { +// gtk_adjustment_set_value( adjustment, floor ((adjustment->value) * adjustment->upper + 0.5) ); +// } + +#ifdef DEBUG_LCMS + g_message("/^^^^^^^^^ %p::_adjustmentChanged()", cs); +#endif // DEBUG_LCMS + + ColorICCSelector *iccSelector = cs->_owner; + if (iccSelector->_impl->_updating) { + return; + } + + iccSelector->_impl->_updating = TRUE; + + gint match = -1; + + SPColor newColor(iccSelector->_impl->_color.color()); + gfloat scaled = ColorScales::getScaled(iccSelector->_impl->_adj); + if (iccSelector->_impl->_adj == adjustment) { +#ifdef DEBUG_LCMS + g_message("ALPHA"); +#endif // DEBUG_LCMS + } + else { +#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) + for (size_t i = 0; i < iccSelector->_impl->_compUI.size(); i++) { + if (iccSelector->_impl->_compUI[i]._adj == adjustment) { + match = i; + break; + } + } + if (match >= 0) { +#ifdef DEBUG_LCMS + g_message(" channel %d", match); +#endif // DEBUG_LCMS + } + + + cmsUInt16Number tmp[4]; + for (guint i = 0; i < 4; i++) { + tmp[i] = ColorScales::getScaled(iccSelector->_impl->_compUI[i]._adj) * 0x0ffff; + } + guchar post[4] = { 0, 0, 0, 0 }; + + cmsHTRANSFORM trans = iccSelector->_impl->_prof->getTransfToSRGB8(); + if (trans) { + cmsDoTransform(trans, tmp, post, 1); + } + + SPColor other(SP_RGBA32_U_COMPOSE(post[0], post[1], post[2], 255)); + other.icc = new SVGICCColor(); + if (iccSelector->_impl->_color.color().icc) { + other.icc->colorProfile = iccSelector->_impl->_color.color().icc->colorProfile; + } + + guint32 prior = iccSelector->_impl->_color.color().toRGBA32(255); + guint32 newer = other.toRGBA32(255); + + if (prior != newer) { +#ifdef DEBUG_LCMS + g_message("Transformed color from 0x%08x to 0x%08x", prior, newer); + g_message(" ~~~~ FLIP"); +#endif // DEBUG_LCMS + newColor = other; + newColor.icc->colors.clear(); + for (guint i = 0; i < iccSelector->_impl->_profChannelCount; i++) { + gdouble val = ColorScales::getScaled(iccSelector->_impl->_compUI[i]._adj); + val *= iccSelector->_impl->_compUI[i]._component.scale; + if (iccSelector->_impl->_compUI[i]._component.scale == 256) { + val -= 128; + } + newColor.icc->colors.push_back(val); + } + } +#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) + } + iccSelector->_impl->_color.setColorAlpha(newColor, scaled); + // iccSelector->_updateInternals( newColor, scaled, iccSelector->_impl->_dragging ); + iccSelector->_impl->_updateSliders(match); + + iccSelector->_impl->_updating = FALSE; +#ifdef DEBUG_LCMS + g_message("\\_________ %p::_adjustmentChanged()", cs); +#endif // DEBUG_LCMS +} + +void ColorICCSelectorImpl::_sliderGrabbed() +{ + // ColorICCSelector* iccSelector = dynamic_cast<ColorICCSelector*>(SP_COLOR_SELECTOR(cs)->base); + // if (!iccSelector->_dragging) { + // iccSelector->_dragging = TRUE; + // iccSelector->_grabbed(); + // iccSelector->_updateInternals( iccSelector->_color, ColorScales::getScaled( iccSelector->_impl->_adj ), + // iccSelector->_dragging ); + // } +} + +void ColorICCSelectorImpl::_sliderReleased() +{ + // ColorICCSelector* iccSelector = dynamic_cast<ColorICCSelector*>(SP_COLOR_SELECTOR(cs)->base); + // if (iccSelector->_dragging) { + // iccSelector->_dragging = FALSE; + // iccSelector->_released(); + // iccSelector->_updateInternals( iccSelector->_color, ColorScales::getScaled( iccSelector->_adj ), + // iccSelector->_dragging ); + // } +} + +#ifdef DEBUG_LCMS +void ColorICCSelectorImpl::_sliderChanged(SPColorSlider *slider, SPColorICCSelector *cs) +#else +void ColorICCSelectorImpl::_sliderChanged() +#endif // DEBUG_LCMS +{ +#ifdef DEBUG_LCMS + g_message("Changed %p and %p", slider, cs); +#endif // DEBUG_LCMS + // ColorICCSelector* iccSelector = dynamic_cast<ColorICCSelector*>(SP_COLOR_SELECTOR(cs)->base); + + // iccSelector->_updateInternals( iccSelector->_color, ColorScales::getScaled( iccSelector->_adj ), + // iccSelector->_dragging ); +} + +Gtk::Widget *ColorICCSelectorFactory::createWidget(Inkscape::UI::SelectedColor &color) const +{ + Gtk::Widget *w = Gtk::manage(new ColorICCSelector(color)); + return w; +} + +Glib::ustring ColorICCSelectorFactory::modeName() const { return gettext(ColorICCSelector::MODE_NAME); } +} +} +} +/* + 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 : diff --git a/src/ui/widget/color-icc-selector.h b/src/ui/widget/color-icc-selector.h new file mode 100644 index 000000000..1bcb0a540 --- /dev/null +++ b/src/ui/widget/color-icc-selector.h @@ -0,0 +1,78 @@ +#ifndef SEEN_SP_COLOR_ICC_SELECTOR_H +#define SEEN_SP_COLOR_ICC_SELECTOR_H + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <gtkmm/widget.h> +#if WITH_GTKMM_3_0 +#include <gtkmm/grid.h> +#else +#include <gtkmm/table.h> +#endif + +#include "ui/selected-color.h" + +namespace Inkscape { + +class ColorProfile; + +namespace UI { +namespace Widget { + +class ColorICCSelectorImpl; + +class ColorICCSelector +#if GTK_CHECK_VERSION(3, 0, 0) + : public Gtk::Grid +#else + : public Gtk::Table +#endif + { + public: + static const gchar *MODE_NAME; + + ColorICCSelector(SelectedColor &color); + virtual ~ColorICCSelector(); + + virtual void init(); + + protected: + void on_show(); + + virtual void _colorChanged(); + + void _recalcColor(gboolean changing); + + private: + friend class ColorICCSelectorImpl; + + // By default, disallow copy constructor and assignment operator + ColorICCSelector(const ColorICCSelector &obj); + ColorICCSelector &operator=(const ColorICCSelector &obj); + + ColorICCSelectorImpl *_impl; +}; + + +class ColorICCSelectorFactory : public ColorSelectorFactory { + public: + Gtk::Widget *createWidget(SelectedColor &color) const; + Glib::ustring modeName() const; +}; +} +} +} +#endif // SEEN_SP_COLOR_ICC_SELECTOR_H + +/* + 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 : diff --git a/src/ui/widget/color-notebook.cpp b/src/ui/widget/color-notebook.cpp new file mode 100644 index 000000000..60abf43bf --- /dev/null +++ b/src/ui/widget/color-notebook.cpp @@ -0,0 +1,379 @@ +/** + * @file + * A notebook with RGB, CMYK, CMS, HSL, and Wheel pages - implementation + */ +/* Authors: + * Lauris Kaplinski <lauris@kaplinski.com> + * bulia byak <buliabyak@users.sf.net> + * Tomasz Boczkowski <penginsbacon@gmail.com> (c++-sification) + * + * Copyright (C) 2001-2014 Authors + * + * This code is in public domain + */ + +#undef SPCS_PREVIEW +#define noDUMP_CHANGE_INFO + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "widgets/icon.h" +#include <cstring> +#include <string> +#include <cstdlib> +#include <cstddef> +#include <glibmm/i18n.h> +#include <gtkmm/label.h> +#include <gtkmm/notebook.h> + +#include "preferences.h" +#include "widgets/spw-utilities.h" +#include "svg/svg-icc-color.h" +#include "inkscape.h" +#include "document.h" +#include "profile-manager.h" +#include "color-profile.h" +#include "cms-system.h" +#include "ui/dialog-events.h" +#include "ui/tools-switch.h" +#include "ui/tools/tool-base.h" +#include "ui/widget/color-entry.h" +#include "ui/widget/color-icc-selector.h" +#include "ui/widget/color-notebook.h" +#include "ui/widget/color-scales.h" +#include "ui/widget/color-wheel-selector.h" + +using Inkscape::CMSSystem; + +#define XPAD 4 +#define YPAD 1 + +namespace Inkscape { +namespace UI { +namespace Widget { + + +ColorNotebook::ColorNotebook(SelectedColor &color) +#if GTK_CHECK_VERSION(3, 0, 0) + : Gtk::Grid() +#else + : Gtk::Table(2, 3, false) +#endif + , _selected_color(color) + +{ + Page *page; + + page = new Page(new ColorScalesFactory(SP_COLOR_SCALES_MODE_RGB), true); + _available_pages.push_back(page); + page = new Page(new ColorScalesFactory(SP_COLOR_SCALES_MODE_HSV), true); + _available_pages.push_back(page); + page = new Page(new ColorScalesFactory(SP_COLOR_SCALES_MODE_CMYK), true); + _available_pages.push_back(page); + page = new Page(new ColorWheelSelectorFactory, true); + _available_pages.push_back(page); +#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) + page = new Page(new ColorICCSelectorFactory, true); + _available_pages.push_back(page); +#endif + + _initUI(); + + _selected_color.signal_changed.connect(sigc::mem_fun(this, &ColorNotebook::_onSelectedColorChanged)); + _selected_color.signal_dragged.connect(sigc::mem_fun(this, &ColorNotebook::_onSelectedColorChanged)); +} + +ColorNotebook::~ColorNotebook() +{ + if (_buttons) { + delete[] _buttons; + _buttons = 0; + } +} + +ColorNotebook::Page::Page(Inkscape::UI::ColorSelectorFactory *selector_factory, bool enabled_full) + : selector_factory(selector_factory) + , enabled_full(enabled_full) +{ +} + + +void ColorNotebook::_initUI() +{ + guint row = 0; + + Gtk::Notebook *notebook = Gtk::manage(new Gtk::Notebook); + notebook->show(); + notebook->set_show_border(false); + notebook->set_show_tabs(false); + _book = GTK_WIDGET(notebook->gobj()); + +#if GTK_CHECK_VERSION(3, 0, 0) + _buttonbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 2); + gtk_box_set_homogeneous(GTK_BOX(_buttonbox), TRUE); +#else + _buttonbox = gtk_hbox_new(TRUE, 2); +#endif + + gtk_widget_show(_buttonbox); + _buttons = new GtkWidget *[_available_pages.size()]; + + for (int i = 0; static_cast<size_t>(i) < _available_pages.size(); i++) { + _addPage(_available_pages[i]); + } + + sp_set_font_size_smaller(_buttonbox); + +#if GTK_CHECK_VERSION(3, 0, 0) + #if GTK_CHECK_VERSION(3, 12, 0) + gtk_widget_set_margin_start(_buttonbox, XPAD); + gtk_widget_set_margin_end(_buttonbox, XPAD); + #else + gtk_widget_set_margin_left(_buttonbox, XPAD); + gtk_widget_set_margin_right(_buttonbox, XPAD); + #endif + gtk_widget_set_margin_top(_buttonbox, YPAD); + gtk_widget_set_margin_bottom(_buttonbox, YPAD); + gtk_widget_set_hexpand(_buttonbox, TRUE); + gtk_widget_set_valign(_buttonbox, GTK_ALIGN_CENTER); + attach(*Glib::wrap(_buttonbox), 0, row, 2, 1); +#else + attach(*Glib::wrap(_buttonbox), 0, 2, row, row + 1, Gtk::EXPAND | Gtk::FILL, static_cast<Gtk::AttachOptions>(0), + XPAD, YPAD); +#endif + + row++; + +#if GTK_CHECK_VERSION(3, 0, 0) +#if GTK_CHECK_VERSION(3, 12, 0) + gtk_widget_set_margin_start(_book, XPAD * 2); + gtk_widget_set_margin_end(_book, XPAD * 2); +#else + gtk_widget_set_margin_left(_book, XPAD * 2); + gtk_widget_set_margin_right(_book, XPAD * 2); +#endif + gtk_widget_set_margin_top(_book, YPAD); + gtk_widget_set_margin_bottom(_book, YPAD); + gtk_widget_set_hexpand(_book, TRUE); + gtk_widget_set_vexpand(_book, TRUE); + attach(*notebook, 0, row, 2, 1); +#else + attach(*notebook, 0, 2, row, row + 1, Gtk::EXPAND | Gtk::FILL, Gtk::EXPAND | Gtk::FILL, XPAD * 2, YPAD); +#endif + + // restore the last active page + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + _setCurrentPage(prefs->getInt("/colorselector/page", 0)); + row++; + +#if GTK_CHECK_VERSION(3, 0, 0) + GtkWidget *rgbabox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); +#else + GtkWidget *rgbabox = gtk_hbox_new(FALSE, 0); +#endif + +#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) + /* Create color management icons */ + _box_colormanaged = gtk_event_box_new(); + GtkWidget *colormanaged = gtk_image_new_from_icon_name("color-management-icon", GTK_ICON_SIZE_SMALL_TOOLBAR); + gtk_container_add(GTK_CONTAINER(_box_colormanaged), colormanaged); + gtk_widget_set_tooltip_text(_box_colormanaged, _("Color Managed")); + gtk_widget_set_sensitive(_box_colormanaged, false); + gtk_box_pack_start(GTK_BOX(rgbabox), _box_colormanaged, FALSE, FALSE, 2); + + _box_outofgamut = gtk_event_box_new(); + GtkWidget *outofgamut = gtk_image_new_from_icon_name("out-of-gamut-icon", GTK_ICON_SIZE_SMALL_TOOLBAR); + gtk_container_add(GTK_CONTAINER(_box_outofgamut), outofgamut); + gtk_widget_set_tooltip_text(_box_outofgamut, _("Out of gamut!")); + gtk_widget_set_sensitive(_box_outofgamut, false); + gtk_box_pack_start(GTK_BOX(rgbabox), _box_outofgamut, FALSE, FALSE, 2); + + _box_toomuchink = gtk_event_box_new(); + GtkWidget *toomuchink = gtk_image_new_from_icon_name("too-much-ink-icon", GTK_ICON_SIZE_SMALL_TOOLBAR); + gtk_container_add(GTK_CONTAINER(_box_toomuchink), toomuchink); + gtk_widget_set_tooltip_text(_box_toomuchink, _("Too much ink!")); + gtk_widget_set_sensitive(_box_toomuchink, false); + gtk_box_pack_start(GTK_BOX(rgbabox), _box_toomuchink, FALSE, FALSE, 2); +#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) + + + /* Color picker */ + GtkWidget *picker = gtk_image_new_from_icon_name("color-picker", GTK_ICON_SIZE_SMALL_TOOLBAR); + _btn_picker = gtk_button_new(); + gtk_button_set_relief(GTK_BUTTON(_btn_picker), GTK_RELIEF_NONE); + gtk_container_add(GTK_CONTAINER(_btn_picker), picker); + gtk_widget_set_tooltip_text(_btn_picker, _("Pick colors from image")); + gtk_box_pack_start(GTK_BOX(rgbabox), _btn_picker, FALSE, FALSE, 2); + g_signal_connect(G_OBJECT(_btn_picker), "clicked", G_CALLBACK(ColorNotebook::_onPickerClicked), this); + + /* Create RGBA entry and color preview */ + _rgbal = gtk_label_new_with_mnemonic(_("RGBA_:")); + gtk_misc_set_alignment(GTK_MISC(_rgbal), 1.0, 0.5); + gtk_box_pack_start(GTK_BOX(rgbabox), _rgbal, TRUE, TRUE, 2); + + ColorEntry *rgba_entry = Gtk::manage(new ColorEntry(_selected_color)); + sp_dialog_defocus_on_enter(GTK_WIDGET(rgba_entry->gobj())); + gtk_box_pack_start(GTK_BOX(rgbabox), GTK_WIDGET(rgba_entry->gobj()), FALSE, FALSE, 0); + gtk_label_set_mnemonic_widget(GTK_LABEL(_rgbal), GTK_WIDGET(rgba_entry->gobj())); + + sp_set_font_size_smaller(rgbabox); + gtk_widget_show_all(rgbabox); + +#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) + // the "too much ink" icon is initially hidden + gtk_widget_hide(GTK_WIDGET(_box_toomuchink)); +#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) + +#if GTK_CHECK_VERSION(3, 0, 0) + #if GTK_CHECK_VERSION(3, 12, 0) + gtk_widget_set_margin_start(rgbabox, XPAD); + gtk_widget_set_margin_end(rgbabox, XPAD); + #else + gtk_widget_set_margin_left(rgbabox, XPAD); + gtk_widget_set_margin_right(rgbabox, XPAD); + #endif + gtk_widget_set_margin_top(rgbabox, YPAD); + gtk_widget_set_margin_bottom(rgbabox, YPAD); + attach(*Glib::wrap(rgbabox), 0, row, 2, 1); +#else + attach(*Glib::wrap(rgbabox), 0, 2, row, row + 1, Gtk::FILL, Gtk::SHRINK, XPAD, YPAD); +#endif + +#ifdef SPCS_PREVIEW + _p = sp_color_preview_new(0xffffffff); + gtk_widget_show(_p); + attach(*Glib::wrap(_p), 2, 3, row, row + 1, Gtk::FILL, Gtk::FILL, XPAD, YPAD); +#endif + + g_signal_connect(G_OBJECT(_book), "switch-page", G_CALLBACK(ColorNotebook::_onPageSwitched), this); +} + +void ColorNotebook::_onPickerClicked(GtkWidget * /*widget*/, ColorNotebook * /*colorbook*/) +{ + // Set the dropper into a "one click" mode, so it reverts to the previous tool after a click + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setBool("/tools/dropper/onetimepick", true); + Inkscape::UI::Tools::sp_toggle_dropper(SP_ACTIVE_DESKTOP); +} + +void ColorNotebook::_onButtonClicked(GtkWidget *widget, ColorNotebook *nb) +{ + if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) { + return; + } + + for (gint i = 0; i < gtk_notebook_get_n_pages(GTK_NOTEBOOK(nb->_book)); i++) { + if (nb->_buttons[i] == widget) { + gtk_notebook_set_current_page(GTK_NOTEBOOK(nb->_book), i); + } + } +} + +void ColorNotebook::_onSelectedColorChanged() { _updateICCButtons(); } + +void ColorNotebook::_onPageSwitched(GtkNotebook *notebook, GtkWidget *page, guint page_num, ColorNotebook *colorbook) +{ + if (colorbook->get_visible()) { + // remember the page we switched to + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setInt("/colorselector/page", page_num); + } +} + + +// TODO pass in param so as to avoid the need for SP_ACTIVE_DOCUMENT +void ColorNotebook::_updateICCButtons() +{ + SPColor color = _selected_color.color(); + gfloat alpha = _selected_color.alpha(); + + g_return_if_fail((0.0 <= alpha) && (alpha <= 1.0)); + +#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) + /* update color management icon*/ + gtk_widget_set_sensitive(_box_colormanaged, color.icc != NULL); + + /* update out-of-gamut icon */ + gtk_widget_set_sensitive(_box_outofgamut, false); + if (color.icc) { + Inkscape::ColorProfile *target_profile = + SP_ACTIVE_DOCUMENT->profileManager->find(color.icc->colorProfile.c_str()); + if (target_profile) + gtk_widget_set_sensitive(_box_outofgamut, target_profile->GamutCheck(color)); + } + + /* update too-much-ink icon */ + gtk_widget_set_sensitive(_box_toomuchink, false); + if (color.icc) { + Inkscape::ColorProfile *prof = SP_ACTIVE_DOCUMENT->profileManager->find(color.icc->colorProfile.c_str()); + if (prof && CMSSystem::isPrintColorSpace(prof)) { + gtk_widget_show(GTK_WIDGET(_box_toomuchink)); + double ink_sum = 0; + for (unsigned int i = 0; i < color.icc->colors.size(); i++) { + ink_sum += color.icc->colors[i]; + } + + /* Some literature states that when the sum of paint values exceed 320%, it is considered to be a satured + color, + which means the paper can get too wet due to an excessive ammount of ink. This may lead to several + issues + such as misalignment and poor quality of printing in general.*/ + if (ink_sum > 3.2) + gtk_widget_set_sensitive(_box_toomuchink, true); + } + else { + gtk_widget_hide(GTK_WIDGET(_box_toomuchink)); + } + } +#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) +} + +void ColorNotebook::_setCurrentPage(int i) +{ + gtk_notebook_set_current_page(GTK_NOTEBOOK(_book), i); + + if (_buttons && (static_cast<size_t>(i) < _available_pages.size())) { + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(_buttons[i]), TRUE); + } +} + +void ColorNotebook::_addPage(Page &page) +{ + Gtk::Widget *selector_widget; + + selector_widget = page.selector_factory->createWidget(_selected_color); + if (selector_widget) { + selector_widget->show(); + + Glib::ustring mode_name = page.selector_factory->modeName(); + Gtk::Widget *tab_label = Gtk::manage(new Gtk::Label(mode_name)); + gint page_num = gtk_notebook_append_page(GTK_NOTEBOOK(_book), selector_widget->gobj(), tab_label->gobj()); + + _buttons[page_num] = gtk_radio_button_new_with_label(NULL, mode_name.c_str()); + gtk_toggle_button_set_mode(GTK_TOGGLE_BUTTON(_buttons[page_num]), FALSE); + if (page_num > 0) { + GSList *group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(_buttons[0])); + gtk_radio_button_set_group(GTK_RADIO_BUTTON(_buttons[page_num]), group); + } + gtk_widget_show(_buttons[page_num]); + gtk_box_pack_start(GTK_BOX(_buttonbox), _buttons[page_num], TRUE, TRUE, 0); + + g_signal_connect(G_OBJECT(_buttons[page_num]), "clicked", G_CALLBACK(_onButtonClicked), this); + } +} +} +} +} + +/* + 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 : diff --git a/src/ui/widget/color-notebook.h b/src/ui/widget/color-notebook.h new file mode 100644 index 000000000..d28028c72 --- /dev/null +++ b/src/ui/widget/color-notebook.h @@ -0,0 +1,99 @@ +/** + * @file + * A notebook with RGB, CMYK, CMS, HSL, and Wheel pages + */ +/* Authors: + * Lauris Kaplinski <lauris@kaplinski.com> + * bulia byak <buliabyak@users.sf.net> + * Tomasz Boczkowski <penginsbacon@gmail.com> (c++-sification) + * + * Copyright (C) 2001-2014 Authors + * + * This code is in public domain + */ +#ifndef SEEN_SP_COLOR_NOTEBOOK_H +#define SEEN_SP_COLOR_NOTEBOOK_H + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <boost/ptr_container/ptr_vector.hpp> +#if WITH_GTKMM_3_0 +#include <gtkmm/grid.h> +#else +#include <gtkmm/table.h> +#endif +#include <gtk/gtk.h> +#include <glib.h> + +#include "color.h" +#include "ui/selected-color.h" + +namespace Inkscape { +namespace UI { +namespace Widget { + +class ColorNotebook +#if GTK_CHECK_VERSION(3, 0, 0) + : public Gtk::Grid +#else + : public Gtk::Table +#endif +{ +public: + ColorNotebook(SelectedColor &color); + virtual ~ColorNotebook(); + +protected: + struct Page { + Page(Inkscape::UI::ColorSelectorFactory *selector_factory, bool enabled_full); + + Inkscape::UI::ColorSelectorFactory *selector_factory; + bool enabled_full; + }; + + virtual void _initUI(); + void _addPage(Page &page); + + static void _onButtonClicked(GtkWidget *widget, ColorNotebook *colorbook); + static void _onPickerClicked(GtkWidget *widget, ColorNotebook *colorbook); + static void _onPageSwitched(GtkNotebook *notebook, GtkWidget *page, guint page_num, ColorNotebook *colorbook); + virtual void _onSelectedColorChanged(); + + void _updateICCButtons(); + void _setCurrentPage(int i); + + Inkscape::UI::SelectedColor &_selected_color; + gulong _entryId; + GtkWidget *_book; + GtkWidget *_buttonbox; + GtkWidget **_buttons; + GtkWidget *_rgbal; /* RGBA entry */ +#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) + GtkWidget *_box_outofgamut, *_box_colormanaged, *_box_toomuchink; +#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) + GtkWidget *_btn_picker; + GtkWidget *_p; /* Color preview */ + boost::ptr_vector<Page> _available_pages; + +private: + // By default, disallow copy constructor and assignment operator + ColorNotebook(const ColorNotebook &obj); + ColorNotebook &operator=(const ColorNotebook &obj); +}; +} +} +} +#endif // SEEN_SP_COLOR_NOTEBOOK_H +/* + 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 : + diff --git a/src/ui/widget/color-picker.cpp b/src/ui/widget/color-picker.cpp index d4c4d394e..a66fbfc9c 100644 --- a/src/ui/widget/color-picker.cpp +++ b/src/ui/widget/color-picker.cpp @@ -17,7 +17,7 @@ #include "document-undo.h" #include "ui/dialog-events.h" -#include "widgets/sp-color-notebook.h" +#include "ui/widget/color-notebook.h" #include "verbs.h" @@ -27,8 +27,6 @@ namespace Inkscape { namespace UI { namespace Widget { -void sp_color_picker_color_mod(SPColorSelector *csel, GObject *cp); - ColorPicker::ColorPicker (const Glib::ustring& title, const Glib::ustring& tip, guint32 rgba, bool undo) : _preview(rgba), _title(title), _rgba(rgba), _undo(undo), @@ -39,12 +37,15 @@ ColorPicker::ColorPicker (const Glib::ustring& title, const Glib::ustring& tip, _preview.show(); add (_preview); set_tooltip_text (tip); + + _selected_color.signal_changed.connect(sigc::mem_fun(this, &ColorPicker::_onSelectedColorChanged)); + _selected_color.signal_dragged.connect(sigc::mem_fun(this, &ColorPicker::_onSelectedColorChanged)); + _selected_color.signal_released.connect(sigc::mem_fun(this, &ColorPicker::_onSelectedColorChanged)); } ColorPicker::~ColorPicker() { closeWindow(); - _colorSelector = NULL; } void ColorPicker::setupDialog(const Glib::ustring &title) @@ -55,25 +56,17 @@ void ColorPicker::setupDialog(const Glib::ustring &title) _colorSelectorDialog.hide(); _colorSelectorDialog.set_title (title); _colorSelectorDialog.set_border_width (4); - _colorSelector = SP_COLOR_SELECTOR(sp_color_selector_new(SP_TYPE_COLOR_NOTEBOOK)); + + _color_selector = Gtk::manage(new ColorNotebook(_selected_color)); #if WITH_GTKMM_3_0 _colorSelectorDialog.get_content_area()->pack_start ( - *Glib::wrap(&_colorSelector->vbox), true, true, 0); + *_color_selector, true, true, 0); #else _colorSelectorDialog.get_vbox()->pack_start ( - *Glib::wrap(&_colorSelector->vbox), true, true, 0); + *_color_selector, true, true, 0); #endif - - g_signal_connect(G_OBJECT(_colorSelector), "dragged", - G_CALLBACK(sp_color_picker_color_mod), (void *)this); - g_signal_connect(G_OBJECT(_colorSelector), "released", - G_CALLBACK(sp_color_picker_color_mod), (void *)this); - g_signal_connect(G_OBJECT(_colorSelector), "changed", - G_CALLBACK(sp_color_picker_color_mod), (void *)this); - - gtk_widget_show(GTK_WIDGET(_colorSelector)); - + _color_selector->show(); } void ColorPicker::setRgba32 (guint32 rgba) @@ -82,11 +75,11 @@ void ColorPicker::setRgba32 (guint32 rgba) _preview.setRgba32 (rgba); _rgba = rgba; - if (_colorSelector) + if (_color_selector) { - SPColor color; - color.set( rgba ); - _colorSelector->base->setColorAlpha(color, SP_RGBA32_A_F(rgba)); + _updating = true; + _selected_color.setValue(rgba); + _updating = false; } } @@ -97,11 +90,11 @@ void ColorPicker::closeWindow() void ColorPicker::on_clicked() { - if (_colorSelector) + if (_color_selector) { - SPColor color; - color.set( _rgba ); - _colorSelector->base->setColorAlpha(color, SP_RGBA32_A_F(_rgba)); + _updating = true; + _selected_color.setValue(_rgba); + _updating = false; } _colorSelectorDialog.show(); } @@ -110,34 +103,31 @@ void ColorPicker::on_changed (guint32) { } -void sp_color_picker_color_mod(SPColorSelector *csel, GObject *cp) -{ +void ColorPicker::_onSelectedColorChanged() { + if (_updating) { + return; + } + if (_in_use) { return; } else { _in_use = true; } - SPColor color; - float alpha = 0; - csel->base->getColorAlpha(color, alpha); - guint32 rgba = color.toRGBA32( alpha ); - - ColorPicker *ptr = reinterpret_cast<ColorPicker *>(cp); - - (ptr->_preview).setRgba32 (rgba); + guint32 rgba = _selected_color.value(); + _preview.setRgba32(rgba); - if (ptr->_undo && SP_ACTIVE_DESKTOP) + if (_undo && SP_ACTIVE_DESKTOP) { DocumentUndo::done(SP_ACTIVE_DESKTOP->getDocument(), SP_VERB_NONE, /* TODO: annotate */ "color-picker.cpp:130"); + } - ptr->on_changed (rgba); + on_changed(rgba); _in_use = false; - ptr->_changed_signal.emit (rgba); - ptr->_rgba = rgba; + _changed_signal.emit(rgba); + _rgba = rgba; } - }//namespace Widget }//namespace UI }//namespace Inkscape diff --git a/src/ui/widget/color-picker.h b/src/ui/widget/color-picker.h index 99904b081..e8a738b5b 100644 --- a/src/ui/widget/color-picker.h +++ b/src/ui/widget/color-picker.h @@ -18,6 +18,7 @@ #include <gtkmm/dialog.h> #include <gtkmm/button.h> #include <sigc++/sigc++.h> +#include "ui/selected-color.h" #include "ui/widget/color-preview.h" struct SPColorSelector; @@ -49,7 +50,7 @@ public: protected: - friend void sp_color_picker_color_mod(SPColorSelector *csel, GObject *cp); + void _onSelectedColorChanged(); virtual void on_clicked(); virtual void on_changed (guint32); @@ -59,13 +60,14 @@ protected: sigc::signal<void,guint32> _changed_signal; guint32 _rgba; bool _undo; - + bool _updating; //Dialog void setupDialog(const Glib::ustring &title); //Inkscape::UI::Dialog::Dialog _colorSelectorDialog; Gtk::Dialog _colorSelectorDialog; - SPColorSelector *_colorSelector; + SelectedColor _selected_color; + Gtk::Widget *_color_selector; }; }//namespace Widget diff --git a/src/ui/widget/color-scales.cpp b/src/ui/widget/color-scales.cpp new file mode 100644 index 000000000..170f83887 --- /dev/null +++ b/src/ui/widget/color-scales.cpp @@ -0,0 +1,677 @@ +/* + * bulia byak <buliabyak@users.sf.net> + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <math.h> +#include <gtkmm/adjustment.h> +#include <glibmm/i18n.h> +#include <gtk/gtk.h> + +#include "svg/svg-icc-color.h" +#include "ui/dialog-events.h" +#include "ui/widget/color-scales.h" +#include "ui/widget/color-slider.h" + +#define CSC_CHANNEL_R (1 << 0) +#define CSC_CHANNEL_G (1 << 1) +#define CSC_CHANNEL_B (1 << 2) +#define CSC_CHANNEL_A (1 << 3) +#define CSC_CHANNEL_H (1 << 0) +#define CSC_CHANNEL_S (1 << 1) +#define CSC_CHANNEL_V (1 << 2) +#define CSC_CHANNEL_C (1 << 0) +#define CSC_CHANNEL_M (1 << 1) +#define CSC_CHANNEL_Y (1 << 2) +#define CSC_CHANNEL_K (1 << 3) +#define CSC_CHANNEL_CMYKA (1 << 4) + +#define CSC_CHANNELS_ALL 0 + +#define XPAD 4 +#define YPAD 1 + +#define noDUMP_CHANGE_INFO 1 + +namespace Inkscape { +namespace UI { +namespace Widget { + + +static const gchar *sp_color_scales_hue_map(); + +const gchar *ColorScales::SUBMODE_NAMES[] = { N_("None"), N_("RGB"), N_("HSL"), N_("CMYK") }; + +ColorScales::ColorScales(SelectedColor &color, SPColorScalesMode mode) +#if GTK_CHECK_VERSION(3, 0, 0) + : Gtk::Grid() +#else + : Gtk::Table(5, 3, false) +#endif + , _color(color) + , _rangeLimit(255.0) + , _updating(FALSE) + , _dragging(FALSE) +{ + for (gint i = 0; i < 5; i++) { + _l[i] = 0; + _a[i] = 0; + _s[i] = 0; + _b[i] = 0; + } + + _initUI(mode); + + _color.signal_changed.connect(sigc::mem_fun(this, &ColorScales::_onColorChanged)); + _color.signal_dragged.connect(sigc::mem_fun(this, &ColorScales::_onColorChanged)); +} + +ColorScales::~ColorScales() +{ + for (gint i = 0; i < 5; i++) { + _l[i] = 0; + _a[i] = 0; + _s[i] = 0; + _b[i] = 0; + } +} + +void ColorScales::_initUI(SPColorScalesMode mode) +{ + gint i; + + _updating = FALSE; + _dragging = FALSE; + + GtkWidget *t = GTK_WIDGET(gobj()); + + /* Create components */ + for (i = 0; i < static_cast<gint>(G_N_ELEMENTS(_a)); i++) { + /* Label */ + _l[i] = gtk_label_new(""); + gtk_misc_set_alignment(GTK_MISC(_l[i]), 1.0, 0.5); + gtk_widget_show(_l[i]); + +#if GTK_CHECK_VERSION(3, 0, 0) + #if GTK_CHECK_VERSION(3, 12, 0) + gtk_widget_set_margin_start(_l[i], XPAD); + gtk_widget_set_margin_end(_l[i], XPAD); + #else + gtk_widget_set_margin_left(_l[i], XPAD); + gtk_widget_set_margin_right(_l[i], XPAD); + #endif + gtk_widget_set_margin_top(_l[i], YPAD); + gtk_widget_set_margin_bottom(_l[i], YPAD); + gtk_grid_attach(GTK_GRID(t), _l[i], 0, i, 1, 1); +#else + gtk_table_attach(GTK_TABLE(t), _l[i], 0, 1, i, i + 1, GTK_FILL, GTK_FILL, XPAD, YPAD); +#endif + + /* Adjustment */ + _a[i] = GTK_ADJUSTMENT(gtk_adjustment_new(0.0, 0.0, _rangeLimit, 1.0, 10.0, 10.0)); + /* Slider */ + _s[i] = Gtk::manage(new Inkscape::UI::Widget::ColorSlider(Glib::wrap(_a[i], true))); + _s[i]->show(); + +#if GTK_CHECK_VERSION(3, 0, 0) + #if GTK_CHECK_VERSION(3, 12, 0) + _s[i]->set_margin_start(XPAD); + _s[i]->set_margin_end(XPAD); + #else + _s[i]->set_margin_left(XPAD); + _s[i]->set_margin_right(XPAD); + #endif + _s[i]->set_margin_top(YPAD); + _s[i]->set_margin_bottom(YPAD); + _s[i]->set_hexpand(true); + gtk_grid_attach(GTK_GRID(t), _s[i]->gobj(), 1, i, 1, 1); +#else + gtk_table_attach(GTK_TABLE(t), _s[i]->gobj(), 1, 2, i, i + 1, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), + GTK_FILL, XPAD, YPAD); +#endif + + /* Spinbutton */ + _b[i] = gtk_spin_button_new(GTK_ADJUSTMENT(_a[i]), 1.0, 0); + sp_dialog_defocus_on_enter(_b[i]); + gtk_label_set_mnemonic_widget(GTK_LABEL(_l[i]), _b[i]); + gtk_widget_show(_b[i]); + +#if GTK_CHECK_VERSION(3, 0, 0) + #if GTK_CHECK_VERSION(3, 12, 0) + gtk_widget_set_margin_start(_b[i], XPAD); + gtk_widget_set_margin_end(_b[i], XPAD); + #else + gtk_widget_set_margin_left(_b[i], XPAD); + gtk_widget_set_margin_right(_b[i], XPAD); + #endif + gtk_widget_set_margin_top(_b[i], YPAD); + gtk_widget_set_margin_bottom(_b[i], YPAD); + gtk_widget_set_halign(_b[i], GTK_ALIGN_CENTER); + gtk_widget_set_valign(_b[i], GTK_ALIGN_CENTER); + gtk_grid_attach(GTK_GRID(t), _b[i], 2, i, 1, 1); +#else + gtk_table_attach(GTK_TABLE(t), _b[i], 2, 3, i, i + 1, (GtkAttachOptions)0, (GtkAttachOptions)0, XPAD, YPAD); +#endif + + /* Attach channel value to adjustment */ + g_object_set_data(G_OBJECT(_a[i]), "channel", GINT_TO_POINTER(i)); + /* Signals */ + g_signal_connect(G_OBJECT(_a[i]), "value_changed", G_CALLBACK(_adjustmentAnyChanged), this); + _s[i]->signal_grabbed.connect(sigc::mem_fun(this, &ColorScales::_sliderAnyGrabbed)); + _s[i]->signal_released.connect(sigc::mem_fun(this, &ColorScales::_sliderAnyReleased)); + _s[i]->signal_value_changed.connect(sigc::mem_fun(this, &ColorScales::_sliderAnyChanged)); + } + + //Prevent 5th bar from being shown by PanelDialog::show_all_children + gtk_widget_set_no_show_all(_l[4], TRUE); + _s[4]->set_no_show_all(true); + gtk_widget_set_no_show_all(_b[4], TRUE); + + /* Initial mode is none, so it works */ + setMode(mode); +} + +void ColorScales::_recalcColor() +{ + SPColor color; + gfloat alpha = 1.0; + gfloat c[5]; + + switch (_mode) { + case SP_COLOR_SCALES_MODE_RGB: + case SP_COLOR_SCALES_MODE_HSV: + _getRgbaFloatv(c); + color.set(c[0], c[1], c[2]); + alpha = c[3]; + break; + case SP_COLOR_SCALES_MODE_CMYK: { + _getCmykaFloatv(c); + + float rgb[3]; + sp_color_cmyk_to_rgb_floatv(rgb, c[0], c[1], c[2], c[3]); + color.set(rgb[0], rgb[1], rgb[2]); + alpha = c[4]; + break; + } + default: + g_warning("file %s: line %d: Illegal color selector mode %d", __FILE__, __LINE__, _mode); + break; + } + + _color.preserveICC(); + _color.setColorAlpha(color, alpha); +} + +void ColorScales::_updateDisplay() +{ +#ifdef DUMP_CHANGE_INFO + g_message("ColorScales::_onColorChanged( this=%p, %f, %f, %f, %f)", this, _color.color().v.c[0], + _color.color().v.c[1], _color.color().v.c[2], _color.alpha()); +#endif + gfloat tmp[3]; + gfloat c[5] = { 0.0, 0.0, 0.0, 0.0 }; + + SPColor color = _color.color(); + + switch (_mode) { + case SP_COLOR_SCALES_MODE_RGB: + sp_color_get_rgb_floatv(&color, c); + c[3] = _color.alpha(); + c[4] = 0.0; + break; + case SP_COLOR_SCALES_MODE_HSV: + sp_color_get_rgb_floatv(&color, tmp); + sp_color_rgb_to_hsl_floatv(c, tmp[0], tmp[1], tmp[2]); + c[3] = _color.alpha(); + c[4] = 0.0; + break; + case SP_COLOR_SCALES_MODE_CMYK: + sp_color_get_cmyk_floatv(&color, c); + c[4] = _color.alpha(); + break; + default: + g_warning("file %s: line %d: Illegal color selector mode %d", __FILE__, __LINE__, _mode); + break; + } + + _updating = TRUE; + setScaled(_a[0], c[0]); + setScaled(_a[1], c[1]); + setScaled(_a[2], c[2]); + setScaled(_a[3], c[3]); + setScaled(_a[4], c[4]); + _updateSliders(CSC_CHANNELS_ALL); + _updating = FALSE; +} + +/* Helpers for setting color value */ +gfloat ColorScales::getScaled(const GtkAdjustment *a) +{ + gfloat val = gtk_adjustment_get_value(const_cast<GtkAdjustment *>(a)) / + gtk_adjustment_get_upper(const_cast<GtkAdjustment *>(a)); + return val; +} + +void ColorScales::setScaled(GtkAdjustment *a, gfloat v) +{ + gfloat val = v * gtk_adjustment_get_upper(a); + gtk_adjustment_set_value(a, val); +} + +void ColorScales::_setRangeLimit(gdouble upper) +{ + _rangeLimit = upper; + for (gint i = 0; i < static_cast<gint>(G_N_ELEMENTS(_a)); i++) { + gtk_adjustment_set_upper(_a[i], upper); + gtk_adjustment_changed(_a[i]); + } +} + +void ColorScales::_onColorChanged() +{ + if (!get_visible()) { + return; + } + _updateDisplay(); +} + +void ColorScales::on_show() +{ +#if GTK_CHECK_VERSION(3, 0, 0) + Gtk::Grid::on_show(); +#else + Gtk::Table::on_show(); +#endif + _updateDisplay(); +} + +void ColorScales::_getRgbaFloatv(gfloat *rgba) +{ + g_return_if_fail(rgba != NULL); + + switch (_mode) { + case SP_COLOR_SCALES_MODE_RGB: + rgba[0] = getScaled(_a[0]); + rgba[1] = getScaled(_a[1]); + rgba[2] = getScaled(_a[2]); + rgba[3] = getScaled(_a[3]); + break; + case SP_COLOR_SCALES_MODE_HSV: + sp_color_hsl_to_rgb_floatv(rgba, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2])); + rgba[3] = getScaled(_a[3]); + break; + case SP_COLOR_SCALES_MODE_CMYK: + sp_color_cmyk_to_rgb_floatv(rgba, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), getScaled(_a[3])); + rgba[3] = getScaled(_a[4]); + break; + default: + g_warning("file %s: line %d: Illegal color selector mode", __FILE__, __LINE__); + break; + } +} + +void ColorScales::_getCmykaFloatv(gfloat *cmyka) +{ + gfloat rgb[3]; + + g_return_if_fail(cmyka != NULL); + + switch (_mode) { + case SP_COLOR_SCALES_MODE_RGB: + sp_color_rgb_to_cmyk_floatv(cmyka, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2])); + cmyka[4] = getScaled(_a[3]); + break; + case SP_COLOR_SCALES_MODE_HSV: + sp_color_hsl_to_rgb_floatv(rgb, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2])); + sp_color_rgb_to_cmyk_floatv(cmyka, rgb[0], rgb[1], rgb[2]); + cmyka[4] = getScaled(_a[3]); + break; + case SP_COLOR_SCALES_MODE_CMYK: + cmyka[0] = getScaled(_a[0]); + cmyka[1] = getScaled(_a[1]); + cmyka[2] = getScaled(_a[2]); + cmyka[3] = getScaled(_a[3]); + cmyka[4] = getScaled(_a[4]); + break; + default: + g_warning("file %s: line %d: Illegal color selector mode", __FILE__, __LINE__); + break; + } +} + +guint32 ColorScales::_getRgba32() +{ + gfloat c[4]; + guint32 rgba; + + _getRgbaFloatv(c); + + rgba = SP_RGBA32_F_COMPOSE(c[0], c[1], c[2], c[3]); + + return rgba; +} + +void ColorScales::setMode(SPColorScalesMode mode) +{ + gfloat rgba[4]; + gfloat c[4]; + + if (_mode == mode) + return; + + if ((_mode == SP_COLOR_SCALES_MODE_RGB) || (_mode == SP_COLOR_SCALES_MODE_HSV) || + (_mode == SP_COLOR_SCALES_MODE_CMYK)) { + _getRgbaFloatv(rgba); + } + else { + rgba[0] = rgba[1] = rgba[2] = rgba[3] = 1.0; + } + + _mode = mode; + + switch (mode) { + case SP_COLOR_SCALES_MODE_RGB: + _setRangeLimit(255.0); + gtk_label_set_markup_with_mnemonic(GTK_LABEL(_l[0]), _("_R:")); + _s[0]->set_tooltip_text(_("Red")); + gtk_widget_set_tooltip_text(_b[0], _("Red")); + gtk_label_set_markup_with_mnemonic(GTK_LABEL(_l[1]), _("_G:")); + _s[1]->set_tooltip_text(_("Green")); + gtk_widget_set_tooltip_text(_b[1], _("Green")); + gtk_label_set_markup_with_mnemonic(GTK_LABEL(_l[2]), _("_B:")); + _s[2]->set_tooltip_text(_("Blue")); + gtk_widget_set_tooltip_text(_b[2], _("Blue")); + gtk_label_set_markup_with_mnemonic(GTK_LABEL(_l[3]), _("_A:")); + _s[3]->set_tooltip_text(_("Alpha (opacity)")); + gtk_widget_set_tooltip_text(_b[3], _("Alpha (opacity)")); + _s[0]->setMap(NULL); + gtk_widget_hide(_l[4]); + _s[4]->hide(); + gtk_widget_hide(_b[4]); + _updating = TRUE; + setScaled(_a[0], rgba[0]); + setScaled(_a[1], rgba[1]); + setScaled(_a[2], rgba[2]); + setScaled(_a[3], rgba[3]); + _updateSliders(CSC_CHANNELS_ALL); + _updating = FALSE; + break; + case SP_COLOR_SCALES_MODE_HSV: + _setRangeLimit(255.0); + gtk_label_set_markup_with_mnemonic(GTK_LABEL(_l[0]), _("_H:")); + _s[0]->set_tooltip_text(_("Hue")); + gtk_widget_set_tooltip_text(_b[0], _("Hue")); + gtk_label_set_markup_with_mnemonic(GTK_LABEL(_l[1]), _("_S:")); + _s[1]->set_tooltip_text(_("Saturation")); + gtk_widget_set_tooltip_text(_b[1], _("Saturation")); + gtk_label_set_markup_with_mnemonic(GTK_LABEL(_l[2]), _("_L:")); + _s[2]->set_tooltip_text(_("Lightness")); + gtk_widget_set_tooltip_text(_b[2], _("Lightness")); + gtk_label_set_markup_with_mnemonic(GTK_LABEL(_l[3]), _("_A:")); + _s[3]->set_tooltip_text(_("Alpha (opacity)")); + gtk_widget_set_tooltip_text(_b[3], _("Alpha (opacity)")); + _s[0]->setMap((guchar *)(sp_color_scales_hue_map())); + gtk_widget_hide(_l[4]); + _s[4]->hide(); + gtk_widget_hide(_b[4]); + _updating = TRUE; + c[0] = 0.0; + sp_color_rgb_to_hsl_floatv(c, rgba[0], rgba[1], rgba[2]); + setScaled(_a[0], c[0]); + setScaled(_a[1], c[1]); + setScaled(_a[2], c[2]); + setScaled(_a[3], rgba[3]); + _updateSliders(CSC_CHANNELS_ALL); + _updating = FALSE; + break; + case SP_COLOR_SCALES_MODE_CMYK: + _setRangeLimit(100.0); + gtk_label_set_markup_with_mnemonic(GTK_LABEL(_l[0]), _("_C:")); + _s[0]->set_tooltip_text(_("Cyan")); + gtk_widget_set_tooltip_text(_b[0], _("Cyan")); + gtk_label_set_markup_with_mnemonic(GTK_LABEL(_l[1]), _("_M:")); + _s[1]->set_tooltip_text(_("Magenta")); + gtk_widget_set_tooltip_text(_b[1], _("Magenta")); + gtk_label_set_markup_with_mnemonic(GTK_LABEL(_l[2]), _("_Y:")); + _s[2]->set_tooltip_text(_("Yellow")); + gtk_widget_set_tooltip_text(_b[2], _("Yellow")); + gtk_label_set_markup_with_mnemonic(GTK_LABEL(_l[3]), _("_K:")); + _s[3]->set_tooltip_text(_("Black")); + gtk_widget_set_tooltip_text(_b[3], _("Black")); + gtk_label_set_markup_with_mnemonic(GTK_LABEL(_l[4]), _("_A:")); + _s[4]->set_tooltip_text(_("Alpha (opacity)")); + gtk_widget_set_tooltip_text(_b[4], _("Alpha (opacity)")); + _s[0]->setMap(NULL); + gtk_widget_show(_l[4]); + _s[4]->show(); + gtk_widget_show(_b[4]); + _updating = TRUE; + + sp_color_rgb_to_cmyk_floatv(c, rgba[0], rgba[1], rgba[2]); + setScaled(_a[0], c[0]); + setScaled(_a[1], c[1]); + setScaled(_a[2], c[2]); + setScaled(_a[3], c[3]); + + setScaled(_a[4], rgba[3]); + _updateSliders(CSC_CHANNELS_ALL); + _updating = FALSE; + break; + default: + g_warning("file %s: line %d: Illegal color selector mode", __FILE__, __LINE__); + break; + } +} + +SPColorScalesMode ColorScales::getMode() const { return _mode; } + +void ColorScales::_adjustmentAnyChanged(GtkAdjustment *adjustment, ColorScales *cs) +{ + gint channel = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(adjustment), "channel")); + + _adjustmentChanged(cs, channel); +} + +void ColorScales::_sliderAnyGrabbed() +{ + if (_updating) { + return; + } + if (!_dragging) { + _dragging = TRUE; + _color.setHeld(true); + } +} + +void ColorScales::_sliderAnyReleased() +{ + if (_updating) { + return; + } + if (_dragging) { + _dragging = FALSE; + _color.setHeld(false); + } +} + +void ColorScales::_sliderAnyChanged() +{ + if (_updating) { + return; + } + _recalcColor(); +} + +void ColorScales::_adjustmentChanged(ColorScales *scales, guint channel) +{ + if (scales->_updating) { + return; + } + + scales->_updateSliders((1 << channel)); + scales->_recalcColor(); +} + +void ColorScales::_updateSliders(guint channels) +{ + gfloat rgb0[3], rgbm[3], rgb1[3]; +#ifdef SPCS_PREVIEW + guint32 rgba; +#endif + switch (_mode) { + case SP_COLOR_SCALES_MODE_RGB: + if ((channels != CSC_CHANNEL_R) && (channels != CSC_CHANNEL_A)) { + /* Update red */ + _s[0]->setColors(SP_RGBA32_F_COMPOSE(0.0, getScaled(_a[1]), getScaled(_a[2]), 1.0), + SP_RGBA32_F_COMPOSE(0.5, getScaled(_a[1]), getScaled(_a[2]), 1.0), + SP_RGBA32_F_COMPOSE(1.0, getScaled(_a[1]), getScaled(_a[2]), 1.0)); + } + if ((channels != CSC_CHANNEL_G) && (channels != CSC_CHANNEL_A)) { + /* Update green */ + _s[1]->setColors(SP_RGBA32_F_COMPOSE(getScaled(_a[0]), 0.0, getScaled(_a[2]), 1.0), + SP_RGBA32_F_COMPOSE(getScaled(_a[0]), 0.5, getScaled(_a[2]), 1.0), + SP_RGBA32_F_COMPOSE(getScaled(_a[0]), 1.0, getScaled(_a[2]), 1.0)); + } + if ((channels != CSC_CHANNEL_B) && (channels != CSC_CHANNEL_A)) { + /* Update blue */ + _s[2]->setColors(SP_RGBA32_F_COMPOSE(getScaled(_a[0]), getScaled(_a[1]), 0.0, 1.0), + SP_RGBA32_F_COMPOSE(getScaled(_a[0]), getScaled(_a[1]), 0.5, 1.0), + SP_RGBA32_F_COMPOSE(getScaled(_a[0]), getScaled(_a[1]), 1.0, 1.0)); + } + if (channels != CSC_CHANNEL_A) { + /* Update alpha */ + _s[3]->setColors(SP_RGBA32_F_COMPOSE(getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), 0.0), + SP_RGBA32_F_COMPOSE(getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), 0.5), + SP_RGBA32_F_COMPOSE(getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), 1.0)); + } + break; + case SP_COLOR_SCALES_MODE_HSV: + /* Hue is never updated */ + if ((channels != CSC_CHANNEL_S) && (channels != CSC_CHANNEL_A)) { + /* Update saturation */ + sp_color_hsl_to_rgb_floatv(rgb0, getScaled(_a[0]), 0.0, getScaled(_a[2])); + sp_color_hsl_to_rgb_floatv(rgbm, getScaled(_a[0]), 0.5, getScaled(_a[2])); + sp_color_hsl_to_rgb_floatv(rgb1, getScaled(_a[0]), 1.0, getScaled(_a[2])); + _s[1]->setColors(SP_RGBA32_F_COMPOSE(rgb0[0], rgb0[1], rgb0[2], 1.0), + SP_RGBA32_F_COMPOSE(rgbm[0], rgbm[1], rgbm[2], 1.0), + SP_RGBA32_F_COMPOSE(rgb1[0], rgb1[1], rgb1[2], 1.0)); + } + if ((channels != CSC_CHANNEL_V) && (channels != CSC_CHANNEL_A)) { + /* Update value */ + sp_color_hsl_to_rgb_floatv(rgb0, getScaled(_a[0]), getScaled(_a[1]), 0.0); + sp_color_hsl_to_rgb_floatv(rgbm, getScaled(_a[0]), getScaled(_a[1]), 0.5); + sp_color_hsl_to_rgb_floatv(rgb1, getScaled(_a[0]), getScaled(_a[1]), 1.0); + _s[2]->setColors(SP_RGBA32_F_COMPOSE(rgb0[0], rgb0[1], rgb0[2], 1.0), + SP_RGBA32_F_COMPOSE(rgbm[0], rgbm[1], rgbm[2], 1.0), + SP_RGBA32_F_COMPOSE(rgb1[0], rgb1[1], rgb1[2], 1.0)); + } + if (channels != CSC_CHANNEL_A) { + /* Update alpha */ + sp_color_hsl_to_rgb_floatv(rgb0, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2])); + _s[3]->setColors(SP_RGBA32_F_COMPOSE(rgb0[0], rgb0[1], rgb0[2], 0.0), + SP_RGBA32_F_COMPOSE(rgb0[0], rgb0[1], rgb0[2], 0.5), + SP_RGBA32_F_COMPOSE(rgb0[0], rgb0[1], rgb0[2], 1.0)); + } + break; + case SP_COLOR_SCALES_MODE_CMYK: + if ((channels != CSC_CHANNEL_C) && (channels != CSC_CHANNEL_CMYKA)) { + /* Update C */ + sp_color_cmyk_to_rgb_floatv(rgb0, 0.0, getScaled(_a[1]), getScaled(_a[2]), getScaled(_a[3])); + sp_color_cmyk_to_rgb_floatv(rgbm, 0.5, getScaled(_a[1]), getScaled(_a[2]), getScaled(_a[3])); + sp_color_cmyk_to_rgb_floatv(rgb1, 1.0, getScaled(_a[1]), getScaled(_a[2]), getScaled(_a[3])); + _s[0]->setColors(SP_RGBA32_F_COMPOSE(rgb0[0], rgb0[1], rgb0[2], 1.0), + SP_RGBA32_F_COMPOSE(rgbm[0], rgbm[1], rgbm[2], 1.0), + SP_RGBA32_F_COMPOSE(rgb1[0], rgb1[1], rgb1[2], 1.0)); + } + if ((channels != CSC_CHANNEL_M) && (channels != CSC_CHANNEL_CMYKA)) { + /* Update M */ + sp_color_cmyk_to_rgb_floatv(rgb0, getScaled(_a[0]), 0.0, getScaled(_a[2]), getScaled(_a[3])); + sp_color_cmyk_to_rgb_floatv(rgbm, getScaled(_a[0]), 0.5, getScaled(_a[2]), getScaled(_a[3])); + sp_color_cmyk_to_rgb_floatv(rgb1, getScaled(_a[0]), 1.0, getScaled(_a[2]), getScaled(_a[3])); + _s[1]->setColors(SP_RGBA32_F_COMPOSE(rgb0[0], rgb0[1], rgb0[2], 1.0), + SP_RGBA32_F_COMPOSE(rgbm[0], rgbm[1], rgbm[2], 1.0), + SP_RGBA32_F_COMPOSE(rgb1[0], rgb1[1], rgb1[2], 1.0)); + } + if ((channels != CSC_CHANNEL_Y) && (channels != CSC_CHANNEL_CMYKA)) { + /* Update Y */ + sp_color_cmyk_to_rgb_floatv(rgb0, getScaled(_a[0]), getScaled(_a[1]), 0.0, getScaled(_a[3])); + sp_color_cmyk_to_rgb_floatv(rgbm, getScaled(_a[0]), getScaled(_a[1]), 0.5, getScaled(_a[3])); + sp_color_cmyk_to_rgb_floatv(rgb1, getScaled(_a[0]), getScaled(_a[1]), 1.0, getScaled(_a[3])); + _s[2]->setColors(SP_RGBA32_F_COMPOSE(rgb0[0], rgb0[1], rgb0[2], 1.0), + SP_RGBA32_F_COMPOSE(rgbm[0], rgbm[1], rgbm[2], 1.0), + SP_RGBA32_F_COMPOSE(rgb1[0], rgb1[1], rgb1[2], 1.0)); + } + if ((channels != CSC_CHANNEL_K) && (channels != CSC_CHANNEL_CMYKA)) { + /* Update K */ + sp_color_cmyk_to_rgb_floatv(rgb0, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), 0.0); + sp_color_cmyk_to_rgb_floatv(rgbm, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), 0.5); + sp_color_cmyk_to_rgb_floatv(rgb1, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), 1.0); + _s[3]->setColors(SP_RGBA32_F_COMPOSE(rgb0[0], rgb0[1], rgb0[2], 1.0), + SP_RGBA32_F_COMPOSE(rgbm[0], rgbm[1], rgbm[2], 1.0), + SP_RGBA32_F_COMPOSE(rgb1[0], rgb1[1], rgb1[2], 1.0)); + } + if (channels != CSC_CHANNEL_CMYKA) { + /* Update alpha */ + sp_color_cmyk_to_rgb_floatv(rgb0, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), + getScaled(_a[3])); + _s[4]->setColors(SP_RGBA32_F_COMPOSE(rgb0[0], rgb0[1], rgb0[2], 0.0), + SP_RGBA32_F_COMPOSE(rgb0[0], rgb0[1], rgb0[2], 0.5), + SP_RGBA32_F_COMPOSE(rgb0[0], rgb0[1], rgb0[2], 1.0)); + } + break; + default: + g_warning("file %s: line %d: Illegal color selector mode", __FILE__, __LINE__); + break; + } + +#ifdef SPCS_PREVIEW + rgba = sp_color_scales_get_rgba32(cs); + sp_color_preview_set_rgba32(SP_COLOR_PREVIEW(_p), rgba); +#endif +} + +static const gchar *sp_color_scales_hue_map(void) +{ + static gchar *map = NULL; + + if (!map) { + gchar *p; + gint h; + map = g_new(gchar, 4 * 1024); + p = map; + for (h = 0; h < 1024; h++) { + gfloat rgb[3]; + sp_color_hsl_to_rgb_floatv(rgb, h / 1024.0, 1.0, 0.5); + *p++ = SP_COLOR_F_TO_U(rgb[0]); + *p++ = SP_COLOR_F_TO_U(rgb[1]); + *p++ = SP_COLOR_F_TO_U(rgb[2]); + *p++ = 255; + } + } + + return map; +} + +ColorScalesFactory::ColorScalesFactory(SPColorScalesMode submode) + : _submode(submode) +{ +} + +ColorScalesFactory::~ColorScalesFactory() {} + +Gtk::Widget *ColorScalesFactory::createWidget(Inkscape::UI::SelectedColor &color) const +{ + Gtk::Widget *w = Gtk::manage(new ColorScales(color, _submode)); + return w; +} + +Glib::ustring ColorScalesFactory::modeName() const { + return gettext(ColorScales::SUBMODE_NAMES[_submode]); +} + +} +} +} diff --git a/src/ui/widget/color-scales.h b/src/ui/widget/color-scales.h new file mode 100644 index 000000000..aeacfbcc1 --- /dev/null +++ b/src/ui/widget/color-scales.h @@ -0,0 +1,112 @@ +#ifndef SEEN_SP_COLOR_SCALES_H +#define SEEN_SP_COLOR_SCALES_H + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#if WITH_GTKMM_3_0 +#include <gtkmm/grid.h> +#else +#include <gtkmm/table.h> +#endif + +#include "ui/selected-color.h" + +namespace Inkscape { +namespace UI { +namespace Widget { + +class ColorSlider; + +typedef enum { + SP_COLOR_SCALES_MODE_NONE = 0, + SP_COLOR_SCALES_MODE_RGB = 1, + SP_COLOR_SCALES_MODE_HSV = 2, + SP_COLOR_SCALES_MODE_CMYK = 3 +} SPColorScalesMode; + +class ColorScales +#if GTK_CHECK_VERSION(3, 0, 0) + : public Gtk::Grid +#else + : public Gtk::Table +#endif +{ +public: + static const gchar *SUBMODE_NAMES[]; + + static gfloat getScaled(const GtkAdjustment *a); + static void setScaled(GtkAdjustment *a, gfloat v); + + ColorScales(SelectedColor &color, SPColorScalesMode mode); + virtual ~ColorScales(); + + virtual void _initUI(SPColorScalesMode mode); + + void setMode(SPColorScalesMode mode); + SPColorScalesMode getMode() const; + +protected: + void _onColorChanged(); + void on_show(); + + static void _adjustmentAnyChanged(GtkAdjustment *adjustment, ColorScales *cs); + void _sliderAnyGrabbed(); + void _sliderAnyReleased(); + void _sliderAnyChanged(); + static void _adjustmentChanged(ColorScales *cs, guint channel); + + void _getRgbaFloatv(gfloat *rgba); + void _getCmykaFloatv(gfloat *cmyka); + guint32 _getRgba32(); + void _updateSliders(guint channels); + void _recalcColor(); + void _updateDisplay(); + + void _setRangeLimit(gdouble upper); + + SelectedColor &_color; + SPColorScalesMode _mode; + gdouble _rangeLimit; + gboolean _updating : 1; + gboolean _dragging : 1; + GtkAdjustment *_a[5]; /* Channel adjustments */ + Inkscape::UI::Widget::ColorSlider *_s[5]; /* Channel sliders */ + GtkWidget *_b[5]; /* Spinbuttons */ + GtkWidget *_l[5]; /* Labels */ + +private: + // By default, disallow copy constructor and assignment operator + ColorScales(ColorScales const &obj); + ColorScales &operator=(ColorScales const &obj); +}; + +class ColorScalesFactory : public Inkscape::UI::ColorSelectorFactory +{ +public: + ColorScalesFactory(SPColorScalesMode submode); + ~ColorScalesFactory(); + + Gtk::Widget *createWidget(Inkscape::UI::SelectedColor &color) const; + Glib::ustring modeName() const; + +private: + SPColorScalesMode _submode; +}; + +} +} +} + +#endif /* !SEEN_SP_COLOR_SCALES_H */ +/* + 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 : diff --git a/src/ui/widget/color-slider.cpp b/src/ui/widget/color-slider.cpp new file mode 100644 index 000000000..0c9586a67 --- /dev/null +++ b/src/ui/widget/color-slider.cpp @@ -0,0 +1,633 @@ +/** + * @file + * A slider with colored background - implementation. + */ +/* Author: + * Lauris Kaplinski <lauris@kaplinski.com> + * bulia byak <buliabyak@users.sf.net> + * + * Copyright (C) 2001-2002 Lauris Kaplinski + * + * This code is in public domain + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gdkmm/cursor.h> +#include <gdkmm/screen.h> +#include <gdkmm/general.h> +#include <gtkmm/adjustment.h> +#if WITH_GTKMM_3_0 +#include <gtkmm/stylecontext.h> +#else +#include <gtkmm/style.h> +#endif +#include <gtk/gtk.h> + +#include "ui/widget/color-scales.h" +#include "ui/widget/color-slider.h" +#include "preferences.h" + +static const gint SLIDER_WIDTH = 96; +static const gint SLIDER_HEIGHT = 8; +static const gint ARROW_SIZE = 7; + +static const guchar *sp_color_slider_render_gradient(gint x0, gint y0, gint width, gint height, gint c[], gint dc[], + guint b0, guint b1, guint mask); +static const guchar *sp_color_slider_render_map(gint x0, gint y0, gint width, gint height, guchar *map, gint start, + gint step, guint b0, guint b1, guint mask); + +namespace Inkscape { +namespace UI { +namespace Widget { + +#if GTK_CHECK_VERSION(3, 0, 0) +ColorSlider::ColorSlider(Glib::RefPtr<Gtk::Adjustment> adjustment) + : _dragging(false) +#else +ColorSlider::ColorSlider(Gtk::Adjustment *adjustment) + : _dragging(false) + , _adjustment(NULL) +#endif + , _value(0.0) + , _oldvalue(0.0) + , _mapsize(0) + , _map(NULL) +{ + _c0[0] = 0x00; + _c0[1] = 0x00; + _c0[2] = 0x00; + _c0[3] = 0xff; + + _cm[0] = 0xff; + _cm[1] = 0x00; + _cm[2] = 0x00; + _cm[3] = 0xff; + + _c0[0] = 0xff; + _c0[1] = 0xff; + _c0[2] = 0xff; + _c0[3] = 0xff; + + _b0 = 0x5f; + _b1 = 0xa0; + _bmask = 0x08; + + setAdjustment(adjustment); +} + +ColorSlider::~ColorSlider() +{ + if (_adjustment) { + _adjustment_changed_connection.disconnect(); + _adjustment_value_changed_connection.disconnect(); +#if GTK_CHECK_VERSION(3, 0, 0) + _adjustment.reset(); +#else + _adjustment->unreference(); + _adjustment = NULL; +#endif + } +} + +void ColorSlider::on_realize() +{ + set_realized(); + + if (!_gdk_window) { + GdkWindowAttr attributes; + gint attributes_mask; + Gtk::Allocation allocation = get_allocation(); + + memset(&attributes, 0, sizeof(attributes)); + attributes.x = allocation.get_x(); + attributes.y = allocation.get_y(); + attributes.width = allocation.get_width(); + attributes.height = allocation.get_height(); + attributes.window_type = GDK_WINDOW_CHILD; + attributes.wclass = GDK_INPUT_OUTPUT; + attributes.visual = gdk_screen_get_system_visual(gdk_screen_get_default()); +#if !GTK_CHECK_VERSION(3, 0, 0) + attributes.colormap = gdk_screen_get_system_colormap(gdk_screen_get_default()); +#endif + attributes.event_mask = get_events(); + attributes.event_mask |= (Gdk::EXPOSURE_MASK | Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK | + Gdk::POINTER_MOTION_MASK | Gdk::ENTER_NOTIFY_MASK | Gdk::LEAVE_NOTIFY_MASK); + +#if GTK_CHECK_VERSION(3, 0, 0) + attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL; +#else + attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; +#endif + + _gdk_window = Gdk::Window::create(get_parent_window(), &attributes, attributes_mask); + set_window(_gdk_window); + _gdk_window->set_user_data(gobj()); + +#if !GTK_CHECK_VERSION(3, 0, 0) + style_attach(); +#endif + } +} + +void ColorSlider::on_unrealize() +{ + _gdk_window.reset(); + + Gtk::Widget::on_unrealize(); +} + +void ColorSlider::on_size_allocate(Gtk::Allocation &allocation) +{ + set_allocation(allocation); + + if (get_realized()) { + _gdk_window->move_resize(allocation.get_x(), allocation.get_y(), allocation.get_width(), + allocation.get_height()); + } +} + +#if GTK_CHECK_VERSION(3, 0, 0) + +void ColorSlider::get_preferred_width_vfunc(int &minimum_width, int &natural_width) const +{ + Glib::RefPtr<Gtk::StyleContext> style_context = get_style_context(); + Gtk::Border padding = style_context->get_padding(get_state_flags()); + int width = SLIDER_WIDTH + padding.get_left() + padding.get_right(); + minimum_width = natural_width = width; +} + +void ColorSlider::get_preferred_width_for_height_vfunc(int /*height*/, int &minimum_width, int &natural_width) const +{ + get_preferred_width(minimum_width, natural_width); +} + +void ColorSlider::get_preferred_height_vfunc(int &minimum_height, int &natural_height) const +{ + Glib::RefPtr<Gtk::StyleContext> style_context = get_style_context(); + Gtk::Border padding = style_context->get_padding(get_state_flags()); + int height = SLIDER_HEIGHT + padding.get_top() + padding.get_bottom(); + minimum_height = natural_height = height; +} + +void ColorSlider::get_preferred_height_for_width_vfunc(int /*width*/, int &minimum_height, int &natural_height) const +{ + get_preferred_height(minimum_height, natural_height); +} + +#else + +void ColorSlider::on_size_request(Gtk::Requisition *requisition) +{ + GtkStyle *style = gtk_widget_get_style(gobj()); + requisition->width = SLIDER_WIDTH + style->xthickness * 2; + requisition->height = SLIDER_HEIGHT + style->ythickness * 2; +} + +bool ColorSlider::on_expose_event(GdkEventExpose *event) +{ + bool result = false; + + if (get_is_drawable()) { + Cairo::RefPtr<Cairo::Context> cr = _gdk_window->create_cairo_context(); + result = on_draw(cr); + } + return result; +} + +#endif + +bool ColorSlider::on_button_press_event(GdkEventButton *event) +{ + if (event->button == 1) { + Gtk::Allocation allocation = get_allocation(); + gint cx, cw; +#if GTK_CHECK_VERSION(3, 0, 0) + cx = get_style_context()->get_padding(get_state_flags()).get_left(); +#else + cx = get_style()->get_xthickness(); +#endif + cw = allocation.get_width() - 2 * cx; + signal_grabbed.emit(); + _dragging = true; + _oldvalue = _value; + ColorScales::setScaled(_adjustment->gobj(), CLAMP((gfloat)(event->x - cx) / cw, 0.0, 1.0)); + signal_dragged.emit(); + +#if GTK_CHECK_VERSION(3, 0, 0) + gdk_device_grab( + gdk_event_get_device(reinterpret_cast<GdkEvent *>(event)), _gdk_window->gobj(), GDK_OWNERSHIP_NONE, FALSE, + static_cast<GdkEventMask>(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK), NULL, event->time); +#else + gdk_pointer_grab(get_window()->gobj(), FALSE, + static_cast<GdkEventMask>(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK), NULL, NULL, + event->time); +#endif + } + + return false; +} + +bool ColorSlider::on_button_release_event(GdkEventButton *event) +{ + if (event->button == 1) { + +#if GTK_CHECK_VERSION(3, 0, 0) + gdk_device_ungrab(gdk_event_get_device(reinterpret_cast<GdkEvent *>(event)), + gdk_event_get_time(reinterpret_cast<GdkEvent *>(event))); +#else + get_window()->pointer_ungrab(event->time); +#endif + + _dragging = false; + signal_released.emit(); + if (_value != _oldvalue) { + signal_value_changed.emit(); + } + } + + return false; +} + +bool ColorSlider::on_motion_notify_event(GdkEventMotion *event) +{ + if (_dragging) { + gint cx, cw; + Gtk::Allocation allocation = get_allocation(); +#if GTK_CHECK_VERSION(3, 0, 0) + cx = get_style_context()->get_padding(get_state_flags()).get_left(); +#else + cx = get_style()->get_xthickness(); +#endif + cw = allocation.get_width() - 2 * cx; + ColorScales::setScaled(_adjustment->gobj(), CLAMP((gfloat)(event->x - cx) / cw, 0.0, 1.0)); + signal_dragged.emit(); + } + + return false; +} + +#if GTK_CHECK_VERSION(3, 0, 0) +void ColorSlider::setAdjustment(Glib::RefPtr<Gtk::Adjustment> adjustment) +{ +#else +void ColorSlider::setAdjustment(Gtk::Adjustment *adjustment) +{ +#endif + if (!adjustment) { +#if GTK_CHECK_VERSION(3, 0, 0) + _adjustment = Gtk::Adjustment::create(0.0, 0.0, 1.0, 0.01, 0.0, 0.0); +#else + _adjustment = Gtk::manage(new Gtk::Adjustment(0.0, 0.0, 1.0, 0.01, 0.0, 0.0)); +#endif + } + else { + adjustment->set_page_increment(0.0); + adjustment->set_page_size(0.0); + } + + if (_adjustment != adjustment) { + if (_adjustment) { + _adjustment_changed_connection.disconnect(); + _adjustment_value_changed_connection.disconnect(); +#if !GTK_CHECK_VERSION(3, 0, 0) + _adjustment->unreference(); +#endif + } + + _adjustment = adjustment; + _adjustment_changed_connection = + _adjustment->signal_changed().connect(sigc::mem_fun(this, &ColorSlider::_onAdjustmentChanged)); + _adjustment_value_changed_connection = + _adjustment->signal_value_changed().connect(sigc::mem_fun(this, &ColorSlider::_onAdjustmentValueChanged)); + + _value = ColorScales::getScaled(_adjustment->gobj()); + + _onAdjustmentChanged(); + } +} + +void ColorSlider::_onAdjustmentChanged() { queue_draw(); } + +void ColorSlider::_onAdjustmentValueChanged() +{ + if (_value != ColorScales::getScaled(_adjustment->gobj())) { + gint cx, cy, cw, ch; +#if GTK_CHECK_VERSION(3, 0, 0) + Glib::RefPtr<Gtk::StyleContext> style_context = get_style_context(); + Gtk::Allocation allocation = get_allocation(); + Gtk::Border padding = style_context->get_padding(get_state_flags()); + cx = padding.get_left(); + cy = padding.get_top(); +#else + Glib::RefPtr<Gtk::Style> style = get_style(); + Gtk::Allocation allocation = get_allocation(); + cx = style->get_xthickness(); + cy = style->get_ythickness(); +#endif + cw = allocation.get_width() - 2 * cx; + ch = allocation.get_height() - 2 * cy; + if ((gint)(ColorScales::getScaled(_adjustment->gobj()) * cw) != (gint)(_value * cw)) { + gint ax, ay; + gfloat value; + value = _value; + _value = ColorScales::getScaled(_adjustment->gobj()); + ax = (int)(cx + value * cw - ARROW_SIZE / 2 - 2); + ay = cy; + queue_draw_area(ax, ay, ARROW_SIZE + 4, ch); + ax = (int)(cx + _value * cw - ARROW_SIZE / 2 - 2); + ay = cy; + queue_draw_area(ax, ay, ARROW_SIZE + 4, ch); + } + else { + _value = ColorScales::getScaled(_adjustment->gobj()); + } + } +} + +void ColorSlider::setColors(guint32 start, guint32 mid, guint32 end) +{ + // Remove any map, if set + _map = 0; + + _c0[0] = start >> 24; + _c0[1] = (start >> 16) & 0xff; + _c0[2] = (start >> 8) & 0xff; + _c0[3] = start & 0xff; + + _cm[0] = mid >> 24; + _cm[1] = (mid >> 16) & 0xff; + _cm[2] = (mid >> 8) & 0xff; + _cm[3] = mid & 0xff; + + _c1[0] = end >> 24; + _c1[1] = (end >> 16) & 0xff; + _c1[2] = (end >> 8) & 0xff; + _c1[3] = end & 0xff; + + queue_draw(); +} + +void ColorSlider::setMap(const guchar *map) +{ + _map = const_cast<guchar *>(map); + + queue_draw(); +} + +void ColorSlider::setBackground(guint dark, guint light, guint size) +{ + _b0 = dark; + _b1 = light; + _bmask = size; + + queue_draw(); +} + +bool ColorSlider::on_draw(const Cairo::RefPtr<Cairo::Context> &cr) +{ + gboolean colorsOnTop = Inkscape::Preferences::get()->getBool("/options/workarounds/colorsontop", false); + + Gtk::Allocation allocation = get_allocation(); + +#if GTK_CHECK_VERSION(3, 0, 0) + Glib::RefPtr<Gtk::StyleContext> style_context = get_style_context(); +#else + Glib::RefPtr<Gdk::Window> window = get_window(); + Glib::RefPtr<Gtk::Style> style = get_style(); +#endif + + // Draw shadow + if (colorsOnTop) { +#if GTK_CHECK_VERSION(3, 0, 0) + style_context->render_frame(cr, 0, 0, allocation.get_width(), allocation.get_height()); +#else + gtk_paint_shadow(style->gobj(), window->gobj(), gtk_widget_get_state(gobj()), GTK_SHADOW_IN, NULL, gobj(), + "colorslider", 0, 0, allocation.get_width(), allocation.get_height()); +#endif + } + + /* Paintable part of color gradient area */ + Gdk::Rectangle carea; + +#if GTK_CHECK_VERSION(3, 0, 0) + Gtk::Border padding; + + padding = style_context->get_padding(get_state_flags()); + + carea.set_x(padding.get_left()); + carea.set_y(padding.get_top()); + ; +#else + carea.set_x(style->get_xthickness()); + carea.set_y(style->get_ythickness()); +#endif + + carea.set_width(allocation.get_width() - 2 * carea.get_x()); + carea.set_height(allocation.get_height() - 2 * carea.get_y()); + + if (_map) { + /* Render map pixelstore */ + gint d = (1024 << 16) / carea.get_width(); + gint s = 0; + + const guchar *b = + sp_color_slider_render_map(0, 0, carea.get_width(), carea.get_height(), _map, s, d, _b0, _b1, _bmask); + + if (b != NULL && carea.get_width() > 0) { + Glib::RefPtr<Gdk::Pixbuf> pb = Gdk::Pixbuf::create_from_data( + b, Gdk::COLORSPACE_RGB, false, 8, carea.get_width(), carea.get_height(), carea.get_width() * 3); + + Gdk::Cairo::set_source_pixbuf(cr, pb, carea.get_x(), carea.get_y()); + cr->paint(); + } + } + else { + gint c[4], dc[4]; + + /* Render gradient */ + + // part 1: from c0 to cm + if (carea.get_width() > 0) { + for (gint i = 0; i < 4; i++) { + c[i] = _c0[i] << 16; + dc[i] = ((_cm[i] << 16) - c[i]) / (carea.get_width() / 2); + } + guint wi = carea.get_width() / 2; + const guchar *b = sp_color_slider_render_gradient(0, 0, wi, carea.get_height(), c, dc, _b0, _b1, _bmask); + + /* Draw pixelstore 1 */ + if (b != NULL && wi > 0) { + Glib::RefPtr<Gdk::Pixbuf> pb = + Gdk::Pixbuf::create_from_data(b, Gdk::COLORSPACE_RGB, false, 8, wi, carea.get_height(), wi * 3); + + Gdk::Cairo::set_source_pixbuf(cr, pb, carea.get_x(), carea.get_y()); + cr->paint(); + } + } + + // part 2: from cm to c1 + if (carea.get_width() > 0) { + for (gint i = 0; i < 4; i++) { + c[i] = _cm[i] << 16; + dc[i] = ((_c1[i] << 16) - c[i]) / (carea.get_width() / 2); + } + guint wi = carea.get_width() / 2; + const guchar *b = sp_color_slider_render_gradient(carea.get_width() / 2, 0, wi, carea.get_height(), c, dc, + _b0, _b1, _bmask); + + /* Draw pixelstore 2 */ + if (b != NULL && wi > 0) { + Glib::RefPtr<Gdk::Pixbuf> pb = + Gdk::Pixbuf::create_from_data(b, Gdk::COLORSPACE_RGB, false, 8, wi, carea.get_height(), wi * 3); + + Gdk::Cairo::set_source_pixbuf(cr, pb, carea.get_width() / 2 + carea.get_x(), carea.get_y()); + cr->paint(); + } + } + } + + /* Draw shadow */ + if (!colorsOnTop) { +#if GTK_CHECK_VERSION(3, 0, 0) + style_context->render_frame(cr, 0, 0, allocation.get_width(), allocation.get_height()); +#else + gtk_paint_shadow(style->gobj(), window->gobj(), gtk_widget_get_state(gobj()), GTK_SHADOW_IN, NULL, gobj(), + "colorslider", 0, 0, allocation.get_width(), allocation.get_height()); +#endif + } + + /* Draw arrow */ + gint x = (int)(_value * (carea.get_width() - 1) - ARROW_SIZE / 2 + carea.get_x()); + gint y1 = carea.get_y(); + gint y2 = carea.get_y() + carea.get_height() - 1; + cr->set_line_width(1.0); + + // Define top arrow + cr->move_to(x - 0.5, y1 + 0.5); + cr->line_to(x + ARROW_SIZE - 0.5, y1 + 0.5); + cr->line_to(x + (ARROW_SIZE - 1) / 2.0, y1 + ARROW_SIZE / 2.0 + 0.5); + cr->line_to(x - 0.5, y1 + 0.5); + + // Define bottom arrow + cr->move_to(x - 0.5, y2 + 0.5); + cr->line_to(x + ARROW_SIZE - 0.5, y2 + 0.5); + cr->line_to(x + (ARROW_SIZE - 1) / 2.0, y2 - ARROW_SIZE / 2.0 + 0.5); + cr->line_to(x - 0.5, y2 + 0.5); + + // Render both arrows + cr->set_source_rgb(1.0, 1.0, 1.0); + cr->stroke_preserve(); + cr->set_source_rgb(0.0, 0.0, 0.0); + cr->fill(); + + return false; +} + +} // namespace Widget +} // namespace UI +} // namespace Inkscape + +/* Colors are << 16 */ + +static const guchar *sp_color_slider_render_gradient(gint x0, gint y0, gint width, gint height, gint c[], gint dc[], + guint b0, guint b1, guint mask) +{ + static guchar *buf = NULL; + static gint bs = 0; + guchar *dp; + gint x, y; + guint r, g, b, a; + + if (buf && (bs < width * height)) { + g_free(buf); + buf = NULL; + } + if (!buf) { + buf = g_new(guchar, width * height * 3); + bs = width * height; + } + + dp = buf; + r = c[0]; + g = c[1]; + b = c[2]; + a = c[3]; + for (x = x0; x < x0 + width; x++) { + gint cr, cg, cb, ca; + guchar *d; + cr = r >> 16; + cg = g >> 16; + cb = b >> 16; + ca = a >> 16; + d = dp; + for (y = y0; y < y0 + height; y++) { + guint bg, fc; + /* Background value */ + bg = ((x & mask) ^ (y & mask)) ? b0 : b1; + fc = (cr - bg) * ca; + d[0] = bg + ((fc + (fc >> 8) + 0x80) >> 8); + fc = (cg - bg) * ca; + d[1] = bg + ((fc + (fc >> 8) + 0x80) >> 8); + fc = (cb - bg) * ca; + d[2] = bg + ((fc + (fc >> 8) + 0x80) >> 8); + d += 3 * width; + } + r += dc[0]; + g += dc[1]; + b += dc[2]; + a += dc[3]; + dp += 3; + } + + return buf; +} + +/* Positions are << 16 */ + +static const guchar *sp_color_slider_render_map(gint x0, gint y0, gint width, gint height, guchar *map, gint start, + gint step, guint b0, guint b1, guint mask) +{ + static guchar *buf = NULL; + static gint bs = 0; + guchar *dp; + gint x, y; + + if (buf && (bs < width * height)) { + g_free(buf); + buf = NULL; + } + if (!buf) { + buf = g_new(guchar, width * height * 3); + bs = width * height; + } + + dp = buf; + for (x = x0; x < x0 + width; x++) { + gint cr, cg, cb, ca; + guchar *d = dp; + guchar *sp = map + 4 * (start >> 16); + cr = *sp++; + cg = *sp++; + cb = *sp++; + ca = *sp++; + for (y = y0; y < y0 + height; y++) { + guint bg, fc; + /* Background value */ + bg = ((x & mask) ^ (y & mask)) ? b0 : b1; + fc = (cr - bg) * ca; + d[0] = bg + ((fc + (fc >> 8) + 0x80) >> 8); + fc = (cg - bg) * ca; + d[1] = bg + ((fc + (fc >> 8) + 0x80) >> 8); + fc = (cb - bg) * ca; + d[2] = bg + ((fc + (fc >> 8) + 0x80) >> 8); + d += 3 * width; + } + dp += 3; + start += step; + } + + return buf; +} diff --git a/src/ui/widget/color-slider.h b/src/ui/widget/color-slider.h new file mode 100644 index 000000000..253f3123c --- /dev/null +++ b/src/ui/widget/color-slider.h @@ -0,0 +1,110 @@ +/* + * A slider with colored background + * + * Author: + * Lauris Kaplinski <lauris@kaplinski.com> + * + * Copyright (C) 2001-2002 Lauris Kaplinski + * + * This code is in public domain + */ + +#ifndef SEEN_COLOR_SLIDER_H +#define SEEN_COLOR_SLIDER_H + +#include <gtkmm/widget.h> +#include <sigc++/signal.h> + +namespace Inkscape { +namespace UI { +namespace Widget { + +/* + * A slider with colored background + */ +class ColorSlider : public Gtk::Widget { +public: +#if GTK_CHECK_VERSION(3, 0, 0) + ColorSlider(Glib::RefPtr<Gtk::Adjustment> adjustment); +#else + ColorSlider(Gtk::Adjustment *adjustment); +#endif + ~ColorSlider(); + +#if GTK_CHECK_VERSION(3, 0, 0) + void setAdjustment(Glib::RefPtr<Gtk::Adjustment> adjustment); +#else + void setAdjustment(Gtk::Adjustment *adjustment); +#endif + + void setColors(guint32 start, guint32 mid, guint32 end); + + void setMap(const guchar *map); + + void setBackground(guint dark, guint light, guint size); + + sigc::signal<void> signal_grabbed; + sigc::signal<void> signal_dragged; + sigc::signal<void> signal_released; + sigc::signal<void> signal_value_changed; + +protected: + void on_size_allocate(Gtk::Allocation &allocation); + void on_realize(); + void on_unrealize(); + bool on_button_press_event(GdkEventButton *event); + bool on_button_release_event(GdkEventButton *event); + bool on_motion_notify_event(GdkEventMotion *event); + bool on_draw(const Cairo::RefPtr<Cairo::Context> &cr); + +#if GTK_CHECK_VERSION(3, 0, 0) + void get_preferred_width_vfunc(int &minimum_width, int &natural_width) const; + void get_preferred_width_for_height_vfunc(int height, int &minimum_width, int &natural_width) const; + void get_preferred_height_vfunc(int &minimum_height, int &natural_height) const; + void get_preferred_height_for_width_vfunc(int width, int &minimum_height, int &natural_height) const; +#else + void on_size_request(Gtk::Requisition *requisition); + bool on_expose_event(GdkEventExpose *event); +#endif + +private: + void _onAdjustmentChanged(); + void _onAdjustmentValueChanged(); + + bool _dragging; + +#if GTK_CHECK_VERSION(3, 0, 0) + Glib::RefPtr<Gtk::Adjustment> _adjustment; +#else + Gtk::Adjustment *_adjustment; +#endif + sigc::connection _adjustment_changed_connection; + sigc::connection _adjustment_value_changed_connection; + + gfloat _value; + gfloat _oldvalue; + guchar _c0[4], _cm[4], _c1[4]; + guchar _b0, _b1; + guchar _bmask; + + gint _mapsize; + guchar *_map; + + Glib::RefPtr<Gdk::Window> _gdk_window; +}; + +} // namespace Widget +} // namespace UI +} // namespace Inkscape + +#endif +/* + 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 : diff --git a/src/ui/widget/color-wheel-selector.cpp b/src/ui/widget/color-wheel-selector.cpp new file mode 100644 index 000000000..ed3400bb5 --- /dev/null +++ b/src/ui/widget/color-wheel-selector.cpp @@ -0,0 +1,302 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "color-wheel-selector.h" + +#include <math.h> +#include <gtk/gtk.h> +#include <glibmm/i18n.h> +#include <gtkmm/adjustment.h> +#include <gtkmm/label.h> +#include <gtkmm/spinbutton.h> +#include "svg/svg-icc-color.h" +#include "ui/dialog-events.h" +#include "ui/selected-color.h" +#include "ui/widget/color-scales.h" +#include "ui/widget/color-slider.h" +#include "ui/widget/gimpcolorwheel.h" + +namespace Inkscape { +namespace UI { +namespace Widget { + + +#define XPAD 4 +#define YPAD 1 + + +const gchar *ColorWheelSelector::MODE_NAME = N_("Wheel"); + +ColorWheelSelector::ColorWheelSelector(SelectedColor &color) +#if GTK_CHECK_VERSION(3, 0, 0) + : Gtk::Grid() +#else + : Gtk::Table(5, 3, false) +#endif + , _color(color) + , _updating(false) +#if !GTK_CHECK_VERSION(3, 0, 0) + , _alpha_adjustment(NULL) +#endif + , _wheel(0) + , _slider(0) +{ + _initUI(); + _color_changed_connection = color.signal_changed.connect(sigc::mem_fun(this, &ColorWheelSelector::_colorChanged)); + _color_dragged_connection = color.signal_dragged.connect(sigc::mem_fun(this, &ColorWheelSelector::_colorChanged)); +} + +ColorWheelSelector::~ColorWheelSelector() +{ + _wheel = 0; +#if !GTK_CHECK_VERSION(3, 0, 0) + delete _alpha_adjustment; +#endif + + _color_changed_connection.disconnect(); + _color_dragged_connection.disconnect(); +} + +void ColorWheelSelector::_initUI() +{ + /* Create components */ + gint row = 0; + + _wheel = gimp_color_wheel_new(); + gtk_widget_show(_wheel); + +#if GTK_CHECK_VERSION(3, 0, 0) + gtk_widget_set_halign(_wheel, GTK_ALIGN_FILL); + gtk_widget_set_valign(_wheel, GTK_ALIGN_FILL); + gtk_widget_set_hexpand(_wheel, TRUE); + gtk_widget_set_vexpand(_wheel, TRUE); + gtk_grid_attach(GTK_GRID(gobj()), _wheel, 0, row, 3, 1); +#else + gtk_table_attach(GTK_TABLE(gobj()), _wheel, 0, 3, row, row + 1, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), + (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), 0, 0); +#endif + + row++; + + /* Label */ + Gtk::Label *label = Gtk::manage(new Gtk::Label(_("_A:"), true)); + label->set_alignment(1.0, 0.5); + label->show(); + +#if GTK_CHECK_VERSION(3, 0, 0) + #if GTK_CHECK_VERSION(3, 12, 0) + label->set_margin_start(XPAD); + label->set_margin_end(XPAD); + #else + label->set_margin_left(XPAD); + label->set_margin_right(XPAD); + #endif + label->set_margin_top(YPAD); + label->set_margin_bottom(YPAD); + label->set_halign(Gtk::ALIGN_FILL); + label->set_valign(Gtk::ALIGN_FILL); + attach(*label, 0, row, 1, 1); +#else + attach(*label, 0, 1, row, row + 1, Gtk::FILL, Gtk::FILL, XPAD, YPAD); +#endif + +/* Adjustment */ +#if GTK_CHECK_VERSION(3, 0, 0) + _alpha_adjustment = Gtk::Adjustment::create(0.0, 0.0, 255.0, 1.0, 10.0, 10.0); +#else + _alpha_adjustment = new Gtk::Adjustment(0.0, 0.0, 255.0, 1.0, 10.0, 10.0); +#endif + /* Slider */ + _slider = Gtk::manage(new Inkscape::UI::Widget::ColorSlider(_alpha_adjustment)); + _slider->set_tooltip_text(_("Alpha (opacity)")); + _slider->show(); + +#if GTK_CHECK_VERSION(3, 0, 0) + #if GTK_CHECK_VERSION(3, 12, 0) + _slider->set_margin_start(XPAD); + _slider->set_margin_end(XPAD); + #else + _slider->set_margin_left(XPAD); + _slider->set_margin_right(XPAD); + #endif + _slider->set_margin_top(YPAD); + _slider->set_margin_bottom(YPAD); + _slider->set_hexpand(true); + _slider->set_halign(Gtk::ALIGN_FILL); + _slider->set_valign(Gtk::ALIGN_FILL); + attach(*_slider, 1, row, 1, 1); +#else + attach(*_slider, 1, 2, row, row + 1, Gtk::EXPAND | Gtk::FILL, Gtk::FILL, XPAD, YPAD); +#endif + + _slider->setColors(SP_RGBA32_F_COMPOSE(1.0, 1.0, 1.0, 0.0), SP_RGBA32_F_COMPOSE(1.0, 1.0, 1.0, 0.5), + SP_RGBA32_F_COMPOSE(1.0, 1.0, 1.0, 1.0)); + +/* Spinbutton */ +#if GTK_CHECK_VERSION(3, 0, 0) + Gtk::SpinButton *spin_button = Gtk::manage(new Gtk::SpinButton(_alpha_adjustment, 1.0, 0)); +#else + Gtk::SpinButton *spin_button = Gtk::manage(new Gtk::SpinButton(*_alpha_adjustment, 1.0, 0)); +#endif + spin_button->set_tooltip_text(_("Alpha (opacity)")); + sp_dialog_defocus_on_enter(GTK_WIDGET(spin_button->gobj())); + label->set_mnemonic_widget(*spin_button); + spin_button->show(); + +#if GTK_CHECK_VERSION(3, 0, 0) + #if GTK_CHECK_VERSION(3, 12, 0) + spin_button->set_margin_start(XPAD); + spin_button->set_margin_end(XPAD); + #else + spin_button->set_margin_left(XPAD); + spin_button->set_margin_right(XPAD); + #endif + spin_button->set_margin_top(YPAD); + spin_button->set_margin_bottom(YPAD); + spin_button->set_halign(Gtk::ALIGN_CENTER); + spin_button->set_valign(Gtk::ALIGN_CENTER); + attach(*spin_button, 2, row, 1, 1); +#else + attach(*spin_button, 2, 3, row, row + 1, (Gtk::AttachOptions)0, (Gtk::AttachOptions)0, XPAD, YPAD); +#endif + + /* Signals */ + _alpha_adjustment->signal_value_changed().connect(sigc::mem_fun(this, &ColorWheelSelector::_adjustmentChanged)); + _slider->signal_grabbed.connect(sigc::mem_fun(*this, &ColorWheelSelector::_sliderGrabbed)); + _slider->signal_released.connect(sigc::mem_fun(*this, &ColorWheelSelector::_sliderReleased)); + _slider->signal_value_changed.connect(sigc::mem_fun(*this, &ColorWheelSelector::_sliderChanged)); + + g_signal_connect(G_OBJECT(_wheel), "changed", G_CALLBACK(_wheelChanged), this); +} + +void ColorWheelSelector::on_show() +{ +#if GTK_CHECK_VERSION(3, 0, 0) + Gtk::Grid::on_show(); +#else + Gtk::Table::on_show(); +#endif + _updateDisplay(); +} + +void ColorWheelSelector::_colorChanged() +{ + _updateDisplay(); +} + +void ColorWheelSelector::_adjustmentChanged() +{ + if (_updating) { + return; + } + + // TODO check this. It looks questionable: + // if a value is entered between 0 and 1 exclusive, normalize it to (int) 0..255 or 0..100 + gdouble value = _alpha_adjustment->get_value(); + gdouble upper = _alpha_adjustment->get_upper(); + if (value > 0.0 && value < 1.0) { + _alpha_adjustment->set_value(floor(value * upper + 0.5)); + } + + _color.preserveICC(); + _color.setAlpha(ColorScales::getScaled(_alpha_adjustment->gobj())); +} + +void ColorWheelSelector::_sliderGrabbed() +{ + _color.preserveICC(); + _color.setHeld(true); +} + +void ColorWheelSelector::_sliderReleased() +{ + _color.preserveICC(); + _color.setHeld(false); +} + +void ColorWheelSelector::_sliderChanged() +{ + if (_updating) { + return; + } + + _color.preserveICC(); + _color.setAlpha(ColorScales::getScaled(_alpha_adjustment->gobj())); +} + +void ColorWheelSelector::_wheelChanged(GimpColorWheel *wheel, ColorWheelSelector *wheelSelector) +{ + if (wheelSelector->_updating) { + return; + } + + gdouble h = 0; + gdouble s = 0; + gdouble v = 0; + gimp_color_wheel_get_color(wheel, &h, &s, &v); + + float rgb[3] = { 0, 0, 0 }; + sp_color_hsv_to_rgb_floatv(rgb, h, s, v); + + SPColor color(rgb[0], rgb[1], rgb[2]); + + guint32 start = color.toRGBA32(0x00); + guint32 mid = color.toRGBA32(0x7f); + guint32 end = color.toRGBA32(0xff); + + wheelSelector->_slider->setColors(start, mid, end); + + wheelSelector->_color.preserveICC(); + + wheelSelector->_color.setHeld(gimp_color_wheel_is_adjusting(wheel)); + wheelSelector->_color.setColor(color); +} + +void ColorWheelSelector::_updateDisplay() +{ +#ifdef DUMP_CHANGE_INFO + g_message("ColorWheelSelector::_colorChanged( this=%p, %f, %f, %f, %f)", this, _color.color().v.c[0], + _color.color().v.c[1], _color.color().v.c[2], alpha); +#endif + + bool oldval = _updating; + _updating = true; + { + float hsv[3] = { 0, 0, 0 }; + sp_color_rgb_to_hsv_floatv(hsv, _color.color().v.c[0], _color.color().v.c[1], _color.color().v.c[2]); + gimp_color_wheel_set_color(GIMP_COLOR_WHEEL(_wheel), hsv[0], hsv[1], hsv[2]); + } + + guint32 start = _color.color().toRGBA32(0x00); + guint32 mid = _color.color().toRGBA32(0x7f); + guint32 end = _color.color().toRGBA32(0xff); + + _slider->setColors(start, mid, end); + + ColorScales::setScaled(_alpha_adjustment->gobj(), _color.alpha()); + + _updating = oldval; +} + + +Gtk::Widget *ColorWheelSelectorFactory::createWidget(Inkscape::UI::SelectedColor &color) const +{ + Gtk::Widget *w = Gtk::manage(new ColorWheelSelector(color)); + return w; +} + +Glib::ustring ColorWheelSelectorFactory::modeName() const { return gettext(ColorWheelSelector::MODE_NAME); } +} +} +} +/* + 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 : diff --git a/src/ui/widget/color-wheel-selector.h b/src/ui/widget/color-wheel-selector.h new file mode 100644 index 000000000..5711d417c --- /dev/null +++ b/src/ui/widget/color-wheel-selector.h @@ -0,0 +1,101 @@ +/** + * @file + * Color selector widget containing GIMP color wheel and slider + */ +/* Authors: + * Tomasz Boczkowski <penginsbacon@gmail.com> (c++-sification) + * + * Copyright (C) 2014 Authors + * + * This code is in public domain + */ +#ifndef SEEN_SP_COLOR_WHEEL_SELECTOR_H +#define SEEN_SP_COLOR_WHEEL_SELECTOR_H + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#if WITH_GTKMM_3_0 +#include <gtkmm/grid.h> +#else +#include <gtkmm/table.h> +#endif + +#include "ui/selected-color.h" + +typedef struct _GimpColorWheel GimpColorWheel; + +namespace Inkscape { +namespace UI { +namespace Widget { + +class ColorSlider; + +class ColorWheelSelector +#if GTK_CHECK_VERSION(3, 0, 0) + : public Gtk::Grid +#else + : public Gtk::Table +#endif +{ +public: + static const gchar *MODE_NAME; + + ColorWheelSelector(SelectedColor &color); + virtual ~ColorWheelSelector(); + +protected: + void _initUI(); + + void on_show(); + + void _colorChanged(); + void _adjustmentChanged(); + void _sliderGrabbed(); + void _sliderReleased(); + void _sliderChanged(); + static void _wheelChanged(GimpColorWheel *wheel, ColorWheelSelector *cs); + + void _updateDisplay(); + + SelectedColor &_color; + bool _updating; +#if GTK_CHECK_VERSION(3, 0, 0) + Glib::RefPtr<Gtk::Adjustment> _alpha_adjustment; +#else + Gtk::Adjustment *_alpha_adjustment; +#endif + GtkWidget *_wheel; + Inkscape::UI::Widget::ColorSlider *_slider; + +private: + // By default, disallow copy constructor and assignment operator + ColorWheelSelector(const ColorWheelSelector &obj); + ColorWheelSelector &operator=(const ColorWheelSelector &obj); + + sigc::connection _color_changed_connection; + sigc::connection _color_dragged_connection; +}; + +class ColorWheelSelectorFactory : public ColorSelectorFactory { +public: + Gtk::Widget *createWidget(SelectedColor &color) const; + Glib::ustring modeName() const; +}; +} +} +} + +#endif // SEEN_SP_COLOR_WHEEL_SELECTOR_H + +/* + 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 : diff --git a/src/widgets/CMakeLists.txt b/src/widgets/CMakeLists.txt index 072b905a2..a3e9e14d0 100644 --- a/src/widgets/CMakeLists.txt +++ b/src/widgets/CMakeLists.txt @@ -41,12 +41,7 @@ set(widgets_SRC select-toolbar.cpp shrink-wrap-button.cpp sp-attribute-widget.cpp - sp-color-icc-selector.cpp - sp-color-notebook.cpp - sp-color-scales.cpp sp-color-selector.cpp - sp-color-slider.cpp - sp-color-wheel-selector.cpp sp-widget.cpp sp-xmlview-attr-list.cpp sp-xmlview-content.cpp @@ -103,12 +98,7 @@ set(widgets_SRC select-toolbar.h shrink-wrap-button.h sp-attribute-widget.h - sp-color-icc-selector.h - sp-color-notebook.h - sp-color-scales.h sp-color-selector.h - sp-color-slider.h - sp-color-wheel-selector.h sp-widget.h sp-xmlview-attr-list.h sp-xmlview-content.h diff --git a/src/widgets/Makefile_insert b/src/widgets/Makefile_insert index dc4c12967..f66be66ed 100644 --- a/src/widgets/Makefile_insert +++ b/src/widgets/Makefile_insert @@ -76,18 +76,8 @@ ink_common_sources += \ widgets/spiral-toolbar.h \ widgets/sp-attribute-widget.cpp \ widgets/sp-attribute-widget.h \ - widgets/sp-color-icc-selector.cpp \ - widgets/sp-color-icc-selector.h \ - widgets/sp-color-notebook.cpp \ - widgets/sp-color-notebook.h \ - widgets/sp-color-scales.cpp \ - widgets/sp-color-scales.h \ widgets/sp-color-selector.cpp \ widgets/sp-color-selector.h \ - widgets/sp-color-slider.cpp \ - widgets/sp-color-slider.h \ - widgets/sp-color-wheel-selector.cpp \ - widgets/sp-color-wheel-selector.h \ widgets/spinbutton-events.cpp \ widgets/spinbutton-events.h \ widgets/sp-widget.cpp \ diff --git a/src/widgets/fill-style.cpp b/src/widgets/fill-style.cpp index b1f812338..fa5eabab4 100644 --- a/src/widgets/fill-style.cpp +++ b/src/widgets/fill-style.cpp @@ -300,7 +300,7 @@ void FillNStroke::performUpdate() psel->setGradientProperties( rg->getUnits(), rg->getSpread() ); } else if (SP_IS_PATTERN(server)) { - SPPattern *pat = pattern_getroot(SP_PATTERN(server)); + SPPattern *pat = SP_PATTERN(server)->rootPattern(); psel->updatePatternList( pat ); } } @@ -431,8 +431,7 @@ void FillNStroke::dragFromPaint() update = true; switch (psel->mode) { - case SPPaintSelector::MODE_COLOR_RGB: - case SPPaintSelector::MODE_COLOR_CMYK: + case SPPaintSelector::MODE_SOLID_COLOR: { // local change, do not update from selection dragId = g_timeout_add_full(G_PRIORITY_DEFAULT, 100, dragDelayCB, this, 0); @@ -505,8 +504,7 @@ void FillNStroke::updateFromPaint() break; } - case SPPaintSelector::MODE_COLOR_RGB: - case SPPaintSelector::MODE_COLOR_CMYK: + case SPPaintSelector::MODE_SOLID_COLOR: { if (kind == FILL) { // FIXME: fix for GTK breakage, see comment in SelectedStyle::on_opacity_changed; here it results in losing release events @@ -656,7 +654,7 @@ void FillNStroke::updateFromPaint() SPPaintServer *server = (kind == FILL) ? selobj->style->getFillPaintServer() : selobj->style->getStrokePaintServer(); - if (SP_IS_PATTERN(server) && pattern_getroot(SP_PATTERN(server)) == pattern) + if (SP_IS_PATTERN(server) && SP_PATTERN(server)->rootPattern() == pattern) // only if this object's pattern is not rooted in our selected pattern, apply continue; } diff --git a/src/widgets/gradient-selector.cpp b/src/widgets/gradient-selector.cpp index 42e59cbfe..402f30846 100644 --- a/src/widgets/gradient-selector.cpp +++ b/src/widgets/gradient-selector.cpp @@ -17,6 +17,10 @@ # include "config.h" #endif +#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H +#include <glibmm/threads.h> +#endif + #include <gtkmm/treeview.h> #include "gradient-vector.h" diff --git a/src/widgets/gradient-vector.cpp b/src/widgets/gradient-vector.cpp index 10d1cc107..259d4c9af 100644 --- a/src/widgets/gradient-vector.cpp +++ b/src/widgets/gradient-vector.cpp @@ -31,17 +31,16 @@ #include "macros.h" #include <glibmm/i18n.h> #include <set> -#include "widgets/gradient-image.h" -#include "inkscape.h" -#include "document-private.h" -#include "gradient-chemistry.h" -#include "helper/window.h" +#include "../widgets/gradient-image.h" +#include "../inkscape.h" +#include "../document-private.h" +#include "../gradient-chemistry.h" +#include "../helper/window.h" #include "io/resource.h" #include "xml/repr.h" -#include "ui/dialog-events.h" -#include "preferences.h" +#include "../preferences.h" #include "svg/css-ostringstream.h" #include "sp-stop.h" #include "selection-chemistry.h" @@ -51,10 +50,16 @@ #include "desktop.h" #include "layer-manager.h" -#include <sigc++/sigc++.h> +#include <sigc++/functors/ptr_fun.h> +#include <sigc++/adaptors/bind.h> #include "document-undo.h" +#include "ui/dialog-events.h" +#include "ui/selected-color.h" +#include "ui/widget/color-notebook.h" + using Inkscape::DocumentUndo; +using Inkscape::UI::SelectedColor; enum { VECTOR_SET, @@ -468,11 +473,10 @@ void SPGradientVectorSelector::setSwatched() ### Vector Editing Widget ##################################################################*/ -#include "widgets/sp-color-notebook.h" #include "widgets/widget-sizes.h" #include "xml/node-event-vector.h" #include "svg/svg-color.h" - +#include "ui/widget/color-notebook.h" #define PAD 4 @@ -491,8 +495,8 @@ static void sp_gradient_vector_widget_destroy(GtkObject *object, gpointer data); static void sp_gradient_vector_gradient_release(SPObject *obj, GtkWidget *widget); static void sp_gradient_vector_gradient_modified(SPObject *obj, guint flags, GtkWidget *widget); -static void sp_gradient_vector_color_dragged(SPColorSelector *csel, GObject *object); -static void sp_gradient_vector_color_changed(SPColorSelector *csel, GObject *object); +static void sp_gradient_vector_color_dragged(Inkscape::UI::SelectedColor *selected_color, GObject *object); +static void sp_gradient_vector_color_changed(Inkscape::UI::SelectedColor *selected_color, GObject *object); static void update_stop_list( GtkWidget *vb, SPGradient *gradient, SPStop *new_stop); static gboolean blocked = FALSE; @@ -649,9 +653,11 @@ static void sp_grad_edit_combo_box_changed (GtkComboBox * /*widget*/, GtkWidget blocked = TRUE; - SPColorSelector *csel = static_cast<SPColorSelector*>(g_object_get_data(G_OBJECT(tbl), "cselector")); + SelectedColor *csel = static_cast<SelectedColor*>(g_object_get_data(G_OBJECT(tbl), "cselector")); // set its color, from the stored array - csel->base->setColorAlpha( stop->getEffectiveColor(), stop->opacity ); + g_object_set_data(G_OBJECT(tbl), "updating_color", reinterpret_cast<void*>(1)); + csel->setColorAlpha(stop->getEffectiveColor(), stop->opacity); + g_object_set_data(G_OBJECT(tbl), "updating_color", reinterpret_cast<void*>(0)); GtkWidget *offspin = GTK_WIDGET(g_object_get_data(G_OBJECT(tbl), "offspn")); GtkWidget *offslide =GTK_WIDGET(g_object_get_data(G_OBJECT(tbl), "offslide")); @@ -832,7 +838,9 @@ static void sp_grd_ed_del_stop(GtkWidget */*widget*/, GtkWidget *vb) static GtkWidget * sp_gradient_vector_widget_new(SPGradient *gradient, SPStop *select_stop) { - GtkWidget *vb, *w, *f, *csel; + using Inkscape::UI::Widget::ColorNotebook; + + GtkWidget *vb, *w, *f; g_return_val_if_fail(!gradient || SP_IS_GRADIENT(gradient), NULL); @@ -960,12 +968,23 @@ static GtkWidget * sp_gradient_vector_widget_new(SPGradient *gradient, SPStop *s f = gtk_frame_new(_("Stop Color")); gtk_widget_show(f); gtk_box_pack_start(GTK_BOX(vb), f, TRUE, TRUE, PAD); - csel = static_cast<GtkWidget*>(sp_color_selector_new(SP_TYPE_COLOR_NOTEBOOK)); - g_object_set_data(G_OBJECT(vb), "cselector", csel); + + Inkscape::UI::SelectedColor *selected_color = new Inkscape::UI::SelectedColor; + g_object_set_data(G_OBJECT(vb), "cselector", selected_color); + g_object_set_data(G_OBJECT(vb), "updating_color", reinterpret_cast<void*>(0)); + selected_color->signal_dragged.connect(sigc::bind(sigc::ptr_fun(&sp_gradient_vector_color_dragged), selected_color, G_OBJECT(vb))); + selected_color->signal_dragged.connect(sigc::bind(sigc::ptr_fun(&sp_gradient_vector_color_changed), selected_color, G_OBJECT(vb))); + + Gtk::Widget *color_selector = Gtk::manage(new ColorNotebook(*selected_color)); + color_selector->show(); + gtk_container_add(GTK_CONTAINER(f), color_selector->gobj()); + + /* gtk_widget_show(csel); gtk_container_add(GTK_CONTAINER(f), csel); g_signal_connect(G_OBJECT(csel), "dragged", G_CALLBACK(sp_gradient_vector_color_dragged), vb); g_signal_connect(G_OBJECT(csel), "changed", G_CALLBACK(sp_gradient_vector_color_changed), vb); + */ gtk_widget_show(vb); @@ -1126,9 +1145,11 @@ static void sp_gradient_vector_widget_load_gradient(GtkWidget *widget, SPGradien } // get the color selector - SPColorSelector *csel = SP_COLOR_SELECTOR(g_object_get_data(G_OBJECT(widget), "cselector")); + SelectedColor *csel = static_cast<SelectedColor*>(g_object_get_data(G_OBJECT(widget), "cselector")); - csel->base->setColorAlpha( stop->getEffectiveColor(), stop->opacity ); + g_object_set_data(G_OBJECT(widget), "updating_color", reinterpret_cast<void*>(1)); + csel->setColorAlpha(stop->getEffectiveColor(), stop->opacity); + g_object_set_data(G_OBJECT(widget), "updating_color", reinterpret_cast<void*>(0)); /* Fill preview */ GtkWidget *w = static_cast<GtkWidget *>(g_object_get_data(G_OBJECT(widget), "preview")); @@ -1228,6 +1249,12 @@ static void sp_gradient_vector_widget_destroy(GtkObject *object, gpointer /*data sp_repr_remove_listener_by_data(gradient->getRepr(), object); } } + + SelectedColor *selected_color = static_cast<SelectedColor *>(g_object_get_data(G_OBJECT(object), "cselector")); + if (selected_color) { + delete selected_color; + g_object_set_data(G_OBJECT(object), "cselector", NULL); + } } static void sp_gradient_vector_gradient_release(SPObject */*object*/, GtkWidget *widget) @@ -1245,7 +1272,7 @@ static void sp_gradient_vector_gradient_modified(SPObject *object, guint /*flags } } -static void sp_gradient_vector_color_dragged(SPColorSelector *csel, GObject *object) +static void sp_gradient_vector_color_dragged(Inkscape::UI::SelectedColor *selected_color, GObject *object) { SPGradient *gradient, *ngr; @@ -1273,14 +1300,21 @@ static void sp_gradient_vector_color_dragged(SPColorSelector *csel, GObject *obj return; } - csel->base->getColorAlpha(stop->specified_color, stop->opacity); + selected_color->colorAlpha(stop->specified_color, stop->opacity); stop->currentColor = false; blocked = FALSE; } -static void sp_gradient_vector_color_changed(SPColorSelector *csel, GObject *object) +static void sp_gradient_vector_color_changed(Inkscape::UI::SelectedColor *selected_color, GObject *object) { + (void)selected_color; + + void* updating_color = g_object_get_data(G_OBJECT(object), "updating_color"); + if (updating_color) { + return; + } + if (blocked) { return; } @@ -1309,10 +1343,10 @@ static void sp_gradient_vector_color_changed(SPColorSelector *csel, GObject *obj return; } - csel = static_cast<SPColorSelector*>(g_object_get_data(G_OBJECT(object), "cselector")); + SelectedColor *csel = static_cast<SelectedColor *>(g_object_get_data(G_OBJECT(object), "cselector")); SPColor color; float alpha = 0; - csel->base->getColorAlpha( color, alpha ); + csel->colorAlpha(color, alpha); sp_repr_set_css_double(stop->getRepr(), "offset", stop->offset); Inkscape::CSSOStringStream os; diff --git a/src/widgets/paint-selector.cpp b/src/widgets/paint-selector.cpp index 221344296..846ded511 100644 --- a/src/widgets/paint-selector.cpp +++ b/src/widgets/paint-selector.cpp @@ -31,7 +31,6 @@ #include "widgets/widget-sizes.h" #include "xml/repr.h" -#include "sp-color-notebook.h" #include "sp-linear-gradient.h" #include "sp-radial-gradient.h" #include "sp-mesh.h" @@ -48,6 +47,7 @@ #include "io/sys.h" #include "helper/stock-items.h" #include "ui/icon-names.h" +#include "ui/widget/color-notebook.h" #include "paint-selector.h" @@ -58,6 +58,7 @@ #include <gtk/gtk.h> using Inkscape::Widgets::SwatchSelector; +using Inkscape::UI::SelectedColor; enum { MODE_CHANGED, @@ -94,8 +95,7 @@ static gchar const* modeStrings[] = { "MODE_EMPTY", "MODE_MULTIPLE", "MODE_NONE", - "MODE_COLOR_RGB", - "MODE_COLOR_CMYK", + "MODE_SOLID_COLOR", "MODE_GRADIENT_LINEAR", "MODE_GRADIENT_RADIAL", "MODE_PATTERN", @@ -218,7 +218,7 @@ sp_paint_selector_init(SPPaintSelector *psel) psel->none = sp_paint_selector_style_button_add(psel, INKSCAPE_ICON("paint-none"), SPPaintSelector::MODE_NONE, _("No paint")); psel->solid = sp_paint_selector_style_button_add(psel, INKSCAPE_ICON("paint-solid"), - SPPaintSelector::MODE_COLOR_RGB, _("Flat color")); + SPPaintSelector::MODE_SOLID_COLOR, _("Flat color")); psel->gradient = sp_paint_selector_style_button_add(psel, INKSCAPE_ICON("paint-gradient-linear"), SPPaintSelector::MODE_GRADIENT_LINEAR, _("Linear gradient")); psel->radial = sp_paint_selector_style_button_add(psel, INKSCAPE_ICON("paint-gradient-radial"), @@ -292,8 +292,13 @@ sp_paint_selector_init(SPPaintSelector *psel) /* Last used color */ - psel->color.set( 0.0, 0.0, 0.0 ); - psel->alpha = 1.0; + psel->selected_color = new SelectedColor; + psel->updating_color = false; + + psel->selected_color->signal_grabbed.connect(sigc::mem_fun(psel, &SPPaintSelector::onSelectedColorGrabbed)); + psel->selected_color->signal_dragged.connect(sigc::mem_fun(psel, &SPPaintSelector::onSelectedColorDragged)); + psel->selected_color->signal_released.connect(sigc::mem_fun(psel, &SPPaintSelector::onSelectedColorReleased)); + psel->selected_color->signal_changed.connect(sigc::mem_fun(psel, &SPPaintSelector::onSelectedColorChanged)); } static void sp_paint_selector_dispose(GObject *object) @@ -303,6 +308,11 @@ static void sp_paint_selector_dispose(GObject *object) // clean up our long-living pattern menu g_object_set_data(G_OBJECT(psel),"patternmenu",NULL); + if (psel->selected_color) { + delete psel->selected_color; + psel->selected_color = NULL; + } + if ((G_OBJECT_CLASS(sp_paint_selector_parent_class))->dispose) (G_OBJECT_CLASS(sp_paint_selector_parent_class))->dispose(object); } @@ -396,8 +406,7 @@ void SPPaintSelector::setMode(Mode mode) case MODE_NONE: sp_paint_selector_set_mode_none(this); break; - case MODE_COLOR_RGB: - case MODE_COLOR_CMYK: + case MODE_SOLID_COLOR: sp_paint_selector_set_mode_color(this, mode); break; case MODE_GRADIENT_LINEAR: @@ -438,7 +447,6 @@ void SPPaintSelector::setFillrule(FillRule fillrule) void SPPaintSelector::setColorAlpha(SPColor const &color, float alpha) { g_return_if_fail( ( 0.0 <= alpha ) && ( alpha <= 1.0 ) ); - SPColorSelector *csel = 0; /* guint32 rgba = 0; @@ -455,12 +463,13 @@ void SPPaintSelector::setColorAlpha(SPColor const &color, float alpha) #ifdef SP_PS_VERBOSE g_print("PaintSelector set RGBA\n"); #endif - setMode(MODE_COLOR_RGB); + setMode(MODE_SOLID_COLOR); } - csel = reinterpret_cast<SPColorSelector*>(g_object_get_data(G_OBJECT(selector), "color-selector")); + updating_color = true; + selected_color->setColorAlpha(color, alpha); + updating_color = false; //rgba = color.toRGBA32( alpha ); - csel->base->setColorAlpha( color, alpha ); } void SPPaintSelector::setSwatch(SPGradient *vector ) @@ -541,11 +550,7 @@ void SPPaintSelector::getGradientProperties( SPGradientUnits &units, SPGradientS */ void SPPaintSelector::getColorAlpha(SPColor &color, gfloat &alpha) const { - SPColorSelector *csel; - - csel = reinterpret_cast<SPColorSelector*>(g_object_get_data(G_OBJECT(selector), "color-selector")); - - csel->base->getColorAlpha( color, alpha ); + selected_color->colorAlpha(color, alpha); g_assert( ( 0.0 <= alpha ) && ( alpha <= 1.0 ) ); @@ -581,6 +586,9 @@ sp_paint_selector_clear_frame(SPPaintSelector *psel) if (psel->selector) { + //This is a hack to work around GtkNotebook bug in ColorSelector. Is sends signal switch-page on destroy + //The widget is hidden firts so it can recognize that it should not process signals from notebook child + gtk_widget_set_visible(psel->selector, false); gtk_widget_destroy(psel->selector); psel->selector = NULL; } @@ -633,82 +641,82 @@ sp_paint_selector_set_mode_none(SPPaintSelector *psel) /* Color paint */ -static void sp_paint_selector_color_grabbed(SPColorSelector * /*csel*/, SPPaintSelector *psel) -{ - g_signal_emit(G_OBJECT(psel), psel_signals[GRABBED], 0); +void SPPaintSelector::onSelectedColorGrabbed() { + g_signal_emit(G_OBJECT(this), psel_signals[GRABBED], 0); } -static void sp_paint_selector_color_dragged(SPColorSelector * /*csel*/, SPPaintSelector *psel) -{ - g_signal_emit(G_OBJECT(psel), psel_signals[DRAGGED], 0); +void SPPaintSelector::onSelectedColorDragged() { + if (updating_color) { + return; + } + g_signal_emit(G_OBJECT(this), psel_signals[DRAGGED], 0); } -static void sp_paint_selector_color_released(SPColorSelector * /*csel*/, SPPaintSelector *psel) -{ - g_signal_emit(G_OBJECT(psel), psel_signals[RELEASED], 0); +void SPPaintSelector::onSelectedColorReleased() { + g_signal_emit(G_OBJECT(this), psel_signals[RELEASED], 0); } -static void -sp_paint_selector_color_changed(SPColorSelector *csel, SPPaintSelector *psel) -{ - csel->base->getColorAlpha( psel->color, psel->alpha ); +void SPPaintSelector::onSelectedColorChanged() { + if (updating_color) { + return; + } - g_signal_emit(G_OBJECT(psel), psel_signals[CHANGED], 0); + if (mode == MODE_SOLID_COLOR) { + g_signal_emit(G_OBJECT(this), psel_signals[CHANGED], 0); + } else { + g_warning("SPPaintSelector::onSelectedColorChanged(): selected color changed while not in color selection mode"); + } } static void sp_paint_selector_set_mode_color(SPPaintSelector *psel, SPPaintSelector::Mode /*mode*/) { - GtkWidget *csel; - - SPColor newcolor = psel->color; - float newalpha = psel->alpha; - + using Inkscape::UI::Widget::ColorNotebook; + if ((psel->mode == SPPaintSelector::MODE_SWATCH) || (psel->mode == SPPaintSelector::MODE_GRADIENT_LINEAR) || (psel->mode == SPPaintSelector::MODE_GRADIENT_RADIAL) ) { SPGradientSelector *gsel = getGradientFromData(psel); if (gsel) { SPGradient *gradient = gsel->getVector(); - newcolor = gradient->getFirstStop()->specified_color; - newalpha = gradient->getFirstStop()->opacity; + + // Gradient can be null if object paint is changed externally (ie. with a color picker tool) + if (gradient) + { + SPColor color = gradient->getFirstStop()->specified_color; + float alpha = gradient->getFirstStop()->opacity; + psel->selected_color->setColorAlpha(color, alpha, false); + } } } sp_paint_selector_set_style_buttons(psel, psel->solid); gtk_widget_set_sensitive(psel->style, TRUE); - if ((psel->mode == SPPaintSelector::MODE_COLOR_RGB) || (psel->mode == SPPaintSelector::MODE_COLOR_CMYK)) { + if ((psel->mode == SPPaintSelector::MODE_SOLID_COLOR)) { /* Already have color selector */ - csel = GTK_WIDGET(g_object_get_data(G_OBJECT(psel->selector), "color-selector")); + // Do nothing } else { sp_paint_selector_clear_frame(psel); /* Create new color selector */ /* Create vbox */ #if GTK_CHECK_VERSION(3,0,0) - GtkWidget *vb = gtk_box_new(GTK_ORIENTATION_VERTICAL, 4); - gtk_box_set_homogeneous(GTK_BOX(vb), FALSE); + GtkWidget *vb = gtk_box_new(GTK_ORIENTATION_VERTICAL, 4); + gtk_box_set_homogeneous(GTK_BOX(vb), FALSE); #else GtkWidget *vb = gtk_vbox_new(FALSE, 4); #endif gtk_widget_show(vb); /* Color selector */ - csel = sp_color_selector_new( SP_TYPE_COLOR_NOTEBOOK ); - gtk_widget_show(csel); - g_object_set_data(G_OBJECT(vb), "color-selector", csel); - gtk_box_pack_start(GTK_BOX(vb), csel, TRUE, TRUE, 0); - g_signal_connect(G_OBJECT(csel), "grabbed", G_CALLBACK(sp_paint_selector_color_grabbed), psel); - g_signal_connect(G_OBJECT(csel), "dragged", G_CALLBACK(sp_paint_selector_color_dragged), psel); - g_signal_connect(G_OBJECT(csel), "released", G_CALLBACK(sp_paint_selector_color_released), psel); - g_signal_connect(G_OBJECT(csel), "changed", G_CALLBACK(sp_paint_selector_color_changed), psel); + Gtk::Widget *color_selector = Gtk::manage(new ColorNotebook(*(psel->selected_color))); + color_selector->show(); + gtk_box_pack_start(GTK_BOX(vb), color_selector->gobj(), TRUE, TRUE, 0); + /* Pack everything to frame */ gtk_container_add(GTK_CONTAINER(psel->frame), vb); psel->selector = vb; - - /* Set color */ - SP_COLOR_SELECTOR( csel )->base->setColorAlpha( newcolor, newalpha ); } gtk_label_set_markup(GTK_LABEL(psel->label), _("<b>Flat color</b>")); @@ -720,22 +728,22 @@ static void sp_paint_selector_set_mode_color(SPPaintSelector *psel, SPPaintSelec /* Gradient */ -static void sp_paint_selector_gradient_grabbed(SPColorSelector * /*csel*/, SPPaintSelector *psel) +static void sp_paint_selector_gradient_grabbed(SPGradientSelector * /*csel*/, SPPaintSelector *psel) { g_signal_emit(G_OBJECT(psel), psel_signals[GRABBED], 0); } -static void sp_paint_selector_gradient_dragged(SPColorSelector * /*csel*/, SPPaintSelector *psel) +static void sp_paint_selector_gradient_dragged(SPGradientSelector * /*csel*/, SPPaintSelector *psel) { g_signal_emit(G_OBJECT(psel), psel_signals[DRAGGED], 0); } -static void sp_paint_selector_gradient_released(SPColorSelector * /*csel*/, SPPaintSelector *psel) +static void sp_paint_selector_gradient_released(SPGradientSelector * /*csel*/, SPPaintSelector *psel) { g_signal_emit(G_OBJECT(psel), psel_signals[RELEASED], 0); } -static void sp_paint_selector_gradient_changed(SPColorSelector * /*csel*/, SPPaintSelector *psel) +static void sp_paint_selector_gradient_changed(SPGradientSelector * /*csel*/, SPPaintSelector *psel) { g_signal_emit(G_OBJECT(psel), psel_signals[CHANGED], 0); } @@ -838,7 +846,7 @@ ink_pattern_list_get (SPDocument *source) GSList *pl = NULL; GSList const *patterns = source->getResourceList("pattern"); for (GSList *l = const_cast<GSList *>(patterns); l != NULL; l = l->next) { - if (SP_PATTERN(l->data) == pattern_getroot(SP_PATTERN(l->data))) { // only if this is a root pattern + if (SP_PATTERN(l->data) == SP_PATTERN(l->data)->rootPattern()) { // only if this is a root pattern pl = g_slist_prepend(pl, l->data); } } @@ -1158,7 +1166,7 @@ SPPattern *SPPaintSelector::getPattern() } g_free(paturn); } else { - pat = pattern_getroot(SP_PATTERN(patid)); + pat = SP_PATTERN(patid)->rootPattern(); } if (pat && !SP_IS_PATTERN(pat)) { @@ -1265,7 +1273,7 @@ SPPaintSelector::Mode SPPaintSelector::getModeForStyle(SPStyle const & style, Fi } } else if ( target.isColor() ) { // TODO this is no longer a valid assertion: - mode = MODE_COLOR_RGB; // so far only rgb can be read from svg + mode = MODE_SOLID_COLOR; // so far only rgb can be read from svg } else if ( target.isNone() ) { mode = MODE_NONE; } else { diff --git a/src/widgets/paint-selector.h b/src/widgets/paint-selector.h index 788aa673e..23c2dd456 100644 --- a/src/widgets/paint-selector.h +++ b/src/widgets/paint-selector.h @@ -12,12 +12,18 @@ * */ +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <glib.h> #include <gtk/gtk.h> #include "color.h" #include "fill-or-stroke.h" #include "sp-gradient-spread.h" #include "sp-gradient-units.h" +#include "ui/selected-color.h" class SPGradient; class SPDesktop; @@ -44,8 +50,7 @@ struct SPPaintSelector { MODE_EMPTY, MODE_MULTIPLE, MODE_NONE, - MODE_COLOR_RGB, - MODE_COLOR_CMYK, + MODE_SOLID_COLOR, MODE_GRADIENT_LINEAR, MODE_GRADIENT_RADIAL, #ifdef WITH_MESH @@ -83,9 +88,8 @@ struct SPPaintSelector { GtkWidget *frame, *selector; GtkWidget *label; - SPColor color; - float alpha; - + Inkscape::UI::SelectedColor *selected_color; + bool updating_color; static Mode getModeForStyle(SPStyle const & style, FillOrStroke kind); @@ -114,6 +118,11 @@ struct SPPaintSelector { // TODO move this elsewhere: void setFlatColor( SPDesktop *desktop, const gchar *color_property, const gchar *opacity_property ); + + void onSelectedColorGrabbed(); + void onSelectedColorDragged(); + void onSelectedColorReleased(); + void onSelectedColorChanged(); }; enum {COMBO_COL_LABEL=0, COMBO_COL_STOCK=1, COMBO_COL_PATTERN=2, COMBO_COL_SEP=3, COMBO_N_COLS=4}; diff --git a/src/widgets/sp-color-icc-selector.cpp b/src/widgets/sp-color-icc-selector.cpp deleted file mode 100644 index 6e910c582..000000000 --- a/src/widgets/sp-color-icc-selector.cpp +++ /dev/null @@ -1,1113 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include "gradient-vector.h" -#include <math.h> -#include <gtk/gtk.h> -#include <glibmm/i18n.h> -#include <map> -#include <set> -#include <vector> - -#include "ui/dialog-events.h" -#include "sp-color-icc-selector.h" -#include "sp-color-scales.h" -#include "sp-color-slider.h" -#include "svg/svg-icc-color.h" -#include "colorspace.h" -#include "document.h" -#include "inkscape.h" -#include "profile-manager.h" - -#define noDEBUG_LCMS - -#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) -#include "color-profile.h" -#include "cms-system.h" -#include "color-profile-cms-fns.h" - -#ifdef DEBUG_LCMS -#include "preferences.h" -#endif // DEBUG_LCMS -#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - - -#ifdef DEBUG_LCMS -extern guint update_in_progress; -#define DEBUG_MESSAGE(key, ...) \ -{\ - Inkscape::Preferences *prefs = Inkscape::Preferences::get();\ - bool dump = prefs->getBool("/options/scislac/" #key);\ - bool dumpD = prefs->getBool("/options/scislac/" #key "D");\ - bool dumpD2 = prefs->getBool("/options/scislac/" #key "D2");\ - dumpD &&= ( (update_in_progress == 0) || dumpD2 );\ - if ( dump )\ - {\ - g_message( __VA_ARGS__ );\ -\ - }\ - if ( dumpD )\ - {\ - GtkWidget *dialog = gtk_message_dialog_new(NULL,\ - GTK_DIALOG_DESTROY_WITH_PARENT, \ - GTK_MESSAGE_INFO, \ - GTK_BUTTONS_OK, \ - __VA_ARGS__ \ - );\ - g_signal_connect_swapped(dialog, "response",\ - G_CALLBACK(gtk_widget_destroy), \ - dialog); \ - gtk_widget_show_all( dialog );\ - }\ -} -#endif // DEBUG_LCMS - - - -G_BEGIN_DECLS - -static void sp_color_icc_selector_dispose(GObject *object); -static void sp_color_icc_selector_show_all (GtkWidget *widget); -static void sp_color_icc_selector_hide(GtkWidget *widget); - -G_END_DECLS - -/** - * Class containing the parts for a single color component's UI presence. - */ -class ComponentUI -{ -public: - ComponentUI() : - _component(), - _adj(0), - _slider(0), - _btn(0), - _label(0), - _map(0) - { - } - - ComponentUI(colorspace::Component const &component) : - _component(component), - _adj(0), - _slider(0), - _btn(0), - _label(0), - _map(0) - { - } - - colorspace::Component _component; - GtkAdjustment *_adj; // Component adjustment - GtkWidget *_slider; - GtkWidget *_btn; // spinbutton - GtkWidget *_label; // Label - guchar *_map; -}; - -/** - * Class that implements the internals of the selector. - */ -class ColorICCSelectorImpl -{ -public: - - ColorICCSelectorImpl( ColorICCSelector *owner); - - ~ColorICCSelectorImpl(); - - static void _adjustmentChanged ( GtkAdjustment *adjustment, SPColorICCSelector *cs ); - - static void _sliderGrabbed( SPColorSlider *slider, SPColorICCSelector *cs ); - static void _sliderReleased( SPColorSlider *slider, SPColorICCSelector *cs ); - static void _sliderChanged( SPColorSlider *slider, SPColorICCSelector *cs ); - - static void _profileSelected( GtkWidget* src, gpointer data ); - static void _fixupHit( GtkWidget* src, gpointer data ); - -#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - void _setProfile( SVGICCColor* profile ); - void _switchToProfile( gchar const* name ); -#endif - void _updateSliders( gint ignore ); - void _profilesChanged( std::string const & name ); - - ColorICCSelector *_owner; - - gboolean _updating : 1; - gboolean _dragging : 1; - - guint32 _fixupNeeded; - GtkWidget* _fixupBtn; - GtkWidget* _profileSel; - - std::vector<ComponentUI> _compUI; - - GtkAdjustment* _adj; // Channel adjustment - GtkWidget* _slider; - GtkWidget* _sbtn; // Spinbutton - GtkWidget* _label; // Label - -#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - std::string _profileName; - Inkscape::ColorProfile* _prof; - guint _profChannelCount; - gulong _profChangedID; -#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) -}; - -#define XPAD 4 -#define YPAD 1 - -namespace -{ - -size_t maxColorspaceComponentCount = 0; - -#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - -/** - * Internal variable to track all known colorspaces. - */ -std::set<cmsUInt32Number> knownColorspaces; - -#endif - - -/** - * Simple helper to allow bitwise or on GtkAttachOptions. - */ -GtkAttachOptions operator|(GtkAttachOptions lhs, GtkAttachOptions rhs) -{ - return static_cast<GtkAttachOptions>(static_cast<int>(lhs) | static_cast<int>(rhs)); -} - -/** - * Helper function to handle GTK2/GTK3 attachment #ifdef code. - */ -void attachToGridOrTable(GtkWidget *parent, - GtkWidget *child, - guint left, - guint top, - guint width, - guint height, - bool hexpand = false, - bool centered = false, - guint xpadding = XPAD, - guint ypadding = YPAD) -{ -#if GTK_CHECK_VERSION(3,0,0) - #if GTK_CHECK_VERSION(3,12,0) - gtk_widget_set_margin_start( child, xpadding ); - gtk_widget_set_margin_end( child, xpadding ); - #else - gtk_widget_set_margin_left( child, xpadding ); - gtk_widget_set_margin_right( child, xpadding ); - #endif - - gtk_widget_set_margin_top( child, ypadding ); - gtk_widget_set_margin_bottom( child, ypadding ); - if (hexpand) { - gtk_widget_set_hexpand(child, TRUE); - } - if (centered) { - gtk_widget_set_halign( child, GTK_ALIGN_CENTER ); - gtk_widget_set_valign( child, GTK_ALIGN_CENTER ); - } - gtk_grid_attach( GTK_GRID(parent), child, left, top, width, height ); -#else - GtkAttachOptions xoptions = centered ? static_cast<GtkAttachOptions>(0) : hexpand ? (GTK_EXPAND | GTK_FILL) : GTK_FILL; - GtkAttachOptions yoptions = centered ? static_cast<GtkAttachOptions>(0) : GTK_FILL; - - gtk_table_attach( GTK_TABLE(parent), child, left, left + width, top, top + height, xoptions, yoptions, xpadding, ypadding ); -#endif -} - -} // namespace - -G_DEFINE_TYPE(SPColorICCSelector, sp_color_icc_selector, SP_TYPE_COLOR_SELECTOR); - -static void sp_color_icc_selector_class_init(SPColorICCSelectorClass *klass) -{ - static const gchar* nameset[] = {N_("CMS"), 0}; - GObjectClass *object_class = G_OBJECT_CLASS(klass); - GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass); - SPColorSelectorClass *selector_class = SP_COLOR_SELECTOR_CLASS (klass); - - selector_class->name = nameset; - selector_class->submode_count = 1; - - object_class->dispose = sp_color_icc_selector_dispose; - - widget_class->show_all = sp_color_icc_selector_show_all; - widget_class->hide = sp_color_icc_selector_hide; -} - - -ColorICCSelector::ColorICCSelector( SPColorSelector* csel ) - : ColorSelector( csel ), - _impl(NULL) -{ -} - -ColorICCSelector::~ColorICCSelector() -{ - if (_impl) - { - delete _impl; - _impl = 0; - } -} - -void sp_color_icc_selector_init(SPColorICCSelector *cs) -{ - SP_COLOR_SELECTOR(cs)->base = new ColorICCSelector( SP_COLOR_SELECTOR(cs) ); - - if ( SP_COLOR_SELECTOR(cs)->base ) - { - SP_COLOR_SELECTOR(cs)->base->init(); - } -} - - -/* -icSigRgbData -icSigCmykData -icSigCmyData -*/ -#define SPACE_ID_RGB 0 -#define SPACE_ID_CMY 1 -#define SPACE_ID_CMYK 2 - - -#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) -static cmsUInt16Number* getScratch() { - // bytes per pixel * input channels * width - static cmsUInt16Number* scritch = static_cast<cmsUInt16Number*>(g_new(cmsUInt16Number, 4 * 1024)); - - return scritch; -} - -colorspace::Component::Component() : - name(), - tip(), - scale(1) -{ -} - -colorspace::Component::Component(std::string const &name, std::string const &tip, guint scale) : - name(name), - tip(tip), - scale(scale) -{ -} - -std::vector<colorspace::Component> colorspace::getColorSpaceInfo( uint32_t space ) -{ - static std::map<cmsUInt32Number, std::vector<Component> > sets; - if (sets.empty()) - { - sets[cmsSigXYZData].push_back(Component("_X", "X", 2)); // TYPE_XYZ_16 - sets[cmsSigXYZData].push_back(Component("_Y", "Y", 1)); - sets[cmsSigXYZData].push_back(Component("_Z", "Z", 2)); - - sets[cmsSigLabData].push_back(Component("_L", "L", 100)); // TYPE_Lab_16 - sets[cmsSigLabData].push_back(Component("_a", "a", 256)); - sets[cmsSigLabData].push_back(Component("_b", "b", 256)); - - //cmsSigLuvData - - sets[cmsSigYCbCrData].push_back(Component("_Y", "Y", 1)); // TYPE_YCbCr_16 - sets[cmsSigYCbCrData].push_back(Component("C_b", "Cb", 1)); - sets[cmsSigYCbCrData].push_back(Component("C_r", "Cr", 1)); - - sets[cmsSigYxyData].push_back(Component("_Y", "Y", 1)); // TYPE_Yxy_16 - sets[cmsSigYxyData].push_back(Component("_x", "x", 1)); - sets[cmsSigYxyData].push_back(Component("y", "y", 1)); - - sets[cmsSigRgbData].push_back(Component(_("_R:"), _("Red"), 1)); // TYPE_RGB_16 - sets[cmsSigRgbData].push_back(Component(_("_G:"), _("Green"), 1)); - sets[cmsSigRgbData].push_back(Component(_("_B:"), _("Blue"), 1)); - - sets[cmsSigGrayData].push_back(Component(_("G:"), _("Gray"), 1)); // TYPE_GRAY_16 - - sets[cmsSigHsvData].push_back(Component(_("_H:"), _("Hue"), 360)); // TYPE_HSV_16 - sets[cmsSigHsvData].push_back(Component(_("_S:"), _("Saturation"), 1)); - sets[cmsSigHsvData].push_back(Component("_V:", "Value", 1)); - - sets[cmsSigHlsData].push_back(Component(_("_H:"), _("Hue"), 360)); // TYPE_HLS_16 - sets[cmsSigHlsData].push_back(Component(_("_L:"), _("Lightness"), 1)); - sets[cmsSigHlsData].push_back(Component(_("_S:"), _("Saturation"), 1)); - - sets[cmsSigCmykData].push_back(Component(_("_C:"), _("Cyan"), 1)); // TYPE_CMYK_16 - sets[cmsSigCmykData].push_back(Component(_("_M:"), _("Magenta"), 1)); - sets[cmsSigCmykData].push_back(Component(_("_Y:"), _("Yellow"), 1)); - sets[cmsSigCmykData].push_back(Component(_("_K:"), _("Black"), 1)); - - sets[cmsSigCmyData].push_back(Component(_("_C:"), _("Cyan"), 1)); // TYPE_CMY_16 - sets[cmsSigCmyData].push_back(Component(_("_M:"), _("Magenta"), 1)); - sets[cmsSigCmyData].push_back(Component(_("_Y:"), _("Yellow"), 1)); - - for (std::map<cmsUInt32Number, std::vector<Component> >::iterator it = sets.begin(); it != sets.end(); ++it) - { - knownColorspaces.insert(it->first); - maxColorspaceComponentCount = std::max(maxColorspaceComponentCount, it->second.size()); - } - } - - std::vector<Component> target; - - if (sets.find(space) != sets.end()) - { - target = sets[space]; - } - return target; -} - - -std::vector<colorspace::Component> colorspace::getColorSpaceInfo( Inkscape::ColorProfile *prof ) -{ - return getColorSpaceInfo( asICColorSpaceSig(prof->getColorSpace()) ); -} - -#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - -ColorICCSelectorImpl::ColorICCSelectorImpl(ColorICCSelector *owner) : - _owner(owner), - _updating( FALSE ), - _dragging( FALSE ), - _fixupNeeded(0), - _fixupBtn(0), - _profileSel(0), - _compUI(), - _adj(0), - _slider(0), - _sbtn(0), - _label(0) -#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - , - _profileName(), - _prof(0), - _profChannelCount(0), - _profChangedID(0) -#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) -{ -} - -ColorICCSelectorImpl::~ColorICCSelectorImpl() -{ - _adj = 0; - _sbtn = 0; - _label = 0; -} - -void ColorICCSelector::init() -{ - if (_impl) delete(_impl); - _impl = new ColorICCSelectorImpl(this); - gint row = 0; - - _impl->_updating = FALSE; - _impl->_dragging = FALSE; - -#if GTK_CHECK_VERSION(3,0,0) - GtkWidget *t = gtk_grid_new(); -#else - GtkWidget *t = gtk_table_new(5, 3, FALSE); -#endif - - gtk_widget_show (t); - gtk_box_pack_start (GTK_BOX (_csel), t, TRUE, TRUE, 4); - - _impl->_compUI.clear(); - - // Create components - row = 0; - - - _impl->_fixupBtn = gtk_button_new_with_label(_("Fix")); - g_signal_connect( G_OBJECT(_impl->_fixupBtn), "clicked", G_CALLBACK(ColorICCSelectorImpl::_fixupHit), (gpointer)_impl ); - gtk_widget_set_sensitive( _impl->_fixupBtn, FALSE ); - gtk_widget_set_tooltip_text( _impl->_fixupBtn, _("Fix RGB fallback to match icc-color() value.") ); - //gtk_misc_set_alignment( GTK_MISC (_impl->_fixupBtn), 1.0, 0.5 ); - gtk_widget_show( _impl->_fixupBtn ); - - attachToGridOrTable(t, _impl->_fixupBtn, 0, row, 1, 1); - - // Combobox and store with 2 columns : label (0) and full name (1) - GtkListStore *store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING); - _impl->_profileSel = gtk_combo_box_new_with_model (GTK_TREE_MODEL (store)); - - GtkCellRenderer *renderer = gtk_cell_renderer_text_new (); - gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(_impl->_profileSel), renderer, TRUE); - gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(_impl->_profileSel), renderer, "text", 0, NULL); - - GtkTreeIter iter; - gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, 0, _("<none>"), 1, _("<none>"), -1); - - gtk_widget_show( _impl->_profileSel ); - gtk_combo_box_set_active( GTK_COMBO_BOX(_impl->_profileSel), 0 ); - - attachToGridOrTable(t, _impl->_profileSel, 1, row, 1, 1); - -#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - _impl->_profChangedID = g_signal_connect( G_OBJECT(_impl->_profileSel), "changed", G_CALLBACK(ColorICCSelectorImpl::_profileSelected), (gpointer)_impl ); -#else - gtk_widget_set_sensitive( _impl->_profileSel, false ); -#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - - - row++; - - // populate the data for colorspaces and channels: -#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - std::vector<colorspace::Component> things = colorspace::getColorSpaceInfo( cmsSigRgbData ); -#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - - for ( size_t i = 0; i < maxColorspaceComponentCount; i++ ) { -#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - if (i < things.size()) { - _impl->_compUI.push_back(ComponentUI(things[i])); - } else { - _impl->_compUI.push_back(ComponentUI()); - } - - std::string labelStr = (i < things.size()) ? things[i].name.c_str() : ""; -#else - _impl->_compUI.push_back(ComponentUI()); - - std::string labelStr = "."; -#endif - - _impl->_compUI[i]._label = gtk_label_new_with_mnemonic( labelStr.c_str() ); - gtk_misc_set_alignment( GTK_MISC (_impl->_compUI[i]._label), 1.0, 0.5 ); - gtk_widget_show( _impl->_compUI[i]._label ); - - attachToGridOrTable(t, _impl->_compUI[i]._label, 0, row, 1, 1); - - // Adjustment - guint scaleValue = _impl->_compUI[i]._component.scale; - gdouble step = static_cast<gdouble>(scaleValue) / 100.0; - gdouble page = static_cast<gdouble>(scaleValue) / 10.0; - gint digits = (step > 0.9) ? 0 : 2; - _impl->_compUI[i]._adj = GTK_ADJUSTMENT( gtk_adjustment_new( 0.0, 0.0, scaleValue, step, page, page ) ); - - // Slider - _impl->_compUI[i]._slider = sp_color_slider_new( _impl->_compUI[i]._adj ); -#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - gtk_widget_set_tooltip_text( _impl->_compUI[i]._slider, (i < things.size()) ? things[i].tip.c_str() : "" ); -#else - gtk_widget_set_tooltip_text( _impl->_compUI[i]._slider, "." ); -#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - gtk_widget_show( _impl->_compUI[i]._slider ); - - attachToGridOrTable(t, _impl->_compUI[i]._slider, 1, row, 1, 1, true); - - _impl->_compUI[i]._btn = gtk_spin_button_new( _impl->_compUI[i]._adj, step, digits ); -#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - gtk_widget_set_tooltip_text( _impl->_compUI[i]._btn, (i < things.size()) ? things[i].tip.c_str() : "" ); -#else - gtk_widget_set_tooltip_text( _impl->_compUI[i]._btn, "." ); -#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - sp_dialog_defocus_on_enter( _impl->_compUI[i]._btn ); - gtk_label_set_mnemonic_widget( GTK_LABEL(_impl->_compUI[i]._label), _impl->_compUI[i]._btn ); - gtk_widget_show( _impl->_compUI[i]._btn ); - - attachToGridOrTable(t, _impl->_compUI[i]._btn, 2, row, 1, 1, false, true); - - _impl->_compUI[i]._map = g_new( guchar, 4 * 1024 ); - memset( _impl->_compUI[i]._map, 0x0ff, 1024 * 4 ); - - - // Signals - g_signal_connect( G_OBJECT( _impl->_compUI[i]._adj ), "value_changed", G_CALLBACK( ColorICCSelectorImpl::_adjustmentChanged ), _csel ); - - g_signal_connect( G_OBJECT( _impl->_compUI[i]._slider ), "grabbed", G_CALLBACK( ColorICCSelectorImpl::_sliderGrabbed ), _csel ); - g_signal_connect( G_OBJECT( _impl->_compUI[i]._slider ), "released", G_CALLBACK( ColorICCSelectorImpl::_sliderReleased ), _csel ); - g_signal_connect( G_OBJECT( _impl->_compUI[i]._slider ), "changed", G_CALLBACK( ColorICCSelectorImpl::_sliderChanged ), _csel ); - - row++; - } - - // Label - _impl->_label = gtk_label_new_with_mnemonic(_("_A:")); - gtk_misc_set_alignment(GTK_MISC(_impl->_label), 1.0, 0.5); - gtk_widget_show(_impl->_label); - - attachToGridOrTable(t, _impl->_label, 0, row, 1, 1); - - // Adjustment - _impl->_adj = GTK_ADJUSTMENT(gtk_adjustment_new(0.0, 0.0, 255.0, 1.0, 10.0, 10.0)); - - // Slider - _impl->_slider = sp_color_slider_new(_impl->_adj); - gtk_widget_set_tooltip_text(_impl->_slider, _("Alpha (opacity)")); - gtk_widget_show(_impl->_slider); - - attachToGridOrTable(t, _impl->_slider, 1, row, 1, 1, true); - - sp_color_slider_set_colors( SP_COLOR_SLIDER( _impl->_slider ), - SP_RGBA32_F_COMPOSE( 1.0, 1.0, 1.0, 0.0 ), - SP_RGBA32_F_COMPOSE( 1.0, 1.0, 1.0, 0.5 ), - SP_RGBA32_F_COMPOSE( 1.0, 1.0, 1.0, 1.0 ) ); - - - // Spinbutton - _impl->_sbtn = gtk_spin_button_new(GTK_ADJUSTMENT(_impl->_adj), 1.0, 0); - gtk_widget_set_tooltip_text(_impl->_sbtn, _("Alpha (opacity)")); - sp_dialog_defocus_on_enter(_impl->_sbtn); - gtk_label_set_mnemonic_widget(GTK_LABEL(_impl->_label), _impl->_sbtn); - gtk_widget_show(_impl->_sbtn); - - attachToGridOrTable(t, _impl->_sbtn, 2, row, 1, 1, false, true); - - // Signals - g_signal_connect(G_OBJECT(_impl->_adj), "value_changed", G_CALLBACK(ColorICCSelectorImpl::_adjustmentChanged), _csel); - - g_signal_connect(G_OBJECT(_impl->_slider), "grabbed", G_CALLBACK(ColorICCSelectorImpl::_sliderGrabbed), _csel); - g_signal_connect(G_OBJECT(_impl->_slider), "released", G_CALLBACK(ColorICCSelectorImpl::_sliderReleased), _csel); - g_signal_connect(G_OBJECT(_impl->_slider), "changed", G_CALLBACK(ColorICCSelectorImpl::_sliderChanged), _csel); -} - -static void sp_color_icc_selector_dispose(GObject *object) -{ - if (G_OBJECT_CLASS(sp_color_icc_selector_parent_class)->dispose) { - G_OBJECT_CLASS(sp_color_icc_selector_parent_class)->dispose(object); - } -} - -static void -sp_color_icc_selector_show_all (GtkWidget *widget) -{ - gtk_widget_show (widget); -} - -static void sp_color_icc_selector_hide(GtkWidget *widget) -{ - gtk_widget_hide(widget); -} - -GtkWidget * -sp_color_icc_selector_new (void) -{ - SPColorICCSelector *csel; - - csel = static_cast<SPColorICCSelector*>(g_object_new (SP_TYPE_COLOR_ICC_SELECTOR, NULL)); - - return GTK_WIDGET (csel); -} - - -void ColorICCSelectorImpl::_fixupHit( GtkWidget* /*src*/, gpointer data ) -{ - ColorICCSelectorImpl* self = reinterpret_cast<ColorICCSelectorImpl*>(data); - gtk_widget_set_sensitive( self->_fixupBtn, FALSE ); - self->_adjustmentChanged( self->_compUI[0]._adj, SP_COLOR_ICC_SELECTOR(self->_owner->_csel) ); -} - -#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) -void ColorICCSelectorImpl::_profileSelected( GtkWidget* /*src*/, gpointer data ) -{ - ColorICCSelectorImpl* self = reinterpret_cast<ColorICCSelectorImpl*>(data); - - GtkTreeIter iter; - if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(self->_profileSel), &iter)) { - GtkTreeModel *store = gtk_combo_box_get_model(GTK_COMBO_BOX(self->_profileSel)); - gchar* name = 0; - - gtk_tree_model_get(store, &iter, 1, &name, -1); - self->_switchToProfile( name ); - gtk_widget_set_tooltip_text(self->_profileSel, name ); - - if ( name ) { - g_free( name ); - } - } -} -#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - -#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) -void ColorICCSelectorImpl::_switchToProfile( gchar const* name ) -{ - bool dirty = false; - SPColor tmp( _owner->_color ); - - if ( name ) { - if ( tmp.icc && tmp.icc->colorProfile == name ) { -#ifdef DEBUG_LCMS - g_message("Already at name [%s]", name ); -#endif // DEBUG_LCMS - } else { -#ifdef DEBUG_LCMS - g_message("Need to switch to profile [%s]", name ); -#endif // DEBUG_LCMS - if ( tmp.icc ) { - tmp.icc->colors.clear(); - } else { - tmp.icc = new SVGICCColor(); - } - tmp.icc->colorProfile = name; - Inkscape::ColorProfile* newProf = SP_ACTIVE_DOCUMENT->profileManager->find(name); - if ( newProf ) { - cmsHTRANSFORM trans = newProf->getTransfFromSRGB8(); - if ( trans ) { - guint32 val = _owner->_color.toRGBA32(0); - guchar pre[4] = { - static_cast<guchar>(SP_RGBA32_R_U(val)), - static_cast<guchar>(SP_RGBA32_G_U(val)), - static_cast<guchar>(SP_RGBA32_B_U(val)), - 255}; -#ifdef DEBUG_LCMS - g_message("Shoving in [%02x] [%02x] [%02x]", pre[0], pre[1], pre[2]); -#endif // DEBUG_LCMS - cmsUInt16Number post[4] = {0,0,0,0}; - cmsDoTransform( trans, pre, post, 1 ); -#ifdef DEBUG_LCMS - g_message("got on out [%04x] [%04x] [%04x] [%04x]", post[0], post[1], post[2], post[3]); -#endif // DEBUG_LCMS -#if HAVE_LIBLCMS1 - guint count = _cmsChannelsOf( asICColorSpaceSig(newProf->getColorSpace()) ); -#elif HAVE_LIBLCMS2 - guint count = cmsChannelsOf( asICColorSpaceSig(newProf->getColorSpace()) ); -#endif - - std::vector<colorspace::Component> things = colorspace::getColorSpaceInfo(asICColorSpaceSig(newProf->getColorSpace())); - - for ( guint i = 0; i < count; i++ ) { - gdouble val = (((gdouble)post[i])/65535.0) * (gdouble)((i < things.size()) ? things[i].scale : 1); -#ifdef DEBUG_LCMS - g_message(" scaled %d by %d to be %f", i, ((i < things.size()) ? things[i].scale : 1), val); -#endif // DEBUG_LCMS - tmp.icc->colors.push_back(val); - } - cmsHTRANSFORM retrans = newProf->getTransfToSRGB8(); - if ( retrans ) { - cmsDoTransform( retrans, post, pre, 1 ); -#ifdef DEBUG_LCMS - g_message(" back out [%02x] [%02x] [%02x]", pre[0], pre[1], pre[2]); -#endif // DEBUG_LCMS - tmp.set(SP_RGBA32_U_COMPOSE(pre[0], pre[1], pre[2], 0xff)); - } - } - } - dirty = true; - } - } else { -#ifdef DEBUG_LCMS - g_message("NUKE THE ICC"); -#endif // DEBUG_LCMS - if ( tmp.icc ) { - delete tmp.icc; - tmp.icc = 0; - dirty = true; - _fixupHit( 0, this ); - } else { -#ifdef DEBUG_LCMS - g_message("No icc to nuke"); -#endif // DEBUG_LCMS - } - } - - if ( dirty ) { -#ifdef DEBUG_LCMS - g_message("+----------------"); - g_message("+ new color is [%s]", tmp.toString().c_str()); -#endif // DEBUG_LCMS - _setProfile( tmp.icc ); - //_adjustmentChanged( _compUI[0]._adj, SP_COLOR_ICC_SELECTOR(_csel) ); - _owner->setColorAlpha( tmp, _owner->_alpha, true ); -#ifdef DEBUG_LCMS - g_message("+_________________"); -#endif // DEBUG_LCMS - } -} -#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - -#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) -void ColorICCSelectorImpl::_profilesChanged( std::string const & name ) -{ - GtkComboBox* combo = GTK_COMBO_BOX(_profileSel); - - g_signal_handler_block( G_OBJECT(_profileSel), _profChangedID ); - - GtkListStore *store = GTK_LIST_STORE(gtk_combo_box_get_model(combo)); - gtk_list_store_clear(store); - - GtkTreeIter iter; - gtk_list_store_append (store, &iter); - gtk_list_store_set(store, &iter, 0, _("<none>"), 1, _("<none>"), -1); - - gtk_combo_box_set_active( combo, 0 ); - - int index = 1; - const GSList *current = SP_ACTIVE_DOCUMENT->getResourceList( "iccprofile" ); - while ( current ) { - SPObject* obj = SP_OBJECT(current->data); - Inkscape::ColorProfile* prof = reinterpret_cast<Inkscape::ColorProfile*>(obj); - - gtk_list_store_append (store, &iter); - gtk_list_store_set(store, &iter, 0, gr_ellipsize_text(prof->name, 25).c_str(), 1, prof->name, -1); - - if ( name == prof->name ) { - gtk_combo_box_set_active( combo, index ); - gtk_widget_set_tooltip_text(_profileSel, prof->name ); - } - - index++; - current = g_slist_next(current); - } - - g_signal_handler_unblock( G_OBJECT(_profileSel), _profChangedID ); -} -#else -void ColorICCSelectorImpl::_profilesChanged( std::string const & /*name*/ ) -{ -} -#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - -// Helpers for setting color value - -void ColorICCSelector::_colorChanged() -{ - _impl->_updating = TRUE; - //sp_color_icc_set_color( SP_COLOR_ICC( _icc ), &color ); - -#ifdef DEBUG_LCMS - g_message( "/^^^^^^^^^ %p::_colorChanged(%08x:%s)", this, - _color.toRGBA32(_alpha), ( (_color.icc) ? _color.icc->colorProfile.c_str(): "<null>" ) - ); -#endif // DEBUG_LCMS - -#ifdef DEBUG_LCMS - g_message("FLIPPIES!!!! %p '%s'", _color.icc, (_color.icc ? _color.icc->colorProfile.c_str():"<null>")); -#endif // DEBUG_LCMS - - _impl->_profilesChanged( (_color.icc) ? _color.icc->colorProfile : std::string("") ); - ColorScales::setScaled( _impl->_adj, _alpha ); - -#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - _impl->_setProfile( _color.icc ); - _impl->_fixupNeeded = 0; - gtk_widget_set_sensitive( _impl->_fixupBtn, FALSE ); - - if (_impl->_prof) { - if (_impl->_prof->getTransfToSRGB8() ) { - cmsUInt16Number tmp[4]; - for ( guint i = 0; i < _impl->_profChannelCount; i++ ) { - gdouble val = 0.0; - if ( _color.icc->colors.size() > i ) { - if ( _impl->_compUI[i]._component.scale == 256 ) { - val = (_color.icc->colors[i] + 128.0) / static_cast<gdouble>(_impl->_compUI[i]._component.scale); - } else { - val = _color.icc->colors[i] / static_cast<gdouble>(_impl->_compUI[i]._component.scale); - } - } - tmp[i] = val * 0x0ffff; - } - guchar post[4] = {0,0,0,0}; - cmsHTRANSFORM trans = _impl->_prof->getTransfToSRGB8(); - if ( trans ) { - cmsDoTransform( trans, tmp, post, 1 ); - guint32 other = SP_RGBA32_U_COMPOSE(post[0], post[1], post[2], 255 ); - if ( other != _color.toRGBA32(255) ) { - _impl->_fixupNeeded = other; - gtk_widget_set_sensitive( _impl->_fixupBtn, TRUE ); -#ifdef DEBUG_LCMS - g_message("Color needs to change 0x%06x to 0x%06x", _color.toRGBA32(255) >> 8, other >> 8 ); -#endif // DEBUG_LCMS - } - } - } - } -#else - //(void)color; -#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - _impl->_updateSliders( -1 ); - - - _impl->_updating = FALSE; -#ifdef DEBUG_LCMS - g_message( "\\_________ %p::_colorChanged()", this ); -#endif // DEBUG_LCMS -} - -#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) -void ColorICCSelectorImpl::_setProfile( SVGICCColor* profile ) -{ -#ifdef DEBUG_LCMS - g_message( "/^^^^^^^^^ %p::_setProfile(%s)", this, - ( (profile) ? profile->colorProfile.c_str() : "<null>") - ); -#endif // DEBUG_LCMS - bool profChanged = false; - if ( _prof && (!profile || (_profileName != profile->colorProfile) ) ) { - // Need to clear out the prior one - profChanged = true; - _profileName.clear(); - _prof = 0; - _profChannelCount = 0; - } else if ( profile && !_prof ) { - profChanged = true; - } - - for ( size_t i = 0; i < _compUI.size(); i++ ) { - gtk_widget_hide( _compUI[i]._label ); - gtk_widget_hide( _compUI[i]._slider ); - gtk_widget_hide( _compUI[i]._btn ); - } - - if ( profile ) { - _prof = SP_ACTIVE_DOCUMENT->profileManager->find(profile->colorProfile.c_str()); - if ( _prof && (asICColorProfileClassSig(_prof->getProfileClass()) != cmsSigNamedColorClass) ) { -#if HAVE_LIBLCMS1 - _profChannelCount = _cmsChannelsOf( asICColorSpaceSig(_prof->getColorSpace()) ); -#elif HAVE_LIBLCMS2 - _profChannelCount = cmsChannelsOf( asICColorSpaceSig(_prof->getColorSpace()) ); -#endif - - if ( profChanged ) { - std::vector<colorspace::Component> things = colorspace::getColorSpaceInfo(asICColorSpaceSig(_prof->getColorSpace())); - for (size_t i = 0; (i < things.size()) && (i < _profChannelCount); ++i) - { - _compUI[i]._component = things[i]; - } - - for ( guint i = 0; i < _profChannelCount; i++ ) { - gtk_label_set_text_with_mnemonic( GTK_LABEL(_compUI[i]._label), (i < things.size()) ? things[i].name.c_str() : ""); - - gtk_widget_set_tooltip_text( _compUI[i]._slider, (i < things.size()) ? things[i].tip.c_str() : "" ); - gtk_widget_set_tooltip_text( _compUI[i]._btn, (i < things.size()) ? things[i].tip.c_str() : "" ); - - sp_color_slider_set_colors( SP_COLOR_SLIDER(_compUI[i]._slider), - SPColor(0.0, 0.0, 0.0).toRGBA32(0xff), - SPColor(0.5, 0.5, 0.5).toRGBA32(0xff), - SPColor(1.0, 1.0, 1.0).toRGBA32(0xff) ); -/* - _compUI[i]._adj = GTK_ADJUSTMENT( gtk_adjustment_new( val, 0.0, _fooScales[i], step, page, page ) ); - g_signal_connect( G_OBJECT( _compUI[i]._adj ), "value_changed", G_CALLBACK( _adjustmentChanged ), _csel ); - - sp_color_slider_set_adjustment( SP_COLOR_SLIDER(_compUI[i]._slider), _compUI[i]._adj ); - gtk_spin_button_set_adjustment( GTK_SPIN_BUTTON(_compUI[i]._btn), _compUI[i]._adj ); - gtk_spin_button_set_digits( GTK_SPIN_BUTTON(_compUI[i]._btn), digits ); -*/ - gtk_widget_show( _compUI[i]._label ); - gtk_widget_show( _compUI[i]._slider ); - gtk_widget_show( _compUI[i]._btn ); - //gtk_adjustment_set_value( _compUI[i]._adj, 0.0 ); - //gtk_adjustment_set_value( _compUI[i]._adj, val ); - } - for ( size_t i = _profChannelCount; i < _compUI.size(); i++ ) { - gtk_widget_hide( _compUI[i]._label ); - gtk_widget_hide( _compUI[i]._slider ); - gtk_widget_hide( _compUI[i]._btn ); - } - } - } else { - // Give up for now on named colors - _prof = 0; - } - } - -#ifdef DEBUG_LCMS - g_message( "\\_________ %p::_setProfile()", this ); -#endif // DEBUG_LCMS -} -#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - -void ColorICCSelectorImpl::_updateSliders( gint ignore ) -{ -#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - if ( _owner->_color.icc ) - { - for ( guint i = 0; i < _profChannelCount; i++ ) { - gdouble val = 0.0; - if ( _owner->_color.icc->colors.size() > i ) { - if ( _compUI[i]._component.scale == 256 ) { - val = (_owner->_color.icc->colors[i] + 128.0) / static_cast<gdouble>(_compUI[i]._component.scale); - } else { - val = _owner->_color.icc->colors[i] / static_cast<gdouble>(_compUI[i]._component.scale); - } - } - gtk_adjustment_set_value( _compUI[i]._adj, val ); - } - - if ( _prof ) { - if ( _prof->getTransfToSRGB8() ) { - for ( guint i = 0; i < _profChannelCount; i++ ) { - if ( static_cast<gint>(i) != ignore ) { - cmsUInt16Number* scratch = getScratch(); - cmsUInt16Number filler[4] = {0, 0, 0, 0}; - for ( guint j = 0; j < _profChannelCount; j++ ) { - filler[j] = 0x0ffff * ColorScales::getScaled( _compUI[j]._adj ); - } - - cmsUInt16Number* p = scratch; - for ( guint x = 0; x < 1024; x++ ) { - for ( guint j = 0; j < _profChannelCount; j++ ) { - if ( j == i ) { - *p++ = x * 0x0ffff / 1024; - } else { - *p++ = filler[j]; - } - } - } - - cmsHTRANSFORM trans = _prof->getTransfToSRGB8(); - if ( trans ) { - cmsDoTransform( trans, scratch, _compUI[i]._map, 1024 ); - sp_color_slider_set_map( SP_COLOR_SLIDER(_compUI[i]._slider), _compUI[i]._map ); - } - } - } - } - } - } -#else - (void)ignore; -#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - - guint32 start = _owner->_color.toRGBA32( 0x00 ); - guint32 mid = _owner->_color.toRGBA32( 0x7f ); - guint32 end = _owner->_color.toRGBA32( 0xff ); - - sp_color_slider_set_colors( SP_COLOR_SLIDER(_slider), start, mid, end ); -} - - -void ColorICCSelectorImpl::_adjustmentChanged( GtkAdjustment *adjustment, SPColorICCSelector *cs ) -{ -// // TODO check this. It looks questionable: -// // if a value is entered between 0 and 1 exclusive, normalize it to (int) 0..255 or 0..100 -// if (adjustment->value > 0.0 && adjustment->value < 1.0) { -// gtk_adjustment_set_value( adjustment, floor ((adjustment->value) * adjustment->upper + 0.5) ); -// } - -#ifdef DEBUG_LCMS - g_message( "/^^^^^^^^^ %p::_adjustmentChanged()", cs ); -#endif // DEBUG_LCMS - - ColorICCSelector* iccSelector = static_cast<ColorICCSelector*>(SP_COLOR_SELECTOR(cs)->base); - if (iccSelector->_impl->_updating) { - return; - } - - iccSelector->_impl->_updating = TRUE; - - gint match = -1; - - SPColor newColor( iccSelector->_color ); - gfloat scaled = ColorScales::getScaled( iccSelector->_impl->_adj ); - if ( iccSelector->_impl->_adj == adjustment ) { -#ifdef DEBUG_LCMS - g_message("ALPHA"); -#endif // DEBUG_LCMS - } else { -#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - for ( size_t i = 0; i < iccSelector->_impl->_compUI.size(); i++ ) { - if ( iccSelector->_impl->_compUI[i]._adj == adjustment ) { - match = i; - break; - } - } - if ( match >= 0 ) { -#ifdef DEBUG_LCMS - g_message(" channel %d", match ); -#endif // DEBUG_LCMS - } - - - cmsUInt16Number tmp[4]; - for ( guint i = 0; i < 4; i++ ) { - tmp[i] = ColorScales::getScaled( iccSelector->_impl->_compUI[i]._adj ) * 0x0ffff; - } - guchar post[4] = {0,0,0,0}; - - cmsHTRANSFORM trans = iccSelector->_impl->_prof->getTransfToSRGB8(); - if ( trans ) { - cmsDoTransform( trans, tmp, post, 1 ); - } - - SPColor other( SP_RGBA32_U_COMPOSE(post[0], post[1], post[2], 255) ); - other.icc = new SVGICCColor(); - if ( iccSelector->_color.icc ) { - other.icc->colorProfile = iccSelector->_color.icc->colorProfile; - } - - guint32 prior = iccSelector->_color.toRGBA32(255); - guint32 newer = other.toRGBA32(255); - - if ( prior != newer ) { -#ifdef DEBUG_LCMS - g_message("Transformed color from 0x%08x to 0x%08x", prior, newer ); - g_message(" ~~~~ FLIP"); -#endif // DEBUG_LCMS - newColor = other; - newColor.icc->colors.clear(); - for ( guint i = 0; i < iccSelector->_impl->_profChannelCount; i++ ) { - gdouble val = ColorScales::getScaled( iccSelector->_impl->_compUI[i]._adj ); - val *= iccSelector->_impl->_compUI[i]._component.scale; - if ( iccSelector->_impl->_compUI[i]._component.scale == 256 ) { - val -= 128; - } - newColor.icc->colors.push_back( val ); - } - } -#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - } - iccSelector->_updateInternals( newColor, scaled, iccSelector->_impl->_dragging ); - iccSelector->_impl->_updateSliders( match ); - - iccSelector->_impl->_updating = FALSE; -#ifdef DEBUG_LCMS - g_message( "\\_________ %p::_adjustmentChanged()", cs ); -#endif // DEBUG_LCMS -} - -void ColorICCSelectorImpl::_sliderGrabbed( SPColorSlider * /*slider*/, SPColorICCSelector * /*cs*/ ) -{ -// ColorICCSelector* iccSelector = dynamic_cast<ColorICCSelector*>(SP_COLOR_SELECTOR(cs)->base); -// if (!iccSelector->_dragging) { -// iccSelector->_dragging = TRUE; -// iccSelector->_grabbed(); -// iccSelector->_updateInternals( iccSelector->_color, ColorScales::getScaled( iccSelector->_impl->_adj ), iccSelector->_dragging ); -// } -} - -void ColorICCSelectorImpl::_sliderReleased( SPColorSlider * /*slider*/, SPColorICCSelector * /*cs*/ ) -{ -// ColorICCSelector* iccSelector = dynamic_cast<ColorICCSelector*>(SP_COLOR_SELECTOR(cs)->base); -// if (iccSelector->_dragging) { -// iccSelector->_dragging = FALSE; -// iccSelector->_released(); -// iccSelector->_updateInternals( iccSelector->_color, ColorScales::getScaled( iccSelector->_adj ), iccSelector->_dragging ); -// } -} - -#ifdef DEBUG_LCMS -void ColorICCSelectorImpl::_sliderChanged( SPColorSlider *slider, SPColorICCSelector *cs ) -#else -void ColorICCSelectorImpl::_sliderChanged( SPColorSlider * /*slider*/, SPColorICCSelector * /*cs*/ ) -#endif // DEBUG_LCMS -{ -#ifdef DEBUG_LCMS - g_message("Changed %p and %p", slider, cs ); -#endif // DEBUG_LCMS -// ColorICCSelector* iccSelector = dynamic_cast<ColorICCSelector*>(SP_COLOR_SELECTOR(cs)->base); - -// iccSelector->_updateInternals( iccSelector->_color, ColorScales::getScaled( iccSelector->_adj ), iccSelector->_dragging ); -} - - -/* - 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 : diff --git a/src/widgets/sp-color-icc-selector.h b/src/widgets/sp-color-icc-selector.h deleted file mode 100644 index 6cdaff639..000000000 --- a/src/widgets/sp-color-icc-selector.h +++ /dev/null @@ -1,72 +0,0 @@ -#ifndef SEEN_SP_COLOR_ICC_SELECTOR_H -#define SEEN_SP_COLOR_ICC_SELECTOR_H - -#include <glib.h> -#include "sp-color-selector.h" - -namespace Inkscape { -class ColorProfile; -} - -struct SPColorICCSelector; -struct SPColorICCSelectorClass; - -class ColorICCSelectorImpl; - -class ColorICCSelector: public ColorSelector -{ -public: - ColorICCSelector( SPColorSelector* csel ); - virtual ~ColorICCSelector(); - - virtual void init(); - -protected: - virtual void _colorChanged(); - - void _recalcColor( gboolean changing ); - -private: - friend class ColorICCSelectorImpl; - - // By default, disallow copy constructor and assignment operator - ColorICCSelector( const ColorICCSelector& obj ); - ColorICCSelector& operator=( const ColorICCSelector& obj ); - - ColorICCSelectorImpl *_impl; -}; - - - -#define SP_TYPE_COLOR_ICC_SELECTOR (sp_color_icc_selector_get_type()) -#define SP_COLOR_ICC_SELECTOR(o) (G_TYPE_CHECK_INSTANCE_CAST((o), SP_TYPE_COLOR_ICC_SELECTOR, SPColorICCSelector)) -#define SP_COLOR_ICC_SELECTOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), SP_TYPE_COLOR_ICC_SELECTOR, SPColorICCSelectorClass)) -#define SP_IS_COLOR_ICC_SELECTOR(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), SP_TYPE_COLOR_ICC_SELECTOR)) -#define SP_IS_COLOR_ICC_SELECTOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), SP_TYPE_COLOR_ICC_SELECTOR)) - -struct SPColorICCSelector { - SPColorSelector parent; -}; - -struct SPColorICCSelectorClass { - SPColorSelectorClass parent_class; -}; - -GType sp_color_icc_selector_get_type(void); - -GtkWidget *sp_color_icc_selector_new(void); - - - -#endif // SEEN_SP_COLOR_ICC_SELECTOR_H - -/* - 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 : diff --git a/src/widgets/sp-color-notebook.cpp b/src/widgets/sp-color-notebook.cpp deleted file mode 100644 index c7fa96efd..000000000 --- a/src/widgets/sp-color-notebook.cpp +++ /dev/null @@ -1,826 +0,0 @@ -/* - * A notebook with RGB, CMYK, CMS, HSL, and Wheel pages - * - * Author: - * Lauris Kaplinski <lauris@kaplinski.com> - * bulia byak <buliabyak@users.sf.net> - * - * Copyright (C) 2001-2002 Lauris Kaplinski - * - * This code is in public domain - */ - -#undef SPCS_PREVIEW -#define noDUMP_CHANGE_INFO - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include "widgets/icon.h" -#include <cstring> -#include <string> -#include <cstdlib> -#include <cstddef> -#include <gtk/gtk.h> -#include <glibmm/i18n.h> - -#include "ui/dialog-events.h" -#include "../preferences.h" -#include "sp-color-notebook.h" -#include "spw-utilities.h" -#include "sp-color-scales.h" -#include "sp-color-icc-selector.h" -#include "sp-color-wheel-selector.h" -#include "svg/svg-icc-color.h" -#include "../inkscape.h" -#include "../document.h" -#include "../profile-manager.h" -#include "color-profile.h" -#include "cms-system.h" -#include "ui/tools-switch.h" -#include "ui/tools/tool-base.h" - -using Inkscape::CMSSystem; - -struct SPColorNotebookTracker { - const gchar* name; - const gchar* className; - GType type; - guint submode; - gboolean enabledFull; - gboolean enabledBrief; - SPColorNotebook *backPointer; -}; - -static void sp_color_notebook_dispose(GObject *object); - -static void sp_color_notebook_show_all (GtkWidget *widget); -static void sp_color_notebook_hide(GtkWidget *widget); - -#define XPAD 4 -#define YPAD 1 - -G_DEFINE_TYPE(SPColorNotebook, sp_color_notebook, SP_TYPE_COLOR_SELECTOR); - -static void sp_color_notebook_class_init(SPColorNotebookClass *klass) -{ - GObjectClass *object_class = reinterpret_cast<GObjectClass *>(klass); - GtkWidgetClass *widget_class = reinterpret_cast<GtkWidgetClass *>(klass); - - object_class->dispose = sp_color_notebook_dispose; - - widget_class->show_all = sp_color_notebook_show_all; - widget_class->hide = sp_color_notebook_hide; -} - -static void -sp_color_notebook_switch_page(GtkNotebook *notebook, - GtkWidget *page, - guint page_num, - SPColorNotebook *colorbook) -{ - if ( colorbook ) - { - ColorNotebook* nb = dynamic_cast<ColorNotebook*>(SP_COLOR_SELECTOR(colorbook)->base); - nb->switchPage( notebook, page, page_num ); - - // remember the page we switched to - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setInt("/colorselector/page", page_num); - } -} - -void ColorNotebook::switchPage(GtkNotebook*, - GtkWidget*, - guint page_num) -{ - SPColorSelector* csel; - GtkWidget* widget; - - if ( gtk_notebook_get_current_page (GTK_NOTEBOOK (_book)) >= 0 ) - { - csel = getCurrentSelector(); - csel->base->getColorAlpha(_color, _alpha); - } - widget = gtk_notebook_get_nth_page (GTK_NOTEBOOK (_book), page_num); - if ( widget && SP_IS_COLOR_SELECTOR(widget) ) - { - csel = SP_COLOR_SELECTOR (widget); - csel->base->setColorAlpha( _color, _alpha ); - - // Temporary workaround to undo a spurious GRABBED - _released(); - } -} - -static gint sp_color_notebook_menu_handler( GtkWidget *widget, GdkEvent *event ) -{ - if (event->type == GDK_BUTTON_PRESS) - { - SPColorSelector* csel = SP_COLOR_SELECTOR(widget); - (dynamic_cast<ColorNotebook*>(csel->base))->menuHandler( event ); - - /* Tell calling code that we have handled this event; the buck - * stops here. */ - return TRUE; - } - - /* Tell calling code that we have not handled this event; pass it on. */ - return FALSE; -} - -gint ColorNotebook::menuHandler( GdkEvent* event ) -{ - GdkEventButton *bevent = (GdkEventButton *) event; - gtk_menu_popup (GTK_MENU( _popup ), NULL, NULL, NULL, NULL, - bevent->button, bevent->time); - return TRUE; -} - -static void sp_color_notebook_menuitem_response (GtkMenuItem *menuitem, gpointer user_data) -{ - gboolean active = gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (menuitem)); - SPColorNotebookTracker *entry = reinterpret_cast< SPColorNotebookTracker* > (user_data); - if ( entry ) - { - if ( active ) - { - (dynamic_cast<ColorNotebook*>(SP_COLOR_SELECTOR(entry->backPointer)->base))->addPage(entry->type, entry->submode); - } - else - { - (dynamic_cast<ColorNotebook*>(SP_COLOR_SELECTOR(entry->backPointer)->base))->removePage(entry->type, entry->submode); - } - } -} - -static void -sp_color_notebook_init (SPColorNotebook *colorbook) -{ - SP_COLOR_SELECTOR(colorbook)->base = new ColorNotebook( SP_COLOR_SELECTOR(colorbook) ); - - if ( SP_COLOR_SELECTOR(colorbook)->base ) - { - SP_COLOR_SELECTOR(colorbook)->base->init(); - } -} - -void ColorNotebook::init() -{ - guint row = 0; - guint i = 0; - guint j = 0; - GType *selector_types = 0; - guint selector_type_count = 0; - - /* tempory hardcoding to get types loaded */ - SP_TYPE_COLOR_SCALES; - SP_TYPE_COLOR_WHEEL_SELECTOR; -#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - SP_TYPE_COLOR_ICC_SELECTOR; -#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - - /* REJON: Comment out the next line to not use the normal GTK Color - wheel. */ - -// SP_TYPE_COLOR_GTKSELECTOR; - - _updating = FALSE; - _updatingrgba = FALSE; - _btn = 0; - _popup = 0; - _trackerList = g_ptr_array_new (); - - _book = gtk_notebook_new (); - gtk_widget_show (_book); - - // Dont show the notebook tabs, use radiobuttons instead - gtk_notebook_set_show_border (GTK_NOTEBOOK (_book), false); - gtk_notebook_set_show_tabs (GTK_NOTEBOOK (_book), false); - - selector_types = g_type_children (SP_TYPE_COLOR_SELECTOR, &selector_type_count); - - for ( i = 0; i < selector_type_count; i++ ) - { - if (!g_type_is_a (selector_types[i], SP_TYPE_COLOR_NOTEBOOK)) - { - guint howmany = 1; - gpointer klass = g_type_class_ref (selector_types[i]); - if ( klass && SP_IS_COLOR_SELECTOR_CLASS(klass) ) - { - SPColorSelectorClass *ck = SP_COLOR_SELECTOR_CLASS (klass); - howmany = MAX (1, ck->submode_count); - for ( j = 0; j < howmany; j++ ) - { - SPColorNotebookTracker *entry = reinterpret_cast< SPColorNotebookTracker* > (malloc(sizeof(SPColorNotebookTracker))); - if ( entry ) - { - memset( entry, 0, sizeof(SPColorNotebookTracker) ); - entry->name = ck->name[j]; - entry->type = selector_types[i]; - entry->submode = j; - entry->enabledFull = TRUE; - entry->enabledBrief = TRUE; - entry->backPointer = SP_COLOR_NOTEBOOK(_csel); - - g_ptr_array_add (_trackerList, entry); - } - } - } - } - } - -#if GTK_CHECK_VERSION(3,0,0) - _buttonbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 2); - gtk_box_set_homogeneous(GTK_BOX(_buttonbox), TRUE); -#else - _buttonbox = gtk_hbox_new (TRUE, 2); -#endif - - gtk_widget_show (_buttonbox); - _buttons = new GtkWidget *[_trackerList->len]; - - for ( i = 0; i < _trackerList->len; i++ ) - { - SPColorNotebookTracker *entry = - reinterpret_cast< SPColorNotebookTracker* > (g_ptr_array_index (_trackerList, i)); - if ( entry ) - { - addPage(entry->type, entry->submode); - } - } - -#if GTK_CHECK_VERSION(3,0,0) - GtkWidget* table = gtk_grid_new(); -#else - GtkWidget* table = gtk_table_new(2, 3, FALSE); -#endif - - gtk_widget_show (table); - - gtk_box_pack_start (GTK_BOX (_csel), table, TRUE, TRUE, 0); - - sp_set_font_size_smaller (_buttonbox); - -#if GTK_CHECK_VERSION(3,0,0) - #if GTK_CHECK_VERSION(3,12,0) - gtk_widget_set_margin_start(_buttonbox, XPAD); - gtk_widget_set_margin_end(_buttonbox, XPAD); - #else - gtk_widget_set_margin_left(_buttonbox, XPAD); - gtk_widget_set_margin_right(_buttonbox, XPAD); - #endif - gtk_widget_set_margin_top(_buttonbox, YPAD); - gtk_widget_set_margin_bottom(_buttonbox, YPAD); - gtk_widget_set_hexpand(_buttonbox, TRUE); - gtk_widget_set_valign(_buttonbox, GTK_ALIGN_CENTER); - gtk_grid_attach(GTK_GRID(table), _buttonbox, 0, row, 2, 1); -#else - gtk_table_attach (GTK_TABLE (table), _buttonbox, 0, 2, row, row + 1, - static_cast<GtkAttachOptions>(GTK_EXPAND|GTK_FILL), - static_cast<GtkAttachOptions>(0), - XPAD, YPAD); -#endif - - row++; - -#if GTK_CHECK_VERSION(3,0,0) - #if GTK_CHECK_VERSION(3,12,0) - gtk_widget_set_margin_start(_book, XPAD*2); - gtk_widget_set_margin_end(_book, XPAD*2); - #else - gtk_widget_set_margin_left(_book, XPAD*2); - gtk_widget_set_margin_right(_book, XPAD*2); - #endif - gtk_widget_set_margin_top(_book, YPAD); - gtk_widget_set_margin_bottom(_book, YPAD); - gtk_widget_set_hexpand(_book, TRUE); - gtk_widget_set_vexpand(_book, TRUE); - gtk_grid_attach(GTK_GRID(table), _book, 0, row, 2, 1); -#else - gtk_table_attach (GTK_TABLE (table), _book, 0, 2, row, row + 1, - static_cast<GtkAttachOptions>(GTK_EXPAND|GTK_FILL), - static_cast<GtkAttachOptions>(GTK_EXPAND|GTK_FILL), - XPAD*2, YPAD); -#endif - - // restore the last active page - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - _setCurrentPage(prefs->getInt("/colorselector/page", 0)); - - { - gboolean found = FALSE; - - _popup = gtk_menu_new(); - GtkMenu *menu = GTK_MENU (_popup); - - for ( i = 0; i < _trackerList->len; i++ ) - { - SPColorNotebookTracker *entry = reinterpret_cast< SPColorNotebookTracker* > (g_ptr_array_index (_trackerList, i)); - if ( entry ) - { - GtkWidget *item = gtk_check_menu_item_new_with_label (_(entry->name)); - gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), entry->enabledFull); - gtk_widget_show (item); - gtk_menu_shell_append (GTK_MENU_SHELL(menu), item); - - g_signal_connect (G_OBJECT (item), "activate", - G_CALLBACK (sp_color_notebook_menuitem_response), - reinterpret_cast< gpointer > (entry) ); - found = TRUE; - } - } - - GtkWidget *arrow = gtk_arrow_new(GTK_ARROW_RIGHT, GTK_SHADOW_NONE); - gtk_widget_show (arrow); - - _btn = gtk_button_new (); - gtk_widget_show (_btn); - gtk_container_add (GTK_CONTAINER (_btn), arrow); - - GtkWidget *align = gtk_alignment_new (1.0, 0.0, 0.0, 0.0); - gtk_widget_show (align); - gtk_container_add (GTK_CONTAINER (align), _btn); - - // uncomment to reenable the "show/hide modes" menu, - // but first fix it so it remembers its settings in prefs and does not take that much space (entire vertical column!) - //gtk_table_attach (GTK_TABLE (table), align, 2, 3, row, row + 1, GTK_FILL, GTK_FILL, XPAD, YPAD); - - g_signal_connect_swapped(G_OBJECT(_btn), "event", G_CALLBACK (sp_color_notebook_menu_handler), G_OBJECT(_csel)); - if ( !found ) - { - gtk_widget_set_sensitive (_btn, FALSE); - } - } - - row++; - -#if GTK_CHECK_VERSION(3,0,0) - GtkWidget *rgbabox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); -#else - GtkWidget *rgbabox = gtk_hbox_new (FALSE, 0); -#endif - -#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - /* Create color management icons */ - _box_colormanaged = gtk_event_box_new (); - GtkWidget *colormanaged = gtk_image_new_from_icon_name ("color-management-icon", GTK_ICON_SIZE_SMALL_TOOLBAR); - gtk_container_add (GTK_CONTAINER (_box_colormanaged), colormanaged); - gtk_widget_set_tooltip_text (_box_colormanaged, _("Color Managed")); - gtk_widget_set_sensitive (_box_colormanaged, false); - gtk_box_pack_start(GTK_BOX(rgbabox), _box_colormanaged, FALSE, FALSE, 2); - - _box_outofgamut = gtk_event_box_new (); - GtkWidget *outofgamut = gtk_image_new_from_icon_name ("out-of-gamut-icon", GTK_ICON_SIZE_SMALL_TOOLBAR); - gtk_container_add (GTK_CONTAINER (_box_outofgamut), outofgamut); - gtk_widget_set_tooltip_text (_box_outofgamut, _("Out of gamut!")); - gtk_widget_set_sensitive (_box_outofgamut, false); - gtk_box_pack_start(GTK_BOX(rgbabox), _box_outofgamut, FALSE, FALSE, 2); - - _box_toomuchink = gtk_event_box_new (); - GtkWidget *toomuchink = gtk_image_new_from_icon_name ("too-much-ink-icon", GTK_ICON_SIZE_SMALL_TOOLBAR); - gtk_container_add (GTK_CONTAINER (_box_toomuchink), toomuchink); - gtk_widget_set_tooltip_text (_box_toomuchink, _("Too much ink!")); - gtk_widget_set_sensitive (_box_toomuchink, false); - gtk_box_pack_start(GTK_BOX(rgbabox), _box_toomuchink, FALSE, FALSE, 2); -#endif //defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - - - /* Color picker */ - GtkWidget *picker = gtk_image_new_from_icon_name ("color-picker", GTK_ICON_SIZE_SMALL_TOOLBAR); - _btn_picker = gtk_button_new (); - gtk_button_set_relief(GTK_BUTTON(_btn_picker), GTK_RELIEF_NONE); - gtk_widget_show (_btn); - gtk_container_add (GTK_CONTAINER (_btn_picker), picker); - gtk_widget_set_tooltip_text (_btn_picker, _("Pick colors from image")); - gtk_box_pack_start(GTK_BOX(rgbabox), _btn_picker, FALSE, FALSE, 2); - g_signal_connect(G_OBJECT(_btn_picker), "clicked", G_CALLBACK(ColorNotebook::_picker_clicked), _csel); - - /* Create RGBA entry and color preview */ - _rgbal = gtk_label_new_with_mnemonic (_("RGBA_:")); - gtk_misc_set_alignment (GTK_MISC (_rgbal), 1.0, 0.5); - gtk_box_pack_start(GTK_BOX(rgbabox), _rgbal, TRUE, TRUE, 2); - - _rgbae = gtk_entry_new (); - sp_dialog_defocus_on_enter (_rgbae); - gtk_entry_set_max_length (GTK_ENTRY (_rgbae), 8); - gtk_entry_set_width_chars (GTK_ENTRY (_rgbae), 8); - gtk_widget_set_tooltip_text (_rgbae, _("Hexadecimal RGBA value of the color")); - gtk_box_pack_start(GTK_BOX(rgbabox), _rgbae, FALSE, FALSE, 0); - gtk_label_set_mnemonic_widget (GTK_LABEL(_rgbal), _rgbae); - - sp_set_font_size_smaller (rgbabox); - gtk_widget_show_all (rgbabox); - -#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - //the "too much ink" icon is initially hidden - gtk_widget_hide(GTK_WIDGET(_box_toomuchink)); -#endif //defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - -#if GTK_CHECK_VERSION(3,0,0) - #if GTK_CHECK_VERSION(3,12,0) - gtk_widget_set_margin_start(rgbabox, XPAD); - gtk_widget_set_margin_end(rgbabox, XPAD); - #else - gtk_widget_set_margin_left(rgbabox, XPAD); - gtk_widget_set_margin_right(rgbabox, XPAD); - #endif - gtk_widget_set_margin_top(rgbabox, YPAD); - gtk_widget_set_margin_bottom(rgbabox, YPAD); - gtk_grid_attach(GTK_GRID(table), rgbabox, 0, row, 2, 1); -#else - gtk_table_attach (GTK_TABLE (table), rgbabox, 0, 2, row, row + 1, GTK_FILL, GTK_SHRINK, XPAD, YPAD); -#endif - -#ifdef SPCS_PREVIEW - _p = sp_color_preview_new (0xffffffff); - gtk_widget_show (_p); - gtk_table_attach (GTK_TABLE (table), _p, 2, 3, row, row + 1, GTK_FILL, GTK_FILL, XPAD, YPAD); -#endif - - _switchId = g_signal_connect(G_OBJECT (_book), "switch-page", - G_CALLBACK (sp_color_notebook_switch_page), SP_COLOR_NOTEBOOK(_csel)); - - _entryId = g_signal_connect (G_OBJECT (_rgbae), "changed", G_CALLBACK (ColorNotebook::_rgbaEntryChangedHook), _csel); -} - -static void sp_color_notebook_dispose(GObject *object) -{ - if (G_OBJECT_CLASS(sp_color_notebook_parent_class)->dispose) - G_OBJECT_CLASS(sp_color_notebook_parent_class)->dispose(object); -} - -ColorNotebook::~ColorNotebook() -{ - if ( _trackerList ) - { - g_ptr_array_free (_trackerList, TRUE); - _trackerList = 0; - } - - if ( _switchId ) - { - if ( _book ) - { - g_signal_handler_disconnect (_book, _switchId); - _switchId = 0; - } - } - - if ( _buttons ) - { - delete [] _buttons; - _buttons = 0; - } - -} - -static void -sp_color_notebook_show_all (GtkWidget *widget) -{ - gtk_widget_show (widget); -} - -static void sp_color_notebook_hide(GtkWidget *widget) -{ - gtk_widget_hide(widget); -} - -GtkWidget *sp_color_notebook_new() -{ - SPColorNotebook *colorbook = SP_COLOR_NOTEBOOK(g_object_new (SP_TYPE_COLOR_NOTEBOOK, NULL)); - - return GTK_WIDGET(colorbook); -} - -ColorNotebook::ColorNotebook( SPColorSelector* csel ) - : ColorSelector( csel ) -{ -} - -SPColorSelector* ColorNotebook::getCurrentSelector() -{ - SPColorSelector* csel = NULL; - gint current_page = gtk_notebook_get_current_page (GTK_NOTEBOOK (_book)); - - if ( current_page >= 0 ) - { - GtkWidget* widget = gtk_notebook_get_nth_page (GTK_NOTEBOOK (_book), current_page); - if ( SP_IS_COLOR_SELECTOR (widget) ) - { - csel = SP_COLOR_SELECTOR (widget); - } - } - - return csel; -} - -void ColorNotebook::_colorChanged() -{ - SPColorSelector* cselPage = getCurrentSelector(); - if ( cselPage ) - { - cselPage->base->setColorAlpha( _color, _alpha ); - } - - _updateRgbaEntry( _color, _alpha ); -} - -void ColorNotebook::_picker_clicked(GtkWidget * /*widget*/, SPColorNotebook * /*colorbook*/) -{ - // Set the dropper into a "one click" mode, so it reverts to the previous tool after a click - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setBool("/tools/dropper/onetimepick", true); - Inkscape::UI::Tools::sp_toggle_dropper(SP_ACTIVE_DESKTOP); -} - -void ColorNotebook::_rgbaEntryChangedHook(GtkEntry *entry, SPColorNotebook *colorbook) -{ - (dynamic_cast<ColorNotebook*>(SP_COLOR_SELECTOR(colorbook)->base))->_rgbaEntryChanged( entry ); -} - -void ColorNotebook::_rgbaEntryChanged(GtkEntry* entry) -{ - if (_updating) return; - if (_updatingrgba) return; - - const gchar *t = gtk_entry_get_text( entry ); - - if (t) { - Glib::ustring text = t; - bool changed = false; - if (!text.empty() && text[0] == '#') { - changed = true; - text.erase(0,1); - if (text.size() == 6) { - // it was a standard RGB hex - unsigned int alph = SP_COLOR_F_TO_U(_alpha); - gchar* tmp = g_strdup_printf("%02x", alph); - text += tmp; - g_free(tmp); - } - } - gchar* str = g_strdup(text.c_str()); - gchar* end = 0; - guint64 rgba = g_ascii_strtoull( str, &end, 16 ); - if ( end != str ) { - ptrdiff_t len = end - str; - if ( len < 8 ) { - rgba = rgba << ( 4 * ( 8 - len ) ); - } - _updatingrgba = TRUE; - if ( changed ) { - gtk_entry_set_text( entry, str ); - } - SPColor color( rgba ); - setColorAlpha( color, SP_RGBA32_A_F(rgba), true ); - _updatingrgba = FALSE; - } - g_free(str); - } -} - -// TODO pass in param so as to avoid the need for SP_ACTIVE_DOCUMENT -void ColorNotebook::_updateRgbaEntry( const SPColor& color, gfloat alpha ) -{ - g_return_if_fail( ( 0.0 <= alpha ) && ( alpha <= 1.0 ) ); - -#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - /* update color management icon*/ - gtk_widget_set_sensitive (_box_colormanaged, color.icc != NULL); - - /* update out-of-gamut icon */ - gtk_widget_set_sensitive (_box_outofgamut, false); - if (color.icc){ - Inkscape::ColorProfile* target_profile = SP_ACTIVE_DOCUMENT->profileManager->find(color.icc->colorProfile.c_str()); - if ( target_profile ) - gtk_widget_set_sensitive(_box_outofgamut, target_profile->GamutCheck(color)); - } - - /* update too-much-ink icon */ - gtk_widget_set_sensitive (_box_toomuchink, false); - if (color.icc){ - Inkscape::ColorProfile* prof = SP_ACTIVE_DOCUMENT->profileManager->find(color.icc->colorProfile.c_str()); - if ( prof && CMSSystem::isPrintColorSpace(prof) ) { - gtk_widget_show(GTK_WIDGET(_box_toomuchink)); - double ink_sum = 0; - for (unsigned int i=0; i<color.icc->colors.size(); i++){ - ink_sum += color.icc->colors[i]; - } - - /* Some literature states that when the sum of paint values exceed 320%, it is considered to be a satured color, - which means the paper can get too wet due to an excessive ammount of ink. This may lead to several issues - such as misalignment and poor quality of printing in general.*/ - if ( ink_sum > 3.2 ) - gtk_widget_set_sensitive (_box_toomuchink, true); - } else { - gtk_widget_hide(GTK_WIDGET(_box_toomuchink)); - } - } -#endif //defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - - if ( !_updatingrgba ) - { - gchar s[32]; - guint32 rgba; - - /* Update RGBA entry */ - rgba = color.toRGBA32( alpha ); - - g_snprintf (s, 32, "%08x", rgba); - const gchar* oldText = gtk_entry_get_text( GTK_ENTRY( _rgbae ) ); - if ( strcmp( oldText, s ) != 0 ) - { - g_signal_handler_block( _rgbae, _entryId ); - gtk_entry_set_text( GTK_ENTRY(_rgbae), s ); - g_signal_handler_unblock( _rgbae, _entryId ); - } - } -} - -void ColorNotebook::_setCurrentPage(int i) -{ - gtk_notebook_set_current_page(GTK_NOTEBOOK(_book), i); - - if (_buttons && _trackerList && (static_cast<size_t>(i) < _trackerList->len) ) { - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(_buttons[i]), TRUE); - } -} - -void ColorNotebook::_buttonClicked(GtkWidget *widget, SPColorNotebook *colorbook) -{ - ColorNotebook* nb = dynamic_cast<ColorNotebook*>(SP_COLOR_SELECTOR(colorbook)->base); - - if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(widget))) { - return; - } - - for(gint i = 0; i < gtk_notebook_get_n_pages (GTK_NOTEBOOK (nb->_book)); i++) { - if (nb->_buttons[i] == widget) { - gtk_notebook_set_current_page (GTK_NOTEBOOK (nb->_book), i); - } - } -} - -void ColorNotebook::_entryGrabbed (SPColorSelector *, SPColorNotebook *colorbook) -{ - ColorNotebook* nb = dynamic_cast<ColorNotebook*>(SP_COLOR_SELECTOR(colorbook)->base); - nb->_grabbed(); -} - -void ColorNotebook::_entryDragged (SPColorSelector *csel, SPColorNotebook *colorbook) -{ - gboolean oldState; - ColorNotebook* nb = dynamic_cast<ColorNotebook*>(SP_COLOR_SELECTOR(colorbook)->base); - - oldState = nb->_dragging; - - nb->_dragging = TRUE; - nb->_entryModified( csel, colorbook ); - - nb->_dragging = oldState; -} - -void ColorNotebook::_entryReleased (SPColorSelector *, SPColorNotebook *colorbook) -{ - ColorNotebook* nb = dynamic_cast<ColorNotebook*>(SP_COLOR_SELECTOR(colorbook)->base); - nb->_released(); -} - -void ColorNotebook::_entryChanged (SPColorSelector *csel, SPColorNotebook *colorbook) -{ - gboolean oldState; - ColorNotebook* nb = dynamic_cast<ColorNotebook*>(SP_COLOR_SELECTOR(colorbook)->base); - - oldState = nb->_dragging; - - nb->_dragging = FALSE; - nb->_entryModified( csel, colorbook ); - - nb->_dragging = oldState; -} - -void ColorNotebook::_entryModified (SPColorSelector *csel, SPColorNotebook *colorbook) -{ - g_return_if_fail (colorbook != NULL); - g_return_if_fail (SP_IS_COLOR_NOTEBOOK (colorbook)); - g_return_if_fail (csel != NULL); - g_return_if_fail (SP_IS_COLOR_SELECTOR (csel)); - - ColorNotebook* nb = dynamic_cast<ColorNotebook*>(SP_COLOR_SELECTOR(colorbook)->base); - SPColor color; - gfloat alpha = 1.0; - - csel->base->getColorAlpha( color, alpha ); - nb->_updateRgbaEntry( color, alpha ); - nb->_updateInternals( color, alpha, nb->_dragging ); -} - -GtkWidget* ColorNotebook::addPage(GType page_type, guint submode) -{ - GtkWidget *page; - - page = sp_color_selector_new( page_type ); - if ( page ) - { - GtkWidget* tab_label = 0; - SPColorSelector* csel; - - csel = SP_COLOR_SELECTOR (page); - if ( submode > 0 ) - { - csel->base->setSubmode( submode ); - } - gtk_widget_show (page); - int index = csel->base ? csel->base->getSubmode() : 0; - const gchar* str = _(SP_COLOR_SELECTOR_GET_CLASS (csel)->name[index]); -// g_message( "Hitting up for tab for '%s'", str ); - tab_label = gtk_label_new(_(str)); - gint pageNum = gtk_notebook_append_page( GTK_NOTEBOOK (_book), page, tab_label ); - - // Add a button for each page - _buttons[pageNum] = gtk_radio_button_new_with_label(NULL, _(str)); - gtk_toggle_button_set_mode(GTK_TOGGLE_BUTTON(_buttons[pageNum]), FALSE); - if (pageNum > 0) { - GSList *group = gtk_radio_button_get_group (GTK_RADIO_BUTTON(_buttons[0])); - gtk_radio_button_set_group (GTK_RADIO_BUTTON(_buttons[pageNum]), group); - } - gtk_widget_show (_buttons[pageNum]); - gtk_box_pack_start (GTK_BOX (_buttonbox), _buttons[pageNum], TRUE, TRUE, 0); - - g_signal_connect (G_OBJECT (_buttons[pageNum]), "clicked", G_CALLBACK (_buttonClicked), _csel); - g_signal_connect (G_OBJECT (page), "grabbed", G_CALLBACK (_entryGrabbed), _csel); - g_signal_connect (G_OBJECT (page), "dragged", G_CALLBACK (_entryDragged), _csel); - g_signal_connect (G_OBJECT (page), "released", G_CALLBACK (_entryReleased), _csel); - g_signal_connect (G_OBJECT (page), "changed", G_CALLBACK (_entryChanged), _csel); - } - - return page; -} - -GtkWidget* ColorNotebook::getPage(GType page_type, guint submode) -{ - gint count = 0; - gint i = 0; - GtkWidget* page = 0; - -// count = gtk_notebook_get_n_pages (_book); - count = 200; - for ( i = 0; i < count && !page; i++ ) - { - page = gtk_notebook_get_nth_page (GTK_NOTEBOOK (_book), i); - if ( page ) - { - SPColorSelector* csel; - guint pagemode; - csel = SP_COLOR_SELECTOR (page); - pagemode = csel->base->getSubmode(); - if ( G_TYPE_FROM_INSTANCE (page) == page_type - && pagemode == submode ) - { - // found it. - break; - } - else - { - page = 0; - } - } - else - { - break; - } - } - return page; -} - -void ColorNotebook::removePage( GType page_type, guint submode ) -{ - GtkWidget *page = 0; - - page = getPage(page_type, submode); - if ( page ) - { - gint where = gtk_notebook_page_num (GTK_NOTEBOOK (_book), page); - if ( where >= 0 ) - { - if ( gtk_notebook_get_current_page (GTK_NOTEBOOK (_book)) == where ) - { -// getColorAlpha(_color, &_alpha); - } - gtk_notebook_remove_page (GTK_NOTEBOOK (_book), where); - } - } -} - -/* - 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 : diff --git a/src/widgets/sp-color-notebook.h b/src/widgets/sp-color-notebook.h deleted file mode 100644 index 469bb56e8..000000000 --- a/src/widgets/sp-color-notebook.h +++ /dev/null @@ -1,120 +0,0 @@ -#ifndef SEEN_SP_COLOR_NOTEBOOK_H -#define SEEN_SP_COLOR_NOTEBOOK_H - -/* - * A notebook with RGB, CMYK, CMS, HSL, and Wheel pages - * - * Author: - * Lauris Kaplinski <lauris@kaplinski.com> - * - * Copyright (C) 2001-2002 Lauris Kaplinski - * - * This code is in public domain - */ - -#include "sp-color-selector.h" - -#include <glib.h> - -struct SPColorNotebook; - -class ColorNotebook: public ColorSelector -{ -public: - ColorNotebook( SPColorSelector* csel ); - virtual ~ColorNotebook(); - - virtual void init(); - - SPColorSelector* getCurrentSelector(); - void switchPage( GtkNotebook *notebook, GtkWidget *page, guint page_num ); - - GtkWidget* addPage( GType page_type, guint submode ); - void removePage( GType page_type, guint submode ); - GtkWidget* getPage( GType page_type, guint submode ); - - gint menuHandler( GdkEvent* event ); - -protected: - static void _rgbaEntryChangedHook( GtkEntry* entry, SPColorNotebook *colorbook ); - static void _entryGrabbed( SPColorSelector *csel, SPColorNotebook *colorbook ); - static void _entryDragged( SPColorSelector *csel, SPColorNotebook *colorbook ); - static void _entryReleased( SPColorSelector *csel, SPColorNotebook *colorbook ); - static void _entryChanged( SPColorSelector *csel, SPColorNotebook *colorbook ); - static void _entryModified( SPColorSelector *csel, SPColorNotebook *colorbook ); - static void _buttonClicked(GtkWidget *widget, SPColorNotebook *colorbook); - static void _picker_clicked(GtkWidget *widget, SPColorNotebook *colorbook); - - virtual void _colorChanged(); - - void _rgbaEntryChanged( GtkEntry* entry ); - void _updateRgbaEntry( const SPColor& color, gfloat alpha ); - void _setCurrentPage(int i); - - gboolean _updating : 1; - gboolean _updatingrgba : 1; - gboolean _dragging : 1; - gulong _switchId; - gulong _entryId; - GtkWidget *_book; - GtkWidget *_buttonbox; - GtkWidget **_buttons; - GtkWidget *_rgbal, *_rgbae; /* RGBA entry */ -#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - GtkWidget *_box_outofgamut, *_box_colormanaged, *_box_toomuchink; -#endif //defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - GtkWidget *_btn_picker; - GtkWidget *_p; /* Color preview */ - GtkWidget *_btn; - GtkWidget *_popup; - GPtrArray *_trackerList; - -private: - // By default, disallow copy constructor and assignment operator - ColorNotebook( const ColorNotebook& obj ); - ColorNotebook& operator=( const ColorNotebook& obj ); -}; - - - -#define SP_TYPE_COLOR_NOTEBOOK (sp_color_notebook_get_type ()) -#define SP_COLOR_NOTEBOOK(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SP_TYPE_COLOR_NOTEBOOK, SPColorNotebook)) -#define SP_COLOR_NOTEBOOK_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), SP_TYPE_COLOR_NOTEBOOK, SPColorNotebookClass)) -#define SP_IS_COLOR_NOTEBOOK(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SP_TYPE_COLOR_NOTEBOOK)) -#define SP_IS_COLOR_NOTEBOOK_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SP_TYPE_COLOR_NOTEBOOK)) - -struct SPColorNotebook { - SPColorSelector parent; /* Parent */ -}; - -struct SPColorNotebookClass { - SPColorSelectorClass parent_class; - - void (* grabbed) (SPColorNotebook *rgbsel); - void (* dragged) (SPColorNotebook *rgbsel); - void (* released) (SPColorNotebook *rgbsel); - void (* changed) (SPColorNotebook *rgbsel); -}; - -GType sp_color_notebook_get_type(void); - -GtkWidget *sp_color_notebook_new (void); - -/* void sp_color_notebook_set_mode (SPColorNotebook *csel, SPColorNotebookMode mode); */ -/* SPColorNotebookMode sp_color_notebook_get_mode (SPColorNotebook *csel); */ - - - -#endif // SEEN_SP_COLOR_NOTEBOOK_H - -/* - 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 : - diff --git a/src/widgets/sp-color-scales.cpp b/src/widgets/sp-color-scales.cpp deleted file mode 100644 index 60ba62ec5..000000000 --- a/src/widgets/sp-color-scales.cpp +++ /dev/null @@ -1,760 +0,0 @@ -/* - * bulia byak <buliabyak@users.sf.net> - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif -#include <math.h> -#include <gtk/gtk.h> -#include <glibmm/i18n.h> -#include "ui/dialog-events.h" -#include "sp-color-scales.h" -#include "sp-color-slider.h" -#include "svg/svg-icc-color.h" - -#define CSC_CHANNEL_R (1 << 0) -#define CSC_CHANNEL_G (1 << 1) -#define CSC_CHANNEL_B (1 << 2) -#define CSC_CHANNEL_A (1 << 3) -#define CSC_CHANNEL_H (1 << 0) -#define CSC_CHANNEL_S (1 << 1) -#define CSC_CHANNEL_V (1 << 2) -#define CSC_CHANNEL_C (1 << 0) -#define CSC_CHANNEL_M (1 << 1) -#define CSC_CHANNEL_Y (1 << 2) -#define CSC_CHANNEL_K (1 << 3) -#define CSC_CHANNEL_CMYKA (1 << 4) - -#define CSC_CHANNELS_ALL 0 - - -G_BEGIN_DECLS - -static void sp_color_scales_dispose(GObject *object); - -static void sp_color_scales_show_all (GtkWidget *widget); -static void sp_color_scales_hide(GtkWidget *widget); - -static const gchar *sp_color_scales_hue_map (void); - -G_END_DECLS - -#define XPAD 4 -#define YPAD 1 - -#define noDUMP_CHANGE_INFO 1 - -G_DEFINE_TYPE(SPColorScales, sp_color_scales, SP_TYPE_COLOR_SELECTOR); - -static void -sp_color_scales_class_init (SPColorScalesClass *klass) -{ - static const gchar* nameset[] = {N_("RGB"), N_("HSL"), N_("CMYK"), 0}; - GObjectClass *object_class = G_OBJECT_CLASS(klass); - GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass); - SPColorSelectorClass *selector_class = SP_COLOR_SELECTOR_CLASS (klass); - - selector_class->name = nameset; - selector_class->submode_count = 3; - - object_class->dispose = sp_color_scales_dispose; - - widget_class->show_all = sp_color_scales_show_all; - widget_class->hide = sp_color_scales_hide; -} - -ColorScales::ColorScales( SPColorSelector* csel ) - : ColorSelector( csel ), - _mode( SP_COLOR_SCALES_MODE_NONE ), - _rangeLimit( 255.0 ), - _updating( FALSE ), - _dragging( FALSE ) -{ - for (gint i = 0; i < 5; i++) { - _l[i] = 0; - _a[i] = 0; - _s[i] = 0; - _b[i] = 0; - } -} - -ColorScales::~ColorScales() -{ - for (gint i = 0; i < 5; i++) { - _l[i] = 0; - _a[i] = 0; - _s[i] = 0; - _b[i] = 0; - } -} - -void sp_color_scales_init (SPColorScales *cs) -{ - SP_COLOR_SELECTOR(cs)->base = new ColorScales( SP_COLOR_SELECTOR(cs) ); - - if ( SP_COLOR_SELECTOR(cs)->base ) - { - SP_COLOR_SELECTOR(cs)->base->init(); - } -} - -void ColorScales::init() -{ - gint i; - - _updating = FALSE; - _dragging = FALSE; - -#if GTK_CHECK_VERSION(3,0,0) - GtkWidget *t = gtk_grid_new(); -#else - GtkWidget *t = gtk_table_new (5, 3, FALSE); -#endif - gtk_widget_show (t); - gtk_box_pack_start (GTK_BOX (_csel), t, TRUE, TRUE, 4); - - /* Create components */ - for (i = 0; i < static_cast< gint > (G_N_ELEMENTS(_a)) ; i++) { - /* Label */ - _l[i] = gtk_label_new(""); - gtk_misc_set_alignment (GTK_MISC (_l[i]), 1.0, 0.5); - gtk_widget_show (_l[i]); - -#if GTK_CHECK_VERSION(3,0,0) - #if GTK_CHECK_VERSION(3,12,0) - gtk_widget_set_margin_start(_l[i], XPAD); - gtk_widget_set_margin_end(_l[i], XPAD); - #else - gtk_widget_set_margin_left(_l[i], XPAD); - gtk_widget_set_margin_right(_l[i], XPAD); - #endif - gtk_widget_set_margin_top(_l[i], YPAD); - gtk_widget_set_margin_bottom(_l[i], YPAD); - gtk_grid_attach(GTK_GRID(t), _l[i], 0, i, 1, 1); -#else - gtk_table_attach (GTK_TABLE (t), _l[i], 0, 1, i, i + 1, GTK_FILL, GTK_FILL, XPAD, YPAD); -#endif - - /* Adjustment */ - _a[i] = GTK_ADJUSTMENT(gtk_adjustment_new(0.0, 0.0, _rangeLimit, 1.0, 10.0, 10.0)); - /* Slider */ - _s[i] = sp_color_slider_new (_a[i]); - gtk_widget_show (_s[i]); - -#if GTK_CHECK_VERSION(3,0,0) - #if GTK_CHECK_VERSION(3,12,0) - gtk_widget_set_margin_start(_s[i], XPAD); - gtk_widget_set_margin_end(_s[i], XPAD); - #else - gtk_widget_set_margin_left(_s[i], XPAD); - gtk_widget_set_margin_right(_s[i], XPAD); - #endif - gtk_widget_set_margin_top(_s[i], YPAD); - gtk_widget_set_margin_bottom(_s[i], YPAD); - gtk_widget_set_hexpand(_s[i], TRUE); - gtk_grid_attach(GTK_GRID(t), _s[i], 1, i, 1, 1); -#else - gtk_table_attach (GTK_TABLE (t), _s[i], 1, 2, i, i + 1, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), GTK_FILL, XPAD, YPAD); -#endif - - /* Spinbutton */ - _b[i] = gtk_spin_button_new (GTK_ADJUSTMENT (_a[i]), 1.0, 0); - sp_dialog_defocus_on_enter (_b[i]); - gtk_label_set_mnemonic_widget (GTK_LABEL(_l[i]), _b[i]); - gtk_widget_show (_b[i]); - -#if GTK_CHECK_VERSION(3,0,0) - #if GTK_CHECK_VERSION(3,12,0) - gtk_widget_set_margin_start(_b[i], XPAD); - gtk_widget_set_margin_end(_b[i], XPAD); - #else - gtk_widget_set_margin_left(_b[i], XPAD); - gtk_widget_set_margin_right(_b[i], XPAD); - #endif - gtk_widget_set_margin_top(_b[i], YPAD); - gtk_widget_set_margin_bottom(_b[i], YPAD); - gtk_widget_set_halign(_b[i], GTK_ALIGN_CENTER); - gtk_widget_set_valign(_b[i], GTK_ALIGN_CENTER); - gtk_grid_attach(GTK_GRID(t), _b[i], 2, i, 1, 1); -#else - gtk_table_attach (GTK_TABLE (t), _b[i], 2, 3, i, i + 1, (GtkAttachOptions)0, (GtkAttachOptions)0, XPAD, YPAD); -#endif - - /* Attach channel value to adjustment */ - g_object_set_data (G_OBJECT (_a[i]), "channel", GINT_TO_POINTER (i)); - /* Signals */ - g_signal_connect (G_OBJECT (_a[i]), "value_changed", - G_CALLBACK (_adjustmentAnyChanged), _csel); - g_signal_connect (G_OBJECT (_s[i]), "grabbed", - G_CALLBACK (_sliderAnyGrabbed), _csel); - g_signal_connect (G_OBJECT (_s[i]), "released", - G_CALLBACK (_sliderAnyReleased), _csel); - g_signal_connect (G_OBJECT (_s[i]), "changed", - G_CALLBACK (_sliderAnyChanged), _csel); - } - - /* Initial mode is none, so it works */ - setMode(SP_COLOR_SCALES_MODE_RGB); -} - -static void sp_color_scales_dispose(GObject *object) -{ - if (G_OBJECT_CLASS(sp_color_scales_parent_class)->dispose) - G_OBJECT_CLASS(sp_color_scales_parent_class)->dispose(object); -} - -static void -sp_color_scales_show_all (GtkWidget *widget) -{ - gtk_widget_show (widget); -} - -static void sp_color_scales_hide(GtkWidget *widget) -{ - gtk_widget_hide(widget); -} - -GtkWidget *sp_color_scales_new() -{ - SPColorScales *csel = SP_COLOR_SCALES(g_object_new (SP_TYPE_COLOR_SCALES, NULL)); - - return GTK_WIDGET (csel); -} - -void ColorScales::_recalcColor( gboolean changing ) -{ - if ( changing ) - { - SPColor color; - gfloat alpha = 1.0; - gfloat c[5]; - - switch (_mode) { - case SP_COLOR_SCALES_MODE_RGB: - case SP_COLOR_SCALES_MODE_HSV: - _getRgbaFloatv(c); - color.set( c[0], c[1], c[2] ); - alpha = c[3]; - break; - case SP_COLOR_SCALES_MODE_CMYK: - { - _getCmykaFloatv( c ); - - float rgb[3]; - sp_color_cmyk_to_rgb_floatv( rgb, c[0], c[1], c[2], c[3] ); - color.set( rgb[0], rgb[1], rgb[2] ); - alpha = c[4]; - break; - } - default: - g_warning ("file %s: line %d: Illegal color selector mode %d", __FILE__, __LINE__, _mode); - break; - } - - /* Preserve ICC */ - color.icc = _color.icc ? new SVGICCColor(*_color.icc) : 0; - - _updateInternals( color, alpha, _dragging ); - } - else - { - _updateInternals( _color, _alpha, _dragging ); - } -} - -/* Helpers for setting color value */ -gfloat ColorScales::getScaled( const GtkAdjustment *a ) -{ - gfloat val = gtk_adjustment_get_value (const_cast<GtkAdjustment*>(a)) - / gtk_adjustment_get_upper (const_cast<GtkAdjustment*>(a)); - return val; -} - -void ColorScales::setScaled( GtkAdjustment *a, gfloat v ) -{ - gfloat val = v * gtk_adjustment_get_upper (a); - gtk_adjustment_set_value( a, val ); -} - -void ColorScales::_setRangeLimit( gdouble upper ) -{ - _rangeLimit = upper; - for ( gint i = 0; i < static_cast<gint>(G_N_ELEMENTS(_a)); i++ ) { - gtk_adjustment_set_upper (_a[i], upper); - gtk_adjustment_changed( _a[i] ); - } -} - -void ColorScales::_colorChanged() -{ -#ifdef DUMP_CHANGE_INFO - g_message("ColorScales::_colorChanged( this=%p, %f, %f, %f, %f)", this, _color.v.c[0], _color.v.c[1], _color.v.c[2], _alpha ); -#endif - gfloat tmp[3]; - gfloat c[5] = {0.0, 0.0, 0.0, 0.0}; - - switch (_mode) { - case SP_COLOR_SCALES_MODE_RGB: - sp_color_get_rgb_floatv( &_color, c ); - c[3] = _alpha; - c[4] = 0.0; - break; - case SP_COLOR_SCALES_MODE_HSV: - sp_color_get_rgb_floatv( &_color, tmp ); - sp_color_rgb_to_hsl_floatv (c, tmp[0], tmp[1], tmp[2]); - c[3] = _alpha; - c[4] = 0.0; - break; - case SP_COLOR_SCALES_MODE_CMYK: - sp_color_get_cmyk_floatv( &_color, c ); - c[4] = _alpha; - break; - default: - g_warning ("file %s: line %d: Illegal color selector mode %d", __FILE__, __LINE__, _mode); - break; - } - - _updating = TRUE; - setScaled( _a[0], c[0] ); - setScaled( _a[1], c[1] ); - setScaled( _a[2], c[2] ); - setScaled( _a[3], c[3] ); - setScaled( _a[4], c[4] ); - _updateSliders( CSC_CHANNELS_ALL ); - _updating = FALSE; -} - -void ColorScales::_getRgbaFloatv( gfloat *rgba ) -{ - g_return_if_fail (rgba != NULL); - - switch (_mode) { - case SP_COLOR_SCALES_MODE_RGB: - rgba[0] = getScaled(_a[0]); - rgba[1] = getScaled(_a[1]); - rgba[2] = getScaled(_a[2]); - rgba[3] = getScaled(_a[3]); - break; - case SP_COLOR_SCALES_MODE_HSV: - sp_color_hsl_to_rgb_floatv (rgba, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2])); - rgba[3] = getScaled(_a[3]); - break; - case SP_COLOR_SCALES_MODE_CMYK: - sp_color_cmyk_to_rgb_floatv (rgba, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), getScaled(_a[3])); - rgba[3] = getScaled(_a[4]); - break; - default: - g_warning ("file %s: line %d: Illegal color selector mode", __FILE__, __LINE__); - break; - } -} - -void ColorScales::_getCmykaFloatv( gfloat *cmyka ) -{ - gfloat rgb[3]; - - g_return_if_fail (cmyka != NULL); - - switch (_mode) { - case SP_COLOR_SCALES_MODE_RGB: - sp_color_rgb_to_cmyk_floatv (cmyka, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2])); - cmyka[4] = getScaled(_a[3]); - break; - case SP_COLOR_SCALES_MODE_HSV: - sp_color_hsl_to_rgb_floatv (rgb, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2])); - sp_color_rgb_to_cmyk_floatv (cmyka, rgb[0], rgb[1], rgb[2]); - cmyka[4] = getScaled(_a[3]); - break; - case SP_COLOR_SCALES_MODE_CMYK: - cmyka[0] = getScaled(_a[0]); - cmyka[1] = getScaled(_a[1]); - cmyka[2] = getScaled(_a[2]); - cmyka[3] = getScaled(_a[3]); - cmyka[4] = getScaled(_a[4]); - break; - default: - g_warning ("file %s: line %d: Illegal color selector mode", __FILE__, __LINE__); - break; - } -} - -guint32 ColorScales::_getRgba32() -{ - gfloat c[4]; - guint32 rgba; - - _getRgbaFloatv(c); - - rgba = SP_RGBA32_F_COMPOSE (c[0], c[1], c[2], c[3]); - - return rgba; -} - -void ColorScales::setMode(SPColorScalesMode mode) -{ - gfloat rgba[4]; - gfloat c[4]; - - if (_mode == mode) return; - - if ((_mode == SP_COLOR_SCALES_MODE_RGB) || - (_mode == SP_COLOR_SCALES_MODE_HSV) || - (_mode == SP_COLOR_SCALES_MODE_CMYK)) { - _getRgbaFloatv(rgba); - } else { - rgba[0] = rgba[1] = rgba[2] = rgba[3] = 1.0; - } - - _mode = mode; - - switch (mode) { - case SP_COLOR_SCALES_MODE_RGB: - _setRangeLimit(255.0); - gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[0]), _("_R:")); - gtk_widget_set_tooltip_text (_s[0], _("Red")); - gtk_widget_set_tooltip_text (_b[0], _("Red")); - gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[1]), _("_G:")); - gtk_widget_set_tooltip_text (_s[1], _("Green")); - gtk_widget_set_tooltip_text (_b[1], _("Green")); - gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[2]), _("_B:")); - gtk_widget_set_tooltip_text (_s[2], _("Blue")); - gtk_widget_set_tooltip_text (_b[2], _("Blue")); - gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[3]), _("_A:")); - gtk_widget_set_tooltip_text (_s[3], _("Alpha (opacity)")); - gtk_widget_set_tooltip_text (_b[3], _("Alpha (opacity)")); - sp_color_slider_set_map (SP_COLOR_SLIDER (_s[0]), NULL); - gtk_widget_hide (_l[4]); - gtk_widget_hide (_s[4]); - gtk_widget_hide (_b[4]); - _updating = TRUE; - setScaled( _a[0], rgba[0] ); - setScaled( _a[1], rgba[1] ); - setScaled( _a[2], rgba[2] ); - setScaled( _a[3], rgba[3] ); - _updating = FALSE; - _updateSliders( CSC_CHANNELS_ALL ); - break; - case SP_COLOR_SCALES_MODE_HSV: - _setRangeLimit(255.0); - gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[0]), _("_H:")); - gtk_widget_set_tooltip_text (_s[0], _("Hue")); - gtk_widget_set_tooltip_text (_b[0], _("Hue")); - gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[1]), _("_S:")); - gtk_widget_set_tooltip_text (_s[1], _("Saturation")); - gtk_widget_set_tooltip_text (_b[1], _("Saturation")); - gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[2]), _("_L:")); - gtk_widget_set_tooltip_text (_s[2], _("Lightness")); - gtk_widget_set_tooltip_text (_b[2], _("Lightness")); - gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[3]), _("_A:")); - gtk_widget_set_tooltip_text (_s[3], _("Alpha (opacity)")); - gtk_widget_set_tooltip_text (_b[3], _("Alpha (opacity)")); - sp_color_slider_set_map (SP_COLOR_SLIDER (_s[0]), (guchar *)(sp_color_scales_hue_map())); - gtk_widget_hide (_l[4]); - gtk_widget_hide (_s[4]); - gtk_widget_hide (_b[4]); - _updating = TRUE; - c[0] = 0.0; - sp_color_rgb_to_hsl_floatv (c, rgba[0], rgba[1], rgba[2]); - setScaled( _a[0], c[0] ); - setScaled( _a[1], c[1] ); - setScaled( _a[2], c[2] ); - setScaled( _a[3], rgba[3] ); - _updating = FALSE; - _updateSliders( CSC_CHANNELS_ALL ); - break; - case SP_COLOR_SCALES_MODE_CMYK: - _setRangeLimit(100.0); - gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[0]), _("_C:")); - gtk_widget_set_tooltip_text (_s[0], _("Cyan")); - gtk_widget_set_tooltip_text (_b[0], _("Cyan")); - gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[1]), _("_M:")); - gtk_widget_set_tooltip_text (_s[1], _("Magenta")); - gtk_widget_set_tooltip_text (_b[1], _("Magenta")); - gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[2]), _("_Y:")); - gtk_widget_set_tooltip_text (_s[2], _("Yellow")); - gtk_widget_set_tooltip_text (_b[2], _("Yellow")); - gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[3]), _("_K:")); - gtk_widget_set_tooltip_text (_s[3], _("Black")); - gtk_widget_set_tooltip_text (_b[3], _("Black")); - gtk_label_set_markup_with_mnemonic (GTK_LABEL (_l[4]), _("_A:")); - gtk_widget_set_tooltip_text (_s[4], _("Alpha (opacity)")); - gtk_widget_set_tooltip_text (_b[4], _("Alpha (opacity)")); - sp_color_slider_set_map (SP_COLOR_SLIDER (_s[0]), NULL); - gtk_widget_show (_l[4]); - gtk_widget_show (_s[4]); - gtk_widget_show (_b[4]); - _updating = TRUE; - - sp_color_rgb_to_cmyk_floatv (c, rgba[0], rgba[1], rgba[2]); - setScaled( _a[0], c[0] ); - setScaled( _a[1], c[1] ); - setScaled( _a[2], c[2] ); - setScaled( _a[3], c[3] ); - - setScaled( _a[4], rgba[3] ); - _updating = FALSE; - _updateSliders( CSC_CHANNELS_ALL ); - break; - default: - g_warning ("file %s: line %d: Illegal color selector mode", __FILE__, __LINE__); - break; - } -} - -SPColorScalesMode ColorScales::getMode() const -{ - return _mode; -} - -void ColorScales::setSubmode( guint submode ) -{ - g_return_if_fail (_csel != NULL); - g_return_if_fail (SP_IS_COLOR_SCALES (_csel)); - g_return_if_fail (submode < 3); - - switch ( submode ) - { - default: - case 0: - setMode(SP_COLOR_SCALES_MODE_RGB); - break; - case 1: - setMode(SP_COLOR_SCALES_MODE_HSV); - break; - case 2: - setMode(SP_COLOR_SCALES_MODE_CMYK); - break; - } -} - -guint ColorScales::getSubmode() const -{ - guint submode = 0; - - switch ( _mode ) - { - case SP_COLOR_SCALES_MODE_HSV: - submode = 1; - break; - case SP_COLOR_SCALES_MODE_CMYK: - submode = 2; - break; - case SP_COLOR_SCALES_MODE_RGB: - default: - submode = 0; - } - - return submode; -} - -void ColorScales::_adjustmentAnyChanged( GtkAdjustment *adjustment, SPColorScales *cs ) -{ - gint channel = GPOINTER_TO_INT (g_object_get_data(G_OBJECT (adjustment), "channel")); - - _adjustmentChanged(cs, channel); -} - -void ColorScales::_sliderAnyGrabbed( SPColorSlider *slider, SPColorScales *cs ) -{ - (void)slider; - ColorScales* scales = static_cast<ColorScales*>(SP_COLOR_SELECTOR(cs)->base); - if (!scales->_dragging) { - scales->_dragging = TRUE; - scales->_grabbed(); - scales->_recalcColor( FALSE ); - } -} - -void ColorScales::_sliderAnyReleased( SPColorSlider *slider, SPColorScales *cs ) -{ - (void)slider; - ColorScales* scales = static_cast<ColorScales*>(SP_COLOR_SELECTOR(cs)->base); - if (scales->_dragging) { - scales->_dragging = FALSE; - scales->_released(); - scales->_recalcColor( FALSE ); - } -} - -void ColorScales::_sliderAnyChanged( SPColorSlider *slider, SPColorScales *cs ) -{ - (void)slider; - ColorScales* scales = static_cast<ColorScales*>(SP_COLOR_SELECTOR(cs)->base); - - scales->_recalcColor( TRUE ); -} - -void ColorScales::_adjustmentChanged( SPColorScales *cs, guint channel ) -{ - ColorScales* scales = static_cast<ColorScales*>(SP_COLOR_SELECTOR(cs)->base); - if (scales->_updating) return; - - scales->_updating = TRUE; - - scales->_updateSliders( (1 << channel) ); - - scales->_recalcColor (TRUE); - - scales->_updating = FALSE; -} - -void ColorScales::_updateSliders( guint channels ) -{ - gfloat rgb0[3], rgbm[3], rgb1[3]; -#ifdef SPCS_PREVIEW - guint32 rgba; -#endif - switch (_mode) { - case SP_COLOR_SCALES_MODE_RGB: - if ((channels != CSC_CHANNEL_R) && (channels != CSC_CHANNEL_A)) { - /* Update red */ - sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[0]), - SP_RGBA32_F_COMPOSE (0.0, getScaled(_a[1]), getScaled(_a[2]), 1.0), - SP_RGBA32_F_COMPOSE (0.5, getScaled(_a[1]), getScaled(_a[2]), 1.0), - SP_RGBA32_F_COMPOSE (1.0, getScaled(_a[1]), getScaled(_a[2]), 1.0)); - } - if ((channels != CSC_CHANNEL_G) && (channels != CSC_CHANNEL_A)) { - /* Update green */ - sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[1]), - SP_RGBA32_F_COMPOSE (getScaled(_a[0]), 0.0, getScaled(_a[2]), 1.0), - SP_RGBA32_F_COMPOSE (getScaled(_a[0]), 0.5, getScaled(_a[2]), 1.0), - SP_RGBA32_F_COMPOSE (getScaled(_a[0]), 1.0, getScaled(_a[2]), 1.0)); - } - if ((channels != CSC_CHANNEL_B) && (channels != CSC_CHANNEL_A)) { - /* Update blue */ - sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[2]), - SP_RGBA32_F_COMPOSE (getScaled(_a[0]), getScaled(_a[1]), 0.0, 1.0), - SP_RGBA32_F_COMPOSE (getScaled(_a[0]), getScaled(_a[1]), 0.5, 1.0), - SP_RGBA32_F_COMPOSE (getScaled(_a[0]), getScaled(_a[1]), 1.0, 1.0)); - } - if (channels != CSC_CHANNEL_A) { - /* Update alpha */ - sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[3]), - SP_RGBA32_F_COMPOSE (getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), 0.0), - SP_RGBA32_F_COMPOSE (getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), 0.5), - SP_RGBA32_F_COMPOSE (getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), 1.0)); - } - break; - case SP_COLOR_SCALES_MODE_HSV: - /* Hue is never updated */ - if ((channels != CSC_CHANNEL_S) && (channels != CSC_CHANNEL_A)) { - /* Update saturation */ - sp_color_hsl_to_rgb_floatv (rgb0, getScaled(_a[0]), 0.0, getScaled(_a[2])); - sp_color_hsl_to_rgb_floatv (rgbm, getScaled(_a[0]), 0.5, getScaled(_a[2])); - sp_color_hsl_to_rgb_floatv (rgb1, getScaled(_a[0]), 1.0, getScaled(_a[2])); - sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[1]), - SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 1.0), - SP_RGBA32_F_COMPOSE (rgbm[0], rgbm[1], rgbm[2], 1.0), - SP_RGBA32_F_COMPOSE (rgb1[0], rgb1[1], rgb1[2], 1.0)); - } - if ((channels != CSC_CHANNEL_V) && (channels != CSC_CHANNEL_A)) { - /* Update value */ - sp_color_hsl_to_rgb_floatv (rgb0, getScaled(_a[0]), getScaled(_a[1]), 0.0); - sp_color_hsl_to_rgb_floatv (rgbm, getScaled(_a[0]), getScaled(_a[1]), 0.5); - sp_color_hsl_to_rgb_floatv (rgb1, getScaled(_a[0]), getScaled(_a[1]), 1.0); - sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[2]), - SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 1.0), - SP_RGBA32_F_COMPOSE (rgbm[0], rgbm[1], rgbm[2], 1.0), - SP_RGBA32_F_COMPOSE (rgb1[0], rgb1[1], rgb1[2], 1.0)); - } - if (channels != CSC_CHANNEL_A) { - /* Update alpha */ - sp_color_hsl_to_rgb_floatv (rgb0, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2])); - sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[3]), - SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 0.0), - SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 0.5), - SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 1.0)); - } - break; - case SP_COLOR_SCALES_MODE_CMYK: - if ((channels != CSC_CHANNEL_C) && (channels != CSC_CHANNEL_CMYKA)) { - /* Update C */ - sp_color_cmyk_to_rgb_floatv (rgb0, 0.0, getScaled(_a[1]), getScaled(_a[2]), getScaled(_a[3])); - sp_color_cmyk_to_rgb_floatv (rgbm, 0.5, getScaled(_a[1]), getScaled(_a[2]), getScaled(_a[3])); - sp_color_cmyk_to_rgb_floatv (rgb1, 1.0, getScaled(_a[1]), getScaled(_a[2]), getScaled(_a[3])); - sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[0]), - SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 1.0), - SP_RGBA32_F_COMPOSE (rgbm[0], rgbm[1], rgbm[2], 1.0), - SP_RGBA32_F_COMPOSE (rgb1[0], rgb1[1], rgb1[2], 1.0)); - } - if ((channels != CSC_CHANNEL_M) && (channels != CSC_CHANNEL_CMYKA)) { - /* Update M */ - sp_color_cmyk_to_rgb_floatv (rgb0, getScaled(_a[0]), 0.0, getScaled(_a[2]), getScaled(_a[3])); - sp_color_cmyk_to_rgb_floatv (rgbm, getScaled(_a[0]), 0.5, getScaled(_a[2]), getScaled(_a[3])); - sp_color_cmyk_to_rgb_floatv (rgb1, getScaled(_a[0]), 1.0, getScaled(_a[2]), getScaled(_a[3])); - sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[1]), - SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 1.0), - SP_RGBA32_F_COMPOSE (rgbm[0], rgbm[1], rgbm[2], 1.0), - SP_RGBA32_F_COMPOSE (rgb1[0], rgb1[1], rgb1[2], 1.0)); - } - if ((channels != CSC_CHANNEL_Y) && (channels != CSC_CHANNEL_CMYKA)) { - /* Update Y */ - sp_color_cmyk_to_rgb_floatv (rgb0, getScaled(_a[0]), getScaled(_a[1]), 0.0, getScaled(_a[3])); - sp_color_cmyk_to_rgb_floatv (rgbm, getScaled(_a[0]), getScaled(_a[1]), 0.5, getScaled(_a[3])); - sp_color_cmyk_to_rgb_floatv (rgb1, getScaled(_a[0]), getScaled(_a[1]), 1.0, getScaled(_a[3])); - sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[2]), - SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 1.0), - SP_RGBA32_F_COMPOSE (rgbm[0], rgbm[1], rgbm[2], 1.0), - SP_RGBA32_F_COMPOSE (rgb1[0], rgb1[1], rgb1[2], 1.0)); - } - if ((channels != CSC_CHANNEL_K) && (channels != CSC_CHANNEL_CMYKA)) { - /* Update K */ - sp_color_cmyk_to_rgb_floatv (rgb0, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), 0.0); - sp_color_cmyk_to_rgb_floatv (rgbm, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), 0.5); - sp_color_cmyk_to_rgb_floatv (rgb1, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), 1.0); - sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[3]), - SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 1.0), - SP_RGBA32_F_COMPOSE (rgbm[0], rgbm[1], rgbm[2], 1.0), - SP_RGBA32_F_COMPOSE (rgb1[0], rgb1[1], rgb1[2], 1.0)); - } - if (channels != CSC_CHANNEL_CMYKA) { - /* Update alpha */ - sp_color_cmyk_to_rgb_floatv (rgb0, getScaled(_a[0]), getScaled(_a[1]), getScaled(_a[2]), getScaled(_a[3])); - sp_color_slider_set_colors (SP_COLOR_SLIDER (_s[4]), - SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 0.0), - SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 0.5), - SP_RGBA32_F_COMPOSE (rgb0[0], rgb0[1], rgb0[2], 1.0)); - } - break; - default: - g_warning ("file %s: line %d: Illegal color selector mode", __FILE__, __LINE__); - break; - } - - // Force the internal color to be updated - if ( !_updating ) - { - _recalcColor( TRUE ); - } - -#ifdef SPCS_PREVIEW - rgba = sp_color_scales_get_rgba32 (cs); - sp_color_preview_set_rgba32 (SP_COLOR_PREVIEW (_p), rgba); -#endif -} - -static const gchar * -sp_color_scales_hue_map (void) -{ - static gchar *map = NULL; - - if (!map) { - gchar *p; - gint h; - map = g_new (gchar, 4 * 1024); - p = map; - for (h = 0; h < 1024; h++) { - gfloat rgb[3]; - sp_color_hsl_to_rgb_floatv (rgb, h / 1024.0, 1.0, 0.5); - *p++ = SP_COLOR_F_TO_U (rgb[0]); - *p++ = SP_COLOR_F_TO_U (rgb[1]); - *p++ = SP_COLOR_F_TO_U (rgb[2]); - *p++ = 255; - } - } - - return map; -} - - diff --git a/src/widgets/sp-color-scales.h b/src/widgets/sp-color-scales.h deleted file mode 100644 index 72cbafa2f..000000000 --- a/src/widgets/sp-color-scales.h +++ /dev/null @@ -1,102 +0,0 @@ -#ifndef SEEN_SP_COLOR_SCALES_H -#define SEEN_SP_COLOR_SCALES_H - -#include <glib.h> - -#include <widgets/sp-color-selector.h> - -struct SPColorScales; -struct SPColorScalesClass; -struct SPColorSlider; - -typedef enum { - SP_COLOR_SCALES_MODE_NONE = 0, - SP_COLOR_SCALES_MODE_RGB = 1, - SP_COLOR_SCALES_MODE_HSV = 2, - SP_COLOR_SCALES_MODE_CMYK = 3 -} SPColorScalesMode; - - - -class ColorScales: public ColorSelector -{ -public: - static gfloat getScaled( const GtkAdjustment *a ); - static void setScaled( GtkAdjustment *a, gfloat v); - - ColorScales(SPColorSelector *csel); - virtual ~ColorScales(); - - virtual void init(); - - virtual void setSubmode(guint submode); - virtual guint getSubmode() const; - - void setMode(SPColorScalesMode mode); - SPColorScalesMode getMode() const; - - -protected: - virtual void _colorChanged(); - - static void _adjustmentAnyChanged(GtkAdjustment *adjustment, SPColorScales *cs); - static void _sliderAnyGrabbed(SPColorSlider *slider, SPColorScales *cs); - static void _sliderAnyReleased(SPColorSlider *slider, SPColorScales *cs); - static void _sliderAnyChanged(SPColorSlider *slider, SPColorScales *cs); - static void _adjustmentChanged(SPColorScales *cs, guint channel); - - void _getRgbaFloatv(gfloat *rgba); - void _getCmykaFloatv(gfloat *cmyka); - guint32 _getRgba32(); - void _updateSliders(guint channels); - void _recalcColor(gboolean changing); - - void _setRangeLimit( gdouble upper ); - - SPColorScalesMode _mode; - gdouble _rangeLimit; - gboolean _updating : 1; - gboolean _dragging : 1; - GtkAdjustment *_a[5]; /* Channel adjustments */ - GtkWidget *_s[5]; /* Channel sliders */ - GtkWidget *_b[5]; /* Spinbuttons */ - GtkWidget *_l[5]; /* Labels */ - -private: - // By default, disallow copy constructor and assignment operator - ColorScales(ColorScales const &obj); - ColorScales &operator=(ColorScales const &obj ); -}; - - - -#define SP_TYPE_COLOR_SCALES (sp_color_scales_get_type()) -#define SP_COLOR_SCALES(o) (G_TYPE_CHECK_INSTANCE_CAST((o), SP_TYPE_COLOR_SCALES, SPColorScales)) -#define SP_COLOR_SCALES_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), SP_TYPE_COLOR_SCALES, SPColorScalesClass)) -#define SP_IS_COLOR_SCALES(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), SP_TYPE_COLOR_SCALES)) -#define SP_IS_COLOR_SCALES_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), SP_TYPE_COLOR_SCALES)) - -struct SPColorScales { - SPColorSelector parent; -}; - -struct SPColorScalesClass { - SPColorSelectorClass parent_class; -}; - -GType sp_color_scales_get_type(); - -GtkWidget *sp_color_scales_new(); - -#endif /* !SEEN_SP_COLOR_SCALES_H */ - -/* - 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 : diff --git a/src/widgets/sp-color-selector.cpp b/src/widgets/sp-color-selector.cpp index e97c36431..dad0a18b0 100644 --- a/src/widgets/sp-color-selector.cpp +++ b/src/widgets/sp-color-selector.cpp @@ -6,6 +6,11 @@ #ifdef HAVE_CONFIG_H # include "config.h" #endif + +#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H +#include <glibmm/threads.h> +#endif + #include <math.h> #include <gtk/gtk.h> #include <glibmm/i18n.h> @@ -289,7 +294,7 @@ void ColorSelector::_updateInternals( const SPColor& color, gfloat alpha, gboole (_held ? "CHANGED" : "DRAGGED" ), color.toRGBA32( alpha ), (color.icc?color.icc->colorProfile.c_str():"<null>"), FOO_NAME(_csel)); #endif - g_signal_emit(G_OBJECT(_csel), csel_signals[_held ? CHANGED : DRAGGED], 0); + g_signal_emit(G_OBJECT(_csel), csel_signals[_held ? DRAGGED : CHANGED], 0); } } diff --git a/src/widgets/sp-color-selector.h b/src/widgets/sp-color-selector.h index 30061774a..308a5519c 100644 --- a/src/widgets/sp-color-selector.h +++ b/src/widgets/sp-color-selector.h @@ -1,6 +1,14 @@ #ifndef SEEN_SP_COLOR_SELECTOR_H #define SEEN_SP_COLOR_SELECTOR_H +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H +#include <glibmm/threads.h> +#endif + #include <gtk/gtk.h> #include "color.h" diff --git a/src/widgets/sp-color-slider.cpp b/src/widgets/sp-color-slider.cpp deleted file mode 100644 index ab7e2cd84..000000000 --- a/src/widgets/sp-color-slider.cpp +++ /dev/null @@ -1,749 +0,0 @@ -/* - * A slider with colored background - * - * Author: - * Lauris Kaplinski <lauris@kaplinski.com> - * bulia byak <buliabyak@users.sf.net> - * - * Copyright (C) 2001-2002 Lauris Kaplinski - * - * This code is in public domain - */ - -#include <gtk/gtk.h> -#include "sp-color-scales.h" -#include "sp-color-slider.h" -#include "preferences.h" - -#define SLIDER_WIDTH 96 -#define SLIDER_HEIGHT 8 -#define ARROW_SIZE 7 - -enum { - GRABBED, - DRAGGED, - RELEASED, - CHANGED, - LAST_SIGNAL -}; - -static void sp_color_slider_dispose(GObject *object); - -static void sp_color_slider_realize (GtkWidget *widget); -static void sp_color_slider_size_request (GtkWidget *widget, GtkRequisition *requisition); - -#if GTK_CHECK_VERSION(3,0,0) -static void sp_color_slider_get_preferred_width(GtkWidget *widget, - gint *minimal_width, - gint *natural_width); - -static void sp_color_slider_get_preferred_height(GtkWidget *widget, - gint *minimal_height, - gint *natural_height); -#else -static gboolean sp_color_slider_expose(GtkWidget *widget, GdkEventExpose *event); -#endif - -static void sp_color_slider_size_allocate (GtkWidget *widget, GtkAllocation *allocation); - -static gboolean sp_color_slider_draw(GtkWidget *widget, cairo_t *cr); - -static gint sp_color_slider_button_press (GtkWidget *widget, GdkEventButton *event); -static gint sp_color_slider_button_release (GtkWidget *widget, GdkEventButton *event); -static gint sp_color_slider_motion_notify (GtkWidget *widget, GdkEventMotion *event); - -static void sp_color_slider_adjustment_changed (GtkAdjustment *adjustment, SPColorSlider *slider); -static void sp_color_slider_adjustment_value_changed (GtkAdjustment *adjustment, SPColorSlider *slider); - -static const guchar *sp_color_slider_render_gradient (gint x0, gint y0, gint width, gint height, - gint c[], gint dc[], guint b0, guint b1, guint mask); -static const guchar *sp_color_slider_render_map (gint x0, gint y0, gint width, gint height, - guchar *map, gint start, gint step, guint b0, guint b1, guint mask); - -static guint slider_signals[LAST_SIGNAL] = {0}; - -G_DEFINE_TYPE(SPColorSlider, sp_color_slider, GTK_TYPE_WIDGET); - -static void sp_color_slider_class_init(SPColorSliderClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS(klass); - GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass); - - slider_signals[GRABBED] = g_signal_new ("grabbed", - G_TYPE_FROM_CLASS(object_class), - (GSignalFlags)(G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE), - G_STRUCT_OFFSET (SPColorSliderClass, grabbed), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - slider_signals[DRAGGED] = g_signal_new ("dragged", - G_TYPE_FROM_CLASS(object_class), - (GSignalFlags)(G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE), - G_STRUCT_OFFSET (SPColorSliderClass, dragged), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - slider_signals[RELEASED] = g_signal_new ("released", - G_TYPE_FROM_CLASS(object_class), - (GSignalFlags)(G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE), - G_STRUCT_OFFSET (SPColorSliderClass, released), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - slider_signals[CHANGED] = g_signal_new ("changed", - G_TYPE_FROM_CLASS(object_class), - (GSignalFlags)(G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE), - G_STRUCT_OFFSET (SPColorSliderClass, changed), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - object_class->dispose = sp_color_slider_dispose; - - widget_class->realize = sp_color_slider_realize; -#if GTK_CHECK_VERSION(3,0,0) - widget_class->get_preferred_width = sp_color_slider_get_preferred_width; - widget_class->get_preferred_height = sp_color_slider_get_preferred_height; - widget_class->draw = sp_color_slider_draw; -#else - widget_class->size_request = sp_color_slider_size_request; - widget_class->expose_event = sp_color_slider_expose; -#endif - widget_class->size_allocate = sp_color_slider_size_allocate; -/* widget_class->draw_focus = sp_color_slider_draw_focus; */ -/* widget_class->draw_default = sp_color_slider_draw_default; */ - - widget_class->button_press_event = sp_color_slider_button_press; - widget_class->button_release_event = sp_color_slider_button_release; - widget_class->motion_notify_event = sp_color_slider_motion_notify; -} - -static void -sp_color_slider_init (SPColorSlider *slider) -{ - /* We are widget with window */ - gtk_widget_set_has_window (GTK_WIDGET(slider), TRUE); - - slider->dragging = FALSE; - - slider->adjustment = NULL; - slider->value = 0.0; - - slider->c0[0] = 0x00; - slider->c0[1] = 0x00; - slider->c0[2] = 0x00; - slider->c0[3] = 0xff; - - slider->cm[0] = 0xff; - slider->cm[1] = 0x00; - slider->cm[2] = 0x00; - slider->cm[3] = 0xff; - - slider->c1[0] = 0xff; - slider->c1[1] = 0xff; - slider->c1[2] = 0xff; - slider->c1[3] = 0xff; - - slider->b0 = 0x5f; - slider->b1 = 0xa0; - slider->bmask = 0x08; - - slider->map = NULL; -} - -static void sp_color_slider_dispose(GObject *object) -{ - SPColorSlider *slider = SP_COLOR_SLIDER (object); - - if (slider->adjustment) { - g_signal_handlers_disconnect_matched (G_OBJECT (slider->adjustment), G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, slider); - g_object_unref (slider->adjustment); - slider->adjustment = NULL; - } - - if (G_OBJECT_CLASS(sp_color_slider_parent_class)->dispose) - G_OBJECT_CLASS(sp_color_slider_parent_class)->dispose (object); -} - -static void -sp_color_slider_realize (GtkWidget *widget) -{ - GdkWindowAttr attributes; - gint attributes_mask; - GtkAllocation allocation; - - gtk_widget_get_allocation(widget, &allocation); - gtk_widget_set_realized (widget, TRUE); - - attributes.window_type = GDK_WINDOW_CHILD; - attributes.x = allocation.x; - attributes.y = allocation.y; - attributes.width = allocation.width; - attributes.height = allocation.height; - attributes.wclass = GDK_INPUT_OUTPUT; - attributes.visual = gdk_screen_get_system_visual(gdk_screen_get_default()); - -#if !GTK_CHECK_VERSION(3,0,0) - attributes.colormap = gdk_screen_get_system_colormap(gdk_screen_get_default()); -#endif - - attributes.event_mask = gtk_widget_get_events (widget); - attributes.event_mask |= (GDK_EXPOSURE_MASK | - GDK_BUTTON_PRESS_MASK | - GDK_BUTTON_RELEASE_MASK | - GDK_POINTER_MOTION_MASK | - GDK_ENTER_NOTIFY_MASK | - GDK_LEAVE_NOTIFY_MASK); -#if GTK_CHECK_VERSION(3,0,0) - attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL; -#else - attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; -#endif - - gtk_widget_set_window(widget, - gdk_window_new(gtk_widget_get_parent_window(widget), - &attributes, attributes_mask)); - - gdk_window_set_user_data(gtk_widget_get_window(widget), widget); - -#if !GTK_CHECK_VERSION(3,0,0) - // This doesn't do anything in GTK+ 3 - gtk_widget_set_style(widget, - gtk_style_attach(gtk_widget_get_style(widget), - gtk_widget_get_window(widget))); -#endif -} - -static void -sp_color_slider_size_request (GtkWidget *widget, GtkRequisition *requisition) -{ - GtkStyle *style = gtk_widget_get_style(widget); - requisition->width = SLIDER_WIDTH + style->xthickness * 2; - requisition->height = SLIDER_HEIGHT + style->ythickness * 2; -} - -#if GTK_CHECK_VERSION(3,0,0) -static void sp_color_slider_get_preferred_width(GtkWidget *widget, gint *minimal_width, gint *natural_width) -{ - GtkRequisition requisition; - sp_color_slider_size_request(widget, &requisition); - *minimal_width = *natural_width = requisition.width; -} - -static void sp_color_slider_get_preferred_height(GtkWidget *widget, gint *minimal_height, gint *natural_height) -{ - GtkRequisition requisition; - sp_color_slider_size_request(widget, &requisition); - *minimal_height = *natural_height = requisition.height; -} -#endif - -static void -sp_color_slider_size_allocate (GtkWidget *widget, GtkAllocation *allocation) -{ - gtk_widget_set_allocation(widget, allocation); - - if (gtk_widget_get_realized (widget)) { - /* Resize GdkWindow */ - gdk_window_move_resize(gtk_widget_get_window(widget), - allocation->x, allocation->y, - allocation->width, allocation->height); - } -} - -#if !GTK_CHECK_VERSION(3,0,0) -static gboolean sp_color_slider_expose(GtkWidget *widget, GdkEventExpose * /*event*/) -{ - gboolean result = FALSE; - - if (gtk_widget_is_drawable(widget)) { - GdkWindow *window = gtk_widget_get_window(widget); - cairo_t *cr = gdk_cairo_create(window); - result = sp_color_slider_draw(widget, cr); - cairo_destroy(cr); - } - - return result; -} -#endif - -static gint -sp_color_slider_button_press (GtkWidget *widget, GdkEventButton *event) -{ - SPColorSlider *slider; - - slider = SP_COLOR_SLIDER (widget); - - if (event->button == 1) { - GtkAllocation allocation; - gtk_widget_get_allocation(widget, &allocation); - gint cx, cw; - cx = gtk_widget_get_style(widget)->xthickness; - cw = allocation.width - 2 * cx; - g_signal_emit (G_OBJECT (slider), slider_signals[GRABBED], 0); - slider->dragging = TRUE; - slider->oldvalue = slider->value; - ColorScales::setScaled( slider->adjustment, CLAMP ((gfloat) (event->x - cx) / cw, 0.0, 1.0) ); - g_signal_emit (G_OBJECT (slider), slider_signals[DRAGGED], 0); - -#if GTK_CHECK_VERSION(3,0,0) - gdk_device_grab(gdk_event_get_device(reinterpret_cast<GdkEvent *>(event)), - gtk_widget_get_window(widget), - GDK_OWNERSHIP_NONE, - FALSE, - static_cast<GdkEventMask>(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK), - NULL, - event->time); -#else - gdk_pointer_grab(gtk_widget_get_window(widget), FALSE, - static_cast<GdkEventMask>(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK), - NULL, NULL, event->time); -#endif - } - - return FALSE; -} - -static gint -sp_color_slider_button_release (GtkWidget *widget, GdkEventButton *event) -{ - SPColorSlider *slider; - - slider = SP_COLOR_SLIDER (widget); - - if (event->button == 1) { - -#if GTK_CHECK_VERSION(3,0,0) - gdk_device_ungrab(gdk_event_get_device(reinterpret_cast<GdkEvent *>(event)), - gdk_event_get_time(reinterpret_cast<GdkEvent *>(event))); -#else - gdk_pointer_ungrab (event->time); -#endif - - slider->dragging = FALSE; - g_signal_emit (G_OBJECT (slider), slider_signals[RELEASED], 0); - if (slider->value != slider->oldvalue) g_signal_emit (G_OBJECT (slider), slider_signals[CHANGED], 0); - } - - return FALSE; -} - -static gint -sp_color_slider_motion_notify (GtkWidget *widget, GdkEventMotion *event) -{ - SPColorSlider *slider; - - slider = SP_COLOR_SLIDER (widget); - - if (slider->dragging) { - gint cx, cw; - GtkAllocation allocation; - gtk_widget_get_allocation(widget, &allocation); - cx = gtk_widget_get_style(widget)->xthickness; - cw = allocation.width - 2 * cx; - ColorScales::setScaled( slider->adjustment, CLAMP ((gfloat) (event->x - cx) / cw, 0.0, 1.0) ); - g_signal_emit (G_OBJECT (slider), slider_signals[DRAGGED], 0); - } - - return FALSE; -} - -GtkWidget *sp_color_slider_new(GtkAdjustment *adjustment) -{ - SPColorSlider *slider = SP_COLOR_SLIDER(g_object_new(SP_TYPE_COLOR_SLIDER, NULL)); - - sp_color_slider_set_adjustment (slider, adjustment); - - return GTK_WIDGET (slider); -} - -void sp_color_slider_set_adjustment(SPColorSlider *slider, GtkAdjustment *adjustment) -{ - g_return_if_fail (slider != NULL); - g_return_if_fail (SP_IS_COLOR_SLIDER (slider)); - - if (!adjustment) { - adjustment = GTK_ADJUSTMENT(gtk_adjustment_new(0.0, 0.0, 1.0, 0.01, 0.0, 0.0)); - } else { - gtk_adjustment_set_page_increment(adjustment, 0.0); - gtk_adjustment_set_page_size(adjustment, 0.0); - } - - if (slider->adjustment != adjustment) { - if (slider->adjustment) { - g_signal_handlers_disconnect_matched (G_OBJECT (slider->adjustment), G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, slider); - g_object_unref (slider->adjustment); - } - - slider->adjustment = adjustment; - g_object_ref (adjustment); - g_object_ref_sink (adjustment); - - g_signal_connect (G_OBJECT (adjustment), "changed", - G_CALLBACK (sp_color_slider_adjustment_changed), slider); - g_signal_connect (G_OBJECT (adjustment), "value_changed", - G_CALLBACK (sp_color_slider_adjustment_value_changed), slider); - - slider->value = ColorScales::getScaled( adjustment ); - - sp_color_slider_adjustment_changed (adjustment, slider); - } -} - -void -sp_color_slider_set_colors (SPColorSlider *slider, guint32 start, guint32 mid, guint32 end) -{ - g_return_if_fail (slider != NULL); - g_return_if_fail (SP_IS_COLOR_SLIDER (slider)); - - // Remove any map, if set - slider->map = 0; - - slider->c0[0] = start >> 24; - slider->c0[1] = (start >> 16) & 0xff; - slider->c0[2] = (start >> 8) & 0xff; - slider->c0[3] = start & 0xff; - - slider->cm[0] = mid >> 24; - slider->cm[1] = (mid >> 16) & 0xff; - slider->cm[2] = (mid >> 8) & 0xff; - slider->cm[3] = mid & 0xff; - - slider->c1[0] = end >> 24; - slider->c1[1] = (end >> 16) & 0xff; - slider->c1[2] = (end >> 8) & 0xff; - slider->c1[3] = end & 0xff; - - gtk_widget_queue_draw (GTK_WIDGET (slider)); -} - -void -sp_color_slider_set_map (SPColorSlider *slider, const guchar *map) -{ - g_return_if_fail (slider != NULL); - g_return_if_fail (SP_IS_COLOR_SLIDER (slider)); - - slider->map = const_cast<guchar *>(map); - - gtk_widget_queue_draw (GTK_WIDGET (slider)); -} - -void -sp_color_slider_set_background (SPColorSlider *slider, guint dark, guint light, guint size) -{ - g_return_if_fail (slider != NULL); - g_return_if_fail (SP_IS_COLOR_SLIDER (slider)); - - slider->b0 = dark; - slider->b1 = light; - slider->bmask = size; - - gtk_widget_queue_draw (GTK_WIDGET (slider)); -} - -static void -sp_color_slider_adjustment_changed (GtkAdjustment */*adjustment*/, SPColorSlider *slider) -{ - gtk_widget_queue_draw (GTK_WIDGET (slider)); -} - -static void -sp_color_slider_adjustment_value_changed (GtkAdjustment *adjustment, SPColorSlider *slider) -{ - GtkWidget *widget; - - widget = GTK_WIDGET (slider); - - if (slider->value != ColorScales::getScaled( adjustment )) { - gint cx, cy, cw, ch; - GtkStyle *style = gtk_widget_get_style(widget); - GtkAllocation allocation; - gtk_widget_get_allocation(widget, &allocation); - cx = style->xthickness; - cy = style->ythickness; - cw = allocation.width - 2 * cx; - ch = allocation.height - 2 * cy; - if ((gint) (ColorScales::getScaled( adjustment ) * cw) != (gint) (slider->value * cw)) { - gint ax, ay; - gfloat value; - value = slider->value; - slider->value = ColorScales::getScaled( adjustment ); - ax = (int)(cx + value * cw - ARROW_SIZE / 2 - 2); - ay = cy; - gtk_widget_queue_draw_area (widget, ax, ay, ARROW_SIZE + 4, ch); - ax = (int)(cx + slider->value * cw - ARROW_SIZE / 2 - 2); - ay = cy; - gtk_widget_queue_draw_area (widget, ax, ay, ARROW_SIZE + 4, ch); - } else { - slider->value = ColorScales::getScaled( adjustment ); - } - } -} - -static gboolean sp_color_slider_draw(GtkWidget *widget, cairo_t *cr) -{ - SPColorSlider *slider = SP_COLOR_SLIDER(widget); - - gboolean colorsOnTop = Inkscape::Preferences::get()->getBool("/options/workarounds/colorsontop", false); - - GtkAllocation allocation; - gtk_widget_get_allocation(widget, &allocation); - -#if GTK_CHECK_VERSION(3,0,0) - GtkStyleContext *context = gtk_widget_get_style_context(widget); -#else - GdkWindow *window = gtk_widget_get_window(widget); - GtkStyle *style = gtk_widget_get_style(widget); -#endif - - // Draw shadow - if (colorsOnTop) { -#if GTK_CHECK_VERSION(3,0,0) - gtk_render_frame(context, - cr, - 0, 0, - allocation.width, allocation.height); -#else - gtk_paint_shadow( style, window, - gtk_widget_get_state(widget), GTK_SHADOW_IN, - NULL, widget, "colorslider", - 0, 0, - allocation.width, allocation.height); -#endif - } - - /* Paintable part of color gradient area */ - GdkRectangle carea; - -#if GTK_CHECK_VERSION(3,0,0) - GtkBorder padding; - - gtk_style_context_get_padding(context, - gtk_widget_get_state_flags(widget), - &padding); - - carea.x = padding.left; - carea.y = padding.top; -#else - carea.x = style->xthickness; - carea.y = style->ythickness; -#endif - - carea.width = allocation.width - 2 * carea.x; - carea.height = allocation.height - 2 * carea.y; - - if (slider->map) { - /* Render map pixelstore */ - gint d = (1024 << 16) / carea.width; - gint s = 0; - - const guchar *b = sp_color_slider_render_map(0, 0, carea.width, carea.height, - slider->map, s, d, - slider->b0, slider->b1, slider->bmask); - - if (b != NULL && carea.width > 0) { - GdkPixbuf *pb = gdk_pixbuf_new_from_data (b, GDK_COLORSPACE_RGB, - 0, 8, carea.width, carea.height, carea.width * 3, NULL, NULL); - - gdk_cairo_set_source_pixbuf(cr, pb, carea.x, carea.y); - cairo_paint(cr); - g_object_unref(pb); - } - - } else { - gint c[4], dc[4]; - - /* Render gradient */ - - // part 1: from c0 to cm - if (carea.width > 0) { - for (gint i = 0; i < 4; i++) { - c[i] = slider->c0[i] << 16; - dc[i] = ((slider->cm[i] << 16) - c[i]) / (carea.width/2); - } - guint wi = carea.width/2; - const guchar *b = sp_color_slider_render_gradient(0, 0, wi, carea.height, - c, dc, slider->b0, slider->b1, slider->bmask); - - /* Draw pixelstore 1 */ - if (b != NULL && wi > 0) { - GdkPixbuf *pb = gdk_pixbuf_new_from_data (b, GDK_COLORSPACE_RGB, - 0, 8, wi, carea.height, wi * 3, NULL, NULL); - - gdk_cairo_set_source_pixbuf(cr, pb, carea.x, carea.y); - cairo_paint(cr); - g_object_unref(pb); - } - } - - // part 2: from cm to c1 - if (carea.width > 0) { - for (gint i = 0; i < 4; i++) { - c[i] = slider->cm[i] << 16; - dc[i] = ((slider->c1[i] << 16) - c[i]) / (carea.width/2); - } - guint wi = carea.width/2; - const guchar *b = sp_color_slider_render_gradient(carea.width/2, 0, wi, carea.height, - c, dc, - slider->b0, slider->b1, slider->bmask); - - /* Draw pixelstore 2 */ - if (b != NULL && wi > 0) { - GdkPixbuf *pb = gdk_pixbuf_new_from_data (b, GDK_COLORSPACE_RGB, - 0, 8, wi, carea.height, wi * 3, NULL, NULL); - - gdk_cairo_set_source_pixbuf(cr, pb, carea.width/2 + carea.x, carea.y); - cairo_paint(cr); - - g_object_unref(pb); - } - } - } - - /* Draw shadow */ - if (!colorsOnTop) { -#if GTK_CHECK_VERSION(3,0,0) - gtk_render_frame(context, - cr, - 0, 0, - allocation.width, allocation.height); -#else - gtk_paint_shadow( style, window, - gtk_widget_get_state(widget), GTK_SHADOW_IN, - NULL, widget, "colorslider", - 0, 0, - allocation.width, allocation.height); -#endif - } - - /* Draw arrow */ - gint x = (int)(slider->value * (carea.width - 1) - ARROW_SIZE / 2 + carea.x); - gint y1 = carea.y; - gint y2 = carea.y + carea.height - 1; - cairo_set_line_width(cr, 1.0); - - // Define top arrow - cairo_move_to(cr, x - 0.5, y1 + 0.5); - cairo_line_to(cr, x + ARROW_SIZE - 0.5, y1 + 0.5); - cairo_line_to(cr, x + (ARROW_SIZE-1)/2.0, y1 + ARROW_SIZE/2.0 + 0.5); - cairo_line_to(cr, x - 0.5, y1 + 0.5); - - // Define bottom arrow - cairo_move_to(cr, x - 0.5, y2 + 0.5); - cairo_line_to(cr, x + ARROW_SIZE - 0.5, y2 + 0.5); - cairo_line_to(cr, x + (ARROW_SIZE-1)/2.0, y2 - ARROW_SIZE/2.0 + 0.5); - cairo_line_to(cr, x - 0.5, y2 + 0.5); - - // Render both arrows - cairo_set_source_rgb(cr, 1.0, 1.0, 1.0); - cairo_stroke_preserve(cr); - cairo_set_source_rgb(cr, 0.0, 0.0, 0.0); - cairo_fill(cr); - - return FALSE; -} - -/* Colors are << 16 */ - -static const guchar * -sp_color_slider_render_gradient (gint x0, gint y0, gint width, gint height, - gint c[], gint dc[], guint b0, guint b1, guint mask) -{ - static guchar *buf = NULL; - static gint bs = 0; - guchar *dp; - gint x, y; - guint r, g, b, a; - - if (buf && (bs < width * height)) { - g_free (buf); - buf = NULL; - } - if (!buf) { - buf = g_new (guchar, width * height * 3); - bs = width * height; - } - - dp = buf; - r = c[0]; - g = c[1]; - b = c[2]; - a = c[3]; - for (x = x0; x < x0 + width; x++) { - gint cr, cg, cb, ca; - guchar *d; - cr = r >> 16; - cg = g >> 16; - cb = b >> 16; - ca = a >> 16; - d = dp; - for (y = y0; y < y0 + height; y++) { - guint bg, fc; - /* Background value */ - bg = ((x & mask) ^ (y & mask)) ? b0 : b1; - fc = (cr - bg) * ca; - d[0] = bg + ((fc + (fc >> 8) + 0x80) >> 8); - fc = (cg - bg) * ca; - d[1] = bg + ((fc + (fc >> 8) + 0x80) >> 8); - fc = (cb - bg) * ca; - d[2] = bg + ((fc + (fc >> 8) + 0x80) >> 8); - d += 3 * width; - } - r += dc[0]; - g += dc[1]; - b += dc[2]; - a += dc[3]; - dp += 3; - } - - return buf; -} - -/* Positions are << 16 */ - -static const guchar * -sp_color_slider_render_map (gint x0, gint y0, gint width, gint height, - guchar *map, gint start, gint step, guint b0, guint b1, guint mask) -{ - static guchar *buf = NULL; - static gint bs = 0; - guchar *dp; - gint x, y; - - if (buf && (bs < width * height)) { - g_free (buf); - buf = NULL; - } - if (!buf) { - buf = g_new (guchar, width * height * 3); - bs = width * height; - } - - dp = buf; - for (x = x0; x < x0 + width; x++) { - gint cr, cg, cb, ca; - guchar *d = dp; - guchar *sp = map + 4 * (start >> 16); - cr = *sp++; - cg = *sp++; - cb = *sp++; - ca = *sp++; - for (y = y0; y < y0 + height; y++) { - guint bg, fc; - /* Background value */ - bg = ((x & mask) ^ (y & mask)) ? b0 : b1; - fc = (cr - bg) * ca; - d[0] = bg + ((fc + (fc >> 8) + 0x80) >> 8); - fc = (cg - bg) * ca; - d[1] = bg + ((fc + (fc >> 8) + 0x80) >> 8); - fc = (cb - bg) * ca; - d[2] = bg + ((fc + (fc >> 8) + 0x80) >> 8); - d += 3 * width; - } - dp += 3; - start += step; - } - - return buf; -} - diff --git a/src/widgets/sp-color-slider.h b/src/widgets/sp-color-slider.h deleted file mode 100644 index b81d62e41..000000000 --- a/src/widgets/sp-color-slider.h +++ /dev/null @@ -1,60 +0,0 @@ -#ifndef __SP_COLOR_SLIDER_H__ -#define __SP_COLOR_SLIDER_H__ - -/* - * A slider with colored background - * - * Author: - * Lauris Kaplinski <lauris@kaplinski.com> - * - * Copyright (C) 2001-2002 Lauris Kaplinski - * - * This code is in public domain - */ - -#include <gtk/gtk.h> - -#define SP_TYPE_COLOR_SLIDER (sp_color_slider_get_type ()) -#define SP_COLOR_SLIDER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SP_TYPE_COLOR_SLIDER, SPColorSlider)) -#define SP_COLOR_SLIDER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), SP_TYPE_COLOR_SLIDER, SPColorSliderClass)) -#define SP_IS_COLOR_SLIDER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SP_TYPE_COLOR_SLIDER)) -#define SP_IS_COLOR_SLIDER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SP_TYPE_COLOR_SLIDER)) - -struct SPColorSlider { - GtkWidget widget; - - guint dragging : 1; - - GtkAdjustment *adjustment; - - gfloat value; - gfloat oldvalue; - guchar c0[4], cm[4], c1[4]; - guchar b0, b1; - guchar bmask; - - gint mapsize; - guchar *map; -}; - -struct SPColorSliderClass { - GtkWidgetClass parent_class; - - void (* grabbed) (SPColorSlider *slider); - void (* dragged) (SPColorSlider *slider); - void (* released) (SPColorSlider *slider); - void (* changed) (SPColorSlider *slider); -}; - -GType sp_color_slider_get_type (void); - -GtkWidget *sp_color_slider_new (GtkAdjustment *adjustment); - -void sp_color_slider_set_adjustment (SPColorSlider *slider, GtkAdjustment *adjustment); -void sp_color_slider_set_colors (SPColorSlider *slider, guint32 start, guint32 mid, guint32 end); -void sp_color_slider_set_map (SPColorSlider *slider, const guchar *map); -void sp_color_slider_set_background (SPColorSlider *slider, guint dark, guint light, guint size); - - - -#endif diff --git a/src/widgets/sp-color-wheel-selector.cpp b/src/widgets/sp-color-wheel-selector.cpp deleted file mode 100644 index 6cfa7c14d..000000000 --- a/src/widgets/sp-color-wheel-selector.cpp +++ /dev/null @@ -1,348 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif -#include <math.h> -#include <gtk/gtk.h> -#include <glibmm/i18n.h> -#include "ui/dialog-events.h" -#include "sp-color-wheel-selector.h" -#include "sp-color-scales.h" -#include "sp-color-slider.h" -#include "sp-color-icc-selector.h" -#include "../svg/svg-icc-color.h" -#include "ui/widget/gimpcolorwheel.h" - -G_BEGIN_DECLS - -static void sp_color_wheel_selector_dispose(GObject *object); - -static void sp_color_wheel_selector_show_all (GtkWidget *widget); -static void sp_color_wheel_selector_hide(GtkWidget *widget); - - -G_END_DECLS - -#define XPAD 4 -#define YPAD 1 - -G_DEFINE_TYPE(SPColorWheelSelector, sp_color_wheel_selector, SP_TYPE_COLOR_SELECTOR); - -static void sp_color_wheel_selector_class_init(SPColorWheelSelectorClass *klass) -{ - static const gchar* nameset[] = {N_("Wheel"), 0}; - GObjectClass *object_class = G_OBJECT_CLASS(klass); - GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass); - SPColorSelectorClass *selector_class = SP_COLOR_SELECTOR_CLASS (klass); - - selector_class->name = nameset; - selector_class->submode_count = 1; - - object_class->dispose = sp_color_wheel_selector_dispose; - - widget_class->show_all = sp_color_wheel_selector_show_all; - widget_class->hide = sp_color_wheel_selector_hide; -} - -ColorWheelSelector::ColorWheelSelector( SPColorSelector* csel ) - : ColorSelector( csel ), - _updating( FALSE ), - _dragging( FALSE ), - _adj(0), - _wheel(0), - _slider(0), - _sbtn(0), - _label(0) -{ -} - -ColorWheelSelector::~ColorWheelSelector() -{ - _adj = 0; - _wheel = 0; - _sbtn = 0; - _label = 0; -} - -void sp_color_wheel_selector_init (SPColorWheelSelector *cs) -{ - SP_COLOR_SELECTOR(cs)->base = new ColorWheelSelector( SP_COLOR_SELECTOR(cs) ); - - if ( SP_COLOR_SELECTOR(cs)->base ) - { - SP_COLOR_SELECTOR(cs)->base->init(); - } -} - -void ColorWheelSelector::init() -{ - gint row = 0; - - _updating = FALSE; - _dragging = FALSE; - -#if GTK_CHECK_VERSION(3,0,0) - GtkWidget *t = gtk_grid_new(); -#else - GtkWidget *t = gtk_table_new (5, 3, FALSE); -#endif - - gtk_widget_show (t); - gtk_box_pack_start (GTK_BOX (_csel), t, TRUE, TRUE, 0); - - /* Create components */ - row = 0; - - _wheel = gimp_color_wheel_new(); - gtk_widget_show( _wheel ); - -#if GTK_CHECK_VERSION(3,0,0) - gtk_widget_set_halign(_wheel, GTK_ALIGN_FILL); - gtk_widget_set_valign(_wheel, GTK_ALIGN_FILL); - gtk_widget_set_hexpand(_wheel, TRUE); - gtk_widget_set_vexpand(_wheel, TRUE); - gtk_grid_attach(GTK_GRID(t), _wheel, 0, row, 3, 1); -#else - gtk_table_attach(GTK_TABLE(t), _wheel, 0, 3, row, row + 1, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), 0, 0); -#endif - - row++; - - /* Label */ - _label = gtk_label_new_with_mnemonic (_("_A:")); - gtk_misc_set_alignment (GTK_MISC (_label), 1.0, 0.5); - gtk_widget_show (_label); - -#if GTK_CHECK_VERSION(3,0,0) - #if GTK_CHECK_VERSION(3,12,0) - gtk_widget_set_margin_start(_label, XPAD); - gtk_widget_set_margin_end(_label, XPAD); - #else - gtk_widget_set_margin_left(_label, XPAD); - gtk_widget_set_margin_right(_label, XPAD); - #endif - gtk_widget_set_margin_top(_label, YPAD); - gtk_widget_set_margin_bottom(_label, YPAD); - gtk_widget_set_halign(_label, GTK_ALIGN_FILL); - gtk_widget_set_valign(_label, GTK_ALIGN_FILL); - gtk_grid_attach(GTK_GRID(t), _label, 0, row, 1, 1); -#else - gtk_table_attach (GTK_TABLE (t), _label, 0, 1, row, row + 1, GTK_FILL, GTK_FILL, XPAD, YPAD); -#endif - - /* Adjustment */ - _adj = GTK_ADJUSTMENT(gtk_adjustment_new(0.0, 0.0, 255.0, 1.0, 10.0, 10.0)); - - /* Slider */ - _slider = sp_color_slider_new (_adj); - gtk_widget_set_tooltip_text (_slider, _("Alpha (opacity)")); - gtk_widget_show (_slider); - -#if GTK_CHECK_VERSION(3,0,0) - #if GTK_CHECK_VERSION(3,12,0) - gtk_widget_set_margin_start(_slider, XPAD); - gtk_widget_set_margin_end(_slider, XPAD); - #else - gtk_widget_set_margin_left(_slider, XPAD); - gtk_widget_set_margin_right(_slider, XPAD); - #endif - gtk_widget_set_margin_top(_slider, YPAD); - gtk_widget_set_margin_bottom(_slider, YPAD); - gtk_widget_set_hexpand(_slider, TRUE); - gtk_widget_set_halign(_slider, GTK_ALIGN_FILL); - gtk_widget_set_valign(_slider, GTK_ALIGN_FILL); - gtk_grid_attach(GTK_GRID(t), _slider, 1, row, 1, 1); -#else - gtk_table_attach(GTK_TABLE (t), _slider, 1, 2, row, row + 1, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), GTK_FILL, XPAD, YPAD); -#endif - - sp_color_slider_set_colors (SP_COLOR_SLIDER (_slider), - SP_RGBA32_F_COMPOSE (1.0, 1.0, 1.0, 0.0), - SP_RGBA32_F_COMPOSE (1.0, 1.0, 1.0, 0.5), - SP_RGBA32_F_COMPOSE (1.0, 1.0, 1.0, 1.0)); - - - /* Spinbutton */ - _sbtn = gtk_spin_button_new (GTK_ADJUSTMENT (_adj), 1.0, 0); - gtk_widget_set_tooltip_text (_sbtn, _("Alpha (opacity)")); - sp_dialog_defocus_on_enter (_sbtn); - gtk_label_set_mnemonic_widget (GTK_LABEL(_label), _sbtn); - gtk_widget_show (_sbtn); - -#if GTK_CHECK_VERSION(3,0,0) - #if GTK_CHECK_VERSION(3,12,0) - gtk_widget_set_margin_start(_sbtn, XPAD); - gtk_widget_set_margin_end(_sbtn, XPAD); - #else - gtk_widget_set_margin_left(_sbtn, XPAD); - gtk_widget_set_margin_right(_sbtn, XPAD); - #endif - gtk_widget_set_margin_top(_sbtn, YPAD); - gtk_widget_set_margin_bottom(_sbtn, YPAD); - gtk_widget_set_halign(_sbtn, GTK_ALIGN_CENTER); - gtk_widget_set_valign(_sbtn, GTK_ALIGN_CENTER); - gtk_grid_attach(GTK_GRID(t), _sbtn, 2, row, 1, 1); -#else - gtk_table_attach (GTK_TABLE (t), _sbtn, 2, 3, row, row + 1, (GtkAttachOptions)0, (GtkAttachOptions)0, XPAD, YPAD); -#endif - - /* Signals */ - g_signal_connect (G_OBJECT (_adj), "value_changed", - G_CALLBACK (_adjustmentChanged), _csel); - - g_signal_connect (G_OBJECT (_slider), "grabbed", - G_CALLBACK (_sliderGrabbed), _csel); - g_signal_connect (G_OBJECT (_slider), "released", - G_CALLBACK (_sliderReleased), _csel); - g_signal_connect (G_OBJECT (_slider), "changed", - G_CALLBACK (_sliderChanged), _csel); - - g_signal_connect( G_OBJECT(_wheel), "changed", - G_CALLBACK (_wheelChanged), _csel ); -} - -static void sp_color_wheel_selector_dispose(GObject *object) -{ - if (G_OBJECT_CLASS(sp_color_wheel_selector_parent_class)->dispose) - G_OBJECT_CLASS(sp_color_wheel_selector_parent_class)->dispose(object); -} - -static void -sp_color_wheel_selector_show_all (GtkWidget *widget) -{ - gtk_widget_show (widget); -} - -static void sp_color_wheel_selector_hide(GtkWidget *widget) -{ - gtk_widget_hide(widget); -} - -GtkWidget *sp_color_wheel_selector_new() -{ - SPColorWheelSelector *csel = SP_COLOR_WHEEL_SELECTOR(g_object_new (SP_TYPE_COLOR_WHEEL_SELECTOR, NULL)); - - return GTK_WIDGET (csel); -} - -/* Helpers for setting color value */ - -static void preserve_icc(SPColor *color, SPColorWheelSelector *cs){ - ColorSelector* selector = static_cast<ColorSelector*>(SP_COLOR_SELECTOR(cs)->base); - color->icc = selector->getColor().icc ? new SVGICCColor(*selector->getColor().icc) : 0; -} - -void ColorWheelSelector::_colorChanged() -{ -#ifdef DUMP_CHANGE_INFO - g_message("ColorWheelSelector::_colorChanged( this=%p, %f, %f, %f, %f)", this, color.v.c[0], color.v.c[1], color.v.c[2], alpha ); -#endif - _updating = TRUE; - { - float hsv[3] = {0,0,0}; - sp_color_rgb_to_hsv_floatv(hsv, _color.v.c[0], _color.v.c[1], _color.v.c[2]); - gimp_color_wheel_set_color( GIMP_COLOR_WHEEL(_wheel), hsv[0], hsv[1], hsv[2] ); - } - - guint32 start = _color.toRGBA32( 0x00 ); - guint32 mid = _color.toRGBA32( 0x7f ); - guint32 end = _color.toRGBA32( 0xff ); - - sp_color_slider_set_colors(SP_COLOR_SLIDER(_slider), start, mid, end); - - ColorScales::setScaled(_adj, _alpha); - - _updating = FALSE; -} - -void ColorWheelSelector::_adjustmentChanged( GtkAdjustment *adjustment, SPColorWheelSelector *cs ) -{ -// TODO check this. It looks questionable: - // if a value is entered between 0 and 1 exclusive, normalize it to (int) 0..255 or 0..100 - gdouble value = gtk_adjustment_get_value (adjustment); - gdouble upper = gtk_adjustment_get_upper (adjustment); - - if (value > 0.0 && value < 1.0) { - gtk_adjustment_set_value( adjustment, floor (value * upper + 0.5) ); - } - - ColorWheelSelector* wheelSelector = static_cast<ColorWheelSelector*>(SP_COLOR_SELECTOR(cs)->base); - if (wheelSelector->_updating) return; - - wheelSelector->_updating = TRUE; - - preserve_icc(&wheelSelector->_color, cs); - wheelSelector->_updateInternals( wheelSelector->_color, ColorScales::getScaled( wheelSelector->_adj ), wheelSelector->_dragging ); - - wheelSelector->_updating = FALSE; -} - -void ColorWheelSelector::_sliderGrabbed( SPColorSlider *slider, SPColorWheelSelector *cs ) -{ - (void)slider; - ColorWheelSelector* wheelSelector = static_cast<ColorWheelSelector*>(SP_COLOR_SELECTOR(cs)->base); - if (!wheelSelector->_dragging) { - wheelSelector->_dragging = TRUE; - wheelSelector->_grabbed(); - - preserve_icc(&wheelSelector->_color, cs); - wheelSelector->_updateInternals( wheelSelector->_color, ColorScales::getScaled( wheelSelector->_adj ), wheelSelector->_dragging ); - } -} - -void ColorWheelSelector::_sliderReleased( SPColorSlider *slider, SPColorWheelSelector *cs ) -{ - (void)slider; - ColorWheelSelector* wheelSelector = static_cast<ColorWheelSelector*>(SP_COLOR_SELECTOR(cs)->base); - if (wheelSelector->_dragging) { - wheelSelector->_dragging = FALSE; - wheelSelector->_released(); - - preserve_icc(&wheelSelector->_color, cs); - wheelSelector->_updateInternals( wheelSelector->_color, ColorScales::getScaled( wheelSelector->_adj ), wheelSelector->_dragging ); - } -} - -void ColorWheelSelector::_sliderChanged( SPColorSlider *slider, SPColorWheelSelector *cs ) -{ - (void)slider; - ColorWheelSelector* wheelSelector = static_cast<ColorWheelSelector*>(SP_COLOR_SELECTOR(cs)->base); - - preserve_icc(&wheelSelector->_color, cs); - wheelSelector->_updateInternals( wheelSelector->_color, ColorScales::getScaled( wheelSelector->_adj ), wheelSelector->_dragging ); -} - -void ColorWheelSelector::_wheelChanged( GimpColorWheel *wheel, SPColorWheelSelector *cs ) -{ - ColorWheelSelector* wheelSelector = static_cast<ColorWheelSelector*>(SP_COLOR_SELECTOR(cs)->base); - - gdouble h = 0; - gdouble s = 0; - gdouble v = 0; - gimp_color_wheel_get_color( wheel, &h, &s, &v ); - - float rgb[3] = {0,0,0}; - sp_color_hsv_to_rgb_floatv (rgb, h, s, v); - - SPColor color(rgb[0], rgb[1], rgb[2]); - - guint32 start = color.toRGBA32( 0x00 ); - guint32 mid = color.toRGBA32( 0x7f ); - guint32 end = color.toRGBA32( 0xff ); - - sp_color_slider_set_colors (SP_COLOR_SLIDER(wheelSelector->_slider), start, mid, end); - - preserve_icc(&color, cs); - wheelSelector->_updateInternals( color, wheelSelector->_alpha, gimp_color_wheel_is_adjusting(wheel) ); -} - - -/* - 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 : diff --git a/src/widgets/sp-color-wheel-selector.h b/src/widgets/sp-color-wheel-selector.h deleted file mode 100644 index 12b060dbe..000000000 --- a/src/widgets/sp-color-wheel-selector.h +++ /dev/null @@ -1,82 +0,0 @@ -#ifndef SEEN_SP_COLOR_WHEEL_SELECTOR_H -#define SEEN_SP_COLOR_WHEEL_SELECTOR_H - -#include <gtk/gtk.h> - -#include "sp-color-selector.h" - -typedef struct _GimpColorWheel GimpColorWheel; -struct SPColorSlider; -struct SPColorWheelSelector; -struct SPColorWheelSelectorClass; - -class ColorWheelSelector: public ColorSelector -{ -public: - ColorWheelSelector( SPColorSelector* csel ); - virtual ~ColorWheelSelector(); - - virtual void init(); - -protected: - virtual void _colorChanged(); - - static void _adjustmentChanged ( GtkAdjustment *adjustment, SPColorWheelSelector *cs ); - - static void _sliderGrabbed( SPColorSlider *slider, SPColorWheelSelector *cs ); - static void _sliderReleased( SPColorSlider *slider, SPColorWheelSelector *cs ); - static void _sliderChanged( SPColorSlider *slider, SPColorWheelSelector *cs ); - static void _wheelChanged( GimpColorWheel *wheel, SPColorWheelSelector *cs ); - - static void _fooChanged( GtkWidget foo, SPColorWheelSelector *cs ); - - void _recalcColor( gboolean changing ); - - gboolean _updating : 1; - gboolean _dragging : 1; - GtkAdjustment* _adj; // Channel adjustment - GtkWidget* _wheel; - GtkWidget* _slider; - GtkWidget* _sbtn; // Spinbutton - GtkWidget* _label; // Label - -private: - // By default, disallow copy constructor and assignment operator - ColorWheelSelector( const ColorWheelSelector& obj ); - ColorWheelSelector& operator=( const ColorWheelSelector& obj ); -}; - - - -#define SP_TYPE_COLOR_WHEEL_SELECTOR (sp_color_wheel_selector_get_type ()) -#define SP_COLOR_WHEEL_SELECTOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SP_TYPE_COLOR_WHEEL_SELECTOR, SPColorWheelSelector)) -#define SP_COLOR_WHEEL_SELECTOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), SP_TYPE_COLOR_WHEEL_SELECTOR, SPColorWheelSelectorClass)) -#define SP_IS_COLOR_WHEEL_SELECTOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SP_TYPE_COLOR_WHEEL_SELECTOR)) -#define SP_IS_COLOR_WHEEL_SELECTOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SP_TYPE_COLOR_WHEEL_SELECTOR)) - -struct SPColorWheelSelector { - SPColorSelector parent; -}; - -struct SPColorWheelSelectorClass { - SPColorSelectorClass parent_class; -}; - -GType sp_color_wheel_selector_get_type (void); - -GtkWidget *sp_color_wheel_selector_new (void); - - - -#endif // SEEN_SP_COLOR_WHEEL_SELECTOR_H - -/* - 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 : diff --git a/src/widgets/swatch-selector.cpp b/src/widgets/swatch-selector.cpp index 7178ad072..6f2807255 100644 --- a/src/widgets/swatch-selector.cpp +++ b/src/widgets/swatch-selector.cpp @@ -5,11 +5,11 @@ #include "document-undo.h" #include "gradient-chemistry.h" #include "gradient-selector.h" -#include "sp-color-notebook.h" #include "sp-stop.h" #include "svg/css-ostringstream.h" #include "svg/svg-color.h" #include "verbs.h" +#include "ui/widget/color-notebook.h" #include "xml/node.h" namespace Inkscape @@ -20,8 +20,10 @@ namespace Widgets SwatchSelector::SwatchSelector() : Gtk::VBox(), _gsel(0), - _csel(0) + _updating_color(false) { + using Inkscape::UI::Widget::ColorNotebook; + GtkWidget *gsel = sp_gradient_selector_new(); _gsel = SP_GRADIENT_SELECTOR(gsel); g_object_set_data( G_OBJECT(gobj()), "base", this ); @@ -31,27 +33,18 @@ SwatchSelector::SwatchSelector() : pack_start(*Gtk::manage(Glib::wrap(gsel))); + Gtk::Widget *color_selector = Gtk::manage(new ColorNotebook(_selected_color)); + color_selector->show(); + pack_start(*color_selector); - GtkWidget *csel = sp_color_selector_new( SP_TYPE_COLOR_NOTEBOOK ); - _csel = SP_COLOR_SELECTOR(csel); - Gtk::Widget *wrappedCSel = Glib::wrap(csel); - wrappedCSel->show(); - //gtk_widget_show(csel); - - - GObject *obj = G_OBJECT(csel); - - g_signal_connect(obj, "grabbed", G_CALLBACK(_grabbedCb), this); - g_signal_connect(obj, "dragged", G_CALLBACK(_draggedCb), this); - g_signal_connect(obj, "released", G_CALLBACK(_releasedCb), this); - g_signal_connect(obj, "changed", G_CALLBACK(_changedCb), this); - - pack_start(*Gtk::manage(wrappedCSel)); + _selected_color.signal_grabbed.connect(sigc::mem_fun(this, &SwatchSelector::_grabbedCb)); + _selected_color.signal_dragged.connect(sigc::mem_fun(this, &SwatchSelector::_draggedCb)); + _selected_color.signal_released.connect(sigc::mem_fun(this, &SwatchSelector::_releasedCb)); + _selected_color.signal_changed.connect(sigc::mem_fun(this, &SwatchSelector::_changedCb)); } SwatchSelector::~SwatchSelector() { - _csel = 0; // dtor should be handled by Gtk::manage() _gsel = 0; } @@ -60,13 +53,13 @@ SPGradientSelector *SwatchSelector::getGradientSelector() return _gsel; } -void SwatchSelector::_grabbedCb(SPColorSelector * /*csel*/, void * /*data*/) +void SwatchSelector::_grabbedCb() { } -void SwatchSelector::_draggedCb(SPColorSelector * /*csel*/, void *data) +void SwatchSelector::_draggedCb() { - if (data) { + // if (data) { //SwatchSelector *swsel = reinterpret_cast<SwatchSelector*>(data); // TODO might have to block cycles @@ -92,50 +85,46 @@ void SwatchSelector::_draggedCb(SPColorSelector * /*csel*/, void *data) } } */ - } + // } } -void SwatchSelector::_releasedCb(SPColorSelector * /*csel*/, void * /*data*/) +void SwatchSelector::_releasedCb() { } -void SwatchSelector::_changedCb(SPColorSelector */*csel*/, void *data) +void SwatchSelector::_changedCb() { - if (data) { - SwatchSelector *swsel = reinterpret_cast<SwatchSelector*>(data); + if (_updating_color) { + return; + } + // TODO might have to block cycles + + if (_gsel && _gsel->getVector()) { + SPGradient *gradient = _gsel->getVector(); + SPGradient *ngr = sp_gradient_ensure_vector_normalized(gradient); + if (ngr != gradient) { + /* Our master gradient has changed */ + // TODO replace with proper - sp_gradient_vector_widget_load_gradient(GTK_WIDGET(swsel->_gsel), ngr); + } - // TODO might have to block cycles + ngr->ensureVector(); - if (swsel->_gsel && swsel->_gsel->getVector()) { - SPGradient *gradient = swsel->_gsel->getVector(); - SPGradient *ngr = sp_gradient_ensure_vector_normalized(gradient); - if (ngr != gradient) { - /* Our master gradient has changed */ - // TODO replace with proper - sp_gradient_vector_widget_load_gradient(GTK_WIDGET(swsel->_gsel), ngr); - } - ngr->ensureVector(); + SPStop* stop = ngr->getFirstStop(); + if (stop) { + SPColor color = _selected_color.color(); + gfloat alpha = _selected_color.alpha(); + guint32 rgb = color.toRGBA32( 0x00 ); + // TODO replace with generic shared code that also handles icc-color + Inkscape::CSSOStringStream os; + gchar c[64]; + sp_svg_write_color(c, sizeof(c), rgb); + os << "stop-color:" << c << ";stop-opacity:" << static_cast<gdouble>(alpha) <<";"; + stop->getRepr()->setAttribute("style", os.str().c_str()); - SPStop* stop = ngr->getFirstStop(); - if (stop) { - SPColor color; - float alpha = 0; - guint32 rgb = 0; - - swsel->_csel->base->getColorAlpha( color, alpha ); - rgb = color.toRGBA32( 0x00 ); - - // TODO replace with generic shared code that also handles icc-color - Inkscape::CSSOStringStream os; - gchar c[64]; - sp_svg_write_color(c, sizeof(c), rgb); - os << "stop-color:" << c << ";stop-opacity:" << static_cast<gdouble>(alpha) <<";"; - stop->getRepr()->setAttribute("style", os.str().c_str()); - - DocumentUndo::done(ngr->document, SP_VERB_CONTEXT_GRADIENT, - _("Change swatch color")); - } + DocumentUndo::done(ngr->document, SP_VERB_CONTEXT_GRADIENT, + _("Change swatch color")); } } } @@ -173,11 +162,10 @@ void SwatchSelector::setVector(SPDocument */*doc*/, SPGradient *vector) SPStop* stop = vector->getFirstStop(); guint32 const colorVal = stop->get_rgba32(); - _csel->base->setAlpha(SP_RGBA32_A_F(colorVal)); - SPColor color( SP_RGBA32_R_F(colorVal), SP_RGBA32_G_F(colorVal), SP_RGBA32_B_F(colorVal) ); - // set its color, from the stored array - _csel->base->setColor( color ); - gtk_widget_show_all( GTK_WIDGET(_csel) ); + _updating_color = true; + _selected_color.setValue(colorVal); + _updating_color = false; + // gtk_widget_show_all( GTK_WIDGET(_csel) ); } else { //gtk_widget_hide( GTK_WIDGET(_csel) ); } diff --git a/src/widgets/swatch-selector.h b/src/widgets/swatch-selector.h index 4b7aa483f..16a8cfac8 100644 --- a/src/widgets/swatch-selector.h +++ b/src/widgets/swatch-selector.h @@ -2,6 +2,7 @@ #define SEEN_SP_SWATCH_SELECTOR_H #include <gtkmm/box.h> +#include "ui/selected-color.h" class SPDocument; class SPGradient; @@ -29,13 +30,14 @@ public: SPGradientSelector *getGradientSelector(); private: - static void _grabbedCb(SPColorSelector *csel, void *data); - static void _draggedCb(SPColorSelector *csel, void *data); - static void _releasedCb(SPColorSelector *csel, void *data); - static void _changedCb(SPColorSelector *csel, void *data); + void _grabbedCb(); + void _draggedCb(); + void _releasedCb(); + void _changedCb(); SPGradientSelector *_gsel; - SPColorSelector *_csel; + Inkscape::UI::SelectedColor _selected_color; + bool _updating_color; }; |
