11using System . Windows ;
22using System . Windows . Input ;
33using System . Windows . Media ;
4+ using System . Windows . Media . Animation ;
45using System . Windows . Shapes ;
6+ using System . Windows . Threading ;
57using GhostDraw . Helpers ;
68using GhostDraw . Services ;
79using Microsoft . Extensions . Logging ;
@@ -17,6 +19,11 @@ public partial class OverlayWindow : Window
1719 private Polyline ? _currentStroke ;
1820 private bool _isDrawing = false ;
1921
22+ // Thickness indicator animation
23+ private readonly DispatcherTimer _thicknessIndicatorTimer ;
24+ private readonly TimeSpan _indicatorDisplayDuration = TimeSpan . FromSeconds ( 1.5 ) ;
25+ private readonly TimeSpan _fadeOutDuration = TimeSpan . FromMilliseconds ( 300 ) ;
26+
2027 public OverlayWindow ( ILogger < OverlayWindow > logger , AppSettingsService appSettings , CursorHelper cursorHelper )
2128 {
2229 _logger = logger ;
@@ -26,6 +33,13 @@ public OverlayWindow(ILogger<OverlayWindow> logger, AppSettingsService appSettin
2633
2734 InitializeComponent ( ) ;
2835
36+ // Initialize thickness indicator timer
37+ _thicknessIndicatorTimer = new DispatcherTimer
38+ {
39+ Interval = _indicatorDisplayDuration
40+ } ;
41+ _thicknessIndicatorTimer . Tick += ThicknessIndicatorTimer_Tick ;
42+
2943 // Make window span all monitors
3044 Left = SystemParameters . VirtualScreenLeft ;
3145 Top = SystemParameters . VirtualScreenTop ;
@@ -48,6 +62,9 @@ public OverlayWindow(ILogger<OverlayWindow> logger, AppSettingsService appSettin
4862 Loaded += ( s , e ) => _logger . LogDebug ( "Loaded event fired" ) ;
4963 IsVisibleChanged += ( s , e ) => _logger . LogDebug ( "IsVisibleChanged ? {IsVisible}" , IsVisible ) ;
5064
65+ // Ensure timer is stopped when window is closed
66+ Closed += ( s , e ) => _thicknessIndicatorTimer . Stop ( ) ;
67+
5168 _logger . LogDebug ( "Mouse events wired up" ) ;
5269 }
5370
@@ -69,6 +86,9 @@ public void DisableDrawing()
6986 _logger . LogInformation ( "?? Drawing disabled" ) ;
7087 _isDrawing = false ;
7188
89+ // Hide thickness indicator
90+ HideThicknessIndicator ( ) ;
91+
7292 // Clear canvas when exiting drawing mode too
7393 ClearDrawing ( ) ;
7494
@@ -163,6 +183,9 @@ private void OverlayWindow_MouseWheel(object sender, MouseWheelEventArgs e)
163183 _appSettings . SetBrushThickness ( newThickness ) ;
164184 _logger . LogInformation ( "Brush thickness adjusted to {Thickness} via mouse wheel" , newThickness ) ;
165185
186+ // Show thickness indicator
187+ ShowThicknessIndicator ( newThickness ) ;
188+
166189 // Mark event as handled
167190 e . Handled = true ;
168191 }
@@ -240,4 +263,80 @@ private void AdjustBrushThickness(double delta)
240263 _currentStroke . StrokeThickness = settings . BrushThickness ;
241264 }
242265 }
266+
267+ /// <summary>
268+ /// Shows the thickness indicator with the specified value and resets the fade timer
269+ /// </summary>
270+ /// <param name="thickness">The current brush thickness value</param>
271+ private void ShowThicknessIndicator ( double thickness )
272+ {
273+ try
274+ {
275+ // Update the text
276+ ThicknessIndicatorText . Text = $ "{ thickness : 0} px";
277+
278+ // Stop any existing animations and timer
279+ _thicknessIndicatorTimer . Stop ( ) ;
280+ ThicknessIndicatorBorder . BeginAnimation ( OpacityProperty , null ) ;
281+
282+ // Show the indicator immediately
283+ ThicknessIndicatorBorder . Opacity = 1.0 ;
284+
285+ // Start the timer for fade-out
286+ _thicknessIndicatorTimer . Start ( ) ;
287+
288+ _logger . LogDebug ( "Thickness indicator shown: {Thickness} px" , thickness ) ;
289+ }
290+ catch ( Exception ex )
291+ {
292+ _logger . LogError ( ex , "Failed to show thickness indicator" ) ;
293+ }
294+ }
295+
296+ /// <summary>
297+ /// Timer tick handler that starts the fade-out animation
298+ /// </summary>
299+ private void ThicknessIndicatorTimer_Tick ( object ? sender , EventArgs e )
300+ {
301+ try
302+ {
303+ _thicknessIndicatorTimer . Stop ( ) ;
304+
305+ // Create and start fade-out animation
306+ var fadeOutAnimation = new DoubleAnimation
307+ {
308+ From = 1.0 ,
309+ To = 0.0 ,
310+ Duration = new Duration ( _fadeOutDuration ) ,
311+ EasingFunction = new QuadraticEase { EasingMode = EasingMode . EaseOut }
312+ } ;
313+
314+ ThicknessIndicatorBorder . BeginAnimation ( OpacityProperty , fadeOutAnimation ) ;
315+
316+ _logger . LogDebug ( "Thickness indicator fade-out started" ) ;
317+ }
318+ catch ( Exception ex )
319+ {
320+ _logger . LogError ( ex , "Failed to fade out thickness indicator" ) ;
321+ // Ensure indicator is hidden even if animation fails
322+ ThicknessIndicatorBorder . Opacity = 0 ;
323+ }
324+ }
325+
326+ /// <summary>
327+ /// Immediately hides the thickness indicator (called when drawing mode is disabled)
328+ /// </summary>
329+ private void HideThicknessIndicator ( )
330+ {
331+ try
332+ {
333+ _thicknessIndicatorTimer . Stop ( ) ;
334+ ThicknessIndicatorBorder . BeginAnimation ( OpacityProperty , null ) ;
335+ ThicknessIndicatorBorder . Opacity = 0 ;
336+ }
337+ catch ( Exception ex )
338+ {
339+ _logger . LogError ( ex , "Failed to hide thickness indicator" ) ;
340+ }
341+ }
243342}
0 commit comments