<commit_before>package com.jaygoo.widget;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.TypeEvaluator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.NinePatch;
import android.graphics.Paint;
import android.graphics.RadialGradient;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.Typeface;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.v4.content.ContextCompat;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;


public class RangeSeekBar extends View {

    //the progress hint mode
    //defaultMode: show hint when you move the thumb
    //alwaysHide: hide progress hint all the time
    //alwaysShow: show progress hint all the time
    private static final int DEFAULT_MODE = 0;
    private static final int ALWAYS_HIDE = 1;
    private static final int ALWAYS_SHOW = 2;

    private static final float DEFAULT_RADIUS = 0.5f;

    //default seekbar's padding left and right
    private  int DEFAULT_PADDING_LEFT_AND_RIGHT;

    private int defaultPaddingTop;
    //进度提示的背景 The background of the progress
    private final int mProgressHintBGId;

    // 按钮的背景   The background of the Drag button
    private final int mThumbResId;

    //刻度模式：number根据数字实际比例排列；other 均分排列
    //Scale mode:
    // number according to the actual proportion of the number of arranged;
    // other equally arranged
    private final int mCellMode;

    //single是Seekbar模式，range是RangeSeekbar
    //single is Seekbar mode, range is angeSeekbar
    //single = 1; range = 2
    private final int mSeekBarMode ;

    //默认为1，当大于1时自动切回刻度模式
    //The default is 1, and when it is greater than 1,
    // it will automatically switch back to the scale mode
    private int cellsCount = 1;

    //刻度与进度条间的间距
    //The spacing between the scale and the progress bar
    private int textPadding;

    //进度提示背景与按钮之间的距离
    //The progress indicates the distance between the background and the button
    private int mHintBGPadding;

    private int mSeekBarHeight;
    private int mThumbSize;

    //两个按钮之间的最小距离
    //The minimum distance between two buttons
    private int reserveCount;

    private int mCursorTextHeight;
    private int mPartLength;
    private int heightNeeded;
    private int lineCorners;
    private int lineWidth;

    //选择过的进度条颜色
    // the color of the selected progress bar
    private int colorLineSelected;

    //未选则的进度条颜色
    // the color of the unselected progress bar
    private int colorLineEdge;

    //The foreground color of progress bar and thumb button.
    private int colorPrimary;

    //The background color of progress bar and thumb button.
    private int colorSecondary;

    //刻度文字与提示文字的大小
    //Scale text and prompt text size
    private int mTextSize;

    private int lineTop, lineBottom, lineLeft, lineRight;

    //进度提示背景的高度，宽度如果是0的话会自适应调整
    //Progress prompted the background height, width,
    // if it is 0, then adaptively adjust
    private float mHintBGHeight;
    private float mHintBGWith;

    private float offsetValue;
    private float cellsPercent;
    private float reserveValue;
    private float reservePercent;
    private float maxValue, minValue;

    //真实的最大值和最小值
    //True maximum and minimum values
    private float mMin,mMax;

    private boolean isEnable = true;

    private int mProgressHintMode;

    //刻度上显示的文字
    //The texts displayed on the scale
    private CharSequence[] mTextArray;

    private Bitmap mProgressHintBG;
    private Paint mMainPaint = new Paint();
    private Paint mCursorPaint = new Paint();
    private Paint mProgressPaint;
    private RectF line = new RectF();
    private SeekBar leftSB ;
    private SeekBar rightSB;
    private SeekBar currTouch;

    private OnRangeChangedListener callback;


    public RangeSeekBar(Context context) {
        this(context, null);
    }

