summaryrefslogtreecommitdiffstats
path: root/src/ui/widget
diff options
context:
space:
mode:
authorsu_v <suv-sf@users.sourceforge.net>2012-09-23 17:24:25 +0000
committer~suv <suv-sf@users.sourceforge.net>2012-09-23 17:24:25 +0000
commitac16411f213f98407fc42c1d04eb4ae6c187e4a6 (patch)
treeb8fd94caee6b202043810a7366ab3f032882a48f /src/ui/widget
parentadd newly linked-in m4 files to .bzrignore (diff)
parentFix for 170395 : Add Trace Bitmap to context menu of images : Focus fix (diff)
downloadinkscape-ac16411f213f98407fc42c1d04eb4ae6c187e4a6.tar.gz
inkscape-ac16411f213f98407fc42c1d04eb4ae6c187e4a6.zip
merge from trunk (r11698)
(bzr r11668.1.10)
Diffstat (limited to 'src/ui/widget')
-rw-r--r--src/ui/widget/Makefile_insert4
-rw-r--r--src/ui/widget/filter-effect-chooser.cpp15
-rw-r--r--src/ui/widget/filter-effect-chooser.h8
-rw-r--r--src/ui/widget/gimpspinscale.c1089
-rw-r--r--src/ui/widget/gimpspinscale.h76
-rw-r--r--src/ui/widget/layer-selector.cpp26
-rw-r--r--src/ui/widget/layer-selector.h5
-rw-r--r--src/ui/widget/object-composite-settings.cpp58
-rw-r--r--src/ui/widget/object-composite-settings.h12
-rw-r--r--src/ui/widget/selected-style.cpp11
-rw-r--r--src/ui/widget/spin-scale.cpp248
-rw-r--r--src/ui/widget/spin-scale.h117
-rw-r--r--src/ui/widget/spin-slider.cpp2
-rw-r--r--src/ui/widget/style-swatch.cpp17
14 files changed, 1603 insertions, 85 deletions
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();