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 }