Search in sources :

Example 1 with PostDrawEvent

use of org.eclipse.tracecompass.internal.tmf.ui.widgets.timegraph.TimeGraphRender.PostDrawEvent in project tracecompass by tracecompass.

the class TimeGraphControl method paint.

@Override
void paint(Rectangle bounds, PaintEvent e) {
    try (ScopeLog sl = new ScopeLog(LOGGER, Level.FINE, fPaintScopeLabel)) {
        GC gc = e.gc;
        fPostDrawEntries.clear();
        fPostDrawArrows.clear();
        fLines.clear();
        fPoints.clear();
        fSelectedRectangles.clear();
        if (bounds.width < 2 || bounds.height < 2 || null == fTimeProvider) {
            return;
        }
        fIdealNameSpace = 0;
        int nameSpace = fTimeProvider.getNameSpace();
        try (ScopeLog bgScope = new ScopeLog(LOGGER, Level.FINEST, fBackgroundScopeLabel)) {
            // draw the background layer
            drawBackground(bounds, nameSpace, gc);
        }
        try (ScopeLog glScope = new ScopeLog(LOGGER, Level.FINEST, fGridLinesScopeLabel)) {
            // draw the grid lines
            drawGridLines(bounds, gc);
        }
        try (ScopeLog bgmScope = new ScopeLog(LOGGER, Level.FINEST, fBgmScopeLabel)) {
            // draw the background markers
            drawMarkers(bounds, fTimeProvider, fMarkers, false, nameSpace, gc);
        }
        try (ScopeLog itemsScope = new ScopeLog(LOGGER, Level.FINEST, fItemsScopeLabel)) {
            // draw the items
            drawItems(bounds, fTimeProvider, fItemData.fExpandedItems, fTopIndex, nameSpace, gc);
        }
        try (ScopeLog markerScope = new ScopeLog(LOGGER, Level.FINEST, fMarkersScopeLabel)) {
            // draw the foreground markers
            drawMarkers(bounds, fTimeProvider, fMarkers, true, nameSpace, gc);
        }
        try (ScopeLog linksScope = new ScopeLog(LOGGER, Level.FINEST, fLinksScopeLabel)) {
            // draw the links (arrows)
            drawLinks(bounds, fTimeProvider, fItemData.fLinks, nameSpace, gc);
        }
        gc.setAlpha(OPAQUE * 2 / 5);
        long time0 = fTimeProvider.getTime0();
        long time1 = fTimeProvider.getTime1();
        long selectionBegin = fTimeProvider.getSelectionBegin();
        long selectionEnd = fTimeProvider.getSelectionEnd();
        double pixelsPerNanoSec = (bounds.width - nameSpace <= RIGHT_MARGIN) ? 0 : (double) (bounds.width - nameSpace - RIGHT_MARGIN) / (time1 - time0);
        int x0 = SaturatedArithmetic.add(bounds.x + nameSpace, (int) ((selectionBegin - time0) * pixelsPerNanoSec));
        int x1 = SaturatedArithmetic.add(bounds.x + nameSpace, (int) ((selectionEnd - time0) * pixelsPerNanoSec));
        // draw selection lines
        if (fDragState != DRAG_SELECTION) {
            gc.setForeground(getColorScheme().getColor(TimeGraphColorScheme.SELECTED_TIME));
            if (x0 >= nameSpace && x0 < bounds.x + bounds.width) {
                gc.drawLine(x0, bounds.y, x0, bounds.y + bounds.height);
            }
            if (x1 != x0) {
                if (x1 >= nameSpace && x1 < bounds.x + bounds.width) {
                    gc.drawLine(x1, bounds.y, x1, bounds.y + bounds.height);
                }
            }
        }
        // draw selection background
        if (selectionBegin != 0 && selectionEnd != 0 && fDragState != DRAG_SELECTION) {
            x0 = Math.max(nameSpace, Math.min(bounds.x + bounds.width, x0));
            x1 = Math.max(nameSpace, Math.min(bounds.x + bounds.width, x1));
            gc.setBackground(getColorScheme().getBkColor(false, false, true));
            if (x1 - x0 > 1) {
                gc.fillRectangle(new Rectangle(x0 + 1, bounds.y, x1 - x0 - 1, bounds.height));
            } else if (x0 - x1 > 1) {
                gc.fillRectangle(new Rectangle(x1 + 1, bounds.y, x0 - x1 - 1, bounds.height));
            }
        }
        // draw drag selection background
        if (fDragState == DRAG_ZOOM || fDragState == DRAG_SELECTION) {
            gc.setBackground(getColorScheme().getBkColor(false, false, true));
            if (fDragX0 < fDragX) {
                gc.fillRectangle(new Rectangle(fDragX0, bounds.y, fDragX - fDragX0, bounds.height));
            } else if (fDragX0 > fDragX) {
                gc.fillRectangle(new Rectangle(fDragX, bounds.y, fDragX0 - fDragX, bounds.height));
            }
        }
        // draw split line
        if (DRAG_SPLIT_LINE == fDragState || (DRAG_NONE == fDragState && fMouseOverSplitLine && fTimeProvider.getNameSpace() > 0)) {
            gc.setBackground(getColorScheme().getColor(TimeGraphColorScheme.DARK_GRAY));
        } else {
            gc.setBackground(getColorScheme().getColor(TimeGraphColorScheme.GRAY));
        }
        gc.fillRectangle(bounds.x + nameSpace - SNAP_WIDTH, bounds.y, SNAP_WIDTH, bounds.height);
        if (DRAG_ZOOM == fDragState && Math.max(fDragX, fDragX0) > nameSpace) {
            gc.setForeground(getColorScheme().getColor(TimeGraphColorScheme.TOOL_FOREGROUND));
            gc.drawLine(fDragX0, bounds.y, fDragX0, bounds.y + bounds.height - 1);
            if (fDragX != fDragX0) {
                gc.drawLine(fDragX, bounds.y, fDragX, bounds.y + bounds.height - 1);
            }
        } else if (DRAG_SELECTION == fDragState && Math.max(fDragX, fDragX0) > nameSpace) {
            gc.setForeground(getColorScheme().getColor(TimeGraphColorScheme.SELECTED_TIME));
            gc.drawLine(fDragX0, bounds.y, fDragX0, bounds.y + bounds.height - 1);
            if (fDragX != fDragX0) {
                gc.drawLine(fDragX, bounds.y, fDragX, bounds.y + bounds.height - 1);
            }
        }
        gc.setAlpha(OPAQUE);
        for (PostDrawEvent postDrawEvent : fPostDrawArrows) {
            postDrawEvent.draw(fTimeGraphProvider, gc);
        }
        fPostDrawEntries.clear();
        fPostDrawArrows.clear();
        fTimeGraphProvider.postDrawControl(bounds, gc);
    }
}
Also used : PostDrawEvent(org.eclipse.tracecompass.internal.tmf.ui.widgets.timegraph.TimeGraphRender.PostDrawEvent) Rectangle(org.eclipse.swt.graphics.Rectangle) GC(org.eclipse.swt.graphics.GC) ScopeLog(org.eclipse.tracecompass.common.core.log.TraceCompassLogUtils.ScopeLog) Point(org.eclipse.swt.graphics.Point) LongPoint(org.eclipse.tracecompass.internal.tmf.ui.widgets.timegraph.TimeGraphRender.LongPoint)

