Added love.window.showMessageBox.

It has two variants: showMessageBox(type, title, message [, attachtowindow=true]), and showMessageBox(type, title, message, buttons [, attachtowindow=true]). The former shows a simple message box with a single OK button, and the latter displays several buttons. The buttons argument is an array of button names.

The second variant returns the index of the pressed button, or 0 if the message box was closed some other way. showMessageBox will block until the message box is closed (and it can't be called on a separate thread.)
This commit is contained in:
Alex Szpakowski
2014-07-21 21:28:21 -03:00
parent d52bab4221
commit 3ae336dd43
6 changed files with 176 additions and 0 deletions
+19
View File
@@ -74,6 +74,16 @@ bool Window::getConstant(Window::Setting in, const char *&out)
return settings.find(in, out);
}
bool Window::getConstant(const char *in, MessageBoxType &out)
{
return messageBoxTypes.find(in, out);
}
bool Window::getConstant(MessageBoxType in, const char *&out)
{
return messageBoxTypes.find(in, out);
}
StringMap<Window::Setting, Window::SETTING_MAX_ENUM>::Entry Window::settingEntries[] =
{
{"fullscreen", SETTING_FULLSCREEN},
@@ -101,5 +111,14 @@ StringMap<Window::FullscreenType, Window::FULLSCREEN_TYPE_MAX_ENUM>::Entry Windo
StringMap<Window::FullscreenType, Window::FULLSCREEN_TYPE_MAX_ENUM> Window::fullscreenTypes(Window::fullscreenTypeEntries, sizeof(Window::fullscreenTypeEntries));
StringMap<Window::MessageBoxType, Window::MESSAGEBOX_MAX_ENUM>::Entry Window::messageBoxTypeEntries[] =
{
{"error", Window::MESSAGEBOX_ERROR},
{"warning", Window::MESSAGEBOX_WARNING},
{"info", Window::MESSAGEBOX_INFO},
};
StringMap<Window::MessageBoxType, Window::MESSAGEBOX_MAX_ENUM> Window::messageBoxTypes(Window::messageBoxTypeEntries, sizeof(Window::messageBoxTypeEntries));
} // window
} // love
+31
View File
@@ -69,12 +69,34 @@ public:
FULLSCREEN_TYPE_MAX_ENUM
};
enum MessageBoxType
{
MESSAGEBOX_ERROR,
MESSAGEBOX_WARNING,
MESSAGEBOX_INFO,
MESSAGEBOX_MAX_ENUM
};
struct WindowSize
{
int width;
int height;
};
struct MessageBoxData
{
MessageBoxType type;
std::string title;
std::string message;
std::vector<std::string> buttons;
int enterButtonIndex;
int escapeButtonIndex;
bool attachToWindow;
};
virtual ~Window();
// Implements Module.
@@ -127,6 +149,9 @@ public:
virtual const void *getHandle() const = 0;
virtual bool showMessageBox(MessageBoxType type, const std::string &title, const std::string &message, bool attachtowindow) = 0;
virtual int showMessageBox(const MessageBoxData &data) = 0;
//virtual static Window *createSingleton() = 0;
//virtual static Window *getSingleton() = 0;
// No virtual statics, of course, but you are supposed to implement these statics.
@@ -137,6 +162,9 @@ public:
static bool getConstant(const char *in, FullscreenType &out);
static bool getConstant(FullscreenType in, const char *&out);
static bool getConstant(const char *in, MessageBoxType &out);
static bool getConstant(MessageBoxType in, const char *&out);
protected:
static Window *singleton;
@@ -149,6 +177,9 @@ private:
static StringMap<FullscreenType, FULLSCREEN_TYPE_MAX_ENUM>::Entry fullscreenTypeEntries[];
static StringMap<FullscreenType, FULLSCREEN_TYPE_MAX_ENUM> fullscreenTypes;
static StringMap<MessageBoxType, MESSAGEBOX_MAX_ENUM>::Entry messageBoxTypeEntries[];
static StringMap<MessageBoxType, MESSAGEBOX_MAX_ENUM> messageBoxTypes;
}; // Window
struct WindowSettings
+59
View File
@@ -678,6 +678,65 @@ const void *Window::getHandle() const
return window;
}
SDL_MessageBoxFlags Window::convertMessageBoxType(MessageBoxType type) const
{
switch (type)
{
case MESSAGEBOX_ERROR:
return SDL_MESSAGEBOX_ERROR;
case MESSAGEBOX_WARNING:
return SDL_MESSAGEBOX_WARNING;
case MESSAGEBOX_INFO:
default:
return SDL_MESSAGEBOX_INFORMATION;
}
}
bool Window::showMessageBox(MessageBoxType type, const std::string &title, const std::string &message, bool attachtowindow)
{
SDL_MessageBoxFlags flags = convertMessageBoxType(type);
SDL_Window *sdlwindow = attachtowindow ? window : nullptr;
return SDL_ShowSimpleMessageBox(flags, title.c_str(), message.c_str(), sdlwindow) >= 0;
}
int Window::showMessageBox(const MessageBoxData &data)
{
SDL_MessageBoxData sdldata = {};
sdldata.flags = convertMessageBoxType(data.type);
sdldata.title = data.title.c_str();
sdldata.message = data.message.c_str();
sdldata.window = data.attachToWindow ? window : nullptr;
sdldata.numbuttons = (int) data.buttons.size();
std::vector<SDL_MessageBoxButtonData> sdlbuttons;
for (size_t i = 0; i < data.buttons.size(); i++)
{
SDL_MessageBoxButtonData sdlbutton = {};
sdlbutton.buttonid = (int) i;
sdlbutton.text = data.buttons[i].c_str();
if ((int) i == data.enterButtonIndex)
sdlbutton.flags |= SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT;
if ((int) i == data.escapeButtonIndex)
sdlbutton.flags |= SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT;
sdlbuttons.push_back(sdlbutton);
}
sdldata.buttons = &sdlbuttons[0];
int pressedbutton = -2;
SDL_ShowMessageBox(&sdldata, &pressedbutton);
return pressedbutton;
}
love::window::Window *Window::createSingleton()
{
if (!singleton)
+5
View File
@@ -87,6 +87,9 @@ public:
const void *getHandle() const;
bool showMessageBox(MessageBoxType type, const std::string &title, const std::string &message, bool attachtowindow);
int showMessageBox(const MessageBoxData &data);
static love::window::Window *createSingleton();
static love::window::Window *getSingleton();
@@ -100,6 +103,8 @@ private:
// Update the saved window settings based on the window's actual state.
void updateSettings(const WindowSettings &newsettings);
SDL_MessageBoxFlags convertMessageBoxType(MessageBoxType type) const;
std::string windowTitle;
struct _currentMode
+61
View File
@@ -340,6 +340,66 @@ int w_minimize(lua_State* /*L*/)
return 0;
}
int w_showMessageBox(lua_State *L)
{
Window::MessageBoxData data = {};
const char *typestr = luaL_checkstring(L, 1);
if (!Window::getConstant(typestr, data.type))
return luaL_error(L, "Invalid messagebox type: %s", typestr);
data.title = luaL_checkstring(L, 2);
data.message = luaL_checkstring(L, 3);
// If we have a table argument, we assume a list of button names, which
// means we should use the more complex message box API.
if (lua_istable(L, 4))
{
size_t numbuttons = lua_objlen(L, 4);
if (numbuttons == 0)
return luaL_error(L, "Must have at least one messagebox button.");
// Array of button names.
for (size_t i = 0; i < numbuttons; i++)
{
lua_rawgeti(L, 4, i + 1);
data.buttons.push_back(luax_checkstring(L, -1));
lua_pop(L, 1);
}
// Optional table entry specifying the button to use when enter is pressed.
lua_getfield(L, 4, "enterbutton");
if (!lua_isnoneornil(L, -1))
data.enterButtonIndex = luaL_checkint(L, -1) - 1;
else
data.enterButtonIndex = 0;
lua_pop(L, 1);
// Optional table entry specifying the button to use when esc is pressed.
lua_getfield(L, 4, "escapebutton");
if (!lua_isnoneornil(L, -1))
data.escapeButtonIndex = luaL_checkint(L, -1) - 1;
else
data.escapeButtonIndex = (int) data.buttons.size() - 1;
lua_pop(L, 1);
data.attachToWindow = luax_optboolean(L, 5, true);
int pressedbutton = instance()->showMessageBox(data);
lua_pushinteger(L, pressedbutton + 1);
}
else
{
data.attachToWindow = luax_optboolean(L, 4, true);
// Display a simple message box.
bool success = instance()->showMessageBox(data.type, data.title, data.message, data.attachToWindow);
luax_pushboolean(L, success);
}
return 1;
}
static const luaL_Reg functions[] =
{
{ "getDisplayCount", w_getDisplayCount },
@@ -363,6 +423,7 @@ static const luaL_Reg functions[] =
{ "isVisible", w_isVisible },
{ "getPixelScale", w_getPixelScale },
{ "minimize", w_minimize },
{ "showMessageBox", w_showMessageBox },
{ 0, 0 }
};
+1
View File
@@ -50,6 +50,7 @@ int w_hasMouseFocus(lua_State *L);
int w_isVisible(lua_State *L);
int w_getPixelScale(lua_State *L);
int w_minimize(lua_State *L);
int w_showMessageBox(lua_State *L);
extern "C" LOVE_EXPORT int luaopen_love_window(lua_State *L);
} // window