Mercurial > projects > dynamin
annotate dynamin/gui/container.d @ 55:c138461bf845
Add focusing and other changes that are related
like descendantAdded/Removed events, Window.activated event, and updating List.
Window.state was also added, even though focusing does not depend on it.
author | Jordan Miner <jminer7@gmail.com> |
---|---|
date | Sat, 08 Aug 2009 15:42:27 -0500 |
parents | ee9a564d2814 |
children | c2566ab82535 |
rev | line source |
---|---|
0 | 1 // Written in the D programming language |
2 // www.digitalmars.com/d/ | |
3 | |
4 /* | |
5 * The contents of this file are subject to the Mozilla Public License Version | |
6 * 1.1 (the "License"); you may not use this file except in compliance with | |
7 * the License. You may obtain a copy of the License at | |
8 * http://www.mozilla.org/MPL/ | |
9 * | |
10 * Software distributed under the License is distributed on an "AS IS" basis, | |
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License | |
12 * for the specific language governing rights and limitations under the | |
13 * License. | |
14 * | |
15 * The Original Code is the Dynamin library. | |
16 * | |
17 * The Initial Developer of the Original Code is Jordan Miner. | |
18 * Portions created by the Initial Developer are Copyright (C) 2006-2009 | |
19 * the Initial Developer. All Rights Reserved. | |
20 * | |
21 * Contributor(s): | |
22 * Jordan Miner <jminer7@gmail.com> | |
23 * | |
24 */ | |
25 | |
26 module dynamin.gui.container; | |
27 | |
28 import dynamin.all_core; | |
29 import dynamin.all_painting; | |
30 import dynamin.all_gui; | |
31 import dynamin.gui.control; | |
32 import dynamin.gui.events; | |
33 import tango.io.Stdout; | |
34 | |
55
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
35 alias List!(Control, true) ControlList; |
0 | 36 |
37 /// | |
38 class Container : Control { | |
39 protected: | |
40 ControlList _children; | |
41 Size _minSize; | |
42 Size _maxSize; | |
43 | |
44 override void whenResized(EventArgs e) { | |
45 layout(); | |
46 } | |
55
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
47 // If the specified array is large enough to hold the results, no heap |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
48 // allocation will be done. |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
49 Control[] getFocusableDescendants(Control[] des = null) { |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
50 uint cur = 0; |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
51 |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
52 void addDescendants(Container c) { |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
53 if(c._focusable) { // TODO: && c.enabled) { |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
54 if(cur == des.length) |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
55 des.length = des.length + 20; |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
56 des[cur++] = c; |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
57 } |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
58 foreach(ch; c._children) { |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
59 if(cast(Container)ch) |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
60 addDescendants(cast(Container)ch); |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
61 else if(ch.focusable) { // TODO: && ch.enabled) { |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
62 if(cur == des.length) |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
63 des.length = des.length + 20; |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
64 des[cur++] = ch; |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
65 } |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
66 } |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
67 } |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
68 addDescendants(this); |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
69 return des[0..cur]; |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
70 } |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
71 unittest { |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
72 class MyControl : Control { |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
73 this() { |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
74 _focusable = true; |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
75 } |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
76 } |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
77 auto container1 = new Container(); |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
78 auto container2 = new Container(); |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
79 auto container3 = new Container(); |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
80 auto container4 = new Container(); |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
81 container2._focusable = true; |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
82 container4._focusable = true; |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
83 auto ctrl1 = new MyControl(); |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
84 auto ctrl2 = new MyControl(); |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
85 auto ctrl3 = new MyControl(); |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
86 |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
87 container1.add(container2); |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
88 container1.add(container3); |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
89 container3.add(container4); |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
90 container2.add(ctrl1); |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
91 container4.add(ctrl2); |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
92 container4.add(ctrl3); |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
93 assert(container1.getFocusableDescendants() == |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
94 [cast(Control)container2, ctrl1, container4, ctrl2, ctrl3]); |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
95 Control[5] buf; |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
96 assert(container1.getFocusableDescendants(buf).ptr == buf.ptr); |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
97 } |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
98 |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
99 // not an event |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
100 void whenChildAdded(Control child, int) { |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
101 if(child.parent) |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
102 child.parent.remove(child); |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
103 child.parent = this; |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
104 repaint(); |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
105 |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
106 void callAdded(Control ctrl) { |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
107 scope e = new HierarchyEventArgs(ctrl); |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
108 descendantAdded(e); |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
109 |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
110 if(auto cntr = cast(Container)ctrl) { |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
111 foreach(c; cntr._children) |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
112 callAdded(c); |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
113 } |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
114 } |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
115 callAdded(child); |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
116 } |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
117 |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
118 // not an event |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
119 void whenChildRemoved(Control child, int) { |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
120 child.parent = null; |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
121 repaint(); |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
122 |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
123 scope e = new HierarchyEventArgs(child); |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
124 descendantRemoved(e); |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
125 } |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
126 |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
127 void dispatchDescendantAdded(HierarchyEventArgs e) { |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
128 descendantAdded.callHandlers(e); |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
129 descendantAdded.callMainHandler(e); |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
130 e.levels = e.levels + 1; |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
131 if(_parent) |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
132 _parent.descendantAdded(e); |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
133 } |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
134 void dispatchDescendantRemoved(HierarchyEventArgs e) { |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
135 descendantRemoved.callHandlers(e); |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
136 descendantRemoved.callMainHandler(e); |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
137 e.levels = e.levels + 1; |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
138 if(_parent) |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
139 _parent.descendantRemoved(e); |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
140 } |
0 | 141 public: |
142 /// Override this method in a subclass to handle the minSizeChanged event. | |
143 protected void whenMinSizeChanged(EventArgs e) { } | |
8
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
144 /// This event occurs after the control's minimum size has been changed. |
10
ccc108b25a0a
Convert to using a struct for events. Fix some comments too.
Jordan Miner <jminer7@gmail.com>
parents:
8
diff
changeset
|
145 Event!(whenMinSizeChanged) minSizeChanged; |
0 | 146 |
8
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
147 /// Override this method in a subclass to handle the maxSizeChanged event. |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
148 protected void whenMaxSizeChanged(EventArgs e) { } |
0 | 149 /// This event occurs after the control's maximum size has been changed. |
10
ccc108b25a0a
Convert to using a struct for events. Fix some comments too.
Jordan Miner <jminer7@gmail.com>
parents:
8
diff
changeset
|
150 Event!(whenMaxSizeChanged) maxSizeChanged; |
0 | 151 |
55
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
152 /// Override this method in a subclass to handle the descendantAdded event. |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
153 protected void whenDescendantAdded(HierarchyEventArgs e) { } |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
154 /// This event occurs after a control is added as a descendant of this container. |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
155 Event!(whenDescendantAdded) descendantAdded; |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
156 |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
157 /// Override this method in a subclass to handle the descendantRemoved event. |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
158 protected void whenDescendantRemoved(HierarchyEventArgs e) { } |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
159 /// This event occurs after a descendant of this container has been removed. |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
160 Event!(whenDescendantRemoved) descendantRemoved; |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
161 |
0 | 162 this() { |
10
ccc108b25a0a
Convert to using a struct for events. Fix some comments too.
Jordan Miner <jminer7@gmail.com>
parents:
8
diff
changeset
|
163 minSizeChanged.mainHandler = &whenMinSizeChanged; |
ccc108b25a0a
Convert to using a struct for events. Fix some comments too.
Jordan Miner <jminer7@gmail.com>
parents:
8
diff
changeset
|
164 maxSizeChanged.mainHandler = &whenMaxSizeChanged; |
55
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
165 descendantAdded.mainHandler = &whenDescendantAdded; |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
166 descendantAdded.dispatcher = &dispatchDescendantAdded; |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
167 descendantRemoved.mainHandler = &whenDescendantRemoved; |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
168 descendantRemoved.dispatcher = &dispatchDescendantRemoved; |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
169 |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
170 _children = new ControlList(&whenChildAdded, &whenChildRemoved); |
0 | 171 |
172 elasticX = true; | |
173 elasticY = true; | |
174 } | |
175 override void dispatchPainting(PaintingEventArgs e) { | |
176 super.dispatchPainting(e); | |
177 foreach(c; _children) { | |
178 e.graphics.save(); | |
179 e.graphics.translate(c.x, c.y); | |
180 c.setupGraphics(e.graphics); | |
181 c.painting(e); | |
182 e.graphics.restore(); | |
183 } | |
184 } | |
185 // TODO: make these use common code...get rid of copy and paste | |
186 override void dispatchMouseDown(MouseEventArgs e) { | |
187 auto c = getChildAtPoint(e.location); | |
188 if(c && getCaptorControl() !is this) { | |
189 e.location = e.location - c.location; | |
190 c.mouseDown(e); | |
191 e.location = e.location + c.location; | |
192 } else { | |
193 super.dispatchMouseDown(e); | |
194 } | |
195 } | |
196 override void dispatchMouseUp(MouseEventArgs e) { | |
197 auto c = getChildAtPoint(e.location); | |
198 if(c && getCaptorControl() !is this) { | |
199 e.location = e.location - c.location; | |
200 c.mouseUp(e); | |
201 e.location = e.location + c.location; | |
202 } else { | |
203 super.dispatchMouseUp(e); | |
204 } | |
205 } | |
206 override void dispatchMouseMoved(MouseEventArgs e) { | |
207 auto c = getChildAtPoint(e.location); | |
208 if(c && getCaptorControl() !is this) { | |
209 e.location = e.location - c.location; | |
210 c.mouseMoved(e); | |
211 e.location = e.location + c.location; | |
212 } else { | |
213 super.dispatchMouseMoved(e); | |
214 } | |
215 } | |
216 override void dispatchMouseDragged(MouseEventArgs e) { | |
217 auto c = getChildAtPoint(e.location); | |
218 if(c && getCaptorControl() !is this) { | |
219 e.location = e.location - c.location; | |
220 c.mouseDragged(e); | |
221 e.location = e.location + c.location; | |
222 } else { | |
223 super.dispatchMouseDragged(e); | |
224 } | |
225 } | |
5
4029d5af7542
Add blank lines and rewrap some comments.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
226 |
0 | 227 /** |
228 * Gets the child control at the specified point. If there are | |
229 * multiple child controls at the point, the topmost control is returned. | |
230 * If there is no child control at the point, null is returned. The returned | |
231 * control, if any, is a direct child of this container. | |
232 */ | |
233 Control getChildAtPoint(real[] pt) { | |
234 assert(pt.length == 2, "pt must be just an x and y"); | |
235 return getChildAtPoint(Point(pt[0], pt[1])); | |
236 } | |
237 /// ditto | |
238 Control getChildAtPoint(real x, real y) { | |
239 return getChildAtPoint(Point(x, y)); | |
240 } | |
241 /// ditto | |
242 Control getChildAtPoint(Point pt) { | |
243 for(int i = _children.count-1; i >= 0; --i) { | |
244 pt = pt - _children[i].location; | |
245 scope(exit) pt = pt + _children[i].location; | |
246 if(_children[i].contains(pt)) | |
247 return _children[i]; | |
248 } | |
249 return null; | |
250 } | |
5
4029d5af7542
Add blank lines and rewrap some comments.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
251 |
0 | 252 /** |
253 * Never returns null. If there is no descendant at the specified point, | |
254 * this container will be returned. | |
255 */ | |
256 Control getDescendantAtPoint(real[] pt) { | |
257 assert(pt.length == 2, "pt must be just an x and y"); | |
258 return getDescendantAtPoint(Point(pt[0], pt[1])); | |
259 } | |
260 /// ditto | |
261 Control getDescendantAtPoint(real x, real y) { | |
262 return getDescendantAtPoint(Point(x, y)); | |
263 } | |
264 /// ditto | |
265 Control getDescendantAtPoint(Point pt) { | |
266 Container des = this; | |
267 while(true) { | |
268 auto child = des.getChildAtPoint(pt); | |
269 if(!child) | |
270 return des; | |
271 auto isContainer = cast(Container)child; | |
272 if(isContainer) { | |
273 des = isContainer; | |
274 pt = pt - des.location; | |
275 // loop around with this container | |
276 } else { | |
277 return child; | |
278 } | |
279 } | |
280 } | |
5
4029d5af7542
Add blank lines and rewrap some comments.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
281 |
0 | 282 /** |
283 * Gets or sets the minimum size of this window. A minimum width or | |
284 * height of 0 means that there is no minimum width or height. | |
285 * The default is Size(0, 0). | |
286 */ | |
287 Size minSize() { return _minSize; } | |
288 /// ditto | |
289 void minSize(Size size) { | |
290 _minSize = size; | |
291 minSizeChanged(new EventArgs); | |
292 } | |
293 /// ditto | |
294 void minSize(real[] size) { | |
295 assert(size.length == 2, "size must be just a width and height"); | |
296 minSize = Size(size[0], size[1]); | |
297 } | |
298 /// | |
299 real minWidth() { return _minSize.width; } | |
300 /// | |
301 real minHeight() { return _minSize.height; } | |
5
4029d5af7542
Add blank lines and rewrap some comments.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
302 |
0 | 303 /** |
304 * Gets or sets the maximum size of this window. A maximum width or | |
305 * height of 0 means that there is no maximum width or height. | |
306 * The default is Size(0, 0). | |
307 */ | |
308 Size maxSize() { return _maxSize; } | |
309 /// ditto | |
310 void maxSize(Size size) { | |
311 _maxSize = size; | |
312 minSizeChanged(new EventArgs); | |
313 } | |
314 /// ditto | |
315 void maxSize(real[] size) { | |
316 assert(size.length == 2, "size must be just a width and height"); | |
317 maxSize = Size(size[0], size[1]); | |
318 } | |
319 /// | |
320 real maxWidth() { return _maxSize.width; } | |
321 /// | |
322 real maxHeight() { return _maxSize.height; } | |
5
4029d5af7542
Add blank lines and rewrap some comments.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
323 |
0 | 324 /** |
325 * Causes this container to position its child controls. Called on every | |
326 * resize. Usually, this function will get each child's best size, and | |
327 * then set each child's location and height. The definition in Container | |
328 * is empty, as it is intended for subclasses to override. | |
329 */ | |
330 void layout() { | |
331 } | |
5
4029d5af7542
Add blank lines and rewrap some comments.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
332 |
0 | 333 protected void add(Control child) { |
334 _children.add(child); | |
335 } | |
5
4029d5af7542
Add blank lines and rewrap some comments.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
336 |
0 | 337 protected void remove(Control child) { |
338 _children.remove(child); | |
339 } | |
5
4029d5af7542
Add blank lines and rewrap some comments.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
340 |
35
ee9a564d2814
Allow more use of Containers versus Panels.
Jordan Miner <jminer7@gmail.com>
parents:
10
diff
changeset
|
341 int opApply(int delegate(inout Control item) dg) { |
0 | 342 for(uint i = 0; i < _children.count; ++i) { |
343 auto tmp = _children[i]; | |
344 if(int result = dg(tmp)) | |
345 return result; | |
346 } | |
347 return 0; | |
348 } | |
35
ee9a564d2814
Allow more use of Containers versus Panels.
Jordan Miner <jminer7@gmail.com>
parents:
10
diff
changeset
|
349 int opApply(int delegate(inout uint index, inout Control item) dg) { |
0 | 350 for(uint i = 0; i < _children.count; ++i) { |
351 auto tmp = _children[i]; | |
352 if(int result = dg(i, tmp)) | |
353 return result; | |
354 } | |
355 return 0; | |
356 } | |
357 } | |
55
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
358 unittest { |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
359 auto i = 0; |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
360 auto container = new Panel; |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
361 container.descendantAdded += (HierarchyEventArgs e) { i++; }; |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
362 auto sub = new Panel; |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
363 sub.add(new Control); |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
364 container.add(sub); |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
365 assert(i == 2); |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
366 } |
0 | 367 |
368 // TODO: calling panel.children.add(button) will cause a crash | |
369 // because the button's parent is not set to the panel | |
370 // need to add a change handler on children? | |
371 class Panel : Container { | |
372 ControlList children() { return _children; } | |
373 void add(Control child) { super.add(child); }; | |
374 void remove(Control child) { super.remove(child); }; | |
375 int opApply(int delegate(inout Control item) dg) { | |
376 return super.opApply(dg); | |
377 } | |
378 int opApply(int delegate(inout uint index, inout Control item) dg) { | |
379 return super.opApply(dg); | |
380 } | |
381 // override protected void whenPainting() { | |
382 // } | |
383 } | |
384 |