summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 74ab8b5)
raw | patch | inline | side by side (parent: 74ab8b5)
author | Krzysztof Kosiński <tweenk.pl@gmail.com> | |
Thu, 16 Dec 2010 23:01:36 +0000 (00:01 +0100) | ||
committer | Krzysztof Kosiński <tweenk.pl@gmail.com> | |
Thu, 16 Dec 2010 23:01:36 +0000 (00:01 +0100) |
src/ui/tool/multi-path-manipulator.cpp | patch | blob | history | |
src/ui/tool/path-manipulator.cpp | patch | blob | history | |
src/ui/tool/path-manipulator.h | patch | blob | history |
index 5f60f117a3d0ceb32aa4dfb5e03d58799613e9dc..082ac194b962e85a2501f99120814896689fbd27 100644 (file)
void MultiPathManipulator::shiftSelection(int dir)
{
- invokeForAll(&PathManipulator::shiftSelection, dir);
+ if (empty()) return;
+
+ // 1. find last selected node
+ // 2. select the next node; if the last node or nothing is selected,
+ // select first node
+ MapType::iterator last_i;
+ SubpathList::iterator last_j;
+ NodeList::iterator last_k;
+ bool anything_found = false;
+
+ for (MapType::iterator i = _mmap.begin(); i != _mmap.end(); ++i) {
+ SubpathList &sp = i->second->subpathList();
+ for (SubpathList::iterator j = sp.begin(); j != sp.end(); ++j) {
+ for (NodeList::iterator k = (*j)->begin(); k != (*j)->end(); ++k) {
+ if (k->selected()) {
+ last_i = i;
+ last_j = j;
+ last_k = k;
+ anything_found = true;
+ // when tabbing backwards, we want the first node
+ if (dir == -1) goto exit_loop;
+ }
+ }
+ }
+ }
+ exit_loop:
+
+ // NOTE: we should not assume the _selection contains only nodes
+ // in future it might also contain handles and other types of control points
+ // this is why we use a flag instead in the loop above, instead of calling
+ // selection.empty()
+ if (!anything_found) {
+ // select first / last node
+ // this should never fail because there must be at least 1 non-empty manipulator
+ if (dir == 1) {
+ _selection.insert((*_mmap.begin()->second->subpathList().begin())->begin().ptr());
+ } else {
+ _selection.insert((--(*--(--_mmap.end())->second->subpathList().end())->end()).ptr());
+ }
+ return;
+ }
+
+ // three levels deep - w00t!
+ if (dir == 1) {
+ if (++last_k == (*last_j)->end()) {
+ // here, last_k points to the node to be selected
+ ++last_j;
+ if (last_j == last_i->second->subpathList().end()) {
+ ++last_i;
+ if (last_i == _mmap.end()) {
+ last_i = _mmap.begin();
+ }
+ last_j = last_i->second->subpathList().begin();
+ }
+ last_k = (*last_j)->begin();
+ }
+ } else {
+ if (!last_k || last_k == (*last_j)->begin()) {
+ if (last_j == last_i->second->subpathList().begin()) {
+ if (last_i == _mmap.begin()) {
+ last_i = _mmap.end();
+ }
+ --last_i;
+ last_j = last_i->second->subpathList().end();
+ }
+ --last_j;
+ last_k = (*last_j)->end();
+ }
+ --last_k;
+ }
+ _selection.clear();
+ _selection.insert(last_k.ptr());
}
void MultiPathManipulator::invertSelectionInSubpaths()
index 5ae9c4137255c7ab9cc1db66f7cb700045190448..7c60efbabbef193183547e4583c8d0daa0a9e626 100644 (file)
/** Select all nodes in subpaths that have something selected. */
void PathManipulator::selectSubpaths()
{
- for (std::list<SubpathPtr>::iterator i = _subpaths.begin(); i != _subpaths.end(); ++i) {
+ for (SubpathList::iterator i = _subpaths.begin(); i != _subpaths.end(); ++i) {
NodeList::iterator sp_start = (*i)->begin(), sp_end = (*i)->end();
for (NodeList::iterator j = sp_start; j != sp_end; ++j) {
if (j->selected()) {
}
}
-/** Move the selection forward or backward by one node in each subpath, based on the sign
- * of the parameter. */
-void PathManipulator::shiftSelection(int dir)
-{
- if (dir == 0) return;
- if (_num_selected == 0) {
- // select the first node of the path.
- SubpathList::iterator s = _subpaths.begin();
- if (s == _subpaths.end()) return;
- NodeList::iterator n = (*s)->begin();
- if (n != (*s)->end())
- _selection.insert(n.ptr());
- return;
- }
- // We cannot do any tricks here, like iterating in different directions based on
- // the sign and only setting the selection of nodes behind us, because it would break
- // for closed paths.
- for (SubpathList::iterator i = _subpaths.begin(); i != _subpaths.end(); ++i) {
- std::deque<bool> sels; // I hope this is specialized for bools!
- unsigned num = 0;
-
- for (NodeList::iterator j = (*i)->begin(); j != (*i)->end(); ++j) {
- sels.push_back(j->selected());
- _selection.erase(j.ptr());
- ++num;
- }
- if (num == 0) continue; // should never happen! zero-node subpaths are not allowed
-
- num = 0;
- // In closed subpath, shift the selection cyclically. In an open one,
- // let the selection 'slide into nothing' at ends.
- if (dir > 0) {
- if ((*i)->closed()) {
- bool last = sels.back();
- sels.pop_back();
- sels.push_front(last);
- } else {
- sels.push_front(false);
- }
- } else {
- if ((*i)->closed()) {
- bool first = sels.front();
- sels.pop_front();
- sels.push_back(first);
- } else {
- sels.push_back(false);
- num = 1;
- }
- }
-
- for (NodeList::iterator j = (*i)->begin(); j != (*i)->end(); ++j) {
- if (sels[num]) _selection.insert(j.ptr());
- ++num;
- }
- }
-}
-
/** Invert selection in the selected subpaths. */
void PathManipulator::invertSelectionInSubpaths()
{
index 87b88fc77495bfb4c141bb2a936eec1f1d968d53..8a0167e595111ff38785cce37c9fe1bbc8e859d5 100644 (file)
SPPath *item() { return _path; }
void selectSubpaths();
- void shiftSelection(int dir);
void invertSelectionInSubpaths();
void insertNodes();
NodeList::iterator extremeNode(NodeList::iterator origin, bool search_selected,
bool search_unselected, bool closest);
+ // this is necessary for Tab-selection in MultiPathManipulator
+ SubpathList &subpathList() { return _subpaths; }
+
static bool is_item_type(void *item);
private:
typedef NodeList Subpath;