Mercurial > projects > dynamin
annotate dynamin/gui/control.d @ 8:b621b528823d
whenXX methods have to come before the event if switched to template mixins.
author | Jordan Miner <jminer7@gmail.com> |
---|---|
date | Wed, 15 Jul 2009 14:04:55 -0500 |
parents | 4029d5af7542 |
children | ccc108b25a0a |
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.control; | |
27 | |
28 import dynamin.all_core; | |
29 import dynamin.all_painting; | |
30 import dynamin.gui.container; | |
31 import dynamin.gui.events; | |
32 import dynamin.gui.window; | |
33 import dynamin.gui.cursor; | |
34 import tango.io.Stdout; | |
35 | |
36 Control hotControl; | |
37 // the hot control is the one the mouse is over | |
38 package void setHotControl(Control c) { | |
39 if(c !is hotControl) { | |
40 if(hotControl) | |
41 hotControl.mouseLeft(new EventArgs); | |
42 hotControl = c; | |
43 if(c) | |
44 c.mouseEntered(new EventArgs); | |
45 } | |
46 } | |
47 package Control getHotControl() { return hotControl; } | |
48 Control captorControl; | |
49 package void setCaptorControl(Control c) { | |
50 captorControl = c; | |
51 } | |
52 package Control getCaptorControl() { return captorControl; } | |
53 | |
54 /** | |
55 * The painting event is an exception to the rule that added handlers are called | |
56 * before whenPainting. The painting event is far more useful since | |
57 * added handles are called after the control's whenPainting has finished. | |
58 * Otherwise, anything handlers painted would likely be painted over when the | |
59 * control painted. | |
60 */ | |
61 class Control { | |
62 protected: | |
63 bool _visible; | |
64 bool _focusable; | |
65 bool _focused; | |
66 package Point _location; | |
67 package Size _size; | |
68 string _text; | |
69 Color _backColor; | |
70 Color _foreColor; | |
71 Font _font; | |
72 Cursor _cursor; | |
73 Container _parent; | |
74 bool _elasticX, _elasticY; | |
75 public: | |
76 protected void dispatchMouseEntered(EventArgs e) { | |
77 Cursor.setCurrent(this, _cursor); | |
78 mouseEntered.callHandlers(e); | |
79 mouseEntered.callMainHandler(e); | |
80 } | |
81 protected void dispatchMouseDown(MouseEventArgs e) { | |
82 setCaptorControl(this); | |
83 mouseDown.callHandlers(e); | |
84 mouseDown.callMainHandler(e); | |
85 } | |
86 protected void dispatchMouseUp(MouseEventArgs e) { | |
87 setCaptorControl(null); | |
88 mouseUp.callHandlers(e); | |
89 mouseUp.callMainHandler(e); | |
90 } | |
91 protected void dispatchMouseMoved(MouseEventArgs e) { | |
92 setHotControl(this); | |
93 mouseMoved.callHandlers(e); | |
94 mouseMoved.callMainHandler(e); | |
95 } | |
96 protected void dispatchMouseDragged(MouseEventArgs e) { | |
97 setHotControl(this); | |
98 mouseDragged.callHandlers(e); | |
99 mouseDragged.callMainHandler(e); | |
100 } | |
101 protected void dispatchMouseTurned(MouseTurnedEventArgs e) { | |
102 mouseTurned.callHandlers(e); | |
103 mouseTurned.callMainHandler(e); | |
104 if(!e.stopped && _parent) | |
105 _parent.mouseTurned(e); | |
106 } | |
107 protected void dispatchPainting(PaintingEventArgs e) { | |
108 e.graphics.save(); | |
109 painting.callMainHandler(e); | |
110 e.graphics.restore(); | |
111 e.graphics.save(); | |
112 // TODO: every call to a handler should be wrapped in a save/restore | |
113 painting.callHandlers(e); | |
114 e.graphics.restore(); | |
115 } | |
5
4029d5af7542
Add blank lines and rewrap some comments.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
116 |
8
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
117 /// Override this method in a subclass to handle the Moved event. |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
118 protected void whenMoved(EventArgs e) { } |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
119 /// This event occurs after the control has been moved. |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
120 Event!() moved; |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
121 |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
122 /// Override this method in a subclass to handle the Resized event. |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
123 protected void whenResized(EventArgs e) { } |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
124 /// This event occurs after the control has been resized. |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
125 Event!() resized; |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
126 |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
127 /// Override this method in a subclass to handle the MouseEntered event. |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
128 protected void whenMouseEntered(EventArgs e) { } |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
129 /// This event occurs after the mouse has entered the control. |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
130 Event!() mouseEntered; |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
131 |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
132 /// Override this method in a subclass to handle the MouseLeft event. |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
133 protected void whenMouseLeft(EventArgs e) { } |
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 mouse has left the control. |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
135 Event!() mouseLeft; |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
136 |
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 MouseDown 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 whenMouseDown(MouseEventArgs e) { } |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
139 /// This event occurs after a mouse button is pressed. |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
140 Event!(MouseEventArgs) mouseDown; |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
141 |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
142 /// Override this method in a subclass to handle the MouseUp event. |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
143 protected void whenMouseUp(MouseEventArgs e) { } |
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 a mouse button is released. |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
145 Event!(MouseEventArgs) mouseUp; |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
146 |
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 MouseMoved 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 whenMouseMoved(MouseEventArgs e) { } |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
149 /// This event occurs after the mouse has been moved. |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
150 Event!(MouseEventArgs) mouseMoved; |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
151 |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
152 /// Override this method in a subclass to handle the MouseMoved event. |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
153 protected void whenMouseDragged(MouseEventArgs e) { } |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
154 /// This event occurs after the mouse has been moved. |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
155 Event!(MouseEventArgs) mouseDragged; |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
156 |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
157 /// Override this method in a subclass to handle the MouseTurned event. |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
158 protected void whenMouseTurned(MouseTurnedEventArgs e) { } |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
159 /// This event occurs after the mouse wheel has been turned. |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
160 Event!(MouseTurnedEventArgs) mouseTurned; |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
161 |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
162 /// Override this method in a subclass to handle the KeyDown event. |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
163 protected void whenKeyDown(KeyEventArgs e) { } |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
164 /// This event occurs after a key is pressed. |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
165 Event!(KeyEventArgs) keyDown; |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
166 |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
167 /// Override this method in a subclass to handle the KeyTyped event. |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
168 protected void whenKeyTyped(KeyTypedEventArgs e) { } |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
169 /// This event occurs after a character key is pressed. |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
170 Event!(KeyTypedEventArgs) keyTyped; |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
171 |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
172 /// Override this method in a subclass to handle the KeyUp event. |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
173 protected void whenKeyUp(KeyEventArgs e) { } |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
174 /// This event occurs after a key is released. |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
175 Event!(KeyEventArgs) keyUp; |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
176 |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
177 /// Override this method in a subclass to handle the painting event. |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
178 protected void whenPainting(PaintingEventArgs e) { |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
179 e.graphics.source = backColor; |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
180 e.graphics.paint(); |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
181 } |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
182 /// This event occurs when the control needs to be painted. |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
183 Event!(PaintingEventArgs) painting; |
b621b528823d
whenXX methods have to come before the event if switched to template mixins.
Jordan Miner <jminer7@gmail.com>
parents:
5
diff
changeset
|
184 |
0 | 185 this() { |
186 moved = new Event!()(&whenMoved); | |
187 resized = new Event!()(&whenResized); | |
188 mouseEntered = new Event!()(&whenMouseEntered, &dispatchMouseEntered); | |
189 mouseLeft = new Event!()(&whenMouseLeft); | |
190 mouseDown = new Event!(MouseEventArgs)(&whenMouseDown, &dispatchMouseDown); | |
191 mouseUp = new Event!(MouseEventArgs)(&whenMouseUp, &dispatchMouseUp); | |
192 mouseMoved = new Event!(MouseEventArgs)(&whenMouseMoved, &dispatchMouseMoved); | |
193 mouseDragged = new Event!(MouseEventArgs)(&whenMouseDragged, &dispatchMouseDragged); | |
194 mouseTurned = new Event!(MouseTurnedEventArgs)(&whenMouseTurned, &dispatchMouseTurned); | |
195 keyDown = new Event!(KeyEventArgs)(&whenKeyDown); | |
196 keyTyped = new Event!(KeyTypedEventArgs)(&whenKeyTyped); | |
197 keyUp = new Event!(KeyEventArgs)(&whenKeyUp); | |
198 painting = new Event!(PaintingEventArgs)(&whenPainting, &dispatchPainting); | |
199 | |
200 _location = Point(0, 0); | |
201 _size = Size(100, 100); | |
202 _text = ""; | |
203 _focusable = false; | |
204 _focused = false; | |
205 _visible = true; | |
206 _cursor = Cursor.Arrow; | |
207 _elasticX = false; | |
208 _elasticY = false; | |
209 | |
210 // TODO: remove these when themes mature | |
211 _foreColor = Color.Black; | |
212 _font = new Font("Tahoma", 11); | |
213 } | |
5
4029d5af7542
Add blank lines and rewrap some comments.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
214 |
0 | 215 protected Graphics quickCreateGraphics() { |
216 if(_parent is null) | |
217 return null; | |
218 auto g = _parent.quickCreateGraphics(); | |
219 g.translate(location); | |
220 return g; | |
221 } | |
5
4029d5af7542
Add blank lines and rewrap some comments.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
222 |
0 | 223 /** |
224 * Sets the specified Graphics' font and source to this control's font | |
225 * and foreground color. Also, clips to this control's rectangle. | |
226 */ | |
227 void setupGraphics(Graphics g) { | |
228 g.rectangle(0, 0, width, height); | |
229 g.clip(); | |
230 g.font = font; | |
231 g.source = foreColor; | |
232 } | |
5
4029d5af7542
Add blank lines and rewrap some comments.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
233 |
0 | 234 /** |
235 * Creates a Graphics, calls the specified delegate with it, and deletes | |
236 * it to release resources. | |
237 */ | |
238 void withGraphics(void delegate(Graphics g) dg) { | |
239 auto g = quickCreateGraphics(); | |
240 setupGraphics(g); | |
241 dg(g); | |
242 delete g; | |
243 } | |
5
4029d5af7542
Add blank lines and rewrap some comments.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
244 |
0 | 245 /** |
246 * | |
247 */ | |
248 bool focused() { | |
249 return _focused; | |
250 } | |
5
4029d5af7542
Add blank lines and rewrap some comments.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
251 |
0 | 252 /** |
253 * | |
254 */ | |
255 void focus() { | |
256 if(!_focusable) | |
257 return; | |
258 Control c = this; | |
259 while(c.parent) | |
260 c = c.parent; | |
261 if(auto win = cast(Window)c) { | |
262 if(win.focusedControl) { | |
263 win.focusedControl._focused = false; | |
264 win.focusedControl.repaint(); | |
265 } | |
266 win.focusedControl = this; | |
267 _focused = true; | |
268 repaint(); | |
269 } | |
270 } | |
5
4029d5af7542
Add blank lines and rewrap some comments.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
271 |
0 | 272 /** |
273 * Returns whether this control is on the screen. A control is | |
274 * on screen if one of its ancestors is a top level window. Whether or | |
275 * not the control is visible has no bearing on this value. If a control | |
276 * has no parent, then it is clearly not on the screen. | |
277 */ | |
278 bool onScreen() { | |
279 return _parent && _parent.onScreen; | |
280 } | |
5
4029d5af7542
Add blank lines and rewrap some comments.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
281 |
0 | 282 /** |
283 * Gets the location of this control in screen coordinates. An exception is | |
284 * thrown if this control is not on the screen. | |
285 */ | |
286 Point screenLocation() { | |
287 if(!_parent) | |
288 throw new Exception("control is not on screen"); | |
289 return _parent.screenLocation + location; | |
290 } | |
5
4029d5af7542
Add blank lines and rewrap some comments.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
291 |
0 | 292 /** |
293 * Converts the specified point in content coordinates into screen | |
294 * coordinates. An exception is thrown if this control is not on the screen. | |
295 */ | |
296 Point contentToScreen(Point pt) { // TODO: content?? even on Window?? | |
297 if(!_parent) | |
298 throw new Exception("control is not on screen"); | |
299 return _parent.contentToScreen(pt + location); | |
300 } | |
5
4029d5af7542
Add blank lines and rewrap some comments.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
301 |
0 | 302 /** |
303 * Converts the specified point in screen coordinates into content | |
304 * coordinates. An exception is thrown if this control is not on the screen. | |
305 */ | |
306 Point screenToContent(Point pt) { | |
307 if(!_parent) | |
308 throw new Exception("control is not on screen"); | |
309 return _parent.screenToContent(pt) - location; // TODO: borders | |
310 } | |
5
4029d5af7542
Add blank lines and rewrap some comments.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
311 |
0 | 312 /** |
313 * Converts the specified point in this control's content coordinates | |
314 * into the specified control's content coordinates. An exception is | |
315 * thrown if this control is not on the screen. | |
316 */ | |
317 Point contentToContent(Point pt, Control c) { | |
318 return c.screenToContent(contentToScreen(pt)); | |
319 } | |
5
4029d5af7542
Add blank lines and rewrap some comments.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
320 |
0 | 321 /** |
322 * Returns whether the specified point is inside this control. | |
323 */ | |
324 bool contains(Point pt) { | |
325 return pt.x >= 0 && pt.y >= 0 && pt.x < width && pt.y < height; | |
326 } | |
327 /// ditto | |
328 bool contains(real x, real y) { | |
329 return contains(Point(x, y)); | |
330 } | |
5
4029d5af7542
Add blank lines and rewrap some comments.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
331 |
0 | 332 bool topLevel() { return false; } |
333 // TODO: return NativeControl/Window? | |
334 Control getTopLevel() { | |
335 Control c = this; | |
336 while(c.parent) | |
337 c = c.parent; | |
338 return c.topLevel ? c : null; | |
339 } | |
5
4029d5af7542
Add blank lines and rewrap some comments.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
340 |
0 | 341 /** |
342 * Gets this control's parent. | |
343 */ | |
344 Container parent() { return _parent; } | |
345 package void parent(Container c) { | |
346 _parent = c; | |
347 //ParentChanged(new EventArgs); // TODO: add event | |
348 } | |
5
4029d5af7542
Add blank lines and rewrap some comments.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
349 |
0 | 350 /** |
5
4029d5af7542
Add blank lines and rewrap some comments.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
351 * Gets or sets whether is control is visible. The default is true, except |
4029d5af7542
Add blank lines and rewrap some comments.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
352 * on top-level windows. |
0 | 353 */ |
354 //void visible(bool b) { visible = b; } | |
355 bool visible() { return _visible; } | |
356 | |
357 /** | |
358 * Gets or sets the location of this control in its parent's content | |
359 * coordinates. | |
360 * Examples: | |
361 * ----- | |
362 * control.location = [5, 35]; | |
363 * control.location = Point(50, 50); | |
364 * ----- | |
365 */ | |
366 Point location() { return _location; } | |
367 /// ditto | |
368 void location(Point pt) { | |
369 if((cast(Window)_parent) !is null) | |
370 throw new Exception("cannot set location of a window's content"); | |
371 pt.x = round(pt.x); | |
372 pt.y = round(pt.y); | |
373 repaint(); | |
374 _location = pt; | |
375 repaint(); | |
376 moved(new EventArgs); | |
377 } | |
378 /// ditto | |
379 void location(real[] pt) { | |
380 assert(pt.length == 2, "pt must be just an x and y"); | |
381 location = Point(pt[0], pt[1]); | |
382 } | |
383 | |
384 /** | |
385 * Gets or sets the size of this control. | |
386 * Examples: | |
387 * ----- | |
388 * control.size = [75, 23]; | |
389 * control.size = Size(80, 20); | |
390 * ----- | |
391 */ | |
392 Size size() { return _size; } | |
393 /// ditto | |
394 void size(Size newSize) { | |
395 if(newSize.width < 0) | |
396 newSize.width = 0; | |
397 if(newSize.height < 0) | |
398 newSize.height = 0; | |
399 newSize.width = round(newSize.width); | |
400 newSize.height = round(newSize.height); | |
401 repaint(); | |
402 _size = newSize; | |
403 repaint(); | |
404 resized(new EventArgs); | |
405 } | |
406 /// ditto | |
407 void size(real[] newSize) { | |
408 assert(newSize.length == 2, "size must be just a width and height"); | |
409 size = Size(newSize[0], newSize[1]); | |
410 } | |
411 | |
412 /** | |
413 * Gets the size at which this control looks the best. It is intended that | |
414 * the control not be made smaller than this size, and only be made larger | |
415 * if it is elastic, or if it needs to be aligned with other controls. | |
416 * | |
417 * This property should be overridden in subclasses to return a best size. | |
418 */ | |
419 Size bestSize() { return Size(100, 100); } | |
5
4029d5af7542
Add blank lines and rewrap some comments.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
420 |
0 | 421 /** |
422 * Gets the distance from the top of this control to the baseline of | |
423 * the first line of this control's text. If this control does not have | |
424 * text, 0 may be returned. | |
425 */ | |
426 int baseline() { return 0; } | |
427 | |
428 /// Same as location.x | |
429 real x() { return location.x; } | |
430 /// Same as location.y | |
431 real y() { return location.y; } | |
432 /// Same as size.width | |
433 real width() { return size.width; } | |
434 /// Same as size.height | |
435 real height() { return size.height; } | |
436 | |
437 /** | |
438 * Gets or sets whether this control is elastic horizontally or vertically. | |
439 * If a control is elastic, then it is intended to be made larger than its | |
440 * best size. | |
441 */ | |
442 bool elasticX() { return _elasticX; } | |
443 /// ditto | |
444 void elasticX(bool b) { _elasticX = b; } | |
445 /// ditto | |
446 bool elasticY() { return _elasticY; } | |
447 /// ditto | |
448 void elasticY(bool b) { _elasticY = b; } | |
5
4029d5af7542
Add blank lines and rewrap some comments.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
449 |
0 | 450 /** |
451 * Gets or sets the text that this control shows. | |
452 */ | |
453 string text() { return _text.dup; } | |
454 /// ditto | |
455 void text(string str) { | |
456 _text = str.dup; | |
457 repaint(); | |
458 //TextChanged(EventArgs e) // TODO: add event | |
459 } | |
460 | |
461 /** | |
462 * Gets or sets the background color of this control. | |
463 */ | |
464 Color backColor() { return _backColor; } | |
465 /// ditto | |
466 void backColor(Color c) { | |
467 _backColor = c; | |
468 repaint(); | |
469 } | |
470 | |
471 /** | |
472 * Gets or sets the foreground color of this control. | |
473 */ | |
474 Color foreColor() { return _foreColor; } | |
475 /// ditto | |
476 void foreColor(Color c) { | |
477 _foreColor = c; | |
478 repaint(); | |
479 } | |
480 | |
481 /** | |
482 * Gets or sets the font of this control uses to display text. A value of | |
483 * null means that the font is unset. When the font is null, the | |
484 * current theme's font is used. The default is null. | |
485 */ | |
486 Font font() { | |
487 // TODO: if font is null (unset), return from theme | |
488 //if(font is null) | |
489 // return Theme.Current.Control_Font(this); | |
490 //else | |
491 return _font; | |
492 } | |
493 /// ditto | |
494 void font(Font f) { | |
495 _font = f; | |
496 repaint(); | |
497 } | |
5
4029d5af7542
Add blank lines and rewrap some comments.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
498 |
0 | 499 Cursor cursor() { |
500 return _cursor; | |
501 } | |
502 void cursor(Cursor cur) { | |
503 if(_cursor is cur) | |
504 return; | |
505 _cursor = cur; | |
506 if(getHotControl() is this) | |
507 Cursor.setCurrent(this, _cursor); | |
508 } | |
509 | |
510 /** | |
511 * Causes the part of the control inside the specified | |
512 * rectangle to be repainted. The rectangle is in content coordinates. | |
513 * | |
514 * The control will not be repainted before this method returns; rather, | |
515 * the area is just marked as needing to be repainted. The next time there | |
516 * are no other system events to be processed, a painting event will called. | |
517 */ | |
518 void repaint(Rect rect) { | |
5
4029d5af7542
Add blank lines and rewrap some comments.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
519 // TODO: make sure that parts clipped off by the parent are |
4029d5af7542
Add blank lines and rewrap some comments.
Jordan Miner <jminer7@gmail.com>
parents:
0
diff
changeset
|
520 // not invalidated |
0 | 521 if(_parent) |
522 _parent.repaint(rect + location); | |
523 } | |
524 /// ditto | |
525 void repaint(real x, real y, real width, real height) { | |
526 repaint(Rect(x, y, width, height)); | |
527 } | |
528 /** | |
529 * Causes the entire control to be repainted. | |
530 */ | |
531 void repaint() { | |
532 repaint(Rect(0, 0, width, height)); | |
533 } | |
534 } | |
535 | |
536 |