diff options
author | piaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204> | 2009-10-08 17:40:19 +0800 |
---|---|---|
committer | piaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204> | 2009-10-08 17:40:19 +0800 |
commit | 49261f990fffc8affd585338b4e96698e6a3ed26 (patch) | |
tree | c6c8f4d1156a4a45dfe5c680c8f356fb565f51f6 | |
parent | 56df18c2ec194b4207ba2c471fc54d396110ee70 (diff) | |
download | pttbbs-49261f990fffc8affd585338b4e96698e6a3ed26.tar pttbbs-49261f990fffc8affd585338b4e96698e6a3ed26.tar.gz pttbbs-49261f990fffc8affd585338b4e96698e6a3ed26.tar.bz2 pttbbs-49261f990fffc8affd585338b4e96698e6a3ed26.tar.lz pttbbs-49261f990fffc8affd585338b4e96698e6a3ed26.tar.xz pttbbs-49261f990fffc8affd585338b4e96698e6a3ed26.tar.zst pttbbs-49261f990fffc8affd585338b4e96698e6a3ed26.zip |
* move help rendering (as T-Table) from more.c to vtuikit: vs_multi_T_table_simple
git-svn-id: http://opensvn.csie.org/pttbbs/trunk@4916 63ad8ddf-47c3-0310-b6dd-a9e9d9715204
-rw-r--r-- | pttbbs/include/vtuikit.h | 4 | ||||
-rw-r--r-- | pttbbs/mbbsd/more.c | 354 | ||||
-rw-r--r-- | pttbbs/mbbsd/vtuikit.c | 58 |
3 files changed, 228 insertions, 188 deletions
diff --git a/pttbbs/include/vtuikit.h b/pttbbs/include/vtuikit.h index 09257345..7a2080a9 100644 --- a/pttbbs/include/vtuikit.h +++ b/pttbbs/include/vtuikit.h @@ -140,6 +140,10 @@ void vs_hdr (const char *title); // vs_bar, stand_title void vs_footer (const char *caption, const char *prompt); void vs_rectangle_simple(int l, int t, int r, int b); // draw a single line rectangle, not filling inside interior +void vs_multi_T_table_simple( + const char ***t_tables, int n_t_tables, + const int *col_widths, const int *l_widths, + const char *attr_caption, const char *attr_l, const char *attr_r); // columned output void vs_cols_layout (const VCOL* cols, VCOLW *ws, int n); /// calculate VCOL to fit current screen in ws diff --git a/pttbbs/mbbsd/more.c b/pttbbs/mbbsd/more.c index 8859d14a..b732a387 100644 --- a/pttbbs/mbbsd/more.c +++ b/pttbbs/mbbsd/more.c @@ -35,7 +35,149 @@ check_sysop_edit_perm(const char *fpath) return 1; } -#ifdef USE_PMORE +#ifndef USE_PMORE /////////////////////////////////////////////////////////// + +// minimore: a mini pager in exactly 130 lines +#define PAGER_MAXLINES (2048) +int more(const char *fpath, int promptend) +{ + FILE *fp = fopen(fpath, "rt"); + int lineno = 0, lines = 0, oldlineno = -1; + int i = 0, abort = 0, showall = 0, colorize = 0; + int lpos[PAGER_MAXLINES] = {0}; // line position + char buf [ANSILINELEN]; + + if (!fp) return -1; + clear(); + + if (promptend == NA) { // quick print one page + for (i = 0; i < t_lines-1; i++) + if (!fgets(buf, sizeof(buf), fp)) + break; + else + outs(buf); + fclose(fp); + return 0; + } + // YEA mode: pre-read + while (lines < PAGER_MAXLINES-1 && + fgets(buf, sizeof(buf), fp) != NULL) + lpos[++lines] = ftell(fp); + rewind(fp); + + while (!abort) + { + if (oldlineno != lineno) // seek and print + { + clear(); + showall = 0; + oldlineno = lineno; + fseek(fp, lpos[lineno], SEEK_SET); + + for (i = 0, buf[0] = 0; i < t_lines-1; i++, buf[0] = 0) + { + if (!showall) + { + fgets(buf, sizeof(buf), fp); + if (lineno + i == 0 && + (strncmp(buf, STR_AUTHOR1, strlen(STR_AUTHOR1))==0 || + strncmp(buf, STR_AUTHOR2, strlen(STR_AUTHOR2))==0)) + colorize = 1; + } + + if (!buf[0]) + { + outs("\n"); + showall = 1; + } else { + // dirty code to render heeader + if (colorize && lineno+i < 4 && *buf && + *buf != '\n' && strchr(buf, ':')) + { + char *q1 = strchr(buf, ':'); + int l = t_columns - 2 - strlen(buf); + char *q2 = strstr(buf, STR_POST1); + + chomp(buf); + if (q2 == NULL) q2 = strstr(buf, STR_POST2); + if (q2) { *(q2-1) = 0; q2 = strchr(q2, ':'); } + else q2 = q1; + + *q1++ = 0; *q2++ = 0; + if (q1 == q2) q2 = NULL; + + outs(ANSI_COLOR(34;47) " "); + outs(buf); outs(" " ANSI_REVERSE); + outs(q1); prints("%*s", l, ""); q1 += strlen(q1); + + if (q2) { + outs(ANSI_COLOR(0;34;47) " "); outs(q1+1); + outs(" " ANSI_REVERSE); outs(q2); + } + outs(ANSI_RESET"\n"); + } else + outs(buf); + } + } + if (lineno + i >= lines) + showall = 1; + + // print prompt bar + snprintf(buf, sizeof(buf), + " 瀏覽 P.%d ", 1 + (lineno / (t_lines-2))); + vs_footer(buf, + " (→↓[PgUp][PgDn][Home][End])游標移動\t(←/q)結束"); + } + // process key + switch(vkey()) { + case KEY_UP: case 'k': case Ctrl('P'): + if (lineno == 0) abort = READ_PREV; + lineno--; + break; + + case KEY_PGUP: case Ctrl('B'): + if (lineno == 0) abort = READ_PREV; + lineno -= t_lines-2; + break; + + case KEY_PGDN: case Ctrl('F'): case ' ': + case KEY_RIGHT: + if (showall) abort = READ_NEXT; + lineno += t_lines-2; + break; + + case KEY_DOWN: case 'j': case Ctrl('N'): + if (showall) abort = READ_NEXT; + lineno++; + break; + case KEY_HOME: case Ctrl('A'): + lineno = 0; + break; + case KEY_END: case Ctrl('E'): + lineno = lines - (t_lines-1); + break; + case KEY_LEFT: case 'q': + abort = FULLUPDATE; + break; + + case 'b': + abort = READ_PREV; + break; + case 'f': + abort = READ_NEXT; + break; + } + if (lineno + (t_lines-1) >= lines) + lineno = lines-(t_lines-1); + if (lineno < 0) + lineno = 0; + } + fclose(fp); + return abort > 0 ? abort : 0; +} + +#else // USE_PMORE //////////////////////////////////////////////////////// + static int common_pmore_key_handler(int ch, void *ctx) { @@ -65,7 +207,8 @@ common_pmore_key_handler(int ch, void *ctx) return RET_COPY2TMP; case 'E': - if (!check_sysop_edit_perm("")) // for early check, skip file name (must check again later) + // for early check, skip file name (must check again later) + if (!check_sysop_edit_perm("")) break; return RET_DOSYSOPEDIT; @@ -118,70 +261,45 @@ common_pmore_key_handler(int ch, void *ctx) static const char *hlp_nav [] = { "【瀏覽指令】", NULL, - "下篇文章 ", "f", - "前篇文章 ", "b", - "同主題下篇", "] +", - "同主題前篇", "[ -", - "同主題首篇", "=", - "同主題循序", "t", - "同作者前篇", "A", - "同作者下篇", "a", + " 下篇文章 ", "f", + " 前篇文章 ", "b", + " 同主題下篇", "] +", + " 同主題前篇", "[ -", + " 同主題首篇", "=", + " 同主題循序", "t", + " 同作者前篇", "A", + " 同作者下篇", "a", NULL, }, *hlp_reply [] = { "【回應指令】", NULL, - "推薦文章", "% X", - "回信回文", "r", - "全部回覆", "y", + " 推薦文章", "% X", + " 回信回文", "r", + " 全部回覆", "y", NULL, }, *hlp_spc [] = { "【特殊指令】", NULL, - "查詢資訊 ", "Q", - "存入暫存檔", "^T", - "切換看板 ", "s", - "棋局打譜 ", "z", + " 查詢資訊 ", "Q", + " 存入暫存檔", "^T", + " 切換看板 ", "s", + " 棋局打譜 ", "z", #if defined(USE_BBSLUA) && !defined(DISABLE_BBSLUA_IN_PAGER) - "執行BBSLua", "L l", + " 執行BBSLua", "L l", #endif NULL, }; -#ifndef PMHLPATTR_NORMAL -#define PMHLPATTR_NORMAL ANSI_COLOR(0) -#define PMHLPATTR_NORMAL_KEY ANSI_COLOR(0;1;36) -#define PMHLPATTR_HEADER ANSI_COLOR(0;1;32) -#endif - -// TODO make this help renderer into vtuikit or other location someday static int common_pmore_help_handler(int y, void *ctx) { // simply show ptt special function keys - int i; const char ** p[3] = { hlp_nav, hlp_reply, hlp_spc }; - const int cols[3] = { 29, 29, 20 }, // columns - desc[3] = { 14, 11, 13 }; // desc width + const int cols[3] = { 29, 29, 20 }, // columns, to fit pmore built-ins + desc[3] = { 15, 12, 14 }; // desc width move(y+1, 0); - // render help page - while (*p[0] || *p[1] || *p[2]) - { - y++; - for ( i = 0; i < 3; i++ ) - { - const char *dstr = "", *kstr = ""; - if (*p[i]) { - dstr = *p[i]++; kstr = *p[i]++; - } - if (!kstr) - prints( PMHLPATTR_HEADER "%-*s", cols[i], dstr); - else - prints( PMHLPATTR_NORMAL " %-*s" - PMHLPATTR_NORMAL_KEY "%-*s", - desc[i], dstr, cols[i]-desc[i]-1, kstr); - } - outs("\n"); - } + vs_multi_T_table_simple(p, 3, cols, desc, + ANSI_COLOR(1;32), ANSI_COLOR(0), ANSI_COLOR(1;36) ); PRESSANYKEY(); return 0; } @@ -248,145 +366,5 @@ more(const char *fpath, int promptend) return r; } -#else // !USE_PMORE - -// minimore: a mini pager in exactly 130 lines -#define PAGER_MAXLINES (2048) -int more(const char *fpath, int promptend) -{ - FILE *fp = fopen(fpath, "rt"); - int lineno = 0, lines = 0, oldlineno = -1; - int i = 0, abort = 0, showall = 0, colorize = 0; - int lpos[PAGER_MAXLINES] = {0}; // line position - char buf [ANSILINELEN]; - - if (!fp) return -1; - clear(); - - if (promptend == NA) { // quick print one page - for (i = 0; i < t_lines-1; i++) - if (!fgets(buf, sizeof(buf), fp)) - break; - else - outs(buf); - fclose(fp); - return 0; - } - // YEA mode: pre-read - while (lines < PAGER_MAXLINES-1 && - fgets(buf, sizeof(buf), fp) != NULL) - lpos[++lines] = ftell(fp); - rewind(fp); - - while (!abort) - { - if (oldlineno != lineno) // seek and print - { - clear(); - showall = 0; - oldlineno = lineno; - fseek(fp, lpos[lineno], SEEK_SET); - - for (i = 0, buf[0] = 0; i < t_lines-1; i++, buf[0] = 0) - { - if (!showall) - { - fgets(buf, sizeof(buf), fp); - if (lineno + i == 0 && - (strncmp(buf, STR_AUTHOR1, strlen(STR_AUTHOR1))==0 || - strncmp(buf, STR_AUTHOR2, strlen(STR_AUTHOR2))==0)) - colorize = 1; - } - - if (!buf[0]) - { - outs("\n"); - showall = 1; - } else { - // dirty code to render heeader - if (colorize && lineno+i < 4 && *buf && - *buf != '\n' && strchr(buf, ':')) - { - char *q1 = strchr(buf, ':'); - int l = t_columns - 2 - strlen(buf); - char *q2 = strstr(buf, STR_POST1); - - chomp(buf); - if (q2 == NULL) q2 = strstr(buf, STR_POST2); - if (q2) { *(q2-1) = 0; q2 = strchr(q2, ':'); } - else q2 = q1; - - *q1++ = 0; *q2++ = 0; - if (q1 == q2) q2 = NULL; - - outs(ANSI_COLOR(34;47) " "); - outs(buf); outs(" " ANSI_REVERSE); - outs(q1); prints("%*s", l, ""); q1 += strlen(q1); - - if (q2) { - outs(ANSI_COLOR(0;34;47) " "); outs(q1+1); - outs(" " ANSI_REVERSE); outs(q2); - } - outs(ANSI_RESET"\n"); - } else - outs(buf); - } - } - if (lineno + i >= lines) - showall = 1; - - // print prompt bar - snprintf(buf, sizeof(buf), - " 瀏覽 P.%d ", 1 + (lineno / (t_lines-2))); - vs_footer(buf, - " (→↓[PgUp][PgDn][Home][End])游標移動\t(←/q)結束"); - } - // process key - switch(vkey()) { - case KEY_UP: case 'k': case Ctrl('P'): - if (lineno == 0) abort = READ_PREV; - lineno--; - break; - - case KEY_PGUP: case Ctrl('B'): - if (lineno == 0) abort = READ_PREV; - lineno -= t_lines-2; - break; - - case KEY_PGDN: case Ctrl('F'): case ' ': - case KEY_RIGHT: - if (showall) abort = READ_NEXT; - lineno += t_lines-2; - break; - - case KEY_DOWN: case 'j': case Ctrl('N'): - if (showall) abort = READ_NEXT; - lineno++; - break; - case KEY_HOME: case Ctrl('A'): - lineno = 0; - break; - case KEY_END: case Ctrl('E'): - lineno = lines - (t_lines-1); - break; - case KEY_LEFT: case 'q': - abort = FULLUPDATE; - break; - - case 'b': - abort = READ_PREV; - break; - case 'f': - abort = READ_NEXT; - break; - } - if (lineno + (t_lines-1) >= lines) - lineno = lines-(t_lines-1); - if (lineno < 0) - lineno = 0; - } - fclose(fp); - return abort > 0 ? abort : 0; -} +#endif // USE_PMORE ///////////////////////////////////////////////////////// -#endif // !USE_PMORE diff --git a/pttbbs/mbbsd/vtuikit.c b/pttbbs/mbbsd/vtuikit.c index 9dbcdf55..a18df7a1 100644 --- a/pttbbs/mbbsd/vtuikit.c +++ b/pttbbs/mbbsd/vtuikit.c @@ -770,6 +770,64 @@ vs_cols(const VCOL *cols, const VCOLW *ws, int n, ...) outs(ANSI_RESET "\n"); } +/* + * vs_multi_T_table_simple: render multiple T-type tables + * + * @param t_tables NOTE: the pointers inside will be changed. + * + * T table format: + * const char *table[] = { + * "caption", NULL, + * "lvar", "rvar", + * NULL + * }; + */ +void +vs_multi_T_table_simple( + const char ***t_tables, int n_t_tables, + const int *col_widths, const int *l_widths, + const char *attr_caption, const char *attr_l, const char *attr_r) +{ + int i; + int incomplete; + + do + { + incomplete = n_t_tables; + for (i = 0; i < n_t_tables; i++) + { + const char *lvar = NULL, *rvar = ""; + + if (*t_tables[i]) + { + lvar = *t_tables[i]++; + rvar = *t_tables[i]++; + } + + if (!rvar) { + // draw caption + if (attr_caption) outs(attr_caption); + vfill(col_widths[i], 0, lvar); + continue; + } + + if (!lvar) { + // table is complete... + incomplete --; + lvar = ""; + } + + // draw table body + if(attr_l) outs(attr_l); + vfill(l_widths[i], 0, lvar); + if(attr_r) outs(attr_r); + vfill(col_widths[i] - l_widths[i], 0, rvar); + } + outc('\n'); + } + while (incomplete); +} + //////////////////////////////////////////////////////////////////////// // DBCS Aware Helpers //////////////////////////////////////////////////////////////////////// |