Big work. As you know, i'm still using OOLua for Lua bindings. But i refused wrappers, and using now OOLua with support of std::shared_ptr, it became much easier. For example:
This is controls that are required and used now. If i need new control, i'm just adding it to the end.
namespace OOLUA
{
typedef sfg::Signal sfgSignal;
typedef sfg::Misc sfgMisc;
typedef sfg::Object sfgObject;
typedef sfg::Widget sfgWidget;
typedef sfg::Bin sfgBin;
typedef sfg::Container sfgContainer;
typedef sfg::Fixed sfgFixed;
typedef sfg::Alignment sfgAlignment;
typedef sfg::Adjustment sfgAdjustment;
typedef sfg::Separator sfgSeparator;
typedef sfg::Box sfgBox;
typedef sfg::Frame sfgFrame;
typedef sfg::Window sfgWindow;
typedef sfg::ScrolledWindow sfgScrolledWindow;
typedef sfg::Button sfgButton;
typedef sfg::Entry sfgEntry;
typedef sfg::Label sfgLabel;
} // namespace OOLUA
DECLARE_LUA_SINGLETON(GuiManager)
OOLUA_PROXY(GuiManager, Singleton<GuiManager>)
OOLUA_TAGS(No_public_constructors)
OOLUA_MFUNC(Add)
OOLUA_MFUNC(Remove)
OOLUA_MFUNC(RemoveAll)
OOLUA_MFUNC_CONST(GetScreenSize)
OOLUA_SFUNC(ApplyStyle)
OOLUA_SFUNC(ApplyStyleFromFile)
OOLUA_PROXY_END
OOLUA_PROXY(VoidCallback)
OOLUA_TAGS(Abstract)
OOLUA_PROXY_END
OOLUA_PROXY(sfgSignal)
OOLUA_TAGS(Abstract)
OOLUA_MFUNC(Connect)
OOLUA_MFUNC(Disconnect)
OOLUA_SFUNC(GetGUID)
OOLUA_PROXY_END
OOLUA_PROXY(sfgMisc)
OOLUA_TAGS(Abstract)
OOLUA_MFUNC_CONST(GetAlignment)
OOLUA_MFUNC(SetAlignment)
OOLUA_PROXY_END
OOLUA_PROXY(sfgObject)
OOLUA_TAGS(Shared, Abstract, No_public_constructors)
OOLUA_MFUNC(GetSignal)
OOLUA_PROXY_END
OOLUA_PROXY( sfgWidget, sfgObject)
OOLUA_TAGS(Shared, Abstract, Register_class_enums)
OOLUA_ENUMS
(
OOLUA_ENUM(NORMAL)
OOLUA_ENUM(ACTIVE)
OOLUA_ENUM(PRELIGHT)
OOLUA_ENUM(SELECTED)
OOLUA_ENUM(INSENSITIVE)
)
OOLUA_MFUNC(Show)
OOLUA_MFUNC(SetAllocation)
OOLUA_MFUNC(SetPosition)
OOLUA_MFUNC(SetState)
OOLUA_MFUNC(SetId)
OOLUA_MEM_FUNC_0(void, SetActiveWidget)
//OOLUA_MFUNC(SetActiveWidget)
OOLUA_MEM_FUNC_0(void, GrabFocus)
//OOLUA_MFUNC(GrabFocus)
OOLUA_MFUNC_CONST(Invalidate)
OOLUA_MFUNC_CONST(GetAllocation)
OOLUA_MFUNC_CONST(GetState)
OOLUA_MFUNC_CONST(GetId)
OOLUA_MFUNC_CONST(IsGloballyVisible)
OOLUA_MFUNC_CONST(IsLocallyVisible)
OOLUA_MEM_FUNC_CONST_0(bool, HasFocus)
//OOLUA_MFUNC_CONST(HasFocus)
OOLUA_MEM_FUNC_CONST_0(bool, IsActiveWidget)
//OOLUA_MFUNC_CONST(IsActiveWidget)
OOLUA_PROXY_END
OOLUA_PROXY( sfgAdjustment, sfgObject)
OOLUA_TAGS(Shared, Abstract)
OOLUA_PROXY_END
OOLUA_PROXY( sfgContainer, sfgWidget )
OOLUA_TAGS(Shared, Abstract)
OOLUA_MFUNC(Add)
OOLUA_MFUNC(Remove)
OOLUA_MFUNC(RemoveAll)
OOLUA_MFUNC(Refresh)
OOLUA_MFUNC_CONST(IsChild)
OOLUA_PROXY_END
OOLUA_PROXY( sfgBin, sfgContainer )
OOLUA_TAGS(Shared, No_public_constructors)
OOLUA_MFUNC_CONST( GetChild )
OOLUA_PROXY_END
OOLUA_PROXY( sfgFixed, sfgContainer )
OOLUA_TAGS(Shared, No_public_constructors)
OOLUA_MFUNC( Put )
OOLUA_MFUNC( Move )
OOLUA_SFUNC(Create)
OOLUA_PROXY_END
OOLUA_PROXY( sfgAlignment, sfgBin, sfgMisc)
OOLUA_TAGS(Shared, No_public_constructors)
OOLUA_MFUNC( SetScale )
OOLUA_MFUNC_CONST( GetScale )
OOLUA_SFUNC(Create)
OOLUA_PROXY_END
OOLUA_PROXY( sfgFrame, sfgBin, sfgMisc)
OOLUA_TAGS(Shared, No_public_constructors)
OOLUA_MFUNC( SetLabel )
OOLUA_MFUNC_CONST( GetLabel )
OOLUA_SFUNC(Create)
OOLUA_PROXY_END
OOLUA_PROXY( sfgBox, sfgContainer )
OOLUA_TAGS(Shared, No_public_constructors, Register_class_enums)
OOLUA_ENUMS
(
OOLUA_ENUM(HORIZONTAL)
OOLUA_ENUM(VERTICAL)
)
OOLUA_MFUNC(Pack)
OOLUA_SFUNC(Create)
OOLUA_PROXY_END
OOLUA_PROXY( sfgSeparator, sfgWidget )
OOLUA_TAGS(Shared, No_public_constructors, Register_class_enums)
OOLUA_ENUMS
(
OOLUA_ENUM(HORIZONTAL)
OOLUA_ENUM(VERTICAL)
)
OOLUA_MFUNC_CONST(GetOrientation)
OOLUA_SFUNC(Create)
OOLUA_PROXY_END
OOLUA_PROXY( sfgWindow, sfgBin )
OOLUA_TAGS(Shared, No_public_constructors, Register_class_enums)
OOLUA_ENUMS
(
OOLUA_ENUM(NO_STYLE)
OOLUA_ENUM(TITLEBAR)
OOLUA_ENUM(BACKGROUND)
OOLUA_ENUM(RESIZE)
OOLUA_ENUM(SHADOW)
OOLUA_ENUM(TOPLEVEL)
)
OOLUA_MFUNC(SetTitle)
OOLUA_SFUNC(Create)
OOLUA_PROXY_END
OOLUA_PROXY( sfgScrolledWindow, sfgContainer )
OOLUA_TAGS(Shared, No_public_constructors)
OOLUA_PROXY_END
namespace OOLUA
{
int sfgScrolledWindow_Static_Create(lua_State* vm);
int sfgScrolledWindow_Static_Create_With_Adjustments(lua_State* vm);
}
OOLUA_PROXY( sfgButton, sfgBin )
OOLUA_TAGS(Shared, No_public_constructors)
OOLUA_SFUNC(Create)
OOLUA_PROXY_END
OOLUA_PROXY( sfgEntry, sfgWidget )
OOLUA_TAGS(Shared, No_public_constructors)
OOLUA_SFUNC(Create)
OOLUA_PROXY_END
OOLUA_PROXY( sfgLabel, sfgWidget, sfgMisc )
OOLUA_TAGS(Shared, No_public_constructors)
OOLUA_SFUNC(Create)
OOLUA_PROXY_END
But all this not very useful without a little extension. Binding Lua functions and sounds to sfgui signals:
struct GuiEnum
{
enum GuiSignal
{
signalOnStateChange, //!< Fired when state changed.
signalOnGainFocus, //!< Fired when focus gained.
signalOnLostFocus, //!< Fired when focus lost.
signalOnExpose, //!< Fired when widget is being rendered.
signalOnSizeAllocate, //!< Fired when widget's allocation changed.
signalOnSizeRequest, //!< Fired when size was requested.
signalOnMouseEnter, //!< Fired when mouse entered widget.
signalOnMouseLeave, //!< Fired when mouse left widget.
signalOnMouseMove, //!< Fired when mouse moved over widget.
signalOnMouseLeftPress, //!< Fired when left button pressed.
signalOnMouseRightPress, //!< Fired when right button pressed.
signalOnMouseLeftRelease, //!< Fired when left button released.
signalOnMouseRightRelease, //!< Fired when right button released.
signalOnLeftClick, //!< Fired when left button clicked.
signalOnRightClick, //!< Fired when right button clicked.
signalOnKeyPress, //!< Fired when a key is pressed while State == Active.
signalOnKeyRelease, //!< Fired when a key is released while State == Active.
signalOnText, //!< Fired when text is entered while State == Active.
signalNum
};
}; // struct GuiEnum
///////////////////////////////////////////////////////////////////////////////
class IExtended
{
protected:
static sfg::Signal::SignalID* sSignals[GuiEnum::signalNum];
};
template<class T>
class SFGExtended: public T, protected IExtended
{
typedef SFGExtended<T> ThisClass;
typedef void (ThisClass::*SignalCallback)();
SignalCallback mSignalCallbacks[GuiEnum::signalNum];
public:
virtual ~SFGExtended<T>()
{
}
void SetSignalCallback(GuiEnum::GuiSignal signal, const std::string& callback)
{
mLuaCallbacks[signal] = callback;
this->GetSignal(*sSignals[signal]).Connect( std::bind(mSignalCallbacks[signal], this) );
}
static bool SetSound(int signal, const std::string& filename);
protected:
explicit SFGExtended<T>()
{
#define STORE_CALLBACK(Name) mSignalCallbacks[GuiEnum::signal##Name] = &ThisClass::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 void RunCallback(GuiEnum::GuiSignal signal)
{
LuaManager::Instance().AddCallback(mLuaCallbacks[signal], this, false);
//LuaManager::Instance().Lua().call(mLuaCallbacks[signal], this);
}
inline void PlaySound(GuiEnum::GuiSignal signal)
{
if (sSounds[signal])
{
mSound.setBuffer(*sSounds[signal]);
mSound.play();
}
}
#define DECLARE_CALLBACK(Name) \
virtual void Name() {\
PlaySound(GuiEnum::signal##Name);\
RunCallback(GuiEnum::signal##Name); }
DECLARE_CALLBACK(OnStateChange)
DECLARE_CALLBACK(OnGainFocus)
DECLARE_CALLBACK(OnLostFocus)
DECLARE_CALLBACK(OnExpose)
DECLARE_CALLBACK(OnSizeAllocate)
DECLARE_CALLBACK(OnSizeRequest)
DECLARE_CALLBACK(OnMouseEnter)
DECLARE_CALLBACK(OnMouseLeave)
DECLARE_CALLBACK(OnMouseMove)
DECLARE_CALLBACK(OnMouseLeftPress)
DECLARE_CALLBACK(OnMouseRightPress)
DECLARE_CALLBACK(OnMouseLeftRelease)
DECLARE_CALLBACK(OnMouseRightRelease)
DECLARE_CALLBACK(OnLeftClick)
DECLARE_CALLBACK(OnRightClick)
DECLARE_CALLBACK(OnKeyPress)
DECLARE_CALLBACK(OnKeyRelease)
DECLARE_CALLBACK(OnText)
#undef DECLARE_CALLBACK
private:
std::string mLuaCallbacks[GuiEnum::signalNum];
sf::Sound mSound;
static sf::SoundBuffer* sSounds[GuiEnum::signalNum];
};
template<class T>
/* static */ sf::SoundBuffer* SFGExtended<T>::sSounds[GuiEnum::signalNum] = { nullptr };
template<class T>
/* static */ bool SFGExtended<T>::SetSound(int signal, const std::string& filename)
{
return ResourceManager::Instance().GetSoundBuffer(filename, sSounds[signal]);
}
#define DECLARE_EXTENDED(x)\
typedef SFGExtended<sfg::x> Extended##x;\
OOLUA_PROXY( Extended##x, sfg##x)\
OOLUA_TAGS(Shared, Abstract)\
OOLUA_MFUNC(SetSignalCallback)\
OOLUA_SFUNC(SetSound)\
OOLUA_PROXY_END
DECLARE_EXTENDED(Button)
#undef DECLARE_EXTENDED
class GuiButton: public ExtendedButton
{
public:
typedef std::shared_ptr<GuiButton> Ptr;
typedef std::shared_ptr<const GuiButton> PtrConst;
static Ptr Create( const std::string& label);
private:
};
OOLUA_PROXY(GuiEnum)
OOLUA_TAGS(Abstract, Register_class_enums)
OOLUA_ENUMS(
OOLUA_ENUM(signalOnStateChange)
OOLUA_ENUM(signalOnGainFocus)
OOLUA_ENUM(signalOnLostFocus)
OOLUA_ENUM(signalOnExpose)
OOLUA_ENUM(signalOnSizeAllocate)
OOLUA_ENUM(signalOnSizeRequest)
OOLUA_ENUM(signalOnMouseEnter)
OOLUA_ENUM(signalOnMouseLeave)
OOLUA_ENUM(signalOnMouseMove)
OOLUA_ENUM(signalOnMouseLeftPress)
OOLUA_ENUM(signalOnMouseRightPress)
OOLUA_ENUM(signalOnMouseLeftRelease)
OOLUA_ENUM(signalOnMouseRightRelease)
OOLUA_ENUM(signalOnLeftClick)
OOLUA_ENUM(signalOnRightClick)
OOLUA_ENUM(signalOnKeyPress)
OOLUA_ENUM(signalOnKeyRelease)
OOLUA_ENUM(signalOnText))
OOLUA_PROXY_END
OOLUA_PROXY( GuiButton, ExtendedButton)
OOLUA_TAGS(Shared, No_public_constructors)
OOLUA_SFUNC(Create)
OOLUA_PROXY_END
There are two CPP files also and ResourceManager for sounds. So, i think that OOLua is very good library to create Lua bindings. =)
PS One bad thing. OOLua not supports strongly typed enums yet. Deleting keyword 'class' solves the problem, but this is hack and ugly.