/**
 * RelatedTaskViewer - Related task cell renderer (Canvas implementation)
 * Displays the first related task's configured display fields.
 *
 * Layout modes:
 *   - Single-line (default): task name | thumbnails | "label: value" pairs — all horizontal, vertically centered
 *   - Multi-line (when row is expanded by nested columns): one field per line, vertically stacked
 */
import type { CellViewer, ViewerRenderContext, RelatedTaskViewerData } from './types';
declare class RelatedTaskViewer implements CellViewer<RelatedTaskViewerData> {
    readonly type = "related-task";
    private imageManager;
    /** Track failed image URLs to avoid retrying */
    private failedImages;
    private _sm;
    private get TEXT_COLOR();
    private get LABEL_COLOR();
    private get EMPTY_TEXT_COLOR();
    private get DASHED_BORDER_COLOR();
    /** Color for trailing "..." indicating overflow content — uses link/brand color so users notice the cell has more content. */
    private get OVERFLOW_HINT_COLOR();
    constructor();
    /**
     * Calculate thumbnail height for single-line mode.
     * Max height = cell height - top/bottom padding (4px each).
     */
    private getSingleLineThumbnailHeight;
    /**
     * Calculate thumbnail width for a given image, maintaining aspect ratio.
     * If no image is cached yet, returns thumbHeight (square placeholder).
     */
    private getThumbnailWidth;
    /**
     * Draw an image within the given area according to the specified fit mode.
     * Mirrors the logic in FileViewer.drawPreviewImage and ImageViewer.drawImageWithFit.
     */
    private drawImageWithFit;
    /**
     * Draw the related task cell content
     */
    draw(context: ViewerRenderContext, data: RelatedTaskViewerData): void;
    private drawSingleLine;
    /**
     * Single file-type field branch: draws label + thumbnails.
     * Each thumbnail keeps its own aspect ratio (width = baseH × ratio, no per-image cap) and is laid out
     * left-to-right; trailing thumbnails are dropped (and "..." shown) when remaining space cannot fit the
     * next thumbnail at the minimum drawable width. When the total width still exceeds the available area
     * after dropping, all kept thumbnails are uniformly height-scaled so they stay vertically aligned.
     */
    private drawSingleFileFieldLine;
    /**
     * Compute thumbnail layout for "single file-type field" mode (also reused by inline / multi-line
     * thumbnail rendering).
     *
     * Algorithm (Plan B — per-thumbnail independent width, with per-image MAX cap):
     *   1. Each thumbnail's natural width = baseH × aspectRatio, then capped at MAX_THUMBNAIL_WIDTH
     *      so a single panorama-style image cannot dominate the row. The row height stays at baseH;
     *      capped wide images are rendered into a baseH × MAX box with `contain` fit so they're
     *      shown letterboxed instead of distorted.
     *   2. Walk thumbnails left-to-right, accumulating width + THUMBNAIL_GAP. The first thumbnail
     *      whose remaining space cannot fit even MIN_THUMBNAIL_WIDTH is dropped together with all
     *      subsequent ones; the caller draws a trailing "..." indicator.
     *   3. If the kept thumbnails' total width still exceeds availableWidth (e.g. one extreme image
     *      alone can't fit), apply a uniform height-scale so they all shrink proportionally while
     *      staying vertically aligned. Re-check MIN_THUMBNAIL_WIDTH after scaling and drop tail
     *      one-by-one if any kept item falls below the minimum (n === 1 is always accepted to keep
     *      at least one image visible).
     *
     * Compared to the previous algorithm, a single overly-wide thumbnail no longer compresses the
     * entire row, so unrelated narrow thumbnails won't be silently dropped.
     */
    private computeSingleFileFieldLayout;
    /**
     * Draw a single inline thumbnail at the given position (for single-line mode, multi-field branch).
     * Reuses computeSingleFileFieldLayout so behavior matches the single-file-field branch:
     *   - All thumbnails proportionally scale into available width
     *   - Trailing thumbnails dropped only when scaled width < MIN_THUMBNAIL_WIDTH
     *   - When n === 1, accepts whatever width to keep at least one image visible
     * @returns The X position after the thumbnail(s) and whether any thumbnails were dropped
     */
    private drawInlineThumbnail;
    private drawMultiLine;
    /**
     * Draw empty placeholder — consistent with other viewers
     */
    private drawEmptyPlaceholder;
    /**
     * Draw the deliverable acceptance mark badge (bottom-right circle) on a thumbnail.
     * Aligned with FileViewer.drawMarkIcon / ImageViewer.drawMarkIcon:
     * - ah-icon_finish1: green circle + white check (已验收)
     * - ah-icon_help2: orange circle + white question mark (待验收)
     *
     * Only invoked when the related-task display field's fileData item carries a `mark`
     * (the business layer gates it by 被引用字段.showAcceptanceRemind && 节点关联任务列.isAcceptanceRemind).
     */
    private drawFileMark;
    private drawMarkIcon;
    /**
     * Draw a file status/format icon when coverUrl is not available.
     * Uses the same getIconByFileStatus logic as FileViewer for visual consistency.
     */
    private drawFileStatusIcon;
    /**
     * Draw a dashed rectangle placeholder for unloaded/missing images
     */
    private drawDashedPlaceholder;
    /**
     * Draw the trailing overflow-indicator ellipsis with a cell-colored background block.
     *
     * The background uses `context.fillColor` so it always matches the cell's actual
     * fill (hover, selection, highlight row/cell, upstream/match colors, etc.) — there
     * is no hard-coded color and no need for hover-only logic. The block extends to the
     * full cell height (top..bottom) so it visually "belongs" to the cell, and is wider
     * than the ellipsis text by `bgPadX` on the left so it can occlude the trailing edge
     * of any thumbnail/text drawn earlier.
     *
     * Drawn after thumbnails/text but before any post-decorations, this guarantees the
     * ellipsis is never visually mixed with overflowing image content.
     */
    private drawOverflowEllipsisWithBg;
    /**
     * Truncate text to fit within maxWidth, appending ellipsis if needed
     */
    private truncateText;
    /**
     * Truncate text to fit within maxWidth WITHOUT appending an ellipsis.
     * Used when the caller intends to draw a separate trailing overflow indicator.
     * Returns the longest prefix whose rendered width ≤ maxWidth.
     * Returns '' if maxWidth ≤ 0 or even one character cannot fit.
     */
    private truncateTextNoEllipsis;
    /**
     * Draw a label that is character-truncated to fit `availableWidth` and never lets
     * the cell go visually empty: if not even one character fits, the caller should
     * still rely on the trailing overflow ellipsis to indicate "there is content here".
     *
     * Returns the X position right after the drawn (possibly truncated) label.
     * Sets `wasTruncated` via the return tuple so caller can decide whether to draw a
     * trailing overflow ellipsis.
     */
    private drawTruncatedLabel;
    /**
     * Handle click events on the cell.
     * Detects clicks on file thumbnails and triggers onFileGoToDetail callback.
     */
    onClick(context: ViewerRenderContext, data: RelatedTaskViewerData, localX: number, localY: number): boolean;
    /**
     * Get cursor style for hover — show pointer on file thumbnails
     */
    getHitArea(context: ViewerRenderContext, data: RelatedTaskViewerData, localX: number, localY: number): string | null;
    private calculateSingleLineThumbnailAreas;
    private calculateMultiLineThumbnailAreas;
}
export default RelatedTaskViewer;
