The Flex TitleWindow component is a great start for making dialog panels, because it has a close button in the title bar. By clicking the button this component automatically dispatches a CloseEvent. Nice, but… this button doesn’t show the hand cursor on roll over.
Personally I find it very annoying one has to set the buttonMode to true for each and every component. In some of the default Flex components this can be a real pain. Here’s how one can set the buttonMode for the close button of the TitleWindow component:

1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0" encoding="utf-8"?>
<mx:TitleWindow showCloseButton="true" creationComplete="init()"  xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="400" height="100" title="My title window">
    <mx:Script>
        <![CDATA[
            private function init():void{
                if(mx_internal::closeButton!=null)
                    mx_internal::closeButton.buttonMode = true;
            }
        ]]>
    </mx:Script>
</mx:TitleWindow>

I’m using Flex 3.2, so it’s possible this no longer works in newer versions.

Today, I started working on a new internet application in Flex… and I ran into some of the same annoying default Flex component behaviors I usually change or work around. These are small details, but the application will look so much more polished and professional when they are implemented.
Alert.show() for example creates an alert dialog, but the text inside the dialog is selectable and the buttons don’t show a hand cursor on rollover. One could argue that the alert message should be selectable so people can copy it. But personally I don’t like this behavior.
To make the text unselectable, you can do the following (I’m using Flex 3.2, so it’s possible this will no longer work in new versions):

1
2
var a:Alert=Alert.show("This is an alert", "Alert", Alert.OK | Alert.CANCEL,this);
a.mx_internal::alertForm.mx_internal::textField.selectable = false;

And to show a hand cursor for the buttons, all one has to do is this:

1
a.buttonMode=true;

As a professional Flash and Flex developer, I wrote lots of handy utilities that I use on a daily basis when developing Flash websites or Flex applications. I developed my own library containing base classes and utilities that allow me to setup Flash website projects in no time. I call it the “viplib”.

I plan to releasing some of that code. And here’s a first code snippit:

In Flex, it’s easy to do form validation using the various validator components. But for Flash, one has to write his own code. Here’s a simple form-validation class that not only checks empty fields and invalid email entries, but also highlights those fields when their content is invalid. Using this class you can validate a form and highlight the fields that are invalid with only 1 line of code.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
//copyright Ward De Langhe
//Very Interactive People
package be.viplib.util
{
    import flash.display.Sprite;
    import flash.events.FocusEvent;
    import flash.text.TextField;
   
    public class FormValidator
    {
        private var _target:Sprite;
        private var _requiredFields:Array;
        private var _emailFields:Array;
        private var _normalColor:Number;
        private var _invalidColor:Number;
        private var _requiredMessage:String;
        private var _invalidEmailMessage:String;
       
        public function FormValidator(target:Sprite,requiredFields:Array, emailFields:Array,normalColor:Number=0x000000,invalidColor:Number=0xff0000,requiredFieldMessage:String="required field",invalidEmailMessage:String="invalid email")
        {
            _target=target;
            _requiredFields=requiredFields;
            _emailFields=emailFields;
            _normalColor=normalColor;
            _invalidColor=invalidColor;
            _requiredMessage=requiredFieldMessage;
            _invalidEmailMessage=invalidEmailMessage;
        }
        public function set invalidMailMessage(value:String):void{
            _invalidEmailMessage=value;
            for(var i:Number=0;i<_emailFields.length;i++){
                var field:TextField=_target.getChildByName(_emailFields[i]) as TextField;
                if(field.text==_invalidEmailMessage){
                    field.text=value;
                }
            }
        }
        public function set requiredMessage(value:String):void{
            _requiredMessage=value;
            for(var i:Number=0;i<_requiredFields.length;i++){
                var field:TextField=_target.getChildByName(_requiredFields[i]) as TextField;
                if(field.text==_requiredMessage){
                    field.text=value;
                }
            }
        }
        public function validate():Boolean{
            var valid:Boolean=true;
            for(var i:Number=0;i<_requiredFields.length;i++){
                var field:TextField=_target.getChildByName(_requiredFields[i]) as TextField;
                if(field.text=="" || field.text== _requiredMessage || field.text==_invalidEmailMessage || (field.text.length==1 && field.text.charCodeAt(0)==13)){
                    field.textColor=_invalidColor;
                    field.text=_requiredMessage;
                    field.addEventListener(FocusEvent.FOCUS_IN,fieldFocus_handler);
                    valid=false;
                }
            }
            for(i=0;i<_emailFields.length;i++){
                field=_target.getChildByName(_emailFields[i]) as TextField;
                if(field.textColor!=_invalidColor){
                    if(!MailValidator.validateEmail(field.text)){
                        field.textColor=_invalidColor;
                        field.text=_invalidEmailMessage;
                        field.addEventListener(FocusEvent.FOCUS_IN,fieldFocus_handler);
                        valid=false;
                    }
                }
            }
            return valid;
        }
        private function fieldFocus_handler(evt:FocusEvent):void{
            for(var i:Number=0;i<_requiredFields.length;i++){
                var field:TextField=_target.getChildByName(_requiredFields[i]) as TextField;
                if(field.textColor==_invalidColor){
                    field.textColor=_normalColor;
                    field.text="";
                    field.removeEventListener(FocusEvent.FOCUS_IN,fieldFocus_handler);
                }
            }
            for(i=0;i<_emailFields.length;i++){
                field=_target.getChildByName(_emailFields[i]) as TextField;
                if(field.textColor==_invalidColor){
                    field.textColor=_normalColor;
                    field.text="";
                    field.removeEventListener(FocusEvent.FOCUS_IN,fieldFocus_handler);
                }
            }
        }
    }
}

