blob: 15aa2b730adf99ad5023eec1fab8da4c08169928 [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.systemui.settings.brightness;
import android.content.Context;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.DrawableWrapper;
import android.graphics.drawable.LayerDrawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.SeekBar.OnSeekBarChangeListener;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.settingslib.RestrictedLockUtils;
import com.android.systemui.Gefingerpoken;
import com.android.systemui.R;
/**
* {@code FrameLayout} used to show and manipulate a {@link ToggleSeekBar}.
*
*/
public class BrightnessSliderView extends FrameLayout {
@NonNull
private ToggleSeekBar mSlider;
private DispatchTouchEventListener mListener;
private Gefingerpoken mOnInterceptListener;
@Nullable
private Drawable mProgressDrawable;
private float mScale = 1f;
public BrightnessSliderView(Context context) {
this(context, null);
}
public BrightnessSliderView(Context context, AttributeSet attrs) {
super(context, attrs);
}
// Inflated from quick_settings_brightness_dialog
@Override
protected void onFinishInflate() {
super.onFinishInflate();
mSlider = requireViewById(R.id.slider);
mSlider.setAccessibilityLabel(getContentDescription().toString());
// Finds the progress drawable. Assumes brightness_progress_drawable.xml
try {
LayerDrawable progress = (LayerDrawable) mSlider.getProgressDrawable();
DrawableWrapper progressSlider = (DrawableWrapper) progress
.findDrawableByLayerId(android.R.id.progress);
LayerDrawable actualProgressSlider = (LayerDrawable) progressSlider.getDrawable();
mProgressDrawable = actualProgressSlider.findDrawableByLayerId(R.id.slider_foreground);
} catch (Exception e) {
// Nothing to do, mProgressDrawable will be null.
}
}
/**
* Attaches a listener to relay touch events.
* @param listener use {@code null} to remove listener
*/
public void setOnDispatchTouchEventListener(
DispatchTouchEventListener listener) {
mListener = listener;
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (mListener != null) {
mListener.onDispatchTouchEvent(ev);
}
return super.dispatchTouchEvent(ev);
}
@Override
public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
// We prevent disallowing on this view, but bubble it up to our parents.
// We need interception to handle falsing.
if (mParent != null) {
mParent.requestDisallowInterceptTouchEvent(disallowIntercept);
}
}
/**
* Attaches a listener to the {@link ToggleSeekBar} in the view so changes can be observed
* @param seekListener use {@code null} to remove listener
*/
public void setOnSeekBarChangeListener(OnSeekBarChangeListener seekListener) {
mSlider.setOnSeekBarChangeListener(seekListener);
}
/**
* Enforces admin rules for toggling auto-brightness and changing value of brightness
* @param admin
* @see ToggleSeekBar#setEnforcedAdmin
*/
public void setEnforcedAdmin(RestrictedLockUtils.EnforcedAdmin admin) {
mSlider.setEnabled(admin == null);
mSlider.setEnforcedAdmin(admin);
}
/**
* Enables or disables the slider
* @param enable
*/
public void enableSlider(boolean enable) {
mSlider.setEnabled(enable);
}
/**
* @return the maximum value of the {@link ToggleSeekBar}.
*/
public int getMax() {
return mSlider.getMax();
}
/**
* Sets the maximum value of the {@link ToggleSeekBar}.
* @param max
*/
public void setMax(int max) {
mSlider.setMax(max);
}
/**
* Sets the current value of the {@link ToggleSeekBar}.
* @param value
*/
public void setValue(int value) {
mSlider.setProgress(value);
}
/**
* @return the current value of the {@link ToggleSeekBar}
*/
public int getValue() {
return mSlider.getProgress();
}
public void setOnInterceptListener(Gefingerpoken onInterceptListener) {
mOnInterceptListener = onInterceptListener;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (mOnInterceptListener != null) {
return mOnInterceptListener.onInterceptTouchEvent(ev);
}
return super.onInterceptTouchEvent(ev);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
applySliderScale();
}
/**
* Sets the scale for the progress bar (for brightness_progress_drawable.xml)
*
* This will only scale the thick progress bar and not the icon inside
*
* Used in {@link com.android.systemui.qs.QSAnimator}.
*/
public void setSliderScaleY(float scale) {
if (scale != mScale) {
mScale = scale;
applySliderScale();
}
}
private void applySliderScale() {
if (mProgressDrawable != null) {
final Rect r = mProgressDrawable.getBounds();
int height = (int) (mProgressDrawable.getIntrinsicHeight() * mScale);
int inset = (mProgressDrawable.getIntrinsicHeight() - height) / 2;
mProgressDrawable.setBounds(r.left, inset, r.right, inset + height);
}
}
public float getSliderScaleY() {
return mScale;
}
/**
* Interface to attach a listener for {@link View#dispatchTouchEvent}.
*/
@FunctionalInterface
interface DispatchTouchEventListener {
boolean onDispatchTouchEvent(MotionEvent ev);
}
}