#nullable enable namespace Terminal.Gui; public partial class View { /// /// Gets the current Clip region. /// /// /// /// There is a single clip region for the entire application. /// /// /// This method returns the current clip region, not a clone. If there is a need to modify the clip region, clone it first. /// /// /// The current Clip. public static Region? GetClip () { return Application.Driver?.Clip; } /// /// Sets the Clip to the specified region. /// /// /// /// There is a single clip region for the entire application. This method sets the clip region to the specified /// region. /// /// /// public static void SetClip (Region? region) { if (Driver is { } && region is { }) { Driver.Clip = region; } } /// /// Sets the Clip to be the rectangle of the screen. /// /// /// /// There is a single clip region for the entire application. This method sets the clip region to the screen. /// /// /// This method returns the current clip region, not a clone. If there is a need to modify the clip region, it is /// recommended to clone it first. /// /// /// /// The current Clip, which can be then re-applied /// public static Region? SetClipToScreen () { Region? previous = GetClip (); if (Driver is { }) { Driver.Clip = new (Application.Screen); } return previous; } /// /// Removes the specified rectangle from the Clip. /// /// /// /// There is a single clip region for the entire application. /// /// /// public static void ExcludeFromClip (Rectangle rectangle) { Driver?.Clip?.Exclude (rectangle); } /// /// Removes the specified rectangle from the Clip. /// /// /// /// There is a single clip region for the entire application. /// /// /// public static void ExcludeFromClip (Region? region) { Driver?.Clip?.Exclude (region); } /// /// Changes the Clip to the intersection of the current Clip and the of this View. /// /// /// /// This method returns the current clip region, not a clone. If there is a need to modify the clip region, it is /// recommended to clone it first. /// /// /// /// The current Clip, which can be then re-applied /// internal Region? AddFrameToClip () { if (Driver is null) { return null; } Region previous = GetClip () ?? new (Application.Screen); Region frameRegion = previous.Clone (); // Translate viewportRegion to screen-relative coords Rectangle screenRect = FrameToScreen (); frameRegion.Intersect (screenRect); if (this is Adornment adornment && adornment.Thickness != Thickness.Empty) { // Ensure adornments can't draw outside their thickness frameRegion.Exclude (adornment.Thickness.GetInside (FrameToScreen())); } SetClip (frameRegion); return previous; } /// Changes the Clip to the intersection of the current Clip and the of this View. /// /// /// By default, sets the Clip to the intersection of the current clip region and the /// . This ensures that drawing is constrained to the viewport, but allows /// content to be drawn beyond the viewport. /// /// /// If has set, clipping will be /// applied to just the visible content area. /// /// /// /// This method returns the current clip region, not a clone. If there is a need to modify the clip region, it /// is recommended to clone it first. /// /// /// /// /// The current Clip, which can be then re-applied /// public Region? AddViewportToClip () { if (Driver is null) { return null; } Region previous = GetClip () ?? new (Application.Screen); Region viewportRegion = previous.Clone (); Rectangle viewport = ViewportToScreen (new Rectangle (Point.Empty, Viewport.Size)); viewportRegion?.Intersect (viewport); if (ViewportSettings.HasFlag (ViewportSettings.ClipContentOnly)) { // Clamp the Clip to the just content area that is within the viewport Rectangle visibleContent = ViewportToScreen (new Rectangle (new (-Viewport.X, -Viewport.Y), GetContentSize ())); viewportRegion?.Intersect (visibleContent); } if (this is Adornment adornment && adornment.Thickness != Thickness.Empty) { // Ensure adornments can't draw outside their thickness viewportRegion?.Exclude (adornment.Thickness.GetInside (viewport)); } SetClip (viewportRegion); return previous; } }