Skip to content

Commit 4cc1717

Browse files
committed
Added NotificationForm to pop up alert messages.
Added NotificationOptionsForm to test alert popups. NotificationOptionsForm should later feature notification options, too.
1 parent 17a2454 commit 4cc1717

13 files changed

+652
-49
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,19 @@
11
using System.ComponentModel;
2+
using System.Drawing;
23
using System.Windows.Forms;
4+
using Bitmap = System.Drawing.Bitmap;
35

46
namespace ScriptFUSION.WarframeAlertTracker.Controls {
57
internal static class ControlExtension {
68
public static bool IsDesignTime(this Control control) {
79
return LicenseManager.UsageMode == LicenseUsageMode.Designtime;
810
}
11+
12+
public static Bitmap Snapshot(this Control control) {
13+
var image = new Bitmap(control.Width, control.Height);
14+
control.DrawToBitmap(image, control.ClientRectangle);
15+
16+
return image;
17+
}
918
}
1019
}

Source/Controls/FissureControl.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.ComponentModel;
1+
using System;
2+
using System.ComponentModel;
23
using System.Drawing;
34
using System.Threading.Tasks;
45
using System.Windows.Forms;
@@ -35,6 +36,15 @@ public FissureControl() {
3536
relic.Paint += Relic_Paint;
3637
}
3738

