-
Notifications
You must be signed in to change notification settings - Fork 563
Editor Extensions
Atomic has an editor extension capability which will allow specially constructed TypeScript/JavaScript plugin files to be hooked into the editor once a project is loaded. The extension mechanism currently has the following features:
- Scripts can be written in JavaScript or TypeScript
- Scripts run in the same process as the editor
- Menu items can be added to the
Developer->Plugins
menu of the editor - Menu items can be added to the right+click menu on files
- Menu items can be added to the right+click menu on the Hierarchy
- Plugins have access to the active editor scene
- Plugins have access to read/write project preferences
- Plugins can implement their own resource editors
An example exists in the examples repository in the Editor Plugins folder.
To get started, you will need to create a new 2D TypeScript project in the editor and then create a new folder called: EditorData
under Resources
This folder is what the editor looks at to determine if there are any plugins to load. Each plugin must follow the naming convention: *.plugin.js
and will be loaded up when the project is opened.
A simple example will be to add a menu to the developer menu. This example will be written in TypeScript.
Create a new script file called: mymenu.plugin.ts
under the EditorData
folder.
Replace the contents with the following:
class MyMenuPlugin extends Atomic.ScriptObject
implements Editor.HostExtensions.HostEditorService,
Editor.HostExtensions.UIServicesEventListener,
Editor.HostExtensions.ProjectServicesEventListener {
// Define the name and description of the plugin.
name = "MyMenuPlugin";
description = "Simple example of a menu";
private serviceLocator: Editor.HostExtensions.HostServiceLocator;
/**
* Called when the plugin is first loaded by the editor. A reference to the
* service locator interface will be passed to the initialization routine so that
* it can 'talk back' to the editor.
*
* @param {Editor.HostExtensions.HostServiceLocator} serviceLocator
*
* @memberOf MyMenuPlugin
*/
initialize(serviceLocator: Editor.HostExtensions.HostServiceLocator) {
// some debug
console.log(`${this.name}.initialize`);
this.serviceLocator = serviceLocator;
}
}
export default new MyMenuPlugin();
This is a minimalist plugin. It activates, but does not do anything. In order for the plugin to start interacting with the editor, it needs to register itself with various editor subsystems. In this example, we want to register with the ProjectServicesEventListener
and UIServicesEventListener
.
Add the following to the initialize
method:
this.serviceLocator.uiServices.register(this);
this.serviceLocator.projectServices.register(this);
At this point, you can add any of the handlers that are available in the UIServicesEventListener and ProjectServicesEventListener
When the project loads, we want to attach our menu item to the menu. To do this, we will hook into the Project Loaded Event which will be called by the editor and then call a uiServices method to add the menu:
projectLoaded(ev: Editor.EditorLoadProjectEvent) {
// some debug
console.log(`${this.name}.projectLoaded`);
this.serviceLocator.uiServices.createPluginMenuItemSource("My Menu", { "Open" : [`${this.name}.open.myaction`] });
}
We also want to make sure the menu is removed and we unregister from the editor when we close the project:
projectUnloaded() {
// some debug
console.log(`${this.name}.projectUnloaded`);
this.serviceLocator.uiServices.removePluginMenuItemSource("My Menu");
this.serviceLocator.projectServices.unregister(this);
this.serviceLocator.uiServices.unregister(this);
this.unsubscribeFromAllEvents();
}
Finally, we want to actually do something when the menu is clicked. To do that, we need to implement the menuItemClicked
method:
menuItemClicked(refId: string): boolean {
// some debug
console.log(`${this.name}.menuItemClicked: ${refId}`);
if (refId == `${this.name}.open.myaction`) {
// Here we can launch our own dialog, or perform some kind
// of action. But let's just throw an alert
this.serviceLocator.uiServices.showModalError("Alert", "Clicked!");
// Return true to indicate that we handled the click event
return true;
}
return false;
}
In order for this to be picked up by the editor, you will need to transpile the typescript to javascript. This can be done by clicking the Developer->Plugins->TypeScript->Compile Project
menu item.
Once it's transpiled, you will need to close your project and re-open it for the changes to be recognized. Click the Developer->Plugins->MyMenu->Open
menu item and then you can see the Clicked message alert.
Home | Copyright (c) 2014 - 2017 THUNDERBEAST GAMES LLC