emotionhero/app/src/main/java/com/rubenvandeven/emotionhero/ScenarioView.java

244 lines
8.2 KiB
Java
Raw Normal View History

2016-08-17 13:17:04 +02:00
package com.rubenvandeven.emotionhero;
import android.content.Context;
import android.graphics.Canvas;
2016-08-17 19:21:16 +02:00
import android.graphics.Color;
2016-08-17 13:17:04 +02:00
import android.graphics.Paint;
2016-08-17 19:21:16 +02:00
import android.graphics.Path;
2016-08-17 13:17:04 +02:00
import android.graphics.PixelFormat;
2016-08-19 13:38:59 +02:00
import android.graphics.Typeface;
2016-08-17 13:17:04 +02:00
import android.view.SurfaceHolder;
import android.view.SurfaceView;
2016-08-17 19:21:16 +02:00
import com.affectiva.android.affdex.sdk.detector.Face;
import java.util.HashMap;
import java.util.Map;
2016-08-17 13:17:04 +02:00
/**
* Created by ruben on 16/08/16.
*/
public class ScenarioView extends SurfaceView implements SurfaceHolder.Callback {
private PanelThread _thread;
private Scenario _scenario;
2016-08-17 19:21:16 +02:00
/**
* The scorres in this moment, as to draw them on the screen.
* Indexes are Emotion ordinals
*/
private Map<Emotion, Float> currentAttributeScores = new HashMap<>();
2016-08-19 13:38:59 +02:00
//avoid object instantiation on each onDraw
private Map<Emotion, Paint> emoPaints = new HashMap<>();
private Map<Emotion, Paint> emoOutlinePaints = new HashMap<>();
private Map<Emotion, Paint> emoScoredPaints = new HashMap<>();
private Paint mainPaint = new Paint();
private Paint attrScorePaint = new Paint();
private Paint linePaint = new Paint();
2016-08-17 13:17:04 +02:00
// see: http://blog.danielnadeau.io/2012/01/android-canvas-beginners-tutorial.html
class PanelThread extends Thread {
private SurfaceHolder _surfaceHolder;
private ScenarioView _panel;
private boolean _run = false;
public PanelThread(SurfaceHolder surfaceHolder, ScenarioView panel) {
_surfaceHolder = surfaceHolder;
_panel = panel;
}
public void setRunning(boolean run) { //Allow us to stop the thread
_run = run;
}
@Override
public void run() {
Canvas c;
while (_run) { //When setRunning(false) occurs, _run is
c = null; //set to false and loop ends, stopping thread
try {
2016-08-19 13:38:59 +02:00
// c = _surfaceHolder.lockCanvas(null);
2016-08-17 13:17:04 +02:00
c = _surfaceHolder.lockCanvas(null);
synchronized (_surfaceHolder) {
//Insert methods to modify positions of items in onDraw()
postInvalidate();
}
} finally {
if (c != null) {
_surfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
}
public ScenarioView(Context context, Scenario s) {
super(context);
getHolder().addCallback(this);
_scenario = s;
2016-08-19 13:38:59 +02:00
//setup paints for drawing
mainPaint.setColor(Color.GRAY);
mainPaint.setTextSize(40);
mainPaint.setTypeface(Typeface.SANS_SERIF);
linePaint.setColor(Color.GRAY);
linePaint.setStrokeWidth(5);
attrScorePaint.setColor(Color.DKGRAY);
for(Emotion emotion: Emotion.values()) {
Paint emoPaint = new Paint();
emoPaint.setTextSize(20);
emoPaint.setColor(emotion.getColor());
emoPaints.put(emotion, emoPaint);
Paint emoPaintOutline = new Paint();
emoPaintOutline.setColor(emotion.getColor());
emoPaintOutline.setStyle(Paint.Style.STROKE);
emoPaintOutline.setStrokeWidth(2);
emoOutlinePaints.put(emotion, emoPaintOutline);
Paint emoScoredPaint = new Paint();
float darkenFactor = 0.4f;
int red = (int) ((Color.red(emotion.getColor()) * darkenFactor));
int green = (int) ((Color.green(emotion.getColor()) * darkenFactor));
int blue = (int) ((Color.blue(emotion.getColor()) * darkenFactor));
int emoLightenedColor = Color.rgb(red, green, blue);
emoScoredPaint.setColor(emoLightenedColor);
emoScoredPaint.setTextSize(20);
emoScoredPaint.setStrokeWidth(2);
emoScoredPaint.setStyle(Paint.Style.FILL_AND_STROKE);
emoScoredPaints.put(emotion, emoScoredPaint);
}
2016-08-17 13:17:04 +02:00
}
@Override
public void onDraw(Canvas canvas) {
//do drawing stuff here.
2016-08-17 19:21:16 +02:00
float height = canvas.getHeight();
float width = canvas.getWidth();
// bottom at 80%;
float bottomline_height = height * (float) 0.8;
// draw current scores:
float used_width = (float) 0.8; // 0.7: only use center
float padding_left = canvas.getWidth() * (1-used_width) / 2;
float step_y = (canvas.getWidth() * used_width) / Emotion.values().length;
float max_ball_radius = step_y * (float) 0.8 / 2;
// canvas.drawLine(0, bottomline_height, width, bottomline_height, linePaint);
2016-08-17 19:21:16 +02:00
for(Emotion emotion: Emotion.values())
{
float value = 0;
if(currentAttributeScores.containsKey(emotion)) {
value = currentAttributeScores.get(emotion);
}
if(value < 5) {
value = 5;
}
float cx = padding_left + (step_y * emotion.ordinal() + step_y / 2);
float cy = bottomline_height;
canvas.drawCircle(cx, cy, max_ball_radius, mainPaint);
2016-08-19 13:38:59 +02:00
canvas.drawCircle(cx, cy, max_ball_radius, emoOutlinePaints.get(emotion));
2016-08-17 19:21:16 +02:00
2016-08-19 13:38:59 +02:00
// canvas.drawCircle(cx, cy, max_ball_radius * value/100, emoPaints.get(emotion.ordinal()));
canvas.drawCircle(cx, cy, max_ball_radius * value/100, attrScorePaint);
2016-08-17 19:21:16 +02:00
Path emoNamePath = new Path();
emoNamePath.moveTo(cx, cy + max_ball_radius * 1.5f);
// more curly line to draw on:
// emoNamePath.rCubicTo(width*0.1f,0, width*0.1f, height*0.2f,width*0.2f,height*0.2f);
emoNamePath.rLineTo(1000,1000);
2016-08-17 19:21:16 +02:00
// canvas.drawText(emotion.toString(), cx, cy + max_ball_radius * (float) 1.3, emoPaint);
2016-08-19 13:38:59 +02:00
canvas.drawTextOnPath(emotion.toString(), emoNamePath, 0, 0, emoPaints.get(emotion));
2016-08-17 19:21:16 +02:00
}
// Draw targets:
float sec_height = height * (float) 0.2; // each second is 20% of canvas height
// current moved position
float diff_y = sec_height * _scenario.getTime();
for(Scenario.Target target: _scenario.getTargets()) {
2016-08-19 13:38:59 +02:00
Paint targetPaint = (target.score == null) ? emoPaints.get(target.emotion) : emoScoredPaints.get(target.emotion);
2016-08-17 19:21:16 +02:00
float cy = bottomline_height - (target.timestamp * sec_height) + diff_y;
float cx = padding_left + (step_y * target.emotion.ordinal() + step_y / 2);
2016-08-19 13:38:59 +02:00
canvas.drawCircle(cx, cy, max_ball_radius * target.value/100, targetPaint);
if(target.score != null) {
canvas.drawText(Float.toString(target.score.value), cx, cy, targetPaint);
}
2016-08-17 19:21:16 +02:00
// String target_text = target.emotion.toString() + " " + target.value + "%";
// canvas.drawText(target_text, cx, y_pos + diff_y , emoPaint);
}
2016-08-19 13:38:59 +02:00
canvas.drawText("Total: " + Float.toString(_scenario.getTotalScore()), 50, 50, mainPaint);
2016-08-17 19:21:16 +02:00
}
2016-08-19 13:38:59 +02:00
// TODO: create AttributeScoreCollection class, with this method.
2016-08-17 19:21:16 +02:00
public void setCurrentAttributeScoresForFace(Face face)
{
for(Emotion emotion: Emotion.values()) {
currentAttributeScores.put(emotion, emotion.getValueFromFace(face));
}
2016-08-17 13:17:04 +02:00
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
setWillNotDraw(false); //Allows us to use invalidate() to call onDraw()
this.setZOrderOnTop(true);
holder.setFormat(PixelFormat.TRANSPARENT);
// Log.e("TEST2", "Jaa2!");
_thread = new PanelThread(getHolder(), this); //Start the thread that
_thread.setRunning(true); //will make calls to
_thread.start(); //onDraw()
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
try {
if(_thread != null) {
_thread.setRunning(false); //Tells thread to stop
_thread.join(); //Removes thread from mem.
}
} catch (InterruptedException e) {}
}
}