summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--LibGUI/GAbstractButton.h2
-rw-r--r--LibGUI/GButton.cpp2
-rw-r--r--LibGUI/GButton.h2
-rw-r--r--LibGUI/GWidget.h2
-rw-r--r--LibGUI/GWindow.cpp68
-rw-r--r--LibGUI/GWindow.h6
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;
};