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(WindowDesc *desc, WindowNumber window_number) : Window(desc)
00033 {
00034 this->CreateNestedTree();
00035 this->vscroll = this->GetScrollbar(WID_GL_SCROLLBAR);
00036 this->FinishInitNested(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_GOAL && widget != WID_GL_PROGRESS) return;
00043
00044 int y = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_GL_GOAL, 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_GOAL && widget != WID_GL_PROGRESS) return;
00139 Dimension d = maxdim(GetStringBoundingBox(STR_GOALS_GLOBAL_TITLE), GetStringBoundingBox(STR_GOALS_COMPANY_TITLE));
00140
00141 if (widget == WID_GL_PROGRESS) {
00142
00143 d.width = 0;
00144 Goal *s;
00145 FOR_ALL_GOALS(s) {
00146 if (s->progress != NULL) {
00147 SetDParamStr(0, s->progress);
00148 Dimension goal_d = GetStringBoundingBox(STR_GOALS_PROGRESS);
00149
00150 if (goal_d.width > d.width) {
00151 d.width = goal_d.width;
00152 }
00153 }
00154 }
00155 }
00156
00157 resize->height = d.height;
00158
00159 d.height *= 5;
00160 d.width += padding.width + WD_FRAMERECT_RIGHT + WD_FRAMERECT_LEFT;
00161 d.height += padding.height + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
00162 *size = maxdim(*size, d);
00163 }
00164
00169 void DrawPartialGoalList(int widget, int &pos, const int cap, int x, int y, int right, bool global_section) const
00170 {
00171 if (widget == WID_GL_GOAL && IsInsideMM(pos, 0, cap)) DrawString(x, right, y + pos * FONT_HEIGHT_NORMAL, global_section ? STR_GOALS_GLOBAL_TITLE : STR_GOALS_COMPANY_TITLE);
00172 pos++;
00173
00174 uint num = 0;
00175 const Goal *s;
00176 FOR_ALL_GOALS(s) {
00177 if (global_section ? s->company == INVALID_COMPANY : s->company == _local_company && s->company != INVALID_COMPANY) {
00178 if (IsInsideMM(pos, 0, cap)) {
00179 switch (widget) {
00180 case WID_GL_GOAL:
00181
00182 SetDParamStr(0, s->text);
00183 DrawString(x, right, y + pos * FONT_HEIGHT_NORMAL, STR_GOALS_TEXT);
00184 break;
00185
00186 case WID_GL_PROGRESS:
00187 if (s->progress != NULL) {
00188 SetDParamStr(0, s->progress);
00189 DrawString(x, right, y + pos * FONT_HEIGHT_NORMAL, s->completed ? STR_GOALS_PROGRESS_COMPLETE : STR_GOALS_PROGRESS, TC_FROMSTRING, SA_RIGHT | SA_FORCE);
00190 }
00191 break;
00192 }
00193 }
00194 pos++;
00195 num++;
00196 }
00197 }
00198
00199 if (widget == WID_GL_GOAL && num == 0) {
00200 if (IsInsideMM(pos, 0, cap)) DrawString(x, right, y + pos * FONT_HEIGHT_NORMAL, STR_GOALS_NONE);
00201 pos++;
00202 }
00203 }
00204
00205 virtual void DrawWidget(const Rect &r, int widget) const
00206 {
00207 if (widget != WID_GL_GOAL && widget != WID_GL_PROGRESS) return;
00208
00209 YearMonthDay ymd;
00210 ConvertDateToYMD(_date, &ymd);
00211
00212 int right = r.right - WD_FRAMERECT_RIGHT;
00213 int y = r.top + WD_FRAMERECT_TOP;
00214 int x = r.left + WD_FRAMERECT_LEFT;
00215
00216 int pos = -this->vscroll->GetPosition();
00217 const int cap = this->vscroll->GetCapacity();
00218
00219
00220 DrawPartialGoalList(widget, pos, cap, x, y, right, true);
00221
00222
00223 pos++;
00224 DrawPartialGoalList(widget, pos, cap, x, y, right, false);
00225 }
00226
00227 virtual void OnResize()
00228 {
00229 this->vscroll->SetCapacityFromWidget(this, WID_GL_GOAL);
00230 }
00231
00237 virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
00238 {
00239 if (!gui_scope) return;
00240 this->vscroll->SetCount(this->CountLines());
00241 }
00242 };
00243
00244 static const NWidgetPart _nested_goals_list_widgets[] = {
00245 NWidget(NWID_HORIZONTAL),
00246 NWidget(WWT_CLOSEBOX, COLOUR_BROWN),
00247 NWidget(WWT_CAPTION, COLOUR_BROWN), SetDataTip(STR_GOALS_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
00248 NWidget(WWT_SHADEBOX, COLOUR_BROWN),
00249 NWidget(WWT_DEFSIZEBOX, COLOUR_BROWN),
00250 NWidget(WWT_STICKYBOX, COLOUR_BROWN),
00251 EndContainer(),
00252 NWidget(NWID_HORIZONTAL), SetFill(1, 1),
00253 NWidget(WWT_PANEL, COLOUR_BROWN), SetDataTip(0x0, STR_GOALS_TOOLTIP_CLICK_ON_SERVICE_TO_CENTER), SetResize(1, 1), SetFill(1, 0), SetScrollbar(WID_GL_SCROLLBAR),
00254 NWidget(NWID_VERTICAL), SetPIP(WD_FRAMERECT_TOP, 4, WD_FRAMETEXT_BOTTOM),
00255 NWidget(NWID_HORIZONTAL), SetPIP(2, 4, 2),
00256 NWidget(WWT_EMPTY, COLOUR_GREY, WID_GL_GOAL), SetResize(1, 1), SetMinimalTextLines(2, 0), SetFill(1, 0),
00257 NWidget(WWT_EMPTY, COLOUR_GREY, WID_GL_PROGRESS), SetResize(0, 1), SetMinimalTextLines(2, 0), SetFill(0, 1),
00258 EndContainer(),
00259 EndContainer(),
00260 EndContainer(),
00261 NWidget(NWID_VERTICAL),
00262 NWidget(NWID_VSCROLLBAR, COLOUR_BROWN, WID_GL_SCROLLBAR),
00263 NWidget(WWT_RESIZEBOX, COLOUR_BROWN),
00264 EndContainer(),
00265 EndContainer(),
00266 };
00267
00268 static WindowDesc _goals_list_desc(
00269 WDP_AUTO, "list_goals", 500, 127,
00270 WC_GOALS_LIST, WC_NONE,
00271 0,
00272 _nested_goals_list_widgets, lengthof(_nested_goals_list_widgets)
00273 );
00274
00275 void ShowGoalsList()
00276 {
00277 AllocateWindowDescFront<GoalListWindow>(&_goals_list_desc, 0);
00278 }
00279
00280
00281
00282 struct GoalQuestionWindow : Window {
00283 char *question;
00284 int buttons;
00285 int button[3];
00286 byte type;
00287
00288 GoalQuestionWindow(WindowDesc *desc, WindowNumber window_number, byte type, uint32 button_mask, const char *question) : Window(desc), type(type)
00289 {
00290 assert(type < GOAL_QUESTION_TYPE_COUNT);
00291 this->question = strdup(question);
00292
00293
00294 uint bit;
00295 int n = 0;
00296 FOR_EACH_SET_BIT(bit, button_mask) {
00297 if (bit >= GOAL_QUESTION_BUTTON_COUNT) break;
00298 this->button[n++] = bit;
00299 if (n == 3) break;
00300 }
00301 this->buttons = n;
00302 assert(this->buttons > 0 && this->buttons < 4);
00303
00304 this->CreateNestedTree();
00305 this->GetWidget<NWidgetStacked>(WID_GQ_BUTTONS)->SetDisplayedPlane(this->buttons - 1);
00306 this->FinishInitNested(window_number);
00307 }
00308
00309 ~GoalQuestionWindow()
00310 {
00311 free(this->question);
00312 }
00313
00314 virtual void SetStringParameters(int widget) const
00315 {
00316 switch (widget) {
00317 case WID_GQ_CAPTION:
00318 SetDParam(0, STR_GOAL_QUESTION_CAPTION_QUESTION + this->type);
00319 break;
00320
00321 case WID_GQ_BUTTON_1:
00322 SetDParam(0, STR_GOAL_QUESTION_BUTTON_CANCEL + this->button[0]);
00323 break;
00324
00325 case WID_GQ_BUTTON_2:
00326 SetDParam(0, STR_GOAL_QUESTION_BUTTON_CANCEL + this->button[1]);
00327 break;
00328
00329 case WID_GQ_BUTTON_3:
00330 SetDParam(0, STR_GOAL_QUESTION_BUTTON_CANCEL + this->button[2]);
00331 break;
00332 }
00333 }
00334
00335 virtual void OnClick(Point pt, int widget, int click_count)
00336 {
00337 switch (widget) {
00338 case WID_GQ_BUTTON_1:
00339 DoCommandP(0, this->window_number, this->button[0], CMD_GOAL_QUESTION_ANSWER);
00340 delete this;
00341 break;
00342
00343 case WID_GQ_BUTTON_2:
00344 DoCommandP(0, this->window_number, this->button[1], CMD_GOAL_QUESTION_ANSWER);
00345 delete this;
00346 break;
00347
00348 case WID_GQ_BUTTON_3:
00349 DoCommandP(0, this->window_number, this->button[2], CMD_GOAL_QUESTION_ANSWER);
00350 delete this;
00351 break;
00352 }
00353 }
00354
00355 virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
00356 {
00357 if (widget != WID_GQ_QUESTION) return;
00358
00359 SetDParamStr(0, this->question);
00360 size->height = GetStringHeight(STR_JUST_RAW_STRING, size->width) + WD_PAR_VSEP_WIDE;
00361 }
00362
00363 virtual void DrawWidget(const Rect &r, int widget) const
00364 {
00365 if (widget != WID_GQ_QUESTION) return;
00366
00367 SetDParamStr(0, this->question);
00368 DrawStringMultiLine(r.left, r.right, r.top, UINT16_MAX, STR_JUST_RAW_STRING, TC_BLACK, SA_TOP | SA_HOR_CENTER);
00369 }
00370 };
00371
00372 static const NWidgetPart _nested_goal_question_widgets[] = {
00373 NWidget(NWID_HORIZONTAL),
00374 NWidget(WWT_CLOSEBOX, COLOUR_LIGHT_BLUE),
00375 NWidget(WWT_CAPTION, COLOUR_LIGHT_BLUE, WID_GQ_CAPTION), SetDataTip(STR_WHITE_STRING, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
00376 EndContainer(),
00377 NWidget(WWT_PANEL, COLOUR_LIGHT_BLUE),
00378 NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GQ_QUESTION), SetMinimalSize(300, 0), SetPadding(8, 8, 8, 8), SetFill(1, 0),
00379 NWidget(NWID_SELECTION, INVALID_COLOUR, WID_GQ_BUTTONS),
00380 NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(85, 10, 85),
00381 NWidget(WWT_PUSHTXTBTN, COLOUR_LIGHT_BLUE, WID_GQ_BUTTON_1), SetDataTip(STR_BLACK_STRING, STR_NULL), SetFill(1, 0),
00382 EndContainer(),
00383 NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(65, 10, 65),
00384 NWidget(WWT_PUSHTXTBTN, COLOUR_LIGHT_BLUE, WID_GQ_BUTTON_1), SetDataTip(STR_BLACK_STRING, STR_NULL), SetFill(1, 0),
00385 NWidget(WWT_PUSHTXTBTN, COLOUR_LIGHT_BLUE, WID_GQ_BUTTON_2), SetDataTip(STR_BLACK_STRING, STR_NULL), SetFill(1, 0),
00386 EndContainer(),
00387 NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(25, 10, 25),
00388 NWidget(WWT_PUSHTXTBTN, COLOUR_LIGHT_BLUE, WID_GQ_BUTTON_1), SetDataTip(STR_BLACK_STRING, STR_NULL), SetFill(1, 0),
00389 NWidget(WWT_PUSHTXTBTN, COLOUR_LIGHT_BLUE, WID_GQ_BUTTON_2), SetDataTip(STR_BLACK_STRING, STR_NULL), SetFill(1, 0),
00390 NWidget(WWT_PUSHTXTBTN, COLOUR_LIGHT_BLUE, WID_GQ_BUTTON_3), SetDataTip(STR_BLACK_STRING, STR_NULL), SetFill(1, 0),
00391 EndContainer(),
00392 EndContainer(),
00393 NWidget(NWID_SPACER), SetMinimalSize(0, 8),
00394 EndContainer(),
00395 };
00396
00397 static WindowDesc _goal_question_list_desc(
00398 WDP_CENTER, NULL, 0, 0,
00399 WC_GOAL_QUESTION, WC_NONE,
00400 WDF_CONSTRUCTION,
00401 _nested_goal_question_widgets, lengthof(_nested_goal_question_widgets)
00402 );
00403
00404
00405 void ShowGoalQuestion(uint16 id, byte type, uint32 button_mask, const char *question)
00406 {
00407 new GoalQuestionWindow(&_goal_question_list_desc, id, type, button_mask, question);
00408 }