Files

250 lines
7.1 KiB
Lua

local _G = ShaguTweaks.GetGlobalEnv()
local T = ShaguTweaks.T
local API = ShaguTweaks.API
local module = ShaguTweaks:register({
title = T["MiniMap Clock"],
description = T["Adds a small 24h clock to the mini map with an integrated timer. Left click the clock to toggle the timer. Left click the timer to start/pause or right click to reset."],
expansions = { ["vanilla"] = true },
category = T["Minimap & World Map"],
enabled = true,
})
MinimapClock = CreateFrame("Frame", "Clock", Minimap)
MinimapClock:Hide()
MinimapClock:SetFrameLevel(64)
MinimapClock:SetPoint("BOTTOM", MinimapCluster, "BOTTOM", 8, 18)
MinimapClock:SetWidth(50)
MinimapClock:SetHeight(23)
MinimapClock:SetClampedToScreen(true)
MinimapClock:SetBackdrop({
bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
tile = true, tileSize = 8, edgeSize = 16,
insets = { left = 3, right = 3, top = 3, bottom = 3 }
})
MinimapClock:SetBackdropBorderColor(.9,.8,.5,1)
MinimapClock:SetBackdropColor(.4,.4,.4,1)
MinimapTimer = CreateFrame("Button", "MinimapTimer", Minimap)
MinimapTimer:Hide()
MinimapTimer:SetFrameStrata("MEDIUM")
MinimapTimer:SetFrameLevel(65)
MinimapTimer:SetWidth(70)
MinimapTimer:SetHeight(23)
MinimapTimer:SetPoint("TOP", MinimapClock, "BOTTOM")
MinimapTimer:SetBackdrop({
bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
tile = true, tileSize = 8, edgeSize = 16,
insets = { left = 3, right = 3, top = 3, bottom = 3 }
})
MinimapTimer:SetBackdropBorderColor(.9,.8,.5,1)
MinimapTimer:SetBackdropColor(.4,.4,.4,1)
MinimapTimer:SetMovable(true)
MinimapTimer:SetClampedToScreen(true)
MinimapTimer:SetUserPlaced(true)
MinimapTimer:EnableMouse(true)
MinimapTimer:RegisterForDrag("LeftButton")
MinimapTimer:RegisterForClicks("LeftButtonUp", "RightButtonUp")
module.enable = function(self)
local timermax = 99 * 3600 + 59 * 60 + 59 -- 99:59:59
local timerstarted = nil
local timerelapsed = 0
local timerpaused = nil
local timerticker = nil
MinimapClock:Show()
MinimapClock:EnableMouse(true)
MinimapClock.text = MinimapClock:CreateFontString("Status", "LOW", "GameFontNormal")
MinimapClock.text:SetFont(STANDARD_TEXT_FONT, 12, "OUTLINE")
MinimapClock.text:SetAllPoints(MinimapClock)
MinimapClock.text:SetFontObject(GameFontWhite)
local function updateclock()
MinimapClock.text:SetText(date("%H:%M"))
end
local function scheduleclock()
updateclock()
-- Recalculate the next minute boundary every time so delayed callbacks,
-- alt-tab stalls or local clock adjustments cannot accumulate drift.
local seconds = tonumber(date("%S")) or 0
C_Timer.After(60 - seconds, scheduleclock)
end
scheduleclock()
local timertext = MinimapTimer:CreateFontString(nil, "LOW", "GameFontNormal")
timertext:SetFont(STANDARD_TEXT_FONT, 12, "OUTLINE")
timertext:SetFontObject(GameFontWhite)
timertext:SetAllPoints(MinimapTimer)
local function formattime(e)
local t = floor(e or 0)
local h = floor(t / 3600)
local m = floor(mod(t, 3600) / 60)
local s = floor(mod(t, 60))
return h, m, s
end
local function updatetimertext()
local h, m, s = formattime(timerelapsed)
timertext:SetText(format("%02d:%02d:%02d", h, m, s))
end
local function stopticker()
if timerticker then
timerticker:Cancel()
timerticker = nil
end
end
local function ticktimer()
timerelapsed = GetTime() - timerstarted
if timerelapsed >= timermax then
timerelapsed = timermax
updatetimertext()
timerpaused = GetTime()
stopticker()
return
end
updatetimertext()
end
local function startticker()
stopticker()
timerticker = C_Timer.NewTicker(1, ticktimer)
end
local function starttimer()
timerstarted = GetTime()
timerelapsed = 0
timerpaused = nil
updatetimertext()
startticker()
end
local function resettimer()
stopticker()
timerstarted = nil
timerelapsed = 0
timerpaused = nil
updatetimertext()
end
local function pausetimer()
if not timerstarted then return end
timerelapsed = GetTime() - timerstarted
if timerelapsed > timermax then timerelapsed = timermax end
timerpaused = GetTime()
stopticker()
updatetimertext()
end
local function continuetimer()
if not timerstarted or not timerpaused then return end
timerstarted = timerstarted + (GetTime() - timerpaused)
timerpaused = nil
startticker()
end
local function toggletimer()
resettimer()
if MinimapTimer:IsVisible() then
MinimapTimer:Hide()
else
MinimapTimer:Show()
end
end
local function resetposition()
-- Once the timer has been moved through Movable Unit Frames it has an
-- absolute saved position. Clearing that position restores the natural
-- Clock -> Timer relationship, so future clock moves carry it again.
local movedb = ShaguTweaks_config and ShaguTweaks_config["MoveUnitframes"]
if movedb then movedb["MinimapTimer"] = nil end
local state = ShaguTweaks.MovableUnitFramesState
if state and state.manual then state.manual.timer = false end
if state and state.dragging then state.dragging.timer = false end
MinimapTimer:SetUserPlaced(false)
MinimapTimer:ClearAllPoints()
MinimapTimer:SetPoint("TOP", MinimapClock, "BOTTOM")
end
MinimapClock:SetScript("OnMouseDown", function()
if arg1 == "LeftButton" then toggletimer() end
end)
MinimapClock:SetScript("OnEnter", function()
local h, m = GetGameTime()
local servertime = string.format("%.2d:%.2d", h, m)
local zonetime
local turtleClock = ShaguTweaks.GetTurtleClockTimes
if turtleClock then
servertime, zonetime = turtleClock()
end
local time = date("%H:%M")
GameTooltip:ClearLines()
GameTooltip:SetOwner(this, ANCHOR_BOTTOMLEFT)
GameTooltip:AddLine(T["Clock"])
GameTooltip:AddDoubleLine(T["Localtime"], time, 1,1,1,1,1,1)
GameTooltip:AddDoubleLine(T["Servertime"], servertime, 1,1,1,1,1,1)
if zonetime then
GameTooltip:AddDoubleLine(T["Zonetime"], zonetime, 1,1,1,1,1,1)
end
GameTooltip:Show()
end)
MinimapClock:SetScript("OnLeave", function()
GameTooltip:Hide()
end)
-- Keep the timer independently movable when Movable Unit Frames is disabled.
-- With the mover enabled, its Ctrl+Shift mode temporarily owns these scripts
-- and restores them afterwards.
MinimapTimer:SetScript("OnDragStart", function()
if API.IsShiftKeyDown() and API.IsControlKeyDown() then
this:StartMoving()
end
end)
MinimapTimer:SetScript("OnDragStop", function()
this:StopMovingOrSizing()
this:SetUserPlaced(true)
end)
MinimapTimer:SetScript("OnClick", function()
if arg1 == "LeftButton" then
if timerpaused then
continuetimer()
elseif not timerstarted then
starttimer()
else
pausetimer()
end
elseif arg1 == "RightButton" then
if API.IsShiftKeyDown() and API.IsControlKeyDown() then
resettimer()
MinimapTimer:Hide()
resetposition()
else
resettimer()
end
end
end)
resettimer()
end