mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-25 17:10:23 +00:00
57ff293a51
This patch adds a simple GMessageBox that can run in a nested event loop. Here's how you use it: GMessageBox box("Message text here", "Message window title"); int result = box.exec(); The next step is to make the WindowServer respect the modality flag of these windows and prevent interaction with other windows in the same process until the modal window has been closed.
103 lines
2.2 KiB
C++
103 lines
2.2 KiB
C++
#include "GObject.h"
|
|
#include "GEvent.h"
|
|
#include "GEventLoop.h"
|
|
#include <AK/Assertions.h>
|
|
#include <stdio.h>
|
|
|
|
GObject::GObject(GObject* parent)
|
|
: m_parent(parent)
|
|
{
|
|
if (m_parent)
|
|
m_parent->add_child(*this);
|
|
}
|
|
|
|
GObject::~GObject()
|
|
{
|
|
stop_timer();
|
|
if (m_parent)
|
|
m_parent->remove_child(*this);
|
|
auto children_to_delete = move(m_children);
|
|
for (auto* child : children_to_delete)
|
|
delete child;
|
|
}
|
|
|
|
void GObject::event(GEvent& event)
|
|
{
|
|
switch (event.type()) {
|
|
case GEvent::Timer:
|
|
return timer_event(static_cast<GTimerEvent&>(event));
|
|
case GEvent::DeferredDestroy:
|
|
delete this;
|
|
break;
|
|
case GEvent::ChildAdded:
|
|
case GEvent::ChildRemoved:
|
|
return child_event(static_cast<GChildEvent&>(event));
|
|
case GEvent::Invalid:
|
|
ASSERT_NOT_REACHED();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void GObject::add_child(GObject& object)
|
|
{
|
|
m_children.append(&object);
|
|
GEventLoop::current().post_event(*this, make<GChildEvent>(GEvent::ChildAdded, object));
|
|
}
|
|
|
|
void GObject::remove_child(GObject& object)
|
|
{
|
|
for (ssize_t i = 0; i < m_children.size(); ++i) {
|
|
if (m_children[i] == &object) {
|
|
m_children.remove(i);
|
|
GEventLoop::current().post_event(*this, make<GChildEvent>(GEvent::ChildRemoved, object));
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
void GObject::timer_event(GTimerEvent&)
|
|
{
|
|
}
|
|
|
|
void GObject::child_event(GChildEvent&)
|
|
{
|
|
}
|
|
|
|
void GObject::start_timer(int ms)
|
|
{
|
|
if (m_timer_id) {
|
|
dbgprintf("GObject{%p} already has a timer!\n", this);
|
|
ASSERT_NOT_REACHED();
|
|
}
|
|
|
|
m_timer_id = GEventLoop::register_timer(*this, ms, true);
|
|
}
|
|
|
|
void GObject::stop_timer()
|
|
{
|
|
if (!m_timer_id)
|
|
return;
|
|
bool success = GEventLoop::unregister_timer(m_timer_id);
|
|
ASSERT(success);
|
|
m_timer_id = 0;
|
|
}
|
|
|
|
void GObject::delete_later()
|
|
{
|
|
GEventLoop::current().post_event(*this, make<GEvent>(GEvent::DeferredDestroy));
|
|
}
|
|
|
|
void GObject::dump_tree(int indent)
|
|
{
|
|
for (int i = 0; i < indent; ++i) {
|
|
printf(" ");
|
|
}
|
|
printf("%s{%p}\n", class_name(), this);
|
|
|
|
for (auto* child : children()) {
|
|
child->dump_tree(indent + 2);
|
|
}
|
|
|
|
}
|