GLWWindow.cpp

Go to the documentation of this file.
00001 ////////////////////////////////////////////////////////////////////////////////
00002 //    Scorched3D (c) 2000-2009
00003 //
00004 //    This file is part of Scorched3D.
00005 //
00006 //    Scorched3D is free software; you can redistribute it and/or modify
00007 //    it under the terms of the GNU General Public License as published by
00008 //    the Free Software Foundation; either version 2 of the License, or
00009 //    (at your option) any later version.
00010 //
00011 //    Scorched3D is distributed in the hope that it will be useful,
00012 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 //    GNU General Public License for more details.
00015 //
00016 //    You should have received a copy of the GNU General Public License
00017 //    along with Scorched3D; if not, write to the Free Software
00018 //    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 ////////////////////////////////////////////////////////////////////////////////
00020 
00021 #include <GLEXT/GLState.h>
00022 #include <GLEXT/GLTexture.h>
00023 #include <GLEXT/GLViewPort.h>
00024 #include <image/ImageFactory.h>
00025 #include <XML/XMLParser.h>
00026 #include <GLW/GLWWindow.h>
00027 #include <GLW/GLWWindowManager.h>
00028 #include <client/ScorchedClient.h>
00029 #include <common/Defines.h>
00030 #include <graph/OptionsDisplay.h>
00031 #include <lang/LangResource.h>
00032 
00033 static const float roundSize = 20.0f;
00034 static const float smallRoundSize = 10.0f;
00035 static const float smallTitleHeight = 14.0f;
00036 static const float minWindowSize = 50.0f;
00037 static const float titleWidth = 100.0f;
00038 static const float titleHeight = 20.0f;
00039 static const float shadowWidth = 10.0f;
00040 
00041 GLTexture GLWWindow::moveTexture_;
00042 
00043 GLWWindow::GLWWindow(const std::string &name, float x, float y, 
00044                                          float w, float h,
00045                                          unsigned int states,
00046                                          const std::string &description) : 
00047         GLWPanel(x, y, w, h), dragging_(NoDrag), 
00048         needCentered_(false), showTitle_(false), 
00049         disabled_(false), windowState_(states), maxWindowSize_(0.0f),
00050         description_(description), toolTip_(ToolTip::ToolTipHelp, 
00051         LANG_RESOURCE(name, name), LANG_RESOURCE(name + "_window", description)),
00052         initPosition_(false), windowLevel_(100000)
00053 {
00054         setName(name);
00055         getDrawPanel() = false;
00056 }
00057 
00058 GLWWindow::GLWWindow(const std::string &name, float w, float h,
00059                                          unsigned int states,
00060                                          const std::string &description) :
00061         GLWPanel(0.0f, 0.0f, w, h), dragging_(NoDrag), 
00062         needCentered_(true), showTitle_(false), 
00063         disabled_(false), windowState_(states),
00064         description_(description), toolTip_(ToolTip::ToolTipHelp, 
00065         LANG_RESOURCE(name, name), LANG_RESOURCE(name + "_window", description)),
00066         initPosition_(false), windowLevel_(100000)
00067 {
00068         setName(name);
00069         getDrawPanel() = false;
00070 }
00071 
00072 GLWWindow::~GLWWindow()
00073 {
00074 
00075 }
00076 
00077 void GLWWindow::windowInit(const unsigned state)
00078 {
00079 
00080 }
00081 
00082 void GLWWindow::drawOutlinePoints(float x, float y, float w, float h)
00083 {
00084         float tw = titleWidth;
00085         if (w < titleWidth + 25.0f) tw = w - 25.0f;
00086 
00087         float th = titleHeight;
00088         float sr = roundSize;
00089         float sz = 20.0f;
00090         if (windowState_ & eSmallTitle)
00091         {
00092                 th = smallTitleHeight;
00093                 sr = smallRoundSize;
00094                 sz = 10.0f;
00095         }
00096 
00097         if (windowState_ & eResizeable)
00098                 drawCircle(8, 4, x + w - smallRoundSize, y + smallRoundSize, 10.0f);
00099         else
00100                 drawCircle(8, 4, x + w - roundSize, y + roundSize, 20.0f);
00101         drawCircle(4, 0, x + w - roundSize, y + h - roundSize, 20.0f);
00102         if (((tw > 70.0f) || (tw > 50.0f && windowState_ & eSmallTitle)) && 
00103                 !(windowState_ & eNoTitle))
00104         {
00105                 showTitle_ = true;
00106                 drawCircle(8, 10, x + tw, y + h + sr, sz);
00107                 drawCircle(2, 0, x + tw - sr - sr, y + h + th - sr, sz);
00108                 drawCircle(0, -4, x + roundSize, y + h + th - roundSize, 20.0f);
00109         }
00110         else
00111         {
00112                 showTitle_ = false;
00113                 drawCircle(0, -4, x + roundSize, y + h - roundSize, 20.0f);
00114         }
00115         drawCircle(-4, -8, x + roundSize, y + roundSize, 20.0f);
00116 }
00117 
00118 void GLWWindow::drawBackSurface(float x, float y, float w, float h)
00119 {
00120         glBegin(GL_TRIANGLE_FAN);
00121                 glVertex2f(x + roundSize, y + roundSize);
00122                 glVertex2f(x + roundSize, y);
00123                 drawOutlinePoints(x, y, w, h);
00124                 glVertex2f(x + roundSize, y);
00125         glEnd();
00126 }
00127 
00128 void GLWWindow::drawSurround(float x, float y, float w, float h)
00129 {
00130         glBegin(GL_LINE_LOOP);
00131                 drawOutlinePoints(x, y, w, h);
00132         glEnd();
00133 }
00134 
00135 void GLWWindow::drawTitleBar(float x, float y, float w, float h)
00136 {
00137         // Draw the indented lines in the header
00138         glBegin(GL_LINES);
00139                 for (int i=0; i<=8; i+=4)
00140                 {
00141                         float top = y + h + titleHeight - i - 6.0f;
00142 
00143                         glColor3f(0.4f, 0.4f, 0.6f);
00144                         glVertex2f(x + 10.0f, top);
00145                         glVertex2f(x + titleWidth - 32.0f, top);
00146                         glColor3f(1.0f, 1.0f, 1.0f);
00147                         glVertex2f(x + 10.0f, top - 1.0f);
00148                         glVertex2f(x + titleWidth - 32.0f, top - 1.0f);
00149                 }
00150         glEnd();
00151 }
00152 
00153 void GLWWindow::drawWindowCircle(float x, float y, float w, float h)
00154 {
00155         glColor4f(0.5f, 0.5f, 1.0f, 0.3f);      
00156         float halfWidth = w / 2.0f;
00157         float halfHeight = h / 2.0f;
00158         glPushMatrix();
00159                 glTranslatef(x + halfWidth, y + halfHeight, 0.0f);
00160                 glScalef(halfWidth, halfHeight, 0.0f);
00161                 glBegin(GL_TRIANGLE_FAN);
00162                         glVertex2f(0.0f, 0.0f);
00163                         drawWholeCircle(true);
00164                 glEnd();
00165                 glColor4f(0.9f, 0.9f, 1.0f, 0.5f);
00166                 glLineWidth(2.0f);
00167                 glBegin(GL_LINE_LOOP);
00168                         drawWholeCircle(false);
00169                 glEnd();
00170                 glLineWidth(1.0f);
00171         glPopMatrix();
00172 }
00173 
00174 void GLWWindow::drawMaximizedWindow()
00175 {
00176         if (windowState_ & eCircle ||
00177                 windowState_ & eNoDraw)
00178         {
00179                 static bool createdTexture = false;
00180                 if (!createdTexture)
00181                 {
00182                         createdTexture = true;
00183 
00184                         ImageHandle moveMap = ImageFactory::loadAlphaImageHandle(
00185                                 S3D::getDataFile("data/windows/move.bmp"));
00186                         moveTexture_.create(moveMap, false);
00187                 }
00188 
00189                 if (windowState_ & eCircle)
00190                 {
00191                         GLState state(GLState::BLEND_ON);
00192                         drawWindowCircle(x_, y_, w_, h_);
00193                 }
00194 
00195                 glPushMatrix();
00196                         GLWPanel::draw();
00197                 glPopMatrix();
00198 
00199                 int x = ScorchedClient::instance()->getGameState().getMouseX();
00200                 int y = ScorchedClient::instance()->getGameState().getMouseY();
00201                 if (GLWWindowManager::instance()->getFocus(x, y) == getId())
00202                 {
00203                         if (windowState_ & eResizeable &&
00204                                 windowState_ & eCircle)
00205                         {
00206                                 drawWindowCircle(x_ + w_ - 12.0f, y_, 12.0f, 12.0f);
00207                         }
00208                         if (!(windowState_ & eNoMove) && !(windowState_ & eNoTitle) && !disabled_)
00209                         {
00210                                 float sizeX = 20.0f;
00211                                 float sizeY = 20.0f;
00212 
00213                                 static ToolTip moveTip(ToolTip::ToolTipHelp, 
00214                                         LANG_RESOURCE("WINDOW_MOVE", "Move Window"),
00215                                         LANG_RESOURCE("WINDOW_MOVE_TOOLTIP", "Left click and drag to move the window."));
00216                                 GLWToolTip::instance()->addToolTip(&moveTip, 
00217                                         x_, y_ + h_ - sizeY, sizeX, sizeY);
00218 
00219                                 GLState currentStateBlend(GLState::BLEND_ON | GLState::TEXTURE_ON);
00220                                 moveTexture_.draw();
00221                                 glColor4f(0.8f, 0.0f, 0.0f, 0.8f);
00222                                 glPushMatrix();
00223                                         glTranslatef(x_, y_ + h_ - sizeY, 0.0f);
00224                                         glScalef(sizeX / 16.0f, sizeY / 16.0f, 1.0f);
00225                                         drawIconBox(0.0f, 0.0f);
00226                                 glPopMatrix();
00227                         }
00228                 }
00229         }
00230         else if (windowState_ & eTransparent || windowState_ & eSemiTransparent)
00231         {
00232                 {
00233                         glPushMatrix();
00234                                 glTranslatef(0.0f, 0.0f, 0.0f);
00235                                 {
00236                                         GLState currentStateBlend(GLState::BLEND_ON);
00237                                         glColor4f(0.4f, 0.6f, 0.8f, 
00238                                                 ((windowState_ & eTransparent)?0.8f:0.8f));
00239                                         drawBackSurface(x_, y_, w_, h_);
00240                                 }
00241                                 glLineWidth(2.0f);
00242                                 glColor4f(0.0f, 0.0f, 0.0f, 
00243                                         ((windowState_ & eTransparent)?1.0f:1.0f));
00244                                 drawSurround(x_, y_, w_, h_);
00245                                 glLineWidth(1.0f);
00246                         glPopMatrix();
00247                 }
00248 
00249                 glPushMatrix();
00250                         GLWPanel::draw();
00251                 glPopMatrix();
00252         }
00253         else
00254         {
00255                 GLState currentStateBlend(GLState::BLEND_ON);
00256                 {
00257                         glColor3f(0.8f, 0.8f, 1.0f);
00258                         drawBackSurface(x_, y_, w_, h_);
00259                 }
00260                 if (showTitle_ && !(windowState_ & eSmallTitle)) drawTitleBar(x_, y_, w_, h_);
00261                 glLineWidth(2.0f);
00262                 glColor3f(0.0f, 0.0f, 0.0f);
00263                 drawSurround(x_, y_, w_, h_);
00264                 glLineWidth(1.0f);
00265 
00266                 glPushMatrix();
00267                         GLWPanel::draw();
00268                 glPopMatrix();
00269         }
00270 }
00271 
00272 void GLWWindow::draw()
00273 {
00274         unsigned int state = GLState::DEPTH_OFF | GLState::TEXTURE_OFF;
00275         if (OptionsDisplay::instance()->getSmoothLines())
00276         {
00277                 state |= GLState::BLEND_ON;
00278                 glEnable(GL_LINE_SMOOTH);
00279         }
00280         GLState currentState(state);
00281 
00282         if (!initPosition_)
00283         {
00284                 if (x_ < 0.0f) setX(GLViewPort::getWidth() + x_);
00285                 if (y_ < 0.0f) setY(GLViewPort::getHeight() + y_);
00286                 if (w_ < 0.0f) setW(GLViewPort::getWidth() + w_);
00287                 if (h_ < 0.0f) setH(GLViewPort::getHeight() + h_);
00288 
00289                 initPosition_ = true;
00290         }
00291         if (needCentered_)
00292         {
00293                 int wWidth = GLViewPort::getWidth();
00294                 int wHeight = GLViewPort::getHeight();
00295                 setX((wWidth - getW()) / 2.0f);
00296                 setY((wHeight - getH()) / 2.0f);
00297                 needCentered_ = false;
00298         }
00299 
00300         drawMaximizedWindow();
00301 
00302         if (OptionsDisplay::instance()->getSmoothLines())
00303         {
00304                 glDisable(GL_LINE_SMOOTH);
00305         }
00306 }
00307 
00308 void GLWWindow::mouseDown(int button, float x, float y, bool &skipRest)
00309 {
00310         if (disabled_) return;
00311 
00312         if (x > x_ && x < x_ + w_)
00313         {
00314                 if (windowState_ & eCircle ||
00315                         windowState_ & eNoDraw)
00316                 {
00317                         float sizeX = w_ / 5.6f;
00318                         float sizeY = w_ / 5.6f;
00319                         if (x < x_ + sizeX &&
00320                                 y < y_ + h_ &&
00321                                 y > y_ + h_ - sizeY &&
00322                                 !(eNoMove & windowState_))
00323                         {
00324                                 // Start window drag
00325                                 dragging_ = TitleDrag;
00326                                 skipRest = !(eClickTransparent & windowState_) || skipRest;
00327                         }
00328                         else if (y > y_ && y < y_ + h_)
00329                         {
00330                                 // There is a mouse down in the actual window
00331                                 GLWPanel::mouseDown(button, x, y, skipRest);
00332                                 skipRest = !(eClickTransparent & windowState_) || skipRest;
00333                         }
00334                 }
00335                 else
00336                 {
00337                         float th = titleHeight;
00338                         if (windowState_ & eSmallTitle) th = smallTitleHeight;
00339                         if (y > y_ + h_ && y < y_ + h_ + th && showTitle_ && x < x_ + titleWidth &&
00340                                 !(eNoMove & windowState_))
00341                         {
00342                                 // Start window drag
00343                                 dragging_ = TitleDrag;
00344                                 skipRest = !(eClickTransparent & windowState_) || skipRest;
00345                         }
00346                         else
00347                         {
00348                                 if ((windowState_ & eResizeable) && 
00349                                         inBox(x, y, x_ + w_ - 12.0f, y_, 12.0f, 12.0f))
00350                                 {
00351                                         // Start resize window drag
00352                                         dragging_ = SizeDrag;
00353                                         skipRest = !(eClickTransparent & windowState_) || skipRest;
00354                                 }
00355                                 else if (y > y_ && y < y_ + h_)
00356                                 {
00357                                         // There is a mouse down in the actual window
00358                                         GLWPanel::mouseDown(button, x, y, skipRest);
00359                                         skipRest = !(eClickTransparent & windowState_) || skipRest;
00360                                 }
00361                         }       
00362                 }
00363         }
00364 }
00365 
00366 void GLWWindow::mouseUp(int button, float x, float y, bool &skipRest)
00367 {
00368         if (disabled_) return;
00369 
00370         dragging_ = NoDrag;
00371         GLWPanel::mouseUp(button, x, y, skipRest);
00372 }
00373 
00374 void GLWWindow::mouseDrag(int button, float mx, float my, float x, float y, bool &skipRest)
00375 {
00376         if (disabled_) return;
00377 
00378         switch(dragging_)
00379         {
00380         case TitleDrag:
00381                 if (x_ + x > 0.0f && y_ - y + h_ - 20.0f > 0 && 
00382                         x_ + x + 50.0f < GLViewPort::getWidth() &&
00383                         y_ - y + h_ + 20.0f < GLViewPort::getHeight())
00384                 {
00385                         x_ += x;
00386                         y_ -= y;
00387                 }
00388                 skipRest = true;
00389                 break;
00390         case SizeDrag:
00391                 if (w_ + x > minWindowSize &&
00392                         (maxWindowSize_ == 0.0f || w_ + x < maxWindowSize_))
00393                 {
00394                         w_ += x;
00395                 }
00396                 if (h_ + y > minWindowSize &&
00397                         (maxWindowSize_ == 0.0f || h_ + y < maxWindowSize_))
00398                 {
00399                         h_ += y;
00400                         y_ -= y;
00401                 }
00402 
00403                 skipRest = true;
00404                 break;
00405         default:
00406                 GLWPanel::mouseDrag(button, mx, my, x, -y, skipRest);
00407                 break;
00408         }
00409 }
00410 
00411 void GLWWindow::mouseWheel(float x, float y, float z, bool &skipRest)
00412 {
00413         if (disabled_) return;
00414 
00415         GLWPanel::mouseWheel(x, y, z, skipRest);
00416 }
00417 
00418 void GLWWindow::keyDown(char *buffer, unsigned int keyState, 
00419                 KeyboardHistory::HistoryElement *history, int hisCount, 
00420                 bool &skipRest)
00421 {
00422         if (disabled_) return;
00423 
00424         GLWPanel::keyDown(buffer, keyState, history, hisCount, skipRest);
00425 }
00426 
00427 void GLWWindow::drawInfoBox(float x, float y, float w)
00428 {
00429         glColor4f(0.5f, 0.5f, 1.0f, 0.3f);      
00430         glBegin(GL_TRIANGLE_FAN);
00431                 glVertex2f(x + 20.0f, y - 8.0f);
00432                 glVertex2f(x + 20.0f, y - 18.0f);
00433                 drawRoundBox(x, y - 18.0f, w, 18.0f, 9.0f);
00434                 glVertex2f(x + 20.0f, y - 18.0f);
00435         glEnd();
00436 
00437         glColor4f(0.9f, 0.9f, 1.0f, 0.5f);
00438         glLineWidth(2.0f);
00439         glBegin(GL_LINE_LOOP);
00440                 drawRoundBox(x, y - 18.0f, w, 18.0f, 9.0f);
00441         glEnd();
00442         glLineWidth(1.0f);
00443 }
00444 
00445 void GLWWindow::drawJoin(float x, float y)
00446 {
00447         glColor4f(0.8f, 0.8f, 0.9f, 0.8f);
00448         glPushMatrix();
00449                 glTranslatef(x, y, 0.0f);
00450                 glScalef(3.0f, 3.0f, 3.0f);
00451                 glBegin(GL_TRIANGLE_FAN);
00452                         drawWholeCircle(true);
00453                 glEnd();
00454         glPopMatrix();
00455 }
00456 
00457 void GLWWindow::drawIconBox(float x, float y)
00458 {
00459         glBegin(GL_QUADS);
00460                 glTexCoord2f(0.0f, 0.0f);
00461                 glVertex2f(x, y);
00462                 glTexCoord2f(1.0f, 0.0f);
00463                 glVertex2f(x + 16.0f, y);
00464                 glTexCoord2f(1.0f, 1.0f);
00465                 glVertex2f(x + 16.0f, y + 16.0f);
00466                 glTexCoord2f(0.0f, 1.0f);
00467                 glVertex2f(x, y + 16.0f);
00468         glEnd();
00469 }
00470 
00471 bool GLWWindow::initFromXML(XMLNode *node)
00472 {
00473         if (!GLWPanel::initFromXML(node)) return false;
00474 
00475         if (name_.c_str()[0] == 0)
00476         {
00477                 // Get name again, just to display the error message
00478                 if (!node->getNamedChild("name", name_)) return false;
00479         }
00480 
00481         bool noTooltip = false;
00482         node->getNamedChild("notooltip", noTooltip, false);
00483 
00484         // Desc
00485         if (!node->getNamedChild("description", description_)) return false;
00486         if (!noTooltip) toolTip_.setText(ToolTip::ToolTipHelp, 
00487                 LANG_RESOURCE(name_, name_), LANG_RESOURCE(name_ + "_window", description_));
00488 
00489         // Disabled
00490         XMLNode *disabled = 0;
00491         if (node->getNamedChild("disabled", disabled, false))
00492         {
00493                 disabled_ = true;
00494         }
00495 
00496         node->getNamedChild("windowlevel", windowLevel_, false);
00497 
00498         unsigned int windowstate = 0;
00499         if (node->getNamedChild("windowstate", windowstate, false))
00500         {
00501                 windowState_ = windowstate;
00502         }
00503 
00504         return true;
00505 }
00506 
00507 void GLWWindow::savePosition(XMLNode *node)
00508 {
00509         bool visible = GLWWindowManager::instance()->windowVisible(getId());
00510 
00511         node->addChild(new XMLNode("x", int(getX())));
00512         node->addChild(new XMLNode("y", int(getY())));
00513         node->addChild(new XMLNode("visible", visible));
00514 }
00515 
00516 void GLWWindow::loadPosition(XMLNode *node)
00517 {
00518         int x, y;
00519         bool visible;
00520         if (!node->getNamedChild("x", x)) return;
00521         if (!node->getNamedChild("y", y)) return;
00522         if (!node->getNamedChild("visible", visible)) return;
00523 
00524         setX(float(x));
00525         setY(float(y));
00526         if (!visible) GLWWindowManager::instance()->hideWindow(getId());
00527         else GLWWindowManager::instance()->showWindow(getId());
00528 }

Generated on Mon Feb 16 15:14:46 2009 for Scorched3D by  doxygen 1.5.3