comparison ext/guichan-0.8.2/src/widgets/slider.cpp @ 378:64738befdf3b

bringing in the changes from the build_system_rework branch in preparation for the 0.3.0 release. This commit will require the Jan2010 devkit. Clients will also need to be modified to the new way to import fife.
author vtchill@33b003aa-7bff-0310-803a-e67f0ece8222
date Mon, 11 Jan 2010 23:34:52 +0000
parents
children
comparison
equal deleted inserted replaced
377:fe6fb0e0ed23 378:64738befdf3b
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 }