@@ -9,6 +9,31 @@ GuiGamelistOptions::GuiGamelistOptions(Window* window, SystemData* system) : Gui
99{
1010 addChild (&mMenu );
1111
12+ // jump to letter
13+ char curChar = getGamelist ()->getCursor ()->getName ()[0 ];
14+ mJumpToLetterList = std::make_shared<LetterList>(mWindow , " JUMP TO LETTER" , false );
15+ for (char c = ' A' ; c <= ' Z' ; c++)
16+ {
17+ mJumpToLetterList ->add (std::string (1 , c), c, c == curChar);
18+ }
19+
20+ ComponentListRow row;
21+ row.addElement (std::make_shared<TextComponent>(mWindow , " JUMP TO LETTER" , Font::get (FONT_SIZE_MEDIUM), 0x777777FF ), true );
22+ row.addElement (mJumpToLetterList , false );
23+ row.input_handler = [&](InputConfig* config, Input input) {
24+ if (config->isMappedTo (" a" , input) && input.value )
25+ {
26+ jumpToLetter ();
27+ return true ;
28+ }
29+ else if (mJumpToLetterList ->input (config, input))
30+ {
31+ return true ;
32+ }
33+ return false ;
34+ };
35+ mMenu .addRow (row);
36+
1237 // sort list by
1338 mListSort = std::make_shared<SortList>(mWindow , " SORT GAMES BY" , false );
1439 for (unsigned int i = 0 ; i < FileSorts::SortTypes.size (); i++)
@@ -20,7 +45,7 @@ GuiGamelistOptions::GuiGamelistOptions(Window* window, SystemData* system) : Gui
2045 mMenu .addWithLabel (" SORT GAMES BY" , mListSort );
2146
2247 // edit game metadata
23- ComponentListRow row;
48+ row. elements . clear () ;
2449 row.addElement (std::make_shared<TextComponent>(mWindow , " EDIT THIS GAME'S METADATA" , Font::get (FONT_SIZE_MEDIUM), 0x777777FF ), true );
2550 row.addElement (makeArrow (mWindow ), false );
2651 row.makeAcceptInputHandler (std::bind (&GuiGamelistOptions::openMetaDataEd, this ));
@@ -57,6 +82,41 @@ void GuiGamelistOptions::openMetaDataEd()
5782 }));
5883}
5984
85+ void GuiGamelistOptions::jumpToLetter ()
86+ {
87+ char letter = mJumpToLetterList ->getSelected ();
88+ IGameListView* gamelist = getGamelist ();
89+
90+ // this is a really shitty way to get a list of files
91+ const std::vector<FileData*>& files = gamelist->getCursor ()->getParent ()->getChildren ();
92+
93+ long min = 0 ;
94+ long max = files.size () - 1 ;
95+ long mid = 0 ;
96+
97+ while (max >= min)
98+ {
99+ mid = ((max - min) / 2 ) + min;
100+
101+ // game somehow has no first character to check
102+ if (files.at (mid)->getName ().empty ())
103+ continue ;
104+
105+ char checkLetter = toupper (files.at (mid)->getName ()[0 ]);
106+
107+ if (checkLetter < letter)
108+ min = mid + 1 ;
109+ else if (checkLetter > letter)
110+ max = mid - 1 ;
111+ else
112+ break ; // exact match found
113+ }
114+
115+ gamelist->setCursor (files.at (mid));
116+
117+ delete this ;
118+ }
119+
60120bool GuiGamelistOptions::input (InputConfig* config, Input input)
61121{
62122 if ((config->isMappedTo (" b" , input) || config->isMappedTo (" select" , input)) && input.value )
0 commit comments