Example 2 with PostDrawEvent

use of org.eclipse.tracecompass.internal.tmf.ui.widgets.timegraph.TimeGraphRender.PostDrawEvent in project tracecompass by tracecompass.

the class TimeGraphControl method drawArrow.

/**
 * Draw an arrow
 *
 * @param colors
 *            Color scheme
 * @param event
 *            Time event for which we're drawing the arrow
 * @param rect
 *            The arrow rectangle
 * @param gc
 *            Graphics context
 * @return true if the arrow was drawn
 */
protected boolean drawArrow(TimeGraphColorScheme colors, @NonNull ITimeEvent event, Rectangle rect, GC gc) {
    if (rect == null || ((rect.height == 0) && (rect.width == 0))) {
        return false;
    }
    StyleManager styleManager = getStyleManager();
    OutputElementStyle elementStyle = getElementStyle(event);
    if (elementStyle == null) {
        return false;
    }
    RGBAColor rgba = styleManager.getColorStyle(elementStyle, StyleProperties.COLOR);
    rgba = (rgba != null) ? rgba : BLACK;
    int colorInt = rgba.toInt();
    Color color = TimeGraphRender.getColor(colorInt);
    int alpha = rgba.getAlpha();
    int prevAlpha = gc.getAlpha();
    gc.setAlpha(alpha);
    gc.setForeground(color);
    gc.setBackground(color);
    int old = gc.getLineWidth();
    Float widthFactor = styleManager.getFactorStyle(elementStyle, StyleProperties.WIDTH);
    if (widthFactor == null) {
        Float heightFactor = styleManager.getFactorStyle(elementStyle, StyleProperties.HEIGHT);
        widthFactor = (heightFactor != null) ? heightFactor * 10.0f : 1.0f;
    }
    widthFactor = Math.max(1.0f, Math.min(10.0f, widthFactor));
    gc.setLineWidth(widthFactor.intValue());
    /* Draw the arrow */
    Point newEndpoint = drawArrowHead(rect.x, rect.y, rect.x + rect.width, rect.y + rect.height, widthFactor, gc);
    gc.drawLine(rect.x, rect.y, newEndpoint.x, newEndpoint.y);
    gc.setLineWidth(old);
    gc.setAlpha(prevAlpha);
    if (!Boolean.TRUE.equals(styleManager.getStyle(elementStyle, ITimeEventStyleStrings.annotated()))) {
        fPostDrawArrows.add(new PostDrawEvent(event, rect));
    }
    return true;
}
Also used : OutputElementStyle(org.eclipse.tracecompass.tmf.core.model.OutputElementStyle) RGBAColor(org.eclipse.tracecompass.tmf.core.presentation.RGBAColor) PostDrawEvent(org.eclipse.tracecompass.internal.tmf.ui.widgets.timegraph.TimeGraphRender.PostDrawEvent) Color(org.eclipse.swt.graphics.Color) RGBAColor(org.eclipse.tracecompass.tmf.core.presentation.RGBAColor) StyleManager(org.eclipse.tracecompass.tmf.ui.model.StyleManager) Point(org.eclipse.swt.graphics.Point) LongPoint(org.eclipse.tracecompass.internal.tmf.ui.widgets.timegraph.TimeGraphRender.LongPoint) Point(org.eclipse.swt.graphics.Point) LongPoint(org.eclipse.tracecompass.internal.tmf.ui.widgets.timegraph.TimeGraphRender.LongPoint)

