summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/gfx_func.h1
-rw-r--r--src/rail_gui.cpp58
-rw-r--r--src/road_gui.cpp42
-rw-r--r--src/video/cocoa/event.mm4
-rw-r--r--src/video/sdl_v.cpp5
-rw-r--r--src/video/win32_v.cpp5
-rw-r--r--src/window.cpp15
-rw-r--r--src/window_gui.h5
8 files changed, 120 insertions, 15 deletions
diff --git a/src/gfx_func.h b/src/gfx_func.h
index 4a85860f2..e97d33e8e 100644
--- a/src/gfx_func.h
+++ b/src/gfx_func.h
@@ -65,6 +65,7 @@ extern uint16 _cur_resolution[2];
extern Colour _cur_palette[256];
void HandleKeypress(uint32 key);
+void HandleCtrlChanged();
void HandleMouseEvents();
void CSleep(int milliseconds);
void UpdateWindows();
diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp
index 8bfc5717c..9f14efe3d 100644
--- a/src/rail_gui.cpp
+++ b/src/rail_gui.cpp
@@ -76,7 +76,7 @@ void CcPlaySound1E(bool success, TileIndex tile, uint32 p1, uint32 p2)
static void GenericPlaceRail(TileIndex tile, int cmd)
{
DoCommandP(tile, _cur_railtype, cmd, CcPlaySound1E,
- (_remove_button_clicked || _ctrl_pressed) ?
+ _remove_button_clicked ?
CMD_REMOVE_SINGLE_RAIL | CMD_MSG(STR_1012_CAN_T_REMOVE_RAILROAD_TRACK) | CMD_NO_WATER :
CMD_BUILD_SINGLE_RAIL | CMD_MSG(STR_1011_CAN_T_BUILD_RAILROAD_TRACK) | CMD_NO_WATER
);
@@ -277,6 +277,43 @@ enum RailToolbarWidgets {
RTW_CONVERT_RAIL,
};
+
+/** Toogles state of the Remove button of Build rail toolbar
+ * @param w window the button belongs to
+ */
+static void ToggleRailButton_Remove(Window *w)
+{
+ w->ToggleWidgetLoweredState(RTW_REMOVE);
+ w->InvalidateWidget(RTW_REMOVE);
+ _remove_button_clicked = w->IsWidgetLowered(RTW_REMOVE);
+ SetSelectionRed(_remove_button_clicked);
+
+ // handle station builder
+ if (_remove_button_clicked) {
+ SetTileSelectSize(1, 1);
+ }
+}
+
+/** Updates the Remove button because of Ctrl state change
+ * @param w window the button belongs to
+ * @return true iff the remove buton was changed
+ */
+static bool RailToolbar_CtrlChanged(Window *w)
+{
+ if (w->IsWidgetDisabled(RTW_REMOVE)) return false;
+
+ /* allow ctrl to switch remove mode only for these widgets */
+ for (uint i = RTW_BUILD_NS; i <= RTW_BUILD_WAYPOINT; i++) {
+ if ((i <= RTW_AUTORAIL || i == RTW_BUILD_WAYPOINT) && w->IsWidgetLowered(i)) {
+ ToggleRailButton_Remove(w);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
static void BuildRailClick_N(Window *w)
{
HandlePlacePushButton(w, RTW_BUILD_NS, GetRailTypeInfo(_cur_railtype)->cursor.rail_ns, VHM_RECT, PlaceRail_N);
@@ -351,17 +388,8 @@ static void BuildRailClick_Tunnel(Window *w)
static void BuildRailClick_Remove(Window *w)
{
if (w->IsWidgetDisabled(RTW_REMOVE)) return;
- SetWindowDirty(w);
+ ToggleRailButton_Remove(w);
SndPlayFx(SND_15_BEEP);
-
- w->ToggleWidgetLoweredState(RTW_REMOVE);
- _remove_button_clicked = w->IsWidgetLowered(RTW_REMOVE);
- SetSelectionRed(_remove_button_clicked);
-
- // handle station builder
- if (_remove_button_clicked) {
- SetTileSelectSize(1, 1);
- }
}
static void BuildRailClick_Convert(Window *w)
@@ -373,7 +401,7 @@ static void BuildRailClick_Convert(Window *w)
static void DoRailroadTrack(int mode)
{
DoCommandP(TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y), _cur_railtype | (mode << 4), NULL,
- (_remove_button_clicked || _ctrl_pressed) ?
+ _remove_button_clicked ?
CMD_REMOVE_RAILROAD_TRACK | CMD_NO_WATER | CMD_MSG(STR_1012_CAN_T_REMOVE_RAILROAD_TRACK) :
CMD_BUILD_RAILROAD_TRACK | CMD_NO_WATER | CMD_MSG(STR_1011_CAN_T_BUILD_RAILROAD_TRACK)
);
@@ -514,6 +542,7 @@ static void BuildRailToolbWndProc(Window *w, WindowEvent *e)
_build_railroad_button_proc[e->we.click.widget - RTW_BUILD_NS](w);
}
UpdateRemoveWidgetStatus(w, e->we.click.widget);
+ if (_ctrl_pressed) RailToolbar_CtrlChanged(w);
break;
case WE_KEYPRESS:
@@ -523,6 +552,7 @@ static void BuildRailToolbWndProc(Window *w, WindowEvent *e)
_remove_button_clicked = false;
_build_railroad_button_proc[i](w);
UpdateRemoveWidgetStatus(w, i + RTW_BUILD_NS);
+ if (_ctrl_pressed) RailToolbar_CtrlChanged(w);
break;
}
}
@@ -607,6 +637,10 @@ static void BuildRailToolbWndProc(Window *w, WindowEvent *e)
case WE_DESTROY:
if (_patches.link_terraform_toolbar) DeleteWindowById(WC_SCEN_LAND_GEN, 0);
break;
+
+ case WE_CTRL_CHANGED:
+ if (RailToolbar_CtrlChanged(w)) e->we.ctrl.cont = false;
+ break;
}
}
diff --git a/src/road_gui.cpp b/src/road_gui.cpp
index af1aff229..6d44ca163 100644
--- a/src/road_gui.cpp
+++ b/src/road_gui.cpp
@@ -255,6 +255,38 @@ enum RoadToolbarWidgets {
typedef void OnButtonClick(Window *w);
+
+/** Toogles state of the Remove button of Build road toolbar
+ * @param w window the button belongs to
+ */
+static void ToggleRoadButton_Remove(Window *w)
+{
+ w->ToggleWidgetLoweredState(RTW_REMOVE);
+ w->InvalidateWidget(RTW_REMOVE);
+ _remove_button_clicked = w->IsWidgetLowered(RTW_REMOVE);
+ SetSelectionRed(_remove_button_clicked);
+}
+
+/** Updates the Remove button because of Ctrl state change
+ * @param w window the button belongs to
+ * @return true iff the remove buton was changed
+ */
+static bool RoadToolbar_CtrlChanged(Window *w)
+{
+ if (w->IsWidgetDisabled(RTW_REMOVE)) return false;
+
+ /* allow ctrl to switch remove mode only for these widgets */
+ for (uint i = RTW_ROAD_X; i <= RTW_AUTOROAD; i++) {
+ if (w->IsWidgetLowered(i)) {
+ ToggleRoadButton_Remove(w);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
/**
* Function that handles the click on the
* X road placement button.
@@ -338,10 +370,8 @@ static void BuildRoadClick_Tunnel(Window *w)
static void BuildRoadClick_Remove(Window *w)
{
if (w->IsWidgetDisabled(RTW_REMOVE)) return;
- SetWindowDirty(w);
+ ToggleRoadButton_Remove(w);
SndPlayFx(SND_15_BEEP);
- w->ToggleWidgetLoweredState(RTW_REMOVE);
- SetSelectionRed(w->IsWidgetLowered(RTW_REMOVE));
}
/** Array with the handlers of the button-clicks for the road-toolbar */
@@ -446,6 +476,7 @@ static void BuildRoadToolbWndProc(Window *w, WindowEvent *e)
_build_road_button_proc[e->we.click.widget - RTW_ROAD_X](w);
}
UpdateOptionWidgetStatus(w, e->we.click.widget);
+ if (_ctrl_pressed) RoadToolbar_CtrlChanged(w);
break;
case WE_KEYPRESS:
@@ -456,6 +487,7 @@ static void BuildRoadToolbWndProc(Window *w, WindowEvent *e)
_one_way_button_clicked = false;
_build_road_button_proc[i](w);
UpdateOptionWidgetStatus(w, i + RTW_ROAD_X);
+ if (_ctrl_pressed) RoadToolbar_CtrlChanged(w);
break;
}
}
@@ -568,6 +600,10 @@ static void BuildRoadToolbWndProc(Window *w, WindowEvent *e)
case WE_DESTROY:
if (_patches.link_terraform_toolbar) DeleteWindowById(WC_SCEN_LAND_GEN, 0);
break;
+
+ case WE_CTRL_CHANGED:
+ if (RoadToolbar_CtrlChanged(w)) e->we.ctrl.cont = false;
+ break;
}
}
diff --git a/src/video/cocoa/event.mm b/src/video/cocoa/event.mm
index 9302f13c8..3e8fc68c1 100644
--- a/src/video/cocoa/event.mm
+++ b/src/video/cocoa/event.mm
@@ -668,9 +668,13 @@ void QZ_GameLoop()
last_cur_ticks = cur_ticks;
next_tick = cur_ticks + 30;
+ bool old_ctrl_pressed = _ctrl_pressed;
+
_ctrl_pressed = !!(_current_mods & ( _patches.right_mouse_btn_emulation != RMBE_CONTROL ? NSControlKeyMask : NSCommandKeyMask));
_shift_pressed = !!(_current_mods & NSShiftKeyMask);
+ if (old_ctrl_pressed != _ctrl_pressed) HandleCtrlChanged();
+
GameLoop();
_screen.dst_ptr = _cocoa_subdriver->GetPixelBuffer();
diff --git a/src/video/sdl_v.cpp b/src/video/sdl_v.cpp
index 25ce5a8c6..12478cfc9 100644
--- a/src/video/sdl_v.cpp
+++ b/src/video/sdl_v.cpp
@@ -490,6 +490,8 @@ void VideoDriver_SDL::MainLoop()
last_cur_ticks = cur_ticks;
next_tick = cur_ticks + 30;
+ bool old_ctrl_pressed = _ctrl_pressed;
+
_ctrl_pressed = !!(mod & KMOD_CTRL);
_shift_pressed = !!(mod & KMOD_SHIFT);
@@ -499,6 +501,9 @@ void VideoDriver_SDL::MainLoop()
(keys[SDLK_UP] ? 2 : 0) |
(keys[SDLK_RIGHT] ? 4 : 0) |
(keys[SDLK_DOWN] ? 8 : 0);
+
+ if (old_ctrl_pressed != _ctrl_pressed) HandleCtrlChanged();
+
GameLoop();
_screen.dst_ptr = _sdl_screen->pixels;
diff --git a/src/video/win32_v.cpp b/src/video/win32_v.cpp
index b0296199a..91f7439fa 100644
--- a/src/video/win32_v.cpp
+++ b/src/video/win32_v.cpp
@@ -856,6 +856,9 @@ void VideoDriver_Win32::MainLoop()
_realtime_tick += cur_ticks - last_cur_ticks;
last_cur_ticks = cur_ticks;
next_tick = cur_ticks + 30;
+
+ bool old_ctrl_pressed = _ctrl_pressed;
+
_ctrl_pressed = _wnd.has_focus && GetAsyncKeyState(VK_CONTROL)<0;
_shift_pressed = _wnd.has_focus && GetAsyncKeyState(VK_SHIFT)<0;
@@ -870,6 +873,8 @@ void VideoDriver_Win32::MainLoop()
_dirkeys = 0;
}
+ if (old_ctrl_pressed != _ctrl_pressed) HandleCtrlChanged();
+
GameLoop();
_cursor.delta.x = _cursor.delta.y = 0;
diff --git a/src/window.cpp b/src/window.cpp
index 1ee8da60b..82b6ced25 100644
--- a/src/window.cpp
+++ b/src/window.cpp
@@ -1709,6 +1709,21 @@ void HandleKeypress(uint32 key)
}
}
+void HandleCtrlChanged()
+{
+ WindowEvent e;
+
+ e.event = WE_CTRL_CHANGED;
+ e.we.ctrl.cont = true;
+
+ /* Call the event, start with the uppermost window. */
+ for (Window* const *wz = _last_z_window; wz != _z_windows;) {
+ Window *w = *--wz;
+ w->wndproc(w, &e);
+ if (!e.we.ctrl.cont) break;
+ }
+}
+
extern void UpdateTileSelection();
extern bool VpHandlePlaceSizingDrag();
diff --git a/src/window_gui.h b/src/window_gui.h
index d83ee950d..e59b5e9b4 100644
--- a/src/window_gui.h
+++ b/src/window_gui.h
@@ -123,6 +123,7 @@ enum WindowEventCodes {
WE_MESSAGE,
WE_SCROLL,
WE_INVALIDATE_DATA,
+ WE_CTRL_CHANGED,
};
struct WindowEvent {
@@ -192,6 +193,10 @@ struct WindowEvent {
struct {
int wheel; ///< how much was 'wheel'd'
} wheel;
+
+ struct {
+ bool cont; ///< continue the search? (default true)
+ } ctrl;
} we;
};