Skip to content

Commit

Permalink
Add mouse support in menus.
Browse files Browse the repository at this point in the history
  • Loading branch information
iwalton3 committed Feb 15, 2023
1 parent 6a64bba commit 4067bec
Show file tree
Hide file tree
Showing 8 changed files with 107 additions and 7 deletions.
3 changes: 2 additions & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
include plex_mpv_shim/systray.png
recursive-include plex_mpv_shim/default_shader_pack *
recursive-include plex_mpv_shim/default_shader_pack *
include jellyfin_mpv_shim/mouse.lua
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,8 @@ Currently on Windows the built-in MPV does not work with SVP. You must download
- `stop_idle` - Stop the player when idle. (Requires `idle_when_paused`.) Default: `false`
- `skip_intro_always` - Always skip intros, without asking. Default: `false`
- `skip_intro_prompt` - Prompt to skip intro via seeking. Default: `true`
- `menu_mouse` - Enable mouse support in the menu. Default: `true`
- This requires MPV to be compiled with lua support.

### MPV Configuration

Expand Down
2 changes: 1 addition & 1 deletion build-debug.bat
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@echo off
git pull
rd /s /q __pycache__ dist build
pyinstaller -cF --add-binary "mpv-2.dll;." --add-binary "plex_mpv_shim\systray.png;." --icon media.ico run.py --hidden-import pystray._win32
pyinstaller -cF --add-binary "mpv-2.dll;." --add-binary "plex_mpv_shim\systray.png;." --add-data "plex_mpv_shim\mouse.lua;plex_mpv_shim" --icon media.ico run.py --hidden-import pystray._win32
2 changes: 1 addition & 1 deletion build.bat
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
@echo off
git pull
rd /s /q __pycache__ dist build
pyinstaller -w --add-binary "mpv-2.dll;." --add-binary "plex_mpv_shim\systray.png;." --add-data "plex_mpv_shim\default_shader_pack;plex_mpv_shim\default_shader_pack" --hidden-import pystray._win32 --icon media.ico run.py
pyinstaller -w --add-binary "mpv-2.dll;." --add-binary "plex_mpv_shim\systray.png;." --add-data "plex_mpv_shim\mouse.lua;plex_mpv_shim" --add-data "plex_mpv_shim\default_shader_pack;plex_mpv_shim\default_shader_pack" --hidden-import pystray._win32 --icon media.ico run.py
if %errorlevel% neq 0 exit /b %errorlevel%
del dist\run\run.exe.manifest
copy hidpi.manifest dist\run\run.exe.manifest
Expand Down
1 change: 1 addition & 0 deletions plex_mpv_shim/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ class Settings(object):
"svp_url": "http://127.0.0.1:9901/",
"svp_socket": None,
"shader_pack_subtype": "lq",
"menu_mouse": True,
}

def __getattr__(self, name):
Expand Down
29 changes: 26 additions & 3 deletions plex_mpv_shim/menu.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ def __init__(self, playerManager):
self.menu_list = []
self.menu_selection = 0
self.menu_tmp = None
self.mouse_back = False
self.original_osd_color = playerManager._player.osd_back_color
self.original_osd_size = playerManager._player.osd_font_size

Expand Down Expand Up @@ -83,15 +84,28 @@ def refresh_menu(self):
items = self.menu_list
selected_item = self.menu_selection

menu_text = "{0}".format(self.menu_title)
if self.mouse_back:
menu_text = "(<--) {0}".format(self.menu_title)
else:
menu_text = self.menu_title
for i, item in enumerate(items):
fmt = "\n {0}"
if i == selected_item:
if i == selected_item and not self.mouse_back:
fmt = "\n **{0}**"
menu_text += fmt.format(item[0])

self.playerManager._player.show_text(menu_text,2**30,1)

def mouse_select(self, idx):
if idx < 0 or idx > len(self.menu_list):
return
if idx == 0:
self.mouse_back = True
else:
self.mouse_back = False
self.menu_selection = idx - 1
self.refresh_menu()

def show_menu(self):
self.is_menu_shown = True
player = self.playerManager._player
Expand All @@ -101,8 +115,11 @@ def show_menu(self):
if hasattr(player, 'osc'):
player.osc = False

player.command("script-message", "shim-menu-enable", "True")

