mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 12:58:12 +00:00
LibGUI: Flesh out focus implementation and more GTextBox work.
This commit is contained in:
parent
d72575d196
commit
de2423de5f
10 changed files with 54 additions and 27 deletions
|
@ -19,6 +19,7 @@ private:
|
||||||
virtual void mousedown_event(GMouseEvent&) override;
|
virtual void mousedown_event(GMouseEvent&) override;
|
||||||
|
|
||||||
virtual const char* class_name() const override { return "GCheckBox"; }
|
virtual const char* class_name() const override { return "GCheckBox"; }
|
||||||
|
virtual bool accepts_focus() const override { return true; }
|
||||||
|
|
||||||
String m_caption;
|
String m_caption;
|
||||||
bool m_checked { false };
|
bool m_checked { false };
|
||||||
|
|
|
@ -5,21 +5,6 @@
|
||||||
#include <AK/AKString.h>
|
#include <AK/AKString.h>
|
||||||
#include <AK/Types.h>
|
#include <AK/Types.h>
|
||||||
|
|
||||||
static const char* eventNames[] = {
|
|
||||||
"Invalid",
|
|
||||||
"Quit",
|
|
||||||
"Show",
|
|
||||||
"Hide",
|
|
||||||
"Paint",
|
|
||||||
"MouseMove",
|
|
||||||
"MouseDown",
|
|
||||||
"MouseUp",
|
|
||||||
"KeyDown",
|
|
||||||
"KeyUp",
|
|
||||||
"Timer",
|
|
||||||
"DeferredDestroy",
|
|
||||||
};
|
|
||||||
|
|
||||||
class GEvent {
|
class GEvent {
|
||||||
public:
|
public:
|
||||||
enum Type {
|
enum Type {
|
||||||
|
@ -37,6 +22,8 @@ public:
|
||||||
DeferredDestroy,
|
DeferredDestroy,
|
||||||
WindowBecameInactive,
|
WindowBecameInactive,
|
||||||
WindowBecameActive,
|
WindowBecameActive,
|
||||||
|
FocusIn,
|
||||||
|
FocusOut,
|
||||||
};
|
};
|
||||||
|
|
||||||
GEvent() { }
|
GEvent() { }
|
||||||
|
@ -45,8 +32,6 @@ public:
|
||||||
|
|
||||||
Type type() const { return m_type; }
|
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_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_key_event() const { return m_type == KeyUp || m_type == KeyDown; }
|
||||||
bool is_paint_event() const { return m_type == Paint; }
|
bool is_paint_event() const { return m_type == Paint; }
|
||||||
|
|
|
@ -14,6 +14,7 @@ private:
|
||||||
virtual void paint_event(GPaintEvent&) override;
|
virtual void paint_event(GPaintEvent&) override;
|
||||||
virtual void mousedown_event(GMouseEvent&) override;
|
virtual void mousedown_event(GMouseEvent&) override;
|
||||||
virtual const char* class_name() const override { return "GListBox"; }
|
virtual const char* class_name() const override { return "GListBox"; }
|
||||||
|
virtual bool accepts_focus() const override { return true; }
|
||||||
|
|
||||||
Rect item_rect(int index) const;
|
Rect item_rect(int index) const;
|
||||||
|
|
||||||
|
|
|
@ -107,8 +107,8 @@ void GTextBox::keydown_event(GKeyEvent& event)
|
||||||
case KeyCode::Key_Backspace:
|
case KeyCode::Key_Backspace:
|
||||||
return handle_backspace();
|
return handle_backspace();
|
||||||
case KeyCode::Key_Return:
|
case KeyCode::Key_Return:
|
||||||
if (onReturnPressed)
|
if (on_return_pressed)
|
||||||
onReturnPressed(*this);
|
on_return_pressed(*this);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ public:
|
||||||
String text() const { return m_text; }
|
String text() const { return m_text; }
|
||||||
void set_text(String&&);
|
void set_text(String&&);
|
||||||
|
|
||||||
Function<void(GTextBox&)> onReturnPressed;
|
Function<void(GTextBox&)> on_return_pressed;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual const char* class_name() const override { return "GTextBox"; }
|
virtual const char* class_name() const override { return "GTextBox"; }
|
||||||
|
@ -19,6 +19,7 @@ private:
|
||||||
virtual void mousedown_event(GMouseEvent&) override;
|
virtual void mousedown_event(GMouseEvent&) override;
|
||||||
virtual void keydown_event(GKeyEvent&) override;
|
virtual void keydown_event(GKeyEvent&) override;
|
||||||
virtual void timerEvent(GTimerEvent&) override;
|
virtual void timerEvent(GTimerEvent&) override;
|
||||||
|
virtual bool accepts_focus() const override { return true; }
|
||||||
|
|
||||||
void handle_backspace();
|
void handle_backspace();
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,9 @@ void GWidget::event(GEvent& event)
|
||||||
case GEvent::Paint:
|
case GEvent::Paint:
|
||||||
m_has_pending_paint_event = false;
|
m_has_pending_paint_event = false;
|
||||||
return paint_event(static_cast<GPaintEvent&>(event));
|
return paint_event(static_cast<GPaintEvent&>(event));
|
||||||
|
case GEvent::FocusIn:
|
||||||
|
case GEvent::FocusOut:
|
||||||
|
return focusin_event(event);
|
||||||
case GEvent::Show:
|
case GEvent::Show:
|
||||||
return show_event(static_cast<GShowEvent&>(event));
|
return show_event(static_cast<GShowEvent&>(event));
|
||||||
case GEvent::Hide:
|
case GEvent::Hide:
|
||||||
|
@ -49,7 +52,8 @@ void GWidget::event(GEvent& event)
|
||||||
case GEvent::MouseMove:
|
case GEvent::MouseMove:
|
||||||
return mousemove_event(static_cast<GMouseEvent&>(event));
|
return mousemove_event(static_cast<GMouseEvent&>(event));
|
||||||
case GEvent::MouseDown:
|
case GEvent::MouseDown:
|
||||||
// FIXME: Focus self if needed.
|
if (accepts_focus())
|
||||||
|
set_focus(true);
|
||||||
return mousedown_event(static_cast<GMouseEvent&>(event));
|
return mousedown_event(static_cast<GMouseEvent&>(event));
|
||||||
case GEvent::MouseUp:
|
case GEvent::MouseUp:
|
||||||
return mouseup_event(static_cast<GMouseEvent&>(event));
|
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()
|
void GWidget::update()
|
||||||
{
|
{
|
||||||
auto* w = window();
|
auto* w = window();
|
||||||
|
@ -130,15 +142,23 @@ void GWidget::set_window(GWindow* window)
|
||||||
|
|
||||||
bool GWidget::is_focused() const
|
bool GWidget::is_focused() const
|
||||||
{
|
{
|
||||||
// FIXME: Implement.
|
auto* win = window();
|
||||||
return false;
|
if (!win)
|
||||||
|
return false;
|
||||||
|
return win->focused_widget() == this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GWidget::set_focus(bool focus)
|
void GWidget::set_focus(bool focus)
|
||||||
{
|
{
|
||||||
if (focus == is_focused())
|
auto* win = window();
|
||||||
|
if (!win)
|
||||||
return;
|
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)
|
void GWidget::set_font(RetainPtr<Font>&& font)
|
||||||
|
|
|
@ -24,6 +24,8 @@ public:
|
||||||
virtual void mousemove_event(GMouseEvent&);
|
virtual void mousemove_event(GMouseEvent&);
|
||||||
virtual void mousedown_event(GMouseEvent&);
|
virtual void mousedown_event(GMouseEvent&);
|
||||||
virtual void mouseup_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; }
|
Rect relative_rect() const { return m_relative_rect; }
|
||||||
Point relative_position() const { return m_relative_rect.location(); }
|
Point relative_position() const { return m_relative_rect.location(); }
|
||||||
|
@ -39,6 +41,8 @@ public:
|
||||||
void update();
|
void update();
|
||||||
void repaint(const Rect&);
|
void repaint(const Rect&);
|
||||||
|
|
||||||
|
virtual bool accepts_focus() const { return false; }
|
||||||
|
|
||||||
bool is_focused() const;
|
bool is_focused() const;
|
||||||
void set_focus(bool);
|
void set_focus(bool);
|
||||||
|
|
||||||
|
|
|
@ -139,8 +139,13 @@ void GWindow::set_focused_widget(GWidget* widget)
|
||||||
{
|
{
|
||||||
if (m_focused_widget == widget)
|
if (m_focused_widget == widget)
|
||||||
return;
|
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->update();
|
||||||
|
}
|
||||||
m_focused_widget = widget;
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,10 @@ public:
|
||||||
GWidget* main_widget() { return m_main_widget; }
|
GWidget* main_widget() { return m_main_widget; }
|
||||||
const GWidget* main_widget() const { return m_main_widget; }
|
const GWidget* main_widget() const { return m_main_widget; }
|
||||||
void set_main_widget(GWidget*);
|
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 set_focused_widget(GWidget*);
|
||||||
|
|
||||||
void show();
|
void show();
|
||||||
|
|
|
@ -110,6 +110,12 @@ GWindow* make_launcher_window()
|
||||||
|
|
||||||
auto* textbox = new GTextBox(widget);
|
auto* textbox = new GTextBox(widget);
|
||||||
textbox->set_relative_rect({ 5, 110, 90, 20 });
|
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);
|
window->set_focused_widget(textbox);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue