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/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 }