/* * Copyright (C) 2016 Naman Dwivedi * * Licensed under the GNU General Public License v3 * * This 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 software 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. */ package com.naman14.algovisualizer.visualizer; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Point; import android.graphics.Rect; import android.util.AttributeSet; import com.naman14.algovisualizer.algorithm.list.Stack; public class StackVisualizer extends AlgorithmVisualizer { int[] array; Stack stack; private Paint textPaint; private Paint circlePaint; private Paint linePaint; private Paint circleHighlightPaint; private Paint lineHighlightPaint; private Rect bounds; private int highlightNode = -1; public StackVisualizer(Context context) { super(context); initialise(); } public StackVisualizer(Context context, AttributeSet attrs) { super(context, attrs); initialise(); } public void setData(Stack stack) { this.stack = stack; this.array = stack.getStackArray(); invalidate(); } private void initialise() { textPaint = new Paint(); circlePaint = new Paint(); textPaint.setColor(Color.WHITE); textPaint.setTextSize(getDimensionInPixelFromSP(15)); textPaint.setAntiAlias(true); textPaint.setTextAlign(Paint.Align.CENTER); bounds = new Rect(); textPaint.getTextBounds("0", 0, 1, bounds); circlePaint.setColor(Color.RED); circlePaint.setAntiAlias(true); linePaint = new Paint(); linePaint.setStrokeWidth(5); linePaint.setColor(Color.BLACK); circleHighlightPaint = new Paint(circlePaint); circleHighlightPaint.setColor(Color.BLUE); lineHighlightPaint = new Paint(linePaint); lineHighlightPaint.setColor(Color.RED); lineHighlightPaint.setStrokeWidth(getDimensionInPixel(2)); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); setMeasuredDimension(getMeasuredWidth(), getDimensionInPixel(170)); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (array != null && array.length != 0) { drawStack(canvas); } } private void drawStack(Canvas canvas) { int actualLength = 0; for (int i : array) { if (i != 0) actualLength++; } if (actualLength == 0) return; int blockWidth = getWidth() / (actualLength); Point p = new Point(); p.x = (array.length > 4) ? getDimensionInPixel(30) : getDimensionInPixel(40); p.y = getHeight() / 2; for (int i = 0; i < array.length; i++) { Point end = new Point(p); end.x = p.x + blockWidth; if (!(i == array.length - 1) && array[i] != 0 && array[i + 1] != 0) drawNodeLine(canvas, p, end, false, true); drawCircleTextNode(canvas, p, array[i]); p.x += blockWidth; } } private void drawNodeLine(Canvas canvas, Point start, Point end, boolean highlight, boolean draw) { if (draw) { int midx = (start.x + end.x) / 2; int midy = (start.y + end.y) / 2; if (highlight) { canvas.drawLine(start.x, start.y, end.x, end.y, lineHighlightPaint); canvas.drawLine(midx, midy, midx - getDimensionInPixel(6), midy + getDimensionInPixel(5), lineHighlightPaint); canvas.drawLine(midx, midy, midx - getDimensionInPixel(6), midy - getDimensionInPixel(5), lineHighlightPaint); } else { canvas.drawLine(start.x, start.y, end.x, end.y, linePaint); canvas.drawLine(midx, midy, midx - getDimensionInPixel(6), midy - getDimensionInPixel(5), linePaint); canvas.drawLine(midx, midy, midx - getDimensionInPixel(6), midy + getDimensionInPixel(5), linePaint); } } } private void drawCircleTextNode(Canvas canvas, Point p, int number) { if (number == 0) { return; } String text = String.valueOf(number); if (number == highlightNode) { canvas.drawCircle(p.x, p.y, getDimensionInPixel(15), circleHighlightPaint); } else { canvas.drawCircle(p.x, p.y, getDimensionInPixel(15), circlePaint); } int yOffset = bounds.height() / 2; canvas.drawText(text, p.x, p.y + yOffset, textPaint); } public void highlightNode(int pos) { this.highlightNode = pos; invalidate(); } @Override public void onCompleted() { this.highlightNode = -1; invalidate(); } }