/* client/chat.cc This file is part of the Osirion project and is distributed under the terms and conditions of the GNU General Public License version 2 */ #include "core/core.h" #include "client/chat.h" #include "client/console.h" #include "client/keyboard.h" #include "render/render.h" namespace client { namespace chat { // input history std::deque history; std::deque::reverse_iterator history_pos; size_t input_pos = 0; // chatbox visibility bool chat_visible = false; //--- engine functions -------------------------------------------- void func_con_chat(std::string const &args) { std::istringstream argstream(args); int i; if (argstream >> i) { if (i) chat_visible = true; else chat_visible = false; } else chat_visible = !chat_visible; } //--- public ------------------------------------------------------ void init() { // add engine functions core::Func::add("con_chat", (core::FuncPtr) func_con_chat); history.clear(); history.push_back(""); history_pos = history.rbegin(); input_pos = 0; } void shutdown() { // remove engine functions core::Func::remove("con_chat"); history.clear(); input_pos = 0; } bool visible() { return chat_visible; } void draw() { using namespace render; if (console::visible() || !visible()) return; // draw the console input gl::enable(GL_TEXTURE_2D); gl::color(1.0f, 1.0f, 1.0f, 1.0f); draw_text(CHARWIDTH , 4 + CHARHEIGHT * (MAXNOTIFYLINES+1), "say"); gl::color(0.0f, 1.0f, .0f, 1.0f); draw_text(CHARWIDTH*4 , 4 + CHARHEIGHT * (MAXNOTIFYLINES+1), ":"); gl::color(1.0f, 1.0f, 1.0f, 1.0f); draw_text(CHARWIDTH*6, 4 + CHARHEIGHT * (MAXNOTIFYLINES+1), (*history_pos)); // draw cursor if ((core::application()->time() - ::floorf(core::application()->time())) < 0.5f) { std::string cursor("_"); draw_text(CHARWIDTH*(input_pos+6), 4 + CHARHEIGHT * (MAXNOTIFYLINES+1) , cursor); } gl::disable(GL_TEXTURE_2D); } void toggle() { chat_visible = !chat_visible; if (chat_visible) { input_pos = 0; history_pos = history.rbegin(); (*history_pos).clear(); } } void keypressed(int key) { std::deque::reverse_iterator upit; switch( key ) { case SDLK_TAB: core::CommandBuffer::complete( (*history_pos), input_pos); break; case SDLK_RETURN: if ((*history_pos).size()) { // store input into history while (history.size() >= MAXHISTOLINES) { history.pop_front(); } core::cmd() << "say " << (*history_pos) << std::endl; (*history.rbegin()) = (*history_pos); history.push_back(""); history_pos = history.rbegin(); input_pos = 0; } toggle(); break; case SDLK_UP: upit = history_pos; ++upit; if (upit != history.rend()) { history_pos = upit; input_pos = (*history_pos).size(); } break; case SDLK_DOWN: if (history_pos != history.rbegin()) { --history_pos; input_pos = (*history_pos).size(); } break; case SDLK_HOME: input_pos = 0; break; case SDLK_END: input_pos = (*history_pos).size(); break; case SDLK_LEFT: if (input_pos > 0) input_pos--; break; case SDLK_RIGHT: if (input_pos < (*history_pos).size()) input_pos++; break; case SDLK_BACKSPACE: if ((*history_pos).size() && input_pos) { (*history_pos).erase(input_pos-1, 1); input_pos--; } break; default: if ((key >= 32 ) && (key <175)) { if (input_pos == (*history_pos).size()) (*history_pos) += (char)key; else (*history_pos).insert(input_pos, 1, (char)key); input_pos++; } break; } } } }