Make rail building tools invert remove mode when buttons are fn-clicked

This commit is contained in:
dP
2020-07-13 21:44:31 +03:00
parent 7441767ed8
commit 495192890a
3 changed files with 136 additions and 8 deletions

View File

@@ -3,12 +3,28 @@
#include "cm_hotkeys.hpp"
#include "cm_settings.hpp"
#include "../newgrf_station.h"
#include "../settings_type.h"
#include "../sound_func.h"
#include "../tilehighlight_func.h"
#include "../viewport_func.h"
#include "../window_func.h"
#include "../window_gui.h"
#include "../window_type.h"
#include "../widgets/rail_widget.h"
#include "../safeguards.h"
struct RailStationGUISettings {
Axis orientation; ///< Currently selected rail station orientation
bool newstations; ///< Are custom station definitions available?
StationClassID station_class; ///< Currently selected custom station class (if newstations is \c true )
byte station_type; ///< %Station type within the currently selected custom station class (if newstations is \c true )
byte station_count; ///< Number of custom stations (if newstations is \c true )
};
extern RailStationGUISettings _railstation; ///< Settings of the station builder GUI
namespace citymania {
bool _fn_mod = false;
@@ -40,4 +56,93 @@ void UpdateModKeys(bool shift_pressed, bool ctrl_pressed, bool alt_pressed) {
}
}
bool HasSeparateRemoveMod() {
return (_settings_client.gui.cm_fn_mod != _settings_client.gui.cm_remove_mod);
}
ToolRemoveMode RailToolbar_GetRemoveMode(int widget) {
switch(widget) {
case WID_RAT_BUILD_NS:
case WID_RAT_BUILD_X:
case WID_RAT_BUILD_EW:
case WID_RAT_BUILD_Y:
case WID_RAT_AUTORAIL:
case WID_RAT_POLYRAIL:
return ToolRemoveMode::MOD;
case WID_RAT_BUILD_WAYPOINT:
case WID_RAT_BUILD_STATION:
case WID_RAT_BUILD_SIGNALS:
return HasSeparateRemoveMod() ? ToolRemoveMode::MOD : ToolRemoveMode::BUTTON;
default:
return ToolRemoveMode::NONE;
}
}
bool RailToolbar_IsRemoveInverted(int widget) {
return (RailToolbar_GetRemoveMode(widget) != ToolRemoveMode::NONE && citymania::_fn_mod);
}
void RailToolbar_UpdateRemoveWidgetStatus(Window *w, int widget, bool remove_active) {
if (widget == WID_RAT_REMOVE) return;
if (RailToolbar_GetRemoveMode(widget) == citymania::ToolRemoveMode::NONE || !w->IsWidgetLowered(widget)) {
w->DisableWidget(WID_RAT_REMOVE);
w->RaiseWidget(WID_RAT_REMOVE);
} else {
w->EnableWidget(WID_RAT_REMOVE);
w->SetWidgetLoweredState(WID_RAT_REMOVE, remove_active);
SetSelectionRed(remove_active);
}
w->SetWidgetDirty(WID_RAT_REMOVE);
/* handle station builder */
if (w->IsWidgetLowered(WID_RAT_BUILD_STATION)) {
if (remove_active) {
/* starting drag & drop remove */
if (!_settings_client.gui.station_dragdrop) {
SetTileSelectSize(1, 1);
} else {
VpSetPlaceSizingLimit(-1);
}
} else {
/* starting station build mode */
if (!_settings_client.gui.station_dragdrop) {
int x = _settings_client.gui.station_numtracks;
int y = _settings_client.gui.station_platlength;
if (_railstation.orientation == 0) Swap(x, y);
SetTileSelectSize(x, y);
} else {
VpSetPlaceSizingLimit(_settings_game.station.station_spread);
}
}
}
}
bool RailToolbar_RemoveModChanged(Window *w, bool invert_remove, bool remove_active, bool button_clicked) {
if (w->IsWidgetDisabled(WID_RAT_REMOVE)) return false;
DeleteWindowById(WC_SELECT_STATION, 0);
for (uint i = WID_RAT_BUILD_NS; i <= WID_RAT_BUILD_TUNNEL; i++) {
if (w->IsWidgetLowered(i)) {
auto old_active = remove_active;
switch (RailToolbar_GetRemoveMode(i)) {
case ToolRemoveMode::BUTTON:
if (button_clicked) remove_active = !w->IsWidgetLowered(WID_RAT_REMOVE);
break;
case ToolRemoveMode::MOD:
if (_remove_mod || !button_clicked) remove_active = (_remove_mod != invert_remove);
else remove_active = !w->IsWidgetLowered(WID_RAT_REMOVE);
break;
default:
break;
}
if (old_active != remove_active) RailToolbar_UpdateRemoveWidgetStatus(w, i, remove_active);
return remove_active;
}
}
return remove_active;
}
} // namespace citymania

View File

