diff --git a/src/order_gui.cpp b/src/order_gui.cpp index 4902be27a3..7ab51ec030 100644 --- a/src/order_gui.cpp +++ b/src/order_gui.cpp @@ -2874,7 +2874,7 @@ public: break; } } - ShowDropDownMenu(this, _order_manage_list_dropdown, -1, widget, disabled_mask, 0, 0, DDSF_LOST_FOCUS); + ShowDropDownMenu(this, _order_manage_list_dropdown, -1, widget, disabled_mask, 0, 0, DDSF_SHARED); break; } @@ -2933,7 +2933,7 @@ public: add_colour(COLOUR_ORANGE); add_colour(COLOUR_PINK); } - ShowDropDownList(this, std::move(list), -1, widget, 0, DDMF_NONE, DDSF_LOST_FOCUS); + ShowDropDownList(this, std::move(list), -1, widget, 0, DDMF_NONE, DDSF_SHARED); break; } @@ -2951,7 +2951,7 @@ public: } else { const Order *o = this->vehicle->GetOrder(this->OrderGetSel()); ShowDropDownMenu(this, _order_non_stop_drowdown, o->GetNonStopType(), WID_O_NON_STOP, _settings_game.order.nonstop_only ? 5 : 0, - o->IsType(OT_GOTO_STATION) ? 0 : (o->IsType(OT_GOTO_WAYPOINT) ? 3 : 12), 0, DDSF_LOST_FOCUS); + o->IsType(OT_GOTO_STATION) ? 0 : (o->IsType(OT_GOTO_WAYPOINT) ? 3 : 12), 0, DDSF_SHARED); } break; @@ -2996,7 +2996,7 @@ public: list.push_back(std::make_unique(STR_ORDER_LABEL_TEXT_BUTTON, ODDI_LABEL_TEXT, false)); list.push_back(std::make_unique(STR_ORDER_LABEL_DEPARTURES_VIA_BUTTON, ODDI_LABEL_DEPARTURES_VIA, false)); - ShowDropDownList(this, std::move(list), sel, WID_O_GOTO, 0, DDMF_NONE, DDSF_LOST_FOCUS); + ShowDropDownList(this, std::move(list), sel, WID_O_GOTO, 0, DDMF_NONE, DDSF_SHARED); } break; @@ -3004,7 +3004,7 @@ public: if (this->GetWidget(widget)->ButtonHit(pt)) { this->OrderClick_FullLoad(OLF_FULL_LOAD_ANY, true); } else { - ShowDropDownMenu(this, _order_full_load_drowdown, this->vehicle->GetOrder(this->OrderGetSel())->GetLoadType(), WID_O_FULL_LOAD, 0, 0xE2 /* 1110 0010 */, 0, DDSF_LOST_FOCUS); + ShowDropDownMenu(this, _order_full_load_drowdown, this->vehicle->GetOrder(this->OrderGetSel())->GetLoadType(), WID_O_FULL_LOAD, 0, 0xE2 /* 1110 0010 */, 0, DDSF_SHARED); } break; @@ -3012,7 +3012,7 @@ public: if (this->GetWidget(widget)->ButtonHit(pt)) { this->OrderClick_Unload(OUFB_UNLOAD, true); } else { - ShowDropDownMenu(this, _order_unload_drowdown, this->vehicle->GetOrder(this->OrderGetSel())->GetUnloadType(), WID_O_UNLOAD, 0, 0xE8 /* 1110 1000 */, 0, DDSF_LOST_FOCUS); + ShowDropDownMenu(this, _order_unload_drowdown, this->vehicle->GetOrder(this->OrderGetSel())->GetUnloadType(), WID_O_UNLOAD, 0, 0xE8 /* 1110 1000 */, 0, DDSF_SHARED); } break; @@ -3022,14 +3022,14 @@ public: case WID_O_DEPOT_ACTION: ShowDropDownMenu(this, _order_depot_action_dropdown, DepotActionStringIndex(this->vehicle->GetOrder(this->OrderGetSel())), - WID_O_DEPOT_ACTION, 0, _settings_client.gui.show_depot_sell_gui ? 0 : (1 << DA_SELL), 0, DDSF_LOST_FOCUS); + WID_O_DEPOT_ACTION, 0, _settings_client.gui.show_depot_sell_gui ? 0 : (1 << DA_SELL), 0, DDSF_SHARED); break; case WID_O_REFIT_DROPDOWN: if (this->GetWidget(widget)->ButtonHit(pt)) { this->OrderClick_Refit(0, true); } else { - ShowDropDownMenu(this, _order_refit_action_dropdown, 0, WID_O_REFIT_DROPDOWN, 0, 0, 0, DDSF_LOST_FOCUS); + ShowDropDownMenu(this, _order_refit_action_dropdown, 0, WID_O_REFIT_DROPDOWN, 0, 0, 0, DDSF_SHARED); } break; @@ -3214,7 +3214,7 @@ public: mask = 0xC0; break; } - ShowDropDownMenu(this, GetComparatorStrings(this->vehicle, o), o->GetConditionComparator(), WID_O_COND_COMPARATOR, 0, mask, 0, DDSF_LOST_FOCUS); + ShowDropDownMenu(this, GetComparatorStrings(this->vehicle, o), o->GetConditionComparator(), WID_O_COND_COMPARATOR, 0, mask, 0, DDSF_SHARED); break; } diff --git a/src/timetable_gui.cpp b/src/timetable_gui.cpp index 2c4350bbb5..28afdc337f 100644 --- a/src/timetable_gui.cpp +++ b/src/timetable_gui.cpp @@ -1059,7 +1059,7 @@ struct TimetableWindow : GeneralVehicleWindow { list.emplace_back(std::make_unique(current == OLT_LEAVE_EARLY, STR_TIMETABLE_LEAVE_EARLY, OLT_LEAVE_EARLY, leave_type_disabled)); list.emplace_back(std::make_unique(current == OLT_LEAVE_EARLY_FULL_ANY, STR_TIMETABLE_LEAVE_EARLY_FULL_ANY, OLT_LEAVE_EARLY_FULL_ANY, leave_type_disabled || !order->IsType(OT_GOTO_STATION))); list.emplace_back(std::make_unique(current == OLT_LEAVE_EARLY_FULL_ALL, STR_TIMETABLE_LEAVE_EARLY_FULL_ALL, OLT_LEAVE_EARLY_FULL_ALL, leave_type_disabled || !order->IsType(OT_GOTO_STATION))); - ShowDropDownList(this, std::move(list), -1, widget, 0, DDMF_NONE, DDSF_LOST_FOCUS); + ShowDropDownList(this, std::move(list), -1, widget, 0, DDMF_NONE, DDSF_SHARED); break; } diff --git a/src/tracerestrict_gui.cpp b/src/tracerestrict_gui.cpp index 5739a30e64..5a37810a17 100644 --- a/src/tracerestrict_gui.cpp +++ b/src/tracerestrict_gui.cpp @@ -4053,7 +4053,7 @@ public: case WID_TRSL_SORT_BY_DROPDOWN: // Select sorting criteria dropdown menu ShowDropDownMenu(this, this->vehicle_group_none_sorter_names, this->vehgroups.SortType(), WID_TRSL_SORT_BY_DROPDOWN, 0, - this->GetSorterDisableMask(this->vli.vtype), 0, DDSF_LOST_FOCUS); + this->GetSorterDisableMask(this->vli.vtype)); return; case WID_TRSL_FILTER_BY_CARGO: // Cargo filter dropdown diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index 6487a026c8..37b87b9735 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -2419,7 +2419,7 @@ public: case WID_VL_SORT_BY_PULLDOWN: // Select sorting criteria dropdown menu ShowDropDownMenu(this, this->GetVehicleSorterNames(), this->vehgroups.SortType(), WID_VL_SORT_BY_PULLDOWN, 0, - this->GetSorterDisableMask(this->vli.vtype), 0, DDSF_LOST_FOCUS); + this->GetSorterDisableMask(this->vli.vtype)); return; case WID_VL_FILTER_BY_CARGO: // Cargo filter dropdown @@ -3365,7 +3365,7 @@ struct VehicleDetailsWindow : Window { const Vehicle *v = Vehicle::Get(this->window_number); ShowDropDownMenu(this, EconTime::UsingWallclockUnits() ? _service_interval_dropdown_wallclock : _service_interval_dropdown_calendar, - v->ServiceIntervalIsCustom() ? (v->ServiceIntervalIsPercent() ? 2 : 1) : 0, widget, 0, 0, 0, DDSF_LOST_FOCUS); + v->ServiceIntervalIsCustom() ? (v->ServiceIntervalIsPercent() ? 2 : 1) : 0, widget, 0, 0, 0, DDSF_SHARED); break; } diff --git a/src/widgets/dropdown.cpp b/src/widgets/dropdown.cpp index a9603368d9..b136d06323 100644 --- a/src/widgets/dropdown.cpp +++ b/src/widgets/dropdown.cpp @@ -94,9 +94,6 @@ struct DropdownWindow : Window { void Close([[maybe_unused]] int data = 0) override { - /* Make the dropdown "invisible", so it doesn't affect new window placement. - * Also mark it dirty in case the callback deals with the screen. (e.g. screenshots). */ - this->SetDirty(); this->Window::Close(); Window *w2 = FindWindowByToken(this->parent_wnd_token); @@ -105,9 +102,6 @@ struct DropdownWindow : Window { pt.x -= w2->left; pt.y -= w2->top; w2->OnDropdownClose(pt, this->parent_button, this->selected_result, (this->mode_flags & DDMF_INSTANT_CLOSE) != 0); - if (_focused_window == this) { - SetFocusedWindow(w2); - } } } @@ -273,15 +267,16 @@ struct DropdownWindow : Window { } if (this->click_delay != 0 && --this->click_delay == 0) { - /* Make the dropdown "invisible", 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->mode_flags & DDMF_PERSIST) == 0) { - this->window_class = WC_INVALID; - this->SetDirty(); + if (this->sync_parent_focus & DDSF_FOCUS_PARENT_ON_SELECT) { + SetFocusedWindow(w2); + } + + /* Close the dropdown, so it doesn't affect new window placement. */ + this->Close(); } w2->OnDropdownSelect(this->parent_button, this->selected_result); - if ((this->mode_flags & DDMF_PERSIST) == 0) this->Close(); return; } @@ -318,17 +313,17 @@ struct DropdownWindow : Window { virtual void OnFocus(Window *previously_focused_window) override { - if (this->sync_parent_focus & DDSF_RECV_FOCUS) { + if (this->sync_parent_focus & DDSF_NOTIFY_RECV_FOCUS) { Window *parent = FindWindowByToken(this->parent_wnd_token); - if (parent) parent->OnFocus(previously_focused_window); + if (parent != nullptr) parent->OnFocus(previously_focused_window); } } virtual void OnFocusLost(bool closing, Window *newly_focused_window) override { - if (this->sync_parent_focus & DDSF_LOST_FOCUS) { + if (this->sync_parent_focus & DDSF_NOTIFY_LOST_FOCUS) { Window *parent = FindWindowByToken(this->parent_wnd_token); - if (parent) parent->OnFocusLost(false, newly_focused_window); + if (parent != nullptr) parent->OnFocusLost(false, newly_focused_window); } } diff --git a/src/widgets/dropdown_type.h b/src/widgets/dropdown_type.h index 58a1e6ab65..b19f48a701 100644 --- a/src/widgets/dropdown_type.h +++ b/src/widgets/dropdown_type.h @@ -20,11 +20,14 @@ #include enum DropDownSyncFocus { - DDSF_NONE = 0, - DDSF_RECV_FOCUS = 1, - DDSF_LOST_FOCUS = 2, - DDSF_ALL = DDSF_RECV_FOCUS | DDSF_LOST_FOCUS, + DDSF_NONE = 0, + DDSF_NOTIFY_RECV_FOCUS = 1 << 0, + DDSF_NOTIFY_LOST_FOCUS = 1 << 1, + DDSF_FOCUS_PARENT_ON_SELECT = 1 << 2, + + DDSF_SHARED = DDSF_NOTIFY_RECV_FOCUS | DDSF_FOCUS_PARENT_ON_SELECT, }; +DECLARE_ENUM_AS_BIT_SET(DropDownSyncFocus) /** * Base list item class from which others are derived. diff --git a/src/window.cpp b/src/window.cpp index 2c036475f4..2212879576 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -429,6 +429,8 @@ void SetFocusedWindow(Window *w) { if (_focused_window == w) return; + if (w != nullptr && w->window_class == WC_INVALID) return; + /* Invalidate focused widget */ if (_focused_window != nullptr) { if (_focused_window->nested_focus != nullptr) _focused_window->nested_focus->SetDirty(_focused_window);