Possible to copy/duplicate a CCLayer? - c++

I'm creating a scene that will have a list of items, like a shop menu. Ideally, I want to create the layout for a single shop item in CocosBuilder. Then, in code, I access that layout and make multiple copies for all my shop items, which can be added to the scene.
Is this possible in cocos2d-x?

if all of items you have are CCSprite, you can use this code for duplicating it:
CCSprite* copy=CCSprite::spriteWithTexture(source->getTexture());
you can duplicate all sprites in a layer then add them to a new layer.

Related

Implement Scrolling for QQuickView containing multiple QQuickPaintedItems

So recently I started a project where I want to display a graph showing relations between different datasets.
The graph consists of Edges and Nodes, while both of these classes inherit QQuickPaintedItem and override the paint(QPainter* painter) method. I have another class which stores all Nodes and Edges in two QLists. When I want to display the Graph, the paint method for every Node and Edge is called and is being painted into a QQuickView. I do this by setting a Qml File for the QQuickView (important: The loaded qml File has nothing to do with the actual Graph, everything is painted with the paint-method from QQuickPaintedItem and i haven't exposed anything related to the Graph to Qml.
The Qml File is being used to display some controls for the graph) and getting the content item (QQuickItem* from method contentItem()) of the QQuickView and setting it as a parent for every Node and Edge. All of this works fine for me.
Now to my problem: Some of the graphs I wanna display are bigger than my actual view i want to display them in, so to solve this i want to implement horizontal and vertical Scrolling for my View. However I haven't found anything that seems to solve my problem due to the fact that i can't use predefined Qml-Layouts like ListView aso. for my Graph.
Does anyone have an idea how I could implement Scrolling? Is there a way to implement this for my QQuickView or is there are way to expose my two Lists of Nodes and Edges to Qml and implement Scrolling in there?
(If you need some code, feel free to ask. I don't think it makes sense to share some code right now since I'm searching for an idea what to do about this topic in the first place).
Thank you!
If you don't mind rendering everything, what you need is Flickable.
Set the viewable width and height of your Flickable (explicitely, with anchors, or with layouts) and nest your custom item in it and set the contentWidth and contentHeight of the flickable depending on the total size or your custom item.

Two qGraphicsScenes Vs. one qGraphicsScene + duplicate items

I have a QGraphicsScene and a QGraphiscView. I have many items in the scene, with the behavior defined for each item sets. I call this normal mode. So in normal mode I can interact and see the items in the scene from the view.
I want to create a X-ray mode, which basically means the position of all items in the scene is the same, but items and behaviors are different.
The question is which of the following is the better approach (or there is even better one) to switch between modes:
Create a new scene, add items to the new scene on the same position as the old scene. To switch to x-ray mode, put view(scene) to the new scene.
Keep only one scene, add items to the normal scene, but for switching to X-ray mode, only hide/show items.
From ease of implementation, efficiency and speed, which option is better? Is there any built-in options in Qt to do this?

QML tree view from a model

I'm quite new to QML and I'm struggling to find any information how to render a tree model in a simple way (although horizontally, rather than vertically):
Seems like QML only supports list data structures from models. Is there any way to do it?
Figured it out on my own. The trick is to use DelegateModel, Repeater and Row/Column layouts, not TreeView.
Create a component which will show your current node using DelegateModel.
Use a Repeater to create children - let the component dynamically create another instance of itself, assign the current node as the rootIndex of newly constructed DelegateModel, and set it as the model for the Repeater.
By properly using layouts, you can position your nodes exactly as in the attached image.

UI Widget drawing in order

I have a custom UI Widget library I've created for a game I'm working on. I need to consider drawing order and retro fit it into what I currently have and not sure of the best way to do so. I have a UI class which loads the widgets from an xml file. It stores all widgets in a map where the key is the string name of the widget.
Widgets can hold other Widgets in a parent child relationship (so the Widget class has a map of Widgets where the name is the key again). When I draw I loop through the UI widget map and only call the Widget's Draw() function's that don't have parents (most top level). Within each Widget's Draw() it loops through it's children and calls their Draw() functions.
The question is what would be a good way to have a sort order variable for each widget work with drawing in the order of the sort order variable while keeping the maps, since I like the ease of finding widgets by the string key name?
Any ideas?
When you need multiple ways to order the same set of items, you have two choices:
Store both orderings, or
Store one ordering, and figure out the other one on the fly
Storing the second set of orderings is a way to pay with memory to save CPU cycles.
In your case, you have two orderings: the one implemented by the name-to-widget map, and the one for the drawing order. You have three implementation choices:
Store widgets in the map (i.e. ordered by name), and run a topological sort each time you need to figure out the drawing order - I assume here that the reason to order for drawing is to make sure that parents are drawn before children, implying the topological sort.
Store widgets in a list by the drawing order, and run linear lookups to get widgets by their name - This may be a good option when you draw widgets a lot, but look up by name very infrequently.
Store widgets in the map (i.e. ordered by name), and make a separate list of either widgets or widget names, arranged according to the drawing order - This double-accounting spends memory to buy back the CPU cycles that you would otherwise waste for re-ordering in the drawing order.

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 :)