1
0
Fork 0

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.
pull/14300/head
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.