From 1cc2a28ce61c5374d51aa2511bd10c4d45a88f21 Mon Sep 17 00:00:00 2001 From: belthazor <76889009+paokkerkir@users.noreply.github.com> Date: Sat, 16 May 2026 00:22:38 +0300 Subject: [PATCH] update: compact mode, mute, UI refinements --- Core.lua | 387 +++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 361 insertions(+), 26 deletions(-) diff --git a/Core.lua b/Core.lua index b9eb494..14ccb50 100644 --- a/Core.lua +++ b/Core.lua @@ -176,11 +176,14 @@ 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", @@ -210,6 +213,14 @@ function WowRadio:OnEnable() -- 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 @@ -501,6 +512,12 @@ 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 }, @@ -534,6 +551,14 @@ function WowRadio:EnsureUIDefaults() 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 @@ -844,16 +869,34 @@ function WowRadio:CreateController() -- Title/banner is part of the custom backdrop image now. -- No code-created title bar here. - local close = CreateFrame("Button", nil, f, "UIPanelCloseButton") + local close = CreateFrame("Button", nil, f, "UIPanelButtonTemplate") if close.SetFrameLevel then close:SetFrameLevel(f:GetFrameLevel() + 20) end - close:SetPoint("TOPRIGHT", f, "TOPRIGHT", -4, -4) + 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 fadeBtn = WowRadio:CreateWRButton(f, "Fade", 8, -6, 50, 18, function() + -- Minimize button: same small style as close, sits to its left. + 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 @@ -861,6 +904,15 @@ function WowRadio:CreateController() end f.fadeButton = fadeBtn + -- Mute button: repositioned by ApplyUIMode for full vs mini layout. + 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) @@ -893,6 +945,7 @@ function WowRadio:CreateController() if newScale > 2.0 then newScale = 2.0 end WowRadioFrame:SetScale(newScale) end) + f.sizer = sizer local wasMoving = false local lastMX, lastMY = 0, 0 @@ -1052,7 +1105,7 @@ function WowRadio:CreateController() end f.pageText = f:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall") - f.pageText:SetPoint("TOPLEFT", f, "TOPLEFT", 20, -394) + f.pageText:SetPoint("TOPLEFT", f, "TOPLEFT", 20, -399) f.pageText:SetWidth(330) f.pageText:SetJustifyH("LEFT") f.pageText:SetText("Page 1") @@ -1131,6 +1184,7 @@ function WowRadio:CreateController() f.urlEditBox = urlEditBox WowRadio:ApplyVolume(WowRadio:GetVolume(), true) + WowRadio:ApplyUIMode() WowRadio:RefreshUI() end @@ -1285,34 +1339,32 @@ function WowRadio:RefreshUI() state = "Stopped" end - if customUrl == nil then - local station = WowRadio:getStation() + if f.nowStatusText then + f.nowStatusText:SetText("|cffffffff"..state..":|r") + end - if f.nowStatusText then - f.nowStatusText:SetText("|cffffffff"..state..":|r") - end - - if f.nowStationText then + if f.nowStationText then + if customUrl == nil then + local station = WowRadio:getStation() f.nowStationText:SetText("|cff00ff00["..station.."] "..wr_trim(WowRadio:getStationShortName(station), 40).."|r") - elseif f.nowText then - f.nowText:SetText("|cffffffff"..state..":|r |cff00ff00["..station.."] "..WowRadio:getStationShortName(station).."|r") - end - else - if f.nowStatusText then - f.nowStatusText:SetText("|cffffffff"..state..":|r") - end - - if f.nowStationText then + else f.nowStationText:SetText("|cff00ff00[custom] "..wr_trim(customUrl, 40).."|r") - elseif f.nowText then + 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 - if self.db.account.autostart == true then - f.autoButton:SetText("Auto: On") - else - f.autoButton:SetText("Auto: Off") + if f.autoButton then + if self.db.account.autostart == true then + f.autoButton:SetText("Auto: On") + else + f.autoButton:SetText("Auto: Off") + end end if f.fadeButton then @@ -1323,6 +1375,14 @@ function WowRadio:RefreshUI() end end + if f.muteButton then + if self.db.account.muted then + f.muteButton:SetText("|cffFF5555Mute|r") + else + f.muteButton:SetText("Mute") + end + end + if f.volumeSlider then local v = WowRadio:GetVolume() if f.volumeSlider:GetValue() ~= v then @@ -1330,6 +1390,7 @@ function WowRadio:RefreshUI() end end + WowRadio:ApplyUIMode() WowRadio:UpdateTabButtons() WowRadio:ShowStationPanel() end @@ -1337,6 +1398,17 @@ 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() @@ -1396,7 +1468,270 @@ function WowRadio:ShowStationPanel() end ----------------------------------------------------------------- --- WowRadio +-- Mini Player / Compact Mode +----------------------------------------------------------------- + +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) + else + WowRadio:ApplyVolume(WowRadio:GetVolume(), true) + end + WowRadio:RefreshUI() +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) + + -- Volume slider (middle row, left group). + 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() + + -- Mute button immediately after vol%, then a gap before transport. + f.muteButton:ClearAllPoints() + f.muteButton:SetPoint("TOPLEFT", f, "TOPLEFT", 135, -38) + f.muteButton:SetWidth(38) + f.muteButton:SetHeight(20) + f.muteButton:Show() + + -- Transport buttons (middle row, right group, detached from mute). + 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() + + -- Now-playing bar (bottom row). + 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) + + -- Hide full-mode-only elements. + 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 + -- Full mode. + 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) + + -- Mute button above vol slider, centered over it on the left. + f.muteButton:ClearAllPoints() + f.muteButton:SetPoint("TOPLEFT", f, "TOPLEFT", 20, -80) + f.muteButton:SetWidth(46) + f.muteButton:SetHeight(18) + f.muteButton:Show() + + -- Volume row. + 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() + + -- Transport row. + 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() + + -- Now-playing bar (bottom of station list). + 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) + + -- Bottom controls. + 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 + + -- Tabs. + 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 + + -- Station rows. + 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 + + -- Fade button always top-left regardless of mode. + f.fadeButton:ClearAllPoints() + f.fadeButton:SetPoint("TOPLEFT", f, "TOPLEFT", 8, -6) + f.fadeButton:SetWidth(46) + f.fadeButton:SetHeight(18) +end + +----------------------------------------------------------------- +-- WowRadio -- Author: Tormentor @Mannoroth -- -- 0.3 initial beta release