Make it possible to drag and drop multiple files
It is now possible to add multiple files before sending them to the processing queue.
This commit is contained in:
254
kernel/progressbar.go
Normal file
254
kernel/progressbar.go
Normal file
@@ -0,0 +1,254 @@
|
||||
package kernel
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"fyne.io/fyne/v2"
|
||||
"fyne.io/fyne/v2/canvas"
|
||||
"fyne.io/fyne/v2/container"
|
||||
"fyne.io/fyne/v2/theme"
|
||||
"fyne.io/fyne/v2/widget"
|
||||
"github.com/nicksnyder/go-i18n/v2/i18n"
|
||||
"image/color"
|
||||
"io"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type BlockProgressbarContract interface {
|
||||
GetContainer() *fyne.Container
|
||||
GetProgressbar(totalDuration float64, filePath string, localizerService LocalizerContract) Progress
|
||||
ProcessEndedWithError(errorText string)
|
||||
ProcessEndedWithSuccess(filePath string)
|
||||
}
|
||||
|
||||
type BlockProgressbar struct {
|
||||
container *fyne.Container
|
||||
label *widget.Label
|
||||
progressbar *widget.ProgressBar
|
||||
errorBlock *container.Scroll
|
||||
messageError *canvas.Text
|
||||
statusMessage *canvas.Text
|
||||
buttonPlay *widget.Button
|
||||
statusesText *BlockProgressbarStatusesText
|
||||
ffplayService FFplayContract
|
||||
}
|
||||
|
||||
func NewBlockProgressbar(statusesText *BlockProgressbarStatusesText, ffplayService FFplayContract) *BlockProgressbar {
|
||||
label := widget.NewLabel("")
|
||||
progressbar := widget.NewProgressBar()
|
||||
|
||||
statusMessage := canvas.NewText("", theme.Color(theme.ColorNamePrimary))
|
||||
messageError := canvas.NewText("", theme.Color(theme.ColorNameError))
|
||||
buttonPlay := widget.NewButtonWithIcon("", theme.Icon(theme.IconNameMediaPlay), func() {
|
||||
|
||||
})
|
||||
buttonPlay.Hide()
|
||||
|
||||
errorBlock := container.NewHScroll(messageError)
|
||||
errorBlock.Hide()
|
||||
|
||||
content := container.NewVBox(
|
||||
container.NewHScroll(label),
|
||||
progressbar,
|
||||
container.NewHScroll(container.NewHBox(
|
||||
buttonPlay,
|
||||
statusMessage,
|
||||
)),
|
||||
errorBlock,
|
||||
)
|
||||
content.Hide()
|
||||
|
||||
return &BlockProgressbar{
|
||||
container: content,
|
||||
label: label,
|
||||
progressbar: progressbar,
|
||||
errorBlock: errorBlock,
|
||||
messageError: messageError,
|
||||
statusMessage: statusMessage,
|
||||
buttonPlay: buttonPlay,
|
||||
statusesText: statusesText,
|
||||
ffplayService: ffplayService,
|
||||
}
|
||||
}
|
||||
|
||||
func (block BlockProgressbar) GetContainer() *fyne.Container {
|
||||
return block.container
|
||||
}
|
||||
|
||||
func (block BlockProgressbar) GetProgressbar(totalDuration float64, filePath string, localizerService LocalizerContract) Progress {
|
||||
block.label.Text = filePath
|
||||
block.statusMessage.Color = theme.Color(theme.ColorNamePrimary)
|
||||
block.statusMessage.Text = block.statusesText.inProgress
|
||||
block.messageError.Text = ""
|
||||
fyne.Do(func() {
|
||||
block.buttonPlay.Hide()
|
||||
if block.errorBlock.Visible() {
|
||||
block.errorBlock.Hide()
|
||||
}
|
||||
block.statusMessage.Refresh()
|
||||
block.container.Refresh()
|
||||
block.errorBlock.Refresh()
|
||||
})
|
||||
|
||||
block.progressbar.Value = 0
|
||||
return NewProgress(totalDuration, block.progressbar, localizerService)
|
||||
}
|
||||
|
||||
func (block BlockProgressbar) ProcessEndedWithError(errorText string) {
|
||||
fyne.Do(func() {
|
||||
block.statusMessage.Color = theme.Color(theme.ColorNameError)
|
||||
block.statusMessage.Text = block.statusesText.error
|
||||
block.messageError.Text = errorText
|
||||
block.errorBlock.Show()
|
||||
})
|
||||
}
|
||||
|
||||
func (block BlockProgressbar) ProcessEndedWithSuccess(filePath string) {
|
||||
fyne.Do(func() {
|
||||
block.statusMessage.Color = color.RGBA{R: 49, G: 127, B: 114, A: 255}
|
||||
block.statusMessage.Text = block.statusesText.completed
|
||||
block.buttonPlay.Show()
|
||||
block.buttonPlay.OnTapped = func() {
|
||||
block.buttonPlay.Disable()
|
||||
go func() {
|
||||
_ = block.ffplayService.Run(FFplaySetting{
|
||||
PathToFile: filePath,
|
||||
})
|
||||
fyne.Do(func() {
|
||||
block.buttonPlay.Enable()
|
||||
})
|
||||
}()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
type Progress struct {
|
||||
totalDuration float64
|
||||
progressbar *widget.ProgressBar
|
||||
protocol string
|
||||
localizerService LocalizerContract
|
||||
}
|
||||
|
||||
func NewProgress(totalDuration float64, progressbar *widget.ProgressBar, localizerService LocalizerContract) Progress {
|
||||
return Progress{
|
||||
totalDuration: totalDuration,
|
||||
progressbar: progressbar,
|
||||
protocol: "pipe:",
|
||||
localizerService: localizerService,
|
||||
}
|
||||
}
|
||||
|
||||
func (p Progress) GetProtocole() string {
|
||||
return p.protocol
|
||||
}
|
||||
|
||||
func (p Progress) Run(stdOut io.ReadCloser, stdErr io.ReadCloser) error {
|
||||
isProcessCompleted := false
|
||||
var errorText string
|
||||
|
||||
p.progressbar.Value = 0
|
||||
p.progressbar.Max = p.totalDuration
|
||||
fyne.Do(func() {
|
||||
p.progressbar.Refresh()
|
||||
})
|
||||
progress := 0.0
|
||||
|
||||
go func() {
|
||||
scannerErr := bufio.NewReader(stdErr)
|
||||
for {
|
||||
line, _, err := scannerErr.ReadLine()
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
continue
|
||||
}
|
||||
data := strings.TrimSpace(string(line))
|
||||
errorText = data
|
||||
}
|
||||
}()
|
||||
|
||||
scannerOut := bufio.NewReader(stdOut)
|
||||
for {
|
||||
line, _, err := scannerOut.ReadLine()
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
continue
|
||||
}
|
||||
data := strings.TrimSpace(string(line))
|
||||
if strings.Contains(data, "progress=end") {
|
||||
p.progressbar.Value = p.totalDuration
|
||||
fyne.Do(func() {
|
||||
p.progressbar.Refresh()
|
||||
})
|
||||
isProcessCompleted = true
|
||||
break
|
||||
}
|
||||
|
||||
re := regexp.MustCompile(`frame=(\d+)`)
|
||||
a := re.FindAllStringSubmatch(data, -1)
|
||||
|
||||
if len(a) > 0 && len(a[len(a)-1]) > 0 {
|
||||
c, err := strconv.Atoi(a[len(a)-1][len(a[len(a)-1])-1])
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
progress = float64(c)
|
||||
}
|
||||
if p.progressbar.Value != progress {
|
||||
p.progressbar.Value = progress
|
||||
fyne.Do(func() {
|
||||
p.progressbar.Refresh()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if isProcessCompleted == false {
|
||||
if len(errorText) == 0 {
|
||||
errorText = p.localizerService.GetMessage(&i18n.LocalizeConfig{
|
||||
MessageID: "errorConverter",
|
||||
})
|
||||
}
|
||||
return errors.New(errorText)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type BlockProgressbarStatusesText struct {
|
||||
inProgress string
|
||||
completed string
|
||||
error string
|
||||
}
|
||||
|
||||
func GetBlockProgressbarStatusesText(localizerService LocalizerContract) *BlockProgressbarStatusesText {
|
||||
statusesText := &BlockProgressbarStatusesText{
|
||||
inProgress: localizerService.GetMessage(&i18n.LocalizeConfig{
|
||||
MessageID: "inProgressQueue",
|
||||
}),
|
||||
completed: localizerService.GetMessage(&i18n.LocalizeConfig{
|
||||
MessageID: "completedQueue",
|
||||
}),
|
||||
error: localizerService.GetMessage(&i18n.LocalizeConfig{
|
||||
MessageID: "errorQueue",
|
||||
}),
|
||||
}
|
||||
|
||||
localizerService.AddChangeCallback("inProgressQueue", func(text string) {
|
||||
statusesText.inProgress = text
|
||||
})
|
||||
|
||||
localizerService.AddChangeCallback("completedQueue", func(text string) {
|
||||
statusesText.completed = text
|
||||
})
|
||||
|
||||
localizerService.AddChangeCallback("errorQueue", func(text string) {
|
||||
statusesText.error = text
|
||||
})
|
||||
|
||||
return statusesText
|
||||
}
|
||||
Reference in New Issue
Block a user