I had the good fortune to spend some time with Alex last night and show him my infamous TiledCanvas, now with renewed urgency since the scroll bars don't appear on Windows under Firefox 3 or IE. We are looking into some other issues in the wrapper that could affect scrolling, but I want to get the custom component right anyway, and Alex thought it could be the culprit.
Alex, I have rewritten measure() so that it computes the tiled size, using only the getExplicitOrMeasuredWidth/Height result for each child (+ padding) to set measuredMinWidth/Height and measuredWidth/Height I have rewritten updateDisplayList so that it does not alter includeInLayout and calls setActualSize rather than setting width and height - Neither method looks at any minimums or maximums, and I'm not clear whether they should. - measure() calls super.measure(), and I'm unclear whether it should in this case (Canvas.measure is probably relatively expensive). The good news is that IF I leave in place the hierarchy below, and the funky runtime switching of minimum sizes when a pod is zoomed, it works as it did before. So at least I'm weaned off the completely wrong-headed measure/udl implementations. However, this alone didn't solve the Windows problem, and if I remove "podSurface" below and set the minimum on the TiledCanvas itself, I get double scrollbars in some cases. If I use the TiledCanvas on its own (setting both minimums and scroll policy auto), I don't get scrollbars and it's clipped. Any further tips welcome, and thanks again for the help, Alex. I can share the measure() method if that helps. I'm still puzzled how the framework uses the measure values and whether they have any bearing on scroll extent, because it seems that the measured size as I'm computing it (based on the "natural size" of the pods) could be much larger than I would ever want to actually scroll. <mx:Canvas id="scrollableArea" width="100%" height="100%" verticalScrollPolicy="auto" horizontalScrollPolicy="auto"> <mx:Canvas id="podSurface" width="100%" height="100%" verticalScrollPolicy="off" horizontalScrollPolicy="off" minWidth="950" minHeight="600" > <view:TiledCanvas3 id="tiledView" verticalScrollPolicy="off" horizontalScrollPolicy="off" styleName="dashboardTiled" width="100%" height="100%" /> </mx:Canvas> </mx:Canvas> On Sun, Jun 8, 2008 at 7:31 PM, Josh McDonald <[EMAIL PROTECTED]> wrote: > It is because of another call to measure(), but that's not getting lucky, > it's being scheduled when you change includeInLayout. > > -Josh > > On Mon, Jun 9, 2008 at 10:39 AM, Richard Rodseth <[EMAIL PROTECTED]> wrote: >> >> I'm still somewhat confused, but have hacked up a workable solution as >> follows: >> >> <mx:Canvas id="scrollableArea" width="100%" height="100%" >> verticalScrollPolicy="auto" >> horizontalScrollPolicy="auto"> >> >> <mx:Canvas id="podSurface" width="100%" height="100%" >> verticalScrollPolicy="off" horizontalScrollPolicy="off" minWidth="950" >> minHeight="600"> >> <view:TiledCanvas2 id="tiledView" width="100%" height="100%" /> >> </mx:Canvas> >> </mx:Canvas> >> >> podSurface.minWidth and minHeight get changed dynamically when a pod >> is expanded, and the scrollbars and scroll extent adjust >> appropriately. >> >> Here's the interesting thing. TiledCanvas2 still uses the inherited >> Canvas.measure(), but the updateDisplayList implementation now sets >> includeInLayout to false for the hidden pods, in addition to setting >> x,y,width,height and visible. Am I just getting lucky because of some >> call to measure() that occurs after updateDisplayList() is called? >> Also, maybe if I was calling setActualSize in UDL, my solution would >> no longer work... >> >> The thing I have a hard time understanding is that the docs talk about >> measure() as setting the "intrinsic" or "natural" size of the >> component, but in a case like this, what is that? What concept tells >> me that an appropriate implementation of measure would "estimate" the >> tiling as Alex suggests but use measured sizes of children, when the >> layout itself is determined by the component size, not vice versa. >> >> I should step through Canvas.measure and see what numbers it's coming >> up with that affect what happens all way up the hierarchy, even >> though the component's size is independent of the contents of each >> pod. My head hurts. >> >> On Sat, Jun 7, 2008 at 11:36 PM, Richard Rodseth <[EMAIL PROTECTED]> >> wrote: >> > Thanks, Alex. That gives me a lot to mull over. >> > Since the only use case of interest that doesn't work is the one where >> > you'd like to specify a minimum size for the tiled view, it's an awful >> > lot of extra work, but I'll think it over. >> > If I can crack my other long-standing challenge (the ScaleOrCenterView >> > of another thread), then I could probably get by with no scroll bars >> > at all. >> > >> > Thanks again for the solution outline. >> > >> > On Sat, Jun 7, 2008 at 11:17 PM, Alex Harui <[EMAIL PROTECTED]> wrote: >> >> Canvas's measure() probably expects all children to be visible or >> >> excluded >> >> via includeInLayout. Since I don't think that's what you want, you'll >> >> need >> >> to write your own measure method(). >> >> >> >> >> >> >> >> The measure() method should assume that all children are property >> >> addChild'd >> >> (and thus your charts shouldn't be unparented) and use the measured >> >> sizes of >> >> its children to calculate its measuredWidth/Height. It would probably >> >> just >> >> call getExplcitOrMeasuredWidth/Height on the children if >> >> selectedChild==null >> >> and estimate what the tile layout will look like, or if there is a >> >> selectedChild, just measure that one child. >> >> >> >> >> >> >> >> Based on those measurements and any other constraints on your >> >> component, its >> >> parent will determine its size and your component's updateDisplayList >> >> gets >> >> called with that size. In your override of updateDL, you would see if >> >> selectedChild==null and do the final sizing and positioning of the >> >> children >> >> and probably make all children visible, or if selectedChild is set, >> >> make all >> >> other children invisible and size and position that one child to fill >> >> the >> >> unscaledWidth/Height passed into updateDL. >> >> >> >> >> >> >> >> I would not remove and re-add children when selectedChild changes. It >> >> would >> >> likely cause more measuring and layout again. >> >> >> >> >> >> >> >> -Alex >> >> >> >> >> >> >> >> ________________________________ >> >> >> >> From: flexcoders@yahoogroups.com [mailto:[EMAIL PROTECTED] On >> >> Behalf Of Richard Rodseth >> >> Sent: Saturday, June 07, 2008 1:30 PM >> >> To: flexcoders@yahoogroups.com >> >> Subject: Re: [flexcoders] Measurement and scrolling >> >> >> >> >> >> >> >> Thanks for indulging me, everyone. I wish I could share all the code >> >> now - I certainly hope to later. I'm sorry to say I find that ESRIA >> >> example quite inscrutable as sample code, though the UI is certainly >> >> nice. >> >> >> >> So, to review where I am, I have a component that tiles its children >> >> and resizes rather well (perhaps by accident). It derives from Canvas >> >> (should possibly be UIComponent), and the updateDisplayList method >> >> sets the x,y,width,height of the children (should possibly be calling >> >> setActualSize, thought it currently doesn't assume that the children >> >> are UIComponents, even though they are). The measure() method is >> >> inherited from Canvas. >> >> >> >> When an individual pod is maximized, the contents of the display list >> >> is not changed. Rather updateDisplayList sets the visible property as >> >> well. That's something I'm trying to rectify now, so that measure() >> >> will be correct, but I'm running into some problems (eg. charting >> >> classes expecting a parent). Any suggestions regarding this aspect? >> >> I'm trying something like the following. >> >> >> >> public function set selectedChild(child:DisplayObject) : void { >> >> trace("selectedChild"); >> >> _selectedChild = child; >> >> if (child == null) { >> >> this.removeAllChildren(); >> >> for each (var child:DisplayObject in _savedTiles) { >> >> this.addChild(child); >> >> } >> >> _savedTiles = null; >> >> } else { >> >> _savedTiles = this.getChildren(); >> >> this.removeAllChildren(); >> >> this.addChild(_selectedChild); >> >> } >> >> invalidateSize(); >> >> } >> >> >> >> I thought of using visible/includinLayout, but then I'd have to >> >> introduce the child-is-UIComponent assumption (which I realize may >> >> ultimately be necessary). >> >> >> >> On Sat, Jun 7, 2008 at 9:35 AM, Daniel Gold <[EMAIL PROTECTED]> >> >> wrote: >> >>> You may want to look at the code in PodLayoutManager.as from the Flex >> >>> Dashboard example as it seems to be very similar to what you're doing >> >>> >> >>> http://examples.adobe.com/flex3/devnet/dashboard/main.html >> >>> >> >>> >> >>> On Fri, Jun 6, 2008 at 12:04 AM, Josh McDonald <[EMAIL PROTECTED]> >> >>> wrote: >> >>>> >> >>>> Measure can always be bigger than the actual width/height, that's >> >>>> what >> >>>> it's for. >> >>>> >> >>>> On Fri, Jun 6, 2008 at 11:32 AM, Richard Rodseth <[EMAIL PROTECTED]> >> >>>> wrote: >> >>>>> >> >>>>> No, I mean like zooming a window. I think the problem lies in how I >> >>>>> tell the TiledCanvas that one of its children is the zoomed one >> >>>>> (setting "visible" of all the others to false in updateDisplayList). >> >>>>> Stay tuned. >> >>>>> >> >>>>> However, setting that aside, it also seems as though I might be >> >>>>> commiting a hack if I allow the measured size of the TiledCanvas to >> >>>>> remain larger than its bounds, even though it allows the scrolling >> >>>>> to >> >>>>> work (at least in the all-tiles-shown case). >> >>>>> >> >>>>> On Thu, Jun 5, 2008 at 5:46 PM, Josh McDonald <[EMAIL PROTECTED]> >> >>>>> wrote: >> >>>>> > I'm not sure exactly what you're doing, or what you're trying to >> >>>>> > achieve >> >>>>> > yet. By "expanding a tile" do you mean you're setting the minimum >> >>>>> > to >> >>>>> > be >> >>>>> > bigger, or you're manually overriding the decisions the base >> >>>>> > Container >> >>>>> > implementation makes in updateDisplayList()? >> >>>>> > >> >>>>> > On Fri, Jun 6, 2008 at 10:41 AM, Richard Rodseth >> >>>>> > <[EMAIL PROTECTED]> >> >>>>> > wrote: >> >>>>> >> >> >>>>> >> The docs say: >> >>>>> >> >> >>>>> >> If the horizontalScrollPolicy is ScrollPolicy.AUTO, the >> >>>>> >> horizontal >> >>>>> >> scroll bar appears when all of the following are true: >> >>>>> >> >> >>>>> >> * One of the container's children extends beyond the left edge or >> >>>>> >> right edge of the container. >> >>>>> >> * The clipContent property is true. >> >>>>> >> * The width and height of the container are large enough to >> >>>>> >> reasonably accommodate a scroll bar. >> >>>>> >> >> >>>>> >> And sure enough, if I set a static minimum on tiledView, I get >> >>>>> >> the >> >>>>> >> desired effect. >> >>>>> >> >> >>>>> >> If I expand a tile and change the minimum to something else, any >> >>>>> >> idea >> >>>>> >> which invalidate method(s) I should call? >> >>>>> >> >> >>>>> >> On Thu, Jun 5, 2008 at 4:57 PM, Josh McDonald <[EMAIL PROTECTED]> >> >>>>> >> wrote: >> >>>>> >> > If you want to be able to measure your subcomponents, always >> >>>>> >> > use >> >>>>> >> > setActualSize. I learned that the hard way recently :) >> >>>>> >> > >> >>>>> >> > I've recently been doing a whole bunch of measure and >> >>>>> >> > updatedisplaylist >> >>>>> >> > voodoo for a custom container, so I'll be slightly helpful! >> >>>>> >> > >> >>>>> >> > -Josh >> >>>>> >> > >> >>>>> >> > On Fri, Jun 6, 2008 at 9:36 AM, Richard Rodseth >> >>>>> >> > <[EMAIL PROTECTED]> >> >>>>> >> > wrote: >> >>>>> >> >> >> >>>>> >> >> Clearly I haven't mastered layout and measurement. >> >>>>> >> >> >> >>>>> >> >> I've implemented a custom component which tiles its children >> >>>>> >> >> in >> >>>>> >> >> equal-sized tiles, but also has a state (not a flex state) >> >>>>> >> >> where >> >>>>> >> >> one >> >>>>> >> >> tile fills the component. >> >>>>> >> >> >> >>>>> >> >> I subclassed Canvas and set the sizes and positions of >> >>>>> >> >> children in >> >>>>> >> >> updateDisplayList. I didn't override measure(), but it works >> >>>>> >> >> very >> >>>>> >> >> nicely, resizing children smoothly as it is resized. >> >>>>> >> >> >> >>>>> >> >> Now, however, I would like to set a minimum width and height >> >>>>> >> >> for >> >>>>> >> >> the >> >>>>> >> >> tiled view, after which scroll bars appear. The minimum will >> >>>>> >> >> be >> >>>>> >> >> different if the component is in the one-tile-expanded case. >> >>>>> >> >> >> >>>>> >> >> Can I do this without further mods to my component? >> >>>>> >> >> Should my updateDisplayList be calling setActualSize rather >> >>>>> >> >> than >> >>>>> >> >> setting x,y,width, height? >> >>>>> >> >> Should I have a measure() implementation? >> >>>>> >> >> How would it differ from the inherited one? >> >>>>> >> >> In a scenario like the following, would I set the minWidth and >> >>>>> >> >> minHeight on the parent or child? >> >>>>> >> >> Or, to ask another way, do the the scrollpolicy and minimum >> >>>>> >> >> properties >> >>>>> >> >> always belong on the same component? >> >>>>> >> >> >> >>>>> >> >> <mx:Canvas id="scrollableArea" width="100%" height="100%" >> >>>>> >> >> verticalScrollPolicy="auto" >> >>>>> >> >> horizontalScrollPolicy="auto"> >> >>>>> >> >> >> >>>>> >> >> <view:TiledCanvas id="tiledView" >> >>>>> >> >> width="100%" height="100%" >> >>>>> >> >> > >> >>>>> >> >> </view:TiledCanvas> >> >>>>> >> >> </mx:Canvas> >> >>>>> >> >> >> >>>>> >> >> Thanks. >> >>>>> >> > >> >>>>> >> > >> >>>>> >> > >> >>>>> >> > -- >> >>>>> >> > "Therefore, send not to know For whom the bell tolls. It tolls >> >>>>> >> > for >> >>>>> >> > thee." >> >>>>> >> > >> >>>>> >> > :: Josh 'G-Funk' McDonald >> >>>>> >> > :: 0437 221 380 :: [EMAIL PROTECTED] >> >>>>> >> > >> >>>>> > >> >>>>> > >> >>>>> > >> >>>>> > -- >> >>>>> > "Therefore, send not to know For whom the bell tolls. It tolls for >> >>>>> > thee." >> >>>>> > >> >>>>> > :: Josh 'G-Funk' McDonald >> >>>>> > :: 0437 221 380 :: [EMAIL PROTECTED] >> >>>>> > >> >>>> >> >>>> >> >>>> >> >>>> -- >> >>>> "Therefore, send not to know For whom the bell tolls. It tolls for >> >>>> thee." >> >>>> >> >>>> :: Josh 'G-Funk' McDonald >> >>>> :: 0437 221 380 :: [EMAIL PROTECTED] >> >>> >> >>> >> >> >> >> >> > > > > > -- > "Therefore, send not to know For whom the bell tolls. It tolls for thee." > > :: Josh 'G-Funk' McDonald > :: 0437 221 380 :: [EMAIL PROTECTED] >