This function will loop through rectangles painted in normal order(I'm implementing the painter's algorithm). However, I made the event handling loop into reversed order so the last rectangle drawn will be the priority of event handling. If one of the rectangles has been hovered by mouse, break the loop then reset the other rectangle.hovering
attribute to false
except the current rectangle being hovered. I have seen the repetition of code here so I would like to transform it into recursive one to make it flexible. Here I present the awful, limited and not flexible code yet functioning.
void swcApplication::overrideOnMouseMove(int x, int y)
{
static swcWidget *prev_widget = nullptr;
auto i = controls.getWidgets().size();
while (i)
{
auto &widget = controls.getWidgets()[--i];
if (!widget->enable) continue;
auto j = widget->components.size();
while (j)
{
auto &widget_component1 = widget->components[--j];
if (!widget_component1->enable) continue;
auto k = widget_component1->components.size();
while (k)
{
auto &widget_component2 = widget_component1->components[--k];
if (!widget_component2->enable) continue;
widget_component2->hovering = widget_component2->contains(x, y);
widget_component2->efOnMouseMove(x, y);
if (widget_component2->hovering)
{
if (prev_widget != nullptr &&
prev_widget != widget_component2)
{
prev_widget->hovering = false;
prev_widget->efOnMouseMove(x, y);
}
prev_widget = widget_component2;
widget_component1->hovering = false;
break;
}
}
widget_component1->hovering = widget_component1->contains(x, y);
widget_component1->efOnMouseMove(x, y);
if (widget_component1->hovering)
{
if (prev_widget != nullptr &&
prev_widget != widget_component1)
{
prev_widget->hovering = false;
prev_widget->efOnMouseMove(x, y);
}
prev_widget = widget_component1;
widget->hovering = false;
break;
}
}
widget->hovering = widget->contains(x, y);
widget->efOnMouseMove(x, y);
if (widget->hovering)
{
if (prev_widget != nullptr &&
prev_widget != widget)
{
prev_widget->hovering = false;
prev_widget->efOnMouseMove(x, y);
}
prev_widget = widget;
break;
}
}
}
I attempted to make my own recursive function to do this but it only works if I started hovering from the very last rectangle painted. If I started to hovering from the very first rectangle painted, it became buggy and I cannot figure out what order(of event) and condition I should make to imitate the iterative one.
Here is the code for recursive function call
//post-order traversal
void swcApplication::recursiveOnMouseMove(swcWidget *next, int x, int y)
{
if (!next->enable) return;
static swcWidget *prev_widget = nullptr;
auto i = next->components.size();
while (i)
{
auto &next_component = next->components[--i];
recursiveOnMouseMove(next_component, x, y);
}
if (prev_widget != nullptr &&
prev_widget != next &&
prev_widget->hovering)
{
prev_widget->hovering = false;
prev_widget->efOnMouseMove(x, y);
prev_widget = next;
return;
}
next->hovering = next->contains(x, y);
next->efOnMouseMove(x, y);
prev_widget = next;
}
//Here is the big loop
//prioritize first all rectangle.components w/c are another rectangle also (...so on and so forth)
while (i)
{
auto &widget = controls.getWidgets()[--i];
recursiveOnMouseMove(widget, x, y);
}
BTW: I am making a GUI simulated through OpenGL