This class uses my mailvalidator utility to validate the email adresses. It’s a simple utility which checks if a e-mailaddress is valid using a regular expression.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//copyright Ward De Langhe
//Very Interactive People
package be.viplib.util
{
    public class MailValidator
    {
        public static function validateEmail(str:String):Boolean {
            var pattern:RegExp = /(\w|[_.\-])+@((\w|-)+\.)+\w{2,4}+/;
            var result:Object = pattern.exec(str);
            if(result == null) {
                return false;
            }
            return true;
        }
    }
}

You can download example source code here. It’s a simple form containing a couple of required fields, and an email field. Here’s how this sample looks when compiled:

Click the “validate” button to see the validation class do it’s job.

I’m an active Flickr.com user, and I’ve noticed lots of HDR images popping up lately. Some of them are absolutely garbage, but every now and then a true jewel pops up. I’ve always wanted to experiment with HDR images, but I don’t own a digital single lens reflex camera. I have a Panasonic Lumix TZ3, which is a great point and shoot camera. Sure, it’s getting a bit outdated, but it’s still a fine piece of equipment. Perfect for travelling pictures, and that’s what I use it for most of the time. Any camera that allows manual over- or under-exposure of a photo can be used to create HDR images, but the TZ3 comes with a handy auto bracketing feature that makes the life of a HDRi enthousiast so much easier.

On my last vacation, I tried a first HDR photo. The result wasn’t great, but it was ok for a first try. You can see that photo here. This first attempted inspired me to try creating some more, and hopefully better ones.
So, recently, me and my girlfriend went to Valencia and Barcelona for a week (between Christmas and New Year). It was the perfect occasion to try some new HDR photo’s.

Taking the source pictures:
I am told, to create good HDRis, your camera will need to be able to do auto bracketing ranging from -2AEB to +2AEB. Unfortunately the TZ3 only supports -1AEB to +1AEB. But, as you can see in the examples below, the results are looking great anyway. When I buy a new camera I will certainly buy one that can handle +-2AEB.
So, before shooting a picture I followed these steps:

  • Put my camera on a tripod (in my case that was just a 10 euro flexible tripod)
  • Configured my camera to automatically shoot 1 under exposed, 1 normal and 1 over exposed image (auto bracketing):

  • Set the self timer to 2 seconds (pressing the button causes the camera to move. After a 2 second delay I’m sure the camera has completely stopped moving)

Unfortunately, I forgot to configure my camera to use a low ISO setting. My camera automatically chose the ISO, and for indoor scenes, it chose a higher ISO. This resulted in a lot of noise. When creating HDR images you should try to avoid noise. Most of my indoor images failed miserably because of this. This is something I need to try next time.

Processing the images:
I used Photomatix Pro to create the HDR and I also used it for tone mapping. Afterwards I did some post-processing in photoshop, but that was merely cropping, adjusting the contrast, exposure, etc. Maybe I will post a tutorial on that later.
You can download 3 of my source images here, so you can try for yourself. The subject is a cannon on top of Mount Juïc, Barcelona (these cannons are placed around the castle of Mount Juïc):


So in Photomatix Pro, you click on the “create HDR image” button, and select the source files.

After clicking “ok”, Photomatix will ask you how the images need to be processed.

If you didn’t use a tripod, you might want to check the “align source images” checkbox. In this case I used a tripod, so that’s not necessary. The object was also very well lit, so there’s little noise. Because of that I also don’t have to check the “reduce noise” checkbox. And finally, because there are no moving objects in the scene (you should avoid moving objects when creating HDRi’s!), I also don’t need Photomatix to try to reduce ghosting artifacts.
Now press “ok” to generate the HDR image. Before tonemapping it, you should check if everything is aligned properly. If not, go back and repeat the same process, but choose “align source images”. If everything is ok, press the “tone mapping” button.
For this tutorial, I tried to create a more or less realistic image. Some people like to over-process their HDRi’s, to get some kind of surrealistic result. Personally I like it somewhere in between. I want the final image to look special, but not overdone.  Click here to see what settings I used to create the image below.

Final result:

On flickr I also have the same picture, but over-processed. It’s very tempting to do this… but the more natural version looks a lot better. Again, that’s just my opinion. If you like the surrealistic look, go for it!  Click here to see the same tonemapped HDR photo, processed with other settings for a more surrealistic/dramatic effect.

And last but not least: here are some of my HDR attempts. I took these photo’s on our trip to Valencia and Barcelona:

You can view the full set here.

At Epyc, we made a little Flash game to support the “Music for life” show on Studio Brussel. This year, MFL collects money to help the prevention of malaria.

For each highscore above 1000 points, Epyc NV will donate 1 euro to Music for life.

Play the game here

I just launched a new website for one of my clients. It’s the website of “Optiek Vandorpe”, an optician located in Sint-Amandsberg, Belgium.

Visit the website here: http://www.optiekvandorpe.be