Android Open Source - meu-android-sdk S V Bar






From Project

Back to project page meu-android-sdk.

License

The source code is released under:

MIT License

If you think the Android project meu-android-sdk 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

/*
 * Copyright 2012 Lars Werkman//from   w  ww  .  j av a2 s  .co  m
 *
 * 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.larswerkman.holocolorpicker;

import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Shader;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import com.ankitg.meusample.R;

public class SVBar extends View {

  /*
   * Constants used to save/restore the instance state.
   */
  private static final String STATE_PARENT = "parent";
  private static final String STATE_COLOR = "color";
  private static final String STATE_SATURATION = "saturation";
  private static final String STATE_VALUE = "value";
  private static final String STATE_ORIENTATION = "orientation";
  
  /**
   * Constants used to identify orientation.
   */
  private static final boolean ORIENTATION_HORIZONTAL = true;
  private static final boolean ORIENTATION_VERTICAL = false;
  
  /**
   * Default orientation of the bar.
   */
  private static final boolean ORIENTATION_DEFAULT = ORIENTATION_HORIZONTAL;

  /**
   * The thickness of the bar.
   */
  private int mBarThickness;

  /**
   * The length of the bar.
   */
  private int mBarLength;
  private int mPreferredBarLength;

  /**
   * The radius of the pointer.
   */
  private int mBarPointerRadius;

  /**
   * The radius of the halo of the pointer.
   */
  private int mBarPointerHaloRadius;

  /**
   * The position of the pointer on the bar.
   */
  private int mBarPointerPosition;

  /**
   * {@code Paint} instance used to draw the bar.
   */
  private Paint mBarPaint;

  /**
   * {@code Paint} instance used to draw the pointer.
   */
  private Paint mBarPointerPaint;

  /**
   * {@code Paint} instance used to draw the halo of the pointer.
   */
  private Paint mBarPointerHaloPaint;

  /**
   * The rectangle enclosing the bar.
   */
  private RectF mBarRect = new RectF();

  /**
   * {@code Shader} instance used to fill the shader of the paint.
   */
  private Shader shader;

  /**
   * {@code true} if the user clicked on the pointer to start the move mode. <br>
   * {@code false} once the user stops touching the screen.
   * 
   * @see #onTouchEvent(android.view.MotionEvent)
   */
  private boolean mIsMovingPointer;

  /**
   * The ARGB value of the currently selected color.
   */
  private int mColor;

  /**
   * An array of floats that can be build into a {@code Color} <br>
   * Where we can extract the Saturation and Value from.
   */
  private float[] mHSVColor = new float[3];

  /**
   * Factor used to calculate the position to the Saturation/Value on the bar.
   */
  private float mPosToSVFactor;

  /**
   * Factor used to calculate the Saturation/Value to the postion on the bar.
   */
  private float mSVToPosFactor;

  /**
   * {@code ColorPicker} instance used to control the ColorPicker.
   */
  private ColorPicker mPicker = null;

  /**
   * Used to toggle orientation between vertical and horizontal.
   */
  private boolean mOrientation;

  public SVBar(Context context) {
    super(context);
    init(null, 0);
  }

  public SVBar(Context context, AttributeSet attrs) {
    super(context, attrs);
    init(attrs, 0);
  }

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

  private void init(AttributeSet attrs, int defStyle) {
    final TypedArray a = getContext().obtainStyledAttributes(attrs,
        R.styleable.ColorBars, defStyle, 0);
    final Resources b = getContext().getResources();

    mBarThickness = a.getDimensionPixelSize(
        R.styleable.ColorBars_bar_thickness,
        b.getDimensionPixelSize(R.dimen.bar_thickness));
    mBarLength = a.getDimensionPixelSize(R.styleable.ColorBars_bar_length,
        b.getDimensionPixelSize(R.dimen.bar_length));
    mPreferredBarLength = mBarLength;
    mBarPointerRadius = a.getDimensionPixelSize(
        R.styleable.ColorBars_bar_pointer_radius,
        b.getDimensionPixelSize(R.dimen.bar_pointer_radius));
    mBarPointerHaloRadius = a.getDimensionPixelSize(
        R.styleable.ColorBars_bar_pointer_halo_radius,
        b.getDimensionPixelSize(R.dimen.bar_pointer_halo_radius));
    mOrientation = a.getBoolean(
        R.styleable.ColorBars_bar_orientation_horizontal, ORIENTATION_DEFAULT);

    a.recycle();

    mBarPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    mBarPaint.setShader(shader);

    mBarPointerPosition = (mBarLength / 2) + mBarPointerHaloRadius;

    mBarPointerHaloPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    mBarPointerHaloPaint.setColor(Color.BLACK);
    mBarPointerHaloPaint.setAlpha(0x50);

    mBarPointerPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    mBarPointerPaint.setColor(0xff81ff00);

    mPosToSVFactor = 1 / ((float) mBarLength / 2);
    mSVToPosFactor = ((float) mBarLength / 2) / 1;
  }

  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    final int intrinsicSize = mPreferredBarLength
        + (mBarPointerHaloRadius * 2);

    // Variable orientation
    int measureSpec;
    if (mOrientation == ORIENTATION_HORIZONTAL) {
      measureSpec = widthMeasureSpec;
    }
    else {
      measureSpec = heightMeasureSpec;
    }
    int lengthMode = MeasureSpec.getMode(measureSpec);
    int lengthSize = MeasureSpec.getSize(measureSpec);

    int length;
    if (lengthMode == MeasureSpec.EXACTLY) {
      length = lengthSize;
    }
    else if (lengthMode == MeasureSpec.AT_MOST) {
      length = Math.min(intrinsicSize, lengthSize);
    }
    else {
      length = intrinsicSize;
    }

    int barPointerHaloRadiusx2 = mBarPointerHaloRadius * 2;
    mBarLength = length - barPointerHaloRadiusx2;
    if(mOrientation == ORIENTATION_VERTICAL) {
      setMeasuredDimension(barPointerHaloRadiusx2,
                (mBarLength + barPointerHaloRadiusx2));
    }
    else {
      setMeasuredDimension((mBarLength + barPointerHaloRadiusx2),
            barPointerHaloRadiusx2);
    }
  }

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

    // Fill the rectangle instance based on orientation
    int x1, y1;
    if (mOrientation == ORIENTATION_HORIZONTAL) {
      x1 = (mBarLength + mBarPointerHaloRadius);
      y1 = mBarThickness;
      mBarLength = w - (mBarPointerHaloRadius * 2);
      mBarRect.set(mBarPointerHaloRadius,
          (mBarPointerHaloRadius - (mBarThickness / 2)),
          (mBarLength + (mBarPointerHaloRadius)),
          (mBarPointerHaloRadius + (mBarThickness / 2)));
    }
    else {
      x1 = mBarThickness;
      y1 = (mBarLength + mBarPointerHaloRadius);
      mBarLength = h - (mBarPointerHaloRadius * 2);
      mBarRect.set((mBarPointerHaloRadius - (mBarThickness / 2)),
          mBarPointerHaloRadius,
          (mBarPointerHaloRadius + (mBarThickness / 2)),
          (mBarLength + (mBarPointerHaloRadius)));
    }

    // Update variables that depend of mBarLength.
    if(!isInEditMode()){
      shader = new LinearGradient(mBarPointerHaloRadius, 0,
          x1, y1, new int[] {
              0xffffffff, Color.HSVToColor(mHSVColor), 0xff000000 },
          null, Shader.TileMode.CLAMP);
    } else {
      shader = new LinearGradient(mBarPointerHaloRadius, 0,
          x1, y1, new int[] {
              0xffffffff, 0xff81ff00, 0xff000000 }, null,
          Shader.TileMode.CLAMP);
      Color.colorToHSV(0xff81ff00, mHSVColor);
    }
    
    mBarPaint.setShader(shader);
    mPosToSVFactor = 1 / ((float) mBarLength / 2);
    mSVToPosFactor = ((float) mBarLength / 2) / 1;
    float[] hsvColor = new float[3];
    Color.colorToHSV(mColor, hsvColor);
    if (hsvColor[1] < hsvColor[2]) {
      mBarPointerPosition = Math.round((mSVToPosFactor * hsvColor[1])
          + mBarPointerHaloRadius);
    } else {
      mBarPointerPosition = Math
          .round((mSVToPosFactor * (1 - hsvColor[2]))
              + mBarPointerHaloRadius + (mBarLength / 2));
    }
    if(isInEditMode()){
      mBarPointerPosition = (mBarLength / 2) + mBarPointerHaloRadius;
    }
  }

  @Override
  protected void onDraw(Canvas canvas) {
    // Draw the bar.
    canvas.drawRect(mBarRect, mBarPaint);

    // Calculate the center of the pointer.
    int cX, cY;
    if (mOrientation == ORIENTATION_HORIZONTAL) {
      cX = mBarPointerPosition;
      cY = mBarPointerHaloRadius;
    }
    else {
      cX = mBarPointerHaloRadius;
      cY = mBarPointerPosition;
    }
    
    // Draw the pointer halo.
    canvas.drawCircle(cX, cY, mBarPointerHaloRadius, mBarPointerHaloPaint);
    // Draw the pointer.
    canvas.drawCircle(cX, cY, mBarPointerRadius, mBarPointerPaint);
  };

  @Override
  public boolean onTouchEvent(MotionEvent event) {
    getParent().requestDisallowInterceptTouchEvent(true);

    // Convert coordinates to our internal coordinate system
    float dimen;
    if (mOrientation == ORIENTATION_HORIZONTAL) {
      dimen = event.getX();
    }
    else {
      dimen = event.getY();
    }

    switch (event.getAction()) {
    case MotionEvent.ACTION_DOWN:
          mIsMovingPointer = true;
      // Check whether the user pressed on the pointer
      if (dimen >= (mBarPointerHaloRadius)
          && dimen <= (mBarPointerHaloRadius + mBarLength)) {
        mBarPointerPosition = Math.round(dimen);
        calculateColor(Math.round(dimen));
        mBarPointerPaint.setColor(mColor);
        invalidate();
      }
      break;
    case MotionEvent.ACTION_MOVE:
      if (mIsMovingPointer) {
        // Move the the pointer on the bar.
        if (dimen >= mBarPointerHaloRadius
            && dimen <= (mBarPointerHaloRadius + mBarLength)) {
          mBarPointerPosition = Math.round(dimen);
          calculateColor(Math.round(dimen));
          mBarPointerPaint.setColor(mColor);
          if (mPicker != null) {
            mPicker.setNewCenterColor(mColor);
            mPicker.changeOpacityBarColor(mColor);
          }
          invalidate();
        } else if (dimen < mBarPointerHaloRadius) {
          mBarPointerPosition = mBarPointerHaloRadius;
          mColor = Color.WHITE;
          mBarPointerPaint.setColor(mColor);
          if (mPicker != null) {
            mPicker.setNewCenterColor(mColor);
            mPicker.changeOpacityBarColor(mColor);
          }
          invalidate();
        } else if (dimen > (mBarPointerHaloRadius + mBarLength)) {
          mBarPointerPosition = mBarPointerHaloRadius + mBarLength;
          mColor = Color.BLACK;
          mBarPointerPaint.setColor(mColor);
          if (mPicker != null) {
            mPicker.setNewCenterColor(mColor);
            mPicker.changeOpacityBarColor(mColor);
          }
          invalidate();
        }
      }
      break;
    case MotionEvent.ACTION_UP:
      mIsMovingPointer = false;
      break;
    }
    return true;
  }

  /**
   * Set the pointer on the bar. With the saturation value.
   * 
   * @param saturation
   *            float between 0 > 1
   */
  public void setSaturation(float saturation) {
    mBarPointerPosition = Math.round((mSVToPosFactor * saturation)
        + mBarPointerHaloRadius);
    calculateColor(mBarPointerPosition);
    mBarPointerPaint.setColor(mColor);
    // Check whether the Saturation/Value bar is added to the ColorPicker
    // wheel
    if (mPicker != null) {
      mPicker.setNewCenterColor(mColor);
      mPicker.changeOpacityBarColor(mColor);
    }
    invalidate();
  }

  /**
   * Set the pointer on the bar. With the Value value.
   * 
   * @param value
   *            float between 0 > 1
   */
  public void setValue(float value) {
    mBarPointerPosition = Math.round((mSVToPosFactor * (1 - value))
        + mBarPointerHaloRadius + (mBarLength / 2));
    calculateColor(mBarPointerPosition);
    mBarPointerPaint.setColor(mColor);
    // Check whether the Saturation/Value bar is added to the ColorPicker
    // wheel
    if (mPicker != null) {
      mPicker.setNewCenterColor(mColor);
      mPicker.changeOpacityBarColor(mColor);
    }
    invalidate();
  }

  /**
   * Set the bar color. <br>
   * <br>
   * Its discouraged to use this method.
   * 
   * @param color
   */
  public void setColor(int color) {
    int x1, y1;
    if(mOrientation) {
      x1 = (mBarLength + mBarPointerHaloRadius);
      y1 = mBarThickness;
    }        else {
      x1 = mBarThickness;
      y1 = (mBarLength + mBarPointerHaloRadius);
    }
    
    Color.colorToHSV(color, mHSVColor);
    shader = new LinearGradient(mBarPointerHaloRadius, 0,
        x1, y1, new int[] {Color.WHITE, color, Color.BLACK}, null,
        Shader.TileMode.CLAMP);
    mBarPaint.setShader(shader);
      calculateColor(mBarPointerPosition);
    mBarPointerPaint.setColor(mColor);
    if (mPicker != null) {
      mPicker.setNewCenterColor(mColor);
      if(mPicker.hasOpacityBar())
        mPicker.changeOpacityBarColor(mColor);
    }
    invalidate();
  }

  /**
   * Calculate the color selected by the pointer on the bar.
   * 
   * @param coord
   *            Coordinate of the pointer.
   */
  private void calculateColor(int coord) {
      coord = coord - mBarPointerHaloRadius;
    if (coord > (mBarLength / 2) && (coord < mBarLength)) {
      mColor = Color
          .HSVToColor(new float[] {
              mHSVColor[0], 1f, 1 - (mPosToSVFactor * (coord - (mBarLength / 2)))
                    });
    } else if (coord > 0 && coord < mBarLength) {
      mColor = Color.HSVToColor(new float[]{
                    mHSVColor[0], (mPosToSVFactor * coord), 1f
            });
    } else if(coord == (mBarLength / 2)){
            mColor = Color.HSVToColor(new float[]{
                    mHSVColor[0], 1f, 1f
            });
        } else if (coord <= 0) {
      mColor = Color.WHITE;
    } else if (coord >= mBarLength) {
      mColor = Color.BLACK;
    }
  }

  /**
   * Get the currently selected color.
   * 
   * @return The ARGB value of the currently selected color.
   */
  public int getColor() {
    return mColor;
  }

  /**
   * Adds a {@code ColorPicker} instance to the bar. <br>
   * <br>
   * WARNING: Don't change the color picker. it is done already when the bar
   * is added to the ColorPicker
   * 
   * @see ColorPicker#addSVBar(com.larswerkman.holocolorpicker.SVBar)
   * @param picker
   */
  public void setColorPicker(ColorPicker picker) {
    mPicker = picker;
  }

  @Override
  protected Parcelable onSaveInstanceState() {
    Parcelable superState = super.onSaveInstanceState();

    Bundle state = new Bundle();
    state.putParcelable(STATE_PARENT, superState);
    state.putFloatArray(STATE_COLOR, mHSVColor);
    float[] hsvColor = new float[3];
    Color.colorToHSV(mColor, hsvColor);
    if (hsvColor[1] < hsvColor[2]) {
      state.putFloat(STATE_SATURATION, hsvColor[1]);
    } else {
      state.putFloat(STATE_VALUE, hsvColor[2]);
    }

    return state;
  }

  @Override
  protected void onRestoreInstanceState(Parcelable state) {
    Bundle savedState = (Bundle) state;

    Parcelable superState = savedState.getParcelable(STATE_PARENT);
    super.onRestoreInstanceState(superState);

    setColor(Color.HSVToColor(savedState.getFloatArray(STATE_COLOR)));
    if (savedState.containsKey(STATE_SATURATION)) {
      setSaturation(savedState.getFloat(STATE_SATURATION));
    } else {
      setValue(savedState.getFloat(STATE_VALUE));
    }
  }
}




Java Source Code List

com.ankitg.meusample.MeUActivity.java
com.ankitguglani.MeU.java
com.larswerkman.holocolorpicker.ColorPicker.java
com.larswerkman.holocolorpicker.OpacityBar.java
com.larswerkman.holocolorpicker.SVBar.java
com.larswerkman.holocolorpicker.SaturationBar.java
com.larswerkman.holocolorpicker.ValueBar.java