Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(createLayerInterface): add download button #723

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
563 changes: 0 additions & 563 deletions package-lock.json

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@
"itk-image-io": "^1.0.0-b.84",
"itk-mesh-io": "^1.0.0-b.84",
"itk-viewer-color-maps": "^1.2.0",
"itk-viewer-icons": "11.14.0",
"itk-viewer-transfer-function-editor": "^1.2.5",
"itk-wasm": "^1.0.0-b.83",
"mobx": "^5.15.7",
Expand Down
1 change: 1 addition & 0 deletions src/Context/ViewerMachineContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class ViewerMachineContext {

// Todo: add config serialization / deserializeation
this.layers = new LayersMachineContext()
this.layers.showSaveRoiButton = config?.showSaveRoiButton ?? false
this.images = new ImagesMachineContext()
this.widgets = new WidgetsMachineContext()
}
Expand Down
59 changes: 48 additions & 11 deletions src/UI/reference-ui/dist/referenceUIMachineOptions.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,21 +113,24 @@ var style = {
}
styleInject(css_248z$1)

const optimizedSVGDataUri$w =
const optimizedSVGDataUri$x =
"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1664 1536'%3e%3cpath d='M725 431L555 881q33 0 136.5 2t160.5 2q19 0 57-2-87-253-184-452zM0 1536l2-79q23-7 56-12.5t57-10.5 49.5-14.5 44.5-29 31-50.5l237-616L757 0h128q8 14 11 21l205 480q33 78 106 257.5t114 274.5q15 34 58 144.5t72 168.5q20 45 35 57 19 15 88 29.5t84 20.5q6 38 6 57 0 4-.5 13t-.5 13q-63 0-190-8t-191-8q-76 0-215 7t-178 8q0-43 4-78l131-28q1 0 12.5-2.5t15.5-3.5 14.5-4.5 15-6.5 11-8 9-11 2.5-14q0-16-31-96.5t-72-177.5-42-100l-450-2q-26 58-76.5 195.5T382 1361q0 22 14 37.5t43.5 24.5 48.5 13.5 57 8.5 41 4q1 19 1 58 0 9-2 27-58 0-174.5-10T236 1514q-8 0-26.5 4t-21.5 4q-80 14-188 14z'/%3e%3c/svg%3e"

const optimizedSVGDataUri$v =
const optimizedSVGDataUri$w =
"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 43 41.91699981689453'%3e%3cpath d='M15 24.089V7.375L9 13V7.5L17 0l8 7.5V13l-6-5.625v15.542h16.625l-5.625-6h5.5l7.5 8-7.5 8H30l5.625-6H17.828l-11 11H15l-4 4H0v-11l4-4v8.172l11-11zm6.253 8.361L18.8 37.262v2.655h-1.707v-2.625l-2.346-4.842h1.921l1.195 2.785.17.61h.022l.165-.588 1.252-2.807h1.781zm8.267-10.533h-2.03l-1.308-2.432-.154-.5h-.021l-.175.522-1.314 2.41H22.48l2.42-3.733-2.207-3.734h2.079l1.083 2.239.227.63h.021l.235-.65 1.194-2.219h1.881l-2.235 3.702 2.342 3.765zm-16.48 1H6.96v-.985l3.875-5.095H7.28V15.45h5.76v.955L9.248 21.53h3.792v1.387z'/%3e%3c/svg%3e"

const optimizedSVGDataUri$u =
const optimizedSVGDataUri$v =
"data:image/svg+xml,%3c%3fxml version='1.0' encoding='UTF-8' standalone='no'%3f%3e %3csvg viewBox='0 0 1763.3333740234375 1792' version='1.1' id='svg113' sodipodi:docname='blendMode.svg' inkscape:version='1.2 (1:1.2%2b202206011326%2bfc4e4096c5)' xmlns:inkscape='http://www.inkscape.org/namespaces/inkscape' xmlns:sodipodi='http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd' xmlns='http://www.w3.org/2000/svg' xmlns:svg='http://www.w3.org/2000/svg'%3e %3cdefs id='defs117' /%3e %3csodipodi:namedview id='namedview115' pagecolor='white' bordercolor='black' borderopacity='0.25' inkscape:showpageshadow='2' inkscape:pageopacity='0.0' inkscape:pagecheckerboard='0' inkscape:deskcolor='%23d1d1d1' showgrid='false' inkscape:zoom='0.27047836' inkscape:cx='763.46218' inkscape:cy='1454.8299' inkscape:window-width='1846' inkscape:window-height='1136' inkscape:window-x='74' inkscape:window-y='27' inkscape:window-maximized='1' inkscape:current-layer='svg113' /%3e %3cellipse style='fill:none%3bfill-opacity:1%3bstroke:black%3bstroke-width:149.145%3bstroke-dasharray:none%3bstroke-opacity:1' id='path223' cx='601' cy='899.99982' rx='525.42761' ry='525.42743' /%3e %3ccircle style='fill:black%3bfill-opacity:1%3bstroke:none%3bstroke-width:100%3bstroke-dasharray:none%3bstroke-opacity:1' id='path223-3' cx='1163' cy='900' r='600' /%3e %3c/svg%3e"

