1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-23 09:17:36 +00:00

GWindow: Add SerenityKeys minimum functionality

This commit is contained in:
faissaloo 2019-06-03 16:02:49 +01:00
parent 9ac95d1867
commit 72264661fd
6 changed files with 109 additions and 4 deletions

View file

@ -230,6 +230,19 @@ void GWindow::event(CEvent& event)
for (auto& rect : rects)
m_main_widget->event(*make<GPaintEvent>(rect));
if (m_keybind_mode) {
//If we're in keybind mode indicate widgets in m_potential_keybind_widgets
GPainter painter(*m_main_widget);
painter.draw_text(Rect(20,20,20,20), m_entered_keybind.characters(), TextAlignment::TopLeft, Color::Green);
for (auto& keypair: m_hashed_potential_keybind_widgets) {
auto widget = keypair.value;
auto rect = Rect(widget->x()-5, widget->y()-5, 12, 12);
painter.draw_text(rect, keypair.key.characters(), TextAlignment::TopLeft, Color::Black);
}
}
if (m_double_buffering_enabled)
flip(rects);
else if (created_new_backing_store)
@ -251,10 +264,44 @@ void GWindow::event(CEvent& event)
}
if (event.type() == GEvent::KeyUp || event.type() == GEvent::KeyDown) {
if (m_focused_widget)
return m_focused_widget->event(event);
if (m_main_widget)
return m_main_widget->event(event);
auto keyevent = static_cast<GKeyEvent&>(event);
if (keyevent.logo() && event.type() == GEvent::KeyUp) {
if (m_keybind_mode) {
m_keybind_mode = false;
} else {
m_keybind_mode = true;
find_keyboard_selectable();
m_entered_keybind = "";
}
update();
return;
}
if (m_keybind_mode) {
StringBuilder builder;
//Y u no work
builder.append(m_entered_keybind);
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()) {
m_keybind_mode = false;
const auto& point = Point();
auto event = make<GMouseEvent>(GEvent::MouseDown, point, 0, GMouseButton::Left, 0, 0);
found_widget->value->event(*event);
event = make<GMouseEvent>(GEvent::MouseUp, point, 0, GMouseButton::Left, 0, 0);
found_widget->value->event(*event);
//Call click on the found widget
}
//m_entered_keybind.append(keyevent.text());
update();
} else {
if (m_focused_widget)
return m_focused_widget->event(event);
if (m_main_widget)
return m_main_widget->event(event);
}
return;
}
@ -296,6 +343,44 @@ void GWindow::event(CEvent& event)
CObject::event(event);
}
void GWindow::find_keyboard_selectable() {
m_potential_keybind_widgets.clear();
m_hashed_potential_keybind_widgets.clear();
find_keyboard_selectable_children(m_main_widget);
size_t buffer_length = ceil_div(m_potential_keybind_widgets.size(), ('z'-'a'))+1;
char keybind_buffer[buffer_length];
for (size_t i = 0; i < buffer_length-1; i++) {
keybind_buffer[i] = 'a';
}
keybind_buffer[buffer_length-1] = '\0';
for (auto& widget: m_potential_keybind_widgets) {
m_hashed_potential_keybind_widgets.set(String(keybind_buffer), widget);
for (size_t i = 0; i < buffer_length-1; i++) {
if (keybind_buffer[i] >= 'z') {
keybind_buffer[i] = 'a';
} else {
keybind_buffer[i]++;
break;
}
}
}
}
void GWindow::find_keyboard_selectable_children(GWidget* widget) {
//Rather than painting immediately we need a step to collect all the keybinds first
widget -> for_each_child_widget([&] (auto& child) {
if (child.accepts_keyboard_select()) {
//auto rect = Rect(child.x()-5, child.y()-5, 10, 10);
m_potential_keybind_widgets.append(&child);
find_keyboard_selectable_children(&child);
}
return IterationDecision::Continue;
});
}
bool GWindow::is_visible() const
{
return false;
@ -305,6 +390,10 @@ void GWindow::update(const Rect& a_rect)
{
if (!m_window_id)
return;
//We probably shouldn't clear the buffer on updates
//find_keyboard_selectable();
for (auto& pending_rect : m_pending_paint_event_rects) {
if (pending_rect.contains(a_rect)) {
#ifdef UPDATE_COALESCING_DEBUG