Skip to content

Tools are not reinializing for other tabs [custom plugin built with cornerstone] #1571

@imran-khani

Description

@imran-khani

Issue: Tools Not Reinitializing for Other Tabs

Description

I'm encountering an issue with Cornerstone tools where they are not reinitializing properly when switching between tabs. I have a setup where multiple DICOM viewers are initialized within tabs, and the tools need to be reinitialized each time a tab is switched. However, it seems that the tools are not being set up correctly for the new active tab, causing the tools to not work as expected.

Steps to Reproduce

  1. Initialize multiple DICOM viewers within tabs.
  2. Switch between the tabs.
  3. Observe that the tools are not reinitialized properly for the newly active tab.

Expected Behavior

The tools should be reinitialized and activated correctly for each tab when it becomes active.

Actual Behavior

The tools are not reinitialized, causing issues with tool activation and functionality in the newly active tab.

Code Example

Here is a simplified version of my code:

document.addEventListener('DOMContentLoaded', function(){
  initializeDICOMViewer();
});

function initializeDICOMViewer(){
  cornerstoneWADOImageLoader.external.cornerstone = cornerstone;
  cornerstoneWADOImageLoader.external.dicomParser = dicomParser;
  cornerstoneWADOImageLoader.webWorkerManager.initialize({
    maxWebWorkers: navigator.hardwareConcurrency || 1,
    startWebWorkersOnDemand: true,
    taskConfiguration: {
      decodeTask: {
        initializeCodecsOnStartup: false,
        usePDFJS: false,
        strict: false
      }
    }
  });

  cornerstoneTools.init({
    globalToolSyncEnabled: true,
  });

  setupViewerContainers();
  setupToolButtons();
}

function setupViewerContainers(){
  const containers = document.querySelectorAll('.dcm-container');
  containers.forEach((container, containerIndex) => {
    initializeContainer(container, container.dataset.instance || containerIndex);
  });
}

function initializeContainer(container, instance){
  const images = dicomImageFiles[instance];
  if (!images || images.length === 0) {
    return;
  }

  const viewersContainer = container.querySelector('.dcm-viewers');
  const viewerElement = document.createElement('div');
  viewerElement.className = 'dcm-viewer';
  viewerElement.style.width = '100%';
  viewerElement.style.height = '500px';
  viewerElement.setAttribute('data-active-tool', 'Wwwc');
  viewersContainer.appendChild(viewerElement);

  cornerstone.enable(viewerElement);

  viewers.push({
    element: viewerElement,
    containerIndex: instance,
    instance: instance,
    images: images,
    currentImageIndex: 0,
    loaded: false
  });

  setupTools(viewerElement);
  loadImage(viewers[viewers.length - 1]); // Load the first image immediately
}

function setupTools(element){
  const tools = [
    { toolName: 'PanTool', options: {} },
    {
      toolName: 'ZoomTool',
      options: { configuration: { invert: false, preventHandleOutsideImage: false, minScale: 0.1, maxScale: 20.0 } }
    },
    { toolName: 'WwwcTool', options: {} },
    { toolName: 'LengthTool', options: {} },
    { toolName: 'ProbeTool', options: {} },
    { toolName: 'AngleTool', options: {} },
    { toolName: 'EllipticalRoiTool', options: {} },
    { toolName: 'RectangleRoiTool', options: {} },
    { toolName: 'RotateTool', options: {} }
  ];

  tools.forEach(({ toolName, options }) => {
    cornerstoneTools.addTool(cornerstoneTools[toolName], options);
  });

  cornerstoneTools.setToolActiveForElement(element, 'WwwcTool', { mouseButtonMask: 1 });
  cornerstoneTools.setToolActiveForElement(element, 'ZoomTool', { mouseButtonMask: 2 });
}

function loadImage(viewer){
  const imageId = `wadouri:${viewer.images[viewer.currentImageIndex]}`;
  cornerstone.loadAndCacheImage(imageId).then(image => {
    cornerstone.displayImage(viewer.element, image);
    cornerstone.resize(viewer.element, true);
    cornerstone.fitToWindow(viewer.element);
    viewer.loaded = true;
    if (!viewer.scrollHandlerSet) {
      setupScrollHandler(viewer);
      viewer.scrollHandlerSet = true;
    }
    setupTools(viewer.element); // Ensure tools are re-initialized
  }).catch(error => {
    console.error('Error loading image:', error);
  });
}

function setupScrollHandler(viewer){
  viewer.element.addEventListener('wheel', (event) => {
    event.preventDefault();
    if (event.deltaY > 0) {
      viewer.currentImageIndex = (viewer.currentImageIndex + 1) % viewer.images.length;
    } else {
      viewer.currentImageIndex = (viewer.currentImageIndex - 1 + viewer.images.length) % viewer.images.length;
    }
    loadImage(viewer);
  });
}

function activateTool(tool, container){
  const viewerElement = container.querySelector('.dcm-viewer');
  viewerElement.setAttribute('data-active-tool', tool);
  if (tool === 'Reset') {
    resetImage(viewerElement);
  } else {
    const toolName = tool === 'WindowLevel' ? 'Wwwc' : tool;
    cornerstoneTools.setToolActiveForElement(viewerElement, toolName, { mouseButtonMask: 1 });
  }
}

function handleTabSwitch(){
  const activePanel = document.querySelector('.wonderplugintabs-panel-active');   
  if (activePanel) {
    const container = activePanel.querySelector('.dcm-container');
    if (container) {
      const viewer = viewers.find(v => v.element.closest('.dcm-container') === container);
      if (viewer) {
        loadImage(viewer);
      } else {
        initializeContainer(container, container.dataset.instance);
      }
    }
  }
}

document.querySelectorAll('.wonderplugintabs-header-li').forEach(header => {
  header.addEventListener('click', function(){
    setTimeout(() => {
      handleTabSwitch();
    }, 500);
  });
});

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions