Ultrashock Tutorials > Flash MX 2004 > XML Portfolio Viewer  
 
by Jim Armstrong, 2112 FX::Singularity
Download Source Files 
 
XML Portfolio Viewer
 
 Introduction and Code Requirements
 Section 01: Layout XML  
 Section 02: Portfolio XML  
 Section 03: Architecture  
 Section 04: Preloading  
 Section 05: Error Handling  
 Section 06: pair & triple classes 
 Section 07: Observer-Observable Utility 

 Section 08: Style Manager 
 Section 09: Layout Items  
 Section 10: Custom Layout Classes  
 Section 11: Glyph Class  
 Section 12: Multi-dimensional Thumbnailer  
 Section 13: Model 
 Section 14: View 
 Section 15: Controller 
 Section 16: Suggestions for Improvement 

Multi-dimensional Thumbnailer

There are several applications in which it is beneficial to layout Glyphs either horizontally or vertically inside a thumbnailer. This section discusses the SCROLLER component, which is a general-purpose thumbnailer allowing Glyphs to be stacked horizontally or vertically and in one or two dimensions.

The thumbnailer is implemented in the Scroller class, which includes a reference to a GlyphHolder class. The Scroller class handles the LayoutItem details, while GlyphHolder functions as a multi-dimensional container for collections of Glyphs. If you wish to rip this thumbnailer out of the portfolio viewer and use it in another project, then GlyphHolder is the primary class of interest.

Thumbnailer Properties

The thumbnailer requires some properties in addition to those in its base class. These are indicated below.

// core
private var __scroller:MovieClip;    // container for scroller
private var __isHorizontal:Boolean;  // true if 1d horizontal scroller
private var __is2D:Boolean;          // true if 2d layout
private var __outlineBuffer:Number;  // buffer space for scroller outline
private var __buffers:triple;        // h-buffer, v-buffer, and o-buffer
private var __mask:pair;             // width/height of glyph mask 
private var __dimension:Number;      // one- or two-dimensional thumbnailer
private var __hBuffer:Number;        // horizontal buffer space
private var __vBuffer:Number;        // vertical buffer space
private var __glyphLinkage:String;   // glyph linkage id
private var __glyphWidth:Number;     // glyph width 
private var __glyphHeight:Number;    // glyph height 
private var __horThumbnails:Number;  // number thumbnails visible horizontally
private var __vertThumbnails:Number; // number thumbnails visible in vertically
private var __thumbAlign:String;     // thumbnailer alignment for scrollbar
private var __orient:String;         // thumbnailer orientation
// glyphs
private var __glyphHolder:GlyphHolder; // reference to glyph holder
private var __glyphs:Array;            // container for all portfolio glyphs
private var __dim:pair;                // pixel width and height of a Glyph
private var __loadCount:Number;        // thumbnail image counter
private var __selectedGlyph:Glyph;     // reference to currently selected Glyph
 

These properties are set in the layout.xml file. An example SCROLLER layout is

<item name="SCROLLER" type="CUSTOM" class="Scroller">
  <data mode="absolute">
    <x>300</x>
    <y>200</y>
    <orient>vertical</orient>
    <dimension>2</dimension>
    <hBuffer>6</hBuffer>
    <vBuffer>6</vBuffer>
    <glyphLinkage>glyph</glyphLinkage>
    <glyphWidth>124</glyphWidth>
    <glyphHeight>43</glyphHeight>
    <horThumbnails>2</horThumbnails>
    <vertThumbnails>3</vertThumbnails>
    <thumbalign>right</thumbalign>
  </data>
</item>

Each property is defined as:

x - absolute x-coordinate of thumbnailer (or centered relative to Stage)

y - absolute y-coordinate of thumbnailer (or centered relative to Stage)

orient - orientation ('horizontal' or 'vertical')

dimension - dimensionality (one- or two-dimensional layout)

hBuffer - horizontal buffer space between Glyphs

vBuffer - vertical buffer space between Glyphs

glyphLinkage - linkage ID of glyph symbol in library

glyphWidth - Glyph width in pixels

glyphHeight - Glyph height in pixels

horThumbnails - number of thumbnails initially visible in horizontal dimension

vertThumbnails - number of thumbnails initially visible in vertical dimension

thumbAlign - Scrollbar alignment in the thumbnailer - 'left', 'right', 'top' or 'bottom'

