2014-11-23 17:28:23 +01:00
|
|
|
/*****************************************************************************
|
2020-07-21 15:04:34 +02:00
|
|
|
* Copyright (c) 2014-2020 OpenRCT2 developers
|
2016-05-04 19:24:41 +02:00
|
|
|
*
|
2018-06-15 14:07:34 +02:00
|
|
|
* For a complete list of all authors, please refer to contributors.md
|
|
|
|
* Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
|
2016-05-04 19:24:41 +02:00
|
|
|
*
|
2018-06-15 14:07:34 +02:00
|
|
|
* OpenRCT2 is licensed under the GNU General Public License version 3.
|
2016-05-04 19:24:41 +02:00
|
|
|
*****************************************************************************/
|
2014-11-23 17:28:23 +01:00
|
|
|
|
2018-01-21 03:39:52 +01:00
|
|
|
#include <algorithm>
|
2018-01-04 00:36:33 +01:00
|
|
|
#include <cctype>
|
2018-06-22 23:21:44 +02:00
|
|
|
#include <openrct2-ui/interface/Dropdown.h>
|
|
|
|
#include <openrct2-ui/interface/Widget.h>
|
|
|
|
#include <openrct2-ui/windows/Window.h>
|
2017-11-23 09:03:56 +01:00
|
|
|
#include <openrct2/Context.h>
|
|
|
|
#include <openrct2/Editor.h>
|
2017-12-05 13:55:33 +01:00
|
|
|
#include <openrct2/EditorObjectSelectionSession.h>
|
2017-11-23 09:03:56 +01:00
|
|
|
#include <openrct2/Game.h>
|
2018-06-22 23:21:44 +02:00
|
|
|
#include <openrct2/OpenRCT2.h>
|
Split actions hpp files into separate h and cpp files (#13548)
* Split up SmallSceneryPlace/Remove
Added undo function for Remove Scenery
* Refactor: Balloon and Banner actions hpp=>h/cpp
* Refactor: rename all action *.hpp files to *.cpp
This is preparation for separation in later commits. Note that without
the complete set of commits in this branch, the code will not build.
* Refactor Clear, Climate, Custom, and Footpath actions hpp=>h/cpp
* VSCode: add src subdirectories to includePath
* Refactor Guest actions hpp=>h/cpp
* Refactor Land actions hpp=>h/cpp
* Refactor LargeScenery actions hpp=>h/cpp
* Refactor Load, Maze, Network actions hpp=>h/cpp
* Refactor Park actions hpp=>h/cpp
* Refactor/style: move private function declarations in actions *.h
Previous action .h files included private function declarations with
private member variables, before public function declarations. This
commit re-orders the header files to the following order:
- public member variables
- private member variables
- public functions
- private functions
* Refactor Pause action hpp=>h/cpp
* Refactor Peep, Place, Player actions hpp=>h/cpp
* Refactor Ride actions hpp=>h/cpp
* Refactor Scenario, Set*, Sign* actions hpp=>h/cpp
* Refactor SmallScenerySetColourAction hpp=>h/cpp
* Refactor Staff actions hpp=>h/cpp
* Refactor Surface, Tile, Track* actions hpp=>h/cpp
* Refactor Wall and Water actions hpp=>h/cpp
* Fix various includes and other compile errors
Update includes for tests.
Move static function declarations to .h files
Add explicit includes to various files that were previously implicit
(the required header was a nested include in an action hpp file, and the
action .h file does not include that header)
Move RideSetStatus string enum to the cpp file to avoid unused imports
* Xcode: modify project file for actions refactor
* Cleanup whitespace and end-of-file newlines
Co-authored-by: duncanspumpkin <duncans_pumpkin@hotmail.co.uk>
2020-12-10 07:39:10 +01:00
|
|
|
#include <openrct2/actions/LoadOrQuitAction.h>
|
2018-06-22 23:21:44 +02:00
|
|
|
#include <openrct2/audio/audio.h>
|
|
|
|
#include <openrct2/config/Config.h>
|
|
|
|
#include <openrct2/core/String.hpp>
|
2021-01-18 21:25:57 +01:00
|
|
|
#include <openrct2/drawing/Drawing.h>
|
2018-01-06 18:32:25 +01:00
|
|
|
#include <openrct2/localisation/Localisation.h>
|
2018-01-21 03:39:52 +01:00
|
|
|
#include <openrct2/object/ObjectList.h>
|
2017-11-23 09:03:56 +01:00
|
|
|
#include <openrct2/object/ObjectManager.h>
|
|
|
|
#include <openrct2/object/ObjectRepository.h>
|
2017-12-05 13:55:33 +01:00
|
|
|
#include <openrct2/object/RideObject.h>
|
2017-11-23 09:03:56 +01:00
|
|
|
#include <openrct2/platform/platform.h>
|
2020-06-20 02:32:52 +02:00
|
|
|
#include <openrct2/ride/RideData.h>
|
2018-08-29 23:29:45 +02:00
|
|
|
#include <openrct2/scenario/Scenario.h>
|
2017-11-23 09:03:56 +01:00
|
|
|
#include <openrct2/sprites.h>
|
2017-12-13 13:02:24 +01:00
|
|
|
#include <openrct2/util/Util.h>
|
2017-11-23 09:03:56 +01:00
|
|
|
#include <openrct2/windows/Intent.h>
|
2018-06-22 23:21:44 +02:00
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
2015-09-10 23:16:41 +02:00
|
|
|
|
2018-05-16 20:41:29 +02:00
|
|
|
// clang-format off
|
2018-01-31 13:07:20 +01:00
|
|
|
enum
|
|
|
|
{
|
|
|
|
FILTER_RCT1 = (1 << 0),
|
|
|
|
FILTER_AA = (1 << 1),
|
|
|
|
FILTER_LL = (1 << 2),
|
|
|
|
FILTER_RCT2 = (1 << 3),
|
|
|
|
FILTER_WW = (1 << 4),
|
|
|
|
FILTER_TT = (1 << 5),
|
|
|
|
FILTER_OO = (1 << 6),
|
|
|
|
FILTER_CUSTOM = (1 << 7),
|
|
|
|
|
|
|
|
FILTER_RIDE_TRANSPORT = (1 << 8),
|
|
|
|
FILTER_RIDE_GENTLE = (1 << 9),
|
|
|
|
FILTER_RIDE_COASTER = (1 << 10),
|
|
|
|
FILTER_RIDE_THRILL = (1 << 11),
|
|
|
|
FILTER_RIDE_WATER = (1 << 12),
|
|
|
|
FILTER_RIDE_STALL = (1 << 13),
|
|
|
|
|
|
|
|
FILTER_SELECTED = (1 << 14),
|
|
|
|
FILTER_NONSELECTED = (1 << 15),
|
2017-06-06 23:24:18 +02:00
|
|
|
|
|
|
|
FILTER_RIDES = FILTER_RIDE_TRANSPORT | FILTER_RIDE_GENTLE | FILTER_RIDE_COASTER | FILTER_RIDE_THRILL | FILTER_RIDE_WATER | FILTER_RIDE_STALL,
|
2018-01-31 13:07:20 +01:00
|
|
|
FILTER_ALL = FILTER_RIDES | FILTER_RCT1 | FILTER_AA | FILTER_LL | FILTER_RCT2 | FILTER_WW | FILTER_TT | FILTER_OO | FILTER_CUSTOM | FILTER_SELECTED | FILTER_NONSELECTED,
|
2017-08-02 00:20:32 +02:00
|
|
|
};
|
2015-06-03 18:37:07 +02:00
|
|
|
|
2018-06-20 17:28:51 +02:00
|
|
|
static constexpr uint8_t _numSourceGameItems = 8;
|
2018-01-31 13:07:20 +01:00
|
|
|
|
2018-06-20 17:28:51 +02:00
|
|
|
static uint32_t _filter_flags;
|
2020-11-09 11:53:29 +01:00
|
|
|
static uint16_t _filter_object_counts[EnumValue(ObjectType::Count)];
|
2015-06-03 18:37:07 +02:00
|
|
|
|
2017-11-23 12:08:04 +01:00
|
|
|
static char _filter_string[MAX_PATH];
|
2015-06-06 00:54:47 +02:00
|
|
|
|
2015-06-03 18:37:07 +02:00
|
|
|
#define _FILTER_ALL ((_filter_flags & FILTER_ALL) == FILTER_ALL)
|
2018-01-31 13:07:20 +01:00
|
|
|
#define _FILTER_RCT1 (_filter_flags & FILTER_RCT1)
|
|
|
|
#define _FILTER_AA (_filter_flags & FILTER_AA)
|
|
|
|
#define _FILTER_LL (_filter_flags & FILTER_LL)
|
2015-06-03 18:37:07 +02:00
|
|
|
#define _FILTER_RCT2 (_filter_flags & FILTER_RCT2)
|
|
|
|
#define _FILTER_WW (_filter_flags & FILTER_WW)
|
|
|
|
#define _FILTER_TT (_filter_flags & FILTER_TT)
|
2018-01-31 13:07:20 +01:00
|
|
|
#define _FILTER_OO (_filter_flags & FILTER_OO)
|
2015-06-03 18:37:07 +02:00
|
|
|
#define _FILTER_CUSTOM (_filter_flags & FILTER_CUSTOM)
|
2016-06-21 20:41:07 +02:00
|
|
|
#define _FILTER_SELECTED (_filter_flags & FILTER_SELECTED)
|
|
|
|
#define _FILTER_NONSELECTED (_filter_flags & FILTER_NONSELECTED)
|
2014-11-25 00:05:35 +01:00
|
|
|
|
2020-05-05 22:26:14 +02:00
|
|
|
static constexpr const rct_string_id WINDOW_TITLE = STR_OBJECT_SELECTION;
|
|
|
|
static constexpr const int32_t WH = 400;
|
|
|
|
static constexpr const int32_t WW = 600;
|
2019-10-19 04:02:31 +02:00
|
|
|
|
2018-05-14 13:27:25 +02:00
|
|
|
struct ObjectPageDesc
|
|
|
|
{
|
|
|
|
rct_string_id Caption;
|
2018-06-20 17:28:51 +02:00
|
|
|
uint32_t Image;
|
2018-05-14 13:27:25 +02:00
|
|
|
bool IsAdvanced;
|
2015-02-11 17:02:57 +01:00
|
|
|
};
|
|
|
|
|
2018-12-10 00:09:42 +01:00
|
|
|
static constexpr const ObjectPageDesc ObjectSelectionPages[] = {
|
2018-05-14 13:27:25 +02:00
|
|
|
{ STR_OBJECT_SELECTION_RIDE_VEHICLES_ATTRACTIONS, SPR_TAB_RIDE_16, false },
|
|
|
|
{ STR_OBJECT_SELECTION_SMALL_SCENERY, SPR_TAB_SCENERY_TREES, true },
|
|
|
|
{ STR_OBJECT_SELECTION_LARGE_SCENERY, SPR_TAB_SCENERY_URBAN, true },
|
|
|
|
{ STR_OBJECT_SELECTION_WALLS_FENCES, SPR_TAB_SCENERY_WALLS, true },
|
|
|
|
{ STR_OBJECT_SELECTION_PATH_SIGNS, SPR_TAB_SCENERY_SIGNAGE, true },
|
|
|
|
{ STR_OBJECT_SELECTION_FOOTPATHS, SPR_TAB_SCENERY_PATHS, false },
|
|
|
|
{ STR_OBJECT_SELECTION_PATH_EXTRAS, SPR_TAB_SCENERY_PATH_ITEMS, false },
|
|
|
|
{ STR_OBJECT_SELECTION_SCENERY_GROUPS, SPR_TAB_SCENERY_STATUES, false },
|
|
|
|
{ STR_OBJECT_SELECTION_PARK_ENTRANCE, SPR_TAB_PARK, false },
|
|
|
|
{ STR_OBJECT_SELECTION_WATER, SPR_TAB_WATER, false },
|
2018-12-10 00:09:42 +01:00
|
|
|
|
|
|
|
// Currently hidden until new save format arrives:
|
|
|
|
// { STR_OBJECT_SELECTION_TERRAIN_SURFACES, SPR_G2_TAB_LAND, false },
|
|
|
|
// { STR_OBJECT_SELECTION_TERRAIN_EDGES, SPR_G2_TAB_LAND, false },
|
|
|
|
// { STR_OBJECT_SELECTION_STATIONS, SPR_TAB_PARK, false },
|
|
|
|
// { STR_OBJECT_SELECTION_MUSIC, SPR_TAB_MUSIC_0, false },
|
2016-07-14 14:07:49 +02:00
|
|
|
};
|
|
|
|
|
2014-11-25 00:05:35 +01:00
|
|
|
#pragma region Widgets
|
|
|
|
|
2020-06-18 19:54:16 +02:00
|
|
|
enum WINDOW_EDITOR_OBJECT_SELECTION_WIDGET_IDX {
|
2018-05-14 13:27:25 +02:00
|
|
|
WIDX_BACKGROUND,
|
|
|
|
WIDX_TITLE,
|
|
|
|
WIDX_CLOSE,
|
|
|
|
WIDX_TAB_CONTENT_PANEL,
|
|
|
|
WIDX_ADVANCED,
|
|
|
|
WIDX_LIST,
|
|
|
|
WIDX_PREVIEW,
|
|
|
|
WIDX_INSTALL_TRACK,
|
|
|
|
WIDX_FILTER_DROPDOWN,
|
2020-06-18 19:54:16 +02:00
|
|
|
WIDX_FILTER_TEXT_BOX,
|
2018-05-14 13:27:25 +02:00
|
|
|
WIDX_FILTER_CLEAR_BUTTON,
|
|
|
|
WIDX_FILTER_RIDE_TAB_FRAME,
|
2017-06-06 23:24:18 +02:00
|
|
|
WIDX_FILTER_RIDE_TAB_ALL,
|
|
|
|
WIDX_FILTER_RIDE_TAB_TRANSPORT,
|
|
|
|
WIDX_FILTER_RIDE_TAB_GENTLE,
|
|
|
|
WIDX_FILTER_RIDE_TAB_COASTER,
|
|
|
|
WIDX_FILTER_RIDE_TAB_THRILL,
|
|
|
|
WIDX_FILTER_RIDE_TAB_WATER,
|
|
|
|
WIDX_FILTER_RIDE_TAB_STALL,
|
|
|
|
WIDX_LIST_SORT_TYPE,
|
|
|
|
WIDX_LIST_SORT_RIDE,
|
2018-05-14 13:27:25 +02:00
|
|
|
WIDX_TAB_1,
|
2015-02-11 17:02:57 +01:00
|
|
|
};
|
|
|
|
|
2017-05-02 02:01:29 +02:00
|
|
|
validate_global_widx(WC_EDITOR_OBJECT_SELECTION, WIDX_TAB_1);
|
|
|
|
|
2018-05-14 13:27:25 +02:00
|
|
|
static bool _window_editor_object_selection_widgets_initialised;
|
|
|
|
static std::vector<rct_widget> _window_editor_object_selection_widgets = {
|
2020-05-09 16:44:21 +02:00
|
|
|
WINDOW_SHIM(WINDOW_TITLE, WW, WH),
|
2020-11-27 04:14:20 +01:00
|
|
|
MakeWidget({ 0, 43}, {600, 357}, WindowWidgetType::Resize, WindowColour::Secondary ),
|
|
|
|
MakeWidget({470, 22}, {122, 14}, WindowWidgetType::Button, WindowColour::Primary, STR_OBJECT_SELECTION_ADVANCED, STR_OBJECT_SELECTION_ADVANCED_TIP),
|
|
|
|
MakeWidget({ 4, 60}, {288, 327}, WindowWidgetType::Scroll, WindowColour::Secondary, SCROLL_VERTICAL ),
|
|
|
|
MakeWidget({391, 45}, {114, 115}, WindowWidgetType::FlatBtn, WindowColour::Secondary ),
|
|
|
|
MakeWidget({470, 22}, {122, 14}, WindowWidgetType::Button, WindowColour::Primary, STR_INSTALL_NEW_TRACK_DESIGN, STR_INSTALL_NEW_TRACK_DESIGN_TIP ),
|
|
|
|
MakeWidget({350, 22}, {114, 14}, WindowWidgetType::Button, WindowColour::Primary, STR_OBJECT_FILTER, STR_OBJECT_FILTER_TIP ),
|
|
|
|
MakeWidget({ 4, 45}, {211, 14}, WindowWidgetType::TextBox, WindowColour::Secondary ),
|
|
|
|
MakeWidget({218, 45}, { 70, 14}, WindowWidgetType::Button, WindowColour::Secondary, STR_OBJECT_SEARCH_CLEAR ),
|
|
|
|
MakeWidget({ 3, 73}, {285, 4}, WindowWidgetType::ImgBtn, WindowColour::Secondary ),
|
2020-08-29 04:31:31 +02:00
|
|
|
MakeTab ({ 3, 47}, STR_OBJECT_FILTER_ALL_RIDES_TIP ),
|
|
|
|
MakeTab ({ 34, 47}, STR_TRANSPORT_RIDES_TIP ),
|
|
|
|
MakeTab ({ 65, 47}, STR_GENTLE_RIDES_TIP ),
|
|
|
|
MakeTab ({ 96, 47}, STR_ROLLER_COASTERS_TIP ),
|
|
|
|
MakeTab ({127, 47}, STR_THRILL_RIDES_TIP ),
|
|
|
|
MakeTab ({158, 47}, STR_WATER_RIDES_TIP ),
|
|
|
|
MakeTab ({189, 47}, STR_SHOPS_STALLS_TIP ),
|
2020-11-27 04:14:20 +01:00
|
|
|
MakeWidget({ 4, 80}, {145, 14}, WindowWidgetType::TableHeader, WindowColour::Secondary ),
|
|
|
|
MakeWidget({149, 80}, {143, 14}, WindowWidgetType::TableHeader, WindowColour::Secondary ),
|
2020-08-29 04:31:31 +02:00
|
|
|
|
|
|
|
MakeTab ({ 3, 17}, STR_STRING_DEFINED_TOOLTIP ),
|
2018-05-14 13:27:25 +02:00
|
|
|
// Copied object type times...
|
|
|
|
|
2017-06-06 23:24:18 +02:00
|
|
|
{ WIDGETS_END }
|
2014-11-25 00:05:35 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
#pragma endregion
|
|
|
|
|
|
|
|
#pragma region Events
|
|
|
|
|
2015-07-10 02:39:16 +02:00
|
|
|
static void window_editor_object_selection_close(rct_window *w);
|
2017-05-01 15:41:45 +02:00
|
|
|
static void window_editor_object_selection_mouseup(rct_window *w, rct_widgetindex widgetIndex);
|
2015-07-10 02:39:16 +02:00
|
|
|
static void window_editor_object_selection_resize(rct_window *w);
|
2017-07-03 23:09:46 +02:00
|
|
|
static void window_editor_object_selection_mousedown(rct_window *w, rct_widgetindex widgetIndex, rct_widget* widget);
|
2018-06-20 17:28:51 +02:00
|
|
|
static void window_editor_object_selection_dropdown(rct_window *w, rct_widgetindex widgetIndex, int32_t dropdownIndex);
|
2015-06-06 23:04:53 +02:00
|
|
|
static void window_editor_object_selection_update(rct_window *w);
|
2018-06-20 17:28:51 +02:00
|
|
|
static void window_editor_object_selection_scrollgetsize(rct_window *w, int32_t scrollIndex, int32_t *width, int32_t *height);
|
2020-02-29 03:43:29 +01:00
|
|
|
static void window_editor_object_selection_scroll_mousedown(rct_window *w, int32_t scrollIndex, const ScreenCoordsXY& screenCoords);
|
|
|
|
static void window_editor_object_selection_scroll_mouseover(rct_window *w, int32_t scrollIndex, const ScreenCoordsXY& screenCoords);
|
2020-10-10 15:49:56 +02:00
|
|
|
static OpenRCT2String window_editor_object_selection_tooltip(rct_window* w, const rct_widgetindex widgetIndex, const rct_string_id fallback);
|
2015-07-10 02:39:16 +02:00
|
|
|
static void window_editor_object_selection_invalidate(rct_window *w);
|
|
|
|
static void window_editor_object_selection_paint(rct_window *w, rct_drawpixelinfo *dpi);
|
2018-06-20 17:28:51 +02:00
|
|
|
static void window_editor_object_selection_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi, int32_t scrollIndex);
|
2017-05-01 15:41:45 +02:00
|
|
|
static void window_editor_object_selection_textinput(rct_window *w, rct_widgetindex widgetIndex, char *text);
|
2015-07-10 02:39:16 +02:00
|
|
|
|
2020-09-28 20:36:15 +02:00
|
|
|
static rct_window_event_list window_editor_object_selection_events([](auto& events)
|
|
|
|
{
|
|
|
|
events.close = &window_editor_object_selection_close;
|
|
|
|
events.mouse_up = &window_editor_object_selection_mouseup;
|
|
|
|
events.resize = &window_editor_object_selection_resize;
|
|
|
|
events.mouse_down = &window_editor_object_selection_mousedown;
|
|
|
|
events.dropdown = &window_editor_object_selection_dropdown;
|
|
|
|
events.update = &window_editor_object_selection_update;
|
|
|
|
events.get_scroll_size = &window_editor_object_selection_scrollgetsize;
|
|
|
|
events.scroll_mousedown = &window_editor_object_selection_scroll_mousedown;
|
|
|
|
events.scroll_mouseover = &window_editor_object_selection_scroll_mouseover;
|
|
|
|
events.text_input = &window_editor_object_selection_textinput;
|
|
|
|
events.tooltip = &window_editor_object_selection_tooltip;
|
|
|
|
events.invalidate = &window_editor_object_selection_invalidate;
|
|
|
|
events.paint = &window_editor_object_selection_paint;
|
|
|
|
events.scroll_paint = &window_editor_object_selection_scrollpaint;
|
|
|
|
});
|
2018-05-16 20:41:29 +02:00
|
|
|
// clang-format on
|
2014-11-25 00:05:35 +01:00
|
|
|
|
|
|
|
#pragma endregion
|
|
|
|
|
2018-06-20 17:28:51 +02:00
|
|
|
static constexpr const int32_t window_editor_object_selection_animation_loops[] = { 20, 32, 10, 72, 24, 28, 16 };
|
|
|
|
static constexpr const int32_t window_editor_object_selection_animation_divisor[] = { 4, 8, 2, 4, 4, 4, 2 };
|
2015-06-26 02:11:24 +02:00
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
static void window_editor_object_set_page(rct_window* w, int32_t page);
|
|
|
|
static void window_editor_object_selection_set_pressed_tab(rct_window* w);
|
2020-11-10 09:00:15 +01:00
|
|
|
static int32_t get_object_from_object_selection(ObjectType object_type, int32_t y);
|
2015-02-13 19:43:22 +01:00
|
|
|
static void window_editor_object_selection_manage_tracks();
|
2015-02-11 17:02:57 +01:00
|
|
|
static void editor_load_selected_objects();
|
2018-06-20 17:28:51 +02:00
|
|
|
static bool filter_selected(uint8_t objectFlags);
|
2018-06-22 23:21:44 +02:00
|
|
|
static bool filter_string(const ObjectRepositoryItem* item);
|
2018-07-03 12:53:29 +02:00
|
|
|
static bool filter_source(const ObjectRepositoryItem* item);
|
2018-06-22 23:21:44 +02:00
|
|
|
static bool filter_chunks(const ObjectRepositoryItem* item);
|
2015-06-06 00:54:47 +02:00
|
|
|
static void filter_update_counts();
|
2014-11-23 17:28:23 +01:00
|
|
|
|
2020-10-14 21:56:48 +02:00
|
|
|
static std::string object_get_description(const Object* object);
|
2020-11-09 11:53:29 +01:00
|
|
|
static ObjectType get_selected_object_type(rct_window* w);
|
2017-12-05 13:55:33 +01:00
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
enum
|
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
RIDE_SORT_TYPE,
|
|
|
|
RIDE_SORT_RIDE
|
2015-06-26 02:11:24 +02:00
|
|
|
};
|
2015-06-25 17:48:32 +02:00
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
enum
|
|
|
|
{
|
2018-01-31 13:07:20 +01:00
|
|
|
DDIX_FILTER_RCT1,
|
|
|
|
DDIX_FILTER_AA,
|
|
|
|
DDIX_FILTER_LL,
|
2017-06-06 23:24:18 +02:00
|
|
|
DDIX_FILTER_RCT2,
|
|
|
|
DDIX_FILTER_WW,
|
|
|
|
DDIX_FILTER_TT,
|
2018-01-31 13:07:20 +01:00
|
|
|
DDIX_FILTER_OO,
|
2017-06-06 23:24:18 +02:00
|
|
|
DDIX_FILTER_CUSTOM,
|
2017-11-13 16:25:31 +01:00
|
|
|
DDIX_FILTER_SEPARATOR,
|
2017-06-06 23:24:18 +02:00
|
|
|
DDIX_FILTER_SELECTED,
|
|
|
|
DDIX_FILTER_NONSELECTED,
|
2016-06-30 22:55:18 +02:00
|
|
|
};
|
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
struct list_item
|
|
|
|
{
|
|
|
|
const ObjectRepositoryItem* repositoryItem;
|
|
|
|
rct_object_entry* entry;
|
2020-04-19 21:28:01 +02:00
|
|
|
std::unique_ptr<rct_object_filters> filter;
|
2018-06-22 23:21:44 +02:00
|
|
|
uint8_t* flags;
|
2018-02-14 09:42:26 +01:00
|
|
|
};
|
2015-06-25 17:48:32 +02:00
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
static rct_string_id get_ride_type_string_id(const ObjectRepositoryItem* item);
|
2016-07-02 11:59:50 +02:00
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
using sortFunc_t = bool (*)(const list_item&, const list_item&);
|
2015-06-26 02:11:24 +02:00
|
|
|
|
2018-01-21 03:39:52 +01:00
|
|
|
static std::vector<list_item> _listItems;
|
2018-06-20 17:28:51 +02:00
|
|
|
static int32_t _listSortType = RIDE_SORT_TYPE;
|
2015-06-26 02:11:24 +02:00
|
|
|
static bool _listSortDescending = false;
|
2020-10-14 21:56:48 +02:00
|
|
|
static std::unique_ptr<Object> _loadedObject;
|
2015-06-25 17:48:32 +02:00
|
|
|
|
|
|
|
static void visible_list_dispose()
|
|
|
|
{
|
2018-01-21 03:39:52 +01:00
|
|
|
_listItems.clear();
|
|
|
|
_listItems.shrink_to_fit();
|
2015-06-25 17:48:32 +02:00
|
|
|
}
|
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
static bool visible_list_sort_ride_name(const list_item& a, const list_item& b)
|
2015-06-26 02:11:24 +02:00
|
|
|
{
|
2018-05-14 14:05:59 +02:00
|
|
|
auto nameA = a.repositoryItem->Name.c_str();
|
|
|
|
auto nameB = b.repositoryItem->Name.c_str();
|
2018-01-21 03:39:52 +01:00
|
|
|
return strcmp(nameA, nameB) < 0;
|
2015-06-26 02:11:24 +02:00
|
|
|
}
|
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
static bool visible_list_sort_ride_type(const list_item& a, const list_item& b)
|
2015-06-25 17:48:32 +02:00
|
|
|
{
|
2018-01-21 03:39:52 +01:00
|
|
|
auto rideTypeA = language_get_string(get_ride_type_string_id(a.repositoryItem));
|
|
|
|
auto rideTypeB = language_get_string(get_ride_type_string_id(b.repositoryItem));
|
2018-06-20 17:28:51 +02:00
|
|
|
int32_t result = String::Compare(rideTypeA, rideTypeB);
|
2018-06-22 23:21:44 +02:00
|
|
|
return result != 0 ? result < 0 : visible_list_sort_ride_name(a, b);
|
2015-06-25 17:48:32 +02:00
|
|
|
}
|
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
static void visible_list_refresh(rct_window* w)
|
2015-06-25 17:48:32 +02:00
|
|
|
{
|
2020-04-18 13:32:48 +02:00
|
|
|
int32_t numObjects = static_cast<int32_t>(object_repository_get_items_count());
|
2017-06-06 23:24:18 +02:00
|
|
|
|
|
|
|
visible_list_dispose();
|
|
|
|
w->selected_list_item = -1;
|
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
const ObjectRepositoryItem* items = object_repository_get_items();
|
|
|
|
for (int32_t i = 0; i < numObjects; i++)
|
|
|
|
{
|
2018-06-20 17:28:51 +02:00
|
|
|
uint8_t selectionFlags = _objectSelectionFlags[i];
|
2018-06-22 23:21:44 +02:00
|
|
|
const ObjectRepositoryItem* item = &items[i];
|
2020-11-10 09:00:15 +01:00
|
|
|
ObjectType objectType = item->ObjectEntry.GetType();
|
2018-07-30 22:44:59 +02:00
|
|
|
if (objectType == get_selected_object_type(w) && !(selectionFlags & OBJECT_SELECTION_FLAG_6) && filter_source(item)
|
|
|
|
&& filter_string(item) && filter_chunks(item) && filter_selected(selectionFlags))
|
2018-06-22 23:21:44 +02:00
|
|
|
{
|
2020-04-19 21:28:01 +02:00
|
|
|
auto filter = std::make_unique<rct_object_filters>();
|
2017-08-02 00:20:32 +02:00
|
|
|
filter->ride.category[0] = 0;
|
|
|
|
filter->ride.category[1] = 0;
|
|
|
|
filter->ride.ride_type = 0;
|
2018-01-21 03:39:52 +01:00
|
|
|
|
|
|
|
list_item currentListItem;
|
|
|
|
currentListItem.repositoryItem = item;
|
2020-04-18 13:32:48 +02:00
|
|
|
currentListItem.entry = const_cast<rct_object_entry*>(&item->ObjectEntry);
|
2020-04-19 21:28:01 +02:00
|
|
|
currentListItem.filter = std::move(filter);
|
2018-01-21 03:39:52 +01:00
|
|
|
currentListItem.flags = &_objectSelectionFlags[i];
|
|
|
|
_listItems.push_back(std::move(currentListItem));
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-20 20:39:47 +02:00
|
|
|
if (_listItems.empty())
|
2017-06-06 23:24:18 +02:00
|
|
|
{
|
|
|
|
visible_list_dispose();
|
|
|
|
}
|
2018-01-21 03:39:52 +01:00
|
|
|
else
|
|
|
|
{
|
2017-08-15 10:07:44 +02:00
|
|
|
sortFunc_t sortFunc = nullptr;
|
2018-01-21 03:39:52 +01:00
|
|
|
switch (_listSortType)
|
|
|
|
{
|
2018-06-22 23:21:44 +02:00
|
|
|
case RIDE_SORT_TYPE:
|
|
|
|
sortFunc = visible_list_sort_ride_type;
|
|
|
|
break;
|
|
|
|
case RIDE_SORT_RIDE:
|
|
|
|
sortFunc = visible_list_sort_ride_name;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
log_warning("Wrong sort type %d, leaving list as-is.", _listSortType);
|
|
|
|
break;
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
2018-01-21 03:39:52 +01:00
|
|
|
if (sortFunc != nullptr)
|
|
|
|
{
|
|
|
|
std::sort(_listItems.begin(), _listItems.end(), sortFunc);
|
|
|
|
if (_listSortDescending)
|
|
|
|
{
|
|
|
|
std::reverse(_listItems.begin(), _listItems.end());
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-06-15 17:20:16 +02:00
|
|
|
w->Invalidate();
|
2015-06-26 02:11:24 +02:00
|
|
|
}
|
2015-06-25 17:48:32 +02:00
|
|
|
|
2018-05-14 13:27:25 +02:00
|
|
|
static void window_editor_object_selection_init_widgets()
|
|
|
|
{
|
2018-06-22 23:21:44 +02:00
|
|
|
auto& widgets = _window_editor_object_selection_widgets;
|
2018-05-14 13:27:25 +02:00
|
|
|
if (!_window_editor_object_selection_widgets_initialised)
|
|
|
|
{
|
|
|
|
_window_editor_object_selection_widgets_initialised = true;
|
2018-05-14 14:05:59 +02:00
|
|
|
auto tabWidget = widgets[widgets.size() - 2];
|
2018-12-10 20:50:12 +01:00
|
|
|
for (size_t i = 1; i < std::size(ObjectSelectionPages); i++)
|
2018-05-14 13:27:25 +02:00
|
|
|
{
|
|
|
|
widgets.insert(widgets.end() - 1, tabWidget);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-23 17:28:23 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006AA64E
|
|
|
|
*/
|
2018-06-22 23:21:44 +02:00
|
|
|
rct_window* window_editor_object_selection_open()
|
2014-11-23 17:28:23 +01:00
|
|
|
{
|
2018-05-14 13:27:25 +02:00
|
|
|
window_editor_object_selection_init_widgets();
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2018-05-14 13:27:25 +02:00
|
|
|
auto window = window_bring_to_front_by_class(WC_EDITOR_OBJECT_SELECTION);
|
2017-08-15 10:07:44 +02:00
|
|
|
if (window != nullptr)
|
2017-11-23 09:03:56 +01:00
|
|
|
return window;
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2018-02-11 18:56:12 +01:00
|
|
|
sub_6AB211();
|
2017-06-06 23:24:18 +02:00
|
|
|
reset_selected_object_count_and_size();
|
|
|
|
|
2020-11-04 05:52:23 +01:00
|
|
|
window = WindowCreateCentred(
|
2018-06-22 23:21:44 +02:00
|
|
|
600, 400, &window_editor_object_selection_events, WC_EDITOR_OBJECT_SELECTION, WF_10 | WF_RESIZABLE);
|
2018-05-14 13:27:25 +02:00
|
|
|
window->widgets = _window_editor_object_selection_widgets.data();
|
2020-06-18 19:54:16 +02:00
|
|
|
window->widgets[WIDX_FILTER_TEXT_BOX].string = _filter_string;
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
window->enabled_widgets = (1 << WIDX_ADVANCED) | (1 << WIDX_INSTALL_TRACK) | (1 << WIDX_FILTER_DROPDOWN)
|
2020-06-18 19:54:16 +02:00
|
|
|
| (1 << WIDX_FILTER_TEXT_BOX) | (1 << WIDX_FILTER_CLEAR_BUTTON) | (1 << WIDX_CLOSE) | (1 << WIDX_LIST_SORT_TYPE)
|
2020-04-18 13:32:48 +02:00
|
|
|
| (1UL << WIDX_LIST_SORT_RIDE);
|
2017-06-06 23:24:18 +02:00
|
|
|
|
|
|
|
_filter_flags = gConfigInterface.object_selection_filter_flags;
|
2018-12-15 22:23:31 +01:00
|
|
|
std::fill_n(_filter_string, sizeof(_filter_string), 0x00);
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2018-12-16 10:02:40 +01:00
|
|
|
for (size_t i = WIDX_TAB_1; i < WIDX_TAB_1 + std::size(ObjectSelectionPages); i++)
|
2018-05-14 13:27:25 +02:00
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
window->enabled_widgets |= (1LL << i);
|
2018-05-14 13:27:25 +02:00
|
|
|
}
|
2020-11-04 05:52:23 +01:00
|
|
|
WindowInitScrollWidgets(window);
|
2017-06-06 23:24:18 +02:00
|
|
|
|
|
|
|
window->selected_tab = 0;
|
|
|
|
window->selected_list_item = -1;
|
2017-10-15 15:53:16 +02:00
|
|
|
window->object_entry = nullptr;
|
2017-06-06 23:24:18 +02:00
|
|
|
window->min_width = 600;
|
|
|
|
window->min_height = 400;
|
|
|
|
window->max_width = 1200;
|
|
|
|
window->max_height = 1000;
|
|
|
|
|
|
|
|
visible_list_refresh(window);
|
2017-11-23 09:03:56 +01:00
|
|
|
|
|
|
|
return window;
|
2014-11-25 00:05:35 +01:00
|
|
|
}
|
|
|
|
|
2015-02-11 17:02:57 +01:00
|
|
|
/**
|
2015-10-20 20:16:30 +02:00
|
|
|
*
|
2015-02-11 17:02:57 +01:00
|
|
|
* rct2: 0x006AB199
|
|
|
|
*/
|
2018-06-22 23:21:44 +02:00
|
|
|
static void window_editor_object_selection_close(rct_window* w)
|
2015-02-11 17:02:57 +01:00
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
unload_unselected_objects();
|
|
|
|
editor_load_selected_objects();
|
|
|
|
editor_object_flags_free();
|
|
|
|
|
2020-10-14 21:56:48 +02:00
|
|
|
if (_loadedObject != nullptr)
|
|
|
|
_loadedObject->Unload();
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
if (gScreenFlags & SCREEN_FLAGS_EDITOR)
|
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
research_populate_list_random();
|
|
|
|
}
|
2018-06-22 23:21:44 +02:00
|
|
|
else
|
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
// Used for in-game object selection cheat
|
|
|
|
// This resets the ride selection list and resets research to 0 on current item
|
|
|
|
gSilentResearch = true;
|
|
|
|
research_reset_current_item();
|
|
|
|
gSilentResearch = false;
|
|
|
|
}
|
2017-10-07 01:28:00 +02:00
|
|
|
|
|
|
|
auto intent = Intent(INTENT_ACTION_REFRESH_NEW_RIDES);
|
|
|
|
context_broadcast_intent(&intent);
|
2017-06-06 23:24:18 +02:00
|
|
|
|
|
|
|
visible_list_dispose();
|
2017-11-11 15:03:59 +01:00
|
|
|
|
2017-11-12 02:32:11 +01:00
|
|
|
intent = Intent(INTENT_ACTION_REFRESH_SCENERY);
|
|
|
|
context_broadcast_intent(&intent);
|
2015-02-11 17:02:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2015-10-20 20:16:30 +02:00
|
|
|
*
|
2015-02-11 17:02:57 +01:00
|
|
|
* rct2: 0x006AAFAB
|
|
|
|
*/
|
2018-06-22 23:21:44 +02:00
|
|
|
static void window_editor_object_selection_mouseup(rct_window* w, rct_widgetindex widgetIndex)
|
2014-11-25 00:05:35 +01:00
|
|
|
{
|
2018-06-22 23:21:44 +02:00
|
|
|
switch (widgetIndex)
|
|
|
|
{
|
|
|
|
case WIDX_CLOSE:
|
2020-04-24 17:19:06 +02:00
|
|
|
window_close(w);
|
2018-06-22 23:21:44 +02:00
|
|
|
if (gScreenFlags & SCREEN_FLAGS_EDITOR)
|
|
|
|
{
|
2020-04-24 17:19:06 +02:00
|
|
|
finish_object_selection();
|
2018-06-22 23:21:44 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case WIDX_FILTER_RIDE_TAB_ALL:
|
|
|
|
_filter_flags |= FILTER_RIDES;
|
|
|
|
gConfigInterface.object_selection_filter_flags = _filter_flags;
|
|
|
|
config_save_default();
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
filter_update_counts();
|
|
|
|
visible_list_refresh(w);
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
w->selected_list_item = -1;
|
|
|
|
w->object_entry = nullptr;
|
|
|
|
w->scrolls[0].v_top = 0;
|
2019-06-15 17:20:16 +02:00
|
|
|
w->Invalidate();
|
2018-06-22 23:21:44 +02:00
|
|
|
break;
|
|
|
|
case WIDX_FILTER_RIDE_TAB_TRANSPORT:
|
|
|
|
case WIDX_FILTER_RIDE_TAB_GENTLE:
|
|
|
|
case WIDX_FILTER_RIDE_TAB_COASTER:
|
|
|
|
case WIDX_FILTER_RIDE_TAB_THRILL:
|
|
|
|
case WIDX_FILTER_RIDE_TAB_WATER:
|
|
|
|
case WIDX_FILTER_RIDE_TAB_STALL:
|
|
|
|
_filter_flags &= ~FILTER_RIDES;
|
|
|
|
_filter_flags |= (1 << (widgetIndex - WIDX_FILTER_RIDE_TAB_TRANSPORT + _numSourceGameItems));
|
|
|
|
gConfigInterface.object_selection_filter_flags = _filter_flags;
|
|
|
|
config_save_default();
|
|
|
|
|
|
|
|
filter_update_counts();
|
|
|
|
visible_list_refresh(w);
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
w->selected_list_item = -1;
|
|
|
|
w->object_entry = nullptr;
|
|
|
|
w->scrolls[0].v_top = 0;
|
|
|
|
w->frame_no = 0;
|
2019-06-15 17:20:16 +02:00
|
|
|
w->Invalidate();
|
2018-06-22 23:21:44 +02:00
|
|
|
break;
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
case WIDX_ADVANCED:
|
|
|
|
w->list_information_type ^= 1;
|
2019-06-15 17:20:16 +02:00
|
|
|
w->Invalidate();
|
2018-06-22 23:21:44 +02:00
|
|
|
break;
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
case WIDX_INSTALL_TRACK:
|
2017-09-12 00:04:03 +02:00
|
|
|
{
|
2018-06-22 23:21:44 +02:00
|
|
|
if (w->selected_list_item != -1)
|
|
|
|
{
|
|
|
|
w->selected_list_item = -1;
|
|
|
|
}
|
2019-06-15 17:20:16 +02:00
|
|
|
w->Invalidate();
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
auto intent = Intent(WC_LOADSAVE);
|
|
|
|
intent.putExtra(INTENT_EXTRA_LOADSAVE_TYPE, LOADSAVETYPE_LOAD | LOADSAVETYPE_TRACK);
|
|
|
|
context_open_intent(&intent);
|
|
|
|
break;
|
2018-05-14 13:27:25 +02:00
|
|
|
}
|
2020-06-18 19:54:16 +02:00
|
|
|
case WIDX_FILTER_TEXT_BOX:
|
2018-06-22 23:21:44 +02:00
|
|
|
window_start_textbox(w, widgetIndex, STR_STRING, _filter_string, sizeof(_filter_string));
|
|
|
|
break;
|
|
|
|
case WIDX_FILTER_CLEAR_BUTTON:
|
2018-12-15 22:23:31 +01:00
|
|
|
std::fill_n(_filter_string, sizeof(_filter_string), 0x00);
|
2018-06-22 23:21:44 +02:00
|
|
|
filter_update_counts();
|
|
|
|
w->scrolls->v_top = 0;
|
|
|
|
visible_list_refresh(w);
|
2019-06-15 17:20:16 +02:00
|
|
|
w->Invalidate();
|
2018-06-22 23:21:44 +02:00
|
|
|
break;
|
|
|
|
case WIDX_LIST_SORT_TYPE:
|
|
|
|
if (_listSortType == RIDE_SORT_TYPE)
|
|
|
|
{
|
|
|
|
_listSortDescending = !_listSortDescending;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
_listSortType = RIDE_SORT_TYPE;
|
|
|
|
_listSortDescending = false;
|
|
|
|
}
|
|
|
|
visible_list_refresh(w);
|
|
|
|
break;
|
|
|
|
case WIDX_LIST_SORT_RIDE:
|
|
|
|
if (_listSortType == RIDE_SORT_RIDE)
|
|
|
|
{
|
|
|
|
_listSortDescending = !_listSortDescending;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
_listSortType = RIDE_SORT_RIDE;
|
|
|
|
_listSortDescending = false;
|
|
|
|
}
|
|
|
|
visible_list_refresh(w);
|
|
|
|
break;
|
|
|
|
default:
|
2020-04-18 13:32:48 +02:00
|
|
|
if (widgetIndex >= WIDX_TAB_1 && static_cast<size_t>(widgetIndex) < WIDX_TAB_1 + std::size(ObjectSelectionPages))
|
2018-06-22 23:21:44 +02:00
|
|
|
{
|
|
|
|
window_editor_object_set_page(w, widgetIndex - WIDX_TAB_1);
|
|
|
|
}
|
|
|
|
break;
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
2014-11-25 00:05:35 +01:00
|
|
|
}
|
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
static void window_editor_object_selection_resize(rct_window* w)
|
2015-06-25 17:48:32 +02:00
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
window_set_resize(w, 600, 400, 1200, 1000);
|
2015-06-25 17:48:32 +02:00
|
|
|
}
|
2016-06-30 22:55:18 +02:00
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
void window_editor_object_selection_mousedown(rct_window* w, rct_widgetindex widgetIndex, rct_widget* widget)
|
2015-06-03 18:37:07 +02:00
|
|
|
{
|
2018-06-20 17:28:51 +02:00
|
|
|
int32_t numSelectionItems = 0;
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
switch (widgetIndex)
|
|
|
|
{
|
|
|
|
case WIDX_FILTER_DROPDOWN:
|
|
|
|
|
|
|
|
gDropdownItemsFormat[DDIX_FILTER_RCT1] = STR_TOGGLE_OPTION;
|
|
|
|
gDropdownItemsFormat[DDIX_FILTER_AA] = STR_TOGGLE_OPTION;
|
|
|
|
gDropdownItemsFormat[DDIX_FILTER_LL] = STR_TOGGLE_OPTION;
|
|
|
|
gDropdownItemsFormat[DDIX_FILTER_RCT2] = STR_TOGGLE_OPTION;
|
|
|
|
gDropdownItemsFormat[DDIX_FILTER_WW] = STR_TOGGLE_OPTION;
|
|
|
|
gDropdownItemsFormat[DDIX_FILTER_TT] = STR_TOGGLE_OPTION;
|
|
|
|
gDropdownItemsFormat[DDIX_FILTER_OO] = STR_TOGGLE_OPTION;
|
|
|
|
gDropdownItemsFormat[DDIX_FILTER_CUSTOM] = STR_TOGGLE_OPTION;
|
|
|
|
|
|
|
|
gDropdownItemsArgs[DDIX_FILTER_RCT1] = STR_SCENARIO_CATEGORY_RCT1;
|
|
|
|
gDropdownItemsArgs[DDIX_FILTER_AA] = STR_SCENARIO_CATEGORY_RCT1_AA;
|
|
|
|
gDropdownItemsArgs[DDIX_FILTER_LL] = STR_SCENARIO_CATEGORY_RCT1_LL;
|
|
|
|
gDropdownItemsArgs[DDIX_FILTER_RCT2] = STR_ROLLERCOASTER_TYCOON_2_DROPDOWN;
|
|
|
|
gDropdownItemsArgs[DDIX_FILTER_WW] = STR_OBJECT_FILTER_WW;
|
|
|
|
gDropdownItemsArgs[DDIX_FILTER_TT] = STR_OBJECT_FILTER_TT;
|
|
|
|
gDropdownItemsArgs[DDIX_FILTER_OO] = STR_OBJECT_FILTER_OPENRCT2_OFFICIAL;
|
|
|
|
gDropdownItemsArgs[DDIX_FILTER_CUSTOM] = STR_OBJECT_FILTER_CUSTOM;
|
|
|
|
|
|
|
|
// Track manager cannot select multiple, so only show selection filters if not in track manager
|
|
|
|
if (!(gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER))
|
|
|
|
{
|
|
|
|
numSelectionItems = 3;
|
|
|
|
gDropdownItemsFormat[DDIX_FILTER_SEPARATOR] = 0;
|
|
|
|
gDropdownItemsFormat[DDIX_FILTER_SELECTED] = STR_TOGGLE_OPTION;
|
|
|
|
gDropdownItemsFormat[DDIX_FILTER_NONSELECTED] = STR_TOGGLE_OPTION;
|
|
|
|
gDropdownItemsArgs[DDIX_FILTER_SEPARATOR] = STR_NONE;
|
|
|
|
gDropdownItemsArgs[DDIX_FILTER_SELECTED] = STR_SELECTED_ONLY;
|
|
|
|
gDropdownItemsArgs[DDIX_FILTER_NONSELECTED] = STR_NON_SELECTED_ONLY;
|
|
|
|
}
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2020-11-03 09:16:06 +01:00
|
|
|
WindowDropdownShowText(
|
2020-06-25 03:44:00 +02:00
|
|
|
{ w->windowPos.x + widget->left, w->windowPos.y + widget->top }, widget->height() + 1,
|
2020-11-03 09:16:06 +01:00
|
|
|
w->colours[widget->colour], Dropdown::Flag::StayOpen, _numSourceGameItems + numSelectionItems);
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
for (int32_t i = 0; i < _numSourceGameItems; i++)
|
2017-07-24 11:24:23 +02:00
|
|
|
{
|
2018-06-22 23:21:44 +02:00
|
|
|
if (_filter_flags & (1 << i))
|
|
|
|
{
|
2020-11-03 09:16:06 +01:00
|
|
|
Dropdown::SetChecked(i, true);
|
2018-06-22 23:21:44 +02:00
|
|
|
}
|
2017-07-24 11:24:23 +02:00
|
|
|
}
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
if (!(gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER))
|
|
|
|
{
|
2020-11-03 09:16:06 +01:00
|
|
|
Dropdown::SetChecked(DDIX_FILTER_SELECTED, _FILTER_SELECTED != 0);
|
|
|
|
Dropdown::SetChecked(DDIX_FILTER_NONSELECTED, _FILTER_NONSELECTED != 0);
|
2018-06-22 23:21:44 +02:00
|
|
|
}
|
|
|
|
break;
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
2015-06-03 18:37:07 +02:00
|
|
|
}
|
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
static void window_editor_object_selection_dropdown(rct_window* w, rct_widgetindex widgetIndex, int32_t dropdownIndex)
|
2015-06-03 18:37:07 +02:00
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
if (dropdownIndex == -1)
|
|
|
|
return;
|
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
switch (widgetIndex)
|
|
|
|
{
|
|
|
|
case WIDX_FILTER_DROPDOWN:
|
|
|
|
if (dropdownIndex == DDIX_FILTER_SELECTED)
|
|
|
|
{
|
|
|
|
_filter_flags ^= FILTER_SELECTED;
|
|
|
|
_filter_flags &= ~FILTER_NONSELECTED;
|
|
|
|
}
|
|
|
|
else if (dropdownIndex == DDIX_FILTER_NONSELECTED)
|
|
|
|
{
|
|
|
|
_filter_flags ^= FILTER_NONSELECTED;
|
|
|
|
_filter_flags &= ~FILTER_SELECTED;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
_filter_flags ^= (1 << dropdownIndex);
|
|
|
|
}
|
|
|
|
gConfigInterface.object_selection_filter_flags = _filter_flags;
|
|
|
|
config_save_default();
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
filter_update_counts();
|
|
|
|
w->scrolls->v_top = 0;
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
visible_list_refresh(w);
|
2019-06-15 17:20:16 +02:00
|
|
|
w->Invalidate();
|
2018-06-22 23:21:44 +02:00
|
|
|
break;
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
2015-06-03 18:37:07 +02:00
|
|
|
}
|
|
|
|
|
2015-02-11 17:02:57 +01:00
|
|
|
/**
|
2015-10-20 20:16:30 +02:00
|
|
|
*
|
2015-02-11 17:02:57 +01:00
|
|
|
* rct2: 0x006AB031
|
|
|
|
*/
|
2018-06-22 23:21:44 +02:00
|
|
|
static void window_editor_object_selection_scrollgetsize(rct_window* w, int32_t scrollIndex, int32_t* width, int32_t* height)
|
2015-02-11 17:02:57 +01:00
|
|
|
{
|
2020-06-18 20:43:38 +02:00
|
|
|
*height = static_cast<int32_t>(_listItems.size() * SCROLLABLE_ROW_HEIGHT);
|
2015-02-11 17:02:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2015-10-20 20:16:30 +02:00
|
|
|
*
|
2015-02-11 17:02:57 +01:00
|
|
|
* rct2: 0x006AB0B6
|
|
|
|
*/
|
2020-02-29 03:43:29 +01:00
|
|
|
static void window_editor_object_selection_scroll_mousedown(
|
|
|
|
rct_window* w, int32_t scrollIndex, const ScreenCoordsXY& screenCoords)
|
2015-02-11 17:02:57 +01:00
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
// Used for in-game object selection cheat to prevent crashing the game
|
|
|
|
// when windows attempt to draw objects that don't exist any more
|
|
|
|
window_close_all_except_class(WC_EDITOR_OBJECT_SELECTION);
|
|
|
|
|
2019-11-14 12:40:40 +01:00
|
|
|
int32_t selected_object = get_object_from_object_selection(get_selected_object_type(w), screenCoords.y);
|
2017-06-06 23:24:18 +02:00
|
|
|
if (selected_object == -1)
|
|
|
|
return;
|
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
list_item* listItem = &_listItems[selected_object];
|
2018-06-20 17:28:51 +02:00
|
|
|
uint8_t object_selection_flags = *listItem->flags;
|
2017-06-06 23:24:18 +02:00
|
|
|
if (object_selection_flags & OBJECT_SELECTION_FLAG_6)
|
|
|
|
return;
|
|
|
|
|
2019-06-15 17:20:16 +02:00
|
|
|
w->Invalidate();
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
const CursorState* state = context_get_cursor_state();
|
2020-10-06 23:34:42 +02:00
|
|
|
OpenRCT2::Audio::Play(OpenRCT2::Audio::SoundId::Click1, 0, state->position.x);
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
if (gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER)
|
|
|
|
{
|
2020-11-07 20:28:01 +01:00
|
|
|
if (!window_editor_object_selection_select_object(0, INPUT_FLAG_EDITOR_OBJECT_SELECT, listItem->entry))
|
2017-06-06 23:24:18 +02:00
|
|
|
return;
|
|
|
|
|
|
|
|
// Close any other open windows such as options/colour schemes to prevent a crash.
|
|
|
|
window_close_all();
|
2018-06-22 23:21:44 +02:00
|
|
|
// window_close(w);
|
2017-06-06 23:24:18 +02:00
|
|
|
|
|
|
|
// This function calls window_track_list_open
|
|
|
|
window_editor_object_selection_manage_tracks();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-11-07 20:28:01 +01:00
|
|
|
int32_t flags = INPUT_FLAG_EDITOR_OBJECT_1 | INPUT_FLAG_EDITOR_OBJECT_SELECT_OBJECTS_IN_SCENERY_GROUP;
|
2017-06-06 23:24:18 +02:00
|
|
|
// If already selected
|
|
|
|
if (!(object_selection_flags & OBJECT_SELECTION_FLAG_SELECTED))
|
2020-11-07 20:28:01 +01:00
|
|
|
flags |= INPUT_FLAG_EDITOR_OBJECT_SELECT;
|
2017-06-06 23:24:18 +02:00
|
|
|
|
|
|
|
_maxObjectsWasHit = false;
|
2020-11-07 20:28:01 +01:00
|
|
|
if (!window_editor_object_selection_select_object(0, flags, listItem->entry))
|
2018-06-22 23:21:44 +02:00
|
|
|
{
|
2020-11-07 20:28:01 +01:00
|
|
|
rct_string_id error_title = (flags & INPUT_FLAG_EDITOR_OBJECT_SELECT) ? STR_UNABLE_TO_SELECT_THIS_OBJECT
|
|
|
|
: STR_UNABLE_TO_DE_SELECT_THIS_OBJECT;
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2020-08-27 00:01:15 +02:00
|
|
|
context_show_error(error_title, gGameCommandErrorText, {});
|
2017-06-06 23:24:18 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
if (_FILTER_SELECTED || _FILTER_NONSELECTED)
|
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
filter_update_counts();
|
|
|
|
visible_list_refresh(w);
|
2019-06-15 17:20:16 +02:00
|
|
|
w->Invalidate();
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
if (_maxObjectsWasHit)
|
|
|
|
{
|
2020-08-27 00:01:15 +02:00
|
|
|
context_show_error(
|
|
|
|
STR_WARNING_TOO_MANY_OBJECTS_SELECTED, STR_NOT_ALL_OBJECTS_IN_THIS_SCENERY_GROUP_COULD_BE_SELECTED, {});
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
2015-02-11 17:02:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2015-10-20 20:16:30 +02:00
|
|
|
*
|
2015-02-11 17:02:57 +01:00
|
|
|
* rct2: 0x006AB079
|
|
|
|
*/
|
2020-02-29 03:43:29 +01:00
|
|
|
static void window_editor_object_selection_scroll_mouseover(
|
|
|
|
rct_window* w, int32_t scrollIndex, const ScreenCoordsXY& screenCoords)
|
2015-02-11 17:02:57 +01:00
|
|
|
{
|
2019-11-14 12:40:40 +01:00
|
|
|
int32_t selectedObject = get_object_from_object_selection(get_selected_object_type(w), screenCoords.y);
|
2018-06-22 23:21:44 +02:00
|
|
|
if (selectedObject != -1)
|
|
|
|
{
|
|
|
|
list_item* listItem = &_listItems[selectedObject];
|
2018-06-20 17:28:51 +02:00
|
|
|
uint8_t objectSelectionFlags = *listItem->flags;
|
2018-06-22 23:21:44 +02:00
|
|
|
if (objectSelectionFlags & OBJECT_SELECTION_FLAG_6)
|
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
selectedObject = -1;
|
|
|
|
}
|
|
|
|
}
|
2018-06-22 23:21:44 +02:00
|
|
|
if (selectedObject != w->selected_list_item)
|
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
w->selected_list_item = selectedObject;
|
|
|
|
|
2020-10-14 21:56:48 +02:00
|
|
|
if (_loadedObject != nullptr)
|
|
|
|
_loadedObject->Unload();
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
if (selectedObject == -1)
|
|
|
|
{
|
2017-08-15 10:07:44 +02:00
|
|
|
w->object_entry = nullptr;
|
2018-06-22 23:21:44 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-04-09 18:46:43 +02:00
|
|
|
auto listItem = &_listItems[selectedObject];
|
2017-06-06 23:24:18 +02:00
|
|
|
w->object_entry = listItem->entry;
|
|
|
|
_loadedObject = object_repository_load_object(listItem->entry);
|
|
|
|
}
|
|
|
|
|
2019-06-15 17:20:16 +02:00
|
|
|
w->Invalidate();
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
2015-02-11 17:02:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2015-10-20 20:16:30 +02:00
|
|
|
*
|
2015-02-11 17:02:57 +01:00
|
|
|
* rct2: 0x006AB058
|
|
|
|
*/
|
2020-10-10 15:49:56 +02:00
|
|
|
static OpenRCT2String window_editor_object_selection_tooltip(
|
|
|
|
rct_window* w, const rct_widgetindex widgetIndex, const rct_string_id fallback)
|
2015-02-11 17:02:57 +01:00
|
|
|
{
|
2020-04-18 13:32:48 +02:00
|
|
|
if (widgetIndex >= WIDX_TAB_1 && static_cast<size_t>(widgetIndex) < WIDX_TAB_1 + std::size(ObjectSelectionPages))
|
2018-05-14 13:27:25 +02:00
|
|
|
{
|
2020-10-10 15:49:56 +02:00
|
|
|
auto ft = Formatter();
|
2020-05-14 02:29:39 +02:00
|
|
|
ft.Add<rct_string_id>(ObjectSelectionPages[(widgetIndex - WIDX_TAB_1)].Caption);
|
2020-10-10 15:49:56 +02:00
|
|
|
return { fallback, ft };
|
2018-05-14 13:27:25 +02:00
|
|
|
}
|
2020-10-10 15:49:56 +02:00
|
|
|
return { fallback, {} };
|
2015-02-11 17:02:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2015-10-20 20:16:30 +02:00
|
|
|
*
|
2015-02-11 17:02:57 +01:00
|
|
|
* rct2: 0x006AA9FD
|
|
|
|
*/
|
2018-06-22 23:21:44 +02:00
|
|
|
static void window_editor_object_selection_invalidate(rct_window* w)
|
2015-02-11 17:02:57 +01:00
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
// Resize widgets
|
|
|
|
w->widgets[WIDX_BACKGROUND].right = w->width - 1;
|
|
|
|
w->widgets[WIDX_BACKGROUND].bottom = w->height - 1;
|
|
|
|
w->widgets[WIDX_TITLE].right = w->width - 2;
|
2020-05-05 22:31:04 +02:00
|
|
|
w->widgets[WIDX_CLOSE].left = w->width - 13;
|
|
|
|
w->widgets[WIDX_CLOSE].right = w->width - 3;
|
2017-06-06 23:24:18 +02:00
|
|
|
w->widgets[WIDX_TAB_CONTENT_PANEL].right = w->width - 1;
|
|
|
|
w->widgets[WIDX_TAB_CONTENT_PANEL].bottom = w->height - 1;
|
|
|
|
w->widgets[WIDX_ADVANCED].left = w->width - 130;
|
|
|
|
w->widgets[WIDX_ADVANCED].right = w->width - 9;
|
|
|
|
w->widgets[WIDX_LIST].right = w->width - 309;
|
|
|
|
w->widgets[WIDX_LIST].bottom = w->height - 14;
|
|
|
|
w->widgets[WIDX_PREVIEW].left = w->width - 209;
|
|
|
|
w->widgets[WIDX_PREVIEW].right = w->width - 96;
|
|
|
|
w->widgets[WIDX_INSTALL_TRACK].left = w->width - 130;
|
|
|
|
w->widgets[WIDX_INSTALL_TRACK].right = w->width - 9;
|
|
|
|
w->widgets[WIDX_FILTER_DROPDOWN].left = w->width - 250;
|
|
|
|
w->widgets[WIDX_FILTER_DROPDOWN].right = w->width - 137;
|
|
|
|
|
|
|
|
// Set pressed widgets
|
|
|
|
w->pressed_widgets |= 1 << WIDX_PREVIEW;
|
|
|
|
window_editor_object_selection_set_pressed_tab(w);
|
|
|
|
if (w->list_information_type & 1)
|
|
|
|
w->pressed_widgets |= (1 << WIDX_ADVANCED);
|
|
|
|
else
|
|
|
|
w->pressed_widgets &= ~(1 << WIDX_ADVANCED);
|
|
|
|
|
|
|
|
// Set window title and buttons
|
2020-05-14 02:29:39 +02:00
|
|
|
auto ft = Formatter::Common();
|
|
|
|
ft.Add<rct_string_id>(ObjectSelectionPages[w->selected_tab].Caption);
|
2018-06-22 23:21:44 +02:00
|
|
|
if (gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER)
|
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
w->widgets[WIDX_TITLE].text = STR_TRACK_DESIGNS_MANAGER_SELECT_RIDE_TYPE;
|
2020-11-27 04:14:20 +01:00
|
|
|
w->widgets[WIDX_INSTALL_TRACK].type = WindowWidgetType::Button;
|
2018-06-22 23:21:44 +02:00
|
|
|
}
|
|
|
|
else if (gScreenFlags & SCREEN_FLAGS_TRACK_DESIGNER)
|
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
w->widgets[WIDX_TITLE].text = STR_ROLLER_COASTER_DESIGNER_SELECT_RIDE_TYPES_VEHICLES;
|
2020-11-27 04:14:20 +01:00
|
|
|
w->widgets[WIDX_INSTALL_TRACK].type = WindowWidgetType::Empty;
|
2018-06-22 23:21:44 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
w->widgets[WIDX_TITLE].text = STR_OBJECT_SELECTION;
|
2020-11-27 04:14:20 +01:00
|
|
|
w->widgets[WIDX_INSTALL_TRACK].type = WindowWidgetType::Empty;
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Align tabs, hide advanced ones
|
2018-05-14 13:27:25 +02:00
|
|
|
bool advancedMode = (w->list_information_type & 1) != 0;
|
2018-06-20 17:28:51 +02:00
|
|
|
int32_t x = 3;
|
2018-12-10 01:26:12 +01:00
|
|
|
for (size_t i = 0; i < std::size(ObjectSelectionPages); i++)
|
2018-05-14 13:27:25 +02:00
|
|
|
{
|
|
|
|
auto widget = &w->widgets[WIDX_TAB_1 + i];
|
2018-08-29 23:29:45 +02:00
|
|
|
if (!advancedMode && ObjectSelectionPages[i].IsAdvanced)
|
2018-05-14 13:27:25 +02:00
|
|
|
{
|
2020-11-27 04:14:20 +01:00
|
|
|
widget->type = WindowWidgetType::Empty;
|
2018-05-14 13:27:25 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-11-27 04:14:20 +01:00
|
|
|
widget->type = WindowWidgetType::Tab;
|
2017-06-06 23:24:18 +02:00
|
|
|
widget->left = x;
|
|
|
|
widget->right = x + 30;
|
|
|
|
x += 31;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
if (gScreenFlags & (SCREEN_FLAGS_TRACK_MANAGER | SCREEN_FLAGS_TRACK_DESIGNER))
|
|
|
|
{
|
2020-11-27 04:14:20 +01:00
|
|
|
w->widgets[WIDX_ADVANCED].type = WindowWidgetType::Empty;
|
2018-12-16 10:02:40 +01:00
|
|
|
for (size_t i = 1; i < std::size(ObjectSelectionPages); i++)
|
2018-05-14 13:27:25 +02:00
|
|
|
{
|
2020-11-27 04:14:20 +01:00
|
|
|
w->widgets[WIDX_TAB_1 + i].type = WindowWidgetType::Empty;
|
2018-05-14 13:27:25 +02:00
|
|
|
}
|
2017-06-06 23:24:18 +02:00
|
|
|
x = 150;
|
2018-06-22 23:21:44 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-11-27 04:14:20 +01:00
|
|
|
w->widgets[WIDX_ADVANCED].type = WindowWidgetType::Button;
|
2017-06-06 23:24:18 +02:00
|
|
|
x = 300;
|
|
|
|
}
|
|
|
|
|
2020-11-27 04:14:20 +01:00
|
|
|
w->widgets[WIDX_FILTER_DROPDOWN].type = WindowWidgetType::Button;
|
2017-06-06 23:24:18 +02:00
|
|
|
w->widgets[WIDX_LIST].right = w->width - (600 - 587) - x;
|
|
|
|
w->widgets[WIDX_PREVIEW].left = w->width - (600 - 537) - (x / 2);
|
|
|
|
w->widgets[WIDX_PREVIEW].right = w->widgets[WIDX_PREVIEW].left + 113;
|
|
|
|
w->widgets[WIDX_FILTER_RIDE_TAB_FRAME].right = w->widgets[WIDX_LIST].right;
|
|
|
|
|
2020-11-09 10:36:37 +01:00
|
|
|
bool ridePage = (get_selected_object_type(w) == ObjectType::Ride);
|
2017-06-06 23:24:18 +02:00
|
|
|
w->widgets[WIDX_LIST].top = (ridePage ? 118 : 60);
|
2020-06-18 19:54:16 +02:00
|
|
|
w->widgets[WIDX_FILTER_TEXT_BOX].right = w->widgets[WIDX_LIST].right - 77;
|
|
|
|
w->widgets[WIDX_FILTER_TEXT_BOX].top = (ridePage ? 79 : 45);
|
|
|
|
w->widgets[WIDX_FILTER_TEXT_BOX].bottom = (ridePage ? 92 : 58);
|
2017-06-06 23:24:18 +02:00
|
|
|
w->widgets[WIDX_FILTER_CLEAR_BUTTON].left = w->widgets[WIDX_LIST].right - 73;
|
|
|
|
w->widgets[WIDX_FILTER_CLEAR_BUTTON].right = w->widgets[WIDX_LIST].right;
|
2020-06-18 19:54:16 +02:00
|
|
|
w->widgets[WIDX_FILTER_CLEAR_BUTTON].top = (ridePage ? 79 : 45);
|
|
|
|
w->widgets[WIDX_FILTER_CLEAR_BUTTON].bottom = (ridePage ? 92 : 58);
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2018-06-03 14:46:17 +02:00
|
|
|
if (ridePage)
|
|
|
|
{
|
2018-06-22 23:21:44 +02:00
|
|
|
w->enabled_widgets |= (1 << WIDX_FILTER_RIDE_TAB_ALL) | (1 << WIDX_FILTER_RIDE_TAB_TRANSPORT)
|
|
|
|
| (1 << WIDX_FILTER_RIDE_TAB_GENTLE) | (1 << WIDX_FILTER_RIDE_TAB_COASTER) | (1 << WIDX_FILTER_RIDE_TAB_THRILL)
|
|
|
|
| (1 << WIDX_FILTER_RIDE_TAB_WATER) | (1 << WIDX_FILTER_RIDE_TAB_STALL);
|
2018-06-03 14:46:17 +02:00
|
|
|
|
2018-06-20 17:28:51 +02:00
|
|
|
for (int32_t i = 0; i < 7; i++)
|
2017-06-06 23:24:18 +02:00
|
|
|
w->pressed_widgets &= ~(1 << (WIDX_FILTER_RIDE_TAB_ALL + i));
|
2018-06-03 14:46:17 +02:00
|
|
|
|
2017-06-06 23:24:18 +02:00
|
|
|
if ((_filter_flags & FILTER_RIDES) == FILTER_RIDES)
|
|
|
|
w->pressed_widgets |= (1 << WIDX_FILTER_RIDE_TAB_ALL);
|
2018-06-03 14:46:17 +02:00
|
|
|
else
|
|
|
|
{
|
2018-06-20 17:28:51 +02:00
|
|
|
for (int32_t i = 0; i < 6; i++)
|
2018-06-03 14:46:17 +02:00
|
|
|
{
|
2018-02-04 13:34:41 +01:00
|
|
|
if (_filter_flags & (1 << (_numSourceGameItems + i)))
|
2020-04-18 13:32:48 +02:00
|
|
|
w->pressed_widgets |= 1ULL << (WIDX_FILTER_RIDE_TAB_TRANSPORT + i);
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
|
|
|
}
|
2018-06-03 14:46:17 +02:00
|
|
|
|
2020-11-27 04:14:20 +01:00
|
|
|
w->widgets[WIDX_FILTER_RIDE_TAB_FRAME].type = WindowWidgetType::ImgBtn;
|
2018-06-20 17:28:51 +02:00
|
|
|
for (int32_t i = WIDX_FILTER_RIDE_TAB_ALL; i <= WIDX_FILTER_RIDE_TAB_STALL; i++)
|
2020-11-27 04:14:20 +01:00
|
|
|
w->widgets[i].type = WindowWidgetType::Tab;
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2020-06-25 03:44:00 +02:00
|
|
|
int32_t width_limit = (w->widgets[WIDX_LIST].width() - 15) / 2;
|
2018-06-03 14:46:17 +02:00
|
|
|
|
2020-11-27 04:14:20 +01:00
|
|
|
w->widgets[WIDX_LIST_SORT_TYPE].type = WindowWidgetType::TableHeader;
|
2020-06-18 19:54:16 +02:00
|
|
|
w->widgets[WIDX_LIST_SORT_TYPE].top = w->widgets[WIDX_FILTER_TEXT_BOX].bottom + 3;
|
2017-06-06 23:24:18 +02:00
|
|
|
w->widgets[WIDX_LIST_SORT_TYPE].bottom = w->widgets[WIDX_LIST_SORT_TYPE].top + 13;
|
2018-06-03 14:46:17 +02:00
|
|
|
w->widgets[WIDX_LIST_SORT_TYPE].left = 4;
|
|
|
|
w->widgets[WIDX_LIST_SORT_TYPE].right = w->widgets[WIDX_LIST_SORT_TYPE].left + width_limit;
|
|
|
|
|
2020-11-27 04:14:20 +01:00
|
|
|
w->widgets[WIDX_LIST_SORT_RIDE].type = WindowWidgetType::TableHeader;
|
2017-06-06 23:24:18 +02:00
|
|
|
w->widgets[WIDX_LIST_SORT_RIDE].top = w->widgets[WIDX_LIST_SORT_TYPE].top;
|
|
|
|
w->widgets[WIDX_LIST_SORT_RIDE].bottom = w->widgets[WIDX_LIST_SORT_TYPE].bottom;
|
2018-06-03 14:46:17 +02:00
|
|
|
w->widgets[WIDX_LIST_SORT_RIDE].left = w->widgets[WIDX_LIST_SORT_TYPE].right + 1;
|
2017-06-06 23:24:18 +02:00
|
|
|
w->widgets[WIDX_LIST_SORT_RIDE].right = w->widgets[WIDX_LIST].right;
|
2018-06-03 14:46:17 +02:00
|
|
|
|
2017-06-06 23:24:18 +02:00
|
|
|
w->widgets[WIDX_LIST].top = w->widgets[WIDX_LIST_SORT_TYPE].bottom + 2;
|
2018-06-03 14:46:17 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-06-22 23:21:44 +02:00
|
|
|
w->enabled_widgets &= ~(
|
|
|
|
(1 << WIDX_FILTER_RIDE_TAB_ALL) | (1 << WIDX_FILTER_RIDE_TAB_TRANSPORT) | (1 << WIDX_FILTER_RIDE_TAB_GENTLE)
|
|
|
|
| (1 << WIDX_FILTER_RIDE_TAB_COASTER) | (1 << WIDX_FILTER_RIDE_TAB_THRILL) | (1 << WIDX_FILTER_RIDE_TAB_WATER)
|
|
|
|
| (1 << WIDX_FILTER_RIDE_TAB_STALL));
|
2018-06-20 17:28:51 +02:00
|
|
|
for (int32_t i = WIDX_FILTER_RIDE_TAB_FRAME; i <= WIDX_FILTER_RIDE_TAB_STALL; i++)
|
2020-11-27 04:14:20 +01:00
|
|
|
w->widgets[i].type = WindowWidgetType::Empty;
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2020-11-27 04:14:20 +01:00
|
|
|
w->widgets[WIDX_LIST_SORT_TYPE].type = WindowWidgetType::Empty;
|
|
|
|
w->widgets[WIDX_LIST_SORT_RIDE].type = WindowWidgetType::Empty;
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
2015-02-11 17:02:57 +01:00
|
|
|
}
|
|
|
|
|
2015-02-11 18:50:52 +01:00
|
|
|
/**
|
2015-10-20 20:16:30 +02:00
|
|
|
*
|
2015-02-11 18:50:52 +01:00
|
|
|
* rct2: 0x006AAB56
|
|
|
|
*/
|
2018-06-22 23:21:44 +02:00
|
|
|
static void window_editor_object_selection_paint(rct_window* w, rct_drawpixelinfo* dpi)
|
2015-02-11 18:50:52 +01:00
|
|
|
{
|
2020-06-11 15:11:12 +02:00
|
|
|
int32_t width;
|
2018-06-22 23:21:44 +02:00
|
|
|
rct_widget* widget;
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2020-11-04 05:52:23 +01:00
|
|
|
WindowDrawWidgets(w, dpi);
|
2017-06-06 23:24:18 +02:00
|
|
|
|
|
|
|
// Draw tabs
|
2018-12-10 01:26:12 +01:00
|
|
|
for (size_t i = 0; i < std::size(ObjectSelectionPages); i++)
|
2018-05-14 13:27:25 +02:00
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
widget = &w->widgets[WIDX_TAB_1 + i];
|
2020-11-27 04:14:20 +01:00
|
|
|
if (widget->type != WindowWidgetType::Empty)
|
2018-05-14 13:27:25 +02:00
|
|
|
{
|
|
|
|
auto image = ObjectSelectionPages[i].Image;
|
2020-06-11 23:26:16 +02:00
|
|
|
auto screenPos = w->windowPos + ScreenCoordsXY{ widget->left, widget->top };
|
2020-06-23 23:32:34 +02:00
|
|
|
gfx_draw_sprite(dpi, image, screenPos, 0);
|
2018-05-14 13:27:25 +02:00
|
|
|
}
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
const int32_t ride_tabs[] = { SPR_TAB_RIDE_16, IMAGE_TYPE_REMAP | SPR_TAB_RIDES_TRANSPORT_0,
|
|
|
|
SPR_TAB_RIDES_GENTLE_0, IMAGE_TYPE_REMAP | SPR_TAB_RIDES_ROLLER_COASTERS_0,
|
|
|
|
SPR_TAB_RIDES_THRILL_0, SPR_TAB_RIDES_WATER_0,
|
|
|
|
SPR_TAB_RIDES_SHOP_0, SPR_TAB_FINANCES_RESEARCH_0 };
|
|
|
|
const int32_t ThrillRidesTabAnimationSequence[] = { 5, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 0, 0, 0 };
|
2017-06-06 23:24:18 +02:00
|
|
|
|
|
|
|
// Draw ride tabs
|
2020-11-09 10:36:37 +01:00
|
|
|
if (get_selected_object_type(w) == ObjectType::Ride)
|
2018-05-14 13:27:25 +02:00
|
|
|
{
|
2018-12-10 01:26:12 +01:00
|
|
|
for (int32_t i = 0; i < 7; i++)
|
2018-06-22 23:21:44 +02:00
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
widget = &w->widgets[WIDX_FILTER_RIDE_TAB_ALL + i];
|
2020-11-27 04:14:20 +01:00
|
|
|
if (widget->type == WindowWidgetType::Empty)
|
2017-06-06 23:24:18 +02:00
|
|
|
continue;
|
|
|
|
|
2018-06-20 17:28:51 +02:00
|
|
|
int32_t spriteIndex = ride_tabs[i];
|
|
|
|
int32_t frame = 0;
|
2018-06-22 23:21:44 +02:00
|
|
|
if (i != 0 && w->pressed_widgets & (1ULL << (WIDX_FILTER_RIDE_TAB_ALL + i)))
|
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
frame = w->frame_no / window_editor_object_selection_animation_divisor[i - 1];
|
|
|
|
}
|
|
|
|
spriteIndex += (i == 4 ? ThrillRidesTabAnimationSequence[frame] : frame);
|
|
|
|
|
2020-06-11 23:26:16 +02:00
|
|
|
auto screenPos = w->windowPos + ScreenCoordsXY{ widget->left, widget->top };
|
2020-06-23 23:32:34 +02:00
|
|
|
gfx_draw_sprite(dpi, spriteIndex | (w->colours[1] << 19), screenPos, 0);
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Preview background
|
|
|
|
widget = &w->widgets[WIDX_PREVIEW];
|
|
|
|
gfx_fill_rect(
|
2020-07-10 18:59:08 +02:00
|
|
|
dpi,
|
|
|
|
{ w->windowPos + ScreenCoordsXY{ widget->left + 1, widget->top + 1 },
|
|
|
|
w->windowPos + ScreenCoordsXY{ widget->right - 1, widget->bottom - 1 } },
|
|
|
|
ColourMapA[w->colours[1]].darkest);
|
2017-06-06 23:24:18 +02:00
|
|
|
|
|
|
|
// Draw number of selected items
|
2018-06-22 23:21:44 +02:00
|
|
|
if (!(gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER))
|
|
|
|
{
|
2020-06-11 23:26:16 +02:00
|
|
|
auto screenPos = w->windowPos + ScreenCoordsXY{ 3, w->height - 13 };
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2020-11-10 09:00:15 +01:00
|
|
|
int32_t numSelected = _numSelectedObjectsForType[EnumValue(get_selected_object_type(w))];
|
|
|
|
int32_t totalSelectable = object_entry_group_counts[EnumValue(get_selected_object_type(w))];
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2020-09-28 02:09:08 +02:00
|
|
|
auto ft = Formatter();
|
2020-06-03 00:40:47 +02:00
|
|
|
ft.Add<uint16_t>(numSelected);
|
|
|
|
ft.Add<uint16_t>(totalSelectable);
|
2021-02-27 16:49:13 +01:00
|
|
|
DrawTextBasic(dpi, screenPos, STR_OBJECT_SELECTION_SELECTION_SIZE, ft);
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Draw sort button text
|
|
|
|
widget = &w->widgets[WIDX_LIST_SORT_TYPE];
|
2020-11-27 04:14:20 +01:00
|
|
|
if (widget->type != WindowWidgetType::Empty)
|
2018-06-22 23:21:44 +02:00
|
|
|
{
|
2020-09-28 02:09:08 +02:00
|
|
|
auto ft = Formatter();
|
2020-08-28 22:33:36 +02:00
|
|
|
auto stringId = _listSortType == RIDE_SORT_TYPE ? static_cast<rct_string_id>(_listSortDescending ? STR_DOWN : STR_UP)
|
|
|
|
: STR_NONE;
|
|
|
|
ft.Add<rct_string_id>(stringId);
|
2020-06-11 23:26:16 +02:00
|
|
|
auto screenPos = w->windowPos + ScreenCoordsXY{ widget->left + 1, widget->top + 1 };
|
2020-08-28 22:33:36 +02:00
|
|
|
DrawTextEllipsised(dpi, screenPos, widget->width(), STR_OBJECTS_SORT_TYPE, ft, w->colours[1]);
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
|
|
|
widget = &w->widgets[WIDX_LIST_SORT_RIDE];
|
2020-11-27 04:14:20 +01:00
|
|
|
if (widget->type != WindowWidgetType::Empty)
|
2018-06-22 23:21:44 +02:00
|
|
|
{
|
2020-09-28 02:09:08 +02:00
|
|
|
auto ft = Formatter();
|
2020-08-28 22:33:36 +02:00
|
|
|
auto stringId = _listSortType == RIDE_SORT_RIDE ? static_cast<rct_string_id>(_listSortDescending ? STR_DOWN : STR_UP)
|
|
|
|
: STR_NONE;
|
|
|
|
ft.Add<rct_string_id>(stringId);
|
2020-06-11 23:26:16 +02:00
|
|
|
auto screenPos = w->windowPos + ScreenCoordsXY{ widget->left + 1, widget->top + 1 };
|
2020-08-28 22:33:36 +02:00
|
|
|
DrawTextEllipsised(dpi, screenPos, widget->width(), STR_OBJECTS_SORT_RIDE, ft, w->colours[1]);
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
|
|
|
|
2017-08-15 10:07:44 +02:00
|
|
|
if (w->selected_list_item == -1 || _loadedObject == nullptr)
|
2017-06-06 23:24:18 +02:00
|
|
|
return;
|
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
list_item* listItem = &_listItems[w->selected_list_item];
|
2017-06-06 23:24:18 +02:00
|
|
|
|
|
|
|
// Draw preview
|
|
|
|
widget = &w->widgets[WIDX_PREVIEW];
|
|
|
|
{
|
|
|
|
rct_drawpixelinfo clipDPI;
|
2020-06-11 23:26:16 +02:00
|
|
|
auto screenPos = w->windowPos + ScreenCoordsXY{ widget->left + 1, widget->top + 1 };
|
2020-06-25 03:44:00 +02:00
|
|
|
width = widget->width() - 1;
|
|
|
|
int32_t height = widget->height() - 1;
|
2020-07-02 19:06:28 +02:00
|
|
|
if (clip_drawpixelinfo(&clipDPI, dpi, screenPos, width, height))
|
2018-06-22 23:21:44 +02:00
|
|
|
{
|
2020-10-14 21:56:48 +02:00
|
|
|
_loadedObject->DrawPreview(&clipDPI, width, height);
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Draw name of object
|
2020-06-11 23:26:16 +02:00
|
|
|
{
|
2020-06-25 10:31:15 +02:00
|
|
|
auto screenPos = w->windowPos + ScreenCoordsXY{ widget->midX() + 1, widget->bottom + 3 };
|
2020-06-11 23:26:16 +02:00
|
|
|
width = w->width - w->widgets[WIDX_LIST].right - 6;
|
2020-09-28 02:09:08 +02:00
|
|
|
auto ft = Formatter();
|
2020-06-11 23:26:16 +02:00
|
|
|
ft.Add<rct_string_id>(STR_STRING);
|
|
|
|
ft.Add<const char*>(listItem->repositoryItem->Name.c_str());
|
2020-08-28 18:03:51 +02:00
|
|
|
DrawTextEllipsised(dpi, screenPos, width, STR_WINDOW_COLOUR_2_STRINGID, ft, COLOUR_BLACK, TextAlignment::CENTRE);
|
2020-06-11 23:26:16 +02:00
|
|
|
}
|
2017-06-06 23:24:18 +02:00
|
|
|
|
|
|
|
// Draw description of object
|
2020-10-14 21:56:48 +02:00
|
|
|
auto description = object_get_description(_loadedObject.get());
|
2018-06-22 23:21:44 +02:00
|
|
|
if (!description.empty())
|
|
|
|
{
|
2020-09-28 02:09:08 +02:00
|
|
|
auto ft = Formatter();
|
2020-06-03 00:40:47 +02:00
|
|
|
ft.Add<rct_string_id>(STR_STRING);
|
|
|
|
ft.Add<const char*>(description.c_str());
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2020-06-11 23:26:16 +02:00
|
|
|
auto screenPos = w->windowPos + ScreenCoordsXY{ w->widgets[WIDX_LIST].right + 4, widget->bottom + 18 };
|
2020-06-11 15:11:12 +02:00
|
|
|
width = w->windowPos.x + w->width - screenPos.x - 4;
|
2018-02-08 20:51:35 +01:00
|
|
|
|
2021-02-27 17:17:17 +01:00
|
|
|
DrawTextWrapped(dpi, screenPos + ScreenCoordsXY{ 0, 5 }, width, STR_WINDOW_COLOUR_2_STRINGID, ft);
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
|
|
|
|
2020-08-09 07:23:28 +02:00
|
|
|
auto screenPos = w->windowPos + ScreenCoordsXY{ w->width - 5, w->height - (LIST_ROW_HEIGHT * 5) };
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2018-06-03 14:46:17 +02:00
|
|
|
// Draw ride type.
|
2020-11-09 10:36:37 +01:00
|
|
|
if (get_selected_object_type(w) == ObjectType::Ride)
|
2018-06-03 14:46:17 +02:00
|
|
|
{
|
2020-08-28 22:33:36 +02:00
|
|
|
auto stringId = get_ride_type_string_id(listItem->repositoryItem);
|
2021-02-27 14:32:13 +01:00
|
|
|
DrawTextBasic(dpi, screenPos, stringId, {}, { COLOUR_WHITE, TextAlignment::RIGHT });
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
|
|
|
|
2020-06-18 20:43:38 +02:00
|
|
|
screenPos.y += LIST_ROW_HEIGHT;
|
2018-06-03 14:46:17 +02:00
|
|
|
|
|
|
|
// Draw object source
|
2020-08-28 22:33:36 +02:00
|
|
|
auto stringId = object_manager_get_source_game_string(listItem->repositoryItem->GetFirstSourceGame());
|
2021-02-27 14:32:13 +01:00
|
|
|
DrawTextBasic(dpi, screenPos, stringId, {}, { COLOUR_WHITE, TextAlignment::RIGHT });
|
2020-06-18 20:43:38 +02:00
|
|
|
screenPos.y += LIST_ROW_HEIGHT;
|
2017-06-06 23:24:18 +02:00
|
|
|
|
|
|
|
// Draw object dat name
|
2020-08-09 07:23:28 +02:00
|
|
|
{
|
|
|
|
const char* path = path_get_filename(listItem->repositoryItem->Path.c_str());
|
2020-09-28 02:09:08 +02:00
|
|
|
auto ft = Formatter();
|
2020-08-09 07:23:28 +02:00
|
|
|
ft.Add<rct_string_id>(STR_STRING);
|
|
|
|
ft.Add<const char*>(path);
|
2020-09-19 02:39:00 +02:00
|
|
|
DrawTextBasic(
|
2021-02-27 14:32:13 +01:00
|
|
|
dpi, { w->windowPos.x + w->width - 5, screenPos.y }, STR_WINDOW_COLOUR_2_STRINGID, ft,
|
|
|
|
{ COLOUR_BLACK, TextAlignment::RIGHT });
|
2020-08-09 07:23:28 +02:00
|
|
|
screenPos.y += LIST_ROW_HEIGHT;
|
|
|
|
}
|
2015-02-11 18:50:52 +01:00
|
|
|
|
2020-08-09 07:23:28 +02:00
|
|
|
// Draw object author (will be blank space if no author in file or a non JSON object)
|
|
|
|
{
|
2020-09-28 02:09:08 +02:00
|
|
|
auto ft = Formatter();
|
2020-08-09 07:23:28 +02:00
|
|
|
std::string authorsString;
|
|
|
|
for (size_t i = 0; i < listItem->repositoryItem->Authors.size(); i++)
|
|
|
|
{
|
|
|
|
if (i > 0)
|
|
|
|
{
|
|
|
|
authorsString.append(", ");
|
|
|
|
}
|
|
|
|
authorsString.append(listItem->repositoryItem->Authors[i]);
|
|
|
|
}
|
|
|
|
ft.Add<rct_string_id>(STR_STRING);
|
|
|
|
ft.Add<const char*>(authorsString.c_str());
|
2020-08-28 18:03:51 +02:00
|
|
|
DrawTextEllipsised(
|
|
|
|
dpi, { w->windowPos.x + w->width - 5, screenPos.y }, w->width - w->widgets[WIDX_LIST].right - 4,
|
|
|
|
STR_WINDOW_COLOUR_2_STRINGID, ft, COLOUR_BLACK, TextAlignment::RIGHT);
|
2020-08-09 07:23:28 +02:00
|
|
|
}
|
|
|
|
}
|
2015-02-11 20:42:10 +01:00
|
|
|
/**
|
2015-10-20 20:16:30 +02:00
|
|
|
*
|
2015-02-11 20:42:10 +01:00
|
|
|
* rct2: 0x006AADA3
|
|
|
|
*/
|
2018-06-22 23:21:44 +02:00
|
|
|
static void window_editor_object_selection_scrollpaint(rct_window* w, rct_drawpixelinfo* dpi, int32_t scrollIndex)
|
2015-02-11 20:42:10 +01:00
|
|
|
{
|
2020-05-10 14:49:15 +02:00
|
|
|
int32_t colour, colour2;
|
|
|
|
ScreenCoordsXY screenCoords;
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2020-11-09 10:36:37 +01:00
|
|
|
bool ridePage = (get_selected_object_type(w) == ObjectType::Ride);
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2018-06-20 17:28:51 +02:00
|
|
|
uint8_t paletteIndex = ColourMapA[w->colours[1]].mid_light;
|
2017-06-06 23:24:18 +02:00
|
|
|
gfx_clear(dpi, paletteIndex);
|
|
|
|
|
2020-05-10 14:49:15 +02:00
|
|
|
screenCoords.y = 0;
|
2018-06-22 23:21:44 +02:00
|
|
|
for (const auto& listItem : _listItems)
|
2018-01-21 03:39:52 +01:00
|
|
|
{
|
2020-06-18 20:43:38 +02:00
|
|
|
if (screenCoords.y + SCROLLABLE_ROW_HEIGHT >= dpi->y && screenCoords.y <= dpi->y + dpi->height)
|
2018-06-22 23:21:44 +02:00
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
// Draw checkbox
|
2018-01-21 03:39:52 +01:00
|
|
|
if (!(gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER) && !(*listItem.flags & 0x20))
|
2020-05-10 14:49:15 +02:00
|
|
|
gfx_fill_rect_inset(dpi, 2, screenCoords.y, 11, screenCoords.y + 10, w->colours[1], INSET_RECT_F_E0);
|
2017-06-06 23:24:18 +02:00
|
|
|
|
|
|
|
// Highlight background
|
2020-11-22 01:56:04 +01:00
|
|
|
auto highlighted = listItem.entry == w->object_entry && !(*listItem.flags & OBJECT_SELECTION_FLAG_6);
|
|
|
|
if (highlighted)
|
2018-06-22 23:21:44 +02:00
|
|
|
{
|
2020-06-18 20:43:38 +02:00
|
|
|
auto bottom = screenCoords.y + (SCROLLABLE_ROW_HEIGHT - 1);
|
2020-12-05 19:13:59 +01:00
|
|
|
gfx_filter_rect(dpi, 0, screenCoords.y, w->width, bottom, FilterPaletteID::PaletteDarken1);
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Draw checkmark
|
2018-06-22 23:21:44 +02:00
|
|
|
if (!(gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER) && (*listItem.flags & OBJECT_SELECTION_FLAG_SELECTED))
|
|
|
|
{
|
2020-05-10 14:49:15 +02:00
|
|
|
screenCoords.x = 2;
|
2021-02-27 18:35:32 +01:00
|
|
|
FontSpriteBase fontSpriteBase = highlighted ? FontSpriteBase::MEDIUM_EXTRA_DARK : FontSpriteBase::MEDIUM_DARK;
|
|
|
|
gCurrentFontSpriteBase = fontSpriteBase;
|
2017-06-06 23:24:18 +02:00
|
|
|
colour2 = NOT_TRANSLUCENT(w->colours[1]);
|
2018-01-21 03:39:52 +01:00
|
|
|
if (*listItem.flags & (OBJECT_SELECTION_FLAG_IN_USE | OBJECT_SELECTION_FLAG_ALWAYS_REQUIRED))
|
2017-06-06 23:24:18 +02:00
|
|
|
colour2 |= COLOUR_FLAG_INSET;
|
|
|
|
|
2021-02-27 18:35:32 +01:00
|
|
|
gfx_draw_string(
|
|
|
|
dpi, screenCoords, static_cast<const char*>(CheckBoxMarkString),
|
|
|
|
{ static_cast<colour_t>(colour2), fontSpriteBase });
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
|
|
|
|
2020-05-10 14:49:15 +02:00
|
|
|
screenCoords.x = gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER ? 0 : 15;
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2020-11-22 01:56:04 +01:00
|
|
|
auto bufferWithColour = strcpy(gCommonStringFormatBuffer, highlighted ? "{WINDOW_COLOUR_2}" : "{BLACK}");
|
|
|
|
auto buffer = strchr(bufferWithColour, '\0');
|
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
if (*listItem.flags & OBJECT_SELECTION_FLAG_6)
|
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
colour = w->colours[1] & 0x7F;
|
2021-02-27 12:40:20 +01:00
|
|
|
gCurrentFontSpriteBase = FontSpriteBase::MEDIUM_DARK;
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
2018-06-22 23:21:44 +02:00
|
|
|
else
|
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
colour = COLOUR_BLACK;
|
2021-02-27 12:40:20 +01:00
|
|
|
gCurrentFontSpriteBase = FontSpriteBase::MEDIUM;
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
|
|
|
|
2020-06-25 03:44:00 +02:00
|
|
|
int32_t width_limit = w->widgets[WIDX_LIST].width() - screenCoords.x;
|
2018-06-03 14:46:17 +02:00
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
if (ridePage)
|
|
|
|
{
|
2020-05-05 18:19:30 +02:00
|
|
|
width_limit /= 2;
|
2017-06-06 23:24:18 +02:00
|
|
|
// Draw ride type
|
2018-01-21 03:39:52 +01:00
|
|
|
rct_string_id rideTypeStringId = get_ride_type_string_id(listItem.repositoryItem);
|
2017-06-06 23:24:18 +02:00
|
|
|
safe_strcpy(buffer, language_get_string(rideTypeStringId), 256 - (buffer - bufferWithColour));
|
2020-09-28 02:09:08 +02:00
|
|
|
auto ft = Formatter();
|
2020-08-28 22:33:36 +02:00
|
|
|
ft.Add<const char*>(gCommonStringFormatBuffer);
|
|
|
|
DrawTextEllipsised(dpi, screenCoords, width_limit - 15, STR_STRING, ft, colour);
|
2020-05-10 14:49:15 +02:00
|
|
|
screenCoords.x = w->widgets[WIDX_LIST_SORT_RIDE].left - w->widgets[WIDX_LIST].left;
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Draw text
|
2018-05-14 14:05:59 +02:00
|
|
|
safe_strcpy(buffer, listItem.repositoryItem->Name.c_str(), 256 - (buffer - bufferWithColour));
|
2018-06-22 23:21:44 +02:00
|
|
|
if (gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER)
|
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
while (*buffer != 0 && *buffer != 9)
|
|
|
|
buffer++;
|
|
|
|
|
|
|
|
*buffer = 0;
|
|
|
|
}
|
2020-09-28 02:09:08 +02:00
|
|
|
auto ft = Formatter();
|
2020-08-28 22:33:36 +02:00
|
|
|
ft.Add<const char*>(gCommonStringFormatBuffer);
|
|
|
|
DrawTextEllipsised(dpi, screenCoords, width_limit, STR_STRING, ft, colour);
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
2020-06-18 20:43:38 +02:00
|
|
|
screenCoords.y += SCROLLABLE_ROW_HEIGHT;
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
2015-02-11 20:42:10 +01:00
|
|
|
}
|
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
static void window_editor_object_set_page(rct_window* w, int32_t page)
|
2014-11-25 00:05:35 +01:00
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
if (w->selected_tab == page)
|
|
|
|
return;
|
|
|
|
|
|
|
|
w->selected_tab = page;
|
|
|
|
w->selected_list_item = -1;
|
2017-10-15 15:53:16 +02:00
|
|
|
w->object_entry = nullptr;
|
2017-06-06 23:24:18 +02:00
|
|
|
w->scrolls[0].v_top = 0;
|
|
|
|
w->frame_no = 0;
|
|
|
|
|
2020-11-09 11:53:29 +01:00
|
|
|
if (page == EnumValue(ObjectType::Ride))
|
2018-06-22 23:21:44 +02:00
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
_listSortType = RIDE_SORT_TYPE;
|
|
|
|
_listSortDescending = false;
|
2018-06-22 23:21:44 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
_listSortType = RIDE_SORT_RIDE;
|
|
|
|
_listSortDescending = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
visible_list_refresh(w);
|
2019-06-15 17:20:16 +02:00
|
|
|
w->Invalidate();
|
2015-02-02 19:49:07 +01:00
|
|
|
}
|
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
static void window_editor_object_selection_set_pressed_tab(rct_window* w)
|
2015-02-11 17:02:57 +01:00
|
|
|
{
|
2018-12-16 10:02:40 +01:00
|
|
|
for (size_t i = 0; i < std::size(ObjectSelectionPages); i++)
|
2018-05-14 13:27:25 +02:00
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
w->pressed_widgets &= ~(1 << (WIDX_TAB_1 + i));
|
2018-05-14 13:27:25 +02:00
|
|
|
}
|
2017-06-06 23:24:18 +02:00
|
|
|
w->pressed_widgets |= 1LL << (WIDX_TAB_1 + w->selected_tab);
|
2015-02-11 17:02:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2015-02-02 19:49:07 +01:00
|
|
|
* Takes the y coordinate of the clicked on scroll list
|
|
|
|
* and converts this into an object selection.
|
|
|
|
* Returns the position in the list.
|
|
|
|
* Object_selection_flags, installed_entry also populated
|
2015-02-11 17:02:57 +01:00
|
|
|
*
|
2015-12-11 16:38:37 +01:00
|
|
|
* rct2: 0x006AA703
|
2015-02-02 19:49:07 +01:00
|
|
|
*/
|
2020-11-10 09:00:15 +01:00
|
|
|
static int32_t get_object_from_object_selection(ObjectType object_type, int32_t y)
|
2015-02-11 17:02:57 +01:00
|
|
|
{
|
2020-06-18 20:43:38 +02:00
|
|
|
int32_t listItemIndex = y / SCROLLABLE_ROW_HEIGHT;
|
2020-04-18 13:32:48 +02:00
|
|
|
if (listItemIndex < 0 || static_cast<size_t>(listItemIndex) >= _listItems.size())
|
2017-06-06 23:24:18 +02:00
|
|
|
return -1;
|
2015-06-25 17:48:32 +02:00
|
|
|
|
2017-06-06 23:24:18 +02:00
|
|
|
return listItemIndex;
|
2015-02-02 19:49:07 +01:00
|
|
|
}
|
|
|
|
|
2015-02-11 17:02:57 +01:00
|
|
|
/**
|
2015-10-20 20:16:30 +02:00
|
|
|
*
|
2015-02-11 17:02:57 +01:00
|
|
|
* rct2: 0x006D33E2
|
|
|
|
*/
|
2015-02-13 19:43:22 +01:00
|
|
|
static void window_editor_object_selection_manage_tracks()
|
2015-02-11 17:02:57 +01:00
|
|
|
{
|
2018-01-10 12:40:50 +01:00
|
|
|
set_every_ride_type_invented();
|
2018-01-02 20:31:48 +01:00
|
|
|
set_every_ride_entry_invented();
|
2015-02-02 19:49:07 +01:00
|
|
|
|
2020-12-23 01:38:39 +01:00
|
|
|
gS6Info.editor_step = EditorStep::DesignsManager;
|
2015-02-02 19:49:07 +01:00
|
|
|
|
2018-06-20 17:28:51 +02:00
|
|
|
int32_t entry_index = 0;
|
2020-11-09 10:36:37 +01:00
|
|
|
for (; object_entry_get_chunk(ObjectType::Ride, entry_index) == nullptr; entry_index++)
|
2018-06-22 23:21:44 +02:00
|
|
|
;
|
2015-02-02 19:49:07 +01:00
|
|
|
|
2017-06-06 23:24:18 +02:00
|
|
|
rct_ride_entry* ride_entry = get_ride_entry(entry_index);
|
2018-06-20 17:28:51 +02:00
|
|
|
uint8_t ride_type = ride_entry_get_first_non_null_ride_type(ride_entry);
|
2015-02-02 19:49:07 +01:00
|
|
|
|
2017-10-21 16:37:30 +02:00
|
|
|
auto intent = Intent(WC_TRACK_DESIGN_LIST);
|
|
|
|
intent.putExtra(INTENT_EXTRA_RIDE_TYPE, ride_type);
|
|
|
|
intent.putExtra(INTENT_EXTRA_RIDE_ENTRY_INDEX, entry_index);
|
|
|
|
context_open_intent(&intent);
|
2015-02-02 19:49:07 +01:00
|
|
|
}
|
|
|
|
|
2015-02-11 17:02:57 +01:00
|
|
|
/**
|
2015-10-20 20:16:30 +02:00
|
|
|
*
|
2015-02-11 17:02:57 +01:00
|
|
|
* rct2: 0x006ABBBE
|
|
|
|
*/
|
|
|
|
static void editor_load_selected_objects()
|
|
|
|
{
|
2020-04-18 13:32:48 +02:00
|
|
|
int32_t numItems = static_cast<int32_t>(object_repository_get_items_count());
|
2018-06-22 23:21:44 +02:00
|
|
|
const ObjectRepositoryItem* items = object_repository_get_items();
|
|
|
|
for (int32_t i = 0; i < numItems; i++)
|
|
|
|
{
|
|
|
|
if (_objectSelectionFlags[i] & OBJECT_SELECTION_FLAG_SELECTED)
|
|
|
|
{
|
|
|
|
const ObjectRepositoryItem* item = &items[i];
|
|
|
|
const rct_object_entry* entry = &item->ObjectEntry;
|
|
|
|
void* loadedObject = object_manager_get_loaded_object(entry);
|
|
|
|
if (loadedObject == nullptr)
|
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
loadedObject = object_manager_load_object(entry);
|
2018-06-22 23:21:44 +02:00
|
|
|
if (loadedObject == nullptr)
|
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
log_error("Failed to load entry %.8s", entry->name);
|
|
|
|
}
|
2018-06-22 23:21:44 +02:00
|
|
|
else if (!(gScreenFlags & SCREEN_FLAGS_EDITOR))
|
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
// Defaults selected items to researched (if in-game)
|
2020-11-09 11:53:29 +01:00
|
|
|
ObjectType objectType = entry->GetType();
|
2020-03-18 21:27:53 +01:00
|
|
|
auto entryIndex = object_manager_get_loaded_object_entry_index(loadedObject);
|
2020-11-09 10:36:37 +01:00
|
|
|
if (objectType == ObjectType::Ride)
|
2018-06-22 23:21:44 +02:00
|
|
|
{
|
|
|
|
rct_ride_entry* rideEntry = get_ride_entry(entryIndex);
|
2018-06-20 17:28:51 +02:00
|
|
|
uint8_t rideType = ride_entry_get_first_non_null_ride_type(rideEntry);
|
2021-02-26 10:01:00 +01:00
|
|
|
ResearchCategory category = static_cast<ResearchCategory>(GetRideTypeDescriptor(rideType).Category);
|
2020-04-30 12:58:20 +02:00
|
|
|
research_insert_ride_entry(rideType, entryIndex, category, true);
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
2020-11-09 10:36:37 +01:00
|
|
|
else if (objectType == ObjectType::SceneryGroup)
|
2018-06-22 23:21:44 +02:00
|
|
|
{
|
2020-01-26 15:17:37 +01:00
|
|
|
research_insert_scenery_group_entry(entryIndex, true);
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-01-18 21:25:57 +01:00
|
|
|
if (_numSelectedObjectsForType[EnumValue(ObjectType::Water)] == 0)
|
|
|
|
{
|
|
|
|
// Reloads the default cyan water palette if no palette was selected.
|
|
|
|
load_palette();
|
|
|
|
}
|
2015-06-04 17:33:29 +02:00
|
|
|
}
|
2015-06-06 00:54:47 +02:00
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
static void window_editor_object_selection_update(rct_window* w)
|
2015-06-06 23:04:53 +02:00
|
|
|
{
|
2018-06-22 23:21:44 +02:00
|
|
|
if (gCurrentTextBox.window.classification == w->classification && gCurrentTextBox.window.number == w->number)
|
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
window_update_textbox_caret();
|
2020-06-18 19:54:16 +02:00
|
|
|
widget_invalidate(w, WIDX_FILTER_TEXT_BOX);
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
for (rct_widgetindex i = WIDX_FILTER_RIDE_TAB_TRANSPORT; i <= WIDX_FILTER_RIDE_TAB_STALL; i++)
|
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
if (!(w->pressed_widgets & (1ULL << i)))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
w->frame_no++;
|
|
|
|
if (w->frame_no >= window_editor_object_selection_animation_loops[i - WIDX_FILTER_RIDE_TAB_TRANSPORT])
|
|
|
|
w->frame_no = 0;
|
|
|
|
|
|
|
|
widget_invalidate(w, i);
|
|
|
|
break;
|
|
|
|
}
|
2015-06-06 23:04:53 +02:00
|
|
|
}
|
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
static void window_editor_object_selection_textinput(rct_window* w, rct_widgetindex widgetIndex, char* text)
|
2015-06-06 00:54:47 +02:00
|
|
|
{
|
2020-06-18 19:54:16 +02:00
|
|
|
if (widgetIndex != WIDX_FILTER_TEXT_BOX || text == nullptr)
|
2017-06-06 23:24:18 +02:00
|
|
|
return;
|
2015-06-06 23:04:53 +02:00
|
|
|
|
2017-06-06 23:24:18 +02:00
|
|
|
if (strcmp(_filter_string, text) == 0)
|
|
|
|
return;
|
2015-06-06 23:04:53 +02:00
|
|
|
|
2017-11-23 12:08:04 +01:00
|
|
|
safe_strcpy(_filter_string, text, sizeof(_filter_string));
|
2015-06-06 00:54:47 +02:00
|
|
|
|
2017-06-06 23:24:18 +02:00
|
|
|
filter_update_counts();
|
2015-06-06 01:02:20 +02:00
|
|
|
|
2017-06-06 23:24:18 +02:00
|
|
|
w->scrolls->v_top = 0;
|
2015-06-06 01:02:20 +02:00
|
|
|
|
2017-06-06 23:24:18 +02:00
|
|
|
visible_list_refresh(w);
|
2019-06-15 17:20:16 +02:00
|
|
|
w->Invalidate();
|
2015-06-06 00:54:47 +02:00
|
|
|
}
|
|
|
|
|
2018-06-20 17:28:51 +02:00
|
|
|
static bool filter_selected(uint8_t objectFlag)
|
2016-07-02 15:59:13 +02:00
|
|
|
{
|
2018-06-22 23:21:44 +02:00
|
|
|
if (_FILTER_SELECTED == _FILTER_NONSELECTED)
|
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
return true;
|
|
|
|
}
|
2018-06-22 23:21:44 +02:00
|
|
|
if (_FILTER_SELECTED && objectFlag & OBJECT_SELECTION_FLAG_SELECTED)
|
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
return true;
|
|
|
|
}
|
2018-06-22 23:21:44 +02:00
|
|
|
else if (_FILTER_NONSELECTED && !(objectFlag & OBJECT_SELECTION_FLAG_SELECTED))
|
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
return true;
|
|
|
|
}
|
2018-06-22 23:21:44 +02:00
|
|
|
else
|
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
return false;
|
|
|
|
}
|
2016-06-17 10:46:30 +02:00
|
|
|
}
|
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
static bool filter_string(const ObjectRepositoryItem* item)
|
2015-06-06 00:54:47 +02:00
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
// Nothing to search for
|
|
|
|
if (_filter_string[0] == '\0')
|
|
|
|
return true;
|
|
|
|
|
|
|
|
// Object doesn't have a name
|
2018-05-14 14:05:59 +02:00
|
|
|
if (item->Name.empty())
|
2017-06-06 23:24:18 +02:00
|
|
|
return false;
|
|
|
|
|
|
|
|
// Get ride type
|
2018-06-22 23:21:44 +02:00
|
|
|
const char* rideTypeName = language_get_string(get_ride_type_string_id(item));
|
2017-06-06 23:24:18 +02:00
|
|
|
|
|
|
|
// Get object name (ride/vehicle for rides) and type name (rides only)
|
|
|
|
char name_lower[MAX_PATH];
|
|
|
|
char type_lower[MAX_PATH];
|
2017-11-23 12:08:04 +01:00
|
|
|
char object_path[MAX_PATH];
|
2017-06-06 23:24:18 +02:00
|
|
|
char filter_lower[sizeof(_filter_string)];
|
2018-05-14 14:05:59 +02:00
|
|
|
safe_strcpy(name_lower, item->Name.c_str(), MAX_PATH);
|
2017-06-06 23:24:18 +02:00
|
|
|
safe_strcpy(type_lower, rideTypeName, MAX_PATH);
|
2018-05-14 14:05:59 +02:00
|
|
|
safe_strcpy(object_path, item->Path.c_str(), MAX_PATH);
|
2017-06-06 23:24:18 +02:00
|
|
|
safe_strcpy(filter_lower, _filter_string, sizeof(_filter_string));
|
|
|
|
|
|
|
|
// Make use of lowercase characters only
|
2018-06-20 17:28:51 +02:00
|
|
|
for (int32_t i = 0; name_lower[i] != '\0'; i++)
|
2020-04-18 13:32:48 +02:00
|
|
|
name_lower[i] = static_cast<char>(tolower(name_lower[i]));
|
2018-06-20 17:28:51 +02:00
|
|
|
for (int32_t i = 0; type_lower[i] != '\0'; i++)
|
2020-04-18 13:32:48 +02:00
|
|
|
type_lower[i] = static_cast<char>(tolower(type_lower[i]));
|
2018-06-20 17:28:51 +02:00
|
|
|
for (int32_t i = 0; object_path[i] != '\0'; i++)
|
2020-04-18 13:32:48 +02:00
|
|
|
object_path[i] = static_cast<char>(tolower(object_path[i]));
|
2018-06-20 17:28:51 +02:00
|
|
|
for (int32_t i = 0; filter_lower[i] != '\0'; i++)
|
2020-04-18 13:32:48 +02:00
|
|
|
filter_lower[i] = static_cast<char>(tolower(filter_lower[i]));
|
2017-06-06 23:24:18 +02:00
|
|
|
|
2017-11-23 12:08:04 +01:00
|
|
|
// Check if the searched string exists in the name, ride type, or filename
|
|
|
|
bool inName = strstr(name_lower, filter_lower) != nullptr;
|
2020-11-09 10:36:37 +01:00
|
|
|
bool inRideType = (item->ObjectEntry.GetType() == ObjectType::Ride) && strstr(type_lower, filter_lower) != nullptr;
|
2017-11-23 12:08:04 +01:00
|
|
|
bool inPath = strstr(object_path, filter_lower) != nullptr;
|
|
|
|
|
|
|
|
return inName || inRideType || inPath;
|
2015-06-06 00:54:47 +02:00
|
|
|
}
|
|
|
|
|
2020-10-17 22:27:02 +02:00
|
|
|
static bool sources_match(ObjectSourceGame source)
|
2018-06-29 16:03:42 +02:00
|
|
|
{
|
|
|
|
// clang-format off
|
2020-10-17 22:27:02 +02:00
|
|
|
return (_FILTER_RCT1 && source == ObjectSourceGame::RCT1) ||
|
|
|
|
(_FILTER_AA && source == ObjectSourceGame::AddedAttractions) ||
|
|
|
|
(_FILTER_LL && source == ObjectSourceGame::LoopyLandscapes) ||
|
|
|
|
(_FILTER_RCT2 && source == ObjectSourceGame::RCT2) ||
|
|
|
|
(_FILTER_WW && source == ObjectSourceGame::WackyWorlds) ||
|
|
|
|
(_FILTER_TT && source == ObjectSourceGame::TimeTwister) ||
|
|
|
|
(_FILTER_OO && source == ObjectSourceGame::OpenRCT2Official) ||
|
2018-06-29 16:03:42 +02:00
|
|
|
(_FILTER_CUSTOM &&
|
2020-10-17 22:27:02 +02:00
|
|
|
source != ObjectSourceGame::RCT1 &&
|
|
|
|
source != ObjectSourceGame::AddedAttractions &&
|
|
|
|
source != ObjectSourceGame::LoopyLandscapes &&
|
|
|
|
source != ObjectSourceGame::RCT2 &&
|
|
|
|
source != ObjectSourceGame::WackyWorlds &&
|
|
|
|
source != ObjectSourceGame::TimeTwister &&
|
|
|
|
source != ObjectSourceGame::OpenRCT2Official);
|
2018-06-29 16:03:42 +02:00
|
|
|
// clang-format on
|
|
|
|
}
|
|
|
|
|
2018-07-30 22:44:59 +02:00
|
|
|
static bool filter_source(const ObjectRepositoryItem* item)
|
2015-06-06 00:54:47 +02:00
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
if (_FILTER_ALL)
|
|
|
|
return true;
|
2015-06-06 00:54:47 +02:00
|
|
|
|
2018-07-30 22:44:59 +02:00
|
|
|
for (auto source : item->Sources)
|
2018-07-06 15:15:56 +02:00
|
|
|
{
|
|
|
|
if (sources_match(source))
|
|
|
|
return true;
|
|
|
|
}
|
2018-07-03 12:53:29 +02:00
|
|
|
|
2018-07-06 15:15:56 +02:00
|
|
|
return false;
|
2015-06-06 00:54:47 +02:00
|
|
|
}
|
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
static bool filter_chunks(const ObjectRepositoryItem* item)
|
2015-06-14 18:19:54 +02:00
|
|
|
{
|
2020-11-11 10:51:10 +01:00
|
|
|
if (item->ObjectEntry.GetType() == ObjectType::Ride)
|
2018-06-22 23:21:44 +02:00
|
|
|
{
|
2020-11-11 10:51:10 +01:00
|
|
|
uint8_t rideType = 0;
|
|
|
|
for (int32_t i = 0; i < MAX_RIDE_TYPES_PER_RIDE_ENTRY; i++)
|
2020-11-09 11:53:29 +01:00
|
|
|
{
|
2020-11-11 10:51:10 +01:00
|
|
|
if (item->RideInfo.RideType[i] != RIDE_TYPE_NULL)
|
2017-12-07 16:12:37 +01:00
|
|
|
{
|
2020-11-11 10:51:10 +01:00
|
|
|
rideType = item->RideInfo.RideType[i];
|
|
|
|
break;
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
2020-11-09 11:53:29 +01:00
|
|
|
}
|
2021-02-26 10:01:00 +01:00
|
|
|
return (_filter_flags & (1 << (GetRideTypeDescriptor(rideType).Category + _numSourceGameItems))) != 0;
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
|
|
|
return true;
|
2015-06-14 18:19:54 +02:00
|
|
|
}
|
|
|
|
|
2015-06-06 00:54:47 +02:00
|
|
|
static void filter_update_counts()
|
|
|
|
{
|
2018-06-22 23:21:44 +02:00
|
|
|
if (!_FILTER_ALL || strlen(_filter_string) > 0)
|
|
|
|
{
|
|
|
|
const auto& selectionFlags = _objectSelectionFlags;
|
2018-12-22 12:18:17 +01:00
|
|
|
std::fill(std::begin(_filter_object_counts), std::end(_filter_object_counts), 0);
|
2017-06-06 23:24:18 +02:00
|
|
|
|
|
|
|
size_t numObjects = object_repository_get_items_count();
|
2018-06-22 23:21:44 +02:00
|
|
|
const ObjectRepositoryItem* items = object_repository_get_items();
|
2018-07-30 22:44:59 +02:00
|
|
|
for (size_t i = 0; i < numObjects; i++)
|
|
|
|
{
|
|
|
|
const ObjectRepositoryItem* item = &items[i];
|
2018-07-03 12:53:29 +02:00
|
|
|
if (filter_source(item) && filter_string(item) && filter_chunks(item) && filter_selected(selectionFlags[i]))
|
2018-06-22 23:21:44 +02:00
|
|
|
{
|
2020-11-10 09:00:15 +01:00
|
|
|
ObjectType objectType = item->ObjectEntry.GetType();
|
|
|
|
_filter_object_counts[EnumValue(objectType)]++;
|
2017-06-06 23:24:18 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-06-06 00:54:47 +02:00
|
|
|
}
|
2016-07-02 11:59:50 +02:00
|
|
|
|
2018-06-22 23:21:44 +02:00
|
|
|
static rct_string_id get_ride_type_string_id(const ObjectRepositoryItem* item)
|
2016-07-02 11:59:50 +02:00
|
|
|
{
|
2017-06-06 23:24:18 +02:00
|
|
|
rct_string_id result = STR_NONE;
|
2018-06-20 17:28:51 +02:00
|
|
|
for (int32_t i = 0; i < MAX_RIDE_TYPES_PER_RIDE_ENTRY; i++)
|
2018-01-29 18:06:11 +01:00
|
|
|
{
|
2018-06-20 17:28:51 +02:00
|
|
|
uint8_t rideType = item->RideInfo.RideType[i];
|
2018-01-29 18:06:11 +01:00
|
|
|
if (rideType != RIDE_TYPE_NULL)
|
|
|
|
{
|
2021-02-26 10:01:00 +01:00
|
|
|
result = GetRideTypeDescriptor(rideType).Naming.Name;
|
2017-06-06 23:24:18 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
2016-07-02 11:59:50 +02:00
|
|
|
}
|
2017-12-05 13:55:33 +01:00
|
|
|
|
2020-10-14 21:56:48 +02:00
|
|
|
static std::string object_get_description(const Object* object)
|
2017-12-05 13:55:33 +01:00
|
|
|
{
|
2020-10-14 21:56:48 +02:00
|
|
|
switch (object->GetObjectType())
|
2017-12-05 13:55:33 +01:00
|
|
|
{
|
2020-11-09 10:36:37 +01:00
|
|
|
case ObjectType::Ride:
|
2018-06-22 23:21:44 +02:00
|
|
|
{
|
2020-10-14 21:56:48 +02:00
|
|
|
const RideObject* rideObject = static_cast<const RideObject*>(object);
|
2018-06-22 23:21:44 +02:00
|
|
|
return rideObject->GetDescription();
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
return "";
|
2017-12-05 13:55:33 +01:00
|
|
|
}
|
|
|
|
}
|
2018-05-14 13:27:25 +02:00
|
|
|
|
2020-11-09 11:53:29 +01:00
|
|
|
static ObjectType get_selected_object_type(rct_window* w)
|
2018-05-14 13:27:25 +02:00
|
|
|
{
|
2019-03-25 17:21:53 +01:00
|
|
|
auto tab = w->selected_tab;
|
2020-11-09 11:53:29 +01:00
|
|
|
if (tab >= EnumValue(ObjectType::ScenarioText))
|
|
|
|
return static_cast<ObjectType>(tab + 1);
|
2019-03-25 17:21:53 +01:00
|
|
|
else
|
2020-11-09 11:53:29 +01:00
|
|
|
return static_cast<ObjectType>(tab);
|
2018-05-14 13:27:25 +02:00
|
|
|
}
|