xxxxxxxxxx
580
let selecteur;
let timeCode;//valeur du timeCode sur la timeline
let mode='navigation';
let echelle =500;
let ofset=0;
let scenario;
let nSources=6;
let couleurInterface={};
let couleurDeSources=[];
let bckColor;
let bornesSelection=[];
let selectionBloc;
let periode=500;
let Frequence;
let inFile;
let saveFile;
let textInfo="";
let uneMicroSec;
let lignes;
function preload() {
lignes = loadStrings('Scenario.tsv');
}
function setup() {
for (let source=1;source<=nSources;source++){
couleurDeSources[source-1]=(170+((source-1)*360/nSources))%360;
}
couleurInterface['bckColor']=color(60, 60, 60);
couleurInterface['grid']=color(240,240,230);
couleurInterface['info']=color(240,240,230);
couleurInterface['curseur']=color(250,254,254);
couleurInterface['courbe']=color(250,20,0);
couleurInterface['surligne']=color(225,200);
couleurInterface['curseurEdition']=color(10,250,75);
createCanvas(windowWidth, windowHeight*0.6);
selecteur=new Selecteur2Sources(nSources);
editeurBloc=new editeur2Bloc();
(scenario = new p5.Table).columns = ['Time_(us)', 'Device1', 'Device2', 'Device3', 'Device4', 'Device5', 'Device6'];
//load a default scenario
chargeScenario();
//select a bloc to edit it
bornesSelection=[0,8];
//copier dans le presse papier
if(selectionBloc==null){
selectionBloc= new p5.Table;
}else{
selectionBloc.clearRows();
}
for(id=0;id<=8;id++){
selectionBloc.addRow(scenario.getRow(id));
}
editeurBloc.timeCodeOrigine=121;
editeurBloc.timeCode.value(121);
mode='selection';
editeurBloc.move();
//try to deplace Bloc : where is the bug
//deplaceBloc();
uneMicroSec=map(1,0,echelle,0,width);
}
function windowResized() {
resizeCanvas(windowWidth, windowHeight*0.6);
}
function sauveScenario(){
filename="ScenarioCesame"
saveTable(scenario,filename,"tsv");
}
function chargeScenario(thefile){
scenario.clearRows();
let numPoints=0;
for(let i=1;i<lignes.length;i+=1){
if (lignes[i].length>0){
valeurs=split(lignes[i], '\t');
numPoints++;
laLigne=scenario.addRow();
laLigne.setString('Time_(us)',valeurs[0]);
//+boolean pour transformer le en integer
laLigne.setNum('Device1',+valeurs[1]);
laLigne.setNum('Device2',+valeurs[2]);
laLigne.setNum('Device3',+valeurs[3]);
laLigne.setNum('Device4',+valeurs[4]);
laLigne.setNum('Device5',+valeurs[5]);
laLigne.setNum('Device6',+valeurs[6]);
}
}
print(numPoints + " points chargés");
ordonneScenario();
}
function draw() {
background(couleurInterface['bckColor']);
grille();
traceScenario();
timeCode=int(mouseX*echelle/windowWidth);
let x;
switch(mode){
case 'navigation':
if (keyIsDown(17) === true) {//touche controle enfoncée : aimantation
for(t=-echelle/50;t<echelle/50;t++){//balaye les valeurs avoisinantes
laLigne=scenario.matchRow(new RegExp(String(timeCode+t)),'Time_(us)');
if(laLigne!=null){
timeCode=timeCode+t;
break;
}
}
}
stroke(couleurInterface['curseur']);
x=map(timeCode,0,echelle,0,width);
line(x,0,x,height);
textInfo="Navigation : Double clic pour éditer un point [Ctrl] pour aimantation vers le points le plus proche. [Shift] pour sélectionner un bloc";
break;
case 'creation':
//point en cours de création
stroke(couleurInterface['curseurEdition']);
x=selecteur.timeCode.value()*windowWidth/echelle;
print("x : "+x);
line(x,0,x,height);
text("><",x-10,height*0.9);
textInfo="Edition : Modifier le timecode pour créer un nouveau point [ok] pour valider [X] pour annuler [efface] pour effacer le point";
break;
case 'edition':
//edition d'un point existant
break;
case 'selection':
stroke(couleurInterface['surligne']);
x=editeurBloc.timeCode.value()*windowWidth/echelle;
line(x,0,x,height);
text("><",x-10,height*0.9);
textInfo="Edition de Bloc : modifier le timecode pour déplacer ou copier le bloc";
//surligne le block selectionné
surligneBloc();
break;
}
legende();
}
function surligneBloc(){
//surligne un bloc sélectionné
let decalage=editeurBloc.timeCode.value()-editeurBloc.timeCodeOrigine;
let lastPoint={};
let previousPoint={};
previousPoint.x=0;
previousPoint.y=0;
for(id=0;id<selectionBloc.getRowCount();id++){
lastPoint.x=map(parseInt(selectionBloc.get(id,0))+decalage,0,echelle,0,width);
lastPoint.y=(5+(selectionBloc.get(id,1)+selectionBloc.get(id,2)+selectionBloc.get(id,3)+selectionBloc.get(id,4)+selectionBloc.get(id,5)+selectionBloc.get(id,6))*(height-10)/6);
//contour de la courbe
colorMode(RGB);
strokeWeight(5);
stroke(couleurInterface['surligne']);
line(previousPoint.x,previousPoint.y,lastPoint.x,previousPoint.y);
line(lastPoint.x,previousPoint.y,lastPoint.x,lastPoint.y);
line(lastPoint.x,lastPoint.y,lastPoint.x+uneMicroSec,lastPoint.y);
previousPoint.x=lastPoint.x+uneMicroSec;
previousPoint.y=lastPoint.y;
}
}
function mouseClicked(){
if (keyIsDown(16) === true) {//shift : selection d'un Block
timeCodeClick=int(mouseX*echelle/windowWidth);
//identification de la zone selectionnée
let pointAvant=0;
let inId=-1;
let outId=-1;
for(id=0;id<scenario.getRowCount();id++){
xBloc=map(parseInt(scenario.get(id,0)),0,echelle,0,width);
sommeSources=(scenario.get(id,1)+scenario.get(id,2)+scenario.get(id,3)+scenario.get(id,4)+scenario.get(id,5)+scenario.get(id,6));
if(pointAvant==0 && sommeSources!=0 && xBloc<mouseX ){//c'est un point d'entrée de bloc
inId=id;
}
if(pointAvant!=0 && sommeSources==0 && xBloc>mouseX && outId==-1){//c'est un point de sortie de bloc
outId=id;
}
pointAvant=sommeSources;
}
if(inId!=-1){//si on a trouvé un bloc
mode='selection';
if(outId==-1){
outId=id-1;
}
print("selection des points "+inId+" a "+outId);
bornesSelection=[inId,outId];
//copier dans le presse papier
if(selectionBloc==null){
selectionBloc= new p5.Table;
}else{
selectionBloc.clearRows();
}
for(id=inId;id<=outId;id++){
selectionBloc.addRow(scenario.getRow(id));
}
print("selectionBloc");
tco=parseInt(scenario.get(inId,0));
editeurBloc.timeCodeOrigine=tco;
editeurBloc.timeCode.value(tco);
editeurBloc.move();
}
}
}
function legende(){
fill(couleurInterface['info']);
noStroke();
text(String(timeCode)+" / "+String(periode)+" µs",20,20);
text(textInfo,20,height-20);
}
function doubleClicked() {
if (mode=='navigation'){
selecteur.pointFocus=-1;
for(id=0;id<scenario.getRowCount();id++){
if (scenario.getString(id,0)==String(timeCode)){
print("edition d'un point exitant "+id);
print(scenario.getString(id,0));
selecteur.pointFocus=id;
}
}
selecteur.timeCode.value(timeCode);
selecteur.majTimeCode();
mode='creation';
}
}
function changeEchelle(){
periode=1000000/Frequence.value();
echelle=parseInt(periode);
uneMicroSec=map(1,0,echelle,0,width);
traceScenario();
}
class editeur2Bloc{
timeCodeOrigine=0;//timeCode d'entrée lors de la selection
constructor(){
this.palette=createDiv();
this.palette.position(100,100);
this.timeCode=createInput(5,'int');
this.timeCode.size(50);
this.timeCode.parent(this.palette);
this.timeCode.changed(this.move);
this.validation=createButton('Deplace','Deplace');
this.validation.mousePressed(deplaceBloc);
this.validation.parent(this.palette);
this.validation=createButton('Copie','Copie');
this.validation.mousePressed(this.move);
this.validation.parent(this.palette);
this.abandon=createButton('X','X');
this.abandon.parent(this.palette);
this.abandon.mousePressed(this.selecteurCLose);
this.palette.hide();
}
selecteurCLose = () =>{
this.palette.hide();
ordonneScenario();
mode='navigation';
}
deplace(){
//nothing
}
move=()=>{
//deplace le menu d'edition
let X=map(this.timeCode.value(),0,echelle,0,width);
this.palette.position(X,300);
this.palette.show();
}
}
class Selecteur2Sources {
s=[];
len=0;
pointFocus;//point edité s'il existe
constructor(len){
this.len=len;//nombre de sources
this.palette=createDiv();
this.palette.position(100,100);
this.timeCode=createInput(5,'int');
this.timeCode.size(50);
this.timeCode.parent(this.palette);
this.timeCode.changed(this.move);
var p=createSpan('<br/>');
p.parent(this.palette);
for (let y=1;y<=len;y +=1 ){
this.s[y-1] = createCheckbox("source "+str(y));
this.s[y-1].parent(this.palette);
}
this.validation=createButton('ok','ok');
this.validation.mousePressed(this.majPoint);
this.validation.parent(this.palette);
this.abandon=createButton('X','X');
this.abandon.parent(this.palette);
this.abandon.mousePressed(this.selecteurCLose);
this.efface=createButton('efface','X');
this.efface.parent(this.palette);
this.efface.mousePressed(this.effacePoint);
this.palette.hide();
}
selecteurCLose=()=>{
this.palette.hide();
mode='navigation';
}
effacePoint(){
print('efface le point');
selecteur.selecteurCLose();
for(id=0;id<scenario.getRowCount();id++){
if (scenario.getNum(id,0)==selecteur.timeCode.value()){
scenario.removeRow(id);
break;
}
}
mode ='navigation';
}
majPoint=()=>{
print("édition d'un point");
print(this.pointFocus);
let laLigne;
if(this.pointFocus==-1){
//si le point n'existe pas le crée
print("création");
laLigne=scenario.addRow();
}else{
//s'il existe verifier que le nouveau timeCode ne pointe pas sur un autre point existant
print("mise à jour");
for(id=0;id<scenario.getRowCount();id++){
if (id!=this.pointFocus && scenario.getString(id,0)==String(selecteur.timeCode.value())){
print("ecrase un point existant");
scenario.removeRow(this.pointFocus);
this.pointFocus=id;
}
}
laLigne=scenario.getRow(this.pointFocus);
}
laLigne.setString('Time_(us)',String(selecteur.timeCode.value()));
//+boolean pour le transformer en integer
laLigne.setNum('Device1',+selecteur.s[0].checked());
laLigne.setNum('Device2',+selecteur.s[1].checked());
laLigne.setNum('Device3',+selecteur.s[2].checked());
laLigne.setNum('Device4',+selecteur.s[3].checked());
laLigne.setNum('Device5',+selecteur.s[4].checked());
laLigne.setNum('Device6',+selecteur.s[5].checked());
ordonneScenario();
selecteur.selecteurCLose();
}
majTimeCode=()=>{
//met à jour la position après une modification du timeCode
let X=map(selecteur.timeCode.value(),0,echelle,0,width);
let numPoints=scenario.getRowCount();
if( numPoints>0){
for(let id=scenario.getRowCount()-1;id>=0;id--){//prend la valeur du precedent point sur la timeline
if (scenario.getNum(id,0)<=selecteur.timeCode.value()){
//set les valeurs actuelles des sources
for(let source=0;source<nSources;source++){
selecteur.s[source].checked(scenario.getNum(id,source+1));
}
break;
}
}
}
this.move();
}
move(){
let X=map(selecteur.timeCode.value(),0,echelle,0,width);
selecteur.palette.position(X,300);
selecteur.palette.show();
}
}
function deplaceBloc(){
//deplace le bloc selectionné
print(scenario.getArray());
//deplace tout le bloc
let decalage=editeurBloc.timeCode.value()-editeurBloc.timeCodeOrigine;
//let lignes=scenario.getRows();
print("bornesSelection : "+bornesSelection);
for(let id=bornesSelection[0];id<=bornesSelection[1];id++){
print("move point "+id);
let nouveauTimeCode=String(parseInt(scenario.get(id,0))+decalage);
print("nouveauTimeCode : "+nouveauTimeCode);
let laLigne=scenario.getRow(id);
print(laLigne);
print("The bug is here : line 434");
laLigne.setString(id,nouveauTimeCode);
print(scenario.getArray());
}
ordonneScenario();
let X=map(editeurBloc.timeCode.value(),0,echelle,0,width);
editeurBloc.palette.position(X,300);
editeurBloc.palette.show();
}
function ordonneScenario(){
//ordonne les points dans l'ordre chronologique
let timeCodes=[];
for(let i=0;i<scenario.getRowCount();i++){
append(timeCodes,parseInt(scenario.getString(i,0)));
}
timeCodes=sort(timeCodes,timeCodes.length);
(scenarioOrdonne = new p5.Table).columns = ['Time_(us)', 'Device1', 'Device2', 'Device3', 'Device4', 'Device5', 'Device6'];
for(let id=0;id<timeCodes.length;id++){
let laLigne=scenario.matchRow(new RegExp(String(timeCodes[id])),0);
laLigneOrdonnee=scenarioOrdonne.addRow();
laLigneOrdonnee.set(0,String(timeCodes[id]));
for(s=1;s<nSources+1;s++){
laLigneOrdonnee.set(s,laLigne.get(s));
}
}
scenario=scenarioOrdonne;
}
function traceScenario(){
//redessine le scenario
if(scenario.getRowCount()>0){
//dessine le graphe
let lastPoint={};
let previousPoint={};
previousPoint.x=0;
previousPoint.y=0;
for(id=0;id<scenario.getRowCount();id++){
lastPoint.x=map(parseInt(scenario.get(id,0)),0,echelle,0,width);
lastPoint.y=(5+(scenario.get(id,1)+scenario.get(id,2)+scenario.get(id,3)+scenario.get(id,4)+scenario.get(id,5)+scenario.get(id,6))*(height-10)/6);
if(id>0){
//a partir du second point colorer la zone précédente
colorMode(HSB);
let intervalleY=(height-10)/nSources;
let rectY=5;
rectMode(CORNERS);
noStroke();
for(let source=1;source<=nSources;source++){
if(scenario.get(id-1,source)){
fill(couleurDeSources[source-1],50,75,1*mouseY/height);
rect(previousPoint.x-uneMicroSec,rectY,lastPoint.x,rectY+intervalleY);
rectY+=intervalleY;
}
}
rectY=5;
}
rectMode(CORNER);
//contour de la courbe
colorMode(RGB);
strokeWeight(1);
stroke(couleurInterface['courbe']);
line(previousPoint.x,previousPoint.y,lastPoint.x,previousPoint.y);
line(lastPoint.x,previousPoint.y,lastPoint.x,lastPoint.y);
line(lastPoint.x,lastPoint.y,lastPoint.x+uneMicroSec,lastPoint.y);
fill(couleurInterface['courbe']);
circle(lastPoint.x,lastPoint.y,11);
previousPoint.x=lastPoint.x+uneMicroSec;
previousPoint.y=lastPoint.y;
}
//legende
for(let source=1;source<=nSources;source++){
//noStroke();
colorMode(HSB);
noStroke();
fill(couleurDeSources[source-1],100,100,1*mouseY/height);
rect(20,18+(20*source),20,20);
fill(0,0,255,1*mouseY/height);
text("Source "+source,50,30+(20*source));
colorMode(RGB);
}
}
}
function grille(){
//dessine la grille
stroke(couleurInterface['grid']);
strokeWeight(1);
for (let y=0;y<height;y += height/6){
line(0,y,width,y);
}
let intervale =periode/100;
for (let x=0;x<width;x += width/intervale){
line(x,0,x,height);
}
}