77// -----------------------------------------------------------------------
88
99using System . Drawing ;
10+ using SharpConsoleUI . Drawing ;
1011using SharpConsoleUI . Events ;
1112using SharpConsoleUI . Layout ;
1213using Color = Spectre . Console . Color ;
@@ -27,6 +28,19 @@ public abstract class PortalContentBase : IWindowControl, IDOMPaintable, IMouseA
2728 private int _actualWidth ;
2829 private int _actualHeight ;
2930
31+ /// <summary>
32+ /// When set, PaintDOM draws a border using these characters and shrinks the
33+ /// inner bounds by 1 on each side before calling <see cref="PaintPortalContent"/>.
34+ /// Mouse coordinates are automatically adjusted by (-1,-1) for the border offset.
35+ /// </summary>
36+ public BoxChars ? BorderStyle { get ; set ; }
37+
38+ /// <summary>Foreground color for the border characters. Falls back to the default foreground.</summary>
39+ public Color ? BorderColor { get ; set ; }
40+
41+ /// <summary>Background color for the border and fill area. Falls back to the default background.</summary>
42+ public Color ? BorderBackgroundColor { get ; set ; }
43+
3044 #region IHasPortalBounds
3145
3246 /// <summary>
@@ -79,7 +93,25 @@ public abstract class PortalContentBase : IWindowControl, IDOMPaintable, IMouseA
7993 public event EventHandler < MouseEventArgs > ? MouseMove ;
8094 #pragma warning restore CS0067
8195
82- /// <inheritdoc/>
96+ /// <summary>
97+ /// Explicit interface implementation that adjusts mouse coordinates for the border
98+ /// offset before delegating to the public virtual <see cref="ProcessMouseEvent"/>.
99+ /// </summary>
100+ bool IMouseAwareControl . ProcessMouseEvent ( MouseEventArgs args )
101+ {
102+ if ( BorderStyle . HasValue )
103+ {
104+ var adjusted = args . WithPosition (
105+ new System . Drawing . Point ( args . Position . X - 1 , args . Position . Y - 1 ) ) ;
106+ return ProcessMouseEvent ( adjusted ) ;
107+ }
108+ return ProcessMouseEvent ( args ) ;
109+ }
110+
111+ /// <summary>
112+ /// Processes a mouse event. When <see cref="BorderStyle"/> is set, coordinates
113+ /// are already adjusted for the border offset.
114+ /// </summary>
83115 public abstract bool ProcessMouseEvent ( MouseEventArgs args ) ;
84116
85117 #endregion
@@ -167,7 +199,18 @@ public void PaintDOM(CharacterBuffer buffer, LayoutRect bounds, LayoutRect clipR
167199 _actualWidth = bounds . Width ;
168200 _actualHeight = bounds . Height ;
169201
170- PaintPortalContent ( buffer , bounds , clipRect , defaultFg , defaultBg ) ;
202+ if ( BorderStyle is { } border )
203+ {
204+ buffer . DrawBox ( bounds , border , BorderColor ?? defaultFg ,
205+ BorderBackgroundColor ?? defaultBg ) ;
206+ var inner = new LayoutRect ( bounds . X + 1 , bounds . Y + 1 ,
207+ Math . Max ( 0 , bounds . Width - 2 ) , Math . Max ( 0 , bounds . Height - 2 ) ) ;
208+ PaintPortalContent ( buffer , inner , clipRect , defaultFg , defaultBg ) ;
209+ }
210+ else
211+ {
212+ PaintPortalContent ( buffer , bounds , clipRect , defaultFg , defaultBg ) ;
213+ }
171214 }
172215
173216 /// <summary>
0 commit comments