package com.mobilesorcery.sdk.profiling.ui.views; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; import java.text.NumberFormat; import java.util.Locale; import org.eclipse.jface.viewers.OwnerDrawLabelProvider; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.TreeItem; import com.mobilesorcery.sdk.core.IFilter; import com.mobilesorcery.sdk.profiling.IInvocation; import com.mobilesorcery.sdk.profiling.IProfilingSession; public class PercentageBarLabelProvider extends OwnerDrawLabelProvider { private final static NumberFormat PERCENTAGE = new DecimalFormat("##0.00%", DecimalFormatSymbols.getInstance(Locale.US)); private IProfilingSession session; private boolean aggregatedPercentage; public PercentageBarLabelProvider(boolean aggregatedPercentage) { this.aggregatedPercentage = aggregatedPercentage; } public void setSession(IProfilingSession session) { this.session = session; } protected void measure(Event event, Object obj) { Rectangle bounds = ((TreeItem)event.item).getBounds(event.index); event.setBounds(new Rectangle(event.x, event.y, bounds.width, bounds.height)); } protected void paint(Event event, Object obj) { if (obj != null && session.getFilter().accept((IInvocation) obj)) { measure(event, obj); IInvocation invocation = (IInvocation) obj; IFilter<IInvocation> filter = aggregatedPercentage ? null : session.getFilter(); float timeInMs = aggregatedPercentage ? invocation.getAggregateTime() : invocation.getSelfTime(); String percentage = getPercentage(timeInMs, filter); float ratio = getRatio(timeInMs, filter); GC gc = event.gc; Rectangle bounds = event.getBounds(); Point actualTextExtent = gc.textExtent(percentage); gc.drawText(percentage, bounds.x + event.width - actualTextExtent.x, bounds.y); gc.setBackground(gc.getDevice().getSystemColor(SWT.COLOR_RED)); gc.setForeground(gc.getDevice().getSystemColor(SWT.COLOR_RED)); int barWidth = Math.round(((float)bounds.width - maxTextExtent(event).x) * ratio); gc.fillRectangle(bounds.x, bounds.y + 1, barWidth, bounds.height - 2); } } private Point maxTextExtent(Event event) { return event.gc.textExtent(">100.00%"); } private float getRatio(float timeInMs, IFilter<IInvocation> filter) { float totalTime = getFilteredAggregateTime(session.getInvocation(), filter); float ratio = timeInMs / totalTime; return ratio; } private String getPercentage(float timeInMs, IFilter<IInvocation> filter) { return PERCENTAGE.format(getRatio(timeInMs, filter)); } private float getFilteredAggregateTime(IInvocation rootInvocation, IFilter<IInvocation> filter) { // TODO: Refactor float totalTime = 0; for (IInvocation child : rootInvocation.getInvocations()) { if (filter == null || filter.accept(child)) { totalTime += child.getSelfTime(); } totalTime += getFilteredAggregateTime(child, filter); } return totalTime; } }