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.panel.content.driver.gridpane; 33 34 import com.oracle.javafx.scenebuilder.kit.editor.panel.content.ContentPanelController; 35 import com.oracle.javafx.scenebuilder.kit.editor.panel.content.driver.handles.AbstractHandles; 36 import com.oracle.javafx.scenebuilder.kit.editor.panel.content.driver.handles.AbstractNodeHandles; 37 import com.oracle.javafx.scenebuilder.kit.editor.panel.content.gesture.AbstractGesture; 38 import com.oracle.javafx.scenebuilder.kit.editor.panel.content.gesture.mouse.ResizeColumnGesture; 39 import com.oracle.javafx.scenebuilder.kit.editor.panel.content.gesture.mouse.ResizeRowGesture; 40 import com.oracle.javafx.scenebuilder.kit.editor.panel.content.gesture.mouse.SelectAndMoveInGridGesture; 41 import com.oracle.javafx.scenebuilder.kit.editor.selection.GridSelectionGroup; 42 import com.oracle.javafx.scenebuilder.kit.fxom.FXOMInstance; 43 import java.util.Collections; 44 import javafx.scene.Node; 45 import javafx.scene.layout.GridPane; 46 47 /** 48 * 49 */ 50 public class GridPaneHandles extends AbstractNodeHandles<GridPane> { 51 52 private final GridPaneMosaic mosaic 53 = new GridPaneMosaic("handles", //NOI18N 54 true /* shouldShowTray */, 55 true /* shouldCreateSensors */ ); 56 57 public GridPaneHandles(ContentPanelController contentPanelController, 58 FXOMInstance fxomInstance) { 59 super(contentPanelController, fxomInstance, GridPane.class); 60 61 getRootNode().getChildren().add(0, mosaic.getTopGroup()); // Below handles 62 } 63 64 public void updateColumnRowSelection(GridSelectionGroup gsg) { 65 66 if (gsg == null) { 67 mosaic.setSelectedColumnIndexes(Collections.emptySet()); 68 mosaic.setSelectedRowIndexes(Collections.emptySet()); 69 } else { 70 switch(gsg.getType()) { 71 case COLUMN: 72 mosaic.setSelectedColumnIndexes(gsg.getIndexes()); 73 mosaic.setSelectedRowIndexes(Collections.emptySet()); 74 break; 75 case ROW: 76 mosaic.setSelectedColumnIndexes(Collections.emptySet()); 77 mosaic.setSelectedRowIndexes(gsg.getIndexes()); 78 break; 79 default: 80 assert false; 81 break; 82 } 83 } 84 } 85 86 87 /* 88 * AbstractNodeHandles 89 */ 90 @Override 91 public void layoutDecoration() { 92 super.layoutDecoration(); 93 94 if (mosaic.getGridPane() != getSceneGraphObject()) { 95 mosaic.setGridPane(getSceneGraphObject()); 96 } else { 97 mosaic.update(); 98 } 99 100 // Mosaic update may have created new trays and new sensors. 101 // Attach this handles to them. 102 for (Node node : this.mosaic.getNorthTrayNodes()) { 103 attachHandles(node); 104 } 105 for (Node node : this.mosaic.getSouthTrayNodes()) { 106 attachHandles(node); 107 } 108 for (Node node : this.mosaic.getEastTrayNodes()) { 109 attachHandles(node); 110 } 111 for (Node node : this.mosaic.getWestTrayNodes()) { 112 attachHandles(node); 113 } 114 for (Node node : this.mosaic.getHgapSensorNodes()) { 115 attachHandles(node); 116 } 117 for (Node node : this.mosaic.getVgapSensorNodes()) { 118 attachHandles(node); 119 } 120 121 // Update mosaic transform 122 mosaic.getTopGroup().getTransforms().clear(); 123 mosaic.getTopGroup().getTransforms().add(getSceneGraphObjectToDecorationTransform()); 124 } 125 126 @Override 127 public AbstractGesture findGesture(Node node) { 128 AbstractGesture result = findGestureInTrays(node); 129 if (result == null) { 130 result = findGestureInSensors(node); 131 } 132 133 return result; 134 } 135 136 137 private AbstractGesture findGestureInTrays(Node node) { 138 final GridSelectionGroup.Type feature; 139 140 int trayIndex = mosaic.getNorthTrayNodes().indexOf(node); 141 if (trayIndex != -1) { 142 feature = GridSelectionGroup.Type.COLUMN; 143 } else { 144 trayIndex = mosaic.getSouthTrayNodes().indexOf(node); 145 if (trayIndex != -1) { 146 feature = GridSelectionGroup.Type.COLUMN; 147 } else { 148 trayIndex = mosaic.getWestTrayNodes().indexOf(node); 149 if (trayIndex != -1) { 150 feature = GridSelectionGroup.Type.ROW; 151 } else { 152 trayIndex = mosaic.getEastTrayNodes().indexOf(node); 153 feature = GridSelectionGroup.Type.ROW; 154 } 155 } 156 } 157 158 final AbstractGesture result; 159 if (trayIndex == -1) { 160 result = super.findGesture(node); 161 } else { 162 result = new SelectAndMoveInGridGesture(getContentPanelController(), 163 getFxomInstance(), feature, trayIndex); 164 } 165 166 return result; 167 } 168 169 170 private AbstractGesture findGestureInSensors(Node node) { 171 final AbstractGesture result; 172 173 int sensorIndex = mosaic.getHgapSensorNodes().indexOf(node); 174 if (sensorIndex != -1) { 175 result = new ResizeColumnGesture(this, sensorIndex); 176 } else { 177 sensorIndex = mosaic.getVgapSensorNodes().indexOf(node); 178 if (sensorIndex != -1) { 179 result = new ResizeRowGesture(this, sensorIndex); 180 } else { 181 result = super.findGesture(node); 182 } 183 } 184 185 return result; 186 } 187 188 189 /* 190 * Private 191 */ 192 193 /* 194 * Wrapper to avoid the 'leaking this in constructor' warning emitted by NB. 195 */ 196 private void attachHandles(Node node) { 197 if (AbstractHandles.lookupHandles(node) == null) { 198 attachHandles(node, this); 199 } 200 } 201 }