comparison ext/guichan-0.8.1/src/widgets/slider.cpp @ 0:4a0efb7baf70

* Datasets becomes the new trunk and retires after that :-)
author mvbarracuda@33b003aa-7bff-0310-803a-e67f0ece8222
date Sun, 29 Jun 2008 18:44:17 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:4a0efb7baf70
1 /* _______ __ __ __ ______ __ __ _______ __ __
2 * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
3 * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
4 * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
5 * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
6 * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
7 * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
8 *
9 * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
10 *
11 *
12 * Per Larsson a.k.a finalman
13 * Olof Naessén a.k.a jansem/yakslem
14 *
15 * Visit: http://guichan.sourceforge.net
16 *
17 * License: (BSD)
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions
20 * are met:
21 * 1. Redistributions of source code must retain the above copyright
22 * notice, this list of conditions and the following disclaimer.
23 * 2. Redistributions in binary form must reproduce the above copyright
24 * notice, this list of conditions and the following disclaimer in
25 * the documentation and/or other materials provided with the
26 * distribution.
27 * 3. Neither the name of Guichan nor the names of its contributors may
28 * be used to endorse or promote products derived from this software
29 * without specific prior written permission.
30 *
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
36 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
37 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
38 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
39 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
40 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
41 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 */
43
44 /*
45 * For comments regarding functions please see the header file.
46 */
47
48 #include "guichan/widgets/slider.hpp"
49
50 #include "guichan/graphics.hpp"
51 #include "guichan/key.hpp"
52 #include "guichan/mouseinput.hpp"
53
54 namespace gcn
55 {
56 Slider::Slider(double scaleEnd)
57 {
58 mDragged = false;
59
60 mScaleStart = 0;
61 mScaleEnd = scaleEnd;
62
63 setFocusable(true);
64 setFrameSize(1);
65 setOrientation(HORIZONTAL);
66 setValue(0);
67 setStepLength(scaleEnd / 10);
68 setMarkerLength(10);
69
70 addMouseListener(this);
71 addKeyListener(this);
72 }
73
74 Slider::Slider(double scaleStart, double scaleEnd)
75 {
76 mDragged = false;
77
78 mScaleStart = scaleStart;
79 mScaleEnd = scaleEnd;
80
81 setFocusable(true);
82 setFrameSize(1);
83 setOrientation(HORIZONTAL);
84 setValue(scaleStart);
85 setStepLength((scaleEnd - scaleStart)/ 10);
86 setMarkerLength(10);
87
88 addMouseListener(this);
89 addKeyListener(this);
90 }
91
92 void Slider::setScale(double scaleStart, double scaleEnd)
93 {
94 mScaleStart = scaleStart;
95 mScaleEnd = scaleEnd;
96 }
97
98 double Slider::getScaleStart() const
99 {
100 return mScaleStart;
101 }
102
103 void Slider::setScaleStart(double scaleStart)
104 {
105 mScaleStart = scaleStart;
106 }
107
108 double Slider::getScaleEnd() const
109 {
110 return mScaleEnd;
111 }
112
113 void Slider::setScaleEnd(double scaleEnd)
114 {
115 mScaleEnd = scaleEnd;
116 }
117
118 void Slider::draw(gcn::Graphics* graphics)
119 {
120 Color shadowColor = getBaseColor() - 0x101010;
121 int alpha = getBaseColor().a;
122 shadowColor.a = alpha;
123
124 graphics->setColor(shadowColor);
125 graphics->fillRectangle(gcn::Rectangle(0,0,getWidth(),getHeight()));
126
127 drawMarker(graphics);
128 }
129
130 void Slider::drawMarker(gcn::Graphics* graphics)
131 {
132 gcn::Color faceColor = getBaseColor();
133 Color highlightColor, shadowColor;
134 int alpha = getBaseColor().a;
135 highlightColor = faceColor + 0x303030;
136 highlightColor.a = alpha;
137 shadowColor = faceColor - 0x303030;
138 shadowColor.a = alpha;
139
140 graphics->setColor(faceColor);
141
142 if (getOrientation() == HORIZONTAL)
143 {
144 int v = getMarkerPosition();
145 graphics->fillRectangle(gcn::Rectangle(v + 1, 1, getMarkerLength() - 2, getHeight() - 2));
146 graphics->setColor(highlightColor);
147 graphics->drawLine(v, 0, v + getMarkerLength() - 1,0);
148 graphics->drawLine(v, 0, v, getHeight() - 1);
149 graphics->setColor(shadowColor);
150 graphics->drawLine(v + getMarkerLength() - 1, 1, v + getMarkerLength() - 1, getHeight() - 1);
151 graphics->drawLine(v + 1, getHeight() - 1, v + getMarkerLength() - 1, getHeight() - 1);
152
153 if (isFocused())
154 {
155 graphics->setColor(getForegroundColor());
156 graphics->drawRectangle(Rectangle(v + 2, 2, getMarkerLength() - 4, getHeight() - 4));
157 }
158 }
159 else
160 {
161 int v = (getHeight() - getMarkerLength()) - getMarkerPosition();
162 graphics->fillRectangle(gcn::Rectangle(1, v + 1, getWidth() - 2, getMarkerLength() - 2));
163 graphics->setColor(highlightColor);
164 graphics->drawLine(0, v, 0, v + getMarkerLength() - 1);
165 graphics->drawLine(0, v, getWidth() - 1, v);
166 graphics->setColor(shadowColor);
167 graphics->drawLine(1, v + getMarkerLength() - 1, getWidth() - 1, v + getMarkerLength() - 1);
168 graphics->drawLine(getWidth() - 1, v + 1, getWidth() - 1, v + getMarkerLength() - 1);
169
170 if (isFocused())
171 {
172 graphics->setColor(getForegroundColor());
173 graphics->drawRectangle(Rectangle(2, v + 2, getWidth() - 4, getMarkerLength() - 4));
174 }
175 }
176 }
177
178 void Slider::mousePressed(MouseEvent& mouseEvent)
179 {
180 if (mouseEvent.getButton() == gcn::MouseEvent::LEFT
181 && mouseEvent.getX() >= 0
182 && mouseEvent.getX() <= getWidth()
183 && mouseEvent.getY() >= 0
184 && mouseEvent.getY() <= getHeight())
185 {
186 if (getOrientation() == HORIZONTAL)
187 {
188 setValue(markerPositionToValue(mouseEvent.getX() - getMarkerLength() / 2));
189 }
190 else
191 {
192 setValue(markerPositionToValue(getHeight() - mouseEvent.getY() - getMarkerLength() / 2));
193 }
194
195 distributeActionEvent();
196 }
197 }
198
199 void Slider::mouseDragged(MouseEvent& mouseEvent)
200 {
201 if (getOrientation() == HORIZONTAL)
202 {
203 setValue(markerPositionToValue(mouseEvent.getX() - getMarkerLength() / 2));
204 }
205 else
206 {
207 setValue(markerPositionToValue(getHeight() - mouseEvent.getY() - getMarkerLength() / 2));
208 }
209
210 distributeActionEvent();
211
212 mouseEvent.consume();
213 }
214
215 void Slider::setValue(double value)
216 {
217 if (value > getScaleEnd())
218 {
219 mValue = getScaleEnd();
220 return;
221 }
222
223 if (value < getScaleStart())
224 {
225 mValue = getScaleStart();
226 return;
227 }
228
229 mValue = value;
230 }
231
232 double Slider::getValue() const
233 {
234 return mValue;
235 }
236
237 int Slider::getMarkerLength() const
238 {
239 return mMarkerLength;
240 }
241
242 void Slider::setMarkerLength(int length)
243 {
244 mMarkerLength = length;
245 }
246
247 void Slider::keyPressed(KeyEvent& keyEvent)
248 {
249 Key key = keyEvent.getKey();
250
251 if (getOrientation() == HORIZONTAL)
252 {
253 if (key.getValue() == Key::RIGHT)
254 {
255 setValue(getValue() + getStepLength());
256 distributeActionEvent();
257 keyEvent.consume();
258 }
259 else if (key.getValue() == Key::LEFT)
260 {
261 setValue(getValue() - getStepLength());
262 distributeActionEvent();
263 keyEvent.consume();
264 }
265 }
266 else
267 {
268 if (key.getValue() == Key::UP)
269 {
270 setValue(getValue() + getStepLength());
271 distributeActionEvent();
272 keyEvent.consume();
273 }
274 else if (key.getValue() == Key::DOWN)
275 {
276 setValue(getValue() - getStepLength());
277 distributeActionEvent();
278 keyEvent.consume();
279 }
280 }
281 }
282
283 void Slider::setOrientation(Slider::Orientation orientation)
284 {
285 mOrientation = orientation;
286 }
287
288 Slider::Orientation Slider::getOrientation() const
289 {
290 return mOrientation;
291 }
292
293 double Slider::markerPositionToValue(int v) const
294 {
295 int w;
296 if (getOrientation() == HORIZONTAL)
297 {
298 w = getWidth();
299 }
300 else
301 {
302 w = getHeight();
303 }
304
305 double pos = v / ((double)w - getMarkerLength());
306 return (1.0 - pos) * getScaleStart() + pos * getScaleEnd();
307
308 }
309
310 int Slider::valueToMarkerPosition(double value) const
311 {
312 int v;
313 if (getOrientation() == HORIZONTAL)
314 {
315 v = getWidth();
316 }
317 else
318 {
319 v = getHeight();
320 }
321
322 int w = (int)((v - getMarkerLength())
323 * (value - getScaleStart())
324 / (getScaleEnd() - getScaleStart()));
325
326 if (w < 0)
327 {
328 return 0;
329 }
330
331 if (w > v - getMarkerLength())
332 {
333 return v - getMarkerLength();
334 }
335
336 return w;
337 }
338
339 void Slider::setStepLength(double length)
340 {
341 mStepLength = length;
342 }
343
344 double Slider::getStepLength() const
345 {
346 return mStepLength;
347 }
348
349 int Slider::getMarkerPosition() const
350 {
351 return valueToMarkerPosition(getValue());
352 }
353
354 void Slider::mouseWheelMovedUp(MouseEvent& mouseEvent)
355 {
356 setValue(getValue() + getStepLength());
357 distributeActionEvent();
358
359 mouseEvent.consume();
360 }
361
362 void Slider::mouseWheelMovedDown(MouseEvent& mouseEvent)
363 {
364 setValue(getValue() - getStepLength());
365 distributeActionEvent();
366
367 mouseEvent.consume();
368 }
369 }