Skip to content
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

Brush presets #7101

Merged
merged 44 commits into from
Jun 20, 2023
Merged

Brush presets #7101

merged 44 commits into from
Jun 20, 2023

Conversation

dieknolle3333
Copy link
Contributor

@dieknolle3333 dieknolle3333 commented May 26, 2023

Steps to test:

  • Go into brush mode when viewing an annotation
  • Open the change brushsize popover
  • Make sure there are buttons you can click to set the brush size to small, medium and large
  • The brush itself should be visible in the center of the active viewport

Issues:


(Please delete unneeded items, merge only when none are left open)

  • Updated changelog
  • Removed dev-only changes like prints and application.conf edits
  • Considered common edge cases
  • Needs datastore update after deployment

@dieknolle3333 dieknolle3333 self-assigned this May 26, 2023
@dieknolle3333
Copy link
Contributor Author

@philippotto Some thoughts and questions.

  • I manage to center the brush upon opening the popover. The problem is that it is only shown in the active viewport (or in Plane_XY as a default am seeing that correctly). That also means that at first the brush is centered in YZ, but as the popover is above XY, the plane with the centered brush switches to XY. I find that to be quite confusing. Should I simply remember the active viewport upon opening the popover and display the brush there as long as the popover remains open? So the viewport where the brush is shown could only change after closing and opening the popover.
  • The initial problem, that the popover is covering up the brush, can still happen (see picture) after resizing the upper right viewport. Is that just how it is or should I try to take care of that?
    image

@philippotto
Copy link
Member

@dieknolle3333 I think you found a deeper problem in the current event handling. Namely, that the brush can be moved even when the mouse is an another UI (e.g, your popover which is placed above the viewport). I investigated this a bit and think that the input.ts module should be adapted accordingly. I just a committed the change for this on this PR. Please test whether this solves your problems. If this is the case, it should even be possible to remove the code you added that ignores the "set mouse position" event while the popover is visible (you might want to comment out the relevant condition first and if this works then the rest can be cleaned up; e.g., storing the visible flag in the store is probably not necessary anymore then).

The initial problem, that the popover is covering up the brush, can still happen (see picture) after resizing the upper right viewport. Is that just how it is or should I try to take care of that?

I think, this edge case is okay to ignore for now. You could try to change the placement property of the antd popover to right so that the popover hides a bit less of the viewports. However, I'm not sure whether the popover will stick out of the top window edge and thus only will be partly visible (which would be bad ^^).

@dieknolle3333
Copy link
Contributor Author

@philippotto
It works, thank you!

const [isBrushSizePopoverOpen, setIsBrushSizePopoverOpen] = useState(false);
const maximumButtonBrushSize = useSelector((state: OxalisState) => getMaximumBrushSize(state));
const mediumButtonBrushSize = calculateMediumBrushSize(maximumButtonBrushSize);
const minimumButtonBrushSize = Math.max(userSettings.brushSize.minimum, 10); // TODO unsure whether that makes sense across the board
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A brush smaller than 10vx is hardly visible for the dataset I used to test (test-agglomerate-file without zooming in), so I thought this makes sense but wasn't sure. See screenshots attached for visibility of brush sizes 5vx and 10vx with said settings
Screenshot from 2023-05-30 16-28-44
Screenshot from 2023-05-30 16-28-52

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A brush smaller than 10vx is hardly visible for the dataset I used to test (test-agglomerate-file without zooming in), so I thought this makes sense but wasn't sure.

I'd vote to not add any clamping, because it can be confusing to the user. Especially, when zooming very far in, this would be very unintuitive in my opinion. If the brush size is so small, that one cannot see it, so be it :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but would this make sense for the default sizes or should the small preset simply be the smallest size possible?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if I understood your question correctly, but I'd change the small brush size preset from 1 to 10 vx, since that is more common in my opinion.

Copy link
Member

@philippotto philippotto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great! Looks already very good 👍 I have left some feedback, but nothing major :)

@@ -586,6 +754,10 @@ function ChangeBrushSizeButton() {
);
}

function calculateMediumBrushSize(maximumBrushSize: number) {
return Math.ceil((maximumBrushSize - userSettings.brushSize.minimum) / 10) * 5;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice touch with the rounding to multiples of 5 👍

return [smallBrushSize, mediumBrushSize, largeBrushSize];
};

let maximumBrushSize = useSelector((state: OxalisState) => getMaximumBrushSize(state));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd move that above line 560 since it's used in line 561. The current way works technically, because line 562 is executed later than line 567, but I find it cleaner to switch the order.

let smallBrushSize: number, mediumBrushSize: number, largeBrushSize: number;
if (presetBrushSizes.length === 0) {
[smallBrushSize, mediumBrushSize, largeBrushSize] = getDefaultBrushSizes();
handleUpdatePresetBrushSizes(getDefaultBrushSizes());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a side-effect (since it causes an action dispatch) which should ideally not happen in the normal rendering code. For example, an endless rendering loop could happen if this statement wasn't guarded with a proper if-logic. Currently, it probably works just fine, but it's still cleaner to wrap it with useEffect. The code would look somewhat like this:

  useEffect(() => {
    if (presetBrushSizes.length === 0) {
      handleUpdatePresetBrushSizes(getDefaultBrushSizes());
    }
  }, [presetBrushSizes]); 

  // basically the old code without the handleUpdatePresetBrushSizes:
  let smallBrushSize: number, mediumBrushSize: number, largeBrushSize: number;
  if (presetBrushSizes.length === 0) {
    [smallBrushSize, mediumBrushSize, largeBrushSize] = getDefaultBrushSizes();
  } ...

@@ -68,6 +68,7 @@ const defaultState: OxalisState = {
centerNewNode: true,
overrideNodeRadius: true,
particleSize: 5,
presetBrushSizesAsc: [],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think, I'd go with an object because the semantics are way clearer then :) Also, I don't think, that it will result in significantly more code, so there's not really a downside, I'd hope. I'd go with: presetBrushSizes and {small, medium, large} then (the keys in the object don't need brushSize again as the context makes this clear).

Copy link
Member

@philippotto philippotto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great, but the keyboard handling code needs to be moved somewhere else :)

frontend/javascripts/oxalis/store.ts Outdated Show resolved Hide resolved
Copy link
Member

@philippotto philippotto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome, let's merge it :)

@dieknolle3333
Copy link
Contributor Author

I just thought, maybe I should quickly add the new shortcuts to the keyboard shortcut docu? If you agree I'll do that :) @philippotto

@philippotto
Copy link
Member

Sure, good catch!

@dieknolle3333
Copy link
Contributor Author

@philippotto can you have a quick look at what I wrote?

@philippotto
Copy link
Member

@philippotto can you have a quick look at what I wrote?

Looks good :)

@dieknolle3333 dieknolle3333 merged commit c8a8264 into master Jun 20, 2023
@dieknolle3333 dieknolle3333 deleted the brush-presets branch June 20, 2023 15:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Brush presets Dataset/Annotation view: disable hover effects while viewport is occluded
2 participants