blob: 6ac68aa3b545600e36e80dbbafb54e86a21d76f0 [file] [log] [blame]
Adam Powell89e06452010-06-23 20:24:52 -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.internal.app;
18
19import com.android.internal.view.menu.ActionMenu;
20import com.android.internal.view.menu.ActionMenuItem;
21import com.android.internal.widget.ActionBarContextView;
22import com.android.internal.widget.ActionBarView;
23
24import android.app.ActionBar;
25import android.graphics.drawable.Drawable;
Adam Powell0e94b512010-06-29 17:58:20 -070026import android.os.Handler;
Adam Powell89e06452010-06-23 20:24:52 -070027import android.view.Menu;
28import android.view.MenuItem;
29import android.view.View;
30import android.widget.LinearLayout;
31import android.widget.SpinnerAdapter;
32import android.widget.ViewAnimator;
33
34/**
35 * ActionBarImpl is the ActionBar implementation used
36 * by devices of all screen sizes. If it detects a compatible decor,
37 * it will split contextual modes across both the ActionBarView at
38 * the top of the screen and a horizontal LinearLayout at the bottom
39 * which is normally hidden.
40 */
41public class ActionBarImpl extends ActionBar {
42 private static final int NORMAL_VIEW = 0;
43 private static final int CONTEXT_VIEW = 1;
44
45 private ViewAnimator mAnimatorView;
46 private ActionBarView mActionView;
47 private ActionBarContextView mUpperContextView;
48 private LinearLayout mLowerContextView;
49
50 private ContextMode mContextMode;
51
52 private static final int CONTEXT_DISPLAY_NORMAL = 0;
53 private static final int CONTEXT_DISPLAY_SPLIT = 1;
54
55 private int mContextDisplayMode;
Adam Powell0e94b512010-06-29 17:58:20 -070056
57 final Handler mHandler = new Handler();
58 final Runnable mCloseContext = new Runnable() {
59 public void run() {
60 mUpperContextView.closeMode();
61 if (mLowerContextView != null) {
62 mLowerContextView.removeAllViews();
63 }
64 }
65 };
66
Adam Powell89e06452010-06-23 20:24:52 -070067 public ActionBarImpl(View decor) {
68 mActionView = (ActionBarView) decor.findViewById(com.android.internal.R.id.action_bar);
69 mUpperContextView = (ActionBarContextView) decor.findViewById(
70 com.android.internal.R.id.action_context_bar);
71 mLowerContextView = (LinearLayout) decor.findViewById(
72 com.android.internal.R.id.lower_action_context_bar);
73 mAnimatorView = (ViewAnimator) decor.findViewById(
74 com.android.internal.R.id.action_bar_animator);
75
76 if (mActionView == null || mUpperContextView == null || mAnimatorView == null) {
77 throw new IllegalStateException(getClass().getSimpleName() + " can only be used " +
78 "with a compatible window decor layout");
79 }
Adam Powell0e94b512010-06-29 17:58:20 -070080
Adam Powell89e06452010-06-23 20:24:52 -070081 mContextDisplayMode = mLowerContextView == null ?
82 CONTEXT_DISPLAY_NORMAL : CONTEXT_DISPLAY_SPLIT;
83 }
84
85 public void setCustomNavigationMode(View view) {
86 mActionView.setCustomNavigationView(view);
87 mActionView.setCallback(null);
88 }
Adam Powell0e94b512010-06-29 17:58:20 -070089
Adam Powell89e06452010-06-23 20:24:52 -070090 public void setDropdownNavigationMode(SpinnerAdapter adapter, NavigationCallback callback) {
91 mActionView.setCallback(callback);
92 mActionView.setNavigationMode(NAVIGATION_MODE_DROPDOWN_LIST);
93 mActionView.setDropdownAdapter(adapter);
94 }
Adam Powell0e94b512010-06-29 17:58:20 -070095
96 public void setStandardNavigationMode() {
97 mActionView.setNavigationMode(NAVIGATION_MODE_STANDARD);
98 mActionView.setCallback(null);
99 }
100
Adam Powell89e06452010-06-23 20:24:52 -0700101 public void setStandardNavigationMode(CharSequence title) {
102 setStandardNavigationMode(title, null);
103 }
Adam Powell0e94b512010-06-29 17:58:20 -0700104
Adam Powell89e06452010-06-23 20:24:52 -0700105 public void setStandardNavigationMode(CharSequence title, CharSequence subtitle) {
106 mActionView.setNavigationMode(NAVIGATION_MODE_STANDARD);
107 mActionView.setTitle(title);
108 mActionView.setSubtitle(subtitle);
109 mActionView.setCallback(null);
110 }
111
Adam Powell0e94b512010-06-29 17:58:20 -0700112 public void setTitle(CharSequence title) {
113 mActionView.setTitle(title);
114 }
115
116 public void setSubtitle(CharSequence subtitle) {
117 mActionView.setSubtitle(subtitle);
118 }
119
Adam Powell89e06452010-06-23 20:24:52 -0700120 public void setDisplayOptions(int options) {
121 mActionView.setDisplayOptions(options);
122 }
Adam Powell0e94b512010-06-29 17:58:20 -0700123
Adam Powell89e06452010-06-23 20:24:52 -0700124 public void setDisplayOptions(int options, int mask) {
125 final int current = mActionView.getDisplayOptions();
126 mActionView.setDisplayOptions((options & mask) | (current & ~mask));
127 }
128
129 public void setBackgroundDrawable(Drawable d) {
130 mActionView.setBackgroundDrawable(d);
131 }
132
133 public View getCustomNavigationView() {
134 return mActionView.getCustomNavigationView();
135 }
136
137 public CharSequence getTitle() {
138 return mActionView.getTitle();
139 }
140
141 public CharSequence getSubtitle() {
142 return mActionView.getSubtitle();
143 }
144
145 public int getNavigationMode() {
146 return mActionView.getNavigationMode();
147 }
148
149 public int getDisplayOptions() {
150 return mActionView.getDisplayOptions();
151 }
152
153 @Override
154 public void startContextMode(ContextModeCallback callback) {
155 if (mContextMode != null) {
156 mContextMode.finish();
157 }
158 mContextMode = new ContextMode(callback);
159 if (callback.onCreateContextMode(mContextMode, mContextMode.getMenu())) {
160 mContextMode.invalidate();
161 mUpperContextView.initForMode(mContextMode);
162 mAnimatorView.setDisplayedChild(CONTEXT_VIEW);
163 if (mLowerContextView != null) {
164 // TODO animate this
165 mLowerContextView.setVisibility(View.VISIBLE);
166 }
167 }
168 }
169
170 @Override
171 public void finishContextMode() {
172 if (mContextMode != null) {
173 mContextMode.finish();
174 }
175 }
176
177 /**
178 * @hide
179 */
180 public class ContextMode extends ActionBar.ContextMode {
181 private ContextModeCallback mCallback;
182 private ActionMenu mMenu;
183
184 public ContextMode(ContextModeCallback callback) {
185 mCallback = callback;
186 mMenu = new ActionMenu(mActionView.getContext());
187 }
188
189 @Override
190 public Menu getMenu() {
191 return mMenu;
192 }
193
194 @Override
195 public void finish() {
196 mCallback.onDestroyContextMode(this);
Adam Powell89e06452010-06-23 20:24:52 -0700197 mAnimatorView.setDisplayedChild(NORMAL_VIEW);
Adam Powell0e94b512010-06-29 17:58:20 -0700198
199 // Clear out the context mode views after the animation finishes
200 mHandler.postDelayed(mCloseContext, mAnimatorView.getOutAnimation().getDuration());
201
Adam Powell89e06452010-06-23 20:24:52 -0700202 if (mLowerContextView != null && mLowerContextView.getVisibility() != View.GONE) {
203 // TODO Animate this
204 mLowerContextView.setVisibility(View.GONE);
205 }
206 mContextMode = null;
207 }
208
209 @Override
210 public void invalidate() {
211 if (mCallback.onPrepareContextMode(this, mMenu)) {
212 // Refresh content in both context views
213 }
214 }
215
216 @Override
217 public void setCustomView(View view) {
218 mUpperContextView.setCustomView(view);
219 }
220
221 @Override
222 public void setSubtitle(CharSequence subtitle) {
223 mUpperContextView.setSubtitle(subtitle);
224 }
225
226 @Override
227 public void setTitle(CharSequence title) {
228 mUpperContextView.setTitle(title);
229 }
230
231 public void dispatchOnContextItemClicked(MenuItem item) {
232 ActionMenuItem actionItem = (ActionMenuItem) item;
233 if (!actionItem.invoke()) {
234 mCallback.onContextItemClicked(this, item);
235 }
236 }
237 }
238}