123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249 |
- using System;
- namespace Terminal.Gui {
- /// <summary>
- /// A container for single <see cref="Child"/> that will allow to drawn <see cref="Border"/> in
- /// two ways. If <see cref="UsePanelFrame"/> the borders and the child will be accommodated in the available
- /// panel size, otherwise the panel will be resized based on the child and borders thickness sizes.
- /// </summary>
- public class PanelView : View {
- ChildContentView childContentView;
- private class ChildContentView : View { }
- private class SavedPosDim {
- public Pos X;
- public Pos Y;
- public Dim Width;
- public Dim Height;
- }
- private SavedPosDim savedPanel;
- private SavedPosDim savedChild;
- private View child;
- private bool usePanelFrame;
- /// <summary>
- /// Initializes a panel with a null child.
- /// </summary>
- public PanelView () : this (null) { }
- /// <summary>
- /// Initializes a panel with a valid child.
- /// </summary>
- /// <param name="child"></param>
- public PanelView (View child)
- {
- childContentView = new ChildContentView ();
- base.Add (childContentView);
- CanFocus = false;
- Child = child;
- if (child != null) {
- Visible = child.Visible;
- }
- }
- /// <summary>
- /// Gets or sets if the panel size will used, otherwise the child size.
- /// </summary>
- public bool UsePanelFrame {
- get => usePanelFrame;
- set {
- usePanelFrame = value;
- AdjustContainer ();
- }
- }
- /// <summary>
- /// The child that will use this panel.
- /// </summary>
- public View Child {
- get => child;
- set {
- if (child != null && value == null) {
- childContentView.Remove (child);
- child = value;
- return;
- }
- child = value;
- savedChild = new SavedPosDim () {
- X = child?.X,
- Y = child?.Y,
- Width = child?.Width,
- Height = child?.Height
- };
- if (child == null) {
- Visible = false;
- return;
- }
- if (child?.Border != null) {
- Border = child.Border;
- } else {
- if (Border == null) {
- Border = new Border ();
- }
- Child.Border = Border;
- }
- Border.Child = childContentView;
- if (!child.IsInitialized) {
- child.Initialized += Child_Initialized;
- }
- childContentView.Add (Child);
- }
- }
- /// <inheritdoc />
- public override Border Border {
- get => base.Border;
- set {
- if (base.Border?.Child != null && value.Child == null) {
- value.Child = base.Border.Child;
- }
- base.Border = value;
- if (value == null) {
- return;
- }
- Border.BorderChanged += Border_BorderChanged;
- if (Child != null && (Child?.Border == null || Child?.Border != value)) {
- if (Child?.Border == null) {
- Child.Border = new Border ();
- }
- Child.Border = Border;
- Child.Border.BorderChanged += Border_BorderChanged;
- }
- AdjustContainer ();
- }
- }
- private void Child_Initialized (object sender, EventArgs e)
- {
- savedPanel = new SavedPosDim () {
- X = X,
- Y = Y,
- Width = Width,
- Height = Height
- };
- AdjustContainer ();
- Child.Initialized -= Child_Initialized;
- }
- private void Border_BorderChanged (Border obj)
- {
- AdjustContainer ();
- }
- private void AdjustContainer ()
- {
- if (Child?.IsInitialized == true) {
- if (Child?.Border != null && Child.Border != Border) {
- Border = Child.Border;
- }
- var borderLength = Child.Border.DrawMarginFrame ? 1 : 0;
- var sumPadding = Child.Border.GetSumThickness ();
- var effect3DOffset = Child.Border.Effect3D ? Child.Border.Effect3DOffset : new Point ();
- if (!UsePanelFrame) {
- X = savedPanel.X;
- childContentView.X = borderLength + sumPadding.Left;
- Y = savedPanel.Y;
- childContentView.Y = borderLength + sumPadding.Top;
- if (savedChild.Width is Dim.DimFill) {
- var margin = -savedChild.Width.Anchor (0);
- Width = Dim.Fill (margin);
- childContentView.Width = Dim.Fill (margin + borderLength + sumPadding.Right);
- } else {
- var savedLayout = LayoutStyle;
- LayoutStyle = LayoutStyle.Absolute;
- Width = savedChild.X.Anchor (0) + savedChild.Width + (2 * borderLength) + sumPadding.Right + sumPadding.Left;
- LayoutStyle = savedLayout;
- childContentView.Width = Dim.Fill (borderLength + sumPadding.Right);
- }
- if (savedChild.Height is Dim.DimFill) {
- var margin = -savedChild.Height.Anchor (0);
- Height = Dim.Fill (margin);
- childContentView.Height = Dim.Fill (margin + borderLength + sumPadding.Bottom);
- } else {
- var savedLayout = LayoutStyle;
- LayoutStyle = LayoutStyle.Absolute;
- Height = savedChild.Y.Anchor (0) + savedChild.Height + (2 * borderLength) + sumPadding.Bottom + sumPadding.Top;
- LayoutStyle = savedLayout;
- childContentView.Height = Dim.Fill (borderLength + sumPadding.Bottom);
- }
- } else {
- X = savedPanel.X - (effect3DOffset.X < 0 ? effect3DOffset.X : 0);
- childContentView.X = borderLength + sumPadding.Left;
- Y = savedPanel.Y - (effect3DOffset.Y < 0 ? effect3DOffset.Y : 0);
- childContentView.Y = borderLength + sumPadding.Top;
- Width = savedPanel.Width;
- Height = savedPanel.Height;
- if (Width is Dim.DimFill) {
- var margin = -savedPanel.Width.Anchor (0) +
- (effect3DOffset.X > 0 ? effect3DOffset.X : 0);
- Width = Dim.Fill (margin);
- childContentView.Width = Dim.Fill (margin + borderLength + sumPadding.Right +
- (effect3DOffset.X > 0 ? effect3DOffset.X : 0));
- } else {
- childContentView.Width = Dim.Fill (borderLength + sumPadding.Right);
- }
- if (Height is Dim.DimFill) {
- var margin = -savedPanel.Height.Anchor (0) +
- (effect3DOffset.Y > 0 ? effect3DOffset.Y : 0);
- Height = Dim.Fill (margin);
- childContentView.Height = Dim.Fill (margin + borderLength + sumPadding.Bottom +
- (effect3DOffset.Y > 0 ? effect3DOffset.Y : 0));
- } else {
- childContentView.Height = Dim.Fill (borderLength + sumPadding.Bottom);
- }
- }
- Visible = Child.Visible;
- } else {
- Visible = false;
- }
- }
- /// <inheritdoc/>
- public override void Add (View view)
- {
- if (Child != null) {
- Child = null;
- }
- Child = view;
- }
- /// <inheritdoc/>
- public override void Remove (View view)
- {
- if (view == childContentView) {
- base.Remove (view);
- return;
- }
- childContentView.Remove (view);
- if (Child != null) {
- Child = null;
- }
- }
- /// <inheritdoc/>
- public override void RemoveAll ()
- {
- if (Child != null) {
- Child = null;
- }
- }
- /// <inheritdoc/>
- public override void Redraw (Rect bounds)
- {
- if (!NeedDisplay.IsEmpty) {
- Driver.SetAttribute (Child.GetNormalColor ());
- Child.Border.DrawContent (Border.Child);
- }
- var savedClip = childContentView.ClipToBounds ();
- childContentView.Redraw (childContentView.Bounds);
- Driver.Clip = savedClip;
- ClearLayoutNeeded ();
- ClearNeedsDisplay ();
- }
- }
- }
|