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

Update displayed position in statusbar when flycam changes #5670

Merged
merged 9 commits into from
Aug 23, 2021

Conversation

MichaelBuessemeyer
Copy link
Contributor

Currently, the displayed position of the mouse in the statusbar does only update, when the mouse is moved. This PR now also changes the statusbar, so that the position also updates, each time the flycam changes (e.g. via space in z direction).

URL of deployed dev instance (used for testing):

  • https://___.webknossos.xyz

Steps to test:

  • Open a tracing and move the mouse over a segment.
  • Now move around with space and the arrow keys.
  • The displayed position should always update.

Issues:


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.

Cool, short fix :) However, I think, there's a more robust way to tackle this problem. See my other comment 🤓

Comment on lines 270 to 271
// Needed so each time the flycam changes, the displayed position also updates.
useSelector(state => state.flycam);
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, this line does not fix the problem at the root. Apart from the fact, that this line purely exists for its side effect (which isn't really idiomatic in this react context), I think, there can still be scenarios where the mouse position will be wrong (didn't test it, but for example, going to full screen with . might not update the position).

I think, the actual problem is that line 286 uses Store.getState() which we should get rid of to be fully reactive. A simple solution could be to use something like const globalMousePosition = useSelector(state => calculateGlobalPos(state), { x, y }).

I think, there is one problem left with my suggested solution: calculateGlobalPos will always return a new instance which means that the statusbar will re-render consequently. However, we've got a helper function for this: reuseInstanceOnEquality. You can read its comment to learn more about it. I think, you can use that helper to make usages of calculateGlobalPos more efficient (since the returned instances will be re-used if they don't change).

Something like
export const calculateGlobalPos = reuseInstanceOnEquality(_calculateGlobalPos); in view_mode_accessor.js. Let me know if you have questions!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I am a bit confused right now. According to the docs shown by vscode we do not need the helper function reuseInstanceOnEquality as useSelector has a second argument:

A hook to access the redux store's state. This hook takes a selector function as an argument. The selector is called with the store state.
This hook takes an optional equality comparison function as the second parameter that allows you to customize the way the selected state is compared to determine whether the component needs to be re-rendered.
If you do not want to have to specify the root state type for whenever you use this hook with an inline selector you can use the TypedUseSelectorHook interface to create a version of this hook that is properly typed for your root state.
@param selector — the selector function
@param equalityFn — the function that will be used to determine equality
@returns — the selected state

The online docs do say the same.

But when I tried this out, the two values passed to the comparison function were always the same 😕.

Thus I simply implemented your suggestion.

I additionally found that the mapping settings view updated with each mouse movement. A quick look revealed that it subscribed to the mouse position without using it. Thus I just removed this in this pr.

Copy link
Member

Choose a reason for hiding this comment

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

I am a bit confused right now. According to the docs shown by vscode we do not need the helper function reuseInstanceOnEquality as useSelector has a second argument:

Yes, this is also a possible workaround. However, that approach requires that all callers of useSelector indeed use the equalityFn parameter (which is very easy to forget and hard to notice afterwards). Using reuseInstanceOnEquality avoids that requirement.

But when I tried this out, the two values passed to the comparison function were always the same confused.

Hm, probably not worth to investigate :)

Thus I simply implemented your suggestion.

👍

I additionally found that the mapping settings view updated with each mouse movement. A quick look revealed that it subscribed to the mouse position without using it. Thus I just removed this in this pr.

Great 👍 This probably dates back to earlier versions where a segment id table was rendered in the mapping view.

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! Works very well 🎉

@philippotto
Copy link
Member

please update the changelog before merging

@MichaelBuessemeyer MichaelBuessemeyer enabled auto-merge (squash) August 23, 2021 13:02
@MichaelBuessemeyer MichaelBuessemeyer merged commit ca6eaeb into master Aug 23, 2021
@philippotto philippotto deleted the fix-positioning-update-in-statusbar branch June 14, 2022 11:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Scrolling data in z should update status bar info
2 participants