📄 rxvtlib_menubar.c
字号:
"`%c' path = <%s>, name = <%s>, name2 = <%s>, action = <%s>\n", cmd, (path ? path : "(nil)"), (name ? name : "(nil)"), (name2 ? name2 : "(nil)"), (str ? str : "(nil)") );#endif } /* process the different commands */ switch (cmd) { case '+': /* add/replace existing menu or menuitem */ if (path[0] != '\0') { int len; path = rxvtlib_menu_find_base (o, &o->BuildMenu, path); len = strlen (path); /* don't allow menus called `*' */ if (path[0] == '*') { rxvtlib_menu_clear (o, o->BuildMenu); break; } else if (len >= 2 && !strcmp ((path + len - 2), "/*")) { path[len - 2] = '\0'; } if (path[0] != '\0') o->BuildMenu = rxvtlib_menu_add (o, o->BuildMenu, path); } if (name != NULL && name[0] != '\0') rxvtlib_menuitem_add (o, o->BuildMenu, (strcmp (name, SEPARATOR_NAME) ? name : ""), name2, str); break; case '-': /* delete menu entry */ if (!strcmp (path, "/*") && (name == NULL || name[0] == '\0')) { rxvtlib_menubar_clear (o); o->BuildMenu = NULL; rxvtlib_menubar_expose (o); break; } else if (path[0] != '\0') { int len; menu_t *menu = o->BuildMenu; path = rxvtlib_menu_find_base (o, &menu, path); len = strlen (path); /* submenu called `*' clears all menu items */ if (path[0] == '*') { rxvtlib_menu_clear (o, menu); break; /* done */ } else if (len >= 2 && !strcmp (&path[len - 2], "/*")) { /* done */ break; } else if (path[0] != '\0') { o->BuildMenu = NULL; break; } else { o->BuildMenu = menu; } } if (o->BuildMenu != NULL) { if (name == NULL || name[0] == '\0') { o->BuildMenu = rxvtlib_menu_delete (o, o->BuildMenu); } else { menuitem_t *item; item = menuitem_find (o->BuildMenu, strcmp (name, SEPARATOR_NAME) ? name : ""); if (item != NULL && item->entry.type != MenuSubMenu) { rxvtlib_menuitem_free (o, o->BuildMenu, item); /* fix up the width */ o->BuildMenu->width = 0; for (item = o->BuildMenu->head; item != NULL; item = item->next) { if (o->BuildMenu->width < (item->len + item->len2)) o->BuildMenu->width = (item->len + item->len2); } } } rxvtlib_menubar_expose (o); } break; } break; }#endif}#ifdef MENUBAR/* INTPROTO */void rxvtlib_draw_Arrows (rxvtlib *o, int name, int state){ GC top, bot; int i;#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 */ } if (!o->Arrows_x) return; for (i = 0; i < NARROWS; i++) { const int w = Width2Pixel (1); const int y = (menuBar_TotalHeight () - w) / 2; int x = o->Arrows_x + (5 * Width2Pixel (i)) / 4; if (!name || name == o->Arrows[i].name) rxvtlib_Draw_Triangle (o, o->menuBar.win, top, bot, x, y, w, o->Arrows[i].name); } XFlush (o->Xdisplay);}#endif/* EXTPROTO */void rxvtlib_menubar_expose (rxvtlib *o){#ifdef MENUBAR menu_t *menu; int x; if (!menubar_visible () || o->menuBar.win == 0) return; if (o->menubarGC == None) { /* Create the graphics context */ XGCValues gcvalue; gcvalue.font = o->TermWin.font->fid; gcvalue.foreground = (o->Xdepth <= 2 ? o->PixColors[Color_fg] : o->PixColors[Color_Black]); o->menubarGC = XCreateGC (o->Xdisplay, o->menuBar.win, GCForeground | GCFont, &gcvalue); gcvalue.foreground = o->PixColors[Color_scroll]; o->neutralGC = XCreateGC (o->Xdisplay, o->menuBar.win, GCForeground, &gcvalue); gcvalue.foreground = o->PixColors[Color_bottomShadow]; o->botShadowGC = XCreateGC (o->Xdisplay, o->menuBar.win, GCForeground | GCFont, &gcvalue); gcvalue.foreground = o->PixColors[Color_topShadow]; o->topShadowGC = XCreateGC (o->Xdisplay, o->menuBar.win, GCForeground, &gcvalue); }/* make sure the font is correct */ XSetFont (o->Xdisplay, o->menubarGC, o->TermWin.font->fid); XSetFont (o->Xdisplay, o->botShadowGC, o->TermWin.font->fid); XClearWindow (o->Xdisplay, o->menuBar.win); rxvtlib_menu_hide_all (o); x = 0; if (o->CurrentBar != NULL) { for (menu = o->CurrentBar->head; menu != NULL; menu = menu->next) { int len = menu->len; x = (menu->x + menu->len + HSPACE);#ifdef DEBUG_MENU_LAYOUT rxvtlib_print_menu_descendants (o, menu);#endif if (x >= o->TermWin.ncol) len = (o->TermWin.ncol - (menu->x + HSPACE)); rxvtlib_drawbox_menubar (o, menu->x, len, +1); XDrawString (o->Xdisplay, o->menuBar.win, o->menubarGC, (Width2Pixel (menu->x) + Width2Pixel (HSPACE) / 2), menuBar_height () - SHADOW, menu->name, len); if (x >= o->TermWin.ncol) break; } } rxvtlib_drawbox_menubar (o, x, o->TermWin.ncol, (o->CurrentBar ? +1 : -1));/* add the menuBar title, if it exists and there's plenty of room */ o->Arrows_x = 0; if (x < o->TermWin.ncol) { const char *str; int len, ncol = o->TermWin.ncol; char title[256]; if (x < (ncol - (NARROWS + 1))) { ncol -= (NARROWS + 1); o->Arrows_x = Width2Pixel (ncol); } rxvtlib_draw_Arrows (o, 0, +1); str = (o->CurrentBar && o->CurrentBar->title) ? o->CurrentBar->title : "%n-%v"; for (len = 0; str[0] && len < sizeof (title) - 1; str++) { const char *s = NULL; switch (str[0]) { case '%': str++; switch (str[0]) { case 'n': s = o->rs[Rs_name]; break; /* resource name */ case 'v': s = VERSION; break; /* version number */ case '%': s = "%"; break; /* literal '%' */ } if (s != NULL) while (*s && len < sizeof (title) - 1) title[len++] = *s++; break; default: title[len++] = str[0]; break; } } title[len] = '\0'; ncol -= (x + len + HSPACE); if (len > 0 && ncol >= 0) XDrawString (o->Xdisplay, o->menuBar.win, o->menubarGC, Width2Pixel (x) + Width2Pixel (ncol + HSPACE) / 2, menuBar_height () - SHADOW, title, len); }#endif}/* EXTPROTO */int rxvtlib_menubar_mapping (rxvtlib *o, int map){#ifdef MENUBAR int change = 0; if (map && !menubar_visible ()) { o->menuBar.state = 1; if (o->menuBar.win == 0) return 0; XMapWindow (o->Xdisplay, o->menuBar.win); change = 1; } else if (!map && menubar_visible ()) { rxvtlib_menubar_expose (o); o->menuBar.state = 0; XUnmapWindow (o->Xdisplay, o->menuBar.win); change = 1; } else rxvtlib_menubar_expose (o); return change;#else return 0;#endif}#ifdef MENUBAR/* INTPROTO */int rxvtlib_menu_select (rxvtlib *o, XButtonEvent * ev){ menuitem_t *thisitem, *item = NULL; int this_y, y; Window unused_root, unused_child; int unused_root_x, unused_root_y; unsigned int unused_mask; if (o->ActiveMenu == NULL) return 0; XQueryPointer (o->Xdisplay, o->ActiveMenu->win, &unused_root, &unused_child, &unused_root_x, &unused_root_y, &(ev->x), &(ev->y), &unused_mask); if (o->ActiveMenu->parent != NULL && (ev->x < 0 || ev->y < 0)) { rxvtlib_menu_hide (o); return 1; }/* determine the menu item corresponding to the Y index */ y = SHADOW; if (ev->x >= 0 && ev->x <= (o->ActiveMenu->w - SHADOW)) { for (item = o->ActiveMenu->head; item != NULL; item = item->next) { int h = HEIGHT_TEXT + 2 * SHADOW; if (isSeparator (item->name)) h = HEIGHT_SEPARATOR; else if (ev->y >= y && ev->y < (y + h)) break; y += h; } } if (item == NULL && ev->type == ButtonRelease) { rxvtlib_menu_hide_all (o); return 0; } thisitem = item; this_y = y - SHADOW;/* erase the last item */ if (o->ActiveMenu->item != NULL) { if (o->ActiveMenu->item != thisitem) { for (y = 0, item = o->ActiveMenu->head; item != NULL; item = item->next) { int h; if (isSeparator (item->name)) h = HEIGHT_SEPARATOR; else if (item == o->ActiveMenu->item) { /* erase old menuitem */ rxvtlib_drawbox_menuitem (o, y, 0); /* No Shadow */ if (item->entry.type == MenuSubMenu) rxvtlib_drawtriangle (o, o->ActiveMenu->w, y, +1); break; } else h = HEIGHT_TEXT + 2 * SHADOW; y += h; } } else { switch (ev->type) { case ButtonRelease: switch (item->entry.type) { case MenuLabel: case MenuSubMenu: rxvtlib_menu_hide_all (o); break; case MenuAction: case MenuTerminalAction: rxvtlib_drawbox_menuitem (o, this_y, -1); /* * use select for timing * remove menu before sending keys to the application */ { struct timeval tv; tv.tv_sec = 0; tv.tv_usec = MENU_DELAY_USEC; select (0, NULL, NULL, NULL, &tv); } rxvtlib_menu_hide_all (o);#ifndef DEBUG_MENU rxvtlib_action_dispatch (o, &(item->entry.action));#else /* DEBUG_MENU */ fprintf (stderr, "%s: %s\n", item->name, item->entry.action.str);#endif /* DEBUG_MENU */ break; } break; default: if (item->entry.type == MenuSubMenu) goto DoMenu; break; } return 0; } } DoMenu: o->ActiveMenu->item = thisitem; y = this_y; if (thisitem != NULL) { item = o->ActiveMenu->item; if (item->entry.type != MenuLabel) rxvtlib_drawbox_menuitem (o, y, +1); if (item->entry.type == MenuSubMenu) { int x; rxvtlib_drawtriangle (o, o->ActiveMenu->w, y, -1); x = ev->x + (o->ActiveMenu->parent ? o->ActiveMenu->x : Width2Pixel (o->ActiveMenu->x)); if (x >= item->entry.submenu.menu->x) { o->ActiveMenu = item->entry.submenu.menu; rxvtlib_menu_show (o); return 1; } } } return 0;}#endif#ifdef MENUBAR/* INTPROTO */void rxvtlib_menubar_select (rxvtlib *o, XButtonEvent * ev){ menu_t *menu = NULL;/* determine the pulldown menu corresponding to the X index */ if (ev->y >= 0 && ev->y <= menuBar_height () && o->CurrentBar != NULL) { for (menu = o->CurrentBar->head; menu != NULL; menu = menu->next) { int x = Width2Pixel (menu->x); int w = Width2Pixel (menu->len + HSPACE); if ((ev->x >= x && ev->x < x + w)) break; } } switch (ev->type) { case ButtonRelease: rxvtlib_menu_hide_all (o); break; case ButtonPress: if (menu == NULL && o->Arrows_x && ev->x >= o->Arrows_x) { int i; for (i = 0; i < NARROWS; i++) { if (ev->x >= (o->Arrows_x + (Width2Pixel (4 * i + i)) / 4) && ev->x < (o->Arrows_x + (Width2Pixel (4 * i + i + 4)) / 4)) { rxvtlib_draw_Arrows (o, o->Arrows[i].name, -1); /* * use select for timing */ { struct timeval tv; tv.tv_sec = 0; tv.tv_usec = MENU_DELAY_USEC; select (0, NULL, NULL, NULL, &tv); } rxvtlib_draw_Arrows (o, o->Arrows[i].name, +1);#ifdef DEBUG_MENUARROWS fprintf (stderr, "'%c': ", o->Arrows[i].name); if (o->CurrentBar == NULL || (o->CurrentBar->arrows[i].type != MenuAction && o->CurrentBar->arrows[i].type != MenuTerminalAction)) { if (o->Arrows[i].str != NULL && o->Arrows[i].str[0]) fprintf (stderr, "(default) \\033%s\n", &(o->Arrows[i].str[2])); } else { fprintf (stderr, "%s\n", o->CurrentBar->arrows[i].str); }#else /* DEBUG_MENUARROWS */ if (o->CurrentBar == NULL || rxvtlib_action_dispatch (o, &(o->CurrentBar->arrows[i]))) { if (o->Arrows[i].str != NULL && o->Arrows[i].str[0] != 0) rxvtlib_tt_write (o, o->Arrows[i].str + 1, o->Arrows[i].str[0]); }#endif /* DEBUG_MENUARROWS */ return; } } } /* FALLTHROUGH */ default: /* * press menubar or move to a new entry */ if (menu != NULL && menu != o->ActiveMenu) { rxvtlib_menu_hide_all (o); /* pop down old menu */ o->ActiveMenu = menu; rxvtlib_menu_show (o); /* pop up new menu */ } break; }}#endif/* * general dispatch routine, * it would be nice to have `sticky' menus *//* EXTPROTO */void rxvtlib_menubar_control (rxvtlib *o, XButtonEvent * ev){#ifdef MENUBAR switch (ev->type) { case ButtonPress: if (ev->button == Button1) rxvtlib_menubar_select (o, ev); break; case ButtonRelease: if (ev->button == Button1) rxvtlib_menu_select (o, ev); break; case MotionNotify: while (XCheckTypedWindowEvent (o->Xdisplay, o->TermWin.parent[0], MotionNotify, (XEvent *) ev)) ; if (o->ActiveMenu) while (rxvtlib_menu_select (o, ev)) ; else ev->y = -1; if (ev->y < 0) { Window unused_root, unused_child; int unused_root_x, unused_root_y; unsigned int unused_mask; XQueryPointer (o->Xdisplay, o->menuBar.win, &unused_root, &unused_child, &unused_root_x, &unused_root_y, &(ev->x), &(ev->y), &unused_mask); rxvtlib_menubar_select (o, ev); } break; }#endif}/* EXTPROTO */void rxvtlib_map_menuBar (rxvtlib *o, int map){#ifdef MENUBAR if (rxvtlib_menubar_mapping (o, map)) rxvtlib_resize_all_windows (o);#endif}/* EXTPROTO */void rxvtlib_create_menuBar (rxvtlib *o, Cursor cursor){#ifdef MENUBAR/* menuBar: size doesn't matter */ o->menuBar.win = XCreateSimpleWindow (o->Xdisplay, o->TermWin.parent[0], 0, 0, 1, 1, 0, o->PixColors[Color_fg], o->PixColors[Color_scroll]); XDefineCursor (o->Xdisplay, o->menuBar.win, cursor); XSelectInput (o->Xdisplay, o->menuBar.win, (ExposureMask | ButtonPressMask | ButtonReleaseMask | Button1MotionMask));#endif}/* EXTPROTO */void rxvtlib_Resize_menuBar (rxvtlib *o, int x, int y, unsigned int width, unsigned int height){#ifdef MENUBAR XMoveResizeWindow (o->Xdisplay, o->menuBar.win, x, y, width, height);#endif}/*----------------------- end-of-file (C source) -----------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -