feat(focus): 完成阶段 2 通用焦点系统

This commit is contained in:
Codex
2026-10-08 18:37:34 +08:00
parent 81341fab2c
commit 255aba688f
25 changed files with 1533 additions and 5 deletions
+59
View File
@@ -251,6 +251,65 @@ int main(int argc, char** argv)
});
window.addControl(std::move(resize));
}
else if (scenario == "focus")
{
// Stage 2 integration: real focus visuals, Table child eligibility, and active Tab page filtering.
auto button = MakeButton(20, 20, 120, 40, "focus button");
Button* buttonRaw = button.get();
bool buttonFocusObserved = false;
button->setOnClickListener([&]() { buttonFocusObserved = buttonRaw->hasLogicalFocus(); });
window.addControl(std::move(button));
auto textBox = std::make_unique<TextBox>(20, 80, 160, 36, "focus text");
TextBox* textBoxRaw = textBox.get();
window.addControl(std::move(textBox));
auto table = std::make_unique<Table>(210, 20);
const auto tableHandle = table->getHandle();
table->setHeaders({ "value" });
table->setRowsPerPage(1);
table->setData({ { "one" }, { "two" } });
window.addControl(std::move(table));
auto tabs = std::make_unique<TabControl>(20, 145, 300, 140);
tabs->setActiveIndex(0);
auto firstPage = std::make_unique<Canvas>(0, 0, 300, 110);
auto firstPageButton = MakeButton(10, 40, 110, 30, "active child");
const auto firstPageChildHandle = firstPageButton->getHandle();
firstPage->addControl(std::move(firstPageButton));
tabs->addTab(MakeButton(0, 0, 100, 30, "first"), std::move(firstPage));
auto secondPage = std::make_unique<Canvas>(0, 0, 300, 110);
auto secondPageButton = MakeButton(10, 40, 110, 30, "inactive child");
const auto secondPageChildHandle = secondPageButton->getHandle();
secondPage->addControl(std::move(secondPageButton));
tabs->addTab(MakeButton(100, 0, 100, 30, "second"), std::move(secondPage));
window.addControl(std::move(tabs));
auto verify = MakeButton(350, 260, 110, 36, "verify");
verify->setOnClickListener([&, buttonRaw]() {
const auto stops = window.getFocusManager().collectTabStops();
std::size_t tableTabStops = 0;
bool activePageChildPresent = false;
bool inactivePageChildPresent = false;
bool allSubNodesZero = true;
for (const auto& stop : stops)
{
if (stop.logicalParent.owner == tableHandle) ++tableTabStops;
if (stop.id.owner == firstPageChildHandle) activePageChildPresent = true;
if (stop.id.owner == secondPageChildHandle) inactivePageChildPresent = true;
if (stop.id.subNode != 0) allSubNodesZero = false;
}
WriteResult(resultDir, scenario,
std::string("{\"buttonFocusObserved\":") + (buttonFocusObserved ? "true" : "false") +
",\"tableTabStops\":" + std::to_string(tableTabStops) +
",\"activePageChildPresent\":" + (activePageChildPresent ? "true" : "false") +
",\"inactivePageChildPresent\":" + (inactivePageChildPresent ? "true" : "false") +
",\"allSubNodesZero\":" + (allSubNodesZero ? "true" : "false") + "}");
});
window.addControl(std::move(verify));
textBoxRaw->requestFocus();
}
else if (scenario == "dialog")
{
// 先叠加两个非模态对话框,再只关闭上层,验证下层恢复和交互顺序。