views:

24

answers:

2

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 !

A: 

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)
Ishtar
About your first solution : you can't paint ON the parent widget with your solution, you'd have to paint directly on the screen. About the second one : no, because you would need the PaintingBehaviour of the parent, and the widgets do not know their PaintingBehaviour, they just have CompositeObjects.
Raveline
A: 

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.

Raveline