Index: ui/android/java/src/org/chromium/ui/base/ViewAndroidDelegate.java |
diff --git a/ui/android/java/src/org/chromium/ui/base/ViewAndroidDelegate.java b/ui/android/java/src/org/chromium/ui/base/ViewAndroidDelegate.java |
index a97b7565637c7985b9fb71bde689944900d053ec..cf0298ccabe0d8084d1bd0e574c8938e1c527f4e 100644 |
--- a/ui/android/java/src/org/chromium/ui/base/ViewAndroidDelegate.java |
+++ b/ui/android/java/src/org/chromium/ui/base/ViewAndroidDelegate.java |
@@ -4,39 +4,127 @@ |
package org.chromium.ui.base; |
+import android.content.ClipData; |
import android.graphics.Bitmap; |
import android.view.View; |
+import android.view.ViewGroup; |
+import android.widget.FrameLayout.LayoutParams; |
+import android.widget.ImageView; |
+ |
+import org.chromium.base.ApiCompatibilityUtils; |
+import org.chromium.base.annotations.CalledByNative; |
+import org.chromium.base.annotations.JNINamespace; |
/** |
- * Interface to acquire and release anchor views from the implementing View. |
+ * Class to acquire, position, and remove anchor views from the implementing View. |
*/ |
-public interface ViewAndroidDelegate { |
+@JNINamespace("ui") |
+public abstract class ViewAndroidDelegate { |
+ |
+ // TODO(hush): use View#DRAG_FLAG_GLOBAL when Chromium starts to build with API 24. |
+ private static final int DRAG_FLAG_GLOBAL = 1 << 8; |
/** |
* @return An anchor view that can be used to anchor decoration views like Autofill popup. |
*/ |
- View acquireAnchorView(); |
+ @CalledByNative |
+ public View acquireView() { |
+ ViewGroup containerView = getContainerView(); |
+ if (containerView == null) return null; |
+ View anchorView = new View(containerView.getContext()); |
+ containerView.addView(anchorView); |
+ return anchorView; |
+ } |
+ |
+ /** |
+ * Release given anchor view. |
+ * @param anchorView The anchor view that needs to be released. |
+ */ |
+ @CalledByNative |
+ public void removeView(View anchorView) { |
+ ViewGroup containerView = getContainerView(); |
+ if (containerView == null) return; |
+ containerView.removeView(anchorView); |
+ } |
/** |
- * Set the anchor view to specified position and width (all units in dp). |
+ * Set the anchor view to specified position and size (all units in dp). |
* @param view The anchor view that needs to be positioned. |
* @param x X coordinate of the top left corner of the anchor view. |
* @param y Y coordinate of the top left corner of the anchor view. |
* @param width The width of the anchor view. |
* @param height The height of the anchor view. |
*/ |
- void setAnchorViewPosition(View view, float x, float y, float width, float height); |
+ @CalledByNative |
+ public void setViewPosition(View view, float x, float y, |
+ float width, float height, float scale, int leftMargin, int topMargin) { |
+ ViewGroup containerView = getContainerView(); |
+ if (containerView == null) return; |
- /** |
- * Release given anchor view. |
- * @param anchorView The anchor view that needs to be released. |
- */ |
- void releaseAnchorView(View anchorView); |
+ int scaledWidth = Math.round(width * scale); |
+ int scaledHeight = Math.round(height * scale); |
+ int startMargin; |
+ |
+ if (ApiCompatibilityUtils.isLayoutRtl(containerView)) { |
+ startMargin = containerView.getMeasuredWidth() - Math.round((width + x) * scale); |
+ } else { |
+ startMargin = leftMargin; |
+ } |
+ if (scaledWidth + startMargin > containerView.getWidth()) { |
+ scaledWidth = containerView.getWidth() - startMargin; |
+ } |
+ LayoutParams lp = new LayoutParams(scaledWidth, scaledHeight); |
+ ApiCompatibilityUtils.setMarginStart(lp, startMargin); |
+ lp.topMargin = topMargin; |
+ view.setLayoutParams(lp); |
+ } |
/** |
* Drag the text out of current view. |
* @param text The dragged text. |
* @param shadowImage The shadow image for the dragged text. |
*/ |
- void startDragAndDrop(String text, Bitmap shadowImage); |
+ @SuppressWarnings("deprecation") |
+ @CalledByNative |
+ private void startDragAndDrop(String text, Bitmap shadowImage) { |
+ ClipData data = ClipData.newPlainText(null, text); |
+ |
+ ViewGroup containerView = getContainerView(); |
+ if (containerView == null) return; |
+ |
+ ImageView imageView = new ImageView(containerView.getContext()); |
+ imageView.setImageBitmap(shadowImage); |
+ imageView.layout(0, 0, shadowImage.getWidth(), shadowImage.getHeight()); |
+ |
+ // TODO(hush): use View#startDragAndDrop when Chromium starts to build with API 24. |
+ containerView.startDrag( |
+ data, new View.DragShadowBuilder(imageView), null, DRAG_FLAG_GLOBAL); |
+ } |
+ |
+ /** |
+ * @return container view that the anchor views are added to. May be null. |
+ */ |
+ public abstract ViewGroup getContainerView(); |
+ |
+ /** |
+ * Create and return a basic implementation of {@link ViewAndroidDelegate} where |
+ * the container view is not allowed to be changed after initialization. |
+ * @param containerView {@link ViewGroup} to be used as a container view. |
+ * @return a new instance of {@link ViewAndroidDelegate}. |
+ */ |
+ public static ViewAndroidDelegate createBasicDelegate(ViewGroup containerView) { |
+ return new ViewAndroidDelegate() { |
+ private ViewGroup mContainerView; |
+ |
+ private ViewAndroidDelegate init(ViewGroup containerView) { |
+ mContainerView = containerView; |
+ return this; |
+ } |
+ |
+ @Override |
+ public ViewGroup getContainerView() { |
+ return mContainerView; |
+ } |
+ }.init(containerView); |
+ } |
} |