Blitting in the right order - a visitor problem
-
29-09-2019 - |
문제
I'm designing a simple GUI. I have Widgets, which have children and one parent. Each Widget is a Composite object, with a vector of WidgetComposite objects. One of those WidgetComposites is a PaintingBehaviour, but the Widget doesn't know it as such.
To display my window, I use a Visitor, called the ScreenVisitor. When the Visitor is called, this is what happens :
The first widget, the WidgetScene, iterates on each of its Widgets and calls the "accept(Visitor* v)" method. Then, each widget accepts the visitor, then iterates on its children.
For instance, this is a list of the objects (in the order it's going to happen) the visitor will have to accept.
root
child1
child2
child3
child4
child5
child6
child7
Now, my problem is simple : I want each Widget to be painted on its parent. How would you proceed ? I've tried with a tree, but I always have the same problem : when I have to go up in the hierarchy (for instance, after having displayed child3, when I have to display child4) I don't know how to get the right parent.
I'm coding in C++ but this problem is not language specific.
Do you have any ideas ? Thanks in advance !
해결책 2
All right, since I could not find anything else, I tried this solution :
The visitor create a tree of "DisplayNodes" objects, who are basically a class made essentially of pointers. Here are the attributes of the class :
class DisplayNode
{
private:
Widget* myWidget;
PaintingBehaviour* myPB;
DisplayNode* myParent;
vector <DisplayNode*>myChildren;
};
Every DisplayNode is stocked in a vector in my visitor.
Then, for each PaintingBehaviour, I test the parent of the Widget connected, and check if one of my Node's "myWidget" is this parent. So I can find back where is everything. After that, it's quite easy, a simple paint method in DisplayNode with recursive calls to the children, called with the first DisplayNode of the scene...
Since it's a bit heavy, I create the tree of DisplayNode only once (though I do it again if PaintingBehaviour or widgets are added / removed). If the tree already exists, I go directly to the recursive painting.
It's a bit twisted (and probably not quite optimized), I'll admit, but it works ! But if anybody has a better solution, I'll be more than happy to hear it.
다른 팁
The question is not very clear to me. If you just need to get them to be painted in the correct order. Parent before children, that would be quite easy:
accept(Visitor v)
paint() //paint parent first
v.visit()
foreach child
child.accept(v) //then paint children
If you need the parent (why?), you could change the accept method to (optionally) take a parent node.
accept(Visitor v,Element parent = null)
paint()
v.visit()
parent.foo()
foreach child
child.accept(v,this)