Monthly Archives: September 2003

hacking startDrag() to provide a solid _droptarget solution


I found a solution to a longstanding problem in Flash. In all players, flash does not recalculate the value of _droptarget unless the mouse is moved. The only exception to this rule is when startDrag() is called initally!

In PowerSDK, startDrag() is called via a setInterval, thus _dropTarget is always dead accurate. This is especially true given that PowerSDK is loaded into a high layer _level10000.

Now the problem has changed, startDrag() and stopDrag() no longer work! But wait, there is a fix for that too!

To provide dragging functionality, I rewrote a mirror drag method that supports dragging many items at once.

mymc.drag(0) // no snap to cursor

yourmc.drag(1) //snap to cursor

Let me repeat that: Dragging N movieclips at once with constraints on each clip! Wow, that was easy!

Here is a great example:

http://www.powersdk.com/sample/v16/drag.html

Why would PowerSDK want to know the correct _droptarget?

In order to send contextual onTarget events, I needed to know the _droptarget. Watching changes in _droptarget value, then becomes a great source of events allowing the detection of onTargetRollOver and the mirror onTargetRollOut. Here are the supported events:

MovieClip.onTargetDouble (timer)

MovieClip.onTargetDragDrop (dropee)

MovieClip.onTargetDragOut (dragee,to)

MovieClip.onTargetDragOver (dragee,from)

MovieClip.onTargetEnterFrame (timer)

MovieClip.onTargetKeyDown (code, ascii)

MovieClip.onTargetKeyUp (code, ascii)

MovieClip.onTargetMouseDown ()

MovieClip.onTargetMouseUp ()

MovieClip.onTargetMouseMove (timer)

MovieClip.onTargetPress ()

MovieClip.onTargetRelease ()

MovieClip.onTargetReleaseOutside ()

MovieClip.onTargetRightMouseUp ()

MovieClip.onTargetRightMouseDown ()

MovieClip.onTargetRightMousePress ()

MovieClip.onTargetRightMouseRelease ()

MovieClip.onTargetRightMouseReleaseOutside ()

MovieClip.onTargetRollOut (to)

MovieClip.onTargetRollOver (from)

http://www.powersdk.com/sample/v16/dragdrop.html

The events pass data too. These arguments make it easy to do great things with very little code. They are especially handy in components as they reduce the volume of event handling code and allow movieclips to detect subtle changes in focus without adding anything to a class.

Much more to come!

Ted ;)

Announcement :: PowerSDK Version 16 Released with Source! ;)


PowerSDK version 16 is released and resolves issues with F7 Player compatibility. I strongly recommend you upgrade to this release as it resolves some longstanding errors and introduces a bunch of new functionality. V16 is a ground up rewrite of the powerSDK framework and incorporates many changes since last release.

Look before you leap >> Online Examples

Download PowerSDK Version 16 + Examples

Download PowerSDK Cummulative Releases 14, 15, 16 + Examples

Open Source Software License

Development Listserv

Documentation

Changes:

Version 16 changes player internals big time! Actually the entire MovieClips.prototype has been rewritten and supports some great high level functionality on top of the inner player methods. The changes are backward compatible with the old methods with some new functionality mixed in. These changes simplify the process of handling MovieClipDatatypes within Actionscript. Here is a sample of the new attach method:

_level0.attach({_name:’ted’, _class:’window’})

//attach a window from the library

_level0.attach({_name:’dog’, _depth:’bottom’})

//attach an empty movieClip

//delete the movieClipdatatypes

delete _level0.ted

_level0.dog = ‘No More Dog MovieClip’

In the above example, MovieClipDataTypes are now just like any other data object and can be overwritten without special handling methods, even by strings or delete. Depth management is also automatic allowing you avoid depth overwriting errors. It takes some getting used to and is specifically intended to make applications easier to author. V16 also has a new set of contextual events allowing you to use onTarget Events. These events combine standard events with the context of the cursor target. These events tend to simplify components and reduce the volume of code thus allowing for easier authoring. Plus they are easy to interactively overwrite by reference. Here is a sample:

_level0.onTargetRollOver = function(id) {trace(‘I took the focus from ‘+id)}

