This commit is contained in:
nickofolas 2022-04-13 14:42:07 -05:00
parent 1f9414fd0e
commit 567fcf8fb6
4 changed files with 79 additions and 68 deletions

@ -9,8 +9,8 @@ import Select from "@mui/material/Select";
import Switch from "@mui/material/Switch"; import Switch from "@mui/material/Switch";
import MenuItem from "@mui/material/MenuItem"; import MenuItem from "@mui/material/MenuItem";
import TextField from "@mui/material/TextField"; import TextField from "@mui/material/TextField";
import EditIcon from '@mui/icons-material/Edit'; import EditIcon from "@mui/icons-material/Edit";
import SaveIcon from '@mui/icons-material/Save'; import SaveIcon from "@mui/icons-material/Save";
import { ThemeEditorModal } from "./ThemeEditorModal"; import { ThemeEditorModal } from "./ThemeEditorModal";
@ -48,10 +48,7 @@ export function OptionsModal(props: IProps): React.ReactElement {
return ( return (
<Modal open={props.open} onClose={props.onClose}> <Modal open={props.open} onClose={props.onClose}>
<ThemeEditorModal <ThemeEditorModal open={themeEditorOpen} onClose={() => setThemeEditorOpen(false)} />
open={themeEditorOpen}
onClose={() => setThemeEditorOpen(false)}
/>
<Box display="flex" flexDirection="row" alignItems="center"> <Box display="flex" flexDirection="row" alignItems="center">
<Typography>Theme: </Typography> <Typography>Theme: </Typography>
<Select onChange={(event) => setTheme(event.target.value)} value={theme}> <Select onChange={(event) => setTheme(event.target.value)} value={theme}>
@ -93,7 +90,9 @@ export function OptionsModal(props: IProps): React.ReactElement {
<TextField type="number" label="Font size" value={fontSize} onChange={onFontChange} /> <TextField type="number" label="Font size" value={fontSize} onChange={onFontChange} />
</Box> </Box>
<br /> <br />
<Button onClick={save} startIcon={<SaveIcon />}>Save</Button> <Button onClick={save} startIcon={<SaveIcon />}>
Save
</Button>
</Modal> </Modal>
); );
} }

@ -10,8 +10,8 @@ import TextField from "@mui/material/TextField";
import Paper from "@mui/material/Paper"; import Paper from "@mui/material/Paper";
import IconButton from "@mui/material/IconButton"; import IconButton from "@mui/material/IconButton";
import ReplyIcon from "@mui/icons-material/Reply"; import ReplyIcon from "@mui/icons-material/Reply";
import HistoryIcon from '@mui/icons-material/History'; import HistoryIcon from "@mui/icons-material/History";
import SaveIcon from '@mui/icons-material/Save'; import SaveIcon from "@mui/icons-material/Save";
import { Settings } from "../../Settings/Settings"; import { Settings } from "../../Settings/Settings";
import { OptionSwitch } from "../../ui/React/OptionSwitch"; import { OptionSwitch } from "../../ui/React/OptionSwitch";
@ -99,10 +99,13 @@ export function ThemeEditorModal(props: IProps): React.ReactElement {
} }
return ( return (
<Modal open={props.open} onClose={() => { <Modal
setThemeCopy(Settings.EditorTheme); open={props.open}
props.onClose(); onClose={() => {
}}> setThemeCopy(Settings.EditorTheme);
props.onClose();
}}
>
<Typography variant="h4">Customize Editor theme</Typography> <Typography variant="h4">Customize Editor theme</Typography>
<Typography>Hover over input boxes for more information</Typography> <Typography>Hover over input boxes for more information</Typography>
<Paper sx={{ p: 1, my: 1 }}> <Paper sx={{ p: 1, my: 1 }}>
@ -115,8 +118,8 @@ export function ThemeEditorModal(props: IProps): React.ReactElement {
text="Use light theme as base" text="Use light theme as base"
tooltip={ tooltip={
<> <>
If enabled, the <code>vs</code> light theme will be used as the If enabled, the <code>vs</code> light theme will be used as the theme base, otherwise,{" "}
theme base, otherwise, <code>vs-dark</code> will be used. <code>vs-dark</code> will be used.
</> </>
} }
/> />
@ -258,19 +261,26 @@ export function ThemeEditorModal(props: IProps): React.ReactElement {
onChange={onThemeChange} onChange={onThemeChange}
/> />
<Box sx={{ mt: 1 }}> <Box sx={{ mt: 1 }}>
<Button onClick={() => { <Button
Settings.EditorTheme = { ...themeCopy }; onClick={() => {
props.onClose() Settings.EditorTheme = { ...themeCopy };
}} startIcon={<SaveIcon />}>Save</Button> props.onClose();
}}
startIcon={<SaveIcon />}
>
Save
</Button>
<Button <Button
onClick={() => { onClick={() => {
setThemeCopy(defaultMonacoTheme); setThemeCopy(defaultMonacoTheme);
rerender(); rerender();
}} }}
startIcon={<HistoryIcon />} startIcon={<HistoryIcon />}
>Reset to default</Button> >
Reset to default
</Button>
</Box> </Box>
</Paper> </Paper>
</Modal> </Modal>
) );
} }