Example 3 with PostDrawEvent

use of org.eclipse.tracecompass.internal.tmf.ui.widgets.timegraph.TimeGraphRender.PostDrawEvent in project tracecompass by tracecompass.

the class TimeGraphControl method drawState.

/**
 * Draw the state (color fill)
 *
 * @param colors
 *            Color scheme
 * @param event
 *            Time event for which we're drawing the state
 * @param rect
 *            The state rectangle
 * @param gc
 *            Graphics context
 * @param selected
 *            Is this time event currently selected (so it appears
 *            highlighted)
 * @param timeSelected
 *            Is the timestamp currently selected
 * @return true if the state was drawn
 */
protected boolean drawState(TimeGraphColorScheme colors, @NonNull ITimeEvent event, Rectangle rect, GC gc, boolean selected, boolean timeSelected) {
    StyleManager styleManager = getStyleManager();
    OutputElementStyle elementStyle = getElementStyle(event);
    if (elementStyle == null) {
        return false;
    }
    boolean transparent = elementStyle.getParentKey() == null && elementStyle.getStyleValues().isEmpty();
    boolean visible = rect.width <= 0 ? false : true;
    rect.width = Math.max(1, rect.width);
    Float heightFactor = styleManager.getFactorStyle(elementStyle, StyleProperties.HEIGHT);
    heightFactor = (heightFactor != null) ? Math.max(0.0f, Math.min(1.0f, heightFactor)) : DEFAULT_STATE_WIDTH;
    int height = 0;
    if (heightFactor != 0.0f && rect.height != 0) {
        height = Math.max(1, (int) (rect.height * heightFactor));
    }
    Rectangle drawRect = new Rectangle(rect.x, rect.y + ((rect.height - height) / 2), rect.width, height);
    Color black = TimeGraphRender.getColor(BLACK.toInt());
    gc.setForeground(black);
    List<DeferredItem> states = fCurrentDeferredEntry.getItems();
    if (transparent) {
        if (visible) {
            // Avoid overlapping transparent states
            int x = Math.max(fLastTransparentX, drawRect.x);
            drawRect.width = drawRect.x + drawRect.width - x;
            if (drawRect.width > 0) {
                // Draw transparent background
                RGBAColor bgColor = fTransparentGrayColor;
                DeferredItem deferredItem = new DeferredTransparentState(drawRect, bgColor);
                if (states.isEmpty() || !states.get(states.size() - 1).getBounds().intersects(drawRect)) {
                    states.add(deferredItem);
                    deferredItem.add(new PostDrawEvent(event, drawRect));
                }
                fLastTransparentX = Math.max(fLastTransparentX, drawRect.x + drawRect.width);
            } else {
                // clamp it to 0, just in case
                drawRect.width = 0;
            }
            if (drawRect.width <= 2) {
                // Draw point over state
                addPoint(fPoints, rect.x, rect.y - 2);
                if (drawRect.width == 2) {
                    addPoint(fPoints, rect.x + 1, rect.y - 2);
                }
            }
        } else {
            addPoint(fPoints, rect.x, rect.y - 2);
        }
        return false;
    }
    int arc = Math.min(drawRect.height + 1, drawRect.width) / 2;
    RGBAColor rgba = styleManager.getColorStyle(elementStyle, StyleProperties.BACKGROUND_COLOR);
    @NonNull RGBAColor bgColor = (rgba != null) ? rgba : BLACK;
    boolean reallySelected = timeSelected && selected;
    // fill all rect area
    boolean draw = visible || fBlendSubPixelEvents;
    DeferredItem last = null;
    if (draw) {
        if (!states.isEmpty()) {
            DeferredItem state = states.get(states.size() - 1);
            while ((state instanceof DeferredTransparentState) && (state.getBounds().x == drawRect.x)) {
                states.remove(states.size() - 1);
                state = states.isEmpty() ? null : states.get(states.size() - 1);
            }
        }
        RGBAColor borderColor = BLACK;
        int lineWidth = DeferredItem.NO_BORDER;
        Object borderStyle = styleManager.getStyle(elementStyle, StyleProperties.BORDER_STYLE);
        boolean hasBorders = borderStyle != null && !BorderStyle.NONE.equals(borderStyle);
        if (hasBorders) {
            Object borderWidth = styleManager.getStyle(elementStyle, StyleProperties.BORDER_WIDTH);
            lineWidth = 1;
            if (borderWidth instanceof Integer) {
                lineWidth = (int) borderWidth;
            }
            borderColor = styleManager.getColorStyle(elementStyle, StyleProperties.BORDER_COLOR);
            if (borderColor == null) {
                borderColor = BLACK;
            }
        }
        /*
             * This has been tested in Linux and Windows, results may vary. The
             * rounded rectangle is not noticeable for adjacent states of the
             * same color until width=6 (arc=3) with antialiasing, or width=8
             * (arc=4) without antialiasing.
             *
             * In other words, only draw rounded rectangles if the arc is
             * noticeable.
             */
        if (arc >= 2) {
            last = new DeferredState(drawRect, bgColor, Objects.requireNonNull(borderColor), arc, lineWidth, fLabelsVisible ? event.getLabel() : null);
            states.add(last);
        } else {
            DeferredTinyState tinyCandidate = new DeferredTinyState(drawRect, bgColor, Objects.requireNonNull(borderColor), lineWidth);
            boolean skipState = false;
            if (!states.isEmpty()) {
                DeferredItem prev = states.get(states.size() - 1);
                if (prev instanceof DeferredTinyState) {
                    DeferredTinyState tinyState = (DeferredTinyState) prev;
                    if (fBlendSubPixelEvents) {
                        skipState = tinyState.squash(tinyCandidate);
                    } else if (tinyState.extend(tinyCandidate)) {
                        skipState = true;
                    }
                }
            }
            if (!skipState) {
                states.add(tinyCandidate);
            }
            last = tinyCandidate;
        }
    }
    if (reallySelected) {
        fSelectedRectangles.add(drawRect);
    }
    if (!visible) {
        addPoint(fPoints, rect.x, rect.y - 2);
    }
    if (visible && !Boolean.TRUE.equals(styleManager.getStyle(elementStyle, ITimeEventStyleStrings.annotated())) && last != null) {
        last.add(new PostDrawEvent(event, drawRect));
    }
    return visible && !event.isPropertyActive(IFilterProperty.DIMMED);
}
Also used : OutputElementStyle(org.eclipse.tracecompass.tmf.core.model.OutputElementStyle) DeferredItem(org.eclipse.tracecompass.internal.tmf.ui.widgets.timegraph.TimeGraphRender.DeferredItem) DeferredTinyState(org.eclipse.tracecompass.internal.tmf.ui.widgets.timegraph.TimeGraphRender.DeferredTinyState) RGBAColor(org.eclipse.tracecompass.tmf.core.presentation.RGBAColor) Color(org.eclipse.swt.graphics.Color) RGBAColor(org.eclipse.tracecompass.tmf.core.presentation.RGBAColor) Rectangle(org.eclipse.swt.graphics.Rectangle) DeferredState(org.eclipse.tracecompass.internal.tmf.ui.widgets.timegraph.TimeGraphRender.DeferredState) Point(org.eclipse.swt.graphics.Point) LongPoint(org.eclipse.tracecompass.internal.tmf.ui.widgets.timegraph.TimeGraphRender.LongPoint) PostDrawEvent(org.eclipse.tracecompass.internal.tmf.ui.widgets.timegraph.TimeGraphRender.PostDrawEvent) NonNull(org.eclipse.jdt.annotation.NonNull) StyleManager(org.eclipse.tracecompass.tmf.ui.model.StyleManager) DeferredTransparentState(org.eclipse.tracecompass.internal.tmf.ui.widgets.timegraph.TimeGraphRender.DeferredTransparentState)

