LT-242: Creating UI resizable, improving heads up display layout and fixing tool selection behavior

This commit is contained in:
Bruno Alves de Faria 2016-07-01 16:40:28 -03:00 committed by Erik Ziegler
parent 40062e2e9d
commit 9beee70081
22 changed files with 515 additions and 270 deletions

View File

@ -17,7 +17,7 @@ $textColorActive = #2D2D2D
.roundedButton .roundedButton
align-items: center align-items: center
background-color: $uiGrayDarker background-color: $uiGrayDark
border: 1px $uiBorderColorDark solid border: 1px $uiBorderColorDark solid
color: $textSecondaryColor color: $textSecondaryColor
display: flex display: flex
@ -56,7 +56,7 @@ $textColorActive = #2D2D2D
&:hover .roundedButton &:hover .roundedButton
background-color: $boxBackgroundColor background-color: $boxBackgroundColor
color: $uiGrayDarker color: $uiGrayDark
&.active .roundedButton &.active .roundedButton
background-color: $activeColor background-color: $activeColor
@ -66,5 +66,5 @@ $textColorActive = #2D2D2D
&:hover .roundedButton &:hover .roundedButton
&.active .roundedButton &.active .roundedButton
svg svg
fill: $uiGrayDarker fill: $uiGrayDark
stroke: $uiGrayDarker stroke: $uiGrayDark

View File

@ -1,9 +1,11 @@
// Common pallete // Common pallete
$uiYellow = #E29E4A $uiYellow = #E29E4A
$uiSkyBlue = #6FBDE2 $uiSkyBlue = #6FBDE2
$uiGrayDark = #263340
$uiGrayDarker = #16202B $uiGray = #263340
$uiGrayDarkest = #151A1F $uiGrayDark = #16202B
$uiGrayDarker = #151A1F
$uiGrayDarkest = #14191E
// Interface UI Colors // Interface UI Colors
$defaultColor = #94A8B3 $defaultColor = #94A8B3

View File

@ -153,7 +153,9 @@
<title> <title>
Close Close
</title> </title>
<polygon id="Shape" points="14 1.4 12.6 0 7 5.6 1.4 0 0 1.4 5.6 7 0 12.6 1.4 14 7 8.4 12.6 14 14 12.6 8.4 7"/> <g id="icon-ui-close-group" stroke-width="1.75">
<path id="icon-ui-close-path" d="M1,1 13,13 M1,13 13,1" />
</g>
</symbol> </symbol>
<symbol id="icon-create-comment" viewBox="0 0 37 34"> <symbol id="icon-create-comment" viewBox="0 0 37 34">
<title> <title>

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 9.9 KiB

View File

@ -29,7 +29,7 @@
font-size: 14px font-size: 14px
padding: 0 10px padding: 0 10px
color: $textPrimaryColor color: $textPrimaryColor
background-color: $uiGrayDarker background-color: $uiGrayDark
.form-group .form-group
padding: 10px padding: 10px

View File

