1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.browser; 17 18 import android.content.Context; 19 import android.graphics.Bitmap; 20 import android.os.Handler; 21 import android.os.Message; 22 import android.text.TextUtils; 23 import android.util.AttributeSet; 24 import android.view.MenuItem; 25 import android.view.View; 26 import android.view.View.OnClickListener; 27 import android.view.ViewConfiguration; 28 import android.view.ViewPropertyAnimator; 29 import android.widget.ImageView; 30 import android.widget.LinearLayout; 31 import android.widget.PopupMenu.OnMenuItemClickListener; 32 import android.widget.TextView; 33 34 import com.android.browser.UI.ComboViews; 35 36 import java.text.DateFormat; 37 import java.util.Date; 38 39 public class SnapshotBar extends LinearLayout implements OnClickListener { 40 41 private static final int MSG_SHOW_TITLE = 1; 42 private static final long DURATION_SHOW_DATE = BaseUi.HIDE_TITLEBAR_DELAY; 43 44 private ImageView mFavicon; 45 private TextView mDate; 46 private TextView mTitle; 47 private View mBookmarks; 48 private TitleBar mTitleBar; 49 private View mTabSwitcher; 50 private View mOverflowMenu; 51 private View mToggleContainer; 52 private boolean mIsAnimating; 53 private ViewPropertyAnimator mTitleAnimator, mDateAnimator; 54 private float mAnimRadius = 20f; 55 56 public SnapshotBar(Context context) { 57 super(context); 58 } 59 60 public SnapshotBar(Context context, AttributeSet attrs) { 61 super(context, attrs); 62 } 63 64 public SnapshotBar(Context context, AttributeSet attrs, int defStyle) { 65 super(context, attrs, defStyle); 66 } 67 68 public void setTitleBar(TitleBar titleBar) { 69 mTitleBar = titleBar; 70 setFavicon(null); 71 } 72 73 private Handler mHandler = new Handler() { 74 @Override 75 public void handleMessage(Message msg) { 76 if (msg.what == MSG_SHOW_TITLE) { 77 mIsAnimating = false; 78 showTitle(); 79 mTitleBar.getUi().showTitleBarForDuration(); 80 } 81 } 82 }; 83 84 @Override 85 protected void onFinishInflate() { 86 super.onFinishInflate(); 87 mFavicon = (ImageView) findViewById(R.id.favicon); 88 mDate = (TextView) findViewById(R.id.date); 89 mTitle = (TextView) findViewById(R.id.title); 90 mBookmarks = findViewById(R.id.all_btn); 91 mTabSwitcher = findViewById(R.id.tab_switcher); 92 mOverflowMenu = findViewById(R.id.more); 93 mToggleContainer = findViewById(R.id.toggle_container); 94 95 if (mBookmarks != null) { 96 mBookmarks.setOnClickListener(this); 97 } 98 if (mTabSwitcher != null) { 99 mTabSwitcher.setOnClickListener(this); 100 } 101 if (mOverflowMenu != null) { 102 mOverflowMenu.setOnClickListener(this); 103 boolean showMenu = !ViewConfiguration.get(getContext()) 104 .hasPermanentMenuKey(); 105 mOverflowMenu.setVisibility(showMenu ? VISIBLE : GONE); 106 } 107 if (mToggleContainer != null) { 108 mToggleContainer.setOnClickListener(this); 109 resetAnimation(); 110 } 111 } 112 113 @Override 114 protected void onLayout(boolean changed, int l, int t, int r, int b) { 115 super.onLayout(changed, l, t, r, b); 116 if (mToggleContainer != null) { 117 mAnimRadius = mToggleContainer.getHeight() / 2f; 118 } 119 } 120 121 void resetAnimation() { 122 if (mToggleContainer == null) { 123 // No animation needed/used 124 return; 125 } 126 if (mTitleAnimator != null) { 127 mTitleAnimator.cancel(); 128 mTitleAnimator = null; 129 } 130 if (mDateAnimator != null) { 131 mDateAnimator.cancel(); 132 mDateAnimator = null; 133 } 134 mIsAnimating = false; 135 mHandler.removeMessages(MSG_SHOW_TITLE); 136 mTitle.setAlpha(1f); 137 mTitle.setTranslationY(0f); 138 mTitle.setRotationX(0f); 139 mDate.setAlpha(0f); 140 mDate.setTranslationY(-mAnimRadius); 141 mDate.setRotationX(90f); 142 } 143 144 private void showDate() { 145 mTitleAnimator = mTitle.animate() 146 .alpha(0f) 147 .translationY(mAnimRadius) 148 .rotationX(-90f); 149 mDateAnimator = mDate.animate() 150 .alpha(1f) 151 .translationY(0f) 152 .rotationX(0f); 153 } 154 155 private void showTitle() { 156 mTitleAnimator = mTitle.animate() 157 .alpha(1f) 158 .translationY(0f) 159 .rotationX(0f); 160 mDateAnimator = mDate.animate() 161 .alpha(0f) 162 .translationY(-mAnimRadius) 163 .rotationX(90f); 164 } 165 166 @Override 167 public void onClick(View v) { 168 if (mBookmarks == v) { 169 mTitleBar.getUiController().bookmarksOrHistoryPicker(ComboViews.Bookmarks); 170 } else if (mTabSwitcher == v) { 171 ((PhoneUi) mTitleBar.getUi()).toggleNavScreen(); 172 } else if (mOverflowMenu == v) { 173 NavigationBarBase navBar = mTitleBar.getNavigationBar(); 174 if (navBar instanceof NavigationBarPhone) { 175 ((NavigationBarPhone)navBar).showMenu(mOverflowMenu); 176 } 177 } else if (mToggleContainer == v && !mIsAnimating) { 178 mIsAnimating = true; 179 showDate(); 180 mTitleBar.getUi().showTitleBar(); 181 Message m = mHandler.obtainMessage(MSG_SHOW_TITLE); 182 mHandler.sendMessageDelayed(m, DURATION_SHOW_DATE); 183 } 184 } 185 186 public void onTabDataChanged(Tab tab) { 187 if (!tab.isSnapshot()) return; 188 SnapshotTab snapshot = (SnapshotTab) tab; 189 DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.LONG); 190 mDate.setText(dateFormat.format(new Date(snapshot.getDateCreated()))); 191 String title = snapshot.getTitle(); 192 if (TextUtils.isEmpty(title)) { 193 title = UrlUtils.stripUrl(snapshot.getUrl()); 194 } 195 mTitle.setText(title); 196 setFavicon(tab.getFavicon()); 197 resetAnimation(); 198 } 199 200 public void setFavicon(Bitmap icon) { 201 if (mFavicon == null) return; 202 mFavicon.setImageDrawable(mTitleBar.getUi().getFaviconDrawable(icon)); 203 } 204 205 public boolean isAnimating() { 206 return mIsAnimating; 207 } 208 209 } 210