# date_gui.cpp

Go to the documentation of this file.

    00001 /* $Id$ */
    00002
    00003 /*
    00004  * This file is part of OpenTTD.
    00005  * 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.
    00006  * 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.
    00007  * 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/>.
    00008  */
    00009
    00012 #include "stdafx.h"
    00013 #include "strings_func.h"
    00014 #include "date_func.h"
    00015 #include "window_func.h"
    00016 #include "window_gui.h"
    00017 #include "date_gui.h"
    00018 #include "core/geometry_func.hpp"
    00019 #include "settings_type.h"
    00020
    00021 #include "widgets/dropdown_type.h"
    00022
    00023 #include "table/strings.h"
    00024
    00026 enum SetDateWidgets {
    00027   SDW_DAY,
    00028   SDW_MONTH,
    00029   SDW_YEAR,
    00030   SDW_SET_DATE,
    00031 };
    00032
    00034 struct SetDateWindow : Window {
    00035   SetDateCallback *callback;
    00036   YearMonthDay date;
    00037   Year min_year;
    00038   Year max_year;
    00039
    00050   SetDateWindow(const WindowDesc *desc, WindowNumber window_number, Window *parent, Date initial_date, Year min_year, Year max_year, SetDateCallback *callback) :
    00051       Window(),
    00052       callback(callback),
    00053       min_year(max(MIN_YEAR, min_year)),
    00054       max_year(min(MAX_YEAR, max_year))
    00055   {
    00056     assert(this->min_year <= this->max_year);
    00057     this->parent = parent;
    00058     this->InitNested(desc, window_number);
    00059
    00060     if (initial_date == 0) initial_date = _date;
    00061     ConvertDateToYMD(initial_date, &this->date);
    00062     this->date.year = Clamp(this->date.year, min_year, max_year);
    00063   }
    00064
    00065   virtual Point OnInitialPosition(const WindowDesc *desc, int16 sm_width, int16 sm_height, int window_number)
    00066   {
    00067     Point pt = { this->parent->left + this->parent->width / 2 - sm_width / 2, this->parent->top + this->parent->height / 2 - sm_height / 2 };
    00068     return pt;
    00069   }
    00070
    00075   virtual void ShowDateDropDown(int widget)
    00076   {
    00077     int selected;
    00078     DropDownList *list = new DropDownList();
    00079
    00080     switch (widget) {
    00081       default: NOT_REACHED();
    00082
    00083       case SDW_DAY:
    00084         for (uint i = 0; i < 31; i++) {
    00085           list->push_back(new DropDownListStringItem(STR_ORDINAL_NUMBER_1ST + i, i + 1, false));
    00086         }
    00087         selected = this->date.day;
    00088         break;
    00089
    00090       case SDW_MONTH:
    00091         for (uint i = 0; i < 12; i++) {
    00092           list->push_back(new DropDownListStringItem(STR_MONTH_JAN + i, i, false));
    00093         }
    00094         selected = this->date.month;
    00095         break;
    00096
    00097       case SDW_YEAR:
    00098         for (Year i = this->min_year; i <= this->max_year; i++) {
    00099           DropDownListParamStringItem *item = new DropDownListParamStringItem(STR_JUST_INT, i, false);
    00100           item->SetParam(0, i);
    00101           list->push_back(item);
    00102         }
    00103         selected = this->date.year;
    00104         break;
    00105     }
    00106
    00107     ShowDropDownList(this, list, selected, widget);
    00108   }
    00109
    00110   virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
    00111   {
    00112     Dimension d = {0, 0};
    00113     switch (widget) {
    00114       default: return;
    00115
    00116       case SDW_DAY:
    00117         for (uint i = 0; i < 31; i++) {
    00118           d = maxdim(d, GetStringBoundingBox(STR_ORDINAL_NUMBER_1ST + i));
    00119         }
    00120         break;
    00121
    00122       case SDW_MONTH:
    00123         for (uint i = 0; i < 12; i++) {
    00124           d = maxdim(d, GetStringBoundingBox(STR_MONTH_JAN + i));
    00125         }
    00126         break;
    00127
    00128       case SDW_YEAR:
    00129         for (Year i = this->min_year; i <= this->max_year; i++) {
    00130           SetDParam(0, i);
    00131           d = maxdim(d, GetStringBoundingBox(STR_JUST_INT));
    00132         }
    00133         break;
    00134     }
    00135
    00136     d.width += padding.width;
    00137     d.height += padding.height;
    00138     *size = d;
    00139   }
    00140
    00141   virtual void SetStringParameters(int widget) const
    00142   {
    00143     switch (widget) {
    00144       case SDW_DAY:   SetDParam(0, this->date.day - 1 + STR_ORDINAL_NUMBER_1ST); break;
    00145       case SDW_MONTH: SetDParam(0, this->date.month + STR_MONTH_JAN); break;
    00146       case SDW_YEAR:  SetDParam(0, this->date.year); break;
    00147     }
    00148   }
    00149
    00150   virtual void OnClick(Point pt, int widget, int click_count)
    00151   {
    00152     switch (widget) {
    00153       case SDW_DAY:
    00154       case SDW_MONTH:
    00155       case SDW_YEAR:
    00156         ShowDateDropDown(widget);
    00157         break;
    00158
    00159       case SDW_SET_DATE:
    00160         if (this->callback != NULL) this->callback(this->parent, ConvertYMDToDate(this->date.year, this->date.month, this->date.day) * DAY_TICKS);
    00161         delete this;
    00162         break;
    00163     }
    00164   }
    00165
    00166   virtual void OnDropdownSelect(int widget, int index)
    00167   {
    00168     switch (widget) {
    00169       case SDW_DAY:
    00170         this->date.day = index;
    00171         break;
    00172
    00173       case SDW_MONTH:
    00174         this->date.month = index;
    00175         break;
    00176
    00177       case SDW_YEAR:
    00178         this->date.year = index;
    00179         break;
    00180     }
    00181     this->SetDirty();
    00182   }
    00183 };
    00184
    00185 struct SetMinutesWindow : SetDateWindow
    00186 {
    00187   Minutes minutes;
    00188
    00190   SetMinutesWindow(const WindowDesc *desc, WindowNumber window_number, Window *parent, DateTicks initial_date, Year min_year, Year max_year, SetDateCallback *callback) :
    00191       SetDateWindow(desc, window_number, parent, initial_date, min_year, max_year, callback),
    00192       minutes(initial_date / _settings_client.gui.ticks_per_minute)
    00193   {
    00194   }
    00195
    00200   virtual void ShowDateDropDown(int widget)
    00201   {
    00202     int selected;
    00203     DropDownList *list = new DropDownList();
    00204
    00205     switch (widget) {
    00206       default: NOT_REACHED();
    00207
    00208       case SDW_DAY:
    00209         for (uint i = 0; i < 60; i++) {
    00210           DropDownListParamStringItem *item = new DropDownListParamStringItem(STR_JUST_INT, i, false);
    00211           item->SetParam(0, i);
    00212           list->push_back(item);
    00213         }
    00214         selected = MINUTES_MINUTE(minutes);
    00215         break;
    00216
    00217       case SDW_MONTH:
    00218         for (uint i = 0; i < 24; i++) {
    00219           DropDownListParamStringItem *item = new DropDownListParamStringItem(STR_JUST_INT, i, false);
    00220           item->SetParam(0, i);
    00221           list->push_back(item);
    00222         }
    00223         selected = MINUTES_HOUR(minutes);
    00224         break;
    00225     }
    00226
    00227     ShowDropDownList(this, list, selected, widget);
    00228   }
    00229
    00230   virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
    00231   {
    00232     Dimension d = {0, 0};
    00233     switch (widget) {
    00234       default: return;
    00235
    00236       case SDW_DAY:
    00237         for (uint i = 0; i < 60; i++) {
    00238           SetDParam(0, i);
    00239           d = maxdim(d, GetStringBoundingBox(STR_JUST_INT));
    00240         }
    00241         break;
    00242
    00243       case SDW_MONTH:
    00244         for (uint i = 0; i < 24; i++) {
    00245           SetDParam(0, i);
    00246           d = maxdim(d, GetStringBoundingBox(STR_JUST_INT));
    00247         }
    00248         break;
    00249     }
    00250
    00251     d.width += padding.width;
    00252     d.height += padding.height;
    00253     *size = d;
    00254   }
    00255
    00256   virtual void SetStringParameters(int widget) const
    00257   {
    00258     switch (widget) {
    00259       case SDW_DAY:   SetDParam(0, MINUTES_MINUTE(minutes)); break;
    00260       case SDW_MONTH: SetDParam(0, MINUTES_HOUR(minutes)); break;
    00261     }
    00262   }
    00263
    00264   virtual void OnClick(Point pt, int widget, int click_count)
    00265   {
    00266     switch (widget) {
    00267       case SDW_DAY:
    00268       case SDW_MONTH:
    00269       case SDW_YEAR:
    00270         ShowDateDropDown(widget);
    00271         break;
    00272
    00273       case SDW_SET_DATE:
    00274         if (this->callback != NULL) this->callback(this->parent, (DateTicks)minutes * _settings_client.gui.ticks_per_minute);
    00275         delete this;
    00276         break;
    00277     }
    00278   }
    00279
    00280   virtual void OnDropdownSelect(int widget, int index)
    00281   {
    00282     Minutes current = 0;
    00283     switch (widget) {
    00284       case SDW_DAY:
    00285         current = MINUTES_DATE(MINUTES_DAY(CURRENT_MINUTE), MINUTES_HOUR(minutes), index);
    00286         break;
    00287
    00288       case SDW_MONTH:
    00289         current = MINUTES_DATE(MINUTES_DAY(CURRENT_MINUTE), index, MINUTES_MINUTE(minutes));
    00290         break;
    00291     }
    00292
    00293     if (current < (CURRENT_MINUTE - 60)) current += 60 * 24;
    00294     minutes = current;
    00295
    00296     this->SetDirty();
    00297   }
    00298 };
    00299
    00301 static const NWidgetPart _nested_set_date_widgets[] = {
    00302   NWidget(NWID_HORIZONTAL),
    00303     NWidget(WWT_CLOSEBOX, COLOUR_BROWN),
    00304     NWidget(WWT_CAPTION, COLOUR_BROWN), SetDataTip(STR_DATE_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
    00305   EndContainer(),
    00306   NWidget(WWT_PANEL, COLOUR_BROWN),
    00307     NWidget(NWID_VERTICAL), SetPIP(6, 6, 6),
    00308       NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(6, 6, 6),
    00309         NWidget(WWT_DROPDOWN, COLOUR_ORANGE, SDW_DAY), SetFill(1, 0), SetDataTip(STR_JUST_STRING, STR_DATE_DAY_TOOLTIP),
    00310         NWidget(WWT_DROPDOWN, COLOUR_ORANGE, SDW_MONTH), SetFill(1, 0), SetDataTip(STR_JUST_STRING, STR_DATE_MONTH_TOOLTIP),
    00311         NWidget(WWT_DROPDOWN, COLOUR_ORANGE, SDW_YEAR), SetFill(1, 0), SetDataTip(STR_JUST_INT, STR_DATE_YEAR_TOOLTIP),
    00312       EndContainer(),
    00313       NWidget(NWID_HORIZONTAL),
    00314         NWidget(NWID_SPACER), SetFill(1, 0),
    00315         NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, SDW_SET_DATE), SetMinimalSize(100, 12), SetDataTip(STR_DATE_SET_DATE, STR_DATE_SET_DATE_TOOLTIP),
    00316         NWidget(NWID_SPACER), SetFill(1, 0),
    00317       EndContainer(),
    00318     EndContainer(),
    00319   EndContainer()
    00320 };
    00321
    00322 static const NWidgetPart _nested_set_minutes_widgets[] = {
    00323   NWidget(NWID_HORIZONTAL),
    00324     NWidget(WWT_CLOSEBOX, COLOUR_BROWN),
    00325     NWidget(WWT_CAPTION, COLOUR_BROWN), SetDataTip(STR_DATE_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
    00326   EndContainer(),
    00327   NWidget(WWT_PANEL, COLOUR_BROWN),
    00328     NWidget(NWID_VERTICAL), SetPIP(6, 6, 6),
    00329       NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(6, 6, 6),
    00330         NWidget(WWT_DROPDOWN, COLOUR_ORANGE, SDW_MONTH), SetFill(1, 0), SetDataTip(STR_JUST_INT, STR_DATE_MINUTES_MONTH_TOOLTIP),
    00331         NWidget(WWT_DROPDOWN, COLOUR_ORANGE, SDW_DAY), SetFill(1, 0), SetDataTip(STR_JUST_INT, STR_DATE_MINUTES_DAY_TOOLTIP),
    00332       EndContainer(),
    00333       NWidget(NWID_HORIZONTAL),
    00334         NWidget(NWID_SPACER), SetFill(1, 0),
    00335         NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, SDW_SET_DATE), SetMinimalSize(100, 12), SetDataTip(STR_DATE_SET_DATE, STR_DATE_SET_DATE_TOOLTIP),
    00336         NWidget(NWID_SPACER), SetFill(1, 0),
    00337       EndContainer(),
    00338     EndContainer(),
    00339   EndContainer()
    00340 };
    00341
    00343 static const WindowDesc _set_date_desc(
    00344   WDP_CENTER, 0, 0,
    00345   WC_SET_DATE, WC_NONE,
    00346   WDF_UNCLICK_BUTTONS,
    00347   _nested_set_date_widgets, lengthof(_nested_set_date_widgets)
    00348 );
    00349
    00350 static const WindowDesc _set_minutes_desc(
    00351   WDP_CENTER, 0, 0,
    00352   WC_SET_DATE, WC_NONE,
    00353   WDF_UNCLICK_BUTTONS,
    00354   _nested_set_minutes_widgets, lengthof(_nested_set_minutes_widgets)
    00355 );
    00356
    00366 void ShowSetDateWindow(Window *parent, int window_number, DateTicks initial_date, Year min_year, Year max_year, SetDateCallback *callback)
    00367 {
    00368   DeleteWindowByClass(WC_SET_DATE);
    00369
    00370   if (!_settings_client.gui.time_in_minutes) {
    00371     new SetDateWindow(&_set_date_desc, window_number, parent, initial_date / DAY_TICKS, min_year, max_year, callback);
    00372   } else {
    00373     new SetMinutesWindow(&_set_minutes_desc, window_number, parent, initial_date, min_year, max_year, callback);
    00374   }
    00375 }