Skip to content

Commit a3c907f

Browse files
Added mousewheel support for controls wich can be moved by pressing the left mouse button
1 parent abb8eb9 commit a3c907f

File tree

6 files changed

+195
-21
lines changed

6 files changed

+195
-21
lines changed

Source/ORTS.Common/Input/UserCommand.cs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,22 @@
1-
namespace ORTS.Common.Input
1+
// COPYRIGHT 2024 by the Open Rails project.
2+
//
3+
// This file is part of Open Rails.
4+
//
5+
// Open Rails is free software: you can redistribute it and/or modify
6+
// it under the terms of the GNU General Public License as published by
7+
// the Free Software Foundation, either version 3 of the License, or
8+
// (at your option) any later version.
9+
//
10+
// Open Rails is distributed in the hope that it will be useful,
11+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
// GNU General Public License for more details.
14+
//
15+
// You should have received a copy of the GNU General Public License
16+
// along with Open Rails. If not, see <http://www.gnu.org/licenses/>.
17+
//
18+
19+
namespace ORTS.Common.Input
220
{
321
/// <summary>
422
/// Specifies game commands.
@@ -49,6 +67,7 @@ public enum UserCommand
4967
[GetString("Display Compass Window")] DisplayCompassWindow,
5068
[GetString("Display Train List Window")] DisplayTrainListWindow,
5169
[GetString("Display EOT List Window")] DisplayEOTListWindow,
70+
[GetString("Display Control Rectangles")] DisplayControlRectangle,
5271

5372
[GetString("Debug Speed Up")] DebugSpeedUp,
5473
[GetString("Debug Speed Down")] DebugSpeedDown,

Source/ORTS.Settings/InputSettings.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,7 @@ static void InitializeCommands(UserCommandInput[] Commands)
514514
Commands[(int)UserCommand.DisplayTrainOperationsWindow] = new UserCommandKeyInput(0x43);
515515
Commands[(int)UserCommand.DisplayTrainDpuWindow] = new UserCommandKeyInput(0x43, KeyModifiers.Shift);
516516
Commands[(int)UserCommand.DisplayEOTListWindow] = new UserCommandKeyInput(0x43, KeyModifiers.Control);
517+
Commands[(int)UserCommand.DisplayControlRectangle] = new UserCommandKeyInput(0x3F, KeyModifiers.Control);
517518

518519
Commands[(int)UserCommand.GameAutopilotMode] = new UserCommandKeyInput(0x1E, KeyModifiers.Alt);
519520
Commands[(int)UserCommand.GameChangeCab] = new UserCommandKeyInput(0x12, KeyModifiers.Control);
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
// COPYRIGHT 2024 by the Open Rails project.
2+
//
3+
// This file is part of Open Rails.
4+
//
5+
// Open Rails is free software: you can redistribute it and/or modify
6+
// it under the terms of the GNU General Public License as published by
7+
// the Free Software Foundation, either version 3 of the License, or
8+
// (at your option) any later version.
9+
//
10+
// Open Rails is distributed in the hope that it will be useful,
11+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
// GNU General Public License for more details.
14+
//
15+
// You should have received a copy of the GNU General Public License
16+
// along with Open Rails. If not, see <http://www.gnu.org/licenses/>.
17+
18+
using System;
19+
using Microsoft.Xna.Framework;
20+
using Microsoft.Xna.Framework.Graphics;
21+
using Orts.Viewer3D.RollingStock;
22+
23+
namespace Orts.Viewer3D.Popups
24+
{
25+
public class ControlRectangle : Window
26+
{
27+
private readonly Texture2D Line;
28+
private readonly int Thickness = 3;
29+
private readonly Color Color = Color.Yellow;
30+
private readonly Viewer Viewer;
31+
32+
public ControlRectangle(WindowManager owner, Viewer viewer) : base(owner)
33+
{
34+
Line = new Texture2D(Owner.Viewer.GraphicsDevice, 1, 1, false, SurfaceFormat.Color);
35+
Line.SetData(new[] { Color });
36+
Viewer = viewer;
37+
}
38+
39+
public override void Draw(SpriteBatch spriteBatch)
40+
{
41+
if (Viewer.Camera is CabCamera && (Viewer.PlayerLocomotiveViewer as MSTSLocomotiveViewer)._hasCabRenderer)
42+
{
43+
var cabRenderer = (Viewer.PlayerLocomotiveViewer as MSTSLocomotiveViewer)._CabRenderer;
44+
foreach (var controlRenderer in cabRenderer.ControlMap.Values)
45+
{
46+
if ((Viewer.Camera as CabCamera).SideLocation == controlRenderer.Control.CabViewpoint && controlRenderer is ICabViewMouseControlRenderer mouseRenderer)
47+
{
48+
if (mouseRenderer.isMouseControl())
49+
{
50+
Rectangle rectangle = mouseRenderer.DestinationRectangleGet();
51+
52+
int width = rectangle.Width;
53+
int height = rectangle.Height;
54+
55+
if (width > 0)
56+
{
57+
// do not know why rectangles with width and height = 0 are there
58+
59+
// top line
60+
DrawLine(spriteBatch, rectangle.X, rectangle.Y, width, Thickness, 0);
61+
62+
// bottom line
63+
DrawLine(spriteBatch, rectangle.X, rectangle.Y + height - Thickness, width, Thickness, 0);
64+
65+
// left line
66+
DrawLine(spriteBatch, rectangle.X + Thickness, rectangle.Y, height, Thickness, 90);
67+
68+
// right line
69+
DrawLine(spriteBatch, rectangle.X + width, rectangle.Y, height, Thickness, 90);
70+
}
71+
}
72+
}
73+
}
74+
}
75+
}
76+
77+
private void DrawLine(SpriteBatch spriteBatch, int X, int Y, int width, int height, int degrees)
78+
{
79+
spriteBatch.Draw(
80+
Line,
81+
new Rectangle(X, Y, width, height),
82+
null,
83+
Color,
84+
ConvertToRadiansFromDegrees(degrees),
85+
new Vector2(0, 0),
86+
SpriteEffects.None, 0);
87+
}
88+
89+
private float ConvertToRadiansFromDegrees(int angle)
90+
{
91+
return (float)((System.Math.PI / 180) * angle);
92+
}
93+
}
94+
}

Source/RunActivity/Viewer3D/RollingStock/MSTSLocomotiveViewer.cs

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1700,6 +1700,8 @@ public interface ICabViewMouseControlRenderer
17001700
void HandleUserInput();
17011701
string GetControlName();
17021702
string ControlLabel { get; }
1703+
Rectangle DestinationRectangleGet();
1704+
bool isMouseControl();
17031705
}
17041706

