Is CSS the best metaphor for styling for a UIToolkit? Maybe not

Writing your own UI Toolkit is, if nothing else, educational. As the OpenPyro framework continues to evolve, every time a new feature is added, I look around at prior art in the domain and evaluate the choices made by different frameworks which has been fascinating. Of course, the first framework I look at (since I have had most experience with that) has always been Flex (both Flex 3 and 4 separatly since they are so different), but often I do compare that with choices made by the IPhone’s UIKit, HTML/CSS and (rarely) Swing or any of the Java toolkits.

One of the features that I know I will need to add in a future version will be a simpler way to style/skin the controls. OpenPyro controls are based around composition so creating new UI assets and passing them in as skin elements is simple enough but there is always a need to do something simpler. A blue scrollbar for example shouldn’t need blue assets, more the ability to tell the scrollbar to draw itself with a stroke/fill of blue color.

Flex’s choice in this domain has been CSS and thats not surprising. A lot of the way Flex was developed was to enable it to be a gateway drug to ActionScript for developers from other technology domains and who doesn’t know CSS? Flex 3’s CSS capabilities were very basic and I keep reading how Flex 4’s CSS engine is so much more complete. And considering how much easier it is to create a Flex 3 theme compared to a Look and Feel in Swing, that seems to have been a decent choice. Someone recently asked when OpenPyro would support that functionality which led to this post.

I have often found writing CSS for Flex a chore, for most of the reasons I find writing CSS rules boring: complete loss of any logic system. Deep in ActionScript land while developing an application, switching to CSS is irritating. Suddenly I am in a file where I cannot really code any logic or rules. One of the first libraries of ActionScript I wrote over 3 years back had explicitly defined style objects. For example, ScrollBars would have a corresponding ScrollBarStyle class that listed all style properties. Being a pure AS class, I could also code logic in that, so conditionally apply style properties because I could inspect the properties of the UI element the style was being applied to. Heck, I could even get code hinting of relevant styles for a particular component.

What spurred this post today was seeing how the engineering team I work with at Comcast Interactive Media adopting the Less CSS engine. I have personally not worked with this yet but I might in a coming sprint. By accounts so far, its awesome to work with and I completely don’t doubt that. Most of the logic here seems something that you can write pretty easily in pure AS3 classes and pass them around as something equivalent to Flex/Javascript’s CSSStyleDeclaration object (link to JS CSSStyleDeclaration object)

Anyway, the point of this post was, while CSS may be the most familiar styling metaphor, there may be better ones. I hope OpenPyro can probably adopt something more powerful like lessCSS rather than pure CSS.

Update: Another flavor of a *better CSS* system: SASS

Update 2: Smashing Magazine has a pretty good writeup on CSS ideas and debates. More food for thought as I spec out a styling language for OpenPyro.

On Toolkits vs Frameworks: Why not both and how OpenPyro does it

I was just catching up on Keith Peter’s blog and one of the posts that really caught my attention was on Toolkits vs Frameworks. The defining difference between the two, as Keith quotes Gamma, is “Toolkits do not attempt to take control for you…”.The Framework vs. Toolkit debate was in my mind when I started OpenPyro, but I feel I never stressed that enough so I felt it was worth a blog post.

OpenPyro was written in a way that it can be leveraged in either fashion. Lets take a few of examples:

The “Sprite” equivalent in OpenPyro is the UIControl, which does a few things like interpret percent based measurements, etc. It can also have a painter attached to it that can paint solid colors, gradients, stripes etc. So to create a gradient on a UIControl, all you have to do is:


var uic:UIControl = new UIControl();
var painter:GradientFillPainter = new GradientFillPainter([0xdddddd, 0xffffff]);
uic.backgroundPainter = painter

Now everytime the UIControl resizes, the painter repaints the gradient on its graphics context. However if you are not using a UIControl, and just plain sprites, you can leverage the painters again as so:

var sprite:Sprite = new Sprite();
var painter:GradientFillPainter = new GradientFillPainter([0xdddddd, 0xffffff]);
painter.draw(sprite, 200,200);

Now the painter paints the gradient on the Sprite’s graphics context. Its up to the developer to decide when to repaint the Sprite.

Here is another example with the layouts package:

