/** * erlyberly, erlang trace debugger * Copyright (C) 2016 Andy Till * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package erlyberly; import java.util.ArrayList; import javafx.application.Platform; import javafx.scene.Scene; import javafx.scene.control.Control; import javafx.scene.input.KeyCode; import javafx.scene.input.KeyCodeCombination; import javafx.scene.input.KeyCombination; public class FilterFocusManager { private static final KeyCodeCombination REFRESH_MODULES_SHORTCUT = new KeyCodeCombination(KeyCode.F, KeyCombination.SHORTCUT_DOWN); private static final ArrayList<Control> FILTERS = new ArrayList<>(); private static int lastFocusedIndex = -1; private FilterFocusManager() {} public static void init(Scene scene) { FILTERS.add(null); FILTERS.add(null); FILTERS.add(null); Platform.runLater(() -> { scene.getAccelerators().put(REFRESH_MODULES_SHORTCUT, () -> { nextFilter(); }); }); } private static void nextFilter() { if(FILTERS.isEmpty()) return; Control control = findNextFilter(); requestFocus(control); } private static Control findNextFilter() { // if we know about a filter control that was focused last but does not currently // have focus then return to it. The filter must be visible and attached to the scene. if(lastFocusedIndex != -1) { Control lastFocused = FILTERS.get(lastFocusedIndex); if(!lastFocused.isFocused() && lastFocused.isVisible() && lastFocused.getScene() != null) { return lastFocused; } } int focused = findCurrentFilter(); if(focused == -1) { focused = 0; } // iterate the filters until we find one that is part of the scene or we run out of filters int iterations = 0; while(iterations < FILTERS.size()) { iterations++; focused++; if(focused >= FILTERS.size()) { focused = 0; } boolean isFocusable = FILTERS.get(focused).getScene() != null; if(isFocusable) break; } return FILTERS.get(focused); } private static int findCurrentFilter() { int focused = -1; for (int i = 0; i < FILTERS.size(); i++) { Control control = FILTERS.get(i); if(control != null && control.isFocused()) { focused = i; break; } } return focused; } private static void requestFocus(Control control) { if(control != null) Platform.runLater(() -> { control.requestFocus(); }); } public static void addFilter(Control control, int order) { assert control != null; assert order >= 0; assert Platform.isFxApplicationThread(); FILTERS.set(order, control); control.focusedProperty().addListener((o, oldFocus, newFocus) -> { lastFocusedIndex = order; }); } }