summaryrefslogtreecommitdiffstats
path: root/mpvcore/lua/osc.lua
diff options
context:
space:
mode:
Diffstat (limited to 'mpvcore/lua/osc.lua')
-rw-r--r--mpvcore/lua/osc.lua110
1 files changed, 71 insertions, 39 deletions
diff --git a/mpvcore/lua/osc.lua b/mpvcore/lua/osc.lua
index 4b7c21abad..c724c7737c 100644
--- a/mpvcore/lua/osc.lua
+++ b/mpvcore/lua/osc.lua
@@ -10,17 +10,19 @@ local msg = require 'mp.msg'
-- default user option values
-- do not touch, change them in plugin_osc.conf
local user_opts = {
- showWindowed = true, -- show OSC when windowed?
- showFullscreen = true, -- show OSC when fullscreen?
- scaleWindowed = 1, -- scaling of the controller when windowed
- scaleFullscreen = 1, -- scaling of the controller when fullscreen
- scaleForcedWindow = 2, -- scaling of the controller when rendered on a forced (dummy) window
+ showwindowed = true, -- show OSC when windowed?
+ showfullscreen = true, -- show OSC when fullscreen?
+ scalewindowed = 1, -- scaling of the controller when windowed
+ scalefullscreen = 1, -- scaling of the controller when fullscreen
+ scaleforcedwindow = 2, -- scaling of the controller when rendered on a forced (dummy) window
vidscale = true, -- scale the controller with the video?
valign = 0.8, -- vertical alignment, -1 (top) to 1 (bottom)
halign = 0, -- horizontal alignment, -1 (left) to 1 (right)
+ hidetimeout = 500, -- duration in ms until the OSC hides if no mouse movement, negative value disables autohide
fadeduration = 200, -- duration of fade out in ms, 0 = no fade
- deadzonedist = 0.15, -- distance between OSC and deadzone
- iAmAProgrammer = false, -- use native mpv values and disable OSC internal playlist management (and some functions that depend on it)
+ deadzonesize = 0, -- size of deadzone
+ minmousemove = 3, -- minimum amount of pixels the mouse has to move between ticks to make the OSC show up
+ iamaprogrammer = false, -- use native mpv values and disable OSC internal playlist management (and some functions that depend on it)
}
local osc_param = {
@@ -50,6 +52,7 @@ local osc_styles = {
-- internal states, do not touch
local state = {
+ showtime, -- time of last invocation (last mouse move)
osc_visible = false,
anistart, -- time when the animation started
anitype, -- current type of animation
@@ -62,6 +65,7 @@ local state = {
mp_screen_sizeX, mp_screen_sizeY, -- last screen-resolution, to detect resolution changes to issue reINITs
initREQ = false, -- is a re-init request pending?
last_seek, -- last seek position, to avoid deadlocks by repeatedly seeking to the same position
+ last_mouseX, last_mouseY, -- last mouse position, to detect siginificant mouse movement
message_text,
message_timeout,
}
@@ -117,16 +121,7 @@ function read_config(options, identifier)
local conffile = mp.find_config_file(conffilename)
local f = io.open(conffile,"r")
if f == nil then
- msg.warn(conffile.." does not exist, creating it ...")
- -- so create it, write default options
- local f = io.open(conffile,"w+")
- f:write("# Config file for "..identifier.."\n# <-- works only at beginning of line.\n# Do not have any spare spaces flying around.\n\n")
- -- iterate over the options table
- for key, value in pairs(options) do
- f:write("#" .. key .. "=" .. val2str(value) .. "\n")
- end
- io.close(f)
-
+ -- config not found
else
-- config exists, read values
local linecounter = 1
@@ -227,7 +222,7 @@ function get_slider_value(element)
end
function countone(val)
- if not (user_opts.iAmAProgrammer) then
+ if not (user_opts.iamaprogrammer) then
val = val + 1
end
return val
@@ -641,17 +636,17 @@ function osc_init()
-- kill old Elements
elements = {}
- -- set canvas resolution acording to display aspect and scaling setting
+ -- set canvas resolution according to display aspect and scaling setting
local baseResY = 720
local display_w, display_h, display_aspect = mp.get_screen_size()
local scale = 1
if (mp.property_get("video") == "no") then -- dummy/forced window
- scale = user_opts.scaleForcedWindow
+ scale = user_opts.scaleforcedwindow
elseif (mp.property_get("fullscreen") == "yes") then
- scale = user_opts.scaleFullscreen
+ scale = user_opts.scalefullscreen
else
- scale = user_opts.scaleWindowed
+ scale = user_opts.scalewindowed
end
@@ -796,7 +791,7 @@ function osc_init()
-- Smaller buttons
--
- if not (user_opts.iAmAProgrammer) then
+ if not (user_opts.iamaprogrammer) then
update_tracklist()
end
@@ -806,7 +801,7 @@ function osc_init()
local eventresponder = {}
local contentF
- if not (user_opts.iAmAProgrammer) then
+ if not (user_opts.iamaprogrammer) then
metainfo.enabled = (#tracks_osc.audio > 0)
contentF = function (ass)
@@ -843,7 +838,7 @@ function osc_init()
local eventresponder = {}
local contentF
- if not (user_opts.iAmAProgrammer) then
+ if not (user_opts.iamaprogrammer) then
metainfo.enabled = (#tracks_osc.sub > 0)
contentF = function (ass)
@@ -1004,6 +999,9 @@ end
function show_osc()
+ --remember last time of invocation (mouse move)
+ state.showtime = mp.get_timer()
+
state.osc_visible = true
if (user_opts.fadeduration > 0) then
@@ -1024,36 +1022,51 @@ end
function mouse_leave()
hide_osc()
+ -- reset mouse position
+ state.last_mouseX, state.last_mouseY = nil, nil
end
function request_init()
state.initREQ = true
end
--- called by mpv on every frame
function render()
local current_screen_sizeX, current_screen_sizeY = mp.get_screen_size()
+ local mouseX, mouseY = mp.get_mouse_pos()
+ local now = mp.get_timer()
+ -- check if display changed, if so request reinit
if not (state.mp_screen_sizeX == current_screen_sizeX and state.mp_screen_sizeY == current_screen_sizeY) then
- -- display changed, reinit everything
request_init()
state.mp_screen_sizeX, state.mp_screen_sizeY = current_screen_sizeX, current_screen_sizeY
end
+ -- init management
if state.initREQ then
osc_init()
state.initREQ = false
+
+ -- store initial mouse position
+ if (state.last_mouseX == nil or state.last_mouseY == nil) and not (mouseX == nil or mouseY == nil) then
+ state.last_mouseX, state.last_mouseY = mouseX, mouseY
+ end
end
- if not(state.anitype == nil) then
+ -- autohide
+ if not (state.showtime == nil) and (user_opts.hidetimeout >= 0) and (state.showtime + (user_opts.hidetimeout/1000) < now) and (state.active_element == nil)
+ and not (mouseX >= osc_param.posX - (osc_param.osc_w / 2) and mouseX <= osc_param.posX + (osc_param.osc_w / 2)
+ and mouseY >= osc_param.posY - (osc_param.osc_h / 2) and mouseY <= osc_param.posY + (osc_param.osc_h / 2)) then
+ hide_osc()
+ end
- local now = mp.get_timer()
+ -- fade animation
+ if not(state.anitype == nil) then
if (state.anistart == nil) then
state.anistart = now
end
- if (now < state.anistart + (user_opts.fadeduration/1000) ) then
+ if (now < state.anistart + (user_opts.fadeduration/1000)) then
if (state.anitype == "in") then --fade in
state.osc_visible = true
@@ -1074,14 +1087,18 @@ function render()
state.anitype = nil
end
+ -- actual rendering
local ass = assdraw.ass_new()
+ -- Messages
render_message(ass)
+ -- actual OSC
if state.osc_visible then
render_elements(ass)
end
+ -- submit
local w, h, aspect = mp.get_screen_size()
mp.set_osd_ass(osc_param.playresy * aspect, osc_param.playresy, ass.text)
@@ -1089,23 +1106,28 @@ function render()
local area_y0, area_y1
if user_opts.valign > 0 then
-- deadzone above OSC
- area_y0 = get_align(1 - user_opts.deadzonedist, osc_param.posY - (osc_param.osc_h / 2), 0, 0)
+ area_y0 = get_align(-1 + (2*user_opts.deadzonesize), osc_param.posY - (osc_param.osc_h / 2), 0, 0)
area_y1 = osc_param.playresy
else
-- deadzone below OSC
area_y0 = 0
area_y1 = (osc_param.posY + (osc_param.osc_h / 2))
- + get_align(-1 + user_opts.deadzonedist, osc_param.playresy - (osc_param.posY + (osc_param.osc_h / 2)), 0, 0)
+ + get_align(1 - (2*user_opts.deadzonesize), osc_param.playresy - (osc_param.posY + (osc_param.osc_h / 2)), 0, 0)
end
--mouse show/hide area
mp.set_mouse_area(0, area_y0, osc_param.playresx, area_y1, "showhide")
--mouse input area
- mp.set_mouse_area(
- osc_param.posX - (osc_param.osc_w / 2), osc_param.posY - (osc_param.osc_h / 2),
- osc_param.posX + (osc_param.osc_w / 2), osc_param.posY + (osc_param.osc_h / 2),
- "input")
+ if state.osc_visible then -- activate only when OSC is actually visible
+ mp.set_mouse_area(
+ osc_param.posX - (osc_param.osc_w / 2), osc_param.posY - (osc_param.osc_h / 2),
+ osc_param.posX + (osc_param.osc_w / 2), osc_param.posY + (osc_param.osc_h / 2),
+ "input")
+ mp.enable_key_bindings("input")
+ else
+ mp.disable_key_bindings("input")
+ end
end
@@ -1155,7 +1177,16 @@ function process_event(source, what)
state.last_seek = nil
elseif source == "mouse_move" then
- show_osc()
+ local mouseX, mouseY = mp.get_mouse_pos()
+ if (user_opts.minmousemove == 0) or
+ (not ((state.last_mouseX == nil) or (state.last_mouseY == nil)) and
+ ((math.abs(mouseX - state.last_mouseX) >= user_opts.minmousemove)
+ or (math.abs(mouseY - state.last_mouseY) >= user_opts.minmousemove)
+ )
+ ) then
+ show_osc()
+ end
+ state.last_mouseX, state.last_mouseY = mouseX, mouseY
if not (state.active_element == nil) then
@@ -1170,8 +1201,9 @@ function process_event(source, what)
end
end
+-- called by mpv on every frame
function tick()
- if (mp.property_get("fullscreen") == "yes" and user_opts.showFullscreen) or (mp.property_get("fullscreen") == "no" and user_opts.showWindowed) then
+ if (mp.property_get("fullscreen") == "yes" and user_opts.showfullscreen) or (mp.property_get("fullscreen") == "no" and user_opts.showwindowed) then
render()
else
mp.set_osd_ass(osc_param.playresy, osc_param.playresy, "")
@@ -1192,7 +1224,7 @@ mp.set_key_bindings({
{"mouse_move", function(e) process_event("mouse_move", nil) end},
{"mouse_leave", mouse_leave},
}, "showhide")
-mp.enable_key_bindings("showhide", "allow-vo-dragging")
+mp.enable_key_bindings("showhide", "allow-vo-dragging|allow-hide-cursor")
--mouse input bindings
mp.set_key_bindings({