Skip to content

Commit b26eb7c

Browse files
committed
feat(banner): Make banner stackable instead of replacing content
1 parent 15fddc8 commit b26eb7c

10 files changed

+54
-30
lines changed

SoundSwitch/Framework/Banner/BannerForm.cs

+17-2
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ public partial class BannerForm : Form
3434
private bool _hiding;
3535
private BannerData _currentData;
3636
private CancellationTokenSource _cancellationTokenSource = new();
37+
private int _currentOffset;
38+
public Guid Id { get; } = Guid.NewGuid();
3739

3840
/// <summary>
3941
/// Get the Screen object
@@ -76,13 +78,15 @@ public BannerForm()
7678
/// Called internally to configure pass notification parameters
7779
/// </summary>
7880
/// <param name="data">The configuration data to setup the notification UI</param>
79-
internal void SetData(BannerData data)
81+
/// <param name="positionOffset"></param>
82+
internal void SetData(BannerData data, int positionOffset)
8083
{
8184
if (_currentData != null && _currentData.Priority > data.Priority)
8285
{
8386
return;
8487
}
8588

89+
_currentOffset = positionOffset;
8690
_currentData = data;
8791
if (_timerHide == null)
8892
{
@@ -112,12 +116,23 @@ internal void SetData(BannerData data)
112116

113117
var screen = GetScreen();
114118

115-
Location = data.Position.GetScreenPosition(screen, Height, Width);
119+
Location = data.Position.GetScreenPosition(screen, Height, Width, positionOffset);
116120

117121
_timerHide.Enabled = true;
118122

119123
Show();
120124
}
125+
126+
/// <summary>
127+
/// Update Location of banner depending of the position change
128+
/// </summary>
129+
/// <param name="positionChange"></param>
130+
public void UpdateLocation(int positionChange)
131+
{
132+
var screen = GetScreen();
133+
_currentOffset -= positionChange;
134+
Location = _currentData.Position.GetScreenPosition(screen, Height, Width, _currentOffset);
135+
}
121136

122137
/// <summary>
123138
///

SoundSwitch/Framework/Banner/BannerManager.cs

+19-11
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
********************************************************************/
1414

1515
using System;
16+
using System.Collections.Generic;
1617
using Serilog;
1718

1819
namespace SoundSwitch.Framework.Banner
@@ -22,8 +23,9 @@ namespace SoundSwitch.Framework.Banner
2223
/// </summary>
2324
public class BannerManager
2425
{
25-
private static System.Threading.SynchronizationContext syncContext;
26-
private static BannerForm banner;
26+
private static System.Threading.SynchronizationContext _syncContext;
27+
private int _currentOffset = 0;
28+
private readonly Dictionary<Guid, BannerForm> _bannerForms = new();
2729

2830
/// <summary>
2931
/// Show a banner notification with the given data
@@ -32,15 +34,21 @@ public class BannerManager
3234
public void ShowNotification(BannerData data)
3335
{
3436
// Execute the banner in the context of the UI thread
35-
syncContext.Send(_ =>
37+
_syncContext.Send(_ =>
3638
{
37-
if (banner == null)
39+
var banner = new BannerForm();
40+
banner.Disposed += (s, e) =>
3841
{
39-
banner = new BannerForm();
40-
banner.Disposed += (s, e) => banner = null;
41-
}
42-
43-
banner.SetData(data);
42+
_currentOffset -= banner.Height;
43+
_bannerForms.Remove(banner.Id);
44+
foreach (var bannerForm in _bannerForms.Values)
45+
{
46+
bannerForm.UpdateLocation(banner.Height);
47+
}
48+
};
49+
banner.SetData(data, _currentOffset);
50+
_currentOffset += banner.Height;
51+
_bannerForms.Add(banner.Id, banner);
4452
}, null);
4553
}
4654

@@ -51,8 +59,8 @@ public void ShowNotification(BannerData data)
5159
internal static void Setup()
5260
{
5361
// Grab the synchronization context of the UI thread!
54-
syncContext = System.Threading.SynchronizationContext.Current;
55-
if (!(syncContext is System.Windows.Forms.WindowsFormsSynchronizationContext))
62+
_syncContext = System.Threading.SynchronizationContext.Current;
63+
if (!(_syncContext is System.Windows.Forms.WindowsFormsSynchronizationContext))
5664
throw new InvalidOperationException("BannerManager must be called in the context of the UI thread.");
5765
Log.Information("Banner manager initialized");
5866
}

SoundSwitch/Framework/Banner/Position/APosition.cs

+4-4
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@ namespace SoundSwitch.Framework.Banner.Position
1818
{
1919
internal class APosition
2020
{
21-
public int PositionTop(Screen screen) => screen.Bounds.X + 50;
22-
public int PositionLeft(Screen screen) => screen.Bounds.Y + 60;
23-
public int PositionBottom(Screen screen, int height) => screen.Bounds.Height - height - PositionTop(screen);
21+
public int PositionTop(Screen screen, int offset) => screen.Bounds.Y + 60 + offset;
22+
public int PositionLeft(Screen screen) => screen.Bounds.X + 50;
23+
public int PositionBottom(Screen screen, int height, int offset) => screen.Bounds.Height - height - PositionTop(screen, 0) - offset;
2424
public int PositionRight(Screen screen, int width) => screen.Bounds.Width - width - PositionLeft(screen);
2525
public int PositionCenter(Screen screen, int width) => (screen.Bounds.Width - width) / 2;
2626
}
27-
}
27+
}

SoundSwitch/Framework/Banner/Position/IPosition.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ public interface IPosition : IEnumImpl<BannerPositionEnum>
2626
/// <param name="screen"></param>
2727
/// <param name="height"></param>
2828
/// <param name="width"></param>
29+
/// <param name="offset"></param>
2930
/// <returns></returns>
30-
public Point GetScreenPosition(Screen screen, int height, int width);
31+
public Point GetScreenPosition(Screen screen, int height, int width, int offset);
3132
}
3233
}

