summaryrefslogtreecommitdiffstats
path: root/.config/mpv/scripts/uosc_shared/elements/CycleButton.lua
blob: 7f1c02fc4c57e56e6169e4c38e5cb8a883ecbece (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
local Button = require('uosc_shared/elements/Button')

---@alias CycleState {value: any; icon: string; active?: boolean}
---@alias CycleButtonProps {prop: string; states: CycleState[]; anchor_id?: string; tooltip?: string}

---@class CycleButton : Button
local CycleButton = class(Button)

---@param id string
---@param props CycleButtonProps
function CycleButton:new(id, props) return Class.new(self, id, props) --[[@as CycleButton]] end
---@param id string
---@param props CycleButtonProps
function CycleButton:init(id, props)
	local is_state_prop = itable_index_of({'shuffle'}, props.prop)
	self.prop = props.prop
	self.states = props.states

	Button.init(self, id, props)

	self.icon = self.states[1].icon
	self.active = self.states[1].active
	self.current_state_index = 1
	self.on_click = function()
		local new_state = self.states[self.current_state_index + 1] or self.states[1]
		local new_value = new_state.value
		if self.owner then
			mp.commandv('script-message-to', self.owner, 'set', self.prop, new_value)
		elseif is_state_prop then
			if itable_index_of({'yes', 'no'}, new_value) then new_value = new_value == 'yes' end
			set_state(self.prop, new_value)
		else
			mp.set_property(self.prop, new_value)
		end
	end

	self.handle_change = function(name, value)
		if is_state_prop and type(value) == 'boolean' then value = value and 'yes' or 'no' end
		local index = itable_find(self.states, function(state) return state.value == value end)
		self.current_state_index = index or 1
		self.icon = self.states[self.current_state_index].icon
		self.active = self.states[self.current_state_index].active
		request_render()
	end

	local prop_parts = split(self.prop, '@')
	if #prop_parts == 2 then -- External prop with a script owner
		self.prop, self.owner = prop_parts[1], prop_parts[2]
		self['on_external_prop_' .. self.prop] = function(_, value) self.handle_change(self.prop, value) end
		self.handle_change(self.prop, external[self.prop])
	elseif is_state_prop then -- uosc's state props
		self['on_prop_' .. self.prop] = function(self, value) self.handle_change(self.prop, value) end
		self.handle_change(self.prop, state[self.prop])
	else
		mp.observe_property(self.prop, 'string', self.handle_change)
	end
end

function CycleButton:destroy()
	Button.destroy(self)
	mp.unobserve_property(self.handle_change)
end

return CycleButton