From b89a7ee8b956c96a1dcee995ea840feddc5d4b27 Mon Sep 17 00:00:00 2001 From: Pierre Frisch Date: Thu, 22 Dec 2011 07:25:50 -0800 Subject: First commit of Ninja to ninja-internal Signed-off-by: Valerio Virgillito --- js/components/hottext.reel/hottext.js | 381 ++++++++++++++++++++++++++++++++++ 1 file changed, 381 insertions(+) create mode 100644 js/components/hottext.reel/hottext.js (limited to 'js/components/hottext.reel/hottext.js') diff --git a/js/components/hottext.reel/hottext.js b/js/components/hottext.reel/hottext.js new file mode 100644 index 00000000..0480597a --- /dev/null +++ b/js/components/hottext.reel/hottext.js @@ -0,0 +1,381 @@ +/* +This file contains proprietary software owned by Motorola Mobility, Inc.
+No rights, expressed or implied, whatsoever to this software are provided by Motorola Mobility, Inc. hereunder.
+(c) Copyright 2011 Motorola Mobility, Inc. All Rights Reserved. +
*/ + +var Montage = require("montage/core/core").Montage; +var SliderBase = require("js/components/sliderbase").SliderBase; + +var HotText = exports.HotText = Montage.create(SliderBase, { + /* Allow users to specify a function to format the display. + * For example, the Color Picker can specify a function to map + * the numeric hot text value to hex color values. + */ + labelFunction: { + serializable: true, + enumerable: true, + value: null + }, + + inputFunction: { + serializable: true, + enumerable: true, + value: parseFloat + }, + + _numValue: { + enumerable: false, + value: 0 + }, + + numValue: { + serializable: false, + enumerable: true, + get: function() { + return this._numValue; + }, + set: function(value) { + if (value < this._minValue) { + value = this._minValue; + } + if (value > this._maxValue) { + value = this._maxValue; + } + if (value !== this._numValue) { + this._numValue = Math.round(value * this._decimalPlace)/this._decimalPlace; + } + } + }, + + _previousValue: { + enumerable: false, + value: null + }, + + _stepSize: { + enumerable: false, + value: 1 + }, + + stepSize: { + serializable: true, + enumerable: true, + get: function() { + return this._stepSize; + }, + set: function(value) { + if (value !== this._stepSize) { + this._stepSize = value; + this.needsDraw = true; + } + } + }, + + _stepSizeShift: { + enumerable: false, + value: 10 + }, + + _xStart: { + enumerable: false, + value: 0 + }, + + _yStart: { + enumerable: false, + value: 0 + }, + + // Needed to determine when to commit a value change + _wasShiftKeyPressed: { + enumerable: false, + value: false + }, + + // for ones, use 1 + // for tenths, use 10 + // for hundredths, use 100, etc. + _decimalPlace: { + enumerable: false, + value: 1 + }, + + decimalPlace: { + serializable: true, + enumerable: true, + get: function() { + return this._decimalPlace; + }, + set: function(value) { + if (value !== this._decimalPlace) { + this._decimalPlace = value; + this.needsDraw = true; + } + } + }, + + // TODO - Need to set max value to 2000 for demo. + _maxValue: { + enumerable: false, + value: 2000 + }, + + value: { + serializable: true, + enumerable: true, + get: function() { + return this._value; + }, + set: function(value, fromInput) { + if (isNaN(value)) { + this._valueSyncedWithInputField = false; + this.needsDraw = true; + return; + } + if (value < this._minValue) { + value = this._minValue; + this._valueSyncedWithInputField = false; + this.needsDraw = true; + } + else if (value > this._maxValue) { + value = this._maxValue; + this._valueSyncedWithInputField = false; + this.needsDraw = true; + } + + if (value !== this._value) { + this._value = this._numValue = Math.round(value * this._decimalPlace)/this._decimalPlace; + this._valueSyncedWithInputField = false; + this.needsDraw = true; + this._dispatchActionEvent(); + } + } + }, + + _valueSyncedWithInputField: { + enumerable: false, + value: false + }, + + // We don't want to handle every input; we only want to handle input from tab or enter + // Thus, we don't listen for an input event; we call this from handleKeydown + handleInput: { + enumerable: false, + value: function() { + this._setEventFlags("change", false); + Object.getPropertyDescriptor(this, "value").set.call(this, this.inputFunction(this.element.value), true); + } + }, + + + _valueFromPageOffset: { + value: function(offset, pageY, isShiftKeyPressed, wasSetByCode) { + if(!this._isMouseDown) + { + this._handleMoveEnd(); // If the user has moused up, check if we should go into input mode + return; + } + + var clickPoint = webkitConvertPointFromPageToNode(this.element, new WebKitPoint(offset,pageY)); + + var dX = clickPoint.x - this._xStart; + var dY = clickPoint.y - this._yStart; + + var dXAbs = Math.abs(dX); + var dYAbs = Math.abs(dY); + + if( (dXAbs < 5) && (dYAbs < 5) ) + { + return; // Don't process unless the user moves at least 5 pixels + } + + var incrementVal = dXAbs-4; // otherwise, the first value change will be 5 pixels + var multFactor = 1; + + if(dXAbs > dYAbs) + { + if(dX < 0) + { + multFactor = -1; + } + } + else + { + if(dY > 0) + { + multFactor = -1; + } + incrementVal = dYAbs-4; + } + + if(isShiftKeyPressed) + { + if(!this._wasShiftKeyPressed) + { + this._xStart = clickPoint.x; + this._yStart = clickPoint.y; + this._previousValue = this._numValue; + incrementVal = 1; + } + this.numValue = this._previousValue + multFactor * incrementVal * this._stepSizeShift; + this._wasShiftKeyPressed = true; + } + else + { + if(this._wasShiftKeyPressed) + { + this._xStart = clickPoint.x; + this._yStart = clickPoint.y; + this._previousValue = this._numValue; + incrementVal = 1; + this._wasShiftKeyPressed = false; + } + this.numValue = this._previousValue + multFactor * incrementVal * this._stepSize; + } + + this.value = this._numValue; + } + }, + + handleKeydown: { + enumerable: false, + value: function(event) { + switch(event.keyCode) + { + case 9: //tab + case 13: // enter + this.handleInput(); + break; + case 27: // esc + this._valueSyncedWithInputField = false; + this.needsDraw = true; + break; + case 38: // up + this._setEventFlags("change", false); + this.value += this._stepSize; + break; + case 40: // down + this._setEventFlags("change", false); + this.value -= this._stepSize; + break; + default: +// return; + } + } + }, + + handleBlur: { + enumerable: false, + value: function(event) { + event.target = this; + this._hasFocus = false; + + this.handleInput(); // Check if value has changed when focusing out + this.needsDraw = true; + + this.dispatchEvent(event); + } + }, + + handleFocus: { + enumerable: false, + value: function(event) { + event.target = this; + this._hasFocus = true; + this.dispatchEvent(event); + } + }, + + _handleMoveEnd: { + value: function() { + // If we don't change value (mouse up on ourself), we should go into text edit mode + if(this._numValue === this._previousValue) + { + this._hasFocus = true; + } + else + { + this._hasFocus = false; + this._dispatchActionEvent(); + } + this.needsDraw = true; + } + }, + + draw: { + enumerable: false, + value: function() { + if(this._hasFocus) + { + if(!this._isMouseDown) + { + this.element.classList.remove("hottext"); + this.element.classList.add("hottextInput"); + + // if element targeted; balancing demands of multitouch + // with traditional single focus model + this.element.addEventListener("keydown", this, false); + } + } + else + { + this.element.classList.remove("hottextInput"); + this.element.classList.add("hottext"); + } + + if (!this._valueSyncedWithInputField) + { + if(this.labelFunction) + { + this.element.value = this.labelFunction(this._value); + } + else + { + this.element.value = this._value; + } + } + } + }, + + didDraw: { + enumerable: false, + value: function() { + if(!this._isMouseDown && this._hasFocus) + { + var length = 0; + if(this.labelFunction) + { + length = this.labelFunction(this._value).length; + } + else + { + length = this._value.toString().length; + } + this.element.setSelectionRange(0, length); + } + this._valueSyncedWithInputField = true; + } + }, + + prepareForDraw: { + value: function() { + if(this._value) + { + this._numValue = this._value; + } + + if(this._enabled) + { + this.element.addEventListener("blur", this); + this.element.addEventListener("focus", this); + + // TODO only install low level event listeners for high level + // events others listen to us for + this.element.addEventListener("touchstart", this, false); + this.element.addEventListener("mousedown", this, false); + } + } + } + +}); -- cgit v1.2.3