From 23550c65a92f7b5bfb83635c78856dbe5d404102 Mon Sep 17 00:00:00 2001 From: lolodomo Date: Tue, 3 Oct 2023 19:28:54 +0200 Subject: [PATCH] [BasicUI] Prefer icon over text in buttons (switch element) (#2085) Related to openhab/openhab-core#3441 Depends on openhab/openhab-core#3809 Icons will not be used if icons are not enabled (app setting). Signed-off-by: Laurent Garnier --- .../ui/basic/internal/WebAppConfig.java | 7 ++++ .../render/AbstractWidgetRenderer.java | 9 ++--- .../basic/internal/render/SwitchRenderer.java | 38 ++++++++++++++----- .../src/main/resources/snippets/button.html | 4 +- .../org.openhab.ui.basic/web-src/_layout.scss | 17 +++++++++ 5 files changed, 59 insertions(+), 16 deletions(-) diff --git a/bundles/org.openhab.ui.basic/src/main/java/org/openhab/ui/basic/internal/WebAppConfig.java b/bundles/org.openhab.ui.basic/src/main/java/org/openhab/ui/basic/internal/WebAppConfig.java index 8edc6fa05b..93d3fcad9e 100644 --- a/bundles/org.openhab.ui.basic/src/main/java/org/openhab/ui/basic/internal/WebAppConfig.java +++ b/bundles/org.openhab.ui.basic/src/main/java/org/openhab/ui/basic/internal/WebAppConfig.java @@ -36,6 +36,7 @@ public class WebAppConfig { public static final String THEME_NAME_SYSTEM = "system"; private static final String DEFAULT_THEME = THEME_NAME_BRIGHT; + private static final String DEFAULT_ICONS = "true"; private static final String DEFAULT_ICONIFY = "false"; private static final String DEFAULT_INLINE_SVG = "false"; private static final String DEFAULT_WEB_AUDIO = "false"; @@ -48,6 +49,7 @@ public class WebAppConfig { private String theme = DEFAULT_THEME; private int nbColsDesktop = DEFAULT_NB_COLUMNS_DESKTOP; private int nbColsTablet = DEFAULT_NB_COLUMNS_TABLET; + private boolean icons = Boolean.parseBoolean(DEFAULT_ICONS); private boolean iconify = Boolean.parseBoolean(DEFAULT_ICONIFY); private boolean inlineSvg = Boolean.parseBoolean(DEFAULT_INLINE_SVG); private boolean webAudio = Boolean.parseBoolean(DEFAULT_WEB_AUDIO); @@ -116,6 +118,7 @@ public void applyConfig(Map configProps) { nbColsDesktop = DEFAULT_NB_COLUMNS_DESKTOP; nbColsTablet = DEFAULT_NB_COLUMNS_TABLET; } + icons = "true".equalsIgnoreCase((String) configProps.getOrDefault(CONFIG_ENABLE_ICONS, DEFAULT_ICONS)); iconify = "true".equalsIgnoreCase((String) configProps.getOrDefault("enableIconify", DEFAULT_ICONIFY)); inlineSvg = "true".equalsIgnoreCase((String) configProps.getOrDefault("inlineSvg", DEFAULT_INLINE_SVG)); webAudio = "true".equalsIgnoreCase((String) configProps.getOrDefault("webAudio", DEFAULT_WEB_AUDIO)); @@ -147,6 +150,10 @@ public int getNbColsTablet() { return nbColsTablet; } + public boolean isIconsEnabled() { + return icons; + } + public boolean isIconifyEnabled() { return iconify; } diff --git a/bundles/org.openhab.ui.basic/src/main/java/org/openhab/ui/basic/internal/render/AbstractWidgetRenderer.java b/bundles/org.openhab.ui.basic/src/main/java/org/openhab/ui/basic/internal/render/AbstractWidgetRenderer.java index 3815f99069..41923e1cd2 100644 --- a/bundles/org.openhab.ui.basic/src/main/java/org/openhab/ui/basic/internal/render/AbstractWidgetRenderer.java +++ b/bundles/org.openhab.ui.basic/src/main/java/org/openhab/ui/basic/internal/render/AbstractWidgetRenderer.java @@ -123,7 +123,7 @@ protected String preprocessSnippet(String originalSnippet, Widget w) { * @return HTML code */ protected String preprocessSnippet(String originalSnippet, Widget w, boolean ignoreStateForIcon) { - String snippet = preprocessIcon(originalSnippet, w, ignoreStateForIcon); + String snippet = preprocessIcon(originalSnippet, getCategory(w), ignoreStateForIcon); snippet = snippet.replace("%cells%", String.valueOf(12 / config.getNbColsDesktop())); snippet = snippet.replace("%cells_tablet%", String.valueOf(8 / config.getNbColsTablet())); @@ -144,13 +144,12 @@ protected String preprocessSnippet(String originalSnippet, Widget w, boolean ign return snippet; } - private String preprocessIcon(String originalSnippet, Widget w, boolean ignoreState) { - String category = getCategory(w); + protected String preprocessIcon(String originalSnippet, @Nullable String icon, boolean ignoreState) { String iconSource = DEFAULT_ICON_SOURCE; String iconSet = DEFAULT_ICON_SET; String iconName = DEFAULT_ICON_NAME; - if (category != null) { - String[] segments = category.split(":", 3); + if (icon != null) { + String[] segments = icon.split(":", 3); if (segments.length == 1) { iconName = segments[0]; } else if (segments.length == 2) { diff --git a/bundles/org.openhab.ui.basic/src/main/java/org/openhab/ui/basic/internal/render/SwitchRenderer.java b/bundles/org.openhab.ui.basic/src/main/java/org/openhab/ui/basic/internal/render/SwitchRenderer.java index 1047213a0b..e182df1c99 100644 --- a/bundles/org.openhab.ui.basic/src/main/java/org/openhab/ui/basic/internal/render/SwitchRenderer.java +++ b/bundles/org.openhab.ui.basic/src/main/java/org/openhab/ui/basic/internal/render/SwitchRenderer.java @@ -34,6 +34,7 @@ import org.openhab.core.types.State; import org.openhab.core.types.util.UnitUtils; import org.openhab.core.ui.items.ItemUIRegistry; +import org.openhab.ui.basic.internal.WebAppConfig; import org.openhab.ui.basic.render.RenderException; import org.openhab.ui.basic.render.WidgetRenderer; import org.osgi.framework.BundleContext; @@ -49,6 +50,7 @@ * * @author Kai Kreuzer - Initial contribution and API * @author Vlad Ivanov - BasicUI changes + * @author Laurent Garnier - Use icon instead of label for button if icon is set */ @Component(service = WidgetRenderer.class) @NonNullByDefault @@ -126,12 +128,13 @@ public EList renderWidget(Widget w, StringBuilder sb, String sitemap) th if (commandDescription != null) { for (CommandOption option : commandDescription.getCommandOptions()) { // Truncate the button label to MAX_LABEL_SIZE characters - buildButton(s, option.getLabel(), option.getCommand(), MAX_LABEL_SIZE, item, state, buttons); + buildButton(s, option.getLabel(), option.getCommand(), null, MAX_LABEL_SIZE, item, state, + buttons); } } } else { for (Mapping mapping : s.getMappings()) { - buildButton(s, mapping.getLabel(), mapping.getCmd(), -1, item, state, buttons); + buildButton(s, mapping.getLabel(), mapping.getCmd(), mapping.getIcon(), -1, item, state, buttons); } } snippet = snippet.replace("%buttons%", buttons.toString()); @@ -145,8 +148,8 @@ public EList renderWidget(Widget w, StringBuilder sb, String sitemap) th return ECollections.emptyEList(); } - private void buildButton(Switch w, @Nullable String lab, String cmd, int maxLabelSize, @Nullable Item item, - @Nullable State state, StringBuilder buttons) throws RenderException { + private void buildButton(Switch w, @Nullable String lab, String cmd, @Nullable String icon, int maxLabelSize, + @Nullable Item item, @Nullable State state, StringBuilder buttons) throws RenderException { String button = getSnippet("button"); String command = cmd; @@ -166,9 +169,28 @@ private void buildButton(Switch w, @Nullable String lab, String cmd, int maxLabe button = button.replace("%item%", w.getItem()); button = button.replace("%cmd%", escapeHtml(command)); - button = button.replace("%label%", escapeHtml(label)); + String buttonClass = ""; + String style = ""; + if (icon == null || !config.isIconsEnabled()) { + button = button.replace("%label%", escapeHtml(label)); + button = button.replace("%icon_snippet%", ""); + } else { + button = button.replace("%label%", ""); + button = preprocessIcon(button, icon, true); + buttonClass = "mdl-button-icon"; + switch (config.getTheme()) { + case WebAppConfig.THEME_NAME_BRIGHT: + style = "style=\"color-scheme: light\""; + break; + case WebAppConfig.THEME_NAME_DARK: + style = "style=\"color-scheme: dark\""; + break; + default: + break; + } + } + button = button.replace("%buttonstyle%", style); - String buttonClass; State compareMappingState = state; if (state instanceof QuantityType) { // convert the item state to the command value for proper // comparison and buttonClass calculation @@ -176,9 +198,7 @@ private void buildButton(Switch w, @Nullable String lab, String cmd, int maxLabe } if (compareMappingState != null && compareMappingState.toString().equals(command)) { - buttonClass = "mdl-button--accent"; - } else { - buttonClass = "mdl-button"; + buttonClass += " mdl-button--accent"; } button = button.replace("%class%", buttonClass); diff --git a/bundles/org.openhab.ui.basic/src/main/resources/snippets/button.html b/bundles/org.openhab.ui.basic/src/main/resources/snippets/button.html index d4b7610ccb..2148173478 100644 --- a/bundles/org.openhab.ui.basic/src/main/resources/snippets/button.html +++ b/bundles/org.openhab.ui.basic/src/main/resources/snippets/button.html @@ -1,6 +1,6 @@ - diff --git a/bundles/org.openhab.ui.basic/web-src/_layout.scss b/bundles/org.openhab.ui.basic/web-src/_layout.scss index 399833ef8f..7631cd5495 100644 --- a/bundles/org.openhab.ui.basic/web-src/_layout.scss +++ b/bundles/org.openhab.ui.basic/web-src/_layout.scss @@ -246,6 +246,23 @@ box-shadow: none; -webkit-box-shadow: none; } + .mdl-button-icon { + min-width: 0; + img { + width: 24px; + height: 24px; + object-fit: contain; + } + iconify-icon { + font-size: 24px; + vertical-align: middle; + } + .material-icons, + .f7-icons { + font-size: 24px; + vertical-align: middle; + } + } .mdl-textfield { &__input, &__label {