Browse Source

TB-70: RPC widgets: Implemented switch control widget.

pull/212/head
Igor Kulikov 9 years ago
parent
commit
91afd7164f
  1. 20
      application/src/main/data/json/system/widget_bundles/control_widgets.json
  2. 4
      ui/src/app/widget/lib/rpc/index.js
  3. 6
      ui/src/app/widget/lib/rpc/knob.directive.js
  4. 5
      ui/src/app/widget/lib/rpc/knob.scss
  5. 2
      ui/src/app/widget/lib/rpc/knob.tpl.html
  6. 0
      ui/src/app/widget/lib/rpc/svg/knob.svg
  7. 43
      ui/src/app/widget/lib/rpc/svg/thumb-bar-checked.svg
  8. 42
      ui/src/app/widget/lib/rpc/svg/thumb-bar.svg
  9. 40
      ui/src/app/widget/lib/rpc/svg/thumb-checked.svg
  10. 37
      ui/src/app/widget/lib/rpc/svg/thumb.svg
  11. 214
      ui/src/app/widget/lib/rpc/switch.directive.js
  12. 127
      ui/src/app/widget/lib/rpc/switch.scss
  13. 40
      ui/src/app/widget/lib/rpc/switch.tpl.html

20
application/src/main/data/json/system/widget_bundles/control_widgets.json

@ -48,9 +48,25 @@
"templateHtml": "<tb-knob ctx='ctx'></tb-knob>",
"templateCss": "",
"controllerScript": "self.onInit = function() {\n var scope = self.ctx.$scope;\n scope.ctx = self.ctx;\n}\n\nself.onResize = function() {\n if (self.ctx.resize) {\n self.ctx.resize();\n }\n}\n\nself.onDestroy = function() {\n}\n",
"settingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"Settings\",\n \"properties\": {\n \"minValue\": {\n \"title\": \"Minimum value\",\n \"type\": \"number\",\n \"default\": 0\n },\n \"maxValue\": {\n \"title\": \"Maximum value\",\n \"type\": \"number\",\n \"default\": 100\n },\n \"initialValue\": {\n \"title\": \"Initial value\",\n \"type\": \"number\",\n \"default\": 50\n },\n \"title\": {\n \"title\": \"Knob title\",\n \"type\": \"string\",\n \"default\": \"\"\n },\n \"getValueMethod\": {\n \"title\": \"Get value method\",\n \"type\": \"string\",\n \"default\": \"getValue\"\n },\n \"setValueMethod\": {\n \"title\": \"Set value method\",\n \"type\": \"string\",\n \"default\": \"setValue\"\n },\n \"requestTimeout\": {\n \"title\": \"RPC request timeout\",\n \"type\": \"number\",\n \"default\": 500\n }\n },\n \"required\": [\"minValue\", \"maxValue\", \"getValueMethod\", \"setValueMethod\", \"requestTimeout\"]\n },\n \"form\": [\n \"minValue\",\n \"maxValue\",\n \"initialValue\",\n \"getValueMethod\",\n \"setValueMethod\",\n \"title\",\n \"requestTimeout\"\n ]\n}",
"settingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"Settings\",\n \"properties\": {\n \"minValue\": {\n \"title\": \"Minimum value\",\n \"type\": \"number\",\n \"default\": 0\n },\n \"maxValue\": {\n \"title\": \"Maximum value\",\n \"type\": \"number\",\n \"default\": 100\n },\n \"initialValue\": {\n \"title\": \"Initial value\",\n \"type\": \"number\",\n \"default\": 50\n },\n \"title\": {\n \"title\": \"Knob title\",\n \"type\": \"string\",\n \"default\": \"\"\n },\n \"getValueMethod\": {\n \"title\": \"Get value method\",\n \"type\": \"string\",\n \"default\": \"getValue\"\n },\n \"setValueMethod\": {\n \"title\": \"Set value method\",\n \"type\": \"string\",\n \"default\": \"setValue\"\n },\n \"requestTimeout\": {\n \"title\": \"RPC request timeout\",\n \"type\": \"number\",\n \"default\": 500\n }\n },\n \"required\": [\"minValue\", \"maxValue\", \"getValueMethod\", \"setValueMethod\", \"requestTimeout\"]\n },\n \"form\": [\n \"minValue\",\n \"maxValue\",\n \"initialValue\",\n \"title\",\n \"getValueMethod\",\n \"setValueMethod\",\n \"requestTimeout\"\n ]\n}",
"dataKeySettingsSchema": "{}\n",
"defaultConfig": "{\"targetDeviceAliases\":[],\"showTitle\":false,\"backgroundColor\":\"#fff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0px\",\"settings\":{\"requestTimeout\":500,\"maxValue\":100,\"initialValue\":50,\"minValue\":0,\"title\":\"Knob control\"},\"title\":\"Knob Control\",\"dropShadow\":true,\"enableFullscreen\":false,\"widgetStyle\":{},\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"useDashboardTimewindow\":true,\"showLegend\":false,\"actions\":{},\"decimals\":2}"
"defaultConfig": "{\"targetDeviceAliases\":[],\"showTitle\":false,\"backgroundColor\":\"#fff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0px\",\"settings\":{\"requestTimeout\":500,\"maxValue\":100,\"initialValue\":50,\"minValue\":0,\"title\":\"Knob control\",\"getValueMethod\":\"getValue\",\"setValueMethod\":\"setValue\"},\"title\":\"Knob Control\",\"dropShadow\":true,\"enableFullscreen\":false,\"widgetStyle\":{},\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"useDashboardTimewindow\":true,\"showLegend\":false,\"actions\":{},\"decimals\":2}"
}
},
{
"alias": "switch_control",
"name": "Switch Control",
"descriptor": {
"type": "rpc",
"sizeX": 4,
"sizeY": 2.5,
"resources": [],
"templateHtml": "<tb-switch ctx='ctx'></tb-switch>",
"templateCss": "",
"controllerScript": "self.onInit = function() {\n var scope = self.ctx.$scope;\n scope.ctx = self.ctx;\n}\n\nself.onResize = function() {\n if (self.ctx.resize) {\n self.ctx.resize();\n }\n}\n\nself.onDestroy = function() {\n}\n",
"settingsSchema": "{\n \"schema\": {\n \"type\": \"object\",\n \"title\": \"Settings\",\n \"properties\": {\n \"initialValue\": {\n \"title\": \"Initial value\",\n \"type\": \"boolean\",\n \"default\": false\n },\n \"title\": {\n \"title\": \"Switch title\",\n \"type\": \"string\",\n \"default\": \"\"\n },\n \"showOnOffLabels\": {\n \"title\": \"Show on/off labels\",\n \"type\": \"boolean\",\n \"default\": true\n },\n \"getValueMethod\": {\n \"title\": \"Get value method\",\n \"type\": \"string\",\n \"default\": \"getValue\"\n },\n \"setValueMethod\": {\n \"title\": \"Set value method\",\n \"type\": \"string\",\n \"default\": \"setValue\"\n },\n \"requestTimeout\": {\n \"title\": \"RPC request timeout\",\n \"type\": \"number\",\n \"default\": 500\n }\n },\n \"required\": [\"getValueMethod\", \"setValueMethod\", \"requestTimeout\"]\n },\n \"form\": [\n \"initialValue\",\n \"title\",\n \"showOnOffLabels\",\n \"getValueMethod\",\n \"setValueMethod\",\n \"requestTimeout\"\n ]\n}",
"dataKeySettingsSchema": "{}\n",
"defaultConfig": "{\"targetDeviceAliases\":[],\"showTitle\":false,\"backgroundColor\":\"#fff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0px\",\"settings\":{\"requestTimeout\":500,\"initialValue\":false,\"getValueMethod\":\"getValue\",\"setValueMethod\":\"setValue\",\"showOnOffLabels\":true,\"title\":\"Switch control\"},\"title\":\"Switch Control\",\"dropShadow\":true,\"enableFullscreen\":false,\"widgetStyle\":{},\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"useDashboardTimewindow\":true,\"showLegend\":false,\"actions\":{},\"decimals\":2}"
}
}
]

