123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538 |
- // Copyright (c) Jupyter Development Team.
- // Distributed under the terms of the Modified BSD License.
- import {
- Message
- } from 'phosphor-messaging';
- import {
- Panel
- } from 'phosphor-panel';
- import {
- ISignal, Signal, clearSignalData
- } from 'phosphor-signaling';
- import {
- TabPanel
- } from 'phosphor-tabs';
- import {
- Widget
- } from 'phosphor-widget';
- import {
- NotebookToolbar, ToolbarButton
- } from '../notebook/notebook/toolbar';
- /**
- * The class name added to inspector panels.
- */
- const PANEL_CLASS = 'jp-Inspector';
- /**
- * The class name added to inspector child item widgets.
- */
- const ITEM_CLASS = 'jp-InspectorItem';
- /**
- * The class name added to inspector child item widgets' content.
- */
- const CONTENT_CLASS = 'jp-InspectorItem-content';
- /**
- * The history clear button class name.
- */
- const CLEAR_CLASS = 'jp-InspectorItem-clear';
- /**
- * The back button class name.
- */
- const BACK_CLASS = 'jp-InspectorItem-back';
- /**
- * The forward button class name.
- */
- const FORWARD_CLASS = 'jp-InspectorItem-forward';
- /**
- * The orientation toggle bottom button class name.
- */
- const BOTTOM_TOGGLE_CLASS = 'jp-InspectorItem-bottom';
- /**
- * The orientation toggle right button class name.
- */
- const RIGHT_TOGGLE_CLASS = 'jp-InspectorItem-right';
- /**
- * A panel which contains a set of inspectors.
- */
- export
- class Inspector extends TabPanel {
- /**
- * Construct an inspector.
- */
- constructor(options: Inspector.IOptions) {
- super();
- this.addClass(PANEL_CLASS);
- // Create console inspector widgets and add them to the inspectors panel.
- (options.items || []).forEach(value => {
- let widget = value.widget || new InspectorItem();
- widget.orientation = this._orientation as Inspector.Orientation;
- widget.orientationToggled.connect(() => {
- this.orientation = 'vertical' ? 'horizontal' : 'vertical';
- });
- widget.rank = value.rank;
- widget.remember = !!value.remember;
- widget.title.closable = false;
- widget.title.text = value.name;
- if (value.className) {
- widget.addClass(value.className);
- }
- this._items[value.type] = widget;
- this.addChild(widget);
- });
- }
- /**
- * Set the orientation of the inspector panel.
- */
- get orientation(): Inspector.Orientation {
- return this._orientation;
- }
- set orientation(orientation: Inspector.Orientation) {
- if (this._orientation === orientation) {
- return;
- }
- this._orientation = orientation;
- Object.keys(this._items).forEach(i => {
- this._items[i].orientation = orientation;
- });
- }
- /**
- * Set the reference to the semantic parent of the inspector panel.
- */
- get reference(): Inspector.IInspectable {
- return this._reference;
- }
- set reference(reference: Inspector.IInspectable) {
- if (this._reference === reference) {
- return;
- }
- // Disconnect old signal handler.
- if (this.reference) {
- this._reference.inspected.disconnect(this.onInspectorUpdate, this);
- }
- // Clear the inspector child items (but maintain history).
- Object.keys(this._items).forEach(i => this._items[i].content = null);
- this._reference = reference;
- // Connect new signal handler.
- if (this.reference) {
- this._reference.inspected.connect(this.onInspectorUpdate, this);
- }
- }
- /**
- * Dispose of the resources held by the widget.
- */
- dispose(): void {
- if (this.isDisposed) {
- return;
- }
- // Dispose the inspector child items.
- Object.keys(this._items).forEach(i => this._items[i].dispose());
- this._items = null;
- // Disconnect from reference.
- this.reference = null;
- super.dispose();
- }
- /**
- * Handle inspector update signals.
- */
- protected onInspectorUpdate(sender: any, args: Inspector.IInspectorUpdate): void {
- let widget = this._items[args.type];
- if (!widget) {
- return;
- }
- // Update the content of the inspector widget.
- widget.content = args.content;
- let items = this._items;
- // If any inspector with a higher rank has content, do not change focus.
- if (args.content) {
- for (let type in items) {
- let inspector = this._items[type];
- if (inspector.rank < widget.rank && inspector.content) {
- return;
- }
- }
- this.currentWidget = widget;
- return;
- }
- // If the inspector was emptied, show the next best ranked inspector.
- let lowest = Infinity;
- widget = null;
- for (let type in items) {
- let inspector = this._items[type];
- if (inspector.rank < lowest && inspector.content) {
- lowest = inspector.rank;
- widget = inspector;
- }
- }
- if (widget) {
- this.currentWidget = widget;
- }
- }
- private _items: { [type: string]: InspectorItem } = Object.create(null);
- private _orientation: Inspector.Orientation = 'horizontal';
- private _reference: Inspector.IInspectable = null;
- }
- /**
- * A namespace for Inspector statics.
- */
- export
- namespace Inspector {
- /**
- * The orientation options of an inspector panel.
- */
- export
- type Orientation = 'horizontal' | 'vertical';
- /**
- * The definition of an inspector.
- */
- export
- interface IInspectable {
- /**
- * A signal emitted when an inspector value is generated.
- */
- inspected: ISignal<any, IInspectorUpdate>;
- }
- /**
- * An update value for code inspectors.
- */
- export
- interface IInspectorUpdate {
- /**
- * The content being sent to the inspector for display.
- */
- content: Widget;
- /**
- * The type of the inspector being updated.
- */
- type: string;
- }
- /**
- * The definition of a child item of an inspector panel.
- */
- export
- interface IInspectorItem {
- /**
- * The optional class name added to the inspector child widget.
- */
- className?: string;
- /**
- * The display name of the inspector child.
- */
- name: string;
- /**
- * The rank order of display priority for inspector updates. A lower rank
- * denotes a higher display priority.
- */
- rank: number;
- /**
- * A flag that indicates whether the inspector remembers history.
- *
- * The default value is `false`.
- */
- remember?: boolean;
- /**
- * The type of the inspector.
- */
- type: string;
- /**
- * The optional console inspector widget instance.
- */
- widget?: InspectorItem;
- }
- /**
- * The initialization options for a console panel.
- */
- export
- interface IOptions {
- /**
- * The list of available child inspectors items for code introspection.
- *
- * #### Notes
- * The order of items in the inspectors array is the order in which they
- * will be rendered in the inspectors tab panel.
- */
- items?: IInspectorItem[];
- /**
- * The orientation of the inspector panel.
- *
- * The default value is `'horizontal'`.
- */
- orientation?: Orientation;
- }
- }
- /**
- * A code inspector child widget.
- */
- export
- class InspectorItem extends Panel {
- /**
- * Construct an inspector widget.
- */
- constructor() {
- super();
- this.addClass(ITEM_CLASS);
- this.update();
- }
- /**
- * The text of the inspector.
- */
- get content(): Widget {
- return this._content;
- }
- set content(newValue: Widget) {
- if (newValue === this._content) {
- return;
- }
- if (this._content) {
- if (this._remember) {
- this._content.hide();
- } else {
- this._content.dispose();
- }
- }
- this._content = newValue;
- if (this._content) {
- this._content.addClass(CONTENT_CLASS);
- this.addChild(this._content);
- if (this.remember) {
- this._history.push(newValue);
- this._index++;
- }
- }
- }
- /**
- * The display orientation of the inspector widget.
- */
- get orientation(): Inspector.Orientation {
- return this._orientation;
- }
- set orientation(newValue: Inspector.Orientation) {
- if (newValue === this._orientation) {
- return;
- }
- this._orientation = newValue;
- this.update();
- }
- /**
- * A signal emitted when an inspector widget's orientation is toggled.
- */
- get orientationToggled(): ISignal<InspectorItem, void> {
- return Private.orientationToggledSignal.bind(this);
- }
- /**
- * A flag that indicates whether the inspector remembers history.
- */
- get remember(): boolean {
- return this._remember;
- }
- set remember(newValue: boolean) {
- if (newValue === this._remember) {
- return;
- }
- this._clear();
- this._remember = newValue;
- if (!this.remember) {
- this._history = null;
- }
- this.update();
- }
- /**
- * The display rank of the inspector.
- */
- get rank(): number {
- return this._rank;
- }
- set rank(newValue: number) {
- this._rank = newValue;
- }
- /**
- * Dispose of the resources held by the widget.
- */
- dispose(): void {
- if (this.isDisposed) {
- return;
- }
- clearSignalData(this);
- if (this._history) {
- this._history.forEach(widget => widget.dispose());
- this._history = null;
- }
- if (this._toolbar) {
- this._toolbar.dispose();
- }
- super.dispose();
- }
- /**
- * Handle `update_request` messages.
- */
- protected onUpdateRequest(msg: Message): void {
- if (this._toolbar) {
- this._toolbar.dispose();
- }
- this._toolbar = this._createToolbar();
- this.insertChild(0, this._toolbar);
- }
- /**
- * Navigate back in history.
- */
- private _back(): void {
- if (this._history.length) {
- this._navigateTo(Math.max(this._index - 1, 0));
- }
- }
- /**
- * Clear history.
- */
- private _clear(): void {
- if (this._history) {
- this._history.forEach(widget => widget.dispose());
- }
- this._history = [];
- this._index = -1;
- }
- /**
- * Navigate forward in history.
- */
- private _forward(): void {
- if (this._history.length) {
- this._navigateTo(Math.min(this._index + 1, this._history.length - 1));
- }
- }
- /**
- * Create a history toolbar.
- */
- private _createToolbar(): NotebookToolbar {
- let toolbar = new NotebookToolbar();
- let toggle = new ToolbarButton({
- className: this.orientation === 'vertical' ? RIGHT_TOGGLE_CLASS
- : BOTTOM_TOGGLE_CLASS,
- onClick: () => this.orientationToggled.emit(void 0),
- tooltip: 'Toggle the inspector orientation.'
- });
- toolbar.add('toggle', toggle);
- if (!this._remember) {
- return toolbar;
- }
- let clear = new ToolbarButton({
- className: CLEAR_CLASS,
- onClick: () => this._clear(),
- tooltip: 'Clear history.'
- });
- toolbar.add('clear', clear);
- let back = new ToolbarButton({
- className: BACK_CLASS,
- onClick: () => this._back(),
- tooltip: 'Navigate back in history.'
- });
- toolbar.add('back', back);
- let forward = new ToolbarButton({
- className: FORWARD_CLASS,
- onClick: () => this._forward(),
- tooltip: 'Navigate forward in history.'
- });
- toolbar.add('forward', forward);
- return toolbar;
- }
- /**
- * Navigate to a known index in history.
- */
- private _navigateTo(index: number): void {
- if (this._content) {
- this._content.hide();
- }
- this._content = this._history[index];
- this._index = index;
- this._content.show();
- }
- private _content: Widget = null;
- private _history: Widget[] = null;
- private _index: number = -1;
- private _orientation: Inspector.Orientation = 'horizontal';
- private _rank: number = Infinity;
- private _remember: boolean = false;
- private _toolbar: NotebookToolbar = null;
- }
- /**
- * A namespace for inspector private data.
- */
- namespace Private {
- /**
- * A signal emitted when an inspector's orientation is toggled.
- */
- export
- const orientationToggledSignal = new Signal<InspectorItem, void>();
- }
|