Skip to content

Commit

Permalink
[BasicUI] Add a new header line for image, chart and video elements
Browse files Browse the repository at this point in the history
Header line for video element contains icon and label.

Header line for image element contains icon, label and a button to switch between no upscale and upscale of the image. Header line for chart element contains icon, label and 4 buttons:
 - one button to show or hide the legend
 - one button to change the time range
 - one button to switch between no upscale and upscale of the chart
 - one button to refresh the chart

Fix handling of iconcolor and labelcolor parameters for mapview and webview elements.

For image and chart elements, the header line is always present so that user has an access to its buttons.
For video, mapview and webview elements, if the label is empty, the header line is hidden.

For chart and image elements, there is now no upscale applied by default (tablet/phone devices) but a button allows upscaling.

Closes openhab#1939
Fixes openhab#1367
Also related to openhab#1930

Signed-off-by: Laurent Garnier <[email protected]>
  • Loading branch information
lolodomo committed Aug 16, 2023
1 parent 7f2dbb3 commit 6c5bfc5
Show file tree
Hide file tree
Showing 13 changed files with 369 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.List;

import org.eclipse.emf.common.util.ECollections;
import org.eclipse.emf.common.util.EList;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.i18n.LocaleProvider;
import org.openhab.core.i18n.TranslationProvider;
import org.openhab.core.items.GroupItem;
Expand Down Expand Up @@ -91,7 +93,9 @@ public EList<Widget> renderWidget(Widget w, StringBuilder sb, String sitemap) th
}

// if legend parameter is given, add corresponding GET parameter
boolean legend = item instanceof GroupItem && !forceAsItem;
if (chart.getLegend() != null) {
legend = chart.getLegend();
if (chart.getLegend()) {
chartUrl += "&legend=true";
} else {
Expand Down Expand Up @@ -123,7 +127,10 @@ public EList<Widget> renderWidget(Widget w, StringBuilder sb, String sitemap) th
}

String snippet = getSnippet("chart");
snippet = preprocessSnippet(snippet, w);
snippet = preprocessSnippet(snippet, w, true);

// Process the color tags
snippet = processColor(w, snippet);

if (chart.getRefresh() > 0) {
snippet = snippet.replace("%update_interval%", Integer.toString(chart.getRefresh()));
Expand All @@ -136,11 +143,43 @@ public EList<Widget> renderWidget(Widget w, StringBuilder sb, String sitemap) th
snippet = snippet.replace("%valid_url%", "true");
snippet = snippet.replace("%ignore_refresh%", ignoreRefresh ? "true" : "false");
snippet = snippet.replace("%url%", url);
snippet = snippet.replace("%legend%", Boolean.valueOf(legend).toString());

List<List<String>> periods = List.of(List.of("Last hour", "h"), List.of("Last 4 hours", "4h"),
List.of("Last 8 hours", "8h"), List.of("Last 12 hours", "12h"), List.of("Last day", "D"),
List.of("Last 2 days", "2D"), List.of("Last 3 days", "3D"), List.of("Last week", "W"),
List.of("Last 2 weeks", "2W"), List.of("Last month", "M"), List.of("Last 2 months", "2M"),
List.of("Last 4 months", "4M"), List.of("Last year", "Y"));
StringBuilder rowSB = new StringBuilder();
for (List<String> period : periods) {
buildRow(chart, period.get(0), period.get(1), chart.getPeriod(), rowSB);
}
snippet = snippet.replace("%period_rows%", rowSB.toString());

sb.append(snippet);
} catch (ItemNotFoundException e) {
logger.warn("Chart cannot be rendered as item '{}' does not exist.", chart.getItem());
}
return ECollections.emptyEList();
}

