diff --git a/CodenameOne/src/com/codename1/ui/Toolbar.java b/CodenameOne/src/com/codename1/ui/Toolbar.java index dc0b904158..ac531c9e92 100644 --- a/CodenameOne/src/com/codename1/ui/Toolbar.java +++ b/CodenameOne/src/com/codename1/ui/Toolbar.java @@ -33,6 +33,7 @@ import com.codename1.ui.events.ActionEvent; import com.codename1.ui.events.ActionListener; import com.codename1.ui.events.ScrollListener; +import com.codename1.ui.geom.Rectangle; import com.codename1.ui.layouts.BorderLayout; import com.codename1.ui.layouts.BoxLayout; import com.codename1.ui.layouts.FlowLayout; @@ -227,7 +228,6 @@ public Toolbar() { && UIManager.getInstance().getComponentStyle("Title").getAlignment() == CENTER) { setTitleCentered(true); } - //setSafeArea(true); } /** @@ -2238,6 +2238,7 @@ protected List createOverflowCommandList(Vector commands) { protected void initTitleBarStatus() { Form f = getComponentForm(); if (f != null && !f.shouldPaintStatusBar()) { + setSafeArea(true); return; } if (getUIManager().isThemeConstant("paintsTitleBarBool", false)) { @@ -2249,11 +2250,42 @@ protected void initTitleBarStatus() { } else { bar.setUIID("StatusBar"); } + reallocateVerticalPaddingAndMarginsToTop(bar); + bar.setSafeArea(true); addComponent(BorderLayout.NORTH, bar); } + } else { + setSafeArea(true); } } + /** + * Reallocates vertical padding and margins to be all on top, so that bottom padding/margin + * is zero, but the total padding/margin is the same. + * + * This is helpful for the status bar so that, when the padding is adjusted by the safeArea + * we don't end up with extra padding at the bottom of the component, which would increase + * the height of the status bar. + * @param cmp + */ + private void reallocateVerticalPaddingAndMarginsToTop(Component cmp) { + Style allStyles = cmp.getAllStyles(); + Style style = cmp.getStyle(); + int topPadding = style.getPaddingTop(); + int topMargin = style.getMarginTop(); + int bottomPadding = style.getPaddingBottom(); + int bottomMargin = style.getMarginBottom(); + allStyles.setPaddingUnitTop(Style.UNIT_TYPE_PIXELS); + allStyles.setMarginUnitTop(Style.UNIT_TYPE_PIXELS); + allStyles.setPaddingUnitBottom(Style.UNIT_TYPE_PIXELS); + allStyles.setMarginUnitBottom(Style.UNIT_TYPE_PIXELS); + allStyles.setPaddingTop(topPadding + bottomPadding); + allStyles.setMarginTop(topMargin + bottomMargin); + allStyles.setPaddingBottom(0); + allStyles.setMarginBottom(0); + } + + private void checkIfInitialized() { if (!initialized) { throw new IllegalStateException("Need to call " diff --git a/CodenameOne/src/com/codename1/ui/plaf/Style.java b/CodenameOne/src/com/codename1/ui/plaf/Style.java index f01be2127a..8bbe946f09 100644 --- a/CodenameOne/src/com/codename1/ui/plaf/Style.java +++ b/CodenameOne/src/com/codename1/ui/plaf/Style.java @@ -1809,6 +1809,12 @@ private void initPaddingUnits() { * @since 7.0 */ public void setPaddingUnitLeft(byte unit) { + if(proxyTo != null) { + for(Style s : proxyTo) { + s.setPaddingUnitLeft(unit); + } + return; + } initPaddingUnits(); paddingUnit[Component.LEFT] = unit; } @@ -1820,6 +1826,12 @@ public void setPaddingUnitLeft(byte unit) { * @since 7.0 */ public void setPaddingUnitRight(byte unit) { + if(proxyTo != null) { + for(Style s : proxyTo) { + s.setPaddingUnitRight(unit); + } + return; + } initPaddingUnits(); paddingUnit[Component.RIGHT] = unit; } @@ -1831,6 +1843,12 @@ public void setPaddingUnitRight(byte unit) { * @since 7.0 */ public void setPaddingUnitTop(byte unit) { + if(proxyTo != null) { + for(Style s : proxyTo) { + s.setPaddingUnitTop(unit); + } + return; + } initPaddingUnits(); paddingUnit[Component.TOP] = unit; } @@ -1842,6 +1860,12 @@ public void setPaddingUnitTop(byte unit) { * @since 7.0 */ public void setPaddingUnitBottom(byte unit) { + if(proxyTo != null) { + for(Style s : proxyTo) { + s.setPaddingUnitBottom(unit); + } + return; + } initPaddingUnits(); paddingUnit[Component.BOTTOM] = unit; } @@ -3027,6 +3051,12 @@ private void initMarginUnits() { * @since 7.0 */ public void setMarginUnitLeft(byte unit) { + if(proxyTo != null) { + for(Style s : proxyTo) { + s.setMarginUnitLeft(unit); + } + return; + } initMarginUnits(); marginUnit[Component.LEFT] = unit; } @@ -3038,6 +3068,12 @@ public void setMarginUnitLeft(byte unit) { * @since 7.0 */ public void setMarginUnitRight(byte unit) { + if(proxyTo != null) { + for(Style s : proxyTo) { + s.setMarginUnitRight(unit); + } + return; + } initMarginUnits(); marginUnit[Component.RIGHT] = unit; } @@ -3049,6 +3085,12 @@ public void setMarginUnitRight(byte unit) { * @since 7.0 */ public void setMarginUnitTop(byte unit) { + if(proxyTo != null) { + for(Style s : proxyTo) { + s.setMarginUnitTop(unit); + } + return; + } initMarginUnits(); marginUnit[Component.TOP] = unit; } @@ -3060,6 +3102,12 @@ public void setMarginUnitTop(byte unit) { * @since 7.0 */ public void setMarginUnitBottom(byte unit) { + if(proxyTo != null) { + for(Style s : proxyTo) { + s.setMarginUnitBottom(unit); + } + return; + } initMarginUnits(); marginUnit[Component.BOTTOM] = unit; } diff --git a/maven/core-unittests/src/test/java/com/codename1/ui/plaf/StyleProxyTest.java b/maven/core-unittests/src/test/java/com/codename1/ui/plaf/StyleProxyTest.java new file mode 100644 index 0000000000..8aa82cbfb3 --- /dev/null +++ b/maven/core-unittests/src/test/java/com/codename1/ui/plaf/StyleProxyTest.java @@ -0,0 +1,88 @@ +package com.codename1.ui.plaf; + +import com.codename1.ui.Component; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class StyleProxyTest { + @Test + public void testSetMarginUnitLeft() { + Style s = new Style(); + Style proxy = Style.createProxyStyle(s); + proxy.setMarginUnitLeft(Style.UNIT_TYPE_PIXELS); + assertEquals(Style.UNIT_TYPE_PIXELS, s.getMarginUnit()[Component.LEFT]); + proxy.setMarginUnitLeft(Style.UNIT_TYPE_DIPS); + assertEquals(Style.UNIT_TYPE_DIPS, s.getMarginUnit()[Component.LEFT]); + } + + @Test + public void testSetMarginUnitRight() { + Style s = new Style(); + Style proxy = Style.createProxyStyle(s); + proxy.setMarginUnitRight(Style.UNIT_TYPE_PIXELS); + assertEquals(Style.UNIT_TYPE_PIXELS, s.getMarginUnit()[Component.RIGHT]); + proxy.setMarginUnitRight(Style.UNIT_TYPE_DIPS); + assertEquals(Style.UNIT_TYPE_DIPS, s.getMarginUnit()[Component.RIGHT]); + } + + @Test + public void testSetMarginUnitBottom() { + Style s = new Style(); + Style proxy = Style.createProxyStyle(s); + proxy.setMarginUnitBottom(Style.UNIT_TYPE_PIXELS); + assertEquals(Style.UNIT_TYPE_PIXELS, s.getMarginUnit()[Component.BOTTOM]); + proxy.setMarginUnitBottom(Style.UNIT_TYPE_DIPS); + assertEquals(Style.UNIT_TYPE_DIPS, s.getMarginUnit()[Component.BOTTOM]); + } + + @Test + public void testSetMarginUnitTop() { + Style s = new Style(); + Style proxy = Style.createProxyStyle(s); + proxy.setMarginUnitTop(Style.UNIT_TYPE_PIXELS); + assertEquals(Style.UNIT_TYPE_PIXELS, s.getMarginUnit()[Component.TOP]); + proxy.setMarginUnitTop(Style.UNIT_TYPE_DIPS); + assertEquals(Style.UNIT_TYPE_DIPS, s.getMarginUnit()[Component.TOP]); + } + + @Test + public void testSetPaddingUnitTop() { + Style s = new Style(); + Style proxy = Style.createProxyStyle(s); + proxy.setPaddingUnitTop(Style.UNIT_TYPE_PIXELS); + assertEquals(Style.UNIT_TYPE_PIXELS, s.getPaddingUnit()[Component.TOP]); + proxy.setPaddingUnitTop(Style.UNIT_TYPE_DIPS); + assertEquals(Style.UNIT_TYPE_DIPS, s.getPaddingUnit()[Component.TOP]); + } + + @Test + public void testSetPaddingUnitBottom() { + Style s = new Style(); + Style proxy = Style.createProxyStyle(s); + proxy.setPaddingUnitBottom(Style.UNIT_TYPE_PIXELS); + assertEquals(Style.UNIT_TYPE_PIXELS, s.getPaddingUnit()[Component.BOTTOM]); + proxy.setPaddingUnitBottom(Style.UNIT_TYPE_DIPS); + assertEquals(Style.UNIT_TYPE_DIPS, s.getPaddingUnit()[Component.BOTTOM]); + } + + @Test + public void testSetPaddingUnitLeft() { + Style s = new Style(); + Style proxy = Style.createProxyStyle(s); + proxy.setPaddingUnitLeft(Style.UNIT_TYPE_PIXELS); + assertEquals(Style.UNIT_TYPE_PIXELS, s.getPaddingUnit()[Component.LEFT]); + proxy.setPaddingUnitLeft(Style.UNIT_TYPE_DIPS); + assertEquals(Style.UNIT_TYPE_DIPS, s.getPaddingUnit()[Component.LEFT]); + } + + @Test + public void testSetPaddingUnitRight() { + Style s = new Style(); + Style proxy = Style.createProxyStyle(s); + proxy.setPaddingUnitRight(Style.UNIT_TYPE_PIXELS); + assertEquals(Style.UNIT_TYPE_PIXELS, s.getPaddingUnit()[Component.RIGHT]); + proxy.setPaddingUnitRight(Style.UNIT_TYPE_DIPS); + assertEquals(Style.UNIT_TYPE_DIPS, s.getPaddingUnit()[Component.RIGHT]); + } +} diff --git a/maven/core-unittests/src/test/java/com/codename1/ui/plaf/StyleTest.java b/maven/core-unittests/src/test/java/com/codename1/ui/plaf/StyleTest.java new file mode 100644 index 0000000000..2b044651bd --- /dev/null +++ b/maven/core-unittests/src/test/java/com/codename1/ui/plaf/StyleTest.java @@ -0,0 +1,81 @@ +package com.codename1.ui.plaf; + +import com.codename1.ui.Component; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class StyleTest { + @Test + public void testSetMarginUnitLeft() { + Style s = new Style(); + s.setMarginUnitLeft(Style.UNIT_TYPE_PIXELS); + assertEquals(Style.UNIT_TYPE_PIXELS, s.getMarginUnit()[Component.LEFT]); + s.setMarginUnitLeft(Style.UNIT_TYPE_DIPS); + assertEquals(Style.UNIT_TYPE_DIPS, s.getMarginUnit()[Component.LEFT]); + } + + @Test + public void testSetMarginUnitRight() { + Style s = new Style(); + s.setMarginUnitRight(Style.UNIT_TYPE_PIXELS); + assertEquals(Style.UNIT_TYPE_PIXELS, s.getMarginUnit()[Component.RIGHT]); + s.setMarginUnitRight(Style.UNIT_TYPE_DIPS); + assertEquals(Style.UNIT_TYPE_DIPS, s.getMarginUnit()[Component.RIGHT]); + } + + @Test + public void testSetMarginUnitBottom() { + Style s = new Style(); + s.setMarginUnitBottom(Style.UNIT_TYPE_PIXELS); + assertEquals(Style.UNIT_TYPE_PIXELS, s.getMarginUnit()[Component.BOTTOM]); + s.setMarginUnitBottom(Style.UNIT_TYPE_DIPS); + assertEquals(Style.UNIT_TYPE_DIPS, s.getMarginUnit()[Component.BOTTOM]); + } + + @Test + public void testSetMarginUnitTop() { + Style s = new Style(); + s.setMarginUnitTop(Style.UNIT_TYPE_PIXELS); + assertEquals(Style.UNIT_TYPE_PIXELS, s.getMarginUnit()[Component.TOP]); + s.setMarginUnitTop(Style.UNIT_TYPE_DIPS); + assertEquals(Style.UNIT_TYPE_DIPS, s.getMarginUnit()[Component.TOP]); + } + + @Test + public void testSetPaddingUnitTop() { + Style s = new Style(); + s.setPaddingUnitTop(Style.UNIT_TYPE_PIXELS); + assertEquals(Style.UNIT_TYPE_PIXELS, s.getPaddingUnit()[Component.TOP]); + s.setPaddingUnitTop(Style.UNIT_TYPE_DIPS); + assertEquals(Style.UNIT_TYPE_DIPS, s.getPaddingUnit()[Component.TOP]); + } + + @Test + public void testSetPaddingUnitBottom() { + Style s = new Style(); + s.setPaddingUnitBottom(Style.UNIT_TYPE_PIXELS); + assertEquals(Style.UNIT_TYPE_PIXELS, s.getPaddingUnit()[Component.BOTTOM]); + s.setPaddingUnitBottom(Style.UNIT_TYPE_DIPS); + assertEquals(Style.UNIT_TYPE_DIPS, s.getPaddingUnit()[Component.BOTTOM]); + } + + @Test + public void testSetPaddingUnitLeft() { + Style s = new Style(); + s.setPaddingUnitLeft(Style.UNIT_TYPE_PIXELS); + assertEquals(Style.UNIT_TYPE_PIXELS, s.getPaddingUnit()[Component.LEFT]); + s.setPaddingUnitLeft(Style.UNIT_TYPE_DIPS); + assertEquals(Style.UNIT_TYPE_DIPS, s.getPaddingUnit()[Component.LEFT]); + } + + @Test + public void testSetPaddingUnitRight() { + Style s = new Style(); + s.setPaddingUnitRight(Style.UNIT_TYPE_PIXELS); + assertEquals(Style.UNIT_TYPE_PIXELS, s.getPaddingUnit()[Component.RIGHT]); + s.setPaddingUnitRight(Style.UNIT_TYPE_DIPS); + assertEquals(Style.UNIT_TYPE_DIPS, s.getPaddingUnit()[Component.RIGHT]); + } + +} diff --git a/tests/core/src/com/codename1/ui/TestComponent.java b/tests/core/src/com/codename1/ui/TestComponent.java index 7764a9aa96..48cffacf8f 100644 --- a/tests/core/src/com/codename1/ui/TestComponent.java +++ b/tests/core/src/com/codename1/ui/TestComponent.java @@ -119,7 +119,9 @@ private void getComponentAt_int_int_button() { f.show(); TestUtils.waitForFormTitle("My Form"); - Component middleComponent = f.getComponentAt(w/2, h/2); + h = f.getContentPane().getHeight(); + int offsetY = f.getContentPane().getAbsoluteY(); + Component middleComponent = f.getComponentAt(w/2, offsetY + h/2); assertEqual(l, middleComponent, "Found wrong component"); } @@ -134,7 +136,9 @@ private void getComponentAt_int_int_label() { f.show(); TestUtils.waitForFormTitle("My Form", 2000); - Component middleComponent = f.getComponentAt(w/2, h/2); + h = f.getContentPane().getHeight(); + int offsetY = f.getContentPane().getAbsoluteY(); + Component middleComponent = f.getComponentAt(w/2, offsetY + h/2); assertEqual(l, middleComponent, "Found wrong component"); @@ -182,7 +186,9 @@ protected Dimension calcPreferredSize() { f.show(); TestUtils.waitForFormTitle("My Form", 2000); - Component middleComponent = f.getComponentAt(w/2, h/2); + int hInner = f.getContentPane().getHeight(); + int offsetY = f.getContentPane().getAbsoluteY(); + Component middleComponent = f.getComponentAt(w/2, offsetY + hInner/2); assertEqual(top, middleComponent, "Found wrong component"); } @@ -231,7 +237,9 @@ protected Dimension calcPreferredSize() { f.show(); TestUtils.waitForFormTitle("My Form", 2000); - Component middleComponent = f.getComponentAt(w/2, h/2); + int hInner = f.getContentPane().getHeight(); + int offsetY = f.getContentPane().getAbsoluteY(); + Component middleComponent = f.getComponentAt(w/2, offsetY + hInner/2); assertEqual(content, middleComponent, "Found wrong component"); } @@ -264,8 +272,12 @@ public void actionPerformed(ActionEvent e) { f.show(); TestUtils.waitForFormTitle("Scrolling Labels", 2000); - Component res = f.getComponentAt(w/2, h/2); - assertTrue(res == cnt || res.getParent() == cnt, "getComponentAt(x,y) should return scrollable container on top of button when in layered pane."); + h = f.getContentPane().getHeight(); + int offsetY = f.getContentPane().getAbsoluteY(); + Component res = f.getComponentAt(w/2, offsetY + h/2); + assertTrue( + res == cnt || res.getParent() == cnt, + "getComponentAt(x,y) should return scrollable container on top of button when in layered pane, but received " + res + ". Form: " + f); } @@ -279,7 +291,9 @@ private void getComponentAt_int_int_container() { f.show(); TestUtils.waitForFormTitle("My Form", 2000); - Component middleComponent = f.getComponentAt(w/2, h/2); + h = f.getContentPane().getHeight(); + int offsetY = f.getContentPane().getAbsoluteY(); + Component middleComponent = f.getComponentAt(w/2, offsetY + h/2); assertEqual(l, middleComponent, "Found wrong component"); } @@ -307,20 +321,21 @@ public void actionPerformed(ActionEvent e) { mapDemo.show(); TestUtils.waitForFormTitle("Maps", 2000); - Component middleComponent = mapDemo.getComponentAt(w/2, h/2); + h = mapDemo.getContentPane().getHeight(); + int offsetY = mapDemo.getContentPane().getAbsoluteY(); + Component middleComponent = mapDemo.getComponentAt(w/2,offsetY + h/2); assertTrue(mc == middleComponent || mc.contains(middleComponent), "Wrong component found in middle. Expected "+mc+" but found "+middleComponent); tb.openSideMenu(); TestUtils.waitFor(500); // wait for side menu to open Component res = null; - - res = tb.getComponentAt(10, h/2); + res = tb.getComponentAt(10, offsetY + h/2); //System.out.println("tb size = "+tb.getAbsoluteX()+", "+tb.getAbsoluteY()+", "+tb.getWidth()+", "+tb.getHeight()); //System.out.println("mb size = "+tb.getMenuBar().getAbsoluteX()+", "+tb.getMenuBar().getAbsoluteY()+", "+tb.getMenuBar().getWidth()+", "+tb.getMenuBar().getHeight()); //System.out.println("res is "+res); - res = mapDemo.getComponentAt(10, h/2); + res = mapDemo.getComponentAt(10, offsetY + h/2); // Let's find the interaction dialog on the form Component interactionDialog = $("*", mapDemo).filter(c->{