2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
8 /** @file date_gui.cpp Graphical selection of a date. */
11 #include "strings_func.h"
12 #include "timer/timer_game_economy.h"
13 #include "window_func.h"
14 #include "window_gui.h"
16 #include "core/geometry_func.hpp"
17 #include "dropdown_type.h"
18 #include "dropdown_func.h"
20 #include "widgets/date_widget.h"
22 #include "safeguards.h"
25 /** Window to select a date graphically by using dropdowns */
26 struct SetDateWindow
: Window
{
27 SetDateCallback
*callback
; ///< Callback to call when a date has been selected
28 void *callback_data
; ///< Callback data pointer.
29 TimerGameEconomy::YearMonthDay date
; ///< The currently selected date
30 TimerGameEconomy::Year min_year
; ///< The minimum year in the year dropdown
31 TimerGameEconomy::Year max_year
; ///< The maximum year (inclusive) in the year dropdown
34 * Create the new 'set date' window
35 * @param desc the window description
36 * @param window_number number of the window
37 * @param parent the parent window, i.e. if this closes we should close too
38 * @param initial_date the initial date to show
39 * @param min_year the minimum year to show in the year dropdown
40 * @param max_year the maximum year (inclusive) to show in the year dropdown
41 * @param callback the callback to call once a date has been selected
43 SetDateWindow(WindowDesc
&desc
, WindowNumber window_number
, Window
*parent
, TimerGameEconomy::Date initial_date
, TimerGameEconomy::Year min_year
, TimerGameEconomy::Year max_year
, SetDateCallback
*callback
, void *callback_data
) :
46 callback_data(callback_data
),
47 min_year(std::max(EconomyTime::MIN_YEAR
, min_year
)),
48 max_year(std::min(EconomyTime::MAX_YEAR
, max_year
))
50 assert(this->min_year
<= this->max_year
);
51 this->parent
= parent
;
52 this->InitNested(window_number
);
54 if (initial_date
== 0) initial_date
= TimerGameEconomy::date
;
55 this->date
= TimerGameEconomy::ConvertDateToYMD(initial_date
);
56 this->date
.year
= Clamp(this->date
.year
, min_year
, max_year
);
59 Point
OnInitialPosition([[maybe_unused
]] int16_t sm_width
, [[maybe_unused
]] int16_t sm_height
, [[maybe_unused
]] int window_number
) override
61 Point pt
= { this->parent
->left
+ this->parent
->width
/ 2 - sm_width
/ 2, this->parent
->top
+ this->parent
->height
/ 2 - sm_height
/ 2 };
66 * Helper function to construct the dropdown.
67 * @param widget the dropdown widget to create the dropdown for
69 void ShowDateDropDown(WidgetID widget
)
75 default: NOT_REACHED();
78 for (uint i
= 0; i
< 31; i
++) {
79 list
.push_back(MakeDropDownListStringItem(STR_DAY_NUMBER_1ST
+ i
, i
+ 1));
81 selected
= this->date
.day
;
85 for (uint i
= 0; i
< 12; i
++) {
86 list
.push_back(MakeDropDownListStringItem(STR_MONTH_JAN
+ i
, i
));
88 selected
= this->date
.month
;
92 for (TimerGameEconomy::Year i
= this->min_year
; i
<= this->max_year
; i
++) {
94 list
.push_back(MakeDropDownListStringItem(STR_JUST_INT
, i
.base()));
96 selected
= this->date
.year
.base();
100 ShowDropDownList(this, std::move(list
), selected
, widget
);
103 void UpdateWidgetSize(WidgetID widget
, Dimension
&size
, [[maybe_unused
]] const Dimension
&padding
, [[maybe_unused
]] Dimension
&fill
, [[maybe_unused
]] Dimension
&resize
) override
105 Dimension d
= {0, 0};
110 for (uint i
= 0; i
< 31; i
++) {
111 d
= maxdim(d
, GetStringBoundingBox(STR_DAY_NUMBER_1ST
+ i
));
116 for (uint i
= 0; i
< 12; i
++) {
117 d
= maxdim(d
, GetStringBoundingBox(STR_MONTH_JAN
+ i
));
122 SetDParamMaxValue(0, this->max_year
);
123 d
= maxdim(d
, GetStringBoundingBox(STR_JUST_INT
));
127 d
.width
+= padding
.width
;
128 d
.height
+= padding
.height
;
132 void SetStringParameters(WidgetID widget
) const override
135 case WID_SD_DAY
: SetDParam(0, this->date
.day
- 1 + STR_DAY_NUMBER_1ST
); break;
136 case WID_SD_MONTH
: SetDParam(0, this->date
.month
+ STR_MONTH_JAN
); break;
137 case WID_SD_YEAR
: SetDParam(0, this->date
.year
); break;
141 void OnClick([[maybe_unused
]] Point pt
, WidgetID widget
, [[maybe_unused
]] int click_count
) override
147 ShowDateDropDown(widget
);
150 case WID_SD_SET_DATE
:
151 if (this->callback
!= nullptr) this->callback(this, TimerGameEconomy::ConvertYMDToDate(this->date
.year
, this->date
.month
, this->date
.day
), this->callback_data
);
157 void OnDropdownSelect(WidgetID widget
, int index
) override
161 this->date
.day
= index
;
165 this->date
.month
= index
;
169 this->date
.year
= index
;
176 /** Widgets for the date setting window. */
177 static constexpr NWidgetPart _nested_set_date_widgets
[] = {
178 NWidget(NWID_HORIZONTAL
),
179 NWidget(WWT_CLOSEBOX
, COLOUR_BROWN
),
180 NWidget(WWT_CAPTION
, COLOUR_BROWN
), SetDataTip(STR_DATE_CAPTION
, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS
),
182 NWidget(WWT_PANEL
, COLOUR_BROWN
),
183 NWidget(NWID_VERTICAL
), SetPIP(6, 6, 6),
184 NWidget(NWID_HORIZONTAL
, NC_EQUALSIZE
), SetPIP(6, 6, 6),
185 NWidget(WWT_DROPDOWN
, COLOUR_ORANGE
, WID_SD_DAY
), SetFill(1, 0), SetDataTip(STR_JUST_STRING
, STR_DATE_DAY_TOOLTIP
),
186 NWidget(WWT_DROPDOWN
, COLOUR_ORANGE
, WID_SD_MONTH
), SetFill(1, 0), SetDataTip(STR_JUST_STRING
, STR_DATE_MONTH_TOOLTIP
),
187 NWidget(WWT_DROPDOWN
, COLOUR_ORANGE
, WID_SD_YEAR
), SetFill(1, 0), SetDataTip(STR_JUST_INT
, STR_DATE_YEAR_TOOLTIP
),
189 NWidget(NWID_HORIZONTAL
),
190 NWidget(NWID_SPACER
), SetFill(1, 0),
191 NWidget(WWT_PUSHTXTBTN
, COLOUR_BROWN
, WID_SD_SET_DATE
), SetMinimalSize(100, 12), SetDataTip(STR_DATE_SET_DATE
, STR_DATE_SET_DATE_TOOLTIP
),
192 NWidget(NWID_SPACER
), SetFill(1, 0),
198 /** Description of the date setting window. */
199 static WindowDesc
_set_date_desc(
200 WDP_CENTER
, nullptr, 0, 0,
201 WC_SET_DATE
, WC_NONE
,
203 _nested_set_date_widgets
207 * Create the new 'set date' window
208 * @param window_number number for the window
209 * @param parent the parent window, i.e. if this closes we should close too
210 * @param initial_date the initial date to show
211 * @param min_year the minimum year to show in the year dropdown
212 * @param max_year the maximum year (inclusive) to show in the year dropdown
213 * @param callback the callback to call once a date has been selected
214 * @param callback_data extra callback data
216 void ShowSetDateWindow(Window
*parent
, int window_number
, TimerGameEconomy::Date initial_date
, TimerGameEconomy::Year min_year
, TimerGameEconomy::Year max_year
, SetDateCallback
*callback
, void *callback_data
)
218 CloseWindowByClass(WC_SET_DATE
);
219 new SetDateWindow(_set_date_desc
, window_number
, parent
, initial_date
, min_year
, max_year
, callback
, callback_data
);