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() } }