作者itoc, 信區: itoc
標題[功能] 使用者自定主選單(2)
時間03/07/16
作者: itoc (風調雨順,國泰民安) 看板: plan
標題: [功能] 使用者自定主選單(2)
時間: Wed Jul 16 22:13:30 2003 Updated: 2003/07/17
使用者自定主選單(2) 編輯自定主選單
: menu.c 一開始
extern UCACHE *ushm;
+ static int launch_set();
: menu.c 在適當的選單加入
+ launch_set, PERM_VALID, M_XMODE,
+ "Menu 《 自定選單 》",
: menu.c 最後加入以下這整段
/* ----------------------------------------------------- */
/* 使用者自定 Quick Launch */
/* ----------------------------------------------------- */
#define MAX_LAUNCH (22 - MENU_XPOS)
static char *fn_quick = "quick";
typedef struct
{
int key;
void *func;
int umode;
char *desc;
} LaunchFunc;
/* 要加 list 的在這邊加 */
#define LAUNCHLIST_LEN 17
static LaunchFunc quick_cb[LAUNCHLIST_LEN + 1] =
{
/* 編號不用照順序,也可以隨便給,只要是不重覆的整數即可,
但是編號不能變動 (因為會存在 user 目錄的 quick 檔中) */
/* 編號, 函式, 動態, 選單敘述 */
1, Boards, M_BOARD, "Boards ← 佈告討論 →",
2, Class, M_BOARD, "Class ← 分組討論 →",
3, MyFavorite, M_MF, "Favorite ← 我的最愛 →",
4, Gem, M_GEM, "Announce ← 精華公佈 →",
101, XoMbox, M_RMAIL, "Read ← 閱\讀信件 →",
102, m_send, M_SMAIL, "Mail ← 站內寄信 →",
103, m_internet, M_SMAIL, "Internet ← 寄依妹兒 →",
201, t_pal, M_PAL, "GoodFriend ← 好友設定 →",
202, XoUlist, M_LUSERS, "Users ← 遊客名單 →",
203, t_query, M_QUERY, "Query ← 查詢網友 →",
204, t_display, M_BMW, "Display ← 瀏覽水球 →",
205, t_bmw, M_BMW, "Write ← 回顧水球 →",
206, bin/chat.so:t_chat", - M_CHAT, "Chat ← 眾口鑠金 →",
301, u_info, M_XMODE, "Info ← 個人資料 →",
302, u_setup, M_UFILES, "Habit ← 喜好模式 →",
303, pad_view, M_READA, "Note ← 觀看留言 →",
401, "bin/enews.so:main_enews", - M_XMODE, "Kimo ← 奇摩新聞 →",
/* 最後一個固定是 0, goodbye */
0, goodbye, M_XMODE, "Goodbye ← 下次再會 →"
};
static int
launch_set()
{
int i, num, keylist[MAX_LAUNCH];
char buf[80];
LaunchFunc *cb;
/* 界面做得頗遜,只能支援到 LAUNCHLIST_LEN = 20,想改的人再自己改 :p */
memset(keylist, 0, sizeof(keylist));
clear();
for (i = 0; i < LAUNCHLIST_LEN; i++)
{
cb = quick_cb + i;
move(i + 2, 0);
prints("%2d %s", i + 1, cb->desc);
}
i = 0;
while (vget(b_lines, 0, "請選擇快捷列選項:", buf, 4, DOECHO))
{
num = atoi(buf) - 1;
if (num >= 0 && num < LAUNCHLIST_LEN)
{
cb = quick_cb + num;
keylist[i] = cb->key;
move(i + 2, 40);
prints("捷徑 %d:%s", i + 1, cb->desc);
if (++i >= MAX_LAUNCH - 1)
{
sprintf(buf, "最多只能加 %d 個捷徑而已", MAX_LAUNCH - 1);
vmsg(buf);
break;
}
}
}
if (i)
{
/* 最後再補上一個捷徑:goodbye */
keylist[i] = (quick_cb + LAUNCHLIST_LEN)->key;
usr_fpath(buf, cuser.userid, fn_quick);
unlink(buf);
rec_add(buf, keylist, sizeof(keylist));
}
return 0;
}
/* ----------------------------------------------------- */
/* 使用 Quick Launch Skin */
/* ----------------------------------------------------- */
static MENU menu_launch[MAX_LAUNCH];
static int /* 回傳設了幾個 quick launch */
launch_load()
{
int i, key, keylist[MAX_LAUNCH];
char fpath[64];
LaunchFunc *cb;
MENU *menu;
usr_fpath(fpath, cuser.userid, fn_quick);
if (rec_get(fpath, keylist, sizeof(keylist), 0))
return 0;
menu = menu_launch;
for (i = 0; i < MAX_LAUNCH; i++)
{
cb = quick_cb;
do
{
key = cb->key;
if (key == keylist[i])
break;
cb++;
} while (key);
menu->func = cb->func;
menu->umode = cb->umode;
menu->desc = cb->desc;
menu++;
if (!key)
break;
}
return i;
}
void
skin()
{
MENU *mptr;
usint mode;
int cc, cx; /* current / previous cursor position */
int max; /* menu max */
int cmd;
char *str;
int (*func) ();
if (!(max = launch_load()))
{
menu();
return;
}
mode = MENU_DRAW | MENU_FILM;
cmd = KEY_HOME; /* default command */
for (;;)
{
if (mode & MENU_DRAW)
{
if (mode & MENU_FILM)
{
clear();
movie();
cx = -1;
}
vs_head("快捷列", NULL);
for (mode = 0; mode <= max; mode++)
{
move(MENU_XPOS + mode, MENU_YPOS + 2);
mptr = menu_launch + mode;
str = mptr->desc;
prints("(\033[1;36m%c\033[m)", *str++);
outs(str);
clrtoeol();
}
}
mode = 0;
switch (cmd)
{
case KEY_DOWN:
cc = (cc == max) ? 0 : cc + 1;
break;
case KEY_UP:
cc = (cc == 0) ? max : cc - 1;
break;
case Ctrl('A'): /* itoc.020829: 預設選項第一個 */
case KEY_HOME:
cc = 0;
break;
case KEY_END:
cc = max;
break;
case KEY_PGUP:
cc = (cc == 0) ? max : 0;
break;
case KEY_PGDN:
cc = (cc == max) ? 0 : max;
break;
case '\n':
case KEY_RIGHT:
mptr = menu_launch + cc;
cmd = mptr->umode;
if (cmd >= 0)
{
utmp_mode(cmd);
func = mptr->func;
mode = (*func) ();
}
else /* dynamic load */
{
if (func = DL_get(mptr->func))
{
utmp_mode(-cmd);
mode = (*func)();
}
else
mode = XEASY;
}
utmp_mode(M_0MENU);
if (mode == XEASY)
{
outz(feeter);
mode = 0;
}
else
{
mode = MENU_DRAW | MENU_FILM;
}
cmd = mptr->desc[0];
continue;
#ifdef EVERY_Z
case Ctrl('Z'):
every_Z(0);
goto every_key;
case Ctrl('U'):
every_U(0);
goto every_key;
#endif
/* itoc.010911: Select everywhere,不再限制是在 M_0MENU */
case 's':
case Ctrl('S'):
utmp_mode(M_BOARD);
Select();
goto every_key;
#ifdef MY_FAVORITE
/* itoc.010911: Favorite everywhere,不再限制是在 M_0MENU */
case 'f':
case Ctrl('F'):
if (HAS_PERM(PERM_BASIC)) /* itoc.010407: 要檢查權限 */
{
utmp_mode(M_MF);
MyFavorite();
}
goto every_key;
#endif
case Ctrl('X'):
cuser.ufo &= ~UFO_USERSKIN;
vmsg("重新上站後就會恢復原來的公版選單");
goto default_key;
every_key: /* 特殊鍵處理結束 */
utmp_mode(M_0MENU);
mode = MENU_DRAW | MENU_FILM;
cmd = (menu_launch + cc)->desc[0];
continue;
case KEY_LEFT:
case 'e':
cmd = 'G';
default_key:
default:
if (cmd >= 'a' && cmd <= 'z')
cmd -= 0x20;
cc = 0;
for (;;)
{
if ((menu_launch + cc)->desc[0] == cmd)
break;
if (++cc > max)
{
cc = cx;
goto menu_key;
}
}
}
if (cc != cx) /* 若游標移動位置 */
{
#ifdef CURSOR_BAR
if (cx >= 0)
{
move(MENU_XPOS + cx, MENU_YPOS);
if (cx <= max)
{
mptr = menu_launch + cx;
str = mptr->desc;
prints(" (\033[1;36m%c\033[m)", *str++);
prints("%s ", str);
}
else
{
outs(" ");
}
}
move(MENU_XPOS + cc, MENU_YPOS);
mptr = menu_launch + cc;
str = mptr->desc;
prints(COLOR4 "> (%c)", *str++);
prints("%s \033[m", str);
cx = cc;
#else /* 沒有 CURSOR_BAR */
if (cx >= 0)
{
move(MENU_XPOS + cx, MENU_YPOS);
outc(' ');
}
move(MENU_XPOS + cc, MENU_YPOS);
outc('>');
cx = cc;
#endif
}
else /* 若游標的位置沒有變 */
{
#ifdef CURSOR_BAR
move(MENU_XPOS + cc, MENU_YPOS);
mptr = menu_launch + cc;
str = mptr->desc;
prints(COLOR4 "> (%c)", *str++);
prints("%s \033[m", str);
#else
move(MENU_XPOS + cc, MENU_YPOS + 1);
#endif
}
menu_key:
cmd = vkey();
}
}
--
□ 本文章由 itoc 從 itoc.Dorm11.NCTU.edu.tw 發表精華選讀←離開[主題上]主題下(k)上篇(j)下篇S/a搜尋 G串列 TAB精華 ↑↓捲 Pg/Space翻