Index: chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/components/CompositorButton.java |
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/components/CompositorButton.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/components/CompositorButton.java |
new file mode 100644 |
index 0000000000000000000000000000000000000000..1d40c0f2e0033fe4a9c31963d4ebad9614599550 |
--- /dev/null |
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/components/CompositorButton.java |
@@ -0,0 +1,347 @@ |
+// Copyright 2015 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+package org.chromium.chrome.browser.compositor.layouts.components; |
+ |
+import android.content.Context; |
+import android.content.res.Resources; |
+import android.graphics.RectF; |
+ |
+import org.chromium.chrome.R; |
+import org.chromium.chrome.browser.compositor.layouts.ChromeAnimation; |
+ |
+/** |
+ * {@link CompositorButton} keeps track of state for buttons that are rendered |
+ * in the compositor. |
+ */ |
+public class CompositorButton |
+ implements ChromeAnimation.Animatable<CompositorButton.Property>, VirtualView { |
+ /** |
+ * Animatable properties that can be used with a {@link ChromeAnimation.Animatable} on a |
+ * {@link CompositorButton}. |
+ */ |
+ public enum Property { |
+ OPACITY, |
+ } |
+ |
+ // Precached bounds rect. |
+ private final RectF mBounds = new RectF(); |
+ |
+ private int mResource; |
+ private int mPressedResource; |
+ private int mIncognitoResource; |
+ private int mIncognitoPressedResource; |
+ |
+ private float mOpacity; |
+ private float mClickSlop; |
+ private boolean mIsPressed; |
+ private boolean mIsVisible; |
+ private boolean mIsIncognito; |
+ private boolean mIsEnabled; |
+ private String mAccessibilityDescription; |
+ private String mAccessibilityDescriptionIncognito; |
+ |
+ private final RectF mCacheBounds = new RectF(); // Pre-allocated to avoid in-frame allocations. |
+ |
+ /** |
+ * Default constructor for {@link CompositorButton} |
+ * @param context An Android context for fetching dimens. |
+ * @param width The button width. |
+ * @param height The button height. |
+ */ |
+ public CompositorButton(Context context, float width, float height) { |
+ mBounds.set(0, 0, width, height); |
+ |
+ mOpacity = 1.f; |
+ mIsPressed = false; |
+ mIsVisible = true; |
+ mIsIncognito = false; |
+ mIsEnabled = true; |
+ |
+ Resources res = context.getResources(); |
+ float sPxToDp = 1.0f / res.getDisplayMetrics().density; |
+ mClickSlop = res.getDimension(R.dimen.compositor_button_slop) * sPxToDp; |
+ } |
+ |
+ /** |
+ * Secondary constructor for {@link CompositorButton} |
+ * @param context An Android context for fetching dimens. |
+ * @param bounds A RectF that bounds the button. |
+ */ |
+ public CompositorButton(Context context, RectF bounds) { |
+ this(context, bounds.width(), bounds.height()); |
+ mBounds.set(bounds); |
+ } |
+ |
+ /** |
+ * A set of Android resources to supply to the compositor. |
+ * @param resource The default Android resource. |
+ * @param pressedResource The pressed Android resource. |
+ * @param incognitoResource The incognito Android resource. |
+ * @param incognitoPressedResource The incognito pressed resource. |
+ */ |
+ public void setResources(int resource, int presssedResource, int incognitoResource, |
+ int incognitoPressedResource) { |
+ mResource = resource; |
+ mPressedResource = presssedResource; |
+ mIncognitoResource = incognitoResource; |
+ mIncognitoPressedResource = incognitoPressedResource; |
+ } |
+ |
+ /** |
+ * @param description A string describing the resource. |
+ */ |
+ public void setAccessibilityDescription(String description, String incognitoDescription) { |
+ mAccessibilityDescription = description; |
+ mAccessibilityDescriptionIncognito = incognitoDescription; |
+ } |
+ |
+ @Override |
+ public String getAccessibilityDescription() { |
+ return mIsIncognito ? mAccessibilityDescriptionIncognito : mAccessibilityDescription; |
+ } |
+ |
+ @Override |
+ public void getTouchTarget(RectF outTarget) { |
+ outTarget.set(mBounds); |
+ // Get the whole touchable region. |
+ outTarget.inset((int) -mClickSlop, (int) -mClickSlop); |
+ } |
+ |
+ /** |
+ * @return The the x offset of the button. |
+ */ |
+ public float getX() { |
+ return mBounds.left; |
+ } |
+ |
+ /** |
+ * @param x The x offset of the button. |
+ */ |
+ public void setX(float x) { |
+ mBounds.right = x + mBounds.width(); |
+ mBounds.left = x; |
+ } |
+ |
+ /** |
+ * @return The y offset of the button. |
+ */ |
+ public float getY() { |
+ return mBounds.top; |
+ } |
+ |
+ /** |
+ * @param y The y offset of the button. |
+ */ |
+ public void setY(float y) { |
+ mBounds.bottom = y + mBounds.height(); |
+ mBounds.top = y; |
+ } |
+ |
+ /** |
+ * @return The width of the button. |
+ */ |
+ public float getWidth() { |
+ return mBounds.width(); |
+ } |
+ |
+ /** |
+ * @param width The width of the button. |
+ */ |
+ public void setWidth(float width) { |
+ mBounds.right = mBounds.left + width; |
+ } |
+ |
+ /** |
+ * @return The height of the button. |
+ */ |
+ public float getHeight() { |
+ return mBounds.height(); |
+ } |
+ |
+ /** |
+ * @param height The height of the button. |
+ */ |
+ public void setHeight(float height) { |
+ mBounds.bottom = mBounds.top + height; |
+ } |
+ |
+ /** |
+ * @param bounds A {@link Rect} representing the location of the button. |
+ */ |
+ public void setBounds(RectF bounds) { |
+ mBounds.set(bounds); |
+ } |
+ |
+ /** |
+ * @return The opacity of the button. |
+ */ |
+ public float getOpacity() { |
+ return mOpacity; |
+ } |
+ |
+ /** |
+ * @param opacity The opacity of the button. |
+ */ |
+ public void setOpacity(float opacity) { |
+ mOpacity = opacity; |
+ } |
+ |
+ /** |
+ * @return The pressed state of the button. |
+ */ |
+ public boolean isPressed() { |
+ return mIsPressed; |
+ } |
+ |
+ /** |
+ * @param state The pressed state of the button. |
+ */ |
+ public void setPressed(boolean state) { |
+ mIsPressed = state; |
+ } |
+ |
+ /** |
+ * @return The visiblity of the button. |
+ */ |
+ public boolean isVisible() { |
+ return mIsVisible; |
+ } |
+ |
+ /** |
+ * @param state The visibility of the button. |
+ */ |
+ public void setVisible(boolean state) { |
+ mIsVisible = state; |
+ } |
+ |
+ /** |
+ * @return The incognito state of the button. |
+ */ |
+ public boolean isIncognito() { |
+ return mIsIncognito; |
+ } |
+ |
+ /** |
+ * @param state The incognito state of the button. |
+ */ |
+ public void setIncognito(boolean state) { |
+ mIsIncognito = state; |
+ } |
+ |
+ /** |
+ * @return Whether or not the button can be interacted with. |
+ */ |
+ public boolean isEnabled() { |
+ return mIsEnabled; |
+ } |
+ |
+ /** |
+ * @param state Whether or not the button can be interacted with. |
+ */ |
+ public void setEnabled(boolean enabled) { |
+ mIsEnabled = enabled; |
+ } |
+ |
+ /** |
+ * @param slop The additional area outside of the button to be considered when |
+ * checking click target bounds. |
+ */ |
+ public void setClickSlop(float slop) { |
+ mClickSlop = slop; |
+ } |
+ |
+ /** |
+ * @return The Android resource id for this button based on it's state. |
+ */ |
+ public int getResourceId() { |
+ if (isPressed()) { |
+ return isIncognito() ? mIncognitoPressedResource : mPressedResource; |
+ } |
+ return isIncognito() ? mIncognitoResource : mResource; |
+ } |
+ |
+ /** |
+ * @param x The x offset of the click. |
+ * @param y The y offset of the click. |
+ * @return Whether or not that click occurred inside of the button + slop area. |
+ */ |
+ @Override |
+ public boolean checkClicked(float x, float y) { |
+ if (mOpacity < 1.f || !mIsVisible || !mIsEnabled) return false; |
+ |
+ mCacheBounds.set(mBounds); |
+ mCacheBounds.inset(-mClickSlop, -mClickSlop); |
+ return mCacheBounds.contains(x, y); |
+ } |
+ |
+ /** |
+ * Set state for a drag event. |
+ * @param x The x offset of the event. |
+ * @param y The y offset of the event. |
+ * @return Whether or not the button is selected after the event. |
+ */ |
+ public boolean drag(float x, float y) { |
+ if (!checkClicked(x, y)) { |
+ setPressed(false); |
+ return false; |
+ } |
+ return isPressed(); |
+ } |
+ |
+ /** |
+ * Set state for an onDown event. |
+ * @param x The x offset of the event. |
+ * @param y The y offset of the event. |
+ * @return Whether or not the close button was selected. |
+ */ |
+ public boolean onDown(float x, float y) { |
+ if (checkClicked(x, y)) { |
+ setPressed(true); |
+ return true; |
+ } |
+ return false; |
+ } |
+ |
+ /** |
+ * @param x The x offset of the event. |
+ * @param y The y offset of the event. |
+ * @return If the button was clicked or not. |
+ */ |
+ public boolean click(float x, float y) { |
+ if (checkClicked(x, y)) { |
+ setPressed(false); |
+ return true; |
+ } |
+ return false; |
+ } |
+ |
+ /** |
+ * Set state for an onUpOrCancel event. |
+ * @return Whether or not the button was selected. |
+ */ |
+ public boolean onUpOrCancel() { |
+ boolean state = isPressed(); |
+ setPressed(false); |
+ return state; |
+ } |
+ |
+ /** |
+ * Callback for {@link org.chromium.chrome.browser.compositor.layouts.ChromeAnimation |
+ * .Animatable} |
+ * |
+ * @param prop The property to set |
+ * @param val The value to set it to |
+ */ |
+ @Override |
+ public void setProperty(Property prop, float val) { |
+ switch (prop) { |
+ case OPACITY: |
+ setOpacity(val); |
+ break; |
+ default: |
+ // Do nothing. |
+ } |
+ } |
+} |