Skip to content

Commit

Permalink
Added case-insensitive search
Browse files Browse the repository at this point in the history
Fixed Windows Debug build
  • Loading branch information
ZimM-LostPolygon authored and revmischa committed Apr 8, 2021
1 parent 1a407a8 commit 4184f23
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 5 deletions.
20 changes: 20 additions & 0 deletions src/libprojectM/Common.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include <typeinfo>
#include <cstdarg>
#include <cassert>
#include <locale>

#ifdef _MSC_VER
#define strcasecmp(s, t) _strcmpi(s, t)
Expand Down Expand Up @@ -233,6 +234,25 @@ inline double meanSquaredError(const double & x, const double & y) {
return (x-y)*(x-y);
}

template <typename charT>
struct caseInsensitiveEqual {
caseInsensitiveEqual(const std::locale &loc) : loc_(loc) {}
bool operator()(charT ch1, charT ch2) { return std::toupper(ch1, loc_) == std::toupper(ch2, loc_); }

private:
const std::locale &loc_;
};

template <typename T>
int caseInsensitiveSubstringFind(const T &haystack, const T &needle, const std::locale &loc = std::locale()) {
typename T::const_iterator it = std::search(
haystack.begin(), haystack.end(),
needle.begin(), needle.end(),
caseInsensitiveEqual<typename T::value_type>(loc));
if (it != haystack.end()) return it - haystack.begin();

return std::string::npos;
}

enum PresetRatingType {
FIRST_RATING_TYPE = 0,
Expand Down
2 changes: 1 addition & 1 deletion src/libprojectM/PCM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ void PCM::freePCM()

#ifndef NDEBUG

#include <PresetLoader.hpp>
#include "PresetLoader.hpp"

#define TEST(cond) if (!verify(__FILE__ ": " #cond,cond)) return false
#define TEST2(str,cond) if (!verify(str,cond)) return false
Expand Down
12 changes: 9 additions & 3 deletions src/libprojectM/Renderer/Renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,15 @@ void Renderer::drawText(GLTtext* text, const char* string, GLfloat x, GLfloat y,
void Renderer::drawText(GLTtext* text, const char* string, const char* needle, GLfloat x, GLfloat y, GLfloat scale, int horizontalAlignment = GLT_LEFT, int verticalAlignment = GLT_TOP, float r = 1.0f, float b = 1.0f, float g = 1.0f, float a = 1.0f, bool highlightable = false) {
int offset = x;
std::string str_find = string;
std::string str_needle = needle;
for( size_t pos = 0; ; pos += str_find.length() ) {
// find search term
pos = str_find.find(needle);
pos = caseInsensitiveSubstringFind(str_find, str_needle);

std::string needle_found = str_needle;
if (pos != std::string::npos) {
needle_found = str_find.substr(pos, str_needle.length());
}

// draw everything normal, up to search term.
gltColor(r, g, b, a);
Expand All @@ -133,14 +139,14 @@ void Renderer::drawText(GLTtext* text, const char* string, const char* needle, G
GLfloat textWidth = gltGetTextWidth(text, scale);
offset = offset + textWidth;
gltColor(1.0f, 0.0f, 1.0f, 1.0f);
gltSetText(text, searchText().c_str());
gltSetText(text, needle_found.c_str());
gltDrawText2DAligned(text, offset, y, scale, horizontalAlignment, verticalAlignment);

// draw rest of name, normally
textWidth = gltGetTextWidth(text, scale);
offset = offset + textWidth;
gltColor(r, g, b, a);
gltSetText(text, str_find.substr(pos+searchText().length(),str_find.length()).c_str());
gltSetText(text, str_find.substr(pos+needle_found.length(), str_find.length()).c_str());
gltDrawText2DAligned(text, offset, y, scale, horizontalAlignment, verticalAlignment);
break; // first search hit is useful enough.
}
Expand Down
2 changes: 1 addition & 1 deletion src/libprojectM/projectM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -801,7 +801,7 @@ void projectM::populatePresetMenu()
std::string presetName = renderer->presetName();
int presetIndex = getSearchIndex(presetName);
for(unsigned int i = 0; i < getPlaylistSize(); i++) { // loop over all presets
if (getPresetName(i).find(renderer->searchText()) != std::string::npos) { // if term matches
if (caseInsensitiveSubstringFind(getPresetName(i), renderer->searchText()) != std::string::npos) { // if term matches
if (h < renderer->textMenuPageSize) // limit to just one page, pagination is not needed.
{
h++;
Expand Down

0 comments on commit 4184f23

Please sign in to comment.