in kit/src/main/java/com/oracle/javafx/scenebuilder/kit/editor/panel/hierarchy/treeview/HierarchyTreeCell.java [161:456]
public HierarchyTreeCell(final AbstractHierarchyPanelController c) {
super();
this.panelController = c;
iconsStack.getChildren().setAll(
classNameImageView,
warningBadgeImageView);
iconsLabel.setGraphic(iconsStack);
// RT-31645 : we cannot dynamically update the HBox graphic children
// in the cell.updateItem method.
// We set once the graphic children, then we update the managed property
// of the children depending on the cell item.
graphic.getChildren().setAll(
includedFileImageView,
placeHolderImageView,
iconsLabel,
placeHolderLabel,
classNameInfoLabel,
displayInfoLabel);
// Add style class used when invoking lookupAll
this.getStyleClass().add(HIERARCHY_TREE_CELL);
// Update vertical insert line indicator stroke width
insertLineIndicator.setStrokeWidth(2.0);
// CSS
graphic.getStyleClass().add(TREE_CELL_GRAPHIC);
updatePlaceHolder();
displayInfoLabel.getStyleClass().add(HIERARCHY_READWRITE_LABEL);
placeHolderLabel.getStyleClass().add(HIERARCHY_PLACE_HOLDER_LABEL);
// Layout
classNameInfoLabel.setMinWidth(Control.USE_PREF_SIZE);
displayInfoLabel.setMaxWidth(Double.MAX_VALUE);
HBox.setHgrow(displayInfoLabel, Priority.ALWAYS);
panelController.displayOptionProperty().addListener(
new WeakChangeListener<>(displayOptionListener));
// Key events
//----------------------------------------------------------------------
final EventHandler<KeyEvent> keyEventHandler = e -> filterKeyEvent(e);
this.addEventFilter(KeyEvent.ANY, keyEventHandler);
// Mouse events
//----------------------------------------------------------------------
final EventHandler<MouseEvent> mouseEventHandler = e -> filterMouseEvent(e);
this.addEventFilter(MouseEvent.ANY, mouseEventHandler);
// Drag events
//----------------------------------------------------------------------
final HierarchyDNDController dndController = panelController.getDNDController();
setOnDragDropped(event -> {
final TreeItem<HierarchyItem> treeItem
= HierarchyTreeCell.this.getTreeItem();
// Forward to the DND controller
dndController.handleOnDragDropped(treeItem, event);
// CSS
panelController.clearBorderColor(HierarchyTreeCell.this);
// Remove insert line indicator
panelController.removeFromPanelControlSkin(insertLineIndicator);
});
setOnDragEntered(event -> {
final TreeItem<HierarchyItem> treeItem
= HierarchyTreeCell.this.getTreeItem();
// Forward to the DND controller
dndController.handleOnDragEntered(treeItem, event);
});
setOnDragExited(event -> {
final TreeItem<HierarchyItem> treeItem
= HierarchyTreeCell.this.getTreeItem();
final Bounds bounds = HierarchyTreeCell.this.getLayoutBounds();
final Point2D point = HierarchyTreeCell.this.localToScene(bounds.getMinX(), bounds.getMinY(), true /* rootScene */);
final DroppingMouseLocation location;
if (event.getSceneY() <= point.getY()) {
location = DroppingMouseLocation.TOP;
} else {
location = DroppingMouseLocation.BOTTOM;
}
// Forward to the DND controller
dndController.handleOnDragExited(treeItem, event, location);
// CSS
panelController.clearBorderColor(HierarchyTreeCell.this);
// Remove insert line indicator
panelController.removeFromPanelControlSkin(insertLineIndicator);
});
setOnDragOver(event -> {
final TreeItem<HierarchyItem> treeItem
= HierarchyTreeCell.this.getTreeItem();
final DragController dragController
= panelController.getEditorController().getDragController();
final DroppingMouseLocation location = getDroppingMouseLocation(event);
// Forward to the DND controller
dndController.handleOnDragOver(treeItem, event, location); // (1)
panelController.clearBorderColor();
// Update vertical insert line indicator stroke color
final Paint paint = panelController.getParentRingColor();
insertLineIndicator.setStroke(paint);
// Remove insert line indicator
panelController.removeFromPanelControlSkin(insertLineIndicator);
// If an animation timeline is running
// (auto-scroll when DND to the top or bottom of the Hierarchy),
// we do not display insert indicators.
if (panelController.isTimelineRunning()) {
return;
}
// Drop target has been updated because of (1)
if (dragController.isDropAccepted()) {
final AbstractDropTarget dropTarget = dragController.getDropTarget();
final FXOMObject dropTargetObject = dropTarget.getTargetObject();
final TreeItem<?> rootTreeItem = getTreeView().getRoot();
if (dropTarget instanceof RootDropTarget) {
// No visual feedback in case of dropping the root node
return;
}
//==========================================================
// ACCESSORIES :
//
// No need to handle the insert line indicator.
// Border is set either on the accessory place holder cell
// or on the accessory owner cell.
//==========================================================
if (dropTarget instanceof AccessoryDropTarget) {
final AccessoryDropTarget accessoryDropTarget = (AccessoryDropTarget) dropTarget;
final TreeCell<?> cell;
// TreeItem is null when dropping below the datas
// => the drop target is the root
if (treeItem == null) {
cell = HierarchyTreeViewUtils.getTreeCell(getTreeView(), rootTreeItem);
} else {
final HierarchyItem item = treeItem.getValue();
assert item != null;
if (item.isPlaceHolder()) {
cell = HierarchyTreeCell.this;
} else if (accessoryDropTarget.getAccessory() == Accessory.GRAPHIC) {
// Check if an empty graphic TreeItem has been added
final TreeItem<HierarchyItem> graphicTreeItem
= dndController.getEmptyGraphicTreeItemFor(treeItem);
if (graphicTreeItem != null) {
cell = HierarchyTreeViewUtils.getTreeCell(getTreeView(), graphicTreeItem);
} else {
final TreeItem<HierarchyItem> accessoryOwnerTreeItem1
= panelController.lookupTreeItem(dropTargetObject);
cell = HierarchyTreeViewUtils.getTreeCell(getTreeView(), accessoryOwnerTreeItem1);
}
} else {
final TreeItem<HierarchyItem> accessoryOwnerTreeItem2
= panelController.lookupTreeItem(dropTargetObject);
cell = HierarchyTreeViewUtils.getTreeCell(getTreeView(), accessoryOwnerTreeItem2);
}
}
panelController.setBorder(cell, BorderSide.TOP_RIGHT_BOTTOM_LEFT);
}//
//==========================================================
// SUB COMPONENTS :
//
// Need to handle the insert line indicator.
//==========================================================
else {
assert dropTarget instanceof ContainerZDropTarget
|| dropTarget instanceof GridPaneDropTarget;
TreeItem<?> startTreeItem;
TreeCell<?> startCell, stopCell;
// TreeItem is null when dropping below the datas
// => the drop target is the root
if (treeItem == null) {
if (rootTreeItem.isLeaf() || !rootTreeItem.isExpanded()) {
final TreeCell<?> rootCell = HierarchyTreeViewUtils.getTreeCell(getTreeView(), 0);
panelController.setBorder(rootCell, BorderSide.TOP_RIGHT_BOTTOM_LEFT);
} else {
final TreeItem<?> lastTreeItem = panelController.getLastVisibleTreeItem(rootTreeItem);
final TreeCell<?> lastCell = HierarchyTreeViewUtils.getTreeCell(getTreeView(), lastTreeItem);
// As we are dropping below the datas, the last cell is visible
assert lastCell != null;
panelController.setBorder(lastCell, BorderSide.BOTTOM);
// Update vertical insert line
startTreeItem = rootTreeItem;
startCell = HierarchyTreeViewUtils.getTreeCell(getTreeView(), startTreeItem);
stopCell = lastCell;
updateInsertLineIndicator(startCell, stopCell);
panelController.addToPanelControlSkin(insertLineIndicator);
}
} else {
final HierarchyItem item = treeItem.getValue();
assert item != null;
if (item.isPlaceHolder() || item.getFxomObject() == dropTargetObject) {
// The place holder item is filled with a container
// accepting sub components
panelController.setBorder(HierarchyTreeCell.this, BorderSide.TOP_RIGHT_BOTTOM_LEFT);
} else {
// REORDERING :
// To avoid visual movement of the horizontal border when
// dragging from one cell to another,
// we always set the border on the cell bottom location :
// - if we handle REORDER BELOW gesture, just set the bottom
// border on the current cell
// - if we handle REORDER ABOVE gesture, we set the bottom
// border on the previous cell
//
switch (location) {
// REORDER ABOVE gesture
case TOP:
if (treeItem == rootTreeItem) {
panelController.setBorder(HierarchyTreeCell.this, BorderSide.TOP_RIGHT_BOTTOM_LEFT);
} else {
final int index = getIndex();
// Retrieve the previous cell
// Note : we set the border on the bottom of the previous cell
// instead of using the top of the current cell in order to avoid
// visual gap when DND from one cell to another
final TreeCell<?> previousCell
= HierarchyTreeViewUtils.getTreeCell(getTreeView(), index - 1);
// The previous cell is null when the item is not visible
if (previousCell != null) {
panelController.setBorder(previousCell, BorderSide.BOTTOM);
}
// Update vertical insert line
startTreeItem = panelController.lookupTreeItem(dropTarget.getTargetObject());
startCell = HierarchyTreeViewUtils.getTreeCell(getTreeView(), startTreeItem);
stopCell = previousCell;
updateInsertLineIndicator(startCell, stopCell);
panelController.addToPanelControlSkin(insertLineIndicator);
}
break;
// REPARENT gesture
case CENTER:
if (treeItem.isLeaf() || !treeItem.isExpanded()) {
panelController.setBorder(HierarchyTreeCell.this, BorderSide.TOP_RIGHT_BOTTOM_LEFT);
} else {
// Reparent to the treeItem as last child
final TreeItem<?> lastTreeItem = panelController.getLastVisibleTreeItem(treeItem);
final TreeCell<?> lastCell = HierarchyTreeViewUtils.getTreeCell(getTreeView(), lastTreeItem);
// Last cell is null when the item is not visible
if (lastCell != null) {
panelController.setBorder(lastCell, BorderSide.BOTTOM);
}
// Update vertical insert line
startTreeItem = getTreeItem();
startCell = HierarchyTreeViewUtils.getTreeCell(getTreeView(), startTreeItem);
stopCell = lastCell;
updateInsertLineIndicator(startCell, stopCell);
panelController.addToPanelControlSkin(insertLineIndicator);
}
break;
// REORDER BELOW gesture
case BOTTOM:
if (treeItem == rootTreeItem
&& (treeItem.isLeaf() || !treeItem.isExpanded())) {
panelController.setBorder(HierarchyTreeCell.this, BorderSide.TOP_RIGHT_BOTTOM_LEFT);
} else {
// Reparent to the treeItem as first child
panelController.setBorder(HierarchyTreeCell.this, BorderSide.BOTTOM);
// Update vertical insert line
startTreeItem = panelController.lookupTreeItem(dropTarget.getTargetObject());
startCell = HierarchyTreeViewUtils.getTreeCell(getTreeView(), startTreeItem);
stopCell = HierarchyTreeCell.this;
updateInsertLineIndicator(startCell, stopCell);
panelController.addToPanelControlSkin(insertLineIndicator);
}
break;
default:
assert false;
break;
}
}
}
}
}
});
}