mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 01:37:34 +00:00
LibCore+LibGUI: Make CObject child events synchronous.
...and then make GWidget layout invalidation lazy. This way we coalesce multiple invalidations into a single relayout and we don't have to worry about child widgets not being fully constructed.
This commit is contained in:
parent
0e6b273620
commit
9e6b0ccc0e
4 changed files with 22 additions and 13 deletions
|
@ -4,8 +4,9 @@
|
||||||
#include <AK/Assertions.h>
|
#include <AK/Assertions.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
CObject::CObject(CObject* parent)
|
CObject::CObject(CObject* parent, bool is_widget)
|
||||||
: m_parent(parent)
|
: m_parent(parent)
|
||||||
|
, m_widget(is_widget)
|
||||||
{
|
{
|
||||||
if (m_parent)
|
if (m_parent)
|
||||||
m_parent->add_child(*this);
|
m_parent->add_child(*this);
|
||||||
|
@ -43,7 +44,7 @@ void CObject::event(CEvent& event)
|
||||||
void CObject::add_child(CObject& object)
|
void CObject::add_child(CObject& object)
|
||||||
{
|
{
|
||||||
m_children.append(&object);
|
m_children.append(&object);
|
||||||
CEventLoop::current().post_event(*this, make<CChildEvent>(CEvent::ChildAdded, object));
|
event(*make<CChildEvent>(CEvent::ChildAdded, object));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CObject::remove_child(CObject& object)
|
void CObject::remove_child(CObject& object)
|
||||||
|
@ -51,7 +52,7 @@ void CObject::remove_child(CObject& object)
|
||||||
for (ssize_t i = 0; i < m_children.size(); ++i) {
|
for (ssize_t i = 0; i < m_children.size(); ++i) {
|
||||||
if (m_children[i] == &object) {
|
if (m_children[i] == &object) {
|
||||||
m_children.remove(i);
|
m_children.remove(i);
|
||||||
CEventLoop::current().post_event(*this, make<CChildEvent>(CEvent::ChildRemoved, object));
|
event(*make<CChildEvent>(CEvent::ChildRemoved, object));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ class CTimerEvent;
|
||||||
|
|
||||||
class CObject : public Weakable<CObject> {
|
class CObject : public Weakable<CObject> {
|
||||||
public:
|
public:
|
||||||
CObject(CObject* parent = nullptr);
|
CObject(CObject* parent = nullptr, bool is_widget = false);
|
||||||
virtual ~CObject();
|
virtual ~CObject();
|
||||||
|
|
||||||
virtual const char* class_name() const { return "CObject"; }
|
virtual const char* class_name() const { return "CObject"; }
|
||||||
|
@ -36,7 +36,7 @@ public:
|
||||||
|
|
||||||
void deferred_invoke(Function<void(CObject&)>);
|
void deferred_invoke(Function<void(CObject&)>);
|
||||||
|
|
||||||
virtual bool is_widget() const { return false; }
|
bool is_widget() const { return m_widget; }
|
||||||
virtual bool is_window() const { return false; }
|
virtual bool is_window() const { return false; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -46,5 +46,6 @@ protected:
|
||||||
private:
|
private:
|
||||||
CObject* m_parent { nullptr };
|
CObject* m_parent { nullptr };
|
||||||
int m_timer_id { 0 };
|
int m_timer_id { 0 };
|
||||||
|
bool m_widget { false };
|
||||||
Vector<CObject*> m_children;
|
Vector<CObject*> m_children;
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
GWidget::GWidget(GWidget* parent)
|
GWidget::GWidget(GWidget* parent)
|
||||||
: CObject(parent)
|
: CObject(parent, true)
|
||||||
{
|
{
|
||||||
set_font(nullptr);
|
set_font(nullptr);
|
||||||
m_background_color = Color::LightGray;
|
m_background_color = Color::LightGray;
|
||||||
|
@ -143,7 +143,7 @@ void GWidget::do_layout()
|
||||||
|
|
||||||
void GWidget::notify_layout_changed(Badge<GLayout>)
|
void GWidget::notify_layout_changed(Badge<GLayout>)
|
||||||
{
|
{
|
||||||
do_layout();
|
invalidate_layout();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GWidget::handle_resize_event(GResizeEvent& event)
|
void GWidget::handle_resize_event(GResizeEvent& event)
|
||||||
|
@ -395,13 +395,19 @@ void GWidget::set_size_policy(SizePolicy horizontal_policy, SizePolicy vertical_
|
||||||
|
|
||||||
void GWidget::invalidate_layout()
|
void GWidget::invalidate_layout()
|
||||||
{
|
{
|
||||||
auto* w = window();
|
if (m_layout_dirty)
|
||||||
if (!w)
|
|
||||||
return;
|
return;
|
||||||
if (!w->main_widget())
|
m_layout_dirty = true;
|
||||||
return;
|
deferred_invoke([this] (auto&) {
|
||||||
do_layout();
|
m_layout_dirty = false;
|
||||||
w->main_widget()->do_layout();
|
auto* w = window();
|
||||||
|
if (!w)
|
||||||
|
return;
|
||||||
|
if (!w->main_widget())
|
||||||
|
return;
|
||||||
|
do_layout();
|
||||||
|
w->main_widget()->do_layout();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void GWidget::set_visible(bool visible)
|
void GWidget::set_visible(bool visible)
|
||||||
|
|
|
@ -200,6 +200,7 @@ private:
|
||||||
bool m_visible { true };
|
bool m_visible { true };
|
||||||
bool m_greedy_for_hits { false };
|
bool m_greedy_for_hits { false };
|
||||||
bool m_enabled { true };
|
bool m_enabled { true };
|
||||||
|
bool m_layout_dirty { false };
|
||||||
|
|
||||||
CElapsedTimer m_click_clock;
|
CElapsedTimer m_click_clock;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue