Skip to content

Commit

Permalink
Update toolbar, smarter hiding of labels
Browse files Browse the repository at this point in the history
  • Loading branch information
WardBrian committed Jul 29, 2024
1 parent e63959e commit 20168e5
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 76 deletions.
32 changes: 14 additions & 18 deletions gui/src/app/FileEditor/StanFileEditor.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { AutoFixHigh, Cancel, Settings } from "@mui/icons-material";
import useMediaQuery from "@mui/material/useMediaQuery";
import { SplitDirection, Splitter } from "@SpComponents/Splitter";
import StanCompileResultWindow from "@SpComponents/StanCompileResultWindow";
import TextEditor, { ToolbarItem } from "@SpComponents/TextEditor";
Expand Down Expand Up @@ -123,7 +122,6 @@ const StanFileEditor: FunctionComponent<Props> = ({
}
}, [fileContent, handleCompile, didInitialCompile]);

const showLabelsOnButtons = useMediaQuery("(min-width:600px)");
const [syntaxWindowVisible, setSyntaxWindowVisible] = useState(false);

const toolbarItems: ToolbarItem[] = useMemo(() => {
Expand All @@ -134,7 +132,7 @@ const StanFileEditor: FunctionComponent<Props> = ({
ret.push({
type: "button",
icon: <Cancel />,
label: showLabelsOnButtons ? "Syntax error" : "",
label: "Syntax error",
color: "darkred",
tooltip: "Syntax error in Stan file",
onClick: () => {
Expand All @@ -145,7 +143,7 @@ const StanFileEditor: FunctionComponent<Props> = ({
ret.push({
type: "button",
icon: <Cancel />,
label: showLabelsOnButtons ? "Syntax warning" : "",
label: "Syntax warning",
color: "blue",
tooltip: "Syntax warning in Stan file",
onClick: () => {
Expand All @@ -155,25 +153,23 @@ const StanFileEditor: FunctionComponent<Props> = ({
}

// auto format
if (!readOnly) {
if (editedFileContent) {
ret.push({
type: "button",
icon: <AutoFixHigh />,
tooltip: "Auto format this stan file",
label: showLabelsOnButtons ? "auto format" : undefined,
onClick: requestFormat,
color: "darkblue",
});
}
if (!readOnly && editedFileContent && validSyntax) {
ret.push({
type: "button",
icon: <AutoFixHigh />,
tooltip: "Auto format this stan file",
label: "Auto format",
onClick: requestFormat,
color: "darkblue",
});
}
if (editedFileContent && editedFileContent === fileContent) {
if (compileStatus !== "compiling") {
if (validSyntax) {
ret.push({
type: "button",
tooltip: "Compile Stan model",
label: "compile",
label: "Compile",
icon: <Settings />,
onClick: handleCompile,
color: "darkblue",
Expand All @@ -183,7 +179,8 @@ const StanFileEditor: FunctionComponent<Props> = ({
if (compileStatus !== "") {
ret.push({
type: "text",
label: compileMessage,
label:
compileMessage.charAt(0).toUpperCase() + compileMessage.slice(1),
color:
compileStatus === "compiled"
? "green"
Expand All @@ -200,7 +197,6 @@ const StanFileEditor: FunctionComponent<Props> = ({
fileContent,
handleCompile,
requestFormat,
showLabelsOnButtons,
validSyntax,
compileStatus,
compileMessage,
Expand Down
137 changes: 90 additions & 47 deletions gui/src/app/FileEditor/TextEditor.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { SmallIconButton } from "@fi-sci/misc";
import { Editor, loader, useMonaco } from "@monaco-editor/react";
import { Save } from "@mui/icons-material";
import Button from "@mui/material/Button";
import Link from "@mui/material/Link";
import monacoAddStanLang from "@SpComponents/stanLang";
import { CodeMarker } from "@SpStanc/Linting";
import { editor, MarkerSeverity } from "monaco-editor";
import {
FunctionComponent,
PropsWithChildren,
useCallback,
useEffect,
useMemo,
useState,
} from "react";

Expand All @@ -36,7 +36,7 @@ export type ToolbarItem =
tooltip?: string;
label?: string;
icon?: any;
onClick?: () => void;
onClick: () => void;
color?: string;
}
| {
Expand Down Expand Up @@ -131,32 +131,19 @@ const TextEditor: FunctionComponent<Props> = ({
[onSaveText, readOnly],
);

const edited = useMemo(() => {
return editedText !== text;
}, [editedText, text]);

return (
<div className="EditorWithToolbar" onKeyDown={handleKeyDown}>
<NotSelectable>
<div className="EditorMenuBar">
<span className="EditorTitle">{label}</span>
&nbsp;&nbsp;&nbsp;
{!readOnly && text !== editedText && (
<SmallIconButton
onClick={onSaveText}
icon={<Save />}
title="Save file"
disabled={text === editedText}
label="save"
/>
)}
&nbsp;&nbsp;&nbsp;
{editedText !== text && <span className="EditedText">edited</span>}
&nbsp;&nbsp;&nbsp;
{readOnly && <span className="ReadOnlyText">read only</span>}
&nbsp;&nbsp;&nbsp;
{toolbarItems &&
toolbarItems.map((item, i) => (
<ToolbarItemComponent key={i} item={item} />
))}
</div>
</NotSelectable>
<ToolBar
items={toolbarItems || []}
label={label}
onSaveText={onSaveText}
edited={edited}
readOnly={!!readOnly}
/>
<Editor
defaultLanguage={language}
onChange={handleChange}
Expand Down Expand Up @@ -186,39 +173,95 @@ const toMonacoMarkerSeverity = (
}
};

type ToolbarProps = {
items: ToolbarItem[];
label: string;
onSaveText: () => void;
edited: boolean;
readOnly: boolean;
};

const ToolBar: FunctionComponent<ToolbarProps> = ({
items,
label,
onSaveText,
edited,
readOnly,
}) => {
const toolBarItems = useMemo(() => {
const editorItems: ToolbarItem[] = [];

if (!readOnly && edited) {
editorItems.push({
type: "button",
icon: <Save />,
onClick: onSaveText,
tooltip: "Save file",
label: "Save",
});
}

if (edited) {
editorItems.push({
type: "text",
label: "Edited",
color: "red",
});
}

if (readOnly) {
editorItems.push({
type: "text",
label: "Read Only",
color: "gray",
});
}

return editorItems.concat(items);
}, [edited, items, onSaveText, readOnly]);

return (
<div className="NotSelectable">
<div className="EditorMenuBar">
<span className="EditorTitle">{label}</span>
{toolBarItems &&
toolBarItems.map((item, i) => (
<ToolbarItemComponent key={i} item={item} />
))}
</div>
</div>
);
};

const ToolbarItemComponent: FunctionComponent<{ item: ToolbarItem }> = ({
item,
}) => {
if (item.type === "button") {
const { onClick, color, label, tooltip, icon } = item;
if (icon) {
return (
<span style={{ color }}>
<SmallIconButton
<span className="EditorToolbarItem" style={{ color }}>
<Button
startIcon={icon}
onClick={onClick}
icon={icon}
title={tooltip}
label={label}
disabled={!onClick}
/>
&nbsp;&nbsp;&nbsp;
color="inherit"
size="small"
title={tooltip}
>
{label && <span className="ToolbarButtonText">{label}</span>}
</Button>
</span>
);
} else {
if (!onClick) {
return (
<span style={{ color: color || "gray" }} title={label}>
{label}&nbsp;&nbsp;&nbsp;
</span>
);
}
return (
<span>
<span className="EditorToolbarItem">
<Link
onClick={onClick}
color={color || "gray"}
component="button"
underline="none"
title={tooltip}
>
{label}
</Link>
Expand All @@ -228,7 +271,11 @@ const ToolbarItemComponent: FunctionComponent<{ item: ToolbarItem }> = ({
}
} else if (item.type === "text") {
return (
<span style={{ color: item.color || "gray" }} title={item.label}>
<span
className="EditorToolbarItem"
style={{ color: item.color || "gray" }}
title={item.label}
>
{item.label}&nbsp;&nbsp;&nbsp;
</span>
);
Expand All @@ -237,10 +284,6 @@ const ToolbarItemComponent: FunctionComponent<{ item: ToolbarItem }> = ({
}
};

const NotSelectable: FunctionComponent<PropsWithChildren> = ({ children }) => {
return <div className="NotSelectable">{children}</div>;
};

const createHintTextContentWidget = (content: string | HTMLSpanElement) => {
return {
getDomNode: () => {
Expand Down
47 changes: 36 additions & 11 deletions gui/src/localStyles.css
Original file line number Diff line number Diff line change
Expand Up @@ -84,28 +84,53 @@

/* Text Editors ------ */

:root {
--editor-menu-height: 30px;
}

.EditorMenuBar {
background-color: lightgray;
height: 25px;
height: var(--editor-menu-height);
position: relative;
display: flex;
align-content: center;
align-items: center;
container-name: EditorMenuBar;
container-type: inline-size;
white-space: nowrap;
overflow-x: auto;
overflow-y: hidden;
}

.EditorWithToolbar {
height: calc(100% - 25px);
height: calc(100% - var(--editor-menu-height));
}

span.EditorTitle {
position: relative;
top: 1px;
padding-left: 5px;
span.EditorToolbarItem {
padding-left: 15px;
}

.EditedText {
color: #a33;
font-size: 12px;
.ToolbarButtonText {
text-transform: none;
font-weight: normal;
letter-spacing: normal;
display: inline-block;
white-space: normal;
}

.ReadOnlyText {
color: gray;
@container EditorMenuBar (max-width: 500px) {
.ToolbarButtonText {
display: none;
width: 0;
}
span.EditorToolbarItem {
padding: 0px;
}
}

span.EditorTitle {
padding-left: 5px;
font-weight: 500;
}

.NotSelectable {
Expand Down

0 comments on commit 20168e5

Please sign in to comment.