Skip to content

Commit

Permalink
OSD is floating, draggable, can be hidden, saves position; Using tran…
Browse files Browse the repository at this point in the history
…slations
  • Loading branch information
kvakvs committed Jul 10, 2019
1 parent 6548688 commit dc72383
Show file tree
Hide file tree
Showing 9 changed files with 177 additions and 42 deletions.
7 changes: 7 additions & 0 deletions TLM/TLM/Resources/lang.txt
Original file line number Diff line number Diff line change
Expand Up @@ -255,3 +255,10 @@ Road_signs_theme_mph Theme for MPH road signs
theme_Square_US US signs
theme_Round_UK British signs
theme_Round_German German signs
Toggle_OSD_panel_visible Hide OSD panel, now visible
Toggle_OSD_panel_hidden Show OSD panel, now hidden
OSD_Lane_Connection__Select Lane Connection: Select a node
OSD_Exit_tool Exit tool
OSD_Lane_Connection__Link Now link incoming lanes to outgoing
OSD_Lane_Connection_Stay_in_lane Stay in lane (both, forward or back)
OSD_Lane_Connection_Clear Clear
4 changes: 4 additions & 0 deletions TLM/TLM/State/ConfigData/Main.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ public class Main {
public int MainMenuY = MainMenuPanel.DEFAULT_MENU_Y;
public bool MainMenuPosLocked = false;

public int OSDPanelX = MainMenuPanel.DEFAULT_MENU_X;
public int OSDPanelY = MainMenuPanel.DEFAULT_MENU_Y - 32;
public bool OSDPanelVisible = true;

/// <summary>
/// Already displayed tutorial messages
/// </summary>
Expand Down
1 change: 1 addition & 0 deletions TLM/TLM/TLM.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@
<Compile Include="UI\MainMenu\OSD\OsdItem.cs" />
<Compile Include="UI\MainMenu\OSD\OsdItem_Shortcut.cs" />
<Compile Include="UI\MainMenu\OSD\OsdItem_Text.cs" />
<Compile Include="UI\MainMenu\OSD\OsdUIPanel.cs" />
<Compile Include="UI\RemoveCitizenInstanceButtonExtender.cs" />
<Compile Include="UI\RemoveVehicleButtonExtender.cs" />
<Compile Include="UI\MainMenu\LaneConnectorButton.cs" />
Expand Down
25 changes: 19 additions & 6 deletions TLM/TLM/UI/MainMenu/MainMenuPanel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,15 @@ public static readonly SizeProfile[] SIZE_PROFILES
private SizeProfile activeProfile = null;
private bool started = false;

public OnScreenDisplayPanel OsdPanel;
/// <summary>
/// OSD Panel with help and keybind tips
/// </summary>
public OnScreenDisplayPanel OsdPanel { get; private set; }

/// <summary>
/// Toggle button for OSD panel visibility
/// </summary>
public UIButton OsdButton { get; private set; }

public override void Start() {
GlobalConfig conf = GlobalConfig.Instance;
Expand Down Expand Up @@ -113,15 +121,22 @@ public override void Start() {
Drag = dragHandler.AddComponent<UIDragHandle>();
Drag.enabled = !GlobalConfig.Instance.Main.MainMenuPosLocked;

UpdateAllSizes();

// Attach On-Screen Display panel (invisible)
OsdPanel = new OnScreenDisplayPanel(this);
// This reads main menu panel size, so goes after Update(All)Sizes
try {
OsdPanel = new OnScreenDisplayPanel(UIView.GetAView(), this);
OsdButton = OsdPanel.CreateOsdButton(VersionLabel);
}
catch (Exception e) {
Log.Error($"Error creating OSD panel: {e}");
}

UpdateAllSizes();
started = true;
}

public override void OnDestroy() {
OsdPanel = null; // break the reference loop
confDisposable?.Dispose();
}

Expand All @@ -141,8 +156,6 @@ protected override void OnPositionChanged() {
config.Main.MainMenuY = (int)absolutePosition.y;

GlobalConfig.WriteConfig();

OsdPanel?.UpdatePosition();
}

base.OnPositionChanged();
Expand Down
121 changes: 98 additions & 23 deletions TLM/TLM/UI/MainMenu/OSD/OnScreenDisplayPanel.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
namespace TrafficManager.UI.MainMenu.OSD {
using System.Collections.Generic;
using ColossalFramework.UI;
using CSUtil.Commons;
using State;
using State.Keybinds;
using UnityEngine;

Expand All @@ -10,7 +12,7 @@ public class Configurator {

public Configurator(OnScreenDisplayPanel panel) {
panel_ = panel;
panel_.items_.Clear();
panel_.Clear();
}

public Configurator Title(string text) {
Expand All @@ -25,7 +27,7 @@ public Configurator Shortcut(string text, KeybindSetting setting) {

public void Show() {
panel_.Update();
panel_ = null;
panel_ = null; // end of work for the configurator object
}
}

Expand All @@ -45,7 +47,6 @@ public void Show() {
/// Sand yellow. Shortcut text.
/// </summary>
public static readonly Color PALETTE_SHORTCUT = new Color(.8f, .6f, .3f, 1f);
// public static readonly Color PALETTE_SHORTCUT = Color.black;

/// <summary>
/// Text line with 8px paddings above and below
Expand All @@ -62,26 +63,68 @@ public void Show() {
/// </summary>
public const float PADDING = 8f;

private readonly UIPanel thisPanel_;
private readonly OsdUIPanel thisPanel_;

public UIDragHandle Drag { get; private set; }

private readonly List<OsdItem> items_;

/// <summary>
/// Stores panel visibility, separate variable because even visible
/// panel is hidden when there's no active tool.
/// </summary>
private bool osdVisible_;

/// <summary>
/// The button used to control attachment
/// </summary>
private UIButton OsdButton_;

private MainMenuPanel mainMenuPanel_;

/// <summary>
/// Initializes a new instance of the <see cref="OnScreenDisplayPanel"/> class.
/// Constructs the empty OSD panel and hides it.
/// </summary>
/// <param name="mainPanel">The parent panel to attach to</param>
public OnScreenDisplayPanel(UIPanel mainPanel) {
/// <param name="parent">The parent panel to attach to</param>
public OnScreenDisplayPanel(UIView uiView, MainMenuPanel mainMenuPanel) {
items_ = new List<OsdItem>();
mainMenuPanel_ = mainMenuPanel;

thisPanel_ = mainPanel.AddUIComponent<UIPanel>();
thisPanel_ = (OsdUIPanel)uiView.AddUIComponent(typeof(OsdUIPanel));
thisPanel_.name = "TMPE_OSD_Panel";
thisPanel_.width = 10f;
thisPanel_.height = PANEL_HEIGHT;
thisPanel_.backgroundSprite = "GenericPanel";
thisPanel_.color = new Color32(64, 64, 64, 240);
Update();

// Hide!
thisPanel_.isVisible = false;

// ResetPanelPosition();
var config = GlobalConfig.Instance.Main;
thisPanel_.absolutePosition = new Vector3(config.OSDPanelX, config.OSDPanelY);

// Setup drag
var dragHandler = new GameObject("TMPE_OSD_DragHandler");
dragHandler.transform.parent = thisPanel_.transform;
dragHandler.transform.localPosition = Vector3.zero;
Drag = dragHandler.AddComponent<UIDragHandle>();
Drag.enabled = true;

// Update();
}

// private void ResetPanelPosition() {
// if (mainMenuPanel_.relativePosition.y < Screen.height / 2f) {
// // Upper part of the screen, place below the TM:PE panel, with 1px margin
// thisPanel_.relativePosition = new Vector3(0f, mainMenuPanel_.height + 1f, 0f);
// } else {
// // Lower part of the screen, place above the TM:PE panel, with 1px margin
// thisPanel_.relativePosition = new Vector3(0f, -thisPanel_.height - 1f, 0f);
// }
// }

public Configurator Setup() {
return new Configurator(this);
}
Expand All @@ -92,13 +135,22 @@ public void Clear() {
}

public void Update() {
UpdatePosition();
thisPanel_.isVisible = items_.Count > 0;
thisPanel_.isVisible = (items_.Count > 0) && osdVisible_;
if (osdVisible_) {
OsdButton_.textColor = Color.green;
OsdButton_.text = "¿";
OsdButton_.tooltip = Translation.GetString("Toggle_OSD_panel_visible");
} else {
OsdButton_.textColor = Color.gray;
OsdButton_.text = "?";
OsdButton_.tooltip = Translation.GetString("Toggle_OSD_panel_hidden");
}

UpdatePanelItems();
}

private void UpdatePanelItems() {
ClearPanelItems();
ClearPanelGuiItems();

var titleLabel = thisPanel_.AddUIComponent<UILabel>();
titleLabel.textColor = PALETTE_TEXT;
Expand All @@ -112,24 +164,47 @@ private void UpdatePanelItems() {
position = item.AddTo(thisPanel_, position);
}

thisPanel_.width = Mathf.Max(position.x, titleLabel.width + 2 * PADDING);
thisPanel_.width = Mathf.Max(position.x, titleLabel.width + (2 * PADDING));
}

private void ClearPanelItems() {
/// <summary>
/// Delete all UILabels in the panel (spare the DragHandler)
/// </summary>
private void ClearPanelGuiItems() {
foreach (var c in thisPanel_.components) {
UnityEngine.Object.Destroy(c);
if (c is UILabel) {
UnityEngine.Object.Destroy(c);
}
}
}

public void UpdatePosition() {
var parent = (UIPanel) thisPanel_.parent;
if (parent.relativePosition.y < Screen.height / 2f) {
// Upper part of the screen, place below the TM:PE panel, with 1px margin
thisPanel_.relativePosition = new Vector3(0f, parent.height + 1f, 0f);
} else {
// Lower part of the screen, place above the TM:PE panel, with 1px margin
thisPanel_.relativePosition = new Vector3(0f, -thisPanel_.height - 1f, 0f);
}
/// <summary>
/// Creates a tiny [?] button on the Main Menu panel to the right of TM:PE version
/// which will toggle visibility for the hints panel
/// </summary>
/// <param name="versionLabel">The version label in the mainmenu, we attach to its right</param>
/// <returns>The OSD button we've just created</returns>
public UIButton CreateOsdButton(UILabel versionLabel) {
OsdButton_ = mainMenuPanel_.AddUIComponent<UIButton>();
OsdButton_.buttonsMask = UIMouseButton.Left;
OsdButton_.normalBgSprite = "ButtonSmall";
OsdButton_.hoveredBgSprite = "ButtonSmallHovered";
OsdButton_.pressedBgSprite = "ButtonSmallPressed";
OsdButton_.canFocus = false; // no focusing just click
OsdButton_.width = 20f;
OsdButton_.position = new Vector3(mainMenuPanel_.width - OsdButton_.width - 4f, 4f, 0f);
OsdButton_.eventClicked += (component, param) => {
osdVisible_ = !osdVisible_;
Log._Debug($"OSD visibility button clicked, now vis={osdVisible_}");

// Update the main config
var config = GlobalConfig.Instance.Main;
config.OSDPanelVisible = osdVisible_;
GlobalConfig.WriteConfig();

Update(); // reset visibility and (unnecessary but cheap) reset items
};
return OsdButton_;
}
}
}
25 changes: 25 additions & 0 deletions TLM/TLM/UI/MainMenu/OSD/OsdUIPanel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
namespace TrafficManager.UI.MainMenu.OSD {
using ColossalFramework.UI;
using CSUtil.Commons;
using State;

public class OsdUIPanel: UIPanel {
protected override void OnPositionChanged() {
GlobalConfig config = GlobalConfig.Instance;

bool posChanged = config.Main.OSDPanelX != (int)absolutePosition.x
|| config.Main.OSDPanelY != (int)absolutePosition.y;

if (posChanged) {
Log._Debug($"OSD position changed to {absolutePosition.x}|{absolutePosition.y}");

config.Main.OSDPanelX = (int)absolutePosition.x;
config.Main.OSDPanelY = (int)absolutePosition.y;

GlobalConfig.WriteConfig();
}

base.OnPositionChanged();
}
}
}
19 changes: 11 additions & 8 deletions TLM/TLM/UI/SubTools/LaneConnectorTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -443,17 +443,21 @@ public override void OnActivate() {

private static void OsdSetup_SelectNode() {
LoadingExtension.BaseUI.MainMenu.OsdPanel.Setup()
.Title("Lane Connections: Select a node")
.Shortcut("Exit tool", KeybindSettingsBase.ToolCancelViewOnly)
.Title(Translation.GetString("OSD_Lane_Connection__Select"))
.Shortcut(Translation.GetString("OSD_Exit_tool"),
KeybindSettingsBase.ToolCancelViewOnly)
.Show();
}

private static void OsdSetup_LinkLanes() {
LoadingExtension.BaseUI.MainMenu.OsdPanel.Setup()
.Title("Link the lanes")
.Shortcut("Clear", KeybindSettingsBase.LaneConnectorDelete)
.Shortcut("Stay in lane", KeybindSettingsBase.LaneConnectorStayInLane)
.Shortcut("Exit tool", KeybindSettingsBase.ToolCancelViewOnly)
.Title(Translation.GetString("OSD_Lane_Connection__Link"))
.Shortcut(Translation.GetString("OSD_Lane_Connection_Clear"),
KeybindSettingsBase.LaneConnectorDelete)
.Shortcut(Translation.GetString("OSD_Lane_Connection_Stay_in_lane"),
KeybindSettingsBase.LaneConnectorStayInLane)
.Shortcut(Translation.GetString("OSD_Exit_tool"),
KeybindSettingsBase.ToolCancelViewOnly)
.Show();
}

Expand Down Expand Up @@ -490,8 +494,7 @@ private MarkerSelectionMode GetMarkerSelectionMode() {

public override void Cleanup() {
// Clear OSD keybinds
var osd = LoadingExtension.BaseUI.MainMenu.OsdPanel;
osd.Clear();
LoadingExtension.BaseUI.MainMenu.OsdPanel.Clear();
}

public override void Initialize() {
Expand Down
12 changes: 7 additions & 5 deletions TLM/TLM/UI/TrafficManagerTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -291,14 +291,16 @@ protected override void OnToolUpdate() {
return;

// check if mouse is inside panel
if (LoadingExtension.BaseUI.GetMenu().containsMouse
var mainMenuPanel = LoadingExtension.BaseUI.GetMenu();
var mainMenuContainsMouse = mainMenuPanel != null && mainMenuPanel.containsMouse;
#if DEBUG
|| LoadingExtension.BaseUI.GetDebugMenu().containsMouse
var debugMenuPanel = LoadingExtension.BaseUI.GetDebugMenu();
var debugMenuContainsMouse = debugMenuPanel != null && debugMenuPanel.containsMouse;
#else
const bool debugMenuContainsMouse = false;
#endif
) {
#if DEBUG
if (mainMenuContainsMouse || debugMenuContainsMouse) {
Log._Debug($"TrafficManagerTool: OnToolUpdate: Menu contains mouse. Ignoring click.");
#endif
return;
}

Expand Down
5 changes: 5 additions & 0 deletions TLM/TLM/UI/UIBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ public class UIBase : UICustomControl {

public UIMainMenuButton MainMenuButton { get; private set; }
public MainMenuPanel MainMenu { get; private set; }

#if DEBUG
public DebugMenuPanel DebugMenu { get; private set; }
#endif

public static TrafficManagerTool GetTrafficManagerTool(bool createIfRequired=true) {
if (tool == null && createIfRequired) {
Log.Info("Initializing traffic manager tool...");
Expand All @@ -21,7 +23,9 @@ public static TrafficManagerTool GetTrafficManagerTool(bool createIfRequired=tru

return tool;
}

private static TrafficManagerTool tool = null;

public static TrafficManagerMode ToolMode { get; set; }

private bool _uiShown = false;
Expand All @@ -39,6 +43,7 @@ public UIBase() {
// add the menu
MainMenu = (MainMenuPanel)uiView.AddUIComponent(typeof(MainMenuPanel));
MainMenu.gameObject.AddComponent<CustomKeyHandler>();

#if DEBUG
DebugMenu = (DebugMenuPanel)uiView.AddUIComponent(typeof(DebugMenuPanel));
#endif
Expand Down

0 comments on commit dc72383

Please sign in to comment.