Creating a dynamically sized Flex list component - apache-flex

I know there are a lot of questions about dynamic sizes for Flex components, but this one is quite specific and the other answers aren't a whole lot of help. Briefly, I need a List that resizes to exactly fit its content, unless that height exceeds its (dynamically sized) parent container. My requirements are as follows:
The component extends List, or at least acts similarly.
variableRowHeight and wordWrap both equal to true.
The height of the list cannot be less than minHeight (roughly 32px for scrollbar arrows).
The height of the list cannot be greater than the height of the parent container .
Note that the parent container can be resized dynamically.
The height of the list should be updated as the size of both the contents and parent container changes.
Live updating would be preferable but not necessary.
There should be no scrollbars if the content height is less than the parent container height (sounds obvious, but I've had trouble with this too).
The trouble is that with variableRowHeight and wordWrap, it's very hard to know the size of the content at any given time. If the parent container's width is reduced, a line wrap may occur in the list which will change the height of the content. I know I can measure the height of the list content using measureHeightOfItems() + viewMetrics.top + viewMetrics.bottom, but when should I calculate that? What events should I listen for? And the thing I've had the most trouble with - when should I calculate it to set the size initially (i.e. just as the content has finished populating)?
I've been tackling this for months now on and off, but can never find a solution (though I've come close with chunks of code of varying degrees of incomprehensibility). I'm not asking for someone to create a full component for me, I'm just hoping someone has the right pointers to let me know how I should go about determining and updating the size. I'm happy to do all the prototyping for you and discuss the results :).

Custom Flex components are definitely their own beast. You have a lot of dedication to spend months working on one!
If you haven't seen it already, you should certainly take a look at the Flex Component Lifecycle. This will answer your questions about where to execute code. I believe that measure() and commitProperties() are going to be important for your component.
I also find validateNow() to be a very useful function when managing components with dynamically sized children and/or parents. I have not yet figured out when the optimal times to call this function are but it seems to be necessary when calculating sizes of Flex components. There's an informative article about it at judah's blog.
Best of luck!
Update -- I stumbled upon a seemingly great article about Flex component lifecycle at DevelopmentArc that I'm adding to my own reading list.

Related

How to properly size Qt widgets?

Main Question
What is the "right" way to give your widgets default sizes and make sure they contract, expand, or remain fixed if there is additional or not enough space to accommodate them?
How I Think Qt Works
After reading the Qt documentation it seems like the sizing algorithm goes something like this...the layout begins by asking its children for their ideal size via the QWidget::sizeHint method. If the layout has additional space or not enough space then it'll determine which widgets to resize based on each widget's sizing policy (QWidget::sizePolicy), minimum size (QWidget::minimumSize), and maximum size (QWidget::maximumSize).
Why isn't there a QWidget::setSizeHint method?
If my understanding is close to being accurate then it would seem all you'd have to do is set the sizeHint, sizePolicy, maximumSize, and minimumSize on each widget and everything would just work. So why isn't there a setSizeHint method?!?!??!! Sure, every time you use a widget that provides all of the functionality you need (QTableView, QComboBox, etc) you could extend it and override a single method but that sounds absolutely ridiculous.
One of the sizing issues I'm fighting with.
I've got a QMainWindow with a QDockWidget on the left hand side. The QDockWidget has a QTableView. I'd like to have the QDockWidget/QTableView take up a "reasonable" amount of space on start up and then the user can resize it however small or large they'd like.
Unfortunately, when the application starts up it gives the QDockWidget/QTableView so little space that it requires a horizontal scroll bar. The only way I've found to force it to give it a reasonable amount of width is to set the QDockWidget's minimum width but then it prevents the user from resizing it as small as they might like to.
Why isn't there a QWidget::setSizeHint method?
In my opinion it is much better for a widget to compute its preferred size based on its content (or rules) instead of allowing the coder to set a sizeHint probably hardcoded or at least prone to errors.
I almost never had to set a size on a widget, playing with the QSizePolicy was enough. And when I needed some specific constraints, playing with minimum/maximum sizes was enough. So that Qt layouts were always able to adapt the widget.
If you want to set up yourself some percentages on the sizes etc, you can play with the stretch parameter. You can also add spacers when you need empty spaces.
Extending a QWidget to override the QWidget::sizeHint method does not sound ridiculous to me, as you change the widget behaviour by changing its preferred size and that fits the polymorphism spirit of OOD.
How to properly size Qt widgets? is a vague question and depends on the use cases. Most of the time choosing the good layouts and size-policy lets you achieve very adaptative GUI. Qt Designer can help to do this right, even if the layout management is not always intuitive (you need to place your widgets first and then set them in layouts from the inner to the outer layout).
About your specific issue, it's hard to tell why your QDockWidget gets too small without knowing the details of the layout(s) you have around your two widgets in the window. Maybe it is a specific issue with QDockWidget : see related questions :
QDockWidget starting size
Qt 5.7 QDockWidget default size
Prevent QDockWidget autosizing behaviour

In Flex, for manually resizing datagrid, how can I keep the column widths reasonable?

