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

📄 menubar.c

📁 rxvt经典的linux下的终端.小巧实用
💻 C
📖 第 1 页 / 共 4 页
字号:
		break;	    }	}    }    item = menu->tail;    while (item != NULL) {	menuitem_t     *p = item->prev;	rxvt_menuitem_free(r, menu, item);	item = p;    }    if (menu->name != NULL)	free(menu->name);    free(menu);    return parent;}/* INTPROTO */menu_t         *rxvt_menu_add(rxvt_t *r, menu_t *parent, char *path){    menu_t         *menu;    bar_t          *CurrentBar = r->h->CurrentBar;#ifdef DEBUG_STRICT    assert(CurrentBar != NULL);#endif    if (STRCHR(path, '/') != NULL) {	char           *p;	if (path[0] == '/') {	    /* shouldn't happen */	    path++;	    parent = NULL;	}	while ((p = STRCHR(path, '/')) != NULL) {	    p[0] = '\0';	    if (path[0] == '\0')		return NULL;	    parent = rxvt_menu_add(r, parent, path);	    path = (p + 1);	}    }    if (!STRCMP(path, DOTS))	return (parent != NULL ? parent->parent : parent);    if (!STRCMP(path, DOT) || path[0] == '\0')	return parent;/* allocate a new menu */    menu = (menu_t *) rxvt_malloc(sizeof(menu_t));    menu->width = 0;    menu->parent = parent;    menu->len = STRLEN(path);    menu->name = rxvt_malloc((menu->len + 1));    STRCPY(menu->name, path);/* initialize head/tail */    menu->head = menu->tail = NULL;    menu->prev = menu->next = NULL;    menu->win = None;    menu->x = menu->y = menu->w = menu->h = 0;    menu->item = NULL;/* add to tail of list */    if (parent == NULL) {	menu->prev = CurrentBar->tail;	if (CurrentBar->tail != NULL)	    CurrentBar->tail->next = menu;	CurrentBar->tail = menu;	if (CurrentBar->head == NULL)	    CurrentBar->head = menu;	/* fix head */	if (menu->prev)	    menu->x = (menu->prev->x + menu->prev->len + HSPACE);    } else {	menuitem_t     *item;	item = rxvt_menuitem_add(parent, path, "", "");	if (item == NULL) {	    free(menu);	    return parent;	}#ifdef DEBUG_STRICT	assert(item->entry.type == MenuLabel);#endif	item->entry.type = MenuSubMenu;	item->entry.submenu.menu = menu;    }    return menu;}/* INTPROTO */voidrxvt_drawbox_menubar(rxvt_t *r, int x, int len, int state){    GC              top, bot;    x = Width2Pixel(x);    len = Width2Pixel(len + HSPACE);    if (x >= r->TermWin.width)	return;    else if (x + len >= r->TermWin.width)	len = (TermWin_TotalWidth() - x);#ifdef MENUBAR_SHADOW_IN    state = -state;#endif    switch (state) {    case +1:	top = r->h->topShadowGC;	bot = r->h->botShadowGC;	break;			/* SHADOW_OUT */    case -1:	top = r->h->botShadowGC;	bot = r->h->topShadowGC;	break;			/* SHADOW_IN */    default:	top = bot = r->h->scrollbarGC;	break;			/* neutral */    }    rxvt_Draw_Shadow(r->Xdisplay, r->menuBar.win, top, bot,		     x, 0, len, menuBar_TotalHeight());}/* INTPROTO */voidrxvt_drawtriangle(rxvt_t *r, int x, int y, int state){    GC              top, bot;    int             w;#ifdef MENU_SHADOW_IN    state = -state;#endif    switch (state) {    case +1:	top = r->h->topShadowGC;	bot = r->h->botShadowGC;	break;			/* SHADOW_OUT */    case -1:	top = r->h->botShadowGC;	bot = r->h->topShadowGC;	break;			/* SHADOW_IN */    default:	top = bot = r->h->scrollbarGC;	break;			/* neutral */    }    w = Height2Pixel(1) - 2 * SHADOW;    x -= SHADOW + (3 * w / 2);    y += SHADOW * 3;    rxvt_Draw_Triangle(r->Xdisplay, r->h->ActiveMenu->win, top, bot, x, y, w,		       'r');}/* INTPROTO */voidrxvt_drawbox_menuitem(rxvt_t *r, int y, int state){    GC              top, bot;#ifdef MENU_SHADOW_IN    state = -state;#endif    switch (state) {    case +1:	top = r->h->topShadowGC;	bot = r->h->botShadowGC;	break;			/* SHADOW_OUT */    case -1:	top = r->h->botShadowGC;	bot = r->h->topShadowGC;	break;			/* SHADOW_IN */    default:	top = bot = r->h->scrollbarGC;	break;			/* neutral */    }    rxvt_Draw_Shadow(r->Xdisplay, r->h->ActiveMenu->win, top, bot,		     SHADOW + 0, SHADOW + y,		     r->h->ActiveMenu->w - 2 * (SHADOW),		     HEIGHT_TEXT + 2 * SHADOW);    XFlush(r->Xdisplay);}#ifdef DEBUG_MENU_LAYOUT/* INTPROTO */voidrxvt_print_menu_ancestors(menu_t *menu){    if (menu == NULL) {	fprintf(stderr, "Top Level menu\n");	return;    }    fprintf(stderr, "menu %s ", menu->name);    if (menu->parent != NULL) {	menuitem_t     *item;	for (item = menu->parent->head; item != NULL; item = item->next) {	    if (item->entry.type == MenuSubMenu		&& item->entry.submenu.menu == menu) {		break;	    }	}	if (item == NULL) {	    fprintf(stderr, "is an orphan!\n");	    return;	}    }    fprintf(stderr, "\n");    rxvt_print_menu_ancestors(menu->parent);}/* INTPROTO */voidrxvt_print_menu_descendants(menu_t *menu){    menuitem_t     *item;    menu_t         *parent;    int             i, level = 0;    parent = menu;    do {	level++;	parent = parent->parent;    }    while (parent != NULL);    for (i = 0; i < level; i++)	fprintf(stderr, ">");    fprintf(stderr, "%s\n", menu->name);    for (item = menu->head; item != NULL; item = item->next) {	if (item->entry.type == MenuSubMenu) {	    if (item->entry.submenu.menu == NULL)		fprintf(stderr, "> %s == NULL\n", item->name);	    else		rxvt_print_menu_descendants(item->entry.submenu.menu);	} else {	    for (i = 0; i < level; i++)		fprintf(stderr, "+");	    if (item->entry.type == MenuLabel)		fprintf(stderr, "label: ");	    fprintf(stderr, "%s\n", item->name);	}    }    for (i = 0; i < level; i++)	fprintf(stderr, "<");    fprintf(stderr, "\n");}#endif/* pop up/down the current menu and redraw the menuBar button *//* INTPROTO */voidrxvt_menu_show(rxvt_t *r){    int             x, y, xright;    menu_t         *ActiveMenu = r->h->ActiveMenu;    menuitem_t     *item;    if (ActiveMenu == NULL)	return;    x = ActiveMenu->x;    if (ActiveMenu->parent == NULL) {	register int    h;	rxvt_drawbox_menubar(r, x, ActiveMenu->len, -1);	x = Width2Pixel(x);	ActiveMenu->y = 1;	ActiveMenu->w = Menu_PixelWidth(ActiveMenu);	if ((x + ActiveMenu->w) >= r->TermWin.width)	    x = (TermWin_TotalWidth() - ActiveMenu->w);	/* find the height */	for (h = 0, item = ActiveMenu->head; item != NULL; item = item->next)	    h += isSeparator(item->name) ? HEIGHT_SEPARATOR					 : HEIGHT_TEXT + 2 * SHADOW;	ActiveMenu->h = h + 2 * SHADOW;    }    if (ActiveMenu->win == None) {	ActiveMenu->win = XCreateSimpleWindow(r->Xdisplay, r->TermWin.vt,					      x, ActiveMenu->y,					      ActiveMenu->w, ActiveMenu->h,					      0,					      r->PixColors[Color_fg],					      r->PixColors[Color_scroll]);	XMapWindow(r->Xdisplay, ActiveMenu->win);    }    rxvt_Draw_Shadow(r->Xdisplay, ActiveMenu->win,		     r->h->topShadowGC, r->h->botShadowGC,		     0, 0, ActiveMenu->w, ActiveMenu->h);/* determine the correct right-alignment */    for (xright = 0, item = ActiveMenu->head; item != NULL; item = item->next)	if (item->len2 > xright)	    xright = item->len2;    for (y = 0, item = ActiveMenu->head; item != NULL; item = item->next) {	const int       xoff = (SHADOW + Width2Pixel(HSPACE) / 2);	register int    h;	GC              gc = r->h->menubarGC;	if (isSeparator(item->name)) {	    rxvt_Draw_Shadow(r->Xdisplay, ActiveMenu->win,			     r->h->topShadowGC, r->h->botShadowGC,			     SHADOW, y + SHADOW + 1,			     ActiveMenu->w - 2 * SHADOW, 0);	    h = HEIGHT_SEPARATOR;	} else {	    char           *name = item->name;	    int             len = item->len;	    if (item->entry.type == MenuLabel) {		gc = r->h->botShadowGC;	    } else if (item->entry.type == MenuSubMenu) {		int             x1, y1;		menuitem_t     *it;		menu_t         *menu = item->entry.submenu.menu;		rxvt_drawtriangle(r, ActiveMenu->w, y, +1);		name = menu->name;		len = menu->len;		y1 = ActiveMenu->y + y;		menu->w = Menu_PixelWidth(menu);		/* place sub-menu at midpoint of parent menu */		x1 = ActiveMenu->w / 2;		if (x1 > menu->w)	/* right-flush menu if too small */		    x1 += (x1 - menu->w);		x1 += x;		/* find the height of this submenu */		for (h = 0, it = menu->head; it != NULL; it = it->next)		    h += isSeparator(it->name) ? HEIGHT_SEPARATOR					       : HEIGHT_TEXT + 2 * SHADOW;		menu->h = h + 2 * SHADOW;		/* ensure menu is in window limits */		if ((x1 + menu->w) >= r->TermWin.width)		    x1 = (TermWin_TotalWidth() - menu->w);		if ((y1 + menu->h) >= r->TermWin.height)		    y1 = (TermWin_TotalHeight() - menu->h);		menu->x = (x1 < 0 ? 0 : x1);		menu->y = (y1 < 0 ? 0 : y1);	    } else if (item->name2 && !STRCMP(name, item->name2))		name = NULL;	    if (len && name) {#ifdef USE_XIM		if (r->TermWin.fontset)		    XmbDrawString(r->Xdisplay,				  ActiveMenu->win, r->TermWin.fontset,				  gc, xoff,				  2 * SHADOW + y + r->TermWin.font->ascent + 1,				  name, len);		else#endif		    XDrawString(r->Xdisplay, ActiveMenu->win, gc, xoff,				2 * SHADOW + y + r->TermWin.font->ascent + 1,				name, len);	    }	    len = item->len2;	    name = item->name2;	    if (len && name) {#ifdef USE_XIM		if (r->TermWin.fontset)		    XmbDrawString(r->Xdisplay,				  ActiveMenu->win, r->TermWin.fontset,				  gc,				  ActiveMenu->w - (xoff + Width2Pixel(xright)),				  2 * SHADOW + y + r->TermWin.font->ascent + 1,				  name, len);		else#endif		    XDrawString(r->Xdisplay, ActiveMenu->win, gc,				ActiveMenu->w - (xoff + Width2Pixel(xright)),				2 * SHADOW + y + r->TermWin.font->ascent + 1,				name, len);	    }	    h = HEIGHT_TEXT + 2 * SHADOW;	}	y += h;    }}/* INTPROTO */voidrxvt_menu_display(rxvt_t *r, void (*update)(rxvt_t *)){    menu_t         *ActiveMenu = r->h->ActiveMenu;    if (ActiveMenu == NULL)	return;    if (ActiveMenu->win != None)	XDestroyWindow(r->Xdisplay, ActiveMenu->win);    ActiveMenu->win = None;    ActiveMenu->item = NULL;    if (ActiveMenu->parent == NULL)	rxvt_drawbox_menubar(r, ActiveMenu->x, ActiveMenu->len, +1);    r->h->ActiveMenu = ActiveMenu->parent;    update(r);}/* INTPROTO */voidrxvt_menu_hide_all(rxvt_t *r){    rxvt_menu_display(r, rxvt_menu_hide_all);}/* INTPROTO */voidrxvt_menu_hide(rxvt_t *r){    rxvt_menu_display(r, rxvt_menu_show);}/* INTPROTO */voidrxvt_menu_clear(rxvt_t *r, menu_t *menu){    if (menu != NULL) {	menuitem_t     *item = menu->tail;	while (item != NULL) {	    rxvt_menuitem_free(r, menu, item);	    /* it didn't get freed ... why? */	    if (item == menu->tail)		return;	    item = menu->tail;	}	menu->width = 0;    }}/* INTPROTO */voidrxvt_menubar_clear(rxvt_t *r){    bar_t          *CurrentBar = r->h->CurrentBar;    if (CurrentBar != NULL) {	menu_t         *menu = CurrentBar->tail;	while (menu != NULL) {	    menu_t         *prev = menu->prev;	    rxvt_menu_delete(r, menu);	    menu = prev;	}	CurrentBar->head = CurrentBar->tail = NULL;	if (CurrentBar->title) {	    free(CurrentBar->title);	    CurrentBar->title = NULL;	}	rxvt_menuarrow_free(r, 0);	/* remove all arrow functions */    }    r->h->ActiveMenu = NULL;}#if (MENUBAR_MAX > 1)/* find if menu already exists *//* INTPROTO */bar_t          *rxvt_menubar_find(rxvt_t *r, const char *name){    bar_t          *bar = r->h->CurrentBar;#ifdef DEBUG_MENUBAR_STACKING    fprintf(stderr, "looking for [menu:%s] ...", name ? name : "(nil)");#endif    if (bar == NULL || name == NULL)	return NULL;    if (STRLEN(name) && STRCMP(name, "*")) {	do {	    if (!STRCMP(bar->name, name)) {#ifdef DEBUG_MENUBAR_STACKING		fprintf(stderr, " found!\n");#endif		return bar;	    }	    bar = bar->next;	}	while (bar != r->h->CurrentBar);	bar = NULL;    }#ifdef DEBUG_MENUBAR_STACKING    fprintf(stderr, "%s found!\n", (bar ? "" : " NOT"));#endif    return bar;}/* INTPROTO */intrxvt_menubar_push(rxvt_t *r, const char *name){    int             ret = 1;    bar_t          *bar;    if (r->h->CurrentBar == NULL) {	/* allocate first one */	bar = (bar_t *) rxvt_malloc(sizeof(bar_t));	MEMSET(bar, 0, sizeof(bar_t));	/* circular linked-list */	bar->next = bar->prev = bar;	bar->head = bar->tail = NULL;	bar->title = NULL;	r->h->CurrentBar = bar;	r->h->Nbars++;	rxvt_menubar_clear(r);    } else {	/* find if menu already exists */	bar = rxvt_menubar_find(r, name);	if (bar != NULL) {	    /* found it, use it */	    r->h->CurrentBar = bar;	} else {	    /* create if needed, or reuse the existing empty menubar */	    if (r->h->CurrentBar->head != NULL) {		/* need to malloc another one */		if (r->h->Nbars < MENUBAR_MAX)		    bar = (bar_t *) rxvt_malloc(sizeof(bar_t));		else		    bar = NULL;		/* malloc failed or too many menubars, reuse another */		if (bar == NULL) {		    bar = r->h->CurrentBar->next;		    ret = -1;		} else {		    bar->head = bar->tail = NULL;		    bar->title = NULL;		    bar->next = r->h->CurrentBar->next;		    r->h->CurrentBar->next = bar;		    bar->prev = r->h->CurrentBar;

⌨️ 快捷键说明

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