1 /// Module that implements Terminal UI rendering
2 module sily.tui.render;
3 
4 import sily.color;
5 static import sily.conv;
6 
7 import std.stdio: write, stdout;
8 import std.string: format;
9 import std.conv: to;
10 
11 /** 
12 Escapes color into bash sequence according to selected color mode
13 Params:
14     c = Color
15     b = Is color background
16     m = ColorMode (ansi8, ansi256, truecolor)
17 Returns: Escaped color
18 */
19 string escape(Color c, bool b, ColorMode m) {
20     switch (m) {
21         case ColorMode.truecolor: return c.toTrueColorString(b);
22         case ColorMode.ansi256: return c.toAnsiString(b);
23         case ColorMode.ansi8: 
24         default: return c.toAnsi8String(b);
25     }
26 }
27 
28 /// Ditto
29 string escape(Color c, bool b) {
30     return escape(c, b, Render.colorMode);
31 }
32 
33 /// Render color mode
34 enum ColorMode {
35     ansi8, ansi256, truecolor
36 }
37 
38 /// Renderer
39 public static class Render {
40     private static ColorMode _colorMode = ColorMode.truecolor;
41 
42     private static dstring _screenBuffer = "";
43 
44     /// Returns current color mode
45     public static ColorMode colorMode() {
46         return _colorMode;
47     }
48 
49     /// Sets color mode
50     public static void colorMode(ColorMode c) {
51         _colorMode = c;
52     }
53 
54     /// Returns screen buffer contents
55     public static dstring readBuffer() {
56         return _screenBuffer;
57     }
58 
59     /// Clears screen buffer
60     public static void clearBuffer() {
61         _screenBuffer = "";
62     }
63 
64     /// Writes buffer into stdout and flushes stdout
65     public static void flushBuffer() {
66         stdout.write(_screenBuffer);
67         stdout.flush(); // Eliminates flickering if used instead of no buffer
68     }
69 
70     /// Replaces buffer contents with `content`
71     public static void writeBuffer(dstring content) {
72         _screenBuffer = content;
73     }
74 
75     /// Formatted writes `args into buffer. Slow
76     public static void writef(A...)(A args) if (args.length > 0) {
77         _screenBuffer ~= .format(args).to!dstring;
78     }
79 
80     /// Writes `args into buffer
81     public static void write(A...)(A args) if (args.length > 0) {
82         foreach (arg; args) {
83             _screenBuffer ~= arg.to!dstring;
84         }
85     }
86 
87     /// Clears terminal screen
88     public static void screenClearOnly() {
89         write("\033[2J");
90     }
91     /// Moves cursor in terminal to `{0, 0}`
92     public static void cursorMoveHome() {
93         write("\033[H");
94     }
95 
96     /**
97     Moves cursor to pos. Allows for chaining
98     Example:
99     ---
100     Render.at(12, 15).write("My pretty text");
101     ---
102     */
103     public static Render at(uint x, uint y) {
104         write("\033[", y + 1, ";", x + 1, "f");
105         return null; // ... what
106     }
107 }