1 // =================================
  2 // Copyright (c) 2021 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 using System;
  7 
  8 namespace System.Windows
  9 {
 10     public class Container
 11     {
 12         public nothrow Container(Component* parent_) : firstChild(null)lastChild(null)parent(parent_)
 13         {
 14         }
 15         public virtual ~Container()
 16         {
 17             Component* child = firstChild;
 18             while (child != null)
 19             {
 20                 Component* next = child->NextSibling();
 21                 delete child;
 22                 child = next;
 23             }
 24         }
 25         public inline nothrow bool IsEmpty() const
 26         {
 27             return firstChild == null;
 28         }
 29         public void AddChild(Component* child)
 30         {
 31             Container* container = child->GetContainer();
 32             if (container != null)
 33             {
 34                 UniquePtr<Component> removedChild = container->RemoveChild(child);
 35                 child = removedChild.Release();
 36             }
 37             if (lastChild != null)
 38             {
 39                 lastChild->LinkAfter(child);
 40             }
 41             if (firstChild == null)
 42             {
 43                 firstChild = child;
 44             }
 45             child->SetContainer(this);
 46             lastChild = child;
 47             if ((child is Control*) && parent != null && (parent is Control*))
 48             {
 49                 Control* childControl = cast<Control*>(child);
 50                 Control* parentControl = cast<Control*>(parent);
 51                 parentControl->AddChildVisual(childControl);
 52             }
 53         }
 54         public UniquePtr<Component> RemoveChild(Component* child)
 55         {
 56             child->Unlink();
 57             if (child == firstChild)
 58             {
 59                 firstChild = child->NextSibling();
 60             }
 61             if (child == lastChild)
 62             {
 63                 lastChild = child->PrevSibling();
 64             }
 65             child->SetContainer(null);
 66             child->SetNextSibling(null);
 67             child->SetPrevSibling(null);
 68             return UniquePtr<Component>(child);
 69         }
 70         public void InsertBefore(Component* childComponent* before)
 71         {
 72             if (before == null)
 73             {
 74                 AddChild(child);
 75             }
 76             else
 77             {
 78                 Container* container = child->GetContainer();
 79                 if (container != null)
 80                 {
 81                     UniquePtr<Component> removedChild = container->RemoveChild(child);
 82                     child = removedChild.Release();
 83                 }
 84                 child->SetContainer(this);
 85                 if (firstChild == before)
 86                 {
 87                     firstChild = child;
 88                 }
 89                 before->LinkBefore(child);
 90                 if ((child is Control*) && parent != null && (parent is Control*))
 91                 {
 92                     Control* childControl = cast<Control*>(child);
 93                     Control* parentControl = cast<Control*>(parent);
 94                     parentControl->AddChildVisual(childControl);
 95                 }
 96             }
 97         }
 98         public void InsertAfter(Component* childComponent* after)
 99         {
100             if (after == null)
101             {
102                 AddChild(child);
103             }
104             else
105             {
106                 Container* container = child->GetContainer();
107                 if (container != null)
108                 {
109                     UniquePtr<Component> removedChild = container->RemoveChild(child);
110                     child = removedChild.Release();
111                 }
112                 child->SetContainer(this);
113                 after->LinkAfter(child);
114                 if (after == lastChild)
115                 {
116                     lastChild = child;
117                 }
118                 if ((child is Control*) && parent != null && (parent is Control*))
119                 {
120                     Control* childControl = cast<Control*>(child);
121                     Control* parentControl = cast<Control*>(parent);
122                     parentControl->AddChildVisual(childControl);
123                 }
124             }
125         }
126         public inline nothrow Component* FirstChild() const
127         {
128             return firstChild;
129         }
130         public inline nothrow Component* LastChild() const
131         {
132             return lastChild;
133         }
134         public inline nothrow Component* Parent() const
135         {
136             return parent;
137         }
138         internal nothrow void SetParent(Component* parent_)
139         {
140             parent = parent_;
141         }
142         private Component* firstChild;
143         private Component* lastChild;
144         private Component* parent;
145     }
146 }