Friday, January 27, 2012

Creating a Flex AIR Screenshot app: Part 6

In this tutorial we'll work on the url-related GUI elements.

The path the user can enter can be either an internet URL, or a local path. It is important to know that www.google.com or google.com alone won't work, http:// is required in front of the link. However, we don't know whether the path that the user entered is a local path or path to a file on the internet, and we don't know if http:// or something else is required, so we can just put "http://" by default into the text field, so that the user will just add his link to it (or replace the content completely with the link that he had copied, which is more likely).

So, find urlInput text field and put "http://" as its text value by default:

<s:TextInput width="250" id="urlInput" text="http://" />

The user should be able to enter anything in the address bar, a long as it is not blank, so let's add a check, which disables the two image buttons if the url is blank.

<custom:ImageButton img="@Embed('../lib/b_cut.png')" over="@Embed('../lib/b_cut_over.png')" toolTip="Crop area" click="goCrop();" buttonMode="true" enabled="{urlInput.text!=''}" />
<custom:ImageButton img="@Embed('../lib/b_screenshot.png')" over="@Embed('../lib/b_screenshot_over.png')" toolTip="Take screenshot" buttonMode="true" enabled="{urlInput.text!=''}" />

Now let's add some loading information to the crop stage window. We'll add 2 label objects, one of them will contain the url, and the second one will display "Loading" or "Loaded".

Add these 2 labels, set the first one's id to cropStatus and the second one's text bound to urlString,

<s:NavigatorContent id="crop">
<s:VGroup width="100%" height="100%" gap="0">
<mx:HBox backgroundColor="#999999" width="100%" height="24" verticalScrollPolicy="off" verticalAlign="middle" paddingLeft="2">
<s:Button label="Back" click="{stack.selectedChild = loadpage}" />
<s:Button label="Continue" enabled="false" />
<s:Label id="cropStatus" />
<s:Label text="{urlString}" />
</mx:HBox>
<mx:HTML width="100%" height="100%" id="cropHTML" />
</s:VGroup>
</s:NavigatorContent>

Now we have to make urlString bindable:

[Bindable]
private var urlString:String;

Go to changeState(). In the second conditional, add lines that set cropStatus' text value to Loading, as well as its color to yellow. Add a listener for its COMPLETE event and set onCropLoad function as its handler.

private function changeState():void {
if (stack.selectedChild == loadpage) {
contentBox.setStyle("horizontalAlign", "center");
urlInput.text = urlString;
cropHTML.htmlLoader.loadString("");
}
if (stack.selectedChild == crop) {
maximize();
contentBox.setStyle("horizontalAlign", "left");
cropHTML.htmlLoader.load(new URLRequest(urlString));
cropHTML.width = contentBox.width;
cropHTML.height = contentBox.height;
cropStatus.text = "Loading";
cropStatus.setStyle("color", "#ffff00");
cropHTML.addEventListener(Event.COMPLETE, onCropLoad);
}
}

The onCropLoad function sets the text to Loaded and color to white:

private function onCropLoad(evt:Event):void {
cropStatus.text = "Loaded";
cropStatus.setStyle("color", "#ffffff");
}

And that's all for today.

Full 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:custom="*"
                       xmlns:mx="library://ns.adobe.com/flex/mx" showStatusBar="false"
   width="450" height="300" creationComplete="init();">
   
   
<fx:Declarations>
<mx:ArrayCollection id="headerTitles">
<fx:Object step="Step one:" description="load a web page." />
<fx:Object step="Step two:" description="set your export preferences." />
<fx:Object step="Step two:" description="select the area you wish to crop." />
<fx:Object step="Step three:" description="set your export preferences for the cropped image." />
<fx:Object step="Final step:" description="please wait while your images are being expored." />
</mx:ArrayCollection>
</fx:Declarations>

<fx:Style>
@namespace s "library://ns.adobe.com/flex/spark";
@namespace mx "library://ns.adobe.com/flex/mx";

.descriptionText{
fontSize: 24;
color: #fff;
}

#headStep{
fontSize: 30;
fontWeight: bold;
color: #ffffbb;
}

#headDesc{
fontSize: 30;
color: #ffffff;
}
</fx:Style>

