views:

75

answers:

2

I'm trying to figure out how I can iterate in reverse, and forward through this, or atleast call a method in reverse.

Here is how it works.

Widgets have a std::vector of Widget* which are that control's children. The child vector is z ordered which means that child[0] is behind child[1] (in render order). Each control has a pointer to its parent except for the root (dummy) widget whos parent is NULL.

For my rendering, I need to sort of do a staircase sort of iteration (back to front) ex:

root->child[0];
root->child[0]->child[0];
root->child[0]->child[1];
root->child[1];
root->child[1]->child[0];
root->child[1]->child[1];

However to find which widget is under the mouse, I must do my point in rectangle test from front to back:

   root->child[9]->child[1];
    root->child[9]->child[0];
    root->child[9];
    root->child[8]->child[2];
    root->child[8]->child[1];
    root->child[8]->child[0];
    root->child[8];

What sort of iteration would I need to efficiently do the above 2 types of iterations? (back to front, front to back).

Thanks

+1  A: 

Forward iteration:

void blah_forward(const Widget *p)
{
    p->do_something();
    std::for_each(p->children.begin(), p->children.end(), blah_forward);
}

Reverse iteration:

void blah_reverse(const Widget *p)
{
    std::for_each(p->children.rbegin(), p->children.rend(), blah_reverse);
    p->do_something();
}

(untested, but hopefully you get the idea).

Oli Charlesworth
But what if p has children, these only do the iteration, it would need to be recursive
Milo
@Milo: These are recursive.
Oli Charlesworth
The reverse would have to `do_something()` after traversing the children. The results shown are in post-order.
Jeff M
@Jeff M: already fixed...
Oli Charlesworth
Works great thanks!
Milo
A: 

What you really have here is a tree with ordered children. And if I understand correctly, what you want to traverse them using Depth First Search visiting the children in reverse order. So you just need some recursive function widgetUnderMouse(Widget*) that traverses the tree in the order you want and checks if the current widget is under the mouse. Something like this I think.

Widget* widgetUnderMouse(Widget* root)
{
    if (root->hasChildren) 
    {
        vector<Widget*>::reverse_iterator rit;
        for (rit = root->child.rbegin(); rit < root->child.rend(); ++rit)
        {
            if (isWidgetUnderMouse(*rit)
            {
                return widgetUnderMouse(*rit);
            }
        }
    }
    else
    {
        return root;
    }
}

Where isWidgetUnderMouse returns true or false if the passed in widget is under the mouse

Nali4Freedom
You don't want `unsigned` here. This is exactly the sort of wheel-reinvention and subsequent bugginess that the STL algorithms were designed to avoid...
Oli Charlesworth