Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BasicUI] Align and optimize available space for switch with mappings #2388

Merged
merged 13 commits into from
Nov 30, 2024
Merged
2 changes: 1 addition & 1 deletion bundles/org.openhab.ui.basic/snippets-src/buttons.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<span class="mdl-form__icon">
%icon_snippet%
</span>
<span class="mdl-form__label">
<span class="mdl-form__label %label_class%">
%label%
</span>
<span class="mdl-form__value mdl-form__value--group">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,17 @@ public EList<Widget> renderWidget(Widget w, StringBuilder sb, String sitemap) th

snippet = preprocessSnippet(snippet, w);

snippet = snippet.replaceAll("%height_auto%", multiline ? "mdl-form__row--height-auto" : "");
snippet = snippet.replaceAll("%buttons_class%",
multiline ? "mdl-form__buttons-multiline" : "mdl-form__buttons");
if (multiline) {
snippet = snippet //
.replaceAll("%height_auto%", "mdl-form__row--height-auto")
.replaceAll("%buttons_class%", "mdl-form__buttons-multiline")
.replaceAll("%label_class%", "mdl-form__label-multiline");
} else {
snippet = snippet //
.replaceAll("%height_auto%", "") //
.replaceAll("%buttons_class%", "mdl-form__buttons") //
.replaceAll("%label_class%", "");
}

StringBuilder buttons = new StringBuilder();
if (s.getMappings().isEmpty() && item != null) {
Expand Down
42 changes: 28 additions & 14 deletions bundles/org.openhab.ui.basic/web-src/_layout.scss
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@
@media screen and (max-width: $layout-tablet-size-threshold) {
padding-left: $form-row-mobile-padding;
html.ui-layout-condensed & {
padding-left: $form-row-mobile-padding-condensed;
padding-left: 0; // there's already padding in .mdl-form__row
}
}
html:not(.ui-icons-enabled) & {
Expand Down Expand Up @@ -212,16 +212,16 @@
}
}
&__label {
padding-left: $form-row-desktop-padding;
html.ui-layout-condensed & {
padding-left: $form-row-desktop-padding-condensed;
}
@media screen and (max-width: $layout-tablet-size-threshold) {
padding-left: $form-row-mobile-padding;
html.ui-layout-condensed & {
padding-left: $form-row-mobile-padding-condensed;
}
}
padding-left: $form-row-desktop-padding;
html.ui-layout-condensed & {
padding-left: $form-row-desktop-padding-condensed;
}
@include flex-shrink(0);
@include flex-grow(2);
@include flex-2011(2 2 auto);
Expand All @@ -232,18 +232,22 @@
font-size: 18px;
}
}
&__label-multiline {
min-width: 3em;
}
&__control {
padding-right: $form-row-desktop-padding;
padding-left: 4px;
html.ui-layout-condensed & {
padding-left: 0;
padding-right: $form-row-desktop-padding-condensed;
}
@media screen and (max-width: $layout-tablet-size-threshold) {
padding-right: $form-row-mobile-padding;
html.ui-layout-condensed & {
padding-left: $form-row-mobile-padding-condensed;
padding-right: $form-row-mobile-padding-condensed;
}
}
padding-right: $form-row-desktop-padding;
padding-left: 4px;
html.ui-layout-condensed & {
padding-left: $form-row-desktop-padding-condensed;
}
font-weight: 700;
html.ui-capitalize-values & {
text-transform: uppercase;
Expand All @@ -270,7 +274,7 @@
.buttongrid-cell {
height: 36px;
.buttongrid-button {
min-width: 100%;
min-width: 100% !important;
text-transform: none;
}
}
Expand All @@ -279,6 +283,12 @@
box-shadow: none;
-webkit-box-shadow: none;
text-transform: unset;
min-width: 54px;
html.ui-layout-condensed & {
min-width: 40px;
padding-left: 4px;
padding-right: 4px;
}
}
.mdl-button-text {
html.ui-bigger-font & {
Expand Down Expand Up @@ -502,16 +512,20 @@
}
&__buttons {
padding-top: 2px;
padding-bottom: 2px;
}
&__buttons-multiline {
margin: 6px 0;
gap: 4px;
html.ui-layout-condensed & {
margin: 0;
gap: 3px;
}
max-width: 60%;
padding-top: 2px;
padding-bottom: 2px;
display: flex;
flex-wrap: wrap;
gap: 4px;
justify-content: end;
}
&__buttongrid {
padding: 0;
Expand Down
75 changes: 75 additions & 0 deletions bundles/org.openhab.ui.basic/web-src/smarthome.js
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,12 @@
});
}

