diff --git a/Code/Main/Interpolate.cs b/Code/Main/Interpolate.cs index 9c767c7..2b5af96 100644 --- a/Code/Main/Interpolate.cs +++ b/Code/Main/Interpolate.cs @@ -247,7 +247,7 @@ namespace Flowframes Logger.LogIfLastLineDoesNotContainMsg("Canceled interpolation."); if (!string.IsNullOrWhiteSpace(reason) && !noMsgBox) - Utils.ShowMessage($"Canceled:\n\n{reason}"); + UiUtils.ShowMessageBox($"Canceled:\n\n{reason}"); } public static async Task Cleanup(bool ignoreKeepSetting = false, int retriesLeft = 3, bool isRetry = false) diff --git a/Code/Main/InterpolateSteps.cs b/Code/Main/InterpolateSteps.cs index 1f1d9e7..7aa559d 100644 --- a/Code/Main/InterpolateSteps.cs +++ b/Code/Main/InterpolateSteps.cs @@ -5,6 +5,7 @@ using System.IO; using System.Threading.Tasks; using Flowframes.MiscUtils; using System.Windows.Forms; +using Flowframes.Ui; namespace Flowframes.Main { @@ -57,7 +58,7 @@ namespace Flowframes.Main { if (!(await IoUtils.TryDeleteIfExistsAsync(current.framesFolder))) { - InterpolateUtils.ShowMessage("Failed to delete existing frames folder - Make sure no file is opened in another program!", "Error"); + UiUtils.ShowMessageBox("Failed to delete existing frames folder - Make sure no file is opened in another program!", UiUtils.MessageType.Error); return; } @@ -83,14 +84,14 @@ namespace Flowframes.Main if (IoUtils.GetAmountOfFiles(current.framesFolder, false, "*") < 2) { - InterpolateUtils.ShowMessage("There are no extracted frames that can be interpolated!\nDid you run the extraction step?", "Error"); + UiUtils.ShowMessageBox("There are no extracted frames that can be interpolated!\nDid you run the extraction step?", UiUtils.MessageType.Error); return; } } if (!(await IoUtils.TryDeleteIfExistsAsync(current.interpFolder))) { - InterpolateUtils.ShowMessage("Failed to delete existing frames folder - Make sure no file is opened in another program!", "Error"); + UiUtils.ShowMessageBox("Failed to delete existing frames folder - Make sure no file is opened in another program!", UiUtils.MessageType.Error); return; } @@ -128,8 +129,8 @@ namespace Flowframes.Main if (outFrames.Length > 0 && !IoUtils.CheckImageValid(outFrames[0])) { - InterpolateUtils.ShowMessage("Invalid frame files detected!\n\nIf you used Auto-Encode, this is normal, and you don't need to run " + - "this step as the video was already created in the \"Interpolate\" step.", "Error"); + UiUtils.ShowMessageBox("Invalid frame files detected!\n\nIf you used Auto-Encode, this is normal, and you don't need to run " + + "this step as the video was already created in the \"Interpolate\" step.", UiUtils.MessageType.Error); return; } diff --git a/Code/Main/InterpolateUtils.cs b/Code/Main/InterpolateUtils.cs index 17a82eb..3958c96 100644 --- a/Code/Main/InterpolateUtils.cs +++ b/Code/Main/InterpolateUtils.cs @@ -104,20 +104,20 @@ namespace Flowframes.Main if ((passes && isFile && !IoUtils.IsFileValid(inDir)) || (!isFile && !IoUtils.IsDirValid(inDir))) { - ShowMessage("Input path is not valid!"); + UiUtils.ShowMessageBox("Input path is not valid!"); passes = false; } if (passes && !IoUtils.IsDirValid(outDir)) { - ShowMessage("Output path is not valid!"); + UiUtils.ShowMessageBox("Output path is not valid!"); passes = false; } if (passes && fpsOut < 1f || fpsOut > 1000f) { string imgSeqNote = isFile ? "" : "\n\nWhen using an image sequence as input, you always have to specify the frame rate manually."; - ShowMessage($"Invalid output frame rate ({fpsOut}).\nMust be 1-1000.{imgSeqNote}"); + UiUtils.ShowMessageBox($"Invalid output frame rate ({fpsOut}).\nMust be 1-1000.{imgSeqNote}"); passes = false; } @@ -143,22 +143,22 @@ namespace Flowframes.Main { if (IoUtils.GetAmountOfFiles(Path.Combine(Paths.GetPkgPath(), ai.pkgDir), true) < 1) { - ShowMessage("The selected AI is not installed!", "Error"); + UiUtils.ShowMessageBox("The selected AI is not installed!", UiUtils.MessageType.Error); I.Cancel("Selected AI not available.", true); return false; } if (model == null || model.dir.Trim() == "") { - ShowMessage("No valid AI model has been selected!", "Error"); + UiUtils.ShowMessageBox("No valid AI model has been selected!", UiUtils.MessageType.Error); I.Cancel("No valid model selected.", true); return false; } if (I.current.ai.aiName.ToUpper().Contains("CUDA") && NvApi.gpuList.Count < 1) { - ShowMessage("Warning: No Nvidia GPU was detected. CUDA might fall back to CPU!\n\nTry an NCNN implementation instead if you don't have an Nvidia GPU.", "Error"); - + UiUtils.ShowMessageBox("Warning: No Nvidia GPU was detected. CUDA might fall back to CPU!\n\nTry an NCNN implementation instead if you don't have an Nvidia GPU.", UiUtils.MessageType.Error); + if (!Config.GetBool("allowCudaWithoutDetectedGpu", true)) { I.Cancel("No CUDA-capable graphics card available.", true); @@ -173,7 +173,7 @@ namespace Flowframes.Main { if (!IoUtils.TryDeleteIfExists(I.current.tempFolder)) { - ShowMessage("Failed to remove an existing temp folder of this video!\nMake sure you didn't open any frames in an editor.", "Error"); + UiUtils.ShowMessageBox("Failed to remove an existing temp folder of this video!\nMake sure you didn't open any frames in an editor.", UiUtils.MessageType.Error); I.Cancel(); return false; } @@ -192,7 +192,7 @@ namespace Flowframes.Main { if (!IoUtils.IsDirValid(path)) { - ShowMessage("Input directory is not valid.\nMake sure it still exists and hasn't been renamed or moved!"); + UiUtils.ShowMessageBox("Input directory is not valid.\nMake sure it still exists and hasn't been renamed or moved!"); I.Cancel(); return false; } @@ -201,7 +201,7 @@ namespace Flowframes.Main { if (!IsVideoValid(path)) { - ShowMessage("Input video file is not valid.\nMake sure it still exists and hasn't been renamed or moved!"); + UiUtils.ShowMessageBox("Input video file is not valid.\nMake sure it still exists and hasn't been renamed or moved!"); return false; } } @@ -217,7 +217,7 @@ namespace Flowframes.Main if (!(await FfmpegCommands.IsEncoderCompatible(enc))) { - ShowMessage("NVENC encoding is not available on your hardware!\nPlease use a different encoder.", "Error"); + UiUtils.ShowMessageBox("NVENC encoding is not available on your hardware!\nPlease use a different encoder.", UiUtils.MessageType.Error); I.Cancel(); return false; } @@ -232,14 +232,6 @@ namespace Flowframes.Main return true; } - public static void ShowMessage(string msg, string title = "Message") - { - if (!BatchProcessing.busy) - MessageBox.Show(msg, title); - - Logger.Log("Message: " + msg, true); - } - public static async Task GetOutputResolution(string inputPath, bool print, bool returnZeroIfUnchanged = false) { Size resolution = await GetMediaResolutionCached.GetSizeAsync(inputPath); diff --git a/Code/Os/AiProcess.cs b/Code/Os/AiProcess.cs index 4e23a9b..f6a9421 100644 --- a/Code/Os/AiProcess.cs +++ b/Code/Os/AiProcess.cs @@ -439,52 +439,52 @@ namespace Flowframes.Os if (!hasShownError && err && line.ToLower().Contains("out of memory")) { hasShownError = true; - InterpolateUtils.ShowMessage($"Your GPU ran out of VRAM! Please try a video with a lower resolution or use the Max Video Size option in the settings.\n\n{line}", "Error"); + UiUtils.ShowMessageBox($"Your GPU ran out of VRAM! Please try a video with a lower resolution or use the Max Video Size option in the settings.\n\n{line}", UiUtils.MessageType.Error); } if (!hasShownError && err && line.ToLower().Contains("modulenotfounderror")) { hasShownError = true; - InterpolateUtils.ShowMessage($"A python module is missing.\nCheck {logFilename} for details.\n\n{line}", "Error"); - if(!Python.HasEmbeddedPyFolder()) + UiUtils.ShowMessageBox($"A python module is missing.\nCheck {logFilename} for details.\n\n{line}", UiUtils.MessageType.Error); + if (!Python.HasEmbeddedPyFolder()) Process.Start("https://github.com/n00mkrad/flowframes/blob/main/PythonDependencies.md"); } if (!hasShownError && line.ToLower().Contains("no longer supports this gpu")) { hasShownError = true; - InterpolateUtils.ShowMessage($"Your GPU seems to be outdated and is not supported!\n\n{line}", "Error"); + UiUtils.ShowMessageBox($"Your GPU seems to be outdated and is not supported!\n\n{line}", UiUtils.MessageType.Error); } if (!hasShownError && line.ToLower().Contains("illegal memory access")) { hasShownError = true; - InterpolateUtils.ShowMessage($"Your GPU appears to be unstable! If you have an overclock enabled, please disable it!\n\n{line}", "Error"); + UiUtils.ShowMessageBox($"Your GPU appears to be unstable! If you have an overclock enabled, please disable it!\n\n{line}", UiUtils.MessageType.Error); } if (!hasShownError && line.ToLower().Contains("error(s) in loading state_dict")) { hasShownError = true; string msg = (Interpolate.current.ai.aiName == Implementations.flavrCuda.aiName) ? "\n\nFor FLAVR, you need to select the correct model for each scale!" : ""; - InterpolateUtils.ShowMessage($"Error loading the AI model!\n\n{line}{msg}", "Error"); + UiUtils.ShowMessageBox($"Error loading the AI model!\n\n{line}{msg}", UiUtils.MessageType.Error); } if (!hasShownError && line.ToLower().Contains("unicodeencodeerror")) { hasShownError = true; - InterpolateUtils.ShowMessage($"It looks like your path contains invalid characters - remove them and try again!\n\n{line}", "Error"); + UiUtils.ShowMessageBox($"It looks like your path contains invalid characters - remove them and try again!\n\n{line}", UiUtils.MessageType.Error); } if (!hasShownError && err && (line.Contains("RuntimeError") || line.Contains("ImportError") || line.Contains("OSError"))) { hasShownError = true; - InterpolateUtils.ShowMessage($"A python error occured during interpolation!\nCheck {logFilename} for details.\n\n{line}", "Error"); + UiUtils.ShowMessageBox($"A python error occured during interpolation!\nCheck {logFilename} for details.\n\n{line}", UiUtils.MessageType.Error); } if (!hasShownError && err && line.MatchesWildcard("vk*Instance* failed")) { hasShownError = true; - InterpolateUtils.ShowMessage($"Vulkan failed to start up!\n\n{line}\n\nThis most likely means your GPU is not compatible.", "Error"); + UiUtils.ShowMessageBox($"Vulkan failed to start up!\n\n{line}\n\nThis most likely means your GPU is not compatible.", UiUtils.MessageType.Error); } if (!hasShownError && err && line.Contains("vkAllocateMemory failed")) @@ -492,19 +492,19 @@ namespace Flowframes.Os hasShownError = true; bool usingDain = (Interpolate.current.ai.aiName == Implementations.dainNcnn.aiName); string msg = usingDain ? "\n\nTry reducing the tile size in the AI settings." : "\n\nTry a lower resolution (Settings -> Max Video Size)."; - InterpolateUtils.ShowMessage($"Vulkan ran out of memory!\n\n{line}{msg}", "Error"); + UiUtils.ShowMessageBox($"Vulkan ran out of memory!\n\n{line}{msg}", UiUtils.MessageType.Error); } if (!hasShownError && err && line.Contains("invalid gpu device")) { hasShownError = true; - InterpolateUtils.ShowMessage($"A Vulkan error occured during interpolation!\n\n{line}\n\nAre your GPU IDs set correctly?", "Error"); + UiUtils.ShowMessageBox($"A Vulkan error occured during interpolation!\n\n{line}\n\nAre your GPU IDs set correctly?", UiUtils.MessageType.Error); } if (!hasShownError && err && line.MatchesWildcard("vk* failed")) { hasShownError = true; - InterpolateUtils.ShowMessage($"A Vulkan error occured during interpolation!\n\n{line}", "Error"); + UiUtils.ShowMessageBox($"A Vulkan error occured during interpolation!\n\n{line}", UiUtils.MessageType.Error); } if (hasShownError) diff --git a/Code/Program.cs b/Code/Program.cs index ab8662f..baf18d6 100644 --- a/Code/Program.cs +++ b/Code/Program.cs @@ -3,6 +3,7 @@ using Flowframes.Forms; using Flowframes.IO; using Flowframes.MiscUtils; using Flowframes.Os; +using Flowframes.Ui; using System; using System.Collections.Generic; using System.IO; @@ -81,7 +82,7 @@ namespace Flowframes static void ShowUnhandledError(string text) { - MessageBox.Show(text, "Unhandled Error"); + UiUtils.ShowMessageBox(text, UiUtils.MessageType.Error); Clipboard.SetText(text); } @@ -118,8 +119,8 @@ namespace Flowframes if (showMsg) { - MessageBox.Show($"Interpolation has been paused because you are running out of disk space on '{drivePath}/' ({spaceGb} GB)!\n\n" + - $"Please either clear up some disk space or cancel the interpolation.", "Warning"); + UiUtils.ShowMessageBox($"Interpolation has been paused because you are running out of disk space on '{drivePath}/' ({spaceGb} GB)!\n\n" + + $"Please either clear up some disk space or cancel the interpolation.", UiUtils.MessageType.Warning); } } } diff --git a/Code/Ui/UiUtils.cs b/Code/Ui/UiUtils.cs index 3bf2c6a..b12c26c 100644 --- a/Code/Ui/UiUtils.cs +++ b/Code/Ui/UiUtils.cs @@ -9,74 +9,131 @@ namespace Flowframes.Ui { class UiUtils { - public static void InitCombox(ComboBox box, int index) - { - if (box.Items.Count >= 1) - { - box.SelectedIndex = index; - box.Text = box.Items[index].ToString(); - } - } - - public static bool AssignComboxIndexFromText (ComboBox box, string text) // Set index to corresponding text + public static void InitCombox(ComboBox box, int index) { - int index = box.Items.IndexOf(text); + if (box.Items.Count >= 1) + { + box.SelectedIndex = index; + box.Text = box.Items[index].ToString(); + } + } - if (index == -1) // custom value, index not found - return false; - - box.SelectedIndex = index; - return true; - } - - public static ComboBox LoadAiModelsIntoGui (ComboBox combox, AI ai) + public static bool AssignComboxIndexFromText(ComboBox box, string text) // Set index to corresponding text { - combox.Items.Clear(); + int index = box.Items.IndexOf(text); + + if (index == -1) // custom value, index not found + return false; + + box.SelectedIndex = index; + return true; + } + + public static ComboBox LoadAiModelsIntoGui(ComboBox combox, AI ai) + { + combox.Items.Clear(); try { - ModelCollection modelCollection = AiModels.GetModels(ai); + ModelCollection modelCollection = AiModels.GetModels(ai); - if (modelCollection.models == null || modelCollection.models.Count < 1) - return combox; + if (modelCollection.models == null || modelCollection.models.Count < 1) + return combox; - for (int i = 0; i < modelCollection.models.Count; i++) - { - ModelCollection.ModelInfo modelInfo = modelCollection.models[i]; + for (int i = 0; i < modelCollection.models.Count; i++) + { + ModelCollection.ModelInfo modelInfo = modelCollection.models[i]; - if (string.IsNullOrWhiteSpace(modelInfo.name)) - continue; + if (string.IsNullOrWhiteSpace(modelInfo.name)) + continue; - combox.Items.Add(modelInfo.GetUiString()); + combox.Items.Add(modelInfo.GetUiString()); - if (modelInfo.isDefault) - combox.SelectedIndex = i; - } + if (modelInfo.isDefault) + combox.SelectedIndex = i; + } - if (combox.SelectedIndex < 0) - combox.SelectedIndex = 0; + if (combox.SelectedIndex < 0) + combox.SelectedIndex = 0; - SelectNcnnIfNoCudaAvail(combox); - } + SelectNcnnIfNoCudaAvail(combox); + } catch (Exception e) { - Logger.Log($"Failed to load available AI models for {ai.aiName}! {e.Message}"); - Logger.Log($"Stack Trace: {e.StackTrace}", true); + Logger.Log($"Failed to load available AI models for {ai.aiName}! {e.Message}"); + Logger.Log($"Stack Trace: {e.StackTrace}", true); } - return combox; - } + return combox; + } - static void SelectNcnnIfNoCudaAvail (ComboBox combox) + static void SelectNcnnIfNoCudaAvail(ComboBox combox) { - if(NvApi.gpuList.Count < 1) + if (NvApi.gpuList.Count < 1) { - for(int i = 0; i < combox.Items.Count; i++) + for (int i = 0; i < combox.Items.Count; i++) { - if (((string)combox.Items[i]).ToUpper().Contains("NCNN")) - combox.SelectedIndex = i; + if (((string)combox.Items[i]).ToUpper().Contains("NCNN")) + combox.SelectedIndex = i; } } } - } + + public enum MessageType { Message, Warning, Error }; + + public static DialogResult ShowMessageBox(string text, MessageType type = MessageType.Message) + { + Logger.Log($"MessageBox: {text} ({type}){(BatchProcessing.busy ? "[Batch Mode - Will not display messagebox]" : "")}"); + + if (BatchProcessing.busy) + return new DialogResult(); + + MessageBoxIcon icon = MessageBoxIcon.Information; + if (type == MessageType.Warning) icon = MessageBoxIcon.Warning; + else if (type == MessageType.Error) icon = MessageBoxIcon.Error; + + DialogResult res = MessageBox.Show(text, $"Flowframes - {type}", MessageBoxButtons.OK, icon, MessageBoxDefaultButton.Button1, MessageBoxOptions.ServiceNotification); + Program.mainForm.Activate(); + return res; + } + + public enum MoveDirection { Up = -1, Down = 1 }; + + public static void MoveListViewItem(ListView listView, MoveDirection direction) + { + if (listView.SelectedItems.Count != 1) + return; + + ListViewItem selected = listView.SelectedItems[0]; + int index = selected.Index; + int count = listView.Items.Count; + + if (direction == MoveDirection.Up) + { + if (index == 0) + { + listView.Items.Remove(selected); + listView.Items.Insert(count - 1, selected); + } + else + { + listView.Items.Remove(selected); + listView.Items.Insert(index - 1, selected); + } + } + else + { + if (index == count - 1) + { + listView.Items.Remove(selected); + listView.Items.Insert(0, selected); + } + else + { + listView.Items.Remove(selected); + listView.Items.Insert(index + 1, selected); + } + } + } + } }