blob: d1c6dcdbe763dfe242e201ad94b4430bc84e8e05 [file] [log] [blame]
/*
* Copyright (C) 2020 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 com.android.customization.picker.theme;
import android.content.Context;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.MainThread;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.OnLifecycleEvent;
import com.android.customization.model.theme.ThemeBundle;
import com.android.customization.model.theme.ThemeBundle.PreviewInfo;
import com.android.customization.picker.TimeTicker;
import com.android.wallpaper.R;
import java.text.DateFormat;
import java.text.FieldPosition;
import java.util.Calendar;
import java.util.List;
import java.util.TimeZone;
/** A class to load the {@link ThemeBundle} preview to the view. */
class ThemeOptionPreviewer implements LifecycleObserver {
/**
* Maps which icon from ResourceConstants#ICONS_FOR_PREVIEW to use for each icon in the
* top bar (fake "status bar") of the cover page.
*/
private static final int [] sTopBarIconToPreviewIcon = new int [] { 0, 6, 7 };
private int[] mShapeIconIds = {
R.id.shape_preview_icon_0, R.id.shape_preview_icon_1,
R.id.shape_preview_icon_2, R.id.shape_preview_icon_3
};
private final Context mContext;
private View mContentView;
private TextView mClock;
private TimeTicker mTicker;
ThemeOptionPreviewer(Lifecycle lifecycle, Context context, ViewGroup previewContainer) {
lifecycle.addObserver(this);
mContext = context;
mContentView = LayoutInflater.from(context).inflate(
R.layout.theme_preview_content_v2, previewContainer);
mClock = mContentView.findViewById(R.id.theme_preview_clock);
updateTime();
}
/** Loads the Theme option into the container view. */
public void setThemeBundle(ThemeBundle themeBundle) {
PreviewInfo previewInfo = themeBundle.getPreviewInfo();
setHeadlineFont(previewInfo.headlineFontFamily);
setTopBarIcons(previewInfo.icons);
setShapeIcons(previewInfo.shapeAppIcons);
setQsbRadius(previewInfo.bottomSheeetCornerRadius);
}
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
@MainThread
public void onResume() {
mTicker = TimeTicker.registerNewReceiver(mContext, this::updateTime);
updateTime();
}
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
@MainThread
public void onPause() {
if (mContext != null) {
mContext.unregisterReceiver(mTicker);
}
}
private void setHeadlineFont(Typeface headlineFont) {
mClock.setTypeface(headlineFont);
// Update other text style here.
}
private void setTopBarIcons(List<Drawable> icons) {
ViewGroup iconsContainer = mContentView.findViewById(R.id.theme_preview_top_bar_icons);
for (int i = 0; i < iconsContainer.getChildCount(); i++) {
int iconIndex = sTopBarIconToPreviewIcon[i];
if (iconIndex < icons.size()) {
((ImageView) iconsContainer.getChildAt(i))
.setImageDrawable(icons.get(iconIndex).getConstantState()
.newDrawable().mutate());
} else {
iconsContainer.getChildAt(i).setVisibility(View.GONE);
}
}
}
private void setShapeIcons(List<Drawable> icons) {
for (int i = 0; i < mShapeIconIds.length && i < icons.size(); i++) {
ImageView iconView = mContentView.findViewById(mShapeIconIds[i]);
iconView.setBackground(icons.get(i));
}
}
private void setQsbRadius(int cornerRadius) {
View qsb = mContentView.findViewById(R.id.theme_qsb);
if (qsb != null && qsb.getVisibility() == View.VISIBLE) {
if (qsb.getBackground() instanceof GradientDrawable) {
GradientDrawable bg = (GradientDrawable) qsb.getBackground();
float radius = useRoundedQSB(cornerRadius)
? (float) qsb.getLayoutParams().height / 2 : cornerRadius;
bg.setCornerRadii(new float[]{
radius, radius, radius, radius,
radius, radius, radius, radius});
}
}
}
private void updateTime() {
if (mClock != null) {
mClock.setText(getFormattedTime());
}
}
private String getFormattedTime() {
DateFormat df = DateFormat.getTimeInstance(DateFormat.SHORT);
StringBuffer time = new StringBuffer();
FieldPosition amPmPosition = new FieldPosition(DateFormat.Field.AM_PM);
df.format(Calendar.getInstance(TimeZone.getDefault()).getTime(), time, amPmPosition);
if (amPmPosition.getBeginIndex() > 0) {
time.delete(amPmPosition.getBeginIndex(), amPmPosition.getEndIndex());
}
return time.toString();
}
private boolean useRoundedQSB(int cornerRadius) {
return cornerRadius >= mContext.getResources().getDimensionPixelSize(
R.dimen.roundCornerThreshold);
}
}