Whenever you resize a datagrid by hand (not via code), the last column seems to retain most of the width. What's worse, whenever you extend it and shrink it to a large degree, the other columns can get smushed. Here's a perfect example:
The ideal solution would distribute width equally or in proportion to the length of the text. In addition, if would avoid covering text when it's not necessary. Now, setting the width to 0.5 in the example above does seem to alleviate the issue, but not prevent it entirely.
What I'd also like to know if there are any well polished, custom datagrids out there that solve this. From trying to find a solution, I suspect the only solutions available are more ad-hoc.
I know two ways to avoid this problem.
1) Use List with special item renderer, which simulates columns (say HBox separated with rules), and header, which repeats the layout of item renderer. It's not very elegant solutions, but the resize is quite predictable. Also you can easily add sorting feature (by adding buttons to header), but I'm not sure if column resize is possible to implement here.
2) Use spark s:DataGrid from SDK 4.x. It hasn't got such resize problems AFAIK.

flex: relative sizing and performance

We are building a flex project and would like it to render faster. We do have situations where we reference parent module size properties to size current module containers, as well as current module size properties for a bunch of attributes including font size and element positions and sizes.
Would it help to create temporary variables for
a) pcw=parentcontainer.width, pch= parentcontainer.height
b) ccw=currentcontainer.width, cch=currentcontainer.height
and reference to pcw,pch,ccw and cch while doing positioning. Will that help?
Also given the bulk of the positioning will be done in mxml, will setting these interim variables in initialization function, allow them to be used in mxml such that they will resize as browser size is changed. Thanks for pointers
I'm not sure if you're using the term "Module" a a generic term to refer to a component, or if you are explicitly referring to classes of the Module class.
It breaks encapsulation if a container is aware of it's parents. In Flex, a parent is always responsible for sizing it's children; and a child should never size itself.
You had code like this to access the parent's height and width:
pcw=parentcontainer.width
parentcontainer.height
I can't imagine how saving the parent's height and width values would speed anything up.
I also find it hard to envision a situation where knowing the parent container's width and height is helpful. Often a container has more than one children. It is important to know how much size a component has for laying out it's own children, not how much space the parent has.
The appropriate way to size and position a component's children is to override updateDisplayList(). updateDisplayList() has two parameters: unscaledWidth and unscaledHeight; that is, in essence, the height and width of the component. You should size and position the component's children based on those two values.
Of course, doing so often relies on ActionScript; not MXML.
Your primary question seemed to want to improve performance. There are many factors involved in the performance of an app. Using ActionScript for layout instead of MXML could be one factor that may help improve performance. Minimize your use on binding is another thing that can sometimes help performance.
Have you used the Flex Profiler? Have you stepped through code? Does doing these things help you determine what exactly the performance issue is?
Unless your application changes it's shape a lot, there shouldn't be any problems laying out with Flex if you use proper skinning/component/layout standards.
Most of the problem isn't from Flex, but the code most people add onto their own application that renders the whole system slow. Make sure you brush up on Flash performance improvements (like data structures, limiting binding, proper architecture, object lifecycle, etc).

Flex: six seconds between initialize and creationComplete

I'm working with a large flex applications and I have noticed that one of our largest components (with lots of child canvases) takes about 6 seconds between the initialize and creationComplete events. I've been doing some reading and have found that having lots of nested canvases can cause slowdowns, but i'm not sure if this is where the slowdowns would be? Anyone have any suggestions on speeding this up, or even diagnosing exactly where the slowdowns are coming from?
It's been my experience that nested containers with dynamic sizing are the most common cause of these types of lags. Some things to try:
Set explicit sizes/positions for your containers/components whenever possible. This reduces the incredible amount of measuring that goes on within the framework during the creation process.
Reduce the number of nested containers. Sounds obvious, but it's amazing how much you can cut away when you start looking critically at how your UI is set up. Specifically, are there HBox and VBox containers you can get rid of by simply setting explicit positions/sizes for the child components? Do you really need to use a Form container?
Switch your containers to the much lighter weight Spark Groups instead of using the heavier weight Canvas where possible.
Hope that helps. If not, post some code so we can dig in to your particular issue.
The biggest thing to consider is to use VBox's and/or HBox's in place of some dynamically generated x's and y's. VBox and HBox are much more efficient. Look into it!
Adding many display objects to the display list all at once can take a long time, especially if we're talking about Flex containers that have layout and scrolling logic in the mix. Since you say you're using many Canvas containers, that could certainly be the issue you're running into.
I know that a lot of developers abuse the creationPolicy property. Normally, it is set to "auto" which allows Flex to defer instantiation of a container's children until a very short time "later". Often, before the next frame, so you don't even see the difference. Do you happen to set creationPolicy to "all" anywhere in that hierarchy? This could be forcing the Canvases and their children to be created immediately.

Question about applying effects on containers

I need to apply an effect on containers that on mouse over the container it get resized or expands while pushing other containers surrounding it and causing them to get resized too. Something similar to this
Can someone provide me with an example or a hint on how to implement something like this?
Thanks
Looks like totally custom component with manually resized containers (for each container there is a list of affected ones). If you want to be sure, try to decompile it :)
More thoughts: every containers grows vertically of horizontally; so it splits all other into two groups, one of them gets free space and starts growing too... Then it all goes back in same order. I think for each container there is list of connected containers, who can grow if that container is grown in same direction. In any case, I don't think it's automatic behavior.

Resources