/* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.drools.workbench.screens.guided.dtable.client.widget.table; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.ait.lienzo.client.core.types.Point2D; import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.EventTarget; import com.google.gwt.dom.client.NativeEvent; import com.google.gwt.event.dom.client.ContextMenuEvent; import com.google.gwt.event.dom.client.ContextMenuHandler; import com.google.gwt.event.dom.client.MouseDownEvent; import com.google.gwt.event.dom.client.MouseDownHandler; import org.drools.workbench.screens.guided.dtable.client.editor.menu.CellContextMenu; import org.drools.workbench.screens.guided.dtable.client.editor.menu.RowContextMenu; import org.uberfire.ext.wires.core.grids.client.model.GridCell; import org.uberfire.ext.wires.core.grids.client.model.GridColumn; import org.uberfire.ext.wires.core.grids.client.model.GridData; import org.uberfire.ext.wires.core.grids.client.util.CoordinateUtilities; import org.uberfire.ext.wires.core.grids.client.widget.dnd.IsRowDragHandle; import org.uberfire.ext.wires.core.grids.client.widget.grid.selections.CellSelectionStrategy; import org.uberfire.ext.wires.core.grids.client.widget.grid.selections.impl.RangeSelectionStrategy; @Dependent public class GuidedDecisionTableModellerContextMenuSupport { private final CellContextMenu cellContextMenu; private final RowContextMenu rowContextMenu; @Inject public GuidedDecisionTableModellerContextMenuSupport( final CellContextMenu cellContextMenu, final RowContextMenu rowContextMenu ) { this.cellContextMenu = cellContextMenu; this.rowContextMenu = rowContextMenu; } public ContextMenuHandler getContextMenuHandler( final GuidedDecisionTableModellerView.Presenter modellerPresenter ) { return new GuidedDecisionTableModellerContextMenuHandler( modellerPresenter, cellContextMenu, rowContextMenu ); } public MouseDownHandler getContextMenuMouseDownHandler() { return new GuidedDecisionTableModellerContextMenuMouseDownHandler( cellContextMenu, rowContextMenu ); } private static class GuidedDecisionTableModellerContextMenuHandler implements ContextMenuHandler { private final GuidedDecisionTableModellerView.Presenter modellerPresenter; private final CellContextMenu cellContextMenu; private final RowContextMenu rowContextMenu; public GuidedDecisionTableModellerContextMenuHandler( final GuidedDecisionTableModellerView.Presenter modellerPresenter, final CellContextMenu cellContextMenu, final RowContextMenu rowContextMenu ) { this.modellerPresenter = modellerPresenter; this.cellContextMenu = cellContextMenu; this.rowContextMenu = rowContextMenu; } @Override public void onContextMenu( final ContextMenuEvent event ) { event.preventDefault(); event.stopPropagation(); final boolean isShiftKeyDown = event.getNativeEvent().getShiftKey(); final boolean isControlKeyDown = event.getNativeEvent().getCtrlKey(); final int eventX = event.getNativeEvent().getClientX(); final int eventY = event.getNativeEvent().getClientY(); final int canvasX = getRelativeX( event ); final int canvasY = getRelativeY( event ); for ( GuidedDecisionTableView.Presenter dtPresenter : modellerPresenter.getAvailableDecisionTables() ) { final GuidedDecisionTableView gridView = dtPresenter.getView(); final GridData gridModel = gridView.getModel(); final Point2D ap = CoordinateUtilities.convertDOMToGridCoordinate( gridView, new Point2D( canvasX, canvasY ) ); final Integer uiRowIndex = CoordinateUtilities.getUiRowIndex( gridView, ap.getY() ); final Integer uiColumnIndex = CoordinateUtilities.getUiColumnIndex( gridView, ap.getX() ); if ( uiRowIndex == null || uiColumnIndex == null ) { continue; } final GridColumn<?> column = gridModel.getColumns().get( uiColumnIndex ); if ( column instanceof IsRowDragHandle ) { rowContextMenu.show( eventX, eventY ); } else { cellContextMenu.show( eventX, eventY ); } selectCell( uiRowIndex, uiColumnIndex, gridView, isShiftKeyDown, isControlKeyDown ); } } private int getRelativeX( final ContextMenuEvent event ) { final NativeEvent e = event.getNativeEvent(); final Element target = event.getRelativeElement(); return e.getClientX() - target.getAbsoluteLeft() + target.getScrollLeft() + target.getOwnerDocument().getScrollLeft(); } private int getRelativeY( final ContextMenuEvent event ) { final NativeEvent e = event.getNativeEvent(); final Element target = event.getRelativeElement(); return e.getClientY() - target.getAbsoluteTop() + target.getScrollTop() + target.getOwnerDocument().getScrollTop(); } private void selectCell( final int uiRowIndex, final int uiColumnIndex, final GuidedDecisionTableView gridView, final boolean isShiftKeyDown, final boolean isControlKeyDown ) { //Lookup CellSelectionManager for cell final GridData gridModel = gridView.getModel(); CellSelectionStrategy selectionStrategy; final GridCell<?> cell = gridModel.getCell( uiRowIndex, uiColumnIndex ); if ( cell == null ) { selectionStrategy = RangeSelectionStrategy.INSTANCE; } else { selectionStrategy = cell.getSelectionManager(); } if ( selectionStrategy == null ) { return; } //Handle selection if ( selectionStrategy.handleSelection( gridModel, uiRowIndex, uiColumnIndex, isShiftKeyDown, isControlKeyDown ) ) { gridView.getLayer().batch(); } } } private static class GuidedDecisionTableModellerContextMenuMouseDownHandler implements MouseDownHandler { private final CellContextMenu cellContextMenu; private final RowContextMenu rowContextMenu; public GuidedDecisionTableModellerContextMenuMouseDownHandler( final CellContextMenu cellContextMenu, final RowContextMenu rowContextMenu ) { this.cellContextMenu = cellContextMenu; this.rowContextMenu = rowContextMenu; } @Override public void onMouseDown( final MouseDownEvent event ) { if ( !eventTargetsPopup( event.getNativeEvent(), cellContextMenu.asWidget().getElement() ) ) { cellContextMenu.hide(); } if ( !eventTargetsPopup( event.getNativeEvent(), rowContextMenu.asWidget().getElement() ) ) { rowContextMenu.hide(); } } private boolean eventTargetsPopup( final NativeEvent event, final Element element ) { final EventTarget target = event.getEventTarget(); if ( Element.is( target ) ) { return element.isOrHasChild( Element.as( target ) ); } return false; } } }