Add hotkey to rotate depot while building, default to middle mouse button (SDL2 only for now)
This commit is contained in:
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|||||||
@@ -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},
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user