Mercurial > projects > dynamin
annotate dynamin/gui/container.d @ 104:5c8c1c2e12c0
Change from real to double.
double is not dependant on the platform, and it uses less space.
author | Jordan Miner <jminer7@gmail.com> |
---|---|
date | Fri, 06 Jul 2012 18:39:45 -0500 |
parents | 73060bc3f004 |
children | acdbb30fee7e |
rev | line source |
---|---|
0 | 1 |
2 /* | |
103
73060bc3f004
Change license to Boost 1.0 and MPL 2.0.
Jordan Miner <jminer7@gmail.com>
parents:
83
diff
changeset
|
3 * Copyright Jordan Miner |
0 | 4 * |
103
73060bc3f004
Change license to Boost 1.0 and MPL 2.0.
Jordan Miner <jminer7@gmail.com>
parents:
83
diff
changeset
|
5 * This Source Code Form is subject to the terms of the Mozilla Public |
73060bc3f004
Change license to Boost 1.0 and MPL 2.0.
Jordan Miner <jminer7@gmail.com>
parents:
83
diff
changeset
|
6 * License, v. 2.0. If a copy of the MPL was not distributed with this |
73060bc3f004
Change license to Boost 1.0 and MPL 2.0.
Jordan Miner <jminer7@gmail.com>
parents:
83
diff
changeset
|
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
0 | 8 * |
9 */ | |
10 | |
11 module dynamin.gui.container; | |
12 | |
13 import dynamin.all_core; | |
14 import dynamin.all_painting; | |
15 import dynamin.all_gui; | |
16 import dynamin.gui.control; | |
17 import dynamin.gui.events; | |
62 | 18 import dynamin.gui.button; |
0 | 19 import tango.io.Stdout; |
20 | |
55
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
21 alias List!(Control, true) ControlList; |
0 | 22 |
23 /// | |
24 class Container : Control { | |
25 protected: | |
26 ControlList _children; | |
27 Size _minSize; | |
28 Size _maxSize; | |
62 | 29 Button _defaultButton; |
0 | 30 |
31 override void whenResized(EventArgs e) { | |
32 layout(); | |
33 } | |
55
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
34 // 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
|
35 // allocation will be done. |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
36 Control[] getFocusableDescendants(Control[] des = null) { |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
37 uint cur = 0; |
70
340c3777ea68
Use Container.descendantsPlus in getFocusableDescendants for shorter code.
Jordan Miner <jminer7@gmail.com>
parents:
68
diff
changeset
|
38 foreach(d; &descendantsPlus) { |
340c3777ea68
Use Container.descendantsPlus in getFocusableDescendants for shorter code.
Jordan Miner <jminer7@gmail.com>
parents:
68
diff
changeset
|
39 if(d.focusable) { // TODO: && ch.enabled) { |
55
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
40 if(cur == des.length) |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
41 des.length = des.length + 20; |
70
340c3777ea68
Use Container.descendantsPlus in getFocusableDescendants for shorter code.
Jordan Miner <jminer7@gmail.com>
parents:
68
diff
changeset
|
42 des[cur++] = d; |
55
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
43 } |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
44 } |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
45 return des[0..cur]; |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
46 } |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
47 unittest { |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
48 class MyControl : Control { |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
49 this() { |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
50 _focusable = true; |
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 } |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
53 auto container1 = new Container(); |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
54 auto container2 = new Container(); |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
55 auto container3 = new Container(); |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
56 auto container4 = new Container(); |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
57 container2._focusable = true; |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
58 container4._focusable = true; |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
59 auto ctrl1 = new MyControl(); |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
60 auto ctrl2 = new MyControl(); |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
61 auto ctrl3 = new MyControl(); |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
62 |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
63 container1.add(container2); |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
64 container1.add(container3); |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
65 container3.add(container4); |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
66 container2.add(ctrl1); |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
67 container4.add(ctrl2); |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
68 container4.add(ctrl3); |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
69 assert(container1.getFocusableDescendants() == |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
70 [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
|
71 Control[5] buf; |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
72 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
|
73 } |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
74 |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
75 // not an event |
83
3cfc83a99cbc
Add List.opIndexAssign and switch to one callback for change notification.
Jordan Miner <jminer7@gmail.com>
parents:
78
diff
changeset
|
76 void whenChildrenChanged(ListChangeType, Control oldChild, Control newChild, uint) { |
3cfc83a99cbc
Add List.opIndexAssign and switch to one callback for change notification.
Jordan Miner <jminer7@gmail.com>
parents:
78
diff
changeset
|
77 if(oldChild) { |
3cfc83a99cbc
Add List.opIndexAssign and switch to one callback for change notification.
Jordan Miner <jminer7@gmail.com>
parents:
78
diff
changeset
|
78 oldChild.parent = null; |
3cfc83a99cbc
Add List.opIndexAssign and switch to one callback for change notification.
Jordan Miner <jminer7@gmail.com>
parents:
78
diff
changeset
|
79 repaint(); |
55
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
80 |
83
3cfc83a99cbc
Add List.opIndexAssign and switch to one callback for change notification.
Jordan Miner <jminer7@gmail.com>
parents:
78
diff
changeset
|
81 scope e = new HierarchyEventArgs(oldChild); |
3cfc83a99cbc
Add List.opIndexAssign and switch to one callback for change notification.
Jordan Miner <jminer7@gmail.com>
parents:
78
diff
changeset
|
82 descendantRemoved(e); |
3cfc83a99cbc
Add List.opIndexAssign and switch to one callback for change notification.
Jordan Miner <jminer7@gmail.com>
parents:
78
diff
changeset
|
83 } |
55
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
84 |
83
3cfc83a99cbc
Add List.opIndexAssign and switch to one callback for change notification.
Jordan Miner <jminer7@gmail.com>
parents:
78
diff
changeset
|
85 if(newChild) { |
3cfc83a99cbc
Add List.opIndexAssign and switch to one callback for change notification.
Jordan Miner <jminer7@gmail.com>
parents:
78
diff
changeset
|
86 if(newChild.parent) |
3cfc83a99cbc
Add List.opIndexAssign and switch to one callback for change notification.
Jordan Miner <jminer7@gmail.com>
parents:
78
diff
changeset
|
87 newChild.parent.remove(newChild); |
3cfc83a99cbc
Add List.opIndexAssign and switch to one callback for change notification.
Jordan Miner <jminer7@gmail.com>
parents:
78
diff
changeset
|
88 newChild.parent = this; |
3cfc83a99cbc
Add List.opIndexAssign and switch to one callback for change notification.
Jordan Miner <jminer7@gmail.com>
parents:
78
diff
changeset
|
89 repaint(); |
55
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
90 |
83
3cfc83a99cbc
Add List.opIndexAssign and switch to one callback for change notification.
Jordan Miner <jminer7@gmail.com>
parents:
78
diff
changeset
|
91 void callAdded(Control ctrl) { |
3cfc83a99cbc
Add List.opIndexAssign and switch to one callback for change notification.
Jordan Miner <jminer7@gmail.com>
parents:
78
diff
changeset
|
92 scope e = new HierarchyEventArgs(ctrl); |
3cfc83a99cbc
Add List.opIndexAssign and switch to one callback for change notification.
Jordan Miner <jminer7@gmail.com>
parents:
78
diff
changeset
|
93 descendantAdded(e); |
55
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
94 |
83
3cfc83a99cbc
Add List.opIndexAssign and switch to one callback for change notification.
Jordan Miner <jminer7@gmail.com>
parents:
78
diff
changeset
|
95 if(auto cntr = cast(Container)ctrl) { |
3cfc83a99cbc
Add List.opIndexAssign and switch to one callback for change notification.
Jordan Miner <jminer7@gmail.com>
parents:
78
diff
changeset
|
96 foreach(c; cntr._children) |
3cfc83a99cbc
Add List.opIndexAssign and switch to one callback for change notification.
Jordan Miner <jminer7@gmail.com>
parents:
78
diff
changeset
|
97 callAdded(c); |
3cfc83a99cbc
Add List.opIndexAssign and switch to one callback for change notification.
Jordan Miner <jminer7@gmail.com>
parents:
78
diff
changeset
|
98 } |
3cfc83a99cbc
Add List.opIndexAssign and switch to one callback for change notification.
Jordan Miner <jminer7@gmail.com>
parents:
78
diff
changeset
|
99 } |
3cfc83a99cbc
Add List.opIndexAssign and switch to one callback for change notification.
Jordan Miner <jminer7@gmail.com>
parents:
78
diff
changeset
|
100 callAdded(newChild); |
3cfc83a99cbc
Add List.opIndexAssign and switch to one callback for change notification.
Jordan Miner <jminer7@gmail.com>
parents:
78
diff
changeset
|
101 } |
3cfc83a99cbc
Add List.opIndexAssign and switch to one callback for change notification.
Jordan Miner <jminer7@gmail.com>
parents:
78
diff
changeset
|
102 |
55
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
103 } |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
104 |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
105 void dispatchDescendantAdded(HierarchyEventArgs e) { |
62 | 106 if(e.descendant is defaultButton) |
107 (cast(Button)e.descendant)._isDefault = true; | |
108 | |
55
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
109 descendantAdded.callHandlers(e); |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
110 descendantAdded.callMainHandler(e); |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
111 e.levels = e.levels + 1; |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
112 if(_parent) |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
113 _parent.descendantAdded(e); |
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 void dispatchDescendantRemoved(HierarchyEventArgs e) { |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
116 descendantRemoved.callHandlers(e); |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
117 descendantRemoved.callMainHandler(e); |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
118 e.levels = e.levels + 1; |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
119 if(_parent) |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
120 _parent.descendantRemoved(e); |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
121 } |
62 | 122 |
123 override void whenKeyDown(KeyEventArgs e) { | |
124 if(e.key == Key.Enter && defaultButton) { | |
125 scope e2 = new EventArgs; | |
126 defaultButton.clicked(e2); | |
127 e.stopped = true; | |
128 } | |
129 } | |
130 | |
0 | 131 public: |
132 /// Override this method in a subclass to handle the minSizeChanged event. | |
133 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
|
134 /// 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
|
135 Event!(whenMinSizeChanged) minSizeChanged; |
0 | 136 |
8
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
137 /// 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
|
138 protected void whenMaxSizeChanged(EventArgs e) { } |
0 | 139 /// 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
|
140 Event!(whenMaxSizeChanged) maxSizeChanged; |
0 | 141 |
55
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
142 /// 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
|
143 protected void whenDescendantAdded(HierarchyEventArgs e) { } |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
144 /// 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
|
145 Event!(whenDescendantAdded) descendantAdded; |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
146 |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
147 /// 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
|
148 protected void whenDescendantRemoved(HierarchyEventArgs e) { } |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
149 /// 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
|
150 Event!(whenDescendantRemoved) descendantRemoved; |
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
151 |
0 | 152 this() { |
78
651082a9b364
Add Event.setUp() and use in place of mainHandler and dispatcher.
Jordan Miner <jminer7@gmail.com>
parents:
70
diff
changeset
|
153 minSizeChanged .setUp(&whenMinSizeChanged); |
651082a9b364
Add Event.setUp() and use in place of mainHandler and dispatcher.
Jordan Miner <jminer7@gmail.com>
parents:
70
diff
changeset
|
154 maxSizeChanged .setUp(&whenMaxSizeChanged); |
651082a9b364
Add Event.setUp() and use in place of mainHandler and dispatcher.
Jordan Miner <jminer7@gmail.com>
parents:
70
diff
changeset
|
155 descendantAdded .setUp(&whenDescendantAdded, &dispatchDescendantAdded); |
651082a9b364
Add Event.setUp() and use in place of mainHandler and dispatcher.
Jordan Miner <jminer7@gmail.com>
parents:
70
diff
changeset
|
156 descendantRemoved.setUp(&whenDescendantRemoved, |
651082a9b364
Add Event.setUp() and use in place of mainHandler and dispatcher.
Jordan Miner <jminer7@gmail.com>
parents:
70
diff
changeset
|
157 &dispatchDescendantRemoved); |
55
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
158 |
83
3cfc83a99cbc
Add List.opIndexAssign and switch to one callback for change notification.
Jordan Miner <jminer7@gmail.com>
parents:
78
diff
changeset
|
159 _children = new ControlList(&whenChildrenChanged); |
0 | 160 |
161 elasticX = true; | |
162 elasticY = true; | |
163 } | |
62 | 164 |
165 /** | |
166 * Gets or sets the default button in this container. | |
167 */ | |
168 Button defaultButton() { return _defaultButton; } | |
169 /// ditto | |
170 void defaultButton(Button b) { | |
171 _defaultButton = b; | |
172 foreach(d; &descendants) { | |
173 if(b == d) | |
174 b._isDefault = true; | |
175 } | |
176 } | |
177 | |
0 | 178 override void dispatchPainting(PaintingEventArgs e) { |
179 super.dispatchPainting(e); | |
180 foreach(c; _children) { | |
181 e.graphics.save(); | |
182 e.graphics.translate(c.x, c.y); | |
183 c.setupGraphics(e.graphics); | |
184 c.painting(e); | |
185 e.graphics.restore(); | |
186 } | |
187 } | |
188 // TODO: make these use common code...get rid of copy and paste | |
189 override void dispatchMouseDown(MouseEventArgs e) { | |
190 auto c = getChildAtPoint(e.location); | |
191 if(c && getCaptorControl() !is this) { | |
192 e.location = e.location - c.location; | |
193 c.mouseDown(e); | |
194 e.location = e.location + c.location; | |
195 } else { | |
196 super.dispatchMouseDown(e); | |
197 } | |
198 } | |
199 override void dispatchMouseUp(MouseEventArgs e) { | |
200 auto c = getChildAtPoint(e.location); | |
201 if(c && getCaptorControl() !is this) { | |
202 e.location = e.location - c.location; | |
203 c.mouseUp(e); | |
204 e.location = e.location + c.location; | |
205 } else { | |
206 super.dispatchMouseUp(e); | |
207 } | |
208 } | |
209 override void dispatchMouseMoved(MouseEventArgs e) { | |
210 auto c = getChildAtPoint(e.location); | |
211 if(c && getCaptorControl() !is this) { | |
212 e.location = e.location - c.location; | |
213 c.mouseMoved(e); | |
214 e.location = e.location + c.location; | |
215 } else { | |
216 super.dispatchMouseMoved(e); | |
217 } | |
218 } | |
219 override void dispatchMouseDragged(MouseEventArgs e) { | |
220 auto c = getChildAtPoint(e.location); | |
221 if(c && getCaptorControl() !is this) { | |
222 e.location = e.location - c.location; | |
223 c.mouseDragged(e); | |
224 e.location = e.location + c.location; | |
225 } else { | |
226 super.dispatchMouseDragged(e); | |
227 } | |
228 } | |
5
4029d5af7542
Add blank lines and rewrap some comments.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
229 |
0 | 230 /** |
231 * Gets the child control at the specified point. If there are | |
232 * multiple child controls at the point, the topmost control is returned. | |
233 * If there is no child control at the point, null is returned. The returned | |
234 * control, if any, is a direct child of this container. | |
235 */ | |
104
5c8c1c2e12c0
Change from real to double.
Jordan Miner <jminer7@gmail.com>
parents:
103
diff
changeset
|
236 Control getChildAtPoint(double[] pt) { |
0 | 237 assert(pt.length == 2, "pt must be just an x and y"); |
238 return getChildAtPoint(Point(pt[0], pt[1])); | |
239 } | |
240 /// ditto | |
104
5c8c1c2e12c0
Change from real to double.
Jordan Miner <jminer7@gmail.com>
parents:
103
diff
changeset
|
241 Control getChildAtPoint(double x, double y) { |
0 | 242 return getChildAtPoint(Point(x, y)); |
243 } | |
244 /// ditto | |
245 Control getChildAtPoint(Point pt) { | |
246 for(int i = _children.count-1; i >= 0; --i) { | |
247 pt = pt - _children[i].location; | |
248 scope(exit) pt = pt + _children[i].location; | |
249 if(_children[i].contains(pt)) | |
250 return _children[i]; | |
251 } | |
252 return null; | |
253 } | |
5
4029d5af7542
Add blank lines and rewrap some comments.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
254 |
0 | 255 /** |
256 * Never returns null. If there is no descendant at the specified point, | |
257 * this container will be returned. | |
258 */ | |
104
5c8c1c2e12c0
Change from real to double.
Jordan Miner <jminer7@gmail.com>
parents:
103
diff
changeset
|
259 Control getDescendantAtPoint(double[] pt) { |
0 | 260 assert(pt.length == 2, "pt must be just an x and y"); |
261 return getDescendantAtPoint(Point(pt[0], pt[1])); | |
262 } | |
263 /// ditto | |
104
5c8c1c2e12c0
Change from real to double.
Jordan Miner <jminer7@gmail.com>
parents:
103
diff
changeset
|
264 Control getDescendantAtPoint(double x, double y) { |
0 | 265 return getDescendantAtPoint(Point(x, y)); |
266 } | |
267 /// ditto | |
268 Control getDescendantAtPoint(Point pt) { | |
269 Container des = this; | |
270 while(true) { | |
271 auto child = des.getChildAtPoint(pt); | |
272 if(!child) | |
273 return des; | |
274 auto isContainer = cast(Container)child; | |
275 if(isContainer) { | |
276 des = isContainer; | |
277 pt = pt - des.location; | |
278 // loop around with this container | |
279 } else { | |
280 return child; | |
281 } | |
282 } | |
283 } | |
5
4029d5af7542
Add blank lines and rewrap some comments.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
284 |
0 | 285 /** |
286 * Gets or sets the minimum size of this window. A minimum width or | |
287 * height of 0 means that there is no minimum width or height. | |
288 * The default is Size(0, 0). | |
289 */ | |
290 Size minSize() { return _minSize; } | |
291 /// ditto | |
292 void minSize(Size size) { | |
68
6580fabb7dce
Setting a property to the value it already is shouldn't do anything
Jordan Miner <jminer7@gmail.com>
parents:
62
diff
changeset
|
293 if(_minSize == size) |
6580fabb7dce
Setting a property to the value it already is shouldn't do anything
Jordan Miner <jminer7@gmail.com>
parents:
62
diff
changeset
|
294 return; |
0 | 295 _minSize = size; |
296 minSizeChanged(new EventArgs); | |
297 } | |
298 /// ditto | |
104
5c8c1c2e12c0
Change from real to double.
Jordan Miner <jminer7@gmail.com>
parents:
103
diff
changeset
|
299 void minSize(double[] size) { |
0 | 300 assert(size.length == 2, "size must be just a width and height"); |
301 minSize = Size(size[0], size[1]); | |
302 } | |
303 /// | |
104
5c8c1c2e12c0
Change from real to double.
Jordan Miner <jminer7@gmail.com>
parents:
103
diff
changeset
|
304 double minWidth() { return _minSize.width; } |
0 | 305 /// |
104
5c8c1c2e12c0
Change from real to double.
Jordan Miner <jminer7@gmail.com>
parents:
103
diff
changeset
|
306 double minHeight() { return _minSize.height; } |
5
4029d5af7542
Add blank lines and rewrap some comments.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
307 |
0 | 308 /** |
309 * Gets or sets the maximum size of this window. A maximum width or | |
310 * height of 0 means that there is no maximum width or height. | |
311 * The default is Size(0, 0). | |
312 */ | |
313 Size maxSize() { return _maxSize; } | |
314 /// ditto | |
315 void maxSize(Size size) { | |
68
6580fabb7dce
Setting a property to the value it already is shouldn't do anything
Jordan Miner <jminer7@gmail.com>
parents:
62
diff
changeset
|
316 if(_maxSize == size) |
6580fabb7dce
Setting a property to the value it already is shouldn't do anything
Jordan Miner <jminer7@gmail.com>
parents:
62
diff
changeset
|
317 return; |
0 | 318 _maxSize = size; |
319 minSizeChanged(new EventArgs); | |
320 } | |
321 /// ditto | |
104
5c8c1c2e12c0
Change from real to double.
Jordan Miner <jminer7@gmail.com>
parents:
103
diff
changeset
|
322 void maxSize(double[] size) { |
0 | 323 assert(size.length == 2, "size must be just a width and height"); |
324 maxSize = Size(size[0], size[1]); | |
325 } | |
326 /// | |
104
5c8c1c2e12c0
Change from real to double.
Jordan Miner <jminer7@gmail.com>
parents:
103
diff
changeset
|
327 double maxWidth() { return _maxSize.width; } |
0 | 328 /// |
104
5c8c1c2e12c0
Change from real to double.
Jordan Miner <jminer7@gmail.com>
parents:
103
diff
changeset
|
329 double maxHeight() { return _maxSize.height; } |
5
4029d5af7542
Add blank lines and rewrap some comments.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
330 |
0 | 331 /** |
332 * Causes this container to position its child controls. Called on every | |
333 * resize. Usually, this function will get each child's best size, and | |
334 * then set each child's location and height. The definition in Container | |
335 * is empty, as it is intended for subclasses to override. | |
336 */ | |
337 void layout() { | |
338 } | |
5
4029d5af7542
Add blank lines and rewrap some comments.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
339 |
0 | 340 protected void add(Control child) { |
341 _children.add(child); | |
342 } | |
5
4029d5af7542
Add blank lines and rewrap some comments.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
343 |
0 | 344 protected void remove(Control child) { |
345 _children.remove(child); | |
346 } | |
5
4029d5af7542
Add blank lines and rewrap some comments.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
347 |
58 | 348 /** |
349 * Calls the specified delegate with each child of this container, for | |
350 * use with foreach. | |
351 */ | |
352 int opApply(int delegate(ref Control item) dg) { | |
0 | 353 for(uint i = 0; i < _children.count; ++i) { |
354 auto tmp = _children[i]; | |
355 if(int result = dg(tmp)) | |
356 return result; | |
357 } | |
358 return 0; | |
359 } | |
58 | 360 /// ditto |
361 int opApply(int delegate(ref uint index, ref Control item) dg) { | |
0 | 362 for(uint i = 0; i < _children.count; ++i) { |
363 auto tmp = _children[i]; | |
364 if(int result = dg(i, tmp)) | |
365 return result; | |
366 } | |
367 return 0; | |
368 } | |
57 | 369 /** |
370 * Calls the specified delegate with each descendant of this container, for | |
371 * use with foreach. | |
372 * | |
373 * Example: | |
374 * ----- | |
375 * foreach(c; &container.descendants) { | |
376 * // do something with c | |
377 * } | |
378 * ----- | |
379 */ | |
380 int descendants(int delegate(ref Control item) dg) { | |
381 for(int i = 0; i < _children.count; ++i) { | |
382 auto tmp = _children[i]; | |
383 if(int result = dg(tmp)) | |
384 return result; | |
385 auto c = cast(Container)_children[i]; | |
386 if(c) | |
387 if(int result = c.descendants(dg)) | |
388 return result; | |
389 } | |
390 return 0; | |
391 } | |
392 /** | |
393 * Same as descendants(), but includes this container in addition to | |
394 * descendants. | |
395 */ | |
396 int descendantsPlus(int delegate(ref Control item) dg) { | |
397 Control tmp = this; | |
398 if(int result = dg(tmp)) | |
399 return result; | |
400 if(int result = descendants(dg)) | |
401 return result; | |
402 return 0; | |
403 } | |
0 | 404 } |
55
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
405 unittest { |
57 | 406 int a = 0, r = 0; |
407 auto container1 = new Panel; | |
408 auto container2 = new Panel; | |
409 auto control1 = new Control; | |
410 auto control2 = new Control; | |
411 auto control3 = new Control; | |
412 container1.descendantAdded += (HierarchyEventArgs e) { a++; }; | |
413 container1.descendantRemoved += (HierarchyEventArgs e) { r++; }; | |
414 | |
415 container2.add(control2); | |
416 container2.children.add(control3); | |
417 assert(control3.parent == container2); | |
418 container1.add(control1); | |
419 assert(a == 1); // test descendantAdded | |
420 container1.add(container2); | |
421 assert(a == 4); // test descendantAdded | |
422 | |
423 // test Container.descendants | |
424 auto list = new List!(Control); | |
425 foreach(c; &container1.descendants) | |
426 list.add(c); | |
427 assert(list.data == [control1, container2, control2, control3]); | |
428 | |
429 list.clear(); | |
430 foreach(c; &container1.descendantsPlus) | |
431 list.add(c); | |
432 assert(list.data == [cast(Control)container1, control1, container2, | |
433 control2, control3]); | |
55
c138461bf845
Add focusing and other changes that are related
Jordan Miner <jminer7@gmail.com>
parents:
35
diff
changeset
|
434 } |
0 | 435 |
58 | 436 /// |
0 | 437 class Panel : Container { |
58 | 438 /// |
0 | 439 ControlList children() { return _children; } |
58 | 440 /// |
0 | 441 void add(Control child) { super.add(child); }; |
58 | 442 /// |
0 | 443 void remove(Control child) { super.remove(child); }; |
58 | 444 /// |
445 int opApply(int delegate(ref Control item) dg) { | |
0 | 446 return super.opApply(dg); |
447 } | |
58 | 448 /// |
449 int opApply(int delegate(ref uint index, ref Control item) dg) { | |
0 | 450 return super.opApply(dg); |
451 } | |
452 } | |
453 |