SFML community forums
General => SFML projects => Topic started by: FRex on November 30, 2013, 01:53:54 am
-
Yes, SFGUI bound to Lua. ;)
It's not a full binding, it just binds widgets and allows for signals in Lua.
It doesn't allow defining styles but it lets you set class and id of widget so you can use a css file with it too.
It's more work in progress than SFGUI's docs. (So quite rough for now) :P
Here is the repo with everything tucked into /src/:
https://github.com/FRex/LuaSFG
This is where code is in /src/, grouped into files, not fully ready but ok-ish state already, this will be just the base c++ code, in separate files. Ideally there might be cmake/premake file, /include/ and /src/ directories and import/export macros in code but oh.. well.. use MoonSFG if you're desperate already..
Here is MoonSFG repo, with monolithic .hpp and .cpp:
https://github.com/FRex/MoonSFG
I just cat'd files together and removed some includes, it compiled but it's stupid and dirty as hell.. I'll have to make a script for generating this two in a saner way from LuaSFG.
This is also the repo that will (ideally) contain examples in both languages, the script used to build monolithic files, lua script to remove explicit casting(see thread and example lua code to see what I mean) and so on.
Monolithic hpp and cpp is what you'd download right now if you want to test it, you link your own Lua, you link your own SFML and you link your own SFGUI. Then add these two to your project and call ee::openLuaSFG(L); No linking, no Lua C/c++ issues, you provide all includes and link and it'll work.
There is example right now of guess my number on official SFG forum: http://sfgui.sfml-dev.de/forum/post1513.html#p1513
There might be bugs, crashes, leaks, errors, typos, things are missing, but it's mostly complete etc.
Strings are passed to/from Lua as ASCII, they'll be UTF-8 later.
The ee namespace is what I use for myself and I didn't plan to share until it got a bit long and just went with it so it might change to something like luasfg or LuaSFGUI or something.
-
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.