import { defaultSettings, settingsMap, useSettings } from '../../../settings.mjs'; import { themes } from '@strudel/codemirror'; import { Textbox } from '../textbox/Textbox.jsx'; import { confirmAndReloadPage, isUdels } from '../../util.mjs'; import { ButtonGroup } from './Forms.jsx'; import { AudioDeviceSelector } from './AudioDeviceSelector.jsx'; import { AudioEngineTargetSelector } from './AudioEngineTargetSelector.jsx'; import { confirmDialog } from '../../util.mjs'; import { DEFAULT_MAX_POLYPHONY, setMaxPolyphony, setMultiChannelOrbits } from '@strudel/webaudio'; import { SpecialActionButton } from '../button/action-button.jsx'; import { ImportPrebakeScriptButton } from './ImportPrebakeScriptButton.jsx'; function Checkbox({ label, value, onChange, disabled = false }) { return ( ); } function SelectInput({ value, options, onChange }) { return ( ); } function NumberSlider({ value, onChange, step = 1, ...rest }) { return (
onChange(Number(e.target.value))} {...rest} /> onChange(Number(e.target.value))} />
); } function FormItem({ label, children, sublabel }) { return (
{children}
); } const themeOptions = Object.fromEntries(Object.keys(themes).map((k) => [k, k])); const fontFamilyOptions = { monospace: 'monospace', Courier: 'Courier', CutiePi: 'CutiePi', JetBrains: 'JetBrains', Hack: 'Hack', FiraCode: 'FiraCode', 'FiraCode-SemiBold': 'FiraCode SemiBold', teletext: 'teletext', tic80: 'tic80', mode7: 'mode7', BigBlueTerminal: 'BigBlueTerminal', x3270: 'x3270', Monocraft: 'Monocraft', PressStart: 'PressStart2P', 'we-come-in-peace': 'we-come-in-peace', galactico: 'galactico', }; export function SettingsTab({ started }) { const { theme, keybindings, isBracketClosingEnabled, isBracketMatchingEnabled, isLineNumbersDisplayed, isPatternHighlightingEnabled, isActiveLineHighlighted, isAutoCompletionEnabled, isTooltipEnabled, isFlashEnabled, isButtonRowHidden, isCSSAnimationDisabled, isSyncEnabled, isLineWrappingEnabled, fontSize, fontFamily, panelPosition, audioDeviceName, audioEngineTarget, togglePanelTrigger, maxPolyphony, multiChannelOrbits, isTabIndentationEnabled, isMultiCursorEnabled, patternAutoStart, includePrebakeScriptInShare, } = useSettings(); const shouldAlwaysSync = isUdels(); const canChangeAudioDevice = AudioContext.prototype.setSinkId != null; return (
{canChangeAudioDevice && ( { confirmAndReloadPage(() => { settingsMap.setKey('audioDeviceName', audioDeviceName); }); }} /> )} { confirmAndReloadPage(() => { settingsMap.setKey('audioEngineTarget', target); }); }} /> { let v = parseInt(e.target.value); v = isNaN(v) ? DEFAULT_MAX_POLYPHONY : v; setMaxPolyphony(v); settingsMap.setKey('maxPolyphony', v); }} onChange={(v) => { v = Math.max(1, parseInt(v)); settingsMap.setKey('maxPolyphony', isNaN(v) ? undefined : v); }} type="number" placeholder="" value={maxPolyphony ?? ''} /> { const val = cbEvent.target.checked; confirmAndReloadPage(() => { settingsMap.setKey('multiChannelOrbits', val); setMultiChannelOrbits(val); }); }} value={multiChannelOrbits} /> settingsMap.setKey('theme', theme)} />
settingsMap.setKey('fontFamily', fontFamily)} /> settingsMap.setKey('fontSize', fontSize)} min={10} max={40} step={2} />
settingsMap.setKey('includePrebakeScriptInShare', cbEvent.target.checked)} value={includePrebakeScriptInShare} /> settingsMap.setKey('keybindings', keybindings)} items={{ codemirror: 'Codemirror', vim: 'Vim', emacs: 'Emacs', vscode: 'VSCode' }} > settingsMap.setKey('panelPosition', value)} items={{ bottom: 'Bottom', right: 'Right' }} > settingsMap.setKey('togglePanelTrigger', value)} items={{ click: 'Click', hover: 'Hover' }} /> settingsMap.setKey('isBracketMatchingEnabled', cbEvent.target.checked)} value={isBracketMatchingEnabled} /> settingsMap.setKey('isBracketClosingEnabled', cbEvent.target.checked)} value={isBracketClosingEnabled} /> settingsMap.setKey('isLineNumbersDisplayed', cbEvent.target.checked)} value={isLineNumbersDisplayed} /> settingsMap.setKey('isActiveLineHighlighted', cbEvent.target.checked)} value={isActiveLineHighlighted} /> settingsMap.setKey('isPatternHighlightingEnabled', cbEvent.target.checked)} value={isPatternHighlightingEnabled} /> settingsMap.setKey('isAutoCompletionEnabled', cbEvent.target.checked)} value={isAutoCompletionEnabled} /> settingsMap.setKey('isTooltipEnabled', cbEvent.target.checked)} value={isTooltipEnabled} /> settingsMap.setKey('isLineWrappingEnabled', cbEvent.target.checked)} value={isLineWrappingEnabled} /> settingsMap.setKey('isTabIndentationEnabled', cbEvent.target.checked)} value={isTabIndentationEnabled} /> settingsMap.setKey('isMultiCursorEnabled', cbEvent.target.checked)} value={isMultiCursorEnabled} /> settingsMap.setKey('isFlashEnabled', cbEvent.target.checked)} value={isFlashEnabled} /> { const newVal = cbEvent.target.checked; confirmAndReloadPage(() => { settingsMap.setKey('isSyncEnabled', newVal); }); }} disabled={shouldAlwaysSync} value={isSyncEnabled} /> settingsMap.setKey('isButtonRowHidden', cbEvent.target.checked)} value={isButtonRowHidden} /> settingsMap.setKey('isCSSAnimationDisabled', cbEvent.target.checked)} value={isCSSAnimationDisabled} /> settingsMap.setKey('patternAutoStart', cbEvent.target.checked)} value={patternAutoStart} /> Try clicking the logo in the top left! { confirmDialog('Sure?').then((r) => { if (r) { const { userPatterns } = settingsMap.get(); // keep current patterns settingsMap.set({ ...defaultSettings, userPatterns }); } }); }} > restore default settings
); }