nativeui: Add basic TextEdit control, and popupchoice

This commit is contained in:
Henrik Rydgard 2014-07-18 11:03:18 +02:00
parent 49e8414fec
commit 76cb31cdd5
4 changed files with 185 additions and 2 deletions

View File

@ -388,4 +388,52 @@ void SliderFloatPopupScreen::OnCompleted(DialogResult result) {
}
}
PopupTextInputChoice::PopupTextInputChoice(std::string *value, const std::string &title, const std::string &placeholder, ScreenManager *screenManager, LayoutParams *layoutParams)
: Choice(title, "", false, layoutParams), value_(value), placeHolder_(placeholder), screenManager_(screenManager) {
OnClick.Handle(this, &PopupTextInputChoice::HandleClick);
}
EventReturn PopupTextInputChoice::HandleClick(EventParams &e) {
TextEditPopupScreen *popupScreen = new TextEditPopupScreen(value_, placeHolder_, text_);
popupScreen->OnChange.Handle(this, &PopupTextInputChoice::HandleChange);
screenManager_->push(popupScreen);
return EVENT_DONE;
}
void PopupTextInputChoice::Draw(UIContext &dc) {
Style style = dc.theme->itemStyle;
if (!IsEnabled()) {
style = dc.theme->itemDisabledStyle;
}
Choice::Draw(dc);
dc.SetFontStyle(dc.theme->uiFont);
dc.DrawText(value_->c_str(), bounds_.x2() - 12, bounds_.centerY(), style.fgColor, ALIGN_RIGHT | ALIGN_VCENTER);
}
EventReturn PopupTextInputChoice::HandleChange(EventParams &e) {
e.v = this;
OnChange.Trigger(e);
return EVENT_DONE;
}
void TextEditPopupScreen::CreatePopupContents(UI::ViewGroup *parent) {
using namespace UI;
textEditValue_ = *value_;
LinearLayout *lin = parent->Add(new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams((UI::Size)300, WRAP_CONTENT)));
edit_ = new TextEdit(textEditValue_, placeholder_, new LinearLayoutParams(1.0f));
lin->Add(edit_);
UI::SetFocusedView(edit_);
}
void TextEditPopupScreen::OnCompleted(DialogResult result) {
if (result == DR_OK) {
*value_ = edit_->GetText();
EventParams e;
e.v = edit_;
OnChange.Trigger(e);
}
}
} // namespace UI

View File

@ -160,6 +160,23 @@ private:
float maxValue_;
};
class TextEditPopupScreen : public PopupScreen {
public:
TextEditPopupScreen(std::string *value, std::string &placeholder, const std::string &title)
: PopupScreen(title, "OK", "Cancel"), value_(value), placeholder_(placeholder) {}
void CreatePopupContents(ViewGroup *parent);
Event OnChange;
private:
virtual void OnCompleted(DialogResult result) override;
TextEdit *edit_;
std::string *value_;
std::string textEditValue_;
std::string placeholder_;
int step_;
};
// Reads and writes value to determine the current selection.
class PopupMultiChoice : public UI::Choice {
public:
@ -230,4 +247,21 @@ private:
ScreenManager *screenManager_;
};
class PopupTextInputChoice: public Choice {
public:
PopupTextInputChoice(std::string *value, const std::string &title, const std::string &placeholder, ScreenManager *screenManager, LayoutParams *layoutParams = 0);
void Draw(UIContext &dc);
Event OnChange;
private:
EventReturn HandleClick(EventParams &e);
EventReturn HandleChange(EventParams &e);
ScreenManager *screenManager_;
std::string *value_;
std::string placeHolder_;
std::string defaultText_;
};
} // namespace UI

View File

