diff --git a/src/lang/english.txt b/src/lang/english.txt index 887d99adb0..92ff143261 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -4212,6 +4212,8 @@ STR_NEWGRF_INSPECT_REFRESH :{BLACK}R STR_NEWGRF_INSPECT_REFRESH_TOOLTIP :{BLACK}Toggle whether to refresh the contents every frame STR_NEWGRF_INSPECT_LOG_CONSOLE :{BLACK}L STR_NEWGRF_INSPECT_LOG_CONSOLE_TOOLTIP :{BLACK}Log text content of this window to the console +STR_NEWGRF_INSPECT_DUPLICATE :{BLACK}D +STR_NEWGRF_INSPECT_DUPLICATE_TOOLTIP :{BLACK}Duplicate this window STR_NEWGRF_INSPECT_SPRITE_DUMP :{BLACK}S STR_NEWGRF_INSPECT_SPRITE_DUMP_TOOLTIP :{BLACK}Display current sprite chain STR_NEWGRF_INSPECT_SPRITE_DUMP_PANEL_TOOLTIP :{BLACK}Click to highlight sprite group{}Shift+Click to collapse sprite group{}Ctrl+Click to highlight temporary storage register diff --git a/src/newgrf_debug_gui.cpp b/src/newgrf_debug_gui.cpp index 38da3b2bdf..5d95b589ff 100644 --- a/src/newgrf_debug_gui.cpp +++ b/src/newgrf_debug_gui.cpp @@ -831,6 +831,12 @@ struct NewGRFInspectWindow : Window { break; } + case WID_NGRFI_DUPLICATE: { + NewGRFInspectWindow *w = new NewGRFInspectWindow(this->window_desc, this->window_number); + w->SetCallerGRFID(this->caller_grfid); + break; + } + case WID_NGRFI_SPRITE_DUMP: { this->sprite_dump = !this->sprite_dump; this->SetWidgetLoweredState(WID_NGRFI_SPRITE_DUMP, this->sprite_dump); @@ -887,6 +893,7 @@ static const NWidgetPart _nested_newgrf_inspect_chain_widgets[] = { NWidget(NWID_SELECTION, INVALID_COLOUR, WID_NGRFI_SPRITE_DUMP_SEL), NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_NGRFI_SPRITE_DUMP), SetDataTip(STR_NEWGRF_INSPECT_SPRITE_DUMP, STR_NEWGRF_INSPECT_SPRITE_DUMP_TOOLTIP), EndContainer(), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_NGRFI_DUPLICATE), SetDataTip(STR_NEWGRF_INSPECT_DUPLICATE, STR_NEWGRF_INSPECT_DUPLICATE_TOOLTIP), NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_NGRFI_LOG_CONSOLE), SetDataTip(STR_NEWGRF_INSPECT_LOG_CONSOLE, STR_NEWGRF_INSPECT_LOG_CONSOLE_TOOLTIP), NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_NGRFI_REFRESH), SetDataTip(STR_NEWGRF_INSPECT_REFRESH, STR_NEWGRF_INSPECT_REFRESH_TOOLTIP), NWidget(WWT_SHADEBOX, COLOUR_GREY), @@ -917,6 +924,7 @@ static const NWidgetPart _nested_newgrf_inspect_widgets[] = { NWidget(NWID_SELECTION, INVALID_COLOUR, WID_NGRFI_SPRITE_DUMP_SEL), NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_NGRFI_SPRITE_DUMP), SetDataTip(STR_NEWGRF_INSPECT_SPRITE_DUMP, STR_NEWGRF_INSPECT_SPRITE_DUMP_TOOLTIP), EndContainer(), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_NGRFI_DUPLICATE), SetDataTip(STR_NEWGRF_INSPECT_DUPLICATE, STR_NEWGRF_INSPECT_DUPLICATE_TOOLTIP), NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_NGRFI_LOG_CONSOLE), SetDataTip(STR_NEWGRF_INSPECT_LOG_CONSOLE, STR_NEWGRF_INSPECT_LOG_CONSOLE_TOOLTIP), NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_NGRFI_REFRESH), SetDataTip(STR_NEWGRF_INSPECT_REFRESH, STR_NEWGRF_INSPECT_REFRESH_TOOLTIP), NWidget(WWT_SHADEBOX, COLOUR_GREY), @@ -997,7 +1005,7 @@ void DeleteNewGRFInspectWindow(GrfSpecFeature feature, uint index) if (index >= (1 << 27)) return; WindowNumber wno = GetInspectWindowNumber(feature, index); - DeleteWindowById(WC_NEWGRF_INSPECT, wno); + DeleteAllWindowsById(WC_NEWGRF_INSPECT, wno); /* Reinitialise the land information window to remove the "debug" sprite if needed. * Note: Since we might be called from a command here, it is important to not execute diff --git a/src/widgets/newgrf_debug_widget.h b/src/widgets/newgrf_debug_widget.h index 49b162269c..fcf45dfc0d 100644 --- a/src/widgets/newgrf_debug_widget.h +++ b/src/widgets/newgrf_debug_widget.h @@ -21,6 +21,7 @@ enum NewGRFInspectWidgets { WID_NGRFI_SCROLLBAR, ///< Scrollbar. WID_NGRFI_REFRESH, ///< Refresh toggle. WID_NGRFI_LOG_CONSOLE, ///< Log to console + WID_NGRFI_DUPLICATE, ///< Duplicate window WID_NGRFI_SPRITE_DUMP, ///< Dump current sprite group WID_NGRFI_SPRITE_DUMP_SEL, ///< Selection widget for WID_NGRFI_SPRITE_DUMP }; diff --git a/src/window.cpp b/src/window.cpp index dd1ba33ee0..cef50f2531 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -1193,6 +1193,22 @@ void DeleteWindowById(WindowClass cls, WindowNumber number, bool force) } } +/** + * Delete all windows of its class and window number (if open). + * @param cls Window class + * @param number Number of the window within the window class + * @param force force deletion; if false don't delete when stickied + */ +void DeleteAllWindowsById(WindowClass cls, WindowNumber number, bool force) +{ + /* Note: the container remains stable, even when deleting windows. */ + for (Window *w : Window::IterateUnordered()) { + if (w->window_class == cls && w->window_number == number && (force || (w->flags & WF_STICKY) == 0)) { + delete w; + } + } +} + /** * Delete all windows of a given class * @param cls Window class of windows to delete diff --git a/src/window_func.h b/src/window_func.h index d63b4f6af2..c16d041073 100644 --- a/src/window_func.h +++ b/src/window_func.h @@ -54,6 +54,7 @@ void SetWindowDirty(WindowClass cls, WindowNumber number); void SetWindowClassesDirty(WindowClass cls); void DeleteWindowById(WindowClass cls, WindowNumber number, bool force = true); +void DeleteAllWindowsById(WindowClass cls, WindowNumber number, bool force = true); void DeleteWindowByClass(WindowClass cls); bool FocusWindowById(WindowClass cls, WindowNumber number);