Legal Terms and Copyright Notice
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
*
* Copyright © 2010, Oracle and/or its affiliates. All rights reserved.
* Oracle is a registered trademark of Oracle Corporation and/or its affiliates.
* Oracle and Java are registered trademarks of Oracle and/or its affiliates.
* Other names may be trademarks of their respective owners.
*
* This file is available and licensed under the following license:
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright notice,
trademark notice, this list of conditions, and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
trademark notice, this list of conditions, and the following disclaimer in
the documentation and/or other materials provided with the distribution.
* * Neither the name of Oracle nor the names of its contributors may be used
to endorse or promote products derived from this software without specific
prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package flowers;
import javafx.scene.Cursor;
import javafx.scene.CustomNode;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.input.MouseEvent;
import javafx.scene.paint.Color;
import javafx.scene.paint.Paint;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Font;
import javafx.stage.AppletStageExtension;
import javafx.stage.Stage;
import javafx.stage.StageStyle.TRANSPARENT;
import javafx.util.Math.max;
/**
* @author Sergey A. Malenkov
*/
public class Application {
public var foreground: Paint = Color.WHITE;
public var background: Paint = Color.rgb(29, 29, 29, 1);
public var size = 16.0;
public var minWidth = 160.0;
public var minHeight = 120.0;
public var title: String;
public var header: Node;
public var content: Node[];
var applet = __PROFILE__ == "browser";
def mobile = __PROFILE__ == "mobile";
var hover: Boolean;
def show: Boolean = bind not mobile and not stage.fullScreen;
def resizable = bind show and not applet;
def draggable = applet and AppletStageExtension.appletDragSupported;
def round: Number = bind size;
def border: Number = bind if (show) size / 4 else 0;
def width: Number = bind stage.scene.width - border - border on replace {
// def panel = content as Resizable;
// panel.width = width
}
def label = Label {
textFill: bind foreground
graphic: bind header
width: bind width - size * 4
text: bind if (header != null) null else title
font: bind Font {
name: "Arial Bold"
size: if (mobile) size else size * 2
}
}
def offset = bind max(size, label.height) + size / 2;
def height: Number = bind stage.scene.height - border - border - offset on replace {
//def panel = content as Resizable;
//panel.height = height
}
def stage: Stage = Stage {
title: bind title
style: TRANSPARENT
opacity: bind if (stage.containsFocus) 1.0 else 0.5
extensions: if (mobile) null else AppletStageExtension {
useDefaultClose: false
shouldDragStart: function(event) {
return hover and event.primaryButtonDown
}
onDragStarted: function() {
applet = false
}
onAppletRestored: function() {
applet = true
}
}
scene: Scene {
fill: null
width: 600
height: 480
content: [
Rectangle {
var sX: Number;
var sY: Number;
var wX: Number;
var wY: Number;
var wW: Number;
var wH: Number;
var top: Boolean;
var left: Boolean;
var right: Boolean;
var bottom: Boolean;
var cursor: Cursor;
cursor: bind cursor
blocksMouse: true
width: bind stage.scene.width
height: bind stage.scene.height + size
arcWidth: bind round * 1.5
arcHeight: bind round * 1.5
fill: bind background
def update = function(event: MouseEvent): Void {
if (not event.primaryButtonDown) {
if (resizable) {
top = event.y < size;
left = event.x < size;
right = event.x > stage.scene.width - size;
bottom = event.y > stage.scene.height - size;
if (top and left) {
cursor = Cursor.NW_RESIZE
}
else if (top and right) {
cursor = Cursor.NE_RESIZE
}
else if (bottom and left) {
cursor = Cursor.SW_RESIZE
}
else if (bottom and right) {
cursor = Cursor.SE_RESIZE
}
else if (top) {
cursor = Cursor.N_RESIZE
}
else if (left) {
cursor = Cursor.W_RESIZE
}
else if (right) {
cursor = Cursor.E_RESIZE
}
else if (bottom) {
cursor = Cursor.S_RESIZE
} else {
cursor = null
}
} else {
cursor = null
}
}
}
onMouseDragged: function(event) {
if (top) {
def dY = event.screenY - sY;
stage.y = wY + dY;
stage.height = max(minHeight, wH - dY);
}
else if (bottom) {
stage.height = max(minHeight, wH + event.screenY - sY);
}
if (left) {
def dX = event.screenX - sX;
stage.x = wX + dX;
stage.width = max(minWidth, wW - dX);
}
else if (right) {
stage.width = max(minWidth, wW + event.screenX - sX);
}
}
onMousePressed: function(event) {
sX = event.screenX;
sY = event.screenY;
wX = stage.x;
wY = stage.y;
wW = stage.width;
wH = stage.height;
}
onMouseReleased: update
onMouseEntered: update
onMouseExited: update
onMouseMoved: update
}
Rectangle {
cursor: Cursor.MOVE
blocksMouse: true
visible: bind show and (not applet or draggable)
x: bind border
y: bind border
width: bind width
height: bind offset
arcWidth: bind round
arcHeight: bind round
fill: bind foreground
opacity: 0.1
onMouseEntered: function(event) {
hover = true
}
onMouseExited: function(event) {
hover = false
}
onMouseDragged: function(event) {
stage.x += event.dragX;
stage.y += event.dragY;
}
}
Group {
translateX: bind border + size / 4
translateY: bind border + size / 4
content: bind label
}
Group {
cursor: Cursor.HAND
blocksMouse: true
visible: bind not applet
translateX: bind stage.scene.width - border
translateY: bind border + size * 0.75
content: [
Button {
rotate: 45
translateX: bind - size * 0.75
onMouseClicked: function(event) {
stage.close()
}
}
Button {
rotate: 90
visible: not mobile
translateX: bind - size * 2
onMouseClicked: function(event) {
stage.fullScreen = not stage.fullScreen;
}
}
Button {
visible: not mobile
translateX: bind - size * 3.25
onMouseClicked: function(event) {
if (stage.fullScreen) {
stage.fullScreen = false
}
stage.iconified = true
}
}
]
}
Group {
blocksMouse: true
translateX: bind border
translateY: bind border + offset
content: bind content
/*TODO:clip: Rectangle {
width: bind width
height: bind height
}*/
}
]
}
}
}
class Button extends CustomNode {
override function create() {
Group {
def rectangle = Rectangle {
visible: bind rotate != 0
x: bind - size / 16
y: bind - size / 4
width: bind size / 8
height: bind size / 2
fill: bind foreground
}
opacity: bind if (hover or mobile) 1.0 else 0.3
content: [
Circle {
radius: bind size / 2
fill: bind foreground
}
Circle {
radius: bind size * 7 / 16
fill: bind background
}
Rectangle {
x: bind rectangle.y
y: bind rectangle.x
width: bind rectangle.height
height: bind rectangle.width
fill: bind foreground
}
rectangle
]
}
}
}