diff options
author | Andreas Kling <awesomekling@gmail.com> | 2019-11-10 10:58:03 +0100 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-11-10 12:57:37 +0100 |
commit | ca538b6ceeb48d6570918a311d7a1ca1137b96f7 (patch) | |
tree | 42ce20efc5a4e6b2b3f0ca238e5a7551e374b348 /Libraries/LibGUI/GWidget.cpp | |
parent | a353d16ff493ee46dc6cf57a448f44e959781609 (diff) | |
download | serenity-ca538b6ceeb48d6570918a311d7a1ca1137b96f7.zip |
LibGUI: Add a simple GWidget class registry/factory
You can now register a GWidget subclass with REGISTER_GWIDGET(class)
and it will be available for factory construction through the new
GWidgetClassRegistration interface.
To obtain a GWidgetClassRegistration for a given class name, you call
GWidgetClassRegistration::find(class_name). You can also iterate over
all the registered classes using GWCR::for_each(callback).
This will be very useful for implementing a proper GUI designer, and
also in the future for things like script bindings.
NOTE: All of the registrations are done in GWidget.cpp at the moment
since I ran into trouble with the fricken linker pruning the global
constructors this mechanism relies on. :^)
Diffstat (limited to 'Libraries/LibGUI/GWidget.cpp')
-rw-r--r-- | Libraries/LibGUI/GWidget.cpp | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/Libraries/LibGUI/GWidget.cpp b/Libraries/LibGUI/GWidget.cpp index 4e7eff78df..7ea80e4c79 100644 --- a/Libraries/LibGUI/GWidget.cpp +++ b/Libraries/LibGUI/GWidget.cpp @@ -12,6 +12,59 @@ #include <LibGUI/GWindowServerConnection.h> #include <unistd.h> +#include <LibGUI/GButton.h> +#include <LibGUI/GCheckBox.h> +#include <LibGUI/GGroupBox.h> +#include <LibGUI/GLabel.h> +#include <LibGUI/GRadioButton.h> +#include <LibGUI/GScrollBar.h> +#include <LibGUI/GSlider.h> +#include <LibGUI/GSpinBox.h> +#include <LibGUI/GTextBox.h> + +REGISTER_GWIDGET(GButton) +REGISTER_GWIDGET(GCheckBox) +REGISTER_GWIDGET(GGroupBox) +REGISTER_GWIDGET(GLabel) +REGISTER_GWIDGET(GRadioButton) +REGISTER_GWIDGET(GScrollBar) +REGISTER_GWIDGET(GSlider) +REGISTER_GWIDGET(GSpinBox) +REGISTER_GWIDGET(GTextBox) +REGISTER_GWIDGET(GWidget) + +static HashMap<String, GWidgetClassRegistration*>& widget_classes() +{ + static HashMap<String, GWidgetClassRegistration*>* map; + if (!map) + map = new HashMap<String, GWidgetClassRegistration*>; + return *map; +} + +GWidgetClassRegistration::GWidgetClassRegistration(const String& class_name, Function<NonnullRefPtr<GWidget>(GWidget*)> factory) + : m_class_name(class_name) + , m_factory(move(factory)) +{ + widget_classes().set(class_name, this); +} + +GWidgetClassRegistration::~GWidgetClassRegistration() +{ + ASSERT_NOT_REACHED(); +} + +void GWidgetClassRegistration::for_each(Function<void(const GWidgetClassRegistration&)> callback) +{ + for (auto& it : widget_classes()) { + callback(*it.value); + } +} + +const GWidgetClassRegistration* GWidgetClassRegistration::find(const String& class_name) +{ + return widget_classes().get(class_name).value_or(nullptr); +} + GWidget::GWidget(GWidget* parent) : CObject(parent, true) , m_font(Font::default_font()) |