ELA.Views ?= {} class ELA.Views.AxisHandler extends Backbone.Poised.View className: 'axis-handler' events: 'pan': 'handlePan' 'tap': 'handleTap' 'press': 'showInputField' 'doubletap': 'showInputField' 'pressup': 'focusInputField' 'tap input': 'handleInputTap' hammerjs: recognizers: [ [ Hammer.Pan, direction: Hammer.DIRECTION_ALL, threshold: 1 ], [ Hammer.Tap, threshold: 1 ], [ Hammer.Tap, event: 'doubletap', taps: 2, posThreshold: 20, threshold: 1, ['tap'] ], [ Hammer.Press, threshold: 1 ] ] initialize: (options) -> @displayParams = options.displayParams @position = options.position or 'bottom' @orientation = switch @position when 'bottom' then 'x' when 'left' then 'y' @attribute = options.attribute @precision = ELA.settings[@model.name]?.formFields?[@attribute]?.precision @precision ?= options.precision @precision ?= 2 @maxValue = ELA.settings[@model.name]?.formFields?[@attribute]?.maxValue @maxValue ?= ELA.settings[@model.name]?.formFields?[@attribute]?.range?[1] @maxValue ?= options.maxValue @maxValue ?= options.range?[1] @minValue = ELA.settings[@model.name]?.formFields?[@attribute]?.minValue @minValue ?= ELA.settings[@model.name]?.formFields?[@attribute]?.range?[0] @minValue ?= options.minValue @minValue ?= options.range?[1] @listenTo(@model, "change:#{@attribute}", @renderSpan) @subviews = {} @formSettings = @model.loadSettings("formFields")[@attribute] @params = new Backbone.Model showInput: false @listenTo(@params, 'change:showInput', @renderSpan) @lastFocusOutAt = undefined handleTap: (e) => @updateValue(e) unless @hasRecentlyOpenInput() handlePan: (e) => @updateValue(e) unless @params.get('showInput') handleInputTap: (e) => e.stopPropagation() updateValue: (e) => origin = @displayParams.get("#{@orientation}Origin") range = @displayParams.get("#{@orientation}Range") graphOffset = @parentView.subviews.graph.$el.offset() if @orientation is 'x' width = @displayParams.get('width') point = (range / width) * (e.gesture.center.x - graphOffset.left - origin) else # @orientation is 'y' height = @displayParams.get('height') y = e.gesture.center.y - graphOffset.top y = Math.min(Math.max(y, 0), height) point = (range / height) * (origin - y) pow = Math.pow(10, @precision) point = Math.round(point * pow) / pow point = Math.max(point, @minValue) if isFinite(@minValue) point = Math.min(point, @maxValue) if isFinite(@maxValue) @model.set(@attribute, point) showInputField: -> @params.set(showInput: true) focusInputField: => _.defer => @subviews.inputControl?.$('input').focus() closeInputField: => @params.set(showInput: false) hasRecentlyOpenInput: -> # not (new Date - @lastFocusOutAt < 100) and (new Date - @lastFocusOutAt > 100) # are not equal when @lastFocusOutAt is undefined! @params.get('showInput') or (new Date - @lastFocusOutAt < 100) handleFocusOut: => @lastFocusOutAt = new Date @closeInputField() text: (value) => t( "#{@model.name}.axisHandler.#{@attribute}.label" "#{@model.name}.axisHandler.label" 'axisHandler.label' value: "" ) renderSpan: => if @params.get('showInput') @$label.addClass('has-input') control = new Backbone.Poised.Textfield( _.defaults( model: @model attribute: @attribute type: 'number' , @formSettings ) ) @subviews.inputControl = control @listenToOnce(control, 'changeValue', @handleFocusOut) @$label.find('span').html(control.render().el) else @$label.removeClass('has-input') @$label.find('span').text( @model.get(@attribute).toFixed(@precision) + ' ' + @formSettings.unit ) render: => delete @subviews.inputField @$label = $('