mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 12:38:12 +00:00
LibGUI: More work on GInputBox.
- If the GInputBox has a parent and the parent is a GWindow, center the input box window within the parent window. This looks quite nice. - Stop processing events in a nested event loop immediately after it's been asked to quit. - Fix GWidget::parent_widget() behavior for non-widget parents.
This commit is contained in:
parent
a6538feed1
commit
f88e550998
9 changed files with 74 additions and 34 deletions
|
@ -50,7 +50,7 @@ void IRCAppWindow::setup_client()
|
||||||
void IRCAppWindow::setup_actions()
|
void IRCAppWindow::setup_actions()
|
||||||
{
|
{
|
||||||
m_join_action = GAction::create("Join channel", GraphicsBitmap::load_from_file(GraphicsBitmap::Format::RGBA32, "/res/icons/16x16/irc-join.rgb", { 16, 16 }), [&] (auto&) {
|
m_join_action = GAction::create("Join channel", GraphicsBitmap::load_from_file(GraphicsBitmap::Format::RGBA32, "/res/icons/16x16/irc-join.rgb", { 16, 16 }), [&] (auto&) {
|
||||||
GInputBox input_box("Enter nickname:", "Join channel");
|
GInputBox input_box("Enter nickname:", "Join channel", this);
|
||||||
if (input_box.exec() == GInputBox::ExecOK)
|
if (input_box.exec() == GInputBox::ExecOK)
|
||||||
m_client.handle_join_action(input_box.text_value());
|
m_client.handle_join_action(input_box.text_value());
|
||||||
});
|
});
|
||||||
|
@ -60,13 +60,13 @@ void IRCAppWindow::setup_actions()
|
||||||
});
|
});
|
||||||
|
|
||||||
m_whois_action = GAction::create("Whois user", GraphicsBitmap::load_from_file(GraphicsBitmap::Format::RGBA32, "/res/icons/16x16/irc-whois.rgb", { 16, 16 }), [&] (auto&) {
|
m_whois_action = GAction::create("Whois user", GraphicsBitmap::load_from_file(GraphicsBitmap::Format::RGBA32, "/res/icons/16x16/irc-whois.rgb", { 16, 16 }), [&] (auto&) {
|
||||||
GInputBox input_box("Enter nickname:", "IRC WHOIS lookup");
|
GInputBox input_box("Enter nickname:", "IRC WHOIS lookup", this);
|
||||||
if (input_box.exec() == GInputBox::ExecOK)
|
if (input_box.exec() == GInputBox::ExecOK)
|
||||||
m_client.handle_whois_action(input_box.text_value());
|
m_client.handle_whois_action(input_box.text_value());
|
||||||
});
|
});
|
||||||
|
|
||||||
m_open_query_action = GAction::create("Open query", GraphicsBitmap::load_from_file(GraphicsBitmap::Format::RGBA32, "/res/icons/16x16/irc-open-query.rgb", { 16, 16 }), [&] (auto&) {
|
m_open_query_action = GAction::create("Open query", GraphicsBitmap::load_from_file(GraphicsBitmap::Format::RGBA32, "/res/icons/16x16/irc-open-query.rgb", { 16, 16 }), [&] (auto&) {
|
||||||
GInputBox input_box("Enter nickname:", "Open IRC query with...");
|
GInputBox input_box("Enter nickname:", "Open IRC query with...", this);
|
||||||
if (input_box.exec() == GInputBox::ExecOK)
|
if (input_box.exec() == GInputBox::ExecOK)
|
||||||
m_client.handle_open_query_action(input_box.text_value());
|
m_client.handle_open_query_action(input_box.text_value());
|
||||||
});
|
});
|
||||||
|
|
|
@ -14,13 +14,25 @@ GDialog::~GDialog()
|
||||||
|
|
||||||
int GDialog::exec()
|
int GDialog::exec()
|
||||||
{
|
{
|
||||||
GEventLoop loop;
|
ASSERT(!m_event_loop);
|
||||||
|
m_event_loop = make<GEventLoop>();
|
||||||
|
if (parent() && parent()->is_window()) {
|
||||||
|
auto& parent_window = *static_cast<GWindow*>(parent());
|
||||||
|
auto new_rect = rect();
|
||||||
|
new_rect.center_within(parent_window.rect());
|
||||||
|
set_rect(new_rect);
|
||||||
|
}
|
||||||
show();
|
show();
|
||||||
return loop.exec();
|
auto result = m_event_loop->exec();
|
||||||
|
m_event_loop = nullptr;
|
||||||
|
dbgprintf("event loop returned with result %d\n", result);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GDialog::done(int result)
|
void GDialog::done(int result)
|
||||||
{
|
{
|
||||||
|
ASSERT(m_event_loop);
|
||||||
m_result = result;
|
m_result = result;
|
||||||
GEventLoop::current().quit(result);
|
dbgprintf("quit event loop with result %d\n", result);
|
||||||
|
m_event_loop->quit(result);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <LibGUI/GWindow.h>
|
#include <LibGUI/GWindow.h>
|
||||||
|
#include <LibGUI/GEventLoop.h>
|
||||||
|
|
||||||
class GDialog : public GWindow {
|
class GDialog : public GWindow {
|
||||||
public:
|
public:
|
||||||
|
enum ExecResult { ExecOK = 0, ExecCancel = 1, ExecAborted = 2 };
|
||||||
|
|
||||||
virtual ~GDialog() override;
|
virtual ~GDialog() override;
|
||||||
|
|
||||||
int exec();
|
int exec();
|
||||||
|
@ -15,5 +18,6 @@ protected:
|
||||||
explicit GDialog(GObject* parent);
|
explicit GDialog(GObject* parent);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int m_result { 0 };
|
OwnPtr<GEventLoop> m_event_loop;
|
||||||
|
int m_result { ExecAborted };
|
||||||
};
|
};
|
||||||
|
|
|
@ -158,6 +158,13 @@ int GEventLoop::exec()
|
||||||
} else {
|
} else {
|
||||||
receiver->event(event);
|
receiver->event(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_exit_requested) {
|
||||||
|
auto rejigged_event_queue = move(events);
|
||||||
|
rejigged_event_queue.append(move(m_queued_events));
|
||||||
|
m_queued_events = move(rejigged_event_queue);
|
||||||
|
return m_exit_code;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
|
|
|
@ -36,9 +36,9 @@ void GInputBox::build()
|
||||||
label->set_size_policy(SizePolicy::Fixed, SizePolicy::Fixed);
|
label->set_size_policy(SizePolicy::Fixed, SizePolicy::Fixed);
|
||||||
label->set_preferred_size({ text_width, 16 });
|
label->set_preferred_size({ text_width, 16 });
|
||||||
|
|
||||||
auto* text_editor = new GTextEditor(GTextEditor::SingleLine, widget);
|
m_text_editor = new GTextEditor(GTextEditor::SingleLine, widget);
|
||||||
text_editor->set_size_policy(SizePolicy::Fill, SizePolicy::Fixed);
|
m_text_editor->set_size_policy(SizePolicy::Fill, SizePolicy::Fixed);
|
||||||
text_editor->set_preferred_size({ 0, 16 });
|
m_text_editor->set_preferred_size({ 0, 16 });
|
||||||
|
|
||||||
auto* button_container_outer = new GWidget(widget);
|
auto* button_container_outer = new GWidget(widget);
|
||||||
button_container_outer->set_layout(make<GBoxLayout>(Orientation::Vertical));
|
button_container_outer->set_layout(make<GBoxLayout>(Orientation::Vertical));
|
||||||
|
@ -47,30 +47,30 @@ void GInputBox::build()
|
||||||
button_container_inner->set_layout(make<GBoxLayout>(Orientation::Horizontal));
|
button_container_inner->set_layout(make<GBoxLayout>(Orientation::Horizontal));
|
||||||
button_container_inner->layout()->set_spacing(8);
|
button_container_inner->layout()->set_spacing(8);
|
||||||
|
|
||||||
auto* cancel_button = new GButton(button_container_inner);
|
m_cancel_button = new GButton(button_container_inner);
|
||||||
cancel_button->set_size_policy(SizePolicy::Fill, SizePolicy::Fixed);
|
m_cancel_button->set_size_policy(SizePolicy::Fill, SizePolicy::Fixed);
|
||||||
cancel_button->set_preferred_size({ 0, 16 });
|
m_cancel_button->set_preferred_size({ 0, 16 });
|
||||||
cancel_button->set_caption("Cancel");
|
m_cancel_button->set_caption("Cancel");
|
||||||
cancel_button->on_click = [&] (auto&) {
|
m_cancel_button->on_click = [this] (auto&) {
|
||||||
fprintf(stderr, "GInputBox: Cancel button clicked\n");
|
dbgprintf("GInputBox: Cancel button clicked\n");
|
||||||
done(1);
|
done(ExecCancel);
|
||||||
};
|
};
|
||||||
|
|
||||||
auto* ok_button = new GButton(button_container_inner);
|
m_ok_button = new GButton(button_container_inner);
|
||||||
ok_button->set_size_policy(SizePolicy::Fill, SizePolicy::Fixed);
|
m_ok_button->set_size_policy(SizePolicy::Fill, SizePolicy::Fixed);
|
||||||
ok_button->set_preferred_size({ 0, 16 });
|
m_ok_button->set_preferred_size({ 0, 16 });
|
||||||
ok_button->set_caption("OK");
|
m_ok_button->set_caption("OK");
|
||||||
ok_button->on_click = [&] (auto&) {
|
m_ok_button->on_click = [this] (auto&) {
|
||||||
fprintf(stderr, "GInputBox: OK button clicked\n");
|
dbgprintf("GInputBox: OK button clicked\n");
|
||||||
m_text_value = text_editor->text();
|
m_text_value = m_text_editor->text();
|
||||||
done(0);
|
done(ExecOK);
|
||||||
};
|
};
|
||||||
|
|
||||||
text_editor->on_return_pressed = [&] (auto&) {
|
m_text_editor->on_return_pressed = [this] (auto&) {
|
||||||
ok_button->click();
|
m_ok_button->click();
|
||||||
};
|
};
|
||||||
text_editor->on_escape_pressed = [&] (auto&) {
|
m_text_editor->on_escape_pressed = [this] (auto&) {
|
||||||
cancel_button->click();
|
m_cancel_button->click();
|
||||||
};
|
};
|
||||||
text_editor->set_focus(true);
|
m_text_editor->set_focus(true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,10 +2,11 @@
|
||||||
|
|
||||||
#include <LibGUI/GDialog.h>
|
#include <LibGUI/GDialog.h>
|
||||||
|
|
||||||
|
class GButton;
|
||||||
|
class GTextEditor;
|
||||||
|
|
||||||
class GInputBox : public GDialog {
|
class GInputBox : public GDialog {
|
||||||
public:
|
public:
|
||||||
enum ExecResult { ExecOK = 0, ExecCancel = 1 };
|
|
||||||
|
|
||||||
explicit GInputBox(const String& prompt, const String& title, GObject* parent = nullptr);
|
explicit GInputBox(const String& prompt, const String& title, GObject* parent = nullptr);
|
||||||
virtual ~GInputBox() override;
|
virtual ~GInputBox() override;
|
||||||
|
|
||||||
|
@ -15,4 +16,8 @@ private:
|
||||||
void build();
|
void build();
|
||||||
String m_prompt;
|
String m_prompt;
|
||||||
String m_text_value;
|
String m_text_value;
|
||||||
|
|
||||||
|
GButton* m_ok_button { nullptr };
|
||||||
|
GButton* m_cancel_button { nullptr };
|
||||||
|
GTextEditor* m_text_editor { nullptr };
|
||||||
};
|
};
|
||||||
|
|
|
@ -33,6 +33,7 @@ public:
|
||||||
void dump_tree(int indent = 0);
|
void dump_tree(int indent = 0);
|
||||||
|
|
||||||
virtual bool is_widget() const { return false; }
|
virtual bool is_widget() const { return false; }
|
||||||
|
virtual bool is_window() const { return false; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void timer_event(GTimerEvent&);
|
virtual void timer_event(GTimerEvent&);
|
||||||
|
|
|
@ -109,8 +109,18 @@ public:
|
||||||
|
|
||||||
void set_window(GWindow*);
|
void set_window(GWindow*);
|
||||||
|
|
||||||
GWidget* parent_widget() { return static_cast<GWidget*>(parent()); }
|
GWidget* parent_widget()
|
||||||
const GWidget* parent_widget() const { return static_cast<const GWidget*>(parent()); }
|
{
|
||||||
|
if (parent() && parent()->is_widget())
|
||||||
|
return static_cast<GWidget*>(parent());
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
const GWidget* parent_widget() const
|
||||||
|
{
|
||||||
|
if (parent() && parent()->is_widget())
|
||||||
|
return static_cast<const GWidget*>(parent());
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
void set_fill_with_background_color(bool b) { m_fill_with_background_color = b; }
|
void set_fill_with_background_color(bool b) { m_fill_with_background_color = b; }
|
||||||
bool fill_with_background_color() const { return m_fill_with_background_color; }
|
bool fill_with_background_color() const { return m_fill_with_background_color; }
|
||||||
|
|
|
@ -82,6 +82,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual const char* class_name() const override { return "GWindow"; }
|
virtual const char* class_name() const override { return "GWindow"; }
|
||||||
|
virtual bool is_window() const override final { return true; }
|
||||||
|
|
||||||
Retained<GraphicsBitmap> create_backing_bitmap(const Size&);
|
Retained<GraphicsBitmap> create_backing_bitmap(const Size&);
|
||||||
void set_current_backing_bitmap(GraphicsBitmap&, bool flush_immediately = false);
|
void set_current_backing_bitmap(GraphicsBitmap&, bool flush_immediately = false);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue