diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1d484735cc66..47573dc2aa90 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1210,6 +1210,7 @@ if(ENABLE_SDL2_TOOLS) add_executable(sdl2 tools/sdl2/sdl2.cpp + tools/sdl2/window.cpp ) target_link_libraries(sdl2 diff --git a/src/tools/sdl2/sdl2.cpp b/src/tools/sdl2/sdl2.cpp index 16cc838726a4..ce2976a93819 100644 --- a/src/tools/sdl2/sdl2.cpp +++ b/src/tools/sdl2/sdl2.cpp @@ -17,8 +17,11 @@ * Tool to test SDL 2 functions. */ +#include "tools/sdl2/sdl2.hpp" + #include "sdl/texture.hpp" #include "sdl/window.hpp" +#include "tools/sdl2/window.hpp" #include "text.hpp" #include @@ -28,6 +31,8 @@ #include #include +std::vector windows; + struct texit { }; @@ -97,6 +102,40 @@ static void draw_command_history(sdl::twindow& window, } } +static bool execute_command(std::string& command_line) +{ + std::string::const_iterator begin = command_line.begin(); + const std::string command = get_token(command_line, begin, ' '); + + if(command == "quit") { + + utf8::insert(command_line, utf8::size(command_line), " -> Ok"); + return false; + } else if(command == "window") { + + execute_window(command_line, begin); + } + + return true; +} + +std::string get_token(const std::string& string, + std::string::const_iterator& begin, + const char separator) +{ + const std::string::const_iterator end + = std::find(begin, string.end(), separator); + + std::string result = std::string(begin, end); + + begin = end; + if(begin != string.end()) { + ++begin; + } + + return result; +} + int main() { try @@ -120,7 +159,8 @@ int main() SDL_SetTextInputRect(&rect); const ttext_input text_input; - while(true) { + bool run = true; + while(run) { if(dirty) { window.clear(); draw_command_line(window, line); @@ -128,6 +168,12 @@ int main() dirty = false; } window.render(); + BOOST_FOREACH(sdl::twindow * window, windows) + { + if(window) { + window->render(); + } + } if(SDL_WaitEvent(&event) == 0) { return EXIT_FAILURE; } @@ -154,12 +200,14 @@ int main() case SDL_KEYUP: if(event.key.keysym.sym == SDLK_RETURN) { + run = execute_command(line); history.push_back(line); if(history.size() > 22) { history.pop_front(); } line.clear(); dirty = true; + SDL_RaiseWindow(window); } break; diff --git a/src/tools/sdl2/sdl2.hpp b/src/tools/sdl2/sdl2.hpp new file mode 100644 index 000000000000..539d9f882cef --- /dev/null +++ b/src/tools/sdl2/sdl2.hpp @@ -0,0 +1,59 @@ +/* + Copyright (C) 2014 by Mark de Wever + Part of the Battle for Wesnoth Project http://www.wesnoth.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY. + + See the COPYING file for more details. +*/ + +#ifndef TOOLS_SDL2_SDL2_HPP_INCLUDED +#define TOOLS_SDL2_SDL2_HPP_INCLUDED + +#include +#include + +namespace sdl +{ +class twindow; +} // namespace sdl + +/** + * Contains the windows created by the user. + * + * @note The pointers are leaked when the program terminates, leaving it to the + * OS to do the cleanup. + */ +extern std::vector windows; + +/** + * Gets a token from a string. + * + * Tokens are separated by a single @p separator character. + * + * @param string The string to search for tokens. + * @param[in,out] begin Input: + * - The beginning of the current token. The + * text until the next @p separator is matched. + * Output: + * - The position of the next token or the end + * of the @p string if the @p separator + * character was not found. + * @param separator The character marking the separation between + * tokens. + * + * @returns The matched string. The match is either until + * the @p separator character, or if the + * character is not found until the end of the + * @p string. + */ +std::string get_token(const std::string& string, + std::string::const_iterator& begin, + const char separator); + +#endif diff --git a/src/tools/sdl2/window.cpp b/src/tools/sdl2/window.cpp new file mode 100644 index 000000000000..cef060cf4251 --- /dev/null +++ b/src/tools/sdl2/window.cpp @@ -0,0 +1,125 @@ +/* + Copyright (C) 2014 by Mark de Wever + Part of the Battle for Wesnoth Project http://www.wesnoth.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY. + + See the COPYING file for more details. +*/ + +#include "tools/sdl2/window.hpp" + +#include "tools/sdl2/sdl2.hpp" + +#include "sdl/window.hpp" +#include "serialization/unicode.hpp" + +#include + +static void create(std::string& command, std::string::const_iterator begin) +{ + std::string title; + int x = SDL_WINDOWPOS_CENTERED; + int y = SDL_WINDOWPOS_CENTERED; + int w = 800; + int h = 600; + + while(begin != command.end()) { + const std::string argument = get_token(command, begin, ' '); + + if(argument.find("x=") == 0) { + x = boost::lexical_cast(argument.substr(2)); + } else if(argument.find("y=") == 0) { + y = boost::lexical_cast(argument.substr(2)); + } else if(argument.find("w=") == 0) { + w = boost::lexical_cast(argument.substr(2)); + } else if(argument.find("h=") == 0) { + h = boost::lexical_cast(argument.substr(2)); + } else if(argument.find("title=") == 0) { + title = argument.substr(6); /* todo allow spaces. */ + } else { + utf8::insert(command, utf8::size(command), " -> Unknown argument"); + } + } + + windows.push_back(new sdl::twindow( + title.c_str(), x, y, w, h, 0, SDL_RENDERER_TARGETTEXTURE)); + + utf8::insert(command, + utf8::size(command), + " -> OK ID " + + boost::lexical_cast(windows.size() - 1)); +} + +static void modify(std::string& command, std::string::const_iterator begin) +{ + std::size_t id + = boost::lexical_cast(get_token(command, begin, ' ')); + + if(id >= windows.size()) { + utf8::insert(command, utf8::size(command), " -> ID out of range"); + } else if(windows[id] == NULL) { + utf8::insert(command, utf8::size(command), " -> ID destroyed"); + } else { + + std::string title = SDL_GetWindowTitle(*windows[id]); + int w; + int h; + SDL_GetWindowSize(*windows[id], &w, &h); + + while(begin != command.end()) { + const std::string argument = get_token(command, begin, ' '); + + if(argument.find("w=") == 0) { + w = boost::lexical_cast(argument.substr(2)); + } else if(argument.find("h=") == 0) { + h = boost::lexical_cast(argument.substr(2)); + } else if(argument.find("title=") == 0) { + title = argument.substr(6); /* todo allow spaces. */ + } else { + utf8::insert( + command, utf8::size(command), " -> Unknown argument"); + } + } + + windows[id]->set_title(title); + windows[id]->set_size(w, h); + utf8::insert(command, utf8::size(command), " -> OK"); + } +} + +static void destroy(std::string& command, std::string::const_iterator begin) +{ + std::size_t id + = boost::lexical_cast(get_token(command, begin, ' ')); + + if(id >= windows.size()) { + utf8::insert(command, utf8::size(command), " -> ID out of range"); + } else if(windows[id] == NULL) { + utf8::insert(command, utf8::size(command), " -> ID already destroyed"); + } else { + delete windows[id]; + windows[id] = NULL; + utf8::insert(command, utf8::size(command), " -> OK"); + } +} + +void execute_window(std::string& command, std::string::const_iterator begin) +{ + const std::string action = get_token(command, begin, ' '); + + if(action == "create") { + create(command, begin); + } else if(action == "modify") { + modify(command, begin); + } else if(action == "destroy") { + destroy(command, begin); + } else { + utf8::insert(command, utf8::size(command), " -> Unknown action"); + } +} diff --git a/src/tools/sdl2/window.hpp b/src/tools/sdl2/window.hpp new file mode 100644 index 000000000000..a87a562b5ca5 --- /dev/null +++ b/src/tools/sdl2/window.hpp @@ -0,0 +1,28 @@ +/* + Copyright (C) 2014 by Mark de Wever + Part of the Battle for Wesnoth Project http://www.wesnoth.org + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY. + + See the COPYING file for more details. +*/ + +#ifndef TOOLS_SDL2_WINDOW_HPP_INCLUDED +#define TOOLS_SDL2_WINDOW_HPP_INCLUDED + +#include + +/** + * Executes a window command. + * + * @param command The command to be executed. + * @param begin The beginning of the command's arguments. + */ +void execute_window(std::string& command, std::string::const_iterator begin); + +#endif