Android Open Source - Battery-Indicator Color Picker View






From Project

Back to project page Battery-Indicator.

License

The source code is released under:

GNU General Public License

If you think the Android project Battery-Indicator listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
  Modified from original source which was:
  * Copyright (C) 2010 Daniel Nilsson//w w  w  .j a v a2s  .c  om
  * Licensed under the Apache License, Version 2.0
  * At http://github.com/attenzione/android-ColorPickerPreference

  This file, or at least the changes from the original are

  Copyright (c) 2013 Darshan-Josiah Barber


  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

*/

package com.darshancomputing.BatteryIndicatorPro;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ComposeShader;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.PorterDuff;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.Paint.Align;
import android.graphics.Paint.Style;
import android.graphics.Shader.TileMode;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

public class ColorPickerView extends View {
    private final static int PANEL_SAT_VAL = 0;
    private final static int PANEL_HUE = 1;
    private final static float BORDER_WIDTH_PX = 1;

    private float HUE_PANEL_WIDTH = 30f;
    private float PANEL_SPACING = 10f;
    private float PALETTE_CIRCLE_TRACKER_RADIUS = 5f;
    private float RECTANGLE_TRACKER_OFFSET = 2f;
    private float mDensity = 1f;

    private OnColorChangedListener mListener;

    private Paint mSatValPaint;
    private Paint mSatValTrackerPaint;

    private Paint mHuePaint;
    private Paint mHueTrackerPaint;

    private Paint mBorderPaint;

    private Shader mValShader;
    private Shader mSatShader;
    private Shader mHueShader;

    private int mAlpha = 0xff;
    private float mHue = 360f;
    private float mSat = 0f;
    private float mVal = 0f;

    private int mSliderTrackerColor = 0xff1c1c1c;
    private int mBorderColor = 0xff6E6E6E;
    private int mLastTouchedPanel = PANEL_SAT_VAL;
    private float mDrawingOffset;
    private RectF mDrawingRect;
    private RectF mSatValRect;
    private RectF mHueRect;

    private Point mStartTouchPoint = null;

    public interface OnColorChangedListener {
        public void onColorChanged(int color);
    }

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

    public ColorPickerView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ColorPickerView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    private void init() {
        mDensity = getContext().getResources().getDisplayMetrics().density;
        PALETTE_CIRCLE_TRACKER_RADIUS *= mDensity;
        RECTANGLE_TRACKER_OFFSET *= mDensity;
        HUE_PANEL_WIDTH *= mDensity;
        PANEL_SPACING = PANEL_SPACING * mDensity;

        mDrawingOffset = calculateRequiredOffset();

        initPaintTools();

        setFocusable(true);
        setFocusableInTouchMode(true);
    }

    private void initPaintTools() {
        mSatValPaint = new Paint();
        mSatValTrackerPaint = new Paint();
        mHuePaint = new Paint();
        mHueTrackerPaint = new Paint();
        mBorderPaint = new Paint();


        mSatValTrackerPaint.setStyle(Style.STROKE);
        mSatValTrackerPaint.setStrokeWidth(2f * mDensity);
        mSatValTrackerPaint.setAntiAlias(true);

        mHueTrackerPaint.setColor(mSliderTrackerColor);
        mHueTrackerPaint.setStyle(Style.STROKE);
        mHueTrackerPaint.setStrokeWidth(2f * mDensity);
        mHueTrackerPaint.setAntiAlias(true);
    }

    private float calculateRequiredOffset() {
        float offset = Math.max(PALETTE_CIRCLE_TRACKER_RADIUS, RECTANGLE_TRACKER_OFFSET);
        offset = Math.max(offset, BORDER_WIDTH_PX * mDensity);

        return offset * 1.5f;
    }

    private int[] buildHueColorArray() {
        int[] hue = new int[361];

        int count = 0;
        for (int i = hue.length -1; i >= 0; i--, count++) {
            hue[count] = Color.HSVToColor(new float[]{i, 1f, 1f});
        }

        return hue;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        if (mDrawingRect.width() <= 0 || mDrawingRect.height() <= 0) return;

        drawSatValPanel(canvas);
        drawHuePanel(canvas);
    }

