Path: blob/main/internal/components/hoverpopover/hoverpopover.go
366 views
package hoverpopover12import (3"github.com/diamondburned/gotk4/pkg/glib/v2"4"github.com/diamondburned/gotk4/pkg/gtk/v4"5"github.com/diamondburned/gotkit/gtkutil/cssutil"6)78var _ = cssutil.WriteCSS(`9.popover-label {10padding: 0 0.25em;11}12`)1314// MarkupHoverPopover is a struct that represents a hover popover15// that is displayed when the user hovers over a widget. The popover16// only displays markup text. Markup texts are persisted across17// hovers.18//19// Popovers are lazily allocated, so they are only created when20// the user hovers over a widget. They are automatically destroyed21// a moment after the user stops hovering over the widget.22type MarkupHoverPopover struct {23hover *gtk.EventControllerMotion24controller *PopoverController25initFn func(*MarkupHoverPopoverWidget) bool26}2728// MarkupHoverPopoverWidget is a struct that represents a popover29// widget that displays markup text.30type MarkupHoverPopoverWidget struct {31*gtk.Popover32Label *gtk.Label33}3435var markupHoverPopoverClasses = []string{36"hover-popover",37"hover-popover-markup",38}3940// NewMarkupHoverPopover creates a new MarkupHoverPopover.41func NewMarkupHoverPopover(parent gtk.Widgetter, initFn func(*MarkupHoverPopoverWidget) bool) *MarkupHoverPopover {42p := &MarkupHoverPopover{43initFn: initFn,44}45p.controller = NewPopoverController(parent, p.initPopover)4647p.hover = gtk.NewEventControllerMotion()4849// Implement a very primitive delay. This is to prevent the popover50// from popping up when the user is scrolling on a touchpad.51var delayID glib.SourceHandle52var hovered bool53const hoverDelay = 100 // ms5455p.hover.ConnectEnter(func(_, _ float64) {56hovered = true5758if delayID != 0 {59return60}6162delayID = glib.TimeoutAdd(hoverDelay, func() {63delayID = 06465if hovered {66p.controller.Popup()67}68})69})7071p.hover.ConnectLeave(func() {72hovered = false7374if delayID != 0 {75glib.SourceRemove(delayID)76delayID = 077return78}7980p.controller.Popdown()81})8283parentWidget := gtk.BaseWidget(parent)84parentWidget.AddController(p.hover)8586var windowSignal glib.SignalHandle87var window *gtk.Window8889attachWindow := func() {90if window != nil {91window.HandlerDisconnect(windowSignal)92window = nil93}9495root := parentWidget.Root()96if root != nil {97window = root.CastType(gtk.GTypeWindow).(*gtk.Window)98windowSignal = window.NotifyProperty("is-active", func() {99if p.controller.IsPoppedUp() && !window.IsActive() {100p.controller.Popdown()101}102})103}104}105106parentWidget.NotifyProperty("root", attachWindow)107attachWindow()108109return p110}111112func (p *MarkupHoverPopover) initPopover(popover *gtk.Popover) bool {113current := &MarkupHoverPopoverWidget{Popover: popover}114115current.Label = gtk.NewLabel("")116current.Label.AddCSSClass("popover-label")117current.Label.AddCSSClass("hover-popover-label")118119current.AddCSSClass("hover-popover")120current.AddCSSClass("hover-popover-markup")121current.SetAutohide(false)122current.SetMnemonicsVisible(false)123current.SetCanFocus(false)124current.SetCanTarget(false)125current.SetChild(current.Label)126127return p.initFn(current)128}129130131