@ -7,6 +7,7 @@
#include "gfx_es2/draw_buffer.h"
#include "gfx/texture.h"
#include "gfx/texture_atlas.h"
#include "util/text/utf8.h"
#include "ui/ui.h"
#include "ui/view.h"
#include "ui/ui_context.h"
@ -572,6 +573,89 @@ void TextView::Draw(UIContext &dc) {
dc.DrawTextRect(text_.c_str(), bounds_, 0xFFFFFFFF, textAlign_);
}
TextEdit::TextEdit(const std::string &text, const std::string &placeholderText, LayoutParams *layoutParams)
: View(layoutParams), text_(text), placeholderText_(placeholderText) {
caret_ = (int)text_.size();
}
void TextEdit::Draw(UIContext &dc) {
dc.SetFontStyle(dc.theme->uiFont);
dc.FillRect(UI::Drawable(0x80000000), bounds_);
if (text_.empty()) {
if (placeholderText_.size()) {
dc.DrawTextRect(placeholderText_.c_str(), bounds_, 0x50FFFFFF, ALIGN_CENTER);
}
} else {
dc.DrawTextRect(text_.c_str(), bounds_, 0xFFFFFFFF, ALIGN_VCENTER | ALIGN_LEFT);
}
// Hack to find the caret position. Might want to find a better way...
std::string subset = text_.substr(0, caret_);
float w, h;
dc.MeasureText(dc.theme->uiFont, subset.c_str(), &w, &h, ALIGN_VCENTER | ALIGN_LEFT);
float caretX = bounds_.x + w;
dc.FillRect(UI::Drawable(0xFFFFFFFF), Bounds(caretX - 1, bounds_.y + 2, 3, bounds_.h - 4));
}
void TextEdit::GetContentDimensions(const UIContext &dc, float &w, float &h) const {
dc.MeasureText(dc.theme->uiFont, text_.size() ? text_.c_str() : "Wj", &w, &h);
w += 2;
h += 2;
}
void TextEdit::Key(const KeyInput &input) {
// Process navigation keys. These aren't chars.
if (input.flags & KEY_DOWN) {
switch (input.keyCode) {
case NKCODE_DPAD_LEFT: // ASCII left arrow
caret_--;
break;
case NKCODE_DPAD_RIGHT: // ASCII right arrow
caret_++;
break;
case NKCODE_MOVE_HOME:
case NKCODE_PAGE_UP:
caret_ = 0;
break;
case NKCODE_MOVE_END:
case NKCODE_PAGE_DOWN:
caret_ = (int)text_.size();
break;
case NKCODE_FORWARD_DEL:
if (caret_ < text_.size()) {
text_.erase(text_.begin() + caret_, text_.begin() + caret_ + 1);
}
case NKCODE_DEL:
if (caret_ > 0) {
text_.erase(text_.begin() + caret_ - 1, text_.begin() + caret_);
caret_--;
}
break;
}
if (caret_ < 0) {
caret_ = 0;
}
if (caret_ > (int)text_.size()) {
caret_ = (int)text_.size();
}
}
// Process chars.
if (input.flags & KEY_CHAR) {
int unichar = input.keyCode;
if (unichar >= 0x20) { // Ignore control characters.
// Insert it! (todo: do it with a string insert)
char buf[8];
buf[u8_wc_toutf8(buf, unichar)] = '\0';
for (int i = 0; i < strlen(buf); i++) {
text_.insert(text_.begin() + caret_, buf[i]);
caret_++;
}
}
}
}
void ProgressBar::GetContentDimensions(const UIContext &dc, float &w, float &h) const {
dc.MeasureText(dc.theme->uiFont, " 100% ", &w, &h);
}

View File

@ -654,8 +654,8 @@ public:
TextView(const std::string &text, int textAlign, bool small, LayoutParams *layoutParams = 0)
: InertView(layoutParams), text_(text), textAlign_(textAlign), small_(small) {}
virtual void GetContentDimensions(const UIContext &dc, float &w, float &h) const;
virtual void Draw(UIContext &dc);
virtual void GetContentDimensions(const UIContext &dc, float &w, float &h) const override;
virtual void Draw(UIContext &dc) override;
void SetText(const std::string &text) { text_ = text; }
void SetSmall(bool small) { small_ = small; }
private:
@ -664,6 +664,23 @@ private:
bool small_;
};
class TextEdit : public View {
public:
TextEdit(const std::string &text, const std::string &placeholderText, LayoutParams *layoutParams = 0);
void SetText(const std::string &text) { text_ = text; caret_ = (int)text_.size(); }
const std::string &GetText() const { return text_; }
virtual void GetContentDimensions(const UIContext &dc, float &w, float &h) const override;
virtual void Draw(UIContext &dc) override;
virtual void Key(const KeyInput &input) override;
private:
std::string text_;
std::string placeholderText_;
int caret_;
// TODO: Selections
};
enum ImageSizeMode {
IS_DEFAULT,
};