http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/e1f9d1df/TourDeFlex/LICENSE ---------------------------------------------------------------------- diff --git a/TourDeFlex/LICENSE b/TourDeFlex/LICENSE new file mode 100644 index 0000000..df070f2 --- /dev/null +++ b/TourDeFlex/LICENSE @@ -0,0 +1,219 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. + +TourDeFlex Subcomponents: + +The Apache Tour De Flex includes a number of subcomponents with +separate copyright notices and license terms. Your use of the source +code for the these subcomponents is subject to the terms and +conditions of the following licenses. + +The Open-Sans font is available under Apache License 2.0. For details +see TourDeFlex3/src/mx/effects/assets. + +The ping sound effect (ping.mp3) in TourDeFlex3/mx/src/effects/assets is +licensed under Creative Commons Attribution 3.0 (CC BY 3.0). + + + +
http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/e1f9d1df/TourDeFlex/NOTICE ---------------------------------------------------------------------- diff --git a/TourDeFlex/NOTICE b/TourDeFlex/NOTICE new file mode 100644 index 0000000..70f7066 --- /dev/null +++ b/TourDeFlex/NOTICE @@ -0,0 +1,13 @@ +Apache Flex +Copyright 2014 The Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). + +The Initial Developer of the Original Code, known as TourDeFlex, +is Adobe Systems Incorporated (http://www.adobe.com/). +Copyright 2009 - 2013 Adobe Systems Incorporated. All Rights Reserved. + +The ping sound effect (ping.mp3) in TourDeFlex3/src/mx/effects/assets +was created by CameronMusic. The original file can be found here: +http://www.freesound.org/people/cameronmusic/sounds/138420/ \ No newline at end of file http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/e1f9d1df/TourDeFlex/TourDeFlex/build.xml ---------------------------------------------------------------------- diff --git a/TourDeFlex/TourDeFlex/build.xml b/TourDeFlex/TourDeFlex/build.xml new file mode 100644 index 0000000..f1a3f7b --- /dev/null +++ b/TourDeFlex/TourDeFlex/build.xml @@ -0,0 +1,65 @@ +<?xml version="1.0" ?> +<!-- + + 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. + +--> +<project default="test" basedir="."> + + <property file="${basedir}/env.properties"/> + <property environment="env"/> + <property file="${basedir}/local.properties"/> + <property file="${basedir}/build.properties"/> + <condition property="FLEX_HOME" value="${env.FLEX_HOME}"> + <isset property="env.FLEX_HOME" /> + </condition> + <condition property="AIR_HOME" value="${env.AIR_HOME}"> + <isset property="env.AIR_HOME" /> + </condition> + + <!-- SDK properties --> + <property name="FLEX_HOME" value="C:/air3_beta2"/> + <property name="AIR_HOME" value="C:/air3_beta2"/> + <property name="ADL" value="${AIR_HOME}/bin/adl.exe"/> + <property name="ADT.JAR" value="${AIR_HOME}/lib/adt.jar"/> + + <target name="init" depends="clean"> + </target> + + <!-- additional tasks - mxmlc tag --> + <path id="flexTasks.path"> + <fileset dir="${FLEX_HOME}"> + <include name="lib/flexTasks.jar" /> + <include name="ant/lib/flexTasks.jar" /> + </fileset> + </path> + <taskdef resource="flexTasks.tasks" classpathref="flexTasks.path"/> + + <target name="compile" depends="init"> + <mxmlc file="${basedir}/src/TourDeFlex.mxml" + output="${basedir}/src/TourDeFlex.swf" fork="true" failonerror="true"> + <load-config filename="${FLEX_HOME}/frameworks/air-config.xml"/> + <source-path path-element="${basedir}/src"/> + </mxmlc> + </target> + + <target name="test" depends="compile"> + </target> + + <target name="clean" description="clean up"> + <delete file="${basedir}/src/TourDeFlex.swf"/> + </target> +</project> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/e1f9d1df/TourDeFlex/TourDeFlex/src/Config.as ---------------------------------------------------------------------- diff --git a/TourDeFlex/TourDeFlex/src/Config.as b/TourDeFlex/TourDeFlex/src/Config.as new file mode 100644 index 0000000..85a6384 --- /dev/null +++ b/TourDeFlex/TourDeFlex/src/Config.as @@ -0,0 +1,157 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// 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. +// +//////////////////////////////////////////////////////////////////////////////// +package +{ + import classes.LocalQuickStart; + + import flash.filesystem.File; + import flash.filesystem.FileMode; + import flash.filesystem.FileStream; + import flash.system.Capabilities; + + public class Config + { + [Bindable] public static var PROGRAM_TITLE:String = "Tour de Flex"; + [Bindable] public static var APP_VERSION:String = "0"; + [Bindable] public static var OBJECTS_FILE_VERSION:String = "0"; + [Bindable] public static var OBJECTS_TOTAL:int = 0; + [Bindable] public static var ABOUT_MENU_LIST:XMLList; + [Bindable] public static var IS_ONLINE:Boolean = false; + [Bindable] public static var USE_SPLASH:Boolean = true; + + //public static var SETTINGS_FILE:String = "settings.xml"; + //public static function get SETTINGS_URL():String {return "data/" + SETTINGS_FILE;} + //public static var settingsXml:XML; + + [Bindable] public static var ABOUT_MENU_TITLE:String = "Flex Resources"; + + [Bindable] public static var SPLASH_URL:String = "data/assets/intro.flv"; + [Bindable] public static var QUICK_START_REMOTE_URL:String = "http://tourdeflex.blogspot.com"; + [Bindable] public static var QUICK_START_LOCAL_URL:String = "data/quickstart.html"; + + public static var OBJECTS_FILE:String = "objects-desktop2.xml"; + public static function get OBJECTS_URL():String {return "data/" + OBJECTS_FILE;} + public static var LOCAL_OBJECTS_ROOT_PATH:String = "objects/"; + + public static var OBJECTS_UPDATER_FILE:String = "objects-desktop2-update.xml"; + public static function get OBJECTS_UPDATER_URL():String {return "http://tourdeflex.adobe.com/download/" + OBJECTS_UPDATER_FILE;} + public static var APP_UPDATER_URL:String = "http://tourdeflex.adobe.com/download/update4.xml"; + + public static var ONLINE_STATUS_URL:String = "http://tourdeflex.adobe.com/ping.html"; + public static var OFFLINE_URL:String = "data/offline.html"; + + private static var BASE_URL:String = "http://tourdeflex.adobe.com/server/"; + [Bindable] public static var DATA_EXCHANGE_URL:String = BASE_URL + "main.php"; + + private static var COMENTS_URL_QUERY_STRING:String = "main.php?Request=GetComments&ObjectId="; + public static var COMMENTS_URL:String = BASE_URL + COMENTS_URL_QUERY_STRING; + + public static var HEADER_GRADIENT_IMAGE:String = "images/header_gradient.png"; + public static var HEADER_IMAGE:String = "images/header_logo.png"; + + public static var TREE_NO_ICON:String = "images/tree_noIcon.png"; + + public function Config() + { + } + + /* + public static function loadSettings():void + { + setLocalization(); + + var loader:URLLoader = new URLLoader(new URLRequest(Config.SETTINGS_URL)); + loader.addEventListener(Event.COMPLETE, settingsXmlLoaded); + + var appXml:XML = NativeApplication.nativeApplication.applicationDescriptor; + var ns:Namespace = appXml.namespace(); + APP_VERSION = appXml.ns::version; + } + */ + + public static function setLocalization():void + { + //var localLanguage:String = Capabilities.languages[0].toString().toLowerCase(); //for 'en-us' + var localLanguage:String = Capabilities.language.toLowerCase(); //for 'en' + trace("LANG=" + localLanguage); + //localLanguage = "jp"; //for testing + //trace(localLanguage); + + if(localLanguage != "en" && localLanguage != "en-us") + { + //Config.QUICK_START_REMOTE_URL = appendLanguage(Config.QUICK_START_REMOTE_URL, localLanguage); + //Config.QUICK_START_LOCAL_URL = appendLanguage(Config.QUICK_START_LOCAL_URL, localLanguage); + + var localizedObjectFile:String = "objects-desktop_" + localLanguage + ".xml"; + var staticObjectFile:File = File.applicationDirectory.resolvePath("data/" + localizedObjectFile); + if(staticObjectFile.exists) + { + OBJECTS_FILE = localizedObjectFile; + Config.OBJECTS_UPDATER_FILE = "objects-desktop-update_" + localLanguage + ".xml"; + //SETTINGS_FILE = "settings_" + localLanguage + ".xml"; + } + } + } + + public static function appendLanguage(oldPath:String, lang:String):String + { + var newPath:String = oldPath; + + var pos:int = oldPath.lastIndexOf("."); + if(pos > 0) + { + var ext:String = oldPath.substring(pos, oldPath.length); + newPath = oldPath.substring(0, pos); + newPath += "_" + lang + ext; + } + + return newPath; + } + + /* + private static function settingsXmlLoaded(event:Event):void + { + var loader:URLLoader = URLLoader(event.target); + settingsXml = new XML(loader.data); + PROGRAM_TITLE = settingsXml.@title; + ABOUT_MENU_LIST = settingsXml.AboutMenu.Item; + ABOUT_MENU_TITLE = settingsXml.AboutMenu.@title; + } + */ + + public static function isAppFirstTimeRun():Boolean + { + var isFirstTime:Boolean = false; + var appFirstTimeRunFile:File = File.applicationStorageDirectory.resolvePath("versions/" + APP_VERSION); + + if(!appFirstTimeRunFile.exists) + { + var fileStream:FileStream = new FileStream(); + fileStream.open(appFirstTimeRunFile, FileMode.WRITE); + fileStream.writeUTFBytes(APP_VERSION); + fileStream.close(); + + isFirstTime = true; + } + + return isFirstTime; + } + + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/e1f9d1df/TourDeFlex/TourDeFlex/src/Preferences.as ---------------------------------------------------------------------- diff --git a/TourDeFlex/TourDeFlex/src/Preferences.as b/TourDeFlex/TourDeFlex/src/Preferences.as new file mode 100644 index 0000000..49c7e35 --- /dev/null +++ b/TourDeFlex/TourDeFlex/src/Preferences.as @@ -0,0 +1,68 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// 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. +// +//////////////////////////////////////////////////////////////////////////////// +package +{ + import flash.filesystem.File; + import flash.filesystem.FileMode; + import flash.filesystem.FileStream; + + public class Preferences + { + //-------------------------------------------------------------------------- + // Variables + //-------------------------------------------------------------------------- + private static var filePath:String = "preferences.xml"; + [Bindable] public static var preferencesXml:XML = <Preferences />; + + //-------------------------------------------------------------------------- + // Loading/setup + //-------------------------------------------------------------------------- + public function Preferences() + { + + } + + public static function load():void + { + var preferencesFile:File = File.applicationStorageDirectory.resolvePath(filePath); + if(preferencesFile.exists) + { + var fileStream:FileStream = new FileStream(); + fileStream.open(preferencesFile, FileMode.READ); + preferencesXml = XML(fileStream.readUTFBytes(fileStream.bytesAvailable)); + fileStream.close(); + } + } + + //-------------------------------------------------------------------------- + // Saving + //-------------------------------------------------------------------------- + public static function save():void + { + var preferencesFile:File = File.applicationStorageDirectory.resolvePath(filePath); + var fileStream:FileStream = new FileStream(); + fileStream.open(preferencesFile, FileMode.WRITE); + fileStream.writeUTFBytes(preferencesXml.toXMLString()); + fileStream.close(); + } + + //-------------------------------------------------------------------------- + //-------------------------------------------------------------------------- + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/e1f9d1df/TourDeFlex/TourDeFlex/src/TourDeFlex-app.xml ---------------------------------------------------------------------- diff --git a/TourDeFlex/TourDeFlex/src/TourDeFlex-app.xml b/TourDeFlex/TourDeFlex/src/TourDeFlex-app.xml new file mode 100644 index 0000000..3f5594d --- /dev/null +++ b/TourDeFlex/TourDeFlex/src/TourDeFlex-app.xml @@ -0,0 +1,157 @@ +<?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. + +--> +<application xmlns="http://ns.adobe.com/air/application/2.0"> + +<!-- Adobe AIR Application Descriptor File Template. + + Specifies parameters for identifying, installing, and launching AIR applications. + See http://www.adobe.com/go/air_1.0_application_descriptor for complete documentation. + + xmlns - The Adobe AIR namespace: http://ns.adobe.com/air/application/1.0 + The last segment of the namespace specifies the version + of the AIR runtime required for this application to run. + + minimumPatchLevel - The minimum patch level of the AIR runtime required to run + the application. Optional. +--> + + <!-- The application identifier string, unique to this application. Required. --> + <id>TourDeFlex</id> + + <!-- Used as the filename for the application. Required. --> + <filename>TourDeFlex</filename> + + <!-- The name that is displayed in the AIR application installer. Optional. --> + <name>TourDeFlex</name> + + + <publisherID>E7BED6E5DDA59983786DD72EBFA46B1598278E07.1</publisherID> + <!-- An application version designator (such as "v1", "2.5", or "Alpha 1"). Required. --> + <version>2.0</version> + + <!-- Description, displayed in the AIR application installer. Optional. --> + <description>Tour de Flex - Adobe Systems, Inc.</description> + + <!-- Copyright information. Optional --> + <!-- <copyright>Copyright 2010, Adobe Systems, Inc.</copyright> --> + + <!-- Settings for the application's initial window. Required. --> + <initialWindow> + <!-- The main SWF or HTML file of the application. Required. --> + <!-- Note: In Flex Builder, the SWF reference is set automatically. --> + <content>[This value will be overwritten by Flex Builder in the output app.xml]</content> + + <!-- The title of the main window. Optional. --> + <!-- <title></title> --> + + <!-- The type of system chrome to use (either "standard" or "none"). Optional. Default standard. --> + <!-- <systemChrome></systemChrome> --> + <systemChrome>none</systemChrome> + + <!-- Whether the window is transparent. Only applicable when systemChrome is false. Optional. Default false. --> + <!-- <transparent></transparent> --> + + <!-- Whether the window is initially visible. Optional. Default false. --> + <!-- <visible></visible> --> + + <!-- Whether the user can minimize the window. Optional. Default true. --> + <!-- <minimizable></minimizable> --> + + <!-- Whether the user can maximize the window. Optional. Default true. --> + <!-- <maximizable></maximizable> --> + + <!-- Whether the user can resize the window. Optional. Default true. --> + <!-- <resizable></resizable> --> + + <!-- The window's initial width. Optional. --> + <!-- <width></width> --> + + <!-- The window's initial height. Optional. --> + <!-- <height></height> --> + + <!-- The window's initial x position. Optional. --> + <!-- <x></x> --> + + <!-- The window's initial y position. Optional. --> + <!-- <y></y> --> + + <!-- The window's minimum size, specified as a width/height pair, such as "400 200". Optional. --> + <!-- <minSize></minSize> --> + + <!-- The window's initial maximum size, specified as a width/height pair, such as "1600 1200". Optional. --> + <!-- <maxSize></maxSize> --> + </initialWindow> + + <!-- The subpath of the standard default installation location to use. Optional. --> + <!-- <installFolder></installFolder> --> + + <!-- The subpath of the Windows Start/Programs menu to use. Optional. --> + <!-- <programMenuFolder></programMenuFolder> --> + + <!-- The icon the system uses for the application. For at least one resolution, + specify the path to a PNG file included in the AIR package. Optional. --> + <icon> + <image16x16>images/icons/tdfx_16.png</image16x16> + <image32x32>images/icons/tdfx_32.png</image32x32> + <image48x48>images/icons/tdfx_48.png</image48x48> + <image128x128>images/icons/tdfx_128.png</image128x128> + </icon> + + <!-- Whether the application handles the update when a user double-clicks an update version + of the AIR file (true), or the default AIR application installer handles the update (false). + Optional. Default false. --> + <!-- <customUpdateUI></customUpdateUI> --> + + <!-- Whether the application can be launched when the user clicks a link in a web browser. + Optional. Default false. --> + <allowBrowserInvocation>true</allowBrowserInvocation> + + <!-- Listing of file types for which the application can register. Optional. --> + <!-- <fileTypes> --> + + <!-- Defines one file type. Optional. --> + <!-- <fileType> --> + + <!-- The name that the system displays for the registered file type. Required. --> + <!-- <name></name> --> + + <!-- The extension to register. Required. --> + <!-- <extension></extension> --> + + <!-- The description of the file type. Optional. --> + <!-- <description></description> --> + + <!-- The MIME type. Optional. --> + <!-- <contentType></contentType> --> + + <!-- The icon to display for the file type. Optional. --> + <!-- + <icon> + <image16x16>images/icons/16x16-Icon.png</image16x16> + <image32x32>images/icons/32x32-Icon.png</image32x32> + <image48x48>images/icons/48x48-Icon.png</image48x48> + <image128x128>images/icons/128x128-Icon.png</image128x128> + </icon> + --> + + <!-- </fileType> --> + <!-- </fileTypes> --> + +</application> http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/e1f9d1df/TourDeFlex/TourDeFlex/src/TourDeFlex.mxml ---------------------------------------------------------------------- diff --git a/TourDeFlex/TourDeFlex/src/TourDeFlex.mxml b/TourDeFlex/TourDeFlex/src/TourDeFlex.mxml new file mode 100644 index 0000000..012b79a --- /dev/null +++ b/TourDeFlex/TourDeFlex/src/TourDeFlex.mxml @@ -0,0 +1,881 @@ +<?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. + +--> +<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" showFlexChrome="false" + showStatusBar="false" applicationComplete="init()" title="Tour de Flex" styleName="mainWindow" + width="1000" height="768" minWidth="1000" minHeight="700" xmlns:components="components.*" + visible="true" resize="window_resize(event)" horizontalScrollPolicy="off" verticalScrollPolicy="off"> + + <mx:Style source="styles.css" /> + + <mx:Script> + <![CDATA[ + import mx.events.AIREvent; + import mx.rpc.events.FaultEvent; + import components.QuickStartWindow; + import mx.events.ResizeEvent; + import mx.validators.EmailValidator; +// import TopPanels4_fla.MainTimeline; + import components.SplashWindow; + import mx.rpc.events.ResultEvent; + import classes.ObjectData; + import classes.Document; + import classes.ApplicationUpdaterManager; + import components.IllustrationTab; + import mx.events.CloseEvent; + import components.DownloadWindow; + import mx.controls.Alert; + import air.update.events.UpdateEvent; + import air.net.URLMonitor; + import mx.events.ItemClickEvent; + import components.WipeWindow; + import mx.events.FlexEvent; + import components.SearchWindow; + import mx.events.IndexChangedEvent; + import mx.managers.PopUpManager; + import components.CommentsWindow; + import mx.events.ListEvent; + + //---- ADDED HS ------// + import mx.messaging.messages.IMessage; + import mx.rpc.events.ResultEvent; +// import merapi.BridgeInstance; +// import merapi.Bridge; +// import merapi.messages.Message; +// import merapi.messages.MerapiObjectMessage; + import mx.collections.ArrayCollection; +// import plugin.TDFPluginTransferObject; + import flash.utils.*; + import components.PluginDownloadWindow; + + //-------------------------------------------------------------------------- + // Variables + //-------------------------------------------------------------------------- + [Bindable] + public var objectData:ObjectData; + + private var applicationUpdaterManager:ApplicationUpdaterManager; + private var urlMonitor:URLMonitor; + private var hasSearchOpenedWhileCommenting:Boolean = false; + private var selectedDownloadPath:String = ""; + private var selectedIllustrationURL:String = ""; + private var previousTopLevelCategoriesText:String = ""; + + //---- ADDED HS ------// + private var dockImage:BitmapData; +// private var bridge:Bridge; + private var featuredSent:Boolean = false; + private var isPlugin:Boolean = false; + private var isStandAlone:Boolean = false; + private var comps:ArrayCollection= new ArrayCollection(); +// private var pluginTransferObject:TDFPluginTransferObject; + [Bindable] + private var splashWindow:QuickStartWindow = new QuickStartWindow(); + private var splashPlayed:Boolean = false; + + private var expandMode:int = 0; + + private var illustrationAutoExpanded:Boolean = false; + + + //-------------------------------------------------------------------------- + // Loading/initializing for main application + //-------------------------------------------------------------------------- + private function init():void + { + NativeApplication.nativeApplication.addEventListener(Event.EXITING, onExiting); + + //Config.loadSettings(); + Config.setLocalization(); + Preferences.load(); + + objectData = new ObjectData(); + applicationUpdaterManager = new ApplicationUpdaterManager(); + + urlMonitor = new URLMonitor(new URLRequest(Config.ONLINE_STATUS_URL)); + urlMonitor.addEventListener(StatusEvent.STATUS, urlMonitor_status); + urlMonitor.pollInterval = 20000; // Every 20 seconds + urlMonitor.start(); + + // Request notification whenever the app is activated or deactivated + //this.addEventListener(AIREvent.APPLICATION_ACTIVATE, applicationActivate); + //this.addEventListener(AIREvent.APPLICATION_DEACTIVATE, applicationDeactivate); + + // Use the loader object to load an image, which will be used for the systray + // After the image has been loaded into the object, we can prepare the application for docking to the system tray + var iconLoad:Loader = new Loader(); + var loader:Loader = new Loader(); + + iconLoad.load(new URLRequest("app:/images/icons/tdfx_128.png")); + iconLoad.contentLoaderInfo.addEventListener(Event.COMPLETE,prepareForSystray); + + NativeApplication.nativeApplication.addEventListener(InvokeEvent.INVOKE, onInvoke); + + // Center app when it starts - will add code later to remember where it was last -- GAW + var currentScreen:Screen = getCurrentScreen(); + stage.nativeWindow.x = (currentScreen.bounds.right / 2) - (this.width / 2); + stage.nativeWindow.y = (currentScreen.bounds.height / 2) - (this.height / 2); + if (stage.nativeWindow.x < 0) stage.nativeWindow.x = 0; + if (stage.nativeWindow.y < 0) stage.nativeWindow.y = 0; + + } + + + private function getCurrentScreen():Screen{ + var current:Screen; + var screens:Array = Screen.getScreensForRectangle(stage.nativeWindow.bounds); + (screens.length > 0) ? current = screens[0] : current = Screen.mainScreen; + return current; + } + + public function showQuickStart():void + { + illustrationTabs.visible = false; + documentTabs.visible = false; + quickStartWindow.visible = true; + if(Config.IS_ONLINE ) + { + quickStartWindow.location = Config.QUICK_START_REMOTE_URL; + } + else + { + quickStartWindow.location = Config.QUICK_START_LOCAL_URL; + } + } + + private function closeQuickStart(event:CloseEvent = null):void + { + illustrationTabs.visible = true; + documentTabs.visible = true; + quickStartWindow.visible = false; + quickStartWindow.clearContents(); // to kill any running content + } + + /** + * Called when the invoke event is fired, such as when this app is called. ADDED HS + */ + private function onInvoke(invokeEvt:InvokeEvent):void + { + // Here we need to figure out how the app was invoked, if from the Eclipse plug-in, then we should + // create the Merapi bridge. If not, then we should just set the app to visible since it starts off + // invisible so we can keep it in the system tray + /* + if (invokeEvt.arguments[0] == "plugin" && isPlugin == false) { + isPlugin = true; + bridge = Bridge.instance; + bridge.addEventListener(ResultEvent.RESULT,handleResponse); + } else { */ + isStandAlone = true; + this.undock(invokeEvt); + /*}*/ + + // If started in stand alone mode and later invoked again as a plugin, send featured components - GAW + //if (isStandAlone && isPlugin) sendFeatured(); + + + //if(!isPlugin && Config.USE_SPLASH && Preferences.preferencesXml.Splash.@skip != "true") + if(!isPlugin && Config.USE_SPLASH && !splashPlayed) + { + showQuickStart(); + splashPlayed = true; + } + } + + /* + private function sendFeatured():void { + // Never send featured components more than once + if (!featuredSent) { + var featuredComps:ArrayCollection = objectData.getFeaturedComponents(); + var m : Message = new Message(); + m.type = "FindFeaturedComponents"; + m.data = featuredComps; + bridge.sendMessage(m); + featuredSent = true; + } + } + */ + + private function urlMonitor_status(event:StatusEvent):void + { + Config.IS_ONLINE = urlMonitor.available; + + if(Config.IS_ONLINE ) + { + quickStartWindow.location = Config.QUICK_START_REMOTE_URL; + if(objectList.selectedId > 0) + button_comments.enabled = true; + } + else + { + quickStartWindow.location = Config.QUICK_START_LOCAL_URL; + button_comments.enabled = false; + } + + + } + + private function confirmExit():void { + Alert.yesLabel = "Close"; + Alert.noLabel = "Minimize"; + Alert.show("Closing will cause the plug-in search capabilities to be rendered useless. Close or minimize?", "Close?", 3, this, confirmationClickHandler); + + } + + private function confirmationClickHandler(event:CloseEvent):void { + if (event.detail==Alert.YES) { + isPlugin = false; + NativeApplication.nativeApplication.dispatchEvent(new Event(Event.EXITING,true,true)); + } else { + dock(); + } + } + + private function closeSplash():void { + PopUpManager.removePopUp(splashWindow); + //mx.core.Application.application.removeChild(movieBackground); + } + + private function onExiting(exitingEvent:Event):void { + var winClosingEvent:Event; + + // Kill the movie and it's background if it exists + //if (this.contains(movieBackground)) closeSplash(); + + exitingEvent.preventDefault(); + if (isPlugin) { + undock(exitingEvent); + confirmExit(); + return; + } + + NativeApplication.nativeApplication.removeEventListener(Event.EXITING, onExiting); + + for each (var win:NativeWindow in NativeApplication.nativeApplication.openedWindows) { + winClosingEvent = new Event(Event.CLOSING,false,true); + win.dispatchEvent(winClosingEvent); + if (!winClosingEvent.isDefaultPrevented()) { + win.close(); + } else { + exitingEvent.preventDefault(); + } + } + + if (!exitingEvent.isDefaultPrevented()) { + Preferences.save(); + } + } + + //-------------------------------------------------------------------------- + // Window events + //-------------------------------------------------------------------------- + private function window_resize(event:ResizeEvent):void + { + if (documentTabs != null) documentTabs.needHtmlHack = false; + + //if(splashWindow.video_intro) + //{ + //splashWindow.width = this.width - splashWindow.x - 40; + //splashWindow.height = this.height - splashWindow.y - 65; + //splashWindow.video_intro.width = splashWindow.width; + //splashWindow.video_intro.height = splashWindow.height; + //} + } + + //-------------------------------------------------------------------------- + // Object list UI coordination/management + //-------------------------------------------------------------------------- + private function objectList_change(event:ListEvent):void + { + var objectXml:XML = null; + + documentTabs.needHtmlHack = true; + // Kill the movie and it's background if it exists + //if (this.contains(movieBackground)) closeSplash(); + + /* + // Get the object xml differently depending on if it was clicked from AIR side or plugin ... HS + if (event==null && pluginTransferObject!=null) { + objectXml = objectData.getXMLForObjectId(pluginTransferObject.selectedComponentId); + } + else + { */ + objectXml = XML(event.itemRenderer.data); + /*}*/ + + objectList.selectedId = objectXml.@id; + objectList.selectedObject = objectXml; + + button_download.enabled = false; + button_comments.enabled = false; + button_expand.enabled = false; + button_browser.enabled = false; + + if(objectList.selectedId > 0) + { + closeQuickStart(); + + label_objectName.text = objectXml.@name; + if(Config.IS_ONLINE) + { + //HTTP_GetCommentsTotal.send(); + HTTP_logView.send(); + button_comments.enabled = true; + } + + searchWindow.visible = false; + commentsWindow.visible = false; + objectList.setDescription(objectXml.@description, objectXml.@dateAdded, objectXml.@author); + + documentTabs.needHtmlHack = true; + + //reset selected tab due to tab selection issue + documentTabs.selectedIndex = 0; + documentTabs.validateNow(); + + illustrationTabs.removeAll(); + illustrationTabs.removeAllIllustrations(); + + var illustrations:XMLList = XMLList(objectXml.Illustrations.Illustration); + for each(var illustration:XML in illustrations) + { + var associatedDocuments:Array = new Array(); + documentTabs.removeAllChildren(); + var documents:XMLList = XMLList(illustration.Documents.Document); + for each(var document:XML in documents) + { + var documentPath:String = document.@path; + if(document.@localPath.toString().length > 0) + documentPath = document.@localPath; + + associatedDocuments.push(new Document(document.@name, documentPath, document.@openLinksExternal)); + } + + if(!Config.IS_ONLINE && illustration.@localPath.toString().length == 0 && illustration.@path.toLowerCase().indexOf("http") == 0) + { + illustrationTabs.addTab(illustration.@name, Config.OFFLINE_URL, "", "", "", "", "", "", null); + } + else + { + var illustrationPath:String = illustration.@path; + if(illustration.@localPath.toString().length > 0) + illustrationPath = illustration.@localPath; + + var illustrationDownloadPath:String = illustration.@downloadPath; + if(illustration.@localDownloadPath.toString().length > 0) + illustrationDownloadPath = illustration.@localDownloadPath; + + illustrationTabs.addTab(illustration.@name, illustrationPath, Config.LOCAL_OBJECTS_ROOT_PATH, illustration.@isModule, illustrationDownloadPath, illustration.@autoExpand, illustration.@openLinksExternal, illustration.@scrollBars, associatedDocuments); + } + } + + documentTabs.addTabs(illustrationTabs.associatedDocumentsCollection[0], Config.LOCAL_OBJECTS_ROOT_PATH); + + if(illustrationTabs.numChildren > 0) + autoExpandIllustrationTab(IllustrationTab(illustrationTabs.getChildAt(0)).autoExpand); + + if(illustrationTabs.numChildren > 0 && IllustrationTab(illustrationTabs.getChildAt(0)).downloadPath.length > 0) + { + button_download.enabled = true; + selectedDownloadPath = IllustrationTab(illustrationTabs.getChildAt(0)).downloadPath; + } + selectedIllustrationURL = IllustrationTab(illustrationTabs.getChildAt(0)).illustrationURL; + } + else + { + button_comments.label = "Comments"; + } + } + + private function illustrationTabs_change(event:IndexChangedEvent):void + { + var documents:Array = IllustrationTabs(event.currentTarget).associatedDocumentsCollection[event.newIndex]; + documentTabs.addTabs(documents, Config.LOCAL_OBJECTS_ROOT_PATH); + + var tab:IllustrationTab = IllustrationTab(IllustrationTabs(event.currentTarget).getChildAt(event.newIndex)); + selectedDownloadPath = tab.downloadPath; + if(selectedDownloadPath.length == 0) + button_download.enabled = false; + else + button_download.enabled = true; + + selectedIllustrationURL = tab.illustrationURL; + if(selectedIllustrationURL.length == 0) + button_browser.enabled = false; + else + button_browser.enabled = true; + + autoExpandIllustrationTab(tab.autoExpand); + } + + private function autoExpandIllustrationTab(autoExpand:Boolean):void + { + var documentsBox:DisplayObject = vdivider.getChildAt(1); + if(autoExpand) + { + //button_expand.enabled = false; + illustrationAutoExpanded = true; + documentsBox.height = 0; + } + else + { + button_expand.enabled = true; + illustrationAutoExpanded = false; + + if(expandMode == 0) // showing split + documentsBox.height = vdivider.height/2; + else if(expandMode == 1) // showing illustrations + documentsBox.height = 0; + else if(expandMode == 2) // showing documents + documentsBox.height = vdivider.height; + } + } + + private function toggleButtonBar_treeList_itemClick(event:ItemClickEvent):void + { + if(event.index == 0) + { + objectList.showTreeView(true); + comboBox_topLevelCategories.visible = false; + comboBox_topLevelCategories.height = 0; + } + else + { + objectData.sort(objectList.sortType); + objectList.showTreeView(false); + comboBox_topLevelCategories.visible = true; + comboBox_topLevelCategories.height = 22; + } + } + + private function comboBox_topLevelCategories_change(event:ListEvent):void + { + searchWindow.clear(); + objectData.filterTopLevelCategory(comboBox_topLevelCategories.selectedLabel); + objectData.sort(objectList.sortType); + } + + private function objectList_sortChange(event:ListEvent):void + { + objectData.sort(objectList.sortType); + } + + //-------------------------------------------------------------------------- + // Comments window + //-------------------------------------------------------------------------- + private function button_comments_click(event:MouseEvent):void + { + if(objectList.selectedId > 0) + { + var url:String = objectList.selectedObject.@commentsUrl; + if(url.length > 0) + navigateToURL(new URLRequest(url)); + else + Alert.show("Comments are currently unavailable for this item.", "Unavailable"); + } + } + + /* + private function button_comments_click(event:MouseEvent):void + { + if(objectList.selectedId > 0) + { + commentsWindow.loadComments(objectList.selectedId, Config.IS_ONLINE); + commentsWindow.visible = true; + illustrationTabs.visible = false + previousTopLevelCategoriesText = comboBox_topLevelCategories.text; + } + } + + private function processGetCommentsTotal(event:ResultEvent):void + { + var total:int = parseInt(event.result.toString()); + button_comments.label = "Comments (" + total + ")"; + } + + private function processGetCommentsTotal_fault():void + { + //Alert.show('An Internet connection is required', 'Offline'); + } + */ + + private function HTTP_logView_fault(event:FaultEvent):void + { + //Alert.show('An Internet connection is required' + event.message, 'Offline'); + } + + //-------------------------------------------------------------------------- + // Search window + //-------------------------------------------------------------------------- + private function button_search_click(event:MouseEvent):void + { + // Kill the movie and it's background if it exists + //if (this.contains(movieBackground)) closeSplash(); + + if(button_search.selected) + { + if(commentsWindow.visible) + hasSearchOpenedWhileCommenting = true; + + closeQuickStart(); + + commentsWindow.visible = false; + searchWindow.visible = true; + illustrationTabs.visible = false; + comboBox_topLevelCategories.enabled = false; + previousTopLevelCategoriesText = comboBox_topLevelCategories.text; + comboBox_topLevelCategories.text = "All"; + } + else + { + searchWindow.visible = false; + comboBox_topLevelCategories.enabled = true; + comboBox_topLevelCategories.text = previousTopLevelCategoriesText; + } + } + + private function searchWindow_submit(event:Event):void + { + toggleButtonBar_treeList.selectedIndex = 1; + objectList.showTreeView(false); + } + + //-------------------------------------------------------------------------- + // Shared wipe-window functionality and coordination + //-------------------------------------------------------------------------- + private function wipedWindow_hide(event:FlexEvent):void + { + if(!hasSearchOpenedWhileCommenting) + { + illustrationTabs.visible = true; + button_search.selected = false; + comboBox_topLevelCategories.enabled = true; + comboBox_topLevelCategories.text = previousTopLevelCategoriesText; + } + + hasSearchOpenedWhileCommenting = false; + } + + //-------------------------------------------------------------------------- + // Download window + //-------------------------------------------------------------------------- + private function button_download_click(event:MouseEvent):void + { + if(objectList.selectedId > 0) + { + illustrationTabs.visible = false; + + /*if (this.isPlugin && pluginTransferObject!=null) + { + var pluginPopup:PluginDownloadWindow = new PluginDownloadWindow(); + pluginPopup.addEventListener(FlexEvent.REMOVE, downloadWindow_close); + PopUpManager.addPopUp(pluginPopup, this, true); + PopUpManager.centerPopUp(pluginPopup); + pluginPopup.download(selectedDownloadPath, pluginTransferObject.pluginDownloadPath, Config.LOCAL_OBJECTS_ROOT_PATH); + } + else {*/ + var popup:DownloadWindow = new DownloadWindow(); + popup.addEventListener(FlexEvent.REMOVE, downloadWindow_close); + PopUpManager.addPopUp(popup, this, true); + PopUpManager.centerPopUp(popup); + popup.download(selectedDownloadPath, Config.LOCAL_OBJECTS_ROOT_PATH); + /*}*/ + } + } + + private function button_browser_click(eveng:MouseEvent):void { + navigateToURL(new URLRequest(selectedIllustrationURL)); + } + + private function downloadWindow_close(event:FlexEvent):void + { + illustrationTabs.visible = true; + } + + //-------------------------------------------------------------------------- + // Plugin related + //-------------------------------------------------------------------------- + // ----- ADDED THE REST OF THE SCRIPT... HS + /** + * Handle the Merapi communication from the plug-in + private function handleResponse(event:Event):void + { + var ev:ResultEvent = ResultEvent(event); + var msg:Message = Message(ev.result); + if (msg.type == "FindComponents") { + if (msg.data != null) { + var msgType:String = msg.type; + comps = objectData.getFilteredComponents(String(msg.data)); + + } + var m : Message = new Message(); + m.type = "FindComponents"; + m.data = comps; + bridge.sendMessage(m); + } + else if (msg.type == "SendPluginTO") { + pluginTransferObject = TDFPluginTransferObject(msg.data); + } + else if (msg.type == "Minimize") { + this.minimize(); + } + else if (msg.type == "Dock") { + this.dock(); + } + else if (msg.type == "Undock") { + // We need to figure out what the download path is from the returned message and set it + if (msg.data != null) { + pluginTransferObject = TDFPluginTransferObject(msg.data); + this.objectList_change(null); // Fire the navigation to the component double-clicked from plugin + } + this.undock(event); + } + else if (msg.type == "Exit") { + isPlugin = false; + onExiting(event); + } + } + **/ + + + /** + * Prepare for docking + */ + public function prepareForSystray(event:Event):void { + // Immediately send featured component list to plugin, if plugin invoked + //if (isPlugin) sendFeatured(); + + if (event!=null) + // Retrieve the image being used as the systray icon + dockImage = event.target.content.bitmapData; + + // If this is Mac... + if (NativeApplication.supportsDockIcon) + { + setDockProperties(); + DockIcon(NativeApplication.nativeApplication.icon).menu = createSystrayRootMenu(); + } + else + { + setSystemTrayProperties(); + SystemTrayIcon(NativeApplication.nativeApplication.icon).menu = createSystrayRootMenu(); + } + // If we are using this independent of the plug-in, we want to undock it because it was opened in + // docked mode and non-visible so that when the plug-in opens it, it does not flash onto the screen. + if (!isPlugin){ + this.undock(null); + } + else this.dock(); + } + + /** + * Create a menu that can be accessed from the systray + */ + private function createSystrayRootMenu():NativeMenu{ + var menu:NativeMenu = new NativeMenu(); + var openNativeMenuItem:NativeMenuItem = new NativeMenuItem("Open"); + var exitNativeMenuItem:NativeMenuItem = new NativeMenuItem("Exit"); + + openNativeMenuItem.addEventListener(Event.SELECT, undock); + exitNativeMenuItem.addEventListener(Event.SELECT, onExiting); + + menu.addItem(openNativeMenuItem); + menu.addItem(exitNativeMenuItem); + + return menu; + } + + /** + * Add event listeners + */ + private function setDockProperties():void { + //Listen to the display state changing of the window, so that we can catch the minimize and dock + stage.nativeWindow.addEventListener(NativeWindowDisplayStateEvent.DISPLAY_STATE_CHANGING, processMinimized); //Catch the minimize event + } + /** + * To be able to dock and undock we need to set some eventlisteners + */ + private function setSystemTrayProperties():void { + SystemTrayIcon(NativeApplication.nativeApplication.icon).tooltip = "Tour de Flex"; + + SystemTrayIcon(NativeApplication.nativeApplication.icon).addEventListener(MouseEvent.CLICK, undock); + stage.nativeWindow.addEventListener(NativeWindowDisplayStateEvent.DISPLAY_STATE_CHANGING, processMinimized); //Catch the minimize event + } + + /** + * Do the appropriate actions after the windows display state has changed. + * E.g. dock when the user clicks on minimize + * + */ + private function processMinimized(displayStateEvent:NativeWindowDisplayStateEvent):void { + // prevent the minimize + if(displayStateEvent.afterDisplayState == NativeWindowDisplayState.MINIMIZED) { + displayStateEvent.preventDefault(); + + //Dock instead + dock(); + } + } + + /** + * Do our own 'minimize' by docking the application to the systray (showing the application icon in the systray) + */ + public function dock():void { + // Hide the applcation + stage.nativeWindow.visible = false; + + //Setting the bitmaps array will show the application icon in the systray + NativeApplication.nativeApplication.icon.bitmaps = [dockImage]; + + } + + /** + * Show the application again and remove the application icon from the systray + * + */ + public function undock(evt:Event):void { + // After setting the window to visible, make sure that the application is ordered to the front, + // else we'll still need to click on the application on the taskbar to make it visible + stage.nativeWindow.visible = true; + stage.nativeWindow.restore(); + stage.nativeWindow.orderToFront(); + stage.nativeWindow.activate(); + + // Clearing the bitmaps array also clears the applcation icon from the systray + NativeApplication.nativeApplication .icon.bitmaps = []; + + // Force the application to the front with focus, then allow user to switch to other apps + if (isPlugin) { + this.alwaysInFront = true + this.activate(); + this.alwaysInFront = false; + } + } + + private function expandIllustration():void { + documentTabs.needHtmlHack = false; + + if (expandMode == 0) { + sideBar.setStyle("resizeEffect", expandEffect); + sideBar.width = 0; + if (illustrationAutoExpanded) + { + expandMode = 3; + } else { + expandMode = 1; + } + } else if (expandMode == 1) { + docBox.setStyle("resizeEffect",expandEffect); + illBox.setStyle("resizeEffect",null); + sideBar.setStyle("resizeEffect", expandEffect); + vdivider.moveDivider(0,vdivider.height); + sideBar.width = 0; + expandMode=2; + } else if (expandMode == 2) { + docBox.setStyle("resizeEffect",null); + illBox.setStyle("resizeEffect",expandEffect); + vdivider.moveDivider(0, - (vdivider.height)); + expandMode=3; + } else if (expandMode == 3) { + docBox.setStyle("resizeEffect",expandEffect); + illBox.setStyle("resizeEffect",null); + sideBar.width=230; + vdivider.moveDivider(0, + (vdivider.height/2)); + expandMode=0; + } + } + + //-------------------------------------------------------------------------- + //-------------------------------------------------------------------------- + + ]]> + </mx:Script> + + <!-- + <mx:HTTPService id="HTTP_GetCommentsTotal" showBusyCursor="false" result="processGetCommentsTotal(event)" resultFormat="e4x" fault="processGetCommentsTotal_fault()" url="{Config.DATA_EXCHANGE_URL}" useProxy="false" method="POST"> + <mx:request xmlns=""> + <Request>GetCommentsTotal</Request> + <ObjectId>{objectList.selectedId}</ObjectId> + </mx:request> + </mx:HTTPService> + --> + + <mx:HTTPService id="HTTP_logView" showBusyCursor="false" resultFormat="e4x" fault="HTTP_logView_fault(event)" url="{Config.DATA_EXCHANGE_URL}" useProxy="false" method="POST"> + <mx:request xmlns=""> + <Request>logView</Request> + <ObjectId>{objectList.selectedId}</ObjectId> + <ObjectName>{label_objectName.text}</ObjectName> + </mx:request> + </mx:HTTPService> + + <mx:Resize id="expandEffect" duration="200" /> + <mx:VBox width="100%" height="100%" verticalGap="0" styleName="mainWindow"> + <components:ApplicationHeader id="applicationHeader" /> + <mx:HDividedBox styleName="mainBackground" width="100%" height="100%" paddingBottom="0" paddingLeft="12" paddingRight="0" paddingTop="7"> + + <mx:VBox id="sideBar" styleName="outerDividedBoxes" width="245" minWidth="0" height="100%" horizontalScrollPolicy="off" > + <mx:HBox width="100%" paddingRight="6"> + <mx:ToggleButtonBar width="60" id="toggleButtonBar_treeList" itemClick="toggleButtonBar_treeList_itemClick(event)" > + <mx:dataProvider> + <mx:Object id="toggle_tree" icon="@Embed('images/toggle_tree.png')" toolTip="View Tree" /> + <mx:Object id="toggle_list" icon="@Embed('images/toggle_list.png')" toolTip="View List" /> + </mx:dataProvider> + </mx:ToggleButtonBar> + <mx:HBox width="100%" horizontalAlign="right"> + <mx:Button id="button_search" label="Search » Filter" toggle="true" click="button_search_click(event)" labelPlacement="left" styleName="searchButton"/> + </mx:HBox> + </mx:HBox> + <mx:ComboBox id="comboBox_topLevelCategories" height="0" visible="false" rowCount="10" width="97%" dataProvider="{objectData.topLevelCategoriesXml}" change="comboBox_topLevelCategories_change(event)" /> + <components:ObjectList id="objectList" treeDataProvider="{objectData.treeXml}" listDataProvider="{objectData.listXml}" change="objectList_change(event)" sortChange="objectList_sortChange(event)"/> + </mx:VBox> + + <mx:Canvas id="box_illustrationsAndDocumentsOuterContainer" width="100%" height="100%"> + <mx:VBox id="box_illustrationsAndDocuments" styleName="outerDividedBoxes" width="100%" height="100%" horizontalAlign="right" paddingRight="30" > + <mx:HBox id="box_illustrationControls" width="100%"> + <mx:Label id="label_objectName" fontSize="10" fontWeight="bold" /> + <mx:HBox width="100%" horizontalAlign="right" verticalAlign="middle"> + <mx:LinkButton id="button_comments" click="button_comments_click(event)" label="Comments" fontSize="9" enabled="false" styleName="commentButton" /> + <mx:LinkButton id="button_download" click="button_download_click(event)" label="Download" fontSize="9" enabled="false" styleName="downloadButton" /> + <mx:LinkButton id="button_browser" click="button_browser_click(event)" label="Open in Browser" fontSize="9" enabled="false" styleName="buttonBrowser" /> + <mx:LinkButton id="button_expand" click="expandIllustration()" label="Toggle Layout" fontSize="9" enabled="false" styleName="maximizeButton" /> + </mx:HBox> + </mx:HBox> + <mx:VDividedBox id="vdivider" width="100%" height="100%"> + <mx:VBox id="illBox" styleName="illustrationsBox" width="100%" height="100%" > + <components:IllustrationTabs id="illustrationTabs" change="illustrationTabs_change(event)" /> + </mx:VBox> + <mx:VBox id="docBox" styleName="illustrationsBox" width="100%" height="100%"> + <components:DocumentTabs id="documentTabs"/> + </mx:VBox> + </mx:VDividedBox> + </mx:VBox> + <mx:VBox width="100%" height="100%" paddingBottom="5" paddingRight="10"> + <components:QuickStartWindow id="quickStartWindow" close="closeQuickStart(event)" width="100%" height="100%" /> + </mx:VBox> + </mx:Canvas> + </mx:HDividedBox> + + <components:ApplicationFooter /> + + </mx:VBox> + + <!--<mx:Box id="movieBackground" backgroundColor="black" x="{splashWindow.x}" y="{splashWindow.y}" width="{splashWindow.width}" height="{splashWindow.height}"/>--> + + <components:CommentsWindow id="commentsWindow" visible="false" hideComplete="wipedWindow_hide(event)" x="{box_illustrationsAndDocuments.x}" y="{box_illustrationsAndDocuments.y + applicationHeader.height}" width="{box_illustrationsAndDocuments.width}" height="{box_illustrationsAndDocuments.height}"/> + <components:SearchWindow id="searchWindow" visible="false" searchSubmit="searchWindow_submit(event)" objectData="{objectData}" searchTagsData="{objectData.searchTags}" hideComplete="wipedWindow_hide(event)" x="{box_illustrationsAndDocumentsOuterContainer.x}" y="{box_illustrationsAndDocumentsOuterContainer.y + applicationHeader.height}" width="{box_illustrationsAndDocumentsOuterContainer.width}" height="{box_illustrationsAndDocumentsOuterContainer.height}"/> +</mx:WindowedApplication> http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/e1f9d1df/TourDeFlex/TourDeFlex/src/classes/ApplicationUpdaterManager.as ---------------------------------------------------------------------- diff --git a/TourDeFlex/TourDeFlex/src/classes/ApplicationUpdaterManager.as b/TourDeFlex/TourDeFlex/src/classes/ApplicationUpdaterManager.as new file mode 100644 index 0000000..4a69b36 --- /dev/null +++ b/TourDeFlex/TourDeFlex/src/classes/ApplicationUpdaterManager.as @@ -0,0 +1,55 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// 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. +// +//////////////////////////////////////////////////////////////////////////////// +package classes +{ + import air.update.ApplicationUpdaterUI; + import air.update.events.UpdateEvent; + + import flash.desktop.NativeApplication; + import flash.events.ErrorEvent; + import flash.events.Event; + + import mx.controls.Alert; + + public class ApplicationUpdaterManager + { + private var appUpdater:ApplicationUpdaterUI = new ApplicationUpdaterUI(); + + public function ApplicationUpdaterManager() + { + appUpdater.updateURL = Config.APP_UPDATER_URL; + appUpdater.isCheckForUpdateVisible = false; + //appUpdater.isInstallUpdateVisible = false; + appUpdater.addEventListener(ErrorEvent.ERROR, appUpdater_error); + appUpdater.addEventListener(UpdateEvent.INITIALIZED, appUpdater_update); + appUpdater.initialize(); + } + + private function appUpdater_update(event:UpdateEvent):void + { + appUpdater.checkNow(); + } + + private function appUpdater_error(event:ErrorEvent):void + { + Alert.show(event.toString()); + } + + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/e1f9d1df/TourDeFlex/TourDeFlex/src/classes/Document.as ---------------------------------------------------------------------- diff --git a/TourDeFlex/TourDeFlex/src/classes/Document.as b/TourDeFlex/TourDeFlex/src/classes/Document.as new file mode 100644 index 0000000..e029609 --- /dev/null +++ b/TourDeFlex/TourDeFlex/src/classes/Document.as @@ -0,0 +1,35 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// 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. +// +//////////////////////////////////////////////////////////////////////////////// +package classes +{ + public class Document + { + public var name:String = ""; + public var path:String = ""; + public var openLinksExternal:String = ""; + + public function Document(name:String = "", path:String = "", openLinksExternal:String = "") + { + this.name = name; + this.path = path; + this.openLinksExternal = openLinksExternal; + } + + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/flex-utilities/blob/e1f9d1df/TourDeFlex/TourDeFlex/src/classes/LocalQuickStart.as ---------------------------------------------------------------------- diff --git a/TourDeFlex/TourDeFlex/src/classes/LocalQuickStart.as b/TourDeFlex/TourDeFlex/src/classes/LocalQuickStart.as new file mode 100644 index 0000000..f3cbdbf --- /dev/null +++ b/TourDeFlex/TourDeFlex/src/classes/LocalQuickStart.as @@ -0,0 +1,159 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// 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. +// +//////////////////////////////////////////////////////////////////////////////// +package classes +{ + /******************************** + * This class has been deprecated + *********************************/ + + + import flash.events.Event; + import flash.events.IOErrorEvent; + import flash.filesystem.File; + import flash.filesystem.FileMode; + import flash.filesystem.FileStream; + import flash.net.SharedObject; + import flash.net.URLLoader; + import flash.net.URLRequest; + import flash.system.Capabilities; + + public class LocalQuickStart + { + + //-------------------------------------------------------------------------- + // Variables + //-------------------------------------------------------------------------- + public static var url:String = "quickstart.html"; + + private static var cookieName:String = "TourDeFlex"; + private static var onlineVersion:String = ""; + private static var localLanguage:String = "en"; + private static var onlineVersionUrl:String = ""; + + + //-------------------------------------------------------------------------- + // Load/setup + //-------------------------------------------------------------------------- + public function LocalQuickStart() + { + } + + public static function update():void + { + var staticContainerPath:String = "data/"; + var updatableFile:File = File.applicationStorageDirectory.resolvePath(url); + var staticFile:File = File.applicationDirectory.resolvePath(staticContainerPath + url); + + localLanguage = Capabilities.language.toLowerCase(); + //localLanguage = "jp"; + + if(localLanguage != "en") + { + var newUrl:String = Config.appendLanguage(url, localLanguage); + var newStaticFile:File = File.applicationDirectory.resolvePath(staticContainerPath + newUrl); + if(newStaticFile.exists) + staticFile = newStaticFile; + } + + if(Config.isAppFirstTimeRun() || !updatableFile.exists) + staticFile.copyTo(updatableFile, true); + + url = updatableFile.url; + + checkForNewLocalQuickStart(); + } + + //-------------------------------------------------------------------------- + // Helper/shared functions + //-------------------------------------------------------------------------- + private static function checkForNewLocalQuickStart():void + { + var loader:URLLoader = new URLLoader(new URLRequest(Config.QUICK_START_LOCAL_UPDATER_URL)); + loader.addEventListener(Event.COMPLETE, updaterXmlLoaded); + loader.addEventListener(IOErrorEvent.IO_ERROR, updaterXmlLoadedError); + } + + private static function updaterXmlLoadedError(event:IOErrorEvent):void + { + } + + private static function updaterXmlLoaded(event:Event):void + { + var loader:URLLoader = URLLoader(event.target); + var updaterXml:XML = new XML(loader.data); + + var currentVersion:String = "0"; + var cookie:SharedObject = SharedObject.getLocal(cookieName); + if(cookie.data.localQuickStartVersion != null) + currentVersion = cookie.data.localQuickStartVersion; + + onlineVersion = updaterXml.version; + var onlineVersionDescription:String = updaterXml.description; + + if(onlineVersion > currentVersion) + { + onlineVersionUrl = updaterXml.url; + downloadNewVersion(onlineVersionUrl); + if(onlineVersionDescription.length > 0) + { + // Only show notice if a description was provided, otherwise, silent install + //Alert.show(onlineVersionDescription, "Updated to Version " + onlineVersion); + } + } + } + + private static function downloadNewVersion(path:String):void + { + if(localLanguage != "en") + path = Config.appendLanguage(path, localLanguage); + + var loader:URLLoader = new URLLoader(new URLRequest(path)); + loader.addEventListener(Event.COMPLETE, updatedVersionLoaded); + loader.addEventListener(IOErrorEvent.IO_ERROR, updatedVersionLoadingError); + } + + private static function updatedVersionLoadingError(event:IOErrorEvent):void + { + var loader:URLLoader = new URLLoader(new URLRequest(onlineVersionUrl)); + loader.addEventListener(Event.COMPLETE, updatedVersionLoaded); + loader.addEventListener(IOErrorEvent.IO_ERROR, updatedVersionLoadingError); + } + + private static function updatedVersionLoaded(event:Event):void + { + var file:File = File.applicationStorageDirectory; + file = file.resolvePath(url); + if(file.exists) + file.deleteFile(); + + var loader:URLLoader = URLLoader(event.target); + + var fileStream:FileStream = new FileStream(); + fileStream.open(file, FileMode.WRITE); + fileStream.writeUTFBytes(loader.data); + fileStream.close(); + + var cookie:SharedObject = SharedObject.getLocal(cookieName); + cookie.data.localQuickStartVersion = onlineVersion; + cookie.flush(); + } + //-------------------------------------------------------------------------- + //-------------------------------------------------------------------------- + } +} \ No newline at end of file