List monitors

This commit is contained in:
Thomas Weber committed 2021-06-24 14:08:47 -05:00
1 parent 036368778a
commit 22d1ca351d
3 files changed
+193 -35

No files matched your search

+17 -15
View File
@@ -5,7 +5,7 @@ import AudioEngine from 'scratch-audio';
import {BitmapAdapter} from 'scratch-svg-renderer';
import Question from './question';
import {VariableMonitor} from './monitor';
import {ListMonitor, VariableMonitor} from './monitor';
import styles from './style.css';
class Scaffolding {
@@ -154,22 +154,24 @@ class Scaffolding {
}
_onmonitorsupdate (monitors) {
// for (const key of this._monitors.keys()) {
// if (!monitors.has(key)) {
// console.log("remove", key);
// const monitor = this._monitors.get(key);
// monitor.destroy();
// this._monitors.delete(key);
// }
// }
for (const monitor of monitors.valueSeq()) {
const id = monitor.get('id');
for (const monitorData of monitors.valueSeq()) {
const id = monitorData.get('id');
if (!this._monitors.has(id)) {
this._monitors.set(id, new VariableMonitor(this, monitor));
const visible = monitorData.get('visible');
if (!visible) {
// Would be a waste to make it now
continue;
}
// TODO: add to DOM in same order as appears in list
const mode = monitorData.get('mode');
if (mode === 'list') {
this._monitors.set(id, new ListMonitor(this, monitorData));
} else {
this._monitors.set(id, new VariableMonitor(this, monitorData));
}
}
const mon = this._monitors.get(id);
mon.update(monitor);
const monitorObject = this._monitors.get(id);
monitorObject.update(monitorData);
}
}
+146 -19
View File
@@ -1,6 +1,6 @@
import styles from './style.css';
class VariableMonitor {
class Monitor {
constructor (parent, monitor) {
this.parent = parent;
@@ -14,6 +14,37 @@ class VariableMonitor {
this.root.className = styles.monitorRoot;
this.root.setAttribute('opcode', this.opcode);
this.parent._monitorOverlay.appendChild(this.root);
}
getLabel () {
let base;
if (Object.keys(this.params).length) {
base = this.params[Object.keys(this.params)[0]];
} else {
base = this.id;
}
if (this.spriteName) {
return `${this.spriteName}: ${base}`;
}
return base;
}
update (monitor) {
// TODO: don't touch if not changed
const x = monitor.get('x');
const y = monitor.get('y');
const visible = monitor.get('visible');
this.root.style.transform = `translate(${x}px, ${y}px)`;
this.root.style.display = visible ? '' : 'none';
}
}
class VariableMonitor extends Monitor {
constructor (parent, monitor) {
super(parent, monitor);
this.inner = document.createElement('div');
this.inner.className = styles.monitorInner;
@@ -34,33 +65,129 @@ class VariableMonitor {
this.parent._monitorOverlay.appendChild(this.root);
}
getLabel () {
let base;
if (Object.keys(this.params).length) {
base = this.params[Object.keys(this.params)[0]];
} else {
base = this.id;
}
update (monitor) {
const value = monitor.get('value');
this.value.textContent = value;
}
}
if (this.spriteName) {
return `${this.spriteName}: ${base}`;
const ROW_HEIGHT = 20;
class Row {
constructor () {
this._index = -1;
this._value = '';
this._visible = true;
this.root = document.createElement('div');
this.root.className = styles.monitorRowRoot;
this.indexEl = document.createElement('div');
this.indexEl.className = styles.monitorRowIndex;
this.valueEl = document.createElement('div');
this.valueEl.className = styles.monitorRowValue;
this.root.appendChild(this.indexEl);
this.root.appendChild(this.valueEl);
}
setIndex (index) {
if (this._index !== index) {
this._index = index;
this.root.style.transform = `translateY(${index * ROW_HEIGHT}px)`;
this.indexEl.textContent = index + 1;
}
return base;
}
setValue (value) {
if (this._value !== value) {
this._value = value;
this.valueEl.textContent = value;
}
}
setVisible (visible) {
if (this._visible !== visible) {
this._visible = visible;
this.root.style.display = visible ? '' : 'none';
}
}
}
class ListMonitor extends Monitor {
constructor (parent, monitor) {
super(parent, monitor);
this.rows = [];
this.scrollTop = 0;
this.rowsOuter = document.createElement('div');
this.rowsOuter.className = styles.monitorRowsOuter;
this.rowsInner = document.createElement('div');
this.rowsInner.className = styles.monitorRowsInner;
this.rowsInner.addEventListener('scroll', this._onscroll.bind(this));
this.endPoint = document.createElement('div');
this.endPoint.className = styles.monitorRowsEndpoint;
this.rowsInner.appendChild(this.endPoint);
this.rowsOuter.appendChild(this.rowsInner);
this.root.appendChild(this.rowsOuter);
}
_onscroll (e) {
this.scrollTop = e.target.scrollTop;
this.updateValue(this.value);
}
getRow () {
if (this.rows.length) {
return this.rows.pop();
}
return new Row();
}
update (monitor) {
const x = monitor.get('x');
const y = monitor.get('y');
const value = monitor.get('value');
const visible = monitor.get('visible');
super.update(monitor);
this.root.style.transform = `translate(${x}px, ${y}px)`;
this.value.textContent = value;
this.width = monitor.get('width') || 200;
this.height = monitor.get('height') || 200;
this.root.style.width = `${this.width}px`;
this.root.style.height = `${this.height}px`;
this.root.style.display = visible ? '' : 'none';
this.value = monitor.get('value');
this.updateValue(this.value);
}
updateValue (value) {
this.endPoint.style.transform = `translateY(${value.length * ROW_HEIGHT}px)`;
let startIndex = Math.floor(this.scrollTop / ROW_HEIGHT) - 5;
if (startIndex < 0) startIndex = 0;
let endIndex = Math.ceil((this.scrollTop + this.height) / ROW_HEIGHT) + 5;
if (endIndex > value.length - 1) endIndex = value.length - 1;
const rowsNeeded = endIndex - startIndex + 1;
while (this.rows.length < rowsNeeded) {
const row = new Row();
this.rows.push(row);
this.rowsInner.appendChild(row.root);
}
for (var i = 0; i < rowsNeeded; i++) {
const row = this.rows[i];
const rowIndex = i + startIndex;
row.setIndex(rowIndex);
row.setValue(value[rowIndex]);
row.setVisible(true);
}
while (i < this.rows.length) {
const row = this.rows[i];
row.setVisible(false);
i++;
}
}
}
export {
VariableMonitor
VariableMonitor,
ListMonitor
};
+30 -1
View File
@@ -66,7 +66,6 @@
border: 1px solid hsla(0, 0%, 0%, 0.15);
border-radius: 4px;
font-size: 12px;
user-select: none;
overflow: hidden;
}
.monitor-inner {
@@ -98,3 +97,33 @@
.monitor-root[opcode^="data_"] .monitor-value {
background-color: rgb(255, 140, 26);
}
.monitor-rows-outer {
height: 200px;
}
.monitor-rows-inner {
height: 100%;
overflow-y: auto;
position: relative;
}
.monitor-rows-endpoint {
position: absolute;
top: 0;
left: 0;
width: 1px;
height: 1px;
pointer-events: none;
}
.monitor-row-root {
position: absolute;
top: 0;
left: 0;
display: flex;
}
.monitor-row-index {
}
.monitor-row-value {
}