Introduce a new layout system for managing main window content and tabs. Integrate file selection and drag-and-drop functionality for adding files to the conversion list, with automatic tab switching to "Added Files". Refactor existing components to support these features.
173 lines
4.1 KiB
Go
173 lines
4.1 KiB
Go
package view
|
|
|
|
import (
|
|
"errors"
|
|
"fyne.io/fyne/v2"
|
|
"fyne.io/fyne/v2/canvas"
|
|
"fyne.io/fyne/v2/container"
|
|
"fyne.io/fyne/v2/lang"
|
|
"fyne.io/fyne/v2/storage"
|
|
"fyne.io/fyne/v2/widget"
|
|
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg"
|
|
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/gui/window"
|
|
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/utils"
|
|
"git.kor-elf.net/kor-elf/gui-for-ffmpeg/kernel"
|
|
"image/color"
|
|
"os"
|
|
"path/filepath"
|
|
)
|
|
|
|
func Convertor(window window.WindowContract, addFileForConversion func(file ffmpeg.File)) fyne.CanvasObject {
|
|
form := newFormConvertor(window, addFileForConversion)
|
|
|
|
converterVideoFilesTitle := lang.L("converterVideoFilesTitle")
|
|
return widget.NewCard(converterVideoFilesTitle, "", container.NewVScroll(form.getForm()))
|
|
}
|
|
|
|
type formConvertor struct {
|
|
form *widget.Form
|
|
items []*widget.FormItem
|
|
|
|
window window.WindowContract
|
|
addFileForConversion func(file ffmpeg.File)
|
|
}
|
|
|
|
func newFormConvertor(window window.WindowContract, addFileForConversion func(file ffmpeg.File)) *formConvertor {
|
|
f := widget.NewForm()
|
|
f.SubmitText = lang.L("converterVideoFilesSubmitTitle")
|
|
|
|
formConvertor := &formConvertor{
|
|
form: f,
|
|
window: window,
|
|
addFileForConversion: addFileForConversion,
|
|
}
|
|
|
|
fileForConversion := formConvertor.newFileForConversion()
|
|
|
|
items := []*widget.FormItem{
|
|
{
|
|
Text: lang.L("fileForConversionTitle"),
|
|
Widget: fileForConversion.button,
|
|
},
|
|
{
|
|
Widget: container.NewHScroll(fileForConversion.message),
|
|
},
|
|
}
|
|
formConvertor.form.Items = items
|
|
formConvertor.items = items
|
|
|
|
return formConvertor
|
|
}
|
|
|
|
func (f *formConvertor) getForm() *widget.Form {
|
|
return f.form
|
|
}
|
|
|
|
type fileForConversion struct {
|
|
button *widget.Button
|
|
message *canvas.Text
|
|
file *kernel.File
|
|
|
|
changeCallbacks map[int]func(err error)
|
|
}
|
|
|
|
func (f *formConvertor) newFileForConversion() *fileForConversion {
|
|
message := canvas.NewText("", color.RGBA{R: 255, G: 0, B: 0, A: 255})
|
|
fileForConversion := &fileForConversion{
|
|
message: message,
|
|
|
|
changeCallbacks: map[int]func(err error){},
|
|
}
|
|
|
|
buttonTitle := lang.L("choose") + "\n" +
|
|
lang.L("or") + "\n" +
|
|
lang.L("dragAndDropFiles")
|
|
|
|
var locationURI fyne.ListableURI
|
|
|
|
fileForConversion.button = widget.NewButton(buttonTitle, func() {
|
|
f.window.NewFileOpen(func(r fyne.URIReadCloser, err error) {
|
|
fyne.Do(func() {
|
|
fileForConversion.message.Text = ""
|
|
fileForConversion.message.Refresh()
|
|
})
|
|
|
|
if err != nil {
|
|
fyne.Do(func() {
|
|
fileForConversion.message.Text = err.Error()
|
|
fileForConversion.message.Refresh()
|
|
})
|
|
fileForConversion.eventSelectFile(err)
|
|
return
|
|
}
|
|
if r == nil {
|
|
return
|
|
}
|
|
|
|
f.addFileForConversion(ffmpeg.File{
|
|
Path: r.URI().Path(),
|
|
Name: r.URI().Name(),
|
|
Ext: r.URI().Extension(),
|
|
})
|
|
|
|
fileForConversion.eventSelectFile(nil)
|
|
|
|
listableURI := storage.NewFileURI(filepath.Dir(r.URI().Path()))
|
|
locationURI, _ = storage.ListerForURI(listableURI)
|
|
}, locationURI)
|
|
})
|
|
|
|
f.window.SetOnDropped(func(position fyne.Position, uris []fyne.URI) {
|
|
if len(uris) == 0 {
|
|
return
|
|
}
|
|
|
|
isError := false
|
|
for _, uri := range uris {
|
|
info, err := os.Stat(uri.Path())
|
|
if err != nil {
|
|
isError = true
|
|
continue
|
|
}
|
|
if info.IsDir() {
|
|
isError = true
|
|
continue
|
|
}
|
|
|
|
f.addFileForConversion(ffmpeg.File{
|
|
Path: uri.Path(),
|
|
Name: uri.Name(),
|
|
Ext: uri.Extension(),
|
|
})
|
|
|
|
fileForConversion.eventSelectFile(nil)
|
|
|
|
listableURI := storage.NewFileURI(filepath.Dir(uri.Path()))
|
|
locationURI, _ = storage.ListerForURI(listableURI)
|
|
}
|
|
|
|
if isError {
|
|
fileForConversion.message.Text = lang.L("errorDragAndDropFile")
|
|
utils.SetStringErrorStyle(fileForConversion.message)
|
|
fileForConversion.eventSelectFile(errors.New(fileForConversion.message.Text))
|
|
} else {
|
|
fyne.Do(func() {
|
|
fileForConversion.message.Text = ""
|
|
fileForConversion.message.Refresh()
|
|
})
|
|
}
|
|
})
|
|
|
|
return fileForConversion
|
|
}
|
|
|
|
func (c *fileForConversion) addChangeCallback(callback func(err error)) {
|
|
c.changeCallbacks[len(c.changeCallbacks)] = callback
|
|
}
|
|
|
|
func (c *fileForConversion) eventSelectFile(err error) {
|
|
for _, changeCallback := range c.changeCallbacks {
|
|
changeCallback(err)
|
|
}
|
|
}
|