    private void drawSatValPanel(Canvas canvas) {
        final RectF rect = mSatValRect;

        if (BORDER_WIDTH_PX > 0) {
            mBorderPaint.setColor(mBorderColor);
            canvas.drawRect(mDrawingRect.left, mDrawingRect.top, rect.right + BORDER_WIDTH_PX, rect.bottom + BORDER_WIDTH_PX, mBorderPaint);
        }

        if (mValShader == null) {
            mValShader = new LinearGradient(rect.left, rect.top, rect.left, rect.bottom,
                                            0xffffffff, 0xff000000, TileMode.CLAMP);
        }

        int rgb = Color.HSVToColor(new float[]{mHue,1f,1f});

        mSatShader = new LinearGradient(rect.left, rect.top, rect.right, rect.top,
                                        0xffffffff, rgb, TileMode.CLAMP);
        ComposeShader mShader = new ComposeShader(mValShader, mSatShader, PorterDuff.Mode.MULTIPLY);
        mSatValPaint.setShader(mShader);

        canvas.drawRect(rect, mSatValPaint);

        Point p = satValToPoint(mSat, mVal);

        mSatValTrackerPaint.setColor(0xff000000);
        canvas.drawCircle(p.x, p.y, PALETTE_CIRCLE_TRACKER_RADIUS - 1f * mDensity, mSatValTrackerPaint);

        mSatValTrackerPaint.setColor(0xffdddddd);
        canvas.drawCircle(p.x, p.y, PALETTE_CIRCLE_TRACKER_RADIUS, mSatValTrackerPaint);
    }

    private void drawHuePanel(Canvas canvas) {
        final RectF rect = mHueRect;

        if (BORDER_WIDTH_PX > 0) {
            mBorderPaint.setColor(mBorderColor);
            canvas.drawRect(rect.left - BORDER_WIDTH_PX,
                            rect.top - BORDER_WIDTH_PX,
                            rect.right + BORDER_WIDTH_PX,
                            rect.bottom + BORDER_WIDTH_PX,
                            mBorderPaint);
        }

        if (mHueShader == null) {
            mHueShader = new LinearGradient(rect.left, rect.top, rect.left, rect.bottom, buildHueColorArray(), null, TileMode.CLAMP);
            mHuePaint.setShader(mHueShader);
        }

        canvas.drawRect(rect, mHuePaint);

        float rectHeight = 4 * mDensity / 2;

        Point p = hueToPoint(mHue);

        RectF r = new RectF();
        r.left = rect.left - RECTANGLE_TRACKER_OFFSET;
        r.right = rect.right + RECTANGLE_TRACKER_OFFSET;
        r.top = p.y - rectHeight;
        r.bottom = p.y + rectHeight;

        canvas.drawRoundRect(r, 2, 2, mHueTrackerPaint);
    }

    private Point hueToPoint(float hue) {
        final RectF rect = mHueRect;
        final float height = rect.height();

        Point p = new Point();

        p.y = (int) (height - (hue * height / 360f) + rect.top);
        p.x = (int) rect.left;

        return p;
    }

    private Point satValToPoint(float sat, float val) {

        final RectF rect = mSatValRect;
        final float height = rect.height();
        final float width = rect.width();

        Point p = new Point();

        p.x = (int) (sat * width + rect.left);
        p.y = (int) ((1f - val) * height + rect.top);

        return p;
    }

    private float[] pointToSatVal(float x, float y) {
        final RectF rect = mSatValRect;
        float[] result = new float[2];

        float width = rect.width();
        float height = rect.height();

        if (x < rect.left) {
            x = 0f;
        } else if (x > rect.right) {
            x = width;
        } else {
            x = x - rect.left;
        }

        if (y < rect.top) {
            y = 0f;
        } else if (y > rect.bottom) {
            y = height;
        } else {
            y = y - rect.top;
        }

        result[0] = 1.f / width * x;
        result[1] = 1.f - (1.f / height * y);

        return result;
    }

    private float pointToHue(float y) {
        final RectF rect = mHueRect;
        float height = rect.height();

        if (y < rect.top) {
            y = 0f;
        } else if (y > rect.bottom) {
            y = height;
        } else {
            y = y - rect.top;
        }

        return 360f - (y * 360f / height);
    }

