A Flash Developer Resource Site

Results 1 to 16 of 16

Thread: Overriding the width getter on a DisplayObject

  1. #1
    Multitouch Aficionado
    Join Date
    Mar 2006
    Posts
    275

    Overriding the width getter on a DisplayObject

    I frequently find myself wanting more granular control of the width/height properties.

    Consider either of the following cases:
    - The DisplayObject is clipped with DisplayObject.mask, but Flash reports unmasked width.
    - An image is displayed with a transform cage drawn over it. The width of the cage shouldn't be calculated when determining the DisplayObject's width.

    The naive way to solve this problem is to override the width getter of the DisplayObject in question. The problem is that the core implementation of DisplayObject.width is written in native code. If after overriding the width getter, I call overridenObject.width, I get what I want; however, if I call overriddenObject.parent.width, DisplayObject.width ignores my override and calculates the dimensions based on its own internal display list representation.

    Does anyone know of a technique to limit which children are considered when calculating width without having to override every parent's width getter? I've tried overriding width, getRect, getBounds, and scrollRect, but none of them seem to be referenced by DisplayObject.width's native implementation.

    Thanks.

  2. #2
    Ө_ө sleepy mod
    Join Date
    Mar 2003
    Location
    Oregon, USA
    Posts
    2,441
    However you approach it, you're still blocking the native width accessor and replacing it with your own code...if there's a logical system involved, you could make a dynamic override and apply it to an entire class of objects at once via prototype...although that might start screwing with rendering and bounding boxes in the guts of the player. What's the application?
    Please use [php] or [code] tags, and mark your threads resolved 8)

  3. #3
    Multitouch Aficionado
    Join Date
    Mar 2006
    Posts
    275
    I don't have much experience with prototypes. I thought they'd only be useful for code in the AS3 namespace, as opposed to native code. Also, I didn't know you can write getters as prototypes.

    I create fluid layouts. I'll often be in a situation where I want the visible part of A to be S distance away from that of B, and I don't want to be concerned with masks, hit areas, or any of the like. If I draw a bigger hit area on Sprite B, its visible portion should still be S distance from A.

    Ideally, there'd be a DisplayObject.contributesSize, which when set to false would mean AS3's native dimensions calculators ignore that child entirely when determining an ancestor's size.

  4. #4
    ___________________
    Join Date
    May 2004
    Posts
    3,174
    nt
    Last edited by moagrius; 12-08-2009 at 04:17 AM. Reason: didn't think my input was helpful after rereading original post

  5. #5
    Ө_ө sleepy mod
    Join Date
    Mar 2003
    Location
    Oregon, USA
    Posts
    2,441
    Hrmm - scratch that, I don't think you can overload accessors through prototype.

    You could however, add that flag to the prototype - then you'd need to do your own recursive crawl of the dom to calculate the width of everything depending on that flag...probably not too efficient but it should work if you don't have a ton of stuff and you don't need extreme performance. I'd love to see an implementation.
    Please use [php] or [code] tags, and mark your threads resolved 8)

  6. #6
    Multitouch Aficionado
    Join Date
    Mar 2006
    Posts
    275
    That doesn't get you around the problem of overriding every width getter in a parent chain.

    One technique I tried before I posted this was to make a class called MaskedSprite, where width, height, getBounds, getRect, and scrollRect were overridden to return the mask's dimensions. That's how I discovered that none of these properties are considered by the Flash Player when it calculates width.

    A similar, but more useful, technique could be to create a base class LayoutSprite that keeps track of all its children in a Vector. Calling LayoutSprite.getBounds would return a union of child.getBounds() for each child in the list. width and height would return getBounds().width and getBounds().height. If you used LayoutSprites for all the containers in your display list, you'd be able to create a fluid layout that ignores hitAreas, transform cages, mask overflow, and the like.

    I don't know how it would affect performance to calculate width by hand every time. Rectangle and its member are defined in AS (not natively), so there may be a performance hit there as well.

    It's interesting to think about though.

    BTW, this is how I tell if a function is native or AS3:
    http://reclipse.net/kirupa/playerglobal.abc.il

  7. #7
    Ө_ө sleepy mod
    Join Date
    Mar 2003
    Location
    Oregon, USA
    Posts
    2,441
    You could do it with a layout class but you'd need to manually make sure everything is extending that class in your project. It would be easier to monkey patch a getWidth and setWidth function onto DisplayObjectContainer that does the checks for you and just use that instead of the native width accessors.
    Please use [php] or [code] tags, and mark your threads resolved 8)

  8. #8
    Bearded (M|G)od MyFriendIsATaco's Avatar
    Join Date
    Dec 2002
    Location
    Awesomeville.
    Posts
    3,045
    You could override the width getter... there's no reason why you can't. I come across situations when I frequently need to.
    Code:
    override public function get width():Number { return 15; }
    You can do whatever you want inside the getter.

  9. #9
    Total Universe Mod jAQUAN's Avatar
    Join Date
    Jul 2000
    Location
    Honolulu
    Posts
    2,429
    I recently used getter overrides to great effect for a certain person in this thread
    Following this as an example. http://www.bytearray.org/?p=118
    I created a class that handled fluid layouts via a width prop and when I needed it, I could simply call super.width to get the untouched one.

  10. #10
    Multitouch Aficionado
    Join Date
    Mar 2006
    Posts
    275
    I know you can override width. I also do it all the time. The problem is that this only works if you call the getter explicitly.

    Consider an object maskedShape where width has been overridden to return the mask's width (100), but the underlying shape is 200 pixels wide:

    var container = new Sprite();
    container.addChild(maskedShape);
    trace(maskedShape.width); //100
    trace(container.width); //200

    container is a regular-old DisplayObject. Calling its width getter invokes the native width implementation, which pays no attention at all to maskedShape's overridden getter.

    I've created a feature request on bugs.adobe to that effect:
    https://bugs.adobe.com/jira/browse/FP-3420

    I appreciate all your input. If I'm thinking about this in the wrong way, please let me know. Otherwise, please vote on the above issue.

  11. #11
    Total Universe Mod jAQUAN's Avatar
    Join Date
    Jul 2000
    Location
    Honolulu
    Posts
    2,429
    I agree with the oddity. I have the same gripe about children that have an x other than zero. If you place a 50px wide square in a sprite at an x of 10, it seems width should return 60, not 50.

    Perhaps the best solution is to create a sprite subclass that implements a deluxe interface that includes new getters and setters like visibleWidth or pixelWidth.

  12. #12
    Multitouch Aficionado
    Join Date
    Mar 2006
    Posts
    275
    Quote Originally Posted by jAQUAN View Post
    Perhaps the best solution is to create a sprite subclass that implements a deluxe interface that includes new getters and setters like visibleWidth or pixelWidth.
    An equally good solution is to vote on the bug. It's easier too. =)

  13. #13
    Multitouch Aficionado
    Join Date
    Mar 2006
    Posts
    275
    I just discovered a frustrating truth about scrollRects that may be useful for masking.

    If you set a scrollRect, that alters what the width, height, getBounds, and getRect members of a DisplayObject return. So, if you mask something with a mask, maskedObject.height returns the unmasked height (not useful). If you instead set maskedObject.scrollRect to a rectangle the size of your mask, maskedObject.height will return the clipped height.

    It seems to me that you'd always want the masked height of a masked object, but not always the clipped height of a scrollRect'ed object. Apparently Adobe thinks the opposite.

  14. #14
    Total Universe Mod jAQUAN's Avatar
    Join Date
    Jul 2000
    Location
    Honolulu
    Posts
    2,429
    Thanks for the info. I've struggled to understand adobe's mentality in a lot of cases and I can only conclude that they would rather allow for any possibility by not assuming anything about your intentions. Seems like they favor the least likely situation over everyday ones but on rare occasion I'm glad they didn't hand-cuff me.

  15. #15
    Multitouch Aficionado
    Join Date
    Mar 2006
    Posts
    275
    I'm still not sure when you would not want the masked size of an object, since the dimensions getters seem to default to returning the visible portion of an object in all other cases.

    The scrollRect thing is frustrating, because the straightforward way to scroll an object is scrollPercentage x scrolledContentHeight. The best solution I could find was to double-wrap the content I wanted to scroll. The inner wrapper returns the right dimensions, and the outer wrapper is what I scroll.

    Glad I'm not the only one with these issues. =)

  16. #16
    Ө_ө sleepy mod
    Join Date
    Mar 2003
    Location
    Oregon, USA
    Posts
    2,441
    As illustratedlife pointed out, you want to key off of getBounds or getRect depending on whether you want to use actual bounds or display bounds - Adobe has given you both sets of measurements already.
    Please use [php] or [code] tags, and mark your threads resolved 8)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  




Click Here to Expand Forum to Full Width

HTML5 Development Center