#include #include #include #include "Config.h" #include "interface/Point.h" #include "interface/Textbox.h" #include "interface/Keys.h" using namespace ui; Textbox::Textbox(Point position, Point size, std::string textboxText, std::string textboxPlaceholder): Label(position, size, ""), actionCallback(NULL), masked(false), border(true), mouseDown(false) { placeHolder = textboxPlaceholder; SetText(textboxText); cursor = text.length(); } Textbox::~Textbox() { if(actionCallback) delete actionCallback; } void Textbox::SetText(std::string newText) { backingText = newText; if(masked) { std::string maskedText = std::string(newText); std::fill(maskedText.begin(), maskedText.end(), '\x8D'); Label::SetText(maskedText); } else Label::SetText(newText); if(cursor) { cursorPosition = Graphics::textnwidth((char *)text.c_str(), cursor); } else { cursorPosition = 0; } } void Textbox::SetDisplayText(std::string newText) { Label::SetText(text); } std::string Textbox::GetText() { return backingText; } void Textbox::OnKeyPress(int key, Uint16 character, bool shift, bool ctrl, bool alt) { bool changed = false; try { switch(key) { case KEY_HOME: cursor = 0; break; case KEY_END: cursor = backingText.length(); break; case KEY_LEFT: if(cursor > 0) cursor--; break; case KEY_RIGHT: if(cursor < backingText.length()) cursor++; break; case KEY_DELETE: if(HasSelection()) { if(getLowerSelectionBound() < 0 || getHigherSelectionBound() > backingText.length()) return; backingText.erase(backingText.begin()+getLowerSelectionBound(), backingText.begin()+getHigherSelectionBound()); cursor = getLowerSelectionBound(); changed = true; } else if(backingText.length() && cursor < backingText.length()) { if(ctrl) backingText.erase(cursor, backingText.length()-cursor); else backingText.erase(cursor, 1); changed = true; } break; case KEY_BACKSPACE: if(HasSelection()) { if(getLowerSelectionBound() < 0 || getHigherSelectionBound() > backingText.length()) return; backingText.erase(backingText.begin()+getLowerSelectionBound(), backingText.begin()+getHigherSelectionBound()); cursor = getLowerSelectionBound(); changed = true; } else if(backingText.length() && cursor > 0) { if(ctrl) { backingText.erase(0, cursor); cursor = 0; } else { backingText.erase(cursor-1, 1); cursor--; } changed = true; } break; } if(character >= ' ' && character < 127) { if(HasSelection()) { if(getLowerSelectionBound() < 0 || getHigherSelectionBound() > backingText.length()) return; backingText.erase(backingText.begin()+getLowerSelectionBound(), backingText.begin()+getHigherSelectionBound()); cursor = getLowerSelectionBound(); } if(cursor == backingText.length()) { backingText += character; } else { backingText.insert(cursor, 1, (char)character); } cursor++; changed = true; } ClearSelection(); } catch(std::out_of_range &e) { cursor = 0; backingText = ""; } if(changed) { if(masked) { std::string maskedText = std::string(backingText); std::fill(maskedText.begin(), maskedText.end(), '\x8D'); Label::SetText(maskedText); } else { text = backingText; } if(actionCallback) actionCallback->TextChangedCallback(this); } if(multiline) updateMultiline(); updateSelection(); TextPosition(text); if(cursor) { cursorPosition = Graphics::textnwidth((char *)text.c_str(), cursor); } else { cursorPosition = 0; } } void Textbox::OnMouseClick(int x, int y, unsigned button) { mouseDown = true; cursor = Graphics::CharIndexAtPosition((char*)text.c_str(), x-textPosition.X, y-textPosition.Y); if(cursor) { cursorPosition = Graphics::textnwidth((char *)text.c_str(), cursor); } else { cursorPosition = 0; } Label::OnMouseClick(x, y, button); } void Textbox::OnMouseUp(int x, int y, unsigned button) { mouseDown = false; Label::OnMouseUp(x, y, button); } void Textbox::OnMouseMoved(int localx, int localy, int dx, int dy) { if(mouseDown) { cursor = Graphics::CharIndexAtPosition((char*)text.c_str(), localx-textPosition.X, localy-textPosition.Y); if(cursor) { cursorPosition = Graphics::textnwidth((char *)text.c_str(), cursor); } else { cursorPosition = 0; } } Label::OnMouseMoved(localx, localy, dx, dy); } void Textbox::Draw(const Point& screenPos) { Label::Draw(screenPos); Graphics * g = Engine::Ref().g; if(IsFocused()) { if(border) g->drawrect(screenPos.X, screenPos.Y, Size.X, Size.Y, 255, 255, 255, 255); g->draw_line(screenPos.X+textPosition.X+cursorPosition, screenPos.Y+3, screenPos.X+textPosition.X+cursorPosition, screenPos.Y+12, 255, 255, 255, XRES+BARSIZE); } else { if(!text.length()) { g->drawtext(screenPos.X+textPosition.X, screenPos.Y+textPosition.Y, placeHolder, textColour.Red, textColour.Green, textColour.Blue, 170); } if(border) g->drawrect(screenPos.X, screenPos.Y, Size.X, Size.Y, 160, 160, 160, 255); } } /* Textbox::Textbox(Point position, Point size, std::string textboxText): Component(position, size), text(textboxText), actionCallback(NULL), masked(false), border(true) { SetText(textboxText); cursor = text.length(); } Textbox::~Textbox() { if(actionCallback) delete actionCallback; } void Textbox::TextPosition() { if(cursor) { cursorPosition = Graphics::textnwidth((char *)displayText.c_str(), cursor); } else { cursorPosition = 0; } Component::TextPosition(displayText); } void Textbox::SetText(std::string text) { cursor = text.length(); this->text = text; this->displayText = text; TextPosition(); } void Textbox::SetDisplayText(std::string text) { displayText = text; TextPosition(); } std::string Textbox::GetText() { return text; } void Textbox::OnKeyPress(int key, Uint16 character, bool shift, bool ctrl, bool alt) { bool changed = false; try { switch(key) { case KEY_HOME: cursor = 0; break; case KEY_END: cursor = text.length(); break; case KEY_LEFT: if(cursor > 0) cursor--; break; case KEY_RIGHT: if(cursor < text.length()) cursor++; break; case KEY_DELETE: if(text.length() && cursor < text.length()) { if(ctrl) text.erase(cursor, text.length()-cursor); else text.erase(cursor, 1); changed = true; } break; case KEY_BACKSPACE: if(text.length() && cursor > 0) { if(ctrl) { text.erase(0, cursor); cursor = 0; } else { text.erase(cursor-1, 1); cursor--; } changed = true; } break; } if(character >= ' ' && character < 127) { if(cursor == text.length()) { text += character; } else { text.insert(cursor, 1, (char)character); } cursor++; changed = true; } } catch(std::out_of_range &e) { cursor = 0; text = ""; } if(changed) { if(masked) { char * tempText = new char[text.length()+1]; std::fill(tempText, tempText+text.length(), 0x8d); tempText[text.length()] = 0; displayText = std::string(tempText); delete tempText; } else { displayText = text; } if(actionCallback) actionCallback->TextChangedCallback(this); } TextPosition(); } void Textbox::Draw(const Point& screenPos) { if(!drawn) { TextPosition(); drawn = true; } Graphics * g = Engine::Ref().g; if(IsFocused()) { if(border) g->drawrect(screenPos.X, screenPos.Y, Size.X, Size.Y, 255, 255, 255, 255); g->draw_line(screenPos.X+textPosition.X+cursorPosition, screenPos.Y+3, screenPos.X+textPosition.X+cursorPosition, screenPos.Y+12, 255, 255, 255, XRES+BARSIZE); } else { if(border) g->drawrect(screenPos.X, screenPos.Y, Size.X, Size.Y, 160, 160, 160, 255); } g->drawtext(screenPos.X+textPosition.X, screenPos.Y+textPosition.Y, displayText, 255, 255, 255, 255); if(Appearance.icon) g->draw_icon(screenPos.X+iconPosition.X, screenPos.Y+iconPosition.Y, Appearance.icon); }*/