Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Volodymyr Babak 2017-07-26 16:17:10 +03:00
commit d1f9f25f29
8 changed files with 779 additions and 1 deletions

View File

@ -68,6 +68,38 @@
"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}"
}
},
{
"alias": "round_switch",
"name": "Round switch",
"descriptor": {
"type": "rpc",
"sizeX": 2.5,
"sizeY": 2,
"resources": [],
"templateHtml": "<tb-round-switch ctx='ctx'></tb-round-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 \"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 \"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\":\"Round switch\"},\"title\":\"Round switch\",\"dropShadow\":true,\"enableFullscreen\":false,\"widgetStyle\":{},\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"useDashboardTimewindow\":true,\"showLegend\":false,\"actions\":{},\"decimals\":2}"
}
},
{
"alias": "led_indicator",
"name": "Led indicator",
"descriptor": {
"type": "rpc",
"sizeX": 2.5,
"sizeY": 2.5,
"resources": [],
"templateHtml": "<tb-led-indicator ctx='ctx'></tb-led-indicator>",
"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\": \"LED title\",\n \"type\": \"string\",\n \"default\": \"\"\n },\n \"ledColor\": {\n \"title\": \"LED Color\",\n \"type\": \"string\",\n \"default\": \"green\"\n },\n \"getValueMethod\": {\n \"title\": \"Get value method\",\n \"type\": \"string\",\n \"default\": \"getValue\"\n },\n \"valuePollingInterval\": {\n \"title\": \"Value polling interval (ms)\",\n \"type\": \"number\",\n \"default\": 500\n },\n \"requestTimeout\": {\n \"title\": \"RPC request timeout (ms)\",\n \"type\": \"number\",\n \"default\": 500\n }\n },\n \"required\": [\"getValueMethod\", \"requestTimeout\"]\n },\n \"form\": [\n \"initialValue\",\n \"title\",\n {\n \"key\": \"ledColor\",\n \"type\": \"color\"\n },\n \"getValueMethod\",\n \"valuePollingInterval\",\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\":true,\"getValueMethod\":\"getValue\",\"title\":\"Led indicator\",\"ledColor\":\"#4caf50\",\"valuePollingInterval\":500},\"title\":\"Led indicator\",\"dropShadow\":true,\"enableFullscreen\":false,\"widgetStyle\":{},\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"useDashboardTimewindow\":true,\"showLegend\":false,\"actions\":{},\"decimals\":2}"
}
}
]
}

View File

@ -16,8 +16,12 @@
import tbKnob from './knob.directive';
import tbSwitch from './switch.directive';
import tbRoundSwitch from './round-switch.directive';
import tbLedIndicator from './led-indicator.directive';
export default angular.module('thingsboard.widgets.rpc', [
tbKnob,
tbSwitch
tbSwitch,
tbRoundSwitch,
tbLedIndicator
]).name;

View File

@ -0,0 +1,201 @@
/*
* 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 './led-indicator.scss';
import tinycolor from 'tinycolor2';
/* eslint-disable import/no-unresolved, import/default */
import ledIndicatorTemplate from './led-indicator.tpl.html';
/* eslint-enable import/no-unresolved, import/default */
export default angular.module('thingsboard.widgets.rpc.ledIndicator', [])
.directive('tbLedIndicator', LedIndicator)
.name;
/*@ngInject*/
function LedIndicator() {
return {
restrict: "E",
scope: true,
bindToController: {
ctx: '='
},
controller: LedIndicatorController,
controllerAs: 'vm',
templateUrl: ledIndicatorTemplate
};
}
/*@ngInject*/
function LedIndicatorController($element, $scope, $timeout) {
let vm = this;
vm.showTitle = false;
vm.value = false;
vm.error = '';
var led = angular.element('.led', $element),
ledContainer = angular.element('#led-container', $element),
textMeasure = angular.element('#text-measure', $element),
ledTitleContainer = angular.element('.title-container', $element),
ledTitle = angular.element('.led-title', $element),
ledErrorContainer = angular.element('.error-container', $element),
ledError = angular.element('.led-error', $element);
$scope.$watch('vm.ctx', () => {
if (vm.ctx) {
init();
}
});
$scope.$on('$destroy', () => {
vm.destroyed = true;
if (vm.requestValueTimeoutHandle) {
$timeout.cancel(vm.requestValueTimeoutHandle);
}
});
resize();
function init() {
vm.title = angular.isDefined(vm.ctx.settings.title) ? vm.ctx.settings.title : '';
vm.showTitle = vm.title && vm.title.length ? true : false;
var origColor = angular.isDefined(vm.ctx.settings.ledColor) ? vm.ctx.settings.ledColor : 'green';
vm.ledColor = tinycolor(origColor).brighten(30).toHexString();
vm.ledMiddleColor = tinycolor(origColor).toHexString();
vm.disabledColor = tinycolor(origColor).darken(40).toHexString();
vm.disabledMiddleColor = tinycolor(origColor).darken(60).toHexString();
vm.ctx.resize = resize;
$scope.$applyAsync(() => {
resize();
});
var initialValue = angular.isDefined(vm.ctx.settings.initialValue) ? vm.ctx.settings.initialValue : false;
setValue(initialValue, true);
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.valuePollingInterval = 500;
if (vm.ctx.settings.valuePollingInterval) {
vm.valuePollingInterval = vm.ctx.settings.valuePollingInterval;
}
vm.getValueMethod = 'getValue';
if (vm.ctx.settings.getValueMethod && vm.ctx.settings.getValueMethod.length) {
vm.getValueMethod = vm.ctx.settings.getValueMethod;
}
if (!rpcEnabled) {
onError('Target device is not set!');
} else {
if (!vm.isSimulated) {
rpcRequestValue();
}
}
}
function resize() {
var width = ledContainer.width();
var height = ledContainer.height();
var size = Math.min(width, height);
led.css({width: size, height: size});
if (vm.showTitle) {
setFontSize(ledTitle, vm.title, ledTitleContainer.height() * 2 / 3, ledTitleContainer.width());
}
setFontSize(ledError, vm.error, ledErrorContainer.height(), ledErrorContainer.width());
}
function setValue(value, forceUpdate) {
if (vm.value != value || forceUpdate) {
vm.value = value;
updateColor();
}
}
function updateColor() {
var color = vm.value ? vm.ledColor : vm.disabledColor;
var middleColor = vm.value ? vm.ledMiddleColor : vm.disabledMiddleColor;
var boxShadow = `#000 0 -1px 6px 1px, inset ${middleColor} 0 -1px 8px, ${color} 0 3px 11px`;
led.css({'backgroundColor': color});
led.css({'boxShadow': boxShadow});
if (vm.value) {
led.removeClass( 'disabled' );
} else {
led.addClass( 'disabled' );
}
}
function onError(error) {
$scope.$applyAsync(() => {
vm.error = error;
setFontSize(ledError, vm.error, ledErrorContainer.height(), ledErrorContainer.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() {
if (vm.destroyed) {
return;
}
vm.error = '';
vm.ctx.controlApi.sendTwoWayCommand(vm.getValueMethod, null, vm.requestTimeout).then(
(responseBody) => {
var newValue = responseBody ? true : false;
setValue(newValue);
if (vm.requestValueTimeoutHandle) {
$timeout.cancel(vm.requestValueTimeoutHandle);
}
vm.requestValueTimeoutHandle = $timeout(rpcRequestValue, vm.valuePollingInterval);
},
() => {
var errorText = vm.ctx.defaultSubscription.rpcErrorText;
onError(errorText);
if (vm.requestValueTimeoutHandle) {
$timeout.cancel(vm.requestValueTimeoutHandle);
}
vm.requestValueTimeoutHandle = $timeout(rpcRequestValue, vm.valuePollingInterval);
}
);
}
}

View File

@ -0,0 +1,78 @@
/**
* 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 "~compass-sass-mixins/lib/compass";
$error-height: 14px;
$background-color: #e6e7e8;
.tb-led-indicator {
width:100%;
height:100%;
background: $background-color;
.title-container {
.led-title {
color: #757575;
font-weight: 500;
white-space: nowrap;
}
}
.error-container {
position:absolute;
top: 1%;
left: 0;
right: 0;
z-index:4;
height: $error-height;
.led-error {
color: #ff3315;
white-space: nowrap;
}
}
#text-measure {
position: absolute;
visibility: hidden;
height: auto;
width: auto;
white-space: nowrap;
}
#led-container {
padding: 10px;
.led {
cursor: pointer;
position: relative;
border-radius: 50%;
background-image: -owg-radial-gradient(50% 50%, circle closest-corner, transparent, rgba(0, 0, 0, 0.25));
background-image: -webkit-radial-gradient(50% 50%, circle closest-corner, transparent, rgba(0, 0, 0, 0.25));
background-image: -moz-radial-gradient(50% 50%, circle closest-corner, transparent, rgba(0, 0, 0, 0.25));
background-image: -o-radial-gradient(50% 50%, circle closest-corner, transparent, rgba(0, 0, 0, 0.25));
background-image: radial-gradient(50% 50%, circle closest-corner, transparent, rgba(0, 0, 0, 0.25));
transition: background-color 0.5s, box-shadow 0.5s;
&.disabled {
background-image: -owg-radial-gradient(50% 50%, circle closest-corner, rgba(255, 255, 255, 0.5), rgba(0, 0, 0, 0.1));
background-image: -webkit-radial-gradient(50% 50%, circle closest-corner, rgba(255, 255, 255, 0.5), rgba(0, 0, 0, 0.1));
background-image: -moz-radial-gradient(50% 50%, circle closest-corner, rgba(255, 255, 255, 0.5), rgba(0, 0, 0, 0.1));
background-image: -o-radial-gradient(50% 50%, circle closest-corner, rgba(255, 255, 255, 0.5), rgba(0, 0, 0, 0.1));
background-image: radial-gradient(50% 50%, circle closest-corner, rgba(255, 255, 255, 0.5), rgba(0, 0, 0, 0.1));
}
}
}
}

View File

@ -0,0 +1,32 @@
<!--
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-led-indicator" layout="column">
<div flex="20" class="title-container" layout="row" layout-align="center center" ng-show="vm.showTitle">
<span class="led-title">{{vm.title}}</span>
</div>
<div flex="{{vm.showTitle ? 80 : 100}}"
ng-style="{paddingTop: vm.showTitle ? '5px': '10px'}" id="led-container" layout="column" layout-align="center center">
<div class="led">
</div>
</div>
<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="led-error">{{ vm.error }}</span>
</div>
<div id="text-measure"></div>
</div>

View File

@ -0,0 +1,198 @@
/*
* 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 './round-switch.scss';
/* eslint-disable import/no-unresolved, import/default */
import roundSwitchTemplate from './round-switch.tpl.html';
/* eslint-enable import/no-unresolved, import/default */
export default angular.module('thingsboard.widgets.rpc.roundSwitch', [])
.directive('tbRoundSwitch', RoundSwitch)
.name;
/*@ngInject*/
function RoundSwitch() {
return {
restrict: "E",
scope: true,
bindToController: {
ctx: '='
},
controller: RoundSwitchController,
controllerAs: 'vm',
templateUrl: roundSwitchTemplate
};
}
/*@ngInject*/
function RoundSwitchController($element, $scope, utils) {
let vm = this;
vm.showTitle = false;
vm.value = false;
vm.error = '';
vm.checkboxId = 'onoff-' + utils.guid();
var switchElement = angular.element('.switch', $element),
switchContainer = angular.element('#switch-container', $element),
onoff = angular.element('input', $element),
textMeasure = angular.element('#text-measure', $element),
switchTitleContainer = angular.element('.title-container', $element),
switchTitle = angular.element('.switch-title', $element),
switchErrorContainer = angular.element('.error-container', $element),
switchError = angular.element('.switch-error', $element);
onoff.bind('change', () => {
vm.value = onoff.prop('checked') === false;
onValue();
});
$scope.$watch('vm.ctx', () => {
if (vm.ctx) {
init();
}
});
resize();
function init() {
vm.title = angular.isDefined(vm.ctx.settings.title) ? vm.ctx.settings.title : '';
vm.showTitle = vm.title && vm.title.length ? true : false;
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();
}
}
}
function resize() {
var width = switchContainer.width();
var height = switchContainer.height();
var size = Math.min(width, height);
var scale = size/260;
switchElement.css({
'-webkit-transform': `scale(${scale})`,
'-moz-transform': `scale(${scale})`,
'-ms-transform': `scale(${scale})`,
'-o-transform': `scale(${scale})`,
transform: `scale(${scale})`
});
if (vm.showTitle) {
setFontSize(switchTitle, vm.title, switchTitleContainer.height() * 2 / 3, switchTitleContainer.width());
}
setFontSize(switchError, vm.error, switchErrorContainer.height(), switchErrorContainer.width());
}
function setValue(value) {
vm.value = value ? true : false;
onoff.prop('checked', !vm.value);
}
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);
}
);
}
}

