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.handles;
  33 
  34 import java.util.List;
  35 
  36 import javafx.geometry.Point2D;
  37 import javafx.scene.Cursor;
  38 import javafx.scene.Node;
  39 import javafx.scene.shape.Circle;
  40 import javafx.scene.shape.Line;
  41 
  42 import com.oracle.javafx.scenebuilder.kit.editor.panel.content.ContentPanelController;
  43 import com.oracle.javafx.scenebuilder.kit.editor.panel.content.gesture.AbstractGesture;
  44 import com.oracle.javafx.scenebuilder.kit.editor.panel.content.gesture.mouse.EditCurveGesture;
  45 import com.oracle.javafx.scenebuilder.kit.fxom.FXOMInstance;
  46 
  47 /**
  48  *
  49  *
  50  */
  51 public class LineHandles extends AbstractCurveHandles<Line> {
  52 
  53     private final Circle startHandle = new Circle(SELECTION_HANDLES_SIZE / 2.0);
  54     private final Circle endHandle = new Circle(SELECTION_HANDLES_SIZE / 2.0);
  55 
  56 
  57     public LineHandles(ContentPanelController contentPanelController,
  58             FXOMInstance fxomInstance) {
  59         super(contentPanelController, fxomInstance, Line.class);
  60 
  61         setupHandleState(startHandle);
  62         setupHandleState(endHandle);
  63 
  64         setupHandles(startHandle);
  65         setupHandles(endHandle);
  66 
  67         final List<Node> rootNodeChildren = getRootNode().getChildren();
  68         rootNodeChildren.add(startHandle);
  69         rootNodeChildren.add(endHandle);
  70     }
  71 
  72     public FXOMInstance getFxomInstance() {
  73         return (FXOMInstance) getFxomObject();
  74     }
  75 
  76     /*
  77      * AbstractCurveHandles
  78      */
  79     @Override
  80     protected void layoutDecoration() {
  81         final Line l = getSceneGraphObject();
  82 
  83         final boolean snapToPixel = true;
  84         final Point2D s = sceneGraphObjectToDecoration(l.getStartX(), l.getStartY(), snapToPixel);
  85         final Point2D e = sceneGraphObjectToDecoration(l.getEndX(), l.getEndY(), snapToPixel);
  86 
  87         startHandle.setCenterX(s.getX());
  88         startHandle.setCenterY(s.getY());
  89         endHandle.setCenterX(e.getX());
  90         endHandle.setCenterY(e.getY());
  91     }
  92 
  93     @Override
  94     protected void startListeningToSceneGraphObject() {
  95         super.startListeningToSceneGraphObject();
  96 
  97         final Line l = getSceneGraphObject();
  98         l.startXProperty().addListener(coordinateListener);
  99         l.startYProperty().addListener(coordinateListener);
 100         l.endXProperty().addListener(coordinateListener);
 101         l.endYProperty().addListener(coordinateListener);
 102     }
 103 
 104     @Override
 105     protected void stopListeningToSceneGraphObject() {
 106         super.stopListeningToSceneGraphObject();
 107 
 108         final Line l = getSceneGraphObject();
 109         l.startXProperty().removeListener(coordinateListener);
 110         l.startYProperty().removeListener(coordinateListener);
 111         l.endXProperty().removeListener(coordinateListener);
 112         l.endYProperty().removeListener(coordinateListener);
 113     }
 114 
 115     @Override
 116     public AbstractGesture findGesture(Node node) {
 117         final AbstractGesture result;
 118 
 119         if (node == startHandle) {
 120             result = new EditCurveGesture(getContentPanelController(),
 121                     EditCurveGesture.Tunable.START);
 122         } else if (node == endHandle) {
 123             result = new EditCurveGesture(getContentPanelController(),
 124                     EditCurveGesture.Tunable.END);
 125         } else {
 126             result = null;
 127         }
 128 
 129         return result;
 130     }
 131 
 132     @Override
 133     public void enabledDidChange() {
 134         setupHandleState(startHandle);
 135         setupHandleState(endHandle);
 136     }
 137 
 138     /*
 139      * Private
 140      */
 141 
 142     private void setupHandleState(Circle handleCircle) {
 143 
 144         final String styleClass = isEnabled() ? SELECTION_HANDLES : SELECTION_HANDLES_DIM;
 145         final Cursor cursor = isEnabled() ? Cursor.CROSSHAIR : Cursor.DEFAULT;
 146 
 147         handleCircle.getStyleClass().add(styleClass);
 148         handleCircle.setCursor(cursor);
 149     }
 150 
 151 
 152     /*
 153      * Wraper to avoid the 'leaking this in constructor' warning emitted by NB.
 154      */
 155     private void setupHandles(Node node) {
 156         attachHandles(node, this);
 157     }
 158 }