Skip to content

Commit

Permalink
PlayerのフレームでDragDrop対応
Browse files Browse the repository at this point in the history
  • Loading branch information
yuto-trd committed Sep 16, 2023
1 parent 560c3f6 commit a302241
Show file tree
Hide file tree
Showing 6 changed files with 351 additions and 158 deletions.
7 changes: 5 additions & 2 deletions src/Beutl/Models/ElementDescription.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
namespace Beutl.Models;
using Beutl.Graphics;

namespace Beutl.Models;

public record struct ElementDescription(
TimeSpan Start,
TimeSpan Length,
int Layer,
string Name = "",
Type? InitialOperator = null,
string? FileName = null);
string? FileName = null,
Point Position = default);
28 changes: 26 additions & 2 deletions src/Beutl/ViewModels/Dialogs/AddElementDialogViewModel.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Beutl.Media;
using Beutl.Graphics.Transformation;
using Beutl.Media;
using Beutl.Models;
using Beutl.Operation;
using Beutl.ProjectSystem;
Expand Down Expand Up @@ -83,7 +84,30 @@ public AddElementDialogViewModel(Scene scene, ElementDescription desc)
if (_description.InitialOperator != null)
{
sLayer.Operation.AddChild((SourceOperator)Activator.CreateInstance(_description.InitialOperator)!).Do();
var op = (SourceOperator)Activator.CreateInstance(_description.InitialOperator)!;
sLayer.Operation.AddChild(op).Do();
if (!_description.Position.IsDefault
&& op.Properties.FirstOrDefault(v => v.PropertyType == typeof(ITransform)) is IAbstractProperty<ITransform?> transformp)
{
ITransform? transform = transformp.GetValue();
var translate = new TranslateTransform(_description.Position);
if (transform is TransformGroup group)
{
group.Children.Add(translate);
}
else if (transform == null)
{
transformp.SetValue(translate);
}
else
{
transformp.SetValue(new TransformGroup
{
Children = { transform, translate }
});
}
}
}
sLayer.Save(sLayer.FileName);
Expand Down
188 changes: 188 additions & 0 deletions src/Beutl/ViewModels/EditViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@

using Beutl.Animation;
using Beutl.Api.Services;
using Beutl.Graphics.Transformation;
using Beutl.Helpers;
using Beutl.Media.Decoding;
using Beutl.Media.Source;
using Beutl.Models;
using Beutl.Operation;
using Beutl.Operators.Source;
using Beutl.ProjectSystem;
using Beutl.Services;
using Beutl.Services.PrimitiveImpls;
Expand All @@ -16,6 +22,8 @@

using Serilog;

using LibraryService = Beutl.Services.LibraryService;

namespace Beutl.ViewModels;

public sealed class ToolTabViewModel : IDisposable
Expand Down Expand Up @@ -460,6 +468,186 @@ void RestoreTabItems(JsonArray source, CoreList<ToolTabViewModel> destination)
return null;
}

