Archive for the ‘Flex Components’ Category.

Flex4.6 mobile maxChars bug/problem and workaround

Bug-note to self, and workaround while waiting for the bug-base to migrate from Adobe to Apache.

I’m using in a Flex 4.6 mobile project and found that setting the maxChars property to 512 caused exeption:

Main Thread (Suspended: ArgumentError: Error #2006: The supplied index is out of bounds.)
flash.text::StageText/set viewPort [no source]
spark.components.supportClasses::StyleableStageText/updateViewPort
spark.components.supportClasses::StyleableStageText/commitProperties
mx.core::UIComponent/validateProperties
mx.managers::LayoutManager/validateProperties
mx.managers::LayoutManager/doPhasedInstantiation
mx.managers::LayoutManager/doPhasedInstantiationCallback

However setting maxChars to something much smaller (e.g. 10) was fine. From experimentation, seems that the biggest number to which maxChars could be set without causing the problem was 481. I have no idea what that number relates to. Anyway the database field my TextInput corresponds to is 512 chars max so that’s the number I need.

The workaround:

Setting maxWidth on the TextInput seems to solve the problem. But rather than insert a constant I want the TextInput to flex to the width of it’s container, so the following seems to avoid the problem:

 

<s:TextInput
id        ="textInputId"
maxWidth  ="{skinableContainerId.width}"
maxChars  ="512" />

 

The future of Flex :

Flex 4 Spark VideoDisplay (measure, overlay, skin)

In a previous article I described some of the steps required in Flex 3 in order to keep an overlay position in sync with a VideoDisplay component. With the release of Flex 4, VideoDisplay is one of the components to be updated. Via VideoPlayer, it gets a Spark makeover. Internally its core, or ‘view’, has been reimplemented using Open Source Media Framework. For anyone wishing to keep an overlay in position over the view, however, the same key issue remains:

None of the various width or height properties of the VideoDisplay component describe the width or height of the contained view.

So, to get the properties of the view we need to delve deeper into VideoDisplay and use the mx_internal namespace. Even then, the ResizeEvent.RESIZE event is broadcast by VideoDisplay before it’s view dimensions (column B) have been updated to the new site.

In that previous article I observed that if, after each resize, I added an Event.EXIT_FRAME listener, I could guarantee that the VideoDisplay’s view had been sized by the time it was called. I observed that the same is true in Flex 4. However EXIT_FRAME didn’t feel like the right place to be doing this. So with a closer look at the component life cycle we can see that handling the FlexEvent.UPDATE_COMPLETE event is more appropriate. Column C shows the view’s width/height after UPDATE_COMPLETE has been broadcast. It colours red when a value  disagrees with column B (RESIZE). And so, it is column C that contains the values we want to use while managing our overlay.



Sample 1 : Comparing width/height after resize, then updateComplete

Using this information and Flex 4’s new component and skinning architecture, we can build quick and simple to use video overlay component rather than messing about with external listeners and calculating positions as we did in the previous Flex 3 examples.

Reviewing what Flex 4 includes ‘out of the box’…

  • VideoDisplay : a non-skinable component that wraps an osmf ‘view’. It translates much of the osmf api and events to what we are accustomed to with Flex 3.
  • VideoPlayer : A skinable component provides hooks for skin parts. A required part is an instance of VideoDisplay. The others are the buttons and controls we’d normally expect when giving the user control of the video.

The VideoPlayer and it’s skin are overkill for this example, so we’ll create something far simpler…

  • VideoDisplayOverlayContainer : A container component who’s children will overlay a VideoDisplay
  • VideoDisplayOverlayContainerSkin : A simple skin, providing the required videoDisplay skin part.

This way, overlaying the video is as simple as giving the container some child components and a layout (defaults to basic layout). In the example that follows we overlay a label instance to each of the four corners and the centre of the view…

<components:VideoDisplayOverlayContainer
    id     ="videoDisplayContainer"
    source ="VideoSampleForFlex.mp4"
    width  ="100%"
    height ="100%" 	>
    <s:Label text="A" top="2" left="2" backgroundColor="0xffffff" backgroundAlpha="0.4" />
    <s:Label text="B" top="2" right="2" backgroundColor="0xffffff" backgroundAlpha="0.4"  />
    <s:Label text="C" bottom="2" left="2" backgroundColor="0xffffff" backgroundAlpha="0.4"  />
    <s:Label text="D" bottom="2" right="2" backgroundColor="0xffffff" backgroundAlpha="0.4"  />
    <s:Label text="O" verticalCenter="0" horizontalCenter="0" backgroundColor="0xffffff" backgroundAlpha="0.4"  />
</components:VideoDisplayOverlayContainer>



Sample 2 : Overlay container component

View source

overlaying VideoDisplay with constrained fluid layout

UPDATE 28 April 2010 : This subject is revisited in relation to Flex 4 spark components, here.

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:

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.

code-snippet

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…

videoDisplay.mx_internal::videoPlayer.attribute

Where we replace ‘attribute’ with the property name we are after, so the following would be of use to us…

videoDisplay.mx_internal::videoPlayer.x
videoDisplay.mx_internal::videoPlayer.y
videoDisplay.mx_internal::videoPlayer.width
videoDisplay.mx_internal::videoPlayer.height

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.

code-snippet

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.

code-snippet

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.

finding information on Flex 3 component lifecycle

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….

Understanding the Adobe Flex® 3 Component and Framework Lifecycle

Feel free to post links to other compent lifecycle resrouces in the comments.

SimpleOscilloscope : filter update

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.

As ever, the project is on google code, and the test bed is here.

SimpleOscilloscope snapshot - with filters

SimpleOscilloscope : my first opensource Flex component

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.

SimpleOscilloscope snapshot

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.