LibGUI: Flesh out focus implementation and more GTextBox work.

This commit is contained in:
Andreas Kling 2019-01-26 11:24:16 +01:00
parent d72575d196
commit de2423de5f
10 changed files with 54 additions and 27 deletions

View file

@ -19,6 +19,7 @@ private:
virtual void mousedown_event(GMouseEvent&) override;
virtual const char* class_name() const override { return "GCheckBox"; }
virtual bool accepts_focus() const override { return true; }
String m_caption;
bool m_checked { false };

View file

@ -5,21 +5,6 @@
#include <AK/AKString.h>
#include <AK/Types.h>
static const char* eventNames[] = {
"Invalid",
"Quit",
"Show",
"Hide",
"Paint",
"MouseMove",
"MouseDown",
"MouseUp",
"KeyDown",
"KeyUp",
"Timer",
"DeferredDestroy",
};
class GEvent {
public:
enum Type {
@ -37,6 +22,8 @@ public:
DeferredDestroy,
WindowBecameInactive,
WindowBecameActive,
FocusIn,
FocusOut,
};
GEvent() { }
@ -45,8 +32,6 @@ public:
Type type() const { return m_type; }
const char* name() const { return eventNames[(unsigned)m_type]; }
bool is_mouse_event() const { return m_type == MouseMove || m_type == MouseDown || m_type == MouseUp; }
bool is_key_event() const { return m_type == KeyUp || m_type == KeyDown; }
bool is_paint_event() const { return m_type == Paint; }

View file

@ -14,6 +14,7 @@ private:
virtual void paint_event(GPaintEvent&) override;
virtual void mousedown_event(GMouseEvent&) override;
virtual const char* class_name() const override { return "GListBox"; }
virtual bool accepts_focus() const override { return true; }
Rect item_rect(int index) const;

View file

@ -107,8 +107,8 @@ void GTextBox::keydown_event(GKeyEvent& event)
case KeyCode::Key_Backspace:
return handle_backspace();
case KeyCode::Key_Return:
if (onReturnPressed)
onReturnPressed(*this);
if (on_return_pressed)
on_return_pressed(*this);
return;
}

View file

@ -11,7 +11,7 @@ public:
String text() const { return m_text; }
void set_text(String&&);
Function<void(GTextBox&)> onReturnPressed;
Function<void(GTextBox&)> on_return_pressed;
private:
virtual const char* class_name() const override { return "GTextBox"; }
@ -19,6 +19,7 @@ private:
virtual void mousedown_event(GMouseEvent&) override;
virtual void keydown_event(GKeyEvent&) override;
virtual void timerEvent(GTimerEvent&) override;
virtual bool accepts_focus() const override { return true; }
void handle_backspace();

View file

@ -38,6 +38,9 @@ void GWidget::event(GEvent& event)
case GEvent::Paint:
m_has_pending_paint_event = false;
return paint_event(static_cast<GPaintEvent&>(event));
case GEvent::FocusIn:
case GEvent::FocusOut:
return focusin_event(event);
case GEvent::Show:
return show_event(static_cast<GShowEvent&>(event));
case GEvent::Hide:
@ -49,7 +52,8 @@ void GWidget::event(GEvent& event)
case GEvent::MouseMove:
return mousemove_event(static_cast<GMouseEvent&>(event));
case GEvent::MouseDown:
// FIXME: Focus self if needed.
if (accepts_focus())
set_focus(true);
return mousedown_event(static_cast<GMouseEvent&>(event));
case GEvent::MouseUp:
return mouseup_event(static_cast<GMouseEvent&>(event));
@ -98,6 +102,14 @@ void GWidget::mousemove_event(GMouseEvent&)
{
}
void GWidget::focusin_event(GEvent&)
{
}
void GWidget::focusout_event(GEvent&)
{
}
void GWidget::update()
{
auto* w = window();
@ -130,15 +142,23 @@ void GWidget::set_window(GWindow* window)
bool GWidget::is_focused() const
{
// FIXME: Implement.
return false;
auto* win = window();
if (!win)
return false;
return win->focused_widget() == this;
}
void GWidget::set_focus(bool focus)
{
if (focus == is_focused())
auto* win = window();
if (!win)
return;
// FIXME: Implement.
if (focus) {
win->set_focused_widget(this);
} else {
if (win->focused_widget() == this)
win->set_focused_widget(nullptr);
}
}
void GWidget::set_font(RetainPtr<Font>&& font)

View file

@ -24,6 +24,8 @@ public:
virtual void mousemove_event(GMouseEvent&);
virtual void mousedown_event(GMouseEvent&);
virtual void mouseup_event(GMouseEvent&);
virtual void focusin_event(GEvent&);
virtual void focusout_event(GEvent&);
Rect relative_rect() const { return m_relative_rect; }
Point relative_position() const { return m_relative_rect.location(); }
@ -39,6 +41,8 @@ public:
void update();
void repaint(const Rect&);
virtual bool accepts_focus() const { return false; }
bool is_focused() const;
void set_focus(bool);

View file

@ -139,8 +139,13 @@ void GWindow::set_focused_widget(GWidget* widget)
{
if (m_focused_widget == widget)
return;
if (m_focused_widget)
if (m_focused_widget) {
GEventLoop::main().post_event(m_focused_widget, make<GEvent>(GEvent::FocusOut));
m_focused_widget->update();
}
m_focused_widget = widget;
m_focused_widget->update();
if (m_focused_widget) {
GEventLoop::main().post_event(m_focused_widget, make<GEvent>(GEvent::FocusIn));
m_focused_widget->update();
}
}

View file

@ -38,6 +38,10 @@ public:
GWidget* main_widget() { return m_main_widget; }
const GWidget* main_widget() const { return m_main_widget; }
void set_main_widget(GWidget*);
GWidget* focused_widget() { return m_focused_widget; }
const GWidget* focused_widget() const { return m_focused_widget; }
void set_focused_widget(GWidget*);
void show();

View file

@ -110,6 +110,12 @@ GWindow* make_launcher_window()
auto* textbox = new GTextBox(widget);
textbox->set_relative_rect({ 5, 110, 90, 20 });
textbox->on_return_pressed = [window] (GTextBox& textbox) {
window->set_title(textbox.text());
};
auto* other_textbox = new GTextBox(widget);
other_textbox->set_relative_rect({ 5, 140, 90, 20 });
window->set_focused_widget(textbox);