How to create an exit button in a full screen swf file? - actionscript-3

I'm currently making my thesis in Flash. Does anyone know how to put a warning before quitting the app? Like when a user clicks the "X" button, a "Are you sure you want to quit? Yes? No?" will pop up? Also, it is on a f
So far, my code for the Exit button is
addEventListener(MouseEvent.CLICK, CloseApp);
function CloseApp(e:MouseEvent) {
fscommand("quit");
}
hence, when click, it automatically closes the app. Thank you very much!

The following piece of code illustrates how to achieve this result using Adobe AIR & Flex SDK.
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
closing="onClosingMainWindow(event)">
<fx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.events.CloseEvent;
protected function onClosingMainWindow(event:Event):void
{
event.preventDefault();
Alert.show('Are you sure?','',Alert.YES|Alert.NO,null,function(event:CloseEvent):void{
if(event.detail == Alert.YES)
nativeApplication.exit();
});
}
]]>
</fx:Script>
</s:WindowedApplication>
And the same result using Adobe AIR in Flash Pro. (Pure AS3)
import flash.desktop.NativeApplication;
import flash.events.Event;
//activeWindow will be null until the frame will not be constructed.
stage.addEventListener(Event.FRAME_CONSTRUCTED, onFrameConstructed);
function onFrameConstructed(event:Event){
stage.removeEventListener(Event.FRAME_CONSTRUCTED, onFrameConstructed);
NativeApplication.nativeApplication.activeWindow.addEventListener(Event.CLOSING, onClosingMainWindow);
}
function onClosingMainWindow(event:Event):void
{
event.preventDefault();
//The following code will close the app.
//NativeApplication.nativeApplication.exit();
}

import flash.desktop.NativeApplication;
import flash.events.Event;
addEventListener(MouseEvent.CLICK, CloseApp);
function CloseApp(e:MouseEvent) {
stage.nativeWindow.close();
}
should do the job

//Just add following script in button
href="javascript: history.go(-1)"

Related

Trace in FlashBuilder 4.7 not working

I'm using FlashBuilder 4.7 and Flex SDK 4.11.
I've created new Mobile Flex Project and created 2 files in default package:
bestPairs.mxml:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:bestpairs="*"
width="640"
height="480">
<s:layout>
<s:BasicLayout />
</s:layout>
<s:Label text="Hello World!" horizontalCenter="0" verticalCenter="0" />
<s:Button id="myButton"/>
</s:Application>
Main.as:
package
{
import flash.events.MouseEvent;
import mx.events.FlexEvent;
import spark.components.Button;
import spark.components.Group;
public class Main extends Group
{
public var myButton:Button;
public function Main()
{
super();
this.addEventListener(FlexEvent.CREATION_COMPLETE, onCreationComplete);
trace("main!");
}
private function onCreationComplete(e:FlexEvent):void {
this.removeEventListener(FlexEvent.CREATION_COMPLETE, onCreationComplete);
myButton.addEventListener(MouseEvent.CLICK, onClick);
}
private function onClick(e:MouseEvent):void {
// Do something
trace("clicked!");
}
}
}
because I want to split code from design. Anyway trace are not showing at all. In Debug Mode too. I tried also this: https://stackoverflow.com/a/3627826/1264375 (I made flex-config.xml file in src/config and added parameter to compiler - http://blog.flexexamples.com/2008/12/21/using-a-custom-flex-configxml-file-in-flex-builder-3/) and other googled solutions. Nothing is working I just see this:
[SWF] bestPairs.swf - 3,190,645 bytes after decompression
and later on:
[Unload SWF] bestPairs.swf
I'm using iPhone4 Air simulator to test app.
Is there any way to display trace logs? It's hard to develop without them.
Any help will be appreciated,
Regards!
Unless I am missing something, you never add a Main object to your application. For the trace to occur, you have to instantiate an instance of Main. Prior to that, none of the code in that class will run

Air application hangs instead of throwing MemoryError

