diff --git a/src/Classes/NotesListControl.lua b/src/Classes/NotesListControl.lua new file mode 100644 index 0000000000..f86f9e2d97 --- /dev/null +++ b/src/Classes/NotesListControl.lua @@ -0,0 +1,101 @@ +-- Path of Building +-- +-- Class: Note List +-- Note list control. +-- +local t_insert = table.insert +local t_remove = table.remove +local m_max = math.max + +local NotesListClass = newClass("NotesListControl", "ListControl", function(self, anchor, rect, notesTab) + self.ListControl(anchor, rect, 16, "VERTICAL", true, notesTab.notesOrderList) + self.notesTab = notesTab + + self.label = "^7Notes:" + self.controls.delete = new("ButtonControl", {"BOTTOMRIGHT",self,"TOPRIGHT"}, {0, -2, 60, 18}, "Delete", function() + self:OnSelDelete(self.selIndex, self.selValue) + end) + + self.controls.delete.enabled = function() + return self.selValue ~= nil and #self.list > 1 + end + + self.controls.rename = new("ButtonControl", {"RIGHT",self.controls.delete,"LEFT"}, {-2, 0, 60, 18}, "Rename", function() + self:RenameNote(notesTab.notes[self.selValue]) + end) + self.controls.rename.enabled = function() + return self.selValue ~= nil + end + + self.controls.new = new("ButtonControl", {"RIGHT",self.controls.rename,"LEFT"}, {-2, 0, 60, 18}, "New", function() + self:RenameNote(notesTab:NewNote(), true) + end) +end) + +-- Triggered when the order of the list has changed +function NotesListClass:OnOrderChange(selIndex, selDragIndex) + self.notesTab.modFlag = true +end + +function NotesListClass:OnSelDelete(index, noteId) + local note = self.notesTab.notes[noteId] + if #self.list > 1 then + main:OpenConfirmPopup("Delete Note", "Are you sure you want to delete '"..(note.title or "Default").."'?", "Delete", function() + t_remove(self.list, index) + self.notesTab.notes[noteId] = nil + + self.selIndex = nil + self.selValue = nil + + if noteId == self.notesTab.activeNoteId then + self.notesTab:SetActiveNote(self.list[m_max(1, index - 1)]) + end + end) + end +end + +-- Get the value to display in the list row +function NotesListClass:GetRowValue(column, index, noteId) + local note = self.notesTab.notes[noteId] + if column == 1 then + return (note.title or "Default") .. (noteId == self.notesTab.activeNoteId and " ^9(Current)" or "") + end +end + +function NotesListClass:RenameNote(note, addOnName) + local controls = { } + controls.label = new("LabelControl", nil, {0, 20, 0, 16}, "^7Enter name for this note:") + controls.edit = new("EditControl", nil, {0, 40, 350, 20}, note.title, nil, nil, 100, function(buf) + controls.save.enabled = buf:match("%S") + end) + controls.save = new("ButtonControl", nil, {-45, 70, 80, 20}, "Save", function() + note.title = controls.edit.buf + self.notesTab.modFlag = true + + if addOnName then + t_insert(self.list, note.id) + self.selIndex = #self.list + self.selValue = note.id + end + + self.notesTab:SetActiveNote(note.id) + main:ClosePopup() + end) + controls.save.enabled = false + controls.cancel = new("ButtonControl", nil, {45, 70, 80, 20}, "Cancel", function() + if addOnName then + self.notesTab.notes[note.id] = nil + end + main:ClosePopup() + end) + main:OpenPopup(370, 100, note.title and "Rename" or "Note Name", controls, "save", "edit", "cancel") +end + +-- Triggered when a note is selected from the list +function NotesListClass:OnSelClick(index, noteId, doubleClick) + self.notesTab:SaveContentToNote(self.notesTab.activeNoteId) + + if doubleClick and noteId ~= self.notesTab.activeNoteId then + self.notesTab:SetActiveNote(noteId) + end +end diff --git a/src/Classes/NotesTab.lua b/src/Classes/NotesTab.lua index f78ea2eb41..ac436df4ab 100644 --- a/src/Classes/NotesTab.lua +++ b/src/Classes/NotesTab.lua @@ -11,13 +11,21 @@ local NotesTabClass = newClass("NotesTab", "ControlHost", "Control", function(se self.build = build - self.lastContent = "" + self.notes = { } + self.notesOrderList = { } + self.showColorCodes = false + local listSize = 250 + local notesDesc = [[^7You can use Ctrl +/- (or Ctrl+Scroll) to zoom in and out and Ctrl+0 to reset. This field also supports different colors. Using the caret symbol (^) followed by a Hex code or a number (0-9) will set the color. Below are some common color codes PoB uses: ]] - self.controls.notesDesc = new("LabelControl", {"TOPLEFT",self,"TOPLEFT"}, {8, 8, 150, 16}, notesDesc) + + -- Notes group list + self.controls.noteList = new("NotesListControl", { "TOPLEFT", self, "TOPLEFT" }, { 8, 30, listSize - 16, 80 }, self) + + self.controls.notesDesc = new("LabelControl", {"TOPLEFT",self.controls.noteList,"TOPRIGHT"}, {8, -22, 150, 16}, notesDesc) self.controls.normal = new("ButtonControl", {"TOPLEFT",self.controls.notesDesc,"TOPLEFT"}, {0, 48, 100, 18}, colorCodes.NORMAL.."NORMAL", function() self:SetColor(colorCodes.NORMAL) end) self.controls.magic = new("ButtonControl", {"TOPLEFT",self.controls.normal,"TOPLEFT"}, {120, 0, 100, 18}, colorCodes.MAGIC.."MAGIC", function() self:SetColor(colorCodes.MAGIC) end) self.controls.rare = new("ButtonControl", {"TOPLEFT",self.controls.magic,"TOPLEFT"}, {120, 0, 100, 18}, colorCodes.RARE.."RARE", function() self:SetColor(colorCodes.RARE) end) @@ -31,7 +39,7 @@ Below are some common color codes PoB uses: ]] self.controls.intelligence = new("ButtonControl", {"TOPLEFT",self.controls.dexterity,"TOPLEFT"}, {120, 0, 100, 18}, colorCodes.INTELLIGENCE.."INTELLIGENCE", function() self:SetColor(colorCodes.INTELLIGENCE) end) self.controls.default = new("ButtonControl", {"TOPLEFT",self.controls.intelligence,"TOPLEFT"}, {120, 0, 100, 18}, "^7DEFAULT", function() self:SetColor("^7") end) - self.controls.edit = new("EditControl", {"TOPLEFT",self.controls.fire,"TOPLEFT"}, {0, 48, 0, 0}, "", nil, "^%C\t\n", nil, nil, 16, true) + self.controls.edit = new("EditControl", {"TOPLEFT",self.controls.noteList,"BOTTOMLEFT"}, {0, 8, 0, 0}, "", nil, "^%C\t\n", nil, nil, 16, true) self.controls.edit.width = function() return self.width - 16 end @@ -42,6 +50,9 @@ Below are some common color codes PoB uses: ]] self.showColorCodes = not self.showColorCodes self:SetShowColorCodes(self.showColorCodes) end) + + self:SetActiveNote(1) + self:SelectControl(self.controls.edit) end) @@ -68,18 +79,62 @@ function NotesTabClass:SetColor(color) end function NotesTabClass:Load(xml, fileName) - for _, node in ipairs(xml) do + self.activeNoteId = 0 + self.notes = { } + self.noteOrderList = { } + + for index, node in ipairs(xml) do + -- backwards compatibility if type(node) == "string" then - self.controls.edit:SetText(node) + self.notesOrderList[1] = 1 + self.notes[1] = { + id = 1, + content = node + } + + self:SetActiveNote(1) + else + local savedNoteId = tonumber(node.attrib.id) + self.notesOrderList[index] = savedNoteId + + self.notes[savedNoteId] = { + id = savedNoteId, + title = node.attrib.title, + content = node[1] or "" + } + + if node.attrib.active ~= nil then + self:SetActiveNote(savedNoteId) + end end end - self.lastContent = self.controls.edit.buf + + self.modFlag = false end function NotesTabClass:Save(xml) self:SetShowColorCodes(false) - t_insert(xml, self.controls.edit.buf) - self.lastContent = self.controls.edit.buf + + self.notes[self.activeNoteId].content = self.controls.edit.buf + + for _, noteId in ipairs(self.notesOrderList) do + local attrib = { + id = tostring(noteId), + title = self.notes[noteId].title, + } + + if self.activeNoteId == noteId then + attrib.active = "1" + end + + local note = { + elem = "Note", + attrib = attrib, + [1] = self.notes[noteId].content + } + + t_insert(xml, note) + end end function NotesTabClass:Draw(viewPort, inputEvents) @@ -91,17 +146,63 @@ function NotesTabClass:Draw(viewPort, inputEvents) for id, event in ipairs(inputEvents) do if event.type == "KeyDown" then if event.key == "z" and IsKeyDown("CTRL") then - self.controls.edit:Undo() + if self.controls.edit.hasFocus then + self.controls.edit:Undo() + end elseif event.key == "y" and IsKeyDown("CTRL") then - self.controls.edit:Redo() + if self.controls.edit.hasFocus then + self.controls.edit:Redo() + end end end end + self:ProcessControlsInput(inputEvents, viewPort) main:DrawBackground(viewPort) self:DrawControls(viewPort) - self.modFlag = (self.lastContent ~= self.controls.edit.buf) + self.modFlag = (self.notes[self.activeNoteId].content ~= self.controls.edit.buf) or self.modFlag +end + +-- Creates a new note +function NotesTabClass:NewNote(noteId) + local note = { id = noteId, content = "" } + + if not noteId then + note.id = 1 + while self.notes[note.id] do + note.id = note.id + 1 + end + end + + self.notes[note.id] = note + + return note +end + +-- Changes the active note +function NotesTabClass:SetActiveNote(noteId) + -- Initialize note if needed + if not self.notesOrderList[1] then + self.notesOrderList[1] = 1 + self:NewNote(1) + end + + if not noteId then + noteId = self.activeNoteId + end + + if not self.notes[noteId] then + noteId = self.notesOrderList[1] + end + + self.activeNoteId = noteId + self.notes[self.activeNoteId].lastContent = self.controls.edit.buf + self.controls.edit:SetText(self.notes[noteId].content) +end + +function NotesTabClass:SaveContentToNote(noteId) + self.notes[noteId].content = self.controls.edit.buf end