What is a good way to know when all surfaces had been initially rendered in famo.us? - famo.us

I would like to be able to know when all views have been rendered in a layout. The reason I want to do this is because I need to be able to reference positions of rendered views in the layout, so that I may animate views relative to other views that had already been rendered.
I have read this:
Surface render events in famo.us
One way I can think of is to count views that have been rendered and after all had been rendered (based on a known count), I can then assume all have been rendered. Obviously this would not work if there's an unknown number of views to render.
So another way to achieve this would be to have the layout fire a custom event when all of its managed surfaces have completed rendering. It seems like a good place to do this would be in a function shim in the given layout. For example, in SequentialLayout it would be SequentialLayout.prototype.commit. But, I am not 100% certain on whether that's the right approach, because it looks like the Engine or Entity manages the rendering. So, what that smells like to me is that this approach wouldn't actually fire the event I want fired at the right time.
Are there any best practices for this?

The best way in your use case may be to listen for the deploy on each surface (renderable) in each view
surface.on('deploy', function() {...});
and once all of the surfaces have been deployed emit a custom event to the view
thisView._eventOutput.emit('completed-deploy', {data: someData});
You can then listen to each view to know when the renderables are deployed
view.on('completed-deploy', function(data) {....});
Although this does take care of the fact that the renderable is deployed to the DOM, it will not let you know if it is done with any transition of a modifier. In the case you would also need to have a function for flagging when transition is complete in your views, if that is what you need.

Related

Change the order of ColumnLayout or ListView and save / restore it

I'm working on a stream overlay that extracts information out of a game (flight simulator) and displays it on the screen. Right now I'm using Qt in conjunction with a *.html to render the overlay. It is all working really well, however I wanted to add some customization options for the users of my overlay software and I figured the best way would be to render the Overlay in QML.
The main part of the overlay is a row that contains around 8 "elements" that display the relevant data.
One thing that should be customized is the order of the elements in the row. But I really have no idea how to implement this feature. I've seen a few posts and tutorials on how to customize the order in a View using the DelegateModel. However right now it's not a view but QML Components inserted in a RowLayout due to the fact that they are all different components (e.g. some of the images are actually animated for which I'm using a component that uses Canvas2D to draw the images). I guess I could figure out a way to store those elements in a model using the Loader Component to display the content in QML. But even then I'm not entirely sure how to store and restore the order of the elements. As far as I can tell the DelegateModel only changes the View and not the underlying model.
Any suggestion or best practice to accomplish my goal would be highly appreciated.

How to remove surfaces from a layout?

I'm creating a lot of little surfaces that get added to a layout ( int this case a header footer layout), animated, then need to go away. However, I'm not sure how to remove the surfaces once added?
Kraig is right about using a RenderController when possible, but I would not suggest it for your case. RenderController works well with large layouts and not so much for small particles and such. RenderController only shows one view at a time.
I have asked about this on the IRC channel and it turns out the way I do it, feels really hacky, but is still the recommended most straight forward approach. The idea is to just redefine the render function to return null.
// surface to remove
surface.render = function(){ return null; }
That's it!
Just make sure you remove all references in your code as well!
I often do it from an object..
delete littleSurfaces['little-surface-key']
FWIW The more advanced approach is to actually define a view that controls specifically the surfaces that get rendered. You do this by defining the render function on a custom view that returns what is known as a renderSpec. A renderSpec is a list of hashes that define the surfaces that will be rendered. The example everyone points to is the Flipper class. Take a look at Flippers render function..
https://github.com/Famous/views/blob/master/Flipper.js
Good Luck!
You can add/remove surfaces using a RenderController object. You can also apply an optional transition when things are shown and hidden.
The DOM may lie to you sometimes, as Famo.us repurposes and recycles DOM Elements for efficiency.
https://famo.us/docs/api/latest/views/RenderController

Refresh of a QGraphicsScene / QGraphicsView

I am troubled by the following:
I am working with an interactive QGraphicsScene that needs to render the graphical representation of an SQL query, based on the users' operations, such as: add something to the query (a table, a new column, something else) or remove something from the query (a keyword, a table, a column ...). The changes of the scene must be displayed after the operation, and also the "logic layer" of the application needs to track the operations the user did, since the "rendering" of the query is done by the "logic" layer (ie: the "logic layer" creates all the QGraphicsItemGroup derived objects which at a later stage, after all the logic layer components were built, are being added to the graphics scene of the query and put on the window).
The problem that occurs is the following: right now I did not manage to find any usable solution to present a query after a change in the smoothest possible way.
Allow me to link in a screenshot for further explanation:
Let's suppose the user wants to remove the PERSON.NAME column from the query. What happens in the application:
the user clicks on the "remove" (small red X after the column name) button of the PERSON.NAME columns' graphic item
the Graphics View senses this operation, sends the REMOVE column from the graphic system to the "logic layer" (the "model")
the logic layer on its turn removes the corresponding "logic layer" object representing the PERSON.NAME column,
And here the trouble starts:
the entire graphic (yes, everything) is re-rendered by the logic layer creating the graphic items for the same query, without PERSON.NAME
then I have to create a new window which has a new QGraphicsScene object together with a QGraphicsView
insert the re-rendered objects' graphic items representing the query, (but now without the PERSON.NAME column) into the new QGraphicsScene with addItem()
and now replace the central widget of the application with the new window.
and now you can see, that indeed, in the query the PERSON.NAME is not there anymore and all the graphic elements that were below PERSON.NAME were moved up on the screen.
Obviously this is not a good solution, there is an ugly flickering when I change the window, but I simply did not find a better solution to this problem till now.
So I am asking for your help in order to identify what improvements can be done to this methodology of updating the screen upon removal (addition) of a new element knowing the background information above, without a new window. Obviously other, mroe generic graphic related comments are welcome too.
Thanks,f
Based on the information from the question and the comments, a couple of things you could consider:
First thing is that you need to get rid of creating a new Window and a new QGraphicsView when refreshing.
I suppose this is the main reason for flickering. Keep your UI structure unmodified and only modify the scene.
You could use one of these approaches:
Either create a new QGraphicsScene and set it as the view's scene, or call clear() on
the existing scene. Then recreate your QGraphicsItems from your native model and make sure that all your pointers and references are updated.
Another approach would be to have the QGraphicsScene update your native model when something changes, to avoid the need to recreate the whole scene from scratch. For example, let the QGraphicsScene handle the deletion of the QGraphicsItem when the user clicks the delete icon, and then let the scene update your native model to reflect this change.
Yet another approach would be to discard your native model, and use the QGraphicsScene with its QGraphicsItems as your model. Implement serialization etc. in the scene class. This avoids the need to synchronize the two models. The drawback is that your graphics independant logic is then much tighter coupled to the QGraphicsScene, which you might not want. Depending on your code size, this might also be a lot of work.
I would start with 1., since it seems to be the easiest way to go based on your existing approach. If you still come across weird issues with pointers and object ownership, try to isolate them and ask on SO :)