39+
internal static async Task<FissureControl> CreateTestControl(ImageRepository imageRepository) {
40+
return new FissureControl {
41+
relic = { Image = await imageRepository.Lith },
42+
countdownClock = { CountdownTo = DateTime.Now.AddHours(1.25) },
43+
ImageRepository = imageRepository,
44+
Active = true,
45+
};
46+
}
47+
3848
protected override void OnPaint(PaintEventArgs e) {
3949
base.OnPaint(e);
4050

Source/Forms/AlertsForm.Designer.cs

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Source/Forms/AlertsForm.resx

Lines changed: 45 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -124,51 +124,51 @@
124124
<value>
125125
AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w
126126
LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
127-
ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAAA6
128-
CgAAAk1TRnQBSQFMAgEBAgEAASABAAEgAQABEAEAARABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFA
129-
AwABEAMAAQEBAAEgBgABEP8AJwADOAFdAVEBVAFPAaUBWgFqAU0BzgFZAWgBTQHJAVABUgFNAZ0DMgFQ
130-
JAADEAEVAkgBSgGIAlUBdQHOAUEBQgGsAfABQQFCAawB8AJUAXgB0QJNAU8BlAMbASacAAMlATcBWQFw
131-
AUYB1wFNAaQBAAH/AUwBpAEAAf8BTQGkAQAB/wFNAaQBAAH/AU0BpAEAAf8BTQGkAQAB/wFZAWUBTQHH
132-
AxgBIhgAAywBRAFGAUgBpQHsASkBKwHbAf8BLwExAdwB/wEvATEB3AH/AS8BMQHcAf8BMAEyAdwB/wEp
133-
ASsB2wH/ATQBNgHQAf0COQE6AWCUAAMkATYBTQGkAQAB/wFRAaYBAAH/AUQBnwEAAf8BMAGVAQAB/wE8
134-
AZsBAAH/AVABpgEAAf8BTQGkAQAB/wFNAaQBAAH/AU0BpAEAAf8BUwGOASMB8QMWAR4QAAMjATMBMgE0
135-
Ad0B/wEgASIB2QH/AR0BHwHZAf8BGQEcAdgB/wEzATUB3QH/ATQBNgHdAf8BGwEdAdkB/wEdASAB2QH/
136-
ASABIgHZAf8BMAEyAdwB/wM0AVSMAAMEAQYBVwGPASEB8gFPAaUBAAH/AT0BnAEAAf8BSwGjAQAB/wGo
137-
AdIBgAH/AWwBtAEqAf8BLQGTAQAB/wFPAaUBAAH/AU4BpAEAAf8BTQGkAQAB/wFNAaQBAAH/AVkBcAFG
138-
AdcQAAFNAU4BlgHlARcBGQHYAf8BhwGIAeoB/wLKAfYB/wFQAVIB4gH/AQsBDQHWAf8BDQEPAdYB/wE/
139-
AUEB3wH/AsoB9gH/AZ4BnwHuAf8BGQEcAdkB/wExATMB1QH+AwkBDIgAA0ABcQFOAaUBAAH/AUcBoQEA
140-
Af8BJwGQAQAB/wHBAd8BpQn/AWEBrgEnAf8BKQGRAQAB/wFOAaUBAAH/AU4BpAEAAf8BTQGkAQAB/wFN
141-
AaQBAAH/AjEBMAFNCAADOAFcAS4BMAHcAf8BBwEJAdUB/wG2AbcB8wX/AvYB/QH/AS0BLwHcAf8BHAEf
142-
AdkB/wLpAfsF/wHNAc4B9gH/AQsBDQHWAf8BLAEuAdwB/wJEAUUBe4gAAVoBaAFOAcoBTgGlAQAB/wEr
143-
AZIBAAH/AZgByQFfBf8B8AH3AeIJ/wFkAbABLAH/ASgBkQEAAf8BTgGlAQAB/wFOAaQBAAH/AU0BpAEA
144-
Af8BUQFUAU8BpQgAAlIBXAGuAS8BMQHcAf8BJAEnAdoB/wEiASUB2gH/AcsBzAH2Bf8C6gH7Af8C4gH6
145-
Bf8C2wH5Af8BKgEsAdsB/wEhASMB2gH/AS8BMQHcAf8CVQFxAcyIAAFYAX0BOwHjATQBlwEAAf8BdgG5
146-
ATwF/wL9AfsB/wFAAZ0BAgH/AXIBtwE4Cf8BaQGzATMB/wEoAZABAAH/AU0BpAEAAf8BTgGkAQAB/wFZ
147-
AWwBTAHPCAABVAFWAXEByQEvATEB3AH/ATQBNgHdAf8BGQEcAdkB/wEGAQkB1QH/AcMBxAH1Cf8C0gH3
148-
Af8BFAEWAdcB/wETARUB1wH/ATQBNgHdAf8BLwExAdwB/wFNAU8BjwHiiAABVgF6ATcB5AEzAZYBAAH/
149-
AY8BxQFVAf8B7gH2AeYB/wF6AbsBPgH/ASgBkQEAAf8BKQGRAQAB/wGCAb0BSwn/AW8BtgE6Af8BKgGS
150-
AQAB/wFPAaUBAAH/AVoBcAFHAdUIAAJUAXABygEvATEB3AH/ATQBNgHdAf8BFAEWAdcB/wEaARwB2AH/
151-
AcgByQH2Cf8B2AHZAfgB/wEqASwB2wH/AQ4BEQHWAf8BMwE1Ad0B/wEvATEB3AH/Ak8BhwHfiAABWQFs
152-
AUwBzwFPAaUBAAH/AUgBoQEAAf8BSwGjAQAB/wE+AZwBAAH/AU8BpQEAAf8BTAGjAQAB/wEkAY8BAAH/
153-
AXgBugFDCf8BgQG9AUwB/wE4AZkBAAH/AVUBWgFRAbEIAAJRAVkBqQEvATEB3AH/ASEBIwHaAf8BMAEy
154-
AdwB/wLhAfoF/wLSAfcB/wHHAcgB9QX/Au8B/AH/AT0BPwHeAf8BHQEgAdkB/wEvATEB3AH/AlQBaAHB
155-
iAADSAGEAU4BpQEAAf8BSwGjAQAB/wFEAZ8BAAH/AUwBowEAAf8BTgGkAQAB/wFOAaUBAAH/AUwBpAEA
156-
Af8BJwGQAQAB/wF4AboBQAX/AcsB5AGwAf8BLgGUAQAB/wM4AV0IAAMxAU0BLgEwAdwB/wEFAQcB1QH/
157-
AbwBvQHzBf8B5QHmAfsB/wEbAR0B2AH/AQoBDAHWAf8B0gHTAfcF/wLfAfoB/wELAQ4B1gH/ASsBLQHb
158-
Af8CPwFAAW+IAAMNAREBUQGdAQEB/gFNAaQBAAH/AU0BpAEAAf8BTQGkAQAB/wFNAaQBAAH/AU0BpAEA
159-
Af8BTgGlAQAB/wFNAaQBAAH/ATUBmAEAAf8BYQGuARsB/wFYAaoBDQH/AVcBfgEwAegQAAFUAVUBegHU
160-
ARsBHQHYAf8BcQFyAecB/wKzAfIB/wFBAUMB3wH/ARABEgHXAf8BFAEXAdgB/wExATMB3AH/Aq8B8QH/
161-
AYcBiQHrAf8BHgEgAdkB/wE2ATgBvAH2AwUBB4wAAzIBUAFNAaQBAAH/AU0BpAEAAf8BTQGkAQAB/wFN
162-
AaQBAAH/AU0BpAEAAf8BTQGkAQAB/wFOAaQBAAH/AU4BpAEAAf8BOwGbAQAB/wFDAZ8BAAH/AiIBIQEx
163-
EAADGQEjATwBPgHLAfoBHgEgAdkB/wESARQB1wH/AR4BIAHZAf8BNAE2Ad0B/wE0ATYB3QH/ASEBIwHa
164-
Af8BEQEUAdcB/wEZARsB2AH/ATIBNAHdAf8DKAE9lAADNQFXAVIBigEjAfABTQGkAQAB/wFNAaQBAAH/
165-
AU0BpAEAAf8BTQGkAQAB/wFNAaQBAAH/AU0BpAEAAf8BWAF9ATsB4wMmATkYAAMgAS8BUgFUAXgB0gEs
166-
AS4B3AH/AS8BMQHcAf8BLwExAdwB/wEvATEB3AH/AS8BMQHcAf8BLQEvAdwB/wFOAU8BjwHhAysBQpwA
167-
Aw8BFAJHAUYBgQFZAWUBTQHHAVoBeQE+AeABWAF1AUEB3QFXAWABUAG/AkABPwFvAwcBCSQAAzsBZQJS
168-
AV4BtAJRAYAB2AJUAYMB2gJUAWUBvQNBAXIDCAEL/wCRAAFCAU0BPgcAAT4DAAEoAwABQAMAARADAAEB
169-
AQABAQUAAYAXAAP/AQAE/wQAAfgBHwHwAQ8EAAHgAQcB4AEHBAABwAEDAcABAwQAAYABAwHAAQEEAAGA
170-
AQEBgAEBBAABgAEBAYABAQQAAYABAQGAAQEEAAGAAQEBgAEBBAABgAEBAYABAQQAAYABAQGAAQEEAAGA
171-
AQMBwAEBBAABwAEDAcABAwQAAeABBwHgAQcEAAHwAQ8B+AEPBAAE/wQACw==
127+
ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAAAy
128+
CgAAAk1TRnQBSQFMAgEBAgEAASgBAAEoAQABEAEAARABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFA
129+
AwABEAMAAQEBAAEgBgABEP8AJwADOAFdAVEBUwFPAaUBWwFmAVIBzgFZAWMBUwHJAlABTwGdAzIBUCQA
130+
AxABFQJIAUkBiAJYAW4BzgFDAUQBpAHwAUMBRAGkAfACVwFvAdEDTgGUAxsBJpwAAyUBNwFZAWoBTAHX
131+
AUwBpAEAAf8BSwGkAQAB/wFMAaQBAAH/AUwBpAEAAf8BTAGkAQAB/wFMAaQBAAH/AVkBYQFRAccDGAEi
132+
GAADLAFEAUoBTAGcAewBKAEqAdsB/wEuATAB3AH/AS4BMAHcAf8BLgEwAdwB/wEvATEB3AH/ASgBKgHb
133+
Af8BNQE3Ac0B/QI5AToBYJQAAyQBNgFMAaQBAAH/AVABpgEAAf8BQwGfAQAB/wEvAZUBAAH/ATsBmwEA
134+
Af8BTwGmAQAB/wFMAaQBAAH/AUwBpAEAAf8BTAGkAQAB/wFTAYkBKQHxAxYBHhAAAyMBMwExATMB3QH/
135+
AR8BIQHZAf8BHAEeAdkB/wEYARsB2AH/ATIBNAHdAf8BMwE1Ad0B/wEaARwB2QH/ARwBHwHZAf8BHwEh
136+
AdkB/wEvATEB3AH/AzQBVIwAAwQBBgFYAYsBJgHyAU4BpQEAAf8BPAGcAQAB/wFKAaMBAAH/AagB0gGA
137+
Af8BawG0ASkB/wEsAZMBAAH/AU4BpQEAAf8BTQGkAQAB/wFMAaQBAAH/AUwBpAEAAf8BWQFqAUwB1xAA
138+
AVABUQGNAeUBFgEYAdgB/wGHAYgB6gH/AsoB9gH/AU8BUQHiAf8BCgEMAdYB/wEMAQ4B1gH/AT4BQAHf
139+
Af8CygH2Af8BngGfAe4B/wEYARsB2QH/ATEBMwHTAf4DCQEMiAADQAFxAU0BpQEAAf8BRgGhAQAB/wEm
140+
AZABAAH/AcEB3wGlCf8BYAGuASYB/wEoAZEBAAH/AU0BpQEAAf8BTQGkAQAB/wFMAaQBAAH/AUwBpAEA
141+
Af8CMQEwAU0IAAM4AVwBLQEvAdwB/wEGAQgB1QH/AbYBtwHzBf8C9gH9Af8BLAEuAdwB/wEbAR4B2QH/
142+
AukB+wX/Ac0BzgH2Af8BCgEMAdYB/wErAS0B3AH/A0QBe4gAAVoBYwFTAcoBTQGlAQAB/wEqAZIBAAH/
143+
AZgByQFeBf8B8AH3AeIJ/wFjAbABKwH/AScBkQEAAf8BTQGlAQAB/wFNAaQBAAH/AUwBpAEAAf8BUQFT
144+
AU8BpQgAAlMBWQGuAS4BMAHcAf8BIwEmAdoB/wEhASQB2gH/AcsBzAH2Bf8C6gH7Af8C4gH6Bf8C2wH5
145+
Af8BKQErAdsB/wEgASIB2gH/AS4BMAHcAf8CVwFpAcyIAAFYAXYBQwHjATMBlwEAAf8BdQG5ATsF/wL9
146+
AfsB/wE/AZ0BAQH/AXEBtwE3Cf8BaAGzATIB/wEnAZABAAH/AUwBpAEAAf8BTQGkAQAB/wFZAWgBUgHP
147+
CAABVgFYAWkByQEuATAB3AH/ATMBNQHdAf8BGAEbAdkB/wEFAQgB1QH/AcMBxAH1Cf8C0gH3Af8BEwEV
148+
AdcB/wESARQB1wH/ATMBNQHdAf8BLgEwAdwB/wFQAVIBhgHiiAABWAF0AT4B5AEyAZYBAAH/AY8BxQFU
149+
Af8B7gH2AeYB/wF5AbsBPQH/AScBkQEAAf8BKAGRAQAB/wGCAb0BSgn/AW4BtgE5Af8BKQGSAQAB/wFO
150+
AaUBAAH/AVoBbAFNAdUIAAJXAWkBygEuATAB3AH/ATMBNQHdAf8BEwEVAdcB/wEZARsB2AH/AcgByQH2
151+
Cf8B2AHZAfgB/wEpASsB2wH/AQ0BEAHWAf8BMgE0Ad0B/wEuATAB3AH/AlEBfQHfiAABWQFoAVIBzwFO
152+
AaUBAAH/AUcBoQEAAf8BSgGjAQAB/wE9AZwBAAH/AU4BpQEAAf8BSwGjAQAB/wEjAY8BAAH/AXcBugFC
153+
Cf8BgQG9AUsB/wE3AZkBAAH/AVUBVwFTAbEIAAJSAVYBqQEuATAB3AH/ASABIgHaAf8BLwExAdwB/wLh
154+
AfoF/wLSAfcB/wHHAcgB9QX/Au8B/AH/ATwBPgHeAf8BHAEfAdkB/wEuATAB3AH/AlYBYgHBiAADSAGE
155+
AU0BpQEAAf8BSgGjAQAB/wFDAZ8BAAH/AUsBowEAAf8BTQGkAQAB/wFNAaUBAAH/AUsBpAEAAf8BJgGQ
156+
AQAB/wF3AboBPwX/AcsB5AGwAf8BLQGUAQAB/wM4AV0IAAMxAU0BLQEvAdwB/wEEAQYB1QH/AbwBvQHz
157+
Bf8B5QHmAfsB/wEaARwB2AH/AQkBCwHWAf8B0gHTAfcF/wLfAfoB/wEKAQ0B1gH/ASoBLAHbAf8CPwFA
158+
AW+IAAMNAREBUQGbAQEB/gFMAaQBAAH/AUwBpAEAAf8BTAGkAQAB/wFMAaQBAAH/AUwBpAEAAf8BTQGl
159+
AQAB/wFMAaQBAAH/ATQBmAEAAf8BYAGuARoB/wFXAaoBDAH/AVcBegE5AegQAAFXAVgBcgHUARoBHAHY
160+
Af8BcAFxAecB/wKzAfIB/wFAAUIB3wH/AQ8BEQHXAf8BEwEWAdgB/wEwATIB3AH/Aq8B8QH/AYcBiQHr
161+
Af8BHQEfAdkB/wE3ATkBtAH2AwUBB4wAAzIBUAFMAaQBAAH/AUwBpAEAAf8BTAGkAQAB/wFMAaQBAAH/
162+
AUwBpAEAAf8BTAGkAQAB/wFNAaQBAAH/AU0BpAEAAf8BOgGbAQAB/wFCAZ8BAAH/AiIBIQExEAADGQEj
163+
AT0BPwHGAfoBHQEfAdkB/wERARMB1wH/AR0BHwHZAf8BMwE1Ad0B/wEzATUB3QH/ASABIgHaAf8BEAET
164+
AdcB/wEYARoB2AH/ATEBMwHdAf8DKAE9lAADNQFXAVIBhgEqAfABTAGkAQAB/wFMAaQBAAH/AUwBpAEA
165+
Af8BTAGkAQAB/wFMAaQBAAH/AUwBpAEAAf8BWAF2AUMB4wMmATkYAAMgAS8CVgFwAdIBKwEtAdwB/wEu
166+
ATAB3AH/AS4BMAHcAf8BLgEwAdwB/wEuATAB3AH/ASwBLgHcAf8BUgFTAYQB4QMrAUKcAAMPARQCRwFG
167+
AYEBWQFhAVEBxwFbAXMBRgHgAVgBcAFHAd0BVwFdAVQBvwJAAT8BbwMHAQkkAAM7AWUCVAFaAbQCVQF2
168+
AdgCVwF6AdoCVgFgAb0DQQFyAwgBC/8AkQABQgFNAT4HAAE+AwABKAMAAUADAAEQAwABAQEAAQEFAAGA
169+
FwAD/wEABP8EAAH4AR8B8AEPBAAB4AEHAeABBwQAAcABAwHAAQMEAAGAAQMBwAEBBAABgAEBAYABAQQA
170+
AYABAQGAAQEEAAGAAQEBgAEBBAABgAEBAYABAQQAAYABAQGAAQEEAAGAAQEBgAEBBAABgAEDAcABAQQA
171+
AcABAwHAAQMEAAHgAQcB4AEHBAAB8AEPAfgBDwQABP8EAAs=
172172
</value>
173173
</data>
174174
<metadata name="alertsMenu.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">

Source/Forms/NotificationForm.Designer.cs

Lines changed: 45 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Source/Forms/NotificationForm.cs

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
using System;
2+
using System.Drawing;
3+
using System.Threading.Tasks;
4+
using System.Windows.Forms;
5+
6+
namespace ScriptFUSION.WarframeAlertTracker.Forms {
7+
public partial class NotificationForm : Form {
8+
private const int ANIMATION_TICK_FREQUENCY = 2;
9+
10+
private Control childControl;
11+
12+
public Control ChildControl
13+
{
14+
get => childControl;
15+
private set
16+
{
17+
value.Anchor = AnchorStyles.Left;
18+
Controls.Add(childControl = value);
19+
}
20+
}
21+
22+
// Do not steal focus when shown.
23+
protected override bool ShowWithoutActivation => true;
24+
25+
protected override CreateParams CreateParams
26+
{
27+
get
28+
{
29+
const int WS_EX_TOPMOST = 8;
30+
31+
var baseParams = base.CreateParams;
32+
// Force window to be top-most, without stealing focus as TopMost property does.
33+
baseParams.ExStyle |= WS_EX_TOPMOST;
34+
35+
return baseParams;
36+
}
37+
}
38+
39+
/// <summary>
40+
/// Gets or sets the animation time in seconds.
41+
/// </summary>
42+
private double AnimationTime { get; } = .5;
43+
44+
private double HoldTime { get; } = 2.5;
45+
46+
public NotificationForm(Control childControl) {
47+
InitializeComponent();
48+
49+
ChildControl = childControl;
50+
}
51+
52+
private enum SlideDirection {
53+
/// <summary>
54+
/// Slide into view.
55+
/// </summary>
56+
In,
57+
58+
/// <summary>
59+
/// Slide out of view.
60+
/// </summary>
61+
Out
62+
}
63+
64+
private async Task Animate() {
65+
var target = ChildControl;
66+
var screen = Screen.FromHandle(Owner.Handle).Bounds;
67+
68+
void ShowWindow(double portion) {
69+
var width = (int)Math.Round(target.Width * portion);
70+
71+
Size = new Size(
72+
screen.Width - width,
73+
target.Height
74+
);
75+
Location = new Point(
76+
screen.Right - width,
77+
screen.Height / 2 - target.Height / 2
78+
);
79+
}
80+
81+
async Task Slide(SlideDirection direction) {
82+
var animationTime = TimeSpan.FromSeconds(AnimationTime);
83+
var finishTime = DateTime.Now.Add(animationTime);
84+
85+
while (DateTime.Now < finishTime) {
86+
var portion = (finishTime - DateTime.Now).TotalMilliseconds / animationTime.TotalMilliseconds;
87+
if (direction == SlideDirection.In) portion = 1 - portion;
88+
ShowWindow(portion);
89+
90+
await Task.Delay(ANIMATION_TICK_FREQUENCY);
91+
}
92+
}
93+
94+
// Animate in.
95+
await Slide(SlideDirection.In);
96+
97+
// Ensure window completely visible.
98+
ShowWindow(1);
99+
await Task.Delay((int)(HoldTime * 1000));
100+
101+
// Animate out.
102+
await Slide(SlideDirection.Out);
103+
}
104+
105+
private async void NotificationForm_Load(object sender, EventArgs e) {
106+
try {
107+
await Animate();
108+
}
109+
catch (ObjectDisposedException) {
110+
// Continue closing the form.
111+
}
112+
113+
Close();
114+
}
115+
116+
private void NotificationForm_FormClosed(object sender, FormClosedEventArgs e) {
117+
Controls.Remove(ChildControl);
118+
}
119+
}
120+
}

0 commit comments

Comments
 (0)