summaryrefslogtreecommitdiffstats
path: root/mbbsd/visio.c
diff options
context:
space:
mode:
authorpiaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2008-04-16 01:08:07 +0800
committerpiaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2008-04-16 01:08:07 +0800
commita38ce8fbc7b7b18ad75f86278fe25fd85ba485d2 (patch)
tree5a227cdba379a203155bbaf91b8b2323a2130a3c /mbbsd/visio.c
parentdb9187feb31e50ed2fbe78f7fd73bf8d37bf0edc (diff)
downloadpttbbs-a38ce8fbc7b7b18ad75f86278fe25fd85ba485d2.tar
pttbbs-a38ce8fbc7b7b18ad75f86278fe25fd85ba485d2.tar.gz
pttbbs-a38ce8fbc7b7b18ad75f86278fe25fd85ba485d2.tar.bz2
pttbbs-a38ce8fbc7b7b18ad75f86278fe25fd85ba485d2.tar.lz
pttbbs-a38ce8fbc7b7b18ad75f86278fe25fd85ba485d2.tar.xz
pttbbs-a38ce8fbc7b7b18ad75f86278fe25fd85ba485d2.tar.zst
pttbbs-a38ce8fbc7b7b18ad75f86278fe25fd85ba485d2.zip
- (internal) visio: add columned output API.
git-svn-id: http://opensvn.csie.org/pttbbs/trunk/pttbbs@4170 63ad8ddf-47c3-0310-b6dd-a9e9d9715204
Diffstat (limited to 'mbbsd/visio.c')
-rw-r--r--mbbsd/visio.c204
1 files changed, 204 insertions, 0 deletions
diff --git a/mbbsd/visio.c b/mbbsd/visio.c
index 5f71645f..43b9ff3e 100644
--- a/mbbsd/visio.c
+++ b/mbbsd/visio.c
@@ -49,6 +49,26 @@ nblank(int n)
outnc(n, ' ');
}
+inline void
+fillns(int n, const char *s)
+{
+ while (n > 0 && *s)
+ outc(*s++), n--;
+ if (n > 0)
+ outnc(n, ' ');
+}
+
+inline void
+fillns_ansi(int n, char *s)
+{
+ int d = strat_ansi(n, s);
+ if (d < 0) {
+ outs(s); nblank(-d);
+ } else {
+ outns(s, d);
+ }
+}
+
// ---- VREF API --------------------------------------------------
/**
@@ -493,3 +513,187 @@ vs_footer(const char *caption, const char *msg)
outs(ANSI_RESET);
}
+/**
+ * vs_cols_layout(cols, ws, n): 依據 cols (大小寫 n) 的定義計算適合的行寬於 ws
+ */
+
+void
+vs_cols_layout(const VCOL *cols, VCOLW *ws, int n)
+{
+ int i, tw, d = 0;
+ memset(ws, 0, sizeof(VCOLW) * n);
+
+ // first run, calculate minimal size
+ for (i = 0, tw = 0; i < n; i++)
+ {
+ // drop any trailing if required
+ if (tw + cols[i].minw > MAX_COL)
+ break;
+ ws[i] = cols[i].minw;
+ tw += ws[i];
+ }
+
+ // try to iterate through all.
+ while (tw < MAX_COL) {
+ char run = 0;
+ d++;
+ for (i = 0; i < n; i++)
+ {
+ // increase fields if still ok.
+ if (cols[i].maxw - cols[i].minw < d)
+ continue;
+ ws[i] ++;
+ if (++tw >= MAX_COL) break;
+ run ++;
+ }
+ // if no more fields...
+ if (!run) break;
+ }
+}
+
+/**
+ * vs_cols_hdr: 依照已經算好的欄位輸出標題列
+ */
+void
+vs_cols_hdr (const VCOL* cols, const VCOLW *ws, int n)
+{
+ int i;
+ char *s;
+
+ outs(ANSI_COLOR(5)); // TODO use theme color?
+ for (i = 0; i < n; i++, cols++, ws++)
+ {
+ int w = *ws;
+
+ s = cols->caption;
+ if (!s) s = "";
+
+ if (!cols->usewhole)
+ w--;
+
+ if (w > 0) {
+ switch(cols->align)
+ {
+ case VCOL_ALIGN_LEFT:
+ fillns(w, s);
+ break;
+
+ case VCOL_ALIGN_RIGHT:
+ {
+ int l = strlen(s);
+
+ if (l >= w)
+ l = w;
+ else
+ nblank(w - l);
+
+ // simular to left align
+ fillns(l, s);
+ }
+ break;
+
+ default:
+ assert(0);
+ }
+ }
+
+ // only drop if w < 0 (no space for whole)
+ if (!cols->usewhole && w >= 0)
+ outc(' ');
+ }
+ outs(ANSI_RESET "\n");
+}
+
+/**
+ * vs_cols: 依照已經算好的欄位大小進行輸出
+ */
+void
+vs_cols(const VCOL *cols, const VCOLW *ws, int n, ...)
+{
+ int i = 0, w = 0;
+ char *s = NULL;
+ char ovattr = 0;
+
+ va_list ap;
+ va_start(ap, n);
+
+ for (i = 0; i < n; i++, cols++, ws++)
+ {
+ s = va_arg(ap, char*);
+
+ // quick check input.
+ if (!s)
+ {
+ s = "";
+ }
+ else if (*s == ESC_CHR && !cols->has_ansi) // special rule to escape
+ {
+ outs(s); i--; // one more parameter!
+ ovattr = 1;
+ continue;
+ }
+
+ if (cols->attr && !ovattr)
+ outs(cols->attr);
+
+ w = *ws;
+
+ if (!cols->usewhole)
+ w--;
+
+ // render value if field has enough space.
+ if (w > 0) {
+ switch (cols->align)
+ {
+ case VCOL_ALIGN_LEFT:
+ if (cols->has_ansi)
+ fillns_ansi(w, s);
+ else
+ fillns(w, s);
+ break;
+
+ case VCOL_ALIGN_RIGHT:
+ // complex...
+ {
+ int l = 0;
+ if (cols->has_ansi)
+ l = strlen_noansi(s);
+ else
+ l = strlen(s);
+
+ if (l >= w)
+ l = w;
+ else
+ nblank(w - l);
+
+ // simular to left align
+ if (cols->has_ansi)
+ fillns_ansi(l, s);
+ else
+ fillns(l, s);
+ }
+ break;
+
+ default:
+ assert(0);
+ break;
+ }
+ }
+
+ // only drop if w < 0 (no space for whole)
+ if (!cols->usewhole && w >= 0)
+ outc(' ');
+
+ if (cols->attr || cols->has_ansi || ovattr)
+ {
+ if (ovattr)
+ ovattr = 0;
+ outs(ANSI_RESET);
+ }
+ }
+ va_end(ap);
+
+ // end line
+ outs(ANSI_RESET "\n");
+}
+