/* * Copyright (C) 2014 Brockmann Consult GmbH (info@brockmann-consult.de) * * 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 org.esa.snap.netbeans.tile; import org.openide.windows.Mode; import org.openide.windows.TopComponent; import org.openide.windows.WindowManager; import java.awt.*; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.List; import java.util.Set; import java.util.stream.Collectors; import static java.lang.Math.min; /** * Collections of utility methods used for editor tiling. * * @author Norman Fomferra * @since 1.0 */ public class TileUtilities { public static final String EDITOR_MODE_NAME_FORMAT = "editor_r%dc%d"; public static final int MAX_TILE_ROW_COUNT = 16; public static final int MAX_TILE_COLUMN_COUNT = 16; /** * Opens a top component in a mode of kind "editor" at the given row and column. * * @param topComponent The top component to open. * @param rowIndex The row index. * @param colIndex The column index. * @return {@code true} on success. */ public static boolean openInEditorMode(TopComponent topComponent, int rowIndex, int colIndex) { String modeName = String.format(EDITOR_MODE_NAME_FORMAT, rowIndex, colIndex); return openInMode(topComponent, modeName); } /** * Opens a top component in the given mode. * * @param topComponent The top component to open. * @param modeName The mode's name. * @return {@code true} on success. */ public static boolean openInMode(TopComponent topComponent, String modeName) { Mode mode = WindowManager.getDefault().findMode(modeName); if (mode != null) { if (!Arrays.asList(mode.getTopComponents()).contains(topComponent)) { if (mode.dockInto(topComponent)) { topComponent.open(); return true; } } else { topComponent.open(); return true; } } return false; } /** * Counts the currently opened top components in modes of kind "editor". * * @return The number of currently opened top components in modes of kind "editor" */ public static int countOpenEditorWindows() { int count = 0; WindowManager wm = WindowManager.getDefault(); Set<TopComponent> opened = wm.getRegistry().getOpened(); for (TopComponent openedWindow : opened) { if (wm.isEditorTopComponent(openedWindow)) { count++; } } return count; } /** * Finds all opened top components in modes of kind "editor" ordered by display name. * * @return The list of opened top components. */ public static List<TopComponent> findOpenEditorWindows() { return findOpenEditorWindows((win1, win2) -> { String name1 = win1.getDisplayName(); String name2 = win2.getDisplayName(); return (name1 != null ? name1 : "").compareTo(name2 != null ? name2 : ""); }); } /** * Finds all opened top components in modes of kind "editor" using the given comparator. * * @return The list of opened top components. */ public static List<TopComponent> findOpenEditorWindows(Comparator<TopComponent> comparator) { ArrayList<TopComponent> editorWindows = new ArrayList<>(); Set<TopComponent> openedWindows = WindowManager.getDefault().getRegistry().getOpened(); editorWindows.addAll(openedWindows .stream() .filter(topComponent -> WindowManager.getDefault().isEditorTopComponent(topComponent)) .collect(Collectors.toList())); if (comparator != null) { editorWindows.sort(comparator); } return editorWindows; } /** * Finds the best matching matrix of equal-area squares * given a fixed number of window areas. * * @param windowCount Number of window areas. * @return Matrix size, where width=#columns, and height=#rows. */ public static Dimension computeMatrixSizeForEqualAreaTiling(int windowCount) { double minDeltaValue = Double.POSITIVE_INFINITY; int bestRowCount = -1; int bestColCount = -1; for (int rowCount = 1; rowCount <= min(windowCount, MAX_TILE_ROW_COUNT); rowCount++) { for (int colCount = 1; colCount <= min(windowCount, MAX_TILE_COLUMN_COUNT); colCount++) { if (colCount * rowCount >= windowCount && colCount * rowCount <= 2 * windowCount) { double deltaRatio = Math.abs(1.0 - rowCount / (double) colCount); double deltaCount = Math.abs(1.0 - (colCount * rowCount) / ((double) windowCount)); double deltaValue = deltaRatio + deltaCount; if (deltaValue < minDeltaValue) { minDeltaValue = deltaValue; bestRowCount = rowCount; bestColCount = colCount; if (deltaValue == 0.0) { break; } } } } } return new Dimension(bestColCount, bestRowCount); } }