/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
* Copyright 2008, 2010 Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*
* 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,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright 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 Corporation 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 com.sun.list;
import javafx.scene.CustomNode;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.scene.Group;
import javafx.scene.input.MouseEvent;
import javafx.scene.Node;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseButton;
import com.sun.list.ListModal;
public class ListView extends CustomNode{
public var listWidth: Number;
public var listHeight: Number;
var items: ListItem[];
public var factory:ListItemFactory;
public var selectedItem:ListModal;
public-read var focusedListItem: ListItem on replace oldVal{
oldVal.isFocused = false;
focusedListItem.isFocused = true;
focusedListItem.requestFocus();
};
public-read var selectedIndex: Integer = 0;
var draggedListItem: ListItem;
public var inset: Number = 5;
public var slotWidth: Number = listWidth - inset / 2.0;
public var slotHeight: Number = 20;
public var hSlotGap: Number = 1;
public var actionOnSelect:function():Void;
var itemsGroup: Group;
var dragStart: Number;
var velocity: Number;
var friction: Number = 0.7;
var minY: Number = 0;
var maxY: Number = 0;
var origY: Number;
var vGap: Number = 0;
var listViewMaxY: Number = bind maxY + 20;
public var listItems: ListModal[] on replace {
var listItem: ListItem;
delete items;
items = for(i in [0..listItems.size() - 1]) {
listItem = factory.create();
listItem.item = listItems[i];
listItem.width = slotWidth - 1;
listItem.height = slotHeight;
listItem.translateX = (inset / 2.0);
listItem.translateY = (slotHeight * i);
if (listItems[i].selected == true)
{
selectedItem = listItems[i];
}
listItem.onKeyPressed = function (ke: KeyEvent) {
if (ke.code == KeyCode.VK_DOWN or ke.code == KeyCode.VK_TAB ) {
if (i < items.size() - 1) {
focusedListItem = items[i+1];
var slotMaxY = items[i+1].boundsInParent.maxY;
var slotMinY = items[i+1].boundsInParent.minY;
if( slotMaxY > listHeight) {
itemsGroup.translateY = listHeight - slotMaxY;
}
} else if (i == items.size() - 1) {
var slotMinY = items[0].boundsInParent.minY;
items[0].requestFocus();
itemsGroup.translateY = slotMinY;
}
} else if (ke.code == KeyCode.VK_UP) {
if (i > 0) {
focusedListItem = items[i-1];
var slotMinY = items[i - 1].localToScene(items[i - 1].boundsInLocal).minY;
var thisMinY = localToScene(boundsInLocal).minY;
if( thisMinY > slotMinY) {
itemsGroup.translateY += thisMinY - slotMinY;
}
} else if (i == 0) {
items[items.size() - 1].requestFocus();
var slotMaxY = items[items.size() - 1].boundsInParent.maxY;
itemsGroup.translateY = listHeight - slotMaxY;
}
}
}
listItem.onMousePressed = function(me: MouseEvent):Void{
selectedIndex = i;
focusedListItem = items[i];
if ( actionOnSelect != null ){
if (me.button == MouseButton.SECONDARY)
{
actionOnSelect();
}
}
}
listItem.onMouseClicked = function(me: MouseEvent):Void{
selectedIndex = i;
focusedListItem = items[i];
if ( actionOnSelect != null ){
if (me.clickCount > 1)
{
actionOnSelect();
}
}
}
listItem;
}
}
public override function create(): Node {
itemsGroup = Group {
content: bind [
items,
]
};
var group = Group {
content: bind[itemsGroup]
onMouseDragged: function(e:MouseEvent):Void {
var newY = origY + e.dragY;
if(itemsGroup.boundsInLocal.height <= listHeight)
return;
if ( newY > 0 ) {
newY = newY * 0.3;
} else {
if ( newY < - (itemsGroup.boundsInLocal.height - listHeight) ){
itemsGroup.translateY = -(itemsGroup.boundsInLocal.height - listHeight);
}
else {
itemsGroup.translateY = newY;
}
}
}
clip: Rectangle {
width: listWidth
height: listHeight
}
}
return group;
}
}