@ -53,20 +53,20 @@ export const defaultMonacoTheme: IScriptEditorTheme = {
keyword: "569CD6", keyword: "569CD6",
comment: "6A9955", comment: "6A9955",
constant: "569CD6", constant: "569CD6",
error: "F44747" error: "F44747",
}, },
ui: { ui: {
line: "1E1E1E", line: "1E1E1E",
panel: { panel: {
bg: "252526", bg: "252526",
selected: "252526", selected: "252526",
border: "1E1E1E" border: "1E1E1E",
}, },
selection: { selection: {
bg: "ADD6FF26" bg: "ADD6FF26",
} },
} },
} };
// Regex used for token color validation // Regex used for token color validation
// https://github.com/microsoft/vscode/blob/973684056e67153952f495fce93bf50d0ec0b892/src/vs/editor/common/languages/supports/tokenization.ts#L153 // https://github.com/microsoft/vscode/blob/973684056e67153952f495fce93bf50d0ec0b892/src/vs/editor/common/languages/supports/tokenization.ts#L153
@ -93,122 +93,124 @@ export const sanitizeTheme = (theme: IScriptEditorTheme): void => {
if (!v.match(colorRegExp)) block[k] = "FF0000"; if (!v.match(colorRegExp)) block[k] = "FF0000";
} }
} }
} };
repairBlock(v); repairBlock(v);
} }
} };
export function makeTheme(theme: IScriptEditorTheme): any { export function makeTheme(theme: IScriptEditorTheme): any {
const themeRules = [ const themeRules = [
{ {
token: "", token: "",
background: theme.ui.line, background: theme.ui.line,
foreground: theme.common.fg foreground: theme.common.fg,
}, },
{ {
token: "identifier", token: "identifier",
foreground: theme.common.accent foreground: theme.common.accent,
}, },
{ {
token: "keyword", token: "keyword",
foreground: theme.syntax.keyword foreground: theme.syntax.keyword,
}, },
{ {
token: "string", token: "string",
foreground: theme.syntax.string foreground: theme.syntax.string,
}, },
{ {
token: "string.escape", token: "string.escape",
foreground: theme.syntax.regexp foreground: theme.syntax.regexp,
}, },
{ {
token: "comment", token: "comment",
foreground: theme.syntax.comment foreground: theme.syntax.comment,
}, },
{ {
token: "constant", token: "constant",
foreground: theme.syntax.constant foreground: theme.syntax.constant,
}, },
{ {
token: "entity", token: "entity",
foreground: theme.syntax.entity foreground: theme.syntax.entity,
}, },
{ {
token: "type", token: "type",
foreground: theme.syntax.tag foreground: theme.syntax.tag,
}, },
{ {
token: "tag", token: "tag",
foreground: theme.syntax.tag foreground: theme.syntax.tag,
}, },
{ {
token: "regexp", token: "regexp",
foreground: theme.syntax.regexp foreground: theme.syntax.regexp,
}, },
{ {
token: "attribute", token: "attribute",
foreground: theme.syntax.tag foreground: theme.syntax.tag,
}, },
{ {
token: "constructor", token: "constructor",
foreground: theme.syntax.markup foreground: theme.syntax.markup,
}, },
{ {
token: "invalid", token: "invalid",
foreground: theme.syntax.error foreground: theme.syntax.error,
}, },
{ {
token: "number", token: "number",
foreground: theme.common.accent foreground: theme.common.accent,
}, },
{ {
token: "delimiter", token: "delimiter",
foreground: theme.common.fg foreground: theme.common.fg,
}, },
// Custom tokens // Custom tokens
{ {
token: "ns", token: "ns",
foreground: theme.syntax.tag foreground: theme.syntax.tag,
}, },
{ {
token: "netscriptfunction", token: "netscriptfunction",
foreground: theme.syntax.markup foreground: theme.syntax.markup,
}, },
{ {
token: "otherkeywords", token: "otherkeywords",
foreground: theme.syntax.keyword foreground: theme.syntax.keyword,
}, },
{ {
token: "otherkeyvars", token: "otherkeyvars",
foreground: theme.common.accent foreground: theme.common.accent,
}, },
{ {
token: "this", token: "this",
foreground: theme.syntax.tag foreground: theme.syntax.tag,
} },
]; ];
const themeColors = Object.fromEntries([ const themeColors = Object.fromEntries(
["editor.background", theme.common.bg], [
["editor.foreground", theme.common.fg], ["editor.background", theme.common.bg],
["editor.lineHighlightBackground", theme.ui.line], ["editor.foreground", theme.common.fg],
["editor.selectionBackground", theme.ui.selection.bg], ["editor.lineHighlightBackground", theme.ui.line],
["editor.selectionBackground", theme.ui.selection.bg],
["editorSuggestWidget.background", theme.ui.panel.bg], ["editorSuggestWidget.background", theme.ui.panel.bg],
["editorSuggestWidget.border", theme.ui.panel.border], ["editorSuggestWidget.border", theme.ui.panel.border],
["editorSuggestWidget.selectedBackground", theme.ui.panel.selected], ["editorSuggestWidget.selectedBackground", theme.ui.panel.selected],
["editorHoverWidget.background", theme.ui.panel.bg], ["editorHoverWidget.background", theme.ui.panel.bg],
["editorHoverWidget.border", theme.ui.panel.border], ["editorHoverWidget.border", theme.ui.panel.border],
["editorWidget.background", theme.ui.panel.bg], ["editorWidget.background", theme.ui.panel.bg],
["editorWidget.border", theme.ui.panel.border], ["editorWidget.border", theme.ui.panel.border],
["input.background", theme.ui.panel.bg], ["input.background", theme.ui.panel.bg],
["input.border", theme.ui.panel.border] ["input.border", theme.ui.panel.border],
].map(([k, v]) => [k, "#" + v])); ].map(([k, v]) => [k, "#" + v]),
);
return { base: theme.base, inherit: theme.inherit, rules: themeRules, colors: themeColors } return { base: theme.base, inherit: theme.inherit, rules: themeRules, colors: themeColors };
} }
export async function loadThemes(monaco: { editor: any }): Promise<void> { export async function loadThemes(monaco: { editor: any }): Promise<void> {

@ -266,7 +266,7 @@ export const Settings: ISettings & ISelfInitializer & ISelfLoading = {
MonacoFontSize: 20, MonacoFontSize: 20,
MonacoVim: false, MonacoVim: false,
MonacoWordWrap: "off", MonacoWordWrap: "off",
theme: { ...defaultTheme }, theme: { ...defaultTheme },
styles: { ...defaultStyles }, styles: { ...defaultStyles },
overview: defaultSettings.overview, overview: defaultSettings.overview,