1 /* 2 * Copyright (c) 2012, 2014, Oracle and/or its affiliates. 3 * All rights reserved. Use is subject to license terms. 4 * 5 * This file is available and licensed under the following license: 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * - Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * - Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the distribution. 16 * - Neither the name of Oracle Corporation nor the names of its 17 * contributors may be used to endorse or promote products derived 18 * from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 package com.oracle.javafx.scenebuilder.kit.editor.job.gridpane; 33 34 import com.oracle.javafx.scenebuilder.kit.editor.EditorController; 35 import com.oracle.javafx.scenebuilder.kit.editor.selection.AbstractSelectionGroup; 36 import com.oracle.javafx.scenebuilder.kit.editor.selection.GridSelectionGroup; 37 import com.oracle.javafx.scenebuilder.kit.editor.selection.GridSelectionGroup.Type; 38 import com.oracle.javafx.scenebuilder.kit.editor.selection.ObjectSelectionGroup; 39 import com.oracle.javafx.scenebuilder.kit.editor.selection.Selection; 40 import com.oracle.javafx.scenebuilder.kit.fxom.FXOMObject; 41 import com.oracle.javafx.scenebuilder.kit.metadata.util.DesignHierarchyMask; 42 import java.util.ArrayList; 43 import java.util.HashSet; 44 import java.util.List; 45 import java.util.Set; 46 import javafx.scene.layout.GridPane; 47 48 /** 49 * Utilities to build GridPane jobs. 50 */ 51 public class GridPaneJobUtils { 52 53 public enum Position { 54 55 ABOVE, BELOW, BEFORE, AFTER 56 } 57 58 /** 59 * Returns the list of target GridPane objects. 60 * 61 * @return the list of target GridPane objects 62 */ 63 static List<FXOMObject> getTargetGridPanes( 64 final EditorController editorController) { 65 66 final Selection selection = editorController.getSelection(); 67 final AbstractSelectionGroup asg = selection.getGroup(); 68 assert asg instanceof ObjectSelectionGroup 69 || asg instanceof GridSelectionGroup; 70 71 final List<FXOMObject> result = new ArrayList<>(); 72 73 // Selection == GridPanes 74 if (asg instanceof ObjectSelectionGroup) { 75 final ObjectSelectionGroup osg = (ObjectSelectionGroup) asg; 76 result.addAll(osg.getItems()); 77 } // 78 // Selection == GridPane rows or columns 79 else if (asg instanceof GridSelectionGroup) { 80 final GridSelectionGroup gsg = (GridSelectionGroup) asg; 81 result.add(gsg.getParentObject()); 82 } 83 84 return result; 85 } 86 87 /** 88 * Returns the list of integers 89 * - greater (or ==) than fromIndex 90 * - smaller (or ==) than toIndex 91 * 92 * @param fromIndex 93 * @param toIndex 94 * @return 95 */ 96 static List<Integer> getIndexes(int fromIndex, int toIndex) { 97 assert fromIndex <= toIndex; 98 final List<Integer> result = new ArrayList<>(); 99 int index = fromIndex; 100 while (index <= toIndex) { 101 result.add(index++); 102 } 103 return result; 104 } 105 106 /** 107 * Returns the list of indexes to be added : 108 * When adding several rows/columns to a single GridPane (targetIndexes >= 1), 109 * each added row/column must be shifted as many times as rows/columns added before. 110 * 111 * @return the list of target indexes 112 */ 113 static Set<Integer> getAddedIndexes( 114 final Set<Integer> targetIndexes, 115 final Position position) { 116 final Set<Integer> result = new HashSet<>(); 117 int shiftIndex = 0; 118 for (int targetIndex : targetIndexes) { 119 int addedIndex = targetIndex + shiftIndex++; 120 if (position == Position.BELOW || position == Position.AFTER) { 121 addedIndex++; 122 } 123 result.add(addedIndex); 124 } 125 return result; 126 } 127 128 /** 129 * Returns true if the selection is : 130 * - either 1 or more GridPanes 131 * - or 1 or more rows/columns within a single GridPane 132 * 133 * @param editorController 134 * @return 135 */ 136 static boolean canPerformAdd(final EditorController editorController) { 137 138 boolean result; 139 final Selection selection = editorController.getSelection(); 140 final AbstractSelectionGroup asg = selection.getGroup(); 141 142 if (asg instanceof ObjectSelectionGroup) { 143 final ObjectSelectionGroup osg = (ObjectSelectionGroup) asg; 144 result = true; 145 for (FXOMObject obj : osg.getItems()) { 146 if ((obj.getSceneGraphObject() instanceof GridPane) == false) { 147 result = false; 148 break; 149 } 150 } 151 } else { 152 result = asg instanceof GridSelectionGroup; 153 } 154 return result; 155 } 156 157 /** 158 * Returns true if the selection is 1 or more rows/columns 159 * within a single GridPane 160 * 161 * @param editorController 162 * @return 163 */ 164 static boolean canPerformRemove(final EditorController editorController) { 165 166 final Selection selection = editorController.getSelection(); 167 final AbstractSelectionGroup asg = selection.getGroup(); 168 169 return asg instanceof GridSelectionGroup; 170 } 171 172 /** 173 * Returns true if the selection is 1 or more rows/columns 174 * within a single GridPane 175 * 176 * @param editorController 177 * @return 178 */ 179 static boolean canPerformMove( 180 final EditorController editorController, 181 final Position position) { 182 183 boolean result; 184 final Selection selection = editorController.getSelection(); 185 final AbstractSelectionGroup asg = selection.getGroup(); 186 187 if (asg instanceof GridSelectionGroup) { 188 final GridSelectionGroup gsg = (GridSelectionGroup) asg; 189 final FXOMObject gridPane = gsg.getParentObject(); 190 final Type type = gsg.getType(); 191 final DesignHierarchyMask mask = new DesignHierarchyMask(gridPane); 192 193 switch (type) { 194 case COLUMN: 195 if (position == Position.BEFORE) { 196 result = true; 197 for (int index : gsg.getIndexes()) { 198 // First index column cannot be moved before 199 if (index == 0) { 200 result = false; 201 break; 202 } 203 } 204 } else if (position == Position.AFTER) { 205 result = true; 206 for (int index : gsg.getIndexes()) { 207 // Last index column cannot be moved after 208 if (index == (mask.getColumnsSize() - 1)) { 209 result = false; 210 break; 211 } 212 } 213 } else { 214 result = false; 215 } 216 break; 217 case ROW: 218 if (position == Position.ABOVE) { 219 result = true; 220 for (int index : gsg.getIndexes()) { 221 // First index row cannot be moved above 222 if (index == 0) { 223 result = false; 224 break; 225 } 226 } 227 } else if (position == Position.BELOW) { 228 result = true; 229 for (int index : gsg.getIndexes()) { 230 // Last index row cannot be moved below 231 if (index == (mask.getRowsSize() - 1)) { 232 result = false; 233 break; 234 } 235 } 236 } else { 237 result = false; 238 } 239 break; 240 default: 241 result = false; 242 assert false; 243 } 244 } else { 245 result = false; 246 } 247 return result; 248 } 249 }