// Copyright (c) Jupyter Development Team. // Distributed under the terms of the Modified BSD License. import { DOMWidgetView, unpack_models, ViewList, JupyterLuminoPanelWidget, reject, WidgetModel, WidgetView, } from '@jupyter-widgets/base'; import { CoreDOMWidgetModel } from './widget_core'; import { ArrayExt } from '@lumino/algorithm'; import { MessageLoop } from '@lumino/messaging'; import { Widget } from '@lumino/widgets'; import $ from 'jquery'; export class BoxModel extends CoreDOMWidgetModel { defaults(): Backbone.ObjectHash { return { ...super.defaults(), _view_name: 'BoxView', _model_name: 'BoxModel', children: [], box_style: '', }; } static serializers = { ...CoreDOMWidgetModel.serializers, children: { deserialize: unpack_models }, }; } export class HBoxModel extends BoxModel { defaults(): Backbone.ObjectHash { return { ...super.defaults(), _view_name: 'HBoxView', _model_name: 'HBoxModel', }; } } export class VBoxModel extends BoxModel { defaults(): Backbone.ObjectHash { return { ...super.defaults(), _view_name: 'VBoxView', _model_name: 'VBoxModel', }; } } export class BoxView extends DOMWidgetView { _createElement(tagName: string): HTMLElement { this.luminoWidget = new JupyterLuminoPanelWidget({ view: this }); return this.luminoWidget.node; } _setElement(el: HTMLElement): void { if (this.el || el !== this.luminoWidget.node) { // Boxes don't allow setting the element beyond the initial creation. throw new Error('Cannot reset the DOM element.'); } this.el = this.luminoWidget.node; this.$el = $(this.luminoWidget.node); } initialize(parameters: WidgetView.IInitializeParameters): void { super.initialize(parameters); this.children_views = new ViewList(this.add_child_model, null, this); this.listenTo(this.model, 'change:children', this.update_children); this.listenTo(this.model, 'change:box_style', this.update_box_style); this.luminoWidget.addClass('jupyter-widgets'); this.luminoWidget.addClass('widget-container'); this.luminoWidget.addClass('widget-box'); } render(): void { super.render(); this.update_children(); this.set_box_style(); } update_children(): void { this.children_views ?.update(this.model.get('children')) .then((views: DOMWidgetView[]) => { // Notify all children that their sizes may have changed. views.forEach((view) => { MessageLoop.postMessage( view.luminoWidget, Widget.ResizeMessage.UnknownSize ); }); }); } update_box_style(): void { this.update_mapped_classes(BoxView.class_map, 'box_style'); } set_box_style(): void { this.set_mapped_classes(BoxView.class_map, 'box_style'); } add_child_model(model: WidgetModel): Promise { // we insert a dummy element so the order is preserved when we add // the rendered content later. const dummy = new Widget(); this.luminoWidget.addWidget(dummy); return this.create_child_view(model) .then((view: DOMWidgetView) => { // replace the dummy widget with the new one. const i = ArrayExt.firstIndexOf(this.luminoWidget.widgets, dummy); this.luminoWidget.insertWidget(i, view.luminoWidget); dummy.dispose(); return view; }) .catch(reject('Could not add child view to box', true)); } remove(): void { this.children_views = null; super.remove(); } children_views: ViewList | null; luminoWidget: JupyterLuminoPanelWidget; static class_map = { success: ['alert', 'alert-success'], info: ['alert', 'alert-info'], warning: ['alert', 'alert-warning'], danger: ['alert', 'alert-danger'], }; } export class HBoxView extends BoxView { /** * Public constructor */ initialize(parameters: WidgetView.IInitializeParameters): void { super.initialize(parameters); this.luminoWidget.addClass('widget-hbox'); } } export class VBoxView extends BoxView { /** * Public constructor */ initialize(parameters: WidgetView.IInitializeParameters): void { super.initialize(parameters); this.luminoWidget.addClass('widget-vbox'); } } export class GridBoxView extends BoxView { /** * Public constructor */ initialize(parameters: WidgetView.IInitializeParameters): void { super.initialize(parameters); this.luminoWidget.addClass('widget-gridbox'); // display needn't be set to flex and grid this.luminoWidget.removeClass('widget-box'); } } export class GridBoxModel extends BoxModel { defaults(): Backbone.ObjectHash { return { ...super.defaults(), _view_name: 'GridBoxView', _model_name: 'GridBoxModel', }; } }