diff options
Diffstat (limited to 'src/ui')
23 files changed, 1860 insertions, 141 deletions
diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp index c7be0877d..7bd1b81c0 100644 --- a/src/ui/dialog/document-properties.cpp +++ b/src/ui/dialog/document-properties.cpp @@ -959,16 +959,18 @@ void DocumentProperties::removeEmbeddedScript(){ const GSList *current = SP_ACTIVE_DOCUMENT->getResourceList( "script" ); while ( current ) { - SPObject* obj = SP_OBJECT(current->data); - if (id == obj->getId()){ + if (current->data && SP_IS_OBJECT(current->data)) { + SPObject* obj = SP_OBJECT(current->data); + if (id == obj->getId()){ - //XML Tree being used directly here while it shouldn't be. - Inkscape::XML::Node *repr = obj->getRepr(); - if (repr){ - sp_repr_unparent(repr); + //XML Tree being used directly here while it shouldn't be. + Inkscape::XML::Node *repr = obj->getRepr(); + if (repr){ + sp_repr_unparent(repr); - // inform the document, so we can undo - DocumentUndo::done(SP_ACTIVE_DOCUMENT, SP_VERB_EDIT_REMOVE_EMBEDDED_SCRIPT, _("Remove embedded script")); + // inform the document, so we can undo + DocumentUndo::done(SP_ACTIVE_DOCUMENT, SP_VERB_EDIT_REMOVE_EMBEDDED_SCRIPT, _("Remove embedded script")); + } } } current = g_slist_next(current); diff --git a/src/ui/dialog/fill-and-stroke.cpp b/src/ui/dialog/fill-and-stroke.cpp index 74c19fea7..c7efd3bf2 100644 --- a/src/ui/dialog/fill-and-stroke.cpp +++ b/src/ui/dialog/fill-and-stroke.cpp @@ -63,7 +63,7 @@ FillAndStroke::FillAndStroke() _layoutPageStrokePaint(); _layoutPageStrokeStyle(); - contents->pack_start(_composite_settings, false, false, 0); + contents->pack_start(_composite_settings, true, true, 0); show_all_children(); diff --git a/src/ui/dialog/filter-effects-dialog.cpp b/src/ui/dialog/filter-effects-dialog.cpp index 317cb2773..c3c44f6c3 100644 --- a/src/ui/dialog/filter-effects-dialog.cpp +++ b/src/ui/dialog/filter-effects-dialog.cpp @@ -78,8 +78,8 @@ namespace Dialog { using Inkscape::UI::Widget::AttrWidget; using Inkscape::UI::Widget::ComboBoxEnum; -using Inkscape::UI::Widget::DualSpinSlider; -using Inkscape::UI::Widget::SpinSlider; +using Inkscape::UI::Widget::DualSpinScale; +using Inkscape::UI::Widget::SpinScale; // Returns the number of inputs available for the filter primitive type @@ -484,8 +484,8 @@ public: : AttrWidget(SP_ATTR_VALUES), // TRANSLATORS: this dialog is accessible via menu Filters - Filter editor _matrix(SP_ATTR_VALUES, _("This matrix determines a linear transform on color space. Each line affects one of the color components. Each column determines how much of each color component from the input is passed to the output. The last column does not depend on input colors, so can be used to adjust a constant component value.")), - _saturation(0, 0, 1, 0.1, 0.01, 2, SP_ATTR_VALUES), - _angle(0, 0, 360, 0.1, 0.01, 1, SP_ATTR_VALUES), + _saturation("", 0, 0, 1, 0.1, 0.01, 2, SP_ATTR_VALUES), + _angle("", 0, 0, 360, 0.1, 0.01, 1, SP_ATTR_VALUES), _label(_("None"), Gtk::ALIGN_START), _use_stored(false), _saturation_store(0), @@ -567,8 +567,8 @@ private: } MatrixAttr _matrix; - SpinSlider _saturation; - SpinSlider _angle; + SpinScale _saturation; + SpinScale _angle; Gtk::Label _label; // Store separate values for the different color modes @@ -808,22 +808,22 @@ public: return cmv; } - // SpinSlider - SpinSlider* add_spinslider(double def, const SPAttributeEnum attr, const Glib::ustring& label, + // SpinScale + SpinScale* add_spinscale(double def, const SPAttributeEnum attr, const Glib::ustring& label, const double lo, const double hi, const double step_inc, const double climb, const int digits, char* tip_text = NULL) { - SpinSlider* spinslider = new SpinSlider(def, lo, hi, step_inc, climb, digits, attr, tip_text); + SpinScale* spinslider = new SpinScale("", def, lo, hi, step_inc, climb, digits, attr, tip_text); add_widget(spinslider, label); add_attr_widget(spinslider); return spinslider; } - // DualSpinSlider - DualSpinSlider* add_dualspinslider(const SPAttributeEnum attr, const Glib::ustring& label, + // DualSpinScale + DualSpinScale* add_dualspinscale(const SPAttributeEnum attr, const Glib::ustring& label, const double lo, const double hi, const double step_inc, const double climb, const int digits, char* tip_text1 = NULL, char* tip_text2 = NULL) { - DualSpinSlider* dss = new DualSpinSlider(lo, lo, hi, step_inc, climb, digits, attr, tip_text1, tip_text2); + DualSpinScale* dss = new DualSpinScale("", "", lo, lo, hi, step_inc, climb, digits, attr, tip_text1, tip_text2); add_widget(dss, label); add_attr_widget(dss); return dss; @@ -971,8 +971,8 @@ public: // FIXME: these range values are complete crap _settings.type(LIGHT_DISTANT); - _settings.add_spinslider(0, SP_ATTR_AZIMUTH, _("Azimuth"), 0, 360, 1, 1, 0, _("Direction angle for the light source on the XY plane, in degrees")); - _settings.add_spinslider(0, SP_ATTR_ELEVATION, _("Elevation"), 0, 360, 1, 1, 0, _("Direction angle for the light source on the YZ plane, in degrees")); + _settings.add_spinscale(0, SP_ATTR_AZIMUTH, _("Azimuth"), 0, 360, 1, 1, 0, _("Direction angle for the light source on the XY plane, in degrees")); + _settings.add_spinscale(0, SP_ATTR_ELEVATION, _("Elevation"), 0, 360, 1, 1, 0, _("Direction angle for the light source on the YZ plane, in degrees")); _settings.type(LIGHT_POINT); _settings.add_multispinbutton(/*default x:*/ (double) 0, /*default y:*/ (double) 0, /*default z:*/ (double) 0, SP_ATTR_X, SP_ATTR_Y, SP_ATTR_Z, _("Location:"), -99999, 99999, 1, 100, 0, _("X coordinate"), _("Y coordinate"), _("Z coordinate")); @@ -982,9 +982,9 @@ public: _settings.add_multispinbutton(/*default x:*/ (double) 0, /*default y:*/ (double) 0, /*default z:*/ (double) 0, SP_ATTR_POINTSATX, SP_ATTR_POINTSATY, SP_ATTR_POINTSATZ, _("Points At"), -99999, 99999, 1, 100, 0, _("X coordinate"), _("Y coordinate"), _("Z coordinate")); - _settings.add_spinslider(1, SP_ATTR_SPECULAREXPONENT, _("Specular Exponent"), 1, 100, 1, 1, 0, _("Exponent value controlling the focus for the light source")); + _settings.add_spinscale(1, SP_ATTR_SPECULAREXPONENT, _("Specular Exponent"), 1, 100, 1, 1, 0, _("Exponent value controlling the focus for the light source")); //TODO: here I have used 100 degrees as default value. But spec says that if not specified, no limiting cone is applied. So, there should be a way for the user to set a "no limiting cone" option. - _settings.add_spinslider(100, SP_ATTR_LIMITINGCONEANGLE, _("Cone Angle"), 1, 100, 1, 1, 0, _("This is the angle between the spot light axis (i.e. the axis between the light source and the point to which it is pointing at) and the spot light cone. No light is projected outside this cone.")); + _settings.add_spinscale(100, SP_ATTR_LIMITINGCONEANGLE, _("Cone Angle"), 1, 100, 1, 1, 0, _("This is the angle between the spot light axis (i.e. the axis between the light source and the point to which it is pointing at) and the spot light cone. No light is projected outside this cone.")); } Gtk::VBox& get_box() @@ -2331,7 +2331,7 @@ void FilterEffectsDialog::show_all_vfunc() void FilterEffectsDialog::init_settings_widgets() { - // TODO: Find better range/climb-rate/digits values for the SpinSliders, + // TODO: Find better range/climb-rate/digits values for the SpinScales, // most of the current values are complete guesses! _empty_settings.set_sensitive(false); @@ -2358,18 +2358,18 @@ void FilterEffectsDialog::init_settings_widgets() /* //TRANSLATORS: for info on "Slope" and "Intercept", see http://id.mind.net/~zona/mmts/functionInstitute/linearFunctions/lsif.html _settings->add_combo(COMPONENTTRANSFER_TYPE_IDENTITY, SP_ATTR_TYPE, _("Type"), ComponentTransferTypeConverter); - _ct_slope = _settings->add_spinslider(1, SP_ATTR_SLOPE, _("Slope"), -10, 10, 0.1, 0.01, 2); - _ct_intercept = _settings->add_spinslider(0, SP_ATTR_INTERCEPT, _("Intercept"), -10, 10, 0.1, 0.01, 2); - _ct_amplitude = _settings->add_spinslider(1, SP_ATTR_AMPLITUDE, _("Amplitude"), 0, 10, 0.1, 0.01, 2); - _ct_exponent = _settings->add_spinslider(1, SP_ATTR_EXPONENT, _("Exponent"), 0, 10, 0.1, 0.01, 2); - _ct_offset = _settings->add_spinslider(0, SP_ATTR_OFFSET, _("Offset"), -10, 10, 0.1, 0.01, 2);*/ + _ct_slope = _settings->add_spinscale(1, SP_ATTR_SLOPE, _("Slope"), -10, 10, 0.1, 0.01, 2); + _ct_intercept = _settings->add_spinscale(0, SP_ATTR_INTERCEPT, _("Intercept"), -10, 10, 0.1, 0.01, 2); + _ct_amplitude = _settings->add_spinscale(1, SP_ATTR_AMPLITUDE, _("Amplitude"), 0, 10, 0.1, 0.01, 2); + _ct_exponent = _settings->add_spinscale(1, SP_ATTR_EXPONENT, _("Exponent"), 0, 10, 0.1, 0.01, 2); + _ct_offset = _settings->add_spinscale(0, SP_ATTR_OFFSET, _("Offset"), -10, 10, 0.1, 0.01, 2);*/ _settings->type(NR_FILTER_COMPOSITE); _settings->add_combo(COMPOSITE_OVER, SP_ATTR_OPERATOR, _("Operator:"), CompositeOperatorConverter); - _k1 = _settings->add_spinslider(0, SP_ATTR_K1, _("K1:"), -10, 10, 0.1, 0.01, 2, _("If the arithmetic operation is chosen, each result pixel is computed using the formula k1*i1*i2 + k2*i1 + k3*i2 + k4 where i1 and i2 are the pixel values of the first and second inputs respectively.")); - _k2 = _settings->add_spinslider(0, SP_ATTR_K2, _("K2:"), -10, 10, 0.1, 0.01, 2, _("If the arithmetic operation is chosen, each result pixel is computed using the formula k1*i1*i2 + k2*i1 + k3*i2 + k4 where i1 and i2 are the pixel values of the first and second inputs respectively.")); - _k3 = _settings->add_spinslider(0, SP_ATTR_K3, _("K3:"), -10, 10, 0.1, 0.01, 2, _("If the arithmetic operation is chosen, each result pixel is computed using the formula k1*i1*i2 + k2*i1 + k3*i2 + k4 where i1 and i2 are the pixel values of the first and second inputs respectively.")); - _k4 = _settings->add_spinslider(0, SP_ATTR_K4, _("K4:"), -10, 10, 0.1, 0.01, 2, _("If the arithmetic operation is chosen, each result pixel is computed using the formula k1*i1*i2 + k2*i1 + k3*i2 + k4 where i1 and i2 are the pixel values of the first and second inputs respectively.")); + _k1 = _settings->add_spinscale(0, SP_ATTR_K1, _("K1:"), -10, 10, 0.1, 0.01, 2, _("If the arithmetic operation is chosen, each result pixel is computed using the formula k1*i1*i2 + k2*i1 + k3*i2 + k4 where i1 and i2 are the pixel values of the first and second inputs respectively.")); + _k2 = _settings->add_spinscale(0, SP_ATTR_K2, _("K2:"), -10, 10, 0.1, 0.01, 2, _("If the arithmetic operation is chosen, each result pixel is computed using the formula k1*i1*i2 + k2*i1 + k3*i2 + k4 where i1 and i2 are the pixel values of the first and second inputs respectively.")); + _k3 = _settings->add_spinscale(0, SP_ATTR_K3, _("K3:"), -10, 10, 0.1, 0.01, 2, _("If the arithmetic operation is chosen, each result pixel is computed using the formula k1*i1*i2 + k2*i1 + k3*i2 + k4 where i1 and i2 are the pixel values of the first and second inputs respectively.")); + _k4 = _settings->add_spinscale(0, SP_ATTR_K4, _("K4:"), -10, 10, 0.1, 0.01, 2, _("If the arithmetic operation is chosen, each result pixel is computed using the formula k1*i1*i2 + k2*i1 + k3*i2 + k4 where i1 and i2 are the pixel values of the first and second inputs respectively.")); _settings->type(NR_FILTER_CONVOLVEMATRIX); _convolve_order = _settings->add_dualspinbutton((char*)"3", SP_ATTR_ORDER, _("Size:"), 1, 5, 1, 1, 0, _("width of the convolve matrix"), _("height of the convolve matrix")); @@ -2377,50 +2377,50 @@ void FilterEffectsDialog::init_settings_widgets() //TRANSLATORS: for info on "Kernel", see http://en.wikipedia.org/wiki/Kernel_(matrix) _convolve_matrix = _settings->add_matrix(SP_ATTR_KERNELMATRIX, _("Kernel:"), _("This matrix describes the convolve operation that is applied to the input image in order to calculate the pixel colors at the output. Different arrangements of values in this matrix result in various possible visual effects. An identity matrix would lead to a motion blur effect (parallel to the matrix diagonal) while a matrix filled with a constant non-zero value would lead to a common blur effect.")); _convolve_order->signal_attr_changed().connect(sigc::mem_fun(*this, &FilterEffectsDialog::convolve_order_changed)); - _settings->add_spinslider(0, SP_ATTR_DIVISOR, _("Divisor:"), 0, 1000, 1, 0.1, 2, _("After applying the kernelMatrix to the input image to yield a number, that number is divided by divisor to yield the final destination color value. A divisor that is the sum of all the matrix values tends to have an evening effect on the overall color intensity of the result.")); - _settings->add_spinslider(0, SP_ATTR_BIAS, _("Bias:"), -10, 10, 1, 0.01, 1, _("This value is added to each component. This is useful to define a constant value as the zero response of the filter.")); + _settings->add_spinscale(0, SP_ATTR_DIVISOR, _("Divisor:"), 0, 1000, 1, 0.1, 2, _("After applying the kernelMatrix to the input image to yield a number, that number is divided by divisor to yield the final destination color value. A divisor that is the sum of all the matrix values tends to have an evening effect on the overall color intensity of the result.")); + _settings->add_spinscale(0, SP_ATTR_BIAS, _("Bias:"), -10, 10, 1, 0.01, 1, _("This value is added to each component. This is useful to define a constant value as the zero response of the filter.")); _settings->add_combo(CONVOLVEMATRIX_EDGEMODE_DUPLICATE, SP_ATTR_EDGEMODE, _("Edge Mode:"), ConvolveMatrixEdgeModeConverter, _("Determines how to extend the input image as necessary with color values so that the matrix operations can be applied when the kernel is positioned at or near the edge of the input image.")); _settings->add_checkbutton(false, SP_ATTR_PRESERVEALPHA, _("Preserve Alpha"), "true", "false", _("If set, the alpha channel won't be altered by this filter primitive.")); _settings->type(NR_FILTER_DIFFUSELIGHTING); _settings->add_color(/*default: white*/ 0xffffffff, SP_PROP_LIGHTING_COLOR, _("Diffuse Color:"), _("Defines the color of the light source")); - _settings->add_spinslider(1, SP_ATTR_SURFACESCALE, _("Surface Scale:"), -5, 5, 0.01, 0.001, 3, _("This value amplifies the heights of the bump map defined by the input alpha channel")); - _settings->add_spinslider(1, SP_ATTR_DIFFUSECONSTANT, _("Constant:"), 0, 5, 0.1, 0.01, 2, _("This constant affects the Phong lighting model.")); - _settings->add_dualspinslider(SP_ATTR_KERNELUNITLENGTH, _("Kernel Unit Length:"), 0.01, 10, 1, 0.01, 1); + _settings->add_spinscale(1, SP_ATTR_SURFACESCALE, _("Surface Scale:"), -5, 5, 0.01, 0.001, 3, _("This value amplifies the heights of the bump map defined by the input alpha channel")); + _settings->add_spinscale(1, SP_ATTR_DIFFUSECONSTANT, _("Constant:"), 0, 5, 0.1, 0.01, 2, _("This constant affects the Phong lighting model.")); + _settings->add_dualspinscale(SP_ATTR_KERNELUNITLENGTH, _("Kernel Unit Length:"), 0.01, 10, 1, 0.01, 1); _settings->add_lightsource(); _settings->type(NR_FILTER_DISPLACEMENTMAP); - _settings->add_spinslider(0, SP_ATTR_SCALE, _("Scale:"), 0, 100, 1, 0.01, 1, _("This defines the intensity of the displacement effect.")); + _settings->add_spinscale(0, SP_ATTR_SCALE, _("Scale:"), 0, 100, 1, 0.01, 1, _("This defines the intensity of the displacement effect.")); _settings->add_combo(DISPLACEMENTMAP_CHANNEL_ALPHA, SP_ATTR_XCHANNELSELECTOR, _("X displacement:"), DisplacementMapChannelConverter, _("Color component that controls the displacement in the X direction")); _settings->add_combo(DISPLACEMENTMAP_CHANNEL_ALPHA, SP_ATTR_YCHANNELSELECTOR, _("Y displacement:"), DisplacementMapChannelConverter, _("Color component that controls the displacement in the Y direction")); _settings->type(NR_FILTER_FLOOD); _settings->add_color(/*default: black*/ 0, SP_PROP_FLOOD_COLOR, _("Flood Color:"), _("The whole filter region will be filled with this color.")); - _settings->add_spinslider(1, SP_PROP_FLOOD_OPACITY, _("Opacity:"), 0, 1, 0.1, 0.01, 2); + _settings->add_spinscale(1, SP_PROP_FLOOD_OPACITY, _("Opacity:"), 0, 1, 0.1, 0.01, 2); _settings->type(NR_FILTER_GAUSSIANBLUR); - _settings->add_dualspinslider(SP_ATTR_STDDEVIATION, _("Standard Deviation:"), 0.01, 100, 1, 0.01, 1, _("The standard deviation for the blur operation.")); + _settings->add_dualspinscale(SP_ATTR_STDDEVIATION, _("Standard Deviation:"), 0.01, 100, 1, 0.01, 1, _("The standard deviation for the blur operation.")); _settings->type(NR_FILTER_MERGE); _settings->add_no_params(); _settings->type(NR_FILTER_MORPHOLOGY); _settings->add_combo(MORPHOLOGY_OPERATOR_ERODE, SP_ATTR_OPERATOR, _("Operator:"), MorphologyOperatorConverter, _("Erode: performs \"thinning\" of input image.\nDilate: performs \"fattenning\" of input image.")); - _settings->add_dualspinslider(SP_ATTR_RADIUS, _("Radius:"), 0, 100, 1, 0.01, 1); + _settings->add_dualspinscale(SP_ATTR_RADIUS, _("Radius:"), 0, 100, 1, 0.01, 1); _settings->type(NR_FILTER_IMAGE); _settings->add_fileorelement(SP_ATTR_XLINK_HREF, _("Source of Image:")); _settings->type(NR_FILTER_OFFSET); - _settings->add_spinslider(0, SP_ATTR_DX, _("Delta X:"), -100, 100, 1, 0.01, 1, _("This is how far the input image gets shifted to the right")); - _settings->add_spinslider(0, SP_ATTR_DY, _("Delta Y:"), -100, 100, 1, 0.01, 1, _("This is how far the input image gets shifted downwards")); + _settings->add_spinscale(0, SP_ATTR_DX, _("Delta X:"), -100, 100, 1, 0.01, 1, _("This is how far the input image gets shifted to the right")); + _settings->add_spinscale(0, SP_ATTR_DY, _("Delta Y:"), -100, 100, 1, 0.01, 1, _("This is how far the input image gets shifted downwards")); _settings->type(NR_FILTER_SPECULARLIGHTING); _settings->add_color(/*default: white*/ 0xffffffff, SP_PROP_LIGHTING_COLOR, _("Specular Color:"), _("Defines the color of the light source")); - _settings->add_spinslider(1, SP_ATTR_SURFACESCALE, _("Surface Scale:"), -5, 5, 0.1, 0.01, 2, _("This value amplifies the heights of the bump map defined by the input alpha channel")); - _settings->add_spinslider(1, SP_ATTR_SPECULARCONSTANT, _("Constant:"), 0, 5, 0.1, 0.01, 2, _("This constant affects the Phong lighting model.")); - _settings->add_spinslider(1, SP_ATTR_SPECULAREXPONENT, _("Exponent:"), 1, 50, 1, 0.01, 1, _("Exponent for specular term, larger is more \"shiny\".")); - _settings->add_dualspinslider(SP_ATTR_KERNELUNITLENGTH, _("Kernel Unit Length:"), 0.01, 10, 1, 0.01, 1); + _settings->add_spinscale(1, SP_ATTR_SURFACESCALE, _("Surface Scale:"), -5, 5, 0.1, 0.01, 2, _("This value amplifies the heights of the bump map defined by the input alpha channel")); + _settings->add_spinscale(1, SP_ATTR_SPECULARCONSTANT, _("Constant:"), 0, 5, 0.1, 0.01, 2, _("This constant affects the Phong lighting model.")); + _settings->add_spinscale(1, SP_ATTR_SPECULAREXPONENT, _("Exponent:"), 1, 50, 1, 0.01, 1, _("Exponent for specular term, larger is more \"shiny\".")); + _settings->add_dualspinscale(SP_ATTR_KERNELUNITLENGTH, _("Kernel Unit Length:"), 0.01, 10, 1, 0.01, 1); _settings->add_lightsource(); _settings->type(NR_FILTER_TILE); @@ -2429,9 +2429,9 @@ void FilterEffectsDialog::init_settings_widgets() _settings->type(NR_FILTER_TURBULENCE); // _settings->add_checkbutton(false, SP_ATTR_STITCHTILES, _("Stitch Tiles"), "stitch", "noStitch"); _settings->add_combo(TURBULENCE_TURBULENCE, SP_ATTR_TYPE, _("Type:"), TurbulenceTypeConverter, _("Indicates whether the filter primitive should perform a noise or turbulence function.")); - _settings->add_dualspinslider(SP_ATTR_BASEFREQUENCY, _("Base Frequency:"), 0, 1, 0.001, 0.01, 3); - _settings->add_spinslider(1, SP_ATTR_NUMOCTAVES, _("Octaves:"), 1, 10, 1, 1, 0); - _settings->add_spinslider(0, SP_ATTR_SEED, _("Seed:"), 0, 1000, 1, 1, 0, _("The starting number for the pseudo random number generator.")); + _settings->add_dualspinscale(SP_ATTR_BASEFREQUENCY, _("Base Frequency:"), 0, 1, 0.001, 0.01, 3); + _settings->add_spinscale(1, SP_ATTR_NUMOCTAVES, _("Octaves:"), 1, 10, 1, 1, 0); + _settings->add_spinscale(0, SP_ATTR_SEED, _("Seed:"), 0, 1000, 1, 1, 0, _("The starting number for the pseudo random number generator.")); } void FilterEffectsDialog::add_primitive() diff --git a/src/ui/dialog/filter-effects-dialog.h b/src/ui/dialog/filter-effects-dialog.h index 38811354e..acdeecb71 100644 --- a/src/ui/dialog/filter-effects-dialog.h +++ b/src/ui/dialog/filter-effects-dialog.h @@ -20,6 +20,7 @@ #include "sp-filter.h" #include "ui/widget/combo-enums.h" #include "ui/widget/spin-slider.h" +#include "ui/widget/spin-scale.h" #include "xml/helper-observer.h" #include "ui/dialog/desktop-tracker.h" diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index 7ee2aa444..62f48cce0 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -478,6 +478,11 @@ void InkscapePreferences::initPageTools() _page_gradient.add_line( false, "", _misc_gradienteditor, "", _("When on, the Gradient Edit button in the Fill & Stroke dialog will show the legacy Gradient Editor dialog, when off the Gradient Tool will be used"), true); + _misc_gradientangle.init("/dialogs/gradienteditor/angle", -359, 359, 1, 90, 0, false, false); + _page_gradient.add_line( false, _("Linear gradient _angle:"), _misc_gradientangle, "", + _("Default angle of new linear gradients in degrees (clockwise from horizontal"), false); + + //Dropper this->AddPage(_page_dropper, _("Dropper"), iter_tools, PREFS_PAGE_TOOLS_DROPPER); this->AddSelcueCheckbox(_page_dropper, "/tools/dropper", true); @@ -1389,6 +1394,9 @@ void InkscapePreferences::initPageBitmaps() _importexport_import_res.init("/dialogs/import/defaultxdpi/value", 0.0, 6000.0, 1.0, 1.0, PX_PER_IN, true, false); _page_bitmaps.add_line( false, _("Default _import resolution:"), _importexport_import_res, _("dpi"), _("Default bitmap resolution (in dots per inch) for bitmap import"), false); + _importexport_import_res_override.init(_("Override file resolution"), "/dialogs/import/forcexdpi", false); + _page_bitmaps.add_line( false, "", _importexport_import_res_override, "", + _("Use default bitmap resolution in favor of information from file")); this->AddPage(_page_bitmaps, _("Bitmaps"), PREFS_PAGE_BITMAPS); } diff --git a/src/ui/dialog/inkscape-preferences.h b/src/ui/dialog/inkscape-preferences.h index 948a3f87b..d60035515 100644 --- a/src/ui/dialog/inkscape-preferences.h +++ b/src/ui/dialog/inkscape-preferences.h @@ -290,6 +290,7 @@ protected: UI::Widget::PrefSpinButton _importexport_export_res; UI::Widget::PrefSpinButton _importexport_import_res; + UI::Widget::PrefCheckButton _importexport_import_res_override; UI::Widget::PrefSlider _snap_delay; UI::Widget::PrefSlider _snap_weight; UI::Widget::PrefCheckButton _font_dialog; @@ -300,6 +301,7 @@ protected: UI::Widget::PrefCheckButton _misc_default_metadata; UI::Widget::PrefCheckButton _misc_forkvectors; UI::Widget::PrefCheckButton _misc_gradienteditor; + UI::Widget::PrefSpinButton _misc_gradientangle; UI::Widget::PrefCheckButton _misc_scripts; UI::Widget::PrefCheckButton _misc_namedicon_delay; diff --git a/src/ui/dialog/layer-properties.cpp b/src/ui/dialog/layer-properties.cpp index 465192aee..35a235dbc 100644 --- a/src/ui/dialog/layer-properties.cpp +++ b/src/ui/dialog/layer-properties.cpp @@ -28,7 +28,10 @@ #include "sp-item.h" #include "verbs.h" #include "selection.h" - +#include "selection-chemistry.h" +#include "ui/icon-names.h" +#include "ui/widget/imagetoggler.h" +#include "event-context.h" namespace Inkscape { namespace UI { @@ -51,7 +54,7 @@ LayerPropertiesDialog::LayerPropertiesDialog() 0, 1, 0, 1, Gtk::FILL, Gtk::FILL); _layout_table.attach(_layer_name_entry, 1, 2, 0, 1, Gtk::FILL | Gtk::EXPAND, Gtk::FILL); - mainVBox->pack_start(_layout_table, false, false, 4); + mainVBox->pack_start(_layout_table, true, true, 4); // Buttons _close_button.set_use_stock(true); @@ -82,6 +85,7 @@ LayerPropertiesDialog::LayerPropertiesDialog() } LayerPropertiesDialog::~LayerPropertiesDialog() { + _setDesktop(NULL); _setLayer(NULL); } @@ -168,6 +172,131 @@ LayerPropertiesDialog::_setup_position_controls() { show_all_children(); } +void +LayerPropertiesDialog::_setup_layers_controls() { + + ModelColumns *zoop = new ModelColumns(); + _model = zoop; + _store = Gtk::TreeStore::create( *zoop ); + _tree.set_model( _store ); + _tree.set_headers_visible(false); + + Inkscape::UI::Widget::ImageToggler *eyeRenderer = manage( new Inkscape::UI::Widget::ImageToggler( + INKSCAPE_ICON("object-visible"), INKSCAPE_ICON("object-hidden")) ); + int visibleColNum = _tree.append_column("vis", *eyeRenderer) - 1; + Gtk::TreeViewColumn* col = _tree.get_column(visibleColNum); + if ( col ) { + col->add_attribute( eyeRenderer->property_active(), _model->_colVisible ); + } + + Inkscape::UI::Widget::ImageToggler * renderer = manage( new Inkscape::UI::Widget::ImageToggler( + INKSCAPE_ICON("object-locked"), INKSCAPE_ICON("object-unlocked")) ); + int lockedColNum = _tree.append_column("lock", *renderer) - 1; + col = _tree.get_column(lockedColNum); + if ( col ) { + col->add_attribute( renderer->property_active(), _model->_colLocked ); + } + + Gtk::CellRendererText *_text_renderer = manage(new Gtk::CellRendererText()); + int nameColNum = _tree.append_column("Name", *_text_renderer) - 1; + Gtk::TreeView::Column *_name_column = _tree.get_column(nameColNum); + _name_column->add_attribute(_text_renderer->property_text(), _model->_colLabel); + + _tree.set_expander_column( *_tree.get_column(nameColNum) ); + _tree.signal_key_press_event().connect( sigc::mem_fun(*this, &LayerPropertiesDialog::_handleKeyEvent), false ); + _tree.signal_button_press_event().connect_notify( sigc::mem_fun(*this, &LayerPropertiesDialog::_handleButtonEvent) ); + + _scroller.add( _tree ); + _scroller.set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC ); + _scroller.set_shadow_type(Gtk::SHADOW_IN); + _scroller.set_size_request(220, 180); + + SPDocument* document = _desktop->doc(); + SPRoot* root = document->getRoot(); + if ( root ) { + SPObject* target = _desktop->currentLayer(); + _store->clear(); + _addLayer( document, (SPObject *)root, 0, target, 0 ); + } + + _layout_table.remove(_layer_name_entry); + _layout_table.remove(_layer_name_label); + + _layout_table.attach(_scroller, + 0, 2, 1, 2, Gtk::FILL | Gtk::EXPAND, Gtk::FILL | Gtk::EXPAND); + show_all_children(); +} + +void LayerPropertiesDialog::_addLayer( SPDocument* doc, SPObject* layer, Gtk::TreeModel::Row* parentRow, SPObject* target, int level ) +{ + int _maxNestDepth = 20; + if ( _desktop && _desktop->layer_manager && layer && (level < _maxNestDepth) ) { + unsigned int counter = _desktop->layer_manager->childCount(layer); + for ( unsigned int i = 0; i < counter; i++ ) { + SPObject *child = _desktop->layer_manager->nthChildOf(layer, i); + if ( child ) { +#if DUMP_LAYERS + g_message(" %3d layer:%p {%s} [%s]", level, child, child->id, child->label() ); +#endif // DUMP_LAYERS + + Gtk::TreeModel::iterator iter = parentRow ? _store->prepend(parentRow->children()) : _store->prepend(); + Gtk::TreeModel::Row row = *iter; + row[_model->_colObject] = child; + row[_model->_colLabel] = child->label() ? child->label() : child->getId(); + row[_model->_colVisible] = SP_IS_ITEM(child) ? !SP_ITEM(child)->isHidden() : false; + row[_model->_colLocked] = SP_IS_ITEM(child) ? SP_ITEM(child)->isLocked() : false; + + if ( target && child == target ) { + _tree.expand_to_path( _store->get_path(iter) ); + + Glib::RefPtr<Gtk::TreeSelection> select = _tree.get_selection(); + select->select(iter); + + //_checkTreeSelection(); + } + + _addLayer( doc, child, &row, target, level + 1 ); + } + } + } +} + +SPObject* LayerPropertiesDialog::_selectedLayer() +{ + SPObject* obj = 0; + + Gtk::TreeModel::iterator iter = _tree.get_selection()->get_selected(); + if ( iter ) { + Gtk::TreeModel::Row row = *iter; + obj = row[_model->_colObject]; + } + + return obj; +} + +bool LayerPropertiesDialog::_handleKeyEvent(GdkEventKey *event) +{ + + switch (get_group0_keyval(event)) { + case GDK_KEY_Return: + case GDK_KEY_KP_Enter: { + _strategy->perform(*this); + _close(); + return true; + } + break; + } + return false; +} + +void LayerPropertiesDialog::_handleButtonEvent(GdkEventButton* event) +{ + if ( (event->type == GDK_2BUTTON_PRESS) && (event->button == 1) ) { + _strategy->perform(*this); + _close(); + } +} + /** Formats the label for a given layer row */ void LayerPropertiesDialog::_prepareLabelRenderer( @@ -231,6 +360,20 @@ void LayerPropertiesDialog::Create::perform(LayerPropertiesDialog &dialog) { desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("New layer created.")); } +void LayerPropertiesDialog::Move::setup(LayerPropertiesDialog &dialog) { + dialog.set_title(_("Move to Layer")); + //TODO: find an unused layer number, forming name from _("Layer ") + "%d" + dialog._layer_name_entry.set_text(_("Layer")); + dialog._apply_button.set_label(_("_Move")); + dialog._setup_layers_controls(); +} + +void LayerPropertiesDialog::Move::perform(LayerPropertiesDialog &dialog) { + + SPObject *moveto = dialog._selectedLayer(); + sp_selection_to_layer(dialog._desktop, moveto, false); +} + void LayerPropertiesDialog::_setDesktop(SPDesktop *desktop) { if (desktop) { Inkscape::GC::anchor (desktop); diff --git a/src/ui/dialog/layer-properties.h b/src/ui/dialog/layer-properties.h index c7d7de130..46b31ad35 100644 --- a/src/ui/dialog/layer-properties.h +++ b/src/ui/dialog/layer-properties.h @@ -18,8 +18,12 @@ #include <gtkmm/table.h> #include <gtkmm/combobox.h> #include <gtkmm/liststore.h> +#include <gtkmm/treeview.h> +#include <gtkmm/treestore.h> +#include <gtkmm/scrolledwindow.h> #include "layer-fns.h" +#include "ui/widget/layer-selector.h" class SPDesktop; @@ -40,6 +44,9 @@ class LayerPropertiesDialog : public Gtk::Dialog { static void showCreate(SPDesktop *desktop, SPObject *layer) { _showDialog(Create::instance(), desktop, layer); } + static void showMove(SPDesktop *desktop, SPObject *layer) { + _showDialog(Move::instance(), desktop, layer); + } protected: struct Strategy { @@ -57,9 +64,15 @@ protected: void setup(LayerPropertiesDialog &dialog); void perform(LayerPropertiesDialog &dialog); }; + struct Move : public Strategy { + static Move &instance() { static Move instance; return instance; } + void setup(LayerPropertiesDialog &dialog); + void perform(LayerPropertiesDialog &dialog); + }; friend class Rename; friend class Create; + friend class Move; Strategy *_strategy; SPDesktop *_desktop; @@ -82,6 +95,31 @@ protected: Gtk::Table _layout_table; bool _position_visible; + class ModelColumns : public Gtk::TreeModel::ColumnRecord + { + public: + + ModelColumns() + { + add(_colObject); + add(_colVisible); + add(_colLocked); + add(_colLabel); + } + virtual ~ModelColumns() {} + + Gtk::TreeModelColumn<SPObject*> _colObject; + Gtk::TreeModelColumn<Glib::ustring> _colLabel; + Gtk::TreeModelColumn<bool> _colVisible; + Gtk::TreeModelColumn<bool> _colLocked; + }; + + Gtk::TreeView _tree; + ModelColumns* _model; + Glib::RefPtr<Gtk::TreeStore> _store; + Gtk::ScrolledWindow _scroller; + + PositionDropdownColumns _dropdown_columns; Gtk::CellRendererText _label_renderer; Glib::RefPtr<Gtk::ListStore> _dropdown_list; @@ -104,8 +142,14 @@ protected: void _close(); void _setup_position_controls(); + void _setup_layers_controls(); void _prepareLabelRenderer(Gtk::TreeModel::const_iterator const &row); + void _addLayer( SPDocument* doc, SPObject* layer, Gtk::TreeModel::Row* parentRow, SPObject* target, int level ); + SPObject* _selectedLayer(); + bool _handleKeyEvent(GdkEventKey *event); + void _handleButtonEvent(GdkEventButton* event); + private: LayerPropertiesDialog(LayerPropertiesDialog const &); // no copy LayerPropertiesDialog &operator=(LayerPropertiesDialog const &); // no assign diff --git a/src/ui/dialog/livepatheffect-add.cpp b/src/ui/dialog/livepatheffect-add.cpp index c22aace37..e899dbcfc 100644 --- a/src/ui/dialog/livepatheffect-add.cpp +++ b/src/ui/dialog/livepatheffect-add.cpp @@ -48,6 +48,7 @@ LivePathEffectAdd::LivePathEffectAdd() : effectlist_treeview.set_model(effectlist_store); effectlist_treeview.set_headers_visible(false); effectlist_treeview.append_column("Name", _columns.name); + //effectlist_treeview.set_activates_default(true); /** * Initialize Effect list @@ -68,7 +69,7 @@ LivePathEffectAdd::LivePathEffectAdd() : * Buttons */ close_button.set_use_stock(true); - close_button.set_can_default(); + //close_button.set_can_default(); add_button.set_use_underline(true); add_button.set_can_default(); diff --git a/src/ui/widget/Makefile_insert b/src/ui/widget/Makefile_insert index 8589f16b0..bbda64648 100644 --- a/src/ui/widget/Makefile_insert +++ b/src/ui/widget/Makefile_insert @@ -19,6 +19,8 @@ ink_common_sources += \ ui/widget/entry.h \ ui/widget/filter-effect-chooser.h \ ui/widget/filter-effect-chooser.cpp \ + ui/widget/gimpspinscale.c \ + ui/widget/gimpspinscale.h \ ui/widget/frame.cpp \ ui/widget/frame.h \ ui/widget/imageicon.cpp \ @@ -62,6 +64,8 @@ ink_common_sources += \ ui/widget/selected-style.cpp \ ui/widget/spinbutton.h \ ui/widget/spinbutton.cpp \ + ui/widget/spin-scale.h \ + ui/widget/spin-scale.cpp \ ui/widget/spin-slider.h \ ui/widget/spin-slider.cpp \ ui/widget/style-subject.h \ diff --git a/src/ui/widget/filter-effect-chooser.cpp b/src/ui/widget/filter-effect-chooser.cpp index 8d6bcf60f..65706a9dc 100644 --- a/src/ui/widget/filter-effect-chooser.cpp +++ b/src/ui/widget/filter-effect-chooser.cpp @@ -22,12 +22,9 @@ namespace UI { namespace Widget { SimpleFilterModifier::SimpleFilterModifier(int flags) - : _hb_blur(false, 0), - _lb_blend(_("Blend mode:")), - _lb_blur(_("_Blur:")), - _lb_blur_unit(_("%")), + : _lb_blend(_("Blend mode:")), _blend(BlendModeConverter, SP_ATTR_INVALID, false), - _blur(0, 0, 100, 1, 0.01, 1) + _blur(_("Blur (%)"), 0, 0, 100, 1, 0.01, 1) { _flags = flags; @@ -37,11 +34,7 @@ SimpleFilterModifier::SimpleFilterModifier(int flags) _hb_blend.pack_start(_blend); } if (flags & BLUR) { - add(_hb_blur); - _lb_blur.set_alignment(Gtk::ALIGN_END, Gtk::ALIGN_CENTER); - _hb_blur.pack_start(_lb_blur, false, false, 0); - _hb_blur.pack_start(_blur, true, true, 0); - _hb_blur.pack_start(_lb_blur_unit, false, false, 3); + add(_blur); } show_all_children(); @@ -49,8 +42,6 @@ SimpleFilterModifier::SimpleFilterModifier(int flags) _hb_blend.set_spacing(12); _lb_blend.set_use_underline(); _lb_blend.set_mnemonic_widget(_blend); - _lb_blur.set_use_underline(); - _lb_blur.set_mnemonic_widget(_blur.get_scale()); _blend.signal_changed().connect(signal_blend_blur_changed()); _blur.signal_value_changed().connect(signal_blend_blur_changed()); } diff --git a/src/ui/widget/filter-effect-chooser.h b/src/ui/widget/filter-effect-chooser.h index 6afb6c180..ae3ec07c4 100644 --- a/src/ui/widget/filter-effect-chooser.h +++ b/src/ui/widget/filter-effect-chooser.h @@ -18,6 +18,7 @@ #include "combo-enums.h" #include "filter-enums.h" #include "spin-slider.h" +#include "spin-scale.h" namespace Inkscape { namespace UI { @@ -45,17 +46,14 @@ public: double get_blur_value() const; void set_blur_value(const double); void set_blur_sensitive(const bool); - Gtk::Label *get_blur_label() { return &_lb_blur; }; - private: int _flags; Gtk::HBox _hb_blend; - Gtk::HBox _hb_blur; - Gtk::Label _lb_blend, _lb_blur, _lb_blur_unit; + Gtk::Label _lb_blend; ComboBoxEnum<Inkscape::Filters::FilterBlendMode> _blend; - SpinSlider _blur; + SpinScale _blur; sigc::signal<void> _signal_blend_blur_changed; }; diff --git a/src/ui/widget/gimpspinscale.c b/src/ui/widget/gimpspinscale.c new file mode 100644 index 000000000..1b7ac7bfe --- /dev/null +++ b/src/ui/widget/gimpspinscale.c @@ -0,0 +1,1089 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * gimpspinscale.c + * Copyright (C) 2010 Michael Natterer <mitch@gimp.org> + * 2012 Øyvind Kolås <pippin@gimp.org> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <math.h> +#include <string.h> +#include <gdk/gdkkeysyms.h> + +#include "gimpspinscale.h" + + +enum +{ + PROP_0, + PROP_LABEL, + PROP_FOCUS_WIDGET +}; + +typedef enum +{ + TARGET_NUMBER, + TARGET_UPPER, + TARGET_LOWER +#if WITH_GTKMM_3_0 + ,TARGET_NONE +#endif +} SpinScaleTarget; + +typedef enum +{ + APPEARANCE_FULL = 1, /* Full size suitable for tablets */ + APPEARANCE_COMPACT, /* Compact, suitable for desktops with mouse control */ +} SpinScaleAppearance; + +typedef struct _GimpSpinScalePrivate GimpSpinScalePrivate; + +struct _GimpSpinScalePrivate +{ + gchar *label; + + gboolean scale_limits_set; + gdouble scale_lower; + gdouble scale_upper; + gdouble gamma; + + PangoLayout *layout; + gboolean changing_value; + gboolean relative_change; + gdouble start_x; + gdouble start_value; + + GtkWidget* focusWidget; + gboolean transferFocus; + SpinScaleAppearance appearanceMode; +}; + +#define GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \ + GIMP_TYPE_SPIN_SCALE, \ + GimpSpinScalePrivate)) + + +static void gimp_spin_scale_dispose (GObject *object); +static void gimp_spin_scale_finalize (GObject *object); +static void gimp_spin_scale_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec); +static void gimp_spin_scale_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec); + +static void gimp_spin_scale_style_set (GtkWidget *widget, + GtkStyle *prev_style); + +#if WITH_GTKMM_3_0 +static void gimp_spin_scale_get_preferred_width (GtkWidget *widget, + gint *minimum_width, + gint *natural_width); +static void gimp_spin_scale_get_preferred_height (GtkWidget *widget, + gint *minimum_width, + gint *natural_width); +static gboolean gimp_spin_scale_draw (GtkWidget *widget, + cairo_t *cr); +#else +static void gimp_spin_scale_size_request (GtkWidget *widget, + GtkRequisition *requisition); + +static gboolean gimp_spin_scale_expose (GtkWidget *widget, + GdkEventExpose *event); +#endif + +static gboolean gimp_spin_scale_button_press (GtkWidget *widget, + GdkEventButton *event); +static gboolean gimp_spin_scale_button_release (GtkWidget *widget, + GdkEventButton *event); +static gboolean gimp_spin_scale_motion_notify (GtkWidget *widget, + GdkEventMotion *event); +static gboolean gimp_spin_scale_leave_notify (GtkWidget *widget, + GdkEventCrossing *event); +static gboolean gimp_spin_scale_keypress( GtkWidget *widget, + GdkEventKey *event); + +static void gimp_spin_scale_defocus( GtkSpinButton *spin_button ); + +static void gimp_spin_scale_value_changed (GtkSpinButton *spin_button); + + +G_DEFINE_TYPE (GimpSpinScale, gimp_spin_scale, GTK_TYPE_SPIN_BUTTON); + +#define parent_class gimp_spin_scale_parent_class + + +static void +gimp_spin_scale_class_init (GimpSpinScaleClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + GtkSpinButtonClass *spin_button_class = GTK_SPIN_BUTTON_CLASS (klass); + + object_class->dispose = gimp_spin_scale_dispose; + object_class->finalize = gimp_spin_scale_finalize; + object_class->set_property = gimp_spin_scale_set_property; + object_class->get_property = gimp_spin_scale_get_property; + + widget_class->style_set = gimp_spin_scale_style_set; +#if WITH_GTKMM_3_0 + widget_class->get_preferred_width = gimp_spin_scale_get_preferred_width; + widget_class->get_preferred_height = gimp_spin_scale_get_preferred_height; + widget_class->draw = gimp_spin_scale_draw; +#else + widget_class->size_request = gimp_spin_scale_size_request; + widget_class->expose_event = gimp_spin_scale_expose; +#endif + widget_class->button_press_event = gimp_spin_scale_button_press; + widget_class->button_release_event = gimp_spin_scale_button_release; + widget_class->motion_notify_event = gimp_spin_scale_motion_notify; + widget_class->leave_notify_event = gimp_spin_scale_leave_notify; + widget_class->key_press_event = gimp_spin_scale_keypress; + + spin_button_class->value_changed = gimp_spin_scale_value_changed; + + g_object_class_install_property (object_class, PROP_LABEL, + g_param_spec_string ("label", NULL, NULL, + NULL, + G_PARAM_READWRITE)); + + g_type_class_add_private (klass, sizeof (GimpSpinScalePrivate)); +} + +static void +gimp_spin_scale_init (GimpSpinScale *scale) +{ + GimpSpinScalePrivate *private = GET_PRIVATE (scale); + + gtk_entry_set_alignment (GTK_ENTRY (scale), 1.0); + gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (scale), TRUE); + + private->gamma = 1.0; + private->focusWidget = NULL; + private->transferFocus = FALSE; + private->appearanceMode = APPEARANCE_COMPACT; +} + +static void +gimp_spin_scale_dispose (GObject *object) +{ + GimpSpinScalePrivate *private = GET_PRIVATE (object); + + if (private->layout) + { + g_object_unref (private->layout); + private->layout = NULL; + } + + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +gimp_spin_scale_finalize (GObject *object) +{ + GimpSpinScalePrivate *private = GET_PRIVATE (object); + + if (private->label) + { + g_free (private->label); + private->label = NULL; + } + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +gimp_spin_scale_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + GimpSpinScalePrivate *private = GET_PRIVATE (object); + + switch (property_id) + { + case PROP_LABEL: + g_free (private->label); + private->label = g_value_dup_string (value); + if (private->layout) + { + g_object_unref (private->layout); + private->layout = NULL; + } + gtk_widget_queue_resize (GTK_WIDGET (object)); + break; + + case PROP_FOCUS_WIDGET: + { + /* TODO unhook prior */ + private->focusWidget = (GtkWidget*)g_value_get_pointer( value ); + } + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +gimp_spin_scale_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + GimpSpinScalePrivate *private = GET_PRIVATE (object); + + switch (property_id) + { + case PROP_LABEL: + g_value_set_string (value, private->label); + break; + + case PROP_FOCUS_WIDGET: + g_value_set_pointer( value, private->focusWidget ); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + + +void +gimp_spin_scale_set_focuswidget( GtkWidget *scale, GtkWidget* widget ) +{ + GimpSpinScalePrivate *private = GET_PRIVATE (scale); + + /* TODO unhook prior */ + + private->focusWidget = widget; +} + +void +gimp_spin_scale_set_appearance( GtkWidget *widget, const gchar *appearance) +{ + GimpSpinScalePrivate *private = GET_PRIVATE (widget); + + if ( strcmp("full", appearance) == 0 ) { + private->appearanceMode = APPEARANCE_FULL; + } else if ( strcmp("compact", appearance) == 0 ) { + private->appearanceMode = APPEARANCE_COMPACT; + } +} + +static void +#if WITH_GTKMM_3_0 +gimp_spin_scale_get_preferred_width (GtkWidget *widget, + gint *minimum_width, + gint *natural_width) +#else +gimp_spin_scale_size_request (GtkWidget *widget, + GtkRequisition *requisition) +#endif +{ + GimpSpinScalePrivate *private = GET_PRIVATE (widget); + GtkStyle *style = gtk_widget_get_style (widget); + PangoContext *context = gtk_widget_get_pango_context (widget); + PangoFontMetrics *metrics; + +#if WITH_GTKMM_3_0 + GTK_WIDGET_CLASS (parent_class)->get_preferred_width (widget, + minimum_width, + natural_width); +#else + gint height; + GTK_WIDGET_CLASS (parent_class)->size_request (widget, requisition); +#endif + + metrics = pango_context_get_metrics (context, style->font_desc, + pango_context_get_language (context)); + +#if WITH_GTKMM_3_0 +#else + height = PANGO_PIXELS (pango_font_metrics_get_ascent (metrics) + + pango_font_metrics_get_descent (metrics)); + + if (private->appearanceMode == APPEARANCE_COMPACT) { + requisition->height += 1; + } else { + requisition->height += height; + } + +#endif + + + if (private->label) + { + gint char_width; + gint digit_width; + gint char_pixels; + + char_width = pango_font_metrics_get_approximate_char_width (metrics); + digit_width = pango_font_metrics_get_approximate_digit_width (metrics); + char_pixels = PANGO_PIXELS (MAX (char_width, digit_width)); + +#if WITH_GTKMM_3_0 + *minimum_width += char_pixels * 3; + *natural_width += char_pixels * 3; +#else + /* ~3 chars for the ellipses */ + requisition->width += char_pixels * 3; +#endif + + } + + pango_font_metrics_unref (metrics); +} + +#if WITH_GTKMM_3_0 +static void +gimp_spin_scale_get_preferred_height (GtkWidget *widget, + gint *minimum_height, + gint *natural_height) +{ + GtkStyle *style = gtk_widget_get_style (widget); + PangoContext *context = gtk_widget_get_pango_context (widget); + PangoFontMetrics *metrics; + //gint height; + + GTK_WIDGET_CLASS (parent_class)->get_preferred_height (widget, + minimum_height, + natural_height); + + metrics = pango_context_get_metrics (context, style->font_desc, + pango_context_get_language (context)); + + //height = PANGO_PIXELS (pango_font_metrics_get_ascent (metrics) + + // pango_font_metrics_get_descent (metrics)); + + *minimum_height += 1; + *natural_height += 1; + + pango_font_metrics_unref (metrics); +} +#endif + +static void +gimp_spin_scale_style_set (GtkWidget *widget, + GtkStyle *prev_style) +{ + GimpSpinScalePrivate *private = GET_PRIVATE (widget); + + GTK_WIDGET_CLASS (parent_class)->style_set (widget, prev_style); + + if (private->layout) + { + g_object_unref (private->layout); + private->layout = NULL; + } +} + + +static gboolean + +#if WITH_GTKMM_3_0 + gimp_spin_scale_draw (GtkWidget *widget, cairo_t *cr) +#else + gimp_spin_scale_expose (GtkWidget *widget, GdkEventExpose *event) +#endif +{ + GimpSpinScalePrivate *private = GET_PRIVATE (widget); + GtkStyle *style = gtk_widget_get_style (widget); + + +#if WITH_GTKMM_3_0 + GtkAllocation allocation; + + cairo_save (cr); + GTK_WIDGET_CLASS (parent_class)->draw (widget, cr); + cairo_restore (cr); + + gtk_widget_get_allocation (widget, &allocation); + + +#else + cairo_t *cr; + gint w; + + GTK_WIDGET_CLASS (parent_class)->expose_event (widget, event); + + cr = gdk_cairo_create (event->window); + gdk_cairo_region (cr, event->region); + cairo_clip (cr); + + w = gdk_window_get_width (event->window); + +#endif + + cairo_set_line_width (cr, 1.0); + + +#if WITH_GTKMM_3_0 + if (private->label) + { + GdkRectangle text_area; + gint minimum_width; + gint natural_width; +#else + if (private->label && + gtk_widget_is_drawable (widget) && + event->window == gtk_entry_get_text_window (GTK_ENTRY (widget))) + { + GtkRequisition requisition; + GtkAllocation allocation; +#endif + + PangoRectangle logical; + gint layout_offset_x; + gint layout_offset_y; + +#if WITH_GTKMM_3_0 + gtk_entry_get_text_area (GTK_ENTRY (widget), &text_area); + + GTK_WIDGET_CLASS (parent_class)->get_preferred_width (widget, + &minimum_width, + &natural_width); +#else + GTK_WIDGET_CLASS (parent_class)->size_request (widget, &requisition); + gtk_widget_get_allocation (widget, &allocation); +#endif + + if (! private->layout) + { + private->layout = gtk_widget_create_pango_layout (widget, + private->label); + pango_layout_set_ellipsize (private->layout, PANGO_ELLIPSIZE_END); + } + + pango_layout_set_width (private->layout, + PANGO_SCALE * +#if WITH_GTKMM_3_0 + (allocation.width - minimum_width + 10)); +#else + (allocation.width - requisition.width + 10)); +#endif + pango_layout_get_pixel_extents (private->layout, NULL, &logical); + + gtk_entry_get_layout_offsets (GTK_ENTRY (widget), NULL, &layout_offset_y); + + if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) +#if WITH_GTKMM_3_0 + layout_offset_x = text_area.x + text_area.width - logical.width - 4; +#else + layout_offset_x = w - logical.width - 4; +#endif + else + layout_offset_x = 4; + + layout_offset_x -= logical.x; + +#if WITH_GTKMM_3_0 + cairo_move_to (cr, layout_offset_x, text_area.y + layout_offset_y-3); +#else + cairo_move_to (cr, layout_offset_x, layout_offset_y-3); +#endif + + gdk_cairo_set_source_color (cr, + &style->text[gtk_widget_get_state (widget)]); + + pango_cairo_show_layout (cr, private->layout); + } + +#if WITH_GTKMM_3_0 +#else + cairo_destroy (cr); +#endif + + return FALSE; +} + +#if WITH_GTKMM_3_0 +/* Returns TRUE if a translation should be done */ +static gboolean +gtk_widget_get_translation_to_window (GtkWidget *widget, + GdkWindow *window, + int *x, + int *y) +{ + GdkWindow *w, *widget_window; + + if (!gtk_widget_get_has_window (widget)) + { + GtkAllocation allocation; + + gtk_widget_get_allocation (widget, &allocation); + + *x = -allocation.x; + *y = -allocation.y; + } + else + { + *x = 0; + *y = 0; + } + + widget_window = gtk_widget_get_window (widget); + + for (w = window; w && w != widget_window; w = gdk_window_get_parent (w)) + { + int wx, wy; + gdk_window_get_position (w, &wx, &wy); + *x += wx; + *y += wy; + } + + if (w == NULL) + { + *x = 0; + *y = 0; + return FALSE; + } + + return TRUE; +} + +static void +gimp_spin_scale_event_to_widget_coords (GtkWidget *widget, + GdkWindow *window, + gdouble event_x, + gdouble event_y, + gint *widget_x, + gint *widget_y) +{ + gint tx, ty; + + if (gtk_widget_get_translation_to_window (widget, window, &tx, &ty)) + { + event_x += tx; + event_y += ty; + } + + *widget_x = event_x; + *widget_y = event_y; +} +#endif + +static SpinScaleTarget +gimp_spin_scale_get_target (GtkWidget *widget, + gdouble x, + gdouble y) +{ + GtkAllocation allocation; + PangoRectangle logical; + gint layout_x; + gint layout_y; + + gtk_widget_get_allocation (widget, &allocation); + gtk_entry_get_layout_offsets (GTK_ENTRY (widget), &layout_x, &layout_y); + pango_layout_get_pixel_extents (gtk_entry_get_layout (GTK_ENTRY (widget)), + NULL, &logical); + +#if WITH_GTKMM_3_0 + GdkRectangle text_area; + gtk_entry_get_text_area (GTK_ENTRY (widget), &text_area); + + if (x >= text_area.x && x < text_area.width && + y >= text_area.y && y < text_area.height) + { + x -= text_area.x; + y -= text_area.y; + + if (x > layout_x && x < layout_x + logical.width && + y > layout_y && y < layout_y + logical.height) + { + return TARGET_NUMBER; + } + else if (y > text_area.height / 2) + { + return TARGET_LOWER; + } + + return TARGET_UPPER; + } + + return TARGET_NONE; +#else + if (x > layout_x && x < layout_x + logical.width && + y > layout_y && y < layout_y + logical.height) + { + return TARGET_NUMBER; + } + + else if (y > allocation.height / 2) + { + return TARGET_LOWER; + } + return TARGET_UPPER; +#endif +} + +static void +gimp_spin_scale_get_limits (GimpSpinScale *scale, + gdouble *lower, + gdouble *upper) +{ + GimpSpinScalePrivate *private = GET_PRIVATE (scale); + + if (private->scale_limits_set) + { + *lower = private->scale_lower; + *upper = private->scale_upper; + } + else + { + GtkSpinButton *spin_button = GTK_SPIN_BUTTON (scale); + GtkAdjustment *adjustment = gtk_spin_button_get_adjustment (spin_button); + + *lower = gtk_adjustment_get_lower (adjustment); + *upper = gtk_adjustment_get_upper (adjustment); + } +} + +static void +gimp_spin_scale_change_value (GtkWidget *widget, + gdouble x) +{ + GimpSpinScalePrivate *private = GET_PRIVATE (widget); + GtkSpinButton *spin_button = GTK_SPIN_BUTTON (widget); + GtkAdjustment *adjustment = gtk_spin_button_get_adjustment (spin_button); + gdouble lower; + gdouble upper; + gdouble value; +#if WITH_GTKMM_3_0 +#else +#endif +#if WITH_GTKMM_3_0 + GdkRectangle text_area; + gtk_entry_get_text_area (GTK_ENTRY (widget), &text_area); + gimp_spin_scale_get_limits (GIMP_SPIN_SCALE (widget), &lower, &upper); +#else + GdkWindow *text_window = gtk_entry_get_text_window (GTK_ENTRY (widget)); + gint width; + + gimp_spin_scale_get_limits (GIMP_SPIN_SCALE (widget), &lower, &upper); + width = gdk_window_get_width (text_window); + +#endif + + + if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) +#if WITH_GTKMM_3_0 + x = text_area.width - x; +#else + x = width - x; +#endif + + + if (private->relative_change) + { + gdouble diff; + gdouble step; + + +#if WITH_GTKMM_3_0 + step = (upper - lower) / text_area.width / 10.0; +#else + step = (upper - lower) / width / 10.0; +#endif + if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) + +#if WITH_GTKMM_3_0 + diff = x - (text_area.width - private->start_x); +#else + diff = x - (width - private->start_x); +#endif + else + diff = x - private->start_x; + + value = (private->start_value + diff * step); + } + else + { + gdouble fraction; + + +#if WITH_GTKMM_3_0 + fraction = x / (gdouble) text_area.width; +#else + fraction = x / (gdouble) width; +#endif + if (fraction > 0.0) + fraction = pow (fraction, private->gamma); + + value = fraction * (upper - lower) + lower; + } + + gtk_adjustment_set_value (adjustment, value); +} + +static gboolean +gimp_spin_scale_button_press (GtkWidget *widget, + GdkEventButton *event) +{ + GimpSpinScalePrivate *private = GET_PRIVATE (widget); + + private->changing_value = FALSE; + private->relative_change = FALSE; + +#if WITH_GTKMM_3_0 + gint x, y; + gimp_spin_scale_event_to_widget_coords (widget, event->window, + event->x, event->y, + &x, &y); + switch (gimp_spin_scale_get_target (widget, x, y)) + { + case TARGET_UPPER: + private->changing_value = TRUE; + + gtk_widget_grab_focus (widget); + + gimp_spin_scale_change_value (widget, x); + + return TRUE; + + case TARGET_LOWER: + private->changing_value = TRUE; + + gtk_widget_grab_focus (widget); + + private->relative_change = TRUE; + private->start_x = x; + private->start_value = gtk_adjustment_get_value (gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (widget))); + + return TRUE; + + default: + break; + } +#else + if (event->window == gtk_entry_get_text_window (GTK_ENTRY (widget))) + { + switch (gimp_spin_scale_get_target (widget, event->x, event->y)) + { + case TARGET_UPPER: + private->changing_value = TRUE; + + gtk_widget_grab_focus (widget); + + gimp_spin_scale_change_value (widget, event->x); + + return TRUE; + + case TARGET_LOWER: + private->changing_value = TRUE; + + gtk_widget_grab_focus (widget); + + private->relative_change = TRUE; + private->start_x = event->x; + private->start_value = gtk_adjustment_get_value (gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (widget))); + + return TRUE; + + default: + break; + } + } +#endif + + return GTK_WIDGET_CLASS (parent_class)->button_press_event (widget, event); +} + +static gboolean +gimp_spin_scale_button_release (GtkWidget *widget, + GdkEventButton *event) +{ + GimpSpinScalePrivate *private = GET_PRIVATE (widget); +#if WITH_GTKMM_3_0 + gint x, y; + + gimp_spin_scale_event_to_widget_coords (widget, event->window, + event->x, event->y, + &x, &y); +#endif + + if (private->changing_value) + { + private->changing_value = FALSE; +#if WITH_GTKMM_3_0 + gimp_spin_scale_change_value (widget, x); +#else + gimp_spin_scale_change_value (widget, event->x); +#endif + return TRUE; + } + + return GTK_WIDGET_CLASS (parent_class)->button_release_event (widget, event); +} + +static gboolean +gimp_spin_scale_motion_notify (GtkWidget *widget, + GdkEventMotion *event) +{ + GimpSpinScalePrivate *private = GET_PRIVATE (widget); +#if WITH_GTKMM_3_0 + gint x, y; + + gimp_spin_scale_event_to_widget_coords (widget, event->window, + event->x, event->y, + &x, &y); +#endif + + if (private->changing_value) + { +#if WITH_GTKMM_3_0 + gimp_spin_scale_change_value (widget, x); +#else + gimp_spin_scale_change_value (widget, event->x); +#endif + + return TRUE; + } + + GTK_WIDGET_CLASS (parent_class)->motion_notify_event (widget, event); + + if (! (event->state & + (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK)) +#if WITH_GTKMM_3_0 +#else + && event->window == gtk_entry_get_text_window (GTK_ENTRY (widget)) +#endif + ) + { + GdkDisplay *display = gtk_widget_get_display (widget); + GdkCursor *cursor = NULL; + +#if WITH_GTKMM_3_0 + switch (gimp_spin_scale_get_target (widget, x, y)) +#else + switch (gimp_spin_scale_get_target (widget, event->x, event->y)) +#endif + { + case TARGET_NUMBER: + cursor = gdk_cursor_new_for_display (display, GDK_XTERM); + break; + + case TARGET_UPPER: + cursor = gdk_cursor_new_for_display (display, GDK_SB_UP_ARROW); + break; + + case TARGET_LOWER: + cursor = gdk_cursor_new_for_display (display, GDK_SB_H_DOUBLE_ARROW); + break; + + default: + break; + } + + +#if WITH_GTKMM_3_0 + if (cursor) + { + gdk_window_set_cursor (event->window, cursor); + g_object_unref (cursor); + } +#else + gdk_window_set_cursor (event->window, cursor); + gdk_cursor_unref (cursor); +#endif + } + + return FALSE; +} + +static gboolean +gimp_spin_scale_leave_notify (GtkWidget *widget, + GdkEventCrossing *event) +{ + gdk_window_set_cursor (event->window, NULL); + + return GTK_WIDGET_CLASS (parent_class)->leave_notify_event (widget, event); +} + +gboolean gimp_spin_scale_keypress( GtkWidget *widget, GdkEventKey *event) +{ + GimpSpinScalePrivate *private = GET_PRIVATE (widget); + guint key = 0; + gdk_keymap_translate_keyboard_state( gdk_keymap_get_for_display( gdk_display_get_default() ), + event->hardware_keycode, (GdkModifierType)event->state, + 0, &key, 0, 0, 0 ); + + switch ( key ) { + + case GDK_KEY_Escape: + case GDK_KEY_Return: + case GDK_KEY_KP_Enter: + { + private->transferFocus = TRUE; + gimp_spin_scale_defocus( GTK_SPIN_BUTTON(widget) ); + } + break; + + } + + return GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, event); +} + +static void +gimp_spin_scale_defocus( GtkSpinButton *spin_button ) +{ + GimpSpinScalePrivate *private = GET_PRIVATE (spin_button); + + if ( private->transferFocus ) { + if ( private->focusWidget ) { + gtk_widget_grab_focus( private->focusWidget ); + } + } +} + +static void +gimp_spin_scale_value_changed (GtkSpinButton *spin_button) +{ + GtkAdjustment *adjustment = gtk_spin_button_get_adjustment (spin_button); + GimpSpinScalePrivate *private = GET_PRIVATE (spin_button); + gdouble lower; + gdouble upper; + gdouble value; + + gimp_spin_scale_get_limits (GIMP_SPIN_SCALE (spin_button), &lower, &upper); + + value = CLAMP (gtk_adjustment_get_value (adjustment), lower, upper); + + + gtk_entry_set_progress_fraction (GTK_ENTRY (spin_button), + pow ((value - lower) / (upper - lower), + 1.0 / private->gamma)); + + // TODO - Allow scrollwheel to change value then return focus, + // but clicks/keypress should keep focus in the control + //if ( gtk_widget_has_focus( GTK_WIDGET(spin_button) ) ) { + // gimp_spin_scale_defocus( spin_button ); + //} +} + + +/* public functions */ + +GtkWidget * +gimp_spin_scale_new (GtkAdjustment *adjustment, + const gchar *label, + gint digits) +{ + g_return_val_if_fail (GTK_IS_ADJUSTMENT (adjustment), NULL); + + return g_object_new (GIMP_TYPE_SPIN_SCALE, + "adjustment", adjustment, + "label", label, + "digits", digits, + NULL); +} + +void +gimp_spin_scale_set_scale_limits (GimpSpinScale *scale, + gdouble lower, + gdouble upper) +{ + GimpSpinScalePrivate *private; + GtkSpinButton *spin_button; + GtkAdjustment *adjustment; + + g_return_if_fail (GIMP_IS_SPIN_SCALE (scale)); + + private = GET_PRIVATE (scale); + spin_button = GTK_SPIN_BUTTON (scale); + adjustment = gtk_spin_button_get_adjustment (spin_button); + + g_return_if_fail (lower >= gtk_adjustment_get_lower (adjustment)); + g_return_if_fail (upper <= gtk_adjustment_get_upper (adjustment)); + + private->scale_limits_set = TRUE; + private->scale_lower = lower; + private->scale_upper = upper; + private->gamma = 1.0; + + gimp_spin_scale_value_changed (spin_button); +} + +void +gimp_spin_scale_set_gamma (GimpSpinScale *scale, + gdouble gamma) +{ + GimpSpinScalePrivate *private; + + g_return_if_fail (GIMP_IS_SPIN_SCALE (scale)); + + private = GET_PRIVATE (scale); + + private->gamma = gamma; + + gimp_spin_scale_value_changed (GTK_SPIN_BUTTON (scale)); +} + +gdouble +gimp_spin_scale_get_gamma (GimpSpinScale *scale) +{ + GimpSpinScalePrivate *private; + + g_return_val_if_fail (GIMP_IS_SPIN_SCALE (scale), 1.0); + + private = GET_PRIVATE (scale); + + return private->gamma; +} + +void +gimp_spin_scale_unset_scale_limits (GimpSpinScale *scale) +{ + GimpSpinScalePrivate *private; + + g_return_if_fail (GIMP_IS_SPIN_SCALE (scale)); + + private = GET_PRIVATE (scale); + + private->scale_limits_set = FALSE; + private->scale_lower = 0.0; + private->scale_upper = 0.0; + + gimp_spin_scale_value_changed (GTK_SPIN_BUTTON (scale)); +} + +gboolean +gimp_spin_scale_get_scale_limits (GimpSpinScale *scale, + gdouble *lower, + gdouble *upper) +{ + GimpSpinScalePrivate *private; + + g_return_val_if_fail (GIMP_IS_SPIN_SCALE (scale), FALSE); + + private = GET_PRIVATE (scale); + + if (lower) + *lower = private->scale_lower; + + if (upper) + *upper = private->scale_upper; + + return private->scale_limits_set; +} diff --git a/src/ui/widget/gimpspinscale.h b/src/ui/widget/gimpspinscale.h new file mode 100644 index 000000000..ad63625ac --- /dev/null +++ b/src/ui/widget/gimpspinscale.h @@ -0,0 +1,76 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * gimpspinscale.h + * Copyright (C) 2010 Michael Natterer <mitch@gimp.org> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __GIMP_SPIN_SCALE_H__ +#define __GIMP_SPIN_SCALE_H__ + +#ifndef WITH_GIMP +#include <gtk/gtk.h> +#endif + +G_BEGIN_DECLS + +#define GIMP_TYPE_SPIN_SCALE (gimp_spin_scale_get_type ()) +#define GIMP_SPIN_SCALE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_SPIN_SCALE, GimpSpinScale)) +#define GIMP_SPIN_SCALE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_SPIN_SCALE, GimpSpinScaleClass)) +#define GIMP_IS_SPIN_SCALE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_SPIN_SCALE)) +#define GIMP_IS_SPIN_SCALE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_SPIN_SCALE)) +#define GIMP_SPIN_SCALE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_SPIN_SCALE, GimpSpinScaleClass)) + + +typedef struct _GimpSpinScale GimpSpinScale; +typedef struct _GimpSpinScaleClass GimpSpinScaleClass; + +struct _GimpSpinScale +{ + GtkSpinButton parent_instance; +}; + +struct _GimpSpinScaleClass +{ + GtkSpinButtonClass parent_class; +}; + + +GType gimp_spin_scale_get_type (void) G_GNUC_CONST; + +GtkWidget * gimp_spin_scale_new (GtkAdjustment *adjustment, + const gchar *label, + gint digits); + +void gimp_spin_scale_set_scale_limits (GimpSpinScale *scale, + gdouble lower, + gdouble upper); +void gimp_spin_scale_unset_scale_limits (GimpSpinScale *scale); +gboolean gimp_spin_scale_get_scale_limits (GimpSpinScale *scale, + gdouble *lower, + gdouble *upper); + +void gimp_spin_scale_set_gamma (GimpSpinScale *scale, + gdouble gamma); +gdouble gimp_spin_scale_get_gamma (GimpSpinScale *scale); + +void gimp_spin_scale_set_focuswidget( GtkWidget *scale, GtkWidget* widget ); + +void gimp_spin_scale_set_appearance( GtkWidget *scale, const gchar *appearance); + +G_END_DECLS + +#endif /* __GIMP_SPIN_SCALE_H__ */ diff --git a/src/ui/widget/layer-selector.cpp b/src/ui/widget/layer-selector.cpp index c6622627b..a80a1aba0 100644 --- a/src/ui/widget/layer-selector.cpp +++ b/src/ui/widget/layer-selector.cpp @@ -185,7 +185,10 @@ void LayerSelector::setDesktop(SPDesktop *desktop) { if (_desktop) { // _desktop_shutdown_connection.disconnect(); - _layer_changed_connection.disconnect(); + if (_current_layer_changed_connection) + _current_layer_changed_connection.disconnect(); + if (_layers_changed_connection) + _layers_changed_connection.disconnect(); // g_signal_handlers_disconnect_by_func(_desktop, (gpointer)&detach, this); } _desktop = desktop; @@ -195,9 +198,13 @@ void LayerSelector::setDesktop(SPDesktop *desktop) { // sigc::bind (sigc::ptr_fun (detach), this)); // g_signal_connect_after(_desktop, "shutdown", GCallback(detach), this); - _layer_changed_connection = _desktop->connectCurrentLayerChanged( - sigc::mem_fun(*this, &LayerSelector::_selectLayer) - ); + LayerManager *mgr = _desktop->layer_manager; + if ( mgr ) { + _current_layer_changed_connection = mgr->connectCurrentLayerChanged( sigc::mem_fun(*this, &LayerSelector::_selectLayer) ); + //_layerUpdatedConnection = mgr->connectLayerDetailsChanged( sigc::mem_fun(*this, &LayerSelector::_updateLayer) ); + _layers_changed_connection = mgr->connectChanged( sigc::mem_fun(*this, &LayerSelector::_layersChanged) ); + } + _selectLayer(_desktop->currentLayer()); } } @@ -230,6 +237,11 @@ private: } +void LayerSelector::_layersChanged() +{ + //_selectLayer(_desktop->currentLayer()); +} + /** Selects the given layer in the dropdown selector. */ void LayerSelector::_selectLayer(SPObject *layer) { @@ -300,11 +312,13 @@ void LayerSelector::_setDesktopLayer() { Gtk::ListStore::iterator selected(_selector.get_active()); SPObject *layer=_selector.get_active()->get_value(_model_columns.object); if ( _desktop && layer ) { - _layer_changed_connection.block(); + _current_layer_changed_connection.block(); + _layers_changed_connection.block(); _desktop->layer_manager->setCurrentLayer(layer); - _layer_changed_connection.unblock(); + _current_layer_changed_connection.unblock(); + _layers_changed_connection.unblock(); _selectLayer(_desktop->currentLayer()); } diff --git a/src/ui/widget/layer-selector.h b/src/ui/widget/layer-selector.h index 6fbdc9857..ff9e4ddfc 100644 --- a/src/ui/widget/layer-selector.h +++ b/src/ui/widget/layer-selector.h @@ -68,7 +68,8 @@ private: Glib::RefPtr<Gtk::ListStore> _layer_model; // sigc::connection _desktop_shutdown_connection; - sigc::connection _layer_changed_connection; + sigc::connection _layers_changed_connection; + sigc::connection _current_layer_changed_connection; sigc::connection _selection_changed_connection; sigc::connection _visibility_toggled_connection; sigc::connection _lock_toggled_connection; @@ -76,6 +77,8 @@ private: SPObject *_layer; void _selectLayer(SPObject *layer); + void _layersChanged(); + void _setDesktopLayer(); void _buildEntry(unsigned depth, SPObject &object); diff --git a/src/ui/widget/object-composite-settings.cpp b/src/ui/widget/object-composite-settings.cpp index 1cb384501..2789676ea 100644 --- a/src/ui/widget/object-composite-settings.cpp +++ b/src/ui/widget/object-composite-settings.cpp @@ -16,6 +16,7 @@ #include <glibmm/i18n.h> +#include "desktop.h" #include "desktop-handles.h" #include "desktop-style.h" #include "document.h" @@ -32,6 +33,7 @@ #include "ui/icon-names.h" #include "display/sp-canvas.h" #include "ui/widget/style-subject.h" +#include "ui/widget/gimpspinscale.h" namespace Inkscape { namespace UI { @@ -62,50 +64,34 @@ ObjectCompositeSettings::ObjectCompositeSettings(unsigned int verb_code, char co _blur_tag(Glib::ustring(history_prefix) + ":blur"), _opacity_tag(Glib::ustring(history_prefix) + ":opacity"), _opacity_vbox(false, 0), - _opacity_label(_("Opacity:")), - _opacity_label_unit(_("%")), -#if WITH_GTKMM_3_0 - _opacity_adjustment(Gtk::Adjustment::create(100.0, 0.0, 100.0, 1.0, 1.0, 0.0)), -#else - _opacity_adjustment(100.0, 0.0, 100.0, 1.0, 1.0, 0.0), -#endif - _opacity_hscale(_opacity_adjustment), - _opacity_spin_button(_opacity_adjustment, 0.01, 1), + _opacity_scale(_("Opacity (%)"), 100.0, 0.0, 100.0, 1.0, 1.0, 1), _fe_cb(flags), _fe_vbox(false, 0), - _fe_alignment(1, 1, 1, 1), _blocked(false) { // Filter Effects pack_start(_fe_vbox, false, false, 2); - _fe_alignment.set_padding(0, 0, 4, 0); - _fe_alignment.add(_fe_cb); - _fe_vbox.pack_start(_fe_alignment, false, false, 0); + _fe_vbox.pack_start(_fe_cb, false, false, 0); _fe_cb.signal_blend_blur_changed().connect(sigc::mem_fun(*this, &ObjectCompositeSettings::_blendBlurValueChanged)); // Opacity pack_start(_opacity_vbox, false, false, 2); - _opacity_label.set_alignment(Gtk::ALIGN_END, Gtk::ALIGN_CENTER); - _opacity_hbox.pack_start(_opacity_label, false, false, 3); - //_opacity_vbox.pack_start(_opacity_label_box, false, false, 0); - _opacity_vbox.pack_start(_opacity_hbox, false, false, 0); - _opacity_hbox.pack_start(_opacity_hscale, true, true, 0); - _opacity_hbox.pack_start(_opacity_spin_button, false, false, 0); - _opacity_hbox.pack_start(_opacity_label_unit, false, false, 3); - _opacity_hscale.set_draw_value(false); -#if WITH_GTKMM_3_0 - _opacity_adjustment->signal_value_changed().connect(sigc::mem_fun(*this, &ObjectCompositeSettings::_opacityValueChanged)); - _opacity_label.set_mnemonic_widget(_opacity_hscale); -#else - _opacity_adjustment.signal_value_changed().connect(sigc::mem_fun(*this, &ObjectCompositeSettings::_opacityValueChanged)); - _opacity_label.set_mnemonic_widget(_opacity_hscale); -#endif + _opacity_vbox.pack_start(_opacity_scale); + + _opacity_scale.set_appearance("compact"); + + _opacity_scale.signal_value_changed().connect(sigc::mem_fun(*this, &ObjectCompositeSettings::_opacityValueChanged)); + + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + _opacity_scale.set_focuswidget(GTK_WIDGET(desktop->canvas)); /* SizeGroup keeps the blur and opacity labels aligned in Fill & Stroke dlg */ +/* GtkSizeGroup *labels = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); gtk_size_group_add_widget(labels, (GtkWidget *) _opacity_label.gobj()); gtk_size_group_add_widget(labels, (GtkWidget *) _fe_cb.get_blur_label()->gobj()); +*/ show_all_children(); @@ -223,11 +209,7 @@ ObjectCompositeSettings::_opacityValueChanged() SPCSSAttr *css = sp_repr_css_attr_new (); Inkscape::CSSOStringStream os; -#if WITH_GTKMM_3_0 - os << CLAMP (_opacity_adjustment->get_value() / 100, 0.0, 1.0); -#else - os << CLAMP (_opacity_adjustment.get_value() / 100, 0.0, 1.0); -#endif + os << CLAMP (_opacity_scale.get_adjustment()->get_value() / 100, 0.0, 1.0); sp_repr_css_set_property (css, "opacity", os.str().c_str()); _subject->setCSS(css); @@ -263,18 +245,14 @@ ObjectCompositeSettings::_subjectChanged() { switch (result) { case QUERY_STYLE_NOTHING: - _opacity_hbox.set_sensitive(false); + _opacity_vbox.set_sensitive(false); // gtk_widget_set_sensitive (opa, FALSE); break; case QUERY_STYLE_SINGLE: case QUERY_STYLE_MULTIPLE_AVERAGED: // TODO: treat this slightly differently case QUERY_STYLE_MULTIPLE_SAME: - _opacity_hbox.set_sensitive(true); -#if WITH_GTKMM_3_0 - _opacity_adjustment->set_value(100 * SP_SCALE24_TO_FLOAT(query->opacity.value)); -#else - _opacity_adjustment.set_value(100 * SP_SCALE24_TO_FLOAT(query->opacity.value)); -#endif + _opacity_vbox.set_sensitive(true); + _opacity_scale.get_adjustment()->set_value(100 * SP_SCALE24_TO_FLOAT(query->opacity.value)); break; } diff --git a/src/ui/widget/object-composite-settings.h b/src/ui/widget/object-composite-settings.h index 32da626d6..d3a208525 100644 --- a/src/ui/widget/object-composite-settings.h +++ b/src/ui/widget/object-composite-settings.h @@ -45,22 +45,12 @@ private: Glib::ustring _opacity_tag; Gtk::VBox _opacity_vbox; - Gtk::HBox _opacity_hbox; - Gtk::Label _opacity_label; - Gtk::Label _opacity_label_unit; -#if WITH_GTKMM_3_0 - Glib::RefPtr<Gtk::Adjustment> _opacity_adjustment; -#else - Gtk::Adjustment _opacity_adjustment; -#endif - Gtk::HScale _opacity_hscale; - Inkscape::UI::Widget::SpinButton _opacity_spin_button; + Inkscape::UI::Widget::SpinScale _opacity_scale; StyleSubject *_subject; SimpleFilterModifier _fe_cb; Gtk::VBox _fe_vbox; - Gtk::Alignment _fe_alignment; bool _blocked; gulong _desktop_activated; diff --git a/src/ui/widget/selected-style.cpp b/src/ui/widget/selected-style.cpp index a37f36eea..a4313f677 100644 --- a/src/ui/widget/selected-style.cpp +++ b/src/ui/widget/selected-style.cpp @@ -48,6 +48,7 @@ #include "pixmaps/cursor-adj-s.xpm" #include "pixmaps/cursor-adj-l.xpm" #include "sp-cursor.h" +#include "gradient-chemistry.h" static gdouble const _sw_presets[] = { 32 , 16 , 10 , 8 , 6 , 4 , 3 , 2 , 1.5 , 1 , 0.75 , 0.5 , 0.25 , 0.1 }; static gchar const *const _sw_presets_str[] = {"32", "16", "10", "8", "6", "4", "3", "2", "1.5", "1", "0.75", "0.5", "0.25", "0.1"}; @@ -598,6 +599,12 @@ void SelectedStyle::on_fill_invert() { SPCSSAttr *css = sp_repr_css_attr_new (); guint32 color = _thisselected[SS_FILL]; gchar c[64]; + if (_mode[SS_FILL] == SS_LGRADIENT || _mode[SS_FILL] == SS_RGRADIENT) { + sp_gradient_invert_selected_gradients(_desktop, Inkscape::FOR_FILL); + return; + + } + if (_mode[SS_FILL] != SS_COLOR) return; sp_svg_write_color (c, sizeof(c), SP_RGBA32_U_COMPOSE( @@ -618,6 +625,10 @@ void SelectedStyle::on_stroke_invert() { SPCSSAttr *css = sp_repr_css_attr_new (); guint32 color = _thisselected[SS_STROKE]; gchar c[64]; + if (_mode[SS_STROKE] == SS_LGRADIENT || _mode[SS_STROKE] == SS_RGRADIENT) { + sp_gradient_invert_selected_gradients(_desktop, Inkscape::FOR_STROKE); + return; + } if (_mode[SS_STROKE] != SS_COLOR) return; sp_svg_write_color (c, sizeof(c), SP_RGBA32_U_COMPOSE( diff --git a/src/ui/widget/spin-scale.cpp b/src/ui/widget/spin-scale.cpp new file mode 100644 index 000000000..00c575568 --- /dev/null +++ b/src/ui/widget/spin-scale.cpp @@ -0,0 +1,248 @@ +/* + * Author: + * + * Copyright (C) 2012 Author + * + * Released under GNU GPL. Read the file 'COPYING' for more information. + */ + +#include <glib.h> +#include <glibmm/i18n.h> +#include <glibmm/stringutils.h> +#include <gtkmm/adjustment.h> + +#include "spin-scale.h" +#include "ui/widget/gimpspinscale.h" + +namespace Inkscape { +namespace UI { +namespace Widget { + +SpinScale::SpinScale(const char* label, double value, double lower, double upper, double step_inc, + double climb_rate, int digits, const SPAttributeEnum a, const char* tip_text) + : AttrWidget(a, value) +{ + +#if WITH_GTKMM_3_0 + _adjustment = Gtk::Adjustment::create(value, lower, upper, step_inc); + _spinscale = gimp_spin_scale_new (_adjustment->gobj(), label, digits); +#else + _adjustment = new Gtk::Adjustment(value, lower, upper, step_inc); + _spinscale = gimp_spin_scale_new (_adjustment->gobj(), label, digits); +#endif + + signal_value_changed().connect(signal_attr_changed().make_slot()); + + pack_start(*Gtk::manage(Glib::wrap(_spinscale))); + + if (tip_text){ + gtk_widget_set_tooltip_text( _spinscale, tip_text ); + } + + show_all_children(); +} + +SpinScale::SpinScale(const char* label, +#if WITH_GTKMM_3_0 + Glib::RefPtr<Gtk::Adjustment> adj, +#else + Gtk::Adjustment *adj, +#endif + int digits, const SPAttributeEnum a, const char* tip_text) + : AttrWidget(a, 0.0), + _adjustment(adj) + +{ + + _spinscale = gimp_spin_scale_new (_adjustment->gobj(), label, digits); + + signal_value_changed().connect(signal_attr_changed().make_slot()); + + pack_start(*Gtk::manage(Glib::wrap(_spinscale))); + + if (tip_text){ + gtk_widget_set_tooltip_text( _spinscale, tip_text ); + } + + show_all_children(); +} + +Glib::ustring SpinScale::get_as_attribute() const +{ + const double val = _adjustment->get_value(); + + //if(_spin.get_digits() == 0) + // return Glib::Ascii::dtostr((int)val); + //else + return Glib::Ascii::dtostr(val); +} + +void SpinScale::set_from_attribute(SPObject* o) +{ + const gchar* val = attribute_value(o); + if(val) + _adjustment->set_value(Glib::Ascii::strtod(val)); + else + _adjustment->set_value(get_default()->as_double()); +} + +Glib::SignalProxy0<void> SpinScale::signal_value_changed() +{ + return _adjustment->signal_value_changed(); +} + +double SpinScale::get_value() const +{ + return _adjustment->get_value(); +} + +void SpinScale::set_value(const double val) +{ + _adjustment->set_value(val); +} + +void SpinScale::set_focuswidget(GtkWidget *widget) +{ + gimp_spin_scale_set_focuswidget(_spinscale, widget); +} + + +void SpinScale::set_appearance(const gchar* appearance) +{ + gimp_spin_scale_set_appearance(_spinscale, appearance); +} + +#if WITH_GTKMM_3_0 +const Glib::RefPtr<Gtk::Adjustment> SpinScale::get_adjustment() const +#else +const Gtk::Adjustment *SpinScale::get_adjustment() const +#endif +{ + return _adjustment; +} +#if WITH_GTKMM_3_0 +Glib::RefPtr<Gtk::Adjustment> SpinScale::get_adjustment() +#else +Gtk::Adjustment *SpinScale::get_adjustment() +#endif +{ + return _adjustment; +} + + +DualSpinScale::DualSpinScale(const char* label1, const char* label2, double value, double lower, double upper, double step_inc, + double climb_rate, int digits, const SPAttributeEnum a, char* tip_text1, char* tip_text2) + : AttrWidget(a), + _s1(label1, value, lower, upper, step_inc, climb_rate, digits, SP_ATTR_INVALID, tip_text1), + _s2(label2, value, lower, upper, step_inc, climb_rate, digits, SP_ATTR_INVALID, tip_text2), + //TRANSLATORS: "Link" means to _link_ two sliders together + _link(C_("Sliders", "Link")) +{ + signal_value_changed().connect(signal_attr_changed().make_slot()); + + _s1.get_adjustment()->signal_value_changed().connect(_signal_value_changed.make_slot()); + _s2.get_adjustment()->signal_value_changed().connect(_signal_value_changed.make_slot()); + _s1.get_adjustment()->signal_value_changed().connect(sigc::mem_fun(*this, &DualSpinScale::update_linked)); + + _link.signal_toggled().connect(sigc::mem_fun(*this, &DualSpinScale::link_toggled)); + + Gtk::VBox* vb = Gtk::manage(new Gtk::VBox); + vb->add(_s1); + vb->add(_s2); + pack_start(*vb); + pack_start(_link, false, false); + _link.set_active(true); + + show_all(); +} + +Glib::ustring DualSpinScale::get_as_attribute() const +{ + if(_link.get_active()) + return _s1.get_as_attribute(); + else + return _s1.get_as_attribute() + " " + _s2.get_as_attribute(); +} + +void DualSpinScale::set_from_attribute(SPObject* o) +{ + const gchar* val = attribute_value(o); + if(val) { + // Split val into parts + gchar** toks = g_strsplit(val, " ", 2); + + if(toks) { + double v1 = 0.0, v2 = 0.0; + if(toks[0]) + v1 = v2 = Glib::Ascii::strtod(toks[0]); + if(toks[1]) + v2 = Glib::Ascii::strtod(toks[1]); + + _link.set_active(toks[1] == 0); + + _s1.get_adjustment()->set_value(v1); + _s2.get_adjustment()->set_value(v2); + + g_strfreev(toks); + } + } +} + +sigc::signal<void>& DualSpinScale::signal_value_changed() +{ + return _signal_value_changed; +} + +const SpinScale& DualSpinScale::get_SpinScale1() const +{ + return _s1; +} + +SpinScale& DualSpinScale::get_SpinScale1() +{ + return _s1; +} + +const SpinScale& DualSpinScale::get_SpinScale2() const +{ + return _s2; +} + +SpinScale& DualSpinScale::get_SpinScale2() +{ + return _s2; +} + +/*void DualSpinScale::remove_scale() +{ + _s1.remove_scale(); + _s2.remove_scale(); +}*/ + +void DualSpinScale::link_toggled() +{ + _s2.set_sensitive(!_link.get_active()); + update_linked(); +} + +void DualSpinScale::update_linked() +{ + if(_link.get_active()) + _s2.set_value(_s1.get_value()); +} + + +} // namespace Widget +} // namespace UI +} // namespace Inkscape + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/ui/widget/spin-scale.h b/src/ui/widget/spin-scale.h new file mode 100644 index 000000000..a8403307f --- /dev/null +++ b/src/ui/widget/spin-scale.h @@ -0,0 +1,117 @@ +/* + * Author: + * + * Copyright (C) 2012 Author + * + * Released under GNU GPL. Read the file 'COPYING' for more information. + */ + +#ifndef INKSCAPE_UI_WIDGET_SPIN_SCALE_H +#define INKSCAPE_UI_WIDGET_SPIN_SCALE_H + +#include <gtkmm/adjustment.h> +#include <gtkmm/box.h> +#include <gtkmm/scale.h> +#include <gtkmm/togglebutton.h> +#include "spinbutton.h" +#include "attr-widget.h" + +namespace Inkscape { +namespace UI { +namespace Widget { + +/** + * Wrap the gimpspinscale class + * A combo widget with label, scale slider, spinbutton and adjustment + */ +class SpinScale : public Gtk::HBox, public AttrWidget +{ + +public: + SpinScale(const char* label, double value, double lower, double upper, double step_inc, double climb_rate, + int digits, const SPAttributeEnum a = SP_ATTR_INVALID, const char* tip_text = NULL); + + SpinScale(const char* label, +#if WITH_GTKMM_3_0 + Glib::RefPtr<Gtk::Adjustment> adj, +#else + Gtk::Adjustment *adj, +#endif + int digits, const SPAttributeEnum a = SP_ATTR_INVALID, const char* tip_text = NULL); + + virtual Glib::ustring get_as_attribute() const; + virtual void set_from_attribute(SPObject*); + + // Shortcuts to _adjustment + Glib::SignalProxy0<void> signal_value_changed(); + double get_value() const; + void set_value(const double); + void set_focuswidget(GtkWidget *widget); + void set_appearance(const gchar* appearance); + +#if WITH_GTKMM_3_0 + const Glib::RefPtr<Gtk::Adjustment> get_adjustment() const; + Glib::RefPtr<Gtk::Adjustment> get_adjustment(); +#else + const Gtk::Adjustment *get_adjustment() const; + Gtk::Adjustment *get_adjustment(); +#endif + +private: +#if WITH_GTKMM_3_0 + Glib::RefPtr<Gtk::Adjustment> _adjustment; +#else + Gtk::Adjustment *_adjustment; +#endif + + GtkWidget *_spinscale; +}; + + +/** + * Contains two SpinScales for controlling number-opt-number attributes. + * + * @see SpinScale + */ +class DualSpinScale : public Gtk::HBox, public AttrWidget +{ +public: + DualSpinScale(const char* label1, const char* label2, double value, double lower, double upper, double step_inc, + double climb_rate, int digits, const SPAttributeEnum, char* tip_text1, char* tip_text2); + + virtual Glib::ustring get_as_attribute() const; + virtual void set_from_attribute(SPObject*); + + sigc::signal<void>& signal_value_changed(); + + const SpinScale& get_SpinScale1() const; + SpinScale& get_SpinScale1(); + + const SpinScale& get_SpinScale2() const; + SpinScale& get_SpinScale2(); + + //void remove_scale(); +private: + void link_toggled(); + void update_linked(); + sigc::signal<void> _signal_value_changed; + SpinScale _s1, _s2; + Gtk::ToggleButton _link; +}; + +} // namespace Widget +} // namespace UI +} // namespace Inkscape + +#endif // INKSCAPE_UI_WIDGET_SPIN_SCALE_H + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/ui/widget/spin-slider.cpp b/src/ui/widget/spin-slider.cpp index 97ae18e20..323b1209c 100644 --- a/src/ui/widget/spin-slider.cpp +++ b/src/ui/widget/spin-slider.cpp @@ -186,7 +186,7 @@ void DualSpinSlider::set_from_attribute(SPObject* o) gchar** toks = g_strsplit(val, " ", 2); if(toks) { - double v1, v2; + double v1 = 0.0, v2 = 0.0; if(toks[0]) v1 = v2 = Glib::Ascii::strtod(toks[0]); if(toks[1]) diff --git a/src/ui/widget/style-swatch.cpp b/src/ui/widget/style-swatch.cpp index 1ee26e803..857ae7019 100644 --- a/src/ui/widget/style-swatch.cpp +++ b/src/ui/widget/style-swatch.cpp @@ -227,8 +227,7 @@ StyleSwatch::setWatchedTool(const char *path, bool synthesize) } -void -StyleSwatch::setStyle(SPCSSAttr *css) +void StyleSwatch::setStyle(SPCSSAttr *css) { if (_css) sp_repr_css_attr_unref (_css); @@ -239,18 +238,18 @@ StyleSwatch::setStyle(SPCSSAttr *css) _css = sp_repr_css_attr_new(); sp_repr_css_merge(_css, css); - gchar const *css_string = sp_repr_css_write_string (_css); + Glib::ustring css_string; + sp_repr_css_write_string (_css, css_string); SPStyle *temp_spstyle = sp_style_new(SP_ACTIVE_DOCUMENT); - if (css_string) - sp_style_merge_from_style_string (temp_spstyle, css_string); - + if (~css_string.empty()) { + sp_style_merge_from_style_string (temp_spstyle, css_string.c_str()); + } + setStyle (temp_spstyle); - sp_style_unref (temp_spstyle); } -void -StyleSwatch::setStyle(SPStyle *query) +void StyleSwatch::setStyle(SPStyle *query) { _place[SS_FILL].remove(); _place[SS_STROKE].remove(); |
