From e766c6d465bbe7d15b0fd96a5447c536fa2b0a40 Mon Sep 17 00:00:00 2001 From: Leonid Nikitin Date: Tue, 5 Mar 2024 00:58:43 +0500 Subject: [PATCH] Added the ability to show and hide elements by status type. --- kernel/layout.go | 311 ++++++++++++++++++++++++++++++++++-- kernel/queue.go | 8 +- languages/active.en.toml | 14 +- languages/active.kk.toml | 14 +- languages/active.ru.toml | 8 +- languages/translate.en.toml | 14 +- languages/translate.kk.toml | 14 +- 7 files changed, 341 insertions(+), 42 deletions(-) diff --git a/kernel/layout.go b/kernel/layout.go index 4b740d4..a917312 100644 --- a/kernel/layout.go +++ b/kernel/layout.go @@ -66,6 +66,7 @@ type QueueLayoutObject struct { items map[int]QueueLayoutItem localizerService LocalizerContract layoutLocalizerListener LayoutLocalizerListenerContract + queueStatisticsFormat *queueStatisticsFormat } type QueueLayoutItem struct { @@ -73,20 +74,32 @@ type QueueLayoutItem struct { ProgressBar *widget.ProgressBar StatusMessage *canvas.Text MessageError *canvas.Text + + status *StatusContract } func NewQueueLayoutObject(queue QueueListContract, localizerService LocalizerContract, layoutLocalizerListener LayoutLocalizerListenerContract) *QueueLayoutObject { - title := widget.NewLabel(localizerService.GetMessage(&i18n.LocalizeConfig{MessageID: "queue"}) + ":") + title := widget.NewLabel(localizerService.GetMessage(&i18n.LocalizeConfig{MessageID: "queue"})) title.TextStyle.Bold = true - layoutLocalizerListener.AddItem("queue", title) + layoutLocalizerListener.AddItem("queue", func(text string) { + title.Text = text + title.Refresh() + }) + + items := map[int]QueueLayoutItem{} + queueStatisticsFormat := newQueueStatisticsFormat(localizerService, layoutLocalizerListener, &items) queueLayoutObject := &QueueLayoutObject{ - queue: queue, - container: container.NewVBox(title), - items: map[int]QueueLayoutItem{}, + queue: queue, + container: container.NewVBox( + container.NewHBox(title, queueStatisticsFormat.completed.widget, queueStatisticsFormat.error.widget), + container.NewHBox(queueStatisticsFormat.inProgress.widget, queueStatisticsFormat.waiting.widget, queueStatisticsFormat.total.widget), + ), + items: items, localizerService: localizerService, layoutLocalizerListener: layoutLocalizerListener, + queueStatisticsFormat: queueStatisticsFormat, } queue.AddListener(queueLayoutObject) @@ -118,11 +131,18 @@ func (o QueueLayoutObject) Add(id int, queue *Queue) { canvas.NewLine(theme.FocusColor()), container.NewPadded(), ) + + o.queueStatisticsFormat.addQueue() + if o.queueStatisticsFormat.isChecked(queue.Status) == false { + content.Hide() + } + o.items[id] = QueueLayoutItem{ CanvasObject: content, ProgressBar: progressBar, StatusMessage: statusMessage, MessageError: messageError, + status: &queue.Status, } o.container.Add(content) } @@ -130,6 +150,7 @@ func (o QueueLayoutObject) Add(id int, queue *Queue) { func (o QueueLayoutObject) Remove(id int) { if item, ok := o.items[id]; ok { o.container.Remove(item.CanvasObject) + o.queueStatisticsFormat.removeQueue(*item.status) o.items[id] = QueueLayoutItem{} } } @@ -145,6 +166,12 @@ func (o QueueLayoutObject) ChangeQueueStatus(queueId int, queue *Queue) { item.MessageError.Color = statusColor item.MessageError.Refresh() } + if o.queueStatisticsFormat.isChecked(queue.Status) == false && item.CanvasObject.Visible() == true { + item.CanvasObject.Hide() + } else if item.CanvasObject.Visible() == false { + item.CanvasObject.Show() + } + o.queueStatisticsFormat.changeQueue(queue.Status) } } @@ -161,7 +188,7 @@ func (o QueueLayoutObject) getStatusColor(status StatusContract) color.Color { } func (o QueueLayoutObject) getStatusTitle(status StatusContract) string { - return o.localizerService.GetMessage(&i18n.LocalizeConfig{MessageID: status.name()}) + return o.localizerService.GetMessage(&i18n.LocalizeConfig{MessageID: status.Name() + "Queue"}) } type Progress struct { @@ -256,33 +283,287 @@ func (p Progress) Run(stdOut io.ReadCloser, stdErr io.ReadCloser) error { type LayoutLocalizerItem struct { messageID string - object *widget.Label + callback func(text string) } type LayoutLocalizerListener struct { - itemCurrentId int + itemCurrentId *int items map[int]*LayoutLocalizerItem } type LayoutLocalizerListenerContract interface { - AddItem(messageID string, object *widget.Label) + AddItem(messageID string, callback func(text string)) } func NewLayoutLocalizerListener() *LayoutLocalizerListener { + id := 0 return &LayoutLocalizerListener{ - itemCurrentId: 0, + itemCurrentId: &id, items: map[int]*LayoutLocalizerItem{}, } } -func (l LayoutLocalizerListener) AddItem(messageID string, object *widget.Label) { - l.itemCurrentId += 1 - l.items[l.itemCurrentId] = &LayoutLocalizerItem{messageID: messageID, object: object} +func (l LayoutLocalizerListener) AddItem(messageID string, callback func(text string)) { + *l.itemCurrentId += 1 + l.items[*l.itemCurrentId] = &LayoutLocalizerItem{messageID: messageID, callback: callback} } func (l LayoutLocalizerListener) Change(localizerService LocalizerContract) { for _, item := range l.items { - item.object.Text = localizerService.GetMessage(&i18n.LocalizeConfig{MessageID: item.messageID}) - item.object.Refresh() + item.callback(localizerService.GetMessage(&i18n.LocalizeConfig{MessageID: item.messageID})) + } +} + +type queueStatistics struct { + widget *widget.Check + title string + count *int64 +} +type queueStatisticsFormat struct { + waiting *queueStatistics + inProgress *queueStatistics + completed *queueStatistics + error *queueStatistics + total *queueStatistics +} + +func newQueueStatisticsFormat(localizerService LocalizerContract, layoutLocalizerListener LayoutLocalizerListenerContract, queueItems *map[int]QueueLayoutItem) *queueStatisticsFormat { + checkWaiting := newQueueStatistics("waitingQueue", localizerService, layoutLocalizerListener) + checkInProgress := newQueueStatistics("inProgressQueue", localizerService, layoutLocalizerListener) + checkCompleted := newQueueStatistics("completedQueue", localizerService, layoutLocalizerListener) + checkError := newQueueStatistics("errorQueue", localizerService, layoutLocalizerListener) + checkTotal := newQueueStatistics("total", localizerService, layoutLocalizerListener) + + queueStatisticsFormat := &queueStatisticsFormat{ + waiting: checkWaiting, + inProgress: checkInProgress, + completed: checkCompleted, + error: checkError, + total: checkTotal, + } + + checkTotal.widget.OnChanged = func(b bool) { + if b == true { + queueStatisticsFormat.allCheckboxChecked() + } else { + queueStatisticsFormat.allUnCheckboxChecked() + } + queueStatisticsFormat.redrawingQueueItems(queueItems) + } + + queueStatisticsFormat.waiting.widget.OnChanged = func(b bool) { + if b == true { + queueStatisticsFormat.checkboxChecked() + } else { + queueStatisticsFormat.unCheckboxChecked() + } + queueStatisticsFormat.redrawingQueueItems(queueItems) + } + + queueStatisticsFormat.inProgress.widget.OnChanged = func(b bool) { + if b == true { + queueStatisticsFormat.checkboxChecked() + } else { + queueStatisticsFormat.unCheckboxChecked() + } + queueStatisticsFormat.redrawingQueueItems(queueItems) + } + + queueStatisticsFormat.completed.widget.OnChanged = func(b bool) { + if b == true { + queueStatisticsFormat.checkboxChecked() + } else { + queueStatisticsFormat.unCheckboxChecked() + } + queueStatisticsFormat.redrawingQueueItems(queueItems) + } + + queueStatisticsFormat.error.widget.OnChanged = func(b bool) { + if b == true { + queueStatisticsFormat.checkboxChecked() + } else { + queueStatisticsFormat.unCheckboxChecked() + } + queueStatisticsFormat.redrawingQueueItems(queueItems) + } + + return queueStatisticsFormat +} + +func (f queueStatisticsFormat) redrawingQueueItems(queueItems *map[int]QueueLayoutItem) { + for _, item := range *queueItems { + if f.isChecked(*item.status) == true && item.CanvasObject.Visible() == false { + item.CanvasObject.Show() + continue + } + if f.isChecked(*item.status) == false && item.CanvasObject.Visible() == true { + item.CanvasObject.Hide() + } + } +} + +func (f queueStatisticsFormat) isChecked(status StatusContract) bool { + if status == StatusType(InProgress) { + return f.inProgress.widget.Checked + } + if status == StatusType(Completed) { + return f.completed.widget.Checked + } + if status == StatusType(Error) { + return f.error.widget.Checked + } + if status == StatusType(Waiting) { + return f.waiting.widget.Checked + } + + return true +} + +func (f queueStatisticsFormat) addQueue() { + f.waiting.add() + f.total.add() +} + +func (f queueStatisticsFormat) changeQueue(status StatusContract) { + if status == StatusType(InProgress) { + f.waiting.remove() + f.inProgress.add() + return + } + + if status == StatusType(Completed) { + f.inProgress.remove() + f.completed.add() + return + } + + if status == StatusType(Error) { + f.inProgress.remove() + f.error.add() + return + } +} + +func (f queueStatisticsFormat) removeQueue(status StatusContract) { + f.total.remove() + + if status == StatusType(Completed) { + f.completed.remove() + return + } + + if status == StatusType(Error) { + f.error.remove() + return + } + + if status == StatusType(InProgress) { + f.inProgress.remove() + return + } + + if status == StatusType(Waiting) { + f.waiting.remove() + return + } +} + +func (f queueStatisticsFormat) checkboxChecked() { + if f.total.widget.Checked == true { + return + } + + if f.waiting.widget.Checked == false { + return + } + + if f.inProgress.widget.Checked == false { + return + } + + if f.completed.widget.Checked == false { + return + } + + if f.error.widget.Checked == false { + return + } + + f.total.widget.Checked = true + f.total.widget.Refresh() +} + +func (f queueStatisticsFormat) unCheckboxChecked() { + if f.total.widget.Checked == false { + return + } + + f.total.widget.Checked = false + f.total.widget.Refresh() +} + +func (f queueStatisticsFormat) allCheckboxChecked() { + f.waiting.widget.Checked = true + f.waiting.widget.Refresh() + f.inProgress.widget.Checked = true + f.inProgress.widget.Refresh() + f.completed.widget.Checked = true + f.completed.widget.Refresh() + f.error.widget.Checked = true + f.error.widget.Refresh() +} + +func (f queueStatisticsFormat) allUnCheckboxChecked() { + f.waiting.widget.Checked = false + f.waiting.widget.Refresh() + f.inProgress.widget.Checked = false + f.inProgress.widget.Refresh() + f.completed.widget.Checked = false + f.completed.widget.Refresh() + f.error.widget.Checked = false + f.error.widget.Refresh() +} + +func newQueueStatistics(messaigeID string, localizerService LocalizerContract, layoutLocalizerListener LayoutLocalizerListenerContract) *queueStatistics { + checkbox := widget.NewCheck("", nil) + checkbox.Checked = true + + count := int64(0) + + title := localizerService.GetMessage(&i18n.LocalizeConfig{MessageID: messaigeID}) + queueStatistics := &queueStatistics{ + widget: checkbox, + title: strings.ToLower(title), + count: &count, + } + + queueStatistics.formatText(false) + + layoutLocalizerListener.AddItem(messaigeID, func(text string) { + queueStatistics.title = strings.ToLower(text) + queueStatistics.formatText(true) + queueStatistics.widget.Refresh() + }) + + return queueStatistics +} + +func (s queueStatistics) add() { + *s.count += 1 + s.formatText(true) +} + +func (s queueStatistics) remove() { + if *s.count == 0 { + return + } + *s.count -= 1 + s.formatText(true) +} + +func (s queueStatistics) formatText(refresh bool) { + s.widget.Text = s.title + ": " + strconv.FormatInt(*s.count, 10) + if refresh == true { + s.widget.Refresh() } } diff --git a/kernel/queue.go b/kernel/queue.go index 112ce42..6d2f6c4 100644 --- a/kernel/queue.go +++ b/kernel/queue.go @@ -11,8 +11,8 @@ type Queue struct { } type StatusContract interface { - name() string - ordinal() int + Name() string + Ordinal() int } const ( @@ -31,11 +31,11 @@ var statusTypeStrings = []string{ "error", } -func (status StatusType) name() string { +func (status StatusType) Name() string { return statusTypeStrings[status] } -func (status StatusType) ordinal() int { +func (status StatusType) Ordinal() int { return int(status) } diff --git a/languages/active.en.toml b/languages/active.en.toml index 499b140..357f1c0 100644 --- a/languages/active.en.toml +++ b/languages/active.en.toml @@ -38,7 +38,7 @@ other = "Allow file to be overwritten" hash = "sha1-f60bb5f761024d973834b5e9d25ceebce2c85f94" other = "choose" -[completed] +[completedQueue] hash = "sha1-398c7d4f7b0d522afb930769c0fbb1a9f4b61fbe" other = "Completed" @@ -90,6 +90,10 @@ other = "this is not FFprobe" hash = "sha1-da7b37d7df3fafbd153665b13888413d52b24c17" other = "Failed to determine FFprobe version" +[errorQueue] +hash = "sha1-72aecd9ad85642d84d62dbbf3cf70953c5f696c7" +other = "Error" + [errorSelectedFolderSave] hash = "sha1-83da899677cdc90e4344e3b94ee03c46b51bee4c" other = "You haven't selected a folder to save!" @@ -114,7 +118,7 @@ other = "File for conversion:" hash = "sha1-6a45cef900c668effcb2ab10da05855c1fd10f6f" other = "Help" -[inProgress] +[inProgressQueue] hash = "sha1-eff79c40e2100ae5fadf3a7d99336025edcca8b5" other = "In Progress" @@ -174,10 +178,14 @@ other = "Checking FFmpeg for serviceability..." hash = "sha1-92df86371f6c3a06ca1e4754f113142776a32d49" other = "You can download it from here" +[total] +hash = "sha1-3b5143902e0c5c84459aedf918e17604d9735b94" +other = "Total" + [unzipRun] hash = "sha1-c554dad13026668a1f6adf3171837c5d51bbac36" other = "Unpacked..." -[waiting] +[waitingQueue] hash = "sha1-307429dd84150877080c4bbff2b340d1e7dadff2" other = "Waiting" diff --git a/languages/active.kk.toml b/languages/active.kk.toml index d443d8a..0b2e21b 100644 --- a/languages/active.kk.toml +++ b/languages/active.kk.toml @@ -38,7 +38,7 @@ other = "Файлды қайта жазуға рұқсат беріңіз" hash = "sha1-f60bb5f761024d973834b5e9d25ceebce2c85f94" other = "таңдау" -[completed] +[completedQueue] hash = "sha1-398c7d4f7b0d522afb930769c0fbb1a9f4b61fbe" other = "Дайын" @@ -90,6 +90,10 @@ other = "бұл FFprobe емес" hash = "sha1-da7b37d7df3fafbd153665b13888413d52b24c17" other = "FFprobe нұсқасын анықтау мүмкін болмады" +[errorQueue] +hash = "sha1-72aecd9ad85642d84d62dbbf3cf70953c5f696c7" +other = "Қате" + [errorSelectedFolderSave] hash = "sha1-83da899677cdc90e4344e3b94ee03c46b51bee4c" other = "Сіз сақталатын қалтаны таңдамадыңыз!" @@ -114,7 +118,7 @@ other = "Түрлендіруге арналған файл:" hash = "sha1-6a45cef900c668effcb2ab10da05855c1fd10f6f" other = "Анықтама" -[inProgress] +[inProgressQueue] hash = "sha1-eff79c40e2100ae5fadf3a7d99336025edcca8b5" other = "Орындалуда" @@ -174,10 +178,14 @@ other = "FFmpeg функционалдығы тексерілуде..." hash = "sha1-92df86371f6c3a06ca1e4754f113142776a32d49" other = "Сіз оны осы жерден жүктей аласыз" +[total] +hash = "sha1-3b5143902e0c5c84459aedf918e17604d9735b94" +other = "Барлығы" + [unzipRun] hash = "sha1-c554dad13026668a1f6adf3171837c5d51bbac36" other = "Орамнан шығарылуда..." -[waiting] +[waitingQueue] hash = "sha1-307429dd84150877080c4bbff2b340d1e7dadff2" other = "Күту" diff --git a/languages/active.ru.toml b/languages/active.ru.toml index b163e1b..6053ac2 100644 --- a/languages/active.ru.toml +++ b/languages/active.ru.toml @@ -8,7 +8,7 @@ changeFFPath = "FFmpeg и FFprobe" changeLanguage = "Поменять язык" checkboxOverwriteOutputFilesTitle = "Разрешить перезаписать файл" choose = "выбрать" -completed = "Готово" +completedQueue = "Готово" converterVideoFilesSubmitTitle = "Конвертировать" converterVideoFilesTitle = "Конвертор видео файлов в mp4" download = "Скачать" @@ -21,13 +21,14 @@ errorFFmpeg = "это не FFmpeg" errorFFmpegVersion = "Не смогли определить версию FFmpeg" errorFFprobe = "это не FFprobe" errorFFprobeVersion = "Не смогли определить версию FFprobe" +errorQueue = "Ошибка" errorSelectedFolderSave = "Не выбрали папку для сохранения!" exit = "Выход" ffmpegLGPL = "Это программное обеспечение использует библиотеки из проекта **FFmpeg** под **[LGPLv2.1](http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html)**." ffmpegTrademark = "**FFmpeg** — торговая марка **[Fabrice Bellard](http://bellard.org/)** , создателя проекта **[FFmpeg](https://ffmpeg.org/about.html)**." fileVideoForConversionTitle = "Файл для ковертации:" help = "Справка" -inProgress = "Выполняется" +inProgressQueue = "Выполняется" languageSelectionFormHead = "Переключить язык" languageSelectionHead = "Выберите язык" licenseLink = "Сведения о лицензии" @@ -42,5 +43,6 @@ selectFFPathTitle = "Укажите путь к FFmpeg и к FFprobe" settings = "Настройки" testFF = "Проверка FFmpeg на работоспособность..." titleDownloadLink = "Скачать можно от сюда" +total = "Всего" unzipRun = "Распаковывается..." -waiting = "В очереди" +waitingQueue = "В очереди" diff --git a/languages/translate.en.toml b/languages/translate.en.toml index acb16ac..5d5b71c 100644 --- a/languages/translate.en.toml +++ b/languages/translate.en.toml @@ -1,15 +1,15 @@ -[completed] +[completedQueue] hash = "sha1-398c7d4f7b0d522afb930769c0fbb1a9f4b61fbe" other = "Completed" -[inProgress] +[errorQueue] +hash = "sha1-72aecd9ad85642d84d62dbbf3cf70953c5f696c7" +other = "Error" + +[inProgressQueue] hash = "sha1-eff79c40e2100ae5fadf3a7d99336025edcca8b5" other = "In Progress" -[queue] -hash = "sha1-aec93b16baeaf55fed871075c9494a460e4a91b8" -other = "Queue" - -[waiting] +[waitingQueue] hash = "sha1-307429dd84150877080c4bbff2b340d1e7dadff2" other = "Waiting" diff --git a/languages/translate.kk.toml b/languages/translate.kk.toml index 93b8581..24640fa 100644 --- a/languages/translate.kk.toml +++ b/languages/translate.kk.toml @@ -1,15 +1,15 @@ -[completed] +[completedQueue] hash = "sha1-398c7d4f7b0d522afb930769c0fbb1a9f4b61fbe" other = "Дайын" -[inProgress] +[errorQueue] +hash = "sha1-72aecd9ad85642d84d62dbbf3cf70953c5f696c7" +other = "Қате" + +[inProgressQueue] hash = "sha1-eff79c40e2100ae5fadf3a7d99336025edcca8b5" other = "Орындалуда" -[queue] -hash = "sha1-aec93b16baeaf55fed871075c9494a460e4a91b8" -other = "Кезек" - -[waiting] +[waitingQueue] hash = "sha1-307429dd84150877080c4bbff2b340d1e7dadff2" other = "Күту"