diff options
| author | Jon A. Cruz <jon@joncruz.org> | 2012-05-03 02:26:02 +0000 |
|---|---|---|
| committer | Jon A. Cruz <jon@joncruz.org> | 2012-05-03 02:26:02 +0000 |
| commit | 4fd08661432064633ec285160a2c7b8b0f8284a1 (patch) | |
| tree | 6060d32d240e41ba75a01a703b6291f4f1a469fc /src/ui/control-manager.cpp | |
| parent | Adding base configurable sizing of controls/handles. (diff) | |
| download | inkscape-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.cpp | 260 |
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 : |
