From 139dbfd5b508bacf7494ba2318eae80f96dc5e76 Mon Sep 17 00:00:00 2001 From: FalseHonesty Date: Tue, 26 May 2020 22:17:06 -0400 Subject: [PATCH] LibGUI: Add up & down arrow hooks and input history to TextBox This patch adds the ability to enable "input history" on a textbox, allowing to navigate between the history with the arrow keys. Also removes a custom TextBox subclass from HackStudio that added the exact same hooks, and moves it to use the now standard ones. --- DevTools/HackStudio/Locator.cpp | 28 ++---------------- DevTools/HackStudio/Locator.h | 4 +-- Libraries/LibGUI/TextBox.cpp | 51 +++++++++++++++++++++++++++++++++ Libraries/LibGUI/TextBox.h | 19 ++++++++++++ 4 files changed, 74 insertions(+), 28 deletions(-) diff --git a/DevTools/HackStudio/Locator.cpp b/DevTools/HackStudio/Locator.cpp index 5f31c0af372..2a9cc5205a2 100644 --- a/DevTools/HackStudio/Locator.cpp +++ b/DevTools/HackStudio/Locator.cpp @@ -73,28 +73,6 @@ private: Vector m_suggestions; }; -class LocatorTextBox final : public GUI::TextBox { - C_OBJECT(LocatorTextBox) -public: - virtual ~LocatorTextBox() override {} - - Function on_up; - Function on_down; - - virtual void keydown_event(GUI::KeyEvent& event) override - { - if (event.key() == Key_Up) - on_up(); - else if (event.key() == Key_Down) - on_down(); - - GUI::TextBox::keydown_event(event); - } - -private: - LocatorTextBox() {} -}; - Locator::Locator() { if (!s_cplusplus_icon) { @@ -106,14 +84,14 @@ Locator::Locator() set_layout(); set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fixed); set_preferred_size(0, 20); - m_textbox = add(); + m_textbox = add(); m_textbox->on_change = [this] { update_suggestions(); }; m_textbox->on_escape_pressed = [this] { m_popup_window->hide(); }; - m_textbox->on_up = [this] { + m_textbox->on_up_pressed = [this] { GUI::ModelIndex new_index = m_suggestion_view->selection().first(); if (new_index.is_valid()) new_index = m_suggestion_view->model()->index(new_index.row() - 1); @@ -125,7 +103,7 @@ Locator::Locator() m_suggestion_view->scroll_into_view(new_index, Orientation::Vertical); } }; - m_textbox->on_down = [this] { + m_textbox->on_down_pressed = [this] { GUI::ModelIndex new_index = m_suggestion_view->selection().first(); if (new_index.is_valid()) new_index = m_suggestion_view->model()->index(new_index.row() + 1); diff --git a/DevTools/HackStudio/Locator.h b/DevTools/HackStudio/Locator.h index 28033b0fce7..ccd615e4445 100644 --- a/DevTools/HackStudio/Locator.h +++ b/DevTools/HackStudio/Locator.h @@ -28,8 +28,6 @@ #include -class LocatorTextBox; - class Locator final : public GUI::Widget { C_OBJECT(Locator) public: @@ -44,7 +42,7 @@ private: Locator(); - RefPtr m_textbox; + RefPtr m_textbox; RefPtr m_popup_window; RefPtr m_suggestion_view; }; diff --git a/Libraries/LibGUI/TextBox.cpp b/Libraries/LibGUI/TextBox.cpp index 2df42b73b15..d7481c006c7 100644 --- a/Libraries/LibGUI/TextBox.cpp +++ b/Libraries/LibGUI/TextBox.cpp @@ -37,4 +37,55 @@ TextBox::~TextBox() { } +void TextBox::keydown_event(GUI::KeyEvent& event) +{ + TextEditor::keydown_event(event); + + if (event.key() == Key_Up) { + if (on_up_pressed) + on_up_pressed(); + + if (has_no_history() || !can_go_backwards_in_history()) + return; + + if (m_history_index >= static_cast(m_history.size())) + m_saved_input = text(); + + m_history_index--; + set_text(m_history[m_history_index]); + } else if (event.key() == Key_Down) { + if (on_down_pressed) + on_down_pressed(); + + if (has_no_history()) + return; + + if (can_go_forwards_in_history()) { + m_history_index++; + set_text(m_history[m_history_index]); + } else if (m_history_index < static_cast(m_history.size())) { + m_history_index++; + set_text(m_saved_input); + } + } +} + +void TextBox::add_current_text_to_history() +{ + if (!m_history_enabled) + return; + + auto input = text(); + if (m_history.is_empty() || m_history.last() != input) + add_input_to_history(input); + m_history_index = static_cast(m_history.size()); + m_saved_input = {}; +} + +void TextBox::add_input_to_history(String input) +{ + m_history.append(move(input)); + m_history_index++; +} + } diff --git a/Libraries/LibGUI/TextBox.h b/Libraries/LibGUI/TextBox.h index 566c567a604..79be6af5c3a 100644 --- a/Libraries/LibGUI/TextBox.h +++ b/Libraries/LibGUI/TextBox.h @@ -35,6 +35,25 @@ class TextBox : public TextEditor { public: TextBox(); virtual ~TextBox() override; + + Function on_up_pressed; + Function on_down_pressed; + + void set_history_enabled(bool enabled) { m_history_enabled = enabled; } + void add_current_text_to_history(); + +private: + virtual void keydown_event(GUI::KeyEvent&) override; + + bool has_no_history() const { return !m_history_enabled || m_history.is_empty(); } + bool can_go_backwards_in_history() const { return m_history_index > 0; } + bool can_go_forwards_in_history() const { return m_history_index < static_cast(m_history.size()) - 1; } + void add_input_to_history(String); + + bool m_history_enabled { false }; + Vector m_history; + int m_history_index { -1 }; + String m_saved_input; }; }