mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-02-10 16:23:05 +00:00
nativeui: Add basic TextEdit control, and popupchoice
This commit is contained in:
parent
49e8414fec
commit
76cb31cdd5
@ -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
|
||||
|
@ -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
|
||||
|
84
ui/view.cpp
84
ui/view.cpp
@ -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);
|
||||
}
|
||||
|
21
ui/view.h
21
ui/view.h
@ -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,
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user