(svn r25052) -Fix [FS#5490]: Refactor Script Debug GUI to only set widget states in OnInvalidateData.

replace/41b28d7194a279bdc17475d4fbe2ea6ec885a466
frosch 11 years ago
parent 0c582e409e
commit 9b06e79765

@ -1000,6 +1000,43 @@ struct AIDebugWindow : public Window {
return !Company::IsValidAiID(ai_debug_company) || Company::Get(ai_debug_company)->ai_instance->IsDead();
}
/**
* Check whether a company is a valid AI company or GS.
* @param company Company to check for validity.
* @return true if company is valid for debugging.
*/
bool IsValidDebugCompany(CompanyID company) const
{
switch (company) {
case INVALID_COMPANY: return false;
case OWNER_DEITY: return Game::GetInstance() != NULL;
default: return Company::IsValidAiID(company);
}
}
/**
* Ensure that \c ai_debug_company refers to a valid AI company or GS, or is set to #INVALID_COMPANY.
* If no valid company is selected, it selects the first valid AI or GS if any.
*/
void SelectValidDebugCompany()
{
/* Check if the currently selected company is still active. */
if (this->IsValidDebugCompany(ai_debug_company)) return;
ai_debug_company = INVALID_COMPANY;
const Company *c;
FOR_ALL_COMPANIES(c) {
if (c->is_ai) {
ChangeToAI(c->index);
return;
}
}
/* If no AI is available, see if there is a game script. */
if (Game::GetInstance() != NULL) ChangeToAI(OWNER_DEITY);
}
/**
* Constructor for the window.
* @param desc The description of the window.
@ -1014,14 +1051,6 @@ struct AIDebugWindow : public Window {
this->FinishInitNested(desc, number);
if (!this->show_break_box) break_check_enabled = false;
/* Disable the companies who are not active or not an AI */
for (CompanyID i = COMPANY_FIRST; i < MAX_COMPANIES; i++) {
this->SetWidgetDisabledState(i + WID_AID_COMPANY_BUTTON_START, !Company::IsValidAiID(i));
}
this->EnableWidget(WID_AID_SCRIPT_GAME);
this->DisableWidget(WID_AID_RELOAD_TOGGLE);
this->DisableWidget(WID_AID_SETTINGS);
this->DisableWidget(WID_AID_CONTINUE_BTN);
this->last_vscroll_pos = 0;
this->autoscroll = true;
@ -1032,17 +1061,8 @@ struct AIDebugWindow : public Window {
/* Restore the break string value from static variable */
this->break_editbox.text.Assign(this->break_string);
/* Restore button state from static class variables */
if (ai_debug_company == OWNER_DEITY) {
this->LowerWidget(WID_AID_SCRIPT_GAME);
this->SetWidgetDisabledState(WID_AID_CONTINUE_BTN, !Game::IsPaused());
} else if (ai_debug_company != INVALID_COMPANY) {
this->LowerWidget(ai_debug_company + WID_AID_COMPANY_BUTTON_START);
this->SetWidgetDisabledState(WID_AID_CONTINUE_BTN, !AI::IsPaused(ai_debug_company));
}
this->SetWidgetLoweredState(WID_AID_BREAK_STR_ON_OFF_BTN, this->break_check_enabled);
this->SetWidgetLoweredState(WID_AID_MATCH_CASE_BTN, this->case_sensitive_break_check);
this->SelectValidDebugCompany();
this->InvalidateData(-1);
}
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
@ -1055,67 +1075,31 @@ struct AIDebugWindow : public Window {
virtual void OnPaint()
{
/* Check if the currently selected company is still active. */
if (ai_debug_company == INVALID_COMPANY || (ai_debug_company != OWNER_DEITY && !Company::IsValidAiID(ai_debug_company))) {
if (ai_debug_company != INVALID_COMPANY) {
/* Raise the widget for the previous selection. */
this->RaiseWidget(ai_debug_company + WID_AID_COMPANY_BUTTON_START);
ai_debug_company = INVALID_COMPANY;
}
const Company *c;
FOR_ALL_COMPANIES(c) {
if (c->is_ai) {
/* Lower the widget corresponding to this company. */
this->LowerWidget(c->index + WID_AID_COMPANY_BUTTON_START);
ai_debug_company = c->index;
break;
}
}
/* If no AI is available, see if there is a game script. */
if (ai_debug_company == INVALID_COMPANY && Game::GetInstance() != NULL) {
/* Lower the widget corresponding to the game script. */
this->LowerWidget(WID_AID_SCRIPT_GAME);
ai_debug_company = OWNER_DEITY;
}
}
/* Update "Reload AI" and "AI settings" buttons */
this->SetWidgetDisabledState(WID_AID_SETTINGS, ai_debug_company == INVALID_COMPANY);
this->SetWidgetDisabledState(WID_AID_RELOAD_TOGGLE, ai_debug_company == INVALID_COMPANY || ai_debug_company == OWNER_DEITY);
this->SetWidgetDisabledState(WID_AID_SCRIPT_GAME, Game::GetGameInstance() == NULL);
this->SelectValidDebugCompany();
/* Draw standard stuff */
this->DrawWidgets();
if (this->IsShaded()) return; // Don't draw anything when the window is shaded.
bool dirty = false;
/* Paint the company icons */
for (CompanyID i = COMPANY_FIRST; i < MAX_COMPANIES; i++) {
NWidgetCore *button = this->GetWidget<NWidgetCore>(i + WID_AID_COMPANY_BUTTON_START);
bool dirty = false;
bool valid = Company::IsValidAiID(i);
bool disabled = !valid;
if (button->IsDisabled() != disabled) {
/* Invalid/non-AI companies have button disabled */
button->SetDisabled(disabled);
dirty = true;
}
/* Check whether the validity of the company changed */
dirty |= (button->IsDisabled() == valid);
/* Mark dead/paused AIs by setting the background colour. */
bool dead = valid && Company::Get(i)->ai_instance->IsDead();
bool paused = valid && Company::Get(i)->ai_instance->IsPaused();
/* Re-paint if the button was updated.
* (note that it is intentional that SetScriptButtonColour is always called) */
dirty = SetScriptButtonColour(*button, dead, paused) || dirty;
dirty |= SetScriptButtonColour(*button, dead, paused);
/* Do we need a repaint? */
if (dirty) this->SetDirty();
/* Draw company icon only for valid AI companies */
if (!valid) continue;
@ -1125,13 +1109,14 @@ struct AIDebugWindow : public Window {
/* Set button colour for Game Script. */
GameInstance *game = Game::GetInstance();
bool dead = game != NULL && game->IsDead();
bool paused = game != NULL && game->IsPaused();
bool valid = game != NULL;
bool dead = valid && game->IsDead();
bool paused = valid && game->IsPaused();
NWidgetCore *button = this->GetWidget<NWidgetCore>(WID_AID_SCRIPT_GAME);
if (SetScriptButtonColour(*button, dead, paused)) {
/* Re-paint if the button was updated. */
this->SetWidgetDirty(WID_AID_SCRIPT_GAME);
}
dirty |= (button->IsDisabled() == valid) || SetScriptButtonColour(*button, dead, paused);
if (dirty) this->InvalidateData(-1);
/* If there are no active companies, don't display anything else. */
if (ai_debug_company == INVALID_COMPANY) return;
@ -1233,30 +1218,19 @@ struct AIDebugWindow : public Window {
*/
void ChangeToAI(CompanyID show_ai)
{
if (ai_debug_company == OWNER_DEITY) {
this->RaiseWidget(WID_AID_SCRIPT_GAME);
} else {
this->RaiseWidget(ai_debug_company + WID_AID_COMPANY_BUTTON_START);
}
if (!this->IsValidDebugCompany(show_ai)) return;
ai_debug_company = show_ai;
ScriptLog::LogData *log = this->GetLogPointer();
this->vscroll->SetCount((log == NULL) ? 0 : log->used);
this->highlight_row = -1; // The highlight of one AI make little sense for another AI.
if (ai_debug_company == OWNER_DEITY) {
this->LowerWidget(WID_AID_SCRIPT_GAME);
this->SetWidgetDisabledState(WID_AID_CONTINUE_BTN, !Game::IsPaused());
} else {
this->LowerWidget(ai_debug_company + WID_AID_COMPANY_BUTTON_START);
this->SetWidgetDisabledState(WID_AID_CONTINUE_BTN, !AI::IsPaused(ai_debug_company));
}
/* Close AI settings window to prevent confusion */
DeleteWindowByClass(WC_AI_SETTINGS);
this->InvalidateData(-1);
this->highlight_row = -1; // The highlight of one AI make little sense for another AI.
this->autoscroll = true;
this->last_vscroll_pos = this->vscroll->GetPosition();
this->SetDirty();
/* Close AI settings window to prevent confusion */
DeleteWindowByClass(WC_AI_SETTINGS);
}
virtual void OnClick(Point pt, int widget, int click_count)
@ -1287,25 +1261,21 @@ struct AIDebugWindow : public Window {
case WID_AID_BREAK_STR_ON_OFF_BTN:
this->break_check_enabled = !this->break_check_enabled;
this->SetWidgetLoweredState(WID_AID_BREAK_STR_ON_OFF_BTN, this->break_check_enabled);
this->SetWidgetDirty(WID_AID_BREAK_STR_ON_OFF_BTN);
this->InvalidateData(-1);
break;
case WID_AID_MATCH_CASE_BTN:
this->case_sensitive_break_check = !this->case_sensitive_break_check;
this->SetWidgetLoweredState(WID_AID_MATCH_CASE_BTN, this->case_sensitive_break_check);
this->SetWidgetDirty(WID_AID_MATCH_CASE_BTN);
this->InvalidateData(-1);
break;
case WID_AID_CONTINUE_BTN:
/* Unpause current AI / game script and mark the corresponding script button dirty. */
if (!IsDead()) {
if (!this->IsDead()) {
if (ai_debug_company == OWNER_DEITY) {
Game::Unpause();
this->SetWidgetDirty(WID_AID_SCRIPT_GAME);
} else {
AI::Unpause(ai_debug_company);
this->SetWidgetDirty(WID_AID_COMPANY_BUTTON_START + ai_debug_company);
}
}
@ -1328,8 +1298,7 @@ struct AIDebugWindow : public Window {
}
this->highlight_row = -1;
this->SetWidgetDirty(WID_AID_LOG_PANEL);
this->DisableWidget(WID_AID_CONTINUE_BTN);
this->InvalidateData(-1);
break;
}
}
@ -1363,15 +1332,14 @@ struct AIDebugWindow : public Window {
/**
* Some data on this window has become invalid.
* @param data Information about the changed data.
* This is the company ID of the AI/GS which wrote a new log message, or -1 in other cases.
* @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.
*/
virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
{
if (data == -1 || ai_debug_company == data) this->SetDirty();
/* If the log message is related to the active company tab, check the break string.
* This needs to be done in gameloop-scope, so the AI is suspended immediately. */
if (!gui_scope && data == ai_debug_company && this->break_check_enabled && !this->break_string_filter.IsEmpty()) {
if (!gui_scope && data == ai_debug_company && this->IsValidDebugCompany(ai_debug_company) && this->break_check_enabled && !this->break_string_filter.IsEmpty()) {
/* Get the log instance of the active company */
ScriptLog::LogData *log = this->GetLogPointer();
@ -1380,7 +1348,7 @@ struct AIDebugWindow : public Window {
this->break_string_filter.AddLine(log->lines[log->pos]);
if (this->break_string_filter.GetState()) {
/* Pause execution of script. */
if (!IsDead()) {
if (!this->IsDead()) {
if (ai_debug_company == OWNER_DEITY) {
Game::Pause();
} else {
@ -1393,15 +1361,35 @@ struct AIDebugWindow : public Window {
DoCommandP(0, PM_PAUSED_NORMAL, 1, CMD_PAUSE);
}
/* Make it possible to click on the continue button */
this->EnableWidget(WID_AID_CONTINUE_BTN);
this->SetWidgetDirty(WID_AID_CONTINUE_BTN);
/* Highlight row that matched */
this->highlight_row = log->pos;
}
}
}
if (!gui_scope) return;
this->SelectValidDebugCompany();
ScriptLog::LogData *log = ai_debug_company != INVALID_COMPANY ? this->GetLogPointer() : NULL;
this->vscroll->SetCount((log == NULL) ? 0 : log->used);
/* Update company buttons */
for (CompanyID i = COMPANY_FIRST; i < MAX_COMPANIES; i++) {
this->SetWidgetDisabledState(i + WID_AID_COMPANY_BUTTON_START, !Company::IsValidAiID(i));
this->SetWidgetLoweredState(i + WID_AID_COMPANY_BUTTON_START, ai_debug_company == i);
}
this->SetWidgetDisabledState(WID_AID_SCRIPT_GAME, Game::GetGameInstance() == NULL);
this->SetWidgetLoweredState(WID_AID_SCRIPT_GAME, ai_debug_company == OWNER_DEITY);
this->SetWidgetLoweredState(WID_AID_BREAK_STR_ON_OFF_BTN, this->break_check_enabled);
this->SetWidgetLoweredState(WID_AID_MATCH_CASE_BTN, this->case_sensitive_break_check);
this->SetWidgetDisabledState(WID_AID_SETTINGS, ai_debug_company == INVALID_COMPANY);
this->SetWidgetDisabledState(WID_AID_RELOAD_TOGGLE, ai_debug_company == INVALID_COMPANY || ai_debug_company == OWNER_DEITY);
this->SetWidgetDisabledState(WID_AID_CONTINUE_BTN, ai_debug_company == INVALID_COMPANY ||
(ai_debug_company == OWNER_DEITY ? !Game::IsPaused() : !AI::IsPaused(ai_debug_company)));
}
virtual void OnResize()

Loading…
Cancel
Save