How to implement background images on Spark control buttons with scale 9

June 8th, 2009

Hopefully this quick post will be a bit of a time saver for Flex Developers developing Flex 4 SDK projects with Flash Builder or other tools…

Over the last year or 2 I’ve really got comfortable with reskinning Flex 3 applications. For me the quickest, simlest way has usually been to cut up the designer’s photoshop file and implement Scale 9 and syntax in my Flex css files - an example of a recent Flex 3 button skin looked like this:

.answerButton
{
fontSize    : 44px;
fontWeight    : bold;
paddingLeft    : 15px;
paddingRight: 15px;

upSkin        : Embed(source=”assets/images/new/buttons/answerButtonUp.png”,scaleGridTop=”20″, scaleGridLeft=”19″, scaleGridRight=”145″,  scaleGridBottom=”99″);
overSkin    : Embed(source=”assets/images/new/buttons/answerButtonOver.png”,scaleGridTop=”20″, scaleGridLeft=”19″, scaleGridRight=”145″,  scaleGridBottom=”99″);
downSkin    : Embed(source=”assets/images/new/buttons/answerButtonOver.png”,scaleGridTop=”20″, scaleGridLeft=”19″, scaleGridRight=”145″,  scaleGridBottom=”99″);
disabledSkin: Embed(source=”assets/images/new/buttons/answerButtonUp.png”,scaleGridTop=”20″, scaleGridLeft=”19″, scaleGridRight=”145″,  scaleGridBottom=”99″);
selectedDisabledSkin: Embed(source=”assets/images/new/buttons/answerButtonUp.png”,scaleGridTop=”20″, scaleGridLeft=”19″, scaleGridRight=”145″,  scaleGridBottom=”99″);

}

Luckily for me the Flex 4 SDK is backwards compatible for the most part so you can still skin an mx.controls.Button component with the CSS above.

However… one of the reasons I’ve been migrating my Flex 3 project to Flex 4 is to make use of some of the skinning improvements it offers with it’s new Spark components built on top of the Flex 3 halo components.

The code above does not work on a spark.components.Button. I assumed it would… Here’s how I got the example below to work:

http://www.nickkuh.com/demos/gumbo/scale_nine/

Step 1) Create a new Flex Project in Flash Builder

Step 2) You can still customize the label colours and states but you’ll need to implement the new namespaces in CSS introduced in Flex 4 to avoid warnings and errors - see the gumbo_scale_nine.css file.

Step 3) You’ll also notice within the gumbo_scale_nine.css file that I’m pointing a custom style (’answerButton’) to an MXML skin file in the location com.nickkuh.skins.AnswerButtonSkin.mxml. This is the file that I’ve used to custom skin the spark button component. I copied the ButtonSkin.mxml file that comes with Flex 4, stipped out a load of fills and strokes I didn’t require and add these important lines:

<s:BitmapImage left=”0″ right=”0″ top=”0″ bottom=”0″ source=”@Embed(source=’assets/answerButtonUp.png’,scaleGridTop=’20′, scaleGridLeft=’19′, scaleGridRight=’145′,  scaleGridBottom=’99′)” resizeMode=”scale” includeIn=”up” />

<s:BitmapImage left=”0″ right=”0″ top=”0″ bottom=”0″ source=”@Embed(source=’assets/answerButtonOver.png’,scaleGridTop=’20′, scaleGridLeft=’19′, scaleGridRight=’145′,  scaleGridBottom=’99′)” resizeMode=”scale” excludeFrom=”up” />

By default the resizeMode parameter will just tile and repeat your graphic which wasn’t the desired functionality.

So that’s it. Although it took more step to reskin than a Flex 3 component I can certainly see the benefits of the separate FXG skin file. Next step is to change that SimpleText labelElement into a RichEditableText component and enable multilines and imline images into my Spark buttons. Wish me luck!

Getting 0,0 for multiple touches on iPhone?

May 25th, 2009

It’s taken a while for me to discover the simple solution as to why one of my 2 UITouch objects when grabbing the allTouches set from the iPhone SDK touchesMoved event always resulted in 0,0 co-ordinates in my view…

NSSet *allTouches = [event allTouches];

Solution: you need to switch on the multipleTouchEnabled property of the view you want to get multiple touch events from!! ie:

[self.view setMultipleTouchEnabled:YES];

