/*
* Copyright (C) 2007 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 com.florianmski.tracktoid.ui.widgets;
import android.app.Dialog;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.SweepGradient;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.util.FloatMath;
import android.util.SparseArray;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.AnimationUtils;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.uwetrottmann.trakt.v2.enums.Rating;
import java.util.HashMap;
import java.util.Map;
public class RateDialog extends Dialog {
// public final static int WEAK_SAUCE = 0xFF444444;
// public final static int TERRIBLE = 0xFF494040;
// public final static int BAD = 0xFF4E393A;
// public final static int POOR = 0xFF553232;
// public final static int MEH = 0xFF5D292A;
// public final static int FAIR = 0xFF672221;
// public final static int GOOD = 0xFF6E191A;
// public final static int GREAT = 0xFF761212;
// public final static int SUPERB = 0xFF7C0C0b;
// public final static int TOTALLY_NINJA = 0xFF7F0707;
//
// public final static int[] rate = {
// 0xFF444444,
// 0xFF494040,
// 0xFF4E393A,
// 0xFF553232,
// 0xFF5D292A,
// 0xFF672221,
// 0xFF6E191A,
// 0xFF761212,
// 0xFF7C0C0b,
// 0xFF7F0707};
//
// public final static String[] rateNames = {
// "Weak sauce :(",
// "Terrible",
// "Bad",
// "Poor",
// "Meh",
// "Fair",
// "Good",
// "Great",
// "Superb",
// "Totally ninja!"};
public interface OnColorChangedListener
{
void rateChanged(Rating r);
}
private OnColorChangedListener mListener;
private Rating r;
private static class ColorPickerView extends View
{
private Paint mPaint;
private Paint mCenterPaint;
private Paint mNumberPaint;
private Paint mTextPaint;
private final int[] mColors;
private OnColorChangedListener mListener;
private TextView tv;
private RectF rect;
private PorterDuffXfermode duffXMode = new PorterDuffXfermode(PorterDuff.Mode.DST_OUT);
ColorPickerView(Context c, OnColorChangedListener listener, RatingColor r, TextView tv)
{
super(c);
mListener = listener;
this.tv = tv;
mColors = new int[] {
0xFF444444, 0xFF444444,
0xFF494040, 0xFF494040,
0xFF4E393A, 0xFF4E393A,
0xFF553232, 0xFF553232,
0xFF5D292A, 0xFF5D292A,
0xFF672221, 0xFF672221,
0xFF6E191A, 0xFF6E191A,
0xFF761212, 0xFF761212,
0xFF7C0C0b, 0xFF7C0C0b,
0xFF7F0707, 0xFF7F0707
};
float[] mPositions = new float[] {
0f, 0.1f,
0.1f, 0.2f,
0.2f, 0.3f,
0.3f, 0.4f,
0.4f, 0.5f,
0.5f, 0.6f,
0.6f, 0.7f,
0.7f, 0.8f,
0.8f, 0.9f,
0.9f, 1f
};
Shader s = new SweepGradient(0, 0, mColors, mPositions);
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setShader(s);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(CENTER_RADIUS/3);
mCenterPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mCenterPaint.setColor(r.color);
mCenterPaint.setStrokeWidth(5);
mNumberPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mNumberPaint.setTextAlign(Paint.Align.CENTER);
mNumberPaint.setColor(Color.parseColor("#DD000000"));
mNumberPaint.setTextSize(TEXT_SIZE);
mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mTextPaint.setTextAlign(Paint.Align.CENTER);
mTextPaint.setStyle(Paint.Style.STROKE);
mTextPaint.setColor(Color.WHITE);
mTextPaint.setStrokeWidth(5);
mTextPaint.setTextSize(TEXT_SIZE/2);
float l = CENTER_X - mPaint.getStrokeWidth()*0.5f;
rect = new RectF(-l, -l, l, l);
}
private boolean mTrackingCenter;
private boolean mHighlightCenter;
@Override
protected void onDraw(Canvas canvas) {
int yPos = (int) ((canvas.getHeight() / 2) - ((mNumberPaint.descent() - mNumberPaint.ascent()) / 2)) ;
int c = mCenterPaint.getColor();
RatingColor r = RatingColor.fromValue(c);
canvas.translate(CENTER_X, CENTER_X);
canvas.drawOval(rect, mPaint);
canvas.drawCircle(0, 0, CENTER_RADIUS, mCenterPaint);
mNumberPaint.setXfermode(duffXMode);
canvas.drawText(String.valueOf(r.r.toString()), 0, yPos, mNumberPaint);
mNumberPaint.setXfermode(null);
//need to redraw
canvas.drawText(String.valueOf(r.r.toString()), 0, yPos, mNumberPaint);
if(!r.name.equals(tv.getText().toString()))
{
tv.startAnimation(AnimationUtils.makeInAnimation(getContext(), true));
tv.setText(r.name);
}
if (mTrackingCenter) {
mCenterPaint.setStyle(Paint.Style.STROKE);
if (mHighlightCenter) {
mCenterPaint.setAlpha(0xFF);
} else {
mCenterPaint.setAlpha(0x80);
}
canvas.drawCircle(0, 0,
CENTER_RADIUS + mCenterPaint.getStrokeWidth(),
mCenterPaint);
mCenterPaint.setStyle(Paint.Style.FILL);
mCenterPaint.setColor(c);
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(CENTER_X*2, CENTER_Y*2);
}
private static final int SIZE = 300;
private static final int CENTER_X = SIZE;
private static final int CENTER_Y = CENTER_X;
private static final int TEXT_SIZE = CENTER_X;
private static final int CENTER_RADIUS = (int) (CENTER_X*2f/3);
private static final float PI = 3.1415926f;
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX() - CENTER_X;
float y = event.getY() - CENTER_Y;
boolean inCenter = FloatMath.sqrt(x*x + y*y) <= CENTER_RADIUS;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mTrackingCenter = inCenter;
if (inCenter) {
mHighlightCenter = true;
invalidate();
break;
}
case MotionEvent.ACTION_MOVE:
if (mTrackingCenter) {
if (mHighlightCenter != inCenter) {
mHighlightCenter = inCenter;
invalidate();
}
} else {
float angle = (float)java.lang.Math.atan2(y, x);
// need to turn angle [-PI ... PI] into unit [0....1]
float unit = angle/(2*PI);
if (unit < 0) {
unit += 1;
}
mCenterPaint.setColor(mColors[(int) (unit*2*10)]);
invalidate();
}
break;
case MotionEvent.ACTION_UP:
if (mTrackingCenter) {
if (inCenter) {
mListener.rateChanged(RatingColor.fromValue(mCenterPaint.getColor()).r);
}
mTrackingCenter = false; // so we draw w/o halo
invalidate();
}
break;
}
return true;
}
}
private LinearLayout layout;
public RateDialog(Context context, OnColorChangedListener listener, Rating r)
{
super(context, android.R.style.Theme_Black_NoTitleBar);
this.mListener = listener;
this.r = r;
}
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
OnColorChangedListener l = new OnColorChangedListener()
{
public void rateChanged(Rating r)
{
mListener.rateChanged(r);
Animation a = AnimationUtils.loadAnimation(getContext(), android.R.anim.fade_out);
a.setAnimationListener(new AnimationListener()
{
@Override
public void onAnimationStart(Animation animation) {}
@Override
public void onAnimationRepeat(Animation animation) {}
@Override
public void onAnimationEnd(Animation animation)
{
dismiss();
}
});
layout.startAnimation(a);
}
};
layout = new LinearLayout(getContext());
layout.setOrientation(LinearLayout.VERTICAL);
layout.setGravity(android.view.Gravity.CENTER);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
layoutParams.setMargins(10, 0, 10, 5);
TextView tv = new TextView(getContext());
tv.setGravity(Gravity.CENTER_HORIZONTAL);
tv.setTextSize(50);
ColorPickerView mColorPickerView = new ColorPickerView(getContext(), l, RatingColor.fromValue(r), tv);
layout.addView(mColorPickerView, layoutParams);
layout.addView(tv, layoutParams);
getWindow().setBackgroundDrawable(new ColorDrawable(0xDD000000));
layout.startAnimation(AnimationUtils.loadAnimation(getContext(), android.R.anim.fade_in));
setContentView(layout);
}
public enum RatingColor
{
WeakSauce("Weak sauce :(", Rating.WEAKSAUCE, 0xFF444444),
Terrible("Terrible", Rating.TERRIBLE, 0xFF494040),
Bad("Bad", Rating.BAD, 0xFF4E393A),
Poor("Poor", Rating.POOR, 0xFF553232),
Meh("Meh", Rating.MEH, 0xFF5D292A),
Fair("Fair", Rating.FAIR, 0xFF672221),
Good("Good", Rating.GOOD, 0xFF6E191A),
Great("Great", Rating.GREAT, 0xFF761212),
Superb("Superb", Rating.SUPERB, 0xFF7C0C0b),
TotallyNinja("Totally ninja!", Rating.TOTALLYNINJA, 0xFF7F0707);
public final String name;
public final Rating r;
public final int color;
private RatingColor(String name, Rating r, int color)
{
this.name = name;
this.r = r;
this.color = color;
}
@Override
public String toString()
{
return this.name;
}
private static final Map<Rating, RatingColor> RATING_MAPPING = new HashMap<Rating, RatingColor>();
private static final SparseArray<RatingColor> COLOR_MAPPING = new SparseArray<RatingColor>();
static
{
for (RatingColor via : RatingColor.values())
RATING_MAPPING.put(via.r, via);
for (RatingColor via : RatingColor.values())
COLOR_MAPPING.put(via.color, via);
}
public static RatingColor fromValue(Rating value)
{
RatingColor res = RATING_MAPPING.get(value);
if(res != null)
return res;
else
return RatingColor.Meh;
}
public static RatingColor fromValue(int color)
{
RatingColor res = COLOR_MAPPING.get(color);
return res == null ? RatingColor.Meh : res;
}
}
}