Merge branch 'master' into jgrpp
# Conflicts: # .github/workflows/ci-build.yml # .github/workflows/release-linux.yml # .github/workflows/release-macos.yml # .github/workflows/release-windows.yml # .gitignore # COMPILING.md # src/company_gui.cpp # src/date_gui.cpp # src/engine.cpp # src/engine_func.h # src/fileio.cpp # src/linkgraph/linkgraph_gui.h # src/newgrf_debug_gui.cpp # src/newgrf_gui.cpp # src/order_gui.cpp # src/osk_gui.cpp # src/rail_gui.cpp # src/road_gui.cpp # src/script/api/script_event_types.hpp # src/sl/oldloader_sl.cpp # src/smallmap_gui.cpp # src/station_cmd.cpp # src/toolbar_gui.cpp # src/town_gui.cpp # src/transparency_gui.cpp # src/vehicle_gui.cpp # src/widget.cpp # src/widget_type.h # src/widgets/dropdown.cpp # src/widgets/dropdown_func.h # src/widgets/dropdown_type.h # src/widgets/group_widget.h # src/widgets/vehicle_widget.h # src/window.cpp # src/window_gui.h # src/window_type.h
This commit is contained in:
@@ -24,6 +24,9 @@
|
||||
* API removals:
|
||||
* \li AIError::ERR_PRECONDITION_TOO_MANY_PARAMETERS, that error is never returned anymore.
|
||||
*
|
||||
* Other changes:
|
||||
* \li AIVehicleList accepts an optional filter function
|
||||
*
|
||||
* \b 13.0
|
||||
*
|
||||
* API additions:
|
||||
|
@@ -84,6 +84,9 @@
|
||||
* API removals:
|
||||
* \li GSError::ERR_PRECONDITION_TOO_MANY_PARAMETERS, that error is never returned anymore.
|
||||
*
|
||||
* Other changes:
|
||||
* \li GSVehicleList accepts an optional filter function
|
||||
*
|
||||
* \b 13.0
|
||||
*
|
||||
* API additions:
|
||||
|
@@ -925,7 +925,7 @@ public:
|
||||
* @param number The windownumber that was clicked.
|
||||
* @param widget The widget in the window that was clicked.
|
||||
*/
|
||||
ScriptEventWindowWidgetClick(ScriptWindow::WindowClass window, uint32 number, uint8 widget) :
|
||||
ScriptEventWindowWidgetClick(ScriptWindow::WindowClass window, uint32_t number, WidgetID widget) :
|
||||
ScriptEvent(ET_WINDOW_WIDGET_CLICK),
|
||||
window(window),
|
||||
number(number),
|
||||
@@ -956,12 +956,12 @@ public:
|
||||
* Get the number of the widget that was clicked.
|
||||
* @return The number of the clicked widget.
|
||||
*/
|
||||
uint8 GetWidgetNumber() { return this->widget; }
|
||||
int GetWidgetNumber() { return this->widget; }
|
||||
|
||||
private:
|
||||
ScriptWindow::WindowClass window; ///< Window of the click.
|
||||
uint32 number; ///< Number of the click.
|
||||
uint8 widget; ///< Widget of the click.
|
||||
uint32_t number; ///< Number of the click.
|
||||
WidgetID widget; ///< Widget of the click.
|
||||
};
|
||||
|
||||
/**
|
||||
|
@@ -18,12 +18,78 @@
|
||||
|
||||
#include "../../safeguards.h"
|
||||
|
||||
ScriptVehicleList::ScriptVehicleList()
|
||||
ScriptVehicleList::ScriptVehicleList(HSQUIRRELVM vm)
|
||||
{
|
||||
EnforceDeityOrCompanyModeValid_Void();
|
||||
for (const Vehicle *v : Vehicle::Iterate()) {
|
||||
if ((v->owner == ScriptObject::GetCompany() || ScriptCompanyMode::IsDeity()) && (v->IsPrimaryVehicle() || (v->type == VEH_TRAIN && ::Train::From(v)->IsFreeWagon()))) this->AddItem(v->index);
|
||||
|
||||
int nparam = sq_gettop(vm) - 1;
|
||||
if (nparam >= 1) {
|
||||
/* Make sure the filter function is really a function, and not any
|
||||
* other type. It's parameter 2 for us, but for the user it's the
|
||||
* first parameter they give. */
|
||||
SQObjectType valuator_type = sq_gettype(vm, 2);
|
||||
if (valuator_type != OT_CLOSURE && valuator_type != OT_NATIVECLOSURE) {
|
||||
throw sq_throwerror(vm, "parameter 1 has an invalid type (expected function)");
|
||||
}
|
||||
|
||||
/* Push the function to call */
|
||||
sq_push(vm, 2);
|
||||
}
|
||||
|
||||
/* Don't allow docommand from a Valuator, as we can't resume in
|
||||
* mid C++-code. */
|
||||
bool backup_allow = ScriptObject::GetAllowDoCommand();
|
||||
ScriptObject::SetAllowDoCommand(false);
|
||||
|
||||
for (const Vehicle *v : Vehicle::Iterate()) {
|
||||
if (v->owner != ScriptObject::GetCompany() && !ScriptCompanyMode::IsDeity()) continue;
|
||||
if (!v->IsPrimaryVehicle() && !(v->type == VEH_TRAIN && ::Train::From(v)->IsFreeWagon())) continue;
|
||||
|
||||
if (nparam < 1) {
|
||||
/* No filter, just add the item. */
|
||||
this->AddItem(v->index);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Push the root table as instance object, this is what squirrel does for meta-functions. */
|
||||
sq_pushroottable(vm);
|
||||
/* Push all arguments for the valuator function. */
|
||||
sq_pushinteger(vm, v->index);
|
||||
for (int i = 0; i < nparam - 1; i++) {
|
||||
sq_push(vm, i + 3);
|
||||
}
|
||||
|
||||
/* Call the function. Squirrel pops all parameters and pushes the return value. */
|
||||
if (SQ_FAILED(sq_call(vm, nparam + 1, SQTrue, SQTrue))) {
|
||||
ScriptObject::SetAllowDoCommand(backup_allow);
|
||||
throw sq_throwerror(vm, "failed to run filter");
|
||||
}
|
||||
|
||||
/* Retrieve the return value */
|
||||
switch (sq_gettype(vm, -1)) {
|
||||
case OT_BOOL: {
|
||||
SQBool add;
|
||||
sq_getbool(vm, -1, &add);
|
||||
if (add) this->AddItem(v->index);
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
ScriptObject::SetAllowDoCommand(backup_allow);
|
||||
throw sq_throwerror(vm, "return value of filter is not valid (not bool)");
|
||||
}
|
||||
}
|
||||
|
||||
/* Pop the return value. */
|
||||
sq_poptop(vm);
|
||||
}
|
||||
|
||||
if (nparam >= 1) {
|
||||
/* Pop the filter function */
|
||||
sq_poptop(vm);
|
||||
}
|
||||
|
||||
ScriptObject::SetAllowDoCommand(backup_allow);
|
||||
}
|
||||
|
||||
ScriptVehicleList_Station::ScriptVehicleList_Station(StationID station_id)
|
||||
|
@@ -20,7 +20,32 @@
|
||||
*/
|
||||
class ScriptVehicleList : public ScriptList {
|
||||
public:
|
||||
#ifdef DOXYGEN_API
|
||||
ScriptVehicleList();
|
||||
|
||||
/**
|
||||
* Apply a filter when building the list.
|
||||
* @param filter_function The function which will be doing the filtering.
|
||||
* @param params The params to give to the filters (minus the first param,
|
||||
* which is always the index-value).
|
||||
* @note You can write your own filters and use them. Just remember that
|
||||
* the first parameter should be the index-value, and it should return
|
||||
* a bool.
|
||||
* @note Example:
|
||||
* ScriptVehicleList(ScriptVehicle.IsInDepot);
|
||||
* function IsType(vehicle_id, type)
|
||||
* {
|
||||
* return ScriptVehicle.GetVehicleType(vehicle_id) == type;
|
||||
* }
|
||||
* ScriptVehicleList(IsType, ScriptVehicle.VT_ROAD);
|
||||
*/
|
||||
ScriptVehicleList(void *filter_function, int params, ...);
|
||||
#else
|
||||
/**
|
||||
* The constructor wrapper from Squirrel.
|
||||
*/
|
||||
ScriptVehicleList(HSQUIRRELVM vm);
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
|
@@ -97,14 +97,14 @@ struct ScriptListWindow : public Window {
|
||||
}
|
||||
}
|
||||
|
||||
void SetStringParameters(int widget) const override
|
||||
void SetStringParameters(WidgetID widget) const override
|
||||
{
|
||||
if (widget != WID_SCRL_CAPTION) return;
|
||||
|
||||
SetDParam(0, (this->slot == OWNER_DEITY) ? STR_AI_LIST_CAPTION_GAMESCRIPT : STR_AI_LIST_CAPTION_AI);
|
||||
}
|
||||
|
||||
void UpdateWidgetSize(int widget, Dimension *size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension *fill, [[maybe_unused]] Dimension *resize) override
|
||||
void UpdateWidgetSize(WidgetID widget, Dimension *size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension *fill, [[maybe_unused]] Dimension *resize) override
|
||||
{
|
||||
if (widget != WID_SCRL_LIST) return;
|
||||
|
||||
@@ -115,7 +115,7 @@ struct ScriptListWindow : public Window {
|
||||
size->height = 5 * this->line_height;
|
||||
}
|
||||
|
||||
void DrawWidget(const Rect &r, int widget) const override
|
||||
void DrawWidget(const Rect &r, WidgetID widget) const override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_SCRL_LIST: {
|
||||
@@ -192,7 +192,7 @@ struct ScriptListWindow : public Window {
|
||||
}
|
||||
}
|
||||
|
||||
void OnClick([[maybe_unused]] Point pt, int widget, [[maybe_unused]] int click_count) override
|
||||
void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_SCRL_LIST: { // Select one of the Scripts
|
||||
@@ -351,14 +351,14 @@ struct ScriptSettingsWindow : public Window {
|
||||
this->vscroll->SetCount(this->visible_settings.size());
|
||||
}
|
||||
|
||||
void SetStringParameters(int widget) const override
|
||||
void SetStringParameters(WidgetID widget) const override
|
||||
{
|
||||
if (widget != WID_SCRS_CAPTION) return;
|
||||
|
||||
SetDParam(0, (this->slot == OWNER_DEITY) ? STR_AI_SETTINGS_CAPTION_GAMESCRIPT : STR_AI_SETTINGS_CAPTION_AI);
|
||||
}
|
||||
|
||||
void UpdateWidgetSize(int widget, Dimension *size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension *fill, [[maybe_unused]] Dimension *resize) override
|
||||
void UpdateWidgetSize(WidgetID widget, Dimension *size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension *fill, [[maybe_unused]] Dimension *resize) override
|
||||
{
|
||||
if (widget != WID_SCRS_BACKGROUND) return;
|
||||
|
||||
@@ -369,7 +369,7 @@ struct ScriptSettingsWindow : public Window {
|
||||
size->height = 5 * this->line_height;
|
||||
}
|
||||
|
||||
void DrawWidget(const Rect &r, int widget) const override
|
||||
void DrawWidget(const Rect &r, WidgetID widget) const override
|
||||
{
|
||||
if (widget != WID_SCRS_BACKGROUND) return;
|
||||
|
||||
@@ -437,7 +437,7 @@ struct ScriptSettingsWindow : public Window {
|
||||
this->DrawWidgets();
|
||||
}
|
||||
|
||||
void OnClick([[maybe_unused]] Point pt, int widget, [[maybe_unused]] int click_count) override
|
||||
void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_SCRS_BACKGROUND: {
|
||||
@@ -540,14 +540,14 @@ struct ScriptSettingsWindow : public Window {
|
||||
SetValue(value);
|
||||
}
|
||||
|
||||
void OnDropdownSelect(int widget, int index) override
|
||||
void OnDropdownSelect(WidgetID widget, int index) override
|
||||
{
|
||||
if (widget != WID_SCRS_SETTING_DROPDOWN) return;
|
||||
assert(this->clicked_dropdown);
|
||||
SetValue(index);
|
||||
}
|
||||
|
||||
void OnDropdownClose(Point, int widget, int, bool) override
|
||||
void OnDropdownClose(Point, WidgetID widget, int, bool) override
|
||||
{
|
||||
if (widget != WID_SCRS_SETTING_DROPDOWN) return;
|
||||
/* We cannot raise the dropdown button just yet. OnClick needs some hint, whether
|
||||
@@ -652,7 +652,7 @@ struct ScriptTextfileWindow : public TextfileWindow {
|
||||
this->OnInvalidateData();
|
||||
}
|
||||
|
||||
void SetStringParameters(int widget) const override
|
||||
void SetStringParameters(WidgetID widget) const override
|
||||
{
|
||||
if (widget == WID_TF_CAPTION) {
|
||||
SetDParam(0, (slot == OWNER_DEITY) ? STR_CONTENT_TYPE_GAME_SCRIPT : STR_CONTENT_TYPE_AI);
|
||||
@@ -803,19 +803,14 @@ struct ScriptDebugWindow : public Window {
|
||||
this->CreateNestedTree();
|
||||
this->vscroll = this->GetScrollbar(WID_SCRD_VSCROLLBAR);
|
||||
this->hscroll = this->GetScrollbar(WID_SCRD_HSCROLLBAR);
|
||||
this->show_break_box = _settings_client.gui.ai_developer_tools;
|
||||
this->GetWidget<NWidgetStacked>(WID_SCRD_BREAK_STRING_WIDGETS)->SetDisplayedPlane(this->show_break_box ? 0 : SZSP_HORIZONTAL);
|
||||
this->FinishInitNested(number);
|
||||
|
||||
if (!this->show_break_box) this->filter.break_check_enabled = false;
|
||||
|
||||
this->last_vscroll_pos = 0;
|
||||
this->autoscroll = true;
|
||||
this->highlight_row = -1;
|
||||
|
||||
this->querystrings[WID_SCRD_BREAK_STR_EDIT_BOX] = &this->break_editbox;
|
||||
|
||||
SetWidgetsDisabledState(!this->show_break_box, WID_SCRD_BREAK_STR_ON_OFF_BTN, WID_SCRD_BREAK_STR_EDIT_BOX, WID_SCRD_MATCH_CASE_BTN);
|
||||
this->hscroll->SetStepSize(10); // Speed up horizontal scrollbar
|
||||
|
||||
/* Restore the break string value from static variable, and enable the filter. */
|
||||
@@ -831,6 +826,11 @@ struct ScriptDebugWindow : public Window {
|
||||
|
||||
void OnInit() override
|
||||
{
|
||||
this->show_break_box = _settings_client.gui.ai_developer_tools;
|
||||
this->GetWidget<NWidgetStacked>(WID_SCRD_BREAK_STRING_WIDGETS)->SetDisplayedPlane(this->show_break_box ? 0 : SZSP_HORIZONTAL);
|
||||
if (!this->show_break_box) this->filter.break_check_enabled = false;
|
||||
SetWidgetsDisabledState(!this->show_break_box, WID_SCRD_BREAK_STR_ON_OFF_BTN, WID_SCRD_BREAK_STR_EDIT_BOX, WID_SCRD_MATCH_CASE_BTN);
|
||||
|
||||
this->InvalidateData(-1);
|
||||
}
|
||||
|
||||
@@ -839,7 +839,7 @@ struct ScriptDebugWindow : public Window {
|
||||
ScriptDebugWindow::initial_state = this->filter;
|
||||
}
|
||||
|
||||
void UpdateWidgetSize(int widget, Dimension *size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension *fill, [[maybe_unused]] Dimension *resize) override
|
||||
void UpdateWidgetSize(WidgetID widget, Dimension *size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension *fill, [[maybe_unused]] Dimension *resize) override
|
||||
{
|
||||
if (widget == WID_SCRD_LOG_PANEL) {
|
||||
resize->height = GetCharacterHeight(FS_NORMAL) + WidgetDimensions::scaled.vsep_normal;
|
||||
@@ -856,7 +856,7 @@ struct ScriptDebugWindow : public Window {
|
||||
this->DrawWidgets();
|
||||
}
|
||||
|
||||
void SetStringParameters(int widget) const override
|
||||
void SetStringParameters(WidgetID widget) const override
|
||||
{
|
||||
if (widget != WID_SCRD_NAME_TEXT) return;
|
||||
|
||||
@@ -877,7 +877,7 @@ struct ScriptDebugWindow : public Window {
|
||||
}
|
||||
}
|
||||
|
||||
void DrawWidget(const Rect &r, int widget) const override
|
||||
void DrawWidget(const Rect &r, WidgetID widget) const override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_SCRD_LOG_PANEL:
|
||||
@@ -898,7 +898,7 @@ struct ScriptDebugWindow : public Window {
|
||||
* @param widget Widget index to start.
|
||||
* @param start Widget index of first company button.
|
||||
*/
|
||||
void DrawWidgetCompanyButton(const Rect &r, int widget, int start) const
|
||||
void DrawWidgetCompanyButton(const Rect &r, WidgetID widget, int start) const
|
||||
{
|
||||
if (this->IsWidgetDisabled(widget)) return;
|
||||
CompanyID cid = (CompanyID)(widget - start);
|
||||
@@ -1052,7 +1052,7 @@ struct ScriptDebugWindow : public Window {
|
||||
this->last_vscroll_pos = this->vscroll->GetPosition();
|
||||
}
|
||||
|
||||
void OnClick([[maybe_unused]] Point pt, int widget, [[maybe_unused]] int click_count) override
|
||||
void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
|
||||
{
|
||||
/* Also called for hotkeys, so check for disabledness */
|
||||
if (this->IsWidgetDisabled(widget)) return;
|
||||
@@ -1128,7 +1128,7 @@ struct ScriptDebugWindow : public Window {
|
||||
}
|
||||
}
|
||||
|
||||
void OnEditboxChanged(int wid) override
|
||||
void OnEditboxChanged(WidgetID wid) override
|
||||
{
|
||||
if (wid != WID_SCRD_BREAK_STR_EDIT_BOX) return;
|
||||
|
||||
@@ -1145,6 +1145,8 @@ struct ScriptDebugWindow : public Window {
|
||||
*/
|
||||
void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override
|
||||
{
|
||||
if (this->show_break_box != _settings_client.gui.ai_developer_tools) this->ReInit();
|
||||
|
||||
/* 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 == this->filter.script_debug_company &&
|
||||
@@ -1218,9 +1220,9 @@ struct ScriptDebugWindow : public Window {
|
||||
};
|
||||
|
||||
/** Make a number of rows with buttons for each company for the Script debug window. */
|
||||
NWidgetBase *MakeCompanyButtonRowsScriptDebug(int *biggest_index)
|
||||
std::unique_ptr<NWidgetBase> MakeCompanyButtonRowsScriptDebug()
|
||||
{
|
||||
return MakeCompanyButtonRows(biggest_index, WID_SCRD_COMPANY_BUTTON_START, WID_SCRD_COMPANY_BUTTON_END, COLOUR_GREY, 8, STR_AI_DEBUG_SELECT_AI_TOOLTIP);
|
||||
return MakeCompanyButtonRows(WID_SCRD_COMPANY_BUTTON_START, WID_SCRD_COMPANY_BUTTON_END, COLOUR_GREY, 8, STR_AI_DEBUG_SELECT_AI_TOOLTIP);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user