-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDockPanel.cpp
More file actions
131 lines (114 loc) · 3.38 KB
/
Copy pathDockPanel.cpp
File metadata and controls
131 lines (114 loc) · 3.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include "DockPanel.h"
namespace FD2D
{
DockPanel::DockPanel()
: Panel()
{
}
DockPanel::DockPanel(const std::wstring& name)
: Panel(name)
{
}
void DockPanel::SetChildDock(const std::shared_ptr<Wnd>& child, Dock dock)
{
if (!child)
{
return;
}
m_docks[child.get()] = dock;
m_order.push_back(child);
}
void DockPanel::ClearDocks()
{
m_order.clear();
m_docks.clear();
ClearChildren();
}
Size DockPanel::Measure(Size available)
{
// Measure children with remaining space; conservative return = available.
Size remaining = available;
for (auto& child : m_order)
{
if (!child)
{
continue;
}
Dock dock = Dock::Fill;
auto it = m_docks.find(child.get());
if (it != m_docks.end())
{
dock = it->second;
}
Size childAvail = remaining;
child->Measure(childAvail);
// For Auto measure we'd shrink remaining, but we just measure and keep available as-is.
}
m_desired = available;
return m_desired;
}
void DockPanel::Arrange(Rect finalRect)
{
Rect rect = finalRect;
for (auto& child : m_order)
{
if (!child)
{
continue;
}
Dock dock = Dock::Fill;
auto it = m_docks.find(child.get());
if (it != m_docks.end())
{
dock = it->second;
}
switch (dock)
{
case Dock::Left:
{
Size desired = child->Measure({ rect.w, rect.h });
Rect childRect { rect.x, rect.y, desired.w, rect.h };
child->Arrange(childRect);
rect.x += desired.w;
rect.w = (std::max)(0.0f, rect.w - desired.w);
break;
}
case Dock::Right:
{
Size desired = child->Measure({ rect.w, rect.h });
Rect childRect { rect.x + rect.w - desired.w, rect.y, desired.w, rect.h };
child->Arrange(childRect);
rect.w = (std::max)(0.0f, rect.w - desired.w);
break;
}
case Dock::Top:
{
Size desired = child->Measure({ rect.w, rect.h });
Rect childRect { rect.x, rect.y, rect.w, desired.h };
child->Arrange(childRect);
rect.y += desired.h;
rect.h = (std::max)(0.0f, rect.h - desired.h);
break;
}
case Dock::Bottom:
{
Size desired = child->Measure({ rect.w, rect.h });
Rect childRect { rect.x, rect.y + rect.h - desired.h, rect.w, desired.h };
child->Arrange(childRect);
rect.h = (std::max)(0.0f, rect.h - desired.h);
break;
}
case Dock::Fill:
default:
{
child->Arrange(rect);
// After fill we stop docking subsequent children.
rect = { 0, 0, 0, 0 };
break;
}
}
}
m_bounds = finalRect;
m_layoutRect = ToD2D(finalRect);
}
}