textbox autoresize
This commit is contained in:
parent
ea2b77b323
commit
8bf65eef1a
@ -1,5 +1,15 @@
|
||||
<container size='400' size-func="unpack(gui.get_viewport())">
|
||||
<textbox id='log' margin='0' editable='false' multiline='true' size-func="gui.get_viewport()[1],gui.get_viewport()[2]-40">
|
||||
</textbox>
|
||||
<container color='#00000080' size='400' size-func="unpack(gui.get_viewport())">
|
||||
<container size-func="gui.get_viewport()[1],gui.get_viewport()[2]-40">
|
||||
<textbox
|
||||
id='log'
|
||||
color='0'
|
||||
autoresize='true'
|
||||
margin='0,0,0,40'
|
||||
editable='false'
|
||||
multiline='true'
|
||||
size-func="gui.get_viewport()[1],40"
|
||||
gravity="bottom-left"
|
||||
></textbox>
|
||||
</container>
|
||||
<textbox id='prompt' consumer='submit' margin='0' gravity='bottom-left' size-func="gui.get_viewport()[1],40"></textbox>
|
||||
</container>
|
||||
|
||||
@ -10,11 +10,15 @@ function submit(text)
|
||||
|
||||
local status, result = pcall(function() return console.execute(text) end)
|
||||
if result ~= nil then
|
||||
document.log.text = document.log.text..tostring(result)..'\n'
|
||||
local prevtext = document.log.text
|
||||
if #prevtext == 0 then
|
||||
document.log:paste(tostring(result))
|
||||
else
|
||||
document.log:paste('\n'..tostring(result))
|
||||
end
|
||||
end
|
||||
document.prompt.text = ""
|
||||
document.prompt.focused = true
|
||||
print(document.log.pos)
|
||||
end
|
||||
|
||||
function on_open()
|
||||
|
||||
@ -21,6 +21,7 @@ TextBox::TextBox(std::wstring placeholder, glm::vec4 padding)
|
||||
setHoverColor(glm::vec4(0.05f, 0.1f, 0.2f, 0.75f));
|
||||
|
||||
textInitX = label->getPos().x;
|
||||
scrollable = true;
|
||||
}
|
||||
|
||||
void TextBox::draw(const DrawContext* pctx, Assets* assets) {
|
||||
@ -28,9 +29,25 @@ void TextBox::draw(const DrawContext* pctx, Assets* assets) {
|
||||
|
||||
font = assets->getFont(label->getFontName());
|
||||
|
||||
if (!isFocused())
|
||||
if (autoresize && font) {
|
||||
auto size = getSize();
|
||||
int newy = glm::min(static_cast<int>(parent->getSize().y),
|
||||
static_cast<int>(
|
||||
label->getLinesNumber() *
|
||||
label->getLineInterval() *
|
||||
font->getLineHeight())
|
||||
);
|
||||
if (newy != static_cast<int>(size.y)) {
|
||||
size.y = newy;
|
||||
setSize(size);
|
||||
if (positionfunc) {
|
||||
pos = positionfunc();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!isFocused()) {
|
||||
return;
|
||||
|
||||
}
|
||||
glm::vec2 pos = calcPos();
|
||||
glm::vec2 size = getSize();
|
||||
|
||||
@ -186,8 +203,9 @@ void TextBox::extendSelection(int index) {
|
||||
size_t TextBox::getLineLength(uint line) const {
|
||||
size_t position = label->getTextLineOffset(line);
|
||||
size_t lineLength = label->getTextLineOffset(line+1)-position;
|
||||
if (lineLength == 0)
|
||||
if (lineLength == 0) {
|
||||
lineLength = input.length() - position + 1;
|
||||
}
|
||||
return lineLength;
|
||||
}
|
||||
|
||||
@ -255,6 +273,14 @@ void TextBox::setOnEditStart(runnable oneditstart) {
|
||||
onEditStart = oneditstart;
|
||||
}
|
||||
|
||||
void TextBox::setAutoResize(bool flag) {
|
||||
this->autoresize = flag;
|
||||
}
|
||||
|
||||
bool TextBox::isAutoResize() const {
|
||||
return autoresize;
|
||||
}
|
||||
|
||||
void TextBox::onFocus(GUI* gui) {
|
||||
Panel::onFocus(gui);
|
||||
if (onEditStart){
|
||||
@ -312,6 +338,87 @@ void TextBox::resetMaxLocalCaret() {
|
||||
maxLocalCaret = caret - label->getTextLineOffset(label->getLineByTextIndex(caret));
|
||||
}
|
||||
|
||||
void TextBox::stepLeft(bool shiftPressed, bool breakSelection, uint previousCaret) {
|
||||
uint caret = breakSelection ? selectionStart : this->caret;
|
||||
if (caret > 0) {
|
||||
if (caret > input.length()) {
|
||||
setCaret(input.length()-1);
|
||||
} else {
|
||||
setCaret(caret-1);
|
||||
}
|
||||
if (shiftPressed) {
|
||||
if (selectionStart == selectionEnd) {
|
||||
selectionOrigin = previousCaret;
|
||||
}
|
||||
extendSelection(this->caret);
|
||||
} else {
|
||||
resetSelection();
|
||||
}
|
||||
} else {
|
||||
setCaret(caret);
|
||||
resetSelection();
|
||||
}
|
||||
resetMaxLocalCaret();
|
||||
}
|
||||
|
||||
void TextBox::stepRight(bool shiftPressed, bool breakSelection, uint previousCaret) {
|
||||
uint caret = breakSelection ? selectionEnd : this->caret;
|
||||
if (caret < input.length()) {
|
||||
setCaret(caret+1);
|
||||
caretLastMove = Window::time();
|
||||
if (shiftPressed) {
|
||||
if (selectionStart == selectionEnd) {
|
||||
selectionOrigin = previousCaret;
|
||||
}
|
||||
extendSelection(this->caret);
|
||||
} else {
|
||||
resetSelection();
|
||||
}
|
||||
} else {
|
||||
setCaret(caret);
|
||||
resetSelection();
|
||||
}
|
||||
resetMaxLocalCaret();
|
||||
}
|
||||
|
||||
void TextBox::stepDown(bool shiftPressed, bool breakSelection, uint previousCaret) {
|
||||
uint caret = breakSelection ? selectionEnd : this->caret;
|
||||
uint caretLine = label->getLineByTextIndex(caret);
|
||||
if (caretLine < label->getLinesNumber()-1) {
|
||||
uint offset = std::min(size_t(maxLocalCaret), getLineLength(caretLine+1)-1);
|
||||
setCaret(label->getTextLineOffset(caretLine+1) + offset);
|
||||
} else {
|
||||
setCaret(input.length());
|
||||
}
|
||||
if (shiftPressed) {
|
||||
if (selectionStart == selectionEnd) {
|
||||
selectionOrigin = previousCaret;
|
||||
}
|
||||
extendSelection(this->caret);
|
||||
} else {
|
||||
resetSelection();
|
||||
}
|
||||
}
|
||||
|
||||
void TextBox::stepUp(bool shiftPressed, bool breakSelection, uint previousCaret) {
|
||||
uint caret = breakSelection ? selectionStart : this->caret;
|
||||
uint caretLine = label->getLineByTextIndex(caret);
|
||||
if (caretLine > 0) {
|
||||
uint offset = std::min(size_t(maxLocalCaret), getLineLength(caretLine-1)-1);
|
||||
setCaret(label->getTextLineOffset(caretLine-1) + offset);
|
||||
} else {
|
||||
setCaret(0);
|
||||
}
|
||||
if (shiftPressed) {
|
||||
if (selectionStart == selectionEnd) {
|
||||
selectionOrigin = previousCaret;
|
||||
}
|
||||
extendSelection(this->caret);
|
||||
} else {
|
||||
resetSelection();
|
||||
}
|
||||
}
|
||||
|
||||
void TextBox::performEditingKeyboardEvents(keycode key) {
|
||||
bool shiftPressed = Events::pressed(keycode::LEFT_SHIFT);
|
||||
bool breakSelection = getSelectionLength() != 0 && !shiftPressed;
|
||||
@ -342,78 +449,13 @@ void TextBox::performEditingKeyboardEvents(keycode key) {
|
||||
} else if (key == keycode::TAB) {
|
||||
paste(L" ");
|
||||
} else if (key == keycode::LEFT) {
|
||||
uint caret = breakSelection ? selectionStart : this->caret;
|
||||
if (caret > 0) {
|
||||
if (caret > input.length()) {
|
||||
setCaret(input.length()-1);
|
||||
} else {
|
||||
setCaret(caret-1);
|
||||
}
|
||||
if (shiftPressed) {
|
||||
if (selectionStart == selectionEnd) {
|
||||
selectionOrigin = previousCaret;
|
||||
}
|
||||
extendSelection(this->caret);
|
||||
} else {
|
||||
resetSelection();
|
||||
}
|
||||
} else {
|
||||
setCaret(caret);
|
||||
resetSelection();
|
||||
}
|
||||
resetMaxLocalCaret();
|
||||
stepLeft(shiftPressed, breakSelection, previousCaret);
|
||||
} else if (key == keycode::RIGHT) {
|
||||
uint caret = breakSelection ? selectionEnd : this->caret;
|
||||
if (caret < input.length()) {
|
||||
setCaret(caret+1);
|
||||
caretLastMove = Window::time();
|
||||
if (shiftPressed) {
|
||||
if (selectionStart == selectionEnd) {
|
||||
selectionOrigin = previousCaret;
|
||||
}
|
||||
extendSelection(this->caret);
|
||||
} else {
|
||||
resetSelection();
|
||||
}
|
||||
} else {
|
||||
setCaret(caret);
|
||||
resetSelection();
|
||||
}
|
||||
resetMaxLocalCaret();
|
||||
stepRight(shiftPressed, breakSelection, previousCaret);
|
||||
} else if (key == keycode::UP) {
|
||||
uint caret = breakSelection ? selectionStart : this->caret;
|
||||
uint caretLine = label->getLineByTextIndex(caret);
|
||||
if (caretLine > 0) {
|
||||
uint offset = std::min(size_t(maxLocalCaret), getLineLength(caretLine-1)-1);
|
||||
setCaret(label->getTextLineOffset(caretLine-1) + offset);
|
||||
} else {
|
||||
setCaret(0);
|
||||
}
|
||||
if (shiftPressed) {
|
||||
if (selectionStart == selectionEnd) {
|
||||
selectionOrigin = previousCaret;
|
||||
}
|
||||
extendSelection(this->caret);
|
||||
} else {
|
||||
resetSelection();
|
||||
}
|
||||
stepUp(shiftPressed, breakSelection, previousCaret);
|
||||
} else if (key == keycode::DOWN) {
|
||||
uint caret = breakSelection ? selectionEnd : this->caret;
|
||||
uint caretLine = label->getLineByTextIndex(caret);
|
||||
if (caretLine < label->getLinesNumber()-1) {
|
||||
uint offset = std::min(size_t(maxLocalCaret), getLineLength(caretLine+1)-1);
|
||||
setCaret(label->getTextLineOffset(caretLine+1) + offset);
|
||||
} else {
|
||||
setCaret(input.length());
|
||||
}
|
||||
if (shiftPressed) {
|
||||
if (selectionStart == selectionEnd) {
|
||||
selectionOrigin = previousCaret;
|
||||
}
|
||||
extendSelection(this->caret);
|
||||
} else {
|
||||
resetSelection();
|
||||
}
|
||||
stepDown(shiftPressed, breakSelection, previousCaret);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -37,11 +37,16 @@ namespace gui {
|
||||
|
||||
bool multiline = false;
|
||||
bool editable = true;
|
||||
bool autoresize = false;
|
||||
|
||||
void stepLeft(bool shiftPressed, bool breakSelection, uint previousCaret);
|
||||
void stepRight(bool shiftPressed, bool breakSelection, uint previousCaret);
|
||||
void stepDown(bool shiftPressed, bool breakSelection, uint previousCaret);
|
||||
void stepUp(bool shiftPressed, bool breakSelection, uint previousCaret);
|
||||
|
||||
size_t normalizeIndex(int index);
|
||||
|
||||
int calcIndexAt(int x, int y) const;
|
||||
void paste(const std::wstring& text);
|
||||
void setTextOffset(uint x);
|
||||
void erase(size_t start, size_t length);
|
||||
bool eraseSelected();
|
||||
@ -61,7 +66,9 @@ namespace gui {
|
||||
std::wstring placeholder,
|
||||
glm::vec4 padding=glm::vec4(4.0f)
|
||||
);
|
||||
|
||||
|
||||
void paste(const std::wstring& text);
|
||||
|
||||
virtual void setTextSupplier(wstringsupplier supplier);
|
||||
|
||||
/// @brief Consumer called on stop editing text (textbox defocus)
|
||||
@ -139,6 +146,9 @@ namespace gui {
|
||||
/// @brief Set runnable called on textbox focus
|
||||
virtual void setOnEditStart(runnable oneditstart);
|
||||
|
||||
virtual void setAutoResize(bool flag);
|
||||
virtual bool isAutoResize() const;
|
||||
|
||||
virtual void onFocus(GUI*) override;
|
||||
virtual void refresh() override;
|
||||
virtual void click(GUI*, int, int) override;
|
||||
|
||||
@ -313,11 +313,12 @@ static std::shared_ptr<UINode> readTextBox(UiXmlReader& reader, xml::xmlelement
|
||||
if (element->has("text-wrap")) {
|
||||
textbox->setTextWrapping(element->attr("text-wrap").asBool());
|
||||
}
|
||||
|
||||
if (element->has("editable")) {
|
||||
textbox->setEditable(element->attr("editable").asBool());
|
||||
}
|
||||
|
||||
if (element->has("autoresize")) {
|
||||
textbox->setAutoResize(element->attr("autoresize").asBool());
|
||||
}
|
||||
if (element->has("consumer")) {
|
||||
textbox->setTextConsumer(scripting::create_wstring_consumer(
|
||||
reader.getEnvironment(),
|
||||
|
||||
@ -70,6 +70,14 @@ static int l_menu_reset(lua_State* L) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_textbox_paste(lua_State* L) {
|
||||
auto node = getDocumentNode(L);
|
||||
auto box = dynamic_cast<TextBox*>(node.node.get());
|
||||
auto text = lua_tostring(L, 2);
|
||||
box->paste(util::str2wstr_utf8(text));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_container_add(lua_State* L) {
|
||||
auto docnode = getDocumentNode(L);
|
||||
auto node = dynamic_cast<Container*>(docnode.node.get());
|
||||
@ -121,6 +129,13 @@ static int p_get_back(UINode* node) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int p_get_paste(UINode* node) {
|
||||
if (dynamic_cast<TextBox*>(node)) {
|
||||
return state->pushcfunction(l_textbox_paste);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int p_get_page(UINode* node) {
|
||||
if (auto menu = dynamic_cast<Menu*>(node)) {
|
||||
return state->pushstring(menu->getCurrent().name);
|
||||
@ -289,6 +304,7 @@ static int l_gui_getattr(lua_State* L) {
|
||||
{"page", p_get_page},
|
||||
{"back", p_get_back},
|
||||
{"reset", p_get_reset},
|
||||
{"paste", p_get_paste},
|
||||
{"inventory", p_get_inventory},
|
||||
{"focused", p_get_focused},
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user