_level0.onTargetRollOut = function(id){trace(‘I lost focus to ‘+id)}

_level0.onTargetDragDrop = function(id){trace(‘You dropped ‘+ id +’ on me!’)}

_level0.myMC.onTargetRollOver = function(id) {trace(‘I took the focus from ‘+id)}

_level0.myMC.onTargetRollOut = function(id){trace(‘I lost focus to ‘+id)}

_level0.myMC.onTargetDragDrop = function(id){trace(‘You dropped ‘+ id +’ on me!’)}

When events are easier to detect and are in context with the target, it makes for allot less code. It takes some getting used to.

Special thanks in no particular order: Robert Penner (com.penner.math, com.penner.color), Branden Hall(string, XMLNitro), Elvis Mehmedovic(com.powersdk.ras), Erik Westra(com.powersdk.ras functions!), Alex Bradley, Timothee Groleau(cExtends), Owen Van Dijk, Jos Yule, Jim Cipriani, Ryan Eatmon (Jabber Pro!), Mark Wing, Brenda Long-Brown, Weberize Team, Nashville TMUG, Sunny Hong, Alain Moran, Ivan Dembicki(com.powersdk.xmlpath patch), Axexo Team, Pepsi Team, Warner Team, PSDK List members, and countless others for your emails, thoughts and ideas. You helped, Thanks!

We are about 1 month from the release of Version 17 of the framework paving the way for an alpha release of PowerSDK:FLOW. My current consulting gig ends on Tuesday and I will be working 110% on PowerSDK:FLOW and PowerSDK:VIEW. Hopefully both of them will fundamentally change the way you develop.

PowerSDK:FLOW >> Runtime XML Applications in the Flash Player

PowerSDK:VIEW >> A server for team software development

I guess you could say I finally have my priorities in order.

Onward through the fog!

Ted ;)

Strings as an array


One of the features of python is the ability to treat strings as an array. As this would be useful in AS so I wrote an addition to the string class to handle this functionality via __resolve.

Here is some sample usage:

//Test Cases

myString = “Hello World”

trace(myString) //Hello World

trace(myString[0]) //H

trace(myString[1]) //e

trace(myString[-1]) //d

trace(myString[-4]) //o

trace(myString['0:7']) //Hello W

trace(myString['1:8']) //ello Wo

trace(myString['2:9']) //llo Wor

trace(myString['6:']) //World

trace(myString[':5']) //Hello

**WARNING – This distorts inheritance, use with caution.

**Any patches to address this issue would be most welcome.

Download the Sample

Cheers,

Ted

FCHS – Flash CrossDomain HTTP Server


I’ve been dreading installing an HTTP Server on 15 XMLSocket servers just to serve the crossdomain.xml file to support changes in Flash 7. After getting frustrated at Macromedia, I focused on finding a solution that was simple and cost effective. Left with very few cost effective options given time & money, I rolled my own HTTP Server. ;)

http://www.powersdk.com/download/FCHS.py

The server is written in Python in 20 lines of code and runs on Windows, Unix, and OSX. The server only serves the embedded crossdomain.xml file, regardless of the url you enter. You start the server as follows:

//Path_to Python Server_File Server_Port

Python FCHS.py 80

Open the file into a text editor, edit the crossdomain file, and fire it up from the command line. It works great and will save you a world of time configuring apache.

Enjoy,

Ted ;)

What is PowerSDK FLOW?


I have fielded so many questions about FLOW and PowerSDK that it is time to show a bit more of what we have been working on.

FLOW is a runtime execution framework for XML based component applications within the Macromedia Flash Player. FLOW allows you to author component applications quickly and integrate them into existing Flash applications or vice versa. FLOW executes within the existing F6 and F7 players allowing wide deployment. FLOW is scheduled to be released next year.

FLOW consists of several parts:

1. FLOW Runtime – The core files that make FLOW work including : Component Loader, Actionscript Interpreter, and XML Rendering Engine

2. FLOW Components – A collection of FLOW runtime components and classes that can be imported as needed by an application

3. FLOW Builder – IDE for building FLOW based applications. The FLOW IDE is a FLOW application.

Here is how you integrate FLOW into an application:

1. Within a SWF, import the FLOW runtime(swf) into a high layer

