summaryrefslogtreecommitdiff
path: root/library/main
diff options
context:
space:
mode:
authorMaurice Lam <yukl@google.com>2015-11-13 18:19:09 -0800
committerMaurice Lam <yukl@google.com>2015-12-09 15:46:47 -0800
commitc3eebe9f664af4b77e5948a14bf266b25dc25cc8 (patch)
treeb6e67881f05b82072569bbb8ac94c69a0bf1fdcd /library/main
parent38064bc73a1ae04d94557ed35fb2f12b737a8898 (diff)
downloadsetupwizard-c3eebe9f664af4b77e5948a14bf266b25dc25cc8.tar.gz
[SuwLib] Implement pattern drawable background
- Implement the pattern background for GLIF using a custom drawable. The drawable draws the paths manually as specified in the SVG, for backwards compatibility. - Use a FrameLayout subclass to draw the custom status bar background in the case of phone layouts, and set draw the background directly for tablet / clamshell layouts. Bug: 25650709 Change-Id: I527bb47efa143ec43c1030b57087fd2414d7045b
Diffstat (limited to 'library/main')
-rw-r--r--library/main/res/layout/suw_glif_list_template_card.xml4
-rw-r--r--library/main/res/layout/suw_glif_list_template_compact.xml26
-rw-r--r--library/main/res/layout/suw_glif_template_card.xml4
-rw-r--r--library/main/res/layout/suw_glif_template_compact.xml26
-rw-r--r--library/main/res/values/attrs.xml4
-rw-r--r--library/main/res/values/layouts.xml4
-rw-r--r--library/main/src/com/android/setupwizardlib/GlifLayout.java16
-rw-r--r--library/main/src/com/android/setupwizardlib/GlifPatternDrawable.java198
-rw-r--r--library/main/src/com/android/setupwizardlib/view/StatusBarBackgroundLayout.java103
9 files changed, 381 insertions, 4 deletions
diff --git a/library/main/res/layout/suw_glif_list_template_card.xml b/library/main/res/layout/suw_glif_list_template_card.xml
index aae9388..8d7fa95 100644
--- a/library/main/res/layout/suw_glif_list_template_card.xml
+++ b/library/main/res/layout/suw_glif_list_template_card.xml
@@ -16,9 +16,11 @@
-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/suw_pattern_bg"
style="@style/SuwGlifCardBackground"
android:layout_width="match_parent"
- android:layout_height="match_parent">
+ android:layout_height="match_parent"
+ android:fitsSystemWindows="true">
<FrameLayout
style="@style/SuwGlifCardContainer"
diff --git a/library/main/res/layout/suw_glif_list_template_compact.xml b/library/main/res/layout/suw_glif_list_template_compact.xml
new file mode 100644
index 0000000..534fef2
--- /dev/null
+++ b/library/main/res/layout/suw_glif_list_template_compact.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2015 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.
+-->
+
+<com.android.setupwizardlib.view.StatusBarBackgroundLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/suw_pattern_bg"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <include layout="@layout/suw_glif_list_template_content" />
+
+</com.android.setupwizardlib.view.StatusBarBackgroundLayout>
diff --git a/library/main/res/layout/suw_glif_template_card.xml b/library/main/res/layout/suw_glif_template_card.xml
index 98f5547..d1d354f 100644
--- a/library/main/res/layout/suw_glif_template_card.xml
+++ b/library/main/res/layout/suw_glif_template_card.xml
@@ -16,9 +16,11 @@
-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/suw_pattern_bg"
style="@style/SuwGlifCardBackground"
android:layout_width="match_parent"
- android:layout_height="match_parent">
+ android:layout_height="match_parent"
+ android:fitsSystemWindows="true">
<FrameLayout
style="@style/SuwGlifCardContainer"
diff --git a/library/main/res/layout/suw_glif_template_compact.xml b/library/main/res/layout/suw_glif_template_compact.xml
new file mode 100644
index 0000000..65c582d
--- /dev/null
+++ b/library/main/res/layout/suw_glif_template_compact.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2015 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.
+-->
+
+<com.android.setupwizardlib.view.StatusBarBackgroundLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/suw_pattern_bg"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <include layout="@layout/suw_glif_template_content" />
+
+</com.android.setupwizardlib.view.StatusBarBackgroundLayout>
diff --git a/library/main/res/values/attrs.xml b/library/main/res/values/attrs.xml
index 1ac8745..1ebe286 100644
--- a/library/main/res/values/attrs.xml
+++ b/library/main/res/values/attrs.xml
@@ -60,6 +60,10 @@
<attr name="suwDividerInset" />
</declare-styleable>
+ <declare-styleable name="SuwStatusBarBackgroundLayout">
+ <attr name="suwStatusBarBackground" format="color|reference" />
+ </declare-styleable>
+
<declare-styleable name="SuwSetupWizardLayout">
<attr name="suwBackground" format="color|reference" />
<attr name="suwBackgroundTile" format="color|reference" />
diff --git a/library/main/res/values/layouts.xml b/library/main/res/values/layouts.xml
index 7b43110..e4d3327 100644
--- a/library/main/res/values/layouts.xml
+++ b/library/main/res/values/layouts.xml
@@ -24,8 +24,8 @@
<item name="suw_no_scroll_template" type="layout">@layout/suw_no_scroll_template_header</item>
<item name="suw_no_scroll_template_short" type="layout">@layout/suw_no_scroll_template_header_collapsed</item>
- <item name="suw_glif_template" type="layout">@layout/suw_glif_template_content</item>
- <item name="suw_glif_list_template" type="layout">@layout/suw_glif_list_template_content</item>
+ <item name="suw_glif_template" type="layout">@layout/suw_glif_template_compact</item>
+ <item name="suw_glif_list_template" type="layout">@layout/suw_glif_list_template_compact</item>
</resources>
diff --git a/library/main/src/com/android/setupwizardlib/GlifLayout.java b/library/main/src/com/android/setupwizardlib/GlifLayout.java
index 294cc43..f1ec6d4 100644
--- a/library/main/src/com/android/setupwizardlib/GlifLayout.java
+++ b/library/main/src/com/android/setupwizardlib/GlifLayout.java
@@ -21,6 +21,7 @@ import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
+import android.os.Build;
import android.os.Build.VERSION_CODES;
import android.util.AttributeSet;
import android.view.LayoutInflater;
@@ -30,6 +31,8 @@ import android.widget.ImageView;
import android.widget.ScrollView;
import android.widget.TextView;
+import com.android.setupwizardlib.view.StatusBarBackgroundLayout;
+
/**
* Layout for the GLIF theme used in Setup Wizard for N.
*
@@ -103,6 +106,19 @@ public class GlifLayout extends TemplateLayout {
}
a.recycle();
+
+ if (Build.VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) {
+ setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
+ final View patternBg = findViewById(R.id.suw_pattern_bg);
+ if (patternBg != null) {
+ final GlifPatternDrawable background = GlifPatternDrawable.getDefault(getContext());
+ if (patternBg instanceof StatusBarBackgroundLayout) {
+ ((StatusBarBackgroundLayout) patternBg).setStatusBarBackground(background);
+ } else {
+ patternBg.setBackground(background);
+ }
+ }
+ }
}
@Override
diff --git a/library/main/src/com/android/setupwizardlib/GlifPatternDrawable.java b/library/main/src/com/android/setupwizardlib/GlifPatternDrawable.java
new file mode 100644
index 0000000..23db40c
--- /dev/null
+++ b/library/main/src/com/android/setupwizardlib/GlifPatternDrawable.java
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2015 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.setupwizardlib;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.ColorFilter;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.os.Build;
+
+import com.android.setupwizardlib.annotations.VisibleForTesting;
+
+public class GlifPatternDrawable extends Drawable {
+
+ /* static section */
+
+ @SuppressLint("InlinedApi")
+ private static final int[] ATTRS_PRIMARY_COLOR = new int[]{ android.R.attr.colorPrimary };
+
+ private static final float VIEWBOX_HEIGHT = 768f;
+ private static final float VIEWBOX_WIDTH = 1366f;
+ private static final float SCALE_FOCUS_X = 200f;
+ private static final float SCALE_FOCUS_Y = 175f;
+
+ public static GlifPatternDrawable getDefault(Context context) {
+ int colorPrimary = 0;
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ final TypedArray a = context.obtainStyledAttributes(ATTRS_PRIMARY_COLOR);
+ colorPrimary = a.getColor(0, Color.BLACK);
+ a.recycle();
+ }
+ return new GlifPatternDrawable(colorPrimary);
+ }
+
+ /* non-static section */
+
+ private int mColor;
+ private Paint mPaint;
+ private float[] mTempHsv = new float[3];
+ private Path mTempPath = new Path();
+
+ public GlifPatternDrawable(int color) {
+ mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ setColor(color);
+ }
+
+ @Override
+ public void draw(Canvas canvas) {
+ canvas.save();
+ canvas.clipRect(getBounds());
+
+ Color.colorToHSV(mColor, mTempHsv);
+ scaleCanvasToBounds(canvas);
+
+ // Draw the pattern by creating the paths, adjusting the colors and drawing them. The path
+ // values are extracted from the SVG of the pattern file.
+
+ mTempHsv[2] = 0.753f;
+ Path p = mTempPath;
+ p.reset();
+ p.moveTo(1029.4f, 357.5f);
+ p.lineTo(1366f, 759.1f);
+ p.lineTo(1366f, 0f);
+ p.lineTo(1137.7f, 0f);
+ p.close();
+ drawPath(canvas, p, mTempHsv);
+
+ mTempHsv[2] = 0.78f;
+ p.reset();
+ p.moveTo(1138.1f, 0f);
+ p.rLineTo(-144.8f, 768f);
+ p.rLineTo(372.7f, 0f);
+ p.rLineTo(0f, -524f);
+ p.cubicTo(1290.7f, 121.6f, 1219.2f, 41.1f, 1178.7f, 0f);
+ p.close();
+ drawPath(canvas, p, mTempHsv);
+
+ mTempHsv[2] = 0.804f;
+ p.reset();
+ p.moveTo(949.8f, 768f);
+ p.rCubicTo(92.6f, -170.6f, 213f, -440.3f, 269.4f, -768f);
+ p.lineTo(585f, 0f);
+ p.rLineTo(2.1f, 766f);
+ p.close();
+ drawPath(canvas, p, mTempHsv);
+
+ mTempHsv[2] = 0.827f;
+ p.reset();
+ p.moveTo(471.1f, 768f);
+ p.rMoveTo(704.5f, 0f);
+ p.cubicTo(1123.6f, 563.3f, 1027.4f, 275.2f, 856.2f, 0f);
+ p.lineTo(476.4f, 0f);
+ p.rLineTo(-5.3f, 768f);
+ p.close();
+ drawPath(canvas, p, mTempHsv);
+
+ mTempHsv[2] = 0.867f;
+ p.reset();
+ p.moveTo(323.1f, 768f);
+ p.moveTo(777.5f, 768f);
+ p.cubicTo(661.9f, 348.8f, 427.2f, 21.4f, 401.2f, 25.4f);
+ p.lineTo(323.1f, 768f);
+ p.close();
+ drawPath(canvas, p, mTempHsv);
+
+ mTempHsv[2] = 0.894f;
+ p.reset();
+ p.moveTo(178.44286f, 766.85714f);
+ p.lineTo(308.7f, 768f);
+ p.cubicTo(381.7f, 604.6f, 481.6f, 344.3f, 562.2f, 0f);
+ p.lineTo(0f, 0f);
+ p.close();
+ drawPath(canvas, p, mTempHsv);
+
+ mTempHsv[2] = 0.929f;
+ p.reset();
+ p.moveTo(146f, 0f);
+ p.lineTo(0f, 0f);
+ p.lineTo(0f, 768f);
+ p.lineTo(394.2f, 768f);
+ p.cubicTo(327.7f, 475.3f, 228.5f, 201f, 146f, 0f);
+ p.close();
+ drawPath(canvas, p, mTempHsv);
+
+ canvas.restore();
+ }
+
+ @VisibleForTesting
+ public void scaleCanvasToBounds(Canvas canvas) {
+ final Rect bounds = getBounds();
+ final int height = bounds.height();
+ final int width = bounds.width();
+
+ float scaleY = height / VIEWBOX_HEIGHT;
+ float scaleX = width / VIEWBOX_WIDTH;
+ // First scale both sides to fit independently.
+ canvas.scale(scaleX, scaleY);
+ if (scaleY > scaleX) {
+ // Adjust x-scale to maintain aspect ratio, but using (200, 0) as the pivot instead,
+ // so that more of the texture and less of the blank space on the left edge is seen.
+ canvas.scale(scaleY / scaleX, 1f, SCALE_FOCUS_X, 0f);
+ } else {
+ // Adjust y-scale to maintain aspect ratio, but using (0, 175) as the pivot instead,
+ // so that an intersection of two "circles" can always be seen.
+ canvas.scale(1f, scaleX / scaleY, 0f, SCALE_FOCUS_Y);
+ }
+ }
+
+ private void drawPath(Canvas canvas, Path path, float[] hsv) {
+ mPaint.setColor(Color.HSVToColor(hsv));
+ canvas.drawPath(path, mPaint);
+ }
+
+ @Override
+ public void setAlpha(int i) {
+ // Ignore
+ }
+
+ @Override
+ public void setColorFilter(ColorFilter colorFilter) {
+ // Ignore
+ }
+
+ @Override
+ public int getOpacity() {
+ return 0;
+ }
+
+ public void setColor(int color) {
+ mColor = color;
+ mPaint.setColor(color);
+ invalidateSelf();
+ }
+
+ public int getColor() {
+ return mColor;
+ }
+}
diff --git a/library/main/src/com/android/setupwizardlib/view/StatusBarBackgroundLayout.java b/library/main/src/com/android/setupwizardlib/view/StatusBarBackgroundLayout.java
new file mode 100644
index 0000000..7fdabec
--- /dev/null
+++ b/library/main/src/com/android/setupwizardlib/view/StatusBarBackgroundLayout.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2015 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.setupwizardlib.view;
+
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.drawable.Drawable;
+import android.os.Build;
+import android.os.Build.VERSION_CODES;
+import android.util.AttributeSet;
+import android.view.WindowInsets;
+import android.widget.FrameLayout;
+
+import com.android.setupwizardlib.R;
+
+/**
+ * A FrameLayout subclass that will responds to onApplyWindowInsets to draw a drawable in the top
+ * inset area, making a background effect for the navigation bar. To make use of this layout,
+ * specify the system UI visibility {@link android.view.View#SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN} and
+ * set specify fitsSystemWindows.
+ *
+ * <p>This view is a normal FrameLayout if either of those are not set, or if the platform version
+ * is lower than Lollipop.
+ */
+public class StatusBarBackgroundLayout extends FrameLayout {
+
+ private Drawable mStatusBarBackground;
+ private Object mLastInsets; // Use generic Object type for compatibility
+
+ public StatusBarBackgroundLayout(Context context) {
+ super(context);
+ init(context, null, 0);
+ }
+
+ public StatusBarBackgroundLayout(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init(context, attrs, 0);
+ }
+
+ @TargetApi(VERSION_CODES.HONEYCOMB)
+ public StatusBarBackgroundLayout(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ init(context, attrs, defStyleAttr);
+ }
+
+ private void init(Context context, AttributeSet attrs, int defStyleAttr) {
+ final TypedArray a = context.obtainStyledAttributes(attrs,
+ R.styleable.SuwStatusBarBackgroundLayout, defStyleAttr, 0);
+ final Drawable statusBarBackground =
+ a.getDrawable(R.styleable.SuwStatusBarBackgroundLayout_suwStatusBarBackground);
+ setStatusBarBackground(statusBarBackground);
+ a.recycle();
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+ if (Build.VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) {
+ if (mLastInsets != null) {
+ final int insetTop = ((WindowInsets) mLastInsets).getSystemWindowInsetTop();
+ if (insetTop > 0) {
+ mStatusBarBackground.setBounds(0, 0, getWidth(), insetTop);
+ mStatusBarBackground.draw(canvas);
+ }
+ }
+ }
+ }
+
+ public void setStatusBarBackground(Drawable background) {
+ mStatusBarBackground = background;
+ if (Build.VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) {
+ setWillNotDraw(background == null);
+ setFitsSystemWindows(background != null);
+ invalidate();
+ }
+ }
+
+ public Drawable getStatusBarBackground() {
+ return mStatusBarBackground;
+ }
+
+ @Override
+ public WindowInsets onApplyWindowInsets(WindowInsets insets) {
+ mLastInsets = insets;
+ return super.onApplyWindowInsets(insets);
+ }
+}