summaryrefslogtreecommitdiff
path: root/Libraries/LibGUI/GWidget.cpp
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-11-10 10:58:03 +0100
committerAndreas Kling <awesomekling@gmail.com>2019-11-10 12:57:37 +0100
commitca538b6ceeb48d6570918a311d7a1ca1137b96f7 (patch)
tree42ce20efc5a4e6b2b3f0ca238e5a7551e374b348 /Libraries/LibGUI/GWidget.cpp
parenta353d16ff493ee46dc6cf57a448f44e959781609 (diff)
downloadserenity-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.cpp53
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())