ui/uiwidget/dateentry.go
2024-04-11 14:52:32 +02:00

132 lines
2.7 KiB
Go

package uiwidget
import (
"math"
"time"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/theme"
"fyne.io/fyne/v2/widget"
xwidget "fyne.io/x/fyne/widget"
)
type DateEntry struct {
widget.Entry
calendar *xwidget.Calendar
popUp *widget.PopUp
OnDateChanged func(time.Time)
date time.Time
}
func NewDateEntry() *DateEntry {
e := &DateEntry{}
e.Validator = func(s string) error {
_, err := time.Parse("02/01/2006", s)
return err
}
e.OnChanged = func(s string) {
if e.Validate() != nil {
if e.OnDateChanged != nil {
time, _ := time.Parse("02/01/2006", s)
e.OnDateChanged(time)
}
}
}
e.ExtendBaseWidget(e)
e.SetDate(time.Now())
return e
}
func (e *DateEntry) CreateRenderer() fyne.WidgetRenderer {
e.ExtendBaseWidget(e)
if e.ActionItem == nil {
e.ActionItem = e.setupDropdown()
if e.Disabled() {
e.ActionItem.(fyne.Disableable).Disable()
}
}
return e.Entry.CreateRenderer()
}
func (e *DateEntry) Enable() {
if e.ActionItem != nil {
e.ActionItem.(fyne.Disableable).Enable()
}
e.Entry.Enable()
}
func (e *DateEntry) Disable() {
if e.ActionItem != nil {
e.ActionItem.(fyne.Disableable).Disable()
}
e.Entry.Disable()
}
func (e *DateEntry) MinSize() fyne.Size {
e.ExtendBaseWidget(e)
return e.Entry.MinSize()
}
func (e *DateEntry) Move(pos fyne.Position) {
e.Entry.Move(pos)
if e.popUp != nil {
e.popUp.Move(e.popUpPos())
}
}
func (e *DateEntry) Resize(size fyne.Size) {
e.Entry.Resize(size)
if e.popUp != nil {
e.popUp.Resize(fyne.NewSize(size.Width, e.popUp.Size().Height))
}
}
func (e *DateEntry) SetDate(date time.Time) {
e.date = date
e.calendar = xwidget.NewCalendar(date, e.onDateSelected)
e.SetText(date.Format("02/01/2006"))
if e.ActionItem == nil {
e.ActionItem = e.setupDropdown()
if e.Disabled() {
e.ActionItem.(fyne.Disableable).Disable()
}
}
}
func (e *DateEntry) GetDate() time.Time {
return e.date
}
func (e *DateEntry) popUpPos() fyne.Position {
entryPos := fyne.CurrentApp().Driver().AbsolutePositionForObject(e)
return entryPos.Add(fyne.NewPos(0, e.Size().Height-theme.InputBorderSize()))
}
func (e *DateEntry) setupDropdown() *widget.Button {
dropdownButton := widget.NewButton("", func() {
c := fyne.CurrentApp().Driver().CanvasForObject(e)
e.popUp = widget.NewPopUp(e.calendar, c)
e.popUp.ShowAtPosition(e.popUpPos())
e.popUp.Resize(
fyne.NewSize(
float32(math.Max(float64(e.Size().Width), float64(e.popUp.MinSize().Width))),
e.popUp.MinSize().Height))
})
dropdownButton.Importance = widget.LowImportance
dropdownButton.SetIcon(theme.MenuDropDownIcon())
return dropdownButton
}
func (e *DateEntry) onDateSelected(date time.Time) {
e.date = date
e.SetText(e.date.Format("02/01/2006"))
if e.popUp != nil {
e.popUp.Hide()
}
}