4
ui/src/app/widget/lib/rpc/index.js

@ -15,7 +15,9 @@
*/
import tbKnob from './knob.directive';
import tbSwitch from './switch.directive';
export default angular.module('thingsboard.widgets.rpc', [
tbKnob
tbKnob,
tbSwitch
]).name;

6
ui/src/app/widget/lib/rpc/knob.directive.js

@ -63,7 +63,7 @@ function KnobController($element, $scope, $document) {
knobTitleContainer = knob.find('.title-container'),
knobTitle = knob.find('.knob-title'),
knobMinmaxContainer = knob.find('.minmax-container'),
minmaxLanel = knob.find('.minmax-label'),
minmaxLabel = knob.find('.minmax-label'),
textMeasure = knob.find('#text-measure'),
startDeg = -1,
currentDeg = 0,
@ -92,8 +92,6 @@ function KnobController($element, $scope, $document) {
vm.maxValue = angular.isDefined(vm.ctx.settings.maxValue) ? vm.ctx.settings.maxValue : 100;
vm.title = angular.isDefined(vm.ctx.settings.title) ? vm.ctx.settings.title : '';
vm.darkTheme = vm.ctx.settings.theme == 'dark';
var canvasBarData = {
renderTo: canvasBarElement[0],
hideValue: true,
@ -267,7 +265,7 @@ function KnobController($element, $scope, $document) {
setFontSize(knobTitle, vm.title, knobTitleContainer.height(), knobTitleContainer.width());
setFontSize(knobError, vm.error, knobErrorContainer.height(), knobErrorContainer.width());
var minmaxHeight = knobMinmaxContainer.height();
minmaxLanel.css({'fontSize': minmaxHeight+'px', 'lineHeight': minmaxHeight+'px'});
minmaxLabel.css({'fontSize': minmaxHeight+'px', 'lineHeight': minmaxHeight+'px'});
checkValueSize();
}

5
ui/src/app/widget/lib/rpc/knob.scss

@ -14,7 +14,7 @@
* limitations under the License.
*/
$knob-img: url('./knob.svg');
$knob-img: url('./svg/knob.svg');
$bars-margin-pct: percentage(0.033);
$background-margin-pct: percentage(0.05);
@ -33,9 +33,6 @@ $background-color: #e6e7e8;
width:100%;
height:100%;
background: $background-color;
&.dark {
background: #000;
}
.knob {
position: relative;

2
ui/src/app/widget/lib/rpc/knob.tpl.html

@ -16,7 +16,7 @@
-->
<div class="tb-knob" layout="column" ng-class="{'dark': vm.darkTheme}" ng-style="{'pointerEvents': vm.ctx.isEdit ? 'none' : 'all'}">
<div class="tb-knob" layout="column" ng-style="{'pointerEvents': vm.ctx.isEdit ? 'none' : 'all'}">
<div id="knob-container" flex layout="column" layout-align="center center">
<div class="knob">
<div class="value-container" layout="row" layout-align="center center">

0
ui/src/app/widget/lib/rpc/knob.svg → ui/src/app/widget/lib/rpc/svg/knob.svg

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

43
ui/src/app/widget/lib/rpc/svg/thumb-bar-checked.svg

@ -0,0 +1,43 @@
<svg id="svg5466" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="8.4667mm" width="23.616mm" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 83.679981 29.999998" xmlns:dc="http://purl.org/dc/elements/1.1/">
<defs id="defs5468">
<linearGradient id="linearGradient6001-5" y2="-327.83" gradientUnits="userSpaceOnUse" x2="895.4" gradientTransform="translate(-31.905 97.852)" y1="-357.17" x1="895.4">
<stop id="stop5439" stop-color="#bdbdc1" offset="0"/>
<stop id="stop5441" stop-color="#f4f4f4" offset="1"/>
</linearGradient>
<linearGradient id="linearGradient6003-6" y2="-392.51" gradientUnits="userSpaceOnUse" x2="892.44" gradientTransform="matrix(1 0 0 .78494 -34.597 55.388)" y1="-366.35" x1="892.44">
<stop id="stop5486" stop-color="#838383" offset="0"/>
<stop id="stop5492" stop-color="#979797" offset=".53774"/>
<stop id="stop5488" stop-color="#a7a7a7" offset="1"/>
</linearGradient>
<linearGradient id="linearGradient6436" y2="-334.29" xlink:href="#linearGradient5528" gradientUnits="userSpaceOnUse" x2="913.4" gradientTransform="matrix(.78723 0 0 .78723 192.99 -72.172)" y1="-349.49" x1="913.38"/>
<linearGradient id="linearGradient5528">
<stop id="stop5530" stop-color="#3d3d3d" stop-opacity=".86275" offset="0"/>
<stop id="stop5532" stop-color="#fff" stop-opacity="0" offset="1"/>
</linearGradient>
<radialGradient id="radialGradient5502-17-9" xlink:href="#linearGradient5496" gradientUnits="userSpaceOnUse" cy="-341.87" cx="916.16" gradientTransform="matrix(4.5735 -.17574 .13786 3.5876 -3230.9 1043.7)" r="7.5588"/>
<linearGradient id="linearGradient5496">
<stop id="stop5498" stop-color="#fff" stop-opacity="0" offset="0"/>
<stop id="stop5550" stop-color="#fff" stop-opacity=".10435" offset=".17494"/>
<stop id="stop5552" stop-color="#fff" stop-opacity=".92174" offset=".39279"/>
<stop id="stop5500" stop-color="#fff" offset="1"/>
</linearGradient>
</defs>
<g id="layer1" transform="translate(-126.73 -454.51)">
<g id="g6480" transform="translate(-692.33 714.68)">
<g>
<path id="rect5195-5-0-1-9-6" style="color-rendering:auto;text-decoration-color:#000000;color:#000000;isolation:auto;mix-blend-mode:normal;shape-rendering:auto;solid-color:#000000;block-progression:tb;text-decoration-line:none;text-decoration-style:solid;image-rendering:auto;white-space:normal;text-indent:0;text-transform:none" d="m826.67-260.18c-4.201 0.00074-7.606 3.8877-7.6055 8.6819v12.639c0.00065 4.7933 3.4054 8.6788 7.6055 8.6795h68.469c4.2001-0.00073 7.6049-3.8862 7.6055-8.6795v-12.639c0.00053-4.7942-3.4046-8.6812-7.6055-8.6819z" fill="url(#linearGradient6001-5)"/>
<path id="rect5195-5-0-1-4-0-6" style="color-rendering:auto;text-decoration-color:#000000;color:#000000;isolation:auto;mix-blend-mode:normal;shape-rendering:auto;solid-color:#000000;block-progression:tb;text-decoration-line:none;text-decoration-style:solid;image-rendering:auto;white-space:normal;text-indent:0;text-transform:none" d="m826.67-257.4c-4.201 0.00062-7.606 3.2632-7.6055 7.2872v10.608c0.00065 4.0232 3.4054 7.2845 7.6055 7.2851h68.469c4.2001-0.00062 7.6049-3.2619 7.6055-7.2851v-10.608c0.00053-4.024-3.4046-7.2866-7.6055-7.2872z" fill="#585859"/>
<path id="rect5195-5-0-1-4-3-0-8" style="color-rendering:auto;text-decoration-color:#000000;color:#000000;isolation:auto;mix-blend-mode:normal;shape-rendering:auto;solid-color:#000000;block-progression:tb;text-decoration-line:none;text-decoration-style:solid;image-rendering:auto;white-space:normal;text-indent:0;text-transform:none" d="m826.67-253.64c-4.201 0.00052-7.606 2.7592-7.6055 6.1617v8.9697c0.00065 3.4018 3.4054 6.1594 7.6055 6.16h68.469c4.2001-0.00052 7.6049-2.7581 7.6055-6.16v-8.9697c0.00053-3.4025-3.4046-6.1612-7.6055-6.1617z" fill="url(#linearGradient6003-6)"/>
</g>
<g id="g5554-2-1" transform="translate(-29.817 95.669)">
<circle id="path5494-3-7-8" cx="911.68" cy="-340.85" r="6.0124" fill="url(#linearGradient6436)"/>
<circle id="path5494-1-9" cx="911.68" cy="-340.85" r="5.3939" fill="url(#radialGradient5502-17-9)"/>
</g>
<g id="g5554-8-6-2" transform="translate(-71.652 95.669)">
<circle id="path5494-3-9-2-9" cx="911.68" cy="-340.85" r="6.0124" fill="url(#linearGradient6436)"/>
<circle id="path5494-7-0-5" cx="911.68" cy="-340.85" r="5.3939" fill="url(#radialGradient5502-17-9)"/>
</g>
<path id="rect5195-5-0-1-4-0-4-4" style="color-rendering:auto;text-decoration-color:#000000;color:#000000;isolation:auto;mix-blend-mode:normal;shape-rendering:auto;solid-color:#000000;block-progression:tb;text-decoration-line:none;text-decoration-style:solid;image-rendering:auto;white-space:normal;text-indent:0;text-transform:none" d="m826.67-257.4c-4.201 0.00062-7.606 3.2632-7.6055 7.2872v10.608c0.00065 4.0232 3.4054 7.2845 7.6055 7.2851h68.469c4.2001-0.00062 7.6049-3.2619 7.6055-7.2851v-10.608c0.00053-4.024-3.4046-7.2866-7.6055-7.2872z" fill-opacity=".39080" fill="#ff6e4a"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.9 KiB

42
ui/src/app/widget/lib/rpc/svg/thumb-bar.svg

@ -0,0 +1,42 @@
<svg id="svg4749" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="8.4667mm" width="23.616mm" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 83.679981 29.999998" xmlns:dc="http://purl.org/dc/elements/1.1/">
<defs id="defs4751">
<linearGradient id="linearGradient5443" y2="-327.83" gradientUnits="userSpaceOnUse" x2="895.4" y1="-357.17" x1="895.4">
<stop id="stop5439" stop-color="#bdbdc1" offset="0"/>
<stop id="stop5441" stop-color="#f4f4f4" offset="1"/>
</linearGradient>
<linearGradient id="linearGradient5490" y2="-392.51" gradientUnits="userSpaceOnUse" x2="892.44" gradientTransform="matrix(1 0 0 .78494 -2.6922 -42.464)" y1="-366.35" x1="892.44">
<stop id="stop5486" stop-color="#838383" offset="0"/>
<stop id="stop5492" stop-color="#979797" offset=".53774"/>
<stop id="stop5488" stop-color="#a7a7a7" offset="1"/>
</linearGradient>
<linearGradient id="linearGradient5534" y2="-334.29" xlink:href="#linearGradient5528" gradientUnits="userSpaceOnUse" x2="913.4" gradientTransform="matrix(.78723 0 0 .78723 192.99 -72.172)" y1="-349.49" x1="913.38"/>
<linearGradient id="linearGradient5528">
<stop id="stop5530" stop-color="#3d3d3d" stop-opacity=".86275" offset="0"/>
<stop id="stop5532" stop-color="#fff" stop-opacity="0" offset="1"/>
</linearGradient>
<radialGradient id="radialGradient5502" xlink:href="#linearGradient5496" gradientUnits="userSpaceOnUse" cy="-341.87" cx="916.16" gradientTransform="matrix(4.5735 -.17574 .13786 3.5876 -3230.9 1043.7)" r="7.5588"/>
<linearGradient id="linearGradient5496">
<stop id="stop5498" stop-color="#fff" stop-opacity="0" offset="0"/>
<stop id="stop5550" stop-color="#fff" stop-opacity=".10435" offset=".17494"/>
<stop id="stop5552" stop-color="#fff" stop-opacity=".92174" offset=".39279"/>
<stop id="stop5500" stop-color="#fff" offset="1"/>
</linearGradient>
</defs>
<g id="layer1" transform="translate(-312.45 -714.51)">
<g id="g5878" transform="translate(-538.52 1072.5)">
<g>
<path id="rect5195-5-0-1" style="color-rendering:auto;text-decoration-color:#000000;color:#000000;isolation:auto;mix-blend-mode:normal;shape-rendering:auto;solid-color:#000000;block-progression:tb;text-decoration-line:none;text-decoration-style:solid;image-rendering:auto;white-space:normal;text-indent:0;text-transform:none" d="m858.57-358.03c-4.201 0.00074-7.606 3.8877-7.6055 8.6819v12.639c0.00065 4.7933 3.4054 8.6788 7.6055 8.6795h68.469c4.2001-0.00073 7.6049-3.8862 7.6055-8.6795v-12.639c0.00053-4.7942-3.4046-8.6812-7.6055-8.6819z" fill="url(#linearGradient5443)"/>
<path id="rect5195-5-0-1-4" style="color-rendering:auto;text-decoration-color:#000000;color:#000000;isolation:auto;mix-blend-mode:normal;shape-rendering:auto;solid-color:#000000;block-progression:tb;text-decoration-line:none;text-decoration-style:solid;image-rendering:auto;white-space:normal;text-indent:0;text-transform:none" d="m858.57-355.25c-4.201 0.00062-7.606 3.2632-7.6055 7.2872v10.608c0.00065 4.0232 3.4054 7.2845 7.6055 7.2851h68.469c4.2001-0.00062 7.6049-3.2619 7.6055-7.2851v-10.608c0.00053-4.024-3.4046-7.2866-7.6055-7.2872z" fill="#585859"/>
<path id="rect5195-5-0-1-4-3" style="color-rendering:auto;text-decoration-color:#000000;color:#000000;isolation:auto;mix-blend-mode:normal;shape-rendering:auto;solid-color:#000000;block-progression:tb;text-decoration-line:none;text-decoration-style:solid;image-rendering:auto;white-space:normal;text-indent:0;text-transform:none" d="m858.57-351.49c-4.201 0.00052-7.606 2.7592-7.6055 6.1617v8.9697c0.00065 3.4018 3.4054 6.1594 7.6055 6.16h68.469c4.2001-0.00052 7.6049-2.7581 7.6055-6.16v-8.9697c0.00053-3.4025-3.4046-6.1612-7.6055-6.1617z" fill="url(#linearGradient5490)"/>
</g>
<g id="g5554" transform="translate(2.0884 -2.1835)">
<circle id="path5494-3" cx="911.68" cy="-340.85" r="6.0124" fill="url(#linearGradient5534)"/>
<circle id="path5494" cx="911.68" cy="-340.85" r="5.3939" fill="url(#radialGradient5502)"/>
</g>
<g id="g5554-8" transform="translate(-39.746 -2.1835)">
<circle id="path5494-3-9" cx="911.68" cy="-340.85" r="6.0124" fill="url(#linearGradient5534)"/>
<circle id="path5494-7" cx="911.68" cy="-340.85" r="5.3939" fill="url(#radialGradient5502)"/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.3 KiB

40
ui/src/app/widget/lib/rpc/svg/thumb-checked.svg

@ -0,0 +1,40 @@
<svg id="svg7523" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="7.6161mm" width="11.594mm" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 41.08074 26.986356" xmlns:dc="http://purl.org/dc/elements/1.1/">
<defs id="defs7525">
<linearGradient id="linearGradient6257" y2="-412.79" gradientUnits="userSpaceOnUse" x2="821.92" gradientTransform="matrix(1 0 0 1.0219 -4.8132 52.955)" y1="-386.98" x1="822.46">
<stop id="stop5264" stop-color="#3d3d3d" offset="0"/>
<stop id="stop5266" stop-color="#fbfbfb" offset="1"/>
</linearGradient>
<linearGradient id="linearGradient6259" y2="-350.07" gradientUnits="userSpaceOnUse" x2="821.71" gradientTransform="translate(-3.8933 5.8759)" y1="-372.35" x1="821.89">
<stop id="stop5239" stop-color="#d1d1d1" offset="0"/>
<stop id="stop5243" stop-color="#e2e3e2" offset=".36037"/>
<stop id="stop5245" stop-color="#ededed" offset=".67781"/>
<stop id="stop5241" stop-color="#fcfcfc" offset="1"/>
</linearGradient>
<linearGradient id="linearGradient6261" y2="-333.89" gradientUnits="userSpaceOnUse" x2="913.16" gradientTransform="matrix(.78723 0 0 .78723 105.52 -77.537)" y1="-348.85" x1="912.9">
<stop id="stop5650" stop-color="#939393" offset="0"/>
<stop id="stop5652" stop-color="#fff" offset="1"/>
</linearGradient>
<radialGradient id="radialGradient5502-1-0-6" gradientUnits="userSpaceOnUse" cy="-342.2" cx="916.19" gradientTransform="matrix(1.9993 -.036196 .028926 1.5978 -997.39 230.16)" r="7.5588">
<stop id="stop5656" stop-color="#fff" stop-opacity="0" offset="0"/>
<stop id="stop5658" stop-color="#fff" stop-opacity=".18551" offset=".20750"/>
<stop id="stop5660" stop-color="#fff" stop-opacity=".32464" offset=".31814"/>
<stop id="stop5662" stop-color="#fff" offset="1"/>
</radialGradient>
</defs>
<g id="layer1" transform="translate(-259.46 -610.3)">
<g id="g6501" transform="translate(-602.12 869.32)">
<g id="g5664-5" transform="translate(57.91 100.68)">
<g id="g5329-3-4" transform="translate(13.694 -2.3675)">
<path id="rect5195-5-0-8-35" style="color-rendering:auto;text-decoration-color:#000000;color:#000000;isolation:auto;mix-blend-mode:normal;shape-rendering:auto;solid-color:#000000;block-progression:tb;text-decoration-line:none;text-decoration-style:solid;image-rendering:auto;white-space:normal;text-indent:0;text-transform:none" d="m797.58-357.34a7.6067 7.8088 0 0 0 -7.6055 7.8098v11.369a7.6067 7.8088 0 0 0 7.6055 7.8076h25.87a7.6067 7.8088 0 0 0 7.6055 -7.8076v-11.369a7.6067 7.8088 0 0 0 -7.6055 -7.8098h-25.87z" fill="#1b1b1b"/>
<g id="g5300-6-7" transform="translate(-6.6863 11.667)">
<path id="rect5195-5-03-5" style="color-rendering:auto;text-decoration-color:#000000;color:#000000;isolation:auto;mix-blend-mode:normal;shape-rendering:auto;solid-color:#000000;block-progression:tb;text-decoration-line:none;text-decoration-style:solid;image-rendering:auto;white-space:normal;text-indent:0;text-transform:none" d="m804.57-368.63a7.429 7.5918 0 0 0 -7.4279 7.5927v11.053a7.429 7.5918 0 0 0 7.4279 7.5906h25.266a7.429 7.5918 0 0 0 7.4279 -7.5906v-11.053a7.429 7.5918 0 0 0 -7.4279 -7.5927h-25.266z" fill="url(#linearGradient6257)"/>
<path id="rect5195-3-6" style="color-rendering:auto;text-decoration-color:#000000;color:#000000;isolation:auto;mix-blend-mode:normal;shape-rendering:auto;solid-color:#000000;block-progression:tb;text-decoration-line:none;text-decoration-style:solid;image-rendering:auto;white-space:normal;text-indent:0;text-transform:none" d="m805.23-367.67a7.0362 7.0362 0 0 0 -7.0352 7.0371v10.244a7.0362 7.0362 0 0 0 7.0352 7.0352h23.93a7.0362 7.0362 0 0 0 7.0352 -7.0352v-10.244a7.0362 7.0362 0 0 0 -7.0352 -7.0371h-23.93z" fill="url(#linearGradient6259)"/>
</g>
</g>
<circle id="path5494-3-9-7-5" cx="824.21" cy="-346.21" r="6.0124" fill="url(#linearGradient6261)"/>
<circle id="path5494-7-8-95" cx="824.21" cy="-346.21" r="5.3939" fill="url(#radialGradient5502-1-0-6)"/>
</g>
<path id="rect5195-5-0-8-3-8" style="color-rendering:auto;text-decoration-color:#000000;color:#000000;isolation:auto;mix-blend-mode:normal;shape-rendering:auto;solid-color:#000000;block-progression:tb;text-decoration-line:none;text-decoration-style:solid;image-rendering:auto;white-space:normal;text-indent:0;text-transform:none" d="m869.18-259.03a7.6067 7.8088 0 0 0 -7.6055 7.8098v11.369a7.6067 7.8088 0 0 0 7.6055 7.8076h25.87a7.6067 7.8088 0 0 0 7.6055 -7.8076v-11.369a7.6067 7.8088 0 0 0 -7.6055 -7.8098h-25.87z" fill-opacity=".78448" fill="#ff6e40"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.5 KiB

37
ui/src/app/widget/lib/rpc/svg/thumb.svg

@ -0,0 +1,37 @@
<svg id="svg6201" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="7.6161mm" width="11.594mm" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 41.08074 26.986349" xmlns:dc="http://purl.org/dc/elements/1.1/">
<defs id="defs6203">
<linearGradient id="linearGradient5382" y2="-412.79" gradientUnits="userSpaceOnUse" x2="821.92" gradientTransform="matrix(1 0 0 1.0219 -4.8132 52.955)" y1="-386.98" x1="822.46">
<stop id="stop5264" stop-color="#3d3d3d" offset="0"/>
<stop id="stop5266" stop-color="#fbfbfb" offset="1"/>
</linearGradient>
<linearGradient id="linearGradient5384" y2="-350.07" gradientUnits="userSpaceOnUse" x2="821.71" gradientTransform="translate(-3.8933 5.8759)" y1="-372.35" x1="821.89">
<stop id="stop5239" stop-color="#d1d1d1" offset="0"/>
<stop id="stop5243" stop-color="#e2e3e2" offset=".36037"/>
<stop id="stop5245" stop-color="#ededed" offset=".67781"/>
<stop id="stop5241" stop-color="#fcfcfc" offset="1"/>
</linearGradient>
<linearGradient id="linearGradient5644" y2="-333.89" gradientUnits="userSpaceOnUse" x2="913.16" gradientTransform="matrix(.78723 0 0 .78723 105.52 -77.537)" y1="-348.85" x1="912.9">
<stop id="stop5650" stop-color="#939393" offset="0"/>
<stop id="stop5652" stop-color="#fff" offset="1"/>
</linearGradient>
<radialGradient id="radialGradient5502-1-0" gradientUnits="userSpaceOnUse" cy="-342.2" cx="916.19" gradientTransform="matrix(1.9993 -.036196 .028926 1.5978 -997.39 230.16)" r="7.5588">
<stop id="stop5656" stop-color="#fff" stop-opacity="0" offset="0"/>
<stop id="stop5658" stop-color="#fff" stop-opacity=".18551" offset=".20750"/>
<stop id="stop5660" stop-color="#fff" stop-opacity=".32464" offset=".31814"/>
<stop id="stop5662" stop-color="#fff" offset="1"/>
</radialGradient>
</defs>
<g id="layer1" transform="translate(-288.03 -544.58)">
<g id="g5664" transform="translate(-515.63 904.29)">
<g id="g5329-3" transform="translate(13.694 -2.3675)">
<path id="rect5195-5-0-8" style="color-rendering:auto;text-decoration-color:#000000;color:#000000;isolation:auto;mix-blend-mode:normal;shape-rendering:auto;solid-color:#000000;block-progression:tb;text-decoration-line:none;text-decoration-style:solid;image-rendering:auto;white-space:normal;text-indent:0;text-transform:none" d="m797.58-357.34a7.6067 7.8088 0 0 0 -7.6055 7.8098v11.369a7.6067 7.8088 0 0 0 7.6055 7.8076h25.87a7.6067 7.8088 0 0 0 7.6055 -7.8076v-11.369a7.6067 7.8088 0 0 0 -7.6055 -7.8098h-25.87z" fill="#1b1b1b"/>
<g id="g5300-6" transform="translate(-6.6863 11.667)">
<path id="rect5195-5-03" style="color-rendering:auto;text-decoration-color:#000000;color:#000000;isolation:auto;mix-blend-mode:normal;shape-rendering:auto;solid-color:#000000;block-progression:tb;text-decoration-line:none;text-decoration-style:solid;image-rendering:auto;white-space:normal;text-indent:0;text-transform:none" d="m804.57-368.63a7.429 7.5918 0 0 0 -7.4279 7.5927v11.053a7.429 7.5918 0 0 0 7.4279 7.5906h25.266a7.429 7.5918 0 0 0 7.4279 -7.5906v-11.053a7.429 7.5918 0 0 0 -7.4279 -7.5927h-25.266z" fill="url(#linearGradient5382)"/>
<path id="rect5195-3" style="color-rendering:auto;text-decoration-color:#000000;color:#000000;isolation:auto;mix-blend-mode:normal;shape-rendering:auto;solid-color:#000000;block-progression:tb;text-decoration-line:none;text-decoration-style:solid;image-rendering:auto;white-space:normal;text-indent:0;text-transform:none" d="m805.23-367.67a7.0362 7.0362 0 0 0 -7.0352 7.0371v10.244a7.0362 7.0362 0 0 0 7.0352 7.0352h23.93a7.0362 7.0362 0 0 0 7.0352 -7.0352v-10.244a7.0362 7.0362 0 0 0 -7.0352 -7.0371h-23.93z" fill="url(#linearGradient5384)"/>
</g>
</g>
<circle id="path5494-3-9-7" cy="-346.21" cx="824.21" r="6.0124" fill="url(#linearGradient5644)"/>
<circle id="path5494-7-8" cy="-346.21" cx="824.21" r="5.3939" fill="url(#radialGradient5502-1-0)"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.9 KiB

214
ui/src/app/widget/lib/rpc/switch.directive.js

@ -0,0 +1,214 @@
/*
* Copyright © 2016-2017 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import './switch.scss';
/* eslint-disable import/no-unresolved, import/default */
import switchTemplate from './switch.tpl.html';
/* eslint-enable import/no-unresolved, import/default */
export default angular.module('thingsboard.widgets.rpc.switch', [])
.directive('tbSwitch', Switch)
.name;
/*@ngInject*/
function Switch() {
return {
restrict: "E",
scope: true,
bindToController: {
ctx: '='
},
controller: SwitchController,
controllerAs: 'vm',
templateUrl: switchTemplate
};
}
/*@ngInject*/
function SwitchController($element, $scope) {
let vm = this;
vm.showTitle = false;
vm.value = false;
vm.error = '';
var switchElement = angular.element('.switch', $element),
switchContainer = angular.element('#switch-container', $element),
mdSwitch = angular.element('md-switch', switchElement),
onoffContainer = angular.element('.onoff-container', $element),
onLabel = angular.element('.on-label', $element),
offLabel = angular.element('.off-label', $element),
switchTitleContainer = angular.element('.title-container', $element),
switchTitle = angular.element('.switch-title', $element),
textMeasure = angular.element('#text-measure', $element),
switchErrorContainer = angular.element('.error-container', $element),
switchError = angular.element('.switch-error', $element);
vm.onValue = onValue;
$scope.$watch('vm.ctx', () => {
if (vm.ctx) {
init();
}
});
function init() {
vm.title = angular.isDefined(vm.ctx.settings.title) ? vm.ctx.settings.title : '';
vm.showTitle = vm.title && vm.title.length ? true : false;
vm.showOnOffLabels = angular.isDefined(vm.ctx.settings.showOnOffLabels) ? vm.ctx.settings.showOnOffLabels : true;
vm.ctx.resize = resize;
$scope.$applyAsync(() => {
resize();
});
var initialValue = angular.isDefined(vm.ctx.settings.initialValue) ? vm.ctx.settings.initialValue : false;
setValue(initialValue);
var subscription = vm.ctx.defaultSubscription;
var rpcEnabled = subscription.rpcEnabled;
vm.isSimulated = $scope.widgetEditMode;
vm.requestTimeout = 500;
if (vm.ctx.settings.requestTimeout) {
vm.requestTimeout = vm.ctx.settings.requestTimeout;
}
vm.getValueMethod = 'getValue';
if (vm.ctx.settings.getValueMethod && vm.ctx.settings.getValueMethod.length) {
vm.getValueMethod = vm.ctx.settings.getValueMethod;
}
vm.setValueMethod = 'setValue';
if (vm.ctx.settings.setValueMethod && vm.ctx.settings.setValueMethod.length) {
vm.setValueMethod = vm.ctx.settings.setValueMethod;
}
if (!rpcEnabled) {
onError('Target device is not set!');
} else {
if (!vm.isSimulated) {
rpcRequestValue();
}
}
}
const switchAspectRation = 2.7893;
function resize() {
var width = switchContainer.width();
var height;
if (vm.showOnOffLabels) {
height = switchContainer.height()*2/3;
} else {
height = switchContainer.height();
}
var ratio = width/height;
if (ratio > switchAspectRation) {
width = height*switchAspectRation;
} else {
height = width/switchAspectRation;
}
switchElement.css({width: width, height: height});
mdSwitch.css('height', height+'px');
mdSwitch.css('width', width+'px');
mdSwitch.css('min-width', width+'px');
angular.element('.md-container', mdSwitch).css('height', height+'px');
angular.element('.md-container', mdSwitch).css('width', width+'px');
if (vm.showTitle) {
setFontSize(switchTitle, vm.title, switchTitleContainer.height() * 2 / 3, switchTitleContainer.width());
}
if (vm.showOnOffLabels) {
onoffContainer.css({width: width, height: switchContainer.height() / 3});
setFontSize(onLabel, 'OFF', onoffContainer.height(), onoffContainer.width() / 2);
setFontSize(offLabel, 'OFF', onoffContainer.height(), onoffContainer.width() / 2);
}
setFontSize(switchError, vm.error, switchErrorContainer.height(), switchErrorContainer.width());
}
function setValue(value) {
vm.value = value ? true : false;
}
function onValue() {
rpcUpdateValue(vm.value);
}
function onError(error) {
$scope.$applyAsync(() => {
vm.error = error;
setFontSize(switchError, vm.error, switchErrorContainer.height(), switchErrorContainer.width());
});
}
function setFontSize(element, text, fontSize, maxWidth) {
var textWidth = measureTextWidth(text, fontSize);
while (textWidth > maxWidth) {
fontSize--;
textWidth = measureTextWidth(text, fontSize);
}
element.css({'fontSize': fontSize+'px', 'lineHeight': fontSize+'px'});
}
function measureTextWidth(text, fontSize) {
textMeasure.css({'fontSize': fontSize+'px', 'lineHeight': fontSize+'px'});
textMeasure.text(text);
return textMeasure.width();
}
function rpcRequestValue() {
vm.error = '';
vm.ctx.controlApi.sendTwoWayCommand(vm.getValueMethod, null, vm.requestTimeout).then(
(responseBody) => {
setValue(responseBody);
},
() => {
var errorText = vm.ctx.defaultSubscription.rpcErrorText;
onError(errorText);
}
);
}
function rpcUpdateValue(value) {
if (vm.executingUpdateValue) {
vm.scheduledValue = value;
return;
} else {
vm.scheduledValue = null;
vm.rpcValue = value;
vm.executingUpdateValue = true;
}
vm.error = '';
vm.ctx.controlApi.sendOneWayCommand(vm.setValueMethod, value, vm.requestTimeout).then(
() => {
vm.executingUpdateValue = false;
if (vm.scheduledValue != null && vm.scheduledValue != vm.rpcValue) {
rpcUpdateValue(vm.scheduledValue);
}
},
() => {
vm.executingUpdateValue = false;
var errorText = vm.ctx.defaultSubscription.rpcErrorText;
onError(errorText);
}
);
}
}

127
ui/src/app/widget/lib/rpc/switch.scss

@ -0,0 +1,127 @@
/**
* Copyright © 2016-2017 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
$thumb-img: url('./svg/thumb.svg');
$thumb-checked-img: url('./svg/thumb-checked.svg');
$thumb-bar-img: url('./svg/thumb-bar.svg');
$thumb-bar-checked-img: url('./svg/thumb-bar-checked.svg');
$background-color: #e6e7e8;
$error-height: 14px;
.tb-switch {
width:100%;
height:100%;
background: $background-color;
.error-container {
position:absolute;
top: 1%;
left: 0;
right: 0;
z-index:4;
height: $error-height;
.switch-error {
color: #ff3315;
white-space: nowrap;
}
}
.onoff-container {
height: 100%;
color: #757575;
font-weight: 500;
white-space: nowrap;
.off-label {
color: #b7b5b5;
}
.on-label {
color: #ff7e57;
text-shadow: #ff6e4a 1px 1px 10px, #ffd1c3 1px 1px 10px;
}
}
.title-container {
.switch-title {
color: #757575;
font-weight: 500;
white-space: nowrap;
}
}
#switch-container {
padding-left: 10px;
padding-right: 10px;
}
.switch {
position: relative;
md-switch {
margin: 0;
position:absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
.md-container {
margin: 0;
}
.md-bar {
left: 0;
width: 100%;
top: 0;
height: 100%;
border-radius: 0;
background:$thumb-bar-img no-repeat;
background-size: contain;
}
.md-thumb-container {
left: 0.25%;
width: 50%;
top: 5%;
height: 90%;
}
.md-thumb {
top: 0;
left: 0;
height: 100%;
width: 100%;
background:$thumb-img no-repeat;
background-size: contain;
border-radius: 0;
box-shadow: none;
}
&.md-checked {
.md-bar {
background:$thumb-bar-checked-img no-repeat;
background-size: contain;
}
.md-thumb {
background:$thumb-checked-img no-repeat;
background-size: contain;
}
}
}
}
#text-measure {
position: absolute;
visibility: hidden;
height: auto;
width: auto;
white-space: nowrap;
}
}

40
ui/src/app/widget/lib/rpc/switch.tpl.html

@ -0,0 +1,40 @@
<!--
Copyright © 2016-2017 The Thingsboard Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<div class="tb-switch" layout="column" ng-style="{'pointerEvents': vm.ctx.isEdit ? 'none' : 'all'}">
<div class="error-container" ng-style="{'background': vm.error.length ? 'rgba(255,255,255,0.25)' : 'none'}"
layout="row" layout-align="center center">
<span class="switch-error">{{ vm.error }}</span>
</div>
<div flex="30" class="title-container" layout="row" layout-align="center center" ng-show="vm.showTitle">
<span class="switch-title">{{vm.title}}</span>
</div>
<div flex="{{vm.showTitle ? 70 : 100}}" id="switch-container" layout="column" layout-align="center center">
<div class="switch">
<md-switch md-no-ink aria-label="Switch control" ng-model="vm.value" ng-change="vm.onValue()">
</md-switch>
</div>
<div class="onoff-container" layout="row" layout-align="center start" ng-show="vm.showOnOffLabels">
<span flex class="off-label" ng-show="!vm.value" style="text-align: center;">OFF</span>
<span flex ng-show="vm.value"></span>
<span flex class="on-label" ng-show="vm.value" style="text-align: center;">ON</span>
<span flex ng-show="!vm.value"></span>
</div>
</div>
<div id="text-measure"></div>
</div>
Loading…
Cancel
Save