summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpiaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2009-10-08 17:40:19 +0800
committerpiaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2009-10-08 17:40:19 +0800
commit49261f990fffc8affd585338b4e96698e6a3ed26 (patch)
treec6c8f4d1156a4a45dfe5c680c8f356fb565f51f6
parent56df18c2ec194b4207ba2c471fc54d396110ee70 (diff)
downloadpttbbs-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.h4
-rw-r--r--pttbbs/mbbsd/more.c354
-rw-r--r--pttbbs/mbbsd/vtuikit.c58
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
////////////////////////////////////////////////////////////////////////