#ifndef UI_BUILDER_H
#define UI_BUILDER_H
#include <string>
#include <vector>
#include <map>
#include "Utils.h"
#include "Variant.h"
#include "Property.h"
#include "XmlParser.h"
#include "Namespace.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;
};
class UiBuilder : public XmlConsumer
{
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
#endif // UI_BUILDER_H