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