summaryrefslogtreecommitdiff
path: root/src/interface
diff options
context:
space:
mode:
authorSimon Robertshaw <simon@hardwired.org.uk>2012-06-26 21:55:52 (GMT)
committer Simon Robertshaw <simon@hardwired.org.uk>2012-06-26 21:55:52 (GMT)
commit5a71068ba07f42cffbd50324176510d992ebbc5e (patch)
tree10fbbf3e466d10175faaacced7cafba449edbb69 /src/interface
parent7c259c01238d91d41a778003e2529f5c06e09139 (diff)
downloadpowder-5a71068ba07f42cffbd50324176510d992ebbc5e.zip
powder-5a71068ba07f42cffbd50324176510d992ebbc5e.tar.gz
Textbox now inherits from Label - gets all the fancy text selection features
Diffstat (limited to 'src/interface')
-rw-r--r--src/interface/Label.cpp46
-rw-r--r--src/interface/Label.h8
-rw-r--r--src/interface/Textbox.cpp230
-rw-r--r--src/interface/Textbox.h36
4 files changed, 312 insertions, 8 deletions
diff --git a/src/interface/Label.cpp b/src/interface/Label.cpp
index a513878..35b2000 100644
--- a/src/interface/Label.cpp
+++ b/src/interface/Label.cpp
@@ -125,20 +125,58 @@ void Label::Tick(float dt)
{
if(!this->IsFocused() && (selecting || (selectionIndex0 != -1 && selectionIndex1 != -1)))
{
- selecting = false;
- selectionIndex0 = -1;
- selectionIndex1 = -1;
- updateSelection();
+ 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);
diff --git a/src/interface/Label.h b/src/interface/Label.h
index 34822bb..c8c63d4 100644
--- a/src/interface/Label.h
+++ b/src/interface/Label.h
@@ -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);
diff --git a/src/interface/Textbox.cpp b/src/interface/Textbox.cpp
index 4ea5bd0..12a4698 100644
--- a/src/interface/Textbox.cpp
+++ b/src/interface/Textbox.cpp
@@ -9,6 +9,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),
actionCallback(NULL),
@@ -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);
-}
+}*/
diff --git a/src/interface/Textbox.h b/src/interface/Textbox.h
index 551ff54..120194e 100644
--- a/src/interface/Textbox.h
+++ b/src/interface/Textbox.h
@@ -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