pub struct Utf8Char { /* private fields */ }
Expand description
Class to manage the terminal’s individual UTF-8 characters. Includes fg/bg color, attributes (BOLD, UNDERLINE..) This is a low-level “protected” class in the fltk library
Implementations§
Source§impl Utf8Char
impl Utf8Char
Sourcepub fn new(c: u8) -> Self
pub fn new(c: u8) -> Self
Construct a new Utf8Char
, single-byte only. This is really only useful for testing.
‘c’ must be “printable” ASCII in the range (0x20 <= c <= 0x7e).
Anything outside of that is silently ignored.
Allocated Utf8Char
will never be deleted.
Examples found in repository?
554fn mb_test4_cb(_choice: &mut fltk::menu::Choice, term: &mut Terminal) {
555 let sel_len = term.selection_text_len();
556 let sel = term.selection_text();
557
558 term.take_focus().unwrap();
559 term.reset_terminal();
560 // Test the Utf8Char primitive
561 let uc = Utf8Char::new(b'Q');
562 let uc1 = uc.text_utf8();
563 assert_eq!(&uc1, b"Q");
564 assert_eq!(&uc.attrib(), &Attrib::Normal);
565 assert_eq!(
566 &uc.charflags(),
567 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
568 );
569 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
570 assert_eq!(&uc.bgcolor(), &Color::TransparentBg);
571
572 let ring_rows = term.ring_rows();
573
574 term.take_focus().unwrap();
575 term.clear_history();
576 assert_eq!(term.history_use(), 0);
577
578 // Subtract row numbers, modulo `rows`
579 fn row_diff(rows: i32, a: i32, b: i32) -> i32 {
580 match a - b {
581 n if n < 0 => n + rows,
582 n => n,
583 }
584 }
585 // disp_srow is always 1 greater than hist_erow, modulo (ring_rows+1)
586 assert_eq!(row_diff(ring_rows, term.disp_srow(), term.hist_erow()), 1);
587 assert!(term.disp_srow() >= 0);
588 assert!(term.disp_erow() >= 0);
589 assert!(term.hist_srow() >= 0);
590 assert!(term.hist_erow() >= 0);
591 assert!(term.offset() >= 0);
592 assert!(term.disp_srow() <= ring_rows);
593 assert!(term.disp_erow() <= ring_rows);
594 assert!(term.hist_srow() <= ring_rows);
595 assert!(term.hist_erow() <= ring_rows);
596 assert!(term.offset() <= ring_rows);
597
598 assert_eq!(term.ring_srow(), 0);
599 assert_eq!(term.ring_erow(), ring_rows - 1);
600 assert_eq!(
601 row_diff(ring_rows, term.disp_erow(), term.disp_srow()) + 1,
602 term.display_rows()
603 );
604 assert_eq!(
605 row_diff(ring_rows, term.hist_erow(), term.hist_srow()) + 1,
606 term.history_rows()
607 );
608
609 assert_eq!(term.ring_erow(), term.ring_rows() - 1);
610 assert_eq!(term.ring_srow(), 0);
611
612 /// Local function to read back all rows from the display into a long string.
613 /// Does not include scrollback history.
614 /// Trims trailing blanks on each line
615 fn read_disp(term: &Terminal) -> String {
616 let rows = term.display_rows();
617 let mut text: Vec<u8> = Vec::with_capacity((rows * 64) as usize);
618 for row in 0..rows {
619 let r = term.u8c_disp_row(row).trim();
620 // Iterate through a row, accumulating [u8]
621 for c in r.iter() {
622 // Note: Sometimes utf-8 length is > 1
623 text.extend_from_slice(c.text_utf8());
624 }
625 text.extend_from_slice(b"\n");
626 }
627 // Return the result as a string
628 std::str::from_utf8(&text).unwrap().to_string()
629 }
630
631 term.clear();
632 term.append("Top line ↑ (up-arrow)");
633 term.set_text_attrib(Attrib::Underline);
634 term.append(" ");
635 term.set_text_attrib(Attrib::Normal);
636 term.append(" \n");
637 let mut text_out = read_disp(term);
638 // Trim trailing empty lines
639 text_out = text_out.trim_end_matches(&"\n").to_string();
640 // The two plain blanks at the end will be trimmed, the two underlined blanks will be retained.
641
642 assert_eq!(text_out, "Top line ↑ (up-arrow) ");
643 let r = term.u8c_disp_row(0);
644 assert_eq!(r.col(0).text_utf8(), b"T");
645 assert_eq!(r.col(10).text_utf8(), b"\xe2\x86\x91"); // UTF-8 up-arrow
646 assert_eq!(r.col(24).text_utf8(), b" "); // First blank after test text, NOT trimmed
647 let r = term.u8c_disp_row(1);
648 assert_eq!(r.col(0).text_utf8(), b" "); // Second row starts with blanks
649 assert_eq!(r.col(1).text_utf8(), b" "); // Second row is full of blanks
650
651 // Clear the screen again, then append test text, then read it back and compare
652 let test_text = "The wind was a torrent of darkness among the gusty trees.
653The moon was a ghostly galleon tossed upon cloudy seas.
654The road was a ribbon of moonlight over the purple moor,
655And the highwayman came riding—
656 Riding—riding—
657The highwayman came riding, up to the old inn-door.";
658
659 term.clear_history();
660 term.clear();
661 let bg_save = term.text_bg_color();
662 let fg_save = term.text_fg_color();
663 term.set_text_bg_color(Color::DarkBlue); // Set spooky colors
664 term.set_text_fg_color(Color::from_rgb(0x40, 0x40, 0xff));
665 term.append(test_text);
666 term.set_text_bg_color(bg_save);
667 term.set_text_fg_color(fg_save);
668
669 let mut text_out = read_disp(term);
670 // Trim trailing empty lines
671 text_out = text_out.trim_end_matches(&"\n").to_string();
672 assert_eq!(test_text, text_out);
673
674 assert_eq!(row_diff(ring_rows, term.disp_srow(), term.hist_erow()), 1);
675
676 assert_eq!(term.ring_srow(), 0);
677 assert_eq!(term.ring_erow(), ring_rows - 1);
678 assert_eq!(
679 row_diff(ring_rows, term.disp_erow(), term.disp_srow()) + 1,
680 term.display_rows()
681 );
682 assert_eq!(
683 row_diff(ring_rows, term.hist_erow(), term.hist_srow()) + 1,
684 term.history_rows()
685 );
686
687 term.append(&format!(
688 "\n\nScreen has {} rows of {} columns.\n",
689 term.display_rows(),
690 term.display_columns()
691 ));
692
693 term.append(&format!("Selection len: {sel_len}\nSelection: '{sel:?}'\n"));
694}
Sourcepub fn attr_bgcolor(&self, term: Option<&Terminal>) -> Color
pub fn attr_bgcolor(&self, term: Option<&Terminal>) -> Color
Return the actual displayed color of char u8c
possibly influenced by BOLD or DIM if the char is from Xterm.
BG color will be derived from the widget color if a widget is specified and the color is TransparentBg
,
and that won’t be influenced by charflag attributes.
Examples found in repository?
699fn mb_test5_cb(_choice: &mut fltk::menu::Choice, term: &mut Terminal) {
700 term.take_focus().unwrap();
701
702 // Test the attr_fg_color and attr_bg_color methods.
703 // Put a single character 'A' into the buffer and check it
704 term.clear(); // No reset_terminal(), just clear() to preserve the mouse selection for later
705 term.set_text_bg_color(Color::TransparentBg);
706 term.set_text_fg_color(Color::XtermWhite);
707 term.append("A");
708 let r = &term.u8c_disp_row(0);
709 let uc = r.col(0);
710 assert_eq!(uc.text_utf8(), b"A");
711 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
712 assert_eq!(&uc.attr_bgcolor(None), &Color::TransparentBg);
713 assert_eq!(&uc.attr_bgcolor(Some(term)), &Color::Black);
714 assert_eq!(&uc.attr_fgcolor(Some(term)), &Color::XtermWhite);
715 assert_eq!(&uc.attrib(), &Attrib::Normal);
716
717 // Put a short string "BCD" into the first line of the buffer, with fg color change after the 'B' and bold after 'C'
718 term.clear();
719 term.set_text_fg_color_xterm(XtermColor::White);
720 term.set_text_bg_color_xterm(XtermColor::Black);
721 assert_eq!(term.text_attrib(), Attrib::Normal);
722
723 assert!(term.ansi());
724 term.append("B\x1b[32mC\x1b[1mD\n");
725
726 let r = &term.u8c_disp_row(0);
727 let uc = r.col(0);
728 assert_eq!(uc.text_utf8(), b"B");
729 assert!(uc.is_char(b'B'));
730 assert!(!uc.is_char(b'A'));
731 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
732 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
733 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
734 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBlack);
735 assert_eq!(
736 &uc.charflags(),
737 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
738 );
739
740 let uc = r.col(1);
741 assert_eq!(uc.text_utf8(), b"C");
742 assert!(uc.is_char(b'C'));
743 assert_eq!(&uc.fgcolor(), &Color::XtermGreen);
744 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
745 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermGreen);
746 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBlack);
747 assert_eq!(
748 &uc.charflags(),
749 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
750 );
751
752 let uc = r.col(2);
753 assert_eq!(uc.text_utf8(), b"D");
754 assert!(uc.is_char(b'D'));
755 assert_eq!(&uc.fgcolor(), &Color::XtermGreen);
756 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
757 assert_eq!(&uc.attr_fgcolor(None), &Color::from_rgb(0x20, 0xf0, 0x20));
758 assert_eq!(&uc.attr_bgcolor(None), &Color::from_rgb(0x20, 0x20, 0x20));
759 assert_eq!(
760 &uc.attr_fgcolor(Some(term)),
761 &Color::from_rgb(0x20, 0xf0, 0x20)
762 );
763 assert_eq!(&uc.attr_bgcolor(None), &Color::from_rgb(0x20, 0x20, 0x20));
764 assert_eq!(
765 &uc.charflags(),
766 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
767 );
768
769 // Put a short string "BCDE" into the buffer, with fg color change after the 'B', bg change after 'C', and bold after 'D'
770 term.clear();
771 term.set_text_fg_color_xterm(XtermColor::White);
772 term.set_text_bg_color_xterm(XtermColor::Black);
773 term.set_text_attrib(Attrib::Normal);
774 assert_eq!(term.text_attrib(), Attrib::Normal);
775
776 assert!(term.ansi());
777 term.append("B\x1b[37mC\x1b[44mD\x1b[1mE\n");
778
779 let r = &term.u8c_disp_row(0);
780 let uc = r.col(0);
781 assert_eq!(uc.text_utf8(), b"B");
782 assert!(uc.is_char(b'B'));
783 assert!(!uc.is_char(b'A'));
784 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
785 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
786 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
787 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBlack);
788 assert_eq!(
789 &uc.charflags(),
790 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
791 );
792
793 let uc = r.col(1);
794 assert_eq!(uc.text_utf8(), b"C");
795 assert!(uc.is_char(b'C'));
796 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
797 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
798 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
799 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBlack);
800 assert_eq!(
801 &uc.charflags(),
802 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
803 );
804
805 let uc = r.col(2);
806 assert_eq!(uc.text_utf8(), b"D");
807 assert!(uc.is_char(b'D'));
808 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
809 assert_eq!(&uc.bgcolor(), &Color::XtermBgBlue);
810 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
811 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBgBlue);
812 assert_eq!(
813 &uc.charflags(),
814 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
815 );
816
817 let uc = r.col(3);
818 assert_eq!(uc.text_utf8(), b"E");
819 assert!(uc.is_char(b'E'));
820 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
821 assert_eq!(&uc.bgcolor(), &Color::XtermBgBlue);
822 assert_eq!(&uc.attr_fgcolor(None), &Color::from_hex(0xf0f0f0));
823 assert_eq!(&uc.attr_bgcolor(None), &Color::from_hex(0x2020e0));
824 assert_eq!(
825 &uc.charflags(),
826 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
827 );
828
829 // Test some miscellaneous Utf8 constants
830 assert_eq!(uc.length(), 1);
831 assert_eq!(uc.max_utf8(), 4);
832 assert_eq!(uc.pwidth(), 9.0);
833 assert_eq!(uc.pwidth_int(), 9);
834
835 term.set_text_fg_color_xterm(XtermColor::White);
836 term.set_text_bg_color_xterm(XtermColor::Black);
837 term.clear();
838 term.set_text_attrib(Attrib::Normal);
839
840 // Mouse selection functions
841 term.append(&format!("Mouse selection: {:?}\n", &term.get_selection()));
842 term.clear_mouse_selection();
843 assert_eq!(term.get_selection(), None);
844
845 // Play with cursor position
846 term.append("0123456789\n"); // Set up test pattern
847 term.append("ABCDEFGHIJ\n");
848 term.append("abcdefghij\n");
849
850 term.set_cursor_row(1);
851 assert_eq!(term.cursor_row(), 1);
852 term.set_cursor_col(1);
853 assert_eq!(term.cursor_col(), 1);
854 assert_eq!(term.u8c_cursor().text_utf8(), b"1");
855
856 term.append("----"); // Overwrites text at cursor and moves cursor forward
857 assert_eq!(term.cursor_row(), 1);
858 assert_eq!(term.cursor_col(), 5);
859 assert_eq!(term.u8c_cursor().text_utf8(), b"5");
860 term.set_cursor_col(1);
861 assert_eq!(term.u8c_cursor().text_utf8(), b"-"); // Overwritten text
862
863 term.cursor_up(1, false);
864 assert_eq!(term.cursor_row(), 0);
865 assert_eq!(term.cursor_col(), 1);
866 assert_eq!(term.u8c_cursor().text_utf8(), b"o");
867
868 // Hit top of screen, so nothing happens
869 term.cursor_up(1, false);
870 assert_eq!(term.cursor_row(), 0);
871 assert_eq!(term.cursor_col(), 1);
872 assert_eq!(term.u8c_cursor().text_utf8(), b"o");
873
874 // Hit top of screen with scroll enabled. A blank line from history is scrolled in.
875 term.cursor_up(1, true);
876 assert_eq!(term.cursor_row(), 0);
877 assert_eq!(term.cursor_col(), 1);
878 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
879
880 // Go back down to the overwritten text
881 term.cursor_down(2, false);
882 assert_eq!(term.cursor_row(), 2);
883 assert_eq!(term.cursor_col(), 1);
884 assert_eq!(term.u8c_cursor().text_utf8(), b"-");
885
886 // Go right past the overwritten text
887 term.cursor_right(4, false);
888 assert_eq!(term.cursor_row(), 2);
889 assert_eq!(term.cursor_col(), 5);
890 assert_eq!(term.u8c_cursor().text_utf8(), b"5");
891
892 // Go left to the end of the overwritten text
893 term.cursor_left(1);
894 assert_eq!(term.cursor_row(), 2);
895 assert_eq!(term.cursor_col(), 4);
896 assert_eq!(term.u8c_cursor().text_utf8(), b"-");
897
898 // Scroll back down, removing the blank line at the top.
899 // Cursor stays in place, the text moves under it.
900 term.scroll(1);
901 assert_eq!(term.cursor_row(), 2);
902 assert_eq!(term.cursor_col(), 4);
903 assert_eq!(term.u8c_cursor().text_utf8(), b"E");
904
905 // Clear from here to end-of-line
906 term.clear_eol();
907 assert_eq!(term.cursor_row(), 2);
908 assert_eq!(term.cursor_col(), 4);
909 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
910
911 // Now clear from here to start-of-line. Cursor does not move.
912 term.clear_sol();
913 assert_eq!(term.cursor_row(), 2);
914 assert_eq!(term.cursor_col(), 4);
915 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
916 term.cursor_left(1);
917 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
918 term.set_cursor_col(0);
919 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
920
921 // Clear some lines
922 term.clear_line(1);
923 assert_eq!(term.cursor_row(), 2);
924 assert_eq!(term.cursor_col(), 0);
925 term.set_cursor_row(1);
926 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
927 term.set_cursor_row(3);
928 term.clear_cur_line();
929 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
930 assert_eq!(term.cursor_row(), 3);
931 assert_eq!(term.cursor_col(), 0);
932
933 term.append("Two lines above are intentionally left blank.\n");
934 assert_eq!(term.cursor_row(), 4);
935 assert_eq!(term.cursor_col(), 0);
936
937 // Set up the test pattern again, then play with insert/delete
938 term.append("0123456789\n");
939 term.append("ABCDEFGHIJ\n");
940 term.append("abcdefghij\n");
941 assert_eq!(term.cursor_row(), 7);
942
943 term.set_cursor_row(4);
944 term.set_cursor_col(4);
945 assert_eq!(term.u8c_cursor().text_utf8(), b"4");
946
947 term.insert_char('x', 5); // Push this row right 5 chars starting at col 4
948 assert_eq!(term.u8c_cursor().text_utf8(), b"x");
949 term.cursor_right(5, false);
950 assert_eq!(term.cursor_col(), 9);
951 assert_eq!(term.u8c_cursor().text_utf8(), b"4");
952
953 // Insert two blank rows above cursor. Cursor stays put.
954 term.insert_rows(2);
955 assert_eq!(term.cursor_row(), 4);
956 assert_eq!(term.cursor_col(), 9);
957 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
958 term.cursor_down(2, false); // Go down to find our text again
959 assert_eq!(term.u8c_cursor().text_utf8(), b"4");
960
961 // Go back to the beginning of the inserted 'x' characters and delete them.
962 term.cursor_left(5);
963 assert_eq!(term.u8c_cursor().text_utf8(), b"x");
964 term.delete_cur_chars(5);
965 assert_eq!(term.cursor_row(), 6);
966 assert_eq!(term.cursor_col(), 4);
967 assert_eq!(term.u8c_cursor().text_utf8(), b"4");
968
969 term.delete_chars(7, 2, 2); // Delete "CD" from the next row
970 term.cursor_down(1, false);
971 term.cursor_left(2);
972 assert_eq!(term.u8c_cursor().text_utf8(), b"E");
973
974 term.delete_rows(1); // Middle row of pattern is gone, cursor stays put
975 assert_eq!(term.u8c_cursor().text_utf8(), b"c");
976 term.cursor_up(1, false);
977 term.delete_rows(2); // Delete remains of test pattern
978
979 term.set_text_attrib(Attrib::Bold);
980 term.insert_char_eol('-', 3, 15, 20);
981 term.set_cursor_row(3);
982 term.set_cursor_col(15);
983 assert_eq!(term.u8c_cursor().text_utf8(), b"-"); // Check the insertion
984 assert_eq!(term.u8c_cursor().attrib(), Attrib::Bold);
985
986 term.set_text_attrib(Attrib::Italic);
987 term.append(" and all lines below");
988 term.set_text_attrib(Attrib::Normal);
989 term.cursor_down(1, false);
990
991 let mut hsb = term.hscrollbar();
992 let mut sb = term.scrollbar();
993 hsb.set_value(100.0);
994 assert_eq!(hsb.value(), 100.0);
995 sb.set_value(50.0);
996 assert_eq!(sb.value(), 50.0);
997 hsb.set_value(0.0);
998 assert_eq!(hsb.value(), 0.0);
999 sb.set_value(0.0);
1000 assert_eq!(sb.value(), 0.0);
1001}
Sourcepub fn attr_fgcolor(&self, term: Option<&Terminal>) -> Color
pub fn attr_fgcolor(&self, term: Option<&Terminal>) -> Color
Return the actual displayed fg color of char u8c
possibly influenced by BOLD or DIM if the char is from Xterm.
If a term
widget is specified (i.e. not None
), don’t let the color be
influenced by the attribute bits if it matches the term
widget’s own color()
.
Examples found in repository?
699fn mb_test5_cb(_choice: &mut fltk::menu::Choice, term: &mut Terminal) {
700 term.take_focus().unwrap();
701
702 // Test the attr_fg_color and attr_bg_color methods.
703 // Put a single character 'A' into the buffer and check it
704 term.clear(); // No reset_terminal(), just clear() to preserve the mouse selection for later
705 term.set_text_bg_color(Color::TransparentBg);
706 term.set_text_fg_color(Color::XtermWhite);
707 term.append("A");
708 let r = &term.u8c_disp_row(0);
709 let uc = r.col(0);
710 assert_eq!(uc.text_utf8(), b"A");
711 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
712 assert_eq!(&uc.attr_bgcolor(None), &Color::TransparentBg);
713 assert_eq!(&uc.attr_bgcolor(Some(term)), &Color::Black);
714 assert_eq!(&uc.attr_fgcolor(Some(term)), &Color::XtermWhite);
715 assert_eq!(&uc.attrib(), &Attrib::Normal);
716
717 // Put a short string "BCD" into the first line of the buffer, with fg color change after the 'B' and bold after 'C'
718 term.clear();
719 term.set_text_fg_color_xterm(XtermColor::White);
720 term.set_text_bg_color_xterm(XtermColor::Black);
721 assert_eq!(term.text_attrib(), Attrib::Normal);
722
723 assert!(term.ansi());
724 term.append("B\x1b[32mC\x1b[1mD\n");
725
726 let r = &term.u8c_disp_row(0);
727 let uc = r.col(0);
728 assert_eq!(uc.text_utf8(), b"B");
729 assert!(uc.is_char(b'B'));
730 assert!(!uc.is_char(b'A'));
731 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
732 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
733 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
734 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBlack);
735 assert_eq!(
736 &uc.charflags(),
737 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
738 );
739
740 let uc = r.col(1);
741 assert_eq!(uc.text_utf8(), b"C");
742 assert!(uc.is_char(b'C'));
743 assert_eq!(&uc.fgcolor(), &Color::XtermGreen);
744 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
745 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermGreen);
746 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBlack);
747 assert_eq!(
748 &uc.charflags(),
749 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
750 );
751
752 let uc = r.col(2);
753 assert_eq!(uc.text_utf8(), b"D");
754 assert!(uc.is_char(b'D'));
755 assert_eq!(&uc.fgcolor(), &Color::XtermGreen);
756 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
757 assert_eq!(&uc.attr_fgcolor(None), &Color::from_rgb(0x20, 0xf0, 0x20));
758 assert_eq!(&uc.attr_bgcolor(None), &Color::from_rgb(0x20, 0x20, 0x20));
759 assert_eq!(
760 &uc.attr_fgcolor(Some(term)),
761 &Color::from_rgb(0x20, 0xf0, 0x20)
762 );
763 assert_eq!(&uc.attr_bgcolor(None), &Color::from_rgb(0x20, 0x20, 0x20));
764 assert_eq!(
765 &uc.charflags(),
766 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
767 );
768
769 // Put a short string "BCDE" into the buffer, with fg color change after the 'B', bg change after 'C', and bold after 'D'
770 term.clear();
771 term.set_text_fg_color_xterm(XtermColor::White);
772 term.set_text_bg_color_xterm(XtermColor::Black);
773 term.set_text_attrib(Attrib::Normal);
774 assert_eq!(term.text_attrib(), Attrib::Normal);
775
776 assert!(term.ansi());
777 term.append("B\x1b[37mC\x1b[44mD\x1b[1mE\n");
778
779 let r = &term.u8c_disp_row(0);
780 let uc = r.col(0);
781 assert_eq!(uc.text_utf8(), b"B");
782 assert!(uc.is_char(b'B'));
783 assert!(!uc.is_char(b'A'));
784 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
785 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
786 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
787 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBlack);
788 assert_eq!(
789 &uc.charflags(),
790 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
791 );
792
793 let uc = r.col(1);
794 assert_eq!(uc.text_utf8(), b"C");
795 assert!(uc.is_char(b'C'));
796 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
797 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
798 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
799 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBlack);
800 assert_eq!(
801 &uc.charflags(),
802 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
803 );
804
805 let uc = r.col(2);
806 assert_eq!(uc.text_utf8(), b"D");
807 assert!(uc.is_char(b'D'));
808 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
809 assert_eq!(&uc.bgcolor(), &Color::XtermBgBlue);
810 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
811 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBgBlue);
812 assert_eq!(
813 &uc.charflags(),
814 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
815 );
816
817 let uc = r.col(3);
818 assert_eq!(uc.text_utf8(), b"E");
819 assert!(uc.is_char(b'E'));
820 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
821 assert_eq!(&uc.bgcolor(), &Color::XtermBgBlue);
822 assert_eq!(&uc.attr_fgcolor(None), &Color::from_hex(0xf0f0f0));
823 assert_eq!(&uc.attr_bgcolor(None), &Color::from_hex(0x2020e0));
824 assert_eq!(
825 &uc.charflags(),
826 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
827 );
828
829 // Test some miscellaneous Utf8 constants
830 assert_eq!(uc.length(), 1);
831 assert_eq!(uc.max_utf8(), 4);
832 assert_eq!(uc.pwidth(), 9.0);
833 assert_eq!(uc.pwidth_int(), 9);
834
835 term.set_text_fg_color_xterm(XtermColor::White);
836 term.set_text_bg_color_xterm(XtermColor::Black);
837 term.clear();
838 term.set_text_attrib(Attrib::Normal);
839
840 // Mouse selection functions
841 term.append(&format!("Mouse selection: {:?}\n", &term.get_selection()));
842 term.clear_mouse_selection();
843 assert_eq!(term.get_selection(), None);
844
845 // Play with cursor position
846 term.append("0123456789\n"); // Set up test pattern
847 term.append("ABCDEFGHIJ\n");
848 term.append("abcdefghij\n");
849
850 term.set_cursor_row(1);
851 assert_eq!(term.cursor_row(), 1);
852 term.set_cursor_col(1);
853 assert_eq!(term.cursor_col(), 1);
854 assert_eq!(term.u8c_cursor().text_utf8(), b"1");
855
856 term.append("----"); // Overwrites text at cursor and moves cursor forward
857 assert_eq!(term.cursor_row(), 1);
858 assert_eq!(term.cursor_col(), 5);
859 assert_eq!(term.u8c_cursor().text_utf8(), b"5");
860 term.set_cursor_col(1);
861 assert_eq!(term.u8c_cursor().text_utf8(), b"-"); // Overwritten text
862
863 term.cursor_up(1, false);
864 assert_eq!(term.cursor_row(), 0);
865 assert_eq!(term.cursor_col(), 1);
866 assert_eq!(term.u8c_cursor().text_utf8(), b"o");
867
868 // Hit top of screen, so nothing happens
869 term.cursor_up(1, false);
870 assert_eq!(term.cursor_row(), 0);
871 assert_eq!(term.cursor_col(), 1);
872 assert_eq!(term.u8c_cursor().text_utf8(), b"o");
873
874 // Hit top of screen with scroll enabled. A blank line from history is scrolled in.
875 term.cursor_up(1, true);
876 assert_eq!(term.cursor_row(), 0);
877 assert_eq!(term.cursor_col(), 1);
878 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
879
880 // Go back down to the overwritten text
881 term.cursor_down(2, false);
882 assert_eq!(term.cursor_row(), 2);
883 assert_eq!(term.cursor_col(), 1);
884 assert_eq!(term.u8c_cursor().text_utf8(), b"-");
885
886 // Go right past the overwritten text
887 term.cursor_right(4, false);
888 assert_eq!(term.cursor_row(), 2);
889 assert_eq!(term.cursor_col(), 5);
890 assert_eq!(term.u8c_cursor().text_utf8(), b"5");
891
892 // Go left to the end of the overwritten text
893 term.cursor_left(1);
894 assert_eq!(term.cursor_row(), 2);
895 assert_eq!(term.cursor_col(), 4);
896 assert_eq!(term.u8c_cursor().text_utf8(), b"-");
897
898 // Scroll back down, removing the blank line at the top.
899 // Cursor stays in place, the text moves under it.
900 term.scroll(1);
901 assert_eq!(term.cursor_row(), 2);
902 assert_eq!(term.cursor_col(), 4);
903 assert_eq!(term.u8c_cursor().text_utf8(), b"E");
904
905 // Clear from here to end-of-line
906 term.clear_eol();
907 assert_eq!(term.cursor_row(), 2);
908 assert_eq!(term.cursor_col(), 4);
909 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
910
911 // Now clear from here to start-of-line. Cursor does not move.
912 term.clear_sol();
913 assert_eq!(term.cursor_row(), 2);
914 assert_eq!(term.cursor_col(), 4);
915 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
916 term.cursor_left(1);
917 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
918 term.set_cursor_col(0);
919 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
920
921 // Clear some lines
922 term.clear_line(1);
923 assert_eq!(term.cursor_row(), 2);
924 assert_eq!(term.cursor_col(), 0);
925 term.set_cursor_row(1);
926 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
927 term.set_cursor_row(3);
928 term.clear_cur_line();
929 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
930 assert_eq!(term.cursor_row(), 3);
931 assert_eq!(term.cursor_col(), 0);
932
933 term.append("Two lines above are intentionally left blank.\n");
934 assert_eq!(term.cursor_row(), 4);
935 assert_eq!(term.cursor_col(), 0);
936
937 // Set up the test pattern again, then play with insert/delete
938 term.append("0123456789\n");
939 term.append("ABCDEFGHIJ\n");
940 term.append("abcdefghij\n");
941 assert_eq!(term.cursor_row(), 7);
942
943 term.set_cursor_row(4);
944 term.set_cursor_col(4);
945 assert_eq!(term.u8c_cursor().text_utf8(), b"4");
946
947 term.insert_char('x', 5); // Push this row right 5 chars starting at col 4
948 assert_eq!(term.u8c_cursor().text_utf8(), b"x");
949 term.cursor_right(5, false);
950 assert_eq!(term.cursor_col(), 9);
951 assert_eq!(term.u8c_cursor().text_utf8(), b"4");
952
953 // Insert two blank rows above cursor. Cursor stays put.
954 term.insert_rows(2);
955 assert_eq!(term.cursor_row(), 4);
956 assert_eq!(term.cursor_col(), 9);
957 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
958 term.cursor_down(2, false); // Go down to find our text again
959 assert_eq!(term.u8c_cursor().text_utf8(), b"4");
960
961 // Go back to the beginning of the inserted 'x' characters and delete them.
962 term.cursor_left(5);
963 assert_eq!(term.u8c_cursor().text_utf8(), b"x");
964 term.delete_cur_chars(5);
965 assert_eq!(term.cursor_row(), 6);
966 assert_eq!(term.cursor_col(), 4);
967 assert_eq!(term.u8c_cursor().text_utf8(), b"4");
968
969 term.delete_chars(7, 2, 2); // Delete "CD" from the next row
970 term.cursor_down(1, false);
971 term.cursor_left(2);
972 assert_eq!(term.u8c_cursor().text_utf8(), b"E");
973
974 term.delete_rows(1); // Middle row of pattern is gone, cursor stays put
975 assert_eq!(term.u8c_cursor().text_utf8(), b"c");
976 term.cursor_up(1, false);
977 term.delete_rows(2); // Delete remains of test pattern
978
979 term.set_text_attrib(Attrib::Bold);
980 term.insert_char_eol('-', 3, 15, 20);
981 term.set_cursor_row(3);
982 term.set_cursor_col(15);
983 assert_eq!(term.u8c_cursor().text_utf8(), b"-"); // Check the insertion
984 assert_eq!(term.u8c_cursor().attrib(), Attrib::Bold);
985
986 term.set_text_attrib(Attrib::Italic);
987 term.append(" and all lines below");
988 term.set_text_attrib(Attrib::Normal);
989 term.cursor_down(1, false);
990
991 let mut hsb = term.hscrollbar();
992 let mut sb = term.scrollbar();
993 hsb.set_value(100.0);
994 assert_eq!(hsb.value(), 100.0);
995 sb.set_value(50.0);
996 assert_eq!(sb.value(), 50.0);
997 hsb.set_value(0.0);
998 assert_eq!(hsb.value(), 0.0);
999 sb.set_value(0.0);
1000 assert_eq!(sb.value(), 0.0);
1001}
Sourcepub fn attrib(&self) -> Attrib
pub fn attrib(&self) -> Attrib
Return the attributes for this character.
Examples found in repository?
554fn mb_test4_cb(_choice: &mut fltk::menu::Choice, term: &mut Terminal) {
555 let sel_len = term.selection_text_len();
556 let sel = term.selection_text();
557
558 term.take_focus().unwrap();
559 term.reset_terminal();
560 // Test the Utf8Char primitive
561 let uc = Utf8Char::new(b'Q');
562 let uc1 = uc.text_utf8();
563 assert_eq!(&uc1, b"Q");
564 assert_eq!(&uc.attrib(), &Attrib::Normal);
565 assert_eq!(
566 &uc.charflags(),
567 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
568 );
569 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
570 assert_eq!(&uc.bgcolor(), &Color::TransparentBg);
571
572 let ring_rows = term.ring_rows();
573
574 term.take_focus().unwrap();
575 term.clear_history();
576 assert_eq!(term.history_use(), 0);
577
578 // Subtract row numbers, modulo `rows`
579 fn row_diff(rows: i32, a: i32, b: i32) -> i32 {
580 match a - b {
581 n if n < 0 => n + rows,
582 n => n,
583 }
584 }
585 // disp_srow is always 1 greater than hist_erow, modulo (ring_rows+1)
586 assert_eq!(row_diff(ring_rows, term.disp_srow(), term.hist_erow()), 1);
587 assert!(term.disp_srow() >= 0);
588 assert!(term.disp_erow() >= 0);
589 assert!(term.hist_srow() >= 0);
590 assert!(term.hist_erow() >= 0);
591 assert!(term.offset() >= 0);
592 assert!(term.disp_srow() <= ring_rows);
593 assert!(term.disp_erow() <= ring_rows);
594 assert!(term.hist_srow() <= ring_rows);
595 assert!(term.hist_erow() <= ring_rows);
596 assert!(term.offset() <= ring_rows);
597
598 assert_eq!(term.ring_srow(), 0);
599 assert_eq!(term.ring_erow(), ring_rows - 1);
600 assert_eq!(
601 row_diff(ring_rows, term.disp_erow(), term.disp_srow()) + 1,
602 term.display_rows()
603 );
604 assert_eq!(
605 row_diff(ring_rows, term.hist_erow(), term.hist_srow()) + 1,
606 term.history_rows()
607 );
608
609 assert_eq!(term.ring_erow(), term.ring_rows() - 1);
610 assert_eq!(term.ring_srow(), 0);
611
612 /// Local function to read back all rows from the display into a long string.
613 /// Does not include scrollback history.
614 /// Trims trailing blanks on each line
615 fn read_disp(term: &Terminal) -> String {
616 let rows = term.display_rows();
617 let mut text: Vec<u8> = Vec::with_capacity((rows * 64) as usize);
618 for row in 0..rows {
619 let r = term.u8c_disp_row(row).trim();
620 // Iterate through a row, accumulating [u8]
621 for c in r.iter() {
622 // Note: Sometimes utf-8 length is > 1
623 text.extend_from_slice(c.text_utf8());
624 }
625 text.extend_from_slice(b"\n");
626 }
627 // Return the result as a string
628 std::str::from_utf8(&text).unwrap().to_string()
629 }
630
631 term.clear();
632 term.append("Top line ↑ (up-arrow)");
633 term.set_text_attrib(Attrib::Underline);
634 term.append(" ");
635 term.set_text_attrib(Attrib::Normal);
636 term.append(" \n");
637 let mut text_out = read_disp(term);
638 // Trim trailing empty lines
639 text_out = text_out.trim_end_matches(&"\n").to_string();
640 // The two plain blanks at the end will be trimmed, the two underlined blanks will be retained.
641
642 assert_eq!(text_out, "Top line ↑ (up-arrow) ");
643 let r = term.u8c_disp_row(0);
644 assert_eq!(r.col(0).text_utf8(), b"T");
645 assert_eq!(r.col(10).text_utf8(), b"\xe2\x86\x91"); // UTF-8 up-arrow
646 assert_eq!(r.col(24).text_utf8(), b" "); // First blank after test text, NOT trimmed
647 let r = term.u8c_disp_row(1);
648 assert_eq!(r.col(0).text_utf8(), b" "); // Second row starts with blanks
649 assert_eq!(r.col(1).text_utf8(), b" "); // Second row is full of blanks
650
651 // Clear the screen again, then append test text, then read it back and compare
652 let test_text = "The wind was a torrent of darkness among the gusty trees.
653The moon was a ghostly galleon tossed upon cloudy seas.
654The road was a ribbon of moonlight over the purple moor,
655And the highwayman came riding—
656 Riding—riding—
657The highwayman came riding, up to the old inn-door.";
658
659 term.clear_history();
660 term.clear();
661 let bg_save = term.text_bg_color();
662 let fg_save = term.text_fg_color();
663 term.set_text_bg_color(Color::DarkBlue); // Set spooky colors
664 term.set_text_fg_color(Color::from_rgb(0x40, 0x40, 0xff));
665 term.append(test_text);
666 term.set_text_bg_color(bg_save);
667 term.set_text_fg_color(fg_save);
668
669 let mut text_out = read_disp(term);
670 // Trim trailing empty lines
671 text_out = text_out.trim_end_matches(&"\n").to_string();
672 assert_eq!(test_text, text_out);
673
674 assert_eq!(row_diff(ring_rows, term.disp_srow(), term.hist_erow()), 1);
675
676 assert_eq!(term.ring_srow(), 0);
677 assert_eq!(term.ring_erow(), ring_rows - 1);
678 assert_eq!(
679 row_diff(ring_rows, term.disp_erow(), term.disp_srow()) + 1,
680 term.display_rows()
681 );
682 assert_eq!(
683 row_diff(ring_rows, term.hist_erow(), term.hist_srow()) + 1,
684 term.history_rows()
685 );
686
687 term.append(&format!(
688 "\n\nScreen has {} rows of {} columns.\n",
689 term.display_rows(),
690 term.display_columns()
691 ));
692
693 term.append(&format!("Selection len: {sel_len}\nSelection: '{sel:?}'\n"));
694}
695
696//--------------------------------------------------------------------------------------
697/// Yet another set of tests for misc cursor functions and other stuff
698/// Note: these tests depend heavily on the low-level "protected" parts of the fltk library, which should be used with caution.
699fn mb_test5_cb(_choice: &mut fltk::menu::Choice, term: &mut Terminal) {
700 term.take_focus().unwrap();
701
702 // Test the attr_fg_color and attr_bg_color methods.
703 // Put a single character 'A' into the buffer and check it
704 term.clear(); // No reset_terminal(), just clear() to preserve the mouse selection for later
705 term.set_text_bg_color(Color::TransparentBg);
706 term.set_text_fg_color(Color::XtermWhite);
707 term.append("A");
708 let r = &term.u8c_disp_row(0);
709 let uc = r.col(0);
710 assert_eq!(uc.text_utf8(), b"A");
711 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
712 assert_eq!(&uc.attr_bgcolor(None), &Color::TransparentBg);
713 assert_eq!(&uc.attr_bgcolor(Some(term)), &Color::Black);
714 assert_eq!(&uc.attr_fgcolor(Some(term)), &Color::XtermWhite);
715 assert_eq!(&uc.attrib(), &Attrib::Normal);
716
717 // Put a short string "BCD" into the first line of the buffer, with fg color change after the 'B' and bold after 'C'
718 term.clear();
719 term.set_text_fg_color_xterm(XtermColor::White);
720 term.set_text_bg_color_xterm(XtermColor::Black);
721 assert_eq!(term.text_attrib(), Attrib::Normal);
722
723 assert!(term.ansi());
724 term.append("B\x1b[32mC\x1b[1mD\n");
725
726 let r = &term.u8c_disp_row(0);
727 let uc = r.col(0);
728 assert_eq!(uc.text_utf8(), b"B");
729 assert!(uc.is_char(b'B'));
730 assert!(!uc.is_char(b'A'));
731 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
732 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
733 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
734 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBlack);
735 assert_eq!(
736 &uc.charflags(),
737 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
738 );
739
740 let uc = r.col(1);
741 assert_eq!(uc.text_utf8(), b"C");
742 assert!(uc.is_char(b'C'));
743 assert_eq!(&uc.fgcolor(), &Color::XtermGreen);
744 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
745 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermGreen);
746 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBlack);
747 assert_eq!(
748 &uc.charflags(),
749 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
750 );
751
752 let uc = r.col(2);
753 assert_eq!(uc.text_utf8(), b"D");
754 assert!(uc.is_char(b'D'));
755 assert_eq!(&uc.fgcolor(), &Color::XtermGreen);
756 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
757 assert_eq!(&uc.attr_fgcolor(None), &Color::from_rgb(0x20, 0xf0, 0x20));
758 assert_eq!(&uc.attr_bgcolor(None), &Color::from_rgb(0x20, 0x20, 0x20));
759 assert_eq!(
760 &uc.attr_fgcolor(Some(term)),
761 &Color::from_rgb(0x20, 0xf0, 0x20)
762 );
763 assert_eq!(&uc.attr_bgcolor(None), &Color::from_rgb(0x20, 0x20, 0x20));
764 assert_eq!(
765 &uc.charflags(),
766 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
767 );
768
769 // Put a short string "BCDE" into the buffer, with fg color change after the 'B', bg change after 'C', and bold after 'D'
770 term.clear();
771 term.set_text_fg_color_xterm(XtermColor::White);
772 term.set_text_bg_color_xterm(XtermColor::Black);
773 term.set_text_attrib(Attrib::Normal);
774 assert_eq!(term.text_attrib(), Attrib::Normal);
775
776 assert!(term.ansi());
777 term.append("B\x1b[37mC\x1b[44mD\x1b[1mE\n");
778
779 let r = &term.u8c_disp_row(0);
780 let uc = r.col(0);
781 assert_eq!(uc.text_utf8(), b"B");
782 assert!(uc.is_char(b'B'));
783 assert!(!uc.is_char(b'A'));
784 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
785 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
786 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
787 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBlack);
788 assert_eq!(
789 &uc.charflags(),
790 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
791 );
792
793 let uc = r.col(1);
794 assert_eq!(uc.text_utf8(), b"C");
795 assert!(uc.is_char(b'C'));
796 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
797 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
798 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
799 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBlack);
800 assert_eq!(
801 &uc.charflags(),
802 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
803 );
804
805 let uc = r.col(2);
806 assert_eq!(uc.text_utf8(), b"D");
807 assert!(uc.is_char(b'D'));
808 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
809 assert_eq!(&uc.bgcolor(), &Color::XtermBgBlue);
810 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
811 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBgBlue);
812 assert_eq!(
813 &uc.charflags(),
814 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
815 );
816
817 let uc = r.col(3);
818 assert_eq!(uc.text_utf8(), b"E");
819 assert!(uc.is_char(b'E'));
820 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
821 assert_eq!(&uc.bgcolor(), &Color::XtermBgBlue);
822 assert_eq!(&uc.attr_fgcolor(None), &Color::from_hex(0xf0f0f0));
823 assert_eq!(&uc.attr_bgcolor(None), &Color::from_hex(0x2020e0));
824 assert_eq!(
825 &uc.charflags(),
826 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
827 );
828
829 // Test some miscellaneous Utf8 constants
830 assert_eq!(uc.length(), 1);
831 assert_eq!(uc.max_utf8(), 4);
832 assert_eq!(uc.pwidth(), 9.0);
833 assert_eq!(uc.pwidth_int(), 9);
834
835 term.set_text_fg_color_xterm(XtermColor::White);
836 term.set_text_bg_color_xterm(XtermColor::Black);
837 term.clear();
838 term.set_text_attrib(Attrib::Normal);
839
840 // Mouse selection functions
841 term.append(&format!("Mouse selection: {:?}\n", &term.get_selection()));
842 term.clear_mouse_selection();
843 assert_eq!(term.get_selection(), None);
844
845 // Play with cursor position
846 term.append("0123456789\n"); // Set up test pattern
847 term.append("ABCDEFGHIJ\n");
848 term.append("abcdefghij\n");
849
850 term.set_cursor_row(1);
851 assert_eq!(term.cursor_row(), 1);
852 term.set_cursor_col(1);
853 assert_eq!(term.cursor_col(), 1);
854 assert_eq!(term.u8c_cursor().text_utf8(), b"1");
855
856 term.append("----"); // Overwrites text at cursor and moves cursor forward
857 assert_eq!(term.cursor_row(), 1);
858 assert_eq!(term.cursor_col(), 5);
859 assert_eq!(term.u8c_cursor().text_utf8(), b"5");
860 term.set_cursor_col(1);
861 assert_eq!(term.u8c_cursor().text_utf8(), b"-"); // Overwritten text
862
863 term.cursor_up(1, false);
864 assert_eq!(term.cursor_row(), 0);
865 assert_eq!(term.cursor_col(), 1);
866 assert_eq!(term.u8c_cursor().text_utf8(), b"o");
867
868 // Hit top of screen, so nothing happens
869 term.cursor_up(1, false);
870 assert_eq!(term.cursor_row(), 0);
871 assert_eq!(term.cursor_col(), 1);
872 assert_eq!(term.u8c_cursor().text_utf8(), b"o");
873
874 // Hit top of screen with scroll enabled. A blank line from history is scrolled in.
875 term.cursor_up(1, true);
876 assert_eq!(term.cursor_row(), 0);
877 assert_eq!(term.cursor_col(), 1);
878 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
879
880 // Go back down to the overwritten text
881 term.cursor_down(2, false);
882 assert_eq!(term.cursor_row(), 2);
883 assert_eq!(term.cursor_col(), 1);
884 assert_eq!(term.u8c_cursor().text_utf8(), b"-");
885
886 // Go right past the overwritten text
887 term.cursor_right(4, false);
888 assert_eq!(term.cursor_row(), 2);
889 assert_eq!(term.cursor_col(), 5);
890 assert_eq!(term.u8c_cursor().text_utf8(), b"5");
891
892 // Go left to the end of the overwritten text
893 term.cursor_left(1);
894 assert_eq!(term.cursor_row(), 2);
895 assert_eq!(term.cursor_col(), 4);
896 assert_eq!(term.u8c_cursor().text_utf8(), b"-");
897
898 // Scroll back down, removing the blank line at the top.
899 // Cursor stays in place, the text moves under it.
900 term.scroll(1);
901 assert_eq!(term.cursor_row(), 2);
902 assert_eq!(term.cursor_col(), 4);
903 assert_eq!(term.u8c_cursor().text_utf8(), b"E");
904
905 // Clear from here to end-of-line
906 term.clear_eol();
907 assert_eq!(term.cursor_row(), 2);
908 assert_eq!(term.cursor_col(), 4);
909 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
910
911 // Now clear from here to start-of-line. Cursor does not move.
912 term.clear_sol();
913 assert_eq!(term.cursor_row(), 2);
914 assert_eq!(term.cursor_col(), 4);
915 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
916 term.cursor_left(1);
917 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
918 term.set_cursor_col(0);
919 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
920
921 // Clear some lines
922 term.clear_line(1);
923 assert_eq!(term.cursor_row(), 2);
924 assert_eq!(term.cursor_col(), 0);
925 term.set_cursor_row(1);
926 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
927 term.set_cursor_row(3);
928 term.clear_cur_line();
929 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
930 assert_eq!(term.cursor_row(), 3);
931 assert_eq!(term.cursor_col(), 0);
932
933 term.append("Two lines above are intentionally left blank.\n");
934 assert_eq!(term.cursor_row(), 4);
935 assert_eq!(term.cursor_col(), 0);
936
937 // Set up the test pattern again, then play with insert/delete
938 term.append("0123456789\n");
939 term.append("ABCDEFGHIJ\n");
940 term.append("abcdefghij\n");
941 assert_eq!(term.cursor_row(), 7);
942
943 term.set_cursor_row(4);
944 term.set_cursor_col(4);
945 assert_eq!(term.u8c_cursor().text_utf8(), b"4");
946
947 term.insert_char('x', 5); // Push this row right 5 chars starting at col 4
948 assert_eq!(term.u8c_cursor().text_utf8(), b"x");
949 term.cursor_right(5, false);
950 assert_eq!(term.cursor_col(), 9);
951 assert_eq!(term.u8c_cursor().text_utf8(), b"4");
952
953 // Insert two blank rows above cursor. Cursor stays put.
954 term.insert_rows(2);
955 assert_eq!(term.cursor_row(), 4);
956 assert_eq!(term.cursor_col(), 9);
957 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
958 term.cursor_down(2, false); // Go down to find our text again
959 assert_eq!(term.u8c_cursor().text_utf8(), b"4");
960
961 // Go back to the beginning of the inserted 'x' characters and delete them.
962 term.cursor_left(5);
963 assert_eq!(term.u8c_cursor().text_utf8(), b"x");
964 term.delete_cur_chars(5);
965 assert_eq!(term.cursor_row(), 6);
966 assert_eq!(term.cursor_col(), 4);
967 assert_eq!(term.u8c_cursor().text_utf8(), b"4");
968
969 term.delete_chars(7, 2, 2); // Delete "CD" from the next row
970 term.cursor_down(1, false);
971 term.cursor_left(2);
972 assert_eq!(term.u8c_cursor().text_utf8(), b"E");
973
974 term.delete_rows(1); // Middle row of pattern is gone, cursor stays put
975 assert_eq!(term.u8c_cursor().text_utf8(), b"c");
976 term.cursor_up(1, false);
977 term.delete_rows(2); // Delete remains of test pattern
978
979 term.set_text_attrib(Attrib::Bold);
980 term.insert_char_eol('-', 3, 15, 20);
981 term.set_cursor_row(3);
982 term.set_cursor_col(15);
983 assert_eq!(term.u8c_cursor().text_utf8(), b"-"); // Check the insertion
984 assert_eq!(term.u8c_cursor().attrib(), Attrib::Bold);
985
986 term.set_text_attrib(Attrib::Italic);
987 term.append(" and all lines below");
988 term.set_text_attrib(Attrib::Normal);
989 term.cursor_down(1, false);
990
991 let mut hsb = term.hscrollbar();
992 let mut sb = term.scrollbar();
993 hsb.set_value(100.0);
994 assert_eq!(hsb.value(), 100.0);
995 sb.set_value(50.0);
996 assert_eq!(sb.value(), 50.0);
997 hsb.set_value(0.0);
998 assert_eq!(hsb.value(), 0.0);
999 sb.set_value(0.0);
1000 assert_eq!(sb.value(), 0.0);
1001}
Sourcepub fn bgcolor(&self) -> Color
pub fn bgcolor(&self) -> Color
Return the background color for this character.
Examples found in repository?
554fn mb_test4_cb(_choice: &mut fltk::menu::Choice, term: &mut Terminal) {
555 let sel_len = term.selection_text_len();
556 let sel = term.selection_text();
557
558 term.take_focus().unwrap();
559 term.reset_terminal();
560 // Test the Utf8Char primitive
561 let uc = Utf8Char::new(b'Q');
562 let uc1 = uc.text_utf8();
563 assert_eq!(&uc1, b"Q");
564 assert_eq!(&uc.attrib(), &Attrib::Normal);
565 assert_eq!(
566 &uc.charflags(),
567 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
568 );
569 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
570 assert_eq!(&uc.bgcolor(), &Color::TransparentBg);
571
572 let ring_rows = term.ring_rows();
573
574 term.take_focus().unwrap();
575 term.clear_history();
576 assert_eq!(term.history_use(), 0);
577
578 // Subtract row numbers, modulo `rows`
579 fn row_diff(rows: i32, a: i32, b: i32) -> i32 {
580 match a - b {
581 n if n < 0 => n + rows,
582 n => n,
583 }
584 }
585 // disp_srow is always 1 greater than hist_erow, modulo (ring_rows+1)
586 assert_eq!(row_diff(ring_rows, term.disp_srow(), term.hist_erow()), 1);
587 assert!(term.disp_srow() >= 0);
588 assert!(term.disp_erow() >= 0);
589 assert!(term.hist_srow() >= 0);
590 assert!(term.hist_erow() >= 0);
591 assert!(term.offset() >= 0);
592 assert!(term.disp_srow() <= ring_rows);
593 assert!(term.disp_erow() <= ring_rows);
594 assert!(term.hist_srow() <= ring_rows);
595 assert!(term.hist_erow() <= ring_rows);
596 assert!(term.offset() <= ring_rows);
597
598 assert_eq!(term.ring_srow(), 0);
599 assert_eq!(term.ring_erow(), ring_rows - 1);
600 assert_eq!(
601 row_diff(ring_rows, term.disp_erow(), term.disp_srow()) + 1,
602 term.display_rows()
603 );
604 assert_eq!(
605 row_diff(ring_rows, term.hist_erow(), term.hist_srow()) + 1,
606 term.history_rows()
607 );
608
609 assert_eq!(term.ring_erow(), term.ring_rows() - 1);
610 assert_eq!(term.ring_srow(), 0);
611
612 /// Local function to read back all rows from the display into a long string.
613 /// Does not include scrollback history.
614 /// Trims trailing blanks on each line
615 fn read_disp(term: &Terminal) -> String {
616 let rows = term.display_rows();
617 let mut text: Vec<u8> = Vec::with_capacity((rows * 64) as usize);
618 for row in 0..rows {
619 let r = term.u8c_disp_row(row).trim();
620 // Iterate through a row, accumulating [u8]
621 for c in r.iter() {
622 // Note: Sometimes utf-8 length is > 1
623 text.extend_from_slice(c.text_utf8());
624 }
625 text.extend_from_slice(b"\n");
626 }
627 // Return the result as a string
628 std::str::from_utf8(&text).unwrap().to_string()
629 }
630
631 term.clear();
632 term.append("Top line ↑ (up-arrow)");
633 term.set_text_attrib(Attrib::Underline);
634 term.append(" ");
635 term.set_text_attrib(Attrib::Normal);
636 term.append(" \n");
637 let mut text_out = read_disp(term);
638 // Trim trailing empty lines
639 text_out = text_out.trim_end_matches(&"\n").to_string();
640 // The two plain blanks at the end will be trimmed, the two underlined blanks will be retained.
641
642 assert_eq!(text_out, "Top line ↑ (up-arrow) ");
643 let r = term.u8c_disp_row(0);
644 assert_eq!(r.col(0).text_utf8(), b"T");
645 assert_eq!(r.col(10).text_utf8(), b"\xe2\x86\x91"); // UTF-8 up-arrow
646 assert_eq!(r.col(24).text_utf8(), b" "); // First blank after test text, NOT trimmed
647 let r = term.u8c_disp_row(1);
648 assert_eq!(r.col(0).text_utf8(), b" "); // Second row starts with blanks
649 assert_eq!(r.col(1).text_utf8(), b" "); // Second row is full of blanks
650
651 // Clear the screen again, then append test text, then read it back and compare
652 let test_text = "The wind was a torrent of darkness among the gusty trees.
653The moon was a ghostly galleon tossed upon cloudy seas.
654The road was a ribbon of moonlight over the purple moor,
655And the highwayman came riding—
656 Riding—riding—
657The highwayman came riding, up to the old inn-door.";
658
659 term.clear_history();
660 term.clear();
661 let bg_save = term.text_bg_color();
662 let fg_save = term.text_fg_color();
663 term.set_text_bg_color(Color::DarkBlue); // Set spooky colors
664 term.set_text_fg_color(Color::from_rgb(0x40, 0x40, 0xff));
665 term.append(test_text);
666 term.set_text_bg_color(bg_save);
667 term.set_text_fg_color(fg_save);
668
669 let mut text_out = read_disp(term);
670 // Trim trailing empty lines
671 text_out = text_out.trim_end_matches(&"\n").to_string();
672 assert_eq!(test_text, text_out);
673
674 assert_eq!(row_diff(ring_rows, term.disp_srow(), term.hist_erow()), 1);
675
676 assert_eq!(term.ring_srow(), 0);
677 assert_eq!(term.ring_erow(), ring_rows - 1);
678 assert_eq!(
679 row_diff(ring_rows, term.disp_erow(), term.disp_srow()) + 1,
680 term.display_rows()
681 );
682 assert_eq!(
683 row_diff(ring_rows, term.hist_erow(), term.hist_srow()) + 1,
684 term.history_rows()
685 );
686
687 term.append(&format!(
688 "\n\nScreen has {} rows of {} columns.\n",
689 term.display_rows(),
690 term.display_columns()
691 ));
692
693 term.append(&format!("Selection len: {sel_len}\nSelection: '{sel:?}'\n"));
694}
695
696//--------------------------------------------------------------------------------------
697/// Yet another set of tests for misc cursor functions and other stuff
698/// Note: these tests depend heavily on the low-level "protected" parts of the fltk library, which should be used with caution.
699fn mb_test5_cb(_choice: &mut fltk::menu::Choice, term: &mut Terminal) {
700 term.take_focus().unwrap();
701
702 // Test the attr_fg_color and attr_bg_color methods.
703 // Put a single character 'A' into the buffer and check it
704 term.clear(); // No reset_terminal(), just clear() to preserve the mouse selection for later
705 term.set_text_bg_color(Color::TransparentBg);
706 term.set_text_fg_color(Color::XtermWhite);
707 term.append("A");
708 let r = &term.u8c_disp_row(0);
709 let uc = r.col(0);
710 assert_eq!(uc.text_utf8(), b"A");
711 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
712 assert_eq!(&uc.attr_bgcolor(None), &Color::TransparentBg);
713 assert_eq!(&uc.attr_bgcolor(Some(term)), &Color::Black);
714 assert_eq!(&uc.attr_fgcolor(Some(term)), &Color::XtermWhite);
715 assert_eq!(&uc.attrib(), &Attrib::Normal);
716
717 // Put a short string "BCD" into the first line of the buffer, with fg color change after the 'B' and bold after 'C'
718 term.clear();
719 term.set_text_fg_color_xterm(XtermColor::White);
720 term.set_text_bg_color_xterm(XtermColor::Black);
721 assert_eq!(term.text_attrib(), Attrib::Normal);
722
723 assert!(term.ansi());
724 term.append("B\x1b[32mC\x1b[1mD\n");
725
726 let r = &term.u8c_disp_row(0);
727 let uc = r.col(0);
728 assert_eq!(uc.text_utf8(), b"B");
729 assert!(uc.is_char(b'B'));
730 assert!(!uc.is_char(b'A'));
731 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
732 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
733 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
734 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBlack);
735 assert_eq!(
736 &uc.charflags(),
737 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
738 );
739
740 let uc = r.col(1);
741 assert_eq!(uc.text_utf8(), b"C");
742 assert!(uc.is_char(b'C'));
743 assert_eq!(&uc.fgcolor(), &Color::XtermGreen);
744 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
745 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermGreen);
746 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBlack);
747 assert_eq!(
748 &uc.charflags(),
749 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
750 );
751
752 let uc = r.col(2);
753 assert_eq!(uc.text_utf8(), b"D");
754 assert!(uc.is_char(b'D'));
755 assert_eq!(&uc.fgcolor(), &Color::XtermGreen);
756 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
757 assert_eq!(&uc.attr_fgcolor(None), &Color::from_rgb(0x20, 0xf0, 0x20));
758 assert_eq!(&uc.attr_bgcolor(None), &Color::from_rgb(0x20, 0x20, 0x20));
759 assert_eq!(
760 &uc.attr_fgcolor(Some(term)),
761 &Color::from_rgb(0x20, 0xf0, 0x20)
762 );
763 assert_eq!(&uc.attr_bgcolor(None), &Color::from_rgb(0x20, 0x20, 0x20));
764 assert_eq!(
765 &uc.charflags(),
766 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
767 );
768
769 // Put a short string "BCDE" into the buffer, with fg color change after the 'B', bg change after 'C', and bold after 'D'
770 term.clear();
771 term.set_text_fg_color_xterm(XtermColor::White);
772 term.set_text_bg_color_xterm(XtermColor::Black);
773 term.set_text_attrib(Attrib::Normal);
774 assert_eq!(term.text_attrib(), Attrib::Normal);
775
776 assert!(term.ansi());
777 term.append("B\x1b[37mC\x1b[44mD\x1b[1mE\n");
778
779 let r = &term.u8c_disp_row(0);
780 let uc = r.col(0);
781 assert_eq!(uc.text_utf8(), b"B");
782 assert!(uc.is_char(b'B'));
783 assert!(!uc.is_char(b'A'));
784 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
785 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
786 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
787 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBlack);
788 assert_eq!(
789 &uc.charflags(),
790 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
791 );
792
793 let uc = r.col(1);
794 assert_eq!(uc.text_utf8(), b"C");
795 assert!(uc.is_char(b'C'));
796 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
797 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
798 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
799 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBlack);
800 assert_eq!(
801 &uc.charflags(),
802 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
803 );
804
805 let uc = r.col(2);
806 assert_eq!(uc.text_utf8(), b"D");
807 assert!(uc.is_char(b'D'));
808 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
809 assert_eq!(&uc.bgcolor(), &Color::XtermBgBlue);
810 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
811 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBgBlue);
812 assert_eq!(
813 &uc.charflags(),
814 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
815 );
816
817 let uc = r.col(3);
818 assert_eq!(uc.text_utf8(), b"E");
819 assert!(uc.is_char(b'E'));
820 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
821 assert_eq!(&uc.bgcolor(), &Color::XtermBgBlue);
822 assert_eq!(&uc.attr_fgcolor(None), &Color::from_hex(0xf0f0f0));
823 assert_eq!(&uc.attr_bgcolor(None), &Color::from_hex(0x2020e0));
824 assert_eq!(
825 &uc.charflags(),
826 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
827 );
828
829 // Test some miscellaneous Utf8 constants
830 assert_eq!(uc.length(), 1);
831 assert_eq!(uc.max_utf8(), 4);
832 assert_eq!(uc.pwidth(), 9.0);
833 assert_eq!(uc.pwidth_int(), 9);
834
835 term.set_text_fg_color_xterm(XtermColor::White);
836 term.set_text_bg_color_xterm(XtermColor::Black);
837 term.clear();
838 term.set_text_attrib(Attrib::Normal);
839
840 // Mouse selection functions
841 term.append(&format!("Mouse selection: {:?}\n", &term.get_selection()));
842 term.clear_mouse_selection();
843 assert_eq!(term.get_selection(), None);
844
845 // Play with cursor position
846 term.append("0123456789\n"); // Set up test pattern
847 term.append("ABCDEFGHIJ\n");
848 term.append("abcdefghij\n");
849
850 term.set_cursor_row(1);
851 assert_eq!(term.cursor_row(), 1);
852 term.set_cursor_col(1);
853 assert_eq!(term.cursor_col(), 1);
854 assert_eq!(term.u8c_cursor().text_utf8(), b"1");
855
856 term.append("----"); // Overwrites text at cursor and moves cursor forward
857 assert_eq!(term.cursor_row(), 1);
858 assert_eq!(term.cursor_col(), 5);
859 assert_eq!(term.u8c_cursor().text_utf8(), b"5");
860 term.set_cursor_col(1);
861 assert_eq!(term.u8c_cursor().text_utf8(), b"-"); // Overwritten text
862
863 term.cursor_up(1, false);
864 assert_eq!(term.cursor_row(), 0);
865 assert_eq!(term.cursor_col(), 1);
866 assert_eq!(term.u8c_cursor().text_utf8(), b"o");
867
868 // Hit top of screen, so nothing happens
869 term.cursor_up(1, false);
870 assert_eq!(term.cursor_row(), 0);
871 assert_eq!(term.cursor_col(), 1);
872 assert_eq!(term.u8c_cursor().text_utf8(), b"o");
873
874 // Hit top of screen with scroll enabled. A blank line from history is scrolled in.
875 term.cursor_up(1, true);
876 assert_eq!(term.cursor_row(), 0);
877 assert_eq!(term.cursor_col(), 1);
878 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
879
880 // Go back down to the overwritten text
881 term.cursor_down(2, false);
882 assert_eq!(term.cursor_row(), 2);
883 assert_eq!(term.cursor_col(), 1);
884 assert_eq!(term.u8c_cursor().text_utf8(), b"-");
885
886 // Go right past the overwritten text
887 term.cursor_right(4, false);
888 assert_eq!(term.cursor_row(), 2);
889 assert_eq!(term.cursor_col(), 5);
890 assert_eq!(term.u8c_cursor().text_utf8(), b"5");
891
892 // Go left to the end of the overwritten text
893 term.cursor_left(1);
894 assert_eq!(term.cursor_row(), 2);
895 assert_eq!(term.cursor_col(), 4);
896 assert_eq!(term.u8c_cursor().text_utf8(), b"-");
897
898 // Scroll back down, removing the blank line at the top.
899 // Cursor stays in place, the text moves under it.
900 term.scroll(1);
901 assert_eq!(term.cursor_row(), 2);
902 assert_eq!(term.cursor_col(), 4);
903 assert_eq!(term.u8c_cursor().text_utf8(), b"E");
904
905 // Clear from here to end-of-line
906 term.clear_eol();
907 assert_eq!(term.cursor_row(), 2);
908 assert_eq!(term.cursor_col(), 4);
909 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
910
911 // Now clear from here to start-of-line. Cursor does not move.
912 term.clear_sol();
913 assert_eq!(term.cursor_row(), 2);
914 assert_eq!(term.cursor_col(), 4);
915 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
916 term.cursor_left(1);
917 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
918 term.set_cursor_col(0);
919 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
920
921 // Clear some lines
922 term.clear_line(1);
923 assert_eq!(term.cursor_row(), 2);
924 assert_eq!(term.cursor_col(), 0);
925 term.set_cursor_row(1);
926 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
927 term.set_cursor_row(3);
928 term.clear_cur_line();
929 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
930 assert_eq!(term.cursor_row(), 3);
931 assert_eq!(term.cursor_col(), 0);
932
933 term.append("Two lines above are intentionally left blank.\n");
934 assert_eq!(term.cursor_row(), 4);
935 assert_eq!(term.cursor_col(), 0);
936
937 // Set up the test pattern again, then play with insert/delete
938 term.append("0123456789\n");
939 term.append("ABCDEFGHIJ\n");
940 term.append("abcdefghij\n");
941 assert_eq!(term.cursor_row(), 7);
942
943 term.set_cursor_row(4);
944 term.set_cursor_col(4);
945 assert_eq!(term.u8c_cursor().text_utf8(), b"4");
946
947 term.insert_char('x', 5); // Push this row right 5 chars starting at col 4
948 assert_eq!(term.u8c_cursor().text_utf8(), b"x");
949 term.cursor_right(5, false);
950 assert_eq!(term.cursor_col(), 9);
951 assert_eq!(term.u8c_cursor().text_utf8(), b"4");
952
953 // Insert two blank rows above cursor. Cursor stays put.
954 term.insert_rows(2);
955 assert_eq!(term.cursor_row(), 4);
956 assert_eq!(term.cursor_col(), 9);
957 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
958 term.cursor_down(2, false); // Go down to find our text again
959 assert_eq!(term.u8c_cursor().text_utf8(), b"4");
960
961 // Go back to the beginning of the inserted 'x' characters and delete them.
962 term.cursor_left(5);
963 assert_eq!(term.u8c_cursor().text_utf8(), b"x");
964 term.delete_cur_chars(5);
965 assert_eq!(term.cursor_row(), 6);
966 assert_eq!(term.cursor_col(), 4);
967 assert_eq!(term.u8c_cursor().text_utf8(), b"4");
968
969 term.delete_chars(7, 2, 2); // Delete "CD" from the next row
970 term.cursor_down(1, false);
971 term.cursor_left(2);
972 assert_eq!(term.u8c_cursor().text_utf8(), b"E");
973
974 term.delete_rows(1); // Middle row of pattern is gone, cursor stays put
975 assert_eq!(term.u8c_cursor().text_utf8(), b"c");
976 term.cursor_up(1, false);
977 term.delete_rows(2); // Delete remains of test pattern
978
979 term.set_text_attrib(Attrib::Bold);
980 term.insert_char_eol('-', 3, 15, 20);
981 term.set_cursor_row(3);
982 term.set_cursor_col(15);
983 assert_eq!(term.u8c_cursor().text_utf8(), b"-"); // Check the insertion
984 assert_eq!(term.u8c_cursor().attrib(), Attrib::Bold);
985
986 term.set_text_attrib(Attrib::Italic);
987 term.append(" and all lines below");
988 term.set_text_attrib(Attrib::Normal);
989 term.cursor_down(1, false);
990
991 let mut hsb = term.hscrollbar();
992 let mut sb = term.scrollbar();
993 hsb.set_value(100.0);
994 assert_eq!(hsb.value(), 100.0);
995 sb.set_value(50.0);
996 assert_eq!(sb.value(), 50.0);
997 hsb.set_value(0.0);
998 assert_eq!(hsb.value(), 0.0);
999 sb.set_value(0.0);
1000 assert_eq!(sb.value(), 0.0);
1001}
Sourcepub fn fgcolor(&self) -> Color
pub fn fgcolor(&self) -> Color
Return the foreground color for this character.
Examples found in repository?
554fn mb_test4_cb(_choice: &mut fltk::menu::Choice, term: &mut Terminal) {
555 let sel_len = term.selection_text_len();
556 let sel = term.selection_text();
557
558 term.take_focus().unwrap();
559 term.reset_terminal();
560 // Test the Utf8Char primitive
561 let uc = Utf8Char::new(b'Q');
562 let uc1 = uc.text_utf8();
563 assert_eq!(&uc1, b"Q");
564 assert_eq!(&uc.attrib(), &Attrib::Normal);
565 assert_eq!(
566 &uc.charflags(),
567 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
568 );
569 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
570 assert_eq!(&uc.bgcolor(), &Color::TransparentBg);
571
572 let ring_rows = term.ring_rows();
573
574 term.take_focus().unwrap();
575 term.clear_history();
576 assert_eq!(term.history_use(), 0);
577
578 // Subtract row numbers, modulo `rows`
579 fn row_diff(rows: i32, a: i32, b: i32) -> i32 {
580 match a - b {
581 n if n < 0 => n + rows,
582 n => n,
583 }
584 }
585 // disp_srow is always 1 greater than hist_erow, modulo (ring_rows+1)
586 assert_eq!(row_diff(ring_rows, term.disp_srow(), term.hist_erow()), 1);
587 assert!(term.disp_srow() >= 0);
588 assert!(term.disp_erow() >= 0);
589 assert!(term.hist_srow() >= 0);
590 assert!(term.hist_erow() >= 0);
591 assert!(term.offset() >= 0);
592 assert!(term.disp_srow() <= ring_rows);
593 assert!(term.disp_erow() <= ring_rows);
594 assert!(term.hist_srow() <= ring_rows);
595 assert!(term.hist_erow() <= ring_rows);
596 assert!(term.offset() <= ring_rows);
597
598 assert_eq!(term.ring_srow(), 0);
599 assert_eq!(term.ring_erow(), ring_rows - 1);
600 assert_eq!(
601 row_diff(ring_rows, term.disp_erow(), term.disp_srow()) + 1,
602 term.display_rows()
603 );
604 assert_eq!(
605 row_diff(ring_rows, term.hist_erow(), term.hist_srow()) + 1,
606 term.history_rows()
607 );
608
609 assert_eq!(term.ring_erow(), term.ring_rows() - 1);
610 assert_eq!(term.ring_srow(), 0);
611
612 /// Local function to read back all rows from the display into a long string.
613 /// Does not include scrollback history.
614 /// Trims trailing blanks on each line
615 fn read_disp(term: &Terminal) -> String {
616 let rows = term.display_rows();
617 let mut text: Vec<u8> = Vec::with_capacity((rows * 64) as usize);
618 for row in 0..rows {
619 let r = term.u8c_disp_row(row).trim();
620 // Iterate through a row, accumulating [u8]
621 for c in r.iter() {
622 // Note: Sometimes utf-8 length is > 1
623 text.extend_from_slice(c.text_utf8());
624 }
625 text.extend_from_slice(b"\n");
626 }
627 // Return the result as a string
628 std::str::from_utf8(&text).unwrap().to_string()
629 }
630
631 term.clear();
632 term.append("Top line ↑ (up-arrow)");
633 term.set_text_attrib(Attrib::Underline);
634 term.append(" ");
635 term.set_text_attrib(Attrib::Normal);
636 term.append(" \n");
637 let mut text_out = read_disp(term);
638 // Trim trailing empty lines
639 text_out = text_out.trim_end_matches(&"\n").to_string();
640 // The two plain blanks at the end will be trimmed, the two underlined blanks will be retained.
641
642 assert_eq!(text_out, "Top line ↑ (up-arrow) ");
643 let r = term.u8c_disp_row(0);
644 assert_eq!(r.col(0).text_utf8(), b"T");
645 assert_eq!(r.col(10).text_utf8(), b"\xe2\x86\x91"); // UTF-8 up-arrow
646 assert_eq!(r.col(24).text_utf8(), b" "); // First blank after test text, NOT trimmed
647 let r = term.u8c_disp_row(1);
648 assert_eq!(r.col(0).text_utf8(), b" "); // Second row starts with blanks
649 assert_eq!(r.col(1).text_utf8(), b" "); // Second row is full of blanks
650
651 // Clear the screen again, then append test text, then read it back and compare
652 let test_text = "The wind was a torrent of darkness among the gusty trees.
653The moon was a ghostly galleon tossed upon cloudy seas.
654The road was a ribbon of moonlight over the purple moor,
655And the highwayman came riding—
656 Riding—riding—
657The highwayman came riding, up to the old inn-door.";
658
659 term.clear_history();
660 term.clear();
661 let bg_save = term.text_bg_color();
662 let fg_save = term.text_fg_color();
663 term.set_text_bg_color(Color::DarkBlue); // Set spooky colors
664 term.set_text_fg_color(Color::from_rgb(0x40, 0x40, 0xff));
665 term.append(test_text);
666 term.set_text_bg_color(bg_save);
667 term.set_text_fg_color(fg_save);
668
669 let mut text_out = read_disp(term);
670 // Trim trailing empty lines
671 text_out = text_out.trim_end_matches(&"\n").to_string();
672 assert_eq!(test_text, text_out);
673
674 assert_eq!(row_diff(ring_rows, term.disp_srow(), term.hist_erow()), 1);
675
676 assert_eq!(term.ring_srow(), 0);
677 assert_eq!(term.ring_erow(), ring_rows - 1);
678 assert_eq!(
679 row_diff(ring_rows, term.disp_erow(), term.disp_srow()) + 1,
680 term.display_rows()
681 );
682 assert_eq!(
683 row_diff(ring_rows, term.hist_erow(), term.hist_srow()) + 1,
684 term.history_rows()
685 );
686
687 term.append(&format!(
688 "\n\nScreen has {} rows of {} columns.\n",
689 term.display_rows(),
690 term.display_columns()
691 ));
692
693 term.append(&format!("Selection len: {sel_len}\nSelection: '{sel:?}'\n"));
694}
695
696//--------------------------------------------------------------------------------------
697/// Yet another set of tests for misc cursor functions and other stuff
698/// Note: these tests depend heavily on the low-level "protected" parts of the fltk library, which should be used with caution.
699fn mb_test5_cb(_choice: &mut fltk::menu::Choice, term: &mut Terminal) {
700 term.take_focus().unwrap();
701
702 // Test the attr_fg_color and attr_bg_color methods.
703 // Put a single character 'A' into the buffer and check it
704 term.clear(); // No reset_terminal(), just clear() to preserve the mouse selection for later
705 term.set_text_bg_color(Color::TransparentBg);
706 term.set_text_fg_color(Color::XtermWhite);
707 term.append("A");
708 let r = &term.u8c_disp_row(0);
709 let uc = r.col(0);
710 assert_eq!(uc.text_utf8(), b"A");
711 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
712 assert_eq!(&uc.attr_bgcolor(None), &Color::TransparentBg);
713 assert_eq!(&uc.attr_bgcolor(Some(term)), &Color::Black);
714 assert_eq!(&uc.attr_fgcolor(Some(term)), &Color::XtermWhite);
715 assert_eq!(&uc.attrib(), &Attrib::Normal);
716
717 // Put a short string "BCD" into the first line of the buffer, with fg color change after the 'B' and bold after 'C'
718 term.clear();
719 term.set_text_fg_color_xterm(XtermColor::White);
720 term.set_text_bg_color_xterm(XtermColor::Black);
721 assert_eq!(term.text_attrib(), Attrib::Normal);
722
723 assert!(term.ansi());
724 term.append("B\x1b[32mC\x1b[1mD\n");
725
726 let r = &term.u8c_disp_row(0);
727 let uc = r.col(0);
728 assert_eq!(uc.text_utf8(), b"B");
729 assert!(uc.is_char(b'B'));
730 assert!(!uc.is_char(b'A'));
731 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
732 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
733 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
734 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBlack);
735 assert_eq!(
736 &uc.charflags(),
737 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
738 );
739
740 let uc = r.col(1);
741 assert_eq!(uc.text_utf8(), b"C");
742 assert!(uc.is_char(b'C'));
743 assert_eq!(&uc.fgcolor(), &Color::XtermGreen);
744 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
745 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermGreen);
746 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBlack);
747 assert_eq!(
748 &uc.charflags(),
749 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
750 );
751
752 let uc = r.col(2);
753 assert_eq!(uc.text_utf8(), b"D");
754 assert!(uc.is_char(b'D'));
755 assert_eq!(&uc.fgcolor(), &Color::XtermGreen);
756 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
757 assert_eq!(&uc.attr_fgcolor(None), &Color::from_rgb(0x20, 0xf0, 0x20));
758 assert_eq!(&uc.attr_bgcolor(None), &Color::from_rgb(0x20, 0x20, 0x20));
759 assert_eq!(
760 &uc.attr_fgcolor(Some(term)),
761 &Color::from_rgb(0x20, 0xf0, 0x20)
762 );
763 assert_eq!(&uc.attr_bgcolor(None), &Color::from_rgb(0x20, 0x20, 0x20));
764 assert_eq!(
765 &uc.charflags(),
766 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
767 );
768
769 // Put a short string "BCDE" into the buffer, with fg color change after the 'B', bg change after 'C', and bold after 'D'
770 term.clear();
771 term.set_text_fg_color_xterm(XtermColor::White);
772 term.set_text_bg_color_xterm(XtermColor::Black);
773 term.set_text_attrib(Attrib::Normal);
774 assert_eq!(term.text_attrib(), Attrib::Normal);
775
776 assert!(term.ansi());
777 term.append("B\x1b[37mC\x1b[44mD\x1b[1mE\n");
778
779 let r = &term.u8c_disp_row(0);
780 let uc = r.col(0);
781 assert_eq!(uc.text_utf8(), b"B");
782 assert!(uc.is_char(b'B'));
783 assert!(!uc.is_char(b'A'));
784 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
785 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
786 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
787 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBlack);
788 assert_eq!(
789 &uc.charflags(),
790 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
791 );
792
793 let uc = r.col(1);
794 assert_eq!(uc.text_utf8(), b"C");
795 assert!(uc.is_char(b'C'));
796 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
797 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
798 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
799 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBlack);
800 assert_eq!(
801 &uc.charflags(),
802 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
803 );
804
805 let uc = r.col(2);
806 assert_eq!(uc.text_utf8(), b"D");
807 assert!(uc.is_char(b'D'));
808 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
809 assert_eq!(&uc.bgcolor(), &Color::XtermBgBlue);
810 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
811 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBgBlue);
812 assert_eq!(
813 &uc.charflags(),
814 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
815 );
816
817 let uc = r.col(3);
818 assert_eq!(uc.text_utf8(), b"E");
819 assert!(uc.is_char(b'E'));
820 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
821 assert_eq!(&uc.bgcolor(), &Color::XtermBgBlue);
822 assert_eq!(&uc.attr_fgcolor(None), &Color::from_hex(0xf0f0f0));
823 assert_eq!(&uc.attr_bgcolor(None), &Color::from_hex(0x2020e0));
824 assert_eq!(
825 &uc.charflags(),
826 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
827 );
828
829 // Test some miscellaneous Utf8 constants
830 assert_eq!(uc.length(), 1);
831 assert_eq!(uc.max_utf8(), 4);
832 assert_eq!(uc.pwidth(), 9.0);
833 assert_eq!(uc.pwidth_int(), 9);
834
835 term.set_text_fg_color_xterm(XtermColor::White);
836 term.set_text_bg_color_xterm(XtermColor::Black);
837 term.clear();
838 term.set_text_attrib(Attrib::Normal);
839
840 // Mouse selection functions
841 term.append(&format!("Mouse selection: {:?}\n", &term.get_selection()));
842 term.clear_mouse_selection();
843 assert_eq!(term.get_selection(), None);
844
845 // Play with cursor position
846 term.append("0123456789\n"); // Set up test pattern
847 term.append("ABCDEFGHIJ\n");
848 term.append("abcdefghij\n");
849
850 term.set_cursor_row(1);
851 assert_eq!(term.cursor_row(), 1);
852 term.set_cursor_col(1);
853 assert_eq!(term.cursor_col(), 1);
854 assert_eq!(term.u8c_cursor().text_utf8(), b"1");
855
856 term.append("----"); // Overwrites text at cursor and moves cursor forward
857 assert_eq!(term.cursor_row(), 1);
858 assert_eq!(term.cursor_col(), 5);
859 assert_eq!(term.u8c_cursor().text_utf8(), b"5");
860 term.set_cursor_col(1);
861 assert_eq!(term.u8c_cursor().text_utf8(), b"-"); // Overwritten text
862
863 term.cursor_up(1, false);
864 assert_eq!(term.cursor_row(), 0);
865 assert_eq!(term.cursor_col(), 1);
866 assert_eq!(term.u8c_cursor().text_utf8(), b"o");
867
868 // Hit top of screen, so nothing happens
869 term.cursor_up(1, false);
870 assert_eq!(term.cursor_row(), 0);
871 assert_eq!(term.cursor_col(), 1);
872 assert_eq!(term.u8c_cursor().text_utf8(), b"o");
873
874 // Hit top of screen with scroll enabled. A blank line from history is scrolled in.
875 term.cursor_up(1, true);
876 assert_eq!(term.cursor_row(), 0);
877 assert_eq!(term.cursor_col(), 1);
878 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
879
880 // Go back down to the overwritten text
881 term.cursor_down(2, false);
882 assert_eq!(term.cursor_row(), 2);
883 assert_eq!(term.cursor_col(), 1);
884 assert_eq!(term.u8c_cursor().text_utf8(), b"-");
885
886 // Go right past the overwritten text
887 term.cursor_right(4, false);
888 assert_eq!(term.cursor_row(), 2);
889 assert_eq!(term.cursor_col(), 5);
890 assert_eq!(term.u8c_cursor().text_utf8(), b"5");
891
892 // Go left to the end of the overwritten text
893 term.cursor_left(1);
894 assert_eq!(term.cursor_row(), 2);
895 assert_eq!(term.cursor_col(), 4);
896 assert_eq!(term.u8c_cursor().text_utf8(), b"-");
897
898 // Scroll back down, removing the blank line at the top.
899 // Cursor stays in place, the text moves under it.
900 term.scroll(1);
901 assert_eq!(term.cursor_row(), 2);
902 assert_eq!(term.cursor_col(), 4);
903 assert_eq!(term.u8c_cursor().text_utf8(), b"E");
904
905 // Clear from here to end-of-line
906 term.clear_eol();
907 assert_eq!(term.cursor_row(), 2);
908 assert_eq!(term.cursor_col(), 4);
909 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
910
911 // Now clear from here to start-of-line. Cursor does not move.
912 term.clear_sol();
913 assert_eq!(term.cursor_row(), 2);
914 assert_eq!(term.cursor_col(), 4);
915 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
916 term.cursor_left(1);
917 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
918 term.set_cursor_col(0);
919 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
920
921 // Clear some lines
922 term.clear_line(1);
923 assert_eq!(term.cursor_row(), 2);
924 assert_eq!(term.cursor_col(), 0);
925 term.set_cursor_row(1);
926 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
927 term.set_cursor_row(3);
928 term.clear_cur_line();
929 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
930 assert_eq!(term.cursor_row(), 3);
931 assert_eq!(term.cursor_col(), 0);
932
933 term.append("Two lines above are intentionally left blank.\n");
934 assert_eq!(term.cursor_row(), 4);
935 assert_eq!(term.cursor_col(), 0);
936
937 // Set up the test pattern again, then play with insert/delete
938 term.append("0123456789\n");
939 term.append("ABCDEFGHIJ\n");
940 term.append("abcdefghij\n");
941 assert_eq!(term.cursor_row(), 7);
942
943 term.set_cursor_row(4);
944 term.set_cursor_col(4);
945 assert_eq!(term.u8c_cursor().text_utf8(), b"4");
946
947 term.insert_char('x', 5); // Push this row right 5 chars starting at col 4
948 assert_eq!(term.u8c_cursor().text_utf8(), b"x");
949 term.cursor_right(5, false);
950 assert_eq!(term.cursor_col(), 9);
951 assert_eq!(term.u8c_cursor().text_utf8(), b"4");
952
953 // Insert two blank rows above cursor. Cursor stays put.
954 term.insert_rows(2);
955 assert_eq!(term.cursor_row(), 4);
956 assert_eq!(term.cursor_col(), 9);
957 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
958 term.cursor_down(2, false); // Go down to find our text again
959 assert_eq!(term.u8c_cursor().text_utf8(), b"4");
960
961 // Go back to the beginning of the inserted 'x' characters and delete them.
962 term.cursor_left(5);
963 assert_eq!(term.u8c_cursor().text_utf8(), b"x");
964 term.delete_cur_chars(5);
965 assert_eq!(term.cursor_row(), 6);
966 assert_eq!(term.cursor_col(), 4);
967 assert_eq!(term.u8c_cursor().text_utf8(), b"4");
968
969 term.delete_chars(7, 2, 2); // Delete "CD" from the next row
970 term.cursor_down(1, false);
971 term.cursor_left(2);
972 assert_eq!(term.u8c_cursor().text_utf8(), b"E");
973
974 term.delete_rows(1); // Middle row of pattern is gone, cursor stays put
975 assert_eq!(term.u8c_cursor().text_utf8(), b"c");
976 term.cursor_up(1, false);
977 term.delete_rows(2); // Delete remains of test pattern
978
979 term.set_text_attrib(Attrib::Bold);
980 term.insert_char_eol('-', 3, 15, 20);
981 term.set_cursor_row(3);
982 term.set_cursor_col(15);
983 assert_eq!(term.u8c_cursor().text_utf8(), b"-"); // Check the insertion
984 assert_eq!(term.u8c_cursor().attrib(), Attrib::Bold);
985
986 term.set_text_attrib(Attrib::Italic);
987 term.append(" and all lines below");
988 term.set_text_attrib(Attrib::Normal);
989 term.cursor_down(1, false);
990
991 let mut hsb = term.hscrollbar();
992 let mut sb = term.scrollbar();
993 hsb.set_value(100.0);
994 assert_eq!(hsb.value(), 100.0);
995 sb.set_value(50.0);
996 assert_eq!(sb.value(), 50.0);
997 hsb.set_value(0.0);
998 assert_eq!(hsb.value(), 0.0);
999 sb.set_value(0.0);
1000 assert_eq!(sb.value(), 0.0);
1001}
Sourcepub fn charflags(&self) -> CharFlags
pub fn charflags(&self) -> CharFlags
Return the xterm CharFlags
bits
Examples found in repository?
554fn mb_test4_cb(_choice: &mut fltk::menu::Choice, term: &mut Terminal) {
555 let sel_len = term.selection_text_len();
556 let sel = term.selection_text();
557
558 term.take_focus().unwrap();
559 term.reset_terminal();
560 // Test the Utf8Char primitive
561 let uc = Utf8Char::new(b'Q');
562 let uc1 = uc.text_utf8();
563 assert_eq!(&uc1, b"Q");
564 assert_eq!(&uc.attrib(), &Attrib::Normal);
565 assert_eq!(
566 &uc.charflags(),
567 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
568 );
569 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
570 assert_eq!(&uc.bgcolor(), &Color::TransparentBg);
571
572 let ring_rows = term.ring_rows();
573
574 term.take_focus().unwrap();
575 term.clear_history();
576 assert_eq!(term.history_use(), 0);
577
578 // Subtract row numbers, modulo `rows`
579 fn row_diff(rows: i32, a: i32, b: i32) -> i32 {
580 match a - b {
581 n if n < 0 => n + rows,
582 n => n,
583 }
584 }
585 // disp_srow is always 1 greater than hist_erow, modulo (ring_rows+1)
586 assert_eq!(row_diff(ring_rows, term.disp_srow(), term.hist_erow()), 1);
587 assert!(term.disp_srow() >= 0);
588 assert!(term.disp_erow() >= 0);
589 assert!(term.hist_srow() >= 0);
590 assert!(term.hist_erow() >= 0);
591 assert!(term.offset() >= 0);
592 assert!(term.disp_srow() <= ring_rows);
593 assert!(term.disp_erow() <= ring_rows);
594 assert!(term.hist_srow() <= ring_rows);
595 assert!(term.hist_erow() <= ring_rows);
596 assert!(term.offset() <= ring_rows);
597
598 assert_eq!(term.ring_srow(), 0);
599 assert_eq!(term.ring_erow(), ring_rows - 1);
600 assert_eq!(
601 row_diff(ring_rows, term.disp_erow(), term.disp_srow()) + 1,
602 term.display_rows()
603 );
604 assert_eq!(
605 row_diff(ring_rows, term.hist_erow(), term.hist_srow()) + 1,
606 term.history_rows()
607 );
608
609 assert_eq!(term.ring_erow(), term.ring_rows() - 1);
610 assert_eq!(term.ring_srow(), 0);
611
612 /// Local function to read back all rows from the display into a long string.
613 /// Does not include scrollback history.
614 /// Trims trailing blanks on each line
615 fn read_disp(term: &Terminal) -> String {
616 let rows = term.display_rows();
617 let mut text: Vec<u8> = Vec::with_capacity((rows * 64) as usize);
618 for row in 0..rows {
619 let r = term.u8c_disp_row(row).trim();
620 // Iterate through a row, accumulating [u8]
621 for c in r.iter() {
622 // Note: Sometimes utf-8 length is > 1
623 text.extend_from_slice(c.text_utf8());
624 }
625 text.extend_from_slice(b"\n");
626 }
627 // Return the result as a string
628 std::str::from_utf8(&text).unwrap().to_string()
629 }
630
631 term.clear();
632 term.append("Top line ↑ (up-arrow)");
633 term.set_text_attrib(Attrib::Underline);
634 term.append(" ");
635 term.set_text_attrib(Attrib::Normal);
636 term.append(" \n");
637 let mut text_out = read_disp(term);
638 // Trim trailing empty lines
639 text_out = text_out.trim_end_matches(&"\n").to_string();
640 // The two plain blanks at the end will be trimmed, the two underlined blanks will be retained.
641
642 assert_eq!(text_out, "Top line ↑ (up-arrow) ");
643 let r = term.u8c_disp_row(0);
644 assert_eq!(r.col(0).text_utf8(), b"T");
645 assert_eq!(r.col(10).text_utf8(), b"\xe2\x86\x91"); // UTF-8 up-arrow
646 assert_eq!(r.col(24).text_utf8(), b" "); // First blank after test text, NOT trimmed
647 let r = term.u8c_disp_row(1);
648 assert_eq!(r.col(0).text_utf8(), b" "); // Second row starts with blanks
649 assert_eq!(r.col(1).text_utf8(), b" "); // Second row is full of blanks
650
651 // Clear the screen again, then append test text, then read it back and compare
652 let test_text = "The wind was a torrent of darkness among the gusty trees.
653The moon was a ghostly galleon tossed upon cloudy seas.
654The road was a ribbon of moonlight over the purple moor,
655And the highwayman came riding—
656 Riding—riding—
657The highwayman came riding, up to the old inn-door.";
658
659 term.clear_history();
660 term.clear();
661 let bg_save = term.text_bg_color();
662 let fg_save = term.text_fg_color();
663 term.set_text_bg_color(Color::DarkBlue); // Set spooky colors
664 term.set_text_fg_color(Color::from_rgb(0x40, 0x40, 0xff));
665 term.append(test_text);
666 term.set_text_bg_color(bg_save);
667 term.set_text_fg_color(fg_save);
668
669 let mut text_out = read_disp(term);
670 // Trim trailing empty lines
671 text_out = text_out.trim_end_matches(&"\n").to_string();
672 assert_eq!(test_text, text_out);
673
674 assert_eq!(row_diff(ring_rows, term.disp_srow(), term.hist_erow()), 1);
675
676 assert_eq!(term.ring_srow(), 0);
677 assert_eq!(term.ring_erow(), ring_rows - 1);
678 assert_eq!(
679 row_diff(ring_rows, term.disp_erow(), term.disp_srow()) + 1,
680 term.display_rows()
681 );
682 assert_eq!(
683 row_diff(ring_rows, term.hist_erow(), term.hist_srow()) + 1,
684 term.history_rows()
685 );
686
687 term.append(&format!(
688 "\n\nScreen has {} rows of {} columns.\n",
689 term.display_rows(),
690 term.display_columns()
691 ));
692
693 term.append(&format!("Selection len: {sel_len}\nSelection: '{sel:?}'\n"));
694}
695
696//--------------------------------------------------------------------------------------
697/// Yet another set of tests for misc cursor functions and other stuff
698/// Note: these tests depend heavily on the low-level "protected" parts of the fltk library, which should be used with caution.
699fn mb_test5_cb(_choice: &mut fltk::menu::Choice, term: &mut Terminal) {
700 term.take_focus().unwrap();
701
702 // Test the attr_fg_color and attr_bg_color methods.
703 // Put a single character 'A' into the buffer and check it
704 term.clear(); // No reset_terminal(), just clear() to preserve the mouse selection for later
705 term.set_text_bg_color(Color::TransparentBg);
706 term.set_text_fg_color(Color::XtermWhite);
707 term.append("A");
708 let r = &term.u8c_disp_row(0);
709 let uc = r.col(0);
710 assert_eq!(uc.text_utf8(), b"A");
711 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
712 assert_eq!(&uc.attr_bgcolor(None), &Color::TransparentBg);
713 assert_eq!(&uc.attr_bgcolor(Some(term)), &Color::Black);
714 assert_eq!(&uc.attr_fgcolor(Some(term)), &Color::XtermWhite);
715 assert_eq!(&uc.attrib(), &Attrib::Normal);
716
717 // Put a short string "BCD" into the first line of the buffer, with fg color change after the 'B' and bold after 'C'
718 term.clear();
719 term.set_text_fg_color_xterm(XtermColor::White);
720 term.set_text_bg_color_xterm(XtermColor::Black);
721 assert_eq!(term.text_attrib(), Attrib::Normal);
722
723 assert!(term.ansi());
724 term.append("B\x1b[32mC\x1b[1mD\n");
725
726 let r = &term.u8c_disp_row(0);
727 let uc = r.col(0);
728 assert_eq!(uc.text_utf8(), b"B");
729 assert!(uc.is_char(b'B'));
730 assert!(!uc.is_char(b'A'));
731 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
732 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
733 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
734 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBlack);
735 assert_eq!(
736 &uc.charflags(),
737 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
738 );
739
740 let uc = r.col(1);
741 assert_eq!(uc.text_utf8(), b"C");
742 assert!(uc.is_char(b'C'));
743 assert_eq!(&uc.fgcolor(), &Color::XtermGreen);
744 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
745 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermGreen);
746 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBlack);
747 assert_eq!(
748 &uc.charflags(),
749 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
750 );
751
752 let uc = r.col(2);
753 assert_eq!(uc.text_utf8(), b"D");
754 assert!(uc.is_char(b'D'));
755 assert_eq!(&uc.fgcolor(), &Color::XtermGreen);
756 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
757 assert_eq!(&uc.attr_fgcolor(None), &Color::from_rgb(0x20, 0xf0, 0x20));
758 assert_eq!(&uc.attr_bgcolor(None), &Color::from_rgb(0x20, 0x20, 0x20));
759 assert_eq!(
760 &uc.attr_fgcolor(Some(term)),
761 &Color::from_rgb(0x20, 0xf0, 0x20)
762 );
763 assert_eq!(&uc.attr_bgcolor(None), &Color::from_rgb(0x20, 0x20, 0x20));
764 assert_eq!(
765 &uc.charflags(),
766 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
767 );
768
769 // Put a short string "BCDE" into the buffer, with fg color change after the 'B', bg change after 'C', and bold after 'D'
770 term.clear();
771 term.set_text_fg_color_xterm(XtermColor::White);
772 term.set_text_bg_color_xterm(XtermColor::Black);
773 term.set_text_attrib(Attrib::Normal);
774 assert_eq!(term.text_attrib(), Attrib::Normal);
775
776 assert!(term.ansi());
777 term.append("B\x1b[37mC\x1b[44mD\x1b[1mE\n");
778
779 let r = &term.u8c_disp_row(0);
780 let uc = r.col(0);
781 assert_eq!(uc.text_utf8(), b"B");
782 assert!(uc.is_char(b'B'));
783 assert!(!uc.is_char(b'A'));
784 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
785 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
786 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
787 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBlack);
788 assert_eq!(
789 &uc.charflags(),
790 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
791 );
792
793 let uc = r.col(1);
794 assert_eq!(uc.text_utf8(), b"C");
795 assert!(uc.is_char(b'C'));
796 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
797 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
798 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
799 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBlack);
800 assert_eq!(
801 &uc.charflags(),
802 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
803 );
804
805 let uc = r.col(2);
806 assert_eq!(uc.text_utf8(), b"D");
807 assert!(uc.is_char(b'D'));
808 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
809 assert_eq!(&uc.bgcolor(), &Color::XtermBgBlue);
810 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
811 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBgBlue);
812 assert_eq!(
813 &uc.charflags(),
814 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
815 );
816
817 let uc = r.col(3);
818 assert_eq!(uc.text_utf8(), b"E");
819 assert!(uc.is_char(b'E'));
820 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
821 assert_eq!(&uc.bgcolor(), &Color::XtermBgBlue);
822 assert_eq!(&uc.attr_fgcolor(None), &Color::from_hex(0xf0f0f0));
823 assert_eq!(&uc.attr_bgcolor(None), &Color::from_hex(0x2020e0));
824 assert_eq!(
825 &uc.charflags(),
826 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
827 );
828
829 // Test some miscellaneous Utf8 constants
830 assert_eq!(uc.length(), 1);
831 assert_eq!(uc.max_utf8(), 4);
832 assert_eq!(uc.pwidth(), 9.0);
833 assert_eq!(uc.pwidth_int(), 9);
834
835 term.set_text_fg_color_xterm(XtermColor::White);
836 term.set_text_bg_color_xterm(XtermColor::Black);
837 term.clear();
838 term.set_text_attrib(Attrib::Normal);
839
840 // Mouse selection functions
841 term.append(&format!("Mouse selection: {:?}\n", &term.get_selection()));
842 term.clear_mouse_selection();
843 assert_eq!(term.get_selection(), None);
844
845 // Play with cursor position
846 term.append("0123456789\n"); // Set up test pattern
847 term.append("ABCDEFGHIJ\n");
848 term.append("abcdefghij\n");
849
850 term.set_cursor_row(1);
851 assert_eq!(term.cursor_row(), 1);
852 term.set_cursor_col(1);
853 assert_eq!(term.cursor_col(), 1);
854 assert_eq!(term.u8c_cursor().text_utf8(), b"1");
855
856 term.append("----"); // Overwrites text at cursor and moves cursor forward
857 assert_eq!(term.cursor_row(), 1);
858 assert_eq!(term.cursor_col(), 5);
859 assert_eq!(term.u8c_cursor().text_utf8(), b"5");
860 term.set_cursor_col(1);
861 assert_eq!(term.u8c_cursor().text_utf8(), b"-"); // Overwritten text
862
863 term.cursor_up(1, false);
864 assert_eq!(term.cursor_row(), 0);
865 assert_eq!(term.cursor_col(), 1);
866 assert_eq!(term.u8c_cursor().text_utf8(), b"o");
867
868 // Hit top of screen, so nothing happens
869 term.cursor_up(1, false);
870 assert_eq!(term.cursor_row(), 0);
871 assert_eq!(term.cursor_col(), 1);
872 assert_eq!(term.u8c_cursor().text_utf8(), b"o");
873
874 // Hit top of screen with scroll enabled. A blank line from history is scrolled in.
875 term.cursor_up(1, true);
876 assert_eq!(term.cursor_row(), 0);
877 assert_eq!(term.cursor_col(), 1);
878 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
879
880 // Go back down to the overwritten text
881 term.cursor_down(2, false);
882 assert_eq!(term.cursor_row(), 2);
883 assert_eq!(term.cursor_col(), 1);
884 assert_eq!(term.u8c_cursor().text_utf8(), b"-");
885
886 // Go right past the overwritten text
887 term.cursor_right(4, false);
888 assert_eq!(term.cursor_row(), 2);
889 assert_eq!(term.cursor_col(), 5);
890 assert_eq!(term.u8c_cursor().text_utf8(), b"5");
891
892 // Go left to the end of the overwritten text
893 term.cursor_left(1);
894 assert_eq!(term.cursor_row(), 2);
895 assert_eq!(term.cursor_col(), 4);
896 assert_eq!(term.u8c_cursor().text_utf8(), b"-");
897
898 // Scroll back down, removing the blank line at the top.
899 // Cursor stays in place, the text moves under it.
900 term.scroll(1);
901 assert_eq!(term.cursor_row(), 2);
902 assert_eq!(term.cursor_col(), 4);
903 assert_eq!(term.u8c_cursor().text_utf8(), b"E");
904
905 // Clear from here to end-of-line
906 term.clear_eol();
907 assert_eq!(term.cursor_row(), 2);
908 assert_eq!(term.cursor_col(), 4);
909 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
910
911 // Now clear from here to start-of-line. Cursor does not move.
912 term.clear_sol();
913 assert_eq!(term.cursor_row(), 2);
914 assert_eq!(term.cursor_col(), 4);
915 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
916 term.cursor_left(1);
917 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
918 term.set_cursor_col(0);
919 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
920
921 // Clear some lines
922 term.clear_line(1);
923 assert_eq!(term.cursor_row(), 2);
924 assert_eq!(term.cursor_col(), 0);
925 term.set_cursor_row(1);
926 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
927 term.set_cursor_row(3);
928 term.clear_cur_line();
929 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
930 assert_eq!(term.cursor_row(), 3);
931 assert_eq!(term.cursor_col(), 0);
932
933 term.append("Two lines above are intentionally left blank.\n");
934 assert_eq!(term.cursor_row(), 4);
935 assert_eq!(term.cursor_col(), 0);
936
937 // Set up the test pattern again, then play with insert/delete
938 term.append("0123456789\n");
939 term.append("ABCDEFGHIJ\n");
940 term.append("abcdefghij\n");
941 assert_eq!(term.cursor_row(), 7);
942
943 term.set_cursor_row(4);
944 term.set_cursor_col(4);
945 assert_eq!(term.u8c_cursor().text_utf8(), b"4");
946
947 term.insert_char('x', 5); // Push this row right 5 chars starting at col 4
948 assert_eq!(term.u8c_cursor().text_utf8(), b"x");
949 term.cursor_right(5, false);
950 assert_eq!(term.cursor_col(), 9);
951 assert_eq!(term.u8c_cursor().text_utf8(), b"4");
952
953 // Insert two blank rows above cursor. Cursor stays put.
954 term.insert_rows(2);
955 assert_eq!(term.cursor_row(), 4);
956 assert_eq!(term.cursor_col(), 9);
957 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
958 term.cursor_down(2, false); // Go down to find our text again
959 assert_eq!(term.u8c_cursor().text_utf8(), b"4");
960
961 // Go back to the beginning of the inserted 'x' characters and delete them.
962 term.cursor_left(5);
963 assert_eq!(term.u8c_cursor().text_utf8(), b"x");
964 term.delete_cur_chars(5);
965 assert_eq!(term.cursor_row(), 6);
966 assert_eq!(term.cursor_col(), 4);
967 assert_eq!(term.u8c_cursor().text_utf8(), b"4");
968
969 term.delete_chars(7, 2, 2); // Delete "CD" from the next row
970 term.cursor_down(1, false);
971 term.cursor_left(2);
972 assert_eq!(term.u8c_cursor().text_utf8(), b"E");
973
974 term.delete_rows(1); // Middle row of pattern is gone, cursor stays put
975 assert_eq!(term.u8c_cursor().text_utf8(), b"c");
976 term.cursor_up(1, false);
977 term.delete_rows(2); // Delete remains of test pattern
978
979 term.set_text_attrib(Attrib::Bold);
980 term.insert_char_eol('-', 3, 15, 20);
981 term.set_cursor_row(3);
982 term.set_cursor_col(15);
983 assert_eq!(term.u8c_cursor().text_utf8(), b"-"); // Check the insertion
984 assert_eq!(term.u8c_cursor().attrib(), Attrib::Bold);
985
986 term.set_text_attrib(Attrib::Italic);
987 term.append(" and all lines below");
988 term.set_text_attrib(Attrib::Normal);
989 term.cursor_down(1, false);
990
991 let mut hsb = term.hscrollbar();
992 let mut sb = term.scrollbar();
993 hsb.set_value(100.0);
994 assert_eq!(hsb.value(), 100.0);
995 sb.set_value(50.0);
996 assert_eq!(sb.value(), 50.0);
997 hsb.set_value(0.0);
998 assert_eq!(hsb.value(), 0.0);
999 sb.set_value(0.0);
1000 assert_eq!(sb.value(), 0.0);
1001}
Sourcepub fn is_char(&self, c: u8) -> bool
pub fn is_char(&self, c: u8) -> bool
Returns true if the character text in this struct matches the given ASCII character
Examples found in repository?
699fn mb_test5_cb(_choice: &mut fltk::menu::Choice, term: &mut Terminal) {
700 term.take_focus().unwrap();
701
702 // Test the attr_fg_color and attr_bg_color methods.
703 // Put a single character 'A' into the buffer and check it
704 term.clear(); // No reset_terminal(), just clear() to preserve the mouse selection for later
705 term.set_text_bg_color(Color::TransparentBg);
706 term.set_text_fg_color(Color::XtermWhite);
707 term.append("A");
708 let r = &term.u8c_disp_row(0);
709 let uc = r.col(0);
710 assert_eq!(uc.text_utf8(), b"A");
711 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
712 assert_eq!(&uc.attr_bgcolor(None), &Color::TransparentBg);
713 assert_eq!(&uc.attr_bgcolor(Some(term)), &Color::Black);
714 assert_eq!(&uc.attr_fgcolor(Some(term)), &Color::XtermWhite);
715 assert_eq!(&uc.attrib(), &Attrib::Normal);
716
717 // Put a short string "BCD" into the first line of the buffer, with fg color change after the 'B' and bold after 'C'
718 term.clear();
719 term.set_text_fg_color_xterm(XtermColor::White);
720 term.set_text_bg_color_xterm(XtermColor::Black);
721 assert_eq!(term.text_attrib(), Attrib::Normal);
722
723 assert!(term.ansi());
724 term.append("B\x1b[32mC\x1b[1mD\n");
725
726 let r = &term.u8c_disp_row(0);
727 let uc = r.col(0);
728 assert_eq!(uc.text_utf8(), b"B");
729 assert!(uc.is_char(b'B'));
730 assert!(!uc.is_char(b'A'));
731 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
732 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
733 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
734 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBlack);
735 assert_eq!(
736 &uc.charflags(),
737 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
738 );
739
740 let uc = r.col(1);
741 assert_eq!(uc.text_utf8(), b"C");
742 assert!(uc.is_char(b'C'));
743 assert_eq!(&uc.fgcolor(), &Color::XtermGreen);
744 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
745 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermGreen);
746 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBlack);
747 assert_eq!(
748 &uc.charflags(),
749 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
750 );
751
752 let uc = r.col(2);
753 assert_eq!(uc.text_utf8(), b"D");
754 assert!(uc.is_char(b'D'));
755 assert_eq!(&uc.fgcolor(), &Color::XtermGreen);
756 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
757 assert_eq!(&uc.attr_fgcolor(None), &Color::from_rgb(0x20, 0xf0, 0x20));
758 assert_eq!(&uc.attr_bgcolor(None), &Color::from_rgb(0x20, 0x20, 0x20));
759 assert_eq!(
760 &uc.attr_fgcolor(Some(term)),
761 &Color::from_rgb(0x20, 0xf0, 0x20)
762 );
763 assert_eq!(&uc.attr_bgcolor(None), &Color::from_rgb(0x20, 0x20, 0x20));
764 assert_eq!(
765 &uc.charflags(),
766 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
767 );
768
769 // Put a short string "BCDE" into the buffer, with fg color change after the 'B', bg change after 'C', and bold after 'D'
770 term.clear();
771 term.set_text_fg_color_xterm(XtermColor::White);
772 term.set_text_bg_color_xterm(XtermColor::Black);
773 term.set_text_attrib(Attrib::Normal);
774 assert_eq!(term.text_attrib(), Attrib::Normal);
775
776 assert!(term.ansi());
777 term.append("B\x1b[37mC\x1b[44mD\x1b[1mE\n");
778
779 let r = &term.u8c_disp_row(0);
780 let uc = r.col(0);
781 assert_eq!(uc.text_utf8(), b"B");
782 assert!(uc.is_char(b'B'));
783 assert!(!uc.is_char(b'A'));
784 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
785 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
786 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
787 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBlack);
788 assert_eq!(
789 &uc.charflags(),
790 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
791 );
792
793 let uc = r.col(1);
794 assert_eq!(uc.text_utf8(), b"C");
795 assert!(uc.is_char(b'C'));
796 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
797 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
798 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
799 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBlack);
800 assert_eq!(
801 &uc.charflags(),
802 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
803 );
804
805 let uc = r.col(2);
806 assert_eq!(uc.text_utf8(), b"D");
807 assert!(uc.is_char(b'D'));
808 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
809 assert_eq!(&uc.bgcolor(), &Color::XtermBgBlue);
810 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
811 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBgBlue);
812 assert_eq!(
813 &uc.charflags(),
814 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
815 );
816
817 let uc = r.col(3);
818 assert_eq!(uc.text_utf8(), b"E");
819 assert!(uc.is_char(b'E'));
820 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
821 assert_eq!(&uc.bgcolor(), &Color::XtermBgBlue);
822 assert_eq!(&uc.attr_fgcolor(None), &Color::from_hex(0xf0f0f0));
823 assert_eq!(&uc.attr_bgcolor(None), &Color::from_hex(0x2020e0));
824 assert_eq!(
825 &uc.charflags(),
826 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
827 );
828
829 // Test some miscellaneous Utf8 constants
830 assert_eq!(uc.length(), 1);
831 assert_eq!(uc.max_utf8(), 4);
832 assert_eq!(uc.pwidth(), 9.0);
833 assert_eq!(uc.pwidth_int(), 9);
834
835 term.set_text_fg_color_xterm(XtermColor::White);
836 term.set_text_bg_color_xterm(XtermColor::Black);
837 term.clear();
838 term.set_text_attrib(Attrib::Normal);
839
840 // Mouse selection functions
841 term.append(&format!("Mouse selection: {:?}\n", &term.get_selection()));
842 term.clear_mouse_selection();
843 assert_eq!(term.get_selection(), None);
844
845 // Play with cursor position
846 term.append("0123456789\n"); // Set up test pattern
847 term.append("ABCDEFGHIJ\n");
848 term.append("abcdefghij\n");
849
850 term.set_cursor_row(1);
851 assert_eq!(term.cursor_row(), 1);
852 term.set_cursor_col(1);
853 assert_eq!(term.cursor_col(), 1);
854 assert_eq!(term.u8c_cursor().text_utf8(), b"1");
855
856 term.append("----"); // Overwrites text at cursor and moves cursor forward
857 assert_eq!(term.cursor_row(), 1);
858 assert_eq!(term.cursor_col(), 5);
859 assert_eq!(term.u8c_cursor().text_utf8(), b"5");
860 term.set_cursor_col(1);
861 assert_eq!(term.u8c_cursor().text_utf8(), b"-"); // Overwritten text
862
863 term.cursor_up(1, false);
864 assert_eq!(term.cursor_row(), 0);
865 assert_eq!(term.cursor_col(), 1);
866 assert_eq!(term.u8c_cursor().text_utf8(), b"o");
867
868 // Hit top of screen, so nothing happens
869 term.cursor_up(1, false);
870 assert_eq!(term.cursor_row(), 0);
871 assert_eq!(term.cursor_col(), 1);
872 assert_eq!(term.u8c_cursor().text_utf8(), b"o");
873
874 // Hit top of screen with scroll enabled. A blank line from history is scrolled in.
875 term.cursor_up(1, true);
876 assert_eq!(term.cursor_row(), 0);
877 assert_eq!(term.cursor_col(), 1);
878 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
879
880 // Go back down to the overwritten text
881 term.cursor_down(2, false);
882 assert_eq!(term.cursor_row(), 2);
883 assert_eq!(term.cursor_col(), 1);
884 assert_eq!(term.u8c_cursor().text_utf8(), b"-");
885
886 // Go right past the overwritten text
887 term.cursor_right(4, false);
888 assert_eq!(term.cursor_row(), 2);
889 assert_eq!(term.cursor_col(), 5);
890 assert_eq!(term.u8c_cursor().text_utf8(), b"5");
891
892 // Go left to the end of the overwritten text
893 term.cursor_left(1);
894 assert_eq!(term.cursor_row(), 2);
895 assert_eq!(term.cursor_col(), 4);
896 assert_eq!(term.u8c_cursor().text_utf8(), b"-");
897
898 // Scroll back down, removing the blank line at the top.
899 // Cursor stays in place, the text moves under it.
900 term.scroll(1);
901 assert_eq!(term.cursor_row(), 2);
902 assert_eq!(term.cursor_col(), 4);
903 assert_eq!(term.u8c_cursor().text_utf8(), b"E");
904
905 // Clear from here to end-of-line
906 term.clear_eol();
907 assert_eq!(term.cursor_row(), 2);
908 assert_eq!(term.cursor_col(), 4);
909 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
910
911 // Now clear from here to start-of-line. Cursor does not move.
912 term.clear_sol();
913 assert_eq!(term.cursor_row(), 2);
914 assert_eq!(term.cursor_col(), 4);
915 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
916 term.cursor_left(1);
917 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
918 term.set_cursor_col(0);
919 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
920
921 // Clear some lines
922 term.clear_line(1);
923 assert_eq!(term.cursor_row(), 2);
924 assert_eq!(term.cursor_col(), 0);
925 term.set_cursor_row(1);
926 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
927 term.set_cursor_row(3);
928 term.clear_cur_line();
929 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
930 assert_eq!(term.cursor_row(), 3);
931 assert_eq!(term.cursor_col(), 0);
932
933 term.append("Two lines above are intentionally left blank.\n");
934 assert_eq!(term.cursor_row(), 4);
935 assert_eq!(term.cursor_col(), 0);
936
937 // Set up the test pattern again, then play with insert/delete
938 term.append("0123456789\n");
939 term.append("ABCDEFGHIJ\n");
940 term.append("abcdefghij\n");
941 assert_eq!(term.cursor_row(), 7);
942
943 term.set_cursor_row(4);
944 term.set_cursor_col(4);
945 assert_eq!(term.u8c_cursor().text_utf8(), b"4");
946
947 term.insert_char('x', 5); // Push this row right 5 chars starting at col 4
948 assert_eq!(term.u8c_cursor().text_utf8(), b"x");
949 term.cursor_right(5, false);
950 assert_eq!(term.cursor_col(), 9);
951 assert_eq!(term.u8c_cursor().text_utf8(), b"4");
952
953 // Insert two blank rows above cursor. Cursor stays put.
954 term.insert_rows(2);
955 assert_eq!(term.cursor_row(), 4);
956 assert_eq!(term.cursor_col(), 9);
957 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
958 term.cursor_down(2, false); // Go down to find our text again
959 assert_eq!(term.u8c_cursor().text_utf8(), b"4");
960
961 // Go back to the beginning of the inserted 'x' characters and delete them.
962 term.cursor_left(5);
963 assert_eq!(term.u8c_cursor().text_utf8(), b"x");
964 term.delete_cur_chars(5);
965 assert_eq!(term.cursor_row(), 6);
966 assert_eq!(term.cursor_col(), 4);
967 assert_eq!(term.u8c_cursor().text_utf8(), b"4");
968
969 term.delete_chars(7, 2, 2); // Delete "CD" from the next row
970 term.cursor_down(1, false);
971 term.cursor_left(2);
972 assert_eq!(term.u8c_cursor().text_utf8(), b"E");
973
974 term.delete_rows(1); // Middle row of pattern is gone, cursor stays put
975 assert_eq!(term.u8c_cursor().text_utf8(), b"c");
976 term.cursor_up(1, false);
977 term.delete_rows(2); // Delete remains of test pattern
978
979 term.set_text_attrib(Attrib::Bold);
980 term.insert_char_eol('-', 3, 15, 20);
981 term.set_cursor_row(3);
982 term.set_cursor_col(15);
983 assert_eq!(term.u8c_cursor().text_utf8(), b"-"); // Check the insertion
984 assert_eq!(term.u8c_cursor().attrib(), Attrib::Bold);
985
986 term.set_text_attrib(Attrib::Italic);
987 term.append(" and all lines below");
988 term.set_text_attrib(Attrib::Normal);
989 term.cursor_down(1, false);
990
991 let mut hsb = term.hscrollbar();
992 let mut sb = term.scrollbar();
993 hsb.set_value(100.0);
994 assert_eq!(hsb.value(), 100.0);
995 sb.set_value(50.0);
996 assert_eq!(sb.value(), 50.0);
997 hsb.set_value(0.0);
998 assert_eq!(hsb.value(), 0.0);
999 sb.set_value(0.0);
1000 assert_eq!(sb.value(), 0.0);
1001}
Sourcepub fn length(&self) -> usize
pub fn length(&self) -> usize
Return the length of this character in bytes (UTF-8 can be multibyte)
Examples found in repository?
699fn mb_test5_cb(_choice: &mut fltk::menu::Choice, term: &mut Terminal) {
700 term.take_focus().unwrap();
701
702 // Test the attr_fg_color and attr_bg_color methods.
703 // Put a single character 'A' into the buffer and check it
704 term.clear(); // No reset_terminal(), just clear() to preserve the mouse selection for later
705 term.set_text_bg_color(Color::TransparentBg);
706 term.set_text_fg_color(Color::XtermWhite);
707 term.append("A");
708 let r = &term.u8c_disp_row(0);
709 let uc = r.col(0);
710 assert_eq!(uc.text_utf8(), b"A");
711 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
712 assert_eq!(&uc.attr_bgcolor(None), &Color::TransparentBg);
713 assert_eq!(&uc.attr_bgcolor(Some(term)), &Color::Black);
714 assert_eq!(&uc.attr_fgcolor(Some(term)), &Color::XtermWhite);
715 assert_eq!(&uc.attrib(), &Attrib::Normal);
716
717 // Put a short string "BCD" into the first line of the buffer, with fg color change after the 'B' and bold after 'C'
718 term.clear();
719 term.set_text_fg_color_xterm(XtermColor::White);
720 term.set_text_bg_color_xterm(XtermColor::Black);
721 assert_eq!(term.text_attrib(), Attrib::Normal);
722
723 assert!(term.ansi());
724 term.append("B\x1b[32mC\x1b[1mD\n");
725
726 let r = &term.u8c_disp_row(0);
727 let uc = r.col(0);
728 assert_eq!(uc.text_utf8(), b"B");
729 assert!(uc.is_char(b'B'));
730 assert!(!uc.is_char(b'A'));
731 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
732 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
733 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
734 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBlack);
735 assert_eq!(
736 &uc.charflags(),
737 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
738 );
739
740 let uc = r.col(1);
741 assert_eq!(uc.text_utf8(), b"C");
742 assert!(uc.is_char(b'C'));
743 assert_eq!(&uc.fgcolor(), &Color::XtermGreen);
744 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
745 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermGreen);
746 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBlack);
747 assert_eq!(
748 &uc.charflags(),
749 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
750 );
751
752 let uc = r.col(2);
753 assert_eq!(uc.text_utf8(), b"D");
754 assert!(uc.is_char(b'D'));
755 assert_eq!(&uc.fgcolor(), &Color::XtermGreen);
756 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
757 assert_eq!(&uc.attr_fgcolor(None), &Color::from_rgb(0x20, 0xf0, 0x20));
758 assert_eq!(&uc.attr_bgcolor(None), &Color::from_rgb(0x20, 0x20, 0x20));
759 assert_eq!(
760 &uc.attr_fgcolor(Some(term)),
761 &Color::from_rgb(0x20, 0xf0, 0x20)
762 );
763 assert_eq!(&uc.attr_bgcolor(None), &Color::from_rgb(0x20, 0x20, 0x20));
764 assert_eq!(
765 &uc.charflags(),
766 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
767 );
768
769 // Put a short string "BCDE" into the buffer, with fg color change after the 'B', bg change after 'C', and bold after 'D'
770 term.clear();
771 term.set_text_fg_color_xterm(XtermColor::White);
772 term.set_text_bg_color_xterm(XtermColor::Black);
773 term.set_text_attrib(Attrib::Normal);
774 assert_eq!(term.text_attrib(), Attrib::Normal);
775
776 assert!(term.ansi());
777 term.append("B\x1b[37mC\x1b[44mD\x1b[1mE\n");
778
779 let r = &term.u8c_disp_row(0);
780 let uc = r.col(0);
781 assert_eq!(uc.text_utf8(), b"B");
782 assert!(uc.is_char(b'B'));
783 assert!(!uc.is_char(b'A'));
784 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
785 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
786 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
787 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBlack);
788 assert_eq!(
789 &uc.charflags(),
790 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
791 );
792
793 let uc = r.col(1);
794 assert_eq!(uc.text_utf8(), b"C");
795 assert!(uc.is_char(b'C'));
796 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
797 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
798 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
799 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBlack);
800 assert_eq!(
801 &uc.charflags(),
802 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
803 );
804
805 let uc = r.col(2);
806 assert_eq!(uc.text_utf8(), b"D");
807 assert!(uc.is_char(b'D'));
808 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
809 assert_eq!(&uc.bgcolor(), &Color::XtermBgBlue);
810 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
811 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBgBlue);
812 assert_eq!(
813 &uc.charflags(),
814 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
815 );
816
817 let uc = r.col(3);
818 assert_eq!(uc.text_utf8(), b"E");
819 assert!(uc.is_char(b'E'));
820 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
821 assert_eq!(&uc.bgcolor(), &Color::XtermBgBlue);
822 assert_eq!(&uc.attr_fgcolor(None), &Color::from_hex(0xf0f0f0));
823 assert_eq!(&uc.attr_bgcolor(None), &Color::from_hex(0x2020e0));
824 assert_eq!(
825 &uc.charflags(),
826 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
827 );
828
829 // Test some miscellaneous Utf8 constants
830 assert_eq!(uc.length(), 1);
831 assert_eq!(uc.max_utf8(), 4);
832 assert_eq!(uc.pwidth(), 9.0);
833 assert_eq!(uc.pwidth_int(), 9);
834
835 term.set_text_fg_color_xterm(XtermColor::White);
836 term.set_text_bg_color_xterm(XtermColor::Black);
837 term.clear();
838 term.set_text_attrib(Attrib::Normal);
839
840 // Mouse selection functions
841 term.append(&format!("Mouse selection: {:?}\n", &term.get_selection()));
842 term.clear_mouse_selection();
843 assert_eq!(term.get_selection(), None);
844
845 // Play with cursor position
846 term.append("0123456789\n"); // Set up test pattern
847 term.append("ABCDEFGHIJ\n");
848 term.append("abcdefghij\n");
849
850 term.set_cursor_row(1);
851 assert_eq!(term.cursor_row(), 1);
852 term.set_cursor_col(1);
853 assert_eq!(term.cursor_col(), 1);
854 assert_eq!(term.u8c_cursor().text_utf8(), b"1");
855
856 term.append("----"); // Overwrites text at cursor and moves cursor forward
857 assert_eq!(term.cursor_row(), 1);
858 assert_eq!(term.cursor_col(), 5);
859 assert_eq!(term.u8c_cursor().text_utf8(), b"5");
860 term.set_cursor_col(1);
861 assert_eq!(term.u8c_cursor().text_utf8(), b"-"); // Overwritten text
862
863 term.cursor_up(1, false);
864 assert_eq!(term.cursor_row(), 0);
865 assert_eq!(term.cursor_col(), 1);
866 assert_eq!(term.u8c_cursor().text_utf8(), b"o");
867
868 // Hit top of screen, so nothing happens
869 term.cursor_up(1, false);
870 assert_eq!(term.cursor_row(), 0);
871 assert_eq!(term.cursor_col(), 1);
872 assert_eq!(term.u8c_cursor().text_utf8(), b"o");
873
874 // Hit top of screen with scroll enabled. A blank line from history is scrolled in.
875 term.cursor_up(1, true);
876 assert_eq!(term.cursor_row(), 0);
877 assert_eq!(term.cursor_col(), 1);
878 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
879
880 // Go back down to the overwritten text
881 term.cursor_down(2, false);
882 assert_eq!(term.cursor_row(), 2);
883 assert_eq!(term.cursor_col(), 1);
884 assert_eq!(term.u8c_cursor().text_utf8(), b"-");
885
886 // Go right past the overwritten text
887 term.cursor_right(4, false);
888 assert_eq!(term.cursor_row(), 2);
889 assert_eq!(term.cursor_col(), 5);
890 assert_eq!(term.u8c_cursor().text_utf8(), b"5");
891
892 // Go left to the end of the overwritten text
893 term.cursor_left(1);
894 assert_eq!(term.cursor_row(), 2);
895 assert_eq!(term.cursor_col(), 4);
896 assert_eq!(term.u8c_cursor().text_utf8(), b"-");
897
898 // Scroll back down, removing the blank line at the top.
899 // Cursor stays in place, the text moves under it.
900 term.scroll(1);
901 assert_eq!(term.cursor_row(), 2);
902 assert_eq!(term.cursor_col(), 4);
903 assert_eq!(term.u8c_cursor().text_utf8(), b"E");
904
905 // Clear from here to end-of-line
906 term.clear_eol();
907 assert_eq!(term.cursor_row(), 2);
908 assert_eq!(term.cursor_col(), 4);
909 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
910
911 // Now clear from here to start-of-line. Cursor does not move.
912 term.clear_sol();
913 assert_eq!(term.cursor_row(), 2);
914 assert_eq!(term.cursor_col(), 4);
915 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
916 term.cursor_left(1);
917 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
918 term.set_cursor_col(0);
919 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
920
921 // Clear some lines
922 term.clear_line(1);
923 assert_eq!(term.cursor_row(), 2);
924 assert_eq!(term.cursor_col(), 0);
925 term.set_cursor_row(1);
926 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
927 term.set_cursor_row(3);
928 term.clear_cur_line();
929 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
930 assert_eq!(term.cursor_row(), 3);
931 assert_eq!(term.cursor_col(), 0);
932
933 term.append("Two lines above are intentionally left blank.\n");
934 assert_eq!(term.cursor_row(), 4);
935 assert_eq!(term.cursor_col(), 0);
936
937 // Set up the test pattern again, then play with insert/delete
938 term.append("0123456789\n");
939 term.append("ABCDEFGHIJ\n");
940 term.append("abcdefghij\n");
941 assert_eq!(term.cursor_row(), 7);
942
943 term.set_cursor_row(4);
944 term.set_cursor_col(4);
945 assert_eq!(term.u8c_cursor().text_utf8(), b"4");
946
947 term.insert_char('x', 5); // Push this row right 5 chars starting at col 4
948 assert_eq!(term.u8c_cursor().text_utf8(), b"x");
949 term.cursor_right(5, false);
950 assert_eq!(term.cursor_col(), 9);
951 assert_eq!(term.u8c_cursor().text_utf8(), b"4");
952
953 // Insert two blank rows above cursor. Cursor stays put.
954 term.insert_rows(2);
955 assert_eq!(term.cursor_row(), 4);
956 assert_eq!(term.cursor_col(), 9);
957 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
958 term.cursor_down(2, false); // Go down to find our text again
959 assert_eq!(term.u8c_cursor().text_utf8(), b"4");
960
961 // Go back to the beginning of the inserted 'x' characters and delete them.
962 term.cursor_left(5);
963 assert_eq!(term.u8c_cursor().text_utf8(), b"x");
964 term.delete_cur_chars(5);
965 assert_eq!(term.cursor_row(), 6);
966 assert_eq!(term.cursor_col(), 4);
967 assert_eq!(term.u8c_cursor().text_utf8(), b"4");
968
969 term.delete_chars(7, 2, 2); // Delete "CD" from the next row
970 term.cursor_down(1, false);
971 term.cursor_left(2);
972 assert_eq!(term.u8c_cursor().text_utf8(), b"E");
973
974 term.delete_rows(1); // Middle row of pattern is gone, cursor stays put
975 assert_eq!(term.u8c_cursor().text_utf8(), b"c");
976 term.cursor_up(1, false);
977 term.delete_rows(2); // Delete remains of test pattern
978
979 term.set_text_attrib(Attrib::Bold);
980 term.insert_char_eol('-', 3, 15, 20);
981 term.set_cursor_row(3);
982 term.set_cursor_col(15);
983 assert_eq!(term.u8c_cursor().text_utf8(), b"-"); // Check the insertion
984 assert_eq!(term.u8c_cursor().attrib(), Attrib::Bold);
985
986 term.set_text_attrib(Attrib::Italic);
987 term.append(" and all lines below");
988 term.set_text_attrib(Attrib::Normal);
989 term.cursor_down(1, false);
990
991 let mut hsb = term.hscrollbar();
992 let mut sb = term.scrollbar();
993 hsb.set_value(100.0);
994 assert_eq!(hsb.value(), 100.0);
995 sb.set_value(50.0);
996 assert_eq!(sb.value(), 50.0);
997 hsb.set_value(0.0);
998 assert_eq!(hsb.value(), 0.0);
999 sb.set_value(0.0);
1000 assert_eq!(sb.value(), 0.0);
1001}
Sourcepub fn max_utf8(&self) -> usize
pub fn max_utf8(&self) -> usize
Return the maximum length in bytes of a UTF-8 character
Examples found in repository?
699fn mb_test5_cb(_choice: &mut fltk::menu::Choice, term: &mut Terminal) {
700 term.take_focus().unwrap();
701
702 // Test the attr_fg_color and attr_bg_color methods.
703 // Put a single character 'A' into the buffer and check it
704 term.clear(); // No reset_terminal(), just clear() to preserve the mouse selection for later
705 term.set_text_bg_color(Color::TransparentBg);
706 term.set_text_fg_color(Color::XtermWhite);
707 term.append("A");
708 let r = &term.u8c_disp_row(0);
709 let uc = r.col(0);
710 assert_eq!(uc.text_utf8(), b"A");
711 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
712 assert_eq!(&uc.attr_bgcolor(None), &Color::TransparentBg);
713 assert_eq!(&uc.attr_bgcolor(Some(term)), &Color::Black);
714 assert_eq!(&uc.attr_fgcolor(Some(term)), &Color::XtermWhite);
715 assert_eq!(&uc.attrib(), &Attrib::Normal);
716
717 // Put a short string "BCD" into the first line of the buffer, with fg color change after the 'B' and bold after 'C'
718 term.clear();
719 term.set_text_fg_color_xterm(XtermColor::White);
720 term.set_text_bg_color_xterm(XtermColor::Black);
721 assert_eq!(term.text_attrib(), Attrib::Normal);
722
723 assert!(term.ansi());
724 term.append("B\x1b[32mC\x1b[1mD\n");
725
726 let r = &term.u8c_disp_row(0);
727 let uc = r.col(0);
728 assert_eq!(uc.text_utf8(), b"B");
729 assert!(uc.is_char(b'B'));
730 assert!(!uc.is_char(b'A'));
731 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
732 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
733 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
734 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBlack);
735 assert_eq!(
736 &uc.charflags(),
737 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
738 );
739
740 let uc = r.col(1);
741 assert_eq!(uc.text_utf8(), b"C");
742 assert!(uc.is_char(b'C'));
743 assert_eq!(&uc.fgcolor(), &Color::XtermGreen);
744 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
745 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermGreen);
746 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBlack);
747 assert_eq!(
748 &uc.charflags(),
749 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
750 );
751
752 let uc = r.col(2);
753 assert_eq!(uc.text_utf8(), b"D");
754 assert!(uc.is_char(b'D'));
755 assert_eq!(&uc.fgcolor(), &Color::XtermGreen);
756 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
757 assert_eq!(&uc.attr_fgcolor(None), &Color::from_rgb(0x20, 0xf0, 0x20));
758 assert_eq!(&uc.attr_bgcolor(None), &Color::from_rgb(0x20, 0x20, 0x20));
759 assert_eq!(
760 &uc.attr_fgcolor(Some(term)),
761 &Color::from_rgb(0x20, 0xf0, 0x20)
762 );
763 assert_eq!(&uc.attr_bgcolor(None), &Color::from_rgb(0x20, 0x20, 0x20));
764 assert_eq!(
765 &uc.charflags(),
766 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
767 );
768
769 // Put a short string "BCDE" into the buffer, with fg color change after the 'B', bg change after 'C', and bold after 'D'
770 term.clear();
771 term.set_text_fg_color_xterm(XtermColor::White);
772 term.set_text_bg_color_xterm(XtermColor::Black);
773 term.set_text_attrib(Attrib::Normal);
774 assert_eq!(term.text_attrib(), Attrib::Normal);
775
776 assert!(term.ansi());
777 term.append("B\x1b[37mC\x1b[44mD\x1b[1mE\n");
778
779 let r = &term.u8c_disp_row(0);
780 let uc = r.col(0);
781 assert_eq!(uc.text_utf8(), b"B");
782 assert!(uc.is_char(b'B'));
783 assert!(!uc.is_char(b'A'));
784 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
785 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
786 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
787 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBlack);
788 assert_eq!(
789 &uc.charflags(),
790 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
791 );
792
793 let uc = r.col(1);
794 assert_eq!(uc.text_utf8(), b"C");
795 assert!(uc.is_char(b'C'));
796 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
797 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
798 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
799 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBlack);
800 assert_eq!(
801 &uc.charflags(),
802 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
803 );
804
805 let uc = r.col(2);
806 assert_eq!(uc.text_utf8(), b"D");
807 assert!(uc.is_char(b'D'));
808 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
809 assert_eq!(&uc.bgcolor(), &Color::XtermBgBlue);
810 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
811 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBgBlue);
812 assert_eq!(
813 &uc.charflags(),
814 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
815 );
816
817 let uc = r.col(3);
818 assert_eq!(uc.text_utf8(), b"E");
819 assert!(uc.is_char(b'E'));
820 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
821 assert_eq!(&uc.bgcolor(), &Color::XtermBgBlue);
822 assert_eq!(&uc.attr_fgcolor(None), &Color::from_hex(0xf0f0f0));
823 assert_eq!(&uc.attr_bgcolor(None), &Color::from_hex(0x2020e0));
824 assert_eq!(
825 &uc.charflags(),
826 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
827 );
828
829 // Test some miscellaneous Utf8 constants
830 assert_eq!(uc.length(), 1);
831 assert_eq!(uc.max_utf8(), 4);
832 assert_eq!(uc.pwidth(), 9.0);
833 assert_eq!(uc.pwidth_int(), 9);
834
835 term.set_text_fg_color_xterm(XtermColor::White);
836 term.set_text_bg_color_xterm(XtermColor::Black);
837 term.clear();
838 term.set_text_attrib(Attrib::Normal);
839
840 // Mouse selection functions
841 term.append(&format!("Mouse selection: {:?}\n", &term.get_selection()));
842 term.clear_mouse_selection();
843 assert_eq!(term.get_selection(), None);
844
845 // Play with cursor position
846 term.append("0123456789\n"); // Set up test pattern
847 term.append("ABCDEFGHIJ\n");
848 term.append("abcdefghij\n");
849
850 term.set_cursor_row(1);
851 assert_eq!(term.cursor_row(), 1);
852 term.set_cursor_col(1);
853 assert_eq!(term.cursor_col(), 1);
854 assert_eq!(term.u8c_cursor().text_utf8(), b"1");
855
856 term.append("----"); // Overwrites text at cursor and moves cursor forward
857 assert_eq!(term.cursor_row(), 1);
858 assert_eq!(term.cursor_col(), 5);
859 assert_eq!(term.u8c_cursor().text_utf8(), b"5");
860 term.set_cursor_col(1);
861 assert_eq!(term.u8c_cursor().text_utf8(), b"-"); // Overwritten text
862
863 term.cursor_up(1, false);
864 assert_eq!(term.cursor_row(), 0);
865 assert_eq!(term.cursor_col(), 1);
866 assert_eq!(term.u8c_cursor().text_utf8(), b"o");
867
868 // Hit top of screen, so nothing happens
869 term.cursor_up(1, false);
870 assert_eq!(term.cursor_row(), 0);
871 assert_eq!(term.cursor_col(), 1);
872 assert_eq!(term.u8c_cursor().text_utf8(), b"o");
873
874 // Hit top of screen with scroll enabled. A blank line from history is scrolled in.
875 term.cursor_up(1, true);
876 assert_eq!(term.cursor_row(), 0);
877 assert_eq!(term.cursor_col(), 1);
878 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
879
880 // Go back down to the overwritten text
881 term.cursor_down(2, false);
882 assert_eq!(term.cursor_row(), 2);
883 assert_eq!(term.cursor_col(), 1);
884 assert_eq!(term.u8c_cursor().text_utf8(), b"-");
885
886 // Go right past the overwritten text
887 term.cursor_right(4, false);
888 assert_eq!(term.cursor_row(), 2);
889 assert_eq!(term.cursor_col(), 5);
890 assert_eq!(term.u8c_cursor().text_utf8(), b"5");
891
892 // Go left to the end of the overwritten text
893 term.cursor_left(1);
894 assert_eq!(term.cursor_row(), 2);
895 assert_eq!(term.cursor_col(), 4);
896 assert_eq!(term.u8c_cursor().text_utf8(), b"-");
897
898 // Scroll back down, removing the blank line at the top.
899 // Cursor stays in place, the text moves under it.
900 term.scroll(1);
901 assert_eq!(term.cursor_row(), 2);
902 assert_eq!(term.cursor_col(), 4);
903 assert_eq!(term.u8c_cursor().text_utf8(), b"E");
904
905 // Clear from here to end-of-line
906 term.clear_eol();
907 assert_eq!(term.cursor_row(), 2);
908 assert_eq!(term.cursor_col(), 4);
909 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
910
911 // Now clear from here to start-of-line. Cursor does not move.
912 term.clear_sol();
913 assert_eq!(term.cursor_row(), 2);
914 assert_eq!(term.cursor_col(), 4);
915 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
916 term.cursor_left(1);
917 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
918 term.set_cursor_col(0);
919 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
920
921 // Clear some lines
922 term.clear_line(1);
923 assert_eq!(term.cursor_row(), 2);
924 assert_eq!(term.cursor_col(), 0);
925 term.set_cursor_row(1);
926 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
927 term.set_cursor_row(3);
928 term.clear_cur_line();
929 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
930 assert_eq!(term.cursor_row(), 3);
931 assert_eq!(term.cursor_col(), 0);
932
933 term.append("Two lines above are intentionally left blank.\n");
934 assert_eq!(term.cursor_row(), 4);
935 assert_eq!(term.cursor_col(), 0);
936
937 // Set up the test pattern again, then play with insert/delete
938 term.append("0123456789\n");
939 term.append("ABCDEFGHIJ\n");
940 term.append("abcdefghij\n");
941 assert_eq!(term.cursor_row(), 7);
942
943 term.set_cursor_row(4);
944 term.set_cursor_col(4);
945 assert_eq!(term.u8c_cursor().text_utf8(), b"4");
946
947 term.insert_char('x', 5); // Push this row right 5 chars starting at col 4
948 assert_eq!(term.u8c_cursor().text_utf8(), b"x");
949 term.cursor_right(5, false);
950 assert_eq!(term.cursor_col(), 9);
951 assert_eq!(term.u8c_cursor().text_utf8(), b"4");
952
953 // Insert two blank rows above cursor. Cursor stays put.
954 term.insert_rows(2);
955 assert_eq!(term.cursor_row(), 4);
956 assert_eq!(term.cursor_col(), 9);
957 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
958 term.cursor_down(2, false); // Go down to find our text again
959 assert_eq!(term.u8c_cursor().text_utf8(), b"4");
960
961 // Go back to the beginning of the inserted 'x' characters and delete them.
962 term.cursor_left(5);
963 assert_eq!(term.u8c_cursor().text_utf8(), b"x");
964 term.delete_cur_chars(5);
965 assert_eq!(term.cursor_row(), 6);
966 assert_eq!(term.cursor_col(), 4);
967 assert_eq!(term.u8c_cursor().text_utf8(), b"4");
968
969 term.delete_chars(7, 2, 2); // Delete "CD" from the next row
970 term.cursor_down(1, false);
971 term.cursor_left(2);
972 assert_eq!(term.u8c_cursor().text_utf8(), b"E");
973
974 term.delete_rows(1); // Middle row of pattern is gone, cursor stays put
975 assert_eq!(term.u8c_cursor().text_utf8(), b"c");
976 term.cursor_up(1, false);
977 term.delete_rows(2); // Delete remains of test pattern
978
979 term.set_text_attrib(Attrib::Bold);
980 term.insert_char_eol('-', 3, 15, 20);
981 term.set_cursor_row(3);
982 term.set_cursor_col(15);
983 assert_eq!(term.u8c_cursor().text_utf8(), b"-"); // Check the insertion
984 assert_eq!(term.u8c_cursor().attrib(), Attrib::Bold);
985
986 term.set_text_attrib(Attrib::Italic);
987 term.append(" and all lines below");
988 term.set_text_attrib(Attrib::Normal);
989 term.cursor_down(1, false);
990
991 let mut hsb = term.hscrollbar();
992 let mut sb = term.scrollbar();
993 hsb.set_value(100.0);
994 assert_eq!(hsb.value(), 100.0);
995 sb.set_value(50.0);
996 assert_eq!(sb.value(), 50.0);
997 hsb.set_value(0.0);
998 assert_eq!(hsb.value(), 0.0);
999 sb.set_value(0.0);
1000 assert_eq!(sb.value(), 0.0);
1001}
Sourcepub fn pwidth(&self) -> f64
pub fn pwidth(&self) -> f64
Return the width of this character in floating point pixels.
WARNING: Uses current font, so assumes font and font_size
have already been set to current font!
Examples found in repository?
699fn mb_test5_cb(_choice: &mut fltk::menu::Choice, term: &mut Terminal) {
700 term.take_focus().unwrap();
701
702 // Test the attr_fg_color and attr_bg_color methods.
703 // Put a single character 'A' into the buffer and check it
704 term.clear(); // No reset_terminal(), just clear() to preserve the mouse selection for later
705 term.set_text_bg_color(Color::TransparentBg);
706 term.set_text_fg_color(Color::XtermWhite);
707 term.append("A");
708 let r = &term.u8c_disp_row(0);
709 let uc = r.col(0);
710 assert_eq!(uc.text_utf8(), b"A");
711 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
712 assert_eq!(&uc.attr_bgcolor(None), &Color::TransparentBg);
713 assert_eq!(&uc.attr_bgcolor(Some(term)), &Color::Black);
714 assert_eq!(&uc.attr_fgcolor(Some(term)), &Color::XtermWhite);
715 assert_eq!(&uc.attrib(), &Attrib::Normal);
716
717 // Put a short string "BCD" into the first line of the buffer, with fg color change after the 'B' and bold after 'C'
718 term.clear();
719 term.set_text_fg_color_xterm(XtermColor::White);
720 term.set_text_bg_color_xterm(XtermColor::Black);
721 assert_eq!(term.text_attrib(), Attrib::Normal);
722
723 assert!(term.ansi());
724 term.append("B\x1b[32mC\x1b[1mD\n");
725
726 let r = &term.u8c_disp_row(0);
727 let uc = r.col(0);
728 assert_eq!(uc.text_utf8(), b"B");
729 assert!(uc.is_char(b'B'));
730 assert!(!uc.is_char(b'A'));
731 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
732 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
733 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
734 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBlack);
735 assert_eq!(
736 &uc.charflags(),
737 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
738 );
739
740 let uc = r.col(1);
741 assert_eq!(uc.text_utf8(), b"C");
742 assert!(uc.is_char(b'C'));
743 assert_eq!(&uc.fgcolor(), &Color::XtermGreen);
744 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
745 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermGreen);
746 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBlack);
747 assert_eq!(
748 &uc.charflags(),
749 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
750 );
751
752 let uc = r.col(2);
753 assert_eq!(uc.text_utf8(), b"D");
754 assert!(uc.is_char(b'D'));
755 assert_eq!(&uc.fgcolor(), &Color::XtermGreen);
756 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
757 assert_eq!(&uc.attr_fgcolor(None), &Color::from_rgb(0x20, 0xf0, 0x20));
758 assert_eq!(&uc.attr_bgcolor(None), &Color::from_rgb(0x20, 0x20, 0x20));
759 assert_eq!(
760 &uc.attr_fgcolor(Some(term)),
761 &Color::from_rgb(0x20, 0xf0, 0x20)
762 );
763 assert_eq!(&uc.attr_bgcolor(None), &Color::from_rgb(0x20, 0x20, 0x20));
764 assert_eq!(
765 &uc.charflags(),
766 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
767 );
768
769 // Put a short string "BCDE" into the buffer, with fg color change after the 'B', bg change after 'C', and bold after 'D'
770 term.clear();
771 term.set_text_fg_color_xterm(XtermColor::White);
772 term.set_text_bg_color_xterm(XtermColor::Black);
773 term.set_text_attrib(Attrib::Normal);
774 assert_eq!(term.text_attrib(), Attrib::Normal);
775
776 assert!(term.ansi());
777 term.append("B\x1b[37mC\x1b[44mD\x1b[1mE\n");
778
779 let r = &term.u8c_disp_row(0);
780 let uc = r.col(0);
781 assert_eq!(uc.text_utf8(), b"B");
782 assert!(uc.is_char(b'B'));
783 assert!(!uc.is_char(b'A'));
784 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
785 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
786 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
787 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBlack);
788 assert_eq!(
789 &uc.charflags(),
790 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
791 );
792
793 let uc = r.col(1);
794 assert_eq!(uc.text_utf8(), b"C");
795 assert!(uc.is_char(b'C'));
796 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
797 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
798 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
799 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBlack);
800 assert_eq!(
801 &uc.charflags(),
802 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
803 );
804
805 let uc = r.col(2);
806 assert_eq!(uc.text_utf8(), b"D");
807 assert!(uc.is_char(b'D'));
808 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
809 assert_eq!(&uc.bgcolor(), &Color::XtermBgBlue);
810 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
811 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBgBlue);
812 assert_eq!(
813 &uc.charflags(),
814 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
815 );
816
817 let uc = r.col(3);
818 assert_eq!(uc.text_utf8(), b"E");
819 assert!(uc.is_char(b'E'));
820 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
821 assert_eq!(&uc.bgcolor(), &Color::XtermBgBlue);
822 assert_eq!(&uc.attr_fgcolor(None), &Color::from_hex(0xf0f0f0));
823 assert_eq!(&uc.attr_bgcolor(None), &Color::from_hex(0x2020e0));
824 assert_eq!(
825 &uc.charflags(),
826 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
827 );
828
829 // Test some miscellaneous Utf8 constants
830 assert_eq!(uc.length(), 1);
831 assert_eq!(uc.max_utf8(), 4);
832 assert_eq!(uc.pwidth(), 9.0);
833 assert_eq!(uc.pwidth_int(), 9);
834
835 term.set_text_fg_color_xterm(XtermColor::White);
836 term.set_text_bg_color_xterm(XtermColor::Black);
837 term.clear();
838 term.set_text_attrib(Attrib::Normal);
839
840 // Mouse selection functions
841 term.append(&format!("Mouse selection: {:?}\n", &term.get_selection()));
842 term.clear_mouse_selection();
843 assert_eq!(term.get_selection(), None);
844
845 // Play with cursor position
846 term.append("0123456789\n"); // Set up test pattern
847 term.append("ABCDEFGHIJ\n");
848 term.append("abcdefghij\n");
849
850 term.set_cursor_row(1);
851 assert_eq!(term.cursor_row(), 1);
852 term.set_cursor_col(1);
853 assert_eq!(term.cursor_col(), 1);
854 assert_eq!(term.u8c_cursor().text_utf8(), b"1");
855
856 term.append("----"); // Overwrites text at cursor and moves cursor forward
857 assert_eq!(term.cursor_row(), 1);
858 assert_eq!(term.cursor_col(), 5);
859 assert_eq!(term.u8c_cursor().text_utf8(), b"5");
860 term.set_cursor_col(1);
861 assert_eq!(term.u8c_cursor().text_utf8(), b"-"); // Overwritten text
862
863 term.cursor_up(1, false);
864 assert_eq!(term.cursor_row(), 0);
865 assert_eq!(term.cursor_col(), 1);
866 assert_eq!(term.u8c_cursor().text_utf8(), b"o");
867
868 // Hit top of screen, so nothing happens
869 term.cursor_up(1, false);
870 assert_eq!(term.cursor_row(), 0);
871 assert_eq!(term.cursor_col(), 1);
872 assert_eq!(term.u8c_cursor().text_utf8(), b"o");
873
874 // Hit top of screen with scroll enabled. A blank line from history is scrolled in.
875 term.cursor_up(1, true);
876 assert_eq!(term.cursor_row(), 0);
877 assert_eq!(term.cursor_col(), 1);
878 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
879
880 // Go back down to the overwritten text
881 term.cursor_down(2, false);
882 assert_eq!(term.cursor_row(), 2);
883 assert_eq!(term.cursor_col(), 1);
884 assert_eq!(term.u8c_cursor().text_utf8(), b"-");
885
886 // Go right past the overwritten text
887 term.cursor_right(4, false);
888 assert_eq!(term.cursor_row(), 2);
889 assert_eq!(term.cursor_col(), 5);
890 assert_eq!(term.u8c_cursor().text_utf8(), b"5");
891
892 // Go left to the end of the overwritten text
893 term.cursor_left(1);
894 assert_eq!(term.cursor_row(), 2);
895 assert_eq!(term.cursor_col(), 4);
896 assert_eq!(term.u8c_cursor().text_utf8(), b"-");
897
898 // Scroll back down, removing the blank line at the top.
899 // Cursor stays in place, the text moves under it.
900 term.scroll(1);
901 assert_eq!(term.cursor_row(), 2);
902 assert_eq!(term.cursor_col(), 4);
903 assert_eq!(term.u8c_cursor().text_utf8(), b"E");
904
905 // Clear from here to end-of-line
906 term.clear_eol();
907 assert_eq!(term.cursor_row(), 2);
908 assert_eq!(term.cursor_col(), 4);
909 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
910
911 // Now clear from here to start-of-line. Cursor does not move.
912 term.clear_sol();
913 assert_eq!(term.cursor_row(), 2);
914 assert_eq!(term.cursor_col(), 4);
915 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
916 term.cursor_left(1);
917 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
918 term.set_cursor_col(0);
919 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
920
921 // Clear some lines
922 term.clear_line(1);
923 assert_eq!(term.cursor_row(), 2);
924 assert_eq!(term.cursor_col(), 0);
925 term.set_cursor_row(1);
926 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
927 term.set_cursor_row(3);
928 term.clear_cur_line();
929 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
930 assert_eq!(term.cursor_row(), 3);
931 assert_eq!(term.cursor_col(), 0);
932
933 term.append("Two lines above are intentionally left blank.\n");
934 assert_eq!(term.cursor_row(), 4);
935 assert_eq!(term.cursor_col(), 0);
936
937 // Set up the test pattern again, then play with insert/delete
938 term.append("0123456789\n");
939 term.append("ABCDEFGHIJ\n");
940 term.append("abcdefghij\n");
941 assert_eq!(term.cursor_row(), 7);
942
943 term.set_cursor_row(4);
944 term.set_cursor_col(4);
945 assert_eq!(term.u8c_cursor().text_utf8(), b"4");
946
947 term.insert_char('x', 5); // Push this row right 5 chars starting at col 4
948 assert_eq!(term.u8c_cursor().text_utf8(), b"x");
949 term.cursor_right(5, false);
950 assert_eq!(term.cursor_col(), 9);
951 assert_eq!(term.u8c_cursor().text_utf8(), b"4");
952
953 // Insert two blank rows above cursor. Cursor stays put.
954 term.insert_rows(2);
955 assert_eq!(term.cursor_row(), 4);
956 assert_eq!(term.cursor_col(), 9);
957 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
958 term.cursor_down(2, false); // Go down to find our text again
959 assert_eq!(term.u8c_cursor().text_utf8(), b"4");
960
961 // Go back to the beginning of the inserted 'x' characters and delete them.
962 term.cursor_left(5);
963 assert_eq!(term.u8c_cursor().text_utf8(), b"x");
964 term.delete_cur_chars(5);
965 assert_eq!(term.cursor_row(), 6);
966 assert_eq!(term.cursor_col(), 4);
967 assert_eq!(term.u8c_cursor().text_utf8(), b"4");
968
969 term.delete_chars(7, 2, 2); // Delete "CD" from the next row
970 term.cursor_down(1, false);
971 term.cursor_left(2);
972 assert_eq!(term.u8c_cursor().text_utf8(), b"E");
973
974 term.delete_rows(1); // Middle row of pattern is gone, cursor stays put
975 assert_eq!(term.u8c_cursor().text_utf8(), b"c");
976 term.cursor_up(1, false);
977 term.delete_rows(2); // Delete remains of test pattern
978
979 term.set_text_attrib(Attrib::Bold);
980 term.insert_char_eol('-', 3, 15, 20);
981 term.set_cursor_row(3);
982 term.set_cursor_col(15);
983 assert_eq!(term.u8c_cursor().text_utf8(), b"-"); // Check the insertion
984 assert_eq!(term.u8c_cursor().attrib(), Attrib::Bold);
985
986 term.set_text_attrib(Attrib::Italic);
987 term.append(" and all lines below");
988 term.set_text_attrib(Attrib::Normal);
989 term.cursor_down(1, false);
990
991 let mut hsb = term.hscrollbar();
992 let mut sb = term.scrollbar();
993 hsb.set_value(100.0);
994 assert_eq!(hsb.value(), 100.0);
995 sb.set_value(50.0);
996 assert_eq!(sb.value(), 50.0);
997 hsb.set_value(0.0);
998 assert_eq!(hsb.value(), 0.0);
999 sb.set_value(0.0);
1000 assert_eq!(sb.value(), 0.0);
1001}
Sourcepub fn pwidth_int(&self) -> usize
pub fn pwidth_int(&self) -> usize
Return the width of this character in integer pixels.
WARNING: Uses current font, so assumes font and font_size
have already been set to current font!
Examples found in repository?
699fn mb_test5_cb(_choice: &mut fltk::menu::Choice, term: &mut Terminal) {
700 term.take_focus().unwrap();
701
702 // Test the attr_fg_color and attr_bg_color methods.
703 // Put a single character 'A' into the buffer and check it
704 term.clear(); // No reset_terminal(), just clear() to preserve the mouse selection for later
705 term.set_text_bg_color(Color::TransparentBg);
706 term.set_text_fg_color(Color::XtermWhite);
707 term.append("A");
708 let r = &term.u8c_disp_row(0);
709 let uc = r.col(0);
710 assert_eq!(uc.text_utf8(), b"A");
711 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
712 assert_eq!(&uc.attr_bgcolor(None), &Color::TransparentBg);
713 assert_eq!(&uc.attr_bgcolor(Some(term)), &Color::Black);
714 assert_eq!(&uc.attr_fgcolor(Some(term)), &Color::XtermWhite);
715 assert_eq!(&uc.attrib(), &Attrib::Normal);
716
717 // Put a short string "BCD" into the first line of the buffer, with fg color change after the 'B' and bold after 'C'
718 term.clear();
719 term.set_text_fg_color_xterm(XtermColor::White);
720 term.set_text_bg_color_xterm(XtermColor::Black);
721 assert_eq!(term.text_attrib(), Attrib::Normal);
722
723 assert!(term.ansi());
724 term.append("B\x1b[32mC\x1b[1mD\n");
725
726 let r = &term.u8c_disp_row(0);
727 let uc = r.col(0);
728 assert_eq!(uc.text_utf8(), b"B");
729 assert!(uc.is_char(b'B'));
730 assert!(!uc.is_char(b'A'));
731 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
732 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
733 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
734 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBlack);
735 assert_eq!(
736 &uc.charflags(),
737 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
738 );
739
740 let uc = r.col(1);
741 assert_eq!(uc.text_utf8(), b"C");
742 assert!(uc.is_char(b'C'));
743 assert_eq!(&uc.fgcolor(), &Color::XtermGreen);
744 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
745 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermGreen);
746 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBlack);
747 assert_eq!(
748 &uc.charflags(),
749 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
750 );
751
752 let uc = r.col(2);
753 assert_eq!(uc.text_utf8(), b"D");
754 assert!(uc.is_char(b'D'));
755 assert_eq!(&uc.fgcolor(), &Color::XtermGreen);
756 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
757 assert_eq!(&uc.attr_fgcolor(None), &Color::from_rgb(0x20, 0xf0, 0x20));
758 assert_eq!(&uc.attr_bgcolor(None), &Color::from_rgb(0x20, 0x20, 0x20));
759 assert_eq!(
760 &uc.attr_fgcolor(Some(term)),
761 &Color::from_rgb(0x20, 0xf0, 0x20)
762 );
763 assert_eq!(&uc.attr_bgcolor(None), &Color::from_rgb(0x20, 0x20, 0x20));
764 assert_eq!(
765 &uc.charflags(),
766 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
767 );
768
769 // Put a short string "BCDE" into the buffer, with fg color change after the 'B', bg change after 'C', and bold after 'D'
770 term.clear();
771 term.set_text_fg_color_xterm(XtermColor::White);
772 term.set_text_bg_color_xterm(XtermColor::Black);
773 term.set_text_attrib(Attrib::Normal);
774 assert_eq!(term.text_attrib(), Attrib::Normal);
775
776 assert!(term.ansi());
777 term.append("B\x1b[37mC\x1b[44mD\x1b[1mE\n");
778
779 let r = &term.u8c_disp_row(0);
780 let uc = r.col(0);
781 assert_eq!(uc.text_utf8(), b"B");
782 assert!(uc.is_char(b'B'));
783 assert!(!uc.is_char(b'A'));
784 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
785 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
786 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
787 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBlack);
788 assert_eq!(
789 &uc.charflags(),
790 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
791 );
792
793 let uc = r.col(1);
794 assert_eq!(uc.text_utf8(), b"C");
795 assert!(uc.is_char(b'C'));
796 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
797 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
798 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
799 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBlack);
800 assert_eq!(
801 &uc.charflags(),
802 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
803 );
804
805 let uc = r.col(2);
806 assert_eq!(uc.text_utf8(), b"D");
807 assert!(uc.is_char(b'D'));
808 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
809 assert_eq!(&uc.bgcolor(), &Color::XtermBgBlue);
810 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
811 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBgBlue);
812 assert_eq!(
813 &uc.charflags(),
814 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
815 );
816
817 let uc = r.col(3);
818 assert_eq!(uc.text_utf8(), b"E");
819 assert!(uc.is_char(b'E'));
820 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
821 assert_eq!(&uc.bgcolor(), &Color::XtermBgBlue);
822 assert_eq!(&uc.attr_fgcolor(None), &Color::from_hex(0xf0f0f0));
823 assert_eq!(&uc.attr_bgcolor(None), &Color::from_hex(0x2020e0));
824 assert_eq!(
825 &uc.charflags(),
826 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
827 );
828
829 // Test some miscellaneous Utf8 constants
830 assert_eq!(uc.length(), 1);
831 assert_eq!(uc.max_utf8(), 4);
832 assert_eq!(uc.pwidth(), 9.0);
833 assert_eq!(uc.pwidth_int(), 9);
834
835 term.set_text_fg_color_xterm(XtermColor::White);
836 term.set_text_bg_color_xterm(XtermColor::Black);
837 term.clear();
838 term.set_text_attrib(Attrib::Normal);
839
840 // Mouse selection functions
841 term.append(&format!("Mouse selection: {:?}\n", &term.get_selection()));
842 term.clear_mouse_selection();
843 assert_eq!(term.get_selection(), None);
844
845 // Play with cursor position
846 term.append("0123456789\n"); // Set up test pattern
847 term.append("ABCDEFGHIJ\n");
848 term.append("abcdefghij\n");
849
850 term.set_cursor_row(1);
851 assert_eq!(term.cursor_row(), 1);
852 term.set_cursor_col(1);
853 assert_eq!(term.cursor_col(), 1);
854 assert_eq!(term.u8c_cursor().text_utf8(), b"1");
855
856 term.append("----"); // Overwrites text at cursor and moves cursor forward
857 assert_eq!(term.cursor_row(), 1);
858 assert_eq!(term.cursor_col(), 5);
859 assert_eq!(term.u8c_cursor().text_utf8(), b"5");
860 term.set_cursor_col(1);
861 assert_eq!(term.u8c_cursor().text_utf8(), b"-"); // Overwritten text
862
863 term.cursor_up(1, false);
864 assert_eq!(term.cursor_row(), 0);
865 assert_eq!(term.cursor_col(), 1);
866 assert_eq!(term.u8c_cursor().text_utf8(), b"o");
867
868 // Hit top of screen, so nothing happens
869 term.cursor_up(1, false);
870 assert_eq!(term.cursor_row(), 0);
871 assert_eq!(term.cursor_col(), 1);
872 assert_eq!(term.u8c_cursor().text_utf8(), b"o");
873
874 // Hit top of screen with scroll enabled. A blank line from history is scrolled in.
875 term.cursor_up(1, true);
876 assert_eq!(term.cursor_row(), 0);
877 assert_eq!(term.cursor_col(), 1);
878 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
879
880 // Go back down to the overwritten text
881 term.cursor_down(2, false);
882 assert_eq!(term.cursor_row(), 2);
883 assert_eq!(term.cursor_col(), 1);
884 assert_eq!(term.u8c_cursor().text_utf8(), b"-");
885
886 // Go right past the overwritten text
887 term.cursor_right(4, false);
888 assert_eq!(term.cursor_row(), 2);
889 assert_eq!(term.cursor_col(), 5);
890 assert_eq!(term.u8c_cursor().text_utf8(), b"5");
891
892 // Go left to the end of the overwritten text
893 term.cursor_left(1);
894 assert_eq!(term.cursor_row(), 2);
895 assert_eq!(term.cursor_col(), 4);
896 assert_eq!(term.u8c_cursor().text_utf8(), b"-");
897
898 // Scroll back down, removing the blank line at the top.
899 // Cursor stays in place, the text moves under it.
900 term.scroll(1);
901 assert_eq!(term.cursor_row(), 2);
902 assert_eq!(term.cursor_col(), 4);
903 assert_eq!(term.u8c_cursor().text_utf8(), b"E");
904
905 // Clear from here to end-of-line
906 term.clear_eol();
907 assert_eq!(term.cursor_row(), 2);
908 assert_eq!(term.cursor_col(), 4);
909 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
910
911 // Now clear from here to start-of-line. Cursor does not move.
912 term.clear_sol();
913 assert_eq!(term.cursor_row(), 2);
914 assert_eq!(term.cursor_col(), 4);
915 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
916 term.cursor_left(1);
917 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
918 term.set_cursor_col(0);
919 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
920
921 // Clear some lines
922 term.clear_line(1);
923 assert_eq!(term.cursor_row(), 2);
924 assert_eq!(term.cursor_col(), 0);
925 term.set_cursor_row(1);
926 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
927 term.set_cursor_row(3);
928 term.clear_cur_line();
929 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
930 assert_eq!(term.cursor_row(), 3);
931 assert_eq!(term.cursor_col(), 0);
932
933 term.append("Two lines above are intentionally left blank.\n");
934 assert_eq!(term.cursor_row(), 4);
935 assert_eq!(term.cursor_col(), 0);
936
937 // Set up the test pattern again, then play with insert/delete
938 term.append("0123456789\n");
939 term.append("ABCDEFGHIJ\n");
940 term.append("abcdefghij\n");
941 assert_eq!(term.cursor_row(), 7);
942
943 term.set_cursor_row(4);
944 term.set_cursor_col(4);
945 assert_eq!(term.u8c_cursor().text_utf8(), b"4");
946
947 term.insert_char('x', 5); // Push this row right 5 chars starting at col 4
948 assert_eq!(term.u8c_cursor().text_utf8(), b"x");
949 term.cursor_right(5, false);
950 assert_eq!(term.cursor_col(), 9);
951 assert_eq!(term.u8c_cursor().text_utf8(), b"4");
952
953 // Insert two blank rows above cursor. Cursor stays put.
954 term.insert_rows(2);
955 assert_eq!(term.cursor_row(), 4);
956 assert_eq!(term.cursor_col(), 9);
957 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
958 term.cursor_down(2, false); // Go down to find our text again
959 assert_eq!(term.u8c_cursor().text_utf8(), b"4");
960
961 // Go back to the beginning of the inserted 'x' characters and delete them.
962 term.cursor_left(5);
963 assert_eq!(term.u8c_cursor().text_utf8(), b"x");
964 term.delete_cur_chars(5);
965 assert_eq!(term.cursor_row(), 6);
966 assert_eq!(term.cursor_col(), 4);
967 assert_eq!(term.u8c_cursor().text_utf8(), b"4");
968
969 term.delete_chars(7, 2, 2); // Delete "CD" from the next row
970 term.cursor_down(1, false);
971 term.cursor_left(2);
972 assert_eq!(term.u8c_cursor().text_utf8(), b"E");
973
974 term.delete_rows(1); // Middle row of pattern is gone, cursor stays put
975 assert_eq!(term.u8c_cursor().text_utf8(), b"c");
976 term.cursor_up(1, false);
977 term.delete_rows(2); // Delete remains of test pattern
978
979 term.set_text_attrib(Attrib::Bold);
980 term.insert_char_eol('-', 3, 15, 20);
981 term.set_cursor_row(3);
982 term.set_cursor_col(15);
983 assert_eq!(term.u8c_cursor().text_utf8(), b"-"); // Check the insertion
984 assert_eq!(term.u8c_cursor().attrib(), Attrib::Bold);
985
986 term.set_text_attrib(Attrib::Italic);
987 term.append(" and all lines below");
988 term.set_text_attrib(Attrib::Normal);
989 term.cursor_down(1, false);
990
991 let mut hsb = term.hscrollbar();
992 let mut sb = term.scrollbar();
993 hsb.set_value(100.0);
994 assert_eq!(hsb.value(), 100.0);
995 sb.set_value(50.0);
996 assert_eq!(sb.value(), 50.0);
997 hsb.set_value(0.0);
998 assert_eq!(hsb.value(), 0.0);
999 sb.set_value(0.0);
1000 assert_eq!(sb.value(), 0.0);
1001}
Sourcepub fn text_utf8(&self) -> &[u8] ⓘ
pub fn text_utf8(&self) -> &[u8] ⓘ
Return the UTF-8 text string for this character.
Examples found in repository?
554fn mb_test4_cb(_choice: &mut fltk::menu::Choice, term: &mut Terminal) {
555 let sel_len = term.selection_text_len();
556 let sel = term.selection_text();
557
558 term.take_focus().unwrap();
559 term.reset_terminal();
560 // Test the Utf8Char primitive
561 let uc = Utf8Char::new(b'Q');
562 let uc1 = uc.text_utf8();
563 assert_eq!(&uc1, b"Q");
564 assert_eq!(&uc.attrib(), &Attrib::Normal);
565 assert_eq!(
566 &uc.charflags(),
567 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
568 );
569 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
570 assert_eq!(&uc.bgcolor(), &Color::TransparentBg);
571
572 let ring_rows = term.ring_rows();
573
574 term.take_focus().unwrap();
575 term.clear_history();
576 assert_eq!(term.history_use(), 0);
577
578 // Subtract row numbers, modulo `rows`
579 fn row_diff(rows: i32, a: i32, b: i32) -> i32 {
580 match a - b {
581 n if n < 0 => n + rows,
582 n => n,
583 }
584 }
585 // disp_srow is always 1 greater than hist_erow, modulo (ring_rows+1)
586 assert_eq!(row_diff(ring_rows, term.disp_srow(), term.hist_erow()), 1);
587 assert!(term.disp_srow() >= 0);
588 assert!(term.disp_erow() >= 0);
589 assert!(term.hist_srow() >= 0);
590 assert!(term.hist_erow() >= 0);
591 assert!(term.offset() >= 0);
592 assert!(term.disp_srow() <= ring_rows);
593 assert!(term.disp_erow() <= ring_rows);
594 assert!(term.hist_srow() <= ring_rows);
595 assert!(term.hist_erow() <= ring_rows);
596 assert!(term.offset() <= ring_rows);
597
598 assert_eq!(term.ring_srow(), 0);
599 assert_eq!(term.ring_erow(), ring_rows - 1);
600 assert_eq!(
601 row_diff(ring_rows, term.disp_erow(), term.disp_srow()) + 1,
602 term.display_rows()
603 );
604 assert_eq!(
605 row_diff(ring_rows, term.hist_erow(), term.hist_srow()) + 1,
606 term.history_rows()
607 );
608
609 assert_eq!(term.ring_erow(), term.ring_rows() - 1);
610 assert_eq!(term.ring_srow(), 0);
611
612 /// Local function to read back all rows from the display into a long string.
613 /// Does not include scrollback history.
614 /// Trims trailing blanks on each line
615 fn read_disp(term: &Terminal) -> String {
616 let rows = term.display_rows();
617 let mut text: Vec<u8> = Vec::with_capacity((rows * 64) as usize);
618 for row in 0..rows {
619 let r = term.u8c_disp_row(row).trim();
620 // Iterate through a row, accumulating [u8]
621 for c in r.iter() {
622 // Note: Sometimes utf-8 length is > 1
623 text.extend_from_slice(c.text_utf8());
624 }
625 text.extend_from_slice(b"\n");
626 }
627 // Return the result as a string
628 std::str::from_utf8(&text).unwrap().to_string()
629 }
630
631 term.clear();
632 term.append("Top line ↑ (up-arrow)");
633 term.set_text_attrib(Attrib::Underline);
634 term.append(" ");
635 term.set_text_attrib(Attrib::Normal);
636 term.append(" \n");
637 let mut text_out = read_disp(term);
638 // Trim trailing empty lines
639 text_out = text_out.trim_end_matches(&"\n").to_string();
640 // The two plain blanks at the end will be trimmed, the two underlined blanks will be retained.
641
642 assert_eq!(text_out, "Top line ↑ (up-arrow) ");
643 let r = term.u8c_disp_row(0);
644 assert_eq!(r.col(0).text_utf8(), b"T");
645 assert_eq!(r.col(10).text_utf8(), b"\xe2\x86\x91"); // UTF-8 up-arrow
646 assert_eq!(r.col(24).text_utf8(), b" "); // First blank after test text, NOT trimmed
647 let r = term.u8c_disp_row(1);
648 assert_eq!(r.col(0).text_utf8(), b" "); // Second row starts with blanks
649 assert_eq!(r.col(1).text_utf8(), b" "); // Second row is full of blanks
650
651 // Clear the screen again, then append test text, then read it back and compare
652 let test_text = "The wind was a torrent of darkness among the gusty trees.
653The moon was a ghostly galleon tossed upon cloudy seas.
654The road was a ribbon of moonlight over the purple moor,
655And the highwayman came riding—
656 Riding—riding—
657The highwayman came riding, up to the old inn-door.";
658
659 term.clear_history();
660 term.clear();
661 let bg_save = term.text_bg_color();
662 let fg_save = term.text_fg_color();
663 term.set_text_bg_color(Color::DarkBlue); // Set spooky colors
664 term.set_text_fg_color(Color::from_rgb(0x40, 0x40, 0xff));
665 term.append(test_text);
666 term.set_text_bg_color(bg_save);
667 term.set_text_fg_color(fg_save);
668
669 let mut text_out = read_disp(term);
670 // Trim trailing empty lines
671 text_out = text_out.trim_end_matches(&"\n").to_string();
672 assert_eq!(test_text, text_out);
673
674 assert_eq!(row_diff(ring_rows, term.disp_srow(), term.hist_erow()), 1);
675
676 assert_eq!(term.ring_srow(), 0);
677 assert_eq!(term.ring_erow(), ring_rows - 1);
678 assert_eq!(
679 row_diff(ring_rows, term.disp_erow(), term.disp_srow()) + 1,
680 term.display_rows()
681 );
682 assert_eq!(
683 row_diff(ring_rows, term.hist_erow(), term.hist_srow()) + 1,
684 term.history_rows()
685 );
686
687 term.append(&format!(
688 "\n\nScreen has {} rows of {} columns.\n",
689 term.display_rows(),
690 term.display_columns()
691 ));
692
693 term.append(&format!("Selection len: {sel_len}\nSelection: '{sel:?}'\n"));
694}
695
696//--------------------------------------------------------------------------------------
697/// Yet another set of tests for misc cursor functions and other stuff
698/// Note: these tests depend heavily on the low-level "protected" parts of the fltk library, which should be used with caution.
699fn mb_test5_cb(_choice: &mut fltk::menu::Choice, term: &mut Terminal) {
700 term.take_focus().unwrap();
701
702 // Test the attr_fg_color and attr_bg_color methods.
703 // Put a single character 'A' into the buffer and check it
704 term.clear(); // No reset_terminal(), just clear() to preserve the mouse selection for later
705 term.set_text_bg_color(Color::TransparentBg);
706 term.set_text_fg_color(Color::XtermWhite);
707 term.append("A");
708 let r = &term.u8c_disp_row(0);
709 let uc = r.col(0);
710 assert_eq!(uc.text_utf8(), b"A");
711 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
712 assert_eq!(&uc.attr_bgcolor(None), &Color::TransparentBg);
713 assert_eq!(&uc.attr_bgcolor(Some(term)), &Color::Black);
714 assert_eq!(&uc.attr_fgcolor(Some(term)), &Color::XtermWhite);
715 assert_eq!(&uc.attrib(), &Attrib::Normal);
716
717 // Put a short string "BCD" into the first line of the buffer, with fg color change after the 'B' and bold after 'C'
718 term.clear();
719 term.set_text_fg_color_xterm(XtermColor::White);
720 term.set_text_bg_color_xterm(XtermColor::Black);
721 assert_eq!(term.text_attrib(), Attrib::Normal);
722
723 assert!(term.ansi());
724 term.append("B\x1b[32mC\x1b[1mD\n");
725
726 let r = &term.u8c_disp_row(0);
727 let uc = r.col(0);
728 assert_eq!(uc.text_utf8(), b"B");
729 assert!(uc.is_char(b'B'));
730 assert!(!uc.is_char(b'A'));
731 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
732 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
733 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
734 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBlack);
735 assert_eq!(
736 &uc.charflags(),
737 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
738 );
739
740 let uc = r.col(1);
741 assert_eq!(uc.text_utf8(), b"C");
742 assert!(uc.is_char(b'C'));
743 assert_eq!(&uc.fgcolor(), &Color::XtermGreen);
744 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
745 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermGreen);
746 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBlack);
747 assert_eq!(
748 &uc.charflags(),
749 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
750 );
751
752 let uc = r.col(2);
753 assert_eq!(uc.text_utf8(), b"D");
754 assert!(uc.is_char(b'D'));
755 assert_eq!(&uc.fgcolor(), &Color::XtermGreen);
756 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
757 assert_eq!(&uc.attr_fgcolor(None), &Color::from_rgb(0x20, 0xf0, 0x20));
758 assert_eq!(&uc.attr_bgcolor(None), &Color::from_rgb(0x20, 0x20, 0x20));
759 assert_eq!(
760 &uc.attr_fgcolor(Some(term)),
761 &Color::from_rgb(0x20, 0xf0, 0x20)
762 );
763 assert_eq!(&uc.attr_bgcolor(None), &Color::from_rgb(0x20, 0x20, 0x20));
764 assert_eq!(
765 &uc.charflags(),
766 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
767 );
768
769 // Put a short string "BCDE" into the buffer, with fg color change after the 'B', bg change after 'C', and bold after 'D'
770 term.clear();
771 term.set_text_fg_color_xterm(XtermColor::White);
772 term.set_text_bg_color_xterm(XtermColor::Black);
773 term.set_text_attrib(Attrib::Normal);
774 assert_eq!(term.text_attrib(), Attrib::Normal);
775
776 assert!(term.ansi());
777 term.append("B\x1b[37mC\x1b[44mD\x1b[1mE\n");
778
779 let r = &term.u8c_disp_row(0);
780 let uc = r.col(0);
781 assert_eq!(uc.text_utf8(), b"B");
782 assert!(uc.is_char(b'B'));
783 assert!(!uc.is_char(b'A'));
784 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
785 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
786 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
787 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBlack);
788 assert_eq!(
789 &uc.charflags(),
790 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
791 );
792
793 let uc = r.col(1);
794 assert_eq!(uc.text_utf8(), b"C");
795 assert!(uc.is_char(b'C'));
796 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
797 assert_eq!(&uc.bgcolor(), &Color::XtermBlack);
798 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
799 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBlack);
800 assert_eq!(
801 &uc.charflags(),
802 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
803 );
804
805 let uc = r.col(2);
806 assert_eq!(uc.text_utf8(), b"D");
807 assert!(uc.is_char(b'D'));
808 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
809 assert_eq!(&uc.bgcolor(), &Color::XtermBgBlue);
810 assert_eq!(&uc.attr_fgcolor(None), &Color::XtermWhite);
811 assert_eq!(&uc.attr_bgcolor(None), &Color::XtermBgBlue);
812 assert_eq!(
813 &uc.charflags(),
814 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
815 );
816
817 let uc = r.col(3);
818 assert_eq!(uc.text_utf8(), b"E");
819 assert!(uc.is_char(b'E'));
820 assert_eq!(&uc.fgcolor(), &Color::XtermWhite);
821 assert_eq!(&uc.bgcolor(), &Color::XtermBgBlue);
822 assert_eq!(&uc.attr_fgcolor(None), &Color::from_hex(0xf0f0f0));
823 assert_eq!(&uc.attr_bgcolor(None), &Color::from_hex(0x2020e0));
824 assert_eq!(
825 &uc.charflags(),
826 &(CharFlags::FG_XTERM | CharFlags::BG_XTERM)
827 );
828
829 // Test some miscellaneous Utf8 constants
830 assert_eq!(uc.length(), 1);
831 assert_eq!(uc.max_utf8(), 4);
832 assert_eq!(uc.pwidth(), 9.0);
833 assert_eq!(uc.pwidth_int(), 9);
834
835 term.set_text_fg_color_xterm(XtermColor::White);
836 term.set_text_bg_color_xterm(XtermColor::Black);
837 term.clear();
838 term.set_text_attrib(Attrib::Normal);
839
840 // Mouse selection functions
841 term.append(&format!("Mouse selection: {:?}\n", &term.get_selection()));
842 term.clear_mouse_selection();
843 assert_eq!(term.get_selection(), None);
844
845 // Play with cursor position
846 term.append("0123456789\n"); // Set up test pattern
847 term.append("ABCDEFGHIJ\n");
848 term.append("abcdefghij\n");
849
850 term.set_cursor_row(1);
851 assert_eq!(term.cursor_row(), 1);
852 term.set_cursor_col(1);
853 assert_eq!(term.cursor_col(), 1);
854 assert_eq!(term.u8c_cursor().text_utf8(), b"1");
855
856 term.append("----"); // Overwrites text at cursor and moves cursor forward
857 assert_eq!(term.cursor_row(), 1);
858 assert_eq!(term.cursor_col(), 5);
859 assert_eq!(term.u8c_cursor().text_utf8(), b"5");
860 term.set_cursor_col(1);
861 assert_eq!(term.u8c_cursor().text_utf8(), b"-"); // Overwritten text
862
863 term.cursor_up(1, false);
864 assert_eq!(term.cursor_row(), 0);
865 assert_eq!(term.cursor_col(), 1);
866 assert_eq!(term.u8c_cursor().text_utf8(), b"o");
867
868 // Hit top of screen, so nothing happens
869 term.cursor_up(1, false);
870 assert_eq!(term.cursor_row(), 0);
871 assert_eq!(term.cursor_col(), 1);
872 assert_eq!(term.u8c_cursor().text_utf8(), b"o");
873
874 // Hit top of screen with scroll enabled. A blank line from history is scrolled in.
875 term.cursor_up(1, true);
876 assert_eq!(term.cursor_row(), 0);
877 assert_eq!(term.cursor_col(), 1);
878 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
879
880 // Go back down to the overwritten text
881 term.cursor_down(2, false);
882 assert_eq!(term.cursor_row(), 2);
883 assert_eq!(term.cursor_col(), 1);
884 assert_eq!(term.u8c_cursor().text_utf8(), b"-");
885
886 // Go right past the overwritten text
887 term.cursor_right(4, false);
888 assert_eq!(term.cursor_row(), 2);
889 assert_eq!(term.cursor_col(), 5);
890 assert_eq!(term.u8c_cursor().text_utf8(), b"5");
891
892 // Go left to the end of the overwritten text
893 term.cursor_left(1);
894 assert_eq!(term.cursor_row(), 2);
895 assert_eq!(term.cursor_col(), 4);
896 assert_eq!(term.u8c_cursor().text_utf8(), b"-");
897
898 // Scroll back down, removing the blank line at the top.
899 // Cursor stays in place, the text moves under it.
900 term.scroll(1);
901 assert_eq!(term.cursor_row(), 2);
902 assert_eq!(term.cursor_col(), 4);
903 assert_eq!(term.u8c_cursor().text_utf8(), b"E");
904
905 // Clear from here to end-of-line
906 term.clear_eol();
907 assert_eq!(term.cursor_row(), 2);
908 assert_eq!(term.cursor_col(), 4);
909 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
910
911 // Now clear from here to start-of-line. Cursor does not move.
912 term.clear_sol();
913 assert_eq!(term.cursor_row(), 2);
914 assert_eq!(term.cursor_col(), 4);
915 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
916 term.cursor_left(1);
917 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
918 term.set_cursor_col(0);
919 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
920
921 // Clear some lines
922 term.clear_line(1);
923 assert_eq!(term.cursor_row(), 2);
924 assert_eq!(term.cursor_col(), 0);
925 term.set_cursor_row(1);
926 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
927 term.set_cursor_row(3);
928 term.clear_cur_line();
929 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
930 assert_eq!(term.cursor_row(), 3);
931 assert_eq!(term.cursor_col(), 0);
932
933 term.append("Two lines above are intentionally left blank.\n");
934 assert_eq!(term.cursor_row(), 4);
935 assert_eq!(term.cursor_col(), 0);
936
937 // Set up the test pattern again, then play with insert/delete
938 term.append("0123456789\n");
939 term.append("ABCDEFGHIJ\n");
940 term.append("abcdefghij\n");
941 assert_eq!(term.cursor_row(), 7);
942
943 term.set_cursor_row(4);
944 term.set_cursor_col(4);
945 assert_eq!(term.u8c_cursor().text_utf8(), b"4");
946
947 term.insert_char('x', 5); // Push this row right 5 chars starting at col 4
948 assert_eq!(term.u8c_cursor().text_utf8(), b"x");
949 term.cursor_right(5, false);
950 assert_eq!(term.cursor_col(), 9);
951 assert_eq!(term.u8c_cursor().text_utf8(), b"4");
952
953 // Insert two blank rows above cursor. Cursor stays put.
954 term.insert_rows(2);
955 assert_eq!(term.cursor_row(), 4);
956 assert_eq!(term.cursor_col(), 9);
957 assert_eq!(term.u8c_cursor().text_utf8(), b" ");
958 term.cursor_down(2, false); // Go down to find our text again
959 assert_eq!(term.u8c_cursor().text_utf8(), b"4");
960
961 // Go back to the beginning of the inserted 'x' characters and delete them.
962 term.cursor_left(5);
963 assert_eq!(term.u8c_cursor().text_utf8(), b"x");
964 term.delete_cur_chars(5);
965 assert_eq!(term.cursor_row(), 6);
966 assert_eq!(term.cursor_col(), 4);
967 assert_eq!(term.u8c_cursor().text_utf8(), b"4");
968
969 term.delete_chars(7, 2, 2); // Delete "CD" from the next row
970 term.cursor_down(1, false);
971 term.cursor_left(2);
972 assert_eq!(term.u8c_cursor().text_utf8(), b"E");
973
974 term.delete_rows(1); // Middle row of pattern is gone, cursor stays put
975 assert_eq!(term.u8c_cursor().text_utf8(), b"c");
976 term.cursor_up(1, false);
977 term.delete_rows(2); // Delete remains of test pattern
978
979 term.set_text_attrib(Attrib::Bold);
980 term.insert_char_eol('-', 3, 15, 20);
981 term.set_cursor_row(3);
982 term.set_cursor_col(15);
983 assert_eq!(term.u8c_cursor().text_utf8(), b"-"); // Check the insertion
984 assert_eq!(term.u8c_cursor().attrib(), Attrib::Bold);
985
986 term.set_text_attrib(Attrib::Italic);
987 term.append(" and all lines below");
988 term.set_text_attrib(Attrib::Normal);
989 term.cursor_down(1, false);
990
991 let mut hsb = term.hscrollbar();
992 let mut sb = term.scrollbar();
993 hsb.set_value(100.0);
994 assert_eq!(hsb.value(), 100.0);
995 sb.set_value(50.0);
996 assert_eq!(sb.value(), 50.0);
997 hsb.set_value(0.0);
998 assert_eq!(hsb.value(), 0.0);
999 sb.set_value(0.0);
1000 assert_eq!(sb.value(), 0.0);
1001}