summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Vazgenovich Shakaryan <dvshakaryan@gmail.com>2026-01-18 23:32:17 -0800
committerDavid Vazgenovich Shakaryan <dvshakaryan@gmail.com>2026-01-18 23:32:17 -0800
commit664da9e0dfec80dc1cb49d1a1ffa4efa5b948607 (patch)
tree8a2ebad79bda5a95b0d8c03ddefabaef30362af8
parent5e0511b18aa495ea84038f8f1c4f17167790bf84 (diff)
downloadmpv-iptv-menu-664da9e0dfec80dc1cb49d1a1ffa4efa5b948607.tar.gz
mpv-iptv-menu-664da9e0dfec80dc1cb49d1a1ffa4efa5b948607.tar.xz
add menu toggle button for mouse
-rw-r--r--config.lua3
-rw-r--r--main.lua53
-rw-r--r--osd.lua80
3 files changed, 135 insertions, 1 deletions
diff --git a/config.lua b/config.lua
index 9c82f74..5ea72e6 100644
--- a/config.lua
+++ b/config.lua
@@ -12,6 +12,7 @@ config.scroll_margin = 4
config.click_timeout = 0.5
config.click_dbl_time = 0.3
config.click_max_drift = 2
+config.toggle_button_timeout = 0.5
config.bg_alpha = '44'
config.colours = {
@@ -35,6 +36,8 @@ config.colours = {
scrollbar_bg = '333333',
status_info = '55bbdd',
status_error = 'ff3333',
+ toggle_button_fg = '000000',
+ toggle_button_bg = '00cc00',
}
local script_dir = mp.get_script_directory()
diff --git a/main.lua b/main.lua
index 481cb7d..563c2cf 100644
--- a/main.lua
+++ b/main.lua
@@ -1277,6 +1277,59 @@ local function toggle_menu()
set_key_bindings()
end
+local mouse_pos_time
+local mouse_over_button_area = false
+local mouse_over_toggle_button = false
+local mouse_timer; mouse_timer = mp.add_periodic_timer(0.1, function()
+ if mouse_pos_time and
+ not mouse_over_toggle_button and
+ mp.get_time() - mouse_pos_time >
+ config.toggle_button_timeout then
+ osd:show_toggle_button(false)
+ mouse_timer:kill()
+ end
+end, true) -- disabled
+mp.observe_property('mouse-pos', 'native', function(_, mpos)
+ if not mpos then
+ return
+ end
+
+ -- mpv sends (0, 0) on startup if the mouse hasn't moved yet. don't
+ -- trigger display of the button until the mouse has actually moved.
+ if not mouse_pos_time and mpos.x == 0 and mpos.y == 0 then
+ return
+ end
+
+ mouse_pos_time = mp.get_time()
+
+ local is_over = osd:mouse_over_button_area(mpos)
+ if is_over ~= mouse_over_button_area then
+ mouse_over_button_area = is_over
+ osd:show_toggle_button(mouse_over_button_area)
+ elseif mouse_over_button_area and osd.toggle_button.hidden then
+ osd:show_toggle_button(true)
+ end
+
+ if mouse_over_button_area then
+ mouse_timer:resume()
+ else
+ mouse_timer:kill()
+ end
+
+ local is_over = osd:mouse_over_toggle_button(mpos)
+ if is_over ~= mouse_over_toggle_button then
+ mouse_over_toggle_button = is_over
+ if mouse_over_toggle_button then
+ mp.add_forced_key_binding(
+ 'MBTN_LEFT', 'click', toggle_menu)
+ mp.add_forced_key_binding('MBTN_LEFT_DBL', 'click_dbl')
+ else
+ mp.remove_key_binding('click')
+ mp.remove_key_binding('click_dbl')
+ end
+ end
+end)
+
mp.observe_property('user-data/osc/visibility', 'native', function(_, val)
if val and (osd:is_hidden() or val ~= 'never') then
osc_visibility = val
diff --git a/osd.lua b/osd.lua
index bf5dfec..796c3b3 100644
--- a/osd.lua
+++ b/osd.lua
@@ -39,6 +39,7 @@ function osd.new(init)
local t = setmetatable({
fg = mp.create_osd_overlay('ass-events'),
bg = mp.create_osd_overlay('ass-events'),
+ toggle_button = mp.create_osd_overlay('ass-events'),
width = 0,
height = 0,
scale = 1,
@@ -46,6 +47,8 @@ function osd.new(init)
padding = math.floor((720 - (lines * config.font_size)) / 2),
}, mt)
t.bg.z = -1
+ t.toggle_button.z = 1
+ t.toggle_button.hidden = true
for k, v in pairs(init or {}) do
t[k] = v
@@ -67,7 +70,24 @@ end
function mt:resize(w, h)
self.width = w
self.height = h
- self.scale = h / 720
+ self.scale = h > 0 and h/720 or 1
+
+ local sz = self.padding + self:measure_width('»') - 2
+ local coords = {
+ x1 = 2,
+ y1 = self.padding + ((config.font_size - sz) / 2),
+ }
+ coords.x2 = coords.x1 + sz
+ coords.y2 = coords.y1 + sz
+ self.toggle_button_coords = coords
+
+ self.toggle_button.data =
+ '{\\pos(' .. coords.x1 .. ',' .. coords.y1 .. ')}' ..
+ colours.toggle_button_bg .. draw_rect(0, 0, sz, sz) .. '\n' ..
+ '{\\q2\\fs' .. sz .. '\\bord0\\an5\\pos(' ..
+ coords.x1 + sz/2 .. ',' .. coords.y1 + sz/2 ..')}' ..
+ colours.toggle_button_fg .. '≡'
+ self.toggle_button:update()
end
function mt:set_status(msg, level, no_dirty)
@@ -570,6 +590,12 @@ function mt:is_hidden()
end
function mt:get_mouse_line(mpos)
+ local x = mpos.x / self.scale
+ local w = self.width / self.scale
+ if x < self.padding or x > w - self.padding then
+ return
+ end
+
local y = mpos.y / self.scale
local line = math.floor((y - self.padding) / config.font_size) + 1
if line < 1 or line > self.lines then
@@ -578,4 +604,56 @@ function mt:get_mouse_line(mpos)
return line
end
+function mt:mouse_over_button_area(mpos)
+ if not mpos.hover then
+ return false
+ end
+
+ local y = mpos.y / self.scale
+ return y < self.padding + (2 * config.font_size)
+end
+
+function mt:mouse_over_toggle_button(mpos)
+ if not mpos.hover then
+ return false
+ end
+
+ local x = mpos.x / self.scale
+ local y = mpos.y / self.scale
+ local coords = self.toggle_button_coords
+ return coords and
+ x > coords.x1 and x < coords.x2 and
+ y > coords.y1 and y < coords.y2
+end
+
+function mt:show_toggle_button(bool)
+ if self.toggle_button.hidden ~= bool then
+ return
+ end
+
+ self.toggle_button.hidden = not bool
+ self.toggle_button:update()
+end
+
+function mt:measure_width(str)
+ local e = self.toggle_button
+ local data = e.data
+ local hidden = e.hidden
+ e.hidden = true
+ e.compute_bounds = true
+
+ local block = '\xe2\x96\x88'
+ local pre = '{\\q2\\fs' .. config.font_size .. '\\pos(0,0)}' .. block
+ e.data = pre .. block
+ local size = e:update().x1
+ e.data = pre .. str .. block
+ size = e:update().x1 - size
+
+ e.data = data
+ e.hidden = hidden
+ e.compute_bounds = false
+
+ return size
+end
+
return osd