Mercurial > projects > dynamin
comparison dynamin/gui/scroll_bar.d @ 0:aa4efef0f0b1
Initial commit of code.
author | Jordan Miner <jminer7@gmail.com> |
---|---|
date | Mon, 15 Jun 2009 22:10:48 -0500 |
parents | |
children | b621b528823d |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:aa4efef0f0b1 |
---|---|
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) 2007-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.scroll_bar; | |
27 | |
28 import dynamin.all_core; | |
29 import dynamin.all_gui; | |
30 import dynamin.all_painting; | |
31 import tango.io.Stdout; | |
32 | |
33 enum ArrowDirection { | |
34 Left, Right, Up, Down | |
35 } | |
36 class ArrowButton : Button { | |
37 ArrowDirection _direction; | |
38 ArrowDirection direction() { return _direction; } | |
39 void direction(ArrowDirection dir) { _direction = dir; } | |
40 override void whenPainting(PaintingEventArgs e) { | |
41 Theme.current.ArrowButton_paint(this, e.graphics); | |
42 } | |
43 } | |
44 class ScrollBarTrack : Button { | |
45 override void whenPainting(PaintingEventArgs e) { | |
46 Theme.current.ScrollBarTrack_paint(this, e.graphics); | |
47 } | |
48 } | |
49 class ScrollBarThumb : Button { | |
50 override void whenMouseDown(MouseEventArgs e) { | |
51 } | |
52 override void whenMouseDragged(MouseEventArgs e) { | |
53 } | |
54 override void whenPainting(PaintingEventArgs e) { | |
55 Theme.current.ScrollBarThumb_paint(this, e.graphics); | |
56 } | |
57 } | |
58 //debug=ScrollBar; | |
59 | |
60 /// | |
61 abstract class ScrollBar : Container { | |
62 protected: | |
63 ScrollBarTrack _track1, _track2; | |
64 ScrollBarThumb _thumb; | |
65 ArrowButton _button1, _button2; | |
66 int _value = 0, _maxValue = 100; | |
67 real _visibleValue = 0.5; | |
68 real _thumbDragLoc = -1; | |
69 // stores the location of the thumb as a percentage of the track | |
70 real _thumbPos; | |
71 this() { | |
72 valueChanged = new Event!()(&whenValueChanged); | |
73 | |
74 _track1 = new ScrollBarTrack; | |
75 _track2 = new ScrollBarTrack; | |
76 _thumb = new ScrollBarThumb; | |
77 _button1 = new ArrowButton; | |
78 _button2 = new ArrowButton; | |
79 _track1.mouseDown += &whenTrack1MouseDown; | |
80 _track2.mouseDown += &whenTrack2MouseDown; | |
81 _thumb.mouseDown += &whenThumbMouseDown; | |
82 _thumb.mouseUp += &whenThumbMouseUp; | |
83 _thumb.mouseDragged += &whenThumbMouseDragged; | |
84 _button1.mouseDown += &whenButton1MouseDown; | |
85 _button2.mouseDown += &whenButton2MouseDown; | |
86 add(_track1); | |
87 add(_track2); | |
88 add(_thumb); | |
89 add(_button1); | |
90 add(_button2); | |
91 size = _size; | |
92 } | |
93 void whenThumbMouseDown(MouseEventArgs e); | |
94 void whenThumbMouseDragged(MouseEventArgs e); | |
95 void whenThumbMouseUp(MouseEventArgs e) { | |
96 // This gives the behavior of the thumb jumping when MaxValue | |
97 // is smaller than the track to exactly represent where | |
98 // Value is, as jEdit and some of Windows' controls do. | |
99 _thumbPos = 0; | |
100 updateControls(); | |
101 } | |
102 void whenTrack1MouseDown(MouseEventArgs e) { | |
103 value = value - 100; | |
104 } | |
105 void whenTrack2MouseDown(MouseEventArgs e) { | |
106 value = value + 100; | |
107 } | |
108 void whenButton1MouseDown(MouseEventArgs e) { | |
109 value = value - 10; | |
110 } | |
111 void whenButton2MouseDown(MouseEventArgs e) { | |
112 value = value + 10; | |
113 } | |
114 void putControl(Control c, real location, real size); | |
115 real breadth(); | |
116 real length(); | |
117 override void whenResized(EventArgs e) { | |
118 updateControls(); | |
119 } | |
120 void layoutControls(Control[] controls, real[] sizes) { | |
121 assert(controls.length == sizes.length); | |
122 real loc = 0; | |
123 for(int i = 0; i < controls.length; ++i) { | |
124 putControl(controls[i], loc, sizes[i]); | |
125 loc += sizes[i]; | |
126 } | |
127 } | |
128 // updates controls based on what value, visible value, and max value are | |
129 void updateControls() { | |
130 if(breadth*2 > length) { | |
131 return; | |
132 // no track or thumb | |
133 } | |
134 // if thumbPos does not represent the current value | |
135 if(cast(int)(_thumbPos * _maxValue) != _value) | |
136 _thumbPos = _value / cast(real)_maxValue; | |
137 auto totalSz = length; | |
138 auto buttonSz = breadth; | |
139 auto totalTrackSz = totalSz - buttonSz*2; | |
140 auto thumbSz = round(totalTrackSz*_visibleValue); | |
141 auto thumbLoc = buttonSz+(totalTrackSz-thumbSz)*_thumbPos; | |
142 if(thumbSz < 8) | |
143 thumbSz = 8; | |
144 auto track1Sz = thumbLoc-buttonSz; | |
145 auto track2Sz = totalTrackSz-track1Sz-thumbSz; | |
146 if(track1Sz < 0) track1Sz = 0; | |
147 if(track2Sz < 0) track2Sz = 0; | |
148 debug(ScrollBar) { | |
149 Stdout.format("value={}", value).newline; | |
150 Stdout.format("visibleValue={}", visibleValue).newline; | |
151 Stdout.format("maxValue={}", maxValue).newline; | |
152 Stdout.format("totalSz={}", totalSz).newline; | |
153 Stdout.format("buttonSz={}", buttonSz).newline; | |
154 Stdout.format("totalTrackSz={}", totalTrackSz).newline; | |
155 Stdout.format("thumbSz={}", thumbSz).newline; | |
156 Stdout.format("track1Sz={}", track1Sz).newline; | |
157 Stdout.format("track2Sz={}", track2Sz).newline; | |
158 Stdout("********").newline; | |
159 assert(2*buttonSz+track1Sz+thumbSz+track2Sz <= totalSz + 0.01); | |
160 } | |
161 layoutControls([cast(Control) | |
162 _button1, _track1, _thumb, _track2, _button2], | |
163 [buttonSz, track1Sz, thumbSz, track2Sz, buttonSz]); | |
164 } | |
165 public: | |
166 /// This event occurs after Value has been changed. | |
167 Event!() valueChanged; | |
168 /// Override this method in a subclass to handle the ValueChanged event. | |
169 protected void whenValueChanged(EventArgs e) { } | |
170 | |
171 override Size bestSize() { | |
172 if(cast(VScrollBar)this) | |
173 return Size(Theme.current.ScrollBar_size(), 100); | |
174 else | |
175 return Size(100, Theme.current.ScrollBar_size()); | |
176 } | |
177 /// | |
178 real thumbLocation(); | |
179 /// ditto | |
180 void thumbLocation(real loc) { | |
181 // TODO: return if no thumb (too small for one) | |
182 if(loc < trackStart) | |
183 loc = trackStart; | |
184 if(loc > trackEnd - thumbSize) | |
185 loc = trackEnd - thumbSize; | |
186 if(floatsEqual(loc, thumbLocation, 0.1)) | |
187 return; | |
188 | |
189 _thumbPos = (loc - trackStart) / (trackSize - thumbSize); | |
190 value = cast(int)(_thumbPos * _maxValue); | |
191 updateControls(); | |
192 } | |
193 /// | |
194 real thumbSize(); | |
195 /// | |
196 real trackStart(); | |
197 /// | |
198 real trackEnd(); | |
199 /// | |
200 real trackSize() { return trackEnd-trackStart; } | |
201 /// | |
202 int value() { return _value; } | |
203 /// ditto | |
204 void value(int val) { | |
205 if(val < 0) | |
206 val = 0; | |
207 else if(val > _maxValue) | |
208 val = _maxValue; | |
209 if(val == _value) | |
210 return; | |
211 _value = val; | |
212 updateControls(); | |
213 valueChanged(new EventArgs); | |
214 } | |
215 /// | |
216 int maxValue() { return _maxValue; } | |
217 /// ditto | |
218 void maxValue(int val) { | |
219 if(val < 1) | |
220 val = 1; | |
221 if(val == _maxValue) | |
222 return; | |
223 _maxValue = val; | |
224 if(_value > _maxValue) | |
225 _value = _maxValue; | |
226 if(_visibleValue > _maxValue) | |
227 _visibleValue = _maxValue; | |
228 updateControls(); | |
229 } | |
230 /** | |
231 * A floating-point number between 0 and 1 that specifies how large the | |
232 * thumb should be compared to the track. A value of 0 makes the thumb its | |
233 * minimum size, and a value of 1 makes the thumb take up all of the track. | |
234 * The default is 0.5. | |
235 */ | |
236 real visibleValue() { return _visibleValue; } | |
237 /// ditto | |
238 void visibleValue(real val) { | |
239 if(val < 0) | |
240 val = 0; | |
241 else if(val > 1) | |
242 val = 1; | |
243 if(val == _visibleValue) | |
244 return; | |
245 _visibleValue = val; | |
246 updateControls(); | |
247 } | |
248 } | |
249 /// | |
250 class HScrollBar : ScrollBar { | |
251 this() { | |
252 _button1.direction = ArrowDirection.Left; | |
253 _button2.direction = ArrowDirection.Right; | |
254 } | |
255 protected: | |
256 void whenThumbMouseDown(MouseEventArgs e) { | |
257 _thumbDragLoc = e.location.x; | |
258 } | |
259 void whenThumbMouseDragged(MouseEventArgs e) { | |
260 _thumb.state = ButtonState.Pressed; | |
261 thumbLocation = e.location.x + _thumb.location.x - _thumbDragLoc; | |
262 } | |
263 void putControl(Control c, real location, real size) { | |
264 c.location = [location, 0.0]; | |
265 c.size = [size, height]; | |
266 } | |
267 real breadth() { return height; } | |
268 real length() { return width; } | |
269 alias ScrollBar.thumbLocation thumbLocation; | |
270 real thumbLocation() { return _thumb.x; } | |
271 real thumbSize() { return _thumb.width; } | |
272 real trackStart() { return _track1.x; } | |
273 real trackEnd() { return _track2.x+_track2.width; } | |
274 } | |
275 /// | |
276 class VScrollBar : ScrollBar { | |
277 this() { | |
278 _button1.direction = ArrowDirection.Up; | |
279 _button2.direction = ArrowDirection.Down; | |
280 } | |
281 protected: | |
282 void whenThumbMouseDown(MouseEventArgs e) { | |
283 _thumbDragLoc = e.location.y; | |
284 } | |
285 void whenThumbMouseDragged(MouseEventArgs e) { | |
286 _thumb.state = ButtonState.Pressed; | |
287 thumbLocation = e.location.y + _thumb.location.y - _thumbDragLoc; | |
288 } | |
289 void putControl(Control c, real location, real size) { | |
290 c.location = [0.0, location]; | |
291 c.size = [width, size]; | |
292 } | |
293 real breadth() { return width; } | |
294 real length() { return height; } | |
295 alias ScrollBar.thumbLocation thumbLocation; | |
296 real thumbLocation() { return _thumb.y; } | |
297 real thumbSize() { return _thumb.height; } | |
298 real trackStart() { return _track1.y; } | |
299 real trackEnd() { return _track2.y+_track2.height; } | |
300 } | |
301 |