GLWChannelText.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 <GLW/GLWChannelText.h>
00022 #include <GLW/GLWWindowManager.h>
00023 #include <GLW/GLWFont.h>
00024 #include <GLW/GLWPanel.h>
00025 #include <GLW/GLWColors.h>
00026 #include <GLEXT/GLState.h>
00027 #include <image/ImageFactory.h>
00028 #include <XML/XMLParser.h>
00029 #include <client/ScorchedClient.h>
00030 #include <client/ClientChannelManager.h>
00031 #include <tank/TankContainer.h>
00032 #include <tank/TankState.h>
00033 #include <tank/TankColorGenerator.h>
00034 #include <common/ToolTipResource.h>
00035 #include <common/Defines.h>
00036 #include <common/Keyboard.h>
00037 #include <common/OptionsScorched.h>
00038 #include <lang/LangResource.h>
00039 #include <lang/LangParam.h>
00040 
00041 std::list<ChannelText> GLWChannelText::lastMessages_;
00042 
00043 REGISTER_CLASS_SOURCE(GLWChannelText);
00044 
00045 GLWChannelText::GLWChannelText() :
00046         ctime_(0.0f), cursor_(false), maxTextLen_(0), 
00047         visible_(false),
00048         button_(x_ + 2.0f, y_ + 4.0f, 12.0f, 12.0f),
00049         fontSize_(12.0f), outlineFontSize_(14.0f),
00050         whisperDest_(0), createdTexture_(false)
00051 {
00052         view_.setHandler(this);
00053         button_.setHandler(this);
00054         button_.setToolTip(new ToolTipResource(
00055                 ToolTip::ToolTipAlignLeft | ToolTip::ToolTipHelp, 
00056                 "CHAT", "Chat", 
00057                 "CHAT_SHOW_TOOLTIP", "Show chat menu"));
00058         prompt_.setChannelView(&view_);
00059 }
00060 
00061 GLWChannelText::~GLWChannelText()
00062 {
00063 }
00064 
00065 void GLWChannelText::simulate(float frameTime)
00066 {
00067         view_.simulate(frameTime);
00068         button_.simulate(frameTime);
00069 
00070         if (!visible_) return;
00071 
00072         ctime_ += frameTime;
00073         if (ctime_ > 0.5f)
00074         {
00075                 ctime_ = 0.0f;
00076                 cursor_ = !cursor_;
00077         }
00078 }
00079 
00080 void GLWChannelText::draw()
00081 {
00082         view_.draw();
00083         if (view_.getParentSized())
00084         {
00085                 setW(view_.getW());
00086                 setH(view_.getH());
00087         }
00088 
00089         if (!createdTexture_)
00090         {
00091                 createdTexture_ = true;
00092                 ImageHandle buttonImg = ImageFactory::loadAlphaImageHandle(
00093                         S3D::getDataFile("data/windows/arrow_r.png"));
00094                 buttonTexture_.create(buttonImg, false);
00095                 button_.setTexture(&buttonTexture_);
00096                 ImageHandle map = ImageFactory::loadImageHandle(
00097                         S3D::getDataFile("data/windows/white.bmp"));
00098                 colorTexture_.create(map);
00099         }
00100 
00101         button_.draw();
00102 
00103         if (!visible_) return;
00104 
00105         GLWidget::draw();
00106         glColor4f(0.4f, 0.6f, 0.8f, 0.6f);
00107 
00108         {
00109                 GLState currentStateBlend(GLState::BLEND_ON);
00110                 glBegin(GL_TRIANGLE_FAN);
00111                         glVertex2f(x_ + 25.0f, y_ + 5.0f);
00112                         glVertex2f(x_ + 25.0f, y_);
00113                         drawRoundBox(x_ + 15.0f, y_, w_ - 15.0f, h_, 10.0f);
00114                         glVertex2f(x_ + 25.0f, y_);
00115                 glEnd();
00116         }
00117 
00118         glColor3f(0.0f, 0.0f, 0.0f);
00119         glBegin(GL_LINE_LOOP);
00120                 drawRoundBox(x_ + 15.0f, y_, w_ - 15.0f, h_, 10.0f);
00121         glEnd();
00122 
00123         // Get the width of the prompt
00124         float promptWidth = GLWFont::instance()->getGameFont()->getWidth(
00125                 fontSize_, prompt_.getString());
00126 
00127         // Draw prompt black outline
00128         GLWFont::instance()->getGameShadowFont()->
00129                 drawA(GLWColors::black, 1.0f, fontSize_,
00130                         x_ + 20.0f - 1.0f, y_ + 5.0f + 1.0f, 0.0f, 
00131                         prompt_.getString());
00132         
00133         // Draw text black outline
00134         GLWFont::instance()->getGameShadowFont()->drawWidthRhs(
00135                 w_ - 25.0f - promptWidth,
00136                 GLWColors::black, fontSize_,
00137                 x_ + 20.0f + promptWidth - 1.0f, y_ + 5.0f + 1.0f, 0.0f, 
00138                 text_);
00139 
00140         // Draw the prompt
00141         GLWFont::instance()->getGameFont()->
00142                 drawA(&prompt_, channelEntry_.color, 1.0f, fontSize_,
00143                         x_ + 20.0f, y_ + 5.0f, 0.0f, 
00144                         prompt_.getString());
00145 
00146         // Draw the text
00147         GLWFont::instance()->getGameFont()->drawWidthRhs(
00148                 w_ - 25.0f - promptWidth,
00149                 channelEntry_.color, fontSize_,
00150                 x_ + 20.0f + promptWidth, y_ + 5.0f, 0.0f, 
00151                 text_);
00152 }
00153 
00154 void GLWChannelText::keyDown(char *buffer, unsigned int keyState, 
00155                 KeyboardHistory::HistoryElement *history, int hisCount, 
00156                 bool &skipRest)
00157 {
00158         if (visible_) skipRest = true;
00159         for (int i=0; i<hisCount; i++)
00160         {
00161                 unsigned int unicode = history[i].representedUnicode;
00162                 unsigned int dik = history[i].sdlKey;
00163 
00164                 if (!visible_)
00165                 {
00166                         processNotVisibleKey(unicode, dik, skipRest);
00167                 }
00168                 else
00169                 {
00170                         processVisibleKey(unicode, dik);
00171                 }
00172         }
00173         if (visible_) skipRest = true;
00174         else view_.keyDown(buffer, keyState, history, hisCount, skipRest);
00175 }
00176 
00177 void GLWChannelText::processNotVisibleKey(unsigned int unicode, unsigned int dik, bool &skipRest)
00178 {
00179         // Check all of the key entries to see if the channel needs to be displayed
00180         std::map<KeyboardKey *, std::string>::iterator keyItor;
00181         for (keyItor = keys_.begin();
00182                 keyItor != keys_.end();
00183                 keyItor++)
00184         {
00185                 KeyboardKey *key = keyItor->first;
00186                 std::string &channel = keyItor->second;
00187 
00188                 // Check in the list of keys to see if we need to display 
00189                 std::vector<KeyboardKey::KeyEntry> &talkKeys = key->getKeys();
00190                 std::vector<KeyboardKey::KeyEntry>::iterator itor;
00191                 for (itor = talkKeys.begin();
00192                         itor != talkKeys.end();
00193                         itor++)
00194                 {
00195                         KeyboardKey::KeyEntry &entry = *itor;
00196                         if (dik == entry.key)
00197                         {
00198                                 setVisible(true);
00199                                 skipRest = true;
00200 
00201                                 text_.clear();
00202                                 if (!channel.empty())
00203                                 {
00204                                         GLWChannelView::CurrentChannelEntry *channelEntry = view_.getChannel(
00205                                                 channel.c_str());
00206                                         if (channelEntry) setChannelEntry(*channelEntry);
00207                                 }
00208 
00209                                 if (entry.key == SDLK_SLASH) text_ = LANG_STRING("/");
00210                                 else if (entry.key == SDLK_BACKSLASH) text_ = LANG_STRING("\\");
00211 
00212                                 break;
00213                         }
00214                 }
00215         }
00216 
00217         if (visible_)
00218         {
00219                 if (!checkCurrentChannel()) setVisible(false);
00220         }
00221 }
00222 
00223 void GLWChannelText::processVisibleKey(unsigned int unicode, unsigned int dik)
00224 {
00225         if (dik == SDLK_BACKSPACE || dik == SDLK_DELETE)
00226         {
00227                 if (!text_.empty())
00228                 {
00229                         text_ = text_.substr(0, text_.length() - 1);
00230                 }
00231         }
00232         else if (dik == SDLK_ESCAPE)
00233         {
00234                 if (!text_.empty())
00235                 {
00236                         text_.clear();
00237                 }
00238                 else
00239                 {
00240                         setVisible(false);
00241                 }
00242         }
00243         else if (dik == SDLK_RETURN)
00244         {
00245                 if (!text_.empty())
00246                 {
00247                         if (text_[0] == '\\' || text_[0] == '/')
00248                         {
00249                                 processSpecialText();
00250                         }
00251                         else
00252                         {
00253                                 processNormalText();
00254                         }
00255                 }
00256                 setVisible(false);
00257                 text_.clear();
00258         }
00259         else if (unicode >= ' ')
00260         {
00261                 if (ScorchedClient::instance()->getOptionsGame().getAllowMultiLingualChat() ||
00262                         unicode <= 127)
00263                 {
00264                         if ((maxTextLen_==0) || ((int) text_.size() < maxTextLen_))
00265                         {
00266                                 if ((text_[0] == '\\' || text_[0] == '/') && unicode == ' ')
00267                                 {
00268                                         processSpecialText();
00269                                 }
00270                                 else
00271                                 {
00272                                         text_ += unicode;
00273                                 }
00274                         }
00275                 }
00276         }
00277 }
00278 
00279 void GLWChannelText::setVisible(bool visible)
00280 {
00281         visible_ = visible;
00282 
00283         if (0 == strcmp("GLWWindow", getParent()->getClassName()))
00284         {
00285                 GLWWindow *window = (GLWWindow *) getParent();
00286                 window->setWindowLevel(visible_?40000:200000);
00287                 GLWWindowManager::instance()->sortWindowLevels();
00288         }
00289 }
00290 
00291 void GLWChannelText::processNormalText()
00292 {
00293         ChannelText text(channelEntry_.channel.c_str(), text_);
00294         if (channelEntry_.type & ChannelDefinition::eWhisperChannel)
00295         {
00296                 text.setDestPlayerId(whisperDest_);
00297         }
00298 
00299         lastMessages_.push_back(text);
00300         if (lastMessages_.size() > 10) lastMessages_.pop_front();
00301         ClientChannelManager::instance()->sendText(text);
00302 }
00303 
00304 void GLWChannelText::processSpecialText()
00305 {
00306         LangString channelPart(&text_[1]);
00307 
00308         GLWChannelView::CurrentChannelEntry *channelEntry = 
00309                 view_.getChannel(LangStringUtil::convertFromLang(channelPart));
00310         if (channelEntry && 
00311                 channelValid(channelEntry->channel.c_str()))
00312         {
00313                 text_.clear();
00314                 setChannelEntry(*channelEntry);
00315         }
00316         else if (channelPart == LANG_STRING("r"))
00317         {
00318                 text_.clear();
00319 
00320                 whisperDest_ = view_.getLastWhisperSrc();
00321                 GLWChannelView::CurrentChannelEntry *channelEntry = 
00322                         view_.getChannel("whisper");
00323                 if (channelEntry && 
00324                         channelValid(channelEntry->channel.c_str()))
00325                 {
00326                         setChannelEntry(*channelEntry);
00327                 }
00328         }
00329         else if (channelPart == LANG_STRING("t"))
00330         {
00331                 text_.clear();
00332 
00333                 GLWChannelView::CurrentChannelEntry *channelEntry = 
00334                         view_.getChannel("team");
00335                 if (channelEntry && 
00336                         channelValid(channelEntry->channel.c_str()))
00337                 {
00338                         setChannelEntry(*channelEntry);
00339                 }
00340         }
00341         else if (channelPart == LANG_STRING("s") || 
00342                 channelPart == LANG_STRING("say"))
00343         {
00344                 text_.clear();
00345 
00346                 GLWChannelView::CurrentChannelEntry *channelEntry = 
00347                         view_.getChannel("general");
00348                 if (channelEntry && 
00349                         channelValid(channelEntry->channel.c_str()))
00350                 {
00351                         setChannelEntry(*channelEntry);
00352                 }
00353         }
00354 }
00355 
00356 void GLWChannelText::mouseDown(int button, float x, float y, bool &skipRest)
00357 {
00358         view_.mouseDown(button, x, y, skipRest);
00359         button_.mouseDown(button, x, y, skipRest);
00360 }
00361 
00362 void GLWChannelText::mouseUp(int button, float x, float y, bool &skipRest)
00363 {
00364         view_.mouseUp(button, x, y, skipRest);
00365         button_.mouseUp(button, x, y, skipRest);
00366 }
00367 
00368 void GLWChannelText::mouseDrag(int button, float mx, float my, float x, float y, bool &skipRest)
00369 {
00370         view_.mouseDrag(button, mx, my, x, y, skipRest);
00371         button_.mouseDrag(button, mx, my, x, y, skipRest);
00372 }
00373 
00374 void GLWChannelText::setParent(GLWPanel *parent)
00375 {
00376         GLWidget::setParent(parent);
00377         button_.setParent(parent);
00378         view_.setParent(parent);
00379 }
00380 
00381 void GLWChannelText::setX(float x)
00382 {
00383         GLWidget::setX(x);
00384         button_.setX(x + 2.0f);
00385         view_.setX(x);
00386 }
00387 
00388 void GLWChannelText::setY(float y)
00389 {
00390         GLWidget::setY(y);
00391         button_.setY(y + 4.0f);
00392         view_.setY(y + 20.0f);
00393 }
00394 
00395 void GLWChannelText::setW(float w)
00396 {
00397         GLWidget::setW(w);
00398         view_.setW(w);
00399 }
00400 
00401 void GLWChannelText::setH(float h)
00402 {
00403         GLWidget::setH(20.0f);
00404         view_.setH(h - 20.0f);
00405 }
00406 
00407 enum
00408 {
00409         eMuteSelectorStart = 1000,
00410         eWhisperSelectorStart = 2000,
00411         eJoinSelectorStart = 3000,
00412         eLeaveSelectorStart = 4000,
00413         eSelectSelectorStart = 5000,
00414         eColorSelectorStart = 6000,
00415         eChatSelectorStart = 7000,
00416         eReplySelectorStart = 8000,
00417         eResendSelectorStart = 9000
00418 };
00419 
00420 void GLWChannelText::buttonDown(unsigned int id)
00421 {
00422         // Make sure the current channel is valid
00423         checkCurrentChannel();
00424 
00425         // All of the tooltips
00426         static ToolTip muteTooltip(ToolTip::ToolTipHelp | ToolTip::ToolTipAlignBottom, 
00427                 LANG_RESOURCE("IGNORE", "Ignore"), 
00428                 LANG_RESOURCE("IGNORE_TOOLTIP", "Ignore chat from another player (mute)"));
00429         static ToolTip whisperTooltip(ToolTip::ToolTipHelp | ToolTip::ToolTipAlignBottom, 
00430                 LANG_RESOURCE("WHISPER", "Whisper"), 
00431                 LANG_RESOURCE("WHISPER_TOOLTIP", "Send private chat to another player"));
00432         static ToolTip joinTooltip(ToolTip::ToolTipHelp | ToolTip::ToolTipAlignBottom, 
00433                 LANG_RESOURCE("JOIN_CHANNEL", "Join Channel"), 
00434                 LANG_RESOURCE("JOIN_CHANNEL_TOOLTIP", "Join another chat channel.\n"
00435                 "You will be able to see messages sent on this channel"));
00436         static ToolTip leaveTooltip(ToolTip::ToolTipHelp | ToolTip::ToolTipAlignBottom, 
00437                 LANG_RESOURCE("LEAVE_CHANNEL", "Leave Channel"), 
00438                 LANG_RESOURCE("LEAVE_CHANNEL_TOOLTIP", "Leave a current chat channel.\n"
00439                 "You will stop recieving messages sent on this channel"));
00440         static ToolTip selectTooltip(ToolTip::ToolTipHelp | ToolTip::ToolTipAlignBottom, 
00441                 LANG_RESOURCE("SELECT_CHANNEL", "Select Channel"), 
00442                 LANG_RESOURCE("SELECT_CHANNEL_TOOLTIP", "Select the current channel.\n"
00443                 "This is the channel you will send messages on."));
00444         static ToolTip colorTooltip(ToolTip::ToolTipHelp | ToolTip::ToolTipAlignBottom, 
00445                 LANG_RESOURCE("CHANNEL_COLOR", "Channel Color"), 
00446                 LANG_RESOURCE("CHANNEL_COLOR_TOOLTIP", "Change the color of the current channel."));
00447         static ToolTip resendTooltip(ToolTip::ToolTipHelp | ToolTip::ToolTipAlignBottom, 
00448                 LANG_RESOURCE("RESEND", "Resend"), 
00449                 LANG_RESOURCE("RESEND_TOOLTIP", "Resend a previously sent message."));
00450         static ToolTip replyTooltip(ToolTip::ToolTipHelp | ToolTip::ToolTipAlignBottom, 
00451                 LANG_RESOURCE("REPLY", "Reply"), 
00452                 LANG_RESOURCE("REPLY_TOOLTIP", "Reply to the last person that whispered you."));
00453         static ToolTip chatTooltip(ToolTip::ToolTipHelp | ToolTip::ToolTipAlignBottom, 
00454                 LANG_RESOURCE("CHAT", "Chat"), 
00455                 LANG_RESOURCE("CHAT_TOOLTIP", "Show or hide the chat text entry box."));
00456 
00457         GLWSelectorEntry mute(LANG_RESOURCE("IGNORE", "Ignore"), &muteTooltip);
00458         GLWSelectorEntry whisper(LANG_RESOURCE("WHISPER", "Whisper"), &whisperTooltip);
00459         GLWSelectorEntry bar(LANG_STRING("---"));
00460         bar.setSeperator();
00461         GLWSelectorEntry joinChannel(LANG_RESOURCE("JOIN_CHANNEL", "Join Channel"), &joinTooltip);
00462         GLWSelectorEntry leaveChannel(LANG_RESOURCE("LEAVE_CHANNEL", "Leave Channel"), &leaveTooltip);
00463         GLWSelectorEntry selectChannel(LANG_RESOURCE("SELECT_CHANNEL", "Select Channel"), &selectTooltip);
00464         GLWSelectorEntry colorChannel(LANG_RESOURCE("CHANNEL_COLOR", "Channel Color"), &colorTooltip);
00465         GLWSelectorEntry resend(LANG_RESOURCE("RESEND", "Resend"), &resendTooltip);
00466         GLWSelectorEntry reply(LANG_RESOURCE("REPLY", "Reply").append(LANG_STRING(" (/r)")), &replyTooltip, false, 0, (void *) eReplySelectorStart);
00467         GLWSelectorEntry chat(LANG_RESOURCE("CHAT", "Chat"), &chatTooltip, false, 0, (void *) eChatSelectorStart);
00468 
00469         // For each resend
00470         std::list<ChannelText>::iterator resendItor;
00471         for (resendItor = lastMessages_.begin();
00472                 resendItor != lastMessages_.end();
00473                 resendItor++)
00474         {
00475                 ChannelText &channelText = *resendItor;
00476                 resend.getPopups().push_back(GLWSelectorEntry(channelText.getMessage(), 
00477                         0, false, 0, (void *) eResendSelectorStart));
00478         }
00479 
00480         // For each tank
00481         Tank *currentTank = 
00482                 ScorchedClient::instance()->getTankContainer().getCurrentTank();
00483         std::map<unsigned int, Tank *> &tanks = ScorchedClient::instance()->
00484                 getTankContainer().getPlayingTanks();
00485         std::map<unsigned int, Tank *>::iterator tankItor;
00486         for (tankItor = tanks.begin();
00487                 tankItor != tanks.end();
00488                 tankItor++)
00489         {
00490                 Tank *tank = (*tankItor).second;
00491                 if (tank == currentTank ||
00492                         !tank->getDestinationId()) continue;
00493 
00494                 // Add tanks to the mute and whisper lines
00495                 mute.getPopups().push_back(GLWSelectorEntry(tank->getTargetName(),
00496                         0, tank->getState().getMuted(), 0, (void *) eMuteSelectorStart));
00497                 whisper.getPopups().push_back(GLWSelectorEntry(tank->getTargetName(),
00498                         0, false, 0, (void *) eWhisperSelectorStart));
00499         }
00500 
00501         // For each current channel
00502         std::list<GLWChannelView::CurrentChannelEntry> &channels = view_.getCurrentChannels();
00503         std::list<GLWChannelView::CurrentChannelEntry>::iterator channelItor;
00504         for (channelItor = channels.begin();
00505                 channelItor != channels.end();
00506                 channelItor++)
00507         {
00508                 GLWChannelView::CurrentChannelEntry &channel = (*channelItor);
00509 
00510                 // Add an entry saying which current channels we can leave
00511                 std::string text =
00512                         S3D::formatStringBuffer("%u. %s%s", 
00513                                 channel.id, channel.channel.c_str(),
00514                                 (channel.type & ChannelDefinition::eReadOnlyChannel?" (RO)":""));
00515                 leaveChannel.getPopups().push_back(GLWSelectorEntry(
00516                         LANG_STRING(text), 0, false, 0, 
00517                         (void *) eLeaveSelectorStart, channel.channel.c_str()));
00518 
00519                 if (channelValid(channel.channel.c_str()))
00520                 {
00521                         // Add an entry saying which channels we can write on
00522                         selectChannel.getPopups().push_back(GLWSelectorEntry(
00523                                 LANG_RESOURCE_3("WHISPER_CHANNEL", "{0}. {1} {2}", channel.id, channel.channel,
00524                                 (channel.type & ChannelDefinition::eWhisperChannel?whisperDestStr_:LangString())),
00525                                 0, (channelEntry_.channel == channel.channel), 0, 
00526                                 (void *) eSelectSelectorStart, channel.channel.c_str()));
00527                 }
00528         }
00529 
00530         // For each available channel
00531         std::list<GLWChannelView::BaseChannelEntry> &available = view_.getAvailableChannels();
00532         std::list<GLWChannelView::BaseChannelEntry>::iterator availableItor;
00533         for (availableItor = available.begin();
00534                 availableItor != available.end();
00535                 availableItor++)
00536         {
00537                 GLWChannelView::BaseChannelEntry &channel = *availableItor;
00538 
00539                 // Add an entry saying which channels we can join
00540                 std::string text = 
00541                         S3D::formatStringBuffer("%s%s",
00542                                 availableItor->channel.c_str(),
00543                                 (channel.type & ChannelDefinition::eReadOnlyChannel?" (RO)":""));
00544                 joinChannel.getPopups().push_back(GLWSelectorEntry(LANG_STRING(text),
00545                         0, false, 0, (void *) eJoinSelectorStart, 
00546                         availableItor->channel.c_str()));
00547         }
00548 
00549         // For each color
00550         std::vector<Vector *> &colors = TankColorGenerator::instance()->getAllColors();
00551         std::vector<Vector *>::iterator colorItor;
00552         for (colorItor = colors.begin();
00553                 colorItor != colors.end();
00554                 colorItor++)
00555         {
00556                 Vector *color = *colorItor;
00557 
00558                 // Add an entry allowing the user to change channel color
00559                 GLWSelectorEntry entry(LANG_STRING(""), 0, false, &colorTexture_, (void *) eColorSelectorStart);
00560                 entry.getColor() = *color;
00561                 entry.getTextureWidth() = 32;
00562                 colorChannel.getPopups().push_back(entry);
00563         }
00564 
00565         // Build the meny structure, with the popup menus below the main
00566         std::list<GLWSelectorEntry> topLevel;
00567         topLevel.push_back(mute);
00568         topLevel.push_back(whisper);
00569         topLevel.push_back(bar);
00570         topLevel.push_back(joinChannel);
00571         topLevel.push_back(leaveChannel);
00572         topLevel.push_back(selectChannel);
00573         topLevel.push_back(colorChannel);
00574         topLevel.push_back(bar);
00575         topLevel.push_back(resend);
00576         topLevel.push_back(reply);
00577         topLevel.push_back(chat);
00578 
00579         // Show all the entries
00580         float x = (float) ScorchedClient::instance()->getGameState().getMouseX();
00581         float y = (float) ScorchedClient::instance()->getGameState().getMouseY();
00582         GLWSelector::instance()->showSelector(this, x, y, topLevel);
00583 }
00584 
00585 void GLWChannelText::itemSelected(GLWSelectorEntry *entry, int position)
00586 {
00587         int type = int(long(entry->getUserData()));
00588         switch (type)
00589         {
00590         case eMuteSelectorStart:
00591                 {
00592                         Tank *tank = 
00593                                 ScorchedClient::instance()->getTankContainer().
00594                                         getTankByName(entry->getText());
00595                         if (tank) 
00596                         {
00597                                 if (tank->getState().getMuted()) 
00598                                 {
00599                                         tank->getState().setMuted(false);
00600                                         ClientChannelManager::instance()->getMutedPlayers().erase(
00601                                                 tank->getPlayerId());
00602                                 }
00603                                 else
00604                                 {
00605                                         tank->getState().setMuted(true);
00606                                         ClientChannelManager::instance()->getMutedPlayers().insert(
00607                                                 tank->getPlayerId());
00608                                 }
00609                         }
00610                 }
00611                 break;
00612         case eWhisperSelectorStart:
00613                 {
00614                         Tank *tank = 
00615                                 ScorchedClient::instance()->getTankContainer().
00616                                         getTankByName(entry->getText());
00617                         if (tank)
00618                         {
00619                                 whisperDest_ = tank->getPlayerId();
00620                                 GLWChannelView::CurrentChannelEntry *channelEntry = 
00621                                         view_.getChannel("whisper");
00622                                 if (channelEntry && 
00623                                         channelValid(channelEntry->channel.c_str()))
00624                                 {
00625                                         setChannelEntry(*channelEntry);
00626                                         if (checkCurrentChannel()) setVisible(true);
00627                                 }
00628                         }
00629                 }
00630                 break;
00631         case eJoinSelectorStart:
00632                 view_.joinChannel(entry->getDataText());
00633                 break;
00634         case eLeaveSelectorStart:
00635                 view_.leaveChannel(entry->getDataText());
00636                 break;
00637         case eSelectSelectorStart:
00638                 {
00639                         GLWChannelView::CurrentChannelEntry *channel = 
00640                                 view_.getChannel(entry->getDataText());
00641                         if (channel) setChannelEntry(*channel);
00642                 }
00643                 break;
00644         case eColorSelectorStart:
00645                 {
00646                         GLWChannelView::CurrentChannelEntry *channel = 
00647                                 view_.getChannel(channelEntry_.channel.c_str());
00648                         if (channel) 
00649                         {
00650                                 channelEntry_.color = entry->getColor();
00651                                 channel->color = entry->getColor();
00652                         }
00653                 }
00654                 break;
00655         case eChatSelectorStart:
00656                 text_.clear();
00657                 if (visible_) setVisible(false);
00658                 else if (checkCurrentChannel()) setVisible(true);
00659                 break;
00660         case eReplySelectorStart:
00661                 {
00662                         whisperDest_ = view_.getLastWhisperSrc();
00663                         GLWChannelView::CurrentChannelEntry *channelEntry = 
00664                                 view_.getChannel("whisper");
00665                         if (channelEntry && 
00666                                 channelValid(channelEntry->channel.c_str()))
00667                         {
00668                                 setChannelEntry(*channelEntry);
00669 
00670                                 text_.clear();
00671                                 setVisible(true);
00672                         }
00673                 }
00674                 break;
00675         case eResendSelectorStart:
00676                 {
00677                         std::list<ChannelText>::iterator resendItor;
00678                         for (resendItor = lastMessages_.begin();
00679                                 resendItor != lastMessages_.end();
00680                                 resendItor++)
00681                         {
00682                                 ChannelText &text = *resendItor;
00683                                 if (text.getMessage() == entry->getText()) 
00684                                 {
00685                                         ClientChannelManager::instance()->sendText(text);
00686                                         break;
00687                                 }
00688                         }
00689                 }
00690                 break;
00691         }
00692 }
00693 
00694 void GLWChannelText::channelsChanged(unsigned int id)
00695 {
00696         checkCurrentChannel();
00697 }
00698 
00699 bool GLWChannelText::channelValid(const char *channelName)
00700 {
00701         // Check the whisper destination is ok
00702         bool whisperDestValid = false;
00703         if (whisperDest_)
00704         {
00705                 Tank *whisperTank = ScorchedClient::instance()->getTankContainer().
00706                         getTankById(whisperDest_);
00707                 if (whisperTank)
00708                 {
00709                         whisperDestValid = true;
00710                         whisperDestStr_ = whisperTank->getTargetName();
00711                 }
00712                 else
00713                 {
00714                         whisperDest_ = 0;
00715                         whisperDestStr_.clear();
00716                 }
00717         }
00718 
00719         // Check the actual channel exists
00720         GLWChannelView::CurrentChannelEntry *channelEntry = view_.getChannel(
00721                 channelName);                           
00722         if (!channelEntry) return false;
00723 
00724         // Check if this channel is actualy readonly
00725         if (channelEntry->type & ChannelDefinition::eReadOnlyChannel)
00726         {
00727                 return false;
00728         }
00729 
00730         // Check if the channel is a invalid whisper dest
00731         if ((channelEntry->type & ChannelDefinition::eWhisperChannel) && 
00732                 !whisperDestValid)
00733         {
00734                 return false;
00735         }
00736         return true;
00737 }
00738 
00739 bool GLWChannelText::checkCurrentChannel()
00740 {
00741         // Just turned visible, check the current channel is valid
00742         if (!channelValid(channelEntry_.channel.c_str()))
00743         {
00744                 // Its not, try to find a valid channel
00745                 std::list<GLWChannelView::CurrentChannelEntry> &entries = 
00746                         view_.getCurrentChannels();
00747                 std::list<GLWChannelView::CurrentChannelEntry>::iterator itor;
00748                 for (itor = entries.begin();
00749                         itor != entries.end();
00750                         itor++)
00751                 {
00752                         GLWChannelView::CurrentChannelEntry &entry = *itor;
00753                         if (channelValid(channelEntry_.channel.c_str()))
00754                         {
00755                                 // Use the first valid channel
00756                                 setChannelEntry(entry);
00757                                 return true;
00758                         }
00759                 }
00760                 return false;
00761         }
00762         else 
00763         {
00764                 // Get the current channel
00765                 GLWChannelView::CurrentChannelEntry *channelEntry = view_.getChannel(
00766                         channelEntry_.channel.c_str()); 
00767 
00768                 // The current channel is valid
00769                 setChannelEntry(*channelEntry);
00770                 return true;
00771         }       
00772 
00773         return true;
00774 }
00775 
00776 void GLWChannelText::setChannelEntry(GLWChannelView::CurrentChannelEntry &entry)
00777 {
00778         channelEntry_ = entry;
00779 
00780         LangString channelName;
00781         if (channelEntry_.type & ChannelDefinition::eWhisperChannel)
00782         {
00783                 channelName = LANG_PARAM_3("{0}. [c:{1}][p:{2}] : ",
00784                         channelEntry_.id, channelEntry_.channel, 
00785                         whisperDestStr_);
00786         }
00787         else
00788         {
00789                 channelName = LANG_PARAM_2("{0}. [c:{1}] : ",
00790                         channelEntry_.id, channelEntry_.channel);
00791         }
00792         prompt_.parseText(ScorchedClient::instance()->getContext(), channelName);
00793 }
00794 
00795 bool GLWChannelText::initFromXML(XMLNode *node)
00796 {
00797         if (!GLWidget::initFromXML(node)) return false;
00798         if (!view_.initFromXMLInternal(node)) return false;
00799 
00800         XMLNode *keyNode;
00801         while (node->getNamedChild("talkkey", keyNode, false))
00802         {
00803                 std::string key, channel;
00804                 if (!keyNode->getNamedChild("key", key)) return false;
00805                 if (!keyNode->getNamedChild("channel", channel)) return false;
00806 
00807                 KeyboardKey *actualKey = Keyboard::instance()->getKey(key.c_str());
00808                 if (!actualKey) return keyNode->returnError("Unknown key");
00809 
00810                 keys_[actualKey] = channel;
00811         }
00812 
00813         if (!node->getNamedChild("defaultchannel", channelEntry_.channel)) return false;
00814 
00815         return true;
00816 }

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