/* 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 "math/functions.h" #include "core/application.h" namespace ui { InputBox::InputBox(Widget *parent) : Widget(parent) { input_text.clear(); input_pos = 0; input_max = 512; 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::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() { 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()->text()); // draw the prompt if (prompt_width) { paint::text(v, size(), font(), input_prompt); v[0] += 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; 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 - prompt_width - 1) { 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)); } // draw the part behind the cursor v[0] += 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 - prompt_width - 1))) { if (aux::is_color_code(c)) { c++; } else { draw_width++; secondpart += *c; } c++; } 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); } // reset color paint::color(palette()->foreground()); } 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_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; } return false; } bool InputBox::on_keyrelease(const int key, const unsigned int modifier) { return false; } }