self.menu_title = "Main Menu"
self.menu_selection = 0
self.mouse_back = False

if self.playerManager._media_item and not player.playback_abort:
self.menu_list = [
Expand Down Expand Up @@ -154,6 +171,8 @@ def hide_menu(self):
if hasattr(player, 'osc'):
player.osc = settings.enable_osc

player.command("script-message", "shim-menu-enable", "False")

if player.playback_abort:
player.play("")
else:
Expand Down Expand Up @@ -184,9 +203,13 @@ def menu_action(self, action):
else:
self.menu_title, self.menu_list, self.menu_selection = self.menu_stack.get_nowait()
elif action == "ok":
self.menu_list[self.menu_selection][1]()
if self.mouse_back:
self.menu_action("back")
else:
self.menu_list[self.menu_selection][1]()
elif action == "home":
self.show_menu()
self.mouse_back = False
self.refresh_menu()

def change_audio_menu_handle(self):
Expand Down
40 changes: 40 additions & 0 deletions plex_mpv_shim/mouse.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
last_idx = -1
function mouse_handler()
local x, y = mp.get_mouse_pos()
local hy = mp.get_property_native("osd-height")
if hy == nil
then
return
end
idx = math.floor((y * 1000 / hy - 33) / 55)
if idx ~= last_idx
then
last_idx = idx
mp.commandv("script-message", "shim-menu-select", idx)
end
end

function mouse_click_handler()
last_idx = -1 -- Force refresh.
mouse_handler()
mp.commandv("script-message", "shim-menu-click")
end

function client_message_handler(event)
if event["args"][1] == "shim-menu-enable"
then
if event["args"][2] == "True"
then
mp.log("info", "Enabled shim menu mouse events.")
mp.add_key_binding("MOUSE_BTN0", "shim_mouse_click_handler", mouse_click_handler)
mp.add_key_binding("MOUSE_MOVE", "shim_mouse_move_handler", mouse_handler)
else
mp.log("info", "Disabled shim menu mouse events.")
mp.remove_key_binding("shim_mouse_click_handler")
mp.remove_key_binding("shim_mouse_move_handler")
end
end
end

mp.add_key_binding("MOUSE_MOVE", "shim_mouse_move_handler", mouse_handler)
mp.register_event("client-message", client_message_handler)
35 changes: 34 additions & 1 deletion plex_mpv_shim/player.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from collections import OrderedDict

from . import conffile
from .utils import synchronous, Timer
from .utils import synchronous, Timer, get_resource
from .conf import settings
from .menu import OSDMenu
from .media import MediaType
Expand Down Expand Up @@ -100,6 +100,12 @@ def __init__(self):
}
)

if settings.menu_mouse:
if is_using_ext_mpv:
mpv_options["script"] = get_resource("mouse.lua")
else:
mpv_options["scripts"] = get_resource("mouse.lua")

if not (settings.mpv_ext and settings.mpv_ext_no_ovr):
mpv_options["include"] = conffile.get(APP_NAME, "mpv.conf", True)
mpv_options["input_conf"] = conffile.get(APP_NAME, "input.conf", True)
Expand Down Expand Up @@ -242,6 +248,33 @@ def handle_end_idle(_name, value):
has_lock = self._finished_lock.acquire(False)
self.put_task(self.finished_callback, has_lock)

@self._player.event_callback('client-message')
def handle_client_message(event):
try:
# Python-MPV 1.0 uses a class/struct combination now
if hasattr(event, "as_dict"):
event = event.as_dict()
if 'event' in event:
event['event'] = event['event'].decode('utf-8')
if 'args' in event:
event['args'] = [d.decode('utf-8') for d in event['args']]

if "event_id" in event:
args = event["event"]["args"]
else:
args = event["args"]
if len(args) == 0:
return
if args[0] == "shim-menu-select":
# Apparently this can happen...
if args[1] == "inf":
return
self.menu.mouse_select(int(args[1]))
elif args[0] == "shim-menu-click":
self.menu.menu_action("ok")
except Exception:
log.warning("Error when processing client-message.", exc_info=True)

# Put a task to the event queue.
# This ensures the task executes outside
# of an event handler, which causes a crash.
Expand Down

0 comments on commit 4067bec

Please sign in to comment.