zymosis: cosmetix
[iv.d.git] / egtui / utils.d
bloba5c03d164c5d9621e8550cb3bf145efd8d120acd
1 /* Invisible Vector Library
2 * simple FlexBox-based TUI engine
4 * coded by Ketmar // Invisible Vector <ketmar@ketmar.no-ip.org>
5 * Understanding is not required. Only obedience.
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 module iv.egtui.utils /*is aliced*/;
22 import iv.alice;
23 import iv.strex;
24 import iv.rawtty;
26 import iv.egtui.types;
29 // ////////////////////////////////////////////////////////////////////////// //
30 // calculate text bounds (can call delegate to output string too ;-)
31 // use "|...|" to "quote" word
32 void calcTextBounds (out int cols, out int lines, const(char)[] text, int maxwdt,
33 scope void delegate (int x, int y, const(char)[] s) dg=null)
35 int col = 0;
37 void putWord (const(char)[] text) {
38 while (text.length > 0) {
39 while (col == 0 && text.length > maxwdt) {
40 if (dg !is null) dg(0, lines, text[0..maxwdt]);
41 ++lines;
42 text = text[maxwdt..$];
44 if (text.length == 0) break;
45 if (col == 0) {
46 if (dg !is null) dg(0, lines, text);
47 col += cast(int)text.length;
48 if (cols < col) cols = col;
49 break;
51 int nw = col+cast(int)text.length+1;
52 if (nw <= maxwdt) {
53 ++col;
54 if (dg !is null) dg(col, lines, text);
55 col += cast(int)text.length;
56 if (cols < col) cols = col;
57 break;
59 ++lines;
60 col = 0;
64 while (text.length) {
65 int pos = 0;
66 while (pos < text.length && text.ptr[pos] != '\n' && text.ptr[pos] <= ' ') ++pos;
67 if (pos > 0) { text = text[pos..$]; continue; }
68 assert(pos == 0);
69 if (text.ptr[pos] == '\n') {
70 col = 0;
71 ++lines;
72 text = text[1..$];
73 continue;
75 if (text.ptr[pos] == '|') {
76 ++pos;
77 while (pos < text.length && text.ptr[pos] != '|') ++pos;
78 putWord(text[1..pos]);
79 if (pos >= text.length) break;
80 text = text[pos+1..$];
81 } else {
82 while (pos < text.length && text.ptr[pos] > ' ') ++pos;
83 putWord(text[0..pos]);
84 text = text[pos..$];
87 if (col > 0) ++lines;
91 // ////////////////////////////////////////////////////////////////////////// //
92 // calculate text bounds, insert soft wraps, remove excessive spaces
93 // use "|...|" to "quote" word
94 // return new text length
95 uint calcTextBoundsEx (out int cols, out int lines, char[] text, int maxwdt) {
96 enum EOT = 0;
97 enum SoftWrap = 6;
99 if (maxwdt < 1) maxwdt = 1;
101 int col = 0;
102 usize dpos = 0;
103 char[] dtext = text;
105 void putText (const(char)[] s...) {
106 foreach (char ch; s) {
107 if (dpos < dtext.length) dtext.ptr[dpos++] = ch;
111 // replace soft wraps with blanks
112 foreach (char ch; text) {
113 if (ch == EOT) break;
114 if (ch == SoftWrap) ch = ' ';
115 if (ch < 1 || ch > 3) {
116 if (ch != '\n' && (ch < ' ' || ch == 127)) ch = ' ';
118 dtext[dpos++] = ch;
120 // again
121 text = text[0..dpos];
122 dpos = 0;
124 void putWord (const(char)[] text) {
125 while (text.length > 0) {
126 while (col == 0 && text.length > maxwdt) {
127 putText(text[0..maxwdt]);
128 ++lines;
129 text = text[maxwdt..$];
131 if (text.length == 0) break;
132 if (col == 0) {
133 putText(text);
134 col += cast(int)text.length;
135 if (cols < col) cols = col;
136 break;
138 int nw = col+cast(int)text.length+1;
139 if (nw <= maxwdt) {
140 putText(' ');
141 putText(text);
142 col += cast(int)text.length+1;
143 if (cols < col) cols = col;
144 break;
146 // newline
147 if (lines != 0 || col) putText(SoftWrap);
148 ++lines;
149 col = 0;
153 // align chars
154 if (text.length && text.ptr[0] > 0 && text.ptr[0] <= 3) {
155 putText(text.ptr[0]);
156 text = text[1..$];
158 while (text.length) {
159 int pos = 0;
160 while (pos < text.length && text.ptr[pos] != '\n' && text.ptr[pos] <= ' ') ++pos;
161 if (pos > 0) { text = text[pos..$]; continue; }
162 assert(pos == 0);
163 if (text.ptr[pos] == '\n') {
164 if (lines || col) putText('\n');
165 col = 0;
166 ++lines;
167 text = text[1..$];
168 // align chars
169 if (text.length && text.ptr[0] > 0 && text.ptr[0] <= 3) {
170 putText(text.ptr[0]);
171 text = text[1..$];
173 continue;
175 if (text.ptr[pos] == '|') {
176 ++pos;
177 while (pos < text.length && text.ptr[pos] != '|') ++pos;
178 putWord(text[1..pos]);
179 if (pos >= text.length) break;
180 text = text[pos+1..$];
181 } else {
182 while (pos < text.length && text.ptr[pos] > ' ') ++pos;
183 putWord(text[0..pos]);
184 text = text[pos..$];
187 if (col > 0) ++lines;
189 return cast(uint)dpos;