/* 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 com.linkbubble.ui;
import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.AnticipateOvershootInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.LinearInterpolator;
import android.view.animation.Transformation;
import android.widget.FrameLayout;
import android.widget.ImageView;
import com.linkbubble.Constant;
import com.linkbubble.MainController;
import com.linkbubble.R;
import com.linkbubble.Settings;
import com.linkbubble.util.ScaleUpAnimHelper;
import com.linkbubble.util.Util;
import org.mozilla.gecko.favicons.Favicons;
import java.net.MalformedURLException;
import java.net.URL;
public class TabView extends BubbleView {
private ContentView mContentView;
private ImageView mBackIndicatorView;
private ScaleUpAnimHelper mBackIndicatorAnimHelper;
private boolean mPerformEmptyClick;
private int mOriginalParamsTopMargin;
private FrameLayout.LayoutParams mOriginalParams;
private float mOriginalLocationY;
private int mOriginalBottomMargin;
public boolean mWasRestored;
public boolean mIsClosing;
public TabView(Context context) {
this(context, null);
}
public TabView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public TabView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
void configure(String url, long urlLoadStartTime, boolean hasShownAppPicker, boolean performEmptyClick) throws MalformedURLException {
super.configure(url);
mPerformEmptyClick = performEmptyClick;
mBackIndicatorView = (ImageView) findViewById(R.id.back_indicator);
if (Settings.get().getDarkThemeEnabled()) {
mBackIndicatorView.setBackgroundResource(R.drawable.badge_plate_dark);
mBackIndicatorView.setImageResource(R.drawable.ic_action_arrow_left_white);
} else {
mBackIndicatorView.setBackgroundResource(R.drawable.badge_plate);
mBackIndicatorView.setImageResource(R.drawable.ic_action_arrow_left);
}
mBackIndicatorAnimHelper = new ScaleUpAnimHelper(mBackIndicatorView, 1.0f);
mBackIndicatorAnimHelper.hide();
mContentView = (ContentView)inflate(getContext(), R.layout.view_content, null);
mContentView.configure(mUrl.toString(), this, urlLoadStartTime, hasShownAppPicker, new ContentView.EventHandler() {
@Override
public void onPageLoading(URL url) {
boolean setDefaultFavicon = true;
URL previousUrl = mUrl;
mUrl = url;
showProgressBar(0);
if (previousUrl != null && previousUrl.getHost().equals(mUrl.getHost()) && mFaviconLoadId == Favicons.LOADED) {
setDefaultFavicon = false;
} else {
loadFavicon();
if (mFaviconLoadId == Favicons.LOADED || mFaviconLoadId == Favicons.NOT_LOADING) {
setDefaultFavicon = false;
}
}
if (setDefaultFavicon) {
setDefaultFavicon();
}
}
@Override
public void onProgressChanged(int progress) {
showProgressBar(progress);
}
@Override
public void onPageLoaded(boolean withError) {
TabView.this.onPageLoaded(withError);
}
@Override
public boolean onReceivedIcon(Bitmap favicon) {
return TabView.this.onReceivedIcon(favicon, false);
}
@Override
public void setDefaultFavicon() {
TabView.this.onReceivedIcon(null, true);
}
@Override
public void onCanGoBackChanged(boolean canGoBack) {
if (canGoBack) {
mBackIndicatorAnimHelper.show();
} else {
mBackIndicatorAnimHelper.hide();
}
}
@Override
public boolean hasHighQualityFavicon() {
String tag = (String) mFavicon.getTag();
Drawable drawable = mFavicon.getDrawable();
if (tag != null && drawable != null && drawable instanceof BitmapDrawable) {
Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
if (bitmap != null && bitmap.getWidth() >= Constant.DESIRED_FAVICON_SIZE) {
return true;
}
}
return false;
}
@Override
public void onThemeColor(Integer color) {
TabView.this.onThemeColor(color);
}
});
setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO: How does this code path actually get hit?
// GW: Let me know if you hit this code path.
//Util.Assert(false);
//MainController mainController = MainController.get();
//mainController.switchState(mainController.STATE_AnimateToBubbleView);
}
});
setOnApplyFaviconListener(new OnApplyFaviconListener() {
@Override
public boolean applyFavicon(String faviconURL) {
URL currentUrl = mContentView.getUrl();
if (currentUrl != null) {
String currentFaviconUrl = Util.getDefaultFaviconUrl(currentUrl);
if (faviconURL != null && faviconURL.equals(currentFaviconUrl)) {
return true;
}
//Log.d("blerg", "Ignoring favicon " + faviconURL + " in favor of " + currentFaviconUrl);
}
return false;
}
});
}
public void destroy() {
// Will be null
if (mContentView != null) {
mContentView.destroy();
}
}
public int toolbarHeight() {
if (null != mContentView) {
return mContentView.toolbarHeight();
}
return 0;
}
public boolean adjustBubblesPanel(float adjustOn, boolean heightSizeTopMargin, int animDuration) {
if (null == mOriginalParams) {
mOriginalParams = (FrameLayout.LayoutParams)mContentView.getLayoutParams();
if (null == mOriginalParams) {
return false;
}
mOriginalBottomMargin = mOriginalParams.bottomMargin;
}
if (heightSizeTopMargin) {
FrameLayout.LayoutParams currentParams = (FrameLayout.LayoutParams)mContentView.getLayoutParams();
if (null == currentParams) {
return false;
}
float locationYToMove = 0 - currentParams.height - currentParams.topMargin - mContentView.toolbarHeight();
currentParams.bottomMargin = mOriginalBottomMargin + (int)locationYToMove;
mContentView.setLayoutParams(currentParams);
}
ObjectAnimator
.ofFloat(mContentView, "translationY", adjustOn)
.setDuration(animDuration)
.start();
return true;
}
// Empty listener is set so that the mHideListener is not still used, potentially setting the view visibilty as GONE
/*private Animator.AnimatorListener mShowListener = new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
mContentView.setVisibility(View.VISIBLE);
}
@Override
public void onAnimationEnd(Animator animation) {
mContentView.setVisibility(View.GONE);
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
};*/
@Override
protected void onPageLoaded(boolean withError) {
super.onPageLoaded(withError);
if (MainController.get() != null) {
MainController.get().onPageLoaded(this, withError);
}
if (mUrl.toString().equals(getContext().getString(R.string.empty_bubble_page))) {
if (mPerformEmptyClick) {
performClick();
}
else {
mPerformEmptyClick = true;
}
}
}
public ContentView getContentView() {
return mContentView;
}
public long getTotalTrackedLoadTime() {
return mContentView.getTotalTrackedLoadTime();
}
public void updateIncognitoMode(boolean incognito) {
mContentView.updateIncognitoMode(incognito);
}
@Override
void setProgressColor(int color) {
super.setProgressColor(color);
mContentView.setFaviconColor(color);
}
}