Skip to content

Commit 66e16b6

Browse files
committed
fix: properly show selected dropdown element, disregarding zoom level and index in the list
1 parent 1fbc336 commit 66e16b6

1 file changed

Lines changed: 27 additions & 18 deletions

File tree

64klang3/src/gui/NodeCanvas.cpp

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2254,35 +2254,44 @@ void NodeCanvas::drawEditPanel(ImDrawList* dl, const ImVec2& canvasOrigin)
22542254
if (canClick && ImGui::IsMouseClicked(ImGuiMouseButton_Left) && hov)
22552255
ImGui::OpenPopup(popupID);
22562256

2257-
// Popup list — capped at 8 visible items, scrollbar if more
2257+
// Popup list — capped at max 8 visible items, scrollbar if more.
2258+
ImGui::PushFont(pickFont(fontSize));
22582259
{
2259-
float itemH = fontSize * 1.35f;
2260-
float padY = ImGui::GetStyle().WindowPadding.y * 2.f;
2261-
float maxH = itemH * 8.f + padY;
2262-
ImGui::SetNextWindowSizeConstraints(ImVec2(0, 0), ImVec2(FLT_MAX, maxH));
2263-
// When maxH won't fit below the button, anchor the bottom of the popup
2264-
// to the top of the button (pivot Y=1) instead of dropping it down.
2260+
float fontScale = fontSize / ImGui::GetFont()->FontSize;
2261+
float itemH = fontSize + ImGui::GetStyle().ItemSpacing.y * fontScale;
2262+
float padY = ImGui::GetStyle().WindowPadding.y * 2.f;
2263+
float scrollW = ImGui::GetStyle().ScrollbarSize;
2264+
float popupW = btnW + scrollW;
2265+
float popupH = itemH * std::min(8, (int)mg.items.size()) + padY;
2266+
ImGui::SetNextWindowSize(ImVec2(popupW, popupH), ImGuiCond_Always);
22652267
float screenH = ImGui::GetIO().DisplaySize.y;
2266-
if (btnMax.y + maxH > screenH)
2268+
if (btnMax.y + popupH > screenH)
22672269
ImGui::SetNextWindowPos(ImVec2(btnMin.x, btnMin.y), ImGuiCond_Always, ImVec2(0.0f, 1.0f));
22682270
else
22692271
ImGui::SetNextWindowPos(ImVec2(btnMin.x, btnMax.y), ImGuiCond_Always, ImVec2(0.0f, 0.0f));
22702272
}
2271-
ImGui::PushFont(pickFont(fontSize));
22722273
if (ImGui::BeginPopup(popupID))
22732274
{
2274-
ImGui::SetWindowFontScale(fontSize / ImGui::GetFont()->FontSize);
2275-
for (int j = 0; j < (int)mg.items.size(); j++)
2275+
float fontScale = fontSize / ImGui::GetFont()->FontSize;
2276+
ImGui::SetWindowFontScale(fontScale);
2277+
float itemH = fontSize + ImGui::GetStyle().ItemSpacing.y * fontScale;
2278+
ImGuiListClipper clipper;
2279+
clipper.Begin((int)mg.items.size(), itemH);
2280+
clipper.IncludeItemByIndex(activeIdx); // always render selected item
2281+
while (clipper.Step())
22762282
{
2277-
bool selected = (j == activeIdx);
2278-
if (ImGui::Selectable(mg.items[j].name.c_str(), selected, 0, ImVec2(btnW, 0)))
2283+
for (int j = clipper.DisplayStart; j < clipper.DisplayEnd; j++)
22792284
{
2280-
int newBits = (currentBits & ~(int)mg.mask) | (mg.items[j].value << mg.shift);
2281-
sc->setInputMode((DWORD)nodeID, (DWORD)modeInputIdx, (DWORD)newBits, (DWORD)mg.mask);
2282-
currentBits = newBits;
2285+
bool selected = (j == activeIdx);
2286+
if (ImGui::Selectable(mg.items[j].name.c_str(), selected, 0, ImVec2(btnW, 0)))
2287+
{
2288+
int newBits = (currentBits & ~(int)mg.mask) | (mg.items[j].value << mg.shift);
2289+
sc->setInputMode((DWORD)nodeID, (DWORD)modeInputIdx, (DWORD)newBits, (DWORD)mg.mask);
2290+
currentBits = newBits;
2291+
}
2292+
if (selected)
2293+
ImGui::SetItemDefaultFocus(); // focus/center the selected item
22832294
}
2284-
if (selected)
2285-
ImGui::SetItemDefaultFocus();
22862295
}
22872296
ImGui::EndPopup();
22882297
}

0 commit comments

Comments
 (0)