net.simno.dmach.ui.view.SettingView.java Source code

Java tutorial

Introduction

Here is the source code for net.simno.dmach.ui.view.SettingView.java

Source

/*
* Copyright (C) 2014 Simon Norberg
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package net.simno.dmach.ui.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.support.annotation.NonNull;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.MotionEvent;

import net.simno.dmach.DMachApp;
import net.simno.dmach.R;
import net.simno.dmach.model.Channel;
import net.simno.dmach.model.Setting;

import javax.inject.Inject;

import static android.support.v4.content.ContextCompat.getColor;

public final class SettingView extends PdView {

    public interface OnSettingChangedListener {
        void onSettingChanged(Channel channel, float x, float y);
    }

    @Inject
    Typeface typeface;
    private Channel channel;
    private Paint shapePaint;
    private Paint textPaint;
    private float shapeStrokeWidth;
    private float textSize;
    private int backgroundColor;
    private float circleRadius;
    private OnSettingChangedListener listener;
    private final Rect hBounds = new Rect();
    private final Rect vBounds = new Rect();
    private final Path path = new Path();
    private String hText;
    private String vText;
    private float x;
    private float y;
    private float originX;
    private float originY;
    private int hOffset;
    private int vOffset;

    public SettingView(Context context) {
        super(context);
        init(context);
    }

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

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

    private void init(Context context) {
        DMachApp.get(context).component().inject(this);

        backgroundColor = getColor(context, R.color.gamboge);
        textSize = getResources().getDimension(R.dimen.text_size_setting);
        circleRadius = getResources().getDimension(R.dimen.circle_radius);
        shapeStrokeWidth = getResources().getDimension(R.dimen.shape_stroke_width);

        shapePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        shapePaint.setStrokeWidth(shapeStrokeWidth);
        shapePaint.setStyle(Paint.Style.STROKE);
        shapePaint.setColor(getColor(context, R.color.colonial));

        textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        textPaint.setColor(getColor(context, R.color.dune));
        textPaint.setTextSize(textSize);
        textPaint.setStyle(Paint.Style.FILL);
        textPaint.setTypeface(typeface);
    }

    @Override
    protected float getMinX() {
        return circleRadius + (shapeStrokeWidth / 2f);
    }

    @Override
    protected float getMinY() {
        return getMinX();
    }

    @Override
    protected float getMaxX() {
        return getWidth() - getMinX();
    }

    @Override
    protected float getMaxY() {
        return getHeight() - getMinY();
    }

    private void notifyOnSettingChanged() {
        if (listener != null && channel != null) {
            listener.onSettingChanged(channel, xToPd(x), yToPd(y));
        }
    }

    public void setOnSettingChangedListener(OnSettingChangedListener listener) {
        this.listener = listener;
    }

    public void setChannel(Channel channel) {
        this.channel = channel;
        updateSetting();
    }

    private void updateSetting() {
        if (channel == null) {
            return;
        }
        Setting setting = channel.getSetting();

        x = pdToX(setting.getX());
        y = pdToY(setting.getY());
        hText = setting.getHText();
        vText = setting.getVText();

        textPaint.getTextBounds(hText, 0, hText.length(), hBounds);
        originX = (getWidth() / 2f) - hBounds.centerX();
        originY = getHeight() - (textSize * 0.4f);

        textPaint.getTextBounds(vText, 0, vText.length(), vBounds);
        path.reset();
        path.moveTo(0, (getHeight() / 2f) + vBounds.centerX());
        path.lineTo(0, 0);
        hOffset = 0;
        vOffset = (int) textSize;

        invalidate();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawColor(backgroundColor);
        if (!TextUtils.isEmpty(hText)) {
            canvas.drawText(hText, originX, originY, textPaint);
        }
        if (!TextUtils.isEmpty(vText)) {
            canvas.drawTextOnPath(vText, path, hOffset, vOffset, textPaint);
        }
        canvas.drawCircle(x, y, circleRadius, shapePaint);
    }

    @Override
    public boolean onTouchEvent(@NonNull MotionEvent event) {
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
        case MotionEvent.ACTION_MOVE:
            x = getValidX(event.getX());
            y = getValidY(event.getY());
            notifyOnSettingChanged();
            invalidate();
            break;
        }
        return true;
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        if (changed) {
            updateSetting();
        }
    }

    @Override
    public boolean hasOverlappingRendering() {
        return false;
    }
}