private void buildRow(Chart w, @Nullable String lab, String cmd, String current, StringBuilder rowSB)
throws RenderException {
String rowSnippet = getSnippet("selection_row");

String command = cmd;
String label = lab == null ? cmd : lab;

rowSnippet = rowSnippet.replace("%item%", w.getItem() != null ? w.getItem() : "");
rowSnippet = rowSnippet.replace("%cmd%", escapeHtml(command));
rowSnippet = rowSnippet.replace("%label%", escapeHtml(label));

if (command.equals(current)) {
rowSnippet = rowSnippet.replace("%checked%", "checked=\"true\"");
} else {
rowSnippet = rowSnippet.replace("%checked%", "");
}

rowSB.append(rowSnippet);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,10 @@ public EList<Widget> renderWidget(Widget w, StringBuilder sb, String sitemap) th

String widgetId = itemUIRegistry.getWidgetId(w);
snippet = snippet.replace("%id%", widgetId);
snippet = preprocessSnippet(snippet, w);
snippet = preprocessSnippet(snippet, w, true);

// Process the color tags
snippet = processColor(w, snippet);

boolean validUrl = isValidURL(image.getUrl());
String proxiedUrl = "../proxy?sitemap=" + sitemap + "&amp;widgetId=" + widgetId;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,14 @@ public boolean canRender(Widget w) {
public EList<Widget> renderWidget(Widget w, StringBuilder sb, String sitemap) throws RenderException {
Mapview mapview = (Mapview) w;
String snippet = getSnippet("mapview");

boolean showHeaderRow = !getLabel(w).isEmpty();
snippet = snippet.replace("%header_visibility_class%",
showHeaderRow ? "%visibility_class%" : "mdl-form__row--hidden");
snippet = snippet.replace("%header_row%", Boolean.valueOf(showHeaderRow).toString());

snippet = preprocessSnippet(snippet, mapview, true);

// Process the color tags
snippet = processColor(w, snippet);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,16 @@ public EList<Widget> renderWidget(Widget w, StringBuilder sb, String sitemap) th
&& videoWidget.getEncoding().toLowerCase().contains("mjpeg")) ? "image" : "video";

snippet = getSnippet(snippetName);
snippet = preprocessSnippet(snippet, w);

boolean showHeaderRow = !getLabel(w).isEmpty();
snippet = snippet.replace("%header_visibility_class%",
showHeaderRow ? "%visibility_class%" : "mdl-form__row--hidden");
snippet = snippet.replace("%header_row%", Boolean.valueOf(showHeaderRow).toString());

snippet = preprocessSnippet(snippet, w, true);

// Process the color tags
snippet = processColor(w, snippet);

State state = itemUIRegistry.getState(w);
String url;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,14 @@ public boolean canRender(Widget w) {
public EList<Widget> renderWidget(Widget w, StringBuilder sb, String sitemap) throws RenderException {
Webview webview = (Webview) w;
String snippet = getSnippet("webview");

boolean showHeaderRow = !getLabel(w).isEmpty();
snippet = snippet.replace("%header_visibility_class%",
showHeaderRow ? "%visibility_class%" : "mdl-form__row--hidden");
snippet = snippet.replace("%header_row%", Boolean.valueOf(showHeaderRow).toString());

snippet = preprocessSnippet(snippet, webview, true);

// Process the color tags
snippet = processColor(w, snippet);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,38 @@
<div class="mdl-form__row mdl-form__row--header mdl-cell mdl-cell--12-col %visibility_class%">
<span %iconstyle% class="mdl-form__icon">
%icon_snippet%
</span>
<span %labelstyle% class="mdl-form__label">
%label%
</span>
<div class="mdl-form__header">
<button id="button1-%widget_id%" class="mdl-button mdl-button--raised mdl-js-button mdl-js-ripple-effect chart-legend-button">
<!-- legend_toggle -->
<i class="material-icons">&#xF11B;</i>
</button>
<spam class="mdl-tooltip mdl-tooltip--top" for="button1-%widget_id%">Show or hde legend</spam>
<button id="button2-%widget_id%" class="mdl-button mdl-button--raised mdl-js-button mdl-js-ripple-effect chart-period-button">
<!-- more_time -->
<i class="material-icons">&#xEA5D;</i>
</button>
<spam class="mdl-tooltip mdl-tooltip--top" for="button2-%widget_id%">Choose time frame</spam>
<script type="text/html" class="mdl-form__header-rows">
<div class="mdl-radio__group">
%period_rows%
</div>
</script>
<button id="button3-%widget_id%" class="mdl-button mdl-button--raised mdl-js-button mdl-js-ripple-effect image-upscale-button">
<!-- fullscreen -->
<i class="material-icons">&#xE5D0;</i>
</button>
<spam class="mdl-tooltip mdl-tooltip--top" for="button3-%widget_id%">Upscale chart or not</spam>
<button id="button4-%widget_id%" class="mdl-button mdl-button--raised mdl-js-button mdl-js-ripple-effect chart-refresh-button">
<!-- refresh -->
<i class="material-icons">&#xE5D5;</i>
</button>
<spam class="mdl-tooltip mdl-tooltip--top" for="button4-%widget_id%">Refresh chart</spam>
</div>
</div>
<div class="mdl-form__row mdl-form__row--height-auto mdl-cell mdl-cell--12-col %visibility_class%">
<div
class="mdl-form__control mdl-form__image"
Expand All @@ -7,6 +42,8 @@
data-proxied-url="%proxied_url%"
data-valid-url="%valid_url%"
data-ignore-refresh="%ignore_refresh%"
data-header-row="true"
data-legend="%legend%"
>
<img src="%url%" />
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
<div class="mdl-form__row mdl-form__row--header mdl-cell mdl-cell--12-col %visibility_class%">
<span %iconstyle% class="mdl-form__icon">
%icon_snippet%
</span>
<span %labelstyle% class="mdl-form__label">
%label%
</span>
<div class="mdl-form__header">
<button id="button-%widget_id%" class="mdl-button mdl-button--raised mdl-js-button mdl-js-ripple-effect image-upscale-button">
<!-- fullscreen -->
<i class="material-icons">&#xE5D0;</i>
</button>
<spam class="mdl-tooltip mdl-tooltip--top" for="button-%widget_id%">Upscale image or not</spam>
</div>
</div>
<div class="mdl-form__row mdl-form__row--height-auto mdl-cell mdl-cell--12-col %visibility_class%">
<div
class="mdl-form__control mdl-form__image"
Expand All @@ -8,6 +23,7 @@
data-proxied-url="%proxied_url%"
data-valid-url="%valid_url%"
data-ignore-refresh="%ignore_refresh%"
data-header-row="true"
>
<img src="%url%" />
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<div class="mdl-form__row mdl-cell mdl-cell--12-col %visibility_class%">
<span %iconstyle% class="mdl-form__icon">
%icon_snippet%
</span>
<span %labelstyle% class="mdl-form__label">
%label%
</span>
<div class="mdl-form__row mdl-form__row--header mdl-cell mdl-cell--12-col %header_visibility_class%">
<span %iconstyle% class="mdl-form__icon">
%icon_snippet%
</span>
<span %labelstyle% class="mdl-form__label">
%label%
</span>
</div>
<div class="mdl-form__row mdl-form__row--height-auto mdl-cell mdl-cell--12-col %visibility_class%">
<div
Expand All @@ -13,6 +13,7 @@
data-widget-id="%widget_id%"
data-map-url="%map_url%"
data-map-zoom="%map_zoom%"
data-header-row="%header_row%"
>
<iframe src="%url%" height="%height%"></iframe>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
<div class="mdl-form__row mdl-form__row--header mdl-cell mdl-cell--12-col %header_visibility_class%">
<span %iconstyle% class="mdl-form__icon">
%icon_snippet%
</span>
<span %labelstyle% class="mdl-form__label">
%label%
</span>
</div>
<div class="mdl-form__row mdl-form__row--height-auto mdl-cell mdl-cell--12-col %visibility_class%">
<div
class="mdl-form__control mdl-form__video"
data-control-type="video"
data-widget-id="%widget_id%"
data-header-row="%header_row%"
>
<video autoplay controls src="%url%" %media_type%></video>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
<div class="mdl-form__row mdl-cell mdl-cell--12-col %visibility_class%">
<span %iconstyle% class="mdl-form__icon">
%icon_snippet%
</span>
<span %labelstyle% class="mdl-form__label">
%label%
</span>
<div class="mdl-form__row mdl-form__row--header mdl-cell mdl-cell--12-col %header_visibility_class%">
<span %iconstyle% class="mdl-form__icon">
%icon_snippet%
</span>
<span %labelstyle% class="mdl-form__label">
%label%
</span>
</div>
<div class="mdl-form__row mdl-form__row--height-auto mdl-cell mdl-cell--12-col %visibility_class%">
<div
class="mdl-form__control mdl-form__webview"
data-control-type="webview"
data-widget-id="%widget_id%"
data-header-row="%header_row%"
>
<iframe src="%url%" height="%height%"></iframe>
</div>
Expand Down
44 changes: 35 additions & 9 deletions bundles/org.openhab.ui.basic/web-src/_layout.scss
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@
@include align-items-2011(center);
white-space: nowrap;
height: $form-row-desktop-height;
html.ui-layout-condensed & {
height: $form-row-desktop-height-condensed;
}
box-sizing: content-box;
padding: 4px 0;
margin: 0 $mdl-grid-spacing;
Expand All @@ -79,7 +82,7 @@
padding: 4px $mdl-grid-spacing;
margin: 0;
html.ui-layout-condensed & {
height: $form-row-desktop-height-condensed;
height: $form-row-mobile-height-condensed;
}
}
@media screen and (min-width: $layout-tablet-size-threshold) {
Expand All @@ -98,12 +101,19 @@
height: auto;
}
}
&--header {
border-bottom: none;
padding-bottom: 0;
padding-left: 48px;
padding-right: 48px;
@media screen and (max-width: $layout-tablet-size-threshold) {
padding-left: $mdl-grid-spacing + 16px;
padding-right: $mdl-grid-spacing + 16px;
}
}
&--hidden {
display: none;
}
html.ui-layout-condensed & {
height: $form-row-desktop-height-condensed;
}
}
&__image {
&.mdl-form__control {
Expand All @@ -114,11 +124,7 @@
max-width: 100%;
}
}
@media screen and (max-width: $layout-tablet-size-threshold) {
&.mdl-form__control {
padding-left: 0;
padding-right: 0;
}
&-upscale {
width: 100%;
img {
height: auto;
Expand Down Expand Up @@ -264,6 +270,26 @@
padding-top: 6px;
}
}
&__header {
padding-left: 8px;
padding-right: $form-row-desktop-padding;
@media screen and (max-width: $layout-tablet-size-threshold) {
padding-right: $form-row-mobile-padding;
}
.mdl-button {
box-shadow: none;
-webkit-box-shadow: none;
min-width: 0;
padding-top: 6px;
}
.chart-legend-button,
.chart-period-button {
padding-top: 1px;
}
&-rows {
display: none;
}
}
&__group {
padding-top: 4px;
}
Expand Down
4 changes: 4 additions & 0 deletions bundles/org.openhab.ui.basic/web-src/_theming.scss
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ body {
color: var(--container-text-color, #616161) !important;
}

.mdl-form__row--header {
border-bottom: none;
}

.mdl-switch .mdl-switch__track {
background: rgba(0,0,0,.26);
background: var(--switch-off-track-bg, rgba(0,0,0,.26));
Expand Down
Loading

0 comments on commit 6c5bfc5

Please sign in to comment.