using Musewave.Resources; using System; using System.Drawing; using System.IO; using System.Threading; using System.Windows.Forms; namespace Musewave.About { public sealed class AboutWindow : FormBase { public const string ABOUT = "about"; public const string CHANGELOG = "changelog"; public const string UPDATE = "update"; private const int PADDING = 8; private const string CHANGELOG_FILE = "changelog.txt"; private const string HOME_URL = "//musewave.flash.moe"; private const string UPDATE_IDLE = "Check for updates"; private const string UPDATE_CHECKING = "Checking..."; private const string UPDATE_FAIL = "Check failed. Retry?"; private const string UPDATE_LATEST = "On latest version!"; private const string UPDATE_OLDER = "On a future version?!"; private const string UPDATE_NEWER_NO_URL = "{0} is available!"; private const string UPDATE_NEWER_YES_URL = "Download {0}"; private readonly PictureBox Header; private readonly TabControl Tabs; private readonly AboutMainPage MainPage; private readonly AboutChangelogPage ChangelogPage; private readonly Button UpdateButton; private string UpdateButtonIdleText = UPDATE_IDLE; private Thread UpdateThread; private string UpdateUrl = null; private readonly bool AutoClickUpdateButton = false; private readonly AboutCredit[] Credits = new[] { new AboutCredit("BASS Powered MIDI Player by flashwave", "//flash.moe"), new AboutCredit("BASS, BASSENC and BASSMIDI by Un4seen", "//www.un4seen.com"), new AboutCredit("Silk Icons by famfamfam", "http://www.famfamfam.com/lab/icons/silk"), }; public static void Display(IWin32Window owner, string tab = null) { using AboutWindow about = new(tab); about.ShowDialog(owner); } public AboutWindow(string tab = null) { Text = "About Musewave"; ClientSize = new Size(500, 400); StartPosition = FormStartPosition.CenterParent; Controls.Add(Header = new() { Image = Resources.GetImage("Misc.about-v2-fg"), BackgroundImage = Resources.GetImage("Misc.about-v2-bg"), Size = new Size(640, 60), Location = new Point(0, 0), Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right, Dock = DockStyle.Top, }); Controls.Add(Tabs = new() { Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Bottom | AnchorStyles.Right, Location = new Point(PADDING, PADDING + Header.Height), Size = new Size(ClientSize.Width - (PADDING * 2), ClientSize.Height - (PADDING * 2) - Header.Height), }); Tabs.SelectedIndexChanged += Tabs_SelectedIndexChanged; Tabs.TabPages.Add(MainPage = new AboutMainPage()); MainPage.AddButton("Close", (s, e) => Close()); MainPage.AddButton("Website", (s, e) => MwProcess.OpenURL(HOME_URL)); UpdateButton = MainPage.AddButton(UpdateButtonIdleText, UpdateButton_Click); foreach(AboutCredit credit in Credits) MainPage.AddCredit(credit); Tabs.TabPages.Add(ChangelogPage = new AboutChangelogPage { BackColor = Application.RenderWithVisualStyles ? SystemColors.ControlLightLight : SystemColors.Control, }); ChangelogSection[] changelog; using(Stream stream = ResourceLoader.LoadEmbedded(CHANGELOG_FILE)) changelog = ChangelogSection.Parse(stream); foreach(ChangelogSection section in changelog) ChangelogPage.AddSection(section); if(tab != null) { if(tab.Equals(ABOUT, StringComparison.OrdinalIgnoreCase)) Tabs.SelectedTab = MainPage; else if(tab.Equals(CHANGELOG, StringComparison.OrdinalIgnoreCase)) Tabs.SelectedTab = ChangelogPage; else if(tab.Equals(UPDATE, StringComparison.OrdinalIgnoreCase)) { AutoClickUpdateButton = true; Tabs.SelectedTab = MainPage; } } } private void AbortUpdateThread() { if(UpdateThread?.ThreadState == ThreadState.Running) UpdateThread.Abort(); UpdateThread = null; } private void UpdateButton_Click(object sender, EventArgs ev) { if(!string.IsNullOrEmpty(UpdateUrl)) { MwProcess.OpenURL(UpdateUrl); return; } UpdateButton.Enabled = false; UpdateButton.Text = UPDATE_CHECKING; AbortUpdateThread(); UpdateThread = new Thread(() => { try { if(MwUpdate.TryGetUpdateInfo(out MwUpdateInfo updateInfo)) { int diff = Program.Version.CompareTo(updateInfo.Version); if(diff < 0) { if(string.IsNullOrEmpty(updateInfo.Url)) { UpdateButtonIdleText = string.Format(UPDATE_NEWER_NO_URL, MwVersion.GetString(updateInfo.Version)); } else { UpdateUrl = updateInfo.Url; UpdateButtonIdleText = string.Format(UPDATE_NEWER_YES_URL, MwVersion.GetString(updateInfo.Version)); } } else if(diff > 0) UpdateButtonIdleText = UPDATE_OLDER; else UpdateButtonIdleText = UPDATE_LATEST; if(!string.IsNullOrEmpty(updateInfo.Text)) Invoke(new Action(() => ShowMessageBox(updateInfo.Text, "Musewave Update Check", icon: MessageBoxIcon.Information))); } else UpdateButtonIdleText = UPDATE_FAIL; } finally { Invoke(new Action(() => { UpdateButton.Text = UpdateButtonIdleText; UpdateButton.Enabled = true; if(AutoClickUpdateButton) { if(string.IsNullOrEmpty(UpdateUrl)) UpdateButton.Select(); else UpdateButton.PerformClick(); } })); } }) { IsBackground = true }; UpdateThread.Start(); } private void Tabs_SelectedIndexChanged(object sender, EventArgs ev) { TriggerResize(); } protected override void OnFormClosing(FormClosingEventArgs e) { base.OnFormClosing(e); AbortUpdateThread(); } protected override void OnShown(EventArgs e) { base.OnShown(e); TriggerResize(); if(AutoClickUpdateButton) UpdateButton.PerformClick(); } public void TriggerResize() { TabPage selectedTabRaw = Tabs.TabPages[Math.Max(0, Tabs.SelectedIndex)]; if(selectedTabRaw is not AboutPage selectedTab) throw new NotSupportedException("Selected tab of About window tab must inherit AboutPage."); bool isResizable = selectedTab.IsResizeable; MaximumSize = Size.Empty; if(isResizable) { MaximizeBox = true; } else { MaximizeBox = false; if(WindowState == FormWindowState.Maximized) WindowState = FormWindowState.Normal; } Size desiredSize = selectedTab.DesiredSize + (Tabs.ClientSize - selectedTab.ClientSize); ResetMinimumSize(); ClientSize = new Size( desiredSize.Width + (PADDING * 2), desiredSize.Height + Header.Height + (PADDING * 2) ); SetCurrentSizeAsMinimum(); if(!isResizable) MaximumSize = Size; } } }