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/window.hpp" 49 50 #include "guichan/exception.hpp" 51 #include "guichan/font.hpp" 52 #include "guichan/graphics.hpp" 53 #include "guichan/mouseinput.hpp" 54 55 namespace gcn 56 { Window()57 Window::Window() 58 :mMoved(false) 59 { 60 setFrameSize(1); 61 setPadding(2); 62 setTitleBarHeight(16); 63 setAlignment(Graphics::CENTER); 64 addMouseListener(this); 65 setMovable(true); 66 setOpaque(true); 67 } 68 Window(const std::string & caption)69 Window::Window(const std::string& caption) 70 :mMoved(false) 71 { 72 setCaption(caption); 73 setFrameSize(1); 74 setPadding(2); 75 setTitleBarHeight(16); 76 setAlignment(Graphics::CENTER); 77 addMouseListener(this); 78 setMovable(true); 79 setOpaque(true); 80 } 81 ~Window()82 Window::~Window() 83 { 84 } 85 setPadding(unsigned int padding)86 void Window::setPadding(unsigned int padding) 87 { 88 mPadding = padding; 89 } 90 getPadding() const91 unsigned int Window::getPadding() const 92 { 93 return mPadding; 94 } 95 setTitleBarHeight(unsigned int height)96 void Window::setTitleBarHeight(unsigned int height) 97 { 98 mTitleBarHeight = height; 99 } 100 getTitleBarHeight()101 unsigned int Window::getTitleBarHeight() 102 { 103 return mTitleBarHeight; 104 } 105 setCaption(const std::string & caption)106 void Window::setCaption(const std::string& caption) 107 { 108 mCaption = caption; 109 } 110 getCaption() const111 const std::string& Window::getCaption() const 112 { 113 return mCaption; 114 } 115 setAlignment(Graphics::Alignment alignment)116 void Window::setAlignment(Graphics::Alignment alignment) 117 { 118 mAlignment = alignment; 119 } 120 getAlignment() const121 Graphics::Alignment Window::getAlignment() const 122 { 123 return mAlignment; 124 } 125 draw(Graphics * graphics)126 void Window::draw(Graphics* graphics) 127 { 128 Color faceColor = getBaseColor(); 129 Color highlightColor, shadowColor; 130 int alpha = getBaseColor().a; 131 int width = getWidth() + getFrameSize() * 2 - 1; 132 int height = getHeight() + getFrameSize() * 2 - 1; 133 highlightColor = faceColor + 0x303030; 134 highlightColor.a = alpha; 135 shadowColor = faceColor - 0x303030; 136 shadowColor.a = alpha; 137 138 Rectangle d = getChildrenArea(); 139 140 // Fill the background around the content 141 graphics->setColor(faceColor); 142 // Fill top 143 graphics->fillRectangle(Rectangle(0,0,getWidth(),d.y - 1)); 144 // Fill left 145 graphics->fillRectangle(Rectangle(0,d.y - 1, d.x - 1, getHeight() - d.y + 1)); 146 // Fill right 147 graphics->fillRectangle(Rectangle(d.x + d.width + 1, 148 d.y - 1, 149 getWidth() - d.x - d.width - 1, 150 getHeight() - d.y + 1)); 151 // Fill bottom 152 graphics->fillRectangle(Rectangle(d.x - 1, 153 d.y + d.height + 1, 154 d.width + 2, 155 getHeight() - d.height - d.y - 1)); 156 157 if (isOpaque()) 158 { 159 graphics->fillRectangle(d); 160 } 161 162 // Construct a rectangle one pixel bigger than the content 163 d.x -= 1; 164 d.y -= 1; 165 d.width += 2; 166 d.height += 2; 167 168 // Draw a border around the content 169 graphics->setColor(shadowColor); 170 // Top line 171 graphics->drawLine(d.x, 172 d.y, 173 d.x + d.width - 2, 174 d.y); 175 176 // Left line 177 graphics->drawLine(d.x, 178 d.y + 1, 179 d.x, 180 d.y + d.height - 1); 181 182 graphics->setColor(highlightColor); 183 // Right line 184 graphics->drawLine(d.x + d.width - 1, 185 d.y, 186 d.x + d.width - 1, 187 d.y + d.height - 2); 188 // Bottom line 189 graphics->drawLine(d.x + 1, 190 d.y + d.height - 1, 191 d.x + d.width - 1, 192 d.y + d.height - 1); 193 194 drawChildren(graphics); 195 196 int textX; 197 int textY; 198 199 textY = ((int)getTitleBarHeight() - getFont()->getHeight()) / 2; 200 201 switch (getAlignment()) 202 { 203 case Graphics::LEFT: 204 textX = 4; 205 break; 206 case Graphics::CENTER: 207 textX = getWidth() / 2; 208 break; 209 case Graphics::RIGHT: 210 textX = getWidth() - 4; 211 break; 212 default: 213 throw GCN_EXCEPTION("Unknown alignment."); 214 } 215 216 graphics->setColor(getForegroundColor()); 217 graphics->setFont(getFont()); 218 graphics->pushClipArea(Rectangle(0, 0, getWidth(), getTitleBarHeight() - 1)); 219 graphics->drawText(getCaption(), textX, textY, getAlignment()); 220 graphics->popClipArea(); 221 } 222 mousePressed(MouseEvent & mouseEvent)223 void Window::mousePressed(MouseEvent& mouseEvent) 224 { 225 if (mouseEvent.getSource() != this) 226 { 227 return; 228 } 229 230 if (getParent() != NULL) 231 { 232 getParent()->moveToTop(this); 233 } 234 235 mDragOffsetX = mouseEvent.getX(); 236 mDragOffsetY = mouseEvent.getY(); 237 238 mMoved = mouseEvent.getY() <= (int)mTitleBarHeight; 239 } 240 mouseReleased(MouseEvent & mouseEvent)241 void Window::mouseReleased(MouseEvent& mouseEvent) 242 { 243 mMoved = false; 244 } 245 mouseDragged(MouseEvent & mouseEvent)246 void Window::mouseDragged(MouseEvent& mouseEvent) 247 { 248 if (mouseEvent.isConsumed() || mouseEvent.getSource() != this) 249 { 250 return; 251 } 252 253 if (isMovable() && mMoved) 254 { 255 setPosition(mouseEvent.getX() - mDragOffsetX + getX(), 256 mouseEvent.getY() - mDragOffsetY + getY()); 257 } 258 259 mouseEvent.consume(); 260 } 261 getChildrenArea()262 Rectangle Window::getChildrenArea() 263 { 264 return Rectangle(getPadding(), 265 getTitleBarHeight(), 266 getWidth() - getPadding() * 2, 267 getHeight() - getPadding() - getTitleBarHeight()); 268 } 269 setMovable(bool movable)270 void Window::setMovable(bool movable) 271 { 272 mMovable = movable; 273 } 274 isMovable() const275 bool Window::isMovable() const 276 { 277 return mMovable; 278 } 279 setOpaque(bool opaque)280 void Window::setOpaque(bool opaque) 281 { 282 mOpaque = opaque; 283 } 284 isOpaque()285 bool Window::isOpaque() 286 { 287 return mOpaque; 288 } 289 resizeToContent()290 void Window::resizeToContent() 291 { 292 WidgetListIterator it; 293 294 int w = 0, h = 0; 295 for (it = mWidgets.begin(); it != mWidgets.end(); it++) 296 { 297 if ((*it)->getX() + (*it)->getWidth() > w) 298 { 299 w = (*it)->getX() + (*it)->getWidth(); 300 } 301 302 if ((*it)->getY() + (*it)->getHeight() > h) 303 { 304 h = (*it)->getY() + (*it)->getHeight(); 305 } 306 } 307 308 setSize(w + 2* getPadding(), h + getPadding() + getTitleBarHeight()); 309 } 310 } 311