void menu_motion(WThing *thing, XMotionEvent *ev, int dx, int dy, WFunction *func, WFuncArg arg) { WMenu *menu; int ret; if(!WTHING_IS(thing, WTHING_MENU)) return; menu=(WMenu*)thing; if(!menu_select_at(menu, ev->x_root, ev->y_root)){ thing=find_thing(ev->subwindow); if(thing==(WThing*)menu || thing==NULL || !WTHING_IS(thing, WTHING_MENU)){ end_scroll(); return; } wglobal.grab_holder=thing; menu=(WMenu*)thing; if(!menu_select_at(menu, ev->x_root, ev->y_root)){ end_scroll(); return; } } if(test_scroll(menu, ev->x_root, ev->y_root)) start_scroll(menu); }
static void check_scroll(WMenu *menu, int x, int y) { WRegion *parent=REGION_PARENT_REG(menu); int rx, ry; WTimerHandler *fn=NULL; if(!menu->pmenu_mode) return; if(parent==NULL){ end_scroll(menu); return; } region_rootpos(parent, &rx, &ry); x-=rx; y-=ry; if(x<=SCROLL_OFFSET){ fn=(WTimerHandler*)scroll_right; }else if(y<=SCROLL_OFFSET){ fn=(WTimerHandler*)scroll_down; }else if(x>=REGION_GEOM(parent).w-SCROLL_OFFSET){ fn=(WTimerHandler*)scroll_left; }else if(y>=REGION_GEOM(parent).h-SCROLL_OFFSET){ fn=(WTimerHandler*)scroll_up; }else{ end_scroll(menu); return; } assert(fn!=NULL); if(scroll_timer!=NULL){ if(scroll_timer->handler==(WTimerHandler*)fn && timer_is_set(scroll_timer)){ return; } }else{ scroll_timer=create_timer(); if(scroll_timer==NULL) return; } fn(scroll_timer, (Obj*)menu_head(menu)); }
void menu_release(WMenu *menu, XButtonEvent *ev) { int entry=menu_entry_at_root_tree(menu, ev->x_root, ev->y_root, &menu); end_scroll(menu); if(entry>=0){ menu_select_nth(menu, entry); menu_finish(menu); }else if(menu->pmenu_mode){ menu_cancel(menu_head(menu)); } }
static void scrollfunc() { WMenu *menu=scrollmenu; int dx=scrollhoriz*SCROLL_AMOUNT; int dy=scrollvert*SCROLL_AMOUNT; Window win; if(menu->x+dx>0 && scrollhoriz==1) dx=-menu->x; else if(menu->x+menu->w+dx<SCREEN->width-SCROLL_BORDER && scrollhoriz==-1) dx=-(menu->x+menu->w-SCREEN->width+SCROLL_BORDER); if(menu->y+dy>0 && scrollvert==1) dy=-menu->y; else if(menu->y+menu->h+dy<SCREEN->height-SCROLL_BORDER && scrollvert==-1) dy=-(menu->y+menu->h-SCREEN->height+SCROLL_BORDER); move_menu(scrolltop, dx, dy); /* pointer root -> dx, dy */ get_pointer_rootpos(&dx, &dy); if(menu_select_at(menu, dx, dy)){ if(test_scroll(menu, dx, dy)) return; }else if(test_scroll(menu, dx, dy)){ return; }else{ if(!find_window_at(dx, dy, &win)) goto end; menu=(WMenu*)find_thing_t(win, WTHING_MENU); if(menu==NULL) goto end; if(test_scroll(menu, dx, dy)) start_scroll(menu); } end: end_scroll(); }
void menu_button(WThing *thing, XButtonEvent *ev, WFunction *func, WFuncArg arg) { WMenu *menu; int x, y, entry; if(!WTHING_IS(thing, WTHING_MENU)) return; menu=(WMenu*)thing; x=ev->x_root-menu->x; y=ev->y_root-menu->y; entry=entry_at(menu, x, y); if(ev->type==ButtonPress){ /* press */ if(entry==menu->selected){ menu_set_selected(menu, NO_ENTRY); }else{ menu_set_selected(menu, entry); show_selected_submenu(menu); } return; } end_scroll(); /* release */ if(entry>=0){ if(menu->selected==entry) menu_execute_selected(menu); }else if(entry!=ENTRY_TITLE && !(menu->flags&WMENU_KEEP)){ finish_menu(menu, FALSE); } destroy_contextual_menus(); }