    public RangeSeekBar(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray t = context.obtainStyledAttributes(attrs, R.styleable.RangeSeekBar);
        cellsCount = t.getInt(R.styleable.RangeSeekBar_cells, 1);
        reserveValue = t.getFloat(R.styleable.RangeSeekBar_reserve, 0);
        mMin = t.getFloat(R.styleable.RangeSeekBar_min, 0);
        mMax = t.getFloat(R.styleable.RangeSeekBar_max, 100);
        mThumbResId = t.getResourceId(R.styleable.RangeSeekBar_seekBarResId, 0);
        mProgressHintBGId = t.getResourceId(R.styleable.RangeSeekBar_progressHintResId, 0);
        colorLineSelected = t.getColor(R.styleable.RangeSeekBar_lineColorSelected, 0xFF4BD962);
        colorLineEdge = t.getColor(R.styleable.RangeSeekBar_lineColorEdge, 0xFFD7D7D7);
        colorPrimary = t.getColor(R.styleable.RangeSeekBar_thumbPrimaryColor, 0);
        colorSecondary = t.getColor(R.styleable.RangeSeekBar_thumbSecondaryColor, 0);
        mTextArray = t.getTextArray(R.styleable.RangeSeekBar_markTextArray);
        mProgressHintMode = t.getInt(R.styleable.RangeSeekBar_progressHintMode,DEFAULT_MODE);
        textPadding = (int)t.getDimension(R.styleable.RangeSeekBar_textPadding,dp2px(context,7));
        mTextSize = (int)t.getDimension(R.styleable.RangeSeekBar_textSize,dp2px(context,12));
        mHintBGHeight = t.getDimension(R.styleable.RangeSeekBar_hintBGHeight,0);
        mHintBGWith = t.getDimension(R.styleable.RangeSeekBar_hintBGWith,0);
        mSeekBarHeight = (int)t.getDimension(R.styleable.RangeSeekBar_seekBarHeight,dp2px(context,2));
        mHintBGPadding = (int)t.getDimension(R.styleable.RangeSeekBar_hintBGPadding,0);
        mThumbSize = (int)t.getDimension(R.styleable.RangeSeekBar_thumbSize,dp2px(context,26));
        mCellMode = t.getInt(R.styleable.RangeSeekBar_cellMode , 0);
        mSeekBarMode = t.getInt(R.styleable.RangeSeekBar_seekBarMode , 2);

        if (mSeekBarMode == 2){
            leftSB = new SeekBar(-1);
            rightSB = new SeekBar(1);
        }else {
            leftSB = new SeekBar(-1);
        }

        // if you don't set the mHintBGWith or the mHintBGWith < default value, if will use default value
        if (mHintBGWith == 0) {
            DEFAULT_PADDING_LEFT_AND_RIGHT = dp2px(context, 25);
        }else {
            DEFAULT_PADDING_LEFT_AND_RIGHT = Math.max((int)(mHintBGWith / 2+ dp2px(context, 5)),dp2px(context, 25));
        }

        setRules(mMin, mMax, reserveValue, cellsCount);
        initPaint();
        initBitmap();
        t.recycle();

        defaultPaddingTop = mSeekBarHeight / 2 ;
        mHintBGHeight = mHintBGHeight == 0 ? (mCursorPaint.measureText("国") * 3) : mHintBGHeight;

        //Android 7.0以后，优化了View的绘制，onMeasure和onSizeChanged调用顺序有所变化
        //Android7.0以下：onMeasure--->onSizeChanged--->onMeasure
        //Android7.0以上：onMeasure--->onSizeChanged
        lineTop = (int)mHintBGHeight + mThumbSize/2 -mSeekBarHeight/2 ;
        lineBottom = lineTop + mSeekBarHeight ;
        lineCorners = (int) ((lineBottom - lineTop) * 0.45f);

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int heightSize  = MeasureSpec.getSize(heightMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        heightNeeded = 2 * lineTop + mSeekBarHeight;

        /**<commit_msg>fix: #2<commit_after>package com.jaygoo.widget;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.TypeEvaluator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.NinePatch;
import android.graphics.Paint;
import android.graphics.RadialGradient;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.Typeface;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.v4.content.ContextCompat;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;


public class RangeSeekBar extends View {

    //the progress hint mode
    //defaultMode: show hint when you move the thumb
    //alwaysHide: hide progress hint all the time
    //alwaysShow: show progress hint all the time
    private static final int DEFAULT_MODE = 0;
    private static final int ALWAYS_HIDE = 1;
    private static final int ALWAYS_SHOW = 2;

    private static final float DEFAULT_RADIUS = 0.5f;

    //default seekbar's padding left and right
    private  int DEFAULT_PADDING_LEFT_AND_RIGHT;

    private int defaultPaddingTop;
    //进度提示的背景 The background of the progress
    private final int mProgressHintBGId;

    // 按钮的背景   The background of the Drag button
    private final int mThumbResId;

    //刻度模式：number根据数字实际比例排列；other 均分排列
    //Scale mode:
    // number according to the actual proportion of the number of arranged;
    // other equally arranged
    private final int mCellMode;

    //single是Seekbar模式，range是RangeSeekbar
    //single is Seekbar mode, range is angeSeekbar
    //single = 1; range = 2
    private final int mSeekBarMode ;

    //默认为1，当大于1时自动切回刻度模式
    //The default is 1, and when it is greater than 1,
    // it will automatically switch back to the scale mode
    private int cellsCount = 1;

    //刻度与进度条间的间距
    //The spacing between the scale and the progress bar
    private int textPadding;

    //进度提示背景与按钮之间的距离
    //The progress indicates the distance between the background and the button
    private int mHintBGPadding;

    private int mSeekBarHeight;
    private int mThumbSize;

    //两个按钮之间的最小距离
    //The minimum distance between two buttons
    private int reserveCount;

    private int mCursorTextHeight;
    private int mPartLength;
    private int heightNeeded;
    private int lineCorners;
    private int lineWidth;

    //选择过的进度条颜色
    // the color of the selected progress bar
    private int colorLineSelected;

    //未选则的进度条颜色
    // the color of the unselected progress bar
    private int colorLineEdge;

    //The foreground color of progress bar and thumb button.
    private int colorPrimary;

    //The background color of progress bar and thumb button.
    private int colorSecondary;

    //刻度文字与提示文字的大小
    //Scale text and prompt text size
    private int mTextSize;

    private int lineTop, lineBottom, lineLeft, lineRight;

    //进度提示背景的高度，宽度如果是0的话会自适应调整
    //Progress prompted the background height, width,
    // if it is 0, then adaptively adjust
    private float mHintBGHeight;
    private float mHintBGWith;

    private float offsetValue;
    private float cellsPercent;
    private float reserveValue;
    private float reservePercent;
    private float maxValue, minValue;

    //真实的最大值和最小值
    //True maximum and minimum values
    private float mMin,mMax;

    private boolean isEnable = true;

    private int mProgressHintMode;

    //刻度上显示的文字
    //The texts displayed on the scale
    private CharSequence[] mTextArray;

    private Bitmap mProgressHintBG;
    private Paint mMainPaint = new Paint();
    private Paint mCursorPaint = new Paint();
    private Paint mProgressPaint;
    private RectF line = new RectF();
    private SeekBar leftSB ;
    private SeekBar rightSB;
    private SeekBar currTouch;

    private OnRangeChangedListener callback;


    public RangeSeekBar(Context context) {
        this(context, null);
    }

    public RangeSeekBar(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray t = context.obtainStyledAttributes(attrs, R.styleable.RangeSeekBar);
        cellsCount = t.getInt(R.styleable.RangeSeekBar_cells, 1);
        reserveValue = t.getFloat(R.styleable.RangeSeekBar_reserve, 0);
        mMin = t.getFloat(R.styleable.RangeSeekBar_min, 0);
        mMax = t.getFloat(R.styleable.RangeSeekBar_max, 100);
        mThumbResId = t.getResourceId(R.styleable.RangeSeekBar_seekBarResId, 0);
        mProgressHintBGId = t.getResourceId(R.styleable.RangeSeekBar_progressHintResId, 0);
        colorLineSelected = t.getColor(R.styleable.RangeSeekBar_lineColorSelected, 0xFF4BD962);
        colorLineEdge = t.getColor(R.styleable.RangeSeekBar_lineColorEdge, 0xFFD7D7D7);
        colorPrimary = t.getColor(R.styleable.RangeSeekBar_thumbPrimaryColor, 0);
        colorSecondary = t.getColor(R.styleable.RangeSeekBar_thumbSecondaryColor, 0);
        mTextArray = t.getTextArray(R.styleable.RangeSeekBar_markTextArray);
        mProgressHintMode = t.getInt(R.styleable.RangeSeekBar_progressHintMode,DEFAULT_MODE);
        textPadding = (int)t.getDimension(R.styleable.RangeSeekBar_textPadding,dp2px(context,7));
        mTextSize = (int)t.getDimension(R.styleable.RangeSeekBar_textSize,dp2px(context,12));
        mHintBGHeight = t.getDimension(R.styleable.RangeSeekBar_hintBGHeight,0);
        mHintBGWith = t.getDimension(R.styleable.RangeSeekBar_hintBGWith,0);
        mSeekBarHeight = (int)t.getDimension(R.styleable.RangeSeekBar_seekBarHeight,dp2px(context,2));
        mHintBGPadding = (int)t.getDimension(R.styleable.RangeSeekBar_hintBGPadding,0);
        mThumbSize = (int)t.getDimension(R.styleable.RangeSeekBar_thumbSize,dp2px(context,26));
        mCellMode = t.getInt(R.styleable.RangeSeekBar_cellMode , 0);
        mSeekBarMode = t.getInt(R.styleable.RangeSeekBar_seekBarMode , 2);

        if (mSeekBarMode == 2){
            leftSB = new SeekBar(-1);
            rightSB = new SeekBar(1);
        }else {
            leftSB = new SeekBar(-1);
        }

        // if you don't set the mHintBGWith or the mHintBGWith < default value, if will use default value
        if (mHintBGWith == 0) {
            DEFAULT_PADDING_LEFT_AND_RIGHT = dp2px(context, 25);
        }else {
            DEFAULT_PADDING_LEFT_AND_RIGHT = Math.max((int)(mHintBGWith / 2+ dp2px(context, 5)),dp2px(context, 25));
        }

        setRules(mMin, mMax, reserveValue, cellsCount);
        initPaint();
        initBitmap();
        t.recycle();

        defaultPaddingTop = mSeekBarHeight / 2 ;

        if (mProgressHintMode == ALWAYS_HIDE && mTextArray == null){
            mHintBGHeight = mCursorPaint.measureText("国");
        }else {
            mHintBGHeight = mHintBGHeight == 0 ? (mCursorPaint.measureText("国") * 3) : mHintBGHeight;
        }

        //Android 7.0以后，优化了View的绘制，onMeasure和onSizeChanged调用顺序有所变化
        //Android7.0以下：onMeasure--->onSizeChanged--->onMeasure
        //Android7.0以上：onMeasure--->onSizeChanged
        lineTop = (int)mHintBGHeight + mThumbSize/2 -mSeekBarHeight/2 ;
        lineBottom = lineTop + mSeekBarHeight ;
        lineCorners = (int) ((lineBottom - lineTop) * 0.45f);

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int heightSize  = MeasureSpec.getSize(heightMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        heightNeeded = 2 * lineTop + mSeekBarHeight;

        /**
{'fraction_non_alphanumeric': 0.08274385099617107, 'fraction_numerical': 0.010188850671685378, 'mean_word_length': 3.338400900900901, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7149379', 'n_tokens_mistral': 4977, 'n_tokens_neox': 4896, 'n_words': 1169}