Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add drop down menu for commands #5

Merged
merged 3 commits into from
Nov 29, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 84 additions & 5 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@
/* eslint-disable prettier/prettier */

import { JupyterFrontEnd, JupyterFrontEndPlugin } from '@jupyterlab/application'
import { ICommandPalette } from '@jupyterlab/apputils'
import { INotebookTracker } from '@jupyterlab/notebook'
import { ICommandPalette, ToolbarButton } from '@jupyterlab/apputils'
import { INotebookTracker, NotebookPanel } from '@jupyterlab/notebook'
import { Cell } from '@jupyterlab/cells'

import { Scope, apply_on_cells } from 'jupyterlab-celltagsclasses'
import { md_toggle_multi } from 'jupyterlab-celltagsclasses'
import { Menu } from '@lumino/widgets'

const PLUGIN_ID = 'jupyterlab-gridwidth:plugin'

Expand Down Expand Up @@ -54,7 +55,7 @@ const plugin: JupyterFrontEndPlugin<void> = {
const [num, den] = gridwidth.split('-')
command = `gridwidth:toggle-${num}-${den}`
app.commands.addCommand(command, {
label: `cell to take ${num}/${den} space (toggle)`,
label: `Toogle Cell to ${num}/${den} of Full Width`,
execute: () =>
apply_on_cells(notebookTracker, Scope.Active, (cell: Cell) => {
md_toggle_multi(
Expand All @@ -75,10 +76,10 @@ const plugin: JupyterFrontEndPlugin<void> = {
// a shortcut to cancel all gridwidths
command = 'gridwidth:cancel'
app.commands.addCommand(command, {
label: 'cancel all gridwidths',
label: 'Restore Full Cell Width',
execute: () =>
apply_on_cells(notebookTracker, Scope.Active, (cell: Cell) => {
console.log(`cancelling all gridwidths for cell ${cell.model.id}`)
// console.log(`Restore Full Width for Cell ${cell.model.id}`)
md_toggle_multi(cell, 'tags', '', ALL_GRIDWIDTHS_FULL)
})
})
Expand All @@ -88,6 +89,84 @@ const plugin: JupyterFrontEndPlugin<void> = {
keys: ['Alt 0'],
selector: '.jp-Notebook'
})

// activate menu with commands
new CellWidthMenu(app, notebookTracker)
}
}

// a lumino menu & a toolbar button to envok the menu
class CellWidthMenu {
private menuOpen: boolean
private preventOpen: boolean

constructor(app: JupyterFrontEnd, notebookTracker: INotebookTracker) {
this.menuOpen = false
this.preventOpen = false
this.createMenu(app, notebookTracker)
}

createMenu(app: JupyterFrontEnd, notebookTracker: INotebookTracker) {
// create a lumino menu
const menu = new Menu({ commands: app.commands })
menu.title.label = 'Cell Width'

ALL_GRIDWIDTHS.forEach(gridwidth => {
const command = `gridwidth:toggle-${gridwidth.replace('-', '-')}`
menu.addItem({ command })
})

menu.addItem({ type: 'separator' })
menu.addItem({ command: 'gridwidth:cancel' })

/** About to Close Event: When the aboutToClose event of the menu is emitted
* (which happens just before the menu is actually closed),
* the this.menuOpen property is set to false to indicate the menu is not open.
* Simultaneously, this.preventOpen is set to true to prevent the menu from immediately reopening due to subsequent events.
* A setTimeout call is used to reset this.preventOpen to false in the next event loop cycle. */
menu.aboutToClose.connect(() => {
this.menuOpen = false
this.preventOpen = true
// console.log('menu about to close event');
setTimeout(() => {
this.preventOpen = false
// console.log('menu successfully closed and can be opened again.');
}, 0)
// console.log('menu is waiting to be closed... prevent it to open...');
})

// create a toolbar button to envok the menu
const button = new ToolbarButton({
// the icon is similar to the previous split-cell extension button icon
iconClass: 'fa fa-arrows-h',
/** Button Click Event: When the toolbar button is clicked, the click event handler checks the state of this.menuOpen.
* The this.menuOpen is then set to true, indicating the menu is now open.
* If it's true, the menu is currently open and should be closed.
* If this.menuOpen is false and this.preventOpen is also false, the menu is not open and should be opened.
* The rect object represents the button's position, and menu.open positions the menu at the bottom-left of the button.*/
onClick: () => {
// console.log('button clicked');
if (this.menuOpen) {
// Actually not envoked most of the time, no need to manually close the menu here,
// because the menu will be closed automatically when this onClick event emits.
menu.close()
// console.log('menu closed');
} else if (!this.preventOpen) {
const rect = button.node.getBoundingClientRect()
menu.open(rect.left, rect.bottom)
this.menuOpen = true
// console.log('menu opened');
}
},
tooltip: 'Toogle Cell Width'
})

// add the button to the notebook toolbar
notebookTracker.widgetAdded.connect(
(sender, notebookPanel: NotebookPanel) => {
notebookPanel.toolbar.insertItem(10, 'cellWidth', button)
}
)
}
}

Expand Down