Skip to main content
Participant
January 7, 2011
Question

Group not resizing correctly when contents are moved programmatically

  • January 7, 2011
  • 1 reply
  • 1453 views

Hi there,

My apologies in advance if this is a known issue. I searched the forums but I was unable to find a discussion about this topic. The issue we are running into is when we programmatically move the contents of a Group which is in turn enclosed within a Scroller beyond the Scroller's limits the position of the Group within the stage is incorrectly calculated. This will cause mouseEvents in the area beyond the Group's limits to be "ignored" among other problems.

I have created an application to illustrate the problem, we are in 4.1:

<?xml version="1.0" encoding="utf-8"?>
<s:Application
    minWidth="955" minHeight="600"
    xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:s="library://ns.adobe.com/flex/spark"
    xmlns:mx="library://ns.adobe.com/flex/mx">

    <fx:Declarations>
        <!-- Place non-visual elements (e.g., services, value objects) here -->
    </fx:Declarations>

    <fx:Script>
        <![CDATA[
            import mx.controls.Alert;

            private function onGroupClick(event:MouseEvent):void
            {
                Alert.show("It works");
            }

            private function onButtonClick(event:MouseEvent):void
            {
                rect.x += 500;
                rect.y += 500;
            }
        ]]>
    </fx:Script>

    <s:Scroller
        width="100%" height="100%">
        <s:Group id="myGroup"
            width="100%" height="100%"
            click="onGroupClick(event)">
            <s:Rect id="rect"
                x="0" y="0" width="10" height="10"/>
        </s:Group>
    </s:Scroller>
    <s:Button
        label="Move Rectangle"
        click="onButtonClick(event)"/>
</s:Application>

Steps to reproduce:

  1. Click anywhere in the screen - notice that an alert that reads "It works" shows up.
  2. Click on the "Move Rectangle" button enough times for the coordinates of the Rectangle to exceed the limits of the Scroller, hence producing scroll bars.
  3. Scroll all the way to the right and to the bottom.
  4. Click right next to the right bottom corner - notice that no alert is displayed. The reason is the Group has not resized correctly hence we are actually clicking outside the Group. Resizing your browser window for example will cause the Group to resize and events will again "work". FlexSpy will make things pretty apparent as well.

Any pointers regarding where this bug lives in the source code or suggestions on how to fix this would be greatly appreciated, this issue is causing us a lot of pain.

Thanks in advance!!

~ TheMadPenguin

This topic has been closed for replies.

1 reply

Participant
January 14, 2011

Thanks for logging this in the bugbase: https://bugs.adobe.com/jira/browse/SDK-29112. The latest comments there say:

Reproduced in 4.0.0, 4.1.0
Confirmed fixed in 4.5.0.19764

A workaround for the 4.0.0 and 4.1.0 release would be to put the click handler on the Scroller instead of the viewport.

Note: This bug seems to be fixed, but the fact that the width/height of  the Group doesn't change is still consistent (and correct).  Group has a  concept of size and content size, scrolling is enabled when the content  size is larger than the size (with Group.clipAndEnableScrolling set to  true which Scroller sets automatically).

See this spec for more details: http://opensource.adobe.com/wiki/display/flexsdk/Spark+Viewport
Hans has a good article here: http://hansmuller-flex.blogspot.com/

Here's a simple example that demonstrates width does not change:

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark"> 
     <s:Scroller width="100" height="100"> 
         <s:Group id="viewport"> 
             <s:Rect width="100%" height="100%">
                 <s:fill><s:SolidColor color="red" /></s:fill>
             </s:Rect>
             
             <s:Button id="btn" label="out of view" y="150" click="btn.y += 50" />
         </s:Group> 
     </s:Scroller>
</s:Application> 

You might expect that this example should have a red background behind  the Button, but it does not.  That is because width/height of 100% on  the Rect is 100% of the width/height of the viewport, not the  contentWidth/contentHeight.

One way of getting the behavior where the Rect expands across the whole content size would be to bind to contentHeight:

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark"> 
     <s:Scroller width="100" height="100"> 
         <s:Group id="viewport"> 
             <s:Rect width="100%" height="{viewport.contentHeight}">
                 <s:fill><s:SolidColor color="red" /></s:fill>
             </s:Rect>
             
             <s:Button id="btn" label="out of view" y="150" click="btn.y += 50" />
         </s:Group> 
     </s:Scroller>
</s:Application> 

Note: You shouldn't specify or change the size of the viewport Group  inside of a Scroller.  The Scroller component manages the size of the  Group in a specific way and if the Group has a size that conflicts with  that then you can get into a bad situation that might cause infinite  loops.  Notice in my example the viewport Group has no size set on it.

Thanks to SDK QE for the info!

-Heidi