<fx:Script>
<![CDATA[
import flash.events.Event;
import flash.filesystem.File;
import flash.net.URLRequest;
import mx.events.FlexNativeWindowBoundsEvent;

[Bindable]
private var urlString:String;

private function init():void {
addEventListener(FlexNativeWindowBoundsEvent.WINDOW_RESIZE, onResize);
}

private function doBrowse():void{
var file:File = new File();
file.addEventListener(Event.SELECT, browseSelect);
file.browseForOpen("Load a webpage");

function browseSelect(evt:Event):void {
urlInput.text = file.nativePath;
}
}

private function goCrop():void {
stack.selectedChild = crop;
urlString = urlInput.text;
}

private function changeState():void {
if (stack.selectedChild == loadpage) {
contentBox.setStyle("horizontalAlign", "center");
urlInput.text = urlString;
cropHTML.htmlLoader.loadString("");
}
if (stack.selectedChild == crop) {
maximize();
contentBox.setStyle("horizontalAlign", "left");
cropHTML.htmlLoader.load(new URLRequest(urlString));
cropHTML.width = contentBox.width;
cropHTML.height = contentBox.height;
cropStatus.text = "Loading";
cropStatus.setStyle("color", "#ffff00");
cropHTML.addEventListener(Event.COMPLETE, onCropLoad);
}
}

private function onCropLoad(evt:Event):void {
cropStatus.text = "Loaded";
cropStatus.setStyle("color", "#ffffff");
}

private function onResize(evt:Event):void {
if (stack.selectedChild == crop) {
cropHTML.width = contentBox.width;
cropHTML.height = contentBox.height;
}
}
]]>
</fx:Script>
   
<s:VGroup width="100%" height="100%" gap="0">
<mx:HBox backgroundColor="#333333" height="46" width="100%" paddingTop="10" paddingLeft="10">
<s:Label id="headStep" text="{headerTitles.getItemAt(stack.selectedIndex).step}" />
<s:Label id="headDesc" text="{headerTitles.getItemAt(stack.selectedIndex).description}" />
</mx:HBox>
<mx:Box backgroundColor="#666666" width="100%" height="100%" id="contentBox" horizontalAlign="center">
<mx:ViewStack id="stack" change="changeState();">
<s:NavigatorContent id="loadpage">
<s:VGroup width="100%" horizontalAlign="center" paddingTop="20">
<s:Label styleName="descriptionText">Enter the link to the page:</s:Label>
<s:HGroup>
<s:TextInput width="250" id="urlInput" text="http://" /><s:Button label="Browse local..." click="doBrowse();" />
</s:HGroup>
<s:HGroup>
<custom:ImageButton img="@Embed('../lib/b_cut.png')" over="@Embed('../lib/b_cut_over.png')" toolTip="Crop area" click="goCrop();" buttonMode="true" enabled="{urlInput.text!=''}" />
<custom:ImageButton img="@Embed('../lib/b_screenshot.png')" over="@Embed('../lib/b_screenshot_over.png')" toolTip="Take screenshot" buttonMode="true" enabled="{urlInput.text!=''}" />
</s:HGroup>
</s:VGroup>
</s:NavigatorContent>

<s:NavigatorContent id="screenshotsettings">

</s:NavigatorContent>

<s:NavigatorContent id="crop">
<s:VGroup width="100%" height="100%" gap="0">
<mx:HBox backgroundColor="#999999" width="100%" height="24" verticalScrollPolicy="off" verticalAlign="middle" paddingLeft="2">
<s:Button label="Back" click="{stack.selectedChild = loadpage}" />
<s:Button label="Continue" enabled="false" />
<s:Label id="cropStatus" />
<s:Label text="{urlString}" />
</mx:HBox>
<mx:HTML width="100%" height="100%" id="cropHTML" />
</s:VGroup>
</s:NavigatorContent>

<s:NavigatorContent id="cropsettings">

</s:NavigatorContent>

<s:NavigatorContent id="export">

</s:NavigatorContent>
</mx:ViewStack>
</mx:Box>
</s:VGroup>

</s:WindowedApplication>

Thanks for reading!

No comments:

Post a Comment