@ -1,13 +1,16 @@
<template name="lesionTableHUD"> <template name="lesionTableHUD">
<div id="lesionTableHUD"> <div id="lesionTableHUD" class="{{hudHidden}}">
<div class="header"> <div class="header">
Measurements <span>Measurements</span>
<svg class="buttonClose">
<use xlink:href="/packages/lesiontracker/assets/icons.svg#icon-ui-close"></use>
</svg>
</div> </div>
{{ >lesionTableView }} {{>lesionTableView}}
<div class="footer"> <div class="footer">
{{ #each toolbarButtons }} {{#each toolbarButton in toolbarButtons}}
{{ >toolbarSectionButton }} {{>toolbarSectionButton toolbarButton}}
{{ /each }} {{/each}}
</div> </div>
</div> </div>
</template> </template>

View File

@ -1,4 +1,18 @@
Template.lesionTableHUD.onRendered(() => {
const instance = Template.instance();
instance.$('#lesionTableHUD').resizable().draggable();
});
Template.lesionTableHUD.events({
'click .buttonClose'(event, instance) {
Session.set('lesionTableHudOpen', false);
}
});
Template.lesionTableHUD.helpers({ Template.lesionTableHUD.helpers({
hudHidden() {
return Session.get('lesionTableHudOpen') ? '' : 'hidden';
},
toolbarButtons() { toolbarButtons() {
var buttonData = []; var buttonData = [];
@ -26,8 +40,3 @@ Template.lesionTableHUD.helpers({
return buttonData; return buttonData;
} }
}); });
Template.lesionTableHUD.onRendered(function() {
var dialog = $('#lesionTableHUD');
dialog.draggable();
});

View File

@ -1,34 +1,47 @@
@import "{design}/app" @import "{design}/app"
$borderColor = rgba(77, 99, 110, 0.81) $borderColor = rgba(77, 99, 110, 0.81)
$backgroundColor = #14191e
#lesionTableHUD #lesionTableHUD
display: none
position: absolute
top: auto
left: auto
bottom: 3px
right: 3px
z-index: 10000
width: 318px
height: 326px
opacity: 0.95
background: black background: black
border-radius: 8px border-radius: 8px
border: solid 1px $borderColor; border: solid 1px $borderColor;
bottom: 3px
height: 326px
left: auto
opacity: 0.95
overflow: hidden
position: absolute
right: 3px
top: auto
width: 318px
z-index: 10000
.lesionTableView.scrollArea
margin-left: 0
padding-left: 0
.header .header
width: 100% background: $uiGrayDarkest
border-bottom: $uiBorderThickness solid $borderColor
color: $textSecondaryColor
font-weight: 300
font-size: 20px
height: 55px height: 55px
line-height: 55px line-height: 55px
background: $backgroundColor position: relative
border-bottom: $uiBorderThickness solid $borderColor
text-align: center text-align: center
font-weight: 200 width: 100%
font-size: 20px
color: $textSecondaryColor svg.buttonClose
color: $defaultColor
cursor: pointer
height: 14px
position: absolute
right: 14px
stroke: $defaultColor
top: 20px
width: 14px
.lesionTableView.scrollArea .lesionTableView.scrollArea
height: calc(100% - 55px - 70px) height: calc(100% - 55px - 70px)
@ -39,7 +52,7 @@ $backgroundColor = #14191e
height: 70px height: 70px
position: absolute position: absolute
bottom: 0 bottom: 0
background: $backgroundColor background: $uiGrayDarkest
border-top: $uiBorderThickness solid $borderColor border-top: $uiBorderThickness solid $borderColor
padding: 10px padding: 10px

View File

@ -3,7 +3,7 @@
$headerRowHeight = 63px $headerRowHeight = 63px
.lesionTableHeaderRow .lesionTableHeaderRow
background-color: $uiGrayDarkest background-color: $uiGrayDarker
color: $textSecondaryColor color: $textSecondaryColor
display: flex display: flex
fill: $textSecondaryColor fill: $textSecondaryColor

View File

@ -31,7 +31,7 @@
&.response-status .lesionRowSidebar .response-status-icon &.response-status .lesionRowSidebar .response-status-icon
background-color: $defaultColor background-color: $defaultColor
border-radius: 11px border-radius: 11px
color: $uiGrayDark color: $uiGray
font-size: 12px font-size: 12px
font-weight: 700 font-weight: 700
height: 21px height: 21px
@ -55,7 +55,7 @@
fill: $textPrimaryColor fill: $textPrimaryColor
.lesionRowSidebar .lesionRowSidebar
background: $uiGrayDark background: $uiGray
color: $textSecondaryColor color: $textSecondaryColor
flex: 1 flex: 1
max-width: 30px max-width: 30px

View File

@ -10,9 +10,11 @@
{{>lesionTableRow (extend this rowItem=nonTarget)}} {{>lesionTableRow (extend this rowItem=nonTarget)}}
{{/each}} {{/each}}
{{#if gt this.timepoints.get.length 1}}
{{>lesionTableHeaderRow id="newLesion" measurements=newLesions currentTimepointId=currentTimepointId}} {{>lesionTableHeaderRow id="newLesion" measurements=newLesions currentTimepointId=currentTimepointId}}
{{#each newLesion in newLesions}} {{#each newLesion in newLesions}}
{{>lesionTableRow (extend this rowItem=newLesion)}} {{>lesionTableRow (extend this rowItem=newLesion)}}
{{/each}} {{/each}}
{{/if}}
</div> </div>
</template> </template>

View File

@ -1,3 +1,5 @@
@import "{design}/app"
.lesionTableView.scrollArea .lesionTableView.scrollArea
width: 100% width: 100%
height: 100% height: 100%

View File

@ -100,7 +100,7 @@ $seriesSpacing = 2px
.studyTimepointStudy.active .studyModality .studyTimepointStudy.active .studyModality
box-shadow: inset 0 0 0 3px $activeColor box-shadow: inset 0 0 0 3px $activeColor
.studyBox .studyBox
background-color: $uiGrayDarker background-color: $uiGrayDark
border: solid 1px $activeColor border: solid 1px $activeColor
border-radius: 11px border-radius: 11px
display: block display: block

View File

@ -39,7 +39,7 @@
<div class="pull-right m-t-1 rm-x-1"> <div class="pull-right m-t-1 rm-x-1">
{{>roundedButtonGroup rightSidebarToggleButtonData}} {{>roundedButtonGroup rightSidebarToggleButtonData}}
</div> </div>
<div id="toggleHUD" class="toolbarSectionButton pull-right rp-x-1 m-t-1 rm-r-3"> <div id="toggleHUD" class="toolbarSectionButton pull-right rp-x-1 m-t-1 rm-r-3 {{#if session 'lesionTableHudOpen'}}active{{/if}}">
<div class="svgContainer"> <div class="svgContainer">
<svg> <svg>
<use xlink:href="/packages/lesiontracker/assets/icons.svg#icon-hud"></use> <use xlink:href="/packages/lesiontracker/assets/icons.svg#icon-hud"></use>

View File

@ -106,39 +106,9 @@ Template.toolbarSection.helpers({
}); });
Template.toolbarSection.events({ Template.toolbarSection.events({
// TODO: Inherit these from toolbar template somehow 'click #toggleHUD'(event, instance) {
'click .imageViewerTool': function(e) { const state = Session.get('lesionTableHudOpen');
$(e.currentTarget).tooltip('hide'); Session.set('lesionTableHudOpen', !state);
var tool = e.currentTarget.id;
var elements = $('.imageViewerViewport');
var activeTool = toolManager.getActiveTool();
if (tool === activeTool) {
var defaultTool = toolManager.getDefaultTool();
console.log('Setting active tool to: ' + defaultTool);
toolManager.setActiveTool(defaultTool, elements);
} else {
console.log('Setting active tool to: ' + tool);
toolManager.setActiveTool(tool, elements);
}
},
'click .imageViewerCommand': function(e) {
$(e.currentTarget).tooltip('hide');
var command = e.currentTarget.id;
if (!OHIF.viewer.functionList.hasOwnProperty(command)) {
return;
}
var activeViewport = Session.get('activeViewport');
var element = $('.imageViewerViewport').get(activeViewport);
OHIF.viewer.functionList[command](element);
},
'click #toggleHUD': function(e) {
var lesionTableHUD = document.getElementById('lesionTableHUD');
toggleDialog(lesionTableHUD);
}, },
'click #moreTools'(event, instance) { 'click #moreTools'(event, instance) {
const $target = $(event.currentTarget); const $target = $(event.currentTarget);

View File

@ -23,7 +23,7 @@
width: 100% width: 100%
.toolbarSectionDrawer .toolbarSectionDrawer
background-color: $uiGrayDarkest background-color: $uiGrayDarker
border-radius: 7px border-radius: 7px
color: $textPrimaryColor color: $textPrimaryColor
content: '' content: ''

View File

@ -11,3 +11,35 @@ Template.toolbarSectionButton.helpers({
return; return;
} }
}); });
Template.toolbarSectionButton.events({
'click .imageViewerTool'(event, instance) {
$(event.currentTarget).tooltip('hide');
var tool = event.currentTarget.id;
var elements = $('.imageViewerViewport');
var activeTool = toolManager.getActiveTool();
if (tool === activeTool) {
var defaultTool = toolManager.getDefaultTool();
console.log('Setting active tool to: ' + defaultTool);
toolManager.setActiveTool(defaultTool, elements);
} else {
console.log('Setting active tool to: ' + tool);
toolManager.setActiveTool(tool, elements);
}
},
'click .imageViewerCommand'(event, instance) {
$(event.currentTarget).tooltip('hide');
var command = event.currentTarget.id;
if (!OHIF.viewer.functionList.hasOwnProperty(command)) {
return;
}
var activeViewport = Session.get('activeViewport');
var element = $('.imageViewerViewport').get(activeViewport);
OHIF.viewer.functionList[command](element);
}
});

View File

@ -3,6 +3,11 @@ Template.registerHelper('instance', () => {
return Template.instance(); return Template.instance();
}); });
// Return the session value for the given key
Template.registerHelper('session', key => {
return Session.get(key);
});
// Create a new object and extends it with the argument objects // Create a new object and extends it with the argument objects
Template.registerHelper('extend', (...argsArray) => { Template.registerHelper('extend', (...argsArray) => {
// Create the resulting object // Create the resulting object

View File

@ -1,6 +1,7 @@
// Allow attaching to jQuery selectors // Allow attaching to jQuery selectors
$.fn.draggable = function() { $.fn.draggable = function() {
makeDraggable(this); makeDraggable(this);
return this;
}; };
/** /**

View File

@ -0,0 +1,147 @@
// Allow attaching to jQuery selectors
$.fn.resizable = function(options) {
_.each(this, element => {
const resizableInstance = $(element).data('resizableInstance');
if (options === 'destroy' && resizableInstance) {
$(element).removeData('resizableInstance');
resizableInstance.destroy();
} else {
if (resizableInstance) {
resizableInstance.options(options);
} else {
$(element).data('resizableInstance', new Resizable(element, options));
}
}
});
return this;
};
/**
* This class makes an element resizable.
*/
class Resizable {
constructor(element, options={}) {
this.element = element;
this.$element = $(element);
this.options(options);
}
options(options={}) {
const { boundSize, minWidth, minHeight } = options;
this.minWidth = minWidth || this.$element.width() || 16;
this.minHeight = minHeight || this.$element.height() || 16;
this.boundSize = boundSize || 8;
this.destroy();
this.init();
}
init() {
for (var x = -1; x <= 1; x++) {
for (var y = -1; y <= 1; y++) {
this.createBound(x, y);
}
}
this.$element.addClass('resizable');
}
destroy() {
this.$element.removeClass('resizable').find('resize-bound').remove();
}
attachEventHandlers($bound, xDirection, yDirection) {
const $window = $(window);
const initResizeHandler = event => {
event.stopPropagation();
this.width = this.initialWidth = this.$element.width();
this.height = this.initialHeight = this.$element.height();
this.startWidth = this.width;
this.startHeight = this.height;
this.posX = parseInt(this.$element.css('left'));
this.posY = parseInt(this.$element.css('top'));
this.startPosX = this.posX;
this.startPosY = this.posY;
this.startX = event.clientX;
this.startY = event.clientY;
this.$element.addClass('resizing');
$window.on('mousemove', resizeHandler);
$window.on('mouseup', endResizeHandler);
};
const resizeHandler = event => {
let x, y;
x = event.clientX < 0 ? 0 : event.clientX;
x = x > window.innerWidth ? window.innerWidth : x;
y = event.clientY < 0 ? 0 : event.clientY;
y = y > window.innerHeight ? window.innerHeight : y;
const xDistance = (x - this.startX) * xDirection;
const yDistance = (y - this.startY) * yDirection;
const width = xDistance + this.startWidth;
const height = yDistance + this.startHeight;
this.width = width < this.minWidth ? this.minWidth : width;
this.height = height < this.minHeight ? this.minHeight : height;
this.$element.width(this.width);
this.$element.height(this.height);
if (xDirection < 0) {
this.posX = this.startPosX - xDistance;
if (width < this.minWidth) {
this.posX = this.startPosX + (this.startWidth - this.minWidth);
}
this.$element.css('left', `${this.posX}px`);
}
if (yDirection < 0) {
this.posY = this.startPosY - yDistance;
if (height < this.minHeight) {
this.posY = this.startPosY + (this.startHeight - this.minHeight);
}
this.$element.css('top', `${this.posY}px`);
}
};
const endResizeHandler = event => {
$window.off('mousemove', resizeHandler);
$window.off('mouseup', endResizeHandler);
this.$element.removeClass('resizing');
};
$bound.on('mousedown', initResizeHandler);
}
createBound(xDirection, yDirection) {
if (xDirection === 0 && xDirection === yDirection) {
return;
}
const $bound = $('<div class="resize-bound"></div>');
$bound[0].onselectstart = () => false;
$bound.css('font-size', `${this.boundSize}px`);
const mapX = ['left', 'center', 'right'];
const mapY = ['top', 'middle', 'bottom'];
$bound.addClass('bound-' + mapX[xDirection + 1]);
$bound.addClass('bound-' + mapY[yDirection + 1]);
$bound.appendTo(this.$element);
this.attachEventHandlers($bound, xDirection, yDirection);
}
}

View File

@ -0,0 +1,55 @@
@import "{design}/app"
.resizable
transform(scale(1))
&.resizing, .resize-bound
user-select: none
-webkit-touch-callout: none
-webkit-user-select: none
-khtml-user-select: none
-moz-user-select: none
-ms-user-select: none
.resize-bound
content: ''
line-height: 1em
position: fixed
.bound-left
left: 0
width: 1em
.bound-center
left: 1em
height: 1em
right: 1em
.bound-right
right: 0
width: 1em
.bound-top
top: 0
height: 1em
.bound-middle
top: 1em
width: 1em
bottom: 1em
.bound-bottom
bottom: 0
height: 1em
.bound-left.bound-top, .bound-right.bound-bottom
cursor: nwse-resize
.bound-left.bound-bottom, .bound-right.bound-top
cursor: nesw-resize
.bound-left.bound-middle, .bound-right.bound-middle
cursor: ew-resize
.bound-center.bound-top, .bound-center.bound-bottom
cursor: ns-resize

View File

@ -117,7 +117,9 @@ Package.onUse(function(api) {
api.addFiles('lib/toolManager.js', 'client'); api.addFiles('lib/toolManager.js', 'client');
api.addFiles('lib/enablePrefetchOnElement.js', 'client'); api.addFiles('lib/enablePrefetchOnElement.js', 'client');
api.addFiles('lib/displayReferenceLines.js', 'client'); api.addFiles('lib/displayReferenceLines.js', 'client');
api.addFiles('lib/draggable.js', 'client'); api.addFiles('lib/ui/draggable/draggable.js', 'client');
api.addFiles('lib/ui/resizable/resizable.js', 'client');
api.addFiles('lib/ui/resizable/resizable.styl', 'client');
api.addFiles('lib/toggleDialog.js', 'client'); api.addFiles('lib/toggleDialog.js', 'client');
api.addFiles('lib/setActiveViewport.js', 'client'); api.addFiles('lib/setActiveViewport.js', 'client');
api.addFiles('lib/switchToImageByIndex.js', 'client'); api.addFiles('lib/switchToImageByIndex.js', 'client');

View File

@ -8,13 +8,13 @@ $inputBackgroundColor = #2c363f
$inputPlaceholderColor = lightgray $inputPlaceholderColor = lightgray
$studyListToolbarHeight = 75px $studyListToolbarHeight = 75px
$theadBackgroundColor = $uiGrayDarkest $theadBackgroundColor = $uiGrayDarker
$tablePadding = 8% $tablePadding = 8%
$bodyCellHeight = 40px $bodyCellHeight = 40px
.studyListToolbar .studyListToolbar
height: $studyListToolbarHeight height: $studyListToolbarHeight
background: $uiGrayDarkest background: $uiGrayDarker
border-bottom: 2px solid black border-bottom: 2px solid black
padding: 0 30px padding: 0 30px
@ -149,7 +149,7 @@ $bodyCellHeight = 40px
background-color: black background-color: black
&:nth-child(even) &:nth-child(even)
background-color: $uiGrayDarkest background-color: $uiGrayDarker
td td
height: $bodyCellHeight height: $bodyCellHeight