/* Slide.js
*
* copyright (c) 2010-2017, Christian Mayer and the CometVisu contributers.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 3 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
/**
* TODO: complete docs
*
* @module structure/pure/Slide
* @requires structure/pure
* @author Christian Mayer
* @since 2012
*/
define( ['_common'], function( design ) {
"use strict";
var
basicdesign = design.basicdesign,
$main = $('#main');
/**
* Description
* @method transformSlider
* @param {} value
* @param {} handle
*/
function transformSlider( value, handle )
{
if (!$main.data('disableSliderTransform')) {
if (!isNaN(value)) {
value = parseFloat(value); // force any (string) value to float
var sliderMax = $(handle).parent().slider("option","max")+($(handle).parent().slider("option","min")*-1);
var percent = Math.round((100/sliderMax)*(value+($(handle).parent().slider("option","min")*-1)));
//console.log("Value: "+value+", Max/Min: "+sliderMax+", %: "+percent+" => "+percent);
$(handle).css('transform', 'translateX(-'+percent+'%)');
}
}
}
design.basicdesign.addCreator('slide', {
/**
* Description
* @method create
* @param {} element
* @param {} path
* @param {} flavour
* @param {} type
* @return BinaryExpression
*/
create: function( element, path, flavour, type ) {
var $e = $(element);
// create the main structure
var ret_val = basicdesign.createDefaultWidget( 'slide', $e, path, flavour, type, this.update );
// and fill in widget specific data
var datatype_min = undefined;
var datatype_max = undefined;
$e.find('address').each( function(){
var transform = this.getAttribute('transform');
if( Transform[ transform ] && Transform[ transform ].range )
{
if( !( datatype_min > Transform[ transform ].range.min ) )
datatype_min = Transform[ transform ].range.min;
if( !( datatype_max < Transform[ transform ].range.max ) )
datatype_max = Transform[ transform ].range.max;
}
});
var min = parseFloat( $e.attr('min') || datatype_min || 0 );
var max = parseFloat( $e.attr('max') || datatype_max || 100 );
var step = parseFloat( $e.attr('step') || 0.5 );
var send_on_finish = $e.attr('send_on_finish') || 'false';
templateEngine.widgetDataInsert( path, {
//???///'events': $(actor).data( 'events' ),
'min' : min,
'max' : max,
'step' : step,
'send_on_finish' : send_on_finish,
'valueInternal' : true,
'inAction' : false
});
this.construct(path);
return ret_val + '<div class="actor"/></div>';
},
construct: function(path) {
var data = templateEngine.widgetDataGet(path);
// check provided address-items for at least one address which has write-access
var readonly = true;
for (var addrIdx in data.address) {
if (data.address[addrIdx][1] & 2) {
// write-access detected --> no read-only mode
readonly = false;
break;
}
}
// create the actor
templateEngine.messageBroker.subscribe("setup.dom.finished", function() {
var $actor = $( '#' + path + ' .actor' );
$actor.slider({
step: data.step,
min: data.min,
max: data.max,
range: 'min',
animate: true,
send_on_finish : data.send_on_finish,
start: this.slideStart,
change: this.slideChange
});
// disable slider interaction if in read-only mode --> just show the value
if (readonly) {
$actor.slider({ disabled: true });
}
$actor.on( 'slide', this.slideUpdateValue );
if( data['format']) {
// initially setting a value
$actor.children('.ui-slider-handle').text(sprintf(data['format'],templateEngine.map( undefined, data['mapping'] )));
}
}, this);
},
/**
* Description
* @method update
* @param {} ga
* @param {} d
*/
update: function( ga, d ) {
var element = $(this),
actor = element.find('.actor'),
data = templateEngine.widgetDataGetByElement( this );
if( data.inAction )
return;
var value = templateEngine.transformDecode( data.address[ ga ][0], d );
if( data.value != value )
{
data.value = value;
data.valueInternal = false;
actor.slider('value', value);
data.valueInternal = true;
if( data.format != null )
actor.children('.ui-slider-handle').text(sprintf( data.format, templateEngine.map( value, data.mapping )));
}
transformSlider(value,actor.children('.ui-slider-handle'));
},
/**
* Description
* @method slideUpdateValue
* @param {} event
* @param {} ui
*/
slideUpdateValue:function(event,ui) {
var element = $(this).parent(),
actor = element.find('.actor'),
data = templateEngine.widgetDataGetByElement( this );
if( data.format) {
$(ui.handle).text(sprintf( data.format, templateEngine.map( ui.value, data.mapping )));
}
transformSlider(ui.value,ui.handle);
},
/**
* Start a thread that regularily sends the silder position to the bus
* @method slideStart
* @param {} event
* @param {} ui
*/
slideStart:function(event,ui)
{
var element = $(this).parent(),
actor = element.find('.actor'),
data = templateEngine.widgetDataGetByElement( this );
if ( data.send_on_finish == 'true') return;
data.inAction = true;
data.valueInternal = true;
data.updateFn = setInterval( function(){
var asv = actor.slider('value');
if( data.value == asv ) return;
for( var addr in data.address )
{
if( !(data.address[addr][1] & 2) ) continue; // skip when write flag not set
var dv = templateEngine.transformEncode( data.address[addr][0], asv );
if( dv != templateEngine.transformEncode( data.address[addr][0], data.value ) )
templateEngine.visu.write( addr, dv );
}
data.value = asv;
}, 250 ); // update KNX every 250 ms
},
/**
* Delete the update thread and send the final value of the slider to the bus
* @method slideChange
* @param {} event
* @param {} ui
*/
slideChange:function(event,ui)
{
var data = templateEngine.widgetDataGetByElement( this );
clearInterval( data.updateFn, ui.value);
data.inAction = false;
if( data.valueInternal && data.value != ui.value )
{
for( var addr in data.address )
{
if( !(data.address[addr][1] & 2) ) continue; // skip when write flag not set
var uv = templateEngine.transformEncode( data.address[addr][0], ui.value );
if( uv != templateEngine.transformEncode( data.address[addr][0], data.value ) )
templateEngine.visu.write( addr, uv );
}
}
transformSlider(ui.value,ui.handle);
}
});
}); // end define