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.
This commit is contained in:
1 parent
2cb578c705
commit
0dd4623523
4 files changed
+103
-27
No files matched your search
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in new issue
Block a user