Add layout system and file selection logic
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.
This commit is contained in:
@@ -1,14 +1,24 @@
|
||||
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() fyne.CanvasObject {
|
||||
form := newFormConvertor()
|
||||
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()))
|
||||
@@ -17,17 +27,146 @@ func Convertor() fyne.CanvasObject {
|
||||
type formConvertor struct {
|
||||
form *widget.Form
|
||||
items []*widget.FormItem
|
||||
|
||||
window window.WindowContract
|
||||
addFileForConversion func(file ffmpeg.File)
|
||||
}
|
||||
|
||||
func newFormConvertor() *formConvertor {
|
||||
func newFormConvertor(window window.WindowContract, addFileForConversion func(file ffmpeg.File)) *formConvertor {
|
||||
f := widget.NewForm()
|
||||
f.SubmitText = lang.L("converterVideoFilesSubmitTitle")
|
||||
|
||||
return &formConvertor{
|
||||
form: f,
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user