Skip to content

Commit 5eff305

Browse files
authored
Dragging/sizing main menu pushes it back into screen rect (#849)
* Dragging main menu pushes the draghandle back into screen rect * Remove obsolete and commented code pieces * Overlay, GUI opacity and GUI scale sliders now update their tooltips on drag * DLS slider updateTooltip()
1 parent 78cd4a7 commit 5eff305

File tree

9 files changed

+95
-70
lines changed

9 files changed

+95
-70
lines changed

TLM/TLM/State/ConfigData/Main.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public class Main {
3232
public bool EnableTutorial = true;
3333

3434
/// <summary>Determines if the main menu shall be displayed in a tiny format.</summary>
35-
[Obsolete("Do not use. Main Menu now scales based on screen size")]
35+
[Obsolete("Do not use. TM:PE now has UI scale slider")]
3636
public bool TinyMainMenu = true;
3737

3838
/// <summary>User interface transparency, unit: percents, range: 0..100.</summary>

TLM/TLM/State/GlobalConfig.cs

-2
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,6 @@ private static GlobalConfig WriteDefaultConfig(GlobalConfig oldConfig, bool rese
9898
conf.Main.GuiOpacity = oldConfig.Main.GuiOpacity;
9999
conf.Main.OverlayTransparency = oldConfig.Main.OverlayTransparency;
100100

101-
// conf.Main.TinyMainMenu = oldConfig.Main.TinyMainMenu;
102-
103101
conf.Main.EnableTutorial = oldConfig.Main.EnableTutorial;
104102
conf.Main.DisplayedTutorialMessages = oldConfig.Main.DisplayedTutorialMessages;
105103
}

TLM/TLM/State/OptionsTabs/OptionsGameplayTab.cs

+1
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ private static void OnAltLaneSelectionRatioChanged(float newVal) {
167167
_altLaneSelectionRatioSlider.tooltip =
168168
Translation.Options.Get("Gameplay.Tooltip:DLS_percentage") + ": " +
169169
Options.altLaneSelectionRatio + " %";
170+
_altLaneSelectionRatioSlider.RefreshTooltip();
170171

171172
Log._Debug($"altLaneSelectionRatio changed to {Options.altLaneSelectionRatio}");
172173
}

TLM/TLM/State/OptionsTabs/OptionsGeneralTab.cs

+39-36
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,14 @@ private static string T(string key) {
4747
internal static void MakeSettings_General(ExtUITabstrip tabStrip) {
4848
UIHelper panelHelper = tabStrip.AddTabPage(T("Tab:General"));
4949

50-
UIHelperBase generalGroup = panelHelper.AddGroup(
51-
T("Tab:General"));
50+
UIHelperBase generalGroup = panelHelper.AddGroup(T("Tab:General"));
5251
string[] languageLabels = new string[Translation.AvailableLanguageCodes.Count + 1];
5352
languageLabels[0] = T("General.Dropdown.Option:Game language");
5453

5554
for (int i = 0; i < Translation.AvailableLanguageCodes.Count; ++i) {
5655
languageLabels[i + 1] = Translation.Options.Get(
57-
Translation.AvailableLanguageCodes[i], "General.Dropdown.Option:Language Name");
56+
lang: Translation.AvailableLanguageCodes[i],
57+
key: "General.Dropdown.Option:Language Name");
5858
}
5959

6060
int languageIndex = 0;
@@ -70,18 +70,18 @@ internal static void MakeSettings_General(ExtUITabstrip tabStrip) {
7070
}
7171

7272
_languageDropdown = generalGroup.AddDropdown(
73-
T("General.Dropdown:Select language") + ":",
74-
languageLabels,
75-
languageIndex,
76-
OnLanguageChanged) as UIDropDown;
73+
text: T("General.Dropdown:Select language") + ":",
74+
options: languageLabels,
75+
defaultSelection: languageIndex,
76+
eventCallback: OnLanguageChanged) as UIDropDown;
7777
_lockButtonToggle = generalGroup.AddCheckbox(
78-
T("General.Checkbox:Lock main menu button position"),
79-
GlobalConfig.Instance.Main.MainMenuButtonPosLocked,
80-
OnLockButtonChanged) as UICheckBox;
78+
text: T("General.Checkbox:Lock main menu button position"),
79+
defaultValue: GlobalConfig.Instance.Main.MainMenuButtonPosLocked,
80+
eventCallback: OnLockButtonChanged) as UICheckBox;
8181
_lockMenuToggle = generalGroup.AddCheckbox(
82-
T("General.Checkbox:Lock main menu window position"),
83-
GlobalConfig.Instance.Main.MainMenuPosLocked,
84-
OnLockMenuChanged) as UICheckBox;
82+
text: T("General.Checkbox:Lock main menu window position"),
83+
defaultValue: GlobalConfig.Instance.Main.MainMenuPosLocked,
84+
eventCallback: OnLockMenuChanged) as UICheckBox;
8585

