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 "date_func.h"
13 #include "window_func.h"
14 #include "window_gui.h"
16 #include "core/geometry_func.hpp"
18 #include "widgets/dropdown_type.h"
19 #include "widgets/date_widget.h"
21 #include "safeguards.h"
24 /** Window to select a date graphically by using dropdowns */
25 struct SetDateWindow
: Window
{
26 SetDateCallback
*callback
; ///< Callback to call when a date has been selected
27 YearMonthDay date
; ///< The currently selected date
28 Year min_year
; ///< The minimum year in the year dropdown
29 Year max_year
; ///< The maximum year (inclusive) in the year dropdown
32 * Create the new 'set date' window
33 * @param desc the window description
34 * @param window_number number of the window
35 * @param parent the parent window, i.e. if this closes we should close too
36 * @param initial_date the initial date to show
37 * @param min_year the minimum year to show in the year dropdown
38 * @param max_year the maximum year (inclusive) to show in the year dropdown
39 * @param callback the callback to call once a date has been selected
41 SetDateWindow(WindowDesc
*desc
, WindowNumber window_number
, Window
*parent
, Date initial_date
, Year min_year
, Year max_year
, SetDateCallback
*callback
) :
44 min_year(std::max(MIN_YEAR
, min_year
)),
45 max_year(std::min(MAX_YEAR
, max_year
))
47 assert(this->min_year
<= this->max_year
);
48 this->parent
= parent
;
49 this->InitNested(window_number
);
51 if (initial_date
== 0) initial_date
= _date
;
52 ConvertDateToYMD(initial_date
, &this->date
);
53 this->date
.year
= Clamp(this->date
.year
, min_year
, max_year
);
56 Point
OnInitialPosition(int16 sm_width
, int16 sm_height
, int window_number
) override
58 Point pt
= { this->parent
->left
+ this->parent
->width
/ 2 - sm_width
/ 2, this->parent
->top
+ this->parent
->height
/ 2 - sm_height
/ 2 };
63 * Helper function to construct the dropdown.
64 * @param widget the dropdown widget to create the dropdown for
66 void ShowDateDropDown(int widget
)
72 default: NOT_REACHED();
75 for (uint i
= 0; i
< 31; i
++) {
76 list
.emplace_back(new DropDownListStringItem(STR_DAY_NUMBER_1ST
+ i
, i
+ 1, false));
78 selected
= this->date
.day
;
82 for (uint i
= 0; i
< 12; i
++) {
83 list
.emplace_back(new DropDownListStringItem(STR_MONTH_JAN
+ i
, i
, false));
85 selected
= this->date
.month
;
89 for (Year i
= this->min_year
; i
<= this->max_year
; i
++) {
90 DropDownListParamStringItem
*item
= new DropDownListParamStringItem(STR_JUST_INT
, i
, false);
92 list
.emplace_back(item
);
94 selected
= this->date
.year
;
98 ShowDropDownList(this, std::move(list
), selected
, widget
);
101 void UpdateWidgetSize(int widget
, Dimension
*size
, const Dimension
&padding
, Dimension
*fill
, Dimension
*resize
) override
103 Dimension d
= {0, 0};
108 for (uint i
= 0; i
< 31; i
++) {
109 d
= maxdim(d
, GetStringBoundingBox(STR_DAY_NUMBER_1ST
+ i
));
114 for (uint i
= 0; i
< 12; i
++) {
115 d
= maxdim(d
, GetStringBoundingBox(STR_MONTH_JAN
+ i
));
120 SetDParamMaxValue(0, this->max_year
);
121 d
= maxdim(d
, GetStringBoundingBox(STR_JUST_INT
));
125 d
.width
+= padding
.width
;
126 d
.height
+= padding
.height
;
130 void SetStringParameters(int widget
) const override
133 case WID_SD_DAY
: SetDParam(0, this->date
.day
- 1 + STR_DAY_NUMBER_1ST
); break;
134 case WID_SD_MONTH
: SetDParam(0, this->date
.month
+ STR_MONTH_JAN
); break;
135 case WID_SD_YEAR
: SetDParam(0, this->date
.year
); break;
139 void OnClick(Point pt
, int widget
, int click_count
) override
145 ShowDateDropDown(widget
);
148 case WID_SD_SET_DATE
:
149 if (this->callback
!= nullptr) this->callback(this, ConvertYMDToDate(this->date
.year
, this->date
.month
, this->date
.day
));
155 void OnDropdownSelect(int widget
, int index
) override
159 this->date
.day
= index
;
163 this->date
.month
= index
;
167 this->date
.year
= index
;
174 /** Widgets for the date setting window. */
175 static const NWidgetPart _nested_set_date_widgets
[] = {
176 NWidget(NWID_HORIZONTAL
),
177 NWidget(WWT_CLOSEBOX
, COLOUR_BROWN
),
178 NWidget(WWT_CAPTION
, COLOUR_BROWN
), SetDataTip(STR_DATE_CAPTION
, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS
),
180 NWidget(WWT_PANEL
, COLOUR_BROWN
),
181 NWidget(NWID_VERTICAL
), SetPIP(6, 6, 6),
182 NWidget(NWID_HORIZONTAL
, NC_EQUALSIZE
), SetPIP(6, 6, 6),
183 NWidget(WWT_DROPDOWN
, COLOUR_ORANGE
, WID_SD_DAY
), SetFill(1, 0), SetDataTip(STR_JUST_STRING
, STR_DATE_DAY_TOOLTIP
),
184 NWidget(WWT_DROPDOWN
, COLOUR_ORANGE
, WID_SD_MONTH
), SetFill(1, 0), SetDataTip(STR_JUST_STRING
, STR_DATE_MONTH_TOOLTIP
),
185 NWidget(WWT_DROPDOWN
, COLOUR_ORANGE
, WID_SD_YEAR
), SetFill(1, 0), SetDataTip(STR_JUST_INT
, STR_DATE_YEAR_TOOLTIP
),
187 NWidget(NWID_HORIZONTAL
),
188 NWidget(NWID_SPACER
), SetFill(1, 0),
189 NWidget(WWT_PUSHTXTBTN
, COLOUR_BROWN
, WID_SD_SET_DATE
), SetMinimalSize(100, 12), SetDataTip(STR_DATE_SET_DATE
, STR_DATE_SET_DATE_TOOLTIP
),
190 NWidget(NWID_SPACER
), SetFill(1, 0),
196 /** Description of the date setting window. */
197 static WindowDesc
_set_date_desc(
198 WDP_CENTER
, nullptr, 0, 0,
199 WC_SET_DATE
, WC_NONE
,
201 _nested_set_date_widgets
, lengthof(_nested_set_date_widgets
)
205 * Create the new 'set date' window
206 * @param window_number number for the window
207 * @param parent the parent window, i.e. if this closes we should close too
208 * @param initial_date the initial date to show
209 * @param min_year the minimum year to show in the year dropdown
210 * @param max_year the maximum year (inclusive) to show in the year dropdown
211 * @param callback the callback to call once a date has been selected
213 void ShowSetDateWindow(Window
*parent
, int window_number
, Date initial_date
, Year min_year
, Year max_year
, SetDateCallback
*callback
)
215 DeleteWindowByClass(WC_SET_DATE
);
216 new SetDateWindow(&_set_date_desc
, window_number
, parent
, initial_date
, min_year
, max_year
, callback
);