diff --git a/app/assets/javascripts/oxalis/api/api_latest.js b/app/assets/javascripts/oxalis/api/api_latest.js index b2d50bf6217..538d259fb12 100644 --- a/app/assets/javascripts/oxalis/api/api_latest.js +++ b/app/assets/javascripts/oxalis/api/api_latest.js @@ -20,6 +20,8 @@ import { deleteTreeAction, setNodeRadiusAction, setTreeNameAction, + setActiveTreeAction, + setTreeColorIndexAction, } from "oxalis/model/actions/skeletontracing_actions"; import { findTreeByNodeId, @@ -243,6 +245,31 @@ class TracingApi { }); } + /** + * Makes the specified tree active. Within the tree, the node with the highest ID will be activated. + * + * @example + * api.tracing.setActiveTree(3); + */ + setActiveTree(treeId: number) { + const tracing = Store.getState().tracing; + assertSkeleton(tracing); + Store.dispatch(setActiveTreeAction(treeId)); + } + + /** + * Changes the color of the referenced tree. Internally, a pre-defined array of colors is used which is + * why this function uses a colorIndex (between 0 and 500) instead of a proper color. + * + * @example + * api.tracing.setTreeColorIndex(3, 10); + */ + setTreeColorIndex(treeId?: number, colorIndex: number) { + const tracing = Store.getState().tracing; + assertSkeleton(tracing); + Store.dispatch(setTreeColorIndexAction(treeId, colorIndex)); + } + /** * Returns the name for a given tree id. If none is given, the name of the active tree is returned. * diff --git a/app/assets/javascripts/oxalis/model/actions/skeletontracing_actions.js b/app/assets/javascripts/oxalis/model/actions/skeletontracing_actions.js index d2db78403d2..a3c6befa270 100644 --- a/app/assets/javascripts/oxalis/model/actions/skeletontracing_actions.js +++ b/app/assets/javascripts/oxalis/model/actions/skeletontracing_actions.js @@ -72,6 +72,11 @@ type SetActiveTreeActionType = { type: "SET_ACTIVE_TREE", treeId: number }; type MergeTreesActionType = { type: "MERGE_TREES", sourceNodeId: number, targetNodeId: number }; type SetTreeNameActionType = { type: "SET_TREE_NAME", name: ?string, treeId: ?number }; type SelectNextTreeActionType = { type: "SELECT_NEXT_TREE", forward: ?boolean }; +type SetTreeColorIndexActionType = { + type: "SET_TREE_COLOR_INDEX", + treeId?: number, + colorIndex: number, +}; type ShuffleTreeColorActionType = { type: "SHUFFLE_TREE_COLOR", treeId?: number }; type ShuffleAllTreeColorsActionType = { type: "SHUFFLE_ALL_TREE_COLORS", treeId?: number }; type CreateCommentActionType = { @@ -106,6 +111,7 @@ export type SkeletonTracingActionType = | SelectNextTreeActionType | ShuffleTreeColorActionType | ShuffleAllTreeColorsActionType + | SetTreeColorIndexActionType | CreateCommentActionType | DeleteCommentActionType | ToggleTreeActionType @@ -310,6 +316,15 @@ export const selectNextTreeAction = (forward: ?boolean = true): SelectNextTreeAc forward, }); +export const setTreeColorIndexAction = ( + treeId?: number, + colorIndex: number, +): SetTreeColorIndexActionType => ({ + type: "SET_TREE_COLOR_INDEX", + treeId, + colorIndex, +}); + export const shuffleTreeColorAction = (treeId: number): ShuffleTreeColorActionType => ({ type: "SHUFFLE_TREE_COLOR", treeId, diff --git a/app/assets/javascripts/oxalis/model/reducers/skeletontracing_reducer.js b/app/assets/javascripts/oxalis/model/reducers/skeletontracing_reducer.js index 2d0405fe5b2..b07e6ef9b87 100644 --- a/app/assets/javascripts/oxalis/model/reducers/skeletontracing_reducer.js +++ b/app/assets/javascripts/oxalis/model/reducers/skeletontracing_reducer.js @@ -16,6 +16,7 @@ import { deleteNode, deleteEdge, shuffleTreeColor, + setTreeColorIndex, createComment, deleteComment, mergeTrees, @@ -376,6 +377,16 @@ function SkeletonTracingReducer(state: OxalisState, action: ActionType): OxalisS }); } + case "SET_TREE_COLOR_INDEX": { + const { colorIndex } = action; + return getTree(skeletonTracing, action.treeId) + .chain(tree => setTreeColorIndex(skeletonTracing, tree, colorIndex)) + .map(([tree, treeId]) => + update(state, { tracing: { trees: { [treeId]: { $set: tree } } } }), + ) + .getOrElse(state); + } + case "SHUFFLE_TREE_COLOR": { return getTree(skeletonTracing, action.treeId) .chain(tree => shuffleTreeColor(skeletonTracing, tree)) diff --git a/app/assets/javascripts/oxalis/model/reducers/skeletontracing_reducer_helpers.js b/app/assets/javascripts/oxalis/model/reducers/skeletontracing_reducer_helpers.js index 147315cd572..253e5b6abaa 100644 --- a/app/assets/javascripts/oxalis/model/reducers/skeletontracing_reducer_helpers.js +++ b/app/assets/javascripts/oxalis/model/reducers/skeletontracing_reducer_helpers.js @@ -605,8 +605,15 @@ export function shuffleTreeColor( tree: TreeType, ): Maybe<[TreeType, number]> { const randomId = _.random(0, 10000, false); - // ColorGenerator fails to produce distinct color for huge ids (Infinity) - const newTree = update(tree, { color: { $set: ColorGenerator.distinctColorForId(randomId) } }); + return setTreeColorIndex(skeletonTracing, tree, randomId); +} + +export function setTreeColorIndex( + skeletonTracing: SkeletonTracingType, + tree: TreeType, + colorIndex: number, +): Maybe<[TreeType, number]> { + const newTree = update(tree, { color: { $set: ColorGenerator.distinctColorForId(colorIndex) } }); return Maybe.Just([newTree, tree.treeId]); }