package view import ( "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/application/convertor/encoder" "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg" encoder2 "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/ffmpeg/encoder" "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/gui/view/convertor/encoders" "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/gui/window" "git.kor-elf.net/kor-elf/gui-for-ffmpeg/internal/utils" "image/color" "os" "path/filepath" ) func Convertor( window window.WindowContract, addFileForConversion func(file ffmpeg.File), directoryForSavingPath string, directoryForSaving func(path string), formats encoder.ConvertorFormatsContract, ) fyne.CanvasObject { form := newFormConvertor( window, addFileForConversion, directoryForSavingPath, directoryForSaving, formats, ) 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), formats encoder.ConvertorFormatsContract, ) *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) isOverwriteOutputFiles := false checkboxOverwriteOutputFiles := widget.NewCheck(lang.L("checkboxOverwriteOutputFilesTitle"), func(b bool) { isOverwriteOutputFiles = b }) checkboxOverwriteOutputFiles.SetChecked(isOverwriteOutputFiles) selectEncoder := formConvertor.newSelectEncoder(formats) 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), }, { Widget: checkboxOverwriteOutputFiles, }, { Widget: selectEncoder.SelectFileType, }, { Text: lang.L("selectFormat"), Widget: selectEncoder.SelectFormat, }, { Text: lang.L("selectEncoder"), Widget: selectEncoder.SelectEncoder, }, } formConvertor.form.Items = items formConvertor.items = items formConvertor.changeEncoder(selectEncoder.Encoder) return formConvertor } func (f *formConvertor) getForm() *widget.Form { return f.form } type fileForConversion struct { button *widget.Button message *canvas.Text file *ffmpeg.File } func (f *formConvertor) newFileForConversion() *fileForConversion { message := canvas.NewText("", color.RGBA{R: 255, G: 0, B: 0, A: 255}) fileForConversion := &fileForConversion{ message: message, } 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() }) return } if r == nil { return } f.addFileForConversion(ffmpeg.File{ Path: r.URI().Path(), Name: r.URI().Name(), Ext: r.URI().Extension(), }) 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(), }) listableURI := storage.NewFileURI(filepath.Dir(uri.Path())) locationURI, _ = storage.ListerForURI(listableURI) } if isError { fileForConversion.message.Text = lang.L("errorDragAndDropFile") utils.SetStringErrorStyle(fileForConversion.message) } 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 } type selectEncoder struct { SelectFileType *widget.RadioGroup SelectFormat *widget.Select SelectEncoder *widget.Select Encoder encoder2.EncoderContract } func (f *formConvertor) newSelectEncoder(formats encoder.ConvertorFormatsContract) *selectEncoder { selectEncoder := &selectEncoder{} encoderMap := map[int]encoder2.EncoderDataContract{} selectEncoder.SelectEncoder = widget.NewSelect([]string{}, func(s string) { if encoderMap[selectEncoder.SelectEncoder.SelectedIndex()] == nil { return } selectEncoderData := encoderMap[selectEncoder.SelectEncoder.SelectedIndex()] selectEncoder.Encoder = selectEncoderData.NewEncoder() f.changeEncoder(selectEncoder.Encoder) }) formatSelected := "" selectEncoder.SelectFormat = widget.NewSelect([]string{}, func(s string) { if formatSelected == s { return } formatSelected = s format, err := formats.GetFormat(s) if err != nil { return } var encoderOptions []string encoderMap = map[int]encoder2.EncoderDataContract{} for _, e := range format.GetEncoders() { encoderMap[len(encoderMap)] = e encoderOptions = append(encoderOptions, lang.L("encoder_"+e.GetTitle())) } selectEncoder.SelectEncoder.SetOptions(encoderOptions) selectEncoder.SelectEncoder.SetSelectedIndex(0) }) var fileTypeOptions []string for _, fileType := range encoder2.GetListFileType() { fileTypeOptions = append(fileTypeOptions, fileType.Name()) } encoderGroupVideo := lang.L("encoderGroupVideo") encoderGroupAudio := lang.L("encoderGroupAudio") encoderGroupImage := lang.L("encoderGroupImage") encoderGroup := map[string]string{ encoderGroupVideo: "video", encoderGroupAudio: "audio", encoderGroupImage: "image", } selectEncoder.SelectFileType = widget.NewRadioGroup([]string{encoderGroupVideo, encoderGroupAudio, encoderGroupImage}, func(s string) { groupCode := encoderGroup[s] var formatOptions []string for _, f := range formats.GetFormats() { if groupCode != f.GetFileType().Name() { continue } formatOptions = append(formatOptions, f.GetTitle()) } selectEncoder.SelectFormat.SetOptions(formatOptions) if groupCode == encoder2.FileType(encoder2.Video).Name() { selectEncoder.SelectFormat.SetSelected("mp4") } else { selectEncoder.SelectFormat.SetSelectedIndex(0) } }) selectEncoder.SelectFileType.Horizontal = true selectEncoder.SelectFileType.Required = true selectEncoder.SelectFileType.SetSelected(encoderGroupVideo) return selectEncoder } func (f *formConvertor) changeEncoder(encoder encoder2.EncoderContract) { var items []*widget.FormItem if encoders.Views[encoder.GetName()] != nil { items = encoders.Views[encoder.GetName()](encoder) } f.changeItems(items) } func (f *formConvertor) changeItems(items []*widget.FormItem) { fyne.Do(func() { f.form.Items = f.items f.form.Refresh() f.form.Items = append(f.form.Items, items...) f.form.Refresh() }) }