View File

@ -0,0 +1,195 @@
/**
* 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 "~compass-sass-mixins/lib/compass";
$error-height: 14px;
$background-color: #e6e7e8;
.tb-round-switch {
width:100%;
height:100%;
background: $background-color;
.title-container {
.switch-title {
color: #757575;
font-weight: 500;
white-space: nowrap;
}
}
.error-container {
position:absolute;
top: 1%;
left: 0;
right: 0;
z-index:4;
height: $error-height;
.switch-error {
color: #ff3315;
white-space: nowrap;
}
}
#text-measure {
position: absolute;
visibility: hidden;
height: auto;
width: auto;
white-space: nowrap;
}
#switch-container {
padding: 10px;
.switch {
cursor: pointer;
position: relative;
background:#ddd;
background: -owg-linear-gradient(270deg, #bbb, #ddd);
background: -webkit-linear-gradient(270deg, #bbb, #ddd);
background: -moz-linear-gradient(270deg, #bbb, #ddd);
background: -o-linear-gradient(270deg, #bbb, #ddd);
-pie-background: -pie-linear-gradient(270deg, #bbb, #ddd);
background: linear-gradient(180deg, #bbb, #ddd);
border-radius:130px;
@include box-sizing(border-box);
@include box-shadow(
0px 0px 0px 8px rgba(0,0,0,.1)
,0px 0px 3px 1px rgba(0,0,0,.1)
,inset 0 8px 3px -8px rgba(255,255,255,.4));
height: 260px;
min-height: 260px;
padding: 25px;
width: 260px;
min-width: 260px;
color: #424242;
font-family:sans-serif;
font-size:48px;
input {
display:none
}
.on,.off {
position:absolute;
text-align:center;
@include text-shadow(1px 1px 4px #4a4a4a);
width:100%;
}
.on {
color:#444;
top:10px;
@include transition(all 0.1s);
font-family:sans-serif
}
.off {
bottom:5px;
@include transition(all 0.1s);
@include transform(scaleY(0.85));
}
.but {
cursor: pointer;
background-color:#d8d8d8;
border-radius: 400px 400px 400px 400px / 400px 400px 300px 300px;
border-bottom-width:0px;
@include box-shadow(inset 8px 6px 5px -7px #a2a2a2,
inset -8px 6px 5px -7px #a2a2a2,
inset 0 -3px 2px -2px rgba(200, 200, 200, 0.5),
0 3px 3px -2px #ffffff,
inset 0 -230px 60px -200px rgba(255, 255, 255, 0.2),
inset 0 220px 40px -200px rgba(0, 0, 0, 0.3));
display:block;
font-size:48px;
height:178px;
position:relative;
@include transition(all 0.2s);
width:200px;
}
.back {
cursor: pointer;
background-color: #888787;
background-image: -owg-linear-gradient(0deg, transparent 30%, transparent 70%), -owg-linear-gradient(90deg, rgba(150, 150, 150, 0) 30%, rgba(150, 150, 150, 0.2) 50%, rgba(150, 150, 150, 0) 70%);
background-image: -webkit-linear-gradient(0deg, transparent 30%, transparent 70%), -webkit-linear-gradient(90deg, rgba(150, 150, 150, 0) 30%, rgba(150, 150, 150, 0.2) 50%, rgba(150, 150, 150, 0) 70%);
background-image: -moz-linear-gradient(0deg, transparent 30%, transparent 70%), -moz-linear-gradient(90deg, rgba(150, 150, 150, 0) 30%, rgba(150, 150, 150, 0.2) 50%, rgba(150, 150, 150, 0) 70%);
background-image: -o-linear-gradient(0deg, transparent 30%, transparent 70%), -o-linear-gradient(90deg, rgba(150, 150, 150, 0) 30%, rgba(150, 150, 150, 0.2) 50%, rgba(150, 150, 150, 0) 70%);
background-image: linear-gradient(-90deg, transparent 30%, transparent 70%), linear-gradient(0deg, rgba(150, 150, 150, 0) 30%, rgba(150, 150, 150, 0.2) 50%, rgba(150, 150, 150, 0) 70%);
border-radius:105px;
@include box-shadow(30px 30px 30px -20px rgba(58, 58, 58, 0.3),
-30px 30px 30px -20px rgba(58, 58, 58, 0.3),
0 30px 30px 0px rgba(16, 16, 16, 0.3),
inset 0 -1px 0 0 #484848);
@include box-sizing(border-box);
height:210px;
padding:4px 4px;
@include transition(all 0.2s);
width:210px;
}
input:checked + .back .on,input:checked + .back .off{
@include text-shadow(1px 1px 4px #4a4a4a);
}
input:checked + .back .on{
color:#4c4c4c;
top:10px;
@include transform(scaleY(0.85));
}
input:checked + .back .off{
color:#444;
bottom:5px;
@include transform(scaleY(1));
}
input:checked + .back .but{
background:#dcdcdc;
background-image: -owg-radial-gradient(50% 15%, circle closest-corner, rgba(0, 0, 0, 0.3), transparent);
background-image: -webkit-radial-gradient(50% 15%, circle closest-corner, rgba(0, 0, 0, 0.3), transparent);
background-image: -moz-radial-gradient(50% 15%, circle closest-corner, rgba(0, 0, 0, 0.3), transparent);
background-image: -o-radial-gradient(50% 15%, circle closest-corner, rgba(0, 0, 0, 0.3), transparent);
background-image: radial-gradient(50% 15%, circle closest-corner, rgba(0, 0, 0, 0.3), transparent);
border-radius: 400px 400px 400px 400px / 300px 300px 400px 400px;
@include box-shadow(inset 8px -4px 5px -7px #a9a9a9,
inset -8px -4px 5px -7px #808080,
0 -3px 8px -4px rgba(50, 50, 50, 0.4),
inset 0 3px 4px -2px #9c9c9c,
inset 0 280px 40px -200px rgba(0, 0, 0, 0.2),
inset 0 -200px 40px -200px rgba(180, 180, 180, 0.2));
margin-top:20px;
}
input:checked + .back{
background-image: -owg-linear-gradient(90deg, #868686 30%, transparent 70%), -owg-linear-gradient(180deg, rgba(115, 115, 115, 0) 0%, rgba(255, 255, 255, 0.74) 50%, rgba(105, 105, 105, 0) 100%);
background-image: -webkit-linear-gradient(90deg, #868686 30%, transparent 70%), -webkit-linear-gradient(180deg, rgba(115, 115, 115, 0) 0%, rgba(255, 255, 255, 0.74) 50%, rgba(105, 105, 105, 0) 100%);
background-image: -moz-linear-gradient(90deg, #868686 30%, transparent 70%), -moz-linear-gradient(180deg, rgba(115, 115, 115, 0) 0%, rgba(255, 255, 255, 0.74) 50%, rgba(105, 105, 105, 0) 100%);
background-image: -o-linear-gradient(90deg, #868686 30%, transparent 70%), -o-linear-gradient(180deg, rgba(115, 115, 115, 0) 0%, rgba(255, 255, 255, 0.74) 50%, rgba(105, 105, 105, 0) 100%);
background-image: linear-gradient(0deg, #868686 30%, transparent 70%), linear-gradient(90deg, rgba(115, 115, 115, 0) 0%, rgba(255, 255, 255, 0.74) 50%, rgba(105, 105, 105, 0) 100%);
@include box-shadow(30px 30px 30px -20px rgba(49, 49, 49, 0.1),
-30px 30px 30px -20px rgba(111, 111, 111, 0.1),
0 30px 30px 0px rgba(0, 0, 0, 0.2),
inset 0 1px 2px 0 rgba(167, 167, 167, 0.6));
padding:2px 4px;
}
}
}
}

View File

@ -0,0 +1,38 @@
<!--
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-round-switch" layout="column" ng-style="{'pointerEvents': vm.ctx.isEdit ? 'none' : 'all'}">
<div flex="20" 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 ? 80 : 100}}" ng-style="{paddingTop: vm.showTitle ? '5px': '10px'}" id="switch-container" layout="column" layout-align="center center">
<div class="switch">
<input type="checkbox" id="{{vm.checkboxId}}" name="onoff" />
<div class="back">
<label class="but" for="{{vm.checkboxId}}">
<span class="on">I</span>
<span class="off">0</span>
</label>
</div>
</div>
</div>
<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 id="text-measure"></div>
</div>