293 lines
7.6 KiB
Lua
293 lines
7.6 KiB
Lua
TurtleMail = TurtleMail or {}
|
|
local m = TurtleMail
|
|
|
|
if m.Calendar then return end
|
|
|
|
---@class Calendar
|
|
---@field show fun( data: table, date: number, anchor: table, on_select: function )
|
|
---@field hide fun()
|
|
---@field is_visible fun():boolean
|
|
|
|
local M = {}
|
|
|
|
function M.new()
|
|
local BTN_WIDTH = 25
|
|
local BTN_HEIGHT = 20
|
|
|
|
local calendar
|
|
local set_year, set_month
|
|
local year_dd, month_dd
|
|
local date_data = {}
|
|
local months = {}
|
|
local days = {}
|
|
local select_func
|
|
|
|
for i = 1, 12 do
|
|
local timestamp = time( { year = 2025, month = i, day = 1 } )
|
|
months[ i ] = date( "%B", timestamp )
|
|
end
|
|
|
|
local function get_end_day_of_month( year, month )
|
|
if month == 2 then
|
|
if (mod( year, 4 ) == 0 and mod( year, 100 ) ~= 0) or mod( year, 400 ) == 0 then
|
|
return 29
|
|
else
|
|
return 28
|
|
end
|
|
elseif month == 4 or month == 6 or month == 9 or month == 11 then
|
|
return 30
|
|
else
|
|
return 31
|
|
end
|
|
end
|
|
|
|
---@alias DatePart
|
|
---| "Year"
|
|
---| "Month"
|
|
---| "Day"
|
|
|
|
---@param part DatePart
|
|
local function get_valid_dates( part )
|
|
local valid = {}
|
|
for i, v in ipairs( date_data ) do
|
|
local year = tonumber( date( "%Y", v.timestamp ) )
|
|
local month = tonumber( date( "%m", v.timestamp ) )
|
|
local day = tonumber( date( "%d", v.timestamp ) )
|
|
|
|
if year and month and day then
|
|
if part == "Day" and year == set_year and month == set_month then
|
|
valid[ day ] = valid[ day ] and valid[ day ] + 1 or 1
|
|
elseif part == "Month" and year == set_year then
|
|
valid[ month ] = true
|
|
elseif part == "Year" then
|
|
valid[ year ] = true
|
|
end
|
|
end
|
|
end
|
|
|
|
return valid
|
|
end
|
|
|
|
local function refresh()
|
|
local current_month = { year = set_year, month = set_month, day = "01" }
|
|
local skip_days = date( "%w", time( current_month ) )
|
|
local end_day = get_end_day_of_month( tonumber( set_year ), tonumber( set_month ) )
|
|
|
|
for i = 1, 42 do
|
|
days[ i ]:SetText( "" )
|
|
days[ i ]:Disable()
|
|
days[ i ]:Hide()
|
|
end
|
|
|
|
local valid_days = get_valid_dates( "Day" )
|
|
for i = 1, end_day do
|
|
local day = days[ i + skip_days ]
|
|
local d = i
|
|
day:SetText( i )
|
|
|
|
if valid_days[ i ] then
|
|
day.mails = valid_days[ i ]
|
|
day:Enable()
|
|
end
|
|
day:Show()
|
|
|
|
day:SetScript( "OnClick", function()
|
|
local timestamp = time( { year = set_year, month = set_month, day = d } )
|
|
if select_func then
|
|
select_func( timestamp )
|
|
end
|
|
calendar:Hide()
|
|
end )
|
|
end
|
|
|
|
if tonumber( skip_days + end_day ) < 36 then
|
|
calendar:SetHeight( 150 )
|
|
else
|
|
calendar:SetHeight( 170 )
|
|
end
|
|
|
|
m.api.UIDropDownMenu_SetText( months[ set_month ], month_dd )
|
|
m.api.UIDropDownMenu_SetText( set_year, year_dd )
|
|
end
|
|
|
|
local function pfui_skin()
|
|
if m.pfui_skin_enabled then
|
|
m.api.pfUI.api.SkinDropDown( year_dd, nil, nil, nil, true )
|
|
year_dd:SetPoint( "TOPLEFT", -5, -5 )
|
|
m.api.pfUI.api.SkinDropDown( month_dd, nil, nil, nil, true )
|
|
month_dd:SetPoint( "TOPLEFT", 79, -5 )
|
|
m.api.UIDropDownMenu_SetWidth( 70, month_dd )
|
|
|
|
for i = 1, 42 do
|
|
local button = days[ i ]
|
|
m.api.pfUI.api.SkinButton( button )
|
|
button:SetWidth( BTN_WIDTH - 1 )
|
|
button:SetHeight( BTN_HEIGHT - 1 )
|
|
end
|
|
end
|
|
end
|
|
|
|
---@param parent table
|
|
---@param index number
|
|
local function create_date_button( parent, index )
|
|
local button = m.api.CreateFrame( "Button", "TurtleMailCalendarDay" .. index .. "Button", parent, "UIPanelButtonTemplate" )
|
|
button:SetWidth( BTN_WIDTH )
|
|
button:SetHeight( BTN_HEIGHT )
|
|
button:GetFontString():SetFont( m.pfui_skin_enabled and m.api.pfUI.font_default or "Fonts/FRIZQT__.TTF", 9 )
|
|
button:GetFontString():SetTextColor( 1, 1, 1, 1 )
|
|
|
|
local orig_disable = button.Disable
|
|
button.Disable = function( self )
|
|
orig_disable( self )
|
|
button:GetFontString():SetTextColor( 0.5, 0.5, 0.5, 1 )
|
|
end
|
|
|
|
local orig_enable = button.Enable
|
|
button.Enable = function( self )
|
|
orig_enable( self )
|
|
button:GetFontString():SetTextColor( 1, 1, 1, 1 )
|
|
end
|
|
|
|
button:SetScript( "OnEnter", function()
|
|
m.api.GameTooltip:SetOwner( this, "ANCHOR_RIGHT" )
|
|
m.api.GameTooltip:SetText( button.mails .. " mail" .. (button.mails > 1 and "s" or ""), 1, 1, 1, 1, true )
|
|
m.api.GameTooltip:Show()
|
|
end )
|
|
|
|
button:SetScript( "OnLeave", function()
|
|
m.api.GameTooltip:Hide()
|
|
end )
|
|
|
|
return button
|
|
end
|
|
|
|
---@param parent table
|
|
---@param name DatePart
|
|
---@param on_select function
|
|
---@return table
|
|
local function create_dropdown( parent, name, on_select )
|
|
local dropdown = m.api.CreateFrame( "Frame", "TurtleMailDropdown" .. name, parent, "UIDropDownMenuTemplate" )
|
|
|
|
m.api.UIDropDownMenu_Initialize( dropdown, function()
|
|
local valid_dates = get_valid_dates( name )
|
|
local info = {}
|
|
|
|
for i in pairs( valid_dates ) do
|
|
info.arg1 = i
|
|
info.arg2 = name == "Month" and months[ i ] or i
|
|
info.value = info.arg1
|
|
info.text = info.arg2
|
|
|
|
info.func = function( index, value )
|
|
m.api.UIDropDownMenu_SetText( value, dropdown )
|
|
m.api.CloseDropDownMenus()
|
|
on_select( index, value )
|
|
end
|
|
|
|
m.api.UIDropDownMenu_AddButton( info )
|
|
end
|
|
end )
|
|
|
|
return dropdown
|
|
end
|
|
|
|
local function create_calendar()
|
|
local frame = m.api.CreateFrame( "Frame", "TurtleMailCalendarFrame" )
|
|
frame:SetFrameStrata( "FULLSCREEN_DIALOG" )
|
|
frame:SetWidth( 195 )
|
|
frame:SetHeight( 170 )
|
|
frame:SetBackdrop( {
|
|
bgFile = "Interface/Buttons/WHITE8x8",
|
|
edgeFile = "Interface/Buttons/WHITE8x8",
|
|
tile = false,
|
|
tileSize = 0,
|
|
edgeSize = 0.5,
|
|
insets = { left = 0, right = 0, top = 0, bottom = 0 }
|
|
} )
|
|
|
|
frame:SetBackdropColor( 0, 0, 0, 0.9 )
|
|
frame:SetBackdropBorderColor( .4, .4, .4, 0.9 )
|
|
frame:EnableMouse( true )
|
|
frame:Hide()
|
|
m.api.tinsert( m.api.UISpecialFrames, frame:GetName() )
|
|
|
|
frame:SetScript( "OnLeave", function()
|
|
if m.api.MouseIsOver( frame ) then
|
|
return
|
|
end
|
|
calendar:Hide()
|
|
end )
|
|
|
|
year_dd = create_dropdown( frame, "Year", function( _, v )
|
|
set_year = v
|
|
refresh()
|
|
end )
|
|
year_dd:SetPoint( "TOPLEFT", -12, -5 )
|
|
m.api.UIDropDownMenu_SetWidth( 55, year_dd )
|
|
|
|
month_dd = create_dropdown( frame, "Month", function( v )
|
|
set_month = v
|
|
refresh()
|
|
end )
|
|
month_dd:SetPoint( "TOPLEFT", 70, -5 )
|
|
m.api.UIDropDownMenu_SetWidth( 85, month_dd )
|
|
|
|
for i = 1, 42 do
|
|
table.insert( days, create_date_button( frame, i ) )
|
|
end
|
|
|
|
for i = 1, 6 do
|
|
for j = 1, 7 do
|
|
days[ (i - 1) * 7 + j ]:SetPoint( "TOPLEFT", frame, 10 + (j - 1) * BTN_WIDTH, -40 - (i - 1) * BTN_HEIGHT )
|
|
days[ (i - 1) * 7 + j ]:Disable()
|
|
end
|
|
end
|
|
|
|
pfui_skin()
|
|
return frame
|
|
end
|
|
|
|
local function show( data, current_date, anchor, on_select )
|
|
date_data = data
|
|
set_year = tonumber( date( "%Y", current_date ) )
|
|
set_month = tonumber( date( "%m", current_date ) )
|
|
select_func = on_select
|
|
|
|
if not calendar then
|
|
calendar = create_calendar()
|
|
end
|
|
|
|
if m.pfui_skin_enabled then
|
|
calendar:SetPoint( "TOPRIGHT", anchor, "BOTTOMRIGHT", 125, -4 )
|
|
else
|
|
calendar:SetPoint( "TOPRIGHT", anchor, "BOTTOMRIGHT", 100, 1 )
|
|
end
|
|
|
|
refresh()
|
|
calendar:Show()
|
|
end
|
|
|
|
local function hide()
|
|
if calendar then
|
|
calendar:Hide()
|
|
end
|
|
end
|
|
|
|
local function is_visible()
|
|
if calendar then
|
|
return calendar:IsVisible()
|
|
end
|
|
return false
|
|
end
|
|
|
|
---@type Calendar
|
|
return {
|
|
show = show,
|
|
hide = hide,
|
|
is_visible = is_visible
|
|
}
|
|
end
|
|
|
|
m.Calendar = M
|
|
return M
|