summaryrefslogtreecommitdiffstats
path: root/src/ui/control-manager.cpp
diff options
context:
space:
mode:
authorJon A. Cruz <jon@joncruz.org>2012-05-03 02:26:02 +0000
committerJon A. Cruz <jon@joncruz.org>2012-05-03 02:26:02 +0000
commit4fd08661432064633ec285160a2c7b8b0f8284a1 (patch)
tree6060d32d240e41ba75a01a703b6291f4f1a469fc /src/ui/control-manager.cpp
parentAdding base configurable sizing of controls/handles. (diff)
downloadinkscape-4fd08661432064633ec285160a2c7b8b0f8284a1.tar.gz
inkscape-4fd08661432064633ec285160a2c7b8b0f8284a1.zip
Adding the two new files.
(bzr r11317)
Diffstat (limited to 'src/ui/control-manager.cpp')
-rw-r--r--src/ui/control-manager.cpp260
1 files changed, 260 insertions, 0 deletions
diff --git a/src/ui/control-manager.cpp b/src/ui/control-manager.cpp
new file mode 100644
index 000000000..ea9cf175d
--- /dev/null
+++ b/src/ui/control-manager.cpp
@@ -0,0 +1,260 @@
+/*
+ * Central facade for accessing and managing on-canvas controls.
+ *
+ * Author:
+ * Jon A. Cruz <jon@joncruz.org>
+ *
+ * Copyright 2012 Authors
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include "control-manager.h"
+
+#include <algorithm>
+#include <glib.h>
+#include <glib-object.h>
+
+#include "display/sodipodi-ctrl.h" // for SP_TYPE_CTRL
+#include "display/sp-ctrlpoint.h"
+#include "preferences.h"
+
+namespace {
+
+std::map<Inkscape::ControlType, std::vector<int> > sizeTable;
+
+} // namespace
+
+#define FILL_COLOR_NORMAL 0xffffff7f
+#define FILL_COLOR_MOUSEOVER 0xff0000ff
+
+namespace Inkscape {
+
+class ControlManagerImpl
+{
+public:
+ ControlManagerImpl();
+
+ ~ControlManagerImpl() {}
+
+ void setControlSize(int size, bool force = false);
+
+ void track(SPCanvasItem *anchor);
+
+ sigc::connection connectCtrlSizeChanged(const sigc::slot<void> &slot);
+
+ void updateItem(SPCanvasItem *item);
+
+private:
+ static void thingFinalized(gpointer data, GObject *wasObj);
+
+ void thingFinalized(GObject *wasObj);
+
+ class PrefListener : public Inkscape::Preferences::Observer
+ {
+ public:
+ PrefListener(ControlManagerImpl &manager) : Inkscape::Preferences::Observer("/options/grabsize/value"), _mgr(manager) {}
+ virtual ~PrefListener() {}
+
+ virtual void notify(Inkscape::Preferences::Entry const &val) {
+ int size = val.getIntLimited(3, 1, 7);
+ _mgr.setControlSize(size);
+ }
+
+ ControlManagerImpl &_mgr;
+ };
+
+ sigc::signal<void> _sizeChangedSignal;
+ PrefListener _prefHook;
+ int _size;
+ std::vector<SPCanvasItem *> _itemList;
+ std::map<Inkscape::ControlType, std::vector<int> > _sizeTable;
+};
+
+ControlManagerImpl::ControlManagerImpl() :
+ _sizeChangedSignal(),
+ _prefHook(*this),
+ _size(3),
+ _itemList(),
+ _sizeTable()
+{
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ prefs->addObserver(_prefHook);
+
+ _size = prefs->getIntLimited("/options/grabsize/value", 3, 1, 7);
+
+ {
+ int sizes[] = {8, 8, 8, 8, 8, 8, 8};
+ _sizeTable[CTRL_TYPE_UNKNOWN] = std::vector<int>(sizes, sizes + (sizeof(sizes) / sizeof(sizes[0])));
+ }
+ {
+ int sizes[] = {2, 4, 6, 8, 10, 12, 14};
+ _sizeTable[CTRL_TYPE_ANCHOR] = std::vector<int>(sizes, sizes + (sizeof(sizes) / sizeof(sizes[0])));
+ }
+ {
+ int sizes[] = {2, 3, 4, 7, 8, 9, 10};
+ _sizeTable[CTRL_TYPE_ADJ_HANDLE] = std::vector<int>(sizes, sizes + (sizeof(sizes) / sizeof(sizes[0])));
+ }
+ {
+ int sizes[] = {4, 6, 8, 10, 12, 14, 16};
+ _sizeTable[CTRL_TYPE_POINT] = std::vector<int>(sizes, sizes + (sizeof(sizes) / sizeof(sizes[0])));
+ _sizeTable[CTRL_TYPE_ROTATE] = std::vector<int>(sizes, sizes + (sizeof(sizes) / sizeof(sizes[0])));
+ _sizeTable[CTRL_TYPE_SIZER] = std::vector<int>(sizes, sizes + (sizeof(sizes) / sizeof(sizes[0])));
+ _sizeTable[CTRL_TYPE_SHAPER] = std::vector<int>(sizes, sizes + (sizeof(sizes) / sizeof(sizes[0])));
+ }
+ {
+ int sizes[] = {2, 3, 4, 7, 8, 9, 10};
+ _sizeTable[CTRL_TYPE_ORIGIN] = std::vector<int>(sizes, sizes + (sizeof(sizes) / sizeof(sizes[0])));
+ }
+}
+
+
+void ControlManagerImpl::setControlSize(int size, bool force)
+{
+ if ((size < 1) || (size > 7)) {
+ g_warning("Illegal logical size set: %d", size);
+ } else if (force || (size != _size)) {
+ _size = size;
+
+ for (std::vector<SPCanvasItem *>::iterator it = _itemList.begin(); it != _itemList.end(); ++it)
+ {
+ if (*it) {
+ updateItem(*it);
+ }
+ }
+
+ _sizeChangedSignal.emit();
+ }
+}
+
+void ControlManagerImpl::track(SPCanvasItem *item)
+{
+ g_object_weak_ref( G_OBJECT(item), ControlManagerImpl::thingFinalized, this );
+
+ _itemList.push_back(item);
+
+ setControlSize(_size, true);
+}
+
+sigc::connection ControlManagerImpl::connectCtrlSizeChanged(const sigc::slot<void> &slot)
+{
+ return _sizeChangedSignal.connect(slot);
+}
+
+void ControlManagerImpl::updateItem(SPCanvasItem *item)
+{
+ if (item) {
+ double target = _sizeTable[item->ctrlType][_size - 1];
+ if ((item->ctrlType == CTRL_TYPE_ORIGIN) && SP_IS_CTRLPOINT(item)) {
+ sp_ctrlpoint_set_radius(SP_CTRLPOINT(item), target / 2.0);
+ } else {
+ sp_canvas_item_set(item, "size", target, NULL);
+ }
+ sp_canvas_item_request_update(item);
+ }
+}
+
+void ControlManagerImpl::thingFinalized(gpointer data, GObject *wasObj)
+{
+ if (data) {
+ reinterpret_cast<ControlManagerImpl *>(data)->thingFinalized(wasObj);
+ }
+}
+
+void ControlManagerImpl::thingFinalized(GObject *wasObj)
+{
+ SPCanvasItem *wasItem = reinterpret_cast<SPCanvasItem *>(wasObj);
+ if (wasItem)
+ {
+ std::vector<SPCanvasItem *>::iterator it = std::find(_itemList.begin(), _itemList.end(), wasItem);
+ if (it != _itemList.end())
+ {
+ _itemList.erase(it);
+ }
+ }
+}
+
+
+// ----------------------------------------------------
+
+ControlManager::ControlManager() :
+ _impl(new ControlManagerImpl())
+{
+}
+
+ControlManager::~ControlManager()
+{
+}
+
+ControlManager &ControlManager::getManager()
+{
+ static ControlManager instance;
+
+ return instance;
+}
+
+
+SPCanvasItem *ControlManager::createControl(SPCanvasGroup *parent, ControlType type)
+{
+ SPCanvasItem *item = 0;
+ switch (type)
+ {
+ case CTRL_TYPE_ADJ_HANDLE:
+ item = sp_canvas_item_new(parent, SP_TYPE_CTRL,
+ "shape", SP_CTRL_SHAPE_CIRCLE,
+ "size", 4.0,
+ "filled", 0,
+ "fill_color", 0xff00007f,
+ "stroked", 1,
+ "stroke_color", 0x0000ff7f,
+ NULL);
+ break;
+ case CTRL_TYPE_ANCHOR:
+ item = sp_canvas_item_new(parent, SP_TYPE_CTRL,
+ "size", 6.0,
+ "filled", 1,
+ "fill_color", FILL_COLOR_NORMAL,
+ "stroked", 1,
+ "stroke_color", 0x000000ff,
+ NULL);
+ break;
+ case CTRL_TYPE_ORIGIN:
+ item = sp_canvas_item_new(parent, SP_TYPE_CTRLPOINT, NULL);
+ break;
+ case CTRL_TYPE_UNKNOWN:
+ default:
+ item = sp_canvas_item_new(parent, SP_TYPE_CTRL, NULL);
+ }
+ if (item) {
+ item->ctrlType = type;
+ }
+ return item;
+}
+
+void ControlManager::track(SPCanvasItem *item)
+{
+ _impl->track(item);
+}
+
+sigc::connection ControlManager::connectCtrlSizeChanged(const sigc::slot<void> &slot)
+{
+ return _impl->connectCtrlSizeChanged(slot);
+}
+
+void ControlManager::updateItem(SPCanvasItem *item)
+{
+ return _impl->updateItem(item);
+}
+
+} // namespace Inkscape
+
+/*
+ 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 :