I'm trying to make my application throw MemoryError by creating a very long string, but it hangs instead of throwing it.
I tried this with air sdk 3.4 and 3.8, both release and debug builds.
Sometimes when I close the app in a force way, eclipse shows something like app exited with error code:out of memory.
I also noticed that console contains line [Unload SWF] myapp.swf after executing the code(if you add trace(str.length) after doubling the string, you'll see that it happens after length 369098752).
You can see here AS3 Reference for MemoryError that this is legitimate way of causing MemoryError.
So, how can I really catch those MemoryErrors instead of allowing app to crash?
Here is my code:
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
creationComplete="onCreation(event)"
>
<fx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.events.FlexEvent;
import avmplus.getQualifiedClassName;
protected var str:String = 'ssssssssssssssssssssss';
protected function onCreation(event:FlexEvent):void{
var serverString:String = unescape(Capabilities.serverString);
try{
while(true){
str+=str;
}
}catch(e:MemoryError){
Alert.show('memoryError');
}
}
]]>
</fx:Script>
</s:WindowedApplication>
update:
I improved test app, now you can clearly see that no error or uncaught error is thrown.
It crashes when memory usage reaches 1700-1750MB.
I found some bugs that resemble my case in bugbase, but they are related to air 2.x and marked as fixed/not a bug. I can't find any similar bug for air 3.x.
Bug: App crashes when allocates >1.7GB
Bug: App crashes when approaches 2GB
Can anybody reproduce?
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
applicationComplete="onCreation(event)"
>
<fx:Script>
<![CDATA[
import flash.utils.setInterval;
import mx.controls.Alert;
import mx.events.FlexEvent;
import avmplus.getQualifiedClassName;
protected var vectors:Vector.<Vector.<uint>>= new Vector.<Vector.<uint>>();
protected function onCreation(event:FlexEvent):void{
loaderInfo.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR,onUncaughtError);
var serverString:String = unescape(Capabilities.serverString);
trace('vm version: '+System.vmVersion);
setInterval(increaseMemoryUsage,100);
}
protected function increaseMemoryUsage():void{
try{
var vector:Vector.<uint> = new Vector.<uint>();
vector.length = 1024*1024/4;//1MB
vectors.push(vector);
System.gc();
trace(vectors.length*1+'MB');
trace('total: '+System.totalMemoryNumber+', private: '+System.privateMemory+', free: '+System.freeMemory);
totalMemoryDisplay.text=''+int(System.totalMemoryNumber/(1024*1024))+'MB';
}catch(e:MemoryError){
trace('it catches!');
Alert.show('memoryError');
}catch(e:Error){
trace('error'+e.errorID);
}
}
protected function onUncaughtError(e:UncaughtErrorEvent):void{
trace('it is uncaught!');
}
]]>
</fx:Script>
<s:Label id="totalMemoryDisplay" />
</s:WindowedApplication>

Weird crash in AIR application

