⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 menu.c

📁 举世闻名的joe记事本源程序
💻 C
字号:
/* *	Menu selection window *	Copyright *		(C) 1992 Joseph H. Allen * *	This file is part of JOE (Joe's Own Editor) */#include "types.h"int bg_menu;int transpose;static void menufllw(MENU *m){	if (transpose) {		if ((m->cursor % m->lines) < m->top)			m->top = m->cursor % m->lines;		else if (m->cursor % m->lines >= (m->top % m->lines) + m->h)			m->top = (m->cursor % m->lines) - (m->h - 1);	} else {		if (m->cursor < m->top)			m->top = m->cursor - m->cursor % m->perline;		else if (m->cursor >= m->top+m->perline*m->h)			m->top = m->cursor - m->cursor % m->perline - m->perline*(m->h-1);	}}static void menudisp(MENU *m){	int col;	int x;	int y;	int *s = m->t->t->scrn + m->x + m->y * m->t->t->co;	int *a = m->t->t->attr + m->x + m->y * m->t->t->co;	struct utf8_sm sm;	int cut = m->nitems % m->lines;	if (!cut) cut = m->lines;	utf8_init(&sm);	for (y = 0; y != m->h; ++y) {		col = 0;		if (transpose) {			for (x = 0; x < ((y + m->top) >= cut ? m->perline - 1 : m->perline) ; ++x) {				int atr;				int index = x * m->lines + y + m->top;						if (index == m->cursor && m->t->curwin == m->parent)					atr = INVERSE|BG_COLOR(bg_menu);				else					atr = BG_COLOR(bg_menu);				if (col == m->w)					break;				/* Generate field */				genfield(m->t->t,					 s + col,					 a + col,					 m->x + col,					 m->y + y,					 0,					 m->list[index],					 zlen(m->list[index]),					 atr,					 m->width,					 0,NULL);				col += m->width;				/* Space between columns */				if (col != m->w) {					outatr(locale_map, m->t->t, s + col, a + col, m->x + col, m->y+y, ' ', BG_COLOR(bg_menu));					++col;				}			}		} else {			for (x = 0; x != m->perline && y * m->perline + x + m->top < m->nitems; ++x) {				int atr;				int index = x + y * m->perline + m->top;						if (index == m->cursor && m->t->curwin==m->parent)					atr = INVERSE|BG_COLOR(bg_menu);				else					atr = BG_COLOR(bg_menu);				if (col == m->w)					break;				/* Generate field */				genfield(m->t->t,					 s + col,					 a + col,					 m->x + col,					 m->y + y,					 0,					 m->list[index],					 zlen(m->list[index]),					 atr,					 m->width,					 0,NULL);				col += m->width;				/* Space between columns */				if (col != m->w) {					outatr(locale_map, m->t->t, s + col, a + col, m->x + col, m->y+y, ' ', BG_COLOR(bg_menu));					++col;				}			}		}		/* Clear to end of line */		if (col != m->w)			eraeol(m->t->t, m->x + col, m->y + y, BG_COLOR(bg_menu));		s += m->t->t->co;		a += m->t->t->co;	}	if (transpose) {		m->parent->cury = (m->cursor % m->lines) - m->top;		col = txtwidth(m->list[m->cursor],zlen(m->list[m->cursor]));		if (col < m->width)			m->parent->curx = (m->cursor / m->lines) * (m->width + 1) + col;		else			m->parent->curx = (m->cursor / m->lines) * (m->width + 1) + m->width;	} else {		m->parent->cury = (m->cursor - m->top) / m->perline;		col = txtwidth(m->list[m->cursor],zlen(m->list[m->cursor]));		if (col < m->width)			m->parent->curx = ((m->cursor - m->top) % m->perline) * (m->width + 1) + col;		else			m->parent->curx = ((m->cursor - m->top) % m->perline) * (m->width + 1) + m->width;	}}static void menumove(MENU *m, int x, int y){	m->x = x;	m->y = y;}static int mlines(unsigned char **s, int w){	int x;	int lines;	int width;	int nitems;	int perline;	for (x = 0, width = 0; s[x]; ++x) {		int d = txtwidth(s[x],zlen(s[x]));		if (d > width)			width = d;	}	nitems = x;	if (width > w)		width = w - 1;	perline = w / (width + 1);	lines = (nitems + perline - 1) / perline;	return lines;}static void mconfig(MENU *m){	/* Configure menu display parameters */	if (m->list) {		int x;		/* int lines; */		m->top = 0;		for (x = 0, m->width = 0; m->list[x]; ++x) {			int d = txtwidth(m->list[x],zlen(m->list[x]));			if (d > m->width)				m->width = d;		}		m->nitems = x;		if (m->width > m->w)			m->width = m->w - 1;		m->fitline = m->w / (m->width + 1);		m->lines = (m->nitems + m->fitline - 1) / m->fitline;		if (transpose)			m->perline = (m->nitems + m->lines - 1) / m->lines;		else			m->perline = m->fitline;	}}static void menuresz(MENU *m, int wi, int he){	m->w = wi;	m->h = he;	mconfig(m);}int umbol(MENU *m){	if (transpose)		m->cursor %= m->lines;	else		m->cursor -= m->cursor % m->perline;	return 0;}int umbof(MENU *m){	m->cursor = 0;	return 0;}int umeof(MENU *m){	if (m->nitems) {		if (transpose && (m->nitems % m->lines != 0)) {			m->cursor = m->lines - 1 + (m->lines * (m->perline - 2));		} else {			m->cursor = m->nitems - 1;		}	}	return 0;}int umeol(MENU *m){	if (transpose) {		int cut = m->nitems % m->lines;		if (!cut) cut = m->lines;		m->cursor %= m->lines;		if (m->cursor >= cut)			m->cursor += m->lines * (m->perline - 2);		else			m->cursor += m->lines * (m->perline - 1);	} else {		m->cursor -= m->cursor % m->perline;		if (m->cursor+m->perline-1 >= m->nitems)			m->cursor = m->nitems - 1;		else			m->cursor += m->perline - 1;	}	return 0;}int umrtarw(MENU *m){	if (transpose) {		int cut = m->nitems % m->lines;		if (!cut) cut = m->lines;		if (m->cursor % m->lines >= cut) {			if (m->cursor / m->lines != m->perline - 2) {				m->cursor += m->lines;				return 0;			}		} else {			if (m->cursor / m->lines != m->perline - 1) {				m->cursor += m->lines;				return 0;			}		}		if ((m->cursor % m->lines) + 1 < m->lines) {			m->cursor = m->cursor % m->lines + 1;			return 0;		}		return -1;	} else if (m->cursor + 1 < m->nitems) {		++m->cursor;		return 0;	} else		return -1;}int umtab(MENU *m){	if (m->cursor + 1 >= m->nitems)		m->cursor = 0;	else		++ m->cursor;	return 0;}int umltarw(MENU *m){	if (transpose && m->cursor >= m->lines) {		m->cursor -= m->lines;		return 0;	} else if (transpose && m->cursor) {		int cut = m->nitems % m->lines;		if (!cut) cut = m->lines;		--m->cursor;		if (m->cursor >= cut)			m->cursor += (m->perline - 2) * m->lines;		else			m->cursor += (m->perline - 1) * m->lines;		return 0;	} else if (!transpose && m->cursor) {		--m->cursor;		return 0;	} else		return -1;}int umuparw(MENU *m){	if (transpose && (m->cursor % m->lines)) {		--m->cursor;		return 0;	} else if (!transpose && m->cursor >= m->perline) {		m->cursor -= m->perline;		return 0;	} else		return -1;}int umdnarw(MENU *m){	if (transpose) {		if (m->cursor != m->nitems - 1 && m->cursor % m->lines != m->lines - 1) {			++m->cursor;			return 0;		} else {			return -1;		}	} else {		int col = m->cursor % m->perline;	        m->cursor -= col;		if (m->cursor + m->perline < m->nitems) {			m->cursor += m->perline;			if (m->cursor + col >= m->nitems)				if (m->nitems)					m->cursor = m->nitems - 1;				else					m->cursor = 0;			else				m->cursor += col;			return 0;		} else {			m->cursor += col;			return -1;		}	}}void menujump(MENU *m,int x,int y){	int pos = m->top;	if (transpose) {		pos += y;		pos += (x / (m->width + 1)) * m->lines;	} else {		pos += y * m->perline;		pos += x / (m->width + 1);	}	if (pos >= m->nitems)		pos = m->nitems - 1;	if (pos < 0)		pos = 0;	m->cursor = pos;}int mscrup(MENU *m,int amnt){	if (transpose) {		if (m->top >= amnt) {			m->top -= amnt;			m->cursor -= amnt;			return 0;		} else if (m->top) {			m->cursor -= m->top;			m->top = 0;			return 0;		} else if (m->cursor % m->lines) {			m->cursor -= (m->cursor % m->lines);			return 0;		} else			return -1;	} else {		if (m->top >= amnt*m->perline) {			m->top -= amnt*m->perline;			m->cursor -= amnt*m->perline;			return 0;		} else if (m->top) {			m->cursor -= m->top;			m->top = 0;			return 0;		} else if (m->cursor >= m->perline) {			m->cursor = m->cursor % m->perline;			return 0;		} else			return -1;	}}int umscrup(MENU *m){	return mscrup(m, 1);}int umpgup(MENU *m){	return mscrup(m, (m->h + 1) / 2);}int mscrdn(MENU *m, int amnt){	if (transpose) {		int col = m->cursor / m->lines;		int y = m->cursor % m->lines;		int h = m->lines;		int t = m->top;		int cut = m->nitems % m->lines;		if (!cut) cut = m->lines;		m->cursor %= m->lines;		if (t + m->h + amnt <= h) {			m->top += amnt;			m->cursor += amnt;			if (m->cursor >= cut && col == m->perline - 1)				--col;			m->cursor += col * m->lines;			return 0;		} else if (t + m->h < h) {			amnt = h - (t + m->h);			m->top += amnt;			m->cursor += amnt;			if (m->cursor >= cut && col == m->perline - 1)				--col;			m->cursor += col * m->lines;			return 0;		} else if (y + 1 != h) {			m->cursor = h - 1;			if (m->cursor >= cut && col == m->perline - 1)				--col;			m->cursor += col * m->lines;			return 0;		} else {			m->cursor += col * m->lines;			return -1;		}	} else {		int col = m->cursor % m->perline;		int y = m->cursor / m->perline;		int h = (m->nitems + m->perline - 1) / m->perline;		int t = m->top / m->perline;		m->cursor -= col;		if (t + m->h + amnt <= h) {			m->top += amnt*m->perline;			m->cursor += amnt*m->perline;			if (m->cursor + col >= m->nitems)				if (m->nitems)					m->cursor = m->nitems - 1;				else					m->cursor = 0;			else				m->cursor += col;			return 0;		} else if (t + m->h < h) {			amnt = h - (t + m->h);			m->top += amnt*m->perline;			m->cursor += amnt*m->perline;			if (m->cursor + col >= m->nitems)				if (m->nitems)					m->cursor = m->nitems - 1;				else					m->cursor = 0;			else				m->cursor += col;			return 0;		} else if (y+1!=h) {			m->cursor = (h-1)*m->perline;			if (m->cursor + col >= m->nitems)				if (m->nitems)					m->cursor = m->nitems - 1;				else					m->cursor = 0;			else				m->cursor += col;			return 0;		} else {			m->cursor += col;			return -1;		}	}}int umscrdn(MENU *m){	return mscrdn(m, 1);}int umpgdn(MENU *m){	return mscrdn(m, (m->h + 1) / 2);}static int umrtn(MENU *m){	dostaupd = 1;	if (m->func)		return m->func(m, m->cursor, m->object, 0);	else		return -1;}int umbacks(MENU *m){	if (m->backs)		return m->backs(m, m->cursor, m->object);	else		return -1;}static int umkey(MENU *m, int c){	int x;	int n = 0;	if (c == '0') {		if (m->func)			return m->func(m, m->cursor, m->object, -1);		else			return -1;	}	if (c == '1') {		if (m->func)			return m->func(m, m->cursor, m->object, 1);		else			return -1;	}	c &= 0x1F;	for (x = 0; x != m->nitems; ++x)		if ((m->list[x][0] & 0x1F) == c)			++n;	if (!n)		return -1;	if (n == 1)		for (x = 0; x != m->nitems; ++x)			if ((m->list[x][0] & 0x1F) == c) {				m->cursor = x;				return umrtn(m);			}	do {		++m->cursor;		if (m->cursor == m->nitems)			m->cursor = 0;	} while ((m->list[m->cursor][0] & 0x1F) != c);	return -1;}static int menuabort(MENU *m){	W *w = m->parent;	int (*func) () = m->abrt;	void *object = m->object;	int x = m->cursor;	W *win = w->win;	joe_free(m);	if (func)		return func(win->object, x, object);	else		return -1;}WATOM watommenu = {	USTR "menu",	menudisp,	menufllw,	menuabort,	umrtn,	umkey,	menuresz,	menumove,	NULL,	NULL,	TYPEMENU};void ldmenu(MENU *m, unsigned char **s, int cursor){	m->list = s;	m->cursor = cursor;	mconfig(m);}int menu_above;MENU *mkmenu(W *w, W *targ, unsigned char **s, int (*func) (/* ??? */), int (*abrt) (/* ??? */), int (*backs) (/* ??? */), int cursor, void *object, int *notify){	W *new;	MENU *m;	int lines;	int h = (w->main->h*40) / 100; /* 40% of window size */	if (!h)		h = 1;		if (s) {		lines = mlines(s,w->t->w-1);		if (lines < h)			h = lines;	}	new = wcreate(w->t, &watommenu, w, targ, targ->main, h, NULL, notify);	if (!new) {		if (notify)			*notify = 1;		return NULL;	}	wfit(new->t);	new->object = (void *) (m = (MENU *) joe_malloc(sizeof(MENU)));	m->parent = new;	m->func = func;	m->abrt = abrt;	m->backs = backs;	m->object = object;	m->t = w->t;	m->h = new->h;	m->w = new->w;	m->x = new->x;	m->y = new->y;	m->top = 0;	ldmenu(m, s, cursor);	w->t->curwin = new;	return m;}static unsigned char *cull(unsigned char *a, unsigned char *b){	int x;	for (x = 0; a[x] && b[x] && a[x] == b[x]; ++x) ;	return vstrunc(a, x);}unsigned char *find_longest(unsigned char **lst){	unsigned char *com;	int x;	if (!lst || !aLEN(lst))		return vstrunc(NULL, 0);	com = vsncpy(NULL, 0, sv(lst[0]));	for (x = 1; x != aLEN(lst); ++x)		com = cull(com, lst[x]);	return com;}unsigned char *mcomplete(MENU *m){	unsigned char *com;	int x;	if (!m->nitems)		return vstrunc(NULL, 0);	com = vsncpy(NULL, 0, sz(m->list[0]));	for (x = 1; x != m->nitems; ++x)		com = cull(com, m->list[x]);	return com;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -