• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 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 android.support.v7.widget;
18 
19 import android.content.res.ColorStateList;
20 import android.graphics.Canvas;
21 import android.graphics.PorterDuff;
22 import android.graphics.drawable.Drawable;
23 import android.support.annotation.Nullable;
24 import android.support.v4.graphics.drawable.DrawableCompat;
25 import android.support.v4.view.ViewCompat;
26 import android.support.v7.appcompat.R;
27 import android.util.AttributeSet;
28 import android.widget.SeekBar;
29 
30 class AppCompatSeekBarHelper extends AppCompatProgressBarHelper {
31 
32     private final SeekBar mView;
33 
34     private Drawable mTickMark;
35     private ColorStateList mTickMarkTintList = null;
36     private PorterDuff.Mode mTickMarkTintMode = null;
37     private boolean mHasTickMarkTint = false;
38     private boolean mHasTickMarkTintMode = false;
39 
AppCompatSeekBarHelper(SeekBar view)40     AppCompatSeekBarHelper(SeekBar view) {
41         super(view);
42         mView = view;
43     }
44 
45     @Override
loadFromAttributes(AttributeSet attrs, int defStyleAttr)46     void loadFromAttributes(AttributeSet attrs, int defStyleAttr) {
47         super.loadFromAttributes(attrs, defStyleAttr);
48 
49         TintTypedArray a = TintTypedArray.obtainStyledAttributes(mView.getContext(), attrs,
50                 R.styleable.AppCompatSeekBar, defStyleAttr, 0);
51         final Drawable drawable = a.getDrawableIfKnown(R.styleable.AppCompatSeekBar_android_thumb);
52         if (drawable != null) {
53             mView.setThumb(drawable);
54         }
55 
56         final Drawable tickMark = a.getDrawable(R.styleable.AppCompatSeekBar_tickMark);
57         setTickMark(tickMark);
58 
59         if (a.hasValue(R.styleable.AppCompatSeekBar_tickMarkTintMode)) {
60             mTickMarkTintMode = DrawableUtils.parseTintMode(a.getInt(
61                     R.styleable.AppCompatSeekBar_tickMarkTintMode, -1), mTickMarkTintMode);
62             mHasTickMarkTintMode = true;
63         }
64 
65         if (a.hasValue(R.styleable.AppCompatSeekBar_tickMarkTint)) {
66             mTickMarkTintList = a.getColorStateList(R.styleable.AppCompatSeekBar_tickMarkTint);
67             mHasTickMarkTint = true;
68         }
69 
70         a.recycle();
71 
72         applyTickMarkTint();
73     }
74 
setTickMark(@ullable Drawable tickMark)75     void setTickMark(@Nullable Drawable tickMark) {
76         if (mTickMark != null) {
77             mTickMark.setCallback(null);
78         }
79 
80         mTickMark = tickMark;
81 
82         if (tickMark != null) {
83             tickMark.setCallback(mView);
84             DrawableCompat.setLayoutDirection(tickMark, ViewCompat.getLayoutDirection(mView));
85             if (tickMark.isStateful()) {
86                 tickMark.setState(mView.getDrawableState());
87             }
88             applyTickMarkTint();
89         }
90 
91         mView.invalidate();
92     }
93 
94     @Nullable
getTickMark()95     Drawable getTickMark() {
96         return mTickMark;
97     }
98 
setTickMarkTintList(@ullable ColorStateList tint)99     void setTickMarkTintList(@Nullable ColorStateList tint) {
100         mTickMarkTintList = tint;
101         mHasTickMarkTint = true;
102 
103         applyTickMarkTint();
104     }
105 
106     @Nullable
getTickMarkTintList()107     ColorStateList getTickMarkTintList() {
108         return mTickMarkTintList;
109     }
110 
setTickMarkTintMode(@ullable PorterDuff.Mode tintMode)111     void setTickMarkTintMode(@Nullable PorterDuff.Mode tintMode) {
112         mTickMarkTintMode = tintMode;
113         mHasTickMarkTintMode = true;
114 
115         applyTickMarkTint();
116     }
117 
118     @Nullable
getTickMarkTintMode()119     PorterDuff.Mode getTickMarkTintMode() {
120         return mTickMarkTintMode;
121     }
122 
applyTickMarkTint()123     private void applyTickMarkTint() {
124         if (mTickMark != null && (mHasTickMarkTint || mHasTickMarkTintMode)) {
125             mTickMark = DrawableCompat.wrap(mTickMark.mutate());
126 
127             if (mHasTickMarkTint) {
128                 DrawableCompat.setTintList(mTickMark, mTickMarkTintList);
129             }
130 
131             if (mHasTickMarkTintMode) {
132                 DrawableCompat.setTintMode(mTickMark, mTickMarkTintMode);
133             }
134 
135             // The drawable (or one of its children) may not have been
136             // stateful before applying the tint, so let's try again.
137             if (mTickMark.isStateful()) {
138                 mTickMark.setState(mView.getDrawableState());
139             }
140         }
141     }
142 
jumpDrawablesToCurrentState()143     void jumpDrawablesToCurrentState() {
144         if (mTickMark != null) {
145             mTickMark.jumpToCurrentState();
146         }
147     }
148 
drawableStateChanged()149     void drawableStateChanged() {
150         final Drawable tickMark = mTickMark;
151         if (tickMark != null && tickMark.isStateful()
152                 && tickMark.setState(mView.getDrawableState())) {
153             mView.invalidateDrawable(tickMark);
154         }
155     }
156 
157     /**
158      * Draw the tick marks.
159      */
drawTickMarks(Canvas canvas)160     void drawTickMarks(Canvas canvas) {
161         if (mTickMark != null) {
162             final int count = mView.getMax();
163             if (count > 1) {
164                 final int w = mTickMark.getIntrinsicWidth();
165                 final int h = mTickMark.getIntrinsicHeight();
166                 final int halfW = w >= 0 ? w / 2 : 1;
167                 final int halfH = h >= 0 ? h / 2 : 1;
168                 mTickMark.setBounds(-halfW, -halfH, halfW, halfH);
169 
170                 final float spacing = (mView.getWidth() - mView.getPaddingLeft()
171                         - mView.getPaddingRight()) / (float) count;
172                 final int saveCount = canvas.save();
173                 canvas.translate(mView.getPaddingLeft(), mView.getHeight() / 2);
174                 for (int i = 0; i <= count; i++) {
175                     mTickMark.draw(canvas);
176                     canvas.translate(spacing, 0);
177                 }
178                 canvas.restoreToCount(saveCount);
179             }
180         }
181     }
182 
183 }
184