Mercurial > malikania
changeset 82:ee850a6ab89e
Client: namespace and hierarchy
line wrap: on
line diff
--- a/client/main.cpp Sun Jan 22 10:11:17 2017 +0100 +++ b/client/main.cpp Sun Jan 22 11:07:36 2017 +0100 @@ -21,21 +21,21 @@ #include <chrono> #include <thread> -#include "malikania/button.hpp" -#include "malikania/color.hpp" -#include "malikania/frame.hpp" -#include "malikania/label.hpp" -#include "malikania/point.hpp" -#include "malikania/unique_layout.hpp" -#include "malikania/window.hpp" +#include <malikania/client/button.hpp> +#include <malikania/client/color.hpp> +#include <malikania/client/frame.hpp> +#include <malikania/client/label.hpp> +#include <malikania/client/point.hpp> +#include <malikania/client/unique_layout.hpp> +#include <malikania/client/window.hpp> int main() { - mlk::window win; + mlk::client::window win; - auto f = std::make_shared<mlk::frame>(); - auto w = std::make_shared<mlk::label>("Malikania"); - auto l = std::make_shared<mlk::unique_layout>(w); + auto f = std::make_shared<mlk::client::frame>(); + auto w = std::make_shared<mlk::client::label>("Malikania"); + auto l = std::make_shared<mlk::client::unique_layout>(w); f->move({50, 50}); f->set_layout(l);
--- a/examples/animation/main.cpp Sun Jan 22 10:11:17 2017 +0100 +++ b/examples/animation/main.cpp Sun Jan 22 11:07:36 2017 +0100 @@ -20,29 +20,29 @@ #include <thread> #include <exception> -#include <malikania/animation.hpp> -#include <malikania/animator.hpp> -#include <malikania/client_resources_loader.hpp> +#include <malikania/client/animation.hpp> +#include <malikania/client/animator.hpp> +#include <malikania/client/loader.hpp> +#include <malikania/client/window.hpp> #include <malikania/locator.hpp> -#include <malikania/window.hpp> int main() { boost::timer::cpu_timer timer; try { - mlk::window win(400, 400); mlk::directory_locator locator(SOURCE_DIRECTORY); - mlk::client_resources_loader loader(locator); - mlk::animation animation = loader.load_animation("animations/margins.json"); - mlk::animator animator(animation); + mlk::client::window win(400, 400); + mlk::client::loader loader(locator); + mlk::client::animation animation = loader.load_animation("animations/margins.json"); + mlk::client::animator animator(animation); auto x = (400 / 2) - (animation.sprite().cell().width() / 2); auto y = (400 / 2) - (animation.sprite().cell().height() / 2); while (timer.elapsed().wall / 1000000LL < 8000) { win.clear(); - animator.draw(win, mlk::point(x, y)); + animator.draw(win, mlk::client::point(x, y)); animator.update(); win.present(); }
--- a/examples/font/main.cpp Sun Jan 22 10:11:17 2017 +0100 +++ b/examples/font/main.cpp Sun Jan 22 11:07:36 2017 +0100 @@ -19,86 +19,86 @@ #include <chrono> #include <thread> -#include <malikania/client_resources_loader.hpp> -#include <malikania/color.hpp> -#include <malikania/font.hpp> +#include <malikania/client/loader.hpp> +#include <malikania/client/color.hpp> +#include <malikania/client/font.hpp> +#include <malikania/client/point.hpp> +#include <malikania/client/window.hpp> #include <malikania/locator.hpp> -#include <malikania/point.hpp> -#include <malikania/window.hpp> using namespace std::chrono_literals; -void topleft(mlk::window& window, mlk::font& font) +void topleft(mlk::client::window& window, mlk::client::font& font) { - window.set_drawing_color(mlk::color("black")); + window.set_drawing_color(mlk::client::color("black")); window.clear(); - window.set_drawing_color(mlk::color("white")); - window.draw_text("top left", font, mlk::point(10, 10)); + window.set_drawing_color(mlk::client::color("white")); + window.draw_text("top left", font, mlk::client::point(10, 10)); window.present(); std::this_thread::sleep_for(1s); } -void topright(mlk::window& window, mlk::font& font) +void topright(mlk::client::window& window, mlk::client::font& font) { auto dim = font.clip("top right"); - window.set_drawing_color(mlk::color("black")); + window.set_drawing_color(mlk::client::color("black")); window.clear(); - window.set_drawing_color(mlk::color("white")); - window.draw_text("top right", font, mlk::point(400 - dim.width() - 10, 10)); + window.set_drawing_color(mlk::client::color("white")); + window.draw_text("top right", font, mlk::client::point(400 - dim.width() - 10, 10)); window.present(); std::this_thread::sleep_for(1s); } -void bottomleft(mlk::window& window, mlk::font& font) +void bottomleft(mlk::client::window& window, mlk::client::font& font) { auto dim = font.clip("bottom left"); - window.set_drawing_color(mlk::color("black")); + window.set_drawing_color(mlk::client::color("black")); window.clear(); - window.set_drawing_color(mlk::color("white")); - window.draw_text("bottom left", font, mlk::point(10, 400 - dim.height() - 10)); + window.set_drawing_color(mlk::client::color("white")); + window.draw_text("bottom left", font, mlk::client::point(10, 400 - dim.height() - 10)); window.present(); std::this_thread::sleep_for(1s); } -void bottomright(mlk::window& window, mlk::font& font) +void bottomright(mlk::client::window& window, mlk::client::font& font) { auto dim = font.clip("bottom right"); - window.set_drawing_color(mlk::color("black")); + window.set_drawing_color(mlk::client::color("black")); window.clear(); - window.set_drawing_color(mlk::color("white")); - window.draw_text("bottom right", font, mlk::point(400 - dim.width() - 10, 400 - dim.height() - 10)); + window.set_drawing_color(mlk::client::color("white")); + window.draw_text("bottom right", font, mlk::client::point(400 - dim.width() - 10, 400 - dim.height() - 10)); window.present(); std::this_thread::sleep_for(1s); } -void center(mlk::window& window, mlk::font& font) +void center(mlk::client::window& window, mlk::client::font& font) { auto dim = font.clip("center"); - window.set_drawing_color(mlk::color("black")); + window.set_drawing_color(mlk::client::color("black")); window.clear(); - window.set_drawing_color(mlk::color("white")); - window.draw_text("center", font, mlk::point(200 - (dim.width() / 2), 200 - (dim.height() -2))); + window.set_drawing_color(mlk::client::color("white")); + window.draw_text("center", font, mlk::client::point(200 - (dim.width() / 2), 200 - (dim.height() -2))); window.present(); std::this_thread::sleep_for(1s); } -void center2(mlk::window& window, mlk::font& font) +void center2(mlk::client::window& window, mlk::client::font& font) { auto dim = font.clip("The world is Malikania."); - window.set_drawing_color(mlk::color("black")); + window.set_drawing_color(mlk::client::color("black")); window.clear(); - window.set_drawing_color(mlk::color("white")); - window.draw_text("The world is Malikania.", font, mlk::point(200 - (dim.width() / 2), 200 - (dim.height() -2))); + window.set_drawing_color(mlk::client::color("white")); + window.draw_text("The world is Malikania.", font, mlk::client::point(200 - (dim.width() / 2), 200 - (dim.height() -2))); window.present(); std::this_thread::sleep_for(3s); @@ -107,10 +107,10 @@ int main() { try { - mlk::window window(400, 400); + mlk::client::window window(400, 400); mlk::directory_locator locator(SOURCE_DIRECTORY); - mlk::client_resources_loader loader(locator); - mlk::font font = loader.load_font("DejaVuSans.ttf", 10); + mlk::client::loader loader(locator); + mlk::client::font font = loader.load_font("DejaVuSans.ttf", 10); topleft(window, font); topright(window, font);
--- a/examples/image/main.cpp Sun Jan 22 10:11:17 2017 +0100 +++ b/examples/image/main.cpp Sun Jan 22 11:07:36 2017 +0100 @@ -19,14 +19,14 @@ #include <chrono> #include <thread> -#include <malikania/client_resources_loader.hpp> -#include <malikania/image.hpp> +#include <malikania/client/loader.hpp> +#include <malikania/client/image.hpp> +#include <malikania/client/window.hpp> #include <malikania/locator.hpp> -#include <malikania/window.hpp> using namespace std::chrono_literals; -void draw(mlk::window& window, mlk::client_resources_loader& loader) +void draw(mlk::client::window& window, mlk::client::loader& loader) { try { auto image = loader.load_image("images/smiley.png"); @@ -34,7 +34,7 @@ auto y = (400 / 2) - (image.size().height() / 2); window.clear(); - image.draw(window, mlk::point(x, y)); + image.draw(window, mlk::client::point(x, y)); window.present(); std::this_thread::sleep_for(3s); @@ -47,9 +47,9 @@ int main() { try { - mlk::window window(400, 400); + mlk::client::window window(400, 400); mlk::directory_locator locator(SOURCE_DIRECTORY); - mlk::client_resources_loader loader(locator); + mlk::client::loader loader(locator); draw(window, loader); } catch (const std::exception& ex) {
--- a/examples/js-animation/main.cpp Sun Jan 22 10:11:17 2017 +0100 +++ b/examples/js-animation/main.cpp Sun Jan 22 11:07:36 2017 +0100 @@ -31,7 +31,7 @@ { try { mlk::directory_locator locator(SOURCE_DIRECTORY); - mlk::client_resources_loader loader(locator); + mlk::client::loader loader(locator); dukx_context m_ctx; duk_push_object(m_ctx);
--- a/examples/js-font/main.cpp Sun Jan 22 10:11:17 2017 +0100 +++ b/examples/js-font/main.cpp Sun Jan 22 11:07:36 2017 +0100 @@ -51,7 +51,7 @@ { try { mlk::directory_locator locator(SOURCE_DIRECTORY); - mlk::client_resources_loader loader(locator); + mlk::client::loader loader(locator); dukx_context ctx; duk_push_object(ctx);
--- a/examples/js-image/main.cpp Sun Jan 22 10:11:17 2017 +0100 +++ b/examples/js-image/main.cpp Sun Jan 22 11:07:36 2017 +0100 @@ -66,7 +66,7 @@ { try { mlk::directory_locator locator(SOURCE_DIRECTORY); - mlk::client_resources_loader loader(locator); + mlk::client::loader loader(locator); dukx_context ctx; duk_push_object(ctx);
--- a/examples/js-sprite/main.cpp Sun Jan 22 10:11:17 2017 +0100 +++ b/examples/js-sprite/main.cpp Sun Jan 22 11:07:36 2017 +0100 @@ -59,7 +59,7 @@ { try { mlk::directory_locator locator(SOURCE_DIRECTORY); - mlk::client_resources_loader loader(locator); + mlk::client::loader loader(locator); dukx_context ctx; duk_push_object(ctx);
--- a/examples/sprite/main.cpp Sun Jan 22 10:11:17 2017 +0100 +++ b/examples/sprite/main.cpp Sun Jan 22 11:07:36 2017 +0100 @@ -20,14 +20,14 @@ #include <thread> #include <exception> -#include <malikania/client_resources_loader.hpp> +#include <malikania/client/loader.hpp> +#include <malikania/client/sprite.hpp> +#include <malikania/client/window.hpp> #include <malikania/locator.hpp> -#include <malikania/sprite.hpp> -#include <malikania/window.hpp> using namespace std::chrono_literals; -void draw(mlk::window& window, mlk::client_resources_loader& loader) +void draw(mlk::client::window& window, mlk::client::loader& loader) { auto sprite = loader.load_sprite("sprites/margins.json"); auto total = sprite.rows() * sprite.columns(); @@ -36,7 +36,7 @@ for (unsigned c = 0; c < total; ++c) { window.clear(); - sprite.draw(window, c, mlk::point(x, y)); + sprite.draw(window, c, mlk::client::point(x, y)); window.present(); std::this_thread::sleep_for(1s); @@ -47,8 +47,8 @@ { try { mlk::directory_locator locator(SOURCE_DIRECTORY); - mlk::client_resources_loader loader(locator); - mlk::window window(400, 400); + mlk::client::loader loader(locator); + mlk::client::window window(400, 400); draw(window, loader); } catch (const std::exception& ex) {
--- a/libclient-js/malikania/js_animation.cpp Sun Jan 22 10:11:17 2017 +0100 +++ b/libclient-js/malikania/js_animation.cpp Sun Jan 22 11:07:36 2017 +0100 @@ -38,7 +38,7 @@ auto anim = loader.load_animation(duk_require_string(ctx, 0)); duk_push_this(ctx); - duk_push_pointer(ctx, new animation(std::move(anim))); + duk_push_pointer(ctx, new client::animation(std::move(anim))); duk_put_prop_string(ctx, -2, signature.c_str()); duk_pop(ctx); } catch (const std::exception &ex) { @@ -51,7 +51,7 @@ duk_ret_t destructor(duk_context* ctx) { duk_get_prop_string(ctx, 0, signature.c_str()); - delete static_cast<animation *>(duk_to_pointer(ctx, -1)); + delete static_cast<client::animation *>(duk_to_pointer(ctx, -1)); duk_pop(ctx); duk_del_prop_string(ctx, 0, signature.c_str()); @@ -60,19 +60,19 @@ } // !namespace -void dukx_new_animation(duk_context* ctx, animation& anim) +void dukx_new_animation(duk_context* ctx, client::animation& anim) { assert(ctx); dukx_stack_assert sa(ctx); duk_push_this(ctx); - duk_push_pointer(ctx, new animation(std::move(anim))); + duk_push_pointer(ctx, new client::animation(std::move(anim))); duk_put_prop_string(ctx, -2, signature.c_str()); duk_pop(ctx); } -animation& dukx_require_animation(duk_context* ctx, duk_idx_t index) +client::animation& dukx_require_animation(duk_context* ctx, duk_idx_t index) { assert(ctx); @@ -86,7 +86,7 @@ duk_error(ctx, DUK_ERR_TYPE_ERROR, "not an animation object"); } - return *static_cast<animation*>(ptr); + return *static_cast<client::animation*>(ptr); } void dukx_load_animation(duk_context* ctx)
--- a/libclient-js/malikania/js_animation.hpp Sun Jan 22 10:11:17 2017 +0100 +++ b/libclient-js/malikania/js_animation.hpp Sun Jan 22 11:07:36 2017 +0100 @@ -19,10 +19,9 @@ #ifndef MALIKANIA_JS_ANIMATION_HPP #define MALIKANIA_JS_ANIMATION_HPP +#include <malikania/client/animation.hpp> #include <malikania/duktape.hpp> -#include "animation.hpp" - namespace mlk { #if 0 @@ -45,7 +44,7 @@ * \param index the value index * \return the Animation object */ -animation& dukx_require_animation(duk_context* ctx, duk_idx_t index); +client::animation& dukx_require_animation(duk_context* ctx, duk_idx_t index); /** * Load the animation module into the context.
--- a/libclient-js/malikania/js_animator.cpp Sun Jan 22 10:11:17 2017 +0100 +++ b/libclient-js/malikania/js_animator.cpp Sun Jan 22 11:07:36 2017 +0100 @@ -30,7 +30,7 @@ const std::string signature("\xff""\xff""malikania-animator-ptr"); -animator& self(duk_context* ctx) +client::animator& self(duk_context* ctx) { dukx_stack_assert sa(ctx); @@ -43,7 +43,7 @@ duk_error(ctx, DUK_ERR_TYPE_ERROR, "not an animator object"); } - return *static_cast<animator*>(ptr); + return *static_cast<client::animator*>(ptr); } duk_ret_t constructor(duk_context *ctx) @@ -53,7 +53,7 @@ } duk_push_this(ctx); - duk_push_pointer(ctx, new animator(dukx_require_animation(ctx, 0))); + duk_push_pointer(ctx, new client::animator(dukx_require_animation(ctx, 0))); duk_put_prop_string(ctx, -2, signature.c_str()); // Be sure animation get not collected before. @@ -67,7 +67,7 @@ duk_ret_t destructor(duk_context *ctx) { duk_get_prop_string(ctx, 0, signature.c_str()); - delete static_cast<animator *>(duk_to_pointer(ctx, -1)); + delete static_cast<client::animator *>(duk_to_pointer(ctx, -1)); duk_pop(ctx); duk_del_prop_string(ctx, 0, signature.c_str()); @@ -116,7 +116,7 @@ #endif -animator& dukx_require_animator(duk_context* ctx, duk_idx_t index) +client::animator& dukx_require_animator(duk_context* ctx, duk_idx_t index) { assert(ctx); @@ -130,7 +130,7 @@ duk_error(ctx, DUK_ERR_TYPE_ERROR, "not an animator object"); } - return *static_cast<animator*>(ptr); + return *static_cast<client::animator*>(ptr); } void dukx_load_animator(duk_context* ctx)
--- a/libclient-js/malikania/js_animator.hpp Sun Jan 22 10:11:17 2017 +0100 +++ b/libclient-js/malikania/js_animator.hpp Sun Jan 22 11:07:36 2017 +0100 @@ -19,8 +19,8 @@ #ifndef MALIKANIA_JS_ANIMATOR_HPP #define MALIKANIA_JS_ANIMATOR_HPP -#include "animator.hpp" -#include "duktape.hpp" +#include <malikania/client/animator.hpp> +#include <malikania/duktape.hpp> namespace mlk { @@ -46,7 +46,7 @@ * \param index the value index * \return the animator */ -animator& dukx_require_animator(duk_context* ctx, duk_idx_t index); +client::animator& dukx_require_animator(duk_context* ctx, duk_idx_t index); void dukx_load_animator(duk_context* ctx);
--- a/libclient-js/malikania/js_client_resources_loader.cpp Sun Jan 22 10:11:17 2017 +0100 +++ b/libclient-js/malikania/js_client_resources_loader.cpp Sun Jan 22 11:07:36 2017 +0100 @@ -29,7 +29,7 @@ } // !namespace -void dukx_put_client_loader(duk_context* ctx, client_resources_loader& loader) +void dukx_put_client_loader(duk_context* ctx, client::loader& loader) { assert(ctx); @@ -42,17 +42,17 @@ duk_put_global_string(ctx, variable.c_str()); } -client_resources_loader& dukx_get_client_loader(duk_context* ctx) +client::loader& dukx_get_client_loader(duk_context* ctx) { assert(ctx); dukx_stack_assert sa(ctx); duk_get_global_string(ctx, variable.c_str()); - auto ptr = static_cast<client_resources_loader*>(duk_to_pointer(ctx, -1)); + auto ptr = static_cast<client::loader*>(duk_to_pointer(ctx, -1)); duk_pop(ctx); - return *static_cast<client_resources_loader*>(ptr); + return *static_cast<client::loader*>(ptr); } } // !mlk
--- a/libclient-js/malikania/js_client_resources_loader.hpp Sun Jan 22 10:11:17 2017 +0100 +++ b/libclient-js/malikania/js_client_resources_loader.hpp Sun Jan 22 11:07:36 2017 +0100 @@ -19,14 +19,15 @@ #ifndef MALIKANIA_JS_CLIENT_RESOURCES_LOADER_H #define MALIKANIA_JS_CLIENT_RESOURCES_LOADER_H -#include "client_resources_loader.hpp" +#include <malikania/client/loader.hpp> + #include "duktape.hpp" namespace mlk { -void dukx_put_client_loader(duk_context* ctx, client_resources_loader&); +void dukx_put_client_loader(duk_context* ctx, mlk::client::loader&); -client_resources_loader& dukx_get_client_loader(duk_context* ctx); +mlk::client::loader& dukx_get_client_loader(duk_context* ctx); } // !mlk
--- a/libclient-js/malikania/js_color.cpp Sun Jan 22 10:11:17 2017 +0100 +++ b/libclient-js/malikania/js_color.cpp Sun Jan 22 11:07:36 2017 +0100 @@ -38,14 +38,14 @@ return static_cast<std::uint8_t>(value); } -color parse_string(duk_context* ctx, duk_idx_t index, bool required) +client::color parse_string(duk_context* ctx, duk_idx_t index, bool required) { assert(duk_is_string(ctx, index)); - color ret; + client::color ret; try { - ret = color(duk_get_string(ctx, index)); + ret = client::color(duk_get_string(ctx, index)); } catch (const std::exception &ex) { if (required) { duk_error(ctx, DUK_ERR_ERROR, "%s", ex.what()); @@ -55,7 +55,7 @@ return ret; } -color parse_object(duk_context* ctx, duk_idx_t index, bool required) +client::color parse_object(duk_context* ctx, duk_idx_t index, bool required) { assert(duk_is_object(ctx, index)); @@ -76,7 +76,7 @@ auto alpha = duk_is_number(ctx, -1) ? duk_to_int(ctx, -1) : 255; duk_pop(ctx); - return color( + return client::color( require("red"), require("green"), require("blue"), @@ -84,7 +84,7 @@ ); } -color parse(duk_context* ctx, duk_idx_t index, bool required, color ret = {}) +client::color parse(duk_context* ctx, duk_idx_t index, bool required, client::color ret = {}) { switch (duk_get_type(ctx, index)) { case DUK_TYPE_STRING: @@ -106,7 +106,7 @@ duk_ret_t constructor(duk_context* ctx) { - color obj; + client::color obj; /* * The constructor allows an additional signature that takes 4 number @@ -116,7 +116,7 @@ // Alpha is optional. auto alpha = duk_is_number(ctx, 3) ? duk_to_int(ctx, 3) : 255; - obj = color( + obj = client::color( clamp_component(ctx, duk_require_int(ctx, 0), true), clamp_component(ctx, duk_require_int(ctx, 1), true), clamp_component(ctx, duk_require_int(ctx, 2), true), @@ -144,22 +144,22 @@ } //! namespace -color dukx_get_color(duk_context* ctx, duk_idx_t index) +client::color dukx_get_color(duk_context* ctx, duk_idx_t index) { return parse(ctx, index, false); } -color dukx_require_color(duk_context* ctx, duk_idx_t index) +client::color dukx_require_color(duk_context* ctx, duk_idx_t index) { return parse(ctx, index, true); } -color dukx_optional_color(duk_context* ctx, duk_idx_t index, color def) +client::color dukx_optional_color(duk_context* ctx, duk_idx_t index, client::color def) { return parse(ctx, index, false, std::move(def)); } -void dukx_push_color(duk_context* ctx, const color& color) +void dukx_push_color(duk_context* ctx, const client::color& color) { dukx_stack_assert sa(ctx, 1); @@ -167,7 +167,7 @@ dukx_put_color(ctx, color); } -void dukx_put_color(duk_context* ctx, const color &color) +void dukx_put_color(duk_context* ctx, const client::color &color) { assert(duk_is_object(ctx, -1));
--- a/libclient-js/malikania/js_color.hpp Sun Jan 22 10:11:17 2017 +0100 +++ b/libclient-js/malikania/js_color.hpp Sun Jan 22 11:07:36 2017 +0100 @@ -37,8 +37,8 @@ * It can also takes strings like "#rrggbbaa" and SVG names. */ -#include "color.hpp" -#include "duktape.hpp" +#include <malikania/client/color.hpp> +#include <malikania/duktape.hpp> namespace mlk { @@ -50,7 +50,7 @@ * \param ctx the context * \param index the index */ -color dukx_get_color(duk_context* ctx, duk_idx_t index); +client::color dukx_get_color(duk_context* ctx, duk_idx_t index); /** * Require a color. @@ -60,7 +60,7 @@ * \param ctx the context * \param index the index */ -color dukx_require_color(duk_context* ctx, duk_idx_t index); +client::color dukx_require_color(duk_context* ctx, duk_idx_t index); /** * Like get, but return the default value only if the value at the given @@ -70,7 +70,7 @@ * \param index the index * \param def the default value */ -color dukx_optional_color(duk_context* ctx, duk_idx_t index, color def); +client::color dukx_optional_color(duk_context* ctx, duk_idx_t index, client::color def); /** * Push the color as object. @@ -78,7 +78,7 @@ * \param ctx the context * \param color the color */ -void dukx_push_color(duk_context* ctx, const color& color); +void dukx_push_color(duk_context* ctx, const client::color& color); /** * Put the color properties into the object at the top of the stack. @@ -87,7 +87,7 @@ * \param ctx the context * \param color the color */ -void dukx_put_color(duk_context* ctx, const color& color); +void dukx_put_color(duk_context* ctx, const client::color& color); void dukx_load_color(duk_context* ctx);
--- a/libclient-js/malikania/js_font.cpp Sun Jan 22 10:11:17 2017 +0100 +++ b/libclient-js/malikania/js_font.cpp Sun Jan 22 11:07:36 2017 +0100 @@ -28,7 +28,7 @@ const std::string signature("\xff""\xff""malikania-font-ptr"); -font& self(duk_context* ctx) +client::font& self(duk_context* ctx) { dukx_stack_assert sa(ctx); @@ -41,7 +41,7 @@ duk_error(ctx, DUK_ERR_TYPE_ERROR, "not a font object"); } - return *static_cast<font*>(ptr); + return *static_cast<client::font*>(ptr); } duk_ret_t constructor(duk_context* ctx) @@ -62,7 +62,7 @@ } duk_push_this(ctx); - duk_push_pointer(ctx, new font(loader.load_font(id, static_cast<unsigned>(size)))); + duk_push_pointer(ctx, new client::font(loader.load_font(id, static_cast<unsigned>(size)))); duk_put_prop_string(ctx, -2, signature.c_str()); duk_pop(ctx); } catch (const std::exception &ex) { @@ -107,7 +107,7 @@ #endif -font& dukx_require_font(duk_context* ctx, duk_idx_t index) +client::font& dukx_require_font(duk_context* ctx, duk_idx_t index) { assert(ctx); @@ -121,7 +121,7 @@ duk_error(ctx, DUK_ERR_TYPE_ERROR, "not a font object"); } - return *static_cast<font*>(ptr); + return *static_cast<client::font*>(ptr); } void dukx_load_font(duk_context* ctx)
--- a/libclient-js/malikania/js_font.hpp Sun Jan 22 10:11:17 2017 +0100 +++ b/libclient-js/malikania/js_font.hpp Sun Jan 22 11:07:36 2017 +0100 @@ -19,8 +19,8 @@ #ifndef MALIKANIA_JS_FONT_HPP #define MALIKANIA_JS_FONT_HPP -#include "duktape.hpp" -#include "font.hpp" +#include <malikania/client/font.hpp> +#include <malikania/duktape.hpp> namespace mlk { @@ -28,7 +28,7 @@ void dukx_new_font(duk_context *ctx, Font *font); #endif -font& dukx_require_font(duk_context* ctx, duk_idx_t index); +client::font& dukx_require_font(duk_context* ctx, duk_idx_t index); void dukx_load_font(duk_context* ctx);
--- a/libclient-js/malikania/js_image.cpp Sun Jan 22 10:11:17 2017 +0100 +++ b/libclient-js/malikania/js_image.cpp Sun Jan 22 11:07:36 2017 +0100 @@ -29,7 +29,7 @@ const std::string signature("\xff""\xff""malikania-image-ptr"); -image& self(duk_context* ctx) +client::image& self(duk_context* ctx) { dukx_stack_assert sa(ctx); @@ -42,7 +42,7 @@ duk_error(ctx, DUK_ERR_TYPE_ERROR, "not an Animator object"); } - return *static_cast<image *>(ptr); + return *static_cast<client::image *>(ptr); } duk_ret_t size(duk_context* ctx) @@ -86,7 +86,7 @@ auto& loader = dukx_get_client_loader(ctx); duk_push_this(ctx); - duk_push_pointer(ctx, new image(loader.load_image(duk_require_string(ctx, 0)))); + duk_push_pointer(ctx, new client::image(loader.load_image(duk_require_string(ctx, 0)))); duk_put_prop_string(ctx, -2, signature.c_str()); duk_push_string(ctx, "size"); duk_push_c_function(ctx, size, 0); @@ -106,7 +106,7 @@ } // !namespace -void dukx_new_image(duk_context* ctx, image *image) +void dukx_new_image(duk_context* ctx, client::image *image) { assert(ctx); assert(image);
--- a/libclient-js/malikania/js_image.hpp Sun Jan 22 10:11:17 2017 +0100 +++ b/libclient-js/malikania/js_image.hpp Sun Jan 22 11:07:36 2017 +0100 @@ -19,8 +19,8 @@ #ifndef MALIKANIA_JS_IMAGE_HPP #define MALIKANIA_JS_IMAGE_HPP -#include "duktape.hpp" -#include "image.hpp" +#include <malikania/client/image.hpp> +#include <malikania/duktape.hpp> namespace mlk {
--- a/libclient-js/malikania/js_line.cpp Sun Jan 22 10:11:17 2017 +0100 +++ b/libclient-js/malikania/js_line.cpp Sun Jan 22 11:07:36 2017 +0100 @@ -26,10 +26,10 @@ duk_ret_t constructor(duk_context* ctx) { - line obj; + client::line obj; if (duk_get_top(ctx) == 4) { - obj = line( + obj = client::line( duk_get_int(ctx, 0), duk_get_int(ctx, 1), duk_get_int(ctx, 2), @@ -56,7 +56,7 @@ } // !namespace -line dukx_get_line(duk_context* ctx, duk_idx_t index) +client::line dukx_get_line(duk_context* ctx, duk_idx_t index) { auto get = [&] (auto name) { dukx_stack_assert sa(ctx); @@ -68,10 +68,10 @@ return v; }; - return line(get("x1"), get("y1"), get("x2"), get("y2")); + return client::line(get("x1"), get("y1"), get("x2"), get("y2")); } -line dukx_require_line(duk_context* ctx, duk_idx_t index) +client::line dukx_require_line(duk_context* ctx, duk_idx_t index) { auto get = [&] (auto prop) { if (!duk_has_prop_string(ctx, index, prop)) { @@ -92,15 +92,15 @@ return value; }; - return line(get("x1"), get("y1"), get("x2"), get("y2")); + return client::line(get("x1"), get("y1"), get("x2"), get("y2")); } -line dukx_optional_line(duk_context* ctx, duk_idx_t index, line def) +client::line dukx_optional_line(duk_context* ctx, duk_idx_t index, client::line def) { return duk_is_object(ctx, index) ? dukx_get_line(ctx, index) : def; } -void dukx_push_line(duk_context* ctx, const line& line) +void dukx_push_line(duk_context* ctx, const client::line& line) { dukx_stack_assert sa(ctx, 1); @@ -108,7 +108,7 @@ dukx_put_line(ctx, line); } -void dukx_put_line(duk_context* ctx, const line& line) +void dukx_put_line(duk_context* ctx, const client::line& line) { assert(duk_is_object(ctx, -1));
--- a/libclient-js/malikania/js_line.hpp Sun Jan 22 10:11:17 2017 +0100 +++ b/libclient-js/malikania/js_line.hpp Sun Jan 22 11:07:36 2017 +0100 @@ -35,8 +35,8 @@ * ```` */ -#include "duktape.hpp" -#include "line.hpp" +#include <malikania/duktape.hpp> +#include <malikania/client/line.hpp> namespace mlk { @@ -47,7 +47,7 @@ * \param index the index * \return the line */ -line dukx_get_line(duk_context* ctx, duk_idx_t index); +client::line dukx_get_line(duk_context* ctx, duk_idx_t index); /** * Require a line. @@ -58,7 +58,7 @@ * \param index the index * \return the line */ -line dukx_require_line(duk_context* ctx, duk_idx_t index); +client::line dukx_require_line(duk_context* ctx, duk_idx_t index); /** * Like get but return def if the value at the given index is not an object. @@ -68,7 +68,7 @@ * \param def the default value * \return the line */ -line dukx_optional_line(duk_context* ctx, duk_idx_t index, line def); +client::line dukx_optional_line(duk_context* ctx, duk_idx_t index, client::line def); /** * Push the line as object. @@ -76,7 +76,7 @@ * \param ctx the context * \param line the line */ -void dukx_push_line(duk_context* ctx, const line &line); +void dukx_push_line(duk_context* ctx, const client::line &line); /** * Put the line properties into the object at the top of the stack. @@ -84,7 +84,7 @@ * \param ctx the context * \param line the line */ -void dukx_put_line(duk_context* ctx, const line &line); +void dukx_put_line(duk_context* ctx, const client::line &line); void dukx_load_line(duk_context* ctx);
--- a/libclient-js/malikania/js_point.cpp Sun Jan 22 10:11:17 2017 +0100 +++ b/libclient-js/malikania/js_point.cpp Sun Jan 22 11:07:36 2017 +0100 @@ -24,7 +24,7 @@ namespace { -point parse(duk_context* ctx, duk_idx_t index, bool required, point ret = {}) +client::point parse(duk_context* ctx, duk_idx_t index, bool required, client::point ret = {}) { dukx_stack_assert sa(ctx); @@ -46,7 +46,7 @@ y = duk_to_int(ctx, -1); duk_pop(ctx); - ret = point(x, y); + ret = client::point(x, y); } else if (required) { duk_error(ctx, DUK_ERR_TYPE_ERROR, "point object expected"); } @@ -56,10 +56,10 @@ duk_ret_t constructor(duk_context* ctx) { - point obj; + client::point obj; if (duk_get_top(ctx) == 2) { - obj = point(duk_require_int(ctx, 0), duk_require_int(ctx, 1)); + obj = client::point(duk_require_int(ctx, 0), duk_require_int(ctx, 1)); } else if (duk_get_top(ctx) == 1) { obj = parse(ctx, 0, true); } @@ -82,22 +82,22 @@ } // !namespace -point dukx_get_point(duk_context* ctx, duk_idx_t index) +client::point dukx_get_point(duk_context* ctx, duk_idx_t index) { return parse(ctx, index, false); } -point dukx_require_point(duk_context* ctx, duk_idx_t index) +client::point dukx_require_point(duk_context* ctx, duk_idx_t index) { return parse(ctx, index, true); } -point dukx_optional_point(duk_context* ctx, duk_idx_t index, point def) +client::point dukx_optional_point(duk_context* ctx, duk_idx_t index, client::point def) { return parse(ctx, index, false, std::move(def)); } -void dukx_push_point(duk_context* ctx, const point &point) +void dukx_push_point(duk_context* ctx, const client::point &point) { dukx_stack_assert sa(ctx, 1); @@ -105,7 +105,7 @@ dukx_put_point(ctx, point); } -void dukx_put_point(duk_context* ctx, const point& point) +void dukx_put_point(duk_context* ctx, const client::point& point) { assert(duk_is_object(ctx, -1));
--- a/libclient-js/malikania/js_point.hpp Sun Jan 22 10:11:17 2017 +0100 +++ b/libclient-js/malikania/js_point.hpp Sun Jan 22 11:07:36 2017 +0100 @@ -1,5 +1,5 @@ /* - * js_point.hpp -- point description (JavaScript binding) + * js_client::point.hpp -- client::point description (JavaScript binding) * * Copyright (c) 2013-2017 Malikania Authors * @@ -19,18 +19,18 @@ #ifndef MALIKANIA_JS_POINT_HPP #define MALIKANIA_JS_POINT_HPP -#include "duktape.hpp" -#include "point.hpp" +#include <malikania/client/point.hpp> +#include <malikania/duktape.hpp> namespace mlk { -point dukx_require_point(duk_context* ctx, duk_idx_t index); +client::point dukx_require_point(duk_context* ctx, duk_idx_t index); -point dukx_get_point(duk_context* ctx, duk_idx_t index); +client::point dukx_get_point(duk_context* ctx, duk_idx_t index); -void dukx_push_point(duk_context* ctx, const point& point); +void dukx_push_point(duk_context* ctx, const client::point& point); -void dukx_put_point(duk_context* ctx, const point& point); +void dukx_put_point(duk_context* ctx, const client::point& point); void dukx_load_point(duk_context* ctx);
--- a/libclient-js/malikania/js_rectangle.cpp Sun Jan 22 10:11:17 2017 +0100 +++ b/libclient-js/malikania/js_rectangle.cpp Sun Jan 22 11:07:36 2017 +0100 @@ -37,7 +37,7 @@ return static_cast<unsigned>(value); } -rectangle parse(duk_context* ctx, duk_idx_t index, bool required, rectangle rect = {}) +client::rectangle parse(duk_context* ctx, duk_idx_t index, bool required, client::rectangle rect = {}) { dukx_stack_assert sa(ctx); @@ -61,7 +61,7 @@ return value; }; - rect = rectangle(get("x"), get("y"), + rect = client::rectangle(get("x"), get("y"), clamp(ctx, get("width"), required), clamp(ctx, get("height"), required)); } else if (required) { duk_error(ctx, DUK_ERR_TYPE_ERROR, "rectangle object expected"); @@ -72,10 +72,10 @@ duk_ret_t constructor(duk_context* ctx) { - rectangle rect; + client::rectangle rect; if (duk_get_top(ctx) == 4) { - rect = rectangle( + rect = client::rectangle( duk_require_int(ctx, 0), duk_require_int(ctx, 1), clamp(ctx, duk_require_int(ctx, 2), true), @@ -103,22 +103,22 @@ } // !namespace -rectangle dukx_get_rect(duk_context* ctx, duk_idx_t index) +client::rectangle dukx_get_rect(duk_context* ctx, duk_idx_t index) { return parse(ctx, index, false); } -rectangle dukx_require_rect(duk_context* ctx, duk_idx_t index) +client::rectangle dukx_require_rect(duk_context* ctx, duk_idx_t index) { return parse(ctx, index, true); } -rectangle dukx_optional_rect(duk_context* ctx, duk_idx_t index, rectangle def) +client::rectangle dukx_optional_rect(duk_context* ctx, duk_idx_t index, client::rectangle def) { return parse(ctx, index, false, std::move(def)); } -void dukx_push_rect(duk_context* ctx, const rectangle& rect) +void dukx_push_rect(duk_context* ctx, const client::rectangle& rect) { dukx_stack_assert sa(ctx, 1); @@ -126,7 +126,7 @@ dukx_put_rect(ctx, rect); } -void dukx_put_rect(duk_context* ctx, const rectangle& rect) +void dukx_put_rect(duk_context* ctx, const client::rectangle& rect) { assert(duk_is_object(ctx, -1));
--- a/libclient-js/malikania/js_rectangle.hpp Sun Jan 22 10:11:17 2017 +0100 +++ b/libclient-js/malikania/js_rectangle.hpp Sun Jan 22 11:07:36 2017 +0100 @@ -35,8 +35,8 @@ * ```` */ -#include "duktape.hpp" -#include "rectangle.hpp" +#include <malikania/client/rectangle.hpp> +#include <malikania/duktape.hpp> namespace mlk { @@ -49,7 +49,7 @@ * \param index the value index * \return the rectangle */ -rectangle dukx_get_rect(duk_context* ctx, duk_idx_t index); +client::rectangle dukx_get_rect(duk_context* ctx, duk_idx_t index); /** * Require a rectangle. @@ -60,7 +60,7 @@ * \param index the index * \return the rectangle */ -rectangle dukx_require_rect(duk_context* ctx, duk_idx_t index); +client::rectangle dukx_require_rect(duk_context* ctx, duk_idx_t index); /** * Like get but return the default value if the value at the given index is not an object or invalid @@ -70,7 +70,7 @@ * \param def the default value * \return the rectangle */ -rectangle dukx_optional_rect(duk_context* ctx, duk_idx_t index, rectangle def); +client::rectangle dukx_optional_rect(duk_context* ctx, duk_idx_t index, client::rectangle def); /** * Push the rectangle as object. @@ -78,7 +78,7 @@ * \param ctx the context * \param rect the rectangle */ -void dukx_push_rect(duk_context* ctx, const rectangle &rect); +void dukx_push_rect(duk_context* ctx, const client::rectangle &rect); /** * Put the rectangle properties into the object at the top of the stack. @@ -86,7 +86,7 @@ * \param ctx the context * \param rect the rectangle */ -void dukx_put_rect(duk_context* ctx, const rectangle& rect); +void dukx_put_rect(duk_context* ctx, const client::rectangle& rect); void dukx_load_rect(duk_context* ctx);
--- a/libclient-js/malikania/js_size.cpp Sun Jan 22 10:11:17 2017 +0100 +++ b/libclient-js/malikania/js_size.cpp Sun Jan 22 11:07:36 2017 +0100 @@ -24,7 +24,7 @@ namespace { -size parse(duk_context* ctx, duk_idx_t index, bool required, size ret = {}) +client::size parse(duk_context* ctx, duk_idx_t index, bool required, client::size ret = {}) { dukx_stack_assert sa(ctx); @@ -52,7 +52,7 @@ duk_error(ctx, DUK_ERR_RANGE_ERROR, "height can not be negative"); } - ret = size(width, height); + ret = client::size(width, height); } else if (required) { duk_error(ctx, DUK_ERR_TYPE_ERROR, "size object expected"); } @@ -62,7 +62,7 @@ duk_ret_t constructor(duk_context* ctx) { - size obj; + client::size obj; if (duk_get_top(ctx) == 2) { int width; @@ -75,7 +75,7 @@ duk_error(ctx, DUK_ERR_RANGE_ERROR, "argument #1 can not be negative"); } - obj = size(static_cast<unsigned>(width), static_cast<unsigned>(height)); + obj = client::size(static_cast<unsigned>(width), static_cast<unsigned>(height)); } else if (duk_get_top(ctx) == 1) { obj = parse(ctx, 0, true); } @@ -98,22 +98,22 @@ } // !namespace -size dukx_get_size(duk_context* ctx, duk_idx_t index) +client::size dukx_get_size(duk_context* ctx, duk_idx_t index) { return parse(ctx, index, false); } -size dukx_require_size(duk_context* ctx, duk_idx_t index) +client::size dukx_require_size(duk_context* ctx, duk_idx_t index) { return parse(ctx, index, true); } -size dukx_optional_size(duk_context* ctx, duk_idx_t index, size def) +client::size dukx_optional_size(duk_context* ctx, duk_idx_t index, client::size def) { return parse(ctx, index, false, std::move(def)); } -void dukx_push_size(duk_context* ctx, const size& size) +void dukx_push_size(duk_context* ctx, const client::size& size) { dukx_stack_assert sa(ctx, 1); @@ -121,7 +121,7 @@ dukx_put_size(ctx, size); } -void dukx_put_size(duk_context* ctx, const size& size) +void dukx_put_size(duk_context* ctx, const client::size& size) { assert(duk_is_object(ctx, -1));
--- a/libclient-js/malikania/js_size.hpp Sun Jan 22 10:11:17 2017 +0100 +++ b/libclient-js/malikania/js_size.hpp Sun Jan 22 11:07:36 2017 +0100 @@ -33,8 +33,8 @@ * ```` */ -#include "duktape.hpp" -#include "size.hpp" +#include <malikania/duktape.hpp> +#include <malikania/client/size.hpp> namespace mlk { @@ -47,7 +47,7 @@ * \param index the value index * \return the size */ -size dukx_get_size(duk_context* ctx, duk_idx_t index); +client::size dukx_get_size(duk_context* ctx, duk_idx_t index); /** * Require a size @@ -58,7 +58,7 @@ * \param index the index * \return the size */ -size dukx_require_size(duk_context* ctx, duk_idx_t index); +client::size dukx_require_size(duk_context* ctx, duk_idx_t index); /** * Like get but return the default value if the value at the given index is not an object. @@ -68,7 +68,7 @@ * \param def the default value * \return the size */ -size dukx_optional_size(duk_context* ctx, duk_idx_t index, size def); +client::size dukx_optional_size(duk_context* ctx, duk_idx_t index, client::size def); /** * Push the size as object. @@ -76,7 +76,7 @@ * \param ctx the context * \param size the size */ -void dukx_push_size(duk_context* ctx, const size& size); +void dukx_push_size(duk_context* ctx, const client::size& size); /** * Put the size properties into the object at the top of the stack. @@ -84,7 +84,7 @@ * \param ctx the context * \param size the size */ -void dukx_put_size(duk_context* ctx, const size& size); +void dukx_put_size(duk_context* ctx, const client::size& size); void dukx_load_size(duk_context* ctx);
--- a/libclient-js/malikania/js_sprite.cpp Sun Jan 22 10:11:17 2017 +0100 +++ b/libclient-js/malikania/js_sprite.cpp Sun Jan 22 11:07:36 2017 +0100 @@ -28,7 +28,7 @@ const std::string signature("\xff""\xff""malikania-sprite-ptr"); -sprite& self(duk_context *ctx) +client::sprite& self(duk_context *ctx) { dukx_stack_assert sa(ctx); @@ -41,7 +41,7 @@ duk_error(ctx, DUK_ERR_TYPE_ERROR, "not a sprite object"); } - return *static_cast<sprite*>(ptr); + return *static_cast<client::sprite*>(ptr); } duk_ret_t cell(duk_context* ctx) @@ -90,7 +90,7 @@ auto sp = loader.load_sprite(duk_require_string(ctx, 0)); duk_push_this(ctx); - duk_push_pointer(ctx, new sprite(std::move(sp))); + duk_push_pointer(ctx, new client::sprite(std::move(sp))); duk_put_prop_string(ctx, -2, signature.c_str()); // Cell.
--- a/libclient-js/malikania/js_sprite.hpp Sun Jan 22 10:11:17 2017 +0100 +++ b/libclient-js/malikania/js_sprite.hpp Sun Jan 22 11:07:36 2017 +0100 @@ -19,8 +19,8 @@ #ifndef MALIKANIA_JS_SPRITE_HPP #define MALIKANIA_JS_SPRITE_HPP -#include "duktape.hpp" -#include "sprite.hpp" +#include <malikania/duktape.hpp> +#include <malikania/client/sprite.hpp> namespace mlk {
--- a/libclient-js/malikania/js_window.cpp Sun Jan 22 10:11:17 2017 +0100 +++ b/libclient-js/malikania/js_window.cpp Sun Jan 22 11:07:36 2017 +0100 @@ -32,7 +32,7 @@ const std::string signature("\xff""\xff""malikania-window-ptr"); const std::string prototype("\xff""\xff""malikania-window-prototype"); -window& self(duk_context* ctx) +client::window& self(duk_context* ctx) { dukx_stack_assert sa(ctx); @@ -45,7 +45,7 @@ duk_error(ctx, DUK_ERR_TYPE_ERROR, "not an Window object"); } - return *static_cast<window*>(ptr); + return *static_cast<client::window*>(ptr); } duk_ret_t constructor(duk_context* ctx) @@ -59,7 +59,7 @@ // TODO: add parameters. try { duk_push_this(ctx); - duk_push_pointer(ctx, new window); + duk_push_pointer(ctx, new client::window); duk_put_prop_string(ctx, -2, signature.c_str()); duk_pop(ctx); } catch (const std::exception &ex) { @@ -179,7 +179,7 @@ if (!rect.is_null()) { win.draw_text(text, font, rect); } else { - win.draw_text(text, font, point{rect.x(), rect.y()}); + win.draw_text(text, font, client::point{rect.x(), rect.y()}); } } catch (const std::exception &ex) { duk_error(ctx, DUK_ERR_ERROR, "%s", ex.what()); @@ -257,7 +257,7 @@ #endif -window& dukx_require_window(duk_context* ctx, duk_idx_t index) +client::window& dukx_require_window(duk_context* ctx, duk_idx_t index) { assert(ctx); @@ -271,7 +271,7 @@ duk_error(ctx, DUK_ERR_TYPE_ERROR, "not a Window object"); } - return *static_cast<window*>(ptr); + return *static_cast<client::window*>(ptr); } void dukx_load_window(duk_context* ctx)
--- a/libclient-js/malikania/js_window.hpp Sun Jan 22 10:11:17 2017 +0100 +++ b/libclient-js/malikania/js_window.hpp Sun Jan 22 11:07:36 2017 +0100 @@ -19,12 +19,12 @@ #ifndef MALIKANIA_JS_WINDOW_HPP #define MALIKANIA_JS_WINDOW_HPP -#include "duktape.hpp" -#include "window.hpp" +#include <malikania/client/window.hpp> +#include <malikania/duktape.hpp> namespace mlk { -window& dukx_require_window(duk_context* ctx, duk_idx_t index); +client::window& dukx_require_window(duk_context* ctx, duk_idx_t index); void dukx_load_window(duk_context* ctx);
--- a/libclient/CMakeLists.txt Sun Jan 22 10:11:17 2017 +0100 +++ b/libclient/CMakeLists.txt Sun Jan 22 11:07:36 2017 +0100 @@ -20,51 +20,50 @@ set( HEADERS - ${libmlk-client_SOURCE_DIR}/malikania/animation.hpp - ${libmlk-client_SOURCE_DIR}/malikania/animator.hpp - ${libmlk-client_SOURCE_DIR}/malikania/button.hpp - ${libmlk-client_SOURCE_DIR}/malikania/color.hpp - ${libmlk-client_SOURCE_DIR}/malikania/font.hpp - ${libmlk-client_SOURCE_DIR}/malikania/frame.hpp -# ${libmlk-client_SOURCE_DIR}/malikania/grid_layout.hpp - ${libmlk-client_SOURCE_DIR}/malikania/image.hpp - ${libmlk-client_SOURCE_DIR}/malikania/key.hpp - ${libmlk-client_SOURCE_DIR}/malikania/label.hpp - ${libmlk-client_SOURCE_DIR}/malikania/layout.hpp - ${libmlk-client_SOURCE_DIR}/malikania/line.hpp - ${libmlk-client_SOURCE_DIR}/malikania/mouse.hpp - ${libmlk-client_SOURCE_DIR}/malikania/point.hpp - ${libmlk-client_SOURCE_DIR}/malikania/rectangle.hpp - ${libmlk-client_SOURCE_DIR}/malikania/size.hpp - ${libmlk-client_SOURCE_DIR}/malikania/sprite.hpp - ${libmlk-client_SOURCE_DIR}/malikania/theme.hpp - ${libmlk-client_SOURCE_DIR}/malikania/unique_layout.hpp - ${libmlk-client_SOURCE_DIR}/malikania/widget.hpp - ${libmlk-client_SOURCE_DIR}/malikania/window.hpp - ${libmlk-client_SOURCE_DIR}/malikania/${WITH_BACKEND_DIR}/font_backend.hpp - ${libmlk-client_SOURCE_DIR}/malikania/${WITH_BACKEND_DIR}/image_backend.hpp - ${libmlk-client_SOURCE_DIR}/malikania/${WITH_BACKEND_DIR}/window_backend.hpp + ${libmlk-client_SOURCE_DIR}/malikania/client/animation.hpp + ${libmlk-client_SOURCE_DIR}/malikania/client/animator.hpp + ${libmlk-client_SOURCE_DIR}/malikania/client/button.hpp + ${libmlk-client_SOURCE_DIR}/malikania/client/color.hpp + ${libmlk-client_SOURCE_DIR}/malikania/client/font.hpp + ${libmlk-client_SOURCE_DIR}/malikania/client/frame.hpp + ${libmlk-client_SOURCE_DIR}/malikania/client/image.hpp + ${libmlk-client_SOURCE_DIR}/malikania/client/key.hpp + ${libmlk-client_SOURCE_DIR}/malikania/client/label.hpp + ${libmlk-client_SOURCE_DIR}/malikania/client/layout.hpp + ${libmlk-client_SOURCE_DIR}/malikania/client/line.hpp + ${libmlk-client_SOURCE_DIR}/malikania/client/loader.hpp + ${libmlk-client_SOURCE_DIR}/malikania/client/mouse.hpp + ${libmlk-client_SOURCE_DIR}/malikania/client/point.hpp + ${libmlk-client_SOURCE_DIR}/malikania/client/rectangle.hpp + ${libmlk-client_SOURCE_DIR}/malikania/client/size.hpp + ${libmlk-client_SOURCE_DIR}/malikania/client/sprite.hpp + ${libmlk-client_SOURCE_DIR}/malikania/client/theme.hpp + ${libmlk-client_SOURCE_DIR}/malikania/client/unique_layout.hpp + ${libmlk-client_SOURCE_DIR}/malikania/client/widget.hpp + ${libmlk-client_SOURCE_DIR}/malikania/client/window.hpp + ${libmlk-client_SOURCE_DIR}/malikania/client/${WITH_BACKEND_DIR}/font_backend.hpp + ${libmlk-client_SOURCE_DIR}/malikania/client/${WITH_BACKEND_DIR}/image_backend.hpp + ${libmlk-client_SOURCE_DIR}/malikania/client/${WITH_BACKEND_DIR}/window_backend.hpp ) set( SOURCES - ${libmlk-client_SOURCE_DIR}/malikania/animator.cpp - ${libmlk-client_SOURCE_DIR}/malikania/button.cpp - ${libmlk-client_SOURCE_DIR}/malikania/client_resources_loader.cpp - ${libmlk-client_SOURCE_DIR}/malikania/color.cpp - ${libmlk-client_SOURCE_DIR}/malikania/font.cpp - ${libmlk-client_SOURCE_DIR}/malikania/frame.cpp -# ${libmlk-client_SOURCE_DIR}/malikania/grid_layout.cpp - ${libmlk-client_SOURCE_DIR}/malikania/image.cpp - ${libmlk-client_SOURCE_DIR}/malikania/label.cpp - ${libmlk-client_SOURCE_DIR}/malikania/sprite.cpp - ${libmlk-client_SOURCE_DIR}/malikania/theme.cpp - ${libmlk-client_SOURCE_DIR}/malikania/unique_layout.cpp - ${libmlk-client_SOURCE_DIR}/malikania/widget.cpp - ${libmlk-client_SOURCE_DIR}/malikania/window.cpp - ${libmlk-client_SOURCE_DIR}/malikania/${WITH_BACKEND_DIR}/font_backend.cpp - ${libmlk-client_SOURCE_DIR}/malikania/${WITH_BACKEND_DIR}/image_backend.cpp - ${libmlk-client_SOURCE_DIR}/malikania/${WITH_BACKEND_DIR}/window_backend.cpp + ${libmlk-client_SOURCE_DIR}/malikania/client/animator.cpp + ${libmlk-client_SOURCE_DIR}/malikania/client/button.cpp + ${libmlk-client_SOURCE_DIR}/malikania/client/loader.cpp + ${libmlk-client_SOURCE_DIR}/malikania/client/color.cpp + ${libmlk-client_SOURCE_DIR}/malikania/client/font.cpp + ${libmlk-client_SOURCE_DIR}/malikania/client/frame.cpp + ${libmlk-client_SOURCE_DIR}/malikania/client/image.cpp + ${libmlk-client_SOURCE_DIR}/malikania/client/label.cpp + ${libmlk-client_SOURCE_DIR}/malikania/client/sprite.cpp + ${libmlk-client_SOURCE_DIR}/malikania/client/theme.cpp + ${libmlk-client_SOURCE_DIR}/malikania/client/unique_layout.cpp + ${libmlk-client_SOURCE_DIR}/malikania/client/widget.cpp + ${libmlk-client_SOURCE_DIR}/malikania/client/window.cpp + ${libmlk-client_SOURCE_DIR}/malikania/client/${WITH_BACKEND_DIR}/font_backend.cpp + ${libmlk-client_SOURCE_DIR}/malikania/client/${WITH_BACKEND_DIR}/image_backend.cpp + ${libmlk-client_SOURCE_DIR}/malikania/client/${WITH_BACKEND_DIR}/window_backend.cpp ) if (WITH_BACKEND MATCHES "SDL") @@ -93,8 +92,10 @@ TARGET libmlk-client SOURCES ${HEADERS} ${SOURCES} ASSETS ${libmlk-client_SOURCE_DIR}/assets/dejavu_sans.ttf + PRIVATE_INCLUDES + $<BUILD_INTERFACE:${libmlk-client_SOURCE_DIR}/malikania/client> PUBLIC_INCLUDES - $<BUILD_INTERFACE:${libmlk-client_SOURCE_DIR}/malikania/${WITH_BACKEND_DIR}> + $<BUILD_INTERFACE:${libmlk-client_SOURCE_DIR}/malikania/client/${WITH_BACKEND_DIR}> $<BUILD_INTERFACE:${libmlk-client_SOURCE_DIR}/malikania> ${INCLUDES} LIBRARIES libmlk-common ${LIBRARIES}
--- a/libclient/malikania/animation.hpp Sun Jan 22 10:11:17 2017 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,153 +0,0 @@ -/* - * animation.hpp -- animation description - * - * Copyright (c) 2013-2017 Malikania Authors - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef MALIKANIA_ANIMATION_HPP -#define MALIKANIA_ANIMATION_HPP - -/** - * \file animation.hpp - * \brief Describe an animation. - */ - -#include <cassert> -#include <cstdint> -#include <memory> -#include <vector> - -#include "sprite.hpp" - -namespace mlk { - -class window; - -/** - * \brief Animation frame description. - * - * A frame is a duration before switching to the next sprite cell. It is - * currently implemented as a class for future usage. - */ -class animation_frame { -private: - std::uint16_t m_delay; - -public: - /** - * Construct a frame. - * - * \param delay the optional delay - */ - inline animation_frame(std::uint16_t delay = 100) noexcept - : m_delay(delay) - { - } - - /** - * Get the the delay. - * - * \return the delay - */ - inline std::uint16_t delay() const noexcept - { - return m_delay; - } -}; - -/** - * \brief List of frames. - */ -using animation_frames = std::vector<animation_frame>; - -/** - * \brief Animation description. - * - * An animation is a sprite with a set of frames containing a delay for showing - * all sprites in a specific amount of time. - * - * Because an animation contains an image, a state (time, current cell) it must - * be constructed with an animator object so the user is able to use the same - * animation on different parts of the screen without having to duplicate - * resources. - * - * \see Animator - */ -class animation { -private: - mlk::sprite m_sprite; - mlk::animation_frames m_frames; - -public: - /** - * Create an animation. - * - * \param sprite the sprite image - * \param frames the frames to show - */ - inline animation(mlk::sprite sprite, animation_frames frames) noexcept - : m_sprite(std::move(sprite)) - , m_frames(std::move(frames)) - { - } - - /** - * Get the underlying sprite. - * - * \return the sprite - */ - inline const mlk::sprite& sprite() const noexcept - { - return m_sprite; - } - - /** - * Overloaded function. - * - * \return the sprite - */ - inline mlk::sprite& sprite() noexcept - { - return m_sprite; - } - - /** - * Get the frames. - * - * \return the frames - */ - inline const animation_frames& frames() const noexcept - { - return m_frames; - } - - /** - * Access a frame. - * - * \pre index < number of frames - * \param index the index - * \return the frame - */ - inline const animation_frame& operator[](unsigned index) const noexcept - { - assert(index < m_frames.size()); - - return m_frames[index]; - } -}; - -} // !mlk - -#endif // !MALIKANIA_ANIMATION_HPP
--- a/libclient/malikania/animator.cpp Sun Jan 22 10:11:17 2017 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,52 +0,0 @@ -/* - * animator.cpp -- animation drawing object - * - * Copyright (c) 2013-2017 Malikania Authors - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "animation.hpp" -#include "animator.hpp" - -namespace mlk { - -animator::animator(animation& animation) noexcept - : m_animation(animation) -{ -} - -void animator::update() noexcept -{ - auto total = m_animation.sprite().rows() * m_animation.sprite().columns(); - - if (m_current >= total) { - return; - } - - if (m_timer.elapsed().wall / 1000000LL >= m_animation[m_current].delay()) { - m_current ++; - m_timer.start(); - } -} - -void animator::draw(window& window, const point& point) -{ - if (m_current >= m_animation.sprite().rows() * m_animation.sprite().columns()) { - return; - } - - m_animation.sprite().draw(window, m_current, point); -} - -} // !mlk
--- a/libclient/malikania/animator.hpp Sun Jan 22 10:11:17 2017 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,74 +0,0 @@ -/* - * animator.hpp -- animation drawing object - * - * Copyright (c) 2013-2017 Malikania Authors - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef MALIKANIA_ANIMATOR_HPP -#define MALIKANIA_ANIMATOR_HPP - -#include <boost/timer/timer.hpp> - -/** - * \file animator.hpp - * \brief Draw animations. - */ - -namespace mlk { - -class animation; -class point; -class window; - -/** - * \brief Object for drawing animations. - * - * The animator contains an animation and a state. - */ -class animator { -private: - boost::timer::cpu_timer m_timer; - animation& m_animation; - unsigned m_current{0}; - -public: - /** - * Construct an animator. - * - * \pre animation must not be null - * \param animation the animation - */ - animator(animation& animation) noexcept; - - /** - * Update the animator state. - * - * This function should be called in the main loop to update the cell to - * draw before calling draw(). - */ - void update() noexcept; - - /** - * Draw the animation. - * - * \param window the window - * \param position the position in the window - */ - void draw(window& window, const point& position); -}; - -} // !mlk - -#endif // !MALIKANIA_ANIMATOR_HPP
--- a/libclient/malikania/backend/sdl/font_backend.cpp Sun Jan 22 10:11:17 2017 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,57 +0,0 @@ -/* - * font_backend.cpp -- font object (SDL2 implementation) - * - * Copyright (c) 2013-2017 Malikania Authors - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <malikania/backend/sdl/sdl_util.hpp> - -#include <malikania/size.hpp> -#include <malikania/font.hpp> - -#include "font_backend.hpp" - -using namespace std::string_literals; - -namespace mlk { - -font::backend_impl::backend_impl(std::string data, unsigned size) - : m_font(nullptr, nullptr) -{ - auto rw = SDLx_RWFromBinary(std::move(data)); - - if (rw == nullptr) { - throw std::runtime_error(SDL_GetError()); - } - - m_font = {TTF_OpenFontRW(rw, true, size), TTF_CloseFont}; - - if (m_font == nullptr) { - throw std::runtime_error(TTF_GetError()); - } -} - -size font::backend_impl::clip(const mlk::font&, const std::string& text) const -{ - int width, height; - - if (TTF_SizeUTF8(m_font.get(), text.c_str(), &width, &height) != 0) { - throw std::runtime_error(SDL_GetError()); - } - - return mlk::size(static_cast<unsigned>(width), static_cast<unsigned>(height)); -} - -} // !mlk
--- a/libclient/malikania/backend/sdl/font_backend.hpp Sun Jan 22 10:11:17 2017 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,51 +0,0 @@ -/* - * font_backend.hpp -- font object (SDL2 implementation) - * - * Copyright (c) 2013-2017 Malikania Authors - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef MALIKANIA_FONT_BACKEND_HPP -#define MALIKANIA_FONT_BACKEND_HPP - -#include <memory> - -#include <SDL.h> -#include <SDL_ttf.h> - -#include <malikania/font.hpp> - -namespace mlk { - -class font; -class size; - -class font::backend_impl { -private: - std::unique_ptr<TTF_Font, void (*)(TTF_Font*)> m_font; - -public: - backend_impl(std::string data, unsigned size); - - inline TTF_Font* font() noexcept - { - return m_font.get(); - } - - mlk::size clip(const mlk::font& self, const std::string& text) const; -}; - -} // !mlk - -#endif // !MALIKANIA_FONT_BACKEND_HPP
--- a/libclient/malikania/backend/sdl/image_backend.cpp Sun Jan 22 10:11:17 2017 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,119 +0,0 @@ -/* - * image_backend.cpp -- image object (SDL2 implementation) - * - * Copyright (c) 2013-2017 Malikania Authors - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <SDL_image.h> - -#include <malikania/backend/sdl/sdl_util.hpp> - -#include "image_backend.hpp" -#include "window_backend.hpp" - -using namespace std::string_literals; - -namespace mlk { - -void image::backend_impl::create_texture(window& window) -{ - m_texture = { - SDL_CreateTextureFromSurface(window.backend().renderer(), m_surface.get()), - SDL_DestroyTexture - }; - - if (m_texture == nullptr) { - throw std::runtime_error(SDL_GetError()); - } -} - -image::backend_impl::backend_impl(image&, std::string data) - : m_surface(nullptr, nullptr) - , m_texture(nullptr, nullptr) -{ - auto rw = SDLx_RWFromBinary(std::move(data)); - - if (rw == nullptr) { - throw std::runtime_error(SDL_GetError()); - } - - m_surface = {IMG_Load_RW(rw, true), SDL_FreeSurface}; - - if (!m_surface) { - throw std::runtime_error(SDL_GetError()); - } - - m_size = mlk::size( - static_cast<unsigned>(m_surface->w), - static_cast<unsigned>(m_surface->h) - ); -} - -void image::backend_impl::draw(window& window, const point& point) -{ - /* - * Create texture at this step so the image constructor does not need the - * window. - */ - if (!m_texture) { - create_texture(window); - } - - SDL_Rect target; - - target.x = static_cast<int>(point.x()); - target.y = static_cast<int>(point.y()); - target.w = static_cast<int>(m_size.width()); - target.h = static_cast<int>(m_size.height()); - - if (SDL_RenderCopy(window.backend().renderer(), m_texture.get(), nullptr, &target) < 0) { - throw std::runtime_error(SDL_GetError()); - } -} - -void image::backend_impl::draw(window& window, const rectangle& source, const rectangle& target) -{ - if (!m_texture) { - create_texture(window); - } - - SDL_Rect sr, st; - - sr.x = source.x(); - sr.y = source.y(); - sr.w = static_cast<int>(source.width()); - sr.h = static_cast<int>(source.height()); - - st.x = target.x(); - st.y = target.y(); - st.w = static_cast<int>(target.width()); - st.h = static_cast<int>(target.height()); - - // Readjust .w, .h if null. - if (source.is_null()) { - sr.w = static_cast<int>(m_size.width()); - sr.h = static_cast<int>(m_size.height()); - } - if (target.is_null()) { - st.w = static_cast<int>(m_size.width()); - st.h = static_cast<int>(m_size.height()); - } - - if (SDL_RenderCopy(window.backend().renderer(), m_texture.get(), &sr, &st) < 0) { - throw std::runtime_error(SDL_GetError()); - } -} - -} // !mlk
--- a/libclient/malikania/backend/sdl/image_backend.hpp Sun Jan 22 10:11:17 2017 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,65 +0,0 @@ -/* - * image_backend.hpp -- image object (SDL2 implementation) - * - * Copyright (c) 2013-2017 Malikania Authors - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef MALIKANIA_IMAGE_BACKEND_HPP -#define MALIKANIA_IMAGE_BACKEND_HPP - -#include <memory> - -#include <SDL.h> - -#include <malikania/size.hpp> -#include <malikania/image.hpp> - -namespace mlk { - -class image; -class point; -class rectangle; -class window; - -class image::backend_impl { -private: - std::unique_ptr<SDL_Surface, void (*)(SDL_Surface *)> m_surface; - std::unique_ptr<SDL_Texture, void (*)(SDL_Texture *)> m_texture; - - mlk::size m_size; - - void create_texture(window& window); - -public: - backend_impl(image& self, std::string data); - - inline SDL_Texture* texture() noexcept - { - return m_texture.get(); - } - - inline const mlk::size& size() const noexcept - { - return m_size; - } - - void draw(window& window, const point& position); - - void draw(window& window, const rectangle& source, const rectangle& target); -}; - -} // !mlk - -#endif // !MALIKANIA_IMAGE_BACKEND_HPP
--- a/libclient/malikania/backend/sdl/window_backend.cpp Sun Jan 22 10:11:17 2017 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,640 +0,0 @@ -/* - * window_backend.cpp -- window object (SDL2 implementation) - * - * Copyright (c) 2013-2017 Malikania Authors - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <cassert> -#include <stdexcept> -#include <unordered_map> - -#include <SDL.h> -#include <SDL_ttf.h> - -#include <malikania/color.hpp> -#include <malikania/key.hpp> -#include <malikania/line.hpp> -#include <malikania/point.hpp> -#include <malikania/rectangle.hpp> - -#include "font_backend.hpp" -#include "window_backend.hpp" -#include "window.hpp" - -namespace mlk { - -namespace { - -/* - * conversion maps - * ------------------------------------------------------------------ - * - * There is a difference between scancode and key codes. The scancode is the - * key located on the keyboard which is always the same, the key code is the - * translated to the user layout. - * - * For example, on azerty, hitting the 'a' key makes a key code of 'a' but a - * scancode of 'q'. - * - * - scancodes_map : convert SDL scancode do key - * - keycodes_map : convert SDL key code to key - * - modifiers_map : convert masks - * - button_map : convert SDL mouse buttons - */ - -const std::unordered_map<SDL_Keycode, key> scancodes_map{ - { SDL_SCANCODE_A, key::a }, - { SDL_SCANCODE_B, key::b }, - { SDL_SCANCODE_C, key::c }, - { SDL_SCANCODE_D, key::d }, - { SDL_SCANCODE_E, key::e }, - { SDL_SCANCODE_F, key::f }, - { SDL_SCANCODE_G, key::g }, - { SDL_SCANCODE_H, key::h }, - { SDL_SCANCODE_I, key::i }, - { SDL_SCANCODE_J, key::j }, - { SDL_SCANCODE_K, key::k }, - { SDL_SCANCODE_L, key::l }, - { SDL_SCANCODE_M, key::m }, - { SDL_SCANCODE_N, key::n }, - { SDL_SCANCODE_O, key::o }, - { SDL_SCANCODE_P, key::p }, - { SDL_SCANCODE_Q, key::q }, - { SDL_SCANCODE_R, key::r }, - { SDL_SCANCODE_S, key::s }, - { SDL_SCANCODE_T, key::t }, - { SDL_SCANCODE_U, key::u }, - { SDL_SCANCODE_V, key::v }, - { SDL_SCANCODE_W, key::w }, - { SDL_SCANCODE_X, key::x }, - { SDL_SCANCODE_Y, key::y }, - { SDL_SCANCODE_Z, key::z }, - { SDL_SCANCODE_1, key::one }, - { SDL_SCANCODE_2, key::two }, - { SDL_SCANCODE_3, key::three }, - { SDL_SCANCODE_4, key::four }, - { SDL_SCANCODE_5, key::five }, - { SDL_SCANCODE_6, key::six }, - { SDL_SCANCODE_7, key::seven }, - { SDL_SCANCODE_8, key::eight }, - { SDL_SCANCODE_9, key::nine }, - { SDL_SCANCODE_0, key::zero }, - { SDL_SCANCODE_RETURN, key::enter }, - { SDL_SCANCODE_ESCAPE, key::escape }, - { SDL_SCANCODE_BACKSPACE, key::backspace }, - { SDL_SCANCODE_TAB, key::tab }, - { SDL_SCANCODE_SPACE, key::space }, - { SDL_SCANCODE_MINUS, key::minus }, - { SDL_SCANCODE_EQUALS, key::equals }, - { SDL_SCANCODE_LEFTBRACKET, key::left_bracket }, - { SDL_SCANCODE_RIGHTBRACKET, key::right_bracket }, - { SDL_SCANCODE_BACKSLASH, key::backslash }, - { SDL_SCANCODE_NONUSHASH, key::hash }, - { SDL_SCANCODE_SEMICOLON, key::semicolon }, - { SDL_SCANCODE_APOSTROPHE, key::apostrophe }, - { SDL_SCANCODE_GRAVE, key::grave }, - { SDL_SCANCODE_COMMA, key::comma }, - { SDL_SCANCODE_PERIOD, key::period }, - { SDL_SCANCODE_SLASH, key::slash }, - { SDL_SCANCODE_CAPSLOCK, key::caps_lock }, - { SDL_SCANCODE_F1, key::f1 }, - { SDL_SCANCODE_F2, key::f2 }, - { SDL_SCANCODE_F3, key::f3 }, - { SDL_SCANCODE_F4, key::f4 }, - { SDL_SCANCODE_F5, key::f5 }, - { SDL_SCANCODE_F6, key::f6 }, - { SDL_SCANCODE_F7, key::f7 }, - { SDL_SCANCODE_F8, key::f8 }, - { SDL_SCANCODE_F9, key::f9 }, - { SDL_SCANCODE_F10, key::f10 }, - { SDL_SCANCODE_F11, key::f11 }, - { SDL_SCANCODE_F12, key::f12 }, - { SDL_SCANCODE_F13, key::f13 }, - { SDL_SCANCODE_F14, key::f14 }, - { SDL_SCANCODE_F15, key::f15 }, - { SDL_SCANCODE_F16, key::f16 }, - { SDL_SCANCODE_F17, key::f17 }, - { SDL_SCANCODE_F18, key::f18 }, - { SDL_SCANCODE_F19, key::f19 }, - { SDL_SCANCODE_F20, key::f20 }, - { SDL_SCANCODE_F21, key::f21 }, - { SDL_SCANCODE_F22, key::f22 }, - { SDL_SCANCODE_F23, key::f23 }, - { SDL_SCANCODE_F24, key::f24 }, - { SDL_SCANCODE_PRINTSCREEN, key::print_screen }, - { SDL_SCANCODE_SCROLLLOCK, key::scroll_lock }, - { SDL_SCANCODE_PAUSE, key::pause }, - { SDL_SCANCODE_INSERT, key::insert }, - { SDL_SCANCODE_HOME, key::home }, - { SDL_SCANCODE_PAGEUP, key::page_up }, - { SDL_SCANCODE_PAGEDOWN, key::page_down }, - { SDL_SCANCODE_DELETE, key::del }, - { SDL_SCANCODE_END, key::end }, - { SDL_SCANCODE_RIGHT, key::right }, - { SDL_SCANCODE_LEFT, key::left }, - { SDL_SCANCODE_DOWN, key::down }, - { SDL_SCANCODE_UP, key::up }, - { SDL_SCANCODE_KP_DIVIDE, key::kp_divide }, - { SDL_SCANCODE_KP_MULTIPLY, key::kp_multiply }, - { SDL_SCANCODE_KP_MINUS, key::kp_minus }, - { SDL_SCANCODE_KP_PLUS, key::kp_plus }, - { SDL_SCANCODE_KP_ENTER, key::kp_enter }, - { SDL_SCANCODE_KP_1, key::kp_one }, - { SDL_SCANCODE_KP_2, key::kp_two }, - { SDL_SCANCODE_KP_3, key::kp_three }, - { SDL_SCANCODE_KP_4, key::kp_four }, - { SDL_SCANCODE_KP_5, key::kp_five }, - { SDL_SCANCODE_KP_6, key::kp_six }, - { SDL_SCANCODE_KP_7, key::kp_seven }, - { SDL_SCANCODE_KP_8, key::kp_eight }, - { SDL_SCANCODE_KP_9, key::kp_nine }, - { SDL_SCANCODE_KP_0, key::kp_zero }, - { SDL_SCANCODE_MUTE, key::mute }, - { SDL_SCANCODE_VOLUMEUP, key::volume_up }, - { SDL_SCANCODE_VOLUMEDOWN, key::volume_down }, - { SDL_SCANCODE_LCTRL, key::left_control }, - { SDL_SCANCODE_LALT, key::left_alt }, - { SDL_SCANCODE_LSHIFT, key::left_shift }, - { SDL_SCANCODE_LGUI, key::left_super }, - { SDL_SCANCODE_RCTRL, key::right_control }, - { SDL_SCANCODE_RALT, key::right_alt }, - { SDL_SCANCODE_RSHIFT, key::right_shift }, - { SDL_SCANCODE_RGUI, key::right_super } -}; - -const std::unordered_map<SDL_Keycode, key> keycodes_map{ - { SDLK_RETURN, key::enter }, - { SDLK_ESCAPE, key::escape }, - { SDLK_BACKSPACE, key::backspace }, - { SDLK_TAB, key::tab }, - { SDLK_SPACE, key::space }, - { SDLK_EXCLAIM, key::exclaim }, - { SDLK_QUOTEDBL, key::double_quote }, - { SDLK_HASH, key::hash }, - { SDLK_PERCENT, key::percent }, - { SDLK_DOLLAR, key::dollar }, - { SDLK_AMPERSAND, key::ampersand }, - { SDLK_QUOTE, key::quote }, - { SDLK_LEFTPAREN, key::left_parenthese }, - { SDLK_RIGHTPAREN, key::right_parenthese }, - { SDLK_ASTERISK, key::asterisk }, - { SDLK_PLUS, key::plus }, - { SDLK_COMMA, key::comma }, - { SDLK_MINUS, key::minus }, - { SDLK_PERIOD, key::period }, - { SDLK_SLASH, key::slash }, - { SDLK_0, key::zero }, - { SDLK_1, key::one }, - { SDLK_2, key::two }, - { SDLK_3, key::three }, - { SDLK_4, key::four }, - { SDLK_5, key::five }, - { SDLK_6, key::six }, - { SDLK_7, key::seven }, - { SDLK_8, key::eight }, - { SDLK_9, key::nine }, - { SDLK_COLON, key::colon }, - { SDLK_SEMICOLON, key::semicolon }, - { SDLK_LESS, key::less }, - { SDLK_EQUALS, key::equals }, - { SDLK_GREATER, key::greater }, - { SDLK_QUESTION, key::question }, - { SDLK_AT, key::at }, - { SDLK_LEFTBRACKET, key::left_bracket }, - { SDLK_BACKSLASH, key::backslash }, - { SDLK_RIGHTBRACKET, key::right_bracket }, - { SDLK_CARET, key::caret }, - { SDLK_UNDERSCORE, key::underscore }, - { SDLK_BACKQUOTE, key::back_quote }, - { SDLK_a, key::a }, - { SDLK_b, key::b }, - { SDLK_c, key::c }, - { SDLK_d, key::d }, - { SDLK_e, key::e }, - { SDLK_f, key::f }, - { SDLK_g, key::g }, - { SDLK_h, key::h }, - { SDLK_i, key::i }, - { SDLK_j, key::j }, - { SDLK_k, key::k }, - { SDLK_l, key::l }, - { SDLK_m, key::m }, - { SDLK_n, key::n }, - { SDLK_o, key::o }, - { SDLK_p, key::p }, - { SDLK_q, key::q }, - { SDLK_r, key::r }, - { SDLK_s, key::s }, - { SDLK_t, key::t }, - { SDLK_u, key::u }, - { SDLK_v, key::v }, - { SDLK_w, key::w }, - { SDLK_x, key::x }, - { SDLK_y, key::y }, - { SDLK_z, key::z }, - { SDLK_CAPSLOCK, key::caps_lock }, - { SDLK_F1, key::f1 }, - { SDLK_F2, key::f2 }, - { SDLK_F3, key::f3 }, - { SDLK_F4, key::f4 }, - { SDLK_F5, key::f5 }, - { SDLK_F6, key::f6 }, - { SDLK_F7, key::f7 }, - { SDLK_F8, key::f8 }, - { SDLK_F9, key::f9 }, - { SDLK_F10, key::f10 }, - { SDLK_F11, key::f11 }, - { SDLK_F12, key::f12 }, - { SDLK_F13, key::f13 }, - { SDLK_F14, key::f14 }, - { SDLK_F15, key::f15 }, - { SDLK_F16, key::f16 }, - { SDLK_F17, key::f17 }, - { SDLK_F18, key::f18 }, - { SDLK_F19, key::f19 }, - { SDLK_F20, key::f20 }, - { SDLK_F21, key::f21 }, - { SDLK_F22, key::f22 }, - { SDLK_F23, key::f23 }, - { SDLK_F24, key::f24 }, - { SDLK_PRINTSCREEN, key::print_screen }, - { SDLK_SCROLLLOCK, key::scroll_lock }, - { SDLK_PAUSE, key::pause }, - { SDLK_INSERT, key::insert }, - { SDLK_HOME, key::home }, - { SDLK_PAGEUP, key::page_up }, - { SDLK_PAGEDOWN, key::page_down }, - { SDLK_DELETE, key::del }, - { SDLK_END, key::end }, - { SDLK_RIGHT, key::right }, - { SDLK_LEFT, key::left }, - { SDLK_DOWN, key::down }, - { SDLK_UP, key::up }, - { SDLK_KP_DIVIDE, key::kp_divide }, - { SDLK_KP_MULTIPLY, key::kp_multiply }, - { SDLK_KP_MINUS, key::kp_minus }, - { SDLK_KP_PLUS, key::kp_plus }, - { SDLK_KP_ENTER, key::kp_enter }, - { SDLK_KP_1, key::kp_one }, - { SDLK_KP_2, key::kp_two }, - { SDLK_KP_3, key::kp_three }, - { SDLK_KP_4, key::kp_four }, - { SDLK_KP_5, key::kp_five }, - { SDLK_KP_6, key::kp_six }, - { SDLK_KP_7, key::kp_seven }, - { SDLK_KP_8, key::kp_eight }, - { SDLK_KP_9, key::kp_nine }, - { SDLK_KP_0, key::kp_zero }, - { SDLK_MUTE, key::mute }, - { SDLK_VOLUMEUP, key::volume_up }, - { SDLK_VOLUMEDOWN, key::volume_down }, - { SDLK_LCTRL, key::left_control }, - { SDLK_LALT, key::left_alt }, - { SDLK_LSHIFT, key::left_shift }, - { SDLK_LGUI, key::left_super }, - { SDLK_RCTRL, key::right_control }, - { SDLK_RALT, key::right_alt }, - { SDLK_RSHIFT, key::right_shift }, - { SDLK_RGUI, key::right_super } -}; - -const std::unordered_map<SDL_Keymod, mod> modifiers_map{ - { KMOD_LCTRL, mod::left_control }, - { KMOD_LALT, mod::left_alt }, - { KMOD_LSHIFT, mod::left_shift }, - { KMOD_LGUI, mod::left_super }, - { KMOD_RCTRL, mod::right_control }, - { KMOD_RALT, mod::right_alt }, - { KMOD_RSHIFT, mod::right_shift }, - { KMOD_RGUI, mod::right_super }, - { KMOD_NUM, mod::num_lock }, - { KMOD_CAPS, mod::caps_lock } -}; - -const std::unordered_map<Uint32, mouse> button_map{ - { SDL_BUTTON_LEFT, mouse::left }, - { SDL_BUTTON_RIGHT, mouse::right }, - { SDL_BUTTON_MIDDLE, mouse::middle } -}; - -} // !namespace - -void window::backend_impl::handle_key(window& self, const SDL_Event& ev) -{ - assert(ev.type == SDL_KEYDOWN || ev.type == SDL_KEYUP); - - // Key and scan code. - auto kc = keycodes_map.find(ev.key.keysym.sym); - auto sc = scancodes_map.find(ev.key.keysym.scancode); - - if (kc == keycodes_map.end() || sc == scancodes_map.end()) { - return; - } - - key_event kev{kc->second, sc->second, mod::none}; - - // Modifier is a mask. - for (const auto& pair : modifiers_map) { - if (ev.key.keysym.mod & pair.first) { - kev.modifiers |= pair.second; - } - } - - if (ev.type == SDL_KEYDOWN) { - self.handle_key_down(kev); - } else { - self.handle_key_up(kev); - } -} - -void window::backend_impl::handle_mouse(window& self, const SDL_Event& ev) -{ - assert(ev.type == SDL_MOUSEBUTTONDOWN || ev.type == SDL_MOUSEBUTTONUP); - - auto which = button_map.find(ev.button.button); - - if (which == button_map.end()) { - return; - } - - mouse_click_event mev{ - which->second, - point(ev.button.x, ev.button.y) - }; - - if (ev.type == SDL_MOUSEBUTTONDOWN) { - self.handle_mouse_down(mev); - } else { - self.handle_mouse_up(mev); - } -} - -void window::backend_impl::handle_mouse_wheel(window& self, const SDL_Event& ev) -{ - assert(ev.type == SDL_MOUSEWHEEL); - - mouse_wheel_event wev{{ev.wheel.x, ev.wheel.y}}; - - self.handle_mouse_wheel(wev); -} - -window::backend_impl::backend_impl(window&, unsigned width, unsigned height, const std::string& title) - : m_window(nullptr, nullptr) - , m_renderer(nullptr, nullptr) -{ - SDL_SetMainReady(); - SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO); - - m_window = { - SDL_CreateWindow( - title.c_str(), - SDL_WINDOWPOS_UNDEFINED, - SDL_WINDOWPOS_UNDEFINED, - width, height, - SDL_WINDOW_OPENGL - ), - SDL_DestroyWindow - }; - - if (m_window == nullptr) { - throw std::runtime_error(SDL_GetError()); - } - - // Create renderer. - m_renderer = { - SDL_CreateRenderer(m_window.get(), -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC), - SDL_DestroyRenderer - }; - - if (m_renderer == nullptr) { - throw std::runtime_error(SDL_GetError()); - } - if (TTF_Init() == -1) { - throw std::runtime_error(TTF_GetError()); - } -} - -void window::backend_impl::clear() -{ - SDL_RenderClear(m_renderer.get()); -} - -void window::backend_impl::present() -{ - SDL_RenderPresent(m_renderer.get()); -} - -#if 0 - -// TODO: see later if it's really needed - -Size window::backend_impl::resolution() -{ - SDL_DisplayMode current; - int width = 0; - int height = 0; - for (int i = 0; i < SDL_GetNumVideoDisplays(); i++) { - int error = SDL_GetCurrentDisplayMode(i, ¤t); - if (error == 0) { - // Get the last one - // TODO test with only one display mode, but we have to test with more than that - width = current.w; - height = current.hpp; - } else { - throw std::runtime_error("Could not get display mode for video display" + std::string(SDL_GetError())); - } - } - - return Size((unsigned)width, (unsigned)height); -} - -#endif - -color window::backend_impl::drawing_color() const -{ - SDL_Color color; - - if (SDL_GetRenderDrawColor(m_renderer.get(), &color.r, &color.g, &color.b, &color.a) < 0) { - throw std::runtime_error(SDL_GetError()); - } - - return {color.r, color.g, color.b, color.a}; -} - -void window::backend_impl::set_drawing_color(const color& color) -{ - if (SDL_SetRenderDrawColor(m_renderer.get(), color.red(), color.green(), color.blue(), color.alpha()) < 0) { - throw std::runtime_error(SDL_GetError()); - } -} - -void window::backend_impl::draw_line(const line& line) -{ - if (SDL_RenderDrawLine(m_renderer.get(), line.x1(), line.y1(), line.x2(), line.y2()) != 0) { - throw std::runtime_error(SDL_GetError()); - } -} - -void window::backend_impl::draw_lines(const std::vector<point>& points) -{ - std::vector<SDL_Point> sdlpoints(points.size()); - - for (unsigned i = 0; i < points.size(); ++i) { - sdlpoints[i] = {points[i].x(), points[i].y()}; - } - - if (SDL_RenderDrawLines(m_renderer.get(), sdlpoints.data(), sdlpoints.size()) < 0) { - throw std::runtime_error(SDL_GetError()); - } -} - -void window::backend_impl::draw_point(const point& point) -{ - if (SDL_RenderDrawPoint(m_renderer.get(), point.x(), point.y()) != 0) { - throw std::runtime_error(SDL_GetError()); - } -} - -void window::backend_impl::draw_points(const std::vector<point>& points) -{ - std::vector<SDL_Point> sdlpoints(points.size()); - - for (unsigned i = 0; i < points.size(); ++i) { - sdlpoints[i] = {points[i].x(), points[i].y()}; - } - - if (SDL_RenderDrawPoints(m_renderer.get(), sdlpoints.data(), sdlpoints.size()) != 0) { - throw std::runtime_error(SDL_GetError()); - } -} - -void window::backend_impl::draw_rectangle(const rectangle& rectangle) -{ - SDL_Rect rect{ - rectangle.x(), - rectangle.y(), - static_cast<int>(rectangle.width()), - static_cast<int>(rectangle.height()) - }; - - if (SDL_RenderDrawRect(m_renderer.get(), &rect) < 0) { - throw std::runtime_error(SDL_GetError()); - } -} - -void window::backend_impl::draw_rectangles(const std::vector<rectangle>& rectangles) -{ - std::vector<SDL_Rect> sdlrects(rectangles.size()); - - for (unsigned i = 0; i < rectangles.size(); ++i) { - sdlrects[i] = { - rectangles[i].x(), - rectangles[i].y(), - static_cast<int>(rectangles[i].width()), - static_cast<int>(rectangles[i].height()) - }; - } - - if (SDL_RenderDrawRects(m_renderer.get(), sdlrects.data(), sdlrects.size()) != 0) { - throw std::runtime_error(SDL_GetError()); - } -} - -void window::backend_impl::fill_rectangle(const rectangle& rectangle) -{ - SDL_Rect rect{ - rectangle.x(), - rectangle.y(), - static_cast<int>(rectangle.width()), - static_cast<int>(rectangle.height()) - }; - - if (SDL_RenderFillRect(m_renderer.get(), &rect) < 0) { - throw std::runtime_error(SDL_GetError()); - } -} - -void window::backend_impl::fill_rectangles(const std::vector<rectangle>& rectangles) -{ - std::vector<SDL_Rect> sdlrects(rectangles.size()); - - for (unsigned i = 0; i < rectangles.size(); ++i) { - sdlrects[i] = { - rectangles[i].x(), - rectangles[i].y(), - static_cast<int>(rectangles[i].width()), - static_cast<int>(rectangles[i].height()) - }; - } - - if (SDL_RenderFillRects(m_renderer.get(), sdlrects.data(), sdlrects.size()) != 0) { - throw std::runtime_error(SDL_GetError()); - } -} - -void window::backend_impl::draw_text(const std::string& text, font& font, const rectangle& rectangle) -{ - SDL_Color color = {0, 0, 0, 255}; - SDL_Surface* message = TTF_RenderUTF8_Blended(font.backend().font(), text.c_str(), color); - SDL_Texture* texture = SDL_CreateTextureFromSurface(m_renderer.get(), message); - SDL_Rect rect = {rectangle.x(), rectangle.y(), (int)rectangle.width(), (int)rectangle.height()}; - SDL_RenderCopy(m_renderer.get(), texture, nullptr, &rect); - SDL_FreeSurface(message); - SDL_DestroyTexture(texture); -} - -void window::backend_impl::draw_text(const std::string &text, font& font, const point& point) -{ - SDL_Color color = {0, 0, 0, 0}; - SDL_GetRenderDrawColor(m_renderer.get(), &color.r, &color.g, &color.b, &color.a); - SDL_Surface* message = TTF_RenderUTF8_Blended(font.backend().font(), text.c_str(), color); - SDL_Texture* texture = SDL_CreateTextureFromSurface(m_renderer.get(), message); - SDL_Rect rect = {point.x(), point.y(), message->w, message->h}; - SDL_RenderCopy(m_renderer.get(), texture, nullptr, &rect); - SDL_FreeSurface(message); - SDL_DestroyTexture(texture); -} - -void window::backend_impl::close() -{ -} - -void window::backend_impl::poll(window& self) -{ - SDL_Event event; - - while (SDL_PollEvent(&event)) { - switch (event.type) { - case SDL_KEYUP: - case SDL_KEYDOWN: - handle_key(self, event); - break; - case SDL_MOUSEBUTTONDOWN: - case SDL_MOUSEBUTTONUP: - handle_mouse(self, event); - break; - case SDL_MOUSEWHEEL: - handle_mouse_wheel(self, event); - break; - case SDL_QUIT: - self.handle_quit(); - break; - default: - break; - } - } -} - -} // !mlk
--- a/libclient/malikania/backend/sdl/window_backend.hpp Sun Jan 22 10:11:17 2017 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,83 +0,0 @@ -/* - * window_backend.hpp -- window object (SDL2 implementation) - * - * Copyright (c) 2013-2017 Malikania Authors - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef MALIKANIA_WINDOW_BACKEND_HPP -#define MALIKANIA_WINDOW_BACKEND_HPP - -#include <memory> -#include <vector> - -#include <SDL.h> - -#include <malikania/window.hpp> - -namespace mlk { - -class window::backend_impl { -private: - std::unique_ptr<SDL_Window, void (*)(SDL_Window *)> m_window; - std::unique_ptr<SDL_Renderer, void (*)(SDL_Renderer *)> m_renderer; - - void handle_key(window&, const SDL_Event&); - void handle_mouse(window&, const SDL_Event&); - void handle_mouse_wheel(window&, const SDL_Event&); - -public: - backend_impl(window& self, unsigned width, unsigned height, const std::string& title); - - inline SDL_Renderer* renderer() noexcept - { - return m_renderer.get(); - } - - void close(); - - void clear(); - - void present(); - - color drawing_color() const; - - void set_drawing_color(const color& color); - - void draw_line(const line& line); - - void draw_lines(const std::vector<point>& points); - - void draw_point(const point& point); - - void draw_points(const std::vector<point>& points); - - void draw_rectangle(const rectangle& rect); - - void draw_rectangles(const std::vector<rectangle>& rects); - - void fill_rectangle(const rectangle& rect); - - void fill_rectangles(const std::vector<rectangle>& rects); - - void draw_text(const std::string& text, font& font, const rectangle& rectangle); - - void draw_text(const std::string& text, font& font, const point& point); - - void poll(window &self); -}; - -} // !mlk - -#endif // !MALIKANIA_WINDOW_BACKEND_HPP
--- a/libclient/malikania/button.cpp Sun Jan 22 10:11:17 2017 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -/* - * button.cpp -- GUI button element - * - * Copyright (c) 2013-2017 Malikania Authors - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "button.hpp" -#include "theme.hpp" -#include "window.hpp" - -namespace mlk { - -button::button(std::string text) - : m_text(std::move(text)) -{ -} - -void button::handle_mouse_down(const mouse_click_event& ev) -{ - if (ev.button == mouse::left) { - on_clicked(); - } -} - -void button::draw(window& w, const rectangle& rect) -{ - w.theme().draw_button(w, *this, rect); -} - -mlk::size button::size(window& w) const noexcept -{ - return w.theme().size_button(*this); -} - -} // !mlk
--- a/libclient/malikania/button.hpp Sun Jan 22 10:11:17 2017 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,97 +0,0 @@ -/* - * button.hpp -- GUI button element - * - * Copyright (c) 2013-2017 Malikania Authors - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef MALIKANIA_CLIENT_BUTTON_HPP -#define MALIKANIA_CLIENT_BUTTON_HPP - -/** - * \file button.hpp - * \brief GUI button element. - */ - -#include <boost/signals2.hpp> - -#include <string> - -#include "widget.hpp" - -namespace mlk { - -/** - * \brief Basic button element. - */ -class button : public widget { -public: - boost::signals2::signal<void()> on_clicked; - boost::signals2::signal<void()> on_released; - -private: - std::string m_text; - -public: - /** - * Default constructor with optional text. - * - * \param text the text - */ - button(std::string text = ""); - - /** - * Get the button text. - * - * \return the text - */ - inline const std::string& text() const noexcept - { - return m_text; - } - - /** - * Set the button text. - * - * \param text the text - */ - inline void set_text(std::string text) noexcept - { - m_text = std::move(text); - } - - /** - * \copydoc widget::handle_mouse_down - */ - void handle_mouse_down(const mouse_click_event& ev) override; - - /** - * Bring back other functions. - */ - using widget::draw; - - /** - * \copydoc widget::draw - */ - void draw(window& w, const rectangle& rect) override; - - /** - * \copydoc widget::size - */ - mlk::size size(window& w) const noexcept override; -}; - -} // !mlk - -#endif // !MALIKANIA_CLIENT_BUTTON_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/client/animation.hpp Sun Jan 22 11:07:36 2017 +0100 @@ -0,0 +1,157 @@ +/* + * animation.hpp -- animation description + * + * Copyright (c) 2013-2017 Malikania Authors + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef MALIKANIA_ANIMATION_HPP +#define MALIKANIA_ANIMATION_HPP + +/** + * \file animation.hpp + * \brief Describe an animation. + */ + +#include <cassert> +#include <cstdint> +#include <memory> +#include <vector> + +#include "sprite.hpp" + +namespace mlk { + +namespace client { + +class window; + +/** + * \brief Animation frame description. + * + * A frame is a duration before switching to the next sprite cell. It is + * currently implemented as a class for future usage. + */ +class animation_frame { +private: + std::uint16_t m_delay; + +public: + /** + * Construct a frame. + * + * \param delay the optional delay + */ + inline animation_frame(std::uint16_t delay = 100) noexcept + : m_delay(delay) + { + } + + /** + * Get the the delay. + * + * \return the delay + */ + inline std::uint16_t delay() const noexcept + { + return m_delay; + } +}; + +/** + * \brief List of frames. + */ +using animation_frames = std::vector<animation_frame>; + +/** + * \brief Animation description. + * + * An animation is a sprite with a set of frames containing a delay for showing + * all sprites in a specific amount of time. + * + * Because an animation contains an image, a state (time, current cell) it must + * be constructed with an animator object so the user is able to use the same + * animation on different parts of the screen without having to duplicate + * resources. + * + * \see Animator + */ +class animation { +private: + mlk::client::sprite m_sprite; + mlk::client::animation_frames m_frames; + +public: + /** + * Create an animation. + * + * \param sprite the sprite image + * \param frames the frames to show + */ + inline animation(mlk::client::sprite sprite, animation_frames frames) noexcept + : m_sprite(std::move(sprite)) + , m_frames(std::move(frames)) + { + } + + /** + * Get the underlying sprite. + * + * \return the sprite + */ + inline const mlk::client::sprite& sprite() const noexcept + { + return m_sprite; + } + + /** + * Overloaded function. + * + * \return the sprite + */ + inline mlk::client::sprite& sprite() noexcept + { + return m_sprite; + } + + /** + * Get the frames. + * + * \return the frames + */ + inline const animation_frames& frames() const noexcept + { + return m_frames; + } + + /** + * Access a frame. + * + * \pre index < number of frames + * \param index the index + * \return the frame + */ + inline const animation_frame& operator[](unsigned index) const noexcept + { + assert(index < m_frames.size()); + + return m_frames[index]; + } +}; + +} // !client + +} // !mlk + +#endif // !MALIKANIA_ANIMATION_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/client/animator.cpp Sun Jan 22 11:07:36 2017 +0100 @@ -0,0 +1,56 @@ +/* + * animator.cpp -- animation drawing object + * + * Copyright (c) 2013-2017 Malikania Authors + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "animation.hpp" +#include "animator.hpp" + +namespace mlk { + +namespace client { + +animator::animator(animation& animation) noexcept + : m_animation(animation) +{ +} + +void animator::update() noexcept +{ + auto total = m_animation.sprite().rows() * m_animation.sprite().columns(); + + if (m_current >= total) { + return; + } + + if (m_timer.elapsed().wall / 1000000LL >= m_animation[m_current].delay()) { + m_current ++; + m_timer.start(); + } +} + +void animator::draw(window& window, const point& point) +{ + if (m_current >= m_animation.sprite().rows() * m_animation.sprite().columns()) { + return; + } + + m_animation.sprite().draw(window, m_current, point); +} + +} // !client + +} // !mlk
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/client/animator.hpp Sun Jan 22 11:07:36 2017 +0100 @@ -0,0 +1,78 @@ +/* + * animator.hpp -- animation drawing object + * + * Copyright (c) 2013-2017 Malikania Authors + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef MALIKANIA_ANIMATOR_HPP +#define MALIKANIA_ANIMATOR_HPP + +#include <boost/timer/timer.hpp> + +/** + * \file animator.hpp + * \brief Draw animations. + */ + +namespace mlk { + +namespace client { + +class animation; +class point; +class window; + +/** + * \brief Object for drawing animations. + * + * The animator contains an animation and a state. + */ +class animator { +private: + boost::timer::cpu_timer m_timer; + animation& m_animation; + unsigned m_current{0}; + +public: + /** + * Construct an animator. + * + * \pre animation must not be null + * \param animation the animation + */ + animator(animation& animation) noexcept; + + /** + * Update the animator state. + * + * This function should be called in the main loop to update the cell to + * draw before calling draw(). + */ + void update() noexcept; + + /** + * Draw the animation. + * + * \param window the window + * \param position the position in the window + */ + void draw(window& window, const point& position); +}; + +} // !client + +} // !mlk + +#endif // !MALIKANIA_ANIMATOR_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/client/backend/sdl/font_backend.cpp Sun Jan 22 11:07:36 2017 +0100 @@ -0,0 +1,60 @@ +/* + * font_backend.cpp -- font object (SDL2 implementation) + * + * Copyright (c) 2013-2017 Malikania Authors + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <malikania/backend/sdl/sdl_util.hpp> + +#include "size.hpp" +#include "font.hpp" +#include "font_backend.hpp" + +using namespace std::string_literals; + +namespace mlk { + +namespace client { + +font::backend_impl::backend_impl(std::string data, unsigned size) + : m_font(nullptr, nullptr) +{ + auto rw = SDLx_RWFromBinary(std::move(data)); + + if (rw == nullptr) { + throw std::runtime_error(SDL_GetError()); + } + + m_font = {TTF_OpenFontRW(rw, true, size), TTF_CloseFont}; + + if (m_font == nullptr) { + throw std::runtime_error(TTF_GetError()); + } +} + +size font::backend_impl::clip(const mlk::client::font&, const std::string& text) const +{ + int width, height; + + if (TTF_SizeUTF8(m_font.get(), text.c_str(), &width, &height) != 0) { + throw std::runtime_error(SDL_GetError()); + } + + return mlk::client::size(static_cast<unsigned>(width), static_cast<unsigned>(height)); +} + +} // !client + +} // !mlk
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/client/backend/sdl/font_backend.hpp Sun Jan 22 11:07:36 2017 +0100 @@ -0,0 +1,55 @@ +/* + * font_backend.hpp -- font object (SDL2 implementation) + * + * Copyright (c) 2013-2017 Malikania Authors + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef MALIKANIA_FONT_BACKEND_HPP +#define MALIKANIA_FONT_BACKEND_HPP + +#include <memory> + +#include <SDL.h> +#include <SDL_ttf.h> + +#include "font.hpp" + +namespace mlk { + +namespace client { + +class font; +class size; + +class font::backend_impl { +private: + std::unique_ptr<TTF_Font, void (*)(TTF_Font*)> m_font; + +public: + backend_impl(std::string data, unsigned size); + + inline TTF_Font* font() noexcept + { + return m_font.get(); + } + + mlk::client::size clip(const mlk::client::font& self, const std::string& text) const; +}; + +} // !client + +} // !mlk + +#endif // !MALIKANIA_FONT_BACKEND_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/client/backend/sdl/image_backend.cpp Sun Jan 22 11:07:36 2017 +0100 @@ -0,0 +1,123 @@ +/* + * image_backend.cpp -- image object (SDL2 implementation) + * + * Copyright (c) 2013-2017 Malikania Authors + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <SDL_image.h> + +#include <malikania/backend/sdl/sdl_util.hpp> + +#include "image_backend.hpp" +#include "window_backend.hpp" + +using namespace std::string_literals; + +namespace mlk { + +namespace client { + +void image::backend_impl::create_texture(window& window) +{ + m_texture = { + SDL_CreateTextureFromSurface(window.backend().renderer(), m_surface.get()), + SDL_DestroyTexture + }; + + if (m_texture == nullptr) { + throw std::runtime_error(SDL_GetError()); + } +} + +image::backend_impl::backend_impl(image&, std::string data) + : m_surface(nullptr, nullptr) + , m_texture(nullptr, nullptr) +{ + auto rw = SDLx_RWFromBinary(std::move(data)); + + if (rw == nullptr) { + throw std::runtime_error(SDL_GetError()); + } + + m_surface = {IMG_Load_RW(rw, true), SDL_FreeSurface}; + + if (!m_surface) { + throw std::runtime_error(SDL_GetError()); + } + + m_size = mlk::client::size( + static_cast<unsigned>(m_surface->w), + static_cast<unsigned>(m_surface->h) + ); +} + +void image::backend_impl::draw(window& window, const point& point) +{ + /* + * Create texture at this step so the image constructor does not need the + * window. + */ + if (!m_texture) { + create_texture(window); + } + + SDL_Rect target; + + target.x = static_cast<int>(point.x()); + target.y = static_cast<int>(point.y()); + target.w = static_cast<int>(m_size.width()); + target.h = static_cast<int>(m_size.height()); + + if (SDL_RenderCopy(window.backend().renderer(), m_texture.get(), nullptr, &target) < 0) { + throw std::runtime_error(SDL_GetError()); + } +} + +void image::backend_impl::draw(window& window, const rectangle& source, const rectangle& target) +{ + if (!m_texture) { + create_texture(window); + } + + SDL_Rect sr, st; + + sr.x = source.x(); + sr.y = source.y(); + sr.w = static_cast<int>(source.width()); + sr.h = static_cast<int>(source.height()); + + st.x = target.x(); + st.y = target.y(); + st.w = static_cast<int>(target.width()); + st.h = static_cast<int>(target.height()); + + // Readjust .w, .h if null. + if (source.is_null()) { + sr.w = static_cast<int>(m_size.width()); + sr.h = static_cast<int>(m_size.height()); + } + if (target.is_null()) { + st.w = static_cast<int>(m_size.width()); + st.h = static_cast<int>(m_size.height()); + } + + if (SDL_RenderCopy(window.backend().renderer(), m_texture.get(), &sr, &st) < 0) { + throw std::runtime_error(SDL_GetError()); + } +} + +} // !client + +} // !mlk
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/client/backend/sdl/image_backend.hpp Sun Jan 22 11:07:36 2017 +0100 @@ -0,0 +1,69 @@ +/* + * image_backend.hpp -- image object (SDL2 implementation) + * + * Copyright (c) 2013-2017 Malikania Authors + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef MALIKANIA_IMAGE_BACKEND_HPP +#define MALIKANIA_IMAGE_BACKEND_HPP + +#include <memory> + +#include <SDL.h> + +#include "size.hpp" +#include "image.hpp" + +namespace mlk { + +namespace client { + +class image; +class point; +class rectangle; +class window; + +class image::backend_impl { +private: + std::unique_ptr<SDL_Surface, void (*)(SDL_Surface *)> m_surface; + std::unique_ptr<SDL_Texture, void (*)(SDL_Texture *)> m_texture; + + mlk::client::size m_size; + + void create_texture(window& window); + +public: + backend_impl(image& self, std::string data); + + inline SDL_Texture* texture() noexcept + { + return m_texture.get(); + } + + inline const mlk::client::size& size() const noexcept + { + return m_size; + } + + void draw(window& window, const point& position); + + void draw(window& window, const rectangle& source, const rectangle& target); +}; + +} // !client + +} // !mlk + +#endif // !MALIKANIA_IMAGE_BACKEND_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/client/backend/sdl/window_backend.cpp Sun Jan 22 11:07:36 2017 +0100 @@ -0,0 +1,643 @@ +/* + * window_backend.cpp -- window object (SDL2 implementation) + * + * Copyright (c) 2013-2017 Malikania Authors + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <cassert> +#include <stdexcept> +#include <unordered_map> + +#include <SDL.h> +#include <SDL_ttf.h> + +#include "color.hpp" +#include "font_backend.hpp" +#include "key.hpp" +#include "line.hpp" +#include "point.hpp" +#include "rectangle.hpp" +#include "window_backend.hpp" +#include "window.hpp" + +namespace mlk { + +namespace client { + +namespace { + +/* + * conversion maps + * ------------------------------------------------------------------ + * + * There is a difference between scancode and key codes. The scancode is the + * key located on the keyboard which is always the same, the key code is the + * translated to the user layout. + * + * For example, on azerty, hitting the 'a' key makes a key code of 'a' but a + * scancode of 'q'. + * + * - scancodes_map : convert SDL scancode do key + * - keycodes_map : convert SDL key code to key + * - modifiers_map : convert masks + * - button_map : convert SDL mouse buttons + */ + +const std::unordered_map<SDL_Keycode, key> scancodes_map{ + { SDL_SCANCODE_A, key::a }, + { SDL_SCANCODE_B, key::b }, + { SDL_SCANCODE_C, key::c }, + { SDL_SCANCODE_D, key::d }, + { SDL_SCANCODE_E, key::e }, + { SDL_SCANCODE_F, key::f }, + { SDL_SCANCODE_G, key::g }, + { SDL_SCANCODE_H, key::h }, + { SDL_SCANCODE_I, key::i }, + { SDL_SCANCODE_J, key::j }, + { SDL_SCANCODE_K, key::k }, + { SDL_SCANCODE_L, key::l }, + { SDL_SCANCODE_M, key::m }, + { SDL_SCANCODE_N, key::n }, + { SDL_SCANCODE_O, key::o }, + { SDL_SCANCODE_P, key::p }, + { SDL_SCANCODE_Q, key::q }, + { SDL_SCANCODE_R, key::r }, + { SDL_SCANCODE_S, key::s }, + { SDL_SCANCODE_T, key::t }, + { SDL_SCANCODE_U, key::u }, + { SDL_SCANCODE_V, key::v }, + { SDL_SCANCODE_W, key::w }, + { SDL_SCANCODE_X, key::x }, + { SDL_SCANCODE_Y, key::y }, + { SDL_SCANCODE_Z, key::z }, + { SDL_SCANCODE_1, key::one }, + { SDL_SCANCODE_2, key::two }, + { SDL_SCANCODE_3, key::three }, + { SDL_SCANCODE_4, key::four }, + { SDL_SCANCODE_5, key::five }, + { SDL_SCANCODE_6, key::six }, + { SDL_SCANCODE_7, key::seven }, + { SDL_SCANCODE_8, key::eight }, + { SDL_SCANCODE_9, key::nine }, + { SDL_SCANCODE_0, key::zero }, + { SDL_SCANCODE_RETURN, key::enter }, + { SDL_SCANCODE_ESCAPE, key::escape }, + { SDL_SCANCODE_BACKSPACE, key::backspace }, + { SDL_SCANCODE_TAB, key::tab }, + { SDL_SCANCODE_SPACE, key::space }, + { SDL_SCANCODE_MINUS, key::minus }, + { SDL_SCANCODE_EQUALS, key::equals }, + { SDL_SCANCODE_LEFTBRACKET, key::left_bracket }, + { SDL_SCANCODE_RIGHTBRACKET, key::right_bracket }, + { SDL_SCANCODE_BACKSLASH, key::backslash }, + { SDL_SCANCODE_NONUSHASH, key::hash }, + { SDL_SCANCODE_SEMICOLON, key::semicolon }, + { SDL_SCANCODE_APOSTROPHE, key::apostrophe }, + { SDL_SCANCODE_GRAVE, key::grave }, + { SDL_SCANCODE_COMMA, key::comma }, + { SDL_SCANCODE_PERIOD, key::period }, + { SDL_SCANCODE_SLASH, key::slash }, + { SDL_SCANCODE_CAPSLOCK, key::caps_lock }, + { SDL_SCANCODE_F1, key::f1 }, + { SDL_SCANCODE_F2, key::f2 }, + { SDL_SCANCODE_F3, key::f3 }, + { SDL_SCANCODE_F4, key::f4 }, + { SDL_SCANCODE_F5, key::f5 }, + { SDL_SCANCODE_F6, key::f6 }, + { SDL_SCANCODE_F7, key::f7 }, + { SDL_SCANCODE_F8, key::f8 }, + { SDL_SCANCODE_F9, key::f9 }, + { SDL_SCANCODE_F10, key::f10 }, + { SDL_SCANCODE_F11, key::f11 }, + { SDL_SCANCODE_F12, key::f12 }, + { SDL_SCANCODE_F13, key::f13 }, + { SDL_SCANCODE_F14, key::f14 }, + { SDL_SCANCODE_F15, key::f15 }, + { SDL_SCANCODE_F16, key::f16 }, + { SDL_SCANCODE_F17, key::f17 }, + { SDL_SCANCODE_F18, key::f18 }, + { SDL_SCANCODE_F19, key::f19 }, + { SDL_SCANCODE_F20, key::f20 }, + { SDL_SCANCODE_F21, key::f21 }, + { SDL_SCANCODE_F22, key::f22 }, + { SDL_SCANCODE_F23, key::f23 }, + { SDL_SCANCODE_F24, key::f24 }, + { SDL_SCANCODE_PRINTSCREEN, key::print_screen }, + { SDL_SCANCODE_SCROLLLOCK, key::scroll_lock }, + { SDL_SCANCODE_PAUSE, key::pause }, + { SDL_SCANCODE_INSERT, key::insert }, + { SDL_SCANCODE_HOME, key::home }, + { SDL_SCANCODE_PAGEUP, key::page_up }, + { SDL_SCANCODE_PAGEDOWN, key::page_down }, + { SDL_SCANCODE_DELETE, key::del }, + { SDL_SCANCODE_END, key::end }, + { SDL_SCANCODE_RIGHT, key::right }, + { SDL_SCANCODE_LEFT, key::left }, + { SDL_SCANCODE_DOWN, key::down }, + { SDL_SCANCODE_UP, key::up }, + { SDL_SCANCODE_KP_DIVIDE, key::kp_divide }, + { SDL_SCANCODE_KP_MULTIPLY, key::kp_multiply }, + { SDL_SCANCODE_KP_MINUS, key::kp_minus }, + { SDL_SCANCODE_KP_PLUS, key::kp_plus }, + { SDL_SCANCODE_KP_ENTER, key::kp_enter }, + { SDL_SCANCODE_KP_1, key::kp_one }, + { SDL_SCANCODE_KP_2, key::kp_two }, + { SDL_SCANCODE_KP_3, key::kp_three }, + { SDL_SCANCODE_KP_4, key::kp_four }, + { SDL_SCANCODE_KP_5, key::kp_five }, + { SDL_SCANCODE_KP_6, key::kp_six }, + { SDL_SCANCODE_KP_7, key::kp_seven }, + { SDL_SCANCODE_KP_8, key::kp_eight }, + { SDL_SCANCODE_KP_9, key::kp_nine }, + { SDL_SCANCODE_KP_0, key::kp_zero }, + { SDL_SCANCODE_MUTE, key::mute }, + { SDL_SCANCODE_VOLUMEUP, key::volume_up }, + { SDL_SCANCODE_VOLUMEDOWN, key::volume_down }, + { SDL_SCANCODE_LCTRL, key::left_control }, + { SDL_SCANCODE_LALT, key::left_alt }, + { SDL_SCANCODE_LSHIFT, key::left_shift }, + { SDL_SCANCODE_LGUI, key::left_super }, + { SDL_SCANCODE_RCTRL, key::right_control }, + { SDL_SCANCODE_RALT, key::right_alt }, + { SDL_SCANCODE_RSHIFT, key::right_shift }, + { SDL_SCANCODE_RGUI, key::right_super } +}; + +const std::unordered_map<SDL_Keycode, key> keycodes_map{ + { SDLK_RETURN, key::enter }, + { SDLK_ESCAPE, key::escape }, + { SDLK_BACKSPACE, key::backspace }, + { SDLK_TAB, key::tab }, + { SDLK_SPACE, key::space }, + { SDLK_EXCLAIM, key::exclaim }, + { SDLK_QUOTEDBL, key::double_quote }, + { SDLK_HASH, key::hash }, + { SDLK_PERCENT, key::percent }, + { SDLK_DOLLAR, key::dollar }, + { SDLK_AMPERSAND, key::ampersand }, + { SDLK_QUOTE, key::quote }, + { SDLK_LEFTPAREN, key::left_parenthese }, + { SDLK_RIGHTPAREN, key::right_parenthese }, + { SDLK_ASTERISK, key::asterisk }, + { SDLK_PLUS, key::plus }, + { SDLK_COMMA, key::comma }, + { SDLK_MINUS, key::minus }, + { SDLK_PERIOD, key::period }, + { SDLK_SLASH, key::slash }, + { SDLK_0, key::zero }, + { SDLK_1, key::one }, + { SDLK_2, key::two }, + { SDLK_3, key::three }, + { SDLK_4, key::four }, + { SDLK_5, key::five }, + { SDLK_6, key::six }, + { SDLK_7, key::seven }, + { SDLK_8, key::eight }, + { SDLK_9, key::nine }, + { SDLK_COLON, key::colon }, + { SDLK_SEMICOLON, key::semicolon }, + { SDLK_LESS, key::less }, + { SDLK_EQUALS, key::equals }, + { SDLK_GREATER, key::greater }, + { SDLK_QUESTION, key::question }, + { SDLK_AT, key::at }, + { SDLK_LEFTBRACKET, key::left_bracket }, + { SDLK_BACKSLASH, key::backslash }, + { SDLK_RIGHTBRACKET, key::right_bracket }, + { SDLK_CARET, key::caret }, + { SDLK_UNDERSCORE, key::underscore }, + { SDLK_BACKQUOTE, key::back_quote }, + { SDLK_a, key::a }, + { SDLK_b, key::b }, + { SDLK_c, key::c }, + { SDLK_d, key::d }, + { SDLK_e, key::e }, + { SDLK_f, key::f }, + { SDLK_g, key::g }, + { SDLK_h, key::h }, + { SDLK_i, key::i }, + { SDLK_j, key::j }, + { SDLK_k, key::k }, + { SDLK_l, key::l }, + { SDLK_m, key::m }, + { SDLK_n, key::n }, + { SDLK_o, key::o }, + { SDLK_p, key::p }, + { SDLK_q, key::q }, + { SDLK_r, key::r }, + { SDLK_s, key::s }, + { SDLK_t, key::t }, + { SDLK_u, key::u }, + { SDLK_v, key::v }, + { SDLK_w, key::w }, + { SDLK_x, key::x }, + { SDLK_y, key::y }, + { SDLK_z, key::z }, + { SDLK_CAPSLOCK, key::caps_lock }, + { SDLK_F1, key::f1 }, + { SDLK_F2, key::f2 }, + { SDLK_F3, key::f3 }, + { SDLK_F4, key::f4 }, + { SDLK_F5, key::f5 }, + { SDLK_F6, key::f6 }, + { SDLK_F7, key::f7 }, + { SDLK_F8, key::f8 }, + { SDLK_F9, key::f9 }, + { SDLK_F10, key::f10 }, + { SDLK_F11, key::f11 }, + { SDLK_F12, key::f12 }, + { SDLK_F13, key::f13 }, + { SDLK_F14, key::f14 }, + { SDLK_F15, key::f15 }, + { SDLK_F16, key::f16 }, + { SDLK_F17, key::f17 }, + { SDLK_F18, key::f18 }, + { SDLK_F19, key::f19 }, + { SDLK_F20, key::f20 }, + { SDLK_F21, key::f21 }, + { SDLK_F22, key::f22 }, + { SDLK_F23, key::f23 }, + { SDLK_F24, key::f24 }, + { SDLK_PRINTSCREEN, key::print_screen }, + { SDLK_SCROLLLOCK, key::scroll_lock }, + { SDLK_PAUSE, key::pause }, + { SDLK_INSERT, key::insert }, + { SDLK_HOME, key::home }, + { SDLK_PAGEUP, key::page_up }, + { SDLK_PAGEDOWN, key::page_down }, + { SDLK_DELETE, key::del }, + { SDLK_END, key::end }, + { SDLK_RIGHT, key::right }, + { SDLK_LEFT, key::left }, + { SDLK_DOWN, key::down }, + { SDLK_UP, key::up }, + { SDLK_KP_DIVIDE, key::kp_divide }, + { SDLK_KP_MULTIPLY, key::kp_multiply }, + { SDLK_KP_MINUS, key::kp_minus }, + { SDLK_KP_PLUS, key::kp_plus }, + { SDLK_KP_ENTER, key::kp_enter }, + { SDLK_KP_1, key::kp_one }, + { SDLK_KP_2, key::kp_two }, + { SDLK_KP_3, key::kp_three }, + { SDLK_KP_4, key::kp_four }, + { SDLK_KP_5, key::kp_five }, + { SDLK_KP_6, key::kp_six }, + { SDLK_KP_7, key::kp_seven }, + { SDLK_KP_8, key::kp_eight }, + { SDLK_KP_9, key::kp_nine }, + { SDLK_KP_0, key::kp_zero }, + { SDLK_MUTE, key::mute }, + { SDLK_VOLUMEUP, key::volume_up }, + { SDLK_VOLUMEDOWN, key::volume_down }, + { SDLK_LCTRL, key::left_control }, + { SDLK_LALT, key::left_alt }, + { SDLK_LSHIFT, key::left_shift }, + { SDLK_LGUI, key::left_super }, + { SDLK_RCTRL, key::right_control }, + { SDLK_RALT, key::right_alt }, + { SDLK_RSHIFT, key::right_shift }, + { SDLK_RGUI, key::right_super } +}; + +const std::unordered_map<SDL_Keymod, mod> modifiers_map{ + { KMOD_LCTRL, mod::left_control }, + { KMOD_LALT, mod::left_alt }, + { KMOD_LSHIFT, mod::left_shift }, + { KMOD_LGUI, mod::left_super }, + { KMOD_RCTRL, mod::right_control }, + { KMOD_RALT, mod::right_alt }, + { KMOD_RSHIFT, mod::right_shift }, + { KMOD_RGUI, mod::right_super }, + { KMOD_NUM, mod::num_lock }, + { KMOD_CAPS, mod::caps_lock } +}; + +const std::unordered_map<Uint32, mouse> button_map{ + { SDL_BUTTON_LEFT, mouse::left }, + { SDL_BUTTON_RIGHT, mouse::right }, + { SDL_BUTTON_MIDDLE, mouse::middle } +}; + +} // !namespace + +void window::backend_impl::handle_key(window& self, const SDL_Event& ev) +{ + assert(ev.type == SDL_KEYDOWN || ev.type == SDL_KEYUP); + + // Key and scan code. + auto kc = keycodes_map.find(ev.key.keysym.sym); + auto sc = scancodes_map.find(ev.key.keysym.scancode); + + if (kc == keycodes_map.end() || sc == scancodes_map.end()) { + return; + } + + key_event kev{kc->second, sc->second, mod::none}; + + // Modifier is a mask. + for (const auto& pair : modifiers_map) { + if (ev.key.keysym.mod & pair.first) { + kev.modifiers |= pair.second; + } + } + + if (ev.type == SDL_KEYDOWN) { + self.handle_key_down(kev); + } else { + self.handle_key_up(kev); + } +} + +void window::backend_impl::handle_mouse(window& self, const SDL_Event& ev) +{ + assert(ev.type == SDL_MOUSEBUTTONDOWN || ev.type == SDL_MOUSEBUTTONUP); + + auto which = button_map.find(ev.button.button); + + if (which == button_map.end()) { + return; + } + + mouse_click_event mev{ + which->second, + point(ev.button.x, ev.button.y) + }; + + if (ev.type == SDL_MOUSEBUTTONDOWN) { + self.handle_mouse_down(mev); + } else { + self.handle_mouse_up(mev); + } +} + +void window::backend_impl::handle_mouse_wheel(window& self, const SDL_Event& ev) +{ + assert(ev.type == SDL_MOUSEWHEEL); + + mouse_wheel_event wev{{ev.wheel.x, ev.wheel.y}}; + + self.handle_mouse_wheel(wev); +} + +window::backend_impl::backend_impl(window&, unsigned width, unsigned height, const std::string& title) + : m_window(nullptr, nullptr) + , m_renderer(nullptr, nullptr) +{ + SDL_SetMainReady(); + SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO); + + m_window = { + SDL_CreateWindow( + title.c_str(), + SDL_WINDOWPOS_UNDEFINED, + SDL_WINDOWPOS_UNDEFINED, + width, height, + SDL_WINDOW_OPENGL + ), + SDL_DestroyWindow + }; + + if (m_window == nullptr) { + throw std::runtime_error(SDL_GetError()); + } + + // Create renderer. + m_renderer = { + SDL_CreateRenderer(m_window.get(), -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC), + SDL_DestroyRenderer + }; + + if (m_renderer == nullptr) { + throw std::runtime_error(SDL_GetError()); + } + if (TTF_Init() == -1) { + throw std::runtime_error(TTF_GetError()); + } +} + +void window::backend_impl::clear() +{ + SDL_RenderClear(m_renderer.get()); +} + +void window::backend_impl::present() +{ + SDL_RenderPresent(m_renderer.get()); +} + +#if 0 + +// TODO: see later if it's really needed + +Size window::backend_impl::resolution() +{ + SDL_DisplayMode current; + int width = 0; + int height = 0; + for (int i = 0; i < SDL_GetNumVideoDisplays(); i++) { + int error = SDL_GetCurrentDisplayMode(i, ¤t); + if (error == 0) { + // Get the last one + // TODO test with only one display mode, but we have to test with more than that + width = current.w; + height = current.hpp; + } else { + throw std::runtime_error("Could not get display mode for video display" + std::string(SDL_GetError())); + } + } + + return Size((unsigned)width, (unsigned)height); +} + +#endif + +color window::backend_impl::drawing_color() const +{ + SDL_Color color; + + if (SDL_GetRenderDrawColor(m_renderer.get(), &color.r, &color.g, &color.b, &color.a) < 0) { + throw std::runtime_error(SDL_GetError()); + } + + return {color.r, color.g, color.b, color.a}; +} + +void window::backend_impl::set_drawing_color(const color& color) +{ + if (SDL_SetRenderDrawColor(m_renderer.get(), color.red(), color.green(), color.blue(), color.alpha()) < 0) { + throw std::runtime_error(SDL_GetError()); + } +} + +void window::backend_impl::draw_line(const line& line) +{ + if (SDL_RenderDrawLine(m_renderer.get(), line.x1(), line.y1(), line.x2(), line.y2()) != 0) { + throw std::runtime_error(SDL_GetError()); + } +} + +void window::backend_impl::draw_lines(const std::vector<point>& points) +{ + std::vector<SDL_Point> sdlpoints(points.size()); + + for (unsigned i = 0; i < points.size(); ++i) { + sdlpoints[i] = {points[i].x(), points[i].y()}; + } + + if (SDL_RenderDrawLines(m_renderer.get(), sdlpoints.data(), sdlpoints.size()) < 0) { + throw std::runtime_error(SDL_GetError()); + } +} + +void window::backend_impl::draw_point(const point& point) +{ + if (SDL_RenderDrawPoint(m_renderer.get(), point.x(), point.y()) != 0) { + throw std::runtime_error(SDL_GetError()); + } +} + +void window::backend_impl::draw_points(const std::vector<point>& points) +{ + std::vector<SDL_Point> sdlpoints(points.size()); + + for (unsigned i = 0; i < points.size(); ++i) { + sdlpoints[i] = {points[i].x(), points[i].y()}; + } + + if (SDL_RenderDrawPoints(m_renderer.get(), sdlpoints.data(), sdlpoints.size()) != 0) { + throw std::runtime_error(SDL_GetError()); + } +} + +void window::backend_impl::draw_rectangle(const rectangle& rectangle) +{ + SDL_Rect rect{ + rectangle.x(), + rectangle.y(), + static_cast<int>(rectangle.width()), + static_cast<int>(rectangle.height()) + }; + + if (SDL_RenderDrawRect(m_renderer.get(), &rect) < 0) { + throw std::runtime_error(SDL_GetError()); + } +} + +void window::backend_impl::draw_rectangles(const std::vector<rectangle>& rectangles) +{ + std::vector<SDL_Rect> sdlrects(rectangles.size()); + + for (unsigned i = 0; i < rectangles.size(); ++i) { + sdlrects[i] = { + rectangles[i].x(), + rectangles[i].y(), + static_cast<int>(rectangles[i].width()), + static_cast<int>(rectangles[i].height()) + }; + } + + if (SDL_RenderDrawRects(m_renderer.get(), sdlrects.data(), sdlrects.size()) != 0) { + throw std::runtime_error(SDL_GetError()); + } +} + +void window::backend_impl::fill_rectangle(const rectangle& rectangle) +{ + SDL_Rect rect{ + rectangle.x(), + rectangle.y(), + static_cast<int>(rectangle.width()), + static_cast<int>(rectangle.height()) + }; + + if (SDL_RenderFillRect(m_renderer.get(), &rect) < 0) { + throw std::runtime_error(SDL_GetError()); + } +} + +void window::backend_impl::fill_rectangles(const std::vector<rectangle>& rectangles) +{ + std::vector<SDL_Rect> sdlrects(rectangles.size()); + + for (unsigned i = 0; i < rectangles.size(); ++i) { + sdlrects[i] = { + rectangles[i].x(), + rectangles[i].y(), + static_cast<int>(rectangles[i].width()), + static_cast<int>(rectangles[i].height()) + }; + } + + if (SDL_RenderFillRects(m_renderer.get(), sdlrects.data(), sdlrects.size()) != 0) { + throw std::runtime_error(SDL_GetError()); + } +} + +void window::backend_impl::draw_text(const std::string& text, font& font, const rectangle& rectangle) +{ + SDL_Color color = {0, 0, 0, 255}; + SDL_Surface* message = TTF_RenderUTF8_Blended(font.backend().font(), text.c_str(), color); + SDL_Texture* texture = SDL_CreateTextureFromSurface(m_renderer.get(), message); + SDL_Rect rect = {rectangle.x(), rectangle.y(), (int)rectangle.width(), (int)rectangle.height()}; + SDL_RenderCopy(m_renderer.get(), texture, nullptr, &rect); + SDL_FreeSurface(message); + SDL_DestroyTexture(texture); +} + +void window::backend_impl::draw_text(const std::string &text, font& font, const point& point) +{ + SDL_Color color = {0, 0, 0, 0}; + SDL_GetRenderDrawColor(m_renderer.get(), &color.r, &color.g, &color.b, &color.a); + SDL_Surface* message = TTF_RenderUTF8_Blended(font.backend().font(), text.c_str(), color); + SDL_Texture* texture = SDL_CreateTextureFromSurface(m_renderer.get(), message); + SDL_Rect rect = {point.x(), point.y(), message->w, message->h}; + SDL_RenderCopy(m_renderer.get(), texture, nullptr, &rect); + SDL_FreeSurface(message); + SDL_DestroyTexture(texture); +} + +void window::backend_impl::close() +{ +} + +void window::backend_impl::poll(window& self) +{ + SDL_Event event; + + while (SDL_PollEvent(&event)) { + switch (event.type) { + case SDL_KEYUP: + case SDL_KEYDOWN: + handle_key(self, event); + break; + case SDL_MOUSEBUTTONDOWN: + case SDL_MOUSEBUTTONUP: + handle_mouse(self, event); + break; + case SDL_MOUSEWHEEL: + handle_mouse_wheel(self, event); + break; + case SDL_QUIT: + self.handle_quit(); + break; + default: + break; + } + } +} + +} // !client + +} // !mlk
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/client/backend/sdl/window_backend.hpp Sun Jan 22 11:07:36 2017 +0100 @@ -0,0 +1,87 @@ +/* + * window_backend.hpp -- window object (SDL2 implementation) + * + * Copyright (c) 2013-2017 Malikania Authors + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef MALIKANIA_WINDOW_BACKEND_HPP +#define MALIKANIA_WINDOW_BACKEND_HPP + +#include <memory> +#include <vector> + +#include <SDL.h> + +#include "window.hpp" + +namespace mlk { + +namespace client { + +class window::backend_impl { +private: + std::unique_ptr<SDL_Window, void (*)(SDL_Window *)> m_window; + std::unique_ptr<SDL_Renderer, void (*)(SDL_Renderer *)> m_renderer; + + void handle_key(window&, const SDL_Event&); + void handle_mouse(window&, const SDL_Event&); + void handle_mouse_wheel(window&, const SDL_Event&); + +public: + backend_impl(window& self, unsigned width, unsigned height, const std::string& title); + + inline SDL_Renderer* renderer() noexcept + { + return m_renderer.get(); + } + + void close(); + + void clear(); + + void present(); + + color drawing_color() const; + + void set_drawing_color(const color& color); + + void draw_line(const line& line); + + void draw_lines(const std::vector<point>& points); + + void draw_point(const point& point); + + void draw_points(const std::vector<point>& points); + + void draw_rectangle(const rectangle& rect); + + void draw_rectangles(const std::vector<rectangle>& rects); + + void fill_rectangle(const rectangle& rect); + + void fill_rectangles(const std::vector<rectangle>& rects); + + void draw_text(const std::string& text, font& font, const rectangle& rectangle); + + void draw_text(const std::string& text, font& font, const point& point); + + void poll(window &self); +}; + +} // !client + +} // !mlk + +#endif // !MALIKANIA_WINDOW_BACKEND_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/client/button.cpp Sun Jan 22 11:07:36 2017 +0100 @@ -0,0 +1,51 @@ +/* + * button.cpp -- GUI button element + * + * Copyright (c) 2013-2017 Malikania Authors + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "button.hpp" +#include "theme.hpp" +#include "window.hpp" + +namespace mlk { + +namespace client { + +button::button(std::string text) + : m_text(std::move(text)) +{ +} + +void button::handle_mouse_down(const mouse_click_event& ev) +{ + if (ev.button == mouse::left) { + on_clicked(); + } +} + +void button::draw(window& w, const rectangle& rect) +{ + w.theme().draw_button(w, *this, rect); +} + +mlk::client::size button::size(window& w) const noexcept +{ + return w.theme().size_button(*this); +} + +} // !client + +} // !mlk
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/client/button.hpp Sun Jan 22 11:07:36 2017 +0100 @@ -0,0 +1,101 @@ +/* + * button.hpp -- GUI button element + * + * Copyright (c) 2013-2017 Malikania Authors + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef MALIKANIA_CLIENT_BUTTON_HPP +#define MALIKANIA_CLIENT_BUTTON_HPP + +/** + * \file button.hpp + * \brief GUI button element. + */ + +#include <boost/signals2.hpp> + +#include <string> + +#include "widget.hpp" + +namespace mlk { + +namespace client { + +/** + * \brief Basic button element. + */ +class button : public widget { +public: + boost::signals2::signal<void()> on_clicked; + boost::signals2::signal<void()> on_released; + +private: + std::string m_text; + +public: + /** + * Default constructor with optional text. + * + * \param text the text + */ + button(std::string text = ""); + + /** + * Get the button text. + * + * \return the text + */ + inline const std::string& text() const noexcept + { + return m_text; + } + + /** + * Set the button text. + * + * \param text the text + */ + inline void set_text(std::string text) noexcept + { + m_text = std::move(text); + } + + /** + * \copydoc widget::handle_mouse_down + */ + void handle_mouse_down(const mouse_click_event& ev) override; + + /** + * Bring back other functions. + */ + using widget::draw; + + /** + * \copydoc widget::draw + */ + void draw(window& w, const rectangle& rect) override; + + /** + * \copydoc widget::size + */ + mlk::client::size size(window& w) const noexcept override; +}; + +} // !client + +} // !mlk + +#endif // !MALIKANIA_CLIENT_BUTTON_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/client/color.cpp Sun Jan 22 11:07:36 2017 +0100 @@ -0,0 +1,241 @@ +/* + * color.cpp -- color description + * + * Copyright (c) 2013-2017 Malikania Authors + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <cctype> +#include <locale> +#include <unordered_map> + +#include "color.hpp" + +namespace mlk { + +namespace client { + +namespace { + +constexpr unsigned rgb(std::uint8_t r, std::uint8_t g, std::uint8_t b) noexcept +{ + return (0xff000000 | (r << 16) | (g << 8) | b); +} + +/* + * Convert hexadecimal value to the correct number. + */ +std::uint8_t value(char digit) +{ + if (std::isdigit(digit, {})) { + return digit - '0'; + } + if ((digit = std::toupper(digit, {})) < 'A' || digit > 'F') { + throw std::invalid_argument("invalid hexadecimal value: " + std::to_string(digit)); + } + + return digit - 55; +} + +inline std::uint8_t value(char digit1, char digit2) +{ + return ((value(digit1) << 4) & 0xf0) | value(digit2); +} + +const std::unordered_map<std::string, std::uint32_t> colors{ + { "aliceblue", rgb(240, 248, 255) }, + { "antiquewhite", rgb(250, 235, 215) }, + { "aqua", rgb( 0, 255, 255) }, + { "aquamarine", rgb(127, 255, 212) }, + { "azure", rgb(240, 255, 255) }, + { "beige", rgb(245, 245, 220) }, + { "bisque", rgb(255, 228, 196) }, + { "black", rgb( 0, 0, 0) }, + { "blanchedalmond", rgb(255, 235, 205) }, + { "blue", rgb( 0, 0, 255) }, + { "blueviolet", rgb(138, 43, 226) }, + { "brown", rgb(165, 42, 42) }, + { "burlywood", rgb(222, 184, 135) }, + { "cadetblue", rgb( 95, 158, 160) }, + { "chartreuse", rgb(127, 255, 0) }, + { "chocolate", rgb(210, 105, 30) }, + { "coral", rgb(255, 127, 80) }, + { "cornflowerblue", rgb(100, 149, 237) }, + { "cornsilk", rgb(255, 248, 220) }, + { "crimson", rgb(220, 20, 60) }, + { "cyan", rgb( 0, 255, 255) }, + { "darkblue", rgb( 0, 0, 139) }, + { "darkcyan", rgb( 0, 139, 139) }, + { "darkgoldenrod", rgb(184, 134, 11) }, + { "darkgray", rgb(169, 169, 169) }, + { "darkgreen", rgb( 0, 100, 0) }, + { "darkgrey", rgb(169, 169, 169) }, + { "darkkhaki", rgb(189, 183, 107) }, + { "darkmagenta", rgb(139, 0, 139) }, + { "darkolivegreen", rgb( 85, 107, 47) }, + { "darkorange", rgb(255, 140, 0) }, + { "darkorchid", rgb(153, 50, 204) }, + { "darkred", rgb(139, 0, 0) }, + { "darksalmon", rgb(233, 150, 122) }, + { "darkseagreen", rgb(143, 188, 143) }, + { "darkslateblue", rgb( 72, 61, 139) }, + { "darkslategray", rgb( 47, 79, 79) }, + { "darkslategrey", rgb( 47, 79, 79) }, + { "darkturquoise", rgb( 0, 206, 209) }, + { "darkviolet", rgb(148, 0, 211) }, + { "deeppink", rgb(255, 20, 147) }, + { "deepskyblue", rgb( 0, 191, 255) }, + { "dimgray", rgb(105, 105, 105) }, + { "dimgrey", rgb(105, 105, 105) }, + { "dodgerblue", rgb( 30, 144, 255) }, + { "firebrick", rgb(178, 34, 34) }, + { "floralwhite", rgb(255, 250, 240) }, + { "forestgreen", rgb( 34, 139, 34) }, + { "fuchsia", rgb(255, 0, 255) }, + { "gainsboro", rgb(220, 220, 220) }, + { "ghostwhite", rgb(248, 248, 255) }, + { "gold", rgb(255, 215, 0) }, + { "goldenrod", rgb(218, 165, 32) }, + { "gray", rgb(128, 128, 128) }, + { "green", rgb( 0, 128, 0) }, + { "greenyellow", rgb(173, 255, 47) }, + { "grey", rgb(128, 128, 128) }, + { "honeydew", rgb(240, 255, 240) }, + { "hotpink", rgb(255, 105, 180) }, + { "indianred", rgb(205, 92, 92) }, + { "indigo", rgb( 75, 0, 130) }, + { "ivory", rgb(255, 255, 240) }, + { "khaki", rgb(240, 230, 140) }, + { "lavender", rgb(230, 230, 250) }, + { "lavenderblush", rgb(255, 240, 245) }, + { "lawngreen", rgb(124, 252, 0) }, + { "lemonchiffon", rgb(255, 250, 205) }, + { "lightblue", rgb(173, 216, 230) }, + { "lightcoral", rgb(240, 128, 128) }, + { "lightcyan", rgb(224, 255, 255) }, + { "lightgoldenrodyellow", rgb(250, 250, 210) }, + { "lightgray", rgb(211, 211, 211) }, + { "lightgreen", rgb(144, 238, 144) }, + { "lightgrey", rgb(211, 211, 211) }, + { "lightpink", rgb(255, 182, 193) }, + { "lightsalmon", rgb(255, 160, 122) }, + { "lightseagreen", rgb( 32, 178, 170) }, + { "lightskyblue", rgb(135, 206, 250) }, + { "lightslategray", rgb(119, 136, 153) }, + { "lightslategrey", rgb(119, 136, 153) }, + { "lightsteelblue", rgb(176, 196, 222) }, + { "lightyellow", rgb(255, 255, 224) }, + { "lime", rgb( 0, 255, 0) }, + { "limegreen", rgb( 50, 205, 50) }, + { "linen", rgb(250, 240, 230) }, + { "magenta", rgb(255, 0, 255) }, + { "maroon", rgb(128, 0, 0) }, + { "mediumaquamarine", rgb(102, 205, 170) }, + { "mediumblue", rgb( 0, 0, 205) }, + { "mediumorchid", rgb(186, 85, 211) }, + { "mediumpurple", rgb(147, 112, 219) }, + { "mediumseagreen", rgb( 60, 179, 113) }, + { "mediumslateblue", rgb(123, 104, 238) }, + { "mediumspringgreen", rgb( 0, 250, 154) }, + { "mediumturquoise", rgb( 72, 209, 204) }, + { "mediumvioletred", rgb(199, 21, 133) }, + { "midnightblue", rgb( 25, 25, 112) }, + { "mintcream", rgb(245, 255, 250) }, + { "mistyrose", rgb(255, 228, 225) }, + { "moccasin", rgb(255, 228, 181) }, + { "navajowhite", rgb(255, 222, 173) }, + { "navy", rgb( 0, 0, 128) }, + { "oldlace", rgb(253, 245, 230) }, + { "olive", rgb(128, 128, 0) }, + { "olivedrab", rgb(107, 142, 35) }, + { "orange", rgb(255, 165, 0) }, + { "orangered", rgb(255, 69, 0) }, + { "orchid", rgb(218, 112, 214) }, + { "palegoldenrod", rgb(238, 232, 170) }, + { "palegreen", rgb(152, 251, 152) }, + { "paleturquoise", rgb(175, 238, 238) }, + { "palevioletred", rgb(219, 112, 147) }, + { "papayawhip", rgb(255, 239, 213) }, + { "peachpuff", rgb(255, 218, 185) }, + { "peru", rgb(205, 133, 63) }, + { "pink", rgb(255, 192, 203) }, + { "plum", rgb(221, 160, 221) }, + { "powderblue", rgb(176, 224, 230) }, + { "purple", rgb(128, 0, 128) }, + { "red", rgb(255, 0, 0) }, + { "rosybrown", rgb(188, 143, 143) }, + { "royalblue", rgb( 65, 105, 225) }, + { "saddlebrown", rgb(139, 69, 19) }, + { "salmon", rgb(250, 128, 114) }, + { "sandybrown", rgb(244, 164, 96) }, + { "seagreen", rgb( 46, 139, 87) }, + { "seashell", rgb(255, 245, 238) }, + { "sienna", rgb(160, 82, 45) }, + { "silver", rgb(192, 192, 192) }, + { "skyblue", rgb(135, 206, 235) }, + { "slateblue", rgb(106, 90, 205) }, + { "slategray", rgb(112, 128, 144) }, + { "slategrey", rgb(112, 128, 144) }, + { "snow", rgb(255, 250, 250) }, + { "springgreen", rgb( 0, 255, 127) }, + { "steelblue", rgb( 70, 130, 180) }, + { "tan", rgb(210, 180, 140) }, + { "teal", rgb( 0, 128, 128) }, + { "thistle", rgb(216, 191, 216) }, + { "tomato", rgb(255, 99, 71) }, + { "transparent", 0 }, + { "turquoise", rgb( 64, 224, 208) }, + { "violet", rgb(238, 130, 238) }, + { "wheat", rgb(245, 222, 179) }, + { "white", rgb(255, 255, 255) }, + { "whitesmoke", rgb(245, 245, 245) }, + { "yellow", rgb(255, 255, 0) }, + { "yellowgreen", rgb(154, 205, 50) } +}; + +} // !namespace + +color::color(const std::string& name) +{ + if (!name.empty()) { + // Parse #rrggbb or #rgb. + if (name[0] == '#') { + if (name.length() == 7) { + m_red = value(name[1], name[2]); + m_green = value(name[3], name[4]); + m_blue = value(name[5], name[6]); + } else if (name.length() == 4) { + m_red = value(name[1], name[1]); + m_green = value(name[2], name[2]); + m_blue = value(name[3], name[3]); + } else { + throw std::invalid_argument("invalid format"); + } + } else { + // Name lookup. + auto it = colors.find(name); + + if (it == colors.end()) { + throw std::invalid_argument(name + " is not a valid color"); + } + + // Assign the color to *this. + *this = it->second; + } + } +} + +} // !client + +} // !mlk
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/client/color.hpp Sun Jan 22 11:07:36 2017 +0100 @@ -0,0 +1,134 @@ +/* + * color.hpp -- color description + * + * Copyright (c) 2013-2017 Malikania Authors + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef MALIKANIA_COLOR_HPP +#define MALIKANIA_COLOR_HPP + +/** + * \file color.hpp + * \brief Colors. + */ + +#include <cstdint> +#include <string> + +namespace mlk { + +namespace client { + +/** + * \brief color description + */ +class color { +private: + std::uint8_t m_red{0}; + std::uint8_t m_green{0}; + std::uint8_t m_blue{0}; + std::uint8_t m_alpha{255}; + +public: + /** + * Default color to black. + */ + inline color() noexcept = default; + + /** + * Constructor with all fields. + * + * \param red the red value + * \param green the green value + * \param blue the blue value + * \param alpha the alpha value + */ + inline color(std::uint8_t red, std::uint8_t green, std::uint8_t blue, std::uint8_t alpha) noexcept + : m_red(red) + , m_green(green) + , m_blue(blue) + , m_alpha(alpha) + { + } + + /** + * Constructor with an hexadecimal value. + * + * \param hex the color + */ + inline color(std::uint32_t hex) noexcept + : m_red((hex >> 16) & 0xff) + , m_green((hex >> 8) & 0xff) + , m_blue(hex & 0xff) + , m_alpha((hex >> 24) & 0xff) + { + } + + /** + * Construct a color from #rrggbb or name. + * + * See the SVG this [list](http://www.december.com/html/spec/colorsvg.html) for supported names. + * + * \param name the color name + * \throw std::invalid_argument if the color does not exist or is invalid + */ + color(const std::string& name); + + /** + * Get the red value. + * + * \return the value + */ + inline std::uint8_t red() const noexcept + { + return m_red; + } + + /** + * Get the green value. + * + * \return the value + */ + inline std::uint8_t green() const noexcept + { + return m_green; + } + + /** + * Get the blue value. + * + * \return the value + */ + inline std::uint8_t blue() const noexcept + { + return m_blue; + } + + /** + * Get the alpha value. + * + * \return the value + */ + inline std::uint8_t alpha() const noexcept + { + return m_alpha; + } +}; + +} // !client + +} // !mlk + +#endif // !MALIKANIA_COLOR_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/client/font.cpp Sun Jan 22 11:07:36 2017 +0100 @@ -0,0 +1,44 @@ +/* + * font.cpp -- font object + * + * Copyright (c) 2013-2017 Malikania Authors + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "font_backend.hpp" + +namespace mlk { + +namespace client { + +font::font(std::string data, unsigned size) + : m_backend(std::make_unique<backend_impl>(std::move(data), size)) + , m_size(size) +{ +} + +font::font(font&& other) noexcept = default; + +font::~font() noexcept = default; + +size font::clip(const std::string& text) const +{ + return m_backend->clip(*this, text); +} + +font& font::operator=(font&& other) noexcept = default; + +} // !client + +} // !mlk
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/client/font.hpp Sun Jan 22 11:07:36 2017 +0100 @@ -0,0 +1,118 @@ +/* + * font.hpp -- font object + * + * Copyright (c) 2013-2017 Malikania Authors + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef MALIKANIA_FONT_HPP +#define MALIKANIA_FONT_HPP + +/** + * \file font.hpp + * \brief fonts. + */ + +#include <memory> +#include <string> + +#include "size.hpp" + +namespace mlk { + +namespace client { + +/** + * \brief font object. + */ +class font { +private: + class backend_impl; + + std::unique_ptr<backend_impl> m_backend; + unsigned m_size; + +public: + /** + * Construct a font from binary data. + * + * \param data the raw data + * \param size the size + */ + font(std::string data, unsigned size); + + /** + * Default move constructor. + * + * \param other the other font + */ + font(font&& other) noexcept; + + /** + * Default destructor. + */ + virtual ~font() noexcept; + + /** + * Get the font size. + * + * \return the font size + */ + inline unsigned size() const noexcept + { + return m_size; + } + + /** + * Get the underlying backend. + * + * \return the backend + */ + inline const backend_impl& backend() const noexcept + { + return *m_backend; + } + + /** + * Overloaded function. + * + * \return the backend + */ + inline backend_impl& backend() noexcept + { + return *m_backend; + } + + /** + * Get the clipping size required to draw the given text. + * + * \param text the text to clip + * \return the required size + */ + mlk::client::size clip(const std::string& text) const; + + /** + * Default move assignment operator. + * + * \param other the other font + * \return this + */ + font& operator=(font&& other) noexcept; +}; + +} // !client + +} // !mlk + +#endif // MALIKANIA_FONT_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/client/frame.cpp Sun Jan 22 11:07:36 2017 +0100 @@ -0,0 +1,49 @@ +/* + * frame.cpp -- top level GUI frame + * + * Copyright (c) 2013-2017 Malikania Authors + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "layout.hpp" +#include "frame.hpp" +#include "point.hpp" +#include "rectangle.hpp" +#include "theme.hpp" +#include "window.hpp" + +namespace mlk { + +namespace client { + +mlk::client::size frame::size(window &win) +{ + return m_layout ? m_layout->size(win) : mlk::client::size(); +} + +void frame::draw(window& win) +{ + if (m_layout) { + win.theme().draw_frame(win, *this); + } +} + +void frame::move(point pos) +{ + m_position = std::move(pos); +} + +} // !client + +} // !mlk
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/client/frame.hpp Sun Jan 22 11:07:36 2017 +0100 @@ -0,0 +1,178 @@ +/* + * frame.hpp -- top level GUI frame + * + * Copyright (c) 2013-2017 Malikania Authors + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef MALIKANIA_CLIENT_FRAME_HPP +#define MALIKANIA_CLIENT_FRAME_HPP + +/** + * \file frame.hpp + * \brief Top level GUI frame. + */ + +#include <memory> + +#include "point.hpp" +#include "size.hpp" + +namespace mlk { + +namespace client { + +class layout; +class point; +class window; + +/** + * \brief Top level GUI frame. + */ +class frame { +private: + std::shared_ptr<mlk::client::layout> m_layout; + mlk::client::point m_position; + mlk::client::size m_padding{10, 10}; + +public: + /** + * Create a frame with an optional layout. + * + * \param layout the optional layout + */ + inline frame(std::shared_ptr<mlk::client::layout> layout = nullptr) noexcept + : m_layout(std::move(layout)) + { + } + + /** + * Virtual destructor defaulted. + */ + virtual ~frame() = default; + + /** + * Get the current layout. + * + * return the layout + */ + inline const std::shared_ptr<mlk::client::layout>& layout() const noexcept + { + return m_layout; + } + + /** + * Overloaded function. + * + * \return the layout + */ + inline std::shared_ptr<mlk::client::layout>& layout() noexcept + { + return m_layout; + } + + /** + * Change the current frame layout. + * + * \param layout the new layout (may be null) + */ + inline void set_layout(std::shared_ptr<mlk::client::layout> layout) noexcept + { + m_layout = std::move(layout); + } + + /** + * Get the current frame position. + * + * \return the frame position + */ + inline const point& position() const noexcept + { + return m_position; + } + + /** + * Overloaded function. + * + * \return the position + */ + inline point& position() noexcept + { + return m_position; + } + + /** + * Get the frame padding. + * + * \return the frame padding + */ + inline const mlk::client::size& padding() const noexcept + { + return m_padding; + } + + /** + * Overloaded function. + * + * \return the padding + */ + inline mlk::client::size& padding() noexcept + { + return m_padding; + } + + /** + * Set the frame padding. + * + * \param padding the padding + */ + inline void set_padding(mlk::client::size padding) noexcept + { + m_padding = std::move(padding); + } + + /** + * Compute the total frame size. + * + * If no layout is attached, the frame returns a null size. Otherwise, the + * default implementation returns `layout()->size()`. + * + * \param win the window + * \return the size required to draw this frame + */ + virtual mlk::client::size size(window& win); + + /** + * Draw the frame and its content. + * + * If no layout is attached, the function is a no-op. Otherwise the default + * implementation calls `win.theme().draw_frame(*this)`. + * + * \param win the window + */ + virtual void draw(window& win); + + /** + * Move the frame to somewhere else. + * + * \param pos the new position + */ + virtual void move(point pos); +}; + +} // !client + +} // !mlk + +#endif // !MALIKANIA_CLIENT_FRAME_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/client/grid_layout.cpp Sun Jan 22 11:07:36 2017 +0100 @@ -0,0 +1,112 @@ +/* + * grid_layout.cpp -- basic grid layout + * + * Copyright (c) 2013-2016 Malikania Authors + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <algorithm> +#include <numeric> + +#include "grid_layout.hpp" +#include "size.hpp" +#include "widget.hpp" + +namespace mlk { + +unsigned grid_layout::index(unsigned r, unsigned c) const noexcept +{ + return r * m_cols + c; +} + +void grid_layout::update_rsize(window& win) noexcept +{ + for (unsigned r = 0; r < m_rows; ++r) { + m_min_rsize[r] = 0; + + for (unsigned c = 0; c < m_cols; ++c) { + auto idx = index(r, c); + + if (!m_widgets[idx]) { + continue; + } + + auto size = m_widgets[index(r, c)]->size(win); + + if (size.height() > m_min_rsize[r]) { + m_min_rsize[r] = size.height(); + } + } + } +} + +void grid_layout::update_csize(window& win) noexcept +{ + for (unsigned c = 0; c < m_cols; ++c) { + m_min_csize[c] = 0; + + for (unsigned r = 0; r < m_rows; ++r) { + auto idx = index(r, c); + + if (!m_widgets[idx]) { + continue; + } + + auto size = m_widgets[index(r, c)]->size(win); + + if (size.width() > m_min_csize[c]) { + m_min_csize[c] = size.width(); + } + } + } +} + +grid_layout::grid_layout(unsigned rows, unsigned columns) + : m_rows(rows) + , m_cols(columns) +{ + m_widgets.resize(rows * columns); + m_min_rsize.resize(rows); + m_min_csize.resize(columns); +} + +void grid_layout::add_widget(unsigned r, unsigned c, std::shared_ptr<widget> w) +{ + m_widgets[index(r, c)] = std::move(w); +} + +void grid_layout::remove_widget(unsigned r, unsigned c) +{ + m_widgets[index(r, c)] = nullptr; +} + +void grid_layout::remove_widget(std::shared_ptr<widget> w) +{ + m_widgets.erase(std::remove(m_widgets.begin(), m_widgets.end(), w), m_widgets.end()); +} + +mlk::size grid_layout::size(window& win) const noexcept +{ + return { + std::accumulate(m_min_csize.begin(), m_min_csize.end(), 0) + (m_rows * 10), + std::accumulate(m_min_rsize.begin(), m_min_rsize.end(), 0) + (m_cols * 10) + }; +} + +void grid_layout::draw(window &win, const rectangle &dst) +{ + +} + +} // !mlk
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/client/grid_layout.hpp Sun Jan 22 11:07:36 2017 +0100 @@ -0,0 +1,70 @@ +/* + * grid_layout.hpp -- basic grid layout + * + * Copyright (c) 2013-2016 Malikania Authors + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef MALIKANIA_CLIENT_GRID_LAYOUT_HPP +#define MALIKANIA_CLIENT_GRID_LAYOUT_HPP + +#include <memory> +#include <vector> + +#include "layout.hpp" + +namespace mlk { + +class widget; + +class grid_layout : public layout { +private: + // Dimensions. + unsigned m_rows; + unsigned m_cols; + + // Widgets. + std::vector<std::shared_ptr<widget>> m_widgets; + + /* + * Track maximum size by rows/columns to determine the minimum whole + * layout size. + * + * It's only used in draw() but kept as member variables to avoid useless + * reallocation on each frame. + */ + std::vector<unsigned> m_min_rsize; + std::vector<unsigned> m_min_csize; + + unsigned index(unsigned, unsigned) const noexcept; + void update_rsize(window&) noexcept; + void update_csize(window&) noexcept; + +public: + grid_layout(unsigned rows, unsigned columns); + + void add_widget(unsigned r, unsigned c, std::shared_ptr<widget> w); + + void remove_widget(unsigned r, unsigned c); + + void remove_widget(std::shared_ptr<widget> w); + + mlk::size size(window& win) const noexcept override; + + void draw(window& win, const rectangle& dst) override; +}; + +} // !mlk + +#endif // !MALIKANIA_CLIENT_GRID_LAYOUT_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/client/image.cpp Sun Jan 22 11:07:36 2017 +0100 @@ -0,0 +1,53 @@ +/* + * image.cpp -- image object + * + * Copyright (c) 2013-2017 Malikania Authors + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "image_backend.hpp" + +namespace mlk { + +namespace client { + +image::image(std::string data) + : m_backend(new backend_impl(*this, std::move(data))) +{ +} + +image::image(image&&) noexcept = default; + +image::~image() noexcept = default; + +const mlk::client::size& image::size() const noexcept +{ + return m_backend->size(); +} + +void image::draw(window& window, const point& position) +{ + m_backend->draw(window, position); +} + +void image::draw(window& window, const rectangle& source, const rectangle& target) +{ + m_backend->draw(window, source, target); +} + +image& image::operator=(image&&) noexcept = default; + +} // !client + +} // !mlk
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/client/image.hpp Sun Jan 22 11:07:36 2017 +0100 @@ -0,0 +1,127 @@ +/* + * image.hpp -- image object + * + * Copyright (c) 2013-2017 Malikania Authors + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef MALIKANIA_IMAGE_HPP +#define MALIKANIA_IMAGE_HPP + +/** + * \file image.hpp + * \brief Images. + */ + +#include <memory> +#include <string> + +#include "point.hpp" +#include "rectangle.hpp" +#include "size.hpp" + +namespace mlk { + +namespace client { + +class window; + +/** + * \brief Image object. + */ +class image { +private: + class backend_impl; + + std::unique_ptr<backend_impl> m_backend; + +public: + /** + * Construct an image from the binary data. + * + * \param window the window + * \param data the data + */ + image(std::string data); + + /** + * Default move constructor. + * + * \param other the other image + */ + image(image&& other) noexcept; + + /** + * Default destructor. + */ + ~image() noexcept; + + /** + * Overloaded function. + * + * \return the backend + */ + inline class backend_impl& backend() noexcept + { + return *m_backend; + } + + /** + * Get the underlying backend. + * + * \return the backend + */ + inline const backend_impl& backend() const noexcept + { + return *m_backend; + } + + /** + * Get the image size. + * + * \return the size + */ + const mlk::client::size& size() const noexcept; + + /** + * Draw the image to the window. + * + * \param window the window + * \param position the position + */ + void draw(window& window, const point& position = {0, 0}); + + /** + * Overloaded function. + * + * \param window the window + * \param source the source to clip + * \param target the target destination + */ + void draw(window& window, const rectangle& source, const rectangle& target); + + /** + * Default move assignment operator. + * + * \param other the other image + * \return this + */ + image& operator=(image&& image) noexcept; +}; + +} // !client + +} // !mlk + +#endif // !MALIKANIA_IMAGE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/client/key.hpp Sun Jan 22 11:07:36 2017 +0100 @@ -0,0 +1,248 @@ +/* + * key.hpp -- key definitions + * + * Copyright (c) 2013-2017 Malikania Authors + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef MALIKANIA_CLIENT_KEY_HPP +#define MALIKANIA_CLIENT_KEY_HPP + +namespace mlk { + +namespace client { + +/** + * \brief Describe keyboard modifiers + * + * This enumeration is a satisfied the Bitmask concept. + */ +enum class mod { + none = 0, //!< no modifiers + left_control = (1 << 1), //!< left control + left_alt = (1 << 2), //!< left alt + left_shift = (1 << 3), //!< left shift + left_super = (1 << 4), //!< left logo + right_control = (1 << 5), //!< right control + right_alt = (1 << 6), //!< right alt + right_shift = (1 << 7), //!< right shift + right_super = (1 << 8), //!< right logo + num_lock = (1 << 9), //!< num lock is on + caps_lock = (1 << 10), //!< caps lock is on + control = left_control | //!< left or right control + right_control, + shift = left_shift | //!< left or right shift + right_shift, + alt = left_alt | //!< left or right alt + right_alt, + super = left_super | //!< left or right super + right_super +}; + +/** + * \cond ENUM_HIDDEN_SYMBOLS + */ + +inline mod operator^(mod v1, mod v2) noexcept +{ + return static_cast<mod>(static_cast<unsigned>(v1) ^ static_cast<unsigned>(v2)); +} + +inline mod operator&(mod v1, mod v2) noexcept +{ + return static_cast<mod>(static_cast<unsigned>(v1)& static_cast<unsigned>(v2)); +} + +inline mod operator|(mod v1, mod v2) noexcept +{ + return static_cast<mod>(static_cast<unsigned>(v1) | static_cast<unsigned>(v2)); +} + +inline mod operator~(mod v) noexcept +{ + return static_cast<mod>(~static_cast<unsigned>(v)); +} + +inline mod& operator|=(mod& v1, mod v2) noexcept +{ + v1 = static_cast<mod>(static_cast<unsigned>(v1) | static_cast<unsigned>(v2)); + + return v1; +} + +inline mod& operator&=(mod& v1, mod v2) noexcept +{ + v1 = static_cast<mod>(static_cast<unsigned>(v1)& static_cast<unsigned>(v2)); + + return v1; +} + +inline mod& operator^=(mod& v1, mod v2) noexcept +{ + v1 = static_cast<mod>(static_cast<unsigned>(v1) ^ static_cast<unsigned>(v2)); + + return v1; +} + +/** + * \endcond + */ + +/** + * \brief Key description. + */ +enum class key { + unknown, + a, + b, + c, + d, + e, + f, + g, + h, + i, + j, + k, + l, + m, + n, + o, + p, + q, + r, + s, + t, + u, + v, + w, + x, + y, + z, + exclaim, + double_quote, + percent, + dollar, + ampersand, + left_parenthese, + right_parenthese, + asterisk, + plus, + colon, + less, + greater, + question, + at, + caret, + underscore, + back_quote, + quote, + one, + two, + three, + four, + five, + six, + seven, + eight, + nine, + zero, + enter, + escape, + backspace, + tab, + space, + minus, + equals, + left_bracket, + right_bracket, + backslash, + hash, + semicolon, + apostrophe, + grave, + comma, + period, + slash, + caps_lock, + f1, + f2, + f3, + f4, + f5, + f6, + f7, + f8, + f9, + f10, + f11, + f12, + f13, + f14, + f15, + f16, + f17, + f18, + f19, + f20, + f21, + f22, + f23, + f24, + print_screen, + scroll_lock, + pause, + insert, + home, + page_up, + page_down, + del, + end, + right, + left, + down, + up, + kp_divide, + kp_multiply, + kp_minus, + kp_plus, + kp_enter, + kp_one, + kp_two, + kp_three, + kp_four, + kp_five, + kp_six, + kp_seven, + kp_eight, + kp_nine, + kp_zero, + mute, + volume_up, + volume_down, + left_control, + left_alt, + left_shift, + left_super, + right_control, + right_alt, + right_shift, + right_super +}; + +} // !client + +} // !mlk + +#endif // !MALIKANIA_CLIENT_KEY_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/client/label.cpp Sun Jan 22 11:07:36 2017 +0100 @@ -0,0 +1,45 @@ +/* + * label.cpp -- GUI label element + * + * Copyright (c) 2013-2017 Malikania Authors + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "label.hpp" +#include "size.hpp" +#include "theme.hpp" +#include "window.hpp" + +namespace mlk { + +namespace client { + +label::label(std::string text) noexcept + : m_text(std::move(text)) +{ +} + +void label::draw(window& w, const rectangle& rect) +{ + w.theme().draw_label(w, *this, rect); +} + +mlk::client::size label::size(window& w) const noexcept +{ + return w.theme().size_label(*this); +} + +} // !client + +} // !mlk
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/client/label.hpp Sun Jan 22 11:07:36 2017 +0100 @@ -0,0 +1,97 @@ +/* + * label.hpp -- GUI label element + * + * Copyright (c) 2013-2017 Malikania Authors + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef MALIKANIA_CLIENT_LABEL_HPP +#define MALIKANIA_CLIENT_LABEL_HPP + +/** + * \file label.hp + * \brief GUI label element. + */ + +#include <string> + +#include "widget.hpp" + +namespace mlk { + +namespace client { + +/** + * \brief Basic label for displaying test. + */ +class label : public widget { +private: + std::string m_text; + +public: + /** + * Create a label with an optional text. + * + * \param text the text + */ + label(std::string text = "") noexcept; + + /** + * Get the text. + * + * \return the label text + */ + inline const std::string& text() const noexcept + { + return m_text; + } + + /** + * Overloaded function. + * + * \return the text + */ + inline std::string& text() noexcept + { + return m_text; + } + + /** + * Set the label text. + * + * \param text the text + */ + inline void set_text(std::string text) noexcept + { + m_text = std::move(text); + } + + using widget::draw; + + /** + * \copydoc widget::draw + */ + void draw(window& w, const rectangle& rect) override; + + /** + * \copydoc widget::size + */ + mlk::client::size size(window& w) const noexcept override; +}; + +} // !client + +} // !mlk + +#endif // !MALIKANIA_CLIENT_LABEL_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/client/layout.hpp Sun Jan 22 11:07:36 2017 +0100 @@ -0,0 +1,81 @@ +/* + * layout.hpp -- generic layout manager inside a frame + * + * Copyright (c) 2013-2017 Malikania Authors + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef MALIKANIA_CLIENT_LAYOUT_HPP +#define MALIKANIA_CLIENT_LAYOUT_HPP + +/** + * \brief Generic layout manager inside a frame. + */ + +namespace mlk { + +namespace client { + +class mouse_click_event; +class rectangle; +class size; +class window; + +/** + * \brief Manages the widgets inside a frame. + * + * Layouts are responsible of positioning the widgets inside a frame. They + * handle their positions and dispatch events if applicable. + * + * \see grid_layout + */ +class layout { +public: + /** + * Virtual destructor defaulted. + */ + virtual ~layout() noexcept = default; + + /** + * Handle mouse down. + * + * \param ev the mouse event + */ + virtual void handle_mouse_down(const mouse_click_event& ev) = 0; + + /** + * Handle mouse up. + * + * \param ev the event + */ + virtual void handle_mouse_up(const mouse_click_event& ev) = 0; + + /** + * Return the required minimum size to draw the whole layout. + */ + virtual mlk::client::size size(window& win) const = 0; + + /** + * Draw the layout content at the given position. + * + * \param win the window + */ + virtual void draw(window& win, const rectangle& dst) = 0; +}; + +} // !client + +} // !mlk + +#endif // !MALIKANIA_CLIENT_LAYOUT_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/client/line.hpp Sun Jan 22 11:07:36 2017 +0100 @@ -0,0 +1,129 @@ +/* + * line.hpp -- line description + * + * Copyright (c) 2013-2017 Malikania Authors + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef MALIKANIA_LINE_HPP +#define MALIKANIA_LINE_HPP + +/** + * \file line.hpp + * \brief line description. + */ + +namespace mlk { + +namespace client { + +/** + * \brief line description. + * + * A line has an origin (x, y) and a destination (x, y). + */ +class line { +private: + int m_x1; + int m_y1; + int m_x2; + int m_y2; + +public: + /** + * Construct a line. + * + * \param x1 the first x + * \param y1 the first y + * \param x2 the second x + * \param y2 the second y + */ + inline line(int x1 = 0, int y1 = 0, int x2 = 0, int y2 = 0) noexcept + : m_x1(x1) + , m_y1(y1) + , m_x2(x2) + , m_y2(y2) + { + } + + /** + * Get the first x. + * + * \return the x1 + */ + inline int x1() const noexcept + { + return m_x1; + } + + /** + * Get the first y. + * + * \return the y1 + */ + inline int y1() const noexcept + { + return m_y1; + } + + /** + * Get the second x. + * + * \return the x2 + */ + inline int x2() const noexcept + { + return m_x2; + } + + /** + * Get the second y. + * + * \return the y2 + */ + inline int y2() const noexcept + { + return m_y2; + } +}; + +/** + * Compare equality. + * + * \param l1 the first line + * \param l2 the second line + * \return true if they equal + */ +inline bool operator==(const line& l1, const line& l2) noexcept +{ + return l1.x1() == l2.x1() && l1.x2() == l2.x2() && l1.y1() == l2.y1() && l1.y2() == l2.y2(); +} + +/** + * Compare equality. + * + * \param l1 the first line + * \param l2 the second line + * \return false if they equal + */ +inline bool operator!=(const line& l1, const line& l2) noexcept +{ + return !(l1 == l2); +} + +} // !client + +} // !mlk + +#endif // !MALIKANIA_LINE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/client/loader.cpp Sun Jan 22 11:07:36 2017 +0100 @@ -0,0 +1,142 @@ +/* + * client_resources_loader.cpp -- load shared resources files for the client + * + * Copyright (c) 2013-2017 Malikania Authors + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <boost/format.hpp> + +#include <cassert> + +#include "animation.hpp" +#include "loader.hpp" +#include "size.hpp" +#include "sprite.hpp" +#include "util.hpp" + +using boost::str; +using boost::format; + +using mlk::util::json::invalid; + +namespace mlk { + +namespace client { + +size loader::require_size(const std::string& id, + const nlohmann::json& object, + const std::string& property) const +{ + assert(object.is_object()); + + auto it = object.find(property); + + if (it == object.end() || !it->is_array()) { + throw std::runtime_error(str(format("%s: missing '%' property (array expected)") % id % property)); + } + if (it->size() != 2) { + throw std::runtime_error(str(format("%s: property '%s' muve have two values") % id % property)); + } + if (!(*it)[0].is_number_integer() || !(*it)[1].is_number_integer()) { + throw std::runtime_error(str(format("%s: property '%s' must contains two ints"))); + } + + return size((*it)[0].get<int>(), (*it)[1].get<int>()); +} + +size loader::get_size(const std::string&, + const nlohmann::json& object, + const std::string& key) const noexcept +{ + assert(object.is_object()); + + auto it = object.find(key); + + if (it == object.end() || !it->is_array() || it->size() != 2 || + !(*it)[0].is_number_integer() || !(*it)[1].is_number_integer()) { + return size(); + } + + return size((*it)[0].get<int>(), (*it)[1].get<int>()); +} + +font loader::load_font(const std::string& id, unsigned size) +{ + return font(locator().read(id), size); +} + +image loader::load_image(const std::string& id) +{ + return image(locator().read(id)); +} + +sprite loader::load_sprite(const std::string& id) +{ + auto value = nlohmann::json::parse(locator().read(id)); + + if (!value.is_object()) { + throw std::runtime_error(id + ": not a JSON object"); + } + + return sprite( + load_image(require_string(id, value, "image")), + require_size(id, value, "cell"), + get_size(id, value, "size"), + get_size(id, value, "space"), + get_size(id, value, "margin") + ); +} + +animation loader::load_animation(const std::string& id) +{ + auto value = nlohmann::json::parse(locator().read(id)); + + if (!value.is_object()) { + throw std::runtime_error("not a JSON object"); + } + + auto sprite = load_sprite(require_string(id, value, "sprite")); + + // Load all frames. + auto property = value["frames"]; + + if (!property.is_array()) { + throw invalid(id, nlohmann::json::value_t::array); + } + + animation_frames frames; + int index = 0; + + for (auto it = property.begin(); it != property.end(); ++it) { + if (!it->is_object()) { + throw std::runtime_error(id + ": frame " + std::to_string(index) + ": not a JSON object"); + } + + auto delay = it->find("delay"); + + if (delay == it->end() || !delay->is_number_integer()) { + throw std::runtime_error(id + ": frame " + std::to_string(index) + + ": missing 'delay' property (int expected)"); + } + + frames.emplace_back(delay->get<int>()); + } + + return animation(std::move(sprite), std::move(frames)); +} + +} // !client + +} // !mlk
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/client/loader.hpp Sun Jan 22 11:07:36 2017 +0100 @@ -0,0 +1,129 @@ +/* + * client_resources_loader.hpp -- load shared resources files for the client + * + * Copyright (c) 2013-2017 Malikania Authors + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef MALIKANIA_CLIENT_RESOURCES_LOADER_HPP +#define MALIKANIA_CLIENT_RESOURCES_LOADER_HPP + +/* + * \file client_resources_loader.hpp + * \brief Load client assets. + */ + +#include <malikania/loader.hpp> + +#include "animation.hpp" +#include "font.hpp" +#include "image.hpp" +#include "size.hpp" +#include "sprite.hpp" + +namespace mlk { + +namespace client { + +/** + * \brief Load client resources. + */ +class loader : public mlk::loader { +protected: + /** + * Require a size object from an object property. + * + * The size is an array of two integers (e.g. [ 1, 2 ]). + * + * \pre object.is_object() + * \param id the resource id + * \param object the object + * \param property the property + * \return the size + * \throw std::runtime_error if the property is not a size + */ + size require_size(const std::string& id, + const nlohmann::json& object, + const std::string& property) const; + + /** + * Get a size object or a default one if not present or invalid. + * + * \pre object.is_object() + * \param id the resource id + * \param object the object + * \param property the property + * \return the size or default one + */ + size get_size(const std::string& id, + const nlohmann::json& object, + const std::string& property) const noexcept; + +public: + /** + * Client resources loader constructor. + * + * The window is required because some of the resources require it. + * + * \param window the window + * \param locator the resources locator + */ + inline loader(mlk::locator& locator) + : mlk::loader(locator) + { + } + + /** + * Load a font. + * + * \param id the resource id + * \param size the desired size + * \return the font + * \throw std::runtime_error on errors + */ + virtual font load_font(const std::string& id, unsigned size); + + /** + * Load an image. + * + * \param id the resource id + * \return the image + * \throw std::runtime_error on errors + */ + virtual image load_image(const std::string& id); + + /** + * Load a sprite. + * + * \param id the resource id + * \return the sprite + * \throw std::runtime_error on errors + */ + virtual sprite load_sprite(const std::string& id); + + /** + * Load an animation. + * + * \param id the resource id + * \return the animation + * \throw std::runtime_error on errors + */ + virtual animation load_animation(const std::string& id); +}; + +} // !client + +} // !mlk + +#endif // !MALIKANIA_CLIENT_RESOURCES_LOADER_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/client/mouse.hpp Sun Jan 22 11:07:36 2017 +0100 @@ -0,0 +1,45 @@ +/* + * mouse.hpp -- mouse definitions + * + * Copyright (c) 2013-2017 Malikania Authors + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef MALIKANIA_CLIENT_MOUSE_HPP +#define MALIKANIA_CLIENT_MOUSE_HPP + +/** + * \file mouse.hpp + * \brief Mouse definitions. + */ + +namespace mlk { + +namespace client { + +/** + * \brief Describe mouse button + */ +enum class mouse { + none, //!< no buttons are pressed + left, //!< left click is pressed + right, //!< right click is pressed + middle //!< middle click is pressed +}; + +} // !client + +} // !mlk + +#endif // !MALIKANIA_CLIENT_MOUSE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/client/point.hpp Sun Jan 22 11:07:36 2017 +0100 @@ -0,0 +1,101 @@ +/* + * point.hpp -- point description + * + * Copyright (c) 2013-2017 Malikania Authors + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef MALIKANIA_POINT_HPP +#define MALIKANIA_POINT_HPP + +/** + * \file point.hpp + * \brief point description. + */ + +namespace mlk { + +namespace client { + +/** + * \brief point coordinate. + */ +class point { +private: + int m_x; + int m_y; + +public: + /** + * Construct a point. + * + * \param x the x + * \param y the y + */ + inline point(int x = 0, int y = 0) noexcept + : m_x(x) + , m_y(y) + { + } + + /** + * Get the x position. + * + * \return the x + */ + inline int x() const noexcept + { + return m_x; + } + + /** + * Get the y position. + * + * \return the y + */ + inline int y() const noexcept + { + return m_y; + } +}; + +/** + * Compare equality. + * + * \param p1 the first point + * \param p2 the second point + * \return true if they equal + */ +inline bool operator==(const point& p1, const point& p2) noexcept +{ + return p1.x() == p2.x() && p1.y() == p2.y(); +} + +/** + * Compare equality. + * + * \param p1 the first point + * \param p2 the second point + * \return false if they equal + */ +inline bool operator!=(const point& p1, const point& p2) noexcept +{ + return !(p1 == p2); +} + +} // !client + +} // !mlk + +#endif // !MALIKANIA_POINT_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/client/rectangle.hpp Sun Jan 22 11:07:36 2017 +0100 @@ -0,0 +1,142 @@ +/* + * rectangle.hpp -- rectangle description + * + * Copyright (c) 2013-2017 Malikania Authors + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef MALIKANIA_RECTANGLE_HPP +#define MALIKANIA_RECTANGLE_HPP + +/** + * \file rectangle.hpp + * \brief rectangle description. + */ + +namespace mlk { + +namespace client { + +/** + * \brief rectangle description. + * + * A rectangle has coordinates (x, y) and dimensions (width, height). + * + * They are commonly used for clipping images into the window. + */ +class rectangle { +private: + int m_x; + int m_y; + unsigned m_width; + unsigned m_height; + +public: + /** + * Construct a rectangle. + * + * \param x the x position + * \param y the y position + * \param width the width + * \param height the height + */ + inline rectangle(int x = 0, int y = 0, unsigned width = 0, unsigned height = 0) noexcept + : m_x(x) + , m_y(y) + , m_width(width) + , m_height(height) + { + } + + /** + * Get the x position. + * + * \return the x position + */ + inline int x() const noexcept + { + return m_x; + } + + /** + * Get the y position. + * + * \return the y position + */ + inline int y() const noexcept + { + return m_y; + } + + /** + * Get the rectangle width. + * + * \return the width + */ + inline unsigned width() const noexcept + { + return m_width; + } + + /** + * Get the rectangle height. + * + * \return the height + */ + inline unsigned height() const noexcept + { + return m_height; + } + + /** + * Check if the rectangle has null dimensions. + * + * \return true if weight and height are 0 + */ + inline bool is_null() const noexcept + { + return m_width == 0 && m_height == 0; + } +}; + +/** + * Compare equality. + * + * \param r1 the first rectangle + * \param r2 the second rectangle + * \return true if they equal + */ +inline bool operator==(const rectangle& r1, const rectangle& r2) noexcept +{ + return r1.x() == r2.x() && r1.y() == r2.y() && + r1.width() == r2.width() && r1.height() == r2.height(); +} + +/** + * Compare equality. + * + * \param r1 the first rectangle + * \param r2 the second rectangle + * \return false if they equal + */ +inline bool operator!=(const rectangle& r1, const rectangle& r2) noexcept +{ + return !(r1 == r2); +} + +} // !client + +} // !mlk + +#endif // !MALIKANIA_RECTANGLE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/client/size.hpp Sun Jan 22 11:07:36 2017 +0100 @@ -0,0 +1,106 @@ +/* + * size.hpp -- size description + * + * Copyright (c) 2013-2017 Malikania Authors + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef MALIKANIA_SIZE_HPP +#define MALIKANIA_SIZE_HPP + +namespace mlk { + +namespace client { + +/** + * \brief size description. + */ +class size { +private: + unsigned m_width; + unsigned m_height; + +public: + /** + * Constructor. + * + * \param width the size width + * \param height the size height + */ + inline size(unsigned width = 0, unsigned height = 0) noexcept + : m_width(width) + , m_height(height) + { + } + + /** + * Get the width. + * + * \return the width + */ + inline unsigned width() const noexcept + { + return m_width; + } + + /** + * Get the height. + * + * \return the height + */ + inline unsigned height() const noexcept + { + return m_height; + } + + /** + * Check if the size is 0, 0. + * + * \return true if height and width are 0 + */ + inline bool is_null() const noexcept + { + return m_height == 0 && m_width == 0; + } +}; + +/** + * Compare equality. + * + * \param s1 the first size + * \param s2 the second size + * \return true if they equal + */ +inline bool operator==(const size& s1, const size& s2) noexcept +{ + return s1.width() == s2.width() && s1.height() == s2.height(); +} + +/** + * Compare equality. + * + * \param s1 the first size + * \param s2 the second size + * \return false if they equal + */ +inline bool operator!=(const size& s1, const size& s2) noexcept +{ + return !(s1 == s2); +} + +} // !client + +} // !mlk + +#endif // !MALIKANIA_SIZE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/client/sprite.cpp Sun Jan 22 11:07:36 2017 +0100 @@ -0,0 +1,71 @@ +/* + * sprite.cpp -- image sprite + * + * Copyright (c) 2013-2017 Malikania Authors + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <cassert> + +#include "sprite.hpp" + +namespace mlk { + +namespace client { + +sprite::sprite(mlk::client::image image, + mlk::client::size cell, + mlk::client::size size, + mlk::client::size space, + mlk::client::size margin) noexcept + : m_image(std::move(image)) + , m_cell(std::move(cell)) + , m_margin(std::move(margin)) + , m_space(std::move(space)) + , m_size(std::move(size)) +{ + assert(m_cell.width() > 0); + assert(m_cell.height() > 0); + + // If size is not specified, take from image. + if (m_size.is_null()) { + m_size = m_image.size(); + } + + // Compute number of cells. + m_rows = (m_size.height() - (margin.height() * 2) + m_space.height()) / (m_cell.height() + m_space.height()); + m_columns = (m_size.width() - (m_margin.width() * 2) + m_space.width()) / (m_cell.width() + m_space.width()); +} + +void sprite::draw(window& window, unsigned cell, const point& point) +{ + assert(cell < m_rows * m_columns); + + // Compute index in the grid. + unsigned hindex = (cell % m_columns); + unsigned vindex = (cell / m_columns); + + // Compute the pixel boundaries. + int x = m_margin.width() + (hindex * m_space.width()) + (hindex * m_cell.width()); + int y = m_margin.height() + (vindex * m_space.height()) + (vindex * m_cell.height()); + + rectangle source(x, y, m_cell.width(), m_cell.height()); + rectangle target(point.x(), point.y(), m_cell.width(), m_cell.height()); + + m_image.draw(window, source, target); +} + +} // !client + +} // !mlk
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/client/sprite.hpp Sun Jan 22 11:07:36 2017 +0100 @@ -0,0 +1,149 @@ +/* + * sprite.hpp -- image sprite + * + * Copyright (c) 2013-2017 Malikania Authors + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef MALIKANIA_SPRITE_HPP +#define MALIKANIA_SPRITE_HPP + +/** + * \file sprite.hpp + * \brief Sprite description. + */ + +#include "image.hpp" + +namespace mlk { + +namespace client { + +/** + * \brief A Sprite is an image divided into cells. + */ +class sprite { +private: + mlk::client::image m_image; + mlk::client::size m_cell; + mlk::client::size m_margin; + mlk::client::size m_space; + mlk::client::size m_size; + + unsigned m_rows; + unsigned m_columns; + +public: + /** + * Construct a sprite. + * + * \pre cell must not have height or width null + * \param image the image to use + * \param cell size of cell in the image + * \param margin the optional space from borders + * \param space the optional space between cells + * \param size the sprite size (if 0, taken from the image) + */ + sprite(mlk::client::image image, + mlk::client::size cell, + mlk::client::size margin = { 0, 0 }, + mlk::client::size space = { 0, 0 }, + mlk::client::size size = { 0, 0 }) noexcept; + + /** + * Get the underlying image. + * + * \return the image + */ + inline const mlk::client::image& image() const noexcept + { + return m_image; + } + + /** + * Overloaded function. + * + * \return the image + */ + inline mlk::client::image& image() noexcept + { + return m_image; + } + + /** + * Get the cell size. + * + * \return the cell size + */ + inline const size& cell() const noexcept + { + return m_cell; + } + + /** + * Get the margin size. + * + * \return the margin size + */ + inline const size& margin() noexcept + { + return m_margin; + } + + /** + * Get the space size. + * + * \return the space size + */ + inline const size& space() const noexcept + { + return m_space; + } + + /** + * Get the number of rows in the grid. + * + * \return the number of rows + */ + inline unsigned rows() const noexcept + { + return m_rows; + } + + /** + * Get the number of columns in the grid. + * + * \return the number of columns + */ + inline unsigned columns() const noexcept + { + return m_columns; + } + + /** + * Draw the sprite into the window at the specified position. + * + * \pre cell < rows() * columns() + * \param window the window + * \param cell the cell index + * \param position the position in the window + */ + void draw(window& window, unsigned cell, const point& position); +}; + +} // !client + +} // !mlk + +#endif // !MALIKANIA_SPRITE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/client/theme.cpp Sun Jan 22 11:07:36 2017 +0100 @@ -0,0 +1,120 @@ +/* + * theme.cpp -- theming support for gui elements + * + * Copyright (c) 2013-2017 Malikania Authors + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "button.hpp" +#include "color.hpp" +#include "frame.hpp" +#include "label.hpp" +#include "layout.hpp" +#include "point.hpp" +#include "rectangle.hpp" +#include "theme.hpp" +#include "window.hpp" + +namespace mlk { + +namespace client { + +namespace { + +#include <dejavu_sans.cpp> + +} // !namespace + +theme::theme() + : m_font(std::string(dejavu_sans, sizeof (dejavu_sans)), 10) + , m_background_color(228, 228, 228, 255) + , m_border_color(102, 102, 102, 255) + , m_text_color(50, 50, 50, 255) + , m_frame_padding(10, 10) +{ +} + +size theme::size_button(const button &b) +{ + auto clip = m_font.clip(b.text()); + + return { + clip.width() + 12, + clip.height() + 12 + }; +} + +size theme::size_label(const label& l) +{ + return m_font.clip(l.text()); +} + +void theme::draw_frame(window& win, const frame &f) +{ + auto layout_size = f.layout()->size(win); + auto frame_pos = f.position(); + + // Frame border. + win.set_drawing_color(m_border_color); + win.draw_rectangle({ + frame_pos.x(), + frame_pos.y(), + layout_size.width() + m_frame_padding.width() * 2 + 2, + layout_size.height() + m_frame_padding.height() * 2 + 2 + }); + + // Frame content. + win.set_drawing_color(m_background_color); + win.fill_rectangle({ + frame_pos.x() + 1, + frame_pos.y() + 1, + layout_size.width() + m_frame_padding.width() * 2, + layout_size.height() + m_frame_padding.height() * 2 + }); + + // Layout. + f.layout()->draw(win, mlk::client::rectangle( + frame_pos.x() + m_frame_padding.width() + 1, + frame_pos.y() + m_frame_padding.height() + 1, + layout_size.width(), + layout_size.height() + )); +} + +void theme::draw_button(window& w, const button& b, const rectangle& rect) +{ + auto size = size_button(b); + + // Border. + w.set_drawing_color(m_border_color); + w.draw_rectangle({rect.x(), rect.y(), size.width(), size.height()}); + + // Box content. + w.set_drawing_color(m_background_color); + w.fill_rectangle({rect.x() + 1, rect.y() + 1, size.width() - 2, size.height() - 2}); + + // Text. + w.set_drawing_color(m_text_color); + w.draw_text(b.text(), m_font, point{rect.x() + 5, rect.y() + 5}); +} + +void theme::draw_label(window& w, const label& label, const rectangle& rect) +{ + w.set_drawing_color(m_text_color); + w.draw_text(label.text(), m_font, mlk::client::point(rect.x(), rect.y())); +} + +} // !client + +} // !mlk
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/client/theme.hpp Sun Jan 22 11:07:36 2017 +0100 @@ -0,0 +1,125 @@ +/* + * theme.hpp -- theming support for gui elements + * + * Copyright (c) 2013-2017 Malikania Authors + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef MALIKANIA_CLIENT_THEME_HPP +#define MALIKANIA_CLIENT_THEME_HPP + +/** + * \file theme.hpp + * \brief Theming support for gui elements. + */ + +#include "color.hpp" +#include "font.hpp" +#include "size.hpp" + +namespace mlk { + +namespace client { + +class button; +class frame; +class label; +class rectangle; +class point; +class window; + +/** + * \brief Reimplement this class to provide your own theme. + */ +class theme { +private: + font m_font; + color m_background_color; + color m_border_color; + color m_text_color; + size m_frame_padding; + +public: + /** + * Default constructor. + */ + theme(); + + /** + * Virtual destructor defaulted. + */ + virtual ~theme() noexcept = default; + + inline const color& background_color() const noexcept + { + return m_background_color; + } + + inline const color& border_color() const noexcept + { + return m_border_color; + } + + inline const color& text_color() const noexcept + { + return m_text_color; + } + + /** + * Get the required bounding rectangle size for this button. + * + * \param b the button + * \return the size + */ + virtual size size_button(const button& b); + + /** + * Get the required bouding rectangle size for this label. + * + * \param l the label + * \return the size + */ + virtual size size_label(const label& l); + + /** + * Draw the frame. + * + * \param w the main window + * \param f the frame + */ + virtual void draw_frame(window& w, const frame& f); + + /** + * Draw a button. + * + * \param w the main window + * \param b the button + */ + virtual void draw_button(window& w, const button& b, const rectangle& rect); + + /** + * Draw a label. + * + * \param w the main window + * \param l the label + * \param rect the bounding rectangle. + */ + virtual void draw_label(window& w, const label& l, const rectangle& rect); +}; + +} // !client + +} // !mlk + +#endif // !MALIKANIA_CLIENT_THEME_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/client/unique_layout.cpp Sun Jan 22 11:07:36 2017 +0100 @@ -0,0 +1,60 @@ +/* + * unique_layout.cpp -- basic layout with one widget + * + * Copyright (c) 2013-2017 Malikania Authors + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "size.hpp" +#include "unique_layout.hpp" +#include "widget.hpp" + +namespace mlk { + +namespace client { + +unique_layout::unique_layout(std::shared_ptr<mlk::client::widget> widget) noexcept + : m_widget(std::move(widget)) +{ +} + +void unique_layout::handle_mouse_down(const mouse_click_event& ev) +{ + if (m_widget) { + m_widget->handle_mouse_down(ev); + } +} + +void unique_layout::handle_mouse_up(const mouse_click_event& ev) +{ + if (m_widget) { + m_widget->handle_mouse_up(ev); + } +} + +mlk::client::size unique_layout::size(window& win) const +{ + return m_widget ? m_widget->size(win) : mlk::client::size(); +} + +void unique_layout::draw(window& win, const rectangle& dst) +{ + if (m_widget) { + m_widget->draw(win, dst); + } +} + +} // !client + +} // !mlk
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/client/unique_layout.hpp Sun Jan 22 11:07:36 2017 +0100 @@ -0,0 +1,107 @@ +/* + * unique_layout.hpp -- basic layout with one widget + * + * Copyright (c) 2013-2017 Malikania Authors + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef MALIKANIA_CLIENT_UNIQUE_LAYOUT_HPP +#define MALIKANIA_CLIENT_UNIQUE_LAYOUT_HPP + +/** + * \file unique_layout.hpp + * \brief Basic layout with one widget. + */ + +#include <memory> + +#include "layout.hpp" + +namespace mlk { + +namespace client { + +class widget; + +/** + * \brief Simple layout that consists of one widget. + */ +class unique_layout : public layout { +private: + std::shared_ptr<mlk::client::widget> m_widget; + +public: + /** + * Constructor with optional widget. + * + * \param widget the widget + */ + unique_layout(std::shared_ptr<mlk::client::widget> w = nullptr) noexcept; + + /** + * Get the handled widget. + * + * \return the widget + */ + inline const std::shared_ptr<mlk::client::widget>& widget() const noexcept + { + return m_widget; + } + + /** + * Overloaded function. + * + * \return the widget + */ + inline std::shared_ptr<mlk::client::widget>& widget() noexcept + { + return m_widget; + } + + /** + * Replace the current widget with this one. + * + * \param widget the widget + */ + inline void set_widget(std::shared_ptr<mlk::client::widget> widget) noexcept + { + m_widget = std::move(widget); + } + + /** + * \copydoc layout::handle_mouse_down + */ + void handle_mouse_down(const mouse_click_event& ev) override; + + /** + * \copydoc layout::handle_mouse_up + */ + void handle_mouse_up(const mouse_click_event& ev) override; + + /** + * \copydoc layout::size + */ + mlk::client::size size(window& win) const override; + + /** + * \copydoc layout::draw + */ + void draw(window& win, const rectangle& dst) override; +}; + +} // !client + +} // !mlk + +#endif // !MALIKANIA_CLIENT_UNIQUE_LAYOUT_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/client/widget.cpp Sun Jan 22 11:07:36 2017 +0100 @@ -0,0 +1,57 @@ +/* + * widget.cpp -- basic abstract widget for GUI + * + * Copyright (c) 2013-2017 Malikania Authors + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "point.hpp" +#include "rectangle.hpp" +#include "size.hpp" +#include "widget.hpp" + +namespace mlk { + +namespace client { + +void widget::handle_key_down(const key_event&) +{ +} + +void widget::handle_key_up(const key_event&) +{ +} + +void widget::handle_mouse_down(const mouse_click_event&) +{ +} + +void widget::handle_mouse_up(const mouse_click_event&) +{ +} + +void widget::draw(window& w, const point& pos) +{ + mlk::client::size sz = size(w); + mlk::client::rectangle rect{ + pos.x(), pos.y(), + sz.width(), sz.height() + }; + + draw(w, rect); +} + +} // !client + +} // !mlk
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/client/widget.hpp Sun Jan 22 11:07:36 2017 +0100 @@ -0,0 +1,107 @@ +/* + * widget.hpp -- basic abstract widget for GUI + * + * Copyright (c) 2013-2017 Malikania Authors + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef MALIKANIA_CLIENT_WIDGET_HPP +#define MALIKANIA_CLIENT_WIDGET_HPP + +/** + * \file widget.hpp + * \brief Basic abstract widget for GUI + */ + +namespace mlk { + +namespace client { + +class key_event; +class mouse_click_event; +class point; +class rectangle; +class size; +class window; + +/** + * \brief Abstract widget + */ +class widget { +public: + /** + * Default destructor. + */ + virtual ~widget() noexcept = default; + + /** + * Handle a key down. + * + * \param ev the event + */ + virtual void handle_key_down(const key_event& ev); + + /** + * Handle a key up. + * + * \param ev the event + */ + virtual void handle_key_up(const key_event& ev); + + /** + * Handle mouse down event. + * + * \param ev the event + */ + virtual void handle_mouse_down(const mouse_click_event& ev); + + /** + * Handle a mouse up event. + * + * \param ev the event + */ + virtual void handle_mouse_up(const mouse_click_event& ev); + + /** + * Draw the widget at the specified position. + * + * Basic GUI elements will use the window theme to render themselves. + * + * \param w the window + */ + virtual void draw(window& w, const rectangle& rect) = 0; + + /** + * Helper to draw the whole widget at the given position. + * + * Effectively call draw with a rectangle overload. + * + * \param w the window + * \param pos the position + */ + virtual void draw(window& w, const point& pos); + + /** + * Get the required size to draw that widget. + * + * \return the widget size + */ + virtual mlk::client::size size(window& w) const noexcept = 0; +}; + +} // !client + +} // !mlk + +#endif // !MALIKANIA_CLIENT_WIDGET_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/client/window.cpp Sun Jan 22 11:07:36 2017 +0100 @@ -0,0 +1,180 @@ +/* + * window.cpp -- main window and basic drawing + * + * Copyright (c) 2013-2017 Malikania Authors + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <iostream> +#include <stdexcept> + +#include "color.hpp" +#include "frame.hpp" +#include "layout.hpp" +#include "theme.hpp" +#include "widget.hpp" +#include "window_backend.hpp" + +namespace mlk { + +namespace client { + +bool window::is_frame_bound(frame& f, const point& ev_pos) noexcept +{ + auto frame_size = f.size(*this); + auto frame_padding = f.padding(); + auto frame_pos = f.position(); + + return ev_pos.x() >= frame_pos.x() + static_cast<int>(frame_padding.width()) && + ev_pos.y() >= frame_pos.y() + static_cast<int>(frame_padding.height()) && + ev_pos.x() <= frame_pos.x() + static_cast<int>(frame_padding.width() + frame_size.width()) && + ev_pos.y() <= frame_pos.y() + static_cast<int>(frame_padding.height() + frame_size.height()); +} + +window::window(unsigned width, unsigned height, const std::string& title) + : m_backend(std::make_unique<backend_impl>(*this, width, height, title)) + , m_theme(std::make_unique<mlk::client::theme>()) +{ +} + +window::window(window&&) noexcept = default; + +window::~window() noexcept = default; + +void window::clear() +{ + m_backend->clear(); +} + +void window::present() +{ + m_backend->present(); +} + +void window::close() noexcept +{ + m_is_open = false; + m_backend->close(); +} + +color window::drawing_color() const +{ + return m_backend->drawing_color(); +} + +void window::set_drawing_color(const color& color) +{ + m_backend->set_drawing_color(color); +} + +void window::draw_line(const line& line) +{ + m_backend->draw_line(line); +} + +void window::draw_lines(const std::vector<point>& points) +{ + m_backend->draw_lines(points); +} + +void window::draw_point(const point& point) +{ + m_backend->draw_point(point); +} + +void window::draw_points(const std::vector<point>& points) +{ + m_backend->draw_points(points); +} + +void window::draw_rectangle(const rectangle& rectangle) +{ + m_backend->draw_rectangle(rectangle); +} + +void window::draw_rectangles(const std::vector<rectangle>& rectangles) +{ + m_backend->draw_rectangles(rectangles); +} + +void window::draw_frames() +{ + for (const auto& f : m_frames) { + f->draw(*this); + } +} + +void window::fill_rectangle(const rectangle& rectangle) +{ + m_backend->fill_rectangle(rectangle); +} + +void window::fill_rectangles(const std::vector<rectangle>& rectangles) +{ + m_backend->fill_rectangles(rectangles); +} + +void window::draw_text(const std::string& text, font& font, const rectangle& rectangle) +{ + m_backend->draw_text(text, font, rectangle); +} + +void window::draw_text(const std::string& text, font& font, const point& point) +{ + m_backend->draw_text(text, font, point); +} + +void window::poll() +{ + m_backend->poll(*this); +} + +void window::handle_key_down(const key_event&) +{ +} + +void window::handle_key_up(const key_event&) +{ +} + +void window::handle_mouse_down(const mouse_click_event& ev) +{ + for (const auto& f : m_frames) { + if (is_frame_bound(*f, ev.pos)) { + f->layout()->handle_mouse_down({ + ev.button, + point(ev.pos.x() - f->position().x(), ev.pos.y() - f->position().y()) + }); + } + } +} + +void window::handle_mouse_up(const mouse_click_event&) +{ +} + +void window::handle_mouse_wheel(const mouse_wheel_event&) +{ +} + +void window::handle_quit() +{ + m_is_open = false; +} + +window& window::operator=(window&&) noexcept = default; + +} // !client + +} // !mlk
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libclient/malikania/client/window.hpp Sun Jan 22 11:07:36 2017 +0100 @@ -0,0 +1,354 @@ +/* + * window.hpp -- main window and basic drawing + * + * Copyright (c) 2013-2017 Malikania Authors + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef MALIKANIA_WINDOW_HPP +#define MALIKANIA_WINDOW_HPP + +/** + * \file window.hpp + * \brief Window and drawing. + */ + +#include <functional> +#include <memory> +#include <vector> +#include <string> +#include <unordered_set> + +#include "key.hpp" +#include "mouse.hpp" +#include "point.hpp" + +namespace mlk { + +namespace client { + +class color; +class frame; +class line; +class font; +class rectangle; +class theme; + +/** + * \brief Describe key event. + */ +class key_event { +public: + mlk::client::key key{key::unknown}; //!< layout-dependant key + mlk::client::key scancode{key::unknown}; //!< physical key + mlk::client::mod modifiers{mod::none}; //!< optional modifiers +}; + +/** + * \brief Describe mouse click event. + */ +class mouse_click_event { +public: + mouse button{mouse::none}; //!< which mouse button + point pos; //!< current mouse position +}; + +/** + * \brief Describe a mouse motion event. + */ +class mouse_motion_event { +public: + point pos; //!< current mouse position +}; + +/** + * \brief Describe mouse wheel (up/down) event. + */ +class mouse_wheel_event { +public: + point pos; //!< current mouse position +}; + +/** + * \brief Main window class and drawing. + */ +class window { +private: + class backend_impl; + + std::unique_ptr<backend_impl> m_backend; + std::unique_ptr<mlk::client::theme> m_theme; + std::unordered_set<std::shared_ptr<frame>> m_frames; + + bool m_is_open{true}; + + bool is_frame_bound(frame&, const point&) noexcept; + +public: + /** + * Create a window. + * + * \param width the initial width + * \param height the initial height + * \param title the optional title + * \throw std::runtime_error on errors + */ + window(unsigned width = 640, + unsigned height = 480, + const std::string& title = "Malikania Engine"); + + /** + * Move constructor defaulted. + */ + window(window&&) noexcept; + + /** + * Virtual destructor defaulted. + */ + virtual ~window() noexcept; + + /** + * Tells if the window is open. + * + * \return true if open + */ + inline bool is_open() const noexcept + { + return m_is_open; + } + + /** + * Get the underlying backend. + * + * \return the backend + */ + inline const backend_impl& backend() const noexcept + { + return *m_backend; + } + + /** + * Overloaded function. + * + * \return the backend + */ + inline backend_impl& backend() noexcept + { + return *m_backend; + } + + void add_frame(std::shared_ptr<mlk::client::frame> frame) + { + m_frames.insert(std::move(frame)); + } + + void remove_frame(std::shared_ptr<mlk::client::frame> frame) + { + m_frames.erase(frame); + } + + /** + * Get the current theme. + * + * \return the theme + */ + inline const mlk::client::theme& theme() const noexcept + { + return *m_theme; + } + + /** + * Overloaded function. + * + * \return the theme + */ + inline mlk::client::theme& theme() noexcept + { + return *m_theme; + } + + /** + * Clear the window content with the current drawing color. + */ + void clear(); + + /** + * Render the content of the window to the screen. + */ + void present(); + + /** + * Close the window. + */ + void close() noexcept; + + /** + * Get the current drawing color. + * + * \return the color + */ + color drawing_color() const; + + /** + * Set the drawing color. + * + * \param color the color + */ + void set_drawing_color(const color& color); + + /** + * Draw a line. + * + * \param line the line + */ + void draw_line(const line& line); + + /** + * Draw a several lines. + * + * \param the lines vertices + */ + void draw_lines(const std::vector<point>& points); + + /** + * Draw a point. + * + * \param point the point + */ + void draw_point(const point& point); + + /** + * Draw a list of points. + * + * \param points the points + */ + void draw_points(const std::vector<point>& points); + + /** + * Draw a rectangle (only borders). + * + * \param rect the rectangle + * \see fillRectangle + */ + void draw_rectangle(const rectangle& rect); + + /** + * Draw a list of rectangles. + * + * \param rects the rectangles + * \see fillRectangles + */ + void draw_rectangles(const std::vector<rectangle>& rects); + + /** + * Draw internal GUI frames. + */ + void draw_frames(); + + /** + * Fill the given rectangle with the current color. + * + * \param rect the rectangle + * \see drawRectangle + */ + void fill_rectangle(const rectangle& rect); + + /** + * Fill the list of rectangles with the current color. + * + * \param rects the list of rectangles + * \see drawRectangles + */ + void fill_rectangles(const std::vector<rectangle>& rects); + + /** + * Draw some text. + * + * This function may stretch the text texture. + * + * \param text the text (UTF-8) + * \param font the font + * \param rectangle the rectangle target + */ + void draw_text(const std::string& text, font& font, const rectangle& rectangle); + + /** + * Overloaded function. + * + * Draw the text at the given position. + * + * \param text the text (UTF-8) + * \param font the font + * \param point the text position + */ + void draw_text(const std::string& text, font& font, const point& point); + + /** + * Poll all pending events and call appropriate functions. + */ + void poll(); + + /** + * Key down event. + * + * \param ev the event + */ + virtual void handle_key_down(const key_event& ev); + + /** + * Key released event. + * + * \param ev the event + */ + virtual void handle_key_up(const key_event& ev); + + /** + * Mouse click event. + * + * \param ev the event + */ + virtual void handle_mouse_down(const mouse_click_event& ev); + + /** + * Mouse click release event. + * + * \param ev the event + */ + virtual void handle_mouse_up(const mouse_click_event& ev); + + /** + * Mouse wheel event. + * + * \param ev the event + */ + virtual void handle_mouse_wheel(const mouse_wheel_event& ev); + + /** + * Quit request. + */ + virtual void handle_quit(); + + /** + * Move assigment operator defaulted. + * + * \return this + */ + window& operator=(window&&) noexcept; +}; + +} // !client + +} // !mlk + +#endif // !MALIKANIA_WINDOW_HPP
--- a/libclient/malikania/client_resources_loader.cpp Sun Jan 22 10:11:17 2017 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,138 +0,0 @@ -/* - * client_resources_loader.cpp -- load shared resources files for the client - * - * Copyright (c) 2013-2017 Malikania Authors - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <boost/format.hpp> - -#include <cassert> - -#include "animation.hpp" -#include "client_resources_loader.hpp" -#include "size.hpp" -#include "sprite.hpp" -#include "util.hpp" - -using boost::str; -using boost::format; - -using mlk::util::json::invalid; - -namespace mlk { - -size client_resources_loader::require_size(const std::string& id, - const nlohmann::json& object, - const std::string& property) const -{ - assert(object.is_object()); - - auto it = object.find(property); - - if (it == object.end() || !it->is_array()) { - throw std::runtime_error(str(format("%s: missing '%' property (array expected)") % id % property)); - } - if (it->size() != 2) { - throw std::runtime_error(str(format("%s: property '%s' muve have two values") % id % property)); - } - if (!(*it)[0].is_number_integer() || !(*it)[1].is_number_integer()) { - throw std::runtime_error(str(format("%s: property '%s' must contains two ints"))); - } - - return size((*it)[0].get<int>(), (*it)[1].get<int>()); -} - -size client_resources_loader::get_size(const std::string&, - const nlohmann::json& object, - const std::string& key) const noexcept -{ - assert(object.is_object()); - - auto it = object.find(key); - - if (it == object.end() || !it->is_array() || it->size() != 2 || - !(*it)[0].is_number_integer() || !(*it)[1].is_number_integer()) { - return size(); - } - - return size((*it)[0].get<int>(), (*it)[1].get<int>()); -} - -font client_resources_loader::load_font(const std::string& id, unsigned size) -{ - return font(locator().read(id), size); -} - -image client_resources_loader::load_image(const std::string& id) -{ - return image(locator().read(id)); -} - -sprite client_resources_loader::load_sprite(const std::string& id) -{ - auto value = nlohmann::json::parse(locator().read(id)); - - if (!value.is_object()) { - throw std::runtime_error(id + ": not a JSON object"); - } - - return sprite( - load_image(require_string(id, value, "image")), - require_size(id, value, "cell"), - get_size(id, value, "size"), - get_size(id, value, "space"), - get_size(id, value, "margin") - ); -} - -animation client_resources_loader::load_animation(const std::string& id) -{ - auto value = nlohmann::json::parse(locator().read(id)); - - if (!value.is_object()) { - throw std::runtime_error("not a JSON object"); - } - - auto sprite = load_sprite(require_string(id, value, "sprite")); - - // Load all frames. - auto property = value["frames"]; - - if (!property.is_array()) { - throw invalid(id, nlohmann::json::value_t::array); - } - - animation_frames frames; - int index = 0; - - for (auto it = property.begin(); it != property.end(); ++it) { - if (!it->is_object()) { - throw std::runtime_error(id + ": frame " + std::to_string(index) + ": not a JSON object"); - } - - auto delay = it->find("delay"); - - if (delay == it->end() || !delay->is_number_integer()) { - throw std::runtime_error(id + ": frame " + std::to_string(index) + - ": missing 'delay' property (int expected)"); - } - - frames.emplace_back(delay->get<int>()); - } - - return animation(std::move(sprite), std::move(frames)); -} - -} // !mlk
--- a/libclient/malikania/client_resources_loader.hpp Sun Jan 22 10:11:17 2017 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,125 +0,0 @@ -/* - * client_resources_loader.hpp -- load shared resources files for the client - * - * Copyright (c) 2013-2017 Malikania Authors - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef MALIKANIA_CLIENT_RESOURCES_LOADER_HPP -#define MALIKANIA_CLIENT_RESOURCES_LOADER_HPP - -/* - * \file client_resources_loader.hpp - * \brief Load client assets. - */ - -#include <malikania/loader.hpp> - -#include "animation.hpp" -#include "font.hpp" -#include "image.hpp" -#include "size.hpp" -#include "sprite.hpp" - -namespace mlk { - -/** - * \brief Load client resources. - */ -class client_resources_loader : public loader { -protected: - /** - * Require a size object from an object property. - * - * The size is an array of two integers (e.g. [ 1, 2 ]). - * - * \pre object.is_object() - * \param id the resource id - * \param object the object - * \param property the property - * \return the size - * \throw std::runtime_error if the property is not a size - */ - size require_size(const std::string& id, - const nlohmann::json& object, - const std::string& property) const; - - /** - * Get a size object or a default one if not present or invalid. - * - * \pre object.is_object() - * \param id the resource id - * \param object the object - * \param property the property - * \return the size or default one - */ - size get_size(const std::string& id, - const nlohmann::json& object, - const std::string& property) const noexcept; - -public: - /** - * Client resources loader constructor. - * - * The window is required because some of the resources require it. - * - * \param window the window - * \param locator the resources locator - */ - inline client_resources_loader(mlk::locator& locator) - : loader(locator) - { - } - - /** - * Load a font. - * - * \param id the resource id - * \param size the desired size - * \return the font - * \throw std::runtime_error on errors - */ - virtual font load_font(const std::string& id, unsigned size); - - /** - * Load an image. - * - * \param id the resource id - * \return the image - * \throw std::runtime_error on errors - */ - virtual image load_image(const std::string& id); - - /** - * Load a sprite. - * - * \param id the resource id - * \return the sprite - * \throw std::runtime_error on errors - */ - virtual sprite load_sprite(const std::string& id); - - /** - * Load an animation. - * - * \param id the resource id - * \return the animation - * \throw std::runtime_error on errors - */ - virtual animation load_animation(const std::string& id); -}; - -} // !mlk - -#endif // !MALIKANIA_CLIENT_RESOURCES_LOADER_HPP
--- a/libclient/malikania/color.cpp Sun Jan 22 10:11:17 2017 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,237 +0,0 @@ -/* - * color.cpp -- color description - * - * Copyright (c) 2013-2017 Malikania Authors - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <cctype> -#include <locale> -#include <unordered_map> - -#include "color.hpp" - -namespace mlk { - -namespace { - -constexpr unsigned rgb(std::uint8_t r, std::uint8_t g, std::uint8_t b) noexcept -{ - return (0xff000000 | (r << 16) | (g << 8) | b); -} - -/* - * Convert hexadecimal value to the correct number. - */ -std::uint8_t value(char digit) -{ - if (std::isdigit(digit, {})) { - return digit - '0'; - } - if ((digit = std::toupper(digit, {})) < 'A' || digit > 'F') { - throw std::invalid_argument("invalid hexadecimal value: " + std::to_string(digit)); - } - - return digit - 55; -} - -inline std::uint8_t value(char digit1, char digit2) -{ - return ((value(digit1) << 4) & 0xf0) | value(digit2); -} - -const std::unordered_map<std::string, std::uint32_t> colors{ - { "aliceblue", rgb(240, 248, 255) }, - { "antiquewhite", rgb(250, 235, 215) }, - { "aqua", rgb( 0, 255, 255) }, - { "aquamarine", rgb(127, 255, 212) }, - { "azure", rgb(240, 255, 255) }, - { "beige", rgb(245, 245, 220) }, - { "bisque", rgb(255, 228, 196) }, - { "black", rgb( 0, 0, 0) }, - { "blanchedalmond", rgb(255, 235, 205) }, - { "blue", rgb( 0, 0, 255) }, - { "blueviolet", rgb(138, 43, 226) }, - { "brown", rgb(165, 42, 42) }, - { "burlywood", rgb(222, 184, 135) }, - { "cadetblue", rgb( 95, 158, 160) }, - { "chartreuse", rgb(127, 255, 0) }, - { "chocolate", rgb(210, 105, 30) }, - { "coral", rgb(255, 127, 80) }, - { "cornflowerblue", rgb(100, 149, 237) }, - { "cornsilk", rgb(255, 248, 220) }, - { "crimson", rgb(220, 20, 60) }, - { "cyan", rgb( 0, 255, 255) }, - { "darkblue", rgb( 0, 0, 139) }, - { "darkcyan", rgb( 0, 139, 139) }, - { "darkgoldenrod", rgb(184, 134, 11) }, - { "darkgray", rgb(169, 169, 169) }, - { "darkgreen", rgb( 0, 100, 0) }, - { "darkgrey", rgb(169, 169, 169) }, - { "darkkhaki", rgb(189, 183, 107) }, - { "darkmagenta", rgb(139, 0, 139) }, - { "darkolivegreen", rgb( 85, 107, 47) }, - { "darkorange", rgb(255, 140, 0) }, - { "darkorchid", rgb(153, 50, 204) }, - { "darkred", rgb(139, 0, 0) }, - { "darksalmon", rgb(233, 150, 122) }, - { "darkseagreen", rgb(143, 188, 143) }, - { "darkslateblue", rgb( 72, 61, 139) }, - { "darkslategray", rgb( 47, 79, 79) }, - { "darkslategrey", rgb( 47, 79, 79) }, - { "darkturquoise", rgb( 0, 206, 209) }, - { "darkviolet", rgb(148, 0, 211) }, - { "deeppink", rgb(255, 20, 147) }, - { "deepskyblue", rgb( 0, 191, 255) }, - { "dimgray", rgb(105, 105, 105) }, - { "dimgrey", rgb(105, 105, 105) }, - { "dodgerblue", rgb( 30, 144, 255) }, - { "firebrick", rgb(178, 34, 34) }, - { "floralwhite", rgb(255, 250, 240) }, - { "forestgreen", rgb( 34, 139, 34) }, - { "fuchsia", rgb(255, 0, 255) }, - { "gainsboro", rgb(220, 220, 220) }, - { "ghostwhite", rgb(248, 248, 255) }, - { "gold", rgb(255, 215, 0) }, - { "goldenrod", rgb(218, 165, 32) }, - { "gray", rgb(128, 128, 128) }, - { "green", rgb( 0, 128, 0) }, - { "greenyellow", rgb(173, 255, 47) }, - { "grey", rgb(128, 128, 128) }, - { "honeydew", rgb(240, 255, 240) }, - { "hotpink", rgb(255, 105, 180) }, - { "indianred", rgb(205, 92, 92) }, - { "indigo", rgb( 75, 0, 130) }, - { "ivory", rgb(255, 255, 240) }, - { "khaki", rgb(240, 230, 140) }, - { "lavender", rgb(230, 230, 250) }, - { "lavenderblush", rgb(255, 240, 245) }, - { "lawngreen", rgb(124, 252, 0) }, - { "lemonchiffon", rgb(255, 250, 205) }, - { "lightblue", rgb(173, 216, 230) }, - { "lightcoral", rgb(240, 128, 128) }, - { "lightcyan", rgb(224, 255, 255) }, - { "lightgoldenrodyellow", rgb(250, 250, 210) }, - { "lightgray", rgb(211, 211, 211) }, - { "lightgreen", rgb(144, 238, 144) }, - { "lightgrey", rgb(211, 211, 211) }, - { "lightpink", rgb(255, 182, 193) }, - { "lightsalmon", rgb(255, 160, 122) }, - { "lightseagreen", rgb( 32, 178, 170) }, - { "lightskyblue", rgb(135, 206, 250) }, - { "lightslategray", rgb(119, 136, 153) }, - { "lightslategrey", rgb(119, 136, 153) }, - { "lightsteelblue", rgb(176, 196, 222) }, - { "lightyellow", rgb(255, 255, 224) }, - { "lime", rgb( 0, 255, 0) }, - { "limegreen", rgb( 50, 205, 50) }, - { "linen", rgb(250, 240, 230) }, - { "magenta", rgb(255, 0, 255) }, - { "maroon", rgb(128, 0, 0) }, - { "mediumaquamarine", rgb(102, 205, 170) }, - { "mediumblue", rgb( 0, 0, 205) }, - { "mediumorchid", rgb(186, 85, 211) }, - { "mediumpurple", rgb(147, 112, 219) }, - { "mediumseagreen", rgb( 60, 179, 113) }, - { "mediumslateblue", rgb(123, 104, 238) }, - { "mediumspringgreen", rgb( 0, 250, 154) }, - { "mediumturquoise", rgb( 72, 209, 204) }, - { "mediumvioletred", rgb(199, 21, 133) }, - { "midnightblue", rgb( 25, 25, 112) }, - { "mintcream", rgb(245, 255, 250) }, - { "mistyrose", rgb(255, 228, 225) }, - { "moccasin", rgb(255, 228, 181) }, - { "navajowhite", rgb(255, 222, 173) }, - { "navy", rgb( 0, 0, 128) }, - { "oldlace", rgb(253, 245, 230) }, - { "olive", rgb(128, 128, 0) }, - { "olivedrab", rgb(107, 142, 35) }, - { "orange", rgb(255, 165, 0) }, - { "orangered", rgb(255, 69, 0) }, - { "orchid", rgb(218, 112, 214) }, - { "palegoldenrod", rgb(238, 232, 170) }, - { "palegreen", rgb(152, 251, 152) }, - { "paleturquoise", rgb(175, 238, 238) }, - { "palevioletred", rgb(219, 112, 147) }, - { "papayawhip", rgb(255, 239, 213) }, - { "peachpuff", rgb(255, 218, 185) }, - { "peru", rgb(205, 133, 63) }, - { "pink", rgb(255, 192, 203) }, - { "plum", rgb(221, 160, 221) }, - { "powderblue", rgb(176, 224, 230) }, - { "purple", rgb(128, 0, 128) }, - { "red", rgb(255, 0, 0) }, - { "rosybrown", rgb(188, 143, 143) }, - { "royalblue", rgb( 65, 105, 225) }, - { "saddlebrown", rgb(139, 69, 19) }, - { "salmon", rgb(250, 128, 114) }, - { "sandybrown", rgb(244, 164, 96) }, - { "seagreen", rgb( 46, 139, 87) }, - { "seashell", rgb(255, 245, 238) }, - { "sienna", rgb(160, 82, 45) }, - { "silver", rgb(192, 192, 192) }, - { "skyblue", rgb(135, 206, 235) }, - { "slateblue", rgb(106, 90, 205) }, - { "slategray", rgb(112, 128, 144) }, - { "slategrey", rgb(112, 128, 144) }, - { "snow", rgb(255, 250, 250) }, - { "springgreen", rgb( 0, 255, 127) }, - { "steelblue", rgb( 70, 130, 180) }, - { "tan", rgb(210, 180, 140) }, - { "teal", rgb( 0, 128, 128) }, - { "thistle", rgb(216, 191, 216) }, - { "tomato", rgb(255, 99, 71) }, - { "transparent", 0 }, - { "turquoise", rgb( 64, 224, 208) }, - { "violet", rgb(238, 130, 238) }, - { "wheat", rgb(245, 222, 179) }, - { "white", rgb(255, 255, 255) }, - { "whitesmoke", rgb(245, 245, 245) }, - { "yellow", rgb(255, 255, 0) }, - { "yellowgreen", rgb(154, 205, 50) } -}; - -} // !namespace - -color::color(const std::string& name) -{ - if (!name.empty()) { - // Parse #rrggbb or #rgb. - if (name[0] == '#') { - if (name.length() == 7) { - m_red = value(name[1], name[2]); - m_green = value(name[3], name[4]); - m_blue = value(name[5], name[6]); - } else if (name.length() == 4) { - m_red = value(name[1], name[1]); - m_green = value(name[2], name[2]); - m_blue = value(name[3], name[3]); - } else { - throw std::invalid_argument("invalid format"); - } - } else { - // Name lookup. - auto it = colors.find(name); - - if (it == colors.end()) { - throw std::invalid_argument(name + " is not a valid color"); - } - - // Assign the color to *this. - *this = it->second; - } - } -} - -} // !mlk
--- a/libclient/malikania/color.hpp Sun Jan 22 10:11:17 2017 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,130 +0,0 @@ -/* - * color.hpp -- color description - * - * Copyright (c) 2013-2017 Malikania Authors - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef MALIKANIA_COLOR_HPP -#define MALIKANIA_COLOR_HPP - -/** - * \file color.hpp - * \brief Colors. - */ - -#include <cstdint> -#include <string> - -namespace mlk { - -/** - * \brief color description - */ -class color { -private: - std::uint8_t m_red{0}; - std::uint8_t m_green{0}; - std::uint8_t m_blue{0}; - std::uint8_t m_alpha{255}; - -public: - /** - * Default color to black. - */ - inline color() noexcept = default; - - /** - * Constructor with all fields. - * - * \param red the red value - * \param green the green value - * \param blue the blue value - * \param alpha the alpha value - */ - inline color(std::uint8_t red, std::uint8_t green, std::uint8_t blue, std::uint8_t alpha) noexcept - : m_red(red) - , m_green(green) - , m_blue(blue) - , m_alpha(alpha) - { - } - - /** - * Constructor with an hexadecimal value. - * - * \param hex the color - */ - inline color(std::uint32_t hex) noexcept - : m_red((hex >> 16) & 0xff) - , m_green((hex >> 8) & 0xff) - , m_blue(hex & 0xff) - , m_alpha((hex >> 24) & 0xff) - { - } - - /** - * Construct a color from #rrggbb or name. - * - * See the SVG this [list](http://www.december.com/html/spec/colorsvg.html) for supported names. - * - * \param name the color name - * \throw std::invalid_argument if the color does not exist or is invalid - */ - color(const std::string& name); - - /** - * Get the red value. - * - * \return the value - */ - inline std::uint8_t red() const noexcept - { - return m_red; - } - - /** - * Get the green value. - * - * \return the value - */ - inline std::uint8_t green() const noexcept - { - return m_green; - } - - /** - * Get the blue value. - * - * \return the value - */ - inline std::uint8_t blue() const noexcept - { - return m_blue; - } - - /** - * Get the alpha value. - * - * \return the value - */ - inline std::uint8_t alpha() const noexcept - { - return m_alpha; - } -}; - -} // !mlk - -#endif // !MALIKANIA_COLOR_HPP
--- a/libclient/malikania/font.cpp Sun Jan 22 10:11:17 2017 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -/* - * font.cpp -- font object - * - * Copyright (c) 2013-2017 Malikania Authors - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "font_backend.hpp" - -namespace mlk { - -font::font(std::string data, unsigned size) - : m_backend(std::make_unique<backend_impl>(std::move(data), size)) - , m_size(size) -{ -} - -font::font(font&& other) noexcept = default; - -font::~font() noexcept = default; - -size font::clip(const std::string& text) const -{ - return m_backend->clip(*this, text); -} - -font& font::operator=(font&& other) noexcept = default; - -} // !mlk
--- a/libclient/malikania/font.hpp Sun Jan 22 10:11:17 2017 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,114 +0,0 @@ -/* - * font.hpp -- font object - * - * Copyright (c) 2013-2017 Malikania Authors - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef MALIKANIA_FONT_HPP -#define MALIKANIA_FONT_HPP - -/** - * \file font.hpp - * \brief fonts. - */ - -#include <memory> -#include <string> - -#include "size.hpp" - -namespace mlk { - -/** - * \brief font object. - */ -class font { -private: - class backend_impl; - - std::unique_ptr<backend_impl> m_backend; - unsigned m_size; - -public: - /** - * Construct a font from binary data. - * - * \param data the raw data - * \param size the size - */ - font(std::string data, unsigned size); - - /** - * Default move constructor. - * - * \param other the other font - */ - font(font&& other) noexcept; - - /** - * Default destructor. - */ - virtual ~font() noexcept; - - /** - * Get the font size. - * - * \return the font size - */ - inline unsigned size() const noexcept - { - return m_size; - } - - /** - * Get the underlying backend. - * - * \return the backend - */ - inline const backend_impl& backend() const noexcept - { - return *m_backend; - } - - /** - * Overloaded function. - * - * \return the backend - */ - inline backend_impl& backend() noexcept - { - return *m_backend; - } - - /** - * Get the clipping size required to draw the given text. - * - * \param text the text to clip - * \return the required size - */ - mlk::size clip(const std::string& text) const; - - /** - * Default move assignment operator. - * - * \param other the other font - * \return this - */ - font& operator=(font&& other) noexcept; -}; - -} // !mlk - -#endif // MALIKANIA_FONT_HPP
--- a/libclient/malikania/frame.cpp Sun Jan 22 10:11:17 2017 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -/* - * frame.cpp -- top level GUI frame - * - * Copyright (c) 2013-2017 Malikania Authors - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "layout.hpp" -#include "frame.hpp" -#include "point.hpp" -#include "rectangle.hpp" -#include "theme.hpp" -#include "window.hpp" - -namespace mlk { - -mlk::size frame::size(window &win) -{ - return m_layout ? m_layout->size(win) : mlk::size(); -} - -void frame::draw(window& win) -{ - if (m_layout) { - win.theme().draw_frame(win, *this); - } -} - -void frame::move(point pos) -{ - m_position = std::move(pos); -} - -} // !mlk
--- a/libclient/malikania/frame.hpp Sun Jan 22 10:11:17 2017 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,174 +0,0 @@ -/* - * frame.hpp -- top level GUI frame - * - * Copyright (c) 2013-2017 Malikania Authors - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef MALIKANIA_CLIENT_FRAME_HPP -#define MALIKANIA_CLIENT_FRAME_HPP - -/** - * \file frame.hpp - * \brief Top level GUI frame. - */ - -#include <memory> - -#include "point.hpp" -#include "size.hpp" - -namespace mlk { - -class layout; -class point; -class window; - -/** - * \brief Top level GUI frame. - */ -class frame { -private: - std::shared_ptr<mlk::layout> m_layout; - mlk::point m_position; - mlk::size m_padding{10, 10}; - -public: - /** - * Create a frame with an optional layout. - * - * \param layout the optional layout - */ - inline frame(std::shared_ptr<mlk::layout> layout = nullptr) noexcept - : m_layout(std::move(layout)) - { - } - - /** - * Virtual destructor defaulted. - */ - virtual ~frame() = default; - - /** - * Get the current layout. - * - * return the layout - */ - inline const std::shared_ptr<mlk::layout>& layout() const noexcept - { - return m_layout; - } - - /** - * Overloaded function. - * - * \return the layout - */ - inline std::shared_ptr<mlk::layout>& layout() noexcept - { - return m_layout; - } - - /** - * Change the current frame layout. - * - * \param layout the new layout (may be null) - */ - inline void set_layout(std::shared_ptr<mlk::layout> layout) noexcept - { - m_layout = std::move(layout); - } - - /** - * Get the current frame position. - * - * \return the frame position - */ - inline const point& position() const noexcept - { - return m_position; - } - - /** - * Overloaded function. - * - * \return the position - */ - inline point& position() noexcept - { - return m_position; - } - - /** - * Get the frame padding. - * - * \return the frame padding - */ - inline const mlk::size& padding() const noexcept - { - return m_padding; - } - - /** - * Overloaded function. - * - * \return the padding - */ - inline mlk::size& padding() noexcept - { - return m_padding; - } - - /** - * Set the frame padding. - * - * \param padding the padding - */ - inline void set_padding(mlk::size padding) noexcept - { - m_padding = std::move(padding); - } - - /** - * Compute the total frame size. - * - * If no layout is attached, the frame returns a null size. Otherwise, the - * default implementation returns `layout()->size()`. - * - * \param win the window - * \return the size required to draw this frame - */ - virtual mlk::size size(window& win); - - /** - * Draw the frame and its content. - * - * If no layout is attached, the function is a no-op. Otherwise the default - * implementation calls `win.theme().draw_frame(*this)`. - * - * \param win the window - */ - virtual void draw(window& win); - - /** - * Move the frame to somewhere else. - * - * \param pos the new position - */ - virtual void move(point pos); -}; - -} // !mlk - -#endif // !MALIKANIA_CLIENT_FRAME_HPP
--- a/libclient/malikania/grid_layout.cpp Sun Jan 22 10:11:17 2017 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,112 +0,0 @@ -/* - * grid_layout.cpp -- basic grid layout - * - * Copyright (c) 2013-2016 Malikania Authors - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <algorithm> -#include <numeric> - -#include "grid_layout.hpp" -#include "size.hpp" -#include "widget.hpp" - -namespace mlk { - -unsigned grid_layout::index(unsigned r, unsigned c) const noexcept -{ - return r * m_cols + c; -} - -void grid_layout::update_rsize(window& win) noexcept -{ - for (unsigned r = 0; r < m_rows; ++r) { - m_min_rsize[r] = 0; - - for (unsigned c = 0; c < m_cols; ++c) { - auto idx = index(r, c); - - if (!m_widgets[idx]) { - continue; - } - - auto size = m_widgets[index(r, c)]->size(win); - - if (size.height() > m_min_rsize[r]) { - m_min_rsize[r] = size.height(); - } - } - } -} - -void grid_layout::update_csize(window& win) noexcept -{ - for (unsigned c = 0; c < m_cols; ++c) { - m_min_csize[c] = 0; - - for (unsigned r = 0; r < m_rows; ++r) { - auto idx = index(r, c); - - if (!m_widgets[idx]) { - continue; - } - - auto size = m_widgets[index(r, c)]->size(win); - - if (size.width() > m_min_csize[c]) { - m_min_csize[c] = size.width(); - } - } - } -} - -grid_layout::grid_layout(unsigned rows, unsigned columns) - : m_rows(rows) - , m_cols(columns) -{ - m_widgets.resize(rows * columns); - m_min_rsize.resize(rows); - m_min_csize.resize(columns); -} - -void grid_layout::add_widget(unsigned r, unsigned c, std::shared_ptr<widget> w) -{ - m_widgets[index(r, c)] = std::move(w); -} - -void grid_layout::remove_widget(unsigned r, unsigned c) -{ - m_widgets[index(r, c)] = nullptr; -} - -void grid_layout::remove_widget(std::shared_ptr<widget> w) -{ - m_widgets.erase(std::remove(m_widgets.begin(), m_widgets.end(), w), m_widgets.end()); -} - -mlk::size grid_layout::size(window& win) const noexcept -{ - return { - std::accumulate(m_min_csize.begin(), m_min_csize.end(), 0) + (m_rows * 10), - std::accumulate(m_min_rsize.begin(), m_min_rsize.end(), 0) + (m_cols * 10) - }; -} - -void grid_layout::draw(window &win, const rectangle &dst) -{ - -} - -} // !mlk
--- a/libclient/malikania/grid_layout.hpp Sun Jan 22 10:11:17 2017 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,70 +0,0 @@ -/* - * grid_layout.hpp -- basic grid layout - * - * Copyright (c) 2013-2016 Malikania Authors - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef MALIKANIA_CLIENT_GRID_LAYOUT_HPP -#define MALIKANIA_CLIENT_GRID_LAYOUT_HPP - -#include <memory> -#include <vector> - -#include "layout.hpp" - -namespace mlk { - -class widget; - -class grid_layout : public layout { -private: - // Dimensions. - unsigned m_rows; - unsigned m_cols; - - // Widgets. - std::vector<std::shared_ptr<widget>> m_widgets; - - /* - * Track maximum size by rows/columns to determine the minimum whole - * layout size. - * - * It's only used in draw() but kept as member variables to avoid useless - * reallocation on each frame. - */ - std::vector<unsigned> m_min_rsize; - std::vector<unsigned> m_min_csize; - - unsigned index(unsigned, unsigned) const noexcept; - void update_rsize(window&) noexcept; - void update_csize(window&) noexcept; - -public: - grid_layout(unsigned rows, unsigned columns); - - void add_widget(unsigned r, unsigned c, std::shared_ptr<widget> w); - - void remove_widget(unsigned r, unsigned c); - - void remove_widget(std::shared_ptr<widget> w); - - mlk::size size(window& win) const noexcept override; - - void draw(window& win, const rectangle& dst) override; -}; - -} // !mlk - -#endif // !MALIKANIA_CLIENT_GRID_LAYOUT_HPP
--- a/libclient/malikania/image.cpp Sun Jan 22 10:11:17 2017 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,49 +0,0 @@ -/* - * image.cpp -- image object - * - * Copyright (c) 2013-2017 Malikania Authors - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "image_backend.hpp" - -namespace mlk { - -image::image(std::string data) - : m_backend(new backend_impl(*this, std::move(data))) -{ -} - -image::image(image&&) noexcept = default; - -image::~image() noexcept = default; - -const mlk::size& image::size() const noexcept -{ - return m_backend->size(); -} - -void image::draw(window& window, const point& position) -{ - m_backend->draw(window, position); -} - -void image::draw(window& window, const rectangle& source, const rectangle& target) -{ - m_backend->draw(window, source, target); -} - -image& image::operator=(image&&) noexcept = default; - -} // !mlk
--- a/libclient/malikania/image.hpp Sun Jan 22 10:11:17 2017 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,123 +0,0 @@ -/* - * image.hpp -- image object - * - * Copyright (c) 2013-2017 Malikania Authors - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef MALIKANIA_IMAGE_HPP -#define MALIKANIA_IMAGE_HPP - -/** - * \file image.hpp - * \brief Images. - */ - -#include <memory> -#include <string> - -#include "point.hpp" -#include "rectangle.hpp" -#include "size.hpp" - -namespace mlk { - -class window; - -/** - * \brief Image object. - */ -class image { -private: - class backend_impl; - - std::unique_ptr<backend_impl> m_backend; - -public: - /** - * Construct an image from the binary data. - * - * \param window the window - * \param data the data - */ - image(std::string data); - - /** - * Default move constructor. - * - * \param other the other image - */ - image(image&& other) noexcept; - - /** - * Default destructor. - */ - ~image() noexcept; - - /** - * Overloaded function. - * - * \return the backend - */ - inline class backend_impl& backend() noexcept - { - return *m_backend; - } - - /** - * Get the underlying backend. - * - * \return the backend - */ - inline const backend_impl& backend() const noexcept - { - return *m_backend; - } - - /** - * Get the image size. - * - * \return the size - */ - const mlk::size& size() const noexcept; - - /** - * Draw the image to the window. - * - * \param window the window - * \param position the position - */ - void draw(window& window, const point& position = {0, 0}); - - /** - * Overloaded function. - * - * \param window the window - * \param source the source to clip - * \param target the target destination - */ - void draw(window& window, const rectangle& source, const rectangle& target); - - /** - * Default move assignment operator. - * - * \param other the other image - * \return this - */ - image& operator=(image&& image) noexcept; -}; - -} // !mlk - -#endif // !MALIKANIA_IMAGE_HPP
--- a/libclient/malikania/key.hpp Sun Jan 22 10:11:17 2017 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,244 +0,0 @@ -/* - * key.hpp -- key definitions - * - * Copyright (c) 2013-2017 Malikania Authors - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef MALIKANIA_CLIENT_KEY_HPP -#define MALIKANIA_CLIENT_KEY_HPP - -namespace mlk { - -/** - * \brief Describe keyboard modifiers - * - * This enumeration is a satisfied the Bitmask concept. - */ -enum class mod { - none = 0, //!< no modifiers - left_control = (1 << 1), //!< left control - left_alt = (1 << 2), //!< left alt - left_shift = (1 << 3), //!< left shift - left_super = (1 << 4), //!< left logo - right_control = (1 << 5), //!< right control - right_alt = (1 << 6), //!< right alt - right_shift = (1 << 7), //!< right shift - right_super = (1 << 8), //!< right logo - num_lock = (1 << 9), //!< num lock is on - caps_lock = (1 << 10), //!< caps lock is on - control = left_control | //!< left or right control - right_control, - shift = left_shift | //!< left or right shift - right_shift, - alt = left_alt | //!< left or right alt - right_alt, - super = left_super | //!< left or right super - right_super -}; - -/** - * \cond ENUM_HIDDEN_SYMBOLS - */ - -inline mod operator^(mod v1, mod v2) noexcept -{ - return static_cast<mod>(static_cast<unsigned>(v1) ^ static_cast<unsigned>(v2)); -} - -inline mod operator&(mod v1, mod v2) noexcept -{ - return static_cast<mod>(static_cast<unsigned>(v1)& static_cast<unsigned>(v2)); -} - -inline mod operator|(mod v1, mod v2) noexcept -{ - return static_cast<mod>(static_cast<unsigned>(v1) | static_cast<unsigned>(v2)); -} - -inline mod operator~(mod v) noexcept -{ - return static_cast<mod>(~static_cast<unsigned>(v)); -} - -inline mod& operator|=(mod& v1, mod v2) noexcept -{ - v1 = static_cast<mod>(static_cast<unsigned>(v1) | static_cast<unsigned>(v2)); - - return v1; -} - -inline mod& operator&=(mod& v1, mod v2) noexcept -{ - v1 = static_cast<mod>(static_cast<unsigned>(v1)& static_cast<unsigned>(v2)); - - return v1; -} - -inline mod& operator^=(mod& v1, mod v2) noexcept -{ - v1 = static_cast<mod>(static_cast<unsigned>(v1) ^ static_cast<unsigned>(v2)); - - return v1; -} - -/** - * \endcond - */ - -/** - * \brief Key description. - */ -enum class key { - unknown, - a, - b, - c, - d, - e, - f, - g, - h, - i, - j, - k, - l, - m, - n, - o, - p, - q, - r, - s, - t, - u, - v, - w, - x, - y, - z, - exclaim, - double_quote, - percent, - dollar, - ampersand, - left_parenthese, - right_parenthese, - asterisk, - plus, - colon, - less, - greater, - question, - at, - caret, - underscore, - back_quote, - quote, - one, - two, - three, - four, - five, - six, - seven, - eight, - nine, - zero, - enter, - escape, - backspace, - tab, - space, - minus, - equals, - left_bracket, - right_bracket, - backslash, - hash, - semicolon, - apostrophe, - grave, - comma, - period, - slash, - caps_lock, - f1, - f2, - f3, - f4, - f5, - f6, - f7, - f8, - f9, - f10, - f11, - f12, - f13, - f14, - f15, - f16, - f17, - f18, - f19, - f20, - f21, - f22, - f23, - f24, - print_screen, - scroll_lock, - pause, - insert, - home, - page_up, - page_down, - del, - end, - right, - left, - down, - up, - kp_divide, - kp_multiply, - kp_minus, - kp_plus, - kp_enter, - kp_one, - kp_two, - kp_three, - kp_four, - kp_five, - kp_six, - kp_seven, - kp_eight, - kp_nine, - kp_zero, - mute, - volume_up, - volume_down, - left_control, - left_alt, - left_shift, - left_super, - right_control, - right_alt, - right_shift, - right_super -}; - -} // !mlk - -#endif // !MALIKANIA_CLIENT_KEY_HPP
--- a/libclient/malikania/label.cpp Sun Jan 22 10:11:17 2017 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +0,0 @@ -/* - * label.cpp -- GUI label element - * - * Copyright (c) 2013-2017 Malikania Authors - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "label.hpp" -#include "size.hpp" -#include "theme.hpp" -#include "window.hpp" - -namespace mlk { - -label::label(std::string text) noexcept - : m_text(std::move(text)) -{ -} - -void label::draw(window& w, const rectangle& rect) -{ - w.theme().draw_label(w, *this, rect); -} - -mlk::size label::size(window& w) const noexcept -{ - return w.theme().size_label(*this); -} - -} // !mlk
--- a/libclient/malikania/label.hpp Sun Jan 22 10:11:17 2017 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,93 +0,0 @@ -/* - * label.hpp -- GUI label element - * - * Copyright (c) 2013-2017 Malikania Authors - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef MALIKANIA_CLIENT_LABEL_HPP -#define MALIKANIA_CLIENT_LABEL_HPP - -/** - * \file label.hp - * \brief GUI label element. - */ - -#include <string> - -#include "widget.hpp" - -namespace mlk { - -/** - * \brief Basic label for displaying test. - */ -class label : public widget { -private: - std::string m_text; - -public: - /** - * Create a label with an optional text. - * - * \param text the text - */ - label(std::string text = "") noexcept; - - /** - * Get the text. - * - * \return the label text - */ - inline const std::string& text() const noexcept - { - return m_text; - } - - /** - * Overloaded function. - * - * \return the text - */ - inline std::string& text() noexcept - { - return m_text; - } - - /** - * Set the label text. - * - * \param text the text - */ - inline void set_text(std::string text) noexcept - { - m_text = std::move(text); - } - - using widget::draw; - - /** - * \copydoc widget::draw - */ - void draw(window& w, const rectangle& rect) override; - - /** - * \copydoc widget::size - */ - mlk::size size(window& w) const noexcept override; -}; - -} // !mlk - -#endif // !MALIKANIA_CLIENT_LABEL_HPP
--- a/libclient/malikania/layout.hpp Sun Jan 22 10:11:17 2017 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,77 +0,0 @@ -/* - * layout.hpp -- generic layout manager inside a frame - * - * Copyright (c) 2013-2017 Malikania Authors - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef MALIKANIA_CLIENT_LAYOUT_HPP -#define MALIKANIA_CLIENT_LAYOUT_HPP - -/** - * \brief Generic layout manager inside a frame. - */ - -namespace mlk { - -class mouse_click_event; -class rectangle; -class size; -class window; - -/** - * \brief Manages the widgets inside a frame. - * - * Layouts are responsible of positioning the widgets inside a frame. They - * handle their positions and dispatch events if applicable. - * - * \see grid_layout - */ -class layout { -public: - /** - * Virtual destructor defaulted. - */ - virtual ~layout() noexcept = default; - - /** - * Handle mouse down. - * - * \param ev the mouse event - */ - virtual void handle_mouse_down(const mouse_click_event& ev) = 0; - - /** - * Handle mouse up. - * - * \param ev the event - */ - virtual void handle_mouse_up(const mouse_click_event& ev) = 0; - - /** - * Return the required minimum size to draw the whole layout. - */ - virtual mlk::size size(window& win) const = 0; - - /** - * Draw the layout content at the given position. - * - * \param win the window - */ - virtual void draw(window& win, const rectangle& dst) = 0; -}; - -} // !mlk - -#endif // !MALIKANIA_CLIENT_LAYOUT_HPP
--- a/libclient/malikania/line.hpp Sun Jan 22 10:11:17 2017 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,125 +0,0 @@ -/* - * line.hpp -- line description - * - * Copyright (c) 2013-2017 Malikania Authors - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef MALIKANIA_LINE_HPP -#define MALIKANIA_LINE_HPP - -/** - * \file line.hpp - * \brief line description. - */ - -namespace mlk { - -/** - * \brief line description. - * - * A line has an origin (x, y) and a destination (x, y). - */ -class line { -private: - int m_x1; - int m_y1; - int m_x2; - int m_y2; - -public: - /** - * Construct a line. - * - * \param x1 the first x - * \param y1 the first y - * \param x2 the second x - * \param y2 the second y - */ - inline line(int x1 = 0, int y1 = 0, int x2 = 0, int y2 = 0) noexcept - : m_x1(x1) - , m_y1(y1) - , m_x2(x2) - , m_y2(y2) - { - } - - /** - * Get the first x. - * - * \return the x1 - */ - inline int x1() const noexcept - { - return m_x1; - } - - /** - * Get the first y. - * - * \return the y1 - */ - inline int y1() const noexcept - { - return m_y1; - } - - /** - * Get the second x. - * - * \return the x2 - */ - inline int x2() const noexcept - { - return m_x2; - } - - /** - * Get the second y. - * - * \return the y2 - */ - inline int y2() const noexcept - { - return m_y2; - } -}; - -/** - * Compare equality. - * - * \param l1 the first line - * \param l2 the second line - * \return true if they equal - */ -inline bool operator==(const line& l1, const line& l2) noexcept -{ - return l1.x1() == l2.x1() && l1.x2() == l2.x2() && l1.y1() == l2.y1() && l1.y2() == l2.y2(); -} - -/** - * Compare equality. - * - * \param l1 the first line - * \param l2 the second line - * \return false if they equal - */ -inline bool operator!=(const line& l1, const line& l2) noexcept -{ - return !(l1 == l2); -} - -} // !mlk - -#endif // !MALIKANIA_LINE_HPP
--- a/libclient/malikania/mouse.hpp Sun Jan 22 10:11:17 2017 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +0,0 @@ -/* - * mouse.hpp -- mouse definitions - * - * Copyright (c) 2013-2017 Malikania Authors - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef MALIKANIA_CLIENT_MOUSE_HPP -#define MALIKANIA_CLIENT_MOUSE_HPP - -/** - * \file mouse.hpp - * \brief Mouse definitions. - */ - -namespace mlk { - -/** - * \brief Describe mouse button - */ -enum class mouse { - none, //!< no buttons are pressed - left, //!< left click is pressed - right, //!< right click is pressed - middle //!< middle click is pressed -}; - -} // !mlk - -#endif // !MALIKANIA_CLIENT_MOUSE_HPP
--- a/libclient/malikania/point.hpp Sun Jan 22 10:11:17 2017 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,97 +0,0 @@ -/* - * point.hpp -- point description - * - * Copyright (c) 2013-2017 Malikania Authors - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef MALIKANIA_POINT_HPP -#define MALIKANIA_POINT_HPP - -/** - * \file point.hpp - * \brief point description. - */ - -namespace mlk { - -/** - * \brief point coordinate. - */ -class point { -private: - int m_x; - int m_y; - -public: - /** - * Construct a point. - * - * \param x the x - * \param y the y - */ - inline point(int x = 0, int y = 0) noexcept - : m_x(x) - , m_y(y) - { - } - - /** - * Get the x position. - * - * \return the x - */ - inline int x() const noexcept - { - return m_x; - } - - /** - * Get the y position. - * - * \return the y - */ - inline int y() const noexcept - { - return m_y; - } -}; - -/** - * Compare equality. - * - * \param p1 the first point - * \param p2 the second point - * \return true if they equal - */ -inline bool operator==(const point& p1, const point& p2) noexcept -{ - return p1.x() == p2.x() && p1.y() == p2.y(); -} - -/** - * Compare equality. - * - * \param p1 the first point - * \param p2 the second point - * \return false if they equal - */ -inline bool operator!=(const point& p1, const point& p2) noexcept -{ - return !(p1 == p2); -} - -} // !mlk - -#endif // !MALIKANIA_POINT_HPP
--- a/libclient/malikania/rectangle.hpp Sun Jan 22 10:11:17 2017 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,138 +0,0 @@ -/* - * rectangle.hpp -- rectangle description - * - * Copyright (c) 2013-2017 Malikania Authors - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef MALIKANIA_RECTANGLE_HPP -#define MALIKANIA_RECTANGLE_HPP - -/** - * \file rectangle.hpp - * \brief rectangle description. - */ - -namespace mlk { - -/** - * \brief rectangle description. - * - * A rectangle has coordinates (x, y) and dimensions (width, height). - * - * They are commonly used for clipping images into the window. - */ -class rectangle { -private: - int m_x; - int m_y; - unsigned m_width; - unsigned m_height; - -public: - /** - * Construct a rectangle. - * - * \param x the x position - * \param y the y position - * \param width the width - * \param height the height - */ - inline rectangle(int x = 0, int y = 0, unsigned width = 0, unsigned height = 0) noexcept - : m_x(x) - , m_y(y) - , m_width(width) - , m_height(height) - { - } - - /** - * Get the x position. - * - * \return the x position - */ - inline int x() const noexcept - { - return m_x; - } - - /** - * Get the y position. - * - * \return the y position - */ - inline int y() const noexcept - { - return m_y; - } - - /** - * Get the rectangle width. - * - * \return the width - */ - inline unsigned width() const noexcept - { - return m_width; - } - - /** - * Get the rectangle height. - * - * \return the height - */ - inline unsigned height() const noexcept - { - return m_height; - } - - /** - * Check if the rectangle has null dimensions. - * - * \return true if weight and height are 0 - */ - inline bool is_null() const noexcept - { - return m_width == 0 && m_height == 0; - } -}; - -/** - * Compare equality. - * - * \param r1 the first rectangle - * \param r2 the second rectangle - * \return true if they equal - */ -inline bool operator==(const rectangle& r1, const rectangle& r2) noexcept -{ - return r1.x() == r2.x() && r1.y() == r2.y() && - r1.width() == r2.width() && r1.height() == r2.height(); -} - -/** - * Compare equality. - * - * \param r1 the first rectangle - * \param r2 the second rectangle - * \return false if they equal - */ -inline bool operator!=(const rectangle& r1, const rectangle& r2) noexcept -{ - return !(r1 == r2); -} - -} // !mlk - -#endif // !MALIKANIA_RECTANGLE_HPP
--- a/libclient/malikania/size.hpp Sun Jan 22 10:11:17 2017 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,102 +0,0 @@ -/* - * size.hpp -- size description - * - * Copyright (c) 2013-2017 Malikania Authors - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef MALIKANIA_SIZE_HPP -#define MALIKANIA_SIZE_HPP - -namespace mlk { - -/** - * \brief size description. - */ -class size { -private: - unsigned m_width; - unsigned m_height; - -public: - /** - * Constructor. - * - * \param width the size width - * \param height the size height - */ - inline size(unsigned width = 0, unsigned height = 0) noexcept - : m_width(width) - , m_height(height) - { - } - - /** - * Get the width. - * - * \return the width - */ - inline unsigned width() const noexcept - { - return m_width; - } - - /** - * Get the height. - * - * \return the height - */ - inline unsigned height() const noexcept - { - return m_height; - } - - /** - * Check if the size is 0, 0. - * - * \return true if height and width are 0 - */ - inline bool is_null() const noexcept - { - return m_height == 0 && m_width == 0; - } -}; - -/** - * Compare equality. - * - * \param s1 the first size - * \param s2 the second size - * \return true if they equal - */ -inline bool operator==(const size& s1, const size& s2) noexcept -{ - return s1.width() == s2.width() && s1.height() == s2.height(); -} - -/** - * Compare equality. - * - * \param s1 the first size - * \param s2 the second size - * \return false if they equal - */ -inline bool operator!=(const size& s1, const size& s2) noexcept -{ - return !(s1 == s2); -} - -} // !mlk - -#endif // !MALIKANIA_SIZE_HPP
--- a/libclient/malikania/sprite.cpp Sun Jan 22 10:11:17 2017 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,67 +0,0 @@ -/* - * sprite.cpp -- image sprite - * - * Copyright (c) 2013-2017 Malikania Authors - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <cassert> - -#include "sprite.hpp" - -namespace mlk { - -sprite::sprite(mlk::image image, - mlk::size cell, - mlk::size size, - mlk::size space, - mlk::size margin) noexcept - : m_image(std::move(image)) - , m_cell(std::move(cell)) - , m_margin(std::move(margin)) - , m_space(std::move(space)) - , m_size(std::move(size)) -{ - assert(m_cell.width() > 0); - assert(m_cell.height() > 0); - - // If size is not specified, take from image. - if (m_size.is_null()) { - m_size = m_image.size(); - } - - // Compute number of cells. - m_rows = (m_size.height() - (margin.height() * 2) + m_space.height()) / (m_cell.height() + m_space.height()); - m_columns = (m_size.width() - (m_margin.width() * 2) + m_space.width()) / (m_cell.width() + m_space.width()); -} - -void sprite::draw(window& window, unsigned cell, const point& point) -{ - assert(cell < m_rows * m_columns); - - // Compute index in the grid. - unsigned hindex = (cell % m_columns); - unsigned vindex = (cell / m_columns); - - // Compute the pixel boundaries. - int x = m_margin.width() + (hindex * m_space.width()) + (hindex * m_cell.width()); - int y = m_margin.height() + (vindex * m_space.height()) + (vindex * m_cell.height()); - - rectangle source(x, y, m_cell.width(), m_cell.height()); - rectangle target(point.x(), point.y(), m_cell.width(), m_cell.height()); - - m_image.draw(window, source, target); -} - -} // !mlk
--- a/libclient/malikania/sprite.hpp Sun Jan 22 10:11:17 2017 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,144 +0,0 @@ -/* - * sprite.hpp -- image sprite - * - * Copyright (c) 2013-2017 Malikania Authors - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef MALIKANIA_SPRITE_HPP -#define MALIKANIA_SPRITE_HPP - -/** - * \file sprite.hpp - * \brief Sprite description. - */ - -#include "image.hpp" - -namespace mlk { - -/** - * \brief A Sprite is an image divided into cells. - */ -class sprite { -private: - mlk::image m_image; - mlk::size m_cell; - mlk::size m_margin; - mlk::size m_space; - mlk::size m_size; - unsigned m_rows; - unsigned m_columns; - -public: - /** - * Construct a sprite. - * - * \pre cell must not have height or width null - * \param image the image to use - * \param cell size of cell in the image - * \param margin the optional space from borders - * \param space the optional space between cells - * \param size the sprite size (if 0, taken from the image) - */ - sprite(mlk::image image, - mlk::size cell, - mlk::size margin = { 0, 0 }, - mlk::size space = { 0, 0 }, - mlk::size size = { 0, 0 }) noexcept; - - /** - * Get the underlying image. - * - * \return the image - */ - inline const mlk::image& image() const noexcept - { - return m_image; - } - - /** - * Overloaded function. - * - * \return the image - */ - inline mlk::image& image() noexcept - { - return m_image; - } - - /** - * Get the cell size. - * - * \return the cell size - */ - inline const size& cell() const noexcept - { - return m_cell; - } - - /** - * Get the margin size. - * - * \return the margin size - */ - inline const size& margin() noexcept - { - return m_margin; - } - - /** - * Get the space size. - * - * \return the space size - */ - inline const size& space() const noexcept - { - return m_space; - } - - /** - * Get the number of rows in the grid. - * - * \return the number of rows - */ - inline unsigned rows() const noexcept - { - return m_rows; - } - - /** - * Get the number of columns in the grid. - * - * \return the number of columns - */ - inline unsigned columns() const noexcept - { - return m_columns; - } - - /** - * Draw the sprite into the window at the specified position. - * - * \pre cell < rows() * columns() - * \param window the window - * \param cell the cell index - * \param position the position in the window - */ - void draw(window& window, unsigned cell, const point& position); -}; - -} // !mlk - -#endif // !MALIKANIA_SPRITE_HPP
--- a/libclient/malikania/theme.cpp Sun Jan 22 10:11:17 2017 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,116 +0,0 @@ -/* - * theme.cpp -- theming support for gui elements - * - * Copyright (c) 2013-2017 Malikania Authors - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "button.hpp" -#include "color.hpp" -#include "frame.hpp" -#include "label.hpp" -#include "layout.hpp" -#include "point.hpp" -#include "rectangle.hpp" -#include "theme.hpp" -#include "window.hpp" - -namespace mlk { - -namespace { - -#include <dejavu_sans.cpp> - -} // !namespace - -theme::theme() - : m_font(std::string(dejavu_sans, sizeof (dejavu_sans)), 10) - , m_background_color(228, 228, 228, 255) - , m_border_color(102, 102, 102, 255) - , m_text_color(50, 50, 50, 255) - , m_frame_padding(10, 10) -{ -} - -size theme::size_button(const button &b) -{ - auto clip = m_font.clip(b.text()); - - return { - clip.width() + 12, - clip.height() + 12 - }; -} - -size theme::size_label(const label& l) -{ - return m_font.clip(l.text()); -} - -void theme::draw_frame(window& win, const frame &f) -{ - auto layout_size = f.layout()->size(win); - auto frame_pos = f.position(); - - // Frame border. - win.set_drawing_color(m_border_color); - win.draw_rectangle({ - frame_pos.x(), - frame_pos.y(), - layout_size.width() + m_frame_padding.width() * 2 + 2, - layout_size.height() + m_frame_padding.height() * 2 + 2 - }); - - // Frame content. - win.set_drawing_color(m_background_color); - win.fill_rectangle({ - frame_pos.x() + 1, - frame_pos.y() + 1, - layout_size.width() + m_frame_padding.width() * 2, - layout_size.height() + m_frame_padding.height() * 2 - }); - - // Layout. - f.layout()->draw(win, mlk::rectangle( - frame_pos.x() + m_frame_padding.width() + 1, - frame_pos.y() + m_frame_padding.height() + 1, - layout_size.width(), - layout_size.height() - )); -} - -void theme::draw_button(window& w, const button& b, const rectangle& rect) -{ - auto size = size_button(b); - - // Border. - w.set_drawing_color(m_border_color); - w.draw_rectangle({rect.x(), rect.y(), size.width(), size.height()}); - - // Box content. - w.set_drawing_color(m_background_color); - w.fill_rectangle({rect.x() + 1, rect.y() + 1, size.width() - 2, size.height() - 2}); - - // Text. - w.set_drawing_color(m_text_color); - w.draw_text(b.text(), m_font, point{rect.x() + 5, rect.y() + 5}); -} - -void theme::draw_label(window& w, const label& label, const rectangle& rect) -{ - w.set_drawing_color(m_text_color); - w.draw_text(label.text(), m_font, mlk::point(rect.x(), rect.y())); -} - -} // !mlk
--- a/libclient/malikania/theme.hpp Sun Jan 22 10:11:17 2017 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,121 +0,0 @@ -/* - * theme.hpp -- theming support for gui elements - * - * Copyright (c) 2013-2017 Malikania Authors - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef MALIKANIA_CLIENT_THEME_HPP -#define MALIKANIA_CLIENT_THEME_HPP - -/** - * \file theme.hpp - * \brief Theming support for gui elements. - */ - -#include "color.hpp" -#include "font.hpp" -#include "size.hpp" - -namespace mlk { - -class button; -class frame; -class label; -class rectangle; -class point; -class window; - -/** - * \brief Reimplement this class to provide your own theme. - */ -class theme { -private: - font m_font; - color m_background_color; - color m_border_color; - color m_text_color; - size m_frame_padding; - -public: - /** - * Default constructor. - */ - theme(); - - /** - * Virtual destructor defaulted. - */ - virtual ~theme() noexcept = default; - - inline const color& background_color() const noexcept - { - return m_background_color; - } - - inline const color& border_color() const noexcept - { - return m_border_color; - } - - inline const color& text_color() const noexcept - { - return m_text_color; - } - - /** - * Get the required bounding rectangle size for this button. - * - * \param b the button - * \return the size - */ - virtual size size_button(const button& b); - - /** - * Get the required bouding rectangle size for this label. - * - * \param l the label - * \return the size - */ - virtual size size_label(const label& l); - - /** - * Draw the frame. - * - * \param w the main window - * \param f the frame - */ - virtual void draw_frame(window& w, const frame& f); - - /** - * Draw a button. - * - * \param w the main window - * \param b the button - */ - virtual void draw_button(window& w, const button& b, const rectangle& rect); - - /** - * Draw a label. - * - * \param w the main window - * \param l the label - * \param rect the bounding rectangle. - */ - virtual void draw_label(window& w, const label& l, const rectangle& rect); -}; - -} // !mlk - -#endif // !MALIKANIA_CLIENT_THEME_HPP
--- a/libclient/malikania/unique_layout.cpp Sun Jan 22 10:11:17 2017 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -/* - * unique_layout.cpp -- basic layout with one widget - * - * Copyright (c) 2013-2017 Malikania Authors - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "size.hpp" -#include "unique_layout.hpp" -#include "widget.hpp" - -namespace mlk { - -unique_layout::unique_layout(std::shared_ptr<mlk::widget> widget) noexcept - : m_widget(std::move(widget)) -{ -} - -void unique_layout::handle_mouse_down(const mouse_click_event& ev) -{ - if (m_widget) { - m_widget->handle_mouse_down(ev); - } -} - -void unique_layout::handle_mouse_up(const mouse_click_event& ev) -{ - if (m_widget) { - m_widget->handle_mouse_up(ev); - } -} - -mlk::size unique_layout::size(window& win) const -{ - return m_widget ? m_widget->size(win) : mlk::size(); -} - -void unique_layout::draw(window& win, const rectangle& dst) -{ - if (m_widget) { - m_widget->draw(win, dst); - } -} - -} // !mlk
--- a/libclient/malikania/unique_layout.hpp Sun Jan 22 10:11:17 2017 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,103 +0,0 @@ -/* - * unique_layout.hpp -- basic layout with one widget - * - * Copyright (c) 2013-2017 Malikania Authors - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef MALIKANIA_CLIENT_UNIQUE_LAYOUT_HPP -#define MALIKANIA_CLIENT_UNIQUE_LAYOUT_HPP - -/** - * \file unique_layout.hpp - * \brief Basic layout with one widget. - */ - -#include <memory> - -#include "layout.hpp" - -namespace mlk { - -class widget; - -/** - * \brief Simple layout that consists of one widget. - */ -class unique_layout : public layout { -private: - std::shared_ptr<mlk::widget> m_widget; - -public: - /** - * Constructor with optional widget. - * - * \param widget the widget - */ - unique_layout(std::shared_ptr<mlk::widget> w = nullptr) noexcept; - - /** - * Get the handled widget. - * - * \return the widget - */ - inline const std::shared_ptr<mlk::widget>& widget() const noexcept - { - return m_widget; - } - - /** - * Overloaded function. - * - * \return the widget - */ - inline std::shared_ptr<mlk::widget>& widget() noexcept - { - return m_widget; - } - - /** - * Replace the current widget with this one. - * - * \param widget the widget - */ - inline void set_widget(std::shared_ptr<mlk::widget> widget) noexcept - { - m_widget = std::move(widget); - } - - /** - * \copydoc layout::handle_mouse_down - */ - void handle_mouse_down(const mouse_click_event& ev) override; - - /** - * \copydoc layout::handle_mouse_up - */ - void handle_mouse_up(const mouse_click_event& ev) override; - - /** - * \copydoc layout::size - */ - mlk::size size(window& win) const override; - - /** - * \copydoc layout::draw - */ - void draw(window& win, const rectangle& dst) override; -}; - -} // !mlk - -#endif // !MALIKANIA_CLIENT_UNIQUE_LAYOUT_HPP
--- a/libclient/malikania/widget.cpp Sun Jan 22 10:11:17 2017 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,53 +0,0 @@ -/* - * widget.cpp -- basic abstract widget for GUI - * - * Copyright (c) 2013-2017 Malikania Authors - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "point.hpp" -#include "rectangle.hpp" -#include "size.hpp" -#include "widget.hpp" - -namespace mlk { - -void widget::handle_key_down(const key_event&) -{ -} - -void widget::handle_key_up(const key_event&) -{ -} - -void widget::handle_mouse_down(const mouse_click_event&) -{ -} - -void widget::handle_mouse_up(const mouse_click_event&) -{ -} - -void widget::draw(window& w, const point& pos) -{ - mlk::size sz = size(w); - mlk::rectangle rect{ - pos.x(), pos.y(), - sz.width(), sz.height() - }; - - draw(w, rect); -} - -} // !mlk
--- a/libclient/malikania/widget.hpp Sun Jan 22 10:11:17 2017 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,103 +0,0 @@ -/* - * widget.hpp -- basic abstract widget for GUI - * - * Copyright (c) 2013-2017 Malikania Authors - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef MALIKANIA_CLIENT_WIDGET_HPP -#define MALIKANIA_CLIENT_WIDGET_HPP - -/** - * \file widget.hpp - * \brief Basic abstract widget for GUI - */ - -namespace mlk { - -class key_event; -class mouse_click_event; -class point; -class rectangle; -class size; -class window; - -/** - * \brief Abstract widget - */ -class widget { -public: - /** - * Default destructor. - */ - virtual ~widget() noexcept = default; - - /** - * Handle a key down. - * - * \param ev the event - */ - virtual void handle_key_down(const key_event& ev); - - /** - * Handle a key up. - * - * \param ev the event - */ - virtual void handle_key_up(const key_event& ev); - - /** - * Handle mouse down event. - * - * \param ev the event - */ - virtual void handle_mouse_down(const mouse_click_event& ev); - - /** - * Handle a mouse up event. - * - * \param ev the event - */ - virtual void handle_mouse_up(const mouse_click_event& ev); - - /** - * Draw the widget at the specified position. - * - * Basic GUI elements will use the window theme to render themselves. - * - * \param w the window - */ - virtual void draw(window& w, const rectangle& rect) = 0; - - /** - * Helper to draw the whole widget at the given position. - * - * Effectively call draw with a rectangle overload. - * - * \param w the window - * \param pos the position - */ - virtual void draw(window& w, const point& pos); - - /** - * Get the required size to draw that widget. - * - * \return the widget size - */ - virtual mlk::size size(window& w) const noexcept = 0; -}; - -} // !mlk - -#endif // !MALIKANIA_CLIENT_WIDGET_HPP
--- a/libclient/malikania/window.cpp Sun Jan 22 10:11:17 2017 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,176 +0,0 @@ -/* - * window.cpp -- main window and basic drawing - * - * Copyright (c) 2013-2017 Malikania Authors - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <iostream> -#include <stdexcept> - -#include "color.hpp" -#include "frame.hpp" -#include "layout.hpp" -#include "theme.hpp" -#include "widget.hpp" -#include "window_backend.hpp" - -namespace mlk { - -bool window::is_frame_bound(frame& f, const point& ev_pos) noexcept -{ - auto frame_size = f.size(*this); - auto frame_padding = f.padding(); - auto frame_pos = f.position(); - - return ev_pos.x() >= frame_pos.x() + static_cast<int>(frame_padding.width()) && - ev_pos.y() >= frame_pos.y() + static_cast<int>(frame_padding.height()) && - ev_pos.x() <= frame_pos.x() + static_cast<int>(frame_padding.width() + frame_size.width()) && - ev_pos.y() <= frame_pos.y() + static_cast<int>(frame_padding.height() + frame_size.height()); -} - -window::window(unsigned width, unsigned height, const std::string& title) - : m_backend(std::make_unique<backend_impl>(*this, width, height, title)) - , m_theme(std::make_unique<mlk::theme>()) -{ -} - -window::window(window&&) noexcept = default; - -window::~window() noexcept = default; - -void window::clear() -{ - m_backend->clear(); -} - -void window::present() -{ - m_backend->present(); -} - -void window::close() noexcept -{ - m_is_open = false; - m_backend->close(); -} - -color window::drawing_color() const -{ - return m_backend->drawing_color(); -} - -void window::set_drawing_color(const color& color) -{ - m_backend->set_drawing_color(color); -} - -void window::draw_line(const line& line) -{ - m_backend->draw_line(line); -} - -void window::draw_lines(const std::vector<point>& points) -{ - m_backend->draw_lines(points); -} - -void window::draw_point(const point& point) -{ - m_backend->draw_point(point); -} - -void window::draw_points(const std::vector<point>& points) -{ - m_backend->draw_points(points); -} - -void window::draw_rectangle(const rectangle& rectangle) -{ - m_backend->draw_rectangle(rectangle); -} - -void window::draw_rectangles(const std::vector<rectangle>& rectangles) -{ - m_backend->draw_rectangles(rectangles); -} - -void window::draw_frames() -{ - for (const auto& f : m_frames) { - f->draw(*this); - } -} - -void window::fill_rectangle(const rectangle& rectangle) -{ - m_backend->fill_rectangle(rectangle); -} - -void window::fill_rectangles(const std::vector<rectangle>& rectangles) -{ - m_backend->fill_rectangles(rectangles); -} - -void window::draw_text(const std::string& text, font& font, const rectangle& rectangle) -{ - m_backend->draw_text(text, font, rectangle); -} - -void window::draw_text(const std::string& text, font& font, const point& point) -{ - m_backend->draw_text(text, font, point); -} - -void window::poll() -{ - m_backend->poll(*this); -} - -void window::handle_key_down(const key_event&) -{ -} - -void window::handle_key_up(const key_event&) -{ -} - -void window::handle_mouse_down(const mouse_click_event& ev) -{ - for (const auto& f : m_frames) { - if (is_frame_bound(*f, ev.pos)) { - f->layout()->handle_mouse_down({ - ev.button, - point(ev.pos.x() - f->position().x(), ev.pos.y() - f->position().y()) - }); - } - } -} - -void window::handle_mouse_up(const mouse_click_event&) -{ -} - -void window::handle_mouse_wheel(const mouse_wheel_event&) -{ -} - -void window::handle_quit() -{ - m_is_open = false; -} - -window& window::operator=(window&&) noexcept = default; - -} // !mlk
--- a/libclient/malikania/window.hpp Sun Jan 22 10:11:17 2017 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,350 +0,0 @@ -/* - * window.hpp -- main window and basic drawing - * - * Copyright (c) 2013-2017 Malikania Authors - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef MALIKANIA_WINDOW_HPP -#define MALIKANIA_WINDOW_HPP - -/** - * \file window.hpp - * \brief Window and drawing. - */ - -#include <functional> -#include <memory> -#include <vector> -#include <string> -#include <unordered_set> - -#include "key.hpp" -#include "mouse.hpp" -#include "point.hpp" - -namespace mlk { - -class color; -class frame; -class line; -class font; -class rectangle; -class theme; - -/** - * \brief Describe key event. - */ -class key_event { -public: - mlk::key key{key::unknown}; //!< layout-dependant key - mlk::key scancode{key::unknown}; //!< physical key - mlk::mod modifiers{mod::none}; //!< optional modifiers -}; - -/** - * \brief Describe mouse click event. - */ -class mouse_click_event { -public: - mouse button{mouse::none}; //!< which mouse button - point pos; //!< current mouse position -}; - -/** - * \brief Describe a mouse motion event. - */ -class mouse_motion_event { -public: - point pos; //!< current mouse position -}; - -/** - * \brief Describe mouse wheel (up/down) event. - */ -class mouse_wheel_event { -public: - point pos; //!< current mouse position -}; - -/** - * \brief Main window class and drawing. - */ -class window { -private: - class backend_impl; - - std::unique_ptr<backend_impl> m_backend; - std::unique_ptr<mlk::theme> m_theme; - std::unordered_set<std::shared_ptr<frame>> m_frames; - - bool m_is_open{true}; - - bool is_frame_bound(frame&, const point&) noexcept; - -public: - /** - * Create a window. - * - * \param width the initial width - * \param height the initial height - * \param title the optional title - * \throw std::runtime_error on errors - */ - window(unsigned width = 640, - unsigned height = 480, - const std::string& title = "Malikania Engine"); - - /** - * Move constructor defaulted. - */ - window(window&&) noexcept; - - /** - * Virtual destructor defaulted. - */ - virtual ~window() noexcept; - - /** - * Tells if the window is open. - * - * \return true if open - */ - inline bool is_open() const noexcept - { - return m_is_open; - } - - /** - * Get the underlying backend. - * - * \return the backend - */ - inline const backend_impl& backend() const noexcept - { - return *m_backend; - } - - /** - * Overloaded function. - * - * \return the backend - */ - inline backend_impl& backend() noexcept - { - return *m_backend; - } - - void add_frame(std::shared_ptr<mlk::frame> frame) - { - m_frames.insert(std::move(frame)); - } - - void remove_frame(std::shared_ptr<mlk::frame> frame) - { - m_frames.erase(frame); - } - - /** - * Get the current theme. - * - * \return the theme - */ - inline const mlk::theme& theme() const noexcept - { - return *m_theme; - } - - /** - * Overloaded function. - * - * \return the theme - */ - inline mlk::theme& theme() noexcept - { - return *m_theme; - } - - /** - * Clear the window content with the current drawing color. - */ - void clear(); - - /** - * Render the content of the window to the screen. - */ - void present(); - - /** - * Close the window. - */ - void close() noexcept; - - /** - * Get the current drawing color. - * - * \return the color - */ - color drawing_color() const; - - /** - * Set the drawing color. - * - * \param color the color - */ - void set_drawing_color(const color& color); - - /** - * Draw a line. - * - * \param line the line - */ - void draw_line(const line& line); - - /** - * Draw a several lines. - * - * \param the lines vertices - */ - void draw_lines(const std::vector<point>& points); - - /** - * Draw a point. - * - * \param point the point - */ - void draw_point(const point& point); - - /** - * Draw a list of points. - * - * \param points the points - */ - void draw_points(const std::vector<point>& points); - - /** - * Draw a rectangle (only borders). - * - * \param rect the rectangle - * \see fillRectangle - */ - void draw_rectangle(const rectangle& rect); - - /** - * Draw a list of rectangles. - * - * \param rects the rectangles - * \see fillRectangles - */ - void draw_rectangles(const std::vector<rectangle>& rects); - - /** - * Draw internal GUI frames. - */ - void draw_frames(); - - /** - * Fill the given rectangle with the current color. - * - * \param rect the rectangle - * \see drawRectangle - */ - void fill_rectangle(const rectangle& rect); - - /** - * Fill the list of rectangles with the current color. - * - * \param rects the list of rectangles - * \see drawRectangles - */ - void fill_rectangles(const std::vector<rectangle>& rects); - - /** - * Draw some text. - * - * This function may stretch the text texture. - * - * \param text the text (UTF-8) - * \param font the font - * \param rectangle the rectangle target - */ - void draw_text(const std::string& text, font& font, const rectangle& rectangle); - - /** - * Overloaded function. - * - * Draw the text at the given position. - * - * \param text the text (UTF-8) - * \param font the font - * \param point the text position - */ - void draw_text(const std::string& text, font& font, const point& point); - - /** - * Poll all pending events and call appropriate functions. - */ - void poll(); - - /** - * Key down event. - * - * \param ev the event - */ - virtual void handle_key_down(const key_event& ev); - - /** - * Key released event. - * - * \param ev the event - */ - virtual void handle_key_up(const key_event& ev); - - /** - * Mouse click event. - * - * \param ev the event - */ - virtual void handle_mouse_down(const mouse_click_event& ev); - - /** - * Mouse click release event. - * - * \param ev the event - */ - virtual void handle_mouse_up(const mouse_click_event& ev); - - /** - * Mouse wheel event. - * - * \param ev the event - */ - virtual void handle_mouse_wheel(const mouse_wheel_event& ev); - - /** - * Quit request. - */ - virtual void handle_quit(); - - /** - * Move assigment operator defaulted. - * - * \return this - */ - window& operator=(window&&) noexcept; -}; - -} // !mlk - -#endif // !MALIKANIA_WINDOW_HPP
--- a/tests/libclient/color/main.cpp Sun Jan 22 10:11:17 2017 +0100 +++ b/tests/libclient/color/main.cpp Sun Jan 22 11:07:36 2017 +0100 @@ -1,5 +1,5 @@ /* - * main.cpp -- test mlk::color + * main.cpp -- test mlk::client::color * * Copyright (c) 2013-2017 Malikania Authors * @@ -19,7 +19,7 @@ #define BOOST_TEST_MODULE "Color" #include <boost/test/unit_test.hpp> -#include <malikania/color.hpp> +#include <malikania/client/color.hpp> /* * Separate arguments. @@ -30,7 +30,7 @@ BOOST_AUTO_TEST_CASE(black) { - mlk::color c; + mlk::client::color c; BOOST_REQUIRE_EQUAL(0, c.red()); BOOST_REQUIRE_EQUAL(0, c.green()); @@ -40,7 +40,7 @@ BOOST_AUTO_TEST_CASE(white) { - mlk::color c{255, 255, 255, 255}; + mlk::client::color c{255, 255, 255, 255}; BOOST_REQUIRE_EQUAL(255, c.red()); BOOST_REQUIRE_EQUAL(255, c.green()); @@ -50,7 +50,7 @@ BOOST_AUTO_TEST_CASE(red) { - mlk::color c{255, 0, 0, 255}; + mlk::client::color c{255, 0, 0, 255}; BOOST_REQUIRE_EQUAL(255, c.red()); BOOST_REQUIRE_EQUAL(0, c.green()); @@ -60,7 +60,7 @@ BOOST_AUTO_TEST_CASE(green) { - mlk::color c{0, 255, 0, 255}; + mlk::client::color c{0, 255, 0, 255}; BOOST_REQUIRE_EQUAL(0, c.red()); BOOST_REQUIRE_EQUAL(255, c.green()); @@ -70,7 +70,7 @@ BOOST_AUTO_TEST_CASE(blue) { - mlk::color c{0, 0, 255, 255}; + mlk::client::color c{0, 0, 255, 255}; BOOST_REQUIRE_EQUAL(0, c.red()); BOOST_REQUIRE_EQUAL(0, c.green()); @@ -89,7 +89,7 @@ BOOST_AUTO_TEST_CASE(black) { - mlk::color c{0xff000000}; + mlk::client::color c{0xff000000}; BOOST_REQUIRE_EQUAL(0, c.red()); BOOST_REQUIRE_EQUAL(0, c.green()); @@ -99,7 +99,7 @@ BOOST_AUTO_TEST_CASE(white) { - mlk::color c{0xffffffff}; + mlk::client::color c{0xffffffff}; BOOST_REQUIRE_EQUAL(255, c.red()); BOOST_REQUIRE_EQUAL(255, c.green()); @@ -109,7 +109,7 @@ BOOST_AUTO_TEST_CASE(red) { - mlk::color c{0xffff0000}; + mlk::client::color c{0xffff0000}; BOOST_REQUIRE_EQUAL(255, c.red()); BOOST_REQUIRE_EQUAL(0, c.green()); @@ -119,7 +119,7 @@ BOOST_AUTO_TEST_CASE(green) { - mlk::color c{0xff00ff00}; + mlk::client::color c{0xff00ff00}; BOOST_REQUIRE_EQUAL(0, c.red()); BOOST_REQUIRE_EQUAL(255, c.green()); @@ -129,7 +129,7 @@ BOOST_AUTO_TEST_CASE(blue) { - mlk::color c{0xff0000ff}; + mlk::client::color c{0xff0000ff}; BOOST_REQUIRE_EQUAL(0, c.red()); BOOST_REQUIRE_EQUAL(0, c.green()); @@ -150,7 +150,7 @@ BOOST_AUTO_TEST_CASE(black) { - mlk::color c{"black"}; + mlk::client::color c{"black"}; BOOST_REQUIRE_EQUAL(0, c.red()); BOOST_REQUIRE_EQUAL(0, c.green()); @@ -160,7 +160,7 @@ BOOST_AUTO_TEST_CASE(white) { - mlk::color c{"white"}; + mlk::client::color c{"white"}; BOOST_REQUIRE_EQUAL(255, c.red()); BOOST_REQUIRE_EQUAL(255, c.green()); @@ -170,7 +170,7 @@ BOOST_AUTO_TEST_CASE(red) { - mlk::color c{"red"}; + mlk::client::color c{"red"}; BOOST_REQUIRE_EQUAL(255, c.red()); BOOST_REQUIRE_EQUAL(0, c.green()); @@ -180,7 +180,7 @@ BOOST_AUTO_TEST_CASE(green) { - mlk::color c{"green"}; + mlk::client::color c{"green"}; BOOST_REQUIRE_EQUAL(0, c.red()); BOOST_REQUIRE_EQUAL(128, c.green()); @@ -190,7 +190,7 @@ BOOST_AUTO_TEST_CASE(blue) { - mlk::color c{"blue"}; + mlk::client::color c{"blue"}; BOOST_REQUIRE_EQUAL(0, c.red()); BOOST_REQUIRE_EQUAL(0, c.green()); @@ -200,7 +200,7 @@ BOOST_AUTO_TEST_CASE(wrong) { - BOOST_REQUIRE_THROW(mlk::color c{"does not exist"}, std::exception); + BOOST_REQUIRE_THROW(mlk::client::color c{"does not exist"}, std::exception); } BOOST_AUTO_TEST_SUITE_END() @@ -216,7 +216,7 @@ BOOST_AUTO_TEST_CASE(black) { - mlk::color c{"#000000"}; + mlk::client::color c{"#000000"}; BOOST_REQUIRE_EQUAL(0, c.red()); BOOST_REQUIRE_EQUAL(0, c.green()); @@ -226,7 +226,7 @@ BOOST_AUTO_TEST_CASE(white) { - mlk::color c{"#ffffff"}; + mlk::client::color c{"#ffffff"}; BOOST_REQUIRE_EQUAL(255, c.red()); BOOST_REQUIRE_EQUAL(255, c.green()); @@ -236,7 +236,7 @@ BOOST_AUTO_TEST_CASE(red) { - mlk::color c{"#ff0000"}; + mlk::client::color c{"#ff0000"}; BOOST_REQUIRE_EQUAL(255, c.red()); BOOST_REQUIRE_EQUAL(0, c.green()); @@ -246,7 +246,7 @@ BOOST_AUTO_TEST_CASE(green) { - mlk::color c{"#00ff00"}; + mlk::client::color c{"#00ff00"}; BOOST_REQUIRE_EQUAL(0, c.red()); BOOST_REQUIRE_EQUAL(255, c.green()); @@ -256,7 +256,7 @@ BOOST_AUTO_TEST_CASE(blue) { - mlk::color c{"#0000ff"}; + mlk::client::color c{"#0000ff"}; BOOST_REQUIRE_EQUAL(0, c.red()); BOOST_REQUIRE_EQUAL(0, c.green()); @@ -266,7 +266,7 @@ BOOST_AUTO_TEST_CASE(wrong) { - BOOST_REQUIRE_THROW(mlk::color c{"#ghijkl"}, std::exception); + BOOST_REQUIRE_THROW(mlk::client::color c{"#ghijkl"}, std::exception); } BOOST_AUTO_TEST_SUITE_END() @@ -282,7 +282,7 @@ BOOST_AUTO_TEST_CASE(black) { - mlk::color c{"#000"}; + mlk::client::color c{"#000"}; BOOST_REQUIRE_EQUAL(0, c.red()); BOOST_REQUIRE_EQUAL(0, c.green()); @@ -292,7 +292,7 @@ BOOST_AUTO_TEST_CASE(white) { - mlk::color c{"#fff"}; + mlk::client::color c{"#fff"}; BOOST_REQUIRE_EQUAL(255, c.red()); BOOST_REQUIRE_EQUAL(255, c.green()); @@ -302,7 +302,7 @@ BOOST_AUTO_TEST_CASE(red) { - mlk::color c{"#f00"}; + mlk::client::color c{"#f00"}; BOOST_REQUIRE_EQUAL(255, c.red()); BOOST_REQUIRE_EQUAL(0, c.green()); @@ -312,7 +312,7 @@ BOOST_AUTO_TEST_CASE(green) { - mlk::color c{"#0f0"}; + mlk::client::color c{"#0f0"}; BOOST_REQUIRE_EQUAL(0, c.red()); BOOST_REQUIRE_EQUAL(255, c.green()); @@ -322,7 +322,7 @@ BOOST_AUTO_TEST_CASE(blue) { - mlk::color c{"#00f"}; + mlk::client::color c{"#00f"}; BOOST_REQUIRE_EQUAL(0, c.red()); BOOST_REQUIRE_EQUAL(0, c.green()); @@ -332,7 +332,7 @@ BOOST_AUTO_TEST_CASE(combination) { - mlk::color c{"#123"}; + mlk::client::color c{"#123"}; BOOST_REQUIRE_EQUAL(17, c.red()); BOOST_REQUIRE_EQUAL(34, c.green()); @@ -342,7 +342,7 @@ BOOST_AUTO_TEST_CASE(wrong) { - BOOST_REQUIRE_THROW(mlk::color c{"#ghi"}, std::exception); + BOOST_REQUIRE_THROW(mlk::client::color c{"#ghi"}, std::exception); } BOOST_AUTO_TEST_SUITE_END()
--- a/tests/libclient/line/main.cpp Sun Jan 22 10:11:17 2017 +0100 +++ b/tests/libclient/line/main.cpp Sun Jan 22 11:07:36 2017 +0100 @@ -1,5 +1,5 @@ /* - * main.cpp -- test mlk::line + * main.cpp -- test mlk::client::line * * Copyright (c) 2013-2017 Malikania Authors * @@ -19,10 +19,12 @@ #define BOOST_TEST_MODULE "Line" #include <boost/test/unit_test.hpp> -#include <malikania/line.hpp> +#include <malikania/client/line.hpp> namespace mlk { +namespace client { + std::ostream& operator<<(std::ostream& out, const line& line) { out << "{"; @@ -33,11 +35,13 @@ return out; } +} // !client + } // !mlk BOOST_AUTO_TEST_CASE(none) { - mlk::line line; + mlk::client::line line; BOOST_REQUIRE_EQUAL(0, line.x1()); BOOST_REQUIRE_EQUAL(0, line.y1()); @@ -47,7 +51,7 @@ BOOST_AUTO_TEST_CASE(standard) { - mlk::line line(10, 20, 30, 40); + mlk::client::line line(10, 20, 30, 40); BOOST_REQUIRE_EQUAL(10, line.x1()); BOOST_REQUIRE_EQUAL(20, line.y1()); @@ -57,23 +61,23 @@ BOOST_AUTO_TEST_CASE(operator_eq) { - mlk::line line1, line2; + mlk::client::line line1, line2; BOOST_REQUIRE_EQUAL(line1, line2); } BOOST_AUTO_TEST_CASE(operator_eq1) { - mlk::line line1(10, 20, 30, 40); - mlk::line line2(10, 20, 30, 40); + mlk::client::line line1(10, 20, 30, 40); + mlk::client::line line2(10, 20, 30, 40); BOOST_REQUIRE_EQUAL(line1, line2); } BOOST_AUTO_TEST_CASE(operator_neq) { - BOOST_REQUIRE_NE(mlk::line(10), mlk::line(20)); - BOOST_REQUIRE_NE(mlk::line(10, 10), mlk::line(10, 20)); - BOOST_REQUIRE_NE(mlk::line(10, 10, 10), mlk::line(10, 10, 20)); - BOOST_REQUIRE_NE(mlk::line(10, 10, 10, 10), mlk::line(10, 10, 10, 20)); + BOOST_REQUIRE_NE(mlk::client::line(10), mlk::client::line(20)); + BOOST_REQUIRE_NE(mlk::client::line(10, 10), mlk::client::line(10, 20)); + BOOST_REQUIRE_NE(mlk::client::line(10, 10, 10), mlk::client::line(10, 10, 20)); + BOOST_REQUIRE_NE(mlk::client::line(10, 10, 10, 10), mlk::client::line(10, 10, 10, 20)); }
--- a/tests/libclient/point/main.cpp Sun Jan 22 10:11:17 2017 +0100 +++ b/tests/libclient/point/main.cpp Sun Jan 22 11:07:36 2017 +0100 @@ -1,5 +1,5 @@ /* - * main.cpp -- test mlk::point + * main.cpp -- test mlk::client::point * * Copyright (c) 2013-2017 Malikania Authors * @@ -19,10 +19,12 @@ #define BOOST_TEST_MODULE "Point" #include <boost/test/unit_test.hpp> -#include <malikania/point.hpp> +#include <malikania/client/point.hpp> namespace mlk { +namespace client { + std::ostream& operator<<(std::ostream& out, const point& point) { out << "{" << point.x() << ", " << point.y() << "}"; @@ -30,11 +32,13 @@ return out; } +} // !client + } // !mlk BOOST_AUTO_TEST_CASE(none) { - mlk::point point; + mlk::client::point point; BOOST_REQUIRE_EQUAL(0, point.x()); BOOST_REQUIRE_EQUAL(0, point.y()); @@ -42,7 +46,7 @@ BOOST_AUTO_TEST_CASE(standard) { - mlk::point point(10, 20); + mlk::client::point point(10, 20); BOOST_REQUIRE_EQUAL(10, point.x()); BOOST_REQUIRE_EQUAL(20, point.y()); @@ -50,21 +54,21 @@ BOOST_AUTO_TEST_CASE(operator_eq) { - mlk::point point1, point2; + mlk::client::point point1, point2; BOOST_REQUIRE_EQUAL(point1, point2); } BOOST_AUTO_TEST_CASE(operator_eq1) { - mlk::point point1(10, 20); - mlk::point point2(10, 20); + mlk::client::point point1(10, 20); + mlk::client::point point2(10, 20); BOOST_REQUIRE_EQUAL(point1, point2); } BOOST_AUTO_TEST_CASE(operator_neq) { - BOOST_REQUIRE_NE(mlk::point(10), mlk::point(20)); - BOOST_REQUIRE_NE(mlk::point(10, 10), mlk::point(10, 20)); + BOOST_REQUIRE_NE(mlk::client::point(10), mlk::client::point(20)); + BOOST_REQUIRE_NE(mlk::client::point(10, 10), mlk::client::point(10, 20)); }
--- a/tests/libclient/rectangle/main.cpp Sun Jan 22 10:11:17 2017 +0100 +++ b/tests/libclient/rectangle/main.cpp Sun Jan 22 11:07:36 2017 +0100 @@ -1,5 +1,5 @@ /* - * main.cpp -- test mlk::rectangle + * main.cpp -- test mlk::client::rectangle * * Copyright (c) 2013-2017 Malikania Authors * @@ -19,10 +19,12 @@ #define BOOST_TEST_MODULE "Rectangle" #include <boost/test/unit_test.hpp> -#include <malikania/rectangle.hpp> +#include <malikania/client/rectangle.hpp> namespace mlk { +namespace client { + std::ostream& operator<<(std::ostream& out, const rectangle& rectangle) { out << "{"; @@ -33,11 +35,13 @@ return out; } +} // !client + } // !mlk BOOST_AUTO_TEST_CASE(none) { - mlk::rectangle rectangle; + mlk::client::rectangle rectangle; BOOST_REQUIRE_EQUAL(0, rectangle.x()); BOOST_REQUIRE_EQUAL(0, rectangle.y()); @@ -47,15 +51,15 @@ BOOST_AUTO_TEST_CASE(null) { - BOOST_REQUIRE(mlk::rectangle().is_null()); - BOOST_REQUIRE(!mlk::rectangle(0, 0, 10, 0).is_null()); - BOOST_REQUIRE(!mlk::rectangle(0, 0, 0, 10).is_null()); - BOOST_REQUIRE(!mlk::rectangle(0, 0, 10, 10).is_null()); + BOOST_REQUIRE(mlk::client::rectangle().is_null()); + BOOST_REQUIRE(!mlk::client::rectangle(0, 0, 10, 0).is_null()); + BOOST_REQUIRE(!mlk::client::rectangle(0, 0, 0, 10).is_null()); + BOOST_REQUIRE(!mlk::client::rectangle(0, 0, 10, 10).is_null()); } BOOST_AUTO_TEST_CASE(standard) { - mlk::rectangle rectangle(10, 20, 30, 40); + mlk::client::rectangle rectangle(10, 20, 30, 40); BOOST_REQUIRE_EQUAL(10, rectangle.x()); BOOST_REQUIRE_EQUAL(20, rectangle.y()); @@ -65,23 +69,23 @@ BOOST_AUTO_TEST_CASE(operator_eq) { - mlk::rectangle rectangle1, rectangle2; + mlk::client::rectangle rectangle1, rectangle2; BOOST_REQUIRE_EQUAL(rectangle1, rectangle2); } BOOST_AUTO_TEST_CASE(operator_eq1) { - mlk::rectangle rectangle1(10, 20, 30, 40); - mlk::rectangle rectangle2(10, 20, 30, 40); + mlk::client::rectangle rectangle1(10, 20, 30, 40); + mlk::client::rectangle rectangle2(10, 20, 30, 40); BOOST_REQUIRE_EQUAL(rectangle1, rectangle2); } BOOST_AUTO_TEST_CASE(operator_neq) { - BOOST_REQUIRE_NE(mlk::rectangle(10), mlk::rectangle(20)); - BOOST_REQUIRE_NE(mlk::rectangle(10, 10), mlk::rectangle(10, 20)); - BOOST_REQUIRE_NE(mlk::rectangle(10, 10, 10), mlk::rectangle(10, 10, 20)); - BOOST_REQUIRE_NE(mlk::rectangle(10, 10, 10, 10), mlk::rectangle(10, 10, 10, 20)); + BOOST_REQUIRE_NE(mlk::client::rectangle(10), mlk::client::rectangle(20)); + BOOST_REQUIRE_NE(mlk::client::rectangle(10, 10), mlk::client::rectangle(10, 20)); + BOOST_REQUIRE_NE(mlk::client::rectangle(10, 10, 10), mlk::client::rectangle(10, 10, 20)); + BOOST_REQUIRE_NE(mlk::client::rectangle(10, 10, 10, 10), mlk::client::rectangle(10, 10, 10, 20)); }
--- a/tests/libclient/size/main.cpp Sun Jan 22 10:11:17 2017 +0100 +++ b/tests/libclient/size/main.cpp Sun Jan 22 11:07:36 2017 +0100 @@ -1,5 +1,5 @@ /* - * main.cpp -- test mlk::size + * main.cpp -- test mlk::client::size * * Copyright (c) 2013-2017 Malikania Authors * @@ -19,10 +19,12 @@ #define BOOST_TEST_MODULE "Size" #include <boost/test/unit_test.hpp> -#include <malikania/size.hpp> +#include <malikania/client/size.hpp> namespace mlk { +namespace client { + std::ostream& operator<<(std::ostream& out, const size& size) { out << "{" << size.width() << ", " << size.height() << "}"; @@ -30,11 +32,13 @@ return out; } +} // !client + } // !mlk BOOST_AUTO_TEST_CASE(none) { - mlk::size size; + mlk::client::size size; BOOST_REQUIRE_EQUAL(0U, size.width()); BOOST_REQUIRE_EQUAL(0U, size.height()); @@ -42,14 +46,14 @@ BOOST_AUTO_TEST_CASE(null) { - BOOST_REQUIRE(mlk::size().is_null()); - BOOST_REQUIRE(!mlk::size(0, 10).is_null()); - BOOST_REQUIRE(!mlk::size(10, 0).is_null()); + BOOST_REQUIRE(mlk::client::size().is_null()); + BOOST_REQUIRE(!mlk::client::size(0, 10).is_null()); + BOOST_REQUIRE(!mlk::client::size(10, 0).is_null()); } BOOST_AUTO_TEST_CASE(standard) { - mlk::size size(10, 20); + mlk::client::size size(10, 20); BOOST_REQUIRE_EQUAL(10U, size.width()); BOOST_REQUIRE_EQUAL(20U, size.height()); @@ -57,21 +61,21 @@ BOOST_AUTO_TEST_CASE(operator_eq) { - mlk::size size1, size2; + mlk::client::size size1, size2; BOOST_REQUIRE_EQUAL(size1, size2); } BOOST_AUTO_TEST_CASE(operator_eq_1) { - mlk::size size1(10, 20); - mlk::size size2(10, 20); + mlk::client::size size1(10, 20); + mlk::client::size size2(10, 20); BOOST_REQUIRE_EQUAL(size1, size2); } BOOST_AUTO_TEST_CASE(operator_neq) { - BOOST_REQUIRE_NE(mlk::size(10), mlk::size(20)); - BOOST_REQUIRE_NE(mlk::size(10, 10), mlk::size(10, 20)); + BOOST_REQUIRE_NE(mlk::client::size(10), mlk::client::size(20)); + BOOST_REQUIRE_NE(mlk::client::size(10, 10), mlk::client::size(10, 20)); }