Refactoring, various fixes
0
font/roboto-bold.woff → assets/fonts/roboto-bold.woff
Executable file → Normal file
0
font/roboto-bold.woff2 → assets/fonts/roboto-bold.woff2
Executable file → Normal file
0
font/roboto-light.woff → assets/fonts/roboto-light.woff
Executable file → Normal file
0
font/roboto-light.woff2 → assets/fonts/roboto-light.woff2
Executable file → Normal file
0
font/roboto-regular.woff → assets/fonts/roboto-regular.woff
Executable file → Normal file
0
font/roboto-regular.woff2 → assets/fonts/roboto-regular.woff2
Executable file → Normal file
BIN
assets/icons/alignment/icon_AlignNodesBottom_20px.png
Normal file
|
After Width: | Height: | Size: 240 B |
BIN
assets/icons/alignment/icon_AlignNodesCenter_20px.png
Normal file
|
After Width: | Height: | Size: 227 B |
BIN
assets/icons/alignment/icon_AlignNodesLeft_20px.png
Normal file
|
After Width: | Height: | Size: 232 B |
BIN
assets/icons/alignment/icon_AlignNodesMiddle_20px.png
Normal file
|
After Width: | Height: | Size: 253 B |
BIN
assets/icons/alignment/icon_AlignNodesRight_20px.png
Normal file
|
After Width: | Height: | Size: 230 B |
BIN
assets/icons/alignment/icon_AlignNodesTop_20px.png
Normal file
|
After Width: | Height: | Size: 240 B |
BIN
assets/icons/alignment/icon_DistributeNodesHorizontally_20px.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
assets/icons/alignment/icon_DistributeNodesVertically_20px.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
assets/icons/alignment/icon_StraightenConnections_20px.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
@@ -1 +1 @@
|
||||
.ueb{--ueb-pin-color: white;--ueb-pin-dim-color: #afafaf}.ueb-pin-boolean{--ueb-pin-color: #930000}.ueb-pin-int{--ueb-pin-color: #1fe0ad}.ueb-pin-float{--ueb-pin-color: #9ffb44}.ueb-pin-vector{--ueb-pin-color: #fcc823}.ueb-pin-rotator{--ueb-pin-color: #9eb1fc}.ueb-pin-string{--ueb-pin-color: #fc00d2;--ueb-pin-background: linear-gradient(90deg, #fc00d220, #fc00d280 15%, #fc00d250 85%, transparent)}.ueb-pin-name{--ueb-pin-color: #cb81fc}.ueb-pin-object{--ueb-pin-color: #00a8f2}/*# sourceMappingURL=ueblueprint-node-value-type-color.css.map */
|
||||
.ueb{--ueb-pin-color: white;--ueb-pin-dim-color: #afafaf}.ueb-pin-boolean{--ueb-pin-color: #4d0000}.ueb-pin-class{--ueb-pin-color: #5800bb}.ueb-pin-float{--ueb-pin-color: #9ffb44}.ueb-pin-int{--ueb-pin-color: #1fe0ad}.ueb-pin-name{--ueb-pin-color: #cb81fc}.ueb-pin-object{--ueb-pin-color: #006603}.ueb-pin-rotator{--ueb-pin-color: #9eb1fc}.ueb-pin-string{--ueb-pin-color: #fc00d2;--ueb-pin-background: linear-gradient(90deg, #fc00d220, #fc00d280 15%, #fc00d250 85%, transparent)}.ueb-pin-vector{--ueb-pin-color: #fcc823}/*# sourceMappingURL=ueblueprint-node-value-type-color.css.map */
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"sourceRoot":"","sources":["../../scss/ueblueprint-node-value-type-color.scss"],"names":[],"mappings":"AAAA,KAGI,uBACA,6BAGJ,iBAEI,yBAGJ,aAEI,yBAGJ,eAEI,yBAGJ,gBAEI,yBAGJ,iBAEI,yBAGJ,gBAEI,yBACA,mGAGJ,cAEI,yBAGJ,gBAEI","file":"ueblueprint-node-value-type-color.css"}
|
||||
{"version":3,"sourceRoot":"","sources":["../../scss/ueblueprint-node-value-type-color.scss"],"names":[],"mappings":"AAAA,KAGI,uBACA,6BAGJ,iBAEI,yBAGJ,eAEI,yBAGJ,eAEI,yBAGJ,aAEI,yBAGJ,cAEI,yBAGJ,gBAGI,yBAGJ,iBAEI,yBAGJ,gBAEI,yBACA,mGAGJ,gBAEI","file":"ueblueprint-node-value-type-color.css"}
|
||||
2
dist/css/ueblueprint-style.css
vendored
2
dist/css/ueblueprint-style.css.map
vendored
@@ -1 +1 @@
|
||||
{"version":3,"sourceRoot":"","sources":["../../scss/ueblueprint-style.scss"],"names":[],"mappings":"AAAA,WACI,qBACA,iBACA,IACI,kGAIR,WACI,qBACA,mBACA,IACI,sGAIR,cACI,cACA,kBACA,8EACA,+BACA,iBAGJ,qBACI,aACA,kBACA,MACA,QACA,OACA,aACA,0BACA,UAGJ,mBACI,gBAGJ,mBACI,kBACA,aACA,gBACA,qBAGJ,oDACI,gBAGJ,UACI,kFACA,kBACA,eACA,gBACA,kEACA,mEACA,yBACA,iBAEI,s3BA0BJ,gBAEI,sZAQJ,sFACA,gEACA,oDACA,qBACA,gBAGJ,kDACI,gBAGJ,mDACI,eAGJ,qBAGI,eACA,6CAGJ,iBAEI,mBAGJ,iBAEI,kBAGJ,iBAEI,mBAGJ,iBAEI,iBACA,uDAGJ,iBAEI,mBACA,uDAGJ,iBACI,sBACA,uDAGJ,iBACI,iBACA,uDAGJ,iBACI,sBACA,uDAGJ,iBACI,sBACA,uDAGJ,kBAEI,iBACA,uDAGJ,kBAEI,sBACA,uDAGJ,kBAEI,sBACA,uDAGJ,kBACI,kBACA,QACA,SACA,wGAGJ,SACI,cACA,kBACA,sGACA,qCACA,uDACA,sBAGJ,wEACI,YAGJ,iBACI,YACA,YACA,+CAGJ,+BACI,iBACI,kNAIJ,oDACA,0CACA,sDACA,0BACA,oBAGJ,kBACI,kBACA,YACA,gCACA,qCACA,0BACA,gBAGJ,iBACI,kBACA,6DACA,gEACA,8EACA,aACA,gBACA,mBAGJ,eACI,iFACA,qBACA,mBAGJ,eACI,aACA,cACA,WACA,gBACA,mBAGJ,iBACI,kBACA,iBAGJ,kBACI,kBAGJ,QACI,cACA,gBAGJ,wEACI,aAGJ,6EACI,qCACA,iBAGJ,0BACI,iBAGJ,cACI,qBACA,kBACA,YACA,aACA,wBACA,wBAGJ,sBACI,WACA,cACA,kBACA,MACA,QACA,SACA,OACA,sCACA,kBAGJ,2CACI,gCAGJ,qBACI,WACA,cACA,kBACA,qBACA,sBACA,QACA,SACA,kCACA,qCACA,4CAGJ,gEACI,8DACA,8DACA,8DACA,8DACA,oGACA,qGACA,kBACA,wCACA,yCACA,0CACA,4CAGJ,aACI,cACA,kBACA,kBACA,MACA,OACA,QACA,SACA,iBAEI,wlDAmDJ,gBAEI,gQAWJ,oBAEI,wJAOJ,4BAGJ,gDACI,mBAIJ,eACI,mBAGJ,SACI,kEAEA,uEACA,cACA,8CAKA,kBAGJ,aACI,iEACA,kBACA,MACA,OACA,WACA,YACA,eACA,8FACA,iBAGJ,kBACI,mBACA,4BACA,eAGJ,8DAEI,eACA,4BAGJ,iBACI,cACA,mBACA,kBACA,kDACA,qHAOA,sBACA,gBACA,kBACA,4EACA,+BACA,mBACA","file":"ueblueprint-style.css"}
|
||||
{"version":3,"sourceRoot":"","sources":["../../scss/ueblueprint-style.scss"],"names":[],"mappings":"AAAA,WACI,qBACA,iBACA,IACI,kGAIR,WACI,qBACA,mBACA,IACI,sGAIR,cACI,cACA,kBACA,8EACA,+BACA,iBAGJ,qBACI,aACA,kBACA,MACA,QACA,OACA,aACA,0BACA,UAGJ,mBACI,gBAGJ,mBACI,kBACA,aACA,gBACA,qBAGJ,oDACI,gBAGJ,UACI,kFACA,kBACA,eACA,gBACA,kEACA,mEACA,yBACA,iBAEI,s3BA0BJ,gBAEI,sZAQJ,sFACA,gEACA,oDACA,qBACA,gBAGJ,kDACI,gBAGJ,mDACI,eAGJ,qBAGI,eACA,6CAGJ,iBAEI,mBAGJ,iBAEI,kBAGJ,iBAEI,mBAGJ,iBAEI,iBACA,uDAGJ,iBAEI,mBACA,uDAGJ,iBACI,sBACA,uDAGJ,iBACI,iBACA,uDAGJ,iBACI,sBACA,uDAGJ,iBACI,sBACA,uDAGJ,kBAEI,iBACA,uDAGJ,kBAEI,sBACA,uDAGJ,kBAEI,sBACA,uDAGJ,kBACI,kBACA,QACA,SACA,wGAGJ,SACI,cACA,kBACA,sGACA,qCACA,uDACA,sBAGJ,wEACI,YAGJ,iBACI,YACA,YACA,+CAGJ,+BACI,iBACI,kNAIJ,oDACA,0CACA,sDACA,0BACA,oBAGJ,kBACI,kBACA,YACA,gCACA,qCACA,0BACA,gBAGJ,iBACI,kBACA,6DACA,gEACA,8EACA,aACA,gBACA,mBAGJ,eACI,iFACA,qBACA,mBAGJ,eACI,aACA,cACA,WACA,gBACA,mBAGJ,iBACI,kBACA,iBAGJ,kBACI,kBAGJ,iBACI,aAGJ,iDACI,cAGJ,QACI,cACA,gBAGJ,wEACI,aAGJ,6EACI,qCACA,iBAGJ,0BACI,iBAGJ,cACI,qBACA,kBACA,YACA,aACA,wBACA,wBAGJ,sBACI,WACA,cACA,kBACA,MACA,QACA,SACA,OACA,sCACA,kBAGJ,2CACI,gCAGJ,qBACI,WACA,cACA,kBACA,qBACA,sBACA,QACA,SACA,kCACA,qCACA,4CAGJ,gEACI,8DACA,8DACA,8DACA,8DACA,oGACA,qGACA,kBACA,wCACA,yCACA,0CACA,4CAGJ,aACI,cACA,kBACA,kBACA,MACA,OACA,QACA,SACA,iBAEI,wlDAmDJ,gBAEI,gQAWJ,oBAEI,wJAOJ,4BAGJ,gDACI,mBAIJ,eACI,mBAGJ,SACI,kEAEA,uEACA,cACA,8CAKA,kBAGJ,aACI,iEACA,kBACA,MACA,OACA,WACA,YACA,eACA,8FACA,iBAGJ,kBACI,mBACA,4BACA,eAGJ,8DAEI,eACA,4BAGJ,iBACI,cACA,mBACA,kBACA,kDACA,qHAOA,sBACA,gBACA,kBACA,4EACA,+BACA,mBACA","file":"ueblueprint-style.css"}
|
||||
823
dist/ueblueprint.js
vendored
@@ -3,6 +3,7 @@ import Configuration from "./Configuration"
|
||||
import Copy from "./input/common/Copy"
|
||||
import IElement from "./element/IElement"
|
||||
import KeyboardCanc from "./input/keybaord/KeyboardCanc"
|
||||
import KeyboardEnableZoom from "./input/keybaord/KeyboardEnableZoom"
|
||||
import KeyboardSelectAll from "./input/keybaord/KeyboardSelectAll"
|
||||
import LinkElement from "./element/LinkElement"
|
||||
import MouseScrollGraph from "./input/mouse/MouseScrollGraph"
|
||||
@@ -121,7 +122,8 @@ export default class Blueprint extends IElement {
|
||||
moveEverywhere: true,
|
||||
}),
|
||||
new Unfocus(this.getGridDOMElement(), this),
|
||||
new MouseTracking(this.getGridDOMElement(), this)
|
||||
new MouseTracking(this.getGridDOMElement(), this),
|
||||
new KeyboardEnableZoom(this.getGridDOMElement(), this),
|
||||
]
|
||||
}
|
||||
|
||||
@@ -257,7 +259,7 @@ export default class Blueprint extends IElement {
|
||||
}
|
||||
|
||||
setZoom(zoom, center) {
|
||||
zoom = Utility.clamp(zoom, -12, 0)
|
||||
zoom = Utility.clamp(zoom, Configuration.minZoom, Configuration.maxZoom)
|
||||
if (zoom == this.zoom) {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
export default class Configuration {
|
||||
static deleteNodesKeyboardKey = "Delete"
|
||||
static enableZoomIn = ["LeftControl", "RightControl"] // Button to enable more than 0 (1:1) zoom
|
||||
static expandGridSize = 400
|
||||
static fontSize = "13px"
|
||||
static gridAxisLineColor = "black"
|
||||
@@ -22,11 +23,13 @@ export default class Configuration {
|
||||
let end = 100 - start
|
||||
return `M ${start} 0 C ${c1} 0, ${c2} 0, 50 50 S ${end - c1 + start} 100, ${end} 100`
|
||||
}
|
||||
static maxZoom = 7
|
||||
static minZoom = -12
|
||||
static nodeDeleteEventName = "ueb-node-delete"
|
||||
static nodeDragEventName = "ueb-node-drag"
|
||||
static nodeDragLocalEventName = "ueb-node-drag-local"
|
||||
static nodeRadius = 8 // in pixel
|
||||
static selectAllKeyboardKey = "Ctrl+A"
|
||||
static selectAllKeyboardKey = "(bCtrl=True,Key=A)"
|
||||
static trackingMouseEventName = {
|
||||
begin: "ueb-tracking-mouse-begin",
|
||||
end: "ueb-tracking-mouse-end"
|
||||
@@ -41,6 +44,12 @@ export default class Configuration {
|
||||
/* UE name: JS name */
|
||||
"Backspace": "Backspace",
|
||||
"Tab": "Tab",
|
||||
"LeftControl": "ControlLeft",
|
||||
"RightControl": "ControlRight",
|
||||
"LeftShift": "ShiftLeft",
|
||||
"RightShift": "ShiftRight",
|
||||
"LeftAlt": "AltLeft",
|
||||
"RightAlt": "AltRight",
|
||||
"Enter": "Enter",
|
||||
"Pause": "Pause",
|
||||
"CapsLock": "CapsLock",
|
||||
@@ -50,23 +59,23 @@ export default class Configuration {
|
||||
"PageDown": "PageDown",
|
||||
"End": "End",
|
||||
"Home": "Home",
|
||||
"ArrowLeft": "ArrowLeft",
|
||||
"ArrowUp": "ArrowUp",
|
||||
"ArrowRight": "ArrowRight",
|
||||
"ArrowDown": "ArrowDown",
|
||||
"ArrowLeft": "Left",
|
||||
"ArrowUp": "Up",
|
||||
"ArrowRight": "Right",
|
||||
"ArrowDown": "Down",
|
||||
"PrintScreen": "PrintScreen",
|
||||
"Insert": "Insert",
|
||||
"Delete": "Delete",
|
||||
"Digit0": "Digit0",
|
||||
"Digit1": "Digit1",
|
||||
"Digit2": "Digit2",
|
||||
"Digit3": "Digit3",
|
||||
"Digit4": "Digit4",
|
||||
"Digit5": "Digit5",
|
||||
"Digit6": "Digit6",
|
||||
"Digit7": "Digit7",
|
||||
"Digit8": "Digit8",
|
||||
"Digit9": "Digit9",
|
||||
"Zero": "Digit0",
|
||||
"One": "Digit1",
|
||||
"Two": "Digit2",
|
||||
"Three": "Digit3",
|
||||
"Four": "Digit4",
|
||||
"Five": "Digit5",
|
||||
"Six": "Digit6",
|
||||
"Seven": "Digit7",
|
||||
"Eight": "Digit8",
|
||||
"Nine": "Digit9",
|
||||
"A": "KeyA",
|
||||
"B": "KeyB",
|
||||
"C": "KeyC",
|
||||
@@ -92,21 +101,21 @@ export default class Configuration {
|
||||
"X": "KeyX",
|
||||
"Y": "KeyY",
|
||||
"Z": "KeyZ",
|
||||
"Numpad0": "Numpad0",
|
||||
"Numpad1": "Numpad1",
|
||||
"Numpad2": "Numpad2",
|
||||
"Numpad3": "Numpad3",
|
||||
"Numpad4": "Numpad4",
|
||||
"Numpad5": "Numpad5",
|
||||
"Numpad6": "Numpad6",
|
||||
"Numpad7": "Numpad7",
|
||||
"Numpad8": "Numpad8",
|
||||
"Numpad9": "Numpad9",
|
||||
"NumpadMultiply": "NumpadMultiply",
|
||||
"NumpadAdd": "NumpadAdd",
|
||||
"NumpadSubtract": "NumpadSubtract",
|
||||
"NumpadDecimal": "NumpadDecimal",
|
||||
"NumpadDivide": "NumpadDivide",
|
||||
"NumPadZero": "Numpad0",
|
||||
"NumPadOne": "Numpad1",
|
||||
"NumPadTwo": "Numpad2",
|
||||
"NumPadThree": "Numpad3",
|
||||
"NumPadFour": "Numpad4",
|
||||
"NumPadFive": "Numpad5",
|
||||
"NumPadSix": "Numpad6",
|
||||
"NumPadSeven": "Numpad7",
|
||||
"NumPadEight": "Numpad8",
|
||||
"NumPadNine": "Numpad9",
|
||||
"Multiply": "NumpadMultiply",
|
||||
"Add": "NumpadAdd",
|
||||
"Subtract": "NumpadSubtract",
|
||||
"Decimal": "NumpadDecimal",
|
||||
"Divide": "NumpadDivide",
|
||||
"F1": "F1",
|
||||
"F2": "F2",
|
||||
"F3": "F3",
|
||||
|
||||
@@ -9,19 +9,27 @@ export default class IElement extends HTMLElement {
|
||||
|
||||
static tagName = ""
|
||||
|
||||
/** @type {Blueprint} */
|
||||
blueprint
|
||||
|
||||
/** @type {IEntity} */
|
||||
entity
|
||||
|
||||
/** @type {ITemplate} */
|
||||
template
|
||||
|
||||
/** @type {IContext[]} */
|
||||
inputObjects = []
|
||||
|
||||
/**
|
||||
* @param {IEntity} entity The entity containing blueprint related data for this graph element
|
||||
* @param {ITemplate} template The template to render this node
|
||||
*/
|
||||
constructor(entity, template) {
|
||||
super()
|
||||
/** @type {Blueprint} */
|
||||
this.blueprint = null
|
||||
/** @type {IEntity} */
|
||||
this.entity = entity
|
||||
/** @type {ITemplate} */
|
||||
this.template = template
|
||||
/** @type {IContext[]} */
|
||||
this.inputObjects = []
|
||||
}
|
||||
|
||||
@@ -39,14 +47,22 @@ export default class IElement extends HTMLElement {
|
||||
this.inputObjects.forEach(v => v.unlistenDOMElement())
|
||||
}
|
||||
|
||||
createInputObjects() {
|
||||
return []
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {IElement} element
|
||||
*/
|
||||
/** @param {IElement} element */
|
||||
isSameGraph(element) {
|
||||
return this.blueprint && this.blueprint == element?.blueprint
|
||||
}
|
||||
|
||||
/**
|
||||
* @template {} T
|
||||
* @param {new () => T} type
|
||||
* @returns {T}
|
||||
*/
|
||||
getInputObject(type) {
|
||||
return this.inputObjects.find(object => object.constructor == type)
|
||||
}
|
||||
|
||||
// Subclasses will want to override
|
||||
createInputObjects() {
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ export default class IEntity {
|
||||
* - A proper value.
|
||||
*/
|
||||
const value = Utility.objectGet(options, fullKey)
|
||||
if (value !== null) {
|
||||
if (value !== undefined) {
|
||||
target[property] = value
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import IEntity from "./IEntity"
|
||||
|
||||
|
||||
export default class Identifier extends IEntity {
|
||||
export default class IdentifierEntity extends IEntity {
|
||||
|
||||
static attributes = {
|
||||
value: String,
|
||||
@@ -15,11 +15,6 @@ export default class Identifier extends IEntity {
|
||||
}
|
||||
}
|
||||
super(options)
|
||||
/** @type {String} */
|
||||
this.value
|
||||
if (!this.value.match(/\w+/)) {
|
||||
throw new Error("The value must be an identifier (/\w+/).")
|
||||
}
|
||||
}
|
||||
|
||||
valueOf() {
|
||||
@@ -1,12 +1,17 @@
|
||||
import IdentifierEntity from "./IdentifierEntity"
|
||||
import IEntity from "./IEntity"
|
||||
|
||||
export default class KeyBindingEntity extends IEntity {
|
||||
|
||||
static attributes = {
|
||||
bCtrlDown: false,
|
||||
bAltDown: false,
|
||||
bShiftDown: false,
|
||||
Key: String,
|
||||
CommandName: String,
|
||||
ActionName: "",
|
||||
bShift: false,
|
||||
bCtrl: false,
|
||||
bAlt: false,
|
||||
bCmd: false,
|
||||
Key: IdentifierEntity,
|
||||
}
|
||||
constructor(options = {}) {
|
||||
super(options)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import FunctionReferenceEntity from "./FunctionReferenceEntity"
|
||||
import GuidEntity from "./GuidEntity"
|
||||
import Identifier from "./Identifier"
|
||||
import IdentifierEntity from "./IdentifierEntity"
|
||||
import IEntity from "./IEntity"
|
||||
import IntegerEntity from "./IntegerEntity"
|
||||
import ObjectReferenceEntity from "./ObjectReferenceEntity"
|
||||
@@ -20,7 +20,7 @@ export default class ObjectEntity extends IEntity {
|
||||
TargetType: new TypeInitialization(ObjectReferenceEntity, false, null),
|
||||
NodePosX: IntegerEntity,
|
||||
NodePosY: IntegerEntity,
|
||||
AdvancedPinDisplay: new TypeInitialization(Identifier, false, null),
|
||||
AdvancedPinDisplay: new TypeInitialization(IdentifierEntity, false, null),
|
||||
NodeGuid: GuidEntity,
|
||||
ErrorType: new TypeInitialization(IntegerEntity, false),
|
||||
ErrorMsg: new TypeInitialization(String, false, ""),
|
||||
|
||||
@@ -72,16 +72,14 @@ export default class PinEntity extends IEntity {
|
||||
linkTo(targetObjectName, targetPinEntity) {
|
||||
/** @type {PinReferenceEntity[]} */
|
||||
this.LinkedTo
|
||||
const linkFound = this.LinkedTo.find(
|
||||
/** @type {PinReferenceEntity} */
|
||||
pinReferenceEntity => {
|
||||
return pinReferenceEntity.objectName == targetObjectName
|
||||
&& pinReferenceEntity.pinGuid.valueOf() == targetPinEntity.PinId.valueOf()
|
||||
})
|
||||
const linkFound = this.LinkedTo?.find(pinReferenceEntity => {
|
||||
return pinReferenceEntity.objectName == targetObjectName
|
||||
&& pinReferenceEntity.pinGuid.valueOf() == targetPinEntity.PinId.valueOf()
|
||||
})
|
||||
if (!linkFound) {
|
||||
this.LinkedTo.push(new PinReferenceEntity({
|
||||
(this.LinkedTo ?? (this.LinkedTo = [])).push(new PinReferenceEntity({
|
||||
objectName: targetObjectName,
|
||||
pinGuid: targetPinEntity.PinId
|
||||
pinGuid: targetPinEntity.PinId,
|
||||
}))
|
||||
return true
|
||||
}
|
||||
@@ -95,14 +93,16 @@ export default class PinEntity extends IEntity {
|
||||
unlinkFrom(targetObjectName, targetPinEntity) {
|
||||
/** @type {PinReferenceEntity[]} */
|
||||
this.LinkedTo
|
||||
const indexElement = this.LinkedTo.findIndex(
|
||||
/** @type {PinReferenceEntity} */
|
||||
pinReferenceEntity => {
|
||||
return pinReferenceEntity.objectName == targetObjectName
|
||||
&& pinReferenceEntity.pinGuid == targetPinEntity.PinId
|
||||
})
|
||||
const indexElement = this.LinkedTo.findIndex(pinReferenceEntity => {
|
||||
return pinReferenceEntity.objectName == targetObjectName
|
||||
&& pinReferenceEntity.pinGuid == targetPinEntity.PinId
|
||||
})
|
||||
if (indexElement >= 0) {
|
||||
this.LinkedTo.splice(indexElement, 1)
|
||||
if (this.LinkedTo.length == 1) {
|
||||
this.LinkedTo = undefined
|
||||
} else {
|
||||
this.LinkedTo.splice(indexElement, 1)
|
||||
}
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
||||
@@ -1,14 +1,36 @@
|
||||
export default class IContext {
|
||||
|
||||
/** @type {HTMLElement} */
|
||||
target
|
||||
|
||||
/** @type {import("../Blueprint").default}" */
|
||||
blueprint
|
||||
|
||||
/** @type {Object} */
|
||||
options
|
||||
|
||||
#hasFocus = false
|
||||
|
||||
get hasFocus() {
|
||||
return this.#hasFocus
|
||||
}
|
||||
|
||||
set hasFocus(_) {
|
||||
}
|
||||
|
||||
constructor(target, blueprint, options) {
|
||||
/** @type {HTMLElement} */
|
||||
this.target = target
|
||||
/** @type {import("../Blueprint").default}" */
|
||||
this.blueprint = blueprint
|
||||
this.options = options
|
||||
let self = this
|
||||
this.blueprintFocusHandler = _ => self.listenEvents()
|
||||
this.blueprintUnfocusHandler = _ => self.unlistenEvents()
|
||||
this.blueprintFocusHandler = _ => {
|
||||
this.#hasFocus = true
|
||||
self.listenEvents()
|
||||
}
|
||||
this.blueprintUnfocusHandler = _ => {
|
||||
self.unlistenEvents()
|
||||
this.#hasFocus = false
|
||||
}
|
||||
if (options?.wantsFocusCallback ?? false) {
|
||||
this.blueprint.addEventListener("blueprint-focus", this.blueprintFocusHandler)
|
||||
this.blueprint.addEventListener("blueprint-unfocus", this.blueprintUnfocusHandler)
|
||||
|
||||
@@ -1,76 +1,71 @@
|
||||
import Configuration from "../../Configuration"
|
||||
import IContext from "../IContext"
|
||||
import Parsimmon from "parsimmon"
|
||||
|
||||
let P = Parsimmon
|
||||
|
||||
class KeyGrammar {
|
||||
|
||||
// Creates a grammar where each alternative is the string from ModifierKey mapped to a number for bit or use
|
||||
ModifierKey = r => P.alt(...Configuration.ModifierKeys.map((v, i) => P.string(v).map(_ => 1 << i)))
|
||||
Key = r => P.alt(...Object.keys(Configuration.Keys).map(v => P.string(v))).map(v => Configuration.Keys[v])
|
||||
KeyboardShortcut = r => P.alt(
|
||||
P.seqMap(
|
||||
P.seqMap(r.ModifierKey, P.optWhitespace, P.string(Configuration.keysSeparator), (v, _, __) => v)
|
||||
.atLeast(1)
|
||||
.map(v => v.reduce((acc, cur) => acc | cur)),
|
||||
P.optWhitespace,
|
||||
r.Key,
|
||||
(modifierKeysFlag, _, key) => ({
|
||||
key: key,
|
||||
ctrlKey: Boolean(modifierKeysFlag & (1 << Configuration.ModifierKeys.indexOf("Ctrl"))),
|
||||
shiftKey: Boolean(modifierKeysFlag & (1 << Configuration.ModifierKeys.indexOf("Shift"))),
|
||||
altKey: Boolean(modifierKeysFlag & (1 << Configuration.ModifierKeys.indexOf("Alt"))),
|
||||
metaKey: Boolean(modifierKeysFlag & (1 << Configuration.ModifierKeys.indexOf("Meta")))
|
||||
})
|
||||
),
|
||||
r.Key.map(v => ({ key: v }))
|
||||
)
|
||||
.trim(P.optWhitespace)
|
||||
}
|
||||
|
||||
import ISerializer from "../../serialization/ISerializer"
|
||||
import KeyBindingEntity from "../../entity/KeyBindingEntity"
|
||||
export default class IKeyboardShortcut extends IContext {
|
||||
|
||||
static keyGrammar = P.createLanguage(new KeyGrammar())
|
||||
/** @type {KeyBindingEntity} */
|
||||
#activationKeys
|
||||
|
||||
constructor(target, blueprint, options = {}) {
|
||||
options.wantsFocusCallback = true
|
||||
options.activationKeys ??= []
|
||||
if (!(options.activationKeys instanceof Array)) {
|
||||
options.activationKeys = [options.activationKeys]
|
||||
}
|
||||
options.activationKeys = options.activationKeys.map(v => {
|
||||
if (v instanceof KeyBindingEntity) {
|
||||
return v
|
||||
}
|
||||
if (v.constructor === String) {
|
||||
const parsed = ISerializer.grammar.KeyBinding.parse(v)
|
||||
if (parsed.status) {
|
||||
return parsed.value
|
||||
}
|
||||
}
|
||||
throw new Error("Unexpected key value")
|
||||
})
|
||||
|
||||
super(target, blueprint, options)
|
||||
|
||||
/** @type {String[]} */
|
||||
this.key = this.options.key
|
||||
this.ctrlKey = options.ctrlKey ?? false
|
||||
this.shiftKey = options.shiftKey ?? false
|
||||
this.altKey = options.altKey ?? false
|
||||
this.metaKey = options.metaKey ?? false
|
||||
this.#activationKeys = this.options.activationKeys ?? []
|
||||
|
||||
let self = this
|
||||
/** @param {KeyboardEvent} e */
|
||||
this.keyDownHandler = e => {
|
||||
if (
|
||||
e.code == self.key
|
||||
&& e.ctrlKey === self.ctrlKey
|
||||
&& e.shiftKey === self.shiftKey
|
||||
&& e.altKey === self.altKey
|
||||
&& e.metaKey === self.metaKey
|
||||
) {
|
||||
self.fire()
|
||||
self.#activationKeys.some(keyEntry =>
|
||||
keyEntry.bShift === e.shiftKey
|
||||
&& keyEntry.bCtrl === e.ctrlKey
|
||||
&& keyEntry.bAlt === e.altKey
|
||||
&& keyEntry.bCmd === e.metaKey
|
||||
&& Configuration.Keys[keyEntry.Key] === e.code
|
||||
)) {
|
||||
e.preventDefault()
|
||||
return true
|
||||
self.fire()
|
||||
document.removeEventListener("keydown", self.keyDownHandler)
|
||||
document.addEventListener("keyup", self.keyUpHandler)
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {String} keyString
|
||||
* @returns {Object}
|
||||
*/
|
||||
static keyOptionsParse(options, keyString) {
|
||||
options = {
|
||||
...options,
|
||||
...IKeyboardShortcut.keyGrammar.KeyboardShortcut.parse(keyString).value
|
||||
/** @param {KeyboardEvent} e */
|
||||
this.keyUpHandler = e => {
|
||||
if (
|
||||
self.#activationKeys.some(keyEntry =>
|
||||
keyEntry.bShift && e.key === "Shift"
|
||||
|| keyEntry.bCtrl && e.key === "Control"
|
||||
|| keyEntry.bAlt && e.key === "Alt"
|
||||
|| keyEntry.bCmd && e.key === "Meta" // Unsure about this, what key is that?
|
||||
|| Configuration.Keys[keyEntry.Key] === e.code
|
||||
|
||||
)) {
|
||||
e.preventDefault()
|
||||
self.unfire()
|
||||
document.removeEventListener("keyup", this.keyUpHandler)
|
||||
document.addEventListener("keydown", this.keyDownHandler)
|
||||
}
|
||||
}
|
||||
return options
|
||||
|
||||
}
|
||||
|
||||
listenEvents() {
|
||||
@@ -81,6 +76,11 @@ export default class IKeyboardShortcut extends IContext {
|
||||
document.removeEventListener("keydown", this.keyDownHandler)
|
||||
}
|
||||
|
||||
// Subclasses will want to override
|
||||
|
||||
fire() {
|
||||
}
|
||||
|
||||
unfire() {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import Configuration from "../../Configuration"
|
||||
import IKeyboardShortcut from "./IKeyboardShortcut"
|
||||
|
||||
export default class KeyvoardCanc extends IKeyboardShortcut {
|
||||
export default class KeyboardCanc extends IKeyboardShortcut {
|
||||
|
||||
/**
|
||||
* @param {HTMLElement} target
|
||||
@@ -9,7 +9,10 @@ export default class KeyvoardCanc extends IKeyboardShortcut {
|
||||
* @param {OBject} options
|
||||
*/
|
||||
constructor(target, blueprint, options = {}) {
|
||||
options = IKeyboardShortcut.keyOptionsParse(options, Configuration.deleteNodesKeyboardKey)
|
||||
options = {
|
||||
...options,
|
||||
activationKeys: Configuration.deleteNodesKeyboardKey
|
||||
}
|
||||
super(target, blueprint, options)
|
||||
}
|
||||
|
||||
|
||||
31
js/input/keybaord/KeyboardEnableZoom.js
Normal file
@@ -0,0 +1,31 @@
|
||||
import Configuration from "../../Configuration"
|
||||
import IKeyboardShortcut from "./IKeyboardShortcut"
|
||||
import Zoom from "../mouse/Zoom"
|
||||
|
||||
export default class KeyboardEnableZoom extends IKeyboardShortcut {
|
||||
|
||||
/** @type {} */
|
||||
#zoomInputObject
|
||||
|
||||
/**
|
||||
* @param {HTMLElement} target
|
||||
* @param {import("../../Blueprint").default} blueprint
|
||||
* @param {OBject} options
|
||||
*/
|
||||
constructor(target, blueprint, options = {}) {
|
||||
options = {
|
||||
...options,
|
||||
activationKeys: Configuration.enableZoomIn
|
||||
}
|
||||
super(target, blueprint, options)
|
||||
}
|
||||
|
||||
fire() {
|
||||
this.zoomInputObject = this.blueprint.getInputObject(Zoom)
|
||||
zoomInputObject.enableZoonIn = true
|
||||
}
|
||||
|
||||
unfire() {
|
||||
this.#zoomInputObject.enableZoom = false
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,10 @@ export default class KeyboardSelectAll extends IKeyboardShortcut {
|
||||
* @param {Object} options
|
||||
*/
|
||||
constructor(target, blueprint, options = {}) {
|
||||
options = IKeyboardShortcut.keyOptionsParse(options, Configuration.selectAllKeyboardKey)
|
||||
options = {
|
||||
...options,
|
||||
activationKeys: Configuration.selectAllKeyboardKey
|
||||
}
|
||||
super(target, blueprint, options)
|
||||
}
|
||||
|
||||
|
||||
@@ -101,6 +101,7 @@ export default class IMouseClickDrag extends IPointing {
|
||||
if (self.started) {
|
||||
self.endDrag()
|
||||
}
|
||||
self.unclicked()
|
||||
if (self.#trackingMouse) {
|
||||
const dragEvent = self.getEvent(Configuration.trackingMouseEventName.end)
|
||||
this.target.dispatchEvent(dragEvent)
|
||||
@@ -146,4 +147,7 @@ export default class IMouseClickDrag extends IPointing {
|
||||
|
||||
endDrag() {
|
||||
}
|
||||
|
||||
unclicked(location) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,11 @@ export default class Select extends IMouseClickDrag {
|
||||
endDrag() {
|
||||
if (this.started) {
|
||||
this.selectorElement.finishSelecting()
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
unclicked() {
|
||||
if (!this.started) {
|
||||
this.blueprint.unselectAll()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,27 @@ import IMouseWheel from "./IMouseWheel"
|
||||
|
||||
export default class Zoom extends IMouseWheel {
|
||||
|
||||
#enableZoonIn = false
|
||||
|
||||
get enableZoonIn() {
|
||||
return this.#enableZoonIn
|
||||
}
|
||||
|
||||
set enableZoonIn(value) {
|
||||
value = Boolean(value)
|
||||
if (value == this.#enableZoonIn) {
|
||||
return
|
||||
}
|
||||
this.#enableZoonIn = value
|
||||
}
|
||||
|
||||
wheel(variation, location) {
|
||||
let zoomLevel = this.blueprint.getZoom()
|
||||
zoomLevel -= variation
|
||||
variation = -variation
|
||||
if (!this.enableZoonIn && zoomLevel == 0 && variation > 0) {
|
||||
return
|
||||
}
|
||||
zoomLevel += variation
|
||||
this.blueprint.setZoom(zoomLevel, location)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import FunctionReferenceEntity from "../entity/FunctionReferenceEntity"
|
||||
import GuidEntity from "../entity/GuidEntity"
|
||||
import Identifier from "../entity/Identifier"
|
||||
import IdentifierEntity from "../entity/IdentifierEntity"
|
||||
import IntegerEntity from "../entity/IntegerEntity"
|
||||
import KeyBindingEntity from "../entity/KeyBindingEntity"
|
||||
import LocalizedTextEntity from "../entity/LocalizedTextEntity"
|
||||
import ObjectEntity from "../entity/ObjectEntity"
|
||||
import ObjectReferenceEntity from "../entity/ObjectReferenceEntity"
|
||||
@@ -15,102 +16,7 @@ let P = Parsimmon
|
||||
|
||||
export default class Grammar {
|
||||
|
||||
/** @param {Grammar} r */
|
||||
InlineWhitespace = r => P.regex(/[^\S\n]+/).desc("inline whitespace")
|
||||
|
||||
/** @param {Grammar} r */
|
||||
InlineOptWhitespace = r => P.regex(/[^\S\n]*/).desc("inline optional whitespace")
|
||||
|
||||
/** @param {Grammar} r */
|
||||
WhitespaceNewline = r => P.regex(/[^\S\n]*\n\s*/).desc("whitespace with at least a newline")
|
||||
|
||||
/** @param {Grammar} r */
|
||||
Null = r => P.seq(P.string("("), r.InlineOptWhitespace, P.string(")")).map(_ => null).desc("null: ()")
|
||||
|
||||
/** @param {Grammar} r */
|
||||
None = r => P.string("None").map(_ => new ObjectReferenceEntity({ type: "None", path: "" })).desc("none")
|
||||
|
||||
/** @param {Grammar} r */
|
||||
Boolean = r => P.alt(P.string("True"), P.string("False")).map(v => v === "True" ? true : false).desc("either True or False")
|
||||
|
||||
/** @param {Grammar} r */
|
||||
Number = r => P.regex(/[\-\+]?[0-9]+(?:\.[0-9]+)?/).map(Number).desc("a number")
|
||||
|
||||
/** @param {Grammar} r */
|
||||
Integer = r => P.regex(/[\-\+]?[0-9]+/).map(v => new IntegerEntity(v)).desc("an integer")
|
||||
|
||||
/** @param {Grammar} r */
|
||||
String = r => P.regex(/(?:[^"\\]|\\.)*/).wrap(P.string('"'), P.string('"')).desc('string (with possibility to escape the quote using \")')
|
||||
|
||||
/** @param {Grammar} r */
|
||||
Word = r => P.regex(/[a-zA-Z]+/).desc("a word")
|
||||
|
||||
/** @param {Grammar} r */
|
||||
Guid = r => P.regex(/[0-9a-zA-Z]{32}/).map(v => new GuidEntity({ value: v })).desc("32 digit hexadecimal (accepts all the letters for safety) value")
|
||||
|
||||
/** @param {Grammar} */
|
||||
Identifier = r => P.regex(/\w+/).map(v => new Identifier(v))
|
||||
|
||||
/** @param {Grammar} r */
|
||||
PathSymbolEntity = r => P.regex(/[0-9a-zA-Z_]+/).map(v => new PathSymbolEntity({ value: v }))
|
||||
|
||||
/** @param {Grammar} r */
|
||||
ReferencePath = r => P.seq(P.string("/"), r.PathSymbolEntity.map(v => v.toString()).sepBy1(P.string(".")).tieWith("."))
|
||||
.tie()
|
||||
.atLeast(2)
|
||||
.tie()
|
||||
.desc('a path (words with possibly underscore, separated by ".", separated by "/")')
|
||||
|
||||
/** @param {Grammar} r */
|
||||
Reference = r => P.alt(
|
||||
r.None,
|
||||
...[r.ReferencePath.map(path => new ObjectReferenceEntity({ type: "", path: path }))].flatMap(
|
||||
v => [v, v.trim(P.string('"'))]
|
||||
),
|
||||
P.seqMap(
|
||||
r.Word,
|
||||
P.optWhitespace,
|
||||
P.alt(P.string('"'), P.string('\'"')).chain(
|
||||
result => r.ReferencePath.skip(
|
||||
P.string(result.split("").reverse().join(""))
|
||||
)
|
||||
),
|
||||
(referenceType, _, referencePath) => new ObjectReferenceEntity({ type: referenceType, path: referencePath })
|
||||
)
|
||||
)
|
||||
|
||||
/** @param {Grammar} r */
|
||||
AttributeName = r => r.Word.sepBy1(P.string(".")).tieWith(".").desc('words separated by ""')
|
||||
|
||||
/** @param {Grammar} r */
|
||||
AttributeAnyValue = r => P.alt(r.Null, r.None, r.Boolean, r.Number, r.Integer, r.String, r.Guid, r.Reference, r.LocalizedText)
|
||||
|
||||
/** @param {Grammar} r */
|
||||
LocalizedText = r => P.seqMap(
|
||||
P.string(LocalizedTextEntity.lookbehind).skip(P.optWhitespace).skip(P.string("(")),
|
||||
r.String.trim(P.optWhitespace), // namespace
|
||||
P.string(","),
|
||||
r.String.trim(P.optWhitespace), // key
|
||||
P.string(","),
|
||||
r.String.trim(P.optWhitespace), // value
|
||||
P.string(")"),
|
||||
(_, namespace, __, key, ___, value, ____) => new LocalizedTextEntity({
|
||||
namespace: namespace,
|
||||
key: key,
|
||||
value: value
|
||||
})
|
||||
)
|
||||
|
||||
/** @param {Grammar} r */
|
||||
PinReference = r => P.seqMap(
|
||||
r.PathSymbolEntity,
|
||||
P.whitespace,
|
||||
r.Guid,
|
||||
(objectName, _, pinGuid) => new PinReferenceEntity({
|
||||
objectName: objectName,
|
||||
pinGuid: pinGuid
|
||||
})
|
||||
)
|
||||
/* --- Factory --- */
|
||||
|
||||
/** @param {Grammar} r */
|
||||
static getGrammarForType(r, attributeType, defaultGrammar) {
|
||||
@@ -125,7 +31,7 @@ export default class Grammar {
|
||||
return r.String
|
||||
case GuidEntity:
|
||||
return r.Guid
|
||||
case Identifier:
|
||||
case IdentifierEntity:
|
||||
return r.Identifier
|
||||
case ObjectReferenceEntity:
|
||||
return r.Reference
|
||||
@@ -159,7 +65,7 @@ export default class Grammar {
|
||||
}
|
||||
|
||||
/** @param {Grammar} r */
|
||||
static CreateAttributeGrammar = (r, entityType, valueSeparator = P.string("=").trim(P.optWhitespace)) =>
|
||||
static createAttributeGrammar = (r, entityType, valueSeparator = P.string("=").trim(P.optWhitespace)) =>
|
||||
r.AttributeName.skip(valueSeparator)
|
||||
.chain(attributeName => {
|
||||
const attributeKey = attributeName.split(".")
|
||||
@@ -172,7 +78,7 @@ export default class Grammar {
|
||||
})
|
||||
|
||||
/** @param {Grammar} r */
|
||||
static CreateMultiAttributeGrammar = (r, entityType) =>
|
||||
static createMultiAttributeGrammar = (r, entityType) =>
|
||||
/**
|
||||
* Basically this creates a parser that looks for a string like 'Key (A=False,B="Something",)'
|
||||
* Then it populates an object of type EntityType with the attribute values found inside the parentheses.
|
||||
@@ -181,7 +87,7 @@ export default class Grammar {
|
||||
entityType.lookbehind
|
||||
? P.seq(P.string(entityType.lookbehind), P.optWhitespace, P.string("("))
|
||||
: P.string("("),
|
||||
Grammar.CreateAttributeGrammar(r, entityType)
|
||||
Grammar.createAttributeGrammar(r, entityType)
|
||||
.trim(P.optWhitespace)
|
||||
.sepBy(P.string(","))
|
||||
.skip(P.regex(/,?/).then(P.optWhitespace)), // Optional trailing comma
|
||||
@@ -192,11 +98,140 @@ export default class Grammar {
|
||||
return result
|
||||
})
|
||||
|
||||
/** @param {Grammar} r */
|
||||
FunctionReference = r => Grammar.CreateMultiAttributeGrammar(r, FunctionReferenceEntity)
|
||||
/* --- General --- */
|
||||
|
||||
/** @param {Grammar} r */
|
||||
Pin = r => Grammar.CreateMultiAttributeGrammar(r, PinEntity)
|
||||
InlineWhitespace = r => P.regex(/[^\S\n]+/).desc("inline whitespace")
|
||||
|
||||
/** @param {Grammar} r */
|
||||
InlineOptWhitespace = r => P.regex(/[^\S\n]*/).desc("inline optional whitespace")
|
||||
|
||||
/** @param {Grammar} r */
|
||||
MultilineWhitespace = r => P.regex(/[^\S\n]*\n\s*/).desc("whitespace with at least a newline")
|
||||
|
||||
/** @param {Grammar} r */
|
||||
Null = r => P.seq(P.string("("), r.InlineOptWhitespace, P.string(")")).map(_ => null).desc("null: ()")
|
||||
|
||||
/** @param {Grammar} r */
|
||||
Boolean = r => P.alt(P.string("True"), P.string("False")).map(v => v === "True" ? true : false)
|
||||
.desc("either True or False")
|
||||
|
||||
/** @param {Grammar} r */
|
||||
Number = r => P.regex(/[\-\+]?[0-9]+(?:\.[0-9]+)?/).map(Number).desc("a number")
|
||||
|
||||
/** @param {Grammar} r */
|
||||
Word = r => P.regex(/[a-zA-Z]+/).desc("a word")
|
||||
|
||||
/** @param {Grammar} r */
|
||||
String = r => P.regex(/(?:[^"\\]|\\.)*/).wrap(P.string('"'), P.string('"'))
|
||||
.desc('string (with possibility to escape the quote using \")')
|
||||
|
||||
/** @param {Grammar} r */
|
||||
ReferencePath = r => P.seq(
|
||||
P.string("/"),
|
||||
r.PathSymbol
|
||||
.map(v => v.toString())
|
||||
.sepBy1(P.string("."))
|
||||
.tieWith(".")
|
||||
)
|
||||
.tie()
|
||||
.atLeast(2)
|
||||
.tie()
|
||||
.desc('a path (words with possibly underscore, separated by ".", separated by "/")')
|
||||
|
||||
/** @param {Grammar} r */
|
||||
AttributeName = r => r.Word.sepBy1(P.string(".")).tieWith(".").desc('words separated by ""')
|
||||
|
||||
/* --- Entity --- */
|
||||
|
||||
/** @param {Grammar} r */
|
||||
None = r => P.string("None").map(_ => new ObjectReferenceEntity({ type: "None", path: "" })).desc("none")
|
||||
|
||||
/** @param {Grammar} r */
|
||||
Integer = r => P.regex(/[\-\+]?[0-9]+/).map(v => new IntegerEntity(v)).desc("an integer")
|
||||
|
||||
/** @param {Grammar} r */
|
||||
Guid = r => P.regex(/[0-9a-zA-Z]{32}/).map(v => new GuidEntity({ value: v }))
|
||||
.desc("32 digit hexadecimal (accepts all the letters for safety) value")
|
||||
|
||||
/** @param {Grammar} */
|
||||
Identifier = r => P.regex(/\w+/).map(v => new IdentifierEntity(v))
|
||||
|
||||
/** @param {Grammar} r */
|
||||
PathSymbol = r => P.regex(/[0-9a-zA-Z_]+/).map(v => new PathSymbolEntity({ value: v }))
|
||||
|
||||
/** @param {Grammar} r */
|
||||
Reference = r => P.alt(
|
||||
r.None,
|
||||
...[r.ReferencePath.map(path => new ObjectReferenceEntity({ type: "", path: path }))]
|
||||
.flatMap(referencePath => [
|
||||
referencePath, // version having just path
|
||||
referencePath.trim(P.string('"')) // Version having path surround with double quotes
|
||||
]),
|
||||
P.seqMap(
|
||||
r.Word, // Goes into referenceType
|
||||
P.optWhitespace, // Goes into _ (ignored)
|
||||
P.alt(...[r.ReferencePath].flatMap(referencePath => [
|
||||
referencePath.wrap(P.string(`"`), P.string(`"`)),
|
||||
referencePath.wrap(P.string(`'"`), P.string(`"'`))
|
||||
])), // Goes into referencePath
|
||||
(referenceType, _, referencePath) => new ObjectReferenceEntity({ type: referenceType, path: referencePath })
|
||||
),
|
||||
r.Word.map(type => new ObjectReferenceEntity({ type: type, path: "" })),
|
||||
)
|
||||
|
||||
/** @param {Grammar} r */
|
||||
LocalizedText = r => P.seqMap(
|
||||
P.string(LocalizedTextEntity.lookbehind).skip(P.optWhitespace).skip(P.string("(")), // Goes into _ (ignored)
|
||||
r.String.trim(P.optWhitespace), // Goes into namespace
|
||||
P.string(","), // Goes into __ (ignored)
|
||||
r.String.trim(P.optWhitespace), // Goes into key
|
||||
P.string(","), // Goes into ___ (ignored)
|
||||
r.String.trim(P.optWhitespace), // Goes into value
|
||||
P.string(")"), // Goes into ____ (ignored)
|
||||
(_, namespace, __, key, ___, value, ____) => new LocalizedTextEntity({
|
||||
namespace: namespace,
|
||||
key: key,
|
||||
value: value
|
||||
})
|
||||
)
|
||||
|
||||
/** @param {Grammar} r */
|
||||
AttributeAnyValue = r => P.alt(
|
||||
r.Null,
|
||||
r.None,
|
||||
r.Boolean,
|
||||
r.Number,
|
||||
r.Integer,
|
||||
r.String,
|
||||
r.Guid,
|
||||
r.Reference,
|
||||
r.LocalizedText)
|
||||
|
||||
/** @param {Grammar} r */
|
||||
PinReference = r => P.seqMap(
|
||||
r.PathSymbol, // Goes into objectNAme
|
||||
P.whitespace, // Goes into _ (ignored)
|
||||
r.Guid, // Goes into pinGuid
|
||||
(objectName, _, pinGuid) => new PinReferenceEntity({
|
||||
objectName: objectName,
|
||||
pinGuid: pinGuid
|
||||
})
|
||||
)
|
||||
|
||||
/** @param {Grammar} r */
|
||||
FunctionReference = r => Grammar.createMultiAttributeGrammar(r, FunctionReferenceEntity)
|
||||
|
||||
/** @param {Grammar} r */
|
||||
KeyBinding = r => P.alt(
|
||||
r.Identifier.map(identifier => new KeyBindingEntity({
|
||||
Key: identifier
|
||||
})),
|
||||
Grammar.createMultiAttributeGrammar(r, KeyBindingEntity)
|
||||
)
|
||||
|
||||
/** @param {Grammar} r */
|
||||
Pin = r => Grammar.createMultiAttributeGrammar(r, PinEntity)
|
||||
|
||||
/** @param {Grammar} r */
|
||||
CustomProperties = r =>
|
||||
@@ -216,10 +251,10 @@ export default class Grammar {
|
||||
P
|
||||
.alt(
|
||||
r.CustomProperties,
|
||||
Grammar.CreateAttributeGrammar(r, ObjectEntity)
|
||||
Grammar.createAttributeGrammar(r, ObjectEntity)
|
||||
)
|
||||
.sepBy1(P.whitespace),
|
||||
P.seq(r.WhitespaceNewline, P.string("End"), P.whitespace, P.string("Object")),
|
||||
P.seq(r.MultilineWhitespace, P.string("End"), P.whitespace, P.string("Object")),
|
||||
(_, attributes, __) => {
|
||||
let result = new ObjectEntity()
|
||||
attributes.forEach(attributeSetter => attributeSetter(result))
|
||||
|
||||
@@ -2,7 +2,9 @@ import CustomSerializer from "./CustomSerializer"
|
||||
import FunctionReferenceEntity from "../entity/FunctionReferenceEntity"
|
||||
import GeneralSerializer from "./GeneralSerializer"
|
||||
import GuidEntity from "../entity/GuidEntity"
|
||||
import IdentifierEntity from "../entity/IdentifierEntity"
|
||||
import IntegerEntity from "../entity/IntegerEntity"
|
||||
import KeyBindingEntity from "../entity/KeyBindingEntity"
|
||||
import LocalizedTextEntity from "../entity/LocalizedTextEntity"
|
||||
import ObjectEntity from "../entity/ObjectEntity"
|
||||
import ObjectReferenceEntity from "../entity/ObjectReferenceEntity"
|
||||
@@ -12,29 +14,39 @@ import PinEntity from "../entity/PinEntity"
|
||||
import PinReferenceEntity from "../entity/PinReferenceEntity"
|
||||
import SerializerFactory from "./SerializerFactory"
|
||||
import ToStringSerializer from "./ToStringSerializer"
|
||||
import Identifier from "../entity/Identifier"
|
||||
|
||||
export default function initializeSerializerFactory() {
|
||||
|
||||
SerializerFactory.registerSerializer(
|
||||
ObjectEntity,
|
||||
new ObjectSerializer()
|
||||
)
|
||||
|
||||
SerializerFactory.registerSerializer(
|
||||
PinEntity,
|
||||
new GeneralSerializer(v => `${PinEntity.lookbehind} (${v})`, PinEntity, "", ",", true)
|
||||
)
|
||||
|
||||
SerializerFactory.registerSerializer(
|
||||
FunctionReferenceEntity,
|
||||
new GeneralSerializer(v => `(${v})`, FunctionReferenceEntity, "", ",", false)
|
||||
)
|
||||
|
||||
SerializerFactory.registerSerializer(
|
||||
KeyBindingEntity,
|
||||
new GeneralSerializer(v => `(${v})`, KeyBindingEntity, "", ",", false)
|
||||
)
|
||||
|
||||
SerializerFactory.registerSerializer(
|
||||
LocalizedTextEntity,
|
||||
new GeneralSerializer(v => `${LocalizedTextEntity.lookbehind}(${v})`, LocalizedTextEntity, "", ", ", false, "", _ => "")
|
||||
)
|
||||
|
||||
SerializerFactory.registerSerializer(
|
||||
PinReferenceEntity,
|
||||
new GeneralSerializer(v => v, PinReferenceEntity, "", " ", false, "", _ => "")
|
||||
)
|
||||
|
||||
SerializerFactory.registerSerializer(
|
||||
ObjectReferenceEntity,
|
||||
new CustomSerializer(
|
||||
@@ -45,8 +57,12 @@ export default function initializeSerializerFactory() {
|
||||
: ""
|
||||
))
|
||||
)
|
||||
SerializerFactory.registerSerializer(Identifier, new ToStringSerializer(Identifier))
|
||||
|
||||
SerializerFactory.registerSerializer(IdentifierEntity, new ToStringSerializer(IdentifierEntity))
|
||||
|
||||
SerializerFactory.registerSerializer(PathSymbolEntity, new ToStringSerializer(PathSymbolEntity))
|
||||
|
||||
SerializerFactory.registerSerializer(GuidEntity, new ToStringSerializer(GuidEntity))
|
||||
|
||||
SerializerFactory.registerSerializer(IntegerEntity, new ToStringSerializer(IntegerEntity))
|
||||
}
|
||||
|
||||
@@ -28,6 +28,9 @@ export default class NodeTemplate extends SelectableDraggableTemplate {
|
||||
<div class="ueb-node-outputs"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ueb-node-expand">
|
||||
<span class="ueb-node-expand-icon"></span>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ export default class SelectorTemplate extends ITemplate {
|
||||
*/
|
||||
apply(selector) {
|
||||
super.apply(selector)
|
||||
selector.classList.add("ueb-positioned")
|
||||
this.applyFinishSelecting(selector)
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ export default {
|
||||
copy({
|
||||
targets: [
|
||||
{
|
||||
src: ["font/*"],
|
||||
src: ["assets/fonts/*"],
|
||||
dest: "dist/font"
|
||||
}
|
||||
]
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
}
|
||||
|
||||
.ueb-pin-boolean {
|
||||
$ueb-pin-color : #930000;
|
||||
$ueb-pin-color : rgb(30%, 0, 0);
|
||||
--ueb-pin-color: #{$ueb-pin-color};
|
||||
}
|
||||
|
||||
.ueb-pin-int {
|
||||
$ueb-pin-color : #1fe0ad;
|
||||
.ueb-pin-class {
|
||||
$ueb-pin-color : #5800bb;
|
||||
--ueb-pin-color: #{$ueb-pin-color};
|
||||
}
|
||||
|
||||
@@ -20,8 +20,19 @@
|
||||
--ueb-pin-color: #{$ueb-pin-color};
|
||||
}
|
||||
|
||||
.ueb-pin-vector {
|
||||
$ueb-pin-color : #fcc823;
|
||||
.ueb-pin-int {
|
||||
$ueb-pin-color : #1fe0ad;
|
||||
--ueb-pin-color: #{$ueb-pin-color};
|
||||
}
|
||||
|
||||
.ueb-pin-name {
|
||||
$ueb-pin-color : #cb81fc;
|
||||
--ueb-pin-color: #{$ueb-pin-color};
|
||||
}
|
||||
|
||||
.ueb-pin-object {
|
||||
$ueb-pin-color : #00a8f2;
|
||||
$ueb-pin-color : rgba(0%, 40%, 01%);
|
||||
--ueb-pin-color: #{$ueb-pin-color};
|
||||
}
|
||||
|
||||
@@ -36,12 +47,7 @@
|
||||
--ueb-pin-background: linear-gradient(90deg, #fc00d220, #fc00d280 15%, #fc00d250 85%, transparent);
|
||||
}
|
||||
|
||||
.ueb-pin-name {
|
||||
$ueb-pin-color : #cb81fc;
|
||||
--ueb-pin-color: #{$ueb-pin-color};
|
||||
}
|
||||
|
||||
.ueb-pin-object {
|
||||
$ueb-pin-color : #00a8f2;
|
||||
.ueb-pin-vector {
|
||||
$ueb-pin-color : #fcc823;
|
||||
--ueb-pin-color: #{$ueb-pin-color};
|
||||
}
|
||||
@@ -262,6 +262,14 @@ ueb-blueprint[data-drag-scrolling="false"][data-selecting="false"] ueb-node {
|
||||
padding-right: 8px;
|
||||
}
|
||||
|
||||
.ueb-node-expand {
|
||||
display: none;
|
||||
}
|
||||
|
||||
ueb-node[data-advanced-display] .ueb-node-expand {
|
||||
display: block;
|
||||
}
|
||||
|
||||
ueb-pin {
|
||||
display: block;
|
||||
padding: 1px 2px;
|
||||
|
||||