Skip to content
Merged
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
8 changes: 5 additions & 3 deletions components/buttons/fullscreenbutton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@ export default function FullscreenButton() {

return (
<Button
onClick={() => {
setRequestFullscreen(true);
onClick={() => setRequestFullscreen(true)}
sx={{
color: theme.palette.dracula.cyan,
minWidth: 0,
padding: '2px'
}}
sx={{ color: theme.palette.dracula.cyan }}
>
<FullscreenIcon />
</Button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import Hd from '@mui/icons-material/Hd';
import Sd from '@mui/icons-material/Sd';
import Button from '@mui/material/Button';
import { useTheme } from '@mui/material/styles';
import Resolution from 'components/resolution';
import { useAtom, useAtomValue } from 'jotai';
import { halfResolutionAtom } from 'lib/atoms/atoms';

Expand All @@ -11,18 +12,27 @@ const ScaleIcon = () => {
return halfResolution ? <Sd /> : <Hd />;
};

export default function ScaleButton() {
export default function ResolutionButton() {
const [halfResolution, setHalfResolution] = useAtom(halfResolutionAtom);
const theme = useTheme();

// Define styles outside the return for better readability
const buttonStyles = {
padding: '2px',
minWidth: 0,
color: halfResolution ? theme.palette.primary.contrastText : theme.palette.primary.light,
'&:hover': {
backgroundColor: 'rgba(255, 255, 255, 0.08)'
}
};

return (
<Button
onClick={() => setHalfResolution(!halfResolution)}
sx={
halfResolution
? { color: theme.palette.primary.contrastText }
: { color: theme.palette.primary.light }
}
sx={buttonStyles}
aria-label={halfResolution ? 'Full resolution' : 'Half resolution'}
>
<Resolution />
<ScaleIcon />
</Button>
);
Expand Down
151 changes: 96 additions & 55 deletions components/editor/editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import Giscus from '@giscus/react';
import Box from '@mui/material/Box';
import Button from '@mui/material/Button';
import Grid from '@mui/material/Grid';
import Stack from '@mui/material/Stack';
import { useTheme } from '@mui/material/styles';
import useMediaQuery from '@mui/material/useMediaQuery';
import { User } from '@supabase/supabase-js';
Expand All @@ -15,7 +16,7 @@ import PlayPauseButton from 'components/buttons/playpausebutton';
import RecordButton from 'components/buttons/recordbutton';
import ReloadButton from 'components/buttons/reloadbutton';
import ResetButton from 'components/buttons/resetbutton';
import ScaleButton from 'components/buttons/scalebutton';
import ResolutionButton from 'components/buttons/resolutionbutton';
import VimButton from 'components/buttons/vimbutton';
import EntryPointDisplay from 'components/editor/entrypointdisplay';
import { MetadataEditor } from 'components/editor/metadataeditor';
Expand All @@ -31,6 +32,7 @@ import { createClient } from 'lib/supabase/client';
import dynamic from 'next/dynamic';
import { useCallback } from 'react';
import { ItemWithTransitionSignal } from 'theme/itemwithtransition';
import { MonacoTheme } from 'theme/monacotheme';
import { Frame } from 'theme/theme';
import ConfigurationPicker from './configurationpicker';
import Explainer from './explainer';
Expand All @@ -43,21 +45,23 @@ interface EditorProps {

function Comments() {
return (
<Giscus
id="comments"
repo="compute-toys/comments"
repoId="R_kgDOKRTytw"
category="Announcements"
categoryId="DIC_kwDOKRTyt84CllQC"
mapping="pathname"
strict="0"
reactionsEnabled="1"
emitMetadata="1"
inputPosition="top"
theme="dark"
lang="en"
loading="lazy"
/>
<Box sx={{ marginTop: { xs: '2em', sm: 0 } }}>
<Giscus
id="comments"
repo="compute-toys/comments"
repoId="R_kgDOKRTytw"
category="Announcements"
categoryId="DIC_kwDOKRTyt84CllQC"
mapping="pathname"
strict="0"
reactionsEnabled="1"
emitMetadata="1"
inputPosition="top"
theme="dark"
lang="en"
loading="lazy"
/>
</Box>
);
}

Expand All @@ -74,9 +78,6 @@ export default function Editor(props: EditorProps) {
}, []);

const Timer = dynamic(() => import('components/timer'), { ssr: false });
const Resolution = dynamic(() => import('components/resolution'), {
ssr: false
});

let metadataEditor: JSX.Element | null = null;
if (supabase && !props.standalone) {
Expand All @@ -102,6 +103,43 @@ export default function Editor(props: EditorProps) {
};
}

const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down('md'));

const monacoOptions = (isMobile: boolean) => ({
stopRenderingLineAfter: isMobile ? 500 : 1000,
fontSize: isMobile ? 12 : 12,
lineHeight: isMobile ? 16 : 18,
fontFamily: "'Fira Code', monospace",
'bracketPairColorization.enabled': true,
mouseWheelZoom: true,
minimap: { enabled: !isMobile },
scrollBeyondLastLine: !isMobile,
automaticLayout: true,
lineNumbersMinChars: isMobile ? 3 : 4,
useShadowDOM: false // https://github.com/microsoft/monaco-editor/issues/3602
});

const monacoEditorWithButtons = (
<ItemWithTransitionSignal transitionAtom={saveColorTransitionSignalAtom}>
<div className="vim-status"></div>
<MonacoTheme>
<Monaco editorOptions={monacoOptions(isMobile)} />
</MonacoTheme>
<Box sx={{ paddingTop: '4px' }}>
<Box sx={{ display: 'flex', justifyContent: 'space-between' }}>
<Button style={{ pointerEvents: 'none' }} />
<div>
<ReloadButton />
<HotReloadToggle />
<Explainer />
</div>
<VimButton />
</Box>
</Box>
</ItemWithTransitionSignal>
);

const leftPanel = (
<div ref={renderParentNodeRef}>
<ItemWithTransitionSignal transitionAtom={saveColorTransitionSignalAtom}>
Expand All @@ -117,61 +155,63 @@ export default function Editor(props: EditorProps) {
embed={props.embed}
/>
</Frame>
<Grid container>
<Grid item sx={{ textAlign: 'left' }} xs={2}>
<Timer />
<Grid
container
sx={{
display: 'flex',
alignItems: 'center', // Vertically centers
justifyContent: 'center', // Horizontally centers
height: '100%', // Ensures vertical alignment works
padding: '5px 5px 4px 5px' // top right bottom left
}}
>
<Grid item xs={2}>
<Stack
direction="column"
justifyContent="flex-start"
alignItems="flex-start"
>
<Timer />
</Stack>
</Grid>
<Grid item xs={7}>
<Grid item xs={8}>
<PlayPauseButton />
<ResetButton />
<RecordButton />
</Grid>
<Grid item sx={{ textAlign: 'right' }} xs={3}>
<Resolution />
<ScaleButton />
<FullscreenButton />
<Grid item xs={2}>
<Stack direction="column" justifyContent="flex-end" alignItems="flex-end">
<ResolutionButton />
<FullscreenButton />
</Stack>
</Grid>
</Grid>
<UniformSliders />
</ItemWithTransitionSignal>
{metadataEditor}
{shaderID ? <Comments /> : null}

{/* Show code right after shader metadata on mobile */}
{isMobile && monacoEditorWithButtons}

{/* Don't show comments on mobile */}
{!isMobile && (shaderID ? <Comments /> : null)}
</div>
);

const theme = useTheme();

const rightPanel = (
<div>
<ItemWithTransitionSignal transitionAtom={saveColorTransitionSignalAtom}>
<div className="vim-status"></div>
<Monaco
editorOptions={{
stopRenderingLineAfter: 1000,
fontFamily: "'Fira Code', monospace",
'bracketPairColorization.enabled': true,
mouseWheelZoom: true
//fontLigatures: true,
}}
/>
<Box sx={{ paddingTop: '4px' }}>
<Box sx={{ display: 'flex', justifyContent: 'space-between' }}>
<Button style={{ pointerEvents: 'none' }} />{' '}
{/* invisible button, used only for centering */}
<div>
<ReloadButton />
<HotReloadToggle />
<Explainer />
</div>
<VimButton />
</Box>
</Box>
</ItemWithTransitionSignal>
{!isMobile && monacoEditorWithButtons}
<Grid
container
spacing={2}
sx={{
flexWrap: useMediaQuery(theme.breakpoints.up('sm')) ? 'nowrap' : 'wrap'
flexWrap: useMediaQuery(theme.breakpoints.up('sm')) ? 'nowrap' : 'wrap',
'@media (max-width: 600px)': {
'& > .MuiGrid-item': {
minHeight: 'none',
maxHeight: '400px' // Prevents stretch on mobiles
}
}
}}
>
<Grid item>
Expand All @@ -184,6 +224,7 @@ export default function Editor(props: EditorProps) {
<EntryPointDisplay />
</Grid>
</Grid>
{isMobile && (shaderID ? <Comments /> : null)}
</div>
);

Expand Down
24 changes: 18 additions & 6 deletions components/editor/explainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,18 @@ import DraggableWindow from '../global/draggable-window';
import { HiLite } from '../global/hilite';
import Logo from '../global/logo';

const EXPLAINER_INNER_HEIGHT = '570';

const ExplainerBody = () => {
const theme = useTheme();
const prelude = useAtomValue(wgputoyPreludeAtom);

return (
<div
style={{
// Styles for inner text (Chrome/Webkit/Mobiles)
textAlign: 'left',
width: 'min-content',
overflowY: 'auto',
width: '100%',
overflowY: 'unset',
padding: '8px',
height: `${EXPLAINER_INNER_HEIGHT}px`,
color: theme.palette.primary.main
}}
>
Expand Down Expand Up @@ -265,7 +263,21 @@ export default function Explainer() {
<DraggableWindow
hidden={explainerHidden}
setHidden={setExplainerHidden}
sx={{ paddingTop: '8px' }}
sx={{
//styles for the draggable window (Chrome/Webkit/Mobiles)
paddingTop: '8px',
width: '70vw',
maxWidth: '800px',
height: '80vh',
overflowX: 'auto',
zIndex: '9999999999',
//mobile specific
'@media (max-width: 600px)': {
width: '97vw',
height: '60vh',
maxHeight: '80%'
}
}}
>
<ExplainerBody />
</DraggableWindow>
Expand Down
33 changes: 33 additions & 0 deletions components/editor/monaco.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,39 @@ const Monaco = props => {
);
// https://github.com/microsoft/monaco-editor/issues/392
document.fonts.ready.then(() => monaco.editor.remeasureFonts());

// https://github.com/suren-atoyan/monaco-react/issues/733
const handleMouseEvent = (e: MonacoEditor.IEditorMouseEvent) => {
const type = e['changedTouches']
? MonacoEditor.MouseTargetType.UNKNOWN
: MonacoEditor.MouseTargetType.CONTENT_EMPTY;
if (e?.target?.type === type) {
setTimeout(() => {
const position = _editor.getPosition();
const line = position?.lineNumber || 1;
const column =
(_editor.getModel()?.getLineContent(line).length || 0) + 1;
_editor.setSelection(new monaco.Selection(line, column, line, column));
}, 12);
}
};
const handleTouchEvent = e => {
e.preventDefault();
const touch = e.changedTouches[0];
const mouseEvent = new MouseEvent('mouseup', {
bubbles: true,
cancelable: true,
clientX: touch.clientX,
clientY: touch.clientY,
buttons: 1
});
domNode!.dispatchEvent(mouseEvent);
};
const domNode = _editor.getDomNode();
_editor.onMouseDown(handleMouseEvent);
_editor.onMouseUp(handleMouseEvent);
domNode!.addEventListener('touchstart', handleTouchEvent, { passive: false });
domNode!.addEventListener('touchend', handleTouchEvent, { passive: false });
}}
options={props.editorOptions}
theme="global" // preference
Expand Down
17 changes: 7 additions & 10 deletions components/resolution.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,11 @@ export default function Resolution() {
const width = useAtomValue(widthAtom);
const height = useAtomValue(heightAtom);

if (width > 0 && height > 0) {
return (
<Fragment>
<span style={{ color: theme.palette.dracula.foreground }}>
{width}x{height}
</span>
</Fragment>
);
}
return null;
return (
<Fragment>
<span style={{ color: theme.palette.dracula.foreground }}>
{width ? `${width}x${height}` : ''}
</span>
</Fragment>
);
}
Loading