Search in sources :

Example 1 with CellPreviewEvent

use of org.gwtproject.view.client.CellPreviewEvent in project gwtproject by treblereel.

the class AbstractCellTable method onBrowserEvent2.

@Override
protected void onBrowserEvent2(Event event) {
    // Get the event target.
    EventTarget eventTarget = event.getEventTarget();
    if (!Element.is(eventTarget)) {
        return;
    }
    final Element target = event.getEventTarget().cast();
    // Find the cell where the event occurred.
    TableSectionElement tbody = getTableBodyElement();
    TableSectionElement tfoot = getTableFootElement();
    TableSectionElement thead = getTableHeadElement();
    TableSectionElement targetTableSection = null;
    TableCellElement targetTableCell = null;
    Element cellParent = null;
    // Header in the headerBuilder.
    Element headerParent = null;
    // Column in the headerBuilder.
    Element headerColumnParent = null;
    // Header in the footerBuilder.
    Element footerParent = null;
    // Column in the footerBuilder.
    Element footerColumnParent = null;
    {
        Element maybeTableCell = null;
        Element cur = target;
        /*
       * If an event happens in the TD element but outside the cell's div, we want
       * to handle it as if it happened within the table cell.
       */
        if (TableCellElement.TAG_TD.equalsIgnoreCase(cur.getTagName()) && tableBuilder.isColumn(cur.getFirstChildElement())) {
            cur = cur.getFirstChildElement();
        }
        while (cur != null && targetTableSection == null) {
            /*
         * Found the table section. Return the most recent cell element that we
         * discovered.
         */
            if (cur == tbody || cur == tfoot || cur == thead) {
                // We found the table section.
                targetTableSection = cur.cast();
                if (maybeTableCell != null) {
                    targetTableCell = maybeTableCell.cast();
                    break;
                }
            }
            // Look for a table cell.
            String tagName = cur.getTagName();
            if (TableCellElement.TAG_TD.equalsIgnoreCase(tagName) || TableCellElement.TAG_TH.equalsIgnoreCase(tagName)) {
                /*
           * Found a table cell, but we can't return yet because it may be part
           * of a sub table within the a CellTable cell.
           */
                maybeTableCell = cur;
            }
            // Look for the most immediate cell parent if not already found.
            if (cellParent == null && tableBuilder.isColumn(cur)) {
                cellParent = cur;
            }
            /*
         * Look for the most immediate header parent if not already found. Its
         * possible that the footer or header will mistakenly identify a header
         * from the other section, so we remember both. When we eventually reach
         * the target table section element, we'll know for sure if its a header
         * of footer.
         */
            if (headerParent == null && headerBuilder.isHeader(cur)) {
                headerParent = cur;
            }
            if (footerParent == null && footerBuilder.isHeader(cur)) {
                footerParent = cur;
            }
            // Look for the most immediate column parent if not already found.
            if (headerColumnParent == null && headerBuilder.isColumn(cur)) {
                headerColumnParent = cur;
            }
            if (footerColumnParent == null && footerBuilder.isColumn(cur)) {
                footerColumnParent = cur;
            }
            // Iterate.
            cur = cur.getParentElement();
        }
    }
    if (targetTableCell == null) {
        return;
    }
    // parent.
    if (legacyRenderRowValues) {
        cellParent = targetTableCell.getFirstChildElement();
    }
    /*
     * Forward the event to the associated header, footer, or column.
     */
    TableRowElement targetTableRow = targetTableCell.getParentElement().cast();
    String eventType = event.getType();
    boolean isSelect = BrowserEvents.CLICK.equals(eventType) || (BrowserEvents.KEYDOWN.equals(eventType) && event.getKeyCode() == KeyCodes.KEY_ENTER);
    int col = targetTableCell.getCellIndex();
    if (targetTableSection == thead || targetTableSection == tfoot) {
        boolean isHeader = (targetTableSection == thead);
        headerParent = isHeader ? headerParent : footerParent;
        Element columnParent = isHeader ? headerColumnParent : footerColumnParent;
        boolean shouldSortColumn = true;
        // Fire the event to the header.
        if (headerParent != null) {
            Header<?> header = isHeader ? headerBuilder.getHeader(headerParent) : footerBuilder.getHeader(footerParent);
            if (header != null) {
                int headerIndex = isHeader ? headerBuilder.getRowIndex(targetTableRow) : footerBuilder.getRowIndex(targetTableRow);
                Context context = new Context(headerIndex, col, header.getKey());
                if (cellConsumesEventType(header.getCell(), eventType)) {
                    header.onBrowserEvent(context, headerParent, event);
                }
                if (isSelect) {
                    // Preview the event, and possibily disable the column sort event. The event preview is
                    // forced even if the header cell does not consume click event
                    shouldSortColumn = header.onPreviewColumnSortEvent(context, headerParent, event);
                }
            }
        }
        // Sort the header.
        if (isSelect && shouldSortColumn && columnParent != null) {
            Column<T, ?> column = isHeader ? headerBuilder.getColumn(columnParent) : footerBuilder.getColumn(columnParent);
            if (column != null && column.isSortable()) {
                /*
           * Force the headers to refresh the next time data is pushed so we
           * update the sort icon in the header.
           */
                headersDirty = true;
                updatingSortList = true;
                sortList.push(column);
                updatingSortList = false;
                ColumnSortEvent.fire(this, sortList);
            }
        }
    } else if (targetTableSection == tbody) {
        /*
       * Get the row index of the data value. This may not correspond to the DOM
       * row index if the user specifies multiple table rows per row object.
       */
        int absRow = tableBuilder.getRowValueIndex(targetTableRow);
        int relRow = absRow - getPageStart();
        int subrow = tableBuilder.getSubrowValueIndex(targetTableRow);
        if (!skipRowHoverCheck) {
            boolean isRowChange = hoveringRow != targetTableRow;
            if (BrowserEvents.MOUSEOVER.equals(eventType)) {
                // Unstyle the old row if it is still part of the table.
                if (hoveringRow != null && getTableBodyElement().isOrHasChild(hoveringRow)) {
                    setRowHover(hoveringRow, event, false, isRowChange);
                }
                hoveringRow = targetTableRow;
                setRowHover(hoveringRow, event, true, isRowChange);
            } else if (BrowserEvents.MOUSEOUT.equals(eventType) && hoveringRow != null) {
                boolean unhover = true;
                if (!skipRowHoverFloatElementCheck) {
                    // Ignore events happening directly over the hovering row. If there are floating element
                    // on top of the row, mouseout event should not be triggered. This is to avoid the
                    // flickring
                    // effect if the floating element is shown/hide based on hover event.
                    int clientX = event.getClientX() + Window.getScrollLeft();
                    int clientY = event.getClientY() + Window.getScrollTop();
                    int rowLeft = hoveringRow.getAbsoluteLeft();
                    int rowTop = hoveringRow.getAbsoluteTop();
                    int rowWidth = hoveringRow.getOffsetWidth();
                    int rowHeight = hoveringRow.getOffsetHeight();
                    int rowBottom = rowTop + rowHeight;
                    int rowRight = rowLeft + rowWidth;
                    unhover = clientX < rowLeft || clientX > rowRight || clientY < rowTop || clientY > rowBottom;
                }
                if (unhover) {
                    setRowHover(hoveringRow, event, false, isRowChange);
                    hoveringRow = null;
                }
            }
        }
        // of bounds of the underlying data.
        if (!isRowWithinBounds(relRow)) {
            return;
        }
        /*
       * Fire a preview event. The preview event is fired even if the TD does
       * not contain a cell so the selection handler and keyboard handler have a
       * chance to act.
       */
        boolean isSelectionHandled = handlesSelection || KeyboardSelectionPolicy.BOUND_TO_SELECTION == getKeyboardSelectionPolicy();
        T value = getVisibleItem(relRow);
        /*
       * Create a new context based on the dom column index instead of using the
       * user provided one from TableBuilder. We trigger cell preview events for
       * table cells even if there is no associated Cell instance. If we used
       * the user provided context, we could get inconsistent states where the
       * Context is sometimes user provided and sometimes generated based on the
       * DOM column index.
       */
        Context context = new Context(absRow, col, getValueKey(value), subrow);
        CellPreviewEvent<T> previewEvent = CellPreviewEvent.fire(this, event, this, context, value, cellIsEditing, isSelectionHandled);
        // Pass the event to the cell.
        if (cellParent != null && !previewEvent.isCanceled()) {
            HasCell<T, ?> column;
            if (legacyRenderRowValues) {
                column = columns.get(col);
            } else {
                column = tableBuilder.getColumn(context, value, cellParent);
            }
            if (column != null) {
                fireEventToCell(event, eventType, cellParent, value, context, column);
            }
        }
    }
}
Also used : Context(org.gwtproject.cell.client.Cell.Context) TableSectionElement(org.gwtproject.dom.client.TableSectionElement) TableRowElement(org.gwtproject.dom.client.TableRowElement) Element(org.gwtproject.dom.client.Element) TableElement(org.gwtproject.dom.client.TableElement) TableSectionElement(org.gwtproject.dom.client.TableSectionElement) TableRowElement(org.gwtproject.dom.client.TableRowElement) TableCellElement(org.gwtproject.dom.client.TableCellElement) HasCell(org.gwtproject.cell.client.HasCell) CellPreviewEvent(org.gwtproject.view.client.CellPreviewEvent) EventTarget(org.gwtproject.dom.client.EventTarget) TableCellElement(org.gwtproject.dom.client.TableCellElement)

Aggregations

Context (org.gwtproject.cell.client.Cell.Context)1 HasCell (org.gwtproject.cell.client.HasCell)1 Element (org.gwtproject.dom.client.Element)1 EventTarget (org.gwtproject.dom.client.EventTarget)1 TableCellElement (org.gwtproject.dom.client.TableCellElement)1 TableElement (org.gwtproject.dom.client.TableElement)1 TableRowElement (org.gwtproject.dom.client.TableRowElement)1 TableSectionElement (org.gwtproject.dom.client.TableSectionElement)1 CellPreviewEvent (org.gwtproject.view.client.CellPreviewEvent)1