blob: 8e3acf743ffe5fbd4b2eb79a6000e7c8518ab942 [file] [log] [blame]
Michael Kolb370a4f32010-10-06 10:45:32 -07001/*
2 * Copyright (C) 2010 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
17package com.android.browser;
18
19import android.content.Context;
Leon Scroggins74dbe012010-10-15 10:54:27 -040020import android.text.TextUtils;
Michael Kolb370a4f32010-10-06 10:45:32 -070021import android.util.AttributeSet;
22import android.view.Gravity;
23import android.view.View;
24import android.view.View.OnClickListener;
25import android.widget.ImageButton;
26import android.widget.ImageView;
27import android.widget.LinearLayout;
28import android.widget.TextView;
29
30import java.util.ArrayList;
31import java.util.List;
32
33/**
34 * Simple bread crumb view
35 * Use setController to receive callbacks from user interactions
36 * Use pushView, popView, clear, and getTopData to change/access the view stack
37 */
38public class BreadCrumbView extends LinearLayout implements OnClickListener {
39
40 interface Controller {
41 public void onTop(int level, Object data);
42 }
43
44 private ImageButton mBackButton;
45 private Controller mController;
46 private List<Crumb> mCrumbs;
47 private boolean mUseBackButton;
48
49 /**
50 * @param context
51 * @param attrs
52 * @param defStyle
53 */
54 public BreadCrumbView(Context context, AttributeSet attrs, int defStyle) {
55 super(context, attrs, defStyle);
56 init(context);
57 }
58
59 /**
60 * @param context
61 * @param attrs
62 */
63 public BreadCrumbView(Context context, AttributeSet attrs) {
64 super(context, attrs);
65 init(context);
66 }
67
68 /**
69 * @param context
70 */
71 public BreadCrumbView(Context context) {
72 super(context);
73 init(context);
74 }
75
76 private void init(Context ctx) {
77 mUseBackButton = false;
78 mCrumbs = new ArrayList<Crumb>();
79 }
80
81 public void setUseBackButton(boolean useflag) {
82 mUseBackButton = useflag;
83 if (mUseBackButton && (mBackButton == null)) {
84 addBackButton();
85 } else if (!mUseBackButton && (mBackButton != null)) {
86 removeView(mBackButton);
87 mBackButton = null;
88 }
89 }
90
91 public void setController(Controller ctl) {
92 mController = ctl;
93 }
94
95 public Object getTopData() {
96 Crumb c = getTopCrumb();
97 if (c != null) {
98 return c.data;
99 }
100 return null;
101 }
102
103 public int size() {
104 return mCrumbs.size();
105 }
106
107 public void clear() {
108 while (mCrumbs.size() > 1) {
109 pop(false);
110 }
111 pop(true);
112 }
113
114 public void notifyController() {
115 if (mController != null) {
116 if (mCrumbs.size() > 0) {
117 mController.onTop(mCrumbs.size(), getTopCrumb().data);
118 } else {
119 mController.onTop(0, null);
120 }
121 }
122 }
123
124 public void pushView(String name, Object data) {
Leon Scroggins74dbe012010-10-15 10:54:27 -0400125 pushView(name, true, data);
126 }
127
128 public void pushView(String name, boolean canGoBack, Object data) {
129 Crumb crumb = new Crumb(name, canGoBack, data);
Michael Kolb370a4f32010-10-06 10:45:32 -0700130 pushCrumb(crumb);
131 }
132
133 public void pushView(View view, Object data) {
134 Crumb crumb = new Crumb(view, true, data);
135 pushCrumb(crumb);
136 }
137
138 public void popView() {
139 pop(true);
140 }
141
142 private void addBackButton() {
143 mBackButton = new ImageButton(mContext);
144 mBackButton.setImageResource(R.drawable.ic_back_normal);
145 mBackButton.setBackgroundResource(R.drawable.browserbarbutton);
146 mBackButton.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
147 LayoutParams.MATCH_PARENT));
148 mBackButton.setOnClickListener(this);
149 mBackButton.setVisibility(View.GONE);
150 addView(mBackButton, 0);
151 }
152
153 private void pushCrumb(Crumb crumb) {
154 if (!mUseBackButton || (mCrumbs.size() > 0)) {
155 addSeparator();
156 }
157 mCrumbs.add(crumb);
158 addView(crumb.crumbView);
159 if (mUseBackButton) {
160 mBackButton.setVisibility(crumb.canGoBack ? View.VISIBLE : View.GONE);
161 }
162 crumb.crumbView.setOnClickListener(this);
163 }
164
165 private void addSeparator() {
166 ImageView sep = new ImageView(mContext);
167 sep.setImageResource(R.drawable.crumb_divider);
168 sep.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
169 LayoutParams.MATCH_PARENT));
170 addView(sep);
171 }
172
173 private void pop(boolean notify) {
174 int n = mCrumbs.size();
175 if (n > 0) {
176 removeLastView();
177 if (!mUseBackButton || (n > 1)) {
178 // remove separator
179 removeLastView();
180 }
181 mCrumbs.remove(n - 1);
182 if (mUseBackButton) {
183 Crumb top = getTopCrumb();
184 if (top != null) {
185 mBackButton.setVisibility(top.canGoBack ? View.VISIBLE : View.GONE);
186 } else {
187 mBackButton.setVisibility(View.GONE);
188 }
189 }
190 if (notify) {
191 notifyController();
192 }
193 }
194 }
195
196 private void removeLastView() {
197 int ix = getChildCount();
198 if (ix > 0) {
199 removeViewAt(ix-1);
200 }
201 }
202
203 private Crumb getTopCrumb() {
204 Crumb crumb = null;
205 if (mCrumbs.size() > 0) {
206 crumb = mCrumbs.get(mCrumbs.size() - 1);
207 }
208 return crumb;
209 }
210
211 @Override
212 public void onClick(View v) {
213 if (mBackButton == v) {
214 popView();
215 notifyController();
216 } else {
217 // pop until view matches crumb view
218 while (v != getTopCrumb().crumbView) {
219 pop(false);
220 }
221 notifyController();
222 }
223 }
224
225 class Crumb {
226
227 public View crumbView;
228 public boolean canGoBack;
229 public Object data;
230
231 public Crumb(String title, boolean backEnabled, Object tag) {
232 init(makeCrumbView(title), backEnabled, tag);
233 }
234
235 public Crumb(View view, boolean backEnabled, Object tag) {
236 init(view, backEnabled, tag);
237 }
238
239 private void init(View view, boolean back, Object tag) {
240 canGoBack = back;
241 crumbView = view;
242 data = tag;
243 }
244
245 private TextView makeCrumbView(String name) {
246 TextView tv = new TextView(mContext);
247 tv.setTextAppearance(mContext, android.R.style.TextAppearance_Medium);
248 tv.setPadding(16, 0, 16, 0);
249 tv.setGravity(Gravity.CENTER_VERTICAL);
250 tv.setText(name);
251 tv.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
252 LayoutParams.MATCH_PARENT));
Leon Scroggins74dbe012010-10-15 10:54:27 -0400253 tv.setMaxWidth(mContext.getResources().getInteger(
254 R.integer.max_width_crumb));
255 tv.setMaxLines(1);
256 tv.setEllipsize(TextUtils.TruncateAt.END);
Michael Kolb370a4f32010-10-06 10:45:32 -0700257 return tv;
258 }
259
260 }
261
262}