From 28b9bc2fb3cc67662adff6b033a118920ac7cb65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 23 Oct 2025 15:33:09 +0200 Subject: [PATCH] Make more dev screens usable in portrait by converting them to TabbedDialogScreen --- Common/Buffer.cpp | 4 +- Common/GPU/Vulkan/VulkanFrameData.cpp | 2 +- Common/Net/HTTPRequest.cpp | 2 +- UI/DevScreens.cpp | 35 ++-- UI/DevScreens.h | 8 +- UI/DeveloperToolsScreen.cpp | 8 +- UI/DeveloperToolsScreen.h | 1 - UI/JitCompareScreen.cpp | 252 +++++++++++--------------- UI/JitCompareScreen.h | 20 +- UI/MainScreen.cpp | 1 - UI/TabbedDialogScreen.cpp | 31 +++- UI/TabbedDialogScreen.h | 12 +- 12 files changed, 169 insertions(+), 207 deletions(-) diff --git a/Common/Buffer.cpp b/Common/Buffer.cpp index c307d41641..a6cd052729 100644 --- a/Common/Buffer.cpp +++ b/Common/Buffer.cpp @@ -121,7 +121,7 @@ bool Buffer::FlushToFile(const Path &filename, bool clear) { return false; if (!data_.empty()) { // Write the buffer to the file. - data_.iterate_blocks([=](const char *blockData, size_t blockSize) { + data_.iterate_blocks([f](const char *blockData, size_t blockSize) { return fwrite(blockData, 1, blockSize, f) == blockSize; }); if (clear) { @@ -134,7 +134,7 @@ bool Buffer::FlushToFile(const Path &filename, bool clear) { void Buffer::PeekAll(std::string *dest) { dest->resize(data_.size()); - data_.iterate_blocks(([=](const char *blockData, size_t blockSize) { + data_.iterate_blocks(([dest](const char *blockData, size_t blockSize) { dest->append(blockData, blockSize); return true; })); diff --git a/Common/GPU/Vulkan/VulkanFrameData.cpp b/Common/GPU/Vulkan/VulkanFrameData.cpp index 0369cdc697..2e4c60c41b 100644 --- a/Common/GPU/Vulkan/VulkanFrameData.cpp +++ b/Common/GPU/Vulkan/VulkanFrameData.cpp @@ -67,7 +67,7 @@ void FrameData::Destroy(VulkanContext *vulkan) { vkDestroyQueryPool(device, profile.queryPool, nullptr); vkDestroySemaphore(device, acquireSemaphore, nullptr); - readbacks_.IterateMut([=](const ReadbackKey &key, CachedReadback *value) { + readbacks_.IterateMut([vulkan](const ReadbackKey &key, CachedReadback *value) { value->Destroy(vulkan); delete value; }); diff --git a/Common/Net/HTTPRequest.cpp b/Common/Net/HTTPRequest.cpp index 21ddf14516..4369fa685d 100644 --- a/Common/Net/HTTPRequest.cpp +++ b/Common/Net/HTTPRequest.cpp @@ -14,7 +14,7 @@ Request::Request(RequestMethod method, std::string_view url, std::string_view na : method_(method), url_(url), name_(name), progress_(cancelled), flags_(flags) { INFO_LOG(Log::HTTP, "HTTP %s request: %.*s (%.*s)", RequestMethodToString(method), (int)url.size(), url.data(), (int)name.size(), name.data()); - progress_.callback = [=](int64_t bytes, int64_t contentLength, bool done) { + progress_.callback = [this](int64_t bytes, int64_t contentLength, bool done) { std::string message; if (!name_.empty()) { message = name_; diff --git a/UI/DevScreens.cpp b/UI/DevScreens.cpp index 234562993d..19c5737f72 100644 --- a/UI/DevScreens.cpp +++ b/UI/DevScreens.cpp @@ -289,7 +289,7 @@ void LogConfigScreen::CreateViews() { vert->SetSpacing(0); LinearLayout *topbar = new LinearLayout(ORIENT_HORIZONTAL); - topbar->Add(new Choice(di->T("Back")))->OnClick.Handle(this, &UIScreen::OnBack); + topbar->Add(new Choice(ImageID("I_NAVIGATE_BACK")))->OnClick.Handle(this, &UIScreen::OnBack); topbar->Add(new Choice(di->T("Toggle All")))->OnClick.Handle(this, &LogConfigScreen::OnToggleAll); topbar->Add(new Choice(di->T("Enable All")))->OnClick.Handle(this, &LogConfigScreen::OnEnableAll); topbar->Add(new Choice(di->T("Disable All")))->OnClick.Handle(this, &LogConfigScreen::OnDisableAll); @@ -421,7 +421,7 @@ void JitDebugScreen::CreateViews() { vert->SetSpacing(0); LinearLayout *topbar = new LinearLayout(ORIENT_HORIZONTAL); - topbar->Add(new Choice(di->T("Back")))->OnClick.Handle(this, &UIScreen::OnBack); + topbar->Add(new Choice(ImageID("I_NAVIGATE_BACK")))->OnClick.Handle(this, &UIScreen::OnBack); topbar->Add(new Choice(di->T("Disable All")))->OnClick.Handle(this, &JitDebugScreen::OnDisableAll); topbar->Add(new Choice(di->T("Enable All")))->OnClick.Handle(this, &JitDebugScreen::OnEnableAll); @@ -466,31 +466,23 @@ struct { DebugShaderType type; const char *name; } shaderTypes[] = { { SHADER_TYPE_SAMPLER, "Sampler" }, }; -void ShaderListScreen::CreateViews() { +void ShaderListScreen::CreateTabs() { using namespace UI; - auto di = GetI18NCategory(I18NCat::DIALOG); - - LinearLayout *layout = new LinearLayout(ORIENT_VERTICAL); - root_ = layout; - - tabs_ = new TabHolder(ORIENT_HORIZONTAL, 40, TabHolderFlags::Default, nullptr, new LinearLayoutParams(1.0)); - tabs_->SetTag("DevShaderList"); - layout->Add(tabs_); - layout->Add(new Button(di->T("Back")))->OnClick.Handle(this, &UIScreen::OnBack); for (size_t i = 0; i < ARRAY_SIZE(shaderTypes); i++) { - ScrollView *scroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(1.0)); - LinearLayout *shaderList = new LinearLayoutList(ORIENT_VERTICAL, new LayoutParams(FILL_PARENT, WRAP_CONTENT)); - int count = ListShaders(shaderTypes[i].type, shaderList); - scroll->Add(shaderList); - tabs_->AddTab(StringFromFormat("%s (%d)", shaderTypes[i].name, count), scroll); + int count = (int)gpu->DebugGetShaderIDs(shaderTypes[i].type).size(); + AddTab(shaderTypes[i].name, StringFromFormat("%s (%d)", shaderTypes[i].name, count), [this, i](UI::LinearLayout *tabContent) { + LinearLayout *shaderList = new LinearLayoutList(ORIENT_VERTICAL, new LayoutParams(FILL_PARENT, WRAP_CONTENT)); + int count = ListShaders(shaderTypes[i].type, shaderList); + tabContent->Add(shaderList); + }); } } void ShaderListScreen::OnShaderClick(UI::EventParams &e) { using namespace UI; std::string id = e.v->Tag(); - DebugShaderType type = shaderTypes[tabs_->GetCurrentTab()].type; + DebugShaderType type = shaderTypes[GetCurrentTab()].type; screenManager()->push(new ShaderViewScreen(id, type)); } @@ -502,7 +494,10 @@ void ShaderViewScreen::CreateViews() { LinearLayout *layout = new LinearLayout(ORIENT_VERTICAL); root_ = layout; - layout->Add(new TextView(gpu->DebugGetShaderString(id_, type_, SHADER_STRING_SHORT_DESC), FLAG_DYNAMIC_ASCII | FLAG_WRAP_TEXT, false)); + LinearLayout *topbar = new LinearLayout(ORIENT_HORIZONTAL); + topbar->Add(new Choice(ImageID("I_NAVIGATE_BACK"), new LinearLayoutParams()))->OnClick.Handle(this, &UIScreen::OnBack); + topbar->Add(new TextView(gpu->DebugGetShaderString(id_, type_, SHADER_STRING_SHORT_DESC), FLAG_DYNAMIC_ASCII | FLAG_WRAP_TEXT, false)); + layout->Add(topbar); ScrollView *scroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(1.0)); scroll->SetTag("DevShaderView"); @@ -518,8 +513,6 @@ void ShaderViewScreen::CreateViews() { for (const auto &line : lines) { lineLayout->Add(new TextView(line, FLAG_DYNAMIC_ASCII | FLAG_WRAP_TEXT, true)); } - - layout->Add(new Button(di->T("Back")))->OnClick.Handle(this, &UIScreen::OnBack); } bool ShaderViewScreen::key(const KeyInput &ki) { diff --git a/UI/DevScreens.h b/UI/DevScreens.h index 6738916a8c..0b51afeb84 100644 --- a/UI/DevScreens.h +++ b/UI/DevScreens.h @@ -108,18 +108,18 @@ protected: void CreatePopupContents(UI::ViewGroup *parent) override; }; -class ShaderListScreen : public UIDialogScreenWithBackground { +class ShaderListScreen : public TabbedUIDialogScreenWithGameBackground { public: - void CreateViews() override; + ShaderListScreen() : TabbedUIDialogScreenWithGameBackground(Path()) {} + void CreateTabs() override; const char *tag() const override { return "ShaderList"; } private: + bool ForceHorizontalTabs() const override {return true; } int ListShaders(DebugShaderType shaderType, UI::LinearLayout *view); void OnShaderClick(UI::EventParams &e); - - UI::TabHolder *tabs_; }; class ShaderViewScreen : public UIDialogScreenWithBackground { diff --git a/UI/DeveloperToolsScreen.cpp b/UI/DeveloperToolsScreen.cpp index 6f25017ed7..3977bb2350 100644 --- a/UI/DeveloperToolsScreen.cpp +++ b/UI/DeveloperToolsScreen.cpp @@ -159,7 +159,9 @@ void DeveloperToolsScreen::CreateGeneralTab(UI::LinearLayout *list) { list->Add(new ItemHeader(sy->T("General"))); list->Add(new CheckBox(&g_Config.bEnableLogging, dev->T("Enable Logging")))->OnClick.Handle(this, &DeveloperToolsScreen::OnLoggingChanged); - list->Add(new Choice(dev->T("Logging Channels")))->OnClick.Handle(this, &DeveloperToolsScreen::OnLogConfig); + list->Add(new Choice(dev->T("Logging Channels")))->OnClick.Add([this](UI::EventParams &e) { + screenManager()->push(new LogConfigScreen()); + }); list->Add(new CheckBox(&g_Config.bEnableFileLogging, dev->T("Log to file")))->SetEnabledPtr(&g_Config.bEnableLogging); list->Add(new CheckBox(&g_Config.bLogFrameDrops, dev->T("Log Dropped Frame Statistics"))); if (GetGPUBackend() == GPUBackend::VULKAN) { @@ -625,10 +627,6 @@ void DeveloperToolsScreen::OnOpenTexturesIniFile(UI::EventParams &e) { } } -void DeveloperToolsScreen::OnLogConfig(UI::EventParams &e) { - screenManager()->push(new LogConfigScreen()); -} - void DeveloperToolsScreen::OnJitDebugTools(UI::EventParams &e) { screenManager()->push(new JitDebugScreen()); } diff --git a/UI/DeveloperToolsScreen.h b/UI/DeveloperToolsScreen.h index 4ca172a5b8..dbbef1babb 100644 --- a/UI/DeveloperToolsScreen.h +++ b/UI/DeveloperToolsScreen.h @@ -28,7 +28,6 @@ private: void OnLoggingChanged(UI::EventParams &e); void OnOpenTexturesIniFile(UI::EventParams &e); - void OnLogConfig(UI::EventParams &e); void OnJitAffectingSetting(UI::EventParams &e); void OnJitDebugTools(UI::EventParams &e); void OnRemoteDebugger(UI::EventParams &e); diff --git a/UI/JitCompareScreen.cpp b/UI/JitCompareScreen.cpp index bd171026b4..5386b5ec15 100644 --- a/UI/JitCompareScreen.cpp +++ b/UI/JitCompareScreen.cpp @@ -8,7 +8,7 @@ #include "Core/MIPS/JitCommon/JitCommon.h" #include "Core/MIPS/JitCommon/JitState.h" -JitCompareScreen::JitCompareScreen() : UIDialogScreenWithBackground() { +JitCompareScreen::JitCompareScreen() : TabbedUIDialogScreenWithGameBackground(Path()) { if (!MIPSComp::jit) { return; } @@ -22,145 +22,109 @@ JitCompareScreen::JitCompareScreen() : UIDialogScreenWithBackground() { FillBlockList(); } -void JitCompareScreen::Flip() { - using namespace UI; - // If we add more, let's convert to a for loop. - switch (viewMode_) { - case ViewMode::DISASM: - comparisonView_->SetVisibility(V_VISIBLE); - blockListView_->SetVisibility(V_GONE); - statsView_->SetVisibility(V_GONE); - break; - case ViewMode::BLOCK_LIST: - comparisonView_->SetVisibility(V_GONE); - blockListView_->SetVisibility(V_VISIBLE); - statsView_->SetVisibility(V_GONE); - break; - case ViewMode::STATS: - comparisonView_->SetVisibility(V_GONE); - blockListView_->SetVisibility(V_GONE); - statsView_->SetVisibility(V_VISIBLE); - break; - } -} - // Three panes: Block chooser, MIPS view, ARM/x86 view -void JitCompareScreen::CreateViews() { +void JitCompareScreen::CreateTabs() { auto di = GetI18NCategory(I18NCat::DIALOG); auto dev = GetI18NCategory(I18NCat::DEVELOPER); using namespace UI; - root_ = new LinearLayout(ORIENT_HORIZONTAL); - - ScrollView *leftColumnScroll = root_->Add(new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(200, FILL_PARENT))); - LinearLayout *leftColumn = leftColumnScroll->Add(new LinearLayout(ORIENT_VERTICAL)); - - comparisonView_ = root_->Add(new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(1.0f))); - comparisonView_->SetVisibility(V_VISIBLE); - LinearLayout *blockTopBar = comparisonView_->Add(new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT))); - blockTopBar->Add(new Button("", ImageID("I_ARROW_UP")))->OnClick.Add([this](UI::EventParams &e) { - viewMode_ = ViewMode::BLOCK_LIST; - Flip(); - }); - blockTopBar->Add(new Button("", ImageID("I_ARROW_LEFT")))->OnClick.Add([=](UI::EventParams &e) { - if (currentBlock_ >= 1) - currentBlock_--; - UpdateDisasm(); - }); - blockTopBar->Add(new Button("", ImageID("I_ARROW_RIGHT")))->OnClick.Add([=](UI::EventParams &e) { - if (currentBlock_ < blockList_.size() - 1) - currentBlock_++; - UpdateDisasm(); - }); - blockTopBar->Add(new Button(dev->T("Random")))->OnClick.Add([=](UI::EventParams &e) { - if (blockList_.empty()) { - return; - } - currentBlock_ = rand() % blockList_.size(); - UpdateDisasm(); - }); - - blockAddr_ = blockTopBar->Add(new TextEdit("", dev->T("Block address"), "")); - blockAddr_->OnEnter.Handle(this, &JitCompareScreen::OnAddressChange); - blockName_ = blockTopBar->Add(new TextView(dev->T("No block"))); - blockStats_ = blockTopBar->Add(new TextView("")); - - LinearLayout *columns = comparisonView_->Add(new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(1.0f))); - - ScrollView *midColumnScroll = columns->Add(new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(1.0f))); - LinearLayout *midColumn = midColumnScroll->Add(new LinearLayout(ORIENT_VERTICAL)); - midColumn->SetTag("JitCompareLeftDisasm"); - leftDisasm_ = midColumn->Add(new LinearLayout(ORIENT_VERTICAL)); - leftDisasm_->SetSpacing(0.0f); - - ScrollView *rightColumnScroll = columns->Add(new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(1.0f))); - rightColumnScroll->SetTag("JitCompareRightDisasm"); - LinearLayout *rightColumn = rightColumnScroll->Add(new LinearLayout(ORIENT_VERTICAL)); - rightDisasm_ = rightColumn->Add(new LinearLayout(ORIENT_VERTICAL)); - rightDisasm_->SetSpacing(0.0f); - - blockListView_ = root_->Add(new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(1.0f))); - blockListView_->SetVisibility(V_GONE); - - // Should match the ListSort enum - static ContextMenuItem sortMenu[] = { - { "Block number", "I_ARROW_UP" }, - { "Block length", "I_ARROW_DOWN" }, - { "Block length", "I_ARROW_UP" }, - { "Time spent", "I_ARROW_DOWN" }, - { "Executions", "I_ARROW_DOWN" }, - }; - int sortCount = ARRAY_SIZE(sortMenu); - if (MIPSComp::jit) { - JitBlockCacheDebugInterface *blockCacheDebug = MIPSComp::jit->GetBlockCacheDebugInterface(); - if (!blockCacheDebug->SupportsProfiling()) { - sortCount -= 2; - } - } - - LinearLayout *listTopBar = blockListView_->Add(new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT))); - Button *sortButton = new Button(dev->T("Sort...")); - listTopBar->Add(sortButton)->OnClick.Add([this, sortButton, sortCount](UI::EventParams &e) { - PopupContextMenuScreen *contextMenu = new UI::PopupContextMenuScreen(sortMenu, sortCount, I18NCat::DEVELOPER, sortButton); - screenManager()->push(contextMenu); - contextMenu->OnChoice.Add([=](EventParams &e) -> void { - if (e.a < (int)ListSort::MAX) { - listSort_ = (ListSort)e.a; - UpdateDisasm(); + AddTab("Block List", dev->T("Block List"), [=](LinearLayout *tabContent) { + // Should match the ListSort enum + static ContextMenuItem sortMenu[] = { + { "Block number", "I_ARROW_UP" }, + { "Block length", "I_ARROW_DOWN" }, + { "Block length", "I_ARROW_UP" }, + { "Time spent", "I_ARROW_DOWN" }, + { "Executions", "I_ARROW_DOWN" }, + }; + int sortCount = ARRAY_SIZE(sortMenu); + if (MIPSComp::jit) { + JitBlockCacheDebugInterface *blockCacheDebug = MIPSComp::jit->GetBlockCacheDebugInterface(); + if (!blockCacheDebug->SupportsProfiling()) { + sortCount -= 2; } + } + + LinearLayout *listTopBar = tabContent->Add(new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT))); + Choice *sortButton = new Choice(dev->T("Sort..."), new LinearLayoutParams()); + listTopBar->Add(sortButton)->OnClick.Add([this, sortButton, sortCount](UI::EventParams &e) { + PopupContextMenuScreen *contextMenu = new UI::PopupContextMenuScreen(sortMenu, sortCount, I18NCat::DEVELOPER, sortButton); + screenManager()->push(contextMenu); + contextMenu->OnChoice.Add([=](EventParams &e) -> void { + if (e.a < (int)ListSort::MAX) { + listSort_ = (ListSort)e.a; + UpdateDisasm(); + } + }); }); + // leftColumn->Add(new Choice(dev->T("By Address")))->OnClick.Handle(this, &JitCompareScreen::OnSelectBlock); + listTopBar->Add(new Choice(dev->T("All"), new LinearLayoutParams()))->OnClick.Add([=](UI::EventParams &e) { + listType_ = ListType::ALL_BLOCKS; + UpdateDisasm(); + }); + listTopBar->Add(new Choice(dev->T("FPU"), new LinearLayoutParams()))->OnClick.Add([=](UI::EventParams &e) { + listType_ = ListType::FPU_BLOCKS; + UpdateDisasm(); + }); + listTopBar->Add(new Choice(dev->T("VFPU"), new LinearLayoutParams()))->OnClick.Add([=](UI::EventParams &e) { + listType_ = ListType::VFPU_BLOCKS; + UpdateDisasm(); + }); + + blockListContainer_ = tabContent->Add(new LinearLayout(ORIENT_VERTICAL)); }); - ScrollView *blockScroll = blockListView_->Add(new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(1.0f))); - blockListContainer_ = blockScroll->Add(new LinearLayout(ORIENT_VERTICAL)); + AddTab("Comparison", dev->T("Jit Compare"), [=](LinearLayout *tabContent) { + LinearLayout *blockTopBar = tabContent->Add(new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT))); + blockTopBar->Add(new Button("", ImageID("I_ARROW_LEFT")))->OnClick.Add([=](UI::EventParams &e) { + if (currentBlock_ >= 1) + currentBlock_--; + UpdateDisasm(); + }); + blockTopBar->Add(new Button("", ImageID("I_ARROW_RIGHT")))->OnClick.Add([=](UI::EventParams &e) { + if (currentBlock_ < (int)blockList_.size() - 1) + currentBlock_++; + if (currentBlock_ == -1 && !blockList_.empty()) { + currentBlock_ = 0; + } + UpdateDisasm(); + }); + blockTopBar->Add(new Button(dev->T("Random")))->OnClick.Add([=](UI::EventParams &e) { + if (blockList_.empty()) { + return; + } + currentBlock_ = rand() % blockList_.size(); + UpdateDisasm(); + }); - statsView_ = root_->Add(new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(1.0f))); - statsView_->SetVisibility(V_GONE); + blockAddr_ = blockTopBar->Add(new TextEdit("", dev->T("Block address"), "")); + blockAddr_->OnEnter.Handle(this, &JitCompareScreen::OnAddressChange); + blockName_ = blockTopBar->Add(new TextView(dev->T("No block"))); + blockStats_ = blockTopBar->Add(new TextView("")); - LinearLayout *statsTopBar = statsView_->Add(new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT))); - ScrollView *statsScroll = statsView_->Add(new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(1.0f))); - statsContainer_ = statsScroll->Add(new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT))); + tabContent->Add(new Button("test")); - // leftColumn->Add(new Choice(dev->T("By Address")))->OnClick.Handle(this, &JitCompareScreen::OnSelectBlock); - leftColumn->Add(new Choice(dev->T("All")))->OnClick.Add([=](UI::EventParams &e) { - listType_ = ListType::ALL_BLOCKS; - viewMode_ = ViewMode::BLOCK_LIST; - UpdateDisasm(); - }); - leftColumn->Add(new Choice(dev->T("FPU")))->OnClick.Add([=](UI::EventParams &e) { - listType_ = ListType::FPU_BLOCKS; - viewMode_ = ViewMode::BLOCK_LIST; - UpdateDisasm(); - }); - leftColumn->Add(new Choice(dev->T("VFPU")))->OnClick.Add([=](UI::EventParams &e) { - listType_ = ListType::VFPU_BLOCKS; - viewMode_ = ViewMode::BLOCK_LIST; - UpdateDisasm(); + LinearLayout *columns = tabContent->Add(new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(1.0f))); + + ScrollView *midColumnScroll = columns->Add(new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(1.0f))); + LinearLayout *midColumn = midColumnScroll->Add(new LinearLayout(ORIENT_VERTICAL)); + midColumn->SetTag("JitCompareLeftDisasm"); + leftDisasm_ = midColumn->Add(new LinearLayout(ORIENT_VERTICAL)); + leftDisasm_->SetSpacing(0.0f); + + ScrollView *rightColumnScroll = columns->Add(new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(1.0f))); + rightColumnScroll->SetTag("JitCompareRightDisasm"); + LinearLayout *rightColumn = rightColumnScroll->Add(new LinearLayout(ORIENT_VERTICAL)); + rightDisasm_ = rightColumn->Add(new LinearLayout(ORIENT_VERTICAL)); + rightDisasm_->SetSpacing(0.0f); + }, TabFlags::NonScrollable); + + AddTab("Stats", dev->T("Stats"), [=](LinearLayout *tabContent) { + globalStats_ = tabContent->Add(new TextView("N/A")); }); - leftColumn->Add(new Choice(dev->T("Stats")))->OnClick.Handle(this, &JitCompareScreen::OnShowStats); - leftColumn->Add(new Choice(di->T("Back")))->OnClick.Handle(this, &UIScreen::OnBack); + EnsureTabs(); // don't create them lazily, due to the interdependences UpdateDisasm(); } @@ -196,6 +160,7 @@ void JitCompareScreen::FillBlockList() { } } } + break; } default: break; @@ -245,6 +210,10 @@ void JitCompareScreen::FillBlockList() { return false; } }); + + if (currentBlock_ < 0 && !blockList_.empty()) { + currentBlock_ = 0; + } } void JitCompareScreen::UpdateDisasm() { @@ -258,14 +227,10 @@ void JitCompareScreen::UpdateDisasm() { } JitBlockCacheDebugInterface *blockCacheDebug = MIPSComp::jit->GetBlockCacheDebugInterface(); - if (viewMode_ == ViewMode::DISASM && (currentBlock_ < 0 || currentBlock_ >= (int)blockList_.size())) { - viewMode_ = ViewMode::BLOCK_LIST; - } FillBlockList(); - Flip(); - if (viewMode_ == ViewMode::DISASM) { + if (currentBlock_ >= 0 && currentBlock_ < blockList_.size()) { // Update disassembly char temp[256]; snprintf(temp, sizeof(temp), "%d/%d", currentBlock_, (int)blockList_.size()); blockName_->SetText(temp); @@ -276,7 +241,7 @@ void JitCompareScreen::UpdateDisasm() { auto dev = GetI18NCategory(I18NCat::DEVELOPER); leftDisasm_->Add(new TextView(dev->T("No block"))); rightDisasm_->Add(new TextView(dev->T("No block"))); - blockStats_->SetText(""); + blockStats_->SetText("(no stats)"); return; } @@ -315,10 +280,11 @@ void JitCompareScreen::UpdateDisasm() { snprintf(temp, sizeof(temp), "bloat: %0.1f%%", bloat); } blockStats_->SetText(temp); - } else if (viewMode_ == ViewMode::BLOCK_LIST) { + } + { // Update block list blockListContainer_->Clear(); bool profiling = blockCacheDebug->SupportsProfiling(); - for (int i = 0; i < std::min(100, (int)blockList_.size()); i++) { + for (int i = 0; i < std::min(200, (int)blockList_.size()); i++) { int blockNum = blockList_[i]; JitBlockMeta meta = blockCacheDebug->GetBlockMeta(blockNum); char temp[512], small[512]; @@ -335,9 +301,10 @@ void JitCompareScreen::UpdateDisasm() { Choice *blockChoice = blockListContainer_->Add(new Choice(temp, small)); blockChoice->OnClick.Handle(this, &JitCompareScreen::OnBlockClick); } - } else { // viewMode_ == ViewMode::STATS - statsContainer_->Clear(); + } + // Update stats + { BlockCacheStats bcStats{}; blockCacheDebug->ComputeStats(bcStats); @@ -352,15 +319,15 @@ void JitCompareScreen::UpdateDisasm() { 100.0 * bcStats.minBloat, bcStats.minBloatBlock, 100.0 * bcStats.maxBloat, bcStats.maxBloatBlock); - statsContainer_->Add(new TextView(stats)); + globalStats_->SetText(stats); } } void JitCompareScreen::OnBlockClick(UI::EventParams &e) { int blockIndex = blockListContainer_->IndexOfSubview(e.v); if (blockIndex >= 0) { - viewMode_ = ViewMode::DISASM; currentBlock_ = blockIndex; + SetCurrentTab(1); UpdateDisasm(); } } @@ -384,17 +351,6 @@ void JitCompareScreen::OnAddressChange(UI::EventParams &e) { } } -void JitCompareScreen::OnShowStats(UI::EventParams &e) { - std::lock_guard guard(MIPSComp::jitLock); - if (!MIPSComp::jit) { - return; - } - - viewMode_ = ViewMode::STATS; - UpdateDisasm(); -} - - void JitCompareScreen::OnSelectBlock(UI::EventParams &e) { auto dev = GetI18NCategory(I18NCat::DEVELOPER); diff --git a/UI/JitCompareScreen.h b/UI/JitCompareScreen.h index 0e19ee87ed..8b1278b29d 100644 --- a/UI/JitCompareScreen.h +++ b/UI/JitCompareScreen.h @@ -1,16 +1,17 @@ #pragma once #include "Common/UI/UIScreen.h" #include "UI/MiscScreens.h" +#include "UI/TabbedDialogScreen.h" -class JitCompareScreen : public UIDialogScreenWithBackground { +class JitCompareScreen : public TabbedUIDialogScreenWithGameBackground { public: JitCompareScreen(); - void CreateViews() override; + void CreateTabs() override; const char *tag() const override { return "JitCompare"; } private: - void Flip(); + bool ShowSearchControls() const override { return false; } void UpdateDisasm(); // Uses the current ListType @@ -23,21 +24,11 @@ private: UI::LinearLayout *blockListView_ = nullptr; UI::LinearLayout *blockListContainer_ = nullptr; - UI::LinearLayout *statsView_ = nullptr; - UI::LinearLayout *statsContainer_ = nullptr; - void OnSelectBlock(UI::EventParams &e); void OnBlockAddress(UI::EventParams &e); void OnAddressChange(UI::EventParams &e); - void OnShowStats(UI::EventParams &e); void OnBlockClick(UI::EventParams &e); - // To switch, change the below things and call RecreateViews(); - enum class ViewMode { - BLOCK_LIST, - DISASM, - STATS, - }; enum class ListType { ALL_BLOCKS, FPU_BLOCKS, @@ -51,7 +42,6 @@ private: EXECUTIONS, MAX }; - ViewMode viewMode_ = ViewMode::BLOCK_LIST; ListType listType_ = ListType::ALL_BLOCKS; ListSort listSort_ = ListSort::TIME_SPENT; @@ -63,6 +53,8 @@ private: UI::TextView *blockName_ = nullptr; UI::TextEdit *blockAddr_ = nullptr; UI::TextView *blockStats_ = nullptr; + + UI::TextView *globalStats_ = nullptr; }; class AddressPromptScreen : public PopupScreen { diff --git a/UI/MainScreen.cpp b/UI/MainScreen.cpp index ef3ad7f5e1..20dfb2b049 100644 --- a/UI/MainScreen.cpp +++ b/UI/MainScreen.cpp @@ -1262,7 +1262,6 @@ void MainScreen::CreateViews() { ViewGroup *rightColumn = new ScrollView(ORIENT_VERTICAL); LinearLayout *rightColumnItems = new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT)); rightColumnItems->SetSpacing(0.0f); - rightColumnItems->Add(CreateLogoView()); LinearLayout *rightColumnChoices = rightColumnItems; diff --git a/UI/TabbedDialogScreen.cpp b/UI/TabbedDialogScreen.cpp index 2b5c142c50..309fb93007 100644 --- a/UI/TabbedDialogScreen.cpp +++ b/UI/TabbedDialogScreen.cpp @@ -7,24 +7,31 @@ #include "Common/UI/TabHolder.h" #include "UI/TabbedDialogScreen.h" -void TabbedUIDialogScreenWithGameBackground::AddTab(const char *tag, std::string_view title, std::function createCallback, bool isSearch) { +void TabbedUIDialogScreenWithGameBackground::AddTab(const char *tag, std::string_view title, std::function createCallback, TabFlags flags) { using namespace UI; - tabHolder_->AddTabDeferred(title, [createCallback = std::move(createCallback), tag]() -> UI::ViewGroup * { - ViewGroup *scroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, FILL_PARENT)); - scroll->SetTag(tag); + tabHolder_->AddTabDeferred(title, [createCallback = std::move(createCallback), tag, flags]() -> UI::ViewGroup * { + ViewGroup *scroll = nullptr; + if (!(flags & TabFlags::NonScrollable)) { + scroll = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, FILL_PARENT)); + scroll->SetTag(tag); + } LinearLayout *contents = new LinearLayoutList(ORIENT_VERTICAL); contents->SetSpacing(0); - scroll->Add(contents); createCallback(contents); - return scroll; + if (scroll) { + scroll->Add(contents); + return scroll; + } else { + return contents; + } }); } void TabbedUIDialogScreenWithGameBackground::CreateViews() { PreCreateViews(); - bool vertical = UseVerticalLayout(); + bool vertical = UseVerticalLayout() || ForceHorizontalTabs(); // Information in the top left. // Back button to the bottom left. @@ -92,7 +99,7 @@ void TabbedUIDialogScreenWithGameBackground::CreateViews() { clearSearchChoice_->SetVisibility(searchFilter_.empty() ? UI::V_GONE : UI::V_VISIBLE); noSearchResults_ = searchSettings->Add(new TextView("", new LinearLayoutParams(Margins(20, 5)))); - }, true); + }); } } } @@ -120,6 +127,14 @@ void TabbedUIDialogScreenWithGameBackground::EnsureTabs() { } } +int TabbedUIDialogScreenWithGameBackground::GetCurrentTab() const { + return tabHolder_->GetCurrentTab(); +} + +void TabbedUIDialogScreenWithGameBackground::SetCurrentTab(int tab) { + tabHolder_->SetCurrentTab(tab); +} + void TabbedUIDialogScreenWithGameBackground::ApplySearchFilter() { using namespace UI; auto se = GetI18NCategory(I18NCat::SEARCH); diff --git a/UI/TabbedDialogScreen.h b/UI/TabbedDialogScreen.h index a856acbf38..3948ab02cc 100644 --- a/UI/TabbedDialogScreen.h +++ b/UI/TabbedDialogScreen.h @@ -12,11 +12,17 @@ namespace UI { class TabHolder; } +enum class TabFlags { + Default = 0, + NonScrollable = 1, +}; +ENUM_CLASS_BITOPS(TabFlags); + class TabbedUIDialogScreenWithGameBackground : public UIDialogScreenWithGameBackground { public: TabbedUIDialogScreenWithGameBackground(const Path &gamePath) : UIDialogScreenWithGameBackground(gamePath) {} - void AddTab(const char *tag, std::string_view title, std::function createCallback, bool isSearch = false); + void AddTab(const char *tag, std::string_view title, std::function createCallback, TabFlags flags = TabFlags::Default); void CreateViews() override; protected: @@ -26,6 +32,10 @@ protected: virtual void CreateExtraButtons(UI::LinearLayout *verticalLayout, int margins) {} virtual bool ShowSearchControls() const { return true; } virtual void EnsureTabs(); + virtual bool ForceHorizontalTabs() const { return false; } + + int GetCurrentTab() const; + void SetCurrentTab(int tab); void RecreateViews() override; void sendMessage(UIMessage message, const char *value) override;