comparison ext/guichan-0.8.1/src/widgets/button.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/button.hpp"
49
50 #include "guichan/exception.hpp"
51 #include "guichan/font.hpp"
52 #include "guichan/graphics.hpp"
53 #include "guichan/key.hpp"
54 #include "guichan/mouseevent.hpp"
55 #include "guichan/mouseinput.hpp"
56
57 namespace gcn
58 {
59 Button::Button()
60 : mHasMouse(false),
61 mKeyPressed(false),
62 mMousePressed(false),
63 mAlignment(Graphics::CENTER),
64 mSpacing(4)
65 {
66 setFocusable(true);
67 adjustSize();
68 setFrameSize(1);
69
70 addMouseListener(this);
71 addKeyListener(this);
72 addFocusListener(this);
73 }
74
75 Button::Button(const std::string& caption)
76 : mCaption(caption),
77 mHasMouse(false),
78 mKeyPressed(false),
79 mMousePressed(false),
80 mAlignment(Graphics::CENTER),
81 mSpacing(4)
82 {
83 setFocusable(true);
84 adjustSize();
85 setFrameSize(1);
86
87 addMouseListener(this);
88 addKeyListener(this);
89 addFocusListener(this);
90 }
91
92 void Button::setCaption(const std::string& caption)
93 {
94 mCaption = caption;
95 }
96
97 const std::string& Button::getCaption() const
98 {
99 return mCaption;
100 }
101
102 void Button::setAlignment(Graphics::Alignment alignment)
103 {
104 mAlignment = alignment;
105 }
106
107 Graphics::Alignment Button::getAlignment() const
108 {
109 return mAlignment;
110 }
111
112 void Button::setSpacing(unsigned int spacing)
113 {
114 mSpacing = spacing;
115 }
116
117 unsigned int Button::getSpacing() const
118 {
119 return mSpacing;
120 }
121
122 void Button::draw(Graphics* graphics)
123 {
124 Color faceColor = getBaseColor();
125 Color highlightColor, shadowColor;
126 int alpha = getBaseColor().a;
127
128 if (isPressed())
129 {
130 faceColor = faceColor - 0x303030;
131 faceColor.a = alpha;
132 highlightColor = faceColor - 0x303030;
133 highlightColor.a = alpha;
134 shadowColor = faceColor + 0x303030;
135 shadowColor.a = alpha;
136 }
137 else
138 {
139 highlightColor = faceColor + 0x303030;
140 highlightColor.a = alpha;
141 shadowColor = faceColor - 0x303030;
142 shadowColor.a = alpha;
143 }
144
145 graphics->setColor(faceColor);
146 graphics->fillRectangle(Rectangle(1, 1, getDimension().width-1, getHeight() - 1));
147
148 graphics->setColor(highlightColor);
149 graphics->drawLine(0, 0, getWidth() - 1, 0);
150 graphics->drawLine(0, 1, 0, getHeight() - 1);
151
152 graphics->setColor(shadowColor);
153 graphics->drawLine(getWidth() - 1, 1, getWidth() - 1, getHeight() - 1);
154 graphics->drawLine(1, getHeight() - 1, getWidth() - 1, getHeight() - 1);
155
156 graphics->setColor(getForegroundColor());
157
158 int textX;
159 int textY = getHeight() / 2 - getFont()->getHeight() / 2;
160
161 switch (getAlignment())
162 {
163 case Graphics::LEFT:
164 textX = mSpacing;
165 break;
166 case Graphics::CENTER:
167 textX = getWidth() / 2;
168 break;
169 case Graphics::RIGHT:
170 textX = getWidth() - mSpacing;
171 break;
172 default:
173 throw GCN_EXCEPTION("Unknown alignment.");
174 }
175
176 graphics->setFont(getFont());
177
178 if (isPressed())
179 {
180 graphics->drawText(getCaption(), textX + 1, textY + 1, getAlignment());
181 }
182 else
183 {
184 graphics->drawText(getCaption(), textX, textY, getAlignment());
185
186 if (isFocused())
187 {
188 graphics->drawRectangle(Rectangle(2, 2, getWidth() - 4,
189 getHeight() - 4));
190 }
191 }
192 }
193
194 void Button::adjustSize()
195 {
196 setWidth(getFont()->getWidth(mCaption) + 2*mSpacing);
197 setHeight(getFont()->getHeight() + 2*mSpacing);
198 }
199
200 bool Button::isPressed() const
201 {
202 if (mMousePressed)
203 {
204 return mHasMouse;
205 }
206 else
207 {
208 return mKeyPressed;
209 }
210 }
211
212 void Button::mousePressed(MouseEvent& mouseEvent)
213 {
214 if (mouseEvent.getButton() == MouseEvent::LEFT)
215 {
216 mMousePressed = true;
217 mouseEvent.consume();
218 }
219 }
220
221 void Button::mouseExited(MouseEvent& mouseEvent)
222 {
223 mHasMouse = false;
224 }
225
226 void Button::mouseEntered(MouseEvent& mouseEvent)
227 {
228 mHasMouse = true;
229 }
230
231 void Button::mouseReleased(MouseEvent& mouseEvent)
232 {
233 if (mouseEvent.getButton() == MouseEvent::LEFT
234 && mMousePressed
235 && mHasMouse)
236 {
237 mMousePressed = false;
238 distributeActionEvent();
239 mouseEvent.consume();
240 }
241 else if (mouseEvent.getButton() == MouseEvent::LEFT)
242 {
243 mMousePressed = false;
244 mouseEvent.consume();
245 }
246 }
247
248 void Button::mouseDragged(MouseEvent& mouseEvent)
249 {
250 mouseEvent.consume();
251 }
252
253 void Button::keyPressed(KeyEvent& keyEvent)
254 {
255 Key key = keyEvent.getKey();
256
257 if (key.getValue() == Key::ENTER
258 || key.getValue() == Key::SPACE)
259 {
260 mKeyPressed = true;
261 keyEvent.consume();
262 }
263 }
264
265 void Button::keyReleased(KeyEvent& keyEvent)
266 {
267 Key key = keyEvent.getKey();
268
269 if ((key.getValue() == Key::ENTER
270 || key.getValue() == Key::SPACE)
271 && mKeyPressed)
272 {
273 mKeyPressed = false;
274 distributeActionEvent();
275 keyEvent.consume();
276 }
277 }
278
279 void Button::focusLost(const Event& event)
280 {
281 mMousePressed = false;
282 mKeyPressed = false;
283 }
284 }