From d79c0223315beaf55fcd10d6891675c4d57b5e2b Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Tue, 21 Oct 2008 19:00:39 +0000 Subject: moved client console into libui --- src/client/Makefile.am | 8 +- src/client/chat.cc | 2 +- src/client/client.cc | 24 +-- src/client/client.h | 5 - src/client/console.cc | 491 ------------------------------------------------- src/client/console.h | 73 -------- src/client/input.cc | 6 +- src/client/video.cc | 2 +- src/client/view.cc | 14 +- src/ui/Makefile.am | 9 +- src/ui/console.cc | 251 +++++++++++++++++++++++++ src/ui/console.h | 73 ++++++++ src/ui/ui.cc | 18 ++ src/ui/ui.h | 9 + 14 files changed, 371 insertions(+), 614 deletions(-) delete mode 100644 src/client/console.cc delete mode 100644 src/client/console.h create mode 100644 src/ui/console.cc create mode 100644 src/ui/console.h (limited to 'src') diff --git a/src/client/Makefile.am b/src/client/Makefile.am index 9fa05e0..c855ad8 100644 --- a/src/client/Makefile.am +++ b/src/client/Makefile.am @@ -7,12 +7,12 @@ else noinst_LTLIBRARIES = libclient.la endif -libclient_la_SOURCES = action.cc chat.cc client.cc console.cc input.cc \ - joystick.cc key.cc keyboard.cc notifications.cc targets.cc video.cc view.cc +libclient_la_SOURCES = action.cc chat.cc client.cc input.cc joystick.cc key.cc \ + keyboard.cc notifications.cc targets.cc video.cc view.cc libclient_la_CFLAGS = $(LIBSDL_CFLAGS) $(GL_CFLAGS) libclient_la_LDFLAGS = -avoid-version -no-undefined $(GL_LIBS) $(LIBSDL_LIBS) -noinst_HEADERS = action.h chat.h client.h console.h input.h joystick.h key.h \ - keyboard.h notifications.h targets.h video.h view.h +noinst_HEADERS = action.h chat.h client.h input.h joystick.h key.h keyboard.h \ + notifications.h targets.h video.h view.h libclient_la_LIBADD = $(top_builddir)/src/core/libcore.la \ $(top_builddir)/src/render/librender.la $(top_builddir)/src/ui/libui.la diff --git a/src/client/chat.cc b/src/client/chat.cc index c829990..dc66a1b 100644 --- a/src/client/chat.cc +++ b/src/client/chat.cc @@ -150,7 +150,7 @@ bool Chat::on_keypress(const int key, const unsigned int modifier) void Chat::event_draw() { - if (client()->console()->visible()) + if (ui::console()->visible()) return; if (!core::application()->connected()) { diff --git a/src/client/client.cc b/src/client/client.cc index 076e72a..2400089 100644 --- a/src/client/client.cc +++ b/src/client/client.cc @@ -14,7 +14,6 @@ #include "audio/sources.h" #include "client/client.h" #include "client/video.h" -#include "client/console.h" #include "client/input.h" #include "client/view.h" #include "core/core.h" @@ -65,11 +64,6 @@ void func_ui_chatsmall(std::string const &args) } } -void func_ui_console(std::string const &args) -{ - client()->console()->toggle(); -} - //--- public ------------------------------------------------------ void client_main(int count, char **arguments) @@ -100,11 +94,9 @@ void Client::quit(int status) void Client::init(int count, char **arguments) { + client_view = 0; con_print << "^BInitializing client..." << std::endl; - client_console = 0; - client_view = 0; - // initialize core core::Cvar::sv_private = core::Cvar::set("sv_private", "0"); core::Application::init(count, arguments); @@ -128,9 +120,7 @@ void Client::init(int count, char **arguments) // initialize user interface ui::init(); - client_view = new View(ui::root()); - client_console = new Console(ui::root()); // Initialize the video subsystem if (!video::init()) { @@ -155,9 +145,6 @@ void Client::init(int count, char **arguments) func = core::Func::add("ui_chatsmall", func_ui_chatsmall); func->set_info("toggle small chat window"); - func = core::Func::add("ui_console", func_ui_console); - func->set_info("toggle console on or off"); - func = core::Func::add("snd_restart", (core::FuncPtr) func_snd_restart); func->set_info("restart audio subsystem"); @@ -174,8 +161,6 @@ void Client::run() Uint32 client_current_timestamp = 0; Uint32 client_previous_timestamp = 0; - //console()->clear_notify(); - while (true) { // current time in microseconds client_current_timestamp = SDL_GetTicks(); @@ -219,8 +204,8 @@ void Client::frame(unsigned long timestamp) core::application()->connect(""); } // show the console if everything fails - if (!core::application()->connected() && !console()->visible()) { - console()->toggle(); + if (!core::application()->connected() && !ui::console()->visible()) { + ui::console()->toggle(); } } else { // show the main menu on non-interactive modules @@ -243,7 +228,6 @@ void Client::shutdown() core::Func::remove("r_restart"); core::Func::remove("ui_chat"); core::Func::remove("ui_chatsmall"); - core::Func::remove("ui_console"); core::Func::remove("snd_restart"); audio::shutdown(); @@ -271,6 +255,8 @@ void Client::notify_disconnect() audio::reset(); render::reset(); input::reset(); + + // TODO clear chat and notifications } void Client::notify_zonechange() diff --git a/src/client/client.h b/src/client/client.h index d7e3cc0..6fb294d 100644 --- a/src/client/client.h +++ b/src/client/client.h @@ -8,7 +8,6 @@ #define __INCLUDED_CLIENT_H__ #include "core/application.h" -#include "client/console.h" #include "client/view.h" /// client part of the engine @@ -57,16 +56,12 @@ public: /// the main client view inline View *view() { return client_view; } - /// the client console - inline Console *console() { return client_console; } - protected: /// run a client frame virtual void frame(unsigned long timestamp); private: View *client_view; - Console *client_console; unsigned long previous_timestamp; }; diff --git a/src/client/console.cc b/src/client/console.cc deleted file mode 100644 index f4f66c1..0000000 --- a/src/client/console.cc +++ /dev/null @@ -1,491 +0,0 @@ -/* - client/console.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 -#include -#include - -#include "auxiliary/functions.h" -#include "audio/audio.h" -#include "client/chat.h" -#include "client/console.h" -#include "client/video.h" -#include "client/keyboard.h" -#include "core/core.h" -#include "filesystem/filesystem.h" -#include "render/gl.h" -#include "ui/paint.h" - -namespace client { - -const float DEFAULT_CONSOLE_HEIGHT = 0.7f; -const size_t DEFAULT_MAX_HISTO_LINES = 512; - -// the global console buffer object -ConsoleBuffer Console::con_buffer; - -/* -- ConsoleBuffer ------------------------------------------------ */ -ConsoleBuffer::ConsoleBuffer() : sys::ConsoleInterface() -{ - //con_print << "^BInitializing console..." << std::endl; - -} - -ConsoleBuffer::~ConsoleBuffer() -{ - //con_print << "^BShutting down console..." << std::endl; -} - -//--- Console ----------------------------------------------------- - -Console::Console(ui::Widget *parent) : ui::Window(parent) -{ - set_visible(false); - set_border(false); - set_background(true); - set_label("console"); - - history.clear(); - history.push_back(""); - history_pos = history.rbegin(); - - console_scrollpane = new ui::ScrollPane(this, con_buffer.log()); - console_scrollpane->set_border(false); - console_scrollpane->set_scroll(0); - - console_input = new ui::InputBox(this); - console_input->set_focus(); - console_input->set_border(false); - console_input->set_background(false); - console_input->set_prompt("^N>"); - - load_history(); -} - -Console::~Console() -{ - save_history(); - history.clear(); -} - -void Console::show() -{ - ui::Window::show(); - SDL_WM_GrabInput(SDL_GRAB_OFF); - SDL_ShowCursor(SDL_ENABLE); - - console_scrollpane->set_scroll(0); - - history_pos = history.rbegin(); - (*history_pos).clear(); - console_input->set_text((*history_pos)); - - audio::play("ui/console"); -} - -void Console::hide() -{ - ui::Window::hide(); - SDL_WM_GrabInput(SDL_GRAB_ON); - SDL_ShowCursor(SDL_DISABLE); - - audio::play("ui/console"); -} - -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; - - ui::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 (console_input->text().size()) { - // store input in history - while (history.size() >= DEFAULT_MAX_HISTO_LINES) { - history.pop_front(); - } - core::cmd() << console_input->text() << std::endl; - con_print << "^B>" << console_input->text() << std::endl; - (*history.rbegin()).assign(console_input->text()); - history.push_back(""); - history_pos = history.rbegin(); - console_input->set_text((*history_pos)); - } - return true; - break; - - case SDLK_UP: - upit = history_pos; - ++upit; - if (upit != history.rend()) { - history_pos = upit; - console_input->set_text((*history_pos)); - } - return true; - break; - case SDLK_DOWN: - if (history_pos != history.rbegin()) { - --history_pos; - console_input->set_text((*history_pos)); - } - return true; - break; - case SDLK_PAGEUP: - console_scrollpane->inc_scroll(scroll_offset); - return true; - break; - - case SDLK_PAGEDOWN: - console_scrollpane->dec_scroll(scroll_offset); - return true; - break; - } - - return false; -} - -void Console::draw() -{ - if (core::application()->connected()) { - set_size(parent()->size().width(), parent()->size().height() * DEFAULT_CONSOLE_HEIGHT); - } else { - set_size(parent()->size()); - } - - math::Vector2f s(size()); - s.x -= 8; - s.y -= 8; - - console_scrollpane->set_location(4, 4); - console_scrollpane->set_size(s.x, s.y - font()->height()); - - console_input->set_location(4, height() - font()->height() -4); - console_input->set_size(s.x, font()->height()); - - std::string version(core::name()); - version += ' '; - version.append(core::version()); - - render::gl::color(0.0f, 1.0f, 0.0f, 0.5f); - - s.assign(version.size() * font()->width(), font()->height()); - math::Vector2f l(global_location()); - l.x += width() - s.width() -4; - l.y += height() - s.height() -4; - ui::paint::text(l, s, font(), version); - -/* - render::Text::setfont(font()->name().c_str(), font()->width(), font()->height()); - render::gl::enable(GL_TEXTURE_2D); - - // 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); - - // draw the console log() - if (console_scroll > log().size()) - console_scroll = log().size(); - - int height = (size_t) (this->height() / font()->height()) -1; - int width = (size_t) ((this->width()-8) / font()->width()); - int bottom = (int) log().size() - console_scroll; - int current_line = 0; - - ui::Text lines; - for (ui::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; - size_t word_length = 0; - - std::string line; - size_t line_length = 0; - - const char *c = linedata.c_str(); - char pen = 'N'; - char wordpen = 'N'; - - while (*c) { - - // color code - if (aux::is_color_code(c)) { - c++; - pen = *c; - word += '^'; - word += pen; - } - - // new word, wrap if necessary - else if ((*c == '\n' ) || ( *c == ' ')) { - - if (line_length + word_length > (size_t) width) { - if (line.size()) { - lines.push_back(line); - line.clear(); - line += '^'; - line += wordpen; - line_length = 0; - } - } - - line.append(word); - line_length += word_length; - - word.clear(); - word_length = 0; - wordpen = pen; - - // new line - if (*c == '\n' ) { - lines.push_back(line); - line.clear(); - line_length = 0; - // new word - } else if (*c == ' ' ) { - line += ' '; - line_length++; - } - } - - // new character - else { - word += *c; - word_length++; - - if (word_length == (size_t) width) { - if (line.size()) { - lines.push_back(line); - line.clear(); - line += '^'; - line += wordpen; - line_length = 0; - } - - line.append(word); - line_length = word_length; - - word.clear(); - word_length = 0; - wordpen = pen; - } - } - - c++; - } - - } - current_line++; - } - - float y = this->height()-2*font()->height()-4; - render::Text::setcolor('N'); - for (ui::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::save_history() -{ - 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; - } - ui::Text::iterator it; - size_t l = 1; - for (it = history.begin(); it != history.end(); it++) { - if (l < history.size()) - ofs << (*it) << std::endl; - l++; - } - - ofs.close(); -} - -void Console::load_history() -{ - 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; - } - - 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; - size_t word_length = 0; - - std::string line; - size_t line_length = 0; - - const char *c = linedata.c_str(); - char pen = 'N'; - char wordpen = 'N'; - render::Text::setcolor('N'); - - while (*c) { - - // color code - if (aux::is_color_code(c)) { - c++; - pen = *c; - word += '^'; - word += pen; - } - - // new word, wrap if necessary - else if ((*c == '\n' ) || ( *c == ' ')) { - - if (line_length + word_length > width) { - if (line.size()) { - render::Text::draw(4, h, line); - h += font()->width(); - line.clear(); - line += '^'; - line += wordpen; - line_length = 0; - } - } - - line.append(word); - line_length += word_length; - - word.clear(); - word_length = 0; - wordpen = pen; - - // new line - if (*c == '\n' ) { - render::Text::draw(4, h, line); - h += font()->width(); - line.clear(); - line_length = 0; - // new word - } else if (*c == ' ' ) { - line += ' '; - line_length++; - } - } - - // new character - else { - word += *c; - word_length++; - - if (word_length == width) { - if (line.size()) { - render::Text::draw(4, h, line); - h += font()->width(); - line.clear(); - line += '^'; - line += wordpen; - line_length = 0; - } - - line.append(word); - line_length = word_length; - - word.clear(); - word_length = 0; - wordpen = pen; - } - } - - c++; - } - - } - n = (n+1) % MAXNOTIFYLINES; - } -} - - -void Console::clear_notify() -{ - for (size_t i=0; i < MAXNOTIFYLINES; i++) { - notify_text[i].clear(); - notify_time[i] = 0; - } - notify_pos = 0; -} - -void Console::notify(std::string const & message) -{ - // save notification - notify_text[notify_pos] = message; - notify_time[notify_pos] = core::application()->time(); - notify_pos = (notify_pos+1) % MAXNOTIFYLINES; -} -*/ - -} // namespace client - diff --git a/src/client/console.h b/src/client/console.h deleted file mode 100644 index 40bf4c1..0000000 --- a/src/client/console.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - client/console.h - This file is part of the Osirion project and is distributed under - the terms of the GNU General Public License version 2 -*/ - -#ifndef __INCLUDED_CLIENT_CONSOLE_H__ -#define __INCLUDED_CLIENT_CONSOLE_H__ - -#include "sys/consoleinterface.h" -#include "ui/inputbox.h" -#include "ui/scrollpane.h" -#include "ui/window.h" - -namespace client { - -/* -- class ConsoleBuffer ------------------------------------------ */ - -/// client console buffer -/** stores incoming console messages - */ -class ConsoleBuffer : public sys::ConsoleInterface { -public: - ConsoleBuffer(); - virtual ~ConsoleBuffer(); -}; - -/* -- class Console ------------------------------------------------ */ - -/// client system console widget -class Console : public ui::Window { -public: - Console(Widget *parent); - virtual ~Console(); - - /// load input history - void load_history(); - - /// save input history - void save_history(); - - /// show console - virtual void show(); - - /// hide console - virtual void hide(); - - void toggle(); - -protected: - - /// draw the client console - virtual void draw(); - - /// handle keypress events - virtual bool on_keypress(const int key, const unsigned int modifier); - -private: - // input history - ui::Text history; - ui::Text::reverse_iterator history_pos; - - // console widget - ui::InputBox *console_input; - ui::ScrollPane *console_scrollpane; - - // console buffer - static ConsoleBuffer con_buffer; -}; - -} - -#endif // __INCLUDED_CLIENT_CONSOLE_H__ diff --git a/src/client/input.cc b/src/client/input.cc index 1e018f5..aa4a954 100644 --- a/src/client/input.cc +++ b/src/client/input.cc @@ -8,9 +8,7 @@ #include "audio/audio.h" #include "auxiliary/functions.h" -#include "client/chat.h" #include "client/client.h" -#include "client/console.h" #include "client/input.h" #include "client/joystick.h" #include "client/keyboard.h" @@ -485,7 +483,7 @@ void key_pressed(Key *key) render::Camera::set_direction(0.0f); render::Camera::set_pitch(0.0f); - client()->console()->toggle(); + ui::console()->toggle(); return; } @@ -774,7 +772,7 @@ void frame() mouse_deadzone = false; if (core::application()->connected() && core::localcontrol()) { - mouse_control = client()->console()->hidden() && !ui::root()->active() && ((input_mousecontrol->value() > 0) || (mouse_control_override && (mouse_control_override_time + (input_mousedelay->value() / 1000.0f) < core::application()->time()))); + mouse_control = ui::console()->hidden() && !ui::root()->active() && ((input_mousecontrol->value() > 0) || (mouse_control_override && (mouse_control_override_time + (input_mousedelay->value() / 1000.0f) < core::application()->time()))); if (mouse_control && joystick_control && ((render::Camera::mode() == render::Camera::Track) || (render::Camera::mode() == render::Camera::Cockpit))) { if (!(mouse_control_override && (mouse_control_override_time + (input_mousedelay->value() / 1000.0f) < core::application()->time()))) { diff --git a/src/client/video.cc b/src/client/video.cc index 7649449..0fd702f 100644 --- a/src/client/video.cc +++ b/src/client/video.cc @@ -152,7 +152,7 @@ bool init() ui::root()->event_resize(); // to grab or not to grab - if (client()->console()->visible()) { + if (ui::console()->visible()) { SDL_WM_GrabInput(SDL_GRAB_OFF); SDL_ShowCursor(SDL_ENABLE); } else { diff --git a/src/client/view.cc b/src/client/view.cc index 8eaf63f..77e0906 100644 --- a/src/client/view.cc +++ b/src/client/view.cc @@ -14,7 +14,6 @@ #include "auxiliary/functions.h" #include "client/client.h" #include "client/chat.h" -#include "client/console.h" #include "client/input.h" #include "client/targets.h" #include "client/video.h" @@ -35,9 +34,6 @@ core::Cvar *draw_stats = 0; core::Cvar *draw_devinfo = 0; core::Cvar *draw_keypress = 0; -core::Cvar *ui_pointercolor = 0; -core::Cvar *ui_pointerhovercolor = 0; - unsigned long previousframe = 0; void time_to_stream(std::stringstream &str, float time) @@ -248,7 +244,7 @@ void View::draw() view_keypress->set_visible(draw_keypress->value() ? true : false); if (core::application()->connected() && core::game()->interactive()) { - if (client()->console()->visible()) { + if (ui::console()->visible()) { view_notify->set_visible(false); } else if (view_chat->visible() && !view_chat->small()) { view_notify->set_visible(false); @@ -278,12 +274,6 @@ void init() draw_ui = core::Cvar::get("draw_ui", "1", core::Cvar::Archive); draw_ui->set_info("[bool] draw the user interface"); - ui_pointercolor = core::Cvar::get("ui_pointercolor", "0 .5 0", core::Cvar::Archive); - ui_pointercolor->set_info("[r g b] mouse pointer color"); - - ui_pointerhovercolor = core::Cvar::get("ui_pointerhovercolor", "0 1 0", core::Cvar::Archive); - ui_pointerhovercolor->set_info("[r g b] mouse pointer hover color"); - targets::init(); previousframe = 0; @@ -645,7 +635,7 @@ void draw_hud() void draw_cursor() { - if (client()->console()->visible()) { + if (ui::console()->visible()) { ui::root()->set_pointer(); } else if(ui::root()->active()) { diff --git a/src/ui/Makefile.am b/src/ui/Makefile.am index a3084af..b2126fd 100644 --- a/src/ui/Makefile.am +++ b/src/ui/Makefile.am @@ -7,9 +7,10 @@ else noinst_LTLIBRARIES = libui.la endif -noinst_HEADERS = bitmap.h button.h container.h definitions.h font.h inputbox.h label.h \ +noinst_HEADERS = bitmap.h button.h console.h container.h definitions.h font.h inputbox.h label.h \ menu.h paint.h palette.h scrollpane.h ui.h widget.h window.h -libui_la_SOURCES = bitmap.cc button.cc container.cc font.cc inputbox.cc \ - label.cc menu.cc paint.cc palette.cc scrollpane.cc ui.cc widget.cc window.cc -libui_la_LDFLAGS = -avoid-version -no-undefined \ No newline at end of file +libui_la_SOURCES = bitmap.cc button.cc console.cc console.h container.cc \ + font.cc inputbox.cc label.cc menu.cc paint.cc palette.cc scrollpane.cc ui.cc \ + widget.cc window.cc +libui_la_LDFLAGS = -avoid-version -no-undefined diff --git a/src/ui/console.cc b/src/ui/console.cc new file mode 100644 index 0000000..759d67d --- /dev/null +++ b/src/ui/console.cc @@ -0,0 +1,251 @@ +/* + client/console.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 +#include +#include + +#include "auxiliary/functions.h" +#include "audio/audio.h" +#include "core/core.h" +#include "filesystem/filesystem.h" +#include "render/gl.h" +#include "ui/console.h" +#include "ui/paint.h" + +namespace ui { + +const float DEFAULT_CONSOLE_HEIGHT = 0.7f; +const size_t DEFAULT_MAX_HISTO_LINES = 512; + +// the global console buffer object +ConsoleBuffer Console::con_buffer; + +/* -- ConsoleBuffer ------------------------------------------------ */ +ConsoleBuffer::ConsoleBuffer() : sys::ConsoleInterface() +{ + //con_print << "^BInitializing console..." << std::endl; + +} + +ConsoleBuffer::~ConsoleBuffer() +{ + //con_print << "^BShutting down console..." << std::endl; +} + +//--- Console ----------------------------------------------------- + +Console::Console(ui::Widget *parent) : ui::Window(parent) +{ + set_visible(false); + set_border(false); + set_background(true); + set_label("console"); + + history.clear(); + history.push_back(""); + history_pos = history.rbegin(); + + console_scrollpane = new ui::ScrollPane(this, con_buffer.log()); + console_scrollpane->set_border(false); + console_scrollpane->set_scroll(0); + + console_input = new ui::InputBox(this); + console_input->set_focus(); + console_input->set_border(false); + console_input->set_background(false); + console_input->set_prompt("^N>"); + + load_history(); +} + +Console::~Console() +{ + save_history(); + history.clear(); +} + +void Console::show() +{ + ui::Window::show(); + SDL_WM_GrabInput(SDL_GRAB_OFF); + SDL_ShowCursor(SDL_ENABLE); + + console_scrollpane->set_scroll(0); + + history_pos = history.rbegin(); + (*history_pos).clear(); + console_input->set_text((*history_pos)); + + audio::play("ui/console"); +} + +void Console::hide() +{ + ui::Window::hide(); + SDL_WM_GrabInput(SDL_GRAB_ON); + SDL_ShowCursor(SDL_DISABLE); + + audio::play("ui/console"); +} + +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; + + ui::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 (console_input->text().size()) { + // store input in history + while (history.size() >= DEFAULT_MAX_HISTO_LINES) { + history.pop_front(); + } + core::cmd() << console_input->text() << std::endl; + con_print << "^B>" << console_input->text() << std::endl; + (*history.rbegin()).assign(console_input->text()); + history.push_back(""); + history_pos = history.rbegin(); + console_input->set_text((*history_pos)); + } + return true; + break; + + case SDLK_UP: + upit = history_pos; + ++upit; + if (upit != history.rend()) { + history_pos = upit; + console_input->set_text((*history_pos)); + } + return true; + break; + case SDLK_DOWN: + if (history_pos != history.rbegin()) { + --history_pos; + console_input->set_text((*history_pos)); + } + return true; + break; + case SDLK_PAGEUP: + console_scrollpane->inc_scroll(scroll_offset); + return true; + break; + + case SDLK_PAGEDOWN: + console_scrollpane->dec_scroll(scroll_offset); + return true; + break; + } + + return false; +} + +void Console::draw() +{ + if (core::application()->connected()) { + set_size(parent()->size().width(), parent()->size().height() * DEFAULT_CONSOLE_HEIGHT); + } else { + set_size(parent()->size()); + } + + math::Vector2f s(size()); + s.x -= 8; + s.y -= 8; + + console_scrollpane->set_location(4, 4); + console_scrollpane->set_size(s.x, s.y - font()->height()); + + console_input->set_location(4, height() - font()->height() -4); + console_input->set_size(s.x, font()->height()); + + std::string version(core::name()); + version += ' '; + version.append(core::version()); + + render::gl::color(0.0f, 1.0f, 0.0f, 0.5f); + + s.assign(version.size() * font()->width(), font()->height()); + math::Vector2f l(global_location()); + l.x += width() - s.width() -4; + l.y += height() - s.height() -4; + ui::paint::text(l, s, font(), version); +} + +void Console::save_history() +{ + 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; + } + ui::Text::iterator it; + size_t l = 1; + for (it = history.begin(); it != history.end(); it++) { + if (l < history.size()) + ofs << (*it) << std::endl; + l++; + } + + ofs.close(); +} + +void Console::load_history() +{ + 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; + } + + history.clear(); + char line[MAXCMDSIZE]; + while (ifs.getline(line, MAXCMDSIZE-1)) { + history.push_back(line); + } + + ifs.close(); + + history.push_back(""); + history_pos = history.rbegin(); +} + +} + diff --git a/src/ui/console.h b/src/ui/console.h new file mode 100644 index 0000000..2cec72e --- /dev/null +++ b/src/ui/console.h @@ -0,0 +1,73 @@ +/* + ui/console.h + This file is part of the Osirion project and is distributed under + the terms of the GNU General Public License version 2 +*/ + +#ifndef __INCLUDED_UI_CONSOLE_H__ +#define __INCLUDED_UI_CONSOLE_H__ + +#include "sys/consoleinterface.h" +#include "ui/inputbox.h" +#include "ui/scrollpane.h" +#include "ui/window.h" + +namespace ui { + +/* -- class ConsoleBuffer ------------------------------------------ */ + +/// client console buffer +/** stores incoming console messages + */ +class ConsoleBuffer : public sys::ConsoleInterface { +public: + ConsoleBuffer(); + virtual ~ConsoleBuffer(); +}; + +/* -- class Console ------------------------------------------------ */ + +/// client system console widget +class Console : public Window { +public: + Console(Widget *parent); + virtual ~Console(); + + /// load input history + void load_history(); + + /// save input history + void save_history(); + + /// show console + virtual void show(); + + /// hide console + virtual void hide(); + + void toggle(); + +protected: + + /// draw the client console + virtual void draw(); + + /// handle keypress events + virtual bool on_keypress(const int key, const unsigned int modifier); + +private: + // input history + Text history; + Text::reverse_iterator history_pos; + + // console widget + InputBox *console_input; + ScrollPane *console_scrollpane; + + // console buffer + static ConsoleBuffer con_buffer; +}; + +} + +#endif // __INCLUDED_UI_CONSOLE_H__ diff --git a/src/ui/ui.cc b/src/ui/ui.cc index bacc753..c5fdfac 100644 --- a/src/ui/ui.cc +++ b/src/ui/ui.cc @@ -43,6 +43,12 @@ void func_ui_restart(std::string const &args) } } + +void func_ui_console(std::string const &args) +{ + console()->toggle(); +} + void func_list_menu(std::string const &args) { if (global_ui) { @@ -171,6 +177,9 @@ void init() func = core::Func::add("ui_restart", func_ui_restart); func->set_info("[command] [options] reload user interface files"); + + func = core::Func::add("ui_console", func_ui_console); + func->set_info("toggle console on or off"); func = core::Func::add("menu", func_menu); func->set_info("[command] menu functions"); @@ -183,6 +192,7 @@ void shutdown() core::Func::remove("list_ui"); core::Func::remove("list_menu"); core::Func::remove("menu"); + core::Func::remove("ui_console"); core::Func::remove("ui"); if (global_ui) { @@ -200,6 +210,9 @@ UI::UI() : Window(0) set_border(false); set_background(false); + // intialize console + ui_console = new Console(this); + // default palette ui_palette = new Palette(); set_palette(ui_palette); @@ -404,6 +417,11 @@ void UI::show_menu(const char *label) ui_active_menu->show(); set_pointer("pointer"); + + // raise console if it is visible + if (ui_console->visible()) + ui_console->show(); + } else { con_warn << "Unknown window '" << label << "'" << std::endl; } diff --git a/src/ui/ui.h b/src/ui/ui.h index 97577c6..f41df24 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -7,6 +7,7 @@ #ifndef __INCLUDED_UI_H__ #define __INCLUDED_UI_H__ +#include "ui/console.h" #include "ui/font.h" #include "ui/palette.h" #include "ui/widget.h" @@ -41,6 +42,9 @@ public: /// show previous window void previous_menu(); + + /// the console + inline Console *console() { return ui_console; } /// return the active menu Window *active() { @@ -111,6 +115,8 @@ private: Window *ui_active_menu; Widget *ui_mouse_focus; Widget *ui_input_focus; + + Console *ui_console; Menus ui_menus; @@ -130,6 +136,9 @@ void shutdown(); /// the global root window UI *root(); +/// the console +inline Console *console() { return root()->console(); } + /// debug mode inline bool debug() { return UI::ui_debug; } -- cgit v1.2.3