Open dropdowns within the visible part of their list
ElementContext carries the part of the screen where an element can be seen, passed down in a Frame and narrowed by each Scroll to its own box. A dropdown opens below only if its list fits in that part, otherwise above if it fits there, or else on the side with more room, so one at the bottom of a scrolled list no longer opens past the list's edge. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
@@ -37,20 +37,25 @@ public final class Popup {
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens {@code popup} just below its owner, or above it when there isn't
|
||||
* room below.
|
||||
* Opens {@code popup} just below its owner if it fits in the part of the
|
||||
* screen where the owner can be seen, such as a scroll's box; otherwise
|
||||
* above it if it fits there, or else on the side with more room.
|
||||
*
|
||||
* @param originX the owner's top-left corner on the screen
|
||||
* @param originY
|
||||
* @param ownerContext the owner's context from its last render
|
||||
*/
|
||||
public static void openBelow(Element owner, Element popup, int originX, int originY) {
|
||||
int y = originY + owner.height + OWNER_GAP;
|
||||
public static void openBelow(Element owner, Element popup, ElementContext ownerContext) {
|
||||
int top = Math.max(ownerContext.visibleTop, SCREEN_MARGIN);
|
||||
int bottom = Math.min(ownerContext.visibleBottom, screenHeight - SCREEN_MARGIN);
|
||||
|
||||
if (y + popup.height > screenHeight - SCREEN_MARGIN) {
|
||||
y = originY - OWNER_GAP - popup.height;
|
||||
}
|
||||
int below = ownerContext.originY + owner.height + OWNER_GAP;
|
||||
int above = ownerContext.originY - OWNER_GAP - popup.height;
|
||||
|
||||
open(owner, popup, originX, y);
|
||||
boolean fitsBelow = below + popup.height <= bottom;
|
||||
boolean fitsAbove = above >= top;
|
||||
boolean moreRoomBelow = bottom - below >= ownerContext.originY - OWNER_GAP - top;
|
||||
|
||||
int y = fitsBelow || (!fitsAbove && moreRoomBelow) ? below : above;
|
||||
open(owner, popup, ownerContext.originX, y);
|
||||
}
|
||||
|
||||
public static void close() {
|
||||
|
||||
Reference in New Issue
Block a user