Strange multiselect in Flex lists

With old halo lists mx:List you can allow the user to select multiple list items. Set allowMultipleSelection = true and you can add single items to the selected group via Ctrl + Click. Via Shift + Click you can select a set of items. Click on one item to select the first and then Shift + Click on another one to select the whole range of items between the first and last one (each included).

Nothing unexpected so far.

But if you do another Shift + Click to change the selected range, the Flex list reacts strangely. For example, say you’ve clicked on item 3 and then Shift + clicked on item 5, you select items 3 to 5. But what happens when you Shift + click on item 7 afterwards? Windows Explorer and MacOS X Finder will select items 3 to 7. If you then Shift + click on 1, they select 1 to 3. So, the general rule for those standard item lists is that you set an anchor with the first click and each following Shift + click selects all items between this anchor and the last clicked item.

But not so in the Flex list. mx:List resets the anchor with every Shift + click to the last clicked item. The following table highlights the described differences between Explorer/Finder and the Flex list:

Action Explorer Finder mx:List
click 3 3 3 3
shift+click 5 3-5 3-5 3-5
shift+click 7 3-7 3-7 5-7
shift+click 1 1-3 1-3 1-7

I think this is very confusing for the user, because there is no obvious reason for the flex lists to behave in a different way than the corresponding native lists of the operating system. So I wrote the following patch to fix this:

import mx.collections.CursorBookmark;
import mx.controls.List;
import mx.controls.listClasses.IListItemRenderer;

public class OSLikeList extends List {

    private var firstShiftClick:Boolean = true;
    private var oldAnchorBookmark:CursorBookmark;
    private var oldAnchorIndex:int;

    public function OSLikeList() {
        super();
    }

    override protected function selectItem(item:IListItemRenderer, shiftKey:Boolean, ctrlKey:Boolean, transition:Boolean = true):Boolean {
        if (shiftKey && allowMultipleSelection) {
            if (firstShiftClick) {
                oldAnchorBookmark = anchorBookmark;
                oldAnchorIndex = anchorIndex;
                firstShiftClick = false;
            } else {
                anchorIndex = oldAnchorIndex;
                anchorBookmark = oldAnchorBookmark;
            }
        } else {
            firstShiftClick = true;
        }
        return super.selectItem(item,  shiftKey, ctrlKey, transition);
    }

}

Flex application not redrawing screen

From time to time we observe issues with the Pepper player, the built-in Flash player of the Chrome browser. Since January we fight against the problem that our Flex application is not properly redrawing the screen after user interaction.

Fortunately, we stumbled across this issue in the chromium bug database. According to the comments there we have to force the refresh of the application. Of course, we should do this for the Pepper player only, but this is not a great deal. The Adobe online help states how to detect a Pepper player.

Solution

First we check if the user has a Pepper player. In this case we create a timer which calls every 500 ms invalidateDisplayList() on the main Application object.

private static var _refreshTimer:Timer;

public static function checkPepperPlayer(app:Application):void {
    if (Capabilities.manufacturer === "Google Pepper" && !_refreshTimer) {
        _refreshTimer = new Timer(500);
        _refreshTimer.addEventListener(TimerEvent.TIMER, function(event:TimerEvent):void {
            app.invalidateDisplayList()
        });
        _refreshTimer.start();
    }
}

Flash Container Height in IE10

Recently we had a problem with our flash client container within Internet Explorer 10. Within the CSS the height and width of the container is set to 100% to consume all available space. Firefox, Chrome, Opera and IE (pre version 10) have no problem to size the flash container correctly. However, IE 10 shows the flash container about 30% of the height while consuming 100% of the width. The div container has 100% in height, but the included embed object has not.

Our html source looks like:

<div style="height: 100%; width: 100%;">
  < embed id="RewooClient" width="100%" height="100%"
    type="application/x-shockwave-flash" name="Rewoo" src="Rewoo.swf"
    allowfullscreeninteractive="true" allowscriptaccess="sameDomain" >
    <!-- ... -->
  </embed>
</div>

Internet searches did not help. It seems that nobody else have this problem. The pragmatic solution was to use jQuery to set the height manually on page load and on page resizes:

(function($) {
$(document).ready(function() {
  if ($.browser.msie && $.browser.version >= 10) {
    $('#RewooClient').attr('height', $(window).height());
    $(window).resize(function() {
      $('#RewooClient').attr('height', $(window).height());
    });
  }
})(jQuery);

[update 2013-05-13] Starting with jQuery 1.9 the $.browser feature was removed and you need to add the jQuery Migration plugin to get the code working again (Thanks to Ed Graham)[/update]

Maybe this might help you… And if you know a better solution, please drop a line.

Flash ReferenceError #1069: topMostIndex not found

Today, I struggled loading our flex application. I always got the following error

ReferenceError: Error #1069: Property http://www.adobe.com/2006/flex/mx/internal::topMostIndex not found on _Main_mx_managers_SystemManager and there is no default value.

It take me some time to find the solution: This error is caused by the new deployed version 4.57 of FlashFirebug from November 17, 2012. The newest version 4.58 fix this problem but it is not reviewed and therefore not yet deployed via auto-update. You can get this version from Mozilla and you can install it manually by moving your mouse over the version description and clicking “Add to Firefox” button.

Run FlexUnit with Flex4 and Halo theme

Recently we got rid of the Flex3 compatibility mode for Flex4 which was quite tough. We had to add some namespaces to our CSS files and pinned explicitly the halo.swc as theme to migrate step by step to the spark theme. We added

<compiler>
  <!-- ... -->
  <theme>
    <filename>${flexlib}/themes/Halo/halo.swc</filename>
  </theme>
</compiler>

to our custom flex-config.xml to overwrite the theme which is used by our ANT build.xml. So far so good.

As well, we call flexunit through ANT to test our front end application which should also use explicit the halo theme. Unfortunately, flexunit does not support (yet) any flag or configuration to use and overwrite the flex-config.xml from the Flex SDK. At the end of the day with some headache we modified the global Flex SDK config file to pin the halo theme as default theme.

If someone knows a better way to do so, please leave a message.

Update (2010-10-26): The flex configuration supports the global variable flexlib which points to its flex home directory. The halo.swc could now be referred with ${flexlib}/themes/Halo/halo.swc instead of the absolute file path.

Further, an option for flexunit is on the way to set a custom flex configuration file. See here for details.