    @Override
    public boolean onTrackballEvent(MotionEvent event) {
        float x = event.getX();
        float y = event.getY();

        boolean update = false;

        if (event.getAction() == MotionEvent.ACTION_MOVE) {
            switch (mLastTouchedPanel) {
            case PANEL_SAT_VAL:
                float sat, val;

                sat = mSat + x/50f;
                val = mVal - y/50f;

                if (sat < 0f) {
                    sat = 0f;
                } else if (sat > 1f) {
                    sat = 1f;
                }

                if (val < 0f) {
                    val = 0f;
                } else if (val > 1f) {
                    val = 1f;
                }

                mSat = sat;
                mVal = val;
                update = true;
                break;
            case PANEL_HUE:
                float hue = mHue - y * 10f;

                if (hue < 0f) {
                    hue = 0f;
                } else if (hue > 360f) {
                    hue = 360f;
                }

                mHue = hue;
                update = true;
                break;
            }
        }

        if (update) {
            if (mListener != null) {
                mListener.onColorChanged(Color.HSVToColor(mAlpha, new float[]{mHue, mSat, mVal}));
            }

            invalidate();
            return true;
        }

        return super.onTrackballEvent(event);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        boolean update = false;
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            mStartTouchPoint = new Point((int)event.getX(), (int)event.getY());
            update = moveTrackersIfNeeded(event);
            break;
        case MotionEvent.ACTION_MOVE:
            update = moveTrackersIfNeeded(event);
            break;
        case MotionEvent.ACTION_UP:
            mStartTouchPoint = null;
            update = moveTrackersIfNeeded(event);
            break;
        }

        if (update) {
            if (mListener != null) {
                mListener.onColorChanged(Color.HSVToColor(mAlpha, new float[]{mHue, mSat, mVal}));
            }

            invalidate();
            return true;
        }

        return super.onTouchEvent(event);
    }

    private boolean moveTrackersIfNeeded(MotionEvent event) {
        if (mStartTouchPoint == null) return false;

        boolean update = false;

        int startX = mStartTouchPoint.x;
        int startY = mStartTouchPoint.y;

        if (mHueRect.contains(startX, startY)) {
            mLastTouchedPanel = PANEL_HUE;
            mHue = pointToHue(event.getY());
            update = true;
        } else if (mSatValRect.contains(startX, startY)) {
            mLastTouchedPanel = PANEL_SAT_VAL;
            float[] result = pointToSatVal(event.getX(), event.getY());
            mSat = result[0];
            mVal = result[1];
            update = true;
        }

        return update;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int width = 0;
        int height = 0;

        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);

        int widthAllowed = MeasureSpec.getSize(widthMeasureSpec);
        int heightAllowed = MeasureSpec.getSize(heightMeasureSpec);

        widthAllowed = chooseWidth(widthMode, widthAllowed);
        heightAllowed = chooseHeight(heightMode, heightAllowed);

        width = (int) (heightAllowed + HUE_PANEL_WIDTH);

        if (width > widthAllowed) {
            width = widthAllowed;
            height = (int) (widthAllowed - HUE_PANEL_WIDTH);
        } else{
            height = heightAllowed;
        }

        setMeasuredDimension(width, height);
    }

    private int chooseWidth(int mode, int size) {
        if (mode == MeasureSpec.AT_MOST || mode == MeasureSpec.EXACTLY) {
            return size;
        } else { // (mode == MeasureSpec.UNSPECIFIED)
            return getPrefferedWidth();
        }
    }

    private int chooseHeight(int mode, int size) {
        if (mode == MeasureSpec.AT_MOST || mode == MeasureSpec.EXACTLY) {
            return size;
        } else { // (mode == MeasureSpec.UNSPECIFIED)
            return getPrefferedHeight();
        }
    }

    private int getPrefferedWidth() {
        int width = getPrefferedHeight();
        return (int) (width + HUE_PANEL_WIDTH + PANEL_SPACING);
    }

    private int getPrefferedHeight() {
        int height = (int)(200 * mDensity);
        return height;
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);

        mDrawingRect = new RectF();
        mDrawingRect.left = mDrawingOffset + getPaddingLeft();
        mDrawingRect.right  = w - mDrawingOffset - getPaddingRight();
        mDrawingRect.top = mDrawingOffset + getPaddingTop();
        mDrawingRect.bottom = h - mDrawingOffset - getPaddingBottom();

        setUpSatValRect();
        setUpHueRect();
    }

    private void setUpSatValRect() {
        final RectF dRect = mDrawingRect;
        float panelSide = dRect.height() - BORDER_WIDTH_PX * 2;

        float left = dRect.left + BORDER_WIDTH_PX;
        float top = dRect.top + BORDER_WIDTH_PX;
        float bottom = top + panelSide;
        float right = left + panelSide;

        mSatValRect = new RectF(left,top, right, bottom);
    }

    private void setUpHueRect() {
        final RectF dRect = mDrawingRect;

        float left = dRect.right - HUE_PANEL_WIDTH + BORDER_WIDTH_PX;
        float top = dRect.top + BORDER_WIDTH_PX;
        float bottom = dRect.bottom - BORDER_WIDTH_PX - 0;
        float right = dRect.right - BORDER_WIDTH_PX;

        mHueRect = new RectF(left, top, right, bottom);
    }

    public void setOnColorChangedListener(OnColorChangedListener listener) {
        mListener = listener;
    }

    public void setBorderColor(int color) {
        mBorderColor = color;
        invalidate();
    }

    public int getBorderColor() {
        return mBorderColor;
    }

    public int getColor() {
        return Color.HSVToColor(mAlpha, new float[]{mHue,mSat,mVal});
    }

    public void setColor(int color) {
        setColor(color, false);
    }

    public void setColor(int color, boolean callback) {
        int alpha = Color.alpha(color);
        int red = Color.red(color);
        int blue = Color.blue(color);
        int green = Color.green(color);
        float[] hsv = new float[3];

        Color.RGBToHSV(red, green, blue, hsv);

        mAlpha = alpha;
        mHue = hsv[0];
        mSat = hsv[1];
        mVal = hsv[2];

        if (callback && mListener != null) {
            mListener.onColorChanged(Color.HSVToColor(mAlpha, new float[]{mHue, mSat, mVal}));
        }

        invalidate();
    }

    public float getDrawingOffset() {
        return mDrawingOffset;
    }

    public void setSliderTrackerColor(int color) {
        mSliderTrackerColor = color;
        mHueTrackerPaint.setColor(mSliderTrackerColor);
        invalidate();
    }

    public int getSliderTrackerColor() {
        return mSliderTrackerColor;
    }
}




