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), directoryForSavingPath string, directoryForSaving func(path string), ) fyne.CanvasObject { form := newFormConvertor( window, addFileForConversion, directoryForSavingPath, directoryForSaving, ) 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) directoryForSaving func(path string) } func newFormConvertor( window window.WindowContract, addFileForConversion func(file ffmpeg.File), directoryForSavingPath string, directoryForSaving func(path string), ) *formConvertor { f := widget.NewForm() f.SubmitText = lang.L("converterVideoFilesSubmitTitle") formConvertor := &formConvertor{ form: f, window: window, addFileForConversion: addFileForConversion, directoryForSaving: directoryForSaving, } fileForConversion := formConvertor.newFileForConversion() directoryForSavingButton := formConvertor.newDirectoryForSaving(directoryForSavingPath) items := []*widget.FormItem{ { Text: lang.L("fileForConversionTitle"), Widget: fileForConversion.button, }, { Widget: container.NewHScroll(fileForConversion.message), }, { Text: lang.L("buttonForSelectedDirTitle"), Widget: directoryForSavingButton.button, }, { Widget: container.NewHScroll(directoryForSavingButton.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 } type directoryForSaving struct { button *widget.Button message *canvas.Text path string } func (f *formConvertor) newDirectoryForSaving(directoryForSavingPath string) *directoryForSaving { directoryForSaving := &directoryForSaving{ path: "", } directoryForSaving.message = canvas.NewText("", color.RGBA{R: 255, G: 0, B: 0, A: 255}) directoryForSaving.message.TextSize = 16 directoryForSaving.message.TextStyle = fyne.TextStyle{Bold: true} buttonTitle := lang.L("choose") locationURI, err := utils.PathToListableURI(directoryForSavingPath) if err == nil { directoryForSaving.path = locationURI.Path() directoryForSaving.message.Text = locationURI.Path() utils.SetStringSuccessStyle(directoryForSaving.message) } directoryForSaving.button = widget.NewButton(buttonTitle, func() { f.window.NewFolderOpen(func(r fyne.ListableURI, err error) { if err != nil { directoryForSaving.message.Text = err.Error() utils.SetStringErrorStyle(directoryForSaving.message) return } if r == nil { return } directoryForSaving.path = r.Path() directoryForSaving.message.Text = r.Path() utils.SetStringSuccessStyle(directoryForSaving.message) locationURI, err = storage.ListerForURI(r) if err == nil { f.directoryForSaving(locationURI.Path()) } }, locationURI) }) return directoryForSaving } 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) } }