00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #include "stdafx.h"
00013 #include "industry.h"
00014 #include "town.h"
00015 #include "window_gui.h"
00016 #include "strings_func.h"
00017 #include "date_func.h"
00018 #include "viewport_func.h"
00019 #include "gui.h"
00020 #include "goal_base.h"
00021 #include "core/geometry_func.hpp"
00022 #include "company_func.h"
00023 #include "command_func.h"
00024
00025 #include "widgets/goal_widget.h"
00026
00027 #include "table/strings.h"
00028
00029 struct GoalListWindow : Window {
00030 Scrollbar *vscroll;
00031
00032 GoalListWindow(const WindowDesc *desc, WindowNumber window_number) : Window()
00033 {
00034 this->CreateNestedTree(desc);
00035 this->vscroll = this->GetScrollbar(WID_GL_SCROLLBAR);
00036 this->FinishInitNested(desc, window_number);
00037 this->OnInvalidateData(0);
00038 }
00039
00040 virtual void OnClick(Point pt, int widget, int click_count)
00041 {
00042 if (widget != WID_GL_PANEL) return;
00043
00044 int y = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_GL_PANEL, WD_FRAMERECT_TOP);
00045 int num = 0;
00046 const Goal *s;
00047 FOR_ALL_GOALS(s) {
00048 if (s->company == INVALID_COMPANY) {
00049 y--;
00050 if (y == 0) {
00051 this->HandleClick(s);
00052 return;
00053 }
00054 num++;
00055 }
00056 }
00057
00058 if (num == 0) {
00059 y--;
00060 if (y < 0) return;
00061 }
00062
00063 y -= 2;
00064 if (y < 0) return;
00065
00066 FOR_ALL_GOALS(s) {
00067 if (s->company == _local_company) {
00068 y--;
00069 if (y == 0) {
00070 this->HandleClick(s);
00071 return;
00072 }
00073 }
00074 }
00075 }
00076
00077 void HandleClick(const Goal *s)
00078 {
00079
00080 TileIndex xy;
00081 switch (s->type) {
00082 case GT_NONE: return;
00083 case GT_COMPANY: return;
00084
00085 case GT_TILE:
00086 if (!IsValidTile(s->dst)) return;
00087 xy = s->dst;
00088 break;
00089
00090 case GT_INDUSTRY:
00091 if (!Industry::IsValidID(s->dst)) return;
00092 xy = Industry::Get(s->dst)->location.tile;
00093 break;
00094
00095 case GT_TOWN:
00096 if (!Town::IsValidID(s->dst)) return;
00097 xy = Town::Get(s->dst)->xy;
00098 break;
00099
00100 default: NOT_REACHED();
00101 }
00102
00103 if (_ctrl_pressed) {
00104 ShowExtraViewPortWindow(xy);
00105 } else {
00106 ScrollMainWindowToTile(xy);
00107 }
00108 }
00109
00114 uint CountLines()
00115 {
00116
00117 uint num_global = 0;
00118 uint num_company = 0;
00119 const Goal *s;
00120 FOR_ALL_GOALS(s) {
00121 if (s->company == INVALID_COMPANY) {
00122 num_global++;
00123 } else if (s->company == _local_company) {
00124 num_company++;
00125 }
00126 }
00127
00128
00129 if (num_global == 0) num_global = 1;
00130 if (num_company == 0) num_company = 1;
00131
00132
00133 return 3 + num_global + num_company;
00134 }
00135
00136 virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
00137 {
00138 if (widget != WID_GL_PANEL) return;
00139 Dimension d = maxdim(GetStringBoundingBox(STR_GOALS_GLOBAL_TITLE), GetStringBoundingBox(STR_GOALS_COMPANY_TITLE));
00140
00141 resize->height = d.height;
00142
00143 d.height *= 5;
00144 d.width += padding.width + WD_FRAMERECT_RIGHT + WD_FRAMERECT_LEFT;
00145 d.height += padding.height + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
00146 *size = maxdim(*size, d);
00147 }
00148
00149 virtual void DrawWidget(const Rect &r, int widget) const
00150 {
00151 if (widget != WID_GL_PANEL) return;
00152
00153 YearMonthDay ymd;
00154 ConvertDateToYMD(_date, &ymd);
00155
00156 int right = r.right - WD_FRAMERECT_RIGHT;
00157 int y = r.top + WD_FRAMERECT_TOP;
00158 int x = r.left + WD_FRAMERECT_LEFT;
00159
00160 int pos = -this->vscroll->GetPosition();
00161 const int cap = this->vscroll->GetCapacity();
00162
00163
00164 if (IsInsideMM(pos, 0, cap)) DrawString(x, right, y + pos * FONT_HEIGHT_NORMAL, STR_GOALS_GLOBAL_TITLE);
00165 pos++;
00166
00167 uint num = 0;
00168 const Goal *s;
00169 FOR_ALL_GOALS(s) {
00170 if (s->company == INVALID_COMPANY) {
00171 if (IsInsideMM(pos, 0, cap)) {
00172
00173 SetDParamStr(0, s->text);
00174 DrawString(x, right, y + pos * FONT_HEIGHT_NORMAL, STR_GOALS_TEXT);
00175 }
00176 pos++;
00177 num++;
00178 }
00179 }
00180
00181 if (num == 0) {
00182 if (IsInsideMM(pos, 0, cap)) DrawString(x, right, y + pos * FONT_HEIGHT_NORMAL, STR_GOALS_NONE);
00183 pos++;
00184 }
00185
00186
00187 pos++;
00188 if (IsInsideMM(pos, 0, cap)) DrawString(x, right, y + pos * FONT_HEIGHT_NORMAL, STR_GOALS_COMPANY_TITLE);
00189 pos++;
00190 num = 0;
00191
00192 FOR_ALL_GOALS(s) {
00193 if (s->company == _local_company) {
00194 if (IsInsideMM(pos, 0, cap)) {
00195
00196 SetDParamStr(0, s->text);
00197 DrawString(x, right, y + pos * FONT_HEIGHT_NORMAL, STR_GOALS_TEXT);
00198 }
00199 pos++;
00200 num++;
00201 }
00202 }
00203
00204 if (num == 0) {
00205 if (IsInsideMM(pos, 0, cap)) DrawString(x, right, y + pos * FONT_HEIGHT_NORMAL, STR_GOALS_NONE);
00206 pos++;
00207 }
00208 }
00209
00210 virtual void OnResize()
00211 {
00212 this->vscroll->SetCapacityFromWidget(this, WID_GL_PANEL);
00213 }
00214
00220 virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
00221 {
00222 if (!gui_scope) return;
00223 this->vscroll->SetCount(this->CountLines());
00224 }
00225 };
00226
00227 static const NWidgetPart _nested_goals_list_widgets[] = {
00228 NWidget(NWID_HORIZONTAL),
00229 NWidget(WWT_CLOSEBOX, COLOUR_BROWN),
00230 NWidget(WWT_CAPTION, COLOUR_BROWN), SetDataTip(STR_GOALS_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
00231 NWidget(WWT_SHADEBOX, COLOUR_BROWN),
00232 NWidget(WWT_STICKYBOX, COLOUR_BROWN),
00233 EndContainer(),
00234 NWidget(NWID_HORIZONTAL),
00235 NWidget(WWT_PANEL, COLOUR_BROWN, WID_GL_PANEL), SetDataTip(0x0, STR_GOALS_TOOLTIP_CLICK_ON_SERVICE_TO_CENTER), SetResize(1, 1), SetScrollbar(WID_GL_SCROLLBAR), EndContainer(),
00236 NWidget(NWID_VERTICAL),
00237 NWidget(NWID_VSCROLLBAR, COLOUR_BROWN, WID_GL_SCROLLBAR),
00238 NWidget(WWT_RESIZEBOX, COLOUR_BROWN),
00239 EndContainer(),
00240 EndContainer(),
00241 };
00242
00243 static const WindowDesc _goals_list_desc(
00244 WDP_AUTO, 500, 127,
00245 WC_GOALS_LIST, WC_NONE,
00246 0,
00247 _nested_goals_list_widgets, lengthof(_nested_goals_list_widgets)
00248 );
00249
00250 void ShowGoalsList()
00251 {
00252 AllocateWindowDescFront<GoalListWindow>(&_goals_list_desc, 0);
00253 }
00254
00255
00256
00257 struct GoalQuestionWindow : Window {
00258 char *question;
00259 int buttons;
00260 int button[3];
00261 byte type;
00262
00263 GoalQuestionWindow(const WindowDesc *desc, WindowNumber window_number, byte type, uint32 button_mask, const char *question) : Window(), type(type)
00264 {
00265 assert(type < GOAL_QUESTION_TYPE_COUNT);
00266 this->question = strdup(question);
00267
00268
00269 uint bit;
00270 int n = 0;
00271 FOR_EACH_SET_BIT(bit, button_mask) {
00272 if (bit >= GOAL_QUESTION_BUTTON_COUNT) break;
00273 this->button[n++] = bit;
00274 if (n == 3) break;
00275 }
00276 this->buttons = n;
00277 assert(this->buttons > 0 && this->buttons < 4);
00278
00279 this->CreateNestedTree(desc);
00280 this->GetWidget<NWidgetStacked>(WID_GQ_BUTTONS)->SetDisplayedPlane(this->buttons - 1);
00281 this->FinishInitNested(desc, window_number);
00282 }
00283
00284 ~GoalQuestionWindow()
00285 {
00286 free(this->question);
00287 }
00288
00289 virtual void SetStringParameters(int widget) const
00290 {
00291 switch (widget) {
00292 case WID_GQ_CAPTION:
00293 SetDParam(0, STR_GOAL_QUESTION_CAPTION_QUESTION + this->type);
00294 break;
00295
00296 case WID_GQ_BUTTON_1:
00297 SetDParam(0, STR_GOAL_QUESTION_BUTTON_CANCEL + this->button[0]);
00298 break;
00299
00300 case WID_GQ_BUTTON_2:
00301 SetDParam(0, STR_GOAL_QUESTION_BUTTON_CANCEL + this->button[1]);
00302 break;
00303
00304 case WID_GQ_BUTTON_3:
00305 SetDParam(0, STR_GOAL_QUESTION_BUTTON_CANCEL + this->button[2]);
00306 break;
00307 }
00308 }
00309
00310 virtual void OnClick(Point pt, int widget, int click_count)
00311 {
00312 switch (widget) {
00313 case WID_GQ_BUTTON_1:
00314 DoCommandP(0, this->window_number, this->button[0], CMD_GOAL_QUESTION_ANSWER);
00315 delete this;
00316 break;
00317
00318 case WID_GQ_BUTTON_2:
00319 DoCommandP(0, this->window_number, this->button[1], CMD_GOAL_QUESTION_ANSWER);
00320 delete this;
00321 break;
00322
00323 case WID_GQ_BUTTON_3:
00324 DoCommandP(0, this->window_number, this->button[2], CMD_GOAL_QUESTION_ANSWER);
00325 delete this;
00326 break;
00327 }
00328 }
00329
00330 virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
00331 {
00332 if (widget != WID_GQ_QUESTION) return;
00333
00334 SetDParamStr(0, this->question);
00335 size->height = GetStringHeight(STR_JUST_RAW_STRING, size->width) + WD_PAR_VSEP_WIDE;
00336 }
00337
00338 virtual void DrawWidget(const Rect &r, int widget) const
00339 {
00340 if (widget != WID_GQ_QUESTION) return;
00341
00342 SetDParamStr(0, this->question);
00343 DrawStringMultiLine(r.left, r.right, r.top, UINT16_MAX, STR_JUST_RAW_STRING, TC_BLACK, SA_TOP | SA_HOR_CENTER);
00344 }
00345 };
00346
00347 static const NWidgetPart _nested_goal_question_widgets[] = {
00348 NWidget(NWID_HORIZONTAL),
00349 NWidget(WWT_CLOSEBOX, COLOUR_LIGHT_BLUE),
00350 NWidget(WWT_CAPTION, COLOUR_LIGHT_BLUE, WID_GQ_CAPTION), SetDataTip(STR_WHITE_STRING, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
00351 EndContainer(),
00352 NWidget(WWT_PANEL, COLOUR_LIGHT_BLUE),
00353 NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GQ_QUESTION), SetMinimalSize(300, 0), SetPadding(8, 8, 8, 8), SetFill(1, 0),
00354 NWidget(NWID_SELECTION, INVALID_COLOUR, WID_GQ_BUTTONS),
00355 NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(85, 10, 85),
00356 NWidget(WWT_PUSHTXTBTN, COLOUR_LIGHT_BLUE, WID_GQ_BUTTON_1), SetDataTip(STR_BLACK_STRING, STR_NULL), SetFill(1, 0),
00357 EndContainer(),
00358 NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(65, 10, 65),
00359 NWidget(WWT_PUSHTXTBTN, COLOUR_LIGHT_BLUE, WID_GQ_BUTTON_1), SetDataTip(STR_BLACK_STRING, STR_NULL), SetFill(1, 0),
00360 NWidget(WWT_PUSHTXTBTN, COLOUR_LIGHT_BLUE, WID_GQ_BUTTON_2), SetDataTip(STR_BLACK_STRING, STR_NULL), SetFill(1, 0),
00361 EndContainer(),
00362 NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(25, 10, 25),
00363 NWidget(WWT_PUSHTXTBTN, COLOUR_LIGHT_BLUE, WID_GQ_BUTTON_1), SetDataTip(STR_BLACK_STRING, STR_NULL), SetFill(1, 0),
00364 NWidget(WWT_PUSHTXTBTN, COLOUR_LIGHT_BLUE, WID_GQ_BUTTON_2), SetDataTip(STR_BLACK_STRING, STR_NULL), SetFill(1, 0),
00365 NWidget(WWT_PUSHTXTBTN, COLOUR_LIGHT_BLUE, WID_GQ_BUTTON_3), SetDataTip(STR_BLACK_STRING, STR_NULL), SetFill(1, 0),
00366 EndContainer(),
00367 EndContainer(),
00368 NWidget(NWID_SPACER), SetMinimalSize(0, 8),
00369 EndContainer(),
00370 };
00371
00372 static const WindowDesc _goal_question_list_desc(
00373 WDP_CENTER, 0, 0,
00374 WC_GOAL_QUESTION, WC_NONE,
00375 WDF_CONSTRUCTION,
00376 _nested_goal_question_widgets, lengthof(_nested_goal_question_widgets)
00377 );
00378
00379
00380 void ShowGoalQuestion(uint16 id, byte type, uint32 button_mask, const char *question)
00381 {
00382 new GoalQuestionWindow(&_goal_question_list_desc, id, type, button_mask, question);
00383 }