changeset 18:cc13926bed59

Client: add more bindings for Window, #462
author David Demelier <markand@malikania.fr>
date Sun, 03 Apr 2016 20:10:37 +0200
parents 63ba461b7f84
children 6400830bb36b
files libclient/malikania/backend/sdl/window-backend.cpp libclient/malikania/backend/sdl/window-backend.h libclient/malikania/js-window.cpp libclient/malikania/window.cpp libclient/malikania/window.h tests/libclient/font/main.cpp tests/libclient/js-window/main.cpp
diffstat 7 files changed, 434 insertions(+), 194 deletions(-) [+]
line wrap: on
line diff
--- a/libclient/malikania/backend/sdl/window-backend.cpp	Sun Apr 03 14:50:03 2016 +0200
+++ b/libclient/malikania/backend/sdl/window-backend.cpp	Sun Apr 03 20:10:37 2016 +0200
@@ -21,12 +21,17 @@
 
 #include <stdexcept>
 
+#include <malikania/color.h>
+#include <malikania/line.h>
+#include <malikania/point.h>
+#include <malikania/rectangle.h>
+
 #include "font-backend.h"
 #include "window-backend.h"
 
 namespace malikania {
 
-Window::Backend::Backend(Window &, unsigned width, unsigned height)
+Window::Backend::Backend(Window &, unsigned width, unsigned height, const std::string &title)
 	: m_window(nullptr, nullptr)
 	, m_renderer(nullptr, nullptr)
 {
@@ -34,7 +39,7 @@
 	SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO);
 
 	m_window = WindowHandle(
-		SDL_CreateWindow("Malikania", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, SDL_WINDOW_OPENGL),
+		SDL_CreateWindow(title.c_str(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, SDL_WINDOW_OPENGL),
 		SDL_DestroyWindow
 	);
 
@@ -57,6 +62,10 @@
 	}
 }
 
+#if 0
+
+// TODO: later */
+
 void Window::Backend::processEvents(Window &window)
 {
 	SDL_Event event;
@@ -79,26 +88,22 @@
 	}
 }
 
+#endif
+
 void Window::Backend::clear()
 {
 	SDL_RenderClear(m_renderer.get());
 }
 
-void Window::Backend::update()
-{
-	// TO AUDIT
-#if 0
-	for (Refresh function : m_refreshList) {
-		function();
-	}
-#endif
-}
-
 void Window::Backend::present()
 {
 	SDL_RenderPresent(m_renderer.get());
 }
 
+#if 0
+
+// TODO: see later if it's really needed
+
 Size Window::Backend::resolution()
 {
 	SDL_DisplayMode current;
@@ -119,11 +124,23 @@
 	return Size((unsigned)width, (unsigned)height);
 }
 
+#endif
+
+Color Window::Backend::drawingColor() 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(color.r, color.g, color.b, color.a);
+}
+
 void Window::Backend::setDrawingColor(const Color &color)
 {
-	int error = SDL_SetRenderDrawColor(m_renderer.get(), color.red(), color.green(), color.blue(), color.alpha());
-	if (error != 0) {
-		throw std::runtime_error("Couldn't set drawing color" + std::string(SDL_GetError()));
+	if (SDL_SetRenderDrawColor(m_renderer.get(), color.red(), color.green(), color.blue(), color.alpha()) < 0) {
+		throw std::runtime_error(SDL_GetError());
 	}
 }
 
@@ -142,7 +159,7 @@
 		sdlPoints[i] = SDL_Point{points[i].x(), points[i].y()};
 	}
 
-	if (SDL_RenderDrawLines(m_renderer.get(), sdlPoints.data(), sdlPoints.size()) != 0) {
+	if (SDL_RenderDrawLines(m_renderer.get(), sdlPoints.data(), sdlPoints.size()) < 0) {
 		throw std::runtime_error(SDL_GetError());
 	}
 }
@@ -167,25 +184,16 @@
 	}
 }
 
