2011-11-18 10:28:17 -08:00
|
|
|
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
|
2012-05-21 04:12:37 -07:00
|
|
|
* 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/. */
|
2011-11-18 10:28:17 -08:00
|
|
|
|
|
|
|
package org.mozilla.gecko;
|
|
|
|
|
|
|
|
import android.content.Context;
|
2012-10-31 22:12:45 -07:00
|
|
|
import android.graphics.drawable.Drawable;
|
2012-11-16 00:50:28 -08:00
|
|
|
import android.graphics.drawable.StateListDrawable;
|
2012-07-13 12:49:58 -07:00
|
|
|
import android.net.Uri;
|
2012-11-12 10:49:25 -08:00
|
|
|
import android.support.v4.view.ViewPager;
|
|
|
|
import android.support.v4.view.PagerAdapter;
|
2011-11-18 10:28:17 -08:00
|
|
|
import android.util.AttributeSet;
|
|
|
|
import android.util.Log;
|
|
|
|
import android.view.LayoutInflater;
|
|
|
|
import android.view.MotionEvent;
|
|
|
|
import android.view.View;
|
|
|
|
import android.view.ViewGroup;
|
|
|
|
import android.view.inputmethod.InputMethodManager;
|
|
|
|
import android.widget.TabHost;
|
2012-07-02 11:22:29 -07:00
|
|
|
import android.widget.TabWidget;
|
2011-11-18 10:28:17 -08:00
|
|
|
|
2012-07-17 17:54:54 -07:00
|
|
|
public class AwesomeBarTabs extends TabHost {
|
2011-11-18 10:28:17 -08:00
|
|
|
private static final String LOGTAG = "GeckoAwesomeBarTabs";
|
|
|
|
|
|
|
|
private Context mContext;
|
2011-12-07 15:12:51 -08:00
|
|
|
private boolean mInflated;
|
2012-03-27 10:05:41 -07:00
|
|
|
private LayoutInflater mInflater;
|
2011-11-18 10:28:17 -08:00
|
|
|
private OnUrlOpenListener mUrlOpenListener;
|
2012-06-28 11:21:24 -07:00
|
|
|
private View.OnTouchListener mListTouchListener;
|
2012-11-12 10:49:25 -08:00
|
|
|
private boolean mSearching = false;
|
2012-11-16 00:50:28 -08:00
|
|
|
private String mTarget;
|
|
|
|
private Background mBackground;
|
2012-11-12 10:49:25 -08:00
|
|
|
private ViewPager mViewPager;
|
|
|
|
private AwesomePagerAdapter mPagerAdapter;
|
2012-06-18 17:23:15 -07:00
|
|
|
|
2012-06-18 12:39:13 -07:00
|
|
|
private AwesomeBarTab mTabs[];
|
2011-11-18 10:28:17 -08:00
|
|
|
|
|
|
|
// FIXME: This value should probably come from a
|
|
|
|
// prefs key (just like XUL-based fennec)
|
|
|
|
private static final int MAX_RESULTS = 100;
|
|
|
|
|
|
|
|
public interface OnUrlOpenListener {
|
2011-12-07 17:52:07 -08:00
|
|
|
public void onUrlOpen(String url);
|
2012-06-05 14:07:14 -07:00
|
|
|
public void onSearch(String engine, String text);
|
|
|
|
public void onEditSuggestion(String suggestion);
|
2011-11-18 10:28:17 -08:00
|
|
|
}
|
|
|
|
|
2012-11-12 10:49:25 -08:00
|
|
|
private class AwesomePagerAdapter extends PagerAdapter {
|
|
|
|
public AwesomePagerAdapter() {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
|
|
|
public Object instantiateItem(ViewGroup group, int index) {
|
|
|
|
AwesomeBarTab tab = mTabs[index];
|
|
|
|
group.addView(tab.getView());
|
|
|
|
return tab;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void destroyItem(ViewGroup group, int index, Object obj) {
|
|
|
|
AwesomeBarTab tab = (AwesomeBarTab)obj;
|
|
|
|
group.removeView(tab.getView());
|
|
|
|
}
|
|
|
|
|
|
|
|
public int getCount() {
|
|
|
|
if (mSearching)
|
|
|
|
return 1;
|
|
|
|
return mTabs.length;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isViewFromObject(View view, Object object) {
|
|
|
|
return getAwesomeBarTabForView(view) == object;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-06-18 12:39:13 -07:00
|
|
|
private AwesomeBarTab getCurrentAwesomeBarTab() {
|
2012-11-12 10:49:25 -08:00
|
|
|
int index = mViewPager.getCurrentItem();
|
|
|
|
return mTabs[index];
|
2012-06-18 12:39:13 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
public AwesomeBarTab getAwesomeBarTabForView(View view) {
|
|
|
|
String tag = (String)view.getTag();
|
|
|
|
return getAwesomeBarTabForTag(tag);
|
|
|
|
}
|
2012-06-18 17:23:15 -07:00
|
|
|
|
2012-06-18 12:39:13 -07:00
|
|
|
public AwesomeBarTab getAwesomeBarTabForTag(String tag) {
|
|
|
|
for (AwesomeBarTab tab : mTabs) {
|
2012-11-12 10:49:25 -08:00
|
|
|
if (tag.equals(tab.getTag())) {
|
2012-06-18 12:39:13 -07:00
|
|
|
return tab;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
2012-06-18 17:23:15 -07:00
|
|
|
|
2012-06-18 12:39:13 -07:00
|
|
|
public boolean onBackPressed() {
|
|
|
|
AwesomeBarTab tab = getCurrentAwesomeBarTab();
|
|
|
|
if (tab == null)
|
|
|
|
return false;
|
|
|
|
return tab.onBackPressed();
|
2012-06-18 17:23:15 -07:00
|
|
|
}
|
|
|
|
|
2011-11-18 10:28:17 -08:00
|
|
|
public AwesomeBarTabs(Context context, AttributeSet attrs) {
|
|
|
|
super(context, attrs);
|
|
|
|
|
|
|
|
Log.d(LOGTAG, "Creating AwesomeBarTabs");
|
|
|
|
|
|
|
|
mContext = context;
|
2011-12-07 15:12:51 -08:00
|
|
|
mInflated = false;
|
2012-03-27 10:05:41 -07:00
|
|
|
mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
2011-12-07 15:12:51 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onFinishInflate() {
|
|
|
|
super.onFinishInflate();
|
2011-11-18 10:28:17 -08:00
|
|
|
|
2011-12-07 15:12:51 -08:00
|
|
|
// HACK: Without this, the onFinishInflate is called twice
|
|
|
|
// This issue is due to a bug when Android inflates a layout with a
|
|
|
|
// parent. Fixed in Honeycomb
|
|
|
|
if (mInflated)
|
|
|
|
return;
|
2011-11-18 10:28:17 -08:00
|
|
|
|
2011-12-07 15:12:51 -08:00
|
|
|
mInflated = true;
|
2011-11-18 10:28:17 -08:00
|
|
|
|
|
|
|
// This should be called before adding any tabs
|
|
|
|
// to the TabHost.
|
|
|
|
setup();
|
|
|
|
|
2012-06-28 11:21:24 -07:00
|
|
|
mListTouchListener = new View.OnTouchListener() {
|
|
|
|
public boolean onTouch(View view, MotionEvent event) {
|
2012-12-11 15:52:36 -08:00
|
|
|
if (event.getActionMasked() == MotionEvent.ACTION_DOWN)
|
2012-06-28 11:21:24 -07:00
|
|
|
hideSoftInput(view);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2012-11-16 00:50:28 -08:00
|
|
|
mBackground = (Background) findViewById(R.id.awesomebar_background);
|
|
|
|
|
2012-06-18 12:39:13 -07:00
|
|
|
mTabs = new AwesomeBarTab[] {
|
|
|
|
new AllPagesTab(mContext),
|
|
|
|
new BookmarksTab(mContext),
|
|
|
|
new HistoryTab(mContext)
|
|
|
|
};
|
|
|
|
|
2012-11-12 10:49:25 -08:00
|
|
|
final TabWidget tabWidget = (TabWidget) findViewById(android.R.id.tabs);
|
|
|
|
// hide the strip since we aren't using the TabHost...
|
|
|
|
tabWidget.setStripEnabled(false);
|
|
|
|
|
|
|
|
mViewPager = (ViewPager) findViewById(R.id.tabviewpager);
|
|
|
|
mPagerAdapter = new AwesomePagerAdapter();
|
|
|
|
mViewPager.setAdapter(mPagerAdapter);
|
|
|
|
mViewPager.setCurrentItem(0);
|
|
|
|
mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
|
|
|
|
public void onPageScrollStateChanged(int state) { }
|
|
|
|
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { }
|
|
|
|
public void onPageSelected(int position) {
|
|
|
|
tabWidget.setCurrentTab(position);
|
|
|
|
styleSelectedTab();
|
2012-12-11 15:52:36 -08:00
|
|
|
hideSoftInput(mViewPager);
|
2012-11-12 10:49:25 -08:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
for (int i = 0; i < mTabs.length; i++) {
|
2012-12-11 15:52:36 -08:00
|
|
|
mTabs[i].setListTouchListener(mListTouchListener);
|
2012-11-12 10:49:25 -08:00
|
|
|
addAwesomeTab(mTabs[i].getTag(),
|
|
|
|
mTabs[i].getTitleStringId(),
|
|
|
|
i);
|
2012-06-18 12:39:13 -07:00
|
|
|
}
|
2012-06-18 12:39:13 -07:00
|
|
|
|
2012-11-12 10:49:25 -08:00
|
|
|
tabWidget.setCurrentTab(0);
|
2012-07-02 11:22:29 -07:00
|
|
|
|
2012-11-12 10:49:25 -08:00
|
|
|
styleSelectedTab();
|
2012-07-02 11:22:29 -07:00
|
|
|
|
2012-06-18 17:23:15 -07:00
|
|
|
// Initialize "App Pages" list with no filter
|
|
|
|
filter("");
|
2012-06-18 12:39:13 -07:00
|
|
|
}
|
|
|
|
|
2012-07-02 11:22:29 -07:00
|
|
|
private void styleSelectedTab() {
|
2012-11-12 10:49:25 -08:00
|
|
|
int selIndex = mViewPager.getCurrentItem();
|
2012-07-02 11:22:29 -07:00
|
|
|
TabWidget tabWidget = getTabWidget();
|
2012-11-16 00:50:28 -08:00
|
|
|
|
2012-07-02 11:22:29 -07:00
|
|
|
for (int i = 0; i < tabWidget.getTabCount(); i++) {
|
2012-11-16 00:50:28 -08:00
|
|
|
GeckoTextView view = (GeckoTextView) tabWidget.getChildTabViewAt(i);
|
|
|
|
if (mTarget != null && mTarget.equals(AwesomeBar.Target.CURRENT_TAB.name())) {
|
|
|
|
Tab tab = Tabs.getInstance().getSelectedTab();
|
|
|
|
if (tab != null && tab.isPrivate()) {
|
|
|
|
if (i == selIndex)
|
|
|
|
view.setPrivateMode(false);
|
|
|
|
else
|
|
|
|
view.setPrivateMode(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (i == selIndex)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (i == (selIndex - 1))
|
|
|
|
view.getBackground().setLevel(1);
|
|
|
|
else if (i == (selIndex + 1))
|
|
|
|
view.getBackground().setLevel(2);
|
|
|
|
else
|
|
|
|
view.getBackground().setLevel(0);
|
2012-07-02 11:22:29 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if (selIndex == 0)
|
|
|
|
findViewById(R.id.tab_widget_left).getBackground().setLevel(1);
|
|
|
|
else
|
|
|
|
findViewById(R.id.tab_widget_left).getBackground().setLevel(0);
|
|
|
|
|
|
|
|
if (selIndex == (tabWidget.getTabCount() - 1))
|
|
|
|
findViewById(R.id.tab_widget_right).getBackground().setLevel(2);
|
|
|
|
else
|
|
|
|
findViewById(R.id.tab_widget_right).getBackground().setLevel(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-11-12 10:49:25 -08:00
|
|
|
private View addAwesomeTab(String id, int titleId, final int contentId) {
|
2012-11-16 00:50:28 -08:00
|
|
|
GeckoTextView indicatorView = (GeckoTextView) mInflater.inflate(R.layout.awesomebar_tab_indicator, null);
|
2012-07-02 11:22:29 -07:00
|
|
|
indicatorView.setText(titleId);
|
2011-11-18 10:28:17 -08:00
|
|
|
|
2012-11-12 10:49:25 -08:00
|
|
|
getTabWidget().addView(indicatorView);
|
|
|
|
|
|
|
|
// this MUST be done after tw.addView to overwrite the listener added by tabWidget
|
|
|
|
// which delegates to TabHost (which we don't have)
|
|
|
|
indicatorView.setOnClickListener(new View.OnClickListener() {
|
|
|
|
public void onClick(View v) {
|
|
|
|
mViewPager.setCurrentItem(contentId, true);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
return indicatorView;
|
2011-11-18 10:28:17 -08:00
|
|
|
}
|
|
|
|
|
2012-03-30 17:00:41 -07:00
|
|
|
private boolean hideSoftInput(View view) {
|
2011-11-18 10:28:17 -08:00
|
|
|
InputMethodManager imm =
|
|
|
|
(InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
|
|
|
|
|
2012-03-30 17:00:41 -07:00
|
|
|
return imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
|
2011-11-18 10:28:17 -08:00
|
|
|
}
|
|
|
|
|
2012-06-18 17:23:15 -07:00
|
|
|
public void setOnUrlOpenListener(OnUrlOpenListener listener) {
|
|
|
|
mUrlOpenListener = listener;
|
2012-06-18 12:39:13 -07:00
|
|
|
for (AwesomeBarTab tab : mTabs) {
|
|
|
|
tab.setUrlListener(listener);
|
|
|
|
}
|
2012-06-18 12:39:13 -07:00
|
|
|
}
|
|
|
|
|
2012-06-18 17:23:15 -07:00
|
|
|
public void destroy() {
|
2012-06-18 12:39:13 -07:00
|
|
|
for (AwesomeBarTab tab : mTabs) {
|
|
|
|
tab.destroy();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public AllPagesTab getAllPagesTab() {
|
|
|
|
return (AllPagesTab)getAwesomeBarTabForTag("allPages");
|
|
|
|
}
|
|
|
|
|
|
|
|
public BookmarksTab getBookmarksTab() {
|
|
|
|
return (BookmarksTab)getAwesomeBarTabForTag("bookmarks");
|
|
|
|
}
|
|
|
|
|
|
|
|
public HistoryTab getHistoryTab() {
|
|
|
|
return (HistoryTab)getAwesomeBarTabForTag("history");
|
2011-11-18 10:28:17 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
public void filter(String searchTerm) {
|
|
|
|
// Don't let the tab's content steal focus on tab switch
|
|
|
|
setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
|
|
|
|
|
|
|
|
// Ensure the 'All Pages' tab is selected
|
2012-06-18 12:39:13 -07:00
|
|
|
AllPagesTab allPages = getAllPagesTab();
|
|
|
|
setCurrentTabByTag(allPages.getTag());
|
2011-11-18 10:28:17 -08:00
|
|
|
|
|
|
|
// Restore normal focus behavior on tab host
|
|
|
|
setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
|
|
|
|
|
|
|
|
// The tabs should only be visible if there's no on-going search
|
2012-11-12 10:49:25 -08:00
|
|
|
mSearching = searchTerm.length() != 0;
|
|
|
|
// reset the pager adapter to force repopulating the cache
|
|
|
|
mViewPager.setAdapter(mPagerAdapter);
|
|
|
|
int tabsVisibility = !mSearching ? View.VISIBLE : View.GONE;
|
2012-07-02 11:22:29 -07:00
|
|
|
findViewById(R.id.tab_widget_container).setVisibility(tabsVisibility);
|
2011-11-18 10:28:17 -08:00
|
|
|
|
|
|
|
// Perform the actual search
|
2012-06-18 12:39:13 -07:00
|
|
|
allPages.filter(searchTerm);
|
2011-12-07 17:52:07 -08:00
|
|
|
}
|
|
|
|
|
2012-06-02 11:23:45 -07:00
|
|
|
public boolean isInReadingList() {
|
2012-06-18 12:39:13 -07:00
|
|
|
return getBookmarksTab().isInReadingList();
|
2012-06-02 11:23:45 -07:00
|
|
|
}
|
2012-10-31 22:12:45 -07:00
|
|
|
|
2012-11-16 00:50:28 -08:00
|
|
|
public void setTarget(String target) {
|
|
|
|
mTarget = target;
|
|
|
|
styleSelectedTab();
|
|
|
|
if (mTarget.equals(AwesomeBar.Target.CURRENT_TAB.name())) {
|
|
|
|
Tab tab = Tabs.getInstance().getSelectedTab();
|
|
|
|
if (tab != null && tab.isPrivate())
|
|
|
|
mBackground.setPrivateMode(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static class Background extends GeckoLinearLayout
|
2012-10-31 22:12:45 -07:00
|
|
|
implements LightweightTheme.OnChangeListener {
|
|
|
|
private GeckoActivity mActivity;
|
|
|
|
|
|
|
|
public Background(Context context, AttributeSet attrs) {
|
|
|
|
super(context, attrs);
|
|
|
|
mActivity = (GeckoActivity) context;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onAttachedToWindow() {
|
|
|
|
super.onAttachedToWindow();
|
|
|
|
mActivity.getLightweightTheme().addListener(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onDetachedFromWindow() {
|
|
|
|
super.onDetachedFromWindow();
|
|
|
|
mActivity.getLightweightTheme().removeListener(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onLightweightThemeChanged() {
|
|
|
|
Drawable drawable = mActivity.getLightweightTheme().getDrawableWithAlpha(this, 255, 0);
|
|
|
|
if (drawable == null)
|
|
|
|
return;
|
|
|
|
|
2012-11-16 00:50:28 -08:00
|
|
|
StateListDrawable stateList = new StateListDrawable();
|
|
|
|
stateList.addState(new int[] { R.attr.state_private }, mActivity.getResources().getDrawable(R.drawable.address_bar_bg_private));
|
|
|
|
stateList.addState(new int[] {}, drawable);
|
|
|
|
|
2012-10-31 22:12:45 -07:00
|
|
|
int[] padding = new int[] { getPaddingLeft(),
|
|
|
|
getPaddingTop(),
|
|
|
|
getPaddingRight(),
|
|
|
|
getPaddingBottom()
|
|
|
|
};
|
2012-11-16 00:50:28 -08:00
|
|
|
setBackgroundDrawable(stateList);
|
2012-10-31 22:12:45 -07:00
|
|
|
setPadding(padding[0], padding[1], padding[2], padding[3]);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onLightweightThemeReset() {
|
|
|
|
int[] padding = new int[] { getPaddingLeft(),
|
|
|
|
getPaddingTop(),
|
|
|
|
getPaddingRight(),
|
|
|
|
getPaddingBottom()
|
|
|
|
};
|
2012-11-16 00:50:28 -08:00
|
|
|
setBackgroundResource(R.drawable.awesomebar_tabs_bg);
|
2012-10-31 22:12:45 -07:00
|
|
|
setPadding(padding[0], padding[1], padding[2], padding[3]);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
|
|
|
super.onLayout(changed, left, top, right, bottom);
|
|
|
|
onLightweightThemeChanged();
|
|
|
|
}
|
|
|
|
}
|
2011-11-18 10:28:17 -08:00
|
|
|
}
|