mirror of
https://github.com/CharaChorder/DeviceManager.git
synced 2026-06-04 04:48:55 +00:00
update cv2
This commit is contained in:
@@ -24,7 +24,7 @@ export class ActionWidget extends WidgetType {
|
||||
unmount(this.component);
|
||||
}
|
||||
const element = document.createElement("span");
|
||||
element.style.paddingInline = "2px";
|
||||
//element.style.paddingInline = "2px";
|
||||
|
||||
this.component = mount(Action, {
|
||||
target: element,
|
||||
@@ -43,6 +43,10 @@ export class ActionWidget extends WidgetType {
|
||||
unmount(this.component);
|
||||
}
|
||||
}
|
||||
|
||||
override ignoreEvent() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function actionWidgets(view: EditorView) {
|
||||
@@ -51,13 +55,6 @@ function actionWidgets(view: EditorView) {
|
||||
for (const chord of view.state.field(parsedChordsField).chords) {
|
||||
if (chord.range[1] < from || chord.range[0] > to) continue;
|
||||
iterActions(chord, (action) => {
|
||||
if (
|
||||
view.state.selection.ranges.some(
|
||||
(r) => r.from <= action.range[1] && r.to > action.range[0],
|
||||
)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
if (action.info && action.explicit) {
|
||||
const deco = Decoration.replace({
|
||||
widget: new ActionWidget(action.info),
|
||||
|
||||
@@ -4,104 +4,83 @@ import {
|
||||
ViewPlugin,
|
||||
ViewUpdate,
|
||||
WidgetType,
|
||||
type DecorationSet,
|
||||
} from "@codemirror/view";
|
||||
import { syntaxTree } from "@codemirror/language";
|
||||
import type { Range } from "@codemirror/state";
|
||||
import { mount, unmount } from "svelte";
|
||||
import Action from "../components/Action.svelte";
|
||||
import type { SyntaxNodeRef } from "@lezer/common";
|
||||
import classNames from "./concatenator-button.module.scss";
|
||||
|
||||
export class DelimWidget extends WidgetType {
|
||||
component?: {};
|
||||
element?: HTMLElement;
|
||||
|
||||
constructor(readonly hasConcatenator: boolean) {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
override eq(other: DelimWidget) {
|
||||
return this.hasConcatenator == other.hasConcatenator;
|
||||
}
|
||||
|
||||
toDOM() {
|
||||
if (!this.element) {
|
||||
/*this.element = document.createElement("span");
|
||||
this.element.innerHTML =
|
||||
" ⇛" + (this.hasConcatenator ? "" : " ");
|
||||
this.element.style.scale = "1.8";
|
||||
this.element.style.color =
|
||||
"color-mix(in srgb, currentColor 50%, transparent)";
|
||||
|
||||
if (this.hasConcatenator) {
|
||||
const button = document.createElement("button");
|
||||
button.className = classNames["concatenator-button"]!;
|
||||
this.component = mount(Action, {
|
||||
target: button,
|
||||
props: { action: 574, display: "keys", inText: true, ghost: true },
|
||||
});
|
||||
this.element.appendChild(button);
|
||||
}*/
|
||||
this.element = document.createElement("div");
|
||||
this.element.style.breakAfter = "column";
|
||||
}
|
||||
return this.element;
|
||||
}
|
||||
|
||||
override ignoreEvent() {
|
||||
return false;
|
||||
}
|
||||
|
||||
override destroy() {
|
||||
if (this.component) {
|
||||
unmount(this.component);
|
||||
}
|
||||
const element = document.createElement("div");
|
||||
element.style.breakAfter = "column";
|
||||
return element;
|
||||
}
|
||||
}
|
||||
|
||||
function getJoinNode(
|
||||
view: EditorView,
|
||||
phraseDelimNode: SyntaxNodeRef,
|
||||
): SyntaxNodeRef | null | undefined {
|
||||
const firstPhraseAction = phraseDelimNode.node.nextSibling
|
||||
?.getChild("ActionString")
|
||||
?.node.firstChild?.node.getChild("ExplicitAction");
|
||||
const idNode = firstPhraseAction?.node.getChild("ActionId");
|
||||
const actionId = idNode
|
||||
? view.state.doc.sliceString(idNode.from, idNode.to)
|
||||
: null;
|
||||
const isJoinAction =
|
||||
actionId === "JOIN" &&
|
||||
!!firstPhraseAction!.node.getChild("ExplicitDelimEnd");
|
||||
return isJoinAction ? firstPhraseAction : null;
|
||||
}
|
||||
|
||||
function actionWidgets(view: EditorView) {
|
||||
const widgets: Range<Decoration>[] = [];
|
||||
function delimWidgets(view: EditorView): {
|
||||
delims: DecorationSet;
|
||||
surrounding: DecorationSet;
|
||||
} {
|
||||
const delims: Range<Decoration>[] = [];
|
||||
const surrounding: Range<Decoration>[] = [];
|
||||
for (const { from, to } of view.visibleRanges) {
|
||||
let chord: { from: number; to: number } | null = null;
|
||||
syntaxTree(view.state).iterate({
|
||||
from,
|
||||
to,
|
||||
enter: (node) => {
|
||||
if (node.name !== "PhraseDelim") return;
|
||||
const joinNode = getJoinNode(view, node);
|
||||
console.log(node.name, node.from, node.to);
|
||||
if (node.name === "Chord") {
|
||||
chord = { from: node.from, to: node.to };
|
||||
}
|
||||
if (node.name !== "PhraseDelim" || chord === null) return;
|
||||
|
||||
let deco = Decoration.replace({
|
||||
widget: new DelimWidget(!joinNode),
|
||||
});
|
||||
widgets.push(deco.range(node.from, node.to));
|
||||
delims.push(
|
||||
Decoration.mark({
|
||||
class: "chord-delim",
|
||||
}).range(node.from, node.to),
|
||||
);
|
||||
|
||||
if (chord.from < node.from) {
|
||||
surrounding.push(
|
||||
Decoration.mark({
|
||||
tagName: "div",
|
||||
class: "chord-input",
|
||||
}).range(chord.from, node.from),
|
||||
);
|
||||
}
|
||||
if (chord.to > node.to) {
|
||||
surrounding.push(
|
||||
Decoration.mark({
|
||||
tagName: "div",
|
||||
class: "chord-phrase",
|
||||
}).range(node.to, chord.to),
|
||||
);
|
||||
}
|
||||
chord = null;
|
||||
},
|
||||
});
|
||||
}
|
||||
return Decoration.set(widgets);
|
||||
return {
|
||||
delims: Decoration.set(delims),
|
||||
surrounding: Decoration.set([...surrounding, ...delims], true),
|
||||
};
|
||||
}
|
||||
|
||||
export const delimPlugin = ViewPlugin.fromClass(
|
||||
class {
|
||||
decorations = Decoration.none;
|
||||
delims = Decoration.none;
|
||||
surrounding = Decoration.none;
|
||||
|
||||
constructor(view: EditorView) {
|
||||
this.decorations = actionWidgets(view);
|
||||
const { delims, surrounding } = delimWidgets(view);
|
||||
this.delims = delims;
|
||||
this.surrounding = surrounding;
|
||||
}
|
||||
|
||||
update(update: ViewUpdate) {
|
||||
@@ -109,51 +88,21 @@ export const delimPlugin = ViewPlugin.fromClass(
|
||||
update.docChanged ||
|
||||
update.viewportChanged ||
|
||||
syntaxTree(update.startState) != syntaxTree(update.state)
|
||||
)
|
||||
this.decorations = actionWidgets(update.view);
|
||||
) {
|
||||
const { delims, surrounding } = delimWidgets(update.view);
|
||||
this.delims = delims;
|
||||
this.surrounding = surrounding;
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
decorations(instance) {
|
||||
return instance.decorations;
|
||||
return instance.delims;
|
||||
},
|
||||
provide(plugin) {
|
||||
return EditorView.atomicRanges.of(
|
||||
(view) => view.plugin(plugin)?.decorations ?? Decoration.none,
|
||||
(view) => view.plugin(plugin)?.delims ?? Decoration.none,
|
||||
);
|
||||
},
|
||||
eventHandlers: {
|
||||
click: (event, view) => {
|
||||
if (!(event.target instanceof HTMLElement)) return;
|
||||
if (
|
||||
!(
|
||||
event.target instanceof HTMLButtonElement ||
|
||||
(event.target as HTMLElement).parentElement instanceof
|
||||
HTMLButtonElement
|
||||
)
|
||||
)
|
||||
return;
|
||||
|
||||
const chordNode = syntaxTree(view.state).resolve(
|
||||
view.posAtDOM(event.target),
|
||||
);
|
||||
const delimNode = (
|
||||
chordNode.name === "ActionString"
|
||||
? chordNode.parent?.parent
|
||||
: chordNode
|
||||
)?.getChild("PhraseDelim");
|
||||
if (!delimNode) return;
|
||||
const joinNode = getJoinNode(view, delimNode);
|
||||
if (!event.target.checked && !joinNode) {
|
||||
view.dispatch({
|
||||
changes: {
|
||||
from: delimNode.to,
|
||||
insert: "<JOIN>",
|
||||
},
|
||||
selection: { anchor: delimNode.to + "<JOIN>".length },
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
@@ -51,10 +51,9 @@ export function createConfig(params: EditorConfig) {
|
||||
actionHover,
|
||||
changesPanel(),
|
||||
lintGutter(),
|
||||
params.rawCode ? [lineNumbers()] : [delimPlugin, actionPlugin],
|
||||
params.rawCode ? [lineNumbers()] : [/*delimPlugin,*/ actionPlugin],
|
||||
chordLanguageSupport(),
|
||||
actionLinter({
|
||||
delay: 100,
|
||||
markerFilter(diagnostics) {
|
||||
return diagnostics.filter((it) => it.from !== it.to);
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user