Leave That Thing Alone Blog

CFCPhotoBlog 1.1 Update

CFCPhotoBlog has been updated to version 1.1. Here is what is new:

This is not a huge update mainly I wanted a new look on my photoblog, so I added two new skins 'moderndark' and 'modernlight'. For fun I added support for cooliris/piclens, this adds a special RSS feed that allows cooliris to view the photos.

As always suggestions and feature requests are welcomed. I am planning now for version 2.0.

CFCPhotoBlog project page

ColdBox Presentation at Sacramento ColdFusion User Group

Join the Sacramento ColdFusion User Group on January 13th 2009, Matt Graf will be talking about the ColdBox ColdFusion framework.

For more details and directions visit www.saccfug.com

Using Gumbo and itemRendererFunction to create multiple ItemRenderers

Gumbo has added an "itemRendererFunction" function that allows certain data containers to specify an itemRenderer based on the data item. In this example an FxDataContainer's dataProvider is set to an ArrayCollection that contains 2 different types of Value Objects. Depending on the type of Value Object the itemRendererFunction returns a different itemRenderer.


View Example (right click for source)

In this example there are two different Value Objects: PhotoVO and QuoteVO. An FxDataContainer's dataProvider is set to an ArrayCollection:

[Bindable]private var VODataProvider:ArrayCollection;

<FxDataContainer dataProvider="{VODataProvider}"...

The ArrayCollection is populated with 5 Value Objects, 2 PhotoVO and 3 QuoteVO.

In the FxDataContainer the itemRendererFunction is set to a function:

<FxDataContainer dataProvider="{VODataProvider}" 

itemRendererFunction="itemRendererFunction_handler"

In the itemRendererFunction a ClassFactory is passed back based on the type of data item in the itemRenderer. In this example there is a different itemRenderer for the PhotoVO and QuoteVO. We will also pass in a function to the itemRenderer to handle clicks:

private function itemRendererFunction_handler(item:Object):ClassFactory {

var classFactory:ClassFactory;

if (item is PhotoVO) {

//item is PhotoVO so use Photo ItemRenderer

classFactory = new ClassFactory(PhotoItemRenderer);

} else if (item is QuoteVO) {

//item is QuoteVO so use Quote ItemRenderer

classFactory = new ClassFactory(QuoteItemRenderer);

}

//pass callback click function

classFactory.properties = {clickFunction:itemRenderClick_handler};

return classFactory;

}

View Example with source enabled (flash 10 required)

Gumbo and Catalyst Photo Viewer Application

I've posted an example of a Flex application created with the MAX preview versions of Flash Catalyst and Gumbo. This small demo application was created to test out some of the new features in both Catalyst and Gumbo. It is not a perfect project, but a starting point for further projects.

Gumbo Catalyst Photo Application
View Example (right click for source)

The main goal of this project was to play with the new features in Catalyst and Gumbo using a close to real world example application, here is what was done:

  • Start with a photoshop layout (PhotoShop file located in PSD directory)
  • Use Catalyst to layout/components/skins and export FXG project
  • Import FXG to Gumbo project
  • In Gumbo add data/photo/etc functionality to the project
  • Take project back to Catalyst for small visual edits, then back to Gumbo
  • Use new Gumbo MXML tags/components
  • Play with new __AS3__.vec.Vector (using the new BitmapData.histogram)

Instead of detailing every step of the process there is great Gumbo Documentation and Catalyst Examples.

View Catalyst and Gumbo Photo Application (requires Flash 10 player)

Introduction to MVC at November Sacramento ColdFusion User Group

Sacramento ColdFusion User Group meets November 11th, this month Nolan Erck will be giving a presentation on "Introduction to Model View Controllers in ColdFusion". He will go over the basics of what MVC does, pros and cons, and give an introductory look at some code that uses this pattern.

This will be a non-framework-specific talk. No prior knowledge of Model-Glue, Mach-ii, etc required; none of the code samples will use a framework. However, some basic knowledge of CFCs will probably help tremendously

For more information and directions visit www.saccfug.com

ColdFusion Admin Presentation at October Sacramento User Group Meeting

Join SacCFUG Tuesday October 14th for an "Introducing the ColdFusion Administrator" presentation by Jose Gomez.

For more information and directions visit www.saccfug.com

CFImage Presentation Files

I have posted the "Image Manipulation with ColdFusion 8" presentation files for the September 17th 2008 BACFUG meeting.

There are two different ColdFusion folders in the zip file. The first is a is a collection of example cfm files that demonstrates the cfimage tag and the different image functions. The second is a sample application that demonstrates some of the things ColdFusion can do with your digital photos.

CFImage Presentation Files

Example of Feature Rich ItemRenderers in Flex

(Related: see entry on Feature Rich Dynamic Item Renderers)

In response to some requests I got from friends wanting some more real world ItemRenderer examples, here is one that approaches the item renderer from a graphical approach and brings together some different techniques to create a nicely featured ItemRenderer.

Here is what this example DataGrid/ItemRender demonstrates:

  • MXML based ItemRenderer
  • Override ItemRenderer 'set data' have data as a known ValueObject
  • Swap icons/images based on data values
  • Highlight selected ItemRenderer
  • Enable ItemRenderer to dispatch an event to remove a person from the grid

