Skip to content

Commit 2bc522d

Browse files
author
JoyZhou
committed
fix: add draw undo/redo & closed issue #136
1 parent a4c3228 commit 2bc522d

2 files changed

Lines changed: 109 additions & 93 deletions

File tree

src/app/dwv/dwv.component.html

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,13 @@
55
<mat-icon>arrow_drop_down</mat-icon>
66
</button>
77
<mat-menu #menu="matMenu" [overlapTrigger]="false" yPosition="below">
8-
<button *ngFor="let tool of toolNames" mat-menu-item (value)="tool" (click)="onChangeTool(tool)">{{ tool }}</button>
8+
<button *ngFor="let tool of toolNames" mat-menu-item (value)="tool" (click)="onChangeTool(tool)">{{ tool
9+
}}</button>
910
</mat-menu>
1011

1112
<button mat-raised-button color="primary" (click)="onReset()" [disabled]="!dataLoaded">Reset</button>
13+
<button mat-raised-button color="primary" (click)="onUndo()" [disabled]="!dataLoaded">undo</button>
14+
<button mat-raised-button color="primary" (click)="onRedo()" [disabled]="!dataLoaded">redo</button>
1215
<button mat-raised-button color="primary" (click)="openTagsDialog()" [disabled]="!dataLoaded">Tags</button>
1316
</div>
1417
<div class="layerContainer">
@@ -18,7 +21,9 @@
1821
</div>
1922
<div class="legend mat-small">
2023
<p>Powered by
21-
<a href="https://github.com/ivmartel/dwv">dwv</a>
22-
{{ versions.dwv }}
23-
and Angular {{ versions.angular }}</p></div>
24-
</div>
24+
<a href="https://github.com/ivmartel/dwv">dwv</a>
25+
{{ versions.dwv }}
26+
and Angular {{ versions.angular }}
27+
</p>
28+
</div>
29+
</div>

src/app/dwv/dwv.component.ts

Lines changed: 99 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import { Component, OnInit } from '@angular/core';
2-
import { VERSION } from '@angular/core';
3-
import * as dwv from 'dwv';
4-
import { MatDialog } from '@angular/material/dialog';
5-
import { TagsDialogComponent } from './tags-dialog.component';
1+
import { Component, OnInit } from "@angular/core";
2+
import { VERSION } from "@angular/core";
3+
import * as dwv from "dwv";
4+
import { MatDialog } from "@angular/material/dialog";
5+
import { TagsDialogComponent } from "./tags-dialog.component";
66

77
// gui overrides
88

@@ -11,47 +11,46 @@ dwv.gui.getElement = dwv.gui.base.getElement;
1111

1212
// Image decoders (for web workers)
1313
dwv.image.decoderScripts = {
14-
jpeg2000: 'assets/dwv/decoders/pdfjs/decode-jpeg2000.js',
15-
'jpeg-lossless': 'assets/dwv/decoders/rii-mango/decode-jpegloss.js',
16-
'jpeg-baseline': 'assets/dwv/decoders/pdfjs/decode-jpegbaseline.js',
17-
rle: 'assets/dwv/decoders/dwv/decode-rle.js'
14+
jpeg2000: "assets/dwv/decoders/pdfjs/decode-jpeg2000.js",
15+
"jpeg-lossless": "assets/dwv/decoders/rii-mango/decode-jpegloss.js",
16+
"jpeg-baseline": "assets/dwv/decoders/pdfjs/decode-jpegbaseline.js",
17+
rle: "assets/dwv/decoders/dwv/decode-rle.js",
1818
};
1919

