Fixed bug in TextInput where the display could get out of whack if the

string entered by the user is larger than the content width. Also added
StyleBox and StyleLine drawing modes.
This commit is contained in:
casey langen 2017-05-29 14:06:08 -07:00
parent 133f69e93b
commit a282d71766
2 changed files with 75 additions and 38 deletions

View File

@ -33,6 +33,7 @@
//////////////////////////////////////////////////////////////////////////////
#include <stdafx.h>
#include <limits.h>
#include "Screen.h"
#include "Colors.h"
@ -63,12 +64,20 @@ inline static bool removeUtf8Char(std::string& value, size_t position) {
return false;
}
TextInput::TextInput(IInput::InputMode inputMode)
TextInput::TextInput(TextInput::Style style, IInput::InputMode inputMode)
: Window()
, bufferLength(0)
, position(0)
, style(style)
, inputMode(inputMode)
, enterEnabled(true) {
if (style == StyleLine) {
this->SetFrameVisible(false);
}
}
TextInput::TextInput(IInput::InputMode inputMode)
: TextInput(TextInput::StyleBox, inputMode) {
}
TextInput::~TextInput() {
@ -78,18 +87,41 @@ void TextInput::OnRedraw() {
WINDOW* c = this->GetContent();
werase(c);
if (buffer.size()) {
if (inputMode == InputPassword) {
size_t count = u8cols(buffer);
std::string masked(count, '*');
waddstr(c, masked.c_str());
}
else {
waddstr(c, buffer.c_str());
}
std::string trimmed;
int contentWidth = GetContentWidth();
int columns = u8cols(buffer);
/* if the string is larger than our width, we gotta trim it for
display purposes... */
if (position > contentWidth) {
trimmed = u8substr(this->buffer, position - contentWidth, INT_MAX);
}
else if (!this->IsFocused() && hintText.size()) {
waddstr(c, hintText.c_str());
else {
trimmed = buffer;
}
if (!this->IsFocused() && !columns && hintText.size()) {
/* draw the hint if we have one and there's no string yet */
waddstr(c, u8substr(hintText, 0, columns).c_str());
}
else {
/* mask the string if we're in password mode */
if (inputMode == InputPassword) {
trimmed = std::string(columns, '*');
}
/* if we're in "Line" mode and the string is short, pad the
end with a bunch of underscores */
if (style == StyleLine) {
int remaining = contentWidth - columns;
if (remaining > 0) {
trimmed += std::string(remaining, '_');
}
}
/* finally, draw the offset/trimmed, potentially masked, padded
string to the output */
waddstr(c, trimmed.c_str());
}
}
@ -180,7 +212,6 @@ bool TextInput::KeyPress(const std::string& key) {
removeUtf8Char(this->buffer, this->position + 1);
this->bufferLength = u8len(buffer);
this->Redraw();
return true;
}
}

View File

@ -48,40 +48,46 @@ namespace cursespp {
public std::enable_shared_from_this<TextInput>,
#endif
public cursespp::IInput {
public:
sigslot::signal1<TextInput*> EnterPressed;
sigslot::signal2<TextInput*, std::string> TextChanged;
public:
sigslot::signal1<TextInput*> EnterPressed;
sigslot::signal2<TextInput*, std::string> TextChanged;
TextInput(InputMode inputMode = IInput::InputNormal);
virtual ~TextInput();
enum Style { StyleBox, StyleLine };
virtual void OnRedraw();
TextInput(InputMode inputMode = IInput::InputNormal);
TextInput(Style style, InputMode inputMode = IInput::InputNormal);
virtual bool Write(const std::string& key);
virtual size_t Length();
virtual size_t Position();
virtual ~TextInput();
virtual void SetInputMode(InputMode inputMode) {
this->inputMode = inputMode;
};
virtual void OnRedraw();
virtual InputMode GetInputMode() { return this->inputMode; }
virtual bool Write(const std::string& key);
virtual size_t Length();
virtual size_t Position();
virtual bool KeyPress(const std::string& key);
virtual void SetInputMode(InputMode inputMode) {
this->inputMode = inputMode;
};
virtual void SetText(const std::string& value);
virtual std::string GetText() { return this->buffer; }
virtual InputMode GetInputMode() { return this->inputMode; }
void SetHint(const std::string& hint);
void SetEnterEnabled(bool enabled);
virtual bool KeyPress(const std::string& key);
private:
bool OffsetPosition(int delta);
virtual void SetText(const std::string& value);
virtual std::string GetText() { return this->buffer; }
std::string buffer, hintText;
int position;
bool enterEnabled;
size_t bufferLength;
InputMode inputMode;
void SetHint(const std::string& hint);
void SetEnterEnabled(bool enabled);
Style GetStyle() { return style; }
private:
bool OffsetPosition(int delta);
std::string buffer, hintText;
int position;
bool enterEnabled;
size_t bufferLength;
Style style;
InputMode inputMode;
};
}