1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.android.setupdesign.template;
18 
19 import static android.content.res.ColorStateList.valueOf;
20 
21 import android.content.Context;
22 import android.content.res.ColorStateList;
23 import android.content.res.TypedArray;
24 import android.graphics.Typeface;
25 import androidx.annotation.AttrRes;
26 import androidx.annotation.NonNull;
27 import androidx.annotation.Nullable;
28 import android.util.AttributeSet;
29 import android.util.TypedValue;
30 import android.view.Gravity;
31 import android.view.ViewParent;
32 import android.widget.LinearLayout;
33 import android.widget.TextView;
34 import com.google.android.setupcompat.R;
35 import com.google.android.setupcompat.internal.TemplateLayout;
36 import com.google.android.setupcompat.partnerconfig.PartnerConfig;
37 import com.google.android.setupcompat.partnerconfig.PartnerConfigHelper;
38 import com.google.android.setupcompat.template.Mixin;
39 import com.google.android.setupdesign.GlifLayout;
40 import java.util.Locale;
41 
42 /**
43  * A {@link com.google.android.setupcompat.template.Mixin} for setting and getting the header text.
44  */
45 public class HeaderMixin implements Mixin {
46 
47   private final TemplateLayout templateLayout;
48 
49   /**
50    * @param layout The layout this Mixin belongs to.
51    * @param attrs XML attributes given to the layout.
52    * @param defStyleAttr The default style attribute as given to the constructor of the layout.
53    */
HeaderMixin( @onNull TemplateLayout layout, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr)54   public HeaderMixin(
55       @NonNull TemplateLayout layout, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) {
56     templateLayout = layout;
57 
58     final TypedArray a =
59         layout
60             .getContext()
61             .obtainStyledAttributes(attrs, R.styleable.SucHeaderMixin, defStyleAttr, 0);
62 
63     // Set the header text
64     final CharSequence headerText = a.getText(R.styleable.SucHeaderMixin_sucHeaderText);
65     if (headerText != null) {
66       setText(headerText);
67     }
68     // Set the header text color
69     final ColorStateList headerTextColor =
70         a.getColorStateList(R.styleable.SucHeaderMixin_sucHeaderTextColor);
71     if (headerTextColor != null) {
72       setTextColor(headerTextColor);
73     }
74 
75     a.recycle();
76   }
77 
78   /** See {@link #applyPartnerCustomizationStyle(Context, TextView)}. */
applyPartnerCustomizationStyle()79   public void applyPartnerCustomizationStyle() {
80     final Context context = templateLayout.getContext();
81     TextView header = templateLayout.findManagedViewById(R.id.suc_layout_title);
82     applyPartnerCustomizationStyle(context, header);
83   }
84 
85   /**
86    * Use the given {@code header} to apply heavy theme. If {@link
87    * com.google.android.setupdesign.GlifLayout#shouldApplyPartnerHeavyThemeResource()} is true,
88    * {@code header} can be customized style from partner configuration.
89    *
90    * @param context The context of client activity.
91    * @param header The icon image to use for apply heavy theme.
92    */
applyPartnerCustomizationStyle(Context context, @Nullable TextView header)93   private void applyPartnerCustomizationStyle(Context context, @Nullable TextView header) {
94     if (header != null
95         && (templateLayout instanceof GlifLayout)
96         && ((GlifLayout) templateLayout).shouldApplyPartnerHeavyThemeResource()) {
97       int textColor =
98           PartnerConfigHelper.get(context)
99               .getColor(context, PartnerConfig.CONFIG_HEADER_TEXT_COLOR);
100       if (textColor != 0) {
101         setTextColor(valueOf(textColor));
102       }
103 
104       float textSize =
105           PartnerConfigHelper.get(context)
106               .getDimension(context, PartnerConfig.CONFIG_HEADER_TEXT_SIZE);
107       if (textSize != 0) {
108         setTextSize(textSize);
109       }
110 
111       String fontFamily =
112           PartnerConfigHelper.get(context)
113               .getString(context, PartnerConfig.CONFIG_HEADER_FONT_FAMILY);
114       if (fontFamily != null) {
115         setFontFamily(Typeface.create(fontFamily, Typeface.NORMAL));
116       }
117 
118       String gravity =
119           PartnerConfigHelper.get(context).getString(context, PartnerConfig.CONFIG_LAYOUT_GRAVITY);
120       if (gravity != null) {
121         switch (gravity.toLowerCase(Locale.ROOT)) {
122           case "center":
123             setGravity(header, Gravity.CENTER);
124             break;
125           case "start":
126             setGravity(header, Gravity.START);
127             break;
128           default: // fall out
129         }
130       }
131 
132       int color =
133           PartnerConfigHelper.get(context)
134               .getColor(context, PartnerConfig.CONFIG_HEADER_AREA_BACKGROUND_COLOR);
135       setBackgroundColor(color);
136     }
137   }
138 
139   /** @return The TextView displaying the header. */
getTextView()140   public TextView getTextView() {
141     return (TextView) templateLayout.findManagedViewById(R.id.suc_layout_title);
142   }
143 
144   /**
145    * Sets the header text. This can also be set via the XML attribute {@code app:sucHeaderText}.
146    *
147    * @param title The resource ID of the text to be set as header.
148    */
setText(int title)149   public void setText(int title) {
150     final TextView titleView = getTextView();
151     if (titleView != null) {
152       titleView.setText(title);
153     }
154   }
155 
156   /**
157    * Sets the header text. This can also be set via the XML attribute {@code app:sucHeaderText}.
158    *
159    * @param title The text to be set as header.
160    */
setText(CharSequence title)161   public void setText(CharSequence title) {
162     final TextView titleView = getTextView();
163     if (titleView != null) {
164       titleView.setText(title);
165     }
166   }
167 
168   /** @return The current header text. */
getText()169   public CharSequence getText() {
170     final TextView titleView = getTextView();
171     return titleView != null ? titleView.getText() : null;
172   }
173 
setTextSize(float sizePx)174   private void setTextSize(float sizePx) {
175     final TextView titleView = getTextView();
176     if (titleView != null) {
177       titleView.setTextSize(TypedValue.COMPLEX_UNIT_PX, sizePx);
178     }
179   }
180 
181   /**
182    * Sets the color of the header text. This can also be set via XML using {@code
183    * app:sucHeaderTextColor}.
184    *
185    * @param color The text color of the header.
186    */
setTextColor(ColorStateList color)187   public void setTextColor(ColorStateList color) {
188     final TextView titleView = getTextView();
189     if (titleView != null) {
190       titleView.setTextColor(color);
191     }
192   }
193 
194   /** Sets the background color of the header's parent LinearLayout */
setBackgroundColor(int color)195   public void setBackgroundColor(int color) {
196     final TextView titleView = getTextView();
197     if (titleView != null) {
198       ViewParent parent = titleView.getParent();
199       if (parent instanceof LinearLayout) {
200         ((LinearLayout) parent).setBackgroundColor(color);
201       }
202     }
203   }
204 
setFontFamily(Typeface fontFamily)205   private void setFontFamily(Typeface fontFamily) {
206     final TextView titleView = getTextView();
207     if (titleView != null) {
208       titleView.setTypeface(fontFamily);
209     }
210   }
211 
212   /** Returns the current text color of the header. */
getTextColor()213   public ColorStateList getTextColor() {
214     final TextView titleView = getTextView();
215     return titleView != null ? titleView.getTextColors() : null;
216   }
217 
setGravity(TextView header, int gravity)218   private void setGravity(TextView header, int gravity) {
219     header.setGravity(gravity);
220   }
221 }
222