/** * Returns a {@link Set} containing all {@link IFXOnTypePolicy}s that are installed on the target * {@link IVisualPart} for the given {@link Scene}. If an {@link IVisualPart} within the given * {@link Scene} has keyboard focus, that part is used as the target part. Otherwise, the root * part of the {@link IViewer} that is rendered in the given {@link Scene} is used as the target * part. * * @param scene The {@link Scene} for which to determine the {@link IFXOnTypePolicy}s that are * installed on the target {@link IVisualPart}. * @return A {@link List} containing all {@link IFXOnTypePolicy}s that are installed on the target * {@link IVisualPart} for the given {@link Scene}. */ @SuppressWarnings("serial") protected List<? extends IFXOnTypePolicy> getTargetPolicies(Scene scene) { IVisualPart<Node, ? extends Node> targetPart = null; for (IViewer<Node> viewer : getDomain().getViewers().values()) { if (viewer instanceof FXViewer) { if (((FXViewer) viewer).getScene() == scene) { FocusModel<Node> focusModel = viewer.getAdapter(new TypeToken<FocusModel<Node>>() {}); if (focusModel == null) { throw new IllegalStateException("Cannot find FocusModel<Node>."); } IVisualPart<Node, ? extends Node> part = focusModel.getFocus(); if (part == null) { targetPart = viewer.getRootPart(); } else { targetPart = part; } break; } } } if (targetPart == null) { return Collections.emptyList(); } return targetPolicyResolver.getTargetPolicies( this, targetPart.getVisual(), IFXOnTypePolicy.class); }
@Override protected void unregisterListeners() { for (IViewer<Node> viewer : getDomain().getViewers().values()) { viewer.viewerFocusedProperty().removeListener(viewerFocusChangeListeners.remove(viewer)); Scene scene = viewer.getRootPart().getVisual().getScene(); if (pressedFilterMap.containsKey(scene)) { scene.removeEventFilter(KeyEvent.KEY_PRESSED, pressedFilterMap.remove(scene)); } if (releasedFilterMap.containsKey(scene)) { scene.removeEventFilter(KeyEvent.KEY_RELEASED, releasedFilterMap.remove(scene)); } if (typedFilterMap.containsKey(scene)) { scene.removeEventFilter(KeyEvent.KEY_TYPED, typedFilterMap.remove(scene)); } } }
/** * Constructs a new {@link ShowHiddenNeighborsOperation} that will show all hidden neighbors of * the given {@link NodeContentPart} by removing them from the {@link HidingModel} of the given * {@link IViewer} upon execution. * * @param viewer The viewer from which to retrieve the {@link HidingModel}. * @param nodePart The {@link NodeContentPart} of which the hidden neighbors are to be shown. */ public ShowHiddenNeighborsOperation(IViewer<javafx.scene.Node> viewer, NodeContentPart nodePart) { super("ShowHiddenNeighbors"); this.nodePart = nodePart; hidingModel = viewer.getAdapter(HidingModel.class); }
@SuppressWarnings("serial") @Override protected void registerListeners() { for (final IViewer<Node> viewer : getDomain().getViewers().values()) { // check if we have access to a FocusModel<Node> FocusModel<Node> focusModel = viewer.getAdapter(new TypeToken<FocusModel<Node>>() {}); if (focusModel == null) { throw new IllegalStateException("Cannot find FocusModel<Node>."); } // store the key that is initially pressed so that we can wait for // it to be released final Set<KeyCode> pressedKeys = new HashSet<>(); // register a viewer focus change listener to release the initially // pressed key when the window loses focus ChangeListener<Boolean> viewerFocusChangeListener = new ChangeListener<Boolean>() { @Override public void changed( ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) { if (newValue == null || !newValue) { if (pressedKeys.isEmpty()) { return; } // cancel target policies for (IFXOnTypePolicy policy : getActivePolicies(viewer)) { policy.unfocus(); } // clear active policies and close execution // transaction clearActivePolicies(viewer); getDomain().closeExecutionTransaction(FXTypeTool.this); // unset pressed keys pressedKeys.clear(); } } }; viewer.viewerFocusedProperty().addListener(viewerFocusChangeListener); viewerFocusChangeListeners.put(viewer, viewerFocusChangeListener); Scene scene = viewer.getRootPart().getVisual().getScene(); if (pressedFilterMap.containsKey(scene)) { continue; } // generate event handlers EventHandler<KeyEvent> pressedFilter = new EventHandler<KeyEvent>() { @Override public void handle(KeyEvent event) { // store initially pressed key // System.out.println("pressed " + event); if (pressedKeys.isEmpty()) { // open exec tx on first key press getDomain().openExecutionTransaction(FXTypeTool.this); // determine target policies on first key press setActivePolicies(viewer, getTargetPolicies(event)); } pressedKeys.add(event.getCode()); // notify target policies for (IFXOnTypePolicy policy : getActivePolicies(viewer)) { policy.pressed(event); } } }; pressedFilterMap.put(scene, pressedFilter); EventHandler<KeyEvent> releasedFilter = new EventHandler<KeyEvent>() { @Override public void handle(KeyEvent event) { // System.out.println("released " + event); // notify target policies for (IFXOnTypePolicy policy : getActivePolicies(viewer)) { policy.released(event); } // check if the last pressed key is released now if (pressedKeys.size() == 1 && pressedKeys.contains(event.getCode())) { // clear active policies and close execution transaction // only when the initially pressed key is released clearActivePolicies(viewer); getDomain().closeExecutionTransaction(FXTypeTool.this); } pressedKeys.remove(event.getCode()); } }; releasedFilterMap.put(scene, releasedFilter); EventHandler<KeyEvent> typedFilter = new EventHandler<KeyEvent>() { @Override public void handle(KeyEvent event) { // System.out.println("typed " + event); if (pressedKeys.isEmpty()) { getDomain().openExecutionTransaction(FXTypeTool.this); } Collection<? extends IFXOnTypePolicy> policies = getTargetPolicies(event); // active policies are unnecessary because TYPED is not a // gesture, just one event at one point in time for (IFXOnTypePolicy policy : policies) { policy.typed(event); } if (pressedKeys.isEmpty()) { getDomain().closeExecutionTransaction(FXTypeTool.this); } } }; typedFilterMap.put(scene, typedFilter); scene.addEventFilter(KeyEvent.KEY_PRESSED, pressedFilter); scene.addEventFilter(KeyEvent.KEY_RELEASED, releasedFilter); scene.addEventFilter(KeyEvent.KEY_TYPED, typedFilter); } }