Skip to content

Commit 72e8c60

Browse files
authored
Merge pull request #14414 from unknownbrackets/search-settings
Add search for settings
2 parents 593241b + 21ff0b1 commit 72e8c60

13 files changed

+216
-84
lines changed

Common/System/System.h

+1
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ enum SystemProperty {
6565
SYSPROP_HAS_FOLDER_BROWSER,
6666
SYSPROP_HAS_IMAGE_BROWSER,
6767
SYSPROP_HAS_BACK_BUTTON,
68+
SYSPROP_HAS_KEYBOARD,
6869

6970
// Available as Int:
7071
SYSPROP_SYSTEMVERSION,

Common/UI/ViewGroup.cpp

+9-3
Original file line numberDiff line numberDiff line change
@@ -1505,11 +1505,17 @@ void ChoiceStrip::SetSelection(int sel, bool triggerClick) {
15051505
}
15061506
}
15071507

1508-
void ChoiceStrip::HighlightChoice(unsigned int choice){
1509-
if (choice < (unsigned int)views_.size()){
1508+
void ChoiceStrip::HighlightChoice(int choice) {
1509+
if (choice < (int)views_.size()) {
15101510
Choice(choice)->HighlightChanged(true);
15111511
}
1512-
};
1512+
}
1513+
1514+
void ChoiceStrip::EnableChoice(int choice, bool enabled) {
1515+
if (choice < (int)views_.size()) {
1516+
Choice(choice)->SetEnabled(enabled);
1517+
}
1518+
}
15131519

15141520
bool ChoiceStrip::Key(const KeyInput &input) {
15151521
bool ret = false;

Common/UI/ViewGroup.h

+5-1
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,8 @@ class ChoiceStrip : public LinearLayout {
330330
int GetSelection() const { return selected_; }
331331
void SetSelection(int sel, bool triggerClick);
332332

333-
void HighlightChoice(unsigned int choice);
333+
void HighlightChoice(int choice);
334+
void EnableChoice(int choice, bool enabled);
334335

335336
bool Key(const KeyInput &input) override;
336337

@@ -360,6 +361,9 @@ class TabHolder : public LinearLayout {
360361
AddTabContents(title, (View *)tabContents);
361362
return tabContents;
362363
}
364+
void EnableTab(int tab, bool enabled) {
365+
tabStrip_->EnableChoice(tab, enabled);
366+
}
363367

364368
void SetCurrentTab(int tab, bool skipTween = false);
365369

Core/Dialog/PSPOskDialog.cpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -942,8 +942,10 @@ int PSPOskDialog::Update(int animSpeed) {
942942
#if defined(USING_WIN_UI) || defined(USING_QT_UI) || PPSSPP_PLATFORM(ANDROID)
943943
// Windows: Fall back to the OSK/continue normally if we're in fullscreen.
944944
// The dialog box doesn't work right if in fullscreen.
945-
if (g_Config.bBypassOSKWithKeyboard && !g_Config.bFullScreen)
946-
return NativeKeyboard();
945+
if (System_GetPropertyBool(SYSPROP_HAS_KEYBOARD)) {
946+
if (g_Config.bBypassOSKWithKeyboard && !g_Config.bFullScreen)
947+
return NativeKeyboard();
948+
}
947949
#endif
948950

949951
UpdateFade(animSpeed);

Qt/QtMain.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,8 @@ bool System_GetPropertyBool(SystemProperty prop) {
227227
#endif
228228
case SYSPROP_CAN_JIT:
229229
return true;
230+
case SYSPROP_HAS_KEYBOARD:
231+
return true;
230232
default:
231233
return false;
232234
}

UI/GameSettingsScreen.cpp

+128-54
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ void GameSettingsScreen::CreateViews() {
212212
auto co = GetI18NCategory("Controls");
213213
auto a = GetI18NCategory("Audio");
214214
auto sa = GetI18NCategory("Savedata");
215+
auto se = GetI18NCategory("Search");
215216
auto sy = GetI18NCategory("System");
216217
auto n = GetI18NCategory("Networking");
217218
auto ms = GetI18NCategory("MainSettings");
@@ -221,20 +222,21 @@ void GameSettingsScreen::CreateViews() {
221222

222223
root_ = new AnchorLayout(new LayoutParams(FILL_PARENT, FILL_PARENT));
223224

224-
TabHolder *tabHolder;
225225
if (vertical) {
226226
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_);
229229
verticalLayout->Add(new Choice(di->T("Back"), "", false, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT, 0.0f, Margins(0))))->OnClick.Handle<UIScreen>(this, &UIScreen::OnBack);
230230
root_->Add(verticalLayout);
231231
} 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_);
234234
AddStandardBack(root_);
235235
}
236-
tabHolder->SetTag("GameSettings");
237-
root_->SetDefaultFocusView(tabHolder);
236+
tabHolder_->SetTag("GameSettings");
237+
root_->SetDefaultFocusView(tabHolder_);
238+
settingTabContents_.clear();
239+
settingTabFilterNotices_.clear();
238240

239241
float leftSide = 40.0f;
240242
if (!vertical) {
@@ -252,12 +254,7 @@ void GameSettingsScreen::CreateViews() {
252254
// TODO: These currently point to global settings, not game specific ones.
253255

254256
// 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"));
261258

262259
graphicsSettings->Add(new ItemHeader(gr->T("Rendering Mode")));
263260

@@ -629,15 +626,9 @@ void GameSettingsScreen::CreateViews() {
629626
dump->SetEnabled(false);
630627

631628
// 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"));
638630

639631
audioSettings->Add(new ItemHeader(ms->T("Audio")));
640-
641632
audioSettings->Add(new CheckBox(&g_Config.bEnableSound, a->T("Enable Sound")));
642633

643634
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() {
695686
}
696687

697688
// 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+
704691
controlsSettings->Add(new ItemHeader(ms->T("Controls")));
705692
controlsSettings->Add(new Choice(co->T("Control Mapping")))->OnClick.Handle(this, &GameSettingsScreen::OnControlMapping);
706693
controlsSettings->Add(new Choice(co->T("Calibrate Analog Stick")))->OnClick.Handle(this, &GameSettingsScreen::OnCalibrateAnalogs);
@@ -795,12 +782,7 @@ void GameSettingsScreen::CreateViews() {
795782
controlsSettings->Add(new PopupSliderChoiceFloat(&g_Config.fMouseSmoothing, 0.0f, 0.95f, co->T("Mouse smoothing"), 0.05f, screenManager(), "x"))->SetEnabledPtr(&g_Config.bMouseControl);
796783
#endif
797784

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"));
804786

805787
networkingSettings->Add(new ItemHeader(ms->T("Networking")));
806788

@@ -866,24 +848,21 @@ void GameSettingsScreen::CreateViews() {
866848
#endif
867849

868850
#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+
}
874858
#endif
875859

876860
networkingSettings->Add(new ItemHeader(n->T("Misc", "Misc (default = compatibility)")));
877861
networkingSettings->Add(new PopupSliderChoice(&g_Config.iPortOffset, 0, 60000, n->T("Port offset", "Port offset (0 = PSP compatibility)"), 100, screenManager()));
878862
networkingSettings->Add(new PopupSliderChoice(&g_Config.iMinTimeout, 0, 15000, n->T("Minimum Timeout", "Minimum Timeout (override in ms, 0 = default)"), 50, screenManager()));
879863
networkingSettings->Add(new CheckBox(&g_Config.bForcedFirstConnect, n->T("Forced First Connect", "Forced First Connect (faster Connect)")));
880864

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"));
887866

888867
tools->Add(new ItemHeader(ms->T("Tools")));
889868
// 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() {
893872
tools->Add(new Choice(ri->T("Remote disc streaming")))->OnClick.Handle(this, &GameSettingsScreen::OnRemoteISO);
894873

895874
// 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"));
902876

903877
systemSettings->Add(new ItemHeader(sy->T("UI")));
904878
systemSettings->Add(new Choice(dev->T("Language", "Language")))->OnClick.Handle(this, &GameSettingsScreen::OnLanguage);
@@ -1027,9 +1001,8 @@ void GameSettingsScreen::CreateViews() {
10271001
systemSettings->Add(new CheckBox(&g_Config.bEnableStateUndo, sy->T("Savestate slot backups")));
10281002
static const char *autoLoadSaveStateChoices[] = { "Off", "Oldest Save", "Newest Save", "Slot 1", "Slot 2", "Slot 3", "Slot 4", "Slot 5" };
10291003
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")));
10331006

10341007
#if PPSSPP_ARCH(AMD64)
10351008
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() {
10511024
#if !defined(MOBILE_DEVICE) // TODO: Add all platforms where KEY_CHAR support is added
10521025
systemSettings->Add(new PopupTextInputChoice(&g_Config.sNickName, sy->T("Change Nickname"), "", 32, screenManager()));
10531026
#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()));
10551031
#endif
10561032

10571033
systemSettings->Add(new CheckBox(&g_Config.bScreenshotsAsPNG, sy->T("Screenshots as PNG")));
@@ -1070,6 +1046,42 @@ void GameSettingsScreen::CreateViews() {
10701046
systemSettings->Add(new PopupMultiChoice(&g_Config.iTimeFormat, sy->T("Time Format"), timeFormat, 0, 2, sy->GetName(), screenManager()));
10711047
static const char *buttonPref[] = { "Use O to confirm", "Use X to confirm" };
10721048
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;
10731085
}
10741086

10751087
UI::EventReturn GameSettingsScreen::OnAutoFrameskip(UI::EventParams &e) {
@@ -1309,6 +1321,50 @@ void GameSettingsScreen::sendMessage(const char *message, const char *value) {
13091321
g_Config.bShaderChainRequires60FPS = PostShaderChainRequires60FPS(GetFullPostShadersChain(g_Config.vPostShaderNames));
13101322
RecreateViews();
13111323
}
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);
13121368
}
13131369

13141370
void GameSettingsScreen::dialogFinished(const Screen *dialog, DialogResult result) {
@@ -1630,6 +1686,23 @@ UI::EventReturn GameSettingsScreen::OnSysInfo(UI::EventParams &e) {
16301686
return UI::EVENT_DONE;
16311687
}
16321688

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+
16331706
void DeveloperToolsScreen::CreateViews() {
16341707
using namespace UI;
16351708
root_ = new LinearLayout(ORIENT_VERTICAL, new LayoutParams(FILL_PARENT, FILL_PARENT));
@@ -1865,7 +1938,8 @@ void HostnameSelectScreen::CreatePopupContents(UI::ViewGroup *parent) {
18651938

18661939
buttonsRow2->Add(new Spacer(new LinearLayoutParams(1.0, G_LEFT)));
18671940
#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);
18691943
#endif
18701944
buttonsRow2->Add(new Button(di->T("Delete")))->OnClick.Handle(this, &HostnameSelectScreen::OnDeleteClick);
18711945
buttonsRow2->Add(new Button(di->T("Delete all")))->OnClick.Handle(this, &HostnameSelectScreen::OnDeleteAllClick);

0 commit comments

Comments
 (0)