GLWToolTip.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/GLViewPort.h>
00023 #include <GLW/GLWToolTip.h>
00024 #include <GLW/GLWidget.h>
00025 #include <GLW/GLWFont.h>
00026 #include <client/ScorchedClient.h>
00027 #include <graph/OptionsDisplay.h>
00028 #include <common/Defines.h>
00029 #include <string.h>
00030 
00031 static Vector color(0.1f, 0.1f, 0.4f);
00032 static Vector selectedColor(0.9f, 0.9f, 1.0f);
00033 
00034 GLWToolTip *GLWToolTip::instance_ = 0;
00035 
00036 GLWToolTip *GLWToolTip::instance()
00037 {
00038         if (!instance_)
00039         {
00040                 instance_ = new GLWToolTip;
00041         }
00042         return instance_;
00043 }
00044 
00045 GLWToolTip::GLWToolTip() : 
00046         GameStateI("GLWToolTip"),
00047         lastTip_(0), currentTip_(0),
00048         timeDrawn_(0.0f), timeSeen_(0.0),
00049         refreshTime_(100.0f),
00050         tipX_(0.0f), tipY_(0.0f),
00051         tipW_(0.0f), tipH_(0.0f),
00052         tipOffX_(0.0f), tipOffY_(0.0f)
00053 {
00054 }
00055 
00056 GLWToolTip::~GLWToolTip()
00057 {
00058 }
00059 
00060 bool GLWToolTip::addToolTip(ToolTip::ToolTipType type, 
00061         const LangString &title, const LangString &text,
00062         float x, float y, float w, float h)
00063 {
00064         if (!OptionsDisplay::instance()->getShowContextInfo() &&
00065                 (type & ToolTip::ToolTipInfo)) return false;
00066         if (!OptionsDisplay::instance()->getShowContextHelp() &&
00067                 (type & ToolTip::ToolTipHelp)) return false;
00068 
00069         int mouseX = ScorchedClient::instance()->getGameState().getMouseX();
00070         int mouseY = ScorchedClient::instance()->getGameState().getMouseY();
00071         
00072         bool result = false;
00073         if (x < mouseX && mouseX < x + w &&
00074                 y < mouseY && mouseY < y + h)
00075         {
00076                 static ToolTip singleTip;
00077                 singleTip.setText(type, title, text);
00078 
00079                 currentX_ = x;
00080                 currentY_ = y;
00081                 currentW_ = w;
00082                 currentH_ = h;
00083                 currentTip_ = &singleTip;
00084 
00085                 result = true;
00086         }
00087         return result;
00088 }
00089 
00090 bool GLWToolTip::addToolTip(ToolTip *tip, float x, float y, float w, float h)
00091 {
00092         if (!OptionsDisplay::instance()->getShowContextInfo() &&
00093                 (tip->getType() & ToolTip::ToolTipInfo)) return false;
00094         if (!OptionsDisplay::instance()->getShowContextHelp() &&
00095                 (tip->getType() & ToolTip::ToolTipHelp)) return false;
00096 
00097         int mouseX = ScorchedClient::instance()->getGameState().getMouseX();
00098         int mouseY = ScorchedClient::instance()->getGameState().getMouseY();
00099         
00100         bool result = false;
00101         if (x < mouseX && mouseX < x + w &&
00102                 y < mouseY && mouseY < y + h)
00103         {
00104                 currentX_ = x;
00105                 currentY_ = y;
00106                 currentW_ = w;
00107                 currentH_ = h;
00108                 currentTip_ = tip;
00109 
00110                 result = true;
00111         }
00112         return result;
00113 }
00114 
00115 void GLWToolTip::setupTip(ToolTip *tip)
00116 {
00117         currentTip_ = tip;
00118         tipTextWidth_ = 0.0f;
00119         tipTextHeight_ = 0.0f;
00120         tipTitle_ = tip->getTitle();
00121         tipText_ = tip->getText();
00122         tipTexts_.clear();
00123 }
00124 
00125 void GLWToolTip::calculateTip(ToolTip *tip)
00126 {
00127         if (tipTextWidth_ != 0.0f) return;
00128 
00129         tipTextHeight_ = 24.0f;
00130 
00131         int pos, startpos = 0;
00132         LangString tipText = tipText_;
00133         tipText.append(LANG_STRING("\n"));
00134         while ((pos = tipText.find(LANG_STRING("\n"), startpos)) != LangString::npos)
00135         {
00136                 LangString part = LangString(tipText, startpos, pos - startpos);
00137                 tipTexts_.push_back(part);
00138                 tipTextHeight_ += 10.0f;
00139 
00140                 startpos = pos + 1;
00141         }
00142 
00143         std::list<LangString>::iterator itor;
00144         std::list<LangString>::iterator enditor = tipTexts_.end();
00145         for (itor = tipTexts_.begin(); itor != enditor; itor++)
00146         {
00147                 float width = float(GLWFont::instance()->getGameFont()->
00148                         getWidth(9,(*itor))) + 10.0f;
00149                 if (width > tipTextWidth_) tipTextWidth_ = width;
00150         }
00151 
00152         float width = float(GLWFont::instance()->getGameFont()->
00153                 getWidth(11, tipTitle_)) + 10.0f; 
00154         if (width > tipTextWidth_) tipTextWidth_ = width;
00155 }
00156 
00157 void GLWToolTip::clearToolTip(float x, float y, float w, float h)
00158 {
00159         int mouseX = ScorchedClient::instance()->getGameState().getMouseX();
00160         int mouseY = ScorchedClient::instance()->getGameState().getMouseY();
00161         
00162         if (x < mouseX && mouseX < x + w &&
00163                 y < mouseY && mouseY < y + h)
00164         {
00165                 currentTip_ = 0;
00166         }
00167 }
00168 
00169 void GLWToolTip::simulate(const unsigned state, float frameTime)
00170 {
00171         timeDrawn_ += frameTime;
00172 }
00173 
00174 void GLWToolTip::draw(const unsigned state)
00175 {
00176         if (currentTip_ != lastTip_) refreshTime_ = 100.0f;
00177         lastTip_ = currentTip_;
00178         currentTip_ = 0;
00179 
00180         if (lastTip_) timeSeen_ += timeDrawn_;
00181         else timeSeen_ -= timeDrawn_;
00182         refreshTime_ += timeDrawn_;
00183         timeDrawn_ = 0.0f;
00184 
00185         float showTime = 
00186                 float(OptionsDisplay::instance()->getToolTipTime()) / 1000.0f;
00187         if (timeSeen_ <= -showTime)
00188         {
00189                 timeSeen_ = -showTime;
00190                 return;
00191         }
00192 
00193         if ((refreshTime_ > 1.0f || 
00194                 tipX_ != currentX_ || 
00195                 tipY_ != currentY_) && lastTip_)
00196         {
00197                 tipX_ = currentX_;
00198                 tipY_ = currentY_;
00199                 tipW_ = currentW_;
00200                 tipH_ = currentH_;
00201 
00202                 lastTip_->populate();
00203                 setupTip(lastTip_);
00204                 refreshTime_ = 0.0f;
00205         }
00206         if (lastTip_) 
00207         {
00208                 calculateTip(lastTip_);
00209 
00210                 if (lastTip_->getType() & ToolTip::ToolTipAlignLeft)
00211                         tipOffX_ = -currentW_ - tipTextWidth_ - 10;
00212                 else tipOffX_ = 0.0f;
00213 
00214                 if (lastTip_->getType() & ToolTip::ToolTipAlignBottom)
00215                         tipOffY_ = 15.0f;
00216                 else tipOffY_ = 0.0f;
00217         }
00218 
00219         float alpha = timeSeen_ * 
00220                 float(OptionsDisplay::instance()->getToolTipSpeed());
00221         if (alpha > 1.0f)
00222         {
00223                 alpha = 1.0f;
00224                 timeSeen_ = 1.0f / 
00225                         float(OptionsDisplay::instance()->getToolTipSpeed());
00226         }
00227 
00228         GLState currentState(GLState::TEXTURE_OFF | GLState::DEPTH_OFF);
00229 
00230         float posX = tipX_ + tipOffX_;
00231         float posY = tipY_ + tipOffY_;
00232         float posW = tipTextWidth_;
00233         float posH = tipTextHeight_;
00234 
00235         int camWidth = GLViewPort::getWidth();
00236         if (posX > camWidth / 2)
00237         {
00238                 posX -= posW + 5.0f;
00239         }
00240         else
00241         {
00242                 posX += tipW_ + 5.0f;
00243         }
00244         int camHeight = GLViewPort::getHeight();
00245         if (posY > camHeight / 2)
00246         {
00247                 posY -= posH;
00248         }
00249         else
00250         {
00251                 posY += 15.0f;
00252         }
00253 
00254         if (posX < 0) posX = 0;
00255         else if (posX + posW > camWidth) posX -= posX + posW - camWidth;
00256 
00257         {
00258                 if (OptionsDisplay::instance()->getSmoothLines())
00259                 {
00260                         glEnable(GL_LINE_SMOOTH);
00261                 }
00262 
00263                 GLState currentStateBlend(GLState::BLEND_ON);
00264                 glColor4f(0.5f, 0.5f, 1.0f, 0.8f * alpha);      
00265                 glBegin(GL_TRIANGLE_FAN);
00266                         glVertex2f(posX + 10.0f, posY + 2.0f);
00267                         glVertex2f(posX + 10.0f, posY);
00268                         GLWidget::drawRoundBox(
00269                                 posX, posY,
00270                                 posW, posH, 10.0f);
00271                         glVertex2f(posX + 10.0f, posY);
00272                 glEnd();
00273                 glColor4f(0.9f, 0.9f, 1.0f, 0.5f * alpha);
00274                 glLineWidth(2.0f);
00275                 glBegin(GL_LINE_LOOP);
00276                         GLWidget::drawRoundBox(
00277                                 posX, posY,
00278                                 posW, posH, 10.0f);
00279                 glEnd();
00280                 glLineWidth(1.0f);
00281 
00282                 if (OptionsDisplay::instance()->getSmoothLines())
00283                 {
00284                         glDisable(GL_LINE_SMOOTH);
00285                 }
00286         }
00287 
00288         float pos = posY + posH - 16.0f;
00289         GLWFont::instance()->getGameFont()->drawA(selectedColor, alpha, 11, posX + 3.0f, 
00290                 pos, 0.0f, tipTitle_);
00291         pos -= 2.0f;
00292 
00293         std::list<LangString>::iterator itor;
00294         std::list<LangString>::iterator enditor = tipTexts_.end();
00295         for (itor = tipTexts_.begin(); itor != enditor; itor++)
00296         {
00297                 pos -= 10.0f;
00298 
00299                 GLWFont::instance()->getGameFont()->drawA(
00300                         color, alpha, 9, posX + 6.0f, 
00301                         pos, 0.0f, (*itor));
00302         }
00303 }

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