var container:UIContainer = new UIContainer();
container.skin = new AuroraContainerSkin();
container.size(600,100);
container.layout = new VLayout(10);

var c1:UIControl = new UIControl();
c1.size(100%, 60);
container.addChild(c1);

var c2:UIControl = new UIControl();
c2.size("100%", 60);
container.addChild(c2);

In the above example, we have bought into the OpenPyro framework and just this code will let you create 2 control, position them vertically with a gap of 10px and automatically create a scrollbar since it will be needed ( The 2 children measure up to 60+10+60 pixels > 100px)

But the layouts package classes can be used for pure sprites too by using something like this:

var layout:VLayout = new VLayout(10)
layout.layout(sprite1, sprite2);

Similar examples can be drawn from the effects package etc. Also, OpenPyro has a fairly complete controls package each of which can be instantiated in a few lines of code as well completely independent of any framework dependencies. In fact almost all my tests are pure AS3 classes applying the package classes to non OpenPyro classes.

Optimized List: A pure AS3 List with renderer recycling

One of the things that the Flex List component does pretty well is handle large data collections (Arrays, ArrayCollections, etc). The List uses renderer recycling when displaying data, ie, it creates an itemRenderer only for the items that are displayed and not for each item in the dataProvider. As items scroll offscreen, the renderers associated with those data items are reused to render the new data that appeared on screen.

For the last few projects I have worked on Flex has not been an option because of file size concerns besides others which prompted me to start working on OpenPyro, a light weight Flex-esque framework and I have been pretty happy with it so far. However its List component is a far cry from Flex’s, implemented more like a Repeater, creating as many renderers as the length of the dataProvider, and as my new projects seem to get more data intensive, I started feeling a real need for a List that does the efficient renderer recycling that Flex does. Not finding any on the web, I decided to write one for myself.

The algorithm is as follows: The List creates an instance of a class called ObjectPool, which manages used and unused renderers. Whenever the List needs a new renderer, it asks the pool for a new one and when it does not need a renderer, it returns it to the pool. The pool tries to find unused renderers to satisfy the request for a new renderer and if it cannot, will create a new object and return that.

The core part of the logic resides in the onVerticalScroll function. The list always maintains a map of all visible renderers and as the scrollbar scrolls, the map is recalculated and renderers managed if the map is changed. The source and embedded example are the first stab at the implementation. The example renders an array of 200 values but ends up creating only the 8 or 9 renderers it needs to display.

The code is not complete but I am blogging it here so that if someone feels I am on a wrong track or should investigate a different approach, you can let me know.

It should be noted that this technique only works right now for fixed rowHeight lists. I haven’t thought of the variable height renderers yet, so suggestions on that front are welcome.

OpenPyro 0.4 released !