2. At a movieClip, render a FLOW XML application:

_level0.myMoviClip.render(FlowXML)

3. The FLOW application is now executing.

FLOW XML is a combination of ZUL(Mozilla) and Actionscript that work together to create an application or application interfaces within a movieClipDatatype at runtime. FLOW contains an interpreter and can execute code blocks within XML without compiling to swf bytecode. FLOW uses a form based paradigm similar to Visual Basic and Delphi. A developer designs application forms and scripts forms and components into a working application. FLOW components and forms provide persistence by default, so making complex applications is as easy as putting a component on a form. Regardless of how many times you render the form, the data will persist between rendering, unless you don’t want it to. The FLOW rendering engine is extensible as you can add components into your FLOW runtime and render them into a custom application. Unlike other authoring approaches, FLOW executes on the client side and doesn’t require a server like Laszlo or Royale yet allows you to easily share runtime components across applications. All in all, FLOW is simply another way to author RIA applications that execute within the Macromedia Flash Player.

I will be showing FLOW at Macromedia MAX in November during my session on components. I hope you can make it.

Much more to come.

Cheers,

ted ;)

Packaging for runtime


One of the more difficult tasks in making a good runtime model for Flash is deciding how to package code for reuse. This is especially true considering the many dependent classes and managers needed when using MX 2004 components.

Ideally adding a runtime framework to the Flash player should be easy and require as few calls as possible. Here is how this is done in PowerSDK.

1. Load PowerSDK version 18 into _level1000

loadMovieNum (“/PSDK/18/core.swf”, 1000)

PowerSDK uses the file system or URL to allow the framework to be reused across applications. The URL above allows you to specify a framework version to use in your application and to specify where the folder is located. Once ‘core.swf’ loads, it will proceed to load other components based on the URL path to itself. So long as the framework remains in the organized structure, you don’t have to worry about a thing. In this case, the call is loading version 18 of PowerSDK to an arbitrary layer 1000 of the player. This is typically the first call in every one of my applications.

The core.swf also sorts code based on player version allowing you to support the current player version and the one prior. In this case, F6 and F7 are supported by PSDK. So if you loaded a component at a path ‘com.macromedia.mx.core.view’ it would be located at these 2 locations:

/PSDK/18/6/com/macromedia/mx/core/view.swf

/PSDK/18/7/com/macromedia/mx/core/view.swf

Although these 2 swfs have the same name, they are compiled for optimized use with a particular player version. When core.swf (f6) loads it uses the player version to load components from the correct file system. This allows you to develop to a common model, but deploy to an optimized player. This is very different to developing to the weaker player model as it allows performance to be optimized where it can be yet maintain backward compatibility to a feasible extent. Mostly it helps combat the development problems associated with legacy support.

2. What to import and how to import it

PSDKImport = new XML(”)

The new PowerSDK framework supports 2 loading properties, pre and post defined in an XML Object. PRE allows you to load components in advance of the init() execution. POST are loaded as soon as init has executed in the order within the XML object. There is also some other functionality, but I will get into that later on!

Another important consideration is dependencies. When you load a component, the component should inform the framework about its dependencies prior to instantiation. Instantiating a class without a superclass causes all sorts of problems at runtime. Ideally the framework should handle the leg work needed to make this happen without user intervention. In PowerSDK, I use callbacks to denote a dependency in a recursive manner:

// within the component ‘com.macromedia.mx.core.view’ we denote the following dependencies

// ‘com.macromedia.mx.core.UIComponent’ and ‘com.macromedia.mx.core.UIObject’

PSDK.import(‘com.macromedia.mx.core.UIComponent’)

PSDK.import(‘com.macromedia.mx.core.UIObject’)

After all of the dependent components are loaded, the _global/_level0 instances are created in reverse dependency order via the framework. Inside each component SWF the class is declared within a wrapper init() method that places the instance into _global or _level0. This organized preloading and instantiation allows the application to load as little as possible via a simple developer interface. It also makes your components smaller as they can depend on other components for services and functionality. This sort of breaks some rules for componets (encapsulation) but it is very effective.

3. Initialize the application with an INIT method

init = function(){}

