Class: Tui::Line
- Inherits:
-
Object
- Object
- Tui::Line
- Defined in:
- lib/tui.rb
Instance Attribute Summary collapse
-
#background ⇒ Object
Returns the value of attribute background.
-
#truncate ⇒ Object
Returns the value of attribute truncate.
Instance Method Summary collapse
- #center ⇒ Object
- #cursor_column(input_field, width) ⇒ Object
- #has_input? ⇒ Boolean
-
#initialize(screen, background:, truncate: true) ⇒ Line
constructor
A new instance of Line.
- #left ⇒ Object
- #mark_has_input(prefix_width) ⇒ Object
- #render(io, width) ⇒ Object
- #render_no_newline(io, width) ⇒ Object
- #right ⇒ Object
- #write ⇒ Object
Constructor Details
#initialize(screen, background:, truncate: true) ⇒ Line
Returns a new instance of Line.
489 490 491 492 493 494 495 496 497 498 |
# File 'lib/tui.rb', line 489 def initialize(screen, background:, truncate: true) @screen = screen @background = background @truncate = truncate @left = SegmentWriter.new(z_index: 1) @center = nil # Lazy - only created when accessed (z_index: 2, renders on top) @right = nil # Lazy - only created when accessed (z_index: 0) @has_input = false @input_prefix_width = 0 end |
Instance Attribute Details
#background ⇒ Object
Returns the value of attribute background.
487 488 489 |
# File 'lib/tui.rb', line 487 def background @background end |
#truncate ⇒ Object
Returns the value of attribute truncate.
487 488 489 |
# File 'lib/tui.rb', line 487 def truncate @truncate end |
Instance Method Details
#center ⇒ Object
508 509 510 |
# File 'lib/tui.rb', line 508 def center @center ||= SegmentWriter.new(z_index: 2) end |
#cursor_column(input_field, width) ⇒ Object
525 526 527 528 |
# File 'lib/tui.rb', line 525 def cursor_column(input_field, width) # Calculate cursor position: prefix + cursor position in input @input_prefix_width + input_field.cursor + 1 end |
#has_input? ⇒ Boolean
516 517 518 |
# File 'lib/tui.rb', line 516 def has_input? @has_input end |
#left ⇒ Object
504 505 506 |
# File 'lib/tui.rb', line 504 def left @left end |
#mark_has_input(prefix_width) ⇒ Object
520 521 522 523 |
# File 'lib/tui.rb', line 520 def mark_has_input(prefix_width) @has_input = true @input_prefix_width = prefix_width end |
#render(io, width) ⇒ Object
530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 |
# File 'lib/tui.rb', line 530 def render(io, width) buffer = String.new buffer << "\r" buffer << ANSI::CLEAR_EOL # Clear line before rendering to remove stale content # Set background if present buffer << background if background && Tui.colors_enabled? # Maximum content to avoid wrap (leave room for newline) max_content = width - 1 content_width = [width, 1].max left_text = @left.to_s(width: content_width) center_text = @center ? @center.to_s(width: content_width) : "" right_text = @right ? @right.to_s(width: content_width) : "" # Truncate left to fit line left_text = Metrics.truncate(left_text, max_content) if @truncate && !left_text.empty? left_width = left_text.empty? ? 0 : Metrics.visible_width(left_text) # Truncate center text to available space (never wrap) unless center_text.empty? max_center = max_content - left_width - 4 if max_center > 0 center_text = Metrics.truncate(center_text, max_center) else center_text = "" end end center_width = center_text.empty? ? 0 : Metrics.visible_width(center_text) # Calculate available space for right (need at least 1 space gap after left/center) used_by_left_center = left_width + center_width + (center_width > 0 ? 2 : 0) available_for_right = max_content - used_by_left_center - 1 # -1 for mandatory gap # Truncate right from the LEFT if needed (show trailing portion) right_width = 0 unless right_text.empty? right_width = Metrics.visible_width(right_text) if available_for_right <= 0 right_text = "" right_width = 0 elsif right_width > available_for_right # Skip leading characters, keep trailing portion right_text = Metrics.truncate_from_start(right_text, available_for_right) right_width = Metrics.visible_width(right_text) end end # Calculate positions center_col = center_text.empty? ? 0 : [(max_content - center_width) / 2, left_width + 1].max right_col = right_text.empty? ? max_content : (max_content - right_width) # Write left content buffer << left_text unless left_text.empty? current_pos = left_width # Write centered content if present unless center_text.empty? gap_to_center = center_col - current_pos buffer << (" " * gap_to_center) if gap_to_center > 0 buffer << center_text current_pos = center_col + center_width end # Fill gap to right content (or end of line) fill_end = right_text.empty? ? max_content : right_col gap = fill_end - current_pos buffer << (" " * gap) if gap > 0 # Write right content if present unless right_text.empty? buffer << right_text buffer << ANSI::RESET_FG end buffer << ANSI::RESET buffer << "\n" io.write(buffer) end |
#render_no_newline(io, width) ⇒ Object
612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 |
# File 'lib/tui.rb', line 612 def render_no_newline(io, width) buffer = String.new buffer << "\r" buffer << ANSI::CLEAR_EOL buffer << background if background && Tui.colors_enabled? max_content = width - 1 content_width = [width, 1].max left_text = @left.to_s(width: content_width) center_text = @center ? @center.to_s(width: content_width) : "" right_text = @right ? @right.to_s(width: content_width) : "" # Truncate left to fit line left_text = Metrics.truncate(left_text, max_content) if @truncate && !left_text.empty? left_width = left_text.empty? ? 0 : Metrics.visible_width(left_text) # Truncate center text to available space (never wrap) unless center_text.empty? max_center = max_content - left_width - 4 if max_center > 0 center_text = Metrics.truncate(center_text, max_center) else center_text = "" end end center_width = center_text.empty? ? 0 : Metrics.visible_width(center_text) # Calculate available space for right (need at least 1 space gap) used_by_left_center = left_width + center_width + (center_width > 0 ? 2 : 0) available_for_right = max_content - used_by_left_center - 1 # Truncate right from the LEFT if needed (show trailing portion) right_width = 0 unless right_text.empty? right_width = Metrics.visible_width(right_text) if available_for_right <= 0 right_text = "" right_width = 0 elsif right_width > available_for_right right_text = Metrics.truncate_from_start(right_text, available_for_right) right_width = Metrics.visible_width(right_text) end end # Calculate positions center_col = center_text.empty? ? 0 : [(max_content - center_width) / 2, left_width + 1].max right_col = right_text.empty? ? max_content : (max_content - right_width) buffer << left_text unless left_text.empty? current_pos = left_width unless center_text.empty? gap_to_center = center_col - current_pos buffer << (" " * gap_to_center) if gap_to_center > 0 buffer << center_text current_pos = center_col + center_width end fill_end = right_text.empty? ? max_content : right_col gap = fill_end - current_pos buffer << (" " * gap) if gap > 0 unless right_text.empty? buffer << right_text buffer << ANSI::RESET_FG end buffer << ANSI::RESET # No newline at end io.write(buffer) end |
#right ⇒ Object
512 513 514 |
# File 'lib/tui.rb', line 512 def right @right ||= SegmentWriter.new(z_index: 0) end |
#write ⇒ Object
500 501 502 |
# File 'lib/tui.rb', line 500 def write @left end |