stroom.data.grid.client.MoveHandle.java Source code

Java tutorial

Introduction

Here is the source code for stroom.data.grid.client.MoveHandle.java

Source

/*
 * Copyright 2016 Crown Copyright
 *
 * 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 stroom.data.grid.client;

import java.util.List;

import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.dom.client.Style;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.dom.client.Style.Visibility;
import com.google.gwt.user.cellview.client.DataGrid;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Widget;

import stroom.data.grid.client.DataGridViewImpl.ColSettings;
import stroom.data.grid.client.DataGridViewImpl.DefaultResources;
import stroom.data.grid.client.DataGridViewImpl.Heading;

public class MoveHandle<R> extends Widget {
    public static final int LINE_WIDTH = 2;
    public static final int HALF_LINE_WIDTH = LINE_WIDTH / 2;

    private final DataGridViewImpl<R> dataGridView;
    private final DataGrid<R> dataGrid;
    private final List<ColSettings> colSettings;
    private final DefaultResources resources;

    private Heading heading;

    private Element targetLine;

    private int offset;
    private int insertPos = -1;
    private boolean moving;
    private Glass glass;

    public MoveHandle(final DataGridViewImpl<R> dataGridView, final DataGrid<R> dataGrid,
            final List<ColSettings> colSettings, final DefaultResources resources) {
        this.dataGridView = dataGridView;
        this.dataGrid = dataGrid;
        this.colSettings = colSettings;
        this.resources = resources;

        final Element element = DOM.createDiv();
        setElement(element);

        getElement().setClassName(resources.dataGridStyle().moveHandle());

        final Style style = getElement().getStyle();
        style.setHeight(dataGrid.getElement().getOffsetHeight(), Unit.PX);
    }

    public void setHeading(final NativeEvent event, final Heading heading) {
        reset();

        if (heading != null) {
            final int childIndex = heading.getColIndex();
            final ColSettings settings = colSettings.get(childIndex);

            if (settings.isMovable()) {
                // See if we can move this column.
                final Style style = getElement().getStyle();
                style.setLeft(heading.getElement().getAbsoluteLeft(), Unit.PX);
                style.setTop(heading.getElement().getAbsoluteTop(), Unit.PX);
                style.setWidth(heading.getElement().getOffsetWidth(), Unit.PX);
                offset = heading.getInitialX() - heading.getElement().getAbsoluteLeft();

                this.heading = heading;
            }
        }
    }

    public void startMove(final NativeEvent event) {
        if (heading != null && Math.abs(event.getClientX() - heading.getInitialX()) > 10) {
            Event.setCapture(getElement());
            showGlass();
            moving = true;
        }
    }

    public void endMove(final NativeEvent event) {
        final int pos = insertPos;
        if (pos >= 0 && pos != heading.getColIndex()) {
            dataGridView.moveColumn(heading.getColIndex(), pos);
        }

        reset();
    }

    private void reset() {
        heading = null;
        moving = false;
        insertPos = -1;

        hideTargetLine();
        hide();
        hideGlass();

        Event.releaseCapture(getElement());
    }

    public void move(final NativeEvent event) {
        if (heading != null && moving) {
            final Style style = getElement().getStyle();
            style.setVisibility(Visibility.VISIBLE);
            final int left = event.getClientX() - offset;
            style.setLeft(left, Unit.PX);
            style.setTop(heading.getElement().getAbsoluteTop(), Unit.PX);
            style.setWidth(heading.getElement().getOffsetWidth(), Unit.PX);
            style.setHeight(dataGrid.getElement().getOffsetHeight(), Unit.PX);

            final Element parent = heading.getElement().getParentElement();

            insertPos = parent.getChildCount();
            for (int i = 0; i < parent.getChildCount(); i++) {
                final Element child = parent.getChild(i).cast();

                if (i == heading.getColIndex() + 1) {
                    // Don't allow the user to insert an item after itself as
                    // this doesn't make sense.
                    if (child.getAbsoluteLeft() > event.getClientX()) {
                        insertPos = i - 1;
                        break;
                    }

                } else if (i == parent.getChildCount() - 1 && heading.getColIndex() == parent.getChildCount() - 1) {
                    // Don't allow the user to insert an item after itself as
                    // this doesn't make sense.
                    insertPos = i;
                    break;

                } else if (child.getAbsoluteLeft() + (child.getScrollWidth() / 2) >= event.getClientX()) {
                    insertPos = i;
                    break;
                }
            }

            // Constrain to the first movable column.
            int firstMovableCol = 0;
            for (int i = 0; i < colSettings.size(); i++) {
                final ColSettings settings = colSettings.get(i);
                if (settings.isMovable()) {
                    firstMovableCol = i;
                    break;
                }
            }
            insertPos = Math.max(insertPos, firstMovableCol);

            // Show this handle if it isn't already showing.
            show();

            // Show the target line.
            if (insertPos == 0) {
                showTargetLine(dataGrid.getAbsoluteLeft(), dataGrid.getAbsoluteTop(), dataGrid.getOffsetHeight());
            } else {
                final Element child = parent.getChild(insertPos - 1).cast();
                showTargetLine(child.getAbsoluteRight() - HALF_LINE_WIDTH, dataGrid.getAbsoluteTop(),
                        dataGrid.getOffsetHeight());
            }
        }
    }

    private void showGlass() {
        if (glass == null) {
            glass = new Glass(resources.dataGridStyle().moveGlass());
        }
        glass.show();
    }

    private void hideGlass() {
        if (glass != null) {
            glass.hide();
        }
    }

    private void showTargetLine(final int left, final int top, final int height) {
        if (targetLine == null) {
            targetLine = DOM.createDiv();
            targetLine.setClassName(resources.dataGridStyle().moveLine());
        }

        targetLine.getStyle().setLeft(left, Unit.PX);
        targetLine.getStyle().setTop(top, Unit.PX);
        targetLine.getStyle().setHeight(height, Unit.PX);

        if (!targetLine.hasParentElement()) {
            Document.get().getBody().appendChild(targetLine);
        }
    }

    private void hideTargetLine() {
        if (targetLine != null) {
            targetLine.removeFromParent();
        }
    }

    public boolean isMoving() {
        return moving;
    }

    public void show() {
        if (!isAttached()) {
            RootPanel.get().add(this);
        }
    }

    public void hide() {
        if (isAttached()) {
            RootPanel.get().remove(this);
        }
    }
}