Compare with Previous | Blame | View Log
-- ZAM_Notebook © ZAM Network LLC -- All Rights Reserved local wm = WINDOW_MANAGER local em = EVENT_MANAGER local znb, db, indexPool, currentlyViewing local tinsert = table.insert local tremove = table.remove local defaults = { anchor = { a = CENTER, b = CENTER, x = 0, y = 0, } } local function ProtectText(text) --protect against backslashes corrupting our saved variables return text:gsub([[\]], [[%%92]]) end local function UnprotectText(text) --convert back to what should be displayed return text:gsub([[%%92]], [[\]]) end local buttonCount = 1 local function CreateIndexButton(indexPool) local button = ZO_ObjectPool_CreateControl("ZAM_NotebookIndex", indexPool, znb.menu.scrollChild) local anchorBtn = buttonCount == 1 and znb.menu.scrollChild or indexPool:AcquireObject(buttonCount-1) button:SetAnchor(TOPLEFT, anchorBtn, buttonCount == 1 and TOPLEFT or BOTTOMLEFT) button:SetHorizontalAlignment(TEXT_ALIGN_LEFT) button:SetWidth(190) button:SetHandler("OnClicked", function(self) znb.titleEdit:SetText(UnprotectText(self.data.title)) znb.edit:SetText(UnprotectText(self.data.text)) currentlyViewing = self.id znb.save.highlight:SetHidden(true) znb.selectedHL:SetHidden(false) znb.selectedHL:ClearAnchors() znb.selectedHL:SetAnchorFill(self) end) buttonCount = buttonCount + 1 return button end local function RemoveIndexButton(button) button:SetHidden(true) end local function PopulateScrollList() local numPages = #db.pages for i = 1, numPages do local button = indexPool:AcquireObject(i) button.data = db.pages[i] button.id = i button:SetText(UnprotectText(button.data.title)) button:SetHidden(false) end local activePages = indexPool:GetActiveObjectCount() if activePages > numPages then for i = numPages+1, activePages do indexPool:ReleaseObject(i) end end end local function CreateNotebook() --main window znb = wm:CreateTopLevelWindow("ZAM_Notebook") znb:SetDimensions(800, 650) znb:SetAnchor(db.anchor.a, GuiRoot, db.anchor.b, db.anchor.x, db.anchor.y) znb:SetClampedToScreen(true) znb:SetMouseEnabled(true) znb:SetMovable(true) znb:SetHandler("OnReceiveDrag", function(self) --if not db.locked then self:StartMoving() --end end) znb:SetHandler("OnMouseUp", function(self) self:StopMovingOrResizing() local _,a,_,b,x,y = self:GetAnchor() db.anchor = {["a"]=a, ["b"]=b, ["x"]=x, ["y"]=y} end) --window bg znb.bg = wm:CreateControl("ZAM_NotebookBG", znb, CT_TEXTURE) znb.bg:SetTexture("ZAM_Notebook\\NotebookBG.dds") znb.bg:SetTextureCoords(0, 0.98, 0, 0.85) znb.bg:SetAnchorFill(znb) --window title znb.title = wm:CreateControl("ZAM_NotebookTitle", znb, CT_LABEL) znb.title:SetAnchor(TOPLEFT, znb, TOPLEFT, 50, 50) znb.title:SetFont("ZoFontWindowTitle") znb.title:SetText("ZAM Notebook") --divider below title znb.titleDiv = wm:CreateControl("ZAM_NotebookTitleDiv", znb, CT_TEXTURE) znb.titleDiv:SetDimensions(800, 4) znb.titleDiv:SetAnchor(TOPLEFT, znb.title, BOTTOMLEFT, -50, 5) znb.titleDiv:SetTexture("EsoUI\\Art\\Miscellaneous\\centerscreen_topDivider.dds") --pages menu znb.menu = wm:CreateControlFromVirtual("ZAM_NotebookMenu", znb, "ZO_ScrollContainer") znb.menu:SetAnchor(TOPLEFT, znb.titleDiv, BOTTOMLEFT, 70, 30) znb.menu:SetAnchor(BOTTOMLEFT, znb, BOTTOMLEFT, 70, -60) znb.menu:SetWidth(200) znb.menu.scrollChild = znb.menu:GetNamedChild("ScrollChild") --page selected highlight znb.selectedHL = wm:CreateControl(nil, znb.menu.scrollChild, CT_TEXTURE) local selectedHL = znb.selectedHL selectedHL:SetTexture("EsoUI\\Art\\Buttons\\generic_highlight.dds") selectedHL:SetHidden(true) --divider between menu and notebook editbox znb.divider = wm:CreateControl("ZAM_NotebookDivider", znb, CT_TEXTURE) znb.divider:SetAnchor(TOPLEFT, znb.menu, TOPRIGHT, 15, -15) znb.divider:SetAnchor(BOTTOMLEFT, znb.menu, BOTTOMRIGHT) znb.divider:SetWidth(4) znb.divider:SetTexture("EsoUI\\Art\\Miscellaneous\\window_edge.dds") --page title editbox bg znb.titleEditbg = wm:CreateControlFromVirtual("ZAM_NotebookTitleEditBG", znb, "ZO_EditBackdrop") znb.titleEditbg:SetDimensions(250, 28) znb.titleEditbg:SetAnchor(TOPLEFT, znb.divider, TOPRIGHT, 15, 15) --page title editbox znb.titleEdit = wm:CreateControlFromVirtual("ZAM_NotebookTitleEdit", znb.titleEditbg, "ZO_DefaultEditForBackdrop") znb.titleEdit:SetHandler("OnTab", function() znb.edit:TakeFocus() end) znb.titleEdit:SetHandler("OnEscape", znb.titleEdit.LoseFocus) --editbox bg znb.editbg = wm:CreateControlFromVirtual("ZAM_NotebookEditBG", znb, "ZO_EditBackdrop") znb.editbg:SetDimensions(450, 350) znb.editbg:SetAnchor(TOPLEFT, znb.titleEditbg, BOTTOMLEFT, 0, 15) --editbox znb.edit = wm:CreateControlFromVirtual("ZAM_NotebookEdit", znb.editbg, "ZO_DefaultEditMultiLineForBackdrop") znb.edit:SetMaxInputChars(3000) znb.edit:SetHandler("OnTab", function() if IsShiftKeyDown() then znb.titleEdit:TakeFocus() end end) znb.edit:SetHandler("OnEscape", znb.edit.LoseFocus) znb.edit:SetHandler("OnMouseWheel", function(self, delta) if self:HasFocus() then --only set focus to new spots if the editbox is currently in use local cursorPos = self:GetCursorPosition() local text = self:GetText() local textLen = text:len() local newPos if delta > 0 then --scrolling up local reverseText = text:reverse() local revCursorPos = textLen - cursorPos local revPos = reverseText:find("\n", revCursorPos+1) newPos = revPos and textLen - revPos else --scrolling down newPos = text:find("\n", cursorPos+1) end if newPos then --if we found a new line, then scroll, otherwise don't self:SetCursorPosition(newPos) end end end) --run script button znb.run = wm:CreateControl("ZAM_NotebookRun", znb, CT_BUTTON) znb.run:SetDimensions(34, 34) znb.run:SetAnchor(TOPLEFT, znb.editbg, BOTTOMLEFT, 0, 12) znb.run:SetNormalTexture("EsoUI\\Art\\Buttons\\edit_up.dds") znb.run:SetPressedTexture("EsoUI\\Art\\Buttons\\edit_down.dds") znb.run:SetMouseOverTexture("EsoUI\\Art\\Buttons\\edit_over.dds") znb.run.data = {tooltipText = "Run this page as a Lua script."} znb.run:SetHandler("OnMouseEnter", ZO_Options_OnMouseEnter) znb.run:SetHandler("OnMouseExit", ZO_Options_OnMouseExit) --setting to run at startup? znb.run:SetHandler("OnClicked", function() local znbScript = zo_loadstring(znb.edit:GetText()) if znbScript then znbScript() end end) --undo changes button znb.undo = wm:CreateControl("ZAM_NotebookUndo", znb, CT_BUTTON) znb.undo:SetDimensions(30, 30) znb.undo:SetAnchor(LEFT, znb.run, RIGHT, 15, 1) znb.undo:SetNormalTexture("EsoUI\\Art\\Buttons\\decline_up.dds") znb.undo:SetPressedTexture("EsoUI\\Art\\Buttons\\decline_down.dds") znb.undo:SetMouseOverTexture("EsoUI\\Art\\Buttons\\decline_over.dds") znb.undo.data = {tooltipText = "Undo changes made to this page."} znb.undo:SetHandler("OnMouseEnter", ZO_Options_OnMouseEnter) znb.undo:SetHandler("OnMouseExit", ZO_Options_OnMouseExit) znb.undo:SetHandler("OnClicked", function() if currentlyViewing then znb.titleEdit:SetText(db.pages[currentlyViewing].title) znb.edit:SetText(db.pages[currentlyViewing].text) end end) --save changes button znb.save = wm:CreateControl("ZAM_NotebookSave", znb, CT_BUTTON) znb.save.highlight = wm:CreateControl("ZAM_NotebookSaveHL", znb.save, CT_TEXTURE) local highlight = znb.save.highlight znb.save:SetDimensions(30, 30) znb.save:SetAnchor(LEFT, znb.undo, RIGHT, 15, 1) znb.save:SetNormalTexture("EsoUI\\Art\\Buttons\\accept_up.dds") znb.save:SetPressedTexture("EsoUI\\Art\\Buttons\\accept_down.dds") znb.save:SetMouseOverTexture("EsoUI\\Art\\Buttons\\accept_over.dds") znb.save.data = {tooltipText = "Save changes made to this page."} znb.save:SetHandler("OnMouseEnter", ZO_Options_OnMouseEnter) znb.save:SetHandler("OnMouseExit", ZO_Options_OnMouseExit) znb.save:SetHandler("OnClicked", function(self) local titleText = znb.titleEdit:GetText() if titleText == "" then znb.titleEdit:SetText("New Page "..#db.pages+1) titleText = znb.titleEdit:GetText() end local pageText = znb.edit:GetText() --with the changes to how text is stored in saved variables, literal strings work again. --if pageText:find("%[%[") then -- error([=[ZAM_Notebook does not support literal strings. -- -- This would cause a nested literal string error and erase your saved variables data. -- Please edit your page text before saving to remove the literal string. ( [[...]] )]=], 0) -- return --end]] --so now we need to prevent escaped quotes instead... --if pageText:find("%\\\"") then -- error([=[ZAM_Notebook does not support escaped double-quotes. -- -- Because ESO saved variables currently escape any double-quotes found in their contents, -- this would cause a malformed table error and erase your saved variables data. -- -- Please edit your page text before saving to remove the escaped double-quote ( \" ). -- You may use a single quote instead ( \' ) or change to use a literal string. ( [[ "quote" ]] )]=], 0) -- return --end local safe_pageText = ProtectText(pageText) local safe_titleText = ProtectText(titleText) if currentlyViewing == nil then --if this was a new page tinsert(db.pages, {["title"] = safe_titleText, ["text"]=safe_pageText}) currentlyViewing = #db.pages znb.selectedHL:SetHidden(false) znb.selectedHL:ClearAnchors() self.new = true else db.pages[currentlyViewing].title = safe_titleText db.pages[currentlyViewing].text = safe_pageText self.new = false end PopulateScrollList() if self.new then znb.selectedHL:SetAnchorFill(_G["ZAM_NotebookIndex"..currentlyViewing]) end highlight:SetHidden(true) end) highlight:SetAnchor(TOPLEFT, znb.save, TOPLEFT, -15, -15) highlight:SetAnchor(BOTTOMRIGHT, znb.save, BOTTOMRIGHT, 15, 15) highlight:SetTexture("EsoUI\\Art\\Miscellaneous\\icon_highlight_pulse.dds") highlight:SetAlpha(.75) highlight:SetHidden(true) znb.titleEdit:SetHandler("OnTextChanged", function(self) local page = db.pages[currentlyViewing] if not page or self:GetText() ~= page.title or self:GetText() then highlight:SetHidden(false) else highlight:SetHidden(true) end end) znb.edit:SetHandler("OnTextChanged", function(self) local page = db.pages[currentlyViewing] if not page or self:GetText() ~= page.text or self:GetText() then highlight:SetHidden(false) else highlight:SetHidden(true) end end) --close window button znb.close = wm:CreateControlFromVirtual("ZAM_NotebookClose", znb, "ZO_DefaultTextButton") znb.close:SetText("Close") znb.close:SetAnchor(TOPRIGHT, znb.editbg, BOTTOMRIGHT, 0, 15) znb.close:SetWidth(75) znb.close:SetHandler("OnClicked", function() znb:SetHidden(true) end) --new page button znb.new = wm:CreateControl("ZAM_NotebookNew", znb, CT_BUTTON) znb.new:SetDimensions(30, 30) znb.new:SetAnchor(LEFT, znb.titleEditbg, RIGHT, 15, 0) znb.new:SetNormalTexture("EsoUI\\Art\\Buttons\\pointsplus_up.dds") znb.new:SetPressedTexture("EsoUI\\Art\\Buttons\\pointsplus_down.dds") znb.new:SetMouseOverTexture("EsoUI\\Art\\Buttons\\pointsplus_over.dds") znb.new.data = {tooltipText = "Create a new page."} znb.new:SetHandler("OnMouseEnter", ZO_Options_OnMouseEnter) znb.new:SetHandler("OnMouseExit", ZO_Options_OnMouseExit) znb.new:SetHandler("OnClicked", function() currentlyViewing = nil znb.titleEdit:SetText("New Page "..#db.pages+1) znb.titleEdit:SelectAll() znb.titleEdit:TakeFocus() znb.edit:Clear() end) --delete page button znb.delete = wm:CreateControl("ZAM_NotebookDelete", znb, CT_BUTTON) znb.delete:SetDimensions(32, 32) znb.delete:SetAnchor(LEFT, znb.new, RIGHT, 15, 0) znb.delete:SetNormalTexture("EsoUI\\Art\\Buttons\\minus_up.dds") znb.delete:SetPressedTexture("EsoUI\\Art\\Buttons\\minus_down.dds") znb.delete:SetMouseOverTexture("EsoUI\\Art\\Buttons\\minus_over.dds") znb.delete.data = {tooltipText = "Delete this page."} znb.delete:SetHandler("OnMouseEnter", ZO_Options_OnMouseEnter) znb.delete:SetHandler("OnMouseExit", ZO_Options_OnMouseExit) znb.delete:SetHandler("OnClicked", function() if currentlyViewing then tremove(db.pages, currentlyViewing) currentlyViewing = nil PopulateScrollList() znb.save.highlight:SetHidden(true) znb.selectedHL:SetHidden(true) end znb.titleEdit:Clear() znb.edit:Clear() highlight:SetHidden(true) end) znb:SetHidden(true) end --global for keybind function ZAMNotebookToggleVisibility() if znb:IsHidden() then znb:SetHidden(false) if not SCENE_MANAGER:IsInUIMode() then SCENE_MANAGER:SetInUIMode(true) end else znb:SetHidden(true) end end local function Initialize() ZAM_NotebookDB = ZAM_NotebookDB or {} for k,v in pairs(defaults) do if type(ZAM_NotebookDB[k]) == "nil" then ZAM_NotebookDB[k] = v end end ZAM_NotebookDB.pages = ZAM_NotebookDB.pages or {} db = ZAM_NotebookDB indexPool = ZO_ObjectPool:New(CreateIndexButton, RemoveIndexButton) ZO_CreateStringId("SI_BINDING_NAME_ZAM_NOTEBOOK_TOGGLE", "Toggle ZAM Notebook") SLASH_COMMANDS["/znb"] = ZAMNotebookToggleVisibility end em:RegisterForEvent("ZAM_Notebook", EVENT_ADD_ON_LOADED, function(event, addon) --em:RegisterForEvent("ZAM_Notebook", EVENT_PLAYER_ACTIVATED, function(event, addon) if addon == "ZAM_Notebook" then Initialize() CreateNotebook() PopulateScrollList() end end)