Skip to content

Commit

Permalink
Add Korean Keyboard & 4th Keyboard Layout & Unicode support for "Jump…
Browse files Browse the repository at this point in the history
… to game beginning with the letter"
  • Loading branch information
bulzipke committed Feb 2, 2025
1 parent 8e04dca commit 85ad64d
Show file tree
Hide file tree
Showing 10 changed files with 558 additions and 135 deletions.
48 changes: 40 additions & 8 deletions es-app/src/guis/GuiGamelistOptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,13 +100,29 @@ GuiGamelistOptions::GuiGamelistOptions(Window* window, IGameListView* gamelist,
{
mJumpToLetterList = std::make_shared<LetterList>(mWindow, _("JUMP TO GAME BEGINNING WITH THE LETTER"), false);

char curChar = (char)toupper(getGamelist()->getCursor()->getName()[0]);
const std::string& cursorName = getGamelist()->getCursor()->getName();
std::string curChar;

if (std::find(letters.begin(), letters.end(), std::string(1, curChar)) == letters.end())
curChar = letters.at(0)[0];
if (Utils::String::isKorean(cursorName.c_str()))
{
const char* koreanLetter = nullptr;

std::string nameChar = cursorName.substr(0, 3);
if (!Utils::String::splitHangulSyllable(nameChar.c_str(), &koreanLetter) || !koreanLetter)
curChar = std::string(letters.at(0)); // Korean supports chosung search only. set default.
else
curChar = std::string(koreanLetter, 3);
}
else
{
curChar = std::string(1, toupper(cursorName[0]));
}

for (auto letter : letters)
mJumpToLetterList->add(letter, letter[0], letter[0] == curChar);
if (std::find(letters.begin(), letters.end(), curChar) == letters.end())
curChar = letters.at(0);

for (const auto& letter : letters)
mJumpToLetterList->add(letter, letter, letter == curChar);

row.addElement(std::make_shared<TextComponent>(mWindow, _("JUMP TO GAME BEGINNING WITH THE LETTER"), theme->Text.font, theme->Text.color), true);
row.addElement(mJumpToLetterList, false);
Expand Down Expand Up @@ -487,7 +503,7 @@ void GuiGamelistOptions::openMetaDataEd()

void GuiGamelistOptions::jumpToLetter()
{
char letter = mJumpToLetterList->getSelected();
std::string letter = mJumpToLetterList->getSelected();
IGameListView* gamelist = getGamelist();

if (mListSort->getSelected() != 0)
Expand All @@ -505,11 +521,27 @@ void GuiGamelistOptions::jumpToLetter()
auto files = gamelist->getFileDataEntries();
for (int i = files.size() - 1; i >= 0; i--)
{
auto name = files.at(i)->getName();
const std::string& name = files.at(i)->getName();
if (name.empty())
continue;

char checkLetter = (char)toupper(name[0]);
std::string checkLetter;

if (Utils::String::isKorean(name.c_str()))
{
const char* koreanLetter = nullptr;

std::string nameChar = name.substr(0, 3);
if (!Utils::String::splitHangulSyllable(nameChar.c_str(), &koreanLetter) || !koreanLetter)
continue;

checkLetter = std::string(koreanLetter, 3);
}
else
{
checkLetter = std::string(1, toupper(name[0]));
}

if (letterIndex >= 0 && checkLetter != letter)
break;

Expand Down
2 changes: 1 addition & 1 deletion es-app/src/guis/GuiGamelistOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class GuiGamelistOptions : public GuiComponent

MenuComponent mMenu;

typedef OptionListComponent<char> LetterList;
typedef OptionListComponent<std::string> LetterList;
std::shared_ptr<LetterList> mJumpToLetterList;

typedef OptionListComponent<unsigned int> SortList;
Expand Down
150 changes: 89 additions & 61 deletions es-app/src/views/gamelist/ISimpleGameListView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -481,100 +481,128 @@ void ISimpleGameListView::moveToRandomGame()
setCursor(list.at(target));
}

bool ISimpleGameListView::moveToLetter(char letter)
bool ISimpleGameListView::moveToLetter(const std::string& letter)
{

auto files = getFileDataEntries();
long letterIndex = -1;
long letterIndex = -1;

for (int i = files.size() - 1; i >= 0; i--)
{
auto name = files.at(i)->getName();
if (name.empty())
continue;

char checkLetter = (char)toupper(name[0]);
if (letterIndex >= 0 && checkLetter != letter)
break;
{
const std::string& name = files.at(i)->getName();
if (name.empty())
continue;

if (checkLetter == letter)
letterIndex = i;
}
std::string checkLetter;

if (letterIndex >= 0) {
setCursor(files.at(letterIndex));
return 1;
}
if (Utils::String::isKorean(name.c_str()))
{
const char* koreanLetter = nullptr;

return 0;
}
std::string nameChar = name.substr(0, 3);
if (!Utils::String::splitHangulSyllable(nameChar.c_str(), &koreanLetter) || !koreanLetter)
continue; // Korean supports chosung search only.
else
checkLetter = std::string(koreanLetter, 3);
}
else
{
checkLetter = std::string(1, toupper(name[0]));
}

void ISimpleGameListView::moveToNextLetter()
{
std::vector<std::string> letters = getEntriesLetters();
if (letters.empty())
return;
if (letterIndex >= 0 && checkLetter != letter)
break;

FileData* game = getCursor();
if (game == nullptr) {
return;
if (checkLetter == letter)
letterIndex = i;
}

auto namecurrent = game->getName();
char curChar = (char)toupper(namecurrent[0]);

auto it = std::find(letters.begin(), letters.end(), std::string(1, curChar));
if (it != letters.end()) {
int index = it - letters.begin();
index++;
if (index >= letters.size())
index = 0;
char letter = letters.at(index)[0];
moveToLetter(letter);
if (letterIndex >= 0) {
setCursor(files.at(letterIndex));
return true;
}

return false;
}

void ISimpleGameListView::moveToPreviousLetter()
void ISimpleGameListView::moveToLetterByOffset(int offset)
{

std::vector<std::string> letters = getEntriesLetters();
if (letters.empty())
std::vector<std::string> letters = getEntriesLetters();
if (letters.empty())
return;

FileData* game = getCursor();
if (game == nullptr) {
if (game == nullptr)
return;
}

auto namecurrent = game->getName();
char curChar = (char)toupper(namecurrent[0]);
const std::string& namecurrent = game->getName();
std::string curLetter;

if (Utils::String::isKorean(namecurrent.c_str()))
{
const char* koreanLetter = nullptr;

auto it = std::find(letters.begin(), letters.end(), std::string(1, curChar));
if (it != letters.end()) {
int index = it - letters.begin();
index--;
std::string nameChar = namecurrent.substr(0, 3);
if (!Utils::String::splitHangulSyllable(nameChar.c_str(), &koreanLetter) || !koreanLetter)
curLetter = std::string(letters.at(0)); // Korean supports chosung search only. set default.
else
curLetter = std::string(koreanLetter, 3);
}
else
{
curLetter = std::string(1, toupper(namecurrent[0]));
}

auto it = std::find(letters.begin(), letters.end(), curLetter);
if (it != letters.end())
{
int index = std::distance(letters.begin(), it) + offset;
if (index < 0)
index = letters.size()-1;
index = letters.size() - 1;
else if (index >= letters.size())
index = 0;

char letter = letters.at(index)[0];
moveToLetter(letter);
moveToLetter(letters.at(index));
}
}

void ISimpleGameListView::moveToNextLetter()
{
moveToLetterByOffset(1);
}

void ISimpleGameListView::moveToPreviousLetter()
{
moveToLetterByOffset(-1);
}

std::vector<std::string> ISimpleGameListView::getEntriesLetters()
{
std::set<std::string> setOfLetters;

for (auto file : getFileDataEntries())
if (file->getType() == GAME)
setOfLetters.insert(std::string(1, toupper(file->getName()[0])));
for (auto file : getFileDataEntries())
{
if (file->getType() != GAME)
continue;

const std::string& name = file->getName();

if (Utils::String::isKorean(name.c_str()))
{
const char* koreanLetter = nullptr;

std::vector<std::string> letters;
std::string nameChar = name.substr(0, 3);
if (!Utils::String::splitHangulSyllable(nameChar.c_str(), &koreanLetter) || !koreanLetter)
continue;

for (const auto letter : setOfLetters)
letters.push_back(letter);
setOfLetters.insert(std::string(koreanLetter, 3));
}
else
{
setOfLetters.insert(std::string(1, toupper(name[0])));
}
}

std::sort(letters.begin(), letters.end());
std::vector<std::string> letters(setOfLetters.begin(), setOfLetters.end());
return letters;
}

Expand Down
3 changes: 2 additions & 1 deletion es-app/src/views/gamelist/ISimpleGameListView.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ class ISimpleGameListView : public IGameListView
void closePopupContext();

virtual void moveToRandomGame();
virtual bool moveToLetter(char letter);
virtual bool moveToLetter(const std::string& letter);
virtual void moveToLetterByOffset(int offset);
virtual void moveToNextLetter();
virtual void moveToPreviousLetter();

Expand Down
16 changes: 11 additions & 5 deletions es-core/src/components/TextEditComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,20 +67,26 @@ std::string TextEditComponent::getValue() const

void TextEditComponent::textInput(const char* text)
{
if(mEditing)
if (mEditing)
{
mCursorRepeatDir = 0;
if(text[0] == '\b')
if (text[0] == '\b')
{
if(mCursor > 0)
if (mCursor > 0)
{
size_t newCursor = Utils::String::prevCursor(mText, mCursor);
mText.erase(mText.begin() + newCursor, mText.begin() + mCursor);
mCursor = (unsigned int)newCursor;
}
}else{
}
else if (mCursor > 2 && Utils::String::isKorean(text) && Utils::String::isKorean(mText.substr(mCursor - 3, 3).c_str()))
{
Utils::String::koreanTextInput(text, mText, mCursor);
}
else {
mText.insert(mCursor, text);
mCursor += (unsigned int)strlen(text);
size_t newCursor = Utils::String::nextCursor(mText, mCursor);
mCursor = (unsigned int)newCursor;
}
}

Expand Down
Loading

0 comments on commit 85ad64d

Please sign in to comment.