00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "global.hpp"
00017
00018 #include "floating_textbox.hpp"
00019 #include "font.hpp"
00020 #include "game_display.hpp"
00021 #include "game_preferences.hpp"
00022 #include "log.hpp"
00023 #include "team.hpp"
00024
00025 #include <ctime>
00026
00027 namespace gui{
00028 floating_textbox::floating_textbox() :
00029 box_(NULL),
00030 check_(NULL),
00031 mode_(TEXTBOX_NONE),
00032 label_string_(),
00033 label_(0)
00034 {}
00035
00036 void floating_textbox::close(game_display& gui)
00037 {
00038 if(!active()) {
00039 return;
00040 }
00041 if(check_ != NULL) {
00042 if(mode_ == TEXTBOX_MESSAGE) {
00043 preferences::set_message_private(check_->checked());
00044 }
00045 }
00046 box_.assign(NULL);
00047 check_.assign(NULL);
00048 font::remove_floating_label(label_);
00049 mode_ = TEXTBOX_NONE;
00050 gui.invalidate_all();
00051 }
00052
00053 void floating_textbox::update_location(game_display& gui)
00054 {
00055 if (box_ == NULL)
00056 return;
00057
00058 const SDL_Rect& area = gui.map_outside_area();
00059
00060 const int border_size = 10;
00061
00062 const int ypos = area.y+area.h-30 - (check_ != NULL ? check_->height() + border_size : 0);
00063
00064 if (label_ != 0)
00065 font::remove_floating_label(label_);
00066
00067 label_ = font::add_floating_label(label_string_,font::SIZE_NORMAL,
00068 font::YELLOW_COLOUR,area.x+border_size,ypos,0,0,-1, area,font::LEFT_ALIGN);
00069
00070 if (label_ == 0)
00071 return;
00072
00073 const SDL_Rect& label_area = font::get_floating_label_rect(label_);
00074 const int textbox_width = area.w - label_area.w - border_size*3;
00075
00076 if(textbox_width <= 0) {
00077 font::remove_floating_label(label_);
00078 return;
00079 }
00080
00081 if(box_ != NULL) {
00082 box_->set_volatile(true);
00083 const SDL_Rect rect = {
00084 area.x + label_area.w + border_size*2, ypos,
00085 textbox_width, box_->height()
00086 };
00087 box_->set_location(rect);
00088 }
00089
00090 if(check_ != NULL) {
00091 check_->set_volatile(true);
00092 check_->set_location(box_->location().x,box_->location().y + box_->location().h + border_size);
00093 }
00094 }
00095
00096 void floating_textbox::show(gui::TEXTBOX_MODE mode, const std::string& label,
00097 const std::string& check_label, bool checked, game_display& gui)
00098 {
00099 close(gui);
00100
00101 label_string_ = label;
00102 mode_ = mode;
00103
00104 if(check_label != "") {
00105 check_.assign(new gui::button(gui.video(),check_label,gui::button::TYPE_CHECK));
00106 check_->set_check(checked);
00107 }
00108
00109
00110 box_.assign(new gui::textbox(gui.video(),100,"",true,256,0.8,0.6));
00111
00112 update_location(gui);
00113 }
00114
00115 void floating_textbox::tab(std::vector<team>& teams, const unit_map& , game_display& gui)
00116 {
00117 if(active() == false) {
00118 return;
00119 }
00120
00121 switch(mode_) {
00122 case gui::TEXTBOX_SEARCH:
00123 case gui::TEXTBOX_COMMAND:
00124 case gui::TEXTBOX_MESSAGE:
00125 {
00126 std::string text = box_->text();
00127 std::vector<std::string> matches;
00128
00129 for(size_t n = 0; n != teams.size(); ++n) {
00130 if(teams[n].is_empty()) continue;
00131 matches.push_back(teams[n].current_player());
00132 }
00133
00134 const std::set<std::string>& observers = gui.observers();
00135 for(std::set<std::string>::const_iterator i = observers.begin();
00136 i != observers.end(); ++i)
00137 {
00138 matches.push_back(*i);
00139 }
00140
00141 std::sort<std::vector<std::string>::iterator>
00142 (matches.begin(), matches.end());
00143 matches.erase(std::unique(matches.begin(), matches.end()), matches.end());
00144
00145 if (mode_ == gui::TEXTBOX_MESSAGE) {
00146 matches.erase(std::remove(matches.begin(), matches.end(),
00147 preferences::login()), matches.end());
00148 }
00149 const bool line_start = utils::word_completion(text, matches);
00150
00151 if (matches.empty()) return;
00152 if (matches.size() == 1 && mode_ == gui::TEXTBOX_MESSAGE) {
00153 text.append(line_start ? ": " : " ");
00154 } else {
00155 std::string completion_list = utils::join(matches, ' ');
00156 gui.add_chat_message(time(NULL), "", 0, completion_list,
00157 game_display::MESSAGE_PRIVATE, false);
00158 }
00159 box_->set_text(text);
00160 break;
00161 }
00162 default:
00163 LOG_STREAM(err, display) << "unknown textbox mode\n";
00164 }
00165 }
00166 }