diff options
author | frosch <frosch@openttd.org> | 2013-11-07 18:17:21 +0000 |
---|---|---|
committer | frosch <frosch@openttd.org> | 2013-11-07 18:17:21 +0000 |
commit | 0aae2fd606d0011c8e913f7b151bb74b28441a61 (patch) | |
tree | 6ee97fd3823e32d15ffb6012ae7c9d826653ea74 /src | |
parent | b0c2ab4501c21851e84eacfd5ea7bb0927ab9157 (diff) | |
download | openttd-0aae2fd606d0011c8e913f7b151bb74b28441a61.tar.xz |
(svn r25946) -Add: [NewGRF Debuggnig] Inspecting other vehicles in a chain.
Diffstat (limited to 'src')
-rw-r--r-- | src/newgrf_debug.h | 1 | ||||
-rw-r--r-- | src/newgrf_debug_gui.cpp | 177 | ||||
-rw-r--r-- | src/script/api/game/game_window.hpp.sq | 4 | ||||
-rw-r--r-- | src/script/api/script_window.hpp | 3 | ||||
-rw-r--r-- | src/train_cmd.cpp | 3 | ||||
-rw-r--r-- | src/widgets/newgrf_debug_widget.h | 3 |
6 files changed, 185 insertions, 6 deletions
diff --git a/src/newgrf_debug.h b/src/newgrf_debug.h index 89ede74eb..6e514c4ce 100644 --- a/src/newgrf_debug.h +++ b/src/newgrf_debug.h @@ -36,6 +36,7 @@ extern NewGrfDebugSpritePicker _newgrf_debug_sprite_picker; bool IsNewGRFInspectable(GrfSpecFeature feature, uint index); void ShowNewGRFInspectWindow(GrfSpecFeature feature, uint index, const uint32 grfid = 0); +void InvalidateNewGRFInspectWindow(GrfSpecFeature feature, uint index); void DeleteNewGRFInspectWindow(GrfSpecFeature feature, uint index); GrfSpecFeature GetGrfSpecFeature(TileIndex tile); diff --git a/src/newgrf_debug_gui.cpp b/src/newgrf_debug_gui.cpp index bc730981e..cead62750 100644 --- a/src/newgrf_debug_gui.cpp +++ b/src/newgrf_debug_gui.cpp @@ -18,6 +18,7 @@ #include "string_func.h" #include "strings_func.h" #include "textbuf_gui.h" +#include "vehicle_gui.h" #include "engine_base.h" #include "industry.h" @@ -25,6 +26,8 @@ #include "station_base.h" #include "town.h" #include "vehicle_base.h" +#include "train.h" +#include "roadveh.h" #include "newgrf_airporttiles.h" #include "newgrf_debug.h" @@ -278,6 +281,9 @@ struct NewGRFInspectWindow : Window { /** GRFID of the caller of this window, 0 if it has no caller. */ uint32 caller_grfid; + /** For ground vehicles: Index in vehicle chain. */ + uint chain_index; + /** The currently edited parameter, to update the right one. */ byte current_edit_param; @@ -304,15 +310,44 @@ struct NewGRFInspectWindow : Window { } /** + * Check whether this feature has chain index, i.e. refers to ground vehicles. + */ + bool HasChainIndex() const + { + GrfSpecFeature f = GetFeatureNum(this->window_number); + return f == GSF_TRAINS || f == GSF_ROADVEHICLES; + } + + /** * Get the feature index. * @return the feature index */ uint GetFeatureIndex() const { uint index = ::GetFeatureIndex(this->window_number); + if (this->chain_index > 0) { + assert(this->HasChainIndex()); + const Vehicle *v = Vehicle::Get(index); + v = v->Move(this->chain_index); + if (v != NULL) index = v->index; + } return index; } + /** + * Ensure that this->chain_index is in range. + */ + void ValidateChainIndex() + { + if (this->chain_index == 0) return; + + assert(this->HasChainIndex()); + + const Vehicle *v = Vehicle::Get(::GetFeatureIndex(this->window_number)); + v = v->Move(this->chain_index); + if (v == NULL) this->chain_index = 0; + } + NewGRFInspectWindow(WindowDesc *desc, WindowNumber wno) : Window(desc) { this->CreateNestedTree(); @@ -321,6 +356,8 @@ struct NewGRFInspectWindow : Window { this->vscroll->SetCount(0); this->SetWidgetDisabledState(WID_NGRFI_PARENT, GetFeatureHelper(this->window_number)->GetParent(this->GetFeatureIndex()) == UINT32_MAX); + + this->OnInvalidateData(0, true); } virtual void SetStringParameters(int widget) const @@ -332,12 +369,21 @@ struct NewGRFInspectWindow : Window { virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) { - if (widget != WID_NGRFI_MAINPANEL) return; + switch (widget) { + case WID_NGRFI_VEH_CHAIN: { + assert(this->HasChainIndex()); + GrfSpecFeature f = GetFeatureNum(this->window_number); + size->height = max(size->height, GetVehicleImageCellSize((VehicleType)(VEH_TRAIN + (f - GSF_TRAINS)), EIT_IN_DEPOT).height + 2 + WD_BEVEL_TOP + WD_BEVEL_BOTTOM); + break; + } - resize->height = max(11, FONT_HEIGHT_NORMAL + 1); - resize->width = 1; + case WID_NGRFI_MAINPANEL: + resize->height = max(11, FONT_HEIGHT_NORMAL + 1); + resize->width = 1; - size->height = 5 * resize->height + TOP_OFFSET + BOTTOM_OFFSET; + size->height = 5 * resize->height + TOP_OFFSET + BOTTOM_OFFSET; + break; + } } /** @@ -363,6 +409,44 @@ struct NewGRFInspectWindow : Window { virtual void DrawWidget(const Rect &r, int widget) const { + switch (widget) { + case WID_NGRFI_VEH_CHAIN: { + const Vehicle *v = Vehicle::Get(this->GetFeatureIndex()); + int total_width = 0; + int sel_start = 0; + int sel_end = 0; + for (const Vehicle *u = v->First(); u != NULL; u = u->Next()) { + if (u == v) sel_start = total_width; + switch (u->type) { + case VEH_TRAIN: total_width += Train ::From(u)->GetDisplayImageWidth(); break; + case VEH_ROAD: total_width += RoadVehicle::From(u)->GetDisplayImageWidth(); break; + default: NOT_REACHED(); + } + if (u == v) sel_end = total_width; + } + + int width = r.right + 1 - r.left - WD_BEVEL_LEFT - WD_BEVEL_RIGHT; + int skip = 0; + if (total_width > width) { + int sel_center = (sel_start + sel_end) / 2; + if (sel_center > width / 2) skip = min(total_width - width, sel_center - width / 2); + } + + GrfSpecFeature f = GetFeatureNum(this->window_number); + int h = GetVehicleImageCellSize((VehicleType)(VEH_TRAIN + (f - GSF_TRAINS)), EIT_IN_DEPOT).height; + int y = (r.top + r.bottom - h) / 2; + DrawVehicleImage(v->First(), r.left + WD_BEVEL_LEFT, r.right - WD_BEVEL_RIGHT, y + 1, INVALID_VEHICLE, EIT_IN_DETAILS, skip); + + /* Highlight the articulated part (this is different to the whole-vehicle highlighting of DrawVehicleImage */ + if (_current_text_dir == TD_RTL) { + DrawFrameRect(r.right - sel_end + skip, y, r.right - sel_start + skip, y + h, COLOUR_WHITE, FR_BORDERONLY); + } else { + DrawFrameRect(r.left + sel_start - skip, y, r.left + sel_end - skip, y + h, COLOUR_WHITE, FR_BORDERONLY); + } + break; + } + } + if (widget != WID_NGRFI_MAINPANEL) return; uint index = this->GetFeatureIndex(); @@ -469,10 +553,28 @@ struct NewGRFInspectWindow : Window { case WID_NGRFI_PARENT: { const NIHelper *nih = GetFeatureHelper(this->window_number); uint index = nih->GetParent(this->GetFeatureIndex()); - ::ShowNewGRFInspectWindow((GrfSpecFeature)GB(index, 24, 8), ::GetFeatureIndex(index), nih->GetGRFID(this->GetFeatureIndex())); + ::ShowNewGRFInspectWindow(GetFeatureNum(index), ::GetFeatureIndex(index), nih->GetGRFID(this->GetFeatureIndex())); break; } + case WID_NGRFI_VEH_PREV: + if (this->chain_index > 0) { + this->chain_index--; + this->InvalidateData(); + } + break; + + case WID_NGRFI_VEH_NEXT: + if (this->HasChainIndex()) { + uint index = this->GetFeatureIndex(); + Vehicle *v = Vehicle::Get(index); + if (v != NULL && v->Next() != NULL) { + this->chain_index++; + this->InvalidateData(); + } + } + break; + case WID_NGRFI_MAINPANEL: { /* Does this feature have variables? */ const NIFeature *nif = GetFeature(this->window_number); @@ -507,10 +609,50 @@ struct NewGRFInspectWindow : Window { { this->vscroll->SetCapacityFromWidget(this, WID_NGRFI_MAINPANEL, TOP_OFFSET + BOTTOM_OFFSET); } + + /** + * Some data on this window has become invalid. + * @param data Information about the changed data. + * @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 (!gui_scope) return; + if (this->HasChainIndex()) { + this->ValidateChainIndex(); + this->SetWidgetDisabledState(WID_NGRFI_VEH_PREV, this->chain_index == 0); + Vehicle *v = Vehicle::Get(this->GetFeatureIndex()); + this->SetWidgetDisabledState(WID_NGRFI_VEH_NEXT, v == NULL || v->Next() == NULL); + } + } }; /* static */ uint32 NewGRFInspectWindow::var60params[GSF_FAKE_END][0x20] = { {0} }; // Use spec to have 0s in whole array +static const NWidgetPart _nested_newgrf_inspect_chain_widgets[] = { + NWidget(NWID_HORIZONTAL), + NWidget(WWT_CLOSEBOX, COLOUR_GREY), + NWidget(WWT_CAPTION, COLOUR_GREY, WID_NGRFI_CAPTION), SetDataTip(STR_NEWGRF_INSPECT_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), + NWidget(WWT_SHADEBOX, COLOUR_GREY), + NWidget(WWT_DEFSIZEBOX, COLOUR_GREY), + NWidget(WWT_STICKYBOX, COLOUR_GREY), + EndContainer(), + NWidget(WWT_PANEL, COLOUR_GREY), + NWidget(NWID_HORIZONTAL), + NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_NGRFI_VEH_PREV), SetDataTip(AWV_DECREASE, STR_NULL), + NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_NGRFI_VEH_NEXT), SetDataTip(AWV_INCREASE, STR_NULL), + NWidget(WWT_EMPTY, COLOUR_GREY, WID_NGRFI_VEH_CHAIN), SetFill(1, 0), SetResize(1, 0), + EndContainer(), + EndContainer(), + NWidget(NWID_HORIZONTAL), + NWidget(WWT_PANEL, COLOUR_GREY, WID_NGRFI_MAINPANEL), SetMinimalSize(300, 0), SetScrollbar(WID_NGRFI_SCROLLBAR), EndContainer(), + NWidget(NWID_VERTICAL), + NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_NGRFI_SCROLLBAR), + NWidget(WWT_RESIZEBOX, COLOUR_GREY), + EndContainer(), + EndContainer(), +}; + static const NWidgetPart _nested_newgrf_inspect_widgets[] = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY), @@ -529,6 +671,13 @@ static const NWidgetPart _nested_newgrf_inspect_widgets[] = { EndContainer(), }; +static WindowDesc _newgrf_inspect_chain_desc( + WDP_AUTO, "newgrf_inspect_chain", 400, 300, + WC_NEWGRF_INSPECT, WC_NONE, + 0, + _nested_newgrf_inspect_chain_widgets, lengthof(_nested_newgrf_inspect_chain_widgets) +); + static WindowDesc _newgrf_inspect_desc( WDP_AUTO, "newgrf_inspect", 400, 300, WC_NEWGRF_INSPECT, WC_NONE, @@ -550,12 +699,28 @@ void ShowNewGRFInspectWindow(GrfSpecFeature feature, uint index, const uint32 gr if (!IsNewGRFInspectable(feature, index)) return; WindowNumber wno = GetInspectWindowNumber(feature, index); - NewGRFInspectWindow *w = AllocateWindowDescFront<NewGRFInspectWindow>(&_newgrf_inspect_desc, wno); + NewGRFInspectWindow *w = AllocateWindowDescFront<NewGRFInspectWindow>(feature == GSF_TRAINS || feature == GSF_ROADVEHICLES ? &_newgrf_inspect_chain_desc : &_newgrf_inspect_desc, wno); if (w == NULL) w = (NewGRFInspectWindow *)FindWindowById(WC_NEWGRF_INSPECT, wno); w->SetCallerGRFID(grfid); } /** + * Invalidate the inspect window for a given feature and index. + * The index is normally an in-game location/identifier, such + * as a TileIndex or an IndustryID depending on the feature + * we want to inspect. + * @param feature The feature we want to invalidate the window for. + * @param index The index/identifier of the feature to invalidate. + */ +void InvalidateNewGRFInspectWindow(GrfSpecFeature feature, uint index) +{ + if (feature == GSF_INVALID) return; + + WindowNumber wno = GetInspectWindowNumber(feature, index); + InvalidateWindowData(WC_NEWGRF_INSPECT, wno); +} + +/** * Delete inspect window for a given feature and index. * The index is normally an in-game location/identifier, such * as a TileIndex or an IndustryID depending on the feature diff --git a/src/script/api/game/game_window.hpp.sq b/src/script/api/game/game_window.hpp.sq index 0363a004f..f693825b5 100644 --- a/src/script/api/game/game_window.hpp.sq +++ b/src/script/api/game/game_window.hpp.sq @@ -615,6 +615,7 @@ void SQGSWindow_Register(Squirrel *engine) SQGSWindow.DefSQConst(engine, ScriptWindow::WID_Q_NO, "WID_Q_NO"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_Q_YES, "WID_Q_YES"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TF_CAPTION, "WID_TF_CAPTION"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TF_WRAPTEXT, "WID_TF_WRAPTEXT"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TF_BACKGROUND, "WID_TF_BACKGROUND"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TF_VSCROLLBAR, "WID_TF_VSCROLLBAR"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TF_HSCROLLBAR, "WID_TF_HSCROLLBAR"); @@ -752,6 +753,9 @@ void SQGSWindow_Register(Squirrel *engine) SQGSWindow.DefSQConst(engine, ScriptWindow::WID_NCP_OK, "WID_NCP_OK"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_NGRFI_CAPTION, "WID_NGRFI_CAPTION"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_NGRFI_PARENT, "WID_NGRFI_PARENT"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_NGRFI_VEH_PREV, "WID_NGRFI_VEH_PREV"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_NGRFI_VEH_NEXT, "WID_NGRFI_VEH_NEXT"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_NGRFI_VEH_CHAIN, "WID_NGRFI_VEH_CHAIN"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_NGRFI_MAINPANEL, "WID_NGRFI_MAINPANEL"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_NGRFI_SCROLLBAR, "WID_NGRFI_SCROLLBAR"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_SA_CAPTION, "WID_SA_CAPTION"); diff --git a/src/script/api/script_window.hpp b/src/script/api/script_window.hpp index 5335af1b7..7177064f2 100644 --- a/src/script/api/script_window.hpp +++ b/src/script/api/script_window.hpp @@ -1768,6 +1768,9 @@ public: enum NewGRFInspectWidgets { WID_NGRFI_CAPTION = ::WID_NGRFI_CAPTION, ///< The caption bar of course. WID_NGRFI_PARENT = ::WID_NGRFI_PARENT, ///< Inspect the parent. + WID_NGRFI_VEH_PREV = ::WID_NGRFI_VEH_PREV, ///< Go to previous vehicle in chain. + WID_NGRFI_VEH_NEXT = ::WID_NGRFI_VEH_NEXT, ///< Go to next vehicle in chain. + WID_NGRFI_VEH_CHAIN = ::WID_NGRFI_VEH_CHAIN, ///< Display for vehicle chain. WID_NGRFI_MAINPANEL = ::WID_NGRFI_MAINPANEL, ///< Panel widget containing the actual data. WID_NGRFI_SCROLLBAR = ::WID_NGRFI_SCROLLBAR, ///< Scrollbar. }; diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index 96af0ec0c..038649862 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -34,6 +34,7 @@ #include "newgrf.h" #include "order_backup.h" #include "zoom_func.h" +#include "newgrf_debug.h" #include "table/strings.h" #include "table/train_cmd.h" @@ -242,6 +243,7 @@ void Train::ConsistChanged(bool same_length) SetWindowDirty(WC_VEHICLE_DETAILS, this->index); InvalidateWindowData(WC_VEHICLE_REFIT, this->index, VIWD_CONSIST_CHANGED); InvalidateWindowData(WC_VEHICLE_ORDERS, this->index, VIWD_CONSIST_CHANGED); + InvalidateNewGRFInspectWindow(GSF_TRAINS, this->index); } } @@ -1271,6 +1273,7 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, u DeleteWindowById(WC_VEHICLE_REFIT, src->index); DeleteWindowById(WC_VEHICLE_DETAILS, src->index); DeleteWindowById(WC_VEHICLE_TIMETABLE, src->index); + DeleteNewGRFInspectWindow(GSF_TRAINS, src->index); SetWindowDirty(WC_COMPANY, _current_company); /* Delete orders, group stuff and the unit number as we're not the diff --git a/src/widgets/newgrf_debug_widget.h b/src/widgets/newgrf_debug_widget.h index af24549c1..b719bcfc5 100644 --- a/src/widgets/newgrf_debug_widget.h +++ b/src/widgets/newgrf_debug_widget.h @@ -16,6 +16,9 @@ enum NewGRFInspectWidgets { WID_NGRFI_CAPTION, ///< The caption bar of course. WID_NGRFI_PARENT, ///< Inspect the parent. + WID_NGRFI_VEH_PREV, ///< Go to previous vehicle in chain. + WID_NGRFI_VEH_NEXT, ///< Go to next vehicle in chain. + WID_NGRFI_VEH_CHAIN, ///< Display for vehicle chain. WID_NGRFI_MAINPANEL, ///< Panel widget containing the actual data. WID_NGRFI_SCROLLBAR, ///< Scrollbar. }; |