blob: b36524e2d676cb93b063692a3dcc39983daf1885 [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;
26import android.view.Menu;
27import android.view.MenuItem;
28import android.view.View;
29import android.widget.LinearLayout;
30import android.widget.SpinnerAdapter;
31import android.widget.ViewAnimator;
32
33/**
34 * ActionBarImpl is the ActionBar implementation used
35 * by devices of all screen sizes. If it detects a compatible decor,
36 * it will split contextual modes across both the ActionBarView at
37 * the top of the screen and a horizontal LinearLayout at the bottom
38 * which is normally hidden.
39 */
40public class ActionBarImpl extends ActionBar {
41 private static final int NORMAL_VIEW = 0;
42 private static final int CONTEXT_VIEW = 1;
43
44 private ViewAnimator mAnimatorView;
45 private ActionBarView mActionView;
46 private ActionBarContextView mUpperContextView;
47 private LinearLayout mLowerContextView;
48
49 private ContextMode mContextMode;
50
51 private static final int CONTEXT_DISPLAY_NORMAL = 0;
52 private static final int CONTEXT_DISPLAY_SPLIT = 1;
53
54 private int mContextDisplayMode;
55
56 public ActionBarImpl(View decor) {
57 mActionView = (ActionBarView) decor.findViewById(com.android.internal.R.id.action_bar);
58 mUpperContextView = (ActionBarContextView) decor.findViewById(
59 com.android.internal.R.id.action_context_bar);
60 mLowerContextView = (LinearLayout) decor.findViewById(
61 com.android.internal.R.id.lower_action_context_bar);
62 mAnimatorView = (ViewAnimator) decor.findViewById(
63 com.android.internal.R.id.action_bar_animator);
64
65 if (mActionView == null || mUpperContextView == null || mAnimatorView == null) {
66 throw new IllegalStateException(getClass().getSimpleName() + " can only be used " +
67 "with a compatible window decor layout");
68 }
69
70 mContextDisplayMode = mLowerContextView == null ?
71 CONTEXT_DISPLAY_NORMAL : CONTEXT_DISPLAY_SPLIT;
72 }
73
74 public void setCustomNavigationMode(View view) {
75 mActionView.setCustomNavigationView(view);
76 mActionView.setCallback(null);
77 }
78
79 public void setDropdownNavigationMode(SpinnerAdapter adapter, NavigationCallback callback) {
80 mActionView.setCallback(callback);
81 mActionView.setNavigationMode(NAVIGATION_MODE_DROPDOWN_LIST);
82 mActionView.setDropdownAdapter(adapter);
83 }
84
85 public void setStandardNavigationMode(CharSequence title) {
86 setStandardNavigationMode(title, null);
87 }
88
89 public void setStandardNavigationMode(CharSequence title, CharSequence subtitle) {
90 mActionView.setNavigationMode(NAVIGATION_MODE_STANDARD);
91 mActionView.setTitle(title);
92 mActionView.setSubtitle(subtitle);
93 mActionView.setCallback(null);
94 }
95
96 public void setDisplayOptions(int options) {
97 mActionView.setDisplayOptions(options);
98 }
99
100 public void setDisplayOptions(int options, int mask) {
101 final int current = mActionView.getDisplayOptions();
102 mActionView.setDisplayOptions((options & mask) | (current & ~mask));
103 }
104
105 public void setBackgroundDrawable(Drawable d) {
106 mActionView.setBackgroundDrawable(d);
107 }
108
109 public View getCustomNavigationView() {
110 return mActionView.getCustomNavigationView();
111 }
112
113 public CharSequence getTitle() {
114 return mActionView.getTitle();
115 }
116
117 public CharSequence getSubtitle() {
118 return mActionView.getSubtitle();
119 }
120
121 public int getNavigationMode() {
122 return mActionView.getNavigationMode();
123 }
124
125 public int getDisplayOptions() {
126 return mActionView.getDisplayOptions();
127 }
128
129 @Override
130 public void startContextMode(ContextModeCallback callback) {
131 if (mContextMode != null) {
132 mContextMode.finish();
133 }
134 mContextMode = new ContextMode(callback);
135 if (callback.onCreateContextMode(mContextMode, mContextMode.getMenu())) {
136 mContextMode.invalidate();
137 mUpperContextView.initForMode(mContextMode);
138 mAnimatorView.setDisplayedChild(CONTEXT_VIEW);
139 if (mLowerContextView != null) {
140 // TODO animate this
141 mLowerContextView.setVisibility(View.VISIBLE);
142 }
143 }
144 }
145
146 @Override
147 public void finishContextMode() {
148 if (mContextMode != null) {
149 mContextMode.finish();
150 }
151 }
152
153 /**
154 * @hide
155 */
156 public class ContextMode extends ActionBar.ContextMode {
157 private ContextModeCallback mCallback;
158 private ActionMenu mMenu;
159
160 public ContextMode(ContextModeCallback callback) {
161 mCallback = callback;
162 mMenu = new ActionMenu(mActionView.getContext());
163 }
164
165 @Override
166 public Menu getMenu() {
167 return mMenu;
168 }
169
170 @Override
171 public void finish() {
172 mCallback.onDestroyContextMode(this);
173 mUpperContextView.closeMode();
174 if (mLowerContextView != null) {
175 mLowerContextView.removeAllViews();
176 }
177 mAnimatorView.setDisplayedChild(NORMAL_VIEW);
178 if (mLowerContextView != null && mLowerContextView.getVisibility() != View.GONE) {
179 // TODO Animate this
180 mLowerContextView.setVisibility(View.GONE);
181 }
182 mContextMode = null;
183 }
184
185 @Override
186 public void invalidate() {
187 if (mCallback.onPrepareContextMode(this, mMenu)) {
188 // Refresh content in both context views
189 }
190 }
191
192 @Override
193 public void setCustomView(View view) {
194 mUpperContextView.setCustomView(view);
195 }
196
197 @Override
198 public void setSubtitle(CharSequence subtitle) {
199 mUpperContextView.setSubtitle(subtitle);
200 }
201
202 @Override
203 public void setTitle(CharSequence title) {
204 mUpperContextView.setTitle(title);
205 }
206
207 public void dispatchOnContextItemClicked(MenuItem item) {
208 ActionMenuItem actionItem = (ActionMenuItem) item;
209 if (!actionItem.invoke()) {
210 mCallback.onContextItemClicked(this, item);
211 }
212 }
213 }
214}