From 0dd4623523ea4ef39db068c65578a75c1ecddb1a Mon Sep 17 00:00:00 2001 From: Karishma Chadha <kchadha@scratch.mit.edu> Date: Tue, 3 Jul 2018 23:03:09 -0400 Subject: [PATCH] Allow specifying variables as local vs. global. Pass var names from VM to scratch-blocks for checking for conflicts in all sprites when attempting to create a global var. --- src/components/prompt/prompt.css | 20 +++++-- src/components/prompt/prompt.jsx | 89 +++++++++++++++++++++++++------- src/containers/blocks.jsx | 9 +++- src/containers/prompt.jsx | 12 ++++- 4 files changed, 103 insertions(+), 27 deletions(-) diff --git a/src/components/prompt/prompt.css b/src/components/prompt/prompt.css index 34a8f5a21..78e3ecb27 100644 --- a/src/components/prompt/prompt.css +++ b/src/components/prompt/prompt.css @@ -15,7 +15,7 @@ margin: 0 0 0.75rem; } -.input { +.variable-name-text-input { margin-bottom: 1.5rem; width: 100%; border: 1px solid $ui-black-transparent; @@ -26,6 +26,20 @@ font-size: .875rem; } +.info-message { + font-weight: normal; + font-size: .875rem; + margin-bottom: 1.5rem; + text-align: center; +} + +.options-row { + display: flex; + font-weight: normal; + justify-content: space-between; + margin-bottom: 1.5rem; +} + .button-row { font-weight: bolder; text-align: right; @@ -58,10 +72,6 @@ margin: 0 0 1rem; } -.hide-more-options { - display: none; -} - .more-options-accordion { width: 60%; margin: 0 auto; diff --git a/src/components/prompt/prompt.jsx b/src/components/prompt/prompt.jsx index 4feffeb0c..20e6af85e 100644 --- a/src/components/prompt/prompt.jsx +++ b/src/components/prompt/prompt.jsx @@ -11,10 +11,26 @@ import styles from './prompt.css'; import dropdownIcon from './icon--dropdown-caret.svg'; const messages = defineMessages({ + forAllSpritesMessage: { + defaultMessage: 'For all sprites', + description: 'Option message when creating a variable for making it available to all sprites', + id: 'gui.gui.variableScopeOptionAllSprites' + }, + forThisSpriteMessage: { + defaultMessage: 'For this sprite only', + description: 'Option message when creating a varaible for making it only available to the current sprite', + id: 'gui.gui.variableScopeOptionSpriteOnly' + }, moreOptionsMessage: { defaultMessage: 'More Options', description: 'Dropdown message for variable/list options', id: 'gui.gui.variablePrompt' + }, + availableToAllSpritesMessage: { + defaultMessage: 'This variable will be available to all sprites.', + description: 'A message that displays in a variable modal when the stage is selected indicating ' + + 'that the variable being created will available to all sprites.', + id: 'gui.gui.variablePromptAllSpritesMessage' } }); @@ -31,29 +47,64 @@ const PromptComponent = props => ( <Box> <input autoFocus - className={styles.input} + className={styles.variableNameTextInput} placeholder={props.placeholder} onChange={props.onChange} onKeyPress={props.onKeyPress} /> </Box> - <Box className={props.showMoreOptions ? styles.moreOptions : styles.hideMoreOptions}> - <ComingSoonTooltip - className={styles.moreOptionsAccordion} - place="right" - tooltipId="variable-options-accordion" - > - <div className={styles.moreOptionsText}> - <FormattedMessage - {...messages.moreOptionsMessage} - /> - <img - className={styles.moreOptionsIcon} - src={dropdownIcon} - /> - </div> - </ComingSoonTooltip> - </Box> + {props.showMoreOptions ? + <div> + {props.isStage ? + <div className={styles.infoMessage}> + <FormattedMessage + {...messages.availableToAllSpritesMessage} + /> + </div> : + <Box className={styles.optionsRow}> + <label> + <input + checked + name="variableScopeOption" + type="radio" + value="global" + onChange={props.onOptionSelection} + /> + <FormattedMessage + {...messages.forAllSpritesMessage} + /> + </label> + <label> + <input + name="variableScopeOption" + type="radio" + value="local" + onChange={props.onOptionSelection} + /> + <FormattedMessage + {...messages.forThisSpriteMessage} + /> + </label> + </Box>} + <Box className={styles.moreOptions}> + <ComingSoonTooltip + className={styles.moreOptionsAccordion} + place="right" + tooltipId="variable-options-accordion" + > + <div className={styles.moreOptionsText}> + <FormattedMessage + {...messages.moreOptionsMessage} + /> + <img + className={styles.moreOptionsIcon} + src={dropdownIcon} + /> + </div> + </ComingSoonTooltip> + </Box> + </div> : null} + <Box className={styles.buttonRow}> <button className={styles.cancelButton} @@ -81,11 +132,13 @@ const PromptComponent = props => ( ); PromptComponent.propTypes = { + isStage: PropTypes.bool.isRequired, label: PropTypes.string.isRequired, onCancel: PropTypes.func.isRequired, onChange: PropTypes.func.isRequired, onKeyPress: PropTypes.func.isRequired, onOk: PropTypes.func.isRequired, + onOptionSelection: PropTypes.func.isRequired, placeholder: PropTypes.string, showMoreOptions: PropTypes.bool.isRequired, title: PropTypes.string.isRequired diff --git a/src/containers/blocks.jsx b/src/containers/blocks.jsx index 1b411d633..f9db7468b 100644 --- a/src/containers/blocks.jsx +++ b/src/containers/blocks.jsx @@ -322,12 +322,16 @@ class Blocks extends React.Component { const p = {prompt: {callback, message, defaultValue}}; p.prompt.title = optTitle ? optTitle : this.ScratchBlocks.VARIABLE_MODAL_TITLE; + p.prompt.varType = typeof optVarType === 'string' ? + optVarType : this.ScratchBlocks.SCALAR_VARIABLE_TYPE; p.prompt.showMoreOptions = optVarType !== this.ScratchBlocks.BROADCAST_MESSAGE_VARIABLE_TYPE; this.setState(p); } - handlePromptCallback (data) { - this.state.prompt.callback(data); + handlePromptCallback (input, optionSelection) { + this.state.prompt.callback(input, optionSelection, + (optionSelection === 'local') ? [] : + this.props.vm.runtime.getAllVarNamesOfType(this.state.prompt.varType)); this.handlePromptClose(); } handlePromptClose () { @@ -366,6 +370,7 @@ class Blocks extends React.Component { /> {this.state.prompt ? ( <Prompt + isStage={vm.runtime.getEditingTarget().isStage} label={this.state.prompt.message} placeholder={this.state.prompt.defaultValue} showMoreOptions={this.state.prompt.showMoreOptions} diff --git a/src/containers/prompt.jsx b/src/containers/prompt.jsx index a798b02ed..72c8ad8a3 100644 --- a/src/containers/prompt.jsx +++ b/src/containers/prompt.jsx @@ -8,19 +8,21 @@ class Prompt extends React.Component { super(props); bindAll(this, [ 'handleOk', + 'handleOptionSelection', 'handleCancel', 'handleChange', 'handleKeyPress' ]); this.state = { - inputValue: '' + inputValue: '', + optionSelection: null }; } handleKeyPress (event) { if (event.key === 'Enter') this.handleOk(); } handleOk () { - this.props.onOk(this.state.inputValue); + this.props.onOk(this.state.inputValue, this.state.optionSelection); } handleCancel () { this.props.onCancel(); @@ -28,9 +30,13 @@ class Prompt extends React.Component { handleChange (e) { this.setState({inputValue: e.target.value}); } + handleOptionSelection (e) { + this.setState({optionSelection: e.target.value}); + } render () { return ( <PromptComponent + isStage={this.props.isStage} label={this.props.label} placeholder={this.props.placeholder} showMoreOptions={this.props.showMoreOptions} @@ -39,12 +45,14 @@ class Prompt extends React.Component { onChange={this.handleChange} onKeyPress={this.handleKeyPress} onOk={this.handleOk} + onOptionSelection={this.handleOptionSelection} /> ); } } Prompt.propTypes = { + isStage: PropTypes.bool.isRequired, label: PropTypes.string.isRequired, onCancel: PropTypes.func.isRequired, onOk: PropTypes.func.isRequired, -- GitLab