Codechange: Add OnClick handler for dropdown items.

This allows each dropdown item to indicate if something different should happen depending on where in the item was clicked.
This commit is contained in:
Peter Nelson
2025-05-23 17:44:17 +01:00
committed by Peter Nelson
parent 04e07dff84
commit 984d864c72
29 changed files with 95 additions and 55 deletions

View File

@@ -561,7 +561,7 @@ public:
this->SelectOtherAirport(-1);
}
void OnDropdownSelect(WidgetID widget, int index) override
void OnDropdownSelect(WidgetID widget, int index, int) override
{
if (widget == WID_AP_CLASS_DROPDOWN) {
_selected_airport_class = (AirportClassID)index;

View File

@@ -623,7 +623,7 @@ public:
}
}
void OnDropdownSelect(WidgetID widget, int index) override
void OnDropdownSelect(WidgetID widget, int index, int) override
{
switch (widget) {
case WID_RV_SORT_DROPDOWN:

View File

@@ -283,7 +283,7 @@ public:
}
}
void OnDropdownSelect(WidgetID widget, int index) override
void OnDropdownSelect(WidgetID widget, int index, int) override
{
if (widget == WID_BBS_DROPDOWN_CRITERIA && this->bridges.SortType() != index) {
this->bridges.SetSortType(index);

View File

@@ -1834,7 +1834,7 @@ struct BuildVehicleWindow : Window {
Command<CMD_RENAME_ENGINE>::Post(STR_ERROR_CAN_T_RENAME_TRAIN_TYPE + this->vehicle_type, this->rename_engine, *str);
}
void OnDropdownSelect(WidgetID widget, int index) override
void OnDropdownSelect(WidgetID widget, int index, int) override
{
switch (widget) {
case WID_BV_SORT_DROPDOWN:

View File

@@ -992,7 +992,7 @@ public:
this->vscroll->SetCapacityFromWidget(this, WID_SCL_MATRIX);
}
void OnDropdownSelect(WidgetID widget, int index) override
void OnDropdownSelect(WidgetID widget, int index, int) override
{
bool local = this->window_number == _local_company;
if (!local) return;

View File

@@ -153,7 +153,7 @@ struct SetDateWindow : Window {
}
}
void OnDropdownSelect(WidgetID widget, int index) override
void OnDropdownSelect(WidgetID widget, int index, int) override
{
switch (widget) {
case WID_SD_DAY:

View File

@@ -77,6 +77,7 @@ struct DropdownWindow : Window {
Rect wi_rect{}; ///< Rect of the button that opened the dropdown.
DropDownList list{}; ///< List with dropdown menu items.
int selected_result = 0; ///< Result value of the selected item in the list.
int selected_click_result = -1; ///< Click result value, from the OnClick handler of the selected item.
uint8_t click_delay = 0; ///< Timer to delay selection.
bool drag_mode = true;
bool instant_close = false; ///< Close the window when the mouse button is raised.
@@ -131,7 +132,7 @@ struct DropdownWindow : Window {
Point pt = _cursor.pos;
pt.x -= this->parent->left;
pt.y -= this->parent->top;
this->parent->OnDropdownClose(pt, this->parent_button, this->selected_result, this->instant_close);
this->parent->OnDropdownClose(pt, this->parent_button, this->selected_result, this->selected_click_result, this->instant_close);
/* Set flag on parent widget to indicate that we have just closed. */
NWidgetCore *nwc = this->parent->GetWidget<NWidgetCore>(this->parent_button);
@@ -225,14 +226,15 @@ struct DropdownWindow : Window {
/**
* Find the dropdown item under the cursor.
* @param[out] value Selected item, if function returns \c true.
* @param[out] result Selected item, if function returns \c true.
* @param[out] click_result Click result from OnClick of Selected item, if function returns \c true.
* @return Cursor points to a dropdown item.
*/
bool GetDropDownItem(int &value)
bool GetDropDownItem(int &result, int &click_result)
{
if (GetWidgetFromPos(this, _cursor.pos.x - this->left, _cursor.pos.y - this->top) < 0) return false;
const Rect &r = this->GetWidget<NWidgetBase>(WID_DM_ITEMS)->GetCurrentRect().Shrink(WidgetDimensions::scaled.dropdownlist);
const Rect &r = this->GetWidget<NWidgetBase>(WID_DM_ITEMS)->GetCurrentRect().Shrink(WidgetDimensions::scaled.dropdownlist).Shrink(WidgetDimensions::scaled.dropdowntext, RectPadding::zero);
int y = _cursor.pos.y - this->top - r.top;
int pos = this->vscroll->GetPosition();
@@ -244,7 +246,8 @@ struct DropdownWindow : Window {
if (y < item_height) {
if (item->masked || !item->Selectable()) return false;
value = item->result;
result = item->result;
click_result = item->OnClick({r.left, 0, r.right, item_height - 1}, {_cursor.pos.x - this->left, y});
return true;
}
@@ -284,10 +287,11 @@ struct DropdownWindow : Window {
void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
{
if (widget != WID_DM_ITEMS) return;
int item;
if (this->GetDropDownItem(item)) {
int result, click_result;
if (this->GetDropDownItem(result, click_result)) {
this->click_delay = 4;
this->selected_result = item;
this->selected_result = result;
this->selected_click_result = click_result;
this->SetDirty();
}
}
@@ -307,16 +311,16 @@ struct DropdownWindow : Window {
/* Close the dropdown, so it doesn't affect new window placement.
* Also mark it dirty in case the callback deals with the screen. (e.g. screenshots). */
if (!this->persist) this->Close();
this->parent->OnDropdownSelect(this->parent_button, this->selected_result);
this->parent->OnDropdownSelect(this->parent_button, this->selected_result, this->selected_click_result);
return;
}
if (this->drag_mode) {
int item;
int result, click_result;
if (!_left_button_clicked) {
this->drag_mode = false;
if (!this->GetDropDownItem(item)) {
if (!this->GetDropDownItem(result, click_result)) {
if (this->instant_close) this->Close();
return;
}
@@ -332,11 +336,12 @@ struct DropdownWindow : Window {
return;
}
if (!this->GetDropDownItem(item)) return;
if (!this->GetDropDownItem(result, click_result)) return;
}
if (this->selected_result != item) {
this->selected_result = item;
if (this->selected_result != result || this->selected_click_result != click_result) {
this->selected_result = result;
this->selected_click_result = click_result;
this->SetDirty();
}
}

View File

@@ -75,6 +75,12 @@ public:
uint Width() const override { return this->dim.width + this->TBase::Width(); }
int OnClick(const Rect &r, const Point &pt) const override
{
bool rtl = TEnd ^ (_current_text_dir == TD_RTL);
return this->TBase::OnClick(r.Indent(this->dim.width, rtl), pt);
}
void Draw(const Rect &full, const Rect &r, bool sel, Colours bg_colour) const override
{
bool rtl = TEnd ^ (_current_text_dir == TD_RTL);
@@ -125,6 +131,12 @@ public:
uint Height() const override { return std::max(this->dbounds.height, this->TBase::Height()); }
uint Width() const override { return this->dbounds.width + WidgetDimensions::scaled.hsep_normal + this->TBase::Width(); }
int OnClick(const Rect &r, const Point &pt) const override
{
bool rtl = TEnd ^ (_current_text_dir == TD_RTL);
return this->TBase::OnClick(r.Indent(this->dbounds.width + WidgetDimensions::scaled.hsep_normal, rtl), pt);
}
void Draw(const Rect &full, const Rect &r, bool sel, Colours bg_colour) const override
{
bool rtl = TEnd ^ (_current_text_dir == TD_RTL);
@@ -154,6 +166,12 @@ public:
uint Height() const override { return std::max<uint>(this->dim.height, this->TBase::Height()); }
uint Width() const override { return this->dim.width + WidgetDimensions::scaled.hsep_wide + this->TBase::Width(); }
int OnClick(const Rect &r, const Point &pt) const override
{
bool rtl = TEnd ^ (_current_text_dir == TD_RTL);
return this->TBase::OnClick(r.Indent(this->dim.width + WidgetDimensions::scaled.hsep_wide, rtl), pt);
}
void Draw(const Rect &full, const Rect &r, bool sel, Colours bg_colour) const override
{
bool rtl = TEnd ^ (_current_text_dir == TD_RTL);
@@ -178,6 +196,12 @@ public:
uint Width() const override { return this->indent * WidgetDimensions::scaled.hsep_indent + this->TBase::Width(); }
int OnClick(const Rect &r, const Point &pt) const override
{
bool rtl = TEnd ^ (_current_text_dir == TD_RTL);
return this->TBase::OnClick(r.Indent(this->indent * WidgetDimensions::scaled.hsep_indent, rtl), pt);
}
void Draw(const Rect &full, const Rect &r, bool sel, Colours bg_colour) const override
{
bool rtl = TEnd ^ (_current_text_dir == TD_RTL);

View File

@@ -32,6 +32,11 @@ public:
virtual uint Height() const { return 0; }
virtual uint Width() const { return 0; }
virtual int OnClick(const Rect &, const Point &) const
{
return -1;
}
virtual void Draw(const Rect &full, const Rect &, bool, Colours bg_colour) const
{
if (this->masked) GfxFillRect(full, GetColourGradient(bg_colour, SHADE_LIGHT), FILLRECT_CHECKER);

View File

@@ -353,14 +353,14 @@ struct GSConfigWindow : public Window {
SetValue(*value);
}
void OnDropdownSelect(WidgetID widget, int index) override
void OnDropdownSelect(WidgetID widget, int index, int) override
{
if (widget != WID_GSC_SETTING_DROPDOWN) return;
assert(this->clicked_dropdown);
SetValue(index);
}
void OnDropdownClose(Point, WidgetID widget, int, bool) override
void OnDropdownClose(Point, WidgetID widget, int, int, bool) override
{
if (widget != WID_GSC_SETTING_DROPDOWN) return;
/* We cannot raise the dropdown button just yet. OnClick needs some hint, whether

View File

@@ -852,7 +852,7 @@ struct GenerateLandscapeWindow : public Window {
}
}
void OnDropdownSelect(WidgetID widget, int index) override
void OnDropdownSelect(WidgetID widget, int index, int) override
{
switch (widget) {
case WID_GL_MAPSIZE_X_PULLDOWN: _settings_newgame.game_creation.map_x = index; break;
@@ -1190,7 +1190,7 @@ struct CreateScenarioWindow : public Window
this->RaiseWidgetsWhenLowered(WID_CS_START_DATE_DOWN, WID_CS_START_DATE_UP, WID_CS_FLAT_LAND_HEIGHT_DOWN, WID_CS_FLAT_LAND_HEIGHT_UP);
}
void OnDropdownSelect(WidgetID widget, int index) override
void OnDropdownSelect(WidgetID widget, int index, int) override
{
switch (widget) {
case WID_CS_MAPSIZE_X_PULLDOWN: _settings_newgame.game_creation.map_x = index; break;

View File

@@ -988,7 +988,7 @@ public:
this->vscroll->SetCapacityFromWidget(this, WID_GL_LIST_VEHICLE);
}
void OnDropdownSelect(WidgetID widget, int index) override
void OnDropdownSelect(WidgetID widget, int index, int) override
{
switch (widget) {
case WID_GL_GROUP_BY_DROPDOWN:

View File

@@ -1846,7 +1846,7 @@ public:
}
}
void OnDropdownSelect(WidgetID widget, int index) override
void OnDropdownSelect(WidgetID widget, int index, int) override
{
switch (widget) {
case WID_ID_DROPDOWN_CRITERIA: {
@@ -3149,7 +3149,7 @@ struct IndustryCargoesWindow : public Window {
}
}
void OnDropdownSelect(WidgetID widget, int index) override
void OnDropdownSelect(WidgetID widget, int index, int) override
{
if (index < 0) return;

View File

@@ -610,7 +610,7 @@ struct MusicTrackSelectionWindow : public Window {
}
}
void OnDropdownSelect(WidgetID widget, int index) override
void OnDropdownSelect(WidgetID widget, int index, int) override
{
switch (widget) {
case WID_MTS_MUSICSET:

View File

@@ -1082,7 +1082,7 @@ struct NetworkStartServerWindow : public Window {
}
}
void OnDropdownSelect(WidgetID widget, int index) override
void OnDropdownSelect(WidgetID widget, int index, int) override
{
switch (widget) {
case WID_NSS_CONNTYPE_BTN:
@@ -1768,15 +1768,15 @@ public:
return false;
}
void OnDropdownClose(Point pt, WidgetID widget, int index, bool instant_close) override
void OnDropdownClose(Point pt, WidgetID widget, int index, int click_result, bool instant_close) override
{
/* If you close the dropdown outside the list, don't take any action. */
if (widget == WID_CL_MATRIX) return;
Window::OnDropdownClose(pt, widget, index, instant_close);
Window::OnDropdownClose(pt, widget, index, click_result, instant_close);
}
void OnDropdownSelect(WidgetID widget, int index) override
void OnDropdownSelect(WidgetID widget, int index, int) override
{
switch (widget) {
case WID_CL_SERVER_VISIBILITY:

View File

@@ -209,6 +209,12 @@ public:
return this->dim.width + WidgetDimensions::scaled.hsep_wide + this->TBase::Width();
}
int OnClick(const Rect &r, const Point &pt) const override
{
bool rtl = TEnd ^ (_current_text_dir == TD_RTL);
return this->TBase::OnClick(r.Indent(this->dim.width + WidgetDimensions::scaled.hsep_wide, rtl), pt);
}
void Draw(const Rect &full, const Rect &r, bool sel, Colours bg_colour) const override
{
bool rtl = TEnd ^ (_current_text_dir == TD_RTL);

View File

@@ -442,7 +442,7 @@ struct NewGRFParametersWindow : public Window {
this->SetDirty();
}
void OnDropdownSelect(WidgetID widget, int index) override
void OnDropdownSelect(WidgetID widget, int index, int) override
{
if (widget != WID_NP_SETTING_DROPDOWN) return;
assert(this->clicked_dropdown);
@@ -451,7 +451,7 @@ struct NewGRFParametersWindow : public Window {
this->SetDirty();
}
void OnDropdownClose(Point, WidgetID widget, int, bool) override
void OnDropdownClose(Point, WidgetID widget, int, int, bool) override
{
if (widget != WID_NP_SETTING_DROPDOWN) return;
/* We cannot raise the dropdown button just yet. OnClick needs some hint, whether
@@ -1136,7 +1136,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback {
this->CloseChildWindows(WC_QUERY_STRING); // Remove the parameter query window
}
void OnDropdownSelect(WidgetID widget, int index) override
void OnDropdownSelect(WidgetID widget, int index, int) override
{
if (widget != WID_NS_PRESET_LIST) return;
if (!this->editable) return;

View File

@@ -1370,7 +1370,7 @@ public:
Command<CMD_MODIFY_ORDER>::Post(STR_ERROR_CAN_T_MODIFY_THIS_ORDER, this->vehicle->tile, this->vehicle->index, sel, MOF_COND_VALUE, Clamp(*value, 0, 2047));
}
void OnDropdownSelect(WidgetID widget, int index) override
void OnDropdownSelect(WidgetID widget, int index, int) override
{
switch (widget) {
case WID_O_NON_STOP:

View File

@@ -491,14 +491,14 @@ struct ScriptSettingsWindow : public Window {
SetValue(*value);
}
void OnDropdownSelect(WidgetID widget, int index) override
void OnDropdownSelect(WidgetID widget, int index, int) override
{
if (widget != WID_SCRS_SETTING_DROPDOWN) return;
assert(this->clicked_dropdown);
SetValue(index);
}
void OnDropdownClose(Point, WidgetID widget, int, bool) override
void OnDropdownClose(Point, WidgetID widget, int, int, bool) override
{
if (widget != WID_SCRS_SETTING_DROPDOWN) return;
/* We cannot raise the dropdown button just yet. OnClick needs some hint, whether

View File

@@ -1399,7 +1399,7 @@ struct GameOptionsWindow : Window {
}
}
void OnDropdownSelect(WidgetID widget, int index) override
void OnDropdownSelect(WidgetID widget, int index, int) override
{
switch (widget) {
case WID_GO_CURRENCY_DROPDOWN: // Currency
@@ -1492,14 +1492,14 @@ struct GameOptionsWindow : Window {
}
}
void OnDropdownClose(Point pt, WidgetID widget, int index, bool instant_close) override
void OnDropdownClose(Point pt, WidgetID widget, int index, int click_result, bool instant_close) override
{
if (widget != WID_GO_SETTING_DROPDOWN) {
/* Normally the default implementation of OnDropdownClose() takes care of
* a few things. We want that behaviour here too, but only for
* "normal" dropdown boxes. The special dropdown boxes added for every
* setting that needs one can't have this call. */
Window::OnDropdownClose(pt, widget, index, instant_close);
Window::OnDropdownClose(pt, widget, index, click_result, instant_close);
} else {
/* We cannot raise the dropdown button just yet. OnClick needs some hint, whether
* the same dropdown button was clicked again, and then not open the dropdown again.

View File

@@ -668,7 +668,7 @@ public:
}
}
void OnDropdownSelect(WidgetID widget, int index) override
void OnDropdownSelect(WidgetID widget, int index, int) override
{
if (widget == WID_STL_SORTDROPBTN) {
if (this->stations.SortType() != index) {
@@ -2112,7 +2112,7 @@ struct StationViewWindow : public Window {
this->SetDirty();
}
void OnDropdownSelect(WidgetID widget, int index) override
void OnDropdownSelect(WidgetID widget, int index, int) override
{
if (widget == WID_SV_SORT_BY) {
this->SelectSortBy(index);

View File

@@ -832,7 +832,7 @@ public:
}
}
void OnDropdownSelect(WidgetID widget, int index) override
void OnDropdownSelect(WidgetID widget, int index, int) override
{
if (widget != WID_SB_SEL_PAGE) return;

View File

@@ -621,7 +621,7 @@ void TextfileWindow::AfterLoadMarkdown()
this->SetupScrollbars();
}
void TextfileWindow::OnDropdownSelect(WidgetID widget, int index)
void TextfileWindow::OnDropdownSelect(WidgetID widget, int index, int)
{
if (widget != WID_TF_JUMPLIST) return;

View File

@@ -31,7 +31,7 @@ struct TextfileWindow : public Window, MissingGlyphSearcher {
void OnResize() override;
void OnInit() override;
void OnInvalidateData(int data = 0, bool gui_scope = true) override;
void OnDropdownSelect(WidgetID widget, int index) override;
void OnDropdownSelect(WidgetID widget, int index, int) override;
void OnRealtimeTick(uint delta_ms) override;
void OnScrollbarScroll(WidgetID widget) override;

View File

@@ -2027,7 +2027,7 @@ struct MainToolbarWindow : Window {
if (_game_mode != GM_MENU && !this->IsWidgetDisabled(widget)) _toolbar_button_procs[widget](this);
}
void OnDropdownSelect(WidgetID widget, int index) override
void OnDropdownSelect(WidgetID widget, int index, int) override
{
CallBackFunction cbf = _menu_clicked_procs[widget](index);
if (cbf != CBF_NONE) _last_started_action = cbf;
@@ -2403,7 +2403,7 @@ struct ScenarioEditorToolbarWindow : Window {
if (cbf != CBF_NONE) _last_started_action = cbf;
}
void OnDropdownSelect(WidgetID widget, int index) override
void OnDropdownSelect(WidgetID widget, int index, int) override
{
CallBackFunction cbf = _scen_toolbar_dropdown_procs[widget](index);
if (cbf != CBF_NONE) _last_started_action = cbf;

View File

@@ -950,7 +950,7 @@ public:
}
}
void OnDropdownSelect(WidgetID widget, int index) override
void OnDropdownSelect(WidgetID widget, int index, int) override
{
if (widget != WID_TD_SORT_CRITERIA) return;

View File

@@ -2170,7 +2170,7 @@ public:
}
}
void OnDropdownSelect(WidgetID widget, int index) override
void OnDropdownSelect(WidgetID widget, int index, int) override
{
switch (widget) {
case WID_VL_GROUP_BY_PULLDOWN:
@@ -2768,7 +2768,7 @@ struct VehicleDetailsWindow : Window {
return false;
}
void OnDropdownSelect(WidgetID widget, int index) override
void OnDropdownSelect(WidgetID widget, int index, int) override
{
switch (widget) {
case WID_VD_SERVICE_INTERVAL_DROPDOWN: {

View File

@@ -282,7 +282,7 @@ bool Window::IsWidgetHighlighted(WidgetID widget_index) const
* @param index the element in the dropdown that is selected.
* @param instant_close whether the dropdown was configured to close on mouse up.
*/
void Window::OnDropdownClose(Point pt, WidgetID widget, int index, bool instant_close)
void Window::OnDropdownClose(Point pt, WidgetID widget, int index, int click_result, bool instant_close)
{
if (widget < 0) return;
@@ -290,7 +290,7 @@ void Window::OnDropdownClose(Point pt, WidgetID widget, int index, bool instant_
/* Send event for selected option if we're still
* on the parent button of the dropdown (behaviour of the dropdowns in the main toolbar). */
if (GetWidgetFromPos(this, pt.x, pt.y) == widget) {
this->OnDropdownSelect(widget, index);
this->OnDropdownSelect(widget, index, click_result);
}
}

View File

@@ -766,9 +766,9 @@ public:
* @param widget the widget (button) that the dropdown is associated with.
* @param index the element in the dropdown that is selected.
*/
virtual void OnDropdownSelect([[maybe_unused]] WidgetID widget, [[maybe_unused]] int index) {}
virtual void OnDropdownSelect([[maybe_unused]] WidgetID widget, [[maybe_unused]] int index, [[maybe_unused]] int click_result) {}
virtual void OnDropdownClose(Point pt, WidgetID widget, int index, bool instant_close);
virtual void OnDropdownClose(Point pt, WidgetID widget, int index, int click_result, bool instant_close);
/**
* The text in an editbox has been edited.