-
1
using Musewave.Resources;
-
2
using System;
-
3
using System.Drawing;
-
4
using System.IO;
-
5
using System.Threading;
-
6
using System.Windows.Forms;
-
7
-
8
namespace Musewave.About {
-
9
public sealed class AboutWindow : FormBase {
-
10
public const string ABOUT = "about";
-
11
public const string CHANGELOG = "changelog";
-
12
public const string UPDATE = "update";
-
13
-
14
private const int PADDING = 8;
-
15
private const string CHANGELOG_FILE = "changelog.txt";
-
16
private const string HOME_URL = "//musewave.flash.moe";
-
17
-
18
private const string UPDATE_IDLE = "Check for updates";
-
19
private const string UPDATE_CHECKING = "Checking...";
-
20
private const string UPDATE_FAIL = "Check failed. Retry?";
-
21
private const string UPDATE_LATEST = "On latest version!";
-
22
private const string UPDATE_OLDER = "On a future version?!";
-
23
private const string UPDATE_NEWER_NO_URL = "{0} is available!";
-
24
private const string UPDATE_NEWER_YES_URL = "Download {0}";
-
25
-
26
private readonly PictureBox Header;
-
27
private readonly TabControl Tabs;
-
28
-
29
private readonly AboutMainPage MainPage;
-
30
private readonly AboutChangelogPage ChangelogPage;
-
31
-
32
private readonly Button UpdateButton;
-
33
private string UpdateButtonIdleText = UPDATE_IDLE;
-
34
private Thread UpdateThread;
-
35
private string UpdateUrl = null;
-
36
private readonly bool AutoClickUpdateButton = false;
-
37
-
38
private readonly AboutCredit[] Credits = new[] {
-
39
new AboutCredit("BASS Powered MIDI Player by flashwave", "//flash.moe"),
-
40
new AboutCredit("BASS, BASSENC and BASSMIDI by Un4seen", "//www.un4seen.com"),
-
41
new AboutCredit("Silk Icons by famfamfam", "http://www.famfamfam.com/lab/icons/silk"),
-
42
};
-
43
-
44
public static void Display(IWin32Window owner, string tab = null) {
-
45
using AboutWindow about = new(tab);
-
46
about.ShowDialog(owner);
-
47
}
-
48
-
49
public AboutWindow(string tab = null) {
-
50
Text = "About Musewave";
-
51
ClientSize = new Size(500, 400);
-
52
StartPosition = FormStartPosition.CenterParent;
-
53
-
54
Controls.Add(Header = new() {
-
55
Image = Resources.GetImage("Misc.about-v2-fg"),
-
56
BackgroundImage = Resources.GetImage("Misc.about-v2-bg"),
-
57
Size = new Size(640, 60),
-
58
Location = new Point(0, 0),
-
59
Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right,
-
60
Dock = DockStyle.Top,
-
61
});
-
62
-
63
Controls.Add(Tabs = new() {
-
64
Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Bottom | AnchorStyles.Right,
-
65
Location = new Point(PADDING, PADDING + Header.Height),
-
66
Size = new Size(ClientSize.Width - (PADDING * 2), ClientSize.Height - (PADDING * 2) - Header.Height),
-
67
});
-
68
-
69
Tabs.SelectedIndexChanged += Tabs_SelectedIndexChanged;
-
70
-
71
Tabs.TabPages.Add(MainPage = new AboutMainPage());
-
72
-
73
MainPage.AddButton("Close", (s, e) => Close());
-
74
MainPage.AddButton("Website", (s, e) => MwProcess.OpenURL(HOME_URL));
-
75
UpdateButton = MainPage.AddButton(UpdateButtonIdleText, UpdateButton_Click);
-
76
-
77
foreach(AboutCredit credit in Credits)
-
78
MainPage.AddCredit(credit);
-
79
-
80
Tabs.TabPages.Add(ChangelogPage = new AboutChangelogPage {
-
81
BackColor = Application.RenderWithVisualStyles ? SystemColors.ControlLightLight : SystemColors.Control,
-
82
});
-
83
-
84
ChangelogSection[] changelog;
-
85
using(Stream stream = ResourceLoader.LoadEmbedded(CHANGELOG_FILE))
-
86
changelog = ChangelogSection.Parse(stream);
-
87
-
88
foreach(ChangelogSection section in changelog)
-
89
ChangelogPage.AddSection(section);
-
90
-
91
if(tab != null) {
-
92
if(tab.Equals(ABOUT, StringComparison.OrdinalIgnoreCase))
-
93
Tabs.SelectedTab = MainPage;
-
94
else if(tab.Equals(CHANGELOG, StringComparison.OrdinalIgnoreCase))
-
95
Tabs.SelectedTab = ChangelogPage;
-
96
else if(tab.Equals(UPDATE, StringComparison.OrdinalIgnoreCase)) {
-
97
AutoClickUpdateButton = true;
-
98
Tabs.SelectedTab = MainPage;
-
99
}
-
100
}
-
101
}
-
102
-
103
private void AbortUpdateThread() {
-
104
if(UpdateThread?.ThreadState == ThreadState.Running)
-
105
UpdateThread.Abort();
-
106
UpdateThread = null;
-
107
}
-
108
-
109
private void UpdateButton_Click(object sender, EventArgs ev) {
-
110
if(!string.IsNullOrEmpty(UpdateUrl)) {
-
111
MwProcess.OpenURL(UpdateUrl);
-
112
return;
-
113
}
-
114
-
115
UpdateButton.Enabled = false;
-
116
UpdateButton.Text = UPDATE_CHECKING;
-
117
-
118
AbortUpdateThread();
-
119
UpdateThread = new Thread(() => {
-
120
try {
-
121
if(MwUpdate.TryGetUpdateInfo(out MwUpdateInfo updateInfo)) {
-
122
int diff = Program.Version.CompareTo(updateInfo.Version);
-
123
-
124
if(diff < 0) {
-
125
if(string.IsNullOrEmpty(updateInfo.Url)) {
-
126
UpdateButtonIdleText = string.Format(UPDATE_NEWER_NO_URL, MwVersion.GetString(updateInfo.Version));
-
127
} else {
-
128
UpdateUrl = updateInfo.Url;
-
129
UpdateButtonIdleText = string.Format(UPDATE_NEWER_YES_URL, MwVersion.GetString(updateInfo.Version));
-
130
}
-
131
} else if(diff > 0)
-
132
UpdateButtonIdleText = UPDATE_OLDER;
-
133
else
-
134
UpdateButtonIdleText = UPDATE_LATEST;
-
135
-
136
if(!string.IsNullOrEmpty(updateInfo.Text))
-
137
Invoke(new Action(() => ShowMessageBox(updateInfo.Text, "Musewave Update Check", icon: MessageBoxIcon.Information)));
-
138
} else
-
139
UpdateButtonIdleText = UPDATE_FAIL;
-
140
} finally {
-
141
Invoke(new Action(() => {
-
142
UpdateButton.Text = UpdateButtonIdleText;
-
143
UpdateButton.Enabled = true;
-
144
-
145
if(AutoClickUpdateButton) {
-
146
if(string.IsNullOrEmpty(UpdateUrl))
-
147
UpdateButton.Select();
-
148
else
-
149
UpdateButton.PerformClick();
-
150
}
-
151
}));
-
152
}
-
153
}) { IsBackground = true };
-
154
UpdateThread.Start();
-
155
}
-
156
-
157
private void Tabs_SelectedIndexChanged(object sender, EventArgs ev) {
-
158
TriggerResize();
-
159
}
-
160
-
161
protected override void OnFormClosing(FormClosingEventArgs e) {
-
162
base.OnFormClosing(e);
-
163
-
164
AbortUpdateThread();
-
165
}
-
166
-
167
protected override void OnShown(EventArgs e) {
-
168
base.OnShown(e);
-
169
-
170
TriggerResize();
-
171
-
172
if(AutoClickUpdateButton)
-
173
UpdateButton.PerformClick();
-
174
}
-
175
-
176
public void TriggerResize() {
-
177
TabPage selectedTabRaw = Tabs.TabPages[Math.Max(0, Tabs.SelectedIndex)];
-
178
if(selectedTabRaw is not AboutPage selectedTab)
-
179
throw new NotSupportedException("Selected tab of About window tab must inherit AboutPage.");
-
180
-
181
bool isResizable = selectedTab.IsResizeable;
-
182
-
183
MaximumSize = Size.Empty;
-
184
-
185
if(isResizable) {
-
186
MaximizeBox = true;
-
187
} else {
-
188
MaximizeBox = false;
-
189
if(WindowState == FormWindowState.Maximized)
-
190
WindowState = FormWindowState.Normal;
-
191
}
-
192
-
193
Size desiredSize = selectedTab.DesiredSize + (Tabs.ClientSize - selectedTab.ClientSize);
-
194
-
195
ResetMinimumSize();
-
196
ClientSize = new Size(
-
197
desiredSize.Width + (PADDING * 2),
-
198
desiredSize.Height + Header.Height + (PADDING * 2)
-
199
);
-
200
SetCurrentSizeAsMinimum();
-
201
-
202
if(!isResizable)
-
203
MaximumSize = Size;
-
204
}
-
205
}
-
206
}
-
207