Java Source Code List

com.darshancomputing.BatteryIndicatorPro.AlarmDatabase.java
com.darshancomputing.BatteryIndicatorPro.AlarmEditActivity.java
com.darshancomputing.BatteryIndicatorPro.AlarmRingtonePreference.java
com.darshancomputing.BatteryIndicatorPro.AlarmsActivity.java
com.darshancomputing.BatteryIndicatorPro.BatteryInfoActivity.java
com.darshancomputing.BatteryIndicatorPro.BatteryInfoAppWidgetProvider.java
com.darshancomputing.BatteryIndicatorPro.BatteryInfoService.java
com.darshancomputing.BatteryIndicatorPro.BatteryInfo.java
com.darshancomputing.BatteryIndicatorPro.BatteryLevel.java
com.darshancomputing.BatteryIndicatorPro.BootCompletedReceiver.java
com.darshancomputing.BatteryIndicatorPro.CircleWidgetBackground.java
com.darshancomputing.BatteryIndicatorPro.ColorPickerDialog.java
com.darshancomputing.BatteryIndicatorPro.ColorPickerPanelView.java
com.darshancomputing.BatteryIndicatorPro.ColorPickerPreference.java
com.darshancomputing.BatteryIndicatorPro.ColorPickerView.java
com.darshancomputing.BatteryIndicatorPro.ColorPreviewPreference.java
com.darshancomputing.BatteryIndicatorPro.CurrentInfoFragment.java
com.darshancomputing.BatteryIndicatorPro.FullAppWidgetProvider.java
com.darshancomputing.BatteryIndicatorPro.HelpActivity.java
com.darshancomputing.BatteryIndicatorPro.LogDatabase.java
com.darshancomputing.BatteryIndicatorPro.LogViewFragment.java
com.darshancomputing.BatteryIndicatorPro.Logger.java
com.darshancomputing.BatteryIndicatorPro.PluginServiceConnection.java
com.darshancomputing.BatteryIndicatorPro.PredictorCore.java
com.darshancomputing.BatteryIndicatorPro.Predictor.java
com.darshancomputing.BatteryIndicatorPro.SettingsActivity.java
com.darshancomputing.BatteryIndicatorPro.SettingsHelpActivity.java
com.darshancomputing.BatteryIndicatorPro.Str.java