@@ -212,6 +212,7 @@ void GameSettingsScreen::CreateViews() {
212
212
auto co = GetI18NCategory (" Controls" );
213
213
auto a = GetI18NCategory (" Audio" );
214
214
auto sa = GetI18NCategory (" Savedata" );
215
+ auto se = GetI18NCategory (" Search" );
215
216
auto sy = GetI18NCategory (" System" );
216
217
auto n = GetI18NCategory (" Networking" );
217
218
auto ms = GetI18NCategory (" MainSettings" );
@@ -221,20 +222,21 @@ void GameSettingsScreen::CreateViews() {
221
222
222
223
root_ = new AnchorLayout (new LayoutParams (FILL_PARENT, FILL_PARENT));
223
224
224
- TabHolder *tabHolder;
225
225
if (vertical) {
226
226
LinearLayout *verticalLayout = new LinearLayout (ORIENT_VERTICAL, new LayoutParams (FILL_PARENT, FILL_PARENT));
227
- tabHolder = new TabHolder (ORIENT_HORIZONTAL, 200 , new LinearLayoutParams (1 .0f ));
228
- verticalLayout->Add (tabHolder );
227
+ tabHolder_ = new TabHolder (ORIENT_HORIZONTAL, 200 , new LinearLayoutParams (1 .0f ));
228
+ verticalLayout->Add (tabHolder_ );
229
229
verticalLayout->Add (new Choice (di->T (" Back" ), " " , false , new LinearLayoutParams (FILL_PARENT, WRAP_CONTENT, 0 .0f , Margins (0 ))))->OnClick .Handle <UIScreen>(this , &UIScreen::OnBack);
230
230
root_->Add (verticalLayout);
231
231
} else {
232
- tabHolder = new TabHolder (ORIENT_VERTICAL, 200 , new AnchorLayoutParams (10 , 0 , 10 , 0 , false ));
233
- root_->Add (tabHolder );
232
+ tabHolder_ = new TabHolder (ORIENT_VERTICAL, 200 , new AnchorLayoutParams (10 , 0 , 10 , 0 , false ));
233
+ root_->Add (tabHolder_ );
234
234
AddStandardBack (root_);
235
235
}
236
- tabHolder->SetTag (" GameSettings" );
237
- root_->SetDefaultFocusView (tabHolder);
236
+ tabHolder_->SetTag (" GameSettings" );
237
+ root_->SetDefaultFocusView (tabHolder_);
238
+ settingTabContents_.clear ();
239
+ settingTabFilterNotices_.clear ();
238
240
239
241
float leftSide = 40 .0f ;
240
242
if (!vertical) {
@@ -252,12 +254,7 @@ void GameSettingsScreen::CreateViews() {
252
254
// TODO: These currently point to global settings, not game specific ones.
253
255
254
256
// Graphics
255
- ViewGroup *graphicsSettingsScroll = new ScrollView (ORIENT_VERTICAL, new LinearLayoutParams (FILL_PARENT, FILL_PARENT));
256
- graphicsSettingsScroll->SetTag (" GameSettingsGraphics" );
257
- LinearLayout *graphicsSettings = new LinearLayoutList (ORIENT_VERTICAL);
258
- graphicsSettings->SetSpacing (0 );
259
- graphicsSettingsScroll->Add (graphicsSettings);
260
- tabHolder->AddTab (ms->T (" Graphics" ), graphicsSettingsScroll);
257
+ LinearLayout *graphicsSettings = AddTab (" GameSettingsGraphics" , ms->T (" Graphics" ));
261
258
262
259
graphicsSettings->Add (new ItemHeader (gr->T (" Rendering Mode" )));
263
260
@@ -629,15 +626,9 @@ void GameSettingsScreen::CreateViews() {
629
626
dump->SetEnabled (false );
630
627
631
628
// Audio
632
- ViewGroup *audioSettingsScroll = new ScrollView (ORIENT_VERTICAL, new LinearLayoutParams (FILL_PARENT, FILL_PARENT));
633
- audioSettingsScroll->SetTag (" GameSettingsAudio" );
634
- LinearLayout *audioSettings = new LinearLayoutList (ORIENT_VERTICAL);
635
- audioSettings->SetSpacing (0 );
636
- audioSettingsScroll->Add (audioSettings);
637
- tabHolder->AddTab (ms->T (" Audio" ), audioSettingsScroll);
629
+ LinearLayout *audioSettings = AddTab (" GameSettingsAudio" , ms->T (" Audio" ));
638
630
639
631
audioSettings->Add (new ItemHeader (ms->T (" Audio" )));
640
-
641
632
audioSettings->Add (new CheckBox (&g_Config.bEnableSound , a->T (" Enable Sound" )));
642
633
643
634
PopupSliderChoice *volume = audioSettings->Add (new PopupSliderChoice (&g_Config.iGlobalVolume , VOLUME_OFF, VOLUME_FULL, a->T (" Global volume" ), screenManager ()));
@@ -695,12 +686,8 @@ void GameSettingsScreen::CreateViews() {
695
686
}
696
687
697
688
// Control
698
- ViewGroup *controlsSettingsScroll = new ScrollView (ORIENT_VERTICAL, new LinearLayoutParams (FILL_PARENT, FILL_PARENT));
699
- controlsSettingsScroll->SetTag (" GameSettingsControls" );
700
- LinearLayout *controlsSettings = new LinearLayoutList (ORIENT_VERTICAL);
701
- controlsSettings->SetSpacing (0 );
702
- controlsSettingsScroll->Add (controlsSettings);
703
- tabHolder->AddTab (ms->T (" Controls" ), controlsSettingsScroll);
689
+ LinearLayout *controlsSettings = AddTab (" GameSettingsControls" , ms->T (" Controls" ));
690
+
704
691
controlsSettings->Add (new ItemHeader (ms->T (" Controls" )));
705
692
controlsSettings->Add (new Choice (co->T (" Control Mapping" )))->OnClick .Handle (this , &GameSettingsScreen::OnControlMapping);
706
693
controlsSettings->Add (new Choice (co->T (" Calibrate Analog Stick" )))->OnClick .Handle (this , &GameSettingsScreen::OnCalibrateAnalogs);
@@ -795,12 +782,7 @@ void GameSettingsScreen::CreateViews() {
795
782
controlsSettings->Add (new PopupSliderChoiceFloat (&g_Config.fMouseSmoothing , 0 .0f , 0 .95f , co->T (" Mouse smoothing" ), 0 .05f , screenManager (), " x" ))->SetEnabledPtr (&g_Config.bMouseControl );
796
783
#endif
797
784
798
- ViewGroup *networkingSettingsScroll = new ScrollView (ORIENT_VERTICAL, new LinearLayoutParams (FILL_PARENT, FILL_PARENT));
799
- networkingSettingsScroll->SetTag (" GameSettingsNetworking" );
800
- LinearLayout *networkingSettings = new LinearLayoutList (ORIENT_VERTICAL);
801
- networkingSettings->SetSpacing (0 );
802
- networkingSettingsScroll->Add (networkingSettings);
803
- tabHolder->AddTab (ms->T (" Networking" ), networkingSettingsScroll);
785
+ LinearLayout *networkingSettings = AddTab (" GameSettingsNetworking" , ms->T (" Networking" ));
804
786
805
787
networkingSettings->Add (new ItemHeader (ms->T (" Networking" )));
806
788
@@ -866,24 +848,21 @@ void GameSettingsScreen::CreateViews() {
866
848
#endif
867
849
868
850
#if defined(USING_QT_UI) || PPSSPP_PLATFORM(ANDROID)
869
- qc1->OnClick .Handle (this , &GameSettingsScreen::OnChangeQuickChat0);
870
- qc2->OnClick .Handle (this , &GameSettingsScreen::OnChangeQuickChat1);
871
- qc3->OnClick .Handle (this , &GameSettingsScreen::OnChangeQuickChat2);
872
- qc4->OnClick .Handle (this , &GameSettingsScreen::OnChangeQuickChat3);
873
- qc5->OnClick .Handle (this , &GameSettingsScreen::OnChangeQuickChat4);
851
+ if (System_GetPropertyBool (SYSPROP_HAS_KEYBOARD)) {
852
+ qc1->OnClick .Handle (this , &GameSettingsScreen::OnChangeQuickChat0);
853
+ qc2->OnClick .Handle (this , &GameSettingsScreen::OnChangeQuickChat1);
854
+ qc3->OnClick .Handle (this , &GameSettingsScreen::OnChangeQuickChat2);
855
+ qc4->OnClick .Handle (this , &GameSettingsScreen::OnChangeQuickChat3);
856
+ qc5->OnClick .Handle (this , &GameSettingsScreen::OnChangeQuickChat4);
857
+ }
874
858
#endif
875
859
876
860
networkingSettings->Add (new ItemHeader (n->T (" Misc" , " Misc (default = compatibility)" )));
877
861
networkingSettings->Add (new PopupSliderChoice (&g_Config.iPortOffset , 0 , 60000 , n->T (" Port offset" , " Port offset (0 = PSP compatibility)" ), 100 , screenManager ()));
878
862
networkingSettings->Add (new PopupSliderChoice (&g_Config.iMinTimeout , 0 , 15000 , n->T (" Minimum Timeout" , " Minimum Timeout (override in ms, 0 = default)" ), 50 , screenManager ()));
879
863
networkingSettings->Add (new CheckBox (&g_Config.bForcedFirstConnect , n->T (" Forced First Connect" , " Forced First Connect (faster Connect)" )));
880
864
881
- ViewGroup *toolsScroll = new ScrollView (ORIENT_VERTICAL, new LinearLayoutParams (FILL_PARENT, FILL_PARENT));
882
- toolsScroll->SetTag (" GameSettingsTools" );
883
- LinearLayout *tools = new LinearLayoutList (ORIENT_VERTICAL);
884
- tools->SetSpacing (0 );
885
- toolsScroll->Add (tools);
886
- tabHolder->AddTab (ms->T (" Tools" ), toolsScroll);
865
+ LinearLayout *tools = AddTab (" GameSettingsTools" , ms->T (" Tools" ));
887
866
888
867
tools->Add (new ItemHeader (ms->T (" Tools" )));
889
868
// These were moved here so use the wrong translation objects, to avoid having to change all inis... This isn't a sustainable situation :P
@@ -893,12 +872,7 @@ void GameSettingsScreen::CreateViews() {
893
872
tools->Add (new Choice (ri->T (" Remote disc streaming" )))->OnClick .Handle (this , &GameSettingsScreen::OnRemoteISO);
894
873
895
874
// System
896
- ViewGroup *systemSettingsScroll = new ScrollView (ORIENT_VERTICAL, new LinearLayoutParams (FILL_PARENT, FILL_PARENT));
897
- systemSettingsScroll->SetTag (" GameSettingsSystem" );
898
- LinearLayout *systemSettings = new LinearLayoutList (ORIENT_VERTICAL);
899
- systemSettings->SetSpacing (0 );
900
- systemSettingsScroll->Add (systemSettings);
901
- tabHolder->AddTab (ms->T (" System" ), systemSettingsScroll);
875
+ LinearLayout *systemSettings = AddTab (" GameSettingsSystem" , ms->T (" System" ));
902
876
903
877
systemSettings->Add (new ItemHeader (sy->T (" UI" )));
904
878
systemSettings->Add (new Choice (dev->T (" Language" , " Language" )))->OnClick .Handle (this , &GameSettingsScreen::OnLanguage);
@@ -1027,9 +1001,8 @@ void GameSettingsScreen::CreateViews() {
1027
1001
systemSettings->Add (new CheckBox (&g_Config.bEnableStateUndo , sy->T (" Savestate slot backups" )));
1028
1002
static const char *autoLoadSaveStateChoices[] = { " Off" , " Oldest Save" , " Newest Save" , " Slot 1" , " Slot 2" , " Slot 3" , " Slot 4" , " Slot 5" };
1029
1003
systemSettings->Add (new PopupMultiChoice (&g_Config.iAutoLoadSaveState , sy->T (" Auto Load Savestate" ), autoLoadSaveStateChoices, 0 , ARRAY_SIZE (autoLoadSaveStateChoices), sy->GetName (), screenManager ()));
1030
- #if defined(USING_WIN_UI) || defined(USING_QT_UI) || PPSSPP_PLATFORM(ANDROID)
1031
- systemSettings->Add (new CheckBox (&g_Config.bBypassOSKWithKeyboard , sy->T (" Use system native keyboard" )));
1032
- #endif
1004
+ if (System_GetPropertyBool (SYSPROP_HAS_KEYBOARD))
1005
+ systemSettings->Add (new CheckBox (&g_Config.bBypassOSKWithKeyboard , sy->T (" Use system native keyboard" )));
1033
1006
1034
1007
#if PPSSPP_ARCH(AMD64)
1035
1008
systemSettings->Add (new CheckBox (&g_Config.bCacheFullIsoInRam , sy->T (" Cache ISO in RAM" , " Cache full ISO in RAM" )))->SetEnabled (!PSP_IsInited ());
@@ -1051,7 +1024,10 @@ void GameSettingsScreen::CreateViews() {
1051
1024
#if !defined(MOBILE_DEVICE) // TODO: Add all platforms where KEY_CHAR support is added
1052
1025
systemSettings->Add (new PopupTextInputChoice (&g_Config.sNickName , sy->T (" Change Nickname" ), " " , 32 , screenManager ()));
1053
1026
#elif PPSSPP_PLATFORM(ANDROID)
1054
- systemSettings->Add (new ChoiceWithValueDisplay (&g_Config.sNickName , sy->T (" Change Nickname" ), (const char *)nullptr ))->OnClick .Handle (this , &GameSettingsScreen::OnChangeNickname);
1027
+ if (System_GetPropertyBool (SYSPROP_HAS_KEYBOARD))
1028
+ systemSettings->Add (new ChoiceWithValueDisplay (&g_Config.sNickName , sy->T (" Change Nickname" ), (const char *)nullptr ))->OnClick .Handle (this , &GameSettingsScreen::OnChangeNickname);
1029
+ else
1030
+ systemSettings->Add (new PopupTextInputChoice (&g_Config.sNickName , sy->T (" Change Nickname" ), " " , 32 , screenManager ()));
1055
1031
#endif
1056
1032
1057
1033
systemSettings->Add (new CheckBox (&g_Config.bScreenshotsAsPNG , sy->T (" Screenshots as PNG" )));
@@ -1070,6 +1046,42 @@ void GameSettingsScreen::CreateViews() {
1070
1046
systemSettings->Add (new PopupMultiChoice (&g_Config.iTimeFormat , sy->T (" Time Format" ), timeFormat, 0 , 2 , sy->GetName (), screenManager ()));
1071
1047
static const char *buttonPref[] = { " Use O to confirm" , " Use X to confirm" };
1072
1048
systemSettings->Add (new PopupMultiChoice (&g_Config.iButtonPreference , sy->T (" Confirmation Button" ), buttonPref, 0 , 2 , sy->GetName (), screenManager ()));
1049
+
1050
+ if (System_GetPropertyBool (SYSPROP_HAS_KEYBOARD)) {
1051
+ // Search
1052
+ LinearLayout *searchSettings = AddTab (" GameSettingsSearch" , ms->T (" Search" ), true );
1053
+
1054
+ searchSettings->Add (new ItemHeader (se->T (" Find settings" )));
1055
+ searchSettings->Add (new ChoiceWithValueDisplay (&searchFilter_, se->T (" Filter" ), (const char *)nullptr ))->OnClick .Handle (this , &GameSettingsScreen::OnChangeSearchFilter);
1056
+ clearSearchChoice_ = searchSettings->Add (new Choice (se->T (" Clear filter" )));
1057
+ clearSearchChoice_->OnClick .Handle (this , &GameSettingsScreen::OnClearSearchFilter);
1058
+ noSearchResults_ = searchSettings->Add (new TextView (se->T (" No settings matched '%1'" ), new LinearLayoutParams (Margins (20 , 5 ))));
1059
+
1060
+ ApplySearchFilter ();
1061
+ }
1062
+ }
1063
+
1064
+ UI::LinearLayout *GameSettingsScreen::AddTab (const char *tag, const std::string &title, bool isSearch) {
1065
+ auto se = GetI18NCategory (" Search" );
1066
+
1067
+ using namespace UI ;
1068
+ ViewGroup *scroll = new ScrollView (ORIENT_VERTICAL, new LinearLayoutParams (FILL_PARENT, FILL_PARENT));
1069
+ scroll->SetTag (tag);
1070
+
1071
+ LinearLayout *contents = new LinearLayoutList (ORIENT_VERTICAL);
1072
+ contents->SetSpacing (0 );
1073
+ scroll->Add (contents);
1074
+ tabHolder_->AddTab (title, scroll);
1075
+
1076
+ if (!isSearch) {
1077
+ settingTabContents_.push_back (contents);
1078
+
1079
+ auto notice = contents->Add (new TextView (se->T (" Filtering settings by '%1'" ), new LinearLayoutParams (Margins (20 , 5 ))));
1080
+ notice->SetVisibility (V_GONE);
1081
+ settingTabFilterNotices_.push_back (notice);
1082
+ }
1083
+
1084
+ return contents;
1073
1085
}
1074
1086
1075
1087
UI::EventReturn GameSettingsScreen::OnAutoFrameskip (UI::EventParams &e) {
@@ -1309,6 +1321,50 @@ void GameSettingsScreen::sendMessage(const char *message, const char *value) {
1309
1321
g_Config.bShaderChainRequires60FPS = PostShaderChainRequires60FPS (GetFullPostShadersChain (g_Config.vPostShaderNames ));
1310
1322
RecreateViews ();
1311
1323
}
1324
+ if (!strcmp (message, " gameSettings_search" )) {
1325
+ std::string filter = value ? value : " " ;
1326
+ searchFilter_.resize (filter.size ());
1327
+ std::transform (filter.begin (), filter.end (), searchFilter_.begin (), tolower);
1328
+
1329
+ ApplySearchFilter ();
1330
+ }
1331
+ }
1332
+
1333
+ void GameSettingsScreen::ApplySearchFilter () {
1334
+ auto se = GetI18NCategory (" Search" );
1335
+
1336
+ bool matches = searchFilter_.empty ();
1337
+ for (int t = 0 ; t < (int )settingTabContents_.size (); ++t) {
1338
+ auto tabContents = settingTabContents_[t];
1339
+ bool tabMatches = searchFilter_.empty ();
1340
+
1341
+ // Show an indicator that a filter is applied.
1342
+ settingTabFilterNotices_[t]->SetVisibility (tabMatches ? UI::V_GONE : UI::V_VISIBLE);
1343
+ settingTabFilterNotices_[t]->SetText (ReplaceAll (se->T (" Filtering settings by '%1'" ), " %1" , searchFilter_));
1344
+
1345
+ UI::View *lastHeading = nullptr ;
1346
+ for (int i = 1 ; i < tabContents->GetNumSubviews (); ++i) {
1347
+ UI::View *v = tabContents->GetViewByIndex (i);
1348
+ if (!v->CanBeFocused ()) {
1349
+ lastHeading = v;
1350
+ }
1351
+
1352
+ std::string label = v->DescribeText ();
1353
+ std::transform (label.begin (), label.end (), label.begin (), tolower);
1354
+ bool match = v->CanBeFocused () && label.find (searchFilter_) != label.npos ;
1355
+ tabMatches = tabMatches || match;
1356
+
1357
+ if (match && lastHeading)
1358
+ lastHeading->SetVisibility (UI::V_VISIBLE);
1359
+ v->SetVisibility (searchFilter_.empty () || match ? UI::V_VISIBLE : UI::V_GONE);
1360
+ }
1361
+ tabHolder_->EnableTab (t, tabMatches);
1362
+ matches = matches || tabMatches;
1363
+ }
1364
+
1365
+ noSearchResults_->SetText (ReplaceAll (se->T (" No settings matched '%1'" ), " %1" , searchFilter_));
1366
+ noSearchResults_->SetVisibility (matches ? UI::V_GONE : UI::V_VISIBLE);
1367
+ clearSearchChoice_->SetVisibility (searchFilter_.empty () ? UI::V_GONE : UI::V_VISIBLE);
1312
1368
}
1313
1369
1314
1370
void GameSettingsScreen::dialogFinished (const Screen *dialog, DialogResult result) {
@@ -1630,6 +1686,23 @@ UI::EventReturn GameSettingsScreen::OnSysInfo(UI::EventParams &e) {
1630
1686
return UI::EVENT_DONE;
1631
1687
}
1632
1688
1689
+ UI::EventReturn GameSettingsScreen::OnChangeSearchFilter (UI::EventParams &e) {
1690
+ #if PPSSPP_PLATFORM(WINDOWS) || defined(USING_QT_UI) || defined(__ANDROID__)
1691
+ auto se = GetI18NCategory (" Search" );
1692
+ System_InputBoxGetString (se->T (" Search term" ), searchFilter_, [this ](bool result, const std::string &value) {
1693
+ if (result) {
1694
+ NativeMessageReceived (" gameSettings_search" , StripSpaces (value).c_str ());
1695
+ }
1696
+ });
1697
+ #endif
1698
+ return UI::EVENT_DONE;
1699
+ }
1700
+
1701
+ UI::EventReturn GameSettingsScreen::OnClearSearchFilter (UI::EventParams &e) {
1702
+ NativeMessageReceived (" gameSettings_search" , " " );
1703
+ return UI::EVENT_DONE;
1704
+ }
1705
+
1633
1706
void DeveloperToolsScreen::CreateViews () {
1634
1707
using namespace UI ;
1635
1708
root_ = new LinearLayout (ORIENT_VERTICAL, new LayoutParams (FILL_PARENT, FILL_PARENT));
@@ -1865,7 +1938,8 @@ void HostnameSelectScreen::CreatePopupContents(UI::ViewGroup *parent) {
1865
1938
1866
1939
buttonsRow2->Add (new Spacer (new LinearLayoutParams (1.0 , G_LEFT)));
1867
1940
#if PPSSPP_PLATFORM(ANDROID)
1868
- buttonsRow2->Add (new Button (di->T (" Edit" )))->OnClick .Handle (this , &HostnameSelectScreen::OnEditClick); // Since we don't have OnClick Event triggered from TextEdit's Touch().. here we go!
1941
+ if (System_GetPropertyBool (SYSPROP_HAS_KEYBOARD))
1942
+ buttonsRow2->Add (new Button (di->T (" Edit" )))->OnClick .Handle (this , &HostnameSelectScreen::OnEditClick);
1869
1943
#endif
1870
1944
buttonsRow2->Add (new Button (di->T (" Delete" )))->OnClick .Handle (this , &HostnameSelectScreen::OnDeleteClick);
1871
1945
buttonsRow2->Add (new Button (di->T (" Delete all" )))->OnClick .Handle (this , &HostnameSelectScreen::OnDeleteAllClick);
0 commit comments