Skip to content

Commit

Permalink
[BasicUI] Prefer icon over text in buttons (switch element) (#2085)
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
lolodomo authored Oct 3, 2023
1 parent 87e68aa commit 23550c6
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -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);
Expand Down Expand Up @@ -116,6 +118,7 @@ public void applyConfig(Map<String, Object> 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));
Expand Down Expand Up @@ -147,6 +150,10 @@ public int getNbColsTablet() {
return nbColsTablet;
}

public boolean isIconsEnabled() {
return icons;
}

public boolean isIconifyEnabled() {
return iconify;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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()));
Expand All @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
Expand Down Expand Up @@ -126,12 +128,13 @@ public EList<Widget> 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());
Expand All @@ -145,8 +148,8 @@ public EList<Widget> 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;
Expand All @@ -166,19 +169,36 @@ 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
compareMappingState = convertStateToLabelUnit((QuantityType<?>) state, command);
}

if (compareMappingState != null && compareMappingState.toString().equals(command)) {
buttonClass = "mdl-button--accent";
} else {
buttonClass = "mdl-button";
buttonClass += " mdl-button--accent";
}
button = button.replace("%class%", buttonClass);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<button
<button %buttonstyle%
class="mdl-button mdl-button--raised mdl-js-button mdl-js-ripple-effect %class%"
data-value="%cmd%"
>
%label%
%label%%icon_snippet%
</button>
17 changes: 17 additions & 0 deletions bundles/org.openhab.ui.basic/web-src/_layout.scss
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down

0 comments on commit 23550c6

Please sign in to comment.