SoundSwitch/Framework/Banner/Position/PositionBottomCenter.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,11 @@ internal class PositionBottomCenter : APosition, IPosition
2323
public BannerPositionEnum TypeEnum => BannerPositionEnum.BottomCenter;
2424
public string Label => SettingsStrings.positionOptionBottomCenter;
2525

26-
public Point GetScreenPosition(Screen screen, int height, int width)
26+
public Point GetScreenPosition(Screen screen, int height, int width, int offset)
2727
{
2828
return new Point(
2929
PositionCenter(screen, width),
30-
PositionBottom(screen, height)
30+
PositionBottom(screen, height, offset)
3131
);
3232
}
3333
}

SoundSwitch/Framework/Banner/Position/PositionBottomLeft.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,11 @@ internal class PositionBottomLeft : APosition, IPosition
2323
public BannerPositionEnum TypeEnum => BannerPositionEnum.BottomLeft;
2424
public string Label => SettingsStrings.positionOptionBottomLeft;
2525

26-
public Point GetScreenPosition(Screen screen, int height, int width)
26+
public Point GetScreenPosition(Screen screen, int height, int width, int offset)
2727
{
2828
return new Point(
2929
PositionLeft(screen),
30-
PositionBottom(screen, height)
30+
PositionBottom(screen, height, offset)
3131
);
3232
}
3333
}

SoundSwitch/Framework/Banner/Position/PositionBottomRight.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,11 @@ internal class PositionBottomRight : APosition, IPosition
2323
public BannerPositionEnum TypeEnum => BannerPositionEnum.BottomRight;
2424
public string Label => SettingsStrings.positionOptionBottomRight;
2525

26-
public Point GetScreenPosition(Screen screen, int height, int width)
26+
public Point GetScreenPosition(Screen screen, int height, int width, int offset)
2727
{
2828
return new Point(
2929
PositionRight(screen, width),
30-
PositionBottom(screen, height)
30+
PositionBottom(screen, height, offset)
3131
);
3232
}
3333
}

SoundSwitch/Framework/Banner/Position/PositionTopCenter.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,11 @@ internal class PositionTopCenter : APosition, IPosition
2323
public BannerPositionEnum TypeEnum => BannerPositionEnum.TopCenter;
2424
public string Label => SettingsStrings.positionOptionTopCenter;
2525

26-
public Point GetScreenPosition(Screen screen, int height, int width)
26+
public Point GetScreenPosition(Screen screen, int height, int width, int offset)
2727
{
2828
return new Point(
2929
PositionCenter(screen, width),
30-
PositionTop(screen)
30+
PositionTop(screen, offset)
3131
);
3232
}
3333
}

SoundSwitch/Framework/Banner/Position/PositionTopLeft.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@ internal class PositionTopLeft : APosition, IPosition
2222
{
2323
public BannerPositionEnum TypeEnum => BannerPositionEnum.TopLeft;
2424
public string Label => SettingsStrings.positionOptionTopLeft;
25-
public Point GetScreenPosition(Screen screen, int height, int width)
25+
public Point GetScreenPosition(Screen screen, int height, int width, int offset)
2626
{
2727
return new Point(
2828
PositionLeft(screen),
29-
PositionTop(screen)
29+
PositionTop(screen, offset)
3030
);
3131
}
3232
}

SoundSwitch/Framework/Banner/Position/PositionTopRight.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,11 @@ internal class PositionTopRight : APosition, IPosition
2323
public BannerPositionEnum TypeEnum => BannerPositionEnum.TopRight;
2424
public string Label => SettingsStrings.positionOptionTopRight;
2525

26-
public Point GetScreenPosition(Screen screen, int height, int width)
26+
public Point GetScreenPosition(Screen screen, int height, int width, int offset)
2727
{
2828
return new Point(
2929
PositionRight(screen, width),
30-
PositionTop(screen)
30+
PositionTop(screen, offset)
3131
);
3232
}
3333
}

0 commit comments

Comments
 (0)