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 33 package com.oracle.javafx.scenebuilder.kit.editor.panel.content.gesture.mouse; 34 35 import com.oracle.javafx.scenebuilder.kit.editor.EditorController; 36 import com.oracle.javafx.scenebuilder.kit.editor.i18n.I18N; 37 import com.oracle.javafx.scenebuilder.kit.editor.job.BatchJob; 38 import com.oracle.javafx.scenebuilder.kit.editor.job.Job; 39 import com.oracle.javafx.scenebuilder.kit.editor.job.atomic.ModifyObjectJob; 40 import com.oracle.javafx.scenebuilder.kit.editor.panel.content.ContentPanelController; 41 import com.oracle.javafx.scenebuilder.kit.editor.panel.content.driver.resizer.TableColumnResizer; 42 import com.oracle.javafx.scenebuilder.kit.fxom.FXOMInstance; 43 import com.oracle.javafx.scenebuilder.kit.fxom.FXOMObject; 44 import com.oracle.javafx.scenebuilder.kit.metadata.Metadata; 45 import com.oracle.javafx.scenebuilder.kit.metadata.property.ValuePropertyMetadata; 46 import com.oracle.javafx.scenebuilder.kit.metadata.util.PropertyName; 47 import java.util.ArrayList; 48 import java.util.HashMap; 49 import java.util.List; 50 import java.util.Map; 51 import javafx.geometry.Point2D; 52 import javafx.scene.control.TableColumn; 53 import javafx.scene.control.TableView; 54 import javafx.scene.input.KeyEvent; 55 56 /** 57 * 58 */ 59 public class ResizeTableColumnGesture extends AbstractMouseGesture { 60 61 private final FXOMInstance columnInstance; 62 private TableColumnResizer resizer; 63 64 65 public ResizeTableColumnGesture(ContentPanelController contentPanelController, 66 FXOMInstance fxomInstance) { 67 super(contentPanelController); 68 69 assert fxomInstance != null; 70 assert fxomInstance.getSceneGraphObject() instanceof TableColumn; 71 72 this.columnInstance = fxomInstance; 73 } 74 75 /* 76 * AbstractMouseGesture 77 */ 78 79 @Override 80 protected void mousePressed() { 81 // Everthing is done in mouseDragStarted 82 } 83 84 @Override 85 protected void mouseDragStarted() { 86 assert resizer == null; 87 assert columnInstance.getSceneGraphObject() instanceof TableColumn; 88 89 resizer = new TableColumnResizer((TableColumn<?,?>)columnInstance.getSceneGraphObject()); 90 91 // Now same as mouseDragged 92 mouseDragged(); 93 } 94 95 @Override 96 protected void mouseDragged() { 97 assert resizer != null; 98 99 final double startSceneX = getMousePressedEvent().getSceneX(); 100 final double startSceneY = getMousePressedEvent().getSceneY(); 101 final double currentSceneX = getLastMouseEvent().getSceneX(); 102 final double currentSceneY = getLastMouseEvent().getSceneY(); 103 final TableView<?> tableView = resizer.getTableColumn().getTableView(); 104 final Point2D start = tableView.sceneToLocal(startSceneX, startSceneY, true /* rootScene */); 105 final Point2D current = tableView.sceneToLocal(currentSceneX, currentSceneY, true /* rootScene */); 106 final double dx = current.getX() - start.getX(); 107 108 resizer.updateWidth(dx); 109 tableView.layout(); 110 } 111 112 @Override 113 protected void mouseDragEnded() { 114 assert resizer != null; 115 116 /* 117 * Three steps 118 * 119 * 1) Collects sizing properties that have changed 120 * 2) Reverts to initial sizing 121 * => this step is equivalent to userDidCancel() 122 * 3) Push a BatchModifyObjectJob to officially resize the columns 123 */ 124 125 // Step #1 126 final Map<PropertyName, Object> changeMap = resizer.getChangeMap(); 127 final Map<PropertyName, Object> changeMapNext = resizer.getChangeMapNext(); 128 129 130 // Step #2 131 userDidCancel(); 132 133 // Step #3 134 final EditorController editorController 135 = contentPanelController.getEditorController(); 136 final BatchJob batchJob 137 = new BatchJob(editorController, true, 138 I18N.getString("label.action.edit.resize.column")); 139 if (changeMap.isEmpty() == false) { 140 batchJob.addSubJobs(makeResizeJob(columnInstance, changeMap)); 141 } 142 if (changeMapNext.isEmpty() == false) { 143 batchJob.addSubJobs(makeResizeJob(columnInstance.getNextSlibing(), changeMapNext)); 144 } 145 if (batchJob.isExecutable()) { 146 editorController.getJobManager().push(batchJob); 147 } 148 149 resizer = null; // For sake of symetry... 150 } 151 152 @Override 153 protected void mouseReleased() { 154 // Everything is done in mouseDragEnded 155 } 156 157 @Override 158 protected void keyEvent(KeyEvent e) { 159 // Nothing special here 160 } 161 162 @Override 163 protected void userDidCancel() { 164 resizer.revertToOriginalSize(); 165 resizer.getTableColumn().getTableView().layout(); 166 } 167 168 169 /* 170 * Private 171 */ 172 173 private List<Job> makeResizeJob(FXOMObject columnObject, Map<PropertyName, Object> changeMap) { 174 assert columnObject.getSceneGraphObject() instanceof TableColumn; 175 assert columnObject instanceof FXOMInstance; 176 177 final List<Job> result = new ArrayList<>(); 178 179 final Metadata metadata = Metadata.getMetadata(); 180 final Map<ValuePropertyMetadata, Object> metaValueMap = new HashMap<>(); 181 for (Map.Entry<PropertyName,Object> e : changeMap.entrySet()) { 182 final ValuePropertyMetadata vpm = metadata.queryValueProperty(columnInstance, e.getKey()); 183 assert vpm != null; 184 metaValueMap.put(vpm, e.getValue()); 185 } 186 187 for (Map.Entry<ValuePropertyMetadata, Object> e : metaValueMap.entrySet()) { 188 final ModifyObjectJob job = new ModifyObjectJob( 189 (FXOMInstance) columnObject, 190 e.getKey(), 191 e.getValue(), 192 contentPanelController.getEditorController()); 193 result.add(job); 194 } 195 return result; 196 } 197 }