mirror of https://github.com/OpenTTD/OpenTTD
Fix dec7ff6b0c: Dropdowns couldn't be closed by pressing the parent button. (#10954)
Since dropdowns self-close, the detection of re-clicking a dropdown button no longer worked, as the dropdown is already closed. Instead set (and then test) a flag on the parent widget to indicate that the dropdown closed. This method avoids looping windows on every click.pull/10970/head
parent
b2a8d8aea4
commit
b49bd86a46
|
@ -295,6 +295,7 @@ enum NWidgetDisplay {
|
||||||
NDB_SCROLLBAR_DOWN = 7, ///< Down-button is lowered bit.
|
NDB_SCROLLBAR_DOWN = 7, ///< Down-button is lowered bit.
|
||||||
/* Generic. */
|
/* Generic. */
|
||||||
NDB_HIGHLIGHT = 8, ///< Highlight of widget is on.
|
NDB_HIGHLIGHT = 8, ///< Highlight of widget is on.
|
||||||
|
NDB_DROPDOWN_CLOSED = 9, ///< Dropdown menu of the dropdown widget has closed.
|
||||||
|
|
||||||
ND_LOWERED = 1 << NDB_LOWERED, ///< Bit value of the lowered flag.
|
ND_LOWERED = 1 << NDB_LOWERED, ///< Bit value of the lowered flag.
|
||||||
ND_DISABLED = 1 << NDB_DISABLED, ///< Bit value of the disabled flag.
|
ND_DISABLED = 1 << NDB_DISABLED, ///< Bit value of the disabled flag.
|
||||||
|
@ -306,6 +307,7 @@ enum NWidgetDisplay {
|
||||||
ND_SCROLLBAR_UP = 1 << NDB_SCROLLBAR_UP, ///< Bit value of the 'scrollbar up' flag.
|
ND_SCROLLBAR_UP = 1 << NDB_SCROLLBAR_UP, ///< Bit value of the 'scrollbar up' flag.
|
||||||
ND_SCROLLBAR_DOWN = 1 << NDB_SCROLLBAR_DOWN, ///< Bit value of the 'scrollbar down' flag.
|
ND_SCROLLBAR_DOWN = 1 << NDB_SCROLLBAR_DOWN, ///< Bit value of the 'scrollbar down' flag.
|
||||||
ND_SCROLLBAR_BTN = ND_SCROLLBAR_UP | ND_SCROLLBAR_DOWN, ///< Bit value of the 'scrollbar up' or 'scrollbar down' flag.
|
ND_SCROLLBAR_BTN = ND_SCROLLBAR_UP | ND_SCROLLBAR_DOWN, ///< Bit value of the 'scrollbar up' or 'scrollbar down' flag.
|
||||||
|
ND_DROPDOWN_CLOSED = 1 << NDB_DROPDOWN_CLOSED, ///< Bit value of the 'dropdown closed' flag.
|
||||||
};
|
};
|
||||||
DECLARE_ENUM_AS_BIT_SET(NWidgetDisplay)
|
DECLARE_ENUM_AS_BIT_SET(NWidgetDisplay)
|
||||||
|
|
||||||
|
|
|
@ -191,6 +191,10 @@ struct DropdownWindow : Window {
|
||||||
pt.x -= this->parent->left;
|
pt.x -= this->parent->left;
|
||||||
pt.y -= this->parent->top;
|
pt.y -= this->parent->top;
|
||||||
this->parent->OnDropdownClose(pt, this->parent_button, this->selected_index, this->instant_close);
|
this->parent->OnDropdownClose(pt, this->parent_button, this->selected_index, this->instant_close);
|
||||||
|
|
||||||
|
/* Set flag on parent widget to indicate that we have just closed. */
|
||||||
|
NWidgetCore *nwc = this->parent->GetWidget<NWidgetCore>(this->parent_button);
|
||||||
|
if (nwc != nullptr) SetBit(nwc->disp_flags, NDB_DROPDOWN_CLOSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnFocusLost() override
|
void OnFocusLost() override
|
||||||
|
@ -471,25 +475,3 @@ void ShowDropDownMenu(Window *w, const StringID *strings, int selected, int butt
|
||||||
|
|
||||||
if (!list.empty()) ShowDropDownList(w, std::move(list), selected, button, width);
|
if (!list.empty()) ShowDropDownList(w, std::move(list), selected, button, width);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete the drop-down menu from window \a pw
|
|
||||||
* @param pw Parent window of the drop-down menu window
|
|
||||||
* @return Parent widget number if the drop-down was found and closed, \c -1 if the window was not found.
|
|
||||||
*/
|
|
||||||
int HideDropDownMenu(Window *pw)
|
|
||||||
{
|
|
||||||
for (Window *w : Window::Iterate()) {
|
|
||||||
if (w->parent != pw) continue;
|
|
||||||
if (w->window_class != WC_DROPDOWN_MENU) continue;
|
|
||||||
|
|
||||||
DropdownWindow *dw = dynamic_cast<DropdownWindow*>(w);
|
|
||||||
assert(dw != nullptr);
|
|
||||||
int parent_button = dw->parent_button;
|
|
||||||
dw->Close();
|
|
||||||
return parent_button;
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,4 @@
|
||||||
/* Show drop down menu containing a fixed list of strings */
|
/* Show drop down menu containing a fixed list of strings */
|
||||||
void ShowDropDownMenu(Window *w, const StringID *strings, int selected, int button, uint32 disabled_mask, uint32 hidden_mask, uint width = 0);
|
void ShowDropDownMenu(Window *w, const StringID *strings, int selected, int button, uint32 disabled_mask, uint32 hidden_mask, uint width = 0);
|
||||||
|
|
||||||
/* Hide drop down menu of a parent window */
|
|
||||||
int HideDropDownMenu(Window *pw);
|
|
||||||
|
|
||||||
#endif /* WIDGETS_DROPDOWN_FUNC_H */
|
#endif /* WIDGETS_DROPDOWN_FUNC_H */
|
||||||
|
|
|
@ -22,7 +22,6 @@
|
||||||
#include "tilehighlight_func.h"
|
#include "tilehighlight_func.h"
|
||||||
#include "network/network.h"
|
#include "network/network.h"
|
||||||
#include "querystring_gui.h"
|
#include "querystring_gui.h"
|
||||||
#include "widgets/dropdown_func.h"
|
|
||||||
#include "strings_func.h"
|
#include "strings_func.h"
|
||||||
#include "settings_type.h"
|
#include "settings_type.h"
|
||||||
#include "settings_func.h"
|
#include "settings_func.h"
|
||||||
|
@ -679,6 +678,9 @@ static void DispatchLeftClickEvent(Window *w, int x, int y, int click_count)
|
||||||
NWidgetCore *nw = w->nested_root->GetWidgetFromPos(x, y);
|
NWidgetCore *nw = w->nested_root->GetWidgetFromPos(x, y);
|
||||||
WidgetType widget_type = (nw != nullptr) ? nw->type : WWT_EMPTY;
|
WidgetType widget_type = (nw != nullptr) ? nw->type : WWT_EMPTY;
|
||||||
|
|
||||||
|
/* Allow dropdown close flag detection to work. */
|
||||||
|
if (nw != nullptr) ClrBit(nw->disp_flags, NDB_DROPDOWN_CLOSED);
|
||||||
|
|
||||||
bool focused_widget_changed = false;
|
bool focused_widget_changed = false;
|
||||||
/* If clicked on a window that previously did not have focus */
|
/* If clicked on a window that previously did not have focus */
|
||||||
if (_focused_window != w && // We already have focus, right?
|
if (_focused_window != w && // We already have focus, right?
|
||||||
|
@ -711,9 +713,8 @@ static void DispatchLeftClickEvent(Window *w, int x, int y, int click_count)
|
||||||
focused_widget_changed |= w->SetFocusedWidget(widget_index);
|
focused_widget_changed |= w->SetFocusedWidget(widget_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Close any child drop down menus. If the button pressed was the drop down
|
/* Dropdown window of this widget was closed so don't process click this time. */
|
||||||
* list's own button, then we should not process the click any further. */
|
if (HasBit(nw->disp_flags, NDB_DROPDOWN_CLOSED)) return;
|
||||||
if (HideDropDownMenu(w) == widget_index && widget_index >= 0) return;
|
|
||||||
|
|
||||||
if ((widget_type & ~WWB_PUSHBUTTON) < WWT_LAST && (widget_type & WWB_PUSHBUTTON)) w->HandleButtonClick(widget_index);
|
if ((widget_type & ~WWB_PUSHBUTTON) < WWT_LAST && (widget_type & WWB_PUSHBUTTON)) w->HandleButtonClick(widget_index);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue