|
| 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.Collections.Generic; |
| 19 | +using System.Linq; |
| 20 | +using Microsoft.Xna.Framework; |
| 21 | +using Microsoft.Xna.Framework.Graphics; |
| 22 | +using Orts.Simulation.RollingStocks; |
| 23 | +using Orts.Viewer3D.RollingStock; |
| 24 | +using SpriteBatch = Microsoft.Xna.Framework.Graphics.SpriteBatch; |
| 25 | + |
| 26 | +namespace Orts.Viewer3D.Popups |
| 27 | +{ |
| 28 | + public class ControlRectangle : Window |
| 29 | + { |
| 30 | + private readonly Texture2D Line; |
| 31 | + private int Thickness = 1; |
| 32 | + private readonly Color Color = Color.Yellow; |
| 33 | + private readonly Viewer Viewer; |
| 34 | + private bool CabViewFront; |
| 35 | + private bool IsOverRectangle = false; |
| 36 | + private class ListRect |
| 37 | + { |
| 38 | + public bool Front; |
| 39 | + public Rectangle CabRectangle; |
| 40 | + public string Name; |
| 41 | + } |
| 42 | + private List<ListRect> ListRectangles = new List<ListRect>(); |
| 43 | + private ListRect ListRects; |
| 44 | + |
| 45 | + public ControlRectangle(WindowManager owner, Viewer viewer) : base(owner) |
| 46 | + { |
| 47 | + Line = new Texture2D(Owner.Viewer.GraphicsDevice, 1, 1, false, SurfaceFormat.Color); |
| 48 | + Line.SetData(new[] { Color }); |
| 49 | + Viewer = viewer; |
| 50 | + } |
| 51 | + public override void Draw(SpriteBatch spriteBatch) |
| 52 | + { |
| 53 | + if (Viewer.Camera is CabCamera && (Viewer.PlayerLocomotiveViewer as MSTSLocomotiveViewer)._hasCabRenderer) |
| 54 | + { |
| 55 | + var cabRenderer = (Viewer.PlayerLocomotiveViewer as MSTSLocomotiveViewer)._CabRenderer; |
| 56 | + |
| 57 | + var loco = Viewer.PlayerLocomotive as MSTSLocomotive; |
| 58 | + CabViewFront = !loco.UsingRearCab; |
| 59 | + |
| 60 | + var itemsFrontCount = loco.CabViewList[(int)CabViewType.Front].CVFFile.CabViewControls.Count(); |
| 61 | + var itemsRearCount = loco.CabViewList.Count > 1 ? loco.CabViewList[(int)CabViewType.Rear].CVFFile.CabViewControls.Count() : 0; |
| 62 | + |
| 63 | + foreach (var controlRenderer in cabRenderer.ControlMap.Values.Skip(CabViewFront ? 0 : itemsFrontCount).Take(CabViewFront ? itemsFrontCount : itemsRearCount)) |
| 64 | + { |
| 65 | + if ((Viewer.Camera as CabCamera).SideLocation == controlRenderer.Control.CabViewpoint && controlRenderer is ICabViewMouseControlRenderer mouseRenderer) |
| 66 | + { |
| 67 | + if (mouseRenderer.isMouseControl()) |
| 68 | + { |
| 69 | + Rectangle rectangle = mouseRenderer.DestinationRectangleGet(); |
| 70 | + int width = rectangle.Width; |
| 71 | + int height = rectangle.Height; |
| 72 | + |
| 73 | + if (width > 0) |
| 74 | + { |
| 75 | + // do not know why rectangles with width and height = 0 are there |
| 76 | + ListRects = ListRectangles.FirstOrDefault(c => c.Name == mouseRenderer.GetControlName() && c.Front == CabViewFront); |
| 77 | + if (ListRects == null) |
| 78 | + { |
| 79 | + ListRectangles.Add(new ListRect |
| 80 | + { |
| 81 | + CabRectangle = rectangle, |
| 82 | + Front = CabViewFront, |
| 83 | + Name = mouseRenderer.GetControlName(), |
| 84 | + }); |
| 85 | + } |
| 86 | + else |
| 87 | + { |
| 88 | + ListRects.CabRectangle = rectangle; |
| 89 | + } |
| 90 | + |
| 91 | + Thickness = 1; // default |
| 92 | + if (mouseRenderer.IsMouseWithin()) |
| 93 | + { |
| 94 | + ListRects = ListRectangles.FirstOrDefault(c => c.CabRectangle == rectangle && c.Front == CabViewFront); |
| 95 | + |
| 96 | + if (ListRects != null && rectangle.Intersects(ListRects.CabRectangle) && ListRects.Name == mouseRenderer.GetControlName() && !IsOverRectangle) |
| 97 | + { |
| 98 | + Thickness = 3; // Highlights the currently selected rectangle |
| 99 | + IsOverRectangle = true; |
| 100 | + } |
| 101 | + } |
| 102 | + |
| 103 | + DrawRectangle(spriteBatch, rectangle.X, rectangle.Y, width, height, Thickness, Color); |
| 104 | + } |
| 105 | + } |
| 106 | + } |
| 107 | + } |
| 108 | + IsOverRectangle = false; |
| 109 | + } |
| 110 | + } |
| 111 | + |
| 112 | + private void DrawRectangle(SpriteBatch spriteBatch, int newX, int newY, int width, int height, int Thickness, Color Color) |
| 113 | + { // top line |
| 114 | + DrawLine(spriteBatch, newX, newY, width, Thickness, 0, Color); |
| 115 | + // bottom line |
| 116 | + DrawLine(spriteBatch, newX, newY + height - Thickness, width, Thickness, 0, Color); |
| 117 | + // left line |
| 118 | + DrawLine(spriteBatch, newX + Thickness, newY, height, Thickness, 90, Color); |
| 119 | + // right line |
| 120 | + DrawLine(spriteBatch, newX + width, newY, height, Thickness, 90, Color); |
| 121 | + } |
| 122 | + |
| 123 | + private void DrawLine(SpriteBatch spriteBatch, int X, int Y, int width, int height, int degrees, Color Color) |
| 124 | + { |
| 125 | + spriteBatch.Draw( |
| 126 | + Line, |
| 127 | + new Rectangle(X, Y, width, height), |
| 128 | + null, |
| 129 | + Color, |
| 130 | + ConvertToRadiansFromDegrees(degrees), |
| 131 | + new Vector2(0, 0), |
| 132 | + SpriteEffects.None, 0); |
| 133 | + } |
| 134 | + |
| 135 | + private float ConvertToRadiansFromDegrees(int angle) |
| 136 | + { |
| 137 | + return (float)((System.Math.PI / 180) * angle); |
| 138 | + } |
| 139 | + } |
| 140 | +} |
0 commit comments