00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #include "stdafx.h"
00013 #include "gui.h"
00014 #include "window_gui.h"
00015 #include "textbuf_gui.h"
00016 #include "viewport_func.h"
00017 #include "company_func.h"
00018 #include "command_func.h"
00019 #include "network/network.h"
00020 #include "network/network_gui.h"
00021 #include "network/network_func.h"
00022 #include "economy_func.h"
00023 #include "vehicle_base.h"
00024 #include "newgrf.h"
00025 #include "company_manager_face.h"
00026 #include "strings_func.h"
00027 #include "date_func.h"
00028 #include "widgets/dropdown_type.h"
00029 #include "tilehighlight_func.h"
00030 #include "sprite.h"
00031 #include "company_base.h"
00032 #include "core/geometry_func.hpp"
00033
00034 #include "table/strings.h"
00035
00037 enum {
00038 FIRST_GUI_CALL = INT_MAX,
00039
00040 EXP_LINESPACE = 2,
00041 EXP_BLOCKSPACE = 10,
00042 };
00043
00044 static void DoSelectCompanyManagerFace(Window *parent);
00045
00047 static ExpensesType _expenses_list_1[] = {
00048 EXPENSES_CONSTRUCTION,
00049 EXPENSES_NEW_VEHICLES,
00050 EXPENSES_TRAIN_RUN,
00051 EXPENSES_ROADVEH_RUN,
00052 EXPENSES_AIRCRAFT_RUN,
00053 EXPENSES_SHIP_RUN,
00054 EXPENSES_PROPERTY,
00055 EXPENSES_TRAIN_INC,
00056 EXPENSES_ROADVEH_INC,
00057 EXPENSES_AIRCRAFT_INC,
00058 EXPENSES_SHIP_INC,
00059 EXPENSES_LOAN_INT,
00060 EXPENSES_OTHER,
00061 };
00062
00064 static ExpensesType _expenses_list_2[] = {
00065 EXPENSES_TRAIN_INC,
00066 EXPENSES_ROADVEH_INC,
00067 EXPENSES_AIRCRAFT_INC,
00068 EXPENSES_SHIP_INC,
00069 INVALID_EXPENSES,
00070 EXPENSES_TRAIN_RUN,
00071 EXPENSES_ROADVEH_RUN,
00072 EXPENSES_AIRCRAFT_RUN,
00073 EXPENSES_SHIP_RUN,
00074 EXPENSES_PROPERTY,
00075 EXPENSES_LOAN_INT,
00076 INVALID_EXPENSES,
00077 EXPENSES_CONSTRUCTION,
00078 EXPENSES_NEW_VEHICLES,
00079 EXPENSES_OTHER,
00080 INVALID_EXPENSES,
00081 };
00082
00084 struct ExpensesList {
00085 const ExpensesType *et;
00086 const uint length;
00087 const uint num_subtotals;
00088
00089 ExpensesList(ExpensesType *et, int length, int num_subtotals) : et(et), length(length), num_subtotals(num_subtotals)
00090 {
00091 }
00092
00093 uint GetHeight() const
00094 {
00095
00096 return FONT_HEIGHT_NORMAL + EXP_LINESPACE + this->length * FONT_HEIGHT_NORMAL + num_subtotals * (EXP_BLOCKSPACE + EXP_LINESPACE) + EXP_LINESPACE + FONT_HEIGHT_NORMAL;
00097 }
00098
00100 uint GetCategoriesWidth() const
00101 {
00102 uint width = 0;
00103 bool invalid_expenses_measured = false;
00104 for (uint i = 0; i < this->length; i++) {
00105 ExpensesType et = this->et[i];
00106 if (et == INVALID_EXPENSES) {
00107 if (!invalid_expenses_measured) {
00108 width = max(width, GetStringBoundingBox(STR_FINANCES_TOTAL_CAPTION).width);
00109 invalid_expenses_measured = true;
00110 }
00111 } else {
00112 width = max(width, GetStringBoundingBox(STR_FINANCES_SECTION_CONSTRUCTION + et).width);
00113 }
00114 }
00115 return width;
00116 }
00117 };
00118
00119 static const ExpensesList _expenses_list_types[] = {
00120 ExpensesList(_expenses_list_1, lengthof(_expenses_list_1), 0),
00121 ExpensesList(_expenses_list_2, lengthof(_expenses_list_2), 3),
00122 };
00123
00125 enum CompanyFinancesWindowWidgets {
00126 CFW_CAPTION,
00127 CFW_TOGGLE_SIZE,
00128 CFW_SEL_PANEL,
00129 CFW_EXPS_CATEGORY,
00130 CFW_EXPS_PRICE1,
00131 CFW_EXPS_PRICE2,
00132 CFW_EXPS_PRICE3,
00133 CFW_TOTAL_PANEL,
00134 CFW_SEL_MAXLOAN,
00135 CFW_BALANCE_VALUE,
00136 CFW_LOAN_VALUE,
00137 CFW_LOAN_LINE,
00138 CFW_TOTAL_VALUE,
00139 CFW_MAXLOAN_GAP,
00140 CFW_MAXLOAN_VALUE,
00141 CFW_SEL_BUTTONS,
00142 CFW_INCREASE_LOAN,
00143 CFW_REPAY_LOAN,
00144 };
00145
00150 static void DrawCategories(const Rect &r)
00151 {
00152 int y = r.top;
00153
00154 DrawString(r.left, r.right, y, STR_FINANCES_EXPENDITURE_INCOME_TITLE, TC_FROMSTRING, SA_CENTER, true);
00155 y += FONT_HEIGHT_NORMAL + EXP_LINESPACE;
00156
00157 int type = _settings_client.gui.expenses_layout;
00158 for (uint i = 0; i < _expenses_list_types[type].length; i++) {
00159 const ExpensesType et = _expenses_list_types[type].et[i];
00160 if (et == INVALID_EXPENSES) {
00161 y += EXP_LINESPACE;
00162 DrawString(r.left, r.right, y, STR_FINANCES_TOTAL_CAPTION, TC_FROMSTRING, SA_RIGHT);
00163 y += FONT_HEIGHT_NORMAL + EXP_BLOCKSPACE;
00164 } else {
00165 DrawString(r.left, r.right, y, STR_FINANCES_SECTION_CONSTRUCTION + et);
00166 y += FONT_HEIGHT_NORMAL;
00167 }
00168 }
00169
00170 DrawString(r.left, r.right, y + EXP_LINESPACE, STR_FINANCES_TOTAL_CAPTION, TC_FROMSTRING, SA_RIGHT);
00171 }
00172
00179 static void DrawPrice(Money amount, int left, int right, int top)
00180 {
00181 StringID str = STR_FINANCES_NEGATIVE_INCOME;
00182 if (amount < 0) {
00183 amount = -amount;
00184 str++;
00185 }
00186 SetDParam(0, amount);
00187 DrawString(left, right, top, str, TC_FROMSTRING, SA_RIGHT);
00188 }
00189
00196 static void DrawYearColumn(const Rect &r, int year, const Money (*tbl)[EXPENSES_END])
00197 {
00198 int y = r.top;
00199
00200 SetDParam(0, year);
00201 DrawString(r.left, r.right, y, STR_FINANCES_YEAR, TC_FROMSTRING, SA_RIGHT, true);
00202 y += FONT_HEIGHT_NORMAL + EXP_LINESPACE;
00203
00204 Money sum = 0;
00205 Money subtotal = 0;
00206 int type = _settings_client.gui.expenses_layout;
00207 for (uint i = 0; i < _expenses_list_types[type].length; i++) {
00208 const ExpensesType et = _expenses_list_types[type].et[i];
00209 if (et == INVALID_EXPENSES) {
00210 Money cost = subtotal;
00211 subtotal = 0;
00212 GfxFillRect(r.left, y, r.right, y, 215);
00213 y += EXP_LINESPACE;
00214 DrawPrice(cost, r.left, r.right, y);
00215 y += FONT_HEIGHT_NORMAL + EXP_BLOCKSPACE;
00216 } else {
00217 Money cost = (*tbl)[et];
00218 subtotal += cost;
00219 sum += cost;
00220 if (cost != 0) DrawPrice(cost, r.left, r.right, y);
00221 y += FONT_HEIGHT_NORMAL;
00222 }
00223 }
00224
00225 GfxFillRect(r.left, y, r.right, y, 215);
00226 y += EXP_LINESPACE;
00227 DrawPrice(sum, r.left, r.right, y);
00228 }
00229
00230 static const NWidgetPart _nested_company_finances_widgets[] = {
00231 NWidget(NWID_HORIZONTAL),
00232 NWidget(WWT_CLOSEBOX, COLOUR_GREY),
00233 NWidget(WWT_CAPTION, COLOUR_GREY, CFW_CAPTION), SetDataTip(STR_FINANCES_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
00234 NWidget(WWT_IMGBTN, COLOUR_GREY, CFW_TOGGLE_SIZE), SetDataTip(SPR_LARGE_SMALL_WINDOW, STR_TOOLTIP_TOGGLE_LARGE_SMALL_WINDOW),
00235 NWidget(WWT_SHADEBOX, COLOUR_GREY),
00236 NWidget(WWT_STICKYBOX, COLOUR_GREY),
00237 EndContainer(),
00238 NWidget(NWID_SELECTION, INVALID_COLOUR, CFW_SEL_PANEL),
00239 NWidget(WWT_PANEL, COLOUR_GREY),
00240 NWidget(NWID_HORIZONTAL), SetPadding(WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM, WD_FRAMERECT_LEFT), SetPIP(0, 9, 0),
00241 NWidget(WWT_EMPTY, COLOUR_GREY, CFW_EXPS_CATEGORY), SetMinimalSize(120, 0), SetFill(0, 0),
00242 NWidget(WWT_EMPTY, COLOUR_GREY, CFW_EXPS_PRICE1), SetMinimalSize(86, 0), SetFill(0, 0),
00243 NWidget(WWT_EMPTY, COLOUR_GREY, CFW_EXPS_PRICE2), SetMinimalSize(86, 0), SetFill(0, 0),
00244 NWidget(WWT_EMPTY, COLOUR_GREY, CFW_EXPS_PRICE3), SetMinimalSize(86, 0), SetFill(0, 0),
00245 EndContainer(),
00246 EndContainer(),
00247 EndContainer(),
00248 NWidget(WWT_PANEL, COLOUR_GREY),
00249 NWidget(NWID_HORIZONTAL), SetPadding(WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM, WD_FRAMERECT_LEFT),
00250 NWidget(NWID_VERTICAL),
00251 NWidget(WWT_TEXT, COLOUR_GREY), SetDataTip(STR_FINANCES_BANK_BALANCE_TITLE, STR_NULL), SetFill(1, 0),
00252 NWidget(WWT_TEXT, COLOUR_GREY), SetDataTip(STR_FINANCES_LOAN_TITLE, STR_NULL), SetFill(1, 0),
00253 NWidget(NWID_SPACER), SetFill(0, 1),
00254 EndContainer(),
00255 NWidget(NWID_SPACER), SetFill(0, 0), SetMinimalSize(30, 0),
00256 NWidget(NWID_VERTICAL),
00257 NWidget(WWT_TEXT, COLOUR_GREY, CFW_BALANCE_VALUE), SetDataTip(STR_NULL, STR_NULL),
00258 NWidget(WWT_TEXT, COLOUR_GREY, CFW_LOAN_VALUE), SetDataTip(STR_NULL, STR_NULL),
00259 NWidget(WWT_EMPTY, COLOUR_GREY, CFW_LOAN_LINE), SetMinimalSize(0, 2), SetFill(1, 0),
00260 NWidget(WWT_TEXT, COLOUR_GREY, CFW_TOTAL_VALUE), SetDataTip(STR_NULL, STR_NULL),
00261 EndContainer(),
00262 NWidget(NWID_SELECTION, INVALID_COLOUR, CFW_SEL_MAXLOAN),
00263 NWidget(NWID_HORIZONTAL),
00264 NWidget(NWID_SPACER), SetFill(0, 1), SetMinimalSize(25, 0),
00265 NWidget(NWID_VERTICAL),
00266 NWidget(WWT_EMPTY, COLOUR_GREY, CFW_MAXLOAN_GAP), SetFill(0, 0),
00267 NWidget(WWT_TEXT, COLOUR_GREY, CFW_MAXLOAN_VALUE), SetDataTip(STR_FINANCES_MAX_LOAN, STR_NULL),
00268 NWidget(NWID_SPACER), SetFill(0, 1),
00269 EndContainer(),
00270 EndContainer(),
00271 EndContainer(),
00272 NWidget(NWID_SPACER), SetFill(1, 1),
00273 EndContainer(),
00274 EndContainer(),
00275 NWidget(NWID_SELECTION, INVALID_COLOUR, CFW_SEL_BUTTONS),
00276 NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
00277 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, CFW_INCREASE_LOAN), SetFill(1, 0), SetDataTip(STR_FINANCES_BORROW_BUTTON, STR_FINANCES_BORROW_TOOLTIP),
00278 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, CFW_REPAY_LOAN), SetFill(1, 0), SetDataTip(STR_FINANCES_REPAY_BUTTON, STR_FINANCES_REPAY_TOOLTIP),
00279 EndContainer(),
00280 EndContainer(),
00281 };
00282
00286 struct CompanyFinancesWindow : Window {
00287 static Money max_money;
00288 bool small;
00289
00290 CompanyFinancesWindow(const WindowDesc *desc, CompanyID company) : Window()
00291 {
00292 this->small = false;
00293 this->CreateNestedTree(desc);
00294 this->SetupWidgets();
00295 this->FinishInitNested(desc, company);
00296
00297 this->owner = (Owner)this->window_number;
00298 }
00299
00300 virtual void SetStringParameters(int widget) const
00301 {
00302 switch (widget) {
00303 case CFW_CAPTION:
00304 SetDParam(0, (CompanyID)this->window_number);
00305 SetDParam(1, (CompanyID)this->window_number);
00306 break;
00307
00308 case CFW_MAXLOAN_VALUE:
00309 SetDParam(0, _economy.max_loan);
00310 break;
00311
00312 case CFW_INCREASE_LOAN:
00313 case CFW_REPAY_LOAN:
00314 SetDParam(0, LOAN_INTERVAL);
00315 break;
00316 }
00317 }
00318
00319 virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
00320 {
00321 int type = _settings_client.gui.expenses_layout;
00322 switch (widget) {
00323 case CFW_EXPS_CATEGORY:
00324 size->width = _expenses_list_types[type].GetCategoriesWidth();
00325 size->height = _expenses_list_types[type].GetHeight();
00326 break;
00327
00328 case CFW_EXPS_PRICE1:
00329 case CFW_EXPS_PRICE2:
00330 case CFW_EXPS_PRICE3:
00331 size->height = _expenses_list_types[type].GetHeight();
00332
00333 case CFW_BALANCE_VALUE:
00334 case CFW_LOAN_VALUE:
00335 case CFW_TOTAL_VALUE:
00336 SetDParam(0, CompanyFinancesWindow::max_money);
00337 size->width = max(GetStringBoundingBox(STR_FINANCES_NEGATIVE_INCOME).width, GetStringBoundingBox(STR_FINANCES_POSITIVE_INCOME).width) + padding.width;
00338 break;
00339
00340 case CFW_MAXLOAN_GAP:
00341 size->height = FONT_HEIGHT_NORMAL;
00342 break;
00343 }
00344 }
00345
00346 virtual void DrawWidget(const Rect &r, int widget) const
00347 {
00348 switch (widget) {
00349 case CFW_EXPS_CATEGORY:
00350 DrawCategories(r);
00351 break;
00352
00353 case CFW_EXPS_PRICE1:
00354 case CFW_EXPS_PRICE2:
00355 case CFW_EXPS_PRICE3: {
00356 const Company *c = Company::Get((CompanyID)this->window_number);
00357 int age = min(_cur_year - c->inaugurated_year, 2);
00358 int wid_offset = widget - CFW_EXPS_PRICE1;
00359 if (wid_offset <= age) {
00360 DrawYearColumn(r, _cur_year - (age - wid_offset), c->yearly_expenses + (age - wid_offset));
00361 }
00362 break;
00363 }
00364
00365 case CFW_BALANCE_VALUE: {
00366 const Company *c = Company::Get((CompanyID)this->window_number);
00367 SetDParam(0, c->money);
00368 DrawString(r.left, r.right, r.top, STR_FINANCES_TOTAL_CURRENCY, TC_FROMSTRING, SA_RIGHT);
00369 break;
00370 }
00371
00372 case CFW_LOAN_VALUE: {
00373 const Company *c = Company::Get((CompanyID)this->window_number);
00374 SetDParam(0, c->current_loan);
00375 DrawString(r.left, r.right, r.top, STR_FINANCES_TOTAL_CURRENCY, TC_FROMSTRING, SA_RIGHT);
00376 break;
00377 }
00378
00379 case CFW_TOTAL_VALUE: {
00380 const Company *c = Company::Get((CompanyID)this->window_number);
00381 SetDParam(0, c->money - c->current_loan);
00382 DrawString(r.left, r.right, r.top, STR_FINANCES_TOTAL_CURRENCY, TC_FROMSTRING, SA_RIGHT);
00383 break;
00384 }
00385
00386 case CFW_LOAN_LINE:
00387 GfxFillRect(r.left, r.top, r.right, r.top, 215);
00388 break;
00389 }
00390 }
00391
00395 void SetupWidgets()
00396 {
00397 int plane = this->small ? SZSP_NONE : 0;
00398 this->GetWidget<NWidgetStacked>(CFW_SEL_PANEL)->SetDisplayedPlane(plane);
00399 this->GetWidget<NWidgetStacked>(CFW_SEL_MAXLOAN)->SetDisplayedPlane(plane);
00400
00401 CompanyID company = (CompanyID)this->window_number;
00402 plane = (company != _local_company) ? SZSP_NONE : 0;
00403 this->GetWidget<NWidgetStacked>(CFW_SEL_BUTTONS)->SetDisplayedPlane(plane);
00404 }
00405
00406 virtual void OnPaint()
00407 {
00408 if (!this->IsShaded()) {
00409 if (!this->small) {
00410
00411 int type = _settings_client.gui.expenses_layout;
00412 if (_expenses_list_types[type].GetHeight() != this->GetWidget<NWidgetBase>(CFW_EXPS_CATEGORY)->current_y) {
00413 this->SetupWidgets();
00414 this->ReInit();
00415 return;
00416 }
00417 }
00418
00419
00420 CompanyID company = (CompanyID)this->window_number;
00421 int req_plane = (company != _local_company) ? SZSP_NONE : 0;
00422 if (req_plane != this->GetWidget<NWidgetStacked>(CFW_SEL_BUTTONS)->shown_plane) {
00423 this->SetupWidgets();
00424 this->ReInit();
00425 return;
00426 }
00427
00428 const Company *c = Company::Get(company);
00429 this->SetWidgetDisabledState(CFW_INCREASE_LOAN, c->current_loan == _economy.max_loan);
00430 this->SetWidgetDisabledState(CFW_REPAY_LOAN, company != _local_company || c->current_loan == 0);
00431 }
00432
00433 this->DrawWidgets();
00434 }
00435
00436 virtual void OnClick(Point pt, int widget, int click_count)
00437 {
00438 switch (widget) {
00439 case CFW_TOGGLE_SIZE:
00440 this->small = !this->small;
00441 this->SetupWidgets();
00442 if (this->IsShaded()) {
00443
00444
00445 this->SetShaded(false);
00446 } else {
00447 this->ReInit();
00448 }
00449 break;
00450
00451 case CFW_INCREASE_LOAN:
00452 DoCommandP(0, 0, _ctrl_pressed, CMD_INCREASE_LOAN | CMD_MSG(STR_ERROR_CAN_T_BORROW_ANY_MORE_MONEY));
00453 break;
00454
00455 case CFW_REPAY_LOAN:
00456 DoCommandP(0, 0, _ctrl_pressed, CMD_DECREASE_LOAN | CMD_MSG(STR_ERROR_CAN_T_REPAY_LOAN));
00457 break;
00458 }
00459 }
00460
00461 virtual void OnHundredthTick()
00462 {
00463 const Company *c = Company::Get((CompanyID)this->window_number);
00464 if (c->money > CompanyFinancesWindow::max_money) {
00465 CompanyFinancesWindow::max_money = max(c->money * 2, CompanyFinancesWindow::max_money * 4);
00466 this->SetupWidgets();
00467 this->ReInit();
00468 }
00469 }
00470 };
00471
00473 Money CompanyFinancesWindow::max_money = INT32_MAX;
00474
00475 static const WindowDesc _company_finances_desc(
00476 WDP_AUTO, 0, 0,
00477 WC_FINANCES, WC_NONE,
00478 WDF_UNCLICK_BUTTONS,
00479 _nested_company_finances_widgets, lengthof(_nested_company_finances_widgets)
00480 );
00481
00486 void ShowCompanyFinances(CompanyID company)
00487 {
00488 if (!Company::IsValidID(company)) return;
00489 if (BringWindowToFrontById(WC_FINANCES, company)) return;
00490
00491 new CompanyFinancesWindow(&_company_finances_desc, company);
00492 }
00493
00494
00495 static const StringID _colour_dropdown[] = {
00496 STR_COLOUR_DARK_BLUE,
00497 STR_COLOUR_PALE_GREEN,
00498 STR_COLOUR_PINK,
00499 STR_COLOUR_YELLOW,
00500 STR_COLOUR_RED,
00501 STR_COLOUR_LIGHT_BLUE,
00502 STR_COLOUR_GREEN,
00503 STR_COLOUR_DARK_GREEN,
00504 STR_COLOUR_BLUE,
00505 STR_COLOUR_CREAM,
00506 STR_COLOUR_MAUVE,
00507 STR_COLOUR_PURPLE,
00508 STR_COLOUR_ORANGE,
00509 STR_COLOUR_BROWN,
00510 STR_COLOUR_GREY,
00511 STR_COLOUR_WHITE,
00512 };
00513
00514
00515 static const LiveryClass _livery_class[LS_END] = {
00516 LC_OTHER,
00517 LC_RAIL, LC_RAIL, LC_RAIL, LC_RAIL, LC_RAIL, LC_RAIL, LC_RAIL, LC_RAIL, LC_RAIL, LC_RAIL, LC_RAIL, LC_RAIL, LC_RAIL,
00518 LC_ROAD, LC_ROAD,
00519 LC_SHIP, LC_SHIP,
00520 LC_AIRCRAFT, LC_AIRCRAFT, LC_AIRCRAFT,
00521 LC_ROAD, LC_ROAD,
00522 };
00523
00524 class DropDownListColourItem : public DropDownListItem {
00525 public:
00526 DropDownListColourItem(int result, bool masked) : DropDownListItem(result, masked) {}
00527
00528 virtual ~DropDownListColourItem() {}
00529
00530 StringID String() const
00531 {
00532 return _colour_dropdown[this->result];
00533 }
00534
00535 uint Height(uint width) const
00536 {
00537 return max(FONT_HEIGHT_NORMAL, (byte)14);
00538 }
00539
00540 bool Selectable() const
00541 {
00542 return true;
00543 }
00544
00545 void Draw(int left, int right, int top, int bottom, bool sel, int bg_colour) const
00546 {
00547 bool rtl = _dynlang.text_dir == TD_RTL;
00548 DrawSprite(SPR_VEH_BUS_SIDE_VIEW, PALETTE_RECOLOUR_START + this->result, rtl ? right - 16 : left + 16, top + 7);
00549 DrawString(rtl ? left + 2 : left + 32, rtl ? right - 32 : right - 2, top + max(0, 13 - FONT_HEIGHT_NORMAL), this->String(), sel ? TC_WHITE : TC_BLACK);
00550 }
00551 };
00552
00554 enum SelectCompanyLiveryWindowWidgets {
00555 SCLW_WIDGET_CAPTION,
00556 SCLW_WIDGET_CLASS_GENERAL,
00557 SCLW_WIDGET_CLASS_RAIL,
00558 SCLW_WIDGET_CLASS_ROAD,
00559 SCLW_WIDGET_CLASS_SHIP,
00560 SCLW_WIDGET_CLASS_AIRCRAFT,
00561 SCLW_WIDGET_SPACER_DROPDOWN,
00562 SCLW_WIDGET_PRI_COL_DROPDOWN,
00563 SCLW_WIDGET_SEC_COL_DROPDOWN,
00564 SCLW_WIDGET_MATRIX,
00565 };
00566
00568 struct SelectCompanyLiveryWindow : public Window {
00569 private:
00570 static const uint TEXT_INDENT = 15;
00571 uint32 sel;
00572 LiveryClass livery_class;
00573
00574 void ShowColourDropDownMenu(uint32 widget)
00575 {
00576 uint32 used_colours = 0;
00577 const Livery *livery;
00578 LiveryScheme scheme;
00579
00580
00581 if (HasBit(this->sel, LS_DEFAULT) && widget == SCLW_WIDGET_PRI_COL_DROPDOWN) {
00582 const Company *c;
00583 FOR_ALL_COMPANIES(c) {
00584 if (c->index != _local_company) SetBit(used_colours, c->colour);
00585 }
00586 }
00587
00588
00589 for (scheme = LS_BEGIN; scheme < LS_END; scheme++) {
00590 if (HasBit(this->sel, scheme)) break;
00591 }
00592 if (scheme == LS_END) scheme = LS_DEFAULT;
00593 livery = &Company::Get((CompanyID)this->window_number)->livery[scheme];
00594
00595 DropDownList *list = new DropDownList();
00596 for (uint i = 0; i < lengthof(_colour_dropdown); i++) {
00597 list->push_back(new DropDownListColourItem(i, HasBit(used_colours, i)));
00598 }
00599
00600 ShowDropDownList(this, list, widget == SCLW_WIDGET_PRI_COL_DROPDOWN ? livery->colour1 : livery->colour2, widget);
00601 }
00602
00603 public:
00604 SelectCompanyLiveryWindow(const WindowDesc *desc, CompanyID company) : Window()
00605 {
00606 this->livery_class = LC_OTHER;
00607 this->sel = 1;
00608 this->InitNested(desc, company);
00609 this->owner = company;
00610 this->LowerWidget(SCLW_WIDGET_CLASS_GENERAL);
00611 }
00612
00613 virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
00614 {
00615
00616 static const byte livery_height[] = {
00617 1,
00618 13,
00619 4,
00620 2,
00621 3,
00622 };
00623
00624 switch (widget) {
00625 case SCLW_WIDGET_SPACER_DROPDOWN: {
00626
00627 Dimension d = {0, 0};
00628 for (LiveryScheme scheme = LS_DEFAULT; scheme < LS_END; scheme++) {
00629 d = maxdim(d, GetStringBoundingBox(STR_LIVERY_DEFAULT + scheme));
00630 }
00631 size->width = max(size->width, TEXT_INDENT + d.width + WD_FRAMERECT_RIGHT);
00632 break;
00633 }
00634
00635 case SCLW_WIDGET_MATRIX:
00636 size->height = livery_height[this->livery_class] * (4 + FONT_HEIGHT_NORMAL);
00637 this->GetWidget<NWidgetCore>(SCLW_WIDGET_MATRIX)->widget_data = (livery_height[this->livery_class] << MAT_ROW_START) | (1 << MAT_COL_START);
00638 break;
00639
00640 case SCLW_WIDGET_SEC_COL_DROPDOWN:
00641 if (!_loaded_newgrf_features.has_2CC) {
00642 size->width = 0;
00643 break;
00644 }
00645
00646 case SCLW_WIDGET_PRI_COL_DROPDOWN: {
00647 for (const StringID *id = _colour_dropdown; id != endof(_colour_dropdown); id++) {
00648 size->width = max(size->width, GetStringBoundingBox(*id).width + 34);
00649 }
00650 } break;
00651 }
00652 }
00653
00654 virtual void OnPaint()
00655 {
00656
00657 this->SetWidgetDisabledState(SCLW_WIDGET_PRI_COL_DROPDOWN, this->sel == 0);
00658 this->SetWidgetDisabledState(SCLW_WIDGET_SEC_COL_DROPDOWN, this->sel == 0);
00659
00660 this->DrawWidgets();
00661 }
00662
00663 virtual void SetStringParameters(int widget) const
00664 {
00665 switch (widget) {
00666 case SCLW_WIDGET_PRI_COL_DROPDOWN:
00667 case SCLW_WIDGET_SEC_COL_DROPDOWN: {
00668 const Company *c = Company::Get((CompanyID)this->window_number);
00669 LiveryScheme scheme = LS_DEFAULT;
00670
00671 if (this->sel != 0) {
00672 for (scheme = LS_BEGIN; scheme < LS_END; scheme++) {
00673 if (HasBit(this->sel, scheme)) break;
00674 }
00675 if (scheme == LS_END) scheme = LS_DEFAULT;
00676 }
00677 SetDParam(0, STR_COLOUR_DARK_BLUE + ((widget == SCLW_WIDGET_PRI_COL_DROPDOWN) ? c->livery[scheme].colour1 : c->livery[scheme].colour2));
00678 break;
00679 }
00680 }
00681 }
00682
00683 virtual void DrawWidget(const Rect &r, int widget) const
00684 {
00685 if (widget != SCLW_WIDGET_MATRIX) return;
00686
00687 bool rtl = _dynlang.text_dir == TD_RTL;
00688
00689
00690 const NWidgetBase *nwi = this->GetWidget<NWidgetBase>(SCLW_WIDGET_SPACER_DROPDOWN);
00691 int sch_left = nwi->pos_x;
00692 int sch_right = sch_left + nwi->current_x - 1;
00693
00694 nwi = this->GetWidget<NWidgetBase>(SCLW_WIDGET_PRI_COL_DROPDOWN);
00695 int pri_left = nwi->pos_x;
00696 int pri_right = pri_left + nwi->current_x - 1;
00697
00698 nwi = this->GetWidget<NWidgetBase>(SCLW_WIDGET_SEC_COL_DROPDOWN);
00699 int sec_left = nwi->pos_x;
00700 int sec_right = sec_left + nwi->current_x - 1;
00701
00702 int text_left = (rtl ? (uint)WD_FRAMERECT_LEFT : TEXT_INDENT);
00703 int text_right = (rtl ? TEXT_INDENT : (uint)WD_FRAMERECT_RIGHT);
00704
00705 int y = r.top + 3;
00706 const Company *c = Company::Get((CompanyID)this->window_number);
00707 for (LiveryScheme scheme = LS_DEFAULT; scheme < LS_END; scheme++) {
00708 if (_livery_class[scheme] == this->livery_class) {
00709 bool sel = HasBit(this->sel, scheme) != 0;
00710
00711
00712 if (scheme != LS_DEFAULT) {
00713 DrawSprite(c->livery[scheme].in_use ? SPR_BOX_CHECKED : SPR_BOX_EMPTY, PAL_NONE, (rtl ? sch_right - TEXT_INDENT + WD_FRAMERECT_RIGHT : sch_left) + WD_FRAMERECT_LEFT, y);
00714 }
00715 DrawString(sch_left + text_left, sch_right - text_right, y, STR_LIVERY_DEFAULT + scheme, sel ? TC_WHITE : TC_BLACK);
00716
00717
00718 DrawSprite(SPR_SQUARE, GENERAL_SPRITE_COLOUR(c->livery[scheme].colour1), (rtl ? pri_right - TEXT_INDENT + WD_FRAMERECT_RIGHT : pri_left) + WD_FRAMERECT_LEFT, y);
00719 DrawString(pri_left + text_left, pri_right - text_right, y, STR_COLOUR_DARK_BLUE + c->livery[scheme].colour1, sel ? TC_WHITE : TC_GOLD);
00720
00721
00722 if (sec_right > sec_left) {
00723 DrawSprite(SPR_SQUARE, GENERAL_SPRITE_COLOUR(c->livery[scheme].colour2), (rtl ? sec_right - TEXT_INDENT + WD_FRAMERECT_RIGHT : sec_left) + WD_FRAMERECT_LEFT, y);
00724 DrawString(sec_left + text_left, sec_right - text_right, y, STR_COLOUR_DARK_BLUE + c->livery[scheme].colour2, sel ? TC_WHITE : TC_GOLD);
00725 }
00726
00727 y += 4 + FONT_HEIGHT_NORMAL;
00728 }
00729 }
00730 }
00731
00732 virtual void OnClick(Point pt, int widget, int click_count)
00733 {
00734 switch (widget) {
00735
00736 case SCLW_WIDGET_CLASS_GENERAL:
00737 case SCLW_WIDGET_CLASS_RAIL:
00738 case SCLW_WIDGET_CLASS_ROAD:
00739 case SCLW_WIDGET_CLASS_SHIP:
00740 case SCLW_WIDGET_CLASS_AIRCRAFT:
00741 this->RaiseWidget(this->livery_class + SCLW_WIDGET_CLASS_GENERAL);
00742 this->livery_class = (LiveryClass)(widget - SCLW_WIDGET_CLASS_GENERAL);
00743 this->LowerWidget(this->livery_class + SCLW_WIDGET_CLASS_GENERAL);
00744
00745
00746 this->sel = 0;
00747 for (LiveryScheme scheme = LS_DEFAULT; scheme < LS_END; scheme++) {
00748 if (_livery_class[scheme] == this->livery_class) {
00749 this->sel = 1 << scheme;
00750 break;
00751 }
00752 }
00753
00754 this->ReInit();
00755 break;
00756
00757 case SCLW_WIDGET_PRI_COL_DROPDOWN:
00758 ShowColourDropDownMenu(SCLW_WIDGET_PRI_COL_DROPDOWN);
00759 break;
00760
00761 case SCLW_WIDGET_SEC_COL_DROPDOWN:
00762 ShowColourDropDownMenu(SCLW_WIDGET_SEC_COL_DROPDOWN);
00763 break;
00764
00765 case SCLW_WIDGET_MATRIX: {
00766 const NWidgetBase *wid = this->GetWidget<NWidgetBase>(SCLW_WIDGET_MATRIX);
00767 LiveryScheme j = (LiveryScheme)((pt.y - wid->pos_y) / (4 + FONT_HEIGHT_NORMAL));
00768
00769 for (LiveryScheme scheme = LS_BEGIN; scheme <= j; scheme++) {
00770 if (_livery_class[scheme] != this->livery_class) j++;
00771 if (scheme >= LS_END) return;
00772 }
00773 if (j >= LS_END) return;
00774
00775
00776 if (_dynlang.text_dir == TD_RTL ? pt.x - wid->pos_x > wid->current_x - TEXT_INDENT : pt.x - wid->pos_x < TEXT_INDENT) {
00777 DoCommandP(0, j | (2 << 8), !Company::Get((CompanyID)this->window_number)->livery[j].in_use, CMD_SET_COMPANY_COLOUR);
00778 }
00779
00780 if (_ctrl_pressed) {
00781 ToggleBit(this->sel, j);
00782 } else {
00783 this->sel = 1 << j;
00784 }
00785 this->SetDirty();
00786 break;
00787 }
00788 }
00789 }
00790
00791 virtual void OnDropdownSelect(int widget, int index)
00792 {
00793 for (LiveryScheme scheme = LS_DEFAULT; scheme < LS_END; scheme++) {
00794 if (HasBit(this->sel, scheme)) {
00795 DoCommandP(0, scheme | (widget == SCLW_WIDGET_PRI_COL_DROPDOWN ? 0 : 256), index, CMD_SET_COMPANY_COLOUR);
00796 }
00797 }
00798 }
00799
00800 virtual void OnInvalidateData(int data = 0)
00801 {
00802 this->ReInit();
00803 }
00804 };
00805
00806 static const NWidgetPart _nested_select_company_livery_widgets [] = {
00807 NWidget(NWID_HORIZONTAL),
00808 NWidget(WWT_CLOSEBOX, COLOUR_GREY),
00809 NWidget(WWT_CAPTION, COLOUR_GREY, SCLW_WIDGET_CAPTION), SetDataTip(STR_LIVERY_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
00810 EndContainer(),
00811 NWidget(NWID_HORIZONTAL),
00812 NWidget(WWT_IMGBTN, COLOUR_GREY, SCLW_WIDGET_CLASS_GENERAL), SetMinimalSize(22, 22), SetFill(0, 1), SetDataTip(SPR_IMG_COMPANY_GENERAL, STR_LIVERY_GENERAL_TOOLTIP),
00813 NWidget(WWT_IMGBTN, COLOUR_GREY, SCLW_WIDGET_CLASS_RAIL), SetMinimalSize(22, 22), SetFill(0, 1), SetDataTip(SPR_IMG_TRAINLIST, STR_LIVERY_TRAIN_TOOLTIP),
00814 NWidget(WWT_IMGBTN, COLOUR_GREY, SCLW_WIDGET_CLASS_ROAD), SetMinimalSize(22, 22), SetFill(0, 1), SetDataTip(SPR_IMG_TRUCKLIST, STR_LIVERY_ROAD_VEHICLE_TOOLTIP),
00815 NWidget(WWT_IMGBTN, COLOUR_GREY, SCLW_WIDGET_CLASS_SHIP), SetMinimalSize(22, 22), SetFill(0, 1), SetDataTip(SPR_IMG_SHIPLIST, STR_LIVERY_SHIP_TOOLTIP),
00816 NWidget(WWT_IMGBTN, COLOUR_GREY, SCLW_WIDGET_CLASS_AIRCRAFT), SetMinimalSize(22, 22), SetFill(0, 1), SetDataTip(SPR_IMG_AIRPLANESLIST, STR_LIVERY_AIRCRAFT_TOOLTIP),
00817 NWidget(WWT_PANEL, COLOUR_GREY), SetMinimalSize(90, 22), SetFill(1, 1), EndContainer(),
00818 EndContainer(),
00819 NWidget(NWID_HORIZONTAL),
00820 NWidget(WWT_PANEL, COLOUR_GREY, SCLW_WIDGET_SPACER_DROPDOWN), SetMinimalSize(150, 12), SetFill(1, 1), EndContainer(),
00821 NWidget(WWT_DROPDOWN, COLOUR_GREY, SCLW_WIDGET_PRI_COL_DROPDOWN), SetMinimalSize(125, 12), SetFill(0, 1), SetDataTip(STR_BLACK_STRING, STR_LIVERY_PRIMARY_TOOLTIP),
00822 NWidget(WWT_DROPDOWN, COLOUR_GREY, SCLW_WIDGET_SEC_COL_DROPDOWN), SetMinimalSize(125, 12), SetFill(0, 1),
00823 SetDataTip(STR_BLACK_STRING, STR_LIVERY_SECONDARY_TOOLTIP),
00824 EndContainer(),
00825 NWidget(WWT_MATRIX, COLOUR_GREY, SCLW_WIDGET_MATRIX), SetMinimalSize(275, 15), SetFill(1, 0), SetDataTip((1 << MAT_ROW_START) | (1 << MAT_COL_START), STR_LIVERY_PANEL_TOOLTIP),
00826 };
00827
00828 static const WindowDesc _select_company_livery_desc(
00829 WDP_AUTO, 0, 0,
00830 WC_COMPANY_COLOUR, WC_NONE,
00831 0,
00832 _nested_select_company_livery_widgets, lengthof(_nested_select_company_livery_widgets)
00833 );
00834
00842 void DrawCompanyManagerFace(CompanyManagerFace cmf, int colour, int x, int y)
00843 {
00844 GenderEthnicity ge = (GenderEthnicity)GetCompanyManagerFaceBits(cmf, CMFV_GEN_ETHN, GE_WM);
00845
00846 bool has_moustache = !HasBit(ge, GENDER_FEMALE) && GetCompanyManagerFaceBits(cmf, CMFV_HAS_MOUSTACHE, ge) != 0;
00847 bool has_tie_earring = !HasBit(ge, GENDER_FEMALE) || GetCompanyManagerFaceBits(cmf, CMFV_HAS_TIE_EARRING, ge) != 0;
00848 bool has_glasses = GetCompanyManagerFaceBits(cmf, CMFV_HAS_GLASSES, ge) != 0;
00849 PaletteID pal;
00850
00851
00852 if (_cmf_info[CMFV_EYE_COLOUR].valid_values[ge] < 2) {
00853 pal = PAL_NONE;
00854 } else {
00855 switch (GetCompanyManagerFaceBits(cmf, CMFV_EYE_COLOUR, ge)) {
00856 default: NOT_REACHED();
00857 case 0: pal = PALETTE_TO_BROWN; break;
00858 case 1: pal = PALETTE_TO_BLUE; break;
00859 case 2: pal = PALETTE_TO_GREEN; break;
00860 }
00861 }
00862
00863
00864 DrawSprite(SPR_GRADIENT, GENERAL_SPRITE_COLOUR(colour), x, y);
00865
00866 for (CompanyManagerFaceVariable cmfv = CMFV_CHEEKS; cmfv < CMFV_END; cmfv++) {
00867 switch (cmfv) {
00868 case CMFV_MOUSTACHE: if (!has_moustache) continue; break;
00869 case CMFV_LIPS:
00870 case CMFV_NOSE: if (has_moustache) continue; break;
00871 case CMFV_TIE_EARRING: if (!has_tie_earring) continue; break;
00872 case CMFV_GLASSES: if (!has_glasses) continue; break;
00873 default: break;
00874 }
00875 DrawSprite(GetCompanyManagerFaceSprite(cmf, cmfv, ge), (cmfv == CMFV_EYEBROWS) ? pal : PAL_NONE, x, y);
00876 }
00877 }
00878
00884 enum SelectCompanyManagerFaceWidgets {
00885 SCMFW_WIDGET_CAPTION,
00886 SCMFW_WIDGET_TOGGLE_LARGE_SMALL,
00887 SCMFW_WIDGET_SELECT_FACE,
00888 SCMFW_WIDGET_CANCEL,
00889 SCMFW_WIDGET_ACCEPT,
00890 SCMFW_WIDGET_MALE,
00891 SCMFW_WIDGET_FEMALE,
00892 SCMFW_WIDGET_MALE2,
00893 SCMFW_WIDGET_FEMALE2,
00894 SCMFW_WIDGET_SEL_LOADSAVE,
00895 SCMFW_WIDGET_SEL_MALEFEMALE,
00896 SCMFW_WIDGET_SEL_PARTS,
00897 SCMFW_WIDGET_RANDOM_NEW_FACE,
00898 SCMFW_WIDGET_TOGGLE_LARGE_SMALL_BUTTON,
00899 SCMFM_WIDGET_FACE,
00900 SCMFW_WIDGET_LOAD,
00901 SCMFW_WIDGET_FACECODE,
00902 SCMFW_WIDGET_SAVE,
00903 SCMFW_WIDGET_HAS_MOUSTACHE_EARRING_TEXT,
00904 SCMFW_WIDGET_TIE_EARRING_TEXT,
00905 SCMFW_WIDGET_LIPS_MOUSTACHE_TEXT,
00906 SCMFW_WIDGET_HAS_GLASSES_TEXT,
00907 SCMFW_WIDGET_HAIR_TEXT,
00908 SCMFW_WIDGET_EYEBROWS_TEXT,
00909 SCMFW_WIDGET_EYECOLOUR_TEXT,
00910 SCMFW_WIDGET_GLASSES_TEXT,
00911 SCMFW_WIDGET_NOSE_TEXT,
00912 SCMFW_WIDGET_CHIN_TEXT,
00913 SCMFW_WIDGET_JACKET_TEXT,
00914 SCMFW_WIDGET_COLLAR_TEXT,
00915 SCMFW_WIDGET_ETHNICITY_EUR,
00916 SCMFW_WIDGET_ETHNICITY_AFR,
00917 SCMFW_WIDGET_HAS_MOUSTACHE_EARRING,
00918 SCMFW_WIDGET_HAS_GLASSES,
00919 SCMFW_WIDGET_EYECOLOUR_L,
00920 SCMFW_WIDGET_EYECOLOUR,
00921 SCMFW_WIDGET_EYECOLOUR_R,
00922 SCMFW_WIDGET_CHIN_L,
00923 SCMFW_WIDGET_CHIN,
00924 SCMFW_WIDGET_CHIN_R,
00925 SCMFW_WIDGET_EYEBROWS_L,
00926 SCMFW_WIDGET_EYEBROWS,
00927 SCMFW_WIDGET_EYEBROWS_R,
00928 SCMFW_WIDGET_LIPS_MOUSTACHE_L,
00929 SCMFW_WIDGET_LIPS_MOUSTACHE,
00930 SCMFW_WIDGET_LIPS_MOUSTACHE_R,
00931 SCMFW_WIDGET_NOSE_L,
00932 SCMFW_WIDGET_NOSE,
00933 SCMFW_WIDGET_NOSE_R,
00934 SCMFW_WIDGET_HAIR_L,
00935 SCMFW_WIDGET_HAIR,
00936 SCMFW_WIDGET_HAIR_R,
00937 SCMFW_WIDGET_JACKET_L,
00938 SCMFW_WIDGET_JACKET,
00939 SCMFW_WIDGET_JACKET_R,
00940 SCMFW_WIDGET_COLLAR_L,
00941 SCMFW_WIDGET_COLLAR,
00942 SCMFW_WIDGET_COLLAR_R,
00943 SCMFW_WIDGET_TIE_EARRING_L,
00944 SCMFW_WIDGET_TIE_EARRING,
00945 SCMFW_WIDGET_TIE_EARRING_R,
00946 SCMFW_WIDGET_GLASSES_L,
00947 SCMFW_WIDGET_GLASSES,
00948 SCMFW_WIDGET_GLASSES_R,
00949 };
00950
00952 static const NWidgetPart _nested_select_company_manager_face_widgets[] = {
00953 NWidget(NWID_HORIZONTAL),
00954 NWidget(WWT_CLOSEBOX, COLOUR_GREY),
00955 NWidget(WWT_CAPTION, COLOUR_GREY, SCMFW_WIDGET_CAPTION), SetDataTip(STR_FACE_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
00956 NWidget(WWT_IMGBTN, COLOUR_GREY, SCMFW_WIDGET_TOGGLE_LARGE_SMALL), SetDataTip(SPR_LARGE_SMALL_WINDOW, STR_FACE_ADVANCED_TOOLTIP),
00957 EndContainer(),
00958 NWidget(WWT_PANEL, COLOUR_GREY, SCMFW_WIDGET_SELECT_FACE),
00959 NWidget(NWID_SPACER), SetMinimalSize(0, 2),
00960 NWidget(NWID_HORIZONTAL), SetPIP(2, 2, 2),
00961 NWidget(NWID_VERTICAL),
00962 NWidget(NWID_HORIZONTAL),
00963 NWidget(NWID_SPACER), SetFill(1, 0),
00964 NWidget(WWT_EMPTY, COLOUR_GREY, SCMFM_WIDGET_FACE), SetMinimalSize(92, 119),
00965 NWidget(NWID_SPACER), SetFill(1, 0),
00966 EndContainer(),
00967 NWidget(NWID_SPACER), SetMinimalSize(0, 2),
00968 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, SCMFW_WIDGET_RANDOM_NEW_FACE), SetFill(1, 0), SetDataTip(STR_FACE_NEW_FACE_BUTTON, STR_FACE_NEW_FACE_TOOLTIP),
00969 NWidget(NWID_SELECTION, INVALID_COLOUR, SCMFW_WIDGET_SEL_LOADSAVE),
00970 NWidget(NWID_VERTICAL),
00971 NWidget(NWID_SPACER), SetMinimalSize(0, 5), SetFill(0, 1),
00972 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, SCMFW_WIDGET_LOAD), SetFill(1, 0), SetDataTip(STR_FACE_LOAD, STR_FACE_LOAD_TOOLTIP),
00973 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, SCMFW_WIDGET_FACECODE), SetFill(1, 0), SetDataTip(STR_FACE_FACECODE, STR_FACE_FACECODE_TOOLTIP),
00974 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, SCMFW_WIDGET_SAVE), SetFill(1, 0), SetDataTip(STR_FACE_SAVE, STR_FACE_SAVE_TOOLTIP),
00975 NWidget(NWID_SPACER), SetMinimalSize(0, 5), SetFill(0, 1),
00976 EndContainer(),
00977 EndContainer(),
00978 EndContainer(),
00979 NWidget(NWID_VERTICAL),
00980 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, SCMFW_WIDGET_TOGGLE_LARGE_SMALL_BUTTON), SetFill(1, 0), SetDataTip(STR_FACE_ADVANCED, STR_FACE_ADVANCED_TOOLTIP),
00981 NWidget(NWID_SPACER), SetMinimalSize(0, 2),
00982 NWidget(NWID_SELECTION, INVALID_COLOUR, SCMFW_WIDGET_SEL_MALEFEMALE),
00983 NWidget(NWID_VERTICAL),
00984 NWidget(NWID_SPACER), SetFill(0, 1),
00985 NWidget(WWT_TEXTBTN, COLOUR_GREY, SCMFW_WIDGET_MALE), SetFill(1, 0), SetDataTip(STR_FACE_MALE_BUTTON, STR_FACE_MALE_TOOLTIP),
00986 NWidget(WWT_TEXTBTN, COLOUR_GREY, SCMFW_WIDGET_FEMALE), SetFill(1, 0), SetDataTip(STR_FACE_FEMALE_BUTTON, STR_FACE_FEMALE_TOOLTIP),
00987 NWidget(NWID_SPACER), SetFill(0, 1),
00988 EndContainer(),
00989 EndContainer(),
00990 NWidget(NWID_SELECTION, INVALID_COLOUR, SCMFW_WIDGET_SEL_PARTS),
00991 NWidget(NWID_VERTICAL),
00992 NWidget(NWID_SPACER), SetMinimalSize(0, 2),
00993 NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
00994 NWidget(WWT_TEXTBTN, COLOUR_GREY, SCMFW_WIDGET_MALE2), SetFill(1, 0), SetDataTip(STR_FACE_MALE_BUTTON, STR_FACE_MALE_TOOLTIP),
00995 NWidget(WWT_TEXTBTN, COLOUR_GREY, SCMFW_WIDGET_FEMALE2), SetFill(1, 0), SetDataTip(STR_FACE_FEMALE_BUTTON, STR_FACE_FEMALE_TOOLTIP),
00996 EndContainer(),
00997 NWidget(NWID_SPACER), SetMinimalSize(0, 2),
00998 NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
00999 NWidget(WWT_TEXTBTN, COLOUR_GREY, SCMFW_WIDGET_ETHNICITY_EUR), SetFill(1, 0), SetDataTip(STR_FACE_EUROPEAN, STR_FACE_SELECT_EUROPEAN),
01000 NWidget(WWT_TEXTBTN, COLOUR_GREY, SCMFW_WIDGET_ETHNICITY_AFR), SetFill(1, 0), SetDataTip(STR_FACE_AFRICAN, STR_FACE_SELECT_AFRICAN),
01001 EndContainer(),
01002 NWidget(NWID_SPACER), SetMinimalSize(0, 4),
01003 NWidget(NWID_HORIZONTAL),
01004 NWidget(WWT_EMPTY, INVALID_COLOUR, SCMFW_WIDGET_HAS_MOUSTACHE_EARRING_TEXT), SetFill(1, 0),
01005 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, SCMFW_WIDGET_HAS_MOUSTACHE_EARRING), SetDataTip(STR_EMPTY, STR_FACE_MOUSTACHE_EARRING_TOOLTIP),
01006 EndContainer(),
01007 NWidget(NWID_HORIZONTAL),
01008 NWidget(WWT_EMPTY, INVALID_COLOUR, SCMFW_WIDGET_HAS_GLASSES_TEXT), SetFill(1, 0),
01009 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, SCMFW_WIDGET_HAS_GLASSES), SetDataTip(STR_EMPTY, STR_FACE_GLASSES_TOOLTIP),
01010 EndContainer(),
01011 NWidget(NWID_SPACER), SetMinimalSize(0, 2), SetFill(1, 0),
01012 NWidget(NWID_HORIZONTAL),
01013 NWidget(WWT_EMPTY, INVALID_COLOUR, SCMFW_WIDGET_HAIR_TEXT), SetFill(1, 0),
01014 NWidget(NWID_BUTTON_ARROW, COLOUR_GREY, SCMFW_WIDGET_HAIR_L), SetDataTip(AWV_DECREASE, STR_FACE_HAIR_TOOLTIP),
01015 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, SCMFW_WIDGET_HAIR), SetDataTip(STR_EMPTY, STR_FACE_HAIR_TOOLTIP),
01016 NWidget(NWID_BUTTON_ARROW, COLOUR_GREY, SCMFW_WIDGET_HAIR_R), SetDataTip(AWV_INCREASE, STR_FACE_HAIR_TOOLTIP),
01017 EndContainer(),
01018 NWidget(NWID_HORIZONTAL),
01019 NWidget(WWT_EMPTY, INVALID_COLOUR, SCMFW_WIDGET_EYEBROWS_TEXT), SetFill(1, 0),
01020 NWidget(NWID_BUTTON_ARROW, COLOUR_GREY, SCMFW_WIDGET_EYEBROWS_L), SetDataTip(AWV_DECREASE, STR_FACE_EYEBROWS_TOOLTIP),
01021 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, SCMFW_WIDGET_EYEBROWS), SetDataTip(STR_EMPTY, STR_FACE_EYEBROWS_TOOLTIP),
01022 NWidget(NWID_BUTTON_ARROW, COLOUR_GREY, SCMFW_WIDGET_EYEBROWS_R), SetDataTip(AWV_INCREASE, STR_FACE_EYEBROWS_TOOLTIP),
01023 EndContainer(),
01024 NWidget(NWID_HORIZONTAL),
01025 NWidget(WWT_EMPTY, INVALID_COLOUR, SCMFW_WIDGET_EYECOLOUR_TEXT), SetFill(1, 0),
01026 NWidget(NWID_BUTTON_ARROW, COLOUR_GREY, SCMFW_WIDGET_EYECOLOUR_L), SetDataTip(AWV_DECREASE, STR_FACE_EYECOLOUR_TOOLTIP),
01027 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, SCMFW_WIDGET_EYECOLOUR), SetDataTip(STR_EMPTY, STR_FACE_EYECOLOUR_TOOLTIP),
01028 NWidget(NWID_BUTTON_ARROW, COLOUR_GREY, SCMFW_WIDGET_EYECOLOUR_R), SetDataTip(AWV_INCREASE, STR_FACE_EYECOLOUR_TOOLTIP),
01029 EndContainer(),
01030 NWidget(NWID_HORIZONTAL),
01031 NWidget(WWT_EMPTY, INVALID_COLOUR, SCMFW_WIDGET_GLASSES_TEXT), SetFill(1, 0),
01032 NWidget(NWID_BUTTON_ARROW, COLOUR_GREY, SCMFW_WIDGET_GLASSES_L), SetDataTip(AWV_DECREASE, STR_FACE_GLASSES_TOOLTIP_2),
01033 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, SCMFW_WIDGET_GLASSES), SetDataTip(STR_EMPTY, STR_FACE_GLASSES_TOOLTIP_2),
01034 NWidget(NWID_BUTTON_ARROW, COLOUR_GREY, SCMFW_WIDGET_GLASSES_R), SetDataTip(AWV_INCREASE, STR_FACE_GLASSES_TOOLTIP_2),
01035 EndContainer(),
01036 NWidget(NWID_HORIZONTAL),
01037 NWidget(WWT_EMPTY, INVALID_COLOUR, SCMFW_WIDGET_NOSE_TEXT), SetFill(1, 0),
01038 NWidget(NWID_BUTTON_ARROW, COLOUR_GREY, SCMFW_WIDGET_NOSE_L), SetDataTip(AWV_DECREASE, STR_FACE_NOSE_TOOLTIP),
01039 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, SCMFW_WIDGET_NOSE), SetDataTip(STR_EMPTY, STR_FACE_NOSE_TOOLTIP),
01040 NWidget(NWID_BUTTON_ARROW, COLOUR_GREY, SCMFW_WIDGET_NOSE_R), SetDataTip(AWV_INCREASE, STR_FACE_NOSE_TOOLTIP),
01041 EndContainer(),
01042 NWidget(NWID_HORIZONTAL),
01043 NWidget(WWT_EMPTY, INVALID_COLOUR, SCMFW_WIDGET_LIPS_MOUSTACHE_TEXT), SetFill(1, 0),
01044 NWidget(NWID_BUTTON_ARROW, COLOUR_GREY, SCMFW_WIDGET_LIPS_MOUSTACHE_L), SetDataTip(AWV_DECREASE, STR_FACE_LIPS_MOUSTACHE_TOOLTIP),
01045 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, SCMFW_WIDGET_LIPS_MOUSTACHE), SetDataTip(STR_EMPTY, STR_FACE_LIPS_MOUSTACHE_TOOLTIP),
01046 NWidget(NWID_BUTTON_ARROW, COLOUR_GREY, SCMFW_WIDGET_LIPS_MOUSTACHE_R), SetDataTip(AWV_INCREASE, STR_FACE_LIPS_MOUSTACHE_TOOLTIP),
01047 EndContainer(),
01048 NWidget(NWID_HORIZONTAL),
01049 NWidget(WWT_EMPTY, INVALID_COLOUR, SCMFW_WIDGET_CHIN_TEXT), SetFill(1, 0),
01050 NWidget(NWID_BUTTON_ARROW, COLOUR_GREY, SCMFW_WIDGET_CHIN_L), SetDataTip(AWV_DECREASE, STR_FACE_CHIN_TOOLTIP),
01051 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, SCMFW_WIDGET_CHIN), SetDataTip(STR_EMPTY, STR_FACE_CHIN_TOOLTIP),
01052 NWidget(NWID_BUTTON_ARROW, COLOUR_GREY, SCMFW_WIDGET_CHIN_R), SetDataTip(AWV_INCREASE, STR_FACE_CHIN_TOOLTIP),
01053 EndContainer(),
01054 NWidget(NWID_HORIZONTAL),
01055 NWidget(WWT_EMPTY, INVALID_COLOUR, SCMFW_WIDGET_JACKET_TEXT), SetFill(1, 0),
01056 NWidget(NWID_BUTTON_ARROW, COLOUR_GREY, SCMFW_WIDGET_JACKET_L), SetDataTip(AWV_DECREASE, STR_FACE_JACKET_TOOLTIP),
01057 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, SCMFW_WIDGET_JACKET), SetDataTip(STR_EMPTY, STR_FACE_JACKET_TOOLTIP),
01058 NWidget(NWID_BUTTON_ARROW, COLOUR_GREY, SCMFW_WIDGET_JACKET_R), SetDataTip(AWV_INCREASE, STR_FACE_JACKET_TOOLTIP),
01059 EndContainer(),
01060 NWidget(NWID_HORIZONTAL),
01061 NWidget(WWT_EMPTY, INVALID_COLOUR, SCMFW_WIDGET_COLLAR_TEXT), SetFill(1, 0),
01062 NWidget(NWID_BUTTON_ARROW, COLOUR_GREY, SCMFW_WIDGET_COLLAR_L), SetDataTip(AWV_DECREASE, STR_FACE_COLLAR_TOOLTIP),
01063 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, SCMFW_WIDGET_COLLAR), SetDataTip(STR_EMPTY, STR_FACE_COLLAR_TOOLTIP),
01064 NWidget(NWID_BUTTON_ARROW, COLOUR_GREY, SCMFW_WIDGET_COLLAR_R), SetDataTip(AWV_INCREASE, STR_FACE_COLLAR_TOOLTIP),
01065 EndContainer(),
01066 NWidget(NWID_HORIZONTAL),
01067 NWidget(WWT_EMPTY, INVALID_COLOUR, SCMFW_WIDGET_TIE_EARRING_TEXT), SetFill(1, 0),
01068 NWidget(NWID_BUTTON_ARROW, COLOUR_GREY, SCMFW_WIDGET_TIE_EARRING_L), SetDataTip(AWV_DECREASE, STR_FACE_TIE_EARRING_TOOLTIP),
01069 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, SCMFW_WIDGET_TIE_EARRING), SetDataTip(STR_EMPTY, STR_FACE_TIE_EARRING_TOOLTIP),
01070 NWidget(NWID_BUTTON_ARROW, COLOUR_GREY, SCMFW_WIDGET_TIE_EARRING_R), SetDataTip(AWV_INCREASE, STR_FACE_TIE_EARRING_TOOLTIP),
01071 EndContainer(),
01072 NWidget(NWID_SPACER), SetFill(0, 1),
01073 EndContainer(),
01074 EndContainer(),
01075 EndContainer(),
01076 EndContainer(),
01077 NWidget(NWID_SPACER), SetMinimalSize(0, 2),
01078 EndContainer(),
01079 NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
01080 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, SCMFW_WIDGET_CANCEL), SetFill(1, 0), SetDataTip(STR_BUTTON_CANCEL, STR_FACE_CANCEL_TOOLTIP),
01081 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, SCMFW_WIDGET_ACCEPT), SetFill(1, 0), SetDataTip(STR_BUTTON_OK, STR_FACE_OK_TOOLTIP),
01082 EndContainer(),
01083 };
01084
01086 class SelectCompanyManagerFaceWindow : public Window
01087 {
01088 CompanyManagerFace face;
01089 bool advanced;
01090
01091 GenderEthnicity ge;
01092 bool is_female;
01093 bool is_moust_male;
01094
01095 Dimension yesno_dim;
01096 Dimension number_dim;
01097
01098 static const StringID PART_TEXTS_IS_FEMALE[];
01099 static const StringID PART_TEXTS[];
01100
01108 void DrawFaceStringLabel(byte widget_index, uint8 val, bool is_bool_widget) const
01109 {
01110 StringID str;
01111 const NWidgetCore *nwi_widget = this->GetWidget<NWidgetCore>(widget_index);
01112 if (!nwi_widget->IsDisabled()) {
01113 if (is_bool_widget) {
01114
01115 str = (val != 0) ? STR_FACE_YES : STR_FACE_NO;
01116 } else {
01117
01118 SetDParam(0, val + 1);
01119 str = STR_JUST_INT;
01120 }
01121
01122
01123 DrawString(nwi_widget->pos_x + nwi_widget->IsLowered(), nwi_widget->pos_x + nwi_widget->current_x - 1 - nwi_widget->IsLowered(),
01124 nwi_widget->pos_y + 1 + nwi_widget->IsLowered(), str, TC_WHITE, SA_CENTER);
01125 }
01126 }
01127
01128 void UpdateData()
01129 {
01130 this->ge = (GenderEthnicity)GB(this->face, _cmf_info[CMFV_GEN_ETHN].offset, _cmf_info[CMFV_GEN_ETHN].length);
01131 this->is_female = HasBit(this->ge, GENDER_FEMALE);
01132 this->is_moust_male = !is_female && GetCompanyManagerFaceBits(this->face, CMFV_HAS_MOUSTACHE, this->ge) != 0;
01133 }
01134
01135 public:
01136 SelectCompanyManagerFaceWindow(const WindowDesc *desc, Window *parent) : Window()
01137 {
01138 this->advanced = false;
01139 this->CreateNestedTree(desc);
01140 this->SelectDisplayPlanes(this->advanced);
01141 this->FinishInitNested(desc, parent->window_number);
01142 this->parent = parent;
01143 this->owner = (Owner)this->window_number;
01144 this->face = Company::Get((CompanyID)this->window_number)->face;
01145
01146 this->UpdateData();
01147 }
01148
01152 void SelectDisplayPlanes(bool advanced)
01153 {
01154 this->GetWidget<NWidgetStacked>(SCMFW_WIDGET_SEL_LOADSAVE)->SetDisplayedPlane(advanced ? 0 : SZSP_NONE);
01155 this->GetWidget<NWidgetStacked>(SCMFW_WIDGET_SEL_PARTS)->SetDisplayedPlane(advanced ? 0 : SZSP_NONE);
01156 this->GetWidget<NWidgetStacked>(SCMFW_WIDGET_SEL_MALEFEMALE)->SetDisplayedPlane(advanced ? SZSP_NONE : 0);
01157 this->GetWidget<NWidgetCore>(SCMFW_WIDGET_RANDOM_NEW_FACE)->widget_data = advanced ? STR_MAPGEN_RANDOM : STR_FACE_NEW_FACE_BUTTON;
01158
01159 NWidgetCore *wi = this->GetWidget<NWidgetCore>(SCMFW_WIDGET_TOGGLE_LARGE_SMALL_BUTTON);
01160 if (advanced) {
01161 wi->SetDataTip(STR_FACE_SIMPLE, STR_FACE_SIMPLE_TOOLTIP);
01162 } else {
01163 wi->SetDataTip(STR_FACE_ADVANCED, STR_FACE_ADVANCED_TOOLTIP);
01164 }
01165 }
01166
01167 virtual void OnInit()
01168 {
01169
01170 Dimension yesno_dim = maxdim(GetStringBoundingBox(STR_FACE_YES), GetStringBoundingBox(STR_FACE_NO));
01171 yesno_dim.width += WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT;
01172 yesno_dim.height += WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
01173
01174 Dimension number_dim = {0, 0};
01175 for (int val = 1; val <= 12; val++) {
01176 SetDParam(0, val);
01177 number_dim = maxdim(number_dim, GetStringBoundingBox(STR_JUST_INT));
01178 }
01179 uint arrows_width = GetSpriteSize(SPR_ARROW_LEFT).width + GetSpriteSize(SPR_ARROW_RIGHT).width + 2 * (WD_IMGBTN_LEFT + WD_IMGBTN_RIGHT);
01180 number_dim.width += WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT + arrows_width;
01181 number_dim.height += WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
01182
01183 yesno_dim.width = max(yesno_dim.width, number_dim.width);
01184 number_dim.width = yesno_dim.width - arrows_width;
01185
01186 this->yesno_dim = yesno_dim;
01187 this->number_dim = number_dim;
01188 }
01189
01190 virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
01191 {
01192 switch (widget) {
01193 case SCMFW_WIDGET_HAS_MOUSTACHE_EARRING_TEXT:
01194 case SCMFW_WIDGET_TIE_EARRING_TEXT: {
01195 int offset = (widget - SCMFW_WIDGET_HAS_MOUSTACHE_EARRING_TEXT) * 2;
01196 *size = maxdim(GetStringBoundingBox(PART_TEXTS_IS_FEMALE[offset]), GetStringBoundingBox(PART_TEXTS_IS_FEMALE[offset + 1]));
01197 size->width += WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT;
01198 size->height += WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
01199 break;
01200 }
01201
01202 case SCMFW_WIDGET_LIPS_MOUSTACHE_TEXT:
01203 *size = maxdim(GetStringBoundingBox(STR_FACE_LIPS), GetStringBoundingBox(STR_FACE_MOUSTACHE));
01204 size->width += WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT;
01205 size->height += WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
01206 break;
01207
01208 case SCMFW_WIDGET_HAS_GLASSES_TEXT:
01209 case SCMFW_WIDGET_HAIR_TEXT:
01210 case SCMFW_WIDGET_EYEBROWS_TEXT:
01211 case SCMFW_WIDGET_EYECOLOUR_TEXT:
01212 case SCMFW_WIDGET_GLASSES_TEXT:
01213 case SCMFW_WIDGET_NOSE_TEXT:
01214 case SCMFW_WIDGET_CHIN_TEXT:
01215 case SCMFW_WIDGET_JACKET_TEXT:
01216 case SCMFW_WIDGET_COLLAR_TEXT:
01217 *size = GetStringBoundingBox(PART_TEXTS[widget - SCMFW_WIDGET_HAS_GLASSES_TEXT]);
01218 size->width += WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT;
01219 size->height += WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
01220 break;
01221
01222 case SCMFW_WIDGET_HAS_MOUSTACHE_EARRING:
01223 case SCMFW_WIDGET_HAS_GLASSES:
01224 *size = this->yesno_dim;
01225 break;
01226
01227 case SCMFW_WIDGET_EYECOLOUR:
01228 case SCMFW_WIDGET_CHIN:
01229 case SCMFW_WIDGET_EYEBROWS:
01230 case SCMFW_WIDGET_LIPS_MOUSTACHE:
01231 case SCMFW_WIDGET_NOSE:
01232 case SCMFW_WIDGET_HAIR:
01233 case SCMFW_WIDGET_JACKET:
01234 case SCMFW_WIDGET_COLLAR:
01235 case SCMFW_WIDGET_TIE_EARRING:
01236 case SCMFW_WIDGET_GLASSES:
01237 *size = this->number_dim;
01238 break;
01239 }
01240 }
01241
01242 virtual void OnPaint()
01243 {
01244
01245 this->SetWidgetsLoweredState(!this->is_female, SCMFW_WIDGET_MALE, SCMFW_WIDGET_MALE2, WIDGET_LIST_END);
01246 this->SetWidgetsLoweredState( this->is_female, SCMFW_WIDGET_FEMALE, SCMFW_WIDGET_FEMALE2, WIDGET_LIST_END);
01247
01248
01249
01250
01251 this->SetWidgetLoweredState(SCMFW_WIDGET_ETHNICITY_EUR, !HasBit(this->ge, ETHNICITY_BLACK));
01252 this->SetWidgetLoweredState(SCMFW_WIDGET_ETHNICITY_AFR, HasBit(this->ge, ETHNICITY_BLACK));
01253
01254
01255
01256
01257
01258
01259
01260 this->SetWidgetsDisabledState(_cmf_info[CMFV_EYE_COLOUR].valid_values[this->ge] < 2,
01261 SCMFW_WIDGET_EYECOLOUR, SCMFW_WIDGET_EYECOLOUR_L, SCMFW_WIDGET_EYECOLOUR_R, WIDGET_LIST_END);
01262
01263
01264 this->SetWidgetsDisabledState(_cmf_info[CMFV_CHIN].valid_values[this->ge] < 2,
01265 SCMFW_WIDGET_CHIN, SCMFW_WIDGET_CHIN_L, SCMFW_WIDGET_CHIN_R, WIDGET_LIST_END);
01266
01267
01268 this->SetWidgetsDisabledState(_cmf_info[CMFV_EYEBROWS].valid_values[this->ge] < 2,
01269 SCMFW_WIDGET_EYEBROWS, SCMFW_WIDGET_EYEBROWS_L, SCMFW_WIDGET_EYEBROWS_R, WIDGET_LIST_END);
01270
01271
01272 this->SetWidgetsDisabledState(_cmf_info[this->is_moust_male ? CMFV_MOUSTACHE : CMFV_LIPS].valid_values[this->ge] < 2,
01273 SCMFW_WIDGET_LIPS_MOUSTACHE, SCMFW_WIDGET_LIPS_MOUSTACHE_L, SCMFW_WIDGET_LIPS_MOUSTACHE_R, WIDGET_LIST_END);
01274
01275
01276 this->SetWidgetsDisabledState(_cmf_info[CMFV_NOSE].valid_values[this->ge] < 2 || this->is_moust_male,
01277 SCMFW_WIDGET_NOSE, SCMFW_WIDGET_NOSE_L, SCMFW_WIDGET_NOSE_R, WIDGET_LIST_END);
01278
01279
01280 this->SetWidgetsDisabledState(_cmf_info[CMFV_HAIR].valid_values[this->ge] < 2,
01281 SCMFW_WIDGET_HAIR, SCMFW_WIDGET_HAIR_L, SCMFW_WIDGET_HAIR_R, WIDGET_LIST_END);
01282
01283
01284 this->SetWidgetsDisabledState(_cmf_info[CMFV_JACKET].valid_values[this->ge] < 2,
01285 SCMFW_WIDGET_JACKET, SCMFW_WIDGET_JACKET_L, SCMFW_WIDGET_JACKET_R, WIDGET_LIST_END);
01286
01287
01288 this->SetWidgetsDisabledState(_cmf_info[CMFV_COLLAR].valid_values[this->ge] < 2,
01289 SCMFW_WIDGET_COLLAR, SCMFW_WIDGET_COLLAR_L, SCMFW_WIDGET_COLLAR_R, WIDGET_LIST_END);
01290
01291
01292 this->SetWidgetsDisabledState(_cmf_info[CMFV_TIE_EARRING].valid_values[this->ge] < 2 ||
01293 (this->is_female && GetCompanyManagerFaceBits(this->face, CMFV_HAS_TIE_EARRING, this->ge) == 0),
01294 SCMFW_WIDGET_TIE_EARRING, SCMFW_WIDGET_TIE_EARRING_L, SCMFW_WIDGET_TIE_EARRING_R, WIDGET_LIST_END);
01295
01296
01297 this->SetWidgetsDisabledState(_cmf_info[CMFV_GLASSES].valid_values[this->ge] < 2 || GetCompanyManagerFaceBits(this->face, CMFV_HAS_GLASSES, this->ge) == 0,
01298 SCMFW_WIDGET_GLASSES, SCMFW_WIDGET_GLASSES_L, SCMFW_WIDGET_GLASSES_R, WIDGET_LIST_END);
01299
01300 this->DrawWidgets();
01301 }
01302
01303 virtual void DrawWidget(const Rect &r, int widget) const
01304 {
01305 switch (widget) {
01306 case SCMFW_WIDGET_HAS_MOUSTACHE_EARRING_TEXT:
01307 case SCMFW_WIDGET_TIE_EARRING_TEXT: {
01308 StringID str = PART_TEXTS_IS_FEMALE[(widget - SCMFW_WIDGET_HAS_MOUSTACHE_EARRING_TEXT) * 2 + this->is_female];
01309 DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, str, TC_GOLD, SA_RIGHT);
01310 break;
01311 }
01312
01313 case SCMFW_WIDGET_LIPS_MOUSTACHE_TEXT:
01314 DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, (this->is_moust_male) ? STR_FACE_MOUSTACHE : STR_FACE_LIPS, TC_GOLD, SA_RIGHT);
01315 break;
01316
01317 case SCMFW_WIDGET_HAS_GLASSES_TEXT:
01318 case SCMFW_WIDGET_HAIR_TEXT:
01319 case SCMFW_WIDGET_EYEBROWS_TEXT:
01320 case SCMFW_WIDGET_EYECOLOUR_TEXT:
01321 case SCMFW_WIDGET_GLASSES_TEXT:
01322 case SCMFW_WIDGET_NOSE_TEXT:
01323 case SCMFW_WIDGET_CHIN_TEXT:
01324 case SCMFW_WIDGET_JACKET_TEXT:
01325 case SCMFW_WIDGET_COLLAR_TEXT:
01326 DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, PART_TEXTS[widget - SCMFW_WIDGET_HAS_GLASSES_TEXT], TC_GOLD, SA_RIGHT);
01327 break;
01328
01329
01330 case SCMFW_WIDGET_HAS_MOUSTACHE_EARRING:
01331 if (this->is_female) {
01332 this->DrawFaceStringLabel(SCMFW_WIDGET_HAS_MOUSTACHE_EARRING, GetCompanyManagerFaceBits(this->face, CMFV_HAS_TIE_EARRING, this->ge), true);
01333 } else {
01334 this->DrawFaceStringLabel(SCMFW_WIDGET_HAS_MOUSTACHE_EARRING, GetCompanyManagerFaceBits(this->face, CMFV_HAS_MOUSTACHE, this->ge), true);
01335 }
01336 break;
01337
01338 case SCMFW_WIDGET_TIE_EARRING:
01339 if (this->is_female) {
01340 this->DrawFaceStringLabel(SCMFW_WIDGET_TIE_EARRING, GetCompanyManagerFaceBits(this->face, CMFV_TIE_EARRING, this->ge), false);
01341 } else {
01342 this->DrawFaceStringLabel(SCMFW_WIDGET_TIE_EARRING, GetCompanyManagerFaceBits(this->face, CMFV_TIE_EARRING, this->ge), false);
01343 }
01344 break;
01345
01346 case SCMFW_WIDGET_LIPS_MOUSTACHE:
01347 if (this->is_moust_male) {
01348 this->DrawFaceStringLabel(SCMFW_WIDGET_LIPS_MOUSTACHE, GetCompanyManagerFaceBits(this->face, CMFV_MOUSTACHE, this->ge), false);
01349 } else {
01350 this->DrawFaceStringLabel(SCMFW_WIDGET_LIPS_MOUSTACHE, GetCompanyManagerFaceBits(this->face, CMFV_LIPS, this->ge), false);
01351 }
01352 break;
01353
01354 case SCMFW_WIDGET_HAS_GLASSES:
01355 this->DrawFaceStringLabel(SCMFW_WIDGET_HAS_GLASSES, GetCompanyManagerFaceBits(this->face, CMFV_HAS_GLASSES, this->ge), true );
01356 break;
01357
01358 case SCMFW_WIDGET_HAIR:
01359 this->DrawFaceStringLabel(SCMFW_WIDGET_HAIR, GetCompanyManagerFaceBits(this->face, CMFV_HAIR, this->ge), false);
01360 break;
01361
01362 case SCMFW_WIDGET_EYEBROWS:
01363 this->DrawFaceStringLabel(SCMFW_WIDGET_EYEBROWS, GetCompanyManagerFaceBits(this->face, CMFV_EYEBROWS, this->ge), false);
01364 break;
01365
01366 case SCMFW_WIDGET_EYECOLOUR:
01367 this->DrawFaceStringLabel(SCMFW_WIDGET_EYECOLOUR, GetCompanyManagerFaceBits(this->face, CMFV_EYE_COLOUR, this->ge), false);
01368 break;
01369
01370 case SCMFW_WIDGET_GLASSES:
01371 this->DrawFaceStringLabel(SCMFW_WIDGET_GLASSES, GetCompanyManagerFaceBits(this->face, CMFV_GLASSES, this->ge), false);
01372 break;
01373
01374 case SCMFW_WIDGET_NOSE:
01375 this->DrawFaceStringLabel(SCMFW_WIDGET_NOSE, GetCompanyManagerFaceBits(this->face, CMFV_NOSE, this->ge), false);
01376 break;
01377
01378 case SCMFW_WIDGET_CHIN:
01379 this->DrawFaceStringLabel(SCMFW_WIDGET_CHIN, GetCompanyManagerFaceBits(this->face, CMFV_CHIN, this->ge), false);
01380 break;
01381
01382 case SCMFW_WIDGET_JACKET:
01383 this->DrawFaceStringLabel(SCMFW_WIDGET_JACKET, GetCompanyManagerFaceBits(this->face, CMFV_JACKET, this->ge), false);
01384 break;
01385
01386 case SCMFW_WIDGET_COLLAR:
01387 this->DrawFaceStringLabel(SCMFW_WIDGET_COLLAR, GetCompanyManagerFaceBits(this->face, CMFV_COLLAR, this->ge), false);
01388 break;
01389
01390 case SCMFM_WIDGET_FACE:
01391 DrawCompanyManagerFace(this->face, Company::Get((CompanyID)this->window_number)->colour, r.left, r.top);
01392 break;
01393 }
01394 }
01395
01396 virtual void OnClick(Point pt, int widget, int click_count)
01397 {
01398 switch (widget) {
01399
01400 case SCMFW_WIDGET_TOGGLE_LARGE_SMALL:
01401 case SCMFW_WIDGET_TOGGLE_LARGE_SMALL_BUTTON:
01402 this->advanced = !this->advanced;
01403 this->SelectDisplayPlanes(this->advanced);
01404 this->ReInit();
01405 break;
01406
01407
01408 case SCMFW_WIDGET_ACCEPT:
01409 DoCommandP(0, 0, this->face, CMD_SET_COMPANY_MANAGER_FACE);
01410
01411
01412
01413 case SCMFW_WIDGET_CANCEL:
01414 delete this;
01415 break;
01416
01417
01418 case SCMFW_WIDGET_LOAD:
01419 this->face = _company_manager_face;
01420 ScaleAllCompanyManagerFaceBits(this->face);
01421 ShowErrorMessage(STR_FACE_LOAD_DONE, INVALID_STRING_ID, 0, 0);
01422 this->UpdateData();
01423 this->SetDirty();
01424 break;
01425
01426
01427 case SCMFW_WIDGET_FACECODE:
01428 SetDParam(0, this->face);
01429 ShowQueryString(STR_JUST_INT, STR_FACE_FACECODE_CAPTION, 10 + 1, 0, this, CS_NUMERAL, QSF_NONE);
01430 break;
01431
01432
01433 case SCMFW_WIDGET_SAVE:
01434 _company_manager_face = this->face;
01435 ShowErrorMessage(STR_FACE_SAVE_DONE, INVALID_STRING_ID, 0, 0);
01436 break;
01437
01438
01439 case SCMFW_WIDGET_MALE:
01440 case SCMFW_WIDGET_FEMALE:
01441 case SCMFW_WIDGET_MALE2:
01442 case SCMFW_WIDGET_FEMALE2:
01443 SetCompanyManagerFaceBits(this->face, CMFV_GENDER, this->ge, (widget == SCMFW_WIDGET_FEMALE || widget == SCMFW_WIDGET_FEMALE2));
01444 ScaleAllCompanyManagerFaceBits(this->face);
01445 this->UpdateData();
01446 this->SetDirty();
01447 break;
01448
01449
01450 case SCMFW_WIDGET_RANDOM_NEW_FACE:
01451 RandomCompanyManagerFaceBits(this->face, this->ge, this->advanced);
01452 this->UpdateData();
01453 this->SetDirty();
01454 break;
01455
01456
01457 case SCMFW_WIDGET_ETHNICITY_EUR:
01458 case SCMFW_WIDGET_ETHNICITY_AFR:
01459 SetCompanyManagerFaceBits(this->face, CMFV_ETHNICITY, this->ge, widget - SCMFW_WIDGET_ETHNICITY_EUR);
01460 ScaleAllCompanyManagerFaceBits(this->face);
01461 this->UpdateData();
01462 this->SetDirty();
01463 break;
01464
01465 default:
01466
01467
01468
01469
01470 if (widget >= SCMFW_WIDGET_HAS_MOUSTACHE_EARRING && widget <= SCMFW_WIDGET_GLASSES_R) {
01471 CompanyManagerFaceVariable cmfv;
01472
01473 if (widget < SCMFW_WIDGET_EYECOLOUR_L) {
01474 switch (widget - SCMFW_WIDGET_HAS_MOUSTACHE_EARRING) {
01475 default: NOT_REACHED();
01476 case 0: cmfv = this->is_female ? CMFV_HAS_TIE_EARRING : CMFV_HAS_MOUSTACHE; break;
01477 case 1: cmfv = CMFV_HAS_GLASSES; break;
01478 }
01479 SetCompanyManagerFaceBits(this->face, cmfv, this->ge, !GetCompanyManagerFaceBits(this->face, cmfv, this->ge));
01480 ScaleAllCompanyManagerFaceBits(this->face);
01481 } else {
01482 switch ((widget - SCMFW_WIDGET_EYECOLOUR_L) / 3) {
01483 default: NOT_REACHED();
01484 case 0: cmfv = CMFV_EYE_COLOUR; break;
01485 case 1: cmfv = CMFV_CHIN; break;
01486 case 2: cmfv = CMFV_EYEBROWS; break;
01487 case 3: cmfv = this->is_moust_male ? CMFV_MOUSTACHE : CMFV_LIPS; break;
01488 case 4: cmfv = CMFV_NOSE; break;
01489 case 5: cmfv = CMFV_HAIR; break;
01490 case 6: cmfv = CMFV_JACKET; break;
01491 case 7: cmfv = CMFV_COLLAR; break;
01492 case 8: cmfv = CMFV_TIE_EARRING; break;
01493 case 9: cmfv = CMFV_GLASSES; break;
01494 }
01495
01496 IncreaseCompanyManagerFaceBits(this->face, cmfv, this->ge, (((widget - SCMFW_WIDGET_EYECOLOUR_L) % 3) != 0) ? 1 : -1);
01497 }
01498 this->UpdateData();
01499 this->SetDirty();
01500 }
01501 break;
01502 }
01503 }
01504
01505 virtual void OnQueryTextFinished(char *str)
01506 {
01507 if (str == NULL) return;
01508
01509 if (!StrEmpty(str)) {
01510 this->face = strtoul(str, NULL, 10);
01511 ScaleAllCompanyManagerFaceBits(this->face);
01512 ShowErrorMessage(STR_FACE_FACECODE_SET, INVALID_STRING_ID, 0, 0);
01513 this->UpdateData();
01514 this->SetDirty();
01515 } else {
01516 ShowErrorMessage(STR_FACE_FACECODE_ERR, INVALID_STRING_ID, 0, 0);
01517 }
01518 }
01519 };
01520
01522 const StringID SelectCompanyManagerFaceWindow::PART_TEXTS_IS_FEMALE[] = {
01523 STR_FACE_MOUSTACHE, STR_FACE_EARRING,
01524 STR_FACE_TIE, STR_FACE_EARRING,
01525 };
01526
01528 const StringID SelectCompanyManagerFaceWindow::PART_TEXTS[] = {
01529 STR_FACE_GLASSES,
01530 STR_FACE_HAIR,
01531 STR_FACE_EYEBROWS,
01532 STR_FACE_EYECOLOUR,
01533 STR_FACE_GLASSES,
01534 STR_FACE_NOSE,
01535 STR_FACE_CHIN,
01536 STR_FACE_JACKET,
01537 STR_FACE_COLLAR,
01538 };
01539
01541 static const WindowDesc _select_company_manager_face_desc(
01542 WDP_AUTO, 0, 0,
01543 WC_COMPANY_MANAGER_FACE, WC_NONE,
01544 WDF_UNCLICK_BUTTONS | WDF_CONSTRUCTION,
01545 _nested_select_company_manager_face_widgets, lengthof(_nested_select_company_manager_face_widgets)
01546 );
01547
01556 static void DoSelectCompanyManagerFace(Window *parent)
01557 {
01558 if (!Company::IsValidID((CompanyID)parent->window_number)) return;
01559
01560 if (BringWindowToFrontById(WC_COMPANY_MANAGER_FACE, parent->window_number)) return;
01561 new SelectCompanyManagerFaceWindow(&_select_company_manager_face_desc, parent);
01562 }
01563
01564
01566 enum CompanyWindowWidgets {
01567 CW_WIDGET_CAPTION,
01568
01569 CW_WIDGET_FACE,
01570 CW_WIDGET_FACE_TITLE,
01571
01572 CW_WIDGET_DESC_INAUGURATION,
01573 CW_WIDGET_DESC_COLOUR_SCHEME,
01574 CW_WIDGET_DESC_COLOUR_SCHEME_EXAMPLE,
01575 CW_WIDGET_DESC_VEHICLE,
01576 CW_WIDGET_DESC_VEHICLE_COUNTS,
01577 CW_WIDGET_DESC_COMPANY_VALUE,
01578 CW_WIDGET_DESC_OWNERS,
01579
01580 CW_WIDGET_SELECT_BUTTONS,
01581 CW_WIDGET_NEW_FACE,
01582 CW_WIDGET_COLOUR_SCHEME,
01583 CW_WIDGET_PRESIDENT_NAME,
01584 CW_WIDGET_COMPANY_NAME,
01585 CW_WIDGET_BUY_SHARE,
01586 CW_WIDGET_SELL_SHARE,
01587
01588 CW_WIDGET_SELECT_VIEW_BUILD_HQ,
01589 CW_WIDGET_VIEW_HQ,
01590 CW_WIDGET_BUILD_HQ,
01591
01592 CW_WIDGET_SELECT_RELOCATE,
01593 CW_WIDGET_RELOCATE_HQ,
01594
01595 CW_WIDGET_HAS_PASSWORD,
01596 CW_WIDGET_SELECT_MULTIPLAYER,
01597 CW_WIDGET_COMPANY_PASSWORD,
01598 CW_WIDGET_COMPANY_JOIN,
01599 };
01600
01601 static const NWidgetPart _nested_company_widgets[] = {
01602 NWidget(NWID_HORIZONTAL),
01603 NWidget(WWT_CLOSEBOX, COLOUR_GREY),
01604 NWidget(WWT_CAPTION, COLOUR_GREY, CW_WIDGET_CAPTION), SetDataTip(STR_COMPANY_VIEW_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
01605 NWidget(WWT_SHADEBOX, COLOUR_GREY),
01606 NWidget(WWT_STICKYBOX, COLOUR_GREY),
01607 EndContainer(),
01608 NWidget(WWT_PANEL, COLOUR_GREY),
01609 NWidget(NWID_HORIZONTAL), SetPIP(4, 6, 4),
01610 NWidget(NWID_VERTICAL), SetPIP(4, 2, 4),
01611 NWidget(WWT_EMPTY, INVALID_COLOUR, CW_WIDGET_FACE), SetMinimalSize(92, 119), SetFill(1, 0),
01612 NWidget(WWT_EMPTY, INVALID_COLOUR, CW_WIDGET_FACE_TITLE), SetFill(1, 1), SetMinimalTextLines(2, 0),
01613 EndContainer(),
01614 NWidget(NWID_VERTICAL),
01615 NWidget(NWID_HORIZONTAL),
01616 NWidget(NWID_VERTICAL), SetPIP(4, 5, 5),
01617 NWidget(WWT_TEXT, COLOUR_GREY, CW_WIDGET_DESC_INAUGURATION), SetDataTip(STR_COMPANY_VIEW_INAUGURATED_TITLE, STR_NULL), SetFill(1, 0),
01618 NWidget(NWID_HORIZONTAL), SetPIP(0, 5, 0),
01619 NWidget(WWT_LABEL, COLOUR_GREY, CW_WIDGET_DESC_COLOUR_SCHEME), SetDataTip(STR_COMPANY_VIEW_COLOUR_SCHEME_TITLE, STR_NULL),
01620 NWidget(WWT_EMPTY, INVALID_COLOUR, CW_WIDGET_DESC_COLOUR_SCHEME_EXAMPLE), SetMinimalSize(30, 0), SetFill(0, 1),
01621 NWidget(NWID_SPACER), SetFill(1, 0),
01622 EndContainer(),
01623 NWidget(NWID_HORIZONTAL), SetPIP(0, 4, 0),
01624 NWidget(NWID_VERTICAL),
01625 NWidget(WWT_TEXT, COLOUR_GREY, CW_WIDGET_DESC_VEHICLE), SetDataTip(STR_COMPANY_VIEW_VEHICLES_TITLE, STR_NULL),
01626 NWidget(NWID_SPACER), SetFill(0, 1),
01627 EndContainer(),
01628 NWidget(WWT_EMPTY, INVALID_COLOUR, CW_WIDGET_DESC_VEHICLE_COUNTS), SetMinimalTextLines(4, 0),
01629 NWidget(NWID_SPACER), SetFill(1, 0),
01630 EndContainer(),
01631 EndContainer(),
01632 NWidget(NWID_VERTICAL), SetPIP(4, 2, 4),
01633 NWidget(NWID_SELECTION, INVALID_COLOUR, CW_WIDGET_SELECT_VIEW_BUILD_HQ),
01634 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, CW_WIDGET_VIEW_HQ), SetFill(1, 0), SetDataTip(STR_COMPANY_VIEW_VIEW_HQ_BUTTON, STR_COMPANY_VIEW_VIEW_HQ_TOOLTIP),
01635 NWidget(WWT_TEXTBTN, COLOUR_GREY, CW_WIDGET_BUILD_HQ), SetFill(1, 0), SetDataTip(STR_COMPANY_VIEW_BUILD_HQ_BUTTON, STR_COMPANY_VIEW_BUILD_HQ_TOOLTIP),
01636 EndContainer(),
01637 NWidget(NWID_SELECTION, INVALID_COLOUR, CW_WIDGET_SELECT_RELOCATE),
01638 NWidget(WWT_TEXTBTN, COLOUR_GREY, CW_WIDGET_RELOCATE_HQ), SetFill(1, 0), SetDataTip(STR_COMPANY_VIEW_RELOCATE_HQ, STR_COMPANY_VIEW_RELOCATE_COMPANY_HEADQUARTERS),
01639 NWidget(NWID_SPACER), SetMinimalSize(90, 0),
01640 EndContainer(),
01641 NWidget(NWID_SPACER), SetFill(0, 1),
01642 EndContainer(),
01643 EndContainer(),
01644 NWidget(WWT_TEXT, COLOUR_GREY, CW_WIDGET_DESC_COMPANY_VALUE), SetDataTip(STR_COMPANY_VIEW_COMPANY_VALUE, STR_NULL), SetFill(1, 0),
01645 NWidget(NWID_HORIZONTAL),
01646 NWidget(NWID_VERTICAL), SetPIP(5, 5, 4),
01647 NWidget(WWT_EMPTY, INVALID_COLOUR, CW_WIDGET_DESC_OWNERS), SetMinimalTextLines(3, 0),
01648 NWidget(NWID_SPACER), SetFill(0, 1),
01649 EndContainer(),
01650 NWidget(NWID_VERTICAL), SetPIP(4, 2, 4),
01651 NWidget(NWID_SPACER), SetMinimalSize(90, 0), SetFill(0, 1),
01652
01653 NWidget(NWID_HORIZONTAL),
01654 NWidget(WWT_EMPTY, COLOUR_GREY, CW_WIDGET_HAS_PASSWORD),
01655 NWidget(NWID_SELECTION, INVALID_COLOUR, CW_WIDGET_SELECT_MULTIPLAYER),
01656 NWidget(NWID_SPACER), SetFill(1, 0),
01657 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, CW_WIDGET_COMPANY_PASSWORD), SetFill(1, 0), SetDataTip(STR_COMPANY_VIEW_PASSWORD, STR_COMPANY_VIEW_PASSWORD_TOOLTIP),
01658 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, CW_WIDGET_COMPANY_JOIN), SetFill(1, 0), SetDataTip(STR_COMPANY_VIEW_JOIN, STR_COMPANY_VIEW_JOIN_TOOLTIP),
01659 EndContainer(),
01660 EndContainer(),
01661 EndContainer(),
01662 EndContainer(),
01663 EndContainer(),
01664 EndContainer(),
01665 EndContainer(),
01666
01667 NWidget(NWID_SELECTION, INVALID_COLOUR, CW_WIDGET_SELECT_BUTTONS),
01668 NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
01669 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, CW_WIDGET_NEW_FACE), SetFill(1, 0), SetDataTip(STR_COMPANY_VIEW_NEW_FACE_BUTTON, STR_COMPANY_VIEW_NEW_FACE_TOOLTIP),
01670 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, CW_WIDGET_COLOUR_SCHEME), SetFill(1, 0), SetDataTip(STR_COMPANY_VIEW_COLOUR_SCHEME_BUTTON, STR_COMPANY_VIEW_COLOUR_SCHEME_TOOLTIP),
01671 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, CW_WIDGET_PRESIDENT_NAME), SetFill(1, 0), SetDataTip(STR_COMPANY_VIEW_PRESIDENT_NAME_BUTTON, STR_COMPANY_VIEW_PRESIDENT_NAME_TOOLTIP),
01672 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, CW_WIDGET_COMPANY_NAME), SetFill(1, 0), SetDataTip(STR_COMPANY_VIEW_COMPANY_NAME_BUTTON, STR_COMPANY_VIEW_COMPANY_NAME_TOOLTIP),
01673 EndContainer(),
01674 NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
01675 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, CW_WIDGET_BUY_SHARE), SetFill(1, 0), SetDataTip(STR_COMPANY_VIEW_BUY_SHARE_BUTTON, STR_COMPANY_VIEW_BUY_SHARE_TOOLTIP),
01676 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, CW_WIDGET_SELL_SHARE), SetFill(1, 0), SetDataTip(STR_COMPANY_VIEW_SELL_SHARE_BUTTON, STR_COMPANY_VIEW_SELL_SHARE_TOOLTIP),
01677 EndContainer(),
01678 EndContainer(),
01679 };
01680
01681 int GetAmountOwnedBy(const Company *c, Owner owner)
01682 {
01683 return (c->share_owners[0] == owner) +
01684 (c->share_owners[1] == owner) +
01685 (c->share_owners[2] == owner) +
01686 (c->share_owners[3] == owner);
01687 }
01688
01690 static const StringID _company_view_vehicle_count_strings[] = {
01691 STR_COMPANY_VIEW_TRAINS, STR_COMPANY_VIEW_ROAD_VEHICLES, STR_COMPANY_VIEW_SHIPS, STR_COMPANY_VIEW_AIRCRAFT
01692 };
01693
01697 struct CompanyWindow : Window
01698 {
01699 CompanyWindowWidgets query_widget;
01700
01702 enum CompanyWindowPlanes {
01703
01704 CWP_MP_EMPTY = 0,
01705 CWP_MP_C_PWD,
01706 CWP_MP_C_JOIN,
01707
01708
01709 CWP_VB_VIEW = 0,
01710 CWP_VB_BUILD,
01711
01712
01713 CWP_RELOCATE_SHOW = 0,
01714 CWP_RELOCATE_HIDE,
01715
01716
01717 CWP_BUTTONS_LOCAL = 0,
01718 CWP_BUTTONS_OTHER,
01719 };
01720
01721 CompanyWindow(const WindowDesc *desc, WindowNumber window_number) : Window()
01722 {
01723 this->InitNested(desc, window_number);
01724 this->owner = (Owner)this->window_number;
01725 }
01726
01727 virtual void OnPaint()
01728 {
01729 const Company *c = Company::Get((CompanyID)this->window_number);
01730 bool local = this->window_number == _local_company;
01731
01732 if (!this->IsShaded()) {
01733
01734 int plane = local ? CWP_BUTTONS_LOCAL : CWP_BUTTONS_OTHER;
01735 NWidgetStacked *wi = this->GetWidget<NWidgetStacked>(CW_WIDGET_SELECT_BUTTONS);
01736 if (plane != wi->shown_plane) {
01737 wi->SetDisplayedPlane(plane);
01738 this->SetDirty();
01739 return;
01740 }
01741
01742
01743 plane = (local && c->location_of_HQ == INVALID_TILE) ? CWP_VB_BUILD : CWP_VB_VIEW;
01744 wi = this->GetWidget<NWidgetStacked>(CW_WIDGET_SELECT_VIEW_BUILD_HQ);
01745 if (plane != wi->shown_plane) {
01746 wi->SetDisplayedPlane(plane);
01747 this->SetDirty();
01748 return;
01749 }
01750
01751 this->SetWidgetDisabledState(CW_WIDGET_VIEW_HQ, c->location_of_HQ == INVALID_TILE);
01752
01753
01754 plane = (!local || c->location_of_HQ == INVALID_TILE) ? CWP_RELOCATE_HIDE : CWP_RELOCATE_SHOW;
01755 wi = this->GetWidget<NWidgetStacked>(CW_WIDGET_SELECT_RELOCATE);
01756 if (plane != wi->shown_plane) {
01757 wi->SetDisplayedPlane(plane);
01758 this->SetDirty();
01759 return;
01760 }
01761
01762
01763 plane = ((!_networking) ? CWP_MP_EMPTY : (local ? CWP_MP_C_PWD : CWP_MP_C_JOIN));
01764 wi = this->GetWidget<NWidgetStacked>(CW_WIDGET_SELECT_MULTIPLAYER);
01765 if (plane != wi->shown_plane) {
01766 wi->SetDisplayedPlane(plane);
01767 this->SetDirty();
01768 return;
01769 }
01770 this->SetWidgetDisabledState(CW_WIDGET_COMPANY_JOIN, c->is_ai);
01771 }
01772
01773 if (!local) {
01774 if (_settings_game.economy.allow_shares) {
01775
01776 this->SetWidgetDisabledState(CW_WIDGET_BUY_SHARE, GetAmountOwnedBy(c, INVALID_OWNER) == 0 ||
01777
01778 (GetAmountOwnedBy(c, INVALID_OWNER) == 1 && !c->is_ai) ||
01779
01780 _local_company == COMPANY_SPECTATOR);
01781
01782
01783 this->SetWidgetDisabledState(CW_WIDGET_SELL_SHARE, (GetAmountOwnedBy(c, _local_company) == 0) ||
01784
01785 _local_company == COMPANY_SPECTATOR);
01786 } else {
01787 this->DisableWidget(CW_WIDGET_BUY_SHARE);
01788 this->DisableWidget(CW_WIDGET_SELL_SHARE);
01789 }
01790 }
01791
01792 this->DrawWidgets();
01793 }
01794
01795 virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
01796 {
01797 switch (widget) {
01798 case CW_WIDGET_DESC_COMPANY_VALUE:
01799 SetDParam(0, INT64_MAX);
01800 size->width = GetStringBoundingBox(STR_COMPANY_VIEW_COMPANY_VALUE).width;
01801 break;
01802
01803 case CW_WIDGET_DESC_VEHICLE_COUNTS:
01804 SetDParam(0, 5000);
01805 for (uint i = 0; i < lengthof(_company_view_vehicle_count_strings); i++) {
01806 size->width = max(size->width, GetStringBoundingBox(_company_view_vehicle_count_strings[i]).width);
01807 }
01808 break;
01809
01810 case CW_WIDGET_DESC_OWNERS: {
01811 const Company *c2;
01812
01813 FOR_ALL_COMPANIES(c2) {
01814 SetDParam(0, 25);
01815 SetDParam(1, c2->index);
01816
01817 size->width = max(size->width, GetStringBoundingBox(STR_COMPANY_VIEW_SHARES_OWNED_BY).width);
01818 }
01819 } break;
01820
01821 #ifdef ENABLE_NETWORK
01822 case CW_WIDGET_HAS_PASSWORD:
01823 *size = maxdim(*size, GetSpriteSize(SPR_LOCK));
01824 break;
01825 #endif
01826 }
01827 }
01828
01829 virtual void DrawWidget(const Rect &r, int widget) const
01830 {
01831 const Company *c = Company::Get((CompanyID)this->window_number);
01832 switch (widget) {
01833 case CW_WIDGET_FACE:
01834 DrawCompanyManagerFace(c->face, c->colour, r.left, r.top);
01835 break;
01836
01837 case CW_WIDGET_FACE_TITLE:
01838 SetDParam(0, c->index);
01839 DrawStringMultiLine(r.left, r.right, r.top, r.bottom, STR_COMPANY_VIEW_PRESIDENT_MANAGER_TITLE, TC_FROMSTRING, SA_CENTER);
01840 break;
01841
01842 case CW_WIDGET_DESC_COLOUR_SCHEME_EXAMPLE:
01843 DrawSprite(SPR_VEH_BUS_SW_VIEW, COMPANY_SPRITE_COLOUR(c->index), (r.left + r.right) / 2, r.top + FONT_HEIGHT_NORMAL / 10);
01844 break;
01845
01846 case CW_WIDGET_DESC_VEHICLE_COUNTS: {
01847 uint amounts[] = { 0, 0, 0, 0 };
01848 int y = r.top;
01849
01850 const Vehicle *v;
01851 FOR_ALL_VEHICLES(v) {
01852 if (v->owner == c->index) {
01853 if (v->IsPrimaryVehicle()) {
01854 assert((size_t)v->type < lengthof(amounts));
01855 amounts[v->type]++;
01856 }
01857 }
01858 }
01859
01860 if (amounts[0] + amounts[1] + amounts[2] + amounts[3] == 0) {
01861 DrawString(r.left, r.right, y, STR_COMPANY_VIEW_VEHICLES_NONE);
01862 } else {
01863 assert_compile(lengthof(amounts) == lengthof(_company_view_vehicle_count_strings));
01864
01865 for (uint i = 0; i < lengthof(amounts); i++) {
01866 if (amounts[i] != 0) {
01867 SetDParam(0, amounts[i]);
01868 DrawString(r.left, r.right, y, _company_view_vehicle_count_strings[i]);
01869 y += FONT_HEIGHT_NORMAL;
01870 }
01871 }
01872 }
01873 } break;
01874
01875 case CW_WIDGET_DESC_OWNERS: {
01876 const Company *c2;
01877 uint y = r.top;
01878
01879 FOR_ALL_COMPANIES(c2) {
01880 uint amt = GetAmountOwnedBy(c, c2->index);
01881 if (amt != 0) {
01882 SetDParam(0, amt * 25);
01883 SetDParam(1, c2->index);
01884
01885 DrawString(r.left, r.right, y, STR_COMPANY_VIEW_SHARES_OWNED_BY);
01886 y += FONT_HEIGHT_NORMAL;
01887 }
01888 }
01889 } break;
01890
01891 #ifdef ENABLE_NETWORK
01892 case CW_WIDGET_HAS_PASSWORD:
01893 if (_networking && NetworkCompanyIsPassworded(c->index)) {
01894 DrawSprite(SPR_LOCK, PAL_NONE, r.left, r.top);
01895 }
01896 break;
01897 #endif
01898 }
01899 }
01900
01901 virtual void SetStringParameters(int widget) const
01902 {
01903 switch (widget) {
01904 case CW_WIDGET_CAPTION:
01905 SetDParam(0, (CompanyID)this->window_number);
01906 SetDParam(1, (CompanyID)this->window_number);
01907 break;
01908
01909 case CW_WIDGET_DESC_INAUGURATION:
01910 SetDParam(0, Company::Get((CompanyID)this->window_number)->inaugurated_year);
01911 break;
01912
01913 case CW_WIDGET_DESC_COMPANY_VALUE:
01914 SetDParam(0, CalculateCompanyValue(Company::Get((CompanyID)this->window_number)));
01915 break;
01916 }
01917 }
01918
01919 virtual void OnClick(Point pt, int widget, int click_count)
01920 {
01921 switch (widget) {
01922 case CW_WIDGET_NEW_FACE: DoSelectCompanyManagerFace(this); break;
01923
01924 case CW_WIDGET_COLOUR_SCHEME:
01925 if (BringWindowToFrontById(WC_COMPANY_COLOUR, this->window_number)) break;
01926 new SelectCompanyLiveryWindow(&_select_company_livery_desc, (CompanyID)this->window_number);
01927 break;
01928
01929 case CW_WIDGET_PRESIDENT_NAME:
01930 this->query_widget = CW_WIDGET_PRESIDENT_NAME;
01931 SetDParam(0, this->window_number);
01932 ShowQueryString(STR_PRESIDENT_NAME, STR_COMPANY_VIEW_PRESIDENT_S_NAME_QUERY_CAPTION, MAX_LENGTH_PRESIDENT_NAME_BYTES, MAX_LENGTH_PRESIDENT_NAME_PIXELS, this, CS_ALPHANUMERAL, QSF_ENABLE_DEFAULT);
01933 break;
01934
01935 case CW_WIDGET_COMPANY_NAME:
01936 this->query_widget = CW_WIDGET_COMPANY_NAME;
01937 SetDParam(0, this->window_number);
01938 ShowQueryString(STR_COMPANY_NAME, STR_COMPANY_VIEW_COMPANY_NAME_QUERY_CAPTION, MAX_LENGTH_COMPANY_NAME_BYTES, MAX_LENGTH_COMPANY_NAME_PIXELS, this, CS_ALPHANUMERAL, QSF_ENABLE_DEFAULT);
01939 break;
01940
01941 case CW_WIDGET_VIEW_HQ: {
01942 TileIndex tile = Company::Get((CompanyID)this->window_number)->location_of_HQ;
01943 if (_ctrl_pressed) {
01944 ShowExtraViewPortWindow(tile);
01945 } else {
01946 ScrollMainWindowToTile(tile);
01947 }
01948 break;
01949 }
01950
01951 case CW_WIDGET_BUILD_HQ:
01952 if ((byte)this->window_number != _local_company) return;
01953 SetObjectToPlaceWnd(SPR_CURSOR_HQ, PAL_NONE, HT_RECT, this);
01954 SetTileSelectSize(2, 2);
01955 this->LowerWidget(CW_WIDGET_BUILD_HQ);
01956 this->SetWidgetDirty(CW_WIDGET_BUILD_HQ);
01957 break;
01958
01959 case CW_WIDGET_RELOCATE_HQ:
01960 SetObjectToPlaceWnd(SPR_CURSOR_HQ, PAL_NONE, HT_RECT, this);
01961 SetTileSelectSize(2, 2);
01962 this->LowerWidget(CW_WIDGET_RELOCATE_HQ);
01963 this->SetWidgetDirty(CW_WIDGET_RELOCATE_HQ);
01964 break;
01965
01966 case CW_WIDGET_BUY_SHARE:
01967 DoCommandP(0, this->window_number, 0, CMD_BUY_SHARE_IN_COMPANY | CMD_MSG(STR_ERROR_CAN_T_BUY_25_SHARE_IN_THIS));
01968 break;
01969
01970 case CW_WIDGET_SELL_SHARE:
01971 DoCommandP(0, this->window_number, 0, CMD_SELL_SHARE_IN_COMPANY | CMD_MSG(STR_ERROR_CAN_T_SELL_25_SHARE_IN));
01972 break;
01973
01974 #ifdef ENABLE_NETWORK
01975 case CW_WIDGET_COMPANY_PASSWORD:
01976 if (this->window_number == _local_company) ShowNetworkCompanyPasswordWindow(this);
01977 break;
01978
01979 case CW_WIDGET_COMPANY_JOIN: {
01980 this->query_widget = CW_WIDGET_COMPANY_JOIN;
01981 CompanyID company = (CompanyID)this->window_number;
01982 if (_network_server) {
01983 NetworkServerDoMove(CLIENT_ID_SERVER, company);
01984 MarkWholeScreenDirty();
01985 } else if (NetworkCompanyIsPassworded(company)) {
01986
01987 ShowQueryString(STR_EMPTY, STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION, 20, 180, this, CS_ALPHANUMERAL, QSF_NONE);
01988 } else {
01989
01990 NetworkClientRequestMove(company);
01991 }
01992 break;
01993 }
01994 #endif
01995 }
01996 }
01997
01998 virtual void OnHundredthTick()
01999 {
02000
02001 this->SetDirty();
02002 }
02003
02004 virtual void OnPlaceObject(Point pt, TileIndex tile)
02005 {
02006 if (DoCommandP(tile, 0, 0, CMD_BUILD_COMPANY_HQ | CMD_MSG(STR_ERROR_CAN_T_BUILD_COMPANY_HEADQUARTERS))) {
02007 ResetObjectToPlace();
02008 this->RaiseButtons();
02009 }
02010 }
02011
02012 virtual void OnPlaceObjectAbort()
02013 {
02014 this->RaiseButtons();
02015 }
02016
02017 virtual void OnQueryTextFinished(char *str)
02018 {
02019 if (str == NULL) return;
02020
02021 switch (this->query_widget) {
02022 default: NOT_REACHED();
02023
02024 case CW_WIDGET_PRESIDENT_NAME:
02025 DoCommandP(0, 0, 0, CMD_RENAME_PRESIDENT | CMD_MSG(STR_ERROR_CAN_T_CHANGE_PRESIDENT), NULL, str);
02026 break;
02027
02028 case CW_WIDGET_COMPANY_NAME:
02029 DoCommandP(0, 0, 0, CMD_RENAME_COMPANY | CMD_MSG(STR_ERROR_CAN_T_CHANGE_COMPANY_NAME), NULL, str);
02030 break;
02031
02032 #ifdef ENABLE_NETWORK
02033 case CW_WIDGET_COMPANY_JOIN:
02034 NetworkClientRequestMove((CompanyID)this->window_number, str);
02035 break;
02036 #endif
02037 }
02038 }
02039 };
02040
02041 static const WindowDesc _company_desc(
02042 WDP_AUTO, 0, 0,
02043 WC_COMPANY, WC_NONE,
02044 WDF_UNCLICK_BUTTONS,
02045 _nested_company_widgets, lengthof(_nested_company_widgets)
02046 );
02047
02048 void ShowCompany(CompanyID company)
02049 {
02050 if (!Company::IsValidID(company)) return;
02051
02052 AllocateWindowDescFront<CompanyWindow>(&_company_desc, company);
02053 }
02054
02056 enum BuyCompanyWidgets {
02057 BCW_CAPTION,
02058 BCW_FACE,
02059 BCW_QUESTION,
02060 BCW_NO,
02061 BCW_YES,
02062 };
02063
02064 struct BuyCompanyWindow : Window {
02065 BuyCompanyWindow(const WindowDesc *desc, WindowNumber window_number) : Window()
02066 {
02067 this->InitNested(desc, window_number);
02068 }
02069
02070 virtual void OnPaint()
02071 {
02072 this->DrawWidgets();
02073 }
02074
02075 virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
02076 {
02077 switch (widget) {
02078 case BCW_FACE:
02079 *size = GetSpriteSize(SPR_GRADIENT);
02080 break;
02081
02082 case BCW_QUESTION:
02083 const Company *c = Company::Get((CompanyID)this->window_number);
02084 SetDParam(0, c->index);
02085 SetDParam(1, c->bankrupt_value);
02086 size->height = GetStringHeight(STR_BUY_COMPANY_MESSAGE, size->width);
02087 break;
02088 }
02089 }
02090
02091 virtual void SetStringParameters(int widget) const
02092 {
02093 switch (widget) {
02094 case BCW_CAPTION:
02095 SetDParam(0, STR_COMPANY_NAME);
02096 SetDParam(1, Company::Get((CompanyID)this->window_number)->index);
02097 break;
02098 }
02099 }
02100
02101 virtual void DrawWidget(const Rect &r, int widget) const
02102 {
02103 switch (widget) {
02104 case BCW_FACE: {
02105 const Company *c = Company::Get((CompanyID)this->window_number);
02106 DrawCompanyManagerFace(c->face, c->colour, r.left, r.top);
02107 } break;
02108
02109 case BCW_QUESTION: {
02110 const Company *c = Company::Get((CompanyID)this->window_number);
02111 SetDParam(0, c->index);
02112 SetDParam(1, c->bankrupt_value);
02113 DrawStringMultiLine(r.left, r.right, r.top, r.bottom, STR_BUY_COMPANY_MESSAGE, TC_FROMSTRING, SA_CENTER);
02114 } break;
02115 }
02116 }
02117
02118 virtual void OnClick(Point pt, int widget, int click_count)
02119 {
02120 switch (widget) {
02121 case BCW_NO:
02122 delete this;
02123 break;
02124
02125 case BCW_YES:
02126 DoCommandP(0, this->window_number, 0, CMD_BUY_COMPANY | CMD_MSG(STR_ERROR_CAN_T_BUY_COMPANY));
02127 break;
02128 }
02129 }
02130 };
02131
02132 static const NWidgetPart _nested_buy_company_widgets[] = {
02133 NWidget(NWID_HORIZONTAL),
02134 NWidget(WWT_CLOSEBOX, COLOUR_LIGHT_BLUE),
02135 NWidget(WWT_CAPTION, COLOUR_LIGHT_BLUE, BCW_CAPTION), SetDataTip(STR_ERROR_MESSAGE_CAPTION_OTHER_COMPANY, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
02136 EndContainer(),
02137 NWidget(WWT_PANEL, COLOUR_LIGHT_BLUE),
02138 NWidget(NWID_VERTICAL), SetPIP(8, 8, 8),
02139 NWidget(NWID_HORIZONTAL), SetPIP(8, 10, 8),
02140 NWidget(WWT_EMPTY, INVALID_COLOUR, BCW_FACE), SetFill(0, 1),
02141 NWidget(WWT_EMPTY, INVALID_COLOUR, BCW_QUESTION), SetMinimalSize(240, 0), SetFill(1, 1),
02142 EndContainer(),
02143 NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(100, 10, 100),
02144 NWidget(WWT_TEXTBTN, COLOUR_LIGHT_BLUE, BCW_NO), SetMinimalSize(60, 12), SetDataTip(STR_QUIT_NO, STR_NULL), SetFill(1, 0),
02145 NWidget(WWT_TEXTBTN, COLOUR_LIGHT_BLUE, BCW_YES), SetMinimalSize(60, 12), SetDataTip(STR_QUIT_YES, STR_NULL), SetFill(1, 0),
02146 EndContainer(),
02147 EndContainer(),
02148 EndContainer(),
02149 };
02150
02151 static const WindowDesc _buy_company_desc(
02152 WDP_AUTO, 0, 0,
02153 WC_BUY_COMPANY, WC_NONE,
02154 WDF_CONSTRUCTION,
02155 _nested_buy_company_widgets, lengthof(_nested_buy_company_widgets)
02156 );
02157
02158
02159 void ShowBuyCompanyDialog(CompanyID company)
02160 {
02161 AllocateWindowDescFront<BuyCompanyWindow>(&_buy_company_desc, company);
02162 }