8686
_guiScaleSlider = generalGroup.AddSlider(
8787
text: T("General.Slider:GUI scale") + ":",
@@ -124,9 +124,9 @@ internal static void MakeSettings_General(ExtUITabstrip tabStrip) {
124124
GlobalConfig.Instance.Main.ScanForKnownIncompatibleModsAtStartup,
125125
OnScanForKnownIncompatibleModsChanged) as UICheckBox;
126126
_ignoreDisabledModsToggle = generalGroup.AddCheckbox(
127-
Translation.ModConflicts.Get("Checkbox:Ignore disabled mods"),
128-
GlobalConfig.Instance.Main.IgnoreDisabledMods,
129-
OnIgnoreDisabledModsChanged) as UICheckBox;
127+
text: Translation.ModConflicts.Get("Checkbox:Ignore disabled mods"),
128+
defaultValue: GlobalConfig.Instance.Main.IgnoreDisabledMods,
129+
eventCallback: OnIgnoreDisabledModsChanged) as UICheckBox;
130130
Options.Indent(_ignoreDisabledModsToggle);
131131

132132
// General: Speed Limits
@@ -135,28 +135,28 @@ internal static void MakeSettings_General(ExtUITabstrip tabStrip) {
135135
// General: Simulation
136136
UIHelperBase simGroup = panelHelper.AddGroup(T("General.Group:Simulation"));
137137
_simulationAccuracyDropdown = simGroup.AddDropdown(
138-
T("General.Dropdown:Simulation accuracy") + ":",
139-
new[] {
140-
T("General.Dropdown.Option:Very low"),
141-
T("General.Dropdown.Option:Low"),
142-
T("General.Dropdown.Option:Medium"),
143-
T("General.Dropdown.Option:High"),
144-
T("General.Dropdown.Option:Very high")
145-
},
146-
(int)Options.simulationAccuracy,
147-
OnSimulationAccuracyChanged) as UIDropDown;
138+
text: T("General.Dropdown:Simulation accuracy") + ":",
139+
options: new[] {
140+
T("General.Dropdown.Option:Very low"),
141+
T("General.Dropdown.Option:Low"),
142+
T("General.Dropdown.Option:Medium"),
143+
T("General.Dropdown.Option:High"),
144+
T("General.Dropdown.Option:Very high"),
145+
},
146+
defaultSelection: (int)Options.simulationAccuracy,
147+
eventCallback: OnSimulationAccuracyChanged) as UIDropDown;
148148

149149
_instantEffectsToggle = simGroup.AddCheckbox(
150-
T("General.Checkbox:Apply AI changes right away"),
151-
Options.instantEffects,
152-
OnInstantEffectsChanged) as UICheckBox;
150+
text: T("General.Checkbox:Apply AI changes right away"),
151+
defaultValue: Options.instantEffects,
152+
eventCallback: OnInstantEffectsChanged) as UICheckBox;
153153
}
154154

