Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
No results found
Show changes
---
jupytext:
text_representation:
extension: .md
format_name: myst
format_version: 0.13
jupytext_version: 1.15.2
kernelspec:
display_name: C++17
language: C++17
name: xcpp17
---
### Objectif pédagogique : différence entre accumulateur et simple affectation
```{code-cell}
:editable: false
:tags: [hide-cell]
#include <iostream>
#include "jupyter_exercizer_helpers.hpp"
using namespace std;
CONST I1 = RANDOM_INT(5, 17);
```
```{code-cell}
int x, y;
x = 0;
y = 0;
while ( x < I1 ) {
x = x + 1;
y = 1;
}
```
:::{admonition} Consigne
Quelle est la valeur attendue de x et y?
:::
```{code-cell}
---
editable: true
nbgrader:
grade: false
grade_id: init
locked: false
schema_version: 3
solution: true
---
int resultx = INPUT(
/// BEGIN SOLUTION
I1
/// END SOLUTION
);
```
```{code-cell}
---
editable: true
nbgrader:
grade: false
grade_id: init
locked: false
schema_version: 3
solution: true
---
int resulty = INPUT(
/// BEGIN SOLUTION
1
/// END SOLUTION
);
```
```{code-cell}
---
editable: false
nbgrader:
grade: true
grade_id: check
locked: true
points: 1
schema_version: 3
solution: false
tags: [hide-cell]
---
CHECK( resultx == x );
CHECK( resulty == y );
```
---
jupytext:
text_representation:
extension: .md
format_name: myst
format_version: 0.13
jupytext_version: 1.15.2
kernelspec:
display_name: C++17
language: C++17
name: xcpp17
---
### Objectif pédagogique : boucle while avec compteur (ici calcul du quotient)
```{code-cell}
:editable: 'false'
:tags: [hide-cell]
#include <iostream>
#include "jupyter_exercizer_helpers.hpp"
using namespace std;
CONST I1 = RANDOM_INT(20, 37);
CONST I2 = RANDOM_INT(5, 10);
```
```{code-cell}
int n = I1;
int i = 0;
while (n > I2) {
n = n - I2;
i = i + 1;
}
```
:::{admonition} Consigne
Quelle est la valeur attendue de i et n?
:::
```{code-cell}
---
editable: true
nbgrader:
grade: false
grade_id: init
locked: false
schema_version: 3
solution: true
---
int resulti = INPUT(
/// BEGIN SOLUTION
i
/// END SOLUTION
);
```
```{code-cell}
---
editable: true
nbgrader:
grade: false
grade_id: init
locked: false
schema_version: 3
solution: true
---
int resultn = INPUT(
/// BEGIN SOLUTION
n
/// END SOLUTION
);
```
```{code-cell}
---
editable: false
nbgrader:
grade: true
grade_id: check
locked: true
points: 1
schema_version: 3
solution: false
tags: [hide-cell]
---
CHECK( resulti == i );
CHECK( resultn == n );
```
---
jupytext:
text_representation:
extension: .md
format_name: myst
format_version: 0.13
jupytext_version: 1.15.2
kernelspec:
display_name: C++17
language: C++17
name: xcpp17
---
### Objectif pédagogique : boucle while (ici calcul de factorielle)
```{code-cell}
:editable: 'false'
:tags: [hide-cell]
#include <iostream>
#include "jupyter_exercizer_helpers.hpp"
using namespace std;
CONST N0 = RANDOM_INT(3, 5);
```
```{code-cell}
int N, r;
N = N0;
r = 1;
while (N > 0) {
r = r * N;
N = N - 1;
}
```
:::{admonition} Consigne
Quelle est la valeur attendue de `r`?
:::
```{code-cell}
---
editable: true
nbgrader:
grade: false
grade_id: init
locked: false
schema_version: 3
solution: true
---
int result = INPUT(
/// BEGIN SOLUTION
r
/// END SOLUTION
);
```
+++
```{code-cell}
---
editable: false
nbgrader:
grade: true
grade_id: check
locked: true
points: 1
schema_version: 3
solution: false
tags: [hide-cell]
---
CHECK( result == r );
```
---
jupytext:
text_representation:
extension: .md
format_name: myst
format_version: 0.13
jupytext_version: 1.15.2
kernelspec:
display_name: C++17
language: C++17
name: xcpp17
---
### Objectif pédagogique : boucle while (ici calcul du reste)
```{code-cell}
:editable: 'false'
:tags: [hide-cell]
#include <iostream>
#include "jupyter_exercizer_helpers.hpp"
using namespace std;
CONST I1 = RANDOM_INT(20, 37);
CONST I2 = RANDOM_INT(5, 10);
```
```{code-cell}
int r = I1;
while (r > I2) {
r = r - I2;
}
```
:::{admonition} Consigne
Quelle est la valeur attendue de `r`?
:::
```{code-cell}
---
editable: true
nbgrader:
grade: false
grade_id: init
locked: false
schema_version: 3
solution: true
---
int result = INPUT(
/// BEGIN SOLUTION
r
/// END SOLUTION
);
```
+++
```{code-cell}
---
editable: false
nbgrader:
grade: true
grade_id: check
locked: true
points: 1
schema_version: 3
solution: false
tags: [hide-cell]
---
CHECK( result == r );
```
#ifndef RANDOMIZATION_H
#define RANDOMIZATION_H
#include <iostream>
#include <cstdlib>
#include <vector>
#include <functional>
/** Infrastructure minimale de test **/
#ifndef ASSERT
#define ASSERT(test) if (!(test)) { throw std::runtime_error("\\x1b[48;5;224mTest failed: "#test); }
#endif
#ifndef CHECK
#define CHECK(test) if ( !(test) ) { throw std::runtime_error("\\x1b[48;5;224mTest failed: "#test); }
#endif
// TODO: how to initialize the seed?
// TODO: randomize ???
#define PLUSOUMOINS +
#define CONST const auto
// TODO: randomize ???
#define X x
#define Y y
#define Z z
int RANDOM_INT(int min, int max) {
return min + (rand() % (max - min + 1));
}
template<typename T, typename ... Args>
T RANDOM_CHOICE(const T arg0, const Args... args) {
const std::vector<T> v({arg0, args...});
return v[rand() % v.size()];
}
template<typename ... Args>
auto RANDOM_CHOICE(const char * arg0, const Args... args) {
const std::vector<std::string> v({arg0, args...});
return v[rand() % v.size()];
}
class RANDOM_VECTOR_CLASS {
public:
template <typename F, typename ... Args>
auto operator ()(int N, F f, Args ... args) {
using invoke_result_t = typename std::invoke_result<F, Args ...>::type;
std::vector<invoke_result_t> v(N);
for (auto &value: v)
value = f(args...);
return v;
}
/*template<typename ... Args>
auto operator ()(int N, RANDOM_VECTOR_CLASS f, Args... args) {
std::vector<std::vector<int>> v(N);
for (auto &value: v)
value = f(args...);
return v;
}*/
};
RANDOM_VECTOR_CLASS RANDOM_VECTOR;
template<typename T>
std::ostream & operator << (std::ostream& o, const std::vector<T> &v) {
o << "{";
if ( v.size() >= 0 ) {
o << v[0];
for ( unsigned int i=1; i<v.size(); i++ )
o << ", " << v[i];
}
o << "}";
return o;
}
template<class T>
T INPUT(T t) {
return t;
}
#endif
from typing import Any
from random import randint, choice
CONST = Any
def INPUT(default: Any) -> Any:
return default
def RANDOM_INT(min: int, max: int):
return randint(min, max+1)
def RANDOM_CHOICE(*args):
r"""
Return a random element of `args`
>>> RANDOM_CHOICE("alice", "bob", "charlie") # doctest: +SKIP
'charlie'
>>> RANDOM_CHOICE("alice")
'alice'
"""
return choice(args)
......@@ -55,6 +55,16 @@ programmer des dessins et interagir avec l'utilisateur.
## TP
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "0b59002ac0b41ec5fe9db98882963c56", "grade": false, "grade_id": "cell-88edc2f254ba7293", "locked": true, "schema_version": 3, "solution": false}}
### Exercice 0 : préliminaires : exercices d'entraînement
1. Effectuez quelques exercices sur les prototypes de fonction de la
feuille [entraîneur/entraîneur.md](entraîneur/entraîneur.md).
Vous pourrez, pour réviser, travailler les exercices sur les autres
thèmes à la maison, en fonction de vos besoins.
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "c14862eeb15c1d00c45129ecb04ba658", "grade": false, "grade_id": "cell-88edc2f254ba7294", "locked": true, "schema_version": 3, "solution": false}}
### Exercice 1 : préliminaires : compilation séparée
......@@ -172,7 +182,7 @@ programmer des dessins et interagir avec l'utilisateur.
### Exercice 4 : Premiers graphiques avec SFML
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "dc9004964871c8e7a51c6e61d4995bb1", "grade": false, "grade_id": "cell-96bafcc3c30ace6g", "locked": true, "schema_version": 3, "solution": false}}
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "f94f35a5a86a6a9bbfa70e9f2ec5274c", "grade": false, "grade_id": "cell-96bafcc3c30ace6g", "locked": true, "schema_version": 3, "solution": false}}
:::::{attention} SFML et sessions graphiques
......@@ -200,9 +210,15 @@ interface graphique (dite XFCE Desktop) sur le même serveur. Vous
pourrez ensuite basculer entre l'une et l'autre pour éditer et
compiler vos programmes d'une part, et les exécuter d'autre part.
:::{figure} https://nicolas.thiery.name/Enseignement/Info111/media/screencast-sfml-on-jupyterhub.gif
Vidéo: lancer un programme graphique sur JupyterHub
:::
<figure>
<video src="https://nicolas.thiery.name/Enseignement/Info111/media/screencast-sfml-on-jupyterhub.webm"
width="95%" controls
alt="Vidéo: lancer un programme graphique SFML avec JupyterHub"
/>
<figcaption>Vidéo : lancer un programme graphique SFML avec JupyterHub</figcaption>
</figure>
::::
......@@ -311,4 +327,3 @@ de points sera ensuite affiché.
À vous de concevoir les fonctions à introduire pour décomposer le
problème.
......@@ -7,7 +7,7 @@ using namespace std; // Pour les exceptions dans la version distribuée
int main() {
int delai = 1;
RenderWindow window(VideoMode(900, 480), "Ma super fenêtre");
RenderWindow window(VideoMode(640, 480), "Ma super fenêtre");
window.clear(Color::Green);
// Dessine un point noir de coordonnées (418, 143)
......@@ -61,22 +61,31 @@ int main() {
throw runtime_error("code non implanté ligne 56");
window.display();
sleep(seconds(delai));
// Dessine un triangle bleu entre les (0,0), (640,0) et (0,160)
// Remplacez cette ligne et la suivante par le code adéquat
throw runtime_error("code non implanté ligne 65");
window.display();
sleep(seconds(delai));
// Dessine un cercle noir de centre (415,145) et de rayon 10
// Remplacez cette ligne et la suivante par le code adéquat
throw runtime_error("code non implanté ligne 64");
throw runtime_error("code non implanté ligne 72");
window.display();
sleep(seconds(delai));
// Dessine un disque jaune de centre (700, 100) et de rayon 50
// Dessine un disque jaune de centre (550, 75) et de rayon 50
// Remplacez cette ligne et la suivante par le code adéquat
throw runtime_error("code non implanté ligne 72");
throw runtime_error("code non implanté ligne 80");
window.display();
......
......@@ -14,6 +14,15 @@ kernelspec:
# Premiers graphiques avec Jupyter
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "f43a760bd6125e25df23a9ab2628c3e9", "grade": false, "grade_id": "cell-db040b06c5a92100", "locked": true, "schema_version": 3, "solution": false, "task": false}}
Dans cette feuille, nous allons reprendre l'exercice 2 du TD et
effectuer un premier dessin.
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "f4cbf5563a6542f5c409f308fdca30a3", "grade": false, "grade_id": "cell-db040b06c5a92101", "locked": true, "schema_version": 3, "solution": false, "task": false}}
Commençons par créer un canvas vert de taille 640 x 480 :
```{code-cell}
---
deletable: false
......@@ -37,35 +46,44 @@ deletable: false
editable: false
nbgrader:
cell_type: code
checksum: bca96fdfc7023d461b707c8ae74b0caa
checksum: 9d359d2bf83f09dfcd9eb723473a197f
grade: false
grade_id: cell-c2afd88f340f46f4
locked: true
schema_version: 3
solution: false
task: false
tags: []
---
RenderWindow window(VideoMode(900, 480), "Ma super fenêtre");
RenderWindow window(VideoMode(640, 480), "Ma super fenêtre");
window.canvas
```
<canvas id='primitives_canvas'></canvas>
```{code-cell}
window.clear(Color::Green);
```
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "7df12946868397e5fbe4bc994fb8d19c", "grade": false, "grade_id": "cell-db040b06c5a92102", "locked": true, "schema_version": 3, "solution": false, "task": false}}
puis dessinons un point noir de coordonnées (418, 143). Ce point est
tout petit, vous aurez peut-être un peu de mal à le distinguer :
```{code-cell}
// Dessine un point noir de coordonnées (418, 143)
draw_point(window, {418, 143}, Color::Black );
window.display();
```
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "cb08398efe05ecc0073912c50887ba17", "grade": false, "grade_id": "cell-db040b06c5a92103", "locked": true, "schema_version": 3, "solution": false, "task": false}}
1. Dessinez un segment blanc entre les points de coordonnées
respectives (100,200) et (200,200) :
```{code-cell}
---
deletable: false
nbgrader:
cell_type: code
checksum: b956b1c98520d602fab742ceb67096ed
checksum: ce1d6a0deeef3221d1ea8d9afbd40bce
grade: true
grade_id: cell-e77db2d9ed7265ac
locked: false
......@@ -74,17 +92,32 @@ nbgrader:
solution: true
task: false
---
// Dessine un segment blanc entre les points (100,200) et (200,200)
// REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE
window.display();
```
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "5da5ff8010119a35e52e9ba76dc3237d", "grade": false, "grade_id": "cell-db040b06c5a92104", "locked": true, "schema_version": 3, "solution": false, "task": false}}
:::{tip} Astuce
Pour éviter de monter et descendre constamment dans cette feuille,
faites un clic droit sur le canvas et cliquez sur «Créer une nouvelle
vue pour la sortie» (ou «Create new view for output»). Puis disposez
la copie obtenue du canvas sur votre espace de travail de sorte à voir
simultanément votre code et le canvas.
:::
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "fea5730c56d940cd6a18b432d9069629", "grade": false, "grade_id": "cell-db040b06c5a92105", "locked": true, "schema_version": 3, "solution": false, "task": false}}
2. Dessinez un segment rouge entre les points (200,300) et (200,400) :
```{code-cell}
---
deletable: false
nbgrader:
cell_type: code
checksum: 85bdbd533e19a61d9a8a460522c51477
checksum: 90954d14f326667b7a51643cd5d83bc0
grade: true
grade_id: cell-03b3d3f225c29d1d
locked: false
......@@ -93,17 +126,21 @@ nbgrader:
solution: true
task: false
---
// Dessine un segment rouge entre les points (200,300) et (200,400)
// REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE
window.display();
```
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "0791571f18f4df2c2bfecb5a3ba9c0ff", "grade": false, "grade_id": "cell-db040b06c5a92106", "locked": true, "schema_version": 3, "solution": false, "task": false}}
3. Dessinez un rectangle horizontal vide de sommets diagonaux
(200,200) et (400,300) et de contour rouge :
```{code-cell}
---
deletable: false
nbgrader:
cell_type: code
checksum: dea1bd15783375ceace4d093b9200ec4
checksum: 4c65f8e4cec21af229e5a44dd7063a03
grade: true
grade_id: cell-3606e0158c83309d
locked: false
......@@ -112,17 +149,21 @@ nbgrader:
solution: true
task: false
---
// Dessine un rectangle horizontal vide de sommets diagonaux (200,200) et (400,300) et de contour rouge
// REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE
window.display()
```
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "4eda0a34767a781e0fd3c186999331e2", "grade": false, "grade_id": "cell-db040b06c5a92107", "locked": true, "schema_version": 3, "solution": false, "task": false}}
4. Dessinez un rectangle horizontal plein noir de sommets diagonaux
(400,150) et (500,200) :
```{code-cell}
---
deletable: false
nbgrader:
cell_type: code
checksum: 8d1e034e1cda25ee20a1c154f6f26185
checksum: f66e8172c61aca3cb946861a95326520
grade: true
grade_id: cell-25abe8a7c6c8c617
locked: false
......@@ -131,17 +172,21 @@ nbgrader:
solution: true
task: false
---
// Dessine un rectangle horizontal plein noir de sommets diagonaux (400,150) et (500,200)
// REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE
window.display()
```
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "2f11cf73501e6fcc67b66d7ced218656", "grade": false, "grade_id": "cell-db040b06c5a92108", "locked": true, "schema_version": 3, "solution": false, "task": false}}
5. Dessinez un segment rouge entre les points (400,300) et
(500,400) :
```{code-cell}
---
deletable: false
nbgrader:
cell_type: code
checksum: 196d46fbc53bc7393b523ace887864ab
checksum: 49650230393c3fc8d743c211525de50c
grade: true
grade_id: cell-c6d75131df2bea6d
locked: false
......@@ -150,17 +195,42 @@ nbgrader:
solution: true
task: false
---
// Dessine un segment rouge entre les points (400,300) et (500,400)
// REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE
window.display()
```
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "34955bd551a86d7f66e34edca2617cab", "grade": false, "grade_id": "cell-db040b06c5a92109", "locked": true, "schema_version": 3, "solution": false, "task": false}}
6. ♣ Dessinez un triangle bleu entre les (0,0), (640,0) et (0,160) :
```{code-cell}
---
deletable: false
nbgrader:
cell_type: code
checksum: de3439e6f2af1c2ebadec5e92840b900
grade: true
grade_id: cell-c6d75131df2bea6e
locked: false
points: 1
schema_version: 3
solution: true
task: false
---
// REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE
window.display()
```
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "16aaa6f47064b571ba75a417797361e4", "grade": false, "grade_id": "cell-db040b06c5a92110", "locked": true, "schema_version": 3, "solution": false, "task": false}}
7. Dessinez un cercle noir de centre (415,145) et de rayon 10 :
```{code-cell}
---
deletable: false
nbgrader:
cell_type: code
checksum: 783c0f2dd02e54533dd5243b34fe2ccd
checksum: e56a4a8d478945ff8d1ef1c4497dcf05
grade: true
grade_id: cell-63406c09d76b868b
locked: false
......@@ -169,17 +239,20 @@ nbgrader:
solution: true
task: false
---
// Dessine un cercle noir de centre (415,145) et de rayon 10
// REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE
window.display()
```
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "92e964b26520043007e0fe1972b38638", "grade": false, "grade_id": "cell-db040b06c5a92111", "locked": true, "schema_version": 3, "solution": false, "task": false}}
8. Dessinez un disque jaune de centre (550, 75) et de rayon 50 :
```{code-cell}
---
deletable: false
nbgrader:
cell_type: code
checksum: cfc9ac790998bab53ad2de41b30f2f6d
checksum: 6419729d5f34a928308cdd11942a3f1a
grade: true
grade_id: cell-4f7332edb4646cbf
locked: false
......@@ -188,8 +261,25 @@ nbgrader:
solution: true
task: false
---
// Dessine un disque jaune de centre (700, 100) et de rayon 50
// REMPLACEZ CETTE LIGNE PAR VOTRE RÉPONSE
window.display()
```
+++ {"deletable": false, "editable": false, "nbgrader": {"cell_type": "markdown", "checksum": "ef878f93df33be50d5262273cefbc00a", "grade": false, "grade_id": "cell-db040b06c5a92112", "locked": true, "schema_version": 3, "solution": false, "task": false}}
:::{attention}
Comme vous l'avez constaté, les performances sont lamentables. C'est
parce que nous avons abusé des canvas de HTML : alors que ceux-ci sont
conçus pour du dessin vectoriel, nous approximons les figures
vectorielles (lignes, triangles, ...) par des accumulations d'un très
grand nombre de pixels (combien pour le triangle bleu?), sachant que
chacun de ces pixels est en fait représenté en interne par un petit
rectangle.
En dehors de ce premier dessin -- dont l'objectif pédagogique était de
faire un peu d'algorithmique -- il faut au contraire utiliser les
primitives vectorielles fournies.
:::
#ifndef PRIMITIVES_JUPYTER_H
#define PRIMITIVES_JUPYTER_H
/**
Variante de primitives.h pour dessiner dans Jupyter, sans la SFML
......@@ -11,48 +14,16 @@
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");
}
#include <xcanvas/xcanvas.hpp>
namespace Color {
using Color = std::string;
Color White = "white";
Color Red = "red";
Color Yellow = "yellow";
Color Green = "#00FF00";
Color Black = "black";
Color White = "White";
Color Blue = "Blue";
Color Red = "Red";
Color Yellow = "Yellow";
Color Green = "#00CC00";
Color Black = "Black";
}
class Point {
......@@ -70,49 +41,43 @@ class VideoMode {
VideoMode(int w, int h): width(w), height(h) {}
};
using Canvas = xw::xmaterialize<xc::xcanvas>;
class RenderWindow {
xw::html html;
VideoMode vm;
public:
// A buffer of javascript commands to execute
std::ostringstream buffer;
Canvas canvas;
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();
vm = _vm;
canvas = xc::canvas().initialize()
.width(vm.width)
.height(vm.height)
.finalize();
canvas.cache();
}
// Update the canvas by executing all javascript commands in the buffer
void display() {
execute_javascript(buffer.str());
buffer = std::ostringstream();
Canvas& get_canvas() {
return canvas;
}
// 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();
canvas.fill_style = color;
canvas.fill_rect(0, 0, vm.width, vm.height);
display();
}
void display() {
canvas.flush();
canvas.cache();
}
};
void draw_point(RenderWindow &window, Point p, Color::Color color) {
window.buffer << "document.primitives_draw_point("
<< p.x << ", "
<< p.y << ", '"
<< color << "');";
window.canvas.fill_style = color;
window.canvas.fill_rect(p.x, p.y, 1, 1);
}
#endif