From 56cdfd3822d2800abdd2f912ab7f76a5764793a7 Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Sun, 19 Oct 2008 13:45:07 +0000 Subject: scrollpane widget, updated chatbox --- src/client/chat.cc | 61 +++++++++++----- src/client/chat.h | 7 +- src/client/client.cc | 1 + src/client/console.cc | 64 ++++++++++------- src/client/console.h | 25 +++---- src/client/view.cc | 25 +++---- src/client/view.h | 2 +- src/core/gameserver.cc | 2 +- src/sys/consoleinterface.cc | 2 +- src/ui/Makefile.am | 8 +-- src/ui/button.cc | 7 +- src/ui/button.h | 4 +- src/ui/container.cc | 3 - src/ui/definitions.h | 5 ++ src/ui/inputbox.cc | 55 ++++++++++---- src/ui/inputbox.h | 13 +++- src/ui/label.cc | 9 +-- src/ui/label.h | 5 +- src/ui/paint.cc | 77 ++++++++++---------- src/ui/paint.h | 18 ++--- src/ui/palette.cc | 25 +++++-- src/ui/palette.h | 18 ++++- src/ui/scrollpane.cc | 172 ++++++++++++++++++++++++++++++++++++++++++++ src/ui/scrollpane.h | 47 ++++++++++++ src/ui/ui.cc | 9 +++ src/ui/ui.h | 7 +- src/ui/widget.cc | 34 +++++---- src/ui/widget.h | 4 +- src/ui/window.cc | 3 - 29 files changed, 520 insertions(+), 192 deletions(-) create mode 100644 src/ui/scrollpane.cc create mode 100644 src/ui/scrollpane.h diff --git a/src/client/chat.cc b/src/client/chat.cc index 9d51adc..af50dff 100644 --- a/src/client/chat.cc +++ b/src/client/chat.cc @@ -12,7 +12,8 @@ namespace client { -const size_t DEFAULT_MAX_HISTO_LINES = 512; +const size_t DEFAULT_CHAT_LOG_SIZE = 256; +const size_t DEFAULT_CHAT_HISTO_SIZE = 512; Chat::Chat(ui::Widget *parent) : ui::Window(parent) { @@ -21,12 +22,12 @@ Chat::Chat(ui::Widget *parent) : ui::Window(parent) history.push_back(""); history_pos = history.rbegin(); - chat_label = new ui::Label(this, "^BSay^F:^B"); - chat_label->set_alignment(ui::AlignLeft | ui::AlignVCenter); - chat_label->set_border(false); + chat_scrollpane = new ui::ScrollPane(this, chat_log); + chat_scrollpane->set_border(false); chat_input = new ui::InputBox(this); chat_input->set_border(false); + chat_input->set_prompt("^BSay^F:^B "); chat_input->set_focus(); @@ -39,6 +40,13 @@ Chat::~Chat() history.clear(); } +void Chat::event_text(const std::string & text) +{ + while (chat_log.size() >= DEFAULT_CHAT_LOG_SIZE) { + chat_log.pop_front(); + } + chat_log.push_back(text); +} void Chat::show() { @@ -47,6 +55,8 @@ void Chat::show() history_pos = history.rbegin(); (*history_pos).clear(); chat_input->set_text((*history_pos)); + + chat_scrollpane->set_scroll(0); } void Chat::toggle() @@ -57,17 +67,11 @@ void Chat::toggle() show(); } -void Chat::resize() -{ - chat_label->set_location(font()->width(), height() / 5.0f); - chat_label->set_size(width() - font()->width() * 2, height() / 5.0f); - - chat_input->set_location(font()->width(), height() / 5.0f * 3.0f); - chat_input->set_size(width() - font()->width() * 2, height() / 5.0f); -} - bool Chat::on_keypress(const int key, const unsigned int modifier) { + // number of lines to scroll + const size_t scroll_offset = 3; + History::reverse_iterator upit; switch( key ) { @@ -81,7 +85,7 @@ bool Chat::on_keypress(const int key, const unsigned int modifier) case SDLK_RETURN: if (chat_input->text().size()) { // store input into history - while (history.size() >= DEFAULT_MAX_HISTO_LINES) { + while (history.size() >= DEFAULT_CHAT_HISTO_SIZE) { history.pop_front(); } @@ -95,9 +99,9 @@ bool Chat::on_keypress(const int key, const unsigned int modifier) history.push_back(""); history_pos = history.rbegin(); chat_input->set_text((*history_pos)); + } else { + hide(); } - - hide(); return true; break; @@ -118,6 +122,16 @@ bool Chat::on_keypress(const int key, const unsigned int modifier) } return true; break; + + case SDLK_PAGEUP: + chat_scrollpane->inc_scroll(scroll_offset); + return true; + break; + + case SDLK_PAGEDOWN: + chat_scrollpane->dec_scroll(scroll_offset); + return true; + break; } return false; @@ -136,4 +150,19 @@ void Chat::event_draw() Widget::event_draw(); } +void Chat::resize() +{ + const float margin = 8.0f; + math::Vector2f s(size()); + s.x -= margin*2; + s.y -= margin*2; + + chat_scrollpane->set_location(margin, margin); + chat_scrollpane->set_size(s.x, s.y - font()->height() *1.5f); + + chat_input->set_location(margin, height() - font()->height() - margin); + chat_input->set_size(s.x, font()->height()); +} + + } // namespace client diff --git a/src/client/chat.h b/src/client/chat.h index c7232a9..1ea1765 100644 --- a/src/client/chat.h +++ b/src/client/chat.h @@ -11,7 +11,7 @@ #include #include "ui/inputbox.h" -#include "ui/label.h" +#include "ui/scrollpane.h" #include "ui/window.h" namespace client { @@ -25,6 +25,8 @@ public: virtual void show(); void toggle(); + void event_text(const std::string & text); + protected: virtual void event_draw(); virtual void resize(); @@ -33,7 +35,8 @@ protected: private: - ui::Label *chat_label; + ui::Text chat_log; + ui::ScrollPane *chat_scrollpane; ui::InputBox *chat_input; typedef std::deque History; diff --git a/src/client/client.cc b/src/client/client.cc index 13c6214..45cc47a 100644 --- a/src/client/client.cc +++ b/src/client/client.cc @@ -294,6 +294,7 @@ void Client::notify_message(core::Message::Channel const channel, std::string co } con_print << message << std::endl; + view()->chat()->event_text(message); //console()->notify(message); } diff --git a/src/client/console.cc b/src/client/console.cc index 3b94b4d..f4f66c1 100644 --- a/src/client/console.cc +++ b/src/client/console.cc @@ -16,8 +16,8 @@ #include "client/keyboard.h" #include "core/core.h" #include "filesystem/filesystem.h" -#include "render/render.h" -#include "render/textures.h" +#include "render/gl.h" +#include "ui/paint.h" namespace client { @@ -48,15 +48,19 @@ Console::Console(ui::Widget *parent) : ui::Window(parent) set_background(true); set_label("console"); - console_scroll = 0; 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(); } @@ -73,7 +77,8 @@ void Console::show() SDL_WM_GrabInput(SDL_GRAB_OFF); SDL_ShowCursor(SDL_ENABLE); - console_scroll = 0; + console_scrollpane->set_scroll(0); + history_pos = history.rbegin(); (*history_pos).clear(); console_input->set_text((*history_pos)); @@ -103,7 +108,7 @@ bool Console::on_keypress(const int key, const unsigned int modifier) // number of lines to scroll const size_t scroll_offset = 3; - Text::reverse_iterator upit; + ui::Text::reverse_iterator upit; switch( key ) { @@ -154,17 +159,12 @@ bool Console::on_keypress(const int key, const unsigned int modifier) return true; break; case SDLK_PAGEUP: - console_scroll += scroll_offset; - if (console_scroll > log().size()) - console_scroll = log().size(); + console_scrollpane->inc_scroll(scroll_offset); return true; break; case SDLK_PAGEDOWN: - if (console_scroll > scroll_offset) - console_scroll -= scroll_offset; - else - console_scroll = 0; + console_scrollpane->dec_scroll(scroll_offset); return true; break; } @@ -172,7 +172,7 @@ bool Console::on_keypress(const int key, const unsigned int modifier) return false; } -void Console::event_draw() +void Console::draw() { if (core::application()->connected()) { set_size(parent()->size().width(), parent()->size().height() * DEFAULT_CONSOLE_HEIGHT); @@ -180,17 +180,29 @@ void Console::event_draw() set_size(parent()->size()); } - ui::Window::event_draw(); -} + math::Vector2f s(size()); + s.x -= 8; + s.y -= 8; -void Console::draw() -{ - console_input->set_size(this->width(), font()->height()); - console_input->set_location(0, this->height()-font()->height()); + 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()); - draw_background(); - draw_border(); + 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); @@ -210,8 +222,8 @@ void Console::draw() int bottom = (int) log().size() - console_scroll; int current_line = 0; - Text lines; - for (Text::iterator it = log().begin(); it != log().end() && current_line < bottom; it++) { + 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'; @@ -300,13 +312,13 @@ void Console::draw() 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) { + 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() @@ -322,7 +334,7 @@ void Console::save_history() con_warn << "Could not write " << filename << std::endl; return; } - Text::iterator it; + ui::Text::iterator it; size_t l = 1; for (it = history.begin(); it != history.end(); it++) { if (l < history.size()) diff --git a/src/client/console.h b/src/client/console.h index c567d70..40bf4c1 100644 --- a/src/client/console.h +++ b/src/client/console.h @@ -8,8 +8,9 @@ #define __INCLUDED_CLIENT_CONSOLE_H__ #include "sys/consoleinterface.h" -#include "ui/window.h" #include "ui/inputbox.h" +#include "ui/scrollpane.h" +#include "ui/window.h" namespace client { @@ -29,8 +30,6 @@ public: /// client system console widget class Console : public ui::Window { public: - typedef std::deque Text; - Console(Widget *parent); virtual ~Console(); @@ -49,30 +48,24 @@ public: void toggle(); protected: - /// draw event - virtual void event_draw(); - /// draw the client console text + /// draw the client console virtual void draw(); /// handle keypress events virtual bool on_keypress(const int key, const unsigned int modifier); private: - inline Text & log() { return con_buffer.log(); } - // input history - Text history; - Text::reverse_iterator history_pos; - - // scroll position - size_t console_scroll; + ui::Text history; + ui::Text::reverse_iterator history_pos; - // input widget - ui::InputBox *console_input; + // console widget + ui::InputBox *console_input; + ui::ScrollPane *console_scrollpane; // console buffer - static ConsoleBuffer con_buffer; + static ConsoleBuffer con_buffer; }; } diff --git a/src/client/view.cc b/src/client/view.cc index 13feade..a5da7d4 100644 --- a/src/client/view.cc +++ b/src/client/view.cc @@ -52,13 +52,12 @@ void time_to_stream(std::stringstream &str, float time) DevInfo::DevInfo(ui::Widget *parent) : ui::Widget(parent) { set_label("devinfo"); - set_border(true); + set_border(false); + set_background(false); } void DevInfo::draw() { - draw_border(); - std::stringstream textstream; core::Entity *target = targets::current(); float d = 0; @@ -88,7 +87,7 @@ void DevInfo::draw() } ui::paint::color(palette()->foreground()); - ui::paint::text(global_location(), font(), textstream); + ui::paint::text(global_location(), size(), font(), textstream); } /* -- Stats -------------------------------------------------------- */ @@ -96,7 +95,8 @@ void DevInfo::draw() Stats::Stats(ui::Widget *parent) : ui::Widget(parent) { set_label("stats"); - set_border(true); + set_border(false); + set_background(false); // clear counters for (size_t i =0; i < fps_counter_size; i++) @@ -111,8 +111,6 @@ Stats::Stats(ui::Widget *parent) : ui::Widget(parent) void Stats::draw() { - draw_border(); - // average fps fps_counter_time[fps_counter_index] = core::application()->time(); fps_counter_index = (fps_counter_index + 1 ) % fps_counter_size; @@ -157,7 +155,7 @@ void Stats::draw() } ui::paint::color(palette()->foreground()); - ui::paint::text(global_location(), font(), textstream); + ui::paint::text(global_location(), size(), font(), textstream); } /* -- KeyPress ----------------------------------------------------- */ @@ -165,16 +163,15 @@ void Stats::draw() KeyPress::KeyPress(ui::Widget *parent) : Widget(parent) { set_label("keypress"); - set_border(true); + set_border(false); + set_background(false); } void KeyPress::draw() { - draw_border(); - if(input::last_key_pressed()) { ui::paint::color(palette()->highlight()); - ui::paint::text(global_location(), size(), font(), input::last_key_pressed()->name(), ui::AlignCenter); + ui::paint::label(global_location(), size(), font(), input::last_key_pressed()->name(), ui::AlignCenter); } } @@ -212,8 +209,8 @@ void View::resize() set_size(parent()->size()); // reposition chat widget - view_chat->set_size(font()->width()*64, font()->height()*5); - view_chat->set_location(font()->width() * 0.5f, height() *0.5f); + view_chat->set_size(font()->width()*64, height() * 0.5f); + view_chat->set_location(font()->width(), height() - view_chat->height() - font()->height() * 4); // reposition devinfo widget view_devinfo->set_size(font()->width()*32, font()->height()*5); diff --git a/src/client/view.h b/src/client/view.h index dbbd7be..960e633 100644 --- a/src/client/view.h +++ b/src/client/view.h @@ -17,7 +17,7 @@ namespace client const size_t fps_counter_size = 32; // fps is the average of 32 frames const size_t net_counter_size = 128; // net is the average of 128 frames -//// a widget to show developer info +/// a widget to show developer info class DevInfo : public ui::Widget { public: diff --git a/src/core/gameserver.cc b/src/core/gameserver.cc index e73c6ce..4da0be6 100644 --- a/src/core/gameserver.cc +++ b/src/core/gameserver.cc @@ -277,7 +277,7 @@ void GameServer::say(Player *player, std::string const &message) std::string notification("^B"); notification.append(player->name()); - notification.append("^F:^B "); + notification.append("^F:^N "); notification.append(message); broadcast_message(Message::Public, notification); diff --git a/src/sys/consoleinterface.cc b/src/sys/consoleinterface.cc index 284a48d..438a8de 100644 --- a/src/sys/consoleinterface.cc +++ b/src/sys/consoleinterface.cc @@ -204,7 +204,7 @@ void ConsoleInterface::event_text(const std::string & text) consoleinterface_log.pop_front(); } - consoleinterface_log.push_back(std::string(text)); + consoleinterface_log.push_back(text); print(text); } } diff --git a/src/ui/Makefile.am b/src/ui/Makefile.am index 4bfad3d..a3084af 100644 --- a/src/ui/Makefile.am +++ b/src/ui/Makefile.am @@ -8,8 +8,8 @@ noinst_LTLIBRARIES = libui.la endif noinst_HEADERS = bitmap.h button.h container.h definitions.h font.h inputbox.h label.h \ - menu.h paint.h palette.h ui.h widget.h window.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 ui.cc widget.cc window.cc -libui_la_LDFLAGS = -avoid-version -no-undefined +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 diff --git a/src/ui/button.cc b/src/ui/button.cc index e36d036..856c165 100644 --- a/src/ui/button.cc +++ b/src/ui/button.cc @@ -46,9 +46,6 @@ void Button::set_command(const std::string &command) void Button::draw_border() { - if (!border()) - return; - if (has_mouse_focus()) paint::color(palette()->foreground()); else @@ -57,7 +54,7 @@ void Button::draw_border() paint::border(global_location(), size()); } -void Button::draw_text() +void Button::draw() { if (!text().size()) return; @@ -67,7 +64,7 @@ void Button::draw_text() else paint::color(palette()->foreground()); - paint::text(global_location(), size(), font(), text(), alignment()); + paint::label(global_location(), size(), font(), text(), alignment()); } bool Button::on_keypress(const int key, const unsigned int modifier) diff --git a/src/ui/button.h b/src/ui/button.h index b1bb522..24097ae 100644 --- a/src/ui/button.h +++ b/src/ui/button.h @@ -46,8 +46,8 @@ protected: /// draw the button border virtual void draw_border(); - /// draw the button text - virtual void draw_text(); + /// draw the button + virtual void draw(); private: std::string button_command; diff --git a/src/ui/container.cc b/src/ui/container.cc index 37fbea8..977ff4d 100644 --- a/src/ui/container.cc +++ b/src/ui/container.cc @@ -58,9 +58,6 @@ void Container::set_margin(const float margin) void Container::draw_border() { - if (!border()) - return; - if(focus()) { paint::color(palette()->foreground()); } else { diff --git a/src/ui/definitions.h b/src/ui/definitions.h index ea3e040..e04082f 100644 --- a/src/ui/definitions.h +++ b/src/ui/definitions.h @@ -7,6 +7,9 @@ #ifndef __INCLUDED_UI_DEFINITIONS_H__ #define __INCLUDED_UI_DEFINITIONS_H__ +#include +#include + namespace ui { @@ -25,6 +28,8 @@ enum Alignment { const float pointer_size = 48.0f; +typedef std::deque Text; + } #endif // __INCLUDED_UI_DEFINITIONS_H__ diff --git a/src/ui/inputbox.cc b/src/ui/inputbox.cc index 30cae3b..39f8393 100644 --- a/src/ui/inputbox.cc +++ b/src/ui/inputbox.cc @@ -16,6 +16,7 @@ InputBox::InputBox(Widget *parent) : Widget(parent) { input_text.clear(); input_pos = 0; + input_max = 512; set_label("input"); set_background(false); @@ -46,15 +47,38 @@ void InputBox::set_text(const char *text) input_pos = input_text.size(); } +void InputBox::set_prompt(const std::string &prompt) +{ + input_prompt.assign(prompt); +} + +void InputBox::set_prompt(const char *prompt) +{ + if (!prompt) + input_prompt.clear(); + else + input_prompt.assign(prompt); +} + +void InputBox::set_max(const size_t max) +{ + input_max = max; +} + void InputBox::draw() { - draw_background(); - draw_border(); - size_t text_width = (size_t) floorf(width() / font()->width()); + size_t prompt_width = aux::text_length(input_prompt); math::Vector2f v(global_location()); - paint::color(palette()->foreground()); + paint::color(palette()->text()); + // draw the prompt + if (prompt_width) { + paint::text(v, size(), font(), input_prompt); + v.x += prompt_width * font()->width(); + } + paint::color(palette()->text()); + // draw the part before the cursor std::string firstpart(input_text.substr(0, input_pos)); size_t draw_width = 0; @@ -70,7 +94,7 @@ void InputBox::draw() } c = firstpart.c_str(); - while (*c && draw_width > text_width - 2) { + while (*c && draw_width > text_width - prompt_width - 1) { if (aux::is_color_code(c)) { c++; paint::color_code(*c); @@ -81,7 +105,7 @@ void InputBox::draw() } if (*c) { - paint::text(v, size(), font(), std::string(c), AlignLeft | AlignVCenter); + paint::text(v, size(), font(), std::string(c)); } // draw the part behind the cursor @@ -93,7 +117,7 @@ void InputBox::draw() // limit to width std::string secondpart; c = &input_text.c_str()[input_pos]; - while (*c && (draw_width <= (text_width - 2))) { + while (*c && (draw_width <= (text_width - prompt_width - 1))) { if (aux::is_color_code(c)) { c++; } else { @@ -103,14 +127,14 @@ void InputBox::draw() c++; } - paint::text(v, size(), font(), secondpart, AlignLeft | AlignVCenter); + paint::text(v, size(), font(), secondpart); } // draw the cursor if (has_input_focus() && (core::application()->time() - ::floorf(core::application()->time())) < 0.5f) { std::string cursor("^B"); cursor += (char) 11; - paint::text(v, size(), font(), cursor, AlignLeft | AlignVCenter); + paint::text(v, size(), font(), cursor); } } @@ -162,11 +186,14 @@ bool InputBox::on_keypress(const int key, const unsigned int modifier) default: if ((key >= 32) && (key <175)) { - if (input_pos == input_text.size()) - input_text += (char)key; - else - input_text.insert(input_pos, 1, (char)key); - input_pos++; + if (input_text.size() < input_max) { + // TODO bell sound + if (input_pos == input_text.size()) + input_text += (char)key; + else + input_text.insert(input_pos, 1, (char)key); + input_pos++; + } return true; } break; diff --git a/src/ui/inputbox.h b/src/ui/inputbox.h index 557ca6c..961bbcf 100644 --- a/src/ui/inputbox.h +++ b/src/ui/inputbox.h @@ -20,10 +20,19 @@ public: ~InputBox(); /// set the text displayed by the label - void set_text(std::string const &text); + void set_text(const std::string &text); /// set the text displayed by the label void set_text(const char *text); + + /// set the prompt + void set_prompt(const std::string &prompt); + + /// set the prompt + void set_prompt(const char *prompt); + + /// set the maximal input width + void set_max(const size_t max); /// return the text displayed by the label inline std::string const &text() const { @@ -46,7 +55,9 @@ protected: private: std::string input_text; + std::string input_prompt; size_t input_pos; + size_t input_max; }; } diff --git a/src/ui/label.cc b/src/ui/label.cc index 80e493e..cf9b473 100644 --- a/src/ui/label.cc +++ b/src/ui/label.cc @@ -49,19 +49,12 @@ void Label::set_alignment(const unsigned int alignment) } void Label::draw() -{ - Widget::draw(); - - draw_text(); -} - -void Label::draw_text() { if (!label_text.size()) return; paint::color(palette()->foreground()); - paint::text(global_location(), size(), font(), text(), alignment()); + paint::label(global_location(), size(), font(), text(), alignment()); } } diff --git a/src/ui/label.h b/src/ui/label.h index b7925c7..beecfb4 100644 --- a/src/ui/label.h +++ b/src/ui/label.h @@ -45,10 +45,7 @@ public: protected: /// draw the label virtual void draw(); - - /// draw the label text - virtual void draw_text(); - + private: std::string label_text; unsigned int label_alignment; diff --git a/src/ui/paint.cc b/src/ui/paint.cc index d50e3b5..45b7eea 100644 --- a/src/ui/paint.cc +++ b/src/ui/paint.cc @@ -32,7 +32,7 @@ void color_code(const char c) render::Text::setcolor(c); } -void border(math::Vector2f const &location, math::Vector2f const &size) +void border(const math::Vector2f &location, const math::Vector2f &size) { using namespace render::gl; @@ -44,7 +44,7 @@ void border(math::Vector2f const &location, math::Vector2f const &size) end(); } -void rectangle(math::Vector2f const &location, math::Vector2f const &size) +void rectangle(const math::Vector2f &location, const math::Vector2f &size) { using namespace render::gl; @@ -56,9 +56,9 @@ void rectangle(math::Vector2f const &location, math::Vector2f const &size) end(); } -void bitmap(math::Vector2f const &location, math::Vector2f const &size, std::string const &texture) +// draw a bitmap +void bitmap(const math::Vector2f &location, const math::Vector2f &size, std::string const &texture) { - using namespace render::gl; render::Textures::bind("bitmaps/" + texture); @@ -82,41 +82,8 @@ void bitmap(math::Vector2f const &location, math::Vector2f const &size, std::str disable(GL_TEXTURE_2D); } -void text_centered(math::Vector2f const &location, math::Vector2f const &size, std::string const &text, Font const *font) -{ - using namespace render::gl; - - render::Text::setfont(font->name().c_str(), font->width(), font->height()); - enable(GL_TEXTURE_2D); - - math::Vector2f v(location); - - v.x += (size.x - aux::text_strip(text).size() * font->width()) /2.0f; - v.y += (size.y - font->height()) / 2.0f; - - render::Text::draw(v.x, v.y, text); - - disable(GL_TEXTURE_2D); -} - -void text(math::Vector2f const &location, Font const *font, std::stringstream & textstream) -{ - using namespace render::gl; - render::Text::setfont(font->name().c_str(), font->width(), font->height()); - - // enable OpenGL textures - enable(GL_TEXTURE_2D); - - render::Text::draw(location.x, location.y, textstream); - - // disable texturing - disable(GL_TEXTURE_2D); -} - -void text(math::Vector2f const &location, math::Vector2f const &size, - Font const *font, - std::string const &text, - unsigned int align) +// draw aligned text +void label(const math::Vector2f &location, const math::Vector2f &size, const Font *font, const std::string &text, unsigned int align) { unsigned int align_horizontal = (align & 0x000F); if (!align_horizontal) @@ -167,11 +134,41 @@ void text(math::Vector2f const &location, math::Vector2f const &size, render::Text::draw(v.x, v.y, text); - // disable texturing + // disable OpenGL textures disable(GL_TEXTURE_2D); } +// draw unaligned text +void text(const math::Vector2f &location, const math::Vector2f &size, const Font *font, const std::string &text) +{ + using namespace render::gl; + render::Text::setfont(font->name().c_str(), font->width(), font->height()); + + // enable OpenGL textures + enable(GL_TEXTURE_2D); + + render::Text::draw(location.x, location.y, text); + + // disable OpenGL textures + disable(GL_TEXTURE_2D); +} + +// draw unaligned text +void text(const math::Vector2f &location, const math::Vector2f &size, const Font *font, std::stringstream & textstream) +{ + using namespace render::gl; + render::Text::setfont(font->name().c_str(), font->width(), font->height()); + + // enable OpenGL textures + enable(GL_TEXTURE_2D); + + render::Text::draw(location.x, location.y, textstream); + + // disable OpenGL textures + disable(GL_TEXTURE_2D); +} + } } diff --git a/src/ui/paint.h b/src/ui/paint.h index c90f1b5..95f1c62 100644 --- a/src/ui/paint.h +++ b/src/ui/paint.h @@ -25,20 +25,22 @@ void color(math::Color const & color); void color_code(const char c); /// draw a border -void border(math::Vector2f const &location, math::Vector2f const &size); +void border(const math::Vector2f &location, const math::Vector2f &size); /// draw a rectangle -void rectangle(math::Vector2f const &location, math::Vector2f const &size); +void rectangle(const math::Vector2f &location, const math::Vector2f &size); /// draw a rectangular bitmap -void bitmap(math::Vector2f const &location, math::Vector2f const &size, std::string const &texture); +void bitmap(const math::Vector2f &location, const math::Vector2f &size, std::string const &texture); -/// draw one line of text from a string -void text(math::Vector2f const &location, math::Vector2f const &size, Font const *font, - std::string const &text, unsigned int align = AlignCenter); +/// draw aligned text +void label(const math::Vector2f &location, const math::Vector2f &size, const Font *font, const std::string &text, unsigned int align = AlignCenter); -/// draw unaligned text from a stringstream -void text(math::Vector2f const &location, Font const *font, std::stringstream & textstream); +/// draw unaligned text +void text(const math::Vector2f &location, const math::Vector2f &size, const Font *font, const std::string &text); + +/// draw unaligned text +void text(const math::Vector2f &location, const math::Vector2f &size, const Font *font, std::stringstream & textstream); } diff --git a/src/ui/palette.cc b/src/ui/palette.cc index 3a9dc78..79388d8 100644 --- a/src/ui/palette.cc +++ b/src/ui/palette.cc @@ -12,12 +12,15 @@ namespace ui Palette::Palette() { - palette_foreground.assign(0.8f, 1.0f); - palette_highlight.assign(1.0f, 1.0f); - palette_background.assign(0.5f, 0.5f); - palette_border.assign(0.0f, 0.8f, 0.0f); - palette_pointer.assign(0.0f, 0.5f, 0.0f); + palette_foreground.assign(1.0f, 1.0f); + palette_highlight.assign(1.0f, 1.0f, 0.5f); + palette_text.assign(0.75f); + palette_background.assign(0.5f, 0.75f); + palette_border.assign(0.0f, 0.8f, 0.0f, 0.5f); + palette_pointer.assign(0.0f, 0.75f, 0.0f); palette_active.assign(0.0f, 1.0f, 0.0f); + + palette_debug.assign(1.0f, 0.0f, 1.0f, 0.75f); } Palette::~Palette() @@ -45,6 +48,8 @@ const math::Color &Palette::color(Color palettecolor) const case Active: return active(); break; + case Debug: + return debug(); default: return foreground(); break; @@ -61,6 +66,11 @@ void Palette::set_highlight(math::Color const &color) palette_highlight.assign(color); } +void Palette::set_text(math::Color const &color) +{ + palette_text.assign(color); +} + void Palette::set_background(math::Color const &color) { palette_background.assign(color); @@ -81,5 +91,10 @@ void Palette::set_active(math::Color const &color) palette_active.assign(color); } +void Palette::set_debug(math::Color const &color) +{ + palette_debug.assign(color); +} + } diff --git a/src/ui/palette.h b/src/ui/palette.h index 41eee03..1ef49c7 100644 --- a/src/ui/palette.h +++ b/src/ui/palette.h @@ -19,11 +19,15 @@ public: Palette(); ~Palette(); - enum Color { Foreground=0, Background=1, Highlight=2, Border=3, Pointer=4, Active=5 }; + enum Color { Foreground=0, Background=1, Highlight=2, Border=3, Pointer=4, Active=5, Debug=6 }; + /// set foreground color void set_foreground(math::Color const &color); + /// set highlight color void set_highlight(math::Color const &color); + + void set_text(math::Color const &color); void set_background(math::Color const &color); @@ -32,6 +36,8 @@ public: void set_pointer(math::Color const &color); void set_active(math::Color const &color); + + void set_debug(math::Color const &olor); inline const math::Color &foreground() const { return palette_foreground; @@ -40,6 +46,10 @@ public: inline const math::Color &highlight() const { return palette_highlight; } + + inline const math::Color &text() const { + return palette_text; + } inline const math::Color &background() const { return palette_background; @@ -57,6 +67,10 @@ public: return palette_active; } + inline const math::Color &debug() const { + return palette_debug; + } + const math::Color &color(Palette::Color palettecolor) const; private: @@ -67,6 +81,8 @@ private: math::Color palette_pointer; math::Color palette_active; math::Color palette_border; + math::Color palette_debug; + math::Color palette_text; }; } diff --git a/src/ui/scrollpane.cc b/src/ui/scrollpane.cc new file mode 100644 index 0000000..69bc159 --- /dev/null +++ b/src/ui/scrollpane.cc @@ -0,0 +1,172 @@ +/* + ui/scrollpane.cc + This file is part of the Osirion project and is distributed under + the terms of the GNU General Public License version 2 +*/ + +#include + +#include "ui/scrollpane.h" +#include "render/text.h" +#include "render/gl.h" + +namespace ui +{ + +ScrollPane::ScrollPane(Widget *parent, ui::Text &text) : Widget(parent), scrollpane_text(text) +{ + set_label("scrollpane"); +} + +ScrollPane::~ScrollPane() +{ +} + +void ScrollPane::set_scroll(int scroll) +{ + scrollpane_scroll = scroll; + + if (scrollpane_scroll > (int) scrollpane_text.size()) + scrollpane_scroll = (int) scrollpane_text.size(); + else if (scrollpane_scroll < 0) + scrollpane_scroll = 0; +} + +void ScrollPane::inc_scroll(int scroll) +{ + scrollpane_scroll += scroll; + + if (scrollpane_scroll > (int) scrollpane_text.size()) + scrollpane_scroll = (int) scrollpane_text.size(); +} + +void ScrollPane::dec_scroll(int scroll) +{ + scrollpane_scroll -= scroll; + + if (scrollpane_scroll < 0) + scrollpane_scroll = 0; +} + +void ScrollPane::draw() +{ + render::Text::setfont(font()->name().c_str(), font()->width(), font()->height()); + render::gl::enable(GL_TEXTURE_2D); + + // text size + int text_height = (int) floorf(height() / font()->height()); + int text_width = (int) floorf(width() / font()->width()); + + // validate scroll position + if (scrollpane_scroll > (int) scrollpane_text.size()) + scrollpane_scroll = (int) scrollpane_text.size(); + else if (scrollpane_scroll < 0) + scrollpane_scroll = 0; + + int bottom = (int) scrollpane_text.size() - scrollpane_scroll; + int current_line = 0; + + ui::Text lines; + + for (ui::Text::const_iterator it = scrollpane_text.begin(); it != scrollpane_text.end() && current_line < bottom; it++) { + if (current_line >= bottom - text_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) text_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) text_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++; + } + + render::gl::color(palette()->text()); + const math ::Vector2f gl(global_location()); + float y = height() - font()->height(); + + for (ui::Text::reverse_iterator rit = lines.rbegin(); (y >= 0) && (rit != lines.rend()); ++rit) { + render::Text::draw(gl.x, gl.y + y, (*rit)); + y -= font()->height(); + } + + render::gl::disable(GL_TEXTURE_2D); +} + +} + + diff --git a/src/ui/scrollpane.h b/src/ui/scrollpane.h new file mode 100644 index 0000000..47e68ee --- /dev/null +++ b/src/ui/scrollpane.h @@ -0,0 +1,47 @@ +/* + ui/scrollpane.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_SCROLLPANE_H__ +#define __INCLUDED_UI_SCROLLPANE_H__ + +#include "ui/widget.h" +#include "ui/definitions.h" + +namespace ui +{ + +/// a widget displaying centered text +class ScrollPane : public Widget +{ +public: + ScrollPane(Widget *parent, ui::Text &text); + ~ScrollPane(); + + /// set scroll + void set_scroll(int scroll); + + /// increase scroll + void inc_scroll(int scroll); + + /// decrease scroll + void dec_scroll(int scroll); + + /// current scroll position + inline int scroll() const { return scrollpane_scroll; } + +protected: + /// draw the scroll pane + virtual void draw(); + +private: + ui::Text &scrollpane_text; + int scrollpane_scroll; +}; + +} + +#endif // __INCLUDED_UI_SCROLLPANE_H__ + diff --git a/src/ui/ui.cc b/src/ui/ui.cc index 1ecfbb1..bacc753 100644 --- a/src/ui/ui.cc +++ b/src/ui/ui.cc @@ -25,6 +25,8 @@ namespace ui /* -- static functions --------------------------------------------- */ +bool UI::ui_debug = false; + UI *global_ui = 0; void func_list_ui(std::string const &args) @@ -52,6 +54,7 @@ void help() { con_print << "^BUser interface functions" << std::endl; con_print << " ui help show this help" << std::endl; + con_print << " ui debug toggle debug mode" << std::endl; con_print << " ui list list widgets" << std::endl; con_print << " ui show show user interface" << std::endl; con_print << " ui hide hide user interface" << std::endl; @@ -76,6 +79,8 @@ void func_ui(std::string const &args) if (command.compare("help") == 0) { help(); + } else if (command.compare("debug") == 0) { + UI::ui_debug = !UI::ui_debug; } else if (command.compare("list") == 0) { global_ui->list(); } else if (command.compare("show") == 0) { @@ -291,6 +296,8 @@ void UI::load() } else if (ini.got_key_color("highlight", color)) { ui_palette->set_highlight(color); continue; + } else if (ini.got_key_color("text", color)) { + ui_palette->set_text(color); } else if (ini.got_key_color("background", color)) { ui_palette->set_background(color); continue; @@ -301,6 +308,8 @@ void UI::load() ui_palette->set_pointer(color); } else if (ini.got_key_color("active", color)) { ui_palette->set_active(color); + } else if (ini.got_key_color("debug", color)) { + ui_palette->set_debug(color); } else { ini.unkown_key(); } diff --git a/src/ui/ui.h b/src/ui/ui.h index 24f9793..97577c6 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -83,6 +83,8 @@ public: /// set mouse pointer bitmap void set_pointer(const char *pointerbitmap=0, const Palette::Color color = Palette::Highlight,const bool animated = false); + static bool ui_debug; + protected: typedef std::list Menus; @@ -98,7 +100,7 @@ protected: /// handle key release events virtual bool on_keyrelease(const int key, const unsigned int modifier); - + private: void draw_pointer(); @@ -128,6 +130,9 @@ void shutdown(); /// the global root window UI *root(); +/// debug mode +inline bool debug() { return UI::ui_debug; } + } #endif // __INCLUDED_UI_H__ diff --git a/src/ui/widget.cc b/src/ui/widget.cc index 606c4ab..046cb01 100644 --- a/src/ui/widget.cc +++ b/src/ui/widget.cc @@ -200,7 +200,7 @@ void Widget::set_size(float const w, float const h) widget_size.assign(w, h); } -void Widget::set_size(math::Vector2f const &size) +void Widget::set_size(const math::Vector2f &size) { widget_size.assign(size); } @@ -329,7 +329,13 @@ void Widget::event_draw() { if (!visible()) return; - + + if (widget_background) + draw_background(); + if (widget_border) + draw_border(); + if (debug()) + draw_debug_border(); draw(); for (Children::iterator it = widget_children.begin(); it != widget_children.end(); it++) { @@ -371,32 +377,30 @@ bool Widget::on_keyrelease(const int key, const unsigned int modifier) /* -- draw functions ----------------------------------------------- */ -void Widget::resize() -{ -} - -void Widget::draw() +void Widget::draw_debug_border() { - draw_background(); - draw_border(); + paint::color(1.0f, 0.0f, 1.0f, 0.5f); + paint::border(global_location(), size()); } void Widget::draw_background() { - if (!widget_background) - return; - paint::color(palette()->background()); paint::rectangle(global_location(), size()); } void Widget::draw_border() { - if (!widget_border) - return; - paint::color(palette()->border()); paint::border(global_location(), size()); } +void Widget::draw() +{ +} + +void Widget::resize() +{ +} + } diff --git a/src/ui/widget.h b/src/ui/widget.h index ef386c0..60670b6 100644 --- a/src/ui/widget.h +++ b/src/ui/widget.h @@ -149,7 +149,7 @@ public: void set_size(float const w, float const h); /// set the widgets width and height - void set_size(math::Vector2f const &size); + void set_size(const math::Vector2f &size); /// set the widgets width void set_width(float const w); @@ -282,6 +282,8 @@ protected: virtual void remove_child(Widget *child); private: + void draw_debug_border(); + bool widget_visible; bool widget_background; bool widget_border; diff --git a/src/ui/window.cc b/src/ui/window.cc index 9ae9ec5..8494f34 100644 --- a/src/ui/window.cc +++ b/src/ui/window.cc @@ -47,9 +47,6 @@ void Window::clear_previous() void Window::draw_border() { - if (!border()) - return; - paint::color(palette()->border()); paint::border(global_location(), size()); } -- cgit v1.2.3