diff --git a/niivue/src/components/Menu.ts b/niivue/src/components/Menu.ts index 1da664d..f78a2c4 100644 --- a/niivue/src/components/Menu.ts +++ b/niivue/src/components/Menu.ts @@ -1,7 +1,7 @@ import { html } from 'htm/preact' import { AppProps } from './App' import { Signal, computed, effect, useSignal } from '@preact/signals' -import { addImagesEvent, addOverlayEvent, openImageFromURL } from '../events' +import { addDcmFolderEvent, addImagesEvent, addOverlayEvent, openImageFromURL } from '../events' import { SLICE_TYPE } from '@niivue/niivue' import { ScalingBox } from './ScalingBox' import { getMetadataString, getNumberOfPoints } from '../utility' @@ -170,11 +170,12 @@ export const Menu = (props: AppProps) => { ${!isVscode && html`<${MenuButton} label="Home" onClick=${homeEvent} />`} <${MenuItem} label="Add Image" onClick=${addImagesEvent}> <${MenuEntry} label="File(s)" onClick=${addImagesEvent} /> - <${MenuEntry} label="DICOM Folder" - onClick=${() => console.log('Not implemented yet - dicom folder')} - /> --> + onClick=${addDcmFolderEvent} + /> <${MenuEntry} label="Example Image" onClick=${() => openImageFromURL('https://niivue.github.io/niivue-demo-images/mni152.nii.gz')} /> diff --git a/niivue/src/events.ts b/niivue/src/events.ts index 15741ba..420f540 100644 --- a/niivue/src/events.ts +++ b/niivue/src/events.ts @@ -27,6 +27,12 @@ export function listenToMessages(appProps: AppProps) { nv.isNew = false } break + case 'addDcmFiles': + { + const nv = getUnitinializedNvInstance(nvArray) + readDcmFiles(nv, body.files) + } + break case 'initCanvas': { if (nvArray.value.length === 0 && body.n > 1) { @@ -51,6 +57,30 @@ export function listenToMessages(appProps: AppProps) { addImageFromURLParams() } +function readDcmFiles(nv: ExtendedNiivue, files: File[]): void { + if (files.length > 0) { + const getFileObjects = async (fileList: File[]): Promise => { + return fileList // fileList is already an array of File objects + } + getFileObjects(files) + .then((allFileObjects) => { + NVImage.loadFromFile({ + file: allFileObjects, // an array of file objects + name: allFileObjects[0].name, // Use the first filename + urlImgData: null, // nothing + imageType: 16, // DCM_FOLDER + }) + .then((volume) => nv.addVolume(volume)) + .catch((e) => { + throw e + }) + }) + .catch((e) => { + throw e + }) + } +} + function handleDebugMessage(body: any, appProps: AppProps) { // sending arrays is fine, dataBuffer does not work // sending objects only works with one element inside @@ -256,6 +286,29 @@ export function addImagesEvent() { } } +export function addDcmFolderEvent() { + if (typeof vscode === 'object') { + vscode.postMessage({ type: 'addImages' }) + } else { + const input = document.createElement('input') + input.type = 'file' + input.multiple = false + input.webkitdirectory = true + + input.onchange = async (e) => { + const files = Array.from((e.target as HTMLInputElement).files ?? []) + window.postMessage({ + type: 'addDcmFiles', + body: { + files: files, + }, + }) + } + + input.click() + } +} + function getUnitinializedNvInstance(nvArray: Signal) { const nv = nvArray.value.find((nv) => nv.isNew) if (nv) {