@itk-viewer/element
Version:
Web Component for multi-dimensional viewer
201 lines (197 loc) • 7.96 kB
JavaScript
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import { LitElement, css, html } from 'lit';
import { customElement, property, state } from 'lit/decorators.js';
import { ViewControls } from './view-controls-controller.js';
import { ref } from 'lit/directives/ref.js';
import '@shoelace-style/shoelace/dist/components/card/card.js';
import '@shoelace-style/shoelace/dist/components/range/range.js';
import '@shoelace-style/shoelace/dist/components/radio-group/radio-group.js';
import '@shoelace-style/shoelace/dist/components/radio-button/radio-button.js';
import '@shoelace-style/shoelace/dist/components/tab-group/tab-group.js';
import '@shoelace-style/shoelace/dist/components/tab/tab.js';
import '@shoelace-style/shoelace/dist/components/tab-panel/tab-panel.js'; // not used, but needed for selected tab underline to appear at the start
import '@shoelace-style/shoelace/dist/components/dropdown/dropdown.js';
import '@shoelace-style/shoelace/dist/components/button/button.js';
import '@shoelace-style/shoelace/dist/components/menu/menu.js';
import '@shoelace-style/shoelace/dist/components/menu-item/menu-item.js';
let ViewControlsShoelace = class ViewControlsShoelace extends LitElement {
constructor() {
super(...arguments);
this.view = '2d';
this.hideSliceUi = false;
this.hideScaleUi = false;
this.hideColorUi = false;
this.hideTransferFunctionUi = false;
this.controls = new ViewControls(this);
this.selectedComponent = 0;
}
setActor(actor) {
this.actor = actor;
this.controls.setActor(actor);
}
transferFunctionContainerChanged(container) {
this.controls.setTransferFunctionContainer(container);
}
willUpdate(changedProperties) {
if (changedProperties.has('view')) {
this.controls.setView(this.view);
}
}
render() {
const slice = this.controls.slice?.value;
const axis = this.controls.axis?.value;
const imageDimension = this.controls.imageDimension?.value ?? 0;
const scale = this.controls.scale?.value;
const scaleCount = this.controls.scaleCount?.value ?? 1;
const scaleOptions = Array.from({ length: scaleCount }, (_, i) => i).reverse();
const colorMapOptions = this.controls.colorMapsOptions?.value ?? {};
const componentCount = this.controls.componentCount?.value ?? 1;
const showComponentSelector = !(this.hideColorUi && this.hideTransferFunctionUi) && componentCount > 1;
const components = Array.from({ length: componentCount }, (_, i) => i);
const colorMap = this.controls.colorMaps?.value[this.selectedComponent] ?? '';
const isImage3D = imageDimension >= 3;
const showScale = !this.hideScaleUi && scaleCount >= 2;
const tfEditorHeight = this.view === '2d' ? '2rem' : '8rem';
return html `
<sl-card>
${isImage3D && this.view === '2d' && !this.hideSliceUi
? html `
<sl-range
value=${Number(slice)}
-change="${this.controls.onSlice}"
min="0"
max="1"
step=".01"
label="Slice"
style="min-width: 8rem;"
></sl-range>
<sl-radio-group
label="Slice Axis"
value=${axis}
-change="${this.controls.onAxis}"
>
<sl-radio-button value="I">X</sl-radio-button>
<sl-radio-button value="J">Y</sl-radio-button>
<sl-radio-button value="K">Z</sl-radio-button>
</sl-radio-group>
`
: ''}
${showScale
? html `
<sl-radio-group
label="Image Scale"
value=${scale}
-change="${this.controls.onScale}"
>
${scaleOptions.map((option) => html `<sl-radio-button value=${option}>
${option}
</sl-radio-button>`)}
</sl-radio-group>
`
: ''}
${showComponentSelector
? html `
<sl-tab-group
style="max-width: 18rem"
value=${this.controls.selectedComponent}
-tab-show="${(e) => {
const component = Number(e.detail.name);
this.controls.onSelectedComponent(component);
// trigger re-render to update color map value
this.selectedComponent = Number(e.detail.name);
}}"
>
${components.map((option) => html `<sl-tab panel="${option}" slot="nav">
Component ${option}
</sl-tab>`)}
</sl-tab-group>
`
: ''}
${this.hideColorUi
? ''
: html `
<sl-dropdown style="padding-top: .4rem; width: 100%">
<sl-button slot="trigger" caret class="color-button">
<sl-tooltip content=${colorMap}>
<img src=${colorMapOptions[colorMap] ?? ''} class='selected-swatch'></img>
</sl-tooltip>
</sl-button>
<sl-menu
-select=${(e) => {
this.controls.onColorMap(e.detail.item.value);
}}
class="color-button"
>
${Object.entries(colorMapOptions).map(([value, icon]) => html `<sl-menu-item value=${value}>
<div class='swatch'> <img src=${icon}></img> ${value} </div>
</sl-menu-item>`)}
</sl-menu>
</sl-dropdown>
`}
${this.hideTransferFunctionUi
? ''
: html `
<div style="padding-top: 0.4rem;">
${this.view === '2d' ? 'Color Range' : 'Opacity and Color'}
</div>
<div
${ref(this.transferFunctionContainerChanged)}
style=${`width: 100%; min-width: 12rem; height: ${tfEditorHeight};`}
></div>
`}
</sl-card>
`;
}
static { this.styles = css `
.color-button {
width: 100%;
}
.color-button::part(label) {
width: 100%;
max-height: var(--sl-input-height-medium);
padding: 0;
padding-right: var(--sl-spacing-medium);
}
.selected-swatch {
width: 100%;
height: 100%;
}
.swatch {
height: 100%;
display: flex;
}
.swatch img {
width: 8rem;
height: 100%;
padding-right: var(--sl-spacing-small);
}
`; }
};
__decorate([
property({ type: String })
], ViewControlsShoelace.prototype, "view", void 0);
__decorate([
property({ type: Boolean })
], ViewControlsShoelace.prototype, "hideSliceUi", void 0);
__decorate([
property({ type: Boolean })
], ViewControlsShoelace.prototype, "hideScaleUi", void 0);
__decorate([
property({ type: Boolean })
], ViewControlsShoelace.prototype, "hideColorUi", void 0);
__decorate([
property({ type: Boolean })
], ViewControlsShoelace.prototype, "hideTransferFunctionUi", void 0);
__decorate([
state()
], ViewControlsShoelace.prototype, "selectedComponent", void 0);
ViewControlsShoelace = __decorate([
customElement('itk-view-controls-shoelace')
], ViewControlsShoelace);
export { ViewControlsShoelace };
//# sourceMappingURL=itk-view-controls-shoelace.js.map