From 603fade7886b34f218a00aaed8460294e9d5d1fa Mon Sep 17 00:00:00 2001
From: Ray Schamp <ray@scratch.mit.edu>
Date: Mon, 19 Sep 2016 19:23:40 -0400
Subject: [PATCH] Add default toolbox categories

Also make the toolbox actually get used by scratch-blocks, and update the import of scratch-blocks to use the new shimming method.
---
 src/components/blocks.js  |  26 +-
 src/components/gui.js     |  10 +-
 src/components/toolbox.js | 674 +++++++++++++++++++++++++++++++++++++-
 3 files changed, 693 insertions(+), 17 deletions(-)

diff --git a/src/components/blocks.js b/src/components/blocks.js
index 0474480fc..96516131b 100644
--- a/src/components/blocks.js
+++ b/src/components/blocks.js
@@ -1,33 +1,31 @@
 const defaultsDeep = require('lodash.defaultsdeep');
 const React = require('react');
-const ScratchBlocks = require('scratch-blocks/blocks_compressed_vertical');
+const ScratchBlocks = require('scratch-blocks');
 
 class Blocks extends React.Component {
-    constructor (props) {
-        super(props);
-        this.mountBlocks = this.mountBlocks.bind(this);
-    }
-    mountBlocks (component) {
-        this.workspace = ScratchBlocks.inject(
-            component,
-            defaultsDeep({}, this.props.options, Blocks.defaultOptions)
-        );
-        if (this.props.vm) {
-            this.workspace.addChangeListener(this.props.vm.blockListener);
+    componentDidUpdate (prevProps) {
+        if (!prevProps.options.toolbox && this.props.options.toolbox) {
+            let workspaceConfig = defaultsDeep({}, Blocks.defaultOptions, this.props.options);
+            this.workspace = ScratchBlocks.inject(this.refs.scratchBlocks, workspaceConfig);
+            if (this.props.vm) {
+                this.workspace.addChangeListener(this.props.vm.blockListener);
+            }
         }
     }
     render () {
         return (
             <div
                 className="scratch-blocks"
-                ref={this.mountBlocks} />
+                ref="scratchBlocks"
+            />
         );
     }
 }
 
 Blocks.propTypes = {
     options: React.PropTypes.shape({
-        toolbox: React.PropTypes.element,
+        // The toolbox is actually an element, but React doesn't agree :/
+        toolbox: React.PropTypes.object,
         media: React.PropTypes.string,
         zoom: React.PropTypes.shape({
             controls: React.PropTypes.boolean,
diff --git a/src/components/gui.js b/src/components/gui.js
index 614884d0f..2a8867235 100644
--- a/src/components/gui.js
+++ b/src/components/gui.js
@@ -4,13 +4,19 @@ const Blocks = require('./blocks');
 const Toolbox = require('./toolbox');
 
 class GUI extends React.Component {
+    constructor (props) {
+        this.state = {};
+    }
+    componentDidMount () {
+        this.setState({toolbox: this._toolbox});
+    }
     render () {
         return (
             <div className="scratch-gui">
-                <Toolbox ref={toolbox => this.toolbox = toolbox} />
+                <Toolbox toolboxRef={(toolbox) => this._toolbox = toolbox} />
                 <Blocks
                     options={{
-                        toolbox: this.toolbox
+                        toolbox: this.state.toolbox
                     }}
                     vm={this.props.vm}
                 />
diff --git a/src/components/toolbox.js b/src/components/toolbox.js
index 04d31ebbc..5f49cf7f9 100644
--- a/src/components/toolbox.js
+++ b/src/components/toolbox.js
@@ -3,9 +3,681 @@ const React = require('react');
 class Toolbox extends React.Component {
     render () {
         return (
-            <div className="scratch-toolbox" />
+            <xml
+                className="scratch-toolbox"
+                style={{ display: 'none' }}
+                ref={this.props.toolboxRef}
+            >
+                {this.props.children}
+            </xml>
         );
     }
 }
 
+Toolbox.propTypes = {
+    children: React.PropTypes.node,
+    toolboxRef: React.PropTypes.func
+};
+
+Toolbox.defaultProps = {
+    toolboxRef: function () {},
+    children: [
+        <category is key="motion" name="Motion" colour="#4C97FF">
+            <block type="motion_movesteps">
+                <value name="STEPS">
+                    <shadow type="math_number">
+                        <field name="NUM">10</field>
+                    </shadow>
+                </value>
+            </block>
+            <block type="motion_turnright">
+                <value name="DEGREES">
+                    <shadow type="math_number">
+                        <field name="NUM">15</field>
+                    </shadow>
+                </value>
+            </block>
+            <block type="motion_turnleft">
+                <value name="DEGREES">
+                    <shadow type="math_number">
+                        <field name="NUM">15</field>
+                    </shadow>
+                </value>
+            </block>
+            <block type="motion_pointindirection">
+                <value name="DIRECTION">
+                    <shadow type="math_angle">
+                        <field name="NUM">90</field>
+                    </shadow>
+                </value>
+            </block>
+            <block type="motion_pointtowards">
+                <value name="TOWARDS">
+                    <shadow type="motion_pointtowards_menu">
+                    </shadow>
+                </value>
+            </block>
+            <block type="motion_gotoxy">
+                <value name="X">
+                    <shadow type="math_number">
+                        <field name="NUM">0</field>
+                    </shadow>
+                </value>
+                <value name="Y">
+                    <shadow type="math_number">
+                        <field name="NUM">0</field>
+                    </shadow>
+                </value>
+            </block>
+            <block type="motion_goto">
+                <value name="TO">
+                    <shadow type="motion_goto_menu">
+                    </shadow>
+                </value>
+            </block>
+            <block type="motion_glidesecstoxy">
+                <value name="SECS">
+                    <shadow type="math_number">
+                        <field name="NUM">1</field>
+                    </shadow>
+                </value>
+                <value name="X">
+                    <shadow type="math_number">
+                        <field name="NUM">0</field>
+                    </shadow>
+                </value>
+                <value name="Y">
+                    <shadow type="math_number">
+                        <field name="NUM">0</field>
+                    </shadow>
+                </value>
+            </block>
+            <block type="motion_changexby">
+                <value name="DX">
+                    <shadow type="math_number">
+                        <field name="NUM">10</field>
+                    </shadow>
+                </value>
+            </block>
+            <block type="motion_setx">
+                <value name="X">
+                    <shadow type="math_number">
+                        <field name="NUM">0</field>
+                    </shadow>
+                </value>
+            </block>
+            <block type="motion_changeyby">
+                <value name="DY">
+                    <shadow type="math_number">
+                        <field name="NUM">10</field>
+                    </shadow>
+                </value>
+            </block>
+            <block type="motion_sety">
+                <value name="Y">
+                    <shadow type="math_number">
+                        <field name="NUM">0</field>
+                    </shadow>
+                </value>
+            </block>
+            <block type="motion_ifonedgebounce"></block>
+            <block type="motion_setrotationstyle">
+                <value name="STYLE">
+                    <shadow type="motion_setrotationstyle_menu"></shadow>
+                </value>
+            </block>
+            <block type="motion_xposition"></block>
+            <block type="motion_yposition"></block>
+            <block type="motion_direction"></block>
+        </category>,
+        <category is key="looks" name="Looks" colour="#9966FF">
+            <block type="looks_sayforsecs">
+                <value name="MESSAGE">
+                    <shadow type="text">
+                        <field name="TEXT">Hello!</field>
+                    </shadow>
+                </value>
+                <value name="SECS">
+                    <shadow type="math_number">
+                        <field name="NUM">2</field>
+                    </shadow>
+                </value>
+            </block>
+            <block type="looks_say">
+                <value name="MESSAGE">
+                    <shadow type="text">
+                        <field name="TEXT">Hello!</field>
+                    </shadow>
+                </value>
+            </block>
+            <block type="looks_thinkforsecs">
+                <value name="MESSAGE">
+                    <shadow type="text">
+                        <field name="TEXT">Hmm...</field>
+                    </shadow>
+                </value>
+                <value name="SECS">
+                    <shadow type="math_number">
+                        <field name="NUM">2</field>
+                    </shadow>
+                </value>
+            </block>
+            <block type="looks_think">
+                <value name="MESSAGE">
+                    <shadow type="text">
+                        <field name="TEXT">Hmm...</field>
+                    </shadow>
+                </value>
+            </block>
+            <block type="looks_show"></block>
+            <block type="looks_hide"></block>
+            <block type="looks_switchcostumeto">
+                <value name="COSTUME">
+                    <shadow type="looks_costume"></shadow>
+                </value>
+                </block>
+            <block type="looks_nextcostume"></block>
+            <block type="looks_nextbackdrop"></block>
+            <block type="looks_switchbackdropto">
+                <value name="BACKDROP">
+                    <shadow type="looks_backdrops"></shadow>
+                </value>
+                </block>
+            <block type="looks_switchbackdroptoandwait">
+                <value name="BACKDROP">
+                    <shadow type="looks_backdrops"></shadow>
+                </value>
+                </block>
+            <block type="looks_changeeffectby">
+                <value name="EFFECT">
+                    <shadow type="looks_effectmenu"></shadow>
+                </value>
+                <value name="CHANGE">
+                    <shadow type="math_number">
+                        <field name="NUM">10</field>
+                    </shadow>
+                </value>
+            </block>
+            <block type="looks_seteffectto">
+                <value name="EFFECT">
+                    <shadow type="looks_effectmenu"></shadow>
+                </value>
+                <value name="VALUE">
+                    <shadow type="math_number">
+                        <field name="NUM">10</field>
+                    </shadow>
+                </value>
+            </block>
+            <block type="looks_cleargraphiceffects"></block>
+            <block type="looks_changesizeby">
+                <value name="CHANGE">
+                    <shadow type="math_number">
+                        <field name="NUM">10</field>
+                    </shadow>
+                </value>
+            </block>
+            <block type="looks_setsizeto">
+                <value name="SIZE">
+                    <shadow type="math_number">
+                        <field name="NUM">100</field>
+                    </shadow>
+                </value>
+            </block>
+            <block type="looks_gotofront"></block>
+            <block type="looks_gobacklayers">
+                <value name="NUM">
+                    <shadow type="math_integer">
+                        <field name="NUM">1</field>
+                    </shadow>
+                </value>
+            </block>
+            <block type="looks_costumeorder"></block>
+            <block type="looks_backdroporder"></block>
+            <block type="looks_backdropname"></block>
+            <block type="looks_size"></block>
+        </category>,
+        <category is key="sound" name="Sound" colour="#D65CD6">
+            <block type="sound_play">
+                <value name="SOUND_MENU">
+                    <shadow type="sound_sounds_option"></shadow>
+                </value>
+            </block>
+            <block type="sound_playuntildone">
+                <value name="SOUND_MENU">
+                    <shadow type="sound_sounds_option"></shadow>
+                </value>
+            </block>
+            <block type="sound_stopallsounds"></block>
+            <block type="sound_playdrumforbeats">
+                <value name="DRUMTYPE">
+                    <shadow type="math_number">
+                        <field name="NUM">1</field>
+                    </shadow>
+                </value>
+                <value name="BEATS">
+                    <shadow type="math_number">
+                        <field name="NUM">0.25</field>
+                    </shadow>
+                </value>
+            </block>
+            <block type="sound_restforbeats">
+                <value name="BEATS">
+                    <shadow type="math_number">
+                        <field name="NUM">0.25</field>
+                    </shadow>
+                </value>
+            </block>
+            <block type="sound_playnoteforbeats">
+                <value name="NOTE">
+                    <shadow type="math_number">
+                        <field name="NUM">1</field>
+                    </shadow>
+                </value>
+                <value name="BEATS">
+                    <shadow type="math_number">
+                        <field name="NUM">0.5</field>
+                    </shadow>
+                </value>
+            </block>
+            <block type="sound_setinstrumentto">
+                <value name="INSTRUMENT">
+                    <shadow type="math_number">
+                        <field name="NUM">1</field>
+                    </shadow>
+                </value>
+            </block>
+            <block type="sound_changevolumeby">
+                <value name="VOLUME">
+                    <shadow type="math_number">
+                        <field name="NUM">-10</field>
+                    </shadow>
+                </value>
+            </block>
+            <block type="sound_setvolumeto">
+                <value name="VOLUME">
+                    <shadow type="math_number">
+                        <field name="NUM">100</field>
+                    </shadow>
+                </value>
+            </block>
+            <block type="sound_volume"></block>
+            <block type="sound_changetempoby">
+                <value name="TEMPO">
+                    <shadow type="math_number">
+                        <field name="NUM">20</field>
+                    </shadow>
+                </value>
+            </block>
+            <block type="sound_settempotobpm">
+                <value name="TEMPO">
+                    <shadow type="math_number">
+                        <field name="NUM">60</field>
+                    </shadow>
+                </value>
+            </block>
+            <block type="sound_tempo"></block>
+        </category>,
+        <category is key="pen" name="Pen" colour="#00B295">
+            <block type="pen_clear"></block>
+            <block type="pen_stamp"></block>
+            <block type="pen_pendown"></block>
+            <block type="pen_penup"></block>
+            <block type="pen_setpencolortocolor">
+                <value name="COLOR">
+                    <shadow type="colour_picker">
+                    </shadow>
+                </value>
+            </block>
+            <block type="pen_changepencolorby">
+                <value name="COLOR">
+                    <shadow type="math_number">
+                        <field name="NUM">10</field>
+                    </shadow>
+                </value>
+            </block>
+            <block type="pen_setpencolortonum">
+                <value name="COLOR">
+                    <shadow type="math_number">
+                        <field name="NUM">0</field>
+                    </shadow>
+                </value>
+            </block>
+            <block type="pen_changepenshadeby">
+                <value name="SHADE">
+                    <shadow type="math_number">
+                        <field name="NUM">10</field>
+                    </shadow>
+                </value>
+            </block>
+            <block type="pen_setpenshadeto">
+                <value name="SHADE">
+                    <shadow type="math_number">
+                        <field name="NUM">50</field>
+                    </shadow>
+                </value>
+            </block>
+            <block type="pen_changepensizeby">
+                <value name="SIZE">
+                    <shadow type="math_number">
+                        <field name="NUM">1</field>
+                    </shadow>
+                </value>
+            </block>
+            <block type="pen_setpensizeto">
+                <value name="SIZE">
+                    <shadow type="math_number">
+                        <field name="NUM">1</field>
+                    </shadow>
+                </value>
+            </block>
+        </category>,
+        <category is key="data" name="Data" colour="#FF8C1A" custom="VARIABLE"></category>,
+        <category is key="events" name="Events" colour="#FFD500">
+            <block type="event_whenflagclicked"></block>
+            <block type="event_whenkeypressed">
+                <value name="KEY_OPTION">
+                    <shadow type="event_keyoptions"></shadow>
+                </value>
+            </block>
+            <block type="event_whenthisspriteclicked"></block>
+            <block type="event_whenbackdropswitchesto">
+                <value name="BACKDROP">
+                    <shadow type="event_backdrops"></shadow>
+                </value>
+            </block>
+            <block type="event_whengreaterthan">
+                <value name="WHENGREATERTHANMENU">
+                    <shadow type="event_whengreaterthanmenu"></shadow>
+                </value>
+                <value name="VALUE">
+                    <shadow type="math_number">
+                        <field name="NUM">10</field>
+                    </shadow>
+                </value>
+            </block>
+            <block type="event_whenbroadcastreceived">
+                <value name="BROADCAST_OPTION">
+                    <shadow type="event_broadcast_menu"></shadow>
+                </value>
+            </block>
+            <block type="event_broadcast">
+                <value name="BROADCAST_OPTION">
+                    <shadow type="event_broadcast_menu"></shadow>
+                </value>
+            </block>
+            <block type="event_broadcastandwait">
+                <value name="BROADCAST_OPTION">
+                    <shadow type="event_broadcast_menu"></shadow>
+                </value>
+            </block>
+        </category>,
+        <category is key="control" name="Control" colour="#FFAB19">
+            <block type="control_wait">
+                <value name="DURATION">
+                    <shadow type="math_positive_number">
+                        <field name="NUM">1</field>
+                    </shadow>
+                </value>
+            </block>
+            <block type="control_repeat">
+                <value name="TIMES">
+                    <shadow type="math_whole_number">
+                        <field name="NUM">10</field>
+                    </shadow>
+                </value>
+            </block>
+            <block type="control_forever"></block>
+            <block type="control_if"></block>
+            <block type="control_if_else"></block>
+            <block type="control_wait_until"></block>
+            <block type="control_repeat_until"></block>
+            <block type="control_stop">
+                <value name="STOP_OPTION">
+                    <shadow type="control_stop_menu"></shadow>
+                </value>
+            </block>
+            <block type="control_start_as_clone"></block>
+            <block type="control_create_clone_of">
+                <value name="CLONE_OPTION">
+                    <shadow type="control_create_clone_of_menu"></shadow>
+                </value>
+            </block>
+            <block type="control_delete_this_clone"></block>
+        </category>,
+        <category is key="sensing" name="Sensing" colour="#4CBFE6">
+            <block type="sensing_touchingobject">
+                <value name="TOUCHINGOBJECTMENU">
+                    <shadow type="sensing_touchingobjectmenu"></shadow>
+                </value>
+            </block>
+            <block type="sensing_touchingcolor">
+                <value name="COLOR">
+                    <shadow type="colour_picker"></shadow>
+                </value>
+            </block>
+            <block type="sensing_coloristouchingcolor">
+                <value name="COLOR">
+                    <shadow type="colour_picker"></shadow>
+                </value>
+                <value name="COLOR2">
+                    <shadow type="colour_picker"></shadow>
+                </value>
+            </block>
+            <block type="sensing_distanceto">
+                <value name="DISTANCETOMENU">
+                    <shadow type="sensing_distancetomenu"></shadow>
+                </value>
+            </block>
+            <block type="sensing_askandwait">
+                <value name="QUESTION">
+                    <shadow type="text">
+                        <field name="TEXT">What's your name?</field>
+                    </shadow>
+                </value>
+            </block>
+            <block type="sensing_answer"></block>
+            <block type="sensing_keypressed">
+                <value name="KEY_OPTION">
+                    <shadow type="sensing_keyoptions"></shadow>
+                </value>
+            </block>
+            <block type="sensing_mousedown"></block>
+            <block type="sensing_mousex"></block>
+            <block type="sensing_mousey"></block>
+            <block type="sensing_loudness"></block>
+            <block type="sensing_videoon">
+                <value name="VIDEOONMENU1">
+                    <shadow type="sensing_videoonmenuone"></shadow>
+                </value>
+                <value name="VIDEOONMENU2">
+                    <shadow type="sensing_videoonmenutwo"></shadow>
+                </value>
+            </block>
+            <block type="sensing_videotoggle">
+                <value name="VIDEOTOGGLEMENU">
+                    <shadow type="sensing_videotogglemenu"></shadow>
+                </value>
+            </block>
+            <block type="sensing_setvideotransparency">
+            <value name="TRANSPARENCY">
+                <shadow type="math_number">
+                    <field name="NUM">50</field>
+                </shadow>
+            </value>
+            </block>
+            <block type="sensing_timer"></block>
+            <block type="sensing_resettimer"></block>
+            <block type="sensing_current">
+                <value name="CURRENTMENU">
+                    <shadow type="sensing_currentmenu"></shadow>
+                </value>
+            </block>
+            <block type="sensing_dayssince2000"></block>
+            <block type="sensing_username"></block>
+        </category>,
+        <category is key="operators" name="Operators" colour="#40BF4A">
+            <block type="operator_add">
+                <value name="NUM1">
+                    <shadow type="math_number">
+                        <field name="NUM"></field>
+                    </shadow>
+                </value>
+                <value name="NUM2">
+                    <shadow type="math_number">
+                        <field name="NUM"></field>
+                    </shadow>
+                </value>
+            </block>
+            <block type="operator_subtract">
+                <value name="NUM1">
+                    <shadow type="math_number">
+                        <field name="NUM"></field>
+                    </shadow>
+                </value>
+                <value name="NUM2">
+                    <shadow type="math_number">
+                        <field name="NUM"></field>
+                    </shadow>
+                </value>
+            </block>
+            <block type="operator_multiply">
+                <value name="NUM1">
+                    <shadow type="math_number">
+                        <field name="NUM"></field>
+                    </shadow>
+                </value>
+                <value name="NUM2">
+                    <shadow type="math_number">
+                        <field name="NUM"></field>
+                    </shadow>
+                </value>
+            </block>
+            <block type="operator_divide">
+                <value name="NUM1">
+                    <shadow type="math_number">
+                        <field name="NUM"></field>
+                    </shadow>
+                </value>
+                <value name="NUM2">
+                    <shadow type="math_number">
+                        <field name="NUM"></field>
+                    </shadow>
+                </value>
+            </block>
+            <block type="operator_random">
+                <value name="FROM">
+                    <shadow type="math_number">
+                        <field name="NUM">1</field>
+                    </shadow>
+                </value>
+                <value name="TO">
+                    <shadow type="math_number">
+                        <field name="NUM">10</field>
+                    </shadow>
+                </value>
+            </block>
+            <block type="operator_lt">
+                <value name="OPERAND1">
+                    <shadow type="text">
+                        <field name="TEXT"></field>
+                    </shadow>
+                </value>
+                <value name="OPERAND2">
+                    <shadow type="text">
+                        <field name="TEXT"></field>
+                    </shadow>
+                </value>
+            </block>
+            <block type="operator_equals">
+                <value name="OPERAND1">
+                    <shadow type="text">
+                        <field name="TEXT"></field>
+                    </shadow>
+                </value>
+                <value name="OPERAND2">
+                    <shadow type="text">
+                        <field name="TEXT"></field>
+                    </shadow>
+                </value>
+            </block>
+            <block type="operator_gt">
+                <value name="OPERAND1">
+                    <shadow type="text">
+                        <field name="TEXT"></field>
+                    </shadow>
+                </value>
+                <value name="OPERAND2">
+                    <shadow type="text">
+                        <field name="TEXT"></field>
+                    </shadow>
+                </value>
+            </block>
+            <block type="operator_and"></block>
+            <block type="operator_or"></block>
+            <block type="operator_not"></block>
+            <block type="operator_join">
+                <value name="STRING1">
+                    <shadow type="text">
+                        <field name="TEXT">hello</field>
+                    </shadow>
+                </value>
+                <value name="STRING2">
+                    <shadow type="text">
+                        <field name="TEXT">world</field>
+                    </shadow>
+                </value>
+            </block>
+            <block type="operator_letter_of">
+                <value name="LETTER">
+                    <shadow type="math_whole_number">
+                        <field name="NUM">1</field>
+                    </shadow>
+                </value>
+                <value name="STRING">
+                    <shadow type="text">
+                        <field name="TEXT">world</field>
+                    </shadow>
+                </value>
+            </block>
+            <block type="operator_length">
+                <value name="STRING">
+                    <shadow type="text">
+                        <field name="TEXT">world</field>
+                    </shadow>
+                </value>
+            </block>
+            <block type="operator_mod">
+                <value name="NUM1">
+                    <shadow type="math_number">
+                        <field name="NUM"></field>
+                    </shadow>
+                </value>
+                <value name="NUM2">
+                    <shadow type="math_number">
+                        <field name="NUM"></field>
+                    </shadow>
+                </value>
+            </block>
+            <block type="operator_round">
+                <value name="NUM">
+                    <shadow type="math_number">
+                        <field name="NUM"></field>
+                    </shadow>
+                </value>
+            </block>
+            <block type="operator_mathop">
+                <value name="OPERATOR">
+                    <shadow type="operator_mathop_menu"></shadow>
+                </value>
+                <value name="NUM">
+                    <shadow type="math_number">
+                        <field name="NUM"></field>
+                    </shadow>
+                </value>
+            </block>
+        </category>,
+        <category is key="more" name="More Blocks" colour="#FF6680"></category>
+    ]
+};
+
 module.exports = Toolbox;
-- 
GitLab