1 using System;
  2 using System.Windows;
  3 
  4 namespace FileExplorer
  5 {
  6     public System.Windows.Color DefaultPathBarBackgroundColor()
  7     {
  8         return System.Windows.Color.White();
  9     }
 10 
 11     public System.Windows.Color DefaultPathBarFrameColor()
 12     {
 13         return System.Windows.Color(204u206u219u);
 14     }
 15 
 16     public ControlCreateParams& PathBarControlCreateParams(ControlCreateParams& controlCreateParams)
 17     {
 18         return controlCreateParams.SetWindowClassName("FileExplorer.PathBar").
 19             SetWindowClassBackgroundColor(SystemColor.COLOR_WINDOW).
 20             SetBackgroundColor(DefaultPathBarBackgroundColor());
 21     }
 22 
 23     public class PathBarCreateParams
 24     {
 25         public PathBarCreateParams(ControlCreateParams& controlCreateParams_) : 
 26             controlCreateParams(controlCreateParams_)
 27             frameColor(DefaultPathBarFrameColor())
 28         {
 29         }
 30         public PathBarCreateParams& Defaults()
 31         {
 32             return *this;
 33         }
 34         public PathBarCreateParams& SetFrameColor(const System.Windows.Color& frameColor_)
 35         {
 36             frameColor = frameColor_;
 37             return *this;
 38         }
 39         public ControlCreateParams& controlCreateParams;
 40         public System.Windows.Color frameColor;
 41     }
 42 
 43     public class PathBar : ContainerControl
 44     {
 45         public PathBar(PathBarCreateParams& createParams
 46             ControlCreateParams& emptyViewCreateParams
 47             ParentPathSelectorCreateParams& parentPathSelectorCreateParams
 48             PathDividerCreateParams& pathDividerCreateParams
 49             PathViewCreateParams& pathViewCreateParams) : 
 50             base(createParams.controlCreateParams)
 51         {
 52             UniquePtr<EmptyView> emptyViewPtr(new EmptyView(emptyViewCreateParams));
 53             if (emptyViewPtr->Error())
 54             {
 55                 SetErrorId(emptyViewPtr->GetErrorId());
 56                 return;
 57             }
 58             emptyView = emptyViewPtr.Get();
 59             auto result = AddChild(emptyViewPtr.Release());
 60             if (result.Error())
 61             {
 62                 SetErrorId(result.GetErrorId());
 63                 return;
 64             }
 65             UniquePtr<PathDivider> pathDivider1Ptr(new PathDivider(pathDividerCreateParams));
 66             if (pathDivider1Ptr->Error())
 67             {
 68                 SetErrorId(pathDivider1Ptr->GetErrorId());
 69                 return;
 70             }
 71             pathDivider1 = pathDivider1Ptr.Get();
 72             result = AddChild(pathDivider1Ptr.Release());
 73             if (result.Error())
 74             {
 75                 SetErrorId(result.GetErrorId());
 76                 return;
 77             }
 78             UniquePtr<ParentPathSelector> parentPathSelectorPtr(new ParentPathSelector(parentPathSelectorCreateParams));
 79             if (parentPathSelectorPtr->Error())
 80             {
 81                 SetErrorId(parentPathSelectorPtr->GetErrorId());
 82                 return;
 83             }
 84             parentPathSelector = parentPathSelectorPtr.Get();
 85             parentPathSelector->SetDoubleBuffered();
 86             result = AddChild(parentPathSelectorPtr.Release());
 87             if (result.Error())
 88             {
 89                 SetErrorId(result.GetErrorId());
 90                 return;
 91             }
 92             UniquePtr<PathDivider> pathDivider2Ptr(new PathDivider(pathDividerCreateParams));
 93             if (pathDivider2Ptr->Error())
 94             {
 95                 SetErrorId(pathDivider2Ptr->GetErrorId());
 96                 return;
 97             }
 98             pathDivider2 = pathDivider2Ptr.Get();
 99             result = AddChild(pathDivider2Ptr.Release());
100             if (result.Error())
101             {
102                 SetErrorId(result.GetErrorId());
103                 return;
104             }
105             UniquePtr<PathView> pathViewPtr(new PathView(pathViewCreateParams));
106             if (pathViewPtr->Error())
107             {
108                 SetErrorId(pathViewPtr->GetErrorId());
109                 return;
110             }
111             pathView = pathViewPtr.Get();
112             pathView->SetDoubleBuffered();
113             result = AddChild(pathViewPtr.Release());
114             if (result.Error())
115             {
116                 SetErrorId(result.GetErrorId());
117                 return;
118             }
119         }
120         [nodiscard]
121         public Result<bool> SetEmptyViewWidth(int width)
122         {
123             Size sz = emptyView->GetSize();
124             sz.w = width + 4;
125             auto result = emptyView->SetSize(sz);
126             if (result.Error()) return result;
127             Size pathDivider1Size = pathDivider1->GetSize();
128             sz.w = sz.w + pathDivider1Size.w;
129             sz.w = sz.w + 32;
130             Size pathDivider2Size = pathDivider2->GetSize();
131             sz.w = sz.w + pathDivider2Size.w;
132             Size pvSize = pathView->GetSize();
133             sz.w = sz.w + pvSize.w;
134             sz.h = Max(sz.hpvSize.h);
135             result = SetSize(sz);
136             if (result.Error()) return result;
137             return Result<bool>(true);
138         }
139         [nodiscard]
140         public Result<bool> SetPathViewMaxWidth(int width)
141         {
142             Size sz = emptyView->GetSize();
143             auto result = pathView->SetMaxWidth(width);
144             if (result.Error()) return result;
145             Size pathDivider1Size = pathDivider1->GetSize();
146             sz.w = sz.w + pathDivider1Size.w;
147             sz.w = sz.w + 32;
148             Size pathDivider2Size = pathDivider2->GetSize();
149             sz.w = sz.w + pathDivider2Size.w;
150             Size pvSize = pathView->GetSize();
151             sz.w = sz.w + pvSize.w;
152             sz.h = Max(sz.hpvSize.h);
153             result = SetSize(sz);
154             if (result.Error()) return result;
155             return Result<bool>(true);
156         }
157         [nodiscard]
158         public Result<bool> SetCurrentNode(Node* currentNode_)
159         {
160             auto result = pathView->Clear();
161             if (result.Error()) return result;
162             currentNode = currentNode_;
163             Node* node = currentNode;
164             while (node != null)
165             {
166                 if (!node->IsRootDirectory())
167                 {
168                     result = pathView->PushPathComponent(node->Name()node);
169                     if (result.Error()) return result;
170                 }
171                 node = node->Parent();
172             }
173             result = Invalidate();
174             if (result.Error()) return result;
175             return Result<bool>(true);
176         }
177         public inline Node* CurrentNode() const
178         {
179             return currentNode;
180         }
181         public ParentPathSelector* GetParentPathSelector() const
182         {
183             return parentPathSelector;
184         }
185         public PathView* GetPathView() const
186         {
187             return pathView;
188         }
189         protected override Result<bool> OnPaint(PaintEventArgs& args)
190         {
191             if (emptyView != null)
192             {
193                 auto result = emptyView->Invalidate();
194                 if (result.Error()) return result;
195             }
196             if (pathDivider1 != null)
197             {
198                 auto result = pathDivider1->Invalidate();
199                 if (result.Error()) return result;
200             }
201             if (parentPathSelector != null)
202             {
203                 auto result = parentPathSelector->Invalidate();
204                 if (result.Error()) return result;
205             }
206             if (pathDivider2 != null)
207             {
208                 auto result = pathDivider2->Invalidate();
209                 if (result.Error()) return result;
210             }
211             if (pathView != null)
212             {
213                 auto result = pathView->Invalidate();
214                 if (result.Error()) return result;
215             }
216             return base->OnPaint(args);
217         }
218         protected override Result<bool> OnSizeChanged(SizeChangedEventArgs& args)
219         {
220             auto result = base->OnSizeChanged(args);
221             if (result.Error()) return result;
222             result = DockChildren();
223             if (result.Error()) return result;
224             return Result<bool>(true);
225         }
226         private EmptyView* emptyView;
227         private PathDivider* pathDivider1;
228         private ParentPathSelector* parentPathSelector;
229         private PathDivider* pathDivider2;
230         private PathView* pathView;
231         private Node* currentNode;
232     }
233 }