2020
@Component({
21-
selector: 'app-dwv',
22-
templateUrl: './dwv.component.html',
23-
styleUrls: ['./dwv.component.scss']
21+
selector: "app-dwv",
22+
templateUrl: "./dwv.component.html",
23+
styleUrls: ["./dwv.component.scss"],
2424
})
25-
2625
export class DwvComponent implements OnInit {
2726
public versions: any;
2827
public tools = {
29-
Scroll: {},
30-
ZoomAndPan: {},
31-
WindowLevel: {},
32-
Draw: {
33-
options: ['Ruler'],
34-
type: 'factory',
35-
events: ['drawcreate', 'drawchange', 'drawmove', 'drawdelete']
36-
}
28+
Scroll: {},
29+
ZoomAndPan: {},
30+
WindowLevel: {},
31+
Draw: {
32+
options: ["Ruler"],
33+
type: "factory",
34+
events: ["drawcreate", "drawchange", "drawmove", "drawdelete"],
35+
},
3736
};
3837
public toolNames: string[];
39-
public selectedTool = 'Select Tool';
38+
public selectedTool = "Select Tool";
4039
public loadProgress = 0;
4140
public dataLoaded = false;
4241

4342
private dwvApp: any;
4443
private metaData: any[];
4544

4645
// drop box class name
47-
private dropboxClassName = 'dropBox';
48-
private borderClassName = 'dropBoxBorder';
49-
private hoverClassName = 'hover';
46+
private dropboxClassName = "dropBox";
47+
private borderClassName = "dropBoxBorder";
48+
private hoverClassName = "hover";
5049

5150
constructor(public dialog: MatDialog) {
5251
this.versions = {
5352
dwv: dwv.getVersion(),
54-
angular: VERSION.full
53+
angular: VERSION.full,
5554
};
5655
}
5756

@@ -60,14 +59,14 @@ export class DwvComponent implements OnInit {
6059
this.dwvApp = new dwv.App();
6160
// initialise app
6261
this.dwvApp.init({
63-
containerDivId: 'dwv',
64-
tools: this.tools
62+
containerDivId: "dwv",
63+
tools: this.tools,
6564
});
6665
// handle load events
6766
let nLoadItem = null;
6867
let nReceivedError = null;
6968
let nReceivedAbort = null;
70-
this.dwvApp.addEventListener('loadstart', (/*event*/) => {
69+
this.dwvApp.addEventListener("loadstart", (/*event*/) => {
7170
// reset flags
7271
this.dataLoaded = false;
7372
nLoadItem = 0;
@@ -76,57 +75,59 @@ export class DwvComponent implements OnInit {
7675
// hide drop box
7776
this.showDropbox(false);
7877
});
79-
this.dwvApp.addEventListener('loadprogress', (event) => {
78+
this.dwvApp.addEventListener("loadprogress", (event) => {
8079
this.loadProgress = event.loaded;
8180
});
82-
this.dwvApp.addEventListener('load', (/*event*/) => {
81+
this.dwvApp.addEventListener("load", (/*event*/) => {
8382
// set dicom tags
8483
this.metaData = dwv.utils.objectToArray(this.dwvApp.getMetaData());
8584
// available tools
8685
this.toolNames = [];
8786
for (const key in this.tools) {
88-
if ((key === 'Scroll' && this.dwvApp.canScroll()) ||
89-
(key === 'WindowLevel' && this.dwvApp.canWindowLevel()) ||
90-
(key !== 'Scroll' && key !== 'WindowLevel')) {
87+
if (
88+
(key === "Scroll" && this.dwvApp.canScroll()) ||
89+
(key === "WindowLevel" && this.dwvApp.canWindowLevel()) ||
90+
(key !== "Scroll" && key !== "WindowLevel")
91+
) {
9192
this.toolNames.push(key);
9293
}
9394
}
9495
this.onChangeTool(this.toolNames[0]);
9596
// set data loaded flag
9697
this.dataLoaded = true;
9798
});
98-
this.dwvApp.addEventListener('loadend', (/*event*/) => {
99+
this.dwvApp.addEventListener("loadend", (/*event*/) => {
99100
if (nReceivedError) {
100101
this.loadProgress = 0;
101-
alert('Received errors during load. Check log for details.');
102+
alert("Received errors during load. Check log for details.");
102103
// show drop box if nothing has been loaded
103104
if (!nLoadItem) {
104105
this.showDropbox(true);
105106
}
106107
}
107108
if (nReceivedAbort) {
108109
this.loadProgress = 0;
109-
alert('Load was aborted.');
110+
alert("Load was aborted.");
110111
this.showDropbox(true);
111112
}
112113
});
113-
this.dwvApp.addEventListener('loaditem', (/*event*/) => {
114+
this.dwvApp.addEventListener("loaditem", (/*event*/) => {
114115
++nLoadItem;
115116
});
116-
this.dwvApp.addEventListener('error', (event) => {
117+
this.dwvApp.addEventListener("error", (event) => {
117118
console.error(event.error);
118119
++nReceivedError;
119120
});
120-
this.dwvApp.addEventListener('abort', (/*event*/) => {
121+
this.dwvApp.addEventListener("abort", (/*event*/) => {
121122
++nReceivedAbort;
122123
});
123124

124125
// handle key events
125-
this.dwvApp.addEventListener('keydown', (event) => {
126-
this.dwvApp.defaultOnKeydown(event);
126+
this.dwvApp.addEventListener("keydown", (event) => {
127+
this.dwvApp.defaultOnKeydown(event);
127128
});
128129
// handle window resize
129-
window.addEventListener('resize', this.dwvApp.onResize);
130+
window.addEventListener("resize", this.dwvApp.onResize);
130131

131132
// setup drop box
132133
this.setupDropbox();
@@ -140,66 +141,78 @@ export class DwvComponent implements OnInit {
140141
* @param tool The new tool name.
141142
*/
142143
onChangeTool = (tool: string) => {
143-
if ( this.dwvApp ) {
144+
if (this.dwvApp) {
144145
this.selectedTool = tool;
145146
this.dwvApp.setTool(tool);
146-
if (tool === 'Draw') {
147+
if (tool === "Draw") {
147148
this.onChangeShape(this.tools.Draw.options[0]);
148149
}
149150
}
150-
}
151+
};
151152

152153
/**
153154
* Handle a change draw shape event.
154155
* @param shape The new shape name.
155156
*/
156157
private onChangeShape = (shape: string) => {
157-
if ( this.dwvApp && this.selectedTool === 'Draw') {
158+
if (this.dwvApp && this.selectedTool === "Draw") {
158159
this.dwvApp.setDrawShape(shape);
159160
}
160-
}
161+
};
161162

162163
/**
163164
* Handle a reset event.
164165
*/
165166
onReset = () => {
166-
if ( this.dwvApp ) {
167+
if (this.dwvApp) {
167168
this.dwvApp.resetDisplay();
168169
}
170+
};
171+
172+
/**
173+
* handle an undo event
174+
*/
175+
onUndo() {
176+
this.dwvApp.undo();
177+
}
178+
179+
/**
180+
* handle a redo event
181+
*/
182+
onRedo() {
183+
this.dwvApp.redo();
169184
}
170185

171186
/**
172187
* Open the DICOM tags dialog.
173188
*/
174189
openTagsDialog = () => {
175-
this.dialog.open(TagsDialogComponent,
176-
{
177-
width: '80%',
178-
height: '90%',
179-
data: {
180-
title: 'DICOM Tags',
181-
value: this.metaData
182-
}
183-
}
184-
);
185-
}
190+
this.dialog.open(TagsDialogComponent, {
191+
width: "80%",
192+
height: "90%",
193+
data: {
194+
title: "DICOM Tags",
195+
value: this.metaData,
196+
},
197+
});
198+
};
186199

187200
// drag and drop [begin] -----------------------------------------------------
188201

189202
/**
190203
* Setup the data load drop box: add event listeners and set initial size.
191204
*/
192205
private setupDropbox = () => {
193-
const layerContainer = this.dwvApp.getElement('layerContainer');
194-
if (layerContainer) {
195-
// show drop box
196-
this.showDropbox(true);
197-
// start listening to drag events on the layer container
198-
layerContainer.addEventListener('dragover', this.onDragOver);
199-
layerContainer.addEventListener('dragleave', this.onDragLeave);
200-
layerContainer.addEventListener('drop', this.onDrop);
201-
}
202-
}
206+
const layerContainer = this.dwvApp.getElement("layerContainer");
207+
if (layerContainer) {
208+
// show drop box
209+
this.showDropbox(true);
210+
// start listening to drag events on the layer container
211+
layerContainer.addEventListener("dragover", this.onDragOver);
212+
layerContainer.addEventListener("dragleave", this.onDragLeave);
213+
layerContainer.addEventListener("drop", this.onDrop);
214+
}
215+
};
203216

204217
/**
205218
* Handle a drag over.
@@ -212,9 +225,9 @@ export class DwvComponent implements OnInit {
212225
// update box border
213226
const box = this.dwvApp.getElement(this.borderClassName);
214227
if (box && box.className.indexOf(this.hoverClassName) === -1) {
215-
box.className += ' ' + this.hoverClassName;
228+
box.className += " " + this.hoverClassName;
216229
}
217-
}
230+
};
218231

219232
/**
220233
* Handle a drag leave.
@@ -225,11 +238,11 @@ export class DwvComponent implements OnInit {
225238
event.stopPropagation();
226239
event.preventDefault();
227240
// update box class
228-
const box = this.dwvApp.getElement(this.borderClassName + ' hover');
241+
const box = this.dwvApp.getElement(this.borderClassName + " hover");
229242
if (box && box.className.indexOf(this.hoverClassName) !== -1) {
230-
box.className = box.className.replace(' ' + this.hoverClassName, '');
243+
box.className = box.className.replace(" " + this.hoverClassName, "");
231244
}
232-
}
245+
};
233246

234247
/**
235248
* Show/hide the data load drop box.
@@ -240,29 +253,28 @@ export class DwvComponent implements OnInit {
240253
if (box) {
241254
if (show) {
242255
// reset css class
243-
box.className = this.dropboxClassName + ' ' + this.borderClassName;
256+
box.className = this.dropboxClassName + " " + this.borderClassName;
244257
// check content
245-
if (box.innerHTML === '') {
246-
box.innerHTML = 'Drag and drop data here.';
258+
if (box.innerHTML === "") {
259+
box.innerHTML = "Drag and drop data here.";
247260
}
248261
const size = this.dwvApp.getLayerContainerSize();
249262
// set the initial drop box size
250-
const dropBoxSize = 2 * size.height / 3;
263+
const dropBoxSize = (2 * size.height) / 3;
251264
box.setAttribute(
252-
'style',
253-
'width:' + dropBoxSize + 'px;height:' + dropBoxSize + 'px');
265+
"style",
266+
"width:" + dropBoxSize + "px;height:" + dropBoxSize + "px"
267+
);
254268
} else {
255269
// remove border css class
256270
box.className = this.dropboxClassName;
257271
// remove content
258-
box.innerHTML = '';
272+
box.innerHTML = "";
259273
// make not visible
260-
box.setAttribute(
261-
'style',
262-
'visible:false;');
274+
box.setAttribute("style", "visible:false;");
263275
}
264276
}
265-
}
277+
};
266278

267279
/**
268280
* Handle a drop event.
@@ -274,8 +286,7 @@ export class DwvComponent implements OnInit {
274286
event.preventDefault();
275287
// load files
276288
this.dwvApp.loadFiles(event.dataTransfer.files);
277-
}
289+
};
278290

279291
// drag and drop [end] -------------------------------------------------------
280-
281292
}

0 commit comments

Comments
 (0)