From: <enl...@li...> - 2002-12-05 01:32:53
|
Enlightenment CVS committal Author : gilbertt Project : misc Module : feh Dir : misc/feh/src Modified Files: events.c keyevents.c menu.c menu.h options.c winwidget.c Log Message: Thu Dec 05 01:28:44 GMT 2002 Tom Gilbert <to...@li...> * Keyboard control for menus :) * Press 'm' to open the menu, escape to close it, arrow keys (or hjkl) to navigate and space or enter to activate. =================================================================== RCS file: /cvsroot/enlightenment/misc/feh/src/events.c,v retrieving revision 1.64 retrieving revision 1.65 diff -u -3 -r1.64 -r1.65 --- events.c 4 Dec 2002 23:13:58 -0000 1.64 +++ events.c 5 Dec 2002 01:32:51 -0000 1.65 @@ -98,43 +98,8 @@ if (!opt.no_menus && EV_IS_MENU_BUTTON(ev)) { D(3, ("Menu Button Press event\n")); winwid = winwidget_get_from_window(ev->xbutton.window); - if (winwid != NULL) - { - int x, y, b; - unsigned int c; - Window r; - - XQueryPointer(disp, winwid->win, &r, &r, &x, &y, &b, &b, &c); - if (winwid->type == WIN_TYPE_ABOUT) - { - if (!menu_about_win) - feh_menu_init_about_win(); - feh_menu_show_at_xy(menu_about_win, winwid, x, y); - } - else if (winwid->type == WIN_TYPE_SINGLE) - { - if (!menu_single_win) - feh_menu_init_single_win(); - feh_menu_show_at_xy(menu_single_win, winwid, x, y); - } - else if (winwid->type == WIN_TYPE_THUMBNAIL) - { - if (!menu_thumbnail_win) - feh_menu_init_thumbnail_win(); - feh_menu_show_at_xy(menu_thumbnail_win, winwid, x, y); - } - else if (winwid->type == WIN_TYPE_THUMBNAIL_VIEWER) - { - if (!menu_single_win) - feh_menu_init_thumbnail_viewer(); - feh_menu_show_at_xy(menu_thumbnail_viewer, winwid, x, y); - } - else - { - if (!menu_main) - feh_menu_init_main(); - feh_menu_show_at_xy(menu_main, winwid, x, y); - } + if (winwid != NULL) { + winwidget_show_menu(winwid); } } else if ((ev->xbutton.button == opt.rotate_button) @@ -273,16 +238,7 @@ feh_menu_item *i = NULL; i = feh_menu_find_selected(m); - /* watch out for this. I put it this way around so the menu - goes away *before* we perform the action, if we start - freeing menus on hiding, it will break ;-) */ - if ((i) && (i->func)) { - feh_menu_hide(menu_root, False); - feh_main_iteration(0); - (i->func) (m, i, i->data); - if(m->func_free) - m->func_free(m, m->data); - } + feh_menu_item_activate(m, i); } } D_RETURN_(4); =================================================================== RCS file: /cvsroot/enlightenment/misc/feh/src/keyevents.c,v retrieving revision 1.43 retrieving revision 1.44 diff -u -3 -r1.43 -r1.44 --- keyevents.c 24 Nov 2002 23:20:38 -0000 1.43 +++ keyevents.c 5 Dec 2002 01:32:51 -0000 1.44 @@ -38,16 +38,71 @@ XKeyEvent *kev; winwidget winwid = NULL; int curr_screen = 0; + feh_menu_item *selected_item; + feh_menu *selected_menu; D_ENTER(4); - winwid = winwidget_get_from_window(win); - if (winwid == NULL) - D_RETURN_(4); - kev = (XKeyEvent *) ev; len = XLookupString(&ev->xkey, (char *) kbuf, sizeof(kbuf), &keysym, NULL); + /* menus are showing, so this is a menu control keypress */ + if (ev->xbutton.window == menu_cover) { + selected_item = feh_menu_find_selected_r(menu_root, &selected_menu); + switch (keysym) { + case XK_Escape: + feh_menu_hide(menu_root, True); + break; + case XK_Left: + feh_menu_select_parent(selected_menu, selected_item); + break; + case XK_Down: + feh_menu_select_next(selected_menu, selected_item); + break; + case XK_Up: + feh_menu_select_prev(selected_menu, selected_item); + break; + case XK_Right: + feh_menu_select_submenu(selected_menu, selected_item); + break; + case XK_Return: + feh_menu_item_activate(selected_menu, selected_item); + break; + default: + break; + } + if (len <= 0 || len > (int) sizeof(kbuf)) + D_RETURN_(4); + kbuf[len] = '\0'; + + switch (*kbuf) + { + case 'h': + feh_menu_select_parent(selected_menu, selected_item); + break; + case 'j': + feh_menu_select_next(selected_menu, selected_item); + break; + case 'k': + feh_menu_select_prev(selected_menu, selected_item); + break; + case 'l': + feh_menu_select_submenu(selected_menu, selected_item); + break; + case ' ': + feh_menu_item_activate(selected_menu, selected_item); + break; + default: + break; + } + + D_RETURN_(4); + } + + winwid = winwidget_get_from_window(win); + if (winwid == NULL) + D_RETURN_(4); + switch (keysym) { case XK_Left: @@ -62,6 +117,9 @@ if (opt.slideshow) slideshow_change_image(winwid, SLIDE_JUMP_BACK); break; + case XK_Escape: + winwidget_destroy_all(); + break; case XK_Page_Down: if (opt.slideshow) slideshow_change_image(winwid, SLIDE_JUMP_FWD); @@ -151,7 +209,6 @@ if (len <= 0 || len > (int) sizeof(kbuf)) D_RETURN_(4); - kbuf[len] = '\0'; switch (*kbuf) @@ -176,9 +233,9 @@ case 'R': feh_reload_image(winwid, 0); break; - case 'h': - case 'H': - slideshow_pause_toggle(winwid); + case 'h': + case 'H': + slideshow_pause_toggle(winwid); break; case 's': case 'S': @@ -191,6 +248,10 @@ case 'w': case 'W': winwidget_size_to_image(winwid); + break; + case 'm': + case 'M': + winwidget_show_menu(winwid); break; case 'x': case 'X': =================================================================== RCS file: /cvsroot/enlightenment/misc/feh/src/menu.c,v retrieving revision 1.56 retrieving revision 1.57 diff -u -3 -r1.56 -r1.57 --- menu.c 4 Dec 2002 22:17:07 -0000 1.56 +++ menu.c 5 Dec 2002 01:32:51 -0000 1.57 @@ -193,6 +193,7 @@ m->visible = 0; m->items = NULL; m->next = NULL; + m->prev = NULL; m->updates = NULL; m->needs_redraw = 1; m->func_free = NULL; @@ -285,6 +286,122 @@ } feh_menu_item * +feh_menu_find_selected_r(feh_menu * m, feh_menu **parent) +{ + feh_menu_item *i, *ii; + feh_menu *mm; + + D_ENTER(4); + + D(5, ("menu %p\n", m)); + + for (i = m->items; i; i = i->next) { + if (MENU_ITEM_IS_SELECTED(i)) { + if (parent) + *parent = m; + D_RETURN(4, i); + } else if (i->submenu) { + mm = feh_menu_find(i->submenu); + if (mm) + ii = feh_menu_find_selected_r(mm, parent); + if (ii) { + D_RETURN(4, ii); + } + } + } + if (parent) + *parent = m; + D_RETURN(4, NULL); +} + +void +feh_menu_select_next(feh_menu *selected_menu, feh_menu_item *selected_item) { + feh_menu_item *i; + if (!selected_item) { + /* jump to first item, select it */ + feh_menu_select(selected_menu, selected_menu->items); + } else { + i = selected_item; + while (1) { + i = i->next; + if (!i) + i = selected_menu->items; + if (i->func || i->submenu || i->func_gen_sub || i->text) { + break; + } + } + feh_menu_deselect_selected(selected_menu); + feh_menu_select(selected_menu, i); + } +} + +void +feh_menu_select_prev(feh_menu *selected_menu, feh_menu_item *selected_item) { + feh_menu_item *i, *ii; + if (!selected_item) { + /* jump to last item, select it */ + for (i = selected_menu->items; i->next; i = i->next); + feh_menu_select(selected_menu, i); + } else { + i = selected_item; + while (1) { + i = i->prev; + if (!i) { + i = selected_menu->items; + for (ii = selected_menu->items; ii->next; ii = ii->next); + i = ii; + } + if (i->func || i->submenu || i->func_gen_sub || i->text) { + break; + } + } + feh_menu_deselect_selected(selected_menu); + feh_menu_select(selected_menu, i); + } +} + +void +feh_menu_select_parent(feh_menu *selected_menu, feh_menu_item *selected_item) { + feh_menu *m; + feh_menu_item *i; + /* find the parent menu's item which refers to this menu's name */ + if (selected_menu->prev) { + m = selected_menu->prev; + for (i = m->items; i; i = i->next) { + if(i->submenu && !strcmp(i->submenu, selected_menu->name)) + break; + } + /* shouldn't ever happen */ + if (i == NULL) + i = m->items; + feh_menu_deselect_selected(selected_menu); + feh_menu_select(m, i); + } +} + +void +feh_menu_select_submenu(feh_menu *selected_menu, feh_menu_item *selected_item) { + if (selected_menu->next) { + feh_menu_deselect_selected(selected_menu); + feh_menu_select(selected_menu->next, selected_menu->next->items); + } +} + +void feh_menu_item_activate(feh_menu *m, + feh_menu_item *i) { + /* watch out for this. I put it this way around so the menu + goes away *before* we perform the action, if we start + freeing menus on hiding, it will break ;-) */ + if ((i) && (i->func)) { + feh_menu_hide(menu_root, False); + feh_main_iteration(0); + (i->func) (m, i, i->data); + if(m->func_free) + m->func_free(m, m->data); + } +} + +feh_menu_item * feh_menu_find_at_xy(feh_menu * m, int x, int y) @@ -332,6 +449,7 @@ m->updates = imlib_update_append_rect(m->updates, i->x, i->y, i->w, i->h); m->needs_redraw = 1; if (m->next) { + m->next->prev = NULL; feh_menu_hide(m->next, TRUE); m->next = NULL; } @@ -348,9 +466,7 @@ } void -feh_menu_show_at(feh_menu * m, - int x, - int y) +feh_menu_show_at(feh_menu * m, int x, int y) { D_ENTER(4); @@ -367,8 +483,9 @@ InputOnly, vis, CWOverrideRedirect | CWDontPropagate, &attr); XSelectInput(disp, menu_cover, - ButtonPressMask | ButtonReleaseMask | EnterWindowMask | - LeaveWindowMask | PointerMotionMask | ButtonMotionMask); + KeyPressMask | ButtonPressMask | ButtonReleaseMask | + EnterWindowMask | LeaveWindowMask | PointerMotionMask | + ButtonMotionMask); XRaiseWindow(disp, menu_cover); XMapWindow(disp, menu_cover); @@ -444,6 +561,7 @@ my = parent_m->y + i->y - FEH_MENU_PAD_TOP; m->fehwin = parent_m->fehwin; parent_m->next = m; + m->prev = parent_m; feh_menu_move(m, mx, my); feh_menu_show(m); D_RETURN_(4); @@ -509,6 +627,7 @@ if (!m->visible) D_RETURN_(4); if (m->next) { + m->next->prev = NULL; feh_menu_hide(m->next, func_free); m->next = NULL; } @@ -588,6 +707,7 @@ mi->data = data; mi->func_gen_sub = NULL; mi->next = NULL; + mi->prev = NULL; if (!m->items) m->items = mi; @@ -595,6 +715,7 @@ for (ptr = m->items; ptr; ptr = ptr->next) { if (!ptr->next) { ptr->next = mi; + mi->prev = ptr; break; } } =================================================================== RCS file: /cvsroot/enlightenment/misc/feh/src/menu.h,v retrieving revision 1.17 retrieving revision 1.18 diff -u -3 -r1.17 -r1.18 --- menu.h 4 Dec 2002 22:09:44 -0000 1.17 +++ menu.h 5 Dec 2002 01:32:51 -0000 1.18 @@ -99,6 +99,7 @@ void (*func_free) (void *data); void *data; feh_menu_item *next; + feh_menu_item *prev; unsigned char is_toggle; int text_x, icon_x, sub_x, toggle_x; int x, y, w, h; @@ -116,6 +117,7 @@ int visible; feh_menu_item *items; feh_menu *next; + feh_menu *prev; Imlib_Updates updates; Imlib_Image bg; int needs_redraw; @@ -172,6 +174,13 @@ feh_menu *feh_menu_get_from_window(Window win); void feh_raise_all_menus(void); void feh_menu_free(feh_menu * m); +feh_menu_item *feh_menu_find_selected_r(feh_menu *m, feh_menu **parent); +void feh_menu_select_prev(feh_menu *selected_menu, feh_menu_item *selected_item); +void feh_menu_select_next(feh_menu *selected_menu, feh_menu_item *selected_item); +void feh_menu_item_activate(feh_menu *selected_menu, + feh_menu_item *selected_item); +void feh_menu_select_parent(feh_menu *selected_menu, feh_menu_item *selected_item); +void feh_menu_select_submenu(feh_menu *selected_menu, feh_menu_item *selected_item); extern feh_menu *menu_root; extern feh_menu *menu_single_win; =================================================================== RCS file: /cvsroot/enlightenment/misc/feh/src/options.c,v retrieving revision 1.146 retrieving revision 1.147 diff -u -3 -r1.146 -r1.147 --- options.c 4 Dec 2002 22:09:49 -0000 1.146 +++ options.c 5 Dec 2002 01:32:51 -0000 1.147 @@ -1001,6 +1001,7 @@ " n, N, <SPACE>, <RIGHT> Goto next slide\n" " r, R Reload image (good for webcams)\n" " v, V Toggle fullscreen\n" + " m, M Show popup menu\n" " w, W Size window to current image dimensions\n" " h, H Pause the slideshow (only useful when using\n" " s, S Save current image to unique filename\n" @@ -1009,6 +1010,7 @@ " <, > In place editing, rotate 90 degrees right/left\n" " <HOME> Goto first slide\n" " <END> Goto last slide\n" + " <ESCAPE> Quit the slideshow\n" " +, = Increase reload delay\n" " -, _ Decrease reload delay\n" " <DELETE> Remove the currently viewed file from the filelist\n" =================================================================== RCS file: /cvsroot/enlightenment/misc/feh/src/winwidget.c,v retrieving revision 1.108 retrieving revision 1.109 diff -u -3 -r1.108 -r1.109 --- winwidget.c 21 Oct 2002 02:53:44 -0000 1.108 +++ winwidget.c 5 Dec 2002 01:32:51 -0000 1.109 @@ -944,3 +944,41 @@ winwid->h = rect[3]; D_RETURN_(4); } + +void winwidget_show_menu(winwidget winwid) { + int x, y, b; + unsigned int c; + Window r; + + XQueryPointer(disp, winwid->win, &r, &r, &x, &y, &b, &b, &c); + if (winwid->type == WIN_TYPE_ABOUT) + { + if (!menu_about_win) + feh_menu_init_about_win(); + feh_menu_show_at_xy(menu_about_win, winwid, x, y); + } + else if (winwid->type == WIN_TYPE_SINGLE) + { + if (!menu_single_win) + feh_menu_init_single_win(); + feh_menu_show_at_xy(menu_single_win, winwid, x, y); + } + else if (winwid->type == WIN_TYPE_THUMBNAIL) + { + if (!menu_thumbnail_win) + feh_menu_init_thumbnail_win(); + feh_menu_show_at_xy(menu_thumbnail_win, winwid, x, y); + } + else if (winwid->type == WIN_TYPE_THUMBNAIL_VIEWER) + { + if (!menu_single_win) + feh_menu_init_thumbnail_viewer(); + feh_menu_show_at_xy(menu_thumbnail_viewer, winwid, x, y); + } + else + { + if (!menu_main) + feh_menu_init_main(); + feh_menu_show_at_xy(menu_main, winwid, x, y); + } +} |