diff options
| author | Martin Owens <doctormo@gmail.com> | 2014-03-27 01:33:44 +0000 |
|---|---|---|
| committer | Martin Owens <doctormo@gmail.com> | 2014-03-27 01:33:44 +0000 |
| commit | 5a4fb2325f60d292b47330f540b26a3279341c90 (patch) | |
| tree | d2aa7967be25450b83e625025366c618101ae49f /src/ui/control-manager.cpp | |
| parent | The Polar Arrange Tab of the Arrange Dialog now hides the parametric (diff) | |
| parent | Remove Snap menu item and improve grid menu item text (diff) | |
| download | inkscape-5a4fb2325f60d292b47330f540b26a3279341c90.tar.gz inkscape-5a4fb2325f60d292b47330f540b26a3279341c90.zip | |
Commit a merge to trunk, with probabal errors
(bzr r11073.1.36)
Diffstat (limited to 'src/ui/control-manager.cpp')
| -rw-r--r-- | src/ui/control-manager.cpp | 309 |
1 files changed, 272 insertions, 37 deletions
diff --git a/src/ui/control-manager.cpp b/src/ui/control-manager.cpp index ea9cf175d..5a3c5a496 100644 --- a/src/ui/control-manager.cpp +++ b/src/ui/control-manager.cpp @@ -12,31 +12,68 @@ #include "control-manager.h" #include <algorithm> -#include <glib.h> +#include <set> + #include <glib-object.h> #include "display/sodipodi-ctrl.h" // for SP_TYPE_CTRL +#include "display/sp-canvas-item.h" +#include "display/sp-ctrlline.h" +#include "display/sp-ctrlcurve.h" #include "display/sp-ctrlpoint.h" #include "preferences.h" +using Inkscape::ControlFlags; + namespace { std::map<Inkscape::ControlType, std::vector<int> > sizeTable; +// Note: The following operator overloads are local to this file at the moment to discourage flag manipulation elsewhere. +/* +ControlFlags operator |(ControlFlags lhs, ControlFlags rhs) +{ + return static_cast<ControlFlags>(static_cast<int>(lhs) | static_cast<int>(rhs)); +} +*/ + +ControlFlags operator &(ControlFlags lhs, ControlFlags rhs) +{ + return static_cast<ControlFlags>(static_cast<int>(lhs) & static_cast<int>(rhs)); +} + +ControlFlags operator ^(ControlFlags lhs, ControlFlags rhs) +{ + return static_cast<ControlFlags>(static_cast<int>(lhs) ^ static_cast<int>(rhs)); +} + +ControlFlags& operator ^=(ControlFlags &lhs, ControlFlags rhs) +{ + lhs = lhs ^ rhs; + return lhs; +} + } // namespace #define FILL_COLOR_NORMAL 0xffffff7f #define FILL_COLOR_MOUSEOVER 0xff0000ff +// Default color for line: +#define LINE_COLOR_PRIMARY 0x0000ff7f +#define LINE_COLOR_SECONDARY 0xff00007f +#define LINE_COLOR_TERTIARY 0xffff007f + namespace Inkscape { class ControlManagerImpl { public: - ControlManagerImpl(); + ControlManagerImpl(ControlManager &manager); ~ControlManagerImpl() {} + SPCanvasItem *createControl(SPCanvasGroup *parent, ControlType type); + void setControlSize(int size, bool force = false); void track(SPCanvasItem *anchor); @@ -45,6 +82,10 @@ public: void updateItem(SPCanvasItem *item); + bool setControlType(SPCanvasItem *item, ControlType type); + + void setSelected(SPCanvasItem *item, bool selected); + private: static void thingFinalized(gpointer data, GObject *wasObj); @@ -64,14 +105,20 @@ private: ControlManagerImpl &_mgr; }; + + ControlManager &_manager; sigc::signal<void> _sizeChangedSignal; PrefListener _prefHook; int _size; std::vector<SPCanvasItem *> _itemList; std::map<Inkscape::ControlType, std::vector<int> > _sizeTable; + std::map<Inkscape::ControlType, GType> _typeTable; + std::map<Inkscape::ControlType, SPCtrlShapeType> _ctrlToShape; + std::set<Inkscape::ControlType> _sizeChangers; }; -ControlManagerImpl::ControlManagerImpl() : +ControlManagerImpl::ControlManagerImpl(ControlManager &manager) : + _manager(manager), _sizeChangedSignal(), _prefHook(*this), _size(3), @@ -83,6 +130,39 @@ ControlManagerImpl::ControlManagerImpl() : _size = prefs->getIntLimited("/options/grabsize/value", 3, 1, 7); + _typeTable[CTRL_TYPE_UNKNOWN] = SP_TYPE_CTRL; + _typeTable[CTRL_TYPE_ADJ_HANDLE] = SP_TYPE_CTRL; + _typeTable[CTRL_TYPE_ANCHOR] = SP_TYPE_CTRL; + _typeTable[CTRL_TYPE_INVISIPOINT] = SP_TYPE_CTRL; + _typeTable[CTRL_TYPE_NODE_AUTO] = SP_TYPE_CTRL; + _typeTable[CTRL_TYPE_NODE_CUSP] = SP_TYPE_CTRL; + _typeTable[CTRL_TYPE_NODE_SMOOTH] = SP_TYPE_CTRL; + _typeTable[CTRL_TYPE_NODE_SYMETRICAL] = SP_TYPE_CTRL; + + _typeTable[CTRL_TYPE_ORIGIN] = SP_TYPE_CTRLPOINT; + + _typeTable[CTRL_TYPE_LINE] = SP_TYPE_CTRLLINE; + + + // ------- + _ctrlToShape[CTRL_TYPE_UNKNOWN] = SP_CTRL_SHAPE_DIAMOND; + _ctrlToShape[CTRL_TYPE_NODE_CUSP] = SP_CTRL_SHAPE_DIAMOND; + _ctrlToShape[CTRL_TYPE_NODE_SMOOTH] = SP_CTRL_SHAPE_SQUARE; + _ctrlToShape[CTRL_TYPE_NODE_AUTO] = SP_CTRL_SHAPE_CIRCLE; + _ctrlToShape[CTRL_TYPE_NODE_SYMETRICAL] = SP_CTRL_SHAPE_SQUARE; + + _ctrlToShape[CTRL_TYPE_ADJ_HANDLE] = SP_CTRL_SHAPE_CIRCLE; + _ctrlToShape[CTRL_TYPE_INVISIPOINT] = SP_CTRL_SHAPE_SQUARE; + + // ------- + + _sizeChangers.insert(CTRL_TYPE_NODE_AUTO); + _sizeChangers.insert(CTRL_TYPE_NODE_CUSP); + _sizeChangers.insert(CTRL_TYPE_NODE_SMOOTH); + _sizeChangers.insert(CTRL_TYPE_NODE_SYMETRICAL); + + // ------- + { int sizes[] = {8, 8, 8, 8, 8, 8, 8}; _sizeTable[CTRL_TYPE_UNKNOWN] = std::vector<int>(sizes, sizes + (sizeof(sizes) / sizeof(sizes[0]))); @@ -92,7 +172,7 @@ ControlManagerImpl::ControlManagerImpl() : _sizeTable[CTRL_TYPE_ANCHOR] = std::vector<int>(sizes, sizes + (sizeof(sizes) / sizeof(sizes[0]))); } { - int sizes[] = {2, 3, 4, 7, 8, 9, 10}; + int sizes[] = {2, 4, 7, 8, 9, 10, 12}; _sizeTable[CTRL_TYPE_ADJ_HANDLE] = std::vector<int>(sizes, sizes + (sizeof(sizes) / sizeof(sizes[0]))); } { @@ -106,6 +186,20 @@ ControlManagerImpl::ControlManagerImpl() : int sizes[] = {2, 3, 4, 7, 8, 9, 10}; _sizeTable[CTRL_TYPE_ORIGIN] = std::vector<int>(sizes, sizes + (sizeof(sizes) / sizeof(sizes[0]))); } + { + int sizes[] = {5, 7, 9, 10, 11, 12, 13}; + _sizeTable[CTRL_TYPE_NODE_AUTO] = std::vector<int>(sizes, sizes + (sizeof(sizes) / sizeof(sizes[0]))); + _sizeTable[CTRL_TYPE_NODE_CUSP] = std::vector<int>(sizes, sizes + (sizeof(sizes) / sizeof(sizes[0]))); + } + { + int sizes[] = {3, 5, 7, 8, 9, 10, 11}; + _sizeTable[CTRL_TYPE_NODE_SMOOTH] = std::vector<int>(sizes, sizes + (sizeof(sizes) / sizeof(sizes[0]))); + _sizeTable[CTRL_TYPE_NODE_SYMETRICAL] = std::vector<int>(sizes, sizes + (sizeof(sizes) / sizeof(sizes[0]))); + } + { + int sizes[] = {1, 1, 1, 1, 1, 1, 1}; + _sizeTable[CTRL_TYPE_INVISIPOINT] = std::vector<int>(sizes, sizes + (sizeof(sizes) / sizeof(sizes[0]))); + } } @@ -127,6 +221,63 @@ void ControlManagerImpl::setControlSize(int size, bool force) } } +SPCanvasItem *ControlManagerImpl::createControl(SPCanvasGroup *parent, ControlType type) +{ + SPCanvasItem *item = 0; + double targetSize = _sizeTable[type][_size - 1]; + switch (type) + { + case CTRL_TYPE_ADJ_HANDLE: + item = sp_canvas_item_new(parent, SP_TYPE_CTRL, + "shape", SP_CTRL_SHAPE_CIRCLE, + "size", targetSize, + "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", targetSize, + "filled", 1, + "fill_color", FILL_COLOR_NORMAL, + "stroked", 1, + "stroke_color", 0x000000ff, + NULL); + break; + case CTRL_TYPE_NODE_AUTO: + case CTRL_TYPE_NODE_CUSP: + case CTRL_TYPE_NODE_SMOOTH: + case CTRL_TYPE_NODE_SYMETRICAL: + { + SPCtrlShapeType shape = _ctrlToShape[_ctrlToShape.count(type) ? type : CTRL_TYPE_UNKNOWN]; + item = sp_canvas_item_new(parent, SP_TYPE_CTRL, + "shape", shape, + "size", targetSize, + NULL); + break; + } + case CTRL_TYPE_ORIGIN: + item = sp_canvas_item_new(parent, SP_TYPE_CTRLPOINT, + NULL); + break; + case CTRL_TYPE_INVISIPOINT: + item = sp_canvas_item_new(parent, SP_TYPE_CTRL, + "shape", SP_CTRL_SHAPE_SQUARE, + "size", targetSize, + 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 ControlManagerImpl::track(SPCanvasItem *item) { g_object_weak_ref( G_OBJECT(item), ControlManagerImpl::thingFinalized, this ); @@ -145,15 +296,56 @@ 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); + if (_sizeChangers.count(item->ctrlType) && _manager.isSelected(item)) { + target += 2; + } + g_object_set(item, "size", target, NULL); } sp_canvas_item_request_update(item); } } +bool ControlManagerImpl::setControlType(SPCanvasItem *item, ControlType type) +{ + bool accepted = false; + if (item && (item->ctrlType == type)) { + // nothing to do + accepted = true; + } else if (item) { + if (_ctrlToShape.count(type) && (_typeTable[type] == _typeTable[item->ctrlType])) { // compatible? + double targetSize = _sizeTable[type][_size - 1]; + if (_manager.isSelected(item) && _sizeChangers.count(item->ctrlType)) { + targetSize += 2.0; + } + SPCtrlShapeType targetShape = _ctrlToShape[type]; + g_object_set(item, "shape", targetShape, "size", targetSize, NULL); + item->ctrlType = type; + accepted = true; + } + } + + return accepted; +} + + +void ControlManagerImpl::setSelected(SPCanvasItem *item, bool selected) +{ + if (_manager.isSelected(item) != selected) { + item->ctrlFlags ^= CTRL_FLAG_SELECTED; // toggle, since we know it is different + + // TODO refresh colors + double targetSize = _sizeTable[item->ctrlType][_size - 1]; + if (selected && _sizeChangers.count(item->ctrlType)) { + targetSize += 2.0; + } + g_object_set(item, "size", targetSize, NULL); + } +} + void ControlManagerImpl::thingFinalized(gpointer data, GObject *wasObj) { if (data) { @@ -178,7 +370,7 @@ void ControlManagerImpl::thingFinalized(GObject *wasObj) // ---------------------------------------------------- ControlManager::ControlManager() : - _impl(new ControlManagerImpl()) + _impl(new ControlManagerImpl(*this)) { } @@ -196,39 +388,41 @@ ControlManager &ControlManager::getManager() 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); + return _impl->createControl(parent, type); +} + +SPCtrlLine *ControlManager::createControlLine(SPCanvasGroup *parent, CtrlLineType type) +{ + SPCtrlLine *line = SP_CTRLLINE(sp_canvas_item_new(parent, SP_TYPE_CTRLLINE, NULL)); + if (line) { + line->ctrlType = CTRL_TYPE_LINE; + + line->setRgba32((type == CTLINE_PRIMARY) ? LINE_COLOR_PRIMARY : + (type == CTLINE_SECONDARY) ? LINE_COLOR_SECONDARY : LINE_COLOR_TERTIARY); } - if (item) { - item->ctrlType = type; + return line; +} + +SPCtrlLine *ControlManager::createControlLine(SPCanvasGroup *parent, Geom::Point const &p1, Geom::Point const &p2, CtrlLineType type) +{ + SPCtrlLine *line = createControlLine(parent, type); + if (line) { + line->setCoords(p1, p2); } - return item; + return line; +} + +SPCtrlCurve *ControlManager::createControlCurve(SPCanvasGroup *parent, Geom::Point const &p0, Geom::Point const &p1, Geom::Point const &p2, Geom::Point const &p3, CtrlLineType type) +{ + SPCtrlCurve *line = SP_CTRLCURVE(sp_canvas_item_new(parent, SP_TYPE_CTRLCURVE, NULL)); + if (line) { + line->ctrlType = CTRL_TYPE_LINE; + + line->setRgba32((type == CTLINE_PRIMARY) ? LINE_COLOR_PRIMARY : + (type == CTLINE_SECONDARY) ? LINE_COLOR_SECONDARY : LINE_COLOR_TERTIARY); + line->setCoords(p0, p1, p2, p3); + } + return line; } void ControlManager::track(SPCanvasItem *item) @@ -246,6 +440,47 @@ void ControlManager::updateItem(SPCanvasItem *item) return _impl->updateItem(item); } +bool ControlManager::setControlType(SPCanvasItem *item, ControlType type) +{ + return _impl->setControlType(item, type); +} + +bool ControlManager::isActive(SPCanvasItem *item) const +{ + return (item->ctrlFlags & CTRL_FLAG_ACTIVE) != 0; +} + +void ControlManager::setActive(SPCanvasItem *item, bool active) +{ + if (isActive(item) != active) { + item->ctrlFlags ^= CTRL_FLAG_ACTIVE; // toggle, since we know it is different + // TODO refresh size/colors + } +} + +bool ControlManager::isPrelight(SPCanvasItem *item) const +{ + return (item->ctrlFlags & CTRL_FLAG_PRELIGHT) != 0; +} + +void ControlManager::setPrelight(SPCanvasItem *item, bool prelight) +{ + if (isPrelight(item) != prelight) { + item->ctrlFlags ^= CTRL_FLAG_PRELIGHT; // toggle, since we know it is different + // TODO refresh size/colors + } +} + +bool ControlManager::isSelected(SPCanvasItem *item) const +{ + return (item->ctrlFlags & CTRL_FLAG_SELECTED) != 0; +} + +void ControlManager::setSelected(SPCanvasItem *item, bool selected) +{ + _impl->setSelected(item, selected); +} + } // namespace Inkscape /* |
