blob: 5d5bed57afe83726458a145d2038191d8d112eb2 [file] [log] [blame]
/*
* 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 androidx.appcompat.widget;
import android.content.res.ColorStateList;
import android.graphics.Canvas;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.SeekBar;
import androidx.annotation.Nullable;
import androidx.appcompat.R;
import androidx.core.graphics.drawable.DrawableCompat;
import androidx.core.view.ViewCompat;
class AppCompatSeekBarHelper extends AppCompatProgressBarHelper {
private final SeekBar mView;
private Drawable mTickMark;
private ColorStateList mTickMarkTintList = null;
private PorterDuff.Mode mTickMarkTintMode = null;
private boolean mHasTickMarkTint = false;
private boolean mHasTickMarkTintMode = false;
AppCompatSeekBarHelper(SeekBar view) {
super(view);
mView = view;
}
@Override
void loadFromAttributes(AttributeSet attrs, int defStyleAttr) {
super.loadFromAttributes(attrs, defStyleAttr);
TintTypedArray a = TintTypedArray.obtainStyledAttributes(mView.getContext(), attrs,
R.styleable.AppCompatSeekBar, defStyleAttr, 0);
ViewCompat.saveAttributeDataForStyleable(mView, mView.getContext(),
R.styleable.AppCompatSeekBar, attrs, a.getWrappedTypeArray(),
defStyleAttr, 0);
final Drawable drawable = a.getDrawableIfKnown(R.styleable.AppCompatSeekBar_android_thumb);
if (drawable != null) {
mView.setThumb(drawable);
}
final Drawable tickMark = a.getDrawable(R.styleable.AppCompatSeekBar_tickMark);
setTickMark(tickMark);
if (a.hasValue(R.styleable.AppCompatSeekBar_tickMarkTintMode)) {
mTickMarkTintMode = DrawableUtils.parseTintMode(a.getInt(
R.styleable.AppCompatSeekBar_tickMarkTintMode, -1), mTickMarkTintMode);
mHasTickMarkTintMode = true;
}
if (a.hasValue(R.styleable.AppCompatSeekBar_tickMarkTint)) {
mTickMarkTintList = a.getColorStateList(R.styleable.AppCompatSeekBar_tickMarkTint);
mHasTickMarkTint = true;
}
a.recycle();
applyTickMarkTint();
}
void setTickMark(@Nullable Drawable tickMark) {
if (mTickMark != null) {
mTickMark.setCallback(null);
}
mTickMark = tickMark;
if (tickMark != null) {
tickMark.setCallback(mView);
DrawableCompat.setLayoutDirection(tickMark, ViewCompat.getLayoutDirection(mView));
if (tickMark.isStateful()) {
tickMark.setState(mView.getDrawableState());
}
applyTickMarkTint();
}
mView.invalidate();
}
@Nullable
Drawable getTickMark() {
return mTickMark;
}
void setTickMarkTintList(@Nullable ColorStateList tint) {
mTickMarkTintList = tint;
mHasTickMarkTint = true;
applyTickMarkTint();
}
@Nullable
ColorStateList getTickMarkTintList() {
return mTickMarkTintList;
}
void setTickMarkTintMode(@Nullable PorterDuff.Mode tintMode) {
mTickMarkTintMode = tintMode;
mHasTickMarkTintMode = true;
applyTickMarkTint();
}
@Nullable
PorterDuff.Mode getTickMarkTintMode() {
return mTickMarkTintMode;
}
private void applyTickMarkTint() {
if (mTickMark != null && (mHasTickMarkTint || mHasTickMarkTintMode)) {
mTickMark = DrawableCompat.wrap(mTickMark.mutate());
if (mHasTickMarkTint) {
DrawableCompat.setTintList(mTickMark, mTickMarkTintList);
}
if (mHasTickMarkTintMode) {
DrawableCompat.setTintMode(mTickMark, mTickMarkTintMode);
}
// The drawable (or one of its children) may not have been
// stateful before applying the tint, so let's try again.
if (mTickMark.isStateful()) {
mTickMark.setState(mView.getDrawableState());
}
}
}
void jumpDrawablesToCurrentState() {
if (mTickMark != null) {
mTickMark.jumpToCurrentState();
}
}
void drawableStateChanged() {
final Drawable tickMark = mTickMark;
if (tickMark != null && tickMark.isStateful()
&& tickMark.setState(mView.getDrawableState())) {
mView.invalidateDrawable(tickMark);
}
}
/**
* Draw the tick marks.
*/
void drawTickMarks(Canvas canvas) {
if (mTickMark != null) {
final int count = mView.getMax();
if (count > 1) {
final int w = mTickMark.getIntrinsicWidth();
final int h = mTickMark.getIntrinsicHeight();
final int halfW = w >= 0 ? w / 2 : 1;
final int halfH = h >= 0 ? h / 2 : 1;
mTickMark.setBounds(-halfW, -halfH, halfW, halfH);
final float spacing = (mView.getWidth() - mView.getPaddingLeft()
- mView.getPaddingRight()) / (float) count;
final int saveCount = canvas.save();
canvas.translate(mView.getPaddingLeft(), mView.getHeight() / 2);
for (int i = 0; i <= count; i++) {
mTickMark.draw(canvas);
canvas.translate(spacing, 0);
}
canvas.restoreToCount(saveCount);
}
}
}
}