Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/Java/Threema/app/src/main/java/ch/threema/app/ui/     Datei vom 25.3.2026 mit Größe 7 kB image not shown  

Quelle  PaintView.java

  Sprache: JAVA
 

package ch.threema.app.ui;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import androidx.core.view.ViewCompat;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class PaintView extends View {
    private float mX, mY;
    private int currentColor, currentStrokeWidth, currentWidth, currentHeight;
    private boolean isTransparent = false;
    private static final float TOUCH_TOLERANCE = 4;
    private boolean isActive = true, hasMoved;
    private TouchListener onTouchListener;
    private final List<Rect> drawingRect = Collections.singletonList(new Rect());

    private final ArrayList<Path> paths = new ArrayList<>();
    private final ArrayList<Paint> paints = new ArrayList<>();

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

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

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

    private void init() {
        createPath();
        createPaint();

        // defaults
        currentColor = 0xFFFF0000;
        currentStrokeWidth = 15;
    }

    private Path createPath() {
        Path path = new Path();
        paths.add(path);

        return path;
    }

    private void createPaint() {
        Paint paint = new Paint();
        paints.add(paint);

        paint.setAntiAlias(true);
        paint.setDither(true);
        paint.setColor(currentColor);
        if (isTransparent) {
            paint.setAlpha(128);
        }
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeJoin(Paint.Join.ROUND);
        paint.setStrokeCap(Paint.Cap.ROUND);
        paint.setStrokeWidth(currentStrokeWidth);
    }

    private Path getCurrentPath() {
        return paths.get(paths.size() - 1);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        currentWidth = canvas.getWidth();
        currentHeight = canvas.getHeight();

        for (int i = 0; i < paths.size(); i++) {
            canvas.drawPath(paths.get(i), paints.get(i));
        }
    }

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

        getDrawingRect(drawingRect.get(0));
        ViewCompat.setSystemGestureExclusionRects(this, drawingRect);
    }

    private void touch_start(float x, float y) {
        // new path
        Path path = createPath();
        createPaint();

        path.moveTo(x, y);
        mX = x;
        mY = y;
        hasMoved = false;
    }

    private void touch_move(float x, float y) {
        if (isRealMovement(x, y)) {
            getCurrentPath().quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
            mX = x;
            mY = y;
            hasMoved = true;
        }
    }

    private void touch_up(float x, float y) {
        if (isRealMovement(x, y) || hasMoved) {
            getCurrentPath().lineTo(mX, mY);
            onTouchListener.onAdded();
        } else {
            int pathIndex = paths.size() - 1;
            paths.remove(pathIndex);
            paints.remove(pathIndex);
            invalidate();
        }
    }

    private boolean isRealMovement(float x, float y) {
        float dx = Math.abs(x - mX);
        float dy = Math.abs(y - mY);
        return (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (!isActive) {
            return false;
        }

        float x = event.getX();
        float y = event.getY();

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                touch_start(x, y);
                this.onTouchListener.onTouchDown();
                break;
            case MotionEvent.ACTION_MOVE:
                touch_move(x, y);
                break;
            case MotionEvent.ACTION_CANCEL:
                // Handle a cancel action the same as action up (for system gestures)
            case MotionEvent.ACTION_UP:
                touch_up(x, y);
                this.onTouchListener.onTouchUp();
                break;
            default:
                return false;
        }

        invalidate();

        return true;
    }

    public void undo() {
        int pathIndex = paths.size() - 1;
        if (pathIndex > 0) {
            paths.remove(pathIndex);
            paints.remove(pathIndex);
            invalidate();
            onTouchListener.onDeleted();
        }
    }

    public void renderOverlay(Canvas combinedCanvas, int srcWidth, int srcHeight) {
        // render overlay to original canvas
        float factorX = (float) combinedCanvas.getWidth() / (float) srcWidth;
        float factorY = (float) combinedCanvas.getHeight() / (float) srcHeight;

        Matrix matrix = new Matrix();
        matrix.setScale(factorX, factorY);

        for (int i = 0; i < paths.size(); i++) {
            Path path = paths.get(i);
            Path scaledPath = new Path();
            path.transform(matrix, scaledPath);

            Paint paint = paints.get(i);
            Paint scaledPaint = new Paint(paint);
            scaledPaint.setStrokeWidth(scaledPaint.getStrokeWidth() * factorX);

            combinedCanvas.drawPath(scaledPath, scaledPaint);
        }
    }

    public void recalculate(int newWidth, int newHeight) {
        if (currentHeight != 0 && currentWidth != 0) {
            float factorX = (float) newWidth / (float) currentWidth;
            float factorY = (float) newHeight / (float) currentHeight;

            Matrix matrix = new Matrix();
            matrix.setScale(factorX, factorY);

            for (int i = 0; i < paths.size(); i++) {
                Path path = paths.get(i);
                Path scaledPath = new Path();
                path.transform(matrix, scaledPath);
                paths.get(i).set(scaledPath);

                Paint paint = paints.get(i);
                Paint scaledPaint = new Paint(paint);
                scaledPaint.setStrokeWidth(scaledPaint.getStrokeWidth() * factorX);
                paints.get(i).set(scaledPaint);
            }
            invalidate();
        }
    }

    public void flip() {
        Matrix flipMatrix = new Matrix();
        flipMatrix.setScale(-1, 1);
        flipMatrix.postTranslate(getWidth(), 0);

        for (Path path : paths) {
            path.transform(flipMatrix);
        }
    }

    public void setColor(int color) {
        currentColor = color;
    }

    public void setTransparent(boolean isTransparent) {
        this.isTransparent = isTransparent;
    }

    public void setStrokeWidth(int width) {
        currentStrokeWidth = width;
    }

    public void setActive(boolean active) {
        isActive = active;
    }

    public boolean getActive() {
        return isActive;
    }

    public int getNumPaths() {
        return paths.size() - 1;
    }

    public void setTouchListener(TouchListener touchListener) {
        this.onTouchListener = touchListener;
    }

    public interface TouchListener {
        void onTouchUp();

        void onTouchDown();

        void onAdded();

        void onDeleted();
    }
}

Messung V0.5 in Prozent
C=95 H=96 G=95

¤ Dauer der Verarbeitung: 0.0 Sekunden  (vorverarbeitet am  2026-04-27) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.