From a7dcf3611c3d5b57d4f474636eccc2a2c646a58f Mon Sep 17 00:00:00 2001 From: mshafer1 <2565361+mshafer1@users.noreply.github.com> Date: Fri, 20 Dec 2024 11:29:22 -0600 Subject: [PATCH 01/41] make tray pop up and make it work --- ntfysh_client/MainForm.cs | 7 +- ntfysh_client/NotificationDialog.Designer.cs | 85 +++++++++++++ ntfysh_client/NotificationDialog.cs | 84 +++++++++++++ ntfysh_client/NotificationDialog.resx | 120 +++++++++++++++++++ 4 files changed, 295 insertions(+), 1 deletion(-) create mode 100644 ntfysh_client/NotificationDialog.Designer.cs create mode 100644 ntfysh_client/NotificationDialog.cs create mode 100644 ntfysh_client/NotificationDialog.resx diff --git a/ntfysh_client/MainForm.cs b/ntfysh_client/MainForm.cs index cc2cdfa..465c960 100644 --- a/ntfysh_client/MainForm.cs +++ b/ntfysh_client/MainForm.cs @@ -16,6 +16,7 @@ namespace ntfysh_client private readonly NotificationListener _notificationListener; private bool _startInTray; private bool _trueExit; + private NotificationDialog notificationDialog; public MainForm(NotificationListener notificationListener, bool startInTray = false) { @@ -32,6 +33,8 @@ namespace ntfysh_client { LoadSettings(); LoadTopics(); + + this.notificationDialog = new NotificationDialog(); } protected override void SetVisibleCore(bool value) @@ -70,7 +73,9 @@ namespace ntfysh_client string finalTitle = string.IsNullOrWhiteSpace(e.Title) ? $"{e.Sender.TopicId}@{e.Sender.ServerUrl}" : e.Title; - notifyIcon.ShowBalloonTip((int)TimeSpan.FromSeconds((double)Program.Settings.Timeout).TotalMilliseconds, finalTitle, e.Message, priorityIcon); + //notifyIcon.ShowBalloonTip((int)TimeSpan.FromSeconds((double)Program.Settings.Timeout).TotalMilliseconds, finalTitle, e.Message, priorityIcon); + //this.notificationDialog.IsVisible = true; + this.notificationDialog.ShowNotification(finalTitle, e.Message); } private void OnConnectionMultiAttemptFailure(NotificationListener sender, SubscribedTopic topic) diff --git a/ntfysh_client/NotificationDialog.Designer.cs b/ntfysh_client/NotificationDialog.Designer.cs new file mode 100644 index 0000000..8025dd2 --- /dev/null +++ b/ntfysh_client/NotificationDialog.Designer.cs @@ -0,0 +1,85 @@ +namespace ntfysh_client +{ + partial class NotificationDialog + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + tbTitle = new System.Windows.Forms.TextBox(); + button1 = new System.Windows.Forms.Button(); + tbMessage = new System.Windows.Forms.TextBox(); + SuspendLayout(); + // + // tbTitle + // + tbTitle.Location = new System.Drawing.Point(12, 58); + tbTitle.Name = "tbTitle"; + tbTitle.ReadOnly = true; + tbTitle.Size = new System.Drawing.Size(725, 23); + tbTitle.TabIndex = 0; + // + // button1 + // + button1.Location = new System.Drawing.Point(759, 7); + button1.Name = "button1"; + button1.Size = new System.Drawing.Size(29, 38); + button1.TabIndex = 1; + button1.Text = "x"; + button1.UseVisualStyleBackColor = true; + button1.Click += btnClose_Click; + // + // tbMessage + // + tbMessage.Location = new System.Drawing.Point(12, 97); + tbMessage.Multiline = true; + tbMessage.Name = "tbMessage"; + tbMessage.ReadOnly = true; + tbMessage.Size = new System.Drawing.Size(725, 253); + tbMessage.TabIndex = 2; + // + // NotificationDialog + // + AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); + AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + BackColor = System.Drawing.SystemColors.ControlDark; + ClientSize = new System.Drawing.Size(800, 450); + Controls.Add(tbMessage); + Controls.Add(button1); + Controls.Add(tbTitle); + FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; + Name = "NotificationDialog"; + Text = "NotificationDialog"; + ResumeLayout(false); + PerformLayout(); + } + + #endregion + + private System.Windows.Forms.TextBox tbTitle; + private System.Windows.Forms.Button button1; + private System.Windows.Forms.TextBox tbMessage; + } +} \ No newline at end of file diff --git a/ntfysh_client/NotificationDialog.cs b/ntfysh_client/NotificationDialog.cs new file mode 100644 index 0000000..81767e2 --- /dev/null +++ b/ntfysh_client/NotificationDialog.cs @@ -0,0 +1,84 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Runtime.InteropServices; +using System.Security.Cryptography.X509Certificates; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using static System.Windows.Forms.VisualStyles.VisualStyleElement; + +namespace ntfysh_client +{ + public partial class NotificationDialog : Form + { + [DllImport("user32.dll", CharSet = CharSet.Auto)] + private static extern bool AnimateWindow(IntPtr hWnd, int time, int flags); + + private const int ScreenMargin = 20; + + private void SetWindowPosition() + { + int workingtop = Screen.PrimaryScreen.WorkingArea.Height - this.Height; + this.Top = workingtop - NotificationDialog.ScreenMargin; + + int workingleft = Screen.PrimaryScreen.WorkingArea.Width - this.Width; + this.Left = workingleft - NotificationDialog.ScreenMargin; + } + + protected override void SetVisibleCore(bool value) + { + //base.SetVisibleCore(false); + this.SetWindowPosition(); + if (value) + { + this.BringToFront(); + AnimateWindow(this.Handle, 250, 0x00040000 | 0x00000008); + } + base.SetVisibleCore(value); + } + + public void ShowNotification(string title, string message) + { + this.tbTitle.Text = title; + this.tbMessage.Text = message; + this.Show(); + this.SetWindowPosition(); + } + + public bool IsVisible + { + get { return this.Visible; } + set { this.Visible = value; } + } + + protected override void OnShown(EventArgs e) + { + + base.OnShown(e); + } + + public NotificationDialog() + { + this.IsVisible = false; + InitializeComponent(); + InitializeWindowHidden(); + } + + private void InitializeWindowHidden() + { + this.Opacity = 0; + this.ShowNotification("Title", "Message"); + this.IsVisible = false; + this.Opacity = 1; + } + + private void btnClose_Click(object sender, EventArgs e) + { + this.IsVisible = false; + } + } +} diff --git a/ntfysh_client/NotificationDialog.resx b/ntfysh_client/NotificationDialog.resx new file mode 100644 index 0000000..8b2ff64 --- /dev/null +++ b/ntfysh_client/NotificationDialog.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file -- 2.49.1 From 3e43002b47336173a8736ecac4ad79370f66d308 Mon Sep 17 00:00:00 2001 From: mshafer1 <2565361+mshafer1@users.noreply.github.com> Date: Fri, 20 Dec 2024 12:10:12 -0600 Subject: [PATCH 02/41] work on appearance of notification --- ntfysh_client/NotificationDialog.Designer.cs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/ntfysh_client/NotificationDialog.Designer.cs b/ntfysh_client/NotificationDialog.Designer.cs index 8025dd2..9cb3494 100644 --- a/ntfysh_client/NotificationDialog.Designer.cs +++ b/ntfysh_client/NotificationDialog.Designer.cs @@ -35,24 +35,34 @@ // // tbTitle // - tbTitle.Location = new System.Drawing.Point(12, 58); + tbTitle.BackColor = System.Drawing.SystemColors.ControlDark; + tbTitle.BorderStyle = System.Windows.Forms.BorderStyle.None; + tbTitle.Font = new System.Drawing.Font("Segoe UI", 18F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + tbTitle.Location = new System.Drawing.Point(12, 19); tbTitle.Name = "tbTitle"; tbTitle.ReadOnly = true; - tbTitle.Size = new System.Drawing.Size(725, 23); + tbTitle.Size = new System.Drawing.Size(725, 32); tbTitle.TabIndex = 0; // // button1 // + button1.BackColor = System.Drawing.SystemColors.ActiveCaptionText; + button1.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; + button1.FlatStyle = System.Windows.Forms.FlatStyle.Popup; + button1.ForeColor = System.Drawing.SystemColors.ButtonFace; button1.Location = new System.Drawing.Point(759, 7); button1.Name = "button1"; button1.Size = new System.Drawing.Size(29, 38); button1.TabIndex = 1; button1.Text = "x"; - button1.UseVisualStyleBackColor = true; + button1.UseVisualStyleBackColor = false; button1.Click += btnClose_Click; // // tbMessage // + tbMessage.BackColor = System.Drawing.SystemColors.ControlDark; + tbMessage.BorderStyle = System.Windows.Forms.BorderStyle.None; + tbMessage.Font = new System.Drawing.Font("Segoe UI", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); tbMessage.Location = new System.Drawing.Point(12, 97); tbMessage.Multiline = true; tbMessage.Name = "tbMessage"; -- 2.49.1 From f5298e1a4efd866e7e6e922038ccc3652054a57d Mon Sep 17 00:00:00 2001 From: mshafer1 <2565361+mshafer1@users.noreply.github.com> Date: Fri, 20 Dec 2024 12:11:07 -0600 Subject: [PATCH 03/41] get timeout working --- ntfysh_client/MainForm.cs | 2 +- ntfysh_client/NotificationDialog.cs | 43 ++++++++++++++++++++++-- ntfysh_client/SettingsDialog.Designer.cs | 2 +- 3 files changed, 43 insertions(+), 4 deletions(-) diff --git a/ntfysh_client/MainForm.cs b/ntfysh_client/MainForm.cs index 465c960..332dfe6 100644 --- a/ntfysh_client/MainForm.cs +++ b/ntfysh_client/MainForm.cs @@ -75,7 +75,7 @@ namespace ntfysh_client //notifyIcon.ShowBalloonTip((int)TimeSpan.FromSeconds((double)Program.Settings.Timeout).TotalMilliseconds, finalTitle, e.Message, priorityIcon); //this.notificationDialog.IsVisible = true; - this.notificationDialog.ShowNotification(finalTitle, e.Message); + this.notificationDialog.ShowNotification(finalTitle, e.Message, (int)TimeSpan.FromSeconds((double)Program.Settings.Timeout).TotalMilliseconds); } private void OnConnectionMultiAttemptFailure(NotificationListener sender, SubscribedTopic topic) diff --git a/ntfysh_client/NotificationDialog.cs b/ntfysh_client/NotificationDialog.cs index 81767e2..b790a4d 100644 --- a/ntfysh_client/NotificationDialog.cs +++ b/ntfysh_client/NotificationDialog.cs @@ -20,6 +20,8 @@ namespace ntfysh_client private const int ScreenMargin = 20; + private System.Timers.Timer? timer = null; + private void SetWindowPosition() { int workingtop = Screen.PrimaryScreen.WorkingArea.Height - this.Height; @@ -31,6 +33,7 @@ namespace ntfysh_client protected override void SetVisibleCore(bool value) { + //base.SetVisibleCore(false); this.SetWindowPosition(); if (value) @@ -41,8 +44,43 @@ namespace ntfysh_client base.SetVisibleCore(value); } - public void ShowNotification(string title, string message) + private void ui_hide_window(object? sender, EventArgs e) { + AnimateWindow(this.Handle, 250, 0x00040000 | 0x00000004 | 0x00010000); + this.IsVisible = false; + } + + private void handleTimeout(object? sender, EventArgs e) + { + if (this.timer != null) + { + this.timer.Stop(); + this.timer.Dispose(); + this.timer = null; + } + if (this.InvokeRequired) + { + this.Invoke(new Action(() => this.ui_hide_window(sender, e))); + } + else + { + this.ui_hide_window(sender, e); + } + } + + public void ShowNotification(string title, string message, int timeout_ms=-1) + { + if (this.timer != null) + { + this.timer.Stop(); + this.timer.Dispose(); + } + if (timeout_ms > 0) + { + this.timer = new System.Timers.Timer(timeout_ms); + timer.Elapsed += handleTimeout; + this.timer.Start(); + } this.tbTitle.Text = title; this.tbMessage.Text = message; this.Show(); @@ -57,13 +95,13 @@ namespace ntfysh_client protected override void OnShown(EventArgs e) { - base.OnShown(e); } public NotificationDialog() { this.IsVisible = false; + this.TopMost = true; InitializeComponent(); InitializeWindowHidden(); } @@ -78,6 +116,7 @@ namespace ntfysh_client private void btnClose_Click(object sender, EventArgs e) { + // immediate this.IsVisible = false; } } diff --git a/ntfysh_client/SettingsDialog.Designer.cs b/ntfysh_client/SettingsDialog.Designer.cs index 8f240fe..5d07b2a 100644 --- a/ntfysh_client/SettingsDialog.Designer.cs +++ b/ntfysh_client/SettingsDialog.Designer.cs @@ -84,7 +84,7 @@ namespace ntfysh_client timeoutLabel.Name = "timeoutLabel"; timeoutLabel.Size = new System.Drawing.Size(488, 15); timeoutLabel.TabIndex = 3; - timeoutLabel.Text = "Notification Toast Timeout (seconds, may be ignored by OS based on accessibility settings):"; + timeoutLabel.Text = "Notification Toast Timeout (seconds, use -1 to require closing notification):"; // // timeout // -- 2.49.1 From e24ef645acf70eae1d06c1dc55767d36882c82e2 Mon Sep 17 00:00:00 2001 From: mshafer1 <2565361+mshafer1@users.noreply.github.com> Date: Fri, 20 Dec 2024 13:32:19 -0600 Subject: [PATCH 04/41] implement icon --- ntfysh_client/MainForm.cs | 4 +--- ntfysh_client/NotificationDialog.Designer.cs | 17 ++++++++++++-- ntfysh_client/NotificationDialog.cs | 24 +++++++++++++++++++- 3 files changed, 39 insertions(+), 6 deletions(-) diff --git a/ntfysh_client/MainForm.cs b/ntfysh_client/MainForm.cs index 332dfe6..d5906bd 100644 --- a/ntfysh_client/MainForm.cs +++ b/ntfysh_client/MainForm.cs @@ -73,9 +73,7 @@ namespace ntfysh_client string finalTitle = string.IsNullOrWhiteSpace(e.Title) ? $"{e.Sender.TopicId}@{e.Sender.ServerUrl}" : e.Title; - //notifyIcon.ShowBalloonTip((int)TimeSpan.FromSeconds((double)Program.Settings.Timeout).TotalMilliseconds, finalTitle, e.Message, priorityIcon); - //this.notificationDialog.IsVisible = true; - this.notificationDialog.ShowNotification(finalTitle, e.Message, (int)TimeSpan.FromSeconds((double)Program.Settings.Timeout).TotalMilliseconds); + this.notificationDialog.ShowNotification(finalTitle, e.Message, (int)TimeSpan.FromSeconds((double)Program.Settings.Timeout).TotalMilliseconds, priorityIcon); } private void OnConnectionMultiAttemptFailure(NotificationListener sender, SubscribedTopic topic) diff --git a/ntfysh_client/NotificationDialog.Designer.cs b/ntfysh_client/NotificationDialog.Designer.cs index 9cb3494..8718f50 100644 --- a/ntfysh_client/NotificationDialog.Designer.cs +++ b/ntfysh_client/NotificationDialog.Designer.cs @@ -31,6 +31,8 @@ tbTitle = new System.Windows.Forms.TextBox(); button1 = new System.Windows.Forms.Button(); tbMessage = new System.Windows.Forms.TextBox(); + iconBox = new System.Windows.Forms.PictureBox(); + ((System.ComponentModel.ISupportInitialize)iconBox).BeginInit(); SuspendLayout(); // // tbTitle @@ -38,10 +40,10 @@ tbTitle.BackColor = System.Drawing.SystemColors.ControlDark; tbTitle.BorderStyle = System.Windows.Forms.BorderStyle.None; tbTitle.Font = new System.Drawing.Font("Segoe UI", 18F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - tbTitle.Location = new System.Drawing.Point(12, 19); + tbTitle.Location = new System.Drawing.Point(54, 13); tbTitle.Name = "tbTitle"; tbTitle.ReadOnly = true; - tbTitle.Size = new System.Drawing.Size(725, 32); + tbTitle.Size = new System.Drawing.Size(683, 32); tbTitle.TabIndex = 0; // // button1 @@ -70,18 +72,28 @@ tbMessage.Size = new System.Drawing.Size(725, 253); tbMessage.TabIndex = 2; // + // iconBox + // + iconBox.Location = new System.Drawing.Point(12, 12); + iconBox.Name = "iconBox"; + iconBox.Size = new System.Drawing.Size(36, 39); + iconBox.TabIndex = 3; + iconBox.TabStop = false; + // // NotificationDialog // AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; BackColor = System.Drawing.SystemColors.ControlDark; ClientSize = new System.Drawing.Size(800, 450); + Controls.Add(iconBox); Controls.Add(tbMessage); Controls.Add(button1); Controls.Add(tbTitle); FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; Name = "NotificationDialog"; Text = "NotificationDialog"; + ((System.ComponentModel.ISupportInitialize)iconBox).EndInit(); ResumeLayout(false); PerformLayout(); } @@ -91,5 +103,6 @@ private System.Windows.Forms.TextBox tbTitle; private System.Windows.Forms.Button button1; private System.Windows.Forms.TextBox tbMessage; + private System.Windows.Forms.PictureBox iconBox; } } \ No newline at end of file diff --git a/ntfysh_client/NotificationDialog.cs b/ntfysh_client/NotificationDialog.cs index b790a4d..aac9b97 100644 --- a/ntfysh_client/NotificationDialog.cs +++ b/ntfysh_client/NotificationDialog.cs @@ -21,6 +21,7 @@ namespace ntfysh_client private const int ScreenMargin = 20; private System.Timers.Timer? timer = null; + private ToolTipIcon? _icon; private void SetWindowPosition() { @@ -68,8 +69,13 @@ namespace ntfysh_client } } - public void ShowNotification(string title, string message, int timeout_ms=-1) + public void ShowNotification(string title, string message, int timeout_ms = -1, ToolTipIcon? icon = null) { + this._icon = icon; + if (this._icon != null) + { + this.iconBox.Image = ConvertToolTipIconToImage(_icon.Value); + } if (this.timer != null) { this.timer.Stop(); @@ -87,6 +93,22 @@ namespace ntfysh_client this.SetWindowPosition(); } + private Image? ConvertToolTipIconToImage(ToolTipIcon icon) + { + switch (icon) + { + case ToolTipIcon.Info: + return SystemIcons.Information.ToBitmap(); + case ToolTipIcon.Warning: + return SystemIcons.Warning.ToBitmap(); + case ToolTipIcon.Error: + return SystemIcons.Error.ToBitmap(); + case ToolTipIcon.None: + default: + return null; + } + } + public bool IsVisible { get { return this.Visible; } -- 2.49.1 From 8ec1a89941a08ae6d9e4ebf540c973f4bdfa37aa Mon Sep 17 00:00:00 2001 From: mshafer1 <2565361+mshafer1@users.noreply.github.com> Date: Fri, 20 Dec 2024 15:46:08 -0600 Subject: [PATCH 05/41] create a constants class to manage flag names --- ntfysh_client/NotificationDialog.cs | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/ntfysh_client/NotificationDialog.cs b/ntfysh_client/NotificationDialog.cs index aac9b97..5962398 100644 --- a/ntfysh_client/NotificationDialog.cs +++ b/ntfysh_client/NotificationDialog.cs @@ -40,14 +40,22 @@ namespace ntfysh_client if (value) { this.BringToFront(); - AnimateWindow(this.Handle, 250, 0x00040000 | 0x00000008); + AnimateWindow( + this.Handle, + time: 250, + flags: NFWinUserAnimateWindowConstnats.AW_SLIDE | NFWinUserAnimateWindowConstnats.AW_VER_NEGATIVE + ); } base.SetVisibleCore(value); } private void ui_hide_window(object? sender, EventArgs e) { - AnimateWindow(this.Handle, 250, 0x00040000 | 0x00000004 | 0x00010000); + AnimateWindow( + this.Handle, + time: 250, + flags: NFWinUserAnimateWindowConstnats.AW_SLIDE | NFWinUserAnimateWindowConstnats.AW_VER_POSITIVE | NFWinUserAnimateWindowConstnats.AW_HIDE + ); this.IsVisible = false; } @@ -141,5 +149,17 @@ namespace ntfysh_client // immediate this.IsVisible = false; } + private class NFWinUserAnimateWindowConstnats + { + public const int AW_HOR_POSITIVE = 0x00000001; + public const int AW_HOR_NEGATIVE = 0x00000002; + public const int AW_VER_POSITIVE = 0x00000004; + public const int AW_VER_NEGATIVE = 0x00000008; + public const int AW_CENTER = 0x00000010; + public const int AW_HIDE = 0x00010000; + public const int AW_ACTIVATE = 0x00020000; + public const int AW_SLIDE = 0x00040000; + public const int AW_BLEND = 0x00080000; + } } } -- 2.49.1 From 8c04e82dac28b9fd38f1048ae8187c5967d36d55 Mon Sep 17 00:00:00 2001 From: mshafer1 <2565361+mshafer1@users.noreply.github.com> Date: Fri, 20 Dec 2024 15:49:16 -0600 Subject: [PATCH 06/41] rearrange file to properties, public, protected, private --- ntfysh_client/NotificationDialog.cs | 133 ++++++++++++++-------------- 1 file changed, 67 insertions(+), 66 deletions(-) diff --git a/ntfysh_client/NotificationDialog.cs b/ntfysh_client/NotificationDialog.cs index 5962398..56ffe1c 100644 --- a/ntfysh_client/NotificationDialog.cs +++ b/ntfysh_client/NotificationDialog.cs @@ -23,58 +23,18 @@ namespace ntfysh_client private System.Timers.Timer? timer = null; private ToolTipIcon? _icon; - private void SetWindowPosition() + public bool IsVisible { - int workingtop = Screen.PrimaryScreen.WorkingArea.Height - this.Height; - this.Top = workingtop - NotificationDialog.ScreenMargin; - - int workingleft = Screen.PrimaryScreen.WorkingArea.Width - this.Width; - this.Left = workingleft - NotificationDialog.ScreenMargin; + get { return this.Visible; } + set { this.Visible = value; } } - protected override void SetVisibleCore(bool value) + public NotificationDialog() { - - //base.SetVisibleCore(false); - this.SetWindowPosition(); - if (value) - { - this.BringToFront(); - AnimateWindow( - this.Handle, - time: 250, - flags: NFWinUserAnimateWindowConstnats.AW_SLIDE | NFWinUserAnimateWindowConstnats.AW_VER_NEGATIVE - ); - } - base.SetVisibleCore(value); - } - - private void ui_hide_window(object? sender, EventArgs e) - { - AnimateWindow( - this.Handle, - time: 250, - flags: NFWinUserAnimateWindowConstnats.AW_SLIDE | NFWinUserAnimateWindowConstnats.AW_VER_POSITIVE | NFWinUserAnimateWindowConstnats.AW_HIDE - ); this.IsVisible = false; - } - - private void handleTimeout(object? sender, EventArgs e) - { - if (this.timer != null) - { - this.timer.Stop(); - this.timer.Dispose(); - this.timer = null; - } - if (this.InvokeRequired) - { - this.Invoke(new Action(() => this.ui_hide_window(sender, e))); - } - else - { - this.ui_hide_window(sender, e); - } + this.TopMost = true; + InitializeComponent(); + InitializeWindowHidden(); } public void ShowNotification(string title, string message, int timeout_ms = -1, ToolTipIcon? icon = null) @@ -101,6 +61,65 @@ namespace ntfysh_client this.SetWindowPosition(); } + protected override void SetVisibleCore(bool value) + { + this.SetWindowPosition(); + if (value) + { + this.BringToFront(); + AnimateWindow( + this.Handle, + time: 250, + flags: NFWinUserAnimateWindowConstnats.AW_SLIDE | NFWinUserAnimateWindowConstnats.AW_VER_NEGATIVE + ); + } + base.SetVisibleCore(value); + } + + protected override void OnShown(EventArgs e) + { + base.OnShown(e); + } + + private void SetWindowPosition() + { + int workingtop = Screen.PrimaryScreen.WorkingArea.Height - this.Height; + this.Top = workingtop - NotificationDialog.ScreenMargin; + + int workingleft = Screen.PrimaryScreen.WorkingArea.Width - this.Width; + this.Left = workingleft - NotificationDialog.ScreenMargin; + } + + private void ui_hide_window(object? sender, EventArgs e) + { + AnimateWindow( + this.Handle, + time: 250, + flags: NFWinUserAnimateWindowConstnats.AW_SLIDE | NFWinUserAnimateWindowConstnats.AW_VER_POSITIVE | NFWinUserAnimateWindowConstnats.AW_HIDE + ); + this.IsVisible = false; + } + + private void handleTimeout(object? sender, EventArgs e) + { + if (this.timer != null) // check if the timer has already been disposed + { + this.timer.Stop(); + this.timer.Dispose(); + this.timer = null; + } + if (this.InvokeRequired) + { + // on a background thread, so invoke on the UI thread + this.Invoke(new Action(() => this.ui_hide_window(sender, e))); + } + else + { + // in the UI thread, invoke directly + this.ui_hide_window(sender, e); + } + } + private Image? ConvertToolTipIconToImage(ToolTipIcon icon) { switch (icon) @@ -117,25 +136,6 @@ namespace ntfysh_client } } - public bool IsVisible - { - get { return this.Visible; } - set { this.Visible = value; } - } - - protected override void OnShown(EventArgs e) - { - base.OnShown(e); - } - - public NotificationDialog() - { - this.IsVisible = false; - this.TopMost = true; - InitializeComponent(); - InitializeWindowHidden(); - } - private void InitializeWindowHidden() { this.Opacity = 0; @@ -149,6 +149,7 @@ namespace ntfysh_client // immediate this.IsVisible = false; } + private class NFWinUserAnimateWindowConstnats { public const int AW_HOR_POSITIVE = 0x00000001; -- 2.49.1 From c8ba64f5d831ea2e393566a439e291984ced1c28 Mon Sep 17 00:00:00 2001 From: mshafer1 <2565361+mshafer1@users.noreply.github.com> Date: Fri, 20 Dec 2024 15:49:42 -0600 Subject: [PATCH 07/41] remove unused imports --- ntfysh_client/NotificationDialog.cs | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/ntfysh_client/NotificationDialog.cs b/ntfysh_client/NotificationDialog.cs index 56ffe1c..fb69764 100644 --- a/ntfysh_client/NotificationDialog.cs +++ b/ntfysh_client/NotificationDialog.cs @@ -1,15 +1,8 @@ using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Data; using System.Drawing; -using System.Linq; using System.Runtime.InteropServices; -using System.Security.Cryptography.X509Certificates; -using System.Text; -using System.Threading.Tasks; using System.Windows.Forms; -using static System.Windows.Forms.VisualStyles.VisualStyleElement; + namespace ntfysh_client { -- 2.49.1 From a8af6ce48e58fb52aec79170ba34c8ed56cef3dc Mon Sep 17 00:00:00 2001 From: mshafer1 <2565361+mshafer1@users.noreply.github.com> Date: Fri, 20 Dec 2024 15:53:22 -0600 Subject: [PATCH 08/41] if already visible, hide then show ideally, we would stack multiple up each with its own timeout and close event. For now, this just makes a pop up for the new message. --- ntfysh_client/NotificationDialog.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/ntfysh_client/NotificationDialog.cs b/ntfysh_client/NotificationDialog.cs index fb69764..c94244d 100644 --- a/ntfysh_client/NotificationDialog.cs +++ b/ntfysh_client/NotificationDialog.cs @@ -32,6 +32,10 @@ namespace ntfysh_client public void ShowNotification(string title, string message, int timeout_ms = -1, ToolTipIcon? icon = null) { + if (this.IsVisible) + { + this.handleTimeout(null, null); + } this._icon = icon; if (this._icon != null) { @@ -83,7 +87,7 @@ namespace ntfysh_client this.Left = workingleft - NotificationDialog.ScreenMargin; } - private void ui_hide_window(object? sender, EventArgs e) + private void ui_hide_window(object? sender, EventArgs? e) { AnimateWindow( this.Handle, @@ -93,7 +97,7 @@ namespace ntfysh_client this.IsVisible = false; } - private void handleTimeout(object? sender, EventArgs e) + private void handleTimeout(object? sender, EventArgs? e) { if (this.timer != null) // check if the timer has already been disposed { -- 2.49.1 From 9b902f1d38236417ec406351e49925a28e963146 Mon Sep 17 00:00:00 2001 From: mshafer1 <2565361+mshafer1@users.noreply.github.com> Date: Fri, 20 Dec 2024 16:01:15 -0600 Subject: [PATCH 09/41] use a rich text box to get scroll bar if needed and make window a little smaller --- ntfysh_client/NotificationDialog.Designer.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ntfysh_client/NotificationDialog.Designer.cs b/ntfysh_client/NotificationDialog.Designer.cs index 8718f50..681c07c 100644 --- a/ntfysh_client/NotificationDialog.Designer.cs +++ b/ntfysh_client/NotificationDialog.Designer.cs @@ -30,7 +30,7 @@ { tbTitle = new System.Windows.Forms.TextBox(); button1 = new System.Windows.Forms.Button(); - tbMessage = new System.Windows.Forms.TextBox(); + tbMessage = new System.Windows.Forms.RichTextBox(); iconBox = new System.Windows.Forms.PictureBox(); ((System.ComponentModel.ISupportInitialize)iconBox).BeginInit(); SuspendLayout(); @@ -65,12 +65,12 @@ tbMessage.BackColor = System.Drawing.SystemColors.ControlDark; tbMessage.BorderStyle = System.Windows.Forms.BorderStyle.None; tbMessage.Font = new System.Drawing.Font("Segoe UI", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - tbMessage.Location = new System.Drawing.Point(12, 97); - tbMessage.Multiline = true; + tbMessage.Location = new System.Drawing.Point(12, 57); tbMessage.Name = "tbMessage"; tbMessage.ReadOnly = true; - tbMessage.Size = new System.Drawing.Size(725, 253); + tbMessage.Size = new System.Drawing.Size(776, 213); tbMessage.TabIndex = 2; + tbMessage.Text = ""; // // iconBox // @@ -85,7 +85,7 @@ AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; BackColor = System.Drawing.SystemColors.ControlDark; - ClientSize = new System.Drawing.Size(800, 450); + ClientSize = new System.Drawing.Size(800, 289); Controls.Add(iconBox); Controls.Add(tbMessage); Controls.Add(button1); @@ -102,7 +102,7 @@ private System.Windows.Forms.TextBox tbTitle; private System.Windows.Forms.Button button1; - private System.Windows.Forms.TextBox tbMessage; + private System.Windows.Forms.RichTextBox tbMessage; private System.Windows.Forms.PictureBox iconBox; } } \ No newline at end of file -- 2.49.1 From f908e9c4b0eece038a32649f9c705e2a779366c4 Mon Sep 17 00:00:00 2001 From: mshafer1 <2565361+mshafer1@users.noreply.github.com> Date: Fri, 20 Dec 2024 16:16:57 -0600 Subject: [PATCH 10/41] allow a timeout of -1 in settings --- ntfysh_client/SettingsDialog.Designer.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/ntfysh_client/SettingsDialog.Designer.cs b/ntfysh_client/SettingsDialog.Designer.cs index 5d07b2a..a9ccaa0 100644 --- a/ntfysh_client/SettingsDialog.Designer.cs +++ b/ntfysh_client/SettingsDialog.Designer.cs @@ -90,6 +90,7 @@ namespace ntfysh_client // timeout.Location = new System.Drawing.Point(13, 28); timeout.Maximum = new decimal(new int[] { -1981284353, -1966660860, 0, 0 }); + timeout.Minimum = new decimal(new int[] { 1, 0, 0, int.MinValue }); timeout.Name = "timeout"; timeout.Size = new System.Drawing.Size(506, 23); timeout.TabIndex = 4; -- 2.49.1 From 65f27c7c42574f59aa81f597a30dbe88634eaf8f Mon Sep 17 00:00:00 2001 From: mshafer1 <2565361+mshafer1@users.noreply.github.com> Date: Fri, 20 Dec 2024 17:08:53 -0600 Subject: [PATCH 11/41] add a progress bar and timeout text --- ntfysh_client/NotificationDialog.Designer.cs | 42 ++++++- ntfysh_client/NotificationDialog.cs | 122 ++++++++++++++++--- 2 files changed, 147 insertions(+), 17 deletions(-) diff --git a/ntfysh_client/NotificationDialog.Designer.cs b/ntfysh_client/NotificationDialog.Designer.cs index 681c07c..bc34ea4 100644 --- a/ntfysh_client/NotificationDialog.Designer.cs +++ b/ntfysh_client/NotificationDialog.Designer.cs @@ -32,6 +32,8 @@ button1 = new System.Windows.Forms.Button(); tbMessage = new System.Windows.Forms.RichTextBox(); iconBox = new System.Windows.Forms.PictureBox(); + progressBar1 = new System.Windows.Forms.ProgressBar(); + lbTimeout = new System.Windows.Forms.Label(); ((System.ComponentModel.ISupportInitialize)iconBox).BeginInit(); SuspendLayout(); // @@ -40,23 +42,27 @@ tbTitle.BackColor = System.Drawing.SystemColors.ControlDark; tbTitle.BorderStyle = System.Windows.Forms.BorderStyle.None; tbTitle.Font = new System.Drawing.Font("Segoe UI", 18F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + tbTitle.ForeColor = System.Drawing.SystemColors.ControlLightLight; tbTitle.Location = new System.Drawing.Point(54, 13); tbTitle.Name = "tbTitle"; tbTitle.ReadOnly = true; tbTitle.Size = new System.Drawing.Size(683, 32); tbTitle.TabIndex = 0; + tbTitle.MouseDown += window_MouseDown; // // button1 // button1.BackColor = System.Drawing.SystemColors.ActiveCaptionText; button1.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; + button1.FlatAppearance.BorderColor = System.Drawing.Color.White; + button1.FlatAppearance.MouseOverBackColor = System.Drawing.Color.Silver; button1.FlatStyle = System.Windows.Forms.FlatStyle.Popup; button1.ForeColor = System.Drawing.SystemColors.ButtonFace; button1.Location = new System.Drawing.Point(759, 7); button1.Name = "button1"; button1.Size = new System.Drawing.Size(29, 38); button1.TabIndex = 1; - button1.Text = "x"; + button1.Text = "X"; button1.UseVisualStyleBackColor = false; button1.Click += btnClose_Click; // @@ -65,12 +71,14 @@ tbMessage.BackColor = System.Drawing.SystemColors.ControlDark; tbMessage.BorderStyle = System.Windows.Forms.BorderStyle.None; tbMessage.Font = new System.Drawing.Font("Segoe UI", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + tbMessage.ForeColor = System.Drawing.SystemColors.ControlLightLight; tbMessage.Location = new System.Drawing.Point(12, 57); tbMessage.Name = "tbMessage"; tbMessage.ReadOnly = true; - tbMessage.Size = new System.Drawing.Size(776, 213); + tbMessage.Size = new System.Drawing.Size(776, 191); tbMessage.TabIndex = 2; tbMessage.Text = ""; + tbMessage.MouseDown += window_MouseDown; // // iconBox // @@ -80,12 +88,39 @@ iconBox.TabIndex = 3; iconBox.TabStop = false; // + // progressBar1 + // + progressBar1.BackColor = System.Drawing.SystemColors.ControlDarkDark; + progressBar1.Enabled = false; + progressBar1.ForeColor = System.Drawing.SystemColors.WindowFrame; + progressBar1.Location = new System.Drawing.Point(70, 254); + progressBar1.MarqueeAnimationSpeed = 1; + progressBar1.Name = "progressBar1"; + progressBar1.Size = new System.Drawing.Size(718, 23); + progressBar1.Step = 1; + progressBar1.Style = System.Windows.Forms.ProgressBarStyle.Continuous; + progressBar1.TabIndex = 4; + progressBar1.Value = 100; + // + // lbTimeout + // + lbTimeout.AutoSize = true; + lbTimeout.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + lbTimeout.Location = new System.Drawing.Point(21, 254); + lbTimeout.Name = "lbTimeout"; + lbTimeout.Size = new System.Drawing.Size(43, 17); + lbTimeout.TabIndex = 5; + lbTimeout.Text = "label1"; + lbTimeout.TextAlign = System.Drawing.ContentAlignment.TopRight; + // // NotificationDialog // AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; BackColor = System.Drawing.SystemColors.ControlDark; ClientSize = new System.Drawing.Size(800, 289); + Controls.Add(lbTimeout); + Controls.Add(progressBar1); Controls.Add(iconBox); Controls.Add(tbMessage); Controls.Add(button1); @@ -93,6 +128,7 @@ FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; Name = "NotificationDialog"; Text = "NotificationDialog"; + Click += window_MouseDown; ((System.ComponentModel.ISupportInitialize)iconBox).EndInit(); ResumeLayout(false); PerformLayout(); @@ -104,5 +140,7 @@ private System.Windows.Forms.Button button1; private System.Windows.Forms.RichTextBox tbMessage; private System.Windows.Forms.PictureBox iconBox; + private System.Windows.Forms.ProgressBar progressBar1; + private System.Windows.Forms.Label lbTimeout; } } \ No newline at end of file diff --git a/ntfysh_client/NotificationDialog.cs b/ntfysh_client/NotificationDialog.cs index c94244d..7607eff 100644 --- a/ntfysh_client/NotificationDialog.cs +++ b/ntfysh_client/NotificationDialog.cs @@ -2,6 +2,9 @@ using System.Drawing; using System.Runtime.InteropServices; using System.Windows.Forms; +using System.ComponentModel; +using Microsoft.Win32; +using System.Diagnostics; namespace ntfysh_client @@ -13,8 +16,21 @@ namespace ntfysh_client private const int ScreenMargin = 20; - private System.Timers.Timer? timer = null; + private int _timeout = 0; + private System.Timers.Timer? displayTimeoutTimer = null; + private System.Windows.Forms.Timer? updateTimer = null; + private Stopwatch? shownStopwatch = null; private ToolTipIcon? _icon; + private int _progress_value = 0; + private int progress + { + get { return this._progress_value; } + set + { + this._progress_value = value; + this.progressBar1.Value = value; + } + } public bool IsVisible { @@ -34,30 +50,69 @@ namespace ntfysh_client { if (this.IsVisible) { + // close the current notification this.handleTimeout(null, null); } + // setup data this._icon = icon; if (this._icon != null) { this.iconBox.Image = ConvertToolTipIconToImage(_icon.Value); } - if (this.timer != null) + this.tbTitle.Text = title; + this.tbMessage.Text = message; + + // setup timers + if (this.displayTimeoutTimer != null) { - this.timer.Stop(); - this.timer.Dispose(); + this.displayTimeoutTimer.Stop(); + this.displayTimeoutTimer.Dispose(); + } + if (this.updateTimer != null) + { + this.updateTimer.Stop(); + this.updateTimer.Dispose(); } if (timeout_ms > 0) { - this.timer = new System.Timers.Timer(timeout_ms); - timer.Elapsed += handleTimeout; - this.timer.Start(); + this.displayTimeoutTimer = new System.Timers.Timer(timeout_ms); + displayTimeoutTimer.Elapsed += handleTimeout; + this.displayTimeoutTimer.Start(); + + this.progress = 100; + this.updateTimer = new System.Windows.Forms.Timer(); + updateTimer.Interval = 100; + this.updateTimer.Tick += this.UpdateProgress; + this.updateTimer.Start(); + + this.shownStopwatch = new Stopwatch(); + this.shownStopwatch.Start(); + + this.progressBar1.Visible = true; + this.lbTimeout.Visible = true; + this._timeout = timeout_ms; } - this.tbTitle.Text = title; - this.tbMessage.Text = message; + else + { + this.progressBar1.Visible = false; + this.lbTimeout.Visible = false; + } + + // ok, show the window this.Show(); this.SetWindowPosition(); } + private void UpdateProgress(object? sender, EventArgs e) + { + if (this.shownStopwatch == null) + { + return; + } + this.progress = (int)((this._timeout - this.shownStopwatch.ElapsedMilliseconds) * 100 / this._timeout); + this.lbTimeout.Text = $"{(int)(this._timeout - this.shownStopwatch.ElapsedMilliseconds) / 1000}"; + } + protected override void SetVisibleCore(bool value) { this.SetWindowPosition(); @@ -99,12 +154,7 @@ namespace ntfysh_client private void handleTimeout(object? sender, EventArgs? e) { - if (this.timer != null) // check if the timer has already been disposed - { - this.timer.Stop(); - this.timer.Dispose(); - this.timer = null; - } + this.cancelTimer(); if (this.InvokeRequired) { // on a background thread, so invoke on the UI thread @@ -159,5 +209,47 @@ namespace ntfysh_client public const int AW_SLIDE = 0x00040000; public const int AW_BLEND = 0x00080000; } + + private void window_MouseDown(object sender, EventArgs e) + { + this.cancelTimer(); + } + + private void cancelTimer() + { + if (this.InvokeRequired) + { + // on a background thread, so invoke on the UI thread + this.Invoke(new Action(() => + { + this.lbTimeout.Visible = false; + this.progressBar1.Visible = false; + })); + } + else + { + // in the UI thread, invoke directly + this.lbTimeout.Visible = false; + this.progressBar1.Visible = false; + } + + if (this.displayTimeoutTimer != null) // check if the timer has already been disposed + { + this.displayTimeoutTimer.Stop(); + this.displayTimeoutTimer.Dispose(); + this.displayTimeoutTimer = null; + } + if (this.updateTimer != null) + { + this.updateTimer.Stop(); + this.updateTimer.Dispose(); + this.updateTimer = null; + } + if (this.shownStopwatch != null) + { + this.shownStopwatch.Stop(); + this.shownStopwatch = null; + } + } } } -- 2.49.1 From 7c5bb6f862b44341ddab954fb38d66e893351879 Mon Sep 17 00:00:00 2001 From: mshafer1 <2565361+mshafer1@users.noreply.github.com> Date: Fri, 20 Dec 2024 17:47:56 -0600 Subject: [PATCH 12/41] don't show notification window in task bar --- ntfysh_client/NotificationDialog.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/ntfysh_client/NotificationDialog.cs b/ntfysh_client/NotificationDialog.cs index 7607eff..8729bba 100644 --- a/ntfysh_client/NotificationDialog.cs +++ b/ntfysh_client/NotificationDialog.cs @@ -40,6 +40,7 @@ namespace ntfysh_client public NotificationDialog() { + this.ShowInTaskbar = false; this.IsVisible = false; this.TopMost = true; InitializeComponent(); -- 2.49.1 From 93ac99dd7c8a7c5fbd2226fba3b71d39bb119b54 Mon Sep 17 00:00:00 2001 From: mshafer1 <2565361+mshafer1@users.noreply.github.com> Date: Fri, 20 Dec 2024 21:31:40 -0600 Subject: [PATCH 13/41] add to options --- ntfysh_client/MainForm.cs | 31 +++++-- ntfysh_client/SettingsDialog.Designer.cs | 105 +++++++++++++++++++++-- ntfysh_client/SettingsDialog.cs | 53 +++++++++++- ntfysh_client/SettingsModel.cs | 4 + 4 files changed, 181 insertions(+), 12 deletions(-) diff --git a/ntfysh_client/MainForm.cs b/ntfysh_client/MainForm.cs index d5906bd..b759705 100644 --- a/ntfysh_client/MainForm.cs +++ b/ntfysh_client/MainForm.cs @@ -135,10 +135,14 @@ namespace ntfysh_client using SettingsDialog dialog = new(); //Load current settings into dialog - dialog.Timeout = Program.Settings.Timeout; dialog.ReconnectAttempts = Program.Settings.ReconnectAttempts; dialog.ReconnectAttemptDelay = Program.Settings.ReconnectAttemptDelay; - + dialog.UseNativeWindowsNotifications = Program.Settings.UseNativeWindowsNotifications; + dialog.UseCustomTrayNotifications = Program.Settings.UseCustomTrayNotifications; + dialog.CustomTrayNotificationsShowTimeoutBar = Program.Settings.CustomTrayNotificationsShowTimeoutBar; + dialog.CustomTrayNotificationsShowInDarkMode = Program.Settings.CustomTrayNotificationsShowInDarkMode; + dialog.Timeout = Program.Settings.Timeout; // set timeout last so bounds are setup before setting value + //Show dialog DialogResult result = dialog.ShowDialog(); @@ -149,7 +153,11 @@ namespace ntfysh_client Program.Settings.Timeout = dialog.Timeout; Program.Settings.ReconnectAttempts = dialog.ReconnectAttempts; Program.Settings.ReconnectAttemptDelay = dialog.ReconnectAttemptDelay; - + Program.Settings.UseNativeWindowsNotifications = dialog.UseNativeWindowsNotifications; + Program.Settings.UseCustomTrayNotifications = dialog.UseCustomTrayNotifications; + Program.Settings.CustomTrayNotificationsShowTimeoutBar = dialog.CustomTrayNotificationsShowTimeoutBar; + Program.Settings.CustomTrayNotificationsShowInDarkMode = dialog.CustomTrayNotificationsShowInDarkMode; + //Save new settings persistently SaveSettingsToFile(); } @@ -301,10 +309,14 @@ namespace ntfysh_client private SettingsModel GetDefaultSettings() => new() { - Revision = 1, + Revision = 2, Timeout = 5, ReconnectAttempts = 10, - ReconnectAttemptDelay = 3 + ReconnectAttemptDelay = 3, + UseNativeWindowsNotifications = true, + UseCustomTrayNotifications = false, + CustomTrayNotificationsShowTimeoutBar = true, + CustomTrayNotificationsShowInDarkMode = true, }; private void MergeSettingsRevisions(SettingsModel older, SettingsModel newer) @@ -315,6 +327,13 @@ namespace ntfysh_client older.ReconnectAttempts = newer.ReconnectAttempts; older.ReconnectAttemptDelay = newer.ReconnectAttemptDelay; } + if (older.Revision < 2) + { + older.UseNativeWindowsNotifications = newer.UseNativeWindowsNotifications; + older.UseCustomTrayNotifications = newer.UseCustomTrayNotifications; + older.CustomTrayNotificationsShowTimeoutBar = newer.CustomTrayNotificationsShowTimeoutBar; + older.CustomTrayNotificationsShowInDarkMode = newer.CustomTrayNotificationsShowInDarkMode; + } //Update the revision older.Revision = newer.Revision; @@ -364,7 +383,7 @@ namespace ntfysh_client Program.Settings = settings; //Check the settings revision. If it is older than the current latest revision, apply the settings defaults missing from previous revision - if (Program.Settings.Revision < defaultSettings.ReconnectAttempts) + if (Program.Settings.Revision < defaultSettings.Revision) { MergeSettingsRevisions(Program.Settings, defaultSettings); SaveSettingsToFile(); diff --git a/ntfysh_client/SettingsDialog.Designer.cs b/ntfysh_client/SettingsDialog.Designer.cs index a9ccaa0..01d5f9f 100644 --- a/ntfysh_client/SettingsDialog.Designer.cs +++ b/ntfysh_client/SettingsDialog.Designer.cs @@ -38,10 +38,19 @@ namespace ntfysh_client reconnectAttemptsLabel = new System.Windows.Forms.Label(); reconnectAttemptDelay = new System.Windows.Forms.NumericUpDown(); reconnectAttemptDelayLabel = new System.Windows.Forms.Label(); + groupBox1 = new System.Windows.Forms.GroupBox(); + useCustomTrayNotifications = new System.Windows.Forms.RadioButton(); + useNativeWindowsNotifications = new System.Windows.Forms.RadioButton(); + groupCustomNotificationSettings = new System.Windows.Forms.GroupBox(); + customNotificationsShowInDarkMode = new System.Windows.Forms.CheckBox(); + customNotificationsShowTimeoutBar = new System.Windows.Forms.CheckBox(); + label1 = new System.Windows.Forms.Label(); buttonPanel.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)timeout).BeginInit(); ((System.ComponentModel.ISupportInitialize)reconnectAttempts).BeginInit(); ((System.ComponentModel.ISupportInitialize)reconnectAttemptDelay).BeginInit(); + groupBox1.SuspendLayout(); + groupCustomNotificationSettings.SuspendLayout(); SuspendLayout(); // // buttonPanel @@ -50,7 +59,7 @@ namespace ntfysh_client buttonPanel.Controls.Add(cancelButton); buttonPanel.Controls.Add(saveButton); buttonPanel.Dock = System.Windows.Forms.DockStyle.Bottom; - buttonPanel.Location = new System.Drawing.Point(0, 150); + buttonPanel.Location = new System.Drawing.Point(0, 316); buttonPanel.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); buttonPanel.Name = "buttonPanel"; buttonPanel.Size = new System.Drawing.Size(531, 51); @@ -82,7 +91,7 @@ namespace ntfysh_client timeoutLabel.Location = new System.Drawing.Point(13, 9); timeoutLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); timeoutLabel.Name = "timeoutLabel"; - timeoutLabel.Size = new System.Drawing.Size(488, 15); + timeoutLabel.Size = new System.Drawing.Size(401, 15); timeoutLabel.TabIndex = 3; timeoutLabel.Text = "Notification Toast Timeout (seconds, use -1 to require closing notification):"; // @@ -109,7 +118,7 @@ namespace ntfysh_client reconnectAttemptsLabel.Location = new System.Drawing.Point(12, 54); reconnectAttemptsLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); reconnectAttemptsLabel.Name = "reconnectAttemptsLabel"; - reconnectAttemptsLabel.Size = new System.Drawing.Size(198, 15); + reconnectAttemptsLabel.Size = new System.Drawing.Size(287, 15); reconnectAttemptsLabel.TabIndex = 5; reconnectAttemptsLabel.Text = "Maximum reconnect retry attempts (requires restart):"; // @@ -127,16 +136,91 @@ namespace ntfysh_client reconnectAttemptDelayLabel.Location = new System.Drawing.Point(12, 99); reconnectAttemptDelayLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); reconnectAttemptDelayLabel.Name = "reconnectAttemptDelayLabel"; - reconnectAttemptDelayLabel.Size = new System.Drawing.Size(191, 15); + reconnectAttemptDelayLabel.Size = new System.Drawing.Size(275, 15); reconnectAttemptDelayLabel.TabIndex = 7; reconnectAttemptDelayLabel.Text = "Delay between attempts (seconds, requires restart):"; // + // groupBox1 + // + groupBox1.Controls.Add(useCustomTrayNotifications); + groupBox1.Controls.Add(useNativeWindowsNotifications); + groupBox1.Location = new System.Drawing.Point(12, 147); + groupBox1.Name = "groupBox1"; + groupBox1.Size = new System.Drawing.Size(506, 67); + groupBox1.TabIndex = 9; + groupBox1.TabStop = false; + // + // useCustomTrayNotifications + // + useCustomTrayNotifications.AutoSize = true; + useCustomTrayNotifications.Location = new System.Drawing.Point(6, 40); + useCustomTrayNotifications.Name = "useCustomTrayNotifications"; + useCustomTrayNotifications.Size = new System.Drawing.Size(267, 19); + useCustomTrayNotifications.TabIndex = 1; + useCustomTrayNotifications.TabStop = true; + useCustomTrayNotifications.Text = "Use ntfysh-windows custom tray notifications"; + useCustomTrayNotifications.UseVisualStyleBackColor = true; + useCustomTrayNotifications.CheckedChanged += useCustomTrayNotifications_CheckedChanged; + // + // useNativeWindowsNotifications + // + useNativeWindowsNotifications.AutoSize = true; + useNativeWindowsNotifications.Location = new System.Drawing.Point(6, 15); + useNativeWindowsNotifications.Name = "useNativeWindowsNotifications"; + useNativeWindowsNotifications.Size = new System.Drawing.Size(203, 19); + useNativeWindowsNotifications.TabIndex = 0; + useNativeWindowsNotifications.TabStop = true; + useNativeWindowsNotifications.Text = "Use Windows' native notifications"; + useNativeWindowsNotifications.UseVisualStyleBackColor = true; + // + // groupCustomNotificationSettings + // + groupCustomNotificationSettings.Controls.Add(customNotificationsShowInDarkMode); + groupCustomNotificationSettings.Controls.Add(customNotificationsShowTimeoutBar); + groupCustomNotificationSettings.Location = new System.Drawing.Point(12, 243); + groupCustomNotificationSettings.Name = "groupCustomNotificationSettings"; + groupCustomNotificationSettings.Size = new System.Drawing.Size(504, 67); + groupCustomNotificationSettings.TabIndex = 10; + groupCustomNotificationSettings.TabStop = false; + // + // customNotificationsShowInDarkMode + // + customNotificationsShowInDarkMode.AutoSize = true; + customNotificationsShowInDarkMode.Location = new System.Drawing.Point(6, 37); + customNotificationsShowInDarkMode.Name = "customNotificationsShowInDarkMode"; + customNotificationsShowInDarkMode.Size = new System.Drawing.Size(197, 19); + customNotificationsShowInDarkMode.TabIndex = 1; + customNotificationsShowInDarkMode.Text = "Show notifications in dark mode"; + customNotificationsShowInDarkMode.UseVisualStyleBackColor = true; + // + // customNotificationsShowTimeoutBar + // + customNotificationsShowTimeoutBar.AutoSize = true; + customNotificationsShowTimeoutBar.Location = new System.Drawing.Point(6, 14); + customNotificationsShowTimeoutBar.Name = "customNotificationsShowTimeoutBar"; + customNotificationsShowTimeoutBar.Size = new System.Drawing.Size(211, 19); + customNotificationsShowTimeoutBar.TabIndex = 0; + customNotificationsShowTimeoutBar.Text = "Show time-out bar on notifications"; + customNotificationsShowTimeoutBar.UseVisualStyleBackColor = true; + // + // label1 + // + label1.AutoSize = true; + label1.Location = new System.Drawing.Point(12, 227); + label1.Name = "label1"; + label1.Size = new System.Drawing.Size(180, 15); + label1.TabIndex = 11; + label1.Text = "Custom tray notification settings"; + // // SettingsDialog // AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; BackColor = System.Drawing.Color.White; - ClientSize = new System.Drawing.Size(531, 201); + ClientSize = new System.Drawing.Size(531, 367); + Controls.Add(label1); + Controls.Add(groupCustomNotificationSettings); + Controls.Add(groupBox1); Controls.Add(reconnectAttemptDelay); Controls.Add(reconnectAttemptDelayLabel); Controls.Add(reconnectAttempts); @@ -157,6 +241,10 @@ namespace ntfysh_client ((System.ComponentModel.ISupportInitialize)timeout).EndInit(); ((System.ComponentModel.ISupportInitialize)reconnectAttempts).EndInit(); ((System.ComponentModel.ISupportInitialize)reconnectAttemptDelay).EndInit(); + groupBox1.ResumeLayout(false); + groupBox1.PerformLayout(); + groupCustomNotificationSettings.ResumeLayout(false); + groupCustomNotificationSettings.PerformLayout(); ResumeLayout(false); PerformLayout(); } @@ -172,5 +260,12 @@ namespace ntfysh_client private System.Windows.Forms.Label reconnectAttemptsLabel; private System.Windows.Forms.NumericUpDown reconnectAttemptDelay; private System.Windows.Forms.Label reconnectAttemptDelayLabel; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.RadioButton useCustomTrayNotifications; + private System.Windows.Forms.RadioButton useNativeWindowsNotifications; + private System.Windows.Forms.GroupBox groupCustomNotificationSettings; + private System.Windows.Forms.CheckBox customNotificationsShowTimeoutBar; + private System.Windows.Forms.CheckBox customNotificationsShowInDarkMode; + private System.Windows.Forms.Label label1; } } \ No newline at end of file diff --git a/ntfysh_client/SettingsDialog.cs b/ntfysh_client/SettingsDialog.cs index 6568d9d..e63036b 100644 --- a/ntfysh_client/SettingsDialog.cs +++ b/ntfysh_client/SettingsDialog.cs @@ -8,7 +8,7 @@ namespace ntfysh_client public decimal Timeout { get => timeout.Value; - set => timeout.Value = value; + set => timeout.Value = Math.Max(value, timeout.Minimum); // Ensure value is within bounds despite our changing minimum } public decimal ReconnectAttempts @@ -23,9 +23,45 @@ namespace ntfysh_client set => reconnectAttemptDelay.Value = value; } + #region: Native vs custom notifications options. Because these are in a group box, these are mutualy exclusive. + public bool UseNativeWindowsNotifications + { + get => useNativeWindowsNotifications.Checked; + set + { + useNativeWindowsNotifications.Checked = value; + groupCustomNotificationSettings.Enabled = !value; + } + } + + public bool UseCustomTrayNotifications + { + get => useCustomTrayNotifications.Checked; + set { + useCustomTrayNotifications.Checked = value; + groupCustomNotificationSettings.Enabled = value; + } + } + #endregion + + #region: Custom tray notification options + public bool CustomTrayNotificationsShowTimeoutBar + { + get => customNotificationsShowTimeoutBar.Checked; + set => customNotificationsShowTimeoutBar.Checked = value; + } + + public bool CustomTrayNotificationsShowInDarkMode + { + get => customNotificationsShowInDarkMode.Checked; + set => customNotificationsShowInDarkMode.Checked = value; + } + #endregion + public SettingsDialog() { InitializeComponent(); + setNotificationsUIElements(); } private void saveButton_Click(object sender, EventArgs e) @@ -37,5 +73,20 @@ namespace ntfysh_client { DialogResult = DialogResult.Cancel; } + + private void setNotificationsUIElements() + { + groupCustomNotificationSettings.Enabled = useCustomTrayNotifications.Checked; + timeoutLabel.Text = useCustomTrayNotifications.Checked ? _customNotificationsTimeout : _windowsNotificationsTimeout; + timeout.Minimum = useCustomTrayNotifications.Checked ? -1 : 0; + } + + private void useCustomTrayNotifications_CheckedChanged(object sender, EventArgs e) + { + setNotificationsUIElements(); + } + + private const string _windowsNotificationsTimeout = "Notification Toast Timeout (seconds, may be ignored by OS based on accessibility settings):"; + private const string _customNotificationsTimeout = "Notification Toast Timeout (seconds, use -1 to require closing notification):"; } } diff --git a/ntfysh_client/SettingsModel.cs b/ntfysh_client/SettingsModel.cs index ef67969..b370db0 100644 --- a/ntfysh_client/SettingsModel.cs +++ b/ntfysh_client/SettingsModel.cs @@ -6,5 +6,9 @@ public decimal Timeout { get; set; } public decimal ReconnectAttempts { get; set; } public decimal ReconnectAttemptDelay { get; set; } + public bool UseNativeWindowsNotifications { get; set; } + public bool UseCustomTrayNotifications { get; set; } + public bool CustomTrayNotificationsShowTimeoutBar { get; set; } + public bool CustomTrayNotificationsShowInDarkMode { get; set; } } } \ No newline at end of file -- 2.49.1 From 42421d9820a831d71795e06a99217d6ba0daba60 Mon Sep 17 00:00:00 2001 From: mshafer1 <2565361+mshafer1@users.noreply.github.com> Date: Fri, 20 Dec 2024 21:34:18 -0600 Subject: [PATCH 14/41] if settings says to use the native notifications, use them --- ntfysh_client/MainForm.cs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/ntfysh_client/MainForm.cs b/ntfysh_client/MainForm.cs index b759705..536ab8c 100644 --- a/ntfysh_client/MainForm.cs +++ b/ntfysh_client/MainForm.cs @@ -72,8 +72,15 @@ namespace ntfysh_client }; string finalTitle = string.IsNullOrWhiteSpace(e.Title) ? $"{e.Sender.TopicId}@{e.Sender.ServerUrl}" : e.Title; - - this.notificationDialog.ShowNotification(finalTitle, e.Message, (int)TimeSpan.FromSeconds((double)Program.Settings.Timeout).TotalMilliseconds, priorityIcon); + + if (Program.Settings.UseNativeWindowsNotifications) + { + notifyIcon.ShowBalloonTip((int)TimeSpan.FromSeconds((double)Program.Settings.Timeout).TotalMilliseconds, finalTitle, e.Message, priorityIcon); + } + else + { + this.notificationDialog.ShowNotification(finalTitle, e.Message, (int)TimeSpan.FromSeconds((double)Program.Settings.Timeout).TotalMilliseconds, priorityIcon); + } } private void OnConnectionMultiAttemptFailure(NotificationListener sender, SubscribedTopic topic) -- 2.49.1 From 5414aa4996905ee3db1b2893c6a785e3c95659c6 Mon Sep 17 00:00:00 2001 From: mshafer1 <2565361+mshafer1@users.noreply.github.com> Date: Fri, 20 Dec 2024 21:46:45 -0600 Subject: [PATCH 15/41] pass new options down to custom notifications form --- ntfysh_client/MainForm.cs | 9 ++++++++- ntfysh_client/NotificationDialog.cs | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ntfysh_client/MainForm.cs b/ntfysh_client/MainForm.cs index 536ab8c..6684a05 100644 --- a/ntfysh_client/MainForm.cs +++ b/ntfysh_client/MainForm.cs @@ -79,7 +79,14 @@ namespace ntfysh_client } else { - this.notificationDialog.ShowNotification(finalTitle, e.Message, (int)TimeSpan.FromSeconds((double)Program.Settings.Timeout).TotalMilliseconds, priorityIcon); + this.notificationDialog.ShowNotification( + title: finalTitle, + message: e.Message, + timeout_ms: (int)TimeSpan.FromSeconds((double)Program.Settings.Timeout).TotalMilliseconds, + icon: priorityIcon, + showTimeOutBar: Program.Settings.CustomTrayNotificationsShowTimeoutBar + showInDarkMode: Program.Settings.CustomTrayNotificationsShowInDarkMode + ); } } diff --git a/ntfysh_client/NotificationDialog.cs b/ntfysh_client/NotificationDialog.cs index 8729bba..a1cf101 100644 --- a/ntfysh_client/NotificationDialog.cs +++ b/ntfysh_client/NotificationDialog.cs @@ -47,7 +47,7 @@ namespace ntfysh_client InitializeWindowHidden(); } - public void ShowNotification(string title, string message, int timeout_ms = -1, ToolTipIcon? icon = null) + public void ShowNotification(string title, string message, int timeout_ms = -1, ToolTipIcon? icon = null, bool showTimeOutBar = true, bool showInDarkMode = true) { if (this.IsVisible) { -- 2.49.1 From 8203e6c112b8d14a995692d7efe7b9712e32b57f Mon Sep 17 00:00:00 2001 From: mshafer1 <2565361+mshafer1@users.noreply.github.com> Date: Fri, 20 Dec 2024 21:47:06 -0600 Subject: [PATCH 16/41] handle if option to show progress bar is off --- ntfysh_client/NotificationDialog.cs | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/ntfysh_client/NotificationDialog.cs b/ntfysh_client/NotificationDialog.cs index a1cf101..922bf05 100644 --- a/ntfysh_client/NotificationDialog.cs +++ b/ntfysh_client/NotificationDialog.cs @@ -80,18 +80,25 @@ namespace ntfysh_client displayTimeoutTimer.Elapsed += handleTimeout; this.displayTimeoutTimer.Start(); - this.progress = 100; - this.updateTimer = new System.Windows.Forms.Timer(); - updateTimer.Interval = 100; - this.updateTimer.Tick += this.UpdateProgress; - this.updateTimer.Start(); + if (showTimeOutBar) + { + this.progress = 100; + this.updateTimer = new System.Windows.Forms.Timer(); + updateTimer.Interval = 100; + this.updateTimer.Tick += this.UpdateProgress; + this.updateTimer.Start(); - this.shownStopwatch = new Stopwatch(); - this.shownStopwatch.Start(); + this.shownStopwatch = new Stopwatch(); + this.shownStopwatch.Start(); - this.progressBar1.Visible = true; - this.lbTimeout.Visible = true; - this._timeout = timeout_ms; + this.progressBar1.Visible = true; + this.lbTimeout.Visible = true; + this._timeout = timeout_ms; + } else + { + this.progressBar1.Visible = false; + this.lbTimeout.Visible = false; + } } else { -- 2.49.1 From 934edb79eb7899b105e8e31dc501d00bc5553afd Mon Sep 17 00:00:00 2001 From: mshafer1 <2565361+mshafer1@users.noreply.github.com> Date: Sat, 21 Dec 2024 07:51:57 -0600 Subject: [PATCH 17/41] use pep8 style private naming and remove this. --- ntfysh_client/MainForm.cs | 8 +- ntfysh_client/NotificationDialog.cs | 164 ++++++++++++++-------------- 2 files changed, 86 insertions(+), 86 deletions(-) diff --git a/ntfysh_client/MainForm.cs b/ntfysh_client/MainForm.cs index 6684a05..4232d4b 100644 --- a/ntfysh_client/MainForm.cs +++ b/ntfysh_client/MainForm.cs @@ -16,7 +16,7 @@ namespace ntfysh_client private readonly NotificationListener _notificationListener; private bool _startInTray; private bool _trueExit; - private NotificationDialog notificationDialog; + private NotificationDialog _notificationDialog; public MainForm(NotificationListener notificationListener, bool startInTray = false) { @@ -34,7 +34,7 @@ namespace ntfysh_client LoadSettings(); LoadTopics(); - this.notificationDialog = new NotificationDialog(); + _notificationDialog = new NotificationDialog(); } protected override void SetVisibleCore(bool value) @@ -79,12 +79,12 @@ namespace ntfysh_client } else { - this.notificationDialog.ShowNotification( + _notificationDialog.ShowNotification( title: finalTitle, message: e.Message, timeout_ms: (int)TimeSpan.FromSeconds((double)Program.Settings.Timeout).TotalMilliseconds, icon: priorityIcon, - showTimeOutBar: Program.Settings.CustomTrayNotificationsShowTimeoutBar + showTimeOutBar: Program.Settings.CustomTrayNotificationsShowTimeoutBar, showInDarkMode: Program.Settings.CustomTrayNotificationsShowInDarkMode ); } diff --git a/ntfysh_client/NotificationDialog.cs b/ntfysh_client/NotificationDialog.cs index 922bf05..9d3e6d2 100644 --- a/ntfysh_client/NotificationDialog.cs +++ b/ntfysh_client/NotificationDialog.cs @@ -17,118 +17,118 @@ namespace ntfysh_client private const int ScreenMargin = 20; private int _timeout = 0; - private System.Timers.Timer? displayTimeoutTimer = null; - private System.Windows.Forms.Timer? updateTimer = null; - private Stopwatch? shownStopwatch = null; + private System.Timers.Timer? _displayTimeoutTimer = null; + private System.Windows.Forms.Timer? _updateTimer = null; + private Stopwatch? _shownStopwatch = null; private ToolTipIcon? _icon; private int _progress_value = 0; private int progress { - get { return this._progress_value; } + get { return _progress_value; } set { - this._progress_value = value; - this.progressBar1.Value = value; + _progress_value = value; + progressBar1.Value = value; } } public bool IsVisible { - get { return this.Visible; } - set { this.Visible = value; } + get { return Visible; } + set { Visible = value; } } public NotificationDialog() { - this.ShowInTaskbar = false; - this.IsVisible = false; - this.TopMost = true; + ShowInTaskbar = false; + IsVisible = false; + TopMost = true; InitializeComponent(); InitializeWindowHidden(); } public void ShowNotification(string title, string message, int timeout_ms = -1, ToolTipIcon? icon = null, bool showTimeOutBar = true, bool showInDarkMode = true) { - if (this.IsVisible) + if (IsVisible) { // close the current notification - this.handleTimeout(null, null); + handleTimeout(null, null); } // setup data - this._icon = icon; - if (this._icon != null) + _icon = icon; + if (_icon != null) { - this.iconBox.Image = ConvertToolTipIconToImage(_icon.Value); + iconBox.Image = ConvertToolTipIconToImage(_icon.Value); } - this.tbTitle.Text = title; - this.tbMessage.Text = message; + tbTitle.Text = title; + tbMessage.Text = message; // setup timers - if (this.displayTimeoutTimer != null) + if (_displayTimeoutTimer != null) { - this.displayTimeoutTimer.Stop(); - this.displayTimeoutTimer.Dispose(); + _displayTimeoutTimer.Stop(); + _displayTimeoutTimer.Dispose(); } - if (this.updateTimer != null) + if (_updateTimer != null) { - this.updateTimer.Stop(); - this.updateTimer.Dispose(); + _updateTimer.Stop(); + _updateTimer.Dispose(); } if (timeout_ms > 0) { - this.displayTimeoutTimer = new System.Timers.Timer(timeout_ms); - displayTimeoutTimer.Elapsed += handleTimeout; - this.displayTimeoutTimer.Start(); + _displayTimeoutTimer = new System.Timers.Timer(timeout_ms); + _displayTimeoutTimer.Elapsed += handleTimeout; + _displayTimeoutTimer.Start(); if (showTimeOutBar) { - this.progress = 100; - this.updateTimer = new System.Windows.Forms.Timer(); - updateTimer.Interval = 100; - this.updateTimer.Tick += this.UpdateProgress; - this.updateTimer.Start(); + progress = 100; + _updateTimer = new System.Windows.Forms.Timer(); + _updateTimer.Interval = 100; + _updateTimer.Tick += UpdateProgress; + _updateTimer.Start(); - this.shownStopwatch = new Stopwatch(); - this.shownStopwatch.Start(); + _shownStopwatch = new Stopwatch(); + _shownStopwatch.Start(); - this.progressBar1.Visible = true; - this.lbTimeout.Visible = true; - this._timeout = timeout_ms; + progressBar1.Visible = true; + lbTimeout.Visible = true; + _timeout = timeout_ms; } else { - this.progressBar1.Visible = false; - this.lbTimeout.Visible = false; + progressBar1.Visible = false; + lbTimeout.Visible = false; } } else { - this.progressBar1.Visible = false; - this.lbTimeout.Visible = false; + progressBar1.Visible = false; + lbTimeout.Visible = false; } // ok, show the window - this.Show(); - this.SetWindowPosition(); + Show(); + SetWindowPosition(); } private void UpdateProgress(object? sender, EventArgs e) { - if (this.shownStopwatch == null) + if (_shownStopwatch == null) { return; } - this.progress = (int)((this._timeout - this.shownStopwatch.ElapsedMilliseconds) * 100 / this._timeout); - this.lbTimeout.Text = $"{(int)(this._timeout - this.shownStopwatch.ElapsedMilliseconds) / 1000}"; + progress = (int)((_timeout - _shownStopwatch.ElapsedMilliseconds) * 100 / _timeout); + lbTimeout.Text = $"{(int)(_timeout - _shownStopwatch.ElapsedMilliseconds) / 1000}"; } protected override void SetVisibleCore(bool value) { - this.SetWindowPosition(); + SetWindowPosition(); if (value) { - this.BringToFront(); + BringToFront(); AnimateWindow( - this.Handle, + Handle, time: 250, flags: NFWinUserAnimateWindowConstnats.AW_SLIDE | NFWinUserAnimateWindowConstnats.AW_VER_NEGATIVE ); @@ -143,35 +143,35 @@ namespace ntfysh_client private void SetWindowPosition() { - int workingtop = Screen.PrimaryScreen.WorkingArea.Height - this.Height; - this.Top = workingtop - NotificationDialog.ScreenMargin; + int workingtop = Screen.PrimaryScreen.WorkingArea.Height - Height; + Top = workingtop - NotificationDialog.ScreenMargin; - int workingleft = Screen.PrimaryScreen.WorkingArea.Width - this.Width; - this.Left = workingleft - NotificationDialog.ScreenMargin; + int workingleft = Screen.PrimaryScreen.WorkingArea.Width - Width; + Left = workingleft - NotificationDialog.ScreenMargin; } private void ui_hide_window(object? sender, EventArgs? e) { AnimateWindow( - this.Handle, + Handle, time: 250, flags: NFWinUserAnimateWindowConstnats.AW_SLIDE | NFWinUserAnimateWindowConstnats.AW_VER_POSITIVE | NFWinUserAnimateWindowConstnats.AW_HIDE ); - this.IsVisible = false; + IsVisible = false; } private void handleTimeout(object? sender, EventArgs? e) { - this.cancelTimer(); - if (this.InvokeRequired) + cancelTimer(); + if (InvokeRequired) { // on a background thread, so invoke on the UI thread - this.Invoke(new Action(() => this.ui_hide_window(sender, e))); + Invoke(new Action(() => ui_hide_window(sender, e))); } else { // in the UI thread, invoke directly - this.ui_hide_window(sender, e); + ui_hide_window(sender, e); } } @@ -193,16 +193,16 @@ namespace ntfysh_client private void InitializeWindowHidden() { - this.Opacity = 0; - this.ShowNotification("Title", "Message"); - this.IsVisible = false; - this.Opacity = 1; + Opacity = 0; + ShowNotification("Title", "Message"); + IsVisible = false; + Opacity = 1; } private void btnClose_Click(object sender, EventArgs e) { // immediate - this.IsVisible = false; + IsVisible = false; } private class NFWinUserAnimateWindowConstnats @@ -220,43 +220,43 @@ namespace ntfysh_client private void window_MouseDown(object sender, EventArgs e) { - this.cancelTimer(); + cancelTimer(); } private void cancelTimer() { - if (this.InvokeRequired) + if (InvokeRequired) { // on a background thread, so invoke on the UI thread - this.Invoke(new Action(() => + Invoke(new Action(() => { - this.lbTimeout.Visible = false; - this.progressBar1.Visible = false; + lbTimeout.Visible = false; + progressBar1.Visible = false; })); } else { // in the UI thread, invoke directly - this.lbTimeout.Visible = false; - this.progressBar1.Visible = false; + lbTimeout.Visible = false; + progressBar1.Visible = false; } - if (this.displayTimeoutTimer != null) // check if the timer has already been disposed + if (_displayTimeoutTimer != null) // check if the timer has already been disposed { - this.displayTimeoutTimer.Stop(); - this.displayTimeoutTimer.Dispose(); - this.displayTimeoutTimer = null; + _displayTimeoutTimer.Stop(); + _displayTimeoutTimer.Dispose(); + _displayTimeoutTimer = null; } - if (this.updateTimer != null) + if (_updateTimer != null) { - this.updateTimer.Stop(); - this.updateTimer.Dispose(); - this.updateTimer = null; + _updateTimer.Stop(); + _updateTimer.Dispose(); + _updateTimer = null; } - if (this.shownStopwatch != null) + if (_shownStopwatch != null) { - this.shownStopwatch.Stop(); - this.shownStopwatch = null; + _shownStopwatch.Stop(); + _shownStopwatch = null; } } } -- 2.49.1 From fa455baa570be10c58bf76a0df5ca3363c91b4f3 Mon Sep 17 00:00:00 2001 From: mshafer1 <2565361+mshafer1@users.noreply.github.com> Date: Sat, 21 Dec 2024 08:03:23 -0600 Subject: [PATCH 18/41] add blank lines for readability --- ntfysh_client/MainForm.cs | 3 +++ ntfysh_client/NotificationDialog.cs | 17 ++++++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/ntfysh_client/MainForm.cs b/ntfysh_client/MainForm.cs index 4232d4b..89a0b70 100644 --- a/ntfysh_client/MainForm.cs +++ b/ntfysh_client/MainForm.cs @@ -79,6 +79,7 @@ namespace ntfysh_client } else { + _notificationDialog.ShowNotification( title: finalTitle, message: e.Message, @@ -341,6 +342,8 @@ namespace ntfysh_client older.ReconnectAttempts = newer.ReconnectAttempts; older.ReconnectAttemptDelay = newer.ReconnectAttemptDelay; } + + //Apply settings introduced in Revision 2 (Native vs custom notifications) if (older.Revision < 2) { older.UseNativeWindowsNotifications = newer.UseNativeWindowsNotifications; diff --git a/ntfysh_client/NotificationDialog.cs b/ntfysh_client/NotificationDialog.cs index 9d3e6d2..9a34de7 100644 --- a/ntfysh_client/NotificationDialog.cs +++ b/ntfysh_client/NotificationDialog.cs @@ -54,12 +54,15 @@ namespace ntfysh_client // close the current notification handleTimeout(null, null); } + // setup data _icon = icon; + if (_icon != null) { iconBox.Image = ConvertToolTipIconToImage(_icon.Value); } + tbTitle.Text = title; tbMessage.Text = message; @@ -69,11 +72,13 @@ namespace ntfysh_client _displayTimeoutTimer.Stop(); _displayTimeoutTimer.Dispose(); } + if (_updateTimer != null) { _updateTimer.Stop(); _updateTimer.Dispose(); } + if (timeout_ms > 0) { _displayTimeoutTimer = new System.Timers.Timer(timeout_ms); @@ -94,7 +99,8 @@ namespace ntfysh_client progressBar1.Visible = true; lbTimeout.Visible = true; _timeout = timeout_ms; - } else + } + else { progressBar1.Visible = false; lbTimeout.Visible = false; @@ -117,6 +123,7 @@ namespace ntfysh_client { return; } + progress = (int)((_timeout - _shownStopwatch.ElapsedMilliseconds) * 100 / _timeout); lbTimeout.Text = $"{(int)(_timeout - _shownStopwatch.ElapsedMilliseconds) / 1000}"; } @@ -124,15 +131,18 @@ namespace ntfysh_client protected override void SetVisibleCore(bool value) { SetWindowPosition(); + if (value) { BringToFront(); + AnimateWindow( Handle, time: 250, flags: NFWinUserAnimateWindowConstnats.AW_SLIDE | NFWinUserAnimateWindowConstnats.AW_VER_NEGATIVE ); } + base.SetVisibleCore(value); } @@ -152,17 +162,20 @@ namespace ntfysh_client private void ui_hide_window(object? sender, EventArgs? e) { + AnimateWindow( Handle, time: 250, flags: NFWinUserAnimateWindowConstnats.AW_SLIDE | NFWinUserAnimateWindowConstnats.AW_VER_POSITIVE | NFWinUserAnimateWindowConstnats.AW_HIDE ); + IsVisible = false; } private void handleTimeout(object? sender, EventArgs? e) { cancelTimer(); + if (InvokeRequired) { // on a background thread, so invoke on the UI thread @@ -247,12 +260,14 @@ namespace ntfysh_client _displayTimeoutTimer.Dispose(); _displayTimeoutTimer = null; } + if (_updateTimer != null) { _updateTimer.Stop(); _updateTimer.Dispose(); _updateTimer = null; } + if (_shownStopwatch != null) { _shownStopwatch.Stop(); -- 2.49.1 From 2cf458beae0536de895237d61a5452e1feedfdce Mon Sep 17 00:00:00 2001 From: mshafer1 <2565361+mshafer1@users.noreply.github.com> Date: Sat, 21 Dec 2024 08:11:45 -0600 Subject: [PATCH 19/41] use CamelCasing --- ntfysh_client/NotificationDialog.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/ntfysh_client/NotificationDialog.cs b/ntfysh_client/NotificationDialog.cs index 9a34de7..d13fa97 100644 --- a/ntfysh_client/NotificationDialog.cs +++ b/ntfysh_client/NotificationDialog.cs @@ -52,7 +52,7 @@ namespace ntfysh_client if (IsVisible) { // close the current notification - handleTimeout(null, null); + HandleTimeout(null, null); } // setup data @@ -82,7 +82,7 @@ namespace ntfysh_client if (timeout_ms > 0) { _displayTimeoutTimer = new System.Timers.Timer(timeout_ms); - _displayTimeoutTimer.Elapsed += handleTimeout; + _displayTimeoutTimer.Elapsed += HandleTimeout; _displayTimeoutTimer.Start(); if (showTimeOutBar) @@ -160,7 +160,7 @@ namespace ntfysh_client Left = workingleft - NotificationDialog.ScreenMargin; } - private void ui_hide_window(object? sender, EventArgs? e) + private void UIThreadAnimatedHideWindow(object? sender, EventArgs? e) { AnimateWindow( @@ -172,19 +172,19 @@ namespace ntfysh_client IsVisible = false; } - private void handleTimeout(object? sender, EventArgs? e) + private void HandleTimeout(object? sender, EventArgs? e) { - cancelTimer(); + CancelTimer(); if (InvokeRequired) { // on a background thread, so invoke on the UI thread - Invoke(new Action(() => ui_hide_window(sender, e))); + Invoke(new Action(() => UIThreadAnimatedHideWindow(sender, e))); } else { // in the UI thread, invoke directly - ui_hide_window(sender, e); + UIThreadAnimatedHideWindow(sender, e); } } @@ -233,10 +233,10 @@ namespace ntfysh_client private void window_MouseDown(object sender, EventArgs e) { - cancelTimer(); + CancelTimer(); } - private void cancelTimer() + private void CancelTimer() { if (InvokeRequired) { -- 2.49.1 From be0db848dcb0ff306298b9ed825cc2d3c103a782 Mon Sep 17 00:00:00 2001 From: mshafer1 <2565361+mshafer1@users.noreply.github.com> Date: Sat, 21 Dec 2024 08:11:57 -0600 Subject: [PATCH 20/41] improve comment on close handler --- ntfysh_client/NotificationDialog.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ntfysh_client/NotificationDialog.cs b/ntfysh_client/NotificationDialog.cs index d13fa97..2c913a7 100644 --- a/ntfysh_client/NotificationDialog.cs +++ b/ntfysh_client/NotificationDialog.cs @@ -214,7 +214,7 @@ namespace ntfysh_client private void btnClose_Click(object sender, EventArgs e) { - // immediate + // don't animate, immediately "close" IsVisible = false; } -- 2.49.1 From fc3275442c09e9674ce5ef6a1ba04831aeddc788 Mon Sep 17 00:00:00 2001 From: mshafer1 <2565361+mshafer1@users.noreply.github.com> Date: Sat, 21 Dec 2024 08:18:35 -0600 Subject: [PATCH 21/41] more CamelCasing --- ntfysh_client/SettingsDialog.Designer.cs | 2 +- ntfysh_client/SettingsDialog.cs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ntfysh_client/SettingsDialog.Designer.cs b/ntfysh_client/SettingsDialog.Designer.cs index 01d5f9f..7a85107 100644 --- a/ntfysh_client/SettingsDialog.Designer.cs +++ b/ntfysh_client/SettingsDialog.Designer.cs @@ -160,7 +160,7 @@ namespace ntfysh_client useCustomTrayNotifications.TabStop = true; useCustomTrayNotifications.Text = "Use ntfysh-windows custom tray notifications"; useCustomTrayNotifications.UseVisualStyleBackColor = true; - useCustomTrayNotifications.CheckedChanged += useCustomTrayNotifications_CheckedChanged; + useCustomTrayNotifications.CheckedChanged += UseCustomTrayNotifications_CheckedChanged; // // useNativeWindowsNotifications // diff --git a/ntfysh_client/SettingsDialog.cs b/ntfysh_client/SettingsDialog.cs index e63036b..3cb11c5 100644 --- a/ntfysh_client/SettingsDialog.cs +++ b/ntfysh_client/SettingsDialog.cs @@ -61,7 +61,7 @@ namespace ntfysh_client public SettingsDialog() { InitializeComponent(); - setNotificationsUIElements(); + SetNotificationsUIElements(); } private void saveButton_Click(object sender, EventArgs e) @@ -74,16 +74,16 @@ namespace ntfysh_client DialogResult = DialogResult.Cancel; } - private void setNotificationsUIElements() + private void SetNotificationsUIElements() { groupCustomNotificationSettings.Enabled = useCustomTrayNotifications.Checked; timeoutLabel.Text = useCustomTrayNotifications.Checked ? _customNotificationsTimeout : _windowsNotificationsTimeout; timeout.Minimum = useCustomTrayNotifications.Checked ? -1 : 0; } - private void useCustomTrayNotifications_CheckedChanged(object sender, EventArgs e) + private void UseCustomTrayNotifications_CheckedChanged(object sender, EventArgs e) { - setNotificationsUIElements(); + SetNotificationsUIElements(); } private const string _windowsNotificationsTimeout = "Notification Toast Timeout (seconds, may be ignored by OS based on accessibility settings):"; -- 2.49.1 From 5b456c14a736825f02f8c125ee2de15bcc0e5814 Mon Sep 17 00:00:00 2001 From: mshafer1 <2565361+mshafer1@users.noreply.github.com> Date: Sat, 21 Dec 2024 08:18:57 -0600 Subject: [PATCH 22/41] utilize modern c# features --- ntfysh_client/NotificationDialog.cs | 37 +++++++---------------------- 1 file changed, 9 insertions(+), 28 deletions(-) diff --git a/ntfysh_client/NotificationDialog.cs b/ntfysh_client/NotificationDialog.cs index 2c913a7..dae40dd 100644 --- a/ntfysh_client/NotificationDialog.cs +++ b/ntfysh_client/NotificationDialog.cs @@ -119,10 +119,7 @@ namespace ntfysh_client private void UpdateProgress(object? sender, EventArgs e) { - if (_shownStopwatch == null) - { - return; - } + if (_shownStopwatch is null) return; progress = (int)((_timeout - _shownStopwatch.ElapsedMilliseconds) * 100 / _timeout); lbTimeout.Text = $"{(int)(_timeout - _shownStopwatch.ElapsedMilliseconds) / 1000}"; @@ -146,11 +143,6 @@ namespace ntfysh_client base.SetVisibleCore(value); } - protected override void OnShown(EventArgs e) - { - base.OnShown(e); - } - private void SetWindowPosition() { int workingtop = Screen.PrimaryScreen.WorkingArea.Height - Height; @@ -188,21 +180,13 @@ namespace ntfysh_client } } - private Image? ConvertToolTipIconToImage(ToolTipIcon icon) + private Image? ConvertToolTipIconToImage(ToolTipIcon icon) => icon switch { - switch (icon) - { - case ToolTipIcon.Info: - return SystemIcons.Information.ToBitmap(); - case ToolTipIcon.Warning: - return SystemIcons.Warning.ToBitmap(); - case ToolTipIcon.Error: - return SystemIcons.Error.ToBitmap(); - case ToolTipIcon.None: - default: - return null; - } - } + ToolTipIcon.Info => SystemIcons.Information.ToBitmap(), + ToolTipIcon.Warning => SystemIcons.Warning.ToBitmap(), + ToolTipIcon.Error => SystemIcons.Error.ToBitmap(), + _ => null + }; private void InitializeWindowHidden() { @@ -231,11 +215,8 @@ namespace ntfysh_client public const int AW_BLEND = 0x00080000; } - private void window_MouseDown(object sender, EventArgs e) - { - CancelTimer(); - } - + private void window_MouseDown(object sender, EventArgs e) => CancelTimer(); + private void CancelTimer() { if (InvokeRequired) -- 2.49.1 From f8dacac5a6714e6e2362243e5864e8064d798d6c Mon Sep 17 00:00:00 2001 From: mshafer1 <2565361+mshafer1@users.noreply.github.com> Date: Sat, 21 Dec 2024 08:21:18 -0600 Subject: [PATCH 23/41] just utilize the progress bar directly --- ntfysh_client/NotificationDialog.cs | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/ntfysh_client/NotificationDialog.cs b/ntfysh_client/NotificationDialog.cs index dae40dd..f7d0a90 100644 --- a/ntfysh_client/NotificationDialog.cs +++ b/ntfysh_client/NotificationDialog.cs @@ -21,16 +21,6 @@ namespace ntfysh_client private System.Windows.Forms.Timer? _updateTimer = null; private Stopwatch? _shownStopwatch = null; private ToolTipIcon? _icon; - private int _progress_value = 0; - private int progress - { - get { return _progress_value; } - set - { - _progress_value = value; - progressBar1.Value = value; - } - } public bool IsVisible { @@ -87,7 +77,7 @@ namespace ntfysh_client if (showTimeOutBar) { - progress = 100; + progressBar1.Value = 100; _updateTimer = new System.Windows.Forms.Timer(); _updateTimer.Interval = 100; _updateTimer.Tick += UpdateProgress; @@ -121,7 +111,7 @@ namespace ntfysh_client { if (_shownStopwatch is null) return; - progress = (int)((_timeout - _shownStopwatch.ElapsedMilliseconds) * 100 / _timeout); + progressBar1.Value = (int)((_timeout - _shownStopwatch.ElapsedMilliseconds) * 100 / _timeout); lbTimeout.Text = $"{(int)(_timeout - _shownStopwatch.ElapsedMilliseconds) / 1000}"; } -- 2.49.1 From 859a8938c09ba498d68a4d15d2f2f92bc0f1339c Mon Sep 17 00:00:00 2001 From: mshafer1 <2565361+mshafer1@users.noreply.github.com> Date: Sat, 21 Dec 2024 08:22:47 -0600 Subject: [PATCH 24/41] remove IsVisible and just use Visible instead --- ntfysh_client/NotificationDialog.cs | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/ntfysh_client/NotificationDialog.cs b/ntfysh_client/NotificationDialog.cs index f7d0a90..f917ab2 100644 --- a/ntfysh_client/NotificationDialog.cs +++ b/ntfysh_client/NotificationDialog.cs @@ -22,16 +22,10 @@ namespace ntfysh_client private Stopwatch? _shownStopwatch = null; private ToolTipIcon? _icon; - public bool IsVisible - { - get { return Visible; } - set { Visible = value; } - } - public NotificationDialog() { ShowInTaskbar = false; - IsVisible = false; + Visible = false; TopMost = true; InitializeComponent(); InitializeWindowHidden(); @@ -39,7 +33,7 @@ namespace ntfysh_client public void ShowNotification(string title, string message, int timeout_ms = -1, ToolTipIcon? icon = null, bool showTimeOutBar = true, bool showInDarkMode = true) { - if (IsVisible) + if (Visible) { // close the current notification HandleTimeout(null, null); @@ -151,7 +145,7 @@ namespace ntfysh_client flags: NFWinUserAnimateWindowConstnats.AW_SLIDE | NFWinUserAnimateWindowConstnats.AW_VER_POSITIVE | NFWinUserAnimateWindowConstnats.AW_HIDE ); - IsVisible = false; + Visible = false; } private void HandleTimeout(object? sender, EventArgs? e) @@ -182,14 +176,14 @@ namespace ntfysh_client { Opacity = 0; ShowNotification("Title", "Message"); - IsVisible = false; + Visible = false; Opacity = 1; } private void btnClose_Click(object sender, EventArgs e) { // don't animate, immediately "close" - IsVisible = false; + Visible = false; } private class NFWinUserAnimateWindowConstnats -- 2.49.1 From 5977501b915a05c94fcf87479d42916f6049b358 Mon Sep 17 00:00:00 2001 From: mshafer1 <2565361+mshafer1@users.noreply.github.com> Date: Sat, 21 Dec 2024 08:28:46 -0600 Subject: [PATCH 25/41] remove _icon --- ntfysh_client/NotificationDialog.cs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/ntfysh_client/NotificationDialog.cs b/ntfysh_client/NotificationDialog.cs index f917ab2..b9c0039 100644 --- a/ntfysh_client/NotificationDialog.cs +++ b/ntfysh_client/NotificationDialog.cs @@ -20,7 +20,6 @@ namespace ntfysh_client private System.Timers.Timer? _displayTimeoutTimer = null; private System.Windows.Forms.Timer? _updateTimer = null; private Stopwatch? _shownStopwatch = null; - private ToolTipIcon? _icon; public NotificationDialog() { @@ -39,13 +38,9 @@ namespace ntfysh_client HandleTimeout(null, null); } - // setup data - _icon = icon; - if (_icon != null) - { - iconBox.Image = ConvertToolTipIconToImage(_icon.Value); - } + // setup data + iconBox.Image = (icon is null) ? null : ConvertToolTipIconToImage(icon.Value); tbTitle.Text = title; tbMessage.Text = message; -- 2.49.1 From ed13382e46c838e35f38635801fd15616f6bf2c1 Mon Sep 17 00:00:00 2001 From: mshafer1 <2565361+mshafer1@users.noreply.github.com> Date: Sat, 21 Dec 2024 08:32:09 -0600 Subject: [PATCH 26/41] format --- ntfysh_client/NotificationDialog.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ntfysh_client/NotificationDialog.cs b/ntfysh_client/NotificationDialog.cs index b9c0039..767ebd6 100644 --- a/ntfysh_client/NotificationDialog.cs +++ b/ntfysh_client/NotificationDialog.cs @@ -38,7 +38,6 @@ namespace ntfysh_client HandleTimeout(null, null); } - // setup data iconBox.Image = (icon is null) ? null : ConvertToolTipIconToImage(icon.Value); @@ -195,7 +194,7 @@ namespace ntfysh_client } private void window_MouseDown(object sender, EventArgs e) => CancelTimer(); - + private void CancelTimer() { if (InvokeRequired) -- 2.49.1 From c4e5a9059d02c15a08e8d2e2fe5f511391293716 Mon Sep 17 00:00:00 2001 From: mshafer1 <2565361+mshafer1@users.noreply.github.com> Date: Sat, 21 Dec 2024 08:40:17 -0600 Subject: [PATCH 27/41] rename new elements to be camelCase to match existing --- ntfysh_client/SettingsDialog.Designer.cs | 28 ++++++++++++------------ 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/ntfysh_client/SettingsDialog.Designer.cs b/ntfysh_client/SettingsDialog.Designer.cs index 7a85107..b2fe95c 100644 --- a/ntfysh_client/SettingsDialog.Designer.cs +++ b/ntfysh_client/SettingsDialog.Designer.cs @@ -38,7 +38,7 @@ namespace ntfysh_client reconnectAttemptsLabel = new System.Windows.Forms.Label(); reconnectAttemptDelay = new System.Windows.Forms.NumericUpDown(); reconnectAttemptDelayLabel = new System.Windows.Forms.Label(); - groupBox1 = new System.Windows.Forms.GroupBox(); + nativeVersusCustomNotificationsGroupBox = new System.Windows.Forms.GroupBox(); useCustomTrayNotifications = new System.Windows.Forms.RadioButton(); useNativeWindowsNotifications = new System.Windows.Forms.RadioButton(); groupCustomNotificationSettings = new System.Windows.Forms.GroupBox(); @@ -49,7 +49,7 @@ namespace ntfysh_client ((System.ComponentModel.ISupportInitialize)timeout).BeginInit(); ((System.ComponentModel.ISupportInitialize)reconnectAttempts).BeginInit(); ((System.ComponentModel.ISupportInitialize)reconnectAttemptDelay).BeginInit(); - groupBox1.SuspendLayout(); + nativeVersusCustomNotificationsGroupBox.SuspendLayout(); groupCustomNotificationSettings.SuspendLayout(); SuspendLayout(); // @@ -140,15 +140,15 @@ namespace ntfysh_client reconnectAttemptDelayLabel.TabIndex = 7; reconnectAttemptDelayLabel.Text = "Delay between attempts (seconds, requires restart):"; // - // groupBox1 + // nativeVersusCustomNotificationsGroupBox // - groupBox1.Controls.Add(useCustomTrayNotifications); - groupBox1.Controls.Add(useNativeWindowsNotifications); - groupBox1.Location = new System.Drawing.Point(12, 147); - groupBox1.Name = "groupBox1"; - groupBox1.Size = new System.Drawing.Size(506, 67); - groupBox1.TabIndex = 9; - groupBox1.TabStop = false; + nativeVersusCustomNotificationsGroupBox.Controls.Add(useCustomTrayNotifications); + nativeVersusCustomNotificationsGroupBox.Controls.Add(useNativeWindowsNotifications); + nativeVersusCustomNotificationsGroupBox.Location = new System.Drawing.Point(12, 147); + nativeVersusCustomNotificationsGroupBox.Name = "nativeVersusCustomNotificationsGroupBox"; + nativeVersusCustomNotificationsGroupBox.Size = new System.Drawing.Size(506, 67); + nativeVersusCustomNotificationsGroupBox.TabIndex = 9; + nativeVersusCustomNotificationsGroupBox.TabStop = false; // // useCustomTrayNotifications // @@ -220,7 +220,7 @@ namespace ntfysh_client ClientSize = new System.Drawing.Size(531, 367); Controls.Add(label1); Controls.Add(groupCustomNotificationSettings); - Controls.Add(groupBox1); + Controls.Add(nativeVersusCustomNotificationsGroupBox); Controls.Add(reconnectAttemptDelay); Controls.Add(reconnectAttemptDelayLabel); Controls.Add(reconnectAttempts); @@ -241,8 +241,8 @@ namespace ntfysh_client ((System.ComponentModel.ISupportInitialize)timeout).EndInit(); ((System.ComponentModel.ISupportInitialize)reconnectAttempts).EndInit(); ((System.ComponentModel.ISupportInitialize)reconnectAttemptDelay).EndInit(); - groupBox1.ResumeLayout(false); - groupBox1.PerformLayout(); + nativeVersusCustomNotificationsGroupBox.ResumeLayout(false); + nativeVersusCustomNotificationsGroupBox.PerformLayout(); groupCustomNotificationSettings.ResumeLayout(false); groupCustomNotificationSettings.PerformLayout(); ResumeLayout(false); @@ -260,7 +260,7 @@ namespace ntfysh_client private System.Windows.Forms.Label reconnectAttemptsLabel; private System.Windows.Forms.NumericUpDown reconnectAttemptDelay; private System.Windows.Forms.Label reconnectAttemptDelayLabel; - private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.GroupBox nativeVersusCustomNotificationsGroupBox; private System.Windows.Forms.RadioButton useCustomTrayNotifications; private System.Windows.Forms.RadioButton useNativeWindowsNotifications; private System.Windows.Forms.GroupBox groupCustomNotificationSettings; -- 2.49.1 From 1ae481b434070e3d3bedcb76dfa29abebc066a76 Mon Sep 17 00:00:00 2001 From: mshafer1 <2565361+mshafer1@users.noreply.github.com> Date: Sat, 21 Dec 2024 08:42:24 -0600 Subject: [PATCH 28/41] rename elements in new dialogue to PerlCase per PR comment --- ntfysh_client/NotificationDialog.Designer.cs | 168 +++++++++---------- ntfysh_client/NotificationDialog.cs | 34 ++-- 2 files changed, 101 insertions(+), 101 deletions(-) diff --git a/ntfysh_client/NotificationDialog.Designer.cs b/ntfysh_client/NotificationDialog.Designer.cs index bc34ea4..b9f51f5 100644 --- a/ntfysh_client/NotificationDialog.Designer.cs +++ b/ntfysh_client/NotificationDialog.Designer.cs @@ -28,90 +28,90 @@ /// private void InitializeComponent() { - tbTitle = new System.Windows.Forms.TextBox(); - button1 = new System.Windows.Forms.Button(); - tbMessage = new System.Windows.Forms.RichTextBox(); - iconBox = new System.Windows.Forms.PictureBox(); - progressBar1 = new System.Windows.Forms.ProgressBar(); - lbTimeout = new System.Windows.Forms.Label(); - ((System.ComponentModel.ISupportInitialize)iconBox).BeginInit(); + TxBTitle = new System.Windows.Forms.TextBox(); + ButtonClose = new System.Windows.Forms.Button(); + TxBMessage = new System.Windows.Forms.RichTextBox(); + IconBox = new System.Windows.Forms.PictureBox(); + ProgressBar1 = new System.Windows.Forms.ProgressBar(); + LblTimeout = new System.Windows.Forms.Label(); + ((System.ComponentModel.ISupportInitialize)IconBox).BeginInit(); SuspendLayout(); // - // tbTitle + // TxBTitle // - tbTitle.BackColor = System.Drawing.SystemColors.ControlDark; - tbTitle.BorderStyle = System.Windows.Forms.BorderStyle.None; - tbTitle.Font = new System.Drawing.Font("Segoe UI", 18F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - tbTitle.ForeColor = System.Drawing.SystemColors.ControlLightLight; - tbTitle.Location = new System.Drawing.Point(54, 13); - tbTitle.Name = "tbTitle"; - tbTitle.ReadOnly = true; - tbTitle.Size = new System.Drawing.Size(683, 32); - tbTitle.TabIndex = 0; - tbTitle.MouseDown += window_MouseDown; + TxBTitle.BackColor = System.Drawing.SystemColors.ControlDark; + TxBTitle.BorderStyle = System.Windows.Forms.BorderStyle.None; + TxBTitle.Font = new System.Drawing.Font("Segoe UI", 18F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + TxBTitle.ForeColor = System.Drawing.SystemColors.ControlLightLight; + TxBTitle.Location = new System.Drawing.Point(54, 13); + TxBTitle.Name = "TxBTitle"; + TxBTitle.ReadOnly = true; + TxBTitle.Size = new System.Drawing.Size(683, 32); + TxBTitle.TabIndex = 0; + TxBTitle.MouseDown += window_MouseDown; // - // button1 + // ButtonClose // - button1.BackColor = System.Drawing.SystemColors.ActiveCaptionText; - button1.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; - button1.FlatAppearance.BorderColor = System.Drawing.Color.White; - button1.FlatAppearance.MouseOverBackColor = System.Drawing.Color.Silver; - button1.FlatStyle = System.Windows.Forms.FlatStyle.Popup; - button1.ForeColor = System.Drawing.SystemColors.ButtonFace; - button1.Location = new System.Drawing.Point(759, 7); - button1.Name = "button1"; - button1.Size = new System.Drawing.Size(29, 38); - button1.TabIndex = 1; - button1.Text = "X"; - button1.UseVisualStyleBackColor = false; - button1.Click += btnClose_Click; + ButtonClose.BackColor = System.Drawing.SystemColors.ActiveCaptionText; + ButtonClose.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; + ButtonClose.FlatAppearance.BorderColor = System.Drawing.Color.White; + ButtonClose.FlatAppearance.MouseOverBackColor = System.Drawing.Color.Silver; + ButtonClose.FlatStyle = System.Windows.Forms.FlatStyle.Popup; + ButtonClose.ForeColor = System.Drawing.SystemColors.ButtonFace; + ButtonClose.Location = new System.Drawing.Point(759, 7); + ButtonClose.Name = "ButtonClose"; + ButtonClose.Size = new System.Drawing.Size(29, 38); + ButtonClose.TabIndex = 1; + ButtonClose.Text = "X"; + ButtonClose.UseVisualStyleBackColor = false; + ButtonClose.Click += ButtonClose_ClickHandler; // - // tbMessage + // TxBMessage // - tbMessage.BackColor = System.Drawing.SystemColors.ControlDark; - tbMessage.BorderStyle = System.Windows.Forms.BorderStyle.None; - tbMessage.Font = new System.Drawing.Font("Segoe UI", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - tbMessage.ForeColor = System.Drawing.SystemColors.ControlLightLight; - tbMessage.Location = new System.Drawing.Point(12, 57); - tbMessage.Name = "tbMessage"; - tbMessage.ReadOnly = true; - tbMessage.Size = new System.Drawing.Size(776, 191); - tbMessage.TabIndex = 2; - tbMessage.Text = ""; - tbMessage.MouseDown += window_MouseDown; + TxBMessage.BackColor = System.Drawing.SystemColors.ControlDark; + TxBMessage.BorderStyle = System.Windows.Forms.BorderStyle.None; + TxBMessage.Font = new System.Drawing.Font("Segoe UI", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + TxBMessage.ForeColor = System.Drawing.SystemColors.ControlLightLight; + TxBMessage.Location = new System.Drawing.Point(12, 57); + TxBMessage.Name = "TxBMessage"; + TxBMessage.ReadOnly = true; + TxBMessage.Size = new System.Drawing.Size(776, 191); + TxBMessage.TabIndex = 2; + TxBMessage.Text = ""; + TxBMessage.MouseDown += window_MouseDown; // - // iconBox + // IconBox // - iconBox.Location = new System.Drawing.Point(12, 12); - iconBox.Name = "iconBox"; - iconBox.Size = new System.Drawing.Size(36, 39); - iconBox.TabIndex = 3; - iconBox.TabStop = false; + IconBox.Location = new System.Drawing.Point(12, 12); + IconBox.Name = "IconBox"; + IconBox.Size = new System.Drawing.Size(36, 39); + IconBox.TabIndex = 3; + IconBox.TabStop = false; // - // progressBar1 + // ProgressBar1 // - progressBar1.BackColor = System.Drawing.SystemColors.ControlDarkDark; - progressBar1.Enabled = false; - progressBar1.ForeColor = System.Drawing.SystemColors.WindowFrame; - progressBar1.Location = new System.Drawing.Point(70, 254); - progressBar1.MarqueeAnimationSpeed = 1; - progressBar1.Name = "progressBar1"; - progressBar1.Size = new System.Drawing.Size(718, 23); - progressBar1.Step = 1; - progressBar1.Style = System.Windows.Forms.ProgressBarStyle.Continuous; - progressBar1.TabIndex = 4; - progressBar1.Value = 100; + ProgressBar1.BackColor = System.Drawing.SystemColors.ControlDarkDark; + ProgressBar1.Enabled = false; + ProgressBar1.ForeColor = System.Drawing.SystemColors.WindowFrame; + ProgressBar1.Location = new System.Drawing.Point(70, 254); + ProgressBar1.MarqueeAnimationSpeed = 1; + ProgressBar1.Name = "ProgressBar1"; + ProgressBar1.Size = new System.Drawing.Size(718, 23); + ProgressBar1.Step = 1; + ProgressBar1.Style = System.Windows.Forms.ProgressBarStyle.Continuous; + ProgressBar1.TabIndex = 4; + ProgressBar1.Value = 100; // - // lbTimeout + // LblTimeout // - lbTimeout.AutoSize = true; - lbTimeout.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - lbTimeout.Location = new System.Drawing.Point(21, 254); - lbTimeout.Name = "lbTimeout"; - lbTimeout.Size = new System.Drawing.Size(43, 17); - lbTimeout.TabIndex = 5; - lbTimeout.Text = "label1"; - lbTimeout.TextAlign = System.Drawing.ContentAlignment.TopRight; + LblTimeout.AutoSize = true; + LblTimeout.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + LblTimeout.Location = new System.Drawing.Point(21, 254); + LblTimeout.Name = "LblTimeout"; + LblTimeout.Size = new System.Drawing.Size(43, 17); + LblTimeout.TabIndex = 5; + LblTimeout.Text = "label1"; + LblTimeout.TextAlign = System.Drawing.ContentAlignment.TopRight; // // NotificationDialog // @@ -119,28 +119,28 @@ AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; BackColor = System.Drawing.SystemColors.ControlDark; ClientSize = new System.Drawing.Size(800, 289); - Controls.Add(lbTimeout); - Controls.Add(progressBar1); - Controls.Add(iconBox); - Controls.Add(tbMessage); - Controls.Add(button1); - Controls.Add(tbTitle); + Controls.Add(LblTimeout); + Controls.Add(ProgressBar1); + Controls.Add(IconBox); + Controls.Add(TxBMessage); + Controls.Add(ButtonClose); + Controls.Add(TxBTitle); FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; Name = "NotificationDialog"; Text = "NotificationDialog"; Click += window_MouseDown; - ((System.ComponentModel.ISupportInitialize)iconBox).EndInit(); + ((System.ComponentModel.ISupportInitialize)IconBox).EndInit(); ResumeLayout(false); PerformLayout(); } #endregion - private System.Windows.Forms.TextBox tbTitle; - private System.Windows.Forms.Button button1; - private System.Windows.Forms.RichTextBox tbMessage; - private System.Windows.Forms.PictureBox iconBox; - private System.Windows.Forms.ProgressBar progressBar1; - private System.Windows.Forms.Label lbTimeout; + private System.Windows.Forms.TextBox TxBTitle; + private System.Windows.Forms.Button ButtonClose; + private System.Windows.Forms.RichTextBox TxBMessage; + private System.Windows.Forms.PictureBox IconBox; + private System.Windows.Forms.ProgressBar ProgressBar1; + private System.Windows.Forms.Label LblTimeout; } } \ No newline at end of file diff --git a/ntfysh_client/NotificationDialog.cs b/ntfysh_client/NotificationDialog.cs index 767ebd6..ee225de 100644 --- a/ntfysh_client/NotificationDialog.cs +++ b/ntfysh_client/NotificationDialog.cs @@ -39,10 +39,10 @@ namespace ntfysh_client } // setup data - iconBox.Image = (icon is null) ? null : ConvertToolTipIconToImage(icon.Value); + IconBox.Image = (icon is null) ? null : ConvertToolTipIconToImage(icon.Value); - tbTitle.Text = title; - tbMessage.Text = message; + TxBTitle.Text = title; + TxBMessage.Text = message; // setup timers if (_displayTimeoutTimer != null) @@ -65,7 +65,7 @@ namespace ntfysh_client if (showTimeOutBar) { - progressBar1.Value = 100; + ProgressBar1.Value = 100; _updateTimer = new System.Windows.Forms.Timer(); _updateTimer.Interval = 100; _updateTimer.Tick += UpdateProgress; @@ -74,20 +74,20 @@ namespace ntfysh_client _shownStopwatch = new Stopwatch(); _shownStopwatch.Start(); - progressBar1.Visible = true; - lbTimeout.Visible = true; + ProgressBar1.Visible = true; + LblTimeout.Visible = true; _timeout = timeout_ms; } else { - progressBar1.Visible = false; - lbTimeout.Visible = false; + ProgressBar1.Visible = false; + LblTimeout.Visible = false; } } else { - progressBar1.Visible = false; - lbTimeout.Visible = false; + ProgressBar1.Visible = false; + LblTimeout.Visible = false; } // ok, show the window @@ -99,8 +99,8 @@ namespace ntfysh_client { if (_shownStopwatch is null) return; - progressBar1.Value = (int)((_timeout - _shownStopwatch.ElapsedMilliseconds) * 100 / _timeout); - lbTimeout.Text = $"{(int)(_timeout - _shownStopwatch.ElapsedMilliseconds) / 1000}"; + ProgressBar1.Value = (int)((_timeout - _shownStopwatch.ElapsedMilliseconds) * 100 / _timeout); + LblTimeout.Text = $"{(int)(_timeout - _shownStopwatch.ElapsedMilliseconds) / 1000}"; } protected override void SetVisibleCore(bool value) @@ -174,7 +174,7 @@ namespace ntfysh_client Opacity = 1; } - private void btnClose_Click(object sender, EventArgs e) + private void ButtonClose_ClickHandler(object sender, EventArgs e) { // don't animate, immediately "close" Visible = false; @@ -202,15 +202,15 @@ namespace ntfysh_client // on a background thread, so invoke on the UI thread Invoke(new Action(() => { - lbTimeout.Visible = false; - progressBar1.Visible = false; + LblTimeout.Visible = false; + ProgressBar1.Visible = false; })); } else { // in the UI thread, invoke directly - lbTimeout.Visible = false; - progressBar1.Visible = false; + LblTimeout.Visible = false; + ProgressBar1.Visible = false; } if (_displayTimeoutTimer != null) // check if the timer has already been disposed -- 2.49.1 From 7a5d0673430ee0604a1ed58d783db2b6b9e08e0b Mon Sep 17 00:00:00 2001 From: mshafer1 <2565361+mshafer1@users.noreply.github.com> Date: Sat, 21 Dec 2024 09:39:04 -0600 Subject: [PATCH 29/41] fix button hover behavior --- ntfysh_client/NotificationDialog.Designer.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ntfysh_client/NotificationDialog.Designer.cs b/ntfysh_client/NotificationDialog.Designer.cs index b9f51f5..40b8faa 100644 --- a/ntfysh_client/NotificationDialog.Designer.cs +++ b/ntfysh_client/NotificationDialog.Designer.cs @@ -54,9 +54,9 @@ // ButtonClose.BackColor = System.Drawing.SystemColors.ActiveCaptionText; ButtonClose.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None; - ButtonClose.FlatAppearance.BorderColor = System.Drawing.Color.White; - ButtonClose.FlatAppearance.MouseOverBackColor = System.Drawing.Color.Silver; - ButtonClose.FlatStyle = System.Windows.Forms.FlatStyle.Popup; + ButtonClose.FlatAppearance.BorderSize = 0; + ButtonClose.FlatAppearance.MouseOverBackColor = System.Drawing.Color.DimGray; + ButtonClose.FlatStyle = System.Windows.Forms.FlatStyle.Flat; ButtonClose.ForeColor = System.Drawing.SystemColors.ButtonFace; ButtonClose.Location = new System.Drawing.Point(759, 7); ButtonClose.Name = "ButtonClose"; -- 2.49.1 From f187cd8ea607fa2d2641f4ea9eed882bf1db4f04 Mon Sep 17 00:00:00 2001 From: mshafer1 <2565361+mshafer1@users.noreply.github.com> Date: Sat, 21 Dec 2024 09:39:43 -0600 Subject: [PATCH 30/41] introduce theme files and handle in notification popup --- ntfysh_client/NotificationDialog.cs | 41 +++++++++++++++++++++++++++ ntfysh_client/Themes/BaseTheme.cs | 12 ++++++++ ntfysh_client/Themes/DarkModeTheme.cs | 12 ++++++++ ntfysh_client/Themes/DefaultTheme.cs | 12 ++++++++ 4 files changed, 77 insertions(+) create mode 100644 ntfysh_client/Themes/BaseTheme.cs create mode 100644 ntfysh_client/Themes/DarkModeTheme.cs create mode 100644 ntfysh_client/Themes/DefaultTheme.cs diff --git a/ntfysh_client/NotificationDialog.cs b/ntfysh_client/NotificationDialog.cs index ee225de..a824801 100644 --- a/ntfysh_client/NotificationDialog.cs +++ b/ntfysh_client/NotificationDialog.cs @@ -5,6 +5,7 @@ using System.Windows.Forms; using System.ComponentModel; using Microsoft.Win32; using System.Diagnostics; +using ntfysh_client.Themes; namespace ntfysh_client @@ -21,6 +22,10 @@ namespace ntfysh_client private System.Windows.Forms.Timer? _updateTimer = null; private Stopwatch? _shownStopwatch = null; + private BaseTheme _darkModeTheme = new DarkModeTheme(); + private BaseTheme _defaultTheme = new DefaultTheme(); + private BaseTheme? _theme = null; + public NotificationDialog() { ShowInTaskbar = false; @@ -38,6 +43,17 @@ namespace ntfysh_client HandleTimeout(null, null); } + if(showInDarkMode) + { + _theme = _darkModeTheme; + } + else + { + _theme = _defaultTheme; + } + + ApplyTheme(); + // setup data IconBox.Image = (icon is null) ? null : ConvertToolTipIconToImage(icon.Value); @@ -95,6 +111,31 @@ namespace ntfysh_client SetWindowPosition(); } + private void ApplyTheme() + { + if (_theme is null) _theme = _defaultTheme; + + // back colors + BackColor = _theme.BackgroundColor; + TxBTitle.BackColor = _theme.BackgroundColor; + TxBMessage.BackColor = _theme.BackgroundColor; + LblTimeout.BackColor = _theme.BackgroundColor; + ProgressBar1.BackColor = _theme.BackgroundColor; + + // this one is not "hiding" + ButtonClose.BackColor = _theme.ControlBackGroundColor; + // handle mouse over + ButtonClose.FlatAppearance.MouseOverBackColor = _theme.ControlMouseOverBackgroundColor; + + // fore colors + ForeColor = _theme.ForegroundColor; + TxBTitle.ForeColor = _theme.ForegroundColor; + TxBMessage.ForeColor = _theme.ForegroundColor; + LblTimeout.ForeColor = _theme.ForegroundColor; + ProgressBar1.ForeColor = _theme.ForegroundColor; + ButtonClose.ForeColor = _theme.ForegroundColor; + } + private void UpdateProgress(object? sender, EventArgs e) { if (_shownStopwatch is null) return; diff --git a/ntfysh_client/Themes/BaseTheme.cs b/ntfysh_client/Themes/BaseTheme.cs new file mode 100644 index 0000000..b139ab9 --- /dev/null +++ b/ntfysh_client/Themes/BaseTheme.cs @@ -0,0 +1,12 @@ +using System.Drawing; + +namespace ntfysh_client.Themes +{ + internal abstract class BaseTheme + { + public abstract Color BackgroundColor {get; } + public abstract Color ControlBackGroundColor {get; } + public abstract Color ControlMouseOverBackgroundColor { get; } + public abstract Color ForegroundColor { get; } + } +} diff --git a/ntfysh_client/Themes/DarkModeTheme.cs b/ntfysh_client/Themes/DarkModeTheme.cs new file mode 100644 index 0000000..51adc3c --- /dev/null +++ b/ntfysh_client/Themes/DarkModeTheme.cs @@ -0,0 +1,12 @@ +using System.Drawing; + +namespace ntfysh_client.Themes +{ + internal class DarkModeTheme: BaseTheme + { + public override Color BackgroundColor { get => SystemColors.ControlDark; } + public override Color ControlBackGroundColor { get => Color.Black; } + public override Color ControlMouseOverBackgroundColor { get => Color.Silver; } + public override Color ForegroundColor { get => SystemColors.ControlLight; } + } +} diff --git a/ntfysh_client/Themes/DefaultTheme.cs b/ntfysh_client/Themes/DefaultTheme.cs new file mode 100644 index 0000000..b435a16 --- /dev/null +++ b/ntfysh_client/Themes/DefaultTheme.cs @@ -0,0 +1,12 @@ +using System.Drawing; + +namespace ntfysh_client.Themes +{ + internal class DefaultTheme: BaseTheme + { + public override Color BackgroundColor { get => Color.White; } + public override Color ControlBackGroundColor { get => SystemColors.ControlDark; } + public override Color ControlMouseOverBackgroundColor { get => Color.LightSkyBlue; } + public override Color ForegroundColor { get => SystemColors.WindowText; } + } +} -- 2.49.1 From c448de2c17b034e031499a462ec68acffbb7fb55 Mon Sep 17 00:00:00 2001 From: mshafer1 <2565361+mshafer1@users.noreply.github.com> Date: Sat, 21 Dec 2024 09:40:03 -0600 Subject: [PATCH 31/41] remove unused imports --- ntfysh_client/NotificationDialog.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/ntfysh_client/NotificationDialog.cs b/ntfysh_client/NotificationDialog.cs index a824801..f02ab4d 100644 --- a/ntfysh_client/NotificationDialog.cs +++ b/ntfysh_client/NotificationDialog.cs @@ -2,8 +2,6 @@ using System.Drawing; using System.Runtime.InteropServices; using System.Windows.Forms; -using System.ComponentModel; -using Microsoft.Win32; using System.Diagnostics; using ntfysh_client.Themes; -- 2.49.1 From 025a7d04f8e01c033502dfcdaad08d8b95ca59a3 Mon Sep 17 00:00:00 2001 From: mshafer1 <2565361+mshafer1@users.noreply.github.com> Date: Sat, 21 Dec 2024 09:45:08 -0600 Subject: [PATCH 32/41] use 0 for "don't timeout" and don't allow -1 --- ntfysh_client/SettingsDialog.Designer.cs | 1 - ntfysh_client/SettingsDialog.cs | 5 ++--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/ntfysh_client/SettingsDialog.Designer.cs b/ntfysh_client/SettingsDialog.Designer.cs index b2fe95c..157b765 100644 --- a/ntfysh_client/SettingsDialog.Designer.cs +++ b/ntfysh_client/SettingsDialog.Designer.cs @@ -99,7 +99,6 @@ namespace ntfysh_client // timeout.Location = new System.Drawing.Point(13, 28); timeout.Maximum = new decimal(new int[] { -1981284353, -1966660860, 0, 0 }); - timeout.Minimum = new decimal(new int[] { 1, 0, 0, int.MinValue }); timeout.Name = "timeout"; timeout.Size = new System.Drawing.Size(506, 23); timeout.TabIndex = 4; diff --git a/ntfysh_client/SettingsDialog.cs b/ntfysh_client/SettingsDialog.cs index 3cb11c5..c2626e8 100644 --- a/ntfysh_client/SettingsDialog.cs +++ b/ntfysh_client/SettingsDialog.cs @@ -8,7 +8,7 @@ namespace ntfysh_client public decimal Timeout { get => timeout.Value; - set => timeout.Value = Math.Max(value, timeout.Minimum); // Ensure value is within bounds despite our changing minimum + set => timeout.Value = value; } public decimal ReconnectAttempts @@ -78,7 +78,6 @@ namespace ntfysh_client { groupCustomNotificationSettings.Enabled = useCustomTrayNotifications.Checked; timeoutLabel.Text = useCustomTrayNotifications.Checked ? _customNotificationsTimeout : _windowsNotificationsTimeout; - timeout.Minimum = useCustomTrayNotifications.Checked ? -1 : 0; } private void UseCustomTrayNotifications_CheckedChanged(object sender, EventArgs e) @@ -87,6 +86,6 @@ namespace ntfysh_client } private const string _windowsNotificationsTimeout = "Notification Toast Timeout (seconds, may be ignored by OS based on accessibility settings):"; - private const string _customNotificationsTimeout = "Notification Toast Timeout (seconds, use -1 to require closing notification):"; + private const string _customNotificationsTimeout = "Notification Toast Timeout (seconds, use 0 to require closing notification):"; } } -- 2.49.1 From 5f57898f9b35b0bdf4b60d228db286469064ff7a Mon Sep 17 00:00:00 2001 From: mshafer1 <2565361+mshafer1@users.noreply.github.com> Date: Sat, 21 Dec 2024 09:53:57 -0600 Subject: [PATCH 33/41] use seconds for value of timeout rather then mS --- ntfysh_client/MainForm.cs | 6 +++--- ntfysh_client/NotificationDialog.cs | 14 +++++++------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/ntfysh_client/MainForm.cs b/ntfysh_client/MainForm.cs index 89a0b70..cb9b13e 100644 --- a/ntfysh_client/MainForm.cs +++ b/ntfysh_client/MainForm.cs @@ -81,9 +81,9 @@ namespace ntfysh_client { _notificationDialog.ShowNotification( - title: finalTitle, - message: e.Message, - timeout_ms: (int)TimeSpan.FromSeconds((double)Program.Settings.Timeout).TotalMilliseconds, + title: finalTitle, + message: e.Message, + timeoutSeconds: (int)Program.Settings.Timeout, icon: priorityIcon, showTimeOutBar: Program.Settings.CustomTrayNotificationsShowTimeoutBar, showInDarkMode: Program.Settings.CustomTrayNotificationsShowInDarkMode diff --git a/ntfysh_client/NotificationDialog.cs b/ntfysh_client/NotificationDialog.cs index f02ab4d..a5cc21d 100644 --- a/ntfysh_client/NotificationDialog.cs +++ b/ntfysh_client/NotificationDialog.cs @@ -15,7 +15,7 @@ namespace ntfysh_client private const int ScreenMargin = 20; - private int _timeout = 0; + private int _timeoutSeconds = 0; private System.Timers.Timer? _displayTimeoutTimer = null; private System.Windows.Forms.Timer? _updateTimer = null; private Stopwatch? _shownStopwatch = null; @@ -33,7 +33,7 @@ namespace ntfysh_client InitializeWindowHidden(); } - public void ShowNotification(string title, string message, int timeout_ms = -1, ToolTipIcon? icon = null, bool showTimeOutBar = true, bool showInDarkMode = true) + public void ShowNotification(string title, string message, int timeoutSeconds = 0, ToolTipIcon? icon = null, bool showTimeOutBar = true, bool showInDarkMode = true) { if (Visible) { @@ -71,9 +71,9 @@ namespace ntfysh_client _updateTimer.Dispose(); } - if (timeout_ms > 0) + if (timeoutSeconds > 0) { - _displayTimeoutTimer = new System.Timers.Timer(timeout_ms); + _displayTimeoutTimer = new System.Timers.Timer(timeoutSeconds * 1000); _displayTimeoutTimer.Elapsed += HandleTimeout; _displayTimeoutTimer.Start(); @@ -90,7 +90,7 @@ namespace ntfysh_client ProgressBar1.Visible = true; LblTimeout.Visible = true; - _timeout = timeout_ms; + _timeoutSeconds = timeoutSeconds; } else { @@ -138,8 +138,8 @@ namespace ntfysh_client { if (_shownStopwatch is null) return; - ProgressBar1.Value = (int)((_timeout - _shownStopwatch.ElapsedMilliseconds) * 100 / _timeout); - LblTimeout.Text = $"{(int)(_timeout - _shownStopwatch.ElapsedMilliseconds) / 1000}"; + ProgressBar1.Value = (_timeoutSeconds - _shownStopwatch.Elapsed.Seconds) * 100 / _timeoutSeconds; + LblTimeout.Text = $"{_timeoutSeconds - _shownStopwatch.Elapsed.Seconds}"; } protected override void SetVisibleCore(bool value) -- 2.49.1 From 1b51a06eb6993f0c439eb2d1726fc33da12b8dd0 Mon Sep 17 00:00:00 2001 From: mshafer1 <2565361+mshafer1@users.noreply.github.com> Date: Sat, 21 Dec 2024 15:27:22 -0600 Subject: [PATCH 34/41] change default of new notifications to light mode --- ntfysh_client/MainForm.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ntfysh_client/MainForm.cs b/ntfysh_client/MainForm.cs index cb9b13e..24fe6ce 100644 --- a/ntfysh_client/MainForm.cs +++ b/ntfysh_client/MainForm.cs @@ -331,7 +331,7 @@ namespace ntfysh_client UseNativeWindowsNotifications = true, UseCustomTrayNotifications = false, CustomTrayNotificationsShowTimeoutBar = true, - CustomTrayNotificationsShowInDarkMode = true, + CustomTrayNotificationsShowInDarkMode = false, }; private void MergeSettingsRevisions(SettingsModel older, SettingsModel newer) -- 2.49.1 From 582eef1b9d805f797d9bee80ac50fbb522ecdc71 Mon Sep 17 00:00:00 2001 From: mshafer1 <2565361+mshafer1@users.noreply.github.com> Date: Sat, 21 Dec 2024 15:27:32 -0600 Subject: [PATCH 35/41] massage the colors a little more --- ntfysh_client/NotificationDialog.cs | 2 +- ntfysh_client/Themes/DarkModeTheme.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ntfysh_client/NotificationDialog.cs b/ntfysh_client/NotificationDialog.cs index a5cc21d..d456faa 100644 --- a/ntfysh_client/NotificationDialog.cs +++ b/ntfysh_client/NotificationDialog.cs @@ -122,6 +122,7 @@ namespace ntfysh_client // this one is not "hiding" ButtonClose.BackColor = _theme.ControlBackGroundColor; + ButtonClose.ForeColor = _theme.BackgroundColor; // handle mouse over ButtonClose.FlatAppearance.MouseOverBackColor = _theme.ControlMouseOverBackgroundColor; @@ -131,7 +132,6 @@ namespace ntfysh_client TxBMessage.ForeColor = _theme.ForegroundColor; LblTimeout.ForeColor = _theme.ForegroundColor; ProgressBar1.ForeColor = _theme.ForegroundColor; - ButtonClose.ForeColor = _theme.ForegroundColor; } private void UpdateProgress(object? sender, EventArgs e) diff --git a/ntfysh_client/Themes/DarkModeTheme.cs b/ntfysh_client/Themes/DarkModeTheme.cs index 51adc3c..300809f 100644 --- a/ntfysh_client/Themes/DarkModeTheme.cs +++ b/ntfysh_client/Themes/DarkModeTheme.cs @@ -7,6 +7,6 @@ namespace ntfysh_client.Themes public override Color BackgroundColor { get => SystemColors.ControlDark; } public override Color ControlBackGroundColor { get => Color.Black; } public override Color ControlMouseOverBackgroundColor { get => Color.Silver; } - public override Color ForegroundColor { get => SystemColors.ControlLight; } + public override Color ForegroundColor { get => SystemColors.WindowText; } } } -- 2.49.1 From 52f315e4e35b4b883c823d23e7fe66ceea7b772d Mon Sep 17 00:00:00 2001 From: mshafer1 <2565361+mshafer1@users.noreply.github.com> Date: Mon, 23 Dec 2024 09:23:15 -0600 Subject: [PATCH 36/41] use an enum --- ntfysh_client/MainForm.cs | 15 ++++++--------- ntfysh_client/SettingsDialog.cs | 5 +++++ ntfysh_client/SettingsModel.cs | 9 +++++++-- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/ntfysh_client/MainForm.cs b/ntfysh_client/MainForm.cs index 24fe6ce..c9c6a70 100644 --- a/ntfysh_client/MainForm.cs +++ b/ntfysh_client/MainForm.cs @@ -73,7 +73,7 @@ namespace ntfysh_client string finalTitle = string.IsNullOrWhiteSpace(e.Title) ? $"{e.Sender.TopicId}@{e.Sender.ServerUrl}" : e.Title; - if (Program.Settings.UseNativeWindowsNotifications) + if (Program.Settings.NotificationsMethod == SettingsModel.NotificationsType.NativeWindows) { notifyIcon.ShowBalloonTip((int)TimeSpan.FromSeconds((double)Program.Settings.Timeout).TotalMilliseconds, finalTitle, e.Message, priorityIcon); } @@ -152,8 +152,8 @@ namespace ntfysh_client //Load current settings into dialog dialog.ReconnectAttempts = Program.Settings.ReconnectAttempts; dialog.ReconnectAttemptDelay = Program.Settings.ReconnectAttemptDelay; - dialog.UseNativeWindowsNotifications = Program.Settings.UseNativeWindowsNotifications; - dialog.UseCustomTrayNotifications = Program.Settings.UseCustomTrayNotifications; + dialog.UseNativeWindowsNotifications = Program.Settings.NotificationsMethod == SettingsModel.NotificationsType.NativeWindows; + dialog.UseCustomTrayNotifications = Program.Settings.NotificationsMethod == SettingsModel.NotificationsType.CustomTray; dialog.CustomTrayNotificationsShowTimeoutBar = Program.Settings.CustomTrayNotificationsShowTimeoutBar; dialog.CustomTrayNotificationsShowInDarkMode = Program.Settings.CustomTrayNotificationsShowInDarkMode; dialog.Timeout = Program.Settings.Timeout; // set timeout last so bounds are setup before setting value @@ -168,8 +168,7 @@ namespace ntfysh_client Program.Settings.Timeout = dialog.Timeout; Program.Settings.ReconnectAttempts = dialog.ReconnectAttempts; Program.Settings.ReconnectAttemptDelay = dialog.ReconnectAttemptDelay; - Program.Settings.UseNativeWindowsNotifications = dialog.UseNativeWindowsNotifications; - Program.Settings.UseCustomTrayNotifications = dialog.UseCustomTrayNotifications; + Program.Settings.NotificationsMethod = (dialog.UseNativeWindowsNotifications)? SettingsModel.NotificationsType.NativeWindows : SettingsModel.NotificationsType.CustomTray; Program.Settings.CustomTrayNotificationsShowTimeoutBar = dialog.CustomTrayNotificationsShowTimeoutBar; Program.Settings.CustomTrayNotificationsShowInDarkMode = dialog.CustomTrayNotificationsShowInDarkMode; @@ -328,8 +327,7 @@ namespace ntfysh_client Timeout = 5, ReconnectAttempts = 10, ReconnectAttemptDelay = 3, - UseNativeWindowsNotifications = true, - UseCustomTrayNotifications = false, + NotificationsMethod = SettingsModel.NotificationsType.NativeWindows, CustomTrayNotificationsShowTimeoutBar = true, CustomTrayNotificationsShowInDarkMode = false, }; @@ -346,8 +344,7 @@ namespace ntfysh_client //Apply settings introduced in Revision 2 (Native vs custom notifications) if (older.Revision < 2) { - older.UseNativeWindowsNotifications = newer.UseNativeWindowsNotifications; - older.UseCustomTrayNotifications = newer.UseCustomTrayNotifications; + older.NotificationsMethod = newer.NotificationsMethod; older.CustomTrayNotificationsShowTimeoutBar = newer.CustomTrayNotificationsShowTimeoutBar; older.CustomTrayNotificationsShowInDarkMode = newer.CustomTrayNotificationsShowInDarkMode; } diff --git a/ntfysh_client/SettingsDialog.cs b/ntfysh_client/SettingsDialog.cs index c2626e8..754c551 100644 --- a/ntfysh_client/SettingsDialog.cs +++ b/ntfysh_client/SettingsDialog.cs @@ -1,10 +1,13 @@ using System; using System.Windows.Forms; +using static ntfysh_client.SettingsModel; namespace ntfysh_client { public partial class SettingsDialog : Form { + public NotificationsType NotificationsMethod { get; set; } + public decimal Timeout { get => timeout.Value; @@ -31,6 +34,7 @@ namespace ntfysh_client { useNativeWindowsNotifications.Checked = value; groupCustomNotificationSettings.Enabled = !value; + NotificationsMethod = (value) ? NotificationsType.NativeWindows : NotificationsType.CustomTray; } } @@ -40,6 +44,7 @@ namespace ntfysh_client set { useCustomTrayNotifications.Checked = value; groupCustomNotificationSettings.Enabled = value; + NotificationsMethod = (value) ? NotificationsType.NativeWindows : NotificationsType.CustomTray; } } #endregion diff --git a/ntfysh_client/SettingsModel.cs b/ntfysh_client/SettingsModel.cs index b370db0..198580f 100644 --- a/ntfysh_client/SettingsModel.cs +++ b/ntfysh_client/SettingsModel.cs @@ -2,12 +2,17 @@ { public class SettingsModel { + public enum NotificationsType + { + NativeWindows, + CustomTray + } + public uint Revision { get; set; } public decimal Timeout { get; set; } public decimal ReconnectAttempts { get; set; } public decimal ReconnectAttemptDelay { get; set; } - public bool UseNativeWindowsNotifications { get; set; } - public bool UseCustomTrayNotifications { get; set; } + public NotificationsType NotificationsMethod { get; set; } public bool CustomTrayNotificationsShowTimeoutBar { get; set; } public bool CustomTrayNotificationsShowInDarkMode { get; set; } } -- 2.49.1 From 1acd970af6bde6a4f316aee298fdc50423483192 Mon Sep 17 00:00:00 2001 From: mshafer1 <2565361+mshafer1@users.noreply.github.com> Date: Mon, 23 Dec 2024 13:12:23 -0600 Subject: [PATCH 37/41] apply Rider suggestions --- ntfysh_client/NotificationDialog.cs | 31 +++++++++++------------------ ntfysh_client/SettingsDialog.cs | 6 +++--- 2 files changed, 15 insertions(+), 22 deletions(-) diff --git a/ntfysh_client/NotificationDialog.cs b/ntfysh_client/NotificationDialog.cs index d456faa..c27f3db 100644 --- a/ntfysh_client/NotificationDialog.cs +++ b/ntfysh_client/NotificationDialog.cs @@ -20,8 +20,8 @@ namespace ntfysh_client private System.Windows.Forms.Timer? _updateTimer = null; private Stopwatch? _shownStopwatch = null; - private BaseTheme _darkModeTheme = new DarkModeTheme(); - private BaseTheme _defaultTheme = new DefaultTheme(); + private readonly BaseTheme _darkModeTheme = new DarkModeTheme(); + private readonly BaseTheme _defaultTheme = new DefaultTheme(); private BaseTheme? _theme = null; public NotificationDialog() @@ -41,14 +41,7 @@ namespace ntfysh_client HandleTimeout(null, null); } - if(showInDarkMode) - { - _theme = _darkModeTheme; - } - else - { - _theme = _defaultTheme; - } + _theme = showInDarkMode ? _darkModeTheme : _defaultTheme; ApplyTheme(); @@ -111,7 +104,7 @@ namespace ntfysh_client private void ApplyTheme() { - if (_theme is null) _theme = _defaultTheme; + _theme ??= _defaultTheme; // back colors BackColor = _theme.BackgroundColor; @@ -139,7 +132,7 @@ namespace ntfysh_client if (_shownStopwatch is null) return; ProgressBar1.Value = (_timeoutSeconds - _shownStopwatch.Elapsed.Seconds) * 100 / _timeoutSeconds; - LblTimeout.Text = $"{_timeoutSeconds - _shownStopwatch.Elapsed.Seconds}"; + LblTimeout.Text = $@"{_timeoutSeconds - _shownStopwatch.Elapsed.Seconds}"; } protected override void SetVisibleCore(bool value) @@ -153,7 +146,7 @@ namespace ntfysh_client AnimateWindow( Handle, time: 250, - flags: NFWinUserAnimateWindowConstnats.AW_SLIDE | NFWinUserAnimateWindowConstnats.AW_VER_NEGATIVE + flags: NFWinUserAnimateWindowConstants.AW_SLIDE | NFWinUserAnimateWindowConstants.AW_VER_NEGATIVE ); } @@ -162,11 +155,11 @@ namespace ntfysh_client private void SetWindowPosition() { - int workingtop = Screen.PrimaryScreen.WorkingArea.Height - Height; - Top = workingtop - NotificationDialog.ScreenMargin; + var workingTop = Screen.PrimaryScreen.WorkingArea.Height - Height; + Top = workingTop - NotificationDialog.ScreenMargin; - int workingleft = Screen.PrimaryScreen.WorkingArea.Width - Width; - Left = workingleft - NotificationDialog.ScreenMargin; + var workingLeft = Screen.PrimaryScreen.WorkingArea.Width - Width; + Left = workingLeft - NotificationDialog.ScreenMargin; } private void UIThreadAnimatedHideWindow(object? sender, EventArgs? e) @@ -175,7 +168,7 @@ namespace ntfysh_client AnimateWindow( Handle, time: 250, - flags: NFWinUserAnimateWindowConstnats.AW_SLIDE | NFWinUserAnimateWindowConstnats.AW_VER_POSITIVE | NFWinUserAnimateWindowConstnats.AW_HIDE + flags: NFWinUserAnimateWindowConstants.AW_SLIDE | NFWinUserAnimateWindowConstants.AW_VER_POSITIVE | NFWinUserAnimateWindowConstants.AW_HIDE ); Visible = false; @@ -219,7 +212,7 @@ namespace ntfysh_client Visible = false; } - private class NFWinUserAnimateWindowConstnats + private class NFWinUserAnimateWindowConstants { public const int AW_HOR_POSITIVE = 0x00000001; public const int AW_HOR_NEGATIVE = 0x00000002; diff --git a/ntfysh_client/SettingsDialog.cs b/ntfysh_client/SettingsDialog.cs index 754c551..20cbfa2 100644 --- a/ntfysh_client/SettingsDialog.cs +++ b/ntfysh_client/SettingsDialog.cs @@ -66,7 +66,7 @@ namespace ntfysh_client public SettingsDialog() { InitializeComponent(); - SetNotificationsUIElements(); + SetNotificationsUiElements(); } private void saveButton_Click(object sender, EventArgs e) @@ -79,7 +79,7 @@ namespace ntfysh_client DialogResult = DialogResult.Cancel; } - private void SetNotificationsUIElements() + private void SetNotificationsUiElements() { groupCustomNotificationSettings.Enabled = useCustomTrayNotifications.Checked; timeoutLabel.Text = useCustomTrayNotifications.Checked ? _customNotificationsTimeout : _windowsNotificationsTimeout; @@ -87,7 +87,7 @@ namespace ntfysh_client private void UseCustomTrayNotifications_CheckedChanged(object sender, EventArgs e) { - SetNotificationsUIElements(); + SetNotificationsUiElements(); } private const string _windowsNotificationsTimeout = "Notification Toast Timeout (seconds, may be ignored by OS based on accessibility settings):"; -- 2.49.1 From 2add8ad2d6a5d292e50b1352a2e348525c884e65 Mon Sep 17 00:00:00 2001 From: mshafer1 <2565361+mshafer1@users.noreply.github.com> Date: Mon, 23 Dec 2024 13:13:35 -0600 Subject: [PATCH 38/41] Make the blue a little closer to the true default --- ntfysh_client/Themes/DefaultTheme.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ntfysh_client/Themes/DefaultTheme.cs b/ntfysh_client/Themes/DefaultTheme.cs index b435a16..7c3ce2d 100644 --- a/ntfysh_client/Themes/DefaultTheme.cs +++ b/ntfysh_client/Themes/DefaultTheme.cs @@ -6,7 +6,7 @@ namespace ntfysh_client.Themes { public override Color BackgroundColor { get => Color.White; } public override Color ControlBackGroundColor { get => SystemColors.ControlDark; } - public override Color ControlMouseOverBackgroundColor { get => Color.LightSkyBlue; } + public override Color ControlMouseOverBackgroundColor { get => Color.CadetBlue; } public override Color ForegroundColor { get => SystemColors.WindowText; } } } -- 2.49.1 From 4fbc4ca4e47973fefb4bbba605c9ca6d45eedb10 Mon Sep 17 00:00:00 2001 From: mshafer1 <2565361+mshafer1@users.noreply.github.com> Date: Fri, 10 Jan 2025 21:05:28 -0600 Subject: [PATCH 39/41] add support for still playing the Windows alert sound --- ntfysh_client/MainForm.cs | 7 +++++- ntfysh_client/NotificationDialog.cs | 31 +++++++++++++++++++++++- ntfysh_client/SettingsDialog.Designer.cs | 19 ++++++++++++--- ntfysh_client/SettingsDialog.cs | 6 +++++ ntfysh_client/SettingsDialog.resx | 4 +-- ntfysh_client/SettingsModel.cs | 1 + 6 files changed, 61 insertions(+), 7 deletions(-) diff --git a/ntfysh_client/MainForm.cs b/ntfysh_client/MainForm.cs index c9c6a70..10198ea 100644 --- a/ntfysh_client/MainForm.cs +++ b/ntfysh_client/MainForm.cs @@ -86,7 +86,8 @@ namespace ntfysh_client timeoutSeconds: (int)Program.Settings.Timeout, icon: priorityIcon, showTimeOutBar: Program.Settings.CustomTrayNotificationsShowTimeoutBar, - showInDarkMode: Program.Settings.CustomTrayNotificationsShowInDarkMode + showInDarkMode: Program.Settings.CustomTrayNotificationsShowInDarkMode, + playNotificationSound: Program.Settings.CustomTrayNotificationsPlayDefaultWindowsSound ); } } @@ -156,6 +157,7 @@ namespace ntfysh_client dialog.UseCustomTrayNotifications = Program.Settings.NotificationsMethod == SettingsModel.NotificationsType.CustomTray; dialog.CustomTrayNotificationsShowTimeoutBar = Program.Settings.CustomTrayNotificationsShowTimeoutBar; dialog.CustomTrayNotificationsShowInDarkMode = Program.Settings.CustomTrayNotificationsShowInDarkMode; + dialog.CustomTrayNotificationsPlayDefaultWindowsSound = Program.Settings.CustomTrayNotificationsPlayDefaultWindowsSound; dialog.Timeout = Program.Settings.Timeout; // set timeout last so bounds are setup before setting value //Show dialog @@ -171,6 +173,7 @@ namespace ntfysh_client Program.Settings.NotificationsMethod = (dialog.UseNativeWindowsNotifications)? SettingsModel.NotificationsType.NativeWindows : SettingsModel.NotificationsType.CustomTray; Program.Settings.CustomTrayNotificationsShowTimeoutBar = dialog.CustomTrayNotificationsShowTimeoutBar; Program.Settings.CustomTrayNotificationsShowInDarkMode = dialog.CustomTrayNotificationsShowInDarkMode; + Program.Settings.CustomTrayNotificationsPlayDefaultWindowsSound = dialog.CustomTrayNotificationsPlayDefaultWindowsSound; //Save new settings persistently SaveSettingsToFile(); @@ -330,6 +333,7 @@ namespace ntfysh_client NotificationsMethod = SettingsModel.NotificationsType.NativeWindows, CustomTrayNotificationsShowTimeoutBar = true, CustomTrayNotificationsShowInDarkMode = false, + CustomTrayNotificationsPlayDefaultWindowsSound = true, }; private void MergeSettingsRevisions(SettingsModel older, SettingsModel newer) @@ -347,6 +351,7 @@ namespace ntfysh_client older.NotificationsMethod = newer.NotificationsMethod; older.CustomTrayNotificationsShowTimeoutBar = newer.CustomTrayNotificationsShowTimeoutBar; older.CustomTrayNotificationsShowInDarkMode = newer.CustomTrayNotificationsShowInDarkMode; + older.CustomTrayNotificationsPlayDefaultWindowsSound = newer.CustomTrayNotificationsPlayDefaultWindowsSound; } //Update the revision diff --git a/ntfysh_client/NotificationDialog.cs b/ntfysh_client/NotificationDialog.cs index c27f3db..7f70a8f 100644 --- a/ntfysh_client/NotificationDialog.cs +++ b/ntfysh_client/NotificationDialog.cs @@ -4,6 +4,8 @@ using System.Runtime.InteropServices; using System.Windows.Forms; using System.Diagnostics; using ntfysh_client.Themes; +using Microsoft.Win32; +using System.Media; namespace ntfysh_client @@ -33,7 +35,7 @@ namespace ntfysh_client InitializeWindowHidden(); } - public void ShowNotification(string title, string message, int timeoutSeconds = 0, ToolTipIcon? icon = null, bool showTimeOutBar = true, bool showInDarkMode = true) + public void ShowNotification(string title, string message, int timeoutSeconds = 0, ToolTipIcon? icon = null, bool showTimeOutBar = true, bool showInDarkMode = true, bool playNotificationSound = false) { if (Visible) { @@ -100,6 +102,10 @@ namespace ntfysh_client // ok, show the window Show(); SetWindowPosition(); + if(playNotificationSound) + { + PlayNotificationSound(); + } } private void ApplyTheme() @@ -265,5 +271,28 @@ namespace ntfysh_client _shownStopwatch = null; } } + + private void PlayNotificationSound() + { + bool found = false; + try + { + using RegistryKey? key = Registry.CurrentUser.OpenSubKey(@"AppEvents\Schemes\Apps\.Default\Notification.Default\.Current"); + if (key != null) + { + Object? o = key.GetValue(null); // pass null to get (Default) + if (o != null) + { + SoundPlayer theSound = new SoundPlayer((String)o); + theSound.Play(); + found = true; + } + } + } + catch + { } + if (!found) + SystemSounds.Beep.Play(); // consolation prize + } } } diff --git a/ntfysh_client/SettingsDialog.Designer.cs b/ntfysh_client/SettingsDialog.Designer.cs index 157b765..428625a 100644 --- a/ntfysh_client/SettingsDialog.Designer.cs +++ b/ntfysh_client/SettingsDialog.Designer.cs @@ -42,6 +42,7 @@ namespace ntfysh_client useCustomTrayNotifications = new System.Windows.Forms.RadioButton(); useNativeWindowsNotifications = new System.Windows.Forms.RadioButton(); groupCustomNotificationSettings = new System.Windows.Forms.GroupBox(); + customNotificationsPlayWindowsNotificationAudio = new System.Windows.Forms.CheckBox(); customNotificationsShowInDarkMode = new System.Windows.Forms.CheckBox(); customNotificationsShowTimeoutBar = new System.Windows.Forms.CheckBox(); label1 = new System.Windows.Forms.Label(); @@ -59,7 +60,7 @@ namespace ntfysh_client buttonPanel.Controls.Add(cancelButton); buttonPanel.Controls.Add(saveButton); buttonPanel.Dock = System.Windows.Forms.DockStyle.Bottom; - buttonPanel.Location = new System.Drawing.Point(0, 316); + buttonPanel.Location = new System.Drawing.Point(0, 336); buttonPanel.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); buttonPanel.Name = "buttonPanel"; buttonPanel.Size = new System.Drawing.Size(531, 51); @@ -174,14 +175,25 @@ namespace ntfysh_client // // groupCustomNotificationSettings // + groupCustomNotificationSettings.Controls.Add(customNotificationsPlayWindowsNotificationAudio); groupCustomNotificationSettings.Controls.Add(customNotificationsShowInDarkMode); groupCustomNotificationSettings.Controls.Add(customNotificationsShowTimeoutBar); groupCustomNotificationSettings.Location = new System.Drawing.Point(12, 243); groupCustomNotificationSettings.Name = "groupCustomNotificationSettings"; - groupCustomNotificationSettings.Size = new System.Drawing.Size(504, 67); + groupCustomNotificationSettings.Size = new System.Drawing.Size(504, 87); groupCustomNotificationSettings.TabIndex = 10; groupCustomNotificationSettings.TabStop = false; // + // customNotificationsPlayWindowsNotificationAudio + // + customNotificationsPlayWindowsNotificationAudio.AutoSize = true; + customNotificationsPlayWindowsNotificationAudio.Location = new System.Drawing.Point(4, 59); + customNotificationsPlayWindowsNotificationAudio.Name = "customNotificationsPlayWindowsNotificationAudio"; + customNotificationsPlayWindowsNotificationAudio.Size = new System.Drawing.Size(200, 19); + customNotificationsPlayWindowsNotificationAudio.TabIndex = 2; + customNotificationsPlayWindowsNotificationAudio.Text = "Play Windows notification sound"; + customNotificationsPlayWindowsNotificationAudio.UseVisualStyleBackColor = true; + // // customNotificationsShowInDarkMode // customNotificationsShowInDarkMode.AutoSize = true; @@ -216,7 +228,7 @@ namespace ntfysh_client AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; BackColor = System.Drawing.Color.White; - ClientSize = new System.Drawing.Size(531, 367); + ClientSize = new System.Drawing.Size(531, 387); Controls.Add(label1); Controls.Add(groupCustomNotificationSettings); Controls.Add(nativeVersusCustomNotificationsGroupBox); @@ -266,5 +278,6 @@ namespace ntfysh_client private System.Windows.Forms.CheckBox customNotificationsShowTimeoutBar; private System.Windows.Forms.CheckBox customNotificationsShowInDarkMode; private System.Windows.Forms.Label label1; + private System.Windows.Forms.CheckBox customNotificationsPlayWindowsNotificationAudio; } } \ No newline at end of file diff --git a/ntfysh_client/SettingsDialog.cs b/ntfysh_client/SettingsDialog.cs index 20cbfa2..2d4d0ec 100644 --- a/ntfysh_client/SettingsDialog.cs +++ b/ntfysh_client/SettingsDialog.cs @@ -61,6 +61,12 @@ namespace ntfysh_client get => customNotificationsShowInDarkMode.Checked; set => customNotificationsShowInDarkMode.Checked = value; } + + public bool CustomTrayNotificationsPlayDefaultWindowsSound + { + get => customNotificationsPlayWindowsNotificationAudio.Checked; + set => customNotificationsPlayWindowsNotificationAudio.Checked = value; + } #endregion public SettingsDialog() diff --git a/ntfysh_client/SettingsDialog.resx b/ntfysh_client/SettingsDialog.resx index af32865..8b2ff64 100644 --- a/ntfysh_client/SettingsDialog.resx +++ b/ntfysh_client/SettingsDialog.resx @@ -1,7 +1,7 @@