mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2024-11-17 18:06:03 -05:00
Tooltip refactor (#872)
* d2ui: Add tooltip class we reimplemented tooltips in several places (inventory/skill_select_panel). Let's make it its own ui element. * d2player: Refactor skill_select_panel to use the tooltip class * d2player: Refactor inventory to use the tooltip class * Make linter happy * Make golangci-lint 1.27.0 happy as well * tooltip: Remove const and rather disable linter
This commit is contained in:
parent
4a62101b96
commit
79c147866e
188
d2core/d2ui/tooltip.go
Normal file
188
d2core/d2ui/tooltip.go
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
package d2ui
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||||
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2util"
|
||||||
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2gui"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
blackAlpha70 = 0x000000C8
|
||||||
|
screenWidth = 800
|
||||||
|
screenHeight = 600
|
||||||
|
)
|
||||||
|
|
||||||
|
// Tooltip contains a label containing text with a transparent, black background
|
||||||
|
type Tooltip struct {
|
||||||
|
manager *UIManager
|
||||||
|
lines []string
|
||||||
|
label *Label
|
||||||
|
backgroundColor int
|
||||||
|
x, y int
|
||||||
|
originX tooltipXOrigin
|
||||||
|
originY tooltipYOrigin
|
||||||
|
}
|
||||||
|
|
||||||
|
type tooltipXOrigin = int
|
||||||
|
type tooltipYOrigin = int
|
||||||
|
|
||||||
|
const (
|
||||||
|
// TooltipYTop sets the Y origin of the tooltip to the top
|
||||||
|
TooltipYTop tooltipYOrigin = iota
|
||||||
|
// TooltipYCenter sets the Y origin of the tooltip to the center
|
||||||
|
TooltipYCenter
|
||||||
|
// TooltipYBottom sets the Y origin of the tooltip to the bottom
|
||||||
|
TooltipYBottom
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// TooltipXLeft sets the X origin of the tooltip to the left
|
||||||
|
TooltipXLeft tooltipXOrigin = iota
|
||||||
|
// TooltipXCenter sets the X origin of the tooltip to the center
|
||||||
|
TooltipXCenter
|
||||||
|
// TooltipXRight sets the X origin of the tooltip to the right
|
||||||
|
TooltipXRight
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewTooltip creates a tooltip instance. Note here, that we need to define the
|
||||||
|
// orign point of the tooltip rect using tooltipXOrigin and tooltinYOrigin
|
||||||
|
func (ui *UIManager) NewTooltip(font,
|
||||||
|
palette string,
|
||||||
|
originX tooltipXOrigin,
|
||||||
|
originY tooltipYOrigin) *Tooltip {
|
||||||
|
label := ui.NewLabel(font, palette)
|
||||||
|
label.Alignment = d2gui.HorizontalAlignCenter
|
||||||
|
|
||||||
|
res := &Tooltip{
|
||||||
|
backgroundColor: blackAlpha70,
|
||||||
|
label: label,
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
originX: originX,
|
||||||
|
originY: originY,
|
||||||
|
}
|
||||||
|
res.manager = ui
|
||||||
|
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetPosition sets the position of the origin point of the tooltip
|
||||||
|
func (t *Tooltip) SetPosition(x, y int) {
|
||||||
|
t.x = x
|
||||||
|
t.y = y
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetTextLines sets the tooltip text in the form of an array of strings
|
||||||
|
func (t *Tooltip) SetTextLines(lines []string) {
|
||||||
|
t.lines = lines
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetText sets the tooltip text and splits \n into lines
|
||||||
|
func (t *Tooltip) SetText(text string) {
|
||||||
|
t.lines = strings.Split(text, "\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Tooltip) adjustCoordinatesToScreen(maxW, maxH, halfW, halfH int) (rx, ry int) {
|
||||||
|
var xOffset, yOffset int
|
||||||
|
|
||||||
|
switch t.originX {
|
||||||
|
case TooltipXLeft:
|
||||||
|
xOffset = maxW
|
||||||
|
case TooltipXCenter:
|
||||||
|
xOffset = halfW
|
||||||
|
case TooltipXRight:
|
||||||
|
xOffset = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
renderX := t.x
|
||||||
|
if (t.x + xOffset) > screenWidth {
|
||||||
|
renderX = screenWidth - xOffset
|
||||||
|
}
|
||||||
|
|
||||||
|
switch t.originY {
|
||||||
|
case TooltipYTop:
|
||||||
|
yOffset = 0
|
||||||
|
case TooltipYCenter:
|
||||||
|
yOffset = halfH
|
||||||
|
case TooltipYBottom:
|
||||||
|
yOffset = maxH
|
||||||
|
}
|
||||||
|
|
||||||
|
renderY := t.y
|
||||||
|
if (t.y + yOffset) > screenHeight {
|
||||||
|
renderY = screenHeight - yOffset
|
||||||
|
}
|
||||||
|
|
||||||
|
return renderX, renderY
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Tooltip) getTextSize() (sx, sy int) {
|
||||||
|
maxW, maxH := 0, 0
|
||||||
|
|
||||||
|
for i := range t.lines {
|
||||||
|
w, h := t.label.GetTextMetrics(t.lines[i])
|
||||||
|
|
||||||
|
if maxW < w {
|
||||||
|
maxW = w
|
||||||
|
}
|
||||||
|
|
||||||
|
maxH += h
|
||||||
|
}
|
||||||
|
|
||||||
|
return maxW, maxH
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render draws the tooltip
|
||||||
|
func (t *Tooltip) Render(target d2interface.Surface) {
|
||||||
|
maxW, maxH := t.getTextSize()
|
||||||
|
|
||||||
|
// nolint:gomnd // no magic numbers, their meaning is obvious
|
||||||
|
halfW, halfH := maxW/2, maxH/2
|
||||||
|
|
||||||
|
renderX, renderY := t.adjustCoordinatesToScreen(maxW, maxH, halfW, halfH)
|
||||||
|
|
||||||
|
target.PushTranslation(renderX, renderY)
|
||||||
|
defer target.Pop()
|
||||||
|
|
||||||
|
// adjust starting point of the background rect based on the origin point
|
||||||
|
// as we always draw a rect from top left
|
||||||
|
switch t.originX {
|
||||||
|
case TooltipXLeft:
|
||||||
|
target.PushTranslation(0, 0)
|
||||||
|
case TooltipXCenter:
|
||||||
|
target.PushTranslation(-halfW, 0)
|
||||||
|
case TooltipXRight:
|
||||||
|
target.PushTranslation(-maxW, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer target.Pop()
|
||||||
|
|
||||||
|
switch t.originY {
|
||||||
|
case TooltipYTop:
|
||||||
|
target.PushTranslation(0, 0)
|
||||||
|
case TooltipYCenter:
|
||||||
|
target.PushTranslation(0, -halfH)
|
||||||
|
case TooltipXRight:
|
||||||
|
target.PushTranslation(0, -maxH)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer target.Pop()
|
||||||
|
|
||||||
|
// tooltip background
|
||||||
|
target.DrawRect(maxW, maxH, d2util.Color(blackAlpha70))
|
||||||
|
|
||||||
|
// text
|
||||||
|
target.PushTranslation(halfW, 0) // text is centered, our box is not
|
||||||
|
defer target.Pop()
|
||||||
|
|
||||||
|
for i := range t.lines {
|
||||||
|
t.label.SetText(t.lines[i])
|
||||||
|
_, h := t.label.GetTextMetrics(t.lines[i])
|
||||||
|
t.label.Render(target)
|
||||||
|
target.PushTranslation(0, h)
|
||||||
|
}
|
||||||
|
|
||||||
|
target.PopN(len(t.lines))
|
||||||
|
}
|
@ -3,14 +3,12 @@ package d2player
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2util"
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2records"
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2records"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2gui"
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2item/diablo2item"
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2item/diablo2item"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2ui"
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2ui"
|
||||||
)
|
)
|
||||||
@ -22,10 +20,6 @@ const (
|
|||||||
frameInventoryBottomRight = 7
|
frameInventoryBottomRight = 7
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
blackAlpha70 = 0x000000C8
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
invCloseButtonX, invCloseButtonY = 419, 449
|
invCloseButtonX, invCloseButtonY = 419, 449
|
||||||
)
|
)
|
||||||
@ -38,7 +32,7 @@ type Inventory struct {
|
|||||||
frame *d2ui.UIFrame
|
frame *d2ui.UIFrame
|
||||||
panel *d2ui.Sprite
|
panel *d2ui.Sprite
|
||||||
grid *ItemGrid
|
grid *ItemGrid
|
||||||
hoverLabel *d2ui.Label
|
itemTooltip *d2ui.Tooltip
|
||||||
closeButton *d2ui.Button
|
closeButton *d2ui.Button
|
||||||
hoverX int
|
hoverX int
|
||||||
hoverY int
|
hoverY int
|
||||||
@ -54,19 +48,18 @@ type Inventory struct {
|
|||||||
// NewInventory creates an inventory instance and returns a pointer to it
|
// NewInventory creates an inventory instance and returns a pointer to it
|
||||||
func NewInventory(asset *d2asset.AssetManager, ui *d2ui.UIManager,
|
func NewInventory(asset *d2asset.AssetManager, ui *d2ui.UIManager,
|
||||||
record *d2records.InventoryRecord) *Inventory {
|
record *d2records.InventoryRecord) *Inventory {
|
||||||
hoverLabel := ui.NewLabel(d2resource.FontFormal11, d2resource.PaletteStatic)
|
itemTooltip := ui.NewTooltip(d2resource.FontFormal11, d2resource.PaletteStatic, d2ui.TooltipXCenter, d2ui.TooltipYBottom)
|
||||||
hoverLabel.Alignment = d2gui.HorizontalAlignCenter
|
|
||||||
|
|
||||||
// https://github.com/OpenDiablo2/OpenDiablo2/issues/797
|
// https://github.com/OpenDiablo2/OpenDiablo2/issues/797
|
||||||
itemFactory, _ := diablo2item.NewItemFactory(asset)
|
itemFactory, _ := diablo2item.NewItemFactory(asset)
|
||||||
|
|
||||||
return &Inventory{
|
return &Inventory{
|
||||||
asset: asset,
|
asset: asset,
|
||||||
uiManager: ui,
|
uiManager: ui,
|
||||||
item: itemFactory,
|
item: itemFactory,
|
||||||
grid: NewItemGrid(asset, ui, record),
|
grid: NewItemGrid(asset, ui, record),
|
||||||
originX: record.Panel.Left,
|
originX: record.Panel.Left,
|
||||||
hoverLabel: hoverLabel,
|
itemTooltip: itemTooltip,
|
||||||
// originY: record.Panel.Top,
|
// originY: record.Panel.Top,
|
||||||
originY: 0, // expansion data has these all offset by +60 ...
|
originY: 0, // expansion data has these all offset by +60 ...
|
||||||
}
|
}
|
||||||
@ -250,48 +243,8 @@ func (g *Inventory) renderItemHover(target d2interface.Surface) {
|
|||||||
|
|
||||||
func (g *Inventory) renderItemDescription(target d2interface.Surface, i InventoryItem) {
|
func (g *Inventory) renderItemDescription(target d2interface.Surface, i InventoryItem) {
|
||||||
lines := i.GetItemDescription()
|
lines := i.GetItemDescription()
|
||||||
|
g.itemTooltip.SetTextLines(lines)
|
||||||
maxW, maxH := 0, 0
|
_, y := g.grid.SlotToScreen(i.InventoryGridSlot())
|
||||||
_, iy := g.grid.SlotToScreen(i.InventoryGridSlot())
|
g.itemTooltip.SetPosition(g.hoverX, y)
|
||||||
|
g.itemTooltip.Render(target)
|
||||||
for idx := range lines {
|
|
||||||
w, h := g.hoverLabel.GetTextMetrics(lines[idx])
|
|
||||||
|
|
||||||
if maxW < w {
|
|
||||||
maxW = w
|
|
||||||
}
|
|
||||||
|
|
||||||
maxH += h
|
|
||||||
}
|
|
||||||
|
|
||||||
halfW, halfH := maxW>>1, maxH>>1
|
|
||||||
centerX, centerY := g.hoverX, iy-halfH
|
|
||||||
|
|
||||||
if (centerX + halfW) > screenWidth {
|
|
||||||
centerX = screenWidth - halfW
|
|
||||||
}
|
|
||||||
|
|
||||||
if (centerY + halfH) > screenHeight {
|
|
||||||
centerY = screenHeight - halfH
|
|
||||||
}
|
|
||||||
|
|
||||||
target.PushTranslation(centerX, centerY)
|
|
||||||
defer target.Pop()
|
|
||||||
|
|
||||||
target.PushTranslation(-halfW, -halfH)
|
|
||||||
defer target.Pop()
|
|
||||||
|
|
||||||
target.DrawRect(maxW, maxH, d2util.Color(blackAlpha70))
|
|
||||||
|
|
||||||
target.PushTranslation(halfW, 0)
|
|
||||||
defer target.Pop()
|
|
||||||
|
|
||||||
for idx := range lines {
|
|
||||||
g.hoverLabel.SetText(lines[idx])
|
|
||||||
_, h := g.hoverLabel.GetTextMetrics(lines[idx])
|
|
||||||
g.hoverLabel.Render(target)
|
|
||||||
target.PushTranslation(0, h)
|
|
||||||
}
|
|
||||||
|
|
||||||
target.PopN(len(lines))
|
|
||||||
}
|
}
|
||||||
|
@ -5,15 +5,12 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2util"
|
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2tbl"
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2tbl"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2geom"
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2geom"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2gui"
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2hero"
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2hero"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2map/d2mapentity"
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2map/d2mapentity"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2ui"
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2ui"
|
||||||
@ -28,9 +25,6 @@ const (
|
|||||||
leftPanelStartX = 90
|
leftPanelStartX = 90
|
||||||
skillPanelOffsetY = 465
|
skillPanelOffsetY = 465
|
||||||
skillListsLength = 5 // 0 to 4. 0 - General Skills, 1 to 3 - Class-specific skills(based on the 3 different skill trees), 4 - Other skills
|
skillListsLength = 5 // 0 to 4. 0 - General Skills, 1 to 3 - Class-specific skills(based on the 3 different skill trees), 4 - Other skills
|
||||||
tooltipPadLeft = 3
|
|
||||||
tooltipPadRight = 3
|
|
||||||
tooltipPadBottom = 5
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// SkillPanel represents a skill select menu popup that is displayed when the player left clicks on his active left/right skill.
|
// SkillPanel represents a skill select menu popup that is displayed when the player left clicks on his active left/right skill.
|
||||||
@ -42,8 +36,7 @@ type SkillPanel struct {
|
|||||||
renderer d2interface.Renderer
|
renderer d2interface.Renderer
|
||||||
ui *d2ui.UIManager
|
ui *d2ui.UIManager
|
||||||
hoveredSkill *d2hero.HeroSkill
|
hoveredSkill *d2hero.HeroSkill
|
||||||
hoverTooltipRect *d2geom.Rectangle
|
hoverTooltip *d2ui.Tooltip
|
||||||
hoverTooltipText *d2ui.Label
|
|
||||||
isOpen bool
|
isOpen bool
|
||||||
regenerateImageCache bool
|
regenerateImageCache bool
|
||||||
isLeftPanel bool
|
isLeftPanel bool
|
||||||
@ -58,19 +51,18 @@ func NewHeroSkillsPanel(asset *d2asset.AssetManager, ui *d2ui.UIManager, hero *d
|
|||||||
activeSkill = hero.RightSkill
|
activeSkill = hero.RightSkill
|
||||||
}
|
}
|
||||||
|
|
||||||
hoverTooltipText := ui.NewLabel(d2resource.Font16, d2resource.PaletteStatic)
|
hoverTooltip := ui.NewTooltip(d2resource.Font16, d2resource.PaletteStatic, d2ui.TooltipXLeft, d2ui.TooltipYTop)
|
||||||
hoverTooltipText.Alignment = d2gui.HorizontalAlignCenter
|
|
||||||
|
|
||||||
return &SkillPanel{
|
return &SkillPanel{
|
||||||
asset: asset,
|
asset: asset,
|
||||||
activeSkill: activeSkill,
|
activeSkill: activeSkill,
|
||||||
ui: ui,
|
ui: ui,
|
||||||
isOpen: false,
|
isOpen: false,
|
||||||
ListRows: make([]*SkillListRow, skillListsLength),
|
ListRows: make([]*SkillListRow, skillListsLength),
|
||||||
renderer: ui.Renderer(),
|
renderer: ui.Renderer(),
|
||||||
isLeftPanel: isLeftPanel,
|
isLeftPanel: isLeftPanel,
|
||||||
hero: hero,
|
hero: hero,
|
||||||
hoverTooltipText: hoverTooltipText,
|
hoverTooltip: hoverTooltip,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,18 +135,7 @@ func (s *SkillPanel) Render(target d2interface.Surface) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if s.hoveredSkill != nil {
|
if s.hoveredSkill != nil {
|
||||||
target.PushTranslation(s.hoverTooltipRect.Left, s.hoverTooltipRect.Top)
|
s.hoverTooltip.Render(target)
|
||||||
|
|
||||||
black70 := d2util.Color(blackAlpha70)
|
|
||||||
target.DrawRect(s.hoverTooltipRect.Width, s.hoverTooltipRect.Height, black70)
|
|
||||||
|
|
||||||
// the text should be centered horizontally in the tooltip rect
|
|
||||||
centerX := s.hoverTooltipRect.Width >> 1
|
|
||||||
target.PushTranslation(centerX, 0)
|
|
||||||
s.hoverTooltipText.Render(target)
|
|
||||||
|
|
||||||
target.Pop()
|
|
||||||
target.Pop()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -353,26 +334,13 @@ func (s *SkillPanel) HandleMouseMove(x, y int) bool {
|
|||||||
|
|
||||||
if previousHovered != s.hoveredSkill && s.hoveredSkill != nil {
|
if previousHovered != s.hoveredSkill && s.hoveredSkill != nil {
|
||||||
skillDescription := d2tbl.TranslateString(s.hoveredSkill.ShortKey)
|
skillDescription := d2tbl.TranslateString(s.hoveredSkill.ShortKey)
|
||||||
s.hoverTooltipText.SetText(fmt.Sprintf("%s\n%s", s.hoveredSkill.Skill, skillDescription))
|
s.hoverTooltip.SetText(fmt.Sprintf("%s\n%s", s.hoveredSkill.Skill, skillDescription))
|
||||||
|
|
||||||
listRow := s.GetListRowByPos(x, y)
|
listRow := s.GetListRowByPos(x, y)
|
||||||
textWidth, textHeight := s.hoverTooltipText.GetSize()
|
|
||||||
|
|
||||||
tooltipX := (s.getSkillIdxAtPos(x, y) * skillIconWidth) + s.getRowStartX(listRow)
|
tooltipX := (s.getSkillIdxAtPos(x, y) * skillIconWidth) + s.getRowStartX(listRow)
|
||||||
tooltipWidth := textWidth + tooltipPadLeft + tooltipPadRight
|
|
||||||
|
|
||||||
if tooltipX+tooltipWidth >= screenWidth {
|
|
||||||
tooltipX = screenWidth - tooltipWidth
|
|
||||||
}
|
|
||||||
|
|
||||||
tooltipY := listRow.Rectangle.Top + listRow.Rectangle.Height
|
tooltipY := listRow.Rectangle.Top + listRow.Rectangle.Height
|
||||||
tooltipHeight := textHeight + tooltipPadBottom
|
s.hoverTooltip.SetPosition(tooltipX, tooltipY)
|
||||||
|
|
||||||
s.hoverTooltipRect = &d2geom.Rectangle{
|
|
||||||
Left: tooltipX,
|
|
||||||
Top: tooltipY,
|
|
||||||
Width: tooltipWidth,
|
|
||||||
Height: tooltipHeight}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
Loading…
Reference in New Issue
Block a user