class IGuiWrapper
{
public:
typedef std::vector<IGuiWrapper*> WrapperVector;
typedef size_t guiElementId;
virtual ~IGuiWrapper() {}
guiEnum::guiElementType GetElementType() const { return mElementType; }
guiElementId GetId() const { return mId; }
virtual void AddToDesktop() const = 0;
static IGuiWrapper* GetWrapper(guiElementId id);
protected:
explicit IGuiWrapper(guiEnum::guiElementType elType);
guiEnum::guiElementType mElementType;
guiElementId mId;
std::string mLuaCallbacks[guiEnum::signalNum];
static WrapperVector sWrappers;
static sfg::Signal::SignalID* sSignals[guiEnum::signalNum];
};
//////////////////////////////////////////////////////////////////////////
template<class T, guiEnum::guiElementType el>
class GuiWrapper: public IGuiWrapper
{
typedef GuiWrapper<T, el> ThisClassType;
typedef void (ThisClassType::*SignalCallback)();
SignalCallback mSignalCallbacks[guiEnum::signalNum];
public:
typedef sfg::SharedPtr<T> guiPtr;
GuiWrapper():
IGuiWrapper(el),
mObject(T::Create())
{
#define STORE_CALLBACK(Name) mSignalCallbacks[guiEnum::signal##Name] = &ThisClassType::Name;
STORE_CALLBACK(OnStateChange);
STORE_CALLBACK(OnGainFocus);
STORE_CALLBACK(OnLostFocus);
STORE_CALLBACK(OnExpose);
STORE_CALLBACK(OnSizeAllocate);
STORE_CALLBACK(OnSizeRequest);
STORE_CALLBACK(OnMouseEnter);
STORE_CALLBACK(OnMouseLeave);
STORE_CALLBACK(OnMouseMove);
STORE_CALLBACK(OnMouseLeftPress);
STORE_CALLBACK(OnMouseRightPress);
STORE_CALLBACK(OnMouseLeftRelease);
STORE_CALLBACK(OnMouseRightRelease);
STORE_CALLBACK(OnLeftClick);
STORE_CALLBACK(OnRightClick);
STORE_CALLBACK(OnKeyPress);
STORE_CALLBACK(OnKeyRelease);
STORE_CALLBACK(OnText);
#undef STORE_CALLBACK
}
virtual ~GuiWrapper()
{}
virtual void AddToDesktop() const override
{
auto evt = new SFGuiEvent(SFGuiEvent::addToDesktop, mObject);
EventManager::Instance().QueueEvent(evt);
}
guiPtr GetPtr() const { return mObject; }
void Add(IGuiWrapper* wrp)
{
assert(wrp);
typedef GuiWrapper<sfg::Widget, guiEnum::guiNum> Wrapper;
Wrapper* wrapper = static_cast<Wrapper*>(wrp);
mObject->Add( wrapper->GetPtr() );
}
virtual void SetLabel(const char* ) {}
virtual void EnableSignal(int signal, const char* luaFunction) //override
{
mLuaCallbacks[signal] = luaFunction;
mObject->GetSignal(*sSignals[signal]).Connect<ThisClassType>( mSignalCallbacks[signal], this );
}
protected:
virtual void RunCallback(guiEnum::guiSignal signal)
{
Core::Lua().call(mLuaCallbacks[signal], mId);
}
// here will be pretty macro =)
virtual void OnStateChange() {};
virtual void OnGainFocus() {};
virtual void OnLostFocus() {};
virtual void OnExpose() {};
virtual void OnSizeAllocate() {};
virtual void OnSizeRequest() {};
virtual void OnMouseEnter() {};
virtual void OnMouseLeave() {};
virtual void OnMouseMove() {};
virtual void OnMouseLeftPress() {};
virtual void OnMouseRightPress() {};
virtual void OnMouseLeftRelease() {};
virtual void OnMouseRightRelease() {};
virtual void OnLeftClick() { RunCallback(guiEnum::signalOnLeftClick); }
virtual void OnRightClick() {};
virtual void OnKeyPress() {};
virtual void OnKeyRelease() {};
virtual void OnText() {};
guiPtr mObject;
};
/// guiWindowWrapper
class guiWindowWrapper: public GuiWrapper<sfg::Window, guiEnum::guiWindow>
{
public:
guiWindowWrapper();
virtual void SetLabel(const char* txt) override;
};
/// guiButtonWrapper
class guiButtonWrapper: public GuiWrapper<sfg::Button, guiEnum::guiButton>
{
public:
guiButtonWrapper();
virtual void SetLabel(const char* txt) override;
virtual void RunCallback(guiEnum::guiSignal signal) override;
};
function ButtonClicked(btn)
print ("BUTTON CLICKED, id:", btn:GetId())
end
btn = guiButtonWrapper.new()
btn:EnableSignal(guiEnum.signalOnLeftClick, 'ButtonClicked')
btn:SetLabel("Button label")
wnd = guiWindowWrapper.new()
wnd:SetLabel("Window title")
wnd:Add(btn)
AddGuiToDesktop(wnd)