gui2/twidget: Recursively check visibility of parents in is_at()

This fixes an issue where visible children widgets can be interacted
with even if one of their parents is hidden. This fix is particularly
important for the implementation of layer selection in tstacked_widget.
This commit is contained in:
Ignacio R. Morelle 2015-07-10 22:16:23 -03:00
parent 86df4a9250
commit 6c97b05f84
3 changed files with 29 additions and 2 deletions

View file

@ -15,6 +15,9 @@ Version 1.13.1+dev:
* GUI2:
* stacked_widget can optionally display a single layer at a time. This
may be used to implement dialogs with multiple pages or tabs.
* Widgets which are children of invisible or hidden parents can no longer
be interacted with even if the children themselves are still internally
visible.
* Miscellaneous and bug fixes:
* Fixed unbound memory read in internal time formatting code with
specially-crafted input.

View file

@ -607,10 +607,23 @@ bool twidget::is_at(const tpoint& coordinate) const
return is_at(coordinate, true);
}
bool twidget::recursive_is_visible(const twidget* widget, const bool must_be_active) const
{
while(widget) {
if(widget->visible_ == tvisible::invisible
|| (widget->visible_ == tvisible::hidden && must_be_active)) {
return false;
}
widget = widget->parent_;
}
return true;
}
bool twidget::is_at(const tpoint& coordinate, const bool must_be_active) const
{
if(visible_ == tvisible::invisible
|| (visible_ == tvisible::hidden && must_be_active)) {
if(!recursive_is_visible(this, must_be_active)) {
return false;
}

View file

@ -821,6 +821,17 @@ private:
*/
bool is_at(const tpoint& coordinate, const bool must_be_active) const;
/**
* Is the widget and every single one of its parents visible?
*
* @param widget Widget where to start the check.
* @param must_be_active The widget should be active, not all widgets
* have an active flag, those who don't ignore
* flag.
*
* @returns Status.
*/
bool recursive_is_visible(const twidget* widget, const bool must_be_active) const;
/***** ***** ***** ***** Miscellaneous ***** ***** ****** *****/