summaryrefslogtreecommitdiffstats
path: root/src/ui/widget
diff options
context:
space:
mode:
authorMartin Owens <doctormo@gmail.com>2014-03-27 01:33:44 +0000
committerMartin Owens <doctormo@gmail.com>2014-03-27 01:33:44 +0000
commit5a4fb2325f60d292b47330f540b26a3279341c90 (patch)
treed2aa7967be25450b83e625025366c618101ae49f /src/ui/widget
parentThe Polar Arrange Tab of the Arrange Dialog now hides the parametric (diff)
parentRemove Snap menu item and improve grid menu item text (diff)
downloadinkscape-5a4fb2325f60d292b47330f540b26a3279341c90.tar.gz
inkscape-5a4fb2325f60d292b47330f540b26a3279341c90.zip
Commit a merge to trunk, with probabal errors
(bzr r11073.1.36)
Diffstat (limited to 'src/ui/widget')
-rw-r--r--src/ui/widget/Makefile_insert22
-rw-r--r--src/ui/widget/attr-widget.h7
-rw-r--r--src/ui/widget/button.h11
-rw-r--r--src/ui/widget/color-picker.cpp8
-rw-r--r--src/ui/widget/color-picker.h9
-rw-r--r--src/ui/widget/color-preview.cpp97
-rw-r--r--src/ui/widget/color-preview.h23
-rw-r--r--src/ui/widget/dock-item.cpp13
-rw-r--r--src/ui/widget/dock-item.h8
-rw-r--r--src/ui/widget/dock.cpp50
-rw-r--r--src/ui/widget/dock.h18
-rw-r--r--src/ui/widget/entity-entry.cpp43
-rw-r--r--src/ui/widget/entity-entry.h4
-rw-r--r--src/ui/widget/entry.cpp2
-rw-r--r--src/ui/widget/entry.h6
-rw-r--r--src/ui/widget/filter-effect-chooser.cpp17
-rw-r--r--src/ui/widget/filter-effect-chooser.h17
-rw-r--r--src/ui/widget/frame.cpp2
-rw-r--r--src/ui/widget/frame.h14
-rw-r--r--src/ui/widget/gimpcolorwheel.c1598
-rw-r--r--src/ui/widget/gimpcolorwheel.h95
-rw-r--r--src/ui/widget/gimpspinscale.c1225
-rw-r--r--src/ui/widget/gimpspinscale.h82
-rw-r--r--src/ui/widget/handlebox.cpp42
-rw-r--r--src/ui/widget/handlebox.h52
-rw-r--r--src/ui/widget/icon-widget.cpp161
-rw-r--r--src/ui/widget/icon-widget.h64
-rw-r--r--src/ui/widget/imageicon.cpp10
-rw-r--r--src/ui/widget/imageicon.h11
-rw-r--r--src/ui/widget/imagetoggler.cpp74
-rw-r--r--src/ui/widget/imagetoggler.h33
-rw-r--r--src/ui/widget/labelled.cpp11
-rw-r--r--src/ui/widget/labelled.h13
-rw-r--r--src/ui/widget/layer-selector.cpp49
-rw-r--r--src/ui/widget/layer-selector.h5
-rw-r--r--src/ui/widget/licensor.cpp38
-rw-r--r--src/ui/widget/licensor.h8
-rw-r--r--src/ui/widget/notebook-page.cpp27
-rw-r--r--src/ui/widget/notebook-page.h30
-rw-r--r--src/ui/widget/object-composite-settings.cpp80
-rw-r--r--src/ui/widget/object-composite-settings.h23
-rw-r--r--src/ui/widget/page-sizer.cpp302
-rw-r--r--src/ui/widget/page-sizer.h40
-rw-r--r--src/ui/widget/panel.cpp126
-rw-r--r--src/ui/widget/panel.h26
-rw-r--r--src/ui/widget/point.h2
-rw-r--r--src/ui/widget/preferences-widget.cpp325
-rw-r--r--src/ui/widget/preferences-widget.h57
-rw-r--r--src/ui/widget/registered-widget.cpp11
-rw-r--r--src/ui/widget/registered-widget.h14
-rw-r--r--src/ui/widget/registry.h4
-rw-r--r--src/ui/widget/rendering-options.cpp9
-rw-r--r--src/ui/widget/rotateable.cpp59
-rw-r--r--src/ui/widget/rotateable.h3
-rw-r--r--src/ui/widget/ruler.cpp218
-rw-r--r--src/ui/widget/ruler.h184
-rw-r--r--src/ui/widget/scalar-unit.cpp13
-rw-r--r--src/ui/widget/scalar-unit.h2
-rw-r--r--src/ui/widget/scalar.cpp2
-rw-r--r--src/ui/widget/selected-style.cpp282
-rw-r--r--src/ui/widget/selected-style.h42
-rw-r--r--src/ui/widget/spin-scale.cpp247
-rw-r--r--src/ui/widget/spin-scale.h125
-rw-r--r--src/ui/widget/spin-slider.cpp16
-rw-r--r--src/ui/widget/spin-slider.h16
-rw-r--r--src/ui/widget/spinbutton.cpp32
-rw-r--r--src/ui/widget/spinbutton.h23
-rw-r--r--src/ui/widget/style-subject.h2
-rw-r--r--src/ui/widget/style-swatch.cpp90
-rw-r--r--src/ui/widget/style-swatch.h36
-rw-r--r--src/ui/widget/svg-canvas.cpp91
-rw-r--r--src/ui/widget/svg-canvas.h57
-rw-r--r--src/ui/widget/tolerance-slider.cpp13
-rw-r--r--src/ui/widget/tolerance-slider.h13
-rw-r--r--src/ui/widget/toolbox.cpp272
-rw-r--r--src/ui/widget/toolbox.h74
-rw-r--r--src/ui/widget/unit-menu.cpp59
-rw-r--r--src/ui/widget/unit-menu.h13
-rw-r--r--src/ui/widget/unit-tracker.cpp264
-rw-r--r--src/ui/widget/unit-tracker.h74
-rw-r--r--src/ui/widget/zoom-status.cpp136
-rw-r--r--src/ui/widget/zoom-status.h69
82 files changed, 5356 insertions, 2189 deletions
diff --git a/src/ui/widget/Makefile_insert b/src/ui/widget/Makefile_insert
index f36ffbf56..608dd5334 100644
--- a/src/ui/widget/Makefile_insert
+++ b/src/ui/widget/Makefile_insert
@@ -21,12 +21,12 @@ 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/gimpcolorwheel.c \
+ ui/widget/gimpcolorwheel.h \
ui/widget/frame.cpp \
ui/widget/frame.h \
- ui/widget/handlebox.cpp \
- ui/widget/handlebox.h \
- ui/widget/icon-widget.cpp \
- ui/widget/icon-widget.h \
ui/widget/imageicon.cpp \
ui/widget/imageicon.h \
ui/widget/imagetoggler.cpp \
@@ -60,8 +60,6 @@ ink_common_sources += \
ui/widget/rendering-options.h \
ui/widget/rotateable.h \
ui/widget/rotateable.cpp \
- ui/widget/ruler.cpp \
- ui/widget/ruler.h \
ui/widget/scalar-unit.cpp \
ui/widget/scalar-unit.h \
ui/widget/scalar.cpp \
@@ -70,22 +68,20 @@ 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 \
ui/widget/style-subject.cpp \
ui/widget/style-swatch.h \
ui/widget/style-swatch.cpp \
- ui/widget/svg-canvas.cpp \
- ui/widget/svg-canvas.h \
ui/widget/text.cpp \
ui/widget/text.h \
ui/widget/tolerance-slider.cpp \
ui/widget/tolerance-slider.h \
- ui/widget/toolbox.cpp \
- ui/widget/toolbox.h \
ui/widget/unit-menu.cpp \
- ui/widget/unit-menu.h \
- ui/widget/zoom-status.h \
- ui/widget/zoom-status.cpp
+ ui/widget/unit-menu.h \
+ ui/widget/unit-tracker.h \
+ ui/widget/unit-tracker.cpp
diff --git a/src/ui/widget/attr-widget.h b/src/ui/widget/attr-widget.h
index 7c7235386..1238798ef 100644
--- a/src/ui/widget/attr-widget.h
+++ b/src/ui/widget/attr-widget.h
@@ -122,7 +122,12 @@ public:
: _attr(a),
_default(value)
{}
-
+
+ AttrWidget(const SPAttributeEnum a, char* value)
+ : _attr(a),
+ _default(value)
+ {}
+
AttrWidget(const SPAttributeEnum a)
: _attr(a),
_default()
diff --git a/src/ui/widget/button.h b/src/ui/widget/button.h
index b219fc3db..a214dd881 100644
--- a/src/ui/widget/button.h
+++ b/src/ui/widget/button.h
@@ -10,6 +10,14 @@
#ifndef INKSCAPE_UI_WIDGET_BUTTON_H
#define INKSCAPE_UI_WIDGET_BUTTON_H
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H
+#include <glibmm/threads.h>
+#endif
+
#include <gtkmm/checkbutton.h>
#include <gtkmm/radiobutton.h>
@@ -19,6 +27,7 @@ namespace Widget {
/**
* Button widget.
+ * @deprecated - no need for an explicit subclass... just perhaps a helper function.
*/
class Button : public Gtk::Button
{
@@ -29,6 +38,7 @@ public:
/**
* CheckButton widget.
+ * @deprecated - no need for an explicit subclass... just perhaps a helper function.
*/
class CheckButton : public Gtk::CheckButton
{
@@ -41,6 +51,7 @@ public:
/**
* RadioButton widget.
+ * @deprecated - no need for an explicit subclass... just perhaps a helper function.
*/
class RadioButton : public Gtk::RadioButton
{
diff --git a/src/ui/widget/color-picker.cpp b/src/ui/widget/color-picker.cpp
index e5c542a7c..5585f2db4 100644
--- a/src/ui/widget/color-picker.cpp
+++ b/src/ui/widget/color-picker.cpp
@@ -55,9 +55,15 @@ void ColorPicker::setupDialog(const Glib::ustring &title)
_colorSelectorDialog.hide();
_colorSelectorDialog.set_title (title);
_colorSelectorDialog.set_border_width (4);
- _colorSelector = (SPColorSelector*)sp_color_selector_new(SP_TYPE_COLOR_NOTEBOOK);
+ _colorSelector = SP_COLOR_SELECTOR(sp_color_selector_new(SP_TYPE_COLOR_NOTEBOOK));
+
+#if WITH_GTKMM_3_0
+ _colorSelectorDialog.get_content_area()->pack_start (
+ *Glib::wrap(&_colorSelector->vbox), true, true, 0);
+#else
_colorSelectorDialog.get_vbox()->pack_start (
*Glib::wrap(&_colorSelector->vbox), true, true, 0);
+#endif
g_signal_connect(G_OBJECT(_colorSelector), "dragged",
G_CALLBACK(sp_color_picker_color_mod), (void *)this);
diff --git a/src/ui/widget/color-picker.h b/src/ui/widget/color-picker.h
index e20212615..b4da5dbf2 100644
--- a/src/ui/widget/color-picker.h
+++ b/src/ui/widget/color-picker.h
@@ -13,7 +13,16 @@
#ifndef __COLOR_PICKER_H__
#define __COLOR_PICKER_H__
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
#include <stddef.h>
+
+#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H
+#include <glibmm/threads.h>
+#endif
+
#include <gtkmm/dialog.h>
#include <gtkmm/button.h>
#include <sigc++/sigc++.h>
diff --git a/src/ui/widget/color-preview.cpp b/src/ui/widget/color-preview.cpp
index 244e2b4e3..5bcd16528 100644
--- a/src/ui/widget/color-preview.cpp
+++ b/src/ui/widget/color-preview.cpp
@@ -26,13 +26,6 @@ ColorPreview::ColorPreview (guint32 rgba)
}
void
-ColorPreview::on_size_request (Gtk::Requisition *req)
-{
- req->width = SPCP_DEFAULT_WIDTH;
- req->height = SPCP_DEFAULT_HEIGHT;
-}
-
-void
ColorPreview::on_size_allocate (Gtk::Allocation &all)
{
set_allocation (all);
@@ -40,14 +33,55 @@ ColorPreview::on_size_allocate (Gtk::Allocation &all)
queue_draw();
}
+#if WITH_GTKMM_3_0
+void
+ColorPreview::get_preferred_height_vfunc(int& minimum_height, int& natural_height) const
+{
+ minimum_height = natural_height = SPCP_DEFAULT_HEIGHT;
+}
+
+void
+ColorPreview::get_preferred_height_for_width_vfunc(int /* width */, int& minimum_height, int& natural_height) const
+{
+ minimum_height = natural_height = SPCP_DEFAULT_HEIGHT;
+}
+
+void
+ColorPreview::get_preferred_width_vfunc(int& minimum_width, int& natural_width) const
+{
+ minimum_width = natural_width = SPCP_DEFAULT_WIDTH;
+}
+
+void
+ColorPreview::get_preferred_width_for_height_vfunc(int /* height */, int& minimum_width, int& natural_width) const
+{
+ minimum_width = natural_width = SPCP_DEFAULT_WIDTH;
+}
+#else
+void
+ColorPreview::on_size_request (Gtk::Requisition *req)
+{
+ req->width = SPCP_DEFAULT_WIDTH;
+ req->height = SPCP_DEFAULT_HEIGHT;
+}
+
bool
ColorPreview::on_expose_event (GdkEventExpose *event)
{
+ bool result = true;
+
if (get_is_drawable())
- paint (&event->area);
+ {
+ Cairo::RefPtr<Cairo::Context> cr = get_window()->create_cairo_context();
+ cr->rectangle(event->area.x, event->area.y,
+ event->area.width, event->area.height);
+ cr->clip();
+ result = on_draw(cr);
+ }
- return true;
+ return result;
}
+#endif
void
ColorPreview::setRgba32 (guint32 rgba)
@@ -58,11 +92,10 @@ ColorPreview::setRgba32 (guint32 rgba)
queue_draw();
}
-void
-ColorPreview::paint (GdkRectangle *area)
+bool
+ColorPreview::on_draw(const Cairo::RefPtr<Cairo::Context>& cr)
{
GdkRectangle warea, carea;
- GdkRectangle wpaint, cpaint;
gint w2;
const Gtk::Allocation& allocation = get_allocation();
@@ -71,12 +104,6 @@ ColorPreview::paint (GdkRectangle *area)
warea.width = allocation.get_width();
warea.height = allocation.get_height();
- if (!gdk_rectangle_intersect (area, &warea, &wpaint))
- return;
-
- GtkWidget *widget = GTK_WIDGET(this->gobj());
- cairo_t *ct = gdk_cairo_create(widget->window);
-
/* Transparent area */
w2 = warea.width / 2;
@@ -86,17 +113,15 @@ ColorPreview::paint (GdkRectangle *area)
carea.width = w2;
carea.height = warea.height;
- if (gdk_rectangle_intersect (area, &carea, &cpaint)) {
- cairo_pattern_t *checkers = ink_cairo_pattern_create_checkerboard();
+ cairo_pattern_t *checkers = ink_cairo_pattern_create_checkerboard();
- cairo_rectangle(ct, carea.x, carea.y, carea.width, carea.height);
- cairo_set_source(ct, checkers);
- cairo_fill_preserve(ct);
- ink_cairo_set_source_rgba32(ct, _rgba);
- cairo_fill(ct);
+ cr->rectangle(carea.x, carea.y, carea.width, carea.height);
+ cairo_set_source(cr->cobj(), checkers);
+ cr->fill_preserve();
+ ink_cairo_set_source_rgba32(cr->cobj(), _rgba);
+ cr->fill();
- cairo_pattern_destroy(checkers);
- }
+ cairo_pattern_destroy(checkers);
/* Solid area */
@@ -105,13 +130,11 @@ ColorPreview::paint (GdkRectangle *area)
carea.width = warea.width - w2;
carea.height = warea.height;
- if (gdk_rectangle_intersect (area, &carea, &cpaint)) {
- cairo_rectangle(ct, carea.x, carea.y, carea.width, carea.height);
- ink_cairo_set_source_rgba32(ct, _rgba | 0xff);
- cairo_fill(ct);
- }
+ cr->rectangle(carea.x, carea.y, carea.width, carea.height);
+ ink_cairo_set_source_rgba32(cr->cobj(), _rgba | 0xff);
+ cr->fill();
- cairo_destroy(ct);
+ return true;
}
GdkPixbuf*
@@ -153,12 +176,7 @@ ColorPreview::toPixbuf (int width, int height)
cairo_destroy(ct);
cairo_surface_flush(s);
- GdkPixbuf* pixbuf = gdk_pixbuf_new_from_data( cairo_image_surface_get_data(s),
- GDK_COLORSPACE_RGB, TRUE, 8,
- width, height, cairo_image_surface_get_stride(s),
- ink_cairo_pixbuf_cleanup, s);
- convert_pixbuf_argb32_to_normal(pixbuf);
-
+ GdkPixbuf* pixbuf = ink_pixbuf_create_from_cairo_surface(s);
return pixbuf;
}
@@ -173,3 +191,4 @@ ColorPreview::toPixbuf (int width, int height)
fill-column:99
End:
*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
diff --git a/src/ui/widget/color-preview.h b/src/ui/widget/color-preview.h
index d6d3da01c..959b5e09b 100644
--- a/src/ui/widget/color-preview.h
+++ b/src/ui/widget/color-preview.h
@@ -11,6 +11,14 @@
* Released under GNU GPL, read the file 'COPYING' for more information
*/
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H
+#include <glibmm/threads.h>
+#endif
+
#include <gtkmm/widget.h>
namespace Inkscape {
@@ -27,10 +35,19 @@ public:
GdkPixbuf* toPixbuf (int width, int height);
protected:
- virtual void on_size_request (Gtk::Requisition *req);
virtual void on_size_allocate (Gtk::Allocation &all);
- virtual bool on_expose_event (GdkEventExpose *event);
- void paint (GdkRectangle *area);
+
+#if WITH_GTKMM_3_0
+ virtual void get_preferred_height_vfunc(int& minimum_height, int& natural_height) const;
+ virtual void get_preferred_height_for_width_vfunc(int width, int& minimum_height, int& natural_height) const;
+ virtual void get_preferred_width_vfunc(int& minimum_width, int& natural_width) const;
+ virtual void get_preferred_width_for_height_vfunc(int height, int& minimum_width, int& natural_width) const;
+#else
+ virtual void on_size_request (Gtk::Requisition *req);
+ virtual bool on_expose_event(GdkEventExpose *event);
+#endif
+
+ virtual bool on_draw(const Cairo::RefPtr<Cairo::Context>& cr);
guint32 _rgba;
};
diff --git a/src/ui/widget/dock-item.cpp b/src/ui/widget/dock-item.cpp
index 238e93b0b..8d960ddc3 100644
--- a/src/ui/widget/dock-item.cpp
+++ b/src/ui/widget/dock-item.cpp
@@ -18,6 +18,7 @@
#include <gtkmm/icontheme.h>
#include <gtkmm/stockitem.h>
+#include <glibmm/exceptionhandler.h>
namespace Inkscape {
namespace UI {
@@ -58,7 +59,11 @@ DockItem::DockItem(Dock& dock, const Glib::ustring& name, const Glib::ustring& l
Gtk::StockItem item;
Gtk::StockID stockId(icon_name);
if ( Gtk::StockItem::lookup(stockId, item) ) {
+#if WITH_GTKMM_3_0
+ _icon_pixbuf = _dock.getWidget().render_icon_pixbuf( stockId, Gtk::ICON_SIZE_MENU );
+#else
_icon_pixbuf = _dock.getWidget().render_icon( stockId, Gtk::ICON_SIZE_MENU );
+#endif
}
}
}
@@ -168,10 +173,14 @@ DockItem::set_size_request(int width, int height)
getWidget().set_size_request(width, height);
}
-void
-DockItem::size_request(Gtk::Requisition& requisition)
+void DockItem::size_request(Gtk::Requisition& requisition)
{
+#if WITH_GTKMM_3_0
+ Gtk::Requisition req_natural;
+ getWidget().get_preferred_size(req_natural, requisition);
+#else
requisition = getWidget().size_request();
+#endif
}
void
diff --git a/src/ui/widget/dock-item.h b/src/ui/widget/dock-item.h
index 608badb62..cc0c13eea 100644
--- a/src/ui/widget/dock-item.h
+++ b/src/ui/widget/dock-item.h
@@ -11,6 +11,14 @@
#ifndef INKSCAPE_UI_WIGET_DOCK_ITEM_H
#define INKSCAPE_UI_WIGET_DOCK_ITEM_H
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H
+#include <glibmm/threads.h>
+#endif
+
#include <gtkmm/box.h>
#include <gtkmm/frame.h>
#include <gtkmm/window.h>
diff --git a/src/ui/widget/dock.cpp b/src/ui/widget/dock.cpp
index ab3a8adca..52e9ea605 100644
--- a/src/ui/widget/dock.cpp
+++ b/src/ui/widget/dock.cpp
@@ -25,7 +25,7 @@ namespace Widget {
namespace {
-void hideCallback(GtkObject */*object*/, gpointer dock_ptr)
+void hideCallback(GObject * /*object*/, gpointer dock_ptr)
{
g_return_if_fail( dock_ptr != NULL );
@@ -33,7 +33,7 @@ void hideCallback(GtkObject */*object*/, gpointer dock_ptr)
dock->hide();
}
-void unhideCallback(GtkObject */*object*/, gpointer dock_ptr)
+void unhideCallback(GObject * /*object*/, gpointer dock_ptr)
{
g_return_if_fail( dock_ptr != NULL );
@@ -48,12 +48,33 @@ const int Dock::_default_dock_bar_width = 36;
Dock::Dock(Gtk::Orientation orientation)
- : _gdl_dock (GDL_DOCK (gdl_dock_new())),
- _gdl_dock_bar (GDL_DOCK_BAR (gdl_dock_bar_new(GDL_DOCK(_gdl_dock)))),
+ : _gdl_dock(gdl_dock_new()),
+#if WITH_GDL_3_6
+ _gdl_dock_bar(GDL_DOCK_BAR(gdl_dock_bar_new(G_OBJECT(_gdl_dock)))),
+#else
+ _gdl_dock_bar(GDL_DOCK_BAR(gdl_dock_bar_new(GDL_DOCK(_gdl_dock)))),
+#endif
_scrolled_window (Gtk::manage(new Gtk::ScrolledWindow))
{
- gdl_dock_bar_set_orientation(_gdl_dock_bar, static_cast<GtkOrientation>(orientation));
-
+#if WITH_GDL_3_6
+ gtk_orientable_set_orientation(GTK_ORIENTABLE(_gdl_dock_bar),
+ static_cast<GtkOrientation>(orientation));
+#else
+ gdl_dock_bar_set_orientation(_gdl_dock_bar,
+ static_cast<GtkOrientation>(orientation));
+#endif
+
+#if WITH_GTKMM_3_0
+ switch(orientation) {
+ case Gtk::ORIENTATION_VERTICAL:
+ _dock_box = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_HORIZONTAL));
+ break;
+ case Gtk::ORIENTATION_HORIZONTAL:
+ _dock_box = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_VERTICAL));
+ }
+
+ _paned = Gtk::manage(new Gtk::Paned(orientation));
+#else
switch (orientation) {
case Gtk::ORIENTATION_VERTICAL:
_dock_box = Gtk::manage(new Gtk::HBox());
@@ -63,6 +84,7 @@ Dock::Dock(Gtk::Orientation orientation)
_dock_box = Gtk::manage(new Gtk::VBox());
_paned = Gtk::manage(new Gtk::HPaned());
}
+#endif
_scrolled_window->add(*_dock_box);
_scrolled_window->set_policy(Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
@@ -81,9 +103,15 @@ Dock::Dock(Gtk::Orientation orientation)
static_cast<GdlSwitcherStyle>(prefs->getIntLimited("/options/dock/switcherstyle",
GDL_SWITCHER_STYLE_BOTH, 0, 4));
- g_object_set (GDL_DOCK_OBJECT(_gdl_dock)->master,
- "switcher-style", gdl_switcher_style,
- NULL);
+ GdlDockMaster* master = NULL;
+
+ g_object_get(GDL_DOCK_OBJECT(_gdl_dock),
+ "master", &master,
+ NULL);
+
+ g_object_set(master,
+ "switcher-style", gdl_switcher_style,
+ NULL);
GdlDockBarStyle gdl_dock_bar_style =
static_cast<GdlDockBarStyle>(prefs->getIntLimited("/options/dock/dockbarstyle",
@@ -109,7 +137,9 @@ Dock::~Dock()
void Dock::addItem(DockItem& item, DockItem::Placement placement)
{
_dock_items.push_back(&item);
- gdl_dock_add_item(_gdl_dock, GDL_DOCK_ITEM(item.gobj()), (GdlDockPlacement)placement);
+ gdl_dock_add_item(GDL_DOCK(_gdl_dock),
+ GDL_DOCK_ITEM(item.gobj()),
+ (GdlDockPlacement)placement);
// FIXME: This is a hack to prevent the dock from expanding the main window, this can't be done
// initially as the paned doesn't exist.
diff --git a/src/ui/widget/dock.h b/src/ui/widget/dock.h
index 28ab42740..33e60b836 100644
--- a/src/ui/widget/dock.h
+++ b/src/ui/widget/dock.h
@@ -12,6 +12,14 @@
#ifndef INKSCAPE_UI_WIDGET_DOCK_H
#define INKSCAPE_UI_WIDGET_DOCK_H
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H
+#include <glibmm/threads.h>
+#endif
+
#include <gtkmm/box.h>
#include <list>
#include "ui/widget/dock-item.h"
@@ -66,11 +74,11 @@ protected:
/** Interface widgets, will be packed like
* _scrolled_window -> (_dock_box -> (_paned -> (_dock -> _filler) | _dock_bar))
*/
- Gtk::Box *_dock_box;
- Gtk::Paned* _paned;
- GdlDock *_gdl_dock;
- GdlDockBar *_gdl_dock_bar;
- Gtk::VBox _filler;
+ Gtk::Box *_dock_box;
+ Gtk::Paned *_paned;
+ GtkWidget *_gdl_dock;
+ GdlDockBar *_gdl_dock_bar;
+ Gtk::VBox _filler;
Gtk::ScrolledWindow *_scrolled_window;
/** Internal signal handlers */
diff --git a/src/ui/widget/entity-entry.cpp b/src/ui/widget/entity-entry.cpp
index be43e4fda..0f526f77a 100644
--- a/src/ui/widget/entity-entry.cpp
+++ b/src/ui/widget/entity-entry.cpp
@@ -17,6 +17,10 @@
# include <config.h>
#endif
+#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H
+#include <glibmm/threads.h>
+#endif
+
#include <gtkmm/scrolledwindow.h>
#include <gtkmm/entry.h>
@@ -26,6 +30,8 @@
#include "ui/widget/registry.h"
#include "sp-root.h"
#include "document-undo.h"
+#include "document-private.h"
+#include "preferences.h"
#include "verbs.h"
#include "entity-entry.h"
@@ -71,6 +77,13 @@ EntityEntry::~EntityEntry()
_changed_connection.disconnect();
}
+void EntityEntry::save_to_preferences(SPDocument *doc)
+{
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ const gchar *text = rdf_get_work_entity (doc, _entity);
+ prefs->setString(PREFS_METADATA + Glib::ustring(_entity->name), Glib::ustring(text ? text : ""));
+}
+
EntityLineEntry::EntityLineEntry (rdf_work_entity_t* ent, Registry& wr)
: EntityEntry (ent, wr)
{
@@ -96,6 +109,16 @@ void EntityLineEntry::update(SPDocument *doc)
static_cast<Gtk::Entry*>(_packable)->set_text (text ? text : "");
}
+
+void EntityLineEntry::load_from_preferences()
+{
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ Glib::ustring text = prefs->getString(PREFS_METADATA + Glib::ustring(_entity->name));
+ if (text.length() > 0) {
+ static_cast<Gtk::Entry*>(_packable)->set_text (text.c_str());
+ }
+}
+
void
EntityLineEntry::on_changed()
{
@@ -105,8 +128,9 @@ EntityLineEntry::on_changed()
SPDocument *doc = SP_ACTIVE_DOCUMENT;
Glib::ustring text = static_cast<Gtk::Entry*>(_packable)->get_text();
if (rdf_set_work_entity (doc, _entity, text.c_str())) {
- DocumentUndo::done(doc, SP_VERB_NONE,
- /* TODO: annotate */ "entity-entry.cpp:101");
+ if (doc->priv->sensitive) {
+ DocumentUndo::done(doc, SP_VERB_NONE, "Document metadata updated");
+ }
}
_wr->setUpdating (false);
}
@@ -144,6 +168,19 @@ void EntityMultiLineEntry::update(SPDocument *doc)
tv->get_buffer()->set_text (text ? text : "");
}
+
+void EntityMultiLineEntry::load_from_preferences()
+{
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ Glib::ustring text = prefs->getString(PREFS_METADATA + Glib::ustring(_entity->name));
+ if (text.length() > 0) {
+ Gtk::ScrolledWindow *s = static_cast<Gtk::ScrolledWindow*>(_packable);
+ Gtk::TextView *tv = static_cast<Gtk::TextView*>(s->get_child());
+ tv->get_buffer()->set_text (text.c_str());
+ }
+}
+
+
void
EntityMultiLineEntry::on_changed()
{
@@ -155,7 +192,7 @@ EntityMultiLineEntry::on_changed()
Gtk::TextView *tv = static_cast<Gtk::TextView*>(s->get_child());
Glib::ustring text = tv->get_buffer()->get_text();
if (rdf_set_work_entity (doc, _entity, text.c_str())) {
- DocumentUndo::done(doc, SP_VERB_NONE,
+ DocumentUndo::done(doc, SP_VERB_NONE,
/* TODO: annotate */ "entity-entry.cpp:146");
}
_wr->setUpdating (false);
diff --git a/src/ui/widget/entity-entry.h b/src/ui/widget/entity-entry.h
index 0e031bb0a..09289496d 100644
--- a/src/ui/widget/entity-entry.h
+++ b/src/ui/widget/entity-entry.h
@@ -31,6 +31,8 @@ public:
virtual ~EntityEntry() = 0;
virtual void update (SPDocument *doc) = 0;
virtual void on_changed() = 0;
+ virtual void load_from_preferences() = 0;
+ void save_to_preferences(SPDocument *doc);
Gtk::Label _label;
Gtk::Widget *_packable;
@@ -46,6 +48,7 @@ public:
EntityLineEntry (rdf_work_entity_t* ent, Registry& wr);
~EntityLineEntry();
void update (SPDocument *doc);
+ void load_from_preferences();
protected:
virtual void on_changed();
@@ -56,6 +59,7 @@ public:
EntityMultiLineEntry (rdf_work_entity_t* ent, Registry& wr);
~EntityMultiLineEntry();
void update (SPDocument *doc);
+ void load_from_preferences();
protected:
virtual void on_changed();
diff --git a/src/ui/widget/entry.cpp b/src/ui/widget/entry.cpp
index 173e014d9..64d28119a 100644
--- a/src/ui/widget/entry.cpp
+++ b/src/ui/widget/entry.cpp
@@ -13,6 +13,8 @@
#include "entry.h"
+#include <gtkmm/entry.h>
+
namespace Inkscape {
namespace UI {
namespace Widget {
diff --git a/src/ui/widget/entry.h b/src/ui/widget/entry.h
index 53b848fc9..de5cceadd 100644
--- a/src/ui/widget/entry.h
+++ b/src/ui/widget/entry.h
@@ -11,10 +11,10 @@
#define INKSCAPE_UI_WIDGET_ENTRY__H
#include "labelled.h"
-#include <gtkmm.h>
-#include <gtkmm/entry.h>
-#include <gtkmm/comboboxtext.h>
+namespace Gtk {
+class Entry;
+}
namespace Inkscape {
namespace UI {
diff --git a/src/ui/widget/filter-effect-chooser.cpp b/src/ui/widget/filter-effect-chooser.cpp
index cb9d3e7e0..65706a9dc 100644
--- a/src/ui/widget/filter-effect-chooser.cpp
+++ b/src/ui/widget/filter-effect-chooser.cpp
@@ -22,11 +22,9 @@ namespace UI {
namespace Widget {
SimpleFilterModifier::SimpleFilterModifier(int flags)
- : _hb_blur(false, 0),
- _lb_blend(_("Blend mode:")),
- _lb_blur(_("_Blur:")),
+ : _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;
@@ -36,14 +34,7 @@ SimpleFilterModifier::SimpleFilterModifier(int flags)
_hb_blend.pack_start(_blend);
}
if (flags & BLUR) {
- add(_hb_blur);
- #if WITH_GTKMM_2_22
- _lb_blur.set_alignment(Gtk::ALIGN_END, Gtk::ALIGN_CENTER);
- #else
- _lb_blur.set_alignment(Gtk::ALIGN_RIGHT, Gtk::ALIGN_CENTER);
- #endif
- _hb_blur.pack_start(_lb_blur, false, false, 0);
- _hb_blur.pack_start(_blur, true, true, 0);
+ add(_blur);
}
show_all_children();
@@ -51,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 2d5f04007..8d2389b15 100644
--- a/src/ui/widget/filter-effect-chooser.h
+++ b/src/ui/widget/filter-effect-chooser.h
@@ -12,12 +12,20 @@
* Released under GNU GPL, read the file 'COPYING' for more information
*/
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H
+#include <glibmm/threads.h>
+#endif
+
#include <gtkmm/box.h>
#include <gtkmm/combobox.h>
#include "combo-enums.h"
#include "filter-enums.h"
-#include "spin-slider.h"
+#include "spin-scale.h"
namespace Inkscape {
namespace UI {
@@ -45,17 +53,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;
+ 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/frame.cpp b/src/ui/widget/frame.cpp
index b2968f806..eaa4336bb 100644
--- a/src/ui/widget/frame.cpp
+++ b/src/ui/widget/frame.cpp
@@ -56,9 +56,7 @@ Frame::set_label(const Glib::ustring &label_text, gboolean label_bold /*= TRUE*/
void
Frame::set_padding (guint padding_top, guint padding_bottom, guint padding_left, guint padding_right)
{
-#if WITH_GTKMM_2_24
_alignment.set_padding(padding_top, padding_bottom, padding_left, padding_right);
-#endif
}
Gtk::Label const *
diff --git a/src/ui/widget/frame.h b/src/ui/widget/frame.h
index cf736d8a1..55638ad40 100644
--- a/src/ui/widget/frame.h
+++ b/src/ui/widget/frame.h
@@ -10,11 +10,17 @@
#ifndef INKSCAPE_UI_WIDGET_FRAME_H
#define INKSCAPE_UI_WIDGET_FRAME_H
-#include <gtkmm.h>
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
-namespace Gtk {
-class Frame;
-}
+#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H
+#include <glibmm/threads.h>
+#endif
+
+#include <gtkmm/alignment.h>
+#include <gtkmm/frame.h>
+#include <gtkmm/label.h>
namespace Inkscape {
namespace UI {
diff --git a/src/ui/widget/gimpcolorwheel.c b/src/ui/widget/gimpcolorwheel.c
new file mode 100644
index 000000000..f632331d8
--- /dev/null
+++ b/src/ui/widget/gimpcolorwheel.c
@@ -0,0 +1,1598 @@
+/* HSV color selector for GTK+
+ *
+ * Copyright (C) 1999 The Free Software Foundation
+ *
+ * Authors: Simon Budig <Simon.Budig@unix-ag.org> (original code)
+ * Federico Mena-Quintero <federico@gimp.org> (cleanup for GTK+)
+ * Jonathan Blandford <jrb@redhat.com> (cleanup for GTK+)
+ * Michael Natterer <mitch@gimp.org> (ported back to GIMP)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GTK+ Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+/*
+ * This widget was adopted by Inkscape by Alex Valavanis <valavanisalex@gmail.com>
+ * on 2013-01-08. Last merges with GIMP code were applied using the following
+ * commits from the GIMP git repository at
+ * http://git.gnome.org/browse/gimp/tree/modules/gimpcolorwheel.c
+ *
+ * Gtk+ 2 code merge: commit 632c5 (2013-01-06)
+ * Gtk+ 3 code merge: commit bcfc6, gtk3-port branch (2013-01-06)
+ */
+
+#include "config.h"
+
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+
+#include "gimpcolorwheel.h"
+#include <math.h>
+
+
+/* Default ring fraction */
+#define DEFAULT_FRACTION 0.1
+
+/* Default width/height */
+#define DEFAULT_SIZE 100
+
+/* Default ring width */
+#define DEFAULT_RING_WIDTH 10
+
+
+/* Dragging modes */
+typedef enum
+{
+ DRAG_NONE,
+ DRAG_H,
+ DRAG_SV
+} DragMode;
+
+/* Private part of the GimpColorWheel structure */
+typedef struct
+{
+ /* Color value */
+ gdouble h;
+ gdouble s;
+ gdouble v;
+
+ /* ring_width is this fraction of size */
+ gdouble ring_fraction;
+
+ /* Size and ring width */
+ gint size;
+ gint ring_width;
+
+ /* Window for capturing events */
+ GdkWindow *window;
+
+ /* Dragging mode */
+ DragMode mode;
+
+ guint focus_on_ring : 1;
+} GimpColorWheelPrivate;
+
+enum
+{
+ CHANGED,
+ MOVE,
+ LAST_SIGNAL
+};
+
+static void gimp_color_wheel_map (GtkWidget *widget);
+static void gimp_color_wheel_unmap (GtkWidget *widget);
+static void gimp_color_wheel_realize (GtkWidget *widget);
+static void gimp_color_wheel_unrealize (GtkWidget *widget);
+static void gimp_color_wheel_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation);
+static gboolean gimp_color_wheel_button_press (GtkWidget *widget,
+ GdkEventButton *event);
+static gboolean gimp_color_wheel_button_release (GtkWidget *widget,
+ GdkEventButton *event);
+static gboolean gimp_color_wheel_motion (GtkWidget *widget,
+ GdkEventMotion *event);
+#if GTK_CHECK_VERSION(3,0,0)
+static gboolean gimp_color_wheel_draw (GtkWidget *widget,
+ cairo_t *cr);
+static void gimp_color_wheel_get_preferred_width (GtkWidget *widget,
+ gint *minimum_width,
+ gint *natural_width);
+static void gimp_color_wheel_get_preferred_height (GtkWidget *widget,
+ gint *minimum_height,
+ gint *natural_height);
+#else
+static gboolean gimp_color_wheel_expose (GtkWidget *widget,
+ GdkEventExpose *event);
+static void gimp_color_wheel_size_request (GtkWidget *widget,
+ GtkRequisition *requisition);
+#endif
+
+static gboolean gimp_color_wheel_grab_broken (GtkWidget *widget,
+ GdkEventGrabBroken *event);
+static gboolean gimp_color_wheel_focus (GtkWidget *widget,
+ GtkDirectionType direction);
+static void gimp_color_wheel_move (GimpColorWheel *wheel,
+ GtkDirectionType dir);
+
+
+static guint wheel_signals[LAST_SIGNAL];
+
+G_DEFINE_TYPE (GimpColorWheel, gimp_color_wheel, GTK_TYPE_WIDGET)
+
+#define parent_class gimp_color_wheel_parent_class
+
+
+static void
+gimp_color_wheel_class_init (GimpColorWheelClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
+ GimpColorWheelClass *wheel_class = GIMP_COLOR_WHEEL_CLASS (class);
+ GtkBindingSet *binding_set;
+
+ widget_class->map = gimp_color_wheel_map;
+ widget_class->unmap = gimp_color_wheel_unmap;
+ widget_class->realize = gimp_color_wheel_realize;
+ widget_class->unrealize = gimp_color_wheel_unrealize;
+ widget_class->size_allocate = gimp_color_wheel_size_allocate;
+ widget_class->button_press_event = gimp_color_wheel_button_press;
+ widget_class->button_release_event = gimp_color_wheel_button_release;
+ widget_class->motion_notify_event = gimp_color_wheel_motion;
+
+#if GTK_CHECK_VERSION(3,0,0)
+ widget_class->get_preferred_width = gimp_color_wheel_get_preferred_width;
+ widget_class->get_preferred_height = gimp_color_wheel_get_preferred_height;
+ widget_class->draw = gimp_color_wheel_draw;
+#else
+ widget_class->size_request = gimp_color_wheel_size_request;
+ widget_class->expose_event = gimp_color_wheel_expose;
+#endif
+
+ widget_class->focus = gimp_color_wheel_focus;
+ widget_class->grab_broken_event = gimp_color_wheel_grab_broken;
+
+ wheel_class->move = gimp_color_wheel_move;
+
+ wheel_signals[CHANGED] =
+ g_signal_new ("changed",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (GimpColorWheelClass, changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ wheel_signals[MOVE] =
+ g_signal_new ("move",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (GimpColorWheelClass, move),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__ENUM,
+ G_TYPE_NONE, 1,
+ GTK_TYPE_DIRECTION_TYPE);
+
+ binding_set = gtk_binding_set_by_class (class);
+
+ gtk_binding_entry_add_signal (binding_set, GDK_KEY_Up, 0,
+ "move", 1,
+ G_TYPE_ENUM, GTK_DIR_UP);
+ gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Up, 0,
+ "move", 1,
+ G_TYPE_ENUM, GTK_DIR_UP);
+
+ gtk_binding_entry_add_signal (binding_set, GDK_KEY_Down, 0,
+ "move", 1,
+ G_TYPE_ENUM, GTK_DIR_DOWN);
+ gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Down, 0,
+ "move", 1,
+ G_TYPE_ENUM, GTK_DIR_DOWN);
+
+
+ gtk_binding_entry_add_signal (binding_set, GDK_KEY_Right, 0,
+ "move", 1,
+ G_TYPE_ENUM, GTK_DIR_RIGHT);
+ gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Right, 0,
+ "move", 1,
+ G_TYPE_ENUM, GTK_DIR_RIGHT);
+
+ gtk_binding_entry_add_signal (binding_set, GDK_KEY_Left, 0,
+ "move", 1,
+ G_TYPE_ENUM, GTK_DIR_LEFT);
+ gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Left, 0,
+ "move", 1,
+ G_TYPE_ENUM, GTK_DIR_LEFT);
+
+ g_type_class_add_private (object_class, sizeof (GimpColorWheelPrivate));
+}
+
+static void
+gimp_color_wheel_init (GimpColorWheel *wheel)
+{
+ GimpColorWheelPrivate *priv;
+
+ priv = G_TYPE_INSTANCE_GET_PRIVATE (wheel, GIMP_TYPE_COLOR_WHEEL,
+ GimpColorWheelPrivate);
+
+ wheel->priv = priv;
+
+ gtk_widget_set_has_window (GTK_WIDGET (wheel), FALSE);
+ gtk_widget_set_can_focus (GTK_WIDGET (wheel), TRUE);
+
+ priv->ring_fraction = DEFAULT_FRACTION;
+ priv->size = DEFAULT_SIZE;
+ priv->ring_width = DEFAULT_RING_WIDTH;
+}
+
+static void
+gimp_color_wheel_map (GtkWidget *widget)
+{
+ GimpColorWheel *wheel = GIMP_COLOR_WHEEL (widget);
+ GimpColorWheelPrivate *priv = wheel->priv;
+
+ GTK_WIDGET_CLASS (parent_class)->map (widget);
+
+ gdk_window_show (priv->window);
+}
+
+static void
+gimp_color_wheel_unmap (GtkWidget *widget)
+{
+ GimpColorWheel *wheel = GIMP_COLOR_WHEEL (widget);
+ GimpColorWheelPrivate *priv = wheel->priv;
+
+ gdk_window_hide (priv->window);
+
+ GTK_WIDGET_CLASS (parent_class)->unmap (widget);
+}
+
+static void
+gimp_color_wheel_realize (GtkWidget *widget)
+{
+ GimpColorWheel *wheel = GIMP_COLOR_WHEEL (widget);
+ GimpColorWheelPrivate *priv = wheel->priv;
+ GtkAllocation allocation;
+ GdkWindowAttr attr;
+ gint attr_mask;
+ GdkWindow *parent_window;
+
+ gtk_widget_get_allocation (widget, &allocation);
+
+ gtk_widget_set_realized (widget, TRUE);
+
+ attr.window_type = GDK_WINDOW_CHILD;
+ attr.x = allocation.x;
+ attr.y = allocation.y;
+ attr.width = allocation.width;
+ attr.height = allocation.height;
+ attr.wclass = GDK_INPUT_ONLY;
+ attr.event_mask = (gtk_widget_get_events (widget) |
+ GDK_KEY_PRESS_MASK |
+ GDK_BUTTON_PRESS_MASK |
+ GDK_BUTTON_RELEASE_MASK |
+ GDK_POINTER_MOTION_MASK |
+ GDK_ENTER_NOTIFY_MASK |
+ GDK_LEAVE_NOTIFY_MASK);
+
+ attr_mask = GDK_WA_X | GDK_WA_Y;
+
+ parent_window = gtk_widget_get_parent_window (widget);
+
+ gtk_widget_set_window (widget, parent_window);
+ g_object_ref (parent_window);
+
+ priv->window = gdk_window_new (parent_window, &attr, attr_mask);
+ gdk_window_set_user_data (priv->window, wheel);
+
+ gtk_widget_style_attach (widget);
+}
+
+static void
+gimp_color_wheel_unrealize (GtkWidget *widget)
+{
+ GimpColorWheel *wheel = GIMP_COLOR_WHEEL (widget);
+ GimpColorWheelPrivate *priv = wheel->priv;
+
+ gdk_window_set_user_data (priv->window, NULL);
+ gdk_window_destroy (priv->window);
+ priv->window = NULL;
+
+ GTK_WIDGET_CLASS (parent_class)->unrealize (widget);
+}
+
+#if GTK_CHECK_VERSION(3,0,0)
+static void
+gimp_color_wheel_get_preferred_width (GtkWidget *widget,
+ gint *minimum_width,
+ gint *natural_width)
+{
+ gint focus_width;
+ gint focus_pad;
+
+ gtk_widget_style_get (widget,
+ "focus-line-width", &focus_width,
+ "focus-padding", &focus_pad,
+ NULL);
+
+ *minimum_width = *natural_width = DEFAULT_SIZE + 2 * (focus_width + focus_pad);
+}
+
+static void
+gimp_color_wheel_get_preferred_height (GtkWidget *widget,
+ gint *minimum_height,
+ gint *natural_height)
+{
+ gint focus_width;
+ gint focus_pad;
+
+ gtk_widget_style_get (widget,
+ "focus-line-width", &focus_width,
+ "focus-padding", &focus_pad,
+ NULL);
+
+ *minimum_height = *natural_height = DEFAULT_SIZE + 2 * (focus_width + focus_pad);
+}
+#else
+static void
+gimp_color_wheel_size_request (GtkWidget *widget,
+ GtkRequisition *requisition)
+{
+ gint focus_width;
+ gint focus_pad;
+
+ gtk_widget_style_get (widget,
+ "focus-line-width", &focus_width,
+ "focus-padding", &focus_pad,
+ NULL);
+
+ requisition->width = DEFAULT_SIZE + 2 * (focus_width + focus_pad);
+ requisition->height = DEFAULT_SIZE + 2 * (focus_width + focus_pad);
+}
+#endif
+
+static void
+gimp_color_wheel_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation)
+{
+ GimpColorWheel *wheel = GIMP_COLOR_WHEEL (widget);
+ GimpColorWheelPrivate *priv = wheel->priv;
+ gint focus_width;
+ gint focus_pad;
+
+ gtk_widget_set_allocation (widget, allocation);
+
+ gtk_widget_style_get (widget,
+ "focus-line-width", &focus_width,
+ "focus-padding", &focus_pad,
+ NULL);
+
+ priv->size = MIN (allocation->width - 2 * (focus_width + focus_pad),
+ allocation->height - 2 * (focus_width + focus_pad));
+
+ priv->ring_width = priv->size * priv->ring_fraction;
+
+ if (gtk_widget_get_realized (widget))
+ gdk_window_move_resize (priv->window,
+ allocation->x,
+ allocation->y,
+ allocation->width,
+ allocation->height);
+}
+
+
+/* Utility functions */
+
+#define INTENSITY(r, g, b) ((r) * 0.30 + (g) * 0.59 + (b) * 0.11)
+
+/* Converts from HSV to RGB */
+static void
+hsv_to_rgb (gdouble *h,
+ gdouble *s,
+ gdouble *v)
+{
+ gdouble hue, saturation, value;
+ gdouble f, p, q, t;
+
+ if (*s == 0.0)
+ {
+ *h = *v;
+ *s = *v;
+ *v = *v; /* heh */
+ }
+ else
+ {
+ hue = *h * 6.0;
+ saturation = *s;
+ value = *v;
+
+ if (hue == 6.0)
+ hue = 0.0;
+
+ f = hue - (int) hue;
+ p = value * (1.0 - saturation);
+ q = value * (1.0 - saturation * f);
+ t = value * (1.0 - saturation * (1.0 - f));
+
+ switch ((int) hue)
+ {
+ case 0:
+ *h = value;
+ *s = t;
+ *v = p;
+ break;
+
+ case 1:
+ *h = q;
+ *s = value;
+ *v = p;
+ break;
+
+ case 2:
+ *h = p;
+ *s = value;
+ *v = t;
+ break;
+
+ case 3:
+ *h = p;
+ *s = q;
+ *v = value;
+ break;
+
+ case 4:
+ *h = t;
+ *s = p;
+ *v = value;
+ break;
+
+ case 5:
+ *h = value;
+ *s = p;
+ *v = q;
+ break;
+
+ default:
+ g_assert_not_reached ();
+ }
+ }
+}
+
+/* Computes the vertices of the saturation/value triangle */
+static void
+compute_triangle (GimpColorWheel *wheel,
+ gint *hx,
+ gint *hy,
+ gint *sx,
+ gint *sy,
+ gint *vx,
+ gint *vy)
+{
+ GimpColorWheelPrivate *priv = wheel->priv;
+ GtkAllocation allocation;
+ gdouble center_x;
+ gdouble center_y;
+ gdouble inner, outer;
+ gdouble angle;
+
+ gtk_widget_get_allocation (GTK_WIDGET (wheel), &allocation);
+
+ center_x = allocation.width / 2.0;
+ center_y = allocation.height / 2.0;
+
+ outer = priv->size / 2.0;
+ inner = outer - priv->ring_width;
+ angle = priv->h * 2.0 * G_PI;
+
+ *hx = floor (center_x + cos (angle) * inner + 0.5);
+ *hy = floor (center_y - sin (angle) * inner + 0.5);
+ *sx = floor (center_x + cos (angle + 2.0 * G_PI / 3.0) * inner + 0.5);
+ *sy = floor (center_y - sin (angle + 2.0 * G_PI / 3.0) * inner + 0.5);
+ *vx = floor (center_x + cos (angle + 4.0 * G_PI / 3.0) * inner + 0.5);
+ *vy = floor (center_y - sin (angle + 4.0 * G_PI / 3.0) * inner + 0.5);
+}
+
+/* Computes whether a point is inside the hue ring */
+static gboolean
+is_in_ring (GimpColorWheel *wheel,
+ gdouble x,
+ gdouble y)
+{
+ GimpColorWheelPrivate *priv = wheel->priv;
+ GtkAllocation allocation;
+ gdouble dx, dy, dist;
+ gdouble center_x;
+ gdouble center_y;
+ gdouble inner, outer;
+
+ gtk_widget_get_allocation (GTK_WIDGET (wheel), &allocation);
+
+ center_x = allocation.width / 2.0;
+ center_y = allocation.height / 2.0;
+
+ outer = priv->size / 2.0;
+ inner = outer - priv->ring_width;
+
+ dx = x - center_x;
+ dy = center_y - y;
+ dist = dx * dx + dy * dy;
+
+ return (dist >= inner * inner && dist <= outer * outer);
+}
+
+/* Computes a saturation/value pair based on the mouse coordinates */
+static void
+compute_sv (GimpColorWheel *wheel,
+ gdouble x,
+ gdouble y,
+ gdouble *s,
+ gdouble *v)
+{
+ GtkAllocation allocation;
+ gint ihx, ihy, isx, isy, ivx, ivy;
+ gdouble hx, hy, sx, sy, vx, vy;
+ gdouble center_x;
+ gdouble center_y;
+
+ gtk_widget_get_allocation (GTK_WIDGET (wheel), &allocation);
+
+ compute_triangle (wheel, &ihx, &ihy, &isx, &isy, &ivx, &ivy);
+
+ center_x = allocation.width / 2.0;
+ center_y = allocation.height / 2.0;
+
+ hx = ihx - center_x;
+ hy = center_y - ihy;
+ sx = isx - center_x;
+ sy = center_y - isy;
+ vx = ivx - center_x;
+ vy = center_y - ivy;
+ x -= center_x;
+ y = center_y - y;
+
+ if (vx * (x - sx) + vy * (y - sy) < 0.0)
+ {
+ *s = 1.0;
+ *v = (((x - sx) * (hx - sx) + (y - sy) * (hy-sy))
+ / ((hx - sx) * (hx - sx) + (hy - sy) * (hy - sy)));
+
+ if (*v < 0.0)
+ *v = 0.0;
+ else if (*v > 1.0)
+ *v = 1.0;
+ }
+ else if (hx * (x - sx) + hy * (y - sy) < 0.0)
+ {
+ *s = 0.0;
+ *v = (((x - sx) * (vx - sx) + (y - sy) * (vy - sy))
+ / ((vx - sx) * (vx - sx) + (vy - sy) * (vy - sy)));
+
+ if (*v < 0.0)
+ *v = 0.0;
+ else if (*v > 1.0)
+ *v = 1.0;
+ }
+ else if (sx * (x - hx) + sy * (y - hy) < 0.0)
+ {
+ *v = 1.0;
+ *s = (((x - vx) * (hx - vx) + (y - vy) * (hy - vy)) /
+ ((hx - vx) * (hx - vx) + (hy - vy) * (hy - vy)));
+
+ if (*s < 0.0)
+ *s = 0.0;
+ else if (*s > 1.0)
+ *s = 1.0;
+ }
+ else
+ {
+ *v = (((x - sx) * (hy - vy) - (y - sy) * (hx - vx))
+ / ((vx - sx) * (hy - vy) - (vy - sy) * (hx - vx)));
+
+ if (*v<= 0.0)
+ {
+ *v = 0.0;
+ *s = 0.0;
+ }
+ else
+ {
+ if (*v > 1.0)
+ *v = 1.0;
+
+ if (fabs (hy - vy) < fabs (hx - vx))
+ *s = (x - sx - *v * (vx - sx)) / (*v * (hx - vx));
+ else
+ *s = (y - sy - *v * (vy - sy)) / (*v * (hy - vy));
+
+ if (*s < 0.0)
+ *s = 0.0;
+ else if (*s > 1.0)
+ *s = 1.0;
+ }
+ }
+}
+
+/* Computes whether a point is inside the saturation/value triangle */
+static gboolean
+is_in_triangle (GimpColorWheel *wheel,
+ gdouble x,
+ gdouble y)
+{
+ gint hx, hy, sx, sy, vx, vy;
+ gdouble det, s, v;
+
+ compute_triangle (wheel, &hx, &hy, &sx, &sy, &vx, &vy);
+
+ det = (vx - sx) * (hy - sy) - (vy - sy) * (hx - sx);
+
+ s = ((x - sx) * (hy - sy) - (y - sy) * (hx - sx)) / det;
+ v = ((vx - sx) * (y - sy) - (vy - sy) * (x - sx)) / det;
+
+ return (s >= 0.0 && v >= 0.0 && s + v <= 1.0);
+}
+
+/* Computes a value based on the mouse coordinates */
+static double
+compute_v (GimpColorWheel *wheel,
+ gdouble x,
+ gdouble y)
+{
+ GtkAllocation allocation;
+ gdouble center_x;
+ gdouble center_y;
+ gdouble dx, dy;
+ gdouble angle;
+
+ gtk_widget_get_allocation (GTK_WIDGET (wheel), &allocation);
+
+ center_x = allocation.width / 2.0;
+ center_y = allocation.height / 2.0;
+
+ dx = x - center_x;
+ dy = center_y - y;
+
+ angle = atan2 (dy, dx);
+ if (angle < 0.0)
+ angle += 2.0 * G_PI;
+
+ return angle / (2.0 * G_PI);
+}
+
+static void
+set_cross_grab (GimpColorWheel *wheel,
+ guint32 time)
+{
+ GimpColorWheelPrivate *priv = wheel->priv;
+ GdkCursor *cursor;
+
+ cursor =
+ gdk_cursor_new_for_display (gtk_widget_get_display (GTK_WIDGET (wheel)),
+ GDK_CROSSHAIR);
+
+#if GTK_CHECK_VERSION(3,0,0)
+ gdk_device_grab (gtk_get_current_event_device(),
+ priv->window,
+ GDK_OWNERSHIP_NONE,
+ FALSE,
+ GDK_POINTER_MOTION_MASK |
+ GDK_POINTER_MOTION_HINT_MASK |
+ GDK_BUTTON_RELEASE_MASK,
+ cursor, time);
+ g_object_unref (cursor);
+#else
+ gdk_pointer_grab (priv->window, FALSE,
+ GDK_POINTER_MOTION_MASK |
+ GDK_POINTER_MOTION_HINT_MASK |
+ GDK_BUTTON_RELEASE_MASK,
+ NULL, cursor, time);
+ gdk_cursor_unref (cursor);
+#endif
+}
+
+static gboolean gimp_color_wheel_grab_broken(GtkWidget *widget, GdkEventGrabBroken *event)
+{
+ (void)event;
+ GimpColorWheel *wheel = GIMP_COLOR_WHEEL (widget);
+ GimpColorWheelPrivate *priv = wheel->priv;
+
+ priv->mode = DRAG_NONE;
+
+ return TRUE;
+}
+
+static gboolean
+gimp_color_wheel_button_press (GtkWidget *widget,
+ GdkEventButton *event)
+{
+ GimpColorWheel *wheel = GIMP_COLOR_WHEEL (widget);
+ GimpColorWheelPrivate *priv = wheel->priv;
+ gdouble x, y;
+
+ if (priv->mode != DRAG_NONE || event->button != 1)
+ return FALSE;
+
+ x = event->x;
+ y = event->y;
+
+ if (is_in_ring (wheel, x, y))
+ {
+ priv->mode = DRAG_H;
+ set_cross_grab (wheel, event->time);
+
+ gimp_color_wheel_set_color (wheel,
+ compute_v (wheel, x, y),
+ priv->s,
+ priv->v);
+
+ gtk_widget_grab_focus (widget);
+ priv->focus_on_ring = TRUE;
+
+ return TRUE;
+ }
+
+ if (is_in_triangle (wheel, x, y))
+ {
+ gdouble s, v;
+
+ priv->mode = DRAG_SV;
+ set_cross_grab (wheel, event->time);
+
+ compute_sv (wheel, x, y, &s, &v);
+ gimp_color_wheel_set_color (wheel, priv->h, s, v);
+
+ gtk_widget_grab_focus (widget);
+ priv->focus_on_ring = FALSE;
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static gboolean
+gimp_color_wheel_button_release (GtkWidget *widget,
+ GdkEventButton *event)
+{
+ GimpColorWheel *wheel = GIMP_COLOR_WHEEL (widget);
+ GimpColorWheelPrivate *priv = wheel->priv;
+ DragMode mode;
+ gdouble x, y;
+
+ if (priv->mode == DRAG_NONE || event->button != 1)
+ return FALSE;
+
+ /* Set the drag mode to DRAG_NONE so that signal handlers for "catched"
+ * can see that this is the final color state.
+ */
+
+ mode = priv->mode;
+ priv->mode = DRAG_NONE;
+
+ x = event->x;
+ y = event->y;
+
+ if (mode == DRAG_H)
+ {
+ gimp_color_wheel_set_color (wheel,
+ compute_v (wheel, x, y), priv->s, priv->v);
+ }
+ else if (mode == DRAG_SV)
+ {
+ gdouble s, v;
+
+ compute_sv (wheel, x, y, &s, &v);
+ gimp_color_wheel_set_color (wheel, priv->h, s, v);
+ }
+ else
+ g_assert_not_reached ();
+
+#if GTK_CHECK_VERSION(3,0,0)
+ gdk_device_ungrab (gtk_get_current_event_device(),
+ event->time);
+#else
+ gdk_display_pointer_ungrab (gdk_window_get_display (event->window),
+ event->time);
+#endif
+
+ return TRUE;
+}
+
+static gboolean
+gimp_color_wheel_motion (GtkWidget *widget,
+ GdkEventMotion *event)
+{
+ GimpColorWheel *wheel = GIMP_COLOR_WHEEL (widget);
+ GimpColorWheelPrivate *priv = wheel->priv;
+ gdouble x, y;
+
+ if (priv->mode == DRAG_NONE)
+ return FALSE;
+
+ gdk_event_request_motions (event);
+ x = event->x;
+ y = event->y;
+
+ if (priv->mode == DRAG_H)
+ {
+ gimp_color_wheel_set_color (wheel,
+ compute_v (wheel, x, y), priv->s, priv->v);
+ return TRUE;
+ }
+ else if (priv->mode == DRAG_SV)
+ {
+ gdouble s, v;
+
+ compute_sv (wheel, x, y, &s, &v);
+ gimp_color_wheel_set_color (wheel, priv->h, s, v);
+ return TRUE;
+ }
+
+ g_assert_not_reached ();
+
+ return FALSE;
+}
+
+
+/* Redrawing */
+
+/* Paints the hue ring */
+static void
+paint_ring (GimpColorWheel *wheel,
+ cairo_t *cr)
+{
+#if GTK_CHECK_VERSION(3,0,0)
+ GtkWidget *widget = GTK_WIDGET (wheel);
+#else
+ GtkAllocation allocation;
+#endif
+ GimpColorWheelPrivate *priv = wheel->priv;
+ gint width, height;
+ gint xx, yy;
+ gdouble dx, dy, dist;
+ gdouble center_x;
+ gdouble center_y;
+ gdouble inner, outer;
+ guint32 *buf, *p;
+ gdouble angle;
+ gdouble hue;
+ gdouble r, g, b;
+ cairo_surface_t *source;
+ cairo_t *source_cr;
+ gint stride;
+
+#if GTK_CHECK_VERSION(3,0,0)
+ width = gtk_widget_get_allocated_width (widget);
+ height = gtk_widget_get_allocated_height (widget);
+#else
+ gtk_widget_get_allocation (GTK_WIDGET (wheel), &allocation);
+ width = allocation.width;
+ height = allocation.height;
+#endif
+
+ center_x = width / 2.0;
+ center_y = height / 2.0;
+
+ outer = priv->size / 2.0;
+ inner = outer - priv->ring_width;
+
+ /* Create an image initialized with the ring colors */
+
+ stride = cairo_format_stride_for_width (CAIRO_FORMAT_RGB24, width);
+ buf = g_new (guint32, height * stride / 4);
+
+ for (yy = 0; yy < height; yy++)
+ {
+ p = buf + yy * width;
+ dy = -(yy - center_y);
+
+ for (xx = 0; xx < width; xx++)
+ {
+ dx = xx - center_x;
+
+ dist = dx * dx + dy * dy;
+ if (dist < ((inner-1) * (inner-1)) || dist > ((outer+1) * (outer+1)))
+ {
+ *p++ = 0;
+ continue;
+ }
+
+ angle = atan2 (dy, dx);
+ if (angle < 0.0)
+ angle += 2.0 * G_PI;
+
+ hue = angle / (2.0 * G_PI);
+
+ r = hue;
+ g = 1.0;
+ b = 1.0;
+ hsv_to_rgb (&r, &g, &b);
+
+ *p++ = (((int)floor (r * 255 + 0.5) << 16) |
+ ((int)floor (g * 255 + 0.5) << 8) |
+ (int)floor (b * 255 + 0.5));
+ }
+ }
+
+ source = cairo_image_surface_create_for_data ((unsigned char *)buf,
+ CAIRO_FORMAT_RGB24,
+ width, height, stride);
+
+ /* Now draw the value marker onto the source image, so that it
+ * will get properly clipped at the edges of the ring
+ */
+ source_cr = cairo_create (source);
+
+ r = priv->h;
+ g = 1.0;
+ b = 1.0;
+ hsv_to_rgb (&r, &g, &b);
+
+ if (INTENSITY (r, g, b) > 0.5)
+ cairo_set_source_rgb (source_cr, 0.0, 0.0, 0.0);
+ else
+ cairo_set_source_rgb (source_cr, 1.0, 1.0, 1.0);
+
+ cairo_move_to (source_cr, center_x, center_y);
+ cairo_line_to (source_cr,
+ center_x + cos (priv->h * 2.0 * G_PI) * priv->size / 2,
+ center_y - sin (priv->h * 2.0 * G_PI) * priv->size / 2);
+ cairo_stroke (source_cr);
+ cairo_destroy (source_cr);
+
+ /* Draw the ring using the source image */
+
+ cairo_save (cr);
+
+ cairo_set_source_surface (cr, source, 0, 0);
+ cairo_surface_destroy (source);
+
+ cairo_set_line_width (cr, priv->ring_width);
+ cairo_new_path (cr);
+ cairo_arc (cr,
+ center_x, center_y,
+ priv->size / 2.0 - priv->ring_width / 2.0,
+ 0, 2 * G_PI);
+ cairo_stroke (cr);
+
+ cairo_restore (cr);
+
+ g_free (buf);
+}
+
+/* Converts an HSV triplet to an integer RGB triplet */
+static void
+get_color (gdouble h,
+ gdouble s,
+ gdouble v,
+ gint *r,
+ gint *g,
+ gint *b)
+{
+ hsv_to_rgb (&h, &s, &v);
+
+ *r = floor (h * 255 + 0.5);
+ *g = floor (s * 255 + 0.5);
+ *b = floor (v * 255 + 0.5);
+}
+
+#define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
+
+#define LERP(a, b, v1, v2, i) (((v2) - (v1) != 0) \
+ ? ((a) + ((b) - (a)) * ((i) - (v1)) / ((v2) - (v1))) \
+ : (a))
+
+/* Number of pixels we extend out from the edges when creating
+ * color source to avoid artifacts
+ */
+#define PAD 3
+
+/* Paints the HSV triangle */
+static void
+paint_triangle (GimpColorWheel *wheel,
+ cairo_t *cr,
+ gboolean draw_focus)
+{
+ GtkWidget *widget = GTK_WIDGET (wheel);
+ GimpColorWheelPrivate *priv = wheel->priv;
+ gint hx, hy, sx, sy, vx, vy; /* HSV vertices */
+ gint x1, y1, r1, g1, b1; /* First vertex in scanline order */
+ gint x2, y2, r2, g2, b2; /* Second vertex */
+ gint x3, y3, r3, g3, b3; /* Third vertex */
+ gint t;
+ guint32 *buf, *p, c;
+ gint xl, xr, rl, rr, gl, gr, bl, br; /* Scanline data */
+ gint xx, yy;
+ gint x_interp, y_interp;
+ gint x_start, x_end;
+ cairo_surface_t *source;
+ gdouble r, g, b;
+ gint stride;
+ gint width, height;
+#if GTK_CHECK_VERSION(3,0,0)
+ GtkStyleContext *context;
+
+ width = gtk_widget_get_allocated_width (widget);
+ height = gtk_widget_get_allocated_height (widget);
+#else
+ gchar *detail;
+
+ GtkAllocation allocation;
+ gtk_widget_get_allocation (widget, &allocation);
+ width = allocation.width;
+ height = allocation.height;
+#endif
+
+ /* Compute triangle's vertices */
+
+ compute_triangle (wheel, &hx, &hy, &sx, &sy, &vx, &vy);
+
+ x1 = hx;
+ y1 = hy;
+ get_color (priv->h, 1.0, 1.0, &r1, &g1, &b1);
+
+ x2 = sx;
+ y2 = sy;
+ get_color (priv->h, 1.0, 0.0, &r2, &g2, &b2);
+
+ x3 = vx;
+ y3 = vy;
+ get_color (priv->h, 0.0, 1.0, &r3, &g3, &b3);
+
+ if (y2 > y3)
+ {
+ SWAP (x2, x3, t);
+ SWAP (y2, y3, t);
+ SWAP (r2, r3, t);
+ SWAP (g2, g3, t);
+ SWAP (b2, b3, t);
+ }
+
+ if (y1 > y3)
+ {
+ SWAP (x1, x3, t);
+ SWAP (y1, y3, t);
+ SWAP (r1, r3, t);
+ SWAP (g1, g3, t);
+ SWAP (b1, b3, t);
+ }
+
+ if (y1 > y2)
+ {
+ SWAP (x1, x2, t);
+ SWAP (y1, y2, t);
+ SWAP (r1, r2, t);
+ SWAP (g1, g2, t);
+ SWAP (b1, b2, t);
+ }
+
+ /* Shade the triangle */
+
+ stride = cairo_format_stride_for_width (CAIRO_FORMAT_RGB24, width);
+ buf = g_new (guint32, height * stride / 4);
+
+ for (yy = 0; yy < height; yy++)
+ {
+ p = buf + yy * width;
+
+ if (yy >= y1 - PAD && yy < y3 + PAD)
+ {
+ y_interp = CLAMP (yy, y1, y3);
+
+ if (y_interp < y2)
+ {
+ xl = LERP (x1, x2, y1, y2, y_interp);
+
+ rl = LERP (r1, r2, y1, y2, y_interp);
+ gl = LERP (g1, g2, y1, y2, y_interp);
+ bl = LERP (b1, b2, y1, y2, y_interp);
+ }
+ else
+ {
+ xl = LERP (x2, x3, y2, y3, y_interp);
+
+ rl = LERP (r2, r3, y2, y3, y_interp);
+ gl = LERP (g2, g3, y2, y3, y_interp);
+ bl = LERP (b2, b3, y2, y3, y_interp);
+ }
+
+ xr = LERP (x1, x3, y1, y3, y_interp);
+
+ rr = LERP (r1, r3, y1, y3, y_interp);
+ gr = LERP (g1, g3, y1, y3, y_interp);
+ br = LERP (b1, b3, y1, y3, y_interp);
+
+ if (xl > xr)
+ {
+ SWAP (xl, xr, t);
+ SWAP (rl, rr, t);
+ SWAP (gl, gr, t);
+ SWAP (bl, br, t);
+ }
+
+ x_start = MAX (xl - PAD, 0);
+ x_end = MIN (xr + PAD, width);
+ x_start = MIN (x_start, x_end);
+
+ c = (rl << 16) | (gl << 8) | bl;
+
+ for (xx = 0; xx < x_start; xx++)
+ *p++ = c;
+
+ for (; xx < x_end; xx++)
+ {
+ x_interp = CLAMP (xx, xl, xr);
+
+ *p++ = ((LERP (rl, rr, xl, xr, x_interp) << 16) |
+ (LERP (gl, gr, xl, xr, x_interp) << 8) |
+ LERP (bl, br, xl, xr, x_interp));
+ }
+
+ c = (rr << 16) | (gr << 8) | br;
+
+ for (; xx < width; xx++)
+ *p++ = c;
+ }
+ }
+
+ source = cairo_image_surface_create_for_data ((unsigned char *)buf,
+ CAIRO_FORMAT_RGB24,
+ width, height, stride);
+
+ /* Draw a triangle with the image as a source */
+
+ cairo_set_source_surface (cr, source, 0, 0);
+ cairo_surface_destroy (source);
+
+ cairo_move_to (cr, x1, y1);
+ cairo_line_to (cr, x2, y2);
+ cairo_line_to (cr, x3, y3);
+ cairo_close_path (cr);
+ cairo_fill (cr);
+
+ g_free (buf);
+
+ /* Draw value marker */
+
+ xx = floor (sx + (vx - sx) * priv->v + (hx - vx) * priv->s * priv->v + 0.5);
+ yy = floor (sy + (vy - sy) * priv->v + (hy - vy) * priv->s * priv->v + 0.5);
+
+ r = priv->h;
+ g = priv->s;
+ b = priv->v;
+ hsv_to_rgb (&r, &g, &b);
+
+#if GTK_CHECK_VERSION(3,0,0)
+ context = gtk_widget_get_style_context (widget);
+
+ gtk_style_context_save (context);
+#endif
+
+ if (INTENSITY (r, g, b) > 0.5)
+ {
+#if GTK_CHECK_VERSION(3,0,0)
+ gtk_style_context_add_class (context, "light-area-focus");
+#else
+ detail = "colorwheel_light";
+#endif
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+ }
+ else
+ {
+#if GTK_CHECK_VERSION(3,0,0)
+ gtk_style_context_add_class (context, "dark-area-focus");
+#else
+ detail = "colorwheel_dark";
+#endif
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
+ }
+
+#define RADIUS 4
+#define FOCUS_RADIUS 6
+
+ cairo_new_path (cr);
+ cairo_arc (cr, xx, yy, RADIUS, 0, 2 * G_PI);
+ cairo_stroke (cr);
+
+ /* Draw focus outline */
+
+ if (draw_focus && ! priv->focus_on_ring)
+ {
+ gint focus_width;
+ gint focus_pad;
+
+ gtk_widget_style_get (widget,
+ "focus-line-width", &focus_width,
+ "focus-padding", &focus_pad,
+ NULL);
+
+#if GTK_CHECK_VERSION(3,0,0)
+ gtk_render_focus (context, cr,
+ xx - FOCUS_RADIUS - focus_width - focus_pad,
+ yy - FOCUS_RADIUS - focus_width - focus_pad,
+ 2 * (FOCUS_RADIUS + focus_width + focus_pad),
+ 2 * (FOCUS_RADIUS + focus_width + focus_pad));
+#else
+ gtk_widget_get_allocation (widget, &allocation);
+ gtk_paint_focus (gtk_widget_get_style (widget),
+ gtk_widget_get_window (widget),
+ gtk_widget_get_state (widget),
+ NULL, widget, detail,
+ allocation.x + xx - FOCUS_RADIUS - focus_width - focus_pad,
+ allocation.y + yy - FOCUS_RADIUS - focus_width - focus_pad,
+ 2 * (FOCUS_RADIUS + focus_width + focus_pad),
+ 2 * (FOCUS_RADIUS + focus_width + focus_pad));
+#endif
+ }
+
+#if GTK_CHECK_VERSION(3,0,0)
+ gtk_style_context_restore (context);
+#endif
+}
+
+#if GTK_CHECK_VERSION(3,2,0)
+static gboolean
+gimp_color_wheel_draw (GtkWidget *widget,
+ cairo_t *cr)
+{
+ GimpColorWheel *wheel = GIMP_COLOR_WHEEL (widget);
+ GimpColorWheelPrivate *priv = wheel->priv;
+ gboolean draw_focus;
+
+ draw_focus = gtk_widget_has_visible_focus (widget);
+
+ paint_ring (wheel, cr);
+ paint_triangle (wheel, cr, draw_focus);
+
+ if (draw_focus && priv->focus_on_ring)
+ {
+ GtkStyleContext *context = gtk_widget_get_style_context (widget);
+
+ gtk_render_focus (context, cr, 0, 0,
+ gtk_widget_get_allocated_width (widget),
+ gtk_widget_get_allocated_height (widget));
+ }
+
+ return FALSE;
+}
+#else
+static gint
+gimp_color_wheel_expose (GtkWidget *widget,
+ GdkEventExpose *event)
+{
+ cairo_t *cr = gdk_cairo_create (gtk_widget_get_window (widget));
+
+ GimpColorWheel *wheel = GIMP_COLOR_WHEEL (widget);
+ GimpColorWheelPrivate *priv = wheel->priv;
+ gboolean draw_focus;
+ GtkAllocation allocation;
+
+ if (! (event->window == gtk_widget_get_window (widget) &&
+ gtk_widget_is_drawable (widget)))
+ return FALSE;
+
+ gdk_cairo_region (cr, event->region);
+ cairo_clip (cr);
+
+ gtk_widget_get_allocation (widget, &allocation);
+ cairo_translate (cr, allocation.x, allocation.y);
+
+ draw_focus = gtk_widget_has_focus (widget);
+
+ paint_ring (wheel, cr);
+ paint_triangle (wheel, cr, draw_focus);
+
+ cairo_destroy (cr);
+
+ if (draw_focus && priv->focus_on_ring)
+ gtk_paint_focus (gtk_widget_get_style (widget),
+ gtk_widget_get_window (widget),
+ gtk_widget_get_state (widget),
+ &event->area, widget, NULL,
+ allocation.x,
+ allocation.y,
+ allocation.width,
+ allocation.height);
+
+ return FALSE;
+}
+#endif
+
+static gboolean
+gimp_color_wheel_focus (GtkWidget *widget,
+ GtkDirectionType dir)
+{
+ GimpColorWheel *wheel = GIMP_COLOR_WHEEL (widget);
+ GimpColorWheelPrivate *priv = wheel->priv;
+
+ if (!gtk_widget_has_focus (widget))
+ {
+ if (dir == GTK_DIR_TAB_BACKWARD)
+ priv->focus_on_ring = FALSE;
+ else
+ priv->focus_on_ring = TRUE;
+
+ gtk_widget_grab_focus (widget);
+ return TRUE;
+ }
+
+ switch (dir)
+ {
+ case GTK_DIR_UP:
+ if (priv->focus_on_ring)
+ return FALSE;
+ else
+ priv->focus_on_ring = TRUE;
+ break;
+
+ case GTK_DIR_DOWN:
+ if (priv->focus_on_ring)
+ priv->focus_on_ring = FALSE;
+ else
+ return FALSE;
+ break;
+
+ case GTK_DIR_LEFT:
+ case GTK_DIR_TAB_BACKWARD:
+ if (priv->focus_on_ring)
+ return FALSE;
+ else
+ priv->focus_on_ring = TRUE;
+ break;
+
+ case GTK_DIR_RIGHT:
+ case GTK_DIR_TAB_FORWARD:
+ if (priv->focus_on_ring)
+ priv->focus_on_ring = FALSE;
+ else
+ return FALSE;
+ break;
+ }
+
+ gtk_widget_queue_draw (widget);
+
+ return TRUE;
+}
+
+/**
+ * gimp_color_wheel_new:
+ *
+ * Creates a new HSV color selector.
+ *
+ * Return value: A newly-created HSV color selector.
+ *
+ * Since: 2.14
+ */
+GtkWidget*
+gimp_color_wheel_new (void)
+{
+ return g_object_new (GIMP_TYPE_COLOR_WHEEL, NULL);
+}
+
+/**
+ * gimp_color_wheel_set_color:
+ * @hsv: An HSV color selector
+ * @h: Hue
+ * @s: Saturation
+ * @v: Value
+ *
+ * Sets the current color in an HSV color selector.
+ * Color component values must be in the [0.0, 1.0] range.
+ *
+ * Since: 2.14
+ */
+void
+gimp_color_wheel_set_color (GimpColorWheel *wheel,
+ gdouble h,
+ gdouble s,
+ gdouble v)
+{
+ GimpColorWheelPrivate *priv;
+
+ g_return_if_fail (GIMP_IS_COLOR_WHEEL (wheel));
+ g_return_if_fail (h >= 0.0 && h <= 1.0);
+ g_return_if_fail (s >= 0.0 && s <= 1.0);
+ g_return_if_fail (v >= 0.0 && v <= 1.0);
+
+ priv = wheel->priv;
+
+ priv->h = h;
+ priv->s = s;
+ priv->v = v;
+
+ g_signal_emit (wheel, wheel_signals[CHANGED], 0);
+
+ gtk_widget_queue_draw (GTK_WIDGET (wheel));
+}
+
+/**
+ * gimp_color_wheel_get_color:
+ * @hsv: An HSV color selector
+ * @h: (out): Return value for the hue
+ * @s: (out): Return value for the saturation
+ * @v: (out): Return value for the value
+ *
+ * Queries the current color in an HSV color selector.
+ * Returned values will be in the [0.0, 1.0] range.
+ *
+ * Since: 2.14
+ */
+void
+gimp_color_wheel_get_color (GimpColorWheel *wheel,
+ gdouble *h,
+ gdouble *s,
+ gdouble *v)
+{
+ GimpColorWheelPrivate *priv;
+
+ g_return_if_fail (GIMP_IS_COLOR_WHEEL (wheel));
+
+ priv = wheel->priv;
+
+ if (h) *h = priv->h;
+ if (s) *s = priv->s;
+ if (v) *v = priv->v;
+}
+
+/**
+ * gimp_color_wheel_set_ring_fraction:
+ * @ring: A wheel color selector
+ * @fraction: Ring fraction
+ *
+ * Sets the ring fraction of a wheel color selector.
+ *
+ * Since: GIMP 2.10
+ */
+void
+gimp_color_wheel_set_ring_fraction (GimpColorWheel *hsv,
+ gdouble fraction)
+{
+ GimpColorWheelPrivate *priv;
+
+ g_return_if_fail (GIMP_IS_COLOR_WHEEL (hsv));
+
+ priv = hsv->priv;
+
+ priv->ring_fraction = CLAMP (fraction, 0.01, 0.99);
+
+ gtk_widget_queue_draw (GTK_WIDGET (hsv));
+}
+
+/**
+ * gimp_color_wheel_get_ring_fraction:
+ * @ring: A wheel color selector
+ *
+ * Returns value: The ring fraction of the wheel color selector.
+ *
+ * Since: GIMP 2.10
+ */
+gdouble
+gimp_color_wheel_get_ring_fraction (GimpColorWheel *wheel)
+{
+ GimpColorWheelPrivate *priv;
+
+ g_return_val_if_fail (GIMP_IS_COLOR_WHEEL (wheel), DEFAULT_FRACTION);
+
+ priv = wheel->priv;
+
+ return priv->ring_fraction;
+}
+
+/**
+ * gimp_color_wheel_is_adjusting:
+ * @hsv: A #GimpColorWheel
+ *
+ * An HSV color selector can be said to be adjusting if multiple rapid
+ * changes are being made to its value, for example, when the user is
+ * adjusting the value with the mouse. This function queries whether
+ * the HSV color selector is being adjusted or not.
+ *
+ * Return value: %TRUE if clients can ignore changes to the color value,
+ * since they may be transitory, or %FALSE if they should consider
+ * the color value status to be final.
+ *
+ * Since: 2.14
+ */
+gboolean
+gimp_color_wheel_is_adjusting (GimpColorWheel *wheel)
+{
+ GimpColorWheelPrivate *priv;
+
+ g_return_val_if_fail (GIMP_IS_COLOR_WHEEL (wheel), FALSE);
+
+ priv = wheel->priv;
+
+ return priv->mode != DRAG_NONE;
+}
+
+static void
+gimp_color_wheel_move (GimpColorWheel *wheel,
+ GtkDirectionType dir)
+{
+ GimpColorWheelPrivate *priv = wheel->priv;
+ gdouble hue, sat, val;
+ gint hx, hy, sx, sy, vx, vy; /* HSV vertices */
+ gint x, y; /* position in triangle */
+
+ hue = priv->h;
+ sat = priv->s;
+ val = priv->v;
+
+ compute_triangle (wheel, &hx, &hy, &sx, &sy, &vx, &vy);
+
+ x = floor (sx + (vx - sx) * priv->v + (hx - vx) * priv->s * priv->v + 0.5);
+ y = floor (sy + (vy - sy) * priv->v + (hy - vy) * priv->s * priv->v + 0.5);
+
+#define HUE_DELTA 0.002
+ switch (dir)
+ {
+ case GTK_DIR_UP:
+ if (priv->focus_on_ring)
+ hue += HUE_DELTA;
+ else
+ {
+ y -= 1;
+ compute_sv (wheel, x, y, &sat, &val);
+ }
+ break;
+
+ case GTK_DIR_DOWN:
+ if (priv->focus_on_ring)
+ hue -= HUE_DELTA;
+ else
+ {
+ y += 1;
+ compute_sv (wheel, x, y, &sat, &val);
+ }
+ break;
+
+ case GTK_DIR_LEFT:
+ if (priv->focus_on_ring)
+ hue += HUE_DELTA;
+ else
+ {
+ x -= 1;
+ compute_sv (wheel, x, y, &sat, &val);
+ }
+ break;
+
+ case GTK_DIR_RIGHT:
+ if (priv->focus_on_ring)
+ hue -= HUE_DELTA
+ ;
+ else
+ {
+ x += 1;
+ compute_sv (wheel, x, y, &sat, &val);
+ }
+ break;
+
+ default:
+ /* we don't care about the tab directions */
+ break;
+ }
+
+ /* Wrap */
+ if (hue < 0.0)
+ hue = 1.0;
+ else if (hue > 1.0)
+ hue = 0.0;
+
+ gimp_color_wheel_set_color (wheel, hue, sat, val);
+}
diff --git a/src/ui/widget/gimpcolorwheel.h b/src/ui/widget/gimpcolorwheel.h
new file mode 100644
index 000000000..016fb593f
--- /dev/null
+++ b/src/ui/widget/gimpcolorwheel.h
@@ -0,0 +1,95 @@
+/* HSV color selector for GTK+
+ *
+ * Copyright (C) 1999 The Free Software Foundation
+ *
+ * Authors: Simon Budig <Simon.Budig@unix-ag.org> (original code)
+ * Federico Mena-Quintero <federico@gimp.org> (cleanup for GTK+)
+ * Jonathan Blandford <jrb@redhat.com> (cleanup for GTK+)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GTK+ Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#ifndef __GIMP_COLOR_WHEEL_H__
+#define __GIMP_COLOR_WHEEL_H__
+
+G_BEGIN_DECLS
+
+#define GIMP_TYPE_COLOR_WHEEL (gimp_color_wheel_get_type ())
+#define GIMP_COLOR_WHEEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_COLOR_WHEEL, GimpColorWheel))
+#define GIMP_COLOR_WHEEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_COLOR_WHEEL, GimpColorWheelClass))
+#define GIMP_IS_COLOR_WHEEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_COLOR_WHEEL))
+#define GIMP_IS_COLOR_WHEEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_COLOR_WHEEL))
+#define GIMP_COLOR_WHEEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_COLOR_WHEEL, GimpColorWheelClass))
+
+
+typedef struct _GimpColorWheel GimpColorWheel;
+typedef struct _GimpColorWheelClass GimpColorWheelClass;
+
+struct _GimpColorWheel
+{
+ GtkWidget parent_instance;
+
+ /* Private data */
+ gpointer priv;
+};
+
+struct _GimpColorWheelClass
+{
+ GtkWidgetClass parent_class;
+
+ /* Notification signals */
+ void (* changed) (GimpColorWheel *wheel);
+
+ /* Keybindings */
+ void (* move) (GimpColorWheel *wheel,
+ GtkDirectionType type);
+
+ /* Padding for future expansion */
+ void (*_gimp_reserved1) (void);
+ void (*_gimp_reserved2) (void);
+ void (*_gimp_reserved3) (void);
+ void (*_gimp_reserved4) (void);
+};
+
+
+GType gimp_color_wheel_get_type (void) G_GNUC_CONST;
+GtkWidget * gimp_color_wheel_new (void);
+
+void gimp_color_wheel_set_color (GimpColorWheel *wheel,
+ double h,
+ double s,
+ double v);
+void gimp_color_wheel_get_color (GimpColorWheel *wheel,
+ gdouble *h,
+ gdouble *s,
+ gdouble *v);
+
+void gimp_color_wheel_set_ring_fraction (GimpColorWheel *wheel,
+ gdouble fraction);
+gdouble gimp_color_wheel_get_ring_fraction (GimpColorWheel *wheel);
+
+gboolean gimp_color_wheel_is_adjusting (GimpColorWheel *wheel);
+
+G_END_DECLS
+
+#endif /* __GIMP_COLOR_WHEEL_H__ */
diff --git a/src/ui/widget/gimpspinscale.c b/src/ui/widget/gimpspinscale.c
new file mode 100644
index 000000000..d99646a64
--- /dev/null
+++ b/src/ui/widget/gimpspinscale.c
@@ -0,0 +1,1225 @@
+/* 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_widget_add_events (GTK_WIDGET (scale),
+ GDK_BUTTON_PRESS_MASK |
+ GDK_BUTTON_RELEASE_MASK |
+ GDK_POINTER_MOTION_MASK |
+ GDK_BUTTON1_MOTION_MASK |
+ GDK_LEAVE_NOTIFY_MASK);
+
+ 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);
+ GimpSpinScale *scale = GIMP_SPIN_SCALE (object);
+
+ switch (property_id)
+ {
+ case PROP_LABEL:
+ gimp_spin_scale_set_label (scale, g_value_get_string (value));
+ break;
+
+ case PROP_FOCUS_WIDGET:
+ {
+ /* TODO unhook prior */
+ private->focusWidget = GTK_WIDGET (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);
+ GimpSpinScale *scale = GIMP_SPIN_SCALE (object);
+
+ switch (property_id)
+ {
+ case PROP_LABEL:
+ g_value_set_string (value, gimp_spin_scale_get_label (scale));
+ 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;
+ }
+}
+
+#if GTK_CHECK_VERSION(3,0,0)
+static void
+gimp_spin_scale_get_preferred_width (GtkWidget *widget,
+ gint *minimum_width,
+ gint *natural_width)
+{
+ GimpSpinScalePrivate *private = GET_PRIVATE (widget);
+ PangoContext *context = gtk_widget_get_pango_context (widget);
+ PangoFontMetrics *metrics;
+
+ GTK_WIDGET_CLASS (parent_class)->get_preferred_width (widget,
+ minimum_width,
+ natural_width);
+
+ metrics = pango_context_get_metrics (context,
+ pango_context_get_font_description (context),
+ pango_context_get_language (context));
+
+ 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));
+
+ /* ~3 chars for the ellipse */
+ *minimum_width += char_pixels * 3;
+ *natural_width += char_pixels * 3;
+ }
+
+ pango_font_metrics_unref (metrics);
+}
+
+static void
+gimp_spin_scale_get_preferred_height (GtkWidget *widget,
+ gint *minimum_height,
+ gint *natural_height)
+{
+ 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,
+ pango_context_get_font_description (context),
+ 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);
+}
+#else
+static void
+gimp_spin_scale_size_request (GtkWidget *widget,
+ GtkRequisition *requisition)
+{
+ GimpSpinScalePrivate *private = GET_PRIVATE (widget);
+ GtkStyle *style = gtk_widget_get_style (widget);
+ PangoContext *context = gtk_widget_get_pango_context (widget);
+ PangoFontMetrics *metrics;
+ gint height;
+
+ GTK_WIDGET_CLASS (parent_class)->size_request (widget, requisition);
+
+ 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));
+
+ if (private->appearanceMode == APPEARANCE_COMPACT) {
+ requisition->height += 1;
+ } else {
+ requisition->height += height;
+ }
+
+ 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));
+
+ /* ~3 chars for the ellipses */
+ requisition->width += char_pixels * 3;
+ }
+
+ 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 GTK_CHECK_VERSION(3,0,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);
+#if GTK_CHECK_VERSION(3,0,0)
+ GtkStyleContext *style = gtk_widget_get_style_context(widget);
+ GtkAllocation allocation;
+ GdkRGBA color;
+
+ cairo_save (cr);
+ GTK_WIDGET_CLASS (parent_class)->draw (widget, cr);
+ cairo_restore (cr);
+
+ gtk_widget_get_allocation (widget, &allocation);
+#else
+ GtkStyle *style = gtk_widget_get_style (widget);
+ 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 GTK_CHECK_VERSION(3,0,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 GTK_CHECK_VERSION(3,0,0)
+ GtkStateFlags state;
+ GdkRGBA text_color;
+ GdkRGBA bar_text_color;
+#else
+ GtkStateType state;
+ GdkColor text_color;
+ GdkColor bar_text_color;
+ gint window_width;
+ gint window_height;
+#endif
+ gdouble progress_fraction;
+ gint progress_x;
+ gint progress_y;
+ gint progress_width;
+ gint progress_height;
+
+#if GTK_CHECK_VERSION(3,0,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 GTK_CHECK_VERSION(3,0,0)
+ (allocation.width - minimum_width));
+#else
+ (allocation.width - requisition.width));
+#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 GTK_CHECK_VERSION(3,0,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 GTK_CHECK_VERSION(3,0,0)
+ state = gtk_widget_get_state_flags (widget);
+
+ gtk_style_context_get_color (style, state, &text_color);
+
+ gtk_style_context_save (style);
+ gtk_style_context_add_class (style, GTK_STYLE_CLASS_PROGRESSBAR);
+ gtk_style_context_get_color (style, state, &bar_text_color);
+ gtk_style_context_restore (style);
+#else
+ state = GTK_STATE_SELECTED;
+ if (! gtk_widget_get_sensitive (widget))
+ state = GTK_STATE_INSENSITIVE;
+ text_color = style->text[gtk_widget_get_state (widget)];
+ bar_text_color = style->fg[state];
+
+ window_width = gdk_window_get_width (event->window);
+ window_height = gdk_window_get_height (event->window);
+#endif
+
+ progress_fraction = gtk_entry_get_progress_fraction (GTK_ENTRY (widget));
+
+ if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
+ {
+ progress_fraction = 1.0 - progress_fraction;
+
+#if GTK_CHECK_VERSION(3,0,0)
+ progress_x = text_area.width * progress_fraction;
+#else
+ progress_x = window_width * progress_fraction;
+#endif
+ progress_y = 0;
+#if GTK_CHECK_VERSION(3,0,0)
+ progress_width = text_area.width - progress_x;
+ progress_height = text_area.height;
+#else
+ progress_width = window_width - progress_x;
+ progress_height = window_height;
+#endif
+ }
+ else
+ {
+ progress_x = 0;
+ progress_y = 0;
+#if GTK_CHECK_VERSION(3,0,0)
+ progress_width = text_area.width * progress_fraction;
+ progress_height = text_area.height;
+#else
+ progress_width = window_width * progress_fraction;
+ progress_height = window_height;
+#endif
+ }
+
+ cairo_save (cr);
+
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+#if GTK_CHECK_VERSION(3,0,0)
+ cairo_rectangle (cr, 0, 0, text_area.width, text_area.height);
+#else
+ cairo_rectangle (cr, 0, 0, window_width, window_height);
+#endif
+ cairo_rectangle (cr, progress_x, progress_y,
+ progress_width, progress_height);
+ cairo_clip (cr);
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_WINDING);
+
+#if GTK_CHECK_VERSION(3,0,0)
+ cairo_move_to (cr, layout_offset_x, text_area.y + layout_offset_y-3);
+ gdk_cairo_set_source_rgba (cr, &text_color);
+#else
+ cairo_move_to (cr, layout_offset_x, layout_offset_y-3);
+ gdk_cairo_set_source_color (cr, &text_color);
+#endif
+ pango_cairo_show_layout (cr, private->layout);
+ cairo_restore (cr);
+
+ cairo_rectangle (cr, progress_x, progress_y,
+ progress_width, progress_height);
+ cairo_clip (cr);
+
+#if GTK_CHECK_VERSION(3,0,0)
+ cairo_move_to (cr, layout_offset_x, text_area.y + layout_offset_y-3);
+ gdk_cairo_set_source_rgba (cr, &bar_text_color);
+#else
+ cairo_move_to (cr, layout_offset_x, layout_offset_y-3);
+ gdk_cairo_set_source_color (cr, &bar_text_color);
+#endif
+ pango_cairo_show_layout (cr, private->layout);
+ }
+
+#if !GTK_CHECK_VERSION(3,0,0)
+ 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);
+
+ gdk_event_request_motions (event);
+
+#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_label (GimpSpinScale *scale,
+ const gchar *label)
+{
+ GimpSpinScalePrivate *private;
+
+ g_return_if_fail (GIMP_IS_SPIN_SCALE (scale));
+
+ private = GET_PRIVATE (scale);
+
+ if (label == private->label)
+ return;
+
+ g_free (private->label);
+ private->label = g_strdup (label);
+
+ if (private->layout)
+ {
+ g_object_unref (private->layout);
+ private->layout = NULL;
+ }
+
+ gtk_widget_queue_resize (GTK_WIDGET (scale));
+
+ g_object_notify (G_OBJECT (scale), "label");
+}
+
+const gchar *
+gimp_spin_scale_get_label (GimpSpinScale *scale)
+{
+ g_return_val_if_fail (GIMP_IS_SPIN_SCALE (scale), NULL);
+
+ return GET_PRIVATE (scale)->label;
+}
+
+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_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;
+}
+
+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)
+{
+ g_return_val_if_fail (GIMP_IS_SPIN_SCALE (scale), 1.0);
+
+ return GET_PRIVATE(scale)->gamma;
+}
diff --git a/src/ui/widget/gimpspinscale.h b/src/ui/widget/gimpspinscale.h
new file mode 100644
index 000000000..b42a0faf8
--- /dev/null
+++ b/src/ui/widget/gimpspinscale.h
@@ -0,0 +1,82 @@
+/* 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_label (GimpSpinScale *scale,
+ const gchar *label);
+const gchar * gimp_spin_scale_get_label (GimpSpinScale *scale);
+
+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/handlebox.cpp b/src/ui/widget/handlebox.cpp
deleted file mode 100644
index 0ac84ef3a..000000000
--- a/src/ui/widget/handlebox.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Author:
- * Derek P. Moore <derekm@hackunix.org>
- *
- * Copyright (C) 2004 Derek P. Moore
- *
- * Released under GNU GPL. Read the file 'COPYING' for more information.
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include "handlebox.h"
-
-namespace Inkscape {
-namespace UI {
-namespace Widget {
-
-HandleBox::HandleBox(Gtk::Widget *widget,
- Gtk::PositionType position)
- : _widget(widget)
-{
- g_assert(_widget != NULL);
- add(*Gtk::manage(_widget));
- set_handle_position(position);
-}
-
-} // 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/handlebox.h b/src/ui/widget/handlebox.h
deleted file mode 100644
index db384552b..000000000
--- a/src/ui/widget/handlebox.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- *
- * Author:
- * Derek P. Moore <derekm@hackunix.org>
- *
- * Copyright (C) 2004 Derek P. Moore
- *
- * Released under GNU GPL. Read the file 'COPYING' for more information.
- */
-
-#ifndef INKSCAPE_UI_WIDGET_HANDLEBOX_H
-#define INKSCAPE_UI_WIDGET_HANDLEBOX_H
-
-#include <gtkmm/handlebox.h>
-
-namespace Inkscape {
-namespace UI {
-namespace Widget {
-
-/**
- * Adds a detachment handle to another widget.
- *
- * This work really doesn't amount to much more than a convenience constructor
- * for Gtk::HandleBox. Maybe this could be contributed back to Gtkmm, as
- * Gtkmm provides several convenience constructors for other widgets as well.
- */
-class HandleBox : public Gtk::HandleBox
-{
-public:
- HandleBox(Gtk::Widget *widget,
- Gtk::PositionType position = Gtk::POS_LEFT);
-
-protected:
- Gtk::Widget *_widget;
-};
-
-} // namespace Widget
-} // namespace UI
-} // namespace Inkscape
-
-#endif // INKSCAPE_UI_WIDGET_HANDLEBOX_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/icon-widget.cpp b/src/ui/widget/icon-widget.cpp
deleted file mode 100644
index 0e0736371..000000000
--- a/src/ui/widget/icon-widget.cpp
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Author:
- * Bryce Harrington <bryce@bryceharrington.org>
- *
- * Copyright (C) 2004 Bryce Harrington
- * based on work by Lauris Kaplinski in 2002 released under GPL
- *
- * Released under GNU GPL. Read the file 'COPYING' for more information
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <glib.h>
-#include "icon-widget.h"
-
-namespace Inkscape {
-namespace UI {
-namespace Widget {
-
-IconWidget::IconWidget() :
- _size(0),
- _pb(0),
- _do_bitmap_icons(false)
-{
-}
-
-IconWidget::IconWidget(int unsigned size, int unsigned scale, gchar const *name) :
- _pb(0),
- _do_bitmap_icons(false)
-{
- _size = std::max((int unsigned)128, std::min(size, (int unsigned)1));
-
- char c[256];
- g_snprintf (c, 256, "%d:%d:%s", _size, scale, name);
- guchar *pixels = image_load_gtk(name, _size, scale);
-
- if (pixels == NULL) {
- g_warning("Couldn't find matching icon for %s - has this application been installed?", name);
- //_pb = NULL;
- } else {
- /* TODO
- _pb = gdk_pixbuf_new_from_data(pixels, GDK_COLORSPACE_RGB,
- TRUE, 8, _size, _size, _size * 4,
- (GdkPixbufDestroyNotify)g_free, NULL);
- */
- }
-}
-
-IconWidget::IconWidget(int unsigned size, guchar const */*px*/) :
- _pb(0),
- _do_bitmap_icons(false)
-{
- _size = std::max((int unsigned)128, std::min(size, (int unsigned)1));
-
- /*
- _pb = gdk_pixbuf_new_from_data((guchar *)px, GDK_COLORSPACE_RGB,
- TRUE, 8, _size, _size, _size * 4, NULL, NULL);
- */
-}
-
-IconWidget::~IconWidget() {
-}
-
-void IconWidget::size_request(Gtk::Requisition &requisition)
-{
- requisition.width = _size;
- requisition.height = _size;
-}
-
-void IconWidget::size_allocate(Gtk::Allocation const &allocation)
-{
- Gtk::Widget::size_allocate(allocation);
-
- if (this->get_is_drawable()) {
- this->queue_draw();
- }
-}
-
-int IconWidget::expose(GdkEventExpose *event)
-{
- if (this->get_is_drawable()) {
- paint(&(event->area));
- }
- return true;
-}
-
-void IconWidget::paint(GdkRectangle const *area)
-{
- Gtk::Allocation allocation = get_allocation();
- int const x_pad = std::max(0, (allocation.get_width() - _size)/2);
- int const y_pad = std::max(0, (allocation.get_height() - _size)/2);
-
- int const x_max = std::max(area->x, allocation.get_x() + x_pad);
- int const y_max = std::max(area->y, allocation.get_y() + y_pad);
- int const x_min = std::min(area->x + area->width,
- allocation.get_x() + x_pad + _size);
- int const y_min = std::min(area->y + area->height,
- allocation.get_y() + y_pad + _size);
-
- if (_pb) {
- gdk_draw_pixbuf(this->get_window()->gobj(), NULL, _pb,
- x_max - allocation.get_x() - x_pad,
- y_max - allocation.get_y() - y_pad,
- x_max, y_max,
- x_min - x_max, y_min - y_max,
- GDK_RGB_DITHER_NORMAL, x_max, y_max);
- }
-}
-
-guchar* IconWidget::image_load(gchar const *name, int unsigned size, int unsigned scale)
-{
- guchar *px;
-
- if (_do_bitmap_icons) {
- px = image_load_pixmap(name, size, scale);
- if (!px) {
- px = image_load_svg(name, size, scale);
- }
- } else {
- px = image_load_svg(name, size, scale);
- if (!px) {
- px = image_load_pixmap(name, size, scale);
- }
- }
- return px;
-}
-
-guchar* IconWidget::image_load_pixmap(gchar const */*name*/, int unsigned /*size*/, int unsigned /*scale*/)
-{
- // TODO
- return NULL;
-}
-
-guchar* IconWidget::image_load_svg(gchar const */*name*/, int unsigned /*size*/, int unsigned /*scale*/)
-{
- // TODO
- return NULL;
-}
-
-guchar* IconWidget::image_load_gtk(gchar const */*name*/, int unsigned /*size*/, int unsigned /*scale*/)
-{
- // TODO
- return NULL;
-}
-
-} // 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/icon-widget.h b/src/ui/widget/icon-widget.h
deleted file mode 100644
index 329702f2e..000000000
--- a/src/ui/widget/icon-widget.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Author:
- * Bryce Harrington <bryce@bryceharrington.org>
- *
- * Copyright (C) 2004 Bryce Harrington
- *
- * Released under GNU GPL. Read the file 'COPYING' for more information
- */
-
-#ifndef INKSCAPE_UI_WIDGET_ICON_H
-#define INKSCAPE_UI_WIDGET_ICON_H
-
-#include <gtkmm/image.h>
-#include <gdkmm/rectangle.h>
-
-namespace Inkscape {
-namespace UI {
-namespace Widget {
-
-/**
- * Icon Widget - General image widget (including SVG icons).
- */
-class IconWidget : public Gtk::Widget
-{
-public:
- IconWidget();
- IconWidget(int unsigned size, int unsigned scale, gchar const *name);
- IconWidget(int unsigned size, guchar const *px);
- virtual ~IconWidget();
-
- // Overrides of Gtk::Widget functions
- void size_request(Gtk::Requisition &requisition);
- void size_allocate(Gtk::Allocation const &allocation);
-
- int expose(GdkEventExpose *event);
- void paint(GdkRectangle const *area);
- guchar* image_load(gchar const *name, int unsigned size, int unsigned scale);
- guchar* image_load_pixmap(gchar const *name, int unsigned size, int unsigned scale);
- guchar* image_load_svg(gchar const *name, int unsigned size, int unsigned scale);
- guchar* image_load_gtk(gchar const *name, int unsigned size, int unsigned scale);
-
-protected:
- int _size;
- GdkPixbuf *_pb;
- bool _do_bitmap_icons;
-};
-
-
-} // namespace Widget
-} // namespace UI
-} // namespace Inkscape
-
-#endif // INKSCAPE_UI_WIDGET_ICON_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/imageicon.cpp b/src/ui/widget/imageicon.cpp
index 77015bdd2..cf41a16a4 100644
--- a/src/ui/widget/imageicon.cpp
+++ b/src/ui/widget/imageicon.cpp
@@ -19,6 +19,8 @@
#include "svg-view-widget.h"
#include "document.h"
#include "inkscape.h"
+#include <glibmm/convert.h>
+#include <glibmm/fileutils.h>
namespace Inkscape
@@ -115,7 +117,7 @@ bool ImageIcon::showSvgDocument(const SPDocument *docArg)
viewerGtkmm->show();
pack_start(*viewerGtkmm, TRUE, TRUE, 0);
- //GtkWidget *vbox = (GtkWidget *)gobj();
+ //GtkWidget *vbox = GTK_WIDGET(gobj());
//gtk_box_pack_start(GTK_BOX(vbox), viewerGtk, TRUE, TRUE, 0);
return true;
@@ -304,7 +306,7 @@ void ImageIcon::showBrokenImage(const Glib::ustring &errorMessage)
"</svg>";
//Fill in the template
- char *cErrorMessage = (char *)errorMessage.c_str();
+ char *cErrorMessage = const_cast<char *>(errorMessage.c_str());
gchar *xmlBuffer = g_strdup_printf(xformat, cErrorMessage);
//g_message("%s\n", xmlBuffer);
@@ -373,14 +375,14 @@ bool ImageIcon::show(const Glib::ustring &fileName)
if (!Glib::file_test(fileName, Glib::FILE_TEST_EXISTS))
return false;
- gchar *fName = (gchar *)fileName.c_str();
+ gchar *fName = const_cast<gchar *>(fileName.c_str());
//g_message("fname:%s\n", fName);
if (Glib::file_test(fileName, Glib::FILE_TEST_IS_REGULAR))
{
struct stat info;
- if (stat(fName, &info))
+ if (g_file_test (fName, G_FILE_TEST_EXISTS) && stat(fName, &info))
{
Glib::ustring err = "cannot get file info";
showBrokenImage(err);
diff --git a/src/ui/widget/imageicon.h b/src/ui/widget/imageicon.h
index 803b2f53f..8faf13cb1 100644
--- a/src/ui/widget/imageicon.h
+++ b/src/ui/widget/imageicon.h
@@ -12,9 +12,16 @@
* Released under GNU GPL, read the file 'COPYING' for more information
*/
-#include <glibmm/ustring.h>
-#include <gtkmm/box.h>
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H
+#include <glibmm/threads.h>
+#endif
+#include <gtkmm/box.h>
+#include <glibmm/ustring.h>
class SPDocument;
diff --git a/src/ui/widget/imagetoggler.cpp b/src/ui/widget/imagetoggler.cpp
index 6517219f2..29907f4c9 100644
--- a/src/ui/widget/imagetoggler.cpp
+++ b/src/ui/widget/imagetoggler.cpp
@@ -53,13 +53,44 @@ ImageToggler::ImageToggler( char const* on, char const* off) :
property_pixbuf() = _property_pixbuf_off.get_value();
}
-void
-ImageToggler::get_size_vfunc( Gtk::Widget& widget,
- const Gdk::Rectangle* cell_area,
- int* x_offset,
- int* y_offset,
- int* width,
- int* height ) const
+
+#if WITH_GTKMM_3_0
+void ImageToggler::get_preferred_height_vfunc(Gtk::Widget& widget,
+ int& min_h,
+ int& nat_h) const
+{
+ Gtk::CellRendererPixbuf::get_preferred_height_vfunc(widget, min_h, nat_h);
+
+ if (min_h) {
+ min_h += (min_h) >> 1;
+ }
+
+ if (nat_h) {
+ nat_h += (nat_h) >> 1;
+ }
+}
+
+void ImageToggler::get_preferred_width_vfunc(Gtk::Widget& widget,
+ int& min_w,
+ int& nat_w) const
+{
+ Gtk::CellRendererPixbuf::get_preferred_width_vfunc(widget, min_w, nat_w);
+
+ if (min_w) {
+ min_w += (min_w) >> 1;
+ }
+
+ if (nat_w) {
+ nat_w += (nat_w) >> 1;
+ }
+}
+#else
+void ImageToggler::get_size_vfunc(Gtk::Widget& widget,
+ const Gdk::Rectangle* cell_area,
+ int* x_offset,
+ int* y_offset,
+ int* width,
+ int* height ) const
{
Gtk::CellRendererPixbuf::get_size_vfunc( widget, cell_area, x_offset, y_offset, width, height );
@@ -70,18 +101,29 @@ ImageToggler::get_size_vfunc( Gtk::Widget& widget,
*height += (*height) >> 1;
}
}
-
-
-void
-ImageToggler::render_vfunc( const Glib::RefPtr<Gdk::Drawable>& window,
- Gtk::Widget& widget,
- const Gdk::Rectangle& background_area,
- const Gdk::Rectangle& cell_area,
- const Gdk::Rectangle& expose_area,
- Gtk::CellRendererState flags )
+#endif
+
+#if WITH_GTKMM_3_0
+void ImageToggler::render_vfunc( const Cairo::RefPtr<Cairo::Context>& cr,
+ Gtk::Widget& widget,
+ const Gdk::Rectangle& background_area,
+ const Gdk::Rectangle& cell_area,
+ Gtk::CellRendererState flags )
+#else
+void ImageToggler::render_vfunc( const Glib::RefPtr<Gdk::Drawable>& window,
+ Gtk::Widget& widget,
+ const Gdk::Rectangle& background_area,
+ const Gdk::Rectangle& cell_area,
+ const Gdk::Rectangle& expose_area,
+ Gtk::CellRendererState flags )
+#endif
{
property_pixbuf() = _property_active.get_value() ? _property_pixbuf_on : _property_pixbuf_off;
+#if WITH_GTKMM_3_0
+ Gtk::CellRendererPixbuf::render_vfunc( cr, widget, background_area, cell_area, flags );
+#else
Gtk::CellRendererPixbuf::render_vfunc( window, widget, background_area, cell_area, expose_area, flags );
+#endif
}
bool
diff --git a/src/ui/widget/imagetoggler.h b/src/ui/widget/imagetoggler.h
index 6389ce8af..df6eb7ded 100644
--- a/src/ui/widget/imagetoggler.h
+++ b/src/ui/widget/imagetoggler.h
@@ -10,9 +10,17 @@
* Released under GNU GPL, read the file 'COPYING' for more information
*/
-#include <glibmm/property.h>
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H
+#include <glibmm/threads.h>
+#endif
+
#include <gtkmm/cellrendererpixbuf.h>
#include <gtkmm/widget.h>
+#include <glibmm/property.h>
namespace Inkscape {
namespace UI {
@@ -33,17 +41,32 @@ public:
protected:
- virtual void get_size_vfunc( Gtk::Widget &widget,
- Gdk::Rectangle const *cell_area,
- int *x_offset, int *y_offset, int *width, int *height ) const;
-
+#if WITH_GTKMM_3_0
+ virtual void render_vfunc( const Cairo::RefPtr<Cairo::Context>& cr,
+ Gtk::Widget& widget,
+ const Gdk::Rectangle& background_area,
+ const Gdk::Rectangle& cell_area,
+ Gtk::CellRendererState flags );
+ virtual void get_preferred_width_vfunc(Gtk::Widget& widget,
+ int& min_w,
+ int& nat_w) const;
+
+ virtual void get_preferred_height_vfunc(Gtk::Widget& widget,
+ int& min_h,
+ int& nat_h) const;
+#else
virtual void render_vfunc( const Glib::RefPtr<Gdk::Drawable>& window,
Gtk::Widget& widget,
const Gdk::Rectangle& background_area,
const Gdk::Rectangle& cell_area,
const Gdk::Rectangle& expose_area,
Gtk::CellRendererState flags );
+
+ virtual void get_size_vfunc( Gtk::Widget &widget,
+ Gdk::Rectangle const *cell_area,
+ int *x_offset, int *y_offset, int *width, int *height ) const;
+#endif
virtual bool activate_vfunc(GdkEvent *event,
Gtk::Widget &widget,
diff --git a/src/ui/widget/labelled.cpp b/src/ui/widget/labelled.cpp
index df800545a..6e3652830 100644
--- a/src/ui/widget/labelled.cpp
+++ b/src/ui/widget/labelled.cpp
@@ -71,6 +71,17 @@ Labelled::setLabelText(const Glib::ustring &str)
_label->set_text(str);
}
+void
+Labelled::setTooltipText(const Glib::ustring &tooltip)
+{
+ _label->set_tooltip_text(tooltip);
+ _widget->set_tooltip_text(tooltip);
+}
+
+bool Labelled::on_mnemonic_activate ( bool group_cycling )
+{
+ return _widget->mnemonic_activate ( group_cycling );
+}
} // namespace Widget
} // namespace UI
diff --git a/src/ui/widget/labelled.h b/src/ui/widget/labelled.h
index e49b289fe..5334454bc 100644
--- a/src/ui/widget/labelled.h
+++ b/src/ui/widget/labelled.h
@@ -11,6 +11,14 @@
#ifndef INKSCAPE_UI_WIDGET_LABELLED_H
#define INKSCAPE_UI_WIDGET_LABELLED_H
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H
+#include <glibmm/threads.h>
+#endif
+
#include <gtkmm/box.h>
namespace Gtk {
@@ -54,8 +62,13 @@ public:
Gtk::Label const *getLabel() const;
void setLabelText(const Glib::ustring &str);
+ void setTooltipText(const Glib::ustring &tooltip);
+
+private:
+ virtual bool on_mnemonic_activate( bool group_cycling );
protected:
+
Gtk::Widget *_widget;
Gtk::Label *_label;
Gtk::Label *_suffix;
diff --git a/src/ui/widget/layer-selector.cpp b/src/ui/widget/layer-selector.cpp
index c6622627b..7b1a8dbfb 100644
--- a/src/ui/widget/layer-selector.cpp
+++ b/src/ui/widget/layer-selector.cpp
@@ -34,6 +34,7 @@
#include "widgets/icon.h"
#include "widgets/shrink-wrap-button.h"
#include "xml/node-event-vector.h"
+#include "widgets/gradient-vector.h"
namespace Inkscape {
namespace Widgets {
@@ -162,17 +163,6 @@ LayerSelector::~LayerSelector() {
_selection_changed_connection.disconnect();
}
-namespace {
-
-/** Helper function - detaches desktop from selector
- */
-bool detach(LayerSelector *selector) {
- selector->setDesktop(NULL);
- return FALSE;
-}
-
-}
-
/** Sets the desktop for the widget. First disconnects signals
* for the current desktop, then stores the pointer to the
* given \a desktop, and attaches its signals to this one.
@@ -185,7 +175,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 +188,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 +227,17 @@ private:
}
+void LayerSelector::_layersChanged()
+{
+ if (_desktop) {
+ /*
+ * This code fixes #166691 but causes issues #1066543 and #1080378.
+ * Comment out until solution found.
+ */
+ //_selectLayer(_desktop->currentLayer());
+ }
+}
+
/** Selects the given layer in the dropdown selector.
*/
void LayerSelector::_selectLayer(SPObject *layer) {
@@ -300,11 +308,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());
}
@@ -565,7 +575,7 @@ void LayerSelector::_prepareLabelRenderer(
gchar const *label;
if ( object != root ) {
label = object->label();
- if (!label) {
+ if (!object->label()) {
label = object->defaultLabel();
label_defaulted = true;
}
@@ -573,7 +583,7 @@ void LayerSelector::_prepareLabelRenderer(
label = _("(root)");
}
- gchar *text = g_markup_printf_escaped(format, label);
+ gchar *text = g_markup_printf_escaped(format, gr_ellipsize_text (label, 50).c_str());
_label_renderer.property_markup() = text;
g_free(text);
g_free(format);
@@ -585,6 +595,7 @@ void LayerSelector::_prepareLabelRenderer(
_label_renderer.property_style() = ( label_defaulted ?
Pango::STYLE_ITALIC :
Pango::STYLE_NORMAL );
+
}
void LayerSelector::_lockLayer(bool lock) {
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/licensor.cpp b/src/ui/widget/licensor.cpp
index d31d4b759..c729354cb 100644
--- a/src/ui/widget/licensor.cpp
+++ b/src/ui/widget/licensor.cpp
@@ -25,6 +25,7 @@
#include "rdf.h"
#include "inkscape.h"
#include "document-undo.h"
+#include "document-private.h"
#include "verbs.h"
#include <gtkmm/radiobutton.h>
@@ -43,7 +44,7 @@ const struct rdf_license_t _other_license =
class LicenseItem : public Gtk::RadioButton {
public:
- LicenseItem (struct rdf_license_t const* license, EntityEntry* entity, Registry &wr);
+ LicenseItem (struct rdf_license_t const* license, EntityEntry* entity, Registry &wr, Gtk::RadioButtonGroup *group);
protected:
void on_toggled();
struct rdf_license_t const *_lic;
@@ -51,13 +52,12 @@ protected:
Registry &_wr;
};
-LicenseItem::LicenseItem (struct rdf_license_t const* license, EntityEntry* entity, Registry &wr)
+LicenseItem::LicenseItem (struct rdf_license_t const* license, EntityEntry* entity, Registry &wr, Gtk::RadioButtonGroup *group)
: Gtk::RadioButton(_(license->name)), _lic(license), _eep(entity), _wr(wr)
{
- static Gtk::RadioButtonGroup group = get_group();
- static bool first = true;
- if (first) first = false;
- else set_group (group);
+ if (group) {
+ set_group (*group);
+ }
}
/// \pre it is assumed that the license URI entry is a Gtk::Entry
@@ -66,9 +66,11 @@ void LicenseItem::on_toggled()
if (_wr.isUpdating()) return;
_wr.setUpdating (true);
- rdf_set_license (SP_ACTIVE_DOCUMENT, _lic->details ? _lic : 0);
- DocumentUndo::done(SP_ACTIVE_DOCUMENT, SP_VERB_NONE,
- /* TODO: annotate */ "licensor.cpp:65");
+ SPDocument *doc = SP_ACTIVE_DOCUMENT;
+ rdf_set_license (doc, _lic->details ? _lic : 0);
+ if (doc->priv->sensitive) {
+ DocumentUndo::done(doc, SP_VERB_NONE, "Document license updated");
+ }
_wr.setUpdating (false);
static_cast<Gtk::Entry*>(_eep->_packable)->set_text (_lic->uri);
_eep->on_changed();
@@ -77,7 +79,8 @@ void LicenseItem::on_toggled()
//---------------------------------------------------
Licensor::Licensor()
-: Gtk::VBox(false,4)
+: Gtk::VBox(false,4),
+ _eentry (NULL)
{
}
@@ -94,18 +97,19 @@ void Licensor::init (Registry& wr)
LicenseItem *i;
wr.setUpdating (true);
- i = manage (new LicenseItem (&_proprietary_license, _eentry, wr));
+ i = manage (new LicenseItem (&_proprietary_license, _eentry, wr, NULL));
+ Gtk::RadioButtonGroup group = i->get_group();
add (*i);
LicenseItem *pd = i;
for (struct rdf_license_t * license = rdf_licenses;
license && license->name;
license++) {
- i = manage (new LicenseItem (license, _eentry, wr));
+ i = manage (new LicenseItem (license, _eentry, wr, &group));
add(*i);
}
// add Other at the end before the URI field for the confused ppl.
- LicenseItem *io = manage (new LicenseItem (&_other_license, _eentry, wr));
+ LicenseItem *io = manage (new LicenseItem (&_other_license, _eentry, wr, &group));
add (*io);
pd->set_active();
@@ -130,10 +134,18 @@ void Licensor::update (SPDocument *doc)
for (i=0; rdf_licenses[i].name; i++)
if (license == &rdf_licenses[i])
break;
+#if WITH_GTKMM_3_0
+ static_cast<LicenseItem*>(get_children()[i+1])->set_active();
+#else
static_cast<LicenseItem*>(children()[i+1].get_widget())->set_active();
+#endif
}
else {
+#if WITH_GTKMM_3_0
+ static_cast<LicenseItem*>(get_children()[0])->set_active();
+#else
static_cast<LicenseItem*>(children()[0].get_widget())->set_active();
+#endif
}
/* update the URI */
diff --git a/src/ui/widget/licensor.h b/src/ui/widget/licensor.h
index ab6abd0a4..0ac3e5ab8 100644
--- a/src/ui/widget/licensor.h
+++ b/src/ui/widget/licensor.h
@@ -10,6 +10,14 @@
#ifndef INKSCAPE_UI_WIDGET_LICENSOR_H
#define INKSCAPE_UI_WIDGET_LICENSOR_H
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H
+#include <glibmm/threads.h>
+#endif
+
#include <gtkmm/box.h>
class SPDocument;
diff --git a/src/ui/widget/notebook-page.cpp b/src/ui/widget/notebook-page.cpp
index 92bcb6937..6653499b8 100644
--- a/src/ui/widget/notebook-page.cpp
+++ b/src/ui/widget/notebook-page.cpp
@@ -9,22 +9,35 @@
* Released under GNU GPL. Read the file 'COPYING' for more information
*/
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
#include "notebook-page.h"
+#if WITH_GTKMM_3_0
+# include <gtkmm/grid.h>
+#else
+# include <gtkmm/table.h>
+#endif
+
namespace Inkscape {
namespace UI {
namespace Widget {
NotebookPage::NotebookPage(int n_rows, int n_columns, bool expand, bool fill, guint padding)
- :_table(n_rows, n_columns)
+#if WITH_GTKMM_3_0
+ :_table(Gtk::manage(new Gtk::Grid()))
+#else
+ :_table(Gtk::manage(new Gtk::Table(n_rows, n_columns)))
+#endif
{
set_border_width(2);
- _table.set_spacings(2);
- pack_start(_table, expand, fill, padding);
+
+#if WITH_GTKMM_3_0
+ _table->set_row_spacing(2);
+ _table->set_column_spacing(2);
+#else
+ _table->set_spacings(2);
+#endif
+
+ pack_start(*_table, expand, fill, padding);
}
} // namespace Widget
diff --git a/src/ui/widget/notebook-page.h b/src/ui/widget/notebook-page.h
index 140b7cb33..38ae9e054 100644
--- a/src/ui/widget/notebook-page.h
+++ b/src/ui/widget/notebook-page.h
@@ -10,8 +10,23 @@
#ifndef INKSCAPE_UI_WIDGET_NOTEBOOK_PAGE_H
#define INKSCAPE_UI_WIDGET_NOTEBOOK_PAGE_H
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H
+#include <glibmm/threads.h>
+#endif
+
#include <gtkmm/box.h>
-#include <gtkmm/table.h>
+
+namespace Gtk {
+#if WITH_GTKMM_3_0
+class Grid;
+#else
+class Table;
+#endif
+}
namespace Inkscape {
namespace UI {
@@ -31,10 +46,19 @@ public:
*/
NotebookPage(int n_rows, int n_columns, bool expand=false, bool fill=false, guint padding=0);
- Gtk::Table& table() { return _table; }
+#if WITH_GTKMM_3_0
+ Gtk::Grid& table() { return *_table; }
+#else
+ Gtk::Table& table() { return *_table; }
+#endif
protected:
- Gtk::Table _table;
+
+#if WITH_GTKMM_3_0
+ Gtk::Grid *_table;
+#else
+ Gtk::Table *_table;
+#endif
};
} // namespace Widget
diff --git a/src/ui/widget/object-composite-settings.cpp b/src/ui/widget/object-composite-settings.cpp
index eb4790990..537db0fdd 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,13 +33,14 @@
#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 {
namespace Widget {
-void ObjectCompositeSettings::_on_desktop_activate(
- Inkscape::Application */*application*/,
+/*void ObjectCompositeSettings::_on_desktop_activate(
+ Inkscape::Application *application,
SPDesktop *desktop,
ObjectCompositeSettings *w
) {
@@ -48,72 +50,54 @@ void ObjectCompositeSettings::_on_desktop_activate(
}
void ObjectCompositeSettings::_on_desktop_deactivate(
- Inkscape::Application */*application*/,
- SPDesktop */*desktop*/,
+ Inkscape::Application *application,
+ SPDesktop *desktop,
ObjectCompositeSettings *w
) {
if (w->_subject) {
w->_subject->setDesktop(NULL);
}
-}
+}*/
ObjectCompositeSettings::ObjectCompositeSettings(unsigned int verb_code, char const *history_prefix, int flags)
: _verb_code(verb_code),
_blur_tag(Glib::ustring(history_prefix) + ":blur"),
_opacity_tag(Glib::ustring(history_prefix) + ":opacity"),
_opacity_vbox(false, 0),
- _opacity_label(_("Opacity:")),
-#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);
-#if WITH_GTKMM_2_22
- _opacity_label.set_alignment(Gtk::ALIGN_END, Gtk::ALIGN_CENTER);
-#else
- _opacity_label.set_alignment(Gtk::ALIGN_RIGHT, Gtk::ALIGN_CENTER);
-#endif
-
- _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_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());
+ gtk_size_group_add_widget(labels, GTK_WIDGET(_opacity_label.gobj()));
+ gtk_size_group_add_widget(labels, GTK_WIDGET(_fe_cb.get_blur_label()->gobj()));
+*/
show_all_children();
- _desktop_activated = g_signal_connect ( G_OBJECT (INKSCAPE), "activate_desktop", G_CALLBACK (&ObjectCompositeSettings::_on_desktop_activate), this );
- _desktop_activated = g_signal_connect ( G_OBJECT (INKSCAPE), "deactivate_desktop", G_CALLBACK (&ObjectCompositeSettings::_on_desktop_deactivate), this );
+ // These signals dont properly detect change in desktop, rely on owner dialog to call setSubject() from setTargetDesktop()
+ //_desktop_activated = g_signal_connect ( G_OBJECT (INKSCAPE), "activate_desktop", G_CALLBACK (&ObjectCompositeSettings::_on_desktop_activate), this );
+ //_desktop_activated = g_signal_connect ( G_OBJECT (INKSCAPE), "deactivate_desktop", G_CALLBACK (&ObjectCompositeSettings::_on_desktop_deactivate), this );
}
ObjectCompositeSettings::~ObjectCompositeSettings() {
@@ -225,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);
@@ -265,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 9f9b336eb..19a6cb2a5 100644
--- a/src/ui/widget/object-composite-settings.h
+++ b/src/ui/widget/object-composite-settings.h
@@ -11,6 +11,14 @@
* Released under GNU GPL, read the file 'COPYING' for more information
*/
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H
+#include <glibmm/threads.h>
+#endif
+
#include <gtkmm/box.h>
#include <gtkmm/alignment.h>
#include <gtkmm/adjustment.h>
@@ -21,8 +29,10 @@
#include "ui/widget/filter-effect-chooser.h"
#include "ui/widget/spinbutton.h"
+class SPDesktop;
+
namespace Inkscape {
-class Application;
+struct Application;
namespace UI {
namespace Widget {
@@ -45,21 +55,12 @@ private:
Glib::ustring _opacity_tag;
Gtk::VBox _opacity_vbox;
- Gtk::HBox _opacity_hbox;
- Gtk::Label _opacity_label;
-#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/page-sizer.cpp b/src/ui/widget/page-sizer.cpp
index 83d923c15..eae0d4a95 100644
--- a/src/ui/widget/page-sizer.cpp
+++ b/src/ui/widget/page-sizer.cpp
@@ -27,13 +27,17 @@
#include <string>
#include <string.h>
#include <vector>
+
+#include <glibmm/i18n.h>
+
#include <2geom/transforms.h>
#include "desktop-handles.h"
#include "document.h"
#include "desktop.h"
#include "helper/action.h"
-#include "helper/units.h"
+#include "helper/action-context.h"
+#include "util/units.h"
#include "inkscape.h"
#include "sp-namedview.h"
#include "sp-root.h"
@@ -44,6 +48,7 @@
#include "xml/repr.h"
using std::pair;
+using Inkscape::Util::unit_table;
namespace Inkscape {
namespace UI {
@@ -92,7 +97,7 @@ struct PaperSizeRec {
char const * const name; //name
double const smaller; //lesser dimension
double const larger; //greater dimension
- SPUnitId const unit; //units
+ Glib::ustring const unit; //units
};
// list of page formats that should be in landscape automatically
@@ -110,31 +115,31 @@ fill_landscape_papers() {
}
static PaperSizeRec const inkscape_papers[] = {
- { "A4", 210, 297, SP_UNIT_MM },
- { "US Letter", 8.5, 11, SP_UNIT_IN },
- { "US Legal", 8.5, 14, SP_UNIT_IN },
- { "US Executive", 7.25, 10.5, SP_UNIT_IN },
- { "A0", 841, 1189, SP_UNIT_MM },
- { "A1", 594, 841, SP_UNIT_MM },
- { "A2", 420, 594, SP_UNIT_MM },
- { "A3", 297, 420, SP_UNIT_MM },
- { "A5", 148, 210, SP_UNIT_MM },
- { "A6", 105, 148, SP_UNIT_MM },
- { "A7", 74, 105, SP_UNIT_MM },
- { "A8", 52, 74, SP_UNIT_MM },
- { "A9", 37, 52, SP_UNIT_MM },
- { "A10", 26, 37, SP_UNIT_MM },
- { "B0", 1000, 1414, SP_UNIT_MM },
- { "B1", 707, 1000, SP_UNIT_MM },
- { "B2", 500, 707, SP_UNIT_MM },
- { "B3", 353, 500, SP_UNIT_MM },
- { "B4", 250, 353, SP_UNIT_MM },
- { "B5", 176, 250, SP_UNIT_MM },
- { "B6", 125, 176, SP_UNIT_MM },
- { "B7", 88, 125, SP_UNIT_MM },
- { "B8", 62, 88, SP_UNIT_MM },
- { "B9", 44, 62, SP_UNIT_MM },
- { "B10", 31, 44, SP_UNIT_MM },
+ { "A4", 210, 297, "mm" },
+ { "US Letter", 8.5, 11, "in" },
+ { "US Legal", 8.5, 14, "in" },
+ { "US Executive", 7.25, 10.5, "in" },
+ { "A0", 841, 1189, "mm" },
+ { "A1", 594, 841, "mm" },
+ { "A2", 420, 594, "mm" },
+ { "A3", 297, 420, "mm" },
+ { "A5", 148, 210, "mm" },
+ { "A6", 105, 148, "mm" },
+ { "A7", 74, 105, "mm" },
+ { "A8", 52, 74, "mm" },
+ { "A9", 37, 52, "mm" },
+ { "A10", 26, 37, "mm" },
+ { "B0", 1000, 1414, "mm" },
+ { "B1", 707, 1000, "mm" },
+ { "B2", 500, 707, "mm" },
+ { "B3", 353, 500, "mm" },
+ { "B4", 250, 353, "mm" },
+ { "B5", 176, 250, "mm" },
+ { "B6", 125, 176, "mm" },
+ { "B7", 88, 125, "mm" },
+ { "B8", 62, 88, "mm" },
+ { "B9", 44, 62, "mm" },
+ { "B10", 31, 44, "mm" },
@@ -146,63 +151,63 @@ static PaperSizeRec const inkscape_papers[] = {
don't know what D and E series are used for.
*/
- { "C0", 917, 1297, SP_UNIT_MM },
- { "C1", 648, 917, SP_UNIT_MM },
- { "C2", 458, 648, SP_UNIT_MM },
- { "C3", 324, 458, SP_UNIT_MM },
- { "C4", 229, 324, SP_UNIT_MM },
- { "C5", 162, 229, SP_UNIT_MM },
- { "C6", 114, 162, SP_UNIT_MM },
- { "C7", 81, 114, SP_UNIT_MM },
- { "C8", 57, 81, SP_UNIT_MM },
- { "C9", 40, 57, SP_UNIT_MM },
- { "C10", 28, 40, SP_UNIT_MM },
- { "D1", 545, 771, SP_UNIT_MM },
- { "D2", 385, 545, SP_UNIT_MM },
- { "D3", 272, 385, SP_UNIT_MM },
- { "D4", 192, 272, SP_UNIT_MM },
- { "D5", 136, 192, SP_UNIT_MM },
- { "D6", 96, 136, SP_UNIT_MM },
- { "D7", 68, 96, SP_UNIT_MM },
- { "E3", 400, 560, SP_UNIT_MM },
- { "E4", 280, 400, SP_UNIT_MM },
- { "E5", 200, 280, SP_UNIT_MM },
- { "E6", 140, 200, SP_UNIT_MM },
+ { "C0", 917, 1297, "mm" },
+ { "C1", 648, 917, "mm" },
+ { "C2", 458, 648, "mm" },
+ { "C3", 324, 458, "mm" },
+ { "C4", 229, 324, "mm" },
+ { "C5", 162, 229, "mm" },
+ { "C6", 114, 162, "mm" },
+ { "C7", 81, 114, "mm" },
+ { "C8", 57, 81, "mm" },
+ { "C9", 40, 57, "mm" },
+ { "C10", 28, 40, "mm" },
+ { "D1", 545, 771, "mm" },
+ { "D2", 385, 545, "mm" },
+ { "D3", 272, 385, "mm" },
+ { "D4", 192, 272, "mm" },
+ { "D5", 136, 192, "mm" },
+ { "D6", 96, 136, "mm" },
+ { "D7", 68, 96, "mm" },
+ { "E3", 400, 560, "mm" },
+ { "E4", 280, 400, "mm" },
+ { "E5", 200, 280, "mm" },
+ { "E6", 140, 200, "mm" },
//#endif
- { "CSE", 462, 649, SP_UNIT_PT },
- { "US #10 Envelope", 4.125, 9.5, SP_UNIT_IN },
+ { "CSE", 462, 649, "pt" },
+ { "US #10 Envelope", 4.125, 9.5, "in" },
/* See http://www.hbp.com/content/PCR_envelopes.cfm for a much larger list of US envelope
sizes. */
- { "DL Envelope", 110, 220, SP_UNIT_MM },
- { "Ledger/Tabloid", 11, 17, SP_UNIT_IN },
+ { "DL Envelope", 110, 220, "mm" },
+ { "Ledger/Tabloid", 11, 17, "in" },
/* Note that `Folio' (used in QPrinter/KPrinter) is deliberately absent from this list, as it
means different sizes to different people: different people may expect the width to be
either 8, 8.25 or 8.5 inches, and the height to be either 13 or 13.5 inches, even
restricting our interpretation to foolscap folio. If you wish to introduce a folio-like
page size to the list, then please consider using a name more specific than just `Folio' or
`Foolscap Folio'. */
- { "Banner 468x60", 60, 468, SP_UNIT_PX },
- { "Icon 16x16", 16, 16, SP_UNIT_PX },
- { "Icon 32x32", 32, 32, SP_UNIT_PX },
- { "Icon 48x48", 48, 48, SP_UNIT_PX },
+ { "Banner 468x60", 60, 468, "px" },
+ { "Icon 16x16", 16, 16, "px" },
+ { "Icon 32x32", 32, 32, "px" },
+ { "Icon 48x48", 48, 48, "px" },
/* business cards */
- { "Business Card (ISO 7810)", 53.98, 85.60, SP_UNIT_MM },
- { "Business Card (US)", 2, 3.5, SP_UNIT_IN },
- { "Business Card (Europe)", 55, 85, SP_UNIT_MM },
- { "Business Card (Aus/NZ)", 55, 90, SP_UNIT_MM },
+ { "Business Card (ISO 7810)", 53.98, 85.60, "mm" },
+ { "Business Card (US)", 2, 3.5, "in" },
+ { "Business Card (Europe)", 55, 85, "mm" },
+ { "Business Card (Aus/NZ)", 55, 90, "mm" },
// Start Arch Series List
- { "Arch A", 9, 12, SP_UNIT_IN }, // 229 x 305 mm
- { "Arch B", 12, 18, SP_UNIT_IN }, // 305 x 457 mm
- { "Arch C", 18, 24, SP_UNIT_IN }, // 457 x 610 mm
- { "Arch D", 24, 36, SP_UNIT_IN }, // 610 x 914 mm
- { "Arch E", 36, 48, SP_UNIT_IN }, // 914 x 1219 mm
- { "Arch E1", 30, 42, SP_UNIT_IN }, // 762 x 1067 mm
+ { "Arch A", 9, 12, "in" }, // 229 x 305 mm
+ { "Arch B", 12, 18, "in" }, // 305 x 457 mm
+ { "Arch C", 18, 24, "in" }, // 457 x 610 mm
+ { "Arch D", 24, 36, "in" }, // 610 x 914 mm
+ { "Arch E", 36, 48, "in" }, // 914 x 1219 mm
+ { "Arch E1", 30, 42, "in" }, // 762 x 1067 mm
/*
* The above list of Arch sizes were taken from the following site:
@@ -213,7 +218,7 @@ static PaperSizeRec const inkscape_papers[] = {
* September 2009 - DAK
*/
- { NULL, 0, 0, SP_UNIT_PX },
+ { NULL, 0, 0, "px" },
};
@@ -222,10 +227,6 @@ static PaperSizeRec const inkscape_papers[] = {
//# P A G E S I Z E R
//########################################################################
-//The default unit for this widget and its calculations
-static const SPUnit _px_unit = sp_unit_get_by_id (SP_UNIT_PX);
-
-
/**
* Constructor
*/
@@ -242,12 +243,14 @@ PageSizer::PageSizer(Registry & _wr)
_widgetRegistry(&_wr)
{
// set precision of scalar entry boxes
+ _wr.setUpdating (true);
_dimensionWidth.setDigits(5);
_dimensionHeight.setDigits(5);
_marginTop.setDigits(5);
_marginLeft.setDigits(5);
_marginRight.setDigits(5);
_marginBottom.setDigits(5);
+ _wr.setUpdating (false);
//# Set up the Paper Size combo box
_paperSizeListStore = Gtk::ListStore::create(_paperSizeListColumns);
@@ -274,13 +277,8 @@ PageSizer::PageSizer(Registry & _wr)
char formatBuf[80];
snprintf(formatBuf, 79, "%0.1f x %0.1f", p->smaller, p->larger);
Glib::ustring desc = formatBuf;
- if (p->unit == SP_UNIT_IN)
- desc.append(" in");
- else if (p->unit == SP_UNIT_MM)
- desc.append(" mm");
- else if (p->unit == SP_UNIT_PX)
- desc.append(" px");
- PaperSize paper(name, p->smaller, p->larger, p->unit);
+ desc.append(" " + p->unit);
+ PaperSize paper(name, p->smaller, p->larger, unit_table.getUnit(p->unit));
_paperSizeTable[name] = paper;
Gtk::TreeModel::Row row = *(_paperSizeListStore->append());
row[_paperSizeListColumns.nameColumn] = name;
@@ -312,25 +310,49 @@ PageSizer::PageSizer(Registry & _wr)
// Setting default custom unit to document unit
SPDesktop *dt = SP_ACTIVE_DESKTOP;
SPNamedView *nv = sp_desktop_namedview(dt);
+ _wr.setUpdating (true);
if (nv->units) {
- _dimensionUnits.setUnit(nv->units);
+ _dimensionUnits.setUnit(nv->units->abbr);
} else if (nv->doc_units) {
- _dimensionUnits.setUnit(nv->doc_units);
+ _dimensionUnits.setUnit(nv->doc_units->abbr);
}
+ _wr.setUpdating (false);
//## Set up custom size frame
_customFrame.set_label(_("Custom size"));
pack_start (_customFrame, false, false, 0);
_customFrame.add(_customDimTable);
- _customDimTable.resize(3, 2);
_customDimTable.set_border_width(4);
+
+#if WITH_GTKMM_3_0
+ _customDimTable.set_row_spacing(4);
+ _customDimTable.set_column_spacing(4);
+
+ _dimensionWidth.set_hexpand();
+ _dimensionWidth.set_vexpand();
+ _customDimTable.attach(_dimensionWidth, 0, 0, 1, 1);
+
+ _dimensionUnits.set_hexpand();
+ _dimensionUnits.set_vexpand();
+ _customDimTable.attach(_dimensionUnits, 1, 0, 1, 1);
+
+ _dimensionHeight.set_hexpand();
+ _dimensionHeight.set_vexpand();
+ _customDimTable.attach(_dimensionHeight, 0, 1, 1, 1);
+
+ _fitPageMarginExpander.set_hexpand();
+ _fitPageMarginExpander.set_vexpand();
+ _customDimTable.attach(_fitPageMarginExpander, 0, 2, 2, 1);
+#else
+ _customDimTable.resize(3, 2);
_customDimTable.set_row_spacings(4);
_customDimTable.set_col_spacings(4);
_customDimTable.attach(_dimensionWidth, 0,1, 0,1);
_customDimTable.attach(_dimensionUnits, 1,2, 0,1);
_customDimTable.attach(_dimensionHeight, 0,1, 1,2);
_customDimTable.attach(_fitPageMarginExpander, 0,2, 2,3);
+#endif
_dimTabOrderGList = NULL;
_dimTabOrderGList = g_list_append(_dimTabOrderGList, _dimensionWidth.gobj());
@@ -346,7 +368,32 @@ PageSizer::PageSizer(Registry & _wr)
_fitPageMarginExpander.add(_marginTable);
//## Set up margin settings
- _marginTable.resize(4, 2);
+ _marginTable.set_border_width(4);
+
+#if WITH_GTKMM_3_0
+ _marginTable.set_row_spacing(4);
+ _marginTable.set_column_spacing(4);
+
+ _marginTopAlign.set_hexpand();
+ _marginTopAlign.set_vexpand();
+ _marginTable.attach(_marginTopAlign, 0, 0, 2, 1);
+
+ _marginLeftAlign.set_hexpand();
+ _marginLeftAlign.set_vexpand();
+ _marginTable.attach(_marginLeftAlign, 0, 1, 1, 1);
+
+ _marginRightAlign.set_hexpand();
+ _marginRightAlign.set_vexpand();
+ _marginTable.attach(_marginRightAlign, 1, 1, 1, 1);
+
+ _marginBottomAlign.set_hexpand();
+ _marginBottomAlign.set_vexpand();
+ _marginTable.attach(_marginBottomAlign, 0, 2, 2, 1);
+
+ _fitPageButtonAlign.set_hexpand();
+ _fitPageButtonAlign.set_vexpand();
+ _marginTable.attach(_fitPageButtonAlign, 0, 3, 2, 1);
+#else
_marginTable.set_border_width(4);
_marginTable.set_row_spacings(4);
_marginTable.set_col_spacings(4);
@@ -355,6 +402,7 @@ PageSizer::PageSizer(Registry & _wr)
_marginTable.attach(_marginRightAlign, 1,2, 1,2);
_marginTable.attach(_marginBottomAlign, 0,2, 2,3);
_marginTable.attach(_fitPageButtonAlign, 0,2, 3,4);
+#endif
_marginTopAlign.set(0.5, 0.5, 0.0, 1.0);
_marginTopAlign.add(_marginTop);
@@ -394,6 +442,7 @@ PageSizer::init ()
_portrait_connection = _portraitButton.signal_toggled().connect (sigc::mem_fun (*this, &PageSizer::on_portrait));
_changedw_connection = _dimensionWidth.signal_value_changed().connect (sigc::mem_fun (*this, &PageSizer::on_value_changed));
_changedh_connection = _dimensionHeight.signal_value_changed().connect (sigc::mem_fun (*this, &PageSizer::on_value_changed));
+ _changedu_connection = _dimensionUnits.getUnitMenu()->signal_changed().connect (sigc::mem_fun (*this, &PageSizer::on_units_changed));
_fitPageButton.signal_clicked().connect(sigc::mem_fun(*this, &PageSizer::fire_fit_canvas_to_selection_or_drawing));
show_all_children();
@@ -406,11 +455,11 @@ PageSizer::init ()
* 'changeList' is true, then adjust the paperSizeList to show the closest
* standard page size.
*
- * \param w, h given in px
+ * \param w, h
* \param changeList whether to modify the paper size list
*/
void
-PageSizer::setDim (double w, double h, bool changeList)
+PageSizer::setDim (Inkscape::Util::Quantity w, Inkscape::Util::Quantity h, bool changeList)
{
static bool _called = false;
if (_called) {
@@ -425,14 +474,16 @@ PageSizer::setDim (double w, double h, bool changeList)
_changedw_connection.block();
_changedh_connection.block();
+ _unit = w.unit->abbr;
+
if (SP_ACTIVE_DESKTOP && !_widgetRegistry->isUpdating()) {
SPDocument *doc = sp_desktop_document(SP_ACTIVE_DESKTOP);
- double const old_height = doc->getHeight();
- doc->setWidth (w, &_px_unit);
- doc->setHeight (h, &_px_unit);
+ Inkscape::Util::Quantity const old_height = doc->getHeight();
+ doc->setWidth (w);
+ doc->setHeight (h);
// The origin for the user is in the lower left corner; this point should remain stationary when
// changing the page size. The SVG's origin however is in the upper left corner, so we must compensate for this
- Geom::Translate const vert_offset(Geom::Point(0, (old_height - h)));
+ Geom::Translate const vert_offset(Geom::Point(0, (old_height.value("px") - h.value("px"))));
doc->getRoot()->translateChildItems(vert_offset);
DocumentUndo::done(doc, SP_VERB_NONE, _("Set page size"));
}
@@ -455,9 +506,10 @@ PageSizer::setDim (double w, double h, bool changeList)
_paperSizeListSelection->select(row);
}
- Unit const& unit = _dimensionUnits.getUnit();
- _dimensionWidth.setValue (w / unit.factor);
- _dimensionHeight.setValue (h / unit.factor);
+ _dimensionWidth.setUnit(w.unit->abbr);
+ _dimensionWidth.setValue (w.quantity);
+ _dimensionHeight.setUnit(h.unit->abbr);
+ _dimensionHeight.setValue (h.quantity);
_paper_size_list_connection.unblock();
_landscape_connection.unblock();
@@ -495,37 +547,40 @@ PageSizer::updateFitMarginsUI(Inkscape::XML::Node *nv_repr)
/**
* Returns an iterator pointing to a row in paperSizeListStore which
- * contains a paper of the specified size (specified in px), or
+ * contains a paper of the specified size, or
* paperSizeListStore->children().end() if no such paper exists.
+ *
+ * The code is not tested for the case where w and h have different units.
*/
Gtk::ListStore::iterator
-PageSizer::find_paper_size (double w, double h) const
+PageSizer::find_paper_size (Inkscape::Util::Quantity w, Inkscape::Util::Quantity h) const
{
- double smaller = w;
- double larger = h;
+ using Inkscape::Util::Quantity;
+ using std::swap;
+
+ // The code below assumes that w < h, so make sure that's the case:
if ( h < w ) {
- smaller = h; larger = w;
+ swap(h,w);
}
- g_return_val_if_fail(smaller <= larger, _paperSizeListStore->children().end());
+ g_return_val_if_fail(w <= h, _paperSizeListStore->children().end());
std::map<Glib::ustring, PaperSize>::const_iterator iter;
for (iter = _paperSizeTable.begin() ;
iter != _paperSizeTable.end() ; ++iter) {
PaperSize paper = iter->second;
- SPUnit const &i_unit = sp_unit_get_by_id(paper.unit);
- double smallX = sp_units_get_pixels(paper.smaller, i_unit);
- double largeX = sp_units_get_pixels(paper.larger, i_unit);
+ Quantity smallX (paper.smaller, paper.unit);
+ Quantity largeX (paper.larger, paper.unit);
- g_return_val_if_fail(smallX <= largeX, _paperSizeListStore->children().end());
+ g_return_val_if_fail(smallX.quantity < largeX.quantity + 0.001, _paperSizeListStore->children().end());
- if ((std::abs(smaller - smallX) <= 0.1) &&
- (std::abs(larger - largeX) <= 0.1) ) {
- Gtk::ListStore::iterator p;
+ if ( are_near(w, smallX, 0.1) && are_near(h, largeX, 0.1) ) {
+ Gtk::ListStore::iterator p = _paperSizeListStore->children().begin();
+ Gtk::ListStore::iterator pend = _paperSizeListStore->children().end();
// We need to search paperSizeListStore explicitly for the
// specified paper size because it is sorted in a different
// way than paperSizeTable (which is sorted alphabetically)
- for (p = _paperSizeListStore->children().begin(); p != _paperSizeListStore->children().end(); ++p) {
+ for ( ; p != pend; ++p) {
if ((*p)[_paperSizeListColumns.nameColumn] == paper.name) {
return p;
}
@@ -550,7 +605,7 @@ PageSizer::fire_fit_canvas_to_selection_or_drawing()
SPDocument *doc;
SPNamedView *nv;
Inkscape::XML::Node *nv_repr;
-
+
if ((doc = sp_desktop_document(SP_ACTIVE_DESKTOP))
&& (nv = sp_document_namedview(doc, 0))
&& (nv_repr = nv->getRepr())) {
@@ -564,7 +619,7 @@ PageSizer::fire_fit_canvas_to_selection_or_drawing()
Verb *verb = Verb::get( SP_VERB_FIT_CANVAS_TO_SELECTION_OR_DRAWING );
if (verb) {
- SPAction *action = verb->get_action(dt);
+ SPAction *action = verb->get_action(Inkscape::ActionContext(dt));
if (action) {
sp_action_perform(action, NULL);
}
@@ -595,8 +650,8 @@ PageSizer::on_paper_size_list_changed()
return;
}
PaperSize paper = piter->second;
- double w = paper.smaller;
- double h = paper.larger;
+ Inkscape::Util::Quantity w = Inkscape::Util::Quantity(paper.smaller, paper.unit);
+ Inkscape::Util::Quantity h = Inkscape::Util::Quantity(paper.larger, paper.unit);
if (std::find(lscape_papers.begin(), lscape_papers.end(), paper.name.c_str()) != lscape_papers.end()) {
// enforce landscape mode if this is desired for the given page format
@@ -606,10 +661,6 @@ PageSizer::on_paper_size_list_changed()
_landscape = _landscapeButton.get_active();
}
- SPUnit const &src_unit = sp_unit_get_by_id (paper.unit);
- sp_convert_distance (&w, &src_unit, &_px_unit);
- sp_convert_distance (&h, &src_unit, &_px_unit);
-
if (_landscape)
setDim (h, w, false);
else
@@ -626,8 +677,8 @@ PageSizer::on_portrait()
{
if (!_portraitButton.get_active())
return;
- double w = _dimensionWidth.getValue ("px");
- double h = _dimensionHeight.getValue ("px");
+ Inkscape::Util::Quantity w = Inkscape::Util::Quantity(_dimensionWidth.getValue(""), _dimensionWidth.getUnit());
+ Inkscape::Util::Quantity h = Inkscape::Util::Quantity(_dimensionHeight.getValue(""), _dimensionHeight.getUnit());
if (h < w) {
setDim (h, w);
}
@@ -642,8 +693,8 @@ PageSizer::on_landscape()
{
if (!_landscapeButton.get_active())
return;
- double w = _dimensionWidth.getValue ("px");
- double h = _dimensionHeight.getValue ("px");
+ Inkscape::Util::Quantity w = Inkscape::Util::Quantity(_dimensionWidth.getValue(""), _dimensionWidth.getUnit());
+ Inkscape::Util::Quantity h = Inkscape::Util::Quantity(_dimensionHeight.getValue(""), _dimensionHeight.getUnit());
if (w < h) {
setDim (h, w);
}
@@ -656,11 +707,18 @@ void
PageSizer::on_value_changed()
{
if (_widgetRegistry->isUpdating()) return;
-
- setDim (_dimensionWidth.getValue("px"),
- _dimensionHeight.getValue("px"));
+ if (_unit != _dimensionUnits.getUnit()->abbr) return;
+ setDim (Inkscape::Util::Quantity(_dimensionWidth.getValue(""), _dimensionUnits.getUnit()),
+ Inkscape::Util::Quantity(_dimensionHeight.getValue(""), _dimensionUnits.getUnit()));
+}
+void
+PageSizer::on_units_changed()
+{
+ if (_widgetRegistry->isUpdating()) return;
+ _unit = _dimensionUnits.getUnit()->abbr;
+ setDim (Inkscape::Util::Quantity(_dimensionWidth.getValue(""), _dimensionUnits.getUnit()),
+ Inkscape::Util::Quantity(_dimensionHeight.getValue(""), _dimensionUnits.getUnit()));
}
-
} // namespace Widget
} // namespace UI
diff --git a/src/ui/widget/page-sizer.h b/src/ui/widget/page-sizer.h
index 17fd7b1ea..dc8e34d82 100644
--- a/src/ui/widget/page-sizer.h
+++ b/src/ui/widget/page-sizer.h
@@ -10,18 +10,28 @@
#ifndef INKSCAPE_UI_WIDGET_PAGE_SIZER_H
#define INKSCAPE_UI_WIDGET_PAGE_SIZER_H
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
#include <stddef.h>
#include "ui/widget/registered-widget.h"
#include <sigc++/sigc++.h>
-#include "helper/units.h"
+#include "util/units.h"
#include <gtkmm/alignment.h>
#include <gtkmm/expander.h>
#include <gtkmm/frame.h>
#include <gtkmm/liststore.h>
#include <gtkmm/scrolledwindow.h>
-#include <gtkmm/table.h>
+
+#if WITH_GTKMM_3_0
+# include <gtkmm/grid.h>
+#else
+# include <gtkmm/table.h>
+#endif
+
#include <gtkmm/radiobutton.h>
namespace Inkscape {
@@ -54,7 +64,7 @@ public:
PaperSize(const Glib::ustring &nameArg,
double smallerArg,
double largerArg,
- SPUnitId unitArg)
+ Inkscape::Util::Unit const *unitArg)
{
name = nameArg;
smaller = smallerArg;
@@ -98,7 +108,7 @@ public:
/**
* The units (px, pt, mm, etc) of this specification
*/
- SPUnitId unit;
+ Inkscape::Util::Unit const *unit; /// pointer to object in UnitTable, do not delete
private:
@@ -107,7 +117,7 @@ private:
name = "";
smaller = 0.0;
larger = 0.0;
- unit = SP_UNIT_PX;
+ unit = unit_table.getUnit("px");
}
void assign(const PaperSize &other)
@@ -151,7 +161,7 @@ public:
* Set the page size to the given dimensions. If 'changeList' is
* true, then reset the paper size list to the closest match
*/
- void setDim (double w, double h, bool changeList=true);
+ void setDim (Inkscape::Util::Quantity w, Inkscape::Util::Quantity h, bool changeList=true);
/**
* Updates the scalar widgets for the fit margins. (Just changes the value
@@ -169,7 +179,7 @@ protected:
/**
* Find the closest standard paper size in the table, to the
*/
- Gtk::ListStore::iterator find_paper_size (double w, double h) const;
+ Gtk::ListStore::iterator find_paper_size (Inkscape::Util::Quantity w, Inkscape::Util::Quantity h) const;
void fire_fit_canvas_to_selection_or_drawing();
@@ -207,7 +217,13 @@ protected:
//### Custom size frame
Gtk::Frame _customFrame;
+
+#if WITH_GTKMM_3_0
+ Gtk::Grid _customDimTable;
+#else
Gtk::Table _customDimTable;
+#endif
+
RegisteredUnitMenu _dimensionUnits;
RegisteredScalarUnit _dimensionWidth;
RegisteredScalarUnit _dimensionHeight;
@@ -215,7 +231,13 @@ protected:
//### Fit Page options
Gtk::Expander _fitPageMarginExpander;
+
+#if WITH_GTKMM_3_0
+ Gtk::Grid _marginTable;
+#else
Gtk::Table _marginTable;
+#endif
+
Gtk::Alignment _marginTopAlign;
Gtk::Alignment _marginLeftAlign;
Gtk::Alignment _marginRightAlign;
@@ -230,13 +252,17 @@ protected:
//callback
void on_value_changed();
+ void on_units_changed();
sigc::connection _changedw_connection;
sigc::connection _changedh_connection;
+ sigc::connection _changedu_connection;
Registry *_widgetRegistry;
//### state - whether we are currently landscape or portrait
bool _landscape;
+
+ Glib::ustring _unit;
};
diff --git a/src/ui/widget/panel.cpp b/src/ui/widget/panel.cpp
index a1ae6a36d..d60eeefe0 100644
--- a/src/ui/widget/panel.cpp
+++ b/src/ui/widget/panel.cpp
@@ -15,7 +15,9 @@
# include <config.h>
#endif
-#include <glibmm/i18n.h>
+#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H
+#include <glibmm/threads.h>
+#endif
#include <gtkmm/dialog.h> // for Gtk::RESPONSE_*
#include <gtkmm/menu.h>
@@ -24,6 +26,8 @@
#include <gtkmm/radiomenuitem.h>
#include <gtkmm/separatormenuitem.h>
+#include <glibmm/i18n.h>
+
#include <gtk/gtk.h>
#include "panel.h"
@@ -42,7 +46,8 @@ static const int PANEL_SETTING_SIZE = 0;
static const int PANEL_SETTING_MODE = 1;
static const int PANEL_SETTING_SHAPE = 2;
static const int PANEL_SETTING_WRAP = 3;
-static const int PANEL_SETTING_NEXTFREE = 4;
+static const int PANEL_SETTING_BORDER = 4;
+static const int PANEL_SETTING_NEXTFREE = 5;
void Panel::prep() {
@@ -93,7 +98,7 @@ void Panel::_init()
Glib::ustring tmp("<");
_anchor = SP_ANCHOR_CENTER;
- guint panel_size = 0, panel_mode = 0, panel_ratio = 100;
+ guint panel_size = 0, panel_mode = 0, panel_ratio = 100, panel_border = 0;
bool panel_wrap = 0;
if (!_prefs_path.empty()) {
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
@@ -101,6 +106,7 @@ void Panel::_init()
panel_size = prefs->getIntLimited(_prefs_path + "/panel_size", 1, 0, PREVIEW_SIZE_HUGE);
panel_mode = prefs->getIntLimited(_prefs_path + "/panel_mode", 1, 0, 10);
panel_ratio = prefs->getIntLimited(_prefs_path + "/panel_ratio", 100, 0, 500 );
+ panel_border = prefs->getIntLimited(_prefs_path + "/panel_border", BORDER_NONE, 0, 2 );
}
_menu = new Gtk::Menu();
@@ -198,6 +204,42 @@ void Panel::_init()
}
{
+ Glib::ustring widthItemLabel(C_("Swatches", "Border"));
+
+ //TRANSLATORS: Indicates border of colour swatches
+ const gchar *widthLabels[] = {
+ NC_("Swatches border", "None"),
+ NC_("Swatches border", "Solid"),
+ NC_("Swatches border", "Wide"),
+ };
+
+ Gtk::MenuItem *item = manage( new Gtk::MenuItem(widthItemLabel));
+ Gtk::Menu *type_menu = manage(new Gtk::Menu());
+ item->set_submenu(*type_menu);
+ _menu->append(*item);
+
+ Gtk::RadioMenuItem::Group widthGroup;
+
+ guint values[] = {0, 1, 2};
+ guint hot_index = 0;
+ for ( guint i = 0; i < G_N_ELEMENTS(widthLabels); ++i ) {
+ // Assume all values are in increasing order
+ if ( values[i] <= panel_border ) {
+ hot_index = i;
+ }
+ }
+ for ( guint i = 0; i < G_N_ELEMENTS(widthLabels); ++i ) {
+ Glib::ustring _label(g_dpgettext2(NULL, "Swatches border", widthLabels[i]));
+ Gtk::RadioMenuItem *_item = manage(new Gtk::RadioMenuItem(widthGroup, _label));
+ type_menu->append(*_item);
+ if ( i <= hot_index ) {
+ _item->set_active(true);
+ }
+ _item->signal_activate().connect(sigc::bind<int, int>(sigc::mem_fun(*this, &Panel::_bounceCall), PANEL_SETTING_BORDER, values[i]));
+ }
+ }
+
+ {
//TRANSLATORS: "Wrap" indicates how colour swatches are displayed
Glib::ustring wrap_label(C_("Swatches","Wrap"));
Gtk::CheckMenuItem *check = manage(new Gtk::CheckMenuItem(wrap_label));
@@ -259,6 +301,7 @@ void Panel::_init()
_bounceCall(PANEL_SETTING_MODE, panel_mode);
_bounceCall(PANEL_SETTING_SHAPE, panel_ratio);
_bounceCall(PANEL_SETTING_WRAP, panel_wrap);
+ _bounceCall(PANEL_SETTING_BORDER, panel_border);
}
void Panel::setLabel(Glib::ustring const &label)
@@ -323,7 +366,7 @@ void Panel::present()
void Panel::restorePanelPrefs()
{
- guint panel_size = 0, panel_mode = 0, panel_ratio = 100;
+ guint panel_size = 0, panel_mode = 0, panel_ratio = 100, panel_border = 0;
bool panel_wrap = 0;
if (!_prefs_path.empty()) {
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
@@ -331,11 +374,13 @@ void Panel::restorePanelPrefs()
panel_size = prefs->getIntLimited(_prefs_path + "/panel_size", 1, 0, PREVIEW_SIZE_HUGE);
panel_mode = prefs->getIntLimited(_prefs_path + "/panel_mode", 1, 0, 10);
panel_ratio = prefs->getIntLimited(_prefs_path + "/panel_ratio", 000, 0, 500 );
+ panel_border = prefs->getIntLimited(_prefs_path + "/panel_border", BORDER_NONE, 0, 2 );
}
_bounceCall(PANEL_SETTING_SIZE, panel_size);
_bounceCall(PANEL_SETTING_MODE, panel_mode);
_bounceCall(PANEL_SETTING_SHAPE, panel_ratio);
_bounceCall(PANEL_SETTING_WRAP, panel_wrap);
+ _bounceCall(PANEL_SETTING_BORDER, panel_border);
}
sigc::signal<void, int> &Panel::signalResponse()
@@ -360,30 +405,32 @@ void Panel::_bounceCall(int i, int j)
if (_fillable) {
ViewType curr_type = _fillable->getPreviewType();
guint curr_ratio = _fillable->getPreviewRatio();
+ ::BorderStyle curr_border = _fillable->getPreviewBorder();
+
switch (j) {
case 0:
{
- _fillable->setStyle(::PREVIEW_SIZE_TINY, curr_type, curr_ratio);
+ _fillable->setStyle(::PREVIEW_SIZE_TINY, curr_type, curr_ratio, curr_border);
}
break;
case 1:
{
- _fillable->setStyle(::PREVIEW_SIZE_SMALL, curr_type, curr_ratio);
+ _fillable->setStyle(::PREVIEW_SIZE_SMALL, curr_type, curr_ratio, curr_border);
}
break;
case 2:
{
- _fillable->setStyle(::PREVIEW_SIZE_MEDIUM, curr_type, curr_ratio);
+ _fillable->setStyle(::PREVIEW_SIZE_MEDIUM, curr_type, curr_ratio, curr_border);
}
break;
case 3:
{
- _fillable->setStyle(::PREVIEW_SIZE_BIG, curr_type, curr_ratio);
+ _fillable->setStyle(::PREVIEW_SIZE_BIG, curr_type, curr_ratio, curr_border);
}
break;
case 4:
{
- _fillable->setStyle(::PREVIEW_SIZE_HUGE, curr_type, curr_ratio);
+ _fillable->setStyle(::PREVIEW_SIZE_HUGE, curr_type, curr_ratio, curr_border);
}
break;
default:
@@ -399,15 +446,16 @@ void Panel::_bounceCall(int i, int j)
if (_fillable) {
::PreviewSize curr_size = _fillable->getPreviewSize();
guint curr_ratio = _fillable->getPreviewRatio();
+ ::BorderStyle curr_border = _fillable->getPreviewBorder();
switch (j) {
case 0:
{
- _fillable->setStyle(curr_size, VIEW_TYPE_LIST, curr_ratio);
+ _fillable->setStyle(curr_size, VIEW_TYPE_LIST, curr_ratio, curr_border);
}
break;
case 1:
{
- _fillable->setStyle(curr_size, VIEW_TYPE_GRID, curr_ratio);
+ _fillable->setStyle(curr_size, VIEW_TYPE_GRID, curr_ratio, curr_border);
}
break;
default:
@@ -423,7 +471,40 @@ void Panel::_bounceCall(int i, int j)
if ( _fillable ) {
ViewType curr_type = _fillable->getPreviewType();
::PreviewSize curr_size = _fillable->getPreviewSize();
- _fillable->setStyle(curr_size, curr_type, j);
+ ::BorderStyle curr_border = _fillable->getPreviewBorder();
+
+ _fillable->setStyle(curr_size, curr_type, j, curr_border);
+ }
+ break;
+ case PANEL_SETTING_BORDER:
+ if (!_prefs_path.empty()) {
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ prefs->setInt(_prefs_path + "/panel_border", j);
+ }
+ if ( _fillable ) {
+ ::PreviewSize curr_size = _fillable->getPreviewSize();
+ ViewType curr_type = _fillable->getPreviewType();
+ guint curr_ratio = _fillable->getPreviewRatio();
+
+ switch (j) {
+ case 0:
+ {
+ _fillable->setStyle(curr_size, curr_type, curr_ratio, BORDER_NONE);
+ }
+ break;
+ case 1:
+ {
+ _fillable->setStyle(curr_size, curr_type, curr_ratio, BORDER_SOLID);
+ }
+ break;
+ case 2:
+ {
+ _fillable->setStyle(curr_size, curr_type, curr_ratio, BORDER_WIDE);
+ }
+ break;
+ default:
+ break;
+ }
}
break;
case PANEL_SETTING_WRAP:
@@ -483,6 +564,7 @@ void Panel::_regItem(Gtk::MenuItem* item, int group, int id)
_menu->append(*item);
item->signal_activate().connect(sigc::bind<int, int>(sigc::mem_fun(*this, &Panel::_bounceCall), group + PANEL_SETTING_NEXTFREE, id));
item->show();
+
}
void Panel::_handleAction(int /*set_id*/, int /*item_id*/)
@@ -495,31 +577,41 @@ void Panel::_apply()
g_warning("Apply button clicked for panel [Panel::_apply()]");
}
-Gtk::Button *Panel::addResponseButton(const Glib::ustring &button_text, int response_id)
+Gtk::Button *Panel::addResponseButton(const Glib::ustring &button_text, int response_id, bool pack_start)
{
Gtk::Button *button = new Gtk::Button(button_text);
- _addResponseButton(button, response_id);
+ _addResponseButton(button, response_id, pack_start);
return button;
}
-Gtk::Button *Panel::addResponseButton(const Gtk::StockID &stock_id, int response_id)
+Gtk::Button *Panel::addResponseButton(const Gtk::StockID &stock_id, int response_id, bool pack_start)
{
Gtk::Button *button = new Gtk::Button(stock_id);
- _addResponseButton(button, response_id);
+ _addResponseButton(button, response_id, pack_start);
return button;
}
-void Panel::_addResponseButton(Gtk::Button *button, int response_id)
+void Panel::_addResponseButton(Gtk::Button *button, int response_id, bool pack_start)
{
// Create a button box for the response buttons if it's the first button to be added
if (!_action_area) {
+#if WITH_GTKMM_3_0
+ _action_area = new Gtk::ButtonBox();
+ _action_area->set_layout(Gtk::BUTTONBOX_END);
+ _action_area->set_spacing(6);
+#else
_action_area = new Gtk::HButtonBox(Gtk::BUTTONBOX_END, 6);
+#endif
_action_area->set_border_width(4);
pack_end(*_action_area, Gtk::PACK_SHRINK, 0);
}
_action_area->pack_end(*button);
+ if (pack_start) {
+ _action_area->set_child_secondary( *button , true);
+ }
+
if (response_id != 0) {
// Re-emit clicked signals as response signals
button->signal_clicked().connect(sigc::bind(_signal_response.make_slot(), response_id));
diff --git a/src/ui/widget/panel.h b/src/ui/widget/panel.h
index 2d92d65c9..0c3d822b8 100644
--- a/src/ui/widget/panel.h
+++ b/src/ui/widget/panel.h
@@ -13,6 +13,14 @@
#ifndef SEEN_INKSCAPE_UI_WIDGET_PANEL_H
#define SEEN_INKSCAPE_UI_WIDGET_PANEL_H
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H
+#include <glibmm/threads.h>
+#endif
+
#include <gtkmm/box.h>
#include <gtkmm/arrow.h>
#include <gtkmm/button.h>
@@ -27,7 +35,13 @@ class SPDocument;
namespace Gtk {
class CheckMenuItem;
+
+#if WITH_GTKMM_3_0
+ class ButtonBox;
+#else
class HButtonBox;
+#endif
+
class MenuItem;
}
@@ -96,8 +110,8 @@ public:
/* Methods providing a Gtk::Dialog like interface for adding buttons that emit Gtk::RESPONSE
* signals on click. */
- Gtk::Button* addResponseButton (const Glib::ustring &button_text, int response_id);
- Gtk::Button* addResponseButton (const Gtk::StockID &stock_id, int response_id);
+ Gtk::Button* addResponseButton (const Glib::ustring &button_text, int response_id, bool pack_start=false);
+ Gtk::Button* addResponseButton (const Gtk::StockID &stock_id, int response_id, bool pack_start=false);
void setDefaultResponse(int response_id);
void setResponseSensitive(int response_id, bool setting);
@@ -119,7 +133,7 @@ protected:
virtual void _handleResponse(int response_id);
/* Helper methods */
- void _addResponseButton(Gtk::Button *button, int response_id);
+ void _addResponseButton(Gtk::Button *button, int response_id, bool pack_start=false);
Inkscape::Selection *_getSelection();
/**
@@ -157,7 +171,13 @@ private:
Gtk::EventBox _menu_popper;
Gtk::Button _close_button;
Gtk::Menu *_menu;
+
+#if WITH_GTKMM_3_0
+ Gtk::ButtonBox *_action_area; //< stores response buttons
+#else
Gtk::HButtonBox *_action_area; //< stores response buttons
+#endif
+
std::vector<Gtk::Widget *> _non_horizontal;
std::vector<Gtk::Widget *> _non_vertical;
PreviewFillable *_fillable;
diff --git a/src/ui/widget/point.h b/src/ui/widget/point.h
index 15f1a80fb..17078df8f 100644
--- a/src/ui/widget/point.h
+++ b/src/ui/widget/point.h
@@ -13,8 +13,8 @@
#ifndef INKSCAPE_UI_WIDGET_POINT_H
#define INKSCAPE_UI_WIDGET_POINT_H
-#include <2geom/point.h>
#include "ui/widget/labelled.h"
+#include <2geom/point.h>
#include "ui/widget/scalar.h"
namespace Gtk {
diff --git a/src/ui/widget/preferences-widget.cpp b/src/ui/widget/preferences-widget.cpp
index a7b51d535..3ba00c083 100644
--- a/src/ui/widget/preferences-widget.cpp
+++ b/src/ui/widget/preferences-widget.cpp
@@ -18,10 +18,16 @@
#include <windows.h>
#endif
+#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H
+#include <glibmm/threads.h>
+#endif
+
#include <gtkmm/box.h>
#include <gtkmm/frame.h>
#include <gtkmm/alignment.h>
+#include <gtkmm/scale.h>
#include <gtkmm/stock.h>
+#include <gtkmm/table.h>
#include "preferences.h"
#include "ui/widget/preferences-widget.h"
@@ -39,6 +45,8 @@
#include "selection-chemistry.h"
#include "ui/dialog/filedialog.h"
#include "xml/repr.h"
+
+#include <glibmm/convert.h>
#include <glibmm/i18n.h>
using namespace Inkscape::UI::Widget;
@@ -49,98 +57,139 @@ namespace Widget {
DialogPage::DialogPage()
{
- this->set_border_width(12);
- this->set_col_spacings(12);
- this->set_row_spacings(6);
+ set_border_width(12);
+
+#if WITH_GTKMM_3_0
+ set_orientation(Gtk::ORIENTATION_VERTICAL);
+ set_column_spacing(12);
+ set_row_spacing(6);
+#else
+ set_col_spacings(12);
+ set_row_spacings(6);
+#endif
}
-void DialogPage::add_line(bool indent, Glib::ustring const &label, Gtk::Widget &widget, Glib::ustring const &suffix, const Glib::ustring &tip, bool expand_widget)
+/**
+ * Add a widget to the bottom row of the dialog page
+ *
+ * \param[in] indent Whether the widget should be indented by one column
+ * \param[in] label The label text for the widget
+ * \param[in] widget The widget to add to the page
+ * \param[in] suffix Text for an optional label at the right of the widget
+ * \param[in] tip Tooltip text for the widget
+ * \param[in] expand_widget Whether to expand the widget horizontally
+ * \param[in] other_widget An optional additional widget to display at the right of the first one
+ */
+void DialogPage::add_line(bool indent,
+ Glib::ustring const &label,
+ Gtk::Widget &widget,
+ Glib::ustring const &suffix,
+ const Glib::ustring &tip,
+ bool expand_widget,
+ Gtk::Widget *other_widget)
{
- int start_col;
- int row = this->property_n_rows();
- Gtk::Widget* w;
- if (expand_widget)
- {
- w = &widget;
- }
- else
- {
- Gtk::HBox* hb = Gtk::manage(new Gtk::HBox());
- hb->set_spacing(12);
- hb->pack_start(widget,false,false);
- w = (Gtk::Widget*) hb;
- }
- if (label != "")
- {
- Gtk::Label* label_widget;
-#if WITH_GTKMM_2_22
- label_widget = Gtk::manage(new Gtk::Label(label , Gtk::ALIGN_START , Gtk::ALIGN_CENTER, true));
+ if (tip != "")
+ widget.set_tooltip_text (tip);
+
+ Gtk::Alignment* label_alignment = Gtk::manage(new Gtk::Alignment());
+
+ Gtk::HBox* hb = Gtk::manage(new Gtk::HBox());
+ hb->set_spacing(12);
+ hb->pack_start(widget, expand_widget, expand_widget);
+
+ // Pack an additional widget into a box with the widget if desired
+ if (other_widget)
+ hb->pack_start(*other_widget, expand_widget, expand_widget);
+
+ // Pack the widget into an alignment container so that it can
+ // be indented if desired
+ Gtk::Alignment* w_alignment = Gtk::manage(new Gtk::Alignment());
+ w_alignment->add(*hb);
+
+#if WITH_GTKMM_3_0
+ w_alignment->set_valign(Gtk::ALIGN_CENTER);
#else
- label_widget = Gtk::manage(new Gtk::Label(label , Gtk::ALIGN_LEFT , Gtk::ALIGN_CENTER, true));
+ guint row = property_n_rows();
#endif
+
+ // Add a label in the first column if provided
+ if (label != "")
+ {
+ Gtk::Label* label_widget = Gtk::manage(new Gtk::Label(label, Gtk::ALIGN_START,
+ Gtk::ALIGN_CENTER, true));
label_widget->set_mnemonic_widget(widget);
+
+ // Pack the label into an alignment container so that we can indent it
+ // if necessary
+ label_alignment->add(*label_widget);
+
if (indent)
- {
- Gtk::Alignment* alignment = Gtk::manage(new Gtk::Alignment());
- alignment->set_padding(0, 0, 12, 0);
- alignment->add(*label_widget);
- this->attach(*alignment , 0, 1, row, row + 1, Gtk::FILL, Gtk::AttachOptions(), 0, 0);
- }
- else
- this->attach(*label_widget , 0, 1, row, row + 1, Gtk::FILL, Gtk::AttachOptions(), 0, 0);
- start_col = 1;
- }
- else
- start_col = 0;
+ label_alignment->set_padding(0, 0, 12, 0);
- if (start_col == 0 && indent) //indent this widget
- {
- Gtk::Alignment* alignment = Gtk::manage(new Gtk::Alignment());
- alignment->set_padding(0, 0, 12, 0);
- alignment->add(*w);
- this->attach(*alignment, start_col, 2, row, row + 1, Gtk::FILL | Gtk::EXPAND, Gtk::AttachOptions(), 0, 0);
- }
- else
- {
- this->attach(*w, start_col, 2, row, row + 1, Gtk::FILL | Gtk::EXPAND, Gtk::AttachOptions(), 0, 0);
+#if WITH_GTKMM_3_0
+ label_alignment->set_valign(Gtk::ALIGN_CENTER);
+ add(*label_alignment);
+ attach_next_to(*w_alignment, *label_alignment, Gtk::POS_RIGHT, 1, 1);
+#else
+ attach(*label_alignment, 0, 1, row, row + 1, Gtk::FILL, Gtk::AttachOptions(), 0, 0);
+#endif
}
- if (suffix != "")
+ // Now add the widget to the bottom of the dialog
+#if WITH_GTKMM_3_0
+ if (label == "")
{
-#if WITH_GTKMM_2_22
- Gtk::Label* suffix_widget = Gtk::manage(new Gtk::Label(suffix , Gtk::ALIGN_START , Gtk::ALIGN_CENTER, true));
+ if (indent)
+ w_alignment->set_padding(0, 0, 12, 0);
+
+ add(*w_alignment);
+
+ GValue width = G_VALUE_INIT;
+ g_value_init(&width, G_TYPE_INT);
+ g_value_set_int(&width, 2);
+ gtk_container_child_set_property(GTK_CONTAINER(gobj()), GTK_WIDGET(w_alignment->gobj()), "width", &width);
+ }
#else
- Gtk::Label* suffix_widget = Gtk::manage(new Gtk::Label(suffix , Gtk::ALIGN_LEFT , Gtk::ALIGN_CENTER, true));
+ // The widget should span two columns if there is no label
+ int w_col_span = 1;
+ if (label == "")
+ w_col_span = 2;
+
+ attach(*w_alignment, 2 - w_col_span, 2, row, row + 1,
+ Gtk::FILL | Gtk::EXPAND,
+ Gtk::AttachOptions(),
+ 0, 0);
#endif
- if (expand_widget)
- this->attach(*suffix_widget, 2, 3, row, row + 1, Gtk::FILL, Gtk::AttachOptions(), 0, 0);
- else
- ((Gtk::HBox*)w)->pack_start(*suffix_widget,false,false);
- }
- if (tip != "")
+ // Add a label on the right of the widget if desired
+ if (suffix != "")
{
- widget.set_tooltip_text (tip);
+ Gtk::Label* suffix_widget = Gtk::manage(new Gtk::Label(suffix , Gtk::ALIGN_START , Gtk::ALIGN_CENTER, true));
+ hb->pack_start(*suffix_widget,false,false);
}
}
void DialogPage::add_group_header(Glib::ustring name)
{
- int row = this->property_n_rows();
if (name != "")
{
-#if WITH_GTKMM_2_22
Gtk::Label* label_widget = Gtk::manage(new Gtk::Label(Glib::ustring(/*"<span size='large'>*/"<b>") + name +
Glib::ustring("</b>"/*</span>"*/) , Gtk::ALIGN_START , Gtk::ALIGN_CENTER, true));
-#else
- Gtk::Label* label_widget = Gtk::manage(new Gtk::Label(Glib::ustring(/*"<span size='large'>*/"<b>") + name +
- Glib::ustring("</b>"/*</span>"*/) , Gtk::ALIGN_LEFT , Gtk::ALIGN_CENTER, true));
-#endif
+
label_widget->set_use_markup(true);
- this->attach(*label_widget , 0, 4, row, row + 1, Gtk::FILL, Gtk::AttachOptions(), 0, 0);
+
+#if WITH_GTKMM_3_0
+ label_widget->set_valign(Gtk::ALIGN_CENTER);
+ add(*label_widget);
+// if (row != 1)
+ // set_row_spacing(row - 1, 18);
+#else
+ int row = property_n_rows();
+ attach(*label_widget , 0, 4, row, row + 1, Gtk::FILL, Gtk::AttachOptions(), 0, 0);
if (row != 1)
- this->set_row_spacing(row - 1, 18);
+ set_row_spacing(row - 1, 18);
+#endif
}
}
@@ -305,7 +354,7 @@ void PrefSpinUnit::on_my_value_changed()
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
if (getWidget()->get_visible()) //only take action if user changed value
{
- prefs->setDoubleUnit(_prefs_path, getValue(getUnit().abbr), getUnit().abbr);
+ prefs->setDoubleUnit(_prefs_path, getValue(getUnit()->abbr), getUnit()->abbr);
}
}
@@ -381,17 +430,29 @@ ZoomCorrRuler::draw_marks(Cairo::RefPtr<Cairo::Context> cr, double dist, int maj
}
}
-void
-ZoomCorrRuler::redraw() {
+#if !WITH_GTKMM_3_0
+bool
+ZoomCorrRuler::on_expose_event(GdkEventExpose *event) {
+ bool result = false;
+
+ if(get_is_drawable())
+ {
+ Cairo::RefPtr<Cairo::Context> cr = get_window()->create_cairo_context();
+ cr->rectangle(event->area.x, event->area.y,
+ event->area.width, event->area.height);
+ cr->clip();
+ result = on_draw(cr);
+ }
+
+ return result;
+}
+#endif
+
+bool
+ZoomCorrRuler::on_draw(const Cairo::RefPtr<Cairo::Context>& cr) {
Glib::RefPtr<Gdk::Window> window = get_window();
- Cairo::RefPtr<Cairo::Context> cr = window->create_cairo_context();
-#if WITH_GTKMM_2_24
int w = window->get_width();
-#else
- int w, h;
- window->get_size(w, h);
-#endif
_drawing_width = w - _border * 2;
cr->set_source_rgb(1.0, 1.0, 1.0);
@@ -428,14 +489,11 @@ ZoomCorrRuler::redraw() {
draw_marks(cr, 1, 1);
}
cr->stroke();
-}
-bool
-ZoomCorrRuler::on_expose_event(GdkEventExpose */*event*/) {
- this->redraw();
return true;
}
+
void
ZoomCorrRulerSlider::on_slider_value_changed()
{
@@ -443,9 +501,9 @@ ZoomCorrRulerSlider::on_slider_value_changed()
{
freeze = true;
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- prefs->setDouble("/options/zoomcorrection/value", _slider.get_value() / 100.0);
- _sb.set_value(_slider.get_value());
- _ruler.redraw();
+ prefs->setDouble("/options/zoomcorrection/value", _slider->get_value() / 100.0);
+ _sb.set_value(_slider->get_value());
+ _ruler.queue_draw();
freeze = false;
}
}
@@ -458,8 +516,8 @@ ZoomCorrRulerSlider::on_spinbutton_value_changed()
freeze = true;
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
prefs->setDouble("/options/zoomcorrection/value", _sb.get_value() / 100.0);
- _slider.set_value(_sb.get_value());
- _ruler.redraw();
+ _slider->set_value(_sb.get_value());
+ _ruler.queue_draw();
freeze = false;
}
}
@@ -476,10 +534,16 @@ ZoomCorrRulerSlider::on_unit_changed() {
double conv = _unit.getConversion(_unit.getUnitAbbr(), "px");
_ruler.set_unit_conversion(conv);
if (_ruler.get_visible()) {
- _ruler.redraw();
+ _ruler.queue_draw();
}
}
+bool ZoomCorrRulerSlider::on_mnemonic_activate ( bool group_cycling )
+{
+ return _sb.mnemonic_activate ( group_cycling );
+}
+
+
void
ZoomCorrRulerSlider::init(int ruler_width, int ruler_height, double lower, double upper,
double step_increment, double page_increment, double default_value)
@@ -491,13 +555,19 @@ ZoomCorrRulerSlider::init(int ruler_width, int ruler_height, double lower, doubl
_ruler.set_size(ruler_width, ruler_height);
- _slider.set_size_request(_ruler.width(), -1);
- _slider.set_range (lower, upper);
- _slider.set_increments (step_increment, page_increment);
- _slider.set_value (value);
- _slider.set_digits(2);
+#if WITH_GTKMM_3_0
+ _slider = Gtk::manage(new Gtk::Scale(Gtk::ORIENTATION_HORIZONTAL));
+#else
+ _slider = Gtk::manage(new Gtk::HScale());
+#endif
+
+ _slider->set_size_request(_ruler.width(), -1);
+ _slider->set_range (lower, upper);
+ _slider->set_increments (step_increment, page_increment);
+ _slider->set_value (value);
+ _slider->set_digits(2);
- _slider.signal_value_changed().connect(sigc::mem_fun(*this, &ZoomCorrRulerSlider::on_slider_value_changed));
+ _slider->signal_value_changed().connect(sigc::mem_fun(*this, &ZoomCorrRulerSlider::on_slider_value_changed));
_sb.signal_value_changed().connect(sigc::mem_fun(*this, &ZoomCorrRulerSlider::on_spinbutton_value_changed));
_unit.signal_changed().connect(sigc::mem_fun(*this, &ZoomCorrRulerSlider::on_unit_changed));
@@ -511,18 +581,28 @@ ZoomCorrRulerSlider::init(int ruler_width, int ruler_height, double lower, doubl
_unit.set_data("sensitive", GINT_TO_POINTER(1));
_unit.setUnit(prefs->getString("/options/zoomcorrection/unit"));
- Gtk::Table *table = Gtk::manage(new Gtk::Table());
Gtk::Alignment *alignment1 = Gtk::manage(new Gtk::Alignment(0.5,1,0,0));
Gtk::Alignment *alignment2 = Gtk::manage(new Gtk::Alignment(0.5,1,0,0));
alignment1->add(_sb);
alignment2->add(_unit);
- table->attach(_slider, 0, 1, 0, 1);
+#if WITH_GTKMM_3_0
+ Gtk::Grid *table = Gtk::manage(new Gtk::Grid());
+ table->attach(*_slider, 0, 0, 1, 1);
+ alignment1->set_halign(Gtk::ALIGN_CENTER);
+ table->attach(*alignment1, 1, 0, 1, 1);
+ table->attach(_ruler, 0, 1, 1, 1);
+ alignment2->set_halign(Gtk::ALIGN_CENTER);
+ table->attach(*alignment2, 1, 1, 1, 1);
+#else
+ Gtk::Table *table = Gtk::manage(new Gtk::Table());
+ table->attach(*_slider, 0, 1, 0, 1);
table->attach(*alignment1, 1, 2, 0, 1, static_cast<Gtk::AttachOptions>(0));
table->attach(_ruler, 0, 1, 1, 2);
table->attach(*alignment2, 1, 2, 1, 2, static_cast<Gtk::AttachOptions>(0));
+#endif
- this->pack_start(*table, Gtk::PACK_EXPAND_WIDGET);
+ pack_start(*table, Gtk::PACK_SHRINK);
}
void
@@ -532,8 +612,8 @@ PrefSlider::on_slider_value_changed()
{
freeze = true;
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- prefs->setDouble(_prefs_path, _slider.get_value());
- _sb.set_value(_slider.get_value());
+ prefs->setDouble(_prefs_path, _slider->get_value());
+ _sb.set_value(_slider->get_value());
freeze = false;
}
}
@@ -546,11 +626,16 @@ PrefSlider::on_spinbutton_value_changed()
freeze = true;
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
prefs->setDouble(_prefs_path, _sb.get_value());
- _slider.set_value(_sb.get_value());
+ _slider->set_value(_sb.get_value());
freeze = false;
}
}
+bool PrefSlider::on_mnemonic_activate ( bool group_cycling )
+{
+ return _sb.mnemonic_activate ( group_cycling );
+}
+
void
PrefSlider::init(Glib::ustring const &prefs_path,
double lower, double upper, double step_increment, double page_increment, double default_value, int digits)
@@ -562,11 +647,17 @@ PrefSlider::init(Glib::ustring const &prefs_path,
freeze = false;
- _slider.set_range (lower, upper);
- _slider.set_increments (step_increment, page_increment);
- _slider.set_value (value);
- _slider.set_digits(digits);
- _slider.signal_value_changed().connect(sigc::mem_fun(*this, &PrefSlider::on_slider_value_changed));
+#if WITH_GTKMM_3_0
+ _slider = Gtk::manage(new Gtk::Scale(Gtk::ORIENTATION_HORIZONTAL));
+#else
+ _slider = Gtk::manage(new Gtk::HScale());
+#endif
+
+ _slider->set_range (lower, upper);
+ _slider->set_increments (step_increment, page_increment);
+ _slider->set_value (value);
+ _slider->set_digits(digits);
+ _slider->signal_value_changed().connect(sigc::mem_fun(*this, &PrefSlider::on_slider_value_changed));
_sb.signal_value_changed().connect(sigc::mem_fun(*this, &PrefSlider::on_spinbutton_value_changed));
_sb.set_range (lower, upper);
@@ -574,12 +665,20 @@ PrefSlider::init(Glib::ustring const &prefs_path,
_sb.set_value (value);
_sb.set_digits(digits);
- Gtk::Table *table = Gtk::manage(new Gtk::Table());
Gtk::Alignment *alignment1 = Gtk::manage(new Gtk::Alignment(0.5,1,0,0));
alignment1->add(_sb);
- table->attach(_slider, 0, 1, 0, 1);
+#if WITH_GTKMM_3_0
+ Gtk::Grid *table = Gtk::manage(new Gtk::Grid());
+ _slider->set_hexpand();
+ table->attach(*_slider, 0, 0, 1, 1);
+ alignment1->set_halign(Gtk::ALIGN_CENTER);
+ table->attach(*alignment1, 1, 0, 1, 1);
+#else
+ Gtk::Table *table = Gtk::manage(new Gtk::Table());
+ table->attach(*_slider, 0, 1, 0, 1);
table->attach(*alignment1, 1, 2, 0, 1, static_cast<Gtk::AttachOptions>(0));
+#endif
this->pack_start(*table, Gtk::PACK_EXPAND_WIDGET);
}
@@ -594,11 +693,7 @@ void PrefCombo::init(Glib::ustring const &prefs_path,
for (int i = 0 ; i < num_items; ++i)
{
-#if WITH_GTKMM_2_24
this->append(labels[i]);
-#else
- this->append_text(labels[i]);
-#endif
_values.push_back(values[i]);
if (value == values[i])
row = i;
@@ -620,11 +715,7 @@ void PrefCombo::init(Glib::ustring const &prefs_path,
for (int i = 0 ; i < num_items; ++i)
{
-#if WITH_GTKMM_2_24
this->append(labels[i]);
-#else
- this->append_text(labels[i]);
-#endif
_ustr_values.push_back(values[i]);
if (value == values[i])
row = i;
@@ -637,7 +728,7 @@ void PrefCombo::on_changed()
if (this->get_visible()) //only take action if user changed value
{
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- if(_values.size() > 0)
+ if(!_values.empty())
{
prefs->setInt(_prefs_path, _values[this->get_active_row_number()]);
}
@@ -686,6 +777,11 @@ void PrefEntryButtonHBox::onRelatedButtonClickedCallback()
}
}
+bool PrefEntryButtonHBox::on_mnemonic_activate ( bool group_cycling )
+{
+ return relatedEntry->mnemonic_activate ( group_cycling );
+}
+
void PrefEntryFileButtonHBox::init(Glib::ustring const &prefs_path,
bool visibility)
{
@@ -818,6 +914,11 @@ void PrefEntryFileButtonHBox::onRelatedButtonClickedCallback()
}
}
+bool PrefEntryFileButtonHBox::on_mnemonic_activate ( bool group_cycling )
+{
+ return relatedEntry->mnemonic_activate ( group_cycling );
+}
+
void PrefFileButton::init(Glib::ustring const &prefs_path)
{
_prefs_path = prefs_path;
diff --git a/src/ui/widget/preferences-widget.h b/src/ui/widget/preferences-widget.h
index 874e0958a..cb4ce17d1 100644
--- a/src/ui/widget/preferences-widget.h
+++ b/src/ui/widget/preferences-widget.h
@@ -15,8 +15,17 @@
#ifndef INKSCAPE_UI_WIDGET_INKSCAPE_PREFERENCES_H
#define INKSCAPE_UI_WIDGET_INKSCAPE_PREFERENCES_H
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
#include <iostream>
#include <vector>
+
+#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H
+#include <glibmm/threads.h>
+#endif
+
#include <gtkmm/filechooserbutton.h>
#include "ui/widget/spinbutton.h"
#include <stddef.h>
@@ -25,14 +34,26 @@
#include <gtkmm/radiobutton.h>
#include <gtkmm/comboboxtext.h>
#include <gtkmm/drawingarea.h>
-#include <gtkmm/scale.h>
+
+#if WITH_GTKMM_3_0
+#include <gtkmm/grid.h>
+#else
#include <gtkmm/table.h>
+#endif
#include "ui/widget/color-picker.h"
#include "ui/widget/unit-menu.h"
#include "ui/widget/spinbutton.h"
#include "ui/widget/scalar-unit.h"
+namespace Gtk {
+#if WITH_GTKMM_3_0
+class Scale;
+#else
+class HScale;
+#endif
+}
+
namespace Inkscape {
namespace UI {
namespace Widget {
@@ -101,8 +122,6 @@ public:
ZoomCorrRuler(int width = 100, int height = 20);
void set_size(int x, int y);
void set_unit_conversion(double conv) { _unitconv = conv; }
- void set_cairo_context(Cairo::RefPtr<Cairo::Context> cr);
- void redraw();
int width() { return _min_width + _border*2; }
@@ -110,7 +129,12 @@ public:
static const double textpadding;
private:
+#if !WITH_GTKMM_3_0
bool on_expose_event(GdkEventExpose *event);
+#endif
+
+ bool on_draw(const Cairo::RefPtr<Cairo::Context>& cr);
+
void draw_marks(Cairo::RefPtr<Cairo::Context> cr, double dist, int major_interval);
double _unitconv;
@@ -130,10 +154,15 @@ private:
void on_slider_value_changed();
void on_spinbutton_value_changed();
void on_unit_changed();
+ virtual bool on_mnemonic_activate( bool group_cycling );
Inkscape::UI::Widget::SpinButton _sb;
UnitMenu _unit;
- Gtk::HScale _slider;
+#if WITH_GTKMM_3_0
+ Gtk::Scale* _slider;
+#else
+ Gtk::HScale* _slider;
+#endif
ZoomCorrRuler _ruler;
bool freeze; // used to block recursive updates of slider and spinbutton
};
@@ -147,10 +176,17 @@ public:
private:
void on_slider_value_changed();
void on_spinbutton_value_changed();
-
+ virtual bool on_mnemonic_activate( bool group_cycling );
+
Glib::ustring _prefs_path;
Inkscape::UI::Widget::SpinButton _sb;
- Gtk::HScale _slider;
+
+#if WITH_GTKMM_3_0
+ Gtk::Scale* _slider;
+#else
+ Gtk::HScale* _slider;
+#endif
+
bool freeze; // used to block recursive updates of slider and spinbutton
};
@@ -188,6 +224,7 @@ class PrefEntryButtonHBox : public Gtk::HBox
public:
void init(Glib::ustring const &prefs_path,
bool mask, Glib::ustring const &default_string);
+
protected:
Glib::ustring _prefs_path;
Glib::ustring _default_string;
@@ -195,6 +232,7 @@ protected:
Gtk::Entry *relatedEntry;
void onRelatedEntryChangedCallback();
void onRelatedButtonClickedCallback();
+ virtual bool on_mnemonic_activate( bool group_cycling );
};
class PrefEntryFileButtonHBox : public Gtk::HBox
@@ -208,6 +246,7 @@ protected:
Gtk::Entry *relatedEntry;
void onRelatedEntryChangedCallback();
void onRelatedButtonClickedCallback();
+ virtual bool on_mnemonic_activate( bool group_cycling );
};
class PrefFileButton : public Gtk::FileChooserButton
@@ -243,11 +282,15 @@ protected:
void on_changed();
};
+#if WITH_GTKMM_3_0
+class DialogPage : public Gtk::Grid
+#else
class DialogPage : public Gtk::Table
+#endif
{
public:
DialogPage();
- void add_line(bool indent, Glib::ustring const &label, Gtk::Widget& widget, Glib::ustring const &suffix, Glib::ustring const &tip, bool expand = true);
+ void add_line(bool indent, Glib::ustring const &label, Gtk::Widget& widget, Glib::ustring const &suffix, Glib::ustring const &tip, bool expand = true, Gtk::Widget *other_widget = NULL);
void add_group_header(Glib::ustring name);
void set_tip(Gtk::Widget &widget, Glib::ustring const &tip);
};
diff --git a/src/ui/widget/registered-widget.cpp b/src/ui/widget/registered-widget.cpp
index ea2bac867..175f6471c 100644
--- a/src/ui/widget/registered-widget.cpp
+++ b/src/ui/widget/registered-widget.cpp
@@ -27,7 +27,6 @@
#include "ui/widget/random.h"
#include "widgets/spinbutton-events.h"
-#include "helper/units.h"
#include "xml/repr.h"
#include "svg/svg-color.h"
#include "svg/stringstream.h"
@@ -50,8 +49,10 @@ RegisteredCheckButton::~RegisteredCheckButton()
_toggled_connection.disconnect();
}
-RegisteredCheckButton::RegisteredCheckButton (const Glib::ustring& label, const Glib::ustring& tip, const Glib::ustring& key, Registry& wr, bool right, Inkscape::XML::Node* repr_in, SPDocument *doc_in)
+RegisteredCheckButton::RegisteredCheckButton (const Glib::ustring& label, const Glib::ustring& tip, const Glib::ustring& key, Registry& wr, bool right, Inkscape::XML::Node* repr_in, SPDocument *doc_in, char const *active_str, char const *inactive_str)
: RegisteredWidget<Gtk::CheckButton>()
+ , _active_str(active_str)
+ , _inactive_str(inactive_str)
{
init_parent(key, wr, repr_in, doc_in);
@@ -89,7 +90,7 @@ RegisteredCheckButton::on_toggled()
return;
_wr->setUpdating (true);
- write_to_xml(get_active() ? "true" : "false");
+ write_to_xml(get_active() ? _active_str : _inactive_str);
//The slave button is greyed out if the master button is unchecked
for (std::list<Gtk::Widget*>::const_iterator i = _slavewidgets.begin(); i != _slavewidgets.end(); ++i) {
(*i)->set_sensitive(get_active());
@@ -118,9 +119,9 @@ RegisteredUnitMenu::RegisteredUnitMenu (const Glib::ustring& label, const Glib::
}
void
-RegisteredUnitMenu::setUnit (const SPUnit* unit)
+RegisteredUnitMenu::setUnit (Glib::ustring unit)
{
- getUnitMenu()->setUnit (sp_unit_get_abbreviation (unit));
+ getUnitMenu()->setUnit(unit);
}
void
diff --git a/src/ui/widget/registered-widget.h b/src/ui/widget/registered-widget.h
index 2a7843a51..d64c09c16 100644
--- a/src/ui/widget/registered-widget.h
+++ b/src/ui/widget/registered-widget.h
@@ -32,7 +32,6 @@
#include <gtkmm/checkbutton.h>
-class SPUnit;
class SPDocument;
namespace Gtk {
@@ -56,6 +55,11 @@ public:
event_description = _event_description;
write_undo = true;
}
+ void set_xml_target(Inkscape::XML::Node *xml_node, SPDocument *document)
+ {
+ repr = xml_node;
+ doc = document;
+ }
bool is_updating() {if (_wr) return _wr->isUpdating(); else return false;}
@@ -128,6 +132,7 @@ private:
repr = NULL;
doc = NULL;
write_undo = false;
+ event_type = -1;
}
};
@@ -136,7 +141,7 @@ private:
class RegisteredCheckButton : public RegisteredWidget<Gtk::CheckButton> {
public:
virtual ~RegisteredCheckButton();
- RegisteredCheckButton (const Glib::ustring& label, const Glib::ustring& tip, const Glib::ustring& key, Registry& wr, bool right=true, Inkscape::XML::Node* repr_in=NULL, SPDocument *doc_in=NULL);
+ RegisteredCheckButton (const Glib::ustring& label, const Glib::ustring& tip, const Glib::ustring& key, Registry& wr, bool right=true, Inkscape::XML::Node* repr_in=NULL, SPDocument *doc_in=NULL, char const *active_str = "true", char const *inactive_str = "false");
void setActive (bool);
@@ -153,6 +158,7 @@ public:
// if a callback checks it, it must reset it back to false
protected:
+ char const *_active_str, *_inactive_str;
sigc::connection _toggled_connection;
void on_toggled();
};
@@ -166,8 +172,8 @@ public:
Inkscape::XML::Node* repr_in = NULL,
SPDocument *doc_in = NULL );
- void setUnit (const SPUnit*);
- Unit getUnit() const { return static_cast<UnitMenu*>(_widget)->getUnit(); };
+ void setUnit (const Glib::ustring);
+ Unit const * getUnit() const { return static_cast<UnitMenu*>(_widget)->getUnit(); };
UnitMenu* getUnitMenu() const { return static_cast<UnitMenu*>(_widget); };
sigc::connection _changed_connection;
diff --git a/src/ui/widget/registry.h b/src/ui/widget/registry.h
index ed1281d79..2da29735c 100644
--- a/src/ui/widget/registry.h
+++ b/src/ui/widget/registry.h
@@ -9,10 +9,6 @@
#ifndef INKSCAPE_UI_WIDGET_REGISTRY__H
#define INKSCAPE_UI_WIDGET_REGISTRY__H
-#include <map>
-#include <glibmm/i18n.h>
-#include <glibmm/ustring.h>
-
namespace Gtk {
class Object;
}
diff --git a/src/ui/widget/rendering-options.cpp b/src/ui/widget/rendering-options.cpp
index 7655f25e3..d6248df69 100644
--- a/src/ui/widget/rendering-options.cpp
+++ b/src/ui/widget/rendering-options.cpp
@@ -12,10 +12,9 @@
# include <config.h>
#endif
-#include <glibmm/i18n.h>
-
-#include "unit-constants.h"
#include "rendering-options.h"
+#include "util/units.h"
+#include <glibmm/i18n.h>
namespace Inkscape {
namespace UI {
@@ -60,8 +59,8 @@ RenderingOptions::RenderingOptions () :
_radio_bitmap.signal_toggled().connect(sigc::mem_fun(*this, &RenderingOptions::_toggled));
// configure default DPI
- _dpi.setRange(PT_PER_IN,2400.0);
- _dpi.setValue(PT_PER_IN);
+ _dpi.setRange(Inkscape::Util::Quantity::convert(1, "in", "pt"),2400.0);
+ _dpi.setValue(Inkscape::Util::Quantity::convert(1, "in", "pt"));
_dpi.setIncrements(1.0,10.0);
_dpi.setDigits(0);
_dpi.update();
diff --git a/src/ui/widget/rotateable.cpp b/src/ui/widget/rotateable.cpp
index c31e6f529..72ec69362 100644
--- a/src/ui/widget/rotateable.cpp
+++ b/src/ui/widget/rotateable.cpp
@@ -7,11 +7,19 @@
* Released under GNU GPL. Read the file 'COPYING' for more information.
*/
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H
+#include <glibmm/threads.h>
+#endif
+
#include <gtkmm/box.h>
#include <gtkmm/eventbox.h>
#include <glibmm/i18n.h>
#include <2geom/point.h>
-#include "event-context.h"
+#include "ui/tools/tool-base.h"
#include "rotateable.h"
namespace Inkscape {
@@ -24,25 +32,28 @@ Rotateable::Rotateable():
{
dragging = false;
working = false;
+ scrolling = false;
modifier = 0;
current_axis = axis;
signal_button_press_event().connect(sigc::mem_fun(*this, &Rotateable::on_click));
signal_motion_notify_event().connect(sigc::mem_fun(*this, &Rotateable::on_motion));
signal_button_release_event().connect(sigc::mem_fun(*this, &Rotateable::on_release));
+ signal_scroll_event().connect(sigc::mem_fun(*this, &Rotateable::on_scroll));
+
}
bool Rotateable::on_click(GdkEventButton *event) {
- if (event->button == 1) {
+ if (event->button == 1) {
drag_started_x = event->x;
drag_started_y = event->y;
- modifier = get_single_modifier(modifier, event->state);
+ modifier = get_single_modifier(modifier, event->state);
dragging = true;
working = false;
current_axis = axis;
return true;
- }
- return false;
+ }
+ return false;
}
guint Rotateable::get_single_modifier(guint old, guint state) {
@@ -100,7 +111,7 @@ bool Rotateable::on_motion(GdkEventMotion *event) {
do_motion(force, modifier);
}
}
- gobble_motion_events(GDK_BUTTON1_MASK);
+ Inkscape::UI::Tools::gobble_motion_events(GDK_BUTTON1_MASK);
return true;
}
return false;
@@ -108,9 +119,9 @@ bool Rotateable::on_motion(GdkEventMotion *event) {
bool Rotateable::on_release(GdkEventButton *event) {
- if (dragging && working) {
+ if (dragging && working) {
double angle = atan2(event->y - drag_started_y, event->x - drag_started_x);
- double force = CLAMP (-(angle - current_axis)/maxdecl, -1, 1);
+ double force = CLAMP(-(angle - current_axis) / maxdecl, -1, 1);
if (fabs(force) < 0.002)
force = 0; // snap to zero
do_release(force, modifier);
@@ -118,12 +129,40 @@ bool Rotateable::on_release(GdkEventButton *event) {
dragging = false;
working = false;
return true;
- }
+ }
dragging = false;
working = false;
- return false;
+ return false;
}
+bool Rotateable::on_scroll(GdkEventScroll* event)
+{
+ double change = 0.0;
+
+ if (event->direction == GDK_SCROLL_UP) {
+ change = 1.0;
+ } else if (event->direction == GDK_SCROLL_DOWN) {
+ change = -1.0;
+ } else {
+ return FALSE;
+ }
+
+ drag_started_x = event->x;
+ drag_started_y = event->y;
+ modifier = get_single_modifier(modifier, event->state);
+ dragging = false;
+ working = false;
+ scrolling = true;
+ current_axis = axis;
+
+ do_scroll(change, modifier);
+
+ dragging = false;
+ working = false;
+ scrolling = false;
+
+ return TRUE;
+}
Rotateable::~Rotateable() {
}
diff --git a/src/ui/widget/rotateable.h b/src/ui/widget/rotateable.h
index 15e0bf71c..52fb5306c 100644
--- a/src/ui/widget/rotateable.h
+++ b/src/ui/widget/rotateable.h
@@ -31,10 +31,12 @@ public:
bool on_click(GdkEventButton *event);
bool on_motion(GdkEventMotion *event);
bool on_release(GdkEventButton *event);
+ bool on_scroll(GdkEventScroll* event);
double axis;
double current_axis;
double maxdecl;
+ bool scrolling;
private:
double drag_started_x;
@@ -47,6 +49,7 @@ private:
virtual void do_motion (double /*by*/, guint /*state*/) {}
virtual void do_release (double /*by*/, guint /*state*/) {}
+ virtual void do_scroll (double /*by*/, guint /*state*/) {}
};
} // namespace Widget
diff --git a/src/ui/widget/ruler.cpp b/src/ui/widget/ruler.cpp
deleted file mode 100644
index ecbd641a7..000000000
--- a/src/ui/widget/ruler.cpp
+++ /dev/null
@@ -1,218 +0,0 @@
-/** \file
- * Gtkmm facade/wrapper around SPRuler code that formerly lived
- * in desktop-events.cpp
- */
-/*
- * Authors:
- * Ralf Stephan <ralf@ark.in-berlin.de>
- * Lauris Kaplinski
- * Jon A. Cruz <jon@joncruz.org>
- * Abhishek Sharma
- *
- * Copyright (C) 2005 Ralf Stephan
- *
- * Released under GNU GPL, read the file 'COPYING' for more information
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <glibmm/i18n.h>
-
-#include "ui/widget/ruler.h"
-#include "widgets/ruler.h"
-#include "helper/units.h"
-
-#include "xml/repr.h"
-#include "display/sp-canvas.h"
-#include "display/guideline.h"
-#include "desktop.h"
-#include "desktop-handles.h"
-#include "document.h"
-#include "document-undo.h"
-#include "sp-namedview.h"
-#include "verbs.h"
-
-namespace Gtk {
-namespace Deprecated {
-void Ruler::set_range(double lower, double upper, double position, double max_size)
-{
-gtk_deprecated_ruler_set_range(gobj(), lower, upper, position, max_size);
-}
-
-void Ruler::get_range(double& lower, double& upper, double& position, double& max_size)
-{
-gtk_deprecated_ruler_get_range(gobj(), &(lower), &(upper), &(position), &(max_size));
-}
-}// namespace Deprecated
-}// namespace Gtk
-
-
-namespace Inkscape {
-namespace UI {
-namespace Widget {
-
-void
-Ruler::init(SPDesktop *dt, Gtk::Widget &w)
-{
- _dt = dt;
- _canvas_widget = &w;
- _dragging = false;
- _guide = 0;
- sp_ruler_set_metric(GTK_DEPRECATED_RULER(_r->gobj()), SP_PT);
- _r->set_range(-500, 500, 0, 1000);
-}
-
-void
-Ruler::get_range(double &lo, double &up, double &pos, double &max)
-{
- _r->get_range(lo, up, pos, max);
-}
-
-void
-Ruler::set_range(double lo, double up, double pos, double max)
-{
- _r->set_range(lo, up, pos, max);
-}
-
-/// Set metric from namedview
-void
-Ruler::update_metric()
-{
- if (!_dt) return;
- sp_ruler_set_metric(GTK_DEPRECATED_RULER(_r->gobj()), _dt->namedview->getDefaultMetric());
-}
-
-/// Returns text to be used for tooltip for ruler.
-/// \todo incorrect
-Glib::ustring
-Ruler::get_tip()
-{
- return gettext(sp_unit_get_plural( _dt
- ? _dt->namedview->doc_units
- : &sp_unit_get_by_id(SP_UNIT_PT) ));
-}
-
-/// Helper that gets mouse coordinates relative to canvas widget.
-void
-Ruler::canvas_get_pointer(int &x, int &y)
-{
- Gdk::ModifierType mask;
- (void) _canvas_widget->get_window()->get_pointer(x, y, mask);
-}
-
-Geom::Point
-Ruler::get_event_dt()
-{
- int wx, wy;
- canvas_get_pointer(wx, wy);
- Geom::Point const event_win(wx, wy);
- Geom::Point const event_w(sp_canvas_window_to_world(_dt->canvas, event_win));
- return _dt->w2d(event_w);
-}
-
-bool
-Ruler::on_button_press_event(GdkEventButton *evb)
-{
- g_assert(_dt);
- Geom::Point const &event_dt = get_event_dt();
- Inkscape::XML::Node *repr = _dt->namedview->getRepr();
-
- if (evb->button == 1) {
- _dragging = true;
- sp_repr_set_boolean(repr, "showguides", TRUE);
- sp_repr_set_boolean(repr, "inkscape:guide-bbox", TRUE);
- _guide = sp_guideline_new(_dt->guides, NULL, event_dt, _horiz_f ? Geom::Point(0.,1.) : Geom::Point(1.,0.));
- sp_guideline_set_color(SP_GUIDELINE(_guide), _dt->namedview->guidehicolor);
- (void) get_window()->pointer_grab(false,
- Gdk::BUTTON_RELEASE_MASK |
- Gdk::POINTER_MOTION_MASK |
- Gdk::POINTER_MOTION_HINT_MASK,
- evb->time);
- }
- return false;
-}
-
-bool
-Ruler::on_motion_notify_event(GdkEventMotion *)
-{
- g_assert(_dt);
- Geom::Point const &event_dt = get_event_dt();
-
- if (_dragging) {
- sp_guideline_set_position(SP_GUIDELINE(_guide), event_dt);
- _dt->set_coordinate_status(event_dt);
- _dt->setPosition(event_dt);
- }
- return false;
-}
-
-bool
-Ruler::on_button_release_event(GdkEventButton *evb)
-{
- g_assert(_dt);
- int wx, wy;
- canvas_get_pointer(wx, wy);
- Geom::Point const &event_dt = get_event_dt();
-
- if (_dragging && evb->button == 1) {
- Gdk::Window::pointer_ungrab(evb->time);
- gtk_object_destroy(GTK_OBJECT(_guide));
- _guide = 0;
- _dragging = false;
-
- if ( (_horiz_f ? wy : wx ) >= 0 ) {
- Inkscape::XML::Document *xml_doc = _dt->doc()->getReprDoc();
- Inkscape::XML::Node *repr = xml_doc->createElement("sodipodi:guide");
- repr->setAttribute("orientation", _horiz_f ? "horizontal" : "vertical");
- double const guide_pos_dt = event_dt[ _horiz_f ? Geom::Y : Geom::X ];
- sp_repr_set_svg_double(repr, "position", guide_pos_dt);
- _dt->namedview->getRepr()->appendChild(repr);
- Inkscape::GC::release(repr);
- DocumentUndo::done(sp_desktop_document(_dt), SP_VERB_NONE,
- /* TODO: annotate */ "ruler.cpp:157");
- }
- _dt->set_coordinate_status(event_dt);
- }
- return false;
-}
-
-//------------------------------------------------------------
-HRuler::HRuler()
-{
- _dt = 0;
- _r = static_cast<Gtk::Deprecated::HRuler*>(Glib::wrap(static_cast<GtkWidget*> (sp_hruler_new())));
- add(*_r);
- _horiz_f = true;
-}
-
-HRuler::~HRuler()
-{
-}
-
-
-VRuler::VRuler()
-{
- _dt = 0;
- _r = static_cast<Gtk::Deprecated::VRuler*>(Glib::wrap(static_cast<GtkWidget*> (sp_vruler_new())));
- add(*_r);
- _horiz_f = false;
-}
-
-VRuler::~VRuler()
-{
-}
-
-}}}
-
-/*
- Local Variables:
- mode:c++
- c-file-style:"stroustrup"
- c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
- indent-tabs-mode:nil
- fill-column:99
- End:
-*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/ui/widget/ruler.h b/src/ui/widget/ruler.h
deleted file mode 100644
index d63c585a8..000000000
--- a/src/ui/widget/ruler.h
+++ /dev/null
@@ -1,184 +0,0 @@
-#ifndef SEEN_UI_WIDGET_RULER_H
-#define SEEN_UI_WIDGET_RULER_H
-
-/*
- * Authors:
- * Ralf Stephan <ralf@ark.in-berlin.de>
- *
- * Copyright (C) 2005 The Authors
- *
- * Released under GNU GPL, read the file 'COPYING' for more information
- */
-
-#include <gtkmm/eventbox.h>
-#include <2geom/point.h>
-
-struct SPCanvasItem;
-class SPDesktop;
-namespace Glib {
- class ustring;
-}
-
-typedef struct _GtkDeprecatedRuler GtkDeprecatedRuler;
-typedef struct _GtkDeprecatedVRuler GtkDeprecatedVRuler;
-typedef struct _GtkDeprecatedHRuler GtkDeprecatedHRuler;
-
-
-// This is an import of the now-deprecated Gtk::Ruler API.
-namespace Gtk {
-namespace Deprecated {
-
-/** Base class for horizontal or vertical rulers.
- *
- * This is an abstract base for Gtk::HRuler and
- * Gtk::VRuler. Users should only instantiate those types.
- */
-class Ruler : public Widget
-{
-public:
- virtual ~Ruler();
-
-protected:
- explicit Ruler(const Glib::ConstructParams& construct_params);
- explicit Ruler(GtkDeprecatedRuler* castitem);
-
-public:
- ///Provides access to the underlying C GtkObject.
- GtkDeprecatedRuler* gobj() { return reinterpret_cast<GtkDeprecatedRuler*>(gobject_); }
-
- ///Provides access to the underlying C GtkObject.
- const GtkDeprecatedRuler* gobj() const { return reinterpret_cast<GtkDeprecatedRuler*>(gobject_); }
-
-protected:
- Ruler();
-
-public:
- /** sets the range of the ruler.
- * <i>upper</i> and <i>lower</i> arguments denote the extents of the Ruler.
- * <i>max_size</i> is the largest number displayed by the ruler.
- * <i>position</i> gives the initial value of the ruler.
- * Rulers do not have sane defaults so this function should always be called.
- */
- void set_range(double lower, double upper, double position, double max_size);
-
- /** Retrieves values indicating the range and current position of a Gtk::Ruler.
- * See set_range().
- *
- * @param lower Location to store lower limit of the ruler, or <tt>0</tt>.
- * @param upper Location to store upper limit of the ruler, or <tt>0</tt>.
- * @param position Location to store the current position of the mark on the ruler, or <tt>0</tt>.
- * @param max_size Location to store the maximum size of the ruler used when calculating
- * the space to leave for the text, or <tt>0</tt>.
- */
- void get_range(double& lower, double& upper, double& position, double& max_size);
-};
-
-
-/** Vertical Ruler */
-class VRuler : public Ruler
-{
- public:
- virtual ~VRuler();
-
-public:
- ///Provides access to the underlying C GtkObject.
- GtkDeprecatedVRuler* gobj() { return reinterpret_cast<GtkDeprecatedVRuler*>(gobject_); }
-
- ///Provides access to the underlying C GtkObject.
- const GtkDeprecatedVRuler* gobj() const { return reinterpret_cast<GtkDeprecatedVRuler*>(gobject_); }
-
-public:
- VRuler();
-}; //class VRuler
-
-/** Horizontal Ruler */
-class HRuler : public Ruler
-{
- public:
- virtual ~HRuler();
-
-public:
- ///Provides access to the underlying C GtkObject.
- GtkDeprecatedHRuler* gobj() { return reinterpret_cast<GtkDeprecatedHRuler*>(gobject_); }
-
- ///Provides access to the underlying C GtkObject.
- const GtkDeprecatedHRuler* gobj() const { return reinterpret_cast<GtkDeprecatedHRuler*>(gobject_); }
-
-public:
- HRuler();
-}; // class HRuler
-} // namespace Deprecated
-} // namespace Gtk
-
-
-
-namespace Inkscape {
-namespace UI {
-namespace Widget {
-
-/**
- * Gtkmm facade/wrapper around sp_rulers.
- */
-class Ruler : public Gtk::EventBox
-{
-public:
- void init (SPDesktop*, Gtk::Widget&);
- void get_range (double&, double&, double&, double&);
- void set_range (double, double, double, double);
- void update_metric();
- Glib::ustring get_tip();
-
-protected:
- SPDesktop *_dt;
- SPCanvasItem *_guide;
- Gtk::Widget *_canvas_widget;
- Gtk::Deprecated::Ruler *_r;
- bool _horiz_f, _dragging;
-
- virtual bool on_button_press_event (GdkEventButton *);
- virtual bool on_motion_notify_event (GdkEventMotion *);
- virtual bool on_button_release_event (GdkEventButton *);
-
-private:
- void canvas_get_pointer (int&, int&);
- Geom::Point get_event_dt();
-};
-
-/**
- * Horizontal ruler gtkmm wrapper.
- */
-class HRuler : public Ruler
-{
-public:
- HRuler();
- ~HRuler();
-};
-
-/**
- * Vertical ruler gtkmm wrapper.
- */
-class VRuler : public Ruler
-{
-public:
- VRuler();
- ~VRuler();
-};
-
-} // namespace Widget
-} // namespace UI
-} // namespace Inkscape
-
-
-#endif // SEEN_UI_WIDGET_RULER_H
-
-
-/*
- Local Variables:
- mode:c++
- c-file-style:"stroustrup"
- c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
- indent-tabs-mode:nil
- fill-column:99
- End:
-*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
diff --git a/src/ui/widget/scalar-unit.cpp b/src/ui/widget/scalar-unit.cpp
index 99ff70846..4fa1a7584 100644
--- a/src/ui/widget/scalar-unit.cpp
+++ b/src/ui/widget/scalar-unit.cpp
@@ -16,6 +16,8 @@
#include "scalar-unit.h"
#include "spinbutton.h"
+using Inkscape::Util::unit_table;
+
namespace Inkscape {
namespace UI {
namespace Widget {
@@ -100,7 +102,7 @@ void ScalarUnit::resetUnitType(UnitType unit_type)
lastUnits = _unit_menu->getUnitAbbr();
}
-Unit ScalarUnit::getUnit() const
+Unit const * ScalarUnit::getUnit() const
{
g_assert(_unit_menu != NULL);
return _unit_menu->getUnit();
@@ -226,14 +228,13 @@ void ScalarUnit::on_unit_changed()
Glib::ustring abbr = _unit_menu->getUnitAbbr();
_suffix->set_label(abbr);
- Inkscape::Util::UnitTable &table = _unit_menu->getUnitTable();
- Inkscape::Util::Unit new_unit = (table.getUnit(abbr));
- Inkscape::Util::Unit old_unit = (table.getUnit(lastUnits));
+ Inkscape::Util::Unit const *new_unit = unit_table.getUnit(abbr);
+ Inkscape::Util::Unit const *old_unit = unit_table.getUnit(lastUnits);
double convertedVal = 0;
- if (old_unit.type == UNIT_TYPE_DIMENSIONLESS && new_unit.type == UNIT_TYPE_LINEAR) {
+ if (old_unit->type == UNIT_TYPE_DIMENSIONLESS && new_unit->type == UNIT_TYPE_LINEAR) {
convertedVal = PercentageToAbsolute(Scalar::getValue());
- } else if (old_unit.type == UNIT_TYPE_LINEAR && new_unit.type == UNIT_TYPE_DIMENSIONLESS) {
+ } else if (old_unit->type == UNIT_TYPE_LINEAR && new_unit->type == UNIT_TYPE_DIMENSIONLESS) {
convertedVal = AbsoluteToPercentage(Scalar::getValue());
} else {
double conversion = _unit_menu->getConversion(lastUnits);
diff --git a/src/ui/widget/scalar-unit.h b/src/ui/widget/scalar-unit.h
index 4f22f438c..9e310d3bd 100644
--- a/src/ui/widget/scalar-unit.h
+++ b/src/ui/widget/scalar-unit.h
@@ -82,7 +82,7 @@ public:
/**
* Gets the object for the currently selected unit.
*/
- Unit getUnit() const;
+ Unit const * getUnit() const;
/**
* Gets the UnitType ID for the unit.
diff --git a/src/ui/widget/scalar.cpp b/src/ui/widget/scalar.cpp
index 9bbcc80f9..fca8a7974 100644
--- a/src/ui/widget/scalar.cpp
+++ b/src/ui/widget/scalar.cpp
@@ -142,7 +142,7 @@ void Scalar::update()
void Scalar::addSlider()
{
#if WITH_GTKMM_3_0
- Gtk::HScale *scale = new Gtk::HScale(static_cast<SpinButton*>(_widget)->get_adjustment());
+ Gtk::Scale *scale = new Gtk::Scale(static_cast<SpinButton*>(_widget)->get_adjustment());
#else
Gtk::HScale *scale = new Gtk::HScale( * static_cast<SpinButton*>(_widget)->get_adjustment() );
#endif
diff --git a/src/ui/widget/selected-style.cpp b/src/ui/widget/selected-style.cpp
index a60e3cc31..042a6614e 100644
--- a/src/ui/widget/selected-style.cpp
+++ b/src/ui/widget/selected-style.cpp
@@ -23,8 +23,9 @@
#include "desktop-handles.h"
#include "style.h"
#include "desktop-style.h"
-#include "sp-linear-gradient-fns.h"
-#include "sp-radial-gradient-fns.h"
+#include "sp-namedview.h"
+#include "sp-linear-gradient.h"
+#include "sp-radial-gradient.h"
#include "sp-pattern.h"
#include "ui/dialog/dialog-manager.h"
#include "ui/dialog/fill-and-stroke.h"
@@ -38,8 +39,7 @@
#include "sp-gradient.h"
#include "svg/svg-color.h"
#include "svg/css-ostringstream.h"
-#include "helper/units.h"
-#include "event-context.h"
+#include "ui/tools/tool-base.h"
#include "message-context.h"
#include "verbs.h"
#include "color.h"
@@ -47,7 +47,12 @@
#include "pixmaps/cursor-adj-h.xpm"
#include "pixmaps/cursor-adj-s.xpm"
#include "pixmaps/cursor-adj-l.xpm"
+#include "pixmaps/cursor-adj-a.xpm"
#include "sp-cursor.h"
+#include "gradient-chemistry.h"
+#include "util/units.h"
+
+using Inkscape::Util::unit_table;
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"};
@@ -102,7 +107,7 @@ typedef enum {
// pointers/types used need to be read-only. So until we correct the using
// code, those warnings are actually desired. They say "Hey! Fix this". We
// definitely don't want to hide/ignore them. --JonCruz
-static GtkTargetEntry ui_drop_target_entries [] = {
+static const GtkTargetEntry ui_drop_target_entries [] = {
{"application/x-color", 0, APP_X_COLOR}
};
@@ -117,8 +122,11 @@ SelectedStyle::SelectedStyle(bool /*layout*/)
current_stroke_width(0),
_desktop (NULL),
-
+#if WITH_GTKMM_3_0
+ _table(),
+#else
_table(2, 6),
+#endif
_fill_label (_("Fill:")),
_stroke_label (_("Stroke:")),
_opacity_label (_("O:")),
@@ -143,10 +151,7 @@ SelectedStyle::SelectedStyle(bool /*layout*/)
_opacity_blocked (false),
- _popup_px(_sw_group),
- _popup_pt(_sw_group),
- _popup_mm(_sw_group),
-
+ _unit_mis(NULL),
_sw_unit(NULL)
{
_drop[0] = _drop[1] = 0;
@@ -159,8 +164,13 @@ SelectedStyle::SelectedStyle(bool /*layout*/)
_opacity_label.set_alignment(0.0, 0.5);
_opacity_label.set_padding(0, 0);
+#if WITH_GTKMM_3_0
+ _table.set_column_spacing(2);
+ _table.set_row_spacing(0);
+#else
_table.set_col_spacings (2);
_table.set_row_spacings (0);
+#endif
for (int i = SS_FILL; i <= SS_STROKE; i++) {
@@ -297,34 +307,41 @@ SelectedStyle::SelectedStyle(bool /*layout*/)
}
{
- _popup_px.add(*(new Gtk::Label(_("px"), 0.0, 0.5)));
- _popup_px.signal_activate().connect(sigc::mem_fun(*this, &SelectedStyle::on_popup_px));
- _popup_sw.attach(_popup_px, 0,1, 0,1);
-
- _popup_pt.add(*(new Gtk::Label(_("pt"), 0.0, 0.5)));
- _popup_pt.signal_activate().connect(sigc::mem_fun(*this, &SelectedStyle::on_popup_pt));
- _popup_sw.attach(_popup_pt, 0,1, 1,2);
-
- _popup_mm.add(*(new Gtk::Label(_("mm"), 0.0, 0.5)));
- _popup_mm.signal_activate().connect(sigc::mem_fun(*this, &SelectedStyle::on_popup_mm));
- _popup_sw.attach(_popup_mm, 0,1, 2,3);
+ int row = 0;
+
+ Inkscape::Util::UnitTable::UnitMap m = unit_table.units(Inkscape::Util::UNIT_TYPE_LINEAR);
+ Inkscape::Util::UnitTable::UnitMap::iterator iter = m.begin();
+ while(iter != m.end()) {
+ Gtk::RadioMenuItem *mi = Gtk::manage(new Gtk::RadioMenuItem(_sw_group));
+ mi->add(*(new Gtk::Label(iter->first, 0.0, 0.5)));
+ _unit_mis = g_slist_append(_unit_mis, mi);
+ Inkscape::Util::Unit const *u = unit_table.getUnit(iter->first);
+ mi->signal_activate().connect(sigc::bind<Inkscape::Util::Unit const *>(sigc::mem_fun(*this, &SelectedStyle::on_popup_units), u));
+ _popup_sw.attach(*mi, 0,1, row, row+1);
+ row++;
+ ++iter;
+ }
- _popup_sw.attach(*(new Gtk::SeparatorMenuItem()), 0,1, 3,4);
+ _popup_sw.attach(*(new Gtk::SeparatorMenuItem()), 0,1, row, row+1);
+ row++;
for (guint i = 0; i < G_N_ELEMENTS(_sw_presets_str); ++i) {
Gtk::MenuItem *mi = Gtk::manage(new Gtk::MenuItem());
mi->add(*(new Gtk::Label(_sw_presets_str[i], 0.0, 0.5)));
mi->signal_activate().connect(sigc::bind<int>(sigc::mem_fun(*this, &SelectedStyle::on_popup_preset), i));
- _popup_sw.attach(*mi, 0,1, 4+i, 5+i);
+ _popup_sw.attach(*mi, 0,1, row, row+1);
+ row++;
}
- guint i = G_N_ELEMENTS(_sw_presets_str) + 5;
-
- _popup_sw.attach(*(new Gtk::SeparatorMenuItem()), 0,1, i,i+1);
+ _popup_sw.attach(*(new Gtk::SeparatorMenuItem()), 0,1, row, row+1);
+ row++;
_popup_sw_remove.add(*(new Gtk::Label(_("Remove"), 0.0, 0.5)));
_popup_sw_remove.signal_activate().connect(sigc::mem_fun(*this, &SelectedStyle::on_stroke_remove));
- _popup_sw.attach(_popup_sw_remove, 0,1, i+1,i+2);
+ _popup_sw.attach(_popup_sw_remove, 0,1, row, row+1);
+ row++;
+
+ sp_set_font_size_smaller (GTK_WIDGET(_popup_sw.gobj()));
_popup_sw.show_all();
}
@@ -333,9 +350,14 @@ SelectedStyle::SelectedStyle(bool /*layout*/)
_stroke_place.signal_button_release_event().connect(sigc::mem_fun(*this, &SelectedStyle::on_stroke_click));
_opacity_place.signal_button_press_event().connect(sigc::mem_fun(*this, &SelectedStyle::on_opacity_click));
_stroke_width_place.signal_button_press_event().connect(sigc::mem_fun(*this, &SelectedStyle::on_sw_click));
+ _stroke_width_place.signal_button_release_event().connect(sigc::mem_fun(*this, &SelectedStyle::on_sw_click));
+
_opacity_sb.signal_populate_popup().connect(sigc::mem_fun(*this, &SelectedStyle::on_opacity_menu));
_opacity_sb.signal_value_changed().connect(sigc::mem_fun(*this, &SelectedStyle::on_opacity_changed));
+ // Connect to key-press to ensure focus is consistent with other spin buttons when using the keys vs mouse-click
+ g_signal_connect (G_OBJECT (_opacity_sb.gobj()), "key-press-event", G_CALLBACK (spinbutton_keypress), _opacity_sb.gobj());
+ g_signal_connect (G_OBJECT (_opacity_sb.gobj()), "focus-in-event", G_CALLBACK (spinbutton_focus_in), _opacity_sb.gobj());
_fill_place.add(_na[SS_FILL]);
_fill_place.set_tooltip_text(__na[SS_FILL]);
@@ -352,6 +374,16 @@ SelectedStyle::SelectedStyle(bool /*layout*/)
_opacity_sb.set_size_request (SELECTED_STYLE_SB_WIDTH, -1);
_opacity_sb.set_sensitive (false);
+#if WITH_GTKMM_3_0
+ _table.attach(_fill_label, 0, 0, 1, 1);
+ _table.attach(_stroke_label, 0, 1, 1, 1);
+
+ _table.attach(_fill_flag_place, 1, 0, 1, 1);
+ _table.attach(_stroke_flag_place, 1, 1, 1, 1);
+
+ _table.attach(_fill_place, 2, 0, 1, 1);
+ _table.attach(_stroke, 2, 1, 1, 1);
+#else
_table.attach(_fill_label, 0,1, 0,1, Gtk::FILL, Gtk::SHRINK);
_table.attach(_stroke_label, 0,1, 1,2, Gtk::FILL, Gtk::SHRINK);
@@ -360,10 +392,17 @@ SelectedStyle::SelectedStyle(bool /*layout*/)
_table.attach(_fill_place, 2,3, 0,1);
_table.attach(_stroke, 2,3, 1,2);
+#endif
_opacity_place.add(_opacity_label);
+
+#if WITH_GTKMM_3_0
+ _table.attach(_opacity_place, 4, 0, 1, 2);
+ _table.attach(_opacity_sb, 5, 0, 1, 2);
+#else
_table.attach(_opacity_place, 4,5, 0,2, Gtk::SHRINK, Gtk::SHRINK);
_table.attach(_opacity_sb, 5,6, 0,2, Gtk::SHRINK, Gtk::SHRINK);
+#endif
pack_start(_table, true, true, 2);
@@ -442,7 +481,17 @@ SelectedStyle::setDesktop(SPDesktop *desktop)
this )
));
- //_sw_unit = (SPUnit *) sp_desktop_namedview(desktop)->doc_units;
+ _sw_unit = sp_desktop_namedview(desktop)->doc_units;
+
+ // Set the doc default unit active in the units list
+ gint length = g_slist_length(_unit_mis);
+ for (int i = 0; i < length; i++) {
+ Gtk::RadioMenuItem *mi = (Gtk::RadioMenuItem *) g_slist_nth_data(_unit_mis, i);
+ if (mi && mi->get_label() == _sw_unit->abbr) {
+ mi->set_active();
+ break;
+ }
+ }
}
void SelectedStyle::dragDataReceived( GtkWidget */*widget*/,
@@ -594,6 +643,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(
@@ -614,6 +669,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(
@@ -872,16 +931,8 @@ SelectedStyle::on_opacity_click(GdkEventButton *event)
return false;
}
-void SelectedStyle::on_popup_px() {
- _sw_unit = (SPUnit *) &(sp_unit_get_by_id(SP_UNIT_PX));
- update();
-}
-void SelectedStyle::on_popup_pt() {
- _sw_unit = (SPUnit *) &(sp_unit_get_by_id(SP_UNIT_PT));
- update();
-}
-void SelectedStyle::on_popup_mm() {
- _sw_unit = (SPUnit *) &(sp_unit_get_by_id(SP_UNIT_MM));
+void SelectedStyle::on_popup_units(Inkscape::Util::Unit const *unit) {
+ _sw_unit = unit;
update();
}
@@ -889,7 +940,7 @@ void SelectedStyle::on_popup_preset(int i) {
SPCSSAttr *css = sp_repr_css_attr_new ();
gdouble w;
if (_sw_unit) {
- w = sp_units_get_pixels (_sw_presets[i], *_sw_unit);
+ w = Inkscape::Util::Quantity::convert(_sw_presets[i], _sw_unit, "px");
} else {
w = _sw_presets[i];
}
@@ -967,13 +1018,13 @@ SelectedStyle::update()
if (SP_IS_LINEARGRADIENT (server)) {
SPGradient *vector = SP_GRADIENT(server)->getVector();
- sp_gradient_image_set_gradient ((SPGradientImage *) _gradient_preview_l[i], vector);
+ sp_gradient_image_set_gradient(SP_GRADIENT_IMAGE(_gradient_preview_l[i]), vector);
place->add(_gradient_box_l[i]);
place->set_tooltip_text(__lgradient[i]);
_mode[i] = SS_LGRADIENT;
} else if (SP_IS_RADIALGRADIENT (server)) {
SPGradient *vector = SP_GRADIENT(server)->getVector();
- sp_gradient_image_set_gradient ((SPGradientImage *) _gradient_preview_r[i], vector);
+ sp_gradient_image_set_gradient(SP_GRADIENT_IMAGE(_gradient_preview_r[i]), vector);
place->add(_gradient_box_r[i]);
place->set_tooltip_text(__rgradient[i]);
_mode[i] = SS_RGRADIENT;
@@ -989,7 +1040,7 @@ SelectedStyle::update()
guint32 color = paint->value.color.toRGBA32(
SP_SCALE24_TO_FLOAT ((i == SS_FILL)? query->fill_opacity.value : query->stroke_opacity.value));
_lastselected[i] = _thisselected[i];
- _thisselected[i] = color | 0xff; // only color, opacity === 1
+ _thisselected[i] = color; // include opacity
((Inkscape::UI::Widget::ColorPreview*)_color_preview[i])->setRgba32 (color);
_color_preview[i]->show_all();
place->add(*_color_preview[i]);
@@ -1068,7 +1119,7 @@ SelectedStyle::update()
{
double w;
if (_sw_unit) {
- w = sp_pixels_get_units(query->stroke_width.computed, *_sw_unit);
+ w = Inkscape::Util::Quantity::convert(query->stroke_width.computed, "px", _sw_unit);
} else {
w = query->stroke_width.computed;
}
@@ -1082,7 +1133,7 @@ SelectedStyle::update()
{
gchar *str = g_strdup_printf(_("Stroke width: %.5g%s%s"),
w,
- _sw_unit? sp_unit_get_abbreviation(_sw_unit) : "px",
+ _sw_unit? _sw_unit->abbr.c_str() : "px",
(result_sw == QUERY_STYLE_MULTIPLE_AVERAGED)?
_(" (averaged)") : "");
_stroke_width_place.set_tooltip_text(str);
@@ -1192,39 +1243,48 @@ RotateableSwatch::~RotateableSwatch() {
}
double
-RotateableSwatch::color_adjust(float *hsl, double by, guint32 cc, guint modifier)
+RotateableSwatch::color_adjust(float *hsla, double by, guint32 cc, guint modifier)
{
- sp_color_rgb_to_hsl_floatv (hsl, SP_RGBA32_R_F(cc), SP_RGBA32_G_F(cc), SP_RGBA32_B_F(cc));
-
+ sp_color_rgb_to_hsl_floatv (hsla, SP_RGBA32_R_F(cc), SP_RGBA32_G_F(cc), SP_RGBA32_B_F(cc));
+ hsla[3] = SP_RGBA32_A_F(cc);
double diff = 0;
if (modifier == 2) { // saturation
- double old = hsl[1];
+ double old = hsla[1];
if (by > 0) {
- hsl[1] += by * (1 - hsl[1]);
+ hsla[1] += by * (1 - hsla[1]);
} else {
- hsl[1] += by * (hsl[1]);
+ hsla[1] += by * (hsla[1]);
}
- diff = hsl[1] - old;
+ diff = hsla[1] - old;
} else if (modifier == 1) { // lightness
- double old = hsl[2];
+ double old = hsla[2];
if (by > 0) {
- hsl[2] += by * (1 - hsl[2]);
+ hsla[2] += by * (1 - hsla[2]);
} else {
- hsl[2] += by * (hsl[2]);
+ hsla[2] += by * (hsla[2]);
}
- diff = hsl[2] - old;
+ diff = hsla[2] - old;
+ } else if (modifier == 3) { // alpha
+ double old = hsla[3];
+ hsla[3] += by/2;
+ if (hsla[3] < 0) {
+ hsla[3] = 0;
+ } else if (hsla[3] > 1) {
+ hsla[3] = 1;
+ }
+ diff = hsla[3] - old;
} else { // hue
- double old = hsl[0];
- hsl[0] += by/2;
- while (hsl[0] < 0)
- hsl[0] += 1;
- while (hsl[0] > 1)
- hsl[0] -= 1;
- diff = hsl[0] - old;
+ double old = hsla[0];
+ hsla[0] += by/2;
+ while (hsla[0] < 0)
+ hsla[0] += 1;
+ while (hsla[0] > 1)
+ hsla[0] -= 1;
+ diff = hsla[0] - old;
}
float rgb[3];
- sp_color_hsl_to_rgb_floatv (rgb, hsl[0], hsl[1], hsl[2]);
+ sp_color_hsl_to_rgb_floatv (rgb, hsla[0], hsla[1], hsla[2]);
gchar c[64];
sp_svg_write_color (c, sizeof(c),
@@ -1237,10 +1297,14 @@ RotateableSwatch::color_adjust(float *hsl, double by, guint32 cc, guint modifier
);
SPCSSAttr *css = sp_repr_css_attr_new ();
- if (fillstroke == SS_FILL)
- sp_repr_css_set_property (css, "fill", c);
- else
- sp_repr_css_set_property (css, "stroke", c);
+
+ if (modifier == 3) { // alpha
+ Inkscape::CSSOStringStream osalpha;
+ osalpha << hsla[3];
+ sp_repr_css_set_property(css, (fillstroke == SS_FILL) ? "fill-opacity" : "stroke-opacity", osalpha.str().c_str());
+ } else {
+ sp_repr_css_set_property (css, (fillstroke == SS_FILL) ? "fill" : "stroke", c);
+ }
sp_desktop_set_style (parent->getDesktop(), css);
sp_repr_css_attr_unref (css);
return diff;
@@ -1251,32 +1315,31 @@ RotateableSwatch::do_motion(double by, guint modifier) {
if (parent->_mode[fillstroke] != SS_COLOR)
return;
- if (!cr_set && modifier != 3) {
+ if (!scrolling && !cr_set) {
GtkWidget *w = GTK_WIDGET(gobj());
+ GdkPixbuf *pixbuf = NULL;
- GdkBitmap *bitmap = NULL;
- GdkBitmap *mask = NULL;
if (modifier == 2) { // saturation
- sp_cursor_bitmap_and_mask_from_xpm(&bitmap, &mask, cursor_adj_s_xpm);
+ pixbuf = gdk_pixbuf_new_from_xpm_data((const gchar **)cursor_adj_s_xpm);
} else if (modifier == 1) { // lightness
- sp_cursor_bitmap_and_mask_from_xpm(&bitmap, &mask, cursor_adj_l_xpm);
+ pixbuf = gdk_pixbuf_new_from_xpm_data((const gchar **)cursor_adj_l_xpm);
+ } else if (modifier == 3) { // alpha
+ pixbuf = gdk_pixbuf_new_from_xpm_data((const gchar **)cursor_adj_a_xpm);
} else { // hue
- sp_cursor_bitmap_and_mask_from_xpm(&bitmap, &mask, cursor_adj_h_xpm);
+ pixbuf = gdk_pixbuf_new_from_xpm_data((const gchar **)cursor_adj_h_xpm);
}
- if ((bitmap != NULL) && (mask != NULL)) {
- GtkStyle *style = gtk_widget_get_style(w);
- cr = gdk_cursor_new_from_pixmap(bitmap, mask,
- &style->black,
- &style->white,
- 16, 16);
- g_object_unref (bitmap);
- g_object_unref (mask);
+
+ if (pixbuf != NULL) {
+ cr = gdk_cursor_new_from_pixbuf(gdk_display_get_default(), pixbuf, 16, 16);
+
+ g_object_unref(pixbuf);
gdk_window_set_cursor(gtk_widget_get_window(w), cr);
#if GTK_CHECK_VERSION(3,0,0)
g_object_unref(cr);
#else
gdk_cursor_unref(cr);
#endif
+ cr = NULL;
cr_set = true;
}
}
@@ -1289,43 +1352,51 @@ RotateableSwatch::do_motion(double by, guint modifier) {
cc = startcolor;
}
- float hsl[3];
+ float hsla[4];
double diff = 0;
- if (modifier != 3) {
- diff = color_adjust(hsl, by, cc, modifier);
- }
- if (modifier == 3) { // Alt, do nothing
+ diff = color_adjust(hsla, by, cc, modifier);
+
+ if (modifier == 3) { // alpha
+ DocumentUndo::maybeDone(sp_desktop_document(parent->getDesktop()), undokey,
+ SP_VERB_DIALOG_FILL_STROKE, (_("Adjust alpha")));
+ double ch = hsla[3];
+ parent->getDesktop()->event_context->message_context->setF(Inkscape::IMMEDIATE_MESSAGE, _("Adjusting <b>alpha</b>: was %.3g, now <b>%.3g</b> (diff %.3g); with <b>Ctrl</b> to adjust lightness, with <b>Shift</b> to adjust saturation, without modifiers to adjust hue"), ch - diff, ch, diff);
} else if (modifier == 2) { // saturation
DocumentUndo::maybeDone(sp_desktop_document(parent->getDesktop()), undokey,
SP_VERB_DIALOG_FILL_STROKE, (_("Adjust saturation")));
- double ch = hsl[1];
- parent->getDesktop()->event_context->_message_context->setF(Inkscape::IMMEDIATE_MESSAGE, _("Adjusting <b>saturation</b>: was %.3g, now <b>%.3g</b> (diff %.3g); with <b>Ctrl</b> to adjust lightness, without modifiers to adjust hue"), ch - diff, ch, diff);
+ double ch = hsla[1];
+ parent->getDesktop()->event_context->message_context->setF(Inkscape::IMMEDIATE_MESSAGE, _("Adjusting <b>saturation</b>: was %.3g, now <b>%.3g</b> (diff %.3g); with <b>Ctrl</b> to adjust lightness, with <b>Alt</b> to adjust alpha, without modifiers to adjust hue"), ch - diff, ch, diff);
} else if (modifier == 1) { // lightness
DocumentUndo::maybeDone(sp_desktop_document(parent->getDesktop()), undokey,
SP_VERB_DIALOG_FILL_STROKE, (_("Adjust lightness")));
- double ch = hsl[2];
- parent->getDesktop()->event_context->_message_context->setF(Inkscape::IMMEDIATE_MESSAGE, _("Adjusting <b>lightness</b>: was %.3g, now <b>%.3g</b> (diff %.3g); with <b>Shift</b> to adjust saturation, without modifiers to adjust hue"), ch - diff, ch, diff);
+ double ch = hsla[2];
+ parent->getDesktop()->event_context->message_context->setF(Inkscape::IMMEDIATE_MESSAGE, _("Adjusting <b>lightness</b>: was %.3g, now <b>%.3g</b> (diff %.3g); with <b>Shift</b> to adjust saturation, with <b>Alt</b> to adjust alpha, without modifiers to adjust hue"), ch - diff, ch, diff);
} else { // hue
DocumentUndo::maybeDone(sp_desktop_document(parent->getDesktop()), undokey,
SP_VERB_DIALOG_FILL_STROKE, (_("Adjust hue")));
- double ch = hsl[0];
- parent->getDesktop()->event_context->_message_context->setF(Inkscape::IMMEDIATE_MESSAGE, _("Adjusting <b>hue</b>: was %.3g, now <b>%.3g</b> (diff %.3g); with <b>Shift</b> to adjust saturation, with <b>Ctrl</b> to adjust lightness"), ch - diff, ch, diff);
+ double ch = hsla[0];
+ parent->getDesktop()->event_context->message_context->setF(Inkscape::IMMEDIATE_MESSAGE, _("Adjusting <b>hue</b>: was %.3g, now <b>%.3g</b> (diff %.3g); with <b>Shift</b> to adjust saturation, with <b>Alt</b> to adjust alpha, with <b>Ctrl</b> to adjust lightness"), ch - diff, ch, diff);
}
}
+
+void
+RotateableSwatch::do_scroll(double by, guint modifier) {
+ do_motion(by/30.0, modifier);
+ do_release(by/30.0, modifier);
+}
+
void
RotateableSwatch::do_release(double by, guint modifier) {
if (parent->_mode[fillstroke] != SS_COLOR)
return;
- float hsl[3];
- if (modifier != 3) {
- color_adjust(hsl, by, startcolor, modifier);
- }
+ float hsla[4];
+ color_adjust(hsla, by, startcolor, modifier);
if (cr_set) {
GtkWidget *w = GTK_WIDGET(gobj());
@@ -1341,7 +1412,9 @@ RotateableSwatch::do_release(double by, guint modifier) {
cr_set = false;
}
- if (modifier == 3) { // Alt, do nothing
+ if (modifier == 3) { // alpha
+ DocumentUndo::maybeDone(sp_desktop_document(parent->getDesktop()), undokey,
+ SP_VERB_DIALOG_FILL_STROKE, ("Adjust alpha"));
} else if (modifier == 2) { // saturation
DocumentUndo::maybeDone(sp_desktop_document(parent->getDesktop()), undokey,
SP_VERB_DIALOG_FILL_STROKE, ("Adjust saturation"));
@@ -1361,7 +1434,7 @@ RotateableSwatch::do_release(double by, guint modifier) {
undokey = "ssrot1";
}
- parent->getDesktop()->event_context->_message_context->clear();
+ parent->getDesktop()->event_context->message_context->clear();
startcolor_set = false;
}
@@ -1371,9 +1444,7 @@ RotateableStrokeWidth::RotateableStrokeWidth(SelectedStyle *parent) :
parent(parent),
startvalue(0),
startvalue_set(false),
- undokey("swrot1"),
- cr(0),
- cr_set(false)
+ undokey("swrot1")
{
}
@@ -1427,7 +1498,7 @@ RotateableStrokeWidth::do_motion(double by, guint modifier) {
double diff = value_adjust(startvalue, by, modifier, false);
DocumentUndo::maybeDone(sp_desktop_document(parent->getDesktop()), undokey,
SP_VERB_DIALOG_FILL_STROKE, (_("Adjust stroke width")));
- parent->getDesktop()->event_context->_message_context->setF(Inkscape::IMMEDIATE_MESSAGE, _("Adjusting <b>stroke width</b>: was %.3g, now <b>%.3g</b> (diff %.3g)"), startvalue, startvalue + diff, diff);
+ parent->getDesktop()->event_context->message_context->setF(Inkscape::IMMEDIATE_MESSAGE, _("Adjusting <b>stroke width</b>: was %.3g, now <b>%.3g</b> (diff %.3g)"), startvalue, startvalue + diff, diff);
}
}
@@ -1448,9 +1519,14 @@ RotateableStrokeWidth::do_release(double by, guint modifier) {
} else {
undokey = "swrot1";
}
- parent->getDesktop()->event_context->_message_context->clear();
+ parent->getDesktop()->event_context->message_context->clear();
}
+void
+RotateableStrokeWidth::do_scroll(double by, guint modifier) {
+ do_motion(by/10.0, modifier);
+ startvalue_set = false;
+}
Dialog::FillAndStroke *get_fill_and_stroke_panel(SPDesktop *desktop)
{
diff --git a/src/ui/widget/selected-style.h b/src/ui/widget/selected-style.h
index 542983b53..9557a8d74 100644
--- a/src/ui/widget/selected-style.h
+++ b/src/ui/widget/selected-style.h
@@ -11,8 +11,22 @@
#ifndef INKSCAPE_UI_CURRENT_STYLE_H
#define INKSCAPE_UI_CURRENT_STYLE_H
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H
+#include <glibmm/threads.h>
+#endif
+
#include <gtkmm/box.h>
-#include <gtkmm/table.h>
+
+#if WITH_GTKMM_3_0
+# include <gtkmm/grid.h>
+#else
+# include <gtkmm/table.h>
+#endif
+
#include <gtkmm/label.h>
#include <gtkmm/eventbox.h>
#include <gtkmm/enums.h>
@@ -29,9 +43,13 @@
#include "rotateable.h"
class SPDesktop;
-class SPUnit;
namespace Inkscape {
+
+namespace Util {
+ class Unit;
+}
+
namespace UI {
namespace Widget {
@@ -60,8 +78,10 @@ public:
~RotateableSwatch();
double color_adjust (float *hsl, double by, guint32 cc, guint state);
+
virtual void do_motion (double by, guint state);
virtual void do_release (double by, guint state);
+ virtual void do_scroll (double by, guint state);
private:
guint fillstroke;
@@ -86,6 +106,7 @@ public:
double value_adjust(double current, double by, guint modifier, bool final);
virtual void do_motion (double by, guint state);
virtual void do_release (double by, guint state);
+ virtual void do_scroll (double by, guint state);
private:
SelectedStyle *parent;
@@ -94,9 +115,6 @@ private:
bool startvalue_set;
gchar const *undokey;
-
- GdkCursor *cr;
- bool cr_set;
};
/**
@@ -123,7 +141,11 @@ public:
protected:
SPDesktop *_desktop;
+#if WITH_GTKMM_3_0
+ Gtk::Grid _table;
+#else
Gtk::Table _table;
+#endif
Gtk::Label _fill_label;
Gtk::Label _stroke_label;
@@ -250,16 +272,12 @@ protected:
Gtk::Menu _popup_sw;
Gtk::RadioButtonGroup _sw_group;
- Gtk::RadioMenuItem _popup_px;
- void on_popup_px();
- Gtk::RadioMenuItem _popup_pt;
- void on_popup_pt();
- Gtk::RadioMenuItem _popup_mm;
- void on_popup_mm();
+ GSList *_unit_mis;
+ void on_popup_units(Inkscape::Util::Unit const *u);
void on_popup_preset(int i);
Gtk::MenuItem _popup_sw_remove;
- SPUnit *_sw_unit;
+ Inkscape::Util::Unit const *_sw_unit; /// points to object in UnitTable, do not delete
void *_drop[2];
bool _dropEnabled[2];
diff --git a/src/ui/widget/spin-scale.cpp b/src/ui/widget/spin-scale.cpp
new file mode 100644
index 000000000..ade3d1e60
--- /dev/null
+++ b/src/ui/widget/spin-scale.cpp
@@ -0,0 +1,247 @@
+/*
+ * Author:
+ *
+ * Copyright (C) 2012 Author
+ *
+ * Released under GNU GPL. Read the file 'COPYING' for more information.
+ */
+
+#include "spin-scale.h"
+
+#include <gtkmm/adjustment.h>
+#include <glibmm/i18n.h>
+#include <glibmm/stringutils.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..5fec8b1d8
--- /dev/null
+++ b/src/ui/widget/spin-scale.h
@@ -0,0 +1,125 @@
+/*
+ * 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
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H
+#include <glibmm/threads.h>
+#endif
+
+#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..1cb59a7b3 100644
--- a/src/ui/widget/spin-slider.cpp
+++ b/src/ui/widget/spin-slider.cpp
@@ -8,12 +8,11 @@
* Released under GNU GPL. Read the file 'COPYING' for more information.
*/
-#include <glib.h>
+#include "spin-slider.h"
+
#include <glibmm/i18n.h>
#include <glibmm/stringutils.h>
-#include "spin-slider.h"
-
namespace Inkscape {
namespace UI {
namespace Widget {
@@ -116,11 +115,20 @@ Gtk::Adjustment& SpinSlider::get_adjustment()
return _adjustment;
}
+#if WITH_GTKMM_3_0
+const Gtk::Scale& SpinSlider::get_scale() const
+#else
const Gtk::HScale& SpinSlider::get_scale() const
+#endif
{
return _scale;
}
+
+#if WITH_GTKMM_3_0
+Gtk::Scale& SpinSlider::get_scale()
+#else
Gtk::HScale& SpinSlider::get_scale()
+#endif
{
return _scale;
}
@@ -186,7 +194,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/spin-slider.h b/src/ui/widget/spin-slider.h
index f4a62107b..5f86fd15a 100644
--- a/src/ui/widget/spin-slider.h
+++ b/src/ui/widget/spin-slider.h
@@ -10,6 +10,14 @@
#ifndef INKSCAPE_UI_WIDGET_SPIN_SLIDER_H
#define INKSCAPE_UI_WIDGET_SPIN_SLIDER_H
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H
+#include <glibmm/threads.h>
+#endif
+
#include <gtkmm/adjustment.h>
#include <gtkmm/box.h>
#include <gtkmm/scale.h>
@@ -41,13 +49,14 @@ public:
#if WITH_GTKMM_3_0
const Glib::RefPtr<Gtk::Adjustment> get_adjustment() const;
Glib::RefPtr<Gtk::Adjustment> get_adjustment();
+ const Gtk::Scale& get_scale() const;
+ Gtk::Scale& get_scale();
#else
const Gtk::Adjustment& get_adjustment() const;
Gtk::Adjustment& get_adjustment();
-#endif
-
const Gtk::HScale& get_scale() const;
Gtk::HScale& get_scale();
+#endif
const Inkscape::UI::Widget::SpinButton& get_spin_button() const;
Inkscape::UI::Widget::SpinButton& get_spin_button();
@@ -57,10 +66,11 @@ public:
private:
#if WITH_GTKMM_3_0
Glib::RefPtr<Gtk::Adjustment> _adjustment;
+ Gtk::Scale _scale;
#else
Gtk::Adjustment _adjustment;
-#endif
Gtk::HScale _scale;
+#endif
Inkscape::UI::Widget::SpinButton _spin;
};
diff --git a/src/ui/widget/spinbutton.cpp b/src/ui/widget/spinbutton.cpp
index 7d6479923..7709a837b 100644
--- a/src/ui/widget/spinbutton.cpp
+++ b/src/ui/widget/spinbutton.cpp
@@ -14,12 +14,9 @@
#include "spinbutton.h"
#include "unit-menu.h"
+#include "unit-tracker.h"
#include "util/expression-evaluator.h"
-#include "event-context.h"
-
-#if !GTK_CHECK_VERSION(2,22,0)
-#include "compat-key-syms.h"
-#endif
+#include "ui/tools/tool-base.h"
namespace Inkscape {
namespace UI {
@@ -36,16 +33,23 @@ SpinButton::connect_signals() {
int SpinButton::on_input(double* newvalue)
{
try {
- Inkscape::Util::GimpEevlQuantity result;
- if (_unit_menu) {
- Unit unit = _unit_menu->getUnit();
- result = Inkscape::Util::gimp_eevl_evaluate (get_text().c_str(), &unit);
+ Inkscape::Util::EvaluatorQuantity result;
+ if (_unit_menu || _unit_tracker) {
+ Unit const *unit = NULL;
+ if (_unit_menu) {
+ unit = _unit_menu->getUnit();
+ } else {
+ unit = _unit_tracker->getActiveUnit();
+ }
+ Inkscape::Util::ExpressionEvaluator eval = Inkscape::Util::ExpressionEvaluator(get_text().c_str(), unit);
+ result = eval.evaluate();
// check if output dimension corresponds to input unit
- if (result.dimension != (unit.isAbsolute() ? 1 : 0) ) {
+ if (result.dimension != (unit->isAbsolute() ? 1 : 0) ) {
throw Inkscape::Util::EvaluatorException("Input dimensions do not match with parameter dimensions.","");
}
} else {
- result = Inkscape::Util::gimp_eevl_evaluate (get_text().c_str(), NULL);
+ Inkscape::Util::ExpressionEvaluator eval = Inkscape::Util::ExpressionEvaluator(get_text().c_str(), NULL);
+ result = eval.evaluate();
}
*newvalue = result.value;
@@ -61,13 +65,13 @@ int SpinButton::on_input(double* newvalue)
bool SpinButton::on_my_focus_in_event(GdkEventFocus* /*event*/)
{
- on_focus_in_value = get_value();
+ _on_focus_in_value = get_value();
return false; // do not consume the event
}
bool SpinButton::on_my_key_press_event(GdkEventKey* event)
{
- switch (get_group0_keyval (event)) {
+ switch (Inkscape::UI::Tools::get_group0_keyval (event)) {
case GDK_KEY_Escape:
undo();
return true; // I consumed the event
@@ -88,7 +92,7 @@ bool SpinButton::on_my_key_press_event(GdkEventKey* event)
void SpinButton::undo()
{
- set_value(on_focus_in_value);
+ set_value(_on_focus_in_value);
}
diff --git a/src/ui/widget/spinbutton.h b/src/ui/widget/spinbutton.h
index 57c48369e..812b5f515 100644
--- a/src/ui/widget/spinbutton.h
+++ b/src/ui/widget/spinbutton.h
@@ -10,6 +10,14 @@
#ifndef INKSCAPE_UI_WIDGET_SPINBUTTON_H
#define INKSCAPE_UI_WIDGET_SPINBUTTON_H
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H
+#include <glibmm/threads.h>
+#endif
+
#include <gtkmm/spinbutton.h>
namespace Inkscape {
@@ -17,6 +25,7 @@ namespace UI {
namespace Widget {
class UnitMenu;
+class UnitTracker;
/**
* SpinButton widget, that allows entry of simple math expressions (also units, when linked with UnitMenu),
@@ -29,7 +38,9 @@ class SpinButton : public Gtk::SpinButton
public:
SpinButton(double climb_rate = 0.0, guint digits = 0)
: Gtk::SpinButton(climb_rate, digits),
- _unit_menu(NULL)
+ _unit_menu(NULL),
+ _unit_tracker(NULL),
+ _on_focus_in_value(0.)
{
connect_signals();
};
@@ -39,7 +50,9 @@ public:
explicit SpinButton(Gtk::Adjustment& adjustment, double climb_rate = 0.0, guint digits = 0)
#endif
: Gtk::SpinButton(adjustment, climb_rate, digits),
- _unit_menu(NULL)
+ _unit_menu(NULL),
+ _unit_tracker(NULL),
+ _on_focus_in_value(0.)
{
connect_signals();
};
@@ -47,9 +60,13 @@ public:
virtual ~SpinButton() {};
void setUnitMenu(UnitMenu* unit_menu) { _unit_menu = unit_menu; };
+
+ void addUnitTracker(UnitTracker* ut) { _unit_tracker = ut; };
protected:
UnitMenu *_unit_menu; /// Linked unit menu for unit conversion in entered expressions.
+ UnitTracker *_unit_tracker; // Linked unit tracker for unit conversion in entered expressions.
+ double _on_focus_in_value;
void connect_signals();
@@ -82,8 +99,6 @@ protected:
*/
void undo();
- double on_focus_in_value;
-
private:
// noncopyable
SpinButton(const SpinButton&);
diff --git a/src/ui/widget/style-subject.h b/src/ui/widget/style-subject.h
index 47da91732..c2941d995 100644
--- a/src/ui/widget/style-subject.h
+++ b/src/ui/widget/style-subject.h
@@ -20,7 +20,7 @@
class SPDesktop;
class SPObject;
class SPCSSAttr;
-class SPStyle;
+struct SPStyle;
namespace Inkscape {
class Selection;
diff --git a/src/ui/widget/style-swatch.cpp b/src/ui/widget/style-swatch.cpp
index 1ee26e803..a33c1d09f 100644
--- a/src/ui/widget/style-swatch.cpp
+++ b/src/ui/widget/style-swatch.cpp
@@ -11,31 +11,35 @@
* Released under GNU GPL. Read the file 'COPYING' for more information.
*/
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
+#include "style-swatch.h"
#include <cstring>
#include <string>
-#include "style-swatch.h"
-
#include "widgets/spw-utilities.h"
#include "ui/widget/color-preview.h"
#include "style.h"
-#include "sp-linear-gradient-fns.h"
-#include "sp-radial-gradient-fns.h"
+#include "sp-linear-gradient.h"
+#include "sp-radial-gradient.h"
#include "sp-pattern.h"
#include "xml/repr.h"
+#include "xml/sp-css-attr.h"
#include "widgets/widget-sizes.h"
-#include "helper/units.h"
+#include "util/units.h"
#include "helper/action.h"
+#include "helper/action-context.h"
#include "preferences.h"
#include "inkscape.h"
#include "verbs.h"
#include <glibmm/i18n.h>
+#if WITH_GTKMM_3_0
+# include <gtkmm/grid.h>
+#else
+# include <gtkmm/table.h>
+#endif
+
enum {
SS_FILL,
SS_STROKE
@@ -113,7 +117,11 @@ StyleSwatch::StyleSwatch(SPCSSAttr *css, gchar const *main_tip)
_css(NULL),
_tool_obs(NULL),
_style_obs(NULL),
- _table(2, 6),
+#if WITH_GTKMM_3_0
+ _table(Gtk::manage(new Gtk::Grid())),
+#else
+ _table(Gtk::manage(new Gtk::Table(2, 6))),
+#endif
_sw_unit(NULL)
{
_label[SS_FILL].set_markup(_("Fill:"));
@@ -129,23 +137,35 @@ StyleSwatch::StyleSwatch(SPCSSAttr *css, gchar const *main_tip)
_opacity_value.set_alignment(0.0, 0.5);
_opacity_value.set_padding(0, 0);
- _table.set_col_spacings (2);
- _table.set_row_spacings (0);
+#if WITH_GTKMM_3_0
+ _table->set_column_spacing(2);
+ _table->set_row_spacing(0);
+#else
+ _table->set_col_spacings(2);
+ _table->set_row_spacings(0);
+#endif
_stroke.pack_start(_place[SS_STROKE]);
_stroke_width_place.add(_stroke_width);
_stroke.pack_start(_stroke_width_place, Gtk::PACK_SHRINK);
-
- _table.attach(_label[SS_FILL], 0,1, 0,1, Gtk::FILL, Gtk::SHRINK);
- _table.attach(_label[SS_STROKE], 0,1, 1,2, Gtk::FILL, Gtk::SHRINK);
-
- _table.attach(_place[SS_FILL], 1,2, 0,1);
- _table.attach(_stroke, 1,2, 1,2);
-
+
_opacity_place.add(_opacity_value);
- _table.attach(_opacity_place, 2,3, 0,2, Gtk::SHRINK, Gtk::SHRINK);
- _swatch.add(_table);
+#if WITH_GTKMM_3_0
+ _table->attach(_label[SS_FILL], 0, 0, 1, 1);
+ _table->attach(_label[SS_STROKE], 0, 1, 1, 1);
+ _table->attach(_place[SS_FILL], 1, 0, 1, 1);
+ _table->attach(_stroke, 1, 1, 1, 1);
+ _table->attach(_opacity_place, 2, 0, 1, 2);
+#else
+ _table->attach(_label[SS_FILL], 0,1, 0,1, Gtk::FILL, Gtk::SHRINK);
+ _table->attach(_label[SS_STROKE], 0,1, 1,2, Gtk::FILL, Gtk::SHRINK);
+ _table->attach(_place[SS_FILL], 1,2, 0,1);
+ _table->attach(_stroke, 1,2, 1,2);
+ _table->attach(_opacity_place, 2,3, 0,2, Gtk::SHRINK, Gtk::SHRINK);
+#endif
+
+ _swatch.add(*_table);
pack_start(_swatch, true, true, 0);
set_size_request (STYLE_SWATCH_WIDTH, -1);
@@ -181,7 +201,7 @@ StyleSwatch::on_click(GdkEventButton */*event*/)
{
if (this->_desktop && this->_verb_t != SP_VERB_NONE) {
Inkscape::Verb *verb = Inkscape::Verb::get(this->_verb_t);
- SPAction *action = verb->get_action((Inkscape::UI::View::View *) this->_desktop);
+ SPAction *action = verb->get_action(Inkscape::ActionContext((Inkscape::UI::View::View *) this->_desktop));
sp_action_perform (action, NULL);
return true;
}
@@ -227,8 +247,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 +258,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();
@@ -314,7 +333,7 @@ StyleSwatch::setStyle(SPStyle *query)
if (has_stroke) {
double w;
if (_sw_unit) {
- w = sp_pixels_get_units(query->stroke_width.computed, *_sw_unit);
+ w = Inkscape::Util::Quantity::convert(query->stroke_width.computed, "px", _sw_unit);
} else {
w = query->stroke_width.computed;
}
@@ -327,7 +346,7 @@ StyleSwatch::setStyle(SPStyle *query)
{
gchar *str = g_strdup_printf(_("Stroke width: %.5g%s"),
w,
- _sw_unit? sp_unit_get_abbreviation(_sw_unit) : "px");
+ _sw_unit? _sw_unit->abbr.c_str() : "px");
_stroke_width_place.set_tooltip_text(str);
g_free (str);
}
@@ -341,15 +360,12 @@ StyleSwatch::setStyle(SPStyle *query)
if (op != 1) {
{
gchar *str;
- if (op == 0)
- str = g_strdup_printf(_("O:%.3g"), op);
- else
- str = g_strdup_printf(_("O:.%d"), (int) (op*10));
+ str = g_strdup_printf(_("O: %2.0f"), (op*100.0));
_opacity_value.set_markup (str);
g_free (str);
}
{
- gchar *str = g_strdup_printf(_("Opacity: %.3g"), op);
+ gchar *str = g_strdup_printf(_("Opacity: %2.1f %%"), (op*100.0));
_opacity_place.set_tooltip_text(str);
g_free (str);
}
diff --git a/src/ui/widget/style-swatch.h b/src/ui/widget/style-swatch.h
index 999bbd4ca..23ecbdfda 100644
--- a/src/ui/widget/style-swatch.h
+++ b/src/ui/widget/style-swatch.h
@@ -13,21 +13,39 @@
#ifndef INKSCAPE_UI_CURRENT_STYLE_H
#define INKSCAPE_UI_CURRENT_STYLE_H
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H
+#include <glibmm/threads.h>
+#endif
+
#include <gtkmm/box.h>
-#include <gtkmm/table.h>
#include <gtkmm/label.h>
#include <gtkmm/eventbox.h>
#include <gtkmm/enums.h>
#include "desktop.h"
-#include "button.h"
#include "preferences.h"
-class SPUnit;
-class SPStyle;
+struct SPStyle;
class SPCSSAttr;
+namespace Gtk {
+#if WITH_GTKMM_3_0
+class Grid;
+#else
+class Table;
+#endif
+}
+
namespace Inkscape {
+
+namespace Util {
+ class Unit;
+}
+
namespace UI {
namespace Widget {
@@ -60,7 +78,13 @@ private:
Glib::ustring _tool_path;
Gtk::EventBox _swatch;
- Gtk::Table _table;
+
+#if WITH_GTKMM_3_0
+ Gtk::Grid *_table;
+#else
+ Gtk::Table *_table;
+#endif
+
Gtk::Label _label[2];
Gtk::EventBox _place[2];
Gtk::EventBox _opacity_place;
@@ -72,7 +96,7 @@ private:
Gtk::EventBox _stroke_width_place;
Gtk::Label _stroke_width;
- SPUnit *_sw_unit;
+ Inkscape::Util::Unit *_sw_unit;
friend class ToolObserver;
};
diff --git a/src/ui/widget/svg-canvas.cpp b/src/ui/widget/svg-canvas.cpp
deleted file mode 100644
index a00c16f52..000000000
--- a/src/ui/widget/svg-canvas.cpp
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Authors:
- * Ralf Stephan <ralf@ark.in-berlin.de>
- * Jon A. Cruz <jon@joncruz.org>
- *
- * Copyright (C) 2005 The Authors
- *
- * Released under GNU GPL, read the file 'COPYING' for more information
- */
-
-#include <gtkmm/widget.h>
-#include "desktop.h"
-#include "desktop-events.h"
-#include "display/sp-canvas.h"
-#include "display/canvas-arena.h"
-#include "ui/widget/svg-canvas.h"
-
-namespace Inkscape {
-namespace UI {
-namespace Widget {
-
-SVGCanvas::SVGCanvas()
-{
- void *canvas = g_object_new(SPCanvas::getType(), NULL);
- _spcanvas = static_cast<SPCanvas*>(canvas);
- _widget = Glib::wrap (static_cast<GtkWidget*> (canvas));
- _dt = 0;
-}
-
-SVGCanvas::~SVGCanvas()
-{
-}
-
-void
-SVGCanvas::init (SPDesktop *dt)
-{
- _dt = dt;
- _widget->set_can_focus();
-
- // Set background to white
- Glib::RefPtr<Gtk::Style> style = _widget->get_style();
- style->set_bg(Gtk::STATE_NORMAL, style->get_white());
- _widget->set_style(style);
- _widget->set_extension_events(Gdk::EXTENSION_EVENTS_ALL);
- _widget->signal_event().connect(sigc::mem_fun(*this, &SVGCanvas::onEvent));
-}
-
-bool
-SVGCanvas::onEvent (GdkEvent * ev) const
-{
- g_assert (_dt);
-
- // Gdk::Event doesn't appear to be fully usable for this atm
- if (ev->type == GDK_BUTTON_PRESS) {
- // defocus any spinbuttons
- _widget->grab_focus();
- }
-
- if ((ev->type == GDK_BUTTON_PRESS) && (ev->button.button == 3)) {
- if (ev->button.state & GDK_SHIFT_MASK) {
- sp_canvas_arena_set_sticky(SP_CANVAS_ARENA(_dt->drawing), true);
- } else {
- sp_canvas_arena_set_sticky(SP_CANVAS_ARENA(_dt->drawing), false);
- }
- }
-
- // The keypress events need to be passed to desktop handler explicitly,
- // because otherwise the event contexts only receive keypresses when the mouse cursor
- // is over the canvas. This redirection is only done for keypresses and only if there's no
- // current item on the canvas, because item events and all mouse events are caught
- // and passed on by the canvas acetate (I think). --bb
-
- if (ev->type == GDK_KEY_PRESS && !_spcanvas->current_item) {
- return sp_desktop_root_handler(0, ev, _dt);
- }
-
- return false;
-}
-
-}}}
-
-/*
- Local Variables:
- mode:c++
- c-file-style:"stroustrup"
- c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
- indent-tabs-mode:nil
- fill-column:99
- End:
-*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/ui/widget/svg-canvas.h b/src/ui/widget/svg-canvas.h
deleted file mode 100644
index c513bcf26..000000000
--- a/src/ui/widget/svg-canvas.h
+++ /dev/null
@@ -1,57 +0,0 @@
-#ifndef SEEN_UI_WIDGET_SVGCANVAS_H
-#define SEEN_UI_WIDGET_SVGCANVAS_H
-
-/*
- * Authors:
- * Ralf Stephan <ralf@ark.in-berlin.de>
- *
- * Copyright (C) 2005 The Authors
- *
- * Released under GNU GPL, read the file 'COPYING' for more information
- */
-
-struct SPCanvas;
-struct SPDesktop;
-namespace Gtk { class Widget; }
-namespace Inkscape {
-namespace UI {
-namespace Widget {
-
-/**
- * Gtkmm facade/wrapper around SPCanvas.
- */
-class SVGCanvas
-{
-public:
- SVGCanvas();
- ~SVGCanvas();
- void init (SPDesktop*);
- Gtk::Widget& widget() const { return *_widget; }
- SPCanvas* spobj() const { return _spcanvas; }
-
-protected:
- Gtk::Widget *_widget;
- SPCanvas *_spcanvas;
- SPDesktop *_dt;
-
- bool onEvent (GdkEvent *) const;
-};
-
-} // namespace Widget
-} // namespace UI
-} // namespace Inkscape
-
-
-#endif // SEEN_UI_WIDGET_SVGCANVAS_H
-
-
-/*
- Local Variables:
- mode:c++
- c-file-style:"stroustrup"
- c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
- indent-tabs-mode:nil
- fill-column:99
- End:
-*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
diff --git a/src/ui/widget/tolerance-slider.cpp b/src/ui/widget/tolerance-slider.cpp
index 16558f0ee..d166e3831 100644
--- a/src/ui/widget/tolerance-slider.cpp
+++ b/src/ui/widget/tolerance-slider.cpp
@@ -12,6 +12,10 @@
# include <config.h>
#endif
+#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H
+#include <glibmm/threads.h>
+#endif
+
#include <gtkmm/adjustment.h>
#include <gtkmm/box.h>
#include <gtkmm/label.h>
@@ -73,8 +77,15 @@ void ToleranceSlider::init (const Glib::ustring& label1, const Glib::ustring& la
theLabel1->set_use_underline();
theLabel1->set_alignment(0, 0.5);
// align the label with the checkbox text above by indenting 22 px.
- _hbox->pack_start(*theLabel1, Gtk::PACK_EXPAND_WIDGET, 22);
+ _hbox->pack_start(*theLabel1, Gtk::PACK_EXPAND_WIDGET, 22);
+
+#if WITH_GTKMM_3_0
+ _hscale = manage(new Gtk::Scale(Gtk::ORIENTATION_HORIZONTAL));
+ _hscale->set_range(1.0, 51.0);
+#else
_hscale = manage (new Gtk::HScale (1.0, 51, 1.0));
+#endif
+
theLabel1->set_mnemonic_widget (*_hscale);
_hscale->set_draw_value (true);
_hscale->set_value_pos (Gtk::POS_RIGHT);
diff --git a/src/ui/widget/tolerance-slider.h b/src/ui/widget/tolerance-slider.h
index d0b78e3c1..2184cd52b 100644
--- a/src/ui/widget/tolerance-slider.h
+++ b/src/ui/widget/tolerance-slider.h
@@ -13,7 +13,12 @@
#include <gtkmm/radiobuttongroup.h>
namespace Gtk {
- class RadioButton;
+class RadioButton;
+#if WITH_GTKMM_3_0
+class Scale;
+#else
+class HScale;
+#endif
}
namespace Inkscape {
@@ -55,7 +60,13 @@ protected:
void on_toggled();
void update (double val);
Gtk::HBox *_hbox;
+
+#if WITH_GTKMM_3_0
+ Gtk::Scale *_hscale;
+#else
Gtk::HScale *_hscale;
+#endif
+
Gtk::RadioButtonGroup _radio_button_group;
Gtk::RadioButton *_button1;
Gtk::RadioButton *_button2;
diff --git a/src/ui/widget/toolbox.cpp b/src/ui/widget/toolbox.cpp
deleted file mode 100644
index a11bd2d74..000000000
--- a/src/ui/widget/toolbox.cpp
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * Author:
- * Derek P. Moore <derekm@hackunix.org>
- *
- * Copyright (C) 2004 Derek P. Moore
- *
- * Released under GNU GPL. Read the file 'COPYING' for more information.
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <gtkmm/radioaction.h>
-#include <gtkmm/orientable.h>
-#include <gtk/gtk.h>
-#include "ui/widget/toolbox.h"
-#include "path-prefix.h"
-
-namespace Inkscape {
-namespace UI {
-namespace Widget {
-
-Toolbox::Toolbox(Gtk::Toolbar *toolbar,
- Gtk::Orientation orientation)
- : HandleBox(toolbar)
-{
- init_actions();
- init_orientation(orientation);
- init_style(toolbar->get_toolbar_style());
-}
-
-Toolbox::Toolbox(Gtk::Toolbar *toolbar,
- Gtk::ToolbarStyle style,
- Gtk::Orientation orientation)
- : HandleBox(toolbar)
-{
- init_actions();
- init_orientation(orientation);
- init_style(style);
-}
-
-Gtk::Toolbar&
-Toolbox::get_toolbar()
-{
- return static_cast<Gtk::Toolbar&>(*_widget);
-}
-
-static Glib::ustring
-get_uidir_filename(char const *basename_utf8)
-{
- char *const ret_str = g_build_filename(INKSCAPE_UIDIR, basename_utf8, NULL);
- Glib::ustring const ret(ret_str);
- g_free(ret_str);
- return ret;
-}
-
-void
-Toolbox::init_actions()
-{
- _action_grp = Gtk::ActionGroup::create();
-
- Gtk::RadioAction::Group icons;
- _action_grp->add(Gtk::RadioAction::create(icons, "Icons", "Icons Only"),
- sigc::mem_fun(*this, &Toolbox::on_change_style_icons));
- _action_grp->add(Gtk::RadioAction::create(icons, "Text", "Text Only"),
- sigc::mem_fun(*this, &Toolbox::on_change_style_text));
- _action_grp->add(Gtk::RadioAction::create(icons, "Both", "Text Below Icons"),
- sigc::mem_fun(*this, &Toolbox::on_change_style_both));
- _action_grp->add(Gtk::RadioAction::create(icons, "BothHoriz", "Text Beside Icons"),
- sigc::mem_fun(*this, &Toolbox::on_change_style_both_horiz));
-
- _detach_grp = Gtk::ActionGroup::create();
-
- Gtk::RadioAction::Group orient;
- _detach_grp->add(Gtk::RadioAction::create(orient, "OrientHoriz", "Horizontal"),
- sigc::mem_fun(*this, &Toolbox::on_change_orient_horiz));
- _detach_grp->add(Gtk::RadioAction::create(orient, "OrientVert", "Vertical"),
- sigc::mem_fun(*this, &Toolbox::on_change_orient_vert));
-
- _detach_grp->add(Gtk::ToggleAction::create("ShowArrow", "Show Arrow",
- Glib::ustring(), true),
- sigc::mem_fun(*this, &Toolbox::on_show_arrow));
-
- _ui_mgr = Gtk::UIManager::create();
- _ui_mgr->insert_action_group(_action_grp);
- _ui_mgr->insert_action_group(_detach_grp);
- _ui_mgr->add_ui_from_file(get_uidir_filename("toolbox.xml"));
-
- _context_menu = static_cast<Gtk::Menu*>(_ui_mgr->get_widget("/ToolboxMenu"));
-
- static_cast<Gtk::Toolbar*>(_widget)->signal_popup_context_menu()
- .connect(sigc::mem_fun(*this, &Toolbox::on_popup_context_menu));
-
- _detach_grp->set_sensitive(false);
-}
-
-void
-Toolbox::init_orientation(Gtk::Orientation const &orientation)
-{
- gtk_orientable_set_orientation(GTK_ORIENTABLE(static_cast<Gtk::Toolbar*>(_widget)->gobj()),
- GtkOrientation(orientation));
-
- if (orientation == Gtk::ORIENTATION_VERTICAL) {
- set_handle_position(Gtk::POS_TOP);
- }
- switch (orientation) {
- case Gtk::ORIENTATION_HORIZONTAL: {
- Glib::RefPtr<Gtk::RadioAction>::cast_static(_detach_grp->get_action("OrientHoriz"))
- ->set_active();
- break;
- }
- case Gtk::ORIENTATION_VERTICAL: {
- Glib::RefPtr<Gtk::RadioAction>::cast_static(_detach_grp->get_action("OrientVert"))
- ->set_active();
- break;
- }
- }
-}
-
-void
-Toolbox::init_style(Gtk::ToolbarStyle const &style)
-{
- switch (style) {
- case Gtk::TOOLBAR_ICONS: {
- Glib::RefPtr<Gtk::RadioAction>::cast_static(_action_grp->get_action("Icons"))
- ->activate();
- break;
- }
- case Gtk::TOOLBAR_TEXT: {
- Glib::RefPtr<Gtk::RadioAction>::cast_static(_action_grp->get_action("Text"))
- ->activate();
- break;
- }
- case Gtk::TOOLBAR_BOTH: {
- Glib::RefPtr<Gtk::RadioAction>::cast_static(_action_grp->get_action("Both"))
- ->activate();
- break;
- }
- case Gtk::TOOLBAR_BOTH_HORIZ: {
- Glib::RefPtr<Gtk::RadioAction>::cast_static(_action_grp->get_action("BothHoriz"))
- ->activate();
- break;
- }
- }
-}
-
-bool
-Toolbox::on_popup_context_menu(int x, int y, int button)
-{
- (void)x;
- (void)y;
- _context_menu->popup(button, gtk_get_current_event_time());
- return true;
-}
-
-void
-Toolbox::on_child_attached(Gtk::Widget *widget)
-{
- (void)widget;
- Gtk::Toolbar *toolbar = static_cast<Gtk::Toolbar*>(_widget);
-
- if (!(toolbar->get_show_arrow())) {
- Glib::RefPtr<Gtk::RadioAction>::cast_static(_detach_grp->get_action("ShowArrow"))
- ->activate();
- }
-
- if (get_handle_position() == Gtk::POS_LEFT
- && toolbar->get_orientation() != Gtk::ORIENTATION_HORIZONTAL) {
- Glib::RefPtr<Gtk::RadioAction>::cast_static(_detach_grp->get_action("OrientHoriz"))
- ->activate();
- } else if (get_handle_position() == Gtk::POS_TOP
- && toolbar->get_orientation() != Gtk::ORIENTATION_VERTICAL) {
- Glib::RefPtr<Gtk::RadioAction>::cast_static(_detach_grp->get_action("OrientVert"))
- ->activate();
- }
-
- _detach_grp->set_sensitive(false);
-}
-
-void
-Toolbox::on_child_detached(Gtk::Widget *widget)
-{
- (void)widget;
- _detach_grp->set_sensitive(true);
-
- Glib::RefPtr<Gtk::RadioAction>::cast_static(_detach_grp->get_action("ShowArrow"))
- ->set_active(false);
-}
-
-void
-Toolbox::on_change_style_icons()
-{
- Glib::RefPtr<Gtk::RadioAction> action = Glib::RefPtr<Gtk::RadioAction>::cast_static(_action_grp->get_action("Icons"));
- if (action->get_active()) {
- static_cast<Gtk::Toolbar*>(_widget)->set_toolbar_style(Gtk::TOOLBAR_ICONS);
- }
-}
-
-void
-Toolbox::on_change_style_text()
-{
- Glib::RefPtr<Gtk::RadioAction> action = Glib::RefPtr<Gtk::RadioAction>::cast_static(_action_grp->get_action("Text"));
- if (action->get_active()) {
- static_cast<Gtk::Toolbar*>(_widget)->set_toolbar_style(Gtk::TOOLBAR_TEXT);
- }
-}
-
-void
-Toolbox::on_change_style_both()
-{
- Glib::RefPtr<Gtk::RadioAction> action = Glib::RefPtr<Gtk::RadioAction>::cast_static(_action_grp->get_action("Both"));
- if (action->get_active()) {
- static_cast<Gtk::Toolbar*>(_widget)->set_toolbar_style(Gtk::TOOLBAR_BOTH);
- }
-}
-
-void
-Toolbox::on_change_style_both_horiz()
-{
- Glib::RefPtr<Gtk::RadioAction> action = Glib::RefPtr<Gtk::RadioAction>::cast_static(_action_grp->get_action("BothHoriz"));
- if (action->get_active()) {
- static_cast<Gtk::Toolbar*>(_widget)->set_toolbar_style(Gtk::TOOLBAR_BOTH_HORIZ);
- }
-}
-
-void
-Toolbox::on_change_orient_horiz()
-{
- Glib::RefPtr<Gtk::RadioAction> action = Glib::RefPtr<Gtk::RadioAction>::cast_static(_detach_grp->get_action("OrientHoriz"));
- if (action->get_active()) {
- gtk_orientable_set_orientation(GTK_ORIENTABLE(static_cast<Gtk::Toolbar*>(_widget)->gobj()),
- GTK_ORIENTATION_HORIZONTAL);
- }
-}
-
-void
-Toolbox::on_change_orient_vert()
-{
- Glib::RefPtr<Gtk::RadioAction> action = Glib::RefPtr<Gtk::RadioAction>::cast_static(_detach_grp->get_action("OrientVert"));
- if (action->get_active()) {
- gtk_orientable_set_orientation(GTK_ORIENTABLE(static_cast<Gtk::Toolbar*>(_widget)->gobj()),
- GTK_ORIENTATION_VERTICAL);
- }
-}
-
-void
-Toolbox::on_show_arrow()
-{
- Glib::RefPtr<Gtk::RadioAction> action = Glib::RefPtr<Gtk::RadioAction>::cast_static(_detach_grp->get_action("ShowArrow"));
- Gtk::Toolbar *toolbar = static_cast<Gtk::Toolbar*>(_widget);
- if (action->get_active()) {
- toolbar->set_show_arrow(true);
- } else {
- toolbar->set_show_arrow(false);
- }
-}
-
-} // namespace Widget
-} // namespace UI
-} // namespace Inkscape
-
-/*
- Local Variables:
- mode:c++
- c-file-style:"stroustrup"
- c-file-offsets:((innamespace . 0)(inline-open . 0))
- indent-tabs-mode:nil
- fill-column:99
- End:
-*/
-// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
diff --git a/src/ui/widget/toolbox.h b/src/ui/widget/toolbox.h
deleted file mode 100644
index f721bef8a..000000000
--- a/src/ui/widget/toolbox.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Author:
- * Derek P. Moore <derekm@hackunix.org>
- *
- * Copyright (C) 2004 Derek P. Moore
- *
- * Released under GNU GPL. Read the file 'COPYING' for more information.
- */
-
-#ifndef INKSCAPE_UI_WIDGET_TOOLBOX_H
-#define INKSCAPE_UI_WIDGET_TOOLBOX_H
-
-#include <gtkmm/toolbar.h>
-#include <gtkmm/menu.h>
-#include <gtkmm/action.h>
-#include <gtkmm/uimanager.h>
-#include "handlebox.h"
-
-namespace Inkscape {
-namespace UI {
-namespace Widget {
-
-/**
- * A detachable toolbar for buttons and other widgets.
- */
-class Toolbox : public HandleBox
-{
-public:
- Toolbox(Gtk::Toolbar *toolbar,
- Gtk::Orientation orientation = Gtk::ORIENTATION_HORIZONTAL);
- Toolbox(Gtk::Toolbar *toolbar,
- Gtk::ToolbarStyle style,
- Gtk::Orientation orientation = Gtk::ORIENTATION_HORIZONTAL);
-
- Gtk::Toolbar& get_toolbar();
-
-protected:
- Gtk::Menu *_context_menu;
-
- Glib::RefPtr<Gtk::ActionGroup> _action_grp;
- Glib::RefPtr<Gtk::ActionGroup> _detach_grp;
- Glib::RefPtr<Gtk::UIManager> _ui_mgr;
-
- void init_actions();
- void init_orientation(Gtk::Orientation const &orientation);
- void init_style(Gtk::ToolbarStyle const &style);
- bool on_popup_context_menu(int x, int y, int button);
- void on_child_attached(Gtk::Widget *widget);
- void on_child_detached(Gtk::Widget *widget);
- void on_change_style_icons();
- void on_change_style_text();
- void on_change_style_both();
- void on_change_style_both_horiz();
- void on_change_orient_horiz();
- void on_change_orient_vert();
- void on_show_arrow();
-};
-
-} // namespace Widget
-} // namespace UI
-} // namespace Inkscape
-
-#endif // INKSCAPE_UI_WIDGET_TOOLBOX_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/unit-menu.cpp b/src/ui/widget/unit-menu.cpp
index 86e8c9e58..7416a2f02 100644
--- a/src/ui/widget/unit-menu.cpp
+++ b/src/ui/widget/unit-menu.cpp
@@ -15,6 +15,8 @@
#include "unit-menu.h"
+using Inkscape::Util::unit_table;
+
namespace Inkscape {
namespace UI {
namespace Widget {
@@ -30,51 +32,37 @@ UnitMenu::~UnitMenu() {
bool UnitMenu::setUnitType(UnitType unit_type)
{
// Expand the unit widget with unit entries from the unit table
- UnitTable::UnitMap m = _unit_table.units(unit_type);
- UnitTable::UnitMap::iterator iter = m.begin();
- while(iter != m.end()) {
- Glib::ustring text = (*iter).first;
-#if WITH_GTKMM_2_24
- append(text);
-#else
- append_text(text);
-#endif
- ++iter;
+ UnitTable::UnitMap m = unit_table.units(unit_type);
+
+ for (UnitTable::UnitMap::iterator i = m.begin(); i != m.end(); ++i) {
+ append(i->first);
}
_type = unit_type;
- set_active_text(_unit_table.primary(unit_type));
+ set_active_text(unit_table.primary(unit_type));
return true;
}
bool UnitMenu::resetUnitType(UnitType unit_type)
{
-#if WITH_GTKMM_2_24
- remove_all();
-#else
- clear_items();
-#endif
+ remove_all();
return setUnitType(unit_type);
}
void UnitMenu::addUnit(Unit const& u)
{
- _unit_table.addUnit(u, false);
-#if WITH_GTKMM_2_24
+ unit_table.addUnit(u, false);
append(u.abbr);
-#else
- append_text(u.abbr);
-#endif
}
-Unit UnitMenu::getUnit() const
+Unit const * UnitMenu::getUnit() const
{
if (get_active_text() == "") {
g_assert(_type != UNIT_TYPE_NONE);
- return _unit_table.getUnit(_unit_table.primary(_type));
+ return unit_table.getUnit(unit_table.primary(_type));
}
- return _unit_table.getUnit(get_active_text());
+ return unit_table.getUnit(get_active_text());
}
bool UnitMenu::setUnit(Glib::ustring const & unit)
@@ -91,27 +79,27 @@ Glib::ustring UnitMenu::getUnitAbbr() const
if (get_active_text() == "") {
return "";
}
- return getUnit().abbr;
+ return getUnit()->abbr;
}
UnitType UnitMenu::getUnitType() const
{
- return getUnit().type;
+ return getUnit()->type;
}
double UnitMenu::getUnitFactor() const
{
- return getUnit().factor;
+ return getUnit()->factor;
}
int UnitMenu::getDefaultDigits() const
{
- return getUnit().defaultDigits();
+ return getUnit()->defaultDigits();
}
double UnitMenu::getDefaultStep() const
{
- int factor_digits = -1*int(log10(getUnit().factor));
+ int factor_digits = -1*int(log10(getUnit()->factor));
return pow(10.0, factor_digits);
}
@@ -122,19 +110,20 @@ double UnitMenu::getDefaultPage() const
double UnitMenu::getConversion(Glib::ustring const &new_unit_abbr, Glib::ustring const &old_unit_abbr) const
{
- double old_factor = getUnit().factor;
- if (old_unit_abbr != "no_unit")
- old_factor = _unit_table.getUnit(old_unit_abbr).factor;
- Unit new_unit = _unit_table.getUnit(new_unit_abbr);
+ double old_factor = getUnit()->factor;
+ if (old_unit_abbr != "no_unit") {
+ old_factor = unit_table.getUnit(old_unit_abbr)->factor;
+ }
+ Unit const * new_unit = unit_table.getUnit(new_unit_abbr);
// Catch the case of zero or negative unit factors (error!)
if (old_factor < 0.0000001 ||
- new_unit.factor < 0.0000001) {
+ new_unit->factor < 0.0000001) {
// TODO: Should we assert here?
return 0.00;
}
- return old_factor / new_unit.factor;
+ return old_factor / new_unit->factor;
}
bool UnitMenu::isAbsolute() const
diff --git a/src/ui/widget/unit-menu.h b/src/ui/widget/unit-menu.h
index 142b11186..114c536c9 100644
--- a/src/ui/widget/unit-menu.h
+++ b/src/ui/widget/unit-menu.h
@@ -10,6 +10,14 @@
#ifndef INKSCAPE_UI_WIDGET_UNIT_H
#define INKSCAPE_UI_WIDGET_UNIT_H
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if GLIBMM_DISABLE_DEPRECATED && HAVE_GLIBMM_THREADS_H
+#include <glibmm/threads.h>
+#endif
+
#include <gtkmm/comboboxtext.h>
#include "util/units.h"
@@ -66,7 +74,7 @@ public:
* Returns the Unit object corresponding to the current selection
* in the dropdown widget.
*/
- Unit getUnit() const;
+ Unit const * getUnit() const;
/**
* Returns the abbreviated unit name of the selected unit.
@@ -119,10 +127,7 @@ public:
*/
bool isRadial() const;
- UnitTable &getUnitTable() {return _unit_table;}
-
protected:
- UnitTable _unit_table;
UnitType _type;
};
diff --git a/src/ui/widget/unit-tracker.cpp b/src/ui/widget/unit-tracker.cpp
new file mode 100644
index 000000000..67eb1f48d
--- /dev/null
+++ b/src/ui/widget/unit-tracker.cpp
@@ -0,0 +1,264 @@
+/*
+ * Inkscape::UI::Widget::UnitTracker
+ * Simple mediator to synchronize changes to unit menus
+ *
+ * Authors:
+ * Jon A. Cruz <jon@joncruz.org>
+ * Matthew Petroff <matthew@mpetroff.net>
+ *
+ * Copyright (C) 2007 Jon A. Cruz
+ * Copyright (C) 2013 Matthew Petroff
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include "unit-tracker.h"
+#include "ege-select-one-action.h"
+
+#define COLUMN_STRING 0
+
+using Inkscape::Util::UnitTable;
+using Inkscape::Util::unit_table;
+
+namespace Inkscape {
+namespace UI {
+namespace Widget {
+
+UnitTracker::UnitTracker(UnitType unit_type) :
+ _active(0),
+ _isUpdating(false),
+ _activeUnit(NULL),
+ _activeUnitInitialized(false),
+ _store(0),
+ _unitList(0),
+ _actionList(0),
+ _adjList(0),
+ _priorValues()
+{
+ _store = gtk_list_store_new(1, G_TYPE_STRING);
+
+ GtkTreeIter iter;
+ UnitTable::UnitMap m = unit_table.units(unit_type);
+
+
+ for (UnitTable::UnitMap::iterator m_iter = m.begin(); m_iter != m.end(); ++m_iter) {
+ Glib::ustring text = m_iter->first;
+ gtk_list_store_append(_store, &iter);
+ gtk_list_store_set(_store, &iter, COLUMN_STRING, text.c_str(), -1);
+ }
+ gint count = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(_store), 0);
+ if ((count > 0) && (_active > count)) {
+ _setActive(--count);
+ } else {
+ _setActive(_active);
+ }
+}
+
+UnitTracker::~UnitTracker()
+{
+ // Unhook weak references to GtkActions
+ while (_actionList) {
+ g_signal_handlers_disconnect_by_func(G_OBJECT(_actionList->data), (gpointer) _unitChangedCB, this);
+ g_object_weak_unref(G_OBJECT(_actionList->data), _actionFinalizedCB, this);
+ _actionList = g_slist_delete_link(_actionList, _actionList);
+ }
+
+ // Unhook weak references to GtkAdjustments
+ while (_adjList) {
+ g_object_weak_unref(G_OBJECT(_adjList->data), _adjustmentFinalizedCB, this);
+ _adjList = g_slist_delete_link(_adjList, _adjList);
+ }
+}
+
+bool UnitTracker::isUpdating() const
+{
+ return _isUpdating;
+}
+
+Inkscape::Util::Unit const * UnitTracker::getActiveUnit() const
+{
+ return _activeUnit;
+}
+
+void UnitTracker::setActiveUnit(Inkscape::Util::Unit const *unit)
+{
+ if (unit) {
+ GtkTreeIter iter;
+ int index = 0;
+ gboolean found = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(_store), &iter);
+ while (found) {
+ gchar *storedUnit = 0;
+ gtk_tree_model_get(GTK_TREE_MODEL(_store), &iter, COLUMN_STRING, &storedUnit, -1);
+ if (storedUnit && (!unit->abbr.compare(storedUnit))) {
+ _setActive(index);
+ break;
+ }
+
+ found = gtk_tree_model_iter_next(GTK_TREE_MODEL(_store), &iter);
+ index++;
+ }
+ }
+}
+
+void UnitTracker::setActiveUnitByAbbr(gchar const *abbr)
+{
+ Inkscape::Util::Unit const *u = unit_table.getUnit(abbr);
+ setActiveUnit(u);
+}
+
+void UnitTracker::addAdjustment(GtkAdjustment *adj)
+{
+ if (!g_slist_find(_adjList, adj)) {
+ g_object_weak_ref(G_OBJECT(adj), _adjustmentFinalizedCB, this);
+ _adjList = g_slist_append(_adjList, adj);
+ }
+}
+
+void UnitTracker::addUnit(Inkscape::Util::Unit const *u)
+{
+ GtkTreeIter iter;
+ gtk_list_store_append(_store, &iter);
+ gtk_list_store_set(_store, &iter, COLUMN_STRING, u ? u->abbr.c_str() : "NULL", -1);
+}
+
+void UnitTracker::setFullVal(GtkAdjustment *adj, gdouble val)
+{
+ _priorValues[adj] = val;
+}
+
+GtkAction *UnitTracker::createAction(gchar const *name, gchar const *label, gchar const *tooltip)
+{
+ EgeSelectOneAction *act1 = ege_select_one_action_new(name, label, tooltip, NULL, GTK_TREE_MODEL(_store));
+ ege_select_one_action_set_label_column(act1, COLUMN_STRING);
+ if (_active) {
+ ege_select_one_action_set_active(act1, _active);
+ }
+
+ ege_select_one_action_set_appearance(act1, "minimal");
+ g_object_weak_ref(G_OBJECT(act1), _actionFinalizedCB, this);
+ g_signal_connect(G_OBJECT(act1), "changed", G_CALLBACK(_unitChangedCB), this);
+ _actionList = g_slist_append(_actionList, act1);
+
+ return GTK_ACTION(act1);
+}
+
+void UnitTracker::_unitChangedCB(GtkAction *action, gpointer data)
+{
+ if (action && data) {
+ EgeSelectOneAction *act = EGE_SELECT_ONE_ACTION(action);
+ gint active = ege_select_one_action_get_active(act);
+ UnitTracker *self = reinterpret_cast<UnitTracker *>(data);
+ self->_setActive(active);
+ }
+}
+
+void UnitTracker::_actionFinalizedCB(gpointer data, GObject *where_the_object_was)
+{
+ if (data && where_the_object_was) {
+ UnitTracker *self = reinterpret_cast<UnitTracker *>(data);
+ self->_actionFinalized(where_the_object_was);
+ }
+}
+
+void UnitTracker::_adjustmentFinalizedCB(gpointer data, GObject *where_the_object_was)
+{
+ if (data && where_the_object_was) {
+ UnitTracker *self = reinterpret_cast<UnitTracker *>(data);
+ self->_adjustmentFinalized(where_the_object_was);
+ }
+}
+
+void UnitTracker::_actionFinalized(GObject *where_the_object_was)
+{
+ GSList *target = g_slist_find(_actionList, where_the_object_was);
+ if (target) {
+ _actionList = g_slist_remove(_actionList, where_the_object_was);
+ } else {
+ g_warning("Received a finalization callback for unknown object %p", where_the_object_was);
+ }
+}
+
+void UnitTracker::_adjustmentFinalized(GObject *where_the_object_was)
+{
+ GSList *target = g_slist_find(_adjList, where_the_object_was);
+ if (target) {
+ _adjList = g_slist_remove(_adjList, where_the_object_was);
+ } else {
+ g_warning("Received a finalization callback for unknown object %p", where_the_object_was);
+ }
+}
+
+void UnitTracker::_setActive(gint active)
+{
+ if ( active != _active || !_activeUnitInitialized ) {
+ gint oldActive = _active;
+
+ GtkTreeIter iter;
+ gboolean found = gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(_store), &iter, NULL, oldActive);
+ if (found) {
+ gchar *abbr;
+ gtk_tree_model_get(GTK_TREE_MODEL(_store), &iter, COLUMN_STRING, &abbr, -1);
+ Inkscape::Util::Unit const *unit = unit_table.getUnit(abbr);
+
+ found = gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(_store), &iter, NULL, active);
+ if (found) {
+ gchar *newAbbr;
+ gtk_tree_model_get(GTK_TREE_MODEL(_store), &iter, COLUMN_STRING, &newAbbr, -1);
+ Inkscape::Util::Unit const *newUnit = unit_table.getUnit(newAbbr);
+ _activeUnit = newUnit;
+
+ if (_adjList) {
+ _fixupAdjustments(unit, newUnit);
+ }
+
+ } else {
+ g_warning("Did not find new unit");
+ }
+ } else {
+ g_warning("Did not find old unit");
+ }
+
+ _active = active;
+
+ for ( GSList *cur = _actionList ; cur ; cur = g_slist_next(cur) ) {
+ if (IS_EGE_SELECT_ONE_ACTION(cur->data)) {
+ EgeSelectOneAction *act = EGE_SELECT_ONE_ACTION(cur->data);
+ ege_select_one_action_set_active(act, active);
+ }
+ }
+
+ _activeUnitInitialized = true;
+ }
+}
+
+void UnitTracker::_fixupAdjustments(Inkscape::Util::Unit const *oldUnit, Inkscape::Util::Unit const *newUnit)
+{
+ _isUpdating = true;
+ for ( GSList *cur = _adjList ; cur ; cur = g_slist_next(cur) ) {
+ GtkAdjustment *adj = GTK_ADJUSTMENT(cur->data);
+ gdouble oldVal = gtk_adjustment_get_value(adj);
+ gdouble val = oldVal;
+
+ if ( (oldUnit->type != Inkscape::Util::UNIT_TYPE_DIMENSIONLESS)
+ && (newUnit->type == Inkscape::Util::UNIT_TYPE_DIMENSIONLESS) )
+ {
+ val = newUnit->factor * 100;
+ _priorValues[adj] = Inkscape::Util::Quantity::convert(oldVal, oldUnit, "px");
+ } else if ( (oldUnit->type == Inkscape::Util::UNIT_TYPE_DIMENSIONLESS)
+ && (newUnit->type != Inkscape::Util::UNIT_TYPE_DIMENSIONLESS) )
+ {
+ if (_priorValues.find(adj) != _priorValues.end()) {
+ val = Inkscape::Util::Quantity::convert(_priorValues[adj], "px", newUnit);
+ }
+ } else {
+ val = Inkscape::Util::Quantity::convert(oldVal, oldUnit, newUnit);
+ }
+
+ gtk_adjustment_set_value(adj, val);
+ }
+ _isUpdating = false;
+}
+
+} // namespace Widget
+} // namespace UI
+} // namespace Inkscape
diff --git a/src/ui/widget/unit-tracker.h b/src/ui/widget/unit-tracker.h
new file mode 100644
index 000000000..61bb556ef
--- /dev/null
+++ b/src/ui/widget/unit-tracker.h
@@ -0,0 +1,74 @@
+/*
+ * Inkscape::UI::Widget::UnitTracker
+ * Simple mediator to synchronize changes to unit menus
+ *
+ * Authors:
+ * Jon A. Cruz <jon@joncruz.org>
+ * Matthew Petroff <matthew@mpetroff.net>
+ *
+ * Copyright (C) 2007 Jon A. Cruz
+ * Copyright (C) 2013 Matthew Petroff
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifndef INKSCAPE_UI_WIDGET_UNIT_TRACKER_H
+#define INKSCAPE_UI_WIDGET_UNIT_TRACKER_H
+
+#include <map>
+#include <gtk/gtk.h>
+
+#include "util/units.h"
+
+using Inkscape::Util::Unit;
+using Inkscape::Util::UnitType;
+
+namespace Inkscape {
+namespace UI {
+namespace Widget {
+
+class UnitTracker {
+public:
+ UnitTracker(UnitType unit_type);
+ virtual ~UnitTracker();
+
+ bool isUpdating() const;
+
+ void setActiveUnit(Inkscape::Util::Unit const *unit);
+ void setActiveUnitByAbbr(gchar const *abbr);
+ Inkscape::Util::Unit const * getActiveUnit() const;
+
+ void addUnit(Inkscape::Util::Unit const *u);
+ void addAdjustment(GtkAdjustment *adj);
+ void setFullVal(GtkAdjustment *adj, gdouble val);
+
+ GtkAction *createAction(gchar const *name, gchar const *label, gchar const *tooltip);
+
+protected:
+ UnitType _type;
+
+private:
+ static void _unitChangedCB(GtkAction *action, gpointer data);
+ static void _actionFinalizedCB(gpointer data, GObject *where_the_object_was);
+ static void _adjustmentFinalizedCB(gpointer data, GObject *where_the_object_was);
+ void _setActive(gint index);
+ void _fixupAdjustments(Inkscape::Util::Unit const *oldUnit, Inkscape::Util::Unit const *newUnit);
+ void _actionFinalized(GObject *where_the_object_was);
+ void _adjustmentFinalized(GObject *where_the_object_was);
+
+ gint _active;
+ bool _isUpdating;
+ Inkscape::Util::Unit const *_activeUnit;
+ bool _activeUnitInitialized;
+ GtkListStore *_store;
+ GSList *_unitList;
+ GSList *_actionList;
+ GSList *_adjList;
+ std::map <GtkAdjustment *, gdouble> _priorValues;
+};
+
+} // namespace Widget
+} // namespace UI
+} // namespace Inkscape
+
+#endif // INKSCAPE_UI_WIDGET_UNIT_TRACKER_H
diff --git a/src/ui/widget/zoom-status.cpp b/src/ui/widget/zoom-status.cpp
deleted file mode 100644
index aea1beb17..000000000
--- a/src/ui/widget/zoom-status.cpp
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Authors:
- * Ralf Stephan <ralf@ark.in-berlin.de>
- * Lauris Kaplinski <lauris@kaplinski.com>
- * MenTaLguY <mental@rydia.net>
- * bulia byak <buliabyak@users.sf.net>
- *
- * Copyright (C) 2005 Ralf Stephan
- * Copyright (C) 2004 MenTaLguY
- * Copyright (C) 1999-2002 Lauris Kaplinski
- * Copyright (C) 2000-2001 Ximian, Inc.
- *
- * Released under GNU GPL, read the file 'COPYING' for more information
- */
-
-#include "ui/widget/zoom-status.h"
-#include "desktop.h"
-#include "desktop-handles.h"
-#include "widgets/spw-utilities.h"
-
-namespace Inkscape {
-namespace UI {
-namespace Widget {
-
-ZoomStatus::ZoomStatus()
-#if WITH_GTKMM_3_0
- : _adj(Gtk::Adjustment::create(0.0, -1.0, 1.0, 0.1, 0.1))
-#else
- : _adj(0.0, -1.0, 1.0, 0.1, 0.1)
-#endif
-{
- _dt = 0;
- _upd_f = false;
-
- property_numeric() = false;
- property_update_policy() = Gtk::UPDATE_ALWAYS;
- sp_set_font_size_smaller(static_cast<GtkWidget*>((void*)gobj()));
-}
-
-ZoomStatus::~ZoomStatus()
-{
- _dt = 0;
-}
-
-void
-ZoomStatus::init(SPDesktop *dt)
-{
- _dt = dt;
- property_digits() = 4;
-#if WITH_GTKMM_3_0
- _adj->set_value(0.0);
- _adj->set_lower(log(SP_DESKTOP_ZOOM_MIN)/log(2.0));
- _adj->set_upper(log(SP_DESKTOP_ZOOM_MAX)/log(2.0));
- _adj->set_step_increment(0.1);
- _adj->set_page_increment(0.1);
-#else
- _adj.set_value(0.0);
- _adj.set_lower(log(SP_DESKTOP_ZOOM_MIN)/log(2.0));
- _adj.set_upper(log(SP_DESKTOP_ZOOM_MAX)/log(2.0));
- _adj.set_step_increment(0.1);
- _adj.set_page_increment(0.1);
-#endif
- set_adjustment(_adj);
-}
-
-void
-ZoomStatus::update()
-{
- if (!_dt) return;
- _upd_f = true;
- set_value(log(_dt->current_zoom())/log(2.0));
- _upd_f = false;
-}
-
-inline double
-value_to_display(double value)
-{
- return floor(pow(2, value) * 100.0 + 0.5);
-}
-
-inline double
-display_to_value(double value)
-{
- return log(value / 100.0) / log(2.0);
-}
-
-int
-ZoomStatus::on_input(double *new_val)
-{
- double new_scrolled = get_value();
- double new_typed = atof(get_text().c_str());
-
- if (value_to_display(new_scrolled) == new_typed)
- { // the new value is set by scrolling
- *new_val = new_scrolled;
- } else { // the new value is typed in
- *new_val = display_to_value(new_typed);
- }
-
- return true;
-}
-
-bool
-ZoomStatus::on_output()
-{
- gchar b[64];
- g_snprintf(b, 64, "%4.0f%%", value_to_display(get_value()));
- set_text(b);
- return true;
-}
-
-void
-ZoomStatus::on_value_changed()
-{
- if (_upd_f) return;
- _upd_f = true;
- g_assert(_dt);
- double zoom_factor = pow(2, get_value());
- Geom::Rect const d = _dt->get_display_area();
- _dt->zoom_absolute(d.midpoint()[Geom::X], d.midpoint()[Geom::Y], zoom_factor);
- gtk_widget_grab_focus(static_cast<GtkWidget*>((void*)_dt->canvas));
- _upd_f = false;
-}
-
-}}}
-
-/*
- Local Variables:
- mode:c++
- c-file-style:"stroustrup"
- c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
- indent-tabs-mode:nil
- fill-column:99
- End:
-*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/ui/widget/zoom-status.h b/src/ui/widget/zoom-status.h
deleted file mode 100644
index 8f710300a..000000000
--- a/src/ui/widget/zoom-status.h
+++ /dev/null
@@ -1,69 +0,0 @@
-#ifndef SEEN_UI_WIDGET_ZOOMSTATUS_H
-#define SEEN_UI_WIDGET_ZOOMSTATUS_H
-/*
- * Authors:
- * Ralf Stephan <ralf@ark.in-berlin.de>
- *
- * Copyright (C) 2005 The Authors
- *
- * Released under GNU GPL, read the file 'COPYING' for more information
- */
-
-#if HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <gtkmm/adjustment.h>
-#include "ui/widget/spinbutton.h"
-
-struct SPDesktop;
-
-namespace Gtk { class Widget; }
-namespace Inkscape {
- namespace UI {
- namespace Widget {
-
-/**
- * Enhanced spinbutton.
- */
-class ZoomStatus : public Inkscape::UI::Widget::SpinButton
-{
-public:
- ZoomStatus();
- ~ZoomStatus();
-
- void init (SPDesktop*);
- void update();
-
-protected:
-#if WITH_GTKMM_3_0
- Glib::RefPtr<Gtk::Adjustment> _adj;
-#else
- Gtk::Adjustment _adj;
-#endif
- SPDesktop *_dt;
- bool _upd_f;
-
- virtual int on_input (double*);
- virtual bool on_output();
- virtual void on_value_changed();
-};
-
-} // namespace Widget
-} // namespace UI
-} // namespace Inkscape
-
-
-#endif // SEEN_UI_WIDGET_ZOOMSTATUS_H
-
-
-/*
- Local Variables:
- mode:c++
- c-file-style:"stroustrup"
- c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
- indent-tabs-mode:nil
- fill-column:99
- End:
-*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :