comparison ext/guichan-0.8.2/src/widgets/button.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/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 }