overlayModal composites a modal on top of a background, centering the modal.
(background, modal string, screenWidth, screenHeight int)
| 525 | |
| 526 | // overlayModal composites a modal on top of a background, centering the modal. |
| 527 | func overlayModal(background, modal string, screenWidth, screenHeight int) string { |
| 528 | bgLines := strings.Split(background, "\n") |
| 529 | modalLines := strings.Split(modal, "\n") |
| 530 | |
| 531 | // Measure modal dimensions |
| 532 | modalHeight := len(modalLines) |
| 533 | modalWidth := 0 |
| 534 | for _, line := range modalLines { |
| 535 | w := lipgloss.Width(line) |
| 536 | if w > modalWidth { |
| 537 | modalWidth = w |
| 538 | } |
| 539 | } |
| 540 | |
| 541 | // Calculate centering offsets |
| 542 | offsetY := (screenHeight - modalHeight) / 2 |
| 543 | offsetX := (screenWidth - modalWidth) / 2 |
| 544 | if offsetY < 0 { |
| 545 | offsetY = 0 |
| 546 | } |
| 547 | if offsetX < 0 { |
| 548 | offsetX = 0 |
| 549 | } |
| 550 | |
| 551 | // Pad background to full screen height |
| 552 | for len(bgLines) < screenHeight { |
| 553 | bgLines = append(bgLines, strings.Repeat(" ", screenWidth)) |
| 554 | } |
| 555 | |
| 556 | // Overlay modal lines onto background |
| 557 | for i, mLine := range modalLines { |
| 558 | bgIdx := offsetY + i |
| 559 | if bgIdx >= len(bgLines) { |
| 560 | break |
| 561 | } |
| 562 | |
| 563 | mWidth := lipgloss.Width(mLine) |
| 564 | if mWidth == 0 { |
| 565 | continue |
| 566 | } |
| 567 | |
| 568 | bgLine := bgLines[bgIdx] |
| 569 | |
| 570 | // Build: bg prefix (ANSI-aware) + modal line + bg suffix (ANSI-aware) |
| 571 | prefix := ansiTruncate(bgLine, offsetX) |
| 572 | suffix := ansiSkip(bgLine, offsetX+mWidth) |
| 573 | |
| 574 | bgLines[bgIdx] = prefix + mLine + suffix |
| 575 | } |
| 576 | |
| 577 | return strings.Join(bgLines[:screenHeight], "\n") |
| 578 | } |
| 579 | |
| 580 | // centerModal centers a modal string on the screen. |
| 581 | func centerModal(modal string, screenWidth, screenHeight int) string { |
no test coverage detected