Skip to content

Commit

Permalink
Fixed ResourceAVMedia not being serialisable and also resources not b…
Browse files Browse the repository at this point in the history
…eing destroyed when a project is closed (causing things like file handles to stay open until closing the editor), added online/offline indicator in resource manager (red outline + red header), replaced standard message box usage with custom one (for the dark theme :D), added frame progress text block to export dialog
  • Loading branch information
AngryCarrot789 committed Feb 5, 2024
1 parent 2e522cf commit 8a4bf0a
Show file tree
Hide file tree
Showing 20 changed files with 181 additions and 40 deletions.
4 changes: 2 additions & 2 deletions FramePFX/Actions/ActionManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Threading.Tasks;
using System.Windows;
using FramePFX.Interactivity.DataContexts;
using FramePFX.Utils;

namespace FramePFX.Actions {
/// <summary>
Expand Down Expand Up @@ -143,8 +144,7 @@ private static async Task TryExecuteOrShowDialog(AnAction action, AnActionEventA
await action.ExecuteAsync(e);
}
catch (Exception ex) {
MessageBox.Show($"An exception occurred while executing '{e.ActionId ?? action.GetType().ToString()}':\n{ex.Message}", "Action execution exception");
// await IoC.DialogService.ShowMessageExAsync("Action execution exception", , ex.GetToString());
IoC.MessageService.ShowMessage("Action execution exception", $"An exception occurred while executing '{e.ActionId ?? action.GetType().ToString()}'", ex.GetToString());
}
}

Expand Down
9 changes: 5 additions & 4 deletions FramePFX/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,9 @@ public async Task InitWPFApp() {

RuntimeHelpers.RunClassConstructor(typeof(UIInputManager).TypeHandle);

// This is where services are registered
await ApplicationCore.InternalSetupNewInstance(this.splash);
// Most if not all services are available below here

await AppLogger.Instance.FlushEntries();
await this.splash.SetAction("Loading shortcuts and actions...", null);
Expand All @@ -90,11 +92,11 @@ public async Task InitWPFApp() {
}
}
catch (Exception ex) {
MessageBox.Show("Failed to read keymap file" + keymapFilePath + ":" + ex.GetToString());
IoC.MessageService.ShowMessage("Keymap", "Failed to read keymap file" + keymapFilePath + ":" + ex.GetToString());
}
}
else {
MessageBox.Show("Keymap file does not exist at " + keymapFilePath);
IoC.MessageService.ShowMessage("Keymap", "Keymap file does not exist at " + keymapFilePath);
}

await this.splash.SetAction("Loading FFmpeg...", null);
Expand All @@ -103,8 +105,7 @@ public async Task InitWPFApp() {
ffmpeg.avdevice_register_all();
}
catch (Exception e) {
MessageBox.Show("The FFmpeg libraries (avcodec-60.dll, avfilter-9, and all other 6 dlls files) must be placed in the build folder which is where the EXE is, e.g. /FramePFX/bin/x64/Debug", "FFmpeg not found");
throw new Exception("FFmpeg Unavailable. Copy FFmpeg DLLs into the same folder as the app's .exe", e);
IoC.MessageService.ShowMessage("FFmpeg registration failed", "The FFmpeg libraries (avcodec-60.dll, avfilter-9, and all other 6 dlls files) must be placed in the build folder which is where the EXE is, e.g. /FramePFX/bin/x64/Debug", e.GetToString());
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions FramePFX/AttachedProperties/ObservableSelectionHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -330,9 +330,9 @@ private static void OnSourceCollectionChanged(object sender, NotifyCollectionCha
}

if (list.TryGetException(out Exception error)) {
MessageBox.Show("An exception occurred while processing selection change. " +
"This may have corrupted the application in some way, so please restart.\n\n" +
"See the app logs for more info", "Error");
IoC.MessageService.ShowMessage("Error", "An exception occurred while processing selection change. " +
"This may have corrupted the application in some way, so please restart.\n\n" +
"See the app logs for more info");
}
}
}
Expand Down
11 changes: 10 additions & 1 deletion FramePFX/Editors/Actions/NewProjectAction.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System.Threading.Tasks;
using System.Windows;
using FramePFX.Actions;
using FramePFX.Editors.Timelines.Effects;
using FramePFX.Editors.Timelines.Tracks;
using FramePFX.Interactivity.DataContexts;
using FramePFX.Views;

Expand Down Expand Up @@ -44,7 +46,14 @@ public override Task ExecuteAsync(AnActionEventArgs e) {
return Task.CompletedTask;
}

editor.SetProject(new Project());
Project project = new Project();
VideoTrack track = new VideoTrack() {
DisplayName = "Video Track 1"
};

track.AddEffect(new MotionEffect());
project.MainTimeline.AddTrack(track);
editor.SetProject(project);
return Task.CompletedTask;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ protected override async void OnDrop(DragEventArgs e) {
await ResourceDropRegistry.DropRegistry.OnDropped(currentFolder, list, effects);
}
else if (!await ResourceDropRegistry.DropRegistry.OnDroppedNative(currentFolder, new DataObjectWrapper(e.Data), effects)) {
MessageBox.Show("Unknown dropped item. Drop files here", "Unknown data");
IoC.MessageService.ShowMessage("Unknown data", "Unknown dropped item. Drop files here");
// await IoC.DialogService.ShowMessageAsync("Unknown data", "Unknown dropped item. Drop files here");
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ public class ResourceExplorerListItem : ContentControl {
public static readonly DependencyProperty IsDroppableTargetOverProperty = DependencyProperty.Register("IsDroppableTargetOver", typeof(bool), typeof(ResourceExplorerListItem), new PropertyMetadata(BoolBox.False));
public static readonly DependencyProperty IsSelectedProperty = Selector.IsSelectedProperty.AddOwner(typeof(ResourceExplorerListItem), new FrameworkPropertyMetadata(BoolBox.False, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, (d, e) => ((ResourceExplorerListItem) d).OnIsSelectedChanged((bool) e.NewValue)));
public static readonly DependencyProperty DisplayNameProperty = DependencyProperty.Register("DisplayName", typeof(string), typeof(ResourceExplorerListItem), new PropertyMetadata(null));
private static readonly DependencyPropertyKey IsResourceOnlinePropertyKey = DependencyProperty.RegisterReadOnly("IsResourceOnline", typeof(bool), typeof(ResourceExplorerListItem), new PropertyMetadata(BoolBox.True));
public static readonly DependencyProperty IsResourceOnlineProperty = IsResourceOnlinePropertyKey.DependencyProperty;

public bool IsDroppableTargetOver {
get => (bool) this.GetValue(IsDroppableTargetOverProperty);
Expand All @@ -29,14 +31,19 @@ public bool IsDroppableTargetOver {

public bool IsSelected {
get => (bool) this.GetValue(IsSelectedProperty);
set => this.SetValue(IsSelectedProperty, value);
set => this.SetValue(IsSelectedProperty, value.Box());
}

public string DisplayName {
get => (string) this.GetValue(DisplayNameProperty);
set => this.SetValue(DisplayNameProperty, value);
}

public bool IsResourceOnline {
get => (bool) this.GetValue(IsResourceOnlineProperty);
private set => this.SetValue(IsResourceOnlinePropertyKey, value.Box());
}

public BaseResource Model { get; private set; }

public ResourceExplorerListControl ResourceExplorerList { get; private set; }
Expand Down Expand Up @@ -195,8 +202,7 @@ protected override async void OnDrop(DragEventArgs e) {
await ResourceDropRegistry.DropRegistry.OnDropped(folder, list, effects);
}
else if (!await ResourceDropRegistry.DropRegistry.OnDroppedNative(folder, new DataObjectWrapper(e.Data), effects)) {
MessageBox.Show("Unknown dropped item. Drop files here", "Unknown data");
// await IoC.DialogService.ShowMessageAsync("Unknown data", "Unknown dropped item. Drop files here");
IoC.MessageService.ShowMessage("Unknown Data", "Unknown dropped item. Drop files here");
}
}
finally {
Expand Down Expand Up @@ -258,6 +264,11 @@ public void OnAddingToList(ResourceExplorerListControl explorerList, BaseResourc
public void OnAddedToList() {
this.displayNameBinder.Attach(this, this.Model);
this.isSelectedBinder.Attach(this, this.Model);
if (this.Model is ResourceItem item) {
item.OnlineStateChanged += this.UpdateIsOnlineState;
this.UpdateIsOnlineState(item);
}

ResourceExplorerListItemContent content = (ResourceExplorerListItemContent) this.Content;
content.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));

Expand All @@ -270,6 +281,10 @@ public void OnAddedToList() {
public void OnRemovingFromList() {
this.displayNameBinder.Detatch();
this.isSelectedBinder.Detatch();
if (this.Model is ResourceItem item) {
item.OnlineStateChanged -= this.UpdateIsOnlineState;
}

ResourceExplorerListItemContent content = (ResourceExplorerListItemContent) this.Content;
content.Disconnect();
this.Content = null;
Expand All @@ -281,5 +296,9 @@ public void OnRemovedFromList() {
this.ResourceExplorerList = null;
this.Model = null;
}

private void UpdateIsOnlineState(ResourceItem resource) {
this.IsResourceOnline = resource.IsOnline;
}
}
}
21 changes: 19 additions & 2 deletions FramePFX/Editors/Controls/Resources/ResourceStyles.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,15 @@
</DockPanel>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True"/>
<Condition Property="IsResourceOnline" Value="True"/>
</MultiTrigger.Conditions>
<Setter Property="Background" TargetName="PART_HeaderBorder" Value="{DynamicResource Item.MouseOver.Background}"/>
<Setter Property="BorderBrush" TargetName="Bd" Value="{DynamicResource Item.MouseOver.Border}"/>
</Trigger>
</MultiTrigger>

<Trigger Property="IsEnabled" Value="False">
<Setter Property="TextElement.Foreground" TargetName="Bd" Value="{DynamicResource ABrush.Foreground.Disabled}"/>
</Trigger>
Expand All @@ -138,6 +143,18 @@
<Trigger Property="IsDroppableTargetOver" Value="True">
<Setter Property="BorderBrush" TargetName="Bd" Value="OrangeRed"/>
</Trigger>
<Trigger Property="IsResourceOnline" Value="False">
<Setter Property="Background" TargetName="PART_HeaderBorder" Value="Red"/>
<Setter Property="BorderBrush" TargetName="Bd" Value="Red"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True"/>
<Condition Property="IsResourceOnline" Value="False"/>
</MultiTrigger.Conditions>
<Setter Property="Background" TargetName="PART_HeaderBorder" Value="DarkRed"/>
<Setter Property="BorderBrush" TargetName="Bd" Value="DarkRed"/>
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,7 @@ protected override async void OnDrop(DragEventArgs e) {
await ResourceDropRegistry.DropRegistry.OnDropped(manager.RootContainer, list, effects);
}
else if (!await ResourceDropRegistry.DropRegistry.OnDroppedNative(manager.RootContainer, new DataObjectWrapper(e.Data), effects)) {
MessageBox.Show("Unknown dropped item. Drop files here", "Unknown data");
// await IoC.DialogService.ShowMessageAsync("Unknown data", "Unknown dropped item. Drop files here");
IoC.MessageService.ShowMessage("Unknown Data", "Unknown dropped item. Drop files here");
}
}
finally {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -324,8 +324,7 @@ protected override async void OnDrop(DragEventArgs e) {
await ResourceDropRegistry.DropRegistry.OnDropped(self, list, effects);
}
else if (!await ResourceDropRegistry.DropRegistry.OnDroppedNative(self, new DataObjectWrapper(e.Data), effects)) {
MessageBox.Show("Unknown dropped item. Drop files here", "Unknown data");
// await IoC.DialogService.ShowMessageAsync("Unknown data", "Unknown dropped item. Drop files here");
IoC.MessageService.ShowMessage("Unknown Data", "Unknown dropped item. Drop files here");
}
}
finally {
Expand Down
8 changes: 4 additions & 4 deletions FramePFX/Editors/Controls/Timelines/TrackDropRegistry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ static TrackDropRegistry() {
return objekt.GetData(NativeDropTypes.FileDrop) is string[] files && files.Length > 0 ? EnumDropType.Copy : EnumDropType.None;
}, async (model, objekt, type, c) => {
string[] files = (string[]) objekt.GetData(NativeDropTypes.FileDrop);
MessageBox.Show($"Dropping files directly into the timeline is not implemented yet.\nYou dropped: {string.Join(", ", files)}", "STILL TODO");
IoC.MessageService.ShowMessage("STILL TODO", $"Dropping files directly into the timeline is not implemented yet.\nYou dropped: {string.Join(", ", files)}");
});

DropRegistry.Register<VideoTrack, ResourceItem>((track, resource, dt, ctx) => {
Expand All @@ -30,17 +30,17 @@ static TrackDropRegistry() {
: EnumDropType.None;
}, async (track, resource, dt, ctx) => {
if (!ctx.TryGetContext(DataKeys.TrackDropFrameKey, out long frame)) {
MessageBox.Show("Drag drop error: no track frame location", "Drop err");
IoC.MessageService.ShowMessage("Drop err", "Drag drop error: no track frame location");
return;
}

if (!resource.IsOnline) {
MessageBox.Show("Cannot add an offline resource to the timeline", "Resource Offline");
IoC.MessageService.ShowMessage("Resource Offline", "Cannot add an offline resource to the timeline");
return;
}

if (resource.UniqueId == ResourceManager.EmptyId || !resource.IsRegistered()) {
MessageBox.Show("This resource is not registered yet. This is a bug", "Invalid resource");
IoC.MessageService.ShowMessage("Invalid resource", "This resource is not registered yet. This is a bug");
return;
}

Expand Down
2 changes: 2 additions & 0 deletions FramePFX/Editors/Exporting/Controls/ExportProgressDialog.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
<Separator Margin="0,10"/>
<TextBlock Text="Encode Progress" Padding="0,5"/>
<ProgressBar Height="20" x:Name="PART_EncodeProgressBar"/>
<Separator Margin="0,5"/>
<TextBox x:Name="PART_FrameProgressText"/>
</StackPanel>
</Grid>
</v:WindowEx>
12 changes: 7 additions & 5 deletions FramePFX/Editors/Exporting/Controls/ExportProgressDialog.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,24 +27,26 @@ public partial class ExportProgressDialog : WindowEx, IExportProgress {

public CancellationTokenSource Cancellation { get; }

private bool isCancelled;

public ExportProgressDialog(FrameSpan renderSpan, CancellationTokenSource cancellation) {
this.renderSpan = renderSpan;
this.InitializeComponent();

this.Cancellation = cancellation;
this.currentRenderFrame = renderSpan.Begin;
this.currentEncodeFrame = renderSpan.Begin;
this.rapidUpdateRender = new RapidDispatchCallback(() => {
this.PART_RenderProgressBar.Value = this.RenderProgressPercentage;
}, "ExportUpdateRender");
this.PART_FrameProgressText.Text = "0/" + (this.EndFrame - 1);
this.rapidUpdateRender = new RapidDispatchCallback(this.UpdateRenderedFrame, "ExportUpdateRender");

this.rapidUpdateEncode = new RapidDispatchCallback(() => {
this.PART_EncodeProgressBar.Value = this.EncodeProgressPercentage;
}, "ExportUpdateEncode");
}

private void UpdateRenderedFrame() {
this.PART_RenderProgressBar.Value = this.RenderProgressPercentage;
this.PART_FrameProgressText.Text = $"{this.currentRenderFrame}/{this.EndFrame - 1}";
}

public void OnFrameRendered(long frame) {
Interlocked.Increment(ref this.currentRenderFrame);
this.rapidUpdateRender.InvokeAsync();
Expand Down
1 change: 1 addition & 0 deletions FramePFX/Editors/Factories/ResourceTypeFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ private ResourceTypeFactory() {
this.RegisterType("r_argb", typeof(ResourceColour));
this.RegisterType("r_img", typeof(ResourceImage));
this.RegisterType("r_txt", typeof(ResourceTextStyle));
this.RegisterType("r_avmedia", typeof(ResourceAVMedia));
}

public BaseResource NewResource(string id) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public override void OnApplyTemplate() {

private void ConfirmClick(object sender, RoutedEventArgs e) {
if (!this.Entry.TryLoad()) {
MessageBox.Show("File path is still invalid");
IoC.MessageService.ShowMessage("No such file", "File path is still invalid");
}
}

Expand Down
9 changes: 9 additions & 0 deletions FramePFX/Editors/ResourceManaging/ResourceFolder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -151,5 +151,14 @@ public static void DestroyHierarchy(BaseResource resource) {
resource.Destroy();
}
}

public static void ClearHierarchy(BaseResource resource) {
if (resource is ResourceFolder folder) {
for (int i = folder.items.Count - 1; i >= 0; i--) {
ClearHierarchy(folder.items[i]);
folder.RemoveItemAt(i);
}
}
}
}
}
12 changes: 2 additions & 10 deletions FramePFX/Editors/ResourceManaging/ResourceManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -231,16 +231,8 @@ public bool EntryExists(ResourceItem item, out bool isRefEqual) {
}

public void ClearEntries() {
using (ErrorList stack = new ErrorList()) {
foreach (KeyValuePair<ulong, ResourceItem> entry in this.uuidToItem.ToList()) {
try {
this.UnregisterItem(entry.Value);
}
catch (Exception e) {
stack.Add(e);
}
}
}
ResourceFolder.DestroyHierarchy(this.RootContainer);
ResourceFolder.ClearHierarchy(this.RootContainer);
}

#region Static Helper Functions
Expand Down
12 changes: 12 additions & 0 deletions FramePFX/Editors/ResourceManaging/Resources/ResourceAVMedia.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using FramePFX.FFmpegWrapper.Codecs;
using FramePFX.FFmpegWrapper.Containers;
using FramePFX.Logger;
using FramePFX.RBC;
using FramePFX.Utils;

namespace FramePFX.Editors.ResourceManaging.Resources {
Expand Down Expand Up @@ -42,6 +43,17 @@ public ResourceAVMedia() {

}

public override void WriteToRBE(RBEDictionary data) {
base.WriteToRBE(data);
if (!string.IsNullOrEmpty(this.filePath))
data.SetString(nameof(this.FilePath), this.filePath);
}

public override void ReadFromRBE(RBEDictionary data) {
base.ReadFromRBE(data);
this.filePath = data.GetString(nameof(this.FilePath), null);
}

protected override bool OnTryAutoEnable(ResourceLoader loader) {
if (string.IsNullOrEmpty(this.FilePath)) {
return true;
Expand Down
Loading

0 comments on commit 8a4bf0a

Please sign in to comment.