1 /*
   2  * Copyright (c) 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.collections.ObservableList;
  29 import javafx.scene.control.Cell;
  30 import javafx.scene.control.Control;
  31 import javafx.scene.control.TableColumnBase;
  32 import javafx.scene.control.TablePositionBase;
  33 import javafx.scene.control.TableSelectionModel;
  34 import javafx.scene.input.MouseButton;
  35 import javafx.scene.input.MouseEvent;
  36 
  37 import java.util.Collections;
  38 import java.util.List;
  39 
  40 public abstract class TableRowBehaviorBase<T extends Cell> extends CellBehaviorBase<T> {
  41 
  42     /***************************************************************************
  43      *                                                                         *
  44      * Constructors                                                            *
  45      *                                                                         *
  46      **************************************************************************/
  47 
  48     public TableRowBehaviorBase(T control) {
  49         super(control, Collections.emptyList());
  50     }
  51 
  52 
  53 
  54     /***************************************************************************
  55      *                                                                         *
  56      * Public API                                                              *
  57      *                                                                         *
  58      **************************************************************************/
  59 
  60     @Override public void mousePressed(MouseEvent e) {
  61         // we only care about clicks to the right of the right-most column
  62         if (! isClickPositionValid(e.getX(), e.getY())) return;
  63 
  64         super.mousePressed(e);
  65     }
  66 
  67     @Override protected abstract TableSelectionModel<?> getSelectionModel();
  68 
  69     protected abstract TablePositionBase<?> getFocusedCell();
  70 
  71     protected abstract ObservableList getVisibleLeafColumns();
  72 
  73 
  74 
  75     /***************************************************************************
  76      *                                                                         *
  77      * Private implementation                                                  *
  78      *                                                                         *
  79      **************************************************************************/
  80 
  81     @Override protected void doSelect(final double x, final double y, final MouseButton button,
  82                    final int clickCount, final boolean shiftDown, final boolean shortcutDown) {
  83         final Control table = getCellContainer();
  84         if (table == null) return;
  85 
  86         // if the user has clicked on the disclosure node, we do nothing other
  87         // than expand/collapse the tree item (if applicable). We do not do editing!
  88         if (handleDisclosureNode(x,y)) {
  89             return;
  90         }
  91 
  92         final TableSelectionModel<?> sm = getSelectionModel();
  93         if (sm == null || sm.isCellSelectionEnabled()) return;
  94 
  95         final int index = getIndex();
  96         final boolean isAlreadySelected = sm.isSelected(index);
  97         if (clickCount == 1) {
  98             // we only care about clicks to the right of the right-most column
  99             if (! isClickPositionValid(x, y)) return;
 100 
 101             // In the case of clicking to the right of the rightmost
 102             // TreeTableCell, we should still support selection, so that
 103             // is what we are doing here.
 104             if (isAlreadySelected && shortcutDown) {
 105                 sm.clearSelection(index);
 106             } else {
 107                 if (shortcutDown) {
 108                     sm.select(getIndex());
 109                 } else if (shiftDown) {
 110                     // we add all rows between the current focus and
 111                     // this row (inclusive) to the current selection.
 112                     TablePositionBase<?> anchor = TableCellBehavior.getAnchor(table, getFocusedCell());
 113                     final int anchorRow = anchor.getRow();
 114                     selectRows(anchorRow, index);
 115                 } else {
 116                     simpleSelect(button, clickCount, shortcutDown);
 117                 }
 118             }
 119         } else {
 120             simpleSelect(button, clickCount, shortcutDown);
 121         }
 122     }
 123 
 124     @Override protected boolean isClickPositionValid(final double x, final double y) {
 125         // get width of all visible columns (we only care about clicks to the
 126         // right of the right-most column)
 127         List<TableColumnBase<T, ?>> columns = getVisibleLeafColumns();
 128         double width = 0.0;
 129         for (int i = 0; i < columns.size(); i++) {
 130             width += columns.get(i).getWidth();
 131         }
 132 
 133         return x > width;
 134     }
 135 }