mirror of
https://github.com/wiidev/usbloadergx.git
synced 2024-11-04 18:45:05 +01:00
Searchengine changed: now find games, that hath the search string in it.
e.G. "SPOR" find "ea SPORts", "mario SPORts mix", "SPORe heros" and so on.
This commit is contained in:
parent
baff754740
commit
164889c917
@ -2,8 +2,8 @@
|
||||
<app version="1">
|
||||
<name> USB Loader GX</name>
|
||||
<coder>USB Loader GX Team</coder>
|
||||
<version>2.3 r1126</version>
|
||||
<release_date>201111081925</release_date>
|
||||
<version>2.3 r1127</version>
|
||||
<release_date>201111111858</release_date>
|
||||
<!-- // remove this line to enable arguments
|
||||
<arguments>
|
||||
<arg>--ios=250</arg>
|
||||
|
@ -29,7 +29,7 @@ class cSearchButton
|
||||
|
||||
};
|
||||
|
||||
GuiSearchBar::GuiSearchBar(const wchar_t *SearchChars) :
|
||||
GuiSearchBar::GuiSearchBar(const std::set<wchar_t> &SearchChars) :
|
||||
inSide(0), text((char *) NULL, 22, ( GXColor )
|
||||
{ 0, 0, 0, 255}), buttons(0),
|
||||
keyImageData(Resources::GetFile("keyboard_key.png"), Resources::GetFileSize("keyboard_key.png")),
|
||||
@ -39,24 +39,24 @@ GuiSearchBar::GuiSearchBar(const wchar_t *SearchChars) :
|
||||
trigB.SetButtonOnlyTrigger(-1, WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_B, PAD_BUTTON_B);
|
||||
SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE);
|
||||
|
||||
cnt = wcslen(SearchChars);
|
||||
cnt = SearchChars.size();
|
||||
buttons = new cSearchButton*[cnt];
|
||||
|
||||
wchar_t charstr[2] = { 0, 0 };
|
||||
int lines = (cnt + 9) / 10;
|
||||
int buttonsPerLine = (cnt + lines - 1) / lines;
|
||||
width = 10 + buttonsPerLine * 42 + 10;
|
||||
int x_start = 10, x = 0, y_start = 10 + 42, y = 0;
|
||||
if (width < 200)
|
||||
int i = 0, x_start = 10, x = 0, y_start = 10 + 42, y = 0;
|
||||
if (width < 320)
|
||||
{
|
||||
x_start += (200 - width) >> 1;
|
||||
width = 200;
|
||||
x_start += (320 - width) >> 1;
|
||||
width = 320;
|
||||
}
|
||||
for (int i = 0; i < cnt; i++, x++)
|
||||
for (std::set<wchar_t>::iterator it=SearchChars.begin() ; it != SearchChars.end(); it++, i++, x++)
|
||||
{
|
||||
if (x >= buttonsPerLine) x = 0;
|
||||
if (x == 0) y++;
|
||||
charstr[0] = SearchChars[i];
|
||||
charstr[0] = *it;
|
||||
buttons[i] = new cSearchButton(charstr, &keyImageData, &keyOverImageData, x_start + x * 42, y_start - 42 + y
|
||||
* 42, &trig, btnSoundOver, btnSoundClick);
|
||||
this->Append(&(buttons[i]->button));
|
||||
|
@ -1,13 +1,14 @@
|
||||
#ifndef GUI_SEARCHBAR_H_
|
||||
#define GUI_SEARCHBAR_H_
|
||||
#include "gui.h"
|
||||
#include <set>
|
||||
|
||||
class cSearchButton;
|
||||
|
||||
class GuiSearchBar: public GuiWindow
|
||||
{
|
||||
public:
|
||||
GuiSearchBar(const wchar_t *SearchChars);
|
||||
GuiSearchBar(const std::set<wchar_t> &SearchChars);
|
||||
virtual ~GuiSearchBar();
|
||||
void Draw();
|
||||
void Update(GuiTrigger * t);
|
||||
|
@ -908,13 +908,39 @@ int GameBrowseMenu::MainLoop()
|
||||
{
|
||||
if (searchChar > 27) //! Character clicked
|
||||
{
|
||||
int len = gameList.GetCurrentFilter() ? wcslen(gameList.GetCurrentFilter()) : 0;
|
||||
wchar_t newFilter[len + 2];
|
||||
if (gameList.GetCurrentFilter()) wcscpy(newFilter, gameList.GetCurrentFilter());
|
||||
newFilter[len] = searchChar;
|
||||
newFilter[len + 1] = 0;
|
||||
for(;;)
|
||||
{
|
||||
int len = wcslen(gameList.GetCurrentFilter());
|
||||
wchar_t newFilter[len + 2];
|
||||
wcscpy(newFilter, gameList.GetCurrentFilter());
|
||||
newFilter[len] = searchChar;
|
||||
newFilter[len + 1] = 0;
|
||||
|
||||
gameList.FilterList(newFilter);
|
||||
gameList.FilterList(newFilter);
|
||||
if(gameList.GetAvailableSearchChars().size() != 1)
|
||||
break;
|
||||
searchChar = *gameList.GetAvailableSearchChars().begin();
|
||||
}
|
||||
bool autoClose = false;
|
||||
switch(Settings.gameDisplay)
|
||||
{
|
||||
case LIST_MODE:
|
||||
autoClose = gameList.size()<=9;
|
||||
break;
|
||||
case CAROUSEL_MODE:
|
||||
autoClose = gameList.size()<=5;
|
||||
break;
|
||||
case GRID_MODE:
|
||||
autoClose = gameList.size()<=3;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if(autoClose) // Close Searchwindow when less than 5 Games found
|
||||
{
|
||||
show_searchwindow = false;
|
||||
searchBtn->StopEffect();
|
||||
}
|
||||
}
|
||||
else if (searchChar == 27) //! Close
|
||||
{
|
||||
@ -930,11 +956,16 @@ int GameBrowseMenu::MainLoop()
|
||||
{
|
||||
int len = wcslen(gameList.GetCurrentFilter());
|
||||
wchar_t newFilter[len + 1];
|
||||
if (gameList.GetCurrentFilter()) wcscpy(newFilter, gameList.GetCurrentFilter());
|
||||
newFilter[len > 0 ? len - 1 : 0] = 0;
|
||||
gameList.FilterList(newFilter);
|
||||
if(len == 1)
|
||||
Settings.gridRows = GridRowsPreSearch; //! restore old rows amount so we don't stay on one row
|
||||
wcscpy(newFilter, gameList.GetCurrentFilter());
|
||||
int old_game_count = gameList.size();
|
||||
for(; len > 0; len--)
|
||||
{
|
||||
newFilter[len - 1] = 0; // remove last char
|
||||
if(len == 1)
|
||||
Settings.gridRows = GridRowsPreSearch; //! restore old rows amount so we don't stay on one row
|
||||
if(gameList.FilterList(newFilter) != old_game_count)
|
||||
break;
|
||||
}
|
||||
}
|
||||
ReloadBrowser();
|
||||
return MENU_NONE;
|
||||
|
@ -181,14 +181,6 @@ int GameList::ReadGameList()
|
||||
return LoadUnfiltered();
|
||||
}
|
||||
|
||||
static bool WCharSortCallback(const wchar_t char1, const wchar_t char2)
|
||||
{
|
||||
if (char2 == 0) return true;
|
||||
if (char1 == 0) return false;
|
||||
|
||||
return char2 > char1;
|
||||
}
|
||||
|
||||
int GameList::FilterList(const wchar_t * gameFilter)
|
||||
{
|
||||
if (FullGameList.size() == 0) ReadGameList();
|
||||
@ -251,22 +243,30 @@ int GameList::FilterList(const wchar_t * gameFilter)
|
||||
if(n == Settings.EnabledCategories.size()) continue;
|
||||
|
||||
wchar_t *gameName = charToWideChar(GameTitles.GetTitle(header));
|
||||
if (gameName && *GameFilter.c_str())
|
||||
{
|
||||
if (wcsnicmp(gameName, GameFilter.c_str(), GameFilter.size()) != 0)
|
||||
{
|
||||
delete [] gameName;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (gameName)
|
||||
{
|
||||
if (wcslen(gameName) > GameFilter.size() &&
|
||||
AvailableSearchChars.find(towupper(gameName[GameFilter.size()])) == std::string::npos &&
|
||||
AvailableSearchChars.find(towlower(gameName[GameFilter.size()])) == std::string::npos)
|
||||
if ( GameFilter.size() ) // has Filter
|
||||
{
|
||||
AvailableSearchChars.push_back(gameName[GameFilter.size()]);
|
||||
bool found = false;
|
||||
wchar_t *s1 = gameName, *s2;
|
||||
while( (s2 = wcscasestr(s1, GameFilter.c_str())) ) // search filter in gameName
|
||||
{
|
||||
found = true;
|
||||
wchar_t ch = towupper(s2[GameFilter.size()]);
|
||||
if(ch) AvailableSearchChars.insert(ch);
|
||||
s1++; // try search filter in gameName more times
|
||||
}
|
||||
if(!found)
|
||||
{
|
||||
delete [] gameName;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else // no Filter -> makes all chars as aviable
|
||||
{
|
||||
for(wchar_t *ch = gameName; *ch; ch++)
|
||||
if(*ch >= '@') // limit chars by empty filter
|
||||
AvailableSearchChars.insert(towupper(*ch));
|
||||
}
|
||||
|
||||
delete [] gameName;
|
||||
@ -277,7 +277,7 @@ int GameList::FilterList(const wchar_t * gameFilter)
|
||||
|
||||
NewTitles::Instance()->Save();
|
||||
|
||||
AvailableSearchChars.push_back(L'\0');
|
||||
if (FilteredList.size() < 2)
|
||||
|
||||
if (FilteredList.size() < 2)
|
||||
AvailableSearchChars.clear();
|
||||
@ -305,12 +305,9 @@ int GameList::LoadUnfiltered()
|
||||
wchar_t *gameName = charToWideChar(GameTitles.GetTitle(header));
|
||||
if (gameName)
|
||||
{
|
||||
if (wcslen(gameName) > GameFilter.size() &&
|
||||
AvailableSearchChars.find(towupper(gameName[GameFilter.size()])) == std::string::npos &&
|
||||
AvailableSearchChars.find(towlower(gameName[GameFilter.size()])) == std::string::npos)
|
||||
{
|
||||
AvailableSearchChars.push_back(gameName[GameFilter.size()]);
|
||||
}
|
||||
for(wchar_t *ch = gameName; *ch; ch++)
|
||||
if(*ch >= '@') // limit chars by unfiltered list
|
||||
AvailableSearchChars.insert(towupper(*ch));
|
||||
|
||||
delete [] gameName;
|
||||
}
|
||||
@ -320,8 +317,6 @@ int GameList::LoadUnfiltered()
|
||||
|
||||
NewTitles::Instance()->Save();
|
||||
|
||||
AvailableSearchChars.push_back(L'\0');
|
||||
|
||||
if (FilteredList.size() < 2)
|
||||
AvailableSearchChars.clear();
|
||||
|
||||
@ -350,10 +345,6 @@ void GameList::SortList()
|
||||
{
|
||||
std::sort(FilteredList.begin(), FilteredList.end(), NameSortCallback);
|
||||
}
|
||||
|
||||
if (AvailableSearchChars.size() > 1)
|
||||
std::sort(AvailableSearchChars.begin(), AvailableSearchChars.end(), WCharSortCallback);
|
||||
|
||||
}
|
||||
|
||||
bool GameList::NameSortCallback(const struct discHdr *a, const struct discHdr *b)
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define GAME_LIST_H_
|
||||
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include "Controls/DeviceHandler.hpp"
|
||||
#include "wstring.hpp"
|
||||
#include "usbloader/disc.h"
|
||||
@ -19,7 +20,7 @@ class GameList
|
||||
struct discHdr * operator[](int i) const { if (i < 0 || i >= (int) FilteredList.size()) return NULL; return FilteredList[i]; }
|
||||
struct discHdr * GetDiscHeader(const char * gameID) const;
|
||||
const wchar_t * GetCurrentFilter() const { return GameFilter.c_str(); }
|
||||
const wchar_t * GetAvailableSearchChars() const { return AvailableSearchChars.c_str(); }
|
||||
const std::set<wchar_t> &GetAvailableSearchChars() const { return AvailableSearchChars; }
|
||||
void SortList();
|
||||
void clear();
|
||||
bool operator!() const { return (FullGameList.size() == 0); }
|
||||
@ -41,7 +42,7 @@ class GameList
|
||||
static bool RankingSortCallback(const struct discHdr *a, const struct discHdr *b);
|
||||
static bool PlayersSortCallback(const struct discHdr *a, const struct discHdr *b);
|
||||
|
||||
wString AvailableSearchChars;
|
||||
std::set<wchar_t> AvailableSearchChars;
|
||||
wString GameFilter;
|
||||
int selectedGame;
|
||||
std::vector<struct discHdr *> FilteredList;
|
||||
|
@ -147,16 +147,15 @@ size_t utf8Len(const char *s)
|
||||
return len;
|
||||
}
|
||||
|
||||
int wcsnicmp(const wchar_t *s1, const wchar_t *s2, int len)
|
||||
wchar_t *wcscasestr(const wchar_t *s1, const wchar_t *s2)
|
||||
{
|
||||
if (len <= 0) return (0);
|
||||
|
||||
do
|
||||
{
|
||||
int r = towupper(*s1) - towupper(*s2++);
|
||||
if (r) return r;
|
||||
if (*s1++ == 0) break;
|
||||
} while (--len != 0);
|
||||
|
||||
return (0);
|
||||
if(*s2==0) return (wchar_t *)s1;
|
||||
int s1_len = wcslen(s1);
|
||||
int s2_len = wcslen(s2);
|
||||
if(s1_len < s2_len) return 0;
|
||||
const wchar_t *end = &s1[s1_len-s2_len];
|
||||
for(wchar_t *s=(wchar_t *)s1; s<=end; s++)
|
||||
if(wcsncasecmp(s, s2, s2_len)==0)
|
||||
return s;
|
||||
return 0;
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ class wString: public std::basic_string<wchar_t, std::char_traits<wchar_t>, std:
|
||||
};
|
||||
|
||||
size_t utf8Len(const char *s);
|
||||
int wcsnicmp(const wchar_t *s1, const wchar_t *s2, int len);
|
||||
|
||||
wchar_t *wcscasestr(const wchar_t *s1, const wchar_t *s2);
|
||||
|
||||
#endif // !defined(__WSTRING_HPP)
|
||||
|
Loading…
Reference in New Issue
Block a user