315 lines
11 KiB
Plaintext
315 lines
11 KiB
Plaintext
var viewport_active = null;
|
|
var viewerContainer = null;
|
|
var layoutManager = null;
|
|
var viewport_template = null;
|
|
|
|
var _gel = (a) => { return document.getElementById(a); };
|
|
var _dqs = (a) => { return document.querySelectorAll(a); };
|
|
var _gec = (a) => { return document.getElementsByClassName(a); };
|
|
var _oY = (a) => { return a.offsetTop; };
|
|
var _oX = (a) => { return a.offsetLeft; };
|
|
var _pos = (el) => { for (var lx=0, ly=0;el != null;lx += el.offsetLeft, ly += el.offsetTop, el = el.offsetParent); return {x: lx,y: ly}; };
|
|
var _rmc = (el) => { while (el.lastChild) { el.removeChild(el.lastChild); } };
|
|
// draggable item
|
|
var dragstart = (ev) => { ev.dataTransfer.setData("text", ev.target.id); ev.target.style.opacity = .5; };
|
|
var dragend = (ev) => { ev.target.style.opacity = 1; };
|
|
// dropable container
|
|
var dragover = (ev) => { ev.preventDefault(); };
|
|
var dragenter = (ev) => { ev.target.parentNode.style.opacity = .5; };
|
|
var dragleave = (ev) => { ev.target.parentNode.style.opacity = 1; };
|
|
|
|
function loadTemplate(url,callback) {
|
|
http = new XMLHttpRequest();
|
|
http.open("GET", url, true);
|
|
http.onreadystatechange = function() {
|
|
if(http.readyState == 4 && http.status == 200) {
|
|
var parser = new DOMParser();
|
|
var dom = parser.parseFromString(http.responseText, 'text/html');
|
|
callback(dom.getElementsByClassName('viewportContainer')[0]);
|
|
}
|
|
};
|
|
http.send();
|
|
}
|
|
|
|
|
|
function init_thumbnail_drag() {
|
|
var ts = _gec('thumbnailEntry');
|
|
[].forEach.call(ts, function (el) {
|
|
el.addEventListener('dragstart',dragstart);
|
|
el.addEventListener('dragend',dragend);
|
|
});
|
|
}
|
|
|
|
function init_viewport_drop() {
|
|
var vps = viewerContainer.childNodes;
|
|
vps.forEach(function(el) {
|
|
el.addEventListener('dragover',dragover,false);
|
|
el.addEventListener('dragenter',dragenter,false);
|
|
el.addEventListener('dragleave',dragleave,false);
|
|
el.addEventListener('drop',function(ev) {
|
|
ev.preventDefault();
|
|
var thumb_id = ev.dataTransfer.getData("text");
|
|
ev.target.parentNode.style.opacity = 1;
|
|
var series_iuid = _gel(thumb_id).getAttribute('data-value');
|
|
console.log('dropped at',el.idx,series_iuid);
|
|
},false);
|
|
});
|
|
}
|
|
|
|
function viewportSetActive(d) {
|
|
var vps = viewerContainer.childNodes;
|
|
vps.forEach(function(el) {
|
|
el.classList.remove('active');
|
|
});
|
|
d.classList.add('active');
|
|
viewport_active = d;
|
|
console.log('Active viewport: '+d.idx);
|
|
}
|
|
|
|
function init_layout() {
|
|
layoutManager = _gel('layoutManagerTarget');
|
|
viewerContainer = _gel('imageViewerViewports');
|
|
layoutManager.stacks = [];
|
|
layoutManager.viewport_idx = {};
|
|
layoutManager.setLayout = function(y,x) {
|
|
/// render layout
|
|
layoutManager.className = 'layout-'+y+'-'+x;
|
|
_rmc(viewerContainer);
|
|
layoutManager.viewports = [];
|
|
var w = 100/x;
|
|
var h = 100/y;
|
|
var row_top = 1;
|
|
var row_middle = 0;
|
|
var row_bottom = 0;
|
|
if(y>2) {
|
|
row_bottom = 1;
|
|
row_middle = y-2;
|
|
} else if(y==2) {
|
|
row_bottom = 1;
|
|
}
|
|
/// add top
|
|
for(var j=1;j<=x;j++) {
|
|
var vp = viewport_template.cloneNode(true);
|
|
vp.style.height = h+'%';
|
|
vp.style.width = w+'%';
|
|
vp.classList.add('top');
|
|
vp.idx = 1+'x'+j;
|
|
layoutManager.viewport_idx[vp.idx] = layoutManager.viewports.length;
|
|
vp.addEventListener('click',function(e) { viewportSetActive(this); });
|
|
layoutManager.viewports.push(viewerContainer.appendChild(vp));
|
|
if(vp.idx=='1x1') viewportSetActive(vp);
|
|
}
|
|
/// add middle
|
|
for(var i=1;i<=row_middle;i++) {
|
|
for(var j=1;j<=x;j++) {
|
|
var vp = viewport_template.cloneNode(true);
|
|
vp.style.height = h+'%';
|
|
vp.style.width = w+'%';
|
|
vp.classList.add('middle');
|
|
vp.idx = (i+1)+'x'+j;
|
|
layoutManager.viewport_idx[vp.idx] = layoutManager.viewports.length;
|
|
vp.addEventListener('click',function(e) { viewportSetActive(this); });
|
|
layoutManager.viewports.push(viewerContainer.appendChild(vp));
|
|
}
|
|
}
|
|
/// add bottom
|
|
if(row_bottom==1) {
|
|
for(var j=1;j<=x;j++) {
|
|
var vp = viewport_template.cloneNode(true);
|
|
vp.style.height = h+'%';
|
|
vp.style.width = w+'%';
|
|
vp.classList.add('bottom');
|
|
vp.idx = y+'x'+j;
|
|
layoutManager.viewport_idx[vp.idx] = layoutManager.viewports.length;
|
|
vp.addEventListener('click',function(e) { viewportSetActive(this); });
|
|
layoutManager.viewports.push(viewerContainer.appendChild(vp));
|
|
}
|
|
}
|
|
|
|
layoutManager.forEachElement(function(vp) {
|
|
cornerstone.enable(vp);
|
|
});
|
|
|
|
init_viewport_drop();
|
|
|
|
};
|
|
|
|
layoutManager.forEachElement = function(cb) {
|
|
layoutManager.viewports.forEach(function(vp, i){
|
|
cb.call(self, vp.getElementsByClassName('imageViewerViewport')[0], vp, i);
|
|
});
|
|
}
|
|
}
|
|
|
|
function useStack(viewport_idx,stack) {
|
|
var imageId = layoutManager.stacks[stack].imageIds[0];
|
|
var idx = layoutManager.viewport_idx[viewport_idx];
|
|
var viewport = layoutManager.viewports[idx].getElementsByClassName('imageViewerViewport')[0];
|
|
displayImage(imageId,viewport,layoutManager.stacks[stack],function(el) {
|
|
if(!el.setup||(el.setup!=true)) {
|
|
setupViewport(el, layoutManager.stacks[stack], this);
|
|
el.setup = true;
|
|
}
|
|
});
|
|
layoutManager.viewports[idx].getElementsByClassName('viewportInstructions')[0].style.display = 'none';
|
|
}
|
|
|
|
function displayImage(imageId,viewport,stack,loaded) {
|
|
var enabledImage = cornerstone.getEnabledElement(viewport);
|
|
if (enabledImage.image) {
|
|
// Stop clip from if playing on element
|
|
cornerstoneTools.stopClip(viewport);
|
|
// Disable stack scrolling
|
|
cornerstoneTools.stackScroll.disable(viewport);
|
|
// Enable stackScroll on selected series
|
|
cornerstoneTools.stackScroll.enable(viewport);
|
|
}
|
|
|
|
// Load the first image of the selected series stack
|
|
cornerstone.loadAndCacheImage(imageId).then(function(image) {
|
|
if (loaded) {
|
|
loaded.call(image, viewport, stack);
|
|
}
|
|
|
|
// Get the state of the stack tool
|
|
var stackState = cornerstoneTools.getToolState(viewport, 'stack');
|
|
console.log(stackState);
|
|
stackState.data[0] = stack;
|
|
stackState.data[0].currentImageIdIndex = 0;
|
|
|
|
// Get the default viewport
|
|
var defViewport = cornerstone.getDefaultViewport(viewport, image);
|
|
// Get the current series stack index
|
|
// Display the image
|
|
cornerstone.displayImage(viewport, image, defViewport);
|
|
// Fit the image to the viewport window
|
|
cornerstone.fitToWindow(viewport);
|
|
|
|
cornerstoneTools.mouseInput.enable(viewport);
|
|
|
|
// Prefetch the remaining images in the stack (?)
|
|
cornerstoneTools.stackPrefetch.enable(viewport);
|
|
cornerstoneTools.mouseWheelInput.enable(viewport);
|
|
|
|
// Play clip if stack is a movie (has framerate)
|
|
if (stack.frameRate !== undefined) {
|
|
cornerstoneTools.playClip(viewport, stack.frameRate);
|
|
}
|
|
});
|
|
|
|
}
|
|
|
|
function resizeMain() {
|
|
layoutManager.forEachElement(function(el, vp) {
|
|
cornerstone.resize(el, true);
|
|
cornerstone.fitToWindow(el);
|
|
});
|
|
}
|
|
|
|
function setupViewport(element, stack, image) {
|
|
// Display the image on the viewer element
|
|
cornerstone.displayImage(element, image);
|
|
|
|
// If it's a movie (has frames), then play the clip
|
|
if (stack.frameRate !== undefined) {
|
|
cornerstone.playClip(element, stack.frameRate);
|
|
}
|
|
|
|
// Activate mouse clicks, mouse wheel and touch
|
|
cornerstoneTools.mouseInput.enable(element);
|
|
cornerstoneTools.mouseWheelInput.enable(element);
|
|
// cornerstoneTools.touchInput.enable(element);
|
|
|
|
// Enable all tools we want to use with this element
|
|
// cornerstoneTools.wwwc.activate(element, 1); // ww/wc is the default tool for left mouse button
|
|
// cornerstoneTools.pan.activate(element, 2); // pan is the default tool for middle mouse button
|
|
// cornerstoneTools.zoom.activate(element, 4); // zoom is the default tool for right mouse button
|
|
// cornerstoneTools.probe.enable(element);
|
|
// cornerstoneTools.length.enable(element);
|
|
// cornerstoneTools.ellipticalRoi.enable(element);
|
|
// cornerstoneTools.rectangleRoi.enable(element);
|
|
// cornerstoneTools.wwwcTouchDrag.activate(element);
|
|
// cornerstoneTools.zoomTouchPinch.activate(element);
|
|
cornerstoneTools.stackScroll.activate(element,1);
|
|
|
|
// Stack tools
|
|
cornerstoneTools.addStackStateManager(element, ['stack']);
|
|
cornerstoneTools.addToolState(element, 'stack', stack);
|
|
cornerstoneTools.stackScrollWheel.activate(element);
|
|
cornerstoneTools.stackPrefetch.enable(element);
|
|
}
|
|
|
|
function enable_tools() {
|
|
|
|
// sidebar button
|
|
var sidebar = _dqs('[data-value="studies"]')[0];
|
|
sidebar.intransition = false;
|
|
sidebar.addEventListener('click',function(e) {
|
|
var c = this.classList.toggle('active');
|
|
_gec('sidebarMenu sidebar-left')[0].classList.toggle('sidebar-open');
|
|
_gec('mainContent')[0].classList.toggle('sidebar-left-open');
|
|
sidebar.intransition = true;
|
|
// sidebar.t = setInterval(resizeMain,100);
|
|
},false);
|
|
|
|
sidebar.addEventListener('transitionend',function(e) {
|
|
// clearInterval(sidebar.t);
|
|
resizeMain();
|
|
sidebar.intransition = false;
|
|
},false);
|
|
|
|
/// layout chooser
|
|
var lc = _gel('layoutChooser');
|
|
lc.getElementsByTagName('table')[0].addEventListener('mouseover', function(e) {
|
|
var y = e.target.parentElement.rowIndex;
|
|
var x = e.target.cellIndex;
|
|
for(var i=0;i<=3;i++) {
|
|
for(var j=0;j<=3;j++) {
|
|
if(!isNaN(y) && i<=y) {
|
|
if(!isNaN(x) && j<=x) {
|
|
this.rows[i].cells[j].className = 'hover';
|
|
} else {
|
|
this.rows[i].cells[j].className = '';
|
|
}
|
|
} else {
|
|
this.rows[i].cells[j].className = '';
|
|
}
|
|
}
|
|
}
|
|
lc.x = x+1;
|
|
lc.y = y+1;
|
|
}, false);
|
|
|
|
lc.getElementsByTagName('table')[0].addEventListener('click', function(e) {
|
|
var y = e.target.parentElement.rowIndex+1;
|
|
var x = e.target.cellIndex+1;
|
|
console.log('Layout selected : '+y+'x'+x);
|
|
lc.classList.toggle('open');
|
|
lc.classList.toggle('dialog-open');
|
|
layoutManager.setLayout(y,x);
|
|
}, false);
|
|
|
|
var lb = _gel('layout');
|
|
lb.addEventListener('click',function(e) {
|
|
lc.classList.toggle('open');
|
|
lc.classList.toggle('dialog-open');
|
|
lc.style.top = (_pos(this).y+parseInt(this.offsetHeight))+'px';
|
|
lc.style.left = (_pos(this).x)+'px';
|
|
},false);
|
|
}
|
|
|
|
function init_final() {
|
|
|
|
init_thumbnail_drag();
|
|
|
|
// Call resize main on window resize
|
|
window.addEventListener('resize',function() {
|
|
resizeMain();
|
|
});
|
|
|
|
// Prevent scrolling on iOS
|
|
document.body.addEventListener('touchmove', function(e) {
|
|
e.preventDefault();
|
|
});
|
|
}
|