Once this is complete, the player is conditioned for runtime reuse. All in all I have found the PowerSDK framework invaluable as it allows you to reuse solutions via the Player not by the Authoring IDE. Most importantly, it make reusing code across applications easy and keeps your applications small and tight.

On Components – I have a distorted view of what a component it. I view a component as “a reusable unit of deployment”. This means that anything that can be deployed into a swf is eligible. How it is organized internally is up to the developer, externally it must be able to be reused in an organized manner. Although this may rub some people the wrong way, this view has helped me surmount many problems that a purist OOP outlook would not have permitted. There are many ways to write software, none of them are wrong. Each has advantages and disadvantages in certain situations and each is just another option along the road to a completed project.

Cheers,

ted ;)

MX04 Component Direct/Indirect Events


Here is a fun test with the new component model. This shows how to handle direct events. I break events into 2 types, those that happen when something occurs directly (direct) and those that are received through an event broker(indirect). The two models are different yet both are handy in certain cases.

Here is a sample for Direct Events with the new Components

1. Add 2 button components to the stage named ‘but1′ and ‘but2′

2. Add the following actionscript to the keyframe

but1.label = “Button 1″

but1.clickHandler = function(){trace(‘Click But1′)}

but1.keyDownHandler = function(){trace(‘keydown But1′)}

but2.label = “Button 2″

but2.clickHandler = function(){trace(‘Click But2′)}

but2.keyDownHandler = function(){trace(‘keydown But2′)}

3. Compile

You should receive traces from the 2 buttons. You should also note that keyboard events are active when a component has focus, otherwise you do not receive them. Unfortunately clicking on the stage doesn’t clear focus, but that is easy to change via _level0’s inheritance by making it a component too. ;)

You can use this syntax to get direct events from the components.

{event name}Handler = function(){}

unloadHandler = function(){}

moveHandler = function(){}

resizeHandler = function(){}

You can also add direct events directly to the component:

1. Click the component

2. Actions Panel

on(click){

trace(‘clicked’)

}

These components sure look great! More options, cleaner programming syntax and better events.

Also watch out, there is a potential gotcha in subscribing to events. The events are fired as listed and need not have the ‘on’ prefix FUI events. When the docs say click, click is the event name. Here is a sample:

1. Add a button named ‘but1′

2. Timeline Actions

ml = {}

ml.click = function(){trace(‘Listener Click’)}

but1.addEventListener(‘click’, ml)

or (new)

click = function(event){trace(‘Listener’ + event)}

but1.addEventListener(‘click’, click)

You no longer need to nest events is a fixed object structure. That has to be one of my favorites.

Fun, Fun…

Cheers,

ted ;)

Money is to Time as Software is to _____________?


We all know the basis of money is time. It would be nice to be truly self-sufficient but in this modern era, that is difficult to do. I certainly have no means to create the power, water, or the coffee that I consume. The only thing I can do is focus on using my time efficiently and being fairly compensated for my time. I exchange my time for money in order to purchase time spend by countless others making the products I depend on.

So what is software? I view software as time. In most cases, software’s primary intent is to automate and process data to save people time. The more time software saves, the more valuable it is. Take a spreadsheet, can you imagine performing calculations by hand? Take Blogger (the software I am using now), I write into this little text box via keyboard and it publishes a site for me at the push of a button. Attempting to do this on my own would take time, time to write, time to spellcheck, time to format, time to archive, time to make an RDF file to syndicate to you, and time to FTP everything into place. Blogger allows me to enjoy writing daily without taking much time.

Next time you sit down to write software, focus on saving the end user time. You will find the software you write is infinitely more valuable. Your customer/employer will wonder why it is so great and you will find your time is more valuable to others. I guess if software is time, then I save people time for a living.

Cheers,

ted ;)

I Fell Into A Ring Of Fire…


“Love Is A Burning Thing, And It Makes A Fiery Ring, Bound By Wild Desire, I Fell Into A Ring Of Fire” – Johnny Cash.

I vividly remember sitting in front of my fathers Vietnam Era Sony Reel to Reel and listening to recordings of Johnny Cash. My childhood was filled with his music and I continue to enjoy his artistry even today.

Johnny Cash passed this morning in Nashville, Tennessee at age 71.