00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
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
00325 dragging_ = TitleDrag;
00326 skipRest = !(eClickTransparent & windowState_) || skipRest;
00327 }
00328 else if (y > y_ && y < y_ + h_)
00329 {
00330
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
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
00352 dragging_ = SizeDrag;
00353 skipRest = !(eClickTransparent & windowState_) || skipRest;
00354 }
00355 else if (y > y_ && y < y_ + h_)
00356 {
00357
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
00478 if (!node->getNamedChild("name", name_)) return false;
00479 }
00480
00481 bool noTooltip = false;
00482 node->getNamedChild("notooltip", noTooltip, false);
00483
00484
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
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 }