@@ -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