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)))
|
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;
|
selecting = false;
|
||||||
selectionIndex0 = -1;
|
selectionIndex0 = -1;
|
||||||
selectionIndex1 = -1;
|
selectionIndex1 = -1;
|
||||||
updateSelection();
|
updateSelection();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Label::updateSelection()
|
void Label::updateSelection()
|
||||||
{
|
{
|
||||||
std::string currentText;
|
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)
|
if(multiline)
|
||||||
currentText = textLines;
|
currentText = textLines;
|
||||||
else
|
else
|
||||||
currentText = text;
|
currentText = text;
|
||||||
|
|
||||||
if(selectionIndex1 > selectionIndex0) {
|
if(selectionIndex1 > selectionIndex0) {
|
||||||
selectionLineH = Graphics::PositionAtCharIndex((char*)currentText.c_str(), selectionIndex1, selectionXH, selectionYH);
|
selectionLineH = Graphics::PositionAtCharIndex((char*)currentText.c_str(), selectionIndex1, selectionXH, selectionYH);
|
||||||
selectionLineL = Graphics::PositionAtCharIndex((char*)currentText.c_str(), selectionIndex0, selectionXL, selectionYL);
|
selectionLineL = Graphics::PositionAtCharIndex((char*)currentText.c_str(), selectionIndex0, selectionXL, selectionYL);
|
||||||
|
@ -34,6 +34,9 @@ namespace ui
|
|||||||
|
|
||||||
void updateMultiline();
|
void updateMultiline();
|
||||||
void updateSelection();
|
void updateSelection();
|
||||||
|
|
||||||
|
int getLowerSelectionBound();
|
||||||
|
int getHigherSelectionBound();
|
||||||
public:
|
public:
|
||||||
//Label(Window* parent_state, std::string labelText);
|
//Label(Window* parent_state, std::string labelText);
|
||||||
Label(Point position, Point size, std::string labelText);
|
Label(Point position, Point size, std::string labelText);
|
||||||
@ -41,11 +44,14 @@ namespace ui
|
|||||||
virtual ~Label();
|
virtual ~Label();
|
||||||
|
|
||||||
virtual void SetMultiline(bool status);
|
virtual void SetMultiline(bool status);
|
||||||
|
|
||||||
virtual void SetText(std::string text);
|
virtual void SetText(std::string text);
|
||||||
virtual std::string GetText();
|
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 OnMouseClick(int x, int y, unsigned button);
|
||||||
virtual void OnMouseUp(int x, int y, unsigned button);
|
virtual void OnMouseUp(int x, int y, unsigned button);
|
||||||
|
@ -8,6 +8,234 @@
|
|||||||
|
|
||||||
using namespace ui;
|
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):
|
Textbox::Textbox(Point position, Point size, std::string textboxText):
|
||||||
Component(position, size),
|
Component(position, size),
|
||||||
text(textboxText),
|
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);
|
g->drawtext(screenPos.X+textPosition.X, screenPos.Y+textPosition.Y, displayText, 255, 255, 255, 255);
|
||||||
if(Appearance.icon)
|
if(Appearance.icon)
|
||||||
g->draw_icon(screenPos.X+iconPosition.X, screenPos.Y+iconPosition.Y, Appearance.icon);
|
g->draw_icon(screenPos.X+iconPosition.X, screenPos.Y+iconPosition.Y, Appearance.icon);
|
||||||
}
|
}*/
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "Component.h"
|
#include "Label.h"
|
||||||
#include "Misc.h"
|
#include "Misc.h"
|
||||||
|
|
||||||
namespace ui
|
namespace ui
|
||||||
@ -15,7 +15,37 @@ public:
|
|||||||
virtual void TextChangedCallback(ui::Textbox * sender) {}
|
virtual void TextChangedCallback(ui::Textbox * sender) {}
|
||||||
virtual ~TextboxAction() {}
|
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;
|
friend class TextboxAction;
|
||||||
protected:
|
protected:
|
||||||
@ -44,6 +74,8 @@ public:
|
|||||||
|
|
||||||
virtual void Draw(const Point& screenPos);
|
virtual void Draw(const Point& screenPos);
|
||||||
};
|
};
|
||||||
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif // TEXTBOX_H
|
#endif // TEXTBOX_H
|
||||||
|
Loading…
Reference in New Issue
Block a user