From 6c61c41331c43b990ee69f3655bb81491157a2f9 Mon Sep 17 00:00:00 2001 From: liannacasper <67953602+liannacasper@users.noreply.github.com> Date: Wed, 1 Apr 2026 08:09:06 +0300 Subject: [PATCH 1/7] Refine popup bias screenshot test around centered target and fallback --- .../components/InteractionDialog.java | 82 ++++++++++--------- .../components/InteractionDialogTest.java | 55 +++++++++++++ .../tests/Cn1ssDeviceRunner.java | 1 + ...eractionDialogPopupBiasScreenshotTest.java | 66 +++++++++++++++ 4 files changed, 167 insertions(+), 37 deletions(-) create mode 100644 scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/InteractionDialogPopupBiasScreenshotTest.java diff --git a/CodenameOne/src/com/codename1/components/InteractionDialog.java b/CodenameOne/src/com/codename1/components/InteractionDialog.java index d06c410259..00c2f6bdca 100644 --- a/CodenameOne/src/com/codename1/components/InteractionDialog.java +++ b/CodenameOne/src/com/codename1/components/InteractionDialog.java @@ -637,9 +637,10 @@ public void showPopupDialog(Component c) { /// /// - `c`: the context component which is used to position the dialog and can also be pointed at /// - /// - `bias`: @param bias biases the dialog to appear above/below or to the sides. - /// This is ignored if there isn't enough space - public void showPopupDialog(Component c, boolean bias) { + /// - `prioritizeTopOrRightPosition`: if `true`, prefer showing above the target (portrait layout) or to + /// the right of the target (landscape layout) when both positions fit. If `false`, prefer below/left. + /// If there isn't enough room in the preferred position, the dialog falls back automatically. + public void showPopupDialog(Component c, boolean prioritizeTopOrRightPosition) { if (c == null) { throw new IllegalArgumentException("Component cannot be null"); } @@ -653,7 +654,7 @@ public void showPopupDialog(Component c, boolean bias) { componentPos.setX(componentPos.getX() - c.getScrollX()); componentPos.setY(componentPos.getY() - c.getScrollY()); setOwner(c); - showPopupDialog(componentPos, bias); + showPopupDialog(componentPos, prioritizeTopOrRightPosition); } /// A popup dialog is shown with the context of a component and its selection. You should use `#setDisposeWhenPointerOutOfBounds(boolean)` to make it dispose @@ -675,9 +676,10 @@ public void showPopupDialog(Rectangle rect) { /// /// - `rect`: the screen rectangle to which the popup should point /// - /// - `bias`: @param bias biases the dialog to appear above/below or to the sides. - /// This is ignored if there isn't enough space - public void showPopupDialog(Rectangle rect, boolean bias) { + /// - `prioritizeTopOrRightPosition`: if `true`, prefer showing above the target (portrait layout) or to + /// the right of the target (landscape layout) when both positions fit. If `false`, prefer below/left. + /// If there isn't enough room in the preferred position, the dialog falls back automatically. + public void showPopupDialog(Rectangle rect, boolean prioritizeTopOrRightPosition) { if (rect == null) { throw new IllegalArgumentException("rect cannot be null"); } @@ -762,7 +764,7 @@ public void showPopupDialog(Rectangle rect, boolean bias) { int x = 0; int y = 0; - boolean showPortrait = bias; + boolean showPortrait = Display.getInstance().isPortrait(); // if we don't have enough space then disregard device orientation if (showPortrait) { @@ -790,7 +792,22 @@ public void showPopupDialog(Rectangle rect, boolean bias) { } } } - if (rect.getY() + rect.getHeight() < availableHeight / 2) { + int spaceAbove = rect.getY(); + int spaceBelow = availableHeight - (rect.getY() + rect.getHeight()); + boolean canShowAbove = prefHeight <= spaceAbove; + boolean canShowBelow = prefHeight <= spaceBelow; + boolean showAbove; + if (canShowAbove && canShowBelow) { + showAbove = prioritizeTopOrRightPosition; + } else if (canShowAbove) { + showAbove = true; + } else if (canShowBelow) { + showAbove = false; + } else { + showAbove = spaceAbove >= spaceBelow; + } + + if (!showAbove) { // popup downwards y = rect.getY() + rect.getHeight(); int height = Math.min(prefHeight, Math.max(0, availableHeight - y)); @@ -798,30 +815,13 @@ public void showPopupDialog(Rectangle rect, boolean bias) { show(Math.max(0, y), Math.max(0, availableHeight - height - y), Math.max(0, x), Math.max(0, availableWidth - width - x)); padOrientation(contentPaneStyle, TOP, -1); - } else if (rect.getY() > availableHeight / 2) { + } else { // popup upwards int height = Math.min(prefHeight, rect.getY()); y = rect.getY() - height; padOrientation(contentPaneStyle, BOTTOM, 1); show(y, Math.max(0, availableHeight - rect.getY()), x, Math.max(0, availableWidth - width - x)); padOrientation(contentPaneStyle, BOTTOM, -1); - } else if (rect.getY() < availableHeight / 2) { - // popup over aligned with top of rect, but inset a few mm - y = rect.getY() + CN.convertToPixels(3); - - int height = Math.min(prefHeight, availableHeight - y); - padOrientation(contentPaneStyle, BOTTOM, 1); - show(y, Math.max(0, availableHeight - height - y), - Math.max(0, x), Math.max(0, availableWidth - width - x)); - padOrientation(contentPaneStyle, BOTTOM, -1); - } else { - // popup over aligned with bottom of rect but inset a few mm - y = Math.max(0, rect.getY() + rect.getHeight() - CN.convertToPixels(3) - prefHeight); - int height = prefHeight; - padOrientation(contentPaneStyle, TOP, 1); - show(y, Math.max(0, availableHeight - height - y), - Math.max(0, x), Math.max(0, availableWidth - width - x)); - padOrientation(contentPaneStyle, TOP, -1); } } else { int height = Math.min(prefHeight, availableHeight); @@ -839,23 +839,31 @@ public void showPopupDialog(Rectangle rect, boolean bias) { } } - if (prefWidth < availableWidth - rect.getX() - rect.getWidth()) { + int spaceRight = availableWidth - rect.getX() - rect.getWidth(); + int spaceLeft = rect.getX(); + boolean canShowRight = prefWidth <= spaceRight; + boolean canShowLeft = prefWidth <= spaceLeft; + boolean showRight; + if (canShowRight && canShowLeft) { + showRight = prioritizeTopOrRightPosition; + } else if (canShowRight) { + showRight = true; + } else if (canShowLeft) { + showRight = false; + } else { + showRight = spaceRight >= spaceLeft; + } + + if (showRight) { // popup right x = rect.getX() + rect.getWidth(); - - width = Math.min(prefWidth, availableWidth - x); - show(y, availableHeight - height - y, Math.max(0, x), Math.max(0, availableWidth - width - x)); - } else if (prefWidth < rect.getX()) { - x = rect.getX() - prefWidth; - width = prefWidth; - show(y, availableHeight - height - y, Math.max(0, x), Math.max(0, availableWidth - width - x)); } else { // popup left - width = Math.min(prefWidth, availableWidth - (availableWidth - rect.getX())); + width = Math.min(prefWidth, rect.getX()); x = rect.getX() - width; - show(y, availableHeight - height - y, Math.max(0, x), Math.max(0, availableWidth - width - x)); } + show(y, availableHeight - height - y, Math.max(0, x), Math.max(0, availableWidth - width - x)); } } diff --git a/maven/core-unittests/src/test/java/com/codename1/components/InteractionDialogTest.java b/maven/core-unittests/src/test/java/com/codename1/components/InteractionDialogTest.java index d72211c9eb..5197672c26 100644 --- a/maven/core-unittests/src/test/java/com/codename1/components/InteractionDialogTest.java +++ b/maven/core-unittests/src/test/java/com/codename1/components/InteractionDialogTest.java @@ -5,6 +5,7 @@ import com.codename1.ui.Container; import com.codename1.ui.Form; import com.codename1.ui.Label; +import com.codename1.ui.layouts.FlowLayout; import com.codename1.ui.geom.Rectangle; import com.codename1.ui.layouts.BorderLayout; @@ -97,6 +98,60 @@ void formModeUsesFormLayeredPane() { dialog.dispose(); } + @Test + void showPopupDialogBiasTruePrefersTopWhenBothFit() { + Form form = new Form(new BorderLayout()); + implementation.setCurrentForm(form); + + InteractionDialog dialog = new InteractionDialog(); + dialog.setLayout(new FlowLayout()); + dialog.add(new Label("Popup")); + dialog.setAnimateShow(false); + + Rectangle rect = new Rectangle(120, 220, 60, 40); + dialog.showPopupDialog(rect, true); + + assertTrue(dialog.getY() + dialog.getHeight() <= rect.getY(), + "Expected popup above target when prioritizeTopOrRightPosition=true"); + dialog.dispose(); + } + + @Test + void showPopupDialogBiasFalsePrefersBottomWhenBothFit() { + Form form = new Form(new BorderLayout()); + implementation.setCurrentForm(form); + + InteractionDialog dialog = new InteractionDialog(); + dialog.setLayout(new FlowLayout()); + dialog.add(new Label("Popup")); + dialog.setAnimateShow(false); + + Rectangle rect = new Rectangle(120, 220, 60, 40); + dialog.showPopupDialog(rect, false); + + assertTrue(dialog.getY() >= rect.getY() + rect.getHeight(), + "Expected popup below target when prioritizeTopOrRightPosition=false"); + dialog.dispose(); + } + + @Test + void showPopupDialogFallsBackWhenPreferredTopDoesNotFit() { + Form form = new Form(new BorderLayout()); + implementation.setCurrentForm(form); + + InteractionDialog dialog = new InteractionDialog(); + dialog.setLayout(new FlowLayout()); + dialog.add(new Label("Popup")); + dialog.setAnimateShow(false); + + Rectangle rect = new Rectangle(120, 2, 60, 40); + dialog.showPopupDialog(rect, true); + + assertTrue(dialog.getY() >= rect.getY() + rect.getHeight(), + "Expected fallback below when preferred top side does not fit"); + dialog.dispose(); + } + private T getPrivateField(Object target, String name, Class type) throws Exception { Field field = target.getClass().getDeclaredField(name); field.setAccessible(true); diff --git a/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/Cn1ssDeviceRunner.java b/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/Cn1ssDeviceRunner.java index 29d31a3a1f..6ad6468272 100644 --- a/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/Cn1ssDeviceRunner.java +++ b/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/Cn1ssDeviceRunner.java @@ -69,6 +69,7 @@ public final class Cn1ssDeviceRunner extends DeviceRunner { new BrowserComponentScreenshotTest(), new MediaPlaybackScreenshotTest(), new SheetScreenshotTest(), + new InteractionDialogPopupBiasScreenshotTest(), new ImageViewerNavigationScreenshotTest(), new TextAreaAlignmentScreenshotTest(), // Keep this as the last screenshot test; orientation changes can leak into subsequent screenshots. diff --git a/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/InteractionDialogPopupBiasScreenshotTest.java b/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/InteractionDialogPopupBiasScreenshotTest.java new file mode 100644 index 0000000000..a09b691271 --- /dev/null +++ b/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/InteractionDialogPopupBiasScreenshotTest.java @@ -0,0 +1,66 @@ +package com.codenameone.examples.hellocodenameone.tests; + +import com.codename1.components.InteractionDialog; +import com.codename1.ui.Component; +import com.codename1.ui.Container; +import com.codename1.ui.Form; +import com.codename1.ui.Label; +import com.codename1.ui.geom.Rectangle; +import com.codename1.ui.layouts.BorderLayout; +import com.codename1.ui.layouts.BoxLayout; +import com.codename1.ui.layouts.FlowLayout; +import com.codename1.ui.util.UITimer; + +public class InteractionDialogPopupBiasScreenshotTest extends BaseTest { + private InteractionDialog preferredSideDialog; + private InteractionDialog fallbackSideDialog; + + @Override + public boolean runTest() { + Form form = createForm("InteractionDialog Popup Bias", new BorderLayout(), "InteractionDialogPopupBias"); + Container center = new Container(new FlowLayout(Component.CENTER, Component.CENTER)); + Label target = new Label("CENTER TARGET"); + target.getAllStyles().setPaddingMillimeters(2f, 2f, 2f, 2f); + center.add(target); + form.add(BorderLayout.CENTER, center); + form.add(BorderLayout.NORTH, new Label("Top popup: bias works (prefers top when possible)")); + form.add(BorderLayout.SOUTH, new Label("Bottom popup: bias fallback (top requested but unavailable)")); + form.show(); + return true; + } + + @Override + protected void registerReadyCallback(Form parent, Runnable run) { + preferredSideDialog = createDialog("bias=true -> prefers top"); + fallbackSideDialog = createDialog("bias=true -> falls back to bottom"); + int width = parent.getWidth(); + int height = parent.getHeight(); + + // Center target: enough room above and below, so bias=true should place popup above. + Rectangle centerTarget = new Rectangle(width / 2 - 45, height / 2 - 12, 90, 24); + preferredSideDialog.showPopupDialog(centerTarget, true); + + // Near top target: not enough room above, so bias=true should fall back below. + Rectangle topEdgeTarget = new Rectangle(width / 2 - 45, 4, 90, 24); + fallbackSideDialog.showPopupDialog(topEdgeTarget, true); + UITimer.timer(600, false, parent, run); + } + + @Override + public void cleanup() { + if (preferredSideDialog != null && preferredSideDialog.isShowing()) { + preferredSideDialog.dispose(); + } + if (fallbackSideDialog != null && fallbackSideDialog.isShowing()) { + fallbackSideDialog.dispose(); + } + } + + private InteractionDialog createDialog(String text) { + InteractionDialog dialog = new InteractionDialog(); + dialog.setLayout(BoxLayout.y()); + dialog.add(new Label(text)); + dialog.setDisposeWhenPointerOutOfBounds(false); + return dialog; + } +} From 85a2abbdfea3044bec7670ad23e506497cbb0e2b Mon Sep 17 00:00:00 2001 From: liannacasper <67953602+liannacasper@users.noreply.github.com> Date: Wed, 1 Apr 2026 08:59:09 +0300 Subject: [PATCH 2/7] Fix screenshot test style padding API usage --- .../tests/InteractionDialogPopupBiasScreenshotTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/InteractionDialogPopupBiasScreenshotTest.java b/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/InteractionDialogPopupBiasScreenshotTest.java index a09b691271..cd13a341ff 100644 --- a/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/InteractionDialogPopupBiasScreenshotTest.java +++ b/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/InteractionDialogPopupBiasScreenshotTest.java @@ -20,7 +20,7 @@ public boolean runTest() { Form form = createForm("InteractionDialog Popup Bias", new BorderLayout(), "InteractionDialogPopupBias"); Container center = new Container(new FlowLayout(Component.CENTER, Component.CENTER)); Label target = new Label("CENTER TARGET"); - target.getAllStyles().setPaddingMillimeters(2f, 2f, 2f, 2f); + target.getAllStyles().setPadding(2, 2, 2, 2); center.add(target); form.add(BorderLayout.CENTER, center); form.add(BorderLayout.NORTH, new Label("Top popup: bias works (prefers top when possible)")); From c5f82befe1011b5dc1e4ef93fb39e1d18948aa2b Mon Sep 17 00:00:00 2001 From: liannacasper <67953602+liannacasper@users.noreply.github.com> Date: Wed, 1 Apr 2026 09:22:23 +0300 Subject: [PATCH 3/7] Expand popup bias tests and fix screenshot layout --- .../components/InteractionDialogTest.java | 96 +++++++++++++++++++ ...eractionDialogPopupBiasScreenshotTest.java | 32 +++---- 2 files changed, 111 insertions(+), 17 deletions(-) diff --git a/maven/core-unittests/src/test/java/com/codename1/components/InteractionDialogTest.java b/maven/core-unittests/src/test/java/com/codename1/components/InteractionDialogTest.java index 5197672c26..4f1924f87e 100644 --- a/maven/core-unittests/src/test/java/com/codename1/components/InteractionDialogTest.java +++ b/maven/core-unittests/src/test/java/com/codename1/components/InteractionDialogTest.java @@ -152,6 +152,102 @@ void showPopupDialogFallsBackWhenPreferredTopDoesNotFit() { dialog.dispose(); } + @Test + void showPopupDialogFallsBackWhenPreferredBottomDoesNotFit() { + Form form = new Form(new BorderLayout()); + implementation.setCurrentForm(form); + + InteractionDialog dialog = new InteractionDialog(); + dialog.setLayout(new FlowLayout()); + dialog.add(new Label("Popup")); + dialog.setAnimateShow(false); + + int displayHeight = implementation.getDisplayHeight(); + Rectangle rect = new Rectangle(120, Math.max(0, displayHeight - 8), 60, 6); + dialog.showPopupDialog(rect, false); + + assertTrue(dialog.getY() + dialog.getHeight() <= rect.getY(), + "Expected fallback above when preferred bottom side does not fit"); + dialog.dispose(); + } + + @Test + void showPopupDialogBiasTruePrefersRightInLandscapeWhenBothFit() { + implementation.setPortrait(false); + Form form = new Form(new BorderLayout()); + implementation.setCurrentForm(form); + + InteractionDialog dialog = new InteractionDialog(); + dialog.setLayout(new FlowLayout()); + dialog.add(new Label("Popup")); + dialog.setAnimateShow(false); + + Rectangle rect = new Rectangle(120, 140, 60, 40); + dialog.showPopupDialog(rect, true); + + assertTrue(dialog.getX() >= rect.getX() + rect.getWidth(), + "Expected popup on right side when prioritizeTopOrRightPosition=true in landscape"); + dialog.dispose(); + } + + @Test + void showPopupDialogBiasFalsePrefersLeftInLandscapeWhenBothFit() { + implementation.setPortrait(false); + Form form = new Form(new BorderLayout()); + implementation.setCurrentForm(form); + + InteractionDialog dialog = new InteractionDialog(); + dialog.setLayout(new FlowLayout()); + dialog.add(new Label("Popup")); + dialog.setAnimateShow(false); + + Rectangle rect = new Rectangle(120, 140, 60, 40); + dialog.showPopupDialog(rect, false); + + assertTrue(dialog.getX() + dialog.getWidth() <= rect.getX(), + "Expected popup on left side when prioritizeTopOrRightPosition=false in landscape"); + dialog.dispose(); + } + + @Test + void showPopupDialogFallsBackWhenPreferredRightDoesNotFit() { + implementation.setPortrait(false); + Form form = new Form(new BorderLayout()); + implementation.setCurrentForm(form); + + InteractionDialog dialog = new InteractionDialog(); + dialog.setLayout(new FlowLayout()); + dialog.add(new Label("Popup")); + dialog.setAnimateShow(false); + + int displayWidth = implementation.getDisplayWidth(); + Rectangle rect = new Rectangle(Math.max(0, displayWidth - 8), 140, 6, 40); + dialog.showPopupDialog(rect, true); + + assertTrue(dialog.getX() + dialog.getWidth() <= rect.getX(), + "Expected fallback to left when preferred right side does not fit"); + dialog.dispose(); + } + + @Test + void showPopupDialogFallsBackWhenPreferredLeftDoesNotFit() { + implementation.setPortrait(false); + Form form = new Form(new BorderLayout()); + implementation.setCurrentForm(form); + + InteractionDialog dialog = new InteractionDialog(); + dialog.setLayout(new FlowLayout()); + dialog.add(new Label("Popup")); + dialog.setAnimateShow(false); + + Rectangle rect = new Rectangle(2, 140, 6, 40); + dialog.showPopupDialog(rect, false); + + assertTrue(dialog.getX() >= rect.getX() + rect.getWidth(), + "Expected fallback to right when preferred left side does not fit"); + dialog.dispose(); + } + private T getPrivateField(Object target, String name, Class type) throws Exception { Field field = target.getClass().getDeclaredField(name); field.setAccessible(true); diff --git a/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/InteractionDialogPopupBiasScreenshotTest.java b/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/InteractionDialogPopupBiasScreenshotTest.java index cd13a341ff..8ee21c3246 100644 --- a/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/InteractionDialogPopupBiasScreenshotTest.java +++ b/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/InteractionDialogPopupBiasScreenshotTest.java @@ -12,8 +12,8 @@ import com.codename1.ui.util.UITimer; public class InteractionDialogPopupBiasScreenshotTest extends BaseTest { - private InteractionDialog preferredSideDialog; - private InteractionDialog fallbackSideDialog; + private InteractionDialog topPreferredDialog; + private InteractionDialog bottomPreferredDialog; @Override public boolean runTest() { @@ -23,36 +23,34 @@ public boolean runTest() { target.getAllStyles().setPadding(2, 2, 2, 2); center.add(target); form.add(BorderLayout.CENTER, center); - form.add(BorderLayout.NORTH, new Label("Top popup: bias works (prefers top when possible)")); - form.add(BorderLayout.SOUTH, new Label("Bottom popup: bias fallback (top requested but unavailable)")); + form.add(BorderLayout.NORTH, new Label("bias=true : popup should be ABOVE top target")); + form.add(BorderLayout.SOUTH, new Label("bias=false : popup should be BELOW bottom target")); form.show(); return true; } @Override protected void registerReadyCallback(Form parent, Runnable run) { - preferredSideDialog = createDialog("bias=true -> prefers top"); - fallbackSideDialog = createDialog("bias=true -> falls back to bottom"); + topPreferredDialog = createDialog("bias=true -> above target"); + bottomPreferredDialog = createDialog("bias=false -> below target"); int width = parent.getWidth(); int height = parent.getHeight(); - // Center target: enough room above and below, so bias=true should place popup above. - Rectangle centerTarget = new Rectangle(width / 2 - 45, height / 2 - 12, 90, 24); - preferredSideDialog.showPopupDialog(centerTarget, true); - - // Near top target: not enough room above, so bias=true should fall back below. - Rectangle topEdgeTarget = new Rectangle(width / 2 - 45, 4, 90, 24); - fallbackSideDialog.showPopupDialog(topEdgeTarget, true); + // Keep the targets far apart to avoid overlap in screenshot. + Rectangle upperTarget = new Rectangle(width / 2 - 45, height / 3, 90, 24); + Rectangle lowerTarget = new Rectangle(width / 2 - 45, (height * 2 / 3) - 24, 90, 24); + topPreferredDialog.showPopupDialog(upperTarget, true); + bottomPreferredDialog.showPopupDialog(lowerTarget, false); UITimer.timer(600, false, parent, run); } @Override public void cleanup() { - if (preferredSideDialog != null && preferredSideDialog.isShowing()) { - preferredSideDialog.dispose(); + if (topPreferredDialog != null && topPreferredDialog.isShowing()) { + topPreferredDialog.dispose(); } - if (fallbackSideDialog != null && fallbackSideDialog.isShowing()) { - fallbackSideDialog.dispose(); + if (bottomPreferredDialog != null && bottomPreferredDialog.isShowing()) { + bottomPreferredDialog.dispose(); } } From 8814eb42d55c2ee5fadc7336fb10107e43b91c7a Mon Sep 17 00:00:00 2001 From: liannacasper <67953602+liannacasper@users.noreply.github.com> Date: Wed, 1 Apr 2026 10:39:37 +0300 Subject: [PATCH 4/7] Add third popup scenario to screenshot bias test --- .../InteractionDialogPopupBiasScreenshotTest.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/InteractionDialogPopupBiasScreenshotTest.java b/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/InteractionDialogPopupBiasScreenshotTest.java index 8ee21c3246..86352746c4 100644 --- a/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/InteractionDialogPopupBiasScreenshotTest.java +++ b/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/InteractionDialogPopupBiasScreenshotTest.java @@ -14,6 +14,7 @@ public class InteractionDialogPopupBiasScreenshotTest extends BaseTest { private InteractionDialog topPreferredDialog; private InteractionDialog bottomPreferredDialog; + private InteractionDialog topFallbackDialog; @Override public boolean runTest() { @@ -23,8 +24,8 @@ public boolean runTest() { target.getAllStyles().setPadding(2, 2, 2, 2); center.add(target); form.add(BorderLayout.CENTER, center); - form.add(BorderLayout.NORTH, new Label("bias=true : popup should be ABOVE top target")); - form.add(BorderLayout.SOUTH, new Label("bias=false : popup should be BELOW bottom target")); + form.add(BorderLayout.NORTH, new Label("3 dialogs: above target, below target, and top-fallback")); + form.add(BorderLayout.SOUTH, new Label("CENTER TARGET helps verify relative arrow direction")); form.show(); return true; } @@ -33,14 +34,17 @@ public boolean runTest() { protected void registerReadyCallback(Form parent, Runnable run) { topPreferredDialog = createDialog("bias=true -> above target"); bottomPreferredDialog = createDialog("bias=false -> below target"); + topFallbackDialog = createDialog("bias=true near top -> fallback below"); int width = parent.getWidth(); int height = parent.getHeight(); // Keep the targets far apart to avoid overlap in screenshot. Rectangle upperTarget = new Rectangle(width / 2 - 45, height / 3, 90, 24); Rectangle lowerTarget = new Rectangle(width / 2 - 45, (height * 2 / 3) - 24, 90, 24); + Rectangle nearTopTarget = new Rectangle(width / 2 - 45, 6, 90, 24); topPreferredDialog.showPopupDialog(upperTarget, true); bottomPreferredDialog.showPopupDialog(lowerTarget, false); + topFallbackDialog.showPopupDialog(nearTopTarget, true); UITimer.timer(600, false, parent, run); } @@ -52,6 +56,9 @@ public void cleanup() { if (bottomPreferredDialog != null && bottomPreferredDialog.isShowing()) { bottomPreferredDialog.dispose(); } + if (topFallbackDialog != null && topFallbackDialog.isShowing()) { + topFallbackDialog.dispose(); + } } private InteractionDialog createDialog(String text) { From d230b149d81c509efc9b21d897c3209b6337f374 Mon Sep 17 00:00:00 2001 From: liannacasper <67953602+liannacasper@users.noreply.github.com> Date: Wed, 1 Apr 2026 11:35:44 +0300 Subject: [PATCH 5/7] Use compact custom UIIDs for popup bias screenshot dialogs --- ...eractionDialogPopupBiasScreenshotTest.java | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/InteractionDialogPopupBiasScreenshotTest.java b/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/InteractionDialogPopupBiasScreenshotTest.java index 86352746c4..fa43139dfc 100644 --- a/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/InteractionDialogPopupBiasScreenshotTest.java +++ b/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/InteractionDialogPopupBiasScreenshotTest.java @@ -5,6 +5,7 @@ import com.codename1.ui.Container; import com.codename1.ui.Form; import com.codename1.ui.Label; +import com.codename1.ui.plaf.Style; import com.codename1.ui.geom.Rectangle; import com.codename1.ui.layouts.BorderLayout; import com.codename1.ui.layouts.BoxLayout; @@ -18,30 +19,28 @@ public class InteractionDialogPopupBiasScreenshotTest extends BaseTest { @Override public boolean runTest() { - Form form = createForm("InteractionDialog Popup Bias", new BorderLayout(), "InteractionDialogPopupBias"); + Form form = createForm("InteractionDialog Popup", new BorderLayout(), "InteractionDialogPopupBias"); Container center = new Container(new FlowLayout(Component.CENTER, Component.CENTER)); Label target = new Label("CENTER TARGET"); target.getAllStyles().setPadding(2, 2, 2, 2); center.add(target); form.add(BorderLayout.CENTER, center); - form.add(BorderLayout.NORTH, new Label("3 dialogs: above target, below target, and top-fallback")); - form.add(BorderLayout.SOUTH, new Label("CENTER TARGET helps verify relative arrow direction")); form.show(); return true; } @Override protected void registerReadyCallback(Form parent, Runnable run) { - topPreferredDialog = createDialog("bias=true -> above target"); - bottomPreferredDialog = createDialog("bias=false -> below target"); - topFallbackDialog = createDialog("bias=true near top -> fallback below"); + topPreferredDialog = createDialog("T: bias=true"); + bottomPreferredDialog = createDialog("B: bias=false"); + topFallbackDialog = createDialog("F: top fallback"); int width = parent.getWidth(); int height = parent.getHeight(); // Keep the targets far apart to avoid overlap in screenshot. - Rectangle upperTarget = new Rectangle(width / 2 - 45, height / 3, 90, 24); - Rectangle lowerTarget = new Rectangle(width / 2 - 45, (height * 2 / 3) - 24, 90, 24); - Rectangle nearTopTarget = new Rectangle(width / 2 - 45, 6, 90, 24); + Rectangle upperTarget = new Rectangle(width / 2 - 24, Math.max(40, (height / 2) - 130), 48, 20); + Rectangle lowerTarget = new Rectangle(width / 2 - 24, Math.min(height - 60, (height / 2) + 90), 48, 20); + Rectangle nearTopTarget = new Rectangle(width / 2 - 24, 2, 48, 20); topPreferredDialog.showPopupDialog(upperTarget, true); bottomPreferredDialog.showPopupDialog(lowerTarget, false); topFallbackDialog.showPopupDialog(nearTopTarget, true); @@ -63,8 +62,12 @@ public void cleanup() { private InteractionDialog createDialog(String text) { InteractionDialog dialog = new InteractionDialog(); + dialog.setUIID("PopupDialogCN1SSBias"); + dialog.setDialogUIID("PopupDialogCN1SSBiasContent"); dialog.setLayout(BoxLayout.y()); - dialog.add(new Label(text)); + Label label = new Label(text); + label.getAllStyles().setFont(label.getUnselectedStyle().getFont().derive(label.getUnselectedStyle().getFont().getHeight() * 0.75f, Style.FONT_STYLE_PLAIN)); + dialog.add(label); dialog.setDisposeWhenPointerOutOfBounds(false); return dialog; } From ad1ae381000b8b0fa6234e6b5b6579ab723af0cc Mon Sep 17 00:00:00 2001 From: liannacasper <67953602+liannacasper@users.noreply.github.com> Date: Wed, 1 Apr 2026 13:37:39 +0300 Subject: [PATCH 6/7] Fix font style constant in popup bias screenshot test --- .../tests/InteractionDialogPopupBiasScreenshotTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/InteractionDialogPopupBiasScreenshotTest.java b/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/InteractionDialogPopupBiasScreenshotTest.java index fa43139dfc..2f6b16be85 100644 --- a/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/InteractionDialogPopupBiasScreenshotTest.java +++ b/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/InteractionDialogPopupBiasScreenshotTest.java @@ -3,9 +3,9 @@ import com.codename1.components.InteractionDialog; import com.codename1.ui.Component; import com.codename1.ui.Container; +import com.codename1.ui.Font; import com.codename1.ui.Form; import com.codename1.ui.Label; -import com.codename1.ui.plaf.Style; import com.codename1.ui.geom.Rectangle; import com.codename1.ui.layouts.BorderLayout; import com.codename1.ui.layouts.BoxLayout; @@ -66,7 +66,7 @@ private InteractionDialog createDialog(String text) { dialog.setDialogUIID("PopupDialogCN1SSBiasContent"); dialog.setLayout(BoxLayout.y()); Label label = new Label(text); - label.getAllStyles().setFont(label.getUnselectedStyle().getFont().derive(label.getUnselectedStyle().getFont().getHeight() * 0.75f, Style.FONT_STYLE_PLAIN)); + label.getAllStyles().setFont(label.getUnselectedStyle().getFont().derive(label.getUnselectedStyle().getFont().getHeight() * 0.75f, Font.STYLE_PLAIN)); dialog.add(label); dialog.setDisposeWhenPointerOutOfBounds(false); return dialog; From 459e7e3842afce9857c4e4754b9b196c41a9e129 Mon Sep 17 00:00:00 2001 From: liannacasper <67953602+liannacasper@users.noreply.github.com> Date: Wed, 1 Apr 2026 14:08:56 +0300 Subject: [PATCH 7/7] Use default popup styles in bias screenshot test for visibility --- ...eractionDialogPopupBiasScreenshotTest.java | 21 +++++++------------ 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/InteractionDialogPopupBiasScreenshotTest.java b/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/InteractionDialogPopupBiasScreenshotTest.java index 2f6b16be85..639844ce39 100644 --- a/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/InteractionDialogPopupBiasScreenshotTest.java +++ b/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/InteractionDialogPopupBiasScreenshotTest.java @@ -3,7 +3,6 @@ import com.codename1.components.InteractionDialog; import com.codename1.ui.Component; import com.codename1.ui.Container; -import com.codename1.ui.Font; import com.codename1.ui.Form; import com.codename1.ui.Label; import com.codename1.ui.geom.Rectangle; @@ -21,7 +20,7 @@ public class InteractionDialogPopupBiasScreenshotTest extends BaseTest { public boolean runTest() { Form form = createForm("InteractionDialog Popup", new BorderLayout(), "InteractionDialogPopupBias"); Container center = new Container(new FlowLayout(Component.CENTER, Component.CENTER)); - Label target = new Label("CENTER TARGET"); + Label target = new Label("CENTER TARGET (T:true above / B:false below)"); target.getAllStyles().setPadding(2, 2, 2, 2); center.add(target); form.add(BorderLayout.CENTER, center); @@ -31,16 +30,16 @@ public boolean runTest() { @Override protected void registerReadyCallback(Form parent, Runnable run) { - topPreferredDialog = createDialog("T: bias=true"); - bottomPreferredDialog = createDialog("B: bias=false"); - topFallbackDialog = createDialog("F: top fallback"); + topPreferredDialog = createDialog("T: bias=true (prefer top)"); + bottomPreferredDialog = createDialog("B: bias=false (prefer bottom)"); + topFallbackDialog = createDialog("F: bias=true fallback (shown below)"); int width = parent.getWidth(); int height = parent.getHeight(); // Keep the targets far apart to avoid overlap in screenshot. - Rectangle upperTarget = new Rectangle(width / 2 - 24, Math.max(40, (height / 2) - 130), 48, 20); - Rectangle lowerTarget = new Rectangle(width / 2 - 24, Math.min(height - 60, (height / 2) + 90), 48, 20); - Rectangle nearTopTarget = new Rectangle(width / 2 - 24, 2, 48, 20); + Rectangle upperTarget = new Rectangle(width / 2 - 30, Math.max(56, (height / 2) - 130), 60, 18); + Rectangle lowerTarget = new Rectangle(width / 2 - 30, Math.min(height - 76, (height / 2) + 90), 60, 18); + Rectangle nearTopTarget = new Rectangle(width / 2 - 30, 2, 60, 18); topPreferredDialog.showPopupDialog(upperTarget, true); bottomPreferredDialog.showPopupDialog(lowerTarget, false); topFallbackDialog.showPopupDialog(nearTopTarget, true); @@ -62,12 +61,8 @@ public void cleanup() { private InteractionDialog createDialog(String text) { InteractionDialog dialog = new InteractionDialog(); - dialog.setUIID("PopupDialogCN1SSBias"); - dialog.setDialogUIID("PopupDialogCN1SSBiasContent"); dialog.setLayout(BoxLayout.y()); - Label label = new Label(text); - label.getAllStyles().setFont(label.getUnselectedStyle().getFont().derive(label.getUnselectedStyle().getFont().getHeight() * 0.75f, Font.STYLE_PLAIN)); - dialog.add(label); + dialog.add(new Label(text)); dialog.setDisposeWhenPointerOutOfBounds(false); return dialog; }