Observing and requesting better support for panning (horizontal as well as vertical scrolling) in Flash player across all OS platforms and runtimes via ubiquitous input devices.
UPDATE 10-Dec-2009: I’m pretty convinced now that this is an editor bug, not a Mac OS X bug. Essentially the editors are using default OS behaviour which I think is tailored for natural language editing rather than programme-code editing. Original post follows…
I’m currently finding in some applications that “word1.word2.word3” is being treated as a single word as far as the Option-Left Arrow and Option-Right Arrow is concerned on my Mac. This keyboard shortcut should hop word by word. But currently hops from one end to the other. Not an issue for most users, but pretty serious for a programmer working with dot-notation syntax.
I first experienced this working with ActionScript in Adobe’s Flash Builder Beta 2 and logged a bug report, but further investigation reveals that some unrelated applications show the same behaviour. I have now logged a bug with Apple, but in the meantime I would be interested to know if others are experiencing the same? Or if you are running 10.6.1 and not seeing this issue? Please add a comment – I’m still trying to work out if it is something installed on my system. I don’t think it is basic user preferences as I am seeing the same in another user-account on this system.
Editors incorrectly treating “word1.word2.word3” as a single word re opt-left and opt-right:
- FlexBuilder 3 MXML and AS editors
- FlashBuilder 4 Beta2 MXML and AS editors
- Apple Mail
- Apple OS TextFields including:
- Finder window find-file
- Safari: form-textfields & google search field
Editors showing correct opt-left opt-right behaviour:
- Adobe Flash CS4 IDE ActionScript Editor
- Adobe DreamWeaver CS4 editor
- Apple XCode editor
- Apple Finder – filename clicked and editable when renaming
- Firefox form-textfields and goodle search field
The problem: In Flex, how to overlay the video with something (e.g. a logo or caption) and keep the overlay relative to a corner of the actual video rectangle. Sounds like it should be a simple matter of creating a container and layering in the VideoDisplay instance and the over lay instance ? But…
In each of the following samples:
- We have an <mx:Panel> which has been extended to be reposition-able (drag the title bar) and resizable (drag the lower-right corner).
- The panel contains an <mx:VideoDisplay> with 100% width and height
- The panel also contains an overlay graphic – in this case using <mx:Image>
- To view the samples you need to have Flash Player 10.0.32. or higher installed. You can get the latest Flash Player from here: http://get.adobe.com/flashplayer/
- The source-code for these samples can be downloaded
- View source with a right-click on each of the samples
Video Display overlay Sample 1
In our first sample we simply place our overlay image using attributes ‘top’ and ‘right’ to keep the overlay’s top-right corner to 10px in from the VideoDisplay top-right corner.
It basically looks fine until you hit the play button and start resizing the panel.
As you can see the actual video within the VideoDisplay is constrained by its rectangle and depending on the differing aspect ratios, there will either be black space at the sides or the top, and our overlay is faithfully anchored to top right corner of the VideoDisplay and looks odd unless the aspect ratios are equal.
So how to solve this?
Looking at the documentation for VideoDisplay, there are many width and height properties to play with, however none of these relate to the current width and height or position of the contained video rectangle. You might think while looking at the documentation that the videoWidth and videoHeight properties might give the values we are after, but not so. They only return the ‘original’ width and height of the loaded video.
Fortunately the OpenSource nature of the Flex SDK and the magic of, holding the command key on a Mac (control key on a PC) with the cursor over the <mx:VideoDisplay> opening tag, then clicking it as it underlines, (using in Flash Builder or Flex Builder) will open the source for the VideoDisplay component within a new editor. Browsing through the code you will see at line 198:
mx_internal var videoPlayer:VideoPlayer = null;
It is this videoPlayer instance who’s properties we need to monitor to calculate our overlay’s position. The instance is not generally exposed through the VideoDisplay component’s api. Nor is it documented. However since it has been placed in the mx_internal name space, we can actually access it with namespace notation…
Where we replace ‘attribute’ with the property name we are after, so the following would be of use to us…
Video Display overlay Sample 2
In this second sample, we create a positionOverlay method and call it from the resize event of the VideoDisplay component. Within positionOverlay we use the name space notation to get the videoPlayer properties and use some basic maths to reposition our overlay based on the top-right corner of the videoPlayer instance rather than the videoDisplay instance.
Additionally we call positionOverlay from our applicationComplete handler to set the initial position.
This basically seems ok, but play with it for a while and it is clear that something is wrong…
- Resizing slowly, seems ok
- Resizing quickly, and there seems to be some lag in the position of the overlay
- Release the resize handle while resizing quickly and the overlay can be left behind in completely the wrong place
Having traced the videoPlayer instance properties from within the positionOverlay handler, it is apparent that while the videoDisplay properties are correct, the videoPlayer properties are as they were previously. i.e. as they were rather than as they shall be.
Video Display overlay Sample 3 – This one works properly!
This is where Player version 10 comes in. It added Event.EXIT_FRAME. (If your project targets a player older than 10, you will not see this event in your code assist.) If we use the exit frame event to defer the call to overlayPosition, we can then get measured values from videoPlayer and correctly position the overlay.
To do this I have created a new method positionOverlayOnExitFrame who’s job is to add an EXIT_FRAME listener who’s handler will be overlayPosition. The first job of which is to remove the listener, so that it only gets called once. By using a listener we need to change the interface of overlayPosition to accept an Event argument. But we are not interested in the event information and we still wish to call positionOverlay directly, so we have allowed the argument to have a null default.
Playing with the resize handle now, no-matter how quickly it is moved, shows no lag, and always drops in the correct place.
Finally, just to re-iterate, source code zip for these examples is here.
Note: These samples were built against Flex SDK version 3.4.
Note: I haven’t found any official documentation relating to when Event.EXIT_FRAME arrived in the player runtime. The Flash CS4 documentation for Event.EXIT_FRAME indicates player 9. However unless you target player 10 in Flex/Flash Builder, you will get compile errors. If anyone has accurate references, please post to the comments – thanks.
Note: When you look at the source view, it appears ragged. This is because in creating the HTML, Flash builder simply converts tab characters to four space characters. Clearly not every tab in my code actually represents 4 characters and therefore what should look like neat columns becomes ragged. I have filed a bug/enhancement request. If you too would like this fixed, feel free to add your vote to FB-23060.
Ok so CMD-SPACE is the default short cut to launch Spotlight. But I wanted that combo for ‘content assist’ with Flex/Flash Builder. Until installing Snow Leopard, that is what I had for a few years, and Spotlight relegated to CTRL-SPACE. However since SnowLeopard, the CMD-SPACE combo is not transmitted to Flash Builder. I assume this is down to Snow Leopard somehow reserving the combination. So begrudgingly I have returned to defaults…
Spotlight : CMD-SPACE
Flash Builder content assist : CTRL-SPACE
Quickly creating re-usable components based on others, augmented with additional ActionScript behaviour using MXML is as simple as can be. However, to create a component from scratch using ActionScript requires a lot of detailed knowledge of how the Flex framework works and the component life-cycle in particular.
The Flex documentation attempts to describe the lifecycle, but can leave the developer with lots of unanswered questions. When I got more involved in developing components I found chapter 19 of Programming Flex 3 good for filling in the gaps.
This week a new and free paper has been published by DevelopmentArc that also explores the component life-cycle and the application life-cycle. A very well worth while read….
Feel free to post links to other compent lifecycle resrouces in the comments.
My SimpleOscilloscope component described in an earlier post has now been updated to include a few filters controllable through setting styles. Of course like any other Flex component, it can have additional filtering applied in the normal way. I just felt like including these : alphaDecay, redMultiplier, greenMultiplier, blueMultiplier, blurX, blurY, scrollX, scrollY.
The documentation is correct, so i have no excuse, but I didn’t initially read much beyond the signature of the constructor…
public function BitmapData(width:int, height:int, transparent:Boolean = true, fillColor:uint = 0xFFFFFFFF)
I needed a transparent bitmap. Reading the default “transparent:Boolean = true”, I assumed by simply supplying width and height, a transparent bitmap is what I would get. Not so! I got a white rectangle. The reason being, that the default fill colour is 100% white. (The first pair of FFs representing the alpha in ARGB).
At first it would seem slightly unintuitive for the second default to conflict with the first, until one realises that the ‘transparent’ flag is there to indicate whether the object will support transparency or not. Not to state that it should be initially created transparent. Supporting transparency increases data size from 24 bits per pixel to 32 bits per pixel.
So what i should have done :
bmd = new BitmapData( width, height, true, 0 );
In the majority of my projects to-date, I am the sole developer on the project team. I was feeling the need to get into writing Flex components to a level that they could be distributed. Essentially making sure I use meta tags correctly and adding appropriate asdoc comments allowing other Flex developers to easily include the component as they would any other from the Flex SDK.
So, ccglib is an MIT license OpenSource project hosted on google code through which i plan to release a number of components. The first component released is SimpleOscilloscope, which plots the currently playing sound-wave. Designed to be easily sized, coloured and positioned through application of styles.
- the ccglib project on google code (get the source, or download the swc library)
- the test-bed demonstrating SimpleOscilloscope (view source enabled)
- Case-study added to my corporate site
- gotoandlearn : great tutorials on how to get started creating your own sound-wave visualisations with ActionScript
Finally got around to adding a case-study to my corporate site including a screen-cast of some of the features of my longest running project, a Flex/AIR application for communicating football moves and plays. Essentially a digital, animated version of a football tactic board.
More details and the screen-cast are on the creative-cognition case-study page.
Blowing my own trumpet for a moment… last week I sat and passed as Adobe® Certified Expert in Flex with AIR. Which I hope will help make my case with prospective clients.