1 /*
   2  * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package test.javafx.scene;
  27 
  28 import javafx.css.converter.PaintConverter;
  29 import javafx.css.converter.SizeConverter;
  30 import com.sun.javafx.geom.BaseBounds;
  31 import com.sun.javafx.geom.transform.BaseTransform;
  32 import com.sun.javafx.jmx.MXNodeAlgorithm;
  33 import com.sun.javafx.jmx.MXNodeAlgorithmContext;
  34 import com.sun.javafx.sg.prism.NGGroup;
  35 import com.sun.javafx.sg.prism.NGNode;
  36 import javafx.beans.property.*;
  37 import javafx.css.*;
  38 import javafx.scene.paint.Color;
  39 import javafx.scene.paint.Paint;
  40 
  41 import java.util.ArrayList;
  42 import java.util.List;
  43 import javafx.scene.Node;
  44 import test.com.sun.javafx.scene.CSSNodeHelper;
  45 
  46 public  class CSSNode extends Node {
  47     static {
  48         CSSNodeHelper.setCSSNodeAccessor(new CSSNodeHelper.CSSNodeAccessor() {
  49             @Override
  50             public NGNode doCreatePeer(Node node) {
  51                 return ((CSSNode) node).doCreatePeer();
  52             }
  53         });
  54     }
  55 
  56     {
  57         // To initialize the class helper at the begining each constructor of this class
  58         CSSNodeHelper.initHelper(this);
  59     }
  60 
  61     public CSSNode() {
  62         setContentSize(100);
  63     }
  64 
  65     /**
  66      * This variable can be set from CSS and represents the fill
  67      */
  68     private ObjectProperty<Paint> fill;
  69     public ObjectProperty<Paint> fillProperty() {
  70         if (fill == null) {
  71             fill = new StyleableObjectProperty<Paint>(Color.BLACK) {
  72 
  73                 @Override
  74                 public Object getBean() {
  75                     return CSSNode.this;
  76                 }
  77 
  78                 @Override
  79                 public String getName() {
  80                     return "fill";
  81                 }
  82 
  83                 @Override
  84                 public CssMetaData getCssMetaData() {
  85                     return StyleableProperties.FILL;
  86                 }
  87 
  88             };
  89         }
  90         return fill;
  91     }
  92     public void setFill(Paint paint) {
  93         fillProperty().set(paint);
  94     }
  95     public Paint getFill() {
  96         return (fill == null ? Color.BLACK : fill.get());
  97     }
  98 
  99     /**
 100      * This variable can be set from CSS and represents the stroke fill
 101      */
 102     private ObjectProperty<Paint> stroke;
 103     public ObjectProperty<Paint> strokeProperty() {
 104         if (stroke == null) {
 105             stroke = new StyleableObjectProperty<Paint>(Color.BLACK) {
 106 
 107                 @Override
 108                 public Object getBean() {
 109                     return CSSNode.this;
 110                 }
 111 
 112                 @Override
 113                 public String getName() {
 114                     return "stroke";
 115                 }
 116 
 117                 @Override
 118                 public CssMetaData getCssMetaData() {
 119                     return StyleableProperties.STROKE;
 120                 }
 121 
 122             };
 123         }
 124         return stroke;
 125     }
 126     public void setStroke(Paint paint) {
 127         strokeProperty().set(paint);
 128     }
 129     public Paint getStroke() {
 130         return (stroke == null ? Color.BLACK : stroke.get());
 131     }
 132 
 133     /**
 134      * This variable can be set from CSS and is a simple number. For testing,
 135      * this can be font-based, absolute, or percentage based. The CSSNode has
 136      * a contentSize:Number variable which is used when padding is based on
 137      * a percentage
 138      */
 139     private FloatProperty padding;
 140 
 141     public final void setPadding(float value) {
 142         paddingProperty().set(value);
 143     }
 144 
 145     public final float getPadding() {
 146         return padding == null ? 0.0F : padding.get();
 147     }
 148 
 149     public FloatProperty paddingProperty() {
 150         if (padding == null) {
 151             padding = new StyleableFloatProperty() {
 152 
 153                 @Override
 154                 protected void invalidated() {
 155                     impl_geomChanged();
 156                 }
 157 
 158                 @Override
 159                 public Object getBean() {
 160                     return CSSNode.this;
 161                 }
 162 
 163                 @Override
 164                 public String getName() {
 165                     return "padding";
 166                 }
 167 
 168                 @Override
 169                 public CssMetaData getCssMetaData() {
 170                     return StyleableProperties.PADDING;
 171                 }
 172             };
 173         }
 174         return padding;
 175     }
 176 
 177     /**
 178      * Used only when padding is specified as a percentage, as it is a
 179      * percentage of the content size.
 180      */
 181     private FloatProperty contentSize;
 182 
 183     public final void setContentSize(float value) {
 184         contentSizeProperty().set(value);
 185     }
 186 
 187     public final float getContentSize() {
 188         return contentSize == null ? 0.0F : contentSize.get();
 189     }
 190 
 191     public FloatProperty contentSizeProperty() {
 192         if (contentSize == null) {
 193             contentSize = new SimpleFloatProperty() {
 194 
 195                 @Override
 196                 protected void invalidated() {
 197                     impl_geomChanged();
 198                 }
 199             };
 200         }
 201         return contentSize;
 202     }
 203 
 204     /**
 205      * A pseudoclass state for this Node. It cannot be styled, but can
 206      * be used as a pseudoclass
 207      */
 208     private PseudoClass SPECIAL_PSEUDO_CLASS = PseudoClass.getPseudoClass("special");
 209     private BooleanProperty special;
 210     public final void setSpecial(boolean value) {
 211         specialProperty().set(value);
 212     }
 213 
 214     public final boolean isSpecial() {
 215         return special == null ? false : special.get();
 216     }
 217 
 218     public BooleanProperty specialProperty() {
 219         if (special == null) {
 220             special = new SimpleBooleanProperty() {
 221 
 222                 @Override
 223                 protected void invalidated() {
 224                     pseudoClassStateChanged(SPECIAL_PSEUDO_CLASS, get());
 225                 }
 226             };
 227         }
 228         return special;
 229     }
 230 
 231     /*
 232      * These vars are used solely for the sake of testing.
 233      */
 234 
 235     public boolean reapply = false;
 236     public boolean processCalled = false;
 237     public boolean applyCalled = false;
 238 
 239     @Override
 240     public BaseBounds impl_computeGeomBounds(BaseBounds bounds, BaseTransform tx) {
 241         if (bounds != null) {
 242             bounds = bounds.deriveWithNewBounds(0, 0, 0,
 243                     getContentSize() + getPadding() + getPadding(), getContentSize() + getPadding() + getPadding(), 0);
 244         }
 245         return bounds;
 246     }
 247 
 248     @Override
 249     protected boolean impl_computeContains(double localX, double localY) {
 250         // TODO: Missing code.
 251         return false;
 252     }
 253 
 254     private NGNode doCreatePeer() {
 255         return new NGGroup();
 256     }
 257 
 258     public static class StyleableProperties {
 259 
 260         public static final CssMetaData<CSSNode,Paint> FILL =
 261             new CssMetaData<CSSNode,Paint>("fill", PaintConverter.getInstance()) {
 262 
 263             @Override
 264             public boolean isSettable(CSSNode n) {
 265                 return n.fill == null || !n.fill.isBound();
 266             }
 267 
 268             @Override
 269             public StyleableProperty<Paint> getStyleableProperty(CSSNode n) {
 270                 return (StyleableProperty<Paint>)n.fillProperty();
 271             }
 272         };
 273 
 274         public static final CssMetaData<CSSNode,Paint> STROKE =
 275             new CssMetaData<CSSNode,Paint>("stroke", PaintConverter.getInstance()) {
 276 
 277             @Override
 278             public boolean isSettable(CSSNode n) {
 279                 return n.stroke == null || !n.stroke.isBound();
 280             }
 281 
 282             @Override
 283             public StyleableProperty<Paint> getStyleableProperty(CSSNode n) {
 284                 return (StyleableProperty<Paint>)n.strokeProperty();
 285             }
 286         };
 287 
 288         public static final CssMetaData<CSSNode,Number> PADDING =
 289             new CssMetaData<CSSNode,Number>("padding", SizeConverter.getInstance()) {
 290 
 291             @Override
 292             public boolean isSettable(CSSNode n) {
 293                 return n.padding == null || !n.padding.isBound();
 294             }
 295 
 296             @Override
 297             public StyleableProperty<Number> getStyleableProperty(CSSNode n) {
 298                 return (StyleableProperty<Number>)n.paddingProperty();
 299             }
 300         };
 301 
 302         private static List<CssMetaData<? extends Styleable, ?>> STYLEABLES;
 303         static {
 304             final List<CssMetaData<? extends Styleable, ?>> styleables =
 305                 new ArrayList<CssMetaData<? extends Styleable, ?>>(Node.getClassCssMetaData());
 306             styleables.add(FILL);
 307             styleables.add(STROKE);
 308             styleables.add(PADDING);
 309 
 310         }
 311 
 312     }
 313 
 314     /**
 315      * @return The CssMetaData associated with this class, which may include the
 316      * CssMetaData of its super classes.
 317      */
 318     public static List<CssMetaData<? extends Styleable, ?>> getClassCssMetaData() {
 319         return StyleableProperties.STYLEABLES;
 320     }
 321 
 322     /**
 323      * {@inheritDoc}
 324      *
 325      */
 326 
 327 
 328     @Override
 329     public List<CssMetaData<? extends Styleable, ?>> getCssMetaData() {
 330         return getClassCssMetaData();
 331     }
 332 
 333     /**
 334      * @treatAsPrivate Implementation detail
 335      */
 336     @Override
 337     public Object impl_processMXNode(MXNodeAlgorithm alg, MXNodeAlgorithmContext ctx) {
 338         return null;
 339     }
 340 }