1 /*
   2  * Copyright (c) 2011, 2015, 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 com.sun.javafx.scene.control.behavior;
  27 
  28 import javafx.scene.Node;
  29 import javafx.scene.control.TableColumnBase;
  30 import javafx.scene.control.TablePositionBase;
  31 import javafx.scene.control.TreeItem;
  32 import javafx.scene.control.TreeTableCell;
  33 import javafx.scene.control.TreeTableColumn;
  34 import javafx.scene.control.TreeTableView;
  35 import javafx.scene.input.MouseButton;
  36 
  37 /**
  38  */
  39 public class TreeTableCellBehavior<S,T> extends TableCellBehaviorBase<TreeItem<S>, T, TreeTableColumn<S, ?>, TreeTableCell<S,T>> {
  40     
  41     /***************************************************************************
  42      *                                                                         *
  43      * Constructors                                                            *
  44      *                                                                         *
  45      **************************************************************************/    
  46 
  47     public TreeTableCellBehavior(TreeTableCell<S,T> control) {
  48         super(control);
  49     }
  50     
  51     
  52     
  53     /***************************************************************************
  54      *                                                                         *
  55      * Implement TableCellBehaviorBase Abstract API                            *
  56      *                                                                         *
  57      **************************************************************************/          
  58 
  59     /** @{@inheritDoc} */
  60     @Override protected TreeTableView<S> getCellContainer() {
  61         return getNode().getTreeTableView();
  62     }
  63 
  64     /** @{@inheritDoc} */
  65     @Override protected TreeTableColumn<S,T> getTableColumn() {
  66         return getNode().getTableColumn();
  67     }
  68 
  69     /** @{@inheritDoc} */
  70     @Override protected int getItemCount() {
  71         return getCellContainer().getExpandedItemCount();
  72     }
  73 
  74     /** @{@inheritDoc} */
  75     @Override protected TreeTableView.TreeTableViewSelectionModel<S> getSelectionModel() {
  76         return getCellContainer().getSelectionModel();
  77     }
  78 
  79     /** @{@inheritDoc} */
  80     @Override protected TreeTableView.TreeTableViewFocusModel<S> getFocusModel() {
  81         return getCellContainer().getFocusModel();
  82     }
  83 
  84     /** @{@inheritDoc} */
  85     @Override protected TablePositionBase getFocusedCell() {
  86         return getCellContainer().getFocusModel().getFocusedCell();
  87     }
  88 
  89     /** @{@inheritDoc} */
  90     @Override protected boolean isTableRowSelected() {
  91         return getNode().getTreeTableRow().isSelected();
  92     }
  93 
  94     /** @{@inheritDoc} */
  95     @Override protected int getVisibleLeafIndex(TableColumnBase tc) {
  96         return getCellContainer().getVisibleLeafIndex((TreeTableColumn)tc);
  97     }
  98 
  99     /** @{@inheritDoc} */
 100     @Override protected void focus(int row, TableColumnBase tc) {
 101         getFocusModel().focus(row, (TreeTableColumn)tc);
 102     }
 103 
 104     /** @{@inheritDoc} */
 105     @Override protected void edit(TreeTableCell<S,T> cell) {
 106         if (cell == null) {
 107             getCellContainer().edit(-1, null);
 108         } else {
 109             getCellContainer().edit(cell.getIndex(), cell.getTableColumn());
 110         }
 111     }
 112 
 113     @Override protected boolean handleDisclosureNode(double x, double y) {
 114         final TreeItem<S> treeItem = getNode().getTreeTableRow().getTreeItem();
 115 
 116         final TreeTableView<S> treeTableView = getNode().getTreeTableView();
 117         final TreeTableColumn<S,T> column = getTableColumn();
 118         final TreeTableColumn<S,?> treeColumn = treeTableView.getTreeColumn() == null ?
 119                 treeTableView.getVisibleLeafColumn(0) : treeTableView.getTreeColumn();
 120 
 121         if (column == treeColumn) {
 122             final Node disclosureNode = getNode().getTreeTableRow().getDisclosureNode();
 123             if (disclosureNode != null) {
 124                 double startX = 0;
 125                 for (TreeTableColumn<S,?> tc : treeTableView.getVisibleLeafColumns()) {
 126                     if (tc == treeColumn) break;
 127                     startX += tc.getWidth();
 128                 }
 129                 final double endX = disclosureNode.getBoundsInParent().getMaxX();
 130                 if (x < (endX - startX)) {
 131                     if (treeItem != null) {
 132                         treeItem.setExpanded(!treeItem.isExpanded());
 133                     }
 134                     return true;
 135                 }
 136             }
 137         }
 138         return false;
 139     }
 140     
 141     @Override
 142     protected void handleClicks(MouseButton button, int clickCount, boolean isAlreadySelected) {
 143         // handle editing, which only occurs with the primary mouse button
 144         TreeItem<S> treeItem = getNode().getTreeTableRow().getTreeItem();
 145         if (button == MouseButton.PRIMARY) {
 146             if (clickCount == 1 && isAlreadySelected) {
 147                 edit(getNode());
 148             } else if (clickCount == 1) {
 149                 // cancel editing
 150                 edit(null);
 151             } else if (clickCount == 2 && treeItem.isLeaf()) {
 152                 // attempt to edit
 153                 edit(getNode());
 154             } else if (clickCount % 2 == 0) {
 155                 // try to expand/collapse branch tree item
 156                 treeItem.setExpanded(! treeItem.isExpanded());
 157             }
 158         }
 159     }
 160 }