1 /* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 package org
.libreoffice
.canvas
;
11 import android
.graphics
.Canvas
;
12 import android
.graphics
.Color
;
13 import android
.graphics
.Paint
;
14 import android
.graphics
.PointF
;
15 import android
.graphics
.RectF
;
17 import org
.libreoffice
.LOKitShell
;
18 import org
.libreoffice
.LibreOfficeMainActivity
;
19 import org
.mozilla
.gecko
.gfx
.LayerView
;
21 import static org
.libreoffice
.canvas
.GraphicSelectionHandle
.HandlePosition
;
24 * This class is responsible to draw and reposition the selection
27 public class GraphicSelection
extends CommonCanvasElement
{
28 private final Paint mPaintStroke
;
29 private final Paint mPaintFill
;
30 public RectF mRectangle
= new RectF();
31 public RectF mScaledRectangle
= new RectF();
32 private RectF mDrawRectangle
= new RectF();
33 private DragType mType
= DragType
.NONE
;
34 private PointF mStartDragPosition
;
36 private GraphicSelectionHandle mHandles
[] = new GraphicSelectionHandle
[8];
37 private GraphicSelectionHandle mDragHandle
= null;
38 private boolean mTriggerSinglePress
= false;
39 private LibreOfficeMainActivity mContext
;
42 * Construct the graphic selection.
44 public GraphicSelection(LibreOfficeMainActivity context
) {
46 // Create the paint, which is needed at drawing
47 mPaintStroke
= new Paint();
48 mPaintStroke
.setStyle(Paint
.Style
.STROKE
);
49 mPaintStroke
.setColor(Color
.GRAY
);
50 mPaintStroke
.setStrokeWidth(2);
51 mPaintStroke
.setAntiAlias(true);
53 mPaintFill
= new Paint();
54 mPaintFill
.setStyle(Paint
.Style
.FILL
);
55 mPaintFill
.setColor(Color
.WHITE
);
56 mPaintFill
.setAlpha(200);
57 mPaintFill
.setAntiAlias(true);
59 // Create the handles of the selection
60 mHandles
[0] = new GraphicSelectionHandle(HandlePosition
.TOP_LEFT
);
61 mHandles
[1] = new GraphicSelectionHandle(HandlePosition
.TOP
);
62 mHandles
[2] = new GraphicSelectionHandle(HandlePosition
.TOP_RIGHT
);
63 mHandles
[3] = new GraphicSelectionHandle(HandlePosition
.LEFT
);
64 mHandles
[4] = new GraphicSelectionHandle(HandlePosition
.RIGHT
);
65 mHandles
[5] = new GraphicSelectionHandle(HandlePosition
.BOTTOM_LEFT
);
66 mHandles
[6] = new GraphicSelectionHandle(HandlePosition
.BOTTOM
);
67 mHandles
[7] = new GraphicSelectionHandle(HandlePosition
.BOTTOM_RIGHT
);
71 * Viewport has changed, reposition the selection to the new rectangle.
72 * @param scaledRectangle - rectangle of selection position on the document
74 public void reposition(RectF scaledRectangle
) {
75 mScaledRectangle
= scaledRectangle
;
76 mDrawRectangle
= scaledRectangle
; // rectangle that will be draw
78 // reposition the handles too
79 mHandles
[0].reposition(scaledRectangle
.left
, scaledRectangle
.top
);
80 mHandles
[1].reposition(scaledRectangle
.centerX(), scaledRectangle
.top
);
81 mHandles
[2].reposition(scaledRectangle
.right
, scaledRectangle
.top
);
82 mHandles
[3].reposition(scaledRectangle
.left
, scaledRectangle
.centerY());
83 mHandles
[4].reposition(scaledRectangle
.right
, scaledRectangle
.centerY());
84 mHandles
[5].reposition(scaledRectangle
.left
, scaledRectangle
.bottom
);
85 mHandles
[6].reposition(scaledRectangle
.centerX(), scaledRectangle
.bottom
);
86 mHandles
[7].reposition(scaledRectangle
.right
, scaledRectangle
.bottom
);
90 * Hit test for the selection.
91 * @see org.libreoffice.canvas.CanvasElement#draw(android.graphics.Canvas)
94 public boolean onHitTest(float x
, float y
) {
95 // Check if handle was hit
96 for (GraphicSelectionHandle handle
: mHandles
) {
97 if (handle
.contains(x
, y
)) {
101 return mScaledRectangle
.contains(x
, y
);
105 * Draw the selection on the canvas.
106 * @see org.libreoffice.canvas.CanvasElement#draw(android.graphics.Canvas)
109 public void onDraw(Canvas canvas
) {
110 canvas
.drawRect(mDrawRectangle
, mPaintStroke
);
111 if (mType
!= DragType
.NONE
) {
112 canvas
.drawRect(mDrawRectangle
, mPaintFill
);
114 for (GraphicSelectionHandle handle
: mHandles
) {
120 * Dragging on the screen has started.
121 * @param position - position where the dragging started
123 public void dragStart(PointF position
) {
125 mType
= DragType
.NONE
;
126 for (GraphicSelectionHandle handle
: mHandles
) {
127 if (handle
.contains(position
.x
, position
.y
)) {
128 mDragHandle
= handle
;
129 mDragHandle
.select();
130 mType
= DragType
.EXTEND
;
131 sendGraphicSelectionStart(handle
.mPosition
);
134 if (mDragHandle
== null) {
135 mType
= DragType
.MOVE
;
136 sendGraphicSelectionStart(position
);
138 mStartDragPosition
= position
;
139 mTriggerSinglePress
= true;
143 * Dragging is in process.
144 * @param position - position of the drag
146 public void dragging(PointF position
) {
147 if (mType
== DragType
.MOVE
) {
148 float deltaX
= position
.x
- mStartDragPosition
.x
;
149 float deltaY
= position
.y
- mStartDragPosition
.y
;
151 mDrawRectangle
= new RectF(mScaledRectangle
);
152 mDrawRectangle
.offset(deltaX
, deltaY
);
153 } else if (mType
== DragType
.EXTEND
) {
154 adaptDrawRectangle(position
.x
, position
.y
);
156 mTriggerSinglePress
= false;
160 * Dragging has ended.
161 * @param position - last position of the drag
163 public void dragEnd(PointF position
) {
164 PointF point
= new PointF();
165 if (mDragHandle
!= null) {
166 point
.x
= mDragHandle
.mPosition
.x
;
167 point
.y
= mDragHandle
.mPosition
.y
;
171 point
.x
= mStartDragPosition
.x
;
172 point
.y
= mStartDragPosition
.y
;
174 float deltaX
= position
.x
- mStartDragPosition
.x
;
175 float deltaY
= position
.y
- mStartDragPosition
.y
;
176 point
.offset(deltaX
, deltaY
);
178 sendGraphicSelectionEnd(point
);
180 if (mTriggerSinglePress
&& mDragHandle
== null) {
181 onSinglePress(point
);
182 mTriggerSinglePress
= false;
185 mDrawRectangle
= mScaledRectangle
;
186 mType
= DragType
.NONE
;
190 * Adapt the selection depending on which handle was dragged.
192 private void adaptDrawRectangle(float x
, float y
) {
193 mDrawRectangle
= new RectF(mScaledRectangle
);
194 switch(mDragHandle
.getHandlePosition()) {
196 mDrawRectangle
.left
= x
;
197 mDrawRectangle
.top
= y
;
200 mDrawRectangle
.top
= y
;
203 mDrawRectangle
.right
= x
;
204 mDrawRectangle
.top
= y
;
207 mDrawRectangle
.left
= x
;
210 mDrawRectangle
.right
= x
;
213 mDrawRectangle
.left
= x
;
214 mDrawRectangle
.bottom
= y
;
217 mDrawRectangle
.bottom
= y
;
220 mDrawRectangle
.right
= x
;
221 mDrawRectangle
.bottom
= y
;
227 * Send graphic selection start event to LOKitTread.
228 * @param screenPosition - screen position of the selection
230 private void sendGraphicSelectionStart(PointF screenPosition
) {
231 sendGraphicSelection("GraphicSelectionStart", screenPosition
);
235 * Send graphic selection end event to LOKitTread.
236 * @param screenPosition - screen position of the selection
238 private void sendGraphicSelectionEnd(PointF screenPosition
) {
239 sendGraphicSelection("GraphicSelectionEnd", screenPosition
);
243 * Send graphic selection event to LOKitTread.
244 * @param type - type of the graphic selection
245 * @param screenPosition - screen position of the selection
247 private void sendGraphicSelection(String type
, PointF screenPosition
)
249 LayerView layerView
= mContext
.getLayerClient().getView();
250 if (layerView
!= null) {
251 // Position is in screen coordinates. We need to convert them to
252 // document coordinates.
253 PointF documentPoint
= layerView
.getLayerClient().convertViewPointToLayerPoint(screenPosition
);
254 LOKitShell
.sendTouchEvent(type
, documentPoint
);
259 * When a single press (no dragging happened) was performed.
261 private void onSinglePress(PointF screenPosition
) {
262 sendGraphicSelection("LongPress", screenPosition
);
266 * Set the visibility of the graphic selection.
269 public void setVisible(boolean visible
) {
270 super.setVisible(visible
);
271 for (GraphicSelectionHandle handle
: mHandles
) {
272 handle
.setVisible(visible
);
277 * Reset the selection.
279 public void reset() {
281 for (GraphicSelectionHandle handle
: mHandles
) {
287 * Type of the selection dragging.
289 public enum DragType
{
295 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */