Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 46 additions & 73 deletions packages/scratch-gui/src/components/blocks/blocks.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,97 +3,70 @@
@import "../../css/z-index.css";

.blocks {
height: 100%;
height: 100%;
}

.drag-over:after {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0.75;
background-color: $drop-highlight;
transition: all 0.25s ease;
.drag-over::after {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0.75;
background-color: rgba(0, 191, 255, 0.2); /* antes $drop-highlight */
transition: all 0.25s ease;
}

.blocks :global(.injectionDiv){
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
border: 1px solid $ui-black-transparent;
border-top-right-radius: $space;
border-bottom-right-radius: $space;
.blocks .injectionDiv {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
border: 1px solid rgba(0,0,0,0.2); /* antes $ui-black-transparent */
border-top-right-radius: 0.25rem; /* antes $space */
border-bottom-right-radius: 0.25rem;
}

[dir="rtl"] .blocks :global(.injectionDiv) {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
border-top-left-radius: $space;
border-bottom-left-radius: $space;
[dir="rtl"] .blocks .injectionDiv {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
border-top-left-radius: 0.25rem;
border-bottom-left-radius: 0.25rem;
}

.blocks :global(.blocklyMainBackground) {
stroke: none;
.blocks .blocklyMainBackground {
stroke: none;
}

.blocks :global(.blocklyToolboxDiv) {
border-right: 1px solid $ui-black-transparent;
border-bottom: 1px solid $ui-black-transparent;
box-sizing: content-box;
height: calc(100% - 3.25rem) !important;

/*
For now, the layout cannot support scrollbars in the category menu.
The line below works for Edge, the `::-webkit-scrollbar` line
below that is for webkit browsers. It isn't possible to do the
same for Firefox, so a different solution may be needed for them.
*/
-ms-overflow-style: none;
}

[dir="rtl"] .blocks :global(.blocklyToolboxDiv) {
border-right: none;
border-left: 1px solid $ui-black-transparent;
.blocks .blocklyToolboxDiv {
border-right: 1px solid rgba(0,0,0,0.2);
border-bottom: 1px solid rgba(0,0,0,0.2);
box-sizing: content-box;
height: calc(100% - 3.25rem) !important;
-ms-overflow-style: none;
}

.blocks :global(.blocklyToolboxDiv::-webkit-scrollbar) {
display: none;
.blocks .blocklyToolboxDiv::-webkit-scrollbar {
display: none;
}

.blocks :global(.blocklyFlyout) {
border-right: 1px solid $ui-black-transparent;
box-sizing: content-box;
.blocks .blocklyFlyout {
border-right: 1px solid rgba(0,0,0,0.2);
box-sizing: content-box;
}

[dir="rtl"] .blocks :global(.blocklyFlyout) {
border-right: none;
border-left: 1px solid $ui-black-transparent;
}


.blocks :global(.blocklyBlockDragSurface) {
/*
Fix an issue where the drag surface was preventing hover events for sharing blocks.
This does not prevent user interaction on the blocks themselves.
*/
pointer-events: none;
z-index: $z-index-drag-layer; /* make blocks match gui drag layer */
.blocks .blocklyBlockDragSurface {
pointer-events: none;
z-index: 200; /* antes $z-index-drag-layer */
}

/*
Shrink category font to fit "My Blocks" for now.
Probably will need different solutions for language support later, so
make the change here instead of in scratch-blocks.
*/
.blocks :global(.scratchCategoryMenuItemLabel) {
font-size: 0.65rem;
.blocks .scratchCategoryMenuItemLabel {
font-size: 0.65rem;
}

.blocks :global(.blocklyMinimalBody) {
min-width: auto;
min-height: auto;
.blocks .blocklyMinimalBody {
min-width: auto;
min-height: auto;
}
4 changes: 3 additions & 1 deletion packages/scratch-gui/src/components/gui/gui.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ import soundsIcon from './icon--sounds.svg';
import DebugModal from '../debug-modal/debug-modal.jsx';
import {setPlatform} from '../../reducers/platform.js';
import {PLATFORM} from '../../lib/platform.js';
import VisionPreview from '../../containers/vision-preview.jsx';


const messages = defineMessages({
addExtension: {
Expand Down Expand Up @@ -398,7 +400,6 @@ const GUIComponent = props => {
<Backpack host={backpackHost} />
) : null}
</Box>

<Box className={classNames(styles.stageAndTargetWrapper, styles[stageSize])}>
<StageWrapper
isFullScreen={isFullScreen}
Expand All @@ -415,6 +416,7 @@ const GUIComponent = props => {
onNewBackdropClick={onNewLibraryBackdropClick}
/>
</Box>
<VisionPreview vm={vm} />
</Box>
</Box>
</Box>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,43 @@

.stage-wrapper.full-screen {
position: fixed;
top: $stage-menu-height;
top: stage-menu-height;
left: 0;
right: 0;
bottom: 0;
z-index: $z-index-stage-wrapper-overlay;
background-color: $ui-white;
z-index: z-index-stage-wrapper-overlay;
background-color: ui-white;
/* spacing between stage and control bar (on the top), or between
stage and window edges (on left/right/bottom) */
padding: $stage-full-screen-stage-padding;
padding: stage-full-screen-stage-padding;

/* this centers the stage */
display: flex;
flex-direction: column;
align-items: center;
}

.vision-viewer {
margin-top: 10px;
height: 240px; /* ajusta según necesites */
background: #fff;
}

.visionFullScreen {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
background-color: #000; /* Fondo negro */
}

.visionFullScreen canvas,
.visionFullScreen img,
.visionFullScreen video {
max-width: 100%;
max-height: 100%;
object-fit: contain;
border-radius: 8px;
}

Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,28 @@ import classNames from 'classnames';
import VM from '@scratch/scratch-vm';

import Box from '../box/box.jsx';
import {STAGE_DISPLAY_SIZES} from '../../lib/layout-constants.js';
import StageHeader from '../../containers/stage-header.jsx';
import Stage from '../../containers/stage.jsx';
import Loader from '../loader/loader.jsx';

import VisionViewer from '../../lib/vision-viewer';
import styles from './stage-wrapper.css';

const StageWrapperComponent = function (props) {
const {
isFullScreen,
isRtl,
isRendererSupported,
loading,
manuallySaveThumbnails,
onUpdateProjectThumbnail,
stageSize,
vm
} = props;

/**
* StageWrapperComponent
*
* Componente que reemplaza el escenario estándar de Scratch por la vista del Vision Kit.
*
* @param {object} props - Propiedades del componente.
* @param {boolean} props.isFullScreen - Indica si está en modo pantalla completa.
* @param {boolean} props.isRtl - Define la orientación del texto (derecha a izquierda).
* @param {boolean} props.loading - Muestra el loader si está cargando.
* @param {VM} props.vm - Instancia del Virtual Machine (VM) de Scratch.
* @returns {JSX.Element} El componente visual del escenario Vision Kit.
*/
const StageWrapperComponent = function ({
isFullScreen,
isRtl,
loading,
vm
}) {
return (
<Box
className={classNames(
Expand All @@ -31,39 +34,20 @@ const StageWrapperComponent = function (props) {
)}
dir={isRtl ? 'rtl' : 'ltr'}
>
<Box className={styles.stageMenuWrapper}>
<StageHeader
manuallySaveThumbnails={manuallySaveThumbnails}
onUpdateProjectThumbnail={onUpdateProjectThumbnail}
stageSize={stageSize}
vm={vm}
/>
</Box>
<Box className={styles.stageCanvasWrapper}>
{
isRendererSupported ?
<Stage
stageSize={stageSize}
vm={vm}
/> :
null
}
</Box>
{loading ? (
<Loader isFullScreen={isFullScreen} />
) : null}
{/* 🔹 Reemplazamos el escenario normal por la vista de Vision Kit */}
<div className={styles.visionFullScreen}>
<VisionViewer runtime={vm.runtime} />
</div>

{loading ? <Loader isFullScreen={isFullScreen} /> : null}
</Box>
);
};

StageWrapperComponent.propTypes = {
isFullScreen: PropTypes.bool,
isRendererSupported: PropTypes.bool.isRequired,
isRtl: PropTypes.bool.isRequired,
loading: PropTypes.bool,
manuallySaveThumbnails: PropTypes.bool,
onUpdateProjectThumbnail: PropTypes.func,
stageSize: PropTypes.oneOf(Object.keys(STAGE_DISPLAY_SIZES)).isRequired,
vm: PropTypes.instanceOf(VM).isRequired
};

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React from 'react';
import PropTypes from 'prop-types';

class VisionPreview extends React.Component{
constructor (props) {
super(props);
this.state = {dataURL: null};
}
componentDidMount (){
const {vm} = this.props;
this._handler = dataURL => this.setState({dataURL});
vm.on('VISION_IMAGE', this._handler);
}
componentWillUnmount (){
const {vm} = this.props;
if (this._handler) vm.off('VISION_IMAGE', this._handler);
}
render (){
return (
<div style={{border: '1px solid #e5e7eb', borderRadius: 12, padding: 8, marginTop: 8}}>
<div style={{fontSize: 14, fontWeight: 600, marginBottom: 6}}>{'Vista previa (Vision Kit)'}</div>
{this.state.dataURL ? (
<img
src={this.state.dataURL}
alt="preview"
style={{maxWidth: '100%'}}
/>
) : (
<div style={{fontSize: 12, color: '#6b7280'}}>
{'Aún no hay imagen procesada…'}
</div>
)}
</div>
);
}
}
VisionPreview.propTypes = {vm: PropTypes.object.isRequired};
export default VisionPreview;
22 changes: 22 additions & 0 deletions packages/scratch-gui/src/containers/vision-preview.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React from 'react';
import PropTypes from 'prop-types';
import VisionPreview from '../components/vision-preview/vision-preview';

/**
* Contenedor del componente VisionPreview.
* Renderiza la vista previa del Vision Kit y recibe la instancia de VM como prop.
*
* @component
* @param {object} props - Propiedades del componente
* @param {object} props.vm - Instancia de scratch-vm que maneja la lógica del proyecto
* @returns {JSX.Element} El componente VisionPreview con la prop vm
*/
const VisionPreviewContainer = ({vm}) => (
<VisionPreview vm={vm} />
);

VisionPreviewContainer.propTypes = {
vm: PropTypes.object.isRequired
};

export default VisionPreviewContainer;
Loading
Loading