1 #include "CtrlCore.h"
2
3 namespace Upp {
4
5 #define LLOG(x) // DLOG(x)
6
IsDHCtrl() const7 bool Ctrl::IsDHCtrl() const {
8 return dynamic_cast<const DHCtrl *>(this);
9 }
10
AddChild(Ctrl * q,Ctrl * p)11 void Ctrl::AddChild(Ctrl *q, Ctrl *p)
12 {
13 GuiLock __;
14 ASSERT(q);
15 LLOG("Add " << UPP::Name(q) << " to: " << Name());
16 if(p == q) return;
17 bool updaterect = true;
18 if(q->parent) {
19 ASSERT(!q->inframe);
20 if(q->parent == this) {
21 RemoveChild0(q);
22 updaterect = false;
23 }
24 else
25 q->parent->RemoveChild(q);
26 }
27 q->parent = this;
28 if(p) {
29 ASSERT(p->parent == this);
30 q->prev = p;
31 q->next = p->next;
32 if(p == lastchild)
33 lastchild = q;
34 else
35 p->next->prev = q;
36 p->next = q;
37 }
38 else
39 if(firstchild) {
40 q->prev = NULL;
41 q->next = firstchild;
42 firstchild->prev = q;
43 firstchild = q;
44 }
45 else {
46 ASSERT(lastchild == NULL);
47 firstchild = lastchild = q;
48 q->prev = q->next = NULL;
49 }
50 q->CancelModeDeep();
51 if(updaterect)
52 q->UpdateRect();
53 ChildAdded(q);
54 q->ParentChange();
55 if(updaterect && GetTopCtrl()->IsOpen())
56 q->StateH(OPEN);
57 }
58
AddChild(Ctrl * child)59 void Ctrl::AddChild(Ctrl *child)
60 {
61 AddChild(child, lastchild);
62 }
63
AddChildBefore(Ctrl * child,Ctrl * insbefore)64 void Ctrl::AddChildBefore(Ctrl *child, Ctrl *insbefore)
65 {
66 if(insbefore)
67 AddChild(child, insbefore->prev);
68 else
69 AddChild(child);
70 }
71
RemoveChild0(Ctrl * q)72 void Ctrl::RemoveChild0(Ctrl *q)
73 {
74 GuiLock __;
75 ChildRemoved(q);
76 q->DoRemove();
77 q->parent = NULL;
78 if(q == firstchild)
79 firstchild = firstchild->next;
80 if(q == lastchild)
81 lastchild = lastchild->prev;
82 if(q->prev)
83 q->prev->next = q->next;
84 if(q->next)
85 q->next->prev = q->prev;
86 q->next = q->prev = NULL;
87 }
88
RemoveChild(Ctrl * q)89 void Ctrl::RemoveChild(Ctrl *q)
90 {
91 GuiLock __;
92 if(q->parent != this) return;
93 q->RefreshFrame();
94 RemoveChild0(q);
95 q->ParentChange();
96 if(GetTopCtrl()->IsOpen())
97 q->StateH(CLOSE);
98 }
99
Remove()100 void Ctrl::Remove()
101 {
102 GuiLock __;
103 if(parent)
104 parent->RemoveChild(this);
105 }
106
GetChildIndex(const Ctrl * child) const107 int Ctrl::GetChildIndex(const Ctrl *child) const
108 {
109 GuiLock __;
110 int i = 0;
111 for (Ctrl *c = GetFirstChild(); c; c = c->GetNext()) {
112 if(c == child) return i;
113 i++;
114 }
115 return -1;
116 }
117
GetChildCount() const118 int Ctrl::GetChildCount() const
119 {
120 GuiLock __;
121 int n = 0;
122 for (Ctrl *c = GetFirstChild(); c; c = c->GetNext())
123 n++;
124 return n;
125 }
126
GetIndexChild(int ii) const127 Ctrl * Ctrl::GetIndexChild(int ii) const
128 {
129 GuiLock __;
130 Ctrl *c = GetFirstChild();
131 for(int i = 0; i < ii && c; i++)
132 c = c->GetNext();
133 return c;
134 }
135
GetViewChildIndex(const Ctrl * child) const136 int Ctrl::GetViewChildIndex(const Ctrl *child) const
137 {
138 GuiLock __;
139 int i = 0;
140 for (Ctrl *c = GetFirstChild(); c; c = c->GetNext())
141 if(!c->InFrame()) {
142 if(c == child) return i;
143 i++;
144 }
145 return -1;
146 }
147
GetViewChildCount() const148 int Ctrl::GetViewChildCount() const
149 {
150 GuiLock __;
151 int n = 0;
152 for (Ctrl *c = GetFirstChild(); c; c = c->GetNext())
153 if(!c->InFrame())
154 n++;
155 return n;
156 }
157
GetViewIndexChild(int ii) const158 Ctrl * Ctrl::GetViewIndexChild(int ii) const
159 {
160 GuiLock __;
161 int i = 0;
162 for (Ctrl *c = GetFirstChild(); c; c = c->GetNext())
163 if(!c->InFrame()) {
164 if(i == ii)
165 return c;
166 i++;
167 }
168 return NULL;
169 }
170
HasChild(Ctrl * q) const171 bool Ctrl::HasChild(Ctrl *q) const
172 {
173 GuiLock __;
174 return q && q->IsChild() && q->parent == this;
175 }
176
HasChildDeep(Ctrl * q) const177 bool Ctrl::HasChildDeep(Ctrl *q) const
178 {
179 GuiLock __;
180 while(q && q->IsChild()) {
181 if(q->parent == this) return true;
182 q = q->parent;
183 }
184 return false;
185 }
186
IterateFocusFw(Ctrl * ctrl,bool noframe,bool init,bool all)187 static bool IterateFocusFw(Ctrl *ctrl, bool noframe, bool init, bool all)
188 {
189 LLOG("IterateFocusFw(" << UPP::Name(ctrl) << ")");
190 while(ctrl) {
191 if(ctrl->IsOpen() && ctrl->IsVisible() && ctrl->IsEnabled()) {
192 if(!(noframe && ctrl->InFrame())) {
193 if(all) {
194 ctrl->SetFocus();
195 return true;
196 }
197 if((!init || ctrl->IsInitFocus()) && ctrl->SetWantFocus())
198 return true;
199 }
200 if(IterateFocusFw(ctrl->GetFirstChild(), noframe, init, all))
201 return true;
202 }
203 ctrl = ctrl->GetNext();
204 }
205 return false;
206 }
207
IterateFocusForward(Ctrl * ctrl,Ctrl * top,bool noframe,bool init,bool all)208 bool Ctrl::IterateFocusForward(Ctrl *ctrl, Ctrl *top, bool noframe, bool init, bool all)
209 {
210 GuiLock __;
211 LLOG("IterateFocusForward(" << UPP::Name(ctrl) << ", top " << UPP::Name(top) << ", noframe " << noframe << ", init " << init << ")");
212 if(!ctrl) return false;
213 if(IterateFocusFw(ctrl->GetFirstChild(), noframe, init, all))
214 return true;
215 if(ctrl->GetNext() && IterateFocusFw(ctrl->GetNext(), noframe, init, all))
216 return true;
217 while(ctrl->GetParent() != top && (ctrl = ctrl->GetParent()) != NULL)
218 if(IterateFocusFw(ctrl->GetNext(), noframe, init, all))
219 return true;
220 return false;
221 }
222
IterateFocusBw(Ctrl * ctrl,bool noframe,bool all)223 static bool IterateFocusBw(Ctrl *ctrl, bool noframe, bool all)
224 {
225 while(ctrl) {
226 if(ctrl->IsOpen() && ctrl->IsVisible() && ctrl->IsEnabled()) {
227 if(IterateFocusBw(ctrl->GetLastChild(), noframe, all))
228 return true;
229 if(!(noframe && ctrl->InFrame())) {
230 if(all) {
231 ctrl->SetFocus();
232 return true;
233 }
234 if(ctrl->SetWantFocus())
235 return true;
236 }
237 }
238 ctrl = ctrl->GetPrev();
239 }
240 return false;
241 }
242
IterateFocusBackward(Ctrl * ctrl,Ctrl * top,bool noframe,bool all)243 bool Ctrl::IterateFocusBackward(Ctrl *ctrl, Ctrl *top, bool noframe, bool all)
244 {
245 GuiLock __;
246 if(!ctrl || ctrl == top) return false;
247 if(IterateFocusBw(ctrl->GetPrev(), noframe, all))
248 return true;
249 while(ctrl->GetParent() != top) {
250 ctrl = ctrl->GetParent();
251 if(ctrl->SetWantFocus())
252 return true;
253 if(IterateFocusBw(ctrl->GetPrev(), noframe, all))
254 return true;
255 }
256 return false;
257 }
258
GetTopCtrl()259 Ctrl *Ctrl::GetTopCtrl()
260 {
261 GuiLock __;
262 Ctrl *q = this;
263 while(q->parent)
264 q = q->parent;
265 return q;
266 }
267
GetTopCtrl() const268 const Ctrl *Ctrl::GetTopCtrl() const { return const_cast<Ctrl *>(this)->GetTopCtrl(); }
GetOwner() const269 const Ctrl *Ctrl::GetOwner() const { return const_cast<Ctrl *>(this)->GetOwner(); }
GetTopCtrlOwner()270 Ctrl *Ctrl::GetTopCtrlOwner() { return GetTopCtrl()->GetOwner(); }
GetTopCtrlOwner() const271 const Ctrl *Ctrl::GetTopCtrlOwner() const { return GetTopCtrl()->GetOwner(); }
272
GetOwnerCtrl()273 Ctrl *Ctrl::GetOwnerCtrl() { GuiLock __; return !IsChild() && top ? top->owner : NULL; }
GetOwnerCtrl() const274 const Ctrl *Ctrl::GetOwnerCtrl() const { return const_cast<Ctrl *>(this)->GetOwnerCtrl(); }
275
GetTopWindow()276 TopWindow *Ctrl::GetTopWindow()
277 {
278 GuiLock __;
279 Ctrl *q = this;
280 while(q) {
281 q = q->GetTopCtrl();
282 TopWindow *w = dynamic_cast<TopWindow *>(q);
283 if(w) return w;
284 q = q->GetOwner();
285 }
286 return NULL;
287 }
288
GetTopWindow() const289 const TopWindow *Ctrl::GetTopWindow() const
290 {
291 return const_cast<Ctrl *>(this)->GetTopWindow();
292 }
293
GetMainWindow()294 TopWindow *Ctrl::GetMainWindow()
295 {
296 GuiLock __;
297 Ctrl *q = GetTopCtrl();
298 for(;;) {
299 Ctrl *w = q->GetOwner();
300 if(!w)
301 return dynamic_cast<TopWindow *>(q);
302 q = w;
303 }
304 }
305
GetMainWindow() const306 const TopWindow *Ctrl::GetMainWindow() const
307 {
308 return const_cast<Ctrl *>(this)->GetMainWindow();
309 }
310
311 }
312