Work towards tabbed panels. Still very broken
This commit is contained in:
parent
9803046f2d
commit
7217b7c67d
@ -1,38 +0,0 @@
|
||||
<template name="toolbar">
|
||||
<div id='toolbar'>
|
||||
<div class="btn-group">
|
||||
<!-- WW/WL -->
|
||||
<button id="wwwc" type="button" class="imageViewerTool btn btn-sm btn-default" data-container="body" data-toggle="tooltip" data-placement="bottom" title="WW/WC"><span class="fa fa-sun-o"></span></button>
|
||||
<!-- Invert -->
|
||||
<button id="invert" type="button" class="imageViewerCommand btn btn-sm btn-default" data-container="body" data-toggle="tooltip" data-placement="bottom" title="Invert"><span class="fa fa-adjust"></span></button>
|
||||
<!-- Zoom -->
|
||||
<button id="zoom" type="button" class="imageViewerTool btn btn-sm btn-default" data-container="body" data-toggle="tooltip" data-placement="bottom" title="Zoom"><span class="fa fa-search"></span></button>
|
||||
<!-- Pan -->
|
||||
<button id="pan" type="button" class="imageViewerTool btn btn-sm btn-default" data-container="body" data-toggle="tooltip" data-placement="bottom" title="Pan"><span class="fa fa-arrows"></span></button>
|
||||
<!-- Stack scroll -->
|
||||
<button id="stackScroll" type="button" class="imageViewerTool btn btn-sm btn-default" data-container="body" data-toggle="tooltip" data-placement="bottom" title="Stack Scroll"><span class="fa fa-bars"></span></button>
|
||||
<!-- Length measurement -->
|
||||
<button id="length" type="button" class="imageViewerTool btn btn-sm btn-default" data-container="body" data-toggle="tooltip" data-placement="bottom" title="Length Measurement"><span class="fa fa-arrows-v"></span></button>
|
||||
<!-- Angle measurement -->
|
||||
<!--<button id="angle" type="button" class="imageViewerTool btn btn-sm btn-default" data-container="body" data-toggle="tooltip" data-placement="bottom" title="Angle Measurement"><span class="fa fa-angle-left"></span></button>-->
|
||||
<!-- Pixel probe -->
|
||||
<button id="dragProbe" type="button" class="imageViewerTool btn btn-sm btn-default" data-container="body" data-toggle="tooltip" data-placement="bottom" title="Pixel Probe"><span class="fa fa-dot-circle-o"></span></button>
|
||||
<!-- Elliptical ROI -->
|
||||
<button id="ellipticalRoi" type="button" class="imageViewerTool btn btn-sm btn-default" data-container="body" data-toggle="tooltip" data-placement="bottom" title="Elliptical ROI"><span class="fa fa-circle-o"></span></button>
|
||||
<!-- Rectangle ROI -->
|
||||
<button id="rectangleRoi" type="button" class="imageViewerTool btn btn-sm btn-default" data-container="body" data-toggle="tooltip" data-placement="bottom" title="Rectangle ROI"><span class="fa fa-square-o"></span></button>
|
||||
<!-- Play clip -->
|
||||
<button id="playClip" type="button" class="imageViewerCommand btn btn-sm btn-default" data-container="body" data-toggle="tooltip" data-placement="bottom" title="Play/Stop Clip">
|
||||
{{ #if isPlaying }}
|
||||
<span class="fa fa-stop"></span>
|
||||
{{ else }}
|
||||
<span class="fa fa-play"></span>
|
||||
{{ /if }}
|
||||
</button>
|
||||
<!--<button id="layout" type="button" class="btn btn-sm btn-default dropdown-toggle" data-container="body" data-toggle="dropdown" aria-expanded="false" data-placement="right" title="Layout" rel="tooltip"><span class="fa fa-th-large"></span></button>
|
||||
{{> layoutChooser}}-->
|
||||
<!-- Lesion Tool -->
|
||||
<button id="lesion" type="button" class="imageViewerTool btn btn-sm btn-toolbar" data-container="body" data-toggle="tooltip" data-placement="bottom" title="Lesion Tool"><span class="fa fa-arrows-v"></span></button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@ -1,33 +0,0 @@
|
||||
Template.toolbar.events({
|
||||
'click .imageViewerTool': function(e) {
|
||||
var tool = e.currentTarget.id;
|
||||
console.log('Setting active tool to: ' + tool);
|
||||
toolManager.setActiveTool(tool);
|
||||
},
|
||||
'click .imageViewerCommand': function(e) {
|
||||
var command = e.currentTarget.id;
|
||||
if (!OHIF.viewer.functionList.hasOwnProperty(command)) {
|
||||
return;
|
||||
}
|
||||
var viewportIndex = Session.get('ActiveViewport');
|
||||
var element = $('.imageViewerViewport').get(viewportIndex);
|
||||
OHIF.viewer.functionList[command](element);
|
||||
}
|
||||
});
|
||||
|
||||
Template.toolbar.onRendered(function() {
|
||||
var tooltipButtons = $('[data-toggle="tooltip"]');
|
||||
tooltipButtons.tooltip(OHIF.viewer.tooltipConfig);
|
||||
|
||||
// Enable tooltips for the layout button
|
||||
var extraTooltipButtons = $('[rel="tooltip"]');
|
||||
extraTooltipButtons.tooltip(OHIF.viewer.tooltipConfig);
|
||||
});
|
||||
|
||||
Template.toolbar.helpers({
|
||||
'isPlaying': function() {
|
||||
Session.get('UpdateCINE');
|
||||
var viewportIndex = Session.get('ActiveViewport');
|
||||
return !!OHIF.viewer.isPlaying[viewportIndex];
|
||||
}
|
||||
});
|
||||
@ -1,8 +1,7 @@
|
||||
<template name="viewerMain">
|
||||
<div class="viewerMain">
|
||||
{{> toolbar}}
|
||||
{{> imageViewerViewports}}
|
||||
{{> lesionTableContainer}}
|
||||
<!--TODO: Bottom lesion table container will be here-->
|
||||
{{ >toolbar toolbarOptions }}
|
||||
{{ >imageViewerViewports}}
|
||||
{{ >lesionTableContainer}}
|
||||
</div>
|
||||
</template>
|
||||
75
LesionTracker/client/components/viewerMain/viewerMain.js
Normal file
75
LesionTracker/client/components/viewerMain/viewerMain.js
Normal file
@ -0,0 +1,75 @@
|
||||
Template.viewerMain.helpers({
|
||||
'toolbarOptions': function() {
|
||||
var toolbarOptions = {};
|
||||
|
||||
var buttonData = [];
|
||||
|
||||
buttonData.push({
|
||||
id: 'wwwc',
|
||||
title: 'WW/WC',
|
||||
classes: 'imageViewerTool',
|
||||
iconClasses: 'fa fa-sun-o'
|
||||
});
|
||||
|
||||
buttonData.push({
|
||||
id: 'invert',
|
||||
title: 'Invert',
|
||||
classes: 'imageViewerCommand',
|
||||
iconClasses: 'fa fa-adjust'
|
||||
});
|
||||
|
||||
buttonData.push({
|
||||
id: 'zoom',
|
||||
title: 'Zoom',
|
||||
classes: 'imageViewerTool',
|
||||
iconClasses: 'fa fa-search'
|
||||
});
|
||||
|
||||
buttonData.push({
|
||||
id: 'pan',
|
||||
title: 'Pan',
|
||||
classes: 'imageViewerTool',
|
||||
iconClasses: 'fa fa-arrows'
|
||||
});
|
||||
|
||||
buttonData.push({
|
||||
id: 'stackScroll',
|
||||
title: 'Stack Scroll',
|
||||
classes: 'imageViewerTool',
|
||||
iconClasses: 'fa fa-bars'
|
||||
});
|
||||
|
||||
buttonData.push({
|
||||
id: 'length',
|
||||
title: 'Length Measurement',
|
||||
classes: 'imageViewerTool',
|
||||
iconClasses: 'fa fa-arrows-v'
|
||||
});
|
||||
|
||||
buttonData.push({
|
||||
id: 'angle',
|
||||
title: 'Angle Measurement',
|
||||
classes: 'imageViewerTool',
|
||||
iconClasses: 'fa fa-angle-left'
|
||||
});
|
||||
|
||||
buttonData.push({
|
||||
id: 'dragProbe',
|
||||
title: 'Pixel Probe',
|
||||
classes: 'imageViewerTool',
|
||||
iconClasses: 'fa fa-dot-circle-o'
|
||||
});
|
||||
|
||||
buttonData.push({
|
||||
id: 'lesion',
|
||||
title: 'Lesion Tool',
|
||||
classes: 'imageViewerTool',
|
||||
iconClasses: 'fa fa-arrows-v'
|
||||
});
|
||||
|
||||
toolbarOptions.buttonData = buttonData;
|
||||
toolbarOptions.includePlayClipButton = true;
|
||||
toolbarOptions.includeLayoutButton = false;
|
||||
return toolbarOptions;
|
||||
}
|
||||
});
|
||||
@ -11,8 +11,6 @@ Router.route('/', function () {
|
||||
});
|
||||
});
|
||||
|
||||
ViewerStudies = new Mongo.Collection(null);
|
||||
|
||||
Router.route('/viewer/:_id', {
|
||||
layoutTemplate: 'lesionTrackerLayout',
|
||||
name: 'viewer',
|
||||
@ -29,6 +27,7 @@ Router.route('/viewer/:_id', {
|
||||
//Session.set(activeTabId, studies);
|
||||
//Session.set('showContentInTab', true);
|
||||
//self.render('viewer');
|
||||
openNewTab(studies);
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -32,3 +32,4 @@ cornerstone
|
||||
dicomweb
|
||||
viewerbase
|
||||
worklist
|
||||
reactive-var
|
||||
|
||||
@ -1,36 +0,0 @@
|
||||
<template name="toolbar">
|
||||
<div id='toolbar'>
|
||||
<div class="btn-group">
|
||||
<!-- WW/WL -->
|
||||
<button id="wwwc" type="button" class="imageViewerTool btn btn-sm btn-default" data-container="body" data-toggle="tooltip" data-placement="bottom" title="WW/WC"><span class="fa fa-sun-o"></span></button>
|
||||
<!-- Invert -->
|
||||
<button id="invert" type="button" class="imageViewerCommand btn btn-sm btn-default" data-container="body" data-toggle="tooltip" data-placement="bottom" title="Invert"><span class="fa fa-adjust"></span></button>
|
||||
<!-- Zoom -->
|
||||
<button id="zoom" type="button" class="imageViewerTool btn btn-sm btn-default" data-container="body" data-toggle="tooltip" data-placement="bottom" title="Zoom"><span class="fa fa-search"></span></button>
|
||||
<!-- Pan -->
|
||||
<button id="pan" type="button" class="imageViewerTool btn btn-sm btn-default" data-container="body" data-toggle="tooltip" data-placement="bottom" title="Pan"><span class="fa fa-arrows"></span></button>
|
||||
<!-- Stack scroll -->
|
||||
<button id="stackScroll" type="button" class="imageViewerTool btn btn-sm btn-default" data-container="body" data-toggle="tooltip" data-placement="bottom" title="Stack Scroll"><span class="fa fa-bars"></span></button>
|
||||
<!-- Length measurement -->
|
||||
<button id="length" type="button" class="imageViewerTool btn btn-sm btn-default" data-container="body" data-toggle="tooltip" data-placement="bottom" title="Length Measurement"><span class="fa fa-arrows-v"></span></button>
|
||||
<!-- Angle measurement -->
|
||||
<button id="angle" type="button" class="imageViewerTool btn btn-sm btn-default" data-container="body" data-toggle="tooltip" data-placement="bottom" title="Angle Measurement"><span class="fa fa-angle-left"></span></button>
|
||||
<!-- Pixel probe -->
|
||||
<button id="dragProbe" type="button" class="imageViewerTool btn btn-sm btn-default" data-container="body" data-toggle="tooltip" data-placement="bottom" title="Pixel Probe"><span class="fa fa-dot-circle-o"></span></button>
|
||||
<!-- Elliptical ROI -->
|
||||
<button id="ellipticalRoi" type="button" class="imageViewerTool btn btn-sm btn-default" data-container="body" data-toggle="tooltip" data-placement="bottom" title="Elliptical ROI"><span class="fa fa-circle-o"></span></button>
|
||||
<!-- Rectangle ROI -->
|
||||
<button id="rectangleRoi" type="button" class="imageViewerTool btn btn-sm btn-default" data-container="body" data-toggle="tooltip" data-placement="bottom" title="Rectangle ROI"><span class="fa fa-square-o"></span></button>
|
||||
<!-- Play clip -->
|
||||
<button id="playClip" type="button" class="imageViewerCommand btn btn-sm btn-default" data-container="body" data-toggle="tooltip" data-placement="bottom" title="Play/Stop Clip">
|
||||
{{ #if isPlaying }}
|
||||
<span class="fa fa-stop"></span>
|
||||
{{ else }}
|
||||
<span class="fa fa-play"></span>
|
||||
{{ /if }}
|
||||
</button>
|
||||
<button id="layout" type="button" class="btn btn-sm btn-default dropdown-toggle" data-container="body" data-toggle="dropdown" aria-expanded="false" data-placement="right" title="Layout" rel="tooltip"><span class="fa fa-th-large"></span></button>
|
||||
{{> layoutChooser}}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@ -1,40 +0,0 @@
|
||||
Template.toolbar.helpers({
|
||||
studies : function() {
|
||||
var studies = Session.get('studies');
|
||||
return studies;
|
||||
}
|
||||
});
|
||||
|
||||
Template.toolbar.events({
|
||||
'click .imageViewerTool': function(e) {
|
||||
var tool = e.currentTarget.id;
|
||||
console.log('Setting active tool to: ' + tool);
|
||||
toolManager.setActiveTool(tool);
|
||||
},
|
||||
'click .imageViewerCommand': function(e) {
|
||||
var command = e.currentTarget.id;
|
||||
if (!OHIF.viewer.functionList.hasOwnProperty(command)) {
|
||||
return;
|
||||
}
|
||||
var viewportIndex = Session.get('ActiveViewport');
|
||||
var element = $('.imageViewerViewport').get(viewportIndex);
|
||||
OHIF.viewer.functionList[command](element);
|
||||
}
|
||||
});
|
||||
|
||||
Template.toolbar.onRendered(function() {
|
||||
var tooltipButtons = $('[data-toggle="tooltip"]');
|
||||
tooltipButtons.tooltip(OHIF.viewer.tooltipConfig);
|
||||
|
||||
// Enable tooltips for the layout button
|
||||
var extraTooltipButtons = $('[rel="tooltip"]');
|
||||
extraTooltipButtons.tooltip(OHIF.viewer.tooltipConfig);
|
||||
});
|
||||
|
||||
Template.toolbar.helpers({
|
||||
'isPlaying': function() {
|
||||
Session.get('UpdateCINE');
|
||||
var viewportIndex = Session.get('ActiveViewport');
|
||||
return !!OHIF.viewer.isPlaying[viewportIndex];
|
||||
}
|
||||
});
|
||||
@ -1,15 +0,0 @@
|
||||
#toolbar
|
||||
background-color: black
|
||||
text-align: center
|
||||
|
||||
.btn-group
|
||||
display: inline-block
|
||||
|
||||
button
|
||||
text-align: center
|
||||
color: #ffffff
|
||||
background-color: #424242
|
||||
border-color: #424242
|
||||
|
||||
&.active, &:active
|
||||
background-color: #3B678E
|
||||
@ -3,7 +3,7 @@
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1,maximum-scale=1,user-scalable=no">
|
||||
</head>
|
||||
<div id="viewer">
|
||||
{{> studyBrowser}}
|
||||
{{> viewerMain}}
|
||||
{{> studyBrowser studies=studies activeViewport=activeViewport}}
|
||||
{{> viewerMain studies=studies activeViewport=activeViewport viewportRows=viewportRows viewportColumns=viewportColumns}}
|
||||
</div>
|
||||
</template>
|
||||
@ -58,9 +58,11 @@ function resizeViewports() {
|
||||
}, 1);
|
||||
}
|
||||
|
||||
Session.setDefault('ActiveViewport', 0);
|
||||
Session.setDefault('viewportRows', 1);
|
||||
Session.setDefault('viewportColumns', 1);
|
||||
Template.viewer.onCreated(function() {
|
||||
this.data.activeViewport = new ReactiveVar(0);
|
||||
this.data.viewportRows = new ReactiveVar(1);
|
||||
this.data.viewportColumns = new ReactiveVar(1);
|
||||
});
|
||||
|
||||
// Avoid doing DOM manipulation during the resize handler
|
||||
// because it is fired very often.
|
||||
@ -71,19 +73,4 @@ $(window).on('resize', function() {
|
||||
resizeTimer = setTimeout(function() {
|
||||
resizeViewports();
|
||||
}, 100);
|
||||
});
|
||||
|
||||
Template.viewer.onRendered(function() {
|
||||
var imageViewer = $("#viewer");
|
||||
if (imageViewer) {
|
||||
$('.navbar-default').css({
|
||||
'background-color': '#000000',
|
||||
'border-color': '#101010'
|
||||
});
|
||||
document.body.style.overflow = "hidden";
|
||||
document.body.style.height = '100%';
|
||||
document.body.style.width = '100%';
|
||||
document.body.style.minWidth = 0;
|
||||
document.body.style.position = 'fixed'; // Prevent overscroll on mobile devices
|
||||
}
|
||||
});
|
||||
@ -1,6 +1,6 @@
|
||||
<template name="viewerMain">
|
||||
<div class='viewerMain'>
|
||||
{{ > toolbar }}
|
||||
{{ > imageViewerViewports }}
|
||||
{{ > toolbar activeViewport=activeViewport viewportRows=viewportRows viewportColumns=viewportColumns}}
|
||||
{{ > imageViewerViewports studies=studies activeViewport=activeViewport viewportRows=viewportRows viewportColumns=viewportColumns}}
|
||||
</div>
|
||||
</template>
|
||||
@ -1,6 +1,6 @@
|
||||
Template.viewerMain.helpers({
|
||||
studies : function() {
|
||||
var studies = Session.get('studies');
|
||||
return studies;
|
||||
}
|
||||
studies : function() {
|
||||
var studies = this.studies;
|
||||
return studies;
|
||||
}
|
||||
});
|
||||
@ -7,27 +7,32 @@ Router.configure({
|
||||
|
||||
|
||||
Router.route('/', function () {
|
||||
this.render('worklist', {
|
||||
});
|
||||
this.render('worklist', {});
|
||||
});
|
||||
|
||||
ViewerStudies = new Mongo.Collection(null);
|
||||
tabs = new Meteor.Collection(null);
|
||||
|
||||
Router.route('/viewer/:_id', {
|
||||
layoutTemplate: 'layout',
|
||||
name: 'viewer',
|
||||
onBeforeAction: function() {
|
||||
var self = this;
|
||||
Meteor.call('GetStudyMetadata', this.params._id, function(error, study) {
|
||||
//console.log(study);
|
||||
sortStudy(study);
|
||||
layoutTemplate: 'layout',
|
||||
name: 'viewer',
|
||||
onBeforeAction: function() {
|
||||
var self = this;
|
||||
|
||||
var studies = [study];
|
||||
Session.set('studies', studies);
|
||||
Meteor.call('GetStudyMetadata', this.params._id, function(error, study) {
|
||||
sortStudy(study);
|
||||
|
||||
self.render('viewer');
|
||||
});
|
||||
}
|
||||
});
|
||||
var studies = [study];
|
||||
var title = study.seriesList[0].instances[0].patientName;
|
||||
var contentid = generateUUID();
|
||||
|
||||
var newTabObject = {
|
||||
title: title,
|
||||
contentid: contentid,
|
||||
};
|
||||
tabs.insert(newTabObject);
|
||||
Session.set('StudiesInTab#' + contentid, studies);
|
||||
|
||||
self.render('worklist');
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -1,7 +1,7 @@
|
||||
<template name="studyBrowser">
|
||||
<div class="studyBrowser">
|
||||
{{#each studies}}
|
||||
{{> thumbnails}}
|
||||
{{/each}}
|
||||
{{ #each studies }}
|
||||
{{ >thumbnails }}
|
||||
{{ /each }}
|
||||
</div>
|
||||
</template>
|
||||
@ -1,6 +1,5 @@
|
||||
Template.studyBrowser.helpers({
|
||||
studies : function() {
|
||||
var studies = Session.get('studies');
|
||||
return studies;
|
||||
return this.studies;
|
||||
}
|
||||
});
|
||||
@ -1,6 +1,6 @@
|
||||
<template name="thumbnailEntry">
|
||||
<div class="thumbnailEntry">
|
||||
{{ > imageThumbnail }}
|
||||
{{ >imageThumbnail }}
|
||||
<div class='seriesDescription noselect'>{{seriesDescription}}</div>
|
||||
</div>
|
||||
</template>
|
||||
@ -17,7 +17,7 @@ function cloneElement(element, targetId) {
|
||||
return clone;
|
||||
}
|
||||
|
||||
function thumbnailDragStartHandler(e) {
|
||||
function thumbnailDragStartHandler(e, studies) {
|
||||
// Prevent any scrolling behaviour normally caused by the original event
|
||||
e.originalEvent.preventDefault();
|
||||
|
||||
@ -28,7 +28,8 @@ function thumbnailDragStartHandler(e) {
|
||||
// Store this data for use during drag and drop
|
||||
OHIF.viewer.dragAndDropData = {
|
||||
studyInstanceUid: imageThumbnail.data('studyInstanceUid'),
|
||||
seriesInstanceUid: imageThumbnail.data('seriesInstanceUid')
|
||||
seriesInstanceUid: imageThumbnail.data('seriesInstanceUid'),
|
||||
studies: studies
|
||||
};
|
||||
|
||||
// Clone the image thumbnail
|
||||
@ -201,7 +202,8 @@ Template.thumbnailEntry.onRendered(function() {
|
||||
Template.thumbnailEntry.events({
|
||||
// Touch drag/drop events
|
||||
'touchstart .thumbnailEntry, mousedown .thumbnailEntry': function(e) {
|
||||
thumbnailDragStartHandler(e);
|
||||
var studies = Template.parentData(2).studies;
|
||||
thumbnailDragStartHandler(e, studies);
|
||||
},
|
||||
'touchmove .thumbnailEntry': function(e) {
|
||||
thumbnailDragHandler(e, e.currentTarget);
|
||||
|
||||
@ -158,13 +158,13 @@ function loadSeriesIntoViewport(data) {
|
||||
OHIF.viewer.updateImageSynchronizer.add(element);
|
||||
}
|
||||
|
||||
enablePrefetchOnElement();
|
||||
//enablePrefetchOnElement();
|
||||
displayReferenceLines();
|
||||
});
|
||||
}
|
||||
|
||||
Template.imageViewerViewport.onRendered(function() {
|
||||
var studies = Session.get('studies');
|
||||
var studies = this.data.studies;
|
||||
var viewport = this.find(".imageViewerViewport");
|
||||
var viewportIndex = $(".imageViewerViewport").index(viewport);
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
{{ #each viewportArray }}
|
||||
<div class="viewportContainer" style="height:{{height}}%;width:{{width}}%;">
|
||||
<div class="removable">
|
||||
{{ > imageViewerViewport}}
|
||||
{{ >imageViewerViewport studies=studies activeViewport=activeViewport}}
|
||||
</div>
|
||||
</div>
|
||||
{{ /each }}
|
||||
|
||||
@ -1,30 +1,50 @@
|
||||
function getNumViewports() {
|
||||
var viewportRows = Session.get('viewportRows');
|
||||
var viewportColumns = Session.get('viewportColumns');
|
||||
return viewportRows * viewportColumns;
|
||||
}
|
||||
|
||||
Template.imageViewerViewports.helpers({
|
||||
height: function() {
|
||||
var viewportRows = Session.get('viewportRows');
|
||||
var viewportRows;
|
||||
if (!Template.parentData(1).viewportRows) {
|
||||
viewportRows = 1;
|
||||
} else {
|
||||
viewportRows = Template.parentData(1).viewportRows.get();
|
||||
}
|
||||
return 100 / viewportRows;
|
||||
},
|
||||
width: function() {
|
||||
var viewportColumns = Session.get('viewportColumns');
|
||||
var viewportColumns;
|
||||
if (!Template.parentData(1).viewportColumns) {
|
||||
viewportColumns = 1;
|
||||
} else {
|
||||
viewportColumns = Template.parentData(1).viewportColumns.get();
|
||||
}
|
||||
return 100 / viewportColumns;
|
||||
},
|
||||
viewportArray: function() {
|
||||
// This is a really annoying thing to have to do, but Meteor
|
||||
// doesn't want to let me use another type of helper.
|
||||
var numViewports = getNumViewports();
|
||||
var viewportRows;
|
||||
if (!this.viewportRows) {
|
||||
viewportRows = 1;
|
||||
} else {
|
||||
viewportRows = this.viewportRows.get();
|
||||
}
|
||||
|
||||
var viewportColumns;
|
||||
if (!this.viewportColumns) {
|
||||
viewportColumns = 1;
|
||||
} else {
|
||||
viewportColumns = this.viewportColumns.get();
|
||||
}
|
||||
|
||||
var numViewports = viewportRows * viewportColumns;
|
||||
|
||||
var array = [];
|
||||
for (var i=0; i < numViewports; ++i) {
|
||||
var data = {
|
||||
viewportIndex: i
|
||||
viewportIndex: i,
|
||||
studies: this.studies,
|
||||
activeViewport: this.activeViewport
|
||||
};
|
||||
array.push(data);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
},
|
||||
});
|
||||
@ -0,0 +1,6 @@
|
||||
<template name="layoutButton">
|
||||
<button id="layout" type="button" class="btn btn-sm btn-default dropdown-toggle" data-container="body" data-toggle="dropdown" aria-expanded="false" data-placement="right" title="Layout" rel="tooltip">
|
||||
<span class="fa fa-th-large"></span>
|
||||
</button>
|
||||
{{ >layoutChooser }}
|
||||
</template>
|
||||
@ -28,14 +28,30 @@ Template.layoutChooser.events({
|
||||
'click .layoutChooser table td': function(evt) {
|
||||
$('#imageViewerViewports').remove();
|
||||
var container = $(".viewerMain").get(0);
|
||||
UI.render(Template.imageViewerViewports, container);
|
||||
|
||||
var currentCell = $(evt.currentTarget);
|
||||
var rowIndex = currentCell.closest('tr').index();
|
||||
var columnIndex = currentCell.index();
|
||||
|
||||
var data = {};
|
||||
|
||||
// Add 1 because the indices start from zero
|
||||
Session.set('viewportRows', rowIndex + 1);
|
||||
Session.set('viewportColumns', columnIndex + 1);
|
||||
if (this.viewportRows) {
|
||||
this.viewportRows.set(rowIndex + 1);
|
||||
data.viewportRows = this.viewportRows;
|
||||
} else {
|
||||
data.viewportRows = 1;
|
||||
}
|
||||
|
||||
if (this.viewportColumns) {
|
||||
this.viewportColumns.set(columnIndex + 1);
|
||||
data.viewportColumns = this.viewportColumns;
|
||||
} else {
|
||||
data.viewportColumns = 1;
|
||||
}
|
||||
|
||||
data.studies = Template.parentData(2).studies;
|
||||
data.activeViewport = Template.parentData(2).activeViewport;
|
||||
UI.renderWithData(Template.imageViewerViewports, data, container);
|
||||
}
|
||||
});
|
||||
@ -0,0 +1,9 @@
|
||||
<template name="playClipButton">
|
||||
<button id="playClip" type="button" class="imageViewerCommand btn btn-sm btn-default" data-container="body" data-toggle="tooltip" data-placement="bottom" title="Play/Stop Clip">
|
||||
{{ #if isPlaying }}
|
||||
<span class="fa fa-stop"></span>
|
||||
{{ else }}
|
||||
<span class="fa fa-play"></span>
|
||||
{{ /if }}
|
||||
</button>
|
||||
</template>
|
||||
@ -0,0 +1,7 @@
|
||||
Template.playClipButton.helpers({
|
||||
'isPlaying': function() {
|
||||
Session.get('UpdateCINE');
|
||||
var viewportIndex = Session.get('ActiveViewport');
|
||||
return !!OHIF.viewer.isPlaying[viewportIndex];
|
||||
}
|
||||
});
|
||||
@ -0,0 +1,5 @@
|
||||
<template name="simpleToolbarButton">
|
||||
<button id="{{id}}" type="button" class="{{classes}} btn btn-sm btn-default" data-container="body" data-toggle="tooltip" data-placement="bottom" title="{{title}}">
|
||||
<span class="{{iconClasses}}"></span>
|
||||
</button>
|
||||
</template>
|
||||
17
Packages/viewerbase/components/viewer/toolbar/toolbar.html
Normal file
17
Packages/viewerbase/components/viewer/toolbar/toolbar.html
Normal file
@ -0,0 +1,17 @@
|
||||
<template name="toolbar">
|
||||
<div id='toolbar'>
|
||||
<div class="btn-group">
|
||||
{{ #each button }}
|
||||
{{ >simpleToolbarButton }}
|
||||
{{ /each }}
|
||||
|
||||
{{ #if includePlayClipButton }}
|
||||
{{ > playClipButton activeViewport=activeViewport}}
|
||||
{{ /if }}
|
||||
|
||||
{{ #if includeLayoutButton }}
|
||||
{{ > layoutButton viewportRows=viewportRows viewportColumns=viewportColumns}}
|
||||
{{ /if }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
121
Packages/viewerbase/components/viewer/toolbar/toolbar.js
Normal file
121
Packages/viewerbase/components/viewer/toolbar/toolbar.js
Normal file
@ -0,0 +1,121 @@
|
||||
function getDefaultButtonData() {
|
||||
var buttonData = [];
|
||||
|
||||
buttonData.push({
|
||||
id: 'wwwc',
|
||||
title: 'WW/WC',
|
||||
classes: 'imageViewerTool',
|
||||
iconClasses: 'fa fa-sun-o'
|
||||
});
|
||||
|
||||
buttonData.push({
|
||||
id: 'invert',
|
||||
title: 'Invert',
|
||||
classes: 'imageViewerCommand',
|
||||
iconClasses: 'fa fa-adjust'
|
||||
});
|
||||
|
||||
buttonData.push({
|
||||
id: 'zoom',
|
||||
title: 'Zoom',
|
||||
classes: 'imageViewerTool',
|
||||
iconClasses: 'fa fa-search'
|
||||
});
|
||||
|
||||
buttonData.push({
|
||||
id: 'pan',
|
||||
title: 'Pan',
|
||||
classes: 'imageViewerTool',
|
||||
iconClasses: 'fa fa-arrows'
|
||||
});
|
||||
|
||||
buttonData.push({
|
||||
id: 'stackScroll',
|
||||
title: 'Stack Scroll',
|
||||
classes: 'imageViewerTool',
|
||||
iconClasses: 'fa fa-bars'
|
||||
});
|
||||
|
||||
buttonData.push({
|
||||
id: 'length',
|
||||
title: 'Length Measurement',
|
||||
classes: 'imageViewerTool',
|
||||
iconClasses: 'fa fa-arrows-v'
|
||||
});
|
||||
|
||||
buttonData.push({
|
||||
id: 'angle',
|
||||
title: 'Angle Measurement',
|
||||
classes: 'imageViewerTool',
|
||||
iconClasses: 'fa fa-angle-left'
|
||||
});
|
||||
|
||||
buttonData.push({
|
||||
id: 'dragProbe',
|
||||
title: 'Pixel Probe',
|
||||
classes: 'imageViewerTool',
|
||||
iconClasses: 'fa fa-dot-circle-o'
|
||||
});
|
||||
|
||||
buttonData.push({
|
||||
id: 'ellipticalRoi',
|
||||
title: 'Elliptical ROI',
|
||||
classes: 'imageViewerTool',
|
||||
iconClasses: 'fa fa-circle-o'
|
||||
});
|
||||
|
||||
buttonData.push({
|
||||
id: 'rectangleRoi',
|
||||
title: 'Rectangle ROI',
|
||||
classes: 'imageViewerTool',
|
||||
iconClasses: 'fa fa-square-o'
|
||||
});
|
||||
return buttonData;
|
||||
}
|
||||
|
||||
Template.toolbar.events({
|
||||
'click .imageViewerTool': function(e) {
|
||||
var tool = e.currentTarget.id;
|
||||
console.log('Setting active tool to: ' + tool);
|
||||
toolManager.setActiveTool(tool);
|
||||
},
|
||||
'click .imageViewerCommand': function(e) {
|
||||
var command = e.currentTarget.id;
|
||||
if (!OHIF.viewer.functionList.hasOwnProperty(command)) {
|
||||
return;
|
||||
}
|
||||
var viewportIndex = Session.get('ActiveViewport');
|
||||
var element = $('.imageViewerViewport').get(viewportIndex);
|
||||
OHIF.viewer.functionList[command](element);
|
||||
}
|
||||
});
|
||||
|
||||
Template.toolbar.onRendered(function() {
|
||||
var tooltipButtons = $('[data-toggle="tooltip"]');
|
||||
tooltipButtons.tooltip(OHIF.viewer.tooltipConfig);
|
||||
|
||||
// Enable tooltips for the layout button
|
||||
var extraTooltipButtons = $('[rel="tooltip"]');
|
||||
extraTooltipButtons.tooltip(OHIF.viewer.tooltipConfig);
|
||||
});
|
||||
|
||||
Template.toolbar.helpers({
|
||||
'button': function() {
|
||||
if (this.buttonData) {
|
||||
return this.buttonData;
|
||||
}
|
||||
return getDefaultButtonData();
|
||||
},
|
||||
'includePlayClipButton': function() {
|
||||
if (this.includePlayClipButton !== undefined) {
|
||||
return this.includePlayClipButton;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
'includeLayoutButton': function() {
|
||||
if (this.includeLayoutButton !== undefined) {
|
||||
return this.includeLayoutButton;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
@ -37,6 +37,4 @@ rerenderViewportWithNewSeries = function(element, data) {
|
||||
|
||||
// Render and insert the template
|
||||
UI.renderWithData(Template.imageViewerViewport, data, newViewportContainer);
|
||||
|
||||
Session.set('loadedSeriesDictionary', OHIF.viewer.imageViewerLoadedSeriesDictionary);
|
||||
};
|
||||
@ -77,7 +77,7 @@ toolManager = {
|
||||
toolManager.init();
|
||||
}
|
||||
|
||||
$('#toolRow .btn-group button').removeClass('active');
|
||||
$('#toolbar .btn-group button').removeClass('active');
|
||||
var toolButton = document.getElementById(tool);
|
||||
toolButton.classList.add('active');
|
||||
|
||||
|
||||
@ -63,6 +63,17 @@ Package.onUse(function (api) {
|
||||
api.addFiles('components/viewer/layoutChooser/layoutChooser.js', 'client');
|
||||
api.addFiles('components/viewer/layoutChooser/layoutChooser.styl', 'client');
|
||||
|
||||
api.addFiles('components/viewer/simpleToolbarButton/simpleToolbarButton.html', 'client');
|
||||
|
||||
api.addFiles('components/viewer/playClipButton/playClipButton.html', 'client');
|
||||
api.addFiles('components/viewer/playClipButton/playClipButton.js', 'client');
|
||||
|
||||
api.addFiles('components/viewer/layoutButton/layoutButton.html', 'client');
|
||||
|
||||
api.addFiles('components/viewer/toolbar/toolbar.html', 'client');
|
||||
api.addFiles('components/viewer/toolbar/toolbar.js', 'client');
|
||||
api.addFiles('components/viewer/toolbar/toolbar.styl', 'client');
|
||||
|
||||
// Library functions
|
||||
api.addFiles('lib/accountsConfig.js', 'client');
|
||||
api.addFiles('lib/createStacks.js', 'client');
|
||||
|
||||
4
Packages/worklist/components/tabContent/tabContent.html
Normal file
4
Packages/worklist/components/tabContent/tabContent.html
Normal file
@ -0,0 +1,4 @@
|
||||
<template name="tabContent">
|
||||
<div role="tabpanel" class="tab-pane" id="{{contentid}}">
|
||||
</div>
|
||||
</template>
|
||||
8
Packages/worklist/components/tabTitle/tabTitle.html
Normal file
8
Packages/worklist/components/tabTitle/tabTitle.html
Normal file
@ -0,0 +1,8 @@
|
||||
<template name="tabTitle">
|
||||
<li role="presentation" class="tabTitle">
|
||||
<a data-target="#{{contentid}}" role="tab" data-toggle="tab">
|
||||
{{title}}
|
||||
<a class="close">x</a>
|
||||
</a>
|
||||
</li>
|
||||
</template>
|
||||
21
Packages/worklist/components/tabTitle/tabTitle.js
Normal file
21
Packages/worklist/components/tabTitle/tabTitle.js
Normal file
@ -0,0 +1,21 @@
|
||||
Template.tabTitle.events({
|
||||
'click .close': function(e) {
|
||||
var tab = $(e.currentTarget).parents('[data-toggle="tab"]').eq(0);
|
||||
var contentId = tab.data("target").replace("#","");
|
||||
var tabObjectId = tabs.find({contentid: contentId}).fetch()[0]._id;
|
||||
tabs.remove(tabObjectId);
|
||||
|
||||
var tabIndex = tab.index();
|
||||
var newActiveTabIndex = Math.max(tabIndex - 1, 0);
|
||||
if (newActiveTabIndex === 0) {
|
||||
$('a[data-target="#worklistTab"]').addClass('active').tab('show');
|
||||
return;
|
||||
}
|
||||
|
||||
var newActiveTab = $(".tabTitle").eq(newActiveTabIndex);
|
||||
var newContentId = newActiveTab.data("contentid");
|
||||
|
||||
var tabObject = tabs.find({contentId: newContentId}).fetch()[0];
|
||||
tabObject.active = true;
|
||||
}
|
||||
});
|
||||
8
Packages/worklist/components/tabTitle/tabTitle.styl
Normal file
8
Packages/worklist/components/tabTitle/tabTitle.styl
Normal file
@ -0,0 +1,8 @@
|
||||
.tabTitle
|
||||
a
|
||||
padding: 0 5px
|
||||
|
||||
a.close
|
||||
font-size: 16pt
|
||||
padding: 0 5px
|
||||
font-weight: normal
|
||||
@ -1,17 +1,21 @@
|
||||
<template name="worklist">
|
||||
<div class="tabbable">
|
||||
<ul id="tabs" class="nav nav-tabs">
|
||||
<li class="active">
|
||||
<a data-toggle="tab">Study List</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div id="tabs-content" class="tab-content">
|
||||
<div id="contentList" class="tab-pane active">
|
||||
<div class="container">
|
||||
{{> worklistSearch }}
|
||||
{{> worklistResult }}
|
||||
</div>
|
||||
<ul class="nav nav-tabs" role="tablist">
|
||||
<li role="presentation" class="active">
|
||||
<a data-target="#worklistTab" role="tab" data-toggle="tab">Study List</a>
|
||||
</li>
|
||||
{{ #each tabs }}
|
||||
{{ >tabTitle }}
|
||||
{{ /each }}
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
<div role="tabpanel" class="tab-pane active" id="worklistTab">
|
||||
<div class="container">
|
||||
{{> worklistSearch }}
|
||||
{{> worklistResult }}
|
||||
</div>
|
||||
</div>
|
||||
{{ #each tabs }}
|
||||
{{ >tabContent }}
|
||||
{{ /each }}
|
||||
</div>
|
||||
</template>
|
||||
@ -1,110 +1,43 @@
|
||||
var contentID = "";
|
||||
|
||||
//Generate UUID to create unique tabs
|
||||
function generateUUID () {
|
||||
var d = new Date().getTime();
|
||||
var uuid = 'xxxxxxxx'.replace(/[xy]/g, function(c) {
|
||||
var r = (d + Math.random()*8)%8 | 0;
|
||||
d = Math.floor(d/8);
|
||||
return (c=='x' ? r : (r&0x3|0x8)).toString(8);
|
||||
});
|
||||
return uuid;
|
||||
}
|
||||
|
||||
//Remove tab
|
||||
function removeTab (uuid) {
|
||||
var removedTabIndex = $("#tab"+uuid).index();
|
||||
//Remove tab
|
||||
$("#tab"+uuid).remove();
|
||||
//Remove Content
|
||||
$("#content"+uuid).remove();
|
||||
|
||||
//TODO:Activate previous tab
|
||||
|
||||
}
|
||||
|
||||
//Add new tab
|
||||
function addNewTab (data) {
|
||||
//Make inactive all tabs
|
||||
$("#tabs > li").removeClass("active");
|
||||
$("#tabs-content > div").removeClass("active");
|
||||
|
||||
//Create new li element for tab
|
||||
var tabli = document.createElement("li");
|
||||
$(tabli).addClass("active");
|
||||
$("#tabs").append(tabli);
|
||||
|
||||
//a element inside li
|
||||
var taba = document.createElement("a");
|
||||
var uuid = generateUUID();
|
||||
var tabId = "tab"+uuid;
|
||||
|
||||
|
||||
//activeTabId provides unique tabs content and encapsulates templates in tabs
|
||||
Session.set("activeTabId", tabId);
|
||||
console.log(Session.get("activeTabId"));
|
||||
|
||||
//Create tab
|
||||
taba.setAttribute("data-toggle","tab");
|
||||
taba.setAttribute("id",tabId);
|
||||
taba.innerHTML = data.patientName;
|
||||
tabli.appendChild(taba);
|
||||
|
||||
//Create close button
|
||||
var btnClose = document.createElement('button');
|
||||
$(btnClose).addClass("btnClose");
|
||||
btnClose.innerHTML = "x";
|
||||
btnClose.onclick = function() { // Note this is a function
|
||||
removeTab(uuid);
|
||||
};
|
||||
taba.appendChild(btnClose);
|
||||
|
||||
//Create div content
|
||||
var tabContent = document.createElement("div");
|
||||
var contentId = "content"+uuid;
|
||||
tabContent.setAttribute("id",contentId);
|
||||
$(tabContent).css("background-color", "black");
|
||||
$(tabContent).addClass("tab-pane");
|
||||
$(tabContent).addClass("active");
|
||||
$("#tabs-content").append(tabContent);
|
||||
|
||||
contentID = contentId;
|
||||
}
|
||||
|
||||
function insertContent() {
|
||||
console.log('Include imageViewer template');
|
||||
//Include imageViewer template
|
||||
UI.insert( UI.render( Template.viewer ), $( '#'+contentID ).get(0) );
|
||||
}
|
||||
|
||||
Template.worklist.events({
|
||||
'click ul#tabs>li>a': function (event){
|
||||
var tabId = $(event.target).attr("id");
|
||||
if ( tabId !== undefined ) {
|
||||
//Save activeTabId to load correct study for each tab
|
||||
Session.set("activeTabId", tabId);
|
||||
|
||||
var splitTabId = tabId.split("tab");
|
||||
var contentId = "content"+splitTabId[1];
|
||||
|
||||
//Make inactive all tab-pane divs
|
||||
$("#tabs-content>div").removeClass("active");
|
||||
$("#"+contentId).addClass("active");
|
||||
}
|
||||
}
|
||||
Template.worklist.helpers({
|
||||
'tabs': function() {
|
||||
var tabData = tabs.find().fetch();
|
||||
return tabData;
|
||||
},
|
||||
});
|
||||
|
||||
Tracker.autorun(function () {
|
||||
var data = Session.get('openNewTabEvent');
|
||||
var content = Session.get('showContentInTab');
|
||||
if ( data ) {
|
||||
addNewTab(data);
|
||||
}
|
||||
Template.worklist.events({
|
||||
'click a[data-toggle="tab"]': function(e) {
|
||||
console.log(e.currentTarget);
|
||||
var contentId = $(e.currentTarget).data('target');
|
||||
$(e.currentTarget).tab('show');
|
||||
|
||||
if (content) {
|
||||
insertContent();
|
||||
}
|
||||
var container = $('.tab-content').find(contentId).get(0);
|
||||
var studies = Session.get('StudiesInTab' + contentId);
|
||||
var data = {
|
||||
studies: studies
|
||||
};
|
||||
|
||||
Session.set('openNewTabEvent', false);
|
||||
Session.set('showContentInTab', false);
|
||||
if (contentId === '#worklistTab') {
|
||||
console.log('Switching to worklist');
|
||||
$("#viewer").remove();
|
||||
document.body.style.overflow = null;
|
||||
document.body.style.height = null;
|
||||
document.body.style.minWidth = null;
|
||||
document.body.style.position = null;
|
||||
} else {
|
||||
UI.renderWithData(Template.viewer, data, container);
|
||||
var imageViewer = $("#viewer");
|
||||
if (imageViewer) {
|
||||
$('.navbar-default').css({
|
||||
'background-color': '#000000',
|
||||
'border-color': '#101010'
|
||||
});
|
||||
document.body.style.overflow = "hidden";
|
||||
document.body.style.height = '100%';
|
||||
document.body.style.width = '100%';
|
||||
document.body.style.minWidth = 0;
|
||||
document.body.style.position = 'fixed'; // Prevent overscroll on mobile devices
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -1,18 +1,5 @@
|
||||
Template.worklistStudy.events({
|
||||
'click': function (){
|
||||
Router.go('viewer', {_id: this.studyInstanceUid});
|
||||
|
||||
Session.set('openNewTabEvent', self);
|
||||
var studyInstanceUid = this.studyInstanceUid;
|
||||
Meteor.call('GetStudyMetadata', studyInstanceUid, function(error, study) {
|
||||
//console.log(study);
|
||||
sortStudy(study);
|
||||
|
||||
var studies = [study];
|
||||
Session.set('studies', studies);
|
||||
Session.set(activeTabId, studies);
|
||||
Session.set('showContentInTab', true);
|
||||
self.render('viewer');
|
||||
});
|
||||
}
|
||||
});
|
||||
10
Packages/worklist/lib/generateUUID.js
Normal file
10
Packages/worklist/lib/generateUUID.js
Normal file
@ -0,0 +1,10 @@
|
||||
//Generate UUID to create unique tabs
|
||||
generateUUID = function() {
|
||||
var d = new Date().getTime();
|
||||
var uuid = 'xxxxxxxx'.replace(/[xy]/g, function(c) {
|
||||
var r =(d + Math.random()*8)%8 | 0;
|
||||
d = Math.floor(d/8);
|
||||
return(c=='x' ? r :(r&0x3|0x8)).toString(8);
|
||||
});
|
||||
return uuid;
|
||||
};
|
||||
@ -16,6 +16,12 @@ Package.onUse(function (api) {
|
||||
api.addFiles('components/worklist.js', 'client');
|
||||
api.addFiles('components/worklist.styl', 'client');
|
||||
|
||||
api.addFiles('components/tabTitle/tabTitle.html', 'client');
|
||||
api.addFiles('components/tabTitle/tabTitle.js', 'client');
|
||||
api.addFiles('components/tabTitle/tabTitle.styl', 'client');
|
||||
|
||||
api.addFiles('components/tabContent/tabContent.html', 'client');
|
||||
|
||||
api.addFiles('components/worklistStudy/worklistStudy.html', 'client');
|
||||
api.addFiles('components/worklistStudy/worklistStudy.js', 'client');
|
||||
api.addFiles('components/worklistStudy/worklistStudy.styl', 'client');
|
||||
@ -27,5 +33,8 @@ Package.onUse(function (api) {
|
||||
api.addFiles('components/worklistSearch/worklistSearch.html', 'client');
|
||||
api.addFiles('components/worklistSearch/worklistSearch.js', 'client');
|
||||
api.addFiles('components/worklistSearch/worklistSearch.styl', 'client');
|
||||
|
||||
api.addFiles('lib/generateUUID.js', 'client');
|
||||
api.export('generateUUID', 'client');
|
||||
});
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user