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