diff --git a/command.c b/command.c index 9710ca87f3..d6da090f45 100644 --- a/command.c +++ b/command.c @@ -51,6 +51,10 @@ #include "libass/ass.h" #include "libass/ass_mp.h" #endif +#ifdef HAVE_MENU +#include "m_struct.h" +#include "libmenu/menu.h" +#endif #ifdef HAVE_NEW_GUI #include "gui/interface.h" #endif @@ -60,6 +64,8 @@ #define ROUND(x) ((int)((x)<0 ? (x)-0.5 : (x)+0.5)) +extern int use_menu; + static void rescale_input_coordinates(int ix, int iy, double *dx, double *dy) { //remove the borders, if any, and rescale to the range [0,1],[0,1] @@ -2991,6 +2997,10 @@ int run_command(MPContext * mpctx, mp_cmd_t * cmd) set_osd_msg(OSD_MSG_TEXT, 1, osd_duration, "Selected button number %d", button); } +#endif +#ifdef HAVE_MENU + if (use_menu && dx >= 0.0 && dy >= 0.0) + menu_update_mouse_pos(dx, dy); #endif } break; diff --git a/etc/menu.conf b/etc/menu.conf index 205a0d823d..bc8adacfa1 100644 --- a/etc/menu.conf +++ b/etc/menu.conf @@ -23,6 +23,8 @@ + + diff --git a/libmenu/menu.c b/libmenu/menu.c index 358202b715..879e977510 100644 --- a/libmenu/menu.c +++ b/libmenu/menu.c @@ -68,6 +68,10 @@ struct menu_def_st { char* args; }; +double menu_mouse_x = -1.0; +double menu_mouse_y = -1.0; +int menu_mouse_pos_updated = 0; + static struct MPContext *menu_ctx = NULL; static menu_def_t* menu_list = NULL; static int menu_count = 0; @@ -324,6 +328,12 @@ void menu_draw(menu_t* menu,mp_image_t* mpi) { menu->draw(menu,mpi); } +void menu_update_mouse_pos(double x, double y) { + menu_mouse_x = x; + menu_mouse_y = y; + menu_mouse_pos_updated = 1; +} + void menu_read_cmd(menu_t* menu,int cmd) { if(menu->read_cmd) menu->read_cmd(menu,cmd); diff --git a/libmenu/menu.h b/libmenu/menu.h index 8690d4a579..d05749f440 100644 --- a/libmenu/menu.h +++ b/libmenu/menu.h @@ -44,6 +44,7 @@ typedef struct menu_info_s { #define MENU_CMD_END 8 #define MENU_CMD_PAGE_UP 9 #define MENU_CMD_PAGE_DOWN 10 +#define MENU_CMD_CLICK 11 /// Global init/uninit int menu_init(struct MPContext *mpctx, char* cfg_file); @@ -60,6 +61,9 @@ void menu_read_key(menu_t* menu,int cmd); //// Default implementation int menu_dflt_read_key(menu_t* menu,int cmd); +/// Receive mouse position events. +void menu_update_mouse_pos(double x, double y); + /////////// Helpers #define MENU_TEXT_TOP (1<<0) diff --git a/libmenu/menu_list.c b/libmenu/menu_list.c index 990095d368..c49bbd6e4d 100644 --- a/libmenu/menu_list.c +++ b/libmenu/menu_list.c @@ -18,6 +18,16 @@ #define IMPL 1 #include "menu_list.h" +extern double menu_mouse_x; +extern double menu_mouse_y; +extern int menu_mouse_pos_updated; +static int mouse_x; +static int mouse_y; +static int selection_x; +static int selection_y; +static int selection_w; +static int selection_h; + #define mpriv (menu->priv) void menu_list_draw(menu_t* menu,mp_image_t* mpi) { @@ -127,9 +137,39 @@ void menu_list_draw(menu_t* menu,mp_image_t* mpi) { dx = x < 0 ? (mpi->w - need_w) / 2 : x; bx = x < 0 ? (mpi->w - bg_w) / 2 : x - mpriv->minb; + + // If mouse moved, try to update selected menu item by the mouse position. + if (menu_mouse_pos_updated) { + mouse_x = menu_mouse_x * mpi->width; + mouse_y = menu_mouse_y * mpi->height; + if (mouse_x >= bx && mouse_x < bx + bg_w) { + int by = dy + y - mpriv->vspace / 2; + int max_by = dh + y + mpriv->vspace / 2; + if (mouse_y >= by && mouse_y < max_by) { + int cur_no = (mouse_y - by) / line_h; + list_entry_t* e = m; + for (i = 0; e != NULL; e = e->next) { + if (e->hide) continue; + if (i == cur_no) { + mpriv->current = e; + break; + } + ++i; + } + } + } + menu_mouse_pos_updated = 0; + } + for( ; m != NULL && dy + vo_font->height < dh ; m = m->next ) { if(m->hide) continue; if(m == mpriv->current) { + // Record rectangle of current selection box. + selection_x = bx; + selection_y = dy + y - mpriv->vspace / 2; + selection_w = bg_w; + selection_h = line_h; + if(mpriv->ptr_bg >= 0) menu_draw_box(mpi,mpriv->ptr_bg,mpriv->ptr_bg_alpha, bx, dy + y - mpriv->vspace / 2, @@ -211,6 +251,11 @@ void menu_list_read_cmd(menu_t* menu,int cmd) { menu->show = 0; menu->cl = 1; break; + case MENU_CMD_CLICK: + if (mouse_x >= selection_x && mouse_x < selection_x + selection_w && + mouse_y >= selection_y && mouse_y < selection_y + selection_h) + menu_read_cmd(menu, MENU_CMD_OK); + break; } } diff --git a/libmenu/vf_menu.c b/libmenu/vf_menu.c index 29d9e2c55c..7a4902a990 100644 --- a/libmenu/vf_menu.c +++ b/libmenu/vf_menu.c @@ -81,6 +81,8 @@ static int cmd_filter(mp_cmd_t* cmd, int paused, struct vf_priv_s * priv) { menu_read_cmd(priv->current,MENU_CMD_PAGE_UP); else if(strcmp(arg,"pagedown") == 0) menu_read_cmd(priv->current,MENU_CMD_PAGE_DOWN); + else if(strcmp(arg,"click") == 0) + menu_read_cmd(priv->current,MENU_CMD_CLICK); else if(strcmp(arg,"hide") == 0 || strcmp(arg,"toggle") == 0) priv->current->show = 0; else diff --git a/mplayer.c b/mplayer.c index 2134d2360f..0774a3f967 100644 --- a/mplayer.c +++ b/mplayer.c @@ -352,7 +352,7 @@ static vf_info_t* libmenu_vfs[] = { NULL }; static vf_instance_t* vf_menu = NULL; -static int use_menu = 0; +int use_menu = 0; static char* menu_cfg = NULL; static char* menu_root = "main"; #endif