1 /* 2 * Copyright (c) 2011, 2013, 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 javafx.scene; 27 28 import com.sun.javafx.css.converters.PaintConverter; 29 import com.sun.javafx.css.converters.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 44 public class CSSNode extends Node { 45 46 public CSSNode() { 47 setContentSize(100); 48 } 49 50 /** 51 * This variable can be set from CSS and represents the fill 52 */ 53 private ObjectProperty<Paint> fill; 54 public ObjectProperty<Paint> fillProperty() { 55 if (fill == null) { 56 fill = new StyleableObjectProperty<Paint>(Color.BLACK) { 57 58 @Override 59 public Object getBean() { 60 return CSSNode.this; 61 } 62 63 @Override 64 public String getName() { 65 return "fill"; 66 } 67 68 @Override 69 public CssMetaData getCssMetaData() { 70 return StyleableProperties.FILL; 71 } 72 73 }; 74 } 75 return fill; 76 } 77 public void setFill(Paint paint) { 78 fillProperty().set(paint); 79 } 80 public Paint getFill() { 81 return (fill == null ? Color.BLACK : fill.get()); 82 } 83 84 /** 85 * This variable can be set from CSS and represents the stroke fill 86 */ 87 private ObjectProperty<Paint> stroke; 88 public ObjectProperty<Paint> strokeProperty() { 89 if (stroke == null) { 90 stroke = new StyleableObjectProperty<Paint>(Color.BLACK) { 91 92 @Override 93 public Object getBean() { 94 return CSSNode.this; 95 } 96 97 @Override 98 public String getName() { 99 return "stroke"; 100 } 101 102 @Override 103 public CssMetaData getCssMetaData() { 104 return StyleableProperties.STROKE; 105 } 106 107 }; 108 } 109 return stroke; 110 } 111 public void setStroke(Paint paint) { 112 strokeProperty().set(paint); 113 } 114 public Paint getStroke() { 115 return (stroke == null ? Color.BLACK : stroke.get()); 116 } 117 118 /** 119 * This variable can be set from CSS and is a simple number. For testing, 120 * this can be font-based, absolute, or percentage based. The CSSNode has 121 * a contentSize:Number variable which is used when padding is based on 122 * a percentage 123 */ 124 private FloatProperty padding; 125 126 public final void setPadding(float value) { 127 paddingProperty().set(value); 128 } 129 130 public final float getPadding() { 131 return padding == null ? 0.0F : padding.get(); 132 } 133 134 public FloatProperty paddingProperty() { 135 if (padding == null) { 136 padding = new StyleableFloatProperty() { 137 138 @Override 139 protected void invalidated() { 140 impl_geomChanged(); 141 } 142 143 @Override 144 public Object getBean() { 145 return CSSNode.this; 146 } 147 148 @Override 149 public String getName() { 150 return "padding"; 151 } 152 153 @Override 154 public CssMetaData getCssMetaData() { 155 return StyleableProperties.PADDING; 156 } 157 }; 158 } 159 return padding; 160 } 161 162 /** 163 * Used only when padding is specified as a percentage, as it is a 164 * percentage of the content size. 165 */ 166 private FloatProperty contentSize; 167 168 public final void setContentSize(float value) { 169 contentSizeProperty().set(value); 170 } 171 172 public final float getContentSize() { 173 return contentSize == null ? 0.0F : contentSize.get(); 174 } 175 176 public FloatProperty contentSizeProperty() { 177 if (contentSize == null) { 178 contentSize = new SimpleFloatProperty() { 179 180 @Override 181 protected void invalidated() { 182 impl_geomChanged(); 183 } 184 }; 185 } 186 return contentSize; 187 } 188 189 /** 190 * A pseudoclass state for this Node. It cannot be styled, but can 191 * be used as a pseudoclass 192 */ 193 private PseudoClass SPECIAL_PSEUDO_CLASS = PseudoClass.getPseudoClass("special"); 194 private BooleanProperty special; 195 public final void setSpecial(boolean value) { 196 specialProperty().set(value); 197 } 198 199 public final boolean isSpecial() { 200 return special == null ? false : special.get(); 201 } 202 203 public BooleanProperty specialProperty() { 204 if (special == null) { 205 special = new SimpleBooleanProperty() { 206 207 @Override 208 protected void invalidated() { 209 pseudoClassStateChanged(SPECIAL_PSEUDO_CLASS, get()); 210 } 211 }; 212 } 213 return special; 214 } 215 216 /* 217 * These vars are used solely for the sake of testing. 218 */ 219 220 public boolean reapply = false; 221 public boolean processCalled = false; 222 public boolean applyCalled = false; 223 224 @Override 225 public BaseBounds impl_computeGeomBounds(BaseBounds bounds, BaseTransform tx) { 226 if (bounds != null) { 227 bounds = bounds.deriveWithNewBounds(0, 0, 0, 228 getContentSize() + getPadding() + getPadding(), getContentSize() + getPadding() + getPadding(), 0); 229 } 230 return bounds; 231 } 232 233 @Override 234 protected boolean impl_computeContains(double localX, double localY) { 235 // TODO: Missing code. 236 return false; 237 } 238 239 @Override 240 public NGNode impl_createPeer() { 241 return new NGGroup(); 242 } 243 244 public static class StyleableProperties { 245 246 public static final CssMetaData<CSSNode,Paint> FILL = 247 new CssMetaData<CSSNode,Paint>("fill", PaintConverter.getInstance()) { 248 249 @Override 250 public boolean isSettable(CSSNode n) { 251 return n.fill == null || !n.fill.isBound(); 252 } 253 254 @Override 255 public StyleableProperty<Paint> getStyleableProperty(CSSNode n) { 256 return (StyleableProperty<Paint>)n.fillProperty(); 257 } 258 }; 259 260 public static final CssMetaData<CSSNode,Paint> STROKE = 261 new CssMetaData<CSSNode,Paint>("stroke", PaintConverter.getInstance()) { 262 263 @Override 264 public boolean isSettable(CSSNode n) { 265 return n.stroke == null || !n.stroke.isBound(); 266 } 267 268 @Override 269 public StyleableProperty<Paint> getStyleableProperty(CSSNode n) { 270 return (StyleableProperty<Paint>)n.strokeProperty(); 271 } 272 }; 273 274 public static final CssMetaData<CSSNode,Number> PADDING = 275 new CssMetaData<CSSNode,Number>("padding", SizeConverter.getInstance()) { 276 277 @Override 278 public boolean isSettable(CSSNode n) { 279 return n.padding == null || !n.padding.isBound(); 280 } 281 282 @Override 283 public StyleableProperty<Number> getStyleableProperty(CSSNode n) { 284 return (StyleableProperty<Number>)n.paddingProperty(); 285 } 286 }; 287 288 private static List<CssMetaData<? extends Styleable, ?>> STYLEABLES; 289 static { 290 final List<CssMetaData<? extends Styleable, ?>> styleables = 291 new ArrayList<CssMetaData<? extends Styleable, ?>>(Node.getClassCssMetaData()); 292 styleables.add(FILL); 293 styleables.add(STROKE); 294 styleables.add(PADDING); 295 296 } 297 298 } 299 300 /** 301 * @return The CssMetaData associated with this class, which may include the 302 * CssMetaData of its super classes. 303 */ 304 public static List<CssMetaData<? extends Styleable, ?>> getClassCssMetaData() { 305 return StyleableProperties.STYLEABLES; 306 } 307 308 /** 309 * {@inheritDoc} 310 * 311 */ 312 313 314 @Override 315 public List<CssMetaData<? extends Styleable, ?>> getCssMetaData() { 316 return getClassCssMetaData(); 317 } 318 319 /** 320 * @treatAsPrivate Implementation detail 321 */ 322 @Override 323 public Object impl_processMXNode(MXNodeAlgorithm alg, MXNodeAlgorithmContext ctx) { 324 return null; 325 } 326 }