JD2022-TU1/main/tools/framework/JD.Timeline/View/Actions/ActorBrowser.cs

130 lines
No EOL
4.9 KiB
C#

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using JD.Application.Plugin.World;
using JD.Timeline.Plugin;
using JD.UserControls.QuickOpenDialogs;
using TeaBox;
using TeaBox.Gui;
namespace JD.Timeline.View.Actions
{
public class ActorBrowser
{
public static void Browse(Action<Actor> addActor, Actor.ActorContent requiredActorContent)
{
Browse(null, addActor, null, requiredActorContent);
}
public static void Browse(Func<Actor, bool> containsActor, Action<Actor> addActor, Action<Actor> removeActor, Actor.ActorContent requiredActorContent)
{
IEnumerable<Actor> actors;
if (!BuildActorList(requiredActorContent, out actors))
{
return;
}
string requirement = requiredActorContent == Actor.ActorContent.None ? " (any)" : " with content " + requiredActorContent.ToString();
var form = new QuickOpenForm<Actor>(actors)
{
Caption = (containsActor == null ? "Replace actor" : "Browse for actors") + requirement,
HintProvider = actor => actor.Path,
NameProvider = actor => actor.Name,
ImageSize = new Size(32, 32),
ImageProvider = actor => actor.Image,
ShowAllOnEmptyText = true,
};
form.ItemAccepted += addActor;
AddSingleClickBehavior(containsActor, addActor, removeActor, form);
AddSelectedActorStyle(containsActor, form);
form.Show();
}
private static bool BuildActorList(Actor.ActorContent requiredActorContent, out IEnumerable<Actor> actors)
{
actors = TimelinePlugin.Instance.World.Actors;
string noActorMessage = string.Empty;
if (!actors.Any())
{
noActorMessage = "Could not retrieve any actor from the current running game";
}
else
{
actors = actors.Where(actor => actor.Content.Contains(requiredActorContent));
if (!actors.Any())
{
noActorMessage = $"No actor is compatible with the selected clips (needs {requiredActorContent})";
}
}
if (!string.IsNullOrEmpty(noActorMessage))
{
MessageService.MessageService.ShowWarning(noActorMessage);
return false;
}
return true;
}
private static void AddSingleClickBehavior(Func<Actor, bool> containsActor, Action<Actor> addActor, Action<Actor> removeActor, QuickOpenForm<Actor> form)
{
if (containsActor != null && removeActor != null)
{
form.SelectionMode = SelectionMode.MultiExtended;
form.SelectionChanged += () =>
{
if (form.SelectedItems.Count() > 1)
{
foreach (var actor in form.SelectedItems)
{
if (!containsActor(actor))
{
addActor(actor);
form.Invalidate(actor);
}
}
}
};
form.ItemClick += actor =>
{
if (containsActor(actor))
{
removeActor(actor);
form.ClearSelectedItems();
}
else
{
addActor(actor);
form.Invalidate(actor);
}
};
}
}
private static void AddSelectedActorStyle(Func<Actor, bool> containsActor, QuickOpenForm<Actor> form)
{
if (containsActor != null)
{
form.ItemBackgroundPaint += (graphics, bounds, actor) =>
{
if (containsActor(actor))
{
bounds = new Rectangle(bounds.X, bounds.Y, bounds.Width - 1, bounds.Height - 1);
using (var brush = new SolidBrush(Color.FromArgb(0x42, 0xFF, 0xFF, 0x99)))
using (var pen = new Pen(Color.FromArgb(0xAA, 0xAA, 0x00)))
{
graphics.FillRectangle(brush, bounds);
graphics.DrawRectangle(pen, bounds);
}
}
};
}
}
}
}