1780 lines
44 KiB
Lua
1780 lines
44 KiB
Lua
BINDING_HEADER_WOWRADIO = "WowRadio"
|
|
BINDING_NAME_WOWRADIO_TOGGLE = "Open Radio Window"
|
|
BINDING_NAME_WOWRADIO_PLAYSTOP = "Play / Stop"
|
|
BINDING_NAME_WOWRADIO_NEXT = "Next Station"
|
|
BINDING_NAME_WOWRADIO_PREV = "Previous Station"
|
|
BINDING_NAME_WOWRADIO_RANDOM = "Random Station"
|
|
|
|
function WowRadioBinding_Toggle()
|
|
if WowRadio then WowRadio:ToggleUI() end
|
|
end
|
|
|
|
function WowRadioBinding_PlayStop()
|
|
if WowRadio then
|
|
if WowRadio:isStopped() then WowRadio:play() else WowRadio:stop() end
|
|
end
|
|
end
|
|
|
|
function WowRadioBinding_Next()
|
|
if WowRadio then WowRadio:next() end
|
|
end
|
|
|
|
function WowRadioBinding_Prev()
|
|
if WowRadio then WowRadio:prev() end
|
|
end
|
|
|
|
function WowRadioBinding_Random()
|
|
if WowRadio then WowRadio:rnd() end
|
|
end
|
|
|
|
local L = AceLibrary("AceLocale-2.2"):new("WowRadio")
|
|
local version = "0.7i-nowplaying-bottom"
|
|
local customUrl = nil
|
|
local stopped = false
|
|
local stationShortNameCache = {}
|
|
local WR_CHAT_PREFIX = "|cffff9900[WoWRadio]|r "
|
|
|
|
WowRadio = AceLibrary("AceAddon-2.0"):new("AceEvent-2.0", "AceConsole-2.0", "AceDB-2.0")
|
|
|
|
-----------------------------------------------------------------
|
|
-- Slash Commands
|
|
-----------------------------------------------------------------
|
|
|
|
-- Main command now opens/closes the UI.
|
|
WowRadio:RegisterChatCommand({ "/wowradio", "/wr" }, {
|
|
type = 'execute',
|
|
name = "ui",
|
|
desc = "",
|
|
func = "ToggleUI",
|
|
}, "WOWRADIO00")
|
|
|
|
-- Old help/usage command preserved.
|
|
WowRadio:RegisterChatCommand({ "/wrhelp", "/wrusage" }, {
|
|
type = 'execute',
|
|
name = "usage",
|
|
desc = "",
|
|
func = "usage",
|
|
}, "WOWRADIOHELP")
|
|
|
|
WowRadio:RegisterChatCommand({"/wrtune"}, {
|
|
type = 'text',
|
|
name = "tune",
|
|
desc = "",
|
|
usage = "",
|
|
get = false,
|
|
set = "setStation",
|
|
}, "WOWRADIO01")
|
|
|
|
WowRadio:RegisterChatCommand({"/wrplay"}, {
|
|
type = 'execute',
|
|
name = "play",
|
|
desc = "",
|
|
func = "play",
|
|
}, "WOWRADIO02")
|
|
|
|
WowRadio:RegisterChatCommand({"/wrstop"}, {
|
|
type = 'execute',
|
|
name = "stop",
|
|
desc = "",
|
|
func = "stop",
|
|
}, "WOWRADIO03")
|
|
|
|
WowRadio:RegisterChatCommand({"/wrnext"}, {
|
|
type = 'execute',
|
|
name = "next",
|
|
desc = "",
|
|
func = "next",
|
|
}, "WOWRADIO04")
|
|
|
|
WowRadio:RegisterChatCommand({"/wrprev"}, {
|
|
type = 'execute',
|
|
name = "prev",
|
|
desc = "",
|
|
func = "prev",
|
|
}, "WOWRADIO05")
|
|
|
|
WowRadio:RegisterChatCommand({"/wrrnd"}, {
|
|
type = 'execute',
|
|
name = "rnd",
|
|
desc = "",
|
|
func = "rnd",
|
|
}, "WOWRADIO06")
|
|
|
|
WowRadio:RegisterChatCommand({"/wrlist"}, {
|
|
type = 'execute',
|
|
name = "list",
|
|
desc = "",
|
|
func = "list",
|
|
}, "WOWRADIO07")
|
|
|
|
WowRadio:RegisterChatCommand({"/wrindex", "/wri"}, {
|
|
type = 'execute',
|
|
name = "index",
|
|
desc = "",
|
|
func = "index",
|
|
}, "WOWRADIO11")
|
|
|
|
WowRadio:RegisterChatCommand({"/wrfull"}, {
|
|
type = 'execute',
|
|
name = "full",
|
|
desc = "",
|
|
func = "listFull",
|
|
}, "WOWRADIO12")
|
|
|
|
WowRadio:RegisterChatCommand({"/wrfind", "/wrsearch"}, {
|
|
type = 'text',
|
|
name = "find",
|
|
desc = "",
|
|
usage = "",
|
|
get = false,
|
|
set = "findStation",
|
|
}, "WOWRADIO13")
|
|
|
|
WowRadio:RegisterChatCommand({"/wrurl"}, {
|
|
type = 'execute',
|
|
name = "url",
|
|
desc = "",
|
|
func = "currentUrl",
|
|
}, "WOWRADIO14")
|
|
|
|
WowRadio:RegisterChatCommand({"/wrinfo"}, {
|
|
type = 'execute',
|
|
name = "info",
|
|
desc = "",
|
|
func = "info",
|
|
}, "WOWRADIO08")
|
|
|
|
WowRadio:RegisterChatCommand({"/wrauto"}, {
|
|
type = 'execute',
|
|
name = "autostart",
|
|
desc = "",
|
|
func = "toggleAutostart",
|
|
}, "WOWRADIO09")
|
|
|
|
WowRadio:RegisterChatCommand({"/wrcustom"}, {
|
|
type = 'text',
|
|
name = "custom",
|
|
desc = "",
|
|
usage = "",
|
|
get = false,
|
|
set = "url",
|
|
}, "WOWRADIO10")
|
|
|
|
-- Explicit UI aliases.
|
|
WowRadio:RegisterChatCommand({"/wrgui", "/wrui"}, {
|
|
type = 'execute',
|
|
name = "gui",
|
|
desc = "",
|
|
func = "ToggleUI",
|
|
}, "WOWRADIO15")
|
|
|
|
-----------------------------------------------------------------
|
|
-- Database
|
|
-----------------------------------------------------------------
|
|
|
|
WowRadio:RegisterDB("WowRadioDB","WowRadioDBPC")
|
|
|
|
WowRadio:RegisterDefaults("account", {
|
|
autostart = false,
|
|
station = 1,
|
|
fadeOnMove = false,
|
|
muted = false,
|
|
muteVolume = nil,
|
|
|
|
ui = {
|
|
shown = false,
|
|
tab = "ALL",
|
|
page = 1,
|
|
compact = false,
|
|
scale = 1.0,
|
|
framePoint = "CENTER",
|
|
frameRelPoint = "CENTER",
|
|
frameX = 0,
|
|
frameY = 0,
|
|
},
|
|
|
|
favorites = {},
|
|
|
|
minimap = {
|
|
point = "TOPLEFT",
|
|
relPoint = "TOPLEFT",
|
|
x = -8,
|
|
y = -8,
|
|
},
|
|
})
|
|
|
|
-----------------------------------------------------------------
|
|
-- Lifecycle
|
|
-----------------------------------------------------------------
|
|
|
|
function WowRadio:OnEnable()
|
|
WowRadio:EnsureUIDefaults()
|
|
WowRadio:CreateMinimapButton()
|
|
WowRadio:CreateController()
|
|
|
|
-- Restore custom URL from previous session.
|
|
customUrl = self.db.account.customUrl or nil
|
|
|
|
-- Re-apply muted state (CVar resets on reload).
|
|
if WowRadio.db.account.muted then
|
|
WowRadio:SafeSetCVar("EnableMusic", "1")
|
|
WowRadio:SafeSetCVar("Sound_EnableMusic", "1")
|
|
WowRadio:SafeSetCVar("MusicVolume", 0)
|
|
WowRadio:SafeSetCVar("Sound_MusicVolume", 0)
|
|
end
|
|
|
|
if WowRadio.db.account.ui.shown == true then
|
|
WowRadio:ShowController()
|
|
end
|
|
|
|
if WowRadio:isAutostart() == true then
|
|
if customUrl then
|
|
WowRadio:ForceMusicPlay(customUrl)
|
|
stopped = false
|
|
else
|
|
WowRadio:play()
|
|
end
|
|
end
|
|
|
|
self:Print(L["msg_enabled"])
|
|
end
|
|
|
|
-----------------------------------------------------------------
|
|
-- Core Radio Functions
|
|
-----------------------------------------------------------------
|
|
|
|
function WowRadio:ForceMusicPlay(url)
|
|
WowRadio:SafeSetCVar("EnableMusic", "0")
|
|
WowRadio:SafeSetCVar("EnableMusic", "1")
|
|
PlayMusic(url)
|
|
end
|
|
|
|
function WowRadio:setStation(arg)
|
|
local station = tonumber(arg)
|
|
|
|
if station == nil then
|
|
wr_msg("invalid argument")
|
|
return
|
|
end
|
|
|
|
WowRadio:play(station)
|
|
end
|
|
|
|
function WowRadio:getStation()
|
|
return tonumber(self.db.account.station)
|
|
end
|
|
|
|
function WowRadio:toggleAutostart()
|
|
self.db.account.autostart = not self.db.account.autostart
|
|
|
|
if self.db.account.autostart == true then
|
|
wr_msg(WR_CHAT_PREFIX.."Autostart enabled.")
|
|
else
|
|
wr_msg(WR_CHAT_PREFIX.."Autostart disabled.")
|
|
end
|
|
|
|
WowRadio:RefreshAutoButton()
|
|
end
|
|
|
|
function WowRadio:isAutostart()
|
|
return self.db.account.autostart
|
|
end
|
|
|
|
function WowRadio:info()
|
|
if customUrl == nil then
|
|
wr_alert("["..WowRadio:getStation().."] "..stationMsg[WowRadio:getStation()])
|
|
else
|
|
wr_alert("[custom] "..customUrl)
|
|
end
|
|
end
|
|
|
|
function WowRadio:play(station)
|
|
if station == nil then
|
|
station = WowRadio:getStation()
|
|
elseif station > table.getn(stationUrl) then
|
|
station = 1
|
|
elseif station < 1 then
|
|
station = table.getn(stationUrl)
|
|
end
|
|
|
|
wr_alert(WR_CHAT_PREFIX.."Tuning in to "..WowRadio:getStationShortName(station).."...")
|
|
WowRadio:ForceMusicPlay(stationUrl[station])
|
|
|
|
self.db.account.station = station
|
|
self.db.account.customUrl = nil
|
|
stopped = false
|
|
customUrl = nil
|
|
|
|
WowRadio:RefreshNowPlaying()
|
|
end
|
|
|
|
function WowRadio:stop()
|
|
StopMusic()
|
|
stopped = true
|
|
wr_alert(WR_CHAT_PREFIX.."Radio off.")
|
|
WowRadio:RefreshNowPlaying()
|
|
end
|
|
|
|
function WowRadio:next()
|
|
local station = WowRadio:getStation() + 1
|
|
WowRadio:play(station)
|
|
end
|
|
|
|
function WowRadio:prev()
|
|
local station = WowRadio:getStation() - 1
|
|
WowRadio:play(station)
|
|
end
|
|
|
|
function WowRadio:rnd()
|
|
WowRadio:play(math.random(table.getn(stationUrl)))
|
|
end
|
|
|
|
function WowRadio:url(url)
|
|
if url == nil or url == "" then
|
|
wr_msg("Usage: /wrcustom URL")
|
|
return
|
|
end
|
|
|
|
wr_alert(WR_CHAT_PREFIX.."Tuning in to custom stream...")
|
|
customUrl = url
|
|
self.db.account.customUrl = url
|
|
WowRadio:ForceMusicPlay(url)
|
|
stopped = false
|
|
|
|
WowRadio:RefreshNowPlaying()
|
|
end
|
|
|
|
function WowRadio:usage()
|
|
wr_msg("|cff7FFF7FWowRadio "..version.." "..L["usage"]..":|r")
|
|
wr_msg("|cffFFFF00/wr - |r|cffFFFFFFopen/close the radio controller|r")
|
|
wr_msg("|cffFFFF00/wrhelp - |r|cffFFFFFFshow this help text|r")
|
|
wr_msg("|cffFFFF00/wrtune # - |r|cffFFFFFF"..L["wrtune"].."|r")
|
|
wr_msg("|cffFFFF00/wrplay - |r|cffFFFFFF"..L["wrplay"].."|r")
|
|
wr_msg("|cffFFFF00/wrstop - |r|cffFFFFFF"..L["wrstop"].."|r")
|
|
wr_msg("|cffFFFF00/wrnext - |r|cffFFFFFF"..L["wrnext"].."|r")
|
|
wr_msg("|cffFFFF00/wrprev - |r|cffFFFFFF"..L["wrprev"].."|r")
|
|
wr_msg("|cffFFFF00/wrrnd - |r|cffFFFFFF"..L["wrrnd"].."|r")
|
|
wr_msg("|cffFFFF00/wrlist - |r|cffFFFFFFcompact station index, 3 per row|r")
|
|
wr_msg("|cffFFFF00/wrindex or /wri - |r|cffFFFFFFcompact station index, 3 per row|r")
|
|
wr_msg("|cffFFFF00/wrfull - |r|cffFFFFFFfull station list, one per row|r")
|
|
wr_msg("|cffFFFF00/wrfind text - |r|cffFFFFFFsearch stations by name, description, or URL|r")
|
|
wr_msg("|cffFFFF00/wrurl - |r|cffFFFFFFshow the current station URL|r")
|
|
wr_msg("|cffFFFF00/wrinfo - |r|cffFFFFFF"..L["wrinfo"].."|r")
|
|
wr_msg("|cffFFFF00/wrauto - |r|cffFFFFFF"..L["wrauto"].."|r")
|
|
wr_msg("|cffFFFF00/wrcustom URL - |r|cffFFFFFF"..L["wrcustom"].."|r")
|
|
end
|
|
|
|
-----------------------------------------------------------------
|
|
-- Existing List/Search Helpers
|
|
-----------------------------------------------------------------
|
|
|
|
function WowRadio:list()
|
|
WowRadio:index()
|
|
end
|
|
|
|
function WowRadio:index()
|
|
local perRow = 3
|
|
local colWidth = 36
|
|
local line = ""
|
|
local total = table.getn(stationUrl)
|
|
|
|
wr_msg("|cff7FFF7FWowRadio stations ("..total..") - use /wrtune #|r")
|
|
|
|
for index = 1, total do
|
|
local entry = "["..index.."] "..WowRadio:getStationShortName(index)
|
|
line = line..wr_pad(entry, colWidth)
|
|
|
|
if math.mod(index, perRow) == 0 then
|
|
wr_msg(line)
|
|
line = ""
|
|
end
|
|
end
|
|
|
|
if line ~= "" then
|
|
wr_msg(line)
|
|
end
|
|
end
|
|
|
|
function WowRadio:listFull()
|
|
for index,value in ipairs(stationMsg) do
|
|
wr_msg("["..index.."] "..value)
|
|
end
|
|
end
|
|
|
|
function WowRadio:findStation(arg)
|
|
local query = string.lower(arg or "")
|
|
local found = 0
|
|
|
|
if query == "" then
|
|
wr_msg("Usage: /wrfind text")
|
|
return
|
|
end
|
|
|
|
wr_msg("|cff7FFF7FWowRadio search: "..arg.."|r")
|
|
|
|
for index = 1, table.getn(stationUrl) do
|
|
local name = WowRadio:getStationShortName(index)
|
|
local msg = stationMsg[index] or ""
|
|
local url = stationUrl[index] or ""
|
|
local haystack = string.lower(name.." "..msg.." "..url)
|
|
|
|
if string.find(haystack, query, 1, true) then
|
|
found = found + 1
|
|
wr_msg("["..index.."] "..name)
|
|
end
|
|
end
|
|
|
|
if found == 0 then
|
|
wr_msg("No stations found.")
|
|
end
|
|
end
|
|
|
|
function WowRadio:currentUrl()
|
|
if customUrl == nil then
|
|
local station = WowRadio:getStation()
|
|
wr_msg("["..station.."] "..WowRadio:getStationShortName(station))
|
|
wr_msg(stationUrl[station])
|
|
else
|
|
wr_msg("[custom] "..customUrl)
|
|
end
|
|
end
|
|
|
|
function WowRadio:getStationShortName(index)
|
|
local cached = stationShortNameCache[index]
|
|
if cached ~= nil then
|
|
return cached
|
|
end
|
|
|
|
local msg = stationMsg[index] or ""
|
|
local pos = string.find(msg, " %- ")
|
|
local shortName = msg
|
|
|
|
if pos then
|
|
shortName = string.sub(msg, 1, pos - 1)
|
|
end
|
|
|
|
stationShortNameCache[index] = shortName
|
|
return shortName
|
|
end
|
|
|
|
-----------------------------------------------------------------
|
|
-- Generic Helpers
|
|
-----------------------------------------------------------------
|
|
|
|
function wr_alert(txt)
|
|
wr_msg(txt)
|
|
end
|
|
|
|
function wr_msg(txt)
|
|
DEFAULT_CHAT_FRAME:AddMessage(txt)
|
|
end
|
|
|
|
function wr_pad(txt, width)
|
|
local len = string.len(txt)
|
|
|
|
if len > width then
|
|
return string.sub(txt, 1, width - 1).."~"
|
|
end
|
|
|
|
return txt..string.rep(" ", width - len)
|
|
end
|
|
|
|
function wr_trim(txt, width)
|
|
if txt == nil then
|
|
return ""
|
|
end
|
|
|
|
if string.len(txt) > width then
|
|
return string.sub(txt, 1, width - 3).."..."
|
|
end
|
|
|
|
return txt
|
|
end
|
|
|
|
function WowRadio:getStationSize()
|
|
return table.getn(stationUrl)
|
|
end
|
|
|
|
function WowRadio:getStationNames()
|
|
return stationMsg
|
|
end
|
|
|
|
function WowRadio:getCustomUrl()
|
|
return customUrl
|
|
end
|
|
|
|
function WowRadio:isStopped()
|
|
return stopped
|
|
end
|
|
|
|
-----------------------------------------------------------------
|
|
-- WowRadio GUI Layer
|
|
-- Vanilla / 1.12.x compatible controller UI
|
|
-----------------------------------------------------------------
|
|
|
|
local WR_LINES_PER_PAGE = 8
|
|
local WR_FRAME_WIDTH = 560
|
|
local WR_FRAME_HEIGHT = 430
|
|
local WR_BACKDROP_TEXTURE_LEFT = "Interface\\AddOns\\WowRadio-Vanilla\\bg_left"
|
|
local WR_BACKDROP_TEXTURE_RIGHT = "Interface\\AddOns\\WowRadio-Vanilla\\bg_right"
|
|
|
|
local WR_MINI_WIDTH = 370
|
|
local WR_MINI_HEIGHT = 90
|
|
local WR_MICRO_SCROLL_CHARS = 30
|
|
local WR_MICRO_SCROLL_INTERVAL = 0.24
|
|
local WR_MICRO_SCROLL_PAUSE = 10.0
|
|
|
|
local WR_TABS = {
|
|
{ key = "ALL", label = "All", width = 45 },
|
|
{ key = "FAV", label = "Fav", width = 45 },
|
|
{ key = "GAME", label = "Game", width = 55 },
|
|
{ key = "TALK", label = "Talk", width = 55 },
|
|
{ key = "ROCK", label = "Rock", width = 55 },
|
|
{ key = "ELECTRONIC", label = "Electronic", width = 75 },
|
|
{ key = "JAZZ", label = "Jazz", width = 55 },
|
|
{ key = "VARIETY", label = "Various", width = 70 },
|
|
}
|
|
|
|
function WowRadio:EnsureUIDefaults()
|
|
if self.db.account.ui == nil then
|
|
self.db.account.ui = {}
|
|
end
|
|
|
|
if self.db.account.ui.shown == nil then
|
|
self.db.account.ui.shown = false
|
|
end
|
|
|
|
if self.db.account.ui.tab == nil then
|
|
self.db.account.ui.tab = "ALL"
|
|
end
|
|
|
|
-- Old saved states from prior versions should not point at removed panels.
|
|
if self.db.account.ui.tab == "CUSTOM" or self.db.account.ui.tab == "TEST" then
|
|
self.db.account.ui.tab = "ALL"
|
|
end
|
|
|
|
if self.db.account.ui.page == nil then
|
|
self.db.account.ui.page = 1
|
|
end
|
|
|
|
if self.db.account.ui.compact == nil then
|
|
self.db.account.ui.compact = false
|
|
end
|
|
|
|
if self.db.account.muted == nil then
|
|
self.db.account.muted = false
|
|
end
|
|
|
|
if self.db.account.favorites == nil then
|
|
self.db.account.favorites = {}
|
|
end
|
|
|
|
if self.db.account.minimap == nil then
|
|
self.db.account.minimap = {}
|
|
end
|
|
|
|
if self.db.account.minimap.point == nil then
|
|
self.db.account.minimap.point = "TOPLEFT"
|
|
end
|
|
|
|
if self.db.account.minimap.relPoint == nil then
|
|
self.db.account.minimap.relPoint = "TOPLEFT"
|
|
end
|
|
|
|
if self.db.account.minimap.x == nil then
|
|
self.db.account.minimap.x = -8
|
|
end
|
|
|
|
if self.db.account.minimap.y == nil then
|
|
self.db.account.minimap.y = -8
|
|
end
|
|
|
|
if self.db.account.volume == nil then
|
|
self.db.account.volume = WowRadio:ReadCurrentMusicVolume()
|
|
end
|
|
|
|
if self.db.account.fadeOnMove == nil then
|
|
self.db.account.fadeOnMove = false
|
|
end
|
|
end
|
|
|
|
function WowRadio:ShowCustomUrlDialog()
|
|
if not WowRadioUrlDialog then return end
|
|
WowRadioUrlDialog:ClearAllPoints()
|
|
WowRadioUrlDialog:SetPoint("CENTER", UIParent, "CENTER")
|
|
WowRadioUrlEditBox:SetText(customUrl or "")
|
|
WowRadioUrlDialog:Show()
|
|
WowRadioUrlEditBox:SetFocus()
|
|
end
|
|
|
|
function WowRadio:ToggleFadeOnMove()
|
|
self.db.account.fadeOnMove = not self.db.account.fadeOnMove
|
|
|
|
if WowRadioFrame and not self.db.account.fadeOnMove then
|
|
WowRadioFrame:SetAlpha(1)
|
|
end
|
|
|
|
WowRadio:RefreshFadeButton()
|
|
end
|
|
|
|
function WowRadio:SafeGetCVar(name)
|
|
if not GetCVar then
|
|
return nil
|
|
end
|
|
|
|
local ok, value = pcall(GetCVar, name)
|
|
|
|
if ok then
|
|
return value
|
|
end
|
|
|
|
return nil
|
|
end
|
|
|
|
function WowRadio:SafeSetCVar(name, value)
|
|
if not SetCVar then
|
|
return false
|
|
end
|
|
|
|
local ok = pcall(SetCVar, name, tostring(value))
|
|
return ok
|
|
end
|
|
|
|
function WowRadio:ReadCurrentMusicVolume()
|
|
local v = nil
|
|
|
|
-- Vanilla/1.12 commonly uses MusicVolume. Later clients use Sound_MusicVolume.
|
|
-- GetCVar can hard-error on unknown names in 1.12, so every lookup is wrapped.
|
|
v = tonumber(WowRadio:SafeGetCVar("MusicVolume"))
|
|
|
|
if v == nil then
|
|
v = tonumber(WowRadio:SafeGetCVar("Sound_MusicVolume"))
|
|
end
|
|
|
|
if v == nil then
|
|
v = tonumber(WowRadio:SafeGetCVar("SoundVolume"))
|
|
end
|
|
|
|
if v == nil then
|
|
v = 1
|
|
end
|
|
|
|
if v < 0 then
|
|
v = 0
|
|
elseif v > 1 then
|
|
v = 1
|
|
end
|
|
|
|
return v
|
|
end
|
|
|
|
function WowRadio:GetVolume()
|
|
local v = tonumber(self.db.account.volume)
|
|
|
|
if v == nil then
|
|
v = WowRadio:ReadCurrentMusicVolume()
|
|
end
|
|
|
|
if v < 0 then
|
|
v = 0
|
|
elseif v > 1 then
|
|
v = 1
|
|
end
|
|
|
|
return v
|
|
end
|
|
|
|
function WowRadio:ApplyVolume(value, quiet)
|
|
local v = tonumber(value)
|
|
|
|
if v == nil then
|
|
v = 1
|
|
end
|
|
|
|
if v < 0 then
|
|
v = 0
|
|
elseif v > 1 then
|
|
v = 1
|
|
end
|
|
|
|
self.db.account.volume = v
|
|
|
|
-- Vanilla/1.12 commonly uses EnableMusic + MusicVolume.
|
|
-- Later clients may use Sound_EnableMusic + Sound_MusicVolume.
|
|
WowRadio:SafeSetCVar("EnableMusic", "1")
|
|
WowRadio:SafeSetCVar("Sound_EnableMusic", "1")
|
|
WowRadio:SafeSetCVar("MusicVolume", v)
|
|
WowRadio:SafeSetCVar("Sound_MusicVolume", v)
|
|
|
|
if WowRadioFrame and WowRadioFrame.volumeValueText then
|
|
WowRadioFrame.volumeValueText:SetText(math.floor((v * 100) + 0.5).."%")
|
|
end
|
|
|
|
if quiet ~= true then
|
|
wr_msg(WR_CHAT_PREFIX.."Volume set to "..math.floor((v * 100) + 0.5).."%.")
|
|
end
|
|
end
|
|
|
|
function WowRadio:ToggleUI()
|
|
if WowRadioFrame and WowRadioFrame:IsVisible() then
|
|
WowRadio:HideController()
|
|
else
|
|
WowRadio:ShowController()
|
|
end
|
|
end
|
|
|
|
function WowRadio:ShowController()
|
|
if not WowRadioFrame then
|
|
WowRadio:CreateController()
|
|
end
|
|
|
|
WowRadioFrame:Show()
|
|
if WowRadioFrame.moveWatcher then WowRadioFrame.moveWatcher:Show() end
|
|
self.db.account.ui.shown = true
|
|
WowRadio:RefreshUI()
|
|
end
|
|
|
|
function WowRadio:HideController()
|
|
if WowRadioFrame then
|
|
if WowRadioFrame.moveWatcher then WowRadioFrame.moveWatcher:Hide() end
|
|
WowRadioFrame:Hide()
|
|
end
|
|
|
|
self.db.account.ui.shown = false
|
|
end
|
|
|
|
function WowRadio:CreateMinimapButton()
|
|
if WowRadioMinimapButton then
|
|
return
|
|
end
|
|
|
|
local button = CreateFrame("Button", "WowRadioMinimapButton", Minimap)
|
|
button:SetWidth(31)
|
|
button:SetHeight(31)
|
|
button:SetFrameStrata("MEDIUM")
|
|
button:SetFrameLevel(4)
|
|
button:EnableMouse(true)
|
|
button:RegisterForClicks("LeftButtonUp", "RightButtonUp")
|
|
button:RegisterForDrag("LeftButton")
|
|
button:SetHighlightTexture("Interface\\Minimap\\UI-Minimap-ZoomButton-Highlight")
|
|
|
|
local icon = button:CreateTexture(nil, "BACKGROUND")
|
|
icon:SetTexture("Interface\\Icons\\INV_Misc_EngGizmos_13")
|
|
icon:SetTexCoord(0.05, 0.95, 0.05, 0.95)
|
|
icon:SetWidth(20)
|
|
icon:SetHeight(20)
|
|
icon:SetPoint("TOPLEFT", button, "TOPLEFT", 7, -5)
|
|
|
|
local border = button:CreateTexture(nil, "OVERLAY")
|
|
border:SetTexture("Interface\\Minimap\\MiniMap-TrackingBorder")
|
|
border:SetWidth(53)
|
|
border:SetHeight(53)
|
|
border:SetPoint("TOPLEFT", button, "TOPLEFT")
|
|
|
|
local mm = self.db.account.minimap
|
|
button:ClearAllPoints()
|
|
button:SetPoint(mm.point, Minimap, mm.relPoint, mm.x, mm.y)
|
|
|
|
button:SetScript("OnClick", function()
|
|
if arg1 == "RightButton" then
|
|
if WowRadio:isStopped() then
|
|
WowRadio:play()
|
|
else
|
|
WowRadio:stop()
|
|
end
|
|
else
|
|
WowRadio:ToggleUI()
|
|
end
|
|
end)
|
|
|
|
local minimapDragging = false
|
|
local minimapDragX = mm.x or 0
|
|
local minimapDragY = mm.y or 0
|
|
|
|
local function UpdateMinimapButtonDrag()
|
|
local cursorX, cursorY = GetCursorPosition()
|
|
local scale = UIParent:GetScale()
|
|
|
|
if Minimap.GetEffectiveScale then
|
|
scale = Minimap:GetEffectiveScale()
|
|
end
|
|
|
|
if not scale or scale == 0 then
|
|
return
|
|
end
|
|
|
|
cursorX = cursorX / scale
|
|
cursorY = cursorY / scale
|
|
|
|
local centerX, centerY = Minimap:GetCenter()
|
|
if not centerX or not centerY then
|
|
return
|
|
end
|
|
|
|
minimapDragX = cursorX - centerX
|
|
minimapDragY = cursorY - centerY
|
|
|
|
button:ClearAllPoints()
|
|
button:SetPoint("CENTER", Minimap, "CENTER", minimapDragX, minimapDragY)
|
|
end
|
|
|
|
button:SetScript("OnDragStart", function()
|
|
if IsShiftKeyDown() then
|
|
minimapDragging = true
|
|
UpdateMinimapButtonDrag()
|
|
end
|
|
end)
|
|
|
|
button:SetScript("OnDragStop", function()
|
|
if not minimapDragging then
|
|
return
|
|
end
|
|
|
|
UpdateMinimapButtonDrag()
|
|
minimapDragging = false
|
|
|
|
WowRadio.db.account.minimap.point = "CENTER"
|
|
WowRadio.db.account.minimap.relPoint = "CENTER"
|
|
WowRadio.db.account.minimap.x = minimapDragX
|
|
WowRadio.db.account.minimap.y = minimapDragY
|
|
end)
|
|
|
|
button:SetScript("OnUpdate", function()
|
|
if minimapDragging then
|
|
UpdateMinimapButtonDrag()
|
|
end
|
|
end)
|
|
|
|
button:SetScript("OnEnter", function()
|
|
GameTooltip:SetOwner(this, "ANCHOR_LEFT")
|
|
GameTooltip:SetText("|cff7FFF7FWowRadio|r")
|
|
GameTooltip:AddLine("Left-click: open controller", 1, 1, 1)
|
|
GameTooltip:AddLine("Right-click: stop / resume", 1, 1, 1)
|
|
GameTooltip:AddLine("Shift-drag: reposition", 1, 1, 1)
|
|
GameTooltip:Show()
|
|
end)
|
|
|
|
button:SetScript("OnLeave", function()
|
|
GameTooltip:Hide()
|
|
end)
|
|
end
|
|
|
|
function WowRadio:CreateController()
|
|
if WowRadioFrame then
|
|
return
|
|
end
|
|
|
|
local f = CreateFrame("Frame", "WowRadioFrame", UIParent)
|
|
f:SetWidth(WR_FRAME_WIDTH)
|
|
f:SetHeight(WR_FRAME_HEIGHT)
|
|
local savedScale = WowRadio.db.account.ui.scale or 1.0
|
|
f:SetScale(savedScale)
|
|
local uiPos = WowRadio.db.account.ui
|
|
f:SetPoint(uiPos.framePoint or "CENTER", UIParent, uiPos.frameRelPoint or "CENTER", uiPos.frameX or 0, uiPos.frameY or 0)
|
|
f:SetFrameStrata("DIALOG")
|
|
f:EnableMouse(true)
|
|
f:SetMovable(true)
|
|
f:RegisterForDrag("LeftButton")
|
|
f:SetBackdrop({
|
|
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
|
|
tile = true,
|
|
tileSize = 16,
|
|
edgeSize = 16,
|
|
insets = { left = 5, right = 5, top = 5, bottom = 5 }
|
|
})
|
|
|
|
local bgLeft = f:CreateTexture(nil, "BACKGROUND")
|
|
bgLeft:SetTexture(WR_BACKDROP_TEXTURE_LEFT)
|
|
bgLeft:SetPoint("TOPLEFT", f, "TOPLEFT", 5, -5)
|
|
bgLeft:SetPoint("BOTTOMRIGHT", f, "BOTTOM", 0, 5)
|
|
bgLeft:SetTexCoord(0, 1, 0, 1)
|
|
f.bgTextureLeft = bgLeft
|
|
|
|
local bgRight = f:CreateTexture(nil, "BACKGROUND")
|
|
bgRight:SetTexture(WR_BACKDROP_TEXTURE_RIGHT)
|
|
bgRight:SetPoint("TOPLEFT", f, "TOP", 0, -5)
|
|
bgRight:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", -5, 5)
|
|
bgRight:SetTexCoord(0, 1, 0, 1)
|
|
f.bgTextureRight = bgRight
|
|
|
|
f:Hide()
|
|
|
|
f:SetScript("OnDragStart", function()
|
|
this:StartMoving()
|
|
end)
|
|
|
|
f:SetScript("OnDragStop", function()
|
|
this:StopMovingOrSizing()
|
|
local pt, _, rpt, x, y = this:GetPoint(1)
|
|
WowRadio.db.account.ui.framePoint = pt
|
|
WowRadio.db.account.ui.frameRelPoint = rpt
|
|
WowRadio.db.account.ui.frameX = x
|
|
WowRadio.db.account.ui.frameY = y
|
|
end)
|
|
|
|
local close = CreateFrame("Button", nil, f, "UIPanelButtonTemplate")
|
|
if close.SetFrameLevel then
|
|
close:SetFrameLevel(f:GetFrameLevel() + 20)
|
|
end
|
|
close:SetWidth(22)
|
|
close:SetHeight(18)
|
|
close:SetPoint("TOPRIGHT", f, "TOPRIGHT", -8, -6)
|
|
close:SetText("x")
|
|
close:SetScript("OnClick", function()
|
|
WowRadio:HideController()
|
|
end)
|
|
f.closeButton = close
|
|
|
|
local minimizeBtn = CreateFrame("Button", nil, f, "UIPanelButtonTemplate")
|
|
if minimizeBtn.SetFrameLevel then
|
|
minimizeBtn:SetFrameLevel(f:GetFrameLevel() + 20)
|
|
end
|
|
minimizeBtn:SetWidth(22)
|
|
minimizeBtn:SetHeight(18)
|
|
minimizeBtn:SetPoint("TOPRIGHT", f, "TOPRIGHT", -32, -6)
|
|
minimizeBtn:SetText("_")
|
|
minimizeBtn:SetScript("OnClick", function()
|
|
WowRadio:ToggleMiniPlayer()
|
|
end)
|
|
f.minimizeButton = minimizeBtn
|
|
|
|
local fadeBtn = WowRadio:CreateWRButton(f, "Fade", 8, -6, 46, 18, function()
|
|
WowRadio:ToggleFadeOnMove()
|
|
end)
|
|
if fadeBtn.SetFrameLevel then
|
|
fadeBtn:SetFrameLevel(f:GetFrameLevel() + 20)
|
|
end
|
|
f.fadeButton = fadeBtn
|
|
|
|
local muteBtn = WowRadio:CreateWRButton(f, "Mute", 0, 0, 46, 18, function()
|
|
WowRadio:ToggleMute()
|
|
end)
|
|
if muteBtn.SetFrameLevel then
|
|
muteBtn:SetFrameLevel(f:GetFrameLevel() + 20)
|
|
end
|
|
f.muteButton = muteBtn
|
|
|
|
local sizer = CreateFrame("Button", nil, f)
|
|
sizer:SetWidth(16)
|
|
sizer:SetHeight(16)
|
|
sizer:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", 0, 0)
|
|
if sizer.SetFrameLevel then
|
|
sizer:SetFrameLevel(f:GetFrameLevel() + 20)
|
|
end
|
|
sizer:SetNormalTexture("Interface\\ChatFrame\\UI-ChatIM-SizeGrabber-Up")
|
|
sizer:SetHighlightTexture("Interface\\ChatFrame\\UI-ChatIM-SizeGrabber-Highlight")
|
|
sizer:SetPushedTexture("Interface\\ChatFrame\\UI-ChatIM-SizeGrabber-Down")
|
|
local sizerDragging = false
|
|
local sizerStartX, sizerStartScale
|
|
|
|
sizer:SetScript("OnMouseDown", function()
|
|
sizerDragging = true
|
|
sizerStartX = GetCursorPosition()
|
|
sizerStartScale = WowRadioFrame:GetScale()
|
|
end)
|
|
|
|
sizer:SetScript("OnMouseUp", function()
|
|
sizerDragging = false
|
|
WowRadio.db.account.ui.scale = WowRadioFrame:GetScale()
|
|
end)
|
|
|
|
sizer:SetScript("OnUpdate", function()
|
|
if not sizerDragging then return end
|
|
local cx = GetCursorPosition()
|
|
local newScale = sizerStartScale + (cx - sizerStartX) * 0.002
|
|
if newScale < 0.5 then newScale = 0.5 end
|
|
if newScale > 2.0 then newScale = 2.0 end
|
|
WowRadioFrame:SetScale(newScale)
|
|
end)
|
|
f.sizer = sizer
|
|
|
|
local wasMoving = false
|
|
local lastMX, lastMY = 0, 0
|
|
local moveCheckTimer = 0
|
|
local moveWatcher = CreateFrame("Frame", nil, UIParent)
|
|
moveWatcher:SetScript("OnUpdate", function()
|
|
moveCheckTimer = moveCheckTimer + arg1
|
|
if moveCheckTimer < 0.1 then return end
|
|
moveCheckTimer = 0
|
|
|
|
if not WowRadioFrame or not WowRadioFrame:IsVisible() then return end
|
|
if not WowRadio.db.account.fadeOnMove then
|
|
if wasMoving then
|
|
WowRadioFrame:SetAlpha(1)
|
|
wasMoving = false
|
|
end
|
|
return
|
|
end
|
|
local ok, mx, my = pcall(GetPlayerMapPosition, "player")
|
|
if not ok or not mx or not my or (mx == 0 and my == 0) then return end
|
|
local moving = (mx ~= lastMX or my ~= lastMY)
|
|
lastMX, lastMY = mx, my
|
|
if moving and not wasMoving then
|
|
WowRadioFrame:SetAlpha(0.25)
|
|
wasMoving = true
|
|
elseif not moving and wasMoving then
|
|
WowRadioFrame:SetAlpha(1)
|
|
wasMoving = false
|
|
end
|
|
end)
|
|
f.moveWatcher = moveWatcher
|
|
|
|
local nowBack = f:CreateTexture(nil, "ARTWORK")
|
|
nowBack:SetTexture(0, 0, 0, 0.82)
|
|
nowBack:SetPoint("TOPLEFT", f, "TOPLEFT", 20, -364)
|
|
nowBack:SetPoint("BOTTOMRIGHT", f, "TOPRIGHT", -20, -386)
|
|
f.nowBack = nowBack
|
|
|
|
local nowStatus = f:CreateFontString(nil, "OVERLAY", "GameFontNormal")
|
|
nowStatus:SetPoint("TOPLEFT", f, "TOPLEFT", 34, -369)
|
|
nowStatus:SetWidth(72)
|
|
nowStatus:SetJustifyH("LEFT")
|
|
nowStatus:SetText("|cffffffffStopped:|r")
|
|
f.nowStatusText = nowStatus
|
|
|
|
local nowStation = f:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
|
|
nowStation:SetPoint("LEFT", nowStatus, "RIGHT", 4, 0)
|
|
nowStation:SetWidth(320)
|
|
nowStation:SetJustifyH("LEFT")
|
|
nowStation:SetText("|cff00ff00[1] Everlook Broadcasting Co.|r")
|
|
f.nowStationText = nowStation
|
|
|
|
f.nowText = nowStation
|
|
|
|
f.prevButton = WowRadio:CreateWRButton(f, "<<", 205, -100, 46, 20, function()
|
|
WowRadio:prev()
|
|
end)
|
|
|
|
f.playButton = WowRadio:CreateWRButton(f, ">", 254, -100, 46, 20, function()
|
|
WowRadio:play()
|
|
end)
|
|
|
|
f.stopButton = WowRadio:CreateWRButton(f, "[ ]", 303, -100, 46, 20, function()
|
|
WowRadio:stop()
|
|
end)
|
|
|
|
f.nextButton = WowRadio:CreateWRButton(f, ">>", 352, -100, 46, 20, function()
|
|
WowRadio:next()
|
|
end)
|
|
|
|
f.randomButton = WowRadio:CreateWRButton(f, "?", 401, -100, 54, 20, function()
|
|
WowRadio:rnd()
|
|
end)
|
|
|
|
f.autoButton = WowRadio:CreateWRButton(f, "Auto", 458, -100, 82, 20, function()
|
|
WowRadio:toggleAutostart()
|
|
end)
|
|
|
|
local volumeLabel = f:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
|
|
volumeLabel:SetPoint("TOPLEFT", f, "TOPLEFT", 20, -105)
|
|
volumeLabel:SetText("Vol")
|
|
f.volumeLabel = volumeLabel
|
|
|
|
local volume = CreateFrame("Slider", "WowRadioVolumeSlider", f, "OptionsSliderTemplate")
|
|
if volume.SetFrameLevel then
|
|
volume:SetFrameLevel(f:GetFrameLevel() + 10)
|
|
end
|
|
volume:SetWidth(108)
|
|
volume:SetHeight(14)
|
|
volume:SetPoint("TOPLEFT", f, "TOPLEFT", 44, -102)
|
|
volume:SetMinMaxValues(0, 1)
|
|
volume:SetValueStep(0.05)
|
|
|
|
local low = getglobal("WowRadioVolumeSliderLow")
|
|
local high = getglobal("WowRadioVolumeSliderHigh")
|
|
local text = getglobal("WowRadioVolumeSliderText")
|
|
|
|
if low then low:SetText("") end
|
|
if high then high:SetText("") end
|
|
if text then text:SetText("") end
|
|
|
|
local volumeValue = f:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
|
|
volumeValue:SetPoint("TOPLEFT", f, "TOPLEFT", 158, -105)
|
|
volumeValue:SetWidth(40)
|
|
volumeValue:SetJustifyH("LEFT")
|
|
f.volumeValueText = volumeValue
|
|
|
|
volume:SetScript("OnValueChanged", function()
|
|
WowRadio:ApplyVolume(this:GetValue(), true)
|
|
end)
|
|
|
|
volume:SetScript("OnMouseUp", function()
|
|
wr_msg(WR_CHAT_PREFIX.."Volume set to "..math.floor((WowRadio:GetVolume() * 100) + 0.5).."%.")
|
|
end)
|
|
|
|
volume:SetValue(WowRadio:GetVolume())
|
|
f.volumeSlider = volume
|
|
|
|
f.tabButtons = {}
|
|
|
|
local tabX = 20
|
|
local tabY = -130
|
|
for _, tabInfo in ipairs(WR_TABS) do
|
|
local tabKey = tabInfo.key
|
|
local tabButton = WowRadio:CreateWRButton(f, tabInfo.label, tabX, tabY, tabInfo.width, 20, function()
|
|
WowRadio:SetUITab(tabKey)
|
|
end)
|
|
|
|
f.tabButtons[tabInfo.key] = tabButton
|
|
tabX = tabX + tabInfo.width + 5
|
|
end
|
|
|
|
f.rows = {}
|
|
|
|
for i = 1, WR_LINES_PER_PAGE do
|
|
local y = -158 - ((i - 1) * 25)
|
|
|
|
local star = WowRadio:CreateWRButton(f, "+", 20, y, 24, 20, function()
|
|
if this.stationIndex then
|
|
WowRadio:ToggleFavorite(this.stationIndex)
|
|
end
|
|
end)
|
|
|
|
local row = WowRadio:CreateWRButton(f, "", 48, y, 485, 20, function()
|
|
if this.stationIndex then
|
|
WowRadio:play(this.stationIndex)
|
|
end
|
|
end)
|
|
|
|
f.rows[i] = {
|
|
star = star,
|
|
row = row,
|
|
}
|
|
end
|
|
|
|
f.pageText = f:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
|
|
f.pageText:SetPoint("TOPLEFT", f, "TOPLEFT", 20, -399)
|
|
f.pageText:SetWidth(330)
|
|
f.pageText:SetJustifyH("LEFT")
|
|
f.pageText:SetText("Page 1")
|
|
|
|
f.customButton = WowRadio:CreateWRButton(f, "Custom", 355, -391, 88, 22, function()
|
|
WowRadio:ShowCustomUrlDialog()
|
|
end)
|
|
|
|
f.pagePrev = WowRadio:CreateWRButton(f, "<", 449, -391, 44, 22, function()
|
|
WowRadio:PageBack()
|
|
end)
|
|
|
|
f.pageNext = WowRadio:CreateWRButton(f, ">", 496, -391, 44, 22, function()
|
|
WowRadio:PageForward()
|
|
end)
|
|
|
|
local urlDialog = CreateFrame("Frame", "WowRadioUrlDialog", UIParent)
|
|
urlDialog:SetWidth(430)
|
|
urlDialog:SetHeight(95)
|
|
urlDialog:SetFrameStrata("FULLSCREEN_DIALOG")
|
|
urlDialog:SetPoint("CENTER", UIParent, "CENTER")
|
|
urlDialog:SetMovable(true)
|
|
urlDialog:EnableMouse(true)
|
|
urlDialog:RegisterForDrag("LeftButton")
|
|
urlDialog:SetScript("OnDragStart", function() this:StartMoving() end)
|
|
urlDialog:SetScript("OnDragStop", function() this:StopMovingOrSizing() end)
|
|
urlDialog:SetBackdrop({
|
|
bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background",
|
|
edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border",
|
|
tile = true, tileSize = 32, edgeSize = 32,
|
|
insets = { left = 11, right = 12, top = 12, bottom = 11 },
|
|
})
|
|
urlDialog:Hide()
|
|
|
|
local urlLabel = urlDialog:CreateFontString(nil, "OVERLAY", "GameFontNormal")
|
|
urlLabel:SetPoint("TOPLEFT", urlDialog, "TOPLEFT", 16, -14)
|
|
urlLabel:SetText("Custom Stream URL:")
|
|
|
|
local urlEditBox = CreateFrame("EditBox", "WowRadioUrlEditBox", urlDialog, "InputBoxTemplate")
|
|
urlEditBox:SetWidth(390)
|
|
urlEditBox:SetHeight(20)
|
|
urlEditBox:SetPoint("TOPLEFT", urlDialog, "TOPLEFT", 16, -34)
|
|
urlEditBox:SetMaxLetters(250)
|
|
urlEditBox:SetAutoFocus(false)
|
|
urlEditBox:SetScript("OnEscapePressed", function()
|
|
urlDialog:Hide()
|
|
end)
|
|
urlEditBox:SetScript("OnEnterPressed", function()
|
|
local text = this:GetText()
|
|
if text and text ~= "" then WowRadio:url(text) end
|
|
urlDialog:Hide()
|
|
end)
|
|
|
|
local urlPlay = CreateFrame("Button", nil, urlDialog, "UIPanelButtonTemplate")
|
|
urlPlay:SetWidth(80)
|
|
urlPlay:SetHeight(22)
|
|
urlPlay:SetText("Play")
|
|
urlPlay:SetPoint("BOTTOMRIGHT", urlDialog, "BOTTOMRIGHT", -16, 10)
|
|
urlPlay:SetScript("OnClick", function()
|
|
local text = WowRadioUrlEditBox:GetText()
|
|
if text and text ~= "" then WowRadio:url(text) end
|
|
urlDialog:Hide()
|
|
end)
|
|
|
|
local urlCancel = CreateFrame("Button", nil, urlDialog, "UIPanelButtonTemplate")
|
|
urlCancel:SetWidth(80)
|
|
urlCancel:SetHeight(22)
|
|
urlCancel:SetText("Cancel")
|
|
urlCancel:SetPoint("RIGHT", urlPlay, "LEFT", -5, 0)
|
|
urlCancel:SetScript("OnClick", function()
|
|
urlDialog:Hide()
|
|
end)
|
|
|
|
f.urlDialog = urlDialog
|
|
f.urlEditBox = urlEditBox
|
|
|
|
WowRadio:ApplyVolume(WowRadio:GetVolume(), true)
|
|
WowRadio:ApplyUIMode()
|
|
end
|
|
|
|
function WowRadio:CreateWRButton(parent, text, x, y, width, height, onclick)
|
|
local b = CreateFrame("Button", nil, parent, "UIPanelButtonTemplate")
|
|
|
|
if parent and parent.GetFrameLevel and b.SetFrameLevel then
|
|
b:SetFrameLevel(parent:GetFrameLevel() + 10)
|
|
end
|
|
|
|
b:SetWidth(width)
|
|
b:SetHeight(height)
|
|
b:SetPoint("TOPLEFT", parent, "TOPLEFT", x, y)
|
|
b:SetText(text)
|
|
b:SetScript("OnClick", onclick)
|
|
return b
|
|
end
|
|
|
|
function WowRadio:UpdateTabButtons()
|
|
if not WowRadioFrame or not WowRadioFrame.tabButtons then
|
|
return
|
|
end
|
|
|
|
local currentTab = self.db.account.ui.tab or "ALL"
|
|
if WowRadioFrame.activeTabKey == currentTab then
|
|
return
|
|
end
|
|
|
|
for _, tabInfo in ipairs(WR_TABS) do
|
|
local b = WowRadioFrame.tabButtons[tabInfo.key]
|
|
|
|
if b then
|
|
if currentTab == tabInfo.key then
|
|
b:SetText("|cff7FFF7F"..tabInfo.label.."|r")
|
|
else
|
|
b:SetText(tabInfo.label)
|
|
end
|
|
end
|
|
end
|
|
WowRadioFrame.activeTabKey = currentTab
|
|
end
|
|
|
|
function WowRadio:SetUITab(tab)
|
|
self.db.account.ui.tab = tab
|
|
self.db.account.ui.page = 1
|
|
WowRadio:RefreshStationPanel(true)
|
|
end
|
|
|
|
function WowRadio:PageBack()
|
|
local page = tonumber(self.db.account.ui.page) or 1
|
|
page = page - 1
|
|
|
|
if page < 1 then
|
|
page = 1
|
|
end
|
|
|
|
self.db.account.ui.page = page
|
|
WowRadio:RefreshStationPanel(false)
|
|
end
|
|
|
|
function WowRadio:PageForward()
|
|
local page = tonumber(self.db.account.ui.page) or 1
|
|
self.db.account.ui.page = page + 1
|
|
WowRadio:RefreshStationPanel(false)
|
|
end
|
|
|
|
function WowRadio:IsFavorite(index)
|
|
if self.db.account.favorites == nil then
|
|
self.db.account.favorites = {}
|
|
end
|
|
|
|
return self.db.account.favorites[tostring(index)] == true
|
|
end
|
|
|
|
function WowRadio:ToggleFavorite(index)
|
|
if self.db.account.favorites == nil then
|
|
self.db.account.favorites = {}
|
|
end
|
|
|
|
local key = tostring(index)
|
|
if self.db.account.favorites[key] then
|
|
self.db.account.favorites[key] = nil
|
|
else
|
|
self.db.account.favorites[key] = true
|
|
end
|
|
|
|
WowRadio:RefreshStationPanel(false)
|
|
end
|
|
|
|
function WowRadio:GetStationCategory(index)
|
|
if stationCategory and stationCategory[index] then
|
|
return stationCategory[index]
|
|
end
|
|
|
|
return "VARIETY"
|
|
end
|
|
|
|
function WowRadio:GetVisibleStations()
|
|
local visible = {}
|
|
local tab = self.db.account.ui.tab or "ALL"
|
|
|
|
if tab == "CUSTOM" or tab == "TEST" then
|
|
tab = "ALL"
|
|
self.db.account.ui.tab = "ALL"
|
|
end
|
|
|
|
for i = 1, table.getn(stationUrl) do
|
|
local include = true
|
|
|
|
if tab == "FAV" and not WowRadio:IsFavorite(i) then
|
|
include = false
|
|
elseif tab ~= "ALL" and tab ~= "FAV" then
|
|
if WowRadio:GetStationCategory(i) ~= tab then
|
|
include = false
|
|
end
|
|
end
|
|
|
|
if include then
|
|
table.insert(visible, i)
|
|
end
|
|
end
|
|
|
|
return visible
|
|
end
|
|
|
|
function WowRadio:RefreshNowPlaying()
|
|
if not WowRadioFrame or not WowRadioFrame:IsVisible() then
|
|
return
|
|
end
|
|
|
|
local f = WowRadioFrame
|
|
local state = "Playing"
|
|
if stopped == true then
|
|
state = "Stopped"
|
|
end
|
|
|
|
if f.nowStatusText then
|
|
f.nowStatusText:SetText("|cffffffff"..state..":|r")
|
|
end
|
|
|
|
if f.nowStationText then
|
|
if customUrl == nil then
|
|
local station = WowRadio:getStation()
|
|
f.nowStationText:SetText("|cff00ff00["..station.."] "..wr_trim(WowRadio:getStationShortName(station), 40).."|r")
|
|
else
|
|
f.nowStationText:SetText("|cff00ff00[custom] "..wr_trim(customUrl, 40).."|r")
|
|
end
|
|
elseif f.nowText then
|
|
if customUrl == nil then
|
|
local station = WowRadio:getStation()
|
|
f.nowText:SetText("|cffffffff"..state..":|r |cff00ff00["..station.."] "..WowRadio:getStationShortName(station).."|r")
|
|
else
|
|
f.nowText:SetText("|cffffffff"..state..":|r |cff00ff00[custom] "..wr_trim(customUrl, 80).."|r")
|
|
end
|
|
end
|
|
end
|
|
|
|
function WowRadio:RefreshAutoButton()
|
|
if not WowRadioFrame or not WowRadioFrame:IsVisible() or not WowRadioFrame.autoButton then
|
|
return
|
|
end
|
|
|
|
if self.db.account.autostart == true then
|
|
WowRadioFrame.autoButton:SetText("Auto: On")
|
|
else
|
|
WowRadioFrame.autoButton:SetText("Auto: Off")
|
|
end
|
|
end
|
|
|
|
function WowRadio:RefreshFadeButton()
|
|
if not WowRadioFrame or not WowRadioFrame:IsVisible() or not WowRadioFrame.fadeButton then
|
|
return
|
|
end
|
|
|
|
if self.db.account.fadeOnMove then
|
|
WowRadioFrame.fadeButton:SetText("|cff7FFF7FFader|r")
|
|
else
|
|
WowRadioFrame.fadeButton:SetText("Fade")
|
|
end
|
|
end
|
|
|
|
function WowRadio:RefreshMuteButton()
|
|
if not WowRadioFrame or not WowRadioFrame:IsVisible() or not WowRadioFrame.muteButton then
|
|
return
|
|
end
|
|
|
|
if self.db.account.muted then
|
|
WowRadioFrame.muteButton:SetText("|cffFF5555Mute|r")
|
|
else
|
|
WowRadioFrame.muteButton:SetText("Mute")
|
|
end
|
|
end
|
|
|
|
function WowRadio:RefreshVolumeControl()
|
|
if not WowRadioFrame or not WowRadioFrame:IsVisible() or not WowRadioFrame.volumeSlider then
|
|
return
|
|
end
|
|
|
|
local v = WowRadio:GetVolume()
|
|
if WowRadioFrame.volumeSlider:GetValue() ~= v then
|
|
WowRadioFrame.volumeSlider:SetValue(v)
|
|
end
|
|
end
|
|
|
|
function WowRadio:RefreshStationPanel(updateTabs)
|
|
if not WowRadioFrame or not WowRadioFrame:IsVisible() then
|
|
return
|
|
end
|
|
|
|
if self.db.account.ui.compact == true then
|
|
return
|
|
end
|
|
|
|
if updateTabs ~= false then
|
|
WowRadio:UpdateTabButtons()
|
|
end
|
|
WowRadio:ShowStationPanel()
|
|
end
|
|
|
|
function WowRadio:RefreshUI()
|
|
if not WowRadioFrame or not WowRadioFrame:IsVisible() then
|
|
return
|
|
end
|
|
|
|
local tab = self.db.account.ui.tab or "ALL"
|
|
if tab == "CUSTOM" or tab == "TEST" then
|
|
self.db.account.ui.tab = "ALL"
|
|
WowRadioFrame.activeTabKey = nil
|
|
end
|
|
|
|
WowRadio:RefreshNowPlaying()
|
|
WowRadio:RefreshAutoButton()
|
|
WowRadio:RefreshFadeButton()
|
|
WowRadio:RefreshMuteButton()
|
|
WowRadio:RefreshVolumeControl()
|
|
WowRadio:RefreshStationPanel(true)
|
|
end
|
|
|
|
function WowRadio:ShowStationPanel()
|
|
local f = WowRadioFrame
|
|
|
|
if self.db.account.ui.compact == true then
|
|
for i = 1, WR_LINES_PER_PAGE do
|
|
f.rows[i].star:Hide()
|
|
f.rows[i].row:Hide()
|
|
end
|
|
f.pageText:Hide()
|
|
f.pagePrev:Hide()
|
|
f.pageNext:Hide()
|
|
return
|
|
end
|
|
|
|
f.pageText:Show()
|
|
f.pagePrev:Show()
|
|
f.pageNext:Show()
|
|
|
|
local visible = WowRadio:GetVisibleStations()
|
|
local total = table.getn(visible)
|
|
local page = tonumber(self.db.account.ui.page) or 1
|
|
local maxPage = math.ceil(total / WR_LINES_PER_PAGE)
|
|
|
|
if maxPage < 1 then
|
|
maxPage = 1
|
|
end
|
|
|
|
if page > maxPage then
|
|
page = maxPage
|
|
end
|
|
|
|
if page < 1 then
|
|
page = 1
|
|
end
|
|
|
|
self.db.account.ui.page = page
|
|
|
|
local startIndex = ((page - 1) * WR_LINES_PER_PAGE) + 1
|
|
|
|
for rowIndex = 1, WR_LINES_PER_PAGE do
|
|
local stationListIndex = startIndex + rowIndex - 1
|
|
local stationIndex = visible[stationListIndex]
|
|
local row = f.rows[rowIndex]
|
|
|
|
if stationIndex then
|
|
local name = "["..stationIndex.."] "..WowRadio:getStationShortName(stationIndex)
|
|
|
|
row.star:Show()
|
|
row.row:Show()
|
|
|
|
row.star.stationIndex = stationIndex
|
|
row.row.stationIndex = stationIndex
|
|
|
|
if WowRadio:IsFavorite(stationIndex) then
|
|
row.star:SetText("-")
|
|
else
|
|
row.star:SetText("+")
|
|
end
|
|
|
|
row.row:SetText(wr_trim(name, 70))
|
|
else
|
|
row.star:Hide()
|
|
row.row:Hide()
|
|
|
|
row.star.stationIndex = nil
|
|
row.row.stationIndex = nil
|
|
end
|
|
end
|
|
|
|
f.pageText:SetText("Page "..page.." / "..maxPage.." Stations: "..total)
|
|
end
|
|
|
|
function WowRadio:ToggleMiniPlayer()
|
|
self.db.account.ui.compact = not self.db.account.ui.compact
|
|
WowRadio:ApplyUIMode()
|
|
WowRadio:RefreshUI()
|
|
end
|
|
|
|
function WowRadio:ToggleMute()
|
|
self.db.account.muted = not self.db.account.muted
|
|
if self.db.account.muted then
|
|
WowRadio:SafeSetCVar("EnableMusic", "1")
|
|
WowRadio:SafeSetCVar("Sound_EnableMusic", "1")
|
|
WowRadio:SafeSetCVar("MusicVolume", 0)
|
|
WowRadio:SafeSetCVar("Sound_MusicVolume", 0)
|
|
wr_msg(WR_CHAT_PREFIX.."Muted.")
|
|
else
|
|
WowRadio:ApplyVolume(WowRadio:GetVolume(), true)
|
|
wr_msg(WR_CHAT_PREFIX.."Unmuted.")
|
|
end
|
|
WowRadio:RefreshMuteButton()
|
|
end
|
|
|
|
function WowRadio:ApplyUIMode()
|
|
if not WowRadioFrame then return end
|
|
local f = WowRadioFrame
|
|
local compact = self.db.account.ui.compact == true
|
|
|
|
if compact then
|
|
f:SetWidth(WR_MINI_WIDTH)
|
|
f:SetHeight(WR_MINI_HEIGHT)
|
|
|
|
f.bgTextureLeft:ClearAllPoints()
|
|
f.bgTextureLeft:SetPoint("TOPLEFT", f, "TOPLEFT", 5, -5)
|
|
f.bgTextureLeft:SetPoint("BOTTOMRIGHT", f, "BOTTOM", 0, 5)
|
|
|
|
f.bgTextureRight:ClearAllPoints()
|
|
f.bgTextureRight:SetPoint("TOPLEFT", f, "TOP", 0, -5)
|
|
f.bgTextureRight:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", -5, 5)
|
|
|
|
f.volumeLabel:Hide()
|
|
f.volumeSlider:ClearAllPoints()
|
|
f.volumeSlider:SetPoint("TOPLEFT", f, "TOPLEFT", 8, -38)
|
|
f.volumeSlider:SetWidth(88)
|
|
f.volumeSlider:Show()
|
|
|
|
f.volumeValueText:ClearAllPoints()
|
|
f.volumeValueText:SetPoint("TOPLEFT", f, "TOPLEFT", 100, -43)
|
|
f.volumeValueText:SetWidth(34)
|
|
f.volumeValueText:Show()
|
|
|
|
f.muteButton:ClearAllPoints()
|
|
f.muteButton:SetPoint("TOPLEFT", f, "TOPLEFT", 135, -38)
|
|
f.muteButton:SetWidth(38)
|
|
f.muteButton:SetHeight(20)
|
|
f.muteButton:Show()
|
|
|
|
f.prevButton:ClearAllPoints()
|
|
f.prevButton:SetPoint("TOPLEFT", f, "TOPLEFT", 193, -38)
|
|
f.prevButton:SetWidth(42)
|
|
f.prevButton:SetHeight(20)
|
|
f.prevButton:Show()
|
|
|
|
f.playButton:ClearAllPoints()
|
|
f.playButton:SetPoint("TOPLEFT", f, "TOPLEFT", 237, -38)
|
|
f.playButton:SetWidth(42)
|
|
f.playButton:SetHeight(20)
|
|
f.playButton:Show()
|
|
|
|
f.stopButton:ClearAllPoints()
|
|
f.stopButton:SetPoint("TOPLEFT", f, "TOPLEFT", 281, -38)
|
|
f.stopButton:SetWidth(42)
|
|
f.stopButton:SetHeight(20)
|
|
f.stopButton:Show()
|
|
|
|
f.nextButton:ClearAllPoints()
|
|
f.nextButton:SetPoint("TOPLEFT", f, "TOPLEFT", 325, -38)
|
|
f.nextButton:SetWidth(42)
|
|
f.nextButton:SetHeight(20)
|
|
f.nextButton:Show()
|
|
|
|
f.nowBack:ClearAllPoints()
|
|
f.nowBack:SetPoint("TOPLEFT", f, "TOPLEFT", 6, -62)
|
|
f.nowBack:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", -6, 10)
|
|
|
|
f.nowStatusText:ClearAllPoints()
|
|
f.nowStatusText:SetPoint("TOPLEFT", f, "TOPLEFT", 10, -66)
|
|
f.nowStatusText:SetWidth(58)
|
|
|
|
f.nowStationText:ClearAllPoints()
|
|
f.nowStationText:SetPoint("LEFT", f.nowStatusText, "RIGHT", 4, 0)
|
|
f.nowStationText:SetWidth(270)
|
|
|
|
f.randomButton:Hide()
|
|
f.autoButton:Hide()
|
|
f.customButton:Hide()
|
|
f.pageText:Hide()
|
|
f.pagePrev:Hide()
|
|
f.pageNext:Hide()
|
|
if f.sizer then f.sizer:Hide() end
|
|
|
|
for _, tabInfo in ipairs(WR_TABS) do
|
|
local b = f.tabButtons[tabInfo.key]
|
|
if b then b:Hide() end
|
|
end
|
|
|
|
for i = 1, WR_LINES_PER_PAGE do
|
|
f.rows[i].star:Hide()
|
|
f.rows[i].row:Hide()
|
|
end
|
|
else
|
|
f:SetWidth(WR_FRAME_WIDTH)
|
|
f:SetHeight(WR_FRAME_HEIGHT)
|
|
|
|
f.bgTextureLeft:ClearAllPoints()
|
|
f.bgTextureLeft:SetPoint("TOPLEFT", f, "TOPLEFT", 5, -5)
|
|
f.bgTextureLeft:SetPoint("BOTTOMRIGHT", f, "BOTTOM", 0, 5)
|
|
|
|
f.bgTextureRight:ClearAllPoints()
|
|
f.bgTextureRight:SetPoint("TOPLEFT", f, "TOP", 0, -5)
|
|
f.bgTextureRight:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", -5, 5)
|
|
|
|
f.muteButton:ClearAllPoints()
|
|
f.muteButton:SetPoint("TOPLEFT", f, "TOPLEFT", 20, -80)
|
|
f.muteButton:SetWidth(46)
|
|
f.muteButton:SetHeight(18)
|
|
f.muteButton:Show()
|
|
|
|
f.volumeLabel:ClearAllPoints()
|
|
f.volumeLabel:SetPoint("TOPLEFT", f, "TOPLEFT", 20, -105)
|
|
f.volumeLabel:Show()
|
|
|
|
f.volumeSlider:ClearAllPoints()
|
|
f.volumeSlider:SetPoint("TOPLEFT", f, "TOPLEFT", 44, -102)
|
|
f.volumeSlider:SetWidth(108)
|
|
f.volumeSlider:Show()
|
|
|
|
f.volumeValueText:ClearAllPoints()
|
|
f.volumeValueText:SetPoint("TOPLEFT", f, "TOPLEFT", 158, -105)
|
|
f.volumeValueText:SetWidth(40)
|
|
f.volumeValueText:Show()
|
|
|
|
f.prevButton:ClearAllPoints()
|
|
f.prevButton:SetPoint("TOPLEFT", f, "TOPLEFT", 205, -100)
|
|
f.prevButton:SetWidth(46)
|
|
f.prevButton:SetHeight(20)
|
|
f.prevButton:Show()
|
|
|
|
f.playButton:ClearAllPoints()
|
|
f.playButton:SetPoint("TOPLEFT", f, "TOPLEFT", 254, -100)
|
|
f.playButton:SetWidth(46)
|
|
f.playButton:SetHeight(20)
|
|
f.playButton:Show()
|
|
|
|
f.stopButton:ClearAllPoints()
|
|
f.stopButton:SetPoint("TOPLEFT", f, "TOPLEFT", 303, -100)
|
|
f.stopButton:SetWidth(46)
|
|
f.stopButton:SetHeight(20)
|
|
f.stopButton:Show()
|
|
|
|
f.nextButton:ClearAllPoints()
|
|
f.nextButton:SetPoint("TOPLEFT", f, "TOPLEFT", 352, -100)
|
|
f.nextButton:SetWidth(46)
|
|
f.nextButton:SetHeight(20)
|
|
f.nextButton:Show()
|
|
|
|
f.randomButton:ClearAllPoints()
|
|
f.randomButton:SetPoint("TOPLEFT", f, "TOPLEFT", 401, -100)
|
|
f.randomButton:SetWidth(54)
|
|
f.randomButton:SetHeight(20)
|
|
f.randomButton:Show()
|
|
|
|
f.autoButton:ClearAllPoints()
|
|
f.autoButton:SetPoint("TOPLEFT", f, "TOPLEFT", 458, -100)
|
|
f.autoButton:SetWidth(82)
|
|
f.autoButton:SetHeight(20)
|
|
f.autoButton:Show()
|
|
|
|
f.nowBack:ClearAllPoints()
|
|
f.nowBack:SetPoint("TOPLEFT", f, "TOPLEFT", 20, -364)
|
|
f.nowBack:SetPoint("BOTTOMRIGHT", f, "TOPRIGHT", -20, -386)
|
|
|
|
f.nowStatusText:ClearAllPoints()
|
|
f.nowStatusText:SetPoint("TOPLEFT", f, "TOPLEFT", 34, -369)
|
|
f.nowStatusText:SetWidth(72)
|
|
|
|
f.nowStationText:ClearAllPoints()
|
|
f.nowStationText:SetPoint("LEFT", f.nowStatusText, "RIGHT", 4, 0)
|
|
f.nowStationText:SetWidth(320)
|
|
|
|
f.customButton:ClearAllPoints()
|
|
f.customButton:SetPoint("TOPLEFT", f, "TOPLEFT", 355, -391)
|
|
f.customButton:SetWidth(88)
|
|
f.customButton:SetHeight(22)
|
|
f.customButton:Show()
|
|
|
|
f.pagePrev:ClearAllPoints()
|
|
f.pagePrev:SetPoint("TOPLEFT", f, "TOPLEFT", 449, -391)
|
|
f.pagePrev:SetWidth(44)
|
|
f.pagePrev:SetHeight(22)
|
|
f.pagePrev:Show()
|
|
|
|
f.pageNext:ClearAllPoints()
|
|
f.pageNext:SetPoint("TOPLEFT", f, "TOPLEFT", 496, -391)
|
|
f.pageNext:SetWidth(44)
|
|
f.pageNext:SetHeight(22)
|
|
f.pageNext:Show()
|
|
|
|
f.pageText:ClearAllPoints()
|
|
f.pageText:SetPoint("TOPLEFT", f, "TOPLEFT", 20, -399)
|
|
f.pageText:SetWidth(330)
|
|
f.pageText:Show()
|
|
|
|
if f.sizer then f.sizer:Show() end
|
|
|
|
local tabX = 20
|
|
local tabY = -130
|
|
for _, tabInfo in ipairs(WR_TABS) do
|
|
local b = f.tabButtons[tabInfo.key]
|
|
if b then
|
|
b:ClearAllPoints()
|
|
b:SetPoint("TOPLEFT", f, "TOPLEFT", tabX, tabY)
|
|
b:SetWidth(tabInfo.width)
|
|
b:SetHeight(20)
|
|
b:Show()
|
|
end
|
|
tabX = tabX + tabInfo.width + 5
|
|
end
|
|
|
|
for i = 1, WR_LINES_PER_PAGE do
|
|
local row = f.rows[i]
|
|
local y = -158 - ((i - 1) * 25)
|
|
row.star:ClearAllPoints()
|
|
row.star:SetPoint("TOPLEFT", f, "TOPLEFT", 20, y)
|
|
row.star:SetWidth(24)
|
|
row.star:SetHeight(20)
|
|
row.row:ClearAllPoints()
|
|
row.row:SetPoint("TOPLEFT", f, "TOPLEFT", 48, y)
|
|
row.row:SetWidth(485)
|
|
row.row:SetHeight(20)
|
|
end
|
|
end
|
|
|
|
f.fadeButton:ClearAllPoints()
|
|
f.fadeButton:SetPoint("TOPLEFT", f, "TOPLEFT", 8, -6)
|
|
f.fadeButton:SetWidth(46)
|
|
f.fadeButton:SetHeight(18)
|
|
end
|