diff --git a/src/components/monitor/monitor.jsx b/src/components/monitor/monitor.jsx index edd0fb0439a39ab0ccc080c67aa6cd068e603a3a..54b1ebe8a6cb6e3a20b78dadfc8fe7fd3a477bb7 100644 --- a/src/components/monitor/monitor.jsx +++ b/src/components/monitor/monitor.jsx @@ -7,7 +7,7 @@ const styles = require('./monitor.css'); const categories = { data: '#FF8C1A', sensing: '#5CB1D6', - sounds: '#CF63CF', + sound: '#CF63CF', looks: '#9966FF', motion: '#4C97FF' }; diff --git a/src/lib/monitor-adapter.js b/src/lib/monitor-adapter.js new file mode 100644 index 0000000000000000000000000000000000000000..8dcc802a48e9414062431e6ca9137f8d2eef6cde --- /dev/null +++ b/src/lib/monitor-adapter.js @@ -0,0 +1,26 @@ +/** + * Convert monitors from VM format to what the GUI needs to render. + * - Convert opcode to a label and a category + * - Add missing XY position data if needed + */ +const OpcodeLabels = require('../lib/opcode-labels.js'); + +const PADDING = 5; +const MONITOR_HEIGHT = 23; + +const isUndefined = a => typeof a === 'undefined'; + +module.exports = function ({id, opcode, params, value, x, y}, monitorIndex) { + let {label, category, labelFn} = OpcodeLabels(opcode); + + // Use labelFn if provided for dynamic labelling (e.g. variables) + if (!isUndefined(labelFn)) label = labelFn(params); + + // Simple layout if x or y are undefined + // @todo scratch2 has a more complex layout behavior we may want to adopt + // @todo e.g. this does not work well when monitors have already been moved + if (isUndefined(x)) x = PADDING; + if (isUndefined(y)) y = PADDING + (monitorIndex * (PADDING + MONITOR_HEIGHT)); + + return {id, label, category, value, x, y}; +}; diff --git a/src/lib/opcode-labels.js b/src/lib/opcode-labels.js new file mode 100644 index 0000000000000000000000000000000000000000..bebe14743630de643343e9b88318b88fdf312b07 --- /dev/null +++ b/src/lib/opcode-labels.js @@ -0,0 +1,75 @@ +const opcodeMap = { + // Motion + motion_direction: { + category: 'motion', + label: 'direction' + }, + motion_xposition: { + category: 'motion', + label: 'x position' + }, + motion_yposition: { + category: 'motion', + label: 'y position' + }, + + // Looks + looks_size: { + category: 'looks', + label: 'size' + }, + looks_costumeorder: { + category: 'looks', + label: 'costume #' + }, + looks_backdroporder: { + category: 'looks', + label: 'backdrop #' + }, + looks_backdropname: { + category: 'looks', + label: 'backdrop name' + }, + + // Data + data_variable: { + category: 'data', + labelFn: params => params.VARIABLE + }, + + // Sound + sound_volume: { + category: 'sound', + label: 'volume' + }, + sound_tempo: { + category: 'sound', + label: 'tempo' + }, + + // Sensing + sensing_loudness: { + category: 'sensing', + label: 'loudness' + }, + sensing_of: { + category: 'sensing', + labelFn: params => `${params.PROPERTY} of ${params.OBJECT}` + }, + sensing_current: { + category: 'sensing', + labelFn: params => params.CURRENTMENU.toLowerCase() + }, + sensing_timer: { + category: 'sensing', + label: 'timer' + } +}; + +module.exports = function (opcode) { + if (opcode in opcodeMap) return opcodeMap[opcode]; + return { + category: 'data', + label: opcode + }; +}; diff --git a/src/reducers/monitors.js b/src/reducers/monitors.js index e8b4fa947eee4862f24be5ea8727caef6793fe5c..18e9529f4ad417645101a5cc85ed60b6b8adecf0 100644 --- a/src/reducers/monitors.js +++ b/src/reducers/monitors.js @@ -1,3 +1,5 @@ +const monitorAdapter = require('../lib/monitor-adapter.js'); + const UPDATE_MONITORS = 'scratch-gui/monitors/UPDATE_MONITORS'; const initialState = []; @@ -6,7 +8,7 @@ const reducer = function (state, action) { if (typeof state === 'undefined') state = initialState; switch (action.type) { case UPDATE_MONITORS: - return [...action.monitors]; + return action.monitors.map(monitorAdapter); default: return state; }