Skip to content

Latest commit

 

History

History
95 lines (72 loc) · 3.4 KB

add-inspector-properties.md

File metadata and controls

95 lines (72 loc) · 3.4 KB

Recipe: add Inspector properties

The Inspector (properties) view edits the fields of the currently selected object. Your editor supplies a PropertySectionProvider, which adds one or more PropertySections.

Base classes: colibri.ui.controls.properties.PropertySectionProvider and PropertySection<T> Working example: TodoEditorProperties.ts.

1. The provider

import properties = colibri.ui.controls.properties;

export class TodoEditorPropertySectionProvider extends properties.PropertySectionProvider {

    constructor(private _editor: TodoEditor) { super(); }

    addSections(page: properties.PropertyPage, sections: properties.PropertySection<any>[]): void {
        sections.push(new TodoTaskSection(page, this._editor));
    }
}

Return it from your editor:

getPropertyProvider() { return this._propertyProvider; }

If you also have an Outline provider, return the same provider from its getPropertySectionProvider() so the Inspector works whether the editor or the outline has focus.

2. The section

export class TodoTaskSection extends properties.PropertySection<TodoTask> {

    constructor(page: properties.PropertyPage, private _editor: TodoEditor) {
        // 4th arg fillSpace=false: fields size to content instead of
        // stretching to fill the inspector height.
        super(page, "myplugin.example.TodoTaskSection", "Task", false);
    }

    createForm(parent: HTMLDivElement) {
        const comp = this.createGridElement(parent, 2);   // 2-column grid

        this.createLabel(comp, "Name", "The task name.");
        const text = this.createText(comp);
        text.addEventListener("change", () =>
            this.changeTasks(t => t.setName(text.value)));
        this.addUpdater(() =>
            text.value = this.getSelectionFirstElement().getName());
    }

    private changeTasks(setter: (t: TodoTask) => void) {
        for (const t of this.getSelection()) setter(t);
        this._editor.setDirty(true);
        this._editor.refreshViewers();
    }

    canEdit(obj: any, n: number) { return obj instanceof TodoTask; }
    canEditNumber(n: number) { return n >= 1; }   // supports multi-select
}

Key methods

  • Build controls with FormBuilder helpers on the section: createGridElement, createLabel, createText, createTextArea, createMenuButton, etc. They are themed automatically.
  • addUpdater(fn) — fn runs whenever the selection changes; use it to push the model value into the control.
  • On change — write the control value back into every selected object (getSelection()), then setDirty(true) and refresh viewers.
  • canEdit(obj, n) — return true for object types this section handles.
  • canEditNumber(n) — return true for the selection sizes you support (n >= 1 enables multi-select editing).

How selection reaches the section

The Inspector reads the active editor Part's selection. Your editor sets it with this.setSelection(objects) (see add-a-custom-editor). Whatever you pass there is what getSelection() returns inside the section.

Checklist

  • Provider returned from getPropertyProvider() (and the outline provider).
  • Section reads model in addUpdater, writes model on change.
  • setDirty(true) + refresh after edits.
  • npm run build passes.