public void AddElement(ElementDescription desc)
{
Element CreateElement()
{
return new Element()
{
Start = desc.Start,
Length = desc.Length,
ZIndex = desc.Layer,
FileName = RandomFileNameGenerator.Generate(Path.GetDirectoryName(Scene.FileName)!, Constants.ElementFileExtension)
};
}

void SetAccentColor(Element element, string str)
{
element.AccentColor = ColorGenerator.GenerateColor(str);
}

void SetTransform(SourceOperator op)
{
if (!desc.Position.IsDefault
&& op.Properties.FirstOrDefault(v => v.PropertyType == typeof(ITransform)) is IAbstractProperty<ITransform?> transformp)
{
ITransform? transform = transformp.GetValue();
var translate = new TranslateTransform(desc.Position);
if (transform is TransformGroup group)
{
group.Children.Add(translate);
}
else if (transform == null)
{
transformp.SetValue(translate);
}
else
{
transformp.SetValue(new TransformGroup
{
Children = { transform, translate }
});
}
}
}

if (desc.FileName != null)
{
Element CreateElementFor<T>(out T t)
where T : SourceOperator, new()
{
Element element = CreateElement();
element.Name = Path.GetFileName(desc.FileName!);
SetAccentColor(element, typeof(T).FullName!);

element.Operation.AddChild(t = new T()).Do();
SetTransform(t);

return element;
}

var list = new List<IRecordableCommand>();
if (MatchFileImage(desc.FileName))
{
Element element = CreateElementFor(out SourceImageOperator t);
MediaSourceManager.Shared.OpenImageSource(desc.FileName, out IImageSource? image);
t.Source.Value = image;

element.Save(element.FileName);
list.Add(Scene.AddChild(element));
}
else if (MatchFileVideoOnly(desc.FileName))
{
Element element1 = CreateElementFor(out SourceVideoOperator t1);
Element element2 = CreateElementFor(out SourceSoundOperator t2);
element2.ZIndex++;
MediaSourceManager.Shared.OpenVideoSource(desc.FileName, out IVideoSource? video);
MediaSourceManager.Shared.OpenSoundSource(desc.FileName, out ISoundSource? sound);
t1.Source.Value = video;
t2.Source.Value = sound;

if (video != null)
element1.Length = video.Duration;
if (sound != null)
element2.Length = sound.Duration;

element1.Save(element1.FileName);
element2.Save(element2.FileName);
list.Add(Scene.AddChild(element1));
list.Add(Scene.AddChild(element2));
}
else if (MatchFileAudioOnly(desc.FileName))
{
Element element = CreateElementFor(out SourceSoundOperator t);
MediaSourceManager.Shared.OpenSoundSource(desc.FileName, out ISoundSource? sound);
t.Source.Value = sound;
if (sound != null)
{
element.Length = sound.Duration;
}

element.Save(element.FileName);
list.Add(Scene.AddChild(element));
}

list.ToArray()
.ToCommand()
.DoAndRecord(CommandRecorder.Default);
}
else
{
Element element = CreateElement();
if (desc.InitialOperator != null)
{
LibraryItem? item = LibraryService.Current.FindItem(desc.InitialOperator);
if (item != null)
{
element.Name = item.DisplayName;
}

//Todo: レイヤーのアクセントカラー
//sLayer.AccentColor = item.InitialOperator.AccentColor;
element.AccentColor = ColorGenerator.GenerateColor(desc.InitialOperator.FullName ?? desc.InitialOperator.Name);
var operatour = (SourceOperator)Activator.CreateInstance(desc.InitialOperator)!;
element.Operation.AddChild(operatour).Do();
SetTransform(operatour);
}

element.Save(element.FileName);
Scene.AddChild(element).DoAndRecord(CommandRecorder.Default);
}
}

private static bool MatchFileExtensions(string filePath, IEnumerable<string> extensions)
{
return extensions
.Select(x =>
{
int idx = x.LastIndexOf('.');
if (0 <= idx)
return x.Substring(idx);
else
return x;
})
.Any(filePath.EndsWith);
}

private static bool MatchFileAudioOnly(string filePath)
{
return MatchFileExtensions(filePath, DecoderRegistry.EnumerateDecoder()
.SelectMany(x => x.AudioExtensions())
.Distinct());
}

private static bool MatchFileVideoOnly(string filePath)
{
return MatchFileExtensions(filePath, DecoderRegistry.EnumerateDecoder()
.SelectMany(x => x.VideoExtensions())
.Distinct());
}

private static bool MatchFileImage(string filePath)
{
string[] extensions = new string[]
{
"*.bmp",
"*.gif",
"*.ico",
"*.jpg",
"*.jpeg",
"*.png",
"*.wbmp",
"*.webp",
"*.pkm",
"*.ktx",
"*.astc",
"*.dng",
"*.heif",
"*.avif",
};
return MatchFileExtensions(filePath, extensions);
}

void ISupportCloseAnimation.Close(object obj)
{
var searcher = new ObjectSearcher(obj, v => v is IAnimation);
Expand Down
Loading

0 comments on commit a302241

Please sign in to comment.