Notice in the XML file that the width and height of the thumbnailer are never specified. Instead, the number of initially visible Glyphs in each dimension along with Glyph width and height are specified. Glyph width and height serve as upper bounds when constructing the thumbnailer. This is useful in instances where Glyphs are animated into their final state, so the final width and height may not be known when the Glyph is created.

Initialization

It is not possible in the scope of this document to completely deconstruct the GlyphHolder class, so I will go through the main logic. The Scroller's init() method accepts the same inputs as the LayoutItem init() method . A container clip is created to hold all the thumbnail-related visual assets. Thumbnailer properties (documented above) are used to construct a new GlyphHolder.

After initialization, an error handler is assigned to listen for "error" events from the GlyphHolder. The thumbnailer is then drawn on Stage. After drawing is complete, the component is positioned and then observers are notified.

GlyphHolder Construction

A GlyphHolder consists of the following elements,

1- Content Container (MovieClip -- contains all Glyphs).

2- Content Mask (constructed so that the specified number of Glyphs are initially visible in each dimension).

3- UIScrollBar (oriented horizontally or vertically to control scrolling of the content area).

4- Outline (simple outline drawn around the outside of the content area and scrollbar).

The __bounds() method is called to compute the the length (or height) of the scrollbar. The scrollbar is moved into the appropriate position, based on the thumbAlign specification. I have not implemented a horizontal thumbnailer with 'top' alignment. There is something inherently strange about a horizontal thumbnailer with a scrollbar on top.

The __bounds() method also calls specific initialization methods for a horizontally and vertically oriented scrollbar. Each scrollbar is assigned a "scroll" handler to implement scrolling of the content area. The scrollbars are currently implemented as separate items as a carryover from prior implementations with third-party components. Once you understand the code, please feel free to compact it as much as you like.

The __outlines() method is called to draw an outline around the entire component. Both methods are written in a straightforward manner so that the logic is easier to follow. It should be possible to compact the code after you fully understand its function. The __outlines() method also dynamically creates and applies the content mask so that only the specified number of Glyphs are visible in each dimension.

I believe the best way to completely understand the function of the __bounds() method is to draw a few sample pictures. Try three or four initially viewable Glyphs with a one-dimensional, horizontal thumbnailer. With known horizontal buffer space between the Glyphs, what is the length of the scrollbar? Trace the result in the code and compare. Next, try a two-dimensional example.

There are some minor subtleties. For a horizontal thumbnailer, the horizontal buffer is counted both in between Glyphs and once at each end of the thumbnailer. For two-dimensional thumbnailers, width and height of the scrollable area depend on both buffer space and the number of initially visible thumbnails in each dimension.

Adding Glyphs

Glyphs are added into the thumbnailer with the displayThumbnails() method. This method takes an array of portfolio items as an argument. A new Glyph is created for each portfolio item, by calling __glyphHolder.addGlyph() in the Scroller class. The argument to addGlyph() is the linkage ID of the glyph symbol in the library.

Inside GlyphHolder, the addGlyph() method determines the position of the new Glyph based on the number of dimensions, orientation, and number of initially viewable thumbnails in each dimension. In a two-dimensional thumbnailer, the dimension orthogonal to the orientation is loaded first. What the @%#$#!) does that mean?

Suppose a two-dimensional thumbnailer with horizontal orientation is specified with three Glyphs initially viewable horizontally and two Glyphs vertically. Since the orientation is horizontal, the vertical dimension (or columns) is filled first. If there are eight thumbnails, the first column contains thumbnails with ID 0 and 1. The second column contains thumbnails 2 and 3. The third column contains thumbnails 4 and 5. The fourth column contains thumbnails 6 and 7. If there were nine thumbnails, there would be one more column with a single thumbnail in the first row.

The GlyphHolder's content area is passed as the parent reference to the Glyph.createGlyph() method. If there are no errors creating the Glyph, the loop induction variable is stored as the Glyph ID and handlers are assigned for all the Glyph's events. In a separate loop, .jpg images are loaded into each Glyph using the Glyph's load() method.

An event is dispatched as the .jpg thumbnails are loaded into the Glyph image container. Event handling works its way from the GlyphHolder, up to the View. Specific action is documented in a later section.

After initialization, the Scroller class queries the position and dimensions of the GlyphHolder to set its own position and size properties. It then notifies registered Observers that the component has been positioned and drawn on Stage. The Scroller returns from the init() method and allows the .jpg thumbnails to load at their own pace.

 
©2006 Ultrashock.com - All rights reserved