diff --git a/CodenameOne/src/com/codename1/ui/Sheet.java b/CodenameOne/src/com/codename1/ui/Sheet.java index 2abd763db0..88de26b669 100644 --- a/CodenameOne/src/com/codename1/ui/Sheet.java +++ b/CodenameOne/src/com/codename1/ui/Sheet.java @@ -122,12 +122,14 @@ public class Sheet extends Container { private static final int DEFAULT_TRANSITION_DURATION = 300; private final Sheet parentSheet; private final Label title = new Label(); + private Component titleComponent = title; private final EventDispatcher closeListeners = new EventDispatcher(); private final EventDispatcher backListeners = new EventDispatcher(); private final Button backButton = new Button(FontImage.MATERIAL_CLOSE); private final Container commandsContainer = new Container(BoxLayout.x()); + private final Container titleComponentContainer = FlowLayout.encloseCenterMiddle(title); private final Container titleBar = BorderLayout.center(LayeredLayout.encloseIn( - BorderLayout.center(FlowLayout.encloseCenterMiddle(title)), + BorderLayout.center(titleComponentContainer), BorderLayout.centerEastWest(null, commandsContainer, backButton) )); private final Container contentPane = new Container(BoxLayout.y()); @@ -399,6 +401,77 @@ public Container getCommandsContainer() { return commandsContainer; } + /// Gets the title text displayed in the default title label. + /// + /// #### Returns + /// + /// The sheet title text. + /// + /// #### Since + /// + /// 8.0 + public String getTitle() { + return title.getText(); + } + + /// Sets the title text displayed in the default title label. + /// + /// If a custom title component is currently installed via {@link #setTitleComponent(Component)}, + /// this method still updates the default title label so that it will be shown if the title + /// component is reset back to null. + /// + /// #### Parameters + /// + /// - `title`: The title text. + /// + /// #### Since + /// + /// 8.0 + public void setTitle(String title) { + this.title.setText(title); + } + + /// Gets the component currently used in the center of the title bar. + /// + /// #### Returns + /// + /// The current title component. + /// + /// #### Since + /// + /// 8.0 + public Component getTitleComponent() { + return titleComponent; + } + + /// Sets the title component rendered in the center of the title bar. + /// + /// This allows for custom title layouts such as including an image above the title text. + /// If `null` is passed, the default title label is restored. + /// + /// #### Parameters + /// + /// - `cmp`: The component to use for the title area, or `null` to restore the default title label. + /// + /// #### Since + /// + /// 8.0 + public void setTitleComponent(Component cmp) { + if (cmp == null) { + cmp = title; + } + if (cmp == titleComponent) { //NOPMD CompareObjectsWithEquals + return; + } + if (cmp.getParent() != null) { + cmp.remove(); + } + titleComponentContainer.removeAll(); + titleComponentContainer.add(cmp); + titleComponent = cmp; + titleComponentContainer.revalidateLater(); + } + private void initUI() { setLayout(new BorderLayout()); contentPane.setSafeArea(true); @@ -449,7 +522,7 @@ public void show(final int duration) { // Set the padding in the content pane to match the corner radius Style s = getStyle(); - Style titleParentStyle = title.getParent().getStyle(); + Style titleParentStyle = titleComponentContainer.getStyle(); titleParentStyle.setMarginLeft(titleMargin); titleParentStyle.setMarginRight(titleMargin); Border border = s.getBorder(); diff --git a/maven/core-unittests/src/test/java/com/codename1/ui/SheetTest.java b/maven/core-unittests/src/test/java/com/codename1/ui/SheetTest.java index 4e727c12e5..67036f7187 100644 --- a/maven/core-unittests/src/test/java/com/codename1/ui/SheetTest.java +++ b/maven/core-unittests/src/test/java/com/codename1/ui/SheetTest.java @@ -2,8 +2,8 @@ import com.codename1.junit.FormTest; import com.codename1.junit.UITestBase; -import com.codename1.ui.Label; import com.codename1.ui.layouts.BorderLayout; +import com.codename1.ui.layouts.BoxLayout; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -85,4 +85,33 @@ void allowCloseFlagCanBeToggled() { form.getAnimationManager().flush(); assertNull(Sheet.getCurrentSheet(), "No sheet should remain after backing out"); } + + @FormTest + void titleComponentCanBeCustomized() { + implementation.setBuiltinSoundsEnabled(false); + Form form = Display.getInstance().getCurrent(); + form.setLayout(new BorderLayout()); + + Sheet sheet = new Sheet(null, "Default Title"); + Container customTitle = BoxLayout.encloseY( + new Label("Icon"), + new Label("Custom Title") + ); + sheet.setTitleComponent(customTitle); + + assertSame(customTitle, sheet.getTitleComponent(), "Custom title component should be installed"); + assertEquals("Default Title", sheet.getTitle(), "getTitle() should still return default title label text"); + + sheet.show(0); + form.getAnimationManager().flush(); + flushSerialCalls(); + + assertSame(sheet, Sheet.findContainingSheet(customTitle), "Custom title component should be in the sheet hierarchy"); + + sheet.setTitle("Updated"); + assertEquals("Updated", sheet.getTitle(), "setTitle() should update default title label text"); + + sheet.setTitleComponent(null); + assertNotNull(sheet.getTitleComponent(), "Resetting title component should restore default title label"); + } } diff --git a/scripts/android/screenshots/Sheet.png b/scripts/android/screenshots/Sheet.png index 86b9e67602..ec9a98e06e 100644 Binary files a/scripts/android/screenshots/Sheet.png and b/scripts/android/screenshots/Sheet.png differ diff --git a/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/SheetScreenshotTest.java b/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/SheetScreenshotTest.java index f8f1506488..3d7e794c82 100644 --- a/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/SheetScreenshotTest.java +++ b/scripts/hellocodenameone/common/src/main/java/com/codenameone/examples/hellocodenameone/tests/SheetScreenshotTest.java @@ -3,6 +3,7 @@ import com.codename1.ui.Button; import com.codename1.ui.Container; import com.codename1.ui.Form; +import com.codename1.ui.FontImage; import com.codename1.ui.Label; import com.codename1.ui.Sheet; import com.codename1.ui.layouts.BorderLayout; @@ -35,6 +36,12 @@ protected void registerReadyCallback(Form parent, Runnable run) { private Sheet createSheet(Sheet parent, String title) { Sheet newSheet = new Sheet(parent, title); + Label titleIcon = new Label(); + FontImage.setMaterialIcon(titleIcon, FontImage.MATERIAL_IMAGE, 3f); + titleIcon.setUIID("SheetTitleIcon"); + Label titleLabel = new Label(title); + titleLabel.setUIID("SheetTitleText"); + newSheet.setTitleComponent(BoxLayout.encloseYCenter(titleIcon, titleLabel)); Container content = newSheet.getContentPane(); content.setLayout(BoxLayout.y()); content.add(new Label("Sheet content")); diff --git a/scripts/ios/screenshots/Sheet.png b/scripts/ios/screenshots/Sheet.png index c79875356f..fc0a15660c 100644 Binary files a/scripts/ios/screenshots/Sheet.png and b/scripts/ios/screenshots/Sheet.png differ