@@ -1,14 +1,26 @@
#ifndef CMEXT_HOTKEYS_HPP
#define CMEXT_HOTKEYS_HPP
#include "../window_type.h"
namespace citymania {
extern bool _fn_mod;
extern bool _estimate_mod;
extern bool _remove_mod;
enum class ToolRemoveMode : uint8 {
NONE = 0,
BUTTON = 1,
MOD = 2,
};
void UpdateModKeys(bool shift_pressed, bool ctrl_pressed, bool alt_pressed);
bool RailToolbar_IsRemoveInverted(int widget);
void RailToolbar_UpdateRemoveWidgetStatus(Window *w, int widged, bool remove_active);
bool RailToolbar_RemoveModChanged(Window *w, bool invert_remove, bool remove_active, bool button_clicked);
} // namespace citymania
#endif

View File

@@ -46,6 +46,7 @@
RailType _cur_railtype; ///< Rail type of the current build-rail toolbar.
static bool _remove_button_clicked; ///< Flag whether 'remove' toggle-button is currently enabled
static bool _cm_invert_remove; ///< Invert remove mode on tools (when fn-clicked)
static DiagDirection _build_depot_direction; ///< Currently selected depot direction
static byte _waypoint_count = 1; ///< Number of waypoint types
static byte _cur_waypoint_type; ///< Currently selected waypoint type
@@ -58,6 +59,7 @@ extern TileIndex _rail_track_endtile; // rail_cmd.cpp
/* Map the setting: default_signal_type to the corresponding signal type */
static const SignalType _default_signal_type[] = {SIGTYPE_NORMAL, SIGTYPE_PBS, SIGTYPE_PBS_ONEWAY};
static const int HOTKEY_MASK = 0x1000;
static const int HOTKEY_POLYRAIL = 0x1000;
static const int HOTKEY_NEW_POLYRAIL = 0x1001;
static const int HOTKEY_BUILD_STATION_SIZED = 0x1010; ///< Build a station in fixed size mode.
@@ -646,9 +648,7 @@ struct BuildRailToolbarWindow : Window {
void OnClick(Point pt, int widget, int click_count) override
{
if (widget < WID_RAT_BUILD_NS) return;
bool remove_on_ctrl = true; /* do not check ctrl for hotkeys */
_remove_button_clicked = false;
switch (widget) {
case WID_RAT_BUILD_NS:
HandlePlacePushButton(this, WID_RAT_BUILD_NS, GetRailTypeInfo(_cur_railtype)->cursor.rail_ns, HT_LINE | HT_DIR_VL);
@@ -740,7 +740,6 @@ struct BuildRailToolbarWindow : Window {
ShowStationBuilder(this);
}
this->last_user_action = WID_RAT_BUILD_STATION;
remove_on_ctrl = false;
} else { /* button */
if (HandlePlacePushButton(this, WID_RAT_BUILD_STATION, SPR_CURSOR_RAIL_STATION, HT_RECT)) {
ShowStationBuilder(this);
@@ -770,7 +769,8 @@ struct BuildRailToolbarWindow : Window {
break;
case WID_RAT_REMOVE:
BuildRailClick_Remove(this);
_remove_button_clicked = citymania::RailToolbar_RemoveModChanged(this, _cm_invert_remove, _remove_button_clicked, true);
// BuildRailClick_Remove(this);
break;
case WID_RAT_CONVERT_RAIL:
@@ -780,8 +780,16 @@ struct BuildRailToolbarWindow : Window {
default: NOT_REACHED();
}
this->UpdateRemoveWidgetStatus(widget);
if (citymania::_remove_mod && remove_on_ctrl) RailToolbar_CtrlChanged(this);
bool is_hotkey = (pt.x == 0 && pt.y == 0);
if (widget != WID_RAT_REMOVE) {
_cm_invert_remove = (!is_hotkey && citymania::RailToolbar_IsRemoveInverted(widget));
_remove_button_clicked = _cm_invert_remove;
}
citymania::RailToolbar_UpdateRemoveWidgetStatus(this, widget, _remove_button_clicked);
// this->UpdateRemoveWidgetStatus(widget);
// if (_ctrl_pressed) RailToolbar_CtrlChanged(this);
}
EventState OnHotkey(int hotkey) override
@@ -962,8 +970,11 @@ struct BuildRailToolbarWindow : Window {
EventState CM_OnRemoveModStateChange() override
{
/* do not toggle Remove button by Ctrl when placing station */
if (!this->IsWidgetLowered(WID_RAT_BUILD_STATION) && !this->IsWidgetLowered(WID_RAT_BUILD_WAYPOINT) && RailToolbar_CtrlChanged(this)) return ES_HANDLED;
auto new_remove = citymania::RailToolbar_RemoveModChanged(this, _cm_invert_remove, _remove_button_clicked, false);
if (new_remove != _remove_button_clicked) {
_remove_button_clicked = new_remove;
return ES_HANDLED;
}
return ES_NOT_HANDLED;
}