mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2024-11-09 03:37:17 -05:00
1f49df62d1
* d2ui/tooltip: Make it invisible by default * d2ui/button: Add GetToggled() method * d2player/HUD: Add tooltip for minipanel button * d2ui/button: Add disabled frame to minipanel buttons * d2ui/widget_group: Add SetEnable method for clickable widgets * d2player/mini_panel: move menu button here from HUD * d2ui/button: toggled buttons take preference over disabled buttons * d2player/help_overlay: Make panel only use widgets * d2player/hud: Group most widgets into widget group * d2ui/custom_widget: Allow tooltip to be attached * d2player/hud: Attach staminaBar tooltip to staminaBar * d2player/hud: Attach experienceBar tooltip to experienceBar widget * d2ui/ui_manager: Always draw tooltips last * d2player/help_overlay: It should be drawn over the HUD * d2player/globeWidget: Move tooltip here from HUD * d2core/tooltip: Automatically add tooltips to the uiManager * d2core/ui_manager: Remove special handling of widgetGroups for rendering * d2player/help_overlay: Add button to widget group * d2player/hud: Attack runwalk tooltip to button * d2player/mini_panel: Add panelButton to its own widget group * d2core/widget_group: When a clickable is added, it's also added to uiManager * d2player/globeWidget: make tooltip un/lock on click * d2player/hud: Add runbutton to widget group * d2player/mini_panel: Add group for tooltips this allows us to move the tooltip with the panelbuttons. They can't be in the general panelGroup as they would all become visible when the panel is opened. * d2core/button: Remove debug log when a button with tooltip is hovered
202 lines
4.3 KiB
Go
202 lines
4.3 KiB
Go
package d2ui
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2util"
|
|
)
|
|
|
|
const (
|
|
blackAlpha70 = 0x000000C8
|
|
screenWidth = 800
|
|
screenHeight = 600
|
|
)
|
|
|
|
// static check that Tooltip implements widget
|
|
var _ Widget = &Tooltip{}
|
|
|
|
// Tooltip contains a label containing text with a transparent, black background
|
|
type Tooltip struct {
|
|
*BaseWidget
|
|
lines []string
|
|
label *Label
|
|
backgroundColor int
|
|
originX tooltipXOrigin
|
|
originY tooltipYOrigin
|
|
boxEnabled bool
|
|
}
|
|
|
|
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 = HorizontalAlignCenter
|
|
|
|
base := NewBaseWidget(ui)
|
|
base.SetVisible(false)
|
|
|
|
res := &Tooltip{
|
|
BaseWidget: base,
|
|
backgroundColor: blackAlpha70,
|
|
label: label,
|
|
originX: originX,
|
|
originY: originY,
|
|
boxEnabled: true,
|
|
}
|
|
res.manager = ui
|
|
ui.addTooltip(res)
|
|
|
|
return res
|
|
}
|
|
|
|
// 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")
|
|
}
|
|
|
|
// SetBoxEnabled determines whether a black box is drawn around the text
|
|
func (t *Tooltip) SetBoxEnabled(enable bool) {
|
|
t.boxEnabled = enable
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
// GetSize returns the size of the tooltip
|
|
func (t *Tooltip) GetSize() (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.GetSize()
|
|
|
|
// 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
|
|
if t.boxEnabled {
|
|
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))
|
|
}
|
|
|
|
// Advance is a no-op
|
|
func (t *Tooltip) Advance(elapsed float64) error {
|
|
return nil
|
|
}
|