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 ();
}
if (fileDescr) {
selected.push_back (fileDescr);
fileDescr->selected = true;
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 ()) {
addToSelection (clicked, selected);
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 {
// Add an additional range w.r.t. the last clicked entry.
ThumbIterator last = std::find (fd.begin (), fd.end (), lastClicked);
ThumbIterator current = std::find (fd.begin (), fd.end (), clicked);
if (last > current)
std::swap (last, current);
for (; last <= current; ++last)
addToSelection (*last, selected);
}
}
void ThumbBrowserBase::selectRange (ThumbBrowserEntryBase* fileDescr)
void ThumbBrowserBase::selectSet (ThumbBrowserEntryBase* clicked)
{
if (selected.empty()) {
selected.push_back (fileDescr);
fileDescr->selected = true;
const ThumbIterator iterator = std::find (selected.begin (), selected.end (), clicked);
if (iterator != selected.end ()) {
removeFromSelection (iterator, selected);
} else {
// find the start and the end of the selection interval
size_t startx = fd.size() - 1;
if (lastClicked) {
for (; startx > 0; startx--)
if (fd[startx] == lastClicked) {
break;
}
} else {
for (; startx > 0; startx--)
if (fd[startx] == selected[0]) {
break;
}
}
size_t endx = 0;
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);
if (i != selected.end()) {
(*i)->selected = false;
selected.erase (i);
} else {
selected.push_back (fileDescr);
fileDescr->selected = true;
addToSelection (clicked, selected);
}
}
@@ -828,7 +832,7 @@ void ThumbBrowserBase::buttonPressed (int x, int y, int button, GdkEventType typ
doubleClicked (selected[0]);
} else if (button == 1 && type == GDK_BUTTON_PRESS) {
if (fileDescr && (state & GDK_SHIFT_MASK))
selectRange (fileDescr);
selectRange (fileDescr, state & GDK_CONTROL_MASK);
else if (fileDescr && (state & GDK_CONTROL_MASK))
selectSet (fileDescr);
else

View File

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