____ _ __
/ __ )____ _____ | | / /___ ___________
/ __ / __ \/ ___/ | | /| / / __ `/ ___/ ___/
/ /_/ / /_/ (__ ) | |/ |/ / /_/ / / (__ )
/_____/\____/____/ |__/|__/\__,_/_/ /____/
A futuristic real-time strategy game.
This file is part of Bos Wars.
(C) Copyright 2001-2007 by the Bos Wars and Stratagus Project.
Distributed under the "GNU General Public License"00001 /* _______ __ __ __ ______ __ __ _______ __ __ 00002 * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\ 00003 * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / / 00004 * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / / 00005 * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / / 00006 * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ / 00007 * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/ 00008 * 00009 * Copyright (c) 2004, 2005 darkbits Js_./ 00010 * Per Larsson a.k.a finalman _RqZ{a<^_aa 00011 * Olof Naessén a.k.a jansem/yakslem _asww7!uY`> )\a// 00012 * _Qhm`] _f "'c 1!5m 00013 * Visit: http://guichan.darkbits.org )Qk<P ` _: :+' .' "{[ 00014 * .)j(] .d_/ '-( P . S 00015 * License: (BSD) <Td/Z <fP"5(\"??"\a. .L 00016 * Redistribution and use in source and _dV>ws?a-?' ._/L #' 00017 * binary forms, with or without )4d[#7r, . ' )d`)[ 00018 * modification, are permitted provided _Q-5'5W..j/?' -?!\)cam' 00019 * that the following conditions are met: j<<WP+k/);. _W=j f 00020 * 1. Redistributions of source code must .$%w\/]Q . ."' . mj$ 00021 * retain the above copyright notice, ]E.pYY(Q]>. a J@\ 00022 * this list of conditions and the j(]1u<sE"L,. . ./^ ]{a 00023 * following disclaimer. 4'_uomm\. )L);-4 (3= 00024 * 2. Redistributions in binary form must )_]X{Z('a_"a7'<a"a, ]"[ 00025 * reproduce the above copyright notice, #}<]m7`Za??4,P-"'7. ).m 00026 * this list of conditions and the ]d2e)Q(<Q( ?94 b- LQ/ 00027 * following disclaimer in the <B!</]C)d_, '(<' .f. =C+m 00028 * documentation and/or other materials .Z!=J ]e []('-4f _ ) -.)m]' 00029 * provided with the distribution. .w[5]' _[ /.)_-"+? _/ <W" 00030 * 3. Neither the name of Guichan nor the :$we` _! + _/ . j? 00031 * names of its contributors may be used =3)= _f (_yQmWW$#( " 00032 * to endorse or promote products derived - W, sQQQQmZQ#Wwa].. 00033 * from this software without specific (js, \[QQW$QWW#?!V"". 00034 * prior written permission. ]y:.<\.. . 00035 * -]n w/ ' [. 00036 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT )/ )/ ! 00037 * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY < (; sac , ' 00038 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, ]^ .- % 00039 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF c < r 00040 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR aga< <La 00041 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 5% )P'-3L 00042 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR _bQf` y`..)a 00043 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, ,J?4P'.P"_(\?d'., 00044 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES _Pa,)!f/<[]/ ?" 00045 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT _2-..:. .r+_,.. . 00046 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ?a.<%"' " -'.a_ _, 00047 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ^ 00048 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 00049 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00050 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 00051 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 00052 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00053 */ 00054 00055 /* 00056 * For comments regarding functions please see the header file. 00057 */ 00058 00059 #include "guichan/exception.h" 00060 #include "guichan/focushandler.h" 00061 #include "guichan/gui.h" 00062 #include "guichan/key.h" 00063 00064 namespace gcn 00065 { 00066 Gui::Gui() 00067 { 00068 mTop = NULL; 00069 mInput = NULL; 00070 mGraphics = NULL; 00071 mFocusHandler = new FocusHandler(); 00072 mTopHasMouse = false; 00073 mTabbing = true; 00074 mUseDirtyDrawing = true; 00075 } 00076 00077 Gui::~Gui() 00078 { 00079 if (Widget::widgetExists(mTop)) 00080 { 00081 setTop(NULL); 00082 } 00083 00084 delete mFocusHandler; 00085 } 00086 00087 void Gui::setTop(Widget* top) 00088 { 00089 if (mTop) 00090 { 00091 mTop->_setFocusHandler(NULL); 00092 } 00093 if (top) 00094 { 00095 top->_setFocusHandler(mFocusHandler); 00096 top->setDirty(true); 00097 } 00098 00099 mTop = top; 00100 } 00101 00102 Widget* Gui::getTop() const 00103 { 00104 return mTop; 00105 } 00106 00107 void Gui::setGraphics(Graphics* graphics) 00108 { 00109 mGraphics = graphics; 00110 } 00111 00112 Graphics* Gui::getGraphics() const 00113 { 00114 return mGraphics; 00115 } 00116 00117 void Gui::setInput(Input* input) 00118 { 00119 mInput = input; 00120 } 00121 00122 Input* Gui::getInput() const 00123 { 00124 return mInput; 00125 } 00126 00127 void Gui::logic() 00128 { 00129 if (!mTop) 00130 { 00131 throw GCN_EXCEPTION("No top widget set"); 00132 } 00133 00134 if (mInput) 00135 { 00136 mInput->_pollInput(); 00137 00138 while (!mInput->isMouseQueueEmpty()) 00139 { 00140 MouseInput mi = mInput->dequeueMouseInput(); 00141 00142 // Send mouse input to every widget that has the mouse. 00143 if (mi.x > 0 && mi.y > 0 00144 && mTop->getDimension().isPointInRect(mi.x, mi.y)) 00145 { 00146 if (!mTop->hasMouse()) 00147 { 00148 mTop->_mouseInMessage(); 00149 } 00150 00151 MouseInput mio = mi; 00152 mio.x -= mTop->getX(); 00153 mio.y -= mTop->getY(); 00154 mTop->_mouseInputMessage(mio); 00155 } 00156 else if (mTop->hasMouse()) 00157 { 00158 mTop->_mouseOutMessage(); 00159 } 00160 00161 Widget* f = mFocusHandler->getFocused(); 00162 Widget* d = mFocusHandler->getDragged(); 00163 00164 // If the focused widget doesn't have the mouse, 00165 // send the mouse input to the focused widget. 00166 if (f != NULL && !f->hasMouse()) 00167 { 00168 int xOffset, yOffset; 00169 f->getAbsolutePosition(xOffset, yOffset); 00170 00171 MouseInput mio = mi; 00172 mio.x -= xOffset; 00173 mio.y -= yOffset; 00174 00175 f->_mouseInputMessage(mio); 00176 } 00177 00178 // If the dragged widget is different from the focused 00179 // widget, send the mouse input to the dragged widget. 00180 if (d != NULL && d != f && !d->hasMouse()) 00181 { 00182 int xOffset, yOffset; 00183 d->getAbsolutePosition(xOffset, yOffset); 00184 00185 MouseInput mio = mi; 00186 mio.x -= xOffset; 00187 mio.y -= yOffset; 00188 00189 d->_mouseInputMessage(mio); 00190 } 00191 00192 mFocusHandler->applyChanges(); 00193 00194 } // end while 00195 00196 while (!mInput->isKeyQueueEmpty()) 00197 { 00198 KeyInput ki = mInput->dequeueKeyInput(); 00199 00200 if (mTabbing 00201 && ki.getKey().getValue() == Key::TAB 00202 && ki.getType() == KeyInput::PRESS) 00203 { 00204 if (ki.getKey().isShiftPressed()) 00205 { 00206 mFocusHandler->tabPrevious(); 00207 } 00208 else 00209 { 00210 mFocusHandler->tabNext(); 00211 } 00212 } 00213 else 00214 { 00215 bool keyProcessed = false; 00216 00217 // Send key inputs to the focused widgets 00218 if (mFocusHandler->getFocused()) 00219 { 00220 if (mFocusHandler->getFocused()->isFocusable()) 00221 { 00222 keyProcessed = mFocusHandler->getFocused()->_keyInputMessage(ki); 00223 } 00224 else 00225 { 00226 mFocusHandler->focusNone(); 00227 } 00228 } 00229 00230 if (!keyProcessed) 00231 { 00232 mFocusHandler->checkHotKey(ki); 00233 } 00234 } 00235 00236 mFocusHandler->applyChanges(); 00237 00238 } // end while 00239 00240 } // end if 00241 00242 mTop->logic(); 00243 } 00244 00245 void Gui::draw() 00246 { 00247 if (!mTop) 00248 { 00249 throw GCN_EXCEPTION("No top widget set"); 00250 } 00251 if (!mGraphics) 00252 { 00253 throw GCN_EXCEPTION("No graphics set"); 00254 } 00255 00256 if (!mUseDirtyDrawing || mTop->getDirty()) 00257 { 00258 mGraphics->_beginDraw(); 00259 00260 // If top has a border, 00261 // draw it before drawing top 00262 if (mTop->getBorderSize() > 0) 00263 { 00264 Rectangle rec = mTop->getDimension(); 00265 rec.x -= mTop->getBorderSize(); 00266 rec.y -= mTop->getBorderSize(); 00267 rec.width += 2 * mTop->getBorderSize(); 00268 rec.height += 2 * mTop->getBorderSize(); 00269 mGraphics->pushClipArea(rec); 00270 mTop->drawBorder(mGraphics); 00271 mGraphics->popClipArea(); 00272 } 00273 00274 mGraphics->pushClipArea(mTop->getDimension()); 00275 mTop->draw(mGraphics); 00276 mTop->setDirty(false); 00277 mGraphics->popClipArea(); 00278 00279 mGraphics->_endDraw(); 00280 } 00281 } 00282 00283 void Gui::focusNone() 00284 { 00285 mFocusHandler->focusNone(); 00286 } 00287 00288 void Gui::setTabbingEnabled(bool tabbing) 00289 { 00290 mTabbing = tabbing; 00291 } 00292 00293 bool Gui::isTabbingEnabled() 00294 { 00295 return mTabbing; 00296 } 00297 00298 void Gui::setUseDirtyDrawing(bool useDirtyDrawing) 00299 { 00300 mUseDirtyDrawing = useDirtyDrawing; 00301 } 00302 }
1.5.6