1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00

PopupMenu: Extract implementation of ensureItemComponentIsVisible into static function

This makes it a bit easier to see exactly which PopupMenu state is used
during the calculation, and enforces that no menu state is modified
during the call.
This commit is contained in:
reuk 2025-08-18 18:10:36 +01:00
parent 90abc8c1c5
commit edfa87801c
No known key found for this signature in database

View file

@ -431,15 +431,15 @@ struct MenuWindow final : public Component
if (iter != items.end()) if (iter != items.end())
{ {
const auto targetPosition = [&] const auto targetPosition = std::invoke ([&]
{ {
if (auto* pc = options.getParentComponent()) if (auto* pc = options.getParentComponent())
return pc->getLocalPoint (nullptr, targetArea.getTopLeft()); return pc->getLocalPoint (nullptr, targetArea.getTopLeft());
return targetArea.getTopLeft(); return targetArea.getTopLeft();
}(); });
auto y = targetPosition.getY() - windowPos.getY(); const auto y = targetPosition.getY() - windowPos.getY();
ensureItemComponentIsVisible (**iter, isPositiveAndBelow (y, windowPos.getHeight()) ? y : -1); ensureItemComponentIsVisible (**iter, isPositiveAndBelow (y, windowPos.getHeight()) ? y : -1);
} }
} }
@ -1093,20 +1093,40 @@ struct MenuWindow final : public Component
void ensureItemComponentIsVisible (const ItemComponent& itemComp, int wantedY) void ensureItemComponentIsVisible (const ItemComponent& itemComp, int wantedY)
{ {
if (windowPos.getHeight() <= PopupMenuSettings::scrollZone * 4 const auto parentArea = getParentArea (windowPos.getPosition(), options.getParentComponent()) / scaleFactor;
|| (wantedY <= 0 && 0 <= itemComp.getY() && itemComp.getBottom() <= windowPos.getHeight()))
if (const auto posAndOffset = computeInitialPosAndOffset (windowPos, parentArea, itemComp.getBounds(), childYOffset, wantedY))
{ {
return; std::tie (windowPos, childYOffset) = std::tie (posAndOffset->windowPos, posAndOffset->childYOffset);
updateYPositions();
}
}
struct PosAndOffset
{
Rectangle<int> windowPos;
int childYOffset = 0;
};
static std::optional<PosAndOffset> computeInitialPosAndOffset (Rectangle<int> windowPos,
const Rectangle<int>& parentArea,
const Rectangle<int>& itemCompBounds,
int childYOffset,
int wantedY)
{
if (windowPos.getHeight() <= PopupMenuSettings::scrollZone * 4
|| (wantedY <= 0 && 0 <= itemCompBounds.getY() && itemCompBounds.getBottom() <= windowPos.getHeight()))
{
return {};
} }
if (wantedY < 0) if (wantedY < 0)
wantedY = jlimit (PopupMenuSettings::scrollZone, wantedY = jlimit (PopupMenuSettings::scrollZone,
jmax (PopupMenuSettings::scrollZone, jmax (PopupMenuSettings::scrollZone,
windowPos.getHeight() - (PopupMenuSettings::scrollZone + itemComp.getHeight())), windowPos.getHeight() - (PopupMenuSettings::scrollZone + itemCompBounds.getHeight())),
itemComp.getY()); itemCompBounds.getY());
const auto parentArea = getParentArea (windowPos.getPosition(), options.getParentComponent()) / scaleFactor; const auto deltaY = windowPos.getY() + wantedY - itemCompBounds.getY();
const auto deltaY = windowPos.getY() + wantedY - itemComp.getY();
windowPos.setSize (jmin (windowPos.getWidth(), parentArea.getWidth()), windowPos.setSize (jmin (windowPos.getWidth(), parentArea.getWidth()),
jmin (windowPos.getHeight(), parentArea.getHeight())); jmin (windowPos.getHeight(), parentArea.getHeight()));
@ -1118,7 +1138,7 @@ struct MenuWindow final : public Component
childYOffset -= (deltaY - newY); childYOffset -= (deltaY - newY);
windowPos.setPosition (windowPos.getX(), newY); windowPos.setPosition (windowPos.getX(), newY);
updateYPositions(); return PosAndOffset { windowPos, childYOffset };
} }
void resizeToBestWindowPos() void resizeToBestWindowPos()