Skip to content

Commit

Permalink
LibCore+LibGUI: Add is<T>(CObject&) and to<T>(CObject&) helpers.
Browse files Browse the repository at this point in the history
  • Loading branch information
awesomekling committed May 27, 2019
1 parent 723ba91 commit 0c85d3d
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 30 deletions.
17 changes: 17 additions & 0 deletions LibCore/CObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,20 @@ class CObject : public Weakable<CObject> {
bool m_widget { false };
Vector<CObject*> m_children;
};

template<typename T> inline bool is(const CObject&) { return false; }
template<> inline bool is<CObject>(const CObject&) { return true; }

template<typename T>
inline T& to(CObject& object)
{
ASSERT(is<T>(object));
return static_cast<T&>(object);
}

template<typename T>
inline const T& to(const CObject& object)
{
ASSERT(is<T>(object));
return static_cast<const T&>(object);
}
14 changes: 6 additions & 8 deletions LibGUI/GStackWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ void GStackWidget::resize_event(GResizeEvent& event)

void GStackWidget::child_event(CChildEvent& event)
{
if (!event.child() || !event.child()->is_widget())
if (!event.child() || !is<GWidget>(*event.child()))
return GWidget::child_event(event);
auto& child = static_cast<GWidget&>(*event.child());
auto& child = to<GWidget>(*event.child());
if (event.type() == GEvent::ChildAdded) {
if (!m_active_widget)
set_active_widget(&child);
Expand All @@ -44,12 +44,10 @@ void GStackWidget::child_event(CChildEvent& event)
} else if (event.type() == GEvent::ChildRemoved) {
if (m_active_widget == &child) {
GWidget* new_active_widget = nullptr;
for (auto* new_child : children()) {
if (new_child->is_widget()) {
new_active_widget = static_cast<GWidget*>(new_child);
break;
}
}
for_each_child_widget([&] (auto& new_child) {
new_active_widget = &new_child;
return IterationDecision::Abort;
});
set_active_widget(new_active_widget);
}
}
Expand Down
4 changes: 2 additions & 2 deletions LibGUI/GTabWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ Rect GTabWidget::child_rect_for_size(const Size& size) const

void GTabWidget::child_event(CChildEvent& event)
{
if (!event.child() || !event.child()->is_widget())
if (!event.child() || !is<GWidget>(*event.child()))
return GWidget::child_event(event);
auto& child = static_cast<GWidget&>(*event.child());
auto& child = to<GWidget>(*event.child());
if (event.type() == GEvent::ChildAdded) {
if (!m_active_widget)
set_active_widget(&child);
Expand Down
12 changes: 6 additions & 6 deletions LibGUI/GWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@ GWidget::~GWidget()
void GWidget::child_event(CChildEvent& event)
{
if (event.type() == GEvent::ChildAdded) {
if (event.child() && event.child()->is_widget() && layout())
layout()->add_widget(static_cast<GWidget&>(*event.child()));
if (event.child() && is<GWidget>(*event.child()) && layout())
layout()->add_widget(to<GWidget>(*event.child()));
}
if (event.type() == GEvent::ChildRemoved) {
if (layout()) {
if (event.child() && event.child()->is_widget())
layout()->remove_widget(static_cast<GWidget&>(*event.child()));
if (event.child() && is<GWidget>(*event.child()))
layout()->remove_widget(to<GWidget>(*event.child()));
else
invalidate_layout();
}
Expand Down Expand Up @@ -321,9 +321,9 @@ Rect GWidget::screen_relative_rect() const
GWidget* GWidget::child_at(const Point& point) const
{
for (int i = children().size() - 1; i >= 0; --i) {
if (!children()[i]->is_widget())
if (!is<GWidget>(*children()[i]))
continue;
auto& child = *(GWidget*)children()[i];
auto& child = to<GWidget>(*children()[i]);
if (!child.is_visible())
continue;
if (child.relative_rect().contains(point))
Expand Down
36 changes: 22 additions & 14 deletions LibGUI/GWidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,18 +141,8 @@ class GWidget : public CObject {

void set_window(GWindow*);

GWidget* parent_widget()
{
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;
}
GWidget* parent_widget();
const GWidget* parent_widget() const;

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; }
Expand Down Expand Up @@ -189,8 +179,8 @@ class GWidget : public CObject {
void for_each_child_widget(Callback callback)
{
for_each_child([&] (auto& child) {
if (child.is_widget())
return callback(static_cast<GWidget&>(child));
if (is<GWidget>(child))
return callback(to<GWidget>(child));
return IterationDecision::Continue;
});
}
Expand Down Expand Up @@ -233,3 +223,21 @@ class GWidget : public CObject {

HashMap<GShortcut, GAction*> m_local_shortcut_actions;
};

template<> inline bool is<GWidget>(const CObject& object)
{
return object.is_widget();
}

inline GWidget* GWidget::parent_widget()
{
if (parent() && is<GWidget>(*parent()))
return &to<GWidget>(*parent());
return nullptr;
}
inline const GWidget* GWidget::parent_widget() const
{
if (parent() && is<GWidget>(*parent()))
return &to<const GWidget>(*parent());
return nullptr;
}

0 comments on commit 0c85d3d

Please sign in to comment.