1 // =================================
  2 // Copyright (c) 2022 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 using System;
  7 
  8 namespace System.Screen
  9 {
 10     public class Container
 11     {
 12         public nothrow Container(Component* parent_) : parent(parent_)firstChild(null)lastChild(null)
 13         {
 14         }
 15         public ~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 nothrow bool IsEmpty() const
 26         {
 27             return firstChild == null;
 28         }
 29         public nothrow Component* Parent() const
 30         {
 31             return parent;
 32         }
 33         public nothrow Component* FirstChild() const
 34         {
 35             return firstChild;
 36         }
 37         public nothrow Component* LastChild() const
 38         {
 39             return lastChild;
 40         }
 41         public nothrow void AddChild(Component* child)
 42         {
 43             Container* container = child->GetContainer();
 44             if (container != null)
 45             {
 46                 UniquePtr<Component> removedChild = container->RemoveChild(child);
 47                 child = removedChild.Release();
 48             }
 49             if (lastChild != null)
 50             {
 51                 lastChild->LinkAfter(child);
 52             }
 53             if (firstChild == null)
 54             {
 55                 firstChild = child;
 56             }
 57             child->SetContainer(this);
 58             lastChild = child;
 59         }
 60         public nothrow UniquePtr<Component> RemoveChild(Component* child)
 61         {
 62             child->Unlink();
 63             if (child == firstChild)
 64             {
 65                 firstChild = child->NextSibling();
 66             }
 67             if (child == lastChild)
 68             {
 69                 lastChild = child->PrevSibling();
 70             }
 71             child->SetContainer(null);
 72             child->SetNextSibling(null);
 73             child->SetPrevSibling(null);
 74             return UniquePtr<Component>(child);
 75         }
 76         public nothrow void InsertBefore(Component* childComponent* before)
 77         {
 78             if (before == null)
 79             {
 80                 AddChild(child);
 81             }
 82             else
 83             {
 84                 Container* container = child->GetContainer();
 85                 if (container != null)
 86                 {
 87                     UniquePtr<Component> removedChild = container->RemoveChild(child);
 88                     child = removedChild.Release();
 89                 }
 90                 child->SetContainer(this);
 91                 if (firstChild == before)
 92                 {
 93                     firstChild = child;
 94                 }
 95                 before->LinkBefore(child);
 96             }
 97         }
 98         public nothrow 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             }
119         }
120         private Component* parent;
121         private Component* firstChild;
122         private Component* lastChild;
123     }
124 }