Some refactorings
This commit is contained in:
149
extension/ui/src/Components/GraphViz.tsx
Normal file
149
extension/ui/src/Components/GraphViz.tsx
Normal file
@@ -0,0 +1,149 @@
|
||||
import { observer, disposeOnUnmount } from "mobx-react";
|
||||
import * as classNames from "classnames";
|
||||
import * as React from "react";
|
||||
import * as ReactDOM from "react-dom";
|
||||
import { ReactSVGPanZoom, Tool, Value } from "react-svg-pan-zoom";
|
||||
import { computed, observable, autorun, runInAction, action } from "mobx";
|
||||
import Measure, { ContentRect } from "react-measure";
|
||||
import Viz from "viz.js";
|
||||
import { Module, render } from "viz.js/full.render.js";
|
||||
|
||||
export interface GraphData {
|
||||
kind: "GraphData";
|
||||
nodes: { id: string; label: string }[];
|
||||
edges: { from: string; to: string; label: string }[];
|
||||
}
|
||||
|
||||
@observer
|
||||
export class DotGraphViewer extends React.Component<{ data: GraphData }> {
|
||||
render() {
|
||||
const { nodes, edges } = this.props.data;
|
||||
const dotContent = `
|
||||
digraph MyGraph {
|
||||
${nodes
|
||||
.map(n => `${n.id} [ label = ${JSON.stringify(n.label)} ];`)
|
||||
.join("\n ")}
|
||||
${edges
|
||||
.map(
|
||||
e =>
|
||||
`${e.from} -> ${e.to} [ label = ${JSON.stringify(
|
||||
e.label
|
||||
)} ];`
|
||||
)
|
||||
.join("\n")}
|
||||
}
|
||||
`;
|
||||
return <DotViewer dotCode={dotContent} />;
|
||||
}
|
||||
}
|
||||
|
||||
const viz: any = new Viz({
|
||||
Module: () => Module({ TOTAL_MEMORY: 1 << 30 }),
|
||||
render,
|
||||
});
|
||||
|
||||
@observer
|
||||
export class DotViewer extends React.Component<{
|
||||
dotCode: string;
|
||||
svgRef?: (element: SVGSVGElement | null) => void;
|
||||
}> {
|
||||
@observable private svg: string | null = null;
|
||||
|
||||
@disposeOnUnmount
|
||||
// @ts-ignore
|
||||
private readonly _updateSvgAutorun = autorun(async () => {
|
||||
const svg = await viz.renderString(this.props.dotCode);
|
||||
runInAction("Update svg", () => (this.svg = svg));
|
||||
});
|
||||
|
||||
render() {
|
||||
if (!this.svg) {
|
||||
return <div>Loading...</div>;
|
||||
}
|
||||
return <SvgViewer svgRef={this.props.svgRef} svgContent={this.svg} />;
|
||||
}
|
||||
}
|
||||
|
||||
function widthOrDefault(r: ContentRect): number {
|
||||
if (r.bounds && r.bounds.width) {
|
||||
return r.bounds.width;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
function heightOrDefault(r: ContentRect): number {
|
||||
console.log(r);
|
||||
if (r.bounds && r.bounds.height) {
|
||||
return r.bounds.height;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@observer
|
||||
export class SvgViewer extends React.Component<{
|
||||
svgContent: string;
|
||||
svgRef?: (element: SVGSVGElement | null) => void;
|
||||
}> {
|
||||
@observable tool: Tool = "pan";
|
||||
|
||||
@action.bound
|
||||
private setTool(tool: Tool): void {
|
||||
this.tool = tool;
|
||||
}
|
||||
|
||||
private setRef(element: ReactSVGPanZoom | null) {
|
||||
if (this.props.svgRef) {
|
||||
if (!element) {
|
||||
this.props.svgRef(null);
|
||||
return;
|
||||
}
|
||||
|
||||
const svg = (element as any).ViewerDOM as SVGSVGElement;
|
||||
this.props.svgRef(svg);
|
||||
}
|
||||
}
|
||||
|
||||
@observable value: Value | {} = {};
|
||||
|
||||
render() {
|
||||
let { svgContent } = this.props;
|
||||
let width: number = 0;
|
||||
let height: number = 0;
|
||||
svgContent = svgContent.replace(
|
||||
/viewBox="[0-9\.]+ [0-9\.]+ ([0-9\.]+) ([0-9\.]+)"/,
|
||||
(r, w, h) => {
|
||||
width = parseFloat(w);
|
||||
height = parseFloat(h);
|
||||
return "";
|
||||
}
|
||||
);
|
||||
const tool = this.tool;
|
||||
const val = this.value;
|
||||
|
||||
return (
|
||||
<Measure bounds>
|
||||
{({ measureRef, contentRect }) => (
|
||||
<div ref={measureRef} className="svgViewer">
|
||||
<ReactSVGPanZoom
|
||||
width={widthOrDefault(contentRect)}
|
||||
height={heightOrDefault(contentRect)}
|
||||
tool={tool}
|
||||
value={val}
|
||||
onChangeValue={v => (this.value = v)}
|
||||
onChangeTool={this.setTool}
|
||||
ref={e => this.setRef(e)}
|
||||
>
|
||||
<svg width={width} height={height}>
|
||||
<g
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: svgContent,
|
||||
}}
|
||||
/>
|
||||
</svg>
|
||||
</ReactSVGPanZoom>
|
||||
</div>
|
||||
)}
|
||||
</Measure>
|
||||
);
|
||||
}
|
||||
}
|
||||
256
extension/ui/src/Components/Point.ts
Normal file
256
extension/ui/src/Components/Point.ts
Normal file
@@ -0,0 +1,256 @@
|
||||
function sqr(a: number) {
|
||||
return a * a;
|
||||
}
|
||||
|
||||
export type PointLike =
|
||||
| Point
|
||||
| { x?: number; y: number }
|
||||
| { x: number; y?: number };
|
||||
|
||||
export function point(data: PointLike) {
|
||||
if (data instanceof Point) {
|
||||
return data;
|
||||
}
|
||||
return new Point(data.x || 0, data.y || 0);
|
||||
}
|
||||
|
||||
export class Point {
|
||||
public static readonly Zero = new Point(0, 0);
|
||||
|
||||
constructor(public readonly x: number, public readonly y: number) {}
|
||||
|
||||
public mapXY(fn: (arg: number) => number): Point {
|
||||
return new Point(fn(this.x), fn(this.y));
|
||||
}
|
||||
|
||||
public distance(other: PointLike = Point.Zero): number {
|
||||
const d = this.sub(other);
|
||||
return Math.sqrt(sqr(d.x) + sqr(d.y));
|
||||
}
|
||||
|
||||
public sub(other: PointLike): Point {
|
||||
const o = point(other);
|
||||
return new Point(this.x - o.x, this.y - o.y);
|
||||
}
|
||||
|
||||
public add(other: PointLike): Point {
|
||||
const o = point(other);
|
||||
return new Point(this.x + o.x, this.y + o.y);
|
||||
}
|
||||
|
||||
public mul(scalar: number): Point {
|
||||
return new Point(this.x * scalar, this.y * scalar);
|
||||
}
|
||||
|
||||
public div(scalar: number): Point {
|
||||
return new Point(this.x / scalar, this.y / scalar);
|
||||
}
|
||||
|
||||
public equals(other: PointLike) {
|
||||
const o = point(other);
|
||||
return this.x === o.x && this.y === o.y;
|
||||
}
|
||||
|
||||
public angle(): number {
|
||||
const angle = Math.atan2(this.x, this.y);
|
||||
return angle;
|
||||
}
|
||||
|
||||
public getPointCloserTo(dest: PointLike, dist: number): Point {
|
||||
if (this.equals(dest)) return this;
|
||||
|
||||
const angle = point(dest)
|
||||
.sub(this)
|
||||
.angle();
|
||||
|
||||
const result = new Point(
|
||||
this.x + Math.sin(angle) * dist,
|
||||
this.y + Math.cos(angle) * dist
|
||||
);
|
||||
return result;
|
||||
}
|
||||
|
||||
public toJson(): { x: number; y: number } {
|
||||
return { x: this.x, y: this.y };
|
||||
}
|
||||
}
|
||||
|
||||
function turn(p1: Point, p2: Point, p3: Point): number {
|
||||
const A = (p3.y - p1.y) * (p2.x - p1.x);
|
||||
const B = (p2.y - p1.y) * (p3.x - p1.x);
|
||||
return A > B + Number.MIN_VALUE ? 1 : A + Number.MIN_VALUE < B ? -1 : 0;
|
||||
}
|
||||
|
||||
export function isIntersect(
|
||||
aStart: Point,
|
||||
aEnd: Point,
|
||||
bStart: Point,
|
||||
bEnd: Point
|
||||
): boolean {
|
||||
return (
|
||||
turn(aStart, bStart, bEnd) != turn(aEnd, bStart, bEnd) &&
|
||||
turn(aStart, aEnd, bStart) != turn(aStart, aEnd, bEnd)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liang-Barsky function by Daniel White
|
||||
*
|
||||
* @link http://www.skytopia.com/project/articles/compsci/clipping.html
|
||||
*
|
||||
* @param {number} x0
|
||||
* @param {number} y0
|
||||
* @param {number} x1
|
||||
* @param {number} y1
|
||||
* @param {array<number>} bbox
|
||||
* @return {array<array<number>>|null}
|
||||
*/
|
||||
function liangBarsky(
|
||||
x0: number,
|
||||
y0: number,
|
||||
x1: number,
|
||||
y1: number,
|
||||
bbox: [number, number, number, number]
|
||||
): [[number, number], [number, number]] | null {
|
||||
let [xmin, xmax, ymin, ymax] = bbox;
|
||||
let t0 = 0,
|
||||
t1 = 1;
|
||||
let dx = x1 - x0,
|
||||
dy = y1 - y0;
|
||||
let p = 0,
|
||||
q = 0,
|
||||
r = 0;
|
||||
|
||||
for (let edge: 0 | 1 | 2 | 3 = 0; edge < 4; edge++) {
|
||||
// Traverse through left, right, bottom, top edges.
|
||||
if (edge === 0) {
|
||||
p = -dx;
|
||||
q = -(xmin - x0);
|
||||
} else if (edge === 1) {
|
||||
p = dx;
|
||||
q = xmax - x0;
|
||||
} else if (edge === 2) {
|
||||
p = -dy;
|
||||
q = -(ymin - y0);
|
||||
} else if (edge === 3) {
|
||||
p = dy;
|
||||
q = ymax - y0;
|
||||
}
|
||||
|
||||
r = q / p;
|
||||
|
||||
if (p === 0 && q < 0) return null; // Don't draw line at all. (parallel line outside)
|
||||
|
||||
if (p < 0) {
|
||||
if (r > t1) return null;
|
||||
// Don't draw line at all.
|
||||
else if (r > t0) t0 = r; // Line is clipped!
|
||||
} else if (p > 0) {
|
||||
if (r < t0) return null;
|
||||
// Don't draw line at all.
|
||||
else if (r < t1) t1 = r; // Line is clipped!
|
||||
}
|
||||
}
|
||||
|
||||
return [[x0 + t0 * dx, y0 + t0 * dy], [x0 + t1 * dx, y0 + t1 * dy]];
|
||||
}
|
||||
|
||||
export function intersectRectWithLine(
|
||||
start: Point,
|
||||
end: Point,
|
||||
rect: Rectangle
|
||||
): { first: Point; second: Point } | undefined {
|
||||
const r = liangBarsky(start.x, start.y, end.x, end.y, [
|
||||
rect.topLeft.x,
|
||||
rect.bottomRight.x,
|
||||
rect.topLeft.y,
|
||||
rect.bottomRight.y,
|
||||
]);
|
||||
if (!r) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return {
|
||||
first: new Point(r[0][0], r[0][1]),
|
||||
second: new Point(r[1][0], r[1][1]),
|
||||
};
|
||||
}
|
||||
|
||||
// first zoom then translate
|
||||
export function scale(
|
||||
clientOffset: Point,
|
||||
clientSize: Point,
|
||||
viewSize: Point
|
||||
): { clientZoom: number; clientOffset: Point } {
|
||||
const clientRatio = clientSize.x / clientSize.y;
|
||||
const viewRatio = viewSize.x / viewSize.y;
|
||||
|
||||
let zoom = 1;
|
||||
|
||||
if (clientRatio < viewRatio) zoom = viewSize.y / clientSize.y;
|
||||
else zoom = viewSize.x / clientSize.x;
|
||||
|
||||
const clientMid = clientOffset.mul(zoom).add(clientSize.mul(zoom / 2));
|
||||
const viewMid = viewSize.div(2);
|
||||
|
||||
const clientOffset2 = viewMid.sub(clientMid);
|
||||
|
||||
return { clientOffset: clientOffset2, clientZoom: zoom };
|
||||
}
|
||||
|
||||
export class Rectangle {
|
||||
public static ofSize(position: PointLike, size: PointLike): Rectangle {
|
||||
const pos = point(position);
|
||||
return new Rectangle(pos, pos.add(size));
|
||||
}
|
||||
|
||||
public static spanning(first: Point, ...rest: Point[]): Rectangle {
|
||||
let min = first.toJson();
|
||||
let max = first.toJson();
|
||||
for (const p of rest) {
|
||||
min.x = Math.min(min.x, p.x);
|
||||
min.y = Math.min(min.y, p.y);
|
||||
max.x = Math.max(max.x, p.x);
|
||||
max.y = Math.max(max.y, p.y);
|
||||
}
|
||||
|
||||
return new Rectangle(point(min), point(max));
|
||||
}
|
||||
|
||||
constructor(
|
||||
public readonly topLeft: Point,
|
||||
public readonly bottomRight: Point
|
||||
) {}
|
||||
|
||||
get center(): Point {
|
||||
return this.bottomRight.add(this.topLeft).div(2);
|
||||
}
|
||||
|
||||
get size(): Point {
|
||||
return this.bottomRight.sub(this.topLeft);
|
||||
}
|
||||
|
||||
get topRight(): Point {
|
||||
return new Point(this.bottomRight.x, this.topLeft.y);
|
||||
}
|
||||
|
||||
get bottomLeft(): Point {
|
||||
return new Point(this.topLeft.x, this.bottomRight.y);
|
||||
}
|
||||
|
||||
public intersects(selectionRect: Rectangle): boolean {
|
||||
return !(
|
||||
selectionRect.topLeft.x > this.bottomRight.x ||
|
||||
selectionRect.bottomRight.x < this.topLeft.x ||
|
||||
selectionRect.topLeft.y > this.bottomRight.y ||
|
||||
selectionRect.bottomRight.y < this.topLeft.y
|
||||
);
|
||||
}
|
||||
|
||||
equals(other: Rectangle) {
|
||||
return (
|
||||
this.topLeft.equals(other.topLeft) &&
|
||||
this.bottomRight.equals(other.bottomRight)
|
||||
);
|
||||
}
|
||||
}
|
||||
102
extension/ui/src/Components/SvgElements.tsx
Normal file
102
extension/ui/src/Components/SvgElements.tsx
Normal file
@@ -0,0 +1,102 @@
|
||||
import { Point, Rectangle } from "./Point";
|
||||
import * as React from "react";
|
||||
import { Properties } from "csstype";
|
||||
|
||||
type Omit<T, K> = Pick<T, Exclude<keyof T, K>>;
|
||||
|
||||
export function omit<T, K extends keyof T>(obj: T, keys: K[]): Omit<T, K> {
|
||||
const newObj: Omit<T, K> = {} as any;
|
||||
for (const [key, val] of Object.entries(obj)) {
|
||||
if (!keys.includes(key as K)) {
|
||||
(newObj as any)[key] = val;
|
||||
}
|
||||
}
|
||||
return newObj;
|
||||
}
|
||||
|
||||
export interface SvgAttributes<T> extends React.DOMAttributes<T> {
|
||||
stroke?: string;
|
||||
className?: string;
|
||||
style?: Properties;
|
||||
pointerEvents?: "none" | "auto" | "initial";
|
||||
}
|
||||
|
||||
export function SvgText(
|
||||
props: {
|
||||
position: Point;
|
||||
children: any;
|
||||
childRef?: React.Ref<SVGTextElement>;
|
||||
textAnchor?: "middle" | "end" | "start";
|
||||
dominantBaseline?: "central" | "middle";
|
||||
} & SvgAttributes<SVGTextElement>
|
||||
) {
|
||||
return (
|
||||
<text
|
||||
x={props.position.x}
|
||||
y={props.position.y}
|
||||
ref={props.childRef}
|
||||
{...omit(props, ["position", "childRef"])}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export function SvgCircle(
|
||||
props: {
|
||||
center: Point;
|
||||
radius: number;
|
||||
childRef?: React.Ref<SVGCircleElement>;
|
||||
} & SvgAttributes<SVGCircleElement>
|
||||
) {
|
||||
return (
|
||||
<circle
|
||||
cx={props.center.x}
|
||||
cy={props.center.y}
|
||||
r={props.radius}
|
||||
ref={props.childRef}
|
||||
{...omit(props, ["center", "radius", "childRef"])}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export function SvgLine(
|
||||
props: { start: Point; end: Point } & SvgAttributes<SVGLineElement>
|
||||
) {
|
||||
return (
|
||||
<line
|
||||
x1={props.start.x}
|
||||
y1={props.start.y}
|
||||
x2={props.end.x}
|
||||
y2={props.end.y}
|
||||
{...omit(props, ["end", "start"])}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export function SvgRect(
|
||||
props: { rectangle: Rectangle; fill?: string } & SvgAttributes<
|
||||
SVGRectElement
|
||||
>
|
||||
) {
|
||||
const r = props.rectangle;
|
||||
return (
|
||||
<rect
|
||||
x={r.topLeft.x}
|
||||
y={r.topLeft.y}
|
||||
width={r.size.x}
|
||||
height={r.size.y}
|
||||
{...omit(props, ["rectangle"])}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
export function Svg(props: { position: Point } & SvgAttributes<SVGSVGElement>) {
|
||||
return (
|
||||
<svg
|
||||
x={props.position.x}
|
||||
y={props.position.y}
|
||||
{...omit(props, ["position"])}
|
||||
/>
|
||||
);
|
||||
}
|
||||
*/
|
||||
296
extension/ui/src/Components/index.tsx
Normal file
296
extension/ui/src/Components/index.tsx
Normal file
@@ -0,0 +1,296 @@
|
||||
import React = require("react");
|
||||
import { Model } from "../Model";
|
||||
import { observer } from "mobx-react";
|
||||
import { observable, action, computed } from "mobx";
|
||||
import { Popover, Icon, Button } from "@blueprintjs/core";
|
||||
import classnames = require("classnames");
|
||||
import Measure from "react-measure";
|
||||
import { DotGraphViewer } from "./GraphViz";
|
||||
import { TreeView } from "../Visualizers/TreeVisualizer/Views";
|
||||
import { createTreeViewModelFromTreeNodeData } from "../Visualizers/TreeVisualizer/Visualizers";
|
||||
import { CommonDataTypes } from "@hediet/debug-visualizer-data-extraction";
|
||||
@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">
|
||||
<ExpressionInput model={m} />
|
||||
<Button
|
||||
minimal
|
||||
small
|
||||
className="part-icon"
|
||||
icon="refresh"
|
||||
onClick={() => m.refresh()}
|
||||
/>
|
||||
<Button
|
||||
minimal
|
||||
small
|
||||
className="part-icon"
|
||||
icon="log-in"
|
||||
onClick={() => m.openBrowser()}
|
||||
/>
|
||||
<Button
|
||||
minimal
|
||||
small
|
||||
className="part-icon"
|
||||
icon="locate"
|
||||
onClick={() => m.useSelectionAsExpression()}
|
||||
/>
|
||||
</div>
|
||||
{this.expanded && (
|
||||
<>
|
||||
<div style={{ height: 6 }} />
|
||||
<div className="part-header-options">
|
||||
<NamedSelect
|
||||
name="Source"
|
||||
selected={0}
|
||||
options={[{ label: "js" }]}
|
||||
/>
|
||||
<div style={{ width: 10 }} />
|
||||
|
||||
<NamedSelect
|
||||
name="Extractor"
|
||||
selected={0}
|
||||
options={[{ label: "literal" }]}
|
||||
/>
|
||||
<div style={{ width: 10 }} />
|
||||
|
||||
<NamedSelect
|
||||
name="Visualizer"
|
||||
selected={0}
|
||||
options={[{ label: "literal" }]}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="part-visualizer">
|
||||
<Visualizer model={m} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderValue(value: string) {
|
||||
return <div>{`${value.length}`}</div>;
|
||||
}
|
||||
}
|
||||
|
||||
@observer
|
||||
export class ExpressionInput extends React.Component<{ model: Model }> {
|
||||
@observable editedExpression: string | undefined;
|
||||
@computed get currentExpression(): string {
|
||||
return this.editedExpression !== undefined
|
||||
? this.editedExpression
|
||||
: this.props.model.expression;
|
||||
}
|
||||
|
||||
@action.bound
|
||||
updateCurrentExpression(newValue: string) {
|
||||
this.editedExpression = newValue;
|
||||
}
|
||||
|
||||
@action.bound
|
||||
submit() {
|
||||
if (!this.editedExpression) {
|
||||
return;
|
||||
}
|
||||
this.props.model.setExpression(this.editedExpression);
|
||||
this.editedExpression = undefined;
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<input
|
||||
className="part-expression-input"
|
||||
value={this.currentExpression}
|
||||
onChange={e => this.updateCurrentExpression(e.target.value)}
|
||||
onBlur={this.submit}
|
||||
onKeyPress={e => {
|
||||
if (e.charCode === 13) {
|
||||
// enter
|
||||
this.submit();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@observer
|
||||
export class Visualizer extends React.Component<{ model: Model }> {
|
||||
render() {
|
||||
return (
|
||||
<div className="component-Visualizer">{this.renderContent()}</div>
|
||||
);
|
||||
/*
|
||||
|
||||
|
||||
<DotGraphViewer
|
||||
data={{
|
||||
kind: "GraphData",
|
||||
edges: [
|
||||
{
|
||||
from: "1",
|
||||
to: "2",
|
||||
label: "test",
|
||||
},
|
||||
],
|
||||
nodes: [
|
||||
{ id: "1", label: "foo" },
|
||||
{ id: "2", label: "bar" },
|
||||
],
|
||||
}}
|
||||
/>
|
||||
*/
|
||||
}
|
||||
|
||||
renderContent(): JSX.Element {
|
||||
const s = this.props.model.state;
|
||||
if (s.kind === "loading") {
|
||||
return <NoData label="Loading" />;
|
||||
} else if (s.kind === "error") {
|
||||
return <NoData label={"Error: " + s.message} />;
|
||||
} else if (s.kind === "noExpression") {
|
||||
return <NoData label="No Expression" />;
|
||||
} else if (s.kind === "noDebugSession") {
|
||||
return <NoData label="No Debug Session" />;
|
||||
} else if (s.kind === "data") {
|
||||
const data = s.result.data;
|
||||
|
||||
if (data.kind.tree) {
|
||||
const d = data as CommonDataTypes.TreeNodeData;
|
||||
const m = createTreeViewModelFromTreeNodeData(d.root);
|
||||
return <TreeView model={m} />;
|
||||
} else {
|
||||
return <pre>{JSON.stringify(s.result)}</pre>;
|
||||
}
|
||||
} else {
|
||||
const nvr: never = s;
|
||||
return <div />;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@observer
|
||||
class NoData extends React.Component<{ label: string }> {
|
||||
@observable height = 0;
|
||||
@observable width = 0;
|
||||
|
||||
render() {
|
||||
const { width, height } = this;
|
||||
return (
|
||||
<Measure
|
||||
client={true}
|
||||
onResize={e => {
|
||||
if (e.client) {
|
||||
this.height = e.client.height;
|
||||
this.width = e.client.width;
|
||||
}
|
||||
}}
|
||||
>
|
||||
{({ measureRef }) => (
|
||||
<div className="component-NoData" ref={measureRef}>
|
||||
<svg>
|
||||
<line x1={0} y1={0} x2={width} y2={height} />
|
||||
<line x1={width} y1={0} x2={0} y2={height} />
|
||||
<rect
|
||||
x={width / 2 - 50}
|
||||
y={height / 2 - 20}
|
||||
width={100}
|
||||
height={40}
|
||||
/>
|
||||
<text
|
||||
x={width / 2}
|
||||
y={height / 2}
|
||||
textAnchor="middle"
|
||||
alignmentBaseline="central"
|
||||
children={this.props.label}
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
)}
|
||||
</Measure>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export class ExpandButton extends React.Component<{
|
||||
expanded: boolean;
|
||||
setExpanded: (val: boolean) => void;
|
||||
}> {
|
||||
render() {
|
||||
return (
|
||||
<div
|
||||
onClick={() => this.props.setExpanded(!this.props.expanded)}
|
||||
className={classnames(
|
||||
"component-ExpandButton",
|
||||
this.props.expanded && "expanded"
|
||||
)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function NamedSelect(props: {
|
||||
name: string;
|
||||
selected: number;
|
||||
options: SelectableItem[];
|
||||
}) {
|
||||
return (
|
||||
<div className="component-NamedSelect">
|
||||
<div className="part-Select">
|
||||
<Select {...props} />
|
||||
</div>
|
||||
<div>{props.name}</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
interface SelectableItem {
|
||||
label: string;
|
||||
}
|
||||
|
||||
@observer
|
||||
export class Select extends React.Component<{
|
||||
selected: number;
|
||||
options: SelectableItem[];
|
||||
}> {
|
||||
@computed get selected(): SelectableItem {
|
||||
return this.props.options[this.props.selected];
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="component-Select">
|
||||
<Popover
|
||||
position="auto-start"
|
||||
modifiers={{ arrow: { enabled: false } }}
|
||||
usePortal={false}
|
||||
>
|
||||
<button className="part-button">
|
||||
{this.selected.label}
|
||||
</button>
|
||||
<div className={"part-content"}>
|
||||
{this.props.options.map((o, idx) => (
|
||||
<div key={idx}>{o.label}</div>
|
||||
))}
|
||||
</div>
|
||||
</Popover>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
88
extension/ui/src/Model.ts
Normal file
88
extension/ui/src/Model.ts
Normal file
@@ -0,0 +1,88 @@
|
||||
import {
|
||||
debugVisualizerUIContract,
|
||||
DataExtractionState,
|
||||
} from "@hediet/debug-visualizer-vscode-shared";
|
||||
import { WebSocketStream } from "@hediet/typed-json-rpc-websocket";
|
||||
import { ConsoleRpcLogger } from "@hediet/typed-json-rpc";
|
||||
import { observable, action } from "mobx";
|
||||
|
||||
declare const window: Window & {
|
||||
serverPort?: number;
|
||||
};
|
||||
|
||||
export class Model {
|
||||
port: number;
|
||||
|
||||
@observable expression: string = "";
|
||||
@observable state: DataExtractionState | { kind: "noExpression" } = {
|
||||
kind: "noExpression",
|
||||
};
|
||||
|
||||
private server:
|
||||
| typeof debugVisualizerUIContract.TServerInterface
|
||||
| undefined = undefined;
|
||||
|
||||
constructor() {
|
||||
if (window.serverPort) {
|
||||
this.port = window.serverPort;
|
||||
} else {
|
||||
const url = new URL(window.location.href);
|
||||
const portStr = url.searchParams.get("serverPort");
|
||||
if (!portStr) {
|
||||
throw new Error("No port given.");
|
||||
}
|
||||
this.port = parseInt(portStr);
|
||||
}
|
||||
|
||||
this.stayConnected();
|
||||
}
|
||||
|
||||
@action
|
||||
setExpression(newExpression: string) {
|
||||
this.expression = newExpression;
|
||||
if (this.server) {
|
||||
this.server.setExpression({ newExpression });
|
||||
}
|
||||
}
|
||||
|
||||
refresh() {
|
||||
if (this.server) {
|
||||
this.server.refresh();
|
||||
}
|
||||
}
|
||||
|
||||
async stayConnected(): Promise<void> {
|
||||
while (true) {
|
||||
try {
|
||||
const stream = await WebSocketStream.connectTo({
|
||||
host: "localhost",
|
||||
port: this.port,
|
||||
});
|
||||
const {
|
||||
server,
|
||||
} = debugVisualizerUIContract.getServerFromStream(
|
||||
stream,
|
||||
new ConsoleRpcLogger(),
|
||||
{
|
||||
updateState: ({ newState }) => {
|
||||
this.state = newState;
|
||||
},
|
||||
}
|
||||
);
|
||||
this.server = server;
|
||||
|
||||
await stream.onClosed;
|
||||
} catch (e) {}
|
||||
}
|
||||
}
|
||||
|
||||
openBrowser() {
|
||||
if (this.server) {
|
||||
this.server.openInBrowser();
|
||||
}
|
||||
}
|
||||
|
||||
useSelectionAsExpression() {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
import { TreeViewModel, TreeNodeViewModel, TreeWithPathView } from "./Views";
|
||||
import React = require("react");
|
||||
|
||||
export function SampleTreeVisualizer() {
|
||||
interface SampleTreeNode {
|
||||
parentPropertyName: string | undefined;
|
||||
name: string;
|
||||
children: SampleTreeNode[];
|
||||
}
|
||||
|
||||
const data = require("./sample-input.json") as SampleTreeNode;
|
||||
|
||||
const m = new TreeViewModel();
|
||||
m.root = createModel(data, m);
|
||||
m.root.children[0].children[4].children[1].children[0].isMarked = true;
|
||||
|
||||
function createModel(
|
||||
root: SampleTreeNode,
|
||||
viewModel: TreeViewModel
|
||||
): TreeNodeViewModel {
|
||||
const children: TreeNodeViewModel[] = root.children.map(c =>
|
||||
createModel(c, viewModel)
|
||||
);
|
||||
const model = new TreeNodeViewModel(
|
||||
viewModel,
|
||||
root.parentPropertyName,
|
||||
root.name,
|
||||
children
|
||||
);
|
||||
for (const c of children) {
|
||||
c.parent = model;
|
||||
}
|
||||
return model;
|
||||
}
|
||||
|
||||
return <TreeWithPathView model={m} />;
|
||||
}
|
||||
409
extension/ui/src/Visualizers/TreeVisualizer/Views.tsx
Normal file
409
extension/ui/src/Visualizers/TreeVisualizer/Views.tsx
Normal file
@@ -0,0 +1,409 @@
|
||||
import { observer, disposeOnUnmount } from "mobx-react";
|
||||
import { observable, autorun, computed, action, runInAction } from "mobx";
|
||||
import React = require("react");
|
||||
import classNames = require("classnames");
|
||||
import { Rectangle, Point } from "../../Components/Point";
|
||||
import { SvgLine } from "../../Components/SvgElements";
|
||||
import "./style.scss";
|
||||
|
||||
export class TreeViewModel {
|
||||
private version = 0;
|
||||
private lastUpdateVersion = -1;
|
||||
|
||||
@observable public root: TreeNodeViewModel | undefined = undefined;
|
||||
|
||||
public invalidateOffsets() {
|
||||
this.version++;
|
||||
}
|
||||
|
||||
@action
|
||||
public updateOffsets() {
|
||||
if (!this.root) {
|
||||
return;
|
||||
}
|
||||
if (this.lastUpdateVersion === this.version) {
|
||||
return;
|
||||
}
|
||||
this.lastUpdateVersion = this.version;
|
||||
|
||||
this.root.updateOffsets();
|
||||
}
|
||||
|
||||
@observable selected: TreeNodeViewModel | undefined = undefined;
|
||||
|
||||
@action public select(current: TreeNodeViewModel | undefined) {
|
||||
if (this.selected) {
|
||||
this.selected.isSelected = false;
|
||||
}
|
||||
if (current) {
|
||||
current.isSelected = true;
|
||||
}
|
||||
this.selected = current;
|
||||
}
|
||||
|
||||
private selectOnHoverEnabled = false;
|
||||
private selectedBeforeHover: TreeNodeViewModel | undefined = undefined;
|
||||
|
||||
@action public hover(current: TreeNodeViewModel | undefined) {
|
||||
if (this.selectOnHoverEnabled) {
|
||||
if (current) {
|
||||
this.select(current);
|
||||
} else {
|
||||
this.select(this.selectedBeforeHover);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
selectOnHover(enable: boolean) {
|
||||
if (this.selectOnHoverEnabled === enable) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (enable) {
|
||||
this.selectedBeforeHover = this.selected;
|
||||
} else if (!this.selected) {
|
||||
this.select(this.selectedBeforeHover);
|
||||
}
|
||||
|
||||
this.selectOnHoverEnabled = enable;
|
||||
}
|
||||
}
|
||||
|
||||
export class TreeNodeViewModel {
|
||||
public parent: TreeNodeViewModel | null = null;
|
||||
|
||||
constructor(
|
||||
public readonly treeViewModel: TreeViewModel,
|
||||
public readonly id: string | undefined,
|
||||
public readonly name: string,
|
||||
public readonly children: TreeNodeViewModel[]
|
||||
) {}
|
||||
|
||||
@observable expanderOffsetRect: Rectangle | undefined = undefined;
|
||||
private expanderDiv: HTMLDivElement | null = null;
|
||||
|
||||
@action.bound
|
||||
setExpanderDiv(div: HTMLDivElement | null) {
|
||||
this.expanderDiv = div;
|
||||
this.treeViewModel.invalidateOffsets();
|
||||
}
|
||||
|
||||
@observable public expanded: boolean = false;
|
||||
@observable public isMarked: boolean = false;
|
||||
@observable public isSelected: boolean = false;
|
||||
|
||||
@action
|
||||
public toggleExpanded() {
|
||||
this.expanded = !this.expanded;
|
||||
this.treeViewModel.invalidateOffsets();
|
||||
}
|
||||
|
||||
@computed public get isChildOrThisMarked(): boolean {
|
||||
if (this.isMarked) return true;
|
||||
return this.children.some(c => c.isChildOrThisMarked);
|
||||
}
|
||||
|
||||
@computed public get isChildOrThisSelected(): boolean {
|
||||
if (this.isSelected) return true;
|
||||
return this.children.some(c => c.isChildOrThisSelected);
|
||||
}
|
||||
|
||||
@computed public get isParentOrThisSelected(): boolean {
|
||||
if (this.isSelected) return true;
|
||||
if (this.parent) return this.parent.isParentOrThisSelected;
|
||||
return false;
|
||||
}
|
||||
|
||||
get path(): string[] {
|
||||
const result = new Array<string>();
|
||||
let c: TreeNodeViewModel = this;
|
||||
while (c.parent) {
|
||||
result.unshift(c.id || c.name);
|
||||
c = c.parent;
|
||||
}
|
||||
if (result.length === 0) {
|
||||
result.push("root");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
updateOffsets() {
|
||||
for (const c of this.children) {
|
||||
c.updateOffsets();
|
||||
}
|
||||
|
||||
if (!this.expanderDiv) {
|
||||
return;
|
||||
}
|
||||
const newRect = Rectangle.ofSize(
|
||||
new Point(this.expanderDiv.offsetLeft, this.expanderDiv.offsetTop),
|
||||
new Point(
|
||||
this.expanderDiv.offsetWidth,
|
||||
this.expanderDiv.offsetHeight
|
||||
)
|
||||
);
|
||||
if (
|
||||
!this.expanderOffsetRect ||
|
||||
!newRect.equals(this.expanderOffsetRect)
|
||||
) {
|
||||
this.expanderOffsetRect = newRect;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@observer
|
||||
export class TreeWithPathView extends React.Component<{
|
||||
model: TreeViewModel;
|
||||
}> {
|
||||
render() {
|
||||
const model = this.props.model;
|
||||
return (
|
||||
<div className="component-TreeWithPathView">
|
||||
<div className="part-path">
|
||||
<span>
|
||||
{model.selected ? (
|
||||
<span>{model.selected.path.join(" / ")}</span>
|
||||
) : (
|
||||
"(Nothing Selected)"
|
||||
)}
|
||||
</span>
|
||||
</div>
|
||||
<div className="part-tree">
|
||||
<TreeView model={model} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@observer
|
||||
export class TreeView extends React.Component<{ model: TreeViewModel }> {
|
||||
render() {
|
||||
const model = this.props.model;
|
||||
return (
|
||||
<div
|
||||
tabIndex={0}
|
||||
className="component-TreeView"
|
||||
onKeyDown={e => {
|
||||
if (e.keyCode === 18) {
|
||||
// alt
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
model.selectOnHover(true);
|
||||
}
|
||||
}}
|
||||
onKeyUp={e => {
|
||||
if (e.keyCode === 18) {
|
||||
// alt
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
model.selectOnHover(false);
|
||||
}
|
||||
}}
|
||||
>
|
||||
{model.root && (
|
||||
<>
|
||||
<svg className="part-svg">
|
||||
<TreeNodeSvgView model={model.root} />
|
||||
</svg>
|
||||
<div className="part-node">
|
||||
<TreeNodeView model={model.root} />
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@observer
|
||||
export class TreeNodeSvgView extends React.Component<{
|
||||
model: TreeNodeViewModel;
|
||||
}> {
|
||||
render() {
|
||||
const model = this.props.model;
|
||||
if (
|
||||
!model.expanderOffsetRect ||
|
||||
model.children.length === 0 ||
|
||||
model.expanded
|
||||
) {
|
||||
return <g />;
|
||||
}
|
||||
|
||||
function findLastExpanderOffset(
|
||||
predicate: (v: TreeNodeViewModel) => boolean
|
||||
): Rectangle | undefined {
|
||||
const all = model.children
|
||||
.filter(predicate)
|
||||
.map(c => c.expanderOffsetRect);
|
||||
const last = all[all.length - 1];
|
||||
return last;
|
||||
}
|
||||
|
||||
const lastOffset = findLastExpanderOffset(() => true);
|
||||
const selectedOffset = findLastExpanderOffset(
|
||||
v => v.isChildOrThisSelected
|
||||
);
|
||||
const markedOffset = findLastExpanderOffset(v => v.isChildOrThisMarked);
|
||||
|
||||
if (!lastOffset) {
|
||||
return <g />;
|
||||
}
|
||||
|
||||
const start = model.expanderOffsetRect.center.add({ y: 10 });
|
||||
|
||||
return (
|
||||
<g className="component-TreeNodeSvgView">
|
||||
{markedOffset && (
|
||||
<SvgLine
|
||||
className="path childOrThisMarked"
|
||||
start={start}
|
||||
end={new Point(start.x, markedOffset.center.y)}
|
||||
/>
|
||||
)}
|
||||
{selectedOffset && (
|
||||
<SvgLine
|
||||
className="path childOrThisSelected"
|
||||
start={start}
|
||||
end={new Point(start.x, selectedOffset.center.y)}
|
||||
/>
|
||||
)}
|
||||
<SvgLine
|
||||
className="path"
|
||||
start={start}
|
||||
end={new Point(start.x, lastOffset.center.y)}
|
||||
/>
|
||||
{model.children.map((c, idx) => {
|
||||
const end = c.expanderOffsetRect!.center.sub({ x: 5 });
|
||||
|
||||
return (
|
||||
<g key={idx}>
|
||||
{c.isChildOrThisMarked && (
|
||||
<SvgLine
|
||||
className={classNames(
|
||||
"path",
|
||||
"childOrThisMarked"
|
||||
)}
|
||||
start={new Point(start.x, end.y)}
|
||||
end={end}
|
||||
/>
|
||||
)}
|
||||
<SvgLine
|
||||
className={classNames(
|
||||
"path",
|
||||
c.isChildOrThisSelected &&
|
||||
"childOrThisSelected"
|
||||
)}
|
||||
start={new Point(start.x, end.y)}
|
||||
end={end}
|
||||
/>
|
||||
</g>
|
||||
);
|
||||
})}
|
||||
{model.children.map((c, idx) => (
|
||||
<TreeNodeSvgView key={idx} model={c} />
|
||||
))}
|
||||
</g>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@observer
|
||||
export class TreeNodeView extends React.Component<{
|
||||
model: TreeNodeViewModel;
|
||||
}> {
|
||||
@action.bound
|
||||
private clickHandler() {
|
||||
this.props.model.treeViewModel.select(this.props.model);
|
||||
}
|
||||
|
||||
private mouseEnterOrLeaveHandler(enter: boolean) {
|
||||
this.props.model.treeViewModel.hover(
|
||||
enter ? this.props.model : undefined
|
||||
);
|
||||
}
|
||||
|
||||
@observable
|
||||
private rootDiv: HTMLElement | null = null;
|
||||
@action.bound
|
||||
private setRootDiv(div: HTMLElement | null) {
|
||||
this.rootDiv = div;
|
||||
}
|
||||
|
||||
@disposeOnUnmount
|
||||
private readonly _autorun = autorun(() => {
|
||||
if (this.props.model.isMarked && this.rootDiv) {
|
||||
this.rootDiv.scrollIntoView();
|
||||
}
|
||||
});
|
||||
|
||||
public componentDidMount() {
|
||||
this.props.model.treeViewModel.updateOffsets();
|
||||
}
|
||||
|
||||
public componentDidUpdate() {
|
||||
this.props.model.treeViewModel.updateOffsets();
|
||||
}
|
||||
|
||||
public render(): JSX.Element {
|
||||
const model = this.props.model;
|
||||
const collapsed = model.expanded;
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classNames(
|
||||
"component-TreeNodeView",
|
||||
model.expanded && "collapsed",
|
||||
model.isMarked && "selected",
|
||||
model.isSelected && "hovered",
|
||||
model.isChildOrThisSelected &&
|
||||
!model.isSelected &&
|
||||
"childHovered",
|
||||
model.isParentOrThisSelected &&
|
||||
!model.isSelected &&
|
||||
"parentHovered"
|
||||
)}
|
||||
ref={this.setRootDiv}
|
||||
onMouseOver={e => {
|
||||
this.mouseEnterOrLeaveHandler(true);
|
||||
e.stopPropagation();
|
||||
}}
|
||||
onMouseOut={e => {
|
||||
this.mouseEnterOrLeaveHandler(false);
|
||||
e.stopPropagation();
|
||||
}}
|
||||
>
|
||||
<div className="part-header">
|
||||
<div
|
||||
ref={model.setExpanderDiv}
|
||||
onClick={() => model.toggleExpanded()}
|
||||
className={classNames(
|
||||
"part-collapser",
|
||||
model.children.length > 0 &&
|
||||
"decorator-collapse-icon",
|
||||
!collapsed && "expanded"
|
||||
)}
|
||||
/>
|
||||
|
||||
<span className="part-text" onClick={this.clickHandler}>
|
||||
{model.id && (
|
||||
<>
|
||||
<span className="part-id">{model.id}</span>
|
||||
<span>: </span>
|
||||
</>
|
||||
)}
|
||||
<span className="part-name">{model.name}</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{model.children.length > 0 && !model.expanded && (
|
||||
<div className="part-children">
|
||||
{model.children.map((c, idx) => (
|
||||
<TreeNodeView model={c} key={idx} />
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
29
extension/ui/src/Visualizers/TreeVisualizer/Visualizers.ts
Normal file
29
extension/ui/src/Visualizers/TreeVisualizer/Visualizers.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { TreeViewModel, TreeNodeViewModel } from "./Views";
|
||||
import { TreeNodeData } from "@hediet/debug-visualizer-data-extraction";
|
||||
|
||||
export function createTreeViewModelFromTreeNodeData(
|
||||
root: TreeNodeData["root"]
|
||||
): TreeViewModel {
|
||||
const m = new TreeViewModel();
|
||||
m.root = recurse(root, m);
|
||||
return m;
|
||||
|
||||
function recurse(
|
||||
root: TreeNodeData["root"],
|
||||
viewModel: TreeViewModel
|
||||
): TreeNodeViewModel {
|
||||
const children: TreeNodeViewModel[] = root.children.map(c =>
|
||||
recurse(c, viewModel)
|
||||
);
|
||||
const model = new TreeNodeViewModel(
|
||||
viewModel,
|
||||
root.id,
|
||||
root.name,
|
||||
children
|
||||
);
|
||||
for (const c of children) {
|
||||
c.parent = model;
|
||||
}
|
||||
return model;
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
100
extension/ui/src/Visualizers/TreeVisualizer/style.scss
Normal file
100
extension/ui/src/Visualizers/TreeVisualizer/style.scss
Normal file
@@ -0,0 +1,100 @@
|
||||
.component-TreeView {
|
||||
overflow: auto;
|
||||
scroll-behavior: smooth;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
display: grid;
|
||||
|
||||
& > .part-svg,
|
||||
& > .part-node {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
grid-column: 1;
|
||||
grid-row: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.component-TreeNodeSvgView {
|
||||
.path {
|
||||
stroke: gray;
|
||||
stroke-dasharray: 1;
|
||||
|
||||
&.childOrThisMarked {
|
||||
stroke: orange;
|
||||
stroke-width: 5;
|
||||
stroke-dasharray: 0;
|
||||
stroke-linecap: round;
|
||||
}
|
||||
|
||||
&.childOrThisSelected {
|
||||
stroke: black;
|
||||
stroke-width: 2;
|
||||
stroke-dasharray: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.component-TreeNodeView {
|
||||
font-family: -apple-system, BlinkMacSystemFont, Segoe WPC, Segoe UI,
|
||||
HelveticaNeue-Light, Ubuntu, Droid Sans, sans-serif;
|
||||
|
||||
.part-header {
|
||||
padding: 2px;
|
||||
padding-left: 5px;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.part-collapser {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
margin-right: 6px;
|
||||
}
|
||||
|
||||
.part-text {
|
||||
cursor: pointer;
|
||||
.part-id {
|
||||
color: blue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.part-children {
|
||||
margin-left: 0px;
|
||||
margin-top: 0px;
|
||||
|
||||
padding: 5px;
|
||||
padding-left: 15px;
|
||||
}
|
||||
|
||||
&.selected {
|
||||
& > .part-header {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
&.hovered {
|
||||
& > .part-header > span {
|
||||
font-weight: bold;
|
||||
}
|
||||
& > .part-children {
|
||||
background: transparentize(gray, 0.8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.component-TreeWithPathView {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
|
||||
.part-path {
|
||||
overflow: hidden;
|
||||
white-space: pre;
|
||||
padding: 5px 10px;
|
||||
border-bottom: solid gray 1px;
|
||||
}
|
||||
.part-tree {
|
||||
overflow: auto;
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
29
extension/ui/src/index.tsx
Normal file
29
extension/ui/src/index.tsx
Normal file
@@ -0,0 +1,29 @@
|
||||
import * as React from "react";
|
||||
import * as ReactDOM from "react-dom";
|
||||
import "./style.scss";
|
||||
import { Model } from "./Model";
|
||||
import Components = require("./Components");
|
||||
|
||||
const model = new Model();
|
||||
|
||||
function render(target: HTMLDivElement) {
|
||||
const c = require("./Components") as typeof Components;
|
||||
ReactDOM.render(<c.GUI model={model} />, target);
|
||||
}
|
||||
|
||||
const target = document.createElement("div");
|
||||
target.className = "target";
|
||||
document.body.appendChild(target);
|
||||
|
||||
render(target);
|
||||
|
||||
declare var module: {
|
||||
hot?: { accept: (componentName: string, callback: () => void) => void };
|
||||
};
|
||||
declare var require: (name: string) => any;
|
||||
|
||||
if (module.hot) {
|
||||
module.hot.accept("./Components", () => {
|
||||
render(target);
|
||||
});
|
||||
}
|
||||
197
extension/ui/src/style.scss
Normal file
197
extension/ui/src/style.scss
Normal file
@@ -0,0 +1,197 @@
|
||||
@import "./vscode-light.scss";
|
||||
|
||||
@import "~normalize.css";
|
||||
@import "~@blueprintjs/core/lib/css/blueprint.css";
|
||||
@import "~@blueprintjs/icons/lib/css/blueprint-icons.css";
|
||||
|
||||
body {
|
||||
font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
border: 0px;
|
||||
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
html,
|
||||
body,
|
||||
.target {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.component-Visualizer {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.component-NoData {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
svg {
|
||||
float: left; // to prevent scrollbar.
|
||||
// I don't know why it works.
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
rect {
|
||||
fill: white;
|
||||
}
|
||||
|
||||
line {
|
||||
stroke: gray;
|
||||
}
|
||||
|
||||
text {
|
||||
stroke: black;
|
||||
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;
|
||||
|
||||
transition: flex 0.3s ease-out;
|
||||
|
||||
.part-header-main,
|
||||
.part-header-options {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.part-expression-input {
|
||||
//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%;
|
||||
}
|
||||
}
|
||||
|
||||
.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);
|
||||
|
||||
div {
|
||||
color: black;
|
||||
padding: 12px 16px;
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
|
||||
&:hover {
|
||||
background-color: #ddd;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bp3-popover-wrapper {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.bp3-popover-target {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.svgViewer {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
288
extension/ui/src/vscode-dark.scss
Normal file
288
extension/ui/src/vscode-dark.scss
Normal file
@@ -0,0 +1,288 @@
|
||||
:root {
|
||||
--background-color: #263238;
|
||||
--color: #eeffff;
|
||||
--font-family: -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", HelveticaNeue-Light, Ubuntu, "Droid Sans", sans-serif;
|
||||
--font-size: 13px;
|
||||
--font-weight: normal;
|
||||
--link-active-color: #eeffff;
|
||||
--link-color: #80cbc4;
|
||||
--vscode-activityBar-background: #192227;
|
||||
--vscode-activityBar-border: rgba(0, 0, 0, 0.38);
|
||||
--vscode-activityBar-dropBackground: rgba(255, 255, 255, 0.12);
|
||||
--vscode-activityBar-foreground: #eeffff;
|
||||
--vscode-activityBar-inactiveForeground: rgba(238, 255, 255, 0.6);
|
||||
--vscode-activityBarBadge-background: #80cbc4;
|
||||
--vscode-activityBarBadge-foreground: #000000;
|
||||
--vscode-badge-background: rgba(0, 0, 0, 0.19);
|
||||
--vscode-badge-foreground: #546e7a;
|
||||
--vscode-breadcrumb-activeSelectionForeground: #80cbc4;
|
||||
--vscode-breadcrumb-background: #263238;
|
||||
--vscode-breadcrumb-focusForeground: #eeffff;
|
||||
--vscode-breadcrumb-foreground: #5f7a87;
|
||||
--vscode-breadcrumbPicker-background: #192227;
|
||||
--vscode-button-background: rgba(128, 203, 196, 0.13);
|
||||
--vscode-button-foreground: #ffffff;
|
||||
--vscode-button-hoverBackground: rgba(175, 222, 218, 0.13);
|
||||
--vscode-debugExceptionWidget-background: #420b0d;
|
||||
--vscode-debugExceptionWidget-border: #a31515;
|
||||
--vscode-debugToolBar-background: #263238;
|
||||
--vscode-descriptionForeground: rgba(204, 204, 204, 0.7);
|
||||
--vscode-diffEditor-insertedTextBackground: rgba(195, 232, 141, 0.08);
|
||||
--vscode-diffEditor-removedTextBackground: rgba(255, 83, 112, 0.13);
|
||||
--vscode-dropdown-background: #263238;
|
||||
--vscode-dropdown-border: rgba(255, 255, 255, 0.06);
|
||||
--vscode-dropdown-foreground: #f0f0f0;
|
||||
--vscode-editor-background: #263238;
|
||||
--vscode-editor-findMatchBackground: #515c6a;
|
||||
--vscode-editor-findMatchHighlightBackground: rgba(234, 92, 0, 0.33);
|
||||
--vscode-editor-findRangeHighlightBackground: rgba(58, 61, 65, 0.4);
|
||||
--vscode-editor-focusedStackFrameHighlightBackground: rgba(122, 189, 122, 0.3);
|
||||
--vscode-editor-font-family: -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", HelveticaNeue-Light, Ubuntu, "Droid Sans", sans-serif;
|
||||
--vscode-editor-font-size: 13px;
|
||||
--vscode-editor-font-weight: normal;
|
||||
--vscode-editor-foreground: #eeffff;
|
||||
--vscode-editor-hoverHighlightBackground: rgba(38, 79, 120, 0.25);
|
||||
--vscode-editor-inactiveSelectionBackground: rgba(128, 203, 196, 0.06);
|
||||
--vscode-editor-lineHighlightBackground: rgba(0, 0, 0, 0.31);
|
||||
--vscode-editor-lineHighlightBorder: #282828;
|
||||
--vscode-editor-rangeHighlightBackground: rgba(255, 255, 255, 0.04);
|
||||
--vscode-editor-selectionBackground: rgba(128, 203, 196, 0.13);
|
||||
--vscode-editor-selectionHighlightBackground: rgba(255, 204, 0, 0.13);
|
||||
--vscode-editor-snippetFinalTabstopHighlightBorder: #525252;
|
||||
--vscode-editor-snippetTabstopHighlightBackground: rgba(124, 124, 124, 0.3);
|
||||
--vscode-editor-stackFrameHighlightBackground: rgba(255, 255, 0, 0.2);
|
||||
--vscode-editor-wordHighlightBackground: rgba(87, 87, 87, 0.72);
|
||||
--vscode-editor-wordHighlightStrongBackground: rgba(0, 73, 114, 0.72);
|
||||
--vscode-editorActiveLineNumber-foreground: #c6c6c6;
|
||||
--vscode-editorBracketMatch-background: #263238;
|
||||
--vscode-editorBracketMatch-border: rgba(255, 204, 0, 0.31);
|
||||
--vscode-editorCodeLens-foreground: #999999;
|
||||
--vscode-editorCursor-foreground: #ffcc00;
|
||||
--vscode-editorError-foreground: rgba(255, 83, 112, 0.44);
|
||||
--vscode-editorGroup-border: rgba(0, 0, 0, 0.19);
|
||||
--vscode-editorGroup-dropBackground: rgba(83, 89, 93, 0.5);
|
||||
--vscode-editorGroupHeader-noTabsBackground: #263238;
|
||||
--vscode-editorGroupHeader-tabsBackground: #263238;
|
||||
--vscode-editorGutter-addedBackground: rgba(195, 232, 141, 0.38);
|
||||
--vscode-editorGutter-background: #263238;
|
||||
--vscode-editorGutter-commentRangeForeground: #c5c5c5;
|
||||
--vscode-editorGutter-deletedBackground: rgba(255, 83, 112, 0.38);
|
||||
--vscode-editorGutter-modifiedBackground: rgba(130, 170, 255, 0.38);
|
||||
--vscode-editorHint-foreground: rgba(238, 238, 238, 0.7);
|
||||
--vscode-editorHoverWidget-background: #263238;
|
||||
--vscode-editorHoverWidget-border: rgba(255, 255, 255, 0.06);
|
||||
--vscode-editorIndentGuide-activeBackground: #37474f;
|
||||
--vscode-editorIndentGuide-background: rgba(55, 71, 79, 0.44);
|
||||
--vscode-editorInfo-foreground: #008000;
|
||||
--vscode-editorLineNumber-activeForeground: #5f7a87;
|
||||
--vscode-editorLineNumber-foreground: #37474f;
|
||||
--vscode-editorLink-activeForeground: #eeffff;
|
||||
--vscode-editorMarkerNavigation-background: rgba(238, 255, 255, 0.02);
|
||||
--vscode-editorMarkerNavigationError-background: rgba(255, 83, 112, 0.44);
|
||||
--vscode-editorMarkerNavigationInfo-background: #008000;
|
||||
--vscode-editorMarkerNavigationWarning-background: rgba(195, 232, 141, 0.44);
|
||||
--vscode-editorOverviewRuler-addedForeground: rgba(0, 122, 204, 0.6);
|
||||
--vscode-editorOverviewRuler-border: #263238;
|
||||
--vscode-editorOverviewRuler-bracketMatchForeground: #a0a0a0;
|
||||
--vscode-editorOverviewRuler-commonContentForeground: rgba(96, 96, 96, 0.4);
|
||||
--vscode-editorOverviewRuler-currentContentForeground: rgba(64, 200, 174, 0.5);
|
||||
--vscode-editorOverviewRuler-deletedForeground: rgba(0, 122, 204, 0.6);
|
||||
--vscode-editorOverviewRuler-errorForeground: rgba(255, 18, 18, 0.7);
|
||||
--vscode-editorOverviewRuler-findMatchForeground: rgba(246, 185, 77, 0.7);
|
||||
--vscode-editorOverviewRuler-incomingContentForeground: rgba(64, 166, 255, 0.5);
|
||||
--vscode-editorOverviewRuler-infoForeground: rgba(18, 18, 136, 0.7);
|
||||
--vscode-editorOverviewRuler-modifiedForeground: rgba(0, 122, 204, 0.6);
|
||||
--vscode-editorOverviewRuler-rangeHighlightForeground: rgba(0, 122, 204, 0.6);
|
||||
--vscode-editorOverviewRuler-selectionHighlightForeground: rgba(160, 160, 160, 0.8);
|
||||
--vscode-editorOverviewRuler-warningForeground: rgba(18, 136, 18, 0.7);
|
||||
--vscode-editorOverviewRuler-wordHighlightForeground: rgba(160, 160, 160, 0.8);
|
||||
--vscode-editorOverviewRuler-wordHighlightStrongForeground: rgba(192, 160, 192, 0.8);
|
||||
--vscode-editorPane-background: #263238;
|
||||
--vscode-editorRuler-foreground: #37474f;
|
||||
--vscode-editorSuggestWidget-background: #263238;
|
||||
--vscode-editorSuggestWidget-border: rgba(255, 255, 255, 0.06);
|
||||
--vscode-editorSuggestWidget-foreground: #eeffff;
|
||||
--vscode-editorSuggestWidget-highlightForeground: #80cbc4;
|
||||
--vscode-editorSuggestWidget-selectedBackground: rgba(0, 0, 0, 0.31);
|
||||
--vscode-editorUnnecessaryCode-opacity: rgba(0, 0, 0, 0.67);
|
||||
--vscode-editorWarning-foreground: rgba(195, 232, 141, 0.44);
|
||||
--vscode-editorWhitespace-foreground: rgba(238, 255, 255, 0.25);
|
||||
--vscode-editorWidget-background: #192227;
|
||||
--vscode-editorWidget-border: #ff0000;
|
||||
--vscode-editorWidget-resizeBorder: #80cbc4;
|
||||
--vscode-errorForeground: #f48771;
|
||||
--vscode-extensionButton-prominentBackground: rgba(195, 232, 141, 0.56);
|
||||
--vscode-extensionButton-prominentForeground: #ffffff;
|
||||
--vscode-extensionButton-prominentHoverBackground: #c3e88d;
|
||||
--vscode-focusBorder: rgba(255, 255, 255, 0);
|
||||
--vscode-foreground: #cccccc;
|
||||
--vscode-gitDecoration-addedResourceForeground: #81b88b;
|
||||
--vscode-gitDecoration-conflictingResourceForeground: rgba(255, 203, 107, 0.56);
|
||||
--vscode-gitDecoration-deletedResourceForeground: rgba(255, 83, 112, 0.56);
|
||||
--vscode-gitDecoration-ignoredResourceForeground: rgba(95, 122, 135, 0.56);
|
||||
--vscode-gitDecoration-modifiedResourceForeground: rgba(130, 170, 255, 0.56);
|
||||
--vscode-gitDecoration-submoduleResourceForeground: #8db9e2;
|
||||
--vscode-gitDecoration-untrackedResourceForeground: rgba(195, 232, 141, 0.56);
|
||||
--vscode-gitlens-gutterBackgroundColor: rgba(255, 255, 255, 0.07);
|
||||
--vscode-gitlens-gutterForegroundColor: #bebebe;
|
||||
--vscode-gitlens-gutterUncommittedForegroundColor: rgba(0, 188, 242, 0.6);
|
||||
--vscode-gitlens-lineHighlightBackgroundColor: rgba(0, 188, 242, 0.2);
|
||||
--vscode-gitlens-lineHighlightOverviewRulerColor: rgba(0, 188, 242, 0.6);
|
||||
--vscode-gitlens-trailingLineBackgroundColor: rgba(0, 0, 0, 0);
|
||||
--vscode-gitlens-trailingLineForegroundColor: rgba(153, 153, 153, 0.35);
|
||||
--vscode-input-background: #303c41;
|
||||
--vscode-input-border: rgba(255, 255, 255, 0.06);
|
||||
--vscode-input-foreground: #eeffff;
|
||||
--vscode-input-placeholderForeground: rgba(238, 255, 255, 0.38);
|
||||
--vscode-inputOption-activeBorder: #007acc;
|
||||
--vscode-inputValidation-errorBackground: #5a1d1d;
|
||||
--vscode-inputValidation-errorBorder: rgba(255, 83, 112, 0.31);
|
||||
--vscode-inputValidation-infoBackground: #063b49;
|
||||
--vscode-inputValidation-infoBorder: rgba(130, 170, 255, 0.31);
|
||||
--vscode-inputValidation-warningBackground: #352a05;
|
||||
--vscode-inputValidation-warningBorder: rgba(255, 203, 107, 0.31);
|
||||
--vscode-list-activeSelectionBackground: #192227;
|
||||
--vscode-list-activeSelectionForeground: #80cbc4;
|
||||
--vscode-list-dropBackground: rgba(238, 255, 255, 0.13);
|
||||
--vscode-list-errorForeground: #f88070;
|
||||
--vscode-list-focusBackground: rgba(238, 255, 255, 0.13);
|
||||
--vscode-list-focusForeground: #eeffff;
|
||||
--vscode-list-highlightForeground: #80cbc4;
|
||||
--vscode-list-hoverBackground: #192227;
|
||||
--vscode-list-hoverForeground: #ffffff;
|
||||
--vscode-list-inactiveFocusBackground: #313135;
|
||||
--vscode-list-inactiveSelectionBackground: rgba(0, 0, 0, 0.19);
|
||||
--vscode-list-inactiveSelectionForeground: #80cbc4;
|
||||
--vscode-list-invalidItemForeground: #b89500;
|
||||
--vscode-list-warningForeground: #4d9e4d;
|
||||
--vscode-menu-background: #263238;
|
||||
--vscode-menu-foreground: #eeffff;
|
||||
--vscode-menu-selectionBackground: rgba(0, 0, 0, 0.31);
|
||||
--vscode-menu-selectionBorder: rgba(0, 0, 0, 0.19);
|
||||
--vscode-menu-selectionForeground: #80cbc4;
|
||||
--vscode-menu-separatorBackground: #eeffff;
|
||||
--vscode-menubar-selectionBackground: rgba(0, 0, 0, 0.19);
|
||||
--vscode-menubar-selectionBorder: rgba(0, 0, 0, 0.19);
|
||||
--vscode-menubar-selectionForeground: #80cbc4;
|
||||
--vscode-merge-commonContentBackground: rgba(96, 96, 96, 0.16);
|
||||
--vscode-merge-commonHeaderBackground: rgba(96, 96, 96, 0.4);
|
||||
--vscode-merge-currentContentBackground: rgba(64, 200, 174, 0.2);
|
||||
--vscode-merge-currentHeaderBackground: rgba(64, 200, 174, 0.5);
|
||||
--vscode-merge-incomingContentBackground: rgba(64, 166, 255, 0.2);
|
||||
--vscode-merge-incomingHeaderBackground: rgba(64, 166, 255, 0.5);
|
||||
--vscode-notificationCenterHeader-background: #314149;
|
||||
--vscode-notificationLink-foreground: #80cbc4;
|
||||
--vscode-notifications-background: #263238;
|
||||
--vscode-notifications-border: #314149;
|
||||
--vscode-notifications-foreground: #eeffff;
|
||||
--vscode-panel-background: #192227;
|
||||
--vscode-panel-border: rgba(0, 0, 0, 0.38);
|
||||
--vscode-panel-dropBackground: #eeffff;
|
||||
--vscode-panelTitle-activeBorder: #80cbc4;
|
||||
--vscode-panelTitle-activeForeground: #ffffff;
|
||||
--vscode-panelTitle-inactiveForeground: #eeffff;
|
||||
--vscode-peekView-border: rgba(0, 0, 0, 0.19);
|
||||
--vscode-peekViewEditor-background: rgba(238, 255, 255, 0.02);
|
||||
--vscode-peekViewEditor-matchHighlightBackground: rgba(128, 203, 196, 0.13);
|
||||
--vscode-peekViewEditorGutter-background: rgba(238, 255, 255, 0.02);
|
||||
--vscode-peekViewResult-background: rgba(238, 255, 255, 0.02);
|
||||
--vscode-peekViewResult-fileForeground: #ffffff;
|
||||
--vscode-peekViewResult-lineForeground: #bbbbbb;
|
||||
--vscode-peekViewResult-matchHighlightBackground: rgba(128, 203, 196, 0.13);
|
||||
--vscode-peekViewResult-selectionBackground: rgba(95, 122, 135, 0.44);
|
||||
--vscode-peekViewResult-selectionForeground: #ffffff;
|
||||
--vscode-peekViewTitle-background: rgba(238, 255, 255, 0.02);
|
||||
--vscode-peekViewTitleDescription-foreground: rgba(238, 255, 255, 0.38);
|
||||
--vscode-peekViewTitleLabel-foreground: #ffffff;
|
||||
--vscode-pickerGroup-border: #3f3f46;
|
||||
--vscode-pickerGroup-foreground: #80cbc4;
|
||||
--vscode-progressBar-background: #80cbc4;
|
||||
--vscode-scrollbar-shadow: rgba(38, 50, 56, 0);
|
||||
--vscode-scrollbarSlider-activeBackground: #80cbc4;
|
||||
--vscode-scrollbarSlider-background: rgba(238, 255, 255, 0.13);
|
||||
--vscode-scrollbarSlider-hoverBackground: rgba(238, 255, 255, 0.06);
|
||||
--vscode-selection-background: #eeffff;
|
||||
--vscode-settings-checkboxBackground: #192227;
|
||||
--vscode-settings-checkboxBorder: rgba(255, 255, 255, 0.06);
|
||||
--vscode-settings-checkboxForeground: #eeffff;
|
||||
--vscode-settings-dropdownBackground: #192227;
|
||||
--vscode-settings-dropdownBorder: rgba(255, 255, 255, 0.06);
|
||||
--vscode-settings-dropdownForeground: #eeffff;
|
||||
--vscode-settings-dropdownListBorder: #ff0000;
|
||||
--vscode-settings-headerForeground: #80cbc4;
|
||||
--vscode-settings-modifiedItemIndicator: #80cbc4;
|
||||
--vscode-settings-numberInputBackground: #192227;
|
||||
--vscode-settings-numberInputBorder: rgba(255, 255, 255, 0.06);
|
||||
--vscode-settings-numberInputForeground: #eeffff;
|
||||
--vscode-settings-textInputBackground: #192227;
|
||||
--vscode-settings-textInputBorder: rgba(255, 255, 255, 0.06);
|
||||
--vscode-settings-textInputForeground: #eeffff;
|
||||
--vscode-sideBar-background: #192227;
|
||||
--vscode-sideBar-border: rgba(0, 0, 0, 0.38);
|
||||
--vscode-sideBar-dropBackground: rgba(255, 255, 255, 0.12);
|
||||
--vscode-sideBar-foreground: #5f7a87;
|
||||
--vscode-sideBarSectionHeader-background: #192227;
|
||||
--vscode-sideBarSectionHeader-border: rgba(0, 0, 0, 0.38);
|
||||
--vscode-sideBarSectionHeader-foreground: #5f7a87;
|
||||
--vscode-sideBarTitle-foreground: #eeffff;
|
||||
--vscode-statusBar-background: #192227;
|
||||
--vscode-statusBar-border: rgba(0, 0, 0, 0.38);
|
||||
--vscode-statusBar-debuggingBackground: #c792ea;
|
||||
--vscode-statusBar-debuggingBorder: rgba(0, 0, 0, 0.38);
|
||||
--vscode-statusBar-debuggingForeground: #ffffff;
|
||||
--vscode-statusBar-foreground: #546e7a;
|
||||
--vscode-statusBar-noFolderBackground: #263238;
|
||||
--vscode-statusBar-noFolderBorder: rgba(0, 0, 0, 0.38);
|
||||
--vscode-statusBar-noFolderForeground: #546e7a;
|
||||
--vscode-statusBarItem-activeBackground: rgba(255, 255, 255, 0.18);
|
||||
--vscode-statusBarItem-hoverBackground: rgba(84, 110, 122, 0.13);
|
||||
--vscode-statusBarItem-prominentBackground: #388a34;
|
||||
--vscode-statusBarItem-prominentHoverBackground: #369432;
|
||||
--vscode-tab-activeBackground: #263238;
|
||||
--vscode-tab-activeBorder: #80cbc4;
|
||||
--vscode-tab-activeForeground: #ffffff;
|
||||
--vscode-tab-activeModifiedBorder: #5f7a87;
|
||||
--vscode-tab-border: #263238;
|
||||
--vscode-tab-inactiveBackground: #263238;
|
||||
--vscode-tab-inactiveForeground: #5f7a87;
|
||||
--vscode-tab-inactiveModifiedBorder: rgba(95, 122, 135, 0.5);
|
||||
--vscode-tab-unfocusedActiveBorder: #546e7a;
|
||||
--vscode-tab-unfocusedActiveForeground: #eeffff;
|
||||
--vscode-tab-unfocusedActiveModifiedBorder: rgba(95, 122, 135, 0.5);
|
||||
--vscode-tab-unfocusedInactiveForeground: rgba(95, 122, 135, 0.5);
|
||||
--vscode-tab-unfocusedInactiveModifiedBorder: rgba(95, 122, 135, 0.25);
|
||||
--vscode-terminal-ansiBlack: #000000;
|
||||
--vscode-terminal-ansiBlue: #82aaff;
|
||||
--vscode-terminal-ansiBrightBlack: #546e7a;
|
||||
--vscode-terminal-ansiBrightBlue: #82aaff;
|
||||
--vscode-terminal-ansiBrightCyan: #89ddff;
|
||||
--vscode-terminal-ansiBrightGreen: #c3e88d;
|
||||
--vscode-terminal-ansiBrightMagenta: #c792ea;
|
||||
--vscode-terminal-ansiBrightRed: #ff5370;
|
||||
--vscode-terminal-ansiBrightWhite: #ffffff;
|
||||
--vscode-terminal-ansiBrightYellow: #ffcb6b;
|
||||
--vscode-terminal-ansiCyan: #89ddff;
|
||||
--vscode-terminal-ansiGreen: #c3e88d;
|
||||
--vscode-terminal-ansiMagenta: #c792ea;
|
||||
--vscode-terminal-ansiRed: #ff5370;
|
||||
--vscode-terminal-ansiWhite: #ffffff;
|
||||
--vscode-terminal-ansiYellow: #ffcb6b;
|
||||
--vscode-terminal-background: #192227;
|
||||
--vscode-terminal-border: rgba(0, 0, 0, 0.38);
|
||||
--vscode-terminal-foreground: #cccccc;
|
||||
--vscode-terminal-selectionBackground: rgba(255, 255, 255, 0.25);
|
||||
--vscode-textBlockQuote-background: rgba(127, 127, 127, 0.1);
|
||||
--vscode-textBlockQuote-border: rgba(0, 122, 204, 0.5);
|
||||
--vscode-textCodeBlock-background: rgba(10, 10, 10, 0.4);
|
||||
--vscode-textLink-activeForeground: #eeffff;
|
||||
--vscode-textLink-foreground: #80cbc4;
|
||||
--vscode-textPreformat-foreground: #d7ba7d;
|
||||
--vscode-textSeparator-foreground: rgba(255, 255, 255, 0.18);
|
||||
--vscode-titleBar-activeBackground: #192227;
|
||||
--vscode-titleBar-activeForeground: #eeffff;
|
||||
--vscode-titleBar-border: rgba(0, 0, 0, 0.38);
|
||||
--vscode-titleBar-inactiveBackground: #192227;
|
||||
--vscode-titleBar-inactiveForeground: #5f7a87;
|
||||
--vscode-widget-shadow: rgba(0, 0, 0, 0.19);
|
||||
}
|
||||
|
||||
307
extension/ui/src/vscode-light.scss
Normal file
307
extension/ui/src/vscode-light.scss
Normal file
@@ -0,0 +1,307 @@
|
||||
:root {
|
||||
--vscode-activityBar-background: #2c2c2c;
|
||||
--vscode-activityBar-dropBackground: rgba(255, 255, 255, 0.12);
|
||||
--vscode-activityBar-foreground: #ffffff;
|
||||
--vscode-activityBar-inactiveForeground: rgba(255, 255, 255, 0.6);
|
||||
--vscode-activityBarBadge-background: #007acc;
|
||||
--vscode-activityBarBadge-foreground: #ffffff;
|
||||
--vscode-badge-background: #c4c4c4;
|
||||
--vscode-badge-foreground: #333333;
|
||||
--vscode-breadcrumb-activeSelectionForeground: #4e4e4e;
|
||||
--vscode-breadcrumb-background: #ffffff;
|
||||
--vscode-breadcrumb-focusForeground: #4e4e4e;
|
||||
--vscode-breadcrumb-foreground: rgba(97, 97, 97, 0.8);
|
||||
--vscode-breadcrumbPicker-background: #f3f3f3;
|
||||
--vscode-button-background: #007acc;
|
||||
--vscode-button-foreground: #ffffff;
|
||||
--vscode-button-hoverBackground: #0062a3;
|
||||
--vscode-debugExceptionWidget-background: #f1dfde;
|
||||
--vscode-debugExceptionWidget-border: #a31515;
|
||||
--vscode-debugToolBar-background: #f3f3f3;
|
||||
--vscode-descriptionForeground: #717171;
|
||||
--vscode-diffEditor-insertedTextBackground: rgba(155, 185, 85, 0.2);
|
||||
--vscode-diffEditor-removedTextBackground: rgba(255, 0, 0, 0.2);
|
||||
--vscode-dropdown-background: #ffffff;
|
||||
--vscode-dropdown-border: #cecece;
|
||||
--vscode-editor-background: #ffffff;
|
||||
--vscode-editor-findMatchBackground: #a8ac94;
|
||||
--vscode-editor-findMatchHighlightBackground: rgba(234, 92, 0, 0.33);
|
||||
--vscode-editor-findRangeHighlightBackground: rgba(180, 180, 180, 0.3);
|
||||
--vscode-editor-focusedStackFrameHighlightBackground: rgba(
|
||||
206,
|
||||
231,
|
||||
206,
|
||||
0.45
|
||||
);
|
||||
--vscode-editor-font-family: Consolas, "Courier New", monospace;
|
||||
--vscode-editor-font-size: 14;
|
||||
--vscode-editor-font-weight: normal;
|
||||
--vscode-editor-foreground: #000000;
|
||||
--vscode-editor-hoverHighlightBackground: rgba(173, 214, 255, 0.15);
|
||||
--vscode-editor-inactiveSelectionBackground: #e5ebf1;
|
||||
--vscode-editor-lineHighlightBorder: #eeeeee;
|
||||
--vscode-editor-rangeHighlightBackground: rgba(253, 255, 0, 0.2);
|
||||
--vscode-editor-selectionBackground: #add6ff;
|
||||
--vscode-editor-selectionHighlightBackground: rgba(173, 214, 255, 0.5);
|
||||
--vscode-editor-snippetFinalTabstopHighlightBorder: rgba(10, 50, 100, 0.5);
|
||||
--vscode-editor-snippetTabstopHighlightBackground: rgba(10, 50, 100, 0.2);
|
||||
--vscode-editor-stackFrameHighlightBackground: rgba(255, 255, 102, 0.45);
|
||||
--vscode-editor-wordHighlightBackground: rgba(87, 87, 87, 0.25);
|
||||
--vscode-editor-wordHighlightStrongBackground: rgba(14, 99, 156, 0.25);
|
||||
--vscode-editorActiveLineNumber-foreground: #0b216f;
|
||||
--vscode-editorBracketMatch-background: rgba(0, 100, 0, 0.1);
|
||||
--vscode-editorBracketMatch-border: #b9b9b9;
|
||||
--vscode-editorCodeLens-foreground: #999999;
|
||||
--vscode-editorCursor-foreground: #000000;
|
||||
--vscode-editorError-foreground: #e51400;
|
||||
--vscode-editorGroup-border: #e7e7e7;
|
||||
--vscode-editorGroup-dropBackground: rgba(38, 119, 203, 0.18);
|
||||
--vscode-editorGroupHeader-noTabsBackground: #ffffff;
|
||||
--vscode-editorGroupHeader-tabsBackground: #f3f3f3;
|
||||
--vscode-editorGutter-addedBackground: #81b88b;
|
||||
--vscode-editorGutter-background: #ffffff;
|
||||
--vscode-editorGutter-commentRangeForeground: #c5c5c5;
|
||||
--vscode-editorGutter-deletedBackground: #ca4b51;
|
||||
--vscode-editorGutter-modifiedBackground: #66afe0;
|
||||
--vscode-editorHint-foreground: #6c6c6c;
|
||||
--vscode-editorHoverWidget-background: #f3f3f3;
|
||||
--vscode-editorHoverWidget-border: #c8c8c8;
|
||||
--vscode-editorHoverWidget-statusBarBackground: #e7e7e7;
|
||||
--vscode-editorIndentGuide-activeBackground: #939393;
|
||||
--vscode-editorIndentGuide-background: #d3d3d3;
|
||||
--vscode-editorInfo-foreground: #008000;
|
||||
--vscode-editorLineNumber-activeForeground: #0b216f;
|
||||
--vscode-editorLineNumber-foreground: #237893;
|
||||
--vscode-editorLink-activeForeground: #0000ff;
|
||||
--vscode-editorMarkerNavigation-background: #ffffff;
|
||||
--vscode-editorMarkerNavigationError-background: #e51400;
|
||||
--vscode-editorMarkerNavigationInfo-background: #008000;
|
||||
--vscode-editorMarkerNavigationWarning-background: #e9a700;
|
||||
--vscode-editorOverviewRuler-addedForeground: rgba(0, 122, 204, 0.6);
|
||||
--vscode-editorOverviewRuler-border: rgba(127, 127, 127, 0.3);
|
||||
--vscode-editorOverviewRuler-bracketMatchForeground: #a0a0a0;
|
||||
--vscode-editorOverviewRuler-commonContentForeground: rgba(96, 96, 96, 0.4);
|
||||
--vscode-editorOverviewRuler-currentContentForeground: rgba(
|
||||
64,
|
||||
200,
|
||||
174,
|
||||
0.5
|
||||
);
|
||||
--vscode-editorOverviewRuler-deletedForeground: rgba(0, 122, 204, 0.6);
|
||||
--vscode-editorOverviewRuler-errorForeground: rgba(255, 18, 18, 0.7);
|
||||
--vscode-editorOverviewRuler-findMatchForeground: rgba(209, 134, 22, 0.49);
|
||||
--vscode-editorOverviewRuler-incomingContentForeground: rgba(
|
||||
64,
|
||||
166,
|
||||
255,
|
||||
0.5
|
||||
);
|
||||
--vscode-editorOverviewRuler-infoForeground: #008000;
|
||||
--vscode-editorOverviewRuler-modifiedForeground: rgba(0, 122, 204, 0.6);
|
||||
--vscode-editorOverviewRuler-rangeHighlightForeground: rgba(
|
||||
0,
|
||||
122,
|
||||
204,
|
||||
0.6
|
||||
);
|
||||
--vscode-editorOverviewRuler-selectionHighlightForeground: rgba(
|
||||
160,
|
||||
160,
|
||||
160,
|
||||
0.8
|
||||
);
|
||||
--vscode-editorOverviewRuler-warningForeground: #e9a700;
|
||||
--vscode-editorOverviewRuler-wordHighlightForeground: rgba(
|
||||
160,
|
||||
160,
|
||||
160,
|
||||
0.8
|
||||
);
|
||||
--vscode-editorOverviewRuler-wordHighlightStrongForeground: rgba(
|
||||
192,
|
||||
160,
|
||||
192,
|
||||
0.8
|
||||
);
|
||||
--vscode-editorPane-background: #ffffff;
|
||||
--vscode-editorRuler-foreground: #d3d3d3;
|
||||
--vscode-editorSuggestWidget-background: #f3f3f3;
|
||||
--vscode-editorSuggestWidget-border: #c8c8c8;
|
||||
--vscode-editorSuggestWidget-foreground: #000000;
|
||||
--vscode-editorSuggestWidget-highlightForeground: #0066bf;
|
||||
--vscode-editorSuggestWidget-selectedBackground: #d6ebff;
|
||||
--vscode-editorUnnecessaryCode-opacity: rgba(0, 0, 0, 0.47);
|
||||
--vscode-editorWarning-foreground: #e9a700;
|
||||
--vscode-editorWhitespace-foreground: rgba(51, 51, 51, 0.2);
|
||||
--vscode-editorWidget-background: #f3f3f3;
|
||||
--vscode-editorWidget-border: #c8c8c8;
|
||||
--vscode-errorForeground: #a1260d;
|
||||
--vscode-extensionBadge-remoteBackground: #007acc;
|
||||
--vscode-extensionBadge-remoteForeground: #ffffff;
|
||||
--vscode-extensionButton-prominentBackground: #327e36;
|
||||
--vscode-extensionButton-prominentForeground: #ffffff;
|
||||
--vscode-extensionButton-prominentHoverBackground: #28632b;
|
||||
--vscode-focusBorder: rgba(0, 122, 204, 0.4);
|
||||
--vscode-font-family: -apple-system, BlinkMacSystemFont, "Segoe WPC",
|
||||
"Segoe UI", "Ubuntu", "Droid Sans", ans-serif;
|
||||
--vscode-font-size: 13px;
|
||||
--vscode-font-weight: normal;
|
||||
--vscode-foreground: #616161;
|
||||
--vscode-gitDecoration-addedResourceForeground: #587c0c;
|
||||
--vscode-gitDecoration-conflictingResourceForeground: #6c6cc4;
|
||||
--vscode-gitDecoration-deletedResourceForeground: #ad0707;
|
||||
--vscode-gitDecoration-ignoredResourceForeground: #8e8e90;
|
||||
--vscode-gitDecoration-modifiedResourceForeground: #895503;
|
||||
--vscode-gitDecoration-submoduleResourceForeground: #1258a7;
|
||||
--vscode-gitDecoration-untrackedResourceForeground: #007100;
|
||||
--vscode-gitlens-gutterBackgroundColor: rgba(0, 0, 0, 0.05);
|
||||
--vscode-gitlens-gutterForegroundColor: #747474;
|
||||
--vscode-gitlens-gutterUncommittedForegroundColor: rgba(0, 188, 242, 0.6);
|
||||
--vscode-gitlens-lineHighlightBackgroundColor: rgba(0, 188, 242, 0.2);
|
||||
--vscode-gitlens-lineHighlightOverviewRulerColor: rgba(0, 188, 242, 0.6);
|
||||
--vscode-gitlens-trailingLineBackgroundColor: rgba(0, 0, 0, 0);
|
||||
--vscode-gitlens-trailingLineForegroundColor: rgba(153, 153, 153, 0.35);
|
||||
--vscode-input-background: #ffffff;
|
||||
--vscode-input-foreground: #616161;
|
||||
--vscode-input-placeholderForeground: #767676;
|
||||
--vscode-inputOption-activeBorder: #007acc;
|
||||
--vscode-inputValidation-errorBackground: #f2dede;
|
||||
--vscode-inputValidation-errorBorder: #be1100;
|
||||
--vscode-inputValidation-infoBackground: #d6ecf2;
|
||||
--vscode-inputValidation-infoBorder: #007acc;
|
||||
--vscode-inputValidation-warningBackground: #f6f5d2;
|
||||
--vscode-inputValidation-warningBorder: #b89500;
|
||||
--vscode-list-activeSelectionBackground: #0074e8;
|
||||
--vscode-list-activeSelectionForeground: #ffffff;
|
||||
--vscode-list-dropBackground: #d6ebff;
|
||||
--vscode-list-errorForeground: #b01011;
|
||||
--vscode-list-focusBackground: #d6ebff;
|
||||
--vscode-list-highlightForeground: #0066bf;
|
||||
--vscode-list-hoverBackground: #e8e8e8;
|
||||
--vscode-list-inactiveSelectionBackground: #e4e6f1;
|
||||
--vscode-list-invalidItemForeground: #b89500;
|
||||
--vscode-list-warningForeground: #855f00;
|
||||
--vscode-listFilterWidget-background: #efc1ad;
|
||||
--vscode-listFilterWidget-noMatchesOutline: #be1100;
|
||||
--vscode-listFilterWidget-outline: rgba(0, 0, 0, 0);
|
||||
--vscode-menu-background: #ffffff;
|
||||
--vscode-menu-foreground: #616161;
|
||||
--vscode-menu-selectionBackground: #0074e8;
|
||||
--vscode-menu-selectionForeground: #ffffff;
|
||||
--vscode-menu-separatorBackground: #888888;
|
||||
--vscode-menubar-selectionBackground: rgba(0, 0, 0, 0.1);
|
||||
--vscode-menubar-selectionForeground: #333333;
|
||||
--vscode-merge-commonContentBackground: rgba(96, 96, 96, 0.16);
|
||||
--vscode-merge-commonHeaderBackground: rgba(96, 96, 96, 0.4);
|
||||
--vscode-merge-currentContentBackground: rgba(64, 200, 174, 0.2);
|
||||
--vscode-merge-currentHeaderBackground: rgba(64, 200, 174, 0.5);
|
||||
--vscode-merge-incomingContentBackground: rgba(64, 166, 255, 0.2);
|
||||
--vscode-merge-incomingHeaderBackground: rgba(64, 166, 255, 0.5);
|
||||
--vscode-notificationCenterHeader-background: #e7e7e7;
|
||||
--vscode-notificationLink-foreground: #006ab1;
|
||||
--vscode-notifications-background: #f3f3f3;
|
||||
--vscode-notifications-border: #e7e7e7;
|
||||
--vscode-panel-background: #ffffff;
|
||||
--vscode-panel-border: rgba(128, 128, 128, 0.35);
|
||||
--vscode-panel-dropBackground: rgba(38, 119, 203, 0.18);
|
||||
--vscode-panelInput-border: #dddddd;
|
||||
--vscode-panelTitle-activeBorder: rgba(128, 128, 128, 0.35);
|
||||
--vscode-panelTitle-activeForeground: #424242;
|
||||
--vscode-panelTitle-inactiveForeground: rgba(66, 66, 66, 0.75);
|
||||
--vscode-peekView-border: #007acc;
|
||||
--vscode-peekViewEditor-background: #f2f8fc;
|
||||
--vscode-peekViewEditor-matchHighlightBackground: rgba(245, 216, 2, 0.87);
|
||||
--vscode-peekViewEditorGutter-background: #f2f8fc;
|
||||
--vscode-peekViewResult-background: #f3f3f3;
|
||||
--vscode-peekViewResult-fileForeground: #1e1e1e;
|
||||
--vscode-peekViewResult-lineForeground: #646465;
|
||||
--vscode-peekViewResult-matchHighlightBackground: rgba(234, 92, 0, 0.3);
|
||||
--vscode-peekViewResult-selectionBackground: rgba(51, 153, 255, 0.2);
|
||||
--vscode-peekViewResult-selectionForeground: #6c6c6c;
|
||||
--vscode-peekViewTitle-background: #ffffff;
|
||||
--vscode-peekViewTitleDescription-foreground: rgba(108, 108, 108, 0.7);
|
||||
--vscode-peekViewTitleLabel-foreground: #333333;
|
||||
--vscode-pickerGroup-border: #cccedb;
|
||||
--vscode-pickerGroup-foreground: #0066bf;
|
||||
--vscode-progressBar-background: #0e70c0;
|
||||
--vscode-quickInput-background: #f3f3f3;
|
||||
--vscode-scrollbar-shadow: #dddddd;
|
||||
--vscode-scrollbarSlider-activeBackground: rgba(0, 0, 0, 0.6);
|
||||
--vscode-scrollbarSlider-background: rgba(100, 100, 100, 0.4);
|
||||
--vscode-scrollbarSlider-hoverBackground: rgba(100, 100, 100, 0.7);
|
||||
--vscode-settings-checkboxBackground: #ffffff;
|
||||
--vscode-settings-checkboxBorder: #cecece;
|
||||
--vscode-settings-dropdownBackground: #ffffff;
|
||||
--vscode-settings-dropdownBorder: #cecece;
|
||||
--vscode-settings-dropdownListBorder: #c8c8c8;
|
||||
--vscode-settings-headerForeground: #444444;
|
||||
--vscode-settings-modifiedItemIndicator: #66afe0;
|
||||
--vscode-settings-numberInputBackground: #ffffff;
|
||||
--vscode-settings-numberInputBorder: #cecece;
|
||||
--vscode-settings-numberInputForeground: #616161;
|
||||
--vscode-settings-textInputBackground: #ffffff;
|
||||
--vscode-settings-textInputBorder: #cecece;
|
||||
--vscode-settings-textInputForeground: #616161;
|
||||
--vscode-sideBar-background: #f3f3f3;
|
||||
--vscode-sideBar-dropBackground: rgba(0, 0, 0, 0.1);
|
||||
--vscode-sideBarSectionHeader-background: rgba(128, 128, 128, 0.2);
|
||||
--vscode-sideBarTitle-foreground: #6f6f6f;
|
||||
--vscode-statusBar-background: #007acc;
|
||||
--vscode-statusBar-debuggingBackground: #cc6633;
|
||||
--vscode-statusBar-debuggingForeground: #ffffff;
|
||||
--vscode-statusBar-foreground: #ffffff;
|
||||
--vscode-statusBar-noFolderBackground: #68217a;
|
||||
--vscode-statusBar-noFolderForeground: #ffffff;
|
||||
--vscode-statusBarItem-activeBackground: rgba(255, 255, 255, 0.18);
|
||||
--vscode-statusBarItem-hoverBackground: rgba(255, 255, 255, 0.12);
|
||||
--vscode-statusBarItem-prominentBackground: rgba(0, 0, 0, 0.5);
|
||||
--vscode-statusBarItem-prominentForeground: #ffffff;
|
||||
--vscode-statusBarItem-prominentHoverBackground: rgba(0, 0, 0, 0.3);
|
||||
--vscode-statusBarItem-remoteBackground: #16825d;
|
||||
--vscode-statusBarItem-remoteForeground: #ffffff;
|
||||
--vscode-tab-activeBackground: #ffffff;
|
||||
--vscode-tab-activeForeground: #333333;
|
||||
--vscode-tab-activeModifiedBorder: #33aaee;
|
||||
--vscode-tab-border: #f3f3f3;
|
||||
--vscode-tab-inactiveBackground: #ececec;
|
||||
--vscode-tab-inactiveForeground: rgba(51, 51, 51, 0.7);
|
||||
--vscode-tab-inactiveModifiedBorder: rgba(51, 170, 238, 0.5);
|
||||
--vscode-tab-unfocusedActiveBackground: #ffffff;
|
||||
--vscode-tab-unfocusedActiveForeground: rgba(51, 51, 51, 0.7);
|
||||
--vscode-tab-unfocusedActiveModifiedBorder: rgba(51, 170, 238, 0.7);
|
||||
--vscode-tab-unfocusedInactiveForeground: rgba(51, 51, 51, 0.35);
|
||||
--vscode-tab-unfocusedInactiveModifiedBorder: rgba(51, 170, 238, 0.25);
|
||||
--vscode-terminal-ansiBlack: #000000;
|
||||
--vscode-terminal-ansiBlue: #0451a5;
|
||||
--vscode-terminal-ansiBrightBlack: #666666;
|
||||
--vscode-terminal-ansiBrightBlue: #0451a5;
|
||||
--vscode-terminal-ansiBrightCyan: #0598bc;
|
||||
--vscode-terminal-ansiBrightGreen: #14ce14;
|
||||
--vscode-terminal-ansiBrightMagenta: #bc05bc;
|
||||
--vscode-terminal-ansiBrightRed: #cd3131;
|
||||
--vscode-terminal-ansiBrightWhite: #a5a5a5;
|
||||
--vscode-terminal-ansiBrightYellow: #b5ba00;
|
||||
--vscode-terminal-ansiCyan: #0598bc;
|
||||
--vscode-terminal-ansiGreen: #00bc00;
|
||||
--vscode-terminal-ansiMagenta: #bc05bc;
|
||||
--vscode-terminal-ansiRed: #cd3131;
|
||||
--vscode-terminal-ansiWhite: #555555;
|
||||
--vscode-terminal-ansiYellow: #949800;
|
||||
--vscode-terminal-background: #ffffff;
|
||||
--vscode-terminal-border: rgba(128, 128, 128, 0.35);
|
||||
--vscode-terminal-foreground: #333333;
|
||||
--vscode-terminal-selectionBackground: rgba(0, 0, 0, 0.25);
|
||||
--vscode-textBlockQuote-background: rgba(127, 127, 127, 0.1);
|
||||
--vscode-textBlockQuote-border: rgba(0, 122, 204, 0.5);
|
||||
--vscode-textCodeBlock-background: rgba(220, 220, 220, 0.4);
|
||||
--vscode-textLink-activeForeground: #006ab1;
|
||||
--vscode-textLink-foreground: #006ab1;
|
||||
--vscode-textPreformat-foreground: #a31515;
|
||||
--vscode-textSeparator-foreground: rgba(0, 0, 0, 0.18);
|
||||
--vscode-titleBar-activeBackground: #dddddd;
|
||||
--vscode-titleBar-activeForeground: #333333;
|
||||
--vscode-titleBar-inactiveBackground: rgba(221, 221, 221, 0.6);
|
||||
--vscode-titleBar-inactiveForeground: rgba(51, 51, 51, 0.6);
|
||||
--vscode-tree-indentGuidesStroke: #a9a9a9;
|
||||
--vscode-widget-shadow: #a8a8a8;
|
||||
}
|
||||
Reference in New Issue
Block a user