{
className={classNames(
styles.stageButton,
styles.stageButtonFirst,
- (stageSizeMode === STAGE_SIZE_MODES.small) ? null : styles.stageButtonToggledOff
+ (stageSize === STAGE_DISPLAY_SIZES.small) ? null : styles.stageButtonToggledOff
)}
onClick={onSetStageSmall}
>
@@ -97,7 +98,7 @@ const HardwareHeaderComponent = props => {
className={classNames(
styles.stageButton,
styles.stageButtonLast,
- (stageSizeMode === STAGE_SIZE_MODES.large) ? null : styles.stageButtonToggledOff
+ (stageSize === STAGE_DISPLAY_SIZES.large) ? null : styles.stageButtonToggledOff
)}
onClick={onSetStageLarge}
>
@@ -115,7 +116,7 @@ const HardwareHeaderComponent = props => {
{
/>
\ No newline at end of file
diff --git a/src/components/menu-bar/icon--file.svg b/src/components/menu-bar/icon--file.svg
new file mode 100644
index 00000000000..2a4bead2c3e
--- /dev/null
+++ b/src/components/menu-bar/icon--file.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/components/menu-bar/menu-bar.css b/src/components/menu-bar/menu-bar.css
index 5190450a3c4..15787022e88 100644
--- a/src/components/menu-bar/menu-bar.css
+++ b/src/components/menu-bar/menu-bar.css
@@ -44,6 +44,10 @@
padding: 0 0.75rem;
}
+.main-menu span{
+ margin-left: 0.35rem;
+}
+
.file-menu {
display: flex;
flex-direction: row;
@@ -70,7 +74,11 @@
padding: 0 0.75rem;
}
-.scratch-logo {
+.tail-menu span{
+ margin-left: 0.35rem;
+}
+
+.openblock-logo {
height: 1.6rem;
vertical-align: middle;
}
@@ -80,13 +88,12 @@
vertical-align: middle;
}
-.scratch-logo.clickable {
+.openblock-logo.clickable {
cursor: pointer;
}
.upload-firmware-logo {
height: 20px;
- margin-right: 0.35rem;
vertical-align: middle;
}
@@ -139,6 +146,7 @@
.title-field-growable {
flex-grow: 1;
width: 2rem;
+ min-width: 6rem;
}
.menu-bar-item.language-menu {
@@ -193,7 +201,16 @@
}
.help-icon {
- margin-right: 0.35rem;
+ height: 20px;
+}
+
+.file-icon {
+ height: 20px;
+}
+
+.edit-icon {
+ padding-top: 1px;
+ height: 20px;
}
.setting-icon {
@@ -203,17 +220,14 @@
.unconnected-icon {
width: 20px;
- margin-right: 0.35rem;
}
.connected-icon {
height: 20px;
- margin-right: 0.35rem;
}
.device-icon {
height: 20px;
- margin-right: 0.35rem;
}
.save-icon {
@@ -222,17 +236,14 @@
.link-socket-icon {
height: 20px;
- margin-right: 0.35rem;
}
.community-icon{
height: 20px;
- margin-right: 0.35rem;
}
.wiki-icon{
height: 1.4rem;
- margin-right: 0.35rem;
}
.account-nav-menu, .mystuff-button {
@@ -295,26 +306,21 @@
padding-left: 2rem;
}
+.program-mode-group span{
+ margin-left: 0;
+ margin-right: 0.35rem;
+}
+
.program-mode-switch {
vertical-align: middle;
}
-.program-mode-switch .mode-switch-realtime {
+.program-mode-switch .mode-switch-text {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
vertical-align: middle;
padding-right: 2rem;
- white-space: nowrap;
}
-.program-mode-switch .mode-switch-upload {
- display: flex;
- justify-content: center;
- align-items: center;
- height: 100%;
- vertical-align: middle;
- padding-left: 2rem;
- white-space: nowrap;
-}
diff --git a/src/components/menu-bar/menu-bar.jsx b/src/components/menu-bar/menu-bar.jsx
index d8cb99fe516..aec28a232ab 100644
--- a/src/components/menu-bar/menu-bar.jsx
+++ b/src/components/menu-bar/menu-bar.jsx
@@ -92,8 +92,11 @@ import saveIcon from './icon--save.svg';
import linkSocketIcon from './icon--link-socket.svg'; // eslint-disable-line no-unused-vars
import communityIcon from './icon--community.svg';
import wikiIcon from './icon--wiki.svg';
+import fileIcon from './icon--file.svg';
+import editIcon from './icon--edit.svg';
-import scratchLogo from './scratch-logo.svg';
+import openblockLogo from './openblock-logo.svg';
+import openblockLogoSmall from './openblock-logo-small.svg';
import sharedMessages from '../../lib/shared-messages';
@@ -203,6 +206,8 @@ class MenuBar extends React.Component {
constructor (props) {
super(props);
bindAll(this, [
+ 'checkOverflow',
+ 'containerRef',
'handleClickNew',
'handleClickRemix',
'handleClickOpenCommunity',
@@ -218,6 +223,7 @@ class MenuBar extends React.Component {
'restoreOptionMessage',
'handleConnectionMouseUp',
'handleUploadFirmware',
+ 'handleWindowsResize',
'handleSelectDeviceMouseUp',
'handleProgramModeSwitchOnChange',
'handleProgramModeUpdate',
@@ -225,16 +231,44 @@ class MenuBar extends React.Component {
'handleCheckUpdate',
'handleClearCache'
]);
+ this.state = {
+ isOverflow: false
+ };
}
componentDidMount () {
document.addEventListener('keydown', this.handleKeyPress);
this.props.vm.on('PERIPHERAL_DISCONNECTED', this.props.onDisconnect);
this.props.vm.on('PROGRAM_MODE_UPDATE', this.handleProgramModeUpdate);
+ window.addEventListener('resize', this.handleWindowsResize);
+ }
+ componentDidUpdate (prevProps, prevState) {
+ if ((prevState.isOverflow !== this.state.isOverflow && !this.state.isOverflow) ||
+ prevProps.isToolboxUpdating !== this.props.isToolboxUpdating
+ ) {
+ // TODO Maybe there is a better way to dynamically adjust the hidden state of
+ // the element so that the content does not flicker when the window is resized
+ setTimeout(() => {
+ this.checkOverflow();
+ }, 50);
+ }
}
componentWillUnmount () {
document.removeEventListener('keydown', this.handleKeyPress);
this.props.vm.removeListener('PERIPHERAL_DISCONNECTED', this.props.onDisconnect);
this.props.vm.removeListener('PROGRAM_MODE_UPDATE', this.handleProgramModeUpdate);
+ window.removeEventListener('resize', this.handleWindowsResize);
+ }
+ handleWindowsResize () {
+ this.checkOverflow();
+ }
+ containerRef (el) {
+ this.containerElement = el;
+ }
+ checkOverflow () {
+ if (this.containerElement) {
+ const container = this.containerElement;
+ this.setState({isOverflow: container.scrollWidth > container.clientWidth});
+ }
}
handleClickNew () {
// if the project is dirty, and user owns the project, we will autosave.
@@ -525,16 +559,17 @@ class MenuBar extends React.Component {
this.props.className,
styles.menuBar
)}
+ componentRef={this.containerRef}
>
@@ -560,11 +595,16 @@ class MenuBar extends React.Component {
})}
onMouseUp={this.props.onClickFile}
>
-
+ {this.state.isOverflow ? (
+
) :
+ }
-
+ {this.state.isOverflow ? (
+
) :
+ }
- {this.props.peripheralName}
+ {this.state.isOverflow ? null : this.props.peripheralName}
) : (
@@ -710,11 +755,11 @@ class MenuBar extends React.Component {
className={styles.unconnectedIcon}
src={unconnectedIcon}
/>
-
+ />}
)}
@@ -727,41 +772,42 @@ class MenuBar extends React.Component {
/>
*/}
-
- {this.props.canEditTitle ? (
-
- ) : ((this.props.authorUsername && this.props.authorUsername !== this.props.username) ? (
-
- ) : null)}
- {(this.props.canManageFiles) && (
-
{(className, downloadProjectCallback) => (
-
-
+ {this.state.isOverflow ? null :
+ (
+ {this.props.canEditTitle ? (
+
- )}
- )}
-
+ ) : ((this.props.authorUsername && this.props.authorUsername !== this.props.username) ? (
+
+ ) : null)}
+ {(this.props.canManageFiles) && (
+
{(className, downloadProjectCallback) => (
+
+
+
+ )}
+ )}
+
)}
-
+ {this.state.isOverflow ? null :
}
-
+ {this.state.isOverflow ? null : }
+
diff --git a/src/containers/hardware-header.jsx b/src/containers/hardware-header.jsx
index c2efb058d72..037e1a32f69 100644
--- a/src/containers/hardware-header.jsx
+++ b/src/containers/hardware-header.jsx
@@ -9,7 +9,7 @@ import {injectIntl} from 'react-intl';
import VM from 'openblock-vm';
import {setStageSize} from '../reducers/stage-size';
-import {STAGE_SIZE_MODES} from '../lib/layout-constants';
+import {STAGE_SIZE_MODES, STAGE_DISPLAY_SIZES} from '../lib/layout-constants';
import {openUploadProgress} from '../reducers/modals';
import {showAlertWithTimeout} from '../reducers/alerts';
@@ -57,15 +57,14 @@ HardwareHeader.propTypes = {
onOpenUploadProgress: PropTypes.func,
onWorkspaceIsEmpty: PropTypes.func.isRequired,
peripheralName: PropTypes.string,
- stageSizeMode: PropTypes.oneOf(Object.keys(STAGE_SIZE_MODES)),
+ stageSize: PropTypes.oneOf(Object.keys(STAGE_DISPLAY_SIZES)).isRequired,
vm: PropTypes.instanceOf(VM).isRequired
};
const mapStateToProps = state => ({
codeEditorValue: state.scratchGui.code.codeEditorValue,
deviceId: state.scratchGui.device.deviceId,
- peripheralName: state.scratchGui.connectionModal.peripheralName,
- stageSizeMode: state.scratchGui.stageSize.stageSize
+ peripheralName: state.scratchGui.connectionModal.peripheralName
});
const mapDispatchToProps = dispatch => ({
diff --git a/src/containers/hardware.jsx b/src/containers/hardware.jsx
index 391a58da4b4..4295bae95bc 100644
--- a/src/containers/hardware.jsx
+++ b/src/containers/hardware.jsx
@@ -9,6 +9,7 @@ import {injectIntl} from 'react-intl';
import {showAlertWithTimeout} from '../reducers/alerts';
import {setCodeEditorValue, toggleLock} from '../reducers/code';
+import {STAGE_DISPLAY_SIZES} from '../lib/layout-constants.js';
import {getLanguageFromDeviceType} from '../lib/device';
import HardwareComponent from '../components/hardware/hardware.jsx';
@@ -84,14 +85,14 @@ Hardware.propTypes = {
isCodeEditorLocked: PropTypes.bool.isRequired,
onCodeEditorIsLocked: PropTypes.func.isRequired,
onSetCodeEditorValue: PropTypes.func.isRequired,
- onToggleCodeEditorLock: PropTypes.func.isRequired
+ onToggleCodeEditorLock: PropTypes.func.isRequired,
+ stageSize: PropTypes.oneOf(Object.keys(STAGE_DISPLAY_SIZES)).isRequired
};
const mapStateToProps = state => ({
codeEditorValue: state.scratchGui.code.codeEditorValue,
deviceType: state.scratchGui.device.deviceType,
- isCodeEditorLocked: state.scratchGui.code.isCodeEditorLocked,
- stageSizeMode: state.scratchGui.stageSize.stageSize
+ isCodeEditorLocked: state.scratchGui.code.isCodeEditorLocked
});
const mapDispatchToProps = dispatch => ({
diff --git a/src/containers/scanning-step.jsx b/src/containers/scanning-step.jsx
index 4a6d0fbc95d..25b60ea2270 100644
--- a/src/containers/scanning-step.jsx
+++ b/src/containers/scanning-step.jsx
@@ -51,6 +51,10 @@ class ScanningStep extends React.Component {
handleClickListAll () {
this.props.onClickListAll(!this.props.isListAll);
this.scanForPeripheral(!this.props.isListAll);
+ this.setState({
+ scanning: true,
+ peripheralList: []
+ });
}
handleRefresh () {
this.scanForPeripheral(this.props.isListAll);