Skip to content

Commit 32b4140

Browse files
authored
Merge pull request #73 from hbcarlos/widgets
Add support for widgets
2 parents 9625129 + 9031003 commit 32b4140

File tree

8 files changed

+618
-310
lines changed

8 files changed

+618
-310
lines changed

packages/blockly-extension/package.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,11 @@
4343
"watch:labextension": "jupyter labextension watch ."
4444
},
4545
"dependencies": {
46+
"@jupyter-widgets/base": "^6.0.4",
47+
"@jupyter-widgets/jupyterlab-manager": "^5.0.7",
4648
"@jupyterlab/application": "^3.6",
4749
"@jupyterlab/apputils": "^3.6",
50+
"@jupyterlab/cells": "^3.6",
4851
"@jupyterlab/codeeditor": "^3.6",
4952
"@jupyterlab/filebrowser": "^3.6",
5053
"@jupyterlab/launcher": "^3.6",
@@ -81,6 +84,14 @@
8184
"blockly": {
8285
"bundled": true,
8386
"singleton": true
87+
},
88+
"@jupyter-widgets/base": {
89+
"bundled": false,
90+
"singleton": true
91+
},
92+
"@jupyter-widgets/jupyterlab-manager": {
93+
"bundled": false,
94+
"singleton": true
8495
}
8596
},
8697
"webpackConfig": "./webpack.config.js"

packages/blockly-extension/src/index.ts

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,20 @@ import { jsonIcon } from '@jupyterlab/ui-components';
77
import { WidgetTracker, ICommandPalette } from '@jupyterlab/apputils';
88
import { IRenderMimeRegistry } from '@jupyterlab/rendermime';
99
import { IEditorServices } from '@jupyterlab/codeeditor';
10+
import { CodeCell } from '@jupyterlab/cells';
1011
import { IFileBrowserFactory } from '@jupyterlab/filebrowser';
1112
import { ILauncher } from '@jupyterlab/launcher';
1213
import { ITranslator } from '@jupyterlab/translation';
1314
import { ISettingRegistry } from '@jupyterlab/settingregistry';
1415
import { IKernelMenu, IMainMenu } from '@jupyterlab/mainmenu';
1516

17+
import { IJupyterWidgetRegistry } from '@jupyter-widgets/base';
18+
19+
import {
20+
WidgetRenderer,
21+
registerWidgetManager
22+
} from '@jupyter-widgets/jupyterlab-manager';
23+
1624
import { BlocklyEditorFactory } from 'jupyterlab-blockly';
1725
import { IBlocklyRegistry } from 'jupyterlab-blockly';
1826
import { BlocklyEditor } from 'jupyterlab-blockly';
@@ -49,7 +57,7 @@ const plugin: JupyterFrontEndPlugin<IBlocklyRegistry> = {
4957
ISettingRegistry,
5058
ITranslator
5159
],
52-
optional: [ILauncher, ICommandPalette, IMainMenu],
60+
optional: [ILauncher, ICommandPalette, IMainMenu, IJupyterWidgetRegistry],
5361
provides: IBlocklyRegistry,
5462
activate: (
5563
app: JupyterFrontEnd,
@@ -61,7 +69,8 @@ const plugin: JupyterFrontEndPlugin<IBlocklyRegistry> = {
6169
translator: ITranslator,
6270
launcher: ILauncher | null,
6371
palette: ICommandPalette | null,
64-
mainMenu: IMainMenu | null
72+
mainMenu: IMainMenu | null,
73+
widgetRegistry: IJupyterWidgetRegistry | null
6574
): IBlocklyRegistry => {
6675
console.log('JupyterLab extension jupyterlab-blocky is activated!');
6776

@@ -233,8 +242,34 @@ const plugin: JupyterFrontEndPlugin<IBlocklyRegistry> = {
233242
} as IKernelMenu.IKernelUser<BlocklyEditor>);
234243
}
235244

245+
if (widgetRegistry) {
246+
tracker.forEach(panel => {
247+
registerWidgetManager(
248+
panel.context as any,
249+
panel.content.rendermime,
250+
widgetRenderers([panel.content.cell])
251+
);
252+
});
253+
254+
tracker.widgetAdded.connect((sender, panel) => {
255+
registerWidgetManager(
256+
panel.context as any,
257+
panel.content.rendermime,
258+
widgetRenderers([panel.content.cell])
259+
);
260+
});
261+
}
262+
236263
return widgetFactory.registry;
237264
}
238265
};
239266

