diff options
Diffstat (limited to 'android/source/src/java/org/libreoffice/canvas/GraphicSelection.java')
-rw-r--r-- | android/source/src/java/org/libreoffice/canvas/GraphicSelection.java | 295 |
1 files changed, 295 insertions, 0 deletions
diff --git a/android/source/src/java/org/libreoffice/canvas/GraphicSelection.java b/android/source/src/java/org/libreoffice/canvas/GraphicSelection.java new file mode 100644 index 000000000..8d773b2ea --- /dev/null +++ b/android/source/src/java/org/libreoffice/canvas/GraphicSelection.java @@ -0,0 +1,295 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.libreoffice.canvas; + +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.PointF; +import android.graphics.RectF; + +import org.libreoffice.LOKitShell; +import org.libreoffice.LibreOfficeMainActivity; +import org.mozilla.gecko.gfx.LayerView; + +import static org.libreoffice.canvas.GraphicSelectionHandle.HandlePosition; + +/** + * This class is responsible to draw and reposition the selection + * rectangle. + */ +public class GraphicSelection extends CommonCanvasElement { + private final Paint mPaintStroke; + private final Paint mPaintFill; + public RectF mRectangle = new RectF(); + public RectF mScaledRectangle = new RectF(); + private RectF mDrawRectangle = new RectF(); + private DragType mType = DragType.NONE; + private PointF mStartDragPosition; + + private GraphicSelectionHandle mHandles[] = new GraphicSelectionHandle[8]; + private GraphicSelectionHandle mDragHandle = null; + private boolean mTriggerSinglePress = false; + private LibreOfficeMainActivity mContext; + + /** + * Construct the graphic selection. + */ + public GraphicSelection(LibreOfficeMainActivity context) { + mContext = context; + // Create the paint, which is needed at drawing + mPaintStroke = new Paint(); + mPaintStroke.setStyle(Paint.Style.STROKE); + mPaintStroke.setColor(Color.GRAY); + mPaintStroke.setStrokeWidth(2); + mPaintStroke.setAntiAlias(true); + + mPaintFill = new Paint(); + mPaintFill.setStyle(Paint.Style.FILL); + mPaintFill.setColor(Color.WHITE); + mPaintFill.setAlpha(200); + mPaintFill.setAntiAlias(true); + + // Create the handles of the selection + mHandles[0] = new GraphicSelectionHandle(HandlePosition.TOP_LEFT); + mHandles[1] = new GraphicSelectionHandle(HandlePosition.TOP); + mHandles[2] = new GraphicSelectionHandle(HandlePosition.TOP_RIGHT); + mHandles[3] = new GraphicSelectionHandle(HandlePosition.LEFT); + mHandles[4] = new GraphicSelectionHandle(HandlePosition.RIGHT); + mHandles[5] = new GraphicSelectionHandle(HandlePosition.BOTTOM_LEFT); + mHandles[6] = new GraphicSelectionHandle(HandlePosition.BOTTOM); + mHandles[7] = new GraphicSelectionHandle(HandlePosition.BOTTOM_RIGHT); + } + + /** + * Viewport has changed, reposition the selection to the new rectangle. + * @param scaledRectangle - rectangle of selection position on the document + */ + public void reposition(RectF scaledRectangle) { + mScaledRectangle = scaledRectangle; + mDrawRectangle = scaledRectangle; // rectangle that will be draw + + // reposition the handles too + mHandles[0].reposition(scaledRectangle.left, scaledRectangle.top); + mHandles[1].reposition(scaledRectangle.centerX(), scaledRectangle.top); + mHandles[2].reposition(scaledRectangle.right, scaledRectangle.top); + mHandles[3].reposition(scaledRectangle.left, scaledRectangle.centerY()); + mHandles[4].reposition(scaledRectangle.right, scaledRectangle.centerY()); + mHandles[5].reposition(scaledRectangle.left, scaledRectangle.bottom); + mHandles[6].reposition(scaledRectangle.centerX(), scaledRectangle.bottom); + mHandles[7].reposition(scaledRectangle.right, scaledRectangle.bottom); + } + + /** + * Hit test for the selection. + * @see org.libreoffice.canvas.CanvasElement#draw(android.graphics.Canvas) + */ + @Override + public boolean onHitTest(float x, float y) { + // Check if handle was hit + for (GraphicSelectionHandle handle : mHandles) { + if (handle.contains(x, y)) { + return true; + } + } + return mScaledRectangle.contains(x, y); + } + + /** + * Draw the selection on the canvas. + * @see org.libreoffice.canvas.CanvasElement#draw(android.graphics.Canvas) + */ + @Override + public void onDraw(Canvas canvas) { + canvas.drawRect(mDrawRectangle, mPaintStroke); + if (mType != DragType.NONE) { + canvas.drawRect(mDrawRectangle, mPaintFill); + } + for (GraphicSelectionHandle handle : mHandles) { + handle.draw(canvas); + } + } + + /** + * Dragging on the screen has started. + * @param position - position where the dragging started + */ + public void dragStart(PointF position) { + mDragHandle = null; + mType = DragType.NONE; + for (GraphicSelectionHandle handle : mHandles) { + if (handle.contains(position.x, position.y)) { + mDragHandle = handle; + mDragHandle.select(); + mType = DragType.EXTEND; + sendGraphicSelectionStart(handle.mPosition); + } + } + if (mDragHandle == null) { + mType = DragType.MOVE; + sendGraphicSelectionStart(position); + } + mStartDragPosition = position; + mTriggerSinglePress = true; + } + + /** + * Dragging is in process. + * @param position - position of the drag + */ + public void dragging(PointF position) { + if (mType == DragType.MOVE) { + float deltaX = position.x - mStartDragPosition.x; + float deltaY = position.y - mStartDragPosition.y; + + mDrawRectangle = new RectF(mScaledRectangle); + mDrawRectangle.offset(deltaX, deltaY); + } else if (mType == DragType.EXTEND) { + adaptDrawRectangle(position.x, position.y); + } + mTriggerSinglePress = false; + } + + /** + * Dragging has ended. + * @param position - last position of the drag + */ + public void dragEnd(PointF position) { + PointF point = new PointF(); + if (mDragHandle != null) { + point.x = mDragHandle.mPosition.x; + point.y = mDragHandle.mPosition.y; + mDragHandle.reset(); + mDragHandle = null; + } else { + point.x = mStartDragPosition.x; + point.y = mStartDragPosition.y; + } + float deltaX = position.x - mStartDragPosition.x; + float deltaY = position.y - mStartDragPosition.y; + point.offset(deltaX, deltaY); + + sendGraphicSelectionEnd(point); + + if (mTriggerSinglePress && mDragHandle == null) { + onSinglePress(point); + mTriggerSinglePress = false; + } + + mDrawRectangle = mScaledRectangle; + mType = DragType.NONE; + } + + /** + * Adapt the selection depending on which handle was dragged. + */ + private void adaptDrawRectangle(float x, float y) { + mDrawRectangle = new RectF(mScaledRectangle); + switch(mDragHandle.getHandlePosition()) { + case TOP_LEFT: + mDrawRectangle.left = x; + mDrawRectangle.top = y; + break; + case TOP: + mDrawRectangle.top = y; + break; + case TOP_RIGHT: + mDrawRectangle.right = x; + mDrawRectangle.top = y; + break; + case LEFT: + mDrawRectangle.left = x; + break; + case RIGHT: + mDrawRectangle.right = x; + break; + case BOTTOM_LEFT: + mDrawRectangle.left = x; + mDrawRectangle.bottom = y; + break; + case BOTTOM: + mDrawRectangle.bottom = y; + break; + case BOTTOM_RIGHT: + mDrawRectangle.right = x; + mDrawRectangle.bottom = y; + break; + } + } + + /** + * Send graphic selection start event to LOKitTread. + * @param screenPosition - screen position of the selection + */ + private void sendGraphicSelectionStart(PointF screenPosition) { + sendGraphicSelection("GraphicSelectionStart", screenPosition); + } + + /** + * Send graphic selection end event to LOKitTread. + * @param screenPosition - screen position of the selection + */ + private void sendGraphicSelectionEnd(PointF screenPosition) { + sendGraphicSelection("GraphicSelectionEnd", screenPosition); + } + + /** + * Send graphic selection event to LOKitTread. + * @param type - type of the graphic selection + * @param screenPosition - screen position of the selection + */ + private void sendGraphicSelection(String type, PointF screenPosition) + { + LayerView layerView = mContext.getLayerClient().getView(); + if (layerView != null) { + // Position is in screen coordinates. We need to convert them to + // document coordinates. + PointF documentPoint = layerView.getLayerClient().convertViewPointToLayerPoint(screenPosition); + LOKitShell.sendTouchEvent(type, documentPoint); + } + } + + /** + * When a single press (no dragging happened) was performed. + */ + private void onSinglePress(PointF screenPosition) { + sendGraphicSelection("LongPress", screenPosition); + } + + /** + * Set the visibility of the graphic selection. + */ + @Override + public void setVisible(boolean visible) { + super.setVisible(visible); + for (GraphicSelectionHandle handle: mHandles) { + handle.setVisible(visible); + } + } + + /** + * Reset the selection. + */ + public void reset() { + mDragHandle = null; + for (GraphicSelectionHandle handle : mHandles) { + handle.reset(); + } + } + + /** + * Type of the selection dragging. + */ + public enum DragType { + NONE, + MOVE, + EXTEND + } +} +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |