Struct Utf8Char

Source
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

Source

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?
examples/terminal.rs (line 561)
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}
Source

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?
examples/terminal.rs (line 712)
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}
Source

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?
examples/terminal.rs (line 711)
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}
Source

pub fn attrib(&self) -> Attrib

Return the attributes for this character.

Examples found in repository?
examples/terminal.rs (line 564)
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}
Source

pub fn bgcolor(&self) -> Color

Return the background color for this character.

Examples found in repository?
examples/terminal.rs (line 570)
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}
Source

pub fn fgcolor(&self) -> Color

Return the foreground color for this character.

Examples found in repository?
examples/terminal.rs (line 569)
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}
Source

pub fn charflags(&self) -> CharFlags

Return the xterm CharFlags bits

Examples found in repository?
examples/terminal.rs (line 566)
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}
Source

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?
examples/terminal.rs (line 729)
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}
Source

pub fn length(&self) -> usize

Return the length of this character in bytes (UTF-8 can be multibyte)

Examples found in repository?
examples/terminal.rs (line 830)
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}
Source

pub fn max_utf8(&self) -> usize

Return the maximum length in bytes of a UTF-8 character

Examples found in repository?
examples/terminal.rs (line 831)
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}
Source

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?
examples/terminal.rs (line 832)
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}
Source

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?
examples/terminal.rs (line 833)
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}
Source

pub fn text_utf8(&self) -> &[u8]

Return the UTF-8 text string for this character.

Examples found in repository?
examples/terminal.rs (line 562)
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}

Trait Implementations§

Source§

impl Debug for Utf8Char

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.