diff options
| author | Jon A. Cruz <jon@joncruz.org> | 2012-05-21 04:44:54 +0000 |
|---|---|---|
| committer | Jon A. Cruz <jon@joncruz.org> | 2012-05-21 04:44:54 +0000 |
| commit | 9d9347ae2714146bc1a943e8b15f26f161e6e10c (patch) | |
| tree | c25924e3bd82d66e60feff7ef64564f0026ebc3d /src/ui | |
| parent | Fix for 1000023 : Fill & Stroke dialog redesign (diff) | |
| download | inkscape-9d9347ae2714146bc1a943e8b15f26f161e6e10c.tar.gz inkscape-9d9347ae2714146bc1a943e8b15f26f161e6e10c.zip | |
Extended control resizing to node editing. Fixes half of bug #172059.
Additional prep for centralizing color setting.
(bzr r11390)
Diffstat (limited to 'src/ui')
| -rw-r--r-- | src/ui/control-manager.cpp | 192 | ||||
| -rw-r--r-- | src/ui/control-manager.h | 11 | ||||
| -rw-r--r-- | src/ui/control-types.h | 14 | ||||
| -rw-r--r-- | src/ui/tool/control-point.cpp | 23 | ||||
| -rw-r--r-- | src/ui/tool/control-point.h | 13 | ||||
| -rw-r--r-- | src/ui/tool/node.cpp | 75 | ||||
| -rw-r--r-- | src/ui/tool/node.h | 1 | ||||
| -rw-r--r-- | src/ui/tool/selectable-control-point.cpp | 6 | ||||
| -rw-r--r-- | src/ui/tool/selectable-control-point.h | 2 |
9 files changed, 266 insertions, 71 deletions
diff --git a/src/ui/control-manager.cpp b/src/ui/control-manager.cpp index 0e39737b8..124e591a8 100644 --- a/src/ui/control-manager.cpp +++ b/src/ui/control-manager.cpp @@ -12,6 +12,8 @@ #include "control-manager.h" #include <algorithm> +#include <set> + #include <glib.h> #include <glib-object.h> @@ -21,10 +23,47 @@ #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) +{ + lhs = lhs | rhs; + return lhs; +} + +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; +} + +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 @@ -40,7 +79,7 @@ namespace Inkscape { class ControlManagerImpl { public: - ControlManagerImpl(); + ControlManagerImpl(ControlManager &manager); ~ControlManagerImpl() {} @@ -54,6 +93,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); @@ -73,14 +116,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), @@ -92,6 +141,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]))); @@ -116,6 +198,16 @@ ControlManagerImpl::ControlManagerImpl() : _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]))); } @@ -165,6 +257,18 @@ SPCanvasItem *ControlManagerImpl::createControl(SPCanvasGroup *parent, ControlTy "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); @@ -203,15 +307,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 { + if (_sizeChangers.count(item->ctrlType) && _manager.isSelected(item)) { + target += 2; + } sp_canvas_item_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) { @@ -236,7 +381,7 @@ void ControlManagerImpl::thingFinalized(GObject *wasObj) // ---------------------------------------------------- ControlManager::ControlManager() : - _impl(new ControlManagerImpl()) + _impl(new ControlManagerImpl(*this)) { } @@ -293,6 +438,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 /* diff --git a/src/ui/control-manager.h b/src/ui/control-manager.h index 9f0e62543..4abb03e43 100644 --- a/src/ui/control-manager.h +++ b/src/ui/control-manager.h @@ -58,6 +58,17 @@ public: void updateItem(SPCanvasItem *item); + bool setControlType(SPCanvasItem *item, ControlType type); + + bool isActive(SPCanvasItem *item) const; + void setActive(SPCanvasItem *item, bool active); + + bool isPrelight(SPCanvasItem *item) const; + void setPrelight(SPCanvasItem *item, bool prelight); + + bool isSelected(SPCanvasItem *item) const; + void setSelected(SPCanvasItem *item, bool selected); + private: ControlManager(); diff --git a/src/ui/control-types.h b/src/ui/control-types.h index 8a9aef23f..0bbf31144 100644 --- a/src/ui/control-types.h +++ b/src/ui/control-types.h @@ -28,9 +28,23 @@ enum ControlType { CTRL_TYPE_SHAPER, CTRL_TYPE_ORIGIN, CTRL_TYPE_LINE, + CTRL_TYPE_NODE_AUTO, + CTRL_TYPE_NODE_CUSP, + CTRL_TYPE_NODE_SMOOTH, + CTRL_TYPE_NODE_SYMETRICAL, CTRL_TYPE_INVISIPOINT }; +/** + * Flags for internal representation/tracking. + */ +enum ControlFlags { + CTRL_FLAG_NORMAL = 0, + CTRL_FLAG_ACTIVE = 1 << 0, + CTRL_FLAG_PRELIGHT = 1 << 1, + CTRL_FLAG_SELECTED = 1 << 2, +}; + } // namespace Inkscape #endif // SEEN_UI_CONTROL_TYPES_H diff --git a/src/ui/tool/control-point.cpp b/src/ui/tool/control-point.cpp index 9c559be03..c3e7ccbe6 100644 --- a/src/ui/tool/control-point.cpp +++ b/src/ui/tool/control-point.cpp @@ -68,25 +68,6 @@ ControlPoint::ColorSet ControlPoint::invisible_cset = { }; ControlPoint::ControlPoint(SPDesktop *d, Geom::Point const &initial_pos, SPAnchorType anchor, - SPCtrlShapeType shape, unsigned int size, - ColorSet const &cset, SPCanvasGroup *group) : - _desktop(d), - _canvas_item(NULL), - _cset(cset), - _state(STATE_NORMAL), - _position(initial_pos), - _lurking(false) -{ - _canvas_item = sp_canvas_item_new( - group ? group : sp_desktop_controls (_desktop), SP_TYPE_CTRL, - "anchor", (SPAnchorType) anchor, "size", (gdouble) size, "shape", shape, - "filled", TRUE, "fill_color", _cset.normal.fill, - "stroked", TRUE, "stroke_color", _cset.normal.stroke, - "mode", SP_CTRL_MODE_XOR, NULL); - _commonInit(); -} - -ControlPoint::ControlPoint(SPDesktop *d, Geom::Point const &initial_pos, SPAnchorType anchor, Glib::RefPtr<Gdk::Pixbuf> pixbuf, ColorSet const &cset, SPCanvasGroup *group) : _desktop(d), @@ -216,9 +197,9 @@ void ControlPoint::_setSize(unsigned int size) g_object_set(_canvas_item, "size", (gdouble) size, NULL); } -void ControlPoint::_setShape(SPCtrlShapeType shape) +bool ControlPoint::_setControlType(Inkscape::ControlType type) { - g_object_set(_canvas_item, "shape", shape, NULL); + return ControlManager::getManager().setControlType(_canvas_item, type); } void ControlPoint::_setAnchor(SPAnchorType anchor) diff --git a/src/ui/tool/control-point.h b/src/ui/tool/control-point.h index 20122e09c..835fa5ab3 100644 --- a/src/ui/tool/control-point.h +++ b/src/ui/tool/control-point.h @@ -16,6 +16,8 @@ #include <sigc++/signal.h> #include <sigc++/trackable.h> #include <2geom/point.h> + +#include "ui/control-types.h" #include "util/accumulators.h" #include "display/sodipodi-ctrl.h" #include "enums.h" @@ -213,13 +215,12 @@ protected: * @param d Desktop for this control * @param initial_pos Initial position of the control point in desktop coordinates * @param anchor Where is the control point rendered relative to its desktop coordinates - * @param shape Shape of the control point: square, diamond, circle... - * @param size Pixel size of the visual representation + * @param type Logical type of the control point. * @param cset Colors of the point * @param group The canvas group the point's canvas item should be created in */ ControlPoint(SPDesktop *d, Geom::Point const &initial_pos, SPAnchorType anchor, - SPCtrlShapeType shape, unsigned int size, + ControlType type, ColorSet const &cset = _default_color_set, SPCanvasGroup *group = 0); /** @@ -236,10 +237,6 @@ protected: Glib::RefPtr<Gdk::Pixbuf> pixbuf, ColorSet const &cset = _default_color_set, SPCanvasGroup *group = 0); - ControlPoint(SPDesktop *d, Geom::Point const &initial_pos, SPAnchorType anchor, - ControlType type, - ColorSet const &cset = _default_color_set, SPCanvasGroup *group = 0); - /// @name Handle control point events in subclasses /// @{ /** @@ -310,7 +307,7 @@ protected: void _setSize(unsigned int size); - void _setShape(SPCtrlShapeType shape); + bool _setControlType(Inkscape::ControlType type); void _setAnchor(SPAnchorType anchor); diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 7408e4309..8098cbee2 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -35,6 +35,31 @@ #include "compat-key-syms.h" #endif +namespace { + +Inkscape::ControlType nodeTypeToCtrlType(Inkscape::UI::NodeType type) +{ + Inkscape::ControlType result = Inkscape::CTRL_TYPE_NODE_CUSP; + switch(type) { + case Inkscape::UI::NODE_SMOOTH: + result = Inkscape::CTRL_TYPE_NODE_SMOOTH; + break; + case Inkscape::UI::NODE_AUTO: + result = Inkscape::CTRL_TYPE_NODE_AUTO; + break; + case Inkscape::UI::NODE_SYMMETRIC: + result = Inkscape::CTRL_TYPE_NODE_SYMETRICAL; + break; + case Inkscape::UI::NODE_CUSP: + default: + result = Inkscape::CTRL_TYPE_NODE_CUSP; + break; + } + return result; +} + +} // namespace + namespace Inkscape { namespace UI { @@ -482,7 +507,7 @@ Glib::ustring Handle::_getDragTip(GdkEventMotion */*event*/) const Node::Node(NodeSharedData const &data, Geom::Point const &initial_pos) : SelectableControlPoint(data.desktop, initial_pos, SP_ANCHOR_CENTER, - SP_CTRL_SHAPE_DIAMOND, 9.0, + CTRL_TYPE_NODE_CUSP, *data.selection, node_colors, data.node_group), _front(data, initial_pos, this), @@ -736,7 +761,7 @@ void Node::setType(NodeType type, bool update_handles) } } _type = type; - _setShape(_node_type_to_shape(type)); + _setControlType(nodeTypeToCtrlType(_type)); updateState(); } @@ -785,7 +810,7 @@ void Node::pickBestType() } } } while (false); - _setShape(_node_type_to_shape(_type)); + _setControlType(nodeTypeToCtrlType(_type)); updateState(); } @@ -966,21 +991,20 @@ void Node::_linearGrow(int dir) void Node::_setState(State state) { // change node size to match type and selection state - switch (_type) { - case NODE_AUTO: - case NODE_CUSP: - if (selected()) { - _setSize(11); - } else { - _setSize(9); - } + ControlManager &mgr = ControlManager::getManager(); + mgr.setSelected(_canvas_item, selected()); + switch (state) { + case STATE_NORMAL: + mgr.setActive(_canvas_item, false); + mgr.setPrelight(_canvas_item, false); break; - default: - if (selected()) { - _setSize(9); - } else { - _setSize(7); - } + case STATE_MOUSEOVER: + mgr.setActive(_canvas_item, false); + mgr.setPrelight(_canvas_item, true); + break; + case STATE_CLICKED: + mgr.setActive(_canvas_item, true); + mgr.setPrelight(_canvas_item, false); break; } SelectableControlPoint::_setState(state); @@ -1304,23 +1328,6 @@ bool Node::_is_line_segment(Node *first, Node *second) return false; } -SPCtrlShapeType Node::_node_type_to_shape(NodeType type) -{ - switch(type) { - case NODE_CUSP: - return SP_CTRL_SHAPE_DIAMOND; - case NODE_SMOOTH: - return SP_CTRL_SHAPE_SQUARE; - case NODE_AUTO: - return SP_CTRL_SHAPE_CIRCLE; - case NODE_SYMMETRIC: - return SP_CTRL_SHAPE_SQUARE; - default: - return SP_CTRL_SHAPE_DIAMOND; - } -} - - NodeList::NodeList(SubpathList &splist) : _list(splist) , _closed(false) diff --git a/src/ui/tool/node.h b/src/ui/tool/node.h index 084ea1dff..b3964a257 100644 --- a/src/ui/tool/node.h +++ b/src/ui/tool/node.h @@ -251,7 +251,6 @@ private: Inkscape::SnapSourceType _snapSourceType() const; Inkscape::SnapTargetType _snapTargetType() const; inline PathManipulator &_pm(); - static SPCtrlShapeType _node_type_to_shape(NodeType type); /** Determine whether two nodes are joined by a linear segment. */ static bool _is_line_segment(Node *first, Node *second); diff --git a/src/ui/tool/selectable-control-point.cpp b/src/ui/tool/selectable-control-point.cpp index f431b9d57..f3f9c0e1e 100644 --- a/src/ui/tool/selectable-control-point.cpp +++ b/src/ui/tool/selectable-control-point.cpp @@ -24,10 +24,10 @@ ControlPoint::ColorSet SelectableControlPoint::_default_scp_color_set = { }; SelectableControlPoint::SelectableControlPoint(SPDesktop *d, Geom::Point const &initial_pos, SPAnchorType anchor, - SPCtrlShapeType shape, unsigned int size, + Inkscape::ControlType type, ControlPointSelection &sel, ColorSet const &cset, SPCanvasGroup *group) : - ControlPoint(d, initial_pos, anchor, shape, size, cset, group), + ControlPoint(d, initial_pos, anchor, type, cset, group), _selection(sel) { _selection.allPoints().insert(this); @@ -37,7 +37,7 @@ SelectableControlPoint::SelectableControlPoint(SPDesktop *d, Geom::Point const & Glib::RefPtr<Gdk::Pixbuf> pixbuf, ControlPointSelection &sel, ColorSet const &cset, SPCanvasGroup *group) : - ControlPoint (d, initial_pos, anchor, pixbuf, cset, group), + ControlPoint(d, initial_pos, anchor, pixbuf, cset, group), _selection (sel) { _selection.allPoints().insert(this); diff --git a/src/ui/tool/selectable-control-point.h b/src/ui/tool/selectable-control-point.h index 45da6c2b2..8acfc1168 100644 --- a/src/ui/tool/selectable-control-point.h +++ b/src/ui/tool/selectable-control-point.h @@ -32,7 +32,7 @@ public: protected: SelectableControlPoint(SPDesktop *d, Geom::Point const &initial_pos, SPAnchorType anchor, - SPCtrlShapeType shape, unsigned int size, + Inkscape::ControlType type, ControlPointSelection &sel, ColorSet const &cset = _default_scp_color_set, SPCanvasGroup *group = 0); |