155155
private static void SetupSpeedLimitsPanel(UIHelperBase generalGroup) {
156156
_displayMphToggle = generalGroup.AddCheckbox(
157-
Translation.SpeedLimits.Get("Checkbox:Display speed limits mph"),
158-
GlobalConfig.Instance.Main.DisplaySpeedLimitsMph,
159-
OnDisplayMphChanged) as UICheckBox;
157+
text: Translation.SpeedLimits.Get("Checkbox:Display speed limits mph"),
158+
defaultValue: GlobalConfig.Instance.Main.DisplaySpeedLimitsMph,
159+
eventCallback: OnDisplayMphChanged) as UICheckBox;
160160
string[] mphThemeOptions = {
161161
Translation.SpeedLimits.Get("General.Theme.Option:Square US"),
162162
Translation.SpeedLimits.Get("General.Theme.Option:Round UK"),
@@ -165,10 +165,10 @@ private static void SetupSpeedLimitsPanel(UIHelperBase generalGroup) {
165165
_roadSignMphStyleInt = (int)GlobalConfig.Instance.Main.MphRoadSignStyle;
166166
_roadSignsMphThemeDropdown
167167
= generalGroup.AddDropdown(
168-
Translation.SpeedLimits.Get("General.Dropdown:Road signs theme mph") + ":",
169-
mphThemeOptions,
170-
_roadSignMphStyleInt,
171-
OnRoadSignsMphThemeChanged) as UIDropDown;
168+
text: Translation.SpeedLimits.Get("General.Dropdown:Road signs theme mph") + ":",
169+
options: mphThemeOptions,
170+
defaultSelection: _roadSignMphStyleInt,
171+
eventCallback: OnRoadSignsMphThemeChanged) as UIDropDown;
172172
_roadSignsMphThemeDropdown.width = 400;
173173
}
174174

@@ -245,6 +245,7 @@ private static void OnGuiOpacityChanged(float newVal) {
245245
= string.Format(
246246
T("General.Tooltip.Format:Window transparency: {0}%"),
247247
GlobalConfig.Instance.Main.GuiOpacity);
248+
_guiOpacitySlider.RefreshTooltip();
248249

249250
GlobalConfig.WriteConfig();
250251
Log._Debug($"GuiTransparency changed to {GlobalConfig.Instance.Main.GuiOpacity}");
@@ -256,6 +257,7 @@ private static void OnGuiScaleChanged(float newVal) {
256257
= string.Format(
257258
T("General.Tooltip.Format:GUI scale: {0}%"),
258259
GlobalConfig.Instance.Main.GuiScale);
260+
_guiScaleSlider.RefreshTooltip();
259261

260262
GlobalConfig.WriteConfig();
261263
Log._Debug($"GuiScale changed to {GlobalConfig.Instance.Main.GuiScale}");
@@ -271,6 +273,7 @@ private static void OnOverlayTransparencyChanged(float newVal) {
271273
T("General.Tooltip.Format:Overlay transparency: {0}%"),
272274
GlobalConfig.Instance.Main.OverlayTransparency);
273275
GlobalConfig.WriteConfig();
276+
_overlayTransparencySlider.RefreshTooltip();
274277
Log._Debug($"Overlay transparency changed to {GlobalConfig.Instance.Main.OverlayTransparency}");
275278
}
276279

TLM/TLM/U/UIUtil.cs

+40
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
namespace TrafficManager.U {
22
using System.Collections.Generic;
33
using System.Linq;
4+
using ColossalFramework.UI;
5+
using CSUtil.Commons;
46
using UnityEngine;
57

68
/// <summary>
@@ -26,5 +28,43 @@ IEnumerable<GameObject> objects
2628

2729
toMakeUnique.name = name;
2830
}
31+
32+
/// <summary>
33+
/// Checks <paramref name="alwaysVisible"/> and if it is anywhere outside the screen, brings
34+
/// it back into the screen, the <paramref name="window"/> is moved by that delta instead.
35+
/// This is to be called after the resize, and also after the move.
36+
/// </summary>
37+
/// <param name="window">Parent to be moved.</param>
38+
/// <param name="alwaysVisible">Object to be clamped to screen.</param>
39+
/// <returns>True if the position changed.</returns>
40+
public static bool ClampToScreen(UIComponent window, UIComponent alwaysVisible) {
41+
Rect origRect = new Rect(
42+
position: alwaysVisible.absolutePosition,
43+
size: alwaysVisible.size);
44+
45+
Rect clampedRect = new Rect(origRect);
46+
47+
VectorUtil.ClampRectToScreen(
48+
rect: ref clampedRect,
49+
resolution: new Vector2(UIScaler.GUI_WIDTH, UIScaler.GUI_HEIGHT));
50+
51+
float xMotion = clampedRect.x - origRect.x;
52+
float yMotion = clampedRect.y - origRect.y;
53+
54+
// Nothing to do, return here
55+
if (Mathf.Approximately(xMotion, 0f) && Mathf.Approximately(yMotion, 0f)) {
56+
return false;
57+
}
58+
59+
// Move the parent window by the difference
60+
Vector3 pos = window.absolutePosition;
61+
pos += new Vector3(xMotion, yMotion, 0f);
62+
window.absolutePosition = pos;
63+
64+
Log._Debug(
65+
$"Clamping origRect={origRect} to new={clampedRect} "
66+
+ $"moving by {xMotion};{yMotion} newpos={pos}");
67+
return true;
68+
}
2969
}
3070
}

