Further speedups for filebrowser/catalog
This commit is contained in:
parent
1320791052
commit
de963c54de
@ -19,11 +19,11 @@
|
|||||||
#include "browserfilter.h"
|
#include "browserfilter.h"
|
||||||
|
|
||||||
BrowserFilter::BrowserFilter () :
|
BrowserFilter::BrowserFilter () :
|
||||||
showTrash (true),
|
showTrash(true),
|
||||||
showNotTrash (true),
|
showNotTrash(true),
|
||||||
showOriginal (false),
|
showOriginal(false),
|
||||||
multiselect (false),
|
exifFilterEnabled(false),
|
||||||
exifFilterEnabled (false)
|
matchEqual(true)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 6; i++) {
|
for (int i = 0; i < 6; i++) {
|
||||||
showRanked[i] = true;
|
showRanked[i] = true;
|
||||||
|
@ -33,13 +33,11 @@ public:
|
|||||||
bool showOriginal;
|
bool showOriginal;
|
||||||
bool showEdited[2];
|
bool showEdited[2];
|
||||||
bool showRecentlySaved[2];
|
bool showRecentlySaved[2];
|
||||||
bool multiselect;
|
|
||||||
|
|
||||||
Glib::ustring queryString;
|
|
||||||
Glib::ustring queryFileName;
|
|
||||||
|
|
||||||
bool exifFilterEnabled;
|
bool exifFilterEnabled;
|
||||||
|
bool matchEqual;
|
||||||
ExifFilterSettings exifFilter;
|
ExifFilterSettings exifFilter;
|
||||||
|
std::vector<std::string> vFilterStrings;
|
||||||
|
|
||||||
BrowserFilter ();
|
BrowserFilter ();
|
||||||
};
|
};
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
|
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
#include <algorithm>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#include <glibmm.h>
|
#include <glibmm.h>
|
||||||
@ -622,7 +623,7 @@ void FileBrowser::addEntry_ (FileBrowserEntry* entry)
|
|||||||
|
|
||||||
initEntry(entry);
|
initEntry(entry);
|
||||||
}
|
}
|
||||||
redraw(false);
|
redraw(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
FileBrowserEntry* FileBrowser::delEntry (const Glib::ustring& fname)
|
FileBrowserEntry* FileBrowser::delEntry (const Glib::ustring& fname)
|
||||||
@ -1461,12 +1462,12 @@ void FileBrowser::applyFilter (const BrowserFilter& filter)
|
|||||||
redraw ();
|
redraw ();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FileBrowser::checkFilter (ThumbBrowserEntryBase* entryb) // true -> entry complies filter
|
bool FileBrowser::checkFilter (ThumbBrowserEntryBase* entryb) const // true -> entry complies filter
|
||||||
{
|
{
|
||||||
|
|
||||||
FileBrowserEntry* entry = static_cast<FileBrowserEntry*>(entryb);
|
FileBrowserEntry* entry = static_cast<FileBrowserEntry*>(entryb);
|
||||||
|
|
||||||
if (filter.showOriginal && entry->getOriginal() != nullptr) {
|
if (filter.showOriginal && entry->getOriginal()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1485,44 +1486,22 @@ bool FileBrowser::checkFilter (ThumbBrowserEntryBase* entryb) // true -> entry
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// return false is query is not satisfied
|
// return false if query is not satisfied
|
||||||
if (!filter.queryFileName.empty()) {
|
if (!filter.vFilterStrings.empty()) {
|
||||||
// check if image's FileName contains queryFileName (case insensitive)
|
// check if image's FileName contains queryFileName (case insensitive)
|
||||||
// TODO should we provide case-sensitive search option via preferences?
|
// TODO should we provide case-sensitive search option via preferences?
|
||||||
Glib::ustring FileName;
|
std::string FileName = Glib::path_get_basename(entry->thumbnail->getFileName());
|
||||||
FileName = Glib::path_get_basename (entry->thumbnail->getFileName());
|
std::transform(FileName.begin(), FileName.end(), FileName.begin(), ::toupper);
|
||||||
FileName = FileName.uppercase();
|
|
||||||
//printf("FileBrowser::checkFilter FileName = '%s'; find() result= %i \n",FileName.c_str(), FileName.find(filter.queryFileName.uppercase()));
|
|
||||||
|
|
||||||
Glib::ustring decodedQueryFileName;
|
|
||||||
bool MatchEqual;
|
|
||||||
|
|
||||||
// Determine the match mode - check if the first 2 characters are equal to "!="
|
|
||||||
if (filter.queryFileName.find("!=") == 0) {
|
|
||||||
decodedQueryFileName = filter.queryFileName.substr (2, filter.queryFileName.length() - 2);
|
|
||||||
MatchEqual = false;
|
|
||||||
} else {
|
|
||||||
decodedQueryFileName = filter.queryFileName;
|
|
||||||
MatchEqual = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Consider that queryFileName consist of comma separated values (FilterString)
|
|
||||||
// Evaluate if ANY of these FilterString are contained in the filename
|
|
||||||
// This will construct OR filter within the filter.queryFileName
|
|
||||||
int iFilenameMatch = 0;
|
int iFilenameMatch = 0;
|
||||||
std::vector<Glib::ustring> vFilterStrings = Glib::Regex::split_simple(",", decodedQueryFileName.uppercase());
|
|
||||||
|
|
||||||
for(size_t i = 0; i < vFilterStrings.size(); i++) {
|
for (const auto& entry : filter.vFilterStrings) {
|
||||||
// ignore empty vFilterStrings. Otherwise filter will always return true if
|
if (FileName.find(entry) != std::string::npos) {
|
||||||
// e.g. filter.queryFileName ends on "," and will stop being a filter
|
iFilenameMatch++;
|
||||||
if (!vFilterStrings.at(i).empty()) {
|
break;
|
||||||
if (FileName.find(vFilterStrings.at(i)) != Glib::ustring::npos) {
|
|
||||||
iFilenameMatch++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MatchEqual) {
|
if (filter.matchEqual) {
|
||||||
if (iFilenameMatch == 0) { //none of the vFilterStrings found in FileName
|
if (iFilenameMatch == 0) { //none of the vFilterStrings found in FileName
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1531,10 +1510,10 @@ bool FileBrowser::checkFilter (ThumbBrowserEntryBase* entryb) // true -> entry
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*experimental Regex support, this is unlikely to be useful to photographers*/
|
if (!filter.exifFilterEnabled) {
|
||||||
//bool matchfound=Glib::Regex::match_simple(filter.queryFileName.uppercase(),FileName);
|
return true;
|
||||||
//if (!matchfound) return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// check exif filter
|
// check exif filter
|
||||||
@ -1542,17 +1521,12 @@ bool FileBrowser::checkFilter (ThumbBrowserEntryBase* entryb) // true -> entry
|
|||||||
double tol = 0.01;
|
double tol = 0.01;
|
||||||
double tol2 = 1e-8;
|
double tol2 = 1e-8;
|
||||||
|
|
||||||
if (!filter.exifFilterEnabled) {
|
if (!cfs->exifValid) {
|
||||||
return true;
|
return (!filter.exifFilter.filterCamera || filter.exifFilter.cameras.count(cfs->getCamera()) > 0)
|
||||||
}
|
|
||||||
|
|
||||||
Glib::ustring camera(cfs->getCamera());
|
|
||||||
|
|
||||||
if (!cfs->exifValid)
|
|
||||||
return (!filter.exifFilter.filterCamera || filter.exifFilter.cameras.count(camera) > 0)
|
|
||||||
&& (!filter.exifFilter.filterLens || filter.exifFilter.lenses.count(cfs->lens) > 0)
|
&& (!filter.exifFilter.filterLens || filter.exifFilter.lenses.count(cfs->lens) > 0)
|
||||||
&& (!filter.exifFilter.filterFiletype || filter.exifFilter.filetypes.count(cfs->filetype) > 0)
|
&& (!filter.exifFilter.filterFiletype || filter.exifFilter.filetypes.count(cfs->filetype) > 0)
|
||||||
&& (!filter.exifFilter.filterExpComp || filter.exifFilter.expcomp.count(cfs->expcomp) > 0);
|
&& (!filter.exifFilter.filterExpComp || filter.exifFilter.expcomp.count(cfs->expcomp) > 0);
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
(!filter.exifFilter.filterShutter || (rtengine::FramesMetaData::shutterFromString(rtengine::FramesMetaData::shutterToString(cfs->shutter)) >= filter.exifFilter.shutterFrom - tol2 && rtengine::FramesMetaData::shutterFromString(rtengine::FramesMetaData::shutterToString(cfs->shutter)) <= filter.exifFilter.shutterTo + tol2))
|
(!filter.exifFilter.filterShutter || (rtengine::FramesMetaData::shutterFromString(rtengine::FramesMetaData::shutterToString(cfs->shutter)) >= filter.exifFilter.shutterFrom - tol2 && rtengine::FramesMetaData::shutterFromString(rtengine::FramesMetaData::shutterToString(cfs->shutter)) <= filter.exifFilter.shutterTo + tol2))
|
||||||
@ -1560,7 +1534,7 @@ bool FileBrowser::checkFilter (ThumbBrowserEntryBase* entryb) // true -> entry
|
|||||||
&& (!filter.exifFilter.filterFocalLen || (cfs->focalLen >= filter.exifFilter.focalFrom - tol && cfs->focalLen <= filter.exifFilter.focalTo + tol))
|
&& (!filter.exifFilter.filterFocalLen || (cfs->focalLen >= filter.exifFilter.focalFrom - tol && cfs->focalLen <= filter.exifFilter.focalTo + tol))
|
||||||
&& (!filter.exifFilter.filterISO || (cfs->iso >= filter.exifFilter.isoFrom && cfs->iso <= filter.exifFilter.isoTo))
|
&& (!filter.exifFilter.filterISO || (cfs->iso >= filter.exifFilter.isoFrom && cfs->iso <= filter.exifFilter.isoTo))
|
||||||
&& (!filter.exifFilter.filterExpComp || filter.exifFilter.expcomp.count(cfs->expcomp) > 0)
|
&& (!filter.exifFilter.filterExpComp || filter.exifFilter.expcomp.count(cfs->expcomp) > 0)
|
||||||
&& (!filter.exifFilter.filterCamera || filter.exifFilter.cameras.count(camera) > 0)
|
&& (!filter.exifFilter.filterCamera || filter.exifFilter.cameras.count(cfs->getCamera()) > 0)
|
||||||
&& (!filter.exifFilter.filterLens || filter.exifFilter.lenses.count(cfs->lens) > 0)
|
&& (!filter.exifFilter.filterLens || filter.exifFilter.lenses.count(cfs->lens) > 0)
|
||||||
&& (!filter.exifFilter.filterFiletype || filter.exifFilter.filetypes.count(cfs->filetype) > 0);
|
&& (!filter.exifFilter.filterFiletype || filter.exifFilter.filetypes.count(cfs->filetype) > 0);
|
||||||
}
|
}
|
||||||
|
@ -168,7 +168,7 @@ public:
|
|||||||
|
|
||||||
void buttonPressed (LWButton* button, int actionCode, void* actionData) override;
|
void buttonPressed (LWButton* button, int actionCode, void* actionData) override;
|
||||||
void redrawNeeded (LWButton* button) override;
|
void redrawNeeded (LWButton* button) override;
|
||||||
bool checkFilter (ThumbBrowserEntryBase* entry) override;
|
bool checkFilter (ThumbBrowserEntryBase* entry) const override;
|
||||||
void rightClicked (ThumbBrowserEntryBase* entry) override;
|
void rightClicked (ThumbBrowserEntryBase* entry) override;
|
||||||
void doubleClicked (ThumbBrowserEntryBase* entry) override;
|
void doubleClicked (ThumbBrowserEntryBase* entry) override;
|
||||||
bool keyPressed (GdkEventKey* event) override;
|
bool keyPressed (GdkEventKey* event) override;
|
||||||
|
@ -1603,7 +1603,6 @@ BrowserFilter FileCatalog::getFilter ()
|
|||||||
anyRankFilterActive || anyCLabelFilterActive || anyEditedFilterActive;
|
anyRankFilterActive || anyCLabelFilterActive || anyEditedFilterActive;
|
||||||
}
|
}
|
||||||
|
|
||||||
filter.multiselect = false;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Step 2
|
* Step 2
|
||||||
@ -1619,7 +1618,6 @@ BrowserFilter FileCatalog::getFilter ()
|
|||||||
(anyEditedFilterActive && anyRecentlySavedFilterActive) ||
|
(anyEditedFilterActive && anyRecentlySavedFilterActive) ||
|
||||||
(anySupplementaryActive && (anyRankFilterActive || anyCLabelFilterActive || anyEditedFilterActive || anyRecentlySavedFilterActive))) {
|
(anySupplementaryActive && (anyRankFilterActive || anyCLabelFilterActive || anyEditedFilterActive || anyRecentlySavedFilterActive))) {
|
||||||
|
|
||||||
filter.multiselect = true;
|
|
||||||
filter.showRanked[0] = anyRankFilterActive ? bUnRanked->get_active () : true;
|
filter.showRanked[0] = anyRankFilterActive ? bUnRanked->get_active () : true;
|
||||||
filter.showCLabeled[0] = anyCLabelFilterActive ? bUnCLabeled->get_active () : true;
|
filter.showCLabeled[0] = anyCLabelFilterActive ? bUnCLabeled->get_active () : true;
|
||||||
|
|
||||||
@ -1656,14 +1654,28 @@ BrowserFilter FileCatalog::getFilter ()
|
|||||||
//TODO could use date:<value>;iso:<value> etc
|
//TODO could use date:<value>;iso:<value> etc
|
||||||
// default will be filename
|
// default will be filename
|
||||||
|
|
||||||
/* // this is for safe execution if getFilter is called before Query object is instantiated
|
Glib::ustring decodedQueryFileName = Query->get_text(); // for now Query is only by file name
|
||||||
Glib::ustring tempQuery;
|
|
||||||
tempQuery="";
|
|
||||||
if (Query) tempQuery = Query->get_text();
|
|
||||||
*/
|
|
||||||
filter.queryString = Query->get_text(); // full query string from Query Entry
|
|
||||||
filter.queryFileName = Query->get_text(); // for now Query is only by file name
|
|
||||||
|
|
||||||
|
// Determine the match mode - check if the first 2 characters are equal to "!="
|
||||||
|
if (decodedQueryFileName.find("!=") == 0) {
|
||||||
|
decodedQueryFileName = decodedQueryFileName.substr(2);
|
||||||
|
filter.matchEqual = false;
|
||||||
|
} else {
|
||||||
|
filter.matchEqual = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Consider that queryFileName consist of comma separated values (FilterString)
|
||||||
|
// Evaluate if ANY of these FilterString are contained in the filename
|
||||||
|
// This will construct OR filter within the queryFileName
|
||||||
|
filter.vFilterStrings.clear();
|
||||||
|
const std::vector<Glib::ustring> filterStrings = Glib::Regex::split_simple(",", decodedQueryFileName.uppercase());
|
||||||
|
for (const auto& entry : filterStrings) {
|
||||||
|
// ignore empty filterStrings. Otherwise filter will always return true if
|
||||||
|
// e.g. queryFileName ends on "," and will stop being a filter
|
||||||
|
if (!entry.empty()) {
|
||||||
|
filter.vFilterStrings.push_back(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
return filter;
|
return filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
ThumbBrowserBase::ThumbBrowserBase ()
|
ThumbBrowserBase::ThumbBrowserBase ()
|
||||||
: location(THLOC_FILEBROWSER), inspector(nullptr), isInspectorActive(false), eventTime(0), lastClicked(nullptr), previewHeight(options.thumbSize), numOfCols(1), arrangement(TB_Horizontal)
|
: location(THLOC_FILEBROWSER), inspector(nullptr), isInspectorActive(false), eventTime(0), lastClicked(nullptr), previewHeight(options.thumbSize), numOfCols(1), lastRowHeight(0), arrangement(TB_Horizontal)
|
||||||
{
|
{
|
||||||
inW = -1;
|
inW = -1;
|
||||||
inH = -1;
|
inH = -1;
|
||||||
@ -44,6 +44,8 @@ ThumbBrowserBase::ThumbBrowserBase ()
|
|||||||
|
|
||||||
show_all ();
|
show_all ();
|
||||||
|
|
||||||
|
vscroll.get_adjustment()->set_lower(0);
|
||||||
|
hscroll.get_adjustment()->set_lower(0);
|
||||||
vscroll.signal_value_changed().connect( sigc::mem_fun(*this, &ThumbBrowserBase::scrollChanged) );
|
vscroll.signal_value_changed().connect( sigc::mem_fun(*this, &ThumbBrowserBase::scrollChanged) );
|
||||||
hscroll.signal_value_changed().connect( sigc::mem_fun(*this, &ThumbBrowserBase::scrollChanged) );
|
hscroll.signal_value_changed().connect( sigc::mem_fun(*this, &ThumbBrowserBase::scrollChanged) );
|
||||||
|
|
||||||
@ -543,7 +545,6 @@ void ThumbBrowserBase::configScrollBars ()
|
|||||||
auto ha = hscroll.get_adjustment();
|
auto ha = hscroll.get_adjustment();
|
||||||
int iw = internal.get_width();
|
int iw = internal.get_width();
|
||||||
ha->set_upper(inW);
|
ha->set_upper(inW);
|
||||||
ha->set_lower(0);
|
|
||||||
ha->set_step_increment(!fd.empty() ? fd[0]->getEffectiveWidth() : 0);
|
ha->set_step_increment(!fd.empty() ? fd[0]->getEffectiveWidth() : 0);
|
||||||
ha->set_page_increment(iw);
|
ha->set_page_increment(iw);
|
||||||
ha->set_page_size(iw);
|
ha->set_page_size(iw);
|
||||||
@ -558,7 +559,6 @@ void ThumbBrowserBase::configScrollBars ()
|
|||||||
|
|
||||||
auto va = vscroll.get_adjustment();
|
auto va = vscroll.get_adjustment();
|
||||||
va->set_upper(inH);
|
va->set_upper(inH);
|
||||||
va->set_lower(0);
|
|
||||||
const auto height = !fd.empty() ? fd[0]->getEffectiveHeight() : 0;
|
const auto height = !fd.empty() ? fd[0]->getEffectiveHeight() : 0;
|
||||||
va->set_step_increment(height);
|
va->set_step_increment(height);
|
||||||
va->set_page_increment(height == 0 ? ih : (ih / height) * height);
|
va->set_page_increment(height == 0 ? ih : (ih / height) * height);
|
||||||
@ -572,8 +572,22 @@ void ThumbBrowserBase::configScrollBars ()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThumbBrowserBase::arrangeFiles(bool checkfilter)
|
void ThumbBrowserBase::arrangeFiles(ThumbBrowserEntryBase* entry)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
if (fd.empty()) {
|
||||||
|
// nothing to arrange
|
||||||
|
resizeThumbnailArea(0, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(entry && entry->filtered) {
|
||||||
|
// a filtered entry was added, nothing to arrange, but has to be marked not drawable
|
||||||
|
MYREADERLOCK(l, entryRW);
|
||||||
|
entry->drawable = false;
|
||||||
|
MYREADERLOCK_RELEASE(l);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
MYREADERLOCK(l, entryRW);
|
MYREADERLOCK(l, entryRW);
|
||||||
|
|
||||||
// GUI already locked by ::redraw, the only caller of this method for now.
|
// GUI already locked by ::redraw, the only caller of this method for now.
|
||||||
@ -581,17 +595,22 @@ void ThumbBrowserBase::arrangeFiles(bool checkfilter)
|
|||||||
//GThreadLock lock;
|
//GThreadLock lock;
|
||||||
|
|
||||||
int rowHeight = 0;
|
int rowHeight = 0;
|
||||||
for (const auto entry : fd) {
|
if (entry) {
|
||||||
if (checkfilter) {
|
// we got the reference to the added entry, makes calculation of rowHeight O(1)
|
||||||
// apply filter
|
lastRowHeight = rowHeight = std::max(lastRowHeight, entry->getMinimalHeight());
|
||||||
entry->filtered = !checkFilter(entry);
|
} else {
|
||||||
}
|
|
||||||
|
|
||||||
// compute size of the items
|
lastRowHeight = 0;
|
||||||
if (!entry->filtered) {
|
for (const auto thumb : fd) {
|
||||||
rowHeight = std::max(entry->getMinimalHeight(), rowHeight);
|
// apply filter
|
||||||
|
thumb->filtered = !checkFilter(thumb);
|
||||||
|
// compute max rowHeight
|
||||||
|
if (!thumb->filtered) {
|
||||||
|
rowHeight = std::max(thumb->getMinimalHeight(), rowHeight);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arrangement == TB_Horizontal) {
|
if (arrangement == TB_Horizontal) {
|
||||||
numOfCols = 1;
|
numOfCols = 1;
|
||||||
|
|
||||||
@ -622,14 +641,16 @@ void ThumbBrowserBase::arrangeFiles(bool checkfilter)
|
|||||||
const int availWidth = internal.get_width();
|
const int availWidth = internal.get_width();
|
||||||
|
|
||||||
// initial number of columns
|
// initial number of columns
|
||||||
|
int oldNumOfCols = numOfCols;
|
||||||
numOfCols = 0;
|
numOfCols = 0;
|
||||||
int colsWidth = 0;
|
int colsWidth = 0;
|
||||||
|
|
||||||
for (unsigned int i = 0; i < fd.size(); ++i) {
|
for (unsigned int i = 0; i < fd.size(); ++i) {
|
||||||
if (!fd[i]->filtered && colsWidth + fd[i]->getMinimalWidth() <= availWidth) {
|
if (!fd[i]->filtered && colsWidth + fd[i]->getMinimalWidth() <= availWidth) {
|
||||||
colsWidth += fd[numOfCols]->getMinimalWidth();
|
colsWidth += fd[i]->getMinimalWidth();
|
||||||
++numOfCols;
|
++numOfCols;
|
||||||
if(colsWidth > availWidth) {
|
if(colsWidth > availWidth) {
|
||||||
|
--numOfCols;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -640,6 +661,7 @@ void ThumbBrowserBase::arrangeFiles(bool checkfilter)
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::vector<int> colWidths;
|
std::vector<int> colWidths;
|
||||||
|
std::vector<int> oldColWidths;
|
||||||
|
|
||||||
for (; numOfCols > 0; --numOfCols) {
|
for (; numOfCols > 0; --numOfCols) {
|
||||||
// compute column widths
|
// compute column widths
|
||||||
@ -663,10 +685,77 @@ void ThumbBrowserBase::arrangeFiles(bool checkfilter)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (oldNumOfCols == numOfCols) {
|
||||||
|
int oldColsWidth = 0;
|
||||||
|
for (; oldNumOfCols > 0; --oldNumOfCols) {
|
||||||
|
// compute old column widths
|
||||||
|
oldColWidths.assign(oldNumOfCols, 0);
|
||||||
|
|
||||||
|
for (unsigned int i = 0, j = 0; i < fd.size(); ++i) {
|
||||||
|
if (fd[i] != entry && !fd[i]->filtered && fd[i]->getMinimalWidth() > oldColWidths[j % oldNumOfCols]) {
|
||||||
|
oldColWidths[j % oldNumOfCols] = fd[i]->getMinimalWidth();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fd[i] != entry && !fd[i]->filtered) {
|
||||||
|
++j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// if not wider than the space available, arrange it and we are ready
|
||||||
|
oldColsWidth = std::accumulate(oldColWidths.begin(), oldColWidths.end(), 0);
|
||||||
|
|
||||||
|
if (oldNumOfCols == 1 || oldColsWidth < availWidth) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool arrangeAll = true;
|
||||||
|
if (entry && oldNumOfCols == numOfCols && oldColWidths.size() > 0) {
|
||||||
|
arrangeAll = false;
|
||||||
|
for (int i = 0; i < numOfCols; ++i) {
|
||||||
|
if(colWidths[i] != oldColWidths[i]) {
|
||||||
|
arrangeAll = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// arrange files
|
// arrange files
|
||||||
int curry = 0;
|
int curry = 0;
|
||||||
|
size_t ct = 0;
|
||||||
|
if (entry && !arrangeAll) {
|
||||||
|
int i = 0;
|
||||||
|
// Find currently added entry
|
||||||
|
for (; ct < fd.size() && fd[ct] != entry; i += !fd[ct]->filtered, ++ct) {
|
||||||
|
}
|
||||||
|
//Calculate the position of currently added entry
|
||||||
|
const int row = i / numOfCols;
|
||||||
|
const int col = i % numOfCols;
|
||||||
|
curry = row * rowHeight;
|
||||||
|
int currx = 0;
|
||||||
|
for (int c = 0; c < col; ++c) {
|
||||||
|
currx += colWidths[c];
|
||||||
|
}
|
||||||
|
// arrange all entries in the row beginning with the currently added one
|
||||||
|
for (int i = col; ct < fd.size() && i < numOfCols; ++i, ++ct) {
|
||||||
|
for (; ct < fd.size() && fd[ct]->filtered; ++ct) {
|
||||||
|
fd[ct]->drawable = false;
|
||||||
|
}
|
||||||
|
if (ct < fd.size()) {
|
||||||
|
fd[ct]->setPosition(currx, curry, colWidths[i], rowHeight);
|
||||||
|
fd[ct]->drawable = true;
|
||||||
|
currx += colWidths[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currx > 0) { // there were thumbnails placed in the row
|
||||||
|
curry += rowHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// arrange remaining entries, if any, that's the most expensive part
|
||||||
|
for (; ct < fd.size();) {
|
||||||
|
|
||||||
for (unsigned int ct = 0; ct < fd.size();) {
|
|
||||||
// arrange items in the row
|
// arrange items in the row
|
||||||
int currx = 0;
|
int currx = 0;
|
||||||
|
|
||||||
@ -689,7 +778,7 @@ void ThumbBrowserBase::arrangeFiles(bool checkfilter)
|
|||||||
|
|
||||||
MYREADERLOCK_RELEASE(l);
|
MYREADERLOCK_RELEASE(l);
|
||||||
// This will require a Writer access
|
// This will require a Writer access
|
||||||
resizeThumbnailArea (colsWidth, curry);
|
resizeThumbnailArea(colsWidth, curry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -979,11 +1068,11 @@ bool ThumbBrowserBase::Internal::on_scroll_event (GdkEventScroll* event)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ThumbBrowserBase::redraw (bool checkfilter)
|
void ThumbBrowserBase::redraw (ThumbBrowserEntryBase* entry)
|
||||||
{
|
{
|
||||||
|
|
||||||
GThreadLock lock;
|
GThreadLock lock;
|
||||||
arrangeFiles(checkfilter);
|
arrangeFiles(entry);
|
||||||
queue_draw();
|
queue_draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,12 +174,13 @@ protected:
|
|||||||
|
|
||||||
int previewHeight;
|
int previewHeight;
|
||||||
int numOfCols;
|
int numOfCols;
|
||||||
|
int lastRowHeight;
|
||||||
|
|
||||||
Arrangement arrangement;
|
Arrangement arrangement;
|
||||||
|
|
||||||
std::set<Glib::ustring> editedFiles;
|
std::set<Glib::ustring> editedFiles;
|
||||||
|
|
||||||
void arrangeFiles (bool checkfilter = true);
|
void arrangeFiles (ThumbBrowserEntryBase* entry = nullptr);
|
||||||
void zoomChanged (bool zoomIn);
|
void zoomChanged (bool zoomIn);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -201,7 +202,7 @@ public:
|
|||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
void on_style_updated () override;
|
void on_style_updated () override;
|
||||||
void redraw (bool checkfilter = true); // arrange files and draw area
|
void redraw (ThumbBrowserEntryBase* entry = nullptr); // arrange files and draw area
|
||||||
void refreshThumbImages (); // refresh thumbnail sizes, re-generate thumbnail images, arrange and draw
|
void refreshThumbImages (); // refresh thumbnail sizes, re-generate thumbnail images, arrange and draw
|
||||||
void refreshQuickThumbImages (); // refresh thumbnail sizes, re-generate thumbnail images, arrange and draw
|
void refreshQuickThumbImages (); // refresh thumbnail sizes, re-generate thumbnail images, arrange and draw
|
||||||
void refreshEditedState (const std::set<Glib::ustring>& efiles);
|
void refreshEditedState (const std::set<Glib::ustring>& efiles);
|
||||||
@ -214,7 +215,7 @@ public:
|
|||||||
void setArrangement (Arrangement a);
|
void setArrangement (Arrangement a);
|
||||||
void enableTabMode(bool enable); // set both thumb sizes and arrangements
|
void enableTabMode(bool enable); // set both thumb sizes and arrangements
|
||||||
|
|
||||||
virtual bool checkFilter (ThumbBrowserEntryBase* entry)
|
virtual bool checkFilter (ThumbBrowserEntryBase* entry) const
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user