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

Grid: CellFocusEvent: add more information to the event #7044

Open
mvysny opened this issue Jan 14, 2025 · 1 comment
Open

Grid: CellFocusEvent: add more information to the event #7044

mvysny opened this issue Jan 14, 2025 · 1 comment
Labels
enhancement New feature or request

Comments

@mvysny
Copy link
Member

mvysny commented Jan 14, 2025

Describe your motivation

I'm implementing a grid selection based on keyboard events: I select grid rows and fire other app-specific events as the focus rectangle moves around in the grid. If the focus rectangle moves with a shift key pressed, I want to add the new row to the selection (multi-select grid), otherwise I want to set the new row as a singular row in the selection. The behavior is slightly different when clicking with a mouse, so I'd also like to differentiate between the focus rectangle moving as a result of a mouse click, or an arrow key press.

I'm listening for CellFocusEvent events to implement this functionality. Unfortunately, CellFocusEvent doesn't contain the necessary information.

Please backport this functionality to Vaadin 23.

Describe the solution you'd like

The event should contain the following information:

  1. Whether Shift, Alt, Ctrl or other modifier keys were pressed. Shift+Ctrl is the bare minimum
  2. Whether the event is fired as a result of key press (most probably focus moved via cursor keys), or as a result of a mouse click

Describe alternatives you've considered

The ItemClickEvent contains the necessary info but it isn't fired as an outcome of arrow key presses.

Additional context

No response

@yuriy-fix yuriy-fix added the enhancement New feature or request label Jan 16, 2025
@yuriy-fix yuriy-fix self-assigned this Jan 16, 2025
@yuriy-fix yuriy-fix removed their assignment Jan 29, 2025
@mvysny
Copy link
Member Author

mvysny commented Jan 29, 2025

@yuriy-fix posted a lovely workaround which adds additional mousedown and keydown listeners which remember the shift/ctrl/alt modifier keys. This kind of solution always carries an inherent danger of events being processed in different order than intended, so you've been warned. With Yuriy's permission, I'm posting the workaround:

class CustomGrid<T> extends Grid<T> implements KeyNotifier {
        private boolean lastEventWasKeyboard = false;

        private boolean shiftPressed = false;
        private boolean ctrlPressed = false;
        private boolean altPressed = false;

        public CustomGrid() {
            super();

            getElement().executeJs(
                    "this.addEventListener('mousedown', (e) => {this.$server.handleMouseDown(e.shiftKey, e.ctrlKey, e.altKey);});");

            addKeyDownListener(e -> {
                // You can check for the arrows keys for additional logic
                Set<KeyModifier> modifiers = e.getModifiers();
                setModifiers(modifiers.contains(KeyModifier.SHIFT),
                        modifiers.contains(KeyModifier.CONTROL),
                        modifiers.contains(KeyModifier.ALT));

                if(isNotModifier(e.getKey())) {
                    lastEventWasKeyboard = true;
                }
            });

            addKeyUpListener(e -> {
                if (isNotModifier(e.getKey())) {
                    lastEventWasKeyboard = false;
                }
            });

            addCellFocusListener(e -> {
                Optional<T> item = e.getItem();
                if (item.isEmpty()) {
                    return;
                }

                // This is just an example, should be replaced with actual logic
                String type = lastEventWasKeyboard ? "Keyboard" : "Non-keyboard";
                String modifiersString = shiftPressed ? " shiftKey" : "";
                modifiersString += ctrlPressed ? ", ctrlKey" : "";
                modifiersString += altPressed ? ", altKey" : "";

                System.out.println(type + " focus with" + (!modifiersString.isEmpty() ? modifiersString : "out modifiers"));
            });
        }

        @ClientCallable
        private void handleMouseDown(boolean shiftKey, boolean ctrlKey, boolean altKey) {
            lastEventWasKeyboard = false;
            setModifiers(shiftKey, ctrlKey, altKey);
        }

        private void setModifiers(boolean shiftKey, boolean ctrlKey, boolean altKey) {
            shiftPressed = shiftKey;
            ctrlPressed = ctrlKey;
            altPressed = altKey;
        }

        private boolean isNotModifier(Key key) {
            return !key.matches("Shift") && !key.matches("Control") && !key.matches("Alt");
        }
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants