From b8fe0ce13acd0471dd44a354f0e95db799dc15b5 Mon Sep 17 00:00:00 2001 From: Chris Jakeman Date: Sat, 30 Dec 2023 16:12:50 +0000 Subject: [PATCH 1/2] Replaces Update links with a single Notification - unfinished --- Source/Menu/MainForm.cs | 151 +++++++++++++++++++++------ Source/Menu/Notification.cs | 122 ++++++++++++++++------ Source/ORTS.Updater/UpdateManager.cs | 2 +- 3 files changed, 210 insertions(+), 65 deletions(-) diff --git a/Source/Menu/MainForm.cs b/Source/Menu/MainForm.cs index d6269df7c7..815e9b26e9 100644 --- a/Source/Menu/MainForm.cs +++ b/Source/Menu/MainForm.cs @@ -32,6 +32,7 @@ using System.Resources; using System.Runtime.InteropServices; using System.Threading; +using System.Threading.Tasks; using System.Windows.Forms; using static ORTS.Notification; using Path = ORTS.Menu.Path; @@ -320,18 +321,24 @@ void CheckForUpdate() { if (UpdateManager.LastCheckError != null) linkLabelUpdate.Text = catalog.GetString("Update check failed"); - else if (UpdateManager.LastUpdate != null && UpdateManager.LastUpdate.Version != VersionInfo.Version) - linkLabelUpdate.Text = catalog.GetStringFmt("Update to {0}", UpdateManager.LastUpdate.Version); - else - linkLabelUpdate.Text = ""; - linkLabelUpdate.Enabled = true; - linkLabelUpdate.Visible = linkLabelUpdate.Text.Length > 0; - // Update link's elevation icon and size/position. - if (UpdateManager.LastCheckError == null && UpdateManager.LastUpdate != null && UpdateManager.LastUpdate.Version != VersionInfo.Version && UpdateManager.UpdaterNeedsElevation) - linkLabelUpdate.Image = ElevationIcon; - else - linkLabelUpdate.Image = null; + //else if (UpdateManager.LastUpdate != null && UpdateManager.LastUpdate.Version != VersionInfo.Version) + // linkLabelUpdate.Text = catalog.GetStringFmt("Update to {0}", UpdateManager.LastUpdate.Version); + //else + // linkLabelUpdate.Text = ""; + //linkLabelUpdate.Enabled = true; + //linkLabelUpdate.Visible = linkLabelUpdate.Text.Length > 0; + //// Update link's elevation icon and size/position. + //if (UpdateManager.LastCheckError == null && UpdateManager.LastUpdate != null && UpdateManager.LastUpdate.Version != VersionInfo.Version && UpdateManager.UpdaterNeedsElevation) + // linkLabelUpdate.Image = ElevationIcon; + //else + // linkLabelUpdate.Image = null; + + if (UpdateManager.LastUpdate != null) + { + SetUpdateNotification(); + } }); + } void LoadLanguage() @@ -1471,6 +1478,9 @@ void comboBoxTimetable_EnabledChanged(object sender, EventArgs e) // Will probably move this region and the Details region into separate files. bool AreNotificationsVisible = false; + // New notifications are those with a date after the NotificationsReadDate. + // Notifications are listed in reverse date order, with the newest one at the front. + // We don't track the reading of each notification but set the NewNotificationCount = 0 after the last of the new ones has been read. int NewNotificationCount = 1; int LastNotificationViewed = 0; @@ -1506,6 +1516,11 @@ private void ToggleNotifications() private void FiddleNewNotificationCount() { LastNotificationViewed = 1; + UpdateNotificationAlert(); + } + + private void UpdateNotificationAlert() + { if (LastNotificationViewed >= NewNotificationCount) { pbNotificationsSome.Visible = false; @@ -1528,28 +1543,47 @@ void ShowNotifications() /// private void PopulateNotificationList() { - NotificationList.Clear(); - if (NotificationList.Count == 0) - { - var newNotification = new Notification(); - NotificationList.Add(newNotification); - new NHeadingControl(panelDetails, "This is a dummy notification", Color.OrangeRed).Add(newNotification); - new NTitleControl(panelDetails, DateTime.Now, "Update is available").Add(newNotification); - new NRecordControl(panelDetails, "Update mode", 140, "Stable").Add(newNotification); - new NRecordControl(panelDetails, "Installed version", 140, "1.3.1").Add(newNotification); - new NRecordControl(panelDetails, "New version available", 140, "1.4").Add(newNotification); - new NButtonControl(panelDetails, "What's new", 90, "Find out on-line what's new in this version.").Add(newNotification); - new NButtonControl(panelDetails, "Install", 90, "Install the new version.").Add(newNotification); - new NHeadingControl(panelDetails, "Warning", Color.OrangeRed).Add(newNotification); - new NTextControl(panelDetails, "The update from your current version may affect the behaviour of some of your content.").Add(newNotification); - new NButtonControl(panelDetails, "Issue details", 90, "More details about this issue are available on-line.").Add(newNotification); - } - else - { - } + //NotificationList.Clear(); + //if (NotificationList.Count == 0) + //{ + // var newNotification = new Notification(); + // NotificationList.Add(newNotification); + //new NHeadingControl(panelDetails, "This is a dummy notification", Color.OrangeRed).Add(newNotification); + //new NTitleControl(panelDetails, DateTime.Now, "Update is available").Add(newNotification); + //new NRecordControl(panelDetails, "Update mode", 140, "Stable").Add(newNotification); + //new NRecordControl(panelDetails, "Installed version", 140, "1.3.1").Add(newNotification); + //new NRecordControl(panelDetails, "New version available", 140, "1.4").Add(newNotification); + //new NButtonControl(panelDetails, "What's new", 90, "Find out on-line what's new in this version.").Add(newNotification); + //new NButtonControl(panelDetails, "Install", 90, "Install the new version.").Add(newNotification); + //new NHeadingControl(panelDetails, "Warning", Color.OrangeRed).Add(newNotification); + //new NTextControl(panelDetails, "The update from your current version may affect the behaviour of some of your content.").Add(newNotification); + //new NButtonControl(panelDetails, "Issue details", 90, "More details about this issue are available on-line.").Add(newNotification); + + //new NTitleControl(panelDetails, new DateTime(2024, 8, 31, 0, 0, 0), "Update is available").Add(newNotification); + //new NRecordControl(panelDetails, "Update mode", 140, "Stable").Add(newNotification); + //new NRecordControl(panelDetails, "Installed version", 140, "1.6").Add(newNotification); + //new NRecordControl(panelDetails, "New version available", 140, "1.7").Add(newNotification); + //new NButtonControl(panelDetails, "What's new", 90, "Find out on-line what's new in this version.").Add(newNotification); + //new NHeadingControl(panelDetails, "Install Not Available", Color.OrangeRed).Add(newNotification); + //new NTextControl(panelDetails, "V1.7 cannot be installed on your system until the graphics card is upgraded.").Add(newNotification); + //new NButtonControl(panelDetails, "Graphics card", 90, "Find out on-line about graphics hardware needed.").Add(newNotification); + //new NHeadingControl(panelDetails, "More Realism", Color.Blue).Add(newNotification); + //new NTextControl(panelDetails, "This update supports graphics which are significantly more realistic.").Add(newNotification); + //new NButtonControl(panelDetails, "Enhancement", 90, "More details about this enhancement are available on-line.").Add(newNotification); + + //} + //else + //{ + //} + //var notification = NotificationList.LastOrDefault(); + //new NTextControl(panelDetails, "").Add(notification); + //new NTextControl(panelDetails, "(Toggle icon to hide notifications.)").Add(notification); + + SetUpdateNotification(); + var notification = NotificationList.LastOrDefault(); - new NTextControl(panelDetails, "").Add(notification); - new NTextControl(panelDetails, "(Toggle icon to hide notifications.)").Add(notification); + new NTextControl(notification, "").Add(); + new NTextControl(notification, "(Toggle icon to hide notifications.)").Add(); } /// @@ -1561,6 +1595,59 @@ Notification GetCurrentNotification() return NotificationList[0]; } + /// + /// Ultimately there will be a list of notifications downloaded for openrails/content. + /// Until then, there is a single notification announcing either that a new update is available or the installation is up to date. + /// + void SetUpdateNotification() + { + NewNotificationCount = (IsUpdateAvailable()) ? 1 : 0; + UpdateNotificationAlert(); + NotificationList.Clear(); + var newNotification = new Notification(panelDetails); + if (IsUpdateAvailable()) + { + NewNotificationCount = 1; + new NTitleControl(newNotification, UpdateManager.LastUpdate.Date, "Update is available").Add(); + new NRecordControl(newNotification, "Update mode", 140, UpdateManager.ChannelName).Add(); + new NRecordControl(newNotification, "Installed version", 140, VersionInfo.VersionOrBuild).Add(); + new NRecordControl(newNotification, "New version available", 140, UpdateManager.LastUpdate.Version).Add(); + new NLinkControl(newNotification, "What's new", 90, "Find out on-line what's new in this version.", this, UpdateManager.ChangeLogLink).Add(); + new NUpdateControl(newNotification, "Install", 90, "Install the new version.", this).Add(); + + } + else + { + NewNotificationCount = 0; + var channelName = UpdateManager.ChannelName == "" ? "None" : UpdateManager.ChannelName; + new NTitleControl(newNotification, DateTime.Now, "Installation is up to date").Add(); + new NRecordControl(newNotification, "Update mode", 140, channelName).Add(); + new NRecordControl(newNotification, "Installed version", 140, VersionInfo.VersionOrBuild).Add(); + new NRecordControl(newNotification, "New version available", 140, "none").Add(); + } + NotificationList.Add(newNotification); + } + + bool IsUpdateAvailable() + { + return UpdateManager.LastUpdate != null + && UpdateManager.LastUpdate.Version != VersionInfo.Version + && DateTime.Now >= UpdateManager.State.NextCheck; + } + + // 3 should be enough, but is there a way to get unlimited buttons? + public void Button0_Click(object sender, EventArgs e) + { + GetCurrentNotification().DoButton(UpdateManager, 0); + } + public void Button1_Click(object sender, EventArgs e) + { + GetCurrentNotification().DoButton(UpdateManager, 1); + } + public void Button2_Click(object sender, EventArgs e) + { + GetCurrentNotification().DoButton(UpdateManager, 2); + } #endregion Notifications } } diff --git a/Source/Menu/Notification.cs b/Source/Menu/Notification.cs index 3474259625..bb6f6211c9 100644 --- a/Source/Menu/Notification.cs +++ b/Source/Menu/Notification.cs @@ -17,17 +17,24 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Drawing; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using System.Windows.Forms; +using ORTS.Updater; namespace ORTS { public class Notification { public List NDetailList = new List(); + public Dictionary ButtonDictionary = new Dictionary(); + public Panel Panel; + + public Notification(Panel panel) + { + Panel = panel; + NButtonControl.ButtonCount = 0; + } public class NDetail { @@ -42,11 +49,16 @@ public class NDetail public static readonly int RecordHeight = 15; public const int ScrollBarWidth = 20; + public Notification Notification { get; private set; } public Label Control; - public void Add(Notification notification) + public NDetail(Notification notification) { - notification.NDetailList.Add(this); + Notification = notification; + } + public void Add() + { + Notification.NDetailList.Add(this); } } @@ -55,7 +67,7 @@ public void Add(Notification notification) /// public class NTitleControl : NDetail { - public NTitleControl(Panel panelDetails, DateTime date, string text) + public NTitleControl(Notification notification, DateTime date, string text) : base(notification) { var title = $"Notification 1/1: {date:dd-MMM-yyyy} - {text}"; var left = LeftPadding; @@ -63,18 +75,18 @@ public NTitleControl(Panel panelDetails, DateTime date, string text) { Text = title, UseMnemonic = false, - Font = new Font(panelDetails.Font, FontStyle.Bold), + Font = new Font(Notification.Panel.Font, FontStyle.Bold), TextAlign = ContentAlignment.BottomLeft, Height = TitleHeight, - Width = panelDetails.Width - ScrollBarWidth - left, + Width = Notification.Panel.Width - ScrollBarWidth - left, Left = LeftPadding }; - panelDetails.Controls.Add(Control); + Notification.Panel.Controls.Add(Control); } } public class NHeadingControl : NDetail { - public NHeadingControl(Panel panelDetails, string text, Color color = default) + public NHeadingControl(Notification notification, string text, Color color = default) : base(notification) { var left = LeftPadding; Control = new Label @@ -82,46 +94,47 @@ public NHeadingControl(Panel panelDetails, string text, Color color = default) ForeColor = color, Text = text, UseMnemonic = false, - Font = new Font(panelDetails.Font, FontStyle.Bold), + Font = new Font(Notification.Panel.Font, FontStyle.Bold), TextAlign = ContentAlignment.BottomLeft, Height = HeadingHeight, - Width = panelDetails.Width - ScrollBarWidth - left, + Width = Notification.Panel.Width - ScrollBarWidth - left, Left = left, Top = TopPadding, }; - panelDetails.Controls.Add(Control); + Notification.Panel.Controls.Add(Control); } } public class NTextControl : NDetail { - public NTextControl(Panel panelDetails, string text) + public NTextControl(Notification notification, string text) : base(notification) { var left = LeftPaddingIndented; Control = new Label { Text = text, UseMnemonic = false, - Font = new Font(panelDetails.Font, FontStyle.Regular), + Font = new Font(Notification.Panel.Font, FontStyle.Regular), TextAlign = ContentAlignment.BottomLeft, Height = TextHeight, - Width = panelDetails.Width - ScrollBarWidth - left, + Width = Notification.Panel.Width - ScrollBarWidth - left, Left = left, }; - panelDetails.Controls.Add(Control); + Notification.Panel.Controls.Add(Control); } } public class NButtonControl : NDetail { + public static int ButtonCount = 0; public Button Button; - public NButtonControl(Panel panelDetails, string legend, int width, string description) - { + public NButtonControl(Notification notification, string legend, int width, string description, MainForm mainForm) : base(notification) + { var buttonLeft = LeftPaddingIndented; Button = new Button { Margin = new Padding(20), Text = legend, UseMnemonic = false, - Font = new Font(panelDetails.Font, FontStyle.Regular), + Font = new Font(Notification.Panel.Font, FontStyle.Regular), TextAlign = ContentAlignment.MiddleCenter, Height = ButtonHeight, Width = width, @@ -129,7 +142,24 @@ public NButtonControl(Panel panelDetails, string legend, int width, string descr Top = TopPadding, BackColor = SystemColors.ButtonFace }; - panelDetails.Controls.Add(Button); + Notification.Panel.Controls.Add(Button); + + // 3 should be enough, but is there a way to get unlimited buttons? + switch (ButtonCount) + { + case 0: + Button.Click += new EventHandler(mainForm.Button0_Click); + break; + case 1: + Button.Click += new EventHandler(mainForm.Button1_Click); + break; + case 2: + Button.Click += new EventHandler(mainForm.Button2_Click); + break; + default: + MessageBox.Show("Cannot add 4th button; only 3 buttons are supported.", "Add Notification Button"); + break; + } var labelLeft = Button.Left + Button.Width + LeftPaddingIndented; Control = new Label @@ -137,47 +167,76 @@ public NButtonControl(Panel panelDetails, string legend, int width, string descr Margin = new Padding(20), Text = description, UseMnemonic = false, - Font = new Font(panelDetails.Font, FontStyle.Regular), + Font = new Font(Notification.Panel.Font, FontStyle.Regular), TextAlign = ContentAlignment.MiddleLeft, Height = ButtonHeight, - Width = panelDetails.Width - ScrollBarWidth - labelLeft, + Width = Notification.Panel.Width - ScrollBarWidth - labelLeft, Top = TopPadding, Left = labelLeft }; - panelDetails.Controls.Add(Control); + Notification.Panel.Controls.Add(Control); + } + } + public class NLinkControl : NButtonControl + { + public string Url; + public NLinkControl(Notification notification, string legend, int width, string description, MainForm mainForm, string url) + : base(notification, legend, width, description, mainForm) + { + Url = url; + Notification.ButtonDictionary.Add(ButtonCount, this); + ButtonCount++; + } + } + public class NUpdateControl : NButtonControl + { + public NUpdateControl(Notification notification, string legend, int width, string description, MainForm mainForm) + : base(notification, legend, width, description, mainForm) + { + Notification.ButtonDictionary.Add(ButtonCount, this); + ButtonCount++; } } + public void DoButton(UpdateManager updateManager, int key) + { + var button = ButtonDictionary[key]; + if (button is NLinkControl) + Process.Start(((NLinkControl)button).Url); + else if (button is NUpdateControl) + updateManager.Update(); + } + public class NRecordControl : NDetail { public Label Field; - public NRecordControl(Panel panelDetails, string label, int width, string field) - { + public NRecordControl(Notification notification, string label, int width, string field) : base(notification) + { Control = new Label { Text = label + ":", UseMnemonic = false, - Font = new Font(panelDetails.Font, FontStyle.Bold), + Font = new Font(Notification.Panel.Font, FontStyle.Bold), TextAlign = ContentAlignment.BottomRight, Width = width, Height = RecordHeight, Left = LeftPadding, Top = TopPadding }; - panelDetails.Controls.Add(Control); + Notification.Panel.Controls.Add(Control); var left = width + LeftPadding; Field = new Label { Text = field, UseMnemonic = false, - Font = new Font(panelDetails.Font, FontStyle.Regular), + Font = new Font(Notification.Panel.Font, FontStyle.Regular), TextAlign = ContentAlignment.BottomLeft, - Width = panelDetails.Width - ScrollBarWidth - left, + Width = Notification.Panel.Width - ScrollBarWidth - left, Height = RecordHeight, Left = left, Top = TopPadding }; - panelDetails.Controls.Add(Field); + Notification.Panel.Controls.Add(Field); } } @@ -202,5 +261,4 @@ public void FlowNDetails() } } } - } diff --git a/Source/ORTS.Updater/UpdateManager.cs b/Source/ORTS.Updater/UpdateManager.cs index 768ff8d743..2839a147c8 100644 --- a/Source/ORTS.Updater/UpdateManager.cs +++ b/Source/ORTS.Updater/UpdateManager.cs @@ -55,7 +55,7 @@ public class UpdateManager readonly string ProductName; readonly string ProductVersion; readonly UpdateSettings Settings; - readonly UpdateState State; + public readonly UpdateState State; UpdateSettings Channel; bool Force; From 8f943336405f7d0bbc1058a6f8ae724f1b44ae59 Mon Sep 17 00:00:00 2001 From: Chris Jakeman Date: Sun, 31 Dec 2023 16:05:46 +0000 Subject: [PATCH 2/2] Tidy code --- Source/Menu/MainForm.cs | 85 +++++++++++++++++++++++++---------------- 1 file changed, 53 insertions(+), 32 deletions(-) diff --git a/Source/Menu/MainForm.cs b/Source/Menu/MainForm.cs index 815e9b26e9..a90681db71 100644 --- a/Source/Menu/MainForm.cs +++ b/Source/Menu/MainForm.cs @@ -308,19 +308,19 @@ void MainForm_FormClosing(object sender, FormClosingEventArgs e) File.Delete(file); } - void CheckForUpdate() - { - // This is known directly from the chosen channel so doesn't need to wait for the update check itself. - linkLabelChangeLog.Visible = !string.IsNullOrEmpty(UpdateManager.ChangeLogLink); - - new Task(this, () => - { - UpdateManager.Check(); - return null; - }, _ => - { - if (UpdateManager.LastCheckError != null) - linkLabelUpdate.Text = catalog.GetString("Update check failed"); + //void CheckForUpdate() + //{ + // // This is known directly from the chosen channel so doesn't need to wait for the update check itself. + // linkLabelChangeLog.Visible = !string.IsNullOrEmpty(UpdateManager.ChangeLogLink); + + // new Task(this, () => + // { + // UpdateManager.Check(); + // return null; + // }, _ => + // { + // if (UpdateManager.LastCheckError != null) + // linkLabelUpdate.Text = catalog.GetString("Update check failed"); //else if (UpdateManager.LastUpdate != null && UpdateManager.LastUpdate.Version != VersionInfo.Version) // linkLabelUpdate.Text = catalog.GetStringFmt("Update to {0}", UpdateManager.LastUpdate.Version); //else @@ -332,13 +332,26 @@ void CheckForUpdate() // linkLabelUpdate.Image = ElevationIcon; //else // linkLabelUpdate.Image = null; - + // }); + //} + void CheckForUpdate() + { + new Task(this, () => + { + UpdateManager.Check(); + return null; + }, _ => + { + if (UpdateManager.LastCheckError != null) + { + linkLabelUpdate.Text = catalog.GetString("Update check failed"); + linkLabelChangeLog.Visible = true; + } if (UpdateManager.LastUpdate != null) { SetUpdateNotification(); } }); - } void LoadLanguage() @@ -1503,14 +1516,15 @@ private void ToggleNotifications() { if (AreNotificationsVisible == false) { + AreNotificationsVisible = true; // Set before calling ShowNotifcations() ShowNotifications(); FiddleNewNotificationCount(); } else { + AreNotificationsVisible = false; ShowDetails(); } - AreNotificationsVisible = !AreNotificationsVisible; } private void FiddleNewNotificationCount() @@ -1541,8 +1555,8 @@ void ShowNotifications() /// /// Populate the Notifications list /// - private void PopulateNotificationList() - { + //private void PopulateNotificationList() + //{ //NotificationList.Clear(); //if (NotificationList.Count == 0) //{ @@ -1578,7 +1592,10 @@ private void PopulateNotificationList() //var notification = NotificationList.LastOrDefault(); //new NTextControl(panelDetails, "").Add(notification); //new NTextControl(panelDetails, "(Toggle icon to hide notifications.)").Add(notification); + //} + private void PopulateNotificationList() + { SetUpdateNotification(); var notification = NotificationList.LastOrDefault(); @@ -1608,22 +1625,27 @@ void SetUpdateNotification() if (IsUpdateAvailable()) { NewNotificationCount = 1; - new NTitleControl(newNotification, UpdateManager.LastUpdate.Date, "Update is available").Add(); - new NRecordControl(newNotification, "Update mode", 140, UpdateManager.ChannelName).Add(); - new NRecordControl(newNotification, "Installed version", 140, VersionInfo.VersionOrBuild).Add(); - new NRecordControl(newNotification, "New version available", 140, UpdateManager.LastUpdate.Version).Add(); - new NLinkControl(newNotification, "What's new", 90, "Find out on-line what's new in this version.", this, UpdateManager.ChangeLogLink).Add(); - new NUpdateControl(newNotification, "Install", 90, "Install the new version.", this).Add(); - + if (AreNotificationsVisible) + { + new NTitleControl(newNotification, UpdateManager.LastUpdate.Date, "Update is available").Add(); + new NRecordControl(newNotification, "Update mode", 140, UpdateManager.ChannelName).Add(); + new NRecordControl(newNotification, "Installed version", 140, VersionInfo.VersionOrBuild).Add(); + new NRecordControl(newNotification, "New version available", 140, UpdateManager.LastUpdate.Version).Add(); + new NLinkControl(newNotification, "What's new", 90, "Find out on-line what's new in this version.", this, UpdateManager.ChangeLogLink).Add(); + new NUpdateControl(newNotification, "Install", 90, "Install the new version.", this).Add(); + } } else { NewNotificationCount = 0; - var channelName = UpdateManager.ChannelName == "" ? "None" : UpdateManager.ChannelName; - new NTitleControl(newNotification, DateTime.Now, "Installation is up to date").Add(); - new NRecordControl(newNotification, "Update mode", 140, channelName).Add(); - new NRecordControl(newNotification, "Installed version", 140, VersionInfo.VersionOrBuild).Add(); - new NRecordControl(newNotification, "New version available", 140, "none").Add(); + if (AreNotificationsVisible) + { + var channelName = UpdateManager.ChannelName == "" ? "None" : UpdateManager.ChannelName; + new NTitleControl(newNotification, DateTime.Now, "Installation is up to date").Add(); + new NRecordControl(newNotification, "Update mode", 140, channelName).Add(); + new NRecordControl(newNotification, "Installed version", 140, VersionInfo.VersionOrBuild).Add(); + new NRecordControl(newNotification, "New version available", 140, "none").Add(); + } } NotificationList.Add(newNotification); } @@ -1631,8 +1653,7 @@ void SetUpdateNotification() bool IsUpdateAvailable() { return UpdateManager.LastUpdate != null - && UpdateManager.LastUpdate.Version != VersionInfo.Version - && DateTime.Now >= UpdateManager.State.NextCheck; + && UpdateManager.LastUpdate.Version != VersionInfo.Version; } // 3 should be enough, but is there a way to get unlimited buttons?