flex tree custom item renderer children creation - apache-flex

I have created a custom item renderer for the tree, i have added some children in create children function, my problem is that sometimes i need to show these children and sometimes i don't, depending on clicking on a button which also i have added at create children, the problem is that i had to create the item even if i don't want it to be visible, and removed it by making visible false, and this costs a lot of memory, i have tried to create it at buttons click listener but when scrolling the child disappears, and it may appear again if i keep scrolling up and down..
i am trying to add the child just when i need it to be visible, is this possible or i have to create it on child creation method?

Typically you do something like this with states. This way the components within the container (in this case your item renderer) are only created when the container enters the given state. The nice thing about taking this approach is that you can remain oblivious to when components need to be created/removed and let the states model handle that for you. Hope that helps.

Related

Check if QML Item is being drawn

I have a set of QML items distributed all over my UI. They display data from a remote device and their content needs to be updated regularly. The Items are spread on several tabs and hidden in nested ListView instances, so most of them won't be visible to the user all the time.
In order to keep the bandwidth low I want to update only those items that are currently visible to the user.
I am looking for the right hook to get the information which of these Items is currently displayed from within the Item, without relying on information from the parents. If they were all placed in ListView delegates I could use the delegate's Components onCompleted and onDestroyed signals. Since this is not the case I am stuck at finding out how to get this information.
Am I missing something here? Is there an onPaintFinished signal or something similar? My workaround would be to add that logic to the parent containers, but that would be tedious, since there are several kinds of container that can contains these display Items.
Instances that are on delegates of a ListView will not exist until they would be in the visible range or the cache range around the visual area of the list view. If the delegate moves outside of that range, it is destroyed. So, no need to worry about instances hidden there.
Furthermore, items are currently not visible are also not drawn. They are not entered into the scene graph, and hence, not rendered. So, instances of your items appearing on tabs that are currently not current will also not be drawn. However, these items do still exist of course.
Figuring out if an item is effectively visible or not is quite a hard problem though. QML delegates part of that to OpenGL (clipping for instance). There is not feedback on the result of that. You could in theory lift that information out of the renderer, but that would require customizing that and that is very hard. You could take a look at the heuristics that GammaRay uses to warn about items not being visible. Perhaps you can take some inspiration from that.

How to completely initialise a component but not add it to the display? Flex

I need to completely initialize a custom component in my Flex app (i.e. I should be able to access it from action script and get its properties and its children etc), But I do not want to add it to the display or make it visible.
I have tried to add it to my visible component, but keep it visible, but often many of its properties are set only when it is drawn, so i don't get what i need.
Is there a way to add a custom component to some sort of 'Virtual' display, that is not visible to the user?
You could add the component to an invisible Sprite - that way the component itself could both be on the stage and have its own visible property set to true.
Did you try using initialize()? After a view is added to the display list, the initialization stage begins. Calling initialize() before addChild() should let you initialize the view without needing to first add it to the stage.
For more info visit:
http://flexscript.wordpress.com/2008/10/24/flex-component-lifecycle-and-flex-component-framework/
http://blog.deadinkvinyl.com/2008/10/05/flex-3-addchild-and-initialize/
Not sure if possible without adding it to the display list, although I'd wish it were to some extent.
I once had to make custom drag proxy, which didn't work with the real component, because of some weird skinning issues. So instead I had PopupMananger add a box as a popup, added my component to the box, called validateNow on the component, drew it in a bitmap data, removed the popup, and used the bitmap data as the proxy.
So what you were trying was missing a call to validateNow most likely.

How to update a QLayout and get the new dimensions before returning?

This is driving me nuts. I have a custom menu class that, when set visible, shows a list of items located in a particular folder. When a hardware button is pressed, my application gets the latest list of items, populates the menu with them, and returns.
The menu displaying these items uses a QListWidget filled with custom widgets. Each of the widgets contains one or more QLabels in a horizontal layout, and is created at the time the menu is shown. In order to adjust the text displayed based on the menu width available, I need to get the size of the QLabel AFTER it has been resized according to the layout, but before the menu becomes visible to the user. The problem is, my layout does not get updated until all of the functions constructing my list return.
I have tried QApplication::ProcessEvents() and the layout update functions, but none of them have updated the values of my QLabels before returning. I can set a QTimer when the button is initially pressed, and have it show the menu, update the items, and stop itself, but that seems like a terrible solution.
Any help would really be appreciated! I've spent most of a day on this.
Marlon
I had this exact problem and could not find an answer anywhere on the Internet. Calling Layout.update(), Layout.activate(), or widget.adjustSize() (all suggested in various places) all did not work.
I had a widget with a vertical layout that I wanted to add a QLabel to and then immediately use the size of the QLabel.
The only thing that worked reliably was
layout->addWidget(myLabel);
myLabel->show();
size = myLabel->size();
It would seem that layouts will just not recalculate until you either return from a function and allow the Qt event loop to progress or manually call show() yourself.
How to update a QLayout and get the new dimensions before returning?
Don't. You're not meant to do that. It'll drive you "nuts" because you're doing it backwards. Layout updates are handled asynchronously from the event loop. Instead of getting layout dimensions right away, set yourself up to be part of the system. Some options are:
Implement a custom widget that will interact properly with the layout, growing to fill the available width of the layout. Perhaps all you need is a size policy and a way to elide text?
Make a custom layout that takes the special properties of your use case into account.
You want to call QWidget::adjustSize() on your parent widget. This will force the layout recalculations.
Have you tried using layout()->update(); ?
I've tried many but nothing works for me on Qt 5.15.
Only invented little patch - create timer and get size after 20 msec:
QTimer::singleShot(20, this, [this]
{
const auto height = myLayout->contentsRect().height();
// ...
});

Flex custom component first item not read by JAWS

Flex application is being made accessibility compliant. When a custom component is made visible based on some condition, the first item (either text or formitem or textarea) inside the component is skipped by Jaws. It reads from the second item. On pressing UP arrow, the first item is then read.
Is there a way to make the first item accessible without need for pressing UP arrow?
This is likely going to be related to focus management.
You're likely going to want to assign componentId.setFocus() to the first component in the current view when the view state changes.
You need to re-assess the focus when the state of your display changes. If you post how you are managing display state I can suggest exactly how to trigger that via an event or in your custom state method.
Also, if that doesn't work, try this once your screen is ready / state changed :
focusManager.moveFocus(mx.events.FocusRequestDirection.TOP);

flex 4.1 s:List: how can i force the list to load all the items, not only the visible items?

I'm creating a facebook application in flex.
I'm actually working on the friends component that shows your friends who are using the application. now, each friend has a profile image.
I created the component using a s:List element.
In the Skin Class of the element i configured the requestedColumnCount to 3, which means it shows 3 friends. i added buttons to scroll left and right in the list.
Whenever I scroll to see a different friend, for a half of a second i see no image because the List component is loading the image in order to view it.
is there a way to make the list preload all the elements so i won't have this kind of problem ?
You can set useVirtualLayout on the List to false, which means it will no longer "recycle" the item renderers. You may still have a lag when the item renderers initially load the images. Hope that helps.

Resources