Try to refactor the behaviour of the thumb browser selection modes adding support for shift-and-control range-selection to select several independent ranges.

This commit is contained in:
Adam Reichold
2015-11-29 00:07:21 +01:00
parent 88ab82cee9
commit df70d03e13
2 changed files with 74 additions and 70 deletions

View File

@@ -98,81 +98,85 @@ void ThumbBrowserBase::scrollPage (int direction)
} }
} }
void ThumbBrowserBase::selectSingle (ThumbBrowserEntryBase* fileDescr) namespace
{ {
for (size_t i = 0; i < selected.size(); i++) {
selected[i]->selected = false; typedef std::vector<ThumbBrowserEntryBase*> ThumbVector;
} typedef ThumbVector::iterator ThumbIterator;
inline void clearSelection (ThumbVector& selected)
{
for (ThumbIterator thumb = selected.begin (); thumb != selected.end (); ++thumb)
(*thumb)->selected = false;
selected.clear (); selected.clear ();
if (fileDescr) {
selected.push_back (fileDescr);
fileDescr->selected = true;
}
} }
void ThumbBrowserBase::selectRange (ThumbBrowserEntryBase* fileDescr) inline void addToSelection (ThumbBrowserEntryBase* entry, ThumbVector& selected)
{
if (entry->selected || entry->filtered)
return;
entry->selected = true;
selected.push_back (entry);
}
inline void removeFromSelection (const ThumbIterator& iterator, ThumbVector& selected)
{
(*iterator)->selected = false;
selected.erase (iterator);
}
}
void ThumbBrowserBase::selectSingle (ThumbBrowserEntryBase* clicked)
{
clearSelection (selected);
if (clicked)
addToSelection (clicked, selected);
}
void ThumbBrowserBase::selectRange (ThumbBrowserEntryBase* clicked, bool additional)
{ {
if (selected.empty ()) { if (selected.empty ()) {
selected.push_back (fileDescr); addToSelection (clicked, selected);
fileDescr->selected = true; return;
}
if (!additional || !lastClicked) {
// Extend the current range w.r.t to first selected entry.
ThumbIterator front = std::find (fd.begin (), fd.end (), selected.front ());
ThumbIterator current = std::find (fd.begin (), fd.end (), clicked);
if (front > current)
std::swap (front, current);
clearSelection (selected);
for (; front <= current; ++front)
addToSelection (*front, selected);
} else { } else {
// find the start and the end of the selection interval // Add an additional range w.r.t. the last clicked entry.
size_t startx = fd.size() - 1; ThumbIterator last = std::find (fd.begin (), fd.end (), lastClicked);
ThumbIterator current = std::find (fd.begin (), fd.end (), clicked);
if (lastClicked) { if (last > current)
for (; startx > 0; startx--) std::swap (last, current);
if (fd[startx] == lastClicked) {
break; for (; last <= current; ++last)
} addToSelection (*last, selected);
} else {
for (; startx > 0; startx--)
if (fd[startx] == selected[0]) {
break;
} }
} }
size_t endx = 0; void ThumbBrowserBase::selectSet (ThumbBrowserEntryBase* clicked)
for (; endx < fd.size(); endx++)
if (fd[endx] == fileDescr) {
break;
}
if (endx < startx) {
int tmp = endx;
endx = startx;
startx = tmp;
}
// clear current selection
for (size_t i = 0; i < selected.size(); i++) {
selected[i]->selected = false;
}
selected.clear ();
// select thumbnails in the interval
for (size_t i = startx; i <= endx; i++) {
if (!fd[i]->filtered) {
fd[i]->selected = true;
selected.push_back (fd[i]);
}
}
}
}
void ThumbBrowserBase::selectSet (ThumbBrowserEntryBase* fileDescr)
{ {
std::vector<ThumbBrowserEntryBase*>::iterator i = std::find (selected.begin(), selected.end(), fileDescr); const ThumbIterator iterator = std::find (selected.begin (), selected.end (), clicked);
if (i != selected.end()) { if (iterator != selected.end ()) {
(*i)->selected = false; removeFromSelection (iterator, selected);
selected.erase (i);
} else { } else {
selected.push_back (fileDescr); addToSelection (clicked, selected);
fileDescr->selected = true;
} }
} }
@@ -828,7 +832,7 @@ void ThumbBrowserBase::buttonPressed (int x, int y, int button, GdkEventType typ
doubleClicked (selected[0]); doubleClicked (selected[0]);
} else if (button == 1 && type == GDK_BUTTON_PRESS) { } else if (button == 1 && type == GDK_BUTTON_PRESS) {
if (fileDescr && (state & GDK_SHIFT_MASK)) if (fileDescr && (state & GDK_SHIFT_MASK))
selectRange (fileDescr); selectRange (fileDescr, state & GDK_CONTROL_MASK);
else if (fileDescr && (state & GDK_CONTROL_MASK)) else if (fileDescr && (state & GDK_CONTROL_MASK))
selectSet (fileDescr); selectSet (fileDescr);
else else

View File

@@ -111,9 +111,9 @@ public:
void scrollPage (int direction); void scrollPage (int direction);
private: private:
void selectSingle (ThumbBrowserEntryBase* fileDescr); void selectSingle (ThumbBrowserEntryBase* clicked);
void selectRange (ThumbBrowserEntryBase* fileDescr); void selectRange (ThumbBrowserEntryBase* clicked, bool additional);
void selectSet (ThumbBrowserEntryBase* fileDescr); void selectSet (ThumbBrowserEntryBase* clicked);
public: public:
void selectPrev (int distance, bool enlarge); void selectPrev (int distance, bool enlarge);