Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Double-click to select a file in FileOpen / FileSave dialogs #4794

Merged
merged 8 commits into from Apr 27, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
24 changes: 15 additions & 9 deletions dialog/file.go
Expand Up @@ -533,7 +533,14 @@ func (f *fileDialog) setSelected(file fyne.URI, id int) {
func (f *fileDialog) setView(view ViewLayout) {
f.view = view
fyne.CurrentApp().Preferences().SetInt(viewLayoutKey, int(view))

var selectF func(id int)
choose := func(id int) {
selectF(id)
if file, ok := f.getDataItem(id); ok {
f.selectedID = id
f.setSelected(file, id)
}
}
count := func() int {
f.dataLock.RLock()
defer f.dataLock.RUnlock()
Expand All @@ -547,26 +554,25 @@ func (f *fileDialog) setView(view ViewLayout) {
if dir, ok := f.getDataItem(id); ok {
parent := id == 0 && len(dir.Path()) < len(f.dir.Path())
_, isDir := dir.(fyne.ListableURI)
o.(*fileDialogItem).setLocation(dir, isDir || parent, parent)
o.(*fileDialogItem).setLocation(dir, isDir || parent, parent, id)
o.(*fileDialogItem).choose = choose
o.(*fileDialogItem).open = f.open.OnTapped
}
}
choose := func(id int) {
if file, ok := f.getDataItem(id); ok {
f.selectedID = id
f.setSelected(file, id)
}
}

// Acutally, during the real interaction, the choose won't be called.
dweymouth marked this conversation as resolved.
Show resolved Hide resolved
// It will be called only when we directly calls container.select(i)
if f.view == GridView {
grid := widget.NewGridWrap(count, template, update)
grid.OnSelected = choose
f.files = grid
f.toggleViewButton.SetIcon(theme.ListIcon())
selectF = grid.Select
} else {
list := widget.NewList(count, template, update)
list.OnSelected = choose
f.files = list
f.toggleViewButton.SetIcon(theme.GridIcon())
selectF = list.Select
}

if f.dir != nil {
Expand Down
21 changes: 20 additions & 1 deletion dialog/fileitem.go
Expand Up @@ -2,6 +2,7 @@ package dialog

import (
"path/filepath"
"time"

"fyne.io/fyne/v2"
"fyne.io/fyne/v2/lang"
Expand All @@ -20,8 +21,13 @@ type fileDialogItem struct {
picker *fileDialog

name string
id int // id in the father container
Dorbmon marked this conversation as resolved.
Show resolved Hide resolved
choose func(id int)
open func()
location fyne.URI
dir bool

lastClick time.Time
}

func (i *fileDialogItem) CreateRenderer() fyne.WidgetRenderer {
Expand All @@ -39,7 +45,8 @@ func (i *fileDialogItem) CreateRenderer() fyne.WidgetRenderer {
}
}

func (i *fileDialogItem) setLocation(l fyne.URI, dir, up bool) {
func (i *fileDialogItem) setLocation(l fyne.URI, dir, up bool, id int) {
dweymouth marked this conversation as resolved.
Show resolved Hide resolved
i.id = id
i.dir = dir
i.location = l
i.name = l.Name()
Expand All @@ -56,6 +63,18 @@ func (i *fileDialogItem) setLocation(l fyne.URI, dir, up bool) {
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,
Expand Down
2 changes: 1 addition & 1 deletion dialog/fileitem_test.go
Expand Up @@ -120,7 +120,7 @@ func TestFileItem_Wrap(t *testing.T) {
texts := test.WidgetRenderer(label).Objects()
assert.Equal(t, 1, len(texts))

item.setLocation(storage.NewFileURI("/path/to/averylongfilename.svg"), false, false)
item.setLocation(storage.NewFileURI("/path/to/averylongfilename.svg"), false, false, 0)
rich := test.WidgetRenderer(label).Objects()[0].(*widget.RichText)
texts = test.WidgetRenderer(rich).Objects()
assert.Equal(t, 2, len(texts))
Expand Down