diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 46fed91ad4..e1c03bddb2 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -35,10 +35,12 @@ - Fix: [#7544] Starting a headless server with no arguments causes the game to freeze. - Improved: [#2989] Multiplayer window now changes title when tab changes. - Improved: [#5339] Change eyedropper icon to actual eyedropper and change cursor to crosshair. +- Improved: [#5832] Resize tile inspector automatically when selecting a tile element. - Improved: [#7302] Raising land near the map edge makes the affected area smaller instead of showing an 'off edge map' error. - Improved: [#7435] Object indexing now supports multi-threading. - Improved: [#7510] Add horizontal clipping to cut-away view options. - Improved: [#7531] "Save track design" dropdown now stays open. +- Improved: [#7548] Ctrl-clicking with the tile inspector open now directly selects an element and its tile. 0.1.2 (2018-03-18) ------------------------------------------------------------------------ diff --git a/src/openrct2-ui/WindowManager.cpp b/src/openrct2-ui/WindowManager.cpp index 8f7016eb4f..65c022eb8f 100644 --- a/src/openrct2-ui/WindowManager.cpp +++ b/src/openrct2-ui/WindowManager.cpp @@ -345,20 +345,6 @@ public: window_tile_inspector_clear_clipboard(); break; - case INTENT_ACTION_SET_TILE_INSPECTOR_PAGE: - { - auto window = window_find_by_class(WC_TILE_INSPECTOR); - window_tile_inspector_set_page(window, static_cast(intent.GetUIntExtra(INTENT_EXTRA_PAGE))); - break; - } - - case INTENT_ACTION_SET_TILE_INSPECTOR_BUTTONS: - { - auto window = window_find_by_class(WC_TILE_INSPECTOR); - window_tile_inspector_auto_set_buttons(window); - break; - } - case INTENT_ACTION_INVALIDATE_VEHICLE_WINDOW: { rct_vehicle * vehicle = static_cast(intent.GetPointerExtra(INTENT_EXTRA_VEHICLE)); diff --git a/src/openrct2-ui/windows/TileInspector.cpp b/src/openrct2-ui/windows/TileInspector.cpp index 1697caf77d..9fa0bd479c 100644 --- a/src/openrct2-ui/windows/TileInspector.cpp +++ b/src/openrct2-ui/windows/TileInspector.cpp @@ -207,10 +207,10 @@ enum WINDOW_TILE_INSPECTOR_WIDGET_IDX { // Window sizes #define WW 400 -#define WH 280 +#define WH 170 #define MIN_WW WW #define MAX_WW WW -#define MIN_WH 240 +#define MIN_WH 130 #define MAX_WH 800 // Button space for top buttons @@ -464,10 +464,17 @@ static struct { { COR_GBDT, COR_GBDB, COR_GBPT, COR_GBPB, STR_TILE_INSPECTOR_GROUPBOX_CORRUPT_INFO } }; +// clang-format on +static constexpr sint32 ViewportInteractionFlags = VIEWPORT_INTERACTION_MASK_TERRAIN & VIEWPORT_INTERACTION_MASK_SPRITE + & VIEWPORT_INTERACTION_MASK_RIDE & VIEWPORT_INTERACTION_MASK_SCENERY & VIEWPORT_INTERACTION_MASK_FOOTPATH + & VIEWPORT_INTERACTION_MASK_FOOTPATH_ITEM & VIEWPORT_INTERACTION_MASK_PARK & VIEWPORT_INTERACTION_MASK_WALL + & VIEWPORT_INTERACTION_MASK_LARGE_SCENERY & VIEWPORT_INTERACTION_MASK_BANNER; + static sint16 windowTileInspectorHighlightedIndex = -1; static bool windowTileInspectorTileSelected = false; static sint32 windowTileInspectorToolMouseX = 0; static sint32 windowTileInspectorToolMouseY = 0; +static bool windowTileInspectorToolCtrlDown = false; static sint32 windowTileInspectorToolMapX = 0; static sint32 windowTileInspectorToolMapY = 0; static bool windowTileInspectorApplyToAll = false; @@ -490,6 +497,7 @@ static void window_tile_inspector_invalidate(rct_window *w); static void window_tile_inspector_paint(rct_window *w, rct_drawpixelinfo *dpi); static void window_tile_inspector_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi, sint32 scrollIndex); +// clang-format off static rct_window_event_list TileInspectorWindowEvents = { nullptr, window_tile_inspector_mouseup, @@ -566,19 +574,18 @@ rct_window * window_tile_inspector_open() WC_TILE_INSPECTOR, WF_RESIZABLE ); - window_tile_inspector_set_page(window, TILE_INSPECTOR_PAGE_DEFAULT); - window_init_scroll_widgets(window); + window->widgets = PageWidgets[TILE_INSPECTOR_PAGE_DEFAULT]; window->min_width = MIN_WW; window->min_height = MIN_WH; window->max_width = MAX_WW; window->max_height = MAX_WH; window->selected_list_item = -1; + window_init_scroll_widgets(window); windowTileInspectorTileSelected = false; tool_set(window, WIDX_BACKGROUND, TOOL_CROSSHAIR); - window_tile_inspector_auto_set_buttons(window); return window; } @@ -597,44 +604,37 @@ static rct_tile_element* window_tile_inspector_get_selected_element(rct_window * static void window_tile_inspector_select_element_from_list(rct_window *w, sint32 index) { - sint32 page; - if (index < 0 || index >= windowTileInspectorElementCount) { + if (index < 0 || index >= windowTileInspectorElementCount) + { w->selected_list_item = -1; - page = 0; } - else { + else + { w->selected_list_item = index; - - // Get type of selected map element to select the correct page - rct_tile_element *const tileElement = window_tile_inspector_get_selected_element(w); - page = (Math::Min(tileElement->GetType(), TILE_ELEMENT_TYPE_CORRUPT) >> 2) + 1; } - window_tile_inspector_set_page(w, (TILE_INSPECTOR_PAGE)page); - - // Enable/disable buttons - window_tile_inspector_auto_set_buttons(w); window_invalidate(w); } -static void window_tile_inspector_load_tile(rct_window* w) +static void window_tile_inspector_load_tile(rct_window* w, rct_tile_element* elementToSelect) { - rct_tile_element *element = map_get_first_element_at(windowTileInspectorTileX, windowTileInspectorTileY); - sint32 numItems = 0; - do { + w->selected_list_item = -1; + w->scrolls[0].v_top = 0; + + rct_tile_element* element = map_get_first_element_at(windowTileInspectorTileX, windowTileInspectorTileY); + sint16 numItems = 0; + do + { + if (element == elementToSelect) + { + w->selected_list_item = numItems; + } + numItems++; } while (!tile_element_is_last_for_tile(element++)); windowTileInspectorElementCount = numItems; - // Set default page - window_tile_inspector_set_page(w, TILE_INSPECTOR_PAGE_DEFAULT); - - // undo selection and buttons affecting it - w->selected_list_item = -1; - window_tile_inspector_auto_set_buttons(w); - - w->scrolls[0].v_top = 0; window_invalidate(w); } @@ -720,6 +720,7 @@ static void window_tile_inspector_copy_element(rct_window *w) // Copy value, in case the element gets moved tileInspectorCopiedElement = *window_tile_inspector_get_selected_element(w); windowTileInspectorElementCopied = true; + window_invalidate(w); } static void window_tile_inspector_paste_element(rct_window *w) @@ -945,24 +946,20 @@ static void window_tile_inspector_mouseup(rct_window *w, rct_widgetindex widgetI window_close(w); break; case WIDX_SPINNER_X_INCREASE: - windowTileInspectorTileX = Math::Min(windowTileInspectorTileX + 1, 255); - window_tile_inspector_load_tile(w); - window_tile_inspector_auto_set_buttons(w); + windowTileInspectorTileX = Math::Min(windowTileInspectorTileX + 1, MAXIMUM_MAP_SIZE_TECHNICAL - 1); + window_tile_inspector_load_tile(w, nullptr); break; case WIDX_SPINNER_X_DECREASE: windowTileInspectorTileX = Math::Max(windowTileInspectorTileX - 1, 0); - window_tile_inspector_load_tile(w); - window_tile_inspector_auto_set_buttons(w); + window_tile_inspector_load_tile(w, nullptr); break; case WIDX_SPINNER_Y_INCREASE: - windowTileInspectorTileY = Math::Min(windowTileInspectorTileY + 1, 255); - window_tile_inspector_load_tile(w); - window_tile_inspector_auto_set_buttons(w); + windowTileInspectorTileY = Math::Min(windowTileInspectorTileY + 1, MAXIMUM_MAP_SIZE_TECHNICAL - 1); + window_tile_inspector_load_tile(w, nullptr); break; case WIDX_SPINNER_Y_DECREASE: windowTileInspectorTileY = Math::Max(windowTileInspectorTileY - 1, 0); - window_tile_inspector_load_tile(w); - window_tile_inspector_auto_set_buttons(w); + window_tile_inspector_load_tile(w, nullptr); break; case WIDX_BUTTON_CORRUPT: window_tile_inspector_insert_corrupt_element(w->selected_list_item); @@ -981,8 +978,6 @@ static void window_tile_inspector_mouseup(rct_window *w, rct_widgetindex widgetI break; case WIDX_BUTTON_COPY: window_tile_inspector_copy_element(w); - window_tile_inspector_auto_set_buttons(w); - window_invalidate(w); break; case WIDX_BUTTON_PASTE: window_tile_inspector_paste_element(w); @@ -1050,7 +1045,7 @@ static void window_tile_inspector_mouseup(rct_window *w, rct_widgetindex widgetI // 0 = east/right, 1 = south/bottom, 2 = west/left, 3 = north/top const sint32 eswn = (widgetIndex - WIDX_PATH_CHECK_EDGE_E) / 2; // Transform to world orientation - const sint32 index = (4 + eswn - get_current_rotation()) & 3; + const sint32 index = (eswn - get_current_rotation()) & 3; window_tile_inspector_path_toggle_edge(w->selected_list_item, index + 4); // The corners are stored in the 4 most significant bits, hence the + 4 break; } @@ -1062,7 +1057,7 @@ static void window_tile_inspector_mouseup(rct_window *w, rct_widgetindex widgetI // 0 = NE, 1 = SE, 2 = SW, 3 = NW const sint32 neseswnw = (widgetIndex - WIDX_PATH_CHECK_EDGE_NE) / 2; // Transform to world orientation - const sint32 index = (4 + neseswnw - get_current_rotation()) & 3; + const sint32 index = (neseswnw - get_current_rotation()) & 3; window_tile_inspector_path_toggle_edge(w->selected_list_item, index); break; } @@ -1285,17 +1280,30 @@ static void window_tile_inspector_tool_update(rct_window* w, rct_widgetindex wid sint16 mapX = x; sint16 mapY = y; - sint32 direction; - screen_pos_to_map_pos(&mapX, &mapY, &direction); - if (mapX != LOCATION_NULL) { + rct_tile_element* clickedElement = nullptr; + if (input_test_place_object_modifier(PLACE_OBJECT_MODIFIER_COPY_Z)) + { + get_map_coordinates_from_pos(x, y, ViewportInteractionFlags, &mapX, &mapY, nullptr, &clickedElement, nullptr); + } + + // Even if Ctrl was pressed, fall back to normal selection when there was nothing under the cursor + if (clickedElement == nullptr) + { + screen_pos_to_map_pos(&mapX, &mapY, nullptr); + } + + if (mapX != LOCATION_NULL) + { gMapSelectPositionA.x = gMapSelectPositionB.x = mapX; gMapSelectPositionA.y = gMapSelectPositionB.y = mapY; } - else if (windowTileInspectorTileSelected){ + else if (windowTileInspectorTileSelected) + { gMapSelectPositionA.x = gMapSelectPositionB.x = windowTileInspectorTileX << 5; gMapSelectPositionA.y = gMapSelectPositionB.y = windowTileInspectorTileY << 5; } - else { + else + { gMapSelectFlags &= ~MAP_SELECT_FLAG_ENABLE; } @@ -1303,26 +1311,44 @@ static void window_tile_inspector_tool_update(rct_window* w, rct_widgetindex wid map_invalidate_selection_rect(); } -static void window_tile_inspector_update_selected_tile(rct_window *w, sint32 x, sint32 y) +static void window_tile_inspector_update_selected_tile(rct_window* w, sint32 x, sint32 y) { + const bool ctrlIsHeldDown = input_test_place_object_modifier(PLACE_OBJECT_MODIFIER_COPY_Z); + // Mouse hasn't moved - if (x == windowTileInspectorToolMouseX && y == windowTileInspectorToolMouseY) { + if (x == windowTileInspectorToolMouseX && y == windowTileInspectorToolMouseY + && windowTileInspectorToolCtrlDown == ctrlIsHeldDown) + { return; } + windowTileInspectorToolMouseX = x; windowTileInspectorToolMouseY = y; + windowTileInspectorToolCtrlDown = ctrlIsHeldDown; sint16 mapX = x; sint16 mapY = y; - sint32 direction; - screen_pos_to_map_pos(&mapX, &mapY, &direction); - if (mapX == LOCATION_NULL) { - return; + rct_tile_element* clickedElement = nullptr; + if (ctrlIsHeldDown) + { + get_map_coordinates_from_pos(x, y, ViewportInteractionFlags, &mapX, &mapY, nullptr, &clickedElement, nullptr); } - // Tile is already selected - if (windowTileInspectorTileSelected && mapX == windowTileInspectorToolMapX && mapY == windowTileInspectorToolMapY) { - return; + // Even if Ctrl was pressed, fall back to normal selection when there was nothing under the cursor + if (clickedElement == nullptr) + { + screen_pos_to_map_pos(&mapX, &mapY, nullptr); + + if (mapX == LOCATION_NULL) + { + return; + } + + // Tile is already selected + if (windowTileInspectorTileSelected && mapX == windowTileInspectorToolMapX && mapY == windowTileInspectorToolMapY) + { + return; + } } windowTileInspectorTileSelected = true; @@ -1331,8 +1357,7 @@ static void window_tile_inspector_update_selected_tile(rct_window *w, sint32 x, windowTileInspectorTileX = mapX >> 5; windowTileInspectorTileY = mapY >> 5; - window_tile_inspector_load_tile(w); - window_tile_inspector_auto_set_buttons(w); + window_tile_inspector_load_tile(w, clickedElement); } static void window_tile_inspector_tool_down(rct_window* w, rct_widgetindex widgetIndex, sint32 x, sint32 y) @@ -1351,56 +1376,27 @@ static void window_tile_inspector_scrollgetsize(rct_window *w, sint32 scrollInde *height = windowTileInspectorElementCount * LIST_ITEM_HEIGHT; } -void window_tile_inspector_set_page(rct_window *w, const TILE_INSPECTOR_PAGE page) +static void window_tile_inspector_set_page(rct_window *w, const TILE_INSPECTOR_PAGE page) { + // Invalidate the window already, because the size may change + window_invalidate(w); + + // subtract current page height, then add new page height + if (w->page != TILE_INSPECTOR_PAGE_DEFAULT) + { + w->height -= PageGroupBoxSettings[w->page - 1].details_top_offset - GROUPBOX_PADDING - 3; + w->min_height -= PageGroupBoxSettings[w->page - 1].details_top_offset - GROUPBOX_PADDING - 3; + } + if (page != TILE_INSPECTOR_PAGE_DEFAULT) + { + w->height += PageGroupBoxSettings[page - 1].details_top_offset - GROUPBOX_PADDING - 3; + w->min_height += PageGroupBoxSettings[page - 1].details_top_offset - GROUPBOX_PADDING - 3; + } w->page = page; w->widgets = PageWidgets[page]; w->enabled_widgets = PageEnabledWidgets[page]; w->disabled_widgets = PageDisabledWidgets[page]; -} - -void window_tile_inspector_auto_set_buttons(rct_window *w) -{ - // X and Y spinners - widget_set_enabled(w, WIDX_SPINNER_X_INCREASE, (windowTileInspectorTileSelected && (windowTileInspectorTileX < 255))); - widget_set_enabled(w, WIDX_SPINNER_X_DECREASE, (windowTileInspectorTileSelected && (windowTileInspectorTileX > 0))); - widget_set_enabled(w, WIDX_SPINNER_Y_INCREASE, (windowTileInspectorTileSelected && (windowTileInspectorTileY < 255))); - widget_set_enabled(w, WIDX_SPINNER_Y_DECREASE, (windowTileInspectorTileSelected && (windowTileInspectorTileY > 0))); - - // Sort buttons - widget_set_enabled(w, WIDX_BUTTON_SORT, (windowTileInspectorTileSelected && windowTileInspectorElementCount > 1)); - - // Move Up button - widget_set_enabled(w, WIDX_BUTTON_MOVE_UP, (w->selected_list_item > 0)); - widget_invalidate(w, WIDX_BUTTON_MOVE_UP); - - // Move Down button - widget_set_enabled(w, WIDX_BUTTON_MOVE_DOWN, (w->selected_list_item != -1 && w->selected_list_item < windowTileInspectorElementCount - 1)); - widget_invalidate(w, WIDX_BUTTON_MOVE_DOWN); - - // Copy button - widget_set_enabled(w, WIDX_BUTTON_COPY, w->selected_list_item >= 0); - widget_invalidate(w, WIDX_BUTTON_COPY); - - // Paste button - widget_set_enabled(w, WIDX_BUTTON_PASTE, windowTileInspectorTileSelected && windowTileInspectorElementCopied); - widget_invalidate(w, WIDX_BUTTON_PASTE); - - // Page widgets - switch (w->page) { - case TILE_INSPECTOR_PAGE_WALL: { - const rct_tile_element *const tileElement = window_tile_inspector_get_selected_element(w); - const uint8 wallType = tileElement->properties.wall.type; - const rct_wall_scenery_entry wallEntry = get_wall_entry(wallType)->wall; - const bool canBeSloped = !(wallEntry.flags & WALL_SCENERY_CANT_BUILD_ON_SLOPE); - // Wall slope dropdown - widget_set_enabled(w, WIDX_WALL_DROPDOWN_SLOPE, canBeSloped); - widget_invalidate(w, WIDX_WALL_DROPDOWN_SLOPE); - widget_set_enabled(w, WIDX_WALL_DROPDOWN_SLOPE_BUTTON, canBeSloped); - widget_invalidate(w, WIDX_WALL_DROPDOWN_SLOPE_BUTTON); - break; - } - } // switch page + w->pressed_widgets = 0; } static void window_tile_inspector_scrollmousedown(rct_window *w, sint32 scrollIndex, sint32 x, sint32 y) @@ -1423,17 +1419,74 @@ static void window_tile_inspector_scrollmouseover(rct_window *w, sint32 scrollIn static void window_tile_inspector_invalidate(rct_window *w) { + // Set the correct page automatically + TILE_INSPECTOR_PAGE page = TILE_INSPECTOR_PAGE_DEFAULT; + if (w->selected_list_item != -1) + { + const auto element = window_tile_inspector_get_selected_element(w); + auto type = element->GetType(); + switch (type) + { + case TILE_ELEMENT_TYPE_SURFACE: page = TILE_INSPECTOR_PAGE_SURFACE; break; + case TILE_ELEMENT_TYPE_PATH: page = TILE_INSPECTOR_PAGE_PATH; break; + case TILE_ELEMENT_TYPE_TRACK: page = TILE_INSPECTOR_PAGE_TRACK; break; + case TILE_ELEMENT_TYPE_SMALL_SCENERY: page = TILE_INSPECTOR_PAGE_SCENERY; break; + case TILE_ELEMENT_TYPE_ENTRANCE: page = TILE_INSPECTOR_PAGE_ENTRANCE; break; + case TILE_ELEMENT_TYPE_WALL: page = TILE_INSPECTOR_PAGE_WALL; break; + case TILE_ELEMENT_TYPE_LARGE_SCENERY: page = TILE_INSPECTOR_PAGE_LARGE_SCENERY; break; + case TILE_ELEMENT_TYPE_BANNER: page = TILE_INSPECTOR_PAGE_BANNER; break; + case TILE_ELEMENT_TYPE_CORRUPT: + default: + page = TILE_INSPECTOR_PAGE_CORRUPT; + break; + } + } + + if (w->page != page) + { + window_tile_inspector_set_page(w, page); + window_invalidate(w); + } + + // X and Y spinners + widget_set_enabled(w, WIDX_SPINNER_X_INCREASE, (windowTileInspectorTileSelected && (windowTileInspectorTileX < MAXIMUM_MAP_SIZE_TECHNICAL - 1))); + widget_set_enabled(w, WIDX_SPINNER_X_DECREASE, (windowTileInspectorTileSelected && (windowTileInspectorTileX > 0))); + widget_set_enabled(w, WIDX_SPINNER_Y_INCREASE, (windowTileInspectorTileSelected && (windowTileInspectorTileY < MAXIMUM_MAP_SIZE_TECHNICAL - 1))); + widget_set_enabled(w, WIDX_SPINNER_Y_DECREASE, (windowTileInspectorTileSelected && (windowTileInspectorTileY > 0))); + + // Sort buttons + widget_set_enabled(w, WIDX_BUTTON_SORT, (windowTileInspectorTileSelected && windowTileInspectorElementCount > 1)); + + // Move Up button + widget_set_enabled(w, WIDX_BUTTON_MOVE_UP, (w->selected_list_item > 0)); + widget_invalidate(w, WIDX_BUTTON_MOVE_UP); + + // Move Down button + widget_set_enabled( + w, WIDX_BUTTON_MOVE_DOWN, (w->selected_list_item != -1 && w->selected_list_item < windowTileInspectorElementCount - 1)); + widget_invalidate(w, WIDX_BUTTON_MOVE_DOWN); + + // Copy button + widget_set_enabled(w, WIDX_BUTTON_COPY, w->selected_list_item >= 0); + widget_invalidate(w, WIDX_BUTTON_COPY); + + // Paste button + widget_set_enabled(w, WIDX_BUTTON_PASTE, windowTileInspectorTileSelected && windowTileInspectorElementCopied); + widget_invalidate(w, WIDX_BUTTON_PASTE); + w->widgets[WIDX_BACKGROUND].bottom = w->height - 1; - if (w->page == TILE_INSPECTOR_PAGE_DEFAULT) { + if (w->page == TILE_INSPECTOR_PAGE_DEFAULT) + { w->widgets[WIDX_GROUPBOX_DETAILS].type = WWT_EMPTY; w->widgets[WIDX_GROUPBOX_PROPERTIES].type = WWT_EMPTY; w->widgets[WIDX_LIST].bottom = w->height - PADDING_BOTTOM; } - else { + else + { w->widgets[WIDX_GROUPBOX_DETAILS].type = WWT_GROUPBOX; w->widgets[WIDX_GROUPBOX_PROPERTIES].type = WWT_GROUPBOX; - w->widgets[WIDX_GROUPBOX_DETAILS].image = PageGroupBoxSettings[w->page - 1].string_id; + w->widgets[WIDX_GROUPBOX_DETAILS].text = PageGroupBoxSettings[w->page - 1].string_id; w->widgets[WIDX_GROUPBOX_DETAILS].top = w->height - PageGroupBoxSettings[w->page - 1].details_top_offset; w->widgets[WIDX_GROUPBOX_DETAILS].bottom = w->height - PageGroupBoxSettings[w->page - 1].details_bottom_offset; w->widgets[WIDX_GROUPBOX_PROPERTIES].top = w->height - PageGroupBoxSettings[w->page - 1].properties_top_offset; @@ -1441,7 +1494,7 @@ static void window_tile_inspector_invalidate(rct_window *w) w->widgets[WIDX_LIST].bottom = w->widgets[WIDX_GROUPBOX_DETAILS].top - GROUPBOX_PADDING; } - // Only page-specific widgets related to the map element will be + // The default page doesn't need further invalidation if (w->page == TILE_INSPECTOR_PAGE_DEFAULT) { return; } @@ -1449,7 +1502,7 @@ static void window_tile_inspector_invalidate(rct_window *w) // Using a switch, because I don't think giving each page their own callbacks is // needed here, as only the mouseup and invalidate functions are different. const sint32 propertiesAnchor = w->widgets[WIDX_GROUPBOX_PROPERTIES].top; - rct_tile_element *const tileElement = window_tile_inspector_get_selected_element(w); + const rct_tile_element *const tileElement = window_tile_inspector_get_selected_element(w); switch (w->page) { case TILE_INSPECTOR_PAGE_SURFACE: @@ -1587,6 +1640,7 @@ static void window_tile_inspector_invalidate(rct_window *w) widget_set_enabled(w, WIDX_ENTRANCE_BUTTON_MAKE_USABLE, tileElement->properties.entrance.type != ENTRANCE_TYPE_PARK_ENTRANCE); break; case TILE_INSPECTOR_PAGE_WALL: + { w->widgets[WIDX_WALL_SPINNER_HEIGHT].top = GBBT(propertiesAnchor, 0) + 3; w->widgets[WIDX_WALL_SPINNER_HEIGHT].bottom = GBBB(propertiesAnchor, 0) - 3; w->widgets[WIDX_WALL_SPINNER_HEIGHT_INCREASE].top = GBBT(propertiesAnchor, 0) + 4; @@ -1598,7 +1652,16 @@ static void window_tile_inspector_invalidate(rct_window *w) w->widgets[WIDX_WALL_DROPDOWN_SLOPE].text = WallSlopeStringIds[tileElement->GetSceneryQuadrant()]; w->widgets[WIDX_WALL_DROPDOWN_SLOPE_BUTTON].top = GBBT(propertiesAnchor, 1) + 4; w->widgets[WIDX_WALL_DROPDOWN_SLOPE_BUTTON].bottom = GBBB(propertiesAnchor, 1) - 4; + const uint8 wallType = tileElement->properties.wall.type; + const rct_wall_scenery_entry wallEntry = get_wall_entry(wallType)->wall; + const bool canBeSloped = !(wallEntry.flags & WALL_SCENERY_CANT_BUILD_ON_SLOPE); + // Wall slope dropdown + widget_set_enabled(w, WIDX_WALL_DROPDOWN_SLOPE, canBeSloped); + widget_invalidate(w, WIDX_WALL_DROPDOWN_SLOPE); + widget_set_enabled(w, WIDX_WALL_DROPDOWN_SLOPE_BUTTON, canBeSloped); + widget_invalidate(w, WIDX_WALL_DROPDOWN_SLOPE_BUTTON); break; + } case TILE_INSPECTOR_PAGE_LARGE_SCENERY: w->widgets[WIDX_LARGE_SCENERY_SPINNER_HEIGHT].top = GBBT(propertiesAnchor, 0) + 3; w->widgets[WIDX_LARGE_SCENERY_SPINNER_HEIGHT].bottom = GBBB(propertiesAnchor, 0) - 3; @@ -1845,15 +1908,20 @@ static void window_tile_inspector_paint(rct_window *w, rct_drawpixelinfo *dpi) sint16 parkEntranceIndex = park_entrance_get_index(middleX, middleY, tileElement->base_height * 8); gfx_draw_string_left(dpi, STR_TILE_INSPECTOR_ENTRANCE_ENTRANCE_ID, &parkEntranceIndex, COLOUR_DARK_GREEN, x, y + 11); } - else { - sint16 rideEntranceIndex = (tileElement->properties.entrance.index & 0x30) >> 4; - if (tileElement->properties.entrance.type == ENTRANCE_TYPE_RIDE_ENTRANCE) { + else + { + sint16 rideEntranceIndex = (tileElement->properties.entrance.index & 0x30) >> 4; // TODO: use mask or function + if (tileElement->properties.entrance.type == ENTRANCE_TYPE_RIDE_ENTRANCE) + { // Ride entrance ID - gfx_draw_string_left(dpi, STR_TILE_INSPECTOR_ENTRANCE_ENTRANCE_ID, &rideEntranceIndex, COLOUR_DARK_GREEN, x, y + 11); + gfx_draw_string_left( + dpi, STR_TILE_INSPECTOR_ENTRANCE_ENTRANCE_ID, &rideEntranceIndex, COLOUR_DARK_GREEN, x, y + 11); } - else { + else + { // Ride exit ID - gfx_draw_string_left(dpi, STR_TILE_INSPECTOR_ENTRANCE_EXIT_ID, &rideEntranceIndex, COLOUR_DARK_GREEN, x, y + 11); + gfx_draw_string_left( + dpi, STR_TILE_INSPECTOR_ENTRANCE_EXIT_ID, &rideEntranceIndex, COLOUR_DARK_GREEN, x, y + 11); } } @@ -1928,7 +1996,6 @@ static void window_tile_inspector_paint(rct_window *w, rct_drawpixelinfo *dpi) if (largeSceneryEntry->large_scenery.scrolling_mode != 0xFF) { const sint32 bannerIndex = scenery_large_get_banner_id(tileElement); - //window_sign_open(bannerIndex); gfx_draw_string_left(dpi, STR_TILE_INSPECTOR_ENTRY_BANNER_TEXT, &gBanners[bannerIndex].string_idx, COLOUR_DARK_GREEN, x, y + 22); } else { @@ -1994,8 +2061,11 @@ static void window_tile_inspector_paint(rct_window *w, rct_drawpixelinfo *dpi) } } -static void window_tile_inspector_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi, sint32 scrollIndex) +static void window_tile_inspector_scrollpaint(rct_window* w, rct_drawpixelinfo* dpi, sint32 scrollIndex) { + const sint32 listWidth = w->widgets[WIDX_LIST].right - w->widgets[WIDX_LIST].left; + gfx_fill_rect(dpi, dpi->x, dpi->y, dpi->x + dpi->width - 1, dpi->y + dpi->height - 1, ColourMapA[w->colours[1]].mid_light); + sint32 y = LIST_ITEM_HEIGHT * (windowTileInspectorElementCount - 1); sint32 i = 0; char buffer[256]; @@ -2003,23 +2073,28 @@ static void window_tile_inspector_scrollpaint(rct_window *w, rct_drawpixelinfo * if (!windowTileInspectorTileSelected) return; - rct_tile_element *tileElement = map_get_first_element_at(windowTileInspectorTileX, windowTileInspectorTileY); + const rct_tile_element* tileElement = map_get_first_element_at(windowTileInspectorTileX, windowTileInspectorTileY); gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM; do { + const bool selectedRow = i == w->selected_list_item; + const bool hoveredRow = i == windowTileInspectorHighlightedIndex; sint32 type = tileElement->GetType(); - const char * typeName = ""; - sint32 baseHeight = tileElement->base_height; - sint32 clearanceHeight = tileElement->clearance_height; + const char* typeName = ""; - // Fill colour for current list element - const sint32 listWidth = w->widgets[WIDX_LIST].right - w->widgets[WIDX_LIST].left; - if (i == w->selected_list_item) // Currently selected element - gfx_fill_rect(dpi, 0, y, listWidth, y + LIST_ITEM_HEIGHT - 1, ColourMapA[w->colours[1]].darker | 0x1000000); - else if (i == windowTileInspectorHighlightedIndex) // Hovering + if (selectedRow) + { + gfx_fill_rect(dpi, 0, y, listWidth, y + LIST_ITEM_HEIGHT - 1, ColourMapA[w->colours[1]].mid_dark); + } + else if (hoveredRow) + { gfx_fill_rect(dpi, 0, y, listWidth, y + LIST_ITEM_HEIGHT - 1, ColourMapA[w->colours[1]].mid_dark | 0x1000000); - else if ((i & 1) != 0) // odd / even check - gfx_fill_rect(dpi, 0, y, listWidth, y + LIST_ITEM_HEIGHT - 1, ColourMapA[w->colours[1]].lighter | 0x1000000); + } + else if (((windowTileInspectorElementCount - i) & 1) == 0) + { + // Zebra stripes + gfx_fill_rect(dpi, 0, y, listWidth, y + LIST_ITEM_HEIGHT - 1, ColourMapA[w->colours[1]].light | 0x1000000); + } switch (type) { case TILE_ELEMENT_TYPE_SURFACE: @@ -2071,18 +2146,45 @@ static void window_tile_inspector_scrollpaint(rct_window *w, rct_drawpixelinfo * typeName = buffer; } - // Undo relative scroll offset, but keep the 3 pixel padding - sint32 x = -w->widgets[WIDX_LIST].left; + const sint32 baseHeight = tileElement->base_height; + const sint32 clearanceHeight = tileElement->clearance_height; const bool ghost = (tileElement->flags & TILE_ELEMENT_FLAG_GHOST) != 0; const bool broken = (tileElement->flags & TILE_ELEMENT_FLAG_BROKEN) != 0; const bool last = (tileElement->flags & TILE_ELEMENT_FLAG_LAST_TILE) != 0; - gfx_clip_string(buffer, w->widgets[WIDX_COLUMN_TYPE].right - w->widgets[WIDX_COLUMN_TYPE].left - COL_X_TYPE); - gfx_draw_string(dpi, (char *)typeName, COLOUR_DARK_GREEN, x + COL_X_TYPE + 3, y); // 3px padding - gfx_draw_string_left(dpi, STR_FORMAT_INTEGER, &baseHeight, COLOUR_DARK_GREEN, x + COL_X_BH, y); - gfx_draw_string_left(dpi, STR_FORMAT_INTEGER, &clearanceHeight, COLOUR_DARK_GREEN, x + COL_X_CH, y); - if (ghost) gfx_draw_string(dpi, (char*)CheckBoxMarkString, w->colours[1], x + COL_X_GF, y); - if (broken) gfx_draw_string(dpi, (char*)CheckBoxMarkString, w->colours[1], x + COL_X_BF, y); - if (last) gfx_draw_string(dpi, (char*)CheckBoxMarkString, w->colours[1], x + COL_X_LF, y); + + const rct_string_id stringFormat = (selectedRow || hoveredRow) ? STR_WHITE_STRING : STR_WINDOW_COLOUR_2_STRINGID; + + // Undo relative scroll offset, but keep the 3 pixel padding + const sint32 x = -w->widgets[WIDX_LIST].left; + set_format_arg(0, rct_string_id, STR_STRING); + set_format_arg(2, char*, typeName); + gfx_draw_string_left(dpi, stringFormat, gCommonFormatArgs, COLOUR_BLACK, x + COL_X_TYPE + 3, y); // 3px padding + + // Base height + set_format_arg(0, rct_string_id, STR_FORMAT_INTEGER); + set_format_arg(2, sint32, baseHeight); + gfx_draw_string_left(dpi, stringFormat, gCommonFormatArgs, COLOUR_BLACK, x + COL_X_BH, y); + + // Clearance height + set_format_arg(0, rct_string_id, STR_FORMAT_INTEGER); + set_format_arg(2, sint32, clearanceHeight); + gfx_draw_string_left(dpi, stringFormat, gCommonFormatArgs, COLOUR_BLACK, x + COL_X_CH, y); + + // Checkmarks for ghost, broken en last for tile + set_format_arg(0, rct_string_id, STR_STRING); + set_format_arg(2, char*, CheckBoxMarkString); + if (ghost) + { + gfx_draw_string_left(dpi, stringFormat, gCommonFormatArgs, COLOUR_BLACK, x + COL_X_GF, y); + } + if (broken) + { + gfx_draw_string_left(dpi, stringFormat, gCommonFormatArgs, COLOUR_BLACK, x + COL_X_BF, y); + } + if (last) + { + gfx_draw_string_left(dpi, stringFormat, gCommonFormatArgs, COLOUR_BLACK, x + COL_X_LF, y); + } y -= LIST_ITEM_HEIGHT; i++; diff --git a/src/openrct2-ui/windows/Window.h b/src/openrct2-ui/windows/Window.h index 48bb188212..d91cee0fcf 100644 --- a/src/openrct2-ui/windows/Window.h +++ b/src/openrct2-ui/windows/Window.h @@ -163,8 +163,6 @@ rct_window * window_editor_bottom_toolbar_open(); rct_window * window_tile_inspector_open(); void window_tile_inspector_clear_clipboard(); -void window_tile_inspector_set_page(rct_window *w, TILE_INSPECTOR_PAGE page); -void window_tile_inspector_auto_set_buttons(rct_window *w); rct_window * window_editor_object_selection_open(); diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index 917094c80d..e60a163d96 100644 --- a/src/openrct2/network/Network.cpp +++ b/src/openrct2/network/Network.cpp @@ -34,7 +34,7 @@ // This string specifies which version of network stream current build uses. // It is used for making sure only compatible builds get connected, even within // single OpenRCT2 version. -#define NETWORK_STREAM_VERSION "15" +#define NETWORK_STREAM_VERSION "16" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION static rct_peep* _pickup_peep = nullptr; diff --git a/src/openrct2/windows/Intent.h b/src/openrct2/windows/Intent.h index 29bfd625bc..9762bbbfdb 100644 --- a/src/openrct2/windows/Intent.h +++ b/src/openrct2/windows/Intent.h @@ -89,8 +89,6 @@ enum INTENT_ACTION_INVALIDATE_TICKER_NEWS, INTENT_ACTION_REFRESH_GUEST_LIST, INTENT_ACTION_CLEAR_TILE_INSPECTOR_CLIPBOARD, - INTENT_ACTION_SET_TILE_INSPECTOR_PAGE, - INTENT_ACTION_SET_TILE_INSPECTOR_BUTTONS, INTENT_ACTION_REFRESH_STAFF_LIST, INTENT_ACTION_INVALIDATE_VEHICLE_WINDOW, INTENT_ACTION_UPDATE_CLIMATE, diff --git a/src/openrct2/world/TileInspector.cpp b/src/openrct2/world/TileInspector.cpp index 0ed79e9ce9..547156766a 100644 --- a/src/openrct2/world/TileInspector.cpp +++ b/src/openrct2/world/TileInspector.cpp @@ -38,19 +38,6 @@ uint32 windowTileInspectorTileX; uint32 windowTileInspectorTileY; sint32 windowTileInspectorElementCount = 0; -static void window_tile_inspector_set_page(const TILE_INSPECTOR_PAGE page) -{ - auto intent = Intent(INTENT_ACTION_SET_TILE_INSPECTOR_PAGE); - intent.putExtra(INTENT_EXTRA_PAGE, page); - context_broadcast_intent(&intent); -} - -static void window_tile_inspector_auto_set_buttons() -{ - auto intent = Intent(INTENT_ACTION_SET_TILE_INSPECTOR_BUTTONS); - context_broadcast_intent(&intent); -} - static bool map_swap_elements_at(sint32 x, sint32 y, sint16 first, sint16 second) { rct_tile_element * const firstElement = map_get_nth_element_at(x, y, first); @@ -145,12 +132,6 @@ sint32 tile_inspector_insert_corrupt_at(sint32 x, sint32 y, sint16 elementIndex, tileInspectorWindow->selected_list_item++; } - if (tileInspectorWindow->selected_list_item == elementIndex) - { - window_tile_inspector_set_page(TILE_INSPECTOR_PAGE_CORRUPT); - } - - window_tile_inspector_auto_set_buttons(); window_invalidate(tileInspectorWindow); } } @@ -190,10 +171,8 @@ sint32 tile_inspector_remove_element_at(sint32 x, sint32 y, sint16 elementIndex, else if (tileInspectorWindow->selected_list_item == elementIndex) { tileInspectorWindow->selected_list_item = -1; - window_tile_inspector_set_page(TILE_INSPECTOR_PAGE_DEFAULT); } - window_tile_inspector_auto_set_buttons(); window_invalidate(tileInspectorWindow); } } @@ -221,7 +200,6 @@ sint32 tile_inspector_swap_elements_at(sint32 x, sint32 y, sint16 first, sint16 else if (tileInspectorWindow->selected_list_item == second) tileInspectorWindow->selected_list_item = first; - window_tile_inspector_auto_set_buttons(); window_invalidate(tileInspectorWindow); } } @@ -374,7 +352,6 @@ sint32 tile_inspector_paste_element_at(sint32 x, sint32 y, rct_tile_element elem else if (tileInspectorWindow->selected_list_item >= newIndex) tileInspectorWindow->selected_list_item++; - window_tile_inspector_auto_set_buttons(); window_invalidate(tileInspectorWindow); } } @@ -429,9 +406,7 @@ sint32 tile_inspector_sort_elements_at(sint32 x, sint32 y, sint32 flags) rct_window * const tileInspectorWindow = window_find_by_class(WC_TILE_INSPECTOR); if (tileInspectorWindow != nullptr && (uint32)x == windowTileInspectorTileX && (uint32)y == windowTileInspectorTileY) { - window_tile_inspector_set_page(TILE_INSPECTOR_PAGE_DEFAULT); tileInspectorWindow->selected_list_item = -1; - window_tile_inspector_auto_set_buttons(); window_invalidate(tileInspectorWindow); } }