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 const Color &faceColor = getBaseColor(); 129 Color highlightColor, shadowColor; 130 const int alpha = getBaseColor().a; 131 highlightColor = faceColor + 0x303030; 132 highlightColor.a = alpha; 133 shadowColor = faceColor - 0x303030; 134 shadowColor.a = alpha; 135 136 Rectangle d = getChildrenArea(); 137 138 // Fill the background around the content 139 graphics->setColor(faceColor); 140 // Fill top 141 graphics->fillRectangle(Rectangle(0,0,getWidth(),d.y - 1)); 142 // Fill left 143 graphics->fillRectangle(Rectangle(0,d.y - 1, d.x - 1, getHeight() - d.y + 1)); 144 // Fill right 145 graphics->fillRectangle(Rectangle(d.x + d.width + 1, 146 d.y - 1, 147 getWidth() - d.x - d.width - 1, 148 getHeight() - d.y + 1)); 149 // Fill bottom 150 graphics->fillRectangle(Rectangle(d.x - 1, 151 d.y + d.height + 1, 152 d.width + 2, 153 getHeight() - d.height - d.y - 1)); 154 155 if (isOpaque()) 156 { 157 graphics->fillRectangle(d); 158 } 159 160 // Construct a rectangle one pixel bigger than the content 161 d.x -= 1; 162 d.y -= 1; 163 d.width += 2; 164 d.height += 2; 165 166 // Draw a border around the content 167 graphics->setColor(shadowColor); 168 // Top line 169 graphics->drawLine(d.x, 170 d.y, 171 d.x + d.width - 2, 172 d.y); 173 174 // Left line 175 graphics->drawLine(d.x, 176 d.y + 1, 177 d.x, 178 d.y + d.height - 1); 179 180 graphics->setColor(highlightColor); 181 // Right line 182 graphics->drawLine(d.x + d.width - 1, 183 d.y, 184 d.x + d.width - 1, 185 d.y + d.height - 2); 186 // Bottom line 187 graphics->drawLine(d.x + 1, 188 d.y + d.height - 1, 189 d.x + d.width - 1, 190 d.y + d.height - 1); 191 192 drawChildren(graphics); 193 194 int textX; 195 int textY; 196 197 textY = ((int)getTitleBarHeight() - getFont()->getHeight()) / 2; 198 199 switch (getAlignment()) 200 { 201 case Graphics::LEFT: 202 textX = 4; 203 break; 204 case Graphics::CENTER: 205 textX = getWidth() / 2; 206 break; 207 case Graphics::RIGHT: 208 textX = getWidth() - 4; 209 break; 210 default: 211 throw GCN_EXCEPTION("Unknown alignment."); 212 } 213 214 graphics->setColor(getForegroundColor()); 215 graphics->setFont(getFont()); 216 graphics->pushClipArea(Rectangle(0, 0, getWidth(), getTitleBarHeight() - 1)); 217 graphics->drawText(getCaption(), textX, textY, getAlignment()); 218 graphics->popClipArea(); 219 } 220 mousePressed(MouseEvent & mouseEvent)221 void Window::mousePressed(MouseEvent& mouseEvent) 222 { 223 if (mouseEvent.getSource() != this) 224 { 225 return; 226 } 227 228 if (getParent() != NULL) 229 { 230 getParent()->moveToTop(this); 231 } 232 233 mDragOffsetX = mouseEvent.getX(); 234 mDragOffsetY = mouseEvent.getY(); 235 236 mMoved = mouseEvent.getY() <= (int)mTitleBarHeight; 237 } 238 mouseReleased(MouseEvent & mouseEvent)239 void Window::mouseReleased(MouseEvent& mouseEvent) 240 { 241 mMoved = false; 242 } 243 mouseDragged(MouseEvent & mouseEvent)244 void Window::mouseDragged(MouseEvent& mouseEvent) 245 { 246 if (mouseEvent.isConsumed() || mouseEvent.getSource() != this) 247 { 248 return; 249 } 250 251 if (isMovable() && mMoved) 252 { 253 setPosition(mouseEvent.getX() - mDragOffsetX + getX(), 254 mouseEvent.getY() - mDragOffsetY + getY()); 255 } 256 257 mouseEvent.consume(); 258 } 259 getChildrenArea()260 Rectangle Window::getChildrenArea() 261 { 262 return Rectangle(getPadding(), 263 getTitleBarHeight(), 264 getWidth() - getPadding() * 2, 265 getHeight() - getPadding() - getTitleBarHeight()); 266 } 267 setMovable(bool movable)268 void Window::setMovable(bool movable) 269 { 270 mMovable = movable; 271 } 272 isMovable() const273 bool Window::isMovable() const 274 { 275 return mMovable; 276 } 277 setOpaque(bool opaque)278 void Window::setOpaque(bool opaque) 279 { 280 mOpaque = opaque; 281 } 282 isOpaque()283 bool Window::isOpaque() 284 { 285 return mOpaque; 286 } 287 resizeToContent()288 void Window::resizeToContent() 289 { 290 WidgetListIterator it; 291 292 int w = 0, h = 0; 293 for (it = mWidgets.begin(); it != mWidgets.end(); it++) 294 { 295 if ((*it)->getX() + (*it)->getWidth() > w) 296 { 297 w = (*it)->getX() + (*it)->getWidth(); 298 } 299 300 if ((*it)->getY() + (*it)->getHeight() > h) 301 { 302 h = (*it)->getY() + (*it)->getHeight(); 303 } 304 } 305 306 setSize(w + 2* getPadding(), h + getPadding() + getTitleBarHeight()); 307 } 308 } 309