diff --git a/LesionTracker/client/components/toolbarSection/toolbarSection.html b/LesionTracker/client/components/toolbarSection/toolbarSection.html
index 0654390c6..45e1098d2 100644
--- a/LesionTracker/client/components/toolbarSection/toolbarSection.html
+++ b/LesionTracker/client/components/toolbarSection/toolbarSection.html
@@ -7,13 +7,6 @@
{{>toolbarSectionTools toolbarButtons=toolbarButtons}}
- {{#if splitView}}
- {{>studySeriesQuickSwitch (clone this side="right" viewportIndex=1)}}
- {{>studySeriesQuickSwitch (clone this side="left" viewportIndex=0)}}
- {{else}}
- {{>studySeriesQuickSwitch (clone this side="middle" viewportIndex=0)}}
- {{/if}}
-
{{>caseProgress}}
diff --git a/LesionTracker/client/components/toolbarSection/toolbarSection.js b/LesionTracker/client/components/toolbarSection/toolbarSection.js
index 5ed1d8af0..c5e3827b6 100644
--- a/LesionTracker/client/components/toolbarSection/toolbarSection.js
+++ b/LesionTracker/client/components/toolbarSection/toolbarSection.js
@@ -4,19 +4,6 @@ import { OHIF } from 'meteor/ohif:core';
import { Viewerbase } from 'meteor/ohif:viewerbase';
Template.toolbarSection.helpers({
- // Returns true if the view shall be split in two viewports
- splitView() {
- // Run this computation every time the viewports are updated
- Session.get('LayoutManagerUpdated');
-
- // Stops here if layout manager is not defined yet
- if (!Viewerbase.layoutManager) {
- return;
- }
-
- return Viewerbase.layoutManager.viewportData.length > 1;
- },
-
leftSidebarToggleButtonData() {
const instance = Template.instance();
return {
diff --git a/Packages/ohif-core/client/components/scrollArea/scrollArea.js b/Packages/ohif-core/client/components/scrollArea/scrollArea.js
index d81bfaf7a..1657d0ca8 100644
--- a/Packages/ohif-core/client/components/scrollArea/scrollArea.js
+++ b/Packages/ohif-core/client/components/scrollArea/scrollArea.js
@@ -1,5 +1,6 @@
import { Template } from 'meteor/templating';
import { _ } from 'meteor/underscore';
+import { OHIF } from 'meteor/ohif:core';
Template.scrollArea.onCreated(() => {
const instance = Template.instance();
@@ -16,17 +17,20 @@ Template.scrollArea.onCreated(() => {
Template.scrollArea.onRendered(() => {
const instance = Template.instance();
- const { config } = instance;
- if (config.hideScrollbar) {
- const $scrollable = instance.$('.scrollable').first();
- const scrollable = $scrollable[0];
- const x = config.scrollX ? 1 : 0;
- const y = config.scrollY ? 1 : 0;
- $scrollable.css({
- 'margin-right': 0 - (scrollable.offsetWidth - scrollable.clientWidth) * y,
- 'margin-bottom': 0 - (scrollable.offsetHeight - scrollable.clientHeight) * x
- });
- }
+
+ instance.adjustMargins = _.throttle(() => {
+ const { config } = instance;
+ if (config.hideScrollbar) {
+ const $scrollable = instance.$('.scrollable').first();
+ const x = config.scrollX ? 1 : 0;
+ const y = config.scrollY ? 1 : 0;
+ const scrollbarSize = OHIF.ui.getScrollbarSize();
+ $scrollable.css({
+ 'margin-right': 0 - (scrollbarSize[0]) * y,
+ 'margin-bottom': 0 - (scrollbarSize[1]) * x
+ });
+ }
+ }, 150);
instance.$scrollable = instance.$('.scrollable').first();
instance.scrollHandler = _.throttle(event => {
@@ -50,9 +54,17 @@ Template.scrollArea.onRendered(() => {
if (scrollTop + height < scrollHeight) {
$scrollArea.addClass('can-scroll-down');
}
- }, 300);
+ }, 150);
instance.scrollHandler();
+
+ instance.adjustMargins();
+ $(window).on('resize', instance.adjustMargins);
+});
+
+Template.scrollArea.onDestroyed(() => {
+ const instance = Template.instance();
+ $(window).off('resize', instance.adjustMargins);
});
Template.scrollArea.events({
diff --git a/Packages/ohif-core/client/components/scrollArea/scrollArea.styl b/Packages/ohif-core/client/components/scrollArea/scrollArea.styl
index ef0e02b19..86cfe6749 100644
--- a/Packages/ohif-core/client/components/scrollArea/scrollArea.styl
+++ b/Packages/ohif-core/client/components/scrollArea/scrollArea.styl
@@ -9,6 +9,7 @@ $scrollNavSize = 24px
.scrollable
max-height: inherit
overflow: hidden
+ zoom: 1
&.scroll-x
overflow-x: scroll
diff --git a/Packages/ohif-core/client/lib/ui.js b/Packages/ohif-core/client/lib/ui.js
index 6f3b210a7..86aaa57ba 100644
--- a/Packages/ohif-core/client/lib/ui.js
+++ b/Packages/ohif-core/client/lib/ui.js
@@ -26,3 +26,45 @@ OHIF.ui.getOffset = element => {
top
};
};
+
+/**
+ * Get the vertical and horizontal scrollbar sizes
+ * Got from https://stackoverflow.com/questions/986937/how-can-i-get-the-browsers-scrollbar-sizes
+ *
+ * @returns {Array} Array containing the scrollbar horizontal and vertical sizes
+ */
+OHIF.ui.getScrollbarSize = () => {
+ const inner = document.createElement('p');
+ inner.style.width = '100%';
+ inner.style.height = '100%';
+
+ const outer = document.createElement('div');
+ outer.style.position = 'absolute';
+ outer.style.top = '0px';
+ outer.style.left = '0px';
+ outer.style.visibility = 'hidden';
+ outer.style.width = '100px';
+ outer.style.height = '100px';
+ outer.style.overflow = 'hidden';
+ outer.appendChild(inner);
+
+ document.body.appendChild(outer);
+
+ const w1 = inner.offsetWidth;
+ const h1 = inner.offsetHeight;
+ outer.style.overflow = 'scroll';
+ let w2 = inner.offsetWidth;
+ let h2 = inner.offsetHeight;
+
+ if (w1 === w2) {
+ w2 = outer.clientWidth;
+ }
+
+ if (h1 === h2) {
+ h2 = outer.clientHeight;
+ }
+
+ document.body.removeChild(outer);
+
+ return [(w1 - w2), (h1 - h2)];
+};
diff --git a/Packages/ohif-lesiontracker/client/components/timepointBrowser/item.html b/Packages/ohif-lesiontracker/client/components/timepointBrowser/item.html
index 9263dde8e..9b1a4d81a 100644
--- a/Packages/ohif-lesiontracker/client/components/timepointBrowser/item.html
+++ b/Packages/ohif-lesiontracker/client/components/timepointBrowser/item.html
@@ -13,8 +13,8 @@
{{choose instance.summary.get 'Click to load'}}
{{#if this.timepointChildTemplate}}
- {{#if and (not instance.loading.get) instance.loaded}}
- {{>Template.dynamic template=this.timepointChildTemplate data=(clone this studiesInformation=timepoint.studiesData)}}
+ {{#if instance.studiesData.get}}
+ {{>Template.dynamic template=this.timepointChildTemplate data=(clone this studiesInformation=instance.studiesData.get)}}
{{/if}}
{{/if}}
diff --git a/Packages/ohif-lesiontracker/client/components/timepointBrowser/item.js b/Packages/ohif-lesiontracker/client/components/timepointBrowser/item.js
index 5eaa78693..e39c96429 100644
--- a/Packages/ohif-lesiontracker/client/components/timepointBrowser/item.js
+++ b/Packages/ohif-lesiontracker/client/components/timepointBrowser/item.js
@@ -8,15 +8,28 @@ import { OHIF } from 'meteor/ohif:core';
Template.timepointBrowserItem.onCreated(() => {
const instance = Template.instance();
const { timepoint, timepointApi } = instance.data;
+ const { timepointId } = timepoint;
+ const hasStudiesData = !!(timepoint.studiesData && timepoint.studiesData.length);
instance.summary = new ReactiveVar('');
- instance.loading = new ReactiveVar(false);
- instance.loaded = !!(timepoint.studiesData && timepoint.studiesData.length);
+ instance.studiesData = new ReactiveVar(hasStudiesData ? timepoint.studiesData : null);
+
+ const updateStudiesData = newDocument => {
+ const newTimepoint = newDocument || timepointApi.timepoints.findOne({ timepointId });
+ if (newTimepoint && newTimepoint.studiesData && newTimepoint.studiesData.length) {
+ instance.studiesData.set(newTimepoint.studiesData);
+ }
+ };
+
+ timepointApi.timepoints.find({ timepointId }).observe({ changed: updateStudiesData });
// Build the modalities summary of all timepoint's studies
instance.setModalitiesSummary = () => {
+ const studiesData = instance.studiesData.get();
+ if (!studiesData) return;
+
const modalities = {};
- timepoint.studiesData.forEach(study => {
+ studiesData.forEach(study => {
const modality = study.modalities || 'UN';
modalities[modality] = modalities[modality] + 1 || 1;
});
@@ -29,20 +42,22 @@ Template.timepointBrowserItem.onCreated(() => {
const filter = { studyInstanceUid: timepoint.studyInstanceUids };
instance.loadStudies = () => OHIF.studies.searchStudies(filter).then(studiesData => {
- timepoint.studiesData = studiesData;
+ instance.studiesData.set(studiesData);
timepointApi.timepoints.update(timepoint._id, { $set: { studiesData } });
- instance.loaded = true;
instance.setModalitiesSummary();
- instance.loading.set(false);
}).catch(error => {
const text = 'An error has occurred while retrieving studies information';
OHIF.ui.notifications.danger({ text });
OHIF.log.error(error);
});
- if (instance.loaded) {
- instance.setModalitiesSummary();
- }
+ updateStudiesData();
+ instance.autorun(() => {
+ const studiesData = instance.studiesData.get();
+ if (studiesData) {
+ instance.setModalitiesSummary();
+ }
+ });
});
Template.timepointBrowserItem.events({
@@ -58,7 +73,7 @@ Template.timepointBrowserItem.events({
$element.trigger('ohif.lesiontracker.timepoint.click', instance.data.timepoint);
};
- if (!instance.loaded) {
+ if (!instance.studiesData.get()) {
instance.summary.set('Loading...');
instance.loadStudies().then(() => Tracker.afterFlush(triggerClick));
} else {
diff --git a/Packages/ohif-lesiontracker/client/components/timepointBrowser/list.styl b/Packages/ohif-lesiontracker/client/components/timepointBrowser/list.styl
index 5397f7485..653575aa3 100644
--- a/Packages/ohif-lesiontracker/client/components/timepointBrowser/list.styl
+++ b/Packages/ohif-lesiontracker/client/components/timepointBrowser/list.styl
@@ -77,3 +77,9 @@
.timepoint-title
theme('color', '$textPrimaryColor')
padding-top: 2px
+
+.series-quick-switch .timepoint-browser-list
+ padding: 0 10px
+
+ div.timepoint-title
+ text-transform: none
diff --git a/Packages/ohif-lesiontracker/client/components/timepointBrowser/quickSwitch.html b/Packages/ohif-lesiontracker/client/components/timepointBrowser/quickSwitch.html
index 5e7d638cc..99e11f257 100644
--- a/Packages/ohif-lesiontracker/client/components/timepointBrowser/quickSwitch.html
+++ b/Packages/ohif-lesiontracker/client/components/timepointBrowser/quickSwitch.html
@@ -1,6 +1,6 @@
{{>timepointBrowserList (extend timepointBrowserData)}}
- {{#unless instance.showAdditional.get}}
- Show additional timepoints
- {{/unless}}
+ {{#if instance.hasAdditional.get}}
+ Show additional timepoints
+ {{/if}}
diff --git a/Packages/ohif-lesiontracker/client/components/timepointBrowser/quickSwitch.js b/Packages/ohif-lesiontracker/client/components/timepointBrowser/quickSwitch.js
index 51ce41925..52949ed90 100644
--- a/Packages/ohif-lesiontracker/client/components/timepointBrowser/quickSwitch.js
+++ b/Packages/ohif-lesiontracker/client/components/timepointBrowser/quickSwitch.js
@@ -2,45 +2,66 @@ import { Meteor } from 'meteor/meteor';
import { Template } from 'meteor/templating';
import { ReactiveVar } from 'meteor/reactive-var';
import { Tracker } from 'meteor/tracker';
+import { _ } from 'meteor/underscore';
import { OHIF } from 'meteor/ohif:core';
Template.timepointBrowserQuickSwitch.onCreated(() => {
const instance = Template.instance();
- instance.showAdditional = new ReactiveVar(false);
- instance.currentTimepoint = new ReactiveVar();
+ const { timepointApi } = OHIF.viewer;
- instance.updateCurrentTimepoint = studyInstanceUid => {
- const currentTimepoint = OHIF.viewer.timepointApi.study(studyInstanceUid)[0];
- instance.currentTimepoint.set(currentTimepoint);
+ instance.hasAdditional = new ReactiveVar(false);
+ instance.showAdditional = new ReactiveVar(false);
+ instance.selectedTimepoint = new ReactiveVar();
+ instance.timepoints = new ReactiveVar([]);
+
+ instance.updateSelectedTimepoint = studyInstanceUid => {
+ const selectedTimepoint = timepointApi.study(studyInstanceUid)[0];
+ instance.selectedTimepoint.set(selectedTimepoint);
};
+ const currentTimepoint = timepointApi.current();
+ const filter = { latestDate: { $lte: currentTimepoint.latestDate } };
+ instance.keyTimepoints = timepointApi.key(filter);
+
const { viewportIndex } = instance.data;
instance.autorun(() => {
OHIF.viewerbase.layoutManager.observer.depend();
const viewportData = OHIF.viewerbase.layoutManager.viewportData[viewportIndex];
- instance.updateCurrentTimepoint(viewportData.studyInstanceUid);
+ instance.updateSelectedTimepoint(viewportData.studyInstanceUid);
});
instance.autorun(() => {
instance.data.currentStudy.dep.depend();
instance.showAdditional.set(false);
});
+
+ instance.autorun(() => {
+ const showAdditional = instance.showAdditional.get();
+ instance.hasAdditional.set(!showAdditional && instance.keyTimepoints.length > 1);
+ });
+
+ instance.autorun(() => {
+ const selectedTimepoint = instance.selectedTimepoint.get();
+ const showAdditional = instance.showAdditional.get();
+ const timepoints = showAdditional ? instance.keyTimepoints : [selectedTimepoint];
+ instance.timepoints.set(timepoints);
+ });
});
Template.timepointBrowserQuickSwitch.onRendered(() => {
const instance = Template.instance();
instance.autorun(() => {
- const currentTimepoint = instance.currentTimepoint.get();
- const currentTimepointId = (currentTimepoint && currentTimepoint.timepointId) || '';
+ const selectedTimepoint = instance.selectedTimepoint.get();
+ const selectedTimepointId = (selectedTimepoint && selectedTimepoint.timepointId) || '';
const $allBrowserItems = instance.$('.timepoint-browser-item');
- const $browserItem = $allBrowserItems.filter(`[data-id=${currentTimepointId}]`);
+ const $browserItem = $allBrowserItems.filter(`[data-id=${selectedTimepointId}]`);
if (!$browserItem.hasClass('active')) {
$browserItem.find('.timepoint-item').trigger('click');
}
});
- instance.autorun(() => {
+ instance.updateActiveStudy = () => {
const currentStudy = instance.data.currentStudy.get();
const studyInstanceUid = (currentStudy && currentStudy.studyInstanceUid) || '';
Tracker.afterFlush(() => {
@@ -48,15 +69,16 @@ Template.timepointBrowserQuickSwitch.onRendered(() => {
$studyBrowserItems.removeClass('active');
$studyBrowserItems.filter(`[data-uid="${studyInstanceUid}"]`).addClass('active');
});
- });
+ };
+
+ instance.autorun(instance.updateActiveStudy);
});
Template.timepointBrowserQuickSwitch.events({
'ohif.lesiontracker.timepoint.click'(event, instance) {
const $element = $(event.currentTarget);
-
- // Defer the active class toggling to wait for child template rendering
- Meteor.defer(() => $element.toggleClass('active'));
+ $element.toggleClass('active');
+ instance.updateActiveStudy();
},
'ohif.studies.study.click'(event, instance, studyInformation) {
@@ -65,29 +87,39 @@ Template.timepointBrowserQuickSwitch.events({
instance.data.currentStudy.set(study);
const $studySwitch = $(event.currentTarget).closest('.study-switch');
$studySwitch.siblings('.series-switch').trigger('rescale');
- instance.updateCurrentTimepoint(studyInformation.studyInstanceUid);
+ instance.updateSelectedTimepoint(studyInformation.studyInstanceUid);
+
+ // Create a hover bridge to prevent quick switch from closing due to scroll height
+ Meteor.defer(() => {
+ const $scrollable = $studySwitch.find('.study-browser>.scrollable');
+ const offsetY = $scrollable.offset().top + $scrollable.outerHeight();
+ if (event.clientY > offsetY) {
+ const hoverHandler = _.throttle(event => {
+ if (event.clientY <= offsetY) {
+ $scrollable.css('padding-bottom', '');
+ $scrollable.off('mousemove', hoverHandler);
+ $scrollable.off('mouseleave', hoverHandler);
+ }
+ }, 100);
+ $scrollable.css('padding-bottom', event.clientY - offsetY + 20);
+ $scrollable.on('mousemove', hoverHandler);
+ $scrollable.one('mouseleave', () => $scrollable.off('mousemove', hoverHandler));
+ }
+ });
},
- 'click .show-additional'(event, instance) {
+ 'click .study-item-box.additional'(event, instance) {
instance.showAdditional.set(true);
- },
+ }
});
Template.timepointBrowserQuickSwitch.helpers({
timepointBrowserData() {
const instance = Template.instance();
const { timepointApi } = OHIF.viewer;
- const currentTimepoint = instance.currentTimepoint.get();
- let timepoints;
- if (instance.showAdditional.get()) {
- timepoints = timepointApi.key();
- } else {
- timepoints = [currentTimepoint];
- }
-
return {
timepointApi,
- timepoints,
+ timepoints: instance.timepoints.get(),
timepointChildTemplate: 'timepointBrowserStudies'
};
}
diff --git a/Packages/ohif-measurements/both/configuration/timepoints.js b/Packages/ohif-measurements/both/configuration/timepoints.js
index a76ebc370..c28320a42 100644
--- a/Packages/ohif-measurements/both/configuration/timepoints.js
+++ b/Packages/ohif-measurements/both/configuration/timepoints.js
@@ -192,11 +192,11 @@ class TimepointApi {
}
// Return only the key timepoints (current, prior, nadir and baseline)
- key() {
+ key(filter={}) {
const result = [];
// Get all the timepoints
- const all = this.all();
+ const all = this.all(filter);
// Iterate over each timepoint and insert the key ones in the result
_.each(all, (timepoint, index) => {
diff --git a/Packages/ohif-studies/imports/client/components/browser/item.js b/Packages/ohif-studies/imports/client/components/browser/item.js
index ab4f84d7c..6d8cc0d46 100644
--- a/Packages/ohif-studies/imports/client/components/browser/item.js
+++ b/Packages/ohif-studies/imports/client/components/browser/item.js
@@ -22,7 +22,13 @@ Template.studyBrowserItem.events({
const { studyInformation } = instance.data;
const element = event.currentTarget.parentElement;
const $element = $(element);
- const triggerClick = () => $element.trigger('ohif.studies.study.click', studyInformation);
+ const triggerClick = () => {
+ const cloneEvent = _.clone(event);
+ delete cloneEvent.type;
+ cloneEvent.currentTarget = cloneEvent.target = element;
+ const newEvent = $.Event('ohif.studies.study.click', cloneEvent);
+ $element.trigger(newEvent, studyInformation);
+ };
if (instance.loaded) {
triggerClick();
diff --git a/Packages/ohif-viewerbase/client/components/viewer/seriesQuickSwitch/seriesQuickSwitch.js b/Packages/ohif-viewerbase/client/components/viewer/seriesQuickSwitch/seriesQuickSwitch.js
index 023b6172d..fa87c3643 100644
--- a/Packages/ohif-viewerbase/client/components/viewer/seriesQuickSwitch/seriesQuickSwitch.js
+++ b/Packages/ohif-viewerbase/client/components/viewer/seriesQuickSwitch/seriesQuickSwitch.js
@@ -3,10 +3,6 @@ import { ReactiveVar } from 'meteor/reactive-var';
import { $ } from 'meteor/jquery';
import { OHIF } from 'meteor/ohif:core';
-// FIXME >>>> REMOVE
-$(document.body).on('keydown', e => (e.keyCode === 69 && $('.quickSwitchWrapper').toggle()) || 1);
-OHIF.cornerstone.renderer = '';
-
Template.seriesQuickSwitch.onCreated(() => {
const instance = Template.instance();