textbox.caret property

This commit is contained in:
MihailRis 2024-05-17 12:18:39 +03:00
parent 5834233162
commit 3992ca8291
5 changed files with 45 additions and 13 deletions

View File

@ -13,6 +13,7 @@ function on_history_up()
return return
end end
document.prompt.text = history[history_pointer] document.prompt.text = history[history_pointer]
document.prompt.caret = -1
history_pointer = history_pointer - 1 history_pointer = history_pointer - 1
end end
@ -22,6 +23,7 @@ function on_history_down()
end end
history_pointer = history_pointer + 1 history_pointer = history_pointer + 1
document.prompt.text = history[history_pointer + 1] document.prompt.text = history[history_pointer + 1]
document.prompt.caret = -1
end end
function add_to_history(text) function add_to_history(text)

View File

@ -369,7 +369,7 @@ void TextBox::click(GUI*, int x, int y) {
} }
void TextBox::mouseMove(GUI*, int x, int y) { void TextBox::mouseMove(GUI*, int x, int y) {
int index = calcIndexAt(x, y); ssize_t index = calcIndexAt(x, y);
setCaret(index); setCaret(index);
extendSelection(index); extendSelection(index);
resetMaxLocalCaret(); resetMaxLocalCaret();
@ -381,7 +381,7 @@ void TextBox::resetMaxLocalCaret() {
void TextBox::stepLeft(bool shiftPressed, bool breakSelection) { void TextBox::stepLeft(bool shiftPressed, bool breakSelection) {
uint previousCaret = this->caret; uint previousCaret = this->caret;
uint caret = breakSelection ? selectionStart : this->caret; size_t caret = breakSelection ? selectionStart : this->caret;
if (caret > 0) { if (caret > 0) {
if (caret > input.length()) { if (caret > input.length()) {
setCaret(input.length()-1); setCaret(input.length()-1);
@ -405,7 +405,7 @@ void TextBox::stepLeft(bool shiftPressed, bool breakSelection) {
void TextBox::stepRight(bool shiftPressed, bool breakSelection) { void TextBox::stepRight(bool shiftPressed, bool breakSelection) {
uint previousCaret = this->caret; uint previousCaret = this->caret;
uint caret = breakSelection ? selectionEnd : this->caret; size_t caret = breakSelection ? selectionEnd : this->caret;
if (caret < input.length()) { if (caret < input.length()) {
setCaret(caret+1); setCaret(caret+1);
caretLastMove = Window::time(); caretLastMove = Window::time();
@ -452,7 +452,7 @@ void TextBox::stepDefaultUp(bool shiftPressed, bool breakSelection) {
uint offset = std::min(size_t(maxLocalCaret), getLineLength(caretLine-1)-1); uint offset = std::min(size_t(maxLocalCaret), getLineLength(caretLine-1)-1);
setCaret(label->getTextLineOffset(caretLine-1) + offset); setCaret(label->getTextLineOffset(caretLine-1) + offset);
} else { } else {
setCaret(0); setCaret(0UL);
} }
if (shiftPressed) { if (shiftPressed) {
if (selectionStart == selectionEnd) { if (selectionStart == selectionEnd) {
@ -628,11 +628,11 @@ std::wstring TextBox::getSelection() const {
return input.substr(selectionStart, selectionEnd-selectionStart); return input.substr(selectionStart, selectionEnd-selectionStart);
} }
uint TextBox::getCaret() const { size_t TextBox::getCaret() const {
return caret; return caret;
} }
void TextBox::setCaret(uint position) { void TextBox::setCaret(size_t position) {
this->caret = std::min(static_cast<size_t>(position), input.length()); this->caret = std::min(static_cast<size_t>(position), input.length());
caretLastMove = Window::time(); caretLastMove = Window::time();
@ -652,6 +652,14 @@ void TextBox::setCaret(uint position) {
if (realoffset-width > 0) { if (realoffset-width > 0) {
setTextOffset(textOffset + realoffset-width); setTextOffset(textOffset + realoffset-width);
} else if (realoffset < 0) { } else if (realoffset < 0) {
setTextOffset(std::max(textOffset + realoffset, 0U)); setTextOffset(std::max(textOffset + realoffset, 0LU));
}
}
void TextBox::setCaret(ssize_t position) {
if (position < 0) {
setCaret(static_cast<size_t>(input.length() + position + 1));
} else {
setCaret(static_cast<size_t>(position));
} }
} }

View File

@ -24,10 +24,10 @@ namespace gui {
runnable onDownPressed; runnable onDownPressed;
bool valid = true; bool valid = true;
/// @brief text input pointer, value may be greather than text length /// @brief text input pointer, value may be greather than text length
uint caret = 0; size_t caret = 0;
/// @brief actual local (line) position of the caret on vertical move /// @brief actual local (line) position of the caret on vertical move
uint maxLocalCaret = 0; size_t maxLocalCaret = 0;
uint textOffset = 0; size_t textOffset = 0;
int textInitX; int textInitX;
/// @brief last time of the caret was moved (used for blink animation) /// @brief last time of the caret was moved (used for blink animation)
double caretLastMove = 0.0; double caretLastMove = 0.0;
@ -112,11 +112,15 @@ namespace gui {
/// @brief Get current caret position in text /// @brief Get current caret position in text
/// @return integer in range [0, text.length()] /// @return integer in range [0, text.length()]
virtual uint getCaret() const; virtual size_t getCaret() const;
/// @brief Set caret position in the text /// @brief Set caret position in the text
/// @param position integer in range [0, text.length()] /// @param position integer in range [0, text.length()]
virtual void setCaret(uint position); virtual void setCaret(size_t position);
/// @brief Set caret position in the text
/// @param position integer in range [-text.length(), text.length()]
virtual void setCaret(ssize_t position);
/// @brief Select part of the text /// @brief Select part of the text
/// @param start index of the first selected character /// @param start index of the first selected character

View File

@ -50,7 +50,11 @@ static Gravity gravity_from_string(const std::string& str) {
return Gravity::none; return Gravity::none;
} }
static runnable create_runnable(UiXmlReader& reader, xml::xmlelement element, const std::string& name) { static runnable create_runnable(
const UiXmlReader& reader,
xml::xmlelement element,
const std::string& name
) {
if (element->has(name)) { if (element->has(name)) {
std::string text = element->attr(name).getText(); std::string text = element->attr(name).getText();
if (!text.empty()) { if (!text.empty()) {

View File

@ -201,6 +201,13 @@ static int p_is_valid(UINode* node) {
return 0; return 0;
} }
static int p_get_caret(UINode* node) {
if (auto box = dynamic_cast<TextBox*>(node)) {
return state->pushinteger(static_cast<integer_t>(box->getCaret()));
}
return 0;
}
static int p_get_placeholder(UINode* node) { static int p_get_placeholder(UINode* node) {
if (auto box = dynamic_cast<TextBox*>(node)) { if (auto box = dynamic_cast<TextBox*>(node)) {
return state->pushstring(util::wstr2str_utf8(box->getPlaceholder())); return state->pushstring(util::wstr2str_utf8(box->getPlaceholder()));
@ -292,6 +299,7 @@ static int l_gui_getattr(lua_State* L) {
{"clear", p_get_clear}, {"clear", p_get_clear},
{"placeholder", p_get_placeholder}, {"placeholder", p_get_placeholder},
{"valid", p_is_valid}, {"valid", p_is_valid},
{"caret", p_get_caret},
{"text", p_get_text}, {"text", p_get_text},
{"editable", p_get_editable}, {"editable", p_get_editable},
{"value", p_get_value}, {"value", p_get_value},
@ -353,6 +361,11 @@ static void p_set_text(UINode* node, int idx) {
box->setText(util::str2wstr_utf8(state->tostring(idx))); box->setText(util::str2wstr_utf8(state->tostring(idx)));
} }
} }
static void p_set_caret(UINode* node, int idx) {
if (auto box = dynamic_cast<TextBox*>(node)) {
box->setCaret(static_cast<ssize_t>(state->tointeger(idx)));
}
}
static void p_set_editable(UINode* node, int idx) { static void p_set_editable(UINode* node, int idx) {
if (auto box = dynamic_cast<TextBox*>(node)) { if (auto box = dynamic_cast<TextBox*>(node)) {
box->setEditable(state->toboolean(idx)); box->setEditable(state->toboolean(idx));
@ -438,6 +451,7 @@ static int l_gui_setattr(lua_State* L) {
{"placeholder", p_set_placeholder}, {"placeholder", p_set_placeholder},
{"text", p_set_text}, {"text", p_set_text},
{"editable", p_set_editable}, {"editable", p_set_editable},
{"caret", p_set_caret},
{"value", p_set_value}, {"value", p_set_value},
{"min", p_set_min}, {"min", p_set_min},
{"max", p_set_max}, {"max", p_set_max},