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 }