@@ -34,6 +34,7 @@ public class ThemePreviewer : SKControl
3434
3535 // Cached objects to reduce allocations
3636 private readonly SKPaint basePaint = new SKPaint { IsAntialias = true } ;
37+ private readonly SKColor overlayColor = new SKColor ( 0 , 0 , 0 , OVERLAY_ALPHA ) ;
3738 private readonly SKFont titleFont ;
3839 private readonly SKFont previewFont ;
3940 private readonly SKFont textFont ;
@@ -168,39 +169,35 @@ private void DrawImage(SKCanvas canvas, SKImage image, SKImageInfo info, float o
168169
169170 private void DrawOverlay ( SKCanvas canvas , SKImageInfo info )
170171 {
171- basePaint . Style = SKPaintStyle . Fill ;
172-
173172 // Draw left and right arrow button areas
174- if ( ViewModel . ControlsVisible )
175- {
176- DrawArrowArea ( canvas , info , true ) ;
177- DrawArrowArea ( canvas , info , false ) ;
178- }
173+ DrawArrowArea ( canvas , info , true ) ;
174+ DrawArrowArea ( canvas , info , false ) ;
179175
180176 // Title and preview text box (top left)
181177 var titleBounds = new SKRect ( ) ;
182178 titleFont . MeasureText ( ViewModel . Title ?? "" , out titleBounds ) ;
183179 var previewBounds = new SKRect ( ) ;
184180 previewFont . MeasureText ( ViewModel . PreviewText ?? "" , out previewBounds ) ;
185181
186- float boxWidth = Math . Max ( titleBounds . Width , previewBounds . Width ) + 20 ;
187- float boxHeight = 19 + 4 + 16 + 20 ;
188- titleBoxRect = new Rectangle ( 20 , 20 , ( int ) boxWidth , ( int ) boxHeight ) ;
182+ float boxWidth = Math . Max ( titleBounds . Width , previewBounds . Width ) + MARGIN_STANDARD ;
183+ float boxHeight = 19 + 4 + 16 + MARGIN_STANDARD ;
184+ titleBoxRect = new Rectangle ( MARGIN_STANDARD , MARGIN_STANDARD , ( int ) boxWidth , ( int ) boxHeight ) ;
189185
190- basePaint . Color = new SKColor ( 0 , 0 , 0 , 127 ) ;
191- canvas . DrawRoundRect ( SKRect . Create ( titleBoxRect . X , titleBoxRect . Y , titleBoxRect . Width , titleBoxRect . Height ) , 5 , 5 , basePaint ) ;
186+ basePaint . Color = overlayColor ;
187+ canvas . DrawRoundRect ( SKRect . Create ( titleBoxRect . X , titleBoxRect . Y , titleBoxRect . Width , titleBoxRect . Height ) , BORDER_RADIUS , BORDER_RADIUS , basePaint ) ;
192188
193189 basePaint . Color = SKColors . White ;
194190 canvas . DrawText ( ViewModel . Title ?? "" , titleBoxRect . X + 10 , titleBoxRect . Y + 8 + 19 , titleFont , basePaint ) ;
195191 canvas . DrawText ( ViewModel . PreviewText ?? "" , titleBoxRect . X + 10 , titleBoxRect . Y + 8 + 19 + 5 + 16 , previewFont , basePaint ) ;
196192
197193 // Play/Pause button (top right)
198- playButtonRect = new Rectangle ( info . Width - 40 - 20 , 20 , 40 , 40 ) ;
199-
200- basePaint . Color = new SKColor ( 0 , 0 , 0 , 127 ) ;
201- canvas . DrawRoundRect ( SKRect . Create ( playButtonRect . X , playButtonRect . Y , playButtonRect . Width , playButtonRect . Height ) , 5 , 5 , basePaint ) ;
194+ int playButtonSize = 40 ;
195+ playButtonRect = new Rectangle ( info . Width - playButtonSize - MARGIN_STANDARD , MARGIN_STANDARD , playButtonSize , playButtonSize ) ;
202196
203- float playOpacity = isMouseOverPlay ? 1.0f : 0.5f ;
197+ basePaint . Color = overlayColor ;
198+ canvas . DrawRoundRect ( SKRect . Create ( playButtonRect . X , playButtonRect . Y , playButtonRect . Width , playButtonRect . Height ) , BORDER_RADIUS , BORDER_RADIUS , basePaint ) ;
199+
200+ float playOpacity = isMouseOverPlay ? OPACITY_HOVER : OPACITY_NORMAL ;
204201 basePaint . Color = SKColors . White . WithAlpha ( ( byte ) ( 255 * playOpacity ) ) ;
205202 string playIcon = ViewModel . IsPlaying ? "\uf04c " : "\uf04b " ;
206203 var textBounds = new SKRect ( ) ;
@@ -222,10 +219,10 @@ private void DrawOverlay(SKCanvas canvas, SKImageInfo info)
222219 float msgHeight = 6 + 16 + 6 ;
223220 downloadMessageRect = new Rectangle ( ( int ) ( info . Width / 2 - msgWidth / 2 ) , info . Height - ( int ) msgHeight - 15 , ( int ) msgWidth , ( int ) msgHeight ) ;
224221
225- basePaint . Color = new SKColor ( 0 , 0 , 0 , 127 ) ;
226- canvas . DrawRoundRect ( SKRect . Create ( downloadMessageRect . X , downloadMessageRect . Y , downloadMessageRect . Width , downloadMessageRect . Height ) , 5 , 5 , basePaint ) ;
222+ basePaint . Color = overlayColor ;
223+ canvas . DrawRoundRect ( SKRect . Create ( downloadMessageRect . X , downloadMessageRect . Y , downloadMessageRect . Width , downloadMessageRect . Height ) , BORDER_RADIUS , BORDER_RADIUS , basePaint ) ;
227224
228- float msgOpacity = isMouseOverDownload ? 1.0f : 0.8f ;
225+ float msgOpacity = isMouseOverDownload ? OPACITY_HOVER : OPACITY_MESSAGE ;
229226 basePaint . Color = SKColors . White . WithAlpha ( ( byte ) ( 255 * msgOpacity ) ) ;
230227 canvas . DrawText ( ViewModel . Message , downloadMessageRect . X + 8 , downloadMessageRect . Y + 5 + 16 , textFont , basePaint ) ;
231228 }
@@ -244,7 +241,7 @@ private void DrawOverlay(SKCanvas canvas, SKImageInfo info)
244241 private void DrawArrowArea ( SKCanvas canvas , SKImageInfo info , bool isLeft )
245242 {
246243 bool isHovered = isLeft ? isMouseOverLeft : isMouseOverRight ;
247- float opacity = isHovered ? 1.0f : 0.5f ;
244+ float opacity = isHovered ? OPACITY_HOVER : OPACITY_NORMAL ;
248245
249246 float x = isLeft ? 40 : info . Width - 40 ;
250247 float y = info . Height / 2 ;
@@ -271,26 +268,23 @@ private void DrawCornerLabel(SKCanvas canvas, SKImageInfo info, string text, boo
271268 var textBounds = new SKRect ( ) ;
272269 textFont . MeasureText ( text , out textBounds ) ;
273270
274- // Calculate margins and dimensions
275271 float leftMargin = isBottomRight ? 8 : 11 ;
276272 float rightMargin = isBottomRight ? 11 : 8 ;
277273 float borderWidth = textBounds . Width + leftMargin + rightMargin ;
278274 float borderHeight = 4 + 16 + 9 ;
279275
280- // Position rect and cache it
281276 float rectX = isBottomRight ? info . Width - borderWidth + 3 : - 3 ;
282277 float rectY = info . Height - borderHeight + 3 ;
283278 Rectangle labelRect = new Rectangle ( ( int ) rectX , ( int ) rectY , ( int ) borderWidth , ( int ) borderHeight ) ;
284-
279+
285280 if ( isBottomRight )
286281 authorLabelRect = labelRect ;
287282 else
288283 downloadSizeLabelRect = labelRect ;
289284
290- basePaint . Color = new SKColor ( 0 , 0 , 0 , OVERLAY_ALPHA ) ;
285+ basePaint . Color = overlayColor ;
291286 canvas . DrawRoundRect ( SKRect . Create ( rectX , rectY , borderWidth , borderHeight ) , BORDER_RADIUS , BORDER_RADIUS , basePaint ) ;
292287
293- // Draw text
294288 basePaint . Color = SKColors . White . WithAlpha ( OVERLAY_ALPHA ) ;
295289 float textX = isBottomRight ? info . Width - textBounds . Width - rightMargin + 3 : leftMargin - 3 ;
296290 float textY = rectY + 4 + 16 ;
@@ -305,21 +299,19 @@ private void DrawCarouselIndicators(SKCanvas canvas, SKImageInfo info)
305299 int itemSpacing = 6 ;
306300 int totalWidth = count * indicatorWidth + ( count - 1 ) * itemSpacing ;
307301 int startX = ( info . Width - totalWidth ) / 2 ;
308- int y = info . Height - 16 - 32 / 2 ;
302+ int y = info . Height - 16 - 16 ; // bottom margin - half of clickable height
309303
310- // Cache clickable rectangles for hit testing
311304 carouselIndicatorRects = new Rectangle [ count ] ;
312305
313306 for ( int i = 0 ; i < count ; i ++ )
314307 {
315- float opacity = ( i == ViewModel . SelectedIndex ) ? 1.0f : 0.5f ;
308+ float opacity = ( i == ViewModel . SelectedIndex ) ? OPACITY_HOVER : OPACITY_NORMAL ;
316309 basePaint . Color = SKColors . White . WithAlpha ( ( byte ) ( 255 * opacity ) ) ;
317310
318311 int rectX = startX + i * ( indicatorWidth + itemSpacing ) ;
319- var rect = SKRect . Create ( rectX , y - indicatorHeight / 2 , indicatorWidth , indicatorHeight ) ;
320- canvas . DrawRect ( rect , basePaint ) ;
312+ canvas . DrawRect ( rectX , y - indicatorHeight / 2 , indicatorWidth , indicatorHeight , basePaint ) ;
321313
322- // Cache full clickable height for hit testing
314+ // Cache full clickable area for hit testing
323315 carouselIndicatorRects [ i ] = new Rectangle ( rectX , y - 16 , indicatorWidth , 32 ) ;
324316 }
325317 }
@@ -398,7 +390,7 @@ protected override void OnMouseMove(MouseEventArgs e)
398390
399391 // Check UI elements in priority order using cached rectangles
400392 isMouseOverPlay = playButtonRect . Contains ( e . Location ) ;
401-
393+
402394 if ( ! isMouseOverPlay )
403395 isMouseOverDownload = downloadMessageRect . Contains ( e . Location ) ;
404396
@@ -484,6 +476,14 @@ protected override void Dispose(bool disposing)
484476 {
485477 fadeTimer ? . Dispose ( ) ;
486478 ViewModel ? . Stop ( ) ;
479+
480+ // Dispose cached SkiaSharp objects
481+ basePaint ? . Dispose ( ) ;
482+ titleFont ? . Dispose ( ) ;
483+ previewFont ? . Dispose ( ) ;
484+ textFont ? . Dispose ( ) ;
485+ iconFont16 ? . Dispose ( ) ;
486+ iconFont20 ? . Dispose ( ) ;
487487 }
488488 base . Dispose ( disposing ) ;
489489 }
0 commit comments