-
Notifications
You must be signed in to change notification settings - Fork 116
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Feature: drawing annotation deletion (#337)
* Fix: thread save incorrectly rejects when no dialogue exists * Update: drawing annotations now rescale correctly * Fix: annotator is now loaded with the correct initial scale * Fix: update annotator tests for constructor change * Update: tests for updating local annotations on annotationthreads * Update: fix tests * Update: tests for docdrawingthread * Update: undo redo drawing container * Fix: pull request feedback * New: drawing annotation undo and redo container * Update: undo and redo grey out when applicable * Fix: update tests with new fn calls * Chore: update variable name * Chore: actually update the draw states variable * Update: drawing annotation svgs * Update: remove draw from drawstates * Update: handle page change with two toggles * Update: merge refactor from master * Fix: bind cleanup listeners on drawing thread and fix resize * Fix: remove global test variable * Fix: scale annotations in redo stack * Update: drawing method cleanup * Update: remove unused class * Update: undo redo unit tests * Update: remove isTypeEnabled * Update: fix tests again * Update: added test for DocDrawingThreadShow * Update: PR changes * Update: custom thread cleanup for drawing annotationevent * New: drawing deletion * Update: separate drawing methods * Update: Change how controllers are instantiated * Update: bind draw selection to annotated element
- Loading branch information
Showing
23 changed files
with
1,700 additions
and
300 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
import EventEmitter from 'events'; | ||
|
||
class AnnotationModeController extends EventEmitter { | ||
/** @property {Array} - The array of annotation threads */ | ||
threads = []; | ||
|
||
/** @property {Array} - The array of annotation handlers */ | ||
handlers = []; | ||
|
||
/** | ||
* [constructor] | ||
* | ||
* @return {AnnotationModeController} Annotation controller instance | ||
*/ | ||
constructor() { | ||
super(); | ||
|
||
this.handleAnnotationEvent = this.handleAnnotationEvent.bind(this); | ||
} | ||
|
||
/** | ||
* Register the annotator and any information associated with the annotator | ||
* | ||
* @public | ||
* @param {Annotator} annotator - The annotator to be associated with the controller | ||
* @return {void} | ||
*/ | ||
registerAnnotator(annotator) { | ||
// TODO (@minhnguyen): remove the need to register an annotator. Ideally, the annotator should know about the | ||
// controller and the controller does not know about the annotator. | ||
this.annotator = annotator; | ||
} | ||
|
||
/** | ||
* Bind the mode listeners and store each handler for future unbinding | ||
* | ||
* @public | ||
* @return {void} | ||
*/ | ||
bindModeListeners() { | ||
const currentHandlerIndex = this.handlers.length; | ||
this.setupHandlers(); | ||
|
||
for (let index = currentHandlerIndex; index < this.handlers.length; index++) { | ||
const handler = this.handlers[index]; | ||
const types = handler.type instanceof Array ? handler.type : [handler.type]; | ||
|
||
types.forEach((eventName) => handler.eventObj.addEventListener(eventName, handler.func)); | ||
} | ||
} | ||
|
||
/** | ||
* Unbind the previously bound mode listeners | ||
* | ||
* @public | ||
* @return {void} | ||
*/ | ||
unbindModeListeners() { | ||
while (this.handlers.length > 0) { | ||
const handler = this.handlers.pop(); | ||
const types = handler.type instanceof Array ? handler.type : [handler.type]; | ||
|
||
types.forEach((eventName) => { | ||
handler.eventObj.removeEventListener(eventName, handler.func); | ||
}); | ||
} | ||
} | ||
|
||
/** | ||
* Register a thread with the controller so that the controller can keep track of relevant threads | ||
* | ||
* @public | ||
* @param {AnnotationThread} thread - The thread to register with the controller | ||
* @return {void} | ||
*/ | ||
registerThread(thread) { | ||
this.threads.push(thread); | ||
} | ||
|
||
/** | ||
* Unregister a previously registered thread | ||
* | ||
* @public | ||
* @param {AnnotationThread} thread - The thread to unregister with the controller | ||
* @return {void} | ||
*/ | ||
unregisterThread(thread) { | ||
this.threads = this.threads.filter((item) => item !== thread); | ||
} | ||
|
||
/** | ||
* Binds custom event listeners for a thread. | ||
* | ||
* @protected | ||
* @param {AnnotationThread} thread - Thread to bind events to | ||
* @return {void} | ||
*/ | ||
bindCustomListenersOnThread(thread) { | ||
if (!thread) { | ||
return; | ||
} | ||
|
||
// TODO (@minhnguyen): Move annotator.bindCustomListenersOnThread logic to AnnotationModeController | ||
this.annotator.bindCustomListenersOnThread(thread); | ||
thread.addListener('annotationevent', (data) => { | ||
this.handleAnnotationEvent(thread, data); | ||
}); | ||
} | ||
|
||
/** | ||
* Unbinds custom event listeners for the thread. | ||
* | ||
* @protected | ||
* @param {AnnotationThread} thread - Thread to unbind events from | ||
* @return {void} | ||
*/ | ||
unbindCustomListenersOnThread(thread) { | ||
if (!thread) { | ||
return; | ||
} | ||
|
||
thread.removeAllListeners('threaddeleted'); | ||
thread.removeAllListeners('threadcleanup'); | ||
thread.removeAllListeners('annotationsaved'); | ||
thread.removeAllListeners('annotationevent'); | ||
} | ||
|
||
/** | ||
* Set up and return the necessary handlers for the annotation mode | ||
* | ||
* @protected | ||
* @return {Array} An array where each element is an object containing the object that will emit the event, | ||
* the type of events to listen for, and the callback | ||
*/ | ||
setupHandlers() {} | ||
|
||
/** | ||
* Handle an annotation event. | ||
* | ||
* @protected | ||
* @param {AnnotationThread} thread - The thread that emitted the event | ||
* @param {Object} data - Extra data related to the annotation event | ||
* @return {void} | ||
*/ | ||
/* eslint-disable no-unused-vars */ | ||
handleAnnotationEvent(thread, data = {}) {} | ||
/* eslint-enable no-unused-vars */ | ||
|
||
/** | ||
* Creates a handler description object and adds its to the internal handler container. | ||
* Useful for setupAndGetHandlers. | ||
* | ||
* @protected | ||
* @param {HTMLElement} element - The element to bind the listener to | ||
* @param {Array|string} type - An array of event types to listen for or the event name to listen for | ||
* @param {Function} handlerFn - The callback to be invoked when the element emits a specified eventname | ||
* @return {void} | ||
*/ | ||
pushElementHandler(element, type, handlerFn) { | ||
if (!element) { | ||
return; | ||
} | ||
|
||
this.handlers.push({ | ||
eventObj: element, | ||
func: handlerFn, | ||
type | ||
}); | ||
} | ||
} | ||
|
||
export default AnnotationModeController; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.