Add hotkey to rotate depot while building, default to middle mouse button (SDL2 only for now)

This commit is contained in:
dP
2021-01-27 01:13:37 +03:00
parent 9b6d667a54
commit 363cfa7e8c
9 changed files with 94 additions and 30 deletions

View File

@@ -14,6 +14,7 @@
#include "../town_kdtree.h" #include "../town_kdtree.h"
#include "../tilearea_type.h" #include "../tilearea_type.h"
#include "../tilehighlight_type.h" #include "../tilehighlight_type.h"
#include "../tilehighlight_func.h"
#include "../viewport_func.h" #include "../viewport_func.h"
#include "../zoning.h" #include "../zoning.h"
#include "../table/track_land.h" #include "../table/track_land.h"
@@ -608,6 +609,38 @@ DiagDirection AutodetectRailObjectDirection(TileIndex tile, Point pt) {
NOT_REACHED(); NOT_REACHED();
} }
TileIndex _autodetection_tile = INVALID_TILE;
DiagDirDiff _autodetection_rotation = DIAGDIRDIFF_SAME;
static DiagDirDiff GetAutodetectionRotation() {
auto pt = GetTileBelowCursor();
auto tile = TileVirtXY(pt.x, pt.y);
if (tile != _autodetection_tile) {
_autodetection_tile = tile;
_autodetection_rotation = DIAGDIRDIFF_SAME;
}
return _autodetection_rotation;
}
void RotateAutodetection() {
auto rotation = GetAutodetectionRotation();
if (rotation == DIAGDIRDIFF_90LEFT) rotation = DIAGDIRDIFF_SAME;
else rotation++;
_autodetection_rotation = rotation;
::UpdateTileSelection();
}
void ResetRotateAutodetection() {
_autodetection_tile = INVALID_TILE;
_autodetection_rotation = DIAGDIRDIFF_SAME;
}
DiagDirection AddAutodetectionRotation(DiagDirection ddir) {
return ChangeDiagDir(ddir, GetAutodetectionRotation());
}
HighLightStyle UpdateTileSelection(HighLightStyle new_drawstyle) { HighLightStyle UpdateTileSelection(HighLightStyle new_drawstyle) {
_thd.cm_new = ObjectHighlight(ObjectHighlight::Type::NONE); _thd.cm_new = ObjectHighlight(ObjectHighlight::Type::NONE);
if ((_thd.place_mode & HT_DRAG_MASK) == HT_RECT && if ((_thd.place_mode & HT_DRAG_MASK) == HT_RECT &&
@@ -616,8 +649,9 @@ HighLightStyle UpdateTileSelection(HighLightStyle new_drawstyle) {
auto pt = GetTileBelowCursor(); auto pt = GetTileBelowCursor();
auto tile = TileVirtXY(pt.x, pt.y); auto tile = TileVirtXY(pt.x, pt.y);
if (pt.x != -1) { if (pt.x != -1) {
if (dir >= DiagDirection::DIAGDIR_END) if (dir >= DiagDirection::DIAGDIR_END) {
dir = AutodetectRailObjectDirection(tile, pt); dir = AddAutodetectionRotation(AutodetectRailObjectDirection(tile, pt));
}
_thd.cm_new = ObjectHighlight::make_depot(tile, dir); _thd.cm_new = ObjectHighlight::make_depot(tile, dir);
} }
new_drawstyle = HT_RECT; new_drawstyle = HT_RECT;

View File

@@ -95,6 +95,9 @@ void SetIndustryForbiddenTilesHighlight(IndustryType type);
PaletteID GetTreeShadePal(TileIndex tile); PaletteID GetTreeShadePal(TileIndex tile);
void RotateAutodetection();
void ResetRotateAutodetection();
} // namespace citymania } // namespace citymania
#endif #endif

View File

@@ -40,7 +40,6 @@ public:
RAIL_DEPOT = 1, RAIL_DEPOT = 1,
}; };
protected:
Type type; Type type;
union { union {
struct { struct {
@@ -49,6 +48,7 @@ protected:
} depot; } depot;
} u; } u;
protected:
bool tiles_updated = false; bool tiles_updated = false;
std::multimap<TileIndex, ObjectTileHighlight> tiles; std::multimap<TileIndex, ObjectTileHighlight> tiles;
void UpdateTiles(); void UpdateTiles();

View File

@@ -35,6 +35,9 @@ bool _fn_mod = false;
bool _remove_mod = false; bool _remove_mod = false;
bool _estimate_mod = false; bool _estimate_mod = false;
bool _middle_button_down; ///< Is middle mouse button pressed?
bool _middle_button_clicked; ///< Is middle mouse button clicked?
uint32 _effective_actions = 0; uint32 _effective_actions = 0;
uint32 _first_effective_tick = 0; uint32 _first_effective_tick = 0;
std::queue<uint32> _last_actions; std::queue<uint32> _last_actions;

View File

@@ -105,13 +105,15 @@ enum WindowKeyCodes {
WKC_L_BRACE = 154, ///< { Left brace WKC_L_BRACE = 154, ///< { Left brace
WKC_R_BRACE = 155, ///< } Right brace WKC_R_BRACE = 155, ///< } Right brace
WKC_L_PAREN = 157, ///< ( Left parentheses WKC_L_PAREN = 157, ///< ( Left parentheses
WKC_R_PAREN = 158, ///< ) Right parentheses WKC_R_PAREN = 158, ///< ) Right parentheses
WKC_PLUS = 159, ///< + Plus WKC_PLUS = 159, ///< + Plus
WKC_EXCLAIM = 160, ///< ! Exclamation mark WKC_EXCLAIM = 160, ///< ! Exclamation mark
WKC_ASTERISK = 161, ///< * Asterisk WKC_ASTERISK = 161, ///< * Asterisk
WKC_DOLLAR = 162, ///< $ Dollar sign WKC_DOLLAR = 162, ///< $ Dollar sign
CM_WKC_MOUSE_MIDDLE = 255, ///< CityMania special code for middle mouse button
}; };
/** A single sprite of a list of animated cursors */ /** A single sprite of a list of animated cursors */

View File

@@ -85,6 +85,7 @@ static const KeycodeNames _keycode_to_name[] = {
{"R_PAREN", WKC_R_PAREN}, {"R_PAREN", WKC_R_PAREN},
{"EXCLAIM", WKC_EXCLAIM}, {"EXCLAIM", WKC_EXCLAIM},
{"ASTERISK", WKC_ASTERISK}, {"ASTERISK", WKC_ASTERISK},
{"MOUSE_MIDDLE", CM_WKC_MOUSE_MIDDLE},
}; };
/** /**

View File

@@ -39,6 +39,7 @@
#include "widgets/rail_widget.h" #include "widgets/rail_widget.h"
#include "citymania/cm_hotkeys.hpp" #include "citymania/cm_hotkeys.hpp"
#include "citymania/cm_highlight.hpp"
#include "citymania/cm_station_gui.hpp" #include "citymania/cm_station_gui.hpp"
#include "safeguards.h" #include "safeguards.h"
@@ -503,30 +504,6 @@ RoadBits FindRailsToConnect(TileIndex tile) {
return passing; return passing;
} }
/*
* Selects orientation for rail object (depot)
*/
DiagDirection AutodetectRailObjectDirection(TileIndex tile) {
RoadBits bits = FindRailsToConnect(tile);
// FIXME after this point repeats road autodetection
if (HasExactlyOneBit(bits)) return RoadBitsToDiagDir(bits);
if (bits == ROAD_NONE) bits = ROAD_ALL;
RoadBits frac_bits = DiagDirToRoadBits(TileFractCoordsToDiagDir());
if (HasExactlyOneBit(frac_bits & bits)) {
return RoadBitsToDiagDir(frac_bits & bits);
}
frac_bits |= MirrorRoadBits(frac_bits);
if (HasExactlyOneBit(frac_bits & bits)) {
return RoadBitsToDiagDir(frac_bits & bits);
}
for (DiagDirection ddir = DIAGDIR_BEGIN; ddir < DIAGDIR_END; ddir++) {
if (DiagDirToRoadBits(ddir) & bits) {
return ddir;
}
}
NOT_REACHED();
}
/** Rail toolbar management class. */ /** Rail toolbar management class. */
struct BuildRailToolbarWindow : Window { struct BuildRailToolbarWindow : Window {
RailType railtype; ///< Rail type to build. RailType railtype; ///< Rail type to build.
@@ -714,6 +691,7 @@ struct BuildRailToolbarWindow : Window {
case WID_RAT_BUILD_DEPOT: case WID_RAT_BUILD_DEPOT:
if (HandlePlacePushButton(this, WID_RAT_BUILD_DEPOT, GetRailTypeInfo(_cur_railtype)->cursor.depot, HT_RECT | (HighLightStyle)_build_depot_direction)) { if (HandlePlacePushButton(this, WID_RAT_BUILD_DEPOT, GetRailTypeInfo(_cur_railtype)->cursor.depot, HT_RECT | (HighLightStyle)_build_depot_direction)) {
citymania::ResetRotateAutodetection();
ShowBuildTrainDepotPicker(this); ShowBuildTrainDepotPicker(this);
this->last_user_action = widget; this->last_user_action = widget;
} }
@@ -846,7 +824,8 @@ struct BuildRailToolbarWindow : Window {
case WID_RAT_BUILD_DEPOT: case WID_RAT_BUILD_DEPOT:
ddir = _build_depot_direction; ddir = _build_depot_direction;
if (ddir == DIAGDIR_NW + 1) { if (ddir == DIAGDIR_NW + 1) {
ddir = AutodetectRailObjectDirection(tile); assert(_thd.cm.type == citymania::ObjectHighlight::Type::RAIL_DEPOT);
ddir = _thd.cm.u.depot.ddir;
} }
DoCommandP(tile, _cur_railtype, ddir, DoCommandP(tile, _cur_railtype, ddir,
CMD_BUILD_TRAIN_DEPOT | CMD_MSG(STR_ERROR_CAN_T_BUILD_TRAIN_DEPOT), CMD_BUILD_TRAIN_DEPOT | CMD_MSG(STR_ERROR_CAN_T_BUILD_TRAIN_DEPOT),
@@ -1924,6 +1903,10 @@ static void ShowSignalBuilder(Window *parent)
new BuildSignalWindow(&_signal_builder_desc, parent); new BuildSignalWindow(&_signal_builder_desc, parent);
} }
enum class BuildRailDepotWindowHotkey : int {
ROTATE,
};
struct BuildRailDepotWindow : public PickerWindowBase { struct BuildRailDepotWindow : public PickerWindowBase {
BuildRailDepotWindow(WindowDesc *desc, Window *parent) : PickerWindowBase(desc, parent) BuildRailDepotWindow(WindowDesc *desc, Window *parent) : PickerWindowBase(desc, parent)
{ {
@@ -1971,8 +1954,40 @@ struct BuildRailDepotWindow : public PickerWindowBase {
break; break;
} }
} }
EventState OnHotkey(int hotkey) override
{
switch ((BuildRailDepotWindowHotkey)hotkey) {
/* Indicate to the OnClick that the action comes from a hotkey rather
* then from a click and that the CTRL state should be ignored. */
case BuildRailDepotWindowHotkey::ROTATE:
if (_build_depot_direction < DIAGDIR_END) {
this->RaiseWidget(_build_depot_direction + WID_BRAD_DEPOT_NE);
_build_depot_direction = ChangeDiagDir(_build_depot_direction, DIAGDIRDIFF_90RIGHT);
this->LowerWidget(_build_depot_direction + WID_BRAD_DEPOT_NE);
} else {
citymania::RotateAutodetection();
}
this->SetDirty();
return ES_HANDLED;
default:
return ES_NOT_HANDLED;
}
return ES_NOT_HANDLED;
}
static HotkeyList hotkeys;
}; };
static Hotkey build_depot_hotkeys[] = {
Hotkey(CM_WKC_MOUSE_MIDDLE, "rotate", (int)BuildRailDepotWindowHotkey::ROTATE),
HOTKEY_LIST_END
};
HotkeyList BuildRailDepotWindow::hotkeys("cm_build_depot", build_depot_hotkeys);
/** Nested widget definition of the build rail depot window */ /** Nested widget definition of the build rail depot window */
static const NWidgetPart _nested_build_depot_widgets[] = { static const NWidgetPart _nested_build_depot_widgets[] = {
NWidget(NWID_HORIZONTAL), NWidget(NWID_HORIZONTAL),
@@ -2014,7 +2029,8 @@ static WindowDesc _build_depot_desc(
WDP_AUTO, nullptr, 0, 0, WDP_AUTO, nullptr, 0, 0,
WC_BUILD_DEPOT, WC_BUILD_TOOLBAR, WC_BUILD_DEPOT, WC_BUILD_TOOLBAR,
WDF_CONSTRUCTION, WDF_CONSTRUCTION,
_nested_build_depot_widgets, lengthof(_nested_build_depot_widgets) _nested_build_depot_widgets, lengthof(_nested_build_depot_widgets),
&BuildRailDepotWindow::hotkeys
); );
static void ShowBuildTrainDepotPicker(Window *parent) static void ShowBuildTrainDepotPicker(Window *parent)

View File

@@ -544,6 +544,10 @@ int VideoDriver_SDL::PollEvent()
break; break;
case SDL_MOUSEBUTTONUP: case SDL_MOUSEBUTTONUP:
if (ev.button.button == SDL_BUTTON_MIDDLE) {
HandleKeypress(CM_WKC_MOUSE_MIDDLE, 0);
break;
}
if (_rightclick_emulate) { if (_rightclick_emulate) {
_right_button_down = false; _right_button_down = false;
_left_button_down = false; _left_button_down = false;

View File

@@ -2974,6 +2974,7 @@ static void MouseLoop(MouseClick click, int mousewheel)
case MC_HOVER: case MC_HOVER:
DispatchHoverEvent(w, x - w->left, y - w->top); DispatchHoverEvent(w, x - w->left, y - w->top);
break; break;
} }
} }