OLD | NEW |
| (Empty) |
1 // Copyright 2012 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 package org.chromium.content.browser.input; | |
6 | |
7 import android.view.View; | |
8 | |
9 import com.google.common.annotations.VisibleForTesting; | |
10 | |
11 import org.chromium.content.browser.PositionObserver; | |
12 | |
13 /** | |
14 * CursorController for selecting a range of text. | |
15 */ | |
16 public abstract class SelectionHandleController implements CursorController { | |
17 | |
18 // The following constants match the ones in | |
19 // third_party/WebKit/public/web/WebTextDirection.h | |
20 private static final int TEXT_DIRECTION_DEFAULT = 0; | |
21 private static final int TEXT_DIRECTION_LTR = 1; | |
22 private static final int TEXT_DIRECTION_RTL = 2; | |
23 | |
24 /** The cursor controller images, lazily created when shown. */ | |
25 private HandleView mStartHandle, mEndHandle; | |
26 | |
27 /** Whether handles should show automatically when text is selected. */ | |
28 private boolean mAllowAutomaticShowing = true; | |
29 | |
30 /** Whether selection anchors are active. */ | |
31 private boolean mIsShowing; | |
32 | |
33 private View mParent; | |
34 | |
35 private int mFixedHandleX; | |
36 private int mFixedHandleY; | |
37 | |
38 private PositionObserver mPositionObserver; | |
39 | |
40 public SelectionHandleController(View parent, PositionObserver positionObser
ver) { | |
41 mParent = parent; | |
42 mPositionObserver = positionObserver; | |
43 } | |
44 | |
45 /** Automatically show selection anchors when text is selected. */ | |
46 public void allowAutomaticShowing() { | |
47 mAllowAutomaticShowing = true; | |
48 } | |
49 | |
50 /** Hide selection anchors, and don't automatically show them. */ | |
51 public void hideAndDisallowAutomaticShowing() { | |
52 hide(); | |
53 mAllowAutomaticShowing = false; | |
54 } | |
55 | |
56 @Override | |
57 public boolean isShowing() { | |
58 return mIsShowing; | |
59 } | |
60 | |
61 @Override | |
62 public void hide() { | |
63 if (mIsShowing) { | |
64 if (mStartHandle != null) mStartHandle.hide(); | |
65 if (mEndHandle != null) mEndHandle.hide(); | |
66 mIsShowing = false; | |
67 } | |
68 } | |
69 | |
70 void cancelFadeOutAnimation() { | |
71 hide(); | |
72 } | |
73 | |
74 /** | |
75 * Updates the selection for a movement of the given handle (which | |
76 * should be the start handle or end handle) to coordinates x,y. | |
77 * Note that this will not actually result in the handle moving to (x,y): | |
78 * selectBetweenCoordinates(x1,y1,x2,y2) will trigger the selection and set
the | |
79 * actual coordinates later via set[Start|End]HandlePosition. | |
80 */ | |
81 @Override | |
82 public void updatePosition(HandleView handle, int x, int y) { | |
83 selectBetweenCoordinates(mFixedHandleX, mFixedHandleY, x, y); | |
84 } | |
85 | |
86 @Override | |
87 public void beforeStartUpdatingPosition(HandleView handle) { | |
88 HandleView fixedHandle = (handle == mStartHandle) ? mEndHandle : mStartH
andle; | |
89 mFixedHandleX = fixedHandle.getAdjustedPositionX(); | |
90 mFixedHandleY = fixedHandle.getLineAdjustedPositionY(); | |
91 } | |
92 | |
93 /** | |
94 * The concrete implementation must trigger a selection between the given | |
95 * coordinates and (possibly asynchronously) set the actual handle positions | |
96 * after the selection is made via set[Start|End]HandlePosition. | |
97 */ | |
98 protected abstract void selectBetweenCoordinates(int x1, int y1, int x2, int
y2); | |
99 | |
100 /** | |
101 * @return true iff this controller is being used to move the selection star
t. | |
102 */ | |
103 boolean isSelectionStartDragged() { | |
104 return mStartHandle != null && mStartHandle.isDragging(); | |
105 } | |
106 | |
107 /** | |
108 * @return true iff this controller is being used to drag either the selecti
on start or end. | |
109 */ | |
110 public boolean isDragging() { | |
111 return (mStartHandle != null && mStartHandle.isDragging()) || | |
112 (mEndHandle != null && mEndHandle.isDragging()); | |
113 } | |
114 | |
115 @Override | |
116 public void onTouchModeChanged(boolean isInTouchMode) { | |
117 if (!isInTouchMode) { | |
118 hide(); | |
119 } | |
120 } | |
121 | |
122 @Override | |
123 public void onDetached() {} | |
124 | |
125 /** | |
126 * Moves the start handle so that it points at the given coordinates. | |
127 * @param x The start handle position X in physical pixels. | |
128 * @param y The start handle position Y in physical pixels. | |
129 */ | |
130 public void setStartHandlePosition(float x, float y) { | |
131 mStartHandle.positionAt((int) x, (int) y); | |
132 } | |
133 | |
134 /** | |
135 * Moves the end handle so that it points at the given coordinates. | |
136 * @param x The end handle position X in physical pixels. | |
137 * @param y The end handle position Y in physical pixels. | |
138 */ | |
139 public void setEndHandlePosition(float x, float y) { | |
140 mEndHandle.positionAt((int) x, (int) y); | |
141 } | |
142 | |
143 /** | |
144 * If the handles are not visible, sets their visibility to View.VISIBLE and
begins fading them | |
145 * in. | |
146 */ | |
147 public void beginHandleFadeIn() { | |
148 mStartHandle.beginFadeIn(); | |
149 mEndHandle.beginFadeIn(); | |
150 } | |
151 | |
152 /** | |
153 * Sets the start and end handles to the given visibility. | |
154 */ | |
155 public void setHandleVisibility(int visibility) { | |
156 mStartHandle.setVisibility(visibility); | |
157 mEndHandle.setVisibility(visibility); | |
158 } | |
159 | |
160 /** | |
161 * Shows the handles if allowed. | |
162 * | |
163 * @param startDir Direction (left/right) of start handle. | |
164 * @param endDir Direction (left/right) of end handle. | |
165 */ | |
166 public void onSelectionChanged(int startDir, int endDir) { | |
167 if (mAllowAutomaticShowing) { | |
168 showHandles(startDir, endDir); | |
169 } | |
170 } | |
171 | |
172 /** | |
173 * Sets both start and end position and show the handles. | |
174 * Note: this method does not trigger a selection, see | |
175 * selectBetweenCoordinates() | |
176 * | |
177 * @param startDir Direction (left/right) of start handle. | |
178 * @param endDir Direction (left/right) of end handle. | |
179 */ | |
180 public void showHandles(int startDir, int endDir) { | |
181 createHandlesIfNeeded(startDir, endDir); | |
182 showHandlesIfNeeded(); | |
183 } | |
184 | |
185 @VisibleForTesting | |
186 public HandleView getStartHandleViewForTest() { | |
187 return mStartHandle; | |
188 } | |
189 | |
190 @VisibleForTesting | |
191 public HandleView getEndHandleViewForTest() { | |
192 return mEndHandle; | |
193 } | |
194 | |
195 private void createHandlesIfNeeded(int startDir, int endDir) { | |
196 if (mStartHandle == null) { | |
197 mStartHandle = new HandleView(this, | |
198 startDir == TEXT_DIRECTION_RTL ? HandleView.RIGHT : HandleVi
ew.LEFT, mParent, | |
199 mPositionObserver); | |
200 } | |
201 if (mEndHandle == null) { | |
202 mEndHandle = new HandleView(this, | |
203 endDir == TEXT_DIRECTION_RTL ? HandleView.LEFT : HandleView.
RIGHT, mParent, | |
204 mPositionObserver); | |
205 } | |
206 } | |
207 | |
208 private void showHandlesIfNeeded() { | |
209 if (!mIsShowing) { | |
210 mIsShowing = true; | |
211 mStartHandle.show(); | |
212 mEndHandle.show(); | |
213 setHandleVisibility(HandleView.VISIBLE); | |
214 } | |
215 } | |
216 } | |
OLD | NEW |