in flutter-idea/src/io/flutter/editor/InlinePreviewViewController.java [91:209]
public void computeScreenshotBounds() {
final Rectangle previousScreenshotBounds = screenshotBounds;
screenshotBounds = null;
maxHeight = Math.round(PREVIEW_MAX_HEIGHT * 0.16f);
final WidgetIndentGuideDescriptor descriptor = getDescriptor();
final int lineHeight = getEditor() != null ? getEditor().getLineHeight() : defaultLineHeight;
extraHeight = descriptor != null && screenshot != null ? lineHeight : 0;
final Rectangle visibleRect = this.visibleRect;
if (visibleRect == null) {
return;
}
if (descriptor == null) {
// Special case to float in the bottom right corner.
final Screenshot latestScreenshot = getScreenshotNow();
int previewWidth = Math.round(PREVIEW_MAX_WIDTH * previewWidthScale);
int previewHeight = Math.round((PREVIEW_MAX_HEIGHT * 0.16f) * previewWidthScale);
if (latestScreenshot != null) {
previewWidth = (int)(latestScreenshot.image.getWidth() / getDPI());
previewHeight = (int)(latestScreenshot.image.getHeight() / getDPI());
}
final int previewStartX = Math.max(0, visibleRect.x + visibleRect.width - previewWidth - PREVIEW_PADDING_X);
previewHeight = Math.min(previewHeight, visibleRect.height);
maxHeight = visibleRect.height;
final int previewStartY = Math.max(visibleRect.y, visibleRect.y + visibleRect.height - previewHeight);
screenshotBounds = new Rectangle(previewStartX, previewStartY, previewWidth, previewHeight);
return;
}
final TextRange marker = getData().getMarker();
if (marker == null) return;
final int startOffset = marker.getStartOffset();
final Document doc = getData().document;
final int textLength = doc.getTextLength();
if (startOffset >= textLength) return;
final int endOffset = Math.min(marker.getEndOffset(), textLength);
int off;
final int startLine = doc.getLineNumber(startOffset);
final int widgetOffset = getDescriptor().widget.getGuideOffset();
final int widgetLine = doc.getLineNumber(widgetOffset);
final int lineEndOffset = doc.getLineEndOffset(widgetLine);
// Request a thumbnail and render it in the space available.
VisualPosition visualPosition = getEditor().offsetToVisualPosition(lineEndOffset); // e
visualPosition = new VisualPosition(Math.max(visualPosition.line, 0), 81);
final Point start = getEditor().visualPositionToXY(visualPosition);
final Point endz = offsetToPoint(endOffset);
final int endY = endz.y;
final int visibleEndX = visibleRect.x + visibleRect.width;
final int width = Math.max(0, visibleEndX - 20 - start.x);
final int height = Math.max(0, endY - start.y);
int previewStartY = start.y;
int previewStartX = start.x;
final int visibleStart = visibleRect.y;
final int visibleEnd = (int)visibleRect.getMaxY();
// Add extra room for the descriptor.
final Screenshot latestScreenshot = getScreenshotNow();
int previewWidth = PREVIEW_MAX_WIDTH;
int previewHeight = PREVIEW_MAX_HEIGHT / 6;
if (latestScreenshot != null) {
previewWidth = (int)(latestScreenshot.image.getWidth() / getDPI());
previewHeight = (int)(latestScreenshot.image.getHeight() / getDPI());
}
previewStartX = Math.max(previewStartX, visibleEndX - previewWidth - PREVIEW_PADDING_X);
previewHeight += extraHeight;
previewHeight = Math.min(previewHeight, height);
maxHeight = endz.y - start.y;
if (popupActive()) {
// Keep the bounds sticky maintining the same lastScreenshotBoundsWindow.
screenshotBounds = new Rectangle(lastScreenshotBoundsWindow);
screenshotBounds.translate(visibleRect.x, visibleRect.y);
}
else {
boolean lockUpdate = false;
if (isVisiblityLocked()) {
// TODO(jacobr): also need to keep sticky if there is some minor scrolling
if (previousScreenshotBounds != null && visibleRect.contains(previousScreenshotBounds)) {
screenshotBounds = new Rectangle(previousScreenshotBounds);
// Fixup if the screenshot changed
if (previewWidth != screenshotBounds.width) {
screenshotBounds.x += screenshotBounds.width - previewWidth;
screenshotBounds.width = previewWidth;
}
screenshotBounds.height = previewHeight;
// TODO(jacobr): refactor this code so there is less duplication.
lastScreenshotBoundsWindow = new Rectangle(screenshotBounds);
lastScreenshotBoundsWindow.translate(-visibleRect.x, -visibleRect.y);
lockUpdate = true;
}
}
if (!lockUpdate) {
lastLockedRectangle = null;
if (start.y <= visibleEnd && endY >= visibleStart) {
if (visibleStart > previewStartY) {
previewStartY = Math.max(previewStartY, visibleStart);
previewStartY = Math.min(previewStartY, Math.min(endY - previewHeight, visibleEnd - previewHeight));
}
screenshotBounds = new Rectangle(previewStartX, previewStartY, previewWidth, previewHeight);
lastScreenshotBoundsWindow = new Rectangle(screenshotBounds);
lastScreenshotBoundsWindow.translate(-visibleRect.x, -visibleRect.y);
}
}
}
if (popupActive()) {
lastLockedRectangle = new Rectangle(visibleRect);
}
}