TLM/TLM/UI/MainMenu/MainMenuWindow.cs

+14-22
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ public class MainMenuWindow
2222
{
2323
public const int DEFAULT_MENU_X = 85;
2424
public const int DEFAULT_MENU_Y = 60;
25+
public const string WINDOW_CONTROL_NAME = "TMPE_MainMenu_Window";
2526

2627
/// <summary>
2728
/// Panel floating below the main menu and shows keybinds and mouse shortcuts.
@@ -130,7 +131,9 @@ private static readonly MenuButtonDef[] EXTRA_BUTTON_DEFS
130131
public override void Start() {
131132
base.Start();
132133

133-
U.UIUtil.MakeUniqueAndSetName(this.gameObject, "TMPE_MainMenuWindow");
134+
U.UIUtil.MakeUniqueAndSetName(
135+
toMakeUnique: this.gameObject,
136+
name: WINDOW_CONTROL_NAME);
134137

135138
GlobalConfig conf = GlobalConfig.Instance;
136139

@@ -166,7 +169,7 @@ internal static MainMenuWindow CreateMainMenuWindow() {
166169

167170
/// <summary>Called from constructor to setup own properties and events.</summary>
168171
private void SetupWindow() {
169-
this.name = "TMPE_MainMenu_Window";
172+
this.name = WINDOW_CONTROL_NAME;
170173
this.isVisible = false;
171174
this.backgroundSprite = "GenericPanel";
172175
this.color = new Color32(64, 64, 64, 240);
@@ -341,9 +344,6 @@ private void OnToggleOsdButtonClicked(U.Button.UButton button) {
341344

342345
// Refer to the TrafficManager tool asking it to request help from the current tool
343346
ModUI.GetTrafficManagerTool().RequestOnscreenDisplayUpdate();
344-
345-
// The task is delayed till next GUI update frame.
346-
// ModUI.GetTrafficManagerTool().InvalidateOnscreenDisplayFlag = true;
347347
}
348348

349349
private void SetupControls_DebugLabels(UiBuilder<MainMenuWindow> builder,
@@ -456,11 +456,11 @@ public override void OnBeforeResizerUpdate() {
456456
/// <summary>Called by UResizer for every control to be 'resized'.</summary>
457457
public override void OnAfterResizerUpdate() {
458458
if (this.DragHandle != null) {
459-
// Resize to the window width but remember there's padding on the left
460-
// this.DragHandle.size = new Vector2(x: this.width - (UConst.UIPADDING * 2f),
461-
// y: this.VersionLabel.height);
462-
463459
this.DragHandle.size = this.VersionLabel.size;
460+
461+
// Push the window back into screen if the label/draghandle are partially offscreen
462+
U.UIUtil.ClampToScreen(window: this,
463+
alwaysVisible: this.VersionLabel);
464464
}
465465
}
466466

@@ -574,24 +574,16 @@ public void OnUpdate(GlobalConfig config) {
574574
UpdatePosition(new Vector2(config.Main.MainMenuX, config.Main.MainMenuY));
575575
lastUpdatePositionFrame_ = nowFrame;
576576
}
577-
578-
// if (isStarted_) {
579-
// this.Invalidate();
580-
// }
581577
}
582578

583579
/// <summary>Always invalidates the main menu, do not call too often!</summary>
584580
/// <param name="pos">Config main menu position.</param>
585581
public void UpdatePosition(Vector2 pos) {
586-
Rect rect = new Rect(
587-
pos.x,
588-
pos.y,
589-
ModUI.Instance.MainMenu.width,
590-
this.height);
591-
Vector2 resolution = UIView.GetAView().GetScreenResolution();
592-
VectorUtil.ClampRectToScreen(ref rect, resolution);
593-
Log.Info($"Setting main menu position to [{pos.x},{pos.y}]");
594-
absolutePosition = rect.position;
582+
this.absolutePosition = new Vector2(pos.x, pos.y);
583+
if (U.UIUtil.ClampToScreen(window: this, alwaysVisible: this.VersionLabel)) {
584+
Log.Info($"Moving main menu pos={this.absolutePosition}");
585+
}
586+
595587
Invalidate();
596588
}
597589

TLM/TLM/UI/MainMenu/StatsLabel.cs

-6
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,9 @@ public class StatsLabel : U.Label.ULabel {
77

88
public override void Start() {
99
base.Start();
10-
// size = new Vector2(
11-
// ModUI.Instance.MainMenu.width / 2f,
12-
// MainMenuWindow.ScaledSize.GetTitlebarHeight());
1310
this.text = "0";
1411
this.suffix = " pathfinds";
1512
this.textColor = Color.green;
16-
// relativePosition = new Vector3(5f, -20f);
17-
// textAlignment = UIHorizontalAlignment.Left;
18-
// anchor = UIAnchorStyle.Top | UIAnchorStyle.Left;
1913
}
2014

2115
#if QUEUEDSTATS

TLM/TLM/UI/SubTools/LaneArrows/LaneArrowTool.cs

-2
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,6 @@ private void CreateLaneArrowsWindow(int numLanes) {
194194
ToolWindow.SetupControls(builder, numLanes);
195195

196196
// Resize everything correctly
197-
// builder.Control.SetTransparency(GlobalConfig.Instance.Main.GuiTransparency);
198197
builder.Done();
199198
RepositionWindowToNode(); // reposition again 2nd time now that size is known
200199
}
@@ -324,7 +323,6 @@ public override void OnToolLeftClick() {
324323
case State.EditLaneArrows:
325324
if (HoveredSegmentId != 0) {
326325
// Allow selecting other segments while doing lane editing
327-
// fsm_.SendTrigger(Trigger.ReenterSameState);
328326
OnToolLeftClick_Select();
329327
}
330328
break;

TLM/TLM/UI/SubTools/LaneArrows/LaneArrowToolWindow.cs

-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,6 @@ public void SetupControls(UiBuilder<LaneArrowToolWindow> builder, int numLanes)
9090

9191
using (var buttonRowBuilder = builder.ChildPanel<U.Panel.UPanel>(
9292
setupFn: p => { p.name = "TMPE_ButtonRow"; })) {
93-
// buttonRowBuilder.SetPadding(Constants.U_UI_PADDING);
9493
buttonRowBuilder.ResizeFunction(
9594
r => {
9695
r.Stack(mode: UStackMode.Below,

0 commit comments

Comments
 (0)