Loading

Paste #pmqd87lcm

  1. typedef std::vector<const ScriptConfigItem *> VisibleSettingsList;
  2. static VisibleSettingsList BuildVisibleSettingsList(CompanyID slot)
  3. {
  4.     VisibleSettingsList visible_settings; ///< List of visible AI settings
  5.     ScriptConfig *config_list = GetConfig(slot);
  6.  
  7.     ScriptConfigItemList::const_iterator it = config_list->GetConfigList()->begin();
  8.     for (; it != config_list->GetConfigList()->end(); it++) {
  9.         bool no_hide = (it->flags & SCRIPTCONFIG_DEVELOPER) == 0;
  10.         if (no_hide || _settings_client.gui.ai_developer_tools) {
  11.             visible_settings.push_back(&(*it));
  12.         }
  13.     }
  14.  
  15.     return visible_settings;
  16. }
  17.  
  18.  
  19. ////BLA BLA CODE ////
  20.  
  21. /**
  22.  * Window for settings the parameters of an AI.
  23.  */
  24. struct AISettingsWindow : public Window {
  25.     CompanyID slot;                       ///< The currently show company's setting.
  26.     ScriptConfig *ai_config;              ///< The configuration we're modifying.
  27.     int clicked_button;                   ///< The button we clicked.
  28.     bool clicked_increase;                ///< Whether we clicked the increase or decrease button.
  29.     bool clicked_dropdown;                ///< Whether the dropdown is open.
  30.     bool closing_dropdown;                ///< True, if the dropdown list is currently closing.
  31.     GUITimer timeout;                     ///< Timeout for unclicking the button.
  32.     int clicked_row;                      ///< The clicked row of settings.
  33.     int line_height;                      ///< Height of a row in the matrix widget.
  34.     Scrollbar *vscroll;                   ///< Cache of the vertical scrollbar.
  35.     VisibleSettingsList visible_settings; ///< List of visible AI settings
  36.  
  37.     /**
  38.      * Constructor for the window.
  39.      * @param desc The description of the window.
  40.      * @param slot The company we're changing the settings for.
  41.      */
  42.     AISettingsWindow(WindowDesc *desc, CompanyID slot) : Window(desc),
  43.         slot(slot),
  44.         clicked_button(-1),
  45.         clicked_dropdown(false),
  46.         closing_dropdown(false),
  47.         timeout(0)
  48.     {
  49.         this->ai_config = GetConfig(slot);
  50.  
  51.         this->CreateNestedTree();
  52.         this->vscroll = this->GetScrollbar(WID_AIS_SCROLLBAR);
  53.         this->FinishInitNested(slot);  // Initializes 'this->line_height' as side effect.
  54.  
  55.         this->SetWidgetDisabledState(WID_AIS_RESET, _game_mode == GM_EDITOR && !IsConsideredDead(this->slot));
  56.  
  57.         this->RebuildVisibleSettings();
  58.     }
  59.  
  60.     virtual void SetStringParameters(int widget) const
  61.     {
  62.         switch (widget) {
  63.             case WID_AIS_CAPTION:
  64.                 SetDParam(0, (this->slot == OWNER_DEITY) ? STR_AI_SETTINGS_CAPTION_GAMESCRIPT : STR_AI_SETTINGS_CAPTION_AI);
  65.                 break;
  66.         }
  67.     }
  68.  
  69.     /**
  70.      * Rebuilds the list of visible settings. AI settings with the flag
  71.      * SCRIPTCONFIG_DEVELOPER set will only be visible if the client setting
  72.      * gui.ai_developer_tools is enabled.
  73.      */
  74.     void RebuildVisibleSettings()
  75.     {
  76.         this->ai_config = GetConfig(slot);
  77.         visible_settings.clear();
  78.         visible_settings.swap(BuildVisibleSettingsList(slot));
  79.  
  80.         this->vscroll->SetCount((int)this->visible_settings.size());
  81.     }
  82.  
  83.     virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
  84.     {
  85.         if (widget == WID_AIS_BACKGROUND) {
  86.             this->line_height = max(SETTING_BUTTON_HEIGHT, FONT_HEIGHT_NORMAL) + WD_MATRIX_TOP + WD_MATRIX_BOTTOM;
  87.  
  88.             resize->width = 1;
  89.             resize->height = this->line_height;
  90.             size->height = 5 * this->line_height;
  91.         }
  92.     }
  93.  
  94.     virtual void DrawWidget(const Rect &r, int widget) const
  95.     {
  96.         if (widget != WID_AIS_BACKGROUND) return;
  97.  
  98.         ScriptConfig *config = this->ai_config;
  99.         VisibleSettingsList::const_iterator it = this->visible_settings.begin();
  100.         int i = 0;
  101.         for (; !this->vscroll->IsVisible(i); i++) it++;
  102.  
  103.         bool rtl = _current_text_dir == TD_RTL;
  104.         uint buttons_left = rtl ? r.right - SETTING_BUTTON_WIDTH - 3 : r.left + 4;
  105.         uint text_left    = r.left + (rtl ? WD_FRAMERECT_LEFT : SETTING_BUTTON_WIDTH + 8);
  106.         uint text_right   = r.right - (rtl ? SETTING_BUTTON_WIDTH + 8 : WD_FRAMERECT_RIGHT);
  107.  
  108.  
  109.         int y = r.top;
  110.         int button_y_offset = (this->line_height - SETTING_BUTTON_HEIGHT) / 2;
  111.         int text_y_offset = (this->line_height - FONT_HEIGHT_NORMAL) / 2;
  112.         for (; this->vscroll->IsVisible(i) && it != visible_settings.end(); i++, it++) {
  113.             const ScriptConfigItem &config_item = **it;
  114.             int current_value = config->GetSetting((config_item).name);
  115.             bool editable = this->IsEditableItem(config_item);
  116.  
  117.             StringID str;
  118.             TextColour colour;
  119.             uint idx = 0;
  120.             if (StrEmpty(config_item.description)) {
  121.                 if (!strcmp(config_item.name, "start_date")) {
  122.                     /* Build-in translation */
  123.                     str = STR_AI_SETTINGS_START_DELAY;
  124.                     colour = TC_LIGHT_BLUE;
  125.                 } else {
  126.                     str = STR_JUST_STRING;
  127.                     colour = TC_ORANGE;
  128.                 }
  129.             } else {
  130.                 str = STR_AI_SETTINGS_SETTING;
  131.                 colour = TC_LIGHT_BLUE;
  132.                 SetDParamStr(idx++, config_item.description);
  133.             }
  134.  
  135.             if ((config_item.flags & SCRIPTCONFIG_BOOLEAN) != 0) {
  136.                 DrawBoolButton(buttons_left, y + button_y_offset, current_value != 0, editable);
  137.                 SetDParam(idx++, current_value == 0 ? STR_CONFIG_SETTING_OFF : STR_CONFIG_SETTING_ON);
  138.             } else {
  139.                 if (config_item.complete_labels) {
  140.                     DrawDropDownButton(buttons_left, y + button_y_offset, COLOUR_YELLOW, this->clicked_row == i && clicked_dropdown, editable);
  141.                 } else {
  142.                     DrawArrowButtons(buttons_left, y + button_y_offset, COLOUR_YELLOW, (this->clicked_button == i) ? 1 + (this->clicked_increase != rtl) : 0, editable && current_value > config_item.min_value, editable && current_value < config_item.max_value);
  143.                 }
  144.                 if (config_item.labels != NULL && config_item.labels->Contains(current_value)) {
  145.                     SetDParam(idx++, STR_JUST_RAW_STRING);
  146.                     SetDParamStr(idx++, config_item.labels->Find(current_value)->second);
  147.                 } else {
  148.                     SetDParam(idx++, STR_JUST_INT);
  149.                     SetDParam(idx++, current_value);
  150.                 }
  151.             }
  152.  
  153.             DrawString(text_left, text_right, y + text_y_offset, str, colour);
  154.             y += this->line_height;
  155.         }
  156.     }
  157.  
  158.     virtual void OnPaint()
  159.     {
  160.         if (this->closing_dropdown) {
  161.             this->closing_dropdown = false;
  162.             this->clicked_dropdown = false;
  163.         }
  164.         this->DrawWidgets();
  165.     }
  166.  
  167.     virtual void OnClick(Point pt, int widget, int click_count)
  168.     {
  169.         switch (widget) {
  170.             case WID_AIS_BACKGROUND: {
  171.                 const NWidgetBase *wid = this->GetWidget<NWidgetBase>(WID_AIS_BACKGROUND);
  172.                 int num = (pt.y - wid->pos_y) / this->line_height + this->vscroll->GetPosition();
  173.                 if (num >= (int)this->visible_settings.size()) break;
  174.  
  175.                 VisibleSettingsList::const_iterator it = this->visible_settings.begin();
  176.                 for (int i = 0; i < num; i++) it++;
  177.                 const ScriptConfigItem config_item = **it;
  178.                 if (!this->IsEditableItem(config_item)) return;
  179.  
  180.                 if (this->clicked_row != num) {
  181.                     DeleteChildWindows(WC_QUERY_STRING);
  182.                     HideDropDownMenu(this);
  183.                     this->clicked_row = num;
  184.                     this->clicked_dropdown = false;
  185.                 }
  186.  
  187.                 bool bool_item = (config_item.flags & SCRIPTCONFIG_BOOLEAN) != 0;
  188.  
  189.                 int x = pt.x - wid->pos_x;
  190.                 if (_current_text_dir == TD_RTL) x = wid->current_x - 1 - x;
  191.                 x -= 4;
  192.  
  193.                 /* One of the arrows is clicked (or green/red rect in case of bool value) */
  194.                 int old_val = this->ai_config->GetSetting(config_item.name);
  195.                 if (!bool_item && IsInsideMM(x, 0, SETTING_BUTTON_WIDTH) && config_item.complete_labels) {
  196.                     if (this->clicked_dropdown) {
  197.                         /* unclick the dropdown */
  198.                         HideDropDownMenu(this);
  199.                         this->clicked_dropdown = false;
  200.                         this->closing_dropdown = false;
  201.                     } else {
  202.                         const NWidgetBase *wid = this->GetWidget<NWidgetBase>(WID_AIS_BACKGROUND);
  203.                         int rel_y = (pt.y - (int)wid->pos_y) % this->line_height;
  204.  
  205.                         Rect wi_rect;
  206.                         wi_rect.left = pt.x - (_current_text_dir == TD_RTL ? SETTING_BUTTON_WIDTH - 1 - x : x);
  207.                         wi_rect.right = wi_rect.left + SETTING_BUTTON_WIDTH - 1;
  208.                         wi_rect.top = pt.y - rel_y + (this->line_height - SETTING_BUTTON_HEIGHT) / 2;
  209.                         wi_rect.bottom = wi_rect.top + SETTING_BUTTON_HEIGHT - 1;
  210.  
  211.                         /* For dropdowns we also have to check the y position thoroughly, the mouse may not above the just opening dropdown */
  212.                         if (pt.y >= wi_rect.top && pt.y <= wi_rect.bottom) {
  213.                             this->clicked_dropdown = true;
  214.                             this->closing_dropdown = false;
  215.  
  216.                             DropDownList *list = new DropDownList();
  217.                             for (int i = config_item.min_value; i <= config_item.max_value; i++) {
  218.                                 *list->Append() = new DropDownListCharStringItem(config_item.labels->Find(i)->second, i, false);
  219.                             }
  220.  
  221.                             ShowDropDownListAt(this, list, old_val, -1, wi_rect, COLOUR_ORANGE, true);
  222.                         }
  223.                     }
  224.                 } else if (IsInsideMM(x, 0, SETTING_BUTTON_WIDTH)) {
  225.                     int new_val = old_val;
  226.                     if (bool_item) {
  227.                         new_val = !new_val;
  228.                     } else if (x >= SETTING_BUTTON_WIDTH / 2) {
  229.                         /* Increase button clicked */
  230.                         new_val += config_item.step_size;
  231.                         if (new_val > config_item.max_value) new_val = config_item.max_value;
  232.                         this->clicked_increase = true;
  233.                     } else {
  234.                         /* Decrease button clicked */
  235.                         new_val -= config_item.step_size;
  236.                         if (new_val < config_item.min_value) new_val = config_item.min_value;
  237.                         this->clicked_increase = false;
  238.                     }
  239.  
  240.                     if (new_val != old_val) {
  241.                         this->ai_config->SetSetting(config_item.name, new_val);
  242.                         this->clicked_button = num;
  243.                         this->timeout.SetInterval(150);
  244.                     }
  245.                 } else if (!bool_item && !config_item.complete_labels) {
  246.                     /* Display a query box so users can enter a custom value. */
  247.                     SetDParam(0, old_val);
  248.                     ShowQueryString(STR_JUST_INT, STR_CONFIG_SETTING_QUERY_CAPTION, 10, this, CS_NUMERAL, QSF_NONE);
  249.                 }
  250.                 this->SetDirty();
  251.                 break;
  252.             }
  253.  
  254.             case WID_AIS_ACCEPT:
  255.                 delete this;
  256.                 break;
  257.  
  258.             case WID_AIS_RESET:
  259.                 if (_game_mode != GM_EDITOR || IsConsideredDead(this->slot)) {
  260.                     this->ai_config->ResetSettingsGUI(IsConsideredDead(this->slot));
  261.                     this->SetDirty();
  262.                 }
  263.                 break;
  264.         }
  265.     }
  266.  
  267.     virtual void OnQueryTextFinished(char *str)
  268.     {
  269.         if (StrEmpty(str)) return;
  270.         VisibleSettingsList::const_iterator it = this->visible_settings.begin();
  271.         for (int i = 0; i < this->clicked_row; i++) it++;
  272.         const ScriptConfigItem config_item = **it;
  273.         if (_game_mode != GM_MENU && !IsConsideredDead(this->slot) && (config_item.flags & SCRIPTCONFIG_INGAME) == 0) return;
  274.         int32 value = atoi(str);
  275.         this->ai_config->SetSetting(config_item.name, value);
  276.         this->SetDirty();
  277.     }
  278.  
  279.     virtual void OnDropdownSelect(int widget, int index)
  280.     {
  281.         assert(this->clicked_dropdown);
  282.         VisibleSettingsList::const_iterator it = this->visible_settings.begin();
  283.         for (int i = 0; i < this->clicked_row; i++) it++;
  284.         const ScriptConfigItem config_item = **it;
  285.         if (_game_mode != GM_MENU && !IsConsideredDead(this->slot) && (config_item.flags & SCRIPTCONFIG_INGAME) == 0) return;
  286.         this->ai_config->SetSetting(config_item.name, index);
  287.         this->SetDirty();
  288.     }
  289.  
  290.     virtual void OnDropdownClose(Point pt, int widget, int index, bool instant_close)
  291.     {
  292.         /* We cannot raise the dropdown button just yet. OnClick needs some hint, whether
  293.          * the same dropdown button was clicked again, and then not open the dropdown again.
  294.          * So, we only remember that it was closed, and process it on the next OnPaint, which is
  295.          * after OnClick. */
  296.         assert(this->clicked_dropdown);
  297.         this->closing_dropdown = true;
  298.         this->SetDirty();
  299.     }
  300.  
  301.     virtual void OnResize()
  302.     {
  303.         this->vscroll->SetCapacityFromWidget(this, WID_AIS_BACKGROUND);
  304.     }
  305.  
  306.     virtual void OnRealtimeTick(uint delta_ms)
  307.     {
  308.         if (this->timeout.Elapsed(delta_ms)) {
  309.             this->clicked_button = -1;
  310.             this->SetDirty();
  311.         }
  312.     }
  313.  
  314.     /**
  315.      * Some data on this window has become invalid.
  316.      * @param data Information about the changed data.
  317.      * @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.
  318.      */
  319.     virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
  320.     {
  321.         this->RebuildVisibleSettings();
  322.         HideDropDownMenu(this);
  323.         DeleteChildWindows(WC_QUERY_STRING);
  324.     }
  325.  
  326. private:
  327.     bool IsEditableItem(const ScriptConfigItem config_item) const
  328.     {
  329.         if (_game_mode == GM_MENU) return true;
  330.  
  331.         if (_game_mode == GM_NORMAL) {
  332.             if (IsConsideredDead(slot)) return true;
  333.             if (config_item.flags & SCRIPTCONFIG_INGAME) return true;
  334.         }
  335.  
  336.         if (IsConsideredDead(slot)) {
  337.             if (slot == OWNER_DEITY) {
  338.                 if (Game::GetInstance() == NULL) return true;
  339.             }
  340.             if (!Company::IsValidAiID(slot)) return true;
  341.             if (Company::Get(slot)->ai_instance == NULL) return true;
  342.         }
  343.  
  344.         return false;
  345.     }
  346. };

Version history

Revision # Author Created at
paiimwyt5 Anonymous 28 Jan 2019, 18:18:37 UTC Diff

Comments