From 34a64ed25b00028370fdb96cd9a01fa3a3d50fd4 Mon Sep 17 00:00:00 2001 From: Rob Ryan Date: Sun, 15 Aug 2021 15:48:53 +1000 Subject: [PATCH] LibGUI+Browser: Add UrlBox class This allows the address bar to "select all" when initially gaining focus as Firefox and Chrome do. A future improvement on this would be for the Widget class to mange and provide focus transition as part of the events instead of the UrlBox class. Currently focus is updated before the event is provided to the UrlBox class. --- Userland/Applications/Browser/Tab.cpp | 8 ++++-- Userland/Applications/Browser/Tab.h | 2 +- Userland/Libraries/LibGUI/Forward.h | 1 + Userland/Libraries/LibGUI/TextBox.cpp | 35 ++++++++++++++++++++++++ Userland/Libraries/LibGUI/TextBox.h | 16 +++++++++++ Userland/Libraries/LibGUI/TextEditor.cpp | 13 ++++++--- Userland/Libraries/LibGUI/TextEditor.h | 1 + 7 files changed, 68 insertions(+), 8 deletions(-) diff --git a/Userland/Applications/Browser/Tab.cpp b/Userland/Applications/Browser/Tab.cpp index b8f2527d56..ee548706f1 100644 --- a/Userland/Applications/Browser/Tab.cpp +++ b/Userland/Applications/Browser/Tab.cpp @@ -142,7 +142,7 @@ Tab::Tab(BrowserWindow& window, Type type) toolbar.add_action(window.go_home_action()); toolbar.add_action(window.reload_action()); - m_location_box = toolbar.add(); + m_location_box = toolbar.add(); m_location_box->set_placeholder("Address"); m_location_box->on_return_pressed = [this] { @@ -153,7 +153,7 @@ Tab::Tab(BrowserWindow& window, Type type) auto url = url_from_user_input(m_location_box->text()); load(url); - view().set_focus(true); + view(); }; m_location_box->add_custom_context_menu_action(GUI::Action::create("Paste && Go", [this](auto&) { @@ -312,8 +312,8 @@ Tab::Tab(BrowserWindow& window, Type type) auto focus_location_box_action = GUI::Action::create( "Focus location box", { Mod_Ctrl, Key_L }, Key_F6, [this](auto&) { - m_location_box->select_all(); m_location_box->set_focus(true); + m_location_box->select_current_line(); }, this); @@ -371,6 +371,8 @@ void Tab::load(const URL& url, LoadType load_type) m_page_view->load(url); else m_web_content_view->load(url); + + m_location_box->set_focus(false); } URL Tab::url() const diff --git a/Userland/Applications/Browser/Tab.h b/Userland/Applications/Browser/Tab.h index 8e4cb93ee8..49c4a9ecf9 100644 --- a/Userland/Applications/Browser/Tab.h +++ b/Userland/Applications/Browser/Tab.h @@ -89,7 +89,7 @@ private: RefPtr m_page_view; RefPtr m_web_content_view; - RefPtr m_location_box; + RefPtr m_location_box; RefPtr m_bookmark_button; RefPtr m_dom_inspector_window; RefPtr m_console_window; diff --git a/Userland/Libraries/LibGUI/Forward.h b/Userland/Libraries/LibGUI/Forward.h index bfa243ed48..21e0c77f06 100644 --- a/Userland/Libraries/LibGUI/Forward.h +++ b/Userland/Libraries/LibGUI/Forward.h @@ -66,6 +66,7 @@ class Statusbar; class TabWidget; class TableView; class TextBox; +class UrlBox; class TextDocument; class TextDocumentLine; struct TextDocumentSpan; diff --git a/Userland/Libraries/LibGUI/TextBox.cpp b/Userland/Libraries/LibGUI/TextBox.cpp index b93c8d5213..b02b69b9cb 100644 --- a/Userland/Libraries/LibGUI/TextBox.cpp +++ b/Userland/Libraries/LibGUI/TextBox.cpp @@ -8,6 +8,7 @@ REGISTER_WIDGET(GUI, TextBox) REGISTER_WIDGET(GUI, PasswordBox) +REGISTER_WIDGET(GUI, UrlBox) namespace GUI { @@ -80,4 +81,38 @@ PasswordBox::PasswordBox() set_text_is_secret(true); } +UrlBox::UrlBox() + : TextBox() +{ + set_auto_focusable(false); +} + +UrlBox::~UrlBox() +{ +} + +void UrlBox::focusout_event(GUI::FocusEvent& event) +{ + set_focus_transition(true); + + TextBox::focusout_event(event); +} + +void UrlBox::mousedown_event(GUI::MouseEvent& event) +{ + if (is_displayonly()) + return; + + if (event.button() != MouseButton::Left) + return; + + if (is_focus_transition()) { + TextBox::select_current_line(); + + set_focus_transition(false); + } else { + TextBox::mousedown_event(event); + } +} + } diff --git a/Userland/Libraries/LibGUI/TextBox.h b/Userland/Libraries/LibGUI/TextBox.h index 374f579e0a..13e002e628 100644 --- a/Userland/Libraries/LibGUI/TextBox.h +++ b/Userland/Libraries/LibGUI/TextBox.h @@ -43,4 +43,20 @@ public: PasswordBox(); }; +class UrlBox : public TextBox { + C_OBJECT(UrlBox) +public: + UrlBox(); + virtual ~UrlBox() override; + + void set_focus_transition(bool focus_transition) { m_focus_transition = focus_transition; } + bool is_focus_transition() const { return m_focus_transition; } + +private: + virtual void mousedown_event(GUI::MouseEvent&) override; + virtual void focusout_event(GUI::FocusEvent&) override; + + bool m_focus_transition { true }; +}; + } diff --git a/Userland/Libraries/LibGUI/TextEditor.cpp b/Userland/Libraries/LibGUI/TextEditor.cpp index 09cb9e576e..58450027aa 100644 --- a/Userland/Libraries/LibGUI/TextEditor.cpp +++ b/Userland/Libraries/LibGUI/TextEditor.cpp @@ -256,10 +256,7 @@ void TextEditor::mousedown_event(MouseEvent& event) if (m_triple_click_timer.is_valid() && m_triple_click_timer.elapsed() < 250) { m_triple_click_timer = Core::ElapsedTimer(); - m_selection = document().range_for_entire_line(m_cursor.line()); - set_cursor(m_selection.end()); - update(); - did_update_selection(); + select_current_line(); return; } @@ -310,6 +307,14 @@ void TextEditor::mousemove_event(MouseEvent& event) } } +void TextEditor::select_current_line() +{ + m_selection = document().range_for_entire_line(m_cursor.line()); + set_cursor(m_selection.end()); + update(); + did_update_selection(); +} + void TextEditor::automatic_selection_scroll_timer_fired() { if (!m_in_drag_select) { diff --git a/Userland/Libraries/LibGUI/TextEditor.h b/Userland/Libraries/LibGUI/TextEditor.h index 3d832bccda..30b57f1794 100644 --- a/Userland/Libraries/LibGUI/TextEditor.h +++ b/Userland/Libraries/LibGUI/TextEditor.h @@ -142,6 +142,7 @@ public: void delete_previous_char(); void delete_from_line_start_to_cursor(); void select_all(); + void select_current_line(); virtual void undo(); virtual void redo();