Adds support for dark themes.
This commit is contained in:
17
demo/.vscode/launch.json
vendored
17
demo/.vscode/launch.json
vendored
@@ -4,6 +4,12 @@
|
||||
// For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "java",
|
||||
"name": "CodeLens (Launch) - DemoLinkedLists",
|
||||
"request": "launch",
|
||||
"mainClass": "DemoLinkedLists"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
@@ -16,7 +22,7 @@
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "TypeScript - Demo: Doubly Linked List",
|
||||
"program": "${workspaceFolder}/js/dist/demo-doubly-linked-list",
|
||||
"program": "${workspaceFolder}/js/dist/demo_doubly-linked-list",
|
||||
"skipFiles": ["<node_internals>/**"],
|
||||
"preLaunchTask": "typescript-watch"
|
||||
},
|
||||
@@ -64,6 +70,15 @@
|
||||
"xdebugSettings": {
|
||||
"max_data": -1
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Java - Demo",
|
||||
"type": "java",
|
||||
"request": "launch",
|
||||
"mainClass": "DemoLinkedLists.java",
|
||||
"classPaths": ["${workspaceFolder}/java/json-simple-1.1.1.jar"],
|
||||
"sourcePaths": ["${workspaceFolder}/java/"],
|
||||
"cwd": "${workspaceFolder}/java"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -69,6 +69,7 @@ export class ConnectionHandler {
|
||||
throwIfNotAuthenticated();
|
||||
|
||||
const url = server.getIndexUrl({
|
||||
mode: "standalone",
|
||||
expression: this.watcher
|
||||
? this.watcher.expression
|
||||
: undefined,
|
||||
|
||||
@@ -34,13 +34,18 @@ export class Server {
|
||||
});
|
||||
}
|
||||
|
||||
public getIndexUrl(args: { expression?: string } = {}): string {
|
||||
public getIndexUrl(args: {
|
||||
expression?: string;
|
||||
mode: "standalone" | "webViewIFrame";
|
||||
}): string {
|
||||
const port = process.env.USE_DEV_UI ? 8080 : this.port;
|
||||
const expr =
|
||||
args.expression !== undefined
|
||||
? `&expression=${encodeURIComponent(args.expression)}`
|
||||
: "";
|
||||
return `http://localhost:${port}/index.html?serverPort=${this.port}&serverSecret=${this.secret}${expr}`;
|
||||
const inWebView =
|
||||
args.mode === "standalone" ? "" : "&mode=webViewIFrame";
|
||||
return `http://localhost:${port}/index.html?serverPort=${this.port}&serverSecret=${this.secret}${inWebView}${expr}`;
|
||||
}
|
||||
|
||||
public get mainBundleUrl(): string {
|
||||
|
||||
@@ -71,8 +71,10 @@ export function getHtml(server: Server) {
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
window.serverPort = ${server.port};
|
||||
window.serverSecret = ${JSON.stringify(server.secret)};
|
||||
window.webViewData = ${JSON.stringify({
|
||||
serverSecret: server.secret,
|
||||
serverPort: server.port,
|
||||
})};
|
||||
const api = window.VsCodeApi = acquireVsCodeApi();
|
||||
window.addEventListener('message', event => {
|
||||
if (event.source === window.frames[0]) {
|
||||
@@ -89,7 +91,9 @@ export function getHtml(server: Server) {
|
||||
</script>
|
||||
${
|
||||
isDev
|
||||
? `<iframe sandbox="allow-top-navigation allow-scripts allow-same-origin allow-popups allow-pointer-lock allow-forms" src="${server.getIndexUrl()}"></iframe>`
|
||||
? `<iframe sandbox="allow-top-navigation allow-scripts allow-same-origin allow-popups allow-pointer-lock allow-forms" src="${server.getIndexUrl(
|
||||
{ mode: "webViewIFrame" }
|
||||
)}"></iframe>`
|
||||
: `<script type="text/javascript" src="${server.mainBundleUrl}"></script>`
|
||||
}
|
||||
</body>
|
||||
|
||||
@@ -4,26 +4,34 @@ import { observer, disposeOnUnmount } from "mobx-react";
|
||||
import { observable, action, autorun } from "mobx";
|
||||
import * as monaco from "monaco-editor";
|
||||
|
||||
export function getModel(): monaco.editor.ITextModel {
|
||||
return monaco.editor.createModel(
|
||||
"",
|
||||
"javascript",
|
||||
monaco.Uri.parse(`file:///main.ts`)
|
||||
);
|
||||
}
|
||||
|
||||
@observer
|
||||
export class ExpressionInput extends React.Component<{ model: Model }> {
|
||||
@observable private editor: monaco.editor.IStandaloneCodeEditor | undefined;
|
||||
@observable private contentHeight: number | undefined = undefined;
|
||||
private model = getModel();
|
||||
private model = monaco.editor.createModel(
|
||||
"",
|
||||
"javascript",
|
||||
monaco.Uri.parse(`file:///main.ts`)
|
||||
);
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="component-monaco-editor">
|
||||
<div
|
||||
className="component-monaco-editor"
|
||||
style={{
|
||||
// The monaco editor does not have a padding, so we add our own.
|
||||
// We have to match the colors of monaco's background.
|
||||
backgroundColor:
|
||||
this.props.model.theme === "light"
|
||||
? "white"
|
||||
: "#263238",
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{ height: this.contentHeight }}
|
||||
className="part-editor"
|
||||
style={{
|
||||
height: this.contentHeight,
|
||||
}}
|
||||
ref={this.setEditorDiv}
|
||||
/>
|
||||
</div>
|
||||
@@ -68,8 +76,11 @@ export class ExpressionInput extends React.Component<{ model: Model }> {
|
||||
horizontalScrollbarSize: 0,
|
||||
verticalScrollbarSize: 0,
|
||||
},
|
||||
/*theme: { dark: "vs-dark", light: "vs-light" }[
|
||||
this.props.model.theme
|
||||
],*/
|
||||
});
|
||||
|
||||
//
|
||||
this.editor.onDidContentSizeChange(e => {
|
||||
this.contentHeight = e.contentHeight;
|
||||
});
|
||||
|
||||
@@ -1,93 +1,138 @@
|
||||
import React = require("react");
|
||||
import { Button, Spinner } from "@blueprintjs/core";
|
||||
import { observable } from "mobx";
|
||||
import { observable, action } from "mobx";
|
||||
import { observer } from "mobx-react";
|
||||
import { Model } from "../Model/Model";
|
||||
import { ExpressionInput } from "./ExpressionInput";
|
||||
import { Visualizer } from "./Visualizer";
|
||||
import classnames = require("classnames");
|
||||
import { ExpandedOptions } from "./ExpandedOptions";
|
||||
import { VisualizerHeaderDetails } from "./VisualizerHeaderDetails";
|
||||
|
||||
@observer
|
||||
export class GUI extends React.Component<{ model: Model }> {
|
||||
@observable text: string = "node";
|
||||
|
||||
@observable expanded = false;
|
||||
|
||||
render() {
|
||||
const m = this.props.model;
|
||||
return (
|
||||
<div className="component-GUI" tabIndex={0}>
|
||||
<div className="part-header">
|
||||
<ExpandButton
|
||||
expanded={this.expanded}
|
||||
setExpanded={v => (this.expanded = v)}
|
||||
/>
|
||||
<div className="part-header-content">
|
||||
<div className="part-header-main">
|
||||
<div className="part-expression-input ">
|
||||
<ExpressionInput model={m} />
|
||||
</div>
|
||||
<div style={{ width: 4 }} />
|
||||
{m.loading ? (
|
||||
<div style={{ padding: "0 4px" }}>
|
||||
<Spinner size={Spinner.SIZE_SMALL} />
|
||||
</div>
|
||||
) : (
|
||||
<Button
|
||||
minimal
|
||||
small
|
||||
className="part-icon"
|
||||
icon="refresh"
|
||||
onClick={() => m.refresh()}
|
||||
/>
|
||||
)}
|
||||
<Button
|
||||
minimal
|
||||
small
|
||||
className="part-icon"
|
||||
icon="log-in"
|
||||
onClick={() => m.openBrowser()}
|
||||
/>
|
||||
{/*
|
||||
TODO
|
||||
<Button
|
||||
minimal
|
||||
small
|
||||
className="part-icon"
|
||||
icon="locate"
|
||||
onClick={() => m.useSelectionAsExpression()}
|
||||
/>
|
||||
*/}
|
||||
</div>
|
||||
{this.expanded && <ExpandedOptions model={m} />}
|
||||
</div>
|
||||
<div
|
||||
className="component-GUI"
|
||||
tabIndex={0}
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
height: "100%",
|
||||
}}
|
||||
>
|
||||
<div className="part-Header">
|
||||
<VisualizerHeader model={m} />
|
||||
</div>
|
||||
<div className="part-visualizer">
|
||||
<div
|
||||
className="part-Visualizer"
|
||||
style={{ flex: 1, minHeight: 0 }}
|
||||
>
|
||||
<Visualizer model={m} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
renderValue(value: string) {
|
||||
return <div>{`${value.length}`}</div>;
|
||||
@observer
|
||||
export class VisualizerHeader extends React.Component<{ model: Model }> {
|
||||
@observable expanded = false;
|
||||
|
||||
render() {
|
||||
const m = this.props.model;
|
||||
return (
|
||||
<div
|
||||
className="component-VisualizerHeader"
|
||||
style={{ display: "flex", flexDirection: "row" }}
|
||||
>
|
||||
<div
|
||||
className={classnames(
|
||||
"part-ExpandButton",
|
||||
this.expanded && "expanded"
|
||||
)}
|
||||
onClick={this.toggleExpanded}
|
||||
/>
|
||||
<div
|
||||
className="part-HeaderContent"
|
||||
style={{
|
||||
flex: 1,
|
||||
minWidth: 0,
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
}}
|
||||
>
|
||||
<div className="part-HeaderMain">
|
||||
<VisualizerHeaderMain model={m} />
|
||||
</div>
|
||||
|
||||
{this.expanded && (
|
||||
<>
|
||||
<div style={{ height: 6 }} />
|
||||
<VisualizerHeaderDetails model={m} />
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@action.bound
|
||||
toggleExpanded() {
|
||||
this.expanded = !this.expanded;
|
||||
}
|
||||
}
|
||||
|
||||
export class ExpandButton extends React.Component<{
|
||||
expanded: boolean;
|
||||
setExpanded: (val: boolean) => void;
|
||||
}> {
|
||||
export class VisualizerHeaderMain extends React.Component<{ model: Model }> {
|
||||
render() {
|
||||
const m = this.props.model;
|
||||
return (
|
||||
<div
|
||||
onClick={() => this.props.setExpanded(!this.props.expanded)}
|
||||
className={classnames(
|
||||
"component-ExpandButton",
|
||||
this.props.expanded && "expanded"
|
||||
className="component-VisualizerHeaderMain"
|
||||
style={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className="part-ExpressionInput "
|
||||
style={{ flex: 1, minWidth: 0 }}
|
||||
>
|
||||
<ExpressionInput model={m} />
|
||||
</div>
|
||||
<div style={{ width: 4 }} />
|
||||
{m.loading ? (
|
||||
<div style={{ padding: "0 4px" }}>
|
||||
<Spinner size={Spinner.SIZE_SMALL} />
|
||||
</div>
|
||||
) : (
|
||||
<Button
|
||||
minimal
|
||||
small
|
||||
className="part-Icon"
|
||||
icon="refresh"
|
||||
onClick={() => m.refresh()}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
<Button
|
||||
minimal
|
||||
small
|
||||
className="part-Icon"
|
||||
icon="log-in"
|
||||
onClick={() => m.openBrowser()}
|
||||
/>
|
||||
{/*
|
||||
TODO
|
||||
<Button
|
||||
minimal
|
||||
small
|
||||
className="part-Icon"
|
||||
icon="locate"
|
||||
onClick={() => m.useSelectionAsExpression()}
|
||||
/>
|
||||
*/}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import { Model } from "../Model/Model";
|
||||
import { VisualizationId } from "../Visualizers/Visualizer";
|
||||
|
||||
@observer
|
||||
export class ExpandedOptions extends React.Component<{ model: Model }> {
|
||||
export class VisualizerHeaderDetails extends React.Component<{ model: Model }> {
|
||||
render() {
|
||||
const m = this.props.model;
|
||||
let availableExtractors = new Array<DataExtractorInfo>();
|
||||
@@ -38,47 +38,47 @@ export class ExpandedOptions extends React.Component<{ model: Model }> {
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div style={{ height: 6 }} />
|
||||
<div className="part-header-options">
|
||||
<NamedSelect
|
||||
name="Source"
|
||||
selected={0}
|
||||
options={[{ label: "js" }]}
|
||||
onSelected={item => {}}
|
||||
/>
|
||||
<div style={{ width: 10 }} />
|
||||
<div
|
||||
className="component-VisualizerHeaderDetails"
|
||||
style={{ display: "flex", alignItems: "center" }}
|
||||
>
|
||||
<NamedSelect
|
||||
name="Source"
|
||||
selected={0}
|
||||
options={[{ label: "js" }]}
|
||||
onSelected={item => {}}
|
||||
/>
|
||||
<div style={{ width: 10 }} />
|
||||
|
||||
<NamedSelect
|
||||
name="Extractor"
|
||||
selected={selectedExtractor}
|
||||
options={availableExtractors.map(e => ({
|
||||
label: e.name,
|
||||
id: e.id,
|
||||
}))}
|
||||
onSelected={item => {
|
||||
m.setPreferredExtractorId(item.id);
|
||||
}}
|
||||
/>
|
||||
<div style={{ width: 10 }} />
|
||||
<NamedSelect
|
||||
name="Extractor"
|
||||
selected={selectedExtractor}
|
||||
options={availableExtractors.map(e => ({
|
||||
label: e.name,
|
||||
id: e.id,
|
||||
}))}
|
||||
onSelected={item => {
|
||||
m.setPreferredExtractorId(item.id);
|
||||
}}
|
||||
/>
|
||||
<div style={{ width: 10 }} />
|
||||
|
||||
<NamedSelect
|
||||
name="Visualizer"
|
||||
selected={selectedVisualization}
|
||||
onSelected={item => {
|
||||
m.setPreferredVisualizationId(item.id);
|
||||
}}
|
||||
options={
|
||||
m.visualizations
|
||||
? m.visualizations.allVisualizations.map(v => ({
|
||||
label: v.name,
|
||||
id: v.id,
|
||||
}))
|
||||
: []
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
<NamedSelect
|
||||
name="Visualizer"
|
||||
selected={selectedVisualization}
|
||||
onSelected={item => {
|
||||
m.setPreferredVisualizationId(item.id);
|
||||
}}
|
||||
options={
|
||||
m.visualizations
|
||||
? m.visualizations.allVisualizations.map(v => ({
|
||||
label: v.name,
|
||||
id: v.id,
|
||||
}))
|
||||
: []
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -90,11 +90,18 @@ function NamedSelect<T extends SelectableItem>(props: {
|
||||
options: T[];
|
||||
}) {
|
||||
return (
|
||||
<div className="component-NamedSelect">
|
||||
<div className="part-Select">
|
||||
<div
|
||||
className="component-NamedSelect"
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<div className="part-Select" style={{ minWidth: 100 }}>
|
||||
<Select {...props} />
|
||||
</div>
|
||||
<div>{props.name}</div>
|
||||
<div className="part-Name">{props.name}</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -121,14 +128,14 @@ class Select<T extends SelectableItem> extends React.Component<{
|
||||
modifiers={{ arrow: { enabled: false } }}
|
||||
usePortal={false}
|
||||
>
|
||||
<button className="part-button">
|
||||
<button className="part-Button">
|
||||
{this.selected ? this.selected.label : "(none)"}
|
||||
</button>
|
||||
<div className={"part-content"}>
|
||||
<div className="part-Items">
|
||||
{this.props.options.map((o, idx) => (
|
||||
<div
|
||||
key={idx}
|
||||
className="part-option"
|
||||
className="part-Item"
|
||||
onClick={() => this.props.onSelected(o)}
|
||||
>
|
||||
{o.label}
|
||||
@@ -4,19 +4,27 @@ import {
|
||||
} from "@hediet/debug-visualizer-vscode-shared";
|
||||
import { WebSocketStream } from "@hediet/typed-json-rpc-websocket";
|
||||
import { ConsoleRpcLogger } from "@hediet/typed-json-rpc";
|
||||
import { observable, action, computed, when } from "mobx";
|
||||
import { observable, action, computed, when, autorun } from "mobx";
|
||||
import { DataExtractorId } from "@hediet/debug-visualizer-data-extraction";
|
||||
import { Visualization, VisualizationId } from "../Visualizers/Visualizer";
|
||||
import { knownVisualizations } from "../Visualizers";
|
||||
import { getApi as getVsCodeApi } from "./VsCodeApi";
|
||||
import { MonacoBridge } from "./MonacoBridge";
|
||||
import { Disposable } from "@hediet/std/disposable";
|
||||
import { startInterval } from "@hediet/std/timer";
|
||||
|
||||
declare const window: Window & {
|
||||
serverPort?: number;
|
||||
serverSecret?: string;
|
||||
webViewData?: { serverSecret: string; serverPort: number };
|
||||
};
|
||||
|
||||
export class Model {
|
||||
public readonly dispose = Disposable.fn();
|
||||
public readonly runningMode: "standalone" | "webView" | "webViewIFrame" =
|
||||
"webView";
|
||||
|
||||
@observable
|
||||
public theme: "dark" | "light" = "light";
|
||||
|
||||
private port: number;
|
||||
private serverSecret: string;
|
||||
|
||||
@@ -67,9 +75,25 @@ export class Model {
|
||||
private readonly _bridge = new MonacoBridge(this);
|
||||
|
||||
constructor() {
|
||||
if (window.serverPort) {
|
||||
this.port = window.serverPort;
|
||||
this.serverSecret = window.serverSecret!;
|
||||
if (window.webViewData) {
|
||||
const data = window.webViewData;
|
||||
this.port = data.serverPort;
|
||||
this.serverSecret = data.serverSecret;
|
||||
this.runningMode = "webView";
|
||||
|
||||
const updateTheme = () => {
|
||||
const isLight = document.body.classList.contains(
|
||||
"vscode-light"
|
||||
);
|
||||
this.theme = isLight ? "light" : "dark";
|
||||
};
|
||||
updateTheme();
|
||||
|
||||
this.dispose.track(
|
||||
startInterval(1000, () => {
|
||||
updateTheme();
|
||||
})
|
||||
);
|
||||
} else {
|
||||
const url = new URL(window.location.href);
|
||||
const portStr = url.searchParams.get("serverPort");
|
||||
@@ -88,6 +112,20 @@ export class Model {
|
||||
throw new Error("Server secret not set.");
|
||||
}
|
||||
this.serverSecret = secret;
|
||||
|
||||
const theme = url.searchParams.get("theme");
|
||||
if (theme && theme === "dark") {
|
||||
this.theme = "dark";
|
||||
} else {
|
||||
this.theme = "light";
|
||||
}
|
||||
|
||||
const mode = url.searchParams.get("mode");
|
||||
if (mode) {
|
||||
this.runningMode = mode as any;
|
||||
} else {
|
||||
this.runningMode = "standalone";
|
||||
}
|
||||
}
|
||||
|
||||
this.stayConnected();
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import * as monaco from "monaco-editor";
|
||||
import { Model } from "./Model";
|
||||
import { Disposable } from "@hediet/std/disposable";
|
||||
import { autorun } from "mobx";
|
||||
export class MonacoBridge {
|
||||
public readonly dispose = Disposable.fn();
|
||||
|
||||
@@ -41,6 +42,14 @@ export class MonacoBridge {
|
||||
new DebugSessionCompletionProvider(this.model)
|
||||
)
|
||||
);
|
||||
|
||||
this.dispose.track({
|
||||
dispose: autorun(() => {
|
||||
monaco.editor.setTheme(
|
||||
model.theme === "light" ? "vs-light" : "vs-dark"
|
||||
);
|
||||
}),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,10 +91,12 @@ class DebugSessionCompletionProvider
|
||||
if (!this.model.server) {
|
||||
return { suggestions: [] };
|
||||
}
|
||||
const completions = (await this.model.server.getCompletions({
|
||||
text: expression,
|
||||
column: position.column,
|
||||
})).completions;
|
||||
const completions = (
|
||||
await this.model.server.getCompletions({
|
||||
text: expression,
|
||||
column: position.column,
|
||||
})
|
||||
).completions;
|
||||
|
||||
const p = model.getWordAtPosition(position);
|
||||
|
||||
|
||||
@@ -126,3 +126,16 @@
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.decorator-collapse-icon {
|
||||
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath fill='%23646465' d='M6 4v8l4-4-4-4zm1 2.414L8.586 8 7 9.586V6.414z'/%3E%3C/svg%3E");
|
||||
|
||||
background-position: 50%;
|
||||
background-position-x: 50%;
|
||||
background-position-y: center;
|
||||
background-repeat: no-repeat;
|
||||
|
||||
&.expanded {
|
||||
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath fill='%23646465' d='M11 10.07H5.344L11 4.414v5.656z'/%3E%3C/svg%3E");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,14 @@ import Components = require("./Components/GUI");
|
||||
|
||||
const model = new Model();
|
||||
|
||||
if (model.runningMode !== "webView") {
|
||||
if (model.theme === "light") {
|
||||
require("./vscode-light.scss");
|
||||
} else {
|
||||
require("./vscode-dark.scss");
|
||||
}
|
||||
}
|
||||
|
||||
function render(target: HTMLDivElement) {
|
||||
const c = require("./Components/GUI") as typeof Components;
|
||||
ReactDOM.render(<c.GUI model={model} />, target);
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
@import "./vscode-light.scss";
|
||||
|
||||
@import "~normalize.css";
|
||||
@import "~@blueprintjs/core/lib/css/blueprint.css";
|
||||
@import "~@blueprintjs/icons/lib/css/blueprint-icons.css";
|
||||
|
||||
html,
|
||||
body,
|
||||
.target {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
|
||||
margin: 0px;
|
||||
@@ -12,6 +16,8 @@ body {
|
||||
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
background-color: var(--vscode-editor-background);
|
||||
}
|
||||
|
||||
.bp3-input,
|
||||
@@ -26,10 +32,95 @@ body {
|
||||
}
|
||||
}
|
||||
|
||||
html,
|
||||
body,
|
||||
.target {
|
||||
height: 100%;
|
||||
.component-GUI {
|
||||
& > .part-Header {
|
||||
padding: 6px 20px 6px 0;
|
||||
background-color: var(--vscode-sideBar-background);
|
||||
|
||||
// border-top: solid 1px var(--vscode-button-background);
|
||||
// rgba(128, 128, 128, 0.15)
|
||||
}
|
||||
}
|
||||
|
||||
.component-VisualizerHeader {
|
||||
.part-ExpandButton {
|
||||
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath fill='%23646465' d='M6 4v8l4-4-4-4zm1 2.414L8.586 8 7 9.586V6.414z'/%3E%3C/svg%3E");
|
||||
|
||||
background-position: 50%;
|
||||
background-position-x: 50%;
|
||||
background-position-y: center;
|
||||
background-repeat: no-repeat;
|
||||
|
||||
width: 15px;
|
||||
margin: -6px 6px -6px 0px;
|
||||
|
||||
&.expanded {
|
||||
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath fill='%23646465' d='M11 10.07H5.344L11 4.414v5.656z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: var(--vscode-titleBar-activeBackground);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.component-VisualizerHeaderMain {
|
||||
.part-Icon {
|
||||
margin-left: 4px;
|
||||
svg {
|
||||
fill: var(--color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.component-NamedSelect {
|
||||
.part-Name {
|
||||
color: var(--color);
|
||||
}
|
||||
}
|
||||
|
||||
.component-Select {
|
||||
.part-Button {
|
||||
background-color: var(--vscode-button-background);
|
||||
color: var(--vscode-button-foreground);
|
||||
padding: 4px 10px;
|
||||
|
||||
width: 100%;
|
||||
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
&:hover,
|
||||
&:focus {
|
||||
background-color: var(--vscode-button-hoverBackground);
|
||||
}
|
||||
}
|
||||
|
||||
.part-Items {
|
||||
background-color: var(--vscode-sideBar-background);
|
||||
|
||||
.part-Item {
|
||||
//color: black;
|
||||
color: var(--color);
|
||||
padding: 12px 16px;
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background-color: var(
|
||||
--vscode-titleBar-activeBackground
|
||||
); // #ddd;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bp3-popover-wrapper {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.bp3-popover-target {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.component-Visualizer {
|
||||
@@ -49,7 +140,7 @@ body,
|
||||
height: 100%;
|
||||
|
||||
rect {
|
||||
fill: white;
|
||||
fill: var(--vscode-editor-background);
|
||||
}
|
||||
|
||||
line {
|
||||
@@ -57,76 +148,19 @@ body,
|
||||
}
|
||||
|
||||
text {
|
||||
stroke: black;
|
||||
fill: var(--vscode-editor-foreground);
|
||||
stroke-width: 0px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.component-GUI {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
|
||||
& > .part-header {
|
||||
padding: 6px 20px 6px 0;
|
||||
background-color: var(--vscode-sideBar-background);
|
||||
|
||||
//border: solid 8px white;
|
||||
//border-top: solid 1px var(--vscode-button-background);
|
||||
// rgba(128, 128, 128, 0.15)
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
.part-header-content {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
|
||||
transition: flex 0.3s ease-out;
|
||||
|
||||
.part-header-main,
|
||||
.part-header-options {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.part-expression-input {
|
||||
min-width: 0;
|
||||
//color: rgb(155, 70, 176);
|
||||
//font-family: var(--vscode-editor-font-family);
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.part-header-main {
|
||||
.part-icon {
|
||||
margin-left: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.part-header-options {
|
||||
.part-select {
|
||||
min-width: 90px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.part-visualizer {
|
||||
//padding: 10px 20px;
|
||||
flex: 1;
|
||||
min-height: 0px;
|
||||
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.component-monaco-editor {
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
padding: 2px;
|
||||
background-color: white;
|
||||
border: 0.5px solid gray;
|
||||
|
||||
.part-editor {
|
||||
min-width: 0;
|
||||
@@ -142,90 +176,6 @@ body,
|
||||
}
|
||||
}
|
||||
|
||||
.decorator-collapse-icon {
|
||||
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath fill='%23646465' d='M6 4v8l4-4-4-4zm1 2.414L8.586 8 7 9.586V6.414z'/%3E%3C/svg%3E");
|
||||
|
||||
background-position: 50%;
|
||||
background-position-x: 50%;
|
||||
background-position-y: center;
|
||||
background-repeat: no-repeat;
|
||||
|
||||
&.expanded {
|
||||
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath fill='%23646465' d='M11 10.07H5.344L11 4.414v5.656z'/%3E%3C/svg%3E");
|
||||
}
|
||||
}
|
||||
|
||||
.component-ExpandButton {
|
||||
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath fill='%23646465' d='M6 4v8l4-4-4-4zm1 2.414L8.586 8 7 9.586V6.414z'/%3E%3C/svg%3E");
|
||||
|
||||
background-position: 50%;
|
||||
background-position-x: 50%;
|
||||
background-position-y: center;
|
||||
background-repeat: no-repeat;
|
||||
|
||||
width: 15px;
|
||||
margin: -6px 6px -6px 0px;
|
||||
|
||||
&.expanded {
|
||||
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath fill='%23646465' d='M11 10.07H5.344L11 4.414v5.656z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: var(--vscode-titleBar-activeBackground);
|
||||
}
|
||||
}
|
||||
|
||||
.component-NamedSelect {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
.part-Select {
|
||||
min-width: 100px;
|
||||
}
|
||||
}
|
||||
|
||||
.component-Select {
|
||||
.part-button {
|
||||
background-color: var(--vscode-button-background);
|
||||
color: white;
|
||||
padding: 4px 10px;
|
||||
|
||||
width: 100%;
|
||||
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
&:hover,
|
||||
&:focus {
|
||||
background-color: var(--vscode-button-hoverBackground);
|
||||
}
|
||||
}
|
||||
|
||||
.part-content {
|
||||
background-color: var(--vscode-sideBar-background);
|
||||
|
||||
.part-option {
|
||||
color: black;
|
||||
padding: 12px 16px;
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background-color: #ddd;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bp3-popover-wrapper {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.bp3-popover-target {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.svgViewer {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
Reference in New Issue
Block a user