As a component platform Reflex is built on a foundation of core libraries and utilities. Because of the unique culture of the project most of these solutions are independently useful to the Flash developer. Its layout engine is one of Reflex’s profitable solutions and can structure the visual flow of any member of ActionScript’s display list.
The following demo illustrates one of the default layout algorithms in Reflex, named Dock (notice the minimal use of containers used to achieve the structure). Click and drag to resize:
Layout Laid Out
Maybe one of the first things you noticed while playing with the demo is that container’s just can’t get smaller than their children. This and other more subtle behaviors make up the physics of layout, the rules that Reflex embodies and simplifies in just 3 core classes: ILayout, ILayoutAlgorithm and the RenderEvent.
ILayout
A Layout object wraps any DisplayObject in Flash and provides most of the properties for a given layout system, such as minimum and maximum widths and heights. The demo above is made up of Flash-designed MovieClips and Sprites, no special base container class, creating Block layout’s that point to each. Block extends Layout and is the default layout system for components, providing various width/height features, margins, padding and other common properties for dividing the screen into rectangular sections. Other ILayout implementations may be created to easily support different layout systems, such as 3D.
ILayoutAlgorithm
One of the most important members of any Layout object is the algorithm. With each layout system comes a variety of supporting layout algorithms, defining the rules by which a specific container lays out its children. Through the Block-based layout system, the example above takes advantage of the specific algorithm Dock. This algorithm aligns children of a container to the LEFT, TOP, RIGHT, BOTTOM or FILL based on their dock and tile properties and allows a mixed layout within a single container. Other algorithms position and size children DisplayObject’s uniformly, such as in a stack or a row.
RenderEvent
Normally laying out a screen can be complicated because children affect the size of their container and containers determine the position and size their children. The driving force in Reflex’s layout engine is, by itself, a stand alone utility ideal for managing the “layout cycle”. RenderEvent isn’t very complicated but it simplifies the layout process and greatly increases performance. This is made possible in 3 ways:
- delaying layout computation to just before each screen redraw consolidates all of the property changes that affect both children and container
- dividing layout into two phases, where the measure phase allows a container to calculate its minimum (and maximum) size based on its contents, and the layout phase runs the algorithm that finally place those contents
- allowing each phase to run in order from the lowest to the highest depth in the display list ancestry (in the case of measure) or from the highest to the lowest depth (in the case of layout). For example, Flash’s stage and root would measure last, and layout first, then the children of root will layout, then their first-level children and so on. The reason for this feature is a little more involved but it makes a huge difference in performance
Contribution
Fortunately it’s very easy to customize display list layout by creating new layout algorithms. There are only two methods required, the measure() and the layout() methods, and these are automatically invoked precisely when they need to be. Robert Taylor got involved in the code and within an afternoon had built several of his own layout algorithms, complete with custom behaviors and tweening. Reflex as a platform offers a variety of components and solutions, but if layout is where your interests lie you can contribute without using or understanding anything else in the framework. Perhaps the best part is, because it works with any kind of DisplayObject, Reflex’s layout engine can be used in Flex, Flash or most any other ActionScript 3 environment. It’s universal!
Sounds great! Is the code available?
Demo-code added to the right-click menu of the example, and is dependent on the Reflex library at http://github.com/xtyler/reflex
very nice stuff! thanks for sharing
Universal? Just had a sneak peak into code and found alot of bindings and other compiler directives used. Isn’t that only possible with the Flex Framework ? Does this project compares with Java LayoutManagers? Great work anyways, looks promising…
Nice work!
Could you provide a simple example in Flash IDE?
I’ve got it working with flash CS3. I’ve extracted PropertyChangeEvent and PropertyChangeEventKind from flight-framework source at code.google. I’ve cleared initial errors by changing ILayout implementation in Layout to match interface (replacing public variables with setters). BoxGraphic is not included in view source so i created movieclip with rectangle inside and set linkage to BoxGraphic.
Awesome! Soon I’ll check it’s details.
M. – [Bindable] properties are used as a shortcut during current development but will have to be replaced with getter/setters to support the Flash IDE. Reflex uses the Flight Framework binding solutions.
Tomasz – that’s awesome! You really got your hands dirty, keep up the good work.
The Reflex team is in the midst of rapid development to prepare for upcoming conferences and demonstrations, so we’re neglecting select features at times, such as full Flash Professional support. We’ll get back to it soon.
Wow! That demo loaded so fast that I initially thought it was a screenshot of the demo! Nice work!
Did you notice that with Flex Builder 4 when we Eporting Release Build (optimized SWF or Adobe AIR File) the demo doesn’t work anymore ?
Aargh, would really love to change some snowy northern swedish days to sunny and relaxed californian ones..! Good luck with your 360 Flex presentation! Looking forward to follow (and maybe somehow contribute) to the Reflex progress!
I’ve peeked into the code and with the exception of ScrollBlock in the reflex.layout package, the rest of the layout classes do not require any Binding dependencies whatsoever, which makes this quite easy to extract out and integrate into a reusable BlockBehaviour class that can be applied to any display object (or IBoxModel-based) display for my own collection . After all, I need some basic dock and center fill liquid layout functionality, and this package, though it seems not fully incomplete in some parts (a bit of to-dos), can help in that area.
I’m glad you were able to get in and use this! My friend Rob Taylor has already developed a suite of layout algorithms for his own project and doesn’t use anything else from the framework successfully. It’s a good test of the separation in Reflex.
The Block class is already a reusable piece that will target any DisplayObject, you won’t need to do any extra work to create a “BlockBehavior”. Behaviors are specifically interactive elements for components, while Layouts, Skins etc are other types of reusable systems.
I know Blocks can be used standalone. BlockBehaviour was just a standalone adaptor wrapper because my API uses a specific interface-method activate(target:*):void & destroy():void over a target object, which is pretty archaic/boiler-plate heavy on hindsight (What was i thinking?). I’d definitely have to refactor that to using a pure “target” setter as the standard (where setting target to ‘null disposes off the block/behaviour’s listeners), and therefore eliminate the interface dependencies and allow for cross-platform ease. In fact, the benefit of not using interfaces at all to set targets for behaviours is even better because some behaviour targets may not necessarily be InteractiveObjects. Without an interface, the coder is free to create ANY class with set target(val:MyOwnRequiredType), without resorting to casting. It’s simply assumed there’s a ‘target’ setter for such classes..
It would be cool to allow Blocks the option to also bind their width and height properties to other properties of the target component, if required (since not all DisplayObjects’ width/height values reflect the measured width/height settings used for layouts).
Sorry if this is obvious but where is the reflex.swc?
Scott, the Reflex initial website has finally been released and should have some additional information there. http://www.reflex.io
Awesom framework!
Do you have a FLA wherea all components are inluded?
That’s very nice also, save many times
…
The BoxGraphic isn’t included in the demo folder by the looks of things.
Cheers,
Scott