Proclamations: sub-cats always expanded, stable list width
build-dev / nix-build (push) Successful in 43s
build-dev / nix-build (push) Successful in 43s
- Sub-categories start expanded and cannot be collapsed - Only root categories toggle open/closed - LEFT on a sub-category is ignored (navigates to parent for depth-2) - [+]/[-] indicators only shown on root categories - Bounding box width computed over all items to prevent horizontal shifting when groups expand or collapse
This commit is contained in:
@@ -198,7 +198,7 @@ void ProclamationOptionsPage::rebuildItems()
|
|||||||
FlatItem::Type::SubCategory,
|
FlatItem::Type::SubCategory,
|
||||||
std::to_string(sub.id),
|
std::to_string(sub.id),
|
||||||
sub.name,
|
sub.name,
|
||||||
1, false, false, false,
|
1, true, false, false,
|
||||||
});
|
});
|
||||||
|
|
||||||
for (const auto& p : proclamations_) {
|
for (const auto& p : proclamations_) {
|
||||||
@@ -268,7 +268,7 @@ void ProclamationOptionsPage::rebuildVisible()
|
|||||||
parentVisible = true; // the always-on top-level proclamation
|
parentVisible = true; // the always-on top-level proclamation
|
||||||
} else if (currentRoot >= 0 && items_[currentRoot].expanded) {
|
} else if (currentRoot >= 0 && items_[currentRoot].expanded) {
|
||||||
parentVisible = (item.depth == 1) ||
|
parentVisible = (item.depth == 1) ||
|
||||||
(item.depth == 2 && currentSub >= 0 && items_[currentSub].expanded);
|
(item.depth == 2 && currentSub >= 0);
|
||||||
}
|
}
|
||||||
if (parentVisible) visible_.push_back(i);
|
if (parentVisible) visible_.push_back(i);
|
||||||
}
|
}
|
||||||
@@ -283,7 +283,7 @@ void ProclamationOptionsPage::toggleItem()
|
|||||||
if (visible_.empty()) return;
|
if (visible_.empty()) return;
|
||||||
FlatItem& item = items_[visible_[highlightIndex_]];
|
FlatItem& item = items_[visible_[highlightIndex_]];
|
||||||
|
|
||||||
if (item.type == FlatItem::Type::RootCategory || item.type == FlatItem::Type::SubCategory) {
|
if (item.type == FlatItem::Type::RootCategory) {
|
||||||
item.expanded = !item.expanded;
|
item.expanded = !item.expanded;
|
||||||
rebuildVisible();
|
rebuildVisible();
|
||||||
return;
|
return;
|
||||||
@@ -388,7 +388,7 @@ void ProclamationOptionsPage::collapseCurrent()
|
|||||||
{
|
{
|
||||||
if (visible_.empty()) return;
|
if (visible_.empty()) return;
|
||||||
FlatItem& item = items_[visible_[highlightIndex_]];
|
FlatItem& item = items_[visible_[highlightIndex_]];
|
||||||
if (item.type == FlatItem::Type::RootCategory || item.type == FlatItem::Type::SubCategory) {
|
if (item.type == FlatItem::Type::RootCategory) {
|
||||||
if (item.expanded) {
|
if (item.expanded) {
|
||||||
item.expanded = false;
|
item.expanded = false;
|
||||||
rebuildVisible();
|
rebuildVisible();
|
||||||
@@ -400,7 +400,7 @@ void ProclamationOptionsPage::expandCurrent()
|
|||||||
{
|
{
|
||||||
if (visible_.empty()) return;
|
if (visible_.empty()) return;
|
||||||
FlatItem& item = items_[visible_[highlightIndex_]];
|
FlatItem& item = items_[visible_[highlightIndex_]];
|
||||||
if (item.type == FlatItem::Type::RootCategory || item.type == FlatItem::Type::SubCategory) {
|
if (item.type == FlatItem::Type::RootCategory) {
|
||||||
if (!item.expanded) {
|
if (!item.expanded) {
|
||||||
item.expanded = true;
|
item.expanded = true;
|
||||||
rebuildVisible();
|
rebuildVisible();
|
||||||
@@ -526,8 +526,7 @@ void ProclamationOptionsPage::handleEvent(const SDL_Event& event)
|
|||||||
if (searchActive_) return;
|
if (searchActive_) return;
|
||||||
if (!visible_.empty()) {
|
if (!visible_.empty()) {
|
||||||
const FlatItem& item = items_[visible_[highlightIndex_]];
|
const FlatItem& item = items_[visible_[highlightIndex_]];
|
||||||
if ((item.type == FlatItem::Type::RootCategory ||
|
if (item.type == FlatItem::Type::RootCategory && item.expanded) {
|
||||||
item.type == FlatItem::Type::SubCategory) && item.expanded) {
|
|
||||||
collapseCurrent();
|
collapseCurrent();
|
||||||
} else {
|
} else {
|
||||||
moveToParent();
|
moveToParent();
|
||||||
@@ -655,14 +654,18 @@ void ProclamationOptionsPage::render(SDL_Renderer* renderer)
|
|||||||
SDL_RenderTexture(renderer, emptyHintText_.texture, nullptr, &dst);
|
SDL_RenderTexture(renderer, emptyHintText_.texture, nullptr, &dst);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Compute the widest row so the block can be centered.
|
// Stable width: compute from every result so the list doesn't shift.
|
||||||
float maxTotalWidth = 0.0f;
|
float maxTotalWidth = 0.0f;
|
||||||
|
for (const auto& r : searchResults_) {
|
||||||
|
int w = 0, h = 0;
|
||||||
|
TTF_GetStringSize(fontItem_, proclamations_[r].title.c_str(), 0, &w, &h);
|
||||||
|
maxTotalWidth = std::max(maxTotalWidth, static_cast<float>(w));
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<float> textWidths(static_cast<size_t>(listSize));
|
std::vector<float> textWidths(static_cast<size_t>(listSize));
|
||||||
for (int i = scrollOffset_; i < scrollOffset_ + visibleCount_ && i < listSize; ++i) {
|
for (int i = scrollOffset_; i < scrollOffset_ + visibleCount_ && i < listSize; ++i) {
|
||||||
const std::string& label = proclamations_[searchResults_[i]].title;
|
|
||||||
int w = 0, h = 0;
|
int w = 0, h = 0;
|
||||||
TTF_GetStringSize(fontItem_, label.c_str(), 0, &w, &h);
|
TTF_GetStringSize(fontItem_, proclamations_[searchResults_[i]].title.c_str(), 0, &w, &h);
|
||||||
maxTotalWidth = std::max(maxTotalWidth, static_cast<float>(w));
|
|
||||||
textWidths[i] = static_cast<float>(w);
|
textWidths[i] = static_cast<float>(w);
|
||||||
}
|
}
|
||||||
float sharedX = (fw - maxTotalWidth) / 2.0f;
|
float sharedX = (fw - maxTotalWidth) / 2.0f;
|
||||||
@@ -695,19 +698,29 @@ void ProclamationOptionsPage::render(SDL_Renderer* renderer)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// --- Browse tree ---
|
// --- Browse tree ---
|
||||||
// Compute the widest row so the block can be centered.
|
// Stable width: compute from every item so the list doesn't
|
||||||
|
// shift left/right when groups expand or collapse.
|
||||||
float maxTotalWidth = 0.0f;
|
float maxTotalWidth = 0.0f;
|
||||||
std::vector<float> textWidths(visible_.size());
|
for (const auto& item : items_) {
|
||||||
for (int i = scrollOffset_; i < scrollOffset_ + visibleCount_ && i < static_cast<int>(visible_.size()); ++i) {
|
|
||||||
const FlatItem& item = items_[visible_[i]];
|
|
||||||
std::string label = item.label;
|
std::string label = item.label;
|
||||||
if (item.type == FlatItem::Type::RootCategory || item.type == FlatItem::Type::SubCategory) {
|
if (item.type == FlatItem::Type::RootCategory) {
|
||||||
label = (item.expanded ? "[-] " : "[+] ") + label;
|
label = (item.expanded ? "[-] " : "[+] ") + label;
|
||||||
}
|
}
|
||||||
int w = 0, h = 0;
|
int w = 0, h = 0;
|
||||||
TTF_GetStringSize(fontItem_, label.c_str(), 0, &w, &h);
|
TTF_GetStringSize(fontItem_, label.c_str(), 0, &w, &h);
|
||||||
float total = item.depth * indent + static_cast<float>(w);
|
float total = item.depth * indent + static_cast<float>(w);
|
||||||
maxTotalWidth = std::max(maxTotalWidth, total);
|
maxTotalWidth = std::max(maxTotalWidth, total);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<float> textWidths(visible_.size());
|
||||||
|
for (int i = scrollOffset_; i < scrollOffset_ + visibleCount_ && i < static_cast<int>(visible_.size()); ++i) {
|
||||||
|
const FlatItem& item = items_[visible_[i]];
|
||||||
|
std::string label = item.label;
|
||||||
|
if (item.type == FlatItem::Type::RootCategory) {
|
||||||
|
label = (item.expanded ? "[-] " : "[+] ") + label;
|
||||||
|
}
|
||||||
|
int w = 0, h = 0;
|
||||||
|
TTF_GetStringSize(fontItem_, label.c_str(), 0, &w, &h);
|
||||||
textWidths[i] = static_cast<float>(w);
|
textWidths[i] = static_cast<float>(w);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -721,7 +734,7 @@ void ProclamationOptionsPage::render(SDL_Renderer* renderer)
|
|||||||
float y = listTop + rowIndex * rowPitch;
|
float y = listTop + rowIndex * rowPitch;
|
||||||
|
|
||||||
std::string label = item.label;
|
std::string label = item.label;
|
||||||
if (item.type == FlatItem::Type::RootCategory || item.type == FlatItem::Type::SubCategory) {
|
if (item.type == FlatItem::Type::RootCategory) {
|
||||||
label = (item.expanded ? "[-] " : "[+] ") + label;
|
label = (item.expanded ? "[-] " : "[+] ") + label;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user