-
Notifications
You must be signed in to change notification settings - Fork 23
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
Add measurement tools #7258
Add measurement tools #7258
Changes from 13 commits
7e9cca9
7b66507
feffad5
a833b93
aa0b825
0e40634
59dc2cd
d2187c2
ba61b1a
a96589b
bb1e52c
ac930f2
725b966
1f64636
74f4c5f
fc5a064
9fdb2f7
7fc447c
5fbc107
f824392
d2ccb2c
6348abc
0ea1ee7
12a348a
3b1791d
49db897
3d4a5fa
2979b81
50e92e5
61d0ab1
1b66fa3
a4c9bf6
197a7dc
ead52f7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -51,7 +51,11 @@ import { | |
} from "oxalis/model/actions/proofread_actions"; | ||
import { calculateGlobalPos } from "oxalis/model/accessors/view_mode_accessor"; | ||
import { V3 } from "libs/mjs"; | ||
import { setQuickSelectStateAction } from "oxalis/model/actions/ui_actions"; | ||
import { | ||
hideMeasurementTooltipAction, | ||
setQuickSelectStateAction, | ||
showMeasurementTooltipAction, | ||
} from "oxalis/model/actions/ui_actions"; | ||
|
||
export type ActionDescriptor = { | ||
leftClick?: string; | ||
|
@@ -780,6 +784,159 @@ export class QuickSelectTool { | |
static onToolDeselected() {} | ||
} | ||
|
||
export class LineMeasurementTool { | ||
static DOUBLE_CLICK_TIME_THRESHOLD = 600; | ||
static getPlaneMouseControls(_planeId: OrthoView): any { | ||
let initialPlane: OrthoView = OrthoViews.PLANE_XY; | ||
let isMeasuring = false; | ||
let lastLeftClickTime = 0; | ||
const SceneController = getSceneController(); | ||
const { lineMeasurementGeometry } = SceneController; | ||
const guardFromResettedTool = (func: Function) => { | ||
// TODO: Problem typing is lost | ||
return (...args: any) => { | ||
if (lineMeasurementGeometry.isResetted && isMeasuring) { | ||
isMeasuring = false; | ||
return; | ||
} | ||
func(...args); | ||
}; | ||
}; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. All of the following three functions need to be guarded against the user having used escape while still in the process of measuring, to interrupt the measurement. When escape was pressed, the The guarding function takes care of guarding these three functions against the user using escape while still measuring. But the typing is lost (as far as I would guess) and the code ready quite quirky IMO. Maybe you have a better idea? |
||
const mouseMove = guardFromResettedTool( | ||
(_delta: Point2, pos: Point2, plane: OrthoView | null | undefined, evt: MouseEvent) => { | ||
if (plane !== initialPlane || !isMeasuring) { | ||
return; | ||
} | ||
const state = Store.getState(); | ||
const newPos = V3.floor(calculateGlobalPos(state, pos, initialPlane)); | ||
lineMeasurementGeometry.setTopPoint(newPos); | ||
Store.dispatch(showMeasurementTooltipAction([evt.clientX, evt.clientY])); | ||
}, | ||
); | ||
const rightClick = guardFromResettedTool((pos: Point2, plane: OrthoView, event: MouseEvent) => { | ||
if (isMeasuring) { | ||
mouseMove({ x: 0, y: 0 }, pos, plane, event); | ||
isMeasuring = false; | ||
} else { | ||
lineMeasurementGeometry.reset(); | ||
lineMeasurementGeometry.hide(); | ||
Store.dispatch(hideMeasurementTooltipAction()); | ||
} | ||
}); | ||
const leftClick = guardFromResettedTool((pos: Point2, plane: OrthoView, event: MouseEvent) => { | ||
const currentTime = Date.now(); | ||
if (currentTime - lastLeftClickTime <= this.DOUBLE_CLICK_TIME_THRESHOLD) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. wouldn't it make sense to check that the two clicks were registered roughly at the same spot? |
||
rightClick(pos, plane, event); | ||
return; | ||
} | ||
lastLeftClickTime = currentTime; | ||
const state = Store.getState(); | ||
const position = V3.floor(calculateGlobalPos(state, pos, plane)); | ||
initialPlane = plane; | ||
if (!isMeasuring) { | ||
lineMeasurementGeometry.setStartPoint(position, plane); | ||
isMeasuring = true; | ||
} else { | ||
lineMeasurementGeometry.addPoint(position); | ||
Store.dispatch(showMeasurementTooltipAction([event.clientX, event.clientY])); | ||
} | ||
}); | ||
return { | ||
mouseMove, | ||
rightClick, | ||
leftClick, | ||
}; | ||
} | ||
|
||
static getActionDescriptors( | ||
_activeTool: AnnotationTool, | ||
_useLegacyBindings: boolean, | ||
_shiftKey: boolean, | ||
_ctrlKey: boolean, | ||
_altKey: boolean, | ||
): ActionDescriptor { | ||
return { | ||
leftClick: "Left Click to measure distance", | ||
rightClick: "Finish Measurement and reset", | ||
}; | ||
} | ||
|
||
static onToolDeselected() { | ||
const { lineMeasurementGeometry } = getSceneController(); | ||
lineMeasurementGeometry.reset(); | ||
lineMeasurementGeometry.hide(); | ||
Comment on lines
+910
to
+911
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are several places where reset and hide is called. How about adding a |
||
Store.dispatch(hideMeasurementTooltipAction()); | ||
} | ||
} | ||
|
||
export class AreaMeasurementTool { | ||
static getPlaneMouseControls(): any { | ||
let initialPlane: OrthoView = OrthoViews.PLANE_XY; | ||
let isMeasuring = false; | ||
const SceneController = getSceneController(); | ||
const { areaMeasurementGeometry } = SceneController; | ||
return { | ||
leftDownMove: ( | ||
_delta: Point2, | ||
pos: Point2, | ||
id: string | null | undefined, | ||
event: MouseEvent, | ||
) => { | ||
if (id == null) { | ||
return; | ||
} | ||
if (!isMeasuring) { | ||
initialPlane = id as OrthoView; | ||
isMeasuring = true; | ||
areaMeasurementGeometry.reset(); | ||
areaMeasurementGeometry.show(); | ||
areaMeasurementGeometry.setViewport(id as OrthoView); | ||
} | ||
if (id !== initialPlane) { | ||
return; | ||
} | ||
const state = Store.getState(); | ||
const position = V3.floor(calculateGlobalPos(state, pos, initialPlane)); | ||
areaMeasurementGeometry.addEdgePoint(position); | ||
Store.dispatch(showMeasurementTooltipAction([event.clientX, event.clientY])); | ||
}, | ||
leftMouseUp: (event: MouseEvent) => { | ||
if (!isMeasuring) { | ||
return; | ||
} | ||
// Stop drawing area and close the drawn area if still measuring. | ||
isMeasuring = false; | ||
areaMeasurementGeometry.connectToStartPoint(); | ||
Store.dispatch(showMeasurementTooltipAction([event.clientX, event.clientY])); | ||
}, | ||
rightClick: () => { | ||
areaMeasurementGeometry.reset(); | ||
Store.dispatch(hideMeasurementTooltipAction()); | ||
}, | ||
}; | ||
} | ||
|
||
static getActionDescriptors( | ||
_activeTool: AnnotationTool, | ||
_useLegacyBindings: boolean, | ||
_shiftKey: boolean, | ||
_ctrlKey: boolean, | ||
_altKey: boolean, | ||
): ActionDescriptor { | ||
return { | ||
leftDrag: "Drag to measure area", | ||
rightClick: "Reset Measurement", | ||
}; | ||
} | ||
|
||
static onToolDeselected() { | ||
const { areaMeasurementGeometry } = getSceneController(); | ||
areaMeasurementGeometry.reset(); | ||
areaMeasurementGeometry.hide(); | ||
Store.dispatch(hideMeasurementTooltipAction()); | ||
} | ||
} | ||
|
||
export class ProofreadTool { | ||
static getPlaneMouseControls(_planeId: OrthoView, planeView: PlaneView): any { | ||
return { | ||
|
@@ -849,6 +1006,8 @@ const toolToToolClass = { | |
[AnnotationToolEnum.ERASE_BRUSH]: EraseTool, | ||
[AnnotationToolEnum.FILL_CELL]: FillCellTool, | ||
[AnnotationToolEnum.PICK_CELL]: PickCellTool, | ||
[AnnotationToolEnum.LINE_MEASUREMENT]: LineMeasurementTool, | ||
[AnnotationToolEnum.AREA_MEASUREMENT]: AreaMeasurementTool, | ||
}; | ||
export function getToolClassForAnnotationTool(activeTool: AnnotationTool) { | ||
return toolToToolClass[activeTool]; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
getPlaneMouseControls
of the area measurement tool doesn't accept that parameter. maybe make these interfaces consistent?