148 lines
3.4 KiB
Go
148 lines
3.4 KiB
Go
package dialog
|
|
|
|
import (
|
|
"path/filepath"
|
|
"time"
|
|
|
|
"fyne.io/fyne/v2"
|
|
"fyne.io/fyne/v2/lang"
|
|
"fyne.io/fyne/v2/theme"
|
|
"fyne.io/fyne/v2/widget"
|
|
)
|
|
|
|
const (
|
|
fileIconSize = 64
|
|
fileInlineIconSize = 24
|
|
fileIconCellWidth = fileIconSize * 1.25
|
|
)
|
|
|
|
type fileDialogItem struct {
|
|
widget.BaseWidget
|
|
picker *fileDialog
|
|
|
|
name string
|
|
id int // id in the parent container
|
|
choose func(id int)
|
|
open func()
|
|
location fyne.URI
|
|
dir bool
|
|
|
|
lastClick time.Time
|
|
}
|
|
|
|
func (i *fileDialogItem) CreateRenderer() fyne.WidgetRenderer {
|
|
text := widget.NewLabelWithStyle(i.name, fyne.TextAlignCenter, fyne.TextStyle{})
|
|
text.Truncation = fyne.TextTruncateEllipsis
|
|
text.Wrapping = fyne.TextWrapBreak
|
|
icon := widget.NewFileIcon(i.location)
|
|
|
|
return &fileItemRenderer{
|
|
item: i,
|
|
icon: icon,
|
|
text: text,
|
|
objects: []fyne.CanvasObject{icon, text},
|
|
fileTextSize: widget.NewLabel("M\nM").MinSize().Height, // cache two-line label height,
|
|
}
|
|
}
|
|
|
|
func (i *fileDialogItem) setLocation(l fyne.URI, dir, up bool) {
|
|
i.dir = dir
|
|
i.location = l
|
|
i.name = l.Name()
|
|
|
|
if i.picker.view == GridView {
|
|
ext := filepath.Ext(i.name[1:])
|
|
i.name = i.name[:len(i.name)-len(ext)]
|
|
}
|
|
|
|
if up {
|
|
i.name = "(" + lang.X("file.parent", "Parent") + ")"
|
|
}
|
|
|
|
i.Refresh()
|
|
}
|
|
|
|
func (i *fileDialogItem) Tapped(*fyne.PointEvent) {
|
|
if i.choose != nil {
|
|
i.choose(i.id)
|
|
}
|
|
now := time.Now()
|
|
if !i.dir && now.Sub(i.lastClick) < fyne.CurrentApp().Driver().DoubleTapDelay() && i.open != nil {
|
|
// It is a double click, so we ask the dialog to open
|
|
i.open()
|
|
}
|
|
i.lastClick = now
|
|
}
|
|
|
|
func (f *fileDialog) newFileItem(location fyne.URI, dir, up bool) *fileDialogItem {
|
|
item := &fileDialogItem{
|
|
picker: f,
|
|
location: location,
|
|
name: location.Name(),
|
|
dir: dir,
|
|
}
|
|
|
|
if f.view == GridView {
|
|
ext := filepath.Ext(item.name[1:])
|
|
item.name = item.name[:len(item.name)-len(ext)]
|
|
}
|
|
|
|
if up {
|
|
item.name = "(" + lang.X("file.parent", "Parent") + ")"
|
|
}
|
|
|
|
item.ExtendBaseWidget(item)
|
|
return item
|
|
}
|
|
|
|
type fileItemRenderer struct {
|
|
item *fileDialogItem
|
|
fileTextSize float32
|
|
|
|
icon *widget.FileIcon
|
|
text *widget.Label
|
|
objects []fyne.CanvasObject
|
|
}
|
|
|
|
func (s *fileItemRenderer) Layout(size fyne.Size) {
|
|
if s.item.picker.view == GridView {
|
|
s.icon.Resize(fyne.NewSize(fileIconSize, fileIconSize))
|
|
s.icon.Move(fyne.NewPos((size.Width-fileIconSize)/2, 0))
|
|
|
|
s.text.Alignment = fyne.TextAlignCenter
|
|
s.text.Resize(fyne.NewSize(size.Width, s.fileTextSize))
|
|
s.text.Move(fyne.NewPos(0, size.Height-s.fileTextSize))
|
|
} else {
|
|
s.icon.Resize(fyne.NewSize(fileInlineIconSize, fileInlineIconSize))
|
|
s.icon.Move(fyne.NewPos(theme.Padding(), (size.Height-fileInlineIconSize)/2))
|
|
|
|
s.text.Alignment = fyne.TextAlignLeading
|
|
textMin := s.text.MinSize()
|
|
s.text.Resize(fyne.NewSize(size.Width, textMin.Height))
|
|
s.text.Move(fyne.NewPos(fileInlineIconSize, (size.Height-textMin.Height)/2))
|
|
}
|
|
}
|
|
|
|
func (s *fileItemRenderer) MinSize() fyne.Size {
|
|
if s.item.picker.view == GridView {
|
|
return fyne.NewSize(fileIconCellWidth, fileIconSize+s.fileTextSize)
|
|
}
|
|
|
|
textMin := s.text.MinSize()
|
|
return fyne.NewSize(fileInlineIconSize+textMin.Width+theme.Padding(), textMin.Height)
|
|
}
|
|
|
|
func (s *fileItemRenderer) Refresh() {
|
|
s.fileTextSize = widget.NewLabel("M\nM").MinSize().Height // cache two-line label height
|
|
|
|
s.text.SetText(s.item.name)
|
|
s.icon.SetURI(s.item.location)
|
|
}
|
|
|
|
func (s *fileItemRenderer) Objects() []fyne.CanvasObject {
|
|
return s.objects
|
|
}
|
|
|
|
func (s *fileItemRenderer) Destroy() {
|
|
}
|