267+
function* widgetRenderers(cells: CodeCell[]): IterableIterator<WidgetRenderer> {
268+
for (const w of cells) {
269+
if (w instanceof WidgetRenderer) {
270+
yield w;
271+
}
272+
}
273+
}
274+
240275
export default plugin;

packages/blockly/src/factory.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ export class BlocklyEditorFactory extends ABCWidgetFactory<
4646
protected createNewWidget(
4747
context: DocumentRegistry.IContext<DocumentModel>
4848
): BlocklyEditor {
49+
// Set a map to the model. The widgets manager expects a Notebook model
50+
// but the only notebook property it uses is the metadata.
51+
context.model['metadata'] = new Map();
4952
const manager = new BlocklyManager(
5053
this._registry,
5154
context.sessionContext,

packages/blockly/src/layout.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,25 @@ export class BlocklyLayout extends SplitLayout {
5757
this._manager.changed.connect(this._onManagerChanged, this);
5858
}
5959

60+
/*
61+
* The code cell.
62+
*/
63+
get cell(): CodeCell {
64+
return this._cell;
65+
}
66+
67+
/*
68+
* The current workspace.
69+
*/
6070
get workspace(): Blockly.Workspace {
6171
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
6272
// @ts-ignore
6373
return Blockly.serialization.workspaces.save(this._workspace);
6474
}
6575

76+
/*
77+
* Set a new workspace.
78+
*/
6679
set workspace(workspace: Blockly.Workspace) {
6780
const data = workspace === null ? { variables: [] } : workspace;
6881
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
@@ -138,12 +151,16 @@ export class BlocklyLayout extends SplitLayout {
138151
return finalToplevelInit;
139152
}
140153

154+
/*
155+
* Generates and runs the code from the current workspace.
156+
*/
141157
run(): void {
142158
// Get extra code from the blocks in the workspace.
143159
const extra_init = this.getBlocksToplevelInit();
144160
// Serializing our workspace into the chosen language generator.
145161
const code =
146162
extra_init + this._manager.generator.workspaceToCode(this._workspace);
163+
//const code = "import ipywidgets as widgets\nwidgets.IntSlider()";
147164
this._cell.model.sharedModel.setSource(code);
148165

149166
// Execute the code using the kernel, by using a static method from the

packages/blockly/src/widget.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
SelectToolbox,
2020
Spacer
2121
} from './toolbar';
22+
import { CodeCell } from '@jupyterlab/cells';
2223

2324
/**
2425
* DocumentWidget: widget that represents the view or editor for a file type.
@@ -80,6 +81,7 @@ export namespace BlocklyEditor {
8081
*/
8182
export class BlocklyPanel extends SplitPanel {
8283
private _context: DocumentRegistry.IContext<DocumentModel>;
84+
private _rendermime: IRenderMimeRegistry;
8385

8486
/**
8587
* Construct a `BlocklyPanel`.
@@ -96,13 +98,28 @@ export class BlocklyPanel extends SplitPanel {
9698
});
9799
this.addClass('jp-BlocklyPanel');
98100
this._context = context;
101+
this._rendermime = rendermime;
99102

100103
// Load the content of the file when the context is ready
101104
this._context.ready.then(() => this._load());
102105
// Connect to the save signal
103106
this._context.saveState.connect(this._onSave, this);
104107
}
105108

109+
/*
110+
* The code cell.
111+
*/
112+
get cell(): CodeCell {
113+
return (this.layout as BlocklyLayout).cell;
114+
}
115+
116+
/*
117+
* The rendermime instance used in the code cell.
118+
*/
119+
get rendermime(): IRenderMimeRegistry {
120+
return this._rendermime;
121+
}
122+
106123
/**
107124
* Dispose of the resources held by the widget.
108125
*/

pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ classifiers = [
2323
"Programming Language :: Python :: 3.11",
2424
]
2525
dependencies = [
26-
"jupyterlab~=3.6"
26+
"jupyterlab~=3.6",
27+
"jupyterlab_widgets~=3.0"
2728
]
2829
dynamic = ["version", "description", "authors", "urls", "keywords"]
2930

0 commit comments

Comments
 (0)