blob: 1872b96d8ce746f695add0f27cd973eaa4333c34 [file] [log] [blame]
// Copyright 2018 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.contextual_suggestions;
import android.content.Context;
import android.support.v4.view.ViewCompat;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.OnScrollListener;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.native_page.ContextMenuManager;
import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.browser.suggestions.SuggestionsRecyclerView;
import org.chromium.chrome.browser.suggestions.SuggestionsUiDelegate;
import org.chromium.chrome.browser.widget.displaystyle.UiConfig;
import org.chromium.ui.base.WindowAndroid;
/**
* Coordinator for the content sub-component. Responsible for communication with the parent
* {@link ContextualSuggestionsCoordinator} and lifecycle of sub-component objects.
*/
class ContentCoordinator {
private static final String CONTEXT_MENU_USER_ACTION_PREFIX = "ContextualSuggestions";
private final SuggestionsRecyclerView mRecyclerView;
private ContextualSuggestionsModel mModel;
private WindowAndroid mWindowAndroid;
private ContextMenuManager mContextMenuManager;
private ContextualSuggestionsAdapter mAdapter;
/**
* Construct a new {@link ContentCoordinator}.
* @param context The {@link Context} used to retrieve resources.
* @param parentView The parent {@link View} to which the content will eventually be attached.
*/
ContentCoordinator(Context context, ViewGroup parentView) {
mRecyclerView = (SuggestionsRecyclerView) LayoutInflater.from(context).inflate(
R.layout.contextual_suggestions_layout, parentView, false);
}
/** @return The content {@link View}. */
View getView() {
return mRecyclerView;
}
/** @return The vertical scroll offset of the content view. */
int getVerticalScrollOffset() {
return mRecyclerView.computeVerticalScrollOffset();
}
/**
* Show suggestions, retrieved from the model, in the content view.
*
* @param context The {@link Context} used to retrieve resources.
* @param profile The regular {@link Profile}.
* @param uiDelegate The {@link SuggestionsUiDelegate} used to help construct items in the
* content view.
* @param model The {@link ContextualSuggestionsModel} for the component.
* @param windowAndroid The {@link WindowAndroid} for attaching a context menu listener.
* @param closeContextMenuCallback The callback when a context menu is closed.
*/
void showSuggestions(Context context, Profile profile, SuggestionsUiDelegate uiDelegate,
ContextualSuggestionsModel model, WindowAndroid windowAndroid,
Runnable closeContextMenuCallback) {
mModel = model;
mWindowAndroid = windowAndroid;
mContextMenuManager = new ContextMenuManager(uiDelegate.getNavigationDelegate(),
mRecyclerView::setTouchEnabled, closeContextMenuCallback,
CONTEXT_MENU_USER_ACTION_PREFIX);
mWindowAndroid.addContextMenuCloseListener(mContextMenuManager);
ClusterList clusterList = mModel.getClusterList();
mAdapter = new ContextualSuggestionsAdapter(
profile, new UiConfig(mRecyclerView), uiDelegate, mContextMenuManager, clusterList);
mRecyclerView.setAdapter(mAdapter);
// TODO(twellington): Should this be a proper model property, set by the mediator and bound
// to the RecyclerView?
mRecyclerView.addOnScrollListener(new OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
mModel.setToolbarShadowVisibility(mRecyclerView.canScrollVertically(-1));
}
});
if (mModel.isSlimPeekEnabled()) {
ViewCompat.setPaddingRelative(mRecyclerView, ViewCompat.getPaddingStart(mRecyclerView),
context.getResources().getDimensionPixelSize(
R.dimen.bottom_control_container_slim_expanded_height),
ViewCompat.getPaddingEnd(mRecyclerView), mRecyclerView.getPaddingBottom());
}
}
/** Destroy the content component. */
void destroy() {
// The model outlives the content sub-component. Remove the observer so that this object
// can be garbage collected.
if (mAdapter != null) {
mModel.getClusterList().removeObserver(mAdapter);
}
if (mWindowAndroid != null) {
mWindowAndroid.removeContextMenuCloseListener(mContextMenuManager);
}
}
}