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.tring;
  33 
  34 import com.oracle.javafx.scenebuilder.kit.editor.panel.content.ContentPanelController;
  35 import com.oracle.javafx.scenebuilder.kit.fxom.FXOMInstance;
  36 import com.oracle.javafx.scenebuilder.kit.metadata.util.DesignHierarchyMask;
  37 import com.oracle.javafx.scenebuilder.kit.metadata.util.DesignHierarchyMask.Accessory;
  38 import java.util.List;
  39 import javafx.geometry.BoundingBox;
  40 import javafx.geometry.Bounds;
  41 import javafx.scene.control.Label;
  42 import javafx.scene.layout.BorderPane;
  43 
  44 /**
  45  *
  46  *
  47  */
  48 public class BorderPaneTring extends AbstractNodeTring<BorderPane> {
  49 
  50     private final Accessory targetAccessory;
  51     private final BorderPane borderPane = new BorderPane();
  52     private final Label topLabel = new Label();
  53     private final Label bottomLabel = new Label();
  54     private final Label leftLabel = new Label();
  55     private final Label rightLabel = new Label();
  56     private final Label centerLabel = new Label();
  57 
  58 
  59     public BorderPaneTring(ContentPanelController contentPanelController,
  60             FXOMInstance fxomInstance, DesignHierarchyMask.Accessory targetAccessory) {
  61         super(contentPanelController, fxomInstance, BorderPane.class);
  62         assert (targetAccessory == Accessory.TOP)
  63                 || (targetAccessory == Accessory.BOTTOM)
  64                 || (targetAccessory == Accessory.LEFT)
  65                 || (targetAccessory == Accessory.RIGHT)
  66                 || (targetAccessory == Accessory.CENTER);
  67 
  68         this.targetAccessory = targetAccessory;
  69 
  70         topLabel.setMinSize(Label.USE_PREF_SIZE, Label.USE_PREF_SIZE);
  71         topLabel.setMaxSize(Label.USE_PREF_SIZE, Label.USE_PREF_SIZE);
  72         bottomLabel.setMinSize(Label.USE_PREF_SIZE, Label.USE_PREF_SIZE);
  73         bottomLabel.setMaxSize(Label.USE_PREF_SIZE, Label.USE_PREF_SIZE);
  74         leftLabel.setMinSize(Label.USE_PREF_SIZE, Label.USE_PREF_SIZE);
  75         leftLabel.setMaxSize(Label.USE_PREF_SIZE, Label.USE_PREF_SIZE);
  76         rightLabel.setMinSize(Label.USE_PREF_SIZE, Label.USE_PREF_SIZE);
  77         rightLabel.setMaxSize(Label.USE_PREF_SIZE, Label.USE_PREF_SIZE);
  78         centerLabel.setMinSize(Label.USE_PREF_SIZE, Label.USE_PREF_SIZE);
  79         centerLabel.setMaxSize(Label.USE_PREF_SIZE, Label.USE_PREF_SIZE);
  80 
  81         topLabel.setText(Accessory.TOP.toString());
  82         bottomLabel.setText(Accessory.BOTTOM.toString());
  83         leftLabel.setText(Accessory.LEFT.toString());
  84         rightLabel.setText(Accessory.RIGHT.toString());
  85         centerLabel.setText(Accessory.CENTER.toString());
  86 
  87         topLabel.getStyleClass().add(TARGET_RING_CLASS);
  88         topLabel.getStyleClass().add(BorderPane.class.getSimpleName());
  89         bottomLabel.getStyleClass().add(TARGET_RING_CLASS);
  90         bottomLabel.getStyleClass().add(BorderPane.class.getSimpleName());
  91         leftLabel.getStyleClass().add(TARGET_RING_CLASS);
  92         leftLabel.getStyleClass().add(BorderPane.class.getSimpleName());
  93         rightLabel.getStyleClass().add(TARGET_RING_CLASS);
  94         rightLabel.getStyleClass().add(BorderPane.class.getSimpleName());
  95         centerLabel.getStyleClass().add(TARGET_RING_CLASS);
  96         centerLabel.getStyleClass().add(BorderPane.class.getSimpleName());
  97 
  98         final DesignHierarchyMask m = new DesignHierarchyMask(fxomInstance);
  99         topLabel.setVisible(m.getAccessory(DesignHierarchyMask.Accessory.TOP) == null);
 100         bottomLabel.setVisible(m.getAccessory(DesignHierarchyMask.Accessory.BOTTOM) == null);
 101         leftLabel.setVisible(m.getAccessory(DesignHierarchyMask.Accessory.LEFT) == null);
 102         rightLabel.setVisible(m.getAccessory(DesignHierarchyMask.Accessory.RIGHT) == null);
 103         centerLabel.setVisible(m.getAccessory(DesignHierarchyMask.Accessory.CENTER) == null);
 104 
 105         borderPane.setTop(topLabel);
 106         borderPane.setBottom(bottomLabel);
 107         borderPane.setLeft(leftLabel);
 108         borderPane.setRight(rightLabel);
 109         borderPane.setCenter(centerLabel);
 110         borderPane.setMinWidth(BorderPane.USE_PREF_SIZE);
 111         borderPane.setMinHeight(BorderPane.USE_PREF_SIZE);
 112         borderPane.setMaxWidth(BorderPane.USE_PREF_SIZE);
 113         borderPane.setMaxHeight(BorderPane.USE_PREF_SIZE);
 114 
 115         getRootNode().getChildren().add(0, borderPane);
 116     }
 117 
 118 
 119     public static Bounds computeCenterBounds(BorderPane sceneGraphObject) {
 120         final Bounds b = sceneGraphObject.getLayoutBounds();
 121 
 122         final double x0 = b.getMinX();
 123         final double x3 = b.getMaxX();
 124         final double x1 = x0 + (x3 - x0) * 0.25;
 125         final double x2 = x0 + (x3 - x0) * 0.75;
 126 
 127         final double y0 = b.getMinY();
 128         final double y3 = b.getMaxY();
 129         final double y1 = y0 + (y3 - y0) * 0.25;
 130         final double y2 = y0 + (y3 - y0) * 0.75;
 131 
 132         return new BoundingBox(x1, y1, x2 - x1, y2 - y1);
 133     }
 134 
 135 
 136 
 137     public static Bounds computeAreaBounds(Bounds lb, Bounds cb, Accessory area) {
 138         assert lb != null;
 139         assert cb != null;
 140 
 141         /*
 142          *      lb.minx                                    lb.maxx
 143          *              cb.minx                   cb.maxx
 144          *  lb.miny o----------------------------------------o
 145          *          |                  Top                   |
 146          *  cb.miny o-----o-------------------------o--------o
 147          *          |     |                         |        |
 148          *          |     |                         |        |
 149          *          |     |                         |        |
 150          *          |Left |           Center        |  Right |
 151          *          |     |                         |        |
 152          *          |     |                         |        |
 153          *          |     |                         |        |
 154          *  cb.maxy o-----o-------------------------o--------o
 155          *          |                                        |
 156          *          |                 Bottom                 |
 157          *          |                                        |
 158          *  lb.maxy o----------------------------------------o
 159          *
 160          */
 161 
 162         final double xmin, ymin, xmax, ymax;
 163         switch(area) {
 164             case TOP:
 165                 xmin = lb.getMinX();
 166                 ymin = lb.getMinY();
 167                 xmax = lb.getMaxX();
 168                 ymax = cb.getMinY();
 169                 break;
 170             case BOTTOM:
 171                 xmin = lb.getMinX();
 172                 ymin = cb.getMaxY();
 173                 xmax = lb.getMaxX();
 174                 ymax = lb.getMaxY();
 175                 break;
 176             case LEFT:
 177                 xmin = lb.getMinX();
 178                 ymin = cb.getMinY();
 179                 xmax = cb.getMinX();
 180                 ymax = cb.getMaxY();
 181                 break;
 182             case RIGHT:
 183                 xmin = cb.getMaxX();
 184                 ymin = cb.getMinY();
 185                 xmax = lb.getMaxX();
 186                 ymax = cb.getMaxY();
 187                 break;
 188             case CENTER:
 189                 xmin = cb.getMinX();
 190                 ymin = cb.getMinY();
 191                 xmax = cb.getMaxX();
 192                 ymax = cb.getMaxY();
 193                 break;
 194             default:
 195                 // Emergency code
 196                 assert false : "Unexpected area " + area; //NOI18N
 197                 xmin = cb.getMinX();
 198                 ymin = cb.getMinY();
 199                 xmax = cb.getMaxX();
 200                 ymax = cb.getMaxY();
 201                 break;
 202         }
 203 
 204         return new BoundingBox(xmin, ymin, xmax - xmin, ymax - ymin);
 205     }
 206 
 207 
 208     /*
 209      * AbstractGenericTring
 210      */
 211 
 212     @Override
 213     protected void layoutDecoration() {
 214 
 215         super.layoutDecoration();
 216 
 217         final Bounds layoutBounds = getSceneGraphObject().getLayoutBounds();
 218         borderPane.setPrefWidth(layoutBounds.getWidth());
 219         borderPane.setPrefHeight(layoutBounds.getHeight());
 220 
 221 
 222         final Bounds centerBounds = computeCenterBounds(getSceneGraphObject());
 223         centerLabel.setPrefSize(centerBounds.getWidth(), centerBounds.getHeight());
 224 
 225         final Bounds topBounds = computeAreaBounds(layoutBounds, centerBounds, Accessory.TOP);
 226         topLabel.setPrefSize(topBounds.getWidth(), topBounds.getHeight());
 227 
 228         final Bounds bottomBounds = computeAreaBounds(layoutBounds, centerBounds, Accessory.BOTTOM);
 229         bottomLabel.setPrefSize(bottomBounds.getWidth(), bottomBounds.getHeight());
 230 
 231         final Bounds leftBounds = computeAreaBounds(layoutBounds, centerBounds, Accessory.LEFT);
 232         leftLabel.setPrefSize(leftBounds.getWidth(), leftBounds.getHeight());
 233 
 234         final Bounds rightBounds = computeAreaBounds(layoutBounds, centerBounds, Accessory.RIGHT);
 235         rightLabel.setPrefSize(rightBounds.getWidth(), rightBounds.getHeight());
 236 
 237         final Label targetLabel;
 238         switch(targetAccessory) {
 239             case TOP:
 240                 targetLabel = topLabel;
 241                 break;
 242             case BOTTOM:
 243                 targetLabel = bottomLabel;
 244                 break;
 245             case LEFT:
 246                 targetLabel = leftLabel;
 247                 break;
 248             case RIGHT:
 249                 targetLabel = rightLabel;
 250                 break;
 251             case CENTER:
 252                 targetLabel = centerLabel;
 253                 break;
 254             default:
 255                 // Emergency code
 256                 assert false;
 257                 targetLabel = centerLabel;
 258                 break;
 259         }
 260 
 261         setupSelectedStyleClass(topLabel, topLabel == targetLabel);
 262         setupSelectedStyleClass(bottomLabel, bottomLabel == targetLabel);
 263         setupSelectedStyleClass(leftLabel, leftLabel == targetLabel);
 264         setupSelectedStyleClass(rightLabel, rightLabel == targetLabel);
 265         setupSelectedStyleClass(centerLabel, centerLabel == targetLabel);
 266 
 267 
 268         // Update (decoration) border pane transform
 269         borderPane.getTransforms().clear();
 270         borderPane.getTransforms().add(getSceneGraphObjectToDecorationTransform());
 271     }
 272 
 273 
 274 
 275     /*
 276      * Private
 277      */
 278 
 279     private static final String SELECTED = "selected"; //NOI18N
 280 
 281     private static void setupSelectedStyleClass(Label label, boolean selected) {
 282             final List<String> styleClass = label.getStyleClass();
 283         if (selected) {
 284             if (styleClass.contains(SELECTED) == false) {
 285                     styleClass.add(SELECTED);
 286             }
 287         } else {
 288             if (styleClass.contains(SELECTED)) {
 289                 styleClass.remove(SELECTED);
 290             }
 291         }
 292     }
 293 }