function getElementWidth(element) {
var style = getComputedStyle(element);
return element.offsetWidth + parseFloat(style.marginLeft) + parseFloat(style.marginRight) +
parseFloat(style.paddingLeft) + parseFloat(style.paddingRight);
}

function EventMapper() {
var
_t = this;
Expand Down Expand Up @@ -1177,6 +1183,7 @@
Control.call(this, parentNode);

var
maxButtonWidth = 0,
_t = this;

_t.ignoreState = _t.parentNode.getAttribute("data-ignore-state") === "true";
Expand Down Expand Up @@ -1239,6 +1246,7 @@
) {
_t.valueMap[itemState].classList.add(o.buttonActiveClass);
}
_t.minimizeWidth();
};

_t.setValueColor = function(color) {
Expand Down Expand Up @@ -1337,8 +1345,72 @@
icon.addEventListener("load", _t.convertToInlineSVG);
icon.addEventListener("error", _t.replaceImageWithNone);
}

if (maxButtonWidth < button.offsetWidth) {
maxButtonWidth = button.offsetWidth;
}
});

if (_t.buttons.length > 1 && _t.parentNode.classList.contains(o.buttonsMultilineClass)) {
lolodomo marked this conversation as resolved.
Show resolved Hide resolved
var labelMinWidth = 0;
if (_t.label.textContent.trim().length === 0) {
_t.label.style.paddingLeft = 0;
_t.label.style.minWidth = 0;
} else {
// Try to see if setting min-width: min-content would result in a narrower min-width
// than the one set in _layout.scss, e.g. when the label is short.
// If it does make it narrower, it frees up more space for the buttons.
// If it is not narrower, un-set it, so that the min-width from _layout.scss can take effect.

// To measure the min-width using offsetWidth,
// we need to make the neighbouring element (buttons) as wide as possible
// to force the label to shrink to its min-width
// Note that _t.parentNode.style.width will get readjusted inside minimizeWidth()
// so setting it to 100% here wouldn't affect the final layout.
_t.parentNode.style.width = "100%";

var defaultMinWidth = parseFloat(getComputedStyle(_t.label).minWidth);
_t.label.style.minWidth = "min-content";
var minContentWidth = _t.label.offsetWidth;
if (minContentWidth > defaultMinWidth) {
_t.label.style.removeProperty("min-width");
labelMinWidth = defaultMinWidth;
} else {
labelMinWidth = minContentWidth;
}
}

_t.minimizeWidth = function() {
// Minimize the width taken by the buttons without adding extra rows.
// Start from the maximum width the buttons can take,
// then shrink it down to the minimum without causing additional wrapping.
var buttons = _t.parentNode;
var buttonsStyle = getComputedStyle(buttons);
var labelStyle = getComputedStyle(_t.label);
// Calculate the maximum width the buttons can take
var width = buttons.parentElement.offsetWidth -
parseFloat(buttonsStyle.paddingLeft) - parseFloat(buttonsStyle.paddingRight) -
getElementWidth(_t.iconContainer) - getElementWidth(_t.value);
if (labelMinWidth) {
width -= labelMinWidth + parseFloat(labelStyle.paddingLeft) + parseFloat(labelStyle.paddingRight);
}
buttons.style.width = width + "px";
width = buttons.offsetWidth;
var height = buttons.offsetHeight;
while (buttons.offsetHeight === height && width >= maxButtonWidth) {
buttons.style.width = --width + "px";
}
buttons.style.width = (width+1) + "px";
};

_t.minimizeWidth();
// Wait until after all the icons are loaded before running minimizeWidth()
window.addEventListener("load", _t.minimizeWidth);
window.addEventListener("resize", _t.minimizeWidth);
} else {
_t.minimizeWidth = function() {};
}

_t.destroy = function() {
_t.buttons.forEach(function(button) {
var
Expand All @@ -1361,6 +1433,8 @@
}
});
componentHandler.downgradeElements(_t.buttons);
window.removeEventListener("load", _t.minimizeWidth);
window.removeEventListener("resize", _t.minimizeWidth);
lolodomo marked this conversation as resolved.
Show resolved Hide resolved
};

_t.setValueColor(_t.valueColor);
Expand Down Expand Up @@ -3936,6 +4010,7 @@
buttonTextClass: "mdl-button-text",
buttonIconText: ".mdl-button-icon-text",
buttonIconTextClass: "mdl-button-icon-text",
buttonsMultilineClass: "mdl-form__buttons-multiline",
modal: ".mdl-modal",
modalContainer: ".mdl-modal__content",
selectionRows: ".mdl-form__selection-rows",
Expand Down