Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/**
Variante de primitives.h pour dessiner dans Jupyter, sans la SFML
CAVEAT: Ceci est une pure rustine, du genre que l'on bricole entre
minuit et 3h du mat pour sauver un TP, en attendant une solution
pérenne: backend Jupyter pour SFML, utilisation de xcanvas
(https://github.com/martinRenou/xcanvas) l'équivalent de ipycanvas
(https://ipycanvas.readthedocs.io/) pour C++, ou possibilité de
lancer des applications graphiques sur JupyterHub.
NE PRENNEZ PAS EXEMPLE DESSUS!
**/
#include <iostream>
#include <sstream>
#include <xwidgets/xhtml.hpp>
/** Execute javascript code in the Jupyter window
**/
void execute_javascript(std::string js) {
nl::json mime_bundle;
mime_bundle["application/javascript"] = js;
::xeus::get_interpreter().display_data(mime_bundle,
nl::json::object(),
nl::json::object());
}
void load_javascript_library() {
execute_javascript(R"js(
document.primitives_get_context = function() {
return document.primitives_canvas.getContext('2d');
}
document.primitives_draw_rectangle = function(x, y, width, height, color) {
var ctx = document.primitives_get_context();
ctx.strokeStyle = color;
ctx.strokeRect(x, y, width, height);
}
document.primitives_draw_filled_rectangle = function(x, y, width, height, color) {
var ctx = document.primitives_get_context();
ctx.fillStyle = color;
ctx.fillRect(x, y, width, height);
}
document.primitives_draw_point = function(x, y, color) {
document.primitives_draw_rectangle(x, y, 1, 1, color);
}
)js");
}
namespace Color {
using Color = std::string;
Color White = "white";
Color Red = "red";
Color Yellow = "yellow";
Color Green = "#00FF00";
Color Black = "black";
}
class Point {
public:
int x;
int y;
Point(int _x, int _y): x(_x), y(_y) {};
Point(double _x, double _y): x(_x), y(_y) {};
};
class VideoMode {
public:
int width;
int height;
VideoMode(int w, int h): width(w), height(h) {}
};
class RenderWindow {
xw::html html;
VideoMode vm;
public:
// A buffer of javascript commands to execute
std::ostringstream buffer;
RenderWindow(VideoMode _vm, std::string s) : vm(_vm) {
std::ostringstream canvas;
// canvas << "<canvas id='primitives_canvas'"
// << " width=" << vm.width << " height=" << vm.height
// << " style='border:1px solid #000000;'></canvas>";
load_javascript_library();
buffer << "document.primitives_canvas = document.getElementById('primitives_canvas');";
buffer << "document.primitives_canvas.height = " << vm.height << ";";
buffer << "document.primitives_canvas.width = " << vm.width << ";";
buffer << "document.primitives_canvas.style = 'border:1px solid #000000';";
display();
// Disabled until xwidgets is functional again
// For now, the canvas needs to be created in a markdown cell of the notebook
// html.value = canvas.str();
// html.display();
}
// Update the canvas by executing all javascript commands in the buffer
void display() {
execute_javascript(buffer.str());
buffer = std::ostringstream();
}
// Clear the canvas with the given color
void clear(Color::Color color) {
buffer << "document.primitives_draw_filled_rectangle(0, 0, "
<< vm.width << ", "
<< vm.height << ", '"
<< color << "');";
display();
}
};
void draw_point(RenderWindow &window, Point p, Color::Color color) {
window.buffer << "document.primitives_draw_point("
<< p.x << ", "
<< p.y << ", '"
<< color << "');";
}