diff options
-rw-r--r-- | LibGUI/GAbstractButton.h | 2 | ||||
-rw-r--r-- | LibGUI/GButton.cpp | 2 | ||||
-rw-r--r-- | LibGUI/GButton.h | 2 | ||||
-rw-r--r-- | LibGUI/GWidget.h | 2 | ||||
-rw-r--r-- | LibGUI/GWindow.cpp | 68 | ||||
-rw-r--r-- | LibGUI/GWindow.h | 6 |
6 files changed, 43 insertions, 39 deletions
diff --git a/LibGUI/GAbstractButton.h b/LibGUI/GAbstractButton.h index 340b0ee880..269a7ea834 100644 --- a/LibGUI/GAbstractButton.h +++ b/LibGUI/GAbstractButton.h @@ -29,7 +29,7 @@ public: virtual void click() = 0; virtual const char* class_name() const override { return "GAbstractButton"; } virtual bool accepts_focus() const override { return true; } - virtual bool accepts_keyboard_select() const { return true; } + virtual bool supports_keyboard_activation() const { return true; } protected: explicit GAbstractButton(GWidget* parent); diff --git a/LibGUI/GButton.cpp b/LibGUI/GButton.cpp index 203ef664e6..c9c4e119f2 100644 --- a/LibGUI/GButton.cpp +++ b/LibGUI/GButton.cpp @@ -66,7 +66,7 @@ void GButton::click() on_click(*this); } -bool GButton::accepts_keyboard_select() const +bool GButton::supports_keyboard_activation() const { return is_enabled(); } diff --git a/LibGUI/GButton.h b/LibGUI/GButton.h index 11eb68f9f8..2e12b8f3e1 100644 --- a/LibGUI/GButton.h +++ b/LibGUI/GButton.h @@ -33,7 +33,7 @@ public: virtual const char* class_name() const override { return "GButton"; } virtual bool accepts_focus() const override { return true; } - virtual bool accepts_keyboard_select() const; + virtual bool supports_keyboard_activation() const; protected: virtual void paint_event(GPaintEvent&) override; diff --git a/LibGUI/GWidget.h b/LibGUI/GWidget.h index c978f913c9..36d2d025f5 100644 --- a/LibGUI/GWidget.h +++ b/LibGUI/GWidget.h @@ -102,7 +102,7 @@ public: void update(const Rect&); virtual bool accepts_focus() const { return false; } - virtual bool accepts_keyboard_select() const { return false; } + virtual bool supports_keyboard_activation() const { return false; } bool is_focused() const; void set_focus(bool); diff --git a/LibGUI/GWindow.cpp b/LibGUI/GWindow.cpp index cf13d8a24c..1f2e0b1682 100644 --- a/LibGUI/GWindow.cpp +++ b/LibGUI/GWindow.cpp @@ -271,7 +271,7 @@ void GWindow::event(CEvent& event) m_keybind_mode = false; } else { m_keybind_mode = true; - find_keyboard_selectable(); + collect_keyboard_activation_targets(); m_entered_keybind = ""; } update(); @@ -285,8 +285,8 @@ void GWindow::event(CEvent& event) builder.append(keyevent.text()); m_entered_keybind = builder.to_string(); - auto found_widget = m_hashed_potential_keybind_widgets.find(m_entered_keybind); - if (found_widget != m_hashed_potential_keybind_widgets.end()) { + auto found_widget = m_keyboard_activation_targets.find(m_entered_keybind); + if (found_widget != m_keyboard_activation_targets.end()) { m_keybind_mode = false; auto event = make<GMouseEvent>(GEvent::MouseDown, Point(), 0, GMouseButton::Left, 0, 0); found_widget->value->event(*event); @@ -355,66 +355,70 @@ void GWindow::paint_keybinds() return; GPainter painter(*m_main_widget); - for (auto& keypair : m_hashed_potential_keybind_widgets) { - auto widget = keypair.value; + for (auto& keypair : m_keyboard_activation_targets) { + if (!keypair.value) + continue; + auto& widget = *keypair.value; bool could_be_keybind = true; - for (size_t i = 0; i < m_entered_keybind.length(); i++) { + for (int i = 0; i < m_entered_keybind.length(); ++i) { if (keypair.key.characters()[i] != m_entered_keybind.characters()[i]) { could_be_keybind = false; + break; } } if (could_be_keybind) { - auto rect = Rect(widget->x() - 5, widget->y() - 5, 4 + Font::default_font().width(keypair.key), 16); - auto highlight_rect = Rect(widget->x() - 3, widget->y() - 5, 0, 16); + Rect rect { widget.x() - 5, widget.y() - 5, 4 + Font::default_font().width(keypair.key), 16 }; + Rect highlight_rect { widget.x() - 3, widget.y() - 5, 0, 16 }; painter.fill_rect(rect, Color::LightGray); - painter.draw_rect(rect, Color::Black, false); + painter.draw_rect(rect, Color::Black); painter.draw_text(rect, keypair.key.characters(), TextAlignment::Center, Color::Black); painter.draw_text(highlight_rect, m_entered_keybind.characters(), TextAlignment::CenterLeft, Color::MidGray); } } } -void GWindow::find_keyboard_selectable() +static void collect_keyboard_activation_targets_impl(GWidget& widget, Vector<GWidget*>& targets) { - Vector<GWidget*> potential_keybind_widgets; - m_hashed_potential_keybind_widgets.clear(); - find_keyboard_selectable_children(m_main_widget, potential_keybind_widgets); + widget.for_each_child_widget([&](auto& child) { + if (child.supports_keyboard_activation()) { + targets.append(&child); + collect_keyboard_activation_targets_impl(child, targets); + } + return IterationDecision::Continue; + }); +} + +void GWindow::collect_keyboard_activation_targets() +{ + m_keyboard_activation_targets.clear(); + if (!m_main_widget) + return; - m_max_keybind_length = ceil_div(potential_keybind_widgets.size(), ('z' - 'a')); + Vector<GWidget*> targets; + collect_keyboard_activation_targets_impl(*m_main_widget, targets); + + m_max_keybind_length = ceil_div(targets.size(), ('z' - 'a')); size_t buffer_length = m_max_keybind_length + 1; char keybind_buffer[buffer_length]; - for (size_t i = 0; i < buffer_length - 1; i++) { + for (size_t i = 0; i < buffer_length - 1; ++i) keybind_buffer[i] = 'a'; - } keybind_buffer[buffer_length - 1] = '\0'; - for (auto& widget : potential_keybind_widgets) { - m_hashed_potential_keybind_widgets.set(String(keybind_buffer), widget); - - for (size_t i = 0; i < buffer_length - 1; i++) { + for (auto& widget : targets) { + m_keyboard_activation_targets.set(String(keybind_buffer), widget->make_weak_ptr()); + for (size_t i = 0; i < buffer_length - 1; ++i) { if (keybind_buffer[i] >= 'z') { keybind_buffer[i] = 'a'; } else { - keybind_buffer[i]++; + ++keybind_buffer[i]; break; } } } } -void GWindow::find_keyboard_selectable_children(GWidget* widget, Vector<GWidget*>& potential_keybind_widgets) -{ - widget->for_each_child_widget([&](auto& child) { - if (child.accepts_keyboard_select()) { - potential_keybind_widgets.append(&child); - find_keyboard_selectable_children(&child, potential_keybind_widgets); - } - return IterationDecision::Continue; - }); -} - bool GWindow::is_visible() const { return false; diff --git a/LibGUI/GWindow.h b/LibGUI/GWindow.h index 988b81ffb1..f83fded8a5 100644 --- a/LibGUI/GWindow.h +++ b/LibGUI/GWindow.h @@ -133,8 +133,8 @@ private: void paint_keybinds(); - void find_keyboard_selectable(); - void find_keyboard_selectable_children(GWidget* widget, Vector<GWidget*>& potential_keybind_widgets); + void collect_keyboard_activation_targets(); + Retained<GraphicsBitmap> create_backing_bitmap(const Size&); void set_current_backing_bitmap(GraphicsBitmap&, bool flush_immediately = false); void flip(const Vector<Rect, 32>& dirty_rects); @@ -167,5 +167,5 @@ private: bool m_keybind_mode { false }; String m_entered_keybind; size_t m_max_keybind_length { 0 }; - HashMap<String, GWidget*> m_hashed_potential_keybind_widgets; + HashMap<String, WeakPtr<GWidget>> m_keyboard_activation_targets; }; |