I am excited to announce the first official dot release (0.4) of OpenPyro, the open source UI framework I have been working on (on and off) for the last few months. All the information including source code, samples and documentation can be found at OpenPyro.org. I would love to hear some feedback as well. I am really hoping for this to be community powered and would love to integrate or help integrate more features into the framework, so if you are interested in the project and would like to collaborate, please feel free to contact me via blog comments, Twitter (http://twitter.com/arpit) or via the OpenPyro mailing list. And definitely take a look at the OpenPyro Wiki, which has a bunch of examples, samples and some concepts explained.

The biggest feature in 0.4 is the measurement and layout system that is pretty similar to Flex that I love and a fairly decent component set. Because all OpenPyro components use composition rather than inheritance, I am really hoping to build something very Flex4-esque but keeping filesize . Am also hoping to keep the core library pretty small and create a comprehensive library of functionality using plugins, basically libraries whose functionality depends on OpenPyro but not the other way around. For a full set of development themes check out the section here on the wiki.

I have been writing about OpenPyro on this blog for the last few months as well, all those posts can be found here

Hopefully this can grow into a body of code that the community finds useful.

OpenPyro now being ported to Haxe. Can you help ?

Its really awesome to see community interest in OpenPyro, the Flex-lite framework that I have been working on for the last few months. The latest news on that front is an effort to port OpenPyro to HaXe, an open source programming language that can be compiled to a variety of languages like Flash, Javascript, PHP etc by Don-Duong Quach. Don evaluated OpenPyro and has started a Git repository on the porting effort. He was even able to compile a previous example I had built with OpenPyro to a Haxe version which you can find here.

Its really exciting to see this work. My own knowledge of Haxe is minimal so I can’t be as helpful as I would like to be, but if there are other HaXe developers out there, your help in the effort would be really appreciated. The conversation around the port is happening at the OpenPyro mailing list.

In other news, OpenPyro finally has an official home at OpenPyro.org. I am going to start posting architecture documents and examples there. The latest can be found at the OpenPyro wiki and the OpenPyro asdocs page.

OpenPyro wiki updates, and plans going forward

I have been talking a bit around OpenPyro quite a bit in my recent blog posts but I wasn’t sure if the project was gaining traction until MAX SF this year where I actually had more than a few conversations around OpenPyro. Oh wow, that was awesome! But I realize we haven’t been doing a great job communicating progress or direction around this project, or gathering feedback. So I spent a few hours today writing up the Intro and the Development Themes pages on the OpenPyro wiki. Both are also linked off the main project page here.

Please take a few moments to read the pages. If you are interested in this project in any capacity (influence direction, mark bugs, request features or contribute code), please join the OpenPyro google group. To make it even simpler, I am including an inline subscription box here:

Google Groups
Subscribe to AS3 Pyro User Group
Email:
Visit this group

On our side we are going to be busy being even more transparent, by doing things like public code reviews (we use ReviewBoard within CIM and are going to have a public version of it soon).

OpenPyro is definitely a community project and if you have code that would benefit OpenPyro, we would love to include it in our code base.

Thanks and happy coding.

Simple OpenPyro example with source: Image Viewer

Work on OpenPyro goes well, and I keep getting people asking me for examples of the framework in use. After receiving another request today on an OpenPyro example, I figured I’d write a quick widget and release it with the source. So check out this very simple Photo Browser app. The source can be found here. The application is simple on purpose but shows some parts I want to highlight. The widget is a List module on one side and an Image container inside another container on the other side. As you click on a list item, the source of the Image component changes. Here are some key parts of the code:

Measurement:
This of course is the main thing I worked on in OpenPyro. In the main class, the shell lays out a header and a PhotoModule component and a Spacer vertically using a VLayout object. The PhotoModule is sized by setting its percentWidth and percentHeight to 100, and the layout does the rest. Pretty sweet.
The List component within the PhotoModule class is sized similarly with a width of 200 and the ScrollPane is sized at 100% of the unused space.

List with custom renderer:
The List module implementation here is also an interesting example that shows how a List module can work with custom renderers. The code looks like:

[AS]
var list:List = new List();
var itemRendererFactory:ClassFactory = new ClassFactory(DefaultListRenderer)
itemRendererFactory.properties = { percentWidth:100,
height:30,
rollOutBackgroundPainter:new FillPainter(0x444444),
labelFormat:new TextFormat(“Arial”, 12, 0xffffff)}
list.itemRenderer = itemRendererFactory;
list.dataProvider = picData;
list.layout = new VLayout()
list.skin = new AuroraContainerSkin()
list.width = 250;

var listPainter:GradientFillPainter = new GradientFillPainter([0x222222, 0x111111])
listPainter.rotation = Math.PI/2

list.backgroundPainter = listPainter
list.percentHeight = 100;

addChild(list);

[/AS]

Automatic scrollbar creation on containers
The module on the right that shows the photo is basically just an Image control within a UIContainer. If you click on the Asterix photo, the photo is bigger than the container and the container automatically puts the scrollbars in. Its also important to realize that the only reason the photo became bigger than the containing UIContainer was because the image did not have a width,height assigned to it. In that case, all UIControls default into a child based measurement strategy and their sizes are determined by the children they contain.

Using BackgroundPainters
I love the backgroundPainter api on the basic control (UIControl). In one or two lines, you can set the entire look of a component. The code looks something like:

[AS]
var bgPainter:GradientFillPainter = new GradientFillPainter([0,0x333333]);
bgPainter.cornerRadius = 10;
bgPainter.rotation = Math.PI/2
shell.backgroundPainter = bgPainter;

[/AS]
If the shell in the above case resizes, the painter is re-triggered and repaints correctly.

FileSize
Once again the killer part of the framework is the file size. This example is about 21 K.

There is a lot of stuff here I am pretty proud of, but again, it still needs a lot of work. If you are interested in the project and are coming to MAX San Francisco this year, I would love to meet you. My twitter id is @arpit.

me

See you at Max

Mixing up OpenPyro and Facebook: FacebookTV

For the last couple of weeks, I have been working quite a bit more on OpenPyro. Writing a new UI framwork in a vaccum almost never works, so I needed an app to build using OpenPyro. I had some Facebook API code handy so I figured I’d try something with that. So here is a screencast of the app as it is right now. The application uses Facebook’s desktop api to get all the friends of a user and their favorite TV and Movies. Then I group the shows/movies together to see what the most popular of them are and sort them with the most popular ones at top. The data is rendered in an OpenPyro chart component. The TV and Movies are in two different Horizontal Chart components and sit inside an OpenPyro container called SlidePane. SlidePane extends the OpenPyro ViewStack (which is very similar to the Flex ViewStack) and automatically handles sliding between different views (each being an OpenPyro UIContainer). Clicking on an entity does a show/movie lookup from Fancast.com, and also lists who among your friends have added the show/movie as their favorite. The BarChart below is segments those friends by gender or by relationship status ( I have to say, the Facebook API is pretty rocking, and I can segment the data on a variety of axes. )

Here is the awesome-est image of it all:

FacebookTV filesize

Yup. The whole sucker is about 60K. And that includes Labels, Buttons, Lists, ComboBoxes, Layouts, Painters, Containers, etc etc.

So here is the show:

OpenPyro is still not ready for a general release yet, but its coming along pretty sweetly.

Comments welcome.

A sneak peek at OpenPyro: A lightweight alternative to Flex

For the last few months, I have worked quite a bit with Flex and at times, the complexity of the framework really makes it hard to work with. I have mentioned my problems with Flex in an earlier post but the gist of it was:

  • A lot of our projects are widgets rather than apps that are as big as the webpage itself. The smaller the apps get in dimensions, the more unacceptable the load time becomes, so we could not create apps that compiled to swfs greater than 250k (even with framework caching).
  • Flex apps are memory intensive on their own and I really need that memory for other things like rendering high def video (which a lot of our apps do).
  • I want to build apps that are more expressive that what Flex lets me do.

Given these requirements, I have started working on an open source framework modeled after the Flex framework but with the primary goal of being really light and easy to extend. The project is actually being developed within the Flash team at Comcast Interactive Media to allow us to develop apps faster and give all the developers here a common standard to develop against. It started out as an R&D project but is now an official CIM project, so will definitely evolve in the next few months.

OpenPyro is not really complete but its at a good point where I can show it off a little bit and get some feedback. Here is what the framework does so far:

  • A bunch of pre-built components like Buttons, Sliders, Scrollbars, etc (1.0 release should have most of the components we are used to)
  • Has an explicit component lifecycle very similar to Flex with the concept of invalidation and differed UI update
  • Layout management including using percent based layouts (so you can set a dimension of a control as a percent of the container its sitting in using percentWidth or percentUnusedWidth). Also there are no layout specific containers (like H or VBox) but rather a container can be assigned any layout.
  • Runtime skinning
  • Separation the look of the controller (based on a skin file) with its behavior (like Flex 4 or OpenFlux) [work in progress]
  • Concept of Painters (not as complex as Degrafa yet but still pretty good and getting better)
  • The components are not tied to the framework. So you can just use a component like a Scrollbar or Slider in your As3 / Fla project.

The best part is even some pretty complex layouts like the image below weigh only around 23k. Imagine doing that with separate V and HBoxes.

There is also a bunch of other classes (a collections framework-esque package as well as a host of utility classes) that I will migrate to OpenPyro once the core components are at a good point. So stay tuned for that.

Of course with all its wins, there are still things in Flex that OpenPyro will not be able to do:

  • Data Binding: Since Flex does this at compile time using code generation, this has not been done.
  • XML based layout: This may happen later (and may or may not be compile time) but this is definitely a phase 2 thing.

I will post more examples in a couple of days to show some actual apps built with OpenPyro, but in the meanwhile take a look at the video below and let me know if you have any comments on the direction the framework is taking. If you want to look through the source code, the project is hosted at the github. OpenPyro will be released under the MIT license. There is also a google group for the project at http://groups.google.com/group/as3-pyro-user-group/.