1 /* $Id: tablewidget.c,v 1.4 2006/09/15 13:34:06 toad32767 Exp $ */
2 /**
3  ** 2004, 2005, 2006 by Marco Trillo
4  ** This file is part of UModPlayer, and is released by
5  ** its autors to the Public Domain.
6  ** In case it's not legally possible, its autors grant
7  ** anyone the right to use, redistribute and modify
8  ** this software for any purpose, without any conditions,
9  ** unless such conditions are required by law.
10  **
11  ** THIS FILE COMES WITHOUT ANY WARRANTY. THE AUTHORS
12  ** SHALL NOT BE LIABLE FOR ANY DAMAGE RESULTING BY THE
13  ** USE OR MISUSE OF THIS SOFTWARE.
14  **/
15 
16 #include <stdio.h>
17 #include <string.h>
18 #include <umodplayer.h>
19 #include "tablewidget.h"
20 
21 
22 /* Themes */
23 
24 #define TABLE_SYMBOLS	6
25 
26 enum {
27 	TABLE_UPPER_BOUND = 0,
28 	TABLE_LOWER_BOUND = 1,
29 	TABLE_BASE = 2,
30 	TABLE_EDGE = 3,
31 	TABLE_WALL = 4,
32 	TABLE_CAPTION_SPACER = 5
33 };
34 
35 LOCAL char Classic[TABLE_SYMBOLS] = {
36 	'+', '+', '-', '+', '|', ' '
37 };
38 
39 LOCAL char Strong[TABLE_SYMBOLS] = {
40 	'+', '+', '=', '+', '|', '-'
41 };
42 
43 LOCAL char Boxed[TABLE_SYMBOLS] = {
44 	'/', '\\', '-', '+', '|', ' '
45 };
46 
47 
48 /* Public functions */
49 
50 EXPORT int
TableInitCallback(WTable * table,TableCallback callback)51 TableInitCallback(WTable * table, TableCallback callback)
52 {
53 	if (!table)
54 		return TABLE_ERR_NOTABLE;
55 
56 	table->callback = callback;
57 
58 	return TABLE_OK;
59 }
60 
61 EXPORT int
TableSetOptions(WTable * table,int ID,int rows,int cols,int len,int spacer,int align)62 TableSetOptions(WTable * table, int ID, int rows, int cols, int len,
63                 int spacer, int align)
64 {
65 	if (!table)
66 		return TABLE_ERR_NOTABLE;
67 
68 	if (rows < 1 || cols < 1 || len < 2 || spacer < 0) {
69 		return TABLE_ERR_INVALID;
70 	}
71 	table->rows = rows;
72 	table->cols = cols;
73 	table->len = len;
74 	table->align = align;
75 	table->id = ID;
76 	table->spacer = spacer;
77 	table->caption = NULL;
78 	table->callback = NULL;
79 	table->theme = TABLE_THEME_CLASSIC;
80 	table->stream = stdout;
81 
82 	return TABLE_OK;
83 }
84 
85 EXPORT int
TableSetCaption(WTable * table,char * caption)86 TableSetCaption(WTable * table, char *caption)
87 {
88 	if (!table)
89 		return TABLE_ERR_NOTABLE;
90 
91 	if (caption && *caption != '\0') {
92 		table->caption = caption;
93 	} else
94 		table->caption = NULL;
95 
96 	return TABLE_OK;
97 }
98 
99 EXPORT int
TableSetOutput(WTable * table,FILE * stream)100 TableSetOutput(WTable * table, FILE * stream)
101 {
102 	if (!table)
103 		return TABLE_ERR_NOTABLE;
104 
105 	if (stream)
106 		table->stream = stream;
107 	else {
108 		return TABLE_ERR_INVALID;
109 	}
110 
111 	return TABLE_OK;
112 }
113 
114 EXPORT int
TableUseTheme(WTable * table,WTheme theme)115 TableUseTheme(WTable * table, WTheme theme)
116 {
117 	if (!table) {
118 		return TABLE_ERR_NOTABLE;
119 	}
120 	switch (theme) {
121 	case TABLE_THEME_CLASSIC:
122 	case TABLE_THEME_STRONG:
123 	case TABLE_THEME_BOXED:
124 		break;
125 	default:
126 		return TABLE_ERR_INVALID;
127 	}
128 
129 	table->theme = theme;
130 
131 	return TABLE_OK;
132 }
133 
134 
135 EXPORT int
DrawTable(WTable table)136 DrawTable(WTable table)
137 {
138 	register int i, j, e, sp;
139 	int k;
140 	char *symbols;
141 	int rows = table.rows;
142 	int cols = table.cols;
143 	int len = table.len;
144 	int align = table.align;
145 	int spacer = table.spacer;
146 	FILE *stream = table.stream;
147 	char upsymbol, losymbol;
148 	char buffer[TABLE_BUFFER_SIZE];
149 	char format[9];
150 
151 	if (!stream || !(table.callback)) {
152 		return TABLE_ERR_INVALID;
153 	}
154 	switch (table.theme) {
155 	case TABLE_THEME_CLASSIC:
156 		symbols = Classic;
157 		break;
158 	case TABLE_THEME_STRONG:
159 		symbols = Strong;
160 		break;
161 	case TABLE_THEME_BOXED:
162 		symbols = Boxed;
163 		break;
164 	default:
165 		return TABLE_ERR_INVALID;
166 	}
167 
168 
169 	if (table.caption) {
170 		sp = (cols * len) - 1;
171 
172 		if ((sp & 1) == (strlen(table.caption) & 1)) {	/* x & 1 == x % 2 */
173 			i = strlen(table.caption);
174 			strcpy(format, "%s");
175 		} else {
176 			i = strlen(table.caption) + 1;
177 			sprintf(format, "%%s%c", symbols[TABLE_CAPTION_SPACER]);
178 		}
179 
180 		i = (sp - i) >> 1;	/* x >> 1 == x / 2 */
181 
182 		for (e = 0; e < spacer; ++e)
183 			putc(' ', stream);
184 
185 		putc(symbols[TABLE_UPPER_BOUND], stream);
186 		for (e = 0; e < sp; ++e)
187 			putc(symbols[TABLE_BASE], stream);
188 
189 		putc(symbols[TABLE_LOWER_BOUND], stream);
190 		putc('\n', stream);
191 
192 		for (e = 0; e < spacer; ++e)
193 			putc(' ', stream);
194 		putc(symbols[TABLE_WALL], stream);
195 
196 		for (e = 0; e < i; ++e)
197 			putc(symbols[TABLE_CAPTION_SPACER], stream);
198 
199 		fprintf(stream, format, table.caption);
200 
201 		for (e = 0; e < i; ++e)
202 			putc(symbols[TABLE_CAPTION_SPACER], stream);
203 
204 		putc(symbols[TABLE_WALL], stream);
205 		putc('\n', stream);
206 
207 		upsymbol = losymbol = symbols[TABLE_EDGE];
208 	} else {		/* If table hasn`t a caption we need to draw
209 				 * the first row using special symbols */
210 		upsymbol = symbols[TABLE_UPPER_BOUND];
211 		losymbol = symbols[TABLE_LOWER_BOUND];
212 	}
213 
214 	if (align == TABLE_LEFT_ALIGN) {
215 		sprintf(format, "%%-%ds", len - 1);
216 	} else {
217 		sprintf(format, "%%%ds", len - 1);
218 	}
219 
220 	cols = (cols * len) + 1;
221 	rows++;
222 	e = 0;
223 
224 	for (sp = 0; sp < spacer; ++sp)
225 		putchar(' ');
226 
227 	for (i = 0; i < rows; i++) {
228 		for (j = 0; j < cols; j++) {
229 			if (j % len == 0) {
230 				if (j == 0) {
231 					if (i == 0)
232 						putc(upsymbol, stream);
233 					else if (i == table.rows)	/* table.rows = rows-1 */
234 						putc(symbols[TABLE_LOWER_BOUND], stream);
235 					else
236 						putc(symbols[TABLE_EDGE], stream);
237 				} else if (j == (cols - 1)) {
238 					if (i == 0)
239 						putc(losymbol, stream);
240 					else if (i == table.rows)
241 						putc(symbols[TABLE_UPPER_BOUND], stream);
242 					else
243 						putc(symbols[TABLE_EDGE], stream);
244 				} else
245 					putc(symbols[TABLE_EDGE], stream);
246 			} else
247 				putc(symbols[TABLE_BASE], stream);
248 		}
249 
250 		putc('\n', stream);
251 
252 		for (sp = 0; sp < spacer; ++sp)
253 			putc(' ', stream);
254 
255 		if (e < table.rows) {
256 			k = 0;
257 			for (j = 0; j < cols; j++) {
258 				if (j % len == 0) {
259 					putc(symbols[TABLE_WALL], stream);
260 					if (j != (cols - 1)) {
261 						table.callback(table.id, i, k, buffer);
262 						fprintf(stream, format, buffer);
263 					}
264 					++k;
265 				}
266 			}
267 
268 			putc('\n', stream);
269 			for (sp = 0; sp < spacer; ++sp)
270 				putc(' ', stream);
271 		}
272 		e++;
273 	}
274 
275 	return TABLE_OK;
276 }
277 /*
278  * @EOF@ -- revised February 26 2006
279  */
280