/******************************************************************************* * Copyright (c) 2013 Rene Schneider, GEBIT Solutions GmbH and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html *******************************************************************************/ package de.gebit.integrity.eclipse.controls; import org.eclipse.swt.SWT; import org.eclipse.swt.events.PaintEvent; import org.eclipse.swt.events.PaintListener; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import de.gebit.integrity.remoting.entities.setlist.SetList; import de.gebit.integrity.remoting.entities.setlist.SetListEntryResultStates; /** * The test progress bar. * * @author Rene Schneider - initial API and implementation * */ public class ProgressBar extends Composite { /** * The set list. */ private SetList setList; /** * This color will be used for successful tests/calls/suites. */ private Color resultSuccessColor; /** * Color for failed tests/calls/suites. */ private Color resultFailureColor; /** * Color for not-yet-executed tests/calls/suites. */ private Color resultNeutralColor; /** * Color for tests/calls/suites that resulted in an exception being thrown. */ private Color resultExceptionColor; /** * The color of the border. */ private Color borderColor; /** * Creates a new instance. * * @param aParent * the parent container * @param aStyle * the style */ public ProgressBar(Composite aParent, int aStyle) { this(aParent, aStyle, null); } /** * Creates a new instance. * * @param aParent * the parent container * @param aStyle * the style * @param aSetList * the set list to use */ public ProgressBar(Composite aParent, int aStyle, SetList aSetList) { super(aParent, aStyle | SWT.NO_BACKGROUND | SWT.DOUBLE_BUFFERED); setList = aSetList; resultSuccessColor = new Color(Display.getCurrent(), 0, 94, 13); resultFailureColor = new Color(Display.getCurrent(), 190, 0, 0); resultNeutralColor = new Color(Display.getCurrent(), 220, 220, 220); resultExceptionColor = new Color(Display.getCurrent(), 204, 163, 0); borderColor = new Color(Display.getCurrent(), 181, 189, 210); addPaintListener(new PaintListener() { @Override public void paintControl(PaintEvent anEvent) { updateDisplay(anEvent.gc, anEvent.x, anEvent.y, anEvent.width, anEvent.height, ProgressBar.this.getBounds().width); } }); } public void setSetList(SetList aSetList) { setList = aSetList; } private void updateDisplay(GC aGC, int anX, int anY, int aWidth, int aHeight, int aFullWidth) { aGC.setLineStyle(SWT.LINE_SOLID); aGC.setLineWidth(1); if (setList == null) { aGC.setBackground(resultNeutralColor); aGC.fillRectangle(anX, anY, aWidth, aHeight); } else { int tempTotalCount = setList.getNumberOfExecutableEntries(); for (int tempX = anX; tempX < anX + aWidth; tempX++) { SetListEntryResultStates tempState = getResultStateForPosition(tempX, aWidth, tempTotalCount); if (tempState == null) { tempState = SetListEntryResultStates.UNKNOWN; } switch (tempState) { case SUCCESSFUL: aGC.setForeground(resultSuccessColor); break; case FAILED: aGC.setForeground(resultFailureColor); break; case EXCEPTION: aGC.setForeground(resultExceptionColor); break; case UNKNOWN: default: aGC.setForeground(resultNeutralColor); } aGC.drawLine(tempX, anY, tempX, anY + aHeight); } } if (anY + aHeight == getBounds().height) { aGC.setForeground(borderColor); aGC.drawLine(anX, anY + aHeight - 1, anX + aWidth, anY + aHeight - 1); } } /** * Returns the result state (which controls the color) at a specific pixel position. * * @param aPos * the position (must be < aMax) * @param aWidth * the width in pixels * @param aMax * the maximum position * @return */ protected SetListEntryResultStates getResultStateForPosition(int aPos, int aWidth, int aMax) { int tempMinEntryPosition = (int) Math.floor(((double) aPos / (double) aWidth) * (double) aMax); int tempMaxEntryPosition = (int) Math.ceil(((double) (aPos + 1) / (double) aWidth) * (double) aMax) - 1; if (tempMinEntryPosition >= tempMaxEntryPosition) { return setList.getResultStateForExecutableEntry(tempMinEntryPosition); } else { boolean tempHasUnknown = false; for (int i = tempMinEntryPosition; i < tempMaxEntryPosition; i++) { SetListEntryResultStates tempResultState = setList.getResultStateForExecutableEntry(i); if (tempResultState != null) { switch (tempResultState) { case EXCEPTION: return SetListEntryResultStates.EXCEPTION; case FAILED: return SetListEntryResultStates.FAILED; case UNKNOWN: tempHasUnknown = true; break; case SUCCESSFUL: continue; default: break; } } } if (tempHasUnknown) { return SetListEntryResultStates.UNKNOWN; } else { return SetListEntryResultStates.SUCCESSFUL; } } } @Override public void dispose() { resultExceptionColor.dispose(); resultFailureColor.dispose(); resultNeutralColor.dispose(); resultSuccessColor.dispose(); borderColor.dispose(); super.dispose(); } }