Skip to content
Snippets Groups Projects
Commit cfb55514 authored by Christopher Willis-Ford's avatar Christopher Willis-Ford
Browse files

Implement all staging logic in terms of stageSize

Pass a `stageSize` property down from a centralized `MediaQuery` in the
GUI component, and control the size of the stage and all surrounding
elements based on that value. Note that this is a pure property and is
not stored in the Redux state, since we gain access to the results of
the media query during `render()` and we shouldn't change Redux state
during `render()`.

Some stage-adjacent elements don't yet react correctly to the smallest
stage size.
parent 16abc916
No related branches found
No related tags found
No related merge requests found
......@@ -2,6 +2,8 @@ import classNames from 'classnames';
import PropTypes from 'prop-types';
import React from 'react';
import {defineMessages, FormattedMessage, injectIntl, intlShape} from 'react-intl';
import {connect} from 'react-redux';
import MediaQuery from 'react-responsive';
import {Tab, Tabs, TabList, TabPanel} from 'react-tabs';
import tabStyles from 'react-tabs/style/react-tabs.css';
import VM from 'scratch-vm';
......@@ -26,6 +28,9 @@ import TipsLibrary from '../../containers/tips-library.jsx';
import Cards from '../../containers/cards.jsx';
import DragLayer from '../../containers/drag-layer.jsx';
import layout, {STAGE_SIZES} from '../../lib/layout-constants';
import {resolveStageSize} from '../../lib/screen-utils';
import styles from './gui.css';
import addExtensionIcon from './icon--extensions.svg';
import codeIcon from './icon--code.svg';
......@@ -40,7 +45,7 @@ const messages = defineMessages({
}
});
// Cache this value to only retreive it once the first time.
// Cache this value to only retrieve it once the first time.
// Assume that it doesn't change for a session.
let isRendererSupported = null;
......@@ -69,6 +74,7 @@ const GUIComponent = props => {
previewInfoVisible,
targetIsStage,
soundsTabVisible,
stageSizeMode,
tipsLibraryVisible,
vm,
...componentProps
......@@ -90,159 +96,166 @@ const GUIComponent = props => {
isRendererSupported = Renderer.isSupported();
}
return isPlayerOnly ? (
<StageWrapper
isRendererSupported={isRendererSupported}
vm={vm}
/>
) : (
<Box
className={styles.pageWrapper}
{...componentProps}
>
{previewInfoVisible ? (
<PreviewModal />
) : null}
{loading ? (
<Loader />
) : null}
{importInfoVisible ? (
<ImportModal />
) : null}
{isRendererSupported ? null : (
<WebGlModal />
)}
{tipsLibraryVisible ? (
<TipsLibrary />
) : null}
{cardsVisible ? (
<Cards />
) : null}
{costumeLibraryVisible ? (
<CostumeLibrary
vm={vm}
onRequestClose={onRequestCloseCostumeLibrary}
/>
) : null}
{backdropLibraryVisible ? (
<BackdropLibrary
vm={vm}
onRequestClose={onRequestCloseBackdropLibrary}
/>
) : null}
<MenuBar enableCommunity={enableCommunity} />
<Box className={styles.bodyWrapper}>
<Box className={styles.flexWrapper}>
<Box className={styles.editorWrapper}>
<Tabs
className={tabClassNames.tabs}
forceRenderTabPanel={true} // eslint-disable-line react/jsx-boolean-value
selectedIndex={activeTabIndex}
selectedTabClassName={tabClassNames.tabSelected}
selectedTabPanelClassName={tabClassNames.tabPanelSelected}
onSelect={onActivateTab}
>
<TabList className={tabClassNames.tabList}>
<Tab className={tabClassNames.tab}>
<img
draggable={false}
src={codeIcon}
/>
<FormattedMessage
defaultMessage="Code"
description="Button to get to the code panel"
id="gui.gui.codeTab"
/>
</Tab>
<Tab
className={tabClassNames.tab}
onClick={onActivateCostumesTab}
>
<img
draggable={false}
src={costumesIcon}
/>
{targetIsStage ? (
<FormattedMessage
defaultMessage="Backdrops"
description="Button to get to the backdrops panel"
id="gui.gui.backdropsTab"
return (<MediaQuery minWidth={layout.fullSizeMinWidth}>{isFullSize => {
const stageSize = resolveStageSize(stageSizeMode, !isFullSize);
return isPlayerOnly ? (
<StageWrapper
isRendererSupported={isRendererSupported}
stageSize={stageSize}
vm={vm}
/>
) : (
<Box
className={styles.pageWrapper}
{...componentProps}
>
{previewInfoVisible ? (
<PreviewModal />
) : null}
{loading ? (
<Loader />
) : null}
{importInfoVisible ? (
<ImportModal />
) : null}
{isRendererSupported ? null : (
<WebGlModal />
)}
{tipsLibraryVisible ? (
<TipsLibrary />
) : null}
{cardsVisible ? (
<Cards />
) : null}
{costumeLibraryVisible ? (
<CostumeLibrary
vm={vm}
onRequestClose={onRequestCloseCostumeLibrary}
/>
) : null}
{backdropLibraryVisible ? (
<BackdropLibrary
vm={vm}
onRequestClose={onRequestCloseBackdropLibrary}
/>
) : null}
<MenuBar enableCommunity={enableCommunity} />
<Box className={styles.bodyWrapper}>
<Box className={styles.flexWrapper}>
<Box className={styles.editorWrapper}>
<Tabs
className={tabClassNames.tabs}
forceRenderTabPanel={true} // eslint-disable-line react/jsx-boolean-value
selectedIndex={activeTabIndex}
selectedTabClassName={tabClassNames.tabSelected}
selectedTabPanelClassName={tabClassNames.tabPanelSelected}
onSelect={onActivateTab}
>
<TabList className={tabClassNames.tabList}>
<Tab className={tabClassNames.tab}>
<img
draggable={false}
src={codeIcon}
/>
) : (
<FormattedMessage
defaultMessage="Costumes"
description="Button to get to the costumes panel"
id="gui.gui.costumesTab"
defaultMessage="Code"
description="Button to get to the code panel"
id="gui.gui.codeTab"
/>
)}
</Tab>
<Tab
className={tabClassNames.tab}
onClick={onActivateSoundsTab}
>
<img
draggable={false}
src={soundsIcon}
/>
<FormattedMessage
defaultMessage="Sounds"
description="Button to get to the sounds panel"
id="gui.gui.soundsTab"
/>
</Tab>
</TabList>
<TabPanel className={tabClassNames.tabPanel}>
<Box className={styles.blocksWrapper}>
<Blocks
grow={1}
isVisible={blocksTabVisible}
options={{
media: `${basePath}static/blocks-media/`
}}
vm={vm}
/>
</Box>
<Box className={styles.extensionButtonContainer}>
<button
className={styles.extensionButton}
title={intl.formatMessage(messages.addExtension)}
onClick={onExtensionButtonClick}
</Tab>
<Tab
className={tabClassNames.tab}
onClick={onActivateCostumesTab}
>
<img
className={styles.extensionButtonIcon}
draggable={false}
src={addExtensionIcon}
src={costumesIcon}
/>
</button>
</Box>
</TabPanel>
<TabPanel className={tabClassNames.tabPanel}>
{costumesTabVisible ? <CostumeTab vm={vm} /> : null}
</TabPanel>
<TabPanel className={tabClassNames.tabPanel}>
{soundsTabVisible ? <SoundTab vm={vm} /> : null}
</TabPanel>
</Tabs>
{backpackOptions.visible ? (
<Backpack host={backpackOptions.host} />
) : null}
</Box>
{targetIsStage ? (
<FormattedMessage
defaultMessage="Backdrops"
description="Button to get to the backdrops panel"
id="gui.gui.backdropsTab"
/>
) : (
<FormattedMessage
defaultMessage="Costumes"
description="Button to get to the costumes panel"
id="gui.gui.costumesTab"
/>
)}
</Tab>
<Tab
className={tabClassNames.tab}
onClick={onActivateSoundsTab}
>
<img
draggable={false}
src={soundsIcon}
/>
<FormattedMessage
defaultMessage="Sounds"
description="Button to get to the sounds panel"
id="gui.gui.soundsTab"
/>
</Tab>
</TabList>
<TabPanel className={tabClassNames.tabPanel}>
<Box className={styles.blocksWrapper}>
<Blocks
grow={1}
isVisible={blocksTabVisible}
options={{
media: `${basePath}static/blocks-media/`
}}
vm={vm}
/>
</Box>
<Box className={styles.extensionButtonContainer}>
<button
className={styles.extensionButton}
title={intl.formatMessage(messages.addExtension)}
onClick={onExtensionButtonClick}
>
<img
className={styles.extensionButtonIcon}
draggable={false}
src={addExtensionIcon}
/>
</button>
</Box>
</TabPanel>
<TabPanel className={tabClassNames.tabPanel}>
{costumesTabVisible ? <CostumeTab vm={vm} /> : null}
</TabPanel>
<TabPanel className={tabClassNames.tabPanel}>
{soundsTabVisible ? <SoundTab vm={vm} /> : null}
</TabPanel>
</Tabs>
{backpackOptions.visible ? (
<Backpack host={backpackOptions.host} />
) : null}
</Box>
<Box className={styles.stageAndTargetWrapper}>
<StageWrapper
isRendererSupported={isRendererSupported}
vm={vm}
/>
<Box className={styles.targetWrapper}>
<TargetPane vm={vm} />
<Box className={styles.stageAndTargetWrapper}>
<StageWrapper
isRendererSupported={isRendererSupported}
stageSize={stageSize}
vm={vm}
/>
<Box className={styles.targetWrapper}>
<TargetPane vm={vm} />
</Box>
</Box>
</Box>
</Box>
<DragLayer />
</Box>
<DragLayer />
</Box>
);
);
}}</MediaQuery>);
};
GUIComponent.propTypes = {
activeTabIndex: PropTypes.number,
backdropLibraryVisible: PropTypes.bool,
......@@ -270,6 +283,7 @@ GUIComponent.propTypes = {
onTabSelect: PropTypes.func,
previewInfoVisible: PropTypes.bool,
soundsTabVisible: PropTypes.bool,
stageSizeMode: PropTypes.oneOf([STAGE_SIZES.large, STAGE_SIZES.small]),
targetIsStage: PropTypes.bool,
tipsLibraryVisible: PropTypes.bool,
vm: PropTypes.instanceOf(VM).isRequired
......@@ -279,6 +293,15 @@ GUIComponent.defaultProps = {
host: null,
visible: false
},
basePath: './'
basePath: './',
stageSizeMode: STAGE_SIZES.large
};
export default injectIntl(GUIComponent);
const mapStateToProps = state => ({
// This is the button's mode, as opposed to the actual current state
stageSizeMode: state.scratchGui.stageSize.stageSize
});
export default injectIntl(connect(
mapStateToProps
)(GUIComponent));
......@@ -2,13 +2,14 @@ import classNames from 'classnames';
import {defineMessages, injectIntl, intlShape} from 'react-intl';
import PropTypes from 'prop-types';
import React from 'react';
import {connect} from 'react-redux';
import VM from 'scratch-vm';
import Box from '../box/box.jsx';
import Button from '../button/button.jsx';
import {ComingSoonTooltip} from '../coming-soon/coming-soon.jsx';
import Controls from '../../containers/controls.jsx';
import {getStageSize} from '../../lib/screen-utils.js';
import {getStageDimensions} from '../../lib/screen-utils';
import {STAGE_SIZES} from '../../lib/layout-constants';
import fullScreenIcon from './icon--fullscreen.svg';
import largeStageIcon from './icon--large-stage.svg';
......@@ -51,20 +52,22 @@ const StageHeaderComponent = function (props) {
isPlayerOnly,
onKeyPress,
onSetStageLarge,
onSetStageSmall,
onSetStageFull,
onSetStageUnFull,
stageSizeMode,
vm
} = props;
let header = null;
const stageSize = getStageSize(isFullScreen);
if (isFullScreen) {
const stageDimensions = getStageDimensions(null, true);
header = (
<Box className={styles.stageHeaderWrapperOverlay}>
<Box
className={styles.stageMenuWrapper}
style={{width: stageSize.width}}
style={{width: stageDimensions.width}}
>
<Controls vm={vm} />
<Button
......@@ -89,31 +92,30 @@ const StageHeaderComponent = function (props) {
[]
) : (
<div className={styles.stageSizeToggleGroup}>
<ComingSoonTooltip
place="left"
tooltipId="small-stage-button"
>
<div
disabled
<div>
<Button
className={classNames(
styles.stageButton,
styles.stageButtonLeft,
styles.stageButtonDisabled
(stageSizeMode === STAGE_SIZES.small) ? null : styles.stageButtonDisabled
)}
role="button"
onClick={onSetStageSmall}
>
<img
disabled
alt={props.intl.formatMessage(messages.smallStageSizeMessage)}
className={styles.stageButtonIcon}
draggable={false}
src={smallStageIcon}
/>
</div>
</ComingSoonTooltip>
</Button>
</div>
<div>
<Button
className={classNames(styles.stageButton, styles.stageButtonRight)}
className={classNames(
styles.stageButton,
styles.stageButtonRight,
(stageSizeMode === STAGE_SIZES.large) ? null : styles.stageButtonDisabled
)}
onClick={onSetStageLarge}
>
<img
......@@ -155,6 +157,11 @@ const StageHeaderComponent = function (props) {
return header;
};
const mapStateToProps = state => ({
// This is the button's mode, as opposed to the actual current state
stageSizeMode: state.scratchGui.stageSize.stageSize
});
StageHeaderComponent.propTypes = {
intl: intlShape,
isFullScreen: PropTypes.bool.isRequired,
......@@ -162,8 +169,16 @@ StageHeaderComponent.propTypes = {
onKeyPress: PropTypes.func.isRequired,
onSetStageFull: PropTypes.func.isRequired,
onSetStageLarge: PropTypes.func.isRequired,
onSetStageSmall: PropTypes.func.isRequired,
onSetStageUnFull: PropTypes.func.isRequired,
stageSizeMode: PropTypes.oneOf([STAGE_SIZES.large, STAGE_SIZES.small]),
vm: PropTypes.instanceOf(VM).isRequired
};
export default injectIntl(StageHeaderComponent);
StageHeaderComponent.defaultProps = {
stageSizeMode: STAGE_SIZES.large
};
export default injectIntl(connect(
mapStateToProps
)(StageHeaderComponent));
import PropTypes from 'prop-types';
import React from 'react';
import MediaQuery from 'react-responsive';
import VM from 'scratch-vm';
import Box from '../box/box.jsx';
import layout from '../../lib/layout-constants.js';
import {STAGE_SIZES} from '../../lib/layout-constants.js';
import StageHeader from '../../containers/stage-header.jsx';
import Stage from '../../containers/stage.jsx';
......@@ -13,27 +12,28 @@ import styles from './stage-wrapper.css';
const StageWrapperComponent = function (props) {
const {
isRendererSupported,
stageSize,
vm
} = props;
return (
<Box className={styles.stageWrapper}>
<Box className={styles.stageMenuWrapper}>
<StageHeader vm={vm} />
<StageHeader
stageSize={stageSize}
vm={vm}
/>
</Box>
<Box className={styles.stageCanvasWrapper}>
{/* eslint-disable arrow-body-style */}
<MediaQuery minWidth={layout.fullSizeMinWidth}>{isFullSize => {
return isRendererSupported ? (
{
isRendererSupported ?
<Stage
height={isFullSize ? layout.fullStageHeight : layout.smallerStageHeight}
shrink={0}
stageSize={stageSize}
vm={vm}
width={isFullSize ? layout.fullStageWidth : layout.smallerStageWidth}
/>
) : null;
}}</MediaQuery>
{/* eslint-enable arrow-body-style */}
/> :
null
}
</Box>
</Box>
);
......@@ -41,6 +41,7 @@ const StageWrapperComponent = function (props) {
StageWrapperComponent.propTypes = {
isRendererSupported: PropTypes.bool.isRequired,
stageSize: PropTypes.oneOf(Object.values(STAGE_SIZES)).isRequired,
vm: PropTypes.instanceOf(VM).isRequired
};
......
......@@ -6,26 +6,26 @@ import Box from '../box/box.jsx';
import Loupe from '../loupe/loupe.jsx';
import MonitorList from '../../containers/monitor-list.jsx';
import Question from '../../containers/question.jsx';
import {getStageSize} from '../../lib/screen-utils.js';
import {STAGE_SIZES} from '../../lib/layout-constants.js';
import {getStageDimensions} from '../../lib/screen-utils.js';
import styles from './stage.css';
const StageComponent = props => {
const {
canvasRef,
dragRef,
height,
isColorPicking,
isFullScreen,
width,
colorInfo,
onDeactivateColorPicker,
question,
onQuestionAnswered,
stageSize,
useEditorDragStyle,
onDeactivateColorPicker,
onQuestionAnswered,
...boxProps
} = props;
const stageSize = getStageSize(isFullScreen, height, width);
const stageDimensions = getStageDimensions(stageSize, isFullScreen);
return (
<div>
......@@ -43,14 +43,14 @@ const StageComponent = props => {
)}
componentRef={canvasRef}
element="canvas"
height={stageSize.height}
width={stageSize.width}
height={stageDimensions.height}
width={stageDimensions.width}
{...boxProps}
/>
<Box className={styles.monitorWrapper}>
<MonitorList
draggable={useEditorDragStyle}
stageSize={stageSize}
stageSize={stageDimensions}
/>
</Box>
{isColorPicking && colorInfo ? (
......@@ -67,7 +67,7 @@ const StageComponent = props => {
>
<div
className={styles.questionWrapper}
style={{width: stageSize.width}}
style={{width: stageDimensions.width}}
>
<Question
question={question}
......@@ -96,19 +96,16 @@ StageComponent.propTypes = {
canvasRef: PropTypes.func,
colorInfo: Loupe.propTypes.colorInfo,
dragRef: PropTypes.func,
height: PropTypes.number,
isColorPicking: PropTypes.bool,
isFullScreen: PropTypes.bool.isRequired,
onDeactivateColorPicker: PropTypes.func,
onQuestionAnswered: PropTypes.func,
question: PropTypes.string,
useEditorDragStyle: PropTypes.bool,
width: PropTypes.number
stageSize: PropTypes.oneOf(Object.values(STAGE_SIZES)).isRequired,
useEditorDragStyle: PropTypes.bool
};
StageComponent.defaultProps = {
canvasRef: () => {},
dragRef: () => {},
width: 480,
height: 360
dragRef: () => {}
};
export default StageComponent;
......@@ -2,7 +2,8 @@ import PropTypes from 'prop-types';
import React from 'react';
import bindAll from 'lodash.bindall';
import VM from 'scratch-vm';
import {setStageSize, STAGE_SIZES} from '../reducers/stage-size';
import {STAGE_SIZES} from '../lib/layout-constants';
import {setStageSize} from '../reducers/stage-size';
import {setFullScreen} from '../reducers/mode';
import {connect} from 'react-redux';
......@@ -45,7 +46,7 @@ StageHeader.propTypes = {
isFullScreen: PropTypes.bool,
isPlayerOnly: PropTypes.bool,
onSetStageUnFull: PropTypes.func.isRequired,
stageSize: PropTypes.oneOf(Object.keys(STAGE_SIZES)),
stageSize: PropTypes.oneOf(Object.values(STAGE_SIZES)),
vm: PropTypes.instanceOf(VM).isRequired
};
......
import PropTypes from 'prop-types';
import React from 'react';
import VM from 'scratch-vm';
import {STAGE_SIZES} from '../lib/layout-constants.js';
import StageWrapperComponent from '../components/stage-wrapper/stage-wrapper.jsx';
const StageWrapper = props => <StageWrapperComponent {...props} />;
StageWrapper.propTypes = {
isRendererSupported: PropTypes.bool.isRequired,
stageSize: PropTypes.oneOf(Object.values(STAGE_SIZES)).isRequired,
vm: PropTypes.instanceOf(VM).isRequired
};
......
......@@ -5,6 +5,7 @@ import Renderer from 'scratch-render';
import VM from 'scratch-vm';
import {connect} from 'react-redux';
import {STAGE_SIZES} from '../lib/layout-constants';
import {getEventXY} from '../lib/touch-utils';
import VideoProvider from '../lib/video/video-provider';
import {SVGRenderer as V2SVGAdapter} from 'scratch-svg-renderer';
......@@ -63,8 +64,7 @@ class Stage extends React.Component {
this.props.vm.setVideoProvider(new VideoProvider());
}
shouldComponentUpdate (nextProps, nextState) {
return this.props.width !== nextProps.width ||
this.props.height !== nextProps.height ||
return this.props.stageSize !== nextProps.stageSize ||
this.props.isColorPicking !== nextProps.isColorPicking ||
this.state.colorInfo !== nextState.colorInfo ||
this.props.isFullScreen !== nextProps.isFullScreen ||
......@@ -380,14 +380,13 @@ class Stage extends React.Component {
}
Stage.propTypes = {
height: PropTypes.number,
isColorPicking: PropTypes.bool,
isFullScreen: PropTypes.bool.isRequired,
onActivateColorPicker: PropTypes.func,
onDeactivateColorPicker: PropTypes.func,
stageSize: PropTypes.oneOf(Object.values(STAGE_SIZES)).isRequired,
useEditorDragStyle: PropTypes.bool,
vm: PropTypes.instanceOf(VM).isRequired,
width: PropTypes.number
vm: PropTypes.instanceOf(VM).isRequired
};
Stage.defaultProps = {
......
// stage size constants
/**
* Names for each stage size mode
* @enum {string}
*/
const STAGE_SIZES = {
/**
* Large stage with wide browser
*/
large: 'large',
/**
* Large stage with narrow browser
*/
largeConstrained: 'largeConstrained',
/**
* Small stage (ignores browser width)
*/
small: 'small'
};
const STAGE_SCALES = {};
STAGE_SCALES[STAGE_SIZES.large] = 1; // large mode, wide browser (standard)
STAGE_SCALES[STAGE_SIZES.largeConstrained] = 0.85; // large mode but narrow browser
STAGE_SCALES[STAGE_SIZES.small] = 0.5; // small mode, regardless of browser size
export default {
fullStageWidth: 480,
fullStageHeight: 360,
smallerStageWidth: 480 * 0.85,
smallerStageHeight: 360 * 0.85,
standardStageWidth: 480,
standardStageHeight: 360,
fullSizeMinWidth: 1096,
fullSizePaintMinWidth: 1250
};
export {
STAGE_SCALES,
STAGE_SIZES
};
const STAGE_SIZE_DEFAULTS = {
heightSmall: 360,
widthSmall: 480,
import PropTypes from 'prop-types';
import layout, {STAGE_SIZES, STAGE_SCALES} from '../lib/layout-constants';
/**
* @typedef {object} StageDimensions
* @property {int} height - the height to be used for the stage in the current situation.
* @property {int} width - the width to be used for the stage in the current situation.
* @property {number} scale - the scale factor from the stage's default size to its current size.
* @property {int} heightDefault - the height of the stage in its default (large) size.
* @property {int} widthDefault - the width of the stage in its default (large) size.
*/
/**
* PropTypes.shape(...) argument for `getStageDimensions` return value structure.
* @type {object.<PropTypes>}
*/
const StageDimensionsShape = {
height: PropTypes.number.isRequired,
heightDefault: PropTypes.number.isRequired,
width: PropTypes.number.isRequired,
widthDefault: PropTypes.number.isRequired,
scale: PropTypes.number.isRequired
};
const STAGE_DIMENSION_DEFAULTS = {
spacingBorderAdjustment: 9,
menuHeightAdjustment: 40
};
const getStageSize = (
isFullScreen = false,
height = STAGE_SIZE_DEFAULTS.heightSmall,
width = STAGE_SIZE_DEFAULTS.widthSmall) => {
/**
* Resolve the current GUI and browser state to an actual stage size enum value.
* All parameters are optional; if none are provided the result will be `STAGE_SIZES.large`.
* @param {STAGE_SIZES} stageSizeMode - the state of the stage size toggle button.
* @param {boolean} mediaQuerySmallSize - true if the window is too small for the large stage at its full size.
* @return {STAGE_SIZES} - the stage size enum value we should use in this situation.
*/
const resolveStageSize = (stageSizeMode = null, mediaQuerySmallSize = false) => {
stageSizeMode = stageSizeMode || STAGE_SIZES.large;
if (stageSizeMode === STAGE_SIZES.large && mediaQuerySmallSize) {
return STAGE_SIZES.largeConstrained;
}
return stageSizeMode;
};
const stageSize = {
heightDefault: height,
widthDefault: width,
height: height,
width: width
/**
* Retrieve info used to determine the actual stage size based on the current GUI and browser state.
* @param {STAGE_SIZES} stageSize - the current fully-resolved stage size.
* @param {boolean} isFullScreen - true if full-screen mode is enabled.
* @return {StageDimensions} - an object describing the dimensions of the stage.
*/
const getStageDimensions = (stageSize, isFullScreen) => {
const stageDimensions = {
heightDefault: layout.standardStageHeight,
widthDefault: layout.standardStageWidth,
height: 0,
width: 0,
scale: 0
};
if (isFullScreen) {
stageSize.height = window.innerHeight -
STAGE_SIZE_DEFAULTS.menuHeightAdjustment -
STAGE_SIZE_DEFAULTS.spacingBorderAdjustment;
stageDimensions.height = window.innerHeight -
STAGE_DIMENSION_DEFAULTS.menuHeightAdjustment -
STAGE_DIMENSION_DEFAULTS.spacingBorderAdjustment;
stageSize.width = stageSize.height + (stageSize.height / 3);
stageDimensions.width = stageDimensions.height + (stageDimensions.height / 3);
if (stageSize.width > window.innerWidth) {
stageSize.width = window.innerWidth;
stageSize.height = stageSize.width * .75;
if (stageDimensions.width > window.innerWidth) {
stageDimensions.width = window.innerWidth;
stageDimensions.height = stageDimensions.width * .75;
}
stageDimensions.scale = stageDimensions.width / stageDimensions.widthDefault;
} else {
stageDimensions.scale = STAGE_SCALES[stageSize];
stageDimensions.height = stageDimensions.scale * stageDimensions.heightDefault;
stageDimensions.width = stageDimensions.scale * stageDimensions.widthDefault;
}
return stageSize;
return stageDimensions;
};
export {
getStageSize,
STAGE_SIZE_DEFAULTS
getStageDimensions,
resolveStageSize,
StageDimensionsShape
};
import {STAGE_SIZES} from '../lib/layout-constants.js';
const SET_STAGE_SIZE = 'scratch-gui/StageSize/SET_STAGE_SIZE';
const initialState = {
stageSize: 'large'
};
// stage size constants
const STAGE_SIZES = {
small: 'small',
large: 'large'
stageSize: STAGE_SIZES.large
};
const reducer = function (state, action) {
......@@ -32,6 +28,5 @@ const setStageSize = function (stageSize) {
export {
reducer as default,
initialState as stageSizeInitialState,
setStageSize,
STAGE_SIZES
setStageSize
};
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment