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