From 7241ac3771a7b63b7cbb3b0f53d4808bd4c5a979 Mon Sep 17 00:00:00 2001 From: GinjaNinja32 Date: Fri, 23 Aug 2024 21:49:43 +0100 Subject: [PATCH] Improve Lua console behaviour - Print input lines prepended with '> ' before running them. - Store history to allow easily returning to previous inputs. --- src/gui/gui2_textentry.cpp | 22 ++++++++++++++++ src/gui/gui2_textentry.h | 4 +++ src/menus/luaConsole.cpp | 54 ++++++++++++++++++++++++++++++++++++++ src/menus/luaConsole.h | 14 ++++++++++ 4 files changed, 94 insertions(+) diff --git a/src/gui/gui2_textentry.cpp b/src/gui/gui2_textentry.cpp index 96549e514d..49d9f45c6a 100644 --- a/src/gui/gui2_textentry.cpp +++ b/src/gui/gui2_textentry.cpp @@ -170,6 +170,11 @@ void GuiTextEntry::onTextInput(sp::TextInputEvent e) break; case sp::TextInputEvent::Up: case sp::TextInputEvent::UpWithSelection:{ + if (up_func) + { + up_func(text); + return; + } int end_of_line = text.substr(0, selection_end).rfind("\n"); if (end_of_line < 0) return; @@ -182,6 +187,11 @@ void GuiTextEntry::onTextInput(sp::TextInputEvent e) }break; case sp::TextInputEvent::Down: case sp::TextInputEvent::DownWithSelection:{ + if (down_func) + { + down_func(text); + return; + } int start_of_current_line = text.substr(0, selection_end).rfind("\n") + 1; int end_of_current_line = text.find("\n", selection_end); if (end_of_current_line < 0) @@ -413,6 +423,18 @@ GuiTextEntry* GuiTextEntry::enterCallback(func_t func) return this; } +GuiTextEntry* GuiTextEntry::upCallback(func_t func) +{ + this->up_func = func; + return this; +} + +GuiTextEntry* GuiTextEntry::downCallback(func_t func) +{ + this->down_func = func; + return this; +} + void GuiTextEntry::setCursorPosition(int offset) { selection_start = selection_end = std::clamp(offset, 0, int(text.size())); diff --git a/src/gui/gui2_textentry.h b/src/gui/gui2_textentry.h index f75ca64180..1df584699b 100644 --- a/src/gui/gui2_textentry.h +++ b/src/gui/gui2_textentry.h @@ -25,6 +25,8 @@ class GuiTextEntry : public GuiElement const GuiThemeStyle* back_style; func_t func; func_t enter_func; + func_t up_func; + func_t down_func; const float blink_rate = 0.530f; sp::SystemTimer blink_timer; @@ -52,6 +54,8 @@ class GuiTextEntry : public GuiElement GuiTextEntry* setHidePassword(bool enabled=true); GuiTextEntry* callback(func_t func); GuiTextEntry* enterCallback(func_t func); + GuiTextEntry* upCallback(func_t func); + GuiTextEntry* downCallback(func_t func); void setCursorPosition(int offset); protected: diff --git a/src/menus/luaConsole.cpp b/src/menus/luaConsole.cpp index daaa06f9cf..a2b33fdb69 100644 --- a/src/menus/luaConsole.cpp +++ b/src/menus/luaConsole.cpp @@ -41,7 +41,22 @@ LuaConsole::LuaConsole() entry->enterCallback([this](string s) { P script = engine->getObject("scenario"); if (script) + { + LuaConsole::addLog("> " + s); script->runCode(s); + history.append(s); + entry->setText(""); + } + }); + entry->upCallback([this](string s) { + string text = history.movePrevious(s); + entry->setText(text); + entry->setCursorPosition(text.size()); + }); + entry->downCallback([this](string s) { + string text = history.moveNext(s); + entry->setText(text); + entry->setCursorPosition(text.size()); }); top->hide(); @@ -102,3 +117,42 @@ void LuaConsole::update(float delta) } } } + +string ConsoleHistory::movePrevious(string s) { + if (position == 0) + // beginning of history, nothing to go up to. keep the line the same. + return s; + + if (position == entries.size()) + // previous from a line not in history; set it pending so we can go back down to it later + pending = s; + else + entries[position] = s; + + return entries[--position]; +} + +string ConsoleHistory::moveNext(string s) { + if (position == entries.size()) + return s; + + if (position + 1 == entries.size()) + { + // end of history, nothing to do down to. + // if we had a pending entry, put it back + position++; + string wasPending = pending; + pending = ""; + return wasPending; + } + + entries[position] = s; + return entries[++position]; +} + +void ConsoleHistory::append(string s) +{ + entries.push_back(s); + position = entries.size(); + pending = ""; +} diff --git a/src/menus/luaConsole.h b/src/menus/luaConsole.h index 7d03c6d0fb..55d302fbba 100644 --- a/src/menus/luaConsole.h +++ b/src/menus/luaConsole.h @@ -6,6 +6,19 @@ #include "timer.h" +class ConsoleHistory +{ +public: + string movePrevious(string); + string moveNext(string); + void append(string); + +private: + std::vector entries; + unsigned int position = 0; + string pending = ""; +}; + class GuiTextEntry; class LuaConsole : public GuiCanvas, public Updatable { @@ -17,6 +30,7 @@ class LuaConsole : public GuiCanvas, public Updatable void update(float delta) override; private: std::vector log_messages; + ConsoleHistory history; GuiElement* top; GuiTextEntry* log; GuiTextEntry* entry;