#pragma once
#include "Variant.h"
#include "Property.h"
#include "XmlParser.h"
#include "Common.h"
BEGIN_NAMESPACE
class Widget;
enum WidgetType
{
WT_VBox,
WT_HBox,
WT_Label,
WT_RadioButton,
WT_CheckBox,
WT_Button,
WT_Slider,
WT_ComboBox,
WT_GroupBox,
WT_LineEdit,
WT_VSpace,
WT_HSpace,
WT_ProgressBar,
WT_Item,
WT_Unknown
};
struct TypedWidget
{
WidgetType m_type;
Widget* m_widget;
};
template <typename T>
T* widget_cast(TypedWidget* w)
{
if (w->m_type == T::Type)
return w->m_widget;
return nullptr;
}
class UiBuilder : public XmlConsumerInterface
{
public:
UiBuilder(Widget* a_parent);
~UiBuilder();
void registerProperty(const char* a_name, AbstractProperty<bool>& a_property) {
addGenericProperty(a_name, VT_boolean_t, (AbstractProperty<int>*)&a_property);
}
void registerProperty(const char* a_name, AbstractProperty<int>& a_property) {
addGenericProperty(a_name, VT_int32_t, (AbstractProperty<int>*)&a_property);
}
void registerProperty(const char* a_name, AbstractProperty<String>& a_property) {
addGenericProperty(a_name, VT_String, (AbstractProperty<int>*)&a_property);
}
// ... add more as appropriate
// TODO: This is a bad interface as it means the caller knows what the type will be
// but could be easily changed by changing the XML. Really need a type safe way of
// doing this. Perhaps if tries to cast it, and does RTTI checks and if it can't cast
// it, then does something, but what. Problem with loading XML is that it happens at
// runtime so can't do compile time checks, they need to be dynamic which becomes
// a bit more work for the programmer to make it correct. Might be better if can
// avoid the need for this API at all.
//template <typename T>
//T* find(const char* a_name) { return (T*)findWidget(a_name); }
// This returns a widget pointer and it's type. The caller can cast the widget to
// a specific widget sub-class if they first check the type return is as expected.
TypedWidget findWidget(const char* a_name);
protected:
void consumeToken(XmlTokenType a_type, const XmlStringSlice& a_text);
void addGenericProperty(const char* a_name, VariantType a_type, AbstractProperty<int>* a_property);
private:
class UiBuilderData* m_data;
};
END_NAMESPACE