1 // =================================
  2 // Copyright (c) 2024 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 using System;
  7 
  8 namespace System.Windows
  9 {
 10     public class ComponentContainer
 11     {
 12         public explicit ComponentContainer(Component* parent_) : firstChild(null)lastChild(null)parent(parent_)
 13         {
 14         }
 15         public virtual ~ComponentContainer()
 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 bool IsEmpty() const
 26         {
 27             return firstChild == null;
 28         }
 29         [nodiscard]
 30         public Result<bool> AddChild(Component* child)
 31         {
 32             ComponentContainer* container = child->GetContainer();
 33             if (container != null)
 34             {
 35                 UniquePtr<Component> removedChild = container->RemoveChild(child);
 36                 child = removedChild.Release();
 37             }
 38             if (lastChild != null)
 39             {
 40                 lastChild->LinkAfter(child);
 41             }
 42             if (firstChild == null)
 43             {
 44                 firstChild = child;
 45             }
 46             child->SetContainer(this);
 47             lastChild = child;
 48             if ((child is Control*) && parent != null && (parent is Control*))
 49             {
 50                 Control* childControl = cast<Control*>(child);
 51                 Control* parentControl = cast<Control*>(parent);
 52                 auto result = parentControl->AddChildVisual(childControl);
 53                 if (result.Error())
 54                 {
 55                     return Result<bool>(ErrorId(result.GetErrorId()));
 56                 }
 57             }
 58             return Result<bool>(true);
 59         }
 60         public 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         [nodiscard]
 77         public Result<bool> InsertBefore(Component* childComponent* before)
 78         {
 79             if (before == null)
 80             {
 81                 return AddChild(child);
 82             }
 83             else
 84             {
 85                 ComponentContainer* container = child->GetContainer();
 86                 if (container != null)
 87                 {
 88                     UniquePtr<Component> removedChild = container->RemoveChild(child);
 89                     child = removedChild.Release();
 90                 }
 91                 child->SetContainer(this);
 92                 if (firstChild == before)
 93                 {
 94                     firstChild = child;
 95                 }
 96                 before->LinkBefore(child);
 97                 if ((child is Control*) && parent != null && (parent is Control*))
 98                 {
 99                     Control* childControl = cast<Control*>(child);
100                     Control* parentControl = cast<Control*>(parent);
101                     auto result = parentControl->AddChildVisual(childControl);
102                     if (result.Error())
103                     {
104                         return Result<bool>(ErrorId(result.GetErrorId()));
105                     }
106                 }
107             }
108             return Result<bool>(true);
109         }
110         [nodiscard]
111         public Result<bool> InsertAfter(Component* childComponent* after)
112         {
113             if (after == null)
114             {
115                 return AddChild(child);
116             }
117             else
118             {
119                 ComponentContainer* container = child->GetContainer();
120                 if (container != null)
121                 {
122                     UniquePtr<Component> removedChild = container->RemoveChild(child);
123                     child = removedChild.Release();
124                 }
125                 child->SetContainer(this);
126                 after->LinkAfter(child);
127                 if (after == lastChild)
128                 {
129                     lastChild = child;
130                 }
131                 if ((child is Control*) && parent != null && (parent is Control*))
132                 {
133                     Control* childControl = cast<Control*>(child);
134                     Control* parentControl = cast<Control*>(parent);
135                     auto result = parentControl->AddChildVisual(childControl);
136                     if (result.Error())
137                     {
138                         return Result<bool>(ErrorId(result.GetErrorId()));
139                     }
140                 }
141             }
142             return Result<bool>(true);
143         }
144         public inline Component* FirstChild() const
145         {
146             return firstChild;
147         }
148         public inline Component* LastChild() const
149         {
150             return lastChild;
151         }
152         public inline Component* Parent() const
153         {
154             return parent;
155         }
156         internal void SetParent(Component* parent_)
157         {
158             parent = parent_;
159         }
160         private Component* firstChild;
161         private Component* lastChild;
162         private Component* parent;
163     }