From 1e0df536c2fae85c317ce9c3cc17603d5f98c911 Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Wed, 15 Oct 2008 20:33:15 +0000 Subject: moved client console into a Widget --- src/client/console.cc | 424 ++++++++++++++++++++++---------------------------- 1 file changed, 184 insertions(+), 240 deletions(-) (limited to 'src/client/console.cc') diff --git a/src/client/console.cc b/src/client/console.cc index 47f95f7..0ab0767 100644 --- a/src/client/console.cc +++ b/src/client/console.cc @@ -21,97 +21,112 @@ namespace client { -Console client_console; +const float DEFAULT_CONSOLE_HEIGHT = 0.7f; +const size_t DEFAULT_MAX_HISTO_LINES = 512; -Console *console() { - return &client_console; -} - -//--- public ------------------------------------------------------ - -void Console::init() +/* -- ConsoleBuffer ------------------------------------------------ */ +ConsoleBuffer::ConsoleBuffer() { con_print << "^BInitializing console..." << std::endl; - console()->load_history(); + } -void Console::shutdown() +ConsoleBuffer::~ConsoleBuffer() { con_print << "^BShutting down console..." << std::endl; - console()->save_history(); } +// the global console buffer object +ConsoleBuffer Console::con_buffer; + //--- Console ----------------------------------------------------- -Console::Console() +Console::Console(ui::Widget *parent) : ui::Window(parent) { - clear(); -} + set_visible(false); + set_border(false); + set_background(true); + set_label("console"); -Console::~Console() -{ - history.clear(); -} + //clear_notify(); + load_history(); -void Console::clear() -{ - console_visible = false; - console_scroll = 0; + console_scroll = 0; history.clear(); history.push_back(""); history_pos = history.rbegin(); - input_pos = 0; - - clear_notify(); + console_input = new ui::Input(this); + console_input->set_focus(); + console_input->set_border(false); + console_input->set_background(false); } -void Console::draw(bool draw_ui_notifications) { - flush(); - if (visible()) - draw_console(); - else if (draw_ui_notifications) - draw_notify(); +Console::~Console() +{ + save_history(); + history.clear(); } -void Console::toggle() +void Console::show() { - console_visible = !console_visible; - - if (console_visible) { - console_scroll = 0; - input_pos = 0; + ui::Window::show(); + SDL_WM_GrabInput(SDL_GRAB_OFF); + SDL_ShowCursor(SDL_ENABLE); - history_pos = history.rbegin(); - (*history_pos).clear(); + console_scroll = 0; + history_pos = history.rbegin(); + (*history_pos).clear(); + console_input->set_text((*history_pos)); - SDL_WM_GrabInput(SDL_GRAB_OFF); - SDL_ShowCursor(SDL_ENABLE); - } else { - SDL_WM_GrabInput(SDL_GRAB_ON); - SDL_ShowCursor(SDL_DISABLE); - } + audio::play("ui/console"); +} - //setkeyboardmode(console()->visible() || (core::application()->connected() && chat::visible())); +void Console::hide() +{ + ui::Window::hide(); + SDL_WM_GrabInput(SDL_GRAB_ON); + SDL_ShowCursor(SDL_DISABLE); audio::play("ui/console"); } -void Console::keypressed(unsigned int key) +void Console::toggle() +{ + if (visible()) + hide(); + else + show(); +} + +bool Console::on_keypress(const int key, const unsigned int modifier) { // number of lines to scroll const size_t scroll_offset = 3; - std::deque::reverse_iterator upit; + Text::reverse_iterator upit; switch( key ) { + + case SDLK_ESCAPE: + if (visible()) { + hide(); + return true; + } else { + return false; + } + break; +/* case SDLK_TAB: core::CommandBuffer::complete( (*history_pos), input_pos); + return true; break; +*/ case SDLK_RETURN: - if ((*history_pos).size()) { - // store input into history - while (history.size() >= MAXHISTOLINES) { + if (console_input->text().size()) { + // store input in history + (*history_pos).assign(console_input->text()); + while (history.size() >= DEFAULT_MAX_HISTO_LINES) { history.pop_front(); } @@ -121,132 +136,88 @@ void Console::keypressed(unsigned int key) history.push_back(""); history_pos = history.rbegin(); - input_pos = 0; + console_input->set_text((*history_pos)); } + return true; break; + case SDLK_UP: upit = history_pos; ++upit; if (upit != history.rend()) { history_pos = upit; - input_pos = (*history_pos).size(); + console_input->set_text((*history_pos)); } + return true; 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_DELETE: - if ((*history_pos).size() && input_pos < (*history_pos).size()) { - (*history_pos).erase(input_pos, 1); - } - break; - case SDLK_BACKSPACE: - if ((*history_pos).size() && input_pos) { - (*history_pos).erase(input_pos-1, 1); - input_pos--; + console_input->set_text((*history_pos)); } + return true; break; case SDLK_PAGEUP: console_scroll += scroll_offset; - if (console_scroll > consoleinterface_text.size()) - console_scroll = consoleinterface_text.size(); + if (console_scroll > log().size()) + console_scroll = log().size(); + return true; break; + case SDLK_PAGEDOWN: if (console_scroll > scroll_offset) console_scroll -= scroll_offset; else console_scroll = 0; - break; - default: - if ((key >= 32 ) && (key <175) && ((*history_pos).size() < MAXCMDSIZE)) { - if (input_pos == (*history_pos).size()) - (*history_pos) += (char)key; - else - (*history_pos).insert(input_pos, 1, (char)key); - input_pos++; - } + return true; break; } - + return false; } -void Console::save_history() +void Console::event_draw() { - if (history.size() <= 1) - return; - - std::string filename(filesystem::writedir()); - filename.append("history.txt"); - std::ofstream ofs(filename.c_str()); - - if (!ofs.is_open()) { - con_warn << "Could not write " << filename << std::endl; - return; - } - std::deque::iterator it; - size_t l = 1; - for (it = history.begin(); it != history.end(); it++) { - if (l < history.size()) - ofs << (*it) << std::endl; - l++; + if (core::application()->connected()) { + set_size(parent()->size().width(), parent()->size().height() * DEFAULT_CONSOLE_HEIGHT); + } else { + set_size(parent()->size()); } - ofs.close(); + ui::Window::event_draw(); } -void Console::load_history() +void Console::draw() { - std::string filename(filesystem::writedir()); - filename.append("history.txt"); - std::ifstream ifs(filename.c_str(), std::ifstream::in); - - if (!ifs.is_open()) { - con_warn << "Could not read " << filename << std::endl; - return; - } + console_input->set_size(this->width(), font()->height()); + console_input->set_location(0, this->height()-font()->height()); - history.clear(); - char line[MAXCMDSIZE]; - while (ifs.getline(line, MAXCMDSIZE-1)) { - history.push_back(line); - } + draw_background(); + draw_border(); - ifs.close(); + render::Text::setfont(font()->name().c_str(), font()->width(), font()->height()); + render::gl::enable(GL_TEXTURE_2D); - history.push_back(""); - history_pos = history.rbegin(); - input_pos = 0; -} + // draw version below the bottom of the console + std::string version(core::name()); + version += ' '; + version.append(core::version()); + render::gl::color(0.0f, 1.0f, 0.0f, 0.5f); + render::Text::draw(width()-font()->width()*(version.size()+1), height()-font()->height()-4, version); -void Console::draw_notify() -{ - using namespace render; + // draw the console log() + if (console_scroll > log().size()) + console_scroll = log().size(); + + size_t height = (size_t) (this->height() / font()->height()) -1; + size_t width = (size_t) ((this->width()-8) / font()->width()); + size_t bottom = log().size() - console_scroll; + size_t current_line = 0; - // draw notifications - size_t width = (size_t) ((video::width-8) / Text::fontwidth()); - size_t n = notify_pos % MAXNOTIFYLINES; - float h = video::height/2; - for (size_t l = 0; l < MAXNOTIFYLINES; l++) { - if (notify_text[n].size() > 2 && notify_time[n] + 5 > core::application()->time()) { - std::string linedata(notify_text[n]); + Text lines; + for (Text::iterator it = log().begin(); it != log().end() && current_line < bottom; it++) { + if (current_line >= bottom - height) { + std::string linedata(*it); linedata += '\n'; std::string word; @@ -258,7 +229,6 @@ void Console::draw_notify() const char *c = linedata.c_str(); char pen = 'N'; char wordpen = 'N'; - Text::setcolor('N'); while (*c) { @@ -275,8 +245,7 @@ void Console::draw_notify() if (line_length + word_length > width) { if (line.size()) { - Text::draw(4, h, line); - h += Text::fontheight(); + lines.push_back(line); line.clear(); line += '^'; line += wordpen; @@ -293,8 +262,7 @@ void Console::draw_notify() // new line if (*c == '\n' ) { - Text::draw(4, h, line); - h += Text::fontheight(); + lines.push_back(line); line.clear(); line_length = 0; // new word @@ -311,8 +279,7 @@ void Console::draw_notify() if (word_length == width) { if (line.size()) { - Text::draw(4, h, line); - h += Text::fontheight(); + lines.push_back(line); line.clear(); line += '^'; line += wordpen; @@ -332,49 +299,78 @@ void Console::draw_notify() } } - n = (n+1) % MAXNOTIFYLINES; + current_line++; + } + + float y = this->height()-2*font()->height()-4; + render::Text::setcolor('N'); + for (Text::reverse_iterator rit = lines.rbegin(); (y >= 4) && (rit != lines.rend()); ++rit) { + render::Text::draw(4, y, (*rit)); + y -= font()->height(); } + + render::gl::disable(GL_TEXTURE_2D); + } -void Console::draw_console() +void Console::save_history() { - using namespace render; + if (history.size() <= 1) + return; - float con_height = 0.70f; - - gl::disable(GL_TEXTURE_2D); + std::string filename(filesystem::writedir()); + filename.append("history.txt"); + std::ofstream ofs(filename.c_str()); - // draw the transparent console background - gl::color(0.0f, 0.0f, 0.0f, 0.5f); - gl::begin(gl::Quads); - gl::vertex(0.0f, 0.0f, 0.0f); - gl::vertex(video::width, 0.0f,0.0f); - gl::vertex(video::width,video::height*con_height,0.0f); - gl::vertex(0,video::height*con_height,0.0f); - gl::end(); + if (!ofs.is_open()) { + con_warn << "Could not write " << filename << std::endl; + return; + } + Text::iterator it; + size_t l = 1; + for (it = history.begin(); it != history.end(); it++) { + if (l < history.size()) + ofs << (*it) << std::endl; + l++; + } - gl::enable(GL_TEXTURE_2D); + ofs.close(); +} - // draw version below the bottom of the console - std::string version(core::name()); - version += ' '; - version.append(core::version()); - gl::color(0.0f, 1.0f, 0.0f, 0.5f); - Text::draw(video::width-Text::fontwidth()*(version.size()+1), video::height*con_height-Text::fontheight()-4, version); +void Console::load_history() +{ + std::string filename(filesystem::writedir()); + filename.append("history.txt"); + std::ifstream ifs(filename.c_str(), std::ifstream::in); - // draw the console consoleinterface_text - if (console_scroll > consoleinterface_text.size()) - console_scroll = consoleinterface_text.size(); - - size_t height = (size_t) (video::height * con_height / Text::fontheight()) -1; - size_t width = (size_t) ((video::width-8) / Text::fontwidth()); - size_t bottom = consoleinterface_text.size() - console_scroll; - size_t current_line = 0; + if (!ifs.is_open()) { + con_warn << "Could not read " << filename << std::endl; + return; + } - std::deque lines; - for (std::deque::iterator it = consoleinterface_text.begin(); it != consoleinterface_text.end() && current_line < bottom; it++) { - if (current_line >= bottom - height) { - std::string linedata(*it); + history.clear(); + char line[MAXCMDSIZE]; + while (ifs.getline(line, MAXCMDSIZE-1)) { + history.push_back(line); + } + + ifs.close(); + + history.push_back(""); + history_pos = history.rbegin(); +} + + +/* +void Console::draw_notify() +{ + // draw notifications + size_t width = (size_t) ((width()-8) / font()->width()); + size_t n = notify_pos % MAXNOTIFYLINES; + float h = height()/2; + for (size_t l = 0; l < MAXNOTIFYLINES; l++) { + if (notify_text[n].size() > 2 && notify_time[n] + 5 > core::application()->time()) { + std::string linedata(notify_text[n]); linedata += '\n'; std::string word; @@ -386,6 +382,7 @@ void Console::draw_console() const char *c = linedata.c_str(); char pen = 'N'; char wordpen = 'N'; + render::Text::setcolor('N'); while (*c) { @@ -402,7 +399,8 @@ void Console::draw_console() if (line_length + word_length > width) { if (line.size()) { - lines.push_back(line); + render::Text::draw(4, h, line); + h += font()->width(); line.clear(); line += '^'; line += wordpen; @@ -419,7 +417,8 @@ void Console::draw_console() // new line if (*c == '\n' ) { - lines.push_back(line); + render::Text::draw(4, h, line); + h += font()->width(); line.clear(); line_length = 0; // new word @@ -436,7 +435,8 @@ void Console::draw_console() if (word_length == width) { if (line.size()) { - lines.push_back(line); + render::Text::draw(4, h, line); + h += font()->width(); line.clear(); line += '^'; line += wordpen; @@ -456,65 +456,8 @@ void Console::draw_console() } } - current_line++; - } - - float y = video::height*con_height-2*Text::fontheight()-4; - Text::setcolor('N'); - for (std::deque::reverse_iterator rit = lines.rbegin(); (y >= 4) && (rit != lines.rend()); ++rit) { - Text::draw(4, y, (*rit)); - y -= Text::fontheight(); - } - - - // draw the console input - y = video::height*con_height - Text::fontheight() - 4; - Text::draw(4, y, "^B>"); - - std::string firstpart((*history_pos).substr(0, input_pos)); - size_t draw_width = 0; - const char *c = firstpart.c_str(); - - while (*c) { - if (aux::is_color_code(c)) { - c++; - } else { - draw_width++; - } - c++; - } - - c = firstpart.c_str(); - while (*c && draw_width > width - 2) { - if (aux::is_color_code(c)) { - c++; - Text::setcolor(*c); - } else { - draw_width--; - } - c++; - } - - if (*c) { - Text::draw(4+Text::fontwidth(), y, c); - } - - if (input_pos < (*history_pos).size()) { - // FIXME limit to width - if (input_pos > 1 && aux::is_color_code((*history_pos).c_str() + input_pos -1)) { - Text::setcolor((*history_pos)[input_pos]); - } - c = (*history_pos).c_str() + input_pos; - Text::draw(4+Text::fontwidth()*(draw_width+1), y, c); - } - - // draw cursor - if ((core::application()->time() - ::floorf(core::application()->time())) < 0.5f) { - std::string cursor("^B"); - cursor += (char) 11; - Text::draw(4+Text::fontwidth()*(draw_width+1), y , cursor); + n = (n+1) % MAXNOTIFYLINES; } - } @@ -534,6 +477,7 @@ void Console::notify(std::string const & message) notify_time[notify_pos] = core::application()->time(); notify_pos = (notify_pos+1) % MAXNOTIFYLINES; } +*/ } // namespace client -- cgit v1.2.3