Newer
Older
Cactus-CleanArchitecture / app / src / main / java / org / ntlab / radishforandroidstudio / framework / RWT / RWTPad.java
s-iwatani on 29 Nov 2018 3 KB 設計修正
package org.ntlab.radishforandroidstudio.framework.RWT;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.util.AttributeSet;
import android.view.MotionEvent;

import org.ntlab.radishforandroidstudio.framework.event.PadEvent;
import org.ntlab.radishforandroidstudio.framework.listener.PadListener;
import org.ntlab.radishforandroidstudio.framework.listener.SamplePadListener;
import org.ntlab.radishforandroidstudio.framework.subject.PadSubject;

/**
 * Padクラス
 * Android Viewに貼り付けているもの
 *
 * @author s.iwatani
 */

public class RWTPad extends RWTView {
    private Point circlePos;
    private PadSubject subject = new PadSubject();

    public RWTPad(Context context) {
        super(context);
    }

    public RWTPad(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public RWTPad(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    /**
     * 状態を初期化する
     */
    @Override
    public void init() {
        super.init();
    }

    /**
     * canvasに描画を行う
     *
     * @param canvas
     */
    // TODO: 見た目の調整
    @Override
    public void onDraw(Canvas canvas) {
        // super.onDraw(canvas);
        Paint paint = this.createRedPaint();
        canvas.drawCircle(getSize().x / 2, getSize().x / 2, getSize().x / 2, paint);

        // TODO: あとでいい感じになるように修正
        // このクラス内の他の部分も同様
        paint.setColor(Color.BLUE);
        if (circlePos == null) {
            circlePos = new Point(getSize().x / 2, getSize().y / 2);
        }
        canvas.drawCircle(circlePos.x, circlePos.y, getSize().x / 6, paint);
    }

    private Paint createRedPaint() {
        Paint paint = new Paint();
        paint.setAntiAlias(true);
        paint.setColor(Color.RED);
        // 以下の値が小さいと点が見えない可能性があります
        paint.setStrokeWidth(10);
        return paint;
    }

    /**
     * Padをタッチしたときのイベント
     *
     * @param event
     * @return
     */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // 中央からの距離を取得
        float dx = event.getX() - getSize().x / 2;
        float dy = event.getY() - getSize().y / 2;
        float rawLen = (float)Math.sqrt(dx*dx + dy*dy);
        float angle = (float)Math.atan2(dy, dx);
        float maxLen = getSize().x / 2;
        float len = rawLen / maxLen;
        float fixLen = Math.max(Math.min(1.f, len), -1.f);

        circlePos.x = (int)event.getX();
        circlePos.y = (int)event.getY();

        if (len > 1) {
            circlePos.x = (int)(fixLen * Math.cos(angle) * maxLen + maxLen);
            circlePos.y = (int)(fixLen * Math.sin(angle) * maxLen + maxLen);
        }

        MotionEvent touchInfo = event;
        PadEvent padEvent = new PadEvent(event, fixLen, angle);
        subject.notifyListeners(padEvent);

        if (event.getAction() == MotionEvent.ACTION_UP) {
            circlePos.x = getSize().x / 2;
            circlePos.y = getSize().y / 2;
        }

        invalidate();
        return true;
    }

    /**
     * Pad操作時に発生するイベントのリスナを追加する
     * @param listener
     */
    public void addListener(PadListener listener) {
        subject.addListener(listener);
    }
}