Textbox now inherits from Label - gets all the fancy text selection features
This commit is contained in:
parent
7c259c0123
commit
5a71068ba0
@ -125,20 +125,58 @@ void Label::Tick(float dt)
|
||||
{
|
||||
if(!this->IsFocused() && (selecting || (selectionIndex0 != -1 && selectionIndex1 != -1)))
|
||||
{
|
||||
ClearSelection();
|
||||
}
|
||||
}
|
||||
|
||||
int Label::getLowerSelectionBound()
|
||||
{
|
||||
return (selectionIndex0 > selectionIndex1) ? selectionIndex1 : selectionIndex0;
|
||||
}
|
||||
|
||||
int Label::getHigherSelectionBound()
|
||||
{
|
||||
return (selectionIndex0 > selectionIndex1) ? selectionIndex0 : selectionIndex1;
|
||||
}
|
||||
|
||||
bool Label::HasSelection()
|
||||
{
|
||||
if(selectionIndex0 != -1 && selectionIndex1 != -1 && selectionIndex0 != selectionIndex1)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void Label::ClearSelection()
|
||||
{
|
||||
selecting = false;
|
||||
selectionIndex0 = -1;
|
||||
selectionIndex1 = -1;
|
||||
updateSelection();
|
||||
}
|
||||
}
|
||||
|
||||
void Label::updateSelection()
|
||||
{
|
||||
std::string currentText;
|
||||
|
||||
if(selectionIndex0 < 0) selectionIndex0 = 0;
|
||||
if(selectionIndex0 > text.length()) selectionIndex0 = text.length();
|
||||
if(selectionIndex1 < 0) selectionIndex1 = 0;
|
||||
if(selectionIndex1 > text.length()) selectionIndex1 = text.length();
|
||||
|
||||
if(selectionIndex0 == -1 || selectionIndex1 == -1)
|
||||
{
|
||||
selectionXH = -1;
|
||||
selectionXL = -1;
|
||||
|
||||
textFragments = std::string(currentText);
|
||||
return;
|
||||
}
|
||||
|
||||
if(multiline)
|
||||
currentText = textLines;
|
||||
else
|
||||
currentText = text;
|
||||
|
||||
if(selectionIndex1 > selectionIndex0) {
|
||||
selectionLineH = Graphics::PositionAtCharIndex((char*)currentText.c_str(), selectionIndex1, selectionXH, selectionYH);
|
||||
selectionLineL = Graphics::PositionAtCharIndex((char*)currentText.c_str(), selectionIndex0, selectionXL, selectionYL);
|
||||
|
@ -34,6 +34,9 @@ namespace ui
|
||||
|
||||
void updateMultiline();
|
||||
void updateSelection();
|
||||
|
||||
int getLowerSelectionBound();
|
||||
int getHigherSelectionBound();
|
||||
public:
|
||||
//Label(Window* parent_state, std::string labelText);
|
||||
Label(Point position, Point size, std::string labelText);
|
||||
@ -41,11 +44,14 @@ namespace ui
|
||||
virtual ~Label();
|
||||
|
||||
virtual void SetMultiline(bool status);
|
||||
|
||||
virtual void SetText(std::string text);
|
||||
virtual std::string GetText();
|
||||
|
||||
void SetTextColour(Colour textColour) { this->textColour = textColour; }
|
||||
virtual bool HasSelection();
|
||||
virtual void ClearSelection();
|
||||
|
||||
void SetTextColour(Colour textColour) { this->textColour = textColour; }
|
||||
|
||||
virtual void OnMouseClick(int x, int y, unsigned button);
|
||||
virtual void OnMouseUp(int x, int y, unsigned button);
|
||||
|
@ -8,6 +8,234 @@
|
||||
|
||||
using namespace ui;
|
||||
|
||||
Textbox::Textbox(Point position, Point size, std::string textboxText):
|
||||
Label(position, size, ""),
|
||||
actionCallback(NULL),
|
||||
masked(false),
|
||||
border(true),
|
||||
mouseDown(false)
|
||||
{
|
||||
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(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),
|
||||
@ -165,4 +393,4 @@ void Textbox::Draw(const Point& screenPos)
|
||||
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);
|
||||
}
|
||||
}*/
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "Component.h"
|
||||
#include "Label.h"
|
||||
#include "Misc.h"
|
||||
|
||||
namespace ui
|
||||
@ -15,7 +15,37 @@ public:
|
||||
virtual void TextChangedCallback(ui::Textbox * sender) {}
|
||||
virtual ~TextboxAction() {}
|
||||
};
|
||||
class Textbox : public Component
|
||||
|
||||
class Textbox : public Label
|
||||
{
|
||||
friend class TextboxAction;
|
||||
protected:
|
||||
bool mouseDown;
|
||||
bool masked, border;
|
||||
int cursor, cursorPosition;
|
||||
TextboxAction *actionCallback;
|
||||
std::string backingText;
|
||||
public:
|
||||
Textbox(Point position, Point size, std::string textboxText);
|
||||
virtual ~Textbox();
|
||||
|
||||
virtual void SetDisplayText(std::string text);
|
||||
virtual void SetText(std::string text);
|
||||
virtual std::string GetText();
|
||||
|
||||
void SetBorder(bool border) { this->border = border; };
|
||||
void SetHidden(bool hidden) { masked = hidden; }
|
||||
bool GetHidden() { return masked; }
|
||||
void SetActionCallback(TextboxAction * action) { actionCallback = action; }
|
||||
|
||||
virtual void OnMouseClick(int x, int y, unsigned button);
|
||||
virtual void OnMouseUp(int x, int y, unsigned button);
|
||||
virtual void OnMouseMoved(int localx, int localy, int dx, int dy);
|
||||
virtual void OnKeyPress(int key, Uint16 character, bool shift, bool ctrl, bool alt);
|
||||
virtual void Draw(const Point& screenPos);
|
||||
};
|
||||
|
||||
/*class Textbox : public Component
|
||||
{
|
||||
friend class TextboxAction;
|
||||
protected:
|
||||
@ -44,6 +74,8 @@ public:
|
||||
|
||||
virtual void Draw(const Point& screenPos);
|
||||
};
|
||||
}*/
|
||||
}
|
||||
|
||||
|
||||
#endif // TEXTBOX_H
|
||||
|
Loading…
Reference in New Issue
Block a user