diff --git a/CHANGELOG.unreleased.md b/CHANGELOG.unreleased.md index 96d6ed2aa5..e5f8c3ee23 100644 --- a/CHANGELOG.unreleased.md +++ b/CHANGELOG.unreleased.md @@ -17,9 +17,9 @@ For upgrade instructions, please check the [migration guide](MIGRATIONS.released - Added the option for "Selective Segment Visibility" for segmentation layers. Select this option in the left sidebar to only show segments that are currently active or hovered. [#8281](https://github.com/scalableminds/webknossos/pull/8281) - A segment can be activated with doubleclick now. [#8281](https://github.com/scalableminds/webknossos/pull/8281) - It is now possible to select the magnification of the layers on which an AI model will be trained. [#8266](https://github.com/scalableminds/webknossos/pull/8266) +- When the eraser tool is active, one can switch temporarily to the fill-segment tool by pressing shift and ctrl. Only pressing shift, switches to the pick-segment tool. [#8314](https://github.com/scalableminds/webknossos/pull/8314) - Enabled auto sorting of Typescript imports in Biome linter. [#8313](https://github.com/scalableminds/webknossos/pull/8313) - ### Changed - Renamed "resolution" to "magnification" in more places within the codebase, including local variables. [#8168](https://github.com/scalableminds/webknossos/pull/8168) - Layer names are now allowed to contain `$` as special characters. [#8241](https://github.com/scalableminds/webknossos/pull/8241) diff --git a/frontend/javascripts/oxalis/controller/combinations/tool_controls.ts b/frontend/javascripts/oxalis/controller/combinations/tool_controls.ts index 6da4b921ca..478f38aa24 100644 --- a/frontend/javascripts/oxalis/controller/combinations/tool_controls.ts +++ b/frontend/javascripts/oxalis/controller/combinations/tool_controls.ts @@ -497,12 +497,26 @@ export class EraseTool { leftDownMove: (_delta: Point2, pos: Point2) => { VolumeHandlers.handleMoveForDrawOrErase(pos); }, - leftMouseDown: (pos: Point2, plane: OrthoView, _event: MouseEvent) => { + leftMouseDown: (pos: Point2, plane: OrthoView, event: MouseEvent) => { + if (event.shiftKey || event.ctrlKey || event.metaKey) { + return; + } + VolumeHandlers.handleEraseStart(pos, plane); }, leftMouseUp: () => { VolumeHandlers.handleEndForDrawOrErase(); }, + leftClick: (pos: Point2, plane: OrthoView, event: MouseEvent) => { + const isControlOrMetaPressed = event.ctrlKey || event.metaKey; + if (event.shiftKey) { + if (isControlOrMetaPressed) { + VolumeHandlers.handleFloodFill(pos, plane); + } else { + VolumeHandlers.handlePickCell(pos); + } + } + }, rightClick: (pos: Point2, plane: OrthoView, event: MouseEvent, isTouch: boolean) => { SkeletonHandlers.handleOpenContextMenu(planeView, pos, plane, isTouch, event); }, diff --git a/frontend/javascripts/oxalis/model/accessors/tool_accessor.ts b/frontend/javascripts/oxalis/model/accessors/tool_accessor.ts index f7575ec587..366d0a9116 100644 --- a/frontend/javascripts/oxalis/model/accessors/tool_accessor.ts +++ b/frontend/javascripts/oxalis/model/accessors/tool_accessor.ts @@ -350,18 +350,16 @@ export const getDisabledInfoForTools = reuseInstanceOnEquality(_getDisabledInfoF export function adaptActiveToolToShortcuts( activeTool: AnnotationTool, isShiftPressed: boolean, - isControlPressed: boolean, + isControlOrMetaPressed: boolean, isAltPressed: boolean, ): AnnotationTool { - if (!isShiftPressed && !isControlPressed && !isAltPressed) { + if (!isShiftPressed && !isControlOrMetaPressed && !isAltPressed) { // No modifier is pressed return activeTool; } if ( activeTool === AnnotationToolEnum.MOVE || - activeTool === AnnotationToolEnum.ERASE_BRUSH || - activeTool === AnnotationToolEnum.ERASE_TRACE || activeTool === AnnotationToolEnum.QUICK_SELECT || activeTool === AnnotationToolEnum.PROOFREAD || activeTool === AnnotationToolEnum.LINE_MEASUREMENT || @@ -369,28 +367,39 @@ export function adaptActiveToolToShortcuts( ) { // These tools do not have any modifier-related behavior currently (except for ALT // which is already handled below) + } else if ( + activeTool === AnnotationToolEnum.ERASE_BRUSH || + activeTool === AnnotationToolEnum.ERASE_TRACE + ) { + if (isShiftPressed) { + if (isControlOrMetaPressed) { + return AnnotationToolEnum.FILL_CELL; + } else { + return AnnotationToolEnum.PICK_CELL; + } + } } else { if (activeTool === AnnotationToolEnum.SKELETON) { // The "skeleton" tool is not changed right now (since actions such as moving a node // don't have a dedicated tool). The only exception is "Alt" which switches to the move tool. - if (isAltPressed && !isControlPressed && !isShiftPressed) { + if (isAltPressed && !isControlOrMetaPressed && !isShiftPressed) { return AnnotationToolEnum.MOVE; } return activeTool; } - if (isShiftPressed && !isControlPressed && !isAltPressed) { - // Only shift is pressed. Switch to the picker - return AnnotationToolEnum.PICK_CELL; - } - - if (isControlPressed && isShiftPressed && !isAltPressed) { - // Control and shift switch to the eraser - if (activeTool === AnnotationToolEnum.BRUSH) { - return AnnotationToolEnum.ERASE_BRUSH; - } else if (activeTool === AnnotationToolEnum.TRACE) { - return AnnotationToolEnum.ERASE_TRACE; + if (isShiftPressed && !isAltPressed) { + if (!isControlOrMetaPressed) { + // Only shift is pressed. Switch to the picker + return AnnotationToolEnum.PICK_CELL; + } else { + // Control and shift switch to the eraser + if (activeTool === AnnotationToolEnum.BRUSH) { + return AnnotationToolEnum.ERASE_BRUSH; + } else if (activeTool === AnnotationToolEnum.TRACE) { + return AnnotationToolEnum.ERASE_TRACE; + } } } } diff --git a/frontend/javascripts/oxalis/model/sagas/volume/floodfill_saga.tsx b/frontend/javascripts/oxalis/model/sagas/volume/floodfill_saga.tsx index 9274d616b9..9363803ca1 100644 --- a/frontend/javascripts/oxalis/model/sagas/volume/floodfill_saga.tsx +++ b/frontend/javascripts/oxalis/model/sagas/volume/floodfill_saga.tsx @@ -10,11 +10,12 @@ import type { Vector2, Vector3, } from "oxalis/constants"; -import Constants, { FillModeEnum, Unicode } from "oxalis/constants"; +import Constants, { AnnotationToolEnum, FillModeEnum, Unicode } from "oxalis/constants"; import _ from "lodash"; import { getDatasetBoundingBox, getMagInfo } from "oxalis/model/accessors/dataset_accessor"; import { getActiveMagIndexForLayer } from "oxalis/model/accessors/flycam_accessor"; +import { getDisabledInfoForTools } from "oxalis/model/accessors/tool_accessor"; import { enforceActiveVolumeTracing } from "oxalis/model/accessors/volumetracing_accessor"; import { addUserBoundingBoxAction } from "oxalis/model/actions/annotation_actions"; import { setBusyBlockingInfoAction } from "oxalis/model/actions/ui_actions"; @@ -117,8 +118,9 @@ function* getBoundingBoxForFloodFill( function* handleFloodFill(floodFillAction: FloodFillAction): Saga { const allowUpdate = yield* select((state) => state.tracing.restrictions.allowUpdate); + const disabledInfosForTools = yield* select(getDisabledInfoForTools); - if (!allowUpdate) { + if (!allowUpdate || disabledInfosForTools[AnnotationToolEnum.FILL_CELL].isDisabled) { return; } diff --git a/frontend/javascripts/oxalis/view/input_catcher.tsx b/frontend/javascripts/oxalis/view/input_catcher.tsx index 9527899d05..bcf97c2f98 100644 --- a/frontend/javascripts/oxalis/view/input_catcher.tsx +++ b/frontend/javascripts/oxalis/view/input_catcher.tsx @@ -140,7 +140,7 @@ function InputCatcher({ const activeTool = useSelector((state: OxalisState) => state.uiInformation.activeTool); const isShiftPressed = useKeyPress("Shift"); - const isControlPressed = useKeyPress("ControlOrMeta"); + const isControlOrMetaPressed = useKeyPress("ControlOrMeta"); const isAltPressed = useKeyPress("Alt"); const adaptedTool = @@ -148,7 +148,12 @@ function InputCatcher({ ? AnnotationToolEnum.SKELETON : viewportID === OrthoViews.TDView ? AnnotationToolEnum.MOVE - : adaptActiveToolToShortcuts(activeTool, isShiftPressed, isControlPressed, isAltPressed); + : adaptActiveToolToShortcuts( + activeTool, + isShiftPressed, + isControlOrMetaPressed, + isAltPressed, + ); return (
= { '"Nunito", "Monospaced Number", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Helvetica Neue", Helvetica, Arial, sans-serif;', }; +const lightGlobalToken = theme.getDesignToken({ + token: globalDesignToken, + algorithm: theme.defaultAlgorithm, +}); + const darkGlobalToken = theme.getDesignToken({ token: globalDesignToken, algorithm: theme.darkAlgorithm, @@ -87,7 +92,7 @@ export function getAntdTheme(userTheme: Theme) { }, Tree: { colorBgContainer: "transparent", - directoryNodeSelectedBg: ColorWKBlue, + nodeSelectedBg: lightGlobalToken.blue3, titleHeight: 20, // default is 24px, marginXXS: 2, // default is 4px; adjust to match checkboxes because of smaller titleHeight },