The new Flex 3.4 SDK has been released. Since Adobe still hasn’t gotten around to fixing this bug, I’ve again taken it upon myself to release my MonkeyPatched code for Flex 3.4 that allows you to use the Flex DragManager along side the Native DragManager in an AIR app. You can grab the code from SVN from my google code site.
In the new version of ObjectHandles2, we have the ability to use Sprites as the drag handles to resize and move objects around the screen. I was recently made a committer on the project and have added some functionality to allow Degrafa to be used to draw the handles and rotate them along with the object. Check out Example7 that highlights this new functionality.
ObjectHandles2Example View Source is enabled
I’ve recently had the opportunity to dig into Flex 4 skinning a bit deeper with the latest beta. While there is a lot to be desired from the separation of concerns in moving display code into the skin and leaving logic code in the component, there is one LARGE gaping deficiency in Adobe’s model.
I’ve noticed a number of people here (Andy McIntosh), and here (Andy Hulstkamp) working with button icon skins. The main reason for this is that Adobe saw fit to remove the icon property from the Spark button. Being a visual element, it does make some sense for Adobe to let users specify a button icon inside a skin as opposed to putting it in the main Button component.
Now to address the LARGE gaping deficiency in Adobe’s model. Adobe developed the skinning architecture WITHOUT taking something into account that we developers use on a regular basis. This is the Object Oriented principal of Inheritance. Note the following excerpt from Adobe’s livedocs:
Try to encapsulate skinning code. Place code that is used by multiple skins in the component class. Place code that is specific to a particular skin implementation in the skin class.
Most skins use absolute layouts within the skin class.
When creating skins, do not subclass existing skin classes. Instead, copy the source of an existing skin class and create another class. Use this method especially if you are going to reuse the skin for multiple instances of a component or multiple components. If you want to change the appearance of a single instance of a component, you can use FXG inline.
When creating a Spark skin, you can use MXML, FXG, embedded images, or any combination of the above. You do not use run-time loaded assets such as images.
The inability to inherit skins is going to kill my productivity as a developer. For example, let’s say I really liked the code Andy McIntosh had done with the IconButton (which I do) and wanted to re-use it. Let’s say I’ve also done some work on button skinning for my application and I want nice looking gel buttons like this:
Can I set up my GelButtonSkin to inherit from Andy’s IconButtonSkin to take advantage of his image functionality, but override his background drawing with my own? The simple answer from Adobe is NO. In order to accomplish what I want, I’ve have to create a completely new skin class and use copy/paste from both my GelButtonSkin and Andy’s IconButtonSkin to get my desired functionality.
You might say, “Well, Adobe says in the quote above that code that is used by multiple skins should be placed in the component class”. This begs the question though… Why did Adobe remove icon as a button property in the first place? It’s obviously one of those things where you might want different flavors of it. Perhaps a rectangle button /w icon vs. a rounded button /w icon. Instead, we’ll see a fragmentation of Flex while everybody and their brother develops their own flavor of IconButton along with their own custom skins to do exactly what they want. Productivity for developers moving between projects is going to take a hit due to this lack of code re-use.
Note: This post is intentionally antagonistic. I’d love to be proven wrong on my assertions. If someone has come up with an elegant work-around to the problem of skin re-use and inheritance that doesn’t resort to copy/paste, I’d love to be educated and saved from my ignorance.