LibGUI: Make sure that children are actually widgets

Previously this section of code would blindly add *anything* as a child
as long as it has been registered as an object. Since there is no
guarentee that those objects are, in fact, Widgets, this feels like a
logical fallacy.

For example, up until this change, this is perfectly valid GML:

```
@GUI::Widget {
    layout: @GUI::VerticalBoxLayout {
    }

    @GUI::VerticalBoxLayout {
    }
}
```

What exactly does it do? Who knows! It doesn't seem to *break*, but I
think we can all agree it shouldn't be valid.

Instead, we now actually verify that the registered class inherets from
GUI::Widget before adding it as a child. We also error if it's not,
which should hopefully help new GML writers from forgetting to write
'layout: ' before the layout definition and being confused as to why
it's not working.
This commit is contained in:
thislooksfun 2021-10-26 22:14:58 -05:00 committed by Andreas Kling
parent eb3ca64819
commit 4143f6f906

View file

@ -1108,6 +1108,7 @@ bool Widget::load_from_json(const JsonObject& json, RefPtr<Core::Object> (*unreg
});
}
auto& widget_class = *Core::ObjectClassRegistration::find("GUI::Widget");
auto children = json.get("children");
if (children.is_array()) {
for (auto& child_json_value : children.as_array().values()) {
@ -1123,6 +1124,10 @@ bool Widget::load_from_json(const JsonObject& json, RefPtr<Core::Object> (*unreg
RefPtr<Core::Object> child;
if (auto* registration = Core::ObjectClassRegistration::find(class_name.as_string())) {
child = registration->construct();
if (!child || !registration->is_derived_from(widget_class)) {
dbgln("Invalid widget class: '{}'", class_name.to_string());
return false;
}
} else {
child = unregistered_child_handler(class_name.as_string());
}