diff options
Diffstat (limited to 'src/ui/inputbox.cc')
-rw-r--r-- | src/ui/inputbox.cc | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/src/ui/inputbox.cc b/src/ui/inputbox.cc new file mode 100644 index 0000000..30cae3b --- /dev/null +++ b/src/ui/inputbox.cc @@ -0,0 +1,184 @@ +/* + ui/inputbox.cc + This file is part of the Osirion project and is distributed under + the terms of the GNU General Public License version 2 +*/ + +#include "ui/inputbox.h" +#include "ui/paint.h" +#include "auxiliary/functions.h" +#include "core/core.h" + +namespace ui +{ + +InputBox::InputBox(Widget *parent) : Widget(parent) +{ + input_text.clear(); + input_pos = 0; + + set_label("input"); + set_background(false); + set_border(false); +} + +InputBox::~InputBox() +{ +} + +void InputBox::clear() +{ + input_text.clear(); + input_pos = 0; +} +void InputBox::set_text(std::string const &text) +{ + input_text.assign(text); + input_pos = input_text.size(); +} + +void InputBox::set_text(const char *text) +{ + if (text) + input_text.assign(text); + else + input_text.clear(); + input_pos = input_text.size(); +} + +void InputBox::draw() +{ + draw_background(); + draw_border(); + + size_t text_width = (size_t) floorf(width() / font()->width()); + math::Vector2f v(global_location()); + paint::color(palette()->foreground()); + + // draw the part before the cursor + std::string firstpart(input_text.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 > text_width - 2) { + if (aux::is_color_code(c)) { + c++; + paint::color_code(*c); + } else { + draw_width--; + } + c++; + } + + if (*c) { + paint::text(v, size(), font(), std::string(c), AlignLeft | AlignVCenter); + } + + // draw the part behind the cursor + v.x += draw_width * font()->width(); + if (input_pos < input_text.size()) { + if (input_pos > 1 && aux::is_color_code(input_text.c_str() + input_pos -1)) { + paint::color_code(input_text[input_pos]); + } + // limit to width + std::string secondpart; + c = &input_text.c_str()[input_pos]; + while (*c && (draw_width <= (text_width - 2))) { + if (aux::is_color_code(c)) { + c++; + } else { + draw_width++; + secondpart += *c; + } + c++; + } + + paint::text(v, size(), font(), secondpart, AlignLeft | AlignVCenter); + } + + // 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); + } +} + +bool InputBox::on_keypress(const int key, const unsigned int modifier) +{ + switch (key) { + case SDLK_TAB: + // FIXME should not be here + core::CommandBuffer::complete(input_text, input_pos); + return true; + break; + + case SDLK_HOME: + input_pos = 0; + return true; + break; + + case SDLK_END: + input_pos = input_text.size(); + return true; + break; + + case SDLK_LEFT: + if (input_pos > 0) + input_pos--; + return true; + break; + + case SDLK_RIGHT: + if (input_pos < input_text.size()) + input_pos++; + return true; + break; + + case SDLK_DELETE: + if (input_text.size() && input_pos < input_text.size()) { + input_text.erase(input_pos, 1); + } + return true; + break; + + case SDLK_BACKSPACE: + if (input_text.size() && input_pos) { + input_text.erase(input_pos-1, 1); + input_pos--; + } + return true; + break; + + 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++; + return true; + } + break; + } + + return false; +} +bool InputBox::on_keyrelease(const int key, const unsigned int modifier) +{ + return false; +} + +} + + |