Loading

Paste #pcvfymzoe

  1. /**
  2.  * Window that let you choose an available AI.
  3.  */
  4. struct AIListWindow : public Window {
  5.     const ScriptInfoList *info_list;    ///< The list of Scripts.
  6.     int selected;                       ///< The currently selected Script.
  7.     CompanyID slot;                     ///< The company we're selecting a new Script for.
  8.     int line_height;                    ///< Height of a row in the matrix widget.
  9.     Scrollbar *vscroll;                 ///< Cache of the vertical scrollbar.
  10.  
  11.     /**
  12.      * Constructor for the window.
  13.      * @param desc The description of the window.
  14.      * @param slot The company we're changing the AI for.
  15.      */
  16.     AIListWindow(WindowDesc *desc, CompanyID slot) : Window(desc),
  17.         slot(slot)
  18.     {
  19.         if (slot == OWNER_DEITY) {
  20.             this->info_list = Game::GetUniqueInfoList();
  21.         } else {
  22.             this->info_list = AI::GetUniqueInfoList();
  23.         }
  24.  
  25.         this->CreateNestedTree();
  26.         this->vscroll = this->GetScrollbar(WID_AIL_SCROLLBAR);
  27.         this->FinishInitNested(); // Initializes 'this->line_height' as side effect.
  28.  
  29.         this->vscroll->SetCount((int)this->info_list->size() + 1);
  30.  
  31.         /* Try if we can find the currently selected AI */
  32.         this->selected = -1;
  33.         if (GetConfig(slot)->HasScript()) {
  34.             ScriptInfo *info = GetConfig(slot)->GetInfo();
  35.             int i = 0;
  36.             for (ScriptInfoList::const_iterator it = this->info_list->begin(); it != this->info_list->end(); it++, i++) {
  37.                 if ((*it).second == info) {
  38.                     this->selected = i;
  39.                     break;
  40.                 }
  41.             }
  42.         }
  43.     }
  44.  
  45.     virtual void SetStringParameters(int widget) const
  46.     {
  47.         switch (widget) {
  48.             case WID_AIL_CAPTION:
  49.                 SetDParam(0, (this->slot == OWNER_DEITY) ? STR_AI_LIST_CAPTION_GAMESCRIPT : STR_AI_LIST_CAPTION_AI);
  50.                 break;
  51.         }
  52.     }
  53.  
  54.     virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
  55.     {
  56.         if (widget == WID_AIL_LIST) {
  57.             this->line_height = max((uint)FONT_HEIGHT_NORMAL, GetSpriteSize(SPR_AICONFIG_RANDOM).height) + WD_MATRIX_TOP + WD_MATRIX_BOTTOM;
  58.  
  59.             resize->width = 1;
  60.             resize->height = this->line_height;
  61.             size->height = 5 * this->line_height;
  62.         }
  63.     }
  64.  
  65.     virtual void DrawWidget(const Rect &r, int widget) const
  66.     {
  67.         switch (widget) {
  68.             case WID_AIL_LIST: {
  69.                 /* Draw a list of all available AIs. */
  70.                 int y = this->GetWidget<NWidgetBase>(WID_AIL_LIST)->pos_y;
  71.                 Dimension rai = GetSpriteSize(SPR_AICONFIG_RANDOM);
  72.                 uint rai_y_offset = (line_height - rai.height) / 2;
  73.                 /* First AI in the list is hardcoded to random */
  74.                 if (this->vscroll->IsVisible(0)) {
  75.                     StringID text = STR_AI_CONFIG_RANDOM_AI;
  76.                     if (this->slot == OWNER_DEITY) text = STR_AI_CONFIG_NONE;
  77.                     if (text == STR_AI_CONFIG_RANDOM_AI) DrawSprite(SPR_AICONFIG_RANDOM, PAL_NONE, r.left + WD_MATRIX_LEFT, r.left + WD_MATRIX_LEFT + GetSpriteSize(SPR_AICONFIG_RANDOM).width, y + rai_y_offset);
  78.                     DrawString(r.left + WD_MATRIX_LEFT + GetSpriteSize(SPR_AICONFIG_RANDOM).width + 10, r.right - WD_MATRIX_LEFT, y + WD_MATRIX_TOP, text, this->selected == -1 ? TC_WHITE : TC_ORANGE);
  79.                     y += this->line_height;
  80.                 }
  81.                 ScriptInfoList::const_iterator it = this->info_list->begin();
  82.                 for (int i = 1; it != this->info_list->end(); i++, it++) {
  83.                     if (this->vscroll->IsVisible(i)) {
  84.                         DrawString(r.left + WD_MATRIX_LEFT, r.right - WD_MATRIX_RIGHT, y + WD_MATRIX_TOP, (*it).second->GetName(), (this->selected == i - 1) ? TC_WHITE : TC_ORANGE);
  85.                         y += this->line_height;
  86.                     }
  87.                 }
  88.                 break;
  89.             }
  90.             case WID_AIL_INFO_BG: {
  91.                 AIInfo *selected_info = NULL;
  92.                 ScriptInfoList::const_iterator it = this->info_list->begin();
  93.                 for (int i = 1; selected_info == NULL && it != this->info_list->end(); i++, it++) {
  94.                     if (this->selected == i - 1) selected_info = static_cast<AIInfo *>((*it).second);
  95.                 }
  96.                 /* Some info about the currently selected AI. */
  97.                 if (selected_info != NULL) {
  98.                     int y = r.top + WD_FRAMERECT_TOP;
  99.                     SetDParamStr(0, selected_info->GetAuthor());
  100.                     DrawString(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, y, STR_AI_LIST_AUTHOR);
  101.                     y += FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL;
  102.                     SetDParam(0, selected_info->GetVersion());
  103.                     DrawString(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, y, STR_AI_LIST_VERSION);
  104.                     y += FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL;
  105.                     if (selected_info->GetURL() != NULL) {
  106.                         SetDParamStr(0, selected_info->GetURL());
  107.                         DrawString(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, y, STR_AI_LIST_URL);
  108.                         y += FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL;
  109.                     }
  110.                     SetDParamStr(0, selected_info->GetDescription());
  111.                     DrawStringMultiLine(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, y, r.bottom - WD_FRAMERECT_BOTTOM, STR_JUST_RAW_STRING, TC_WHITE);
  112.                 }
  113.                 break;
  114.             }
  115.         }
  116.     }
  117.  
  118.     /**
  119.      * Changes the AI of the current slot.
  120.      */
  121.     void ChangeAI()
  122.     {
  123.         if (this->selected == -1) {
  124.             GetConfig(slot)->Change(NULL);
  125.         } else {
  126.             ScriptInfoList::const_iterator it = this->info_list->begin();
  127.             for (int i = 0; i < this->selected; i++) it++;
  128.             GetConfig(slot)->Change((*it).second->GetName(), (*it).second->GetVersion());
  129.         }
  130.         InvalidateWindowData(WC_GAME_OPTIONS, WN_GAME_OPTIONS_AI);
  131.         DeleteWindowByClass(WC_AI_SETTINGS);
  132.         DeleteWindowByClass(WC_TEXTFILE);
  133.         DeleteWindowByClass(WC_QUERY_STRING);
  134.     }
  135.  
  136.     virtual void OnClick(Point pt, int widget, int click_count)
  137.     {
  138.         switch (widget) {
  139.             case WID_AIL_LIST: { // Select one of the AIs
  140.                 int sel = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_AIL_LIST, 0, this->line_height) - 1;
  141.                 if (sel < (int)this->info_list->size()) {
  142.                     this->selected = sel;
  143.                     this->SetDirty();
  144.                     if (click_count > 1) {
  145.                         this->ChangeAI();
  146.                         delete this;
  147.                     }
  148.                 }
  149.                 break;
  150.             }
  151.  
  152.             case WID_AIL_ACCEPT: {
  153.                 this->ChangeAI();
  154.                 delete this;
  155.                 break;
  156.             }
  157.  
  158.             case WID_AIL_CANCEL:
  159.                 delete this;
  160.                 break;
  161.         }
  162.     }
  163.  
  164.     virtual void OnResize()
  165.     {
  166.         this->vscroll->SetCapacityFromWidget(this, WID_AIL_LIST);
  167.     }
  168.  
  169.     /**
  170.      * Some data on this window has become invalid.
  171.      * @param data Information about the changed data.
  172.      * @param gui_scope Whether the call is done from GUI scope. You may not do everything when not in GUI scope. See #InvalidateWindowData() for details.
  173.      */
  174.     virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
  175.     {
  176.         if (_game_mode == GM_NORMAL && Company::IsValidID(this->slot)) {
  177.             delete this;
  178.             return;
  179.         }
  180.  
  181.         if (!gui_scope) return;
  182.  
  183.         this->vscroll->SetCount((int)this->info_list->size() + 1);
  184.  
  185.         /* selected goes from -1 .. length of ai list - 1. */
  186.         this->selected = min(this->selected, this->vscroll->GetCount() - 2);
  187.     }
  188. };

Comments