const optimizedSVGDataUri$t =
const optimizedSVGDataUri$u =
"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3e%3cpath fill='currentColor' d='M17 22v-2h3v-3h2v3.5c0 .39-.16.74-.46 1.04c-.3.3-.65.46-1.04.46H17M7 22H3.5c-.39 0-.74-.16-1.04-.46c-.3-.3-.46-.65-.46-1.04V17h2v3h3v2M17 2h3.5c.39 0 .74.16 1.04.46c.3.3.46.65.46 1.04V7h-2V4h-3V2M7 2v2H4v3H2V3.5c0-.39.16-.74.46-1.04c.3-.3.65-.46 1.04-.46H7m6 15.25l4-2.3v-4.59l-4 2.3v4.59m-1-6.33l4-2.29l-4-2.35l-4 2.35l4 2.29m-5 4.03l4 2.3v-4.59l-4-2.3v4.59m11.23-7.36c.5.32.77.75.77 1.32v6.32c0 .57-.27 1-.77 1.32l-5.48 3.18c-.5.32-1 .32-1.5 0l-5.48-3.18c-.5-.32-.77-.75-.77-1.32V8.91c0-.57.27-1 .77-1.32l5.48-3.18c.25-.13.5-.19.75-.19s.5.06.75.19l5.48 3.18Z'/%3e%3c/svg%3e"

const optimizedSVGDataUri$s =
const optimizedSVGDataUri$t =
"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 384 384'%3e%3cpath d='M64 0h32v48H64zm32 288V112H64v208h208v-32zm240 0h48v32h-48z'/%3e%3cpath d='M0 64v32h288v288h32V64z'/%3e%3c/svg%3e"

const optimizedSVGDataUri$s =
"data:image/svg+xml,%3c%3fxml version='1.0' encoding='utf-8'%3f%3e%3c!-- Uploaded to: SVG Repo%2c www.svgrepo.com%2c Generator: SVG Repo Mixer Tools --%3e %3csvg fill='black' width='800px' height='800px' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M7.293%2c13.707a1%2c1%2c0%2c1%2c1%2c1.414-1.414L11%2c14.586V3a1%2c1%2c0%2c0%2c1%2c2%2c0V14.586l2.293-2.293a1%2c1%2c0%2c0%2c1%2c1.414%2c1.414l-4%2c4a1%2c1%2c0%2c0%2c1-.325.216.986.986%2c0%2c0%2c1-.764%2c0%2c1%2c1%2c0%2c0%2c1-.325-.216ZM22%2c12a1%2c1%2c0%2c0%2c0-1%2c1v7H3V13a1%2c1%2c0%2c0%2c0-2%2c0v8a1%2c1%2c0%2c0%2c0%2c1%2c1H22a1%2c1%2c0%2c0%2c0%2c1-1V13A1%2c1%2c0%2c0%2c0%2c22%2c12Z'/%3e%3c/svg%3e"

const optimizedSVGDataUri$r =
"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1536 1536'%3e%3cpath d='M1283 413L928 768l355 355 144-144q29-31 70-14 39 17 39 59v448q0 26-19 45t-45 19h-448q-42 0-59-40-17-39 14-69l144-144-355-355-355 355 144 144q31 30 14 69-17 40-59 40H64q-26 0-45-19t-19-45v-448q0-42 40-59 39-17 69 14l144 144 355-355-355-355-144 144q-19 19-45 19-12 0-24-5-40-17-40-59V64q0-26 19-45T64 0h448q42 0 59 40 17 39-14 69L413 253l355 355 355-355-144-144q-31-30-14-69 17-40 59-40h448q26 0 45 19t19 45v448q0 42-39 59-13 5-25 5-26 0-45-19z'/%3e%3c/svg%3e"