-// TODO: not sure to keep this signature (add fillRect probably)
-void Window::Backend::drawRectangle(const Rectangle &rectangle, bool filled, const malikania::Color &fillColor)
+void Window::Backend::drawRectangle(const Rectangle &rectangle)
 {
 	SDL_Rect rect{rectangle.x(), rectangle.y(), (int)rectangle.width(), (int)rectangle.height()};
-	int error = SDL_RenderDrawRect(m_renderer.get(), &rect);
-	if (error != 0) {
+
+	if (SDL_RenderDrawRect(m_renderer.get(), &rect) < 0) {
 		throw std::runtime_error(SDL_GetError());
 	}
-	if (filled) {
-		this->setDrawingColor(fillColor);
-		error = SDL_RenderFillRect(m_renderer.get(), &rect);
-		if (error != 0) {
-			throw std::runtime_error(SDL_GetError());
-		}
-	}
 }
 
-// TODO: same as above
-void Window::Backend::drawRectangles(const std::vector<Rectangle> &rectangles, bool filled, std::vector<Color> fillColors)
+void Window::Backend::drawRectangles(const std::vector<Rectangle> &rectangles)
 {
 	std::vector<SDL_Rect> sdlRects(rectangles.size());
 
@@ -196,45 +204,51 @@
 	if (SDL_RenderDrawRects(m_renderer.get(), sdlRects.data(), sdlRects.size()) != 0) {
 		throw std::runtime_error(SDL_GetError());
 	}
-
-	if (filled) {
-		if (rectangles.size() != fillColors.size()) {
-			throw std::runtime_error("Couldn't fill rectangles, rectangles size and fillColors size are not the same");
-		}
+}
 
-		int j = 0;
-		for (Color fillColor : fillColors) {
-			this->setDrawingColor(fillColor);
+void Window::Backend::fillRectangle(const Rectangle &rectangle)
+{
+	SDL_Rect rect{rectangle.x(), rectangle.y(), (int)rectangle.width(), (int)rectangle.height()};
 
-			if (SDL_RenderFillRect(m_renderer.get(), &sdlRects[j++]) != 0) {
-				throw std::runtime_error("Couldn't fill rectangle" + std::string(SDL_GetError()));
-			}
-		}
+	if (SDL_RenderFillRect(m_renderer.get(), &rect) < 0) {
+		throw std::runtime_error(SDL_GetError());
 	}
 }
 
-// TODO: merge this into only one function and test results.
+void Window::Backend::fillRectangles(const std::vector<Rectangle> &rectangles)
+{
+	std::vector<SDL_Rect> sdlRects(rectangles.size());
+
+	for (unsigned i = 0; i < rectangles.size(); ++i) {
+		sdlRects[i] = SDL_Rect{rectangles[i].x(), rectangles[i].y(), (int)rectangles[i].width(), (int)rectangles[i].height()};
+	}
+
+	if (SDL_RenderFillRects(m_renderer.get(), sdlRects.data(), sdlRects.size()) != 0) {
+		throw std::runtime_error(SDL_GetError());
+	}
+}
+
 void Window::Backend::drawText(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_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::drawText(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* textTexture = SDL_CreateTextureFromSurface(m_renderer.get(), message);
+	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(), textTexture, nullptr, &rect);
+	SDL_RenderCopy(m_renderer.get(), texture, nullptr, &rect);
 	SDL_FreeSurface(message);
+	SDL_DestroyTexture(texture);
 }
 
 void Window::Backend::close()
--- a/libclient/malikania/backend/sdl/window-backend.h	Sun Apr 03 14:50:03 2016 +0200
+++ b/libclient/malikania/backend/sdl/window-backend.h	Sun Apr 03 20:10:37 2016 +0200
@@ -24,18 +24,10 @@
 
 #include <SDL.h>
 
-#include <malikania/color.h>
-#include <malikania/font.h>
-#include <malikania/line.h>
-#include <malikania/point.h>
-#include <malikania/rectangle.h>
-#include <malikania/size.h>
 #include <malikania/window.h>
 
 namespace malikania {
 
-class Window;
-
 class Window::Backend {
 private:
 	using WindowHandle = std::unique_ptr<SDL_Window, void (*)(SDL_Window *)>;
@@ -45,30 +37,42 @@
 	RendererHandle m_renderer;
 
 public:
-	Backend(Window &self, unsigned width, unsigned height);
-
-	void close();
-	void processEvents(Window &window);
-	void clear();
-	void update();
-	void present();
-	Size resolution();
-
-	// Drawing functions
-	void setDrawingColor(const Color &color);
-	void drawLine(const Line &line);
-	void drawLines(const std::vector<Point> &points);
-	void drawPoint(const Point &point);
-	void drawPoints(const std::vector<Point> &points);
-	void drawRectangle(const Rectangle &rectangle, bool filled, const Color &fillColor);
-	void drawRectangles(const std::vector<Rectangle> &rectangles, bool filled, std::vector<Color> fillColors);
-	void drawText(const std::string &text, Font &font, const Rectangle &rectangle);
-	void drawText(const std::string &text, Font &font, const Point &point);
+	Backend(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 drawingColor() const;
+
+	void setDrawingColor(const Color &color);
+
+	void drawLine(const Line &line);
+
+	void drawLines(const std::vector<Point> &points);
+
+	void drawPoint(const Point &point);
+
+	void drawPoints(const std::vector<Point> &points);
+
+	void drawRectangle(const Rectangle &rect);
+
+	void drawRectangles(const std::vector<Rectangle> &rects);
+
+	void fillRectangle(const Rectangle &rect);
+
+	void fillRectangles(const std::vector<Rectangle> &rects);
+
+	void drawText(const std::string &text, Font &font, const Rectangle &rectangle);
+
+	void drawText(const std::string &text, Font &font, const Point &point);
 };
 
 } // !malikania
--- a/libclient/malikania/js-window.cpp	Sun Apr 03 14:50:03 2016 +0200
+++ b/libclient/malikania/js-window.cpp	Sun Apr 03 20:10:37 2016 +0200
@@ -17,6 +17,9 @@
  */
 
 #include "js-color.h"
+#include "js-line.h"
+#include "js-point.h"
+#include "js-rectangle.h"
 #include "js-window.h"
 
 namespace malikania {
@@ -31,6 +34,7 @@
 		duk::raise(ctx, DUK_ERR_ERROR, "window must be new-constructed");
 	}
 
+	/* TODO: add parameters */
 	try {
 		duk::construct(ctx, duk::Pointer<Window>{new Window()});
 	} catch (const std::exception &ex) {
@@ -62,6 +66,105 @@
 	return 0;
 }
 
+duk::Ret drawingColor(duk::ContextPtr ctx)
+{
+	try {
+		duk::push(ctx, duk::self<duk::Pointer<Window>>(ctx)->drawingColor());
+	} catch (const std::exception &ex) {
+		duk::raise(ctx, DUK_ERR_ERROR, "%s", ex.what());
+	}
+
+	return 1;
+}
+
+duk::Ret drawLine(duk::ContextPtr ctx)
+{
+	try {
+		duk::self<duk::Pointer<Window>>(ctx)->drawLine(duk::require<Line>(ctx, 0));
+	} catch (const std::exception &ex) {
+		duk::raise(ctx, DUK_ERR_ERROR, "%s", ex.what());
+	}
+
+	return 0;
+}
+
+duk::Ret drawLines(duk::ContextPtr ctx)
+{
+	try {
+		duk::self<duk::Pointer<Window>>(ctx)->drawLines(duk::get<std::vector<Point>>(ctx, 0));
+	} catch (const std::exception &ex) {
+		duk::raise(ctx, DUK_ERR_ERROR, "%s", ex.what());
+	}
+
+	return 0;
+}
+
+duk::Ret drawPoint(duk::ContextPtr ctx)
+{
+	try {
+		duk::self<duk::Pointer<Window>>(ctx)->drawPoint(duk::require<Point>(ctx, 0));
+	} catch (const std::exception &ex) {
+		duk::raise(ctx, DUK_ERR_ERROR, "%s", ex.what());
+	}
+
+	return 0;
+}
+
+duk::Ret drawPoints(duk::ContextPtr ctx)
+{
+	try {
+		duk::self<duk::Pointer<Window>>(ctx)->drawPoints(duk::get<std::vector<Point>>(ctx, 0));
+	} catch (const std::exception &ex) {
+		duk::raise(ctx, DUK_ERR_ERROR, "%s", ex.what());
+	}
+
+	return 0;
+}
+
+duk::Ret drawRectangle(duk::ContextPtr ctx)
+{
+	try {
+		duk::self<duk::Pointer<Window>>(ctx)->drawRectangle(duk::require<Rectangle>(ctx, 0));
+	} catch (const std::exception &ex) {
+		duk::raise(ctx, DUK_ERR_ERROR, "%s", ex.what());
+	}
+
+	return 0;
+}
+
+duk::Ret drawRectangles(duk::ContextPtr ctx)
+{
+	try {
+		duk::self<duk::Pointer<Window>>(ctx)->drawRectangles(duk::get<std::vector<Rectangle>>(ctx, 0));
+	} catch (const std::exception &ex) {
+		duk::raise(ctx, DUK_ERR_ERROR, "%s", ex.what());
+	}
+
+	return 0;
+}
+
+duk::Ret fillRectangle(duk::ContextPtr ctx)
+{
+	try {
+		duk::self<duk::Pointer<Window>>(ctx)->fillRectangle(duk::require<Rectangle>(ctx, 0));
+	} catch (const std::exception &ex) {
+		duk::raise(ctx, DUK_ERR_ERROR, "%s", ex.what());
+	}
+
+	return 0;
+}
+
+duk::Ret fillRectangles(duk::ContextPtr ctx)
+{
+	try {
+		duk::self<duk::Pointer<Window>>(ctx)->fillRectangles(duk::get<std::vector<Rectangle>>(ctx, 0));
+	} catch (const std::exception &ex) {
+		duk::raise(ctx, DUK_ERR_ERROR, "%s", ex.what());
+	}
+
+	return 0;
+}
+
 duk::Ret setDrawingColor(duk::ContextPtr ctx)
 {
 	try {
@@ -75,6 +178,15 @@
 
 const duk::FunctionMap methods{
 	{ "clear",		{ clear,		0 } },
+	{ "drawingColor",	{ drawingColor,		0 } },
+	{ "drawLine",		{ drawLine,		1 } },
+	{ "drawLines",		{ drawLines,		1 } },
+	{ "drawPoint",		{ drawPoint,		1 } },
+	{ "drawPoints",		{ drawPoints,		1 } },
+	{ "drawRectangle",	{ drawRectangle,	1 } },
+	{ "drawRectangles",	{ drawRectangles,	1 } },
+	{ "fillRectangle",	{ fillRectangle,	1 } },
+	{ "fillRectangles",	{ fillRectangles,	1 } },
 	{ "present",		{ present,		0 } },
 	{ "setDrawingColor",	{ setDrawingColor,	1 } }
 };
--- a/libclient/malikania/window.cpp	Sun Apr 03 14:50:03 2016 +0200
+++ b/libclient/malikania/window.cpp	Sun Apr 03 20:10:37 2016 +0200
@@ -1,11 +1,30 @@
+/*
+ * window.cpp -- main window and basic drawing
+ *
+ * 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 <stdexcept>
 
+#include "color.h"
 #include "window-backend.h"
 
 namespace malikania {
 
-Window::Window(unsigned width, unsigned height)
-	: m_backend(std::make_unique<Backend>(*this, width, height))
+Window::Window(unsigned width, unsigned height, const std::string &title)
+	: m_backend(std::make_unique<Backend>(*this, width, height, title))
 {
 }
 
@@ -13,26 +32,11 @@
 
 Window::~Window() noexcept = default;
 
-Size Window::getWindowResolution()
-{
-	return m_backend->resolution();
-}
-
-void Window::processEvent()
-{
-	m_backend->processEvents(*this);
-}
-
 void Window::clear()
 {
 	m_backend->clear();
 }
 
-void Window::update()
-{
-	m_backend->update();
-}
-
 void Window::present()
 {
 	m_backend->present();
@@ -44,29 +48,13 @@
 	m_backend->close();
 }
 
-void Window::setOnKeyUp(KeyUp function)
+Color Window::drawingColor() const
 {
-	m_keyUpList.push_back(std::move(function));
-}
-
-void Window::setOnKeyDown(KeyDown function)
-{
-	m_keyDownList.push_back(std::move(function));
+	return m_backend->drawingColor();
 }
 
-void Window::setOnMouseMove(MouseMove function)
-{
-	m_mouseMoveList.push_back(std::move(function));
-}
-
-void Window::setOnRefresh(Refresh function)
+void Window::setDrawingColor(const Color &color)
 {
-	m_refreshList.push_back(std::move(function));
-}
-
-void Window::setDrawingColor(Color color)
-{
-	m_drawingColor = std::move(color);
 	m_backend->setDrawingColor(color);
 }
 
@@ -90,14 +78,24 @@
 	m_backend->drawPoints(points);
 }
 
-void Window::drawRectangle(const Rectangle &rectangle, bool filled, Color fillColor)
+void Window::drawRectangle(const Rectangle &rectangle)
 {
-	m_backend->drawRectangle(rectangle, filled, fillColor);
+	m_backend->drawRectangle(rectangle);
 }
 
-void Window::drawRectangles(const std::vector<Rectangle> &rectangles, bool filled, std::vector<Color> fillColors)
+void Window::drawRectangles(const std::vector<Rectangle> &rectangles)
+{
+	m_backend->drawRectangles(rectangles);
+}
+
+void Window::fillRectangle(const Rectangle &rectangle)
 {
-	m_backend->drawRectangles(rectangles, filled, fillColors);
+	m_backend->fillRectangle(rectangle);
+}
+
+void Window::fillRectangles(const std::vector<Rectangle> &rectangles)
+{
+	m_backend->fillRectangles(rectangles);
 }
 
 void Window::drawText(const std::string &text, Font &font, const Rectangle &rectangle)
--- a/libclient/malikania/window.h	Sun Apr 03 14:50:03 2016 +0200
+++ b/libclient/malikania/window.h	Sun Apr 03 20:10:37 2016 +0200
@@ -1,133 +1,222 @@
+/*
+ * window.h -- main window and basic drawing
+ *
+ * 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_WINDOW_H
 #define MALIKANIA_WINDOW_H
 
-#include <functional>
+/**
+ * @file window.h
+ * @brief Window and drawing.
+ */
+
+#include <memory>
 #include <vector>
 #include <string>
-#include <map>
-#include <memory>
-
-#include "line.h"
-#include "color.h"
-#include "font.h"
-#include "point.h"
-#include "rectangle.h"
-#include "size.h"
 
 namespace malikania {
 
+class Color;
+class Line;
+class Font;
+class Point;
+class Rectangle;
+
+/**
+ * @brief Main window class and drawing.
+ */
 class Window {
-public:
-	using KeyUp = std::function<void (int)>;
-	using KeyDown = std::function<void (int)>;
-	using MouseMove = std::function<void (int, int)>;
-	using Refresh = std::function<void (void)>;
-	using KeyUpList = std::vector<KeyUp>;
-	using KeyDownList = std::vector<KeyDown>;
-	using MouseMoveList = std::vector<MouseMove>;
-	using RefreshList = std::vector<Refresh>;
-
 private:
 	class Backend;
 
 	std::unique_ptr<Backend> m_backend;
 
 	bool m_isOpen{true};
-	KeyUpList m_keyUpList;
-	KeyDownList m_keyDownList;
-	MouseMoveList m_mouseMoveList;
-	RefreshList m_refreshList;
-	Color m_drawingColor;
+
+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");
 
-	template <typename FuncList, typename... Args>
-	inline void notify(FuncList list, Args&&... args)
+	/**
+	 * Move constructor defaulted.
+	 */
+	Window(Window &&) noexcept;
+
+	/**
+	 * Virtual destructor defaulted.
+	 */
+	virtual ~Window() noexcept;
+
+	/**
+	 * Tells if the window is open.
+	 *
+	 * @return true if open
+	 */
+	inline bool isOpen() const noexcept
 	{
-		for (auto &f : list) {
-			f(std::forward<Args>(args)...);
-		}
+		return m_isOpen;
 	}
 
-public:
-	Window(unsigned width = 640, unsigned height = 480);
-
-	Window(Window &&) noexcept;
-
-	virtual ~Window() noexcept;
-
+	/**
+	 * Get the underlying backend.
+	 *
+	 * @return the backend
+	 */
 	inline const Backend &backend() const noexcept
 	{
 		return *m_backend;
 	}
 
+	/**
+	 * Overloaded function.
+	 *
+	 * @return the backend
+	 */
 	inline Backend &backend() noexcept
 	{
 		return *m_backend;
 	}
 
-	Size getWindowResolution();
-
-	void processEvent();
-
+	/**
+	 * Clear the window content with the current drawing color.
+	 */
 	void clear();
 
-	void update();
-
+	/**
+	 * Render the content of the window to the screen.
+	 */
 	void present();
 
-	inline bool isOpen() noexcept
-	{
-		return m_isOpen;
-	}
-
+	/**
+	 * Close the window.
+	 */
 	void close() noexcept;
 
-	void setOnKeyUp(KeyUp function);
-	void setOnKeyDown(KeyDown function);
-	void setOnMouseMove(MouseMove function);
-	void setOnRefresh(Refresh function);
-
-	inline void onKeyUp(int key)
-	{
-		notify(m_keyUpList, key);
-	}
+	/**
+	 * Get the current drawing color.
+	 *
+	 * @return the color
+	 */
+	Color drawingColor() const;
 
-	inline void onKeyDown(int key)
-	{
-		notify(m_keyDownList, key);
-	}
+	/**
+	 * Set the drawing color.
+	 *
+	 * @param color the color
+	 */
+	void setDrawingColor(const Color &color);
 
-	inline void onMouseMove(int x, int y)
-	{
-		notify(m_mouseMoveList, x, y);
-	}
-
-	inline Color drawingColor()
-	{
-		return m_drawingColor;
-	}
-
-	void setDrawingColor(Color color);
-
+	/**
+	 * Draw a line.
+	 *
+	 * @param line the line
+	 */
 	void drawLine(const Line &line);
 
+	/**
+	 * Draw a several lines.
+	 *
+	 * @param the lines vertices
+	 */
 	void drawLines(const std::vector<Point> &points);
 
+	/**
+	 * Draw a point.
+	 *
+	 * @param point the point
+	 */
 	void drawPoint(const Point &point);
 
+	/**
+	 * Draw a list of points.
+	 *
+	 * @param points the points
+	 */
 	void drawPoints(const std::vector<Point> &points);
 
-	void drawRectangle(const Rectangle &rectangle, bool filled = false, Color fillColor = {255, 255, 255, 255});
+	/**
+	 * Draw a rectangle (only borders).
+	 *
+	 * @param rect the rectangle
+	 * @see fillRectangle
+	 */
+	void drawRectangle(const Rectangle &rect);
+
+	/**
+	 * Draw a list of rectangles.
+	 *
+	 * @param rects the rectangles
+	 * @see fillRectangles
+	 */
+	void drawRectangles(const std::vector<Rectangle> &rects);
 
-	void drawRectangles(const std::vector<Rectangle> &rectangles, bool filled = false
-		, std::vector<Color> fillColors = {{255, 255, 255, 255}});
+	/**
+	 * Fill the given rectangle with the current color.
+	 *
+	 * @param rect the rectangle
+	 * @see drawRectangle
+	 */
+	void fillRectangle(const Rectangle &rect);
 
+	/**
+	 * Fill the list of rectangles with the current color.
+	 *
+	 * @param rects the list of rectangles
+	 * @see drawRectangles
+	 */
+	void fillRectangles(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 drawText(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 drawText(const std::string &text, Font &font, const Point &point);
 
-	Window &operator=(Window &&other) noexcept;
+	/**
+	 * Move assigment operator defaulted.
+	 *
+	 * @return this
+	 */
+	Window &operator=(Window &&) noexcept;
 };
 
-}// !malikania
+} // !malikania
 
 #endif // !_MALIKANIA_WINDOW_H_
--- a/tests/libclient/font/main.cpp	Sun Apr 03 14:50:03 2016 +0200
+++ b/tests/libclient/font/main.cpp	Sun Apr 03 20:10:37 2016 +0200
@@ -23,6 +23,7 @@
 
 #include <malikania/color.h>
 #include <malikania/font.h>
+#include <malikania/point.h>
 #include <malikania/resources-locator.h>
 #include <malikania/window.h>
 
--- a/tests/libclient/js-window/main.cpp	Sun Apr 03 14:50:03 2016 +0200
+++ b/tests/libclient/js-window/main.cpp	Sun Apr 03 20:10:37 2016 +0200
@@ -60,6 +60,28 @@
 	}
 }
 
+TEST_F(TestWindow, rect)
+{
+	try {
+		auto ret = duk::pevalString(m_ctx,
+			"w = new Malikania.Window();"
+			"w.setDrawingColor('lightskyblue');"
+			"w.clear();"
+			"w.setDrawingColor('white');"
+			"w.drawRectangle({ x: 10, y: 10, width: 10, height: 10 });"
+			"w.present();"
+		);
+
+		if (ret != 0) {
+			throw duk::error(m_ctx, -1);
+		}
+
+		std::this_thread::sleep_for(3s);
+	} catch (const std::exception &ex) {
+		FAIL() << ex.what();
+	}
+}
+
 int main(int argc, char **argv)
 {
 	testing::InitGoogleTest(&argc, argv);