adam-gui/vendor/fyne.io/fyne/v2/widget/popup_menu.go

157 lines
4.2 KiB
Go
Raw Permalink Normal View History

2024-04-29 19:13:50 +02:00
package widget
import (
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/internal/widget"
)
var _ fyne.Widget = (*PopUpMenu)(nil)
var _ fyne.Focusable = (*PopUpMenu)(nil)
// PopUpMenu is a Menu which displays itself in an OverlayContainer.
type PopUpMenu struct {
*Menu
canvas fyne.Canvas
overlay *widget.OverlayContainer
}
// NewPopUpMenu creates a new, reusable popup menu. You can show it using ShowAtPosition.
//
// Since: 2.0
func NewPopUpMenu(menu *fyne.Menu, c fyne.Canvas) *PopUpMenu {
m := &Menu{}
m.setMenu(menu)
p := &PopUpMenu{Menu: m, canvas: c}
p.ExtendBaseWidget(p)
p.Menu.Resize(p.Menu.MinSize())
p.Menu.customSized = true
o := widget.NewOverlayContainer(p, c, p.Dismiss)
o.Resize(o.MinSize())
p.overlay = o
p.OnDismiss = func() {
p.Hide()
}
return p
}
// ShowPopUpMenuAtPosition creates a PopUp menu populated with items from the passed menu structure.
// It will automatically be positioned at the provided location and shown as an overlay on the specified canvas.
func ShowPopUpMenuAtPosition(menu *fyne.Menu, c fyne.Canvas, pos fyne.Position) {
m := NewPopUpMenu(menu, c)
m.ShowAtPosition(pos)
}
// ShowPopUpMenuAtRelativePosition creates a PopUp menu populated with meny items from the passed menu structure.
// It will automatically be positioned at the given position relative to stated object and shown as an overlay on the specified canvas.
//
// Since 2.4
func ShowPopUpMenuAtRelativePosition(menu *fyne.Menu, c fyne.Canvas, rel fyne.Position, to fyne.CanvasObject) {
withRelativePosition(rel, to, func(pos fyne.Position) {
ShowPopUpMenuAtPosition(menu, c, pos)
})
}
// FocusGained is triggered when the object gained focus. For the pop-up menu it does nothing.
//
// Implements: fyne.Focusable
func (p *PopUpMenu) FocusGained() {}
// FocusLost is triggered when the object lost focus. For the pop-up menu it does nothing.
//
// Implements: fyne.Focusable
func (p *PopUpMenu) FocusLost() {}
// Hide hides the pop-up menu.
//
// Implements: fyne.Widget
func (p *PopUpMenu) Hide() {
p.overlay.Hide()
p.Menu.Hide()
}
// Move moves the pop-up menu.
// The position is absolute because pop-up menus are shown in an overlay which covers the whole canvas.
//
// Implements: fyne.Widget
func (p *PopUpMenu) Move(pos fyne.Position) {
p.BaseWidget.Move(p.adjustedPosition(pos, p.Size()))
}
// Resize changes the size of the pop-up menu.
//
// Implements: fyne.Widget
func (p *PopUpMenu) Resize(size fyne.Size) {
p.BaseWidget.Move(p.adjustedPosition(p.Position(), size))
p.Menu.Resize(size)
}
// Show makes the pop-up menu visible.
//
// Implements: fyne.Widget
func (p *PopUpMenu) Show() {
p.Menu.alignment = p.alignment
p.Menu.Refresh()
p.overlay.Show()
p.Menu.Show()
if !fyne.CurrentDevice().IsMobile() {
p.canvas.Focus(p)
}
}
// ShowAtPosition shows the pop-up menu at the specified position.
func (p *PopUpMenu) ShowAtPosition(pos fyne.Position) {
p.Move(pos)
p.Show()
}
// ShowAtRelativePosition shows the pop-up menu at the position relative to given object.
//
// Since 2.4
func (p *PopUpMenu) ShowAtRelativePosition(rel fyne.Position, to fyne.CanvasObject) {
withRelativePosition(rel, to, p.ShowAtPosition)
}
// TypedKey handles key events. It allows keyboard control of the pop-up menu.
//
// Implements: fyne.Focusable
func (p *PopUpMenu) TypedKey(e *fyne.KeyEvent) {
switch e.Name {
case fyne.KeyDown:
p.ActivateNext()
case fyne.KeyEnter, fyne.KeyReturn, fyne.KeySpace:
p.TriggerLast()
case fyne.KeyEscape:
p.Dismiss()
case fyne.KeyLeft:
p.DeactivateLastSubmenu()
case fyne.KeyRight:
p.ActivateLastSubmenu()
case fyne.KeyUp:
p.ActivatePrevious()
}
}
// TypedRune handles text events. For pop-up menus this does nothing.
//
// Implements: fyne.Focusable
func (p *PopUpMenu) TypedRune(rune) {}
func (p *PopUpMenu) adjustedPosition(pos fyne.Position, size fyne.Size) fyne.Position {
x := pos.X
y := pos.Y
if x+size.Width > p.canvas.Size().Width {
x = p.canvas.Size().Width - size.Width
if x < 0 {
x = 0 // TODO here we may need a scroller as it's wider than our canvas
}
}
if y+size.Height > p.canvas.Size().Height {
y = p.canvas.Size().Height - size.Height
if y < 0 {
y = 0 // TODO here we may need a scroller as it's longer than our canvas
}
}
return fyne.NewPos(x, y)
}