Tidy up focus management for vehicle dropdowns

pull/661/head
Jonathan G Rennison 4 months ago
parent fc2f746b80
commit 40f5f17e32

@ -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<DropDownListStringItem>(STR_ORDER_LABEL_TEXT_BUTTON, ODDI_LABEL_TEXT, false));
list.push_back(std::make_unique<DropDownListStringItem>(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<NWidgetLeaf>(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<NWidgetLeaf>(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<NWidgetLeaf>(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;
}

@ -1059,7 +1059,7 @@ struct TimetableWindow : GeneralVehicleWindow {
list.emplace_back(std::make_unique<DropDownListCheckedItem>(current == OLT_LEAVE_EARLY, STR_TIMETABLE_LEAVE_EARLY, OLT_LEAVE_EARLY, leave_type_disabled));
list.emplace_back(std::make_unique<DropDownListCheckedItem>(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<DropDownListCheckedItem>(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;
}

@ -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

@ -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;
}

@ -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);
}
}

@ -20,11 +20,14 @@
#include <vector>
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.

@ -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);

Loading…
Cancel
Save