From b081cd92c1d4fd4611996749e967ea1e8a4d1003 Mon Sep 17 00:00:00 2001 From: Gprasad Date: Fri, 12 Jul 2013 19:37:04 +0530 Subject: [PATCH] Mobile Touch Widgets --- src/aria/touch/widgets/Button.js | 131 ++++++++++++++++ src/aria/touch/widgets/ButtonCSS.tpl.css | 82 ++++++++++ src/aria/touch/widgets/ButtonCfg.js | 54 +++++++ src/aria/touch/widgets/Slider.js | 162 ++++++++++++++++++-- src/aria/touch/widgets/SliderCSS.tpl.css | 21 +++ src/aria/touch/widgets/SliderCfgBeans.js | 10 ++ src/aria/touch/widgets/TouchWidgetLib.js | 3 +- src/aria/utils/Mouse.js | 18 +++ test/aria/touch/TouchTestSuite.js | 4 + test/aria/touch/widgets/ButtonTouch.js | 80 ++++++++++ test/aria/touch/widgets/SingleSliderTpl.tpl | 2 +- test/aria/touch/widgets/SliderHelper.js | 6 + test/aria/touch/widgets/SliderSwitch.js | 87 +++++++++++ test/aria/touch/widgets/SliderSwitchDrag.js | 76 +++++++++ 14 files changed, 725 insertions(+), 11 deletions(-) create mode 100644 src/aria/touch/widgets/Button.js create mode 100644 src/aria/touch/widgets/ButtonCSS.tpl.css create mode 100644 src/aria/touch/widgets/ButtonCfg.js create mode 100644 test/aria/touch/widgets/ButtonTouch.js create mode 100644 test/aria/touch/widgets/SliderSwitch.js create mode 100644 test/aria/touch/widgets/SliderSwitchDrag.js diff --git a/src/aria/touch/widgets/Button.js b/src/aria/touch/widgets/Button.js new file mode 100644 index 000000000..62d4fa502 --- /dev/null +++ b/src/aria/touch/widgets/Button.js @@ -0,0 +1,131 @@ +/* + * Copyright 2012 Amadeus s.a.s. + * 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. + */ + +Aria.classDefinition({ + $classpath : "aria.touch.widgets.Button", + $extends : "aria.html.Element", + $dependencies : ["aria.touch.widgets.ButtonCfg", "aria.touch.Tap", "aria.utils.ClassList"], + $css : ["aria.touch.widgets.ButtonCSS"], + $statics : { + INVALID_USAGE : "Widget %1 can only be used as a %2.", + BUTTON_CLASS : "appButton", + LINK_CLASS : "appLink" + }, + $constructor : function (cfg, context, line) { + /** + * Ref to hold the cancel id of the timer delay + * @type String + * @protected + */ + this._timerId = null; + + cfg.tagName = cfg.tagName || "div"; + + cfg.on = cfg.on || {}; + /** + * delay for highlighting the state change in milliseconds + * @type Integer + * @protected + */ + this._timeDelay = cfg.delay || 30; + /** + * Flag used for switching between Button and Link. + * @type Boolean + * @protected + */ + this._isLink = cfg.isLink; + this.$cfgBean = this.$cfgBean || "aria.touch.widgets.ButtonCfg.Properties"; + + this.$Element.constructor.call(this, cfg, context, line); + + if (cfg.attributes && !cfg.attributes.disabled) { + this._registerListeners(cfg); + } + + // Needed for browsers where classList doesn't existnatively (e.g Android < 3 Version and IOS < 5.X) + this._classList = null; + }, + $destructor : function () { + this.timerId = null; + this.isLink = null; + if (this._classList) { + this._classList.$dispose(); + this._classList = null; + } + this.$Element.$destructor.call(this); + + }, + $prototype : { + + /** + * Initialization method called after the markup of the widget has been inserted in the DOM. + */ + initWidget : function () { + this.$Element.initWidget.call(this); + this._classList = new aria.utils.ClassList(this._domElt); + var classType = (this._isLink) ? this.LINK_CLASS : this.BUTTON_CLASS; + this._classList.add(classType); + + }, + + _manageEvents : function (event) { + if (event.type == "tapstart") { + this.timerId = aria.core.Timer.addCallback({ + fn : this._delayedHighlightCB, + scope : this, + delay : this._timeDelay + }); + } + if (event.type == "tapcancel" || event.type == "tap") { + if (this.timerId) { + aria.core.Timer.cancelCallback(this.timerId); + } + + if (event.type == "tapcancel" || (event.type == "tap" && !this.isLink)) { + this._classList.remove("pressed"); + } + } + + }, + + _delayedHighlightCB : function (args) { + this._classList.add("pressed"); + }, + + /** + * Add special listeners on top of the ones specified in configuration. + * @param {aria.html.beans.TextInputCfg.Properties} cfg Widget configuration. + * @protected + */ + _registerListeners : function (cfg) { + var listeners = cfg.on; + + this._chainListener(listeners, "tapstart", { + fn : this._manageEvents, + scope : this + }); + + this._chainListener(listeners, "tapcancel", { + fn : this._manageEvents, + scope : this + }); + + this._chainListener(listeners, "tap", { + fn : this._manageEvents, + scope : this + }); + } + } +}); diff --git a/src/aria/touch/widgets/ButtonCSS.tpl.css b/src/aria/touch/widgets/ButtonCSS.tpl.css new file mode 100644 index 000000000..bf26e41cc --- /dev/null +++ b/src/aria/touch/widgets/ButtonCSS.tpl.css @@ -0,0 +1,82 @@ +/* + * Copyright 2012 Amadeus s.a.s. + * 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. + */ + +{CSSTemplate { + $classpath : "aria.touch.widgets.ButtonCSS" +}} + + {macro main()} + + .appLink , .appButton { + position: relative; + display: block; + font:normal 700 15px/17px tahoma,arial,helvetica,sans-serif; + padding: 0.6em 1em; + border-radius: 16px; + text-align: center; + cursor: pointer; + } + .appLink { + background-color:#5393C5; + border:solid 1px #6FA0C0; + color:#fff; + } + + .appLink.pressed { + outline: 0 none; + background-color:#5393C5; + background: -webkit-linear-gradient(#5393C5, #6FACD5) repeat scroll 0 0 #5393C5; + background: -ms-linear-gradient(#5393C5, #6FACD5) repeat scroll 0 0 #5393C5; + background: -moz-linear-gradient(#5393C5, #6FACD5) repeat scroll 0 0 #5393C5; + background: -o-linear-gradient(#5393C5, #6FACD5) repeat scroll 0 0 #5393C5; + background: linear-gradient(#5393C5, #6FACD5) repeat scroll 0 0 #5393C5; + /*http://msdn.microsoft.com/en-us/library/ms532997(VS.85,loband).aspx*/ + filter: progid:DXImageTransform.Microsoft.Gradient(startColorstr='#5393C5', endColorstr='#6FACD5', GradientType=0) + } + + .appButton { + background-color:#F1F1F1; + border:solid 1px #BABABA; + color:#000; + } + + .appButton.pressed { + outline: 0 none; + background-color:#F1F1F1; + background: -webkit-linear-gradient(#F1F1F1, #D6D6D6) repeat scroll 0 0 #F1F1F1; + background: -ms-linear-gradient(#F1F1F1, #D6D6D6) repeat scroll 0 0 #F1F1F1; + background: -moz-linear-gradient(#F1F1F1, #D6D6D6) repeat scroll 0 0 #F1F1F1; + background: -o-linear-gradient(#F1F1F1, #D6D6D6) repeat scroll 0 0 #F1F1F1; + background: linear-gradient(#F1F1F1, #D6D6D6) repeat scroll 0 0 #F1F1F1; + /*http://msdn.microsoft.com/en-us/library/ms532997(VS.85,loband).aspx*/ + filter: progid:DXImageTransform.Microsoft.Gradient(startColorstr='#F1F1F1', endColorstr='#D6D6D6', GradientType=0) + } + + .appLink[disabled], .appButton[disabled] { + border: solid 1px #E8E8E8; + color:#B9BEC0; + background: #F1F1F1; /* Old browsers */ + background: -webkit-linear-gradient(#F1F1F1, #F7F7F7) repeat scroll 0 0 #BABABA; + background: -ms-linear-gradient(#F1F1F1, #F7F7F7) repeat scroll 0 0 #BABABA; + background: -moz-linear-gradient(#F1F1F1, #F7F7F7) repeat scroll 0 0 #BABABA; + background: -o-linear-gradient(#F1F1F1, #F7F7F7) repeat scroll 0 0 #BABABA; + background: linear-gradient(#F1F1F1, #F7F7F7) repeat scroll 0 0 #BABABA; + /*http://msdn.microsoft.com/en-us/library/ms532997(VS.85,loband).aspx*/ + filter: progid:DXImageTransform.Microsoft.Gradient(startColorstr='#F1F1F1', endColorstr='#BABABA',GradientType=0) /* IE6-9 */ + } + + {/macro} + +{/CSSTemplate} diff --git a/src/aria/touch/widgets/ButtonCfg.js b/src/aria/touch/widgets/ButtonCfg.js new file mode 100644 index 000000000..b5c510897 --- /dev/null +++ b/src/aria/touch/widgets/ButtonCfg.js @@ -0,0 +1,54 @@ +/* + * Copyright 2012 Amadeus s.a.s. + * 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. + */ +Aria.beanDefinitions({ + $package : "aria.touch.widgets.ButtonCfg", + $description : "Configuration for Button widget.", + $namespaces : { + "json" : "aria.core.JsonTypes", + "base" : "aria.html.beans.ElementCfg", + "common" : "aria.widgetLibs.CommonBeans" + }, + $beans : { + "Properties" : { + $type : "base:Properties", + $description : "Properties of a Button widget.", + $properties : { + "on" : { + $type : "base:Properties.$properties.on", + $properties : { + "type" : { + $type : "common:Callback", + $description : "Callback called when the user interacts with the button.." + } + } + }, + "isLink" : { + $type : "json:Boolean", + $description : "Whether the button is a link, which means a different highlighting pattern.", + $default : false + }, + "delay" : { + $type : "json:Integer", + $description : "delay between and tapstart event and highlighting of the link or button in miliseconds." + + }, + "tagName" : { + $type : "base:Properties.$properties.tagName", + $description : "Tag to be Used for Button Markup." + } + } + } + } +}); \ No newline at end of file diff --git a/src/aria/touch/widgets/Slider.js b/src/aria/touch/widgets/Slider.js index ef3045e15..e822c49a2 100644 --- a/src/aria/touch/widgets/Slider.js +++ b/src/aria/touch/widgets/Slider.js @@ -58,6 +58,37 @@ Aria.classDefinition({ * @protected */ this._parentDomId = this._domId + "_parent"; + /** + * Id generated for the slider switch on container element. + * @type String + * @protected + */ + this._onSwitchId = this._domId + "_on"; + /** + * Id generated for the slider switch off container element. + * @type String + * @protected + */ + this._offSwitchId = this._domId + "_off"; + /** + * Flag used for switching between switch and slider. + * @type Boolean + * @protected + */ + this._isSwitch = cfg.toggleSwitch; + /** + * Reference to the on state DOM element of the slider. + * @type HTMLElement + * @protected + */ + this._onContainer = null; + /** + * Reference to the off state DOM element of the slider. + * @type HTMLElement + * @protected + */ + this._offContainer = null; + /** * Reference to the button DOM element of the slider. * @type HTMLElement @@ -76,6 +107,12 @@ Aria.classDefinition({ * @protected */ this._sliderWidth = null; + /** + * Reference to the Dimension of the Slider. + * @type {aria.utils.DomBeans:Geometry} + * @protected + */ + this._sliderDimension = null; /** * Width of the rail in which thumb travels. @@ -125,8 +162,12 @@ Aria.classDefinition({ this._draggable.$dispose(); this._draggable = null; } + this._dragUtil = null; this._slider = null; this._sliderContainer = null; + this._onContainer = null; + this._offContainer = null; + this._sliderDimension = null; this.$BaseWidget.$destructor.call(this); }, $prototype : { @@ -158,13 +199,23 @@ Aria.classDefinition({ return out.write(this.INVALID_CONFIGURATION); } out.write([ - // Div containing the widget - '
', - // Rail, thumbs move over here - '', - // slider thumb - '', - '
'].join("")); + // Div containing the widget + '
', + // Rail, thumbs move over here + '', + // slider thumb + ''].join("")); + if (this._isSwitch) { + out.write([ + // For ON state Markup + '
ON
', + // For OFF state Markup + '
OFF
'].join("")); + } + out.write('
'); }, /** @@ -178,10 +229,16 @@ Aria.classDefinition({ this._slider = domUtils.getElementById(this._domId); this._sliderContainer = domUtils.getElementById(this._parentDomId); + this._sliderDimension = aria.utils.Dom.getGeometry(this._sliderContainer); this._sliderWidth = parseInt(domUtils.getStyle(this._slider, "width"), 10); this._sliderWidth += parseInt(aria.utils.Dom.getStyle(this._slider, "borderLeftWidth"), 10) || 0; this._sliderWidth += parseInt(aria.utils.Dom.getStyle(this._slider, "borderRightWidth"), 10) || 0; this._railWidth = this._cfg.width - this._sliderWidth; + if (this._isSwitch) { + this._onContainer = domUtils.getElementById(this._onSwitchId); + this._offContainer = domUtils.getElementById(this._offSwitchId); + this._updateSwitch(); + } this._setLeftPosition(); this._updateDisplay(); this._loadAndCreateDraggable(); @@ -197,6 +254,21 @@ Aria.classDefinition({ this._savedX = Math.floor(value * this._railWidth); }, + _updateSwitch : function () { + var val = this._value; + if (val >= 0.5) { + this._onContainer.style.width = this._cfg.width + "px"; + this._onContainer.style.left = "0px"; + this._offContainer.style.width = "0px"; + this._value = 1; + } else { + this._offContainer.style.width = this._cfg.width + "px"; + this._offContainer.style.left = "0px"; + this._onContainer.style.width = "0px"; + this._value = 0; + } + }, + /** * Load the dependency for Drag before if not loaded yet. * @protected @@ -224,14 +296,13 @@ Aria.classDefinition({ // In case the widget gets disposed while loading the dependencies return; } - var thumbs = [this._firstSlider, this._secondSlider]; - this._draggable = new aria.utils.dragdrop.Drag(this._slider, { handle : this._slider, proxy : null, axis : "x", constrainTo : this._sliderContainer }); + this._dragUtil = aria.utils.Mouse; this._draggable.$on({ "dragstart" : { fn : this._onDragStart, @@ -247,6 +318,14 @@ Aria.classDefinition({ } }); + // Listen to either mouse or touch + if (this._cfg.tapToMove) { + this._dragUtil.$on({ + "eventUp" : this._handleTapOnSlider, + scope : this + }); + } + }, /** * Handle the beginning of a drag @@ -274,6 +353,30 @@ Aria.classDefinition({ _onDragEnd : function (evt) { this._move(evt.src); this._initialDrag = null; + if (this._isSwitch) { + this._changeSwith(); + } + }, + /** + * Handle the switch on and off state after drag ends. + * @protected + */ + _changeSwith : function () { + this._updateSwitch(); + this._bindVal(); + this._setLeftPosition(); + this._updateDisplay(); + }, + /** + * Explicitly bind the value incase of swich + * @protected + */ + _bindVal : function () { + var binding = this._binding; + if (!binding) { + return; + } + aria.utils.Json.setValue(binding.inside, binding.to, this._value, this._bindingCallback); }, /** @@ -285,6 +388,19 @@ Aria.classDefinition({ this._savedX += diff; this._initialDrag = src.posX; this._setValue(); + if (this._isSwitch) { + this._switchDisplay(); + } + }, + /** + * Move the On and Off state elements + * @protected + */ + _switchDisplay : function () { + var dragVal = this._slider.offsetLeft; + this._onContainer.style.width = (this._sliderWidth + dragVal) + "px"; + this._offContainer.style.left = dragVal + "px"; + this._offContainer.style.width = (this._cfg.width - dragVal) + "px"; }, /** @@ -342,6 +458,9 @@ Aria.classDefinition({ this._readValue(); this._setLeftPosition(); this._updateDisplay(); + if (this._isSwitch) { + this._switchDisplay(); + } }, /** @@ -352,6 +471,31 @@ Aria.classDefinition({ if (this._slider) { this._slider.style.left = this._savedX + "px"; } + }, + /** + * Use to Handle the tap or mouseup event to set the slider's position + * @param {Object} evt + */ + _handleTapOnSlider : function (evt) { + var target = (evt.originalEvent.target) ? evt.originalEvent.target : evt.originalEvent.srcElement; + if (target.id === this._parentDomId || target.id === this._onSwitchId || target.id === this._offSwitchId) { + this._setHandlePos(evt.posX); + } + }, + /** + * To set the position of the slider thumb after tab or mouseup + * @param {Integer} xPos the position of the event + */ + _setHandlePos : function (xPos) { + this._savedX = xPos - this._sliderDimension.x; + this._savedX = (this._savedX > this._railWidth) ? this._railWidth : this._savedX; + this._value = Math.max(this._savedX / this._railWidth, 0); + if (this._isSwitch) { + this._updateSwitch(); + } + this._bindVal(); + this._setLeftPosition(); + this._updateDisplay(); } } diff --git a/src/aria/touch/widgets/SliderCSS.tpl.css b/src/aria/touch/widgets/SliderCSS.tpl.css index b54a656ea..5f73942fa 100644 --- a/src/aria/touch/widgets/SliderCSS.tpl.css +++ b/src/aria/touch/widgets/SliderCSS.tpl.css @@ -30,6 +30,26 @@ position: absolute; } + div.touchLibSlider .touchLibSwitchOn, div.touchLibSlider .touchLibSwitchOff{ + position: absolute; + border-radius: 32px 32px 32px 32px; + z-index: 1; + height: 17px; + font:normal 700 16px/17px arial,helvetica; + overflow:hidden; + text-align:center; + } + div.touchLibSlider .touchLibSwitchOn{ + background-color: #61A0CD; + color:#fff; + } + + div.touchLibSlider .touchLibSwitchOff{ + background-color: #DADADA; + color:#000; + } + + div.touchLibSlider span.touchContainer { position: absolute; height: 18px; @@ -41,6 +61,7 @@ border-radius: 32px 32px 32px 32px; width: 14px; height: 14px; + z-index: 2; } {/macro} diff --git a/src/aria/touch/widgets/SliderCfgBeans.js b/src/aria/touch/widgets/SliderCfgBeans.js index b62553ec0..dbf81f319 100644 --- a/src/aria/touch/widgets/SliderCfgBeans.js +++ b/src/aria/touch/widgets/SliderCfgBeans.js @@ -34,6 +34,16 @@ Aria.beanDefinitions({ $description : "Width to use for the widget.", $default : 100 }, + toggleSwitch : { + $type : "json:Boolean", + $description : "to enable the Toggle switch.", + $default : false + }, + tapToMove : { + $type : "json:Boolean", + $description : "Tap on the Slider Rail should move the thumb.", + $default : false + }, bindValue : { $type : "json:Object", $description : "Binding for the value of the slider.", diff --git a/src/aria/touch/widgets/TouchWidgetLib.js b/src/aria/touch/widgets/TouchWidgetLib.js index 25938010a..033e772ec 100644 --- a/src/aria/touch/widgets/TouchWidgetLib.js +++ b/src/aria/touch/widgets/TouchWidgetLib.js @@ -28,7 +28,8 @@ Aria.classDefinition({ */ widgets : { "Slider" : "aria.touch.widgets.Slider", - "DoubleSlider" : "aria.touch.widgets.DoubleSlider" + "DoubleSlider" : "aria.touch.widgets.DoubleSlider", + "Button" : "aria.touch.widgets.Button" } } }); \ No newline at end of file diff --git a/src/aria/utils/Mouse.js b/src/aria/utils/Mouse.js index b3ad137f8..8a4628a56 100644 --- a/src/aria/utils/Mouse.js +++ b/src/aria/utils/Mouse.js @@ -104,6 +104,9 @@ Aria.classDefinition({ $classpath : "aria.utils.Mouse", $singleton : true, + $events : { + "eventUp" : "Raised on the mouseup or tap." + }, $dependencies : ["aria.utils.Event", "aria.utils.AriaWindow", "aria.touch.Event", "aria.DomEvent"], $statics : { /** @@ -373,6 +376,21 @@ this._candidateForDrag = null; this._activeDrag = null; + var event = new aria.DomEvent(evt); + if (evt.type === "touchend") { + // The position of touch events is not determined correctly by clientX/Y + var elementPosition = aria.touch.Event.getPositions(event); + event.clientX = elementPosition[0].x; + event.clientY = elementPosition[0].y; + } + this.$raiseEvent({ + name : "eventUp", + originalEvent : evt, + posX : event.clientX, + posY : event.clientY + }); + event.$dispose(); + } } }); diff --git a/test/aria/touch/TouchTestSuite.js b/test/aria/touch/TouchTestSuite.js index 7bb820b30..6e0f76892 100644 --- a/test/aria/touch/TouchTestSuite.js +++ b/test/aria/touch/TouchTestSuite.js @@ -29,5 +29,9 @@ Aria.classDefinition({ this.addTests("test.aria.touch.widgets.DoubleSliderChange"); this.addTests("test.aria.touch.widgets.SingleSliderValue"); this.addTests("test.aria.touch.widgets.SingleSliderDrag"); + this.addTests("test.aria.touch.widgets.SliderSwitch"); + this.addTests("test.aria.touch.widgets.SliderSwitchDrag"); + this.addTests("test.aria.touch.widgets.ButtonTouch"); + } }); diff --git a/test/aria/touch/widgets/ButtonTouch.js b/test/aria/touch/widgets/ButtonTouch.js new file mode 100644 index 000000000..1e8ead680 --- /dev/null +++ b/test/aria/touch/widgets/ButtonTouch.js @@ -0,0 +1,80 @@ +/* + * Copyright 2012 Amadeus s.a.s. + * 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. + */ + +Aria.classDefinition({ + $classpath : "test.aria.touch.widgets.ButtonTouch", + $extends : "aria.jsunit.WidgetTestCase", + $dependencies : ["aria.touch.widgets.Button"], + $prototype : { + + testForSimpleButton : function () { + var cfg1 = { + id : "button1", + isLink : false + + }; + + var widget1 = this.createAndInit("aria.touch.widgets.Button", cfg1); + this.assertEquals(widget1._domElt.className, "appButton", "Wrong Markup for the Button Widget.."); + widget1.$dispose(); + this.outObj.clearAll(); + }, + testForSimpleLink : function () { + var cfg2 = { + id : "button2", + isLink : true, + attributes : { + disabled : "disabled" + } + + }; + + var widget2 = this.createAndInit("aria.touch.widgets.Button", cfg2); + this.assertEquals(widget2._domElt.className, "appLink", "Wrong Markup for the Link Widget.."); + widget2.$dispose(); + this.outObj.clearAll(); + }, + testForDisabledButton : function () { + var cfg3 = { + id : "button3", + isLink : false, + attributes : { + disabled : "disabled" + } + + }; + + var widget3 = this.createAndInit("aria.touch.widgets.Button", cfg3); + this.assertEquals(widget3._domElt.attributes["disabled"].value, "disabled", "Wrong state for the Button Widget.."); + widget3.$dispose(); + this.outObj.clearAll(); + }, + testForDisabledLink : function () { + var cfg4 = { + id : "button4", + isLink : true, + attributes : { + disabled : "disabled" + } + + }; + + var widget4 = this.createAndInit("aria.touch.widgets.Button", cfg4); + this.assertEquals(widget4._domElt.attributes["disabled"].value, "disabled", "Wrong state for the Link Widget.."); + widget4.$dispose(); + this.outObj.clearAll(); + } + } +}); diff --git a/test/aria/touch/widgets/SingleSliderTpl.tpl b/test/aria/touch/widgets/SingleSliderTpl.tpl index c3986b364..2a4fefd24 100644 --- a/test/aria/touch/widgets/SingleSliderTpl.tpl +++ b/test/aria/touch/widgets/SingleSliderTpl.tpl @@ -1 +1 @@ -/* * Copyright 2012 Amadeus s.a.s. * 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. */ {Template { $classpath : 'test.aria.touch.widgets.SingleSliderTpl', $wlibs : { 'touch' : 'aria.touch.widgets.TouchWidgetLib' } }} {macro main()} Here is a Touch Slider Widget bound with a Text Widget to display a value between $0 and $100 :

{@touch:Slider { bindValue: { to: "slider", inside: data }, width: 200, id : "slider" }/}
{/macro} {/Template} \ No newline at end of file +/* * Copyright 2012 Amadeus s.a.s. * 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. */ {Template { $classpath : 'test.aria.touch.widgets.SingleSliderTpl', $wlibs : { 'touch' : 'aria.touch.widgets.TouchWidgetLib' } }} {macro main()} Here is a Touch Slider Widget bound with a Text Widget to display a value between $0 and $100 :

{@touch:Slider { bindValue: { to: "slider", inside: data }, width: 200, id : "slider" }/}
{@touch:Slider { bindValue: { to: "slider1", inside: data }, width: 200, id : "slider1", tapToMove : true }/}
{@touch:Slider { width: 100, id : "switch", toggleSwitch : true, tapToMove : true, bindValue: { to: "switchVal", inside: data } }/} {section { id : "display", macro : "values", bindRefreshTo : [{ inside : data, to : "switchVal" }] }/} {/macro} {macro values()} Value $: ${data.switchVal ? (data.switchVal).toFixed(0) : 0} {/macro} {/Template} \ No newline at end of file diff --git a/test/aria/touch/widgets/SliderHelper.js b/test/aria/touch/widgets/SliderHelper.js index 4cef92112..4a89cda34 100644 --- a/test/aria/touch/widgets/SliderHelper.js +++ b/test/aria/touch/widgets/SliderHelper.js @@ -71,6 +71,12 @@ Aria.classDefinition({ fn : callback, scope : this }); + }, + click : function (position, callback) { + this.synEvent.execute([["click", position]], { + fn : callback, + scope : this + }); } } }); diff --git a/test/aria/touch/widgets/SliderSwitch.js b/test/aria/touch/widgets/SliderSwitch.js new file mode 100644 index 000000000..602d49ad2 --- /dev/null +++ b/test/aria/touch/widgets/SliderSwitch.js @@ -0,0 +1,87 @@ +/* + * Copyright 2012 Amadeus s.a.s. + * 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. + */ + +/** + * Check the initialization of a DoubleSlideWidget + */ +Aria.classDefinition({ + $classpath : "test.aria.touch.widgets.SliderSwitch", + $extends : "aria.jsunit.WidgetTestCase", + // Depend on drag to have synchronous creation of the widget + $dependencies : ["aria.touch.widgets.Slider", "aria.utils.Dom", "aria.utils.dragdrop.Drag"], + $prototype : { + + testCreation : function () { + this._createWidgetAndAssert(); + this._createWidgetAndAssert(0.5, 1); + this._createWidgetAndAssert(0.4, 0); + this._createWidgetAndAssert(2.1, 1); + this._createWidgetAndAssert(-4, 0); + }, + _createWidgetAndAssert : function (values, expected) { + var model = {}; + if (values) { + model.value = values; + } + var cfg = { + width : 100, + toggleSwitch : true, + bindValue : { + inside : model, + to : "value" + } + }; + var widget = this.createAndInit("aria.touch.widgets.Slider", cfg); + if (!expected) { + expected = 0; + } + model.value = (model.value >= 0.5) ? 1 : 0; + this._assertValue(widget, model, expected); + widget.$dispose(); + this.outObj.clearAll(); + }, + _assertValue : function (widget, model, expected) { + this.assertJsonEquals(widget._value, expected, "Widget incorrect with values %1 expecting %2"); + this.assertJsonEquals(model.value, expected, "Model incorrect with values %1 expecting %2"); + var position = parseInt(aria.utils.Dom.getStyle(widget._slider, "left"), 10); + // 15 is the size of the thumbs + var leftPos = (widget._railWidth) * expected; + this.assertEqualsWithTolerance(position, leftPos, 5, "Position of first is %1, expected %2"); + }, + testSetValue : function () { + var model = { + value : 0 + }; + + var cfg = { + width : 100, + toggleSwitch : true, + bindValue : { + inside : model, + to : "value" + } + }; + var widget = this.createAndInit("aria.touch.widgets.Slider", cfg); + + // correct value + aria.utils.Json.setValue(model, "value", 0); + this._assertValue(widget, model, 0); + aria.utils.Json.setValue(model, "value", 1); + this._assertValue(widget, model, 1); + widget.$dispose(); + this.outObj.clearAll(); + } + } +}); diff --git a/test/aria/touch/widgets/SliderSwitchDrag.js b/test/aria/touch/widgets/SliderSwitchDrag.js new file mode 100644 index 000000000..eba01d66a --- /dev/null +++ b/test/aria/touch/widgets/SliderSwitchDrag.js @@ -0,0 +1,76 @@ +/* + * Copyright 2012 Amadeus s.a.s. + * 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. + */ +Aria.classDefinition({ + $classpath : "test.aria.touch.widgets.SliderSwitchDrag", + $extends : "test.aria.touch.widgets.SliderHelper", + $dependencies : ["aria.utils.Dom"], + $prototype : { + runTemplateTest : function () { + this.widget = this.getWidgetInstance("switch"); + var from = this.fromThumb("slider"); + var to = this.toSlider(0.7); + this.drag(from, to, this._dragOn); + }, + + _dragOn : function () { + this._assertValue(1); + var from = this.fromThumb("slider"); + var to = this.toSlider(0.6); + to.x = (from.x * 0.5); + this.drag(from, to, this._dragOff); + }, + + _dragOff : function () { + this._assertValue(0); + var from = this.fromThumb("slider"); + var to = this.toSlider(0.4); + this.drag(from, to, this._dragLess); + }, + + _dragLess : function () { + this._assertValue(0); + var switchwid = this.getWidgetInstance("switch").getDom(); + var pos = aria.utils.Dom.getGeometry(switchwid); + pos.x = pos.x + pos.width * 0.6; + this.click(pos, this._afterFirstClick); + }, + + _afterFirstClick : function () { + this._assertValue(1); + var switchwid = this.getWidgetInstance("switch").getDom(); + var pos = aria.utils.Dom.getGeometry(switchwid); + pos.x = pos.x + pos.width * 0.2; + this.click(pos, this._afterSecondClick); + }, + + _afterSecondClick : function () { + this._assertValue(0); + this.end(); + }, + + _assertValue : function (val) { + var widgetValue = this.widget._value; + var expected = val; + this.assertEqualsWithTolerance(widgetValue, expected, 0.05, "Wrong thumb value in widget, %1 != %2"); + var modelValue = this.data.switchVal; + this.assertEquals(widgetValue, modelValue, "Model differs from widget values, %1 != %2"); + var railWidth = this.widget._railWidth; + var leftpos = parseInt((railWidth * modelValue), 10); + var leftposTab = parseInt(aria.utils.Dom.getStyle(this.widget._slider, "left"), 10); + this.assertEqualsWithTolerance(leftpos, leftposTab, 5, "Position of thumb is %1, expected %2"); + } + + } +}); \ No newline at end of file