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(204u, 206u, 219u);
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.h, pvSize.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.h, pvSize.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 }