/** * Configures {@link KeyModifier KeyModifiers} for the shortcut. * Calling this method will overwrite any previously set modifier keys. * Hence, calling {@code shortcutRegistration.withModifiers();} will remove * all previously set modifier keys. * * @param keyModifiers Key modifiers. Can be empty. * @return this <code>ShortcutRegistration</code> */ public ShortcutRegistration withModifiers(KeyModifier... keyModifiers) { this.modifiers.clear(); prepareForClientResponse(); for (KeyModifier keyModifier : keyModifiers) { addKey(keyModifier); } return this; }
private String filterText() { return generateEventKeyFilter(primaryKey) + " && " + generateEventModifierFilter(modifiers); }
/** * Fluently define the {@link Component} onto which the shortcut's listener * is bound. Calling this method will remove the previous listener from the * {@code component} it was bound to. * * @param listenOnComponent {@code Component} onto which the shortcut * listener is bound. * @return this <code>ShortcutRegistration</code> */ public ShortcutRegistration listenOn(Component listenOnComponent) { removeAllListenerRegistrations(); this.listenOnSupplier = () -> listenOnComponent; prepareForClientResponse(); return this; }
"key")); return new ShortcutRegistration(this, () -> this, listener, key).withModifiers(keyModifiers);
private void registerLifecycleOwner(Component owner) { assert owner != null; lifecycleOwner = owner; // since we are attached, UI should be available Registration attachRegistration = owner.addAttachListener(e -> queueBeforeExecutionCallback()); // remove shortcut listener when detached Registration detachRegistration = owner.addDetachListener(e -> removeListenerRegistration()); lifecycleRegistration = new CompoundRegistration(attachRegistration, detachRegistration); }
/** * @param lifecycleOwner * This is the component which controls when the shortcut is * actually active. If the component is either detached or * invisible, the shortcut will not be active * @param listenOnSupplier * Supplier for component to which the shortcut listener is * bound to. Supplier is given in order to get around some * cases where the component might not be immediately * available. * @param eventListener * The listener to invoke when the shortcut detected * @param key * Primary key of the shortcut. This can not be a * {@link KeyModifier}. */ ShortcutRegistration(Component lifecycleOwner, SerializableSupplier<Component> listenOnSupplier, ShortcutEventListener eventListener, Key key) { if (Key.isModifier(key)) { throw new InvalidParameterException(String.format("Parameter " + "'key' cannot belong to %s", KeyModifier.class.getSimpleName())); } this.eventListener = eventListener; this.listenOnSupplier = listenOnSupplier; setLifecycleOwner(lifecycleOwner); // addKey cannot be called without lifecycleOwner addKey(key); }
private void updateHandlerListenerRegistration() { assert listenOnComponent != null; if (shortcutListenerRegistration == null) { if (listenOnComponent.getUI().isPresent()) { shortcutListenerRegistration = new CompoundRegistration(); Registration keydownRegistration = ComponentUtil.addListener( listenOnComponent, KeyDownEvent.class, e -> { if (lifecycleOwner.isVisible()) { invokeShortcutEventListener(); } }, domRegistration -> { shortcutListenerRegistration.addRegistration( domRegistration); configureHandlerListenerRegistration(); }); shortcutListenerRegistration.addRegistration( keydownRegistration); } } else { configureHandlerListenerRegistration(); } }
/** * Fluently adds {@link KeyModifier#SHIFT} to the shortcut's modifiers. * @return this <code>ShortcutRegistration</code> */ public ShortcutRegistration withShift() { addKey(KeyModifier.SHIFT); return this; }
/** * Allows the default keyboard event handling when the shortcut is invoked. * @return this <code>ShortcutRegistration</code> */ public ShortcutRegistration allowBrowserDefault() { if (preventDefault) { preventDefault = false; prepareForClientResponse(); } return this; }
private void prepareForClientResponse() { assert lifecycleOwner != null; synchronized (this) { if (isDirty.get()) { return; } isDirty.set(true); } // if lifecycleOwner is attached, we'll register new // beforeClientResponse callback. Otherwise we'll need to wait for the // lifecycleOwner's attach-callback to do it queueBeforeExecutionCallback(); }
private void setLifecycleOwner(Component owner) { assert owner != null; if (lifecycleRegistration != null) { lifecycleRegistration.remove(); } registerLifecycleOwner(owner); }
private void configureHandlerListenerRegistration() { if (shortcutListenerRegistration != null) { Optional<Registration> registration = shortcutListenerRegistration .registrations.stream().filter(r -> r instanceof DomListenerRegistration) .findFirst(); registration.ifPresent(r -> { DomListenerRegistration listenerRegistration = (DomListenerRegistration) r; String filterText = filterText(); /* Due to https://github.com/vaadin/flow/issues/4871 we are not able to use setEventData for these values, so we hack the filter. */ if (preventDefault) { filterText += "&& (event.preventDefault() || true)"; } if (stopPropagation) { filterText += "&& (event.stopPropagation() || true)"; } listenerRegistration.setFilter(filterText); shortcutActive = true; }); } }
"key")); return new ShortcutRegistration(this, () -> this, event -> command.execute(), key).withModifiers(keyModifiers);
/** * Fluently adds {@link KeyModifier#ALT} to the shortcut's modifiers. * @return this <code>ShortcutRegistration</code> */ public ShortcutRegistration withAlt() { addKey(KeyModifier.ALT); return this; }
/** * Allow the event to propagate upwards in the dom tree, when the * shortcut is invoked. * @return this <code>ShortcutRegistration</code> */ public ShortcutRegistration allowEventPropagation() { if (stopPropagation) { stopPropagation = false; prepareForClientResponse(); } return this; }
throw new InvalidParameterException(String.format(NULL, "key")); return new ShortcutRegistration(lifecycleOwner, UI::getCurrent, listener, key).withModifiers(keyModifiers);
/** * Fluently adds {@link KeyModifier#CONTROL} to the shortcut's modifiers. * @return this <code>ShortcutRegistration</code> */ public ShortcutRegistration withCtrl() { addKey(KeyModifier.CONTROL); return this; }
private void addKey(Key key) { assert key != null; HashableKey hashableKey = new HashableKey(key); if (Key.isModifier(key)) { if (!modifiers.contains(hashableKey)) { modifiers.add(hashableKey); prepareForClientResponse(); } } else { if (primaryKey == null || !primaryKey.equals(hashableKey)) { primaryKey = hashableKey; prepareForClientResponse(); } } }
return new ShortcutRegistration((Component) this, UI::getCurrent, event -> this.focus(), key).withModifiers(keyModifiers);
/** * Fluently adds {@link KeyModifier#META} to the shortcut's modifiers. * @return this <code>ShortcutRegistration</code> */ public ShortcutRegistration withMeta() { addKey(KeyModifier.META); return this; }