diff options
| -rw-r--r-- | config.lua | 3 | ||||
| -rw-r--r-- | main.lua | 53 | ||||
| -rw-r--r-- | osd.lua | 80 |
3 files changed, 135 insertions, 1 deletions
@@ -12,6 +12,7 @@ config.scroll_margin = 4 config.click_timeout = 0.5 config.click_dbl_time = 0.3 config.click_max_drift = 2 +config.toggle_button_timeout = 0.5 config.bg_alpha = '44' config.colours = { @@ -35,6 +36,8 @@ config.colours = { scrollbar_bg = '333333', status_info = '55bbdd', status_error = 'ff3333', + toggle_button_fg = '000000', + toggle_button_bg = '00cc00', } local script_dir = mp.get_script_directory() @@ -1277,6 +1277,59 @@ local function toggle_menu() set_key_bindings() end +local mouse_pos_time +local mouse_over_button_area = false +local mouse_over_toggle_button = false +local mouse_timer; mouse_timer = mp.add_periodic_timer(0.1, function() + if mouse_pos_time and + not mouse_over_toggle_button and + mp.get_time() - mouse_pos_time > + config.toggle_button_timeout then + osd:show_toggle_button(false) + mouse_timer:kill() + end +end, true) -- disabled +mp.observe_property('mouse-pos', 'native', function(_, mpos) + if not mpos then + return + end + + -- mpv sends (0, 0) on startup if the mouse hasn't moved yet. don't + -- trigger display of the button until the mouse has actually moved. + if not mouse_pos_time and mpos.x == 0 and mpos.y == 0 then + return + end + + mouse_pos_time = mp.get_time() + + local is_over = osd:mouse_over_button_area(mpos) + if is_over ~= mouse_over_button_area then + mouse_over_button_area = is_over + osd:show_toggle_button(mouse_over_button_area) + elseif mouse_over_button_area and osd.toggle_button.hidden then + osd:show_toggle_button(true) + end + + if mouse_over_button_area then + mouse_timer:resume() + else + mouse_timer:kill() + end + + local is_over = osd:mouse_over_toggle_button(mpos) + if is_over ~= mouse_over_toggle_button then + mouse_over_toggle_button = is_over + if mouse_over_toggle_button then + mp.add_forced_key_binding( + 'MBTN_LEFT', 'click', toggle_menu) + mp.add_forced_key_binding('MBTN_LEFT_DBL', 'click_dbl') + else + mp.remove_key_binding('click') + mp.remove_key_binding('click_dbl') + end + end +end) + mp.observe_property('user-data/osc/visibility', 'native', function(_, val) if val and (osd:is_hidden() or val ~= 'never') then osc_visibility = val @@ -39,6 +39,7 @@ function osd.new(init) local t = setmetatable({ fg = mp.create_osd_overlay('ass-events'), bg = mp.create_osd_overlay('ass-events'), + toggle_button = mp.create_osd_overlay('ass-events'), width = 0, height = 0, scale = 1, @@ -46,6 +47,8 @@ function osd.new(init) padding = math.floor((720 - (lines * config.font_size)) / 2), }, mt) t.bg.z = -1 + t.toggle_button.z = 1 + t.toggle_button.hidden = true for k, v in pairs(init or {}) do t[k] = v @@ -67,7 +70,24 @@ end function mt:resize(w, h) self.width = w self.height = h - self.scale = h / 720 + self.scale = h > 0 and h/720 or 1 + + local sz = self.padding + self:measure_width('»') - 2 + local coords = { + x1 = 2, + y1 = self.padding + ((config.font_size - sz) / 2), + } + coords.x2 = coords.x1 + sz + coords.y2 = coords.y1 + sz + self.toggle_button_coords = coords + + self.toggle_button.data = + '{\\pos(' .. coords.x1 .. ',' .. coords.y1 .. ')}' .. + colours.toggle_button_bg .. draw_rect(0, 0, sz, sz) .. '\n' .. + '{\\q2\\fs' .. sz .. '\\bord0\\an5\\pos(' .. + coords.x1 + sz/2 .. ',' .. coords.y1 + sz/2 ..')}' .. + colours.toggle_button_fg .. '≡' + self.toggle_button:update() end function mt:set_status(msg, level, no_dirty) @@ -570,6 +590,12 @@ function mt:is_hidden() end function mt:get_mouse_line(mpos) + local x = mpos.x / self.scale + local w = self.width / self.scale + if x < self.padding or x > w - self.padding then + return + end + local y = mpos.y / self.scale local line = math.floor((y - self.padding) / config.font_size) + 1 if line < 1 or line > self.lines then @@ -578,4 +604,56 @@ function mt:get_mouse_line(mpos) return line end +function mt:mouse_over_button_area(mpos) + if not mpos.hover then + return false + end + + local y = mpos.y / self.scale + return y < self.padding + (2 * config.font_size) +end + +function mt:mouse_over_toggle_button(mpos) + if not mpos.hover then + return false + end + + local x = mpos.x / self.scale + local y = mpos.y / self.scale + local coords = self.toggle_button_coords + return coords and + x > coords.x1 and x < coords.x2 and + y > coords.y1 and y < coords.y2 +end + +function mt:show_toggle_button(bool) + if self.toggle_button.hidden ~= bool then + return + end + + self.toggle_button.hidden = not bool + self.toggle_button:update() +end + +function mt:measure_width(str) + local e = self.toggle_button + local data = e.data + local hidden = e.hidden + e.hidden = true + e.compute_bounds = true + + local block = '\xe2\x96\x88' + local pre = '{\\q2\\fs' .. config.font_size .. '\\pos(0,0)}' .. block + e.data = pre .. block + local size = e:update().x1 + e.data = pre .. str .. block + size = e:update().x1 - size + + e.data = data + e.hidden = hidden + e.compute_bounds = false + + return size +end + return osd |
