aboutsummaryrefslogtreecommitdiff
path: root/tui.jai
blob: 3c868ee0295b6df92c4af5eff80dbbfbf781e7f5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#import "Basic";

Drawings :: struct {
    CornerBR                :: "\x6A";
    CornerTR                :: "\x6B";
    CornerTL                :: "\x6C";
    CornerBL                :: "\x6D";
    Cross                   :: "\x6E";
    LineH                   :: "\x71";
    TeeL                    :: "\x74";
    TeeR                    :: "\x75";
    TeeB                    :: "\x76";
    TeeT                    :: "\x77";
    LineV                   :: "\x78";

    Blank                   :: "\x5F";
    Diamond                 :: "\x60";
    Checkerboard            :: "\x61";
    PlusMinus               :: "\x67";
    LessThanOrEqual         :: "\x79";
    GreaterThanOrEqual      :: "\x7A";
    Pi                      :: "\x7B";
    NotEqual                :: "\x7C";
    CenteredDot             :: "\x7E";
}

Commands :: struct {
    EnterAlternateBuffer    :: "\e[?1049h";
    EnterMainBuffer         :: "\e[?1049l";

    EnterDrawingMode        :: "\e(0";
    EnterNormalMode         :: "\e(B";
    ClearScreen             :: "\e[2J";
    ClearLine               :: "\e[2K";

    RefreshWindow           :: "\e[7t"; // TODO Not yet tested.

    SetUTF8                 :: "\e%G"; // TODO TEST ME PLEASE

    // Cursor Visibility
    ShowCursor              :: "\e[?25h";
    HideCursor              :: "\e[?25l";
    StartBlinking           :: "\e[?25h]";
    StopBlinking            :: "\e[?25l]";

    // Cursor Shape
    DefaultShape            :: "\e[0 q";
    BlinkingBlockShape      :: "\e[1 q";
    SteadyBlockShape        :: "\e[2 q";
    BlinkingUnderlineShape  :: "\e[3 q";
    SteadyUnderlineShape    :: "\e[4 q";
    BlinkingBarShape        :: "\e[5 q";
    SteadyBarShape          :: "\e[6 q";

    // Input Mode
    KeypadAppMode           :: "\e=";
    KeypadNumMode           :: "\e>";
    CursorAppMode           :: "\e[?1h";
    CursorNormalMode        :: "\e[?1l";

    // Query State
    QueryCursorPosition     :: "\e[6n"; // Emits the cursor position as: "ESC [ <r> ; <c> R" Where <r> = row and <c> = column.
    QueryDeviceAttributes   :: "\e[0c";
    QueryWindowSizeInChars  :: "\e[18t"; // Emits the window size as: "ESC [ 8 <r> ; <c> t" Where <r> = row and <c> = column.
    
}

start :: () {
    write_strings(Commands.EnterAlternateBuffer, Commands.SetUTF8, Commands.HideCursor);
}

stop :: () {
    write_strings(Commands.EnterMainBuffer, Commands.ShowCursor);
}

draw_box :: (x: int, y: int, width: int, height: int, to_standard_error := false) {

    write_strings(
        // Commands.EnterNormalMode,
        Commands.EnterDrawingMode,
        "\e[1;1H",       // Move to position 1,1
        // TODO // Move pointer to top-left corner.
        Drawings.CornerTL,
        to_standard_error = to_standard_error);

    for 1..width-2 {
        write_string(Drawings.LineH, to_standard_error = to_standard_error);
    }
    write_string(Drawings.CornerTR, to_standard_error = to_standard_error);


    // TODO Take care of the temporary allocations.
    for idx: 2..height-1 {
        tmpL := tprint("\e[%;%H", idx, 1);
        tmpR := tprint("\e[%;%H", idx, width);
        write_strings(
            tmpL,
            Drawings.LineV,
            tmpR,
            Drawings.LineV,
            to_standard_error = to_standard_error);
    }

    tmpBL := tprint("\e[%;%H", height, 1);
    write_strings(
        tmpBL,
        Drawings.CornerBL,
        to_standard_error = to_standard_error);
    for 1..width-2 {
        write_string(Drawings.LineH, to_standard_error = to_standard_error);
    }
    write_string(Drawings.CornerBR, to_standard_error = to_standard_error);
    
    write_strings(
        // TODO // print
        Commands.EnterNormalMode,
        to_standard_error = to_standard_error);
}

clear_screen :: inline () {
    write_string(Commands.ClearScreen);
}