blob: 91abc8779274c0ffad515161d861f78e063675b6 [file] [log] [blame]
Jorim Jaggibe565df2014-04-28 17:51:23 +02001/*
2 * Copyright (C) 2014 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
17package com.android.systemui.statusbar;
18
19import android.content.Context;
20import android.graphics.Outline;
Chris Craik7b7ca3c2014-07-11 13:32:19 -070021import android.graphics.Rect;
Selim Cinek8efa6dd2014-05-19 16:27:37 +020022import android.graphics.RectF;
Jorim Jaggibe565df2014-04-28 17:51:23 +020023import android.util.AttributeSet;
Chris Craik7b7ca3c2014-07-11 13:32:19 -070024import android.view.View;
25import android.view.ViewOutlineProvider;
Jorim Jaggibe565df2014-04-28 17:51:23 +020026
27/**
28 * Like {@link ExpandableView}, but setting an outline for the height and clipping.
29 */
30public abstract class ExpandableOutlineView extends ExpandableView {
31
Chris Craik7b7ca3c2014-07-11 13:32:19 -070032 private final Rect mOutlineRect = new Rect();
Selim Cinek8efa6dd2014-05-19 16:27:37 +020033 private boolean mCustomOutline;
Selim Cinekd35c2792016-01-21 13:20:57 -080034 private float mOutlineAlpha = -1f;
Jorim Jaggibe565df2014-04-28 17:51:23 +020035
Mady Mellorb0a82462016-04-30 17:31:02 -070036 ViewOutlineProvider mProvider = new ViewOutlineProvider() {
37 @Override
38 public void getOutline(View view, Outline outline) {
39 int translation = (int) getTranslation();
40 if (!mCustomOutline) {
41 outline.setRect(translation,
42 mClipTopAmount,
43 getWidth() + translation,
Selim Cinekb3dadcc2016-11-21 17:21:13 -080044 Math.max(getActualHeight() - mClipBottomAmount, mClipTopAmount));
Mady Mellorb0a82462016-04-30 17:31:02 -070045 } else {
46 outline.setRect(mOutlineRect);
47 }
48 outline.setAlpha(mOutlineAlpha);
49 }
50 };
51
Jorim Jaggibe565df2014-04-28 17:51:23 +020052 public ExpandableOutlineView(Context context, AttributeSet attrs) {
53 super(context, attrs);
Mady Mellorb0a82462016-04-30 17:31:02 -070054 setOutlineProvider(mProvider);
Jorim Jaggibe565df2014-04-28 17:51:23 +020055 }
56
57 @Override
Jorim Jaggid552d9d2014-05-07 19:41:13 +020058 public void setActualHeight(int actualHeight, boolean notifyListeners) {
59 super.setActualHeight(actualHeight, notifyListeners);
Chris Craik7b7ca3c2014-07-11 13:32:19 -070060 invalidateOutline();
Jorim Jaggibe565df2014-04-28 17:51:23 +020061 }
62
63 @Override
64 public void setClipTopAmount(int clipTopAmount) {
65 super.setClipTopAmount(clipTopAmount);
Chris Craik7b7ca3c2014-07-11 13:32:19 -070066 invalidateOutline();
Jorim Jaggibe565df2014-04-28 17:51:23 +020067 }
68
Selim Cinekb3dadcc2016-11-21 17:21:13 -080069 @Override
70 public void setClipBottomAmount(int clipBottomAmount) {
71 super.setClipBottomAmount(clipBottomAmount);
72 invalidateOutline();
73 }
74
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -070075 protected void setOutlineAlpha(float alpha) {
Selim Cinekd35c2792016-01-21 13:20:57 -080076 if (alpha != mOutlineAlpha) {
77 mOutlineAlpha = alpha;
78 invalidateOutline();
79 }
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -070080 }
81
Selim Cinek33223572016-02-19 19:32:22 -080082 @Override
83 public float getOutlineAlpha() {
84 return mOutlineAlpha;
85 }
86
Selim Cinek8efa6dd2014-05-19 16:27:37 +020087 protected void setOutlineRect(RectF rect) {
88 if (rect != null) {
89 setOutlineRect(rect.left, rect.top, rect.right, rect.bottom);
90 } else {
91 mCustomOutline = false;
Selim Cinek560e64d2015-06-09 19:58:11 -070092 setClipToOutline(false);
Chris Craik7b7ca3c2014-07-11 13:32:19 -070093 invalidateOutline();
Selim Cinek8efa6dd2014-05-19 16:27:37 +020094 }
95 }
96
Selim Cinek33223572016-02-19 19:32:22 -080097 @Override
98 public int getOutlineTranslation() {
Mady Mellorb0a82462016-04-30 17:31:02 -070099 return mCustomOutline ? mOutlineRect.left : (int) getTranslation();
100 }
101
102 public void updateOutline() {
103 if (mCustomOutline) {
104 return;
105 }
Selim Cinekad7fac02016-10-18 17:09:15 -0700106 boolean hasOutline = needsOutline();
Mady Mellorb0a82462016-04-30 17:31:02 -0700107 setOutlineProvider(hasOutline ? mProvider : null);
108 }
109
Selim Cinekad7fac02016-10-18 17:09:15 -0700110 /**
111 * @return whether the view currently needs an outline. This is usually false in case it doesn't
112 * have a background.
113 */
114 protected boolean needsOutline() {
115 if (isChildInGroup()) {
116 return isGroupExpanded() && !isGroupExpansionChanging();
117 } else if (isSummaryWithChildren()) {
118 return !isGroupExpanded() || isGroupExpansionChanging();
119 }
120 return true;
121 }
122
Mady Mellorb0a82462016-04-30 17:31:02 -0700123 public boolean isOutlineShowing() {
124 ViewOutlineProvider op = getOutlineProvider();
125 return op != null;
Selim Cinek33223572016-02-19 19:32:22 -0800126 }
127
Selim Cinek8efa6dd2014-05-19 16:27:37 +0200128 protected void setOutlineRect(float left, float top, float right, float bottom) {
129 mCustomOutline = true;
Mady Mellorb0a82462016-04-30 17:31:02 -0700130 setClipToOutline(true);
Selim Cinek8efa6dd2014-05-19 16:27:37 +0200131
Chris Craik7b7ca3c2014-07-11 13:32:19 -0700132 mOutlineRect.set((int) left, (int) top, (int) right, (int) bottom);
Selim Cinek8efa6dd2014-05-19 16:27:37 +0200133
134 // Outlines need to be at least 1 dp
Selim Cinek3969ffa2014-09-01 23:08:39 +0200135 mOutlineRect.bottom = (int) Math.max(top, mOutlineRect.bottom);
136 mOutlineRect.right = (int) Math.max(left, mOutlineRect.right);
Chris Craik7b7ca3c2014-07-11 13:32:19 -0700137
138 invalidateOutline();
Jorim Jaggibe565df2014-04-28 17:51:23 +0200139 }
Selim Cinek8efa6dd2014-05-19 16:27:37 +0200140
Jorim Jaggibe565df2014-04-28 17:51:23 +0200141}