diff --git a/Classes/ItemsTab.lua b/Classes/ItemsTab.lua index e5f853cc82..2875f4e99f 100644 --- a/Classes/ItemsTab.lua +++ b/Classes/ItemsTab.lua @@ -825,13 +825,15 @@ function ItemsTabClass:Draw(viewPort, inputEvents) self.controls.scrollBarV.y = viewPort.y do local maxY = select(2, self.lastSlot:GetPos()) + 24 + local maxX = self.anchorDisplayItem:GetPos() + 462 if self.displayItem then local x, y = self.controls.displayItemTooltipAnchor:GetPos() - local ttW, ttH = self.displayItemTooltip:GetSize() + local ttW, ttH = self.displayItemTooltip:GetDynamicSize(viewPort) maxY = m_max(maxY, y + ttH + 4) + maxX = m_max(maxX, x + ttW + 80) end local contentHeight = maxY - self.y - local contentWidth = self.anchorDisplayItem:GetPos() + 462 - self.x + local contentWidth = maxX - self.x local v = contentHeight > viewPort.height local h = contentWidth > viewPort.width - (v and 20 or 0) if h then diff --git a/Classes/Tooltip.lua b/Classes/Tooltip.lua index be92d46ce2..34ac7ffec7 100644 --- a/Classes/Tooltip.lua +++ b/Classes/Tooltip.lua @@ -9,6 +9,12 @@ local m_max = math.max local m_floor = math.floor local s_gmatch = string.gmatch +-- Constants + +local BORDER_WIDTH = 3 +local H_PAD = 12 +local V_PAD = 10 + -- All possible values for notable recipes (oils) local recipeNames = { "AmberOil", @@ -35,17 +41,20 @@ end local TooltipClass = newClass("Tooltip", function(self) self.lines = { } + self.blocks = { } self:Clear() end) function TooltipClass:Clear() wipeTable(self.lines) + wipeTable(self.blocks) if self.updateParams then wipeTable(self.updateParams) end self.recipe = nil self.center = false self.color = { 0.5, 0.3, 0 } + t_insert(self.blocks, { height = 0 }) end function TooltipClass:CheckForUpdate(...) @@ -71,12 +80,17 @@ end function TooltipClass:AddLine(size, text) if text then for line in s_gmatch(text .. "\n", "([^\n]*)\n") do + if line:match("^.*(Equipping)") == "Equipping" or line:match("^.*(Removing)") == "Removing" then + t_insert(self.blocks, { height = size + 2}) + else + self.blocks[#self.blocks].height = self.blocks[#self.blocks].height + size + 2 + end if self.maxWidth then - for _, line in ipairs(main:WrapString(line, size, self.maxWidth - 12)) do - t_insert(self.lines, { size = size, text = line }) + for _, line in ipairs(main:WrapString(line, size, self.maxWidth - H_PAD)) do + t_insert(self.lines, { size = size, text = line, block = #self.blocks }) end else - t_insert(self.lines, { size = size, text = line }) + t_insert(self.lines, { size = size, text = line, block = #self.blocks }) end end end @@ -117,7 +131,66 @@ function TooltipClass:GetSize() ttW = m_max(ttW, imageX) end - return ttW + 12, ttH + 10 + return ttW + H_PAD, ttH + V_PAD +end + +function TooltipClass:GetDynamicSize(viewPort) + local staticttW, staticttH = self:GetSize() + local columns, ttH = self:CalculateColumns(0, 0, staticttH, staticttW, viewPort) + local ttW = columns * staticttW + + return ttW + H_PAD, ttH + V_PAD +end + +function TooltipClass:CalculateColumns(ttY, ttX, ttH, ttW, viewPort) + local y = ttY + 2 * BORDER_WIDTH + local x = ttX + local columns = 1 -- reset to count columns by block heights + local currentBlock = 1 + local maxColumnHeight = 0 + local drawStack = {} + + for i, data in ipairs(self.lines) do + if self.recipe and i == 1 then + local title = self.lines[1] + local imageX = DrawStringWidth(title.size, "VAR", title.text) + title.size + local recipeTextSize = (title.size * 3) / 4 + for _, recipeName in ipairs(self.recipe) do + -- Trim "Oil" from the recipe name, which normally looks like "GoldenOil" + local recipeNameShort = recipeName + if #recipeNameShort > 3 and recipeNameShort:sub(-3) == "Oil" then + recipeNameShort = recipeNameShort:sub(1, #recipeNameShort - 3) + end + -- Draw the name of the recipe component (oil) + t_insert(drawStack, {ttX + imageX, y + (title.size - recipeTextSize)/2, "LEFT", recipeTextSize, "VAR", recipeNameShort}) + imageX = imageX + DrawStringWidth(recipeTextSize, "VAR", recipeNameShort) + -- Draw the image of the recipe component (oil) + t_insert(drawStack, {recipeImages[recipeName], ttX + imageX, y, title.size, title.size}) + imageX = imageX + title.size * 1.25 + end + end + if data.text then + -- if data + borders is going to go outside of the viewPort + if currentBlock ~= data.block and self.blocks[data.block].height + y > ttY + math.min(ttH, viewPort.height) then + y = ttY + 2 * BORDER_WIDTH + x = ttX + ttW * columns + columns = columns + 1 + end + currentBlock = data.block + if self.center then + t_insert(drawStack, {x + ttW/2, y, "CENTER_X", data.size, "VAR", data.text}) + else + t_insert(drawStack, {x + 6, y, "LEFT", data.size, "VAR", data.text}) + end + y = y + data.size + 2 + elseif self.lines[i + 1] and self.lines[i - 1] and self.lines[i + 1].text then + t_insert(drawStack, {nil, x, y - 1 + data.size / 2, ttW - BORDER_WIDTH, 2}) + y = y + data.size + 2 + end + maxColumnHeight = m_max(y - ttY + 2 * BORDER_WIDTH, maxColumnHeight) + end + + return columns, maxColumnHeight, drawStack end function TooltipClass:Draw(x, y, w, h, viewPort) @@ -141,57 +214,41 @@ function TooltipClass:Draw(x, y, w, h, viewPort) elseif self.center then ttX = m_floor(x - ttW/2) end - if type(self.color) == "string" then - SetDrawColor(self.color) - else - SetDrawColor(unpack(self.color)) - end - DrawImage(nil, ttX, ttY, ttW, 3) - DrawImage(nil, ttX, ttY, 3, ttH) - DrawImage(nil, ttX, ttY + ttH - 3, ttW, 3) - DrawImage(nil, ttX + ttW - 3, ttY, 3, ttH) - SetDrawColor(0, 0, 0, 0.75) - DrawImage(nil, ttX + 3, ttY + 3, ttW - 6, ttH - 6) + SetDrawColor(1, 1, 1) - local y = ttY + 6 - -- Draw the oil recipe for notables - if self.recipe and self.lines[1] then - local title = self.lines[1] - local imageX = DrawStringWidth(title.size, "VAR", title.text) + title.size - local recipeTextSize = (title.size * 3) / 4 - for _, recipeName in ipairs(self.recipe) do - -- Trim "Oil" from the recipe name, which normally looks like "GoldenOil" - local recipeNameShort = recipeName - if #recipeNameShort > 3 and recipeNameShort:sub(-3) == "Oil" then - recipeNameShort = recipeNameShort:sub(1, #recipeNameShort - 3) - end - -- Draw the name of the recipe component (oil) - DrawString(ttX + imageX, y + (title.size - recipeTextSize)/2, "LEFT", recipeTextSize, "VAR", recipeNameShort) - imageX = imageX + DrawStringWidth(recipeTextSize, "VAR", recipeNameShort) - -- Draw the image of the recipe component (oil) - DrawImage(recipeImages[recipeName], ttX + imageX, y, title.size, title.size) - imageX = imageX + title.size * 1.25 - end - end + local columns, maxColumnHeight, drawStack = self:CalculateColumns(ttY, ttX, ttH, ttW, viewPort) - for i, data in ipairs(self.lines) do - if data.text then - if self.center then - DrawString(ttX + ttW/2, y, "CENTER_X", data.size, "VAR", data.text) - else - DrawString(ttX + 6, y, "LEFT", data.size, "VAR", data.text) - end - y = y + data.size + 2 - elseif self.lines[i + 1] and self.lines[i - 1] and self.lines[i + 1].text then - if type(self.color) == "string" then - SetDrawColor(self.color) + -- background shading currently must be drawn before text lines. API change will allow something like the commented lines below + SetDrawColor(0, 0, 0, .85) + --SetDrawLayer(nil, GetDrawLayer() - 5) + DrawImage(nil, ttX, ttY + BORDER_WIDTH, ttW * columns - BORDER_WIDTH, maxColumnHeight - 2 * BORDER_WIDTH) + --SetDrawLayer(nil, GetDrawLayer()) + SetDrawColor(1, 1, 1) + for i, lines in ipairs(drawStack) do + if #lines < 6 then + if(type(self.color) == "string") then + SetDrawColor(self.color) + elseif lines[1] then -- Don't color images + SetDrawColor(1,1,1) else SetDrawColor(unpack(self.color)) end - DrawImage(nil, ttX + 3, y - 1 + data.size / 2, ttW - 6, 2) - y = y + data.size + 2 + DrawImage(unpack(lines)) + else + DrawString(unpack(lines)) end end + if type(self.color) == "string" then + SetDrawColor(self.color) + else + SetDrawColor(unpack(self.color)) + end + for i=0,columns do + DrawImage(nil, ttX + ttW * i - BORDER_WIDTH * math.ceil(i^2 / (i^2 + 1)), ttY, BORDER_WIDTH, maxColumnHeight) -- borders + end + DrawImage(nil, ttX, ttY, ttW * columns, BORDER_WIDTH) -- top border + DrawImage(nil, ttX, ttY + maxColumnHeight - BORDER_WIDTH, ttW * columns, BORDER_WIDTH) -- bottom border + return ttW, ttH end \ No newline at end of file