I have a crash that only happens with the installed application I can't make it cvrash in the IDE(Flash Builder debug or run option)
After a long time of commenting and uncomenting code I found the problem and I am posting the code below
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:ns="generic_components.*"
creationComplete="windowedapplication1_creationCompleteHandler(event)">
<fx:Script>
<![CDATA[
//import core.Logger;
import mx.controls.Alert;
import mx.events.FlexEvent;
import spark.events.TextOperationEvent;
protected function windowedapplication1_creationCompleteHandler(event:FlexEvent):void
{
//Logger.init();
}
public static function humanFromCamelCase(txt:String):String{
var res:String=txt.charAt(0);
//Logger.write("camel case for "+txt);
for (var i:int=1;i<txt.length;i++)
{
// Logger.write("camel iter "+i);
var c:String=txt.charAt(i);
//Logger.write("camel char is "+c);
if(c==c.toUpperCase())
{
res=res+" "+c;
}
else
res=res+c;
}
return res;
}
protected function test_clickHandler(event:Event):void
{
Alert.show(humanFromCamelCase("CompanyId"));
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:layout>
<s:VerticalLayout />
</s:layout>
<s:Button id="test" label="TEST" click="test_clickHandler(event)"/>
</s:WindowedApplication>
Also see a web sample here http://ploscariu.com/crash/TestWeb.html (may be not there in the future)
What is weird about this crash:
1 I have no idea what happens
2 The usual crash handler in the player does not show up
3 is not crashing in the development enviroment IDE
4 if i uncomment those Logger.write then the code works on my machine fine(it could not work on all machines), the Logger.write writes the sting in a file and is placed in another project swf (I did not included the logger code)
I a, assuming that the call to Logger.write can cause a delay or something similar
It is something wrong in my code or the player is buggy? or the compiler??
Any ideas?
Edit:
-is not the logger i use since the error happens when I am not using it like in the sample code or page, no logger the app it crashes
-i get no dialog from Flash with a crash report
This is so incredibly odd!!!! I have NO idea why this happening (yet)... but I have a workaround:
Instead of res=res+c, use res+=c:
public static function humanFromCamelCase(txt:String):String{
var res:String=txt.charAt(0);
for (var i:int=1;i<txt.length;i++)
{
var c:String=txt.charAt(i);
if(c === c.toUpperCase())
{
res += " " + c;
}
else
res += c;
}
return res;
}
I have no idea why you're having an error, however, I would replace the function with this instead:
public static function humanFromCamelCase(txt:String):String{
return txt.replace(/([A-Z])/g, ' $1').replace(/^ /, "");
}
Haven't tested it, but you get the idea. This is a much simpler and faster approach.
I also thought of another way:
public static function humanFromCamelCase(txt:String):String{
return txt.split(/(?=[A-Z])/).join(' ');
}

How to run a function after the canvas has changed in ActionScript 3.0?

Please understand: I am a total beginner at Actionscript and anything like Actionscript, and though I generally have some idea of what I'm doing as a programmer, I'm having some setbacks in self-learning this language and Flex Builder. Right now I'm trying to make a very simple implementation where a label effectively has its text added to multiple times over the first few seconds that the program is run. The problem I'm running into is that I can't just put all that into one function + one call on that function, as changes to the label's text are apparently not seen until that function runs its full course.
So I tried using a viewstack and cloning the canvas a few times, giving each canvas's version of that label a different bit of text. Then I set the initialize function for the viewstack to change the canvases on regular intervals over the first few seconds. But that didn't work either, as the difference isn't seen until the function runs its full course.
So then I tried putting function calls on the individual canvases' initialize attributes, and those functions aren't being called at all apparently.
What the heck? I know this probably isn't even the way that you're supposed to animate something in ActionScript or Flex, but I still would like to know how to approach the problem this way for future reference. What am I missing? Thanks!
As you've noticed, changes to the displayed output of your program can't happen in the middle of executing a function that you've written. ActionScript is single-threaded, which means that none of the framework code that updates the screen can run while your function is running.
If you're interested in learning exactly what happens in order to update the screen, do a search for "flex component lifecycle" and read some of the stuff you find. It's a bit advanced, but it was the thing that really helped me understand how the Flex framework works.
Anyway, on to your real question - how to animate something. There are many ways, but for your case of progressively adding text to a label, I'd probably use the Timer class.
Here is an example:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
private var timer:Timer;
private var words:Array = ["The", "quick", "brown", "fox"];
private function startTimer(event:FlexEvent):void
{
timer = new Timer(1000, 1);
timer.addEventListener(TimerEvent.TIMER, updateText);
timer.start();
}
private privatefunction updateText(event:TimerEvent):void
{
theLabel.text += words.shift() + " ";
if (words.length > 0)
{
timer.reset();
timer.start();
}
}
]]>
</fx:Script>
<s:Label id="theLabel" text="" creationComplete="startTimer(event)"/>
</s:Application>
A basic approach would be to use data binding for the label value, and setTimeout() or setInterval() to cause the delay between updates.
Here is an example:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
initialize="init()"
minWidth="955" minHeight="600">
<fx:Script>
<![CDATA[
[Bindable]
private var displayString:String = "Detonation in ";
private var count:int = 5;
private var timer:uint;
private function init():void {
timer = setInterval(updateDisplay, 1000);
}
private function updateDisplay():void {
displayString += count + ".. ";
if (--count == 0) {
clearInterval(timer);
}
}
]]>
</fx:Script>
<s:Label text="{displayString}"/>
</s:Application>

FlexEvent.APPLICATION_COMPLETE never called in simple app

I've got a really simple flex application, with a main file Rec.mxml:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="215" minHeight="138" width="215" height="138" backgroundAlpha="0.0">
<fx:Script>
<![CDATA[
var rec:LRec = new LRec();
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
</s:Application>
And an AS3 class:
package
{
import mx.core.Application;
import mx.events.FlexEvent;
public class LRec extends Application
{
public function LRec()
{
trace("CONSTRUCTED");
addEventListener(FlexEvent.APPLICATION_COMPLETE, this.mainInit);
}
/**
* After the application startup is complete, debug
*/
public function mainInit(event:FlexEvent):void {
trace("COMPLETE");
}
}
}
The trace ("CONSTRUCTED") is printed, but not "COMPLETE" -- it looks like the FlexEvent.APPLICATION_COMPLETE event is never registering. Any ideas why?
Also, this is the first time I've really done this sort of programming, so if anything else looks wrong, please tell me!
I've updated your code below with some comments on where you were going wrong. If you have any other questions feel free to ask.
Test.mxml
<?xml version="1.0" encoding="utf-8"?>
<s:Application
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="215" minHeight="138" width="215" height="138" backgroundAlpha="0.0"
initialize="handle_initialize(event)"
>
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
// Probably want to keep your rec object around
private var rec:LRec;
// Construct your LRec instance in the Application's inititialize state,
// rather than declaring it statically.
protected function handle_initialize(event:FlexEvent):void
{
// Construct a new LRec instance, assign it to our private variable.
this.rec = new LRec();
// The <s:Applicaiton instance we define in this mxml is the object that
// will actually dispatch the applicationComplete event, so we want to
// listen for that here and pass it on to our LRec instance's mainInit
// method when it fires.
this.addEventListener(FlexEvent.APPLICATION_COMPLETE, this.rec.mainInit);
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
</s:Application>
LRec.as
package
{
import mx.events.FlexEvent;
// Don't inherit from Application, as you've already defined your application
// in your mxml, and you should have only one Application instance per application.
public class LRec
{
public function LRec()
{
trace("CONSTRUCTED");
// Doesn't need the event listener anymore.
// Do any instantiation needed.
}
/**
* After the application startup is complete, debug
*/
public function mainInit(event:FlexEvent):void {
trace("COMPLETE");
// Do any of the work that needs to wait for the applicationComplete
// event to fire.
}
}
}
Here's a good article (though a bit dated) on the Flex Instantiation Model.