use of com.efficios.jabberwocky.common.TimeRange in project lttng-scope by lttng.
the class TimeGraphWidget method paintCurrentLocation.
/**
* Bypass the redraw thread and do a manual redraw of the current location.
*/
@VisibleForTesting
void paintCurrentLocation() {
TimeRange currentHorizontalPos = getViewContext().getVisibleTimeRange();
VerticalPosition currentVerticalPos = getCurrentVerticalPosition();
paintArea(currentHorizontalPos, currentVerticalPos, true, true, 0);
}
use of com.efficios.jabberwocky.common.TimeRange in project lttng-scope by lttng.
the class NavUtils method selectNewTimestamp.
/**
* Move the selection to the target timestamp. Also update the visible range
* to be centered on that timestamp, but only if it is outside of the
* current visible range.
*
* This should only be called when reaching the new timestamp is caused by a
* user action (ie, not simply because another view sent a signal).
*
* @param viewer
* The viewer on which to work
* @param timestamp
* The timestamp to select, and potentially move to
*/
public static void selectNewTimestamp(TimeGraphWidget viewer, long timestamp) {
/* Update the selection to the new timestamp. */
viewer.getControl().updateTimeRangeSelection(TimeRange.of(timestamp, timestamp));
TimeRange fullTimeGraphRange = viewer.getControl().getViewContext().getCurrentProjectFullRange();
TimeRange windowRange = ViewGroupContextManager.getCurrent().getVisibleTimeRange();
long windowStart = windowRange.getStartTime();
long windowEnd = windowRange.getEndTime();
if (windowStart <= timestamp && timestamp <= windowEnd) {
/* Timestamp is still in the visible range, don't touch anything. */
return;
}
/* Update the visible range to the requested timestamp. */
/* The "span" of the window (aka zoom level) will remain constant. */
long windowSpan = windowEnd - windowStart;
if (windowSpan > fullTimeGraphRange.getDuration()) {
/* Should never happen, but just to be mathematically safe. */
windowSpan = fullTimeGraphRange.getDuration();
}
long newStart = timestamp - (windowSpan / 2);
long newEnd = newStart + windowSpan;
/* Clamp the range to the borders of the pane/trace. */
if (newStart < fullTimeGraphRange.getStartTime()) {
newStart = fullTimeGraphRange.getStartTime();
newEnd = newStart + windowSpan;
} else if (newEnd > fullTimeGraphRange.getEndTime()) {
newEnd = fullTimeGraphRange.getEndTime();
newStart = newEnd - windowSpan;
}
viewer.getControl().updateVisibleTimeRange(TimeRange.of(newStart, newEnd), true);
}
use of com.efficios.jabberwocky.common.TimeRange in project lttng-scope by lttng.
the class TimeGraphWidget method seekVisibleRange.
@Override
public void seekVisibleRange(@Nullable TimeRange newVisibleRange) {
requireNonNull(newVisibleRange);
final TimeRange fullTimeGraphRange = getViewContext().getCurrentProjectFullRange();
/* Update the zoom level */
long windowTimeRange = newVisibleRange.getDuration();
double timeGraphVisibleWidth = fTimeGraphScrollPane.getViewportBounds().getWidth();
if (timeGraphVisibleWidth < 100) {
/*
* The view's width is reported as 0 if the widget is not yet part of the
* scenegraph. Instead target a larger width so that we obtain a value of
* nanos-per-pixel that makes sense.
*/
timeGraphVisibleWidth = 2000;
}
fNanosPerPixel.set(windowTimeRange / timeGraphVisibleWidth);
double oldTotalWidth = fTimeGraphPane.getLayoutBounds().getWidth();
double newTotalWidth = timestampToPaneXPos(fullTimeGraphRange.getEndTime()) - timestampToPaneXPos(fullTimeGraphRange.getStartTime());
if (newTotalWidth < 1.0) {
// FIXME
return;
}
double newValue;
if (newVisibleRange.getStartTime() == fullTimeGraphRange.getStartTime()) {
newValue = fTimeGraphScrollPane.getHmin();
} else if (newVisibleRange.getEndTime() == fullTimeGraphRange.getEndTime()) {
newValue = fTimeGraphScrollPane.getHmax();
} else {
/*
* The "hvalue" is in reference to the beginning of the pane, not
* the middle point as one could think.
*
* Also note that the "scrollable distance" is not simply
* "timeGraphTotalWidth", it's
* "timeGraphTotalWidth - timeGraphVisibleWidth". The view does not
* allow scrolling the start and end edges up to the middle point
* for example.
*
* See http://stackoverflow.com/a/23518314/4227853 for a great
* explanation.
*/
double startPos = timestampToPaneXPos(newVisibleRange.getStartTime());
newValue = startPos / (newTotalWidth - timeGraphVisibleWidth);
}
fHScrollListenerStatus.disable();
try {
/*
* If the zoom level changed, resize the pane and relocate its
* current contents. That way the "intermediate" display before the
* next repaint will continue showing correct data.
*/
if (Math.abs(newTotalWidth - oldTotalWidth) > 0.5) {
/* Resize/reposition the state rectangles */
double factor = (newTotalWidth / oldTotalWidth);
fStateLayer.getRenderedStateRectangles().forEach(rect -> {
rect.setLayoutX(rect.getLayoutX() * factor);
rect.setWidth(rect.getWidth() * factor);
});
/* Reposition the text labels (don't stretch them!) */
fStateLayer.getRenderedStateLabels().forEach(text -> {
text.setX(text.getX() * factor);
});
/* Reposition the arrows */
fArrowLayer.getRenderedArrows().forEach(arrow -> {
arrow.setStartX(arrow.getStartX() * factor);
arrow.setEndX(arrow.getEndX() * factor);
});
/* Reposition the drawn events */
fDrawnEventLayer.getRenderedEvents().forEach(event -> {
/*
* Drawn events use the "translate" properties to define
* their position.
*/
event.setTranslateX(event.getTranslateX() * factor);
});
/*
* Resize the pane itself. Remember min/max are bound to the
* "pref" width, so this will change the actual size right away.
*/
fTimeGraphPane.setPrefWidth(newTotalWidth);
/*
* Since we changed the size of a child of the scrollpane, it's
* important to call layout() on it before setHvalue(). If we
* don't, the setHvalue() will apply to the old layout, and the
* upcoming pulse will simply revert our changes.
*/
fTimeGraphScrollPane.layout();
}
fTimeGraphScrollPane.setHvalue(newValue);
} finally {
fHScrollListenerStatus.enable();
}
/*
* Redraw the current selection, as it may have moved if we changed the
* size of the pane.
*/
redrawSelection();
}
use of com.efficios.jabberwocky.common.TimeRange in project lttng-scope by lttng.
the class TimeGraphWidget method paintArea.
/**
* Paint the specified view area.
*
* @param windowRange
* The horizontal position where the visible window currently is
* @param verticalPos
* The vertical position where the visible window currently is
* @param movedHorizontally
* If we have moved horizontally since the last redraw. May be
* used to skip some operations. If you are not sure say "true".
* @param movedVertically
* If we have moved vertically since the last redraw. May be used
* to skip some operations. If you are not sure say "true".
* @param taskSeqNb
* The sequence number of this task, used for logging only
*/
void paintArea(TimeRange windowRange, VerticalPosition verticalPos, boolean movedHorizontally, boolean movedVertically, long taskSeqNb) {
final TimeRange fullTimeGraphRange = getViewContext().getCurrentProjectFullRange();
/*
* Request the needed renders and prepare the corresponding UI objects.
* We may ask for some padding on each side, clamped by the trace's
* start and end.
*/
final long timeRangePadding = Math.round(windowRange.getDuration() * getDebugOptions().renderRangePadding.get());
final long renderingStartTime = Math.max(fullTimeGraphRange.getStartTime(), windowRange.getStartTime() - timeRangePadding);
final long renderingEndTime = Math.min(fullTimeGraphRange.getEndTime(), windowRange.getEndTime() + timeRangePadding);
final TimeRange renderingRange = TimeRange.of(renderingStartTime, renderingEndTime);
/*
* Start a new repaint, display the "loading" overlay. The next
* paint task to finish will put it back to non-visible.
*/
if (getDebugOptions().isLoadingOverlayEnabled.get()) {
fTimeGraphLoadingOverlay.fadeIn();
}
JabberwockyTask<Void> task = new JabberwockyTask<>("Updating Timegraph " + getName(), it -> {
// $NON-NLS-1$
LOGGER.finer(() -> "Starting paint task #" + taskSeqNb);
ITimeGraphModelProvider modelProvider = getControl().getRenderProvider();
TimeGraphTreeRender treeRender = modelProvider.getTreeRender();
if (it.isCancelled()) {
return null;
}
/* Prepare the tree part, if needed */
if (!treeRender.equals(fLatestTreeRender)) {
fLatestTreeRender = treeRender;
fTreeArea.updateTreeContents(treeRender);
}
if (it.isCancelled()) {
return null;
}
/* Paint the background. It's very quick so we can do it every time. */
fBackgroundLayer.drawContents(treeRender, renderingRange, verticalPos, it);
/*
* The state rectangles should be redrawn as soon as we move,
* either horizontally or vertically.
*/
fStateLayer.setWindowRange(windowRange);
fStateLayer.drawContents(treeRender, renderingRange, verticalPos, it);
if (it.isCancelled()) {
return null;
}
/*
* Arrows and drawn events are drawn for the full vertical
* range. Only refetch/repaint them if we moved horizontally.
*/
if (movedHorizontally) {
fArrowLayer.drawContents(treeRender, renderingRange, verticalPos, it);
fDrawnEventLayer.drawContents(treeRender, renderingRange, verticalPos, it);
}
if (it.isCancelled()) {
return null;
}
/* Painting is finished, turn off the loading overlay */
Platform.runLater(() -> {
// $NON-NLS-1$
LOGGER.finest(() -> "fading out overlay");
fTimeGraphLoadingOverlay.fadeOut();
if (fRepaintLatch != null) {
fRepaintLatch.countDown();
}
});
return null;
});
// $NON-NLS-1$
LOGGER.finer(() -> "Queueing task #" + taskSeqNb);
/*
* Attach a listener to the task to receive exceptions thrown within the
* task.
*/
task.exceptionProperty().addListener((obs, oldVal, newVal) -> {
if (newVal != null) {
newVal.printStackTrace();
}
});
fTaskExecutor.schedule(task);
}
use of com.efficios.jabberwocky.common.TimeRange in project lttng-scope by lttng.
the class TimeGraphWidgetSeekTest method testSeekVisibleRange.
private void testSeekVisibleRange(long startTime, long endTime) {
TimeRange range = TimeRange.of(startTime, endTime);
seekVisibleRange(range);
verifyVisibleRange(range);
}
Aggregations