require "ISUI/ISPanel" ISToolTip = ISPanel:derive("ISToolTip"); --************************************************************************-- --** ISPanel:initialise --** --************************************************************************-- function ISToolTip:initialise() ISPanel.initialise(self); end function ISToolTip:instantiate() ISPanel.instantiate(self) self.javaObject:setConsumeMouseEvents(false) end function ISToolTip:setName(name) self.name = name; end function ISToolTip:setContextMenu(contextMenu) self.contextMenu = contextMenu; end function ISToolTip:setTexture(textureName) self.texture = getTexture(textureName); end function ISToolTip:onMouseDown(x, y) return false end function ISToolTip:onMouseUp(x, y) return false end function ISToolTip:onRightMouseDown(x, y) return false end function ISToolTip:onRightMouseUp(x, y) return false end function ISToolTip:prerender() if self.owner and not self.owner:isReallyVisible() then self:removeFromUIManager() self:setVisible(false) return end self:doLayout() self:drawRect(0, 0, self.width, self.height, self.backgroundColor.a, self.backgroundColor.r, self.backgroundColor.g, self.backgroundColor.b); end --************************************************************************-- --** ISPanel:render --** --************************************************************************-- function ISToolTip:render() local mx = getMouseX() + 32 local my = getMouseY() + 10 if not self.followMouse then mx = self:getX() my = self:getY() end if self.desiredX and self.desiredY then mx = self.desiredX my = self.desiredY end self:setX(mx) self:setY(my) if self.contextMenu and self.contextMenu.joyfocus then local playerNum = self.contextMenu.player self:setX(getPlayerScreenLeft(playerNum) + 60); self:setY(getPlayerScreenTop(playerNum) + 60); elseif self.contextMenu and self.contextMenu.currentOptionRect then if self.contextMenu.currentOptionRect.height > 32 then self:setY(my + self.contextMenu.currentOptionRect.height) end self:adjustPositionToAvoidOverlap(self.contextMenu.currentOptionRect) elseif self.owner and self.owner.isButton then local ownerRect = { x = self.owner:getAbsoluteX(), y = self.owner:getAbsoluteY(), width = self.owner.width, height = self.owner.height } self:adjustPositionToAvoidOverlap(ownerRect) end -- big rectangle (our background) self:drawRect(0, 0, self.width, self.height, 0.7, 0.05, 0.05, 0.05) self:drawRectBorder(0, 0, self.width, self.height, 0.5, 0.9, 0.9, 1) -- render texture if self.texture then local widthTexture = self.texture:getWidth() local heightTexture = self.texture:getHeight() local textureY = self.name and 35 or 5 self:drawTextureScaled(self.texture, 8, textureY, widthTexture, heightTexture, 1, 1, 1, 1) end -- render name if self.name then self:drawText(self.name, 8, 5, 1, 1, 1, 1, UIFont.Medium) end self:renderContents() -- render a how to rotate message at the bottom if needed if self.footNote then local fontHgt = getTextManager():getFontFromEnum(UIFont.Small):getLineHeight() self:drawTextCentre(self.footNote, self:getWidth() / 2, self:getHeight() - fontHgt - 4, 1, 1, 1, 1, UIFont.Small) end end function ISToolTip:doLayout() local textX = 10 local textY = 0 local textWidth = 0 local textHeight = 0 local textureX = 8 local textureY = 5 local textureWidth = 0 local textureHeight = 0 if self.texture then textureWidth = self.texture:getWidth() textureHeight = self.texture:getHeight() + 5 textX = textureX + textureWidth + 10 end local nameX = 8 local nameWidth = 0 local nameHeight = 0 if self.name then nameWidth = getTextManager():MeasureStringX(UIFont.Medium, self.name) + 50 nameHeight = getTextManager():getFontFromEnum(UIFont.Medium):getLineHeight() textureY = 35 textY = 25 end textWidth, textHeight = self:layoutContents(textX, textY, math.max(220, nameWidth)) local myWidth = 220 local myHeight = math.max(nameHeight, math.max(textureY + textureHeight, textY + textHeight)) if myWidth < textX + textWidth then myWidth = textX + textWidth end if myWidth < nameWidth then myWidth = nameWidth end -- if self.texture and myHeight < textureHeight + 40 then -- myHeight = textureHeight + 40 -- end if self.footNote then local noteWidth = getTextManager():MeasureStringX(UIFont.Small, self.footNote) if myWidth < noteWidth then myWidth = noteWidth end local fontHgt = getTextManager():getFontFromEnum(UIFont.Small):getLineHeight() myHeight = myHeight + fontHgt + 4 end self:setWidth(myWidth + 20) self:setHeight(myHeight) end function ISToolTip.GetFont() if getCore():getOptionTooltipFont() == "Large" then return UIFont.Large elseif getCore():getOptionTooltipFont() == "Medium" then return UIFont.Medium end return UIFont.NewSmall end function ISToolTip:layoutContents(x, y, myWidth) local textWidth = 0 local textHeight = 0 if self.description ~= "" then self.descriptionPanel.defaultFont = ISToolTip.GetFont() self.descriptionPanel.text = self.description local widthScale = getTextManager():getFontHeight(self.descriptionPanel.defaultFont) / 15 if self.maxLineWidth then self.descriptionPanel.maxLineWidth = self.maxLineWidth * widthScale self.descriptionPanel:setWidth(self.descriptionPanel.marginLeft + self.descriptionPanel.marginRight) else self.descriptionPanel:setWidth(math.max(180 * widthScale, myWidth - x)) end self.descriptionPanel:paginate() local maxLineWidth = 0 for i,v in ipairs(self.descriptionPanel.lines) do local lineWidth = self.descriptionPanel.lineX[i] + getTextManager():MeasureStringX(self.descriptionPanel.defaultFont, v); if lineWidth > maxLineWidth then maxLineWidth = lineWidth end end local panelWidth = maxLineWidth + self.descriptionPanel.marginLeft + self.descriptionPanel.marginRight if panelWidth > self.descriptionPanel:getWidth() then self.descriptionPanel:setWidth(panelWidth) self.descriptionPanel:paginate() -- elseif panelWidth < self.descriptionPanel:getWidth() then -- self.descriptionPanel:setWidth(panelWidth) -- self.descriptionPanel:paginate() end textWidth = self.descriptionPanel:getWidth() textHeight = self.descriptionPanel:getHeight() end return textWidth, textHeight end function ISToolTip:renderContents() if self.description ~= "" then if self.texture then self.descriptionPanel:setX(self:getAbsoluteX() + 8 + self.texture:getWidth() + 10); else self.descriptionPanel:setX(self:getAbsoluteX() + 10); end local y = 0 if self.name then y = 25 end self.descriptionPanel:setY(self:getAbsoluteY() + y) self.descriptionPanel:prerender() self.descriptionPanel:render() end end function ISToolTip:setDesiredPosition(x, y) self.desiredX = x self.desiredY = y if not x or not y then return end self:setX(x) self:setY(y) if self.owner and self.owner.isButton then local ownerRect = { x = self.owner:getAbsoluteX(), y = self.owner:getAbsoluteY(), width = self.owner.width, height = self.owner.height } self:adjustPositionToAvoidOverlap(ownerRect) end end function ISToolTip:adjustPositionToAvoidOverlap(avoidRect) local myRect = { x = self.x, y = self.y, width = self.width, height = self.height } if self.contextMenu and not self.contextMenu.joyfocus and self.contextMenu.currentOptionRect then myRect.y = avoidRect.y local r = self:placeRight(myRect, avoidRect) if self:overlaps(r, avoidRect) then r = self:placeLeft(myRect, avoidRect) if self:overlaps(r, avoidRect) then r = self:placeAbove(myRect, avoidRect) end end self:setX(r.x) self:setY(r.y) return end if self:overlaps(myRect, avoidRect) then local r = self:placeRight(myRect, avoidRect) if self:overlaps(r, avoidRect) then r = self:placeAbove(myRect, avoidRect) if self:overlaps(r, avoidRect) then r = self:placeLeft(myRect, avoidRect) end end self:setX(r.x) self:setY(r.y) end end function ISToolTip:overlaps(r1, r2) return r1.x + r1.width > r2.x and r1.x < r2.x + r2.width and r1.y + r1.height > r2.y and r1.y < r2.y + r2.height end function ISToolTip:placeLeft(r1, r2) local r = r1 r.x = math.max(0, r2.x - r.width - 8) return r end function ISToolTip:placeRight(r1, r2) local r = r1 r.x = r2.x + r2.width + 8 r.x = math.min(r.x, getCore():getScreenWidth() - r.width) return r end function ISToolTip:placeAbove(r1, r2) local r = r1 r.y = r2.y - r.height - 8 r.y = math.max(0, r.y) return r end function ISToolTip:setOwner(ui) self.owner = ui end local function setRGBA(rgba, r, g, b, a) rgba.r = r rgba.g = g rgba.b = b rgba.a = a return rgba end function ISToolTip:reset() self:setVisible(false) self:noBackground() self.name = nil self.description = "" self.texture = nil self.footNote = nil setRGBA(self.borderColor, 0.4, 0.4, 0.4, 1.0) setRGBA(self.backgroundColor, 0.0, 0.0, 0.0, 0.0) self.width = 0 self.height = 0 self.maxLineWidth = nil self.desiredX = nil self.desiredY = nil self.anchorLeft = true self.anchorRight = false self.anchorTop = true self.anchorBottom = false self.descriptionPanel.marginLeft = 0 self.descriptionPanel.marginRight = 0 setRGBA(self.descriptionPanel.backgroundColor, 0, 0, 0, 0.3) setRGBA(self.descriptionPanel.borderColor, 1, 1, 1, 0.1) self.owner = nil self.contextMenu = nil self.followMouse = true end --************************************************************************-- --** ISPanel:new --** --************************************************************************-- function ISToolTip:new() local o = ISPanel.new(self, 0, 0, 0, 0); o:noBackground(); o.name = nil; o.description = ""; o.borderColor = {r=0.4, g=0.4, b=0.4, a=1}; o.backgroundColor = {r=0, g=0, b=0, a=0}; o.width = 0; o.height = 0; o.anchorLeft = true; o.anchorRight = false; o.anchorTop = true; o.anchorBottom = false; -- description panel o.descriptionPanel = ISRichTextPanel:new(0, 0, 0, 0); o.descriptionPanel.marginLeft = 0 o.descriptionPanel.marginRight = 0 o.descriptionPanel:initialise(); o.descriptionPanel:instantiate(); o.descriptionPanel:noBackground(); o.descriptionPanel.backgroundColor = {r=0, g=0, b=0, a=0.3}; o.descriptionPanel.borderColor = {r=1, g=1, b=1, a=0.1}; o.owner = nil o.followMouse = true return o; end