17051707
/// <summary>
@@ -2034,11 +2036,32 @@ public CabViewDiscreteRenderer(Viewer viewer, MSTSLocomotive locomotive, CVCWith
20342036
ChangedValue = (value) =>
20352037
{
20362038
IntermediateValue %= 0.5f;
2037-
IntermediateValue += NormalizedMouseMovement();
2039+
if (UserInput.IsMouseLeftButtonDown)
2040+
{
2041+
IntermediateValue += NormalizedMouseMovement();
2042+
}
2043+
else
2044+
{
2045+
// mousewheel
2046+
IntermediateValue += (float)UserInput.MouseWheelChange / 700;
2047+
}
20382048
return IntermediateValue > 0.5f ? 1 : IntermediateValue < -0.5f ? -1 : 0;
20392049
};
20402050
break;
2041-
default: ChangedValue = (value) => value + NormalizedMouseMovement(); break;
2051+
default:
2052+
ChangedValue = (value) =>
2053+
{
2054+
if (UserInput.IsMouseLeftButtonDown)
2055+
{
2056+
return value + NormalizedMouseMovement();
2057+
}
2058+
else
2059+
{
2060+
// mousewheel
2061+
return value + (float)UserInput.MouseWheelChange / 1500;
2062+
}
2063+
};
2064+
break;
20422065
}
20432066
}
20442067

@@ -2340,10 +2363,21 @@ public virtual int GetDrawIndex()
23402363
/// </summary>
23412364
float NormalizedMouseMovement()
23422365
{
2343-
return (ControlDiscrete.Orientation > 0
2344-
? (float)UserInput.MouseMoveY / (float)Control.Height
2345-
: (float)UserInput.MouseMoveX / (float)Control.Width)
2346-
* (ControlDiscrete.Direction > 0 ? -1 : 1);
2366+
if (UserInput.IsMouseLeftButtonDown)
2367+
{
2368+
return (ControlDiscrete.Orientation > 0
2369+
? (float)UserInput.MouseMoveY / (float)Control.Height
2370+
: (float)UserInput.MouseMoveX / (float)Control.Width)
2371+
* (ControlDiscrete.Direction > 0 ? -1 : 1);
2372+
}
2373+
else
2374+
{
2375+
// mousewheel
2376+
return (ControlDiscrete.Orientation > 0
2377+
? (float)UserInput.MouseWheelChange / (float)Control.Height
2378+
: (float)UserInput.MouseWheelChange / (float)Control.Width)
2379+
* (ControlDiscrete.Direction > 0 ? -1 : 1);
2380+
}
23472381
}
23482382

23492383
public bool IsMouseWithin()
@@ -2849,6 +2883,16 @@ protected int PercentToIndex(float percent)
28492883

28502884
return index;
28512885
}
2886+
2887+
public Rectangle DestinationRectangleGet()
2888+
{
2889+
return DestinationRectangle;
2890+
}
2891+
2892+
public bool isMouseControl()
2893+
{
2894+
return ControlDiscrete.MouseControl;
2895+
}
28522896
}
28532897

28542898
/// <summary>

Source/RunActivity/Viewer3D/RollingStock/SubSystems/ETCS/DriverMachineInterface.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -863,5 +863,14 @@ public override void Draw(GraphicsDevice graphicsDevice)
863863
ControlView.SpriteBatch.End();
864864
ControlView.SpriteBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied, null, DepthStencilState.Default, null, Shader);
865865
}
866+
867+
public Rectangle DestinationRectangleGet()
868+
{
869+
return DrawPosition;
870+
}
871+
public bool isMouseControl()
872+
{
873+
return true;
874+
}
866875
}
867876
}

