Commit 7561e2f9 authored by Tomasz Wiszkowski's avatar Tomasz Wiszkowski Committed by Commit Bot

Create a basic TileView MVC component.

This change introduces a set of classes and properties enabling the
TileView to become a MVC component.

The change collapses the TileView and TileWithTextView classes into
one to avoid awkward naming. The TileView base class is never used as
a stand-alone component and MVC allows the class to control the
visibility of the TextView with ease.

The MVC component features all UI specific features used by TileView,
TileWithTextView, SuggestionsTileView and TopSitesTileView.

Bug: 1106109
Change-Id: I3dde36e767ae876759089bd3580ac5d9ac61e66e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2424490
Commit-Queue: Tomasz Wiszkowski <ender@google.com>
Reviewed-by: default avatarCathy Li <chili@chromium.org>
Reviewed-by: default avatarFilip Gorski <fgorski@chromium.org>
Cr-Commit-Position: refs/heads/master@{#809898}
parent f9bf46a2
......@@ -1446,7 +1446,10 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/suggestions/tile/TileGroupDelegateImpl.java",
"java/src/org/chromium/chrome/browser/suggestions/tile/TileRenderer.java",
"java/src/org/chromium/chrome/browser/suggestions/tile/TileView.java",
"java/src/org/chromium/chrome/browser/suggestions/tile/TileWithTextView.java",
"java/src/org/chromium/chrome/browser/suggestions/tile/TileViewBinder.java",
"java/src/org/chromium/chrome/browser/suggestions/tile/TileViewCoordinator.java",
"java/src/org/chromium/chrome/browser/suggestions/tile/TileViewMediator.java",
"java/src/org/chromium/chrome/browser/suggestions/tile/TileViewProperties.java",
"java/src/org/chromium/chrome/browser/suggestions/tile/TopSitesTileView.java",
"java/src/org/chromium/chrome/browser/survey/ChromeSurveyController.java",
"java/src/org/chromium/chrome/browser/survey/SurveyController.java",
......
......@@ -16,13 +16,13 @@ import androidx.core.graphics.drawable.RoundedBitmapDrawable;
import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.suggestions.tile.TileWithTextView;
import org.chromium.chrome.browser.suggestions.tile.TileView;
import org.chromium.components.browser_ui.widget.RoundedIconGenerator;
/**
* View for a category name and site tiles.
*/
public class ExploreSitesTileView extends TileWithTextView {
public class ExploreSitesTileView extends TileView {
private static final int TITLE_LINES = 2;
private final int mIconCornerRadius;
......
......@@ -16,7 +16,7 @@ import org.chromium.chrome.browser.suggestions.SiteSuggestion;
* The view for a site suggestion tile. Displays the title of the site beneath a large icon. If a
* large icon isn't available, displays a rounded rectangle with a single letter in its place.
*/
public class SuggestionsTileView extends TileWithTextView {
public class SuggestionsTileView extends TileView {
/** The data currently associated to this tile. */
private SiteSuggestion mData;
......
......@@ -9,6 +9,7 @@ import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import org.chromium.chrome.R;
......@@ -19,6 +20,7 @@ import org.chromium.chrome.R;
*/
public class TileView extends FrameLayout {
private ImageView mBadgeView;
private TextView mTitleView;
protected ImageView mIconView;
/**
......@@ -34,17 +36,21 @@ public class TileView extends FrameLayout {
mIconView = findViewById(R.id.tile_view_icon);
mBadgeView = findViewById(R.id.offline_badge);
mTitleView = findViewById(R.id.tile_view_title);
}
/**
* Initializes the view. This should be called immediately after inflation.
* Initializes the view. Non-MVC components should call this immediately after inflation.
*
* @param title The title of the tile.
* @param showOfflineBadge Whether to show the offline badge.
* @param icon The icon to display on the tile.
* @param titleLines The number of text lines to use for the tile title.
*/
public void initialize(boolean showOfflineBadge, Drawable icon) {
void initialize(String title, boolean showOfflineBadge, Drawable icon, int titleLines) {
setOfflineBadgeVisibility(showOfflineBadge);
setIconDrawable(icon);
setTitle(title, titleLines);
}
/**
......@@ -55,7 +61,13 @@ public class TileView extends FrameLayout {
}
/** Shows or hides the offline badge to reflect the offline availability. */
public void setOfflineBadgeVisibility(boolean showOfflineBadge) {
void setOfflineBadgeVisibility(boolean showOfflineBadge) {
mBadgeView.setVisibility(showOfflineBadge ? VISIBLE : GONE);
}
/** Sets the title text and number lines. */
public void setTitle(String title, int titleLines) {
mTitleView.setLines(titleLines);
mTitleView.setText(title);
}
}
// Copyright 2020 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.suggestions.tile;
import android.view.View;
import android.view.ViewGroup.MarginLayoutParams;
import android.widget.ImageView;
import android.widget.TextView;
import org.chromium.chrome.R;
import org.chromium.ui.modelutil.PropertyKey;
import org.chromium.ui.modelutil.PropertyModel;
/** Binder wiring for the TileView. */
public class TileViewBinder {
/** @see PropertyModelChangeProcessor.ViewBinder#bind(Object, Object, Object) */
public static void bind(PropertyModel model, TileView view, PropertyKey propertyKey) {
if (propertyKey == TileViewProperties.TITLE) {
final TextView textView = view.findViewById(R.id.tile_view_title);
textView.setText(model.get(TileViewProperties.TITLE));
} else if (propertyKey == TileViewProperties.TITLE_LINES) {
final TextView textView = view.findViewById(R.id.tile_view_title);
textView.setLines(model.get(TileViewProperties.TITLE_LINES));
} else if (propertyKey == TileViewProperties.ICON) {
final ImageView iconView = view.findViewById(R.id.tile_view_icon);
iconView.setImageDrawable(model.get(TileViewProperties.ICON));
} else if (propertyKey == TileViewProperties.BADGE_VISIBLE) {
final View badgeView = view.findViewById(R.id.offline_badge);
final boolean isVisible = model.get(TileViewProperties.BADGE_VISIBLE);
badgeView.setVisibility(isVisible ? View.VISIBLE : View.GONE);
} else if (propertyKey == TileViewProperties.SHOW_LARGE_ICON) {
final boolean useLargeIcon = model.get(TileViewProperties.SHOW_LARGE_ICON);
final int iconEdgeSize = view.getResources().getDimensionPixelSize(useLargeIcon
? R.dimen.tile_view_icon_size
: R.dimen.tile_view_icon_size_modern);
final int iconTopMarginSize = view.getResources().getDimensionPixelOffset(useLargeIcon
? R.dimen.tile_view_icon_background_margin_top_modern
: R.dimen.tile_view_icon_margin_top_modern);
final View iconView = view.findViewById(R.id.tile_view_icon);
final MarginLayoutParams params = (MarginLayoutParams) iconView.getLayoutParams();
params.width = iconEdgeSize;
params.height = iconEdgeSize;
params.topMargin = iconTopMarginSize;
iconView.setLayoutParams(params);
} else if (propertyKey == TileViewProperties.ON_CLICK) {
view.setOnClickListener(model.get(TileViewProperties.ON_CLICK));
} else if (propertyKey == TileViewProperties.ON_LONG_CLICK) {
view.setOnLongClickListener(model.get(TileViewProperties.ON_LONG_CLICK));
} else if (propertyKey == TileViewProperties.ON_CREATE_CONTEXT_MENU) {
view.setOnCreateContextMenuListener(
model.get(TileViewProperties.ON_CREATE_CONTEXT_MENU));
}
}
}
// Copyright 2020 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.suggestions.tile;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.LayoutRes;
import org.chromium.ui.modelutil.PropertyModel;
import org.chromium.ui.modelutil.PropertyModelChangeProcessor;
/**
* Coordinator for the TileView.
*/
public class TileViewCoordinator {
private final TileView mView;
private final TileViewMediator mMediator;
public TileViewCoordinator(Context context, @LayoutRes int tileLayoutRes, ViewGroup parent) {
mView = (TileView) LayoutInflater.from(context).inflate(tileLayoutRes, parent, false);
PropertyModel model = new PropertyModel();
PropertyModelChangeProcessor.create(model, mView, TileViewBinder::bind);
mMediator = new TileViewMediator(model);
}
/**
* Set the Tile Title.
* The title will be shown in at most TITLE_LINES lines.
*
* @param title Title to be displayed.
*/
public void setTitle(String title) {
mMediator.setTitle(title);
}
/**
* Set the max number of lines for the TextView showing the TITLE.
*
* @param lines Maximum number of lines that can be used to present the Title.
*/
public void setTitleLines(int lines) {
mMediator.setTitleLines(lines);
}
/**
* Set the Tile Icon.
*
* @param icon Icon to show within the tile.
*/
public void setIcon(Drawable icon) {
mMediator.setIcon(icon);
}
/**
* Set whether the Icon Badge should be visible.
*
* @param badgeVisible Whether icon badge should be visible.
*/
public void setBadgeVisible(boolean badgeVisible) {
mMediator.setBadgeVisible(badgeVisible);
}
/**
* Set whether Tile should present a large Icon.
*
* @param showLargeIcon Whether Tile Icon should be large.
*/
public void setShowLargeIcon(boolean showLargeIcon) {
mMediator.setShowLargeIcon(showLargeIcon);
}
/**
* Set the handler receiving click events.
*
* @param listener Handler receiving click events.
*/
public void setOnClickListener(View.OnClickListener listener) {
mMediator.setOnClickListener(listener);
}
/**
* Set the handler receiving long click events.
*
* @param listener Handler receiving long click events.
*/
public void setOnLongClickListener(View.OnLongClickListener listener) {
mMediator.setOnLongClickListener(listener);
}
/**
* Set the handler receiving context menu create events.
*
* @param listener Handler receiving context menu create events.
*/
public void setOnCreateContextMenuListener(View.OnCreateContextMenuListener listener) {
mMediator.setOnCreateContextMenuListener(listener);
}
}
\ No newline at end of file
// Copyright 2020 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.suggestions.tile;
import android.graphics.drawable.Drawable;
import android.view.View;
import org.chromium.ui.modelutil.PropertyModel;
/**
* Mediator for the TileView.
*/
class TileViewMediator {
private final PropertyModel mModel;
/**
* Create new TileViewMediator object.
*/
TileViewMediator(PropertyModel model) {
mModel = model;
}
/**
* Set the Tile Title.
* The title will be shown in at most TITLE_LINES lines.
*
* @param title Title to be displayed.
*/
void setTitle(String title) {
mModel.set(TileViewProperties.TITLE, title);
}
/**
* Set the max number of lines for the TextView showing the TITLE.
*
* @param lines Maximum number of lines that can be used to present the Title.
*/
void setTitleLines(int lines) {
mModel.set(TileViewProperties.TITLE_LINES, lines);
}
/**
* Set the Tile Icon.
*
* @param icon Icon to show within the tile.
*/
void setIcon(Drawable icon) {
mModel.set(TileViewProperties.ICON, icon);
}
/**
* Set whether the Icon Badge should be visible.
*
* @param badgeVisible Whether icon badge should be visible.
*/
void setBadgeVisible(boolean badgeVisible) {
mModel.set(TileViewProperties.BADGE_VISIBLE, badgeVisible);
}
/**
* Set whether Tile should present a large Icon.
*
* @param showLargeIcon Whether Tile Icon should be large.
*/
void setShowLargeIcon(boolean showLargeIcon) {
mModel.set(TileViewProperties.SHOW_LARGE_ICON, showLargeIcon);
}
/**
* Set the handler receiving click events.
*
* @param listener Handler receiving click events.
*/
void setOnClickListener(View.OnClickListener listener) {
mModel.set(TileViewProperties.ON_CLICK, listener);
}
/**
* Set the handler receiving long click events.
*
* @param listener Handler receiving long click events.
*/
void setOnLongClickListener(View.OnLongClickListener listener) {
mModel.set(TileViewProperties.ON_LONG_CLICK, listener);
}
/**
* Set the handler receiving context menu create events.
*
* @param listener Handler receiving context menu create events.
*/
void setOnCreateContextMenuListener(View.OnCreateContextMenuListener listener) {
mModel.set(TileViewProperties.ON_CREATE_CONTEXT_MENU, listener);
}
}
// Copyright 2020 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.suggestions.tile;
import android.graphics.drawable.Drawable;
import android.view.View;
import org.chromium.ui.modelutil.PropertyKey;
import org.chromium.ui.modelutil.PropertyModel.WritableBooleanPropertyKey;
import org.chromium.ui.modelutil.PropertyModel.WritableIntPropertyKey;
import org.chromium.ui.modelutil.PropertyModel.WritableObjectPropertyKey;
/** TileView properties. */
final class TileViewProperties {
/** The title of the tile. */
public static final WritableObjectPropertyKey<String> TITLE = new WritableObjectPropertyKey<>();
/** Maximum number of lines used to present the title. */
public static final WritableIntPropertyKey TITLE_LINES = new WritableIntPropertyKey();
/** The primary icon used by the tile. */
public static final WritableObjectPropertyKey<Drawable> ICON =
new WritableObjectPropertyKey<>();
/** Whether Tile should present a large icon. */
public static final WritableBooleanPropertyKey SHOW_LARGE_ICON =
new WritableBooleanPropertyKey();
/** Badge visibility. */
public static final WritableBooleanPropertyKey BADGE_VISIBLE = new WritableBooleanPropertyKey();
/** Handler receiving click events. */
public static final WritableObjectPropertyKey<View.OnClickListener> ON_CLICK =
new WritableObjectPropertyKey<>();
/** Handler receiving long-click events. */
public static final WritableObjectPropertyKey<View.OnLongClickListener> ON_LONG_CLICK =
new WritableObjectPropertyKey<>();
/** Handler receiving context menu call events. */
public static final WritableObjectPropertyKey<View.OnCreateContextMenuListener>
ON_CREATE_CONTEXT_MENU = new WritableObjectPropertyKey<>();
public static final PropertyKey[] ALL_KEYS = new PropertyKey[] {ICON, TITLE, TITLE_LINES,
BADGE_VISIBLE, SHOW_LARGE_ICON, ON_CLICK, ON_LONG_CLICK, ON_CREATE_CONTEXT_MENU};
}
// 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.suggestions.tile;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.TextView;
import org.chromium.chrome.R;
/**
* The view for a tile with icon and text.
*
* Displays the title of the site beneath a large icon.
*/
public class TileWithTextView extends TileView {
private TextView mTitleView;
/**
* Constructor for inflating from XML.
*/
public TileWithTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
mTitleView = findViewById(R.id.tile_view_title);
}
/**
* Initializes the view. This should be called immediately after inflation.
*
* @param title The title of the tile.
* @param showOfflineBadge Whether to show the offline badge.
* @param icon The icon to display on the tile.
* @param titleLines The number of text lines to use for the tile title.
*/
public void initialize(String title, boolean showOfflineBadge, Drawable icon, int titleLines) {
super.initialize(showOfflineBadge, icon);
setTitle(title, titleLines);
}
/** Sets the title text and number lines. */
public void setTitle(String title, int titleLines) {
mTitleView.setLines(titleLines);
mTitleView.setText(title);
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment