From 9823c911574506256e84ba7507ac79390acf52f4 Mon Sep 17 00:00:00 2001 From: Openarl Date: Wed, 23 Nov 2016 21:08:42 +1000 Subject: [PATCH] Release 1.2.14 - Added a Notes tab --- Classes/BuildListControl.lua | 2 +- Classes/ConfigTab.lua | 6 +- Classes/EditControl.lua | 255 ++++++++++++++++++++++++----------- Classes/GemSelectControl.lua | 2 +- Classes/ImportTab.lua | 10 +- Classes/ItemDBControl.lua | 2 +- Classes/NotesTab.lua | 63 +++++++++ Classes/SkillsTab.lua | 6 +- Classes/TreeTab.lua | 4 +- Modules/Build.lua | 14 +- Modules/Main.lua | 3 +- PathOfBuilding.sln | 1 + README.md | 3 + changelog.txt | 2 + manifest.xml | 25 ++-- 15 files changed, 288 insertions(+), 110 deletions(-) create mode 100644 Classes/NotesTab.lua diff --git a/Classes/BuildListControl.lua b/Classes/BuildListControl.lua index a8078be6..c264ebb5 100644 --- a/Classes/BuildListControl.lua +++ b/Classes/BuildListControl.lua @@ -23,7 +23,7 @@ local BuildListClass = common.NewClass("BuildList", "Control", "ControlHost", fu self.controls.scrollBar.locked = function() return self.listMode.edit end - self.controls.nameEdit = common.New("EditControl", {"TOPLEFT",self,"TOPLEFT"}, 0, 0, 0, 20, nil, nil, "[%w _+-.()'\"]", 50) + self.controls.nameEdit = common.New("EditControl", {"TOPLEFT",self,"TOPLEFT"}, 0, 0, 0, 20, nil, nil, "\\/:%*%?\"<>|", 50) self.controls.nameEdit.shown = function() return self.listMode.edit end diff --git a/Classes/ConfigTab.lua b/Classes/ConfigTab.lua index 0e4c1c90..3105aba1 100644 --- a/Classes/ConfigTab.lua +++ b/Classes/ConfigTab.lua @@ -109,10 +109,6 @@ local ConfigTabClass = common.NewClass("ConfigTab", "UndoHandler", "ControlHost" self:BuildModList() - if launch.devMode then - self.controls.test = common.New("EditControl", {"TOPLEFT",self,"TOPLEFT"}, 500, 50, 300, 300, "", nil, "[%C\n]", 500, nil, 14) - end - local lastSection for _, varData in ipairs(varList) do if varData.section then @@ -143,7 +139,7 @@ local ConfigTabClass = common.NewClass("ConfigTab", "UndoHandler", "ControlHost" self.build.buildFlag = true end) elseif varData.type == "number" then - control = common.New("EditControl", {"TOPLEFT",lastSection,"TOPLEFT"}, 216, 0, 50, 18, "", nil, "[%-%d]", 4, function(buf) + control = common.New("EditControl", {"TOPLEFT",lastSection,"TOPLEFT"}, 216, 0, 50, 18, "", nil, "^%-%d", 4, function(buf) self.input[varData.var] = tonumber(buf) self:AddUndoState() self:BuildModList() diff --git a/Classes/EditControl.lua b/Classes/EditControl.lua index 5174988d..5c1a86da 100644 --- a/Classes/EditControl.lua +++ b/Classes/EditControl.lua @@ -9,12 +9,41 @@ local m_max = math.max local m_min = math.min local m_floor = math.floor -local EditClass = common.NewClass("EditControl", "ControlHost", "Control", function(self, anchor, x, y, width, height, init, prompt, filter, limit, changeFunc, lineHeight) +local function lastLine(str) + local lastLineIndex = 1 + while true do + local nextLine = str:find("\n", lastLineIndex, true) + if nextLine then + lastLineIndex = nextLine + 1 + else + break + end + end + return str:sub(lastLineIndex, -1) +end + +local function newlineCount(str) + local count = 0 + local lastLineIndex = 1 + while true do + local nextLine = str:find("\n", lastLineIndex, true) + if nextLine then + count = count + 1 + lastLineIndex = nextLine + 1 + else + return count + end + end +end + +local EditClass = common.NewClass("EditControl", "ControlHost", "Control", "UndoHandler", function(self, anchor, x, y, width, height, init, prompt, filter, limit, changeFunc, lineHeight) self.ControlHost() self.Control(anchor, x, y, width, height) + self.UndoHandler() self:SetText(init or "") self.prompt = prompt - self.filter = filter or "[%w%p ]" + self.filter = filter or "^%w%p " + self.filterPattern = "["..self.filter.."]" self.limit = limit self.changeFunc = changeFunc self.lineHeight = lineHeight @@ -24,7 +53,7 @@ local EditClass = common.NewClass("EditControl", "ControlHost", "Control", funct self.selCol = "^0" self.selBGCol = "^xBBBBBB" self.blinkStart = GetTime() - if self.filter == "[%d]" then + if self.filter == "%D" then -- Add +/- buttons for integer number edits local function buttonSize() local width, height = self:GetSize() @@ -33,10 +62,24 @@ local EditClass = common.NewClass("EditControl", "ControlHost", "Control", funct self.controls.buttonDown = common.New("ButtonControl", {"RIGHT",self,"RIGHT"}, -2, 0, buttonSize, buttonSize, "-", function() self:OnKeyUp("DOWN") end) - self.controls.buttonUp = common.New("ButtonControl", {"RIGHT",self.controls.buttonDown,"LEFT"}, 0, 0, buttonSize, buttonSize, "+", function() + self.controls.buttonUp = common.New("ButtonControl", {"RIGHT",self.controls.buttonDown,"LEFT"}, -1, 0, buttonSize, buttonSize, "+", function() self:OnKeyUp("UP") end) end + self.controls.scrollBarH = common.New("ScrollBarControl", {"BOTTOMLEFT",self,"BOTTOMLEFT"}, 1, -1, 0, 14, 60, "HORIZONTAL", true) + self.controls.scrollBarH.width = function() + local width, height = self:GetSize() + return width - (self.controls.scrollBarV.enabled and 16 or 2) + end + self.controls.scrollBarV = common.New("ScrollBarControl", {"TOPRIGHT",self,"TOPRIGHT"}, -1, 1, 14, 0, (lineHeight or 0) * 3, "VERTICAL", true) + self.controls.scrollBarV.height = function() + local width, height = self:GetSize() + return height - (self.controls.scrollBarH.enabled and 16 or 2) + end + if not lineHeight then + self.controls.scrollBarH.shown = false + self.controls.scrollBarV.shown = false + end end) function EditClass:SetText(text, notify) @@ -46,6 +89,7 @@ function EditClass:SetText(text, notify) if notify and self.changeFunc then self.changeFunc(self.buf) end + self:ResetUndo() end function EditClass:IsMouseOver() @@ -56,15 +100,15 @@ function EditClass:IsMouseOver() end function EditClass:SelectAll() - self.caret = 1 - self.sel = #self.buf + 1 + self.caret = #self.buf + 1 + self.sel = 1 + self:ScrollCaretIntoView() end function EditClass:ReplaceSel(text) - for i = 1, #text do - if not text:sub(i,i):match(self.filter) then - return - end + text = text:gsub("\r","") + if text:match(self.filterPattern) then + return end local left = m_min(self.caret, self.sel) local right = m_max(self.caret, self.sel) @@ -75,17 +119,18 @@ function EditClass:ReplaceSel(text) self.buf = newBuf self.caret = left + #text self.sel = nil + self:ScrollCaretIntoView() self.blinkStart = GetTime() if self.changeFunc then self.changeFunc(self.buf) end + self:AddUndoState() end function EditClass:Insert(text) - for i = 1, #text do - if not text:sub(i,i):match(self.filter) then - return - end + text = text:gsub("\r","") + if text:match(self.filterPattern) then + return end local newBuf = self.buf:sub(1, self.caret - 1) .. text .. self.buf:sub(self.caret) if self.limit and #newBuf > self.limit then @@ -94,10 +139,45 @@ function EditClass:Insert(text) self.buf = newBuf self.caret = self.caret + #text self.sel = nil + self:ScrollCaretIntoView() self.blinkStart = GetTime() if self.changeFunc then self.changeFunc(self.buf) end + self:AddUndoState() +end + +function EditClass:UpdateScrollBars() + local width, height = self:GetSize() + local textHeight = self.lineHeight or (height - 4) + if self.lineHeight then + self.controls.scrollBarH:SetContentDimension(DrawStringWidth(textHeight, "VAR", self.buf) + 2, width - 18) + self.controls.scrollBarV:SetContentDimension(newlineCount(self.buf.."\n") * textHeight, height - (self.controls.scrollBarH.enabled and 18 or 4)) + else + self.controls.scrollBarH:SetContentDimension(DrawStringWidth(textHeight, "VAR", self.buf) + 2, width - 4 - (self.prompt and DrawStringWidth(textHeight, "VAR", self.prompt) + textHeight/2 or 0)) + end +end + +function EditClass:ScrollCaretIntoView() + local width, height = self:GetSize() + local textHeight = self.lineHeight or (height - 4) + local pre = self.buf:sub(1, self.caret - 1) + local caretX = DrawStringWidth(textHeight, "VAR", lastLine(pre)) + self:UpdateScrollBars() + self.controls.scrollBarH:ScrollIntoView(caretX - textHeight, textHeight * 2) + if self.lineHeight then + local caretY = newlineCount(pre) * textHeight + self.controls.scrollBarV:ScrollIntoView(caretY, textHeight) + end +end + +function EditClass:MoveCaretVertically(offset) + local pre = self.buf:sub(1, self.caret - 1) + local caretX = DrawStringWidth(self.lineHeight, "VAR", lastLine(pre)) + local caretY = newlineCount(pre) * self.lineHeight + self.caret = DrawStringCursorIndex(self.lineHeight, "VAR", self.buf, caretX + 1, caretY + self.lineHeight/2 + offset) + self:ScrollCaretIntoView() + self.blinkStart = GetTime() end function EditClass:Draw(viewPort) @@ -145,9 +225,14 @@ function EditClass:Draw(viewPort) main:DrawTooltip(x, y, width, height, viewPort) SetDrawLayer(nil, 0) end - SetViewport(textX, textY, width - 2 - (textX - x), height - 4) + self:UpdateScrollBars() + local marginL = textX - x - 2 + local marginR = self.controls.scrollBarV:IsShown() and 14 or 0 + local marginB = self.controls.scrollBarH:IsShown() and 14 or 0 + SetViewport(textX, textY, width - 4 - marginL - marginR, height - 4 - marginB) if not self.hasFocus then - DrawString(0, 0, "LEFT", textHeight, "VAR", self.inactiveCol..self.buf) + SetDrawColor(self.inactiveCol) + DrawString(-self.controls.scrollBarH.offset, -self.controls.scrollBarV.offset, "LEFT", textHeight, "VAR", self.buf) SetViewport() self:DrawControls(viewPort) return @@ -157,29 +242,32 @@ function EditClass:Draw(viewPort) end if self.drag then local cursorX, cursorY = GetCursorPos() - self.caret = DrawStringCursorIndex(textHeight, "VAR", self.buf, cursorX - textX, cursorY - textY) + self.caret = DrawStringCursorIndex(textHeight, "VAR", self.buf, cursorX - textX + self.controls.scrollBarH.offset, cursorY - textY + self.controls.scrollBarV.offset) + self:ScrollCaretIntoView() end - textX, textY = 0, 0 + textX = -self.controls.scrollBarH.offset + textY = -self.controls.scrollBarV.offset if self.lineHeight then local left = m_min(self.caret, self.sel or self.caret) local right = m_max(self.caret, self.sel or self.caret) + local caretX + SetDrawColor(self.textCol) for s, line, e in (self.buf.."\n"):gmatch("()([^\n]*)\n()") do - textX = 0 - local caretX + textX = -self.controls.scrollBarH.offset if left >= e or right <= s then - DrawString(textX, textY, "LEFT", textHeight, "VAR", self.textCol .. line) + DrawString(textX, textY, "LEFT", textHeight, "VAR", line) end if left < e then if left > s then - local pre = self.textCol .. line:sub(1, left - s) + local pre = line:sub(1, left - s) DrawString(textX, textY, "LEFT", textHeight, "VAR", pre) textX = textX + DrawStringWidth(textHeight, "VAR", pre) end if left >= s and left == self.caret then - caretX = textX + caretX, caretY = textX, textY end end - if left < e and right > s then + if left ~= right and left < e and right > s then local sel = self.selCol .. StripEscapes(line:sub(m_max(1, left - s + 1), m_min(#line, right - s))) if right >= e then sel = sel .. " " @@ -188,26 +276,27 @@ function EditClass:Draw(viewPort) SetDrawColor(self.selBGCol) DrawImage(nil, textX, textY, selWidth, textHeight) DrawString(textX, textY, "LEFT", textHeight, "VAR", sel) + SetDrawColor(self.textCol) textX = textX + selWidth end if right >= s and right < e and right == self.caret then - caretX = textX + caretX, caretY = textX, textY end if right > s then if right < e then - local post = self.textCol .. line:sub(right - s + 1) + local post = line:sub(right - s + 1) DrawString(textX, textY, "LEFT", textHeight, "VAR", post) textX = textX + DrawStringWidth(textHeight, "VAR", post) end end - if caretX then - if (GetTime() - self.blinkStart) % 1000 < 500 then - SetDrawColor(self.textCol) - DrawImage(nil, caretX, textY, 1, textHeight) - end - end textY = textY + textHeight end + if caretX then + if (GetTime() - self.blinkStart) % 1000 < 500 then + SetDrawColor(self.textCol) + DrawImage(nil, caretX, caretY, 1, textHeight) + end + end elseif self.sel and self.sel ~= self.caret then local left = m_min(self.caret, self.sel) local right = m_max(self.caret, self.sel) @@ -243,7 +332,7 @@ end function EditClass:OnFocusGained() self.blinkStart = GetTime() - if not self.drag then + if not self.drag and not self.selControl then self:SelectAll() end end @@ -254,7 +343,10 @@ function EditClass:OnKeyDown(key, doubleClick) end local mOverControl = self:GetMouseOverControl() if mOverControl and mOverControl.OnKeyDown then - return mOverControl:OnKeyDown(key) + self.selControl = mOverControl + return mOverControl:OnKeyDown(key) and self + else + self.selControl = nil end local shift = IsKeyDown("SHIFT") local ctrl = IsKeyDown("CTRL") @@ -265,6 +357,7 @@ function EditClass:OnKeyDown(key, doubleClick) if doubleClick then self.sel = 1 self.caret = #self.buf + 1 + self:ScrollCaretIntoView() else self.drag = true local x, y = self:GetPos() @@ -276,8 +369,9 @@ function EditClass:OnKeyDown(key, doubleClick) textX = textX + DrawStringWidth(textHeight, "VAR", self.prompt) + textHeight/2 end local cursorX, cursorY = GetCursorPos() - self.caret = DrawStringCursorIndex(textHeight, "VAR", self.buf, cursorX - textX, cursorY - textY) + self.caret = DrawStringCursorIndex(textHeight, "VAR", self.buf, cursorX - textX + self.controls.scrollBarH.offset, cursorY - textY + self.controls.scrollBarV.offset) self.sel = self.caret + self:ScrollCaretIntoView() self.blinkStart = GetTime() end elseif key == "ESCAPE" then @@ -312,70 +406,48 @@ function EditClass:OnKeyDown(key, doubleClick) self.sel = shift and (self.sel or self.caret) or nil if self.caret > 1 then self.caret = self.caret - 1 + self:ScrollCaretIntoView() self.blinkStart = GetTime() end elseif key == "RIGHT" then self.sel = shift and (self.sel or self.caret) or nil if self.caret <= #self.buf then self.caret = self.caret + 1 + self:ScrollCaretIntoView() self.blinkStart = GetTime() end elseif key == "UP" and self.lineHeight then self.sel = shift and (self.sel or self.caret) or nil - local lineNum = 0 - for s, line, e in (self.buf.."\n"):gmatch("()([^\n]*)\n()") do - if self.caret >= s and self.caret < e then - if s > 1 then - local pre = (line.." "):sub(1, self.caret - s) - self.caret = DrawStringCursorIndex(self.lineHeight, "VAR", self.buf, DrawStringWidth(self.lineHeight, "VAR", pre) + 1, lineNum * self.lineHeight) - self.blinkStart = GetTime() - end - break - end - lineNum = lineNum + 1 - end + self:MoveCaretVertically(-self.lineHeight) elseif key == "DOWN" and self.lineHeight then self.sel = shift and (self.sel or self.caret) or nil - local lineNum = 0 - for s, line, e in (self.buf.."\n"):gmatch("()([^\n]*)\n()") do - if self.caret >= s and self.caret < e then - if e - 1 <= #self.buf then - local pre = (line.." "):sub(1, self.caret - s) - self.caret = DrawStringCursorIndex(self.lineHeight, "VAR", self.buf, DrawStringWidth(self.lineHeight, "VAR", pre) + 1, (lineNum + 2) * self.lineHeight) - self.blinkStart = GetTime() - end - break - end - lineNum = lineNum + 1 - end + self:MoveCaretVertically(self.lineHeight) elseif key == "HOME" then self.sel = shift and (self.sel or self.caret) or nil if self.lineHeight and not ctrl then - for s, line, e in (self.buf.."\n"):gmatch("()([^\n]*)\n()") do - if self.caret >= s and self.caret < e then - self.caret = s - self.blinkStart = GetTime() - break - end - end + self.caret = self.caret - #lastLine(self.buf:sub(1, self.caret - 1)) else self.caret = 1 - self.blinkStart = GetTime() end + self:ScrollCaretIntoView() + self.blinkStart = GetTime() elseif key == "END" then self.sel = shift and (self.sel or self.caret) or nil if self.lineHeight and not ctrl then - for s, line, e in (self.buf.."\n"):gmatch("()([^\n]*)\n()") do - if self.caret >= s and self.caret < e then - self.caret = e - 1 - self.blinkStart = GetTime() - break - end - end + self.caret = self.caret + #self.buf:sub(self.caret, -1):match("[^\n]*") else self.caret = #self.buf + 1 - self.blinkStart = GetTime() end + self:ScrollCaretIntoView() + self.blinkStart = GetTime() + elseif key == "PAGEUP" and self.lineHeight then + self.sel = shift and (self.sel or self.caret) or nil + local width, height = self:GetSize() + self:MoveCaretVertically(-height + 18) + elseif key == "PAGEDOWN" and self.lineHeight then + self.sel = shift and (self.sel or self.caret) or nil + local width, height = self:GetSize() + self:MoveCaretVertically(height - 18) elseif key == "BACK" then if self.sel and self.sel ~= self.caret then self:ReplaceSel("") @@ -383,6 +455,7 @@ function EditClass:OnKeyDown(key, doubleClick) self.buf = self.buf:sub(1, self.caret - 2) .. self.buf:sub(self.caret) self.caret = self.caret - 1 self.sel = nil + self:ScrollCaretIntoView() self.blinkStart = GetTime() if self.changeFunc then self.changeFunc(self.buf) @@ -409,11 +482,19 @@ function EditClass:OnKeyUp(key) if not self:IsShown() or not self:IsEnabled() then return end + if self.selControl then + local newSel = self.selControl:OnKeyUp(key) + if newSel then + return self + else + self.selControl = nil + end + end if key == "LEFTBUTTON" then if self.drag then self.drag = false end - elseif self.filter == "[%d]" then + elseif self.filter == "%D" then local cur = tonumber(self.buf) if key == "WHEELUP" or key == "UP" then if cur then @@ -428,6 +509,10 @@ function EditClass:OnKeyUp(key) self:SetText("0", true) end end + elseif key == "WHEELUP" then + self.controls.scrollBarV:Scroll(-1) + elseif key == "WHEELDOWN" then + self.controls.scrollBarV:Scroll(1) end return self.hasFocus and self end @@ -445,3 +530,21 @@ function EditClass:OnChar(key) end return self end + +function EditClass:CreateUndoState() + return { + buf = self.buf, + caret = self.caret, + sel = self.sel, + } +end + +function EditClass:RestoreUndoState(state) + self.buf = state.buf + self.caret = state.caret + self.sel = state.sel + self:ScrollCaretIntoView() + if self.changeFunc then + self.changeFunc(self.buf) + end +end diff --git a/Classes/GemSelectControl.lua b/Classes/GemSelectControl.lua index 5a488e33..5eec3402 100644 --- a/Classes/GemSelectControl.lua +++ b/Classes/GemSelectControl.lua @@ -29,7 +29,7 @@ local GemSelectClass = common.NewClass("GemSelectControl", "EditControl", functi self.index = index self.gemChangeFunc = changeFunc self.list = { } - self.filter = "[ %a']" + self.filter = "^ %a'" self.changeFunc = function() self.dropped = true self.selIndex = 0 diff --git a/Classes/ImportTab.lua b/Classes/ImportTab.lua index 60d0ba2f..2f948fc2 100644 --- a/Classes/ImportTab.lua +++ b/Classes/ImportTab.lua @@ -26,7 +26,7 @@ local ImportTabClass = common.NewClass("ImportTab", "ControlHost", "Control", fu self.controls.accountNameHeader.shown = function() return self.charImportMode == "GETACCOUNTNAME" end - self.controls.accountName = common.New("EditControl", {"TOPLEFT",self.controls.accountNameHeader,"BOTTOMLEFT"}, 0, 4, 200, 20, main.lastAccountName or "", nil, "[%C]", 50) + self.controls.accountName = common.New("EditControl", {"TOPLEFT",self.controls.accountNameHeader,"BOTTOMLEFT"}, 0, 4, 200, 20, main.lastAccountName or "", nil, "%c", 50) self.controls.accountNameGo = common.New("ButtonControl", {"LEFT",self.controls.accountName,"RIGHT"}, 8, 0, 60, 20, "Start", function() self.controls.sessionInput.buf = "" self:DownloadCharacterList() @@ -59,7 +59,7 @@ You can get this from your web browser's cookies while logged into the Path of E self.charImportMode = "GETACCOUNTNAME" self.charImportStatus = "Idle" end) - self.controls.sessionInput = common.New("EditControl", {"TOPLEFT",self.controls.sessionRetry,"BOTTOMLEFT"}, 0, 8, 350, 20, "", "POESESSID", "[%x]", 32) + self.controls.sessionInput = common.New("EditControl", {"TOPLEFT",self.controls.sessionRetry,"BOTTOMLEFT"}, 0, 8, 350, 20, "", "POESESSID", "%X", 32) self.controls.sessionGo = common.New("ButtonControl", {"LEFT",self.controls.sessionInput,"RIGHT"}, 8, 0, 60, 20, "Go", function() self:DownloadCharacterList() end) @@ -107,7 +107,7 @@ You can get this from your web browser's cookies while logged into the Path of E self.controls.generateCode = common.New("ButtonControl", {"LEFT",self.controls.generateCodeLabel,"RIGHT"}, 4, 0, 80, 20, "Generate", function() self.controls.generateCodeOut:SetText(common.base64.encode(Deflate(self.build:SaveDB("code"))):gsub("+","-"):gsub("/","_")) end) - self.controls.generateCodeOut = common.New("EditControl", {"TOPLEFT",self.controls.generateCodeLabel,"BOTTOMLEFT"}, 0, 8, 250, 20, "", "Code", "[%z]") + self.controls.generateCodeOut = common.New("EditControl", {"TOPLEFT",self.controls.generateCodeLabel,"BOTTOMLEFT"}, 0, 8, 250, 20, "", "Code", "%Z") self.controls.generateCodeOut.enabled = function() return #self.controls.generateCodeOut.buf > 0 end @@ -120,7 +120,7 @@ You can get this from your web browser's cookies while logged into the Path of E end self.controls.generateCodeNote = common.New("LabelControl", {"TOPLEFT",self.controls.generateCodeOut,"BOTTOMLEFT"}, 0, 4, 0, 14, "^7Note: this code can be very long; it may be easiest to share it using Pastebin or similar.") self.controls.importCodeHeader = common.New("LabelControl", {"TOPLEFT",self.controls.generateCodeNote,"BOTTOMLEFT"}, 0, 26, 0, 16, "^7To import a build, enter the code here:") - self.controls.importCodeIn = common.New("EditControl", {"TOPLEFT",self.controls.importCodeHeader,"BOTTOMLEFT"}, 0, 4, 250, 20, "", nil, "[%w_%-=]", nil, function(buf) + self.controls.importCodeIn = common.New("EditControl", {"TOPLEFT",self.controls.importCodeHeader,"BOTTOMLEFT"}, 0, 4, 250, 20, "", nil, "^%w_%-=", nil, function(buf) if #buf == 0 then self.importCodeState = nil return @@ -141,7 +141,7 @@ You can get this from your web browser's cookies while logged into the Path of E self.controls.importCodeMode.enabled = function() return self.importCodeState == "VALID" end - self.controls.importCodeBuildName = common.New("EditControl", {"LEFT",self.controls.importCodeMode,"RIGHT"}, 4, 0, 400, 20, "", "New build name", "[%w _+-.()]", 50) + self.controls.importCodeBuildName = common.New("EditControl", {"LEFT",self.controls.importCodeMode,"RIGHT"}, 4, 0, 400, 20, "", "New build name", "\\/:%*%?\"<>|", 50) self.controls.importCodeBuildName.enabled = function() return self.importCodeState == "VALID" and self.controls.importCodeMode.sel == 2 end diff --git a/Classes/ItemDBControl.lua b/Classes/ItemDBControl.lua index 596fab58..b02349d2 100644 --- a/Classes/ItemDBControl.lua +++ b/Classes/ItemDBControl.lua @@ -60,7 +60,7 @@ local ItemDBClass = common.NewClass("ItemDB", "Control", "ControlHost", function self.controls.league.shown = function() return #self.leagueList > 2 end - self.controls.search = common.New("EditControl", {"BOTTOMLEFT",self,"TOPLEFT"}, 0, -2, 258, 18, "", "Search", "[%C]", 100, function() + self.controls.search = common.New("EditControl", {"BOTTOMLEFT",self,"TOPLEFT"}, 0, -2, 258, 18, "", "Search", "%c", 100, function() self:BuildOrderList() end) self.controls.searchMode = common.New("DropDownControl", {"LEFT",self.controls.search,"RIGHT"}, 2, 0, 100, 18, { "Anywhere", "Names", "Modifiers" }, function() diff --git a/Classes/NotesTab.lua b/Classes/NotesTab.lua new file mode 100644 index 00000000..6edfb2fb --- /dev/null +++ b/Classes/NotesTab.lua @@ -0,0 +1,63 @@ +-- Path of Building +-- +-- Module: Notes Tab +-- Notes tab for the current build. +-- +local launch, main = ... + +local t_insert = table.insert + +local NotesTabClass = common.NewClass("NotesTab", "ControlHost", "Control", function(self, build) + self.ControlHost() + self.Control() + + self.build = build + + self.controls.edit = common.New("EditControl", {"TOPLEFT",self,"TOPLEFT"}, 8, 8, 0, 0, "", nil, "^%C\t\n", nil, nil, 16) + self.controls.edit.width = function() + return self.width - 16 + end + self.controls.edit.height = function() + return self.height - 16 + end + self.selControl = self.controls.edit + self.controls.edit.hasFocus = true +end) + +function NotesTabClass:Load(xml, fileName) + for _, node in ipairs(xml) do + if type(node) == "string" then + self.controls.edit:SetText(node) + end + end + self.lastContent = self.controls.edit.buf +end + +function NotesTabClass:Save(xml) + t_insert(xml, self.controls.edit.buf) + self.lastContent = self.controls.edit.buf +end + +function NotesTabClass:Draw(viewPort, inputEvents) + self.x = viewPort.x + self.y = viewPort.y + self.width = viewPort.width + self.height = viewPort.height + + for id, event in ipairs(inputEvents) do + if event.type == "KeyDown" then + if event.key == "z" and IsKeyDown("CTRL") then + self.controls.edit:Undo() + elseif event.key == "y" and IsKeyDown("CTRL") then + self.controls.edit:Redo() + end + end + end + self:ProcessControlsInput(inputEvents, viewPort) + + main:DrawBackground(viewPort) + + self:DrawControls(viewPort) + + self.modFlag = (self.lastContent ~= self.controls.edit.buf) +end diff --git a/Classes/SkillsTab.lua b/Classes/SkillsTab.lua index e4b4fd9c..17c7cc7b 100644 --- a/Classes/SkillsTab.lua +++ b/Classes/SkillsTab.lua @@ -29,7 +29,7 @@ local SkillsTabClass = common.NewClass("SkillsTab", "UndoHandler", "ControlHost" self.anchorGroupDetail.shown = function() return self.displayGroup ~= nil end - self.controls.groupLabel = common.New("EditControl", {"TOPLEFT",self.anchorGroupDetail,"TOPLEFT"}, 0, 0, 380, 20, nil, "Label", "[%C]", 50, function(buf) + self.controls.groupLabel = common.New("EditControl", {"TOPLEFT",self.anchorGroupDetail,"TOPLEFT"}, 0, 0, 380, 20, nil, "Label", "%c", 50, function(buf) self.displayGroup.label = buf self:ProcessSocketGroup(self.displayGroup) self:AddUndoState() @@ -234,7 +234,7 @@ function SkillsTabClass:CreateGemSlot(index) self.controls["gemSlotName"..index] = slot.nameSpec -- Gem level - slot.level = common.New("EditControl", {"LEFT",slot.nameSpec,"RIGHT"}, 2, 0, 60, 20, nil, nil, "[%d]", 2, function(buf) + slot.level = common.New("EditControl", {"LEFT",slot.nameSpec,"RIGHT"}, 2, 0, 60, 20, nil, nil, "%D", 2, function(buf) if not self.displayGroup.gemList[index] then self.displayGroup.gemList[index] = { nameSpec = "", level = 20, quality = 0, enabled = true } slot.quality:SetText("0") @@ -249,7 +249,7 @@ function SkillsTabClass:CreateGemSlot(index) self.controls["gemSlotLevel"..index] = slot.level -- Gem quality - slot.quality = common.New("EditControl", {"LEFT",slot.level,"RIGHT"}, 2, 0, 60, 20, nil, nil, "[%d]", 2, function(buf) + slot.quality = common.New("EditControl", {"LEFT",slot.level,"RIGHT"}, 2, 0, 60, 20, nil, nil, "%D", 2, function(buf) if not self.displayGroup.gemList[index] then self.displayGroup.gemList[index] = { nameSpec = "", level = 20, quality = 0, enabled = true } slot.level:SetText("20") diff --git a/Classes/TreeTab.lua b/Classes/TreeTab.lua index 1fd3ead9..6f767621 100644 --- a/Classes/TreeTab.lua +++ b/Classes/TreeTab.lua @@ -70,7 +70,7 @@ local TreeTabClass = common.NewClass("TreeTab", "ControlHost", function(self, bu local popup popup = main:OpenPopup(380, 100, "Export Tree", { common.New("LabelControl", nil, 0, 20, 0, 16, "Passive tree link:"), - edit = common.New("EditControl", nil, 0, 40, 350, 18, treeLink, nil, "[%z]"), + edit = common.New("EditControl", nil, 0, 40, 350, 18, treeLink, nil, "%Z"), shrink = common.New("ButtonControl", nil, -90, 70, 140, 20, "Shrink with PoEURL", function() popup.controls.shrink.enabled = false popup.controls.shrink.label = "Shrinking..." @@ -93,7 +93,7 @@ local TreeTabClass = common.NewClass("TreeTab", "ControlHost", function(self, bu end), }, "done", "edit") end) - self.controls.treeSearch = common.New("EditControl", {"LEFT",self.controls.export,"RIGHT"}, 8, 0, 400, 20, "", "Search", "[^%c%(%)]", 100, function(buf) + self.controls.treeSearch = common.New("EditControl", {"LEFT",self.controls.export,"RIGHT"}, 8, 0, 400, 20, "", "Search", "%c%(%)", 100, function(buf) self.viewer.searchStr = buf end) self.controls.treeHeatMap = common.New("CheckBoxControl", {"LEFT",self.controls.treeSearch,"RIGHT"}, 130, 0, 20, "Show node power:", function(state) diff --git a/Modules/Build.lua b/Modules/Build.lua index a3182f9c..7165c8a4 100644 --- a/Modules/Build.lua +++ b/Modules/Build.lua @@ -20,6 +20,7 @@ function buildMode:Init(dbFileName, buildName) self.tree = main.tree self.importTab = common.New("ImportTab", self) + self.notesTab = common.New("NotesTab", self) self.configTab = common.New("ConfigTab", self) self.spec = common.New("PassiveSpec", self) self.treeTab = common.New("TreeTab", self) @@ -73,7 +74,7 @@ function buildMode:Init(dbFileName, buildName) local popup popup = main:OpenPopup(370, 100, "Save As", { common.New("LabelControl", nil, 0, 20, 0, 16, "^7Enter new build name:"), - edit = common.New("EditControl", nil, 0, 40, 350, 20, self.buildName, nil, "[%w _+-.()'\"]", 50, function(buf) + edit = common.New("EditControl", nil, 0, 40, 350, 20, self.buildName, nil, "\\/:%*%?\"<>|", 50, function(buf) newFileName = main.buildPath..buf..".xml" newBuildName = buf popup.controls.save.enabled = false @@ -125,7 +126,7 @@ function buildMode:Init(dbFileName, buildName) SetDrawLayer(nil, 0) end end - self.controls.characterLevel = common.New("EditControl", {"LEFT",self.anchorTopBarRight,"RIGHT"}, 0, 0, 106, 20, "", "Level", "[%d]", 3, function(buf) + self.controls.characterLevel = common.New("EditControl", {"LEFT",self.anchorTopBarRight,"RIGHT"}, 0, 0, 106, 20, "", "Level", "%D", 3, function(buf) self.characterLevel = m_min(tonumber(buf) or 1, 100) self.buildFlag = true end) @@ -185,6 +186,10 @@ function buildMode:Init(dbFileName, buildName) self.viewMode = "IMPORT" end) self.controls.modeImport.locked = function() return self.viewMode == "IMPORT" end + self.controls.modeNotes = common.New("ButtonControl", {"LEFT",self.controls.modeImport,"RIGHT"}, 4, 0, 58, 20, "Notes", function() + self.viewMode = "NOTES" + end) + self.controls.modeNotes.locked = function() return self.viewMode == "NOTES" end self.controls.modeConfig = common.New("ButtonControl", {"TOPRIGHT",self.anchorSideBar,"TOPLEFT"}, 300, 0, 100, 20, "Configuration", function() self.viewMode = "CONFIG" end) @@ -328,6 +333,7 @@ function buildMode:Init(dbFileName, buildName) self.savers = { ["Build"] = self, ["Config"] = self.configTab, + ["Notes"] = self.notesTab, ["Spec"] = self.spec, ["TreeView"] = self.treeTab.viewer, ["Items"] = self.itemsTab, @@ -496,6 +502,8 @@ function buildMode:OnFrame(inputEvents) } if self.viewMode == "IMPORT" then self.importTab:Draw(tabViewPort, inputEvents) + elseif self.viewMode == "NOTES" then + self.notesTab:Draw(tabViewPort, inputEvents) elseif self.viewMode == "CONFIG" then self.configTab:Draw(tabViewPort, inputEvents) elseif self.viewMode == "TREE" then @@ -508,7 +516,7 @@ function buildMode:OnFrame(inputEvents) self.calcsTab:Draw(tabViewPort, inputEvents) end - self.unsaved = self.modFlag or self.configTab.modFlag or self.spec.modFlag or self.skillsTab.modFlag or self.itemsTab.modFlag or self.calcsTab.modFlag + self.unsaved = self.modFlag or self.notesTab.modFlag or self.configTab.modFlag or self.spec.modFlag or self.skillsTab.modFlag or self.itemsTab.modFlag or self.calcsTab.modFlag SetDrawLayer(5) diff --git a/Modules/Main.lua b/Modules/Main.lua index ae69e066..00c08ee3 100644 --- a/Modules/Main.lua +++ b/Modules/Main.lua @@ -22,6 +22,7 @@ LoadModule("Classes/ControlHost") local main = common.New("ControlHost") local classList = { + "UndoHandler", -- Basic controls "Control", "LabelControl", @@ -35,13 +36,13 @@ local classList = { "TextListControl", -- Misc "PopupDialog", - "UndoHandler", -- Mode: Build list "BuildListControl", -- Mode: Build "ModList", "ModDB", "ImportTab", + "NotesTab", "ConfigTab", "TreeTab", "PassiveTree", diff --git a/PathOfBuilding.sln b/PathOfBuilding.sln index a76a34cf..0caee3d0 100644 --- a/PathOfBuilding.sln +++ b/PathOfBuilding.sln @@ -81,6 +81,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Classes", "Classes", "{7EE4 Classes\LabelControl.lua = Classes\LabelControl.lua Classes\ModDB.lua = Classes\ModDB.lua Classes\ModList.lua = Classes\ModList.lua + Classes\NotesTab.lua = Classes\NotesTab.lua Classes\PassiveSpec.lua = Classes\PassiveSpec.lua Classes\PassiveTree.lua = Classes\PassiveTree.lua Classes\PassiveTreeView.lua = Classes\PassiveTreeView.lua diff --git a/README.md b/README.md index 1a3c2cd2..32f0139d 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,9 @@ Head over to the [Releases](https://github.com/Openarl/PathOfBuilding/releases) ![ss3](https://cloud.githubusercontent.com/assets/19189971/18089780/f0ff234a-6f04-11e6-8c88-6193fe59a5c4.png) ## Changelog +### 1.2.14 - 2016/11/23 + * Added a Notes tab + ### 1.2.13 - 2016/11/22 * The breakdown for crit chance now includes the "additional chance to receive a Critical Strike" from Assassin's Mark * Added support for the "increased extra damage from Critical Strikes" modifier on Assassin's Mark diff --git a/changelog.txt b/changelog.txt index 40ccbbf1..ddd8d104 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,5 @@ +VERSION[1.2.14][2016/11/23] + * Added a Notes tab VERSION[1.2.13][2016/11/22] * The breakdown for crit chance now includes the "additional chance to receive a Critical Strike" from Assassin's Mark * Added support for the "increased extra damage from Critical Strikes" modifier on Assassin's Mark diff --git a/manifest.xml b/manifest.xml index 3c7852e4..c11831a6 100644 --- a/manifest.xml +++ b/manifest.xml @@ -1,33 +1,34 @@ - + - - + + - + - - - - + + + + + @@ -35,20 +36,20 @@ - + - + - + - +