blob: 7540cc42a0e0ba94999d23d70374a142c3f88d60 [file] [log] [blame]
/*
* Copyright (C) 2013 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 android.support.v7.app;
import android.content.Context;
import android.content.res.Configuration;
import android.os.Bundle;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.view.WindowCompat;
import android.support.v7.internal.view.ActionModeWrapper;
import android.support.v7.internal.view.menu.MenuWrapperFactory;
import android.support.v7.view.ActionMode;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityEvent;
class ActionBarActivityDelegateHC extends ActionBarActivityDelegate {
Menu mMenu;
ActionBarActivityDelegateHC(ActionBarActivity activity) {
super(activity);
}
@Override
public ActionBar createSupportActionBar() {
return new ActionBarImplHC(mActivity, mActivity);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (mHasActionBar) {
// If action bar is requested by inheriting from the appcompat theme,
// the system will not know about that. So explicitly request for an action bar.
mActivity.requestWindowFeature(WindowCompat.FEATURE_ACTION_BAR);
}
if (mOverlayActionBar) {
mActivity.requestWindowFeature(WindowCompat.FEATURE_ACTION_BAR_OVERLAY);
}
/*
* This goofy move needs some explanation.
*
* The verifier on older platform versions has some interesting side effects if
* a class defines a method that takes a parameter of a type that doesn't exist.
* In this case, that type is android.view.ActionMode. Therefore, ActionBarActivity
* cannot override the onActionModeStarted/Finished methods without causing nastiness
* when it is loaded on older platform versions.
*
* Since these methods are actually part of the window callback and not intrinsic to
* Activity itself, we can install a little shim with the window instead that knows
* about the ActionMode class. Note that this means that any new methods added to
* Window.Callback in the future won't get proxied without updating the support lib,
* but we shouldn't be adding new methods to public interfaces that way anyway...right? ;)
*/
final Window w = mActivity.getWindow();
w.setCallback(createWindowCallbackWrapper(w.getCallback()));
}
Window.Callback createWindowCallbackWrapper(Window.Callback cb) {
return new WindowCallbackWrapper(cb);
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
}
@Override
public void onStop() {
}
@Override
public void onPostResume() {
}
@Override
public void setContentView(View v) {
mActivity.superSetContentView(v);
}
@Override
public void setContentView(int resId) {
mActivity.superSetContentView(resId);
}
@Override
public void setContentView(View v, ViewGroup.LayoutParams lp) {
mActivity.superSetContentView(v, lp);
}
@Override
public void addContentView(View v, ViewGroup.LayoutParams lp) {
mActivity.superAddContentView(v, lp);
}
@Override
public boolean supportRequestWindowFeature(int featureId) {
return mActivity.requestWindowFeature(featureId);
}
@Override
public View onCreatePanelView(int featureId) {
// Do not create custom options menu on HC+
return null;
}
@Override
public boolean onCreatePanelMenu(int featureId, Menu menu) {
if (featureId == Window.FEATURE_OPTIONS_PANEL || featureId == Window.FEATURE_ACTION_BAR) {
if (mMenu == null) {
mMenu = MenuWrapperFactory.createMenuWrapper(menu);
}
return mActivity.superOnCreatePanelMenu(featureId, mMenu);
}
return mActivity.superOnCreatePanelMenu(featureId, menu);
}
@Override
public boolean onPreparePanel(int featureId, View view, Menu menu) {
if (featureId == Window.FEATURE_OPTIONS_PANEL || featureId == Window.FEATURE_ACTION_BAR) {
return mActivity.superOnPreparePanel(featureId, view, mMenu);
}
return mActivity.superOnPreparePanel(featureId, view, menu);
}
@Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
if (featureId == Window.FEATURE_OPTIONS_PANEL) {
item = MenuWrapperFactory.createMenuItemWrapper(item);
}
return mActivity.superOnMenuItemSelected(featureId, item);
}
@Override
public void setTitle(CharSequence title) {
// Handled by framework
}
@Override
public ActionMode startSupportActionMode(ActionMode.Callback callback) {
if (callback == null) {
throw new IllegalArgumentException("ActionMode callback can not be null.");
}
Context context = getActionBarThemedContext();
ActionModeWrapper.CallbackWrapper wrappedCallback = new ActionModeWrapper.CallbackWrapper(
context, callback);
ActionModeWrapper wrappedMode = null;
android.view.ActionMode frameworkMode = mActivity.startActionMode(wrappedCallback);
if (frameworkMode != null) {
wrappedMode = new ActionModeWrapper(context,
mActivity.startActionMode(wrappedCallback));
wrappedCallback.setLastStartedActionMode(wrappedMode);
}
return wrappedMode;
}
public void onActionModeStarted(android.view.ActionMode mode) {
mActivity.onSupportActionModeStarted(
new ActionModeWrapper(getActionBarThemedContext(), mode));
}
@Override
void setSupportProgressBarVisibility(boolean visible) {
mActivity.setProgressBarVisibility(visible);
}
@Override
void setSupportProgressBarIndeterminateVisibility(boolean visible) {
mActivity.setProgressBarIndeterminateVisibility(visible);
}
@Override
void setSupportProgressBarIndeterminate(boolean indeterminate) {
mActivity.setProgressBarIndeterminate(indeterminate);
}
@Override
void setSupportProgress(int progress) {
mActivity.setProgress(progress);
}
public void onActionModeFinished(android.view.ActionMode mode) {
mActivity.onSupportActionModeFinished(
new ActionModeWrapper(getActionBarThemedContext(), mode));
}
@Override
public void supportInvalidateOptionsMenu() {
mMenu = null;
}
@Override
public boolean onBackPressed() {
return false;
}
@Override
public ActionBarDrawerToggle.Delegate getDrawerToggleDelegate() {
// Return null so that ActionBarDrawableToggle uses it's standard impl
return null;
}
class WindowCallbackWrapper implements Window.Callback {
final Window.Callback mWrapped;
public WindowCallbackWrapper(Window.Callback wrapped) {
mWrapped = wrapped;
}
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
return mWrapped.dispatchKeyEvent(event);
}
@Override
public boolean dispatchKeyShortcutEvent(KeyEvent event) {
return mWrapped.dispatchKeyShortcutEvent(event);
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
return mWrapped.dispatchTouchEvent(event);
}
@Override
public boolean dispatchTrackballEvent(MotionEvent event) {
return mWrapped.dispatchTrackballEvent(event);
}
public boolean dispatchGenericMotionEvent(MotionEvent event) {
// This method didn't exist until API 12. Overridden elsewhere.
return false;
}
@Override
public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
return mWrapped.dispatchPopulateAccessibilityEvent(event);
}
@Override
public View onCreatePanelView(int featureId) {
return mWrapped.onCreatePanelView(featureId);
}
@Override
public boolean onCreatePanelMenu(int featureId, Menu menu) {
return mWrapped.onCreatePanelMenu(featureId, menu);
}
@Override
public boolean onPreparePanel(int featureId, View view, Menu menu) {
return mWrapped.onPreparePanel(featureId, view, menu);
}
@Override
public boolean onMenuOpened(int featureId, Menu menu) {
return mWrapped.onMenuOpened(featureId, menu);
}
@Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
return mWrapped.onMenuItemSelected(featureId, item);
}
@Override
public void onWindowAttributesChanged(WindowManager.LayoutParams attrs) {
mWrapped.onWindowAttributesChanged(attrs);
}
@Override
public void onContentChanged() {
mWrapped.onContentChanged();
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
mWrapped.onWindowFocusChanged(hasFocus);
}
@Override
public void onAttachedToWindow() {
mWrapped.onAttachedToWindow();
}
@Override
public void onDetachedFromWindow() {
mWrapped.onDetachedFromWindow();
}
@Override
public void onPanelClosed(int featureId, Menu menu) {
mWrapped.onPanelClosed(featureId, menu);
}
@Override
public boolean onSearchRequested() {
return mWrapped.onSearchRequested();
}
@Override
public android.view.ActionMode onWindowStartingActionMode(
android.view.ActionMode.Callback callback) {
return mWrapped.onWindowStartingActionMode(callback);
}
/*
* And here are the money methods, the reason why this wrapper exists:
*/
@Override
public void onActionModeStarted(android.view.ActionMode mode) {
mWrapped.onActionModeStarted(mode);
ActionBarActivityDelegateHC.this.onActionModeStarted(mode);
}
@Override
public void onActionModeFinished(android.view.ActionMode mode) {
mWrapped.onActionModeFinished(mode);
ActionBarActivityDelegateHC.this.onActionModeFinished(mode);
}
}
}