blob: d134bc102201cfdc107661a74318c9de3e1301a2 [file] [log] [blame]
<?xml version="1.0" encoding="utf-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You 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.
-->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:components="comps.*" creationComplete="saveInitialOrientation(event)"
backgroundColor="0xe3e3e3"
applicationComplete="init(event)">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<components:QANavigator id="navigator" />
<fx:Script>
<![CDATA[
import comps.myViewNavigator;
import comps.snappingTouchEvents;
import flash.events.Event;
import mx.collections.ArrayList;
import mx.core.FlexGlobals;
import mx.core.IVisualElement;
import mx.core.mx_internal;
import mx.events.FlexEvent;
import spark.components.DataGroup;
import spark.components.Scroller;
import spark.components.supportClasses.GroupBase;
import spark.layouts.HorizontalLayout;
import spark.layouts.VerticalLayout;
use namespace mx_internal;
/**
* Instantiate a copy of the common mouse event sequences
*/
public var mouseSequences:snappingTouchEvents = new snappingTouchEvents();
/**
* Since we aren't using ViewNavigatorApplication we need to setup the listeners to handle back button
* support. This also sets up a global error handler to log uncaught RTEs and write them to disk.
*/
private function init(event:FlexEvent):void {
systemManager.stage.addEventListener(KeyboardEvent.KEY_DOWN, deviceKeyDownHandler);
systemManager.stage.addEventListener(KeyboardEvent.KEY_UP, deviceKeyUpHandler);
loaderInfo.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR, uncaughtErrorHandler);
}
/**
* Logs an uncaught RTE by writing a file with its information to the sdcard of the device.
* The view title is also updated to show an error has happened.
*/
private function uncaughtErrorHandler(e:UncaughtErrorEvent):void {
// don't show the RTE window
e.stopImmediatePropagation();
e.preventDefault();
// show the error in the title of the view and write to SD card in case needed later
var d:Date = new Date();
var writePath:String = "/sdcard/Flex/QA/List/RTE_" + d.fullYear.toString() + "-" + (d.month + 1).toString() + "-" + (d.date + 1).toString() + "_" + d.hours.toString() + "-" + d.minutes.toString() + "-" + d.seconds.toString() + "-" + d.getMilliseconds().toString() + ".txt";
if (e.error is Error) {
var error:Error = e.error as Error;
var errorString:String = error.name + " " + error.errorID + ": " + error.message + "\n" + error.getStackTrace();
trace(errorString);
navigator.activeView.title = errorString;
TouchScrollingUtil.writeFileToDisk(writePath, errorString);
} else {
var errorEvent:ErrorEvent = e.error as ErrorEvent;
trace(errorEvent);
navigator.activeView.title = "Error: " + errorEvent.errorID;
TouchScrollingUtil.writeFileToDisk(writePath, "Error: " + errorEvent.errorID + "\n" + errorEvent.toString());
}
}
/** For back button support */
private function deviceKeyDownHandler(event:KeyboardEvent):void {
if (event.keyCode == Keyboard.BACK && !navigator.exitApplicationOnBackKey)
event.preventDefault();
}
/** For back button support */
private function deviceKeyUpHandler(event:KeyboardEvent):void {
if (event.keyCode == Keyboard.BACK && !navigator.exitApplicationOnBackKey)
navigator.backKeyUpHandler();
}
/** Keeps track of the initial orientation */
private var initialOrientation:String;
/** Saves the orientation of the device at startup as the initial orientation */
private function saveInitialOrientation(event:FlexEvent):void
{
initialOrientation = aspectRatio;
}
/**
*
* This method is used to reset orientation to portrait mode if not already in portrait to
* ensure all tests have the same set up. Orientation tests change this property that might leave
* tests in other orientations if not run to completion. This method should temporarily help with this
* issue until <RestComponent> mustella function implements to do this.
*
*
* Sample usage: <RunCode code="application.doResetOrientation()" waitTarget="stage" waitEvent="orientationChange" />
*/
public function doResetOrientation():void
{
// if (aspectRatio != initialOrientation)
// {
// systemManager.stage.setAspectRatio(initialOrientation);
// trace("current- "+ aspectRatio + " initial- "+initialOrientation);
// }
// else
if (systemManager.stage.orientation != StageOrientation.DEFAULT)
{
systemManager.stage.setOrientation(StageOrientation.DEFAULT);
}
else
systemManager.stage.dispatchEvent(new StageOrientationEvent('orientationChange'));
}
/**
* This method gets all the current indices in view in groups in any layout
*/
public static function getIndicesInView(group:GroupBase):Vector.<int>
{
var visibleIndices:Vector.<int> = new Vector.<int>();
var eRect:Rectangle = new Rectangle();
for (var i:int = 0; i < group.numElements; i++)
{
var e:IVisualElement = group.getElementAt(i);
if (e != null)
{
eRect.x = e.getLayoutBoundsX();
eRect.y = e.getLayoutBoundsY();
eRect.width = e.getLayoutBoundsWidth();
eRect.height = e.getLayoutBoundsHeight();
if (group.scrollRect.intersects(eRect))
visibleIndices.push(i);
}
}
return visibleIndices;
}
/* gets first item in view */
public static function getFirstInView(group:GroupBase):Number
{
return getIndicesInView(group).reverse().pop();
}
/* gets last item in view */
public static function getLastInView(group:GroupBase):Number
{
return getIndicesInView(group).pop();
}
/* gets center item in view */
public static function getCenterInView(group:GroupBase):Number
{
return (getFirstInView(group) + getLastInView(group)) /2;
}
/**
* This method is used to find whether the current state in a list is leadingEdge aligned.
* Takes the direction (vertical or horizontal) and DataGroup to validate that the scroll position is leading snapped.
*/
public static function isLeading(group:GroupBase, direction:String):String
{
if(direction=="vertical")
{
var top:Number= group.getElementAt(getIndicesInView(group).sort(Array.NUMERIC).reverse().pop()).getLayoutBoundsY();
var scrollPos:Number=group.verticalScrollPosition;
if(-1<=(top-scrollPos)<=1)
return "true";
else
return top + "!=" + scrollPos;
}
if(direction=="horizontal")
{
var left:Number= group.getElementAt(getIndicesInView(group).sort(Array.NUMERIC).reverse().pop()).getLayoutBoundsX();
scrollPos=group.horizontalScrollPosition;
if(-1<=(left-scrollPos)<=1)
return "true";
else
return left + "!=" + scrollPos;
}
return "incorrect direction";
}
/**
* This method is used to find whether the current state in a list is trailingEdge aligned.
* Takes the direction (vertical or horizontal) and DataGroup to validate that the scroll position is trailing snapped.
*/
public static function isTrailing(group:GroupBase, direction:String):String
{
if(direction=="vertical")
{
var bottomElement:IVisualElement=group.getElementAt(getIndicesInView(group).sort(Array.NUMERIC).pop());
var bottom:Number=bottomElement.getLayoutBoundsY() + bottomElement.getLayoutBoundsHeight();
var scrollPos:Number=group.height+group.verticalScrollPosition;
if(-1<=(bottom-scrollPos)<=1)
return "true";
else
return bottom + "!=" + scrollPos;
}
if(direction=="horizontal")
{
var rightElement:IVisualElement=group.getElementAt(getIndicesInView(group).sort(Array.NUMERIC).pop());
var right:Number=rightElement.getLayoutBoundsX() + rightElement.getLayoutBoundsWidth();
scrollPos=group.width+group.horizontalScrollPosition;
if(-1<=(right-scrollPos)<=1)
return "true";
else
return right + "!=" + scrollPos;
}
return "incorrect direction";
}
/**
* This method is used to find whether the current state in a list is center aligned.
* Takes the direction (vertical or horizontal) and DataGroup to validate that the scroll position is center snapped.
*/
public static function isCenterTile(group:GroupBase, direction:String):String
{
var firstInView:Number=getIndicesInView(group).sort(Array.NUMERIC).reverse().pop();
var lastInView:Number=getIndicesInView(group).sort(Array.NUMERIC).pop();
var centerInView:IVisualElement=group.getElementAt(((lastInView-firstInView)/2)+firstInView)
if(direction=="vertical")
{
// # pixles below the center element
var bottom:Number = (group.verticalScrollPosition + group.height)-(centerInView.getLayoutBoundsY()+centerInView.getLayoutBoundsHeight());
// # pixles above the center element
var top:Number = centerInView.getLayoutBoundsY()-group.verticalScrollPosition;
if(-1<=(top-bottom)<=1)
return "true";
else
return top + "!=" + bottom;
}
if(direction=="horizontal")
{
var right:Number = (group.layout.horizontalScrollPosition + group.width)-(centerInView.getLayoutBoundsX()+centerInView.getLayoutBoundsWidth());
// # pixles above the center element
var left:Number = centerInView.getLayoutBoundsX()-group.layout.horizontalScrollPosition
if(-1<=(left-right)<=1)
return "true";
else
return left + "!=" + right;
}
return "incorrect direction";
}
]]>
</fx:Script>
</s:Application>