diff --git a/Librarian.lua b/Librarian.lua index 9faffd1..85c6a82 100644 --- a/Librarian.lua +++ b/Librarian.lua @@ -10,7 +10,7 @@ ZO_CreateStringId("SI_LIBRARIAN_SORT_TYPE_TITLE", "Title") ZO_CreateStringId("SI_LIBRARIAN_SORT_TYPE_WORD_COUNT", "Words") ZO_CreateStringId("SI_LIBRARIAN_MARK_UNREAD", "Mark as Unread") ZO_CreateStringId("SI_LIBRARIAN_MARK_READ", "Mark as Read") -ZO_CreateStringId("SI_LIBRARIAN_CREDIT", "Librarian 1.2.5 by Flamage") +ZO_CreateStringId("SI_LIBRARIAN_CREDIT", "Librarian 1.2.6 by Flamage") ZO_CreateStringId("SI_LIBRARIAN_BOOK_COUNT", "%d Books") ZO_CreateStringId("SI_LIBRARIAN_UNREAD_COUNT", "%s (%d Unread)") ZO_CreateStringId("SI_LIBRARIAN_SHOW_ALL_BOOKS", "Show books for all characters") @@ -24,7 +24,7 @@ ZO_CreateStringId("SI_LIBRARIAN_EMPTY_LIBRARY_IMPORT_PROMPT", [[It appears your Patch 1.3 fixed a bug in the storage of addon data which now needs to be moved back to the correct place. Please click the "Import from before patch" button in the Librarian setting menu to perform this migration. It is recommended that you backup your Librarian SavedVariables before performing this step as a precaution. -Librarian settings can be found by pressing Escape to open the main menu, and selecting Settings, Addon Settings, then Librarian.]]) +Librarian settings can be opened by clicking the settings button in the top right of the window.]]) local SORT_ARROW_UP = "EsoUI/Art/Miscellaneous/list_sortUp.dds" local SORT_ARROW_DOWN = "EsoUI/Art/Miscellaneous/list_sortDown.dds" @@ -40,64 +40,71 @@ local ENTRY_SORT_KEYS = } function Librarian:New() - local librarian = ZO_SortFilterList.New(self, LibrarianFrame) - librarian:Initialise() - return librarian + local librarian = ZO_SortFilterList.New(self, LibrarianFrame) + librarian:Initialise() + return librarian end function Librarian:Initialise() - self.masterList = {} - self.newBookCount = 0 + self.masterList = {} + self.newBookCount = 0 self.sortHeaderGroup:SelectHeaderByKey("timeStamp") - ZO_ScrollList_AddDataType(self.list, LIBRARIAN_DATA, "LibrarianBookRow", 30, function(control, data) self:SetupBookRow(control, data) end) - ZO_ScrollList_EnableHighlight(self.list, "ZO_ThinListHighlight") + ZO_ScrollList_AddDataType(self.list, LIBRARIAN_DATA, "LibrarianBookRow", 30, function(control, data) self:SetupBookRow(control, data) end) + ZO_ScrollList_EnableHighlight(self.list, "ZO_ThinListHighlight") - self.localSavedVars = ZO_SavedVars:New("Librarian_SavedVariables", 1, nil, self.defaults, nil) - self.globalSavedVars = ZO_SavedVars:NewAccountWide("Librarian_SavedVariables", 1, nil, self.defaults, nil) + self.localSavedVars = ZO_SavedVars:New("Librarian_SavedVariables", 1, nil, self.defaults, nil) + self.globalSavedVars = ZO_SavedVars:NewAccountWide("Librarian_SavedVariables", 1, nil, self.defaults, nil) - if not self.globalSavedVars.settings then self.globalSavedVars.settings = {} end - self.settings = self.globalSavedVars.settings + if not self.globalSavedVars.settings then self.globalSavedVars.settings = {} end + self.settings = self.globalSavedVars.settings - if not self.globalSavedVars.books then self.globalSavedVars.books = {} end - self.books = self.globalSavedVars.books + if not self.globalSavedVars.books then self.globalSavedVars.books = {} end + self.books = self.globalSavedVars.books - if not self.localSavedVars.characterBooks then self.localSavedVars.characterBooks = {} end - self.characterBooks = self.localSavedVars.characterBooks + if not self.localSavedVars.characterBooks then self.localSavedVars.characterBooks = {} end + self.characterBooks = self.localSavedVars.characterBooks - self.searchBox = GetControl(LibrarianFrame, "SearchBox") + self.searchBox = GetControl(LibrarianFrame, "SearchBox") self.searchBox:SetHandler("OnTextChanged", function() self:OnSearchTextChanged() end) self.search = ZO_StringSearch:New() self.search:AddProcessor(LIBRARIAN_SEARCH, function(stringSearch, data, searchTerm, cache) return self:ProcessBookEntry(stringSearch, data, searchTerm, cache) end) - self.sortFunction = function(listEntry1, listEntry2) return ZO_TableOrderingFunction(listEntry1.data, listEntry2.data, self.currentSortKey, ENTRY_SORT_KEYS, self.currentSortOrder) end + self.sortFunction = function(listEntry1, listEntry2) return ZO_TableOrderingFunction(listEntry1.data, listEntry2.data, self.currentSortKey, ENTRY_SORT_KEYS, self.currentSortOrder) end - self:UpdateSavedVariables() + self:UpdateSavedVariables() - local settings = LibrarianSettings:New(self.settings) + local settings = LibrarianSettings:New(self.settings) - local function OnShowAllBooksClicked(checkButton, isChecked) + local function OnShowAllBooksClicked(checkButton, isChecked) self.settings.showAllBooks = isChecked self:RefreshFilters() end local function GetShowAllBooks() - return self.settings.showAllBooks + return self.settings.showAllBooks end - local showAllBooks = LibrarianFrameShowAllBooks - ZO_CheckButton_SetToggleFunction(showAllBooks, OnShowAllBooksClicked) + local showAllBooks = LibrarianFrameShowAllBooks + ZO_CheckButton_SetToggleFunction(showAllBooks, OnShowAllBooksClicked) ZO_CheckButton_SetCheckState(showAllBooks, GetShowAllBooks()) --self:ImportFromLoreLibrary() - self:RefreshData() - self:InitializeKeybindStripDescriptors() - self:InitializeScene() - self:AddLoreReaderUnreadToggle() + self:RefreshData() + self:InitializeKeybindStripDescriptors() + self:InitializeScene() + self:AddLoreReaderUnreadToggle() end function Librarian:AddLoreReaderUnreadToggle() - if LORE_READER.keybindStripDescriptor then + local readerKeybinds + if LORE_READER.keybindStripDescriptor then + readerKeybinds = LORE_READER.keybindStripDescriptor + else + readerKeybinds = LORE_READER.PCKeybindStripDescriptor + end + + if readerKeybinds then -- Special exit button local exitKeybind = { @@ -106,35 +113,35 @@ function Librarian:AddLoreReaderUnreadToggle() keybind = "UI_SHORTCUT_EXIT", callback = function() SCENE_MANAGER:HideCurrentScene() end, } - table.insert(LORE_READER.keybindStripDescriptor, exitKeybind) + table.insert(readerKeybinds, exitKeybind) - local toggleKeybind = - { + local toggleKeybind = + { alignment = KEYBIND_STRIP_ALIGN_RIGHT, name = function() - local book = self:FindBook(LORE_READER.titleText) - if not book or book.unread then - if self.settings.showUnreadIndicatorInReader then - self.unreadIndicator:SetHidden(false) - else - self.unreadIndicator:SetHidden(true) - end - return GetString(SI_LIBRARIAN_MARK_READ) - else - self.unreadIndicator:SetHidden(true) - return GetString(SI_LIBRARIAN_MARK_UNREAD) - end + local book = self:FindBook(LORE_READER.titleText) + if not book or book.unread then + if self.settings.showUnreadIndicatorInReader then + self.unreadIndicator:SetHidden(false) + else + self.unreadIndicator:SetHidden(true) + end + return GetString(SI_LIBRARIAN_MARK_READ) + else + self.unreadIndicator:SetHidden(true) + return GetString(SI_LIBRARIAN_MARK_UNREAD) + end end, keybind = "UI_SHORTCUT_SECONDARY", callback = function() - local book = self:FindBook(LORE_READER.titleText) - if not book then return end + local book = self:FindBook(LORE_READER.titleText) + if not book then return end book.unread = not book.unread - KEYBIND_STRIP:UpdateKeybindButtonGroup(LORE_READER.keybindStripDescriptor) + KEYBIND_STRIP:UpdateKeybindButtonGroup(readerKeybinds) self:RefreshData() end } - table.insert(LORE_READER.keybindStripDescriptor, toggleKeybind) + table.insert(readerKeybinds, toggleKeybind) end self.unreadIndicator = WINDOW_MANAGER:CreateControl("LibrarianUnreadIndicator", ZO_LoreReaderBookContainer, CT_TEXTURE) @@ -145,11 +152,19 @@ function Librarian:AddLoreReaderUnreadToggle() local function OnSceneStateChange(oldState, newState) if(newState == SCENE_SHOWING) then - KEYBIND_STRIP:RemoveKeybindButton(KEYBIND_STRIP.defaultExit) - KEYBIND_STRIP:AddKeybindButtonGroup(LORE_READER.keybindStripDescriptor) + if KEYBIND_STRIP.defaultExit then + KEYBIND_STRIP:RemoveKeybindButton(KEYBIND_STRIP.defaultExit) + else + KEYBIND_STRIP:RemoveDefaultExit() + end + KEYBIND_STRIP:AddKeybindButtonGroup(readerKeybinds) elseif(newState == SCENE_HIDDEN) then - KEYBIND_STRIP:RemoveKeybindButtonGroup(LORE_READER.keybindStripDescriptor) - KEYBIND_STRIP:AddKeybindButton(KEYBIND_STRIP.defaultExit) + KEYBIND_STRIP:RemoveKeybindButtonGroup(readerKeybinds) + if KEYBIND_STRIP.defaultExit then + KEYBIND_STRIP:AddKeybindButton(KEYBIND_STRIP.defaultExit) + else + KEYBIND_STRIP:RestoreDefaultExit() + end end end @@ -167,55 +182,55 @@ function Librarian:AddLoreReaderUnreadToggle() end function Librarian:UpdateSavedVariables() - -- Version 1.0.4 - Settings moved to global variables. - if self.localSavedVars.setting_time_format then - self.globalSavedVars.settings.time_format = self.localSavedVars.setting_time_format - self.localSavedVars.setting_time_format = nil - end - - -- Version 1.0.4 - Book data moved to global variables - if self.localSavedVars.books then - for _,book in ipairs(self.localSavedVars.books) do - local timeStamp = book.timeStamp - local unread = book.unread - self:AddBook(book) - local characterBook = self:FindCharacterBook(book.title) - if characterBook then characterBook.timeStamp = timeStamp end - local globalBook = self:FindBook(book.title) - if globalBook then - globalBook.timeStamp = timeStamp - globalBook.unread = unread - end - end - self.localSavedVars.books = nil - self:RefreshData() - end - - -- Version 1.0.16 - Fixed a couple of settings names. - if self.globalSavedVars.settings.alert_style then - self.globalSavedVars.settings.alertStyle = self.globalSavedVars.settings.alert_style - self.globalSavedVars.settings.alert_style = nil - end - - if self.globalSavedVars.settings.time_format then - self.globalSavedVars.settings.timeFormat = self.globalSavedVars.settings.time_format - self.globalSavedVars.settings.time_format = nil - end - - -- Version 1.1.3 - SavedVariable hell! - for _,account in pairs(Librarian_SavedVariables["Default"]) do - for _,book in pairs(account["$AccountWide"].books) do - if type(book.body) == "string" then - local newBody = book.body - book.body = {} - while string.len(newBody) > 1024 do - table.insert(book.body, string.sub(newBody, 0, 1024)) - newBody = string.sub(newBody, 1025) - end - table.insert(book.body, newBody) - end - end - end + -- Version 1.0.4 - Settings moved to global variables. + if self.localSavedVars.setting_time_format then + self.globalSavedVars.settings.time_format = self.localSavedVars.setting_time_format + self.localSavedVars.setting_time_format = nil + end + + -- Version 1.0.4 - Book data moved to global variables + if self.localSavedVars.books then + for _,book in ipairs(self.localSavedVars.books) do + local timeStamp = book.timeStamp + local unread = book.unread + self:AddBook(book) + local characterBook = self:FindCharacterBook(book.title) + if characterBook then characterBook.timeStamp = timeStamp end + local globalBook = self:FindBook(book.title) + if globalBook then + globalBook.timeStamp = timeStamp + globalBook.unread = unread + end + end + self.localSavedVars.books = nil + self:RefreshData() + end + + -- Version 1.0.16 - Fixed a couple of settings names. + if self.globalSavedVars.settings.alert_style then + self.globalSavedVars.settings.alertStyle = self.globalSavedVars.settings.alert_style + self.globalSavedVars.settings.alert_style = nil + end + + if self.globalSavedVars.settings.time_format then + self.globalSavedVars.settings.timeFormat = self.globalSavedVars.settings.time_format + self.globalSavedVars.settings.time_format = nil + end + + -- Version 1.1.3 - SavedVariable hell! + for _,account in pairs(Librarian_SavedVariables["Default"]) do + for _,book in pairs(account["$AccountWide"].books) do + if type(book.body) == "string" then + local newBody = book.body + book.body = {} + while string.len(newBody) > 1024 do + table.insert(book.body, string.sub(newBody, 0, 1024)) + newBody = string.sub(newBody, 1025) + end + table.insert(book.body, newBody) + end + end + end end function Librarian:InitializeKeybindStripDescriptors() @@ -226,7 +241,7 @@ function Librarian:InitializeKeybindStripDescriptors() name = GetString(SI_LORE_LIBRARY_READ), keybind = "UI_SHORTCUT_PRIMARY", visible = function() - return self.mouseOverRow + return self.mouseOverRow end, callback = function() self:ReadBook(self.mouseOverRow.data.title) @@ -235,20 +250,20 @@ function Librarian:InitializeKeybindStripDescriptors() { alignment = KEYBIND_STRIP_ALIGN_RIGHT, name = function() - if not self.mouseOverRow then return nil end - local book = self:FindBook(self.mouseOverRow.data.title) - if book.unread then - return GetString(SI_LIBRARIAN_MARK_READ) - else - return GetString(SI_LIBRARIAN_MARK_UNREAD) - end + if not self.mouseOverRow then return nil end + local book = self:FindBook(self.mouseOverRow.data.title) + if book.unread then + return GetString(SI_LIBRARIAN_MARK_READ) + else + return GetString(SI_LIBRARIAN_MARK_UNREAD) + end end, keybind = "UI_SHORTCUT_SECONDARY", visible = function() - return self.mouseOverRow + return self.mouseOverRow end, callback = function() - local book = self:FindBook(self.mouseOverRow.data.title) + local book = self:FindBook(self.mouseOverRow.data.title) book.unread = not book.unread self:RefreshData() end, @@ -257,92 +272,94 @@ function Librarian:InitializeKeybindStripDescriptors() end function Librarian:InitializeScene() - if not LIBRARIAN_SCENE then - LIBRARIAN_TITLE_FRAGMENT = ZO_SetTitleFragment:New(SI_WINDOW_TITLE_LIBRARIAN) - LIBRARIAN_SCENE = ZO_Scene:New("librarian", SCENE_MANAGER) - LIBRARIAN_SCENE:AddFragmentGroup(FRAGMENT_GROUP.MOUSE_DRIVEN_UI_WINDOW) - LIBRARIAN_SCENE:AddFragmentGroup(FRAGMENT_GROUP.FRAME_TARGET_STANDARD_RIGHT_PANEL) - LIBRARIAN_SCENE:AddFragment(ZO_FadeSceneFragment:New(LibrarianFrame)) - LIBRARIAN_SCENE:AddFragment(RIGHT_BG_FRAGMENT) - LIBRARIAN_SCENE:AddFragment(TITLE_FRAGMENT) - LIBRARIAN_SCENE:AddFragment(LIBRARIAN_TITLE_FRAGMENT) - LIBRARIAN_SCENE:AddFragment(CODEX_WINDOW_SOUNDS) - - LIBRARIAN_SCENE:RegisterCallback("StateChange", - function(oldState, newState) - if(newState == SCENE_SHOWING) then + if not LIBRARIAN_SCENE then + LIBRARIAN_TITLE_FRAGMENT = ZO_SetTitleFragment:New(SI_WINDOW_TITLE_LIBRARIAN) + LIBRARIAN_SCENE = ZO_Scene:New("librarian", SCENE_MANAGER) + LIBRARIAN_SCENE:AddFragmentGroup(FRAGMENT_GROUP.MOUSE_DRIVEN_UI_WINDOW) + if self.settings.enableCharacterSpin then + LIBRARIAN_SCENE:AddFragmentGroup(FRAGMENT_GROUP.FRAME_TARGET_STANDARD_RIGHT_PANEL) + end + LIBRARIAN_SCENE:AddFragment(ZO_FadeSceneFragment:New(LibrarianFrame)) + LIBRARIAN_SCENE:AddFragment(RIGHT_BG_FRAGMENT) + LIBRARIAN_SCENE:AddFragment(TITLE_FRAGMENT) + LIBRARIAN_SCENE:AddFragment(LIBRARIAN_TITLE_FRAGMENT) + LIBRARIAN_SCENE:AddFragment(CODEX_WINDOW_SOUNDS) + + LIBRARIAN_SCENE:RegisterCallback("StateChange", + function(oldState, newState) + if(newState == SCENE_SHOWING) then KEYBIND_STRIP:AddKeybindButtonGroup(self.keybindStripDescriptor) elseif(newState == SCENE_HIDDEN) then KEYBIND_STRIP:RemoveKeybindButtonGroup(self.keybindStripDescriptor) end end) - end + end end function Librarian:ImportFromLoreLibrary() - local hasImportedBooks = false - local chatEnabled = self.settings.chatEnabled - local alertEnabled = self.settings.alertEnabled - self.settings.chatEnabled = true - self.settings.alertEnabled = false - - for categoryIndex = 1, GetNumLoreCategories() do - local categoryName, numCollections = GetLoreCategoryInfo(categoryIndex) - for collectionIndex = 1, numCollections do + local hasImportedBooks = false + local chatEnabled = self.settings.chatEnabled + local alertEnabled = self.settings.alertEnabled + self.settings.chatEnabled = true + self.settings.alertEnabled = false + + for categoryIndex = 1, GetNumLoreCategories() do + local categoryName, numCollections = GetLoreCategoryInfo(categoryIndex) + for collectionIndex = 1, numCollections do local collectionName, description, numKnownBooks, totalBooks, hidden = GetLoreCollectionInfo(categoryIndex, collectionIndex) if not hidden then - for bookIndex = 1, totalBooks do - local title, icon, known = GetLoreBookInfo(categoryIndex, collectionIndex, bookIndex) - if known then - if not self:FindCharacterBook(title) then - local body, medium, showTitle = ReadLoreBook(categoryIndex, collectionIndex, bookIndex) - local book = {title = title, body = body, medium = medium, showTitle = showTitle} - self:AddBook(book) - end - end - end + for bookIndex = 1, totalBooks do + local title, icon, known = GetLoreBookInfo(categoryIndex, collectionIndex, bookIndex) + if known then + if not self:FindCharacterBook(title) then + local body, medium, showTitle = ReadLoreBook(categoryIndex, collectionIndex, bookIndex) + local book = {title = title, body = body, medium = medium, showTitle = showTitle} + self:AddBook(book) + end + end + end end end - end + end - self.settings.chatEnabled = chatEnabled - self.settings.alertEnabled = alertEnabled + self.settings.chatEnabled = chatEnabled + self.settings.alertEnabled = alertEnabled end function Librarian:CanImportFromEmptyAccount() - return Librarian_SavedVariables["Default"][""] ~= nil + return Librarian_SavedVariables["Default"][""] ~= nil end function Librarian:ImportFromEmptyAccount() - if Librarian_SavedVariables["Default"][""] ~= nil then - Librarian_SavedVariables["Default"][GetDisplayName()] = Librarian_SavedVariables["Default"][""] - end - Librarian_SavedVariables["Default"][""] = nil - SLASH_COMMANDS["/reloadui"]() + if Librarian_SavedVariables["Default"][""] ~= nil then + Librarian_SavedVariables["Default"][GetDisplayName()] = Librarian_SavedVariables["Default"][""] + end + Librarian_SavedVariables["Default"][""] = nil + SLASH_COMMANDS["/reloadui"]() end function Librarian:BuildMasterList() - if self:CanImportFromEmptyAccount() and #self.books == 0 then LibrarianFrameMessage:SetHidden(false) end + if self:CanImportFromEmptyAccount() and #self.books == 0 then LibrarianFrameMessage:SetHidden(false) end for i, book in ipairs(self.books) do - local data = {} - for k,v in pairs(book) do - if k == "body" then - data[k] = table.concat(book.body) - else - data[k] = v - end - end - data.type = LIBRARIAN_SEARCH - local characterBook = self:FindCharacterBook(book.title) - if characterBook then - data.seenByCurrentCharacter = true - data.timeStamp = characterBook.timeStamp - else - data.seenByCurrentCharacter = false - data.timeStamp = book.timeStamp - end - self.masterList[i] = data + local data = {} + for k,v in pairs(book) do + if k == "body" then + data[k] = table.concat(book.body) + else + data[k] = v + end + end + data.type = LIBRARIAN_SEARCH + local characterBook = self:FindCharacterBook(book.title) + if characterBook then + data.seenByCurrentCharacter = true + data.timeStamp = characterBook.timeStamp + else + data.seenByCurrentCharacter = false + data.timeStamp = book.timeStamp + end + self.masterList[i] = data end end @@ -356,17 +373,17 @@ function Librarian:FilterScrollList() for i = 1, #self.masterList do local data = self.masterList[i] if self.settings.showAllBooks or data.seenByCurrentCharacter then - if(searchTerm == "" or self.search:IsMatch(searchTerm, data)) then - table.insert(scrollData, ZO_ScrollList_CreateDataEntry(LIBRARIAN_DATA, data)) - bookCount = bookCount + 1 - if data.unread then unreadCount = unreadCount + 1 end + if(searchTerm == "" or self.search:IsMatch(searchTerm, data)) then + table.insert(scrollData, ZO_ScrollList_CreateDataEntry(LIBRARIAN_DATA, data)) + bookCount = bookCount + 1 + if data.unread then unreadCount = unreadCount + 1 end end end end local message = string.format(GetString(SI_LIBRARIAN_BOOK_COUNT), bookCount) if unreadCount > 0 then message = string.format(GetString(SI_LIBRARIAN_UNREAD_COUNT), message, unreadCount) end - LibrarianFrameBookCount:SetText(message) + LibrarianFrameBookCount:SetText(message) end function Librarian:SortScrollList() @@ -375,25 +392,25 @@ function Librarian:SortScrollList() end function Librarian:SetupBookRow(control, data) - control.data = data - control.unread = GetControl(control, "Unread") - control.found = GetControl(control, "Found") - control.title = GetControl(control, "Title") - control.wordCount = GetControl(control, "WordCount") - - control.unread.nonRecolorable = true - if data.unread then control.unread:SetAlpha(1) else control.unread:SetAlpha(0) end + control.data = data + control.unread = GetControl(control, "Unread") + control.found = GetControl(control, "Found") + control.title = GetControl(control, "Title") + control.wordCount = GetControl(control, "WordCount") + + control.unread.nonRecolorable = true + if data.unread then control.unread:SetAlpha(1) else control.unread:SetAlpha(0) end - control.found.normalColor = ZO_NORMAL_TEXT - control.found:SetText(self:FormatClockTime(data.timeStamp)) + control.found.normalColor = ZO_NORMAL_TEXT + control.found:SetText(self:FormatClockTime(data.timeStamp)) - control.title.normalColor = ZO_NORMAL_TEXT - control.title:SetText(data.title) + control.title.normalColor = ZO_NORMAL_TEXT + control.title:SetText(data.title) - control.wordCount.normalColor = ZO_NORMAL_TEXT - control.wordCount:SetText(data.wordCount) + control.wordCount.normalColor = ZO_NORMAL_TEXT + control.wordCount:SetText(data.wordCount) - ZO_SortFilterList.SetupRow(self, control, data) + ZO_SortFilterList.SetupRow(self, control, data) end function Librarian:ProcessBookEntry(stringSearch, data, searchTerm, cache) @@ -411,67 +428,67 @@ function Librarian:ProcessBookEntry(stringSearch, data, searchTerm, cache) end function Librarian:FindCharacterBook(title) - if not self.characterBooks then return nil end - for _,book in pairs(self.characterBooks) do - if book.title == title then return book end - end + if not self.characterBooks then return nil end + for _,book in pairs(self.characterBooks) do + if book.title == title then return book end + end end function Librarian:FindBook(title) - for _,book in pairs(self.books) do - if book.title == title then return book end - end + for _,book in pairs(self.books) do + if book.title == title then return book end + end end function Librarian:AddBook(book) - if not self:FindCharacterBook(book.title) then - if not self:FindBook(book.title) then - book.timeStamp = GetTimeStamp() - book.unread = true - local wordCount = 0 - for w in book.body:gmatch("%S+") do wordCount = wordCount + 1 end - book.wordCount = wordCount - - local newBody = book.body - book.body = {} - while string.len(newBody) > 1024 do - table.insert(book.body, string.sub(newBody, 0, 1024)) - newBody = string.sub(newBody, 1025) - end - table.insert(book.body, newBody) - - table.insert(self.books, book) - end - - local characterBook = { title = book.title, timeStamp = GetTimeStamp() } - table.insert(self.characterBooks, characterBook) - - self:RefreshData() - if self.settings.alertEnabled then - CENTER_SCREEN_ANNOUNCE:AddMessage(EVENT_SKILL_RANK_UPDATE, CSA_EVENT_LARGE_TEXT, SOUNDS.BOOK_ACQUIRED, GetString(SI_LIBRARIAN_NEW_BOOK_FOUND)) - end - if self.settings.chatEnabled then - d(string.format(GetString(SI_LIBRARIAN_NEW_BOOK_FOUND_WITH_TITLE), book.title)) - end - - self.newBookCount = self.newBookCount + 1 - if self.settings.reloadReminderBookCount and self.settings.reloadReminderBookCount > 0 and self.settings.reloadReminderBookCount <= self.newBookCount then - d(GetString(SI_LIBRARIAN_RELOAD_REMINDER)) - end - end + if not self:FindCharacterBook(book.title) then + if not self:FindBook(book.title) then + book.timeStamp = GetTimeStamp() + book.unread = true + local wordCount = 0 + for w in book.body:gmatch("%S+") do wordCount = wordCount + 1 end + book.wordCount = wordCount + + local newBody = book.body + book.body = {} + while string.len(newBody) > 1024 do + table.insert(book.body, string.sub(newBody, 0, 1024)) + newBody = string.sub(newBody, 1025) + end + table.insert(book.body, newBody) + + table.insert(self.books, book) + end + + local characterBook = { title = book.title, timeStamp = GetTimeStamp() } + table.insert(self.characterBooks, characterBook) + + self:RefreshData() + if self.settings.alertEnabled then + CENTER_SCREEN_ANNOUNCE:AddMessage(EVENT_SKILL_RANK_UPDATE, CSA_EVENT_LARGE_TEXT, SOUNDS.BOOK_ACQUIRED, GetString(SI_LIBRARIAN_NEW_BOOK_FOUND)) + end + if self.settings.chatEnabled then + d(string.format(GetString(SI_LIBRARIAN_NEW_BOOK_FOUND_WITH_TITLE), book.title)) + end + + self.newBookCount = self.newBookCount + 1 + if self.settings.reloadReminderBookCount and self.settings.reloadReminderBookCount > 0 and self.settings.reloadReminderBookCount <= self.newBookCount then + d(GetString(SI_LIBRARIAN_RELOAD_REMINDER)) + end + end end function Librarian:Toggle() - if LibrarianFrame:IsControlHidden() then - SCENE_MANAGER:Show("librarian") - else - SCENE_MANAGER:Hide("librarian") - end + if LibrarianFrame:IsControlHidden() then + SCENE_MANAGER:Show("librarian") + else + SCENE_MANAGER:Hide("librarian") + end end function Librarian:ReadBook(title) - local book = self:FindBook(title) - LORE_READER:SetupBook(book.title, book.body and table.concat(book.body), book.medium, book.showTitle) + local book = self:FindBook(title) + LORE_READER:SetupBook(book.title, book.body and table.concat(book.body), book.medium, book.showTitle) SCENE_MANAGER:Push("loreReaderInteraction") PlaySound(LORE_READER.OpenSound) end @@ -481,12 +498,12 @@ function Librarian:FormatClockTime(time) local utcSeconds = GetTimeStamp() % 86400 local offset = midnightSeconds - utcSeconds if offset < -43200 then - offset = offset + 86400 + offset = offset + 86400 end local dateString = GetDateStringFromTimestamp(time) local timeString = ZO_FormatTime((time + offset) % 86400, TIME_FORMAT_STYLE_CLOCK_TIME, self.settings.timeFormat) - return string.format("%s %s", dateString, timeString) + return string.format("%s %s", dateString, timeString) end function Librarian:OnSearchTextChanged() @@ -495,18 +512,18 @@ function Librarian:OnSearchTextChanged() end local function SlashCommand(args) - Librarian:Toggle() + Librarian:Toggle() end local function OnAddonLoaded(event, addon) - if addon == "Librarian" then - LIBRARIAN = Librarian:New() - end + if addon == "Librarian" then + LIBRARIAN = Librarian:New() + end end local function OnShowBook(eventCode, title, body, medium, showTitle) - local book = { title = title, body = body, medium = medium, showTitle = showTitle } - LIBRARIAN:AddBook(book) + local book = { title = title, body = body, medium = medium, showTitle = showTitle } + LIBRARIAN:AddBook(book) end function LibrarianRow_OnMouseEnter(control) diff --git a/Librarian.xml b/Librarian.xml index 11f4a96..3069771 100644 --- a/Librarian.xml +++ b/Librarian.xml @@ -30,6 +30,18 @@ </Button> <TopLevelControl name="LibrarianFrame" inherits="ZO_RightPanelFootPrint" hidden="true"> <Controls> + <Button name="$(parent)Options" mouseOverBlendMode="ADD" inherits="ZO_ButtonBehaviorClickSound"> + <Dimensions x="48" y="48" /> + <Anchor point="BOTTOMRIGHT" relativePoint="TOPRIGHT" /> + <Textures + normal="EsoUI/Art/ChatWindow/chat_options_up.dds" + pressed="EsoUI/Art/ChatWindow/chat_options_down.dds" + mouseOver="EsoUI/Art/ChatWindow/chat_options_over.dds" + /> + <OnClicked> + SLASH_COMMANDS["/librarianOptions"]() + </OnClicked> + </Button> <Label name="$(parent)BookCount" font="ZoFontHeader3" color="INTERFACE_COLOR_TYPE_TEXT_COLORS:INTERFACE_TEXT_COLOR_NORMAL"> <Anchor point="TOPLEFT" offsetY="10" /> </Label> diff --git a/LibrarianSettings.lua b/LibrarianSettings.lua index 244b0a6..a7c6fc0 100644 --- a/LibrarianSettings.lua +++ b/LibrarianSettings.lua @@ -69,14 +69,18 @@ function LibrarianSettings:Initialise(settings) if self.settings.reloadReminderBookCount == nil then self.settings.reloadReminderBookCount = 5 end + + if self.settings.enableCharacterSpin == nil then + self.settings.enableCharacterSpin = true + end local panelData = { type = "panel", name = "Librarian", displayName = "Librarian Book Manager", author = "Flamage", - version = "1.2.5", - slashCommand = "/lo" + version = "1.2.6", + slashCommand = "/librarianOptions" } local optionsTable = { @@ -123,6 +127,17 @@ function LibrarianSettings:Initialise(settings) setFunc = function(value) self.settings.showUnreadIndicatorInReader = value end }, [5] = { + type = "checkbox", + name = "Character Spin", + tooltip = "Allow the character to spin and face the camera when Librarian is open.", + getFunc = function() return self.settings.enableCharacterSpin end, + setFunc = function(value) + self.settings.enableCharacterSpin = value + SLASH_COMMANDS["/reloadui"]() + end, + warning = "UI will be reloaded automatically." + }, + [6] = { type = "button", name = "Import from Lore Library", tooltip = "Import any missing books from the Lore Library. Works with all books once Eidetic Memory is unlocked.",