DataProvider and ValueObjects
The first thing we'll look at in the example is the data and data provider for the Grid. Keep in mind this is just a quick demo way to load sample data, the goal is to create an ArrayCollection of Value Objects. The sample XML data is loaded via an HTTPService. When the result comes back from the service we cast the result as an ArrayCollection, we then loop through each item in that result ArrayCollection. Each item is an Object containing the 'person' data defined in the XML. For this example we want to place each person data in a person ValueObject (VO). This VO provides a known data type that we will use as the 'data' in the ItemRenderer. Often when using AMF taking to ColdFusion/BlazeDS/Java/Etc the VO will be aliased to a data type on the server, so this example simulates the DataGrid provider being an ArrayCollection of VOs.
This result function populates the DataProvider with our Person VOs:


private function httpResult_handler(evt:ResultEvent):void {
    if (evt.result.people.person) {
        //result

        var resultAC:ArrayCollection = evt.result.people.person as ArrayCollection;
        //loop through each item in data

        for (var i:int=0;i<resultAC.length;i++) {
            //create person VO

            var person:Person = new Person();
            //add data

            person.fill(resultAC[i]);
            //add person to main data provider

            peopleDataProvider.addItem(person);
        }
    }
}

ItemRenderer and Override of 'set data'
Next we'll look at how the data is dealt with inside the ItemRenderer. The DataGrid's only column is set to have an ItemRenderer. When the DataProvider is populated the DataGrid is going to set the 'data' property on each row's ItemRenderer with the the associated VO in the DataProvider ArrayCollection. We want to make sure that the data inside the ItemRenderer is actually a Person VO object (not a generic Object), so we need to override the 'set data' function. When we override this function we are now able to cast the data value as a Person VO. This will allow us to refer to data inside the ItemRenderer as that VO with known attributes rather than a generic Object that it would otherwise be:


[Bindable]private var person:Person;
override public function set data(value:Object):void {
    super.data = value;
    if (value is Person) {
        person = Person(value);
    }
}

When overriding the set data function make sure to remember set 'super.data=value'. The ItemRenderer still needs to know the value of the data otherwise it will be treated like an empty row in the DataGrid.

Swap ItemRenderer Images Based on Data
As a nice UI feature let's display a male/female icon based on the person's gender. This is easy to do, we know the data will be a Person VO. So we can have the Image component ask for the correct image based on the 'person.gender' value:


<mx:Image id="gender_img" source="{getGenderImg(person.gender)}"...

Since the person variable is Bindable if there is a change the 'getGenderImg' function will be asked to give the image its source:


private function getGenderImg(gender:String):Class {
    if (gender == Person.GENDER_FEMALE) {
        return imgUserFemale;
    } else {
        return imgUserMale;
    }
}

Highlight Selected ItemRenderer
Next let's add some nice functionality to make the ItemRenderer stand out a little more when it is selected. To do this we need to override another function. This time we're going to override the updateDisplayList function, this will allow us to set some styles and graphical elements to the ItemRenderer is if is the selected itemRenderer. Using 'ListBase' we are able to find out if the 'owner' (the DataGrid) has this data selected:


override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void {
    super.updateDisplayList(unscaledWidth, unscaledHeight);
    if(ListBase(owner).isItemSelected(data)) {
        name_lbl.setStyle("styleName","pnameselected");
        selected_img.visible = true;
    } else {
        name_lbl.setStyle("styleName","pname");
        selected_img.visible = false;
    }
}

Enable ItemRenderer to dispatch a remove person event
Lastly we'd like the trash can icon to remove a the person when clicked. There are other (maybe more preferable, but that's for a different example) methods, but for this example let's have the ItemRenderer dispatch an event and have a listener set to catch that event. On the click event of the trash can icon there is an event dispatched:


public static const DELETE_PERSON_EVENT:String = "deletePerson";
private function deleteClick_handler():void {
    var dEvt:Event = new Event(DELETE_PERSON_EVENT,true);
    this.dispatchEvent(dEvt);
}

This 'deletePerson' event is dispatched by the ItemRenderer and importantly has 'bubbles' set to true. This bubbling enables the parent component to simply add a listener for the event:


myDG.addEventListener(PersonItemRenderer.DELETE_PERSON_EVENT,deletePerson_handler);
private function deletePerson_handler(evt:Event):void {
    if (myDG.selectedIndex != -1)
        peopleDataProvider.removeItemAt(myDG.selectedIndex);
}

That's it for this example. The next example will build on this but go the route of a dynamic ItemRenderer, while they a little bit more complicated can be very flexible allowing for dynamic properties to be set on the itemRenderers.
View the Example

ColdFusion 8 Image Presentation at Bay Area ColdFusion User Group

Next Wednesday September 17th I'll be presenting "Image Manipulation with ColdFusion 8" at the Bay Area ColdFusion User Group.

The presentation will start off by going over CFImage and the image tags that were introduced in CF8, in code we'll walk through examples of all the different functionalities. Next we'll move into some more advanced examples of how to get the image tags to do some neat effects, then briefly get into leveraging available Java libraries (AWT, JAI) to do some fun image stuff. Finally we will walk through an demo application that pulls all of CF8's image abilities together to create an image library for your digital photos that indexes, thumbnails, display camera details, rotates, and even allows search by color.

I will have example code posted next week before the presentation.

More details on the meeting location, RSVP, and Connect URL:
http://bacfug.org/index.cfm?event=showMeeting&meetingID=144AB637-20ED-7D0A-C0162EBEEC9647F1

Sava CMS at Sacramento ColdFusion User Group August 12th

Join SacCFUG Tuesday August 12 and hear Blue River Interactive Group talk about Sava an Open Source ColdFusion content management system.

Blue River will also be talking about their use of Railo an alternative engine for ColdFusion.

For more information and directions visit www.saccfug.com

More Entries