#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;
}
}