249 lines
7.0 KiB
JavaScript
249 lines
7.0 KiB
JavaScript
"use strict";
|
|
|
|
const fs = require("fs");
|
|
const path = require("path");
|
|
|
|
const _ = require("lodash");
|
|
const $ = require("jquery");
|
|
const React = require("react");
|
|
|
|
const { CompositeDisposable } = require("atom");
|
|
|
|
const atomIntegration = require("./atom-react/atom-integration");
|
|
const jsonOpener = require("./common/json-opener");
|
|
const packageGeneratorModal = require("./package-generator/package-generator-modal");
|
|
const launcher = require("./launcher/launcher");
|
|
const treeViewHelper = require("./common/tree-view-helper");
|
|
|
|
const CheatSheetTab = require("./cheat-sheet/cheat-sheat-tab");
|
|
const StyleguideEditor = require("./atom-react/styleguide/styleguide-editor");
|
|
|
|
const JiboSim = require("./animation-preview/jibo-sim");
|
|
const AnimationEditor = require("./animation-editor/animation-editor");
|
|
const BehaviorEditor = require("./behavior-editor/behavior-editor");
|
|
|
|
const AnimationModel = require("./animation-editor/models/animation-model");
|
|
const BehaviorTreeModel = require("./behavior-editor/tree-model");
|
|
|
|
function createUniquePath(directory, baseName, extension) {
|
|
let candidate = path.join(directory, `${baseName}.${extension}`);
|
|
let i = 1;
|
|
while (fs.existsSync(candidate)) {
|
|
candidate = path.join(directory, `${baseName}-${i}.${extension}`);
|
|
i += 1;
|
|
}
|
|
return candidate;
|
|
}
|
|
|
|
function getSelectedProjectSubdir(subdirName) {
|
|
return treeViewHelper.getFolderPathWithDirectory(
|
|
treeViewHelper.getFolderPathOfSelection(),
|
|
subdirName,
|
|
);
|
|
}
|
|
|
|
function notifyError(title, err) {
|
|
if (!atom.notifications) return;
|
|
atom.notifications.addError(title, {
|
|
detail: String((err && err.stack) || err),
|
|
dismissable: true,
|
|
});
|
|
}
|
|
|
|
module.exports = {
|
|
config: {
|
|
AnimationEditorBackgroundColor: {
|
|
type: "color",
|
|
default: "#4C4C4C",
|
|
description: "The background color in the Animation Editor",
|
|
},
|
|
AnimationEditorGridColor: {
|
|
type: "color",
|
|
default: "#E5E5E5",
|
|
description: "The grid color in the Animation Editor",
|
|
},
|
|
"RunConfiguration.type": {
|
|
type: "string",
|
|
enum: ["local", "remote"],
|
|
default: "local",
|
|
description: "Which mode to use when running/debugging your skill.",
|
|
},
|
|
"RunConfiguration.host": {
|
|
type: "string",
|
|
default: "",
|
|
description: "The host or ip of the robot you want to target.",
|
|
},
|
|
"RunConfiguration.run-dir": {
|
|
type: "string",
|
|
default: "${project}",
|
|
description:
|
|
"The directory to run your skill from if it's not the root of your opened project.",
|
|
},
|
|
DisableRunSkillShortcut: {
|
|
type: "boolean",
|
|
default: false,
|
|
description:
|
|
"Disable the shortcut for running skills, if you prefer it binding to built in the Symbol-Viewer toggle.",
|
|
},
|
|
},
|
|
|
|
activate() {
|
|
this.disposables = new CompositeDisposable();
|
|
|
|
try {
|
|
atomIntegration.activate();
|
|
|
|
this.disposables.add(
|
|
atom.workspace.addOpener((uri) => {
|
|
return this.openURI(uri);
|
|
}),
|
|
);
|
|
|
|
this.disposables.add(
|
|
atom.commands.add("atom-workspace", {
|
|
"jibo-sdk:new-project": () => {
|
|
try {
|
|
packageGeneratorModal();
|
|
} catch (err) {
|
|
notifyError("Jibo: New Project failed", err);
|
|
}
|
|
},
|
|
"jibo-sdk:open-as-json": () => {
|
|
try {
|
|
jsonOpener.open();
|
|
} catch (err) {
|
|
notifyError("Jibo: Open as JSON failed", err);
|
|
}
|
|
},
|
|
"jibo-sdk:new-animation-file": () => {
|
|
try {
|
|
const dir = getSelectedProjectSubdir("animations");
|
|
if (!dir) {
|
|
alert(
|
|
"You must have a valid project loaded in order to create a new animation.",
|
|
);
|
|
return;
|
|
}
|
|
const filePath = createUniquePath(dir, "new-animation", "keys");
|
|
if (!AnimationEditor.isValidDirectory(filePath)) {
|
|
alert('You must save animations under the "animations" folder.');
|
|
return;
|
|
}
|
|
AnimationModel.createNewFile(filePath);
|
|
atom.workspace.open(filePath);
|
|
} catch (err) {
|
|
notifyError("Jibo: New Animation failed", err);
|
|
}
|
|
},
|
|
"jibo-sdk:new-behavior-tree-file": () => {
|
|
try {
|
|
const dir = getSelectedProjectSubdir("behaviors");
|
|
if (!dir) {
|
|
alert(
|
|
"You must have a valid project loaded in order to create a new behavior tree file.",
|
|
);
|
|
return;
|
|
}
|
|
const filePath = createUniquePath(dir, "new-behavior", "bt");
|
|
if (!BehaviorEditor.isValidDirectory(filePath)) {
|
|
alert('You must save behavior trees under the "behaviors" folder.');
|
|
return;
|
|
}
|
|
const schema = BehaviorEditor.getNewSchema(filePath);
|
|
BehaviorTreeModel.createNewFile(filePath, schema.core.schema.Sequence);
|
|
atom.workspace.open(filePath);
|
|
} catch (err) {
|
|
notifyError("Jibo: New Behavior Tree failed", err);
|
|
}
|
|
},
|
|
"jibo-sdk:play": () => {
|
|
try {
|
|
launcher.play();
|
|
} catch (err) {
|
|
notifyError("Jibo: Play failed", err);
|
|
}
|
|
},
|
|
"jibo-sdk:play-animation": () => {
|
|
try {
|
|
launcher.play();
|
|
} catch (err) {
|
|
notifyError("Jibo: Play Animation failed", err);
|
|
}
|
|
},
|
|
"jibo-sdk:stop": () => {
|
|
try {
|
|
launcher.stop();
|
|
} catch (err) {
|
|
notifyError("Jibo: Stop failed", err);
|
|
}
|
|
},
|
|
"jibo-sdk:cheat-sheet": () => {
|
|
try {
|
|
atom.workspace.open("atom://jibo-cheat-sheet");
|
|
} catch (err) {
|
|
notifyError("Jibo: Open Cheat Sheet failed", err);
|
|
}
|
|
},
|
|
"atom-react:styleguide": () => {
|
|
try {
|
|
atom.workspace.open("atom://atom-react-styleguide");
|
|
} catch (err) {
|
|
notifyError("Jibo: Open Styleguide failed", err);
|
|
}
|
|
},
|
|
"jibo-sdk:run-skill": (event) => {
|
|
if (atom.config.get("jibo-sdk.DisableRunSkillShortcut")) {
|
|
if (event && typeof event.abortKeyBinding === "function") event.abortKeyBinding();
|
|
return;
|
|
}
|
|
try {
|
|
launcher.togglePlayer();
|
|
} catch (err) {
|
|
notifyError("Jibo: Run Skill failed", err);
|
|
}
|
|
},
|
|
"jibo-sdk:login": () => {
|
|
// Legacy login gating is no longer supported; keep as no-op.
|
|
if (atom.notifications) {
|
|
atom.notifications.addInfo("Jibo: Login is not required in Pulsar", {
|
|
detail:
|
|
"The original Atom-era login flow depended on deprecated Electron APIs.",
|
|
dismissable: true,
|
|
});
|
|
}
|
|
},
|
|
}),
|
|
);
|
|
} catch (err) {
|
|
notifyError("Jibo SDK failed to activate", err);
|
|
}
|
|
},
|
|
|
|
deactivate() {
|
|
if (this.disposables) this.disposables.dispose();
|
|
try {
|
|
atomIntegration.deactivate();
|
|
} catch (err) {
|
|
// ignore
|
|
}
|
|
},
|
|
|
|
openURI(uri) {
|
|
// Always handle package URIs.
|
|
if (uri === "atom://jibo-cheat-sheet") return new CheatSheetTab(uri, true);
|
|
if (uri === "atom://atom-react-styleguide") return new StyleguideEditor(uri, true);
|
|
|
|
// Respect JSON opener toggle for file-based editors.
|
|
if (jsonOpener.useDefaultEditor() === false) return undefined;
|
|
|
|
const handlers = {
|
|
".anim": JiboSim,
|
|
".keys": AnimationEditor,
|
|
".bt": BehaviorEditor,
|
|
};
|
|
const ext = path.extname(uri).toLowerCase();
|
|
if (_.has(handlers, ext)) return new handlers[ext](uri);
|
|
return undefined;
|
|
},
|
|
};
|