public void computeScreenshotBounds()

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);
    }
  }