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