2547 lines
83 KiB
Lua
2547 lines
83 KiB
Lua
local msg = require('mp.msg')
|
||
local log = {
|
||
debug = function(format, ...)
|
||
return msg.debug(format:format(...))
|
||
end,
|
||
info = function(format, ...)
|
||
return msg.info(format:format(...))
|
||
end,
|
||
warn = function(format, ...)
|
||
return msg.warn(format:format(...))
|
||
end,
|
||
dump = function(item, ignore)
|
||
if "table" ~= type(item) then
|
||
msg.info(tostring(item))
|
||
return
|
||
end
|
||
local count = 1
|
||
local tablecount = 1
|
||
local result = {
|
||
"{ @" .. tostring(tablecount)
|
||
}
|
||
local seen = {
|
||
[item] = tablecount
|
||
}
|
||
local recurse
|
||
recurse = function(item, space)
|
||
for key, value in pairs(item) do
|
||
if not (key == ignore) then
|
||
if "table" == type(value) then
|
||
if not (seen[value]) then
|
||
tablecount = tablecount + 1
|
||
seen[value] = tablecount
|
||
count = count + 1
|
||
result[count] = space .. tostring(key) .. ": { @" .. tostring(tablecount)
|
||
recurse(value, space .. " ")
|
||
count = count + 1
|
||
result[count] = space .. "}"
|
||
else
|
||
count = count + 1
|
||
result[count] = space .. tostring(key) .. ": @" .. tostring(seen[value])
|
||
end
|
||
else
|
||
if "string" == type(value) then
|
||
value = ("%q"):format(value)
|
||
end
|
||
count = count + 1
|
||
result[count] = space .. tostring(key) .. ": " .. tostring(value)
|
||
end
|
||
end
|
||
end
|
||
end
|
||
recurse(item, " ")
|
||
count = count + 1
|
||
result[count] = "}"
|
||
return msg.info(table.concat(result, "\n"))
|
||
end
|
||
}
|
||
local options = require('mp.options')
|
||
local utils = require('mp.utils')
|
||
local script_name = 'torque-progressbar'
|
||
mp.get_osd_size = mp.get_osd_size or mp.get_screen_size
|
||
local settings = {
|
||
_defaults = { }
|
||
}
|
||
local settingsMeta = {
|
||
_reload = function(self)
|
||
for key, value in pairs(self._defaults) do
|
||
settings[key] = value
|
||
end
|
||
options.read_options(self, script_name .. '/main')
|
||
if self['bar-height-inactive'] <= 0 then
|
||
self['bar-hide-inactive'] = true
|
||
self['bar-height-inactive'] = 1
|
||
end
|
||
end,
|
||
_migrate = function(self)
|
||
local pathSep = package.config:sub(1, 1)
|
||
local onWindows = pathSep == '\\'
|
||
local mv
|
||
mv = function(oldFile, newFile)
|
||
local cmd = {
|
||
args = {
|
||
'mv',
|
||
oldConfig,
|
||
newConfig
|
||
}
|
||
}
|
||
if onWindows then
|
||
local oldfile = oldFile:gsub('/', pathSep)
|
||
newFile = newFile:gsub('/', pathSep)
|
||
cmd = {
|
||
args = {
|
||
'cmd',
|
||
'/Q',
|
||
'/C',
|
||
'move',
|
||
'/Y',
|
||
oldfile,
|
||
newFile
|
||
}
|
||
}
|
||
end
|
||
return utils.subprocess(cmd)
|
||
end
|
||
local mkdir
|
||
mkdir = function(directory)
|
||
local cmd = {
|
||
args = {
|
||
'mkdir',
|
||
'-p',
|
||
directory
|
||
}
|
||
}
|
||
if onWindows then
|
||
directory = directory:gsub('/', pathSep)
|
||
cmd = {
|
||
args = {
|
||
'cmd',
|
||
'/Q',
|
||
'/C',
|
||
'mkdir',
|
||
directory
|
||
}
|
||
}
|
||
end
|
||
return utils.subprocess(cmd)
|
||
end
|
||
local settingsDirectories = {
|
||
'script-opts',
|
||
'lua-settings'
|
||
}
|
||
local oldConfigFiles
|
||
do
|
||
local _accum_0 = { }
|
||
local _len_0 = 1
|
||
for _index_0 = 1, #settingsDirectories do
|
||
local dir = settingsDirectories[_index_0]
|
||
_accum_0[_len_0] = ('%s/%s.conf'):format(dir, script_name)
|
||
_len_0 = _len_0 + 1
|
||
end
|
||
oldConfigFiles = _accum_0
|
||
end
|
||
local newConfigFiles
|
||
do
|
||
local _accum_0 = { }
|
||
local _len_0 = 1
|
||
for _index_0 = 1, #settingsDirectories do
|
||
local dir = settingsDirectories[_index_0]
|
||
_accum_0[_len_0] = ('%s/%s/main.conf'):format(dir, script_name)
|
||
_len_0 = _len_0 + 1
|
||
end
|
||
newConfigFiles = _accum_0
|
||
end
|
||
local oldConfig = nil
|
||
local oldConfigIndex = 1
|
||
local newConfigFile = nil
|
||
local newConfig = nil
|
||
for idx, file in ipairs(oldConfigFiles) do
|
||
log.debug(('checking for old config "%s"'):format(file))
|
||
oldConfig = mp.find_config_file(file)
|
||
if oldConfig then
|
||
log.debug(('found "%s"'):format(oldConfig))
|
||
oldConfigIndex = idx
|
||
break
|
||
end
|
||
end
|
||
if not (oldConfig) then
|
||
log.debug('No old config file found. Migration finished.')
|
||
return
|
||
end
|
||
for _index_0 = 1, #newConfigFiles do
|
||
local file = newConfigFiles[_index_0]
|
||
log.debug(('checking for new config "%s"'):format(file))
|
||
newConfig = mp.find_config_file(file)
|
||
if newConfig then
|
||
log.debug(('found "%s"'):format(newConfig))
|
||
newConfigFile = file
|
||
break
|
||
end
|
||
end
|
||
if oldConfig and not newConfig then
|
||
log.debug(('Found "%s". Processing migration.'):format(oldConfig))
|
||
newConfigFile = newConfigFiles[oldConfigIndex]
|
||
local baseConfigFolder, _ = utils.split_path(oldConfig)
|
||
local configDir = utils.join_path(baseConfigFolder, script_name)
|
||
newConfig = utils.join_path(configDir, 'main.conf')
|
||
log.info(('Old configuration detected. Attempting to migrate "%s" -> "%s"'):format(oldConfig, newConfig))
|
||
local dirExists = mp.find_config_file(configDir)
|
||
if dirExists and not utils.readdir(configDir) then
|
||
log.warn(('Configuration migration failed. "%s" exists and does not appear to be a folder'):format(configDir))
|
||
return
|
||
else
|
||
if not dirExists then
|
||
log.debug(('Attempting to create directory "%s"'):format(configDir))
|
||
local res = mkdir(configDir)
|
||
if res.error or res.status ~= 0 then
|
||
log.warn(('Making directory "%s" failed.'):format(configDir))
|
||
return
|
||
end
|
||
log.debug('successfully created directory.')
|
||
else
|
||
log.debug(('Directory "%s" already exists. Continuing.'):format(configDir))
|
||
end
|
||
end
|
||
log.debug(('Attempting to move "%s" -> "%s"'):format(oldConfig, newConfig))
|
||
local res = mv(oldConfig, newConfig)
|
||
if res.error or res.status ~= 0 then
|
||
log.warn(('Moving file "%s" -> "%s" failed.'):format(oldConfig, newConfig))
|
||
return
|
||
end
|
||
if mp.find_config_file(newConfigFile) then
|
||
return log.info('Configuration successfully migrated.')
|
||
else
|
||
return log.warn(('Cannot find "%s". Migration mysteriously failed?'):format(newConfigFile))
|
||
end
|
||
end
|
||
end,
|
||
__newindex = function(self, key, value)
|
||
self._defaults[key] = value
|
||
return rawset(self, key, value)
|
||
end
|
||
}
|
||
settingsMeta.__index = settingsMeta
|
||
setmetatable(settings, settingsMeta)
|
||
settings:_migrate()
|
||
local helpText = { }
|
||
settings['hover-zone-height'] = 40
|
||
helpText['hover-zone-height'] = [[Sets the height of the rectangular area at the bottom of the screen that expands
|
||
the progress bar and shows playback time information when the mouse is hovered
|
||
over it.
|
||
]]
|
||
settings['top-hover-zone-height'] = 40
|
||
helpText['top-hover-zone-height'] = [[Sets the height of the rectangular area at the top of the screen that shows the
|
||
file name and system time when the mouse is hovered over it.
|
||
]]
|
||
settings['display-scale-factor'] = 1
|
||
helpText['display-scale-factor'] = [[Acts as a multiplier to increase the size of every UI element. Useful for high-
|
||
DPI displays that cause the UI to be rendered too small (happens at least on
|
||
macOS).
|
||
]]
|
||
settings['default-style'] = [[\fnSource Sans Pro\b1\bord2\shad0\fs30\c&HFC799E&\3c&H2D2D2D&]]
|
||
helpText['default-style'] = [[Default style that is applied to all UI elements. A string of ASS override tags.
|
||
Individual elements have their own style settings which override the tags here.
|
||
Changing the font will likely require changing the hover-time margin settings
|
||
and the offscreen-pos settings.
|
||
|
||
Here are some useful ASS override tags (omit square brackets):
|
||
\fn[Font Name]: sets the font to the named font.
|
||
\fs[number]: sets the font size to the given number.
|
||
\b[1/0]: sets the text bold or not (\b1 is bold, \b0 is regular weight).
|
||
\i[1/0]: sets the text italic or not (same semantics as bold).
|
||
\bord[number]: sets the outline width to the given number (in pixels).
|
||
\shad[number]: sets the shadow size to the given number (pixels).
|
||
\c&H[BBGGRR]&: sets the fill color for the text to the given color (hex pairs in
|
||
the order, blue, green, red).
|
||
\3c&H[BBGGRR]&: sets the outline color of the text to the given color.
|
||
\4c&H[BBGGRR]&: sets the shadow color of the text to the given color.
|
||
\alpha&H[AA]&: sets the line's transparency as a hex pair. 00 is fully opaque
|
||
and FF is fully transparent. Some UI elements are composed of
|
||
multiple layered lines, so adding transparency may not look good.
|
||
For further granularity, \1a&H[AA]& controls the fill opacity,
|
||
\3a&H[AA]& controls the outline opacity, and \4a&H[AA]& controls
|
||
the shadow opacity.
|
||
]]
|
||
settings['enable-bar'] = true
|
||
helpText['enable-bar'] = [[Controls whether or not the progress bar is drawn at all. If this is disabled,
|
||
it also (naturally) disables the click-to-seek functionality.
|
||
]]
|
||
settings['bar-hide-inactive'] = false
|
||
helpText['bar-hide-inactive'] = [[Causes the bar to not be drawn unless the mouse is hovering over it or a
|
||
request-display call is active. This is somewhat redundant with setting bar-
|
||
height-inactive=0, except that it can allow for very rudimentary context-
|
||
sensitive behavior because it can be toggled at runtime. For example, by using
|
||
the binding `f cycle pause; script-binding progressbar/toggle-inactive-bar`, it
|
||
is possible to have the bar be persistently present only in windowed or
|
||
fullscreen contexts, depending on the default setting.
|
||
]]
|
||
settings['bar-height-inactive'] = 3
|
||
helpText['bar-height-inactive'] = [[Sets the height of the bar display when the mouse is not in the active zone and
|
||
there is no request-display active. A value of 0 or less will cause bar-hide-
|
||
inactive to be set to true and the bar height to be set to 1. This should result
|
||
in the desired behavior while avoiding annoying debug logging in mpv (libass
|
||
does not like zero-height objects).
|
||
]]
|
||
settings['bar-height-active'] = 8
|
||
helpText['bar-height-active'] = [[Sets the height of the bar display when the mouse is in the active zone or
|
||
request-display is active. There is no logic attached to this, so 0 or negative
|
||
values may have unexpected results.
|
||
]]
|
||
settings['progress-bar-width'] = 0
|
||
helpText['progress-bar-width'] = [[If greater than zero, changes the progress bar style to be a small segment
|
||
rather than a continuous bar and sets its width.
|
||
]]
|
||
settings['seek-precision'] = 'exact'
|
||
helpText['seek-precision'] = [[Affects precision of seeks due to clicks on the progress bar. Should be 'exact' or
|
||
'keyframes'. Exact is slightly slower, but won't jump around between two
|
||
different times when clicking in the same place.
|
||
|
||
Actually, this gets passed directly into the `seek` command, so the value can be
|
||
any of the arguments supported by mpv, though the ones above are the only ones
|
||
that really make sense.
|
||
]]
|
||
settings['bar-background-adaptive'] = true
|
||
helpText['bar-background-adaptive'] = [[Causes the progress bar background layer to automatically size itself to the
|
||
tallest of the cache or progress bars. Useful for improving contrast but can
|
||
make the bar take up more screen space. Has no effect if the cache bar height is
|
||
less than the bar height.
|
||
]]
|
||
settings['bar-cache-position'] = 'overlay'
|
||
helpText['bar-cache-position'] = [[Placement of the cache bar. Valid values are 'overlay' and 'underlay'.
|
||
|
||
'overlay' causes the cache bar to be drawn on top of the foreground layer of the
|
||
bar, allowing the display of seek ranges that have already been encountered.
|
||
|
||
'underlay' draws the cache bar between the foreground and background layers. Any
|
||
demuxer cache ranges that are prior to the current playback point will not be
|
||
shown. This matches the previous behavior.
|
||
]]
|
||
settings['bar-cache-height-inactive'] = 1.5
|
||
helpText['bar-cache-height-inactive'] = [[Sets the height of the cache bar display when the mouse is not in the active
|
||
zone and there is no request-display active. Useful in combination with bar-
|
||
cache-position to control whether or not the cache bar is occluded by (or
|
||
occludes) the progress bar.
|
||
]]
|
||
settings['bar-cache-height-active'] = 4
|
||
helpText['bar-cache-height-active'] = [[Sets the height of the cache bar display when the mouse is in the active zone or
|
||
request-display is active. Useful in combination with bar-cache- position to
|
||
control whether or not the cache bar is occluded by (or occludes) the progress
|
||
bar.
|
||
]]
|
||
settings['bar-default-style'] = [[\bord0\shad0]]
|
||
helpText['bar-default-style'] = [[A string of ASS override tags that get applied to all three layers of the bar:
|
||
progress, cache, and background. You probably don't want to remove \bord0 unless
|
||
your default-style includes it.
|
||
]]
|
||
settings['bar-foreground-style'] = ''
|
||
helpText['bar-foreground-style'] = [[A string of ASS override tags that get applied only to the progress layer of the
|
||
bar.
|
||
]]
|
||
settings['bar-cache-style'] = [[\c&H515151&]]
|
||
helpText['bar-cache-style'] = [[A string of ASS override tags that get applied only to the cache layer of the
|
||
bar, particularly the part of the cache bar that is behind the current playback
|
||
position. The default sets only the color.
|
||
]]
|
||
settings['bar-cache-background-style'] = [[]]
|
||
helpText['bar-cache-background-style'] = [[A string of ASS override tags that get applied only to the cache layer of the
|
||
bar, particularly the part of the cache bar that is after the current playback
|
||
position. The tags specified here are applied after bar-cache-style and override
|
||
them. Leaving this blank will leave the style the same as specified by bar-
|
||
cache-style. The split does not account for a nonzero progress-bar-width and may
|
||
look odd when used in tandem with that setting.
|
||
]]
|
||
settings['bar-background-style'] = [[\c&H2D2D2D&]]
|
||
helpText['bar-background-style'] = [[A string of ASS override tags that get applied only to the background layer of
|
||
the bar. The default sets only the color.
|
||
]]
|
||
settings['enable-elapsed-time'] = true
|
||
helpText['enable-elapsed-time'] = [[Sets whether or not the elapsed time is displayed at all.
|
||
]]
|
||
settings['elapsed-style'] = ''
|
||
helpText['elapsed-style'] = [[A string of ASS override tags that get applied only to the elapsed time display.
|
||
]]
|
||
settings['elapsed-left-margin'] = 4
|
||
helpText['elapsed-left-margin'] = [[Controls how far from the left edge of the window the elapsed time display is
|
||
positioned.
|
||
]]
|
||
settings['elapsed-bottom-margin'] = 0
|
||
helpText['elapsed-bottom-margin'] = [[Controls how far above the expanded progress bar the elapsed time display is
|
||
positioned.
|
||
]]
|
||
settings['enable-remaining-time'] = true
|
||
helpText['enable-remaining-time'] = [[Sets whether or not the remaining time is displayed at all.
|
||
]]
|
||
settings['remaining-style'] = ''
|
||
helpText['remaining-style'] = [[A string of ASS override tags that get applied only to the remaining time
|
||
display.
|
||
]]
|
||
settings['remaining-right-margin'] = 4
|
||
helpText['remaining-right-margin'] = [[Controls how far from the right edge of the window the remaining time display is
|
||
positioned.
|
||
]]
|
||
settings['remaining-bottom-margin'] = 0
|
||
helpText['remaining-bottom-margin'] = [[Controls how far above the expanded progress bar the remaining time display is
|
||
positioned.
|
||
]]
|
||
settings['enable-hover-time'] = true
|
||
helpText['enable-hover-time'] = [[Sets whether or not the calculated time corresponding to the mouse position
|
||
is displayed when the mouse hovers over the progress bar.
|
||
]]
|
||
settings['hover-time-style'] = [[\fs26]]
|
||
helpText['hover-time-style'] = [[A string of ASS override tags that get applied only to the hover time display.
|
||
Unfortunately, due to the way the hover time display is animated, alpha values
|
||
set here will be overridden. This is subject to change in future versions.
|
||
]]
|
||
settings['hover-time-left-margin'] = 120
|
||
helpText['hover-time-left-margin'] = [[Controls how close to the left edge of the window the hover time display can
|
||
get. If this value is too small, it will end up overlapping the elapsed time
|
||
display.
|
||
]]
|
||
settings['hover-time-right-margin'] = 130
|
||
helpText['hover-time-right-margin'] = [[Controls how close to the right edge of the window the hover time display can
|
||
get. If this value is too small, it will end up overlapping the remaining time
|
||
display.
|
||
]]
|
||
settings['hover-time-bottom-margin'] = 0
|
||
helpText['hover-time-bottom-margin'] = [[Controls how far above the expanded progress bar the remaining time display is
|
||
positioned.
|
||
]]
|
||
settings['enable-title'] = true
|
||
helpText['enable-title'] = [[Sets whether or not the video title is displayed at all.
|
||
]]
|
||
settings['title-style'] = ''
|
||
helpText['title-style'] = [[A string of ASS override tags that get applied only to the video title display.
|
||
]]
|
||
settings['title-left-margin'] = 4
|
||
helpText['title-left-margin'] = [[Controls how far from the left edge of the window the video title display is
|
||
positioned.
|
||
]]
|
||
settings['title-top-margin'] = 0
|
||
helpText['title-top-margin'] = [[Controls how far from the top edge of the window the video title display is
|
||
positioned.
|
||
]]
|
||
settings['title-print-to-cli'] = true
|
||
helpText['title-print-to-cli'] = [[Controls whether or not the script logs the video title and playlist position
|
||
to the console every time a new video starts.
|
||
]]
|
||
settings['enable-system-time'] = true
|
||
helpText['enable-system-time'] = [[Sets whether or not the system time is displayed at all.
|
||
]]
|
||
settings['system-time-style'] = ''
|
||
helpText['system-time-style'] = [[A string of ASS override tags that get applied only to the system time display.
|
||
]]
|
||
settings['system-time-format'] = '%H:%M'
|
||
helpText['system-time-format'] = [[Sets the format used for the system time display. This must be a strftime-
|
||
compatible format string.
|
||
]]
|
||
settings['system-time-right-margin'] = 4
|
||
helpText['system-time-right-margin'] = [[Controls how far from the right edge of the window the system time display is
|
||
positioned.
|
||
]]
|
||
settings['system-time-top-margin'] = 0
|
||
helpText['system-time-top-margin'] = [[Controls how far from the top edge of the window the system time display is
|
||
positioned.
|
||
]]
|
||
settings['pause-indicator'] = true
|
||
helpText['pause-indicator'] = [[Sets whether or not the pause indicator is displayed. The pause indicator is a
|
||
momentary icon that flashes in the middle of the screen, similar to youtube.
|
||
]]
|
||
settings['pause-indicator-foreground-style'] = [[\c&HFC799E&]]
|
||
helpText['pause-indicator-foreground-style'] = [[A string of ASS override tags that get applied only to the foreground of the
|
||
pause indicator.
|
||
]]
|
||
settings['pause-indicator-background-style'] = [[\c&H2D2D2D&]]
|
||
helpText['pause-indicator-background-style'] = [[A string of ASS override tags that get applied only to the background of the
|
||
pause indicator.
|
||
]]
|
||
settings['enable-chapter-markers'] = true
|
||
helpText['enable-chapter-markers'] = [[Sets whether or not the progress bar is decorated with chapter markers. Due to
|
||
the way the chapter markers are currently implemented, videos with a large
|
||
number of chapters may slow down the script somewhat, but I have yet to run
|
||
into this being a problem.
|
||
]]
|
||
settings['chapter-marker-width'] = 2
|
||
helpText['chapter-marker-width'] = [[Controls the width of each chapter marker when the progress bar is inactive.
|
||
]]
|
||
settings['chapter-marker-width-active'] = 4
|
||
helpText['chapter-marker-width-active'] = [[Controls the width of each chapter marker when the progress bar is active.
|
||
]]
|
||
settings['chapter-marker-active-height-fraction'] = 1
|
||
helpText['chapter-marker-active-height-fraction'] = [[Modifies the height of the chapter markers when the progress bar is active. Acts
|
||
as a multiplier on the height of the active progress bar. A value greater than 1
|
||
will cause the markers to be taller than the expanded progress bar, whereas a
|
||
value less than 1 will cause them to be shorter.
|
||
]]
|
||
settings['chapter-marker-before-style'] = [[\c&HFC799E&]]
|
||
helpText['chapter-marker-before-style'] = [[A string of ASS override tags that get applied only to chapter markers that have
|
||
not yet been passed.
|
||
]]
|
||
settings['chapter-marker-after-style'] = [[\c&H2D2D2D&]]
|
||
helpText['chapter-marker-after-style'] = [[A string of ASS override tags that get applied only to chapter markers that have
|
||
already been passed.
|
||
]]
|
||
settings['request-display-duration'] = 1
|
||
helpText['request-display-duration'] = [[Sets the amount of time in seconds that the UI stays on the screen after it
|
||
receives a request-display signal. A value of 0 will keep the display on screen
|
||
only as long as the key bound to it is held down.
|
||
]]
|
||
settings['redraw-period'] = 0.03
|
||
helpText['redraw-period'] = [[Controls how often the display is redrawn, in seconds. This does not seem to
|
||
significantly affect the smoothness of animations, and it is subject to the
|
||
accuracy limits imposed by the scheduler mpv uses. Probably not worth changing
|
||
unless you have major performance problems.
|
||
]]
|
||
settings['animation-duration'] = 0.25
|
||
helpText['animation-duration'] = [[Controls how long the UI animations take. A value of 0 disables all animations
|
||
(which breaks the pause indicator).
|
||
]]
|
||
settings['elapsed-offscreen-pos'] = -100
|
||
helpText['elapsed-offscreen-pos'] = [[Controls how far off the left side of the window the elapsed time display tries
|
||
to move when it is inactive. If you use a non-default font, this value may need
|
||
to be tweaked. If this value is not far enough off-screen, the elapsed display
|
||
will disappear without animating all the way off-screen. Positive values will
|
||
cause the display to animate the wrong direction.
|
||
]]
|
||
settings['remaining-offscreen-pos'] = -100
|
||
helpText['remaining-offscreen-pos'] = [[Controls how far off the left side of the window the remaining time display
|
||
tries to move when it is inactive. If you use a non-default font, this value may
|
||
need to be tweaked. If this value is not far enough off-screen, the elapsed
|
||
display will disappear without animating all the way off-screen. Positive values
|
||
will cause the display to animate the wrong direction.
|
||
]]
|
||
settings['hover-time-offscreen-pos'] = -50
|
||
helpText['hover-time-offscreen-pos'] = [[Controls how far off the bottom of the window the mouse hover time display tries
|
||
to move when it is inactive. If you use a non-default font, this value may need
|
||
to be tweaked. If this value is not far enough off-screen, the elapsed
|
||
display will disappear without animating all the way off-screen. Positive values
|
||
will cause the display to animate the wrong direction.
|
||
]]
|
||
settings['system-time-offscreen-pos'] = -100
|
||
helpText['system-time-offscreen-pos'] = [[Controls how far off the left side of the window the system time display tries
|
||
to move when it is inactive. If you use a non-default font, this value may need
|
||
to be tweaked. If this value is not far enough off-screen, the elapsed display
|
||
will disappear without animating all the way off-screen. Positive values will
|
||
cause the display to animate the wrong direction.
|
||
]]
|
||
settings['title-offscreen-pos'] = -40
|
||
helpText['title-offscreen-pos'] = [[Controls how far off the left side of the window the video title display tries
|
||
to move when it is inactive. If you use a non-default font, this value may need
|
||
to be tweaked. If this value is not far enough off-screen, the elapsed display
|
||
will disappear without animating all the way off-screen. Positive values will
|
||
cause the display to animate the wrong direction.
|
||
]]
|
||
settings:_reload()
|
||
local Stack
|
||
do
|
||
local _class_0
|
||
local removeElementMetadata, reindex
|
||
local _base_0 = {
|
||
insert = function(self, element, index)
|
||
if index then
|
||
table.insert(self, index, element)
|
||
element[self] = index
|
||
else
|
||
table.insert(self, element)
|
||
element[self] = #self
|
||
end
|
||
if self.containmentKey then
|
||
element[self.containmentKey] = true
|
||
end
|
||
end,
|
||
remove = function(self, element)
|
||
if element[self] == nil then
|
||
error("Trying to remove an element that doesn't exist in this stack.")
|
||
end
|
||
table.remove(self, element[self])
|
||
reindex(self, element[self])
|
||
return removeElementMetadata(self, element)
|
||
end,
|
||
clear = function(self)
|
||
local element = table.remove(self)
|
||
while element do
|
||
removeElementMetadata(self, element)
|
||
element = table.remove(self)
|
||
end
|
||
end,
|
||
removeSortedList = function(self, elementList)
|
||
if #elementList < 1 then
|
||
return
|
||
end
|
||
for i = 1, #elementList - 1 do
|
||
local element = table.remove(elementList)
|
||
table.remove(self, element[self])
|
||
removeElementMetadata(self, element)
|
||
end
|
||
local lastElement = table.remove(elementList)
|
||
table.remove(self, lastElement[self])
|
||
reindex(self, lastElement[self])
|
||
return removeElementMetadata(self, lastElement)
|
||
end,
|
||
removeList = function(self, elementList)
|
||
table.sort(elementList, function(a, b)
|
||
return a[self] < b[self]
|
||
end)
|
||
return self:removeSortedList(elementList)
|
||
end
|
||
}
|
||
_base_0.__index = _base_0
|
||
_class_0 = setmetatable({
|
||
__init = function(self, containmentKey)
|
||
self.containmentKey = containmentKey
|
||
end,
|
||
__base = _base_0,
|
||
__name = "Stack"
|
||
}, {
|
||
__index = _base_0,
|
||
__call = function(cls, ...)
|
||
local _self_0 = setmetatable({}, _base_0)
|
||
cls.__init(_self_0, ...)
|
||
return _self_0
|
||
end
|
||
})
|
||
_base_0.__class = _class_0
|
||
local self = _class_0
|
||
removeElementMetadata = function(self, element)
|
||
element[self] = nil
|
||
if self.containmentKey then
|
||
element[self.containmentKey] = false
|
||
end
|
||
end
|
||
reindex = function(self, start)
|
||
if start == nil then
|
||
start = 1
|
||
end
|
||
for i = start, #self do
|
||
(self[i])[self] = i
|
||
end
|
||
end
|
||
Stack = _class_0
|
||
end
|
||
local Window
|
||
do
|
||
local _class_0
|
||
local osdScale
|
||
local _base_0 = { }
|
||
_base_0.__index = _base_0
|
||
_class_0 = setmetatable({
|
||
__init = function() end,
|
||
__base = _base_0,
|
||
__name = "Window"
|
||
}, {
|
||
__index = _base_0,
|
||
__call = function(cls, ...)
|
||
local _self_0 = setmetatable({}, _base_0)
|
||
cls.__init(_self_0, ...)
|
||
return _self_0
|
||
end
|
||
})
|
||
_base_0.__class = _class_0
|
||
local self = _class_0
|
||
osdScale = settings['display-scale-factor']
|
||
self.__class.w, self.__class.h = 0, 0
|
||
self.update = function(self)
|
||
local w, h = mp.get_osd_size()
|
||
w, h = math.floor(w / osdScale), math.floor(h / osdScale)
|
||
if w ~= self.w or h ~= self.h then
|
||
self.w, self.h = w, h
|
||
return true
|
||
else
|
||
return false
|
||
end
|
||
end
|
||
Window = _class_0
|
||
end
|
||
local Mouse
|
||
do
|
||
local _class_0
|
||
local osdScale, scaledPosition
|
||
local _base_0 = { }
|
||
_base_0.__index = _base_0
|
||
_class_0 = setmetatable({
|
||
__init = function() end,
|
||
__base = _base_0,
|
||
__name = "Mouse"
|
||
}, {
|
||
__index = _base_0,
|
||
__call = function(cls, ...)
|
||
local _self_0 = setmetatable({}, _base_0)
|
||
cls.__init(_self_0, ...)
|
||
return _self_0
|
||
end
|
||
})
|
||
_base_0.__class = _class_0
|
||
local self = _class_0
|
||
osdScale = settings['display-scale-factor']
|
||
self.__class.x, self.__class.y = -1, -1
|
||
self.__class.inWindow, self.__class.dead = false, true
|
||
self.__class.clickX, self.__class.clickY = -1, -1
|
||
self.__class.clickPending = false
|
||
scaledPosition = function()
|
||
local x, y = mp.get_mouse_pos()
|
||
return math.floor(x / osdScale), math.floor(y / osdScale)
|
||
end
|
||
self.update = function(self)
|
||
local oldX, oldY = self.x, self.y
|
||
self.x, self.y = scaledPosition()
|
||
if self.dead and (oldX ~= self.x or oldY ~= self.y) then
|
||
self.dead = false
|
||
end
|
||
if not self.dead and self.clickPending then
|
||
self.clickPending = false
|
||
return true
|
||
end
|
||
return false
|
||
end
|
||
self.cacheClick = function(self)
|
||
if not self.dead then
|
||
self.clickX, self.clickY = scaledPosition()
|
||
self.clickPending = true
|
||
else
|
||
self.dead = false
|
||
end
|
||
end
|
||
Mouse = _class_0
|
||
end
|
||
mp.add_key_binding("mouse_btn0", "left-click", function()
|
||
return Mouse:cacheClick()
|
||
end)
|
||
mp.observe_property('fullscreen', 'bool', function()
|
||
Mouse:update()
|
||
Mouse.dead = true
|
||
end)
|
||
mp.add_forced_key_binding("mouse_leave", "mouse-leave", function()
|
||
Mouse.inWindow = false
|
||
end)
|
||
mp.add_forced_key_binding("mouse_enter", "mouse-enter", function()
|
||
Mouse.inWindow = true
|
||
end)
|
||
local Rect
|
||
do
|
||
local _class_0
|
||
local _base_0 = {
|
||
cacheMaxBounds = function(self)
|
||
self.xMax = self.x + self.w
|
||
self.yMax = self.y + self.h
|
||
end,
|
||
setPosition = function(self, x, y)
|
||
self.x = x or self.x
|
||
self.y = y or self.y
|
||
return self:cacheMaxBounds()
|
||
end,
|
||
setSize = function(self, w, h)
|
||
self.w = w or self.w
|
||
self.h = h or self.h
|
||
return self:cacheMaxBounds()
|
||
end,
|
||
reset = function(self, x, y, w, h)
|
||
self.x = x or self.x
|
||
self.y = y or self.y
|
||
self.w = w or self.w
|
||
self.h = h or self.h
|
||
return self:cacheMaxBounds()
|
||
end,
|
||
move = function(self, x, y)
|
||
self.x = self.x + (x or self.x)
|
||
self.y = self.y + (y or self.y)
|
||
return self:cacheMaxBounds()
|
||
end,
|
||
stretch = function(self, w, h)
|
||
self.w = self.w + (w or self.w)
|
||
self.h = self.h + (h or self.h)
|
||
return self:cacheMaxBounds()
|
||
end,
|
||
containsPoint = function(self, x, y)
|
||
return (x >= self.x) and (x < self.xMax) and (y >= self.y) and (y < self.yMax)
|
||
end
|
||
}
|
||
_base_0.__index = _base_0
|
||
_class_0 = setmetatable({
|
||
__init = function(self, x, y, w, h)
|
||
if x == nil then
|
||
x = -1
|
||
end
|
||
if y == nil then
|
||
y = -1
|
||
end
|
||
if w == nil then
|
||
w = -1
|
||
end
|
||
if h == nil then
|
||
h = -1
|
||
end
|
||
self.x, self.y, self.w, self.h = x, y, w, h
|
||
return self:cacheMaxBounds()
|
||
end,
|
||
__base = _base_0,
|
||
__name = "Rect"
|
||
}, {
|
||
__index = _base_0,
|
||
__call = function(cls, ...)
|
||
local _self_0 = setmetatable({}, _base_0)
|
||
cls.__init(_self_0, ...)
|
||
return _self_0
|
||
end
|
||
})
|
||
_base_0.__class = _class_0
|
||
Rect = _class_0
|
||
end
|
||
local ActivityZone
|
||
do
|
||
local _class_0
|
||
local _parent_0 = Rect
|
||
local _base_0 = {
|
||
reconfigure = function(self)
|
||
self.active = false
|
||
end,
|
||
addUIElement = function(self, element)
|
||
self.elements:insert(element)
|
||
return element:activate(self.active)
|
||
end,
|
||
removeUIElement = function(self, element)
|
||
return self.elements:remove(element)
|
||
end,
|
||
clickHandler = function(self)
|
||
if not (self:containsPoint(Mouse.clickX, Mouse.clickY)) then
|
||
return
|
||
end
|
||
for _, element in ipairs(self.elements) do
|
||
if element.clickHandler and not element:clickHandler() then
|
||
break
|
||
end
|
||
end
|
||
end,
|
||
activityCheck = function(self, displayRequested)
|
||
if displayRequested == true then
|
||
return true
|
||
end
|
||
if not (Mouse.inWindow) then
|
||
return false
|
||
end
|
||
if Mouse.dead then
|
||
return false
|
||
end
|
||
return self:containsPoint(Mouse.x, Mouse.y)
|
||
end,
|
||
update = function(self, displayRequested, clickPending)
|
||
local nowActive = self:activityCheck(displayRequested)
|
||
if self.active ~= nowActive then
|
||
self.active = nowActive
|
||
for id, element in ipairs(self.elements) do
|
||
element:activate(nowActive)
|
||
end
|
||
end
|
||
if clickPending then
|
||
self:clickHandler()
|
||
end
|
||
return nowActive
|
||
end
|
||
}
|
||
_base_0.__index = _base_0
|
||
setmetatable(_base_0, _parent_0.__base)
|
||
_class_0 = setmetatable({
|
||
__init = function(self, resize, activityCheck)
|
||
self.resize, self.activityCheck = resize, activityCheck
|
||
_class_0.__parent.__init(self)
|
||
self.active = false
|
||
self.elements = Stack()
|
||
end,
|
||
__base = _base_0,
|
||
__name = "ActivityZone",
|
||
__parent = _parent_0
|
||
}, {
|
||
__index = function(cls, name)
|
||
local val = rawget(_base_0, name)
|
||
if val == nil then
|
||
local parent = rawget(cls, "__parent")
|
||
if parent then
|
||
return parent[name]
|
||
end
|
||
else
|
||
return val
|
||
end
|
||
end,
|
||
__call = function(cls, ...)
|
||
local _self_0 = setmetatable({}, _base_0)
|
||
cls.__init(_self_0, ...)
|
||
return _self_0
|
||
end
|
||
})
|
||
_base_0.__class = _class_0
|
||
if _parent_0.__inherited then
|
||
_parent_0.__inherited(_parent_0, _class_0)
|
||
end
|
||
ActivityZone = _class_0
|
||
end
|
||
local AnimationQueue
|
||
do
|
||
local _class_0
|
||
local animationList, deletionQueue
|
||
local _base_0 = { }
|
||
_base_0.__index = _base_0
|
||
_class_0 = setmetatable({
|
||
__init = function() end,
|
||
__base = _base_0,
|
||
__name = "AnimationQueue"
|
||
}, {
|
||
__index = _base_0,
|
||
__call = function(cls, ...)
|
||
local _self_0 = setmetatable({}, _base_0)
|
||
cls.__init(_self_0, ...)
|
||
return _self_0
|
||
end
|
||
})
|
||
_base_0.__class = _class_0
|
||
local self = _class_0
|
||
animationList = Stack('active')
|
||
deletionQueue = { }
|
||
self.addAnimation = function(animation)
|
||
if not (animation.active) then
|
||
return animationList:insert(animation)
|
||
end
|
||
end
|
||
self.removeAnimation = function(animation)
|
||
if animation.active then
|
||
return animationList:remove(animation)
|
||
end
|
||
end
|
||
self.destroyAnimationStack = function()
|
||
return animationList:clear()
|
||
end
|
||
self.animate = function()
|
||
if #animationList == 0 then
|
||
return
|
||
end
|
||
local currentTime = mp.get_time()
|
||
for _, animation in ipairs(animationList) do
|
||
if animation:update(currentTime) then
|
||
table.insert(deletionQueue, animation)
|
||
end
|
||
end
|
||
if #deletionQueue > 0 then
|
||
return animationList:removeSortedList(deletionQueue)
|
||
end
|
||
end
|
||
self.active = function()
|
||
return #animationList > 0
|
||
end
|
||
AnimationQueue = _class_0
|
||
end
|
||
local EventLoop
|
||
do
|
||
local _class_0
|
||
local _base_0 = {
|
||
reconfigure = function(self)
|
||
settings:_reload()
|
||
AnimationQueue.destroyAnimationStack()
|
||
for _, zone in ipairs(self.activityZones) do
|
||
zone:reconfigure()
|
||
end
|
||
for _, element in ipairs(self.uiElements) do
|
||
element:reconfigure()
|
||
end
|
||
end,
|
||
addZone = function(self, zone)
|
||
if zone == nil then
|
||
return
|
||
end
|
||
return self.activityZones:insert(zone)
|
||
end,
|
||
removeZone = function(self, zone)
|
||
if zone == nil then
|
||
return
|
||
end
|
||
return self.activityZones:remove(zone)
|
||
end,
|
||
generateUIFromZones = function(self)
|
||
local seenUIElements = { }
|
||
self.script = { }
|
||
self.uiElements:clear()
|
||
AnimationQueue.destroyAnimationStack()
|
||
for _, zone in ipairs(self.activityZones) do
|
||
for _, uiElement in ipairs(zone.elements) do
|
||
if not (seenUIElements[uiElement]) then
|
||
self:addUIElement(uiElement)
|
||
seenUIElements[uiElement] = true
|
||
end
|
||
end
|
||
end
|
||
return self.updateTimer:resume()
|
||
end,
|
||
addUIElement = function(self, uiElement)
|
||
if uiElement == nil then
|
||
error('nil UIElement added.')
|
||
end
|
||
self.uiElements:insert(uiElement)
|
||
return table.insert(self.script, '')
|
||
end,
|
||
removeUIElement = function(self, uiElement)
|
||
if uiElement == nil then
|
||
error('nil UIElement removed.')
|
||
end
|
||
table.remove(self.script, uiElement[self.uiElements])
|
||
self.uiElements:remove(uiElement)
|
||
self.needsRedraw = true
|
||
end,
|
||
resize = function(self)
|
||
for _, zone in ipairs(self.activityZones) do
|
||
zone:resize()
|
||
end
|
||
for _, uiElement in ipairs(self.uiElements) do
|
||
uiElement:resize()
|
||
end
|
||
end,
|
||
redraw = function(self, forceRedraw)
|
||
local clickPending = Mouse:update()
|
||
if Window:update() then
|
||
self:resize()
|
||
end
|
||
for index, zone in ipairs(self.activityZones) do
|
||
zone:update(self.displayRequested, clickPending)
|
||
end
|
||
AnimationQueue.animate()
|
||
for index, uiElement in ipairs(self.uiElements) do
|
||
if uiElement:redraw() then
|
||
self.script[index] = uiElement:stringify()
|
||
self.needsRedraw = true
|
||
end
|
||
end
|
||
if self.needsRedraw then
|
||
mp.set_osd_ass(Window.w, Window.h, table.concat(self.script, '\n'))
|
||
self.needsRedraw = false
|
||
end
|
||
end
|
||
}
|
||
_base_0.__index = _base_0
|
||
_class_0 = setmetatable({
|
||
__init = function(self)
|
||
self.script = { }
|
||
self.uiElements = Stack()
|
||
self.activityZones = Stack()
|
||
self.displayRequested = false
|
||
self.needsRedraw = false
|
||
self.updateTimer = mp.add_periodic_timer(settings['redraw-period'], (function()
|
||
local _base_1 = self
|
||
local _fn_0 = _base_1.redraw
|
||
return function(...)
|
||
return _fn_0(_base_1, ...)
|
||
end
|
||
end)())
|
||
self.updateTimer:stop()
|
||
mp.register_event('shutdown', function()
|
||
return self.updateTimer:kill()
|
||
end)
|
||
local displayRequestTimer
|
||
local displayDuration = settings['request-display-duration']
|
||
mp.add_key_binding("tab", "request-display", function(event)
|
||
if event.event == "repeat" then
|
||
return
|
||
end
|
||
if event.event == "down" or event.event == "press" then
|
||
if displayRequestTimer then
|
||
displayRequestTimer:kill()
|
||
end
|
||
self.displayRequested = true
|
||
end
|
||
if event.event == "up" or event.event == "press" then
|
||
if displayDuration == 0 then
|
||
self.displayRequested = false
|
||
else
|
||
displayRequestTimer = mp.add_timeout(displayDuration, function()
|
||
self.displayRequested = false
|
||
end)
|
||
end
|
||
end
|
||
end, {
|
||
complex = true
|
||
})
|
||
return mp.add_key_binding('ctrl+r', 'reconfigure', (function()
|
||
local _base_1 = self
|
||
local _fn_0 = _base_1.reconfigure
|
||
return function(...)
|
||
return _fn_0(_base_1, ...)
|
||
end
|
||
end)(), {
|
||
repeatable = false
|
||
})
|
||
end,
|
||
__base = _base_0,
|
||
__name = "EventLoop"
|
||
}, {
|
||
__index = _base_0,
|
||
__call = function(cls, ...)
|
||
local _self_0 = setmetatable({}, _base_0)
|
||
cls.__init(_self_0, ...)
|
||
return _self_0
|
||
end
|
||
})
|
||
_base_0.__class = _class_0
|
||
EventLoop = _class_0
|
||
end
|
||
local Animation
|
||
do
|
||
local _class_0
|
||
local _base_0 = {
|
||
update = function(self, now)
|
||
if self.isReversed then
|
||
self.linearProgress = math.max(0, math.min(1, self.linearProgress + (self.lastUpdate - now) * self.durationR))
|
||
if self.linearProgress == 0 then
|
||
self.isFinished = true
|
||
end
|
||
else
|
||
self.linearProgress = math.max(0, math.min(1, self.linearProgress + (now - self.lastUpdate) * self.durationR))
|
||
if self.linearProgress == 1 then
|
||
self.isFinished = true
|
||
end
|
||
end
|
||
self.lastUpdate = now
|
||
local progress = math.pow(self.linearProgress, self.accel)
|
||
self.value = (1 - progress) * self.initialValue + progress * self.endValue
|
||
self.updateCb(self.value)
|
||
if self.isFinished and self.finishedCb then
|
||
self:finishedCb()
|
||
end
|
||
return self.isFinished
|
||
end,
|
||
interrupt = function(self, reverse)
|
||
self.finishedCb = nil
|
||
self.lastUpdate = mp.get_time()
|
||
self.isReversed = reverse
|
||
if not (self.active) then
|
||
self.isFinished = false
|
||
return AnimationQueue.addAnimation(self)
|
||
end
|
||
end
|
||
}
|
||
_base_0.__index = _base_0
|
||
_class_0 = setmetatable({
|
||
__init = function(self, initialValue, endValue, duration, updateCb, finishedCb, accel)
|
||
if accel == nil then
|
||
accel = 1
|
||
end
|
||
self.initialValue, self.endValue, self.duration, self.updateCb, self.finishedCb, self.accel = initialValue, endValue, duration, updateCb, finishedCb, accel
|
||
self.value = self.initialValue
|
||
self.linearProgress = 0
|
||
self.lastUpdate = mp.get_time()
|
||
self.durationR = 1 / self.duration
|
||
self.isFinished = (self.duration <= 0)
|
||
self.active = false
|
||
self.isReversed = false
|
||
end,
|
||
__base = _base_0,
|
||
__name = "Animation"
|
||
}, {
|
||
__index = _base_0,
|
||
__call = function(cls, ...)
|
||
local _self_0 = setmetatable({}, _base_0)
|
||
cls.__init(_self_0, ...)
|
||
return _self_0
|
||
end
|
||
})
|
||
_base_0.__class = _class_0
|
||
Animation = _class_0
|
||
end
|
||
local UIElement
|
||
do
|
||
local _class_0
|
||
local _base_0 = {
|
||
stringify = function(self)
|
||
self.needsUpdate = false
|
||
if not self.active then
|
||
return ''
|
||
else
|
||
return table.concat(self.line)
|
||
end
|
||
end,
|
||
activate = function(self, activate)
|
||
if activate == true then
|
||
self.animation:interrupt(false)
|
||
self.active = true
|
||
else
|
||
self.animation:interrupt(true)
|
||
self.animation.finishedCb = function()
|
||
self.active = false
|
||
end
|
||
end
|
||
end,
|
||
reconfigure = function(self)
|
||
self.needsUpdate = true
|
||
self.animationDuration = settings['animation-duration']
|
||
end,
|
||
resize = function(self)
|
||
return error('UIElement updateSize called')
|
||
end,
|
||
redraw = function(self)
|
||
return self.needsUpdate
|
||
end
|
||
}
|
||
_base_0.__index = _base_0
|
||
_class_0 = setmetatable({
|
||
__init = function(self)
|
||
self.needsUpdate = false
|
||
self.active = false
|
||
self.animationDuration = settings['animation-duration']
|
||
end,
|
||
__base = _base_0,
|
||
__name = "UIElement"
|
||
}, {
|
||
__index = _base_0,
|
||
__call = function(cls, ...)
|
||
local _self_0 = setmetatable({}, _base_0)
|
||
cls.__init(_self_0, ...)
|
||
return _self_0
|
||
end
|
||
})
|
||
_base_0.__class = _class_0
|
||
UIElement = _class_0
|
||
end
|
||
local BarAccent
|
||
do
|
||
local _class_0
|
||
local barSize
|
||
local _parent_0 = UIElement
|
||
local _base_0 = {
|
||
reconfigure = function(self)
|
||
_class_0.__parent.__base.reconfigure(self)
|
||
barSize = settings['bar-height-active']
|
||
end,
|
||
resize = function(self)
|
||
self.yPos = Window.h - barSize
|
||
self.needsUpdate = true
|
||
end,
|
||
redraw = function(self)
|
||
if self.barSize ~= barSize then
|
||
self.barSize = barSize
|
||
return self:resize()
|
||
end
|
||
end
|
||
}
|
||
_base_0.__index = _base_0
|
||
setmetatable(_base_0, _parent_0.__base)
|
||
_class_0 = setmetatable({
|
||
__init = function(self)
|
||
_class_0.__parent.__init(self)
|
||
self.yPos = Window.h - barSize
|
||
end,
|
||
__base = _base_0,
|
||
__name = "BarAccent",
|
||
__parent = _parent_0
|
||
}, {
|
||
__index = function(cls, name)
|
||
local val = rawget(_base_0, name)
|
||
if val == nil then
|
||
local parent = rawget(cls, "__parent")
|
||
if parent then
|
||
return parent[name]
|
||
end
|
||
else
|
||
return val
|
||
end
|
||
end,
|
||
__call = function(cls, ...)
|
||
local _self_0 = setmetatable({}, _base_0)
|
||
cls.__init(_self_0, ...)
|
||
return _self_0
|
||
end
|
||
})
|
||
_base_0.__class = _class_0
|
||
local self = _class_0
|
||
barSize = settings['bar-height-active']
|
||
self.changeBarSize = function(size)
|
||
barSize = size
|
||
end
|
||
if _parent_0.__inherited then
|
||
_parent_0.__inherited(_parent_0, _class_0)
|
||
end
|
||
BarAccent = _class_0
|
||
end
|
||
local BarBase
|
||
do
|
||
local _class_0
|
||
local hideInactive, lineBaseTemplate
|
||
local _parent_0 = UIElement
|
||
local _base_0 = {
|
||
_updateBarVisibility = function(self)
|
||
if hideInactive then
|
||
self.animationMinHeight = 0
|
||
else
|
||
self.animationMinHeight = self.minHeight
|
||
end
|
||
end,
|
||
reconfigure = function(self, prefix)
|
||
if prefix == nil then
|
||
prefix = 'bar-'
|
||
end
|
||
_class_0.__parent.__base.reconfigure(self)
|
||
self.minHeight = settings[prefix .. 'height-inactive'] * 100
|
||
self.maxHeight = settings[prefix .. 'height-active'] * 100
|
||
hideInactive = settings['bar-hide-inactive']
|
||
self:_updateBarVisibility()
|
||
self.line[4] = self.minHeight
|
||
self.line[8] = lineBaseTemplate:format(settings['default-style'], settings['bar-default-style'], '%s')
|
||
self.animation = Animation(0, 1, self.animationDuration, (function()
|
||
local _base_1 = self
|
||
local _fn_0 = _base_1.animate
|
||
return function(...)
|
||
return _fn_0(_base_1, ...)
|
||
end
|
||
end)())
|
||
end,
|
||
stringify = function(self)
|
||
self.needsUpdate = false
|
||
if hideInactive and not self.active then
|
||
return ""
|
||
else
|
||
return table.concat(self.line)
|
||
end
|
||
end,
|
||
resize = function(self)
|
||
self.line[2] = ([[%d,%d]]):format(0, Window.h)
|
||
self.line[9] = ([[m 0 0 l %d 0 %d 1 0 1]]):format(Window.w, Window.w)
|
||
self.needsUpdate = true
|
||
end,
|
||
animate = function(self, value)
|
||
self.line[4] = ([[%g]]):format((self.maxHeight - self.animationMinHeight) * value + self.animationMinHeight)
|
||
self.needsUpdate = true
|
||
end,
|
||
redraw = function(self)
|
||
if self.hideInactive ~= hideInactive then
|
||
self.hideInactive = hideInactive
|
||
if not (self.active) then
|
||
self:animate(0)
|
||
end
|
||
end
|
||
return self.needsUpdate
|
||
end
|
||
}
|
||
_base_0.__index = _base_0
|
||
setmetatable(_base_0, _parent_0.__base)
|
||
_class_0 = setmetatable({
|
||
__init = function(self)
|
||
self.minHeight = settings['bar-height-inactive'] * 100
|
||
self.animationMinHeight = minHeight
|
||
self.maxHeight = settings['bar-height-active'] * 100
|
||
self.line = {
|
||
[[{\pos(]],
|
||
0,
|
||
[[)\fscy]],
|
||
minHeight,
|
||
[[\fscx]],
|
||
0.001,
|
||
[[]],
|
||
lineBaseTemplate,
|
||
0
|
||
}
|
||
_class_0.__parent.__init(self)
|
||
table.insert(self.__class.instantiatedBars, self)
|
||
return self:reconfigure()
|
||
end,
|
||
__base = _base_0,
|
||
__name = "BarBase",
|
||
__parent = _parent_0
|
||
}, {
|
||
__index = function(cls, name)
|
||
local val = rawget(_base_0, name)
|
||
if val == nil then
|
||
local parent = rawget(cls, "__parent")
|
||
if parent then
|
||
return parent[name]
|
||
end
|
||
else
|
||
return val
|
||
end
|
||
end,
|
||
__call = function(cls, ...)
|
||
local _self_0 = setmetatable({}, _base_0)
|
||
cls.__init(_self_0, ...)
|
||
return _self_0
|
||
end
|
||
})
|
||
_base_0.__class = _class_0
|
||
local self = _class_0
|
||
hideInactive = settings['bar-hide-inactive']
|
||
self.instantiatedBars = { }
|
||
self.toggleInactiveVisibility = function(self)
|
||
hideInactive = not hideInactive
|
||
local _list_0 = self.instantiatedBars
|
||
for _index_0 = 1, #_list_0 do
|
||
local bar = _list_0[_index_0]
|
||
bar:_updateBarVisibility()
|
||
end
|
||
end
|
||
lineBaseTemplate = [[\an1%s%s%s\p1}]]
|
||
if _parent_0.__inherited then
|
||
_parent_0.__inherited(_parent_0, _class_0)
|
||
end
|
||
BarBase = _class_0
|
||
end
|
||
local ProgressBar
|
||
do
|
||
local _class_0
|
||
local seekString
|
||
local _parent_0 = BarBase
|
||
local _base_0 = {
|
||
reconfigure = function(self)
|
||
_class_0.__parent.__base.reconfigure(self)
|
||
seekString = ('absolute-percent+%s'):format(settings['seek-precision'])
|
||
self.barShift = settings['progress-bar-width'] / 2.0
|
||
self:resize()
|
||
self.line[7] = [[]]
|
||
self.line[8] = self.line[8]:format(settings['bar-foreground-style'])
|
||
end,
|
||
clickHandler = function(self)
|
||
return mp.commandv("seek", Mouse.clickX * 100 / Window.w, seekString)
|
||
end,
|
||
resize = function(self)
|
||
_class_0.__parent.__base.resize(self)
|
||
if self.barShift > 0 then
|
||
self.line[2] = ('%g,%g'):format(self.barShift, Window.h)
|
||
end
|
||
end,
|
||
redraw = function(self)
|
||
_class_0.__parent.__base.redraw(self)
|
||
if self.hideInactive and not self.active then
|
||
return self.needsUpdate
|
||
end
|
||
local position = mp.get_property_number('percent-pos', 0)
|
||
if position ~= self.lastPosition or self.needsUpdate then
|
||
self.line[6] = position
|
||
if self.barShift > 0 then
|
||
local followingEdge = Window.w * position * 1e-2 - self.barShift
|
||
self.line[7] = ([[\clip(m %g 0 l %g 0 %g %g %g %g)]]):format(followingEdge, Window.w, Window.w, Window.h, followingEdge, Window.h)
|
||
end
|
||
self.lastPosition = position
|
||
self.needsUpdate = true
|
||
end
|
||
return self.needsUpdate
|
||
end
|
||
}
|
||
_base_0.__index = _base_0
|
||
setmetatable(_base_0, _parent_0.__base)
|
||
_class_0 = setmetatable({
|
||
__init = function(self)
|
||
_class_0.__parent.__init(self)
|
||
self.lastPosition = 0
|
||
end,
|
||
__base = _base_0,
|
||
__name = "ProgressBar",
|
||
__parent = _parent_0
|
||
}, {
|
||
__index = function(cls, name)
|
||
local val = rawget(_base_0, name)
|
||
if val == nil then
|
||
local parent = rawget(cls, "__parent")
|
||
if parent then
|
||
return parent[name]
|
||
end
|
||
else
|
||
return val
|
||
end
|
||
end,
|
||
__call = function(cls, ...)
|
||
local _self_0 = setmetatable({}, _base_0)
|
||
cls.__init(_self_0, ...)
|
||
return _self_0
|
||
end
|
||
})
|
||
_base_0.__class = _class_0
|
||
local self = _class_0
|
||
seekString = ('absolute-percent+%s'):format(settings['seek-precision'])
|
||
if _parent_0.__inherited then
|
||
_parent_0.__inherited(_parent_0, _class_0)
|
||
end
|
||
ProgressBar = _class_0
|
||
end
|
||
local ProgressBarCache
|
||
do
|
||
local _class_0
|
||
local timestamp
|
||
local _parent_0 = BarBase
|
||
local _base_0 = {
|
||
reconfigure = function(self)
|
||
_class_0.__parent.__base.reconfigure(self, 'bar-cache-')
|
||
self.line[6] = 100
|
||
self.line[8] = self.line[8]:format(settings['bar-cache-style']) .. 'm 0 0'
|
||
self.line[10] = ([[{\p0%s\p1}]]):format(settings['bar-cache-background-style'])
|
||
self.line[11] = [[]]
|
||
self.fileDuration = mp.get_property_number('duration', nil)
|
||
end,
|
||
resize = function(self)
|
||
_class_0.__parent.__base.resize(self)
|
||
if self.fileDuration then
|
||
self.coordinateRemap = Window.w / self.fileDuration
|
||
end
|
||
self.line[9] = [[]]
|
||
end,
|
||
redraw = function(self)
|
||
_class_0.__parent.__base.redraw(self)
|
||
if self.hideInactive and not self.active then
|
||
return self.needsUpdate
|
||
end
|
||
if self.fileDuration and (self.fileDuration > 0) then
|
||
local barDrawing = {
|
||
past = { },
|
||
future = { }
|
||
}
|
||
local ranges
|
||
ranges = mp.get_property_native('demuxer-cache-state', { })['seekable-ranges']
|
||
if ranges and (#ranges > 0) then
|
||
local position = mp.get_property_number('percent-pos', 0)
|
||
local cacheKeyAggregator = {
|
||
Window.w,
|
||
position
|
||
}
|
||
for _index_0 = 1, #ranges do
|
||
local _des_0 = ranges[_index_0]
|
||
local rangeStart, rangeEnd
|
||
rangeStart, rangeEnd = _des_0.start, _des_0["end"]
|
||
table.insert(cacheKeyAggregator, rangeStart)
|
||
table.insert(cacheKeyAggregator, rangeEnd)
|
||
end
|
||
local cacheKey = table.concat(cacheKeyAggregator, '_')
|
||
if cacheKey == self.cacheKey then
|
||
return self.needsUpdate
|
||
end
|
||
local progressPosition = mp.get_property_number('percent-pos', 0) * Window.w * 0.01
|
||
for _index_0 = 1, #ranges do
|
||
local _des_0 = ranges[_index_0]
|
||
local rangeStart, rangeEnd
|
||
rangeStart, rangeEnd = _des_0.start, _des_0["end"]
|
||
rangeStart = rangeStart * self.coordinateRemap
|
||
rangeEnd = rangeEnd * self.coordinateRemap
|
||
if rangeEnd < progressPosition then
|
||
local rect = ('m %g 0 l %g 1 %g 1 %g 0'):format(rangeStart, rangeStart, rangeEnd, rangeEnd)
|
||
table.insert(barDrawing.past, rect)
|
||
elseif rangeStart > progressPosition then
|
||
rangeStart = rangeStart - progressPosition
|
||
rangeEnd = rangeEnd - progressPosition
|
||
local rect = ('m %g 0 l %g 1 %g 1 %g 0'):format(rangeStart, rangeStart, rangeEnd, rangeEnd)
|
||
table.insert(barDrawing.future, rect)
|
||
else
|
||
rangeEnd = rangeEnd - progressPosition
|
||
local rectPast = ('m %g 0 l %g 1 %g 1 %g 0'):format(rangeStart, rangeStart, progressPosition, progressPosition)
|
||
local rectFuture = ('m %g 0 l %g 1 %g 1 %g 0'):format(0, 0, rangeEnd, rangeEnd)
|
||
table.insert(barDrawing.past, rectPast)
|
||
table.insert(barDrawing.future, rectFuture)
|
||
end
|
||
end
|
||
self.line[9] = table.concat(barDrawing.past, ' ') .. ('m %g 0'):format(progressPosition)
|
||
self.line[11] = table.concat(barDrawing.future, ' ')
|
||
self.cacheKey = cacheKey
|
||
self.needsUpdate = true
|
||
end
|
||
end
|
||
return self.needsUpdate
|
||
end
|
||
}
|
||
_base_0.__index = _base_0
|
||
setmetatable(_base_0, _parent_0.__base)
|
||
_class_0 = setmetatable({
|
||
__init = function(self)
|
||
_class_0.__parent.__init(self)
|
||
self.cacheKey = nil
|
||
self.coordinateRemap = 0
|
||
return mp.observe_property('duration', 'number', function(name, value)
|
||
if value and (value > 0) then
|
||
self.fileDuration = value
|
||
self.coordinateRemap = Window.w / value
|
||
end
|
||
end)
|
||
end,
|
||
__base = _base_0,
|
||
__name = "ProgressBarCache",
|
||
__parent = _parent_0
|
||
}, {
|
||
__index = function(cls, name)
|
||
local val = rawget(_base_0, name)
|
||
if val == nil then
|
||
local parent = rawget(cls, "__parent")
|
||
if parent then
|
||
return parent[name]
|
||
end
|
||
else
|
||
return val
|
||
end
|
||
end,
|
||
__call = function(cls, ...)
|
||
local _self_0 = setmetatable({}, _base_0)
|
||
cls.__init(_self_0, ...)
|
||
return _self_0
|
||
end
|
||
})
|
||
_base_0.__class = _class_0
|
||
local self = _class_0
|
||
timestamp = os.time()
|
||
if _parent_0.__inherited then
|
||
_parent_0.__inherited(_parent_0, _class_0)
|
||
end
|
||
ProgressBarCache = _class_0
|
||
end
|
||
local ProgressBarBackground
|
||
do
|
||
local _class_0
|
||
local _parent_0 = BarBase
|
||
local _base_0 = {
|
||
reconfigure = function(self)
|
||
_class_0.__parent.__base.reconfigure(self)
|
||
if settings['bar-background-adaptive'] then
|
||
local _list_0 = self.__class.instantiatedBars
|
||
for _index_0 = 1, #_list_0 do
|
||
local bar = _list_0[_index_0]
|
||
self.minHeight = math.max(self.minHeight, bar.minHeight)
|
||
self.maxHeight = math.max(self.maxHeight, bar.maxHeight)
|
||
end
|
||
self:_updateBarVisibility()
|
||
end
|
||
self.line[6] = 100
|
||
self.line[8] = self.line[8]:format(settings['bar-background-style'])
|
||
end
|
||
}
|
||
_base_0.__index = _base_0
|
||
setmetatable(_base_0, _parent_0.__base)
|
||
_class_0 = setmetatable({
|
||
__init = function(self, ...)
|
||
return _class_0.__parent.__init(self, ...)
|
||
end,
|
||
__base = _base_0,
|
||
__name = "ProgressBarBackground",
|
||
__parent = _parent_0
|
||
}, {
|
||
__index = function(cls, name)
|
||
local val = rawget(_base_0, name)
|
||
if val == nil then
|
||
local parent = rawget(cls, "__parent")
|
||
if parent then
|
||
return parent[name]
|
||
end
|
||
else
|
||
return val
|
||
end
|
||
end,
|
||
__call = function(cls, ...)
|
||
local _self_0 = setmetatable({}, _base_0)
|
||
cls.__init(_self_0, ...)
|
||
return _self_0
|
||
end
|
||
})
|
||
_base_0.__class = _class_0
|
||
if _parent_0.__inherited then
|
||
_parent_0.__inherited(_parent_0, _class_0)
|
||
end
|
||
ProgressBarBackground = _class_0
|
||
end
|
||
local ChapterMarker
|
||
do
|
||
local _class_0
|
||
local beforeStyle, afterStyle
|
||
local _base_0 = {
|
||
stringify = function(self)
|
||
return table.concat(self.line)
|
||
end,
|
||
resize = function(self)
|
||
self.line[2] = ('%d,%d'):format(math.floor(self.position * Window.w), Window.h)
|
||
end,
|
||
animate = function(self, width, height)
|
||
self.line[4] = ('%g'):format(width)
|
||
self.line[6] = ('%g'):format(height)
|
||
end,
|
||
redraw = function(self, position, update)
|
||
if update == nil then
|
||
update = false
|
||
end
|
||
if not self.passed and (position > self.position) then
|
||
self.line[7] = afterStyle
|
||
self.passed = true
|
||
update = true
|
||
elseif self.passed and (position < self.position) then
|
||
self.line[7] = beforeStyle
|
||
self.passed = false
|
||
update = true
|
||
end
|
||
return update
|
||
end
|
||
}
|
||
_base_0.__index = _base_0
|
||
_class_0 = setmetatable({
|
||
__init = function(self, position, minWidth, minHeight)
|
||
self.position = position
|
||
self.line = {
|
||
[[{\an2\bord0\p1\pos(]],
|
||
([[%g,%g]]):format(self.position * Window.w, Window.h),
|
||
[[)\fscx]],
|
||
minWidth,
|
||
[[\fscy]],
|
||
minHeight,
|
||
beforeStyle,
|
||
'}m 0 0 l 1 0 1 1 0 1\n'
|
||
}
|
||
self.passed = false
|
||
end,
|
||
__base = _base_0,
|
||
__name = "ChapterMarker"
|
||
}, {
|
||
__index = _base_0,
|
||
__call = function(cls, ...)
|
||
local _self_0 = setmetatable({}, _base_0)
|
||
cls.__init(_self_0, ...)
|
||
return _self_0
|
||
end
|
||
})
|
||
_base_0.__class = _class_0
|
||
local self = _class_0
|
||
beforeStyle = settings['chapter-marker-before-style']
|
||
afterStyle = settings['chapter-marker-after-style']
|
||
self.reconfigure = function(self)
|
||
beforeStyle = settings['chapter-marker-before-style']
|
||
afterStyle = settings['chapter-marker-after-style']
|
||
end
|
||
ChapterMarker = _class_0
|
||
end
|
||
local Chapters
|
||
do
|
||
local _class_0
|
||
local minWidth, maxWidth, maxHeight, maxHeightFrac
|
||
local _parent_0 = BarBase
|
||
local _base_0 = {
|
||
createMarkers = function(self)
|
||
self.line = { }
|
||
self.markers = { }
|
||
local totalTime = mp.get_property_number('duration', 0.01)
|
||
local chapters = mp.get_property_native('chapter-list', { })
|
||
local markerHeight = self.active and maxHeight * maxHeightFrac or BarBase.instantiatedBars[1].animationMinHeight
|
||
local markerWidth = self.active and maxWidth or minWidth
|
||
for _index_0 = 1, #chapters do
|
||
local chapter = chapters[_index_0]
|
||
local marker = ChapterMarker(chapter.time / totalTime, markerWidth, markerHeight)
|
||
table.insert(self.markers, marker)
|
||
table.insert(self.line, marker:stringify())
|
||
end
|
||
self.needsUpdate = true
|
||
end,
|
||
reconfigure = function(self)
|
||
UIElement.reconfigure(self)
|
||
minWidth = settings['chapter-marker-width'] * 100
|
||
maxWidth = settings['chapter-marker-width-active'] * 100
|
||
maxHeight = settings['bar-height-active'] * 100
|
||
maxHeightFrac = settings['chapter-marker-active-height-fraction']
|
||
ChapterMarker:reconfigure()
|
||
self:createMarkers()
|
||
self.animation = Animation(0, 1, self.animationDuration, (function()
|
||
local _base_1 = self
|
||
local _fn_0 = _base_1.animate
|
||
return function(...)
|
||
return _fn_0(_base_1, ...)
|
||
end
|
||
end)())
|
||
end,
|
||
resize = function(self)
|
||
for i, marker in ipairs(self.markers) do
|
||
marker:resize()
|
||
self.line[i] = marker:stringify()
|
||
end
|
||
self.needsUpdate = true
|
||
end,
|
||
animate = function(self, value)
|
||
local width = (maxWidth - minWidth) * value + minWidth
|
||
local height = (maxHeight * maxHeightFrac - BarBase.instantiatedBars[1].animationMinHeight) * value + BarBase.instantiatedBars[1].animationMinHeight
|
||
for i, marker in ipairs(self.markers) do
|
||
marker:animate(width, height)
|
||
self.line[i] = marker:stringify()
|
||
end
|
||
self.needsUpdate = true
|
||
end,
|
||
redraw = function(self)
|
||
_class_0.__parent.__base.redraw(self)
|
||
local currentPosition = mp.get_property_number('percent-pos', 0) * 0.01
|
||
local update = false
|
||
for i, marker in ipairs(self.markers) do
|
||
if marker:redraw(currentPosition) then
|
||
self.line[i] = marker:stringify()
|
||
update = true
|
||
end
|
||
end
|
||
return self.needsUpdate or update
|
||
end
|
||
}
|
||
_base_0.__index = _base_0
|
||
setmetatable(_base_0, _parent_0.__base)
|
||
_class_0 = setmetatable({
|
||
__init = function(self)
|
||
_class_0.__parent.__init(self)
|
||
self.line = { }
|
||
self.markers = { }
|
||
self.animation = Animation(0, 1, self.animationDuration, (function()
|
||
local _base_1 = self
|
||
local _fn_0 = _base_1.animate
|
||
return function(...)
|
||
return _fn_0(_base_1, ...)
|
||
end
|
||
end)())
|
||
end,
|
||
__base = _base_0,
|
||
__name = "Chapters",
|
||
__parent = _parent_0
|
||
}, {
|
||
__index = function(cls, name)
|
||
local val = rawget(_base_0, name)
|
||
if val == nil then
|
||
local parent = rawget(cls, "__parent")
|
||
if parent then
|
||
return parent[name]
|
||
end
|
||
else
|
||
return val
|
||
end
|
||
end,
|
||
__call = function(cls, ...)
|
||
local _self_0 = setmetatable({}, _base_0)
|
||
cls.__init(_self_0, ...)
|
||
return _self_0
|
||
end
|
||
})
|
||
_base_0.__class = _class_0
|
||
local self = _class_0
|
||
minWidth = settings['chapter-marker-width'] * 100
|
||
maxWidth = settings['chapter-marker-width-active'] * 100
|
||
maxHeight = settings['bar-height-active'] * 100
|
||
maxHeightFrac = settings['chapter-marker-active-height-fraction']
|
||
if _parent_0.__inherited then
|
||
_parent_0.__inherited(_parent_0, _class_0)
|
||
end
|
||
Chapters = _class_0
|
||
end
|
||
local TimeElapsed
|
||
do
|
||
local _class_0
|
||
local bottomMargin
|
||
local _parent_0 = BarAccent
|
||
local _base_0 = {
|
||
reconfigure = function(self)
|
||
_class_0.__parent.__base.reconfigure(self)
|
||
bottomMargin = settings['elapsed-bottom-margin']
|
||
local offscreenPos = settings['elapsed-offscreen-pos']
|
||
self.line[2] = ('%g,%g'):format(self.position, self.yPos - bottomMargin)
|
||
self.line[3] = ([[)\an1%s%s}]]):format(settings['default-style'], settings['elapsed-style'])
|
||
self.animation = Animation(offscreenPos, settings['elapsed-left-margin'], self.animationDuration, (function()
|
||
local _base_1 = self
|
||
local _fn_0 = _base_1.animate
|
||
return function(...)
|
||
return _fn_0(_base_1, ...)
|
||
end
|
||
end)(), nil, 0.5)
|
||
end,
|
||
resize = function(self)
|
||
_class_0.__parent.__base.resize(self)
|
||
self.line[2] = ('%g,%g'):format(self.position, self.yPos - bottomMargin)
|
||
end,
|
||
animate = function(self, value)
|
||
self.position = value
|
||
self.line[2] = ('%g,%g'):format(value, self.yPos - bottomMargin)
|
||
self.needsUpdate = true
|
||
end,
|
||
redraw = function(self)
|
||
if self.active then
|
||
_class_0.__parent.__base.redraw(self)
|
||
local timeElapsed = math.floor(mp.get_property_number('time-pos', 0))
|
||
if timeElapsed ~= self.lastTime then
|
||
local update = true
|
||
self.line[4] = ('%d:%02d:%02d'):format(math.floor(timeElapsed / 3600), math.floor((timeElapsed / 60) % 60), math.floor(timeElapsed % 60))
|
||
self.lastTime = timeElapsed
|
||
self.needsUpdate = true
|
||
end
|
||
end
|
||
return self.needsUpdate
|
||
end
|
||
}
|
||
_base_0.__index = _base_0
|
||
setmetatable(_base_0, _parent_0.__base)
|
||
_class_0 = setmetatable({
|
||
__init = function(self)
|
||
_class_0.__parent.__init(self)
|
||
local offscreenPos = settings['elapsed-offscreen-pos']
|
||
self.line = {
|
||
[[{\pos(]],
|
||
([[%g,0]]):format(offscreenPos),
|
||
([[)\an1%s%s}]]):format(settings['default-style'], settings['elapsed-style']),
|
||
[[????]]
|
||
}
|
||
self.lastTime = -1
|
||
self.position = offscreenPos
|
||
self.animation = Animation(offscreenPos, settings['elapsed-left-margin'], self.animationDuration, (function()
|
||
local _base_1 = self
|
||
local _fn_0 = _base_1.animate
|
||
return function(...)
|
||
return _fn_0(_base_1, ...)
|
||
end
|
||
end)(), nil, 0.5)
|
||
end,
|
||
__base = _base_0,
|
||
__name = "TimeElapsed",
|
||
__parent = _parent_0
|
||
}, {
|
||
__index = function(cls, name)
|
||
local val = rawget(_base_0, name)
|
||
if val == nil then
|
||
local parent = rawget(cls, "__parent")
|
||
if parent then
|
||
return parent[name]
|
||
end
|
||
else
|
||
return val
|
||
end
|
||
end,
|
||
__call = function(cls, ...)
|
||
local _self_0 = setmetatable({}, _base_0)
|
||
cls.__init(_self_0, ...)
|
||
return _self_0
|
||
end
|
||
})
|
||
_base_0.__class = _class_0
|
||
local self = _class_0
|
||
bottomMargin = settings['elapsed-bottom-margin']
|
||
if _parent_0.__inherited then
|
||
_parent_0.__inherited(_parent_0, _class_0)
|
||
end
|
||
TimeElapsed = _class_0
|
||
end
|
||
local TimeRemaining
|
||
do
|
||
local _class_0
|
||
local bottomMargin
|
||
local _parent_0 = BarAccent
|
||
local _base_0 = {
|
||
reconfigure = function(self)
|
||
_class_0.__parent.__base.reconfigure(self)
|
||
bottomMargin = settings['remaining-bottom-margin']
|
||
local offscreenPos = settings['remaining-offscreen-pos']
|
||
self.line[2] = ('%g,%g'):format(self.position, self.yPos - bottomMargin)
|
||
self.line[3] = ([[)\an3%s%s}]]):format(settings['default-style'], settings['remaining-style'])
|
||
self.animation = Animation(offscreenPos, settings['remaining-right-margin'], self.animationDuration, (function()
|
||
local _base_1 = self
|
||
local _fn_0 = _base_1.animate
|
||
return function(...)
|
||
return _fn_0(_base_1, ...)
|
||
end
|
||
end)(), nil, 0.5)
|
||
end,
|
||
resize = function(self)
|
||
_class_0.__parent.__base.resize(self)
|
||
self.position = Window.w - self.animation.value
|
||
self.line[2] = ('%g,%g'):format(self.position, self.yPos - bottomMargin)
|
||
end,
|
||
animate = function(self, value)
|
||
self.position = Window.w - value
|
||
self.line[2] = ('%g,%g'):format(self.position, self.yPos - bottomMargin)
|
||
self.needsUpdate = true
|
||
end,
|
||
redraw = function(self)
|
||
if self.active then
|
||
_class_0.__parent.__base.redraw(self)
|
||
local timeRemaining = math.floor(mp.get_property_number('playtime-remaining', 0))
|
||
if timeRemaining ~= self.lastTime then
|
||
local update = true
|
||
self.line[4] = ('–%d:%02d:%02d'):format(math.floor(timeRemaining / 3600), math.floor((timeRemaining / 60) % 60), math.floor(timeRemaining % 60))
|
||
self.lastTime = timeRemaining
|
||
self.needsUpdate = true
|
||
end
|
||
end
|
||
return self.needsUpdate
|
||
end
|
||
}
|
||
_base_0.__index = _base_0
|
||
setmetatable(_base_0, _parent_0.__base)
|
||
_class_0 = setmetatable({
|
||
__init = function(self)
|
||
_class_0.__parent.__init(self)
|
||
local offscreenPos = settings['remaining-offscreen-pos']
|
||
self.line = {
|
||
[[{\pos(]],
|
||
([[%g,0]]):format(offscreenPos),
|
||
([[)\an3%s%s}]]):format(settings['default-style'], settings['remaining-style']),
|
||
[[????]]
|
||
}
|
||
self.lastTime = -1
|
||
self.position = offscreenPos
|
||
self.animation = Animation(offscreenPos, settings['remaining-right-margin'], self.animationDuration, (function()
|
||
local _base_1 = self
|
||
local _fn_0 = _base_1.animate
|
||
return function(...)
|
||
return _fn_0(_base_1, ...)
|
||
end
|
||
end)(), nil, 0.5)
|
||
end,
|
||
__base = _base_0,
|
||
__name = "TimeRemaining",
|
||
__parent = _parent_0
|
||
}, {
|
||
__index = function(cls, name)
|
||
local val = rawget(_base_0, name)
|
||
if val == nil then
|
||
local parent = rawget(cls, "__parent")
|
||
if parent then
|
||
return parent[name]
|
||
end
|
||
else
|
||
return val
|
||
end
|
||
end,
|
||
__call = function(cls, ...)
|
||
local _self_0 = setmetatable({}, _base_0)
|
||
cls.__init(_self_0, ...)
|
||
return _self_0
|
||
end
|
||
})
|
||
_base_0.__class = _class_0
|
||
local self = _class_0
|
||
bottomMargin = settings['remaining-bottom-margin']
|
||
if _parent_0.__inherited then
|
||
_parent_0.__inherited(_parent_0, _class_0)
|
||
end
|
||
TimeRemaining = _class_0
|
||
end
|
||
local HoverTime
|
||
do
|
||
local _class_0
|
||
local rightMargin, leftMargin, bottomMargin, offScreenPos
|
||
local _parent_0 = BarAccent
|
||
local _base_0 = {
|
||
reconfigure = function(self)
|
||
_class_0.__parent.__base.reconfigure(self)
|
||
rightMargin = settings['hover-time-right-margin']
|
||
leftMargin = settings['hover-time-left-margin']
|
||
bottomMargin = settings['hover-time-bottom-margin']
|
||
offScreenPos = settings['hover-time-offscreen-pos']
|
||
self.line[2] = ('%g,%g'):format(math.min(Window.w - rightMargin, math.max(leftMargin, Mouse.x)), self.position)
|
||
self.line[1] = ([[{%s%s\pos(]]):format(settings['default-style'], settings['hover-time-style'])
|
||
self.animation = Animation(offScreenPos, bottomMargin, self.animationDuration, (function()
|
||
local _base_1 = self
|
||
local _fn_0 = _base_1.animate
|
||
return function(...)
|
||
return _fn_0(_base_1, ...)
|
||
end
|
||
end)(), nil, 0.5)
|
||
end,
|
||
resize = function(self)
|
||
_class_0.__parent.__base.resize(self)
|
||
self.line[2] = ("%g,%g"):format(math.min(Window.w - rightMargin, math.max(leftMargin, Mouse.x)), self.yPos - self.animation.value)
|
||
end,
|
||
animate = function(self, value)
|
||
self.position = self.yPos - value
|
||
self.line[2] = ("%g,%g"):format(math.min(Window.w - rightMargin, math.max(leftMargin, Mouse.x)), self.position)
|
||
self.needsUpdate = true
|
||
end,
|
||
redraw = function(self)
|
||
if self.active then
|
||
_class_0.__parent.__base.redraw(self)
|
||
if Mouse.x ~= self.lastX then
|
||
self.line[2] = ("%g,%g"):format(math.min(Window.w - rightMargin, math.max(leftMargin, Mouse.x)), self.position)
|
||
self.lastX = Mouse.x
|
||
local hoverTime = mp.get_property_number('duration', 0) * Mouse.x / Window.w
|
||
if hoverTime ~= self.lastTime then
|
||
self.line[4] = ([[%d:%02d:%02d]]):format(math.floor(hoverTime / 3600), math.floor((hoverTime / 60) % 60), math.floor(hoverTime % 60))
|
||
self.lastTime = hoverTime
|
||
end
|
||
self.needsUpdate = true
|
||
end
|
||
end
|
||
return self.needsUpdate
|
||
end
|
||
}
|
||
_base_0.__index = _base_0
|
||
setmetatable(_base_0, _parent_0.__base)
|
||
_class_0 = setmetatable({
|
||
__init = function(self)
|
||
_class_0.__parent.__init(self)
|
||
self.line = {
|
||
([[{%s%s\pos(]]):format(settings['default-style'], settings['hover-time-style']),
|
||
[[-100,0]],
|
||
[[)\an2}]],
|
||
[[????]]
|
||
}
|
||
self.lastTime = 0
|
||
self.lastX = -1
|
||
self.position = offScreenPos
|
||
self.animation = Animation(offScreenPos, bottomMargin, self.animationDuration, (function()
|
||
local _base_1 = self
|
||
local _fn_0 = _base_1.animate
|
||
return function(...)
|
||
return _fn_0(_base_1, ...)
|
||
end
|
||
end)(), nil, 0.5)
|
||
end,
|
||
__base = _base_0,
|
||
__name = "HoverTime",
|
||
__parent = _parent_0
|
||
}, {
|
||
__index = function(cls, name)
|
||
local val = rawget(_base_0, name)
|
||
if val == nil then
|
||
local parent = rawget(cls, "__parent")
|
||
if parent then
|
||
return parent[name]
|
||
end
|
||
else
|
||
return val
|
||
end
|
||
end,
|
||
__call = function(cls, ...)
|
||
local _self_0 = setmetatable({}, _base_0)
|
||
cls.__init(_self_0, ...)
|
||
return _self_0
|
||
end
|
||
})
|
||
_base_0.__class = _class_0
|
||
local self = _class_0
|
||
rightMargin = settings['hover-time-right-margin']
|
||
leftMargin = settings['hover-time-left-margin']
|
||
bottomMargin = settings['hover-time-bottom-margin']
|
||
offScreenPos = settings['hover-time-offscreen-pos']
|
||
if _parent_0.__inherited then
|
||
_parent_0.__inherited(_parent_0, _class_0)
|
||
end
|
||
HoverTime = _class_0
|
||
end
|
||
local PauseIndicator
|
||
do
|
||
local _class_0
|
||
local _base_0 = {
|
||
stringify = function(self)
|
||
return table.concat(self.line)
|
||
end,
|
||
resize = function(self)
|
||
local w, h = 0.5 * Window.w, 0.5 * Window.h
|
||
self.line[5] = ([[%g,%g]]):format(w, h)
|
||
self.line[12] = ([[%g,%g]]):format(w, h)
|
||
end,
|
||
redraw = function()
|
||
return true
|
||
end,
|
||
animate = function(self, value)
|
||
local scale = value * 50 + 100
|
||
local scaleStr = ([[{\fscx%g\fscy%g]]):format(scale, scale)
|
||
local alphaStr = ('%02X'):format(value * value * 255)
|
||
self.line[1] = scaleStr
|
||
self.line[8] = scaleStr
|
||
self.line[3] = alphaStr
|
||
self.line[10] = alphaStr
|
||
end,
|
||
destroy = function(self, animation)
|
||
return self.eventLoop:removeUIElement(self)
|
||
end
|
||
}
|
||
_base_0.__index = _base_0
|
||
_class_0 = setmetatable({
|
||
__init = function(self, eventLoop, paused)
|
||
self.eventLoop = eventLoop
|
||
local w, h = 0.5 * Window.w, 0.5 * Window.h
|
||
self.line = {
|
||
[[{\fscx0\fscy0]],
|
||
[[\alpha&H]],
|
||
0,
|
||
[[&\pos(]],
|
||
([[%g,%g]]):format(w, h),
|
||
([[)\an5\bord0%s\p1}]]):format(settings['pause-indicator-background-style']),
|
||
0,
|
||
[[{\fscx0\fscy0]],
|
||
[[\alpha&H]],
|
||
0,
|
||
[[&\pos(]],
|
||
([[%g,%g]]):format(w, h),
|
||
([[)\an5\bord0%s\p1}]]):format(settings['pause-indicator-foreground-style']),
|
||
0
|
||
}
|
||
if paused then
|
||
self.line[7] = 'm 75 37.5 b 75 58.21 58.21 75 37.5 75 16.79 75 0 58.21 0 37.5 0 16.79 16.79 0 37.5 0 58.21 0 75 16.79 75 37.5 m 23 20 l 23 55 33 55 33 20 m 42 20 l 42 55 52 55 52 20\n'
|
||
self.line[14] = 'm 0 0 m 75 75 m 23 20 l 23 55 33 55 33 20 m 42 20 l 42 55 52 55 52 20'
|
||
else
|
||
self.line[7] = 'm 75 37.5 b 75 58.21 58.21 75 37.5 75 16.79 75 0 58.21 0 37.5 0 16.79 16.79 0 37.5 0 58.21 0 75 16.79 75 37.5 m 25.8333 17.18 l 25.8333 57.6 60.8333 37.39\n'
|
||
self.line[14] = 'm 0 0 m 75 75 m 25.8333 17.18 l 25.8333 57.6 60.8333 37.39'
|
||
end
|
||
AnimationQueue.addAnimation(Animation(0, 1, settings['animation-duration'], (function()
|
||
local _base_1 = self
|
||
local _fn_0 = _base_1.animate
|
||
return function(...)
|
||
return _fn_0(_base_1, ...)
|
||
end
|
||
end)(), (function()
|
||
local _base_1 = self
|
||
local _fn_0 = _base_1.destroy
|
||
return function(...)
|
||
return _fn_0(_base_1, ...)
|
||
end
|
||
end)()))
|
||
return self.eventLoop:addUIElement(self)
|
||
end,
|
||
__base = _base_0,
|
||
__name = "PauseIndicator"
|
||
}, {
|
||
__index = _base_0,
|
||
__call = function(cls, ...)
|
||
local _self_0 = setmetatable({}, _base_0)
|
||
cls.__init(_self_0, ...)
|
||
return _self_0
|
||
end
|
||
})
|
||
_base_0.__class = _class_0
|
||
PauseIndicator = _class_0
|
||
end
|
||
local Title
|
||
do
|
||
local _class_0
|
||
local _parent_0 = UIElement
|
||
local _base_0 = {
|
||
reconfigure = function(self)
|
||
_class_0.__parent.__base.reconfigure(self)
|
||
local offscreenPos = settings['title-offscreen-pos']
|
||
self.line[2] = ('%g,%g'):format(settings['title-left-margin'], self.animation.value)
|
||
self.line[3] = ([[)\an7%s%s}]]):format(settings['default-style'], settings['title-style'])
|
||
self.animation = Animation(offscreenPos, settings['title-top-margin'], self.animationDuration, (function()
|
||
local _base_1 = self
|
||
local _fn_0 = _base_1.animate
|
||
return function(...)
|
||
return _fn_0(_base_1, ...)
|
||
end
|
||
end)(), nil, 0.5)
|
||
end,
|
||
resize = function(self) end,
|
||
animate = function(self, value)
|
||
self.line[2] = ('%g,%g'):format(settings['title-left-margin'], value)
|
||
self.needsUpdate = true
|
||
end,
|
||
_forceUpdatePlaylistInfo = function(self)
|
||
self.playlistInfo = {
|
||
['media-title'] = mp.get_property('media-title', '????'),
|
||
['playlist-pos-1'] = mp.get_property_number('playlist-pos-1', 1),
|
||
['playlist-count'] = mp.get_property_number('playlist-count', 1)
|
||
}
|
||
end,
|
||
generateTitleString = function(self, quote)
|
||
if quote == nil then
|
||
quote = false
|
||
end
|
||
local title, position, total
|
||
do
|
||
local _obj_0 = self.playlistInfo
|
||
title, position, total = _obj_0['media-title'], _obj_0['playlist-pos-1'], _obj_0['playlist-count']
|
||
end
|
||
local prefix = (total > 1) and ('%d/%d - '):format(position, total) or ''
|
||
if quote then
|
||
return prefix .. ('%q'):format(title)
|
||
else
|
||
return prefix .. title
|
||
end
|
||
end,
|
||
updatePlaylistInfo = function(self, changedProp, newValue)
|
||
if newValue then
|
||
self.playlistInfo[changedProp] = newValue
|
||
self.line[4] = self:generateTitleString()
|
||
self.needsUpdate = true
|
||
end
|
||
end,
|
||
print = function(self)
|
||
if settings['title-print-to-cli'] then
|
||
return log.warn("Playing: %s", self:generateTitleString(true))
|
||
end
|
||
end
|
||
}
|
||
_base_0.__index = _base_0
|
||
setmetatable(_base_0, _parent_0.__base)
|
||
_class_0 = setmetatable({
|
||
__init = function(self)
|
||
_class_0.__parent.__init(self)
|
||
local offscreenPos = settings['title-offscreen-pos']
|
||
self.line = {
|
||
[[{\pos(]],
|
||
([[%g,%g]]):format(settings['title-left-margin'], offscreenPos),
|
||
([[)\an7%s%s}]]):format(settings['default-style'], settings['title-style']),
|
||
[[????]]
|
||
}
|
||
self.position = offscreenPos
|
||
self.animation = Animation(offscreenPos, settings['title-top-margin'], self.animationDuration, (function()
|
||
local _base_1 = self
|
||
local _fn_0 = _base_1.animate
|
||
return function(...)
|
||
return _fn_0(_base_1, ...)
|
||
end
|
||
end)(), nil, 0.5)
|
||
self:_forceUpdatePlaylistInfo()
|
||
local updatePlaylistInfo
|
||
do
|
||
local _base_1 = self
|
||
local _fn_0 = _base_1.updatePlaylistInfo
|
||
updatePlaylistInfo = function(...)
|
||
return _fn_0(_base_1, ...)
|
||
end
|
||
end
|
||
mp.observe_property('media-title', 'string', updatePlaylistInfo)
|
||
mp.observe_property('playlist-pos-1', 'number', updatePlaylistInfo)
|
||
return mp.observe_property('playlist-count', 'number', updatePlaylistInfo)
|
||
end,
|
||
__base = _base_0,
|
||
__name = "Title",
|
||
__parent = _parent_0
|
||
}, {
|
||
__index = function(cls, name)
|
||
local val = rawget(_base_0, name)
|
||
if val == nil then
|
||
local parent = rawget(cls, "__parent")
|
||
if parent then
|
||
return parent[name]
|
||
end
|
||
else
|
||
return val
|
||
end
|
||
end,
|
||
__call = function(cls, ...)
|
||
local _self_0 = setmetatable({}, _base_0)
|
||
cls.__init(_self_0, ...)
|
||
return _self_0
|
||
end
|
||
})
|
||
_base_0.__class = _class_0
|
||
if _parent_0.__inherited then
|
||
_parent_0.__inherited(_parent_0, _class_0)
|
||
end
|
||
Title = _class_0
|
||
end
|
||
local SystemTime
|
||
do
|
||
local _class_0
|
||
local offscreenPosition, topMargin, timeFormat
|
||
local _parent_0 = UIElement
|
||
local _base_0 = {
|
||
reconfigure = function(self)
|
||
_class_0.__parent.__base.reconfigure(self)
|
||
offscreenPosition = settings['system-time-offscreen-pos']
|
||
topMargin = settings['system-time-top-margin']
|
||
timeFormat = settings['system-time-format']
|
||
self.line[2] = ('%g,%g'):format(self.position, topMargin)
|
||
self.line[3] = ([[)\an9%s%s}]]):format(settings['default-style'], settings['system-time-style'])
|
||
self.animation = Animation(offscreenPosition, settings['system-time-right-margin'], self.animationDuration, (function()
|
||
local _base_1 = self
|
||
local _fn_0 = _base_1.animate
|
||
return function(...)
|
||
return _fn_0(_base_1, ...)
|
||
end
|
||
end)(), nil, 0.5)
|
||
end,
|
||
resize = function(self)
|
||
self.position = Window.w - self.animation.value
|
||
self.line[2] = ('%g,%g'):format(self.position, topMargin)
|
||
end,
|
||
animate = function(self, value)
|
||
self.position = Window.w - value
|
||
self.line[2] = ('%g,%g'):format(self.position, topMargin)
|
||
self.needsUpdate = true
|
||
end,
|
||
redraw = function(self)
|
||
if self.active then
|
||
local systemTime = os.time()
|
||
if systemTime ~= self.lastTime then
|
||
local update = true
|
||
self.line[4] = os.date(timeFormat, systemTime)
|
||
self.lastTime = systemTime
|
||
self.needsUpdate = true
|
||
end
|
||
end
|
||
return self.needsUpdate
|
||
end
|
||
}
|
||
_base_0.__index = _base_0
|
||
setmetatable(_base_0, _parent_0.__base)
|
||
_class_0 = setmetatable({
|
||
__init = function(self)
|
||
_class_0.__parent.__init(self)
|
||
self.line = {
|
||
[[{\pos(]],
|
||
[[-100,0]],
|
||
([[)\an9%s%s}]]):format(settings['default-style'], settings['system-time-style']),
|
||
[[????]]
|
||
}
|
||
self.lastTime = -1
|
||
self.position = offscreenPosition
|
||
self.animation = Animation(offscreenPosition, settings['system-time-right-margin'], self.animationDuration, (function()
|
||
local _base_1 = self
|
||
local _fn_0 = _base_1.animate
|
||
return function(...)
|
||
return _fn_0(_base_1, ...)
|
||
end
|
||
end)(), nil, 0.5)
|
||
end,
|
||
__base = _base_0,
|
||
__name = "SystemTime",
|
||
__parent = _parent_0
|
||
}, {
|
||
__index = function(cls, name)
|
||
local val = rawget(_base_0, name)
|
||
if val == nil then
|
||
local parent = rawget(cls, "__parent")
|
||
if parent then
|
||
return parent[name]
|
||
end
|
||
else
|
||
return val
|
||
end
|
||
end,
|
||
__call = function(cls, ...)
|
||
local _self_0 = setmetatable({}, _base_0)
|
||
cls.__init(_self_0, ...)
|
||
return _self_0
|
||
end
|
||
})
|
||
_base_0.__class = _class_0
|
||
local self = _class_0
|
||
offscreenPosition = settings['system-time-offscreen-pos']
|
||
topMargin = settings['system-time-top-margin']
|
||
timeFormat = settings['system-time-format']
|
||
if _parent_0.__inherited then
|
||
_parent_0.__inherited(_parent_0, _class_0)
|
||
end
|
||
SystemTime = _class_0
|
||
end
|
||
local eventLoop = EventLoop()
|
||
local activeHeight = settings['hover-zone-height']
|
||
local ignoreRequestDisplay
|
||
ignoreRequestDisplay = function(self)
|
||
if not (Mouse.inWindow) then
|
||
return false
|
||
end
|
||
if Mouse.dead then
|
||
return false
|
||
end
|
||
return self:containsPoint(Mouse.x, Mouse.y)
|
||
end
|
||
local bottomZone = ActivityZone(function(self)
|
||
return self:reset(0, Window.h - activeHeight, Window.w, activeHeight)
|
||
end)
|
||
local hoverTimeZone = ActivityZone(function(self)
|
||
return self:reset(0, Window.h - activeHeight, Window.w, activeHeight)
|
||
end, ignoreRequestDisplay)
|
||
local topZone = ActivityZone(function(self)
|
||
return self:reset(0, 0, Window.w, activeHeight)
|
||
end, ignoreRequestDisplay)
|
||
local chapters, progressBar, barCache, barBackground, elapsedTime, remainingTime, hoverTime
|
||
if settings['enable-bar'] then
|
||
progressBar = ProgressBar()
|
||
barCache = ProgressBarCache()
|
||
barBackground = ProgressBarBackground()
|
||
bottomZone:addUIElement(barBackground)
|
||
if settings['bar-cache-position'] == 'overlay' then
|
||
bottomZone:addUIElement(progressBar)
|
||
bottomZone:addUIElement(barCache)
|
||
else
|
||
bottomZone:addUIElement(barCache)
|
||
bottomZone:addUIElement(progressBar)
|
||
end
|
||
mp.add_key_binding("c", "toggle-inactive-bar", function()
|
||
return BarBase:toggleInactiveVisibility()
|
||
end)
|
||
end
|
||
if settings['enable-chapter-markers'] then
|
||
chapters = Chapters()
|
||
bottomZone:addUIElement(chapters)
|
||
end
|
||
if settings['enable-elapsed-time'] then
|
||
elapsedTime = TimeElapsed()
|
||
bottomZone:addUIElement(elapsedTime)
|
||
end
|
||
if settings['enable-remaining-time'] then
|
||
remainingTime = TimeRemaining()
|
||
bottomZone:addUIElement(remainingTime)
|
||
end
|
||
if settings['enable-hover-time'] then
|
||
hoverTime = HoverTime()
|
||
hoverTimeZone:addUIElement(hoverTime)
|
||
end
|
||
local title = nil
|
||
if settings['enable-title'] then
|
||
title = Title()
|
||
bottomZone:addUIElement(title)
|
||
topZone:addUIElement(title)
|
||
end
|
||
if settings['enable-system-time'] then
|
||
local systemTime = SystemTime()
|
||
bottomZone:addUIElement(systemTime)
|
||
topZone:addUIElement(systemTime)
|
||
end
|
||
eventLoop:addZone(hoverTimeZone)
|
||
eventLoop:addZone(bottomZone)
|
||
eventLoop:addZone(topZone)
|
||
local notFrameStepping = false
|
||
if settings['pause-indicator'] then
|
||
local PauseIndicatorWrapper
|
||
PauseIndicatorWrapper = function(event, paused)
|
||
if notFrameStepping then
|
||
return PauseIndicator(eventLoop, paused)
|
||
elseif paused then
|
||
notFrameStepping = true
|
||
end
|
||
end
|
||
mp.add_key_binding('.', 'step-forward', function()
|
||
notFrameStepping = false
|
||
return mp.commandv('frame_step')
|
||
end, {
|
||
repeatable = true
|
||
})
|
||
mp.add_key_binding(',', 'step-backward', function()
|
||
notFrameStepping = false
|
||
return mp.commandv('frame_back_step')
|
||
end, {
|
||
repeatable = true
|
||
})
|
||
mp.observe_property('pause', 'bool', PauseIndicatorWrapper)
|
||
end
|
||
local streamMode = false
|
||
local initDraw
|
||
initDraw = function()
|
||
if chapters then
|
||
chapters:createMarkers()
|
||
end
|
||
if title then
|
||
title:_forceUpdatePlaylistInfo()
|
||
title:print()
|
||
end
|
||
notFrameStepping = true
|
||
local duration = mp.get_property('duration')
|
||
if not (streamMode or duration) then
|
||
BarAccent.changeBarSize(0)
|
||
if progressBar then
|
||
bottomZone:removeUIElement(progressBar)
|
||
bottomZone:removeUIElement(barCache)
|
||
bottomZone:removeUIElement(barBackground)
|
||
end
|
||
if chapters then
|
||
bottomZone:removeUIElement(chapters)
|
||
end
|
||
if hoverTime then
|
||
hoverTimeZone:removeUIElement(hoverTime)
|
||
end
|
||
if remainingTime then
|
||
bottomZone:removeUIElement(remainingTime)
|
||
end
|
||
streamMode = true
|
||
elseif streamMode and duration then
|
||
BarAccent.changeBarSize(settings['bar-height-active'])
|
||
if progressBar then
|
||
bottomZone:addUIElement(barBackground)
|
||
bottomZone:addUIElement(barCache)
|
||
bottomZone:addUIElement(progressBar)
|
||
end
|
||
if chapters then
|
||
bottomZone:addUIElement(chapters)
|
||
end
|
||
if hoverTime then
|
||
hoverTimeZone:addUIElement(hoverTime)
|
||
end
|
||
if remainingTime then
|
||
bottomZone:addUIElement(remainingTime)
|
||
end
|
||
streamMode = false
|
||
end
|
||
mp.command('script-message-to osc disable-osc')
|
||
eventLoop:generateUIFromZones()
|
||
eventLoop:resize()
|
||
return eventLoop:redraw()
|
||
end
|
||
return mp.register_event('file-loaded', initDraw)
|
||
|
||
|