Blog

  • Scale 9 in Silverlight

    Silverlight Scale 9Samples at bottom.

    In creating video players at work in Silverlight, we started getting designs that needed Scale 9. Silverlight, Blend, and/or Design don’t seem to have a Scale 9 option that I can find, so I built one in JavaScript for Silverlight 1.0. Porting to C# for all you Silverlight 1.1 peeps out there should be trivial since it’s not a lot of code.

    What is Scale 9?

    Scale 9 is the ability to have an image scale in a nice, visually appealing way by breaking up the image into 9 sections. It is used primarily with containers such as the windows you use on your OS. For example, if you scale the browser or RSS reader you are reading this in right now, you’ll notice that the top task bar can shrink it’s width, yet still look consistent and nice. If you shrink it vertically, you’ll notice that the sides shrink, yet still keep aligned, and looking nice as well.

    Scale 9 was in my experience done a lot in Flash because as Flash got used more in the application development field, people started creating controls. Those controls were re-usable visual components, and a lot could redraw themselves via code. This code would allow visual layout changes very easily. So, a Button could be as big or as small as you wanted it to be just by calling the Button’s setSize function, and passing in a width and height. The Button would “handle” sizing itself to that size.

    However, a lot of anything in Flash before ActionScript 3 had a lot of overhead in CPU and RAM. So, by implementing Scale 9 natively in the compilers & Flash Player, you reduced the image count from 9 to 1. For 30 buttons, that’s 270 visual objects being moved and sized to 30; 1 to 1. You can see how this is an awesome feature, especially when the runtime does the scaling for you taking the code out of the equation as well.

    RectanglesObviously, for uniform rectangles, you don’t need scale 9. For rounded rectangles, or for anything that has non-uniform edges, if you start scaling it, it’ll stretch and look nasty.

    Here’s a good article by Aral that shows how scale 9 works in Flex (scroll mid-way).

    How does Scale 9 work?

    Image GridScale 9 works by breaking the images into 9 sections. The 4 corners do not scale their width and height, but do reposition themselves to their respective corners. The top left always stays in the top left. The top right always stays in the top right. And so on.

    The top and bottom can scale their width larger or smaller, but not their height. The left and right side can scale their height, but not their width. The center scales normally, and positions himself in the middle of everyone.

    Combining this with custom sliced images, you have 9 pieces that form your image, and can scale to any size, though usually have a minimum width and height.

    How does my implementation differ from Flash & Flex?

    Flash 8 and Flash CS3 do vector only. Additionally, they only require 1 image whereas in this example, you need 9 bitmaps sliced up. Flex can do vector and bitmap, but has the same advantages of Flash; 1 image. Both use the compiler to define the drawing matrix where mine just re-positions things on the fly based on the passed in width and height. Mine’s written in JavaScript which isn’t compiled like C# or ActionScript 3 so runs slower.

    The performance for me, however, is beyond acceptable; for a video player in a browser, it performs very well.

    How do you make an interface capable of being scaled via scale 9?

    A few steps.

    1. Get a designer to create an appropriate comp.
    2. Slice the image up into 9 pieces.
    3. Implement those 9 images into Blend.
    4. Put code to re-position & resize them in your JavaScript.
    5. Tweak.

    Explain to the designer that the border & background, typically a video player, will be scaled to a variety of width’s and height. If you say, “Emulate how Windows XP with the silver theme has those nice, scaleable windows that look good at most any size”, that helps. Things to watch out for are drop-shadows, gradients that go the same direction you are scaling, and lots of textures on the non-corners. Those 3 make it really hard for the design to scale. If the designer can scale it in their image editing program as a bitmap (not vector) and it still looks good, that’s a good acid test for the design. “How would it look with a 4×3 video in it… say, 320×240? How about an HD 16×9 one that’s 420×270?”

    Fireworks RedOnce you get the image, slice the mofo up into pieces. I use Firefox because it’s the shiz for doing quick production work. You could also use Design or Photoshop, for example… I’m just fast at “doing the work the designer doesn’t want to do” in Fireworks. You typically align 4 guides to make your 9 sections. You then make sure the tops can scale width wise, and the sides veritcally. Then you export the slices as PNG’s. You do PNG because it’s lossless comperssion (meaning no image quality loss from compression), and it supports transparency. Then…

    Blend Red…import those bad boys into Blend. Make sure the width and height of the XAML Image tag matches your exported PNG’s so you don’t get any weird scaling. If you see transform matrix tags nested in your image tags for the background pieces, delete that mess; you are using code, not Blend, to position and size your background pieces.

    Use the example scale 9 code below in your JavaScript to scale 9 your interface. Keep in mind CSS has a major impact on this actually working in browsers other than IE. Here’s some example code (at the bottom, 2nd to last thread) on how to get this to work in both browsers.

    Tweak. You may not get it right the first time. Additionally, I swear Silverlight is either scaling my images a tad, or I’m just using Canvas.Left and Canvas.Top wrong. You’ll notice magic numbers in the redraw function; these change EVERY design. For some reason (maybe half-pixel values I’m not seeing) some designs either bleed into another by a pixel, or miss one. The “1”‘s in the redraw function are there to make it, like Goldielocks, just right. Test in both IE, Firefox, and Safari if you gotta Mac or are brave enough to install Safari on your PC.

    Scale 9 JavaScript Code

    Scale9 = function(tl, tc, tr, cl, c, cr, bl, bc, br){
    
    	this.tl = tl;
    
    	this.tc = tc;
    
    	this.tr = tr;
    
    	this.cl = cl;
    
    	this.c  = c;
    
    	this.cr = cr;
    
    	this.bl = bl;
    
    	this.bc = bc;
    
    	this.br = br;
    
    };
    Scale9.prototype.redraw = function(sender, width, height, offsetX, offsetY){
    
    	if(offsetX == null) offsetX = 0;
    
    	if(offsetY == null) offsetY = 0;
    
    	this.move(this.tl, offsetX, offsetY);
    
    	this.move(this.tc, this.getX(this.tl) + this.tl.width, this.getY(this.tl));
    
    	this.move(this.tr, width - this.tr.width, this.getY(this.tc));
    
    	this.tc.width = width - this.getX(this.tc) - this.tr.width;
    
    	this.move(this.cl, this.getX(this.tl), this.getY(this.tl) + this.tl.height);
    
    	this.move(this.c, this.getX(this.cl) + this.cl.width, this.getY(this.cl));
    
    	this.move(this.cr, width - this.cr.width, this.getY(this.cl));
    
    	this.c.width = width - this.getX(this.c) - this.cr.width;
    
    	this.move(this.bl, this.getX(this.cl), height - this.bl.height - 1);
    
    	this.cl.height = height - this.getY(this.cl) - this.bl.height - 1;
    
    	this.c.height = this.cl.height;
    
    	this.cr.height = this.cl.height;
    
    	this.move(this.br, width - this.br.width, height - this.br.height - 1);
    
    	this.move(this.bc, this.getX(this.bl) + this.bl.width, this.getY(this.bl));
    
    	this.bc.width = width - this.getX(this.bc) - this.br.width;
    
    };
    Scale9.prototype.move = function(obj, x, y){
    
    	obj["Canvas.Left"] = x;
    
    	obj["Canvas.Top"] = y;
    
    };
    
    Scale9.prototype.getX = function(obj)
    
    {
    
    	return obj["Canvas.Left"];
    
    };
    
    Scale9.prototype.getY = function(obj)
    
    {
    
    	return obj["Canvas.Top"];
    
    };

    Example Usage

    function onLoaded(sender, args){
    
    	var plugin = sender.getHost();
    
    	plugin.content.onFullScreenChange = onFullScreenChanged;
    
    	plugin.content.onResize = onResized;
    
    }
    
    function onResized(sender, eventArgs)
    {
            var plugin = sender.getHost();
            setSize(sender, plugin.content.actualWidth, plugin.content.actualHeight);
    }
    
    function onFullScreenChanged(sender, eventArgs)
    
    {
    
    	var plugin = sender.getHost();
    
    	setSize(sender, plugin.content.actualWidth, plugin.content.actualHeight);
    
    }
    
    function fullscreenThisMugUpInHere(sender, args)
    
    {
    
    	var plugin = sender.getHost();
    
    	plugin.content.fullScreen = !plugin.content.fullScreen;
    
    }
    function setSize(sender, width, height)
    {
    
    	var scale9 = new Scale9(sender.findName("bg_tl"),
    
    	sender.findName("bg_top"),
    
    	sender.findName("bg_tr"),
    
    	sender.findName("bg_cl"),
    
    	sender.findName("bg_center"),
    
    	sender.findName("bg_cr"),
    
    	sender.findName("bg_bl"),
    
    	sender.findName("bg_bottom"),
    
    	sender.findName("bg_br"));
    
    	scale9.redraw(sender, width, height);
    
    }

    Conclusions

    While vector graphics can be redrawn to get around scale 9 problems with code, not all designs are that simple. Furthermore, as much as Microsoft wants the design community to use Design to create interfaces, they don’t; they use Illustrator, Photoshop, and other 3D and video compositing software NOT made by Microsoft. As such, you’re likely to get a bitmap file that you’re expected to implement into Silverlight instead of an easy, vector design with XAML behind it. Blend is pretty pimp in it’s handling of PNG’s, so if you gotta go raster instead of vector, go with the best.

    Also, keep in mind scale 9 works the same for fullscreen; you just call the scale9.redraw function in the onFullScreen as well as the onResize and it’ll nicely scale to the size of your monitor.

    Thanks for the Gray frame design on such short notice, Charlie!

    Samples

    Red Video Player – Example | Source ZIP

    Gray Video Player – Example | Source ZIP

    Released under a Creative Commons GNU General Public License.

  • No exclude.xml in Flash CS3 for AS3: Solution via Bridge Pattern

    Exclude.xml, functionality in Flash 8 and MX 2004 that allowed you to exclude ActionScript 2 classes compiled into your SWF, does not work in Flash CS3 for ActionScript 3. A similar function is available in Flex 2 via the load-externs option. This is the basis of how Flex modules work. The lack of this functionality just adds another challenge to Flash Developers who have expectations coming from AS2; this actually makes AS3 usage in Flash worse than AS2 when creating Flash sites, or large Flash applications.

    “Great Jesse, no one cares about your vendetta, so how do we fix it?”

    I have no clue, but the server architect I work with, John Howard, had a good idea. We’ll probably implement it in the next 2 weeks after we hit some interim milestones. I’ll explain his idea at the bottom, but first a review. If you want to skip the review, go to the bottom.

    Why Exclude Classes?

    When creating large Flash websites or applications, you’ll tend to have many SWF’s. This was especially true with AS2 driven not just from a media perspective, but also from a performance one. If you go to a visual website, say Flickr, and spend 20 minutes on it, you’ll probably download hundreds of images. Rather than download 20 minutes worth of images initially, you download on the fly and download whats needed. Flash and Flex apps can be built this way; it’s called excluding classes in Flash, and modules in Flex.

    In Flash, the main way to download assets over time is to load external SWF’s into another SWF. You use the loadMovie/loadMovieNum functions or the MovieClipLoader class, or the Loader component to do this pre-AS3. Although you can load images and video externally from a SWF just like a webpage can, the SWF format itself has visual advantages, such as images that can have alpha channels, yet also have JPEG compression applied to those images. JPEG does not have alpha channels, GIF only has a 1 bit alpha, and PNG never got the glorious browser support we all desired and only has lossless compression. When creating visual layouts that have a lot of media such as a multitude of images, audio, and/or video meshed with animations, this can be a stand alone SWF. Typically those types of things would be put into their own symbols such as a Graphic or MovieClip. However, if they got large enough, you should make it an external SWF for 3 reasons.

    The first is because it’s faster for you to make changes to the SWF. When you do a test movie, aka compile a SWF, Flash has to render animations, compress your bitmaps and sounds, as well as integrate your video if any. This can take a lot of time. Sometimes that time isn’t actually that bad, but because of the frequency in which you are re-compiling your SWF’s to check for visual accuracy, and doing this say every 2 minutes, and you end up saving 2 seconds in your compile… well, hey, that’s almost 10 minutes of your day you just saved right there! This is more apparent for larger media, however, like mp3 compressing a bunch of audio, or integrated video that can make your FLA’s take a minute or more to compile.

    The second is you can get help, aka RAD development. Instead of sharing the same FLA, you can have a project broken up into multiple FLA’s that another designer/developer can use so you both can work together on the same project.

    The third is that you only make the user download what they need to download. If you have a site that has 6 sections, you only need to make the user download the first section. You can either load the other section when the user clicks to go there, or download in the background once the first is done.

    The work-flow for visual projects in Flash is dead easy. There are a lot of frameworks, such as Gaia, and methodologies out there for facilitating this kind of work.

    For Flex, you have to be a rocket scientist. Flex 3 has some help in this department, but they are a long way off in how easy this is in Flash.

    For Flash applications, it’s a little different. In the beginning, our first enhancement to this was Remote Shared Libraries. What this allowed you to do was have a “reference MovieClip”, or any other symbol for that matter, in your library. Your symbol would have the SWF that it is stored in stored with the symbol as metadata. You’d go make that Symbol in another FLA, and upload those SWF’s together to your website. When your SWF was played, if a remotely shared symbol appeared on the time line, the Flash Player would automatically go download this for you.

    The bad was you really didn’t have much in the way of code in control or getting events about this. However, that ended up saving you a lot of work since it did it for you. Either way, this worked out pretty good because you could treat the symbols as normal symbols; the FLA would actually keep a local copy. You could update the symbol from the Library in case it changed in another FLA. You could additionally ensure every time you compiled it updated for you, but this was the slowest thing on the planet.

    In the end, Remote Shared Libraries were a management nightmare in Flash. For simple projects where you had a master SWF, they worked damn good. For anything more complicated, it was what I call “Flash Jenga” (Jenga is a game consisting of a tower of stacked wooden blacks the size of your pinky. The challenge was to remove bottom blocks without making the whole thing topple). If you got it to work, you were the shit, but it was very easy to break, and once it did, things came crashing down. The tools never really helped you manage your Remote Shared Libraries.

    Flex Builder has some nice improvements in this realm with regards to tool support.

    The biggest problem, however, with Remote Shared Libraries in regards to application development and code. Like I said, they still work good for assets; anything that isn’t ActionScript classes.

    Since ActionScript 2 and 3 utilize a lot of classes, and thus have dependencies, this makes things challenging when creating your applications for low initial download impact in mind. I’ll rehash my version here, but reading these 3 blog posts by one of the the mxmlc compiler creators, Roger Gonzalez formerly of Adobe, is probably a little more authoritative and better written. (Multi-SWF Applications, Modular Applications (part 1), Modular Applications (part 2)).

    It’s hard enough to architect an application, especially when accounting for a designers needs for dynamic Views. It’s another when you visualize a package of classes, and then have to account on how to reduce dependencies so you only load some classes in some SWF’s, and others in another SWF, but be sure not to use in a master SWF, thus reducing the overall file size. This can lead to code duplication, or a non-efficient use of a RSL, or too much in an RSL that’s not used by 80% of the application. As if software development wasn’t hard enough, you have a designer who keeps changing your MovieClip instance names.

    You could just say fuggit, and just load a bunch of SWF’s as users navigate to those sections. However, your wasting bandwidth by using duplicated code. For example, in the image below, 3 forms are loaded into a master SWF on the fly whenever a user navigates to that section. Each other has it’s own unique set of components; however, each also has it’s own copy of Button, or mx.controls.Button to be exact in AS2. Say that your Button is 14k. You’ve now duplicated that 14k across 3 SWF’s.

    Exclude-01

    …however, why not just load that class once, and have all other SWF’s use that same already loaded class? You can! First, a review on how AS1/AS2 classes work.

    In the old AVM, aka, the one that runs AS2 and A1 (regardless of player version), classes are defined on _global. The _global keyword is like this object that never dies, and is accessible via the _global keyword in ActionScript. It’s also accessible across SWF’s and across _levels (_level is like a loaded SWF basically). This means that SWF’s loaded in can access classes on _global as well as defining their own. They cannot, however, overwrite classes. In AS3, this behavior is controlled via ApplicationDomain; in AS2, it is what it is.

    Since you know you’ll be loading those 3 SWF’s into a SWF that will already have the Button class defined, you can then just not compile those 3 SWF’s with the Button class. The user then only has to download 14k once; any other SWF that uses the Button class can use that already downloaded class. In the example below, the Button class has been moved to the shell.swf, increasing it’s size from 8k to 22k. However, notice that that same 14k is now removed from the login.swf, the amount.swf, and settings.swf.

    Exclude-02

    In this particular example, you’ve ended up saving 24k! Now, imagine a large website or large application consisting of dozens of SWF’s that could potentially use the same class. You can see how this feature saves a ton of bandwidth.

    How Exclude.xml Works

    Exclude.xml works like dis. If you have a FLA called “my.fla”, you create an XML file in the same directory next to the FLA called “my_exclude.xml”. When you compile your FLA, Flash will look for that exclude.xml file. If it finds it, it’ll read it. Any class written in that XML file will NOT be compiled into your SWF. The con to this is the SWF no longer works on it’s own; you have to load it into another SWF to test. The plus is that you’ve now saved file-size since the SWF will get the class it needs to work from another main.swf. Most importantly, your work flow has changed; just your SWF.

    In the past, I wrote some JSFL to automate this. One JSFL script would delete the exclude.xml file, and then do a test movie. You map this JSFL to Control + Enter so your Test Movie works as normal. I then created another JSFL script to create the exclude.xml based off of a set of classes I knew would be shared throughout the site, and then test your movie. I then mapped this JSFL to Control + Alt + Enter, replacing test scene. That way, you can create SWF’s ready for deployment easily.

    Now that Flash CS3 has E4X, writing such scripts is a ton easier, and gives ANT in Eclipse a run for it’s money in automation. Course one could use Rake (Ruby‘s version of Make), but anyway.

    In Flex using mxmlc, this part is actually automated for you; the XML you need is generated via the mxmlc -link-report parameter. You immediately feed that generated XML file to -load-externs, and booya, you have a SWF with those classes removed.

    So, pretty pimp, huh? Guess what; it doesn’t work in Flash CS3 for AS3. I know, right? “Yeah hi, I’ll take some AS3 with a side of lame sauce.”

    Using mxmlc Doesn’t Work

    I tried using mxmlc with -incremental set to true, making sure it doesn’t actually recompile the entire SWF, but just those classes that have changed. If you make sure your FLA has a Document class, this’ll work; mxmlc can use that as the root class. However, in recompiling your classes, it basically ignores the symbols your FLA has created, thus “I’ll take it from here” attitude. Um…mxmlc, dude, f-off, at least we can use pixel fonts…

    You could do this in MTASC for AS2, I guess their bytecode replacement techniques are just different. Either that, or I’m maybe missing a mixture of mxmlc compiler arguments… :: crosses fingers hoping someone says so in comments ::

    Bridge Pattern to the Rescue (sort of)

    So, my boss suggested a proxy technique. Basically, we use the J2EE blah blah blah official blah blah Bridge Pattern. The Bridge Pattern in a nutshell is 2 classes that implement the same interface; one provides the pretty face, whilst the other does all the work. The pretty face is called the Abstraction and the one who does the work is called the Implementation.

    If you were going to create a Button component using the Bridge Pattern, you would do it in 3 steps.

    1. Create the IButton interface
    2. Create the Button class that implements IButton
    3. Create the ButtonImpl class that implements IButton, and does all the work.

    Flex 2 actually uses this in a few places, specifically the ToolTipManager class. ToolTipManager merely proxies everything to ToolTipManagerImpl. He instantiates an Implementation class (ToolTipManagerImpl) via a magic string to ensure there are no dependencies, meaning the compiler doesn’t know to compile it in. To ensure it is compiled in, however, they do do (gross) a dependency variable above that.

    This is how the Bridge pattern will work to save file size. The child SWF’s will only contain the interfaces and abstractions; the implementations will be in the main SWF. First thing to do is create the interface, mainly for typing purposes.

    Now that that’s done, I do the same thing the ToolTipManager does; I instantiate the ButtonImpl class inside of Button via a magic string. This ensures that Flash doesn’t see the usage of the class. If it did that, Flash would compile it in. A magic string, however, cloaks it from the compiler. Using flash.utils.getDefinitionByName, I can instantiate the ButtonImpl class with my magic string:

    var btnImpl:Object = getDefinitionByName("com.multicast.controls.ButtonImpl");
    impl = new btnIpml() as IButton;

    Now, I can just create my sets of components as normal:

    var btn:Button = new Button();
    addChild(btn);

    However, the ButtonImpl class won’t be compiled into the child SWF’s. Instead, he’ll be compiled into the main shell.swf.

    Based on some initial tests, I reckon interface will run about 500 bytes to 2k, and the Button class from 2k to 4k. The Impl will be around 8k. So, being conservative and rounding up, all of my child SWF’s will no longer have 14k in them, but rather 6k. Like exclude, the developer whether using Flex Builder with an ActionScript project, or Flash CS3, can code normally with AS3’s strong-typing, and/or Flash’s time line and symbols. The down-side is I’m still duplicating anywhere from 2k to 6k in any additional child SWF that uses Button.

    It’s not perfect, but it’ll do.

    Unknowns

    What I haven’t figured out yet is the implementation details. Premature optimization is the root of all evil so I hear, but seriously, how much speed does keeping the interface for strong-typing really give me? What if I just remove the interface, and cast impl in the example above as a DisplayObject, or more accurately, a MovieClip? I feel the Interface is for Java people who like a bunch of classes; to me, 2 is too many, let alone 2 and an interface. I’m only doing this because a feature that worked in 2 previous Flash IDE’s now doesn’t; don’t punish me by making me write more classes to compensate for a feature that removed classes in the first place. Convention works for the Ruby guys; why not me? I don’t really want to spend much time on benchmarks, but any dynamic look up will cause the old AVM to be used, and since this component set is created with AS3, it kind of defeats the purpose of using AS3 if you aren’t going to take advantage of the runtime speed.

    Secondly, what is impl, a DisplayObject, or rather a class that uses a DisplayObject via Composition? Traditional programmers who came to Flash in the past would use Composition all the time because the thought of extending a GUI base class freaked them out. So, instead of extending MovieClip or Sprite, they’d instead store a reference to the MovieClip or Sprite passed in the constructor. All methods would then act on that reference, as opposed to the class itself via Inheritance. Would doing Composition be better? Although it may have a tad more code, it’d be redundant, so hopefully zlib SWF compression would see that and I’d still hit my small file size goal. Furthermore, I wouldn’t end up with twice as many DisplayObjects. In AS2 that was bad, but in AS3… not so much. If all Buttons were just a simple shell with the “real” Button inside it as the impl, is that really that bad? My gut says make the Implementation class via Composition to save on the number of DisplayObjects.

    Basically, rather than doing:

    // Button.as
    private var impl:IButton;
    
    public function Button():void
    {
            var btnImplClass:Object = getClassByDefinition("com.multicast.controls.ButtonImpl");
            impl = new btnImplClass() as IButton;
            addChild(impl);
    }
    
    public function setSize(w:Number, h:Number):void
    {
            impl.setSize(w, h);
    }
    
    // ButtonImpl.as
    public function setSize(w:Number, h:Number):void
    {
            this.width         = w;
            this.height     = h;
    }

    I’d instead do:

    // Button.as
    private var impl:IButton;
    
    public function Button():void
    {
            var btnImplClass:Object = getClassByDefinition("com.multicast.controls.ButtonImpl");
            impl = new btnImplClass(this) as IButton;
    }
    
    public function setSize(w:Number, h:Number):void
    {
            impl.setSize(w, h);
    }
    
    // ButtonImpl.as
    private var btn:IButton;
    
    public function ButtonImpl(ref:IButton):void
    {
            btn = ref;
    }
    
    public function setSize(w:Number, h:Number):void
    {
            btn.width         = w;
            btn.height        = h;
    }

    Any other ideas (or corrections), lemme know.

  • How to Show Regular Time in Google Spreadsheets

    I cannot read military time. I can read regular time. Google Spreadsheets at the time of this writing only supports formatting for military time. After digging around, I found this formula works:

    =TEXT ( theCell, “hh:mm a”)

    You can then have the military time column (which will auto-format when you type a time value in) to the left, and then use the above formula for the column to the right. Combined with changing the military time column to a lighter text to lower it’s visual prominence, you get something like this:

  • Flex GUI WYSIWYG Creator Prototype

    Screen cast and source at the bottom.


    Preface

    John Grden created something like this in the past called FLEXible. Basically, you use Flex as a drag and drop interface to create GUI’s. The GUI’s are represented as XML, and this XML is used in another context. FlexBuilder creates and renders MXML as well as ActionScript. Web browsers render HTML, and a variety of tools from Notepad and Dreamweaver can create HTML.

    The reason to use a WYSIWYG editor for layout is that you get more visual control when laying out interfaces. Sure, you can edit an x attribute on an XML tag for pixel precision, but if you want to see the entire interface, a WYSIWYG is the way to go. You can make a visual change, and see how your design is affected. A lot of early Flash Development was layout of the interface first, code second.

    Another use of WYSIWYG editors is for Content Management Systems. In the case of intranets, some have small sections where you can enter custom text, whether normal or HTML, that show up in approved sections of the company website. More advanced ones like WordPress blogging software has a plethora of controls for writing a blog entry. Many buttons will automatically write the appropriate HTML for you. This saves massive amount of time, and allows you to focus on your blog and, and less time on how your blog entry is made.

    We have wants at work for a variety of visual CMS WYSIWYG editors. For customers who request minor graphical and layout changes to their products they purchase from us, it is much quicker to simply re-position a GUI element via a WYSIWYG editor, confirm visually in real-time that is what they want, and save these settings to the profile. This, as opposed to changing some text markup or a value in a MySQL table, and going through the management chain through phone calls and email to answer the question, “I made the change; were they ok with it?”.

    While both actions can take about the same amount of time, using a simple WYSIWYG editor doesn’t require a degree in computer science. Nor does using WordPress ‘ text editor. Easy to use interfaces that generate the necessary code. Whether they are used by users, or client managers doesn’t matter; what matters is that developers are developing instead of spending their valuable (read costly) time on making extremely minor graphical changes to things that anyone could do that had an Internet connection, a web browser, and login credentials.

    I’m all about reducing overhead costs.

    The OTHER Drag and Drop in Flex

    Flex is known to have pimp drag and drop features. They are built into the SDK, and require a boolean and 2 event handlers to work. Mizz-nagic. However, there is another way to do drag and drop in Flex. It’s called the startDrag method, and it’s a party of Sprite. He has a stopDrag method as well. These methods are more efficient than doing your own emulation of drag and drop since they are built-in. The downside is they still have the same refresh problem, but you can fix that the same way you have in the past using a mouse move event handler, and calling updateAfterEvent on the event parameter.

    Using these 2 methods, you can build your own drag and drop interface that consists more of just using the Flex SDK list classes. They are, however, more low level so you have to do some more coding legwork.

    Introduction

    I built this Viewer Editor for a co-worker at work. The goals were thus:

    1. Needs to be done in 2 days.
    2. Worked on outside of work core hours.
    3. Implement important features to showcase ability to create interfaces vs. being feature complete.

    In short, a prototype for a demo. You know what that means kiddies: uber-hacks, kludgey code, and something you don’t bring to an interview (unless you are damn good at explaining context). The GUI you build can be saved as XML. This XML can be re-read in and the Viewer Editor will re-build the interface so you can edit it. This XML ultimately is read by a .NET web service that will build an HTML front-end based on the client’s settings and this layout XML. If a client wants something moved “20 pixels to the right”, you launch the interface, move the GUI element, and click save.

    So why show it knowing the code is bleh? A few reasons:

    • Shows how to do the ‘other’ drag and drop in Flex as well as the regular, built-in kind
    • Shows how to dynamically build forms through ActionScript using the Flex Form & FormItem classes
    • Shows how to use 50 billion bindings through ActionScript
    • Shows what you can build in 12 hours or less using Flex and Red Bull.

    Built JB Style; no Cairngorm overkill insanity here. Speed, people, speed! Code gen is for people who can’t type fast.

    You can view the Captivate screen cast, read the following, or both… or cross the border with a chicken and crowbar.

    Controls

    The Viewer Editor is made up of 3 panels to interact with laying out controls on the Canvas. The first is the Control Panel. This guy is configured via external XML. He dictates what you can drag and drop onto the Viewer Canvas.

    The Viewer Canvas itself is basically just a Canvas that draws draggable controls inside itself. You can select controls, drag them, as well as modify their properties in the Property Inspector.

    The Property Inspector shows the modifiable properties of a control when you select that control. You can also select the Viewer Canvas.

    Although there are 2 missing features such as deleting and changing z-order of elements, this could be easily done by having the Controller either remove an item from the currentViewer.children, or by changing the order of an item in the currentViewer.children.

    Conclusions

    Although Flex 2 is positioned as a way to build Enterprise applications, whilst Flash is for lightweight, speedy RIA development, clearly with the right attitude you can use Flex Builder as a prototyping tool. Drop the frameworks, ignore the code review, and down the caffeine.

    There is also a lot of potential for GUI WYSIWYG’s as front ends for CMS systems. From Scrapblog.com, gModeler, and many others. While it’s great to have a extremely configurable back-end, it’s also nice to have a quick, easy way to modify values in that back-end. It’s even more cool when users and clients can do this themselves in a controlled manner using a tool specifically built for allowing them to configure what they want changed most, without having to utilize a developer’s time.

    It’s fun to do prototypes and CMS’ in Flex.

    Viewer Editor – Screencast | App | Source | ZIP