Hope this post helps others…

Unexpected scroll results with HBox/VBox/Containers using percent height/width

April 2nd, 2009

The objective:

The screen grab below is taken from a Flex application I’m building. This page of the app comprises of 2 VBoxes inside an HBox. The 2 VBoxes need to size to 100% of the height of the HBox container. The user can edit any of the text fields. When the user edits the body text of the left column, if they use up all the vertical space of that left VBox then I’d like the VBox containing the title and the boy text to create scroll bars, not to resize it’s parent VBox. Simple right?

Not so simple… Here’s a snippet of the code:

<mx:VBox width=”50%” height=”100%” styleName=”whiteContainer”>

<mx:Box direction=”vertical” width=”100%” height=”100%” styleName=”scrollableContentWithText” >
<mx:HBox width=”100%” verticalAlign=”middle”>
<mx:Image source=”assets/images/book74×42.png” width=”74″ height=”42″ />
<controls:AdvancedTextArea id=”title1″ multiline=”false” textModify=”captialize” styleName=”whiteContainerHeader” condenseWhite=”true” width=”100%” prompt=”{resourceManager.getString(’resources’,'ENTER_TEXT_PROMPT’).toUpperCase()}” />
</mx:HBox>
<controls:AdvancedTextArea id=”body1″ styleName=”blueOnWhiteText” condenseWhite=”true” width=”100%” prompt=”{resourceManager.getString(’resources’,'ENTER_TEXT_PROMPT’)}” />
</mx:Box>
</mx:VBox>

And here are the results when that body text gets too deep for the VBox:

So the whole parent HBox ended up getting stretched. Not the results I expected.

The solution as it turns out is pretty straight forward. The VBox containing the left column needs it’s minHeight and minWidth properties set to 0! The reason is that with containers using percentage based sizing flex sets the min height and min width properties to the cumulative width and height of the container’s children components. So in my example as the editable text component gets deeper/taller this automatically increases the minHeight property of it’s parent container.

So by explicitly setting the parent container’s minHeight and minWidth to 0:

<mx:VBox width=”50%” height=”100%” styleName=”whiteContainer”>
<mx:Box direction=”vertical” width=”100%” height=”100%” minHeight=”0″ minWidth=”0″ styleName=”scrollableContentWithText” >
<mx:HBox width=”100%” verticalAlign=”middle”>
<mx:Image source=”assets/images/book74×42.png” width=”74″ height=”42″ />
<controls:AdvancedTextArea id=”title1″ multiline=”false” textModify=”captialize” styleName=”whiteContainerHeader” condenseWhite=”true” width=”100%” prompt=”{resourceManager.getString(’resources’,'ENTER_TEXT_PROMPT’).toUpperCase()}” />
</mx:HBox>
<controls:AdvancedTextArea id=”body1″ styleName=”blueOnWhiteText” condenseWhite=”true” width=”100%” prompt=”{resourceManager.getString(’resources’,'ENTER_TEXT_PROMPT’)}” />
</mx:Box>
</mx:VBox>

… I ended up with the desired result:

How to make a custom Flash Preloader for a Flex Application

March 27th, 2009

There are a number of useful Flex techniques I use in the Flex Apps I develop all the time and I thought that some of these might be useful for others. So here’s the first… How to replace that nasty default Flex preloader with your own Flash animated version. Here’s the result (I just downloaded a free preloader animation from the web and applied it to this tutorial:

http://www.nickkuh.com/demos/custom_preloader/

Flex source files can be downloaded from here:

http://www.nickkuh.com/demos/custom_preloader/srcview/CustomPreloader.zip

How it works:

Inside the main application MXML you can specify a custom preloader class for your application to use:

<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml”
layout=”vertical”
backgroundColor=”#000000″
backgroundGradientAlphas=”[0.0,0.0]”
paddingTop=”30″
applicationComplete=”init()”
preloader=”com.nickkuh.preload.Preloader”  viewSourceURL=”srcview/index.html”>

So you’ll see I’m pointing the preloader to my com.nickkuh.preload.Preloader class. This class extends the default Flex DownloadProgressBar class: mx.preloaders.DownloadProgressBar. The Flex Framework passes the application it’s loading to preloader setter method which I’m overriding:

override public function set preloader(value:Sprite):void{
value.addEventListener(ProgressEvent.PROGRESS, progressEventHandler, false, 0, true);
value.addEventListener(Event.COMPLETE, completeEventHandler, false, 0, true);
value.addEventListener(FlexEvent.INIT_PROGRESS, initProgressEventHandler, false, 0, true);
value.addEventListener(FlexEvent.INIT_COMPLETE, initCompleteEventHandler, false, 0, true);
}

So my custom Preloader class is now able to listen to the application preloading events - halfway there…

In the constructor for the Preloader class I’m creating an instance of another custom class which deals with displaying the Flash loading animation and adding this instance to the stage:

progressBar = new ProgressBar;
this.addChild(progressBar);

The Preloader class listens to the instance of the com.nickkuh.preload.ProgressBar class for the custom event ProgressBar.FADE_OUT_COMPLETE. Only when that event is fired will the Preloader class in turn fire an Event.COMPLETE event which the Flex app listens for before it displays the loaded application and fires the applicationComplete event. So this set-up enables the custom ProgressBar to control when the Flex app changes the view from preloader to application.

The custom ProgressBar class extends Flex’s Loader class and loads in the flash loading animation. I’ve set this up so that the ProgressBar checks for the path to the preloader.swf via FlashVars:

var url:String;
if (this.stage.loaderInfo.parameters.hasOwnProperty(”preloaderURL”))
{
url = this.stage.loaderInfo.parameters.preloaderURL;
}
else
{
url = “preloader.swf”;
}
var urlRequest:URLRequest = new URLRequest(url)
this.load(urlRequest);

You’ll find the fla for the preloader in the source files in a folder called ‘design’. The fla actually includes a couple of methods on frame one:

stop();

function setProgress(n:Number)
{

}

function set ready(b:Boolean)
{
if (b) gotoAndPlay(2);
}

The custom ProgressBar class calls these methods with progress updates and sets the ready setter to true when the Flex App has finished loading. If you’re loading animation is a progress bar or needs to give percentage feedback then you can customise the setProgress(n:Number) function - n will be between 0 and 1 - 1 for fully loaded.

In my fla once the preload completes it then plays a few more frames before fading out. This animation could be changed to you requirements.

Once the internal fade out complete the fla fires off an “animationComplete” event which the ProgressBar is listening out for. At this point the closeScreen method of ProgressBar handles the event and ProgressBar fades itself out. Once complete it in turn fires the FADE_OUT_COMPLETE event which causes the main Flex app to close the preloader and display your Flex App.

Yes, it’s a bit time consuming to make a simple preloader but I now use this set-up over and over again. Feel free to do the same!

Upgrading Flex SDK to 3.3

March 6th, 2009

This morning I downloaded and installed the new Flex 3.3 SDK recently released by Adobe. Thanks for the post Ted.

I prefer to load Flex SDK as a runtime shared library but soon found that this was generating a couple of runtime errors when my projects were initialising:

Error #2034: An invalid digest was supplied.
Failed to load RSL framework_3.2.0.3958.swz
Failing over to RSL framework_3.2.0.3958.swf
Flex Error #1001: Digest mismatch with RSL http://myurl/framework_3.2.0.3958.swf. Redeploy the matching RSL or relink your application with the matching library.

Via the project properties I’d set the flex framework to be loaded as a runtime shared library ok and chosen the option to deploy the RSL swf. Flex Builder was deploying the swf, I guess by compiling it from the new SDK source but the error I believe relates to the generated RSLs don’t have the required validation compiled into them.

The solution:

You can just grab the verified RSLs that are included in the new SDK download which you’ll find via the following path:

[Flex SDK folder]/frameworks/rsls/framework_3.3.0.4852.swf
[Flex SDK folder]/frameworks/rsls/framework_3.3.0.4852.swz

Copy those files into your html-template folder and then be sure to specify the relative paths to those 2 RSLs via the [Your Project] > Properties > Flex Build Path > Library Path > Flex 3.3 > framework.swc > RSL URL

Hope that saves you some time with that error :-)

iPhone Development: initial thoughts and suggestions

January 13th, 2009

I’ve recently started work developing a new iPhone Application and have found it fairly straight forward to get up and running with Xcode, Objective-C and the iPhone SDK. I thought I’d share some of my initial experiences and recommendations to other Developers to get up and running with iPhone Development:

If, like me, you’re already comfortable with Object Oriented Programming and MVC patterns then the first thing I’d suggest you read is Apple’s Object-C Primer page here:

http://developer.apple.com/iphone/gettingstarted/docs/objectivecprimer.action

(You may need to create a free developer login with Apple first to read this)

This page is enough to get you up to speed with the basic Object-C syntax - how instance and static methods are written, how each class need a m and a h (header, like an Interface file in Flex).

Download Apple’s examples

The iPhone Dev Center contains a whole bunch over very useful examples that make it very quick work to get up and running building iPhone apps that make use of the components that come bundled with the iPhone SDK. These are the ones I found most helpful for my table/ tab navigator type application:

TableViewSuite - I initially downloaded this example and found it a good starting point for understanding tables and how to create data providers/sources and table delegates.

The Elements - This has been the most useful example I’ve downloaded and used so far. I’ve used this as a base for how I’ve developed my own application. It doesn’t use a single xib/nib file and to be honest I found the whole Interface Builder development made things more confusing than they needed to be. If you don’t like Interface Builder and you want to learn how to build a Table based app without it this is the example you need!

I’m loving this iPhone Development. Might have to start reselling myself as an iPhone Developer :-)

1,500 installs of Scoop in first 5 days!

November 30th, 2008

My first freeware application - Scoop - got added to the Adobe AIR Marketplace 5 days ago. I just checked the latest download/install figures from Adobe and there have been almost 1,500 installations of the software made since it got launched on the Adobe site just 5 days ago!

I’ve had a tonne of feedback for this Google Reader online/offline desktop app in the last week - some good and some constructive but what certainly seems clear is that a lot of people see the benefits of using an app like this that can make offline google reading / tagging/ starring  possible :-)

I’m planning to implement a whole bunch of requested features over the next few weeks/months depending on how much free time I get :-)

NativeWindow class in AIR does not support Flex components

November 24th, 2008

Just a quick tip for any AIR developer’s searching for why there’s no addChild method in the NativeWindow class - I wasted a fair while on this over the weekend. I was adding Flex components to the stage property of NativeWindow and trying various other work arounds. Although you don’t get errors for doing this the Flex components never appear when you test your app!

If you want to add Flex components to a new NativeWindow in AIR then this is what Window class is for. So don’t waste time creating a new NativeWindow and activating it, just create/subclass the Window class not NativeWindow and you’ll find all the stanard Flex component properties and methods :-)

Duh!

Scoop Beta (v0.25) just launched

November 18th, 2008

Have been pretty busy with work recently and haven’t had much spare time to work on my latest personal project but the first public beta of Scoop is finally here.

Scoop is an RSS Feed Reader Adobe Air Application with offline/online Google Reader syncronization built in. It keeps track of multiple Google Reader accounts simultaneously. Read, tag and star your scoops/posts on the train or wherever you like and Scoop will syncronize your changes with Google when you’re back online.

Current features included in this first Beta:

  • Offline mode - all new posts/feeds get stored locally + offline changes you make get syncronized with Google when you’re back online
  • Instant notifications of new scoops/posts from your favorite blogs and websites.
  • Popular Google Read keyboard short cuts like J/K for moving forwards and backwards through your reading lists.
  • Auto-update feature - the application will alert you when a new version of Scoop becomes available.

CluedUp: Flex Crossword application built for the Daily Telegraph

October 30th, 2008

The Daily Telegraph have just launched a new Crosswords and Sudoko site called Clued up - I built the Flex Crosswords Application. Behind the scenes it’s one of my best structured projects to date and uses the following technologies/approaches:

This is just phase 1 of the project. Future releases will include Sudoko, Codewords, possibly the ability to download an Adobe AIR desktop version of the system, Multiplayer - how cool would it be to be able to complete a crossword puzzle with your friend via a multiplayer version of the game?!

I think you have to register a trial account to play the game so here are a few screengrabs…

When the user initially selects a crossword the board/clues are blurred until they begin

When the user initially selects a crossword the board/clues are blurred until they begin

The custom crossword board component subclasses the Flex DataGrid component

The custom crossword board component subclasses the Flex DataGrid component

When you exit a crossword the application checks whether you've got unsaved changes

When you exit a crossword the application checks whether you have unsaved changes