From 4ab6f9e5df48cd6609cdf3ec7f4e937848c7316f Mon Sep 17 00:00:00 2001 From: liannacasper <67953602+liannacasper@users.noreply.github.com> Date: Sat, 4 Apr 2026 11:28:56 +0300 Subject: [PATCH 1/5] Improve playground menu theming and mobile layout --- .../common/src/main/css/theme.css | 2 ++ .../codenameone/playground/CN1Playground.java | 26 +++++++++++++++---- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/scripts/cn1playground/common/src/main/css/theme.css b/scripts/cn1playground/common/src/main/css/theme.css index 895a5aef53..c94de42b4a 100644 --- a/scripts/cn1playground/common/src/main/css/theme.css +++ b/scripts/cn1playground/common/src/main/css/theme.css @@ -2,6 +2,8 @@ #Constants { includeNativeBool: true; defaultSourceDPIInt: "0"; + sideMenuSizeLandscapeInt: "75"; + sideMenuSizeTabLandscapeInt: "75"; } /** Style for Button class */ diff --git a/scripts/cn1playground/common/src/main/java/com/codenameone/playground/CN1Playground.java b/scripts/cn1playground/common/src/main/java/com/codenameone/playground/CN1Playground.java index d7f82f7f45..7131695a9c 100644 --- a/scripts/cn1playground/common/src/main/java/com/codenameone/playground/CN1Playground.java +++ b/scripts/cn1playground/common/src/main/java/com/codenameone/playground/CN1Playground.java @@ -19,7 +19,6 @@ import com.codename1.ui.Toolbar; import com.codename1.ui.layouts.BorderLayout; import com.codename1.ui.layouts.BoxLayout; -import com.codename1.ui.layouts.GridLayout; import com.codename1.ui.plaf.UIManager; import com.codename1.ui.util.Resources; import com.codename1.ui.util.UITimer; @@ -155,12 +154,19 @@ private Container createPreviewRoot() { } private Component createMainContent(Tabs tabs, Container previewPanel) { - if (CN.getDisplayWidth() >= 900) { + if (isDesktopLayout()) { return new SplitPane(SplitPane.HORIZONTAL_SPLIT, tabs, previewPanel, "25%", "50%", "75%"); } - Container stacked = new Container(new GridLayout(2, 1)); - stacked.addAll(tabs, previewPanel); - return stacked; + Tabs mobileTabs = new Tabs(); + mobileTabs.setUIID(websiteDarkMode ? "PlaygroundEditorTabsDark" : "PlaygroundEditorTabs"); + mobileTabs.setTabUIID(websiteDarkMode ? "TabDark" : "Tab"); + mobileTabs.addTab("Editor", tabs); + mobileTabs.addTab("Preview", previewPanel); + return mobileTabs; + } + + private boolean isDesktopLayout() { + return CN.getDisplayWidth() >= 900 && !Display.getInstance().isTouchScreenDevice(); } private void runScript(Form form) { @@ -242,6 +248,7 @@ private void markEmbeddedPreviewRoles(Component component) { } private void installSideMenu(Toolbar toolbar) { + Toolbar.setEnableSideMenuSwipe(false); PlaygroundMenuSection shareSection = new PlaygroundMenuSection("Share"); toolbar.addComponentToSideMenu(shareSection); toolbar.addComponentToSideMenu(createSideMenuButton(SHARE_BUTTON_LABEL, () -> { @@ -710,6 +717,15 @@ private boolean supportsDarkVariant(String uiid) { case "PlaygroundTitle": case "PlaygroundPanel": case "PlaygroundPreview": + case "SideNavigationPanel": + case "StatusBarSideMenu": + case "PlaygroundSideCommand": + case "PlaygroundSideCommandLine1": + case "PlaygroundSideCommandLine2": + case "PlaygroundMenuSection": + case "PlaygroundMenuSectionTitle": + case "PlaygroundMenuEmpty": + case "PlaygroundMenuContainer": case "PlaygroundEmbeddedForm": case "PlaygroundEmbeddedTitleArea": case "PlaygroundInspectorRoot": From 7aa838e12c220276232b41b5df86f2fbb32032ee Mon Sep 17 00:00:00 2001 From: liannacasper <67953602+liannacasper@users.noreply.github.com> Date: Sat, 4 Apr 2026 12:04:17 +0300 Subject: [PATCH 2/5] Refine playground portrait tabs and side menu theming --- .../codenameone/playground/CN1Playground.java | 39 +++++++++++-------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/scripts/cn1playground/common/src/main/java/com/codenameone/playground/CN1Playground.java b/scripts/cn1playground/common/src/main/java/com/codenameone/playground/CN1Playground.java index 7131695a9c..38840eff49 100644 --- a/scripts/cn1playground/common/src/main/java/com/codenameone/playground/CN1Playground.java +++ b/scripts/cn1playground/common/src/main/java/com/codenameone/playground/CN1Playground.java @@ -46,6 +46,7 @@ public class CN1Playground extends Lifecycle { private PlaygroundInspector inspector; private Container previewRoot; private Container historyMenu; + private final List sideMenuComponents = new ArrayList<>(); private Resources theme; private boolean websiteDarkMode = DEFAULT_DARK_MODE; private String currentScript; @@ -154,19 +155,12 @@ private Container createPreviewRoot() { } private Component createMainContent(Tabs tabs, Container previewPanel) { - if (isDesktopLayout()) { + tabs.setSwipeActivated(false); + if (!Display.getInstance().isPortrait()) { return new SplitPane(SplitPane.HORIZONTAL_SPLIT, tabs, previewPanel, "25%", "50%", "75%"); } - Tabs mobileTabs = new Tabs(); - mobileTabs.setUIID(websiteDarkMode ? "PlaygroundEditorTabsDark" : "PlaygroundEditorTabs"); - mobileTabs.setTabUIID(websiteDarkMode ? "TabDark" : "Tab"); - mobileTabs.addTab("Editor", tabs); - mobileTabs.addTab("Preview", previewPanel); - return mobileTabs; - } - - private boolean isDesktopLayout() { - return CN.getDisplayWidth() >= 900 && !Display.getInstance().isTouchScreenDevice(); + tabs.addTab("Preview", previewPanel); + return tabs; } private void runScript(Form form) { @@ -250,28 +244,34 @@ private void markEmbeddedPreviewRoles(Component component) { private void installSideMenu(Toolbar toolbar) { Toolbar.setEnableSideMenuSwipe(false); PlaygroundMenuSection shareSection = new PlaygroundMenuSection("Share"); - toolbar.addComponentToSideMenu(shareSection); - toolbar.addComponentToSideMenu(createSideMenuButton(SHARE_BUTTON_LABEL, () -> { + addSideMenuComponent(toolbar, shareSection); + addSideMenuComponent(toolbar, createSideMenuButton(SHARE_BUTTON_LABEL, () -> { copyCurrentSourceUrl(); toolbar.closeSideMenu(); })); PlaygroundMenuSection samplesSection = new PlaygroundMenuSection("Samples"); - toolbar.addComponentToSideMenu(samplesSection); + addSideMenuComponent(toolbar, samplesSection); for (PlaygroundExamples.Sample sample : PlaygroundExamples.SAMPLES) { - toolbar.addComponentToSideMenu(createSideMenuButton(sample.title, () -> { + addSideMenuComponent(toolbar, createSideMenuButton(sample.title, () -> { setScript(sample.script, true); toolbar.closeSideMenu(); })); } PlaygroundMenuSection historySection = new PlaygroundMenuSection("History"); - toolbar.addComponentToSideMenu(historySection); - toolbar.addComponentToSideMenu(historyMenu); + addSideMenuComponent(toolbar, historySection); + addSideMenuComponent(toolbar, historyMenu); refreshHistoryMenu(toolbar, PlaygroundStateStore.loadHistory()); } + private void addSideMenuComponent(Toolbar toolbar, Component component) { + applyWebsiteTheme(component, websiteDarkMode); + sideMenuComponents.add(component); + toolbar.addComponentToSideMenu(component); + } + private void refreshHistoryMenu(Toolbar toolbar, List history) { historyMenu.removeAll(); @@ -301,6 +301,7 @@ private MultiButton createHistoryButton(PlaygroundStateStore.HistoryEntry entry, setScript(entry.script, true); toolbar.closeSideMenu(); }); + applyWebsiteTheme(button, websiteDarkMode); return button; } @@ -308,6 +309,7 @@ private Button createSideMenuButton(String text, Runnable action) { Button button = new Button(text); button.setUIID("PlaygroundSideCommand"); button.addActionListener(e -> action.run()); + applyWebsiteTheme(button, websiteDarkMode); return button; } @@ -656,6 +658,9 @@ private void applyDarkMode(Form form, boolean dark) { if (inspector != null) { inspector.applyTheme(dark); } + for (Component cmp : sideMenuComponents) { + applyWebsiteTheme(cmp, dark); + } } } From 6b8350680116b454c8853d4072365b613380b9fe Mon Sep 17 00:00:00 2001 From: liannacasper <67953602+liannacasper@users.noreply.github.com> Date: Sat, 4 Apr 2026 14:46:24 +0300 Subject: [PATCH 3/5] Fix folded side menu dark palette and tab uiid refresh --- .../codenameone/playground/CN1Playground.java | 32 +++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/scripts/cn1playground/common/src/main/java/com/codenameone/playground/CN1Playground.java b/scripts/cn1playground/common/src/main/java/com/codenameone/playground/CN1Playground.java index 38840eff49..a7319707ff 100644 --- a/scripts/cn1playground/common/src/main/java/com/codenameone/playground/CN1Playground.java +++ b/scripts/cn1playground/common/src/main/java/com/codenameone/playground/CN1Playground.java @@ -645,6 +645,7 @@ private void applyDarkMode(Form form, boolean dark) { if (!websiteThemeInitialized || dark != websiteDarkMode) { websiteDarkMode = dark; websiteThemeInitialized = true; + applySideMenuPalette(dark); applyWebsiteTheme(form, dark); applyTabsTheme(dark); form.refreshTheme(); @@ -664,6 +665,27 @@ private void applyDarkMode(Form form, boolean dark) { } } + private void applySideMenuPalette(boolean dark) { + Hashtable sideMenuPalette = new Hashtable(); + int bgColor = dark ? 0x0f172a : 0xffffff; + int borderColor = dark ? 0x1f2937 : 0xcccccc; + + sideMenuPalette.put("SideNavigationPanel.bgColor", bgColor); + sideMenuPalette.put("SideNavigationPanel.bgTransparency", 255); + sideMenuPalette.put("SideNavigationPanelDark.bgColor", bgColor); + sideMenuPalette.put("SideNavigationPanelDark.bgTransparency", 255); + + sideMenuPalette.put("StatusBarSideMenu.bgColor", bgColor); + sideMenuPalette.put("StatusBarSideMenu.bgTransparency", 255); + sideMenuPalette.put("StatusBarSideMenuDark.bgColor", bgColor); + sideMenuPalette.put("StatusBarSideMenuDark.bgTransparency", 255); + + sideMenuPalette.put("SideCommand.bgColor", bgColor); + sideMenuPalette.put("SideCommand.bgTransparency", 255); + sideMenuPalette.put("SideCommand.border", com.codename1.ui.plaf.Border.createLineBorder(2, borderColor)); + UIManager.getInstance().addThemeProps(sideMenuPalette); + } + private void applyWebsiteTheme(Component component, boolean dark) { if (component == null) { return; @@ -751,8 +773,14 @@ private boolean supportsDarkVariant(String uiid) { private void applyTabsTheme(boolean dark) { if (editorTabs != null) { - editorTabs.setUIID(dark ? "PlaygroundEditorTabsDark" : "PlaygroundEditorTabs"); - editorTabs.setTabUIID(dark ? "TabDark" : "Tab"); + String tabsUiid = dark ? "PlaygroundEditorTabsDark" : "PlaygroundEditorTabs"; + String tabUiid = dark ? "TabDark" : "Tab"; + editorTabs.setUIID(tabsUiid); + editorTabs.setTabUIID(tabUiid); + Container tabsContainer = editorTabs.getTabsContainer(); + for (int i = 0; i < tabsContainer.getComponentCount(); i++) { + tabsContainer.getComponentAt(i).setUIID(tabUiid); + } editorTabs.refreshTheme(); editorTabs.revalidate(); } From a7ad0015f3f7c17fd66bebf1bdd44870c9c9cdbd Mon Sep 17 00:00:00 2001 From: liannacasper <67953602+liannacasper@users.noreply.github.com> Date: Sat, 4 Apr 2026 16:17:17 +0300 Subject: [PATCH 4/5] Reapply menu/tab palettes after theme resets --- .../src/main/java/com/codenameone/playground/CN1Playground.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/cn1playground/common/src/main/java/com/codenameone/playground/CN1Playground.java b/scripts/cn1playground/common/src/main/java/com/codenameone/playground/CN1Playground.java index a7319707ff..d8ad9f3b05 100644 --- a/scripts/cn1playground/common/src/main/java/com/codenameone/playground/CN1Playground.java +++ b/scripts/cn1playground/common/src/main/java/com/codenameone/playground/CN1Playground.java @@ -460,6 +460,7 @@ private void applyCurrentCss() { return; } restoreThemeDefaults(); + applySideMenuPalette(websiteDarkMode); List diagnostics = new ArrayList(); List messages = new ArrayList(); try { @@ -476,6 +477,7 @@ private void applyCurrentCss() { cssEditor.setMarkers(diagnostics); cssEditor.setInlineMessages(messages); cssEditor.setUiidCompletions(PlaygroundCssSupport.collectVisibleUiids(previewRoot)); + applyTabsTheme(websiteDarkMode); appForm.refreshTheme(); } From aa864d4bc1a99ed40cb7a24e96887b301cca768c Mon Sep 17 00:00:00 2001 From: liannacasper <67953602+liannacasper@users.noreply.github.com> Date: Sat, 4 Apr 2026 18:55:28 +0300 Subject: [PATCH 5/5] Force side menu container theming and selected tab contrast --- .../common/src/main/css/theme.css | 12 +++++++ .../codenameone/playground/CN1Playground.java | 34 +++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/scripts/cn1playground/common/src/main/css/theme.css b/scripts/cn1playground/common/src/main/css/theme.css index c94de42b4a..0f52d5107e 100644 --- a/scripts/cn1playground/common/src/main/css/theme.css +++ b/scripts/cn1playground/common/src/main/css/theme.css @@ -399,6 +399,18 @@ TabDark { text-align: center; } +TabSelected { + background: #ffffff; + color: #111827; + border: 1px solid #94a3b8; +} + +TabSelectedDark { + background: #1f2937; + color: #f8fafc; + border: 1px solid #64748b; +} + TabsContainer { background: #e5e7eb; } diff --git a/scripts/cn1playground/common/src/main/java/com/codenameone/playground/CN1Playground.java b/scripts/cn1playground/common/src/main/java/com/codenameone/playground/CN1Playground.java index d8ad9f3b05..34469e9013 100644 --- a/scripts/cn1playground/common/src/main/java/com/codenameone/playground/CN1Playground.java +++ b/scripts/cn1playground/common/src/main/java/com/codenameone/playground/CN1Playground.java @@ -572,6 +572,7 @@ private void initWebsiteThemeSync(Form form) { websiteThemeNative = NativeLookup.create(WebsiteThemeNative.class); refreshWebsiteTheme(form); UITimer.timer(900, true, form, () -> refreshWebsiteTheme(form)); + UITimer.timer(250, true, form, this::syncOpenSideMenuTheme); } private void notifyWebsiteUiReady() { @@ -676,6 +677,8 @@ private void applySideMenuPalette(boolean dark) { sideMenuPalette.put("SideNavigationPanel.bgTransparency", 255); sideMenuPalette.put("SideNavigationPanelDark.bgColor", bgColor); sideMenuPalette.put("SideNavigationPanelDark.bgTransparency", 255); + sideMenuPalette.put("RightSideNavigationPanel.bgColor", bgColor); + sideMenuPalette.put("RightSideNavigationPanel.bgTransparency", 255); sideMenuPalette.put("StatusBarSideMenu.bgColor", bgColor); sideMenuPalette.put("StatusBarSideMenu.bgTransparency", 255); @@ -688,6 +691,36 @@ private void applySideMenuPalette(boolean dark) { UIManager.getInstance().addThemeProps(sideMenuPalette); } + private void syncOpenSideMenuTheme() { + Form current = Display.getInstance().getCurrent(); + if (current == null) { + return; + } + applySideMenuContainerTheme(current); + } + + private void applySideMenuContainerTheme(Component component) { + if (component == null) { + return; + } + String uiid = component.getUIID(); + if ("SideNavigationPanel".equals(uiid) + || "SideNavigationPanelDark".equals(uiid) + || "RightSideNavigationPanel".equals(uiid) + || "StatusBarSideMenu".equals(uiid) + || "StatusBarSideMenuDark".equals(uiid)) { + applyWebsiteTheme(component, websiteDarkMode); + component.getAllStyles().setBgTransparency(255); + component.getAllStyles().setBgColor(websiteDarkMode ? 0x0f172a : 0xffffff); + } + if (component instanceof Container) { + Container cnt = (Container) component; + for (int i = 0; i < cnt.getComponentCount(); i++) { + applySideMenuContainerTheme(cnt.getComponentAt(i)); + } + } + } + private void applyWebsiteTheme(Component component, boolean dark) { if (component == null) { return; @@ -747,6 +780,7 @@ private boolean supportsDarkVariant(String uiid) { case "PlaygroundPanel": case "PlaygroundPreview": case "SideNavigationPanel": + case "RightSideNavigationPanel": case "StatusBarSideMenu": case "PlaygroundSideCommand": case "PlaygroundSideCommandLine1":