Compare with Previous | Blame | View Log
local addonName, BiM = ... BiM.anchor = CreateFrame("Frame", "BearInMindAnchor", UIParent) local anchor = BiM.anchor BiM.eventFrame = CreateFrame("Frame") local eventFrame = BiM.eventFrame local LSM = LibStub("LibSharedMedia-3.0") local tinsert = table.insert local tremove = table.remove local strformat = string.format local db, pcdb, _ local calIcon = "Interface\\Addons\\Bear in Mind\\calendar" numLines = 0 --just #lines ? inUse = 0 BiM.lines = {} local lines = BiM.lines sRD = {} --shownReminderData (as reminders in our DB get shown, their data is added to this table) local function CreateNew() --factory function to make a new line local line = CreateFrame("Frame", nil, anchor) if inUse >1 then line:SetPoint("TOPLEFT", lines[inUse-1], "BOTTOMLEFT", 0, -5) else line:SetPoint("TOPLEFT", anchor, "TOPLEFT", 5, -5) end line:SetSize(270, 40) line.icon = CreateFrame("Button", nil, line) --need to test to make sure it's created properly local icon = line.icon icon:SetPoint("LEFT") icon:SetSize(40, 40) icon:RegisterForClicks("RightButtonUp") icon:SetScript("OnClick", function() BiM.HideReminder(line) end) line.text = line:CreateFontString() local text = line.text text:SetPoint("LEFT", icon, "RIGHT", 5, 0) text:SetSize(225, 40) text:SetJustifyH("LEFT") text:SetFont(LSM:Fetch("font", db.font), db.fSize) --, "OUTLINE") text:SetShadowColor(0, 0, 0) text:SetShadowOffset(1, -1) text:SetTextColor(db.fColor.r, db.fColor.g, db.fColor.b) tinsert(lines, line) --insert our new line at the end of the table numLines = #lines --now we have this many lines created line.index = numLines --index will increase as lines are created and added to our table return line end function BiM.ConfigureLine(line, data) line.data = data local icon = data.icon or "Interface\\AddOns\\Bear in Mind\\BiM-icon" local text = data.text or "Remember... something?" line.icon:SetNormalTexture(icon) line.text:SetText(text) if data.sound then PlaySoundFile(LSM:Fetch("sound", data.sound)) end data.shown = true end function BiM.DisplayReminder(data, sample) --if this is a sample, let's put it in the table to avoid errors if sample then tinsert(sRD, data) end inUse = inUse + 1 --we have one more used local line --get a line to display if numLines < inUse then line = CreateNew() --we need to make a new line else line = lines[inUse] --use the next available line (if 2 were in use, then 3 is what we're on now) line:Show() end BiM.ConfigureLine(line, data) --moved to own function for reuse end function BiM.HideReminder(line) lines[inUse]:Hide() --hide last one inUse = inUse - 1 --now we're using one less line.data.shown = false --the reminder associated with this line is no longer shown tremove(sRD, line.index) --reconfigure all lines so that the reminders still showing are in the right spots --(in case the 1st of 3 was dismissed, for example) for i = 1, inUse do BiM.ConfigureLine(lines[i], sRD[i]) --make them all match up end end local function ShouldShowReminder(reminder) local show = false if not reminder.data.shown then --if not currently shown if reminder.charName and reminder.charName ~= BiM.charName then --if only for a certain char, and not THIS char, then don't show return end --local _, m, d, y = CalendarGetDate() local dateTable = C_Calendar.GetDate() --local curDate = strformat("%d-%d-%d", m, d, y) local curDate = strformat("%d-%d-%d", dateTable.month, dateTable.monthDay, dateTable.year) --if show always or haven't shown yet today if reminder.showAlways or reminder.lastShown ~= curDate then show = true reminder.lastShown = curDate end end return show end local function CheckForZoneReminders() --will fire for ZONE_CHANGED, ZONE_CHANGED_NEW_AREA, ZONE_CHANGED_INDOORS and PLAYER_ENTERING_WORLD local realZone = GetRealZoneText() local subZone = GetSubZoneText() local zone = GetZoneText() local zoneReminders = db.reminders.zone for i = 1, #zoneReminders do local reminder = zoneReminders[i] local remindAt = reminder.zone if remindAt == realZone or remindAt == subZone or remindAt == zone then --found a reminder, now should we show it? if ShouldShowReminder(reminder) then tinsert(sRD, reminder.data) --backup which reminders are showing (data.icon, data.text, data.sound) BiM.DisplayReminder(reminder.data) end end end end local function CheckForOnEventReminders(event) --will fire for any additional events registered local eventReminders = db.reminders.event for i = 1, #eventReminders do local reminder = eventReminders[i] if event == reminder.event then if ShouldShowReminder(reminder) then tinsert(sRD, reminder.data) BiM.DisplayReminder(reminder.data) end end end end local function CheckForCertainDayReminders() --will fire at login to check the day local dayReminders = db.reminders.day for i = 1, #dayReminders do local reminder = dayReminders[i] --if reminder.day == CalendarGetDate() and ShouldShowReminder(reminder)then --stored and recalled as the weekday index (1-7) if reminder.day == C_Calendar.GetDate().weekday and ShouldShowReminder(reminder)then --stored and recalled as the weekday index (1-7) tinsert(sRD, reminder.data) BiM.DisplayReminder(reminder.data) end end end local function CheckForCertainTimeReminders() --will fire at one-minute intervals to check the time if #db.reminders.time > 0 then local timeReminders = db.reminders.time for i = 1, #timeReminders do local reminder = timeReminders[i] if reminder.time == GameTime_GetTime(true) and ShouldShowReminder(reminder) then tinsert(sRD, reminder.data) BiM.DisplayReminder(reminder.data) end end end C_Timer.After(60, CheckForCertainTimeReminders) --keep polling every minute end local function CheckForLoginReminders() --will fire at at login local loginReminders = db.reminders.login for i = 1, #loginReminders do local reminder = loginReminders[i] if ShouldShowReminder(reminder) then tinsert(sRD, reminder.data) BiM.DisplayReminder(reminder.data) end end end local function CheckForCalendarEvents(dateTable) --will fire at login if calendar checks enabled local curYear, curMonth, curDate = dateTable.year, dateTable.month, dateTable.monthDay local curDateStamp = string.format("%d%d%d", curYear, curMonth, curDate) local calReminders = db.calReminders --[[CalendarSetAbsMonth(curMonth, curYear) OpenCalendar() -- CalendarFrame_Update()]]-- --collect the day's events --local numEvents = CalendarGetNumDayEvents(0, curDate) local numEvents = C_Calendar.GetNumDayEvents(0, curDate) --print(numEvents, "today") local curEvents = {} for i = 1, numEvents do --local title, _,_, calType = CalendarGetDayEvent(0, curDate, i) local eventTable = C_Calendar.GetDayEvent(0, curDate, i) --tinsert(curEvents, {name = "Calendar"..i, data = {text = title, icon = calIcon}}) tinsert(curEvents, {name = "Calendar"..i, data = {text = eventTable.title, icon = calIcon}}) end --loop through saved list for i, r in pairs(calReminders) do r.current = false for j, event in pairs(curEvents) do --compare with current day's events if r.data.text == event.data.text then --if a previously shown event is a current event --print(r.data.text, "still ongoing") curEvents[j] = nil --remove from this table, already matched r.current = true break --break out of loop (match found) and leave in calReminders table end end if r.lastShown and curDateStamp - r.lastShown > 0 then if not r.current then --not a current day's event --print("old event -", r.data.text, "- last shown", curDateStamp - r.lastShown, "days ago", "- current:", r.current) calReminders[i] = nil --remove from saved table - old event end end end --if there are new current events today (that wouldn't have been matched with the saved table) if #curEvents > 0 then for k, v in pairs(curEvents) do --print("new event - adding", v.data.text) tinsert(calReminders, v) --add to saved list end end --display reminders local crNum, crShow = 0, 0 for k, v in pairs(calReminders) do crNum = crNum+1 if db.calendarShowAlways or v.lastShown ~= curDateStamp then --one last check to see if we want to show the saved event v.lastShown = curDateStamp --shown today - update date stamp tinsert(sRD, v.data) BiM.DisplayReminder(v.data) crShow = crShow+1 end end --print("showing", crShow, "/", crNum, "total") end function BiM.PlayerLogin() db = BearInMindDB pcdb = BearInMindPCDB --set up anchor frame anchor:SetSize(280, 50) anchor:SetPoint(db.anchor, UIParent, db.anchor, db.offsetX, db.offsetY) anchor:SetScale(db.scale) anchor.bg = anchor:CreateTexture() anchor.bg:SetAllPoints(anchor) anchor:SetClampedToScreen(true) if db.lock then anchor.bg:SetColorTexture(0,0,1,0) anchor:EnableMouse(false) else anchor.bg:SetColorTexture(0,0,1,.4) anchor:EnableMouse(true) anchor:SetMovable(true) end anchor:SetScript("OnMouseDown", function(self) if not db.lock then anchor:StartMoving() end end) anchor:SetScript("OnMouseUp", function(self) self:StopMovingOrSizing() db.anchor, _, _, db.offsetX, db.offsetY = anchor:GetPoint() end) --check for at login reminders CheckForLoginReminders() --check for any reminders for today specifically CheckForCertainDayReminders() --check for login/current zone reminders CheckForZoneReminders() --listen for event reminders local eventReminders = db.reminders.event for i = 1, #eventReminders do if eventReminders[i].event then eventFrame:RegisterEvent(eventReminders[i].event) end end --check for any reminders for a certain time and start C_Timer.After CheckForCertainTimeReminders() --check for calendar events if db.calendar then --local _, curMonth, curDate, curYear = CalendarGetDate() local dateTable = C_Calendar.GetDate() --CalendarSetAbsMonth(curMonth, curYear) C_Calendar.SetAbsMonth(dateTable.month, dateTable.year) --OpenCalendar() C_Calendar.OpenCalendar() -- CalendarFrame_Update() --C_Timer.After(2, function() CheckForCalendarEvents(curMonth, curDate, curYear) end) C_Timer.After(2, function() CheckForCalendarEvents(dateTable) end) --CheckForCalendarEvents(curMonth, curDate, curYear) end end local zoneEvents = { ["ZONE_CHANGED"] = true, ["ZONE_CHANGED_NEW_AREA"] = true, ["ZONE_CHANGED_INDOORS"] = true, ["PLAYER_ENTERING_WORLD"] = true, } for k,v in pairs(zoneEvents) do eventFrame:RegisterEvent(k) end eventFrame:SetScript("OnEvent", function(self, event, ...) if zoneEvents[event] then CheckForZoneReminders() end CheckForOnEventReminders(event) end)