Expand Down Expand Up @@ -531,7 +534,7 @@ function createAnnotationsButton(context, mainUIRow) {
.concat(style.annotationsButton, ' ')
.concat(style.toggleButton, '" for="')
.concat(context.id, '-toggleAnnotationsButton"><img src="')
.concat(optimizedSVGDataUri$w, '" alt="annotations"/></label>')
.concat(optimizedSVGDataUri$x, '" alt="annotations"/></label>')
var annotationsButtonInput = annotationsButton.children[0]
var annotationsButtonLabel = annotationsButton.children[1]
context.main.annotationsButtonLabel = annotationsButtonLabel
Expand Down Expand Up @@ -567,7 +570,7 @@ function createAxesButton(context, mainUIRow) {
.concat(style.axesButton, ' ')
.concat(style.toggleButton, '" for="')
.concat(context.id, '-toggleAxesButton"><img src="')
.concat(optimizedSVGDataUri$v, '" alt="axes"/></label>')
.concat(optimizedSVGDataUri$w, '" alt="axes"/></label>')
var axesButtonInput = axesButton.children[0]
var axesButtonLabel = axesButton.children[1]
context.main.axesButtonLabel = axesButtonLabel
Expand Down Expand Up @@ -2125,7 +2128,7 @@ function createCroppingButtons(context, mainUIRow) {
.concat(style.cropButton, ' ')
.concat(style.toggleButton, '" for="')
.concat(viewerDOMId, '-toggleCroppingPlanesButton"><img src="')
.concat(optimizedSVGDataUri$s, '" alt="crop"/></label>')
.concat(optimizedSVGDataUri$t, '" alt="crop"/></label>')
var cropButtonInput = cropButton.children[0]
var cropButtonLabel = cropButton.children[1]
context.main.cropButtonLabel = cropButtonLabel
Expand Down Expand Up @@ -8014,11 +8017,11 @@ function createLayerEntry(context, name, layer) {
.concat(context.id, '-layerBBoxButton" type="checkbox" class="')
.concat(
style.toggleInput,
'"><label itk-vtk-tooltip itk-vtk-tooltip-left itk-vtk-tooltip-content="Label BBox" class="'
'"><label itk-vtk-tooltip itk-vtk-tooltip-top itk-vtk-tooltip-content="Label BBox" class="'
)
.concat(style.toggleButton, '" for="')
.concat(context.id, '-layerBBoxButton"><img src="')
.concat(optimizedSVGDataUri$t, '" alt="bbox"/></label>')
.concat(optimizedSVGDataUri$u, '" alt="bbox"/></label>')
var layerBBoxButtonInput = layerBBoxButton.children[0]
var layerBBoxLabel = layerBBoxButton.children[1]
layerBBoxButton.style.height = '23px'
Expand All @@ -8041,6 +8044,40 @@ function createLayerEntry(context, name, layer) {
var actorContext = context.layers.actorContext.get(name)
layerBBoxButtonInput.checked = actorContext.bbox
})
if (context.layers.showSaveRoiButton) {
var downloadImage = document.createElement('div')
downloadImage.innerHTML = '\n <input type="checkbox" checked id='
.concat(context.id, '-download-image" class="')
.concat(
style.toggleInput,
'" />\n <label itk-vtk-tooltip itk-vtk-tooltip-top itk-vtk-tooltip-content="Save ROI" class="'
)
.concat(style.toggleButton, '" for="')
.concat(
context.id,
'-download-image">\n <img style="height: 23px" src="'
)
.concat(optimizedSVGDataUri$s, '" />\n </label>\n ')
var downloadImageLabel = downloadImage.children[1]
downloadImage.style.height = '23px'
applyContrastSensitiveStyleToElement(
context,
'invertibleButton',
downloadImageLabel
)
imageIcons.appendChild(downloadImage)
downloadImage.addEventListener('click', function(event) {
event.preventDefault()
event.stopPropagation()
context.service.send({
type: 'DOWNLOAD_IMAGE',
data: {
name: context.images.selectedName,
layerName: name,
},
})
})
}
var icon = makeHtml(
'<layer-icon class="'.concat(style.layerIcon, '"></layer-icon>')
)
Expand Down Expand Up @@ -22771,7 +22808,7 @@ function createBlendModeSelector(context, uiContainer) {
var blendModeEntry = document.createElement('div')
blendModeEntry.innerHTML = '\n <div itk-vtk-tooltip itk-vtk-tooltip-top itk-vtk-tooltip-content="Blend mode"\n class="'
.concat(style.blendModeButton, '">\n <img src="')
.concat(optimizedSVGDataUri$u, '" alt="blend mode" />\n </div>\n ')
.concat(optimizedSVGDataUri$v, '" alt="blend mode" />\n </div>\n ')
var blendModeDiv = blendModeEntry.children[0]
context.images.blendModeDiv = blendModeDiv
applyContrastSensitiveStyleToElement(
Expand Down
22 changes: 11 additions & 11 deletions src/UI/reference-ui/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/UI/reference-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@
},
"dependencies": {
"@babel/runtime": "^7.17.6",
"@itk-viewer/icons": "^11.14.1",
"@lit-labs/context": "^0.2.0",
"@material/web": "^1.0.0-pre.4",
"itk-viewer-color-maps": "^1.2.0",
"itk-viewer-icons": "^11.14.0",
"itk-viewer-transfer-function-editor": "^1.2.5",
"lit": "^2.4.0",
"xstate-lit": "^1.3.1"
Expand Down
2 changes: 1 addition & 1 deletion src/UI/reference-ui/src/Images/cinematic.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import style from '../ItkVtkViewer.module.css'
import { volumeScatteringIconDataUri } from 'itk-viewer-icons'
import { volumeScatteringIconDataUri } from '@itk-viewer/icons'

const sliderMap = new Map()

Expand Down
2 changes: 1 addition & 1 deletion src/UI/reference-ui/src/Images/createBlendModeSelector.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import style from '../ItkVtkViewer.module.css'
import applyContrastSensitiveStyleToElement from '../applyContrastSensitiveStyleToElement'

import { blendModeIconDataUri } from 'itk-viewer-icons'
import { blendModeIconDataUri } from '@itk-viewer/icons'

function createBlendModeSelector(context, uiContainer) {
const blendModeEntry = document.createElement('div')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import macro from '@kitware/vtk.js/macro'
import style from '../ItkVtkViewer.module.css'
import applyContrastSensitiveStyleToElement from '../applyContrastSensitiveStyleToElement'

import { gradientIconDataUri } from 'itk-viewer-icons'
import { gradientIconDataUri } from '@itk-viewer/icons'

function createGradientOpacitySlider(context, uiContainer) {
const sliderEntry = document.createElement('div')
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import style from '../ItkVtkViewer.module.css'

import { interpolationIconDataUri } from 'itk-viewer-icons'
import { interpolationIconDataUri } from '@itk-viewer/icons'
import applyContrastSensitiveStyleToElement from '../applyContrastSensitiveStyleToElement'
import toggleInterpolation from './toggleInterpolation'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import createCategoricalColorIconSelector from '../createCategoricalColorIconSel
import style from '../ItkVtkViewer.module.css'
import applyContrastSensitiveStyleToElement from '../applyContrastSensitiveStyleToElement'

import { opacityIconDataUri } from 'itk-viewer-icons'
import { opacityIconDataUri } from '@itk-viewer/icons'

function createLabelImageColorWidget(context) {
const viewerDOMId = context.id
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import style from '../ItkVtkViewer.module.css'
import applyContrastSensitiveStyleToElement from '../applyContrastSensitiveStyleToElement'

import { sampleDistanceIconDataUri } from 'itk-viewer-icons'
import { sampleDistanceIconDataUri } from '@itk-viewer/icons'

function createSampleDistanceSlider(context, uiContainer) {
const sliderEntry = document.createElement('div')
Expand Down
2 changes: 1 addition & 1 deletion src/UI/reference-ui/src/Images/createShadowToggle.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import style from '../ItkVtkViewer.module.css'
import applyContrastSensitiveStyleToElement from '../applyContrastSensitiveStyleToElement'

import { shadowIconDataUri } from 'itk-viewer-icons'
import { shadowIconDataUri } from '@itk-viewer/icons'

function createShadowToggle(context, uiContainer) {
const shadowButton = document.createElement('div')
Expand Down
2 changes: 1 addition & 1 deletion src/UI/reference-ui/src/Images/createWindowLevelReset.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import style from '../ItkVtkViewer.module.css'
import applyContrastSensitiveStyleToElement from '../applyContrastSensitiveStyleToElement'

import { resetImageIconDataUri } from 'itk-viewer-icons'
import { resetImageIconDataUri } from '@itk-viewer/icons'

function createWindowLevelReset(context, uiContainer) {
const windowLevelResetButton = document.createElement('div')
Expand Down
2 changes: 1 addition & 1 deletion src/UI/reference-ui/src/Images/createWindowLevelToggle.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import style from '../ItkVtkViewer.module.css'
import applyContrastSensitiveStyleToElement from '../applyContrastSensitiveStyleToElement'

import { windowingIconDataUri } from 'itk-viewer-icons'
import { windowingIconDataUri } from '@itk-viewer/icons'

function createWindowLevelToggle(context, uiContainer) {
const windowLevelToggle = document.createElement('div')
Expand Down
2 changes: 1 addition & 1 deletion src/UI/reference-ui/src/Images/scaleSelector.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import applyContrastSensitiveStyleToElement from '../applyContrastSensitiveStyleToElement'
import style from '../ItkVtkViewer.module.css'
import { scaleSelectIconDataUri } from 'itk-viewer-icons'
import { scaleSelectIconDataUri } from '@itk-viewer/icons'

function applyScaleCount(input, scaleCount) {
input.innerHTML = '' // clear old options
Expand Down
2 changes: 1 addition & 1 deletion src/UI/reference-ui/src/Layers/compareUI.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {
playIconDataUri,
pauseIconDataUri,
rotateIconDataUri,
} from 'itk-viewer-icons'
} from '@itk-viewer/icons'
import style from '../ItkVtkViewer.module.css'
import { makeHtml } from '../utils'

Expand Down
42 changes: 36 additions & 6 deletions src/UI/reference-ui/src/Layers/createLayerInterface.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import style from '../ItkVtkViewer.module.css'

import applyContrastSensitiveStyleToElement from '../applyContrastSensitiveStyleToElement'
import {
visibleIconDataUri,
invisibleIconDataUri,
boundingBoxIconDataUri,
} from 'itk-viewer-icons'
downloadIconDataUri,
visibleIconDataUri,
} from '@itk-viewer/icons'
import style from '../ItkVtkViewer.module.css'

import applyContrastSensitiveStyleToElement from '../applyContrastSensitiveStyleToElement'
import { makeHtml } from '../utils'
import './layerIcon.js'

Expand Down Expand Up @@ -74,7 +75,7 @@ function createLayerEntry(context, name, layer) {
layer.spinner = spinner

const layerBBoxButton = document.createElement('div')
layerBBoxButton.innerHTML = `<input id="${context.id}-layerBBoxButton" type="checkbox" class="${style.toggleInput}"><label itk-vtk-tooltip itk-vtk-tooltip-left itk-vtk-tooltip-content="Label BBox" class="${style.toggleButton}" for="${context.id}-layerBBoxButton"><img src="${boundingBoxIconDataUri}" alt="bbox"/></label>`
layerBBoxButton.innerHTML = `<input id="${context.id}-layerBBoxButton" type="checkbox" class="${style.toggleInput}"><label itk-vtk-tooltip itk-vtk-tooltip-top itk-vtk-tooltip-content="Bounding Box" class="${style.toggleButton}" for="${context.id}-layerBBoxButton"><img src="${boundingBoxIconDataUri}" alt="bbox"/></label>`
const layerBBoxButtonInput = layerBBoxButton.children[0]
const layerBBoxLabel = layerBBoxButton.children[1]
layerBBoxButton.style.height = '23px'
Expand All @@ -98,6 +99,35 @@ function createLayerEntry(context, name, layer) {
layerBBoxButtonInput.checked = actorContext.bbox
})

if (context.layers.showSaveRoiButton) {
const downloadImage = document.createElement('div')
downloadImage.innerHTML = `
<input type="checkbox" checked id=${context.id}-download-image" class="${style.toggleInput}" />
<label itk-vtk-tooltip itk-vtk-tooltip-top itk-vtk-tooltip-content="Save ROI" class="${style.toggleButton}" for="${context.id}-download-image">
<img style="height: 23px" src="${downloadIconDataUri}" />
</label>
`
const downloadImageLabel = downloadImage.children[1]
downloadImage.style.height = '23px'
applyContrastSensitiveStyleToElement(
context,
'invertibleButton',
downloadImageLabel
)
imageIcons.appendChild(downloadImage)
downloadImage.addEventListener('click', event => {
event.preventDefault()
event.stopPropagation()
context.service.send({
type: 'DOWNLOAD_IMAGE',
data: {
name: context.images.selectedName,
layerName: name,
},
})
})
}

const icon = makeHtml(`<layer-icon class="${style.layerIcon}"></layer-icon>`)
icon.layer = layer
icon.name = name
Expand Down
Loading
Loading