From d73dc6ce9135df5d49e5db405dfce0772bb6acbe Mon Sep 17 00:00:00 2001 From: ramon18 Date: Mon, 22 May 2017 14:01:47 +0100 Subject: [PATCH 1/4] Auto detect visual studio edition during build. --- Make.bat | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/Make.bat b/Make.bat index 26c7e3212e..4161fbd079 100644 --- a/Make.bat +++ b/Make.bat @@ -31,8 +31,28 @@ IF "%~1" neq "" ( ) -REM set msbuildexe="%programfiles(x86)%\MSBuild\14.0\Bin\MSBuild.exe" -set msbuildexe="%programfiles(x86)%\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\msbuild.exe" +set VS2017Ent=%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\msbuild.exe +set VS2017Pro=%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Professional\MSBuild\15.0\Bin\msbuild.exe +set VS2017Community=%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\msbuild.exe +set VS2015=%ProgramFiles(x86)%\MSBuild\14.0\bin\msbuild.exe + +if exist "%VS2017Ent%" ( + echo Using VS2017Ent + set msbuildexe="%VS2017Ent%" +) else ( + if exist "%VS2017Community%" ( + echo Using VS2017Community + set msbuildexe="%VS2017Community%" + ) else ( + if exist "%VS2017Pro%" ( + echo Using VS2017Pro + set msbuildexe="%VS2017Pro%" + ) else ( + echo Fallback to VS2015 + set msbuildexe="%VS2015%" + ) + ) +) Echo Making SoundSwitch %buildPlatform% Echo. From 23755e0802ca33fde4d9475646ea5705e54e2d57 Mon Sep 17 00:00:00 2001 From: ramon18 Date: Mon, 22 May 2017 14:07:43 +0100 Subject: [PATCH 2/4] Ignore .vs directory. --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 2ffde39b49..097de35b58 100644 --- a/.gitignore +++ b/.gitignore @@ -32,6 +32,7 @@ *.dSYM/ # Visual Studio +.vs/ bin/ obj/ Debug/ @@ -55,3 +56,4 @@ packages/ /SoundSwitch.VC.VC.opendb /SoundSwitch.VC.db /SoundSwitch.psess + From b9e51a9115f3aad8788281f4484be52a7ab69ffd Mon Sep 17 00:00:00 2001 From: ramon18 Date: Mon, 22 May 2017 15:05:17 +0100 Subject: [PATCH 3/4] Notifications can inform if they require custom sound, this improves a lot the settings form. --- .../Notification/INotification.cs | 6 ++++++ .../Notification/NotificationCustom.cs | 2 ++ .../Notification/NotificationNone.cs | 2 ++ .../Notification/NotificationSound.cs | 2 ++ .../Notification/NotificationToast.cs | 2 ++ .../Notification/NotificationWindows.cs | 2 ++ .../NotificationCustomSoundEnum.cs | 15 +++++++++++++++ SoundSwitch/UI/Forms/Settings.cs | 18 +++++++++--------- 8 files changed, 40 insertions(+), 9 deletions(-) create mode 100644 SoundSwitch/Framework/NotificationManager/NotificationCustomSoundEnum.cs diff --git a/SoundSwitch/Framework/NotificationManager/Notification/INotification.cs b/SoundSwitch/Framework/NotificationManager/Notification/INotification.cs index 392051c1fb..c26f9caab6 100644 --- a/SoundSwitch/Framework/NotificationManager/Notification/INotification.cs +++ b/SoundSwitch/Framework/NotificationManager/Notification/INotification.cs @@ -38,6 +38,12 @@ public interface INotification : IEnumImpl /// void OnSoundChanged(CachedSound newSound); + /// + /// Does the notification support a Custom Sound + /// + /// + NotificationCustomSoundEnum SupportCustomSound(); + /// /// Does the notification need a Custom Sound set to work /// diff --git a/SoundSwitch/Framework/NotificationManager/Notification/NotificationCustom.cs b/SoundSwitch/Framework/NotificationManager/Notification/NotificationCustom.cs index ebabf385bf..d6ec0f5ebf 100644 --- a/SoundSwitch/Framework/NotificationManager/Notification/NotificationCustom.cs +++ b/SoundSwitch/Framework/NotificationManager/Notification/NotificationCustom.cs @@ -58,6 +58,8 @@ public void OnSoundChanged(CachedSound newSound) Configuration.CustomSound = newSound; } + public NotificationCustomSoundEnum SupportCustomSound() => NotificationCustomSoundEnum.Required; + public bool NeedCustomSound() { return true; diff --git a/SoundSwitch/Framework/NotificationManager/Notification/NotificationNone.cs b/SoundSwitch/Framework/NotificationManager/Notification/NotificationNone.cs index 04a09691d9..ea65185772 100644 --- a/SoundSwitch/Framework/NotificationManager/Notification/NotificationNone.cs +++ b/SoundSwitch/Framework/NotificationManager/Notification/NotificationNone.cs @@ -35,6 +35,8 @@ public void OnSoundChanged(CachedSound newSound) { } + public NotificationCustomSoundEnum SupportCustomSound() => NotificationCustomSoundEnum.NotSupported; + public bool NeedCustomSound() { return false; diff --git a/SoundSwitch/Framework/NotificationManager/Notification/NotificationSound.cs b/SoundSwitch/Framework/NotificationManager/Notification/NotificationSound.cs index 22c5089809..e53ee9d1b5 100644 --- a/SoundSwitch/Framework/NotificationManager/Notification/NotificationSound.cs +++ b/SoundSwitch/Framework/NotificationManager/Notification/NotificationSound.cs @@ -66,6 +66,8 @@ public void OnSoundChanged(CachedSound newSound) { } + public NotificationCustomSoundEnum SupportCustomSound() => NotificationCustomSoundEnum.NotSupported; + public bool NeedCustomSound() { return false; diff --git a/SoundSwitch/Framework/NotificationManager/Notification/NotificationToast.cs b/SoundSwitch/Framework/NotificationManager/Notification/NotificationToast.cs index e4bffc537f..fa8e90fe6f 100644 --- a/SoundSwitch/Framework/NotificationManager/Notification/NotificationToast.cs +++ b/SoundSwitch/Framework/NotificationManager/Notification/NotificationToast.cs @@ -61,6 +61,8 @@ public void OnSoundChanged(CachedSound newSound) Configuration.CustomSound = newSound; } + public NotificationCustomSoundEnum SupportCustomSound() => NotificationCustomSoundEnum.NotSupported; + public bool NeedCustomSound() { return false; diff --git a/SoundSwitch/Framework/NotificationManager/Notification/NotificationWindows.cs b/SoundSwitch/Framework/NotificationManager/Notification/NotificationWindows.cs index 6ce2988f55..ea5785fcf6 100644 --- a/SoundSwitch/Framework/NotificationManager/Notification/NotificationWindows.cs +++ b/SoundSwitch/Framework/NotificationManager/Notification/NotificationWindows.cs @@ -51,6 +51,8 @@ public void OnSoundChanged(CachedSound newSound) { } + public NotificationCustomSoundEnum SupportCustomSound() => NotificationCustomSoundEnum.NotSupported; + public bool NeedCustomSound() { return false; diff --git a/SoundSwitch/Framework/NotificationManager/NotificationCustomSoundEnum.cs b/SoundSwitch/Framework/NotificationManager/NotificationCustomSoundEnum.cs new file mode 100644 index 0000000000..b1ba3a6b64 --- /dev/null +++ b/SoundSwitch/Framework/NotificationManager/NotificationCustomSoundEnum.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SoundSwitch.Framework.NotificationManager +{ + public enum NotificationCustomSoundEnum + { + NotSupported = 0, + Optional = 1, + Required = 2 + } +} diff --git a/SoundSwitch/UI/Forms/Settings.cs b/SoundSwitch/UI/Forms/Settings.cs index a857b6c65a..d6d7e22873 100644 --- a/SoundSwitch/UI/Forms/Settings.cs +++ b/SoundSwitch/UI/Forms/Settings.cs @@ -75,7 +75,8 @@ public SettingsForm() var notificationToolTip = new ToolTip(); notificationToolTip.SetToolTip(notificationComboBox, SettingsStrings.notificationTooltip); - new NotificationFactory().ConfigureListControl(notificationComboBox); + var notificationFactory = new NotificationFactory(); + notificationFactory.ConfigureListControl(notificationComboBox); notificationComboBox.SelectedValue = AppModel.Instance.NotificationSettings; selectSoundFileDialog.Filter = SettingsStrings.audioFiles + @" (*.wav;*.mp3)|*.wav;*.mp3;*.aiff"; @@ -83,8 +84,7 @@ public SettingsForm() selectSoundFileDialog.CheckFileExists = true; selectSoundFileDialog.CheckPathExists = true; - selectSoundButton.Visible = AppModel.Instance.NotificationSettings == NotificationTypeEnum.CustomNotification || - AppModel.Instance.NotificationSettings == NotificationTypeEnum.ToastNotification; + selectSoundButton.Visible = notificationFactory.Get(AppModel.Instance.NotificationSettings).SupportCustomSound() != NotificationCustomSoundEnum.NotSupported; var selectSoundButtonToolTip = new ToolTip(); selectSoundButtonToolTip.SetToolTip(selectSoundButton, SettingsStrings.selectSoundButtonTooltip); @@ -271,14 +271,14 @@ private void notificationComboBox_SelectedValueChanged(object sender, EventArgs if (value == null) return; - if ((NotificationTypeEnum)value == AppModel.Instance.NotificationSettings) + NotificationTypeEnum notificationType = (NotificationTypeEnum)value; + if (notificationType == AppModel.Instance.NotificationSettings) return; - var isCustomNotification = (NotificationTypeEnum)value == NotificationTypeEnum.CustomNotification; - selectSoundButton.Visible = isCustomNotification || - (NotificationTypeEnum)value == NotificationTypeEnum.ToastNotification; + NotificationCustomSoundEnum supportCustomSound = new NotificationFactory().Get(notificationType).SupportCustomSound(); + selectSoundButton.Visible = supportCustomSound != NotificationCustomSoundEnum.NotSupported; - if (isCustomNotification) + if (supportCustomSound == NotificationCustomSoundEnum.Required) { try { @@ -290,7 +290,7 @@ private void notificationComboBox_SelectedValueChanged(object sender, EventArgs } } - AppModel.Instance.NotificationSettings = (NotificationTypeEnum)value; + AppModel.Instance.NotificationSettings = notificationType; } private void tooltipInfoComboBox_SelectedValueChanged(object sender, EventArgs e) From 2111002c4ecf348dab2f424cef58d2f54c9e5a2d Mon Sep 17 00:00:00 2001 From: ramon18 Date: Mon, 22 May 2017 15:25:55 +0100 Subject: [PATCH 4/4] Added support for "Banner" notification, an always-on-top banner which stands above any directdraw/opengl windows. --- SoundSwitch/Framework/Banner/BannerData.cs | 48 ++++++ .../Framework/Banner/BannerForm.Designer.cs | 125 +++++++++++++++ SoundSwitch/Framework/Banner/BannerForm.cs | 147 ++++++++++++++++++ SoundSwitch/Framework/Banner/BannerForm.resx | 120 ++++++++++++++ SoundSwitch/Framework/Banner/BannerManager.cs | 58 +++++++ .../Notification/NotificationBanner.cs | 78 ++++++++++ .../NotificationFactory.cs | 1 + .../NotificationTypeEnum.cs | 3 +- .../Localization/SettingsStrings.Designer.cs | 14 +- .../Localization/SettingsStrings.de.resx | 8 +- .../Localization/SettingsStrings.fr.resx | 6 +- SoundSwitch/Localization/SettingsStrings.resx | 6 +- SoundSwitch/SoundSwitch.csproj | 13 ++ 13 files changed, 620 insertions(+), 7 deletions(-) create mode 100644 SoundSwitch/Framework/Banner/BannerData.cs create mode 100644 SoundSwitch/Framework/Banner/BannerForm.Designer.cs create mode 100644 SoundSwitch/Framework/Banner/BannerForm.cs create mode 100644 SoundSwitch/Framework/Banner/BannerForm.resx create mode 100644 SoundSwitch/Framework/Banner/BannerManager.cs create mode 100644 SoundSwitch/Framework/NotificationManager/Notification/NotificationBanner.cs diff --git a/SoundSwitch/Framework/Banner/BannerData.cs b/SoundSwitch/Framework/Banner/BannerData.cs new file mode 100644 index 0000000000..8b6534b463 --- /dev/null +++ b/SoundSwitch/Framework/Banner/BannerData.cs @@ -0,0 +1,48 @@ +/******************************************************************** +* Copyright (C) 2015-2017 Antoine Aflalo +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +********************************************************************/ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SoundSwitch.Framework.Banner +{ + /// + /// Contains configuration data for the banner form. + /// + public class BannerData + { + /// + /// Gets/sets the title of the banner + /// + public string Title { get; internal set; } + + /// + /// Gets/sets the text of the banner + /// + public string Text { get; internal set; } + + /// + /// Gets/sets the path for an image, this is optional. + /// + public string ImagePath { get; internal set; } + + /// + /// Gets/sets the path for a wav sound to be playedc during the notification, this is optional. + /// + public string SoundFilePath { get; internal set; } + } +} diff --git a/SoundSwitch/Framework/Banner/BannerForm.Designer.cs b/SoundSwitch/Framework/Banner/BannerForm.Designer.cs new file mode 100644 index 0000000000..422d0a4d97 --- /dev/null +++ b/SoundSwitch/Framework/Banner/BannerForm.Designer.cs @@ -0,0 +1,125 @@ +namespace SoundSwitch.Framework.Banner +{ + partial class BannerForm + { + /// + /// 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() + { + this.lblTitle = new System.Windows.Forms.Label(); + this.pbxLogo = new System.Windows.Forms.PictureBox(); + this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); + this.lblTop = new System.Windows.Forms.Label(); + ((System.ComponentModel.ISupportInitialize)(this.pbxLogo)).BeginInit(); + this.tableLayoutPanel1.SuspendLayout(); + this.SuspendLayout(); + // + // lblTitle + // + this.lblTitle.Anchor = System.Windows.Forms.AnchorStyles.Left; + this.lblTitle.AutoSize = true; + this.lblTitle.Location = new System.Drawing.Point(31, 26); + this.lblTitle.Margin = new System.Windows.Forms.Padding(5, 0, 5, 0); + this.lblTitle.Name = "lblTitle"; + this.lblTitle.Size = new System.Drawing.Size(36, 21); + this.lblTitle.TabIndex = 0; + this.lblTitle.Text = "title"; + // + // pbxLogo + // + this.pbxLogo.Image = global::SoundSwitch.Properties.Resources.PlaybackDevices; + this.pbxLogo.Location = new System.Drawing.Point(5, 5); + this.pbxLogo.Margin = new System.Windows.Forms.Padding(5); + this.pbxLogo.Name = "pbxLogo"; + this.pbxLogo.Size = new System.Drawing.Size(16, 16); + this.pbxLogo.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize; + this.pbxLogo.TabIndex = 1; + this.pbxLogo.TabStop = false; + // + // tableLayoutPanel1 + // + this.tableLayoutPanel1.AutoSize = true; + this.tableLayoutPanel1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.tableLayoutPanel1.ColumnCount = 2; + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); + this.tableLayoutPanel1.Controls.Add(this.lblTitle, 1, 1); + this.tableLayoutPanel1.Controls.Add(this.pbxLogo, 0, 0); + this.tableLayoutPanel1.Controls.Add(this.lblTop, 1, 0); + this.tableLayoutPanel1.Location = new System.Drawing.Point(15, 15); + this.tableLayoutPanel1.Margin = new System.Windows.Forms.Padding(5); + this.tableLayoutPanel1.Name = "tableLayoutPanel1"; + this.tableLayoutPanel1.RowCount = 2; + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel1.Size = new System.Drawing.Size(89, 47); + this.tableLayoutPanel1.TabIndex = 2; + // + // lblTop + // + this.lblTop.AutoSize = true; + this.lblTop.Font = new System.Drawing.Font("Segoe UI", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.lblTop.Location = new System.Drawing.Point(29, 0); + this.lblTop.Name = "lblTop"; + this.lblTop.Size = new System.Drawing.Size(57, 21); + this.lblTop.TabIndex = 2; + this.lblTop.Text = "label1"; + // + // BannerForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 21F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.AutoSize = true; + this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.BackColor = System.Drawing.Color.Black; + this.ClientSize = new System.Drawing.Size(428, 215); + this.ControlBox = false; + this.Controls.Add(this.tableLayoutPanel1); + this.Font = new System.Drawing.Font("Segoe UI", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.ForeColor = System.Drawing.Color.White; + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; + this.Margin = new System.Windows.Forms.Padding(5); + this.Name = "BannerForm"; + this.Padding = new System.Windows.Forms.Padding(10); + this.ShowIcon = false; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.Manual; + this.TopMost = true; + ((System.ComponentModel.ISupportInitialize)(this.pbxLogo)).EndInit(); + this.tableLayoutPanel1.ResumeLayout(false); + this.tableLayoutPanel1.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Label lblTitle; + private System.Windows.Forms.PictureBox pbxLogo; + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; + private System.Windows.Forms.Label lblTop; + } +} \ No newline at end of file diff --git a/SoundSwitch/Framework/Banner/BannerForm.cs b/SoundSwitch/Framework/Banner/BannerForm.cs new file mode 100644 index 0000000000..38c97106ff --- /dev/null +++ b/SoundSwitch/Framework/Banner/BannerForm.cs @@ -0,0 +1,147 @@ +/******************************************************************** +* Copyright (C) 2015-2017 Antoine Aflalo +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +********************************************************************/ + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Drawing; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace SoundSwitch.Framework.Banner +{ + /// + /// This class implements the UI form used to show a Banner notification. + /// + public partial class BannerForm : Form + { + private Timer timerHide; + private bool hiding; + private System.Media.SoundPlayer player; + + /// + /// Constructor for the class + /// + public BannerForm() + { + InitializeComponent(); + + this.Location = new Point(50, 60); + } + + protected override bool ShowWithoutActivation => true; + + /// + /// Override the parameters used to create the window handle. + /// Ensure that the window will be top-most and do not activate or take focus. + /// + protected override CreateParams CreateParams + { + get + { + CreateParams p = base.CreateParams; + p.ExStyle |= 0x08000000; // WS_EX_NOACTIVATE + p.ExStyle |= 0x00000008; // WS_EX_TOPMOST + return p; + } + } + + /// + /// Called internally to configure pass notification parameters + /// + /// The configuration data to setup the notification UI + internal void SetData(BannerData data) + { + if (this.timerHide == null) + { + this.timerHide = new Timer(); + this.timerHide.Interval = 3000; + this.timerHide.Tick += TimerHide_Tick; + } + else + { + this.timerHide.Enabled = false; + } + + if (!string.IsNullOrEmpty(data.ImagePath) && System.IO.File.Exists(data.ImagePath)) + this.pbxLogo.ImageLocation = data.ImagePath; + + DestroySound(); + + if (!string.IsNullOrEmpty(data.SoundFilePath)) + { + this.player = new System.Media.SoundPlayer(); + player.SoundLocation = data.SoundFilePath; + player.Play(); + } + + this.hiding = false; + this.Opacity = .8; + this.lblTop.Text = data.Title; + this.lblTitle.Text = data.Text; + this.timerHide.Enabled = true; + + this.Show(); + } + + /// + /// Destroy current sound player (if any) + /// + private void DestroySound() + { + if (this.player != null) + { + this.player.Dispose(); + this.player = null; + } + } + + /// + /// Event handler for the "hiding" timer. + /// + /// The sender of the event + /// Arguments of the event + private void TimerHide_Tick(object sender, EventArgs e) + { + this.hiding = true; + this.timerHide.Enabled = false; + DestroySound(); + FadeOut(); + } + + /// + /// Implements an "fadeout" animation while hiding the window. + /// In the end of the animation the form is self disposed. + /// The animation is canceled if the method is called along the animation. + /// + private async void FadeOut() + { + while (this.Opacity > 0.0) + { + await Task.Delay(50); + + if (!this.hiding) + break; + this.Opacity -= 0.05; + } + + if (this.hiding) + { + this.Dispose(); + } + } + } +} diff --git a/SoundSwitch/Framework/Banner/BannerForm.resx b/SoundSwitch/Framework/Banner/BannerForm.resx new file mode 100644 index 0000000000..1af7de150c --- /dev/null +++ b/SoundSwitch/Framework/Banner/BannerForm.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 diff --git a/SoundSwitch/Framework/Banner/BannerManager.cs b/SoundSwitch/Framework/Banner/BannerManager.cs new file mode 100644 index 0000000000..b8c8e22265 --- /dev/null +++ b/SoundSwitch/Framework/Banner/BannerManager.cs @@ -0,0 +1,58 @@ +/******************************************************************** +* Copyright (C) 2015-2017 Antoine Aflalo +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +********************************************************************/ + +using System; +using Windows.UI.Notifications; + +namespace SoundSwitch.Framework.Banner +{ + /// + /// Class to manage the banners. This class is the entrypoint to show a notification banner. + /// + public class BannerManager + { + private static System.Threading.SynchronizationContext syncContext; + private static BannerForm banner; + + /// + /// Show a banner notification with the given data + /// + /// + public void ShowNotification(BannerData data) + { + // Execute the banner in the context of the UI thread + syncContext.Post((d) => + { + if (banner == null) + { + banner = new BannerForm(); + banner.Disposed += (s, e) => banner = null; + } + banner.SetData(data); + }, null); + } + + /// + /// Because notifications dispatched asynchronously, this method must be called in the context of the UI thread + /// This method requires that at least one System.Windows.Form.Control has been created or Application.Run() called + /// + internal static void Setup() + { + // Grab the synchronization context of the UI thread! + syncContext = System.Threading.SynchronizationContext.Current; + if (!(syncContext is System.Windows.Forms.WindowsFormsSynchronizationContext)) + throw new InvalidOperationException("BannerManager must be called in the context of the UI thread."); + } + } +} \ No newline at end of file diff --git a/SoundSwitch/Framework/NotificationManager/Notification/NotificationBanner.cs b/SoundSwitch/Framework/NotificationManager/Notification/NotificationBanner.cs new file mode 100644 index 0000000000..2cb73f0936 --- /dev/null +++ b/SoundSwitch/Framework/NotificationManager/Notification/NotificationBanner.cs @@ -0,0 +1,78 @@ +/******************************************************************** +* Copyright (C) 2015-2017 Antoine Aflalo +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +********************************************************************/ + +using System; +using System.IO; +using AudioEndPointControllerWrapper; +using SoundSwitch.Framework.Audio; +using SoundSwitch.Framework.NotificationManager.Notification.Configuration; +using SoundSwitch.Framework.Banner; +using SoundSwitch.Localization; + +namespace SoundSwitch.Framework.NotificationManager.Notification +{ + public class NotificationBanner : INotification + { + public NotificationTypeEnum TypeEnum => NotificationTypeEnum.BannerNotification; + public string Label => SettingsStrings.notificationOptionBanner; + + public INotificationConfiguration Configuration { get; set; } + + public void NotifyDefaultChanged(IAudioDevice audioDevice) + { + var toastData = new BannerData + { + ImagePath = new System.Uri(Path.GetFullPath(ApplicationPath.DefaultImagePath)).AbsoluteUri, + Text = audioDevice.FriendlyName + }; + if (Configuration.CustomSound != null && File.Exists(Configuration.CustomSound.FilePath)) + { + toastData.SoundFilePath = Configuration.CustomSound.FilePath; + } + + switch (audioDevice.Type) + { + case AudioDeviceType.Playback: + toastData.Title = SettingsStrings.tooltipOnHoverOptionPlaybackDevice; + break; + case AudioDeviceType.Recording: + toastData.Title = SettingsStrings.tooltipOnHoverOptionRecordingDevice; + break; + default: + throw new ArgumentOutOfRangeException(nameof(audioDevice.Type), audioDevice.Type, null); + } + new BannerManager().ShowNotification(toastData); + } + + public void OnSoundChanged(CachedSound newSound) + { + Configuration.CustomSound = newSound; + } + + public NotificationCustomSoundEnum SupportCustomSound() => NotificationCustomSoundEnum.Optional; + + public bool NeedCustomSound() + { + return false; + } + + public bool IsAvailable() + { + BannerManager.Setup(); + + // Available in all Windows versions + return true; + } + } +} \ No newline at end of file diff --git a/SoundSwitch/Framework/NotificationManager/NotificationFactory.cs b/SoundSwitch/Framework/NotificationManager/NotificationFactory.cs index 7e296b0eab..d8df041cba 100644 --- a/SoundSwitch/Framework/NotificationManager/NotificationFactory.cs +++ b/SoundSwitch/Framework/NotificationManager/NotificationFactory.cs @@ -29,6 +29,7 @@ public class NotificationFactory : AbstractFactory - /// Looks up a localized string similar to The audio file you selected to be used as notification can't be found. SoundSwitch switched the notification setting back to {1}.. + /// Looks up a localized string similar to The audio file you selected to be used as notification can't be found. SoundSwitch switched the notification setting back to {0}.. /// internal static string audioFileNotFound { get { @@ -286,6 +286,15 @@ internal static string notification { } } + /// + /// Looks up a localized string similar to Banner. + /// + internal static string notificationOptionBanner { + get { + return ResourceManager.GetString("notificationOptionBanner", resourceCulture); + } + } + /// /// Looks up a localized string similar to Customized Sound Notification. /// @@ -335,7 +344,8 @@ internal static string notificationOptionWindowsDefault { /// Looks up a localized string similar to Windows Notification: The default windows tray pop-up. ///Sound Notification: Plays a sound on the switched Playback Device. ///Customized Sound Notification: Plays the specified sound on the switched Playback Device. - ///Toast Notification: Uses a special form of the windows tray pop-up version.. + ///Toast Notification: Uses a special form of the windows tray pop-up version. + ///Banner: Uses a custom form always on top, may useful in certain for in-game usage because it stands above directdraw/opengl.. /// internal static string notificationTooltip { get { diff --git a/SoundSwitch/Localization/SettingsStrings.de.resx b/SoundSwitch/Localization/SettingsStrings.de.resx index 352cf84044..586a886ff9 100644 --- a/SoundSwitch/Localization/SettingsStrings.de.resx +++ b/SoundSwitch/Localization/SettingsStrings.de.resx @@ -1,6 +1,6 @@ -