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