diff options
Diffstat (limited to 'src/com/android/browser/view')
-rw-r--r-- | src/com/android/browser/view/BookmarkContainer.java | 92 | ||||
-rw-r--r-- | src/com/android/browser/view/BookmarkExpandableGridView.java | 424 |
2 files changed, 516 insertions, 0 deletions
diff --git a/src/com/android/browser/view/BookmarkContainer.java b/src/com/android/browser/view/BookmarkContainer.java new file mode 100644 index 0000000..260b05e --- /dev/null +++ b/src/com/android/browser/view/BookmarkContainer.java @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.browser.view; + +import android.content.Context; +import android.graphics.drawable.Drawable; +import android.graphics.drawable.StateListDrawable; +import android.graphics.drawable.TransitionDrawable; +import android.util.AttributeSet; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.ViewConfiguration; +import android.widget.RelativeLayout; + +public class BookmarkContainer extends RelativeLayout implements OnClickListener { + + private OnClickListener mClickListener; + + public BookmarkContainer(Context context) { + super(context); + init(); + } + + public BookmarkContainer(Context context, AttributeSet attrs) { + super(context, attrs); + init(); + } + + public BookmarkContainer( + Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + init(); + } + + void init() { + setFocusable(true); + super.setOnClickListener(this); + } + + @Override + public void setBackgroundDrawable(Drawable d) { + super.setBackgroundDrawable(d); + } + + @Override + public void setOnClickListener(OnClickListener l) { + mClickListener = l; + } + + @Override + protected void drawableStateChanged() { + super.drawableStateChanged(); + updateTransitionDrawable(isPressed()); + } + + void updateTransitionDrawable(boolean pressed) { + final int longPressTimeout = ViewConfiguration.getLongPressTimeout(); + Drawable selector = getBackground(); + if (selector != null && selector instanceof StateListDrawable) { + Drawable d = ((StateListDrawable)selector).getCurrent(); + if (d != null && d instanceof TransitionDrawable) { + if (pressed && isLongClickable()) { + ((TransitionDrawable) d).startTransition(longPressTimeout); + } else { + ((TransitionDrawable) d).resetTransition(); + } + } + } + } + + @Override + public void onClick(View view) { + updateTransitionDrawable(false); + if (mClickListener != null) { + mClickListener.onClick(view); + } + } +} diff --git a/src/com/android/browser/view/BookmarkExpandableGridView.java b/src/com/android/browser/view/BookmarkExpandableGridView.java new file mode 100644 index 0000000..1d603cc --- /dev/null +++ b/src/com/android/browser/view/BookmarkExpandableGridView.java @@ -0,0 +1,424 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.browser.view; + +import com.android.browser.BreadCrumbView; +import com.android.browser.BrowserBookmarksAdapter; +import com.android.browser.R; +import com.android.internal.view.menu.MenuBuilder; + +import android.content.Context; +import android.database.DataSetObserver; +import android.provider.BrowserContract; +import android.util.AttributeSet; +import android.view.ContextMenu; +import android.view.ContextMenu.ContextMenuInfo; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseExpandableListAdapter; +import android.widget.ExpandableListAdapter; +import android.widget.ExpandableListView; +import android.widget.FrameLayout; +import android.widget.LinearLayout; +import android.widget.TextView; + +import java.util.ArrayList; +import java.util.HashMap; + +public class BookmarkExpandableGridView extends ExpandableListView + implements BreadCrumbView.Controller { + + private BookmarkAccountAdapter mAdapter; + private int mColumnWidth; + private Context mContext; + private OnChildClickListener mOnChildClickListener; + private ContextMenuInfo mContextMenuInfo = null; + private OnCreateContextMenuListener mOnCreateContextMenuListener; + private boolean mLongClickable; + private BreadCrumbView.Controller mBreadcrumbController; + + public BookmarkExpandableGridView(Context context) { + super(context); + init(context); + } + + public BookmarkExpandableGridView(Context context, AttributeSet attrs) { + super(context, attrs); + init(context); + } + + public BookmarkExpandableGridView( + Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + init(context); + } + + void init(Context context) { + mContext = context; + setItemsCanFocus(true); + setLongClickable(false); + mAdapter = new BookmarkAccountAdapter(mContext); + super.setAdapter(mAdapter); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + mAdapter.measureChildren(); + } + + @Override + public void setAdapter(ExpandableListAdapter adapter) { + throw new RuntimeException("Not supported"); + } + + public void setColumnWidthFromLayout(int layout) { + LayoutInflater infalter = LayoutInflater.from(mContext); + View v = infalter.inflate(layout, this, false); + v.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED); + mColumnWidth = v.getMeasuredWidth(); + } + + public void setHorizontalSpacing(int horizontalSpacing) { + // TODO Auto-generated method stub + } + + public void clearAccounts() { + mAdapter.clear(); + } + + public void addAccount(String accountName, BrowserBookmarksAdapter adapter) { + // First, check if it already exists + int indexOf = mAdapter.mGroups.indexOf(accountName); + if (indexOf >= 0) { + BrowserBookmarksAdapter existing = mAdapter.mChildren.get(indexOf); + if (existing != adapter) { + existing.unregisterDataSetObserver(mAdapter.mObserver); + // Replace the existing one + mAdapter.mChildren.remove(indexOf); + mAdapter.mChildren.add(indexOf, adapter); + adapter.registerDataSetObserver(mAdapter.mObserver); + } + } else { + mAdapter.mGroups.add(accountName); + mAdapter.mChildren.add(adapter); + adapter.registerDataSetObserver(mAdapter.mObserver); + } + mAdapter.notifyDataSetChanged(); + expandGroup(mAdapter.getGroupCount() - 1); + } + + @Override + public void setOnChildClickListener(OnChildClickListener onChildClickListener) { + mOnChildClickListener = onChildClickListener; + } + + @Override + public void setOnCreateContextMenuListener(OnCreateContextMenuListener l) { + mOnCreateContextMenuListener = l; + if (!mLongClickable) { + mLongClickable = true; + if (mAdapter != null) { + mAdapter.notifyDataSetChanged(); + } + } + } + + @Override + public void createContextMenu(ContextMenu menu) { + // The below is copied from View - we want to bypass the override + // in AbsListView + + ContextMenuInfo menuInfo = getContextMenuInfo(); + + // Sets the current menu info so all items added to menu will have + // my extra info set. + ((MenuBuilder)menu).setCurrentMenuInfo(menuInfo); + + onCreateContextMenu(menu); + if (mOnCreateContextMenuListener != null) { + mOnCreateContextMenuListener.onCreateContextMenu(menu, this, menuInfo); + } + + // Clear the extra information so subsequent items that aren't mine don't + // have my extra info. + ((MenuBuilder)menu).setCurrentMenuInfo(null); + + if (mParent != null) { + mParent.createContextMenu(menu); + } + } + + @Override + public boolean showContextMenuForChild(View originalView) { + int groupPosition = (Integer) originalView.getTag(R.id.group_position); + int childPosition = (Integer) originalView.getTag(R.id.child_position); + + mContextMenuInfo = new BookmarkContextMenuInfo(originalView, + childPosition, groupPosition); + if (getParent() != null) { + getParent().showContextMenuForChild(this); + } + + return true; + } + + @Override + public void onTop(BreadCrumbView view, int level, Object data) { + if (mBreadcrumbController != null) { + mBreadcrumbController.onTop(view, level, data); + } + } + + public void setBreadcrumbController(BreadCrumbView.Controller controller) { + mBreadcrumbController = controller; + } + + @Override + protected ContextMenuInfo getContextMenuInfo() { + return mContextMenuInfo; + } + + public BrowserBookmarksAdapter getChildAdapter(int groupPosition) { + return mAdapter.mChildren.get(groupPosition); + } + + private OnClickListener mChildClickListener = new OnClickListener() { + + @Override + public void onClick(View v) { + int groupPosition = (Integer) v.getTag(R.id.group_position); + int childPosition = (Integer) v.getTag(R.id.child_position); + long id = (Long) v.getTag(R.id.child_id); + if (mOnChildClickListener != null) { + mOnChildClickListener.onChildClick(BookmarkExpandableGridView.this, + v, groupPosition, childPosition, id); + } + } + }; + + private OnClickListener mGroupOnClickListener = new OnClickListener() { + + @Override + public void onClick(View v) { + int groupPosition = (Integer) v.getTag(R.id.group_position); + if (isGroupExpanded(groupPosition)) { + collapseGroup(groupPosition); + } else { + expandGroup(groupPosition); + } + } + }; + + public BreadCrumbView getBreadCrumbs(int groupPosition) { + return mAdapter.getBreadCrumbView(groupPosition); + } + + class BookmarkAccountAdapter extends BaseExpandableListAdapter { + ArrayList<BrowserBookmarksAdapter> mChildren; + ArrayList<String> mGroups; + HashMap<Integer, BreadCrumbView> mBreadcrumbs = + new HashMap<Integer, BreadCrumbView>(); + LayoutInflater mInflater; + int mRowCount = 1; // assume at least 1 child fits in a row + int mLastViewWidth = -1; + int mRowPadding = -1; + DataSetObserver mObserver = new DataSetObserver() { + @Override + public void onChanged() { + notifyDataSetChanged(); + } + + @Override + public void onInvalidated() { + notifyDataSetChanged(); + } + }; + + public BookmarkAccountAdapter(Context context) { + mContext = context; + mInflater = LayoutInflater.from(mContext); + mChildren = new ArrayList<BrowserBookmarksAdapter>(); + mGroups = new ArrayList<String>(); + } + + public void clear() { + mGroups.clear(); + mChildren.clear(); + notifyDataSetChanged(); + } + + @Override + public Object getChild(int groupPosition, int childPosition) { + return mChildren.get(groupPosition).getItem(childPosition); + } + + @Override + public long getChildId(int groupPosition, int childPosition) { + return childPosition; + } + + @Override + public View getChildView(int groupPosition, int childPosition, + boolean isLastChild, View convertView, ViewGroup parent) { + if (convertView == null) { + convertView = mInflater.inflate(R.layout.bookmark_grid_row, parent, false); + } + LinearLayout row = (LinearLayout) convertView; + row.setPadding( + mRowPadding, + row.getPaddingTop(), + mRowPadding, + row.getPaddingBottom()); + if (row.getChildCount() > mRowCount) { + row.removeViews(mRowCount, row.getChildCount() - mRowCount); + } + for (int i = 0; i < mRowCount; i++) { + View cv = null; + if (row.getChildCount() > i) { + cv = row.getChildAt(i); + } + int realChildPosition = (childPosition * mRowCount) + i; + BrowserBookmarksAdapter childAdapter = mChildren.get(groupPosition); + if (realChildPosition < childAdapter.getCount()) { + View v = childAdapter.getView(realChildPosition, cv, row); + v.setTag(R.id.group_position, groupPosition); + v.setTag(R.id.child_position, realChildPosition); + v.setTag(R.id.child_id, childAdapter.getItemId(realChildPosition)); + v.setOnClickListener(mChildClickListener); + v.setLongClickable(mLongClickable); + if (cv == null) { + row.addView(v); + } else if (cv != v) { + row.removeViewAt(i); + row.addView(v, i); + } else { + cv.setVisibility(View.VISIBLE); + } + } else if (cv != null) { + cv.setVisibility(View.GONE); + } + } + return row; + } + + @Override + public int getChildrenCount(int groupPosition) { + return (int) Math.ceil( + mChildren.get(groupPosition).getCount() / (float)mRowCount); + } + + @Override + public Object getGroup(int groupPosition) { + return mChildren.get(groupPosition); + } + + @Override + public int getGroupCount() { + return mGroups.size(); + } + + public void measureChildren() { + int viewWidth = getMeasuredWidth(); + if (mLastViewWidth == viewWidth) return; + + ViewGroup parent = (ViewGroup) mInflater.inflate(R.layout.bookmark_grid_row, null); + viewWidth -= parent.getPaddingLeft() + parent.getPaddingRight(); + int rowCount = viewWidth / mColumnWidth; + int rowPadding = (viewWidth - (rowCount * mColumnWidth)) / 2; + boolean notify = rowCount != mRowCount || rowPadding != mRowPadding; + mRowCount = rowCount; + mRowPadding = rowPadding; + mLastViewWidth = viewWidth; + if (notify) { + notifyDataSetChanged(); + } + } + + @Override + public long getGroupId(int groupPosition) { + return groupPosition; + } + + @Override + public View getGroupView(int groupPosition, boolean isExpanded, + View view, ViewGroup parent) { + if (view == null) { + view = mInflater.inflate(R.layout.bookmark_group_view, parent, false); + view.setOnClickListener(mGroupOnClickListener); + } + view.setTag(R.id.group_position, groupPosition); + FrameLayout crumbHolder = (FrameLayout) view.findViewById(R.id.crumb_holder); + crumbHolder.removeAllViews(); + BreadCrumbView crumbs = getBreadCrumbView(groupPosition); + if (crumbs.getParent() != null) { + ((ViewGroup)crumbs.getParent()).removeView(crumbs); + } + crumbHolder.addView(crumbs); + TextView name = (TextView) view.findViewById(R.id.group_name); + String groupName = mGroups.get(groupPosition); + if (groupName == null) { + groupName = mContext.getString(R.string.local_bookmarks); + } + name.setText(groupName); + return view; + } + + public BreadCrumbView getBreadCrumbView(int groupPosition) { + BreadCrumbView crumbs = mBreadcrumbs.get(groupPosition); + if (crumbs == null) { + crumbs = (BreadCrumbView) + mInflater.inflate(R.layout.bookmarks_header, null); + crumbs.setController(BookmarkExpandableGridView.this); + crumbs.setUseBackButton(true); + crumbs.setMaxVisible(2); + String bookmarks = mContext.getString(R.string.bookmarks); + crumbs.pushView(bookmarks, false, + BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER); + crumbs.setTag(R.id.group_position, groupPosition); + mBreadcrumbs.put(groupPosition, crumbs); + } + return crumbs; + } + + @Override + public boolean hasStableIds() { + return false; + } + + @Override + public boolean isChildSelectable(int groupPosition, int childPosition) { + return true; + } + } + + public static class BookmarkContextMenuInfo implements ContextMenuInfo { + + private BookmarkContextMenuInfo(View targetView, int childPosition, + int groupPosition) { + this.targetView = targetView; + this.childPosition = childPosition; + this.groupPosition = groupPosition; + } + + public View targetView; + public int childPosition; + public int groupPosition; + } + +} |