diff --git a/doc/en/scripting/ui.md b/doc/en/scripting/ui.md index 0a6ad4c3..4f132462 100644 --- a/doc/en/scripting/ui.md +++ b/doc/en/scripting/ui.md @@ -78,14 +78,18 @@ Properties: | caret | int | yes | yes | carriage position. `textbox.caret = -1` will set the position to the end of the text | | editable | bool | yes | yes | text mutability | | multiline | bool | yes | yes | multiline support | +| lineNumbers | bool | yes | yes | display line numbers | | textWrap | bool | yes | yes | automatic text wrapping (only with multiline: "true") | | valid | bool | yes | no | is the entered text correct | +| textColor | vec4 | yes | yes | text color | Methods: -| Method | Description | -| ----------- | ------------------------------------------------ | -| paste(text) | inserts the specified text at the caret position | +| Method | Description | +| ------------------------- | ---------------------------------------------------------------- | +| paste(text: str) | inserts the specified text at the caret position | +| lineAt(pos: int) -> int | determines the line number by position in the text | +| linePos(line: int) -> int | determines the position of the beginning of the line in the text | ## Slider (trackbar) diff --git a/doc/ru/scripting/ui.md b/doc/ru/scripting/ui.md index 0a955947..4d244210 100644 --- a/doc/ru/scripting/ui.md +++ b/doc/ru/scripting/ui.md @@ -78,14 +78,18 @@ document["worlds-panel"]:clear() | caret | int | да | да | позиция каретки. `textbox.caret = -1` установит позицию в конец текста | | editable | bool | да | да | изменяемость текста | | multiline | bool | да | да | поддержка многострочности | +| lineNumbers | bool | да | да | отображение номеров строк | | textWrap | bool | да | да | автоматический перенос текста (только при multiline: "true") | | valid | bool | да | нет | является ли введенный текст корректным | +| textColor | vec4 | да | да | цвет текста | Методы: -| Метод | Описание | -| ----------- | -------------------------------------------- | -| paste(text) | вставляет указанный текст на позицию каретки | +| Метод | Описание | +| ------------------------- | -------------------------------------------- | +| paste(text: str) | вставляет указанный текст на позицию каретки | +| lineAt(pos: int) -> int | определяет номер строки по позиции в тексте | +| linePos(line: int) -> int | определяет позицию начала строки в тексте | ## Ползунок (trackbar) diff --git a/src/graphics/ui/elements/TextBox.cpp b/src/graphics/ui/elements/TextBox.cpp index 6a123fca..90a4c256 100644 --- a/src/graphics/ui/elements/TextBox.cpp +++ b/src/graphics/ui/elements/TextBox.cpp @@ -623,6 +623,14 @@ void TextBox::select(int start, int end) { setCaret(selectionEnd); } +uint TextBox::getLineAt(size_t position) const { + return label->getLineByTextIndex(position); +} + +size_t TextBox::getLinePos(uint line) const { + return label->getTextLineOffset(line); +} + std::shared_ptr TextBox::getAt(glm::vec2 pos, std::shared_ptr self) { return UINode::getAt(pos, self); } @@ -740,7 +748,7 @@ void TextBox::setCaret(size_t position) { uint lineHeight = font->getLineHeight()*label->getLineInterval(); scrollStep = lineHeight; if (offset < 0) { - scrolled(1); + scrolled(-glm::floor(offset/static_cast(scrollStep)+0.5f)); } else if (offset >= getSize().y) { offset -= getSize().y; scrolled(-glm::ceil(offset/static_cast(scrollStep)+0.5f)); diff --git a/src/graphics/ui/elements/TextBox.hpp b/src/graphics/ui/elements/TextBox.hpp index 1415d89b..d2c4fd8c 100644 --- a/src/graphics/ui/elements/TextBox.hpp +++ b/src/graphics/ui/elements/TextBox.hpp @@ -159,6 +159,16 @@ namespace gui { /// @param end index of the last selected character + 1 virtual void select(int start, int end); + /// @brief Get number of line at specific position in text + /// @param position target position + /// @return line number + virtual uint getLineAt(size_t position) const; + + /// @brief Get specific line text position + /// @param line target line + /// @return line position in text + virtual size_t getLinePos(uint line) const; + /// @brief Check text with validator set with setTextValidator /// @return true if text is valid virtual bool validate(); diff --git a/src/logic/scripting/lua/libs/libgui.cpp b/src/logic/scripting/lua/libs/libgui.cpp index 078a3529..c83e7410 100644 --- a/src/logic/scripting/lua/libs/libgui.cpp +++ b/src/logic/scripting/lua/libs/libgui.cpp @@ -134,6 +134,24 @@ static int l_move_into(lua::State* L) { return 0; } +static int l_get_line_at(lua::State* L) { + auto node = getDocumentNode(L, 1); + auto position = lua::tointeger(L, 2); + if (auto box = dynamic_cast(node.node.get())) { + return lua::pushinteger(L, box->getLineAt(position)); + } + return 0; +} + +static int l_get_line_pos(lua::State* L) { + auto node = getDocumentNode(L, 1); + auto line = lua::tointeger(L, 2); + if (auto box = dynamic_cast(node.node.get())) { + return lua::pushinteger(L, box->getLinePos(line)); + } + return 0; +} + static int p_get_inventory(UINode* node, lua::State* L) { if (auto inventory = dynamic_cast(node)) { auto inv = inventory->getInventory(); @@ -356,6 +374,12 @@ static int p_move_into(UINode*, lua::State* L) { static int p_get_focused(UINode* node, lua::State* L) { return lua::pushboolean(L, node->isFocused()); } +static int p_get_line_at(UINode*, lua::State* L) { + return lua::pushcfunction(L, l_get_line_at); +} +static int p_get_line_pos(UINode*, lua::State* L) { + return lua::pushcfunction(L, l_get_line_pos); +} static int l_gui_getattr(lua::State* L) { auto docname = lua::require_string(L, 1); @@ -391,6 +415,8 @@ static int l_gui_getattr(lua::State* L) { {"text", p_get_text}, {"editable", p_get_editable}, {"lineNumbers", p_get_line_numbers}, + {"lineAt", p_get_line_at}, + {"linePos", p_get_line_pos}, {"src", p_get_src}, {"value", p_get_value}, {"min", p_get_min},