1 // =================================
  2 // Copyright (c) 2025 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 using System;
  7 using System.Collections;
  8 
  9 namespace System.Windows
 10 {
 11     public inline int DefaultControlPadding()
 12     {
 13         return 4;
 14     }
 15 
 16     public ControlCreateParams& PaddedControlControlCreateParams(ControlCreateParams& controlCreateParamsControl* child)
 17     {
 18         return controlCreateParams.SetWindowClassName("System.Windows.PaddedControl").SetBackgroundColor(child->BackgroundColor());
 19     }
 20 
 21     public class PaddedControlCreateParams
 22     {
 23         public PaddedControlCreateParams(ControlCreateParams& controlCreateParams_Control* child_) : 
 24             controlCreateParams(controlCreateParams_)
 25             child(child_)
 26             padding(Padding(DefaultControlPadding()DefaultControlPadding()DefaultControlPadding()DefaultControlPadding()))
 27         {
 28         }
 29         public PaddedControlCreateParams& Defaults()
 30         {
 31             return *this;
 32         }
 33         public PaddedControlCreateParams& SetPadding(const Padding& padding_)
 34         {
 35             padding = padding_;
 36             return *this;
 37         }
 38         public ControlCreateParams& controlCreateParams;
 39         public Control* child;
 40         public Padding padding;
 41     }
 42 
 43     public class PaddedControl : Control
 44     {
 45         public PaddedControl(Control* child_const Padding& padding_const Point& locationconst Size& sizeDock dockAnchors anchors) : 
 46             base("System.Windows.PaddedControl"DefaultWindowClassStyle()DefaultChildWindowStyle()DefaultExtendedWindowStyle()
 47             child_->BackgroundColor()"paddedControl"locationsizedockanchors)container(this)child(child_)padding(padding_)
 48         {
 49             auto result = container.AddChild(child);
 50             if (result.Error())
 51             {
 52                 SetErrorId(result.GetErrorId());
 53                 return;
 54             }
 55             result = SetChildPos();
 56             if (result.Error())
 57             {
 58                 SetErrorId(result.GetErrorId());
 59                 return;
 60             }
 61         }
 62         public explicit PaddedControl(Control* child) : this(childPadding(DefaultControlPadding()DefaultControlPadding()DefaultControlPadding()DefaultControlPadding())
 63             Point()Size()Dock.noneAnchors.none)
 64         {
 65         }
 66         public PaddedControl(PaddedControlCreateParams& createParams) : 
 67             base(createParams.controlCreateParams)
 68             container(this)
 69             child(createParams.child)
 70             padding(createParams.padding)
 71         {
 72             auto result = container.AddChild(child);
 73             if (result.Error())
 74             {
 75                 SetErrorId(result.GetErrorId());
 76                 return;
 77             }
 78             result = SetChildPos();
 79             if (result.Error())
 80             {
 81                 SetErrorId(result.GetErrorId());
 82                 return;
 83             }
 84         }
 85         protected override bool IsDecoratorControl() const
 86         {
 87             return true;
 88         }
 89         public override Padding DefaultPadding() const
 90         {
 91             return padding;
 92         }
 93         [nodiscard]
 94         protected override Result<bool> OnLocationChanged()
 95         {
 96             auto result = base->OnLocationChanged();
 97             if (result.Error()) return result;
 98             result = SetChildPos();
 99             if (result.Error()) return result;
100             return Result<bool>(true);
101         }
102         [nodiscard]
103         protected override Result<bool> OnSizeChanged(SizeChangedEventArgs& args)
104         {
105             auto result = base->OnSizeChanged(args);
106             if (result.Error()) return result;
107             result = SetChildPos();
108             if (result.Error()) return result;
109             return Result<bool>(true);
110         }
111         protected override void OnChildContentChanged(ControlEventArgs& args)
112         {
113             base->OnChildContentChanged(args);
114             Control* parentControl = ParentControl();
115             if (parentControl != null)
116             {
117                 parentControl->OnChildContentChanged(args);
118             }
119         }
120         protected override void OnChildContentLocationChanged(ControlEventArgs& args)
121         {
122             base->OnChildContentLocationChanged(args);
123             Control* parentControl = ParentControl();
124             if (parentControl != null)
125             {
126                 parentControl->OnChildContentLocationChanged(args);
127             }
128         }
129         [nodiscard]
130         protected override Result<bool> OnChildContentSizeChanged(ControlEventArgs& args)
131         {
132             auto result = base->OnChildContentSizeChanged(args);
133             if (result.Error()) return result;
134             Control* parentControl = ParentControl();
135             if (parentControl != null)
136             {
137                 result = parentControl->OnChildContentSizeChanged(args);
138                 if (result.Error()) return result;
139             }
140             return Result<bool>(true);
141         }
142         [nodiscard]
143         protected override Result<bool> OnChildGotFocus(ControlEventArgs& args)
144         {
145             auto result = base->OnChildGotFocus(args);
146             if (result.Error()) return result;
147             Control* parentControl = ParentControl();
148             if (parentControl != null)
149             {
150                 result = parentControl->OnChildGotFocus(args);
151                 if (result.Error()) return result;
152             }
153             return Result<bool>(true);
154         }
155         [nodiscard]
156         protected override Result<bool> OnChildLostFocus(ControlEventArgs& args)
157         {
158             auto result = base->OnChildLostFocus(args);
159             if (result.Error()) return result;
160             Control* parentControl = ParentControl();
161             if (parentControl != null)
162             {
163                 result = parentControl->OnChildLostFocus(args);
164                 if (result.Error()) return result;
165             }
166             return Result<bool>(true);
167         }
168         [nodiscard]
169         protected override Result<bool> OnPaint(PaintEventArgs& args)
170         {
171             auto result = args.graphics.Clear(BackgroundColor());
172             if (result.Error())
173             {
174                 return Result<bool>(ErrorId(result.GetErrorId()));
175             }
176             return base->OnPaint(args);
177         }
178         internal override Control* GetFirstEnabledTabStopControl() const
179         {
180             return child->GetFirstEnabledTabStopControl();
181         }
182         internal override Control* GetLastEnabledTabStopControl() const
183         {
184             return child->GetLastEnabledTabStopControl();
185         }
186         [nodiscard]
187         private Result<bool> SetChildPos()
188         {
189             Point loc;
190             Size size = GetSize();
191             Rect childRect(locsize);
192             childRect.location.x = loc.x + padding.left;
193             childRect.location.y = loc.x + padding.top;
194             childRect.size.w = size.w - padding.Horizontal();
195             childRect.size.h = size.h - padding.Vertical();
196             auto result = child->SetLocation(childRect.location);
197             if (result.Error()) return result;
198             result = child->SetSize(childRect.size);
199             if (result.Error()) return result;
200             return Result<bool>(true);
201         }
202         private ComponentContainer container;
203         private Control* child;
204         private Padding padding;
205     }