// Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. package org.chromium.chrome.browser.compositor.layouts.eventfilter; import android.content.Context; import android.view.MotionEvent; import java.util.Arrays; /** * A {@link CascadeEventFilter} delegates all the events coming its way to another filter. */ public class CascadeEventFilter extends EventFilter { private EventFilter[] mDelegates; private EventFilter mActiveDelegate = null; /** * Creates a {@link CascadeEventFilter}. * * The delegates will be queried in the order specified in this list (0 -> count). Once a * delegate takes ownership of the event by returning {@code true} from * {@link EventFilter#onInterceptTouchEventInternal(MotionEvent, boolean)} it will get all * subsequent events for the same gesture to * {@link EventFilter#onTouchEventInternal(MotionEvent)}. * * @param context A {@link Context} instance. * @param host The host that is responsible for managing event filter status changes. * @param delegates The list of delegates to be given the chance to process the event. */ public CascadeEventFilter(Context context, EventFilterHost host, EventFilter[] delegates) { super(context, host, false); mDelegates = Arrays.copyOf(delegates, delegates.length); } @Override public boolean onInterceptTouchEventInternal(MotionEvent origEvent, boolean isKeyboardShowing) { mActiveDelegate = null; MotionEvent offsetEvent = MotionEvent.obtain(origEvent); offsetEvent.offsetLocation(mCurrentTouchOffsetX, mCurrentTouchOffsetY); for (int i = 0; i < mDelegates.length; ++i) { MotionEvent e = mDelegates[i].autoOffsetEvents() ? offsetEvent : origEvent; if (mDelegates[i].onInterceptTouchEventInternal(e, isKeyboardShowing)) { mActiveDelegate = mDelegates[i]; offsetEvent.recycle(); return true; } } offsetEvent.recycle(); return false; } @Override public boolean onTouchEventInternal(MotionEvent e) { if (mActiveDelegate != null) { if (mActiveDelegate.autoOffsetEvents()) { e.offsetLocation(mCurrentTouchOffsetX, mCurrentTouchOffsetY); } return mActiveDelegate.onTouchEventInternal(e); } return false; } }