📄 rxvtlib_menubar.c
字号:
} } } item = menu->tail; while (item != NULL) { menuitem_t *p = item->prev; rxvtlib_menuitem_free (o, menu, item); item = p; } if (menu->name != NULL) FREE (menu->name); FREE (menu); return parent;}#endif#ifdef MENUBAR/* INTPROTO */menu_t *rxvtlib_menu_add (rxvtlib *o, menu_t * parent, char *path){ menu_t *menu; assert (o->CurrentBar != NULL); if (strchr (path, '/') != NULL) { register 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 = rxvtlib_menu_add (o, 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 */ if ((menu = (menu_t *) MALLOC (sizeof (menu_t))) == NULL) return parent; menu->width = 0; menu->parent = parent; menu->len = strlen (path); menu->name = MALLOC ((menu->len + 1)); if (menu->name == NULL) { FREE (menu); return parent; } 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 = o->CurrentBar->tail; if (o->CurrentBar->tail != NULL) o->CurrentBar->tail->next = menu; o->CurrentBar->tail = menu; if (o->CurrentBar->head == NULL) o->CurrentBar->head = menu; /* fix head */ if (menu->prev) menu->x = (menu->prev->x + menu->prev->len + HSPACE); } else { menuitem_t *item; item = rxvtlib_menuitem_add (o, parent, path, "", ""); if (item == NULL) { FREE (menu); return parent; } assert (item->entry.type == MenuLabel); item->entry.type = MenuSubMenu; item->entry.submenu.menu = menu; } return menu;}#endif#ifdef MENUBAR/* INTPROTO */void rxvtlib_drawbox_menubar (rxvtlib *o, int x, int len, int state){ GC top, bot; x = Width2Pixel (x); len = Width2Pixel (len + HSPACE); if (x >= o->TermWin.width) return; else if (x + len >= o->TermWin.width) len = (TermWin_TotalWidth () - x);#ifdef MENUBAR_SHADOW_IN state = -state;#endif switch (state) { case +1: top = o->topShadowGC; bot = o->botShadowGC; break; /* SHADOW_OUT */ case -1: top = o->botShadowGC; bot = o->topShadowGC; break; /* SHADOW_IN */ default: top = bot = o->neutralGC; break; /* neutral */ } rxvtlib_Draw_Shadow (o, o->menuBar.win, top, bot, x, 0, len, menuBar_TotalHeight ());}#endif#ifdef MENUBAR/* INTPROTO */void rxvtlib_drawtriangle (rxvtlib *o, int x, int y, int state){ GC top, bot; int w;#ifdef MENU_SHADOW_IN state = -state;#endif switch (state) { case +1: top = o->topShadowGC; bot = o->botShadowGC; break; /* SHADOW_OUT */ case -1: top = o->botShadowGC; bot = o->topShadowGC; break; /* SHADOW_IN */ default: top = bot = o->neutralGC; break; /* neutral */ } w = Height2Pixel (1) - 2 * SHADOW; x -= SHADOW + (3 * w / 2); y += SHADOW * 3; rxvtlib_Draw_Triangle (o, o->ActiveMenu->win, top, bot, x, y, w, 'r');}#endif#ifdef MENUBAR/* INTPROTO */void rxvtlib_drawbox_menuitem (rxvtlib *o, int y, int state){ GC top, bot;#ifdef MENU_SHADOW_IN state = -state;#endif switch (state) { case +1: top = o->topShadowGC; bot = o->botShadowGC; break; /* SHADOW_OUT */ case -1: top = o->botShadowGC; bot = o->topShadowGC; break; /* SHADOW_IN */ default: top = bot = o->neutralGC; break; /* neutral */ } rxvtlib_Draw_Shadow (o, o->ActiveMenu->win, top, bot, SHADOW + 0, SHADOW + y, o->ActiveMenu->w - 2 * (SHADOW), HEIGHT_TEXT + 2 * SHADOW); XFlush (o->Xdisplay);}#endif#ifdef DEBUG_MENU_LAYOUT#ifdef MENUBAR/* INTPROTO */void rxvtlib_print_menu_ancestors (rxvtlib *o, 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"); rxvtlib_print_menu_ancestors (o, menu->parent);}#endif#ifdef MENUBAR/* INTPROTO */void rxvtlib_print_menu_descendants (rxvtlib *o, 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 rxvtlib_print_menu_descendants (o, 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#endif#ifdef MENUBAR/* pop up/down the current menu and redraw the menuBar button *//* INTPROTO */void rxvtlib_menu_show (rxvtlib *o){ int x, y, xright; menuitem_t *item; if (o->ActiveMenu == NULL) return; x = o->ActiveMenu->x; if (o->ActiveMenu->parent == NULL) { register int h; rxvtlib_drawbox_menubar (o, x, o->ActiveMenu->len, -1); x = Width2Pixel (x); o->ActiveMenu->y = 1; o->ActiveMenu->w = Menu_PixelWidth (o->ActiveMenu); if ((x + o->ActiveMenu->w) >= o->TermWin.width) x = (TermWin_TotalWidth () - o->ActiveMenu->w); /* find the height */ for (h = 0, item = o->ActiveMenu->head; item != NULL; item = item->next) h += isSeparator (item->name) ? HEIGHT_SEPARATOR : HEIGHT_TEXT + 2 * SHADOW; o->ActiveMenu->h = h + 2 * SHADOW; } if (o->ActiveMenu->win == None) { o->ActiveMenu->win = XCreateSimpleWindow (o->Xdisplay, o->TermWin.vt, x, o->ActiveMenu->y, o->ActiveMenu->w, o->ActiveMenu->h, 0, o->PixColors[Color_fg], o->PixColors[Color_scroll]); XMapWindow (o->Xdisplay, o->ActiveMenu->win); } rxvtlib_Draw_Shadow (o, o->ActiveMenu->win, o->topShadowGC, o->botShadowGC, 0, 0, o->ActiveMenu->w, o->ActiveMenu->h);/* determine the correct right-alignment */ for (xright = 0, item = o->ActiveMenu->head; item != NULL; item = item->next) if (item->len2 > xright) xright = item->len2; for (y = 0, item = o->ActiveMenu->head; item != NULL; item = item->next) { const int xoff = (SHADOW + Width2Pixel (HSPACE) / 2); register int h; GC gc = o->menubarGC; if (isSeparator (item->name)) { rxvtlib_Draw_Shadow (o, o->ActiveMenu->win, o->topShadowGC, o->botShadowGC, SHADOW, y + SHADOW + 1, o->ActiveMenu->w - 2 * SHADOW, 0); h = HEIGHT_SEPARATOR; } else { char *name = item->name; int len = item->len; if (item->entry.type == MenuLabel) { gc = o->botShadowGC; } else if (item->entry.type == MenuSubMenu) { int x1, y1; menuitem_t *it; menu_t *menu = item->entry.submenu.menu; rxvtlib_drawtriangle (o, o->ActiveMenu->w, y, +1); name = menu->name; len = menu->len; y1 = o->ActiveMenu->y + y; menu->w = Menu_PixelWidth (menu); /* place sub-menu at midpoint of parent menu */ x1 = o->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) >= o->TermWin.width) x1 = (TermWin_TotalWidth () - menu->w); if ((y1 + menu->h) >= o->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) XDrawString (o->Xdisplay, o->ActiveMenu->win, gc, xoff, 2 * SHADOW + y + o->TermWin.font->ascent + 1, name, len); len = item->len2; name = item->name2; if (len && name) XDrawString (o->Xdisplay, o->ActiveMenu->win, gc, o->ActiveMenu->w - (xoff + Width2Pixel (xright)), 2 * SHADOW + y + o->TermWin.font->ascent + 1, name, len); h = HEIGHT_TEXT + 2 * SHADOW; } y += h; }}#endif#ifdef MENUBAR/* INTPROTO */void rxvtlib_menu_display (rxvtlib *o, void (*update) (rxvtlib *)){ if (o->ActiveMenu == NULL) return; if (o->ActiveMenu->win != None) XDestroyWindow (o->Xdisplay, o->ActiveMenu->win); o->ActiveMenu->win = None; o->ActiveMenu->item = NULL; if (o->ActiveMenu->parent == NULL) rxvtlib_drawbox_menubar (o, o->ActiveMenu->x, o->ActiveMenu->len, +1); o->ActiveMenu = o->ActiveMenu->parent; update (o);}#endif#ifdef MENUBAR/* INTPROTO */void rxvtlib_menu_hide_all (rxvtlib *o){ rxvtlib_menu_display (o, rxvtlib_menu_hide_all);}#endif#ifdef MENUBAR/* INTPROTO */void rxvtlib_menu_hide (rxvtlib *o){ rxvtlib_menu_display (o, rxvtlib_menu_show);}#endif#ifdef MENUBAR/* INTPROTO */void rxvtlib_menu_clear (rxvtlib *o, menu_t * menu){ if (menu != NULL) { menuitem_t *item = menu->tail; while (item != NULL) { rxvtlib_menuitem_free (o, menu, item); /* it didn't get freed ... why? */ if (item == menu->tail) return; item = menu->tail; } menu->width = 0; }}#endif#ifdef MENUBAR/* INTPROTO */void rxvtlib_menubar_clear (rxvtlib *o){ if (o->CurrentBar != NULL) { menu_t *menu = o->CurrentBar->tail; while (menu != NULL) { menu_t *prev = menu->prev; rxvtlib_menu_delete (o, menu); menu = prev; } o->CurrentBar->head = o->CurrentBar->tail = o->ActiveMenu = NULL; if (o->CurrentBar->title) { FREE (o->CurrentBar->title); o->CurrentBar->title = NULL; } rxvtlib_menuarrow_free (o, 0); /* remove all arrow functions */ } o->ActiveMenu = NULL;}#endif#if (MENUBAR_MAX > 1)#ifdef MENUBAR/* find if menu already exists *//* INTPROTO */bar_t *rxvtlib_menubar_find (rxvtlib *o, const char *name){ bar_t *bar = o->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 != o->CurrentBar); bar = NULL; }#ifdef DEBUG_MENUBAR_STACKING fprintf (stderr, "%s found!\n", (bar ? "" : " NOT"));#endif return bar;}#endif#ifdef MENUBAR/* INTPROTO */int rxvtlib_menubar_push (rxvtlib *o, const char *name){ int ret = 1; bar_t *bar; if (o->CurrentBar == NULL) { /* allocate first one */ bar = (bar_t *) MALLOC (sizeof (bar_t)); if (bar == NULL) return 0; MEMSET (bar, 0, sizeof (bar_t)); /* circular linked-list */ bar->next = bar->prev = bar; bar->head = bar->tail = NULL; bar->title = NULL; o->CurrentBar = bar; o->Nbars++; rxvtlib_menubar_clear (o); } else { /* find if menu already exists */ bar = rxvtlib_menubar_find (o, name); if (bar != NULL) { /* found it, use it */ o->CurrentBar = bar; } else { /* create if needed, or reuse the existing empty menubar */ if (o->CurrentBar->head != NULL) { /* need to malloc another one */ if (o->Nbars < MENUBAR_MAX) bar = (bar_t *) MALLOC (sizeof (bar_t)); else bar = NULL; /* malloc failed or too many menubars, reuse another */ if (bar == NULL) { bar = o->CurrentBar->next; ret = -1; } else { bar->head = bar->tail = NULL; bar->title = NULL; bar->next = o->CurrentBar->next; o->CurrentBar->next = bar; bar->prev = o->CurrentBar; bar->next->prev = bar; o->Nbars++; } o->CurrentBar = bar; } rxvtlib_menubar_clear (o); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -