From 914cc0fe96f098d9945687f1ce39d3a38bde166c Mon Sep 17 00:00:00 2001 From: J0anJosep Date: Wed, 31 Mar 2021 23:20:44 +0200 Subject: [PATCH] Add: Add new viewport place methods for rectangles with one side with a fixed length. --- src/tilehighlight_func.h | 2 ++ src/tilehighlight_type.h | 5 +++-- src/viewport.cpp | 29 +++++++++++++++++++++++------ src/viewport_type.h | 2 ++ 4 files changed, 30 insertions(+), 8 deletions(-) diff --git a/src/tilehighlight_func.h b/src/tilehighlight_func.h index 572c5bd43e..770013bc59 100644 --- a/src/tilehighlight_func.h +++ b/src/tilehighlight_func.h @@ -26,6 +26,8 @@ void VpStartDragging(ViewportDragDropSelectionProcess process); void VpStartPlaceSizing(TileIndex tile, ViewportPlaceMethod method, ViewportDragDropSelectionProcess process); void VpSetPresizeRange(TileIndex from, TileIndex to); void VpSetPlaceSizingLimit(int limit); +void VpSetPlaceFixedSize(uint8_t fixed_size); +void VpResetFixedSize(); void UpdateTileSelection(); diff --git a/src/tilehighlight_type.h b/src/tilehighlight_type.h index a19eef5aac..a7a43d179e 100644 --- a/src/tilehighlight_type.h +++ b/src/tilehighlight_type.h @@ -55,11 +55,12 @@ struct TileHighlightData { Point new_pos; ///< New value for \a pos; used to determine whether to redraw the selection. Point new_size; ///< New value for \a size; used to determine whether to redraw the selection. Point new_outersize; ///< New value for \a outersize; used to determine whether to redraw the selection. - uint8_t dirty; ///< Whether the build station window needs to redraw due to the changed selection. + uint8_t dirty; ///< Whether the build station window needs to redraw due to the changed selection. Point selstart; ///< The location where the dragging started. Point selend; ///< The location where the drag currently ends. - uint8_t sizelimit; ///< Whether the selection is limited in length, and what the maximum length is. + uint8_t sizelimit; ///< Whether the selection is limited in length, and what the maximum length is. + uint8_t fixed_size; ///< The fixed length for one of the sides. HighLightStyle drawstyle; ///< Lower bits 0-3 are reserved for detailed highlight information. HighLightStyle next_drawstyle; ///< Queued, but not yet drawn style. diff --git a/src/viewport.cpp b/src/viewport.cpp index fbe06c45e3..5e60dae16a 100644 --- a/src/viewport.cpp +++ b/src/viewport.cpp @@ -2680,6 +2680,8 @@ void UpdateTileSelection() } _thd.new_pos.x = x1 & ~TILE_UNIT_MASK; _thd.new_pos.y = y1 & ~TILE_UNIT_MASK; + if (_thd.select_method == VPM_LIMITED_X_FIXED_Y) _thd.new_size.y = (TILE_SIZE * _thd.fixed_size) & ~TILE_UNIT_MASK; + if (_thd.select_method == VPM_LIMITED_Y_FIXED_X) _thd.new_size.x = (TILE_SIZE * _thd.fixed_size) & ~TILE_UNIT_MASK; } } @@ -2772,6 +2774,15 @@ void VpSetPlaceSizingLimit(int limit) _thd.sizelimit = limit; } +void VpSetPlaceFixedSize(uint8_t fixed) +{ + _thd.fixed_size = fixed; +} + +void VpResetFixedSize() { + VpSetPlaceFixedSize(1); +} + /** * Highlights all tiles between a set of two tiles. Used in dock and tunnel placement * @param from TileIndex of the first tile to highlight @@ -3243,7 +3254,7 @@ void VpSelectTilesWithMethod(int x, int y, ViewportPlaceMethod method) sx = _thd.selstart.x; sy = _thd.selstart.y; - int limit = 0; + int limit = -1; switch (method) { case VPM_X_OR_Y: // drag in X or Y direction @@ -3256,28 +3267,33 @@ void VpSelectTilesWithMethod(int x, int y, ViewportPlaceMethod method) } goto calc_heightdiff_single_direction; + case VPM_LIMITED_Y_FIXED_X: case VPM_X_LIMITED: // Drag in X direction (limited size). limit = (_thd.sizelimit - 1) * TILE_SIZE; [[fallthrough]]; case VPM_FIX_X: // drag in Y direction - x = sx; + x = sx + (method == VPM_LIMITED_Y_FIXED_X ? (TILE_SIZE * (_thd.fixed_size - 1)) : 0) ; style = HT_DIR_Y; goto calc_heightdiff_single_direction; + case VPM_LIMITED_X_FIXED_Y: case VPM_Y_LIMITED: // Drag in Y direction (limited size). limit = (_thd.sizelimit - 1) * TILE_SIZE; [[fallthrough]]; case VPM_FIX_Y: // drag in X direction - y = sy; + y = sy + (method == VPM_LIMITED_X_FIXED_Y ? (TILE_SIZE * (_thd.fixed_size - 1)) : 0) ; style = HT_DIR_X; calc_heightdiff_single_direction:; - if (limit > 0) { - x = sx + Clamp(x - sx, -limit, limit); - y = sy + Clamp(y - sy, -limit, limit); + if (limit >= 0) { + if (method != VPM_LIMITED_X_FIXED_Y) y = sy + Clamp(y - sy, -limit, limit); + if (method != VPM_LIMITED_Y_FIXED_X) x = sx + Clamp(x - sx, -limit, limit); } + + if (method == VPM_LIMITED_Y_FIXED_X || method == VPM_LIMITED_X_FIXED_Y) goto measure_area; + if (_settings_client.gui.measure_tooltip) { TileIndex t0 = TileVirtXY(sx, sy); TileIndex t1 = TileVirtXY(x, y); @@ -3307,6 +3323,7 @@ calc_heightdiff_single_direction:; [[fallthrough]]; case VPM_X_AND_Y: // drag an X by Y area +measure_area: if (_settings_client.gui.measure_tooltip) { static const StringID measure_strings_area[] = { STR_NULL, STR_NULL, STR_MEASURE_AREA, STR_MEASURE_AREA_HEIGHTDIFF diff --git a/src/viewport_type.h b/src/viewport_type.h index 0fde051f38..b026650db9 100644 --- a/src/viewport_type.h +++ b/src/viewport_type.h @@ -99,6 +99,8 @@ enum ViewportPlaceMethod { VPM_FIX_VERTICAL = 6, ///< drag only in vertical direction VPM_X_LIMITED = 7, ///< Drag only in X axis with limited size VPM_Y_LIMITED = 8, ///< Drag only in Y axis with limited size + VPM_LIMITED_Y_FIXED_X = 9, ///< Drag only in Y axis with limited size and a fixed value for x + VPM_LIMITED_X_FIXED_Y = 10, ///< Drag only in X axis with limited size and a fixed value for y VPM_RAILDIRS = 0x40, ///< all rail directions VPM_SIGNALDIRS = 0x80, ///< similar to VMP_RAILDIRS, but with different cursor };