Aggregations

Point (org.eclipse.swt.graphics.Point)3 LongPoint (org.eclipse.tracecompass.internal.tmf.ui.widgets.timegraph.TimeGraphRender.LongPoint)3 PostDrawEvent (org.eclipse.tracecompass.internal.tmf.ui.widgets.timegraph.TimeGraphRender.PostDrawEvent)3 Color (org.eclipse.swt.graphics.Color)2 Rectangle (org.eclipse.swt.graphics.Rectangle)2 OutputElementStyle (org.eclipse.tracecompass.tmf.core.model.OutputElementStyle)2 RGBAColor (org.eclipse.tracecompass.tmf.core.presentation.RGBAColor)2 StyleManager (org.eclipse.tracecompass.tmf.ui.model.StyleManager)2 NonNull (org.eclipse.jdt.annotation.NonNull)1 GC (org.eclipse.swt.graphics.GC)1 ScopeLog (org.eclipse.tracecompass.common.core.log.TraceCompassLogUtils.ScopeLog)1 DeferredItem (org.eclipse.tracecompass.internal.tmf.ui.widgets.timegraph.TimeGraphRender.DeferredItem)1 DeferredState (org.eclipse.tracecompass.internal.tmf.ui.widgets.timegraph.TimeGraphRender.DeferredState)1 DeferredTinyState (org.eclipse.tracecompass.internal.tmf.ui.widgets.timegraph.TimeGraphRender.DeferredTinyState)1 DeferredTransparentState (org.eclipse.tracecompass.internal.tmf.ui.widgets.timegraph.TimeGraphRender.DeferredTransparentState)1