Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

positioning.lua: add this script #15314

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions DOCS/man/mpv.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1461,6 +1461,8 @@ works like in older mpv releases:

.. include:: console.rst

.. include:: positioning.rst

.. include:: lua.rst

.. include:: javascript.rst
Expand Down
4 changes: 4 additions & 0 deletions DOCS/man/options.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1067,6 +1067,10 @@ Program Behavior
Enable the builtin script that lets you select from lists of items (default:
yes). By default, its keybindings start with the ``g`` key.

``--load-positioning=<yes|no>``
Enable the builtin script that provides various keybindings to pan videos
and images (default: yes).

``--player-operation-mode=<cplayer|pseudo-gui>``
For enabling "pseudo GUI mode", which means that the defaults for some
options are changed. This option should not normally be used directly, but
Expand Down
36 changes: 36 additions & 0 deletions DOCS/man/positioning.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
POSITIONING
===========

This script provides key bindings to pan videos and images.

Script messages and bindings
----------------------------

``pan <axis> <amount>``
Adjust ``--video-align-x`` or ``--video-align-y`` relatively to the OSD
sizes, rather than relatively to the video sizes like the options. This is
useful to pan large images consistently.

``axis`` can be ``x`` or ``y``, and ``amount`` is a number such that an
amount of 1 scrolls as much as the OSD width or height.

``drag-to-pan``
Pan the video while holding a mouse button, relatively to the clicked point in
the OSD.

``align-to-cursor``
Pan the video while holding a mouse button, relatively to the whole video.

``cursor-centric-zoom <zoom>``
Increase ``--video-zoom`` by ``zoom`` and adjust ``--video-align-x`` and
``--video-align-y`` to shift the OSD towards the position hovered by the
cursor, or the average position of touch points if known.

Configurable Options
~~~~~~~~~~~~~~~~~~~~

``suppress_osd``
Default: no

Whether to not print the new value of ``--video-zoom`` when using
``cursor-centric-zoom``.
2 changes: 2 additions & 0 deletions options/options.c
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,7 @@ static const m_option_t mp_opts[] = {
OPT_CHOICE(lua_load_auto_profiles, {"no", 0}, {"yes", 1}, {"auto", -1}),
.flags = UPDATE_BUILTIN_SCRIPTS},
{"load-select", OPT_BOOL(lua_load_select), .flags = UPDATE_BUILTIN_SCRIPTS},
{"load-positioning", OPT_BOOL(lua_load_positioning), .flags = UPDATE_BUILTIN_SCRIPTS},
#endif