Source/RunActivity/Viewer3D/Viewer.cs

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ public class Viewer
103103
public TrainListWindow TrainListWindow { get; private set; } // for switching driven train
104104
public TTDetachWindow TTDetachWindow { get; private set; } // for detaching player train in timetable mode
105105
public EOTListWindow EOTListWindow { get; private set; } // to select EOT
106+
public ControlRectangle ControlRectangle { get; private set; } // to display the control rectangles
107+
106108
private OutOfFocusWindow OutOfFocusWindow; // to show colored rectangle around the main window when not in focus
107109

108110
// Route Information
@@ -501,6 +503,7 @@ internal void Initialize()
501503
TrainListWindow = new TrainListWindow(WindowManager);
502504
TTDetachWindow = new TTDetachWindow(WindowManager);
503505
EOTListWindow = new EOTListWindow(WindowManager);
506+
ControlRectangle = new ControlRectangle(WindowManager, this);
504507
if (Settings.SuppressConfirmations < (int)ConfirmLevel.Error)
505508
// confirm level Error might be set to suppressed when taking a movie
506509
// do not show the out of focus red square in that case
@@ -999,6 +1002,7 @@ void HandleUserInput(ElapsedTime elapsedTime)
9991002
if (UserInput.IsPressed(UserCommand.DebugSignalling)) if (UserInput.IsDown(UserCommand.DisplayNextWindowTab)) SignallingDebugWindow.TabAction(); else SignallingDebugWindow.Visible = !SignallingDebugWindow.Visible;
10001003
if (UserInput.IsPressed(UserCommand.DisplayTrainListWindow)) TrainListWindow.Visible = !TrainListWindow.Visible;
10011004
if (UserInput.IsPressed(UserCommand.DisplayEOTListWindow)) EOTListWindow.Visible = !EOTListWindow.Visible;
1005+
if (UserInput.IsPressed(UserCommand.DisplayControlRectangle)) ControlRectangle.Visible = !ControlRectangle.Visible;
10021006

10031007

10041008
if (UserInput.IsPressed(UserCommand.GameChangeCab))
@@ -1364,29 +1368,32 @@ void HandleUserInput(ElapsedTime elapsedTime)
13641368

13651369
if (Camera is CabCamera && (PlayerLocomotiveViewer as MSTSLocomotiveViewer)._hasCabRenderer)
13661370
{
1367-
if (UserInput.IsMouseLeftButtonPressed)
1371+
if (UserInput.IsMouseLeftButtonPressed || UserInput.IsMouseWheelChanged)
13681372
{
13691373
var cabRenderer = (PlayerLocomotiveViewer as MSTSLocomotiveViewer)._CabRenderer;
13701374
foreach (var controlRenderer in cabRenderer.ControlMap.Values)
13711375
{
1372-
if ((Camera as CabCamera).SideLocation == controlRenderer.Control.CabViewpoint && controlRenderer is ICabViewMouseControlRenderer mouseRenderer && mouseRenderer.IsMouseWithin())
1376+
if ((Camera as CabCamera).SideLocation == controlRenderer.Control.CabViewpoint && controlRenderer is ICabViewMouseControlRenderer mouseRenderer)
13731377
{
1374-
if ((controlRenderer.Control.Screens == null || controlRenderer.Control.Screens[0] == "all"))
1375-
{
1376-
MouseChangingControl = mouseRenderer;
1377-
break;
1378-
}
1379-
else
1378+
if (mouseRenderer.IsMouseWithin())
13801379
{
1381-
foreach (var screen in controlRenderer.Control.Screens)
1380+
if ((controlRenderer.Control.Screens == null || controlRenderer.Control.Screens[0] == "all"))
13821381
{
1383-
if (cabRenderer.ActiveScreen[controlRenderer.Control.Display] == screen)
1382+
MouseChangingControl = mouseRenderer;
1383+
break;
1384+
}
1385+
else
1386+
{
1387+
foreach (var screen in controlRenderer.Control.Screens)
13841388
{
1385-
MouseChangingControl = mouseRenderer;
1386-
break;
1389+
if (cabRenderer.ActiveScreen[controlRenderer.Control.Display] == screen)
1390+
{
1391+
MouseChangingControl = mouseRenderer;
1392+
break;
1393+
}
13871394
}
1395+
if (MouseChangingControl == mouseRenderer) break;
13881396
}
1389-
if (MouseChangingControl == mouseRenderer) break;
13901397
}
13911398
}
13921399
}
@@ -1395,7 +1402,7 @@ void HandleUserInput(ElapsedTime elapsedTime)
13951402
if (MouseChangingControl != null)
13961403
{
13971404
MouseChangingControl.HandleUserInput();
1398-
if (UserInput.IsMouseLeftButtonReleased)
1405+
if (UserInput.IsMouseLeftButtonReleased || UserInput.IsMouseWheelChanged)
13991406
{
14001407
MouseChangingControl = null;
14011408
UserInput.Handled();

0 commit comments

Comments
 (0)