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.com.sun.javafx.pgstub; 27 28 import java.security.AccessControlContext; 29 import java.util.LinkedList; 30 import java.util.List; 31 import java.util.Queue; 32 33 import com.sun.javafx.tk.FocusCause; 34 import com.sun.javafx.tk.TKScene; 35 import com.sun.javafx.tk.TKStage; 36 import com.sun.javafx.tk.TKStageListener; 37 38 /** 39 * @author Richard Bair 40 */ 41 public class StubStage implements TKStage { 42 43 private NotificationSender notificationSender = new NotificationSender(); 44 45 @Override 46 public void setTKStageListener(TKStageListener listener) { 47 notificationSender.setListener(listener); 48 } 49 50 @Override 51 public TKScene createTKScene(boolean depthBuffer, boolean msaa, AccessControlContext acc) { 52 return new StubScene(); 53 } 54 55 @Override 56 public void setScene(TKScene scene) { 57 if (scene != null) { 58 StubScene s = (StubScene) scene; 59 s.stage = this; 60 notificationSender.setScene(s); 61 if (visible && width != -1 && height != -1) 62 s.getListener().changedSize(width, height); 63 } 64 } 65 66 public int numTimesSetSizeAndLocation; 67 68 // Platform place/resize the window with some 69 // "default" value. Pretending that the values 70 // below are those platform defaults. 71 public float x = 16; 72 public float y = 12; 73 public float width = 256; 74 public float height = 192; 75 public float renderScaleX = 1.0f; 76 public float renderScaleY = 1.0f; 77 78 public boolean visible; 79 public float opacity; 80 81 @Override 82 public void setBounds(float x, float y, boolean xSet, boolean ySet, 83 float width, float height, 84 float contentWidth, float contentHeight, 85 float xGravity, float yGravity, 86 float renderScaleX, float renderScaleY) 87 { 88 numTimesSetSizeAndLocation++; 89 90 boolean locationChanged = false; 91 92 if (xSet && (this.x != x)) { 93 this.x = x; 94 locationChanged = true; 95 } 96 97 if (ySet && (this.y != y)) { 98 this.y = y; 99 locationChanged = true; 100 } 101 102 if (locationChanged) { 103 notificationSender.changedLocation(x, y); 104 } 105 106 boolean sizeChanged = false; 107 108 if (width > 0) { 109 if (this.width != width) { 110 this.width = width; 111 sizeChanged = true; 112 } 113 } else if (contentWidth > 0) { 114 if (this.width != contentWidth) { 115 this.width = contentWidth; 116 sizeChanged = true; 117 } 118 } 119 120 if (height > 0) { 121 if (this.height != height) { 122 this.height = height; 123 sizeChanged = true; 124 } 125 } else if (contentHeight > 0) { 126 if (this.height != contentHeight) { 127 this.height = contentHeight; 128 sizeChanged = true; 129 } 130 } 131 132 if (sizeChanged) { 133 notificationSender.changedSize(width, height); 134 } 135 if (renderScaleX > 0.0) this.renderScaleX = renderScaleX; 136 if (renderScaleY > 0.0) this.renderScaleY = renderScaleY; 137 } 138 139 @Override 140 public float getPlatformScaleX() { 141 return 1.0f; 142 } 143 144 @Override 145 public float getPlatformScaleY() { 146 return 1.0f; 147 } 148 149 @Override 150 public float getOutputScaleX() { 151 return 1.0f; 152 } 153 154 @Override 155 public float getOutputScaleY() { 156 return 1.0f; 157 } 158 159 // Just a helper method 160 public void setSize(float w, float h) { 161 setBounds(0, 0, false, false, w, h, 0, 0, 0, 0, 0, 0); 162 } 163 164 // Just a helper method 165 public void setLocation(float x, float y) { 166 setBounds(x, y, true, true, 0, 0, 0, 0, 0, 0, 0, 0); 167 } 168 169 @Override 170 public void setIcons(List icons) { 171 } 172 173 @Override 174 public void setTitle(String title) { 175 } 176 177 @Override 178 public void setVisible(boolean visible) { 179 this.visible = visible; 180 181 if (!visible) { 182 notificationSender.changedFocused(false, FocusCause.DEACTIVATED); 183 } 184 185 notificationSender.changedLocation(x, y); 186 notificationSender.changedSize(width, height); 187 } 188 189 @Override 190 public void setOpacity(float opacity) { 191 this.opacity = opacity; 192 } 193 194 @Override 195 public void setIconified(boolean iconified) { 196 notificationSender.changedIconified(iconified); 197 } 198 199 @Override 200 public void setMaximized(boolean maximized) { 201 notificationSender.changedMaximized(maximized); 202 } 203 204 @Override 205 public void setAlwaysOnTop(boolean alwaysOnTop) { 206 notificationSender.changedAlwaysOnTop(alwaysOnTop); 207 } 208 209 @Override 210 public void setResizable(boolean resizable) { 211 notificationSender.changedResizable(resizable); 212 } 213 214 @Override 215 public void setImportant(boolean important) { 216 } 217 218 @Override 219 public void setFullScreen(boolean fullScreen) { 220 notificationSender.changedFullscreen(fullScreen); 221 } 222 223 @Override 224 public void requestFocus() { 225 notificationSender.changedFocused(true, FocusCause.ACTIVATED); 226 } 227 228 @Override 229 public void requestFocus(FocusCause cause) { 230 notificationSender.changedFocused(true, cause); 231 } 232 233 @Override 234 public void toBack() { 235 } 236 237 @Override 238 public void toFront() { 239 } 240 241 @Override 242 public void close() { 243 } 244 245 private boolean focusGrabbed; 246 247 @Override 248 public boolean grabFocus() { 249 focusGrabbed = true; 250 return true; 251 } 252 253 @Override 254 public void ungrabFocus() { 255 focusGrabbed = false; 256 } 257 258 public boolean isFocusGrabbed() { 259 return focusGrabbed; 260 } 261 262 @Override 263 public void setMinimumSize(int minWidth, int minHeight) { 264 } 265 266 @Override 267 public void setMaximumSize(int maxWidth, int maxHeight) { 268 } 269 270 public void holdNotifications() { 271 notificationSender.holdNotifications(); 272 } 273 274 public void releaseNotifications() { 275 notificationSender.releaseNotifications(); 276 } 277 278 public void releaseSingleNotification() { 279 notificationSender.releaseSingleNotification(); 280 } 281 282 protected final TKStageListener getNotificationSender() { 283 return notificationSender; 284 } 285 286 @Override 287 public void requestInput(String text, int type, double width, double height, 288 double Mxx, double Mxy, double Mxz, double Mxt, 289 double Myx, double Myy, double Myz, double Myt, 290 double Mzx, double Mzy, double Mzz, double Mzt) { 291 throw new UnsupportedOperationException("Not supported yet."); 292 } 293 294 @Override 295 public void releaseInput() { 296 throw new UnsupportedOperationException("Not supported yet."); 297 } 298 299 private interface Notification { 300 void execute(TKStageListener listener); 301 } 302 303 private static final class NotificationSender implements TKStageListener { 304 private final Queue<Notification> queue = 305 new LinkedList<Notification>(); 306 307 private boolean hold; 308 private TKStageListener listener; 309 private StubScene scene; 310 311 public void setListener(final TKStageListener listener) { 312 this.listener = listener; 313 } 314 315 public void setScene(final StubScene scene) { 316 this.scene = scene; 317 } 318 319 public void holdNotifications() { 320 hold = true; 321 } 322 323 public void releaseNotifications() { 324 hold = false; 325 flush(); 326 } 327 328 private void releaseSingleNotification() { 329 queue.poll().execute(listener); 330 } 331 332 @Override 333 public void changedLocation(final float x, final float y) { 334 process(listener1 -> listener1.changedLocation(x, y)); 335 } 336 337 @Override 338 public void changedSize(final float width, final float height) { 339 process(listener1 -> { 340 listener1.changedSize(width, height); 341 if (scene != null && width != -1 && height != -1) { 342 scene.getListener().changedSize(width, height); 343 } 344 }); 345 } 346 347 @Override 348 public void changedScale(float xScale, float yScale) { 349 process(listener1 -> listener1.changedScale(xScale, yScale)); 350 } 351 352 @Override 353 public void changedFocused(final boolean focused, 354 final FocusCause cause) { 355 process(listener1 -> listener1.changedFocused(focused, cause)); 356 } 357 358 @Override 359 public void changedIconified(final boolean iconified) { 360 process(listener1 -> listener1.changedIconified(iconified)); 361 } 362 363 @Override 364 public void changedMaximized(final boolean maximized) { 365 process(listener1 -> listener1.changedMaximized(maximized)); 366 } 367 368 @Override 369 public void changedAlwaysOnTop(boolean alwaysOnTop) { 370 process(listener1 -> listener1.changedAlwaysOnTop(alwaysOnTop)); 371 } 372 373 374 @Override 375 public void changedResizable(final boolean resizable) { 376 process(listener1 -> listener1.changedResizable(resizable)); 377 } 378 379 @Override 380 public void changedFullscreen(final boolean fs) { 381 process(listener1 -> listener1.changedFullscreen(fs)); 382 } 383 384 @Override 385 public void closing() { 386 process(listener1 -> listener1.closing()); 387 } 388 389 @Override 390 public void closed() { 391 process(listener1 -> listener1.closed()); 392 } 393 394 @Override 395 public void focusUngrab() { 396 process(listener1 -> listener1.focusUngrab()); 397 } 398 399 private void process(final Notification notification) { 400 if (hold) { 401 queue.offer(notification); 402 return; 403 } 404 405 if (listener != null) { 406 notification.execute(listener); 407 } 408 } 409 410 private void flush() { 411 if (listener == null) { 412 queue.clear(); 413 return; 414 } 415 416 Notification nextNotification = queue.poll(); 417 while (nextNotification != null) { 418 nextNotification.execute(listener); 419 nextNotification = queue.poll(); 420 } 421 } 422 423 /** 424 * Initialize accessibility 425 */ 426 public void initAccessibleTKStageListener() { 427 // TODO: Add code later 428 } 429 430 @Override 431 public void changedScreen(Object from, Object to) { 432 // TODO: Add code later 433 } 434 435 } 436 437 @Override 438 public void setRTL(boolean b) { 439 } 440 }