// ------------------------- stream options --------------------
Expand Down Expand Up @@ -1009,6 +1010,7 @@ static const struct MPOpts mp_default_opts = {
.lua_load_console = true,
.lua_load_auto_profiles = -1,
.lua_load_select = true,
.lua_load_positioning = true,
#endif
.auto_load_scripts = true,
.loop_times = 1,
Expand Down
1 change: 1 addition & 0 deletions options/options.h
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ typedef struct MPOpts {
bool lua_load_console;
int lua_load_auto_profiles;
bool lua_load_select;
bool lua_load_positioning;

bool auto_load_scripts;

Expand Down
2 changes: 1 addition & 1 deletion player/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,7 @@ typedef struct MPContext {

struct mp_ipc_ctx *ipc_ctx;

int64_t builtin_script_ids[6];
int64_t builtin_script_ids[7];

mp_mutex abort_lock;

Expand Down
3 changes: 3 additions & 0 deletions player/lua.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ static const char * const builtin_lua_scripts[][2] = {
},
{"@select.lua",
# include "player/lua/select.lua.inc"
},
{"@positioning.lua",
# include "player/lua/positioning.lua.inc"
},
{0}
};
Expand Down
2 changes: 1 addition & 1 deletion player/lua/meson.build
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
lua_files = ['defaults.lua', 'assdraw.lua', 'options.lua', 'osc.lua',
'ytdl_hook.lua', 'stats.lua', 'console.lua', 'auto_profiles.lua',
'input.lua', 'fzy.lua', 'select.lua']
'input.lua', 'fzy.lua', 'select.lua', 'positioning.lua']
foreach file: lua_files
lua_file = custom_target(file,
input: file,
Expand Down
119 changes: 119 additions & 0 deletions player/lua/positioning.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
--[[
This file is part of mpv.

mpv is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

mpv is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with mpv. If not, see <http://www.gnu.org/licenses/>.
]]

local options = {
suppress_osd = false,
}

require "mp.options".read_options(options)

mp.register_script_message("pan", function (axis, amount)
local dims = mp.get_property_native("osd-dimensions")
local dimension = axis == "x" and dims.w - dims.ml - dims.mr or dims.h - dims.mt - dims.mb
local osd_dimension = axis == "x" and dims.w or dims.h
-- 1 video-align shifts the OSD by (dimension - osd_dimension) / 2 pixels,
-- so the equation to find how much video-align to add to offset the OSD by
-- osd_dimension is:
-- x/1 = osd_dimension / ((dimension - osd_dimension) / 2)
if dimension ~= osd_dimension then
mp.commandv("add", "video-align-" .. axis,
amount * 2 * osd_dimension / (dimension - osd_dimension))
end
end)

mp.add_key_binding(nil, "drag-to-pan", function (t)
if t.event == "up" then
mp.remove_key_binding("drag-to-pan-mouse-move")
return
end

local dims = mp.get_property_native("osd-dimensions")
local old_mouse_pos = mp.get_property_native("mouse-pos")
local old_align_x = mp.get_property_native("video-align-x")
local old_align_y = mp.get_property_native("video-align-y")

mp.add_forced_key_binding("MOUSE_MOVE", "drag-to-pan-mouse-move", function()
local mouse_pos = mp.get_property_native("mouse-pos")
-- 1 video-align shifts the OSD by (dimension - osd_dimension) / 2 pixels,
-- so the equation to find how much video-align to add to offset the OSD
-- by the difference in mouse position is:
-- x/1 = (mouse_pos - old_mouse_pos) / ((dimension - osd_dimension) / 2)
local align = old_align_x + 2 * (mouse_pos.x - old_mouse_pos.x)
/ (dims.ml + dims.mr)
mp.set_property("video-align-x", math.min(1, math.max(align, -1)))
align = old_align_y + 2 * (mouse_pos.y - old_mouse_pos.y)
/ (dims.mt + dims.mb)
mp.set_property("video-align-y", math.min(1, math.max(align, -1)))
end)
end, { complex = true })

mp.add_key_binding(nil, "align-to-cursor", function (t)
if t.event == "up" then
mp.remove_key_binding("align-to-cursor-mouse-move")
return
end

local dims = mp.get_property_native("osd-dimensions")
mp.add_forced_key_binding("MOUSE_MOVE", "align-to-cursor-mouse-move", function()
local mouse_pos = mp.get_property_native("mouse-pos")
mp.set_property("video-align-x", (mouse_pos.x * 2 - dims.w) / dims.w)
mp.set_property("video-align-y", (mouse_pos.y * 2 - dims.h) / dims.h)
end)
end, { complex = true })

mp.register_script_message("cursor-centric-zoom", function (amount)
local command = (options.suppress_osd and "no-osd " or "") ..
"add video-zoom " .. amount .. ";"

local x, y
local touch_positions = mp.get_property_native("touch-pos")
if next(touch_positions) then
for _, position in pairs(touch_positions) do
x = x + position.x
y = y + position.y
end
x = x / #touch_positions
y = y / #touch_positions
else
local mouse_pos = mp.get_property_native("mouse-pos")
x = mouse_pos.x
y = mouse_pos.y
end

local dims = mp.get_property_native("osd-dimensions")
local width = (dims.w - dims.ml - dims.mr) * 2^amount
local height = (dims.h - dims.mt - dims.mb) * 2^amount

local old_cursor_ml = dims.ml - x
local cursor_ml = old_cursor_ml * 2^amount
local ml = cursor_ml + x
-- video/out/aspect.c:src_dst_split_scaling() defines ml as:
-- ml = (osd-width - width) * (video-align-x + 1) / 2 + pan-x * width
-- So video-align-x is:
local align = 2 * (ml - mp.get_property_native("video-pan-x") * width)
/ (dims.w - width) - 1
command = command .. "no-osd set video-align-x " ..
math.min(1, math.max(align, -1)) .. ";"

local mt = (dims.mt - y) * 2^amount + y
align = 2 * (mt - mp.get_property_native("video-pan-y") * height)
/ (dims.h - height) - 1
command = command .. "no-osd set video-align-y " ..
math.min(1, math.max(align, -1))

mp.command(command)
end)
1 change: 1 addition & 0 deletions player/scripting.c
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ void mp_load_builtin_scripts(struct MPContext *mpctx)
load_builtin_script(mpctx, 4, mpctx->opts->lua_load_auto_profiles,
"@auto_profiles.lua");
load_builtin_script(mpctx, 5, mpctx->opts->lua_load_select, "@select.lua");
load_builtin_script(mpctx, 6, mpctx->opts->lua_load_positioning, "@positioning.lua");
}

bool mp_load_scripts(struct MPContext *mpctx)
Expand Down
Loading