Size View to Fit Scene Processing:

I am looking for a way, in Processing, to automatically zoom in/out to fit a model which I am creating.
That is, set the view such that there is no part of my object which extends outside of the view of the window.
I've looked through the reference, but haven't seen anything which would aid in this.
I figure I could implement a way to do this, but if there's already a way to do this in Processing easily, I'd prefer not to reinvent the wheel.
Note: Also tagged with OpenGL, since the methods used in OpenGL would translate easily to Processing.

How to draw a line (or arrow) from one object to another in run time using Qt

I have to design a GUI using Qt. I would like to draw multiple lines depicting relationships between two objects. It's the same idea as matching a word with a definition by drawing a straight line (which might be a diagonal) between the two.
In my case it is an a label (with image inside of it) that needs to be matched with another label.
So we have something like this - http://dl.dropbox.com/u/46437808/DrawLines.png
And I want to add lines to make it look something like this http://dl.dropbox.com/u/46437808/DrawLines2.png
I need to do this in run time because the relationship will be changing based on different factors.
Thanks!
Do you need interaction or is this just an image that the user needs to see based on other information? If it's just a static image, I would simply draw it onto a QImage and show it. That way you have complete control over how things are drawn. So you can either cache the relationship diagrams you need ahead of time, or just draw them on the fly onto the QImage based on the relationship that needs to be displayed at the time. You can look at Qt's painting example for some ideas on how to accomplish what you need.
If you need interactivity, I would probably go with the Graphics View Framework. This way if you need push buttons, check boxes, etc. for any reason you can use the QGraphicsProxyWidget to get them, or you can just make your own from QGraphicsItem subclasses.