diff --git a/TLM/TLM/Resources/TurnSigns/ButtonF.png b/TLM/TLM/Resources/TurnSigns/ButtonF.png
new file mode 100644
index 000000000..89db7f75c
Binary files /dev/null and b/TLM/TLM/Resources/TurnSigns/ButtonF.png differ
diff --git a/TLM/TLM/Resources/TurnSigns/ButtonFGray.png b/TLM/TLM/Resources/TurnSigns/ButtonFGray.png
new file mode 100644
index 000000000..bacc8b4d2
Binary files /dev/null and b/TLM/TLM/Resources/TurnSigns/ButtonFGray.png differ
diff --git a/TLM/TLM/Resources/TurnSigns/ButtonL.png b/TLM/TLM/Resources/TurnSigns/ButtonL.png
new file mode 100644
index 000000000..6da0d7df2
Binary files /dev/null and b/TLM/TLM/Resources/TurnSigns/ButtonL.png differ
diff --git a/TLM/TLM/Resources/TurnSigns/ButtonLGray.png b/TLM/TLM/Resources/TurnSigns/ButtonLGray.png
new file mode 100644
index 000000000..b8b9fe3b0
Binary files /dev/null and b/TLM/TLM/Resources/TurnSigns/ButtonLGray.png differ
diff --git a/TLM/TLM/Resources/TurnSigns/ButtonR.png b/TLM/TLM/Resources/TurnSigns/ButtonR.png
new file mode 100644
index 000000000..f229f1359
Binary files /dev/null and b/TLM/TLM/Resources/TurnSigns/ButtonR.png differ
diff --git a/TLM/TLM/Resources/TurnSigns/ButtonRGray.png b/TLM/TLM/Resources/TurnSigns/ButtonRGray.png
new file mode 100644
index 000000000..d630df15d
Binary files /dev/null and b/TLM/TLM/Resources/TurnSigns/ButtonRGray.png differ
diff --git a/TLM/TLM/TLM.csproj b/TLM/TLM/TLM.csproj
index cb126ecb2..151e55a78 100644
--- a/TLM/TLM/TLM.csproj
+++ b/TLM/TLM/TLM.csproj
@@ -458,6 +458,16 @@
+
+
+
+
+
+
+
+
+
+
mkdir "$(LOCALAPPDATA)\Colossal Order\Cities_Skylines\Addons\Mods\$(TargetName)"
diff --git a/TLM/TLM/UI/SubTools/LaneArrowTool.cs b/TLM/TLM/UI/SubTools/LaneArrowTool.cs
index e9577dbd4..963c1eca4 100644
--- a/TLM/TLM/UI/SubTools/LaneArrowTool.cs
+++ b/TLM/TLM/UI/SubTools/LaneArrowTool.cs
@@ -19,6 +19,27 @@
namespace TrafficManager.UI.SubTools {
public class LaneArrowTool : SubTool {
+ ///
+ /// Arrow sign bits are combined together to find index in turn arrow textures
+ /// located in TextureResources.TurnSignTextures.
+ ///
+ public const int SIGN_BIT_LEFT = 1;
+ public const int SIGN_BIT_FORWARD = 2;
+ public const int SIGN_BIT_RIGHT = 4;
+
+ /// Size for white turn sign in the GUI
+ private const float BUTTON_GUI_SCALE = 50f;
+
+ ///
+ /// Sum of widths of GUI elements for 1 lane.
+ /// NOTE this also adds spacing between lane columns.
+ ///
+ private const float LANE_GUI_WIDTH = BUTTON_GUI_SCALE * 1.33f + LANE_EXTRA_WIDTH;
+ private const float GUI_HEIGHT = BUTTON_GUI_SCALE * 1.66f; // label size + buttons
+
+ /// Some spacing between lane GUI elements
+ private const float LANE_EXTRA_WIDTH = 36f;
+
private bool _cursorInSecondaryPanel;
public LaneArrowTool(TrafficManagerTool mainTool) : base(mainTool) {
@@ -30,15 +51,20 @@ public class LaneArrowTool : SubTool {
}
public override void OnPrimaryClickOverlay() {
- if (HoveredNodeId == 0 || HoveredSegmentId == 0) return;
+ if (HoveredNodeId == 0 || HoveredSegmentId == 0) {
+ return;
+ }
var netFlags = Singleton.instance.m_nodes.m_buffer[HoveredNodeId].m_flags;
+ if ((netFlags & NetNode.Flags.Junction) == NetNode.Flags.None) {
+ return;
+ }
- if ((netFlags & NetNode.Flags.Junction) == NetNode.Flags.None) return;
-
- if (Singleton.instance.m_segments.m_buffer[HoveredSegmentId].m_startNode != HoveredNodeId &&
- Singleton.instance.m_segments.m_buffer[HoveredSegmentId].m_endNode != HoveredNodeId)
+ var hoveredSegment = Singleton.instance.m_segments.m_buffer[HoveredSegmentId];
+ if (hoveredSegment.m_startNode != HoveredNodeId &&
+ hoveredSegment.m_endNode != HoveredNodeId) {
return;
+ }
SelectedSegmentId = HoveredSegmentId;
SelectedNodeId = HoveredNodeId;
@@ -79,16 +105,19 @@ public class LaneArrowTool : SubTool {
if (diff.magnitude > TrafficManagerTool.MaxOverlayDistance)
return; // do not draw if too distant
- int width = numLanes * 128;
- var windowRect3 = new Rect(screenPos.x - width / 2, screenPos.y - 70, width, 50);
- GUILayout.Window(250, windowRect3, _guiLaneChangeWindow, "", BorderlessStyle);
- _cursorInSecondaryPanel = windowRect3.Contains(Event.current.mousePosition);
+ int width = numLanes * (int)LANE_GUI_WIDTH;
+ var proposedWindowRect = new Rect(screenPos.x - width / 2, screenPos.y - 70, width, GUI_HEIGHT);
+ var actualWindowRect = GUILayout.Window(250, proposedWindowRect, _guiLaneChangeWindow, "", BorderlessStyle);
+ _cursorInSecondaryPanel = actualWindowRect.Contains(Event.current.mousePosition);
}
public override void RenderOverlay(RenderManager.CameraInfo cameraInfo) {
NetManager netManager = Singleton.instance;
//Log._Debug($"LaneArrow Overlay: {HoveredNodeId} {HoveredSegmentId} {SelectedNodeId} {SelectedSegmentId}");
- if (!_cursorInSecondaryPanel && HoveredSegmentId != 0 && HoveredNodeId != 0 && (HoveredSegmentId != SelectedSegmentId || HoveredNodeId != SelectedNodeId)) {
+ if (!_cursorInSecondaryPanel
+ && HoveredSegmentId != 0
+ && HoveredNodeId != 0
+ && (HoveredSegmentId != SelectedSegmentId || HoveredNodeId != SelectedNodeId)) {
var nodeFlags = netManager.m_nodes.m_buffer[HoveredNodeId].m_flags;
if ((netManager.m_segments.m_buffer[HoveredSegmentId].m_startNode == HoveredNodeId || netManager.m_segments.m_buffer[HoveredSegmentId].m_endNode == HoveredNodeId) && (nodeFlags & NetNode.Flags.Junction) != NetNode.Flags.None) {
@@ -118,42 +147,61 @@ public class LaneArrowTool : SubTool {
for (var i = 0; i < laneList.Count; i++) {
var flags = (NetLane.Flags)Singleton.instance.m_lanes.m_buffer[laneList[i].laneId].m_flags;
- var style1 = new GUIStyle("button");
- var style2 = new GUIStyle("button") {
- normal = { textColor = new Color32(255, 0, 0, 255) },
- hover = { textColor = new Color32(255, 0, 0, 255) },
- focused = { textColor = new Color32(255, 0, 0, 255) }
- };
-
var laneStyle = new GUIStyle { contentOffset = new Vector2(12f, 0f) };
- var laneTitleStyle = new GUIStyle {
- contentOffset = new Vector2(36f, 2f),
- normal = { textColor = new Color(1f, 1f, 1f) }
- };
-
GUILayout.BeginVertical(laneStyle);
- GUILayout.Label(Translation.GetString("Lane") + " " + (i + 1), laneTitleStyle);
+
+ //----------------------
+ // Button group
+ //----------------------
GUILayout.BeginVertical();
GUILayout.BeginHorizontal();
+ GUILayout.FlexibleSpace();
if (!Flags.applyLaneArrowFlags(laneList[i].laneId)) {
Flags.removeLaneArrowFlags(laneList[i].laneId);
}
Flags.LaneArrowChangeResult res = Flags.LaneArrowChangeResult.Invalid;
+
bool buttonClicked = false;
- if (GUILayout.Button("←", ((flags & NetLane.Flags.Left) == NetLane.Flags.Left ? style1 : style2), GUILayout.Width(35), GUILayout.Height(25))) {
+ var isLeft = (flags & NetLane.Flags.Left) == NetLane.Flags.Left;
+ var isForward = (flags & NetLane.Flags.Forward) == NetLane.Flags.Forward;
+ var isRight = (flags & NetLane.Flags.Right) == NetLane.Flags.Right;
+
+ if (GUILayout.Button(isForward ? TextureResources.TurnButtonForward : TextureResources.TurnButtonForwardGray,
+ GUILayout.Width(BUTTON_GUI_SCALE * 1.33f),
+ GUILayout.Height(BUTTON_GUI_SCALE * 0.66f))) {
buttonClicked = true;
- LaneArrowManager.Instance.ToggleLaneArrows(laneList[i].laneId, startNode, Flags.LaneArrows.Left, out res);
+ LaneArrowManager.Instance.ToggleLaneArrows(laneList[i].laneId, startNode,
+ Flags.LaneArrows.Forward, out res);
}
- if (GUILayout.Button("↑", ((flags & NetLane.Flags.Forward) == NetLane.Flags.Forward ? style1 : style2), GUILayout.Width(25), GUILayout.Height(35))) {
+ GUILayout.FlexibleSpace();
+ GUILayout.EndHorizontal();
+
+ //----------------------
+ // Arrow sign row
+ //----------------------
+ GUILayout.BeginHorizontal();
+ GUILayout.FlexibleSpace();
+ if (GUILayout.Button(isLeft ? TextureResources.TurnButtonLeft : TextureResources.TurnButtonLeftGray,
+ GUILayout.Width(BUTTON_GUI_SCALE * 0.66f),
+ GUILayout.Height(BUTTON_GUI_SCALE))) {
buttonClicked = true;
- LaneArrowManager.Instance.ToggleLaneArrows(laneList[i].laneId, startNode, Flags.LaneArrows.Forward, out res);
+ LaneArrowManager.Instance.ToggleLaneArrows(laneList[i].laneId, startNode,
+ Flags.LaneArrows.Left, out res);
}
- if (GUILayout.Button("→", ((flags & NetLane.Flags.Right) == NetLane.Flags.Right ? style1 : style2), GUILayout.Width(35), GUILayout.Height(25))) {
+ if (GUILayout.Button(isRight ? TextureResources.TurnButtonRight : TextureResources.TurnButtonRightGray,
+ GUILayout.Width(BUTTON_GUI_SCALE * 0.66f),
+ GUILayout.Height(BUTTON_GUI_SCALE))) {
buttonClicked = true;
- LaneArrowManager.Instance.ToggleLaneArrows(laneList[i].laneId, startNode, Flags.LaneArrows.Right, out res);
+ LaneArrowManager.Instance.ToggleLaneArrows(laneList[i].laneId, startNode,
+ Flags.LaneArrows.Right, out res);
}
+ GUILayout.FlexibleSpace();
+ GUILayout.EndHorizontal();
+ //----------------------
+ // Button click handling
+ //----------------------
if (buttonClicked) {
switch (res) {
case Flags.LaneArrowChangeResult.Invalid:
@@ -169,7 +217,6 @@ public class LaneArrowTool : SubTool {
}
}
- GUILayout.EndHorizontal();
GUILayout.EndVertical();
GUILayout.EndVertical();
}
diff --git a/TLM/TLM/UI/TextureResources.cs b/TLM/TLM/UI/TextureResources.cs
index 60c2d49b0..ad9085be9 100644
--- a/TLM/TLM/UI/TextureResources.cs
+++ b/TLM/TLM/UI/TextureResources.cs
@@ -8,6 +8,7 @@
using TrafficManager.Manager.Impl;
using TrafficManager.Traffic;
using TrafficManager.UI;
+using TrafficManager.UI.SubTools;
using TrafficManager.Util;
using UnityEngine;
using static TrafficManager.Traffic.Data.PrioritySegment;
@@ -42,6 +43,14 @@ public class TextureResources
public static readonly Texture2D PedestrianModeAutomaticTexture2D;
public static readonly Texture2D PedestrianModeManualTexture2D;
public static readonly IDictionary PrioritySignTextures;
+
+ public static readonly Texture2D TurnButtonLeft;
+ public static readonly Texture2D TurnButtonRight;
+ public static readonly Texture2D TurnButtonForward;
+ public static readonly Texture2D TurnButtonLeftGray;
+ public static readonly Texture2D TurnButtonRightGray;
+ public static readonly Texture2D TurnButtonForwardGray;
+
public static readonly Texture2D SignRemoveTexture2D;
public static readonly Texture2D ClockPlayTexture2D;
public static readonly Texture2D ClockPauseTexture2D;
@@ -123,7 +132,14 @@ static TextureResources()
PrioritySignTextures[PriorityType.Main] = LoadDllResource("sign_priority.png", 200, 200);
PrioritySignTextures[PriorityType.Stop] = LoadDllResource("sign_stop.png", 200, 200);
PrioritySignTextures[PriorityType.Yield] = LoadDllResource("sign_yield.png", 200, 200);
-
+
+ TurnButtonLeft = LoadDllResource("TurnSigns.ButtonL.png", 80, 127);
+ TurnButtonRight = LoadDllResource("TurnSigns.ButtonR.png", 80, 127);
+ TurnButtonForward = LoadDllResource("TurnSigns.ButtonF.png", 62, 62);
+ TurnButtonLeftGray = LoadDllResource("TurnSigns.ButtonLGray.png", 80, 127);
+ TurnButtonRightGray = LoadDllResource("TurnSigns.ButtonRGray.png", 80, 127);
+ TurnButtonForwardGray = LoadDllResource("TurnSigns.ButtonFGray.png", 62, 62);
+
// delete priority sign
SignRemoveTexture2D = LoadDllResource("remove_signs.png", 256, 256);
@@ -264,5 +280,5 @@ static byte[] ReadToEnd(Stream stream)
stream.Position = originalPosition;
}
}
- }
+ }
}
\ No newline at end of file