add RMSE method, MatchCount option

This commit is contained in:
sup39 2022-07-31 02:19:51 +09:00
parent 6b37c1c326
commit fd78232340
9 changed files with 910 additions and 829 deletions

View file

@ -13,7 +13,7 @@ using System.Runtime.InteropServices;
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")] [assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("supAutoSplit")] [assembly: AssemblyProduct("supAutoSplit")]
[assembly: AssemblyCopyright("Copyright © 2021 sup39[サポミク]")] [assembly: AssemblyCopyright("Copyright © 2021-2022 sup39[サポミク]")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]

View file

@ -12,157 +12,161 @@ using OpenCvSharp;
namespace LiveSplit.SupAutoSplit { namespace LiveSplit.SupAutoSplit {
public sealed class Component : LogicComponent { public sealed class Component : LogicComponent {
public override string ComponentName => "supAutoSplit"; public override string ComponentName => "supAutoSplit";
private UI.Settings Settings { get; set; } private UI.Settings Settings { get; set; }
private LiveSplitState State { get; set; } private LiveSplitState State { get; set; }
private TimerModel Model { get; } private TimerModel Model { get; }
public Component(LiveSplitState state) { public Component(LiveSplitState state) {
Settings = new UI.Settings(); // TODO
State = state; Environment.SetEnvironmentVariable("OPENCV_VIDEOIO_MSMF_ENABLE_HW_TRANSFORMS", "0", EnvironmentVariableTarget.User);
Model = new TimerModel { Settings = new UI.Settings();
CurrentState = state State = state;
}; Model = new TimerModel {
CurrentState = state
};
ContextMenuControls = new Dictionary<string, Action> { ContextMenuControls = new Dictionary<string, Action> {
{ "Start supAutoSplit", Start } { "Start supAutoSplit", Start }
}; };
} }
private Thread captureThread; private Thread captureThread;
private List<MatchHandler> handlersAll; private List<MatchHandler> handlersAll;
private List<MatchHandler> handlers; private List<MatchHandler> handlers;
private volatile bool handlerReady = false; private volatile bool handlerReady = false;
private void UpdateHandlers(object sender, EventArgs e) { private void UpdateHandlers(object sender, EventArgs e) {
handlers = handlersAll.Where(h => h.Reset(State)).ToList(); handlers = handlersAll.Where(h => h.Reset(State)).ToList();
handlerReady = true; handlerReady = true;
} }
private void UpdateHandlers_Reset(object sender, TimerPhase e) => UpdateHandlers(null, null); private void UpdateHandlers_Reset(object sender, TimerPhase e) => UpdateHandlers(null, null);
private void Start() { private void Start() {
ContextMenuControls.Clear(); ContextMenuControls.Clear();
ContextMenuControls.Add("Reload supAutoSplit", Reload); ContextMenuControls.Add("Reload supAutoSplit", Reload);
ContextMenuControls.Add("Stop supAutoSplit", Stop); ContextMenuControls.Add("Stop supAutoSplit", Stop);
Reload(); Reload();
State.OnStart += UpdateHandlers; State.OnStart += UpdateHandlers;
State.OnSplit += UpdateHandlers; State.OnSplit += UpdateHandlers;
State.OnSkipSplit += UpdateHandlers; State.OnSkipSplit += UpdateHandlers;
State.OnUndoSplit += UpdateHandlers; State.OnUndoSplit += UpdateHandlers;
State.OnPause += UpdateHandlers; State.OnPause += UpdateHandlers;
State.OnResume += UpdateHandlers; State.OnResume += UpdateHandlers;
State.OnReset += UpdateHandlers_Reset; State.OnReset += UpdateHandlers_Reset;
captureThread = new Thread(() => { captureThread = new Thread(() => {
using (var capture = new VideoCapture(Settings.CaptureDevice)) using (var capture = new VideoCapture(Settings.CaptureDevice))
using (var window = new Window(Settings.WindowName)) using (var window = new Window(Settings.WindowName))
using (Mat frame = new Mat()) { using (Mat frame = new Mat()) {
try { try {
// Stopwatch sw = new Stopwatch(); // Stopwatch sw = new Stopwatch();
// Stopwatch sw1 = new Stopwatch(); // Stopwatch sw1 = new Stopwatch();
// Stopwatch sw2 = new Stopwatch(); // Stopwatch sw2 = new Stopwatch();
// sw.Start(); // sw.Start();
while (capture.Read(frame)) { while (capture.Read(frame)) {
// sw1.Restart(); // sw1.Restart();
if (handlerReady) { if (handlerReady) {
foreach (var handler in handlers) { foreach (var handler in handlers) {
if (handler.Match(frame)) { if (handler.Match(frame)) {
handlerReady = false; handlerReady = false;
handler.Action(Model); handler.Action(Model);
break; break;
} }
} }
} }
// sw1.Stop(); // sw1.Stop();
// sw2.Restart(); // sw2.Restart();
window.ShowImage(frame); window.ShowImage(frame);
// sw2.Stop(); // sw2.Stop();
// sw.Stop(); // sw.Stop();
// Debug.WriteLine($"{sw1.ElapsedMilliseconds:#0} ({sw1.ElapsedTicks}) {sw2.ElapsedMilliseconds:#0} ({sw2.ElapsedTicks}) {sw.ElapsedMilliseconds:#0}"); // Debug.WriteLine($"{sw1.ElapsedMilliseconds:#0} ({sw1.ElapsedTicks}) {sw2.ElapsedMilliseconds:#0} ({sw2.ElapsedTicks}) {sw.ElapsedMilliseconds:#0}");
Cv2.WaitKey(1); Cv2.WaitKey(1);
// sw.Restart(); // sw.Restart();
} }
} catch (ThreadInterruptedException) {} } catch (ThreadInterruptedException) { }
} }
}); });
captureThread.Start(); captureThread.Start();
} }
private void Reload() { private void Reload() {
handlersAll = Settings.TemplateSettings.Select(o => new MatchHandler(o)).ToList(); handlersAll = Settings.TemplateSettings.Select(o => new MatchHandler(o)).ToList();
UpdateHandlers(null, null); UpdateHandlers(null, null);
} }
private void Stop() { private void Stop() {
captureThread?.Abort(); captureThread?.Abort();
captureThread = null; captureThread = null;
State.OnStart -= UpdateHandlers; State.OnStart -= UpdateHandlers;
State.OnSplit -= UpdateHandlers; State.OnSplit -= UpdateHandlers;
State.OnSkipSplit -= UpdateHandlers; State.OnSkipSplit -= UpdateHandlers;
State.OnUndoSplit -= UpdateHandlers; State.OnUndoSplit -= UpdateHandlers;
State.OnPause -= UpdateHandlers; State.OnPause -= UpdateHandlers;
State.OnResume -= UpdateHandlers; State.OnResume -= UpdateHandlers;
State.OnReset -= UpdateHandlers_Reset; State.OnReset -= UpdateHandlers_Reset;
ContextMenuControls.Clear(); ContextMenuControls.Clear();
ContextMenuControls.Add("Start supAutoSplit", Start); ContextMenuControls.Add("Start supAutoSplit", Start);
} }
public override void Dispose() { public override void Dispose() {
captureThread?.Abort(); captureThread?.Abort();
} }
public override XmlNode GetSettings(XmlDocument document) => Settings.GetSettings(document); public override XmlNode GetSettings(XmlDocument document) => Settings.GetSettings(document);
public override Control GetSettingsControl(LayoutMode mode) => Settings; public override Control GetSettingsControl(LayoutMode mode) => Settings;
public int GetSettingsHashCode() => Settings.GetSettingsHashCode(); public int GetSettingsHashCode() => Settings.GetSettingsHashCode();
public override void SetSettings(XmlNode settings) => Settings.SetSettings(settings); public override void SetSettings(XmlNode settings) => Settings.SetSettings(settings);
public override void Update(IInvalidator invalidator, LiveSplitState state, float width, float height, LayoutMode mode) {} public override void Update(IInvalidator invalidator, LiveSplitState state, float width, float height, LayoutMode mode) { }
} }
} }
namespace LiveSplit.SupAutoSplit { namespace LiveSplit.SupAutoSplit {
class MatchHandler { class MatchHandler {
private readonly Predicate<LiveSplitState> fEnabled; private readonly Predicate<LiveSplitState> fEnabled;
private readonly Rect imageRange; private readonly Rect imageRange;
private readonly Func<Mat, double> fSim; private readonly Func<Mat, double> fSim;
private readonly Predicate<double> fMatch; private readonly Predicate<double> fMatch;
private readonly Predicate<double> fMatchNeg; private readonly Predicate<double> fMatchNeg;
public Action<TimerModel> Action { get; } public Action<TimerModel> Action { get; }
private bool ready = false; private int ready = 0;
private readonly int maxReady;
private int count = 0;
private readonly int maxCount;
public MatchHandler(UI.TemplateSettings settings) { public MatchHandler(UI.TemplateSettings settings) {
fEnabled = settings.EnableIf; fEnabled = settings.EnableIf;
using (var timg = Cv2.ImRead(settings.ImagePath, ImreadModes.Unchanged)) { using (var timg = Cv2.ImRead(settings.ImagePath, ImreadModes.Unchanged)) {
imageRange = new Rect(settings.ImageOffset, timg.Size()); imageRange = new Rect(settings.ImageOffset, timg.Size());
fSim = settings.MatchMethodFactory(timg); fSim = settings.MatchMethodFactory(timg);
} }
var threshold = settings.MatchThreshold; var threshold = settings.MatchThreshold;
var thresholdNeg = settings.MatchThresholdNeg; var thresholdNeg = settings.MatchThresholdNeg;
if (thresholdNeg <= 0) thresholdNeg = threshold; if (thresholdNeg <= 0) thresholdNeg = threshold;
if (settings.IsActionOnPosedge) { maxReady = settings.IsActionOnPosedge ? 1 : 2;
fMatch = sim => sim <= threshold; fMatch = sim => sim <= threshold;
fMatchNeg = sim => sim >= thresholdNeg; fMatchNeg = sim => sim >= thresholdNeg;
} else { maxCount = settings.MatchCount;
fMatch = sim => sim >= threshold; Action = settings.MatchAction;
fMatchNeg = sim => sim <= thresholdNeg; }
}
Action = settings.MatchAction;
}
public bool Reset(LiveSplitState state) { public bool Reset(LiveSplitState state) {
ready = false; ready = count = 0;
return fEnabled(state); return fEnabled(state);
} }
public bool Match(Mat frame) { public bool Match(Mat frame) {
// Stopwatch sw = new Stopwatch(); // Stopwatch sw = new Stopwatch();
var fimg = frame[imageRange]; var fimg = frame[imageRange];
var sim = fSim(fimg); var sim = fSim(fimg);
// sw.Stop(); // sw.Stop();
// Debug.WriteLine($"#sim {sim} | {sw.ElapsedMilliseconds} ({sw.ElapsedTicks})"); // Debug.WriteLine($"#sim {sim} | {sw.ElapsedMilliseconds} ({sw.ElapsedTicks})");
if (ready) { Debug.WriteLine($"#[{count}/{maxCount}] {sim} {ready}");
return fMatch(sim); if (((ready & 1) == 0 ? fMatchNeg : fMatch)(sim)) {
} else if (fMatchNeg(sim)) { if (++ready > maxReady) {
ready = true; ready = 0;
} return ++count >= maxCount;
return false; }
} }
return false;
}
} }
} }

View file

@ -16,11 +16,11 @@ namespace LiveSplit.SupAutoSplit {
public string UpdateName => ComponentName; public string UpdateName => ComponentName;
public string XMLURL => "https://301.sup39.ml/LiveSplit/supAutoSplit.xml"; // TODO public string XMLURL => "https://link.sup39.dev/LiveSplit/supAutoSplit.xml"; // TODO
public string UpdateURL => "https://301.sup39.ml/LiveSplit/supAutoSplit/update"; // TODO public string UpdateURL => "https://link.sup39.dev/LiveSplit/supAutoSplit/update"; // TODO
public Version Version => Version.Parse("0.1.0"); public Version Version => Version.Parse("0.1.1");
public IComponent Create(LiveSplitState state) => new Component(state); public IComponent Create(LiveSplitState state) => new Component(state);
} }

View file

@ -15,110 +15,119 @@ namespace LiveSplit.SupAutoSplit {
using MatchMethodFactory = Func<Mat, Func<Mat, double>>; using MatchMethodFactory = Func<Mat, Func<Mat, double>>;
class MatchTemplate { class MatchTemplate {
static public readonly ListItem<EnableIfFactory>[] EnableIfFactories = { static public readonly ListItem<EnableIfFactory>[] EnableIfFactories = {
("Index", "Split Index in range", arg => { ("Index", "Split Index in range", arg => {
var testers = arg.Split(',').Select(s => { var testers = arg.Split(',').Select(s => {
string[] ns = arg.Split(':'); string[] ns = s.Split(':');
if (ns.Length == 0 || ns.Length > 3) return null; if (ns.Length == 0 || ns.Length > 3) return null;
int start = 0, end = int.MaxValue, step = 1; int start = 0, end = int.MaxValue, step = 1;
if (ns[0] != "" && !int.TryParse(ns[0], out start)) return null; if (ns[0] != "" && !int.TryParse(ns[0], out start)) return null;
if (ns.Length == 1) return start < 0 ? if (ns.Length == 1) return start < 0 ?
(Func<int, int, bool>)((idx, len) => idx == len + start) : (Func<int, int, bool>)((idx, len) => idx == len + start) :
((idx, len) => idx==start); ((idx, len) => idx==start);
if (ns[1] != "" && !int.TryParse(ns[1], out end)) return null; if (ns[1] != "" && !int.TryParse(ns[1], out end)) return null;
if (ns.Length == 3 && ns[2] != "" && (!int.TryParse(ns[2], out step) || step==0)) return null; if (ns.Length == 3 && ns[2] != "" && (!int.TryParse(ns[2], out step) || step==0)) return null;
return (idx, len) => { return (idx, len) => {
int start1 = start<0 ? start+len : start; int start1 = start<0 ? start+len : start;
int end1 = end<0 ? end+len : end; int end1 = end<0 ? end+len : end;
return start1 <= idx && idx < end1 && (idx-start1)%step == 0; return start1 <= idx && idx < end1 && (idx-start1)%step == 0;
}; };
}).Where(s => s!=null).ToList(); }).Where(s => s!=null).ToList();
return state => testers.Any(f => f(state.CurrentSplitIndex, state.Run.Count)); return state => testers.Any(f => f(state.CurrentSplitIndex, state.Run.Count));
}), }),
("Name", "Split Name matches", arg => { ("Name", "Split Name matches", arg => {
try { try {
var re = new Regex(arg); var re = new Regex(arg);
return state => state.CurrentSplit == null ? false : re.IsMatch(state.CurrentSplit.Name); return state => state.CurrentSplit == null ? false : re.IsMatch(state.CurrentSplit.Name);
} catch { } catch {
// not regex // not regex
return state => state.CurrentSplit == null ? false : state.CurrentSplit.Name == arg; return state => state.CurrentSplit == null ? false : state.CurrentSplit.Name == arg;
} }
}), }),
}; };
static public readonly string[] EnableIfItems = EnableIfFactories.Select(e => e.text).ToArray(); static public readonly string[] EnableIfItems = EnableIfFactories.Select(e => e.text).ToArray();
static public readonly ListItem<MatchAction>[] MatchActions = { static public readonly ListItem<MatchAction>[] MatchActions = {
("Start", "Start", model => model.Start()), ("Start", "Start", model => model.Start()),
("Split", "Split", model => model.Split()), ("Split", "Split", model => model.Split()),
("Skip", "Skip Split", model => model.SkipSplit()), ("Skip", "Skip Split", model => model.SkipSplit()),
("Undo", "Undo Split", model => model.UndoSplit()), ("Undo", "Undo Split", model => model.UndoSplit()),
("Reset", "Reset", model => model.Reset()), ("Reset", "Reset", model => model.Reset()),
("Pause", "Pause", model => model.Pause()), ("Pause", "Pause", model => model.Pause()),
}; };
static public readonly string[] MatchActionItems = MatchActions.Select(e => e.text).ToArray(); static public readonly string[] MatchActionItems = MatchActions.Select(e => e.text).ToArray();
static public readonly ListItem<bool>[] ActionTimings = { static public readonly ListItem<bool>[] ActionTimings = {
("Posedge", "Posedge: First Match after unmatch", true), ("Posedge", "Posedge: First Match after unmatch", true),
("Negedge", "Negedge: First Unmatch after match", false), ("Negedge", "Negedge: First Unmatch after match", false),
}; };
static public readonly string[] ActionTimingItems = ActionTimings.Select(e => e.text).ToArray(); static public readonly string[] ActionTimingItems = ActionTimings.Select(e => e.text).ToArray();
static public readonly ListItem<MatchMethodFactory>[] MatchMethodFactories = { static public readonly ListItem<MatchMethodFactory>[] MatchMethodFactories = {
("COSINE", "1 - Cosine Similarity", timg => { ("COSINE", "1 - Cosine Similarity", timg => {
Mat[] bchs = timg.Split(); Mat[] bchs = timg.Split();
Mat mask = bchs[3]; Mat mask = bchs[3];
Array.Resize(ref bchs, 3); Array.Resize(ref bchs, 3);
Mat[] bimg = bchs.Select(m => (Mat)m.BitwiseAnd(mask)).ToArray(); Mat[] bimg = bchs.Select(m => (Mat)m.BitwiseAnd(mask)).ToArray();
var b1 = Math.Sqrt(bimg.Select(m => m.Norm(NormTypes.L2SQR, mask)).Sum()); var b1 = Math.Sqrt(bimg.Select(m => m.Norm(NormTypes.L2SQR, mask)).Sum());
return frame => { return frame => {
Mat[] fimg = frame.Split(); Mat[] fimg = frame.Split();
var f1 = Math.Sqrt(fimg.Select(m => m.Norm(NormTypes.L2SQR, mask)).Sum()); var f1 = Math.Sqrt(fimg.Select(m => m.Norm(NormTypes.L2SQR, mask)).Sum());
var fb = fimg.Zip(bimg, (mf, mb) => mf.Dot(mb)).Sum(); var fb = fimg.Zip(bimg, (mf, mb) => mf.Dot(mb)).Sum();
fimg.ForEach(m => m.Release()); fimg.ForEach(m => m.Release());
return 1-fb/f1/b1; return 1-fb/f1/b1;
}; };
}), }),
("SQDIFF_NORM", "Normalized Squared Difference", timg => { ("SQDIFF_NORM", "Normalized Squared Difference", timg => {
Mat[] bimg = timg.Split(); Mat[] bimg = timg.Split();
Mat mask = bimg[3]; Mat mask = bimg[3];
Array.Resize(ref bimg, 3); Array.Resize(ref bimg, 3);
var b1 = Math.Sqrt(bimg.Select(m => m.Norm(NormTypes.L2SQR, mask)).Sum()); var b1 = Math.Sqrt(bimg.Select(m => m.Norm(NormTypes.L2SQR, mask)).Sum());
return frame => { return frame => {
Mat[] fimg = frame.Split(); Mat[] fimg = frame.Split();
var f1 = Math.Sqrt(fimg.Select(m => m.Norm(NormTypes.L2SQR, mask)).Sum()); var f1 = Math.Sqrt(fimg.Select(m => m.Norm(NormTypes.L2SQR, mask)).Sum());
var d2 = fimg.Zip(bimg, (mf, mb) => Cv2.Norm(mf, mb, NormTypes.L2SQR, mask)).Sum(); var d2 = fimg.Zip(bimg, (mf, mb) => Cv2.Norm(mf, mb, NormTypes.L2SQR, mask)).Sum();
fimg.ForEach(m => m.Release()); fimg.ForEach(m => m.Release());
return d2/f1/b1; return d2/f1/b1;
}; };
}), }),
("V128_BINARY", "V128 Binary Classification: MAX(R,G,B)<128 or not", timg => { ("RMSE", "Root Mean Squared Error", timg => {
Mat bimg; Mat[] bimgs = timg.Split();
{ Mat bimg = new Mat();
Mat[] chs = timg.Split(); Mat mask = bimgs[3];
if (chs.Length == 3) { Array.Resize(ref bimgs, 3);
using (Mat v = RGB2V(chs)) Cv2.Merge(bimgs, bimg);
bimg = v.LessThan(128); var div = Math.Sqrt(3*bimg.Total())*255.0;
} else { return fimg => Math.Sqrt(Cv2.Norm(fimg, bimg, NormTypes.L2SQR, mask))/div;
bimg = chs[0].LessThan(128); }),
} ("V128_BINARY", "V128 Binary Classification: MAX(R,G,B)<128 or not", timg => {
chs.ForEach(m => m.Release()); Mat bimg;
} {
return frame => { Mat[] chs = timg.Split();
Mat[] chs = frame.Split(); if (chs.Length == 3) {
using (Mat v = RGB2V(chs)) { using (Mat v = RGB2V(chs))
chs.ForEach(ch => ch.Release()); bimg = v.LessThan(128);
using (Mat fimg = v.LessThan(128)) } else {
return Cv2.Mean(fimg.NotEquals(bimg)).ToDouble()/255.0; bimg = chs[0].LessThan(128);
} }
}; chs.ForEach(m => m.Release());
}), }
}; return frame => {
static public readonly string[] MatchMethodItems = MatchMethodFactories.Select(e => e.text).ToArray(); Mat[] chs = frame.Split();
using (Mat v = RGB2V(chs)) {
chs.ForEach(ch => ch.Release());
using (Mat fimg = v.LessThan(128))
return Cv2.Mean(fimg.NotEquals(bimg)).ToDouble()/255.0;
}
};
}),
};
static public readonly string[] MatchMethodItems = MatchMethodFactories.Select(e => e.text).ToArray();
static public Mat RGB2V(Mat[] chs) { static public Mat RGB2V(Mat[] chs) {
Mat m = new Mat(); Mat m = new Mat();
Cv2.Max(chs[0], chs[1], m); Cv2.Max(chs[0], chs[1], m);
Cv2.Max(m, chs[2], m); Cv2.Max(m, chs[2], m);
return m; return m;
} }
} }
} }

View file

@ -14,79 +14,86 @@ using SupExtension;
namespace LiveSplit.SupAutoSplit.UI { namespace LiveSplit.SupAutoSplit.UI {
public partial class Settings : UserControl { public partial class Settings : UserControl {
public int CaptureDevice = 0; // TODO public int CaptureDevice = 0; // TODO
public string WindowName = "supAutoSplit"; // TODO public string WindowName = "supAutoSplit"; // TODO
public List<TemplateSettings> TemplateSettings { get; set; } = new List<TemplateSettings>(); public List<TemplateSettings> TemplateSettings { get; set; } = new List<TemplateSettings>();
public Settings() { public Settings() {
InitializeComponent(); InitializeComponent();
} }
public XmlNode GetSettings(XmlDocument document) { public XmlNode GetSettings(XmlDocument document) {
var parent = document.CreateElement("Settings"); var parent = document.CreateElement("Settings");
CreateSettingsNode(document, parent); CreateSettingsNode(document, parent);
return parent; return parent;
} }
public int GetSettingsHashCode() { public int GetSettingsHashCode() {
return CreateSettingsNode(null, null); return CreateSettingsNode(null, null);
} }
public int CreateSettingsNode(XmlDocument document, XmlElement parent) { public int CreateSettingsNode(XmlDocument document, XmlElement parent) {
var hashCode = var hashCode =
SettingsHelper.CreateSetting(document, parent, "Version", "1.0.0"); SettingsHelper.CreateSetting(document, parent, "Version", "1.0.0");
// profile TODO // profile TODO
var profileRoot = document?.CreateElement("Profile", parent); var profileRoot = document?.CreateElement("Profile", parent);
SettingsHelper.CreateSetting(document, profileRoot, "Name", "SMS Any%"); SettingsHelper.CreateSetting(document, profileRoot, "Name", "SMS Any%");
// templates // templates
var templatesRoot = document?.CreateElement("Templates", profileRoot); var templatesRoot = document?.CreateElement("Templates", profileRoot);
foreach (var ts in TemplateSettings) { foreach (var ts in TemplateSettings) {
XmlElement templateParent = document?.CreateElement("Template", templatesRoot); XmlElement templateParent = document?.CreateElement("Template", templatesRoot);
hashCode ^= ts.CreateSettingsNode(document, templateParent); hashCode ^= ts.CreateSettingsNode(document, templateParent);
} }
// return // return
return hashCode; return hashCode;
} }
public void SetSettings(XmlNode settings) { public void SetSettings(XmlNode settings) {
if (settings == null) return; if (settings == null) return;
// profile // profile
var profileRoot = settings["Profile"]; var profileRoot = settings["Profile"];
if (profileRoot == null) return; if (profileRoot == null) return;
// template // template
var templatesRoot = profileRoot["Templates"]; var templatesRoot = profileRoot["Templates"];
if (templatesRoot == null) return; if (templatesRoot == null) return;
// reset RowStyles // reset RowStyles
var rs = tlpTemplates.RowStyles[0]; var rs = tlpTemplates.RowStyles[0];
tlpTemplates.RowStyles.Clear(); tlpTemplates.RowStyles.Clear();
tlpTemplates.RowStyles.Add(rs); tlpTemplates.RowStyles.Add(rs);
// remove UI // remove UI
foreach (var ts in TemplateSettings) { foreach (var ts in TemplateSettings) {
tlpTemplates.Controls.Remove(ts); tlpTemplates.Controls.Remove(ts);
} }
tlpTemplates.RowCount = 1; tlpTemplates.RowCount = 1;
// reinit TemplateSettings[] // reinit TemplateSettings[]
TemplateSettings.Clear(); TemplateSettings.Clear();
foreach (var templateParent in templatesRoot.ChildNodes) { foreach (var templateParent in templatesRoot.ChildNodes) {
AddTemplateSettings((XmlElement)templateParent); AddTemplateSettings((XmlElement)templateParent);
} }
} }
private void BtnAddTemplate_Click(object sender, EventArgs e) { private void BtnAddTemplate_Click(object sender, EventArgs e) {
AddTemplateSettings(null); AddTemplateSettings(null);
} }
private void AddTemplateSettings(XmlElement settings) { private void AddTemplateSettings(XmlElement settings) {
var irow = tlpTemplates.RowCount; var irow = tlpTemplates.RowCount;
tlpTemplates.RowCount = irow + 1; tlpTemplates.RowCount = irow + 1;
tlpTemplates.RowStyles.Add(new RowStyle(SizeType.AutoSize)); tlpTemplates.RowStyles.Insert(0, new RowStyle(SizeType.AutoSize));
var v = new TemplateSettings(settings, o => { var v = new TemplateSettings(settings, o => {
tlpTemplates.Controls.Remove(o); tlpTemplates.Controls.Remove(o);
tlpTemplates.RowCount = irow; var irowD = tlpTemplates.RowCount - 1;
tlpTemplates.RowStyles.RemoveAt(irow); tlpTemplates.RowCount = irowD;
TemplateSettings.Remove(o); tlpTemplates.RowStyles.RemoveAt(0); // remove 1 TemplateSettings RowStyle
}); TemplateSettings.Remove(o);
// tlpTemplates.RowStyles.Add(new RowStyle(SizeType.Absolute, v.Height)); // move button to the last row
// v.Width = tlpTemplates.Width; tlpTemplates.Controls.Remove(btnAddTemplate);
tlpTemplates.Controls.Add(v, 0, irow); tlpTemplates.Controls.Add(btnAddTemplate, 0, irowD - 1);
TemplateSettings.Add(v); });
} // move button to the last row
tlpTemplates.Controls.Remove(btnAddTemplate);
tlpTemplates.Controls.Add(btnAddTemplate, 0, irow);
// add new template view
tlpTemplates.Controls.Add(v, 0, irow - 1);
TemplateSettings.Add(v);
// TODO scroll to bottom
}
} }
} }

View file

@ -23,386 +23,435 @@
/// コード エディターで変更しないでください。 /// コード エディターで変更しないでください。
/// </summary> /// </summary>
private void InitializeComponent() { private void InitializeComponent() {
this.ofdTemplate = new System.Windows.Forms.OpenFileDialog(); this.components = new System.ComponentModel.Container();
this.gpbRoot = new System.Windows.Forms.GroupBox(); this.ofdTemplate = new System.Windows.Forms.OpenFileDialog();
this.tableLayoutPanel3 = new System.Windows.Forms.TableLayoutPanel(); this.gpbRoot = new System.Windows.Forms.GroupBox();
this.ttbThresholdNeg = new System.Windows.Forms.TextBox(); this.tableLayoutPanel3 = new System.Windows.Forms.TableLayoutPanel();
this.cbbEnableIf = new System.Windows.Forms.ComboBox(); this.label8 = new System.Windows.Forms.Label();
this.cbbActionTiming = new System.Windows.Forms.ComboBox(); this.ttbThresholdNeg = new System.Windows.Forms.TextBox();
this.label1 = new System.Windows.Forms.Label(); this.cbbEnableIf = new System.Windows.Forms.ComboBox();
this.ttbThreshold = new System.Windows.Forms.TextBox(); this.cbbActionTiming = new System.Windows.Forms.ComboBox();
this.label10 = new System.Windows.Forms.Label(); this.label1 = new System.Windows.Forms.Label();
this.label7 = new System.Windows.Forms.Label(); this.ttbThreshold = new System.Windows.Forms.TextBox();
this.label5 = new System.Windows.Forms.Label(); this.label10 = new System.Windows.Forms.Label();
this.label4 = new System.Windows.Forms.Label(); this.label7 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label(); this.label5 = new System.Windows.Forms.Label();
this.cbbAction = new System.Windows.Forms.ComboBox(); this.label4 = new System.Windows.Forms.Label();
this.ttbName = new System.Windows.Forms.TextBox(); this.label2 = new System.Windows.Forms.Label();
this.label9 = new System.Windows.Forms.Label(); this.cbbAction = new System.Windows.Forms.ComboBox();
this.cbbMethod = new System.Windows.Forms.ComboBox(); this.ttbName = new System.Windows.Forms.TextBox();
this.flowLayoutPanel3 = new System.Windows.Forms.FlowLayoutPanel(); this.label9 = new System.Windows.Forms.Label();
this.label12 = new System.Windows.Forms.Label(); this.cbbMethod = new System.Windows.Forms.ComboBox();
this.ttbOffsetX = new System.Windows.Forms.TextBox(); this.flowLayoutPanel3 = new System.Windows.Forms.FlowLayoutPanel();
this.label11 = new System.Windows.Forms.Label(); this.label12 = new System.Windows.Forms.Label();
this.ttbOffsetY = new System.Windows.Forms.TextBox(); this.ttbOffsetX = new System.Windows.Forms.TextBox();
this.label13 = new System.Windows.Forms.Label(); this.label11 = new System.Windows.Forms.Label();
this.btnImage = new System.Windows.Forms.Button(); this.ttbOffsetY = new System.Windows.Forms.TextBox();
this.ttbEnableIfArg = new System.Windows.Forms.TextBox(); this.label13 = new System.Windows.Forms.Label();
this.btnRemove = new System.Windows.Forms.Button(); this.btnImage = new System.Windows.Forms.Button();
this.label3 = new System.Windows.Forms.Label(); this.ttbEnableIfArg = new System.Windows.Forms.TextBox();
this.label6 = new System.Windows.Forms.Label(); this.btnRemove = new System.Windows.Forms.Button();
this.gpbRoot.SuspendLayout(); this.label3 = new System.Windows.Forms.Label();
this.tableLayoutPanel3.SuspendLayout(); this.label6 = new System.Windows.Forms.Label();
this.flowLayoutPanel3.SuspendLayout(); this.nudMatchCount = new System.Windows.Forms.NumericUpDown();
this.SuspendLayout(); this.templateSettingsBindingSource = new System.Windows.Forms.BindingSource(this.components);
// this.gpbRoot.SuspendLayout();
// ofdTemplate this.tableLayoutPanel3.SuspendLayout();
// this.flowLayoutPanel3.SuspendLayout();
this.ofdTemplate.Filter = "Image Files|*.bmp;*.pbm;*.pgm;*.ppm;*.sr;*.ras;*.jpeg;*.jpg;*.jpe;*.jp2;*.tiff;*." + ((System.ComponentModel.ISupportInitialize)(this.nudMatchCount)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.templateSettingsBindingSource)).BeginInit();
this.SuspendLayout();
//
// ofdTemplate
//
this.ofdTemplate.Filter = "Image Files|*.bmp;*.pbm;*.pgm;*.ppm;*.sr;*.ras;*.jpeg;*.jpg;*.jpe;*.jp2;*.tiff;*." +
"tif;*.png"; "tif;*.png";
// //
// gpbRoot // gpbRoot
// //
this.gpbRoot.AutoSize = true; this.gpbRoot.AutoSize = true;
this.gpbRoot.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; this.gpbRoot.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.gpbRoot.Controls.Add(this.tableLayoutPanel3); this.gpbRoot.Controls.Add(this.tableLayoutPanel3);
this.gpbRoot.DataBindings.Add(new System.Windows.Forms.Binding("Text", this, "TemplateTitle", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); this.gpbRoot.DataBindings.Add(new System.Windows.Forms.Binding("Text", this, "TemplateTitle", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
this.gpbRoot.Dock = System.Windows.Forms.DockStyle.Fill; this.gpbRoot.Dock = System.Windows.Forms.DockStyle.Fill;
this.gpbRoot.Location = new System.Drawing.Point(0, 0); this.gpbRoot.Location = new System.Drawing.Point(0, 0);
this.gpbRoot.Name = "gpbRoot"; this.gpbRoot.Name = "gpbRoot";
this.gpbRoot.Size = new System.Drawing.Size(434, 314); this.gpbRoot.Size = new System.Drawing.Size(434, 318);
this.gpbRoot.TabIndex = 16; this.gpbRoot.TabIndex = 16;
this.gpbRoot.TabStop = false; this.gpbRoot.TabStop = false;
this.gpbRoot.Text = "Template: "; this.gpbRoot.Text = "Template: ";
// //
// tableLayoutPanel3 // tableLayoutPanel3
// //
this.tableLayoutPanel3.ColumnCount = 3; this.tableLayoutPanel3.ColumnCount = 3;
this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 126F)); this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 126F));
this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel3.Controls.Add(this.ttbThresholdNeg, 1, 8); this.tableLayoutPanel3.Controls.Add(this.label8, 0, 9);
this.tableLayoutPanel3.Controls.Add(this.cbbEnableIf, 1, 1); this.tableLayoutPanel3.Controls.Add(this.ttbThresholdNeg, 1, 8);
this.tableLayoutPanel3.Controls.Add(this.cbbActionTiming, 1, 3); this.tableLayoutPanel3.Controls.Add(this.cbbEnableIf, 1, 1);
this.tableLayoutPanel3.Controls.Add(this.label1, 0, 2); this.tableLayoutPanel3.Controls.Add(this.cbbActionTiming, 1, 3);
this.tableLayoutPanel3.Controls.Add(this.ttbThreshold, 1, 7); this.tableLayoutPanel3.Controls.Add(this.label1, 0, 2);
this.tableLayoutPanel3.Controls.Add(this.label10, 0, 7); this.tableLayoutPanel3.Controls.Add(this.ttbThreshold, 1, 7);
this.tableLayoutPanel3.Controls.Add(this.label7, 0, 0); this.tableLayoutPanel3.Controls.Add(this.label10, 0, 7);
this.tableLayoutPanel3.Controls.Add(this.label5, 0, 5); this.tableLayoutPanel3.Controls.Add(this.label7, 0, 0);
this.tableLayoutPanel3.Controls.Add(this.label4, 0, 4); this.tableLayoutPanel3.Controls.Add(this.label5, 0, 5);
this.tableLayoutPanel3.Controls.Add(this.label2, 0, 1); this.tableLayoutPanel3.Controls.Add(this.label4, 0, 4);
this.tableLayoutPanel3.Controls.Add(this.cbbAction, 1, 2); this.tableLayoutPanel3.Controls.Add(this.label2, 0, 1);
this.tableLayoutPanel3.Controls.Add(this.ttbName, 1, 0); this.tableLayoutPanel3.Controls.Add(this.cbbAction, 1, 2);
this.tableLayoutPanel3.Controls.Add(this.label9, 0, 6); this.tableLayoutPanel3.Controls.Add(this.ttbName, 1, 0);
this.tableLayoutPanel3.Controls.Add(this.cbbMethod, 1, 6); this.tableLayoutPanel3.Controls.Add(this.label9, 0, 6);
this.tableLayoutPanel3.Controls.Add(this.flowLayoutPanel3, 1, 5); this.tableLayoutPanel3.Controls.Add(this.cbbMethod, 1, 6);
this.tableLayoutPanel3.Controls.Add(this.btnImage, 1, 4); this.tableLayoutPanel3.Controls.Add(this.flowLayoutPanel3, 1, 5);
this.tableLayoutPanel3.Controls.Add(this.ttbEnableIfArg, 2, 1); this.tableLayoutPanel3.Controls.Add(this.btnImage, 1, 4);
this.tableLayoutPanel3.Controls.Add(this.btnRemove, 2, 9); this.tableLayoutPanel3.Controls.Add(this.ttbEnableIfArg, 2, 1);
this.tableLayoutPanel3.Controls.Add(this.label3, 0, 3); this.tableLayoutPanel3.Controls.Add(this.btnRemove, 2, 10);
this.tableLayoutPanel3.Controls.Add(this.label6, 0, 8); this.tableLayoutPanel3.Controls.Add(this.label3, 0, 3);
this.tableLayoutPanel3.Dock = System.Windows.Forms.DockStyle.Fill; this.tableLayoutPanel3.Controls.Add(this.label6, 0, 8);
this.tableLayoutPanel3.Location = new System.Drawing.Point(3, 18); this.tableLayoutPanel3.Controls.Add(this.nudMatchCount, 1, 9);
this.tableLayoutPanel3.Name = "tableLayoutPanel3"; this.tableLayoutPanel3.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel3.RowCount = 10; this.tableLayoutPanel3.Location = new System.Drawing.Point(3, 15);
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel3.Name = "tableLayoutPanel3";
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel3.RowCount = 11;
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel3.Size = new System.Drawing.Size(428, 293); this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel3.TabIndex = 2; this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle());
// this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
// ttbThresholdNeg this.tableLayoutPanel3.Size = new System.Drawing.Size(428, 300);
// this.tableLayoutPanel3.TabIndex = 2;
this.tableLayoutPanel3.SetColumnSpan(this.ttbThresholdNeg, 2); //
this.ttbThresholdNeg.DataBindings.Add(new System.Windows.Forms.Binding("Text", this, "MatchThresholdNegStr", true)); // label8
this.ttbThresholdNeg.Dock = System.Windows.Forms.DockStyle.Fill; //
this.ttbThresholdNeg.Location = new System.Drawing.Point(97, 239); this.label8.AutoSize = true;
this.ttbThresholdNeg.Name = "ttbThresholdNeg"; this.label8.Location = new System.Drawing.Point(3, 253);
this.ttbThresholdNeg.Size = new System.Drawing.Size(328, 22); this.label8.Margin = new System.Windows.Forms.Padding(3);
this.ttbThresholdNeg.TabIndex = 28; this.label8.Name = "label8";
// this.label8.Padding = new System.Windows.Forms.Padding(3);
// cbbEnableIf this.label8.Size = new System.Drawing.Size(78, 18);
// this.label8.TabIndex = 29;
this.cbbEnableIf.Dock = System.Windows.Forms.DockStyle.Fill; this.label8.Text = "Match Count:";
this.cbbEnableIf.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; //
this.cbbEnableIf.FormattingEnabled = true; // ttbThresholdNeg
this.cbbEnableIf.Location = new System.Drawing.Point(97, 31); //
this.cbbEnableIf.Name = "cbbEnableIf"; this.tableLayoutPanel3.SetColumnSpan(this.ttbThresholdNeg, 2);
this.cbbEnableIf.Size = new System.Drawing.Size(120, 20); this.ttbThresholdNeg.DataBindings.Add(new System.Windows.Forms.Binding("Text", this, "MatchThresholdNegStr", true));
this.cbbEnableIf.TabIndex = 26; this.ttbThresholdNeg.Dock = System.Windows.Forms.DockStyle.Fill;
// this.ttbThresholdNeg.Location = new System.Drawing.Point(105, 228);
// cbbActionTiming this.ttbThresholdNeg.Name = "ttbThresholdNeg";
// this.ttbThresholdNeg.Size = new System.Drawing.Size(320, 19);
this.tableLayoutPanel3.SetColumnSpan(this.cbbActionTiming, 2); this.ttbThresholdNeg.TabIndex = 28;
this.cbbActionTiming.Dock = System.Windows.Forms.DockStyle.Fill; //
this.cbbActionTiming.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; // cbbEnableIf
this.cbbActionTiming.FormattingEnabled = true; //
this.cbbActionTiming.Location = new System.Drawing.Point(97, 85); this.cbbEnableIf.Dock = System.Windows.Forms.DockStyle.Fill;
this.cbbActionTiming.Name = "cbbActionTiming"; this.cbbEnableIf.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.cbbActionTiming.Size = new System.Drawing.Size(328, 20); this.cbbEnableIf.FormattingEnabled = true;
this.cbbActionTiming.TabIndex = 25; this.cbbEnableIf.Location = new System.Drawing.Point(105, 28);
// this.cbbEnableIf.Name = "cbbEnableIf";
// label1 this.cbbEnableIf.Size = new System.Drawing.Size(120, 20);
// this.cbbEnableIf.TabIndex = 26;
this.label1.AutoSize = true; //
this.label1.Location = new System.Drawing.Point(3, 59); // cbbActionTiming
this.label1.Margin = new System.Windows.Forms.Padding(3); //
this.label1.Name = "label1"; this.tableLayoutPanel3.SetColumnSpan(this.cbbActionTiming, 2);
this.label1.Padding = new System.Windows.Forms.Padding(3); this.cbbActionTiming.Dock = System.Windows.Forms.DockStyle.Fill;
this.label1.Size = new System.Drawing.Size(45, 18); this.cbbActionTiming.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.label1.TabIndex = 22; this.cbbActionTiming.FormattingEnabled = true;
this.label1.Text = "Action:"; this.cbbActionTiming.Location = new System.Drawing.Point(105, 80);
// this.cbbActionTiming.Name = "cbbActionTiming";
// ttbThreshold this.cbbActionTiming.Size = new System.Drawing.Size(320, 20);
// this.cbbActionTiming.TabIndex = 25;
this.tableLayoutPanel3.SetColumnSpan(this.ttbThreshold, 2); //
this.ttbThreshold.DataBindings.Add(new System.Windows.Forms.Binding("Text", this, "MatchThresholdStr", true)); // label1
this.ttbThreshold.Dock = System.Windows.Forms.DockStyle.Fill; //
this.ttbThreshold.Location = new System.Drawing.Point(97, 211); this.label1.AutoSize = true;
this.ttbThreshold.Name = "ttbThreshold"; this.label1.Location = new System.Drawing.Point(3, 54);
this.ttbThreshold.Size = new System.Drawing.Size(328, 22); this.label1.Margin = new System.Windows.Forms.Padding(3);
this.ttbThreshold.TabIndex = 8; this.label1.Name = "label1";
// this.label1.Padding = new System.Windows.Forms.Padding(3);
// label10 this.label1.Size = new System.Drawing.Size(46, 18);
// this.label1.TabIndex = 22;
this.label10.AutoSize = true; this.label1.Text = "Action:";
this.label10.Location = new System.Drawing.Point(3, 211); //
this.label10.Margin = new System.Windows.Forms.Padding(3); // ttbThreshold
this.label10.Name = "label10"; //
this.label10.Padding = new System.Windows.Forms.Padding(3); this.tableLayoutPanel3.SetColumnSpan(this.ttbThreshold, 2);
this.label10.Size = new System.Drawing.Size(87, 18); this.ttbThreshold.DataBindings.Add(new System.Windows.Forms.Binding("Text", this, "MatchThresholdStr", true));
this.label10.TabIndex = 17; this.ttbThreshold.Dock = System.Windows.Forms.DockStyle.Fill;
this.label10.Text = "Max Difference:"; this.ttbThreshold.Location = new System.Drawing.Point(105, 203);
// this.ttbThreshold.Name = "ttbThreshold";
// label7 this.ttbThreshold.Size = new System.Drawing.Size(320, 19);
// this.ttbThreshold.TabIndex = 8;
this.label7.AutoSize = true; //
this.label7.Location = new System.Drawing.Point(3, 3); // label10
this.label7.Margin = new System.Windows.Forms.Padding(3); //
this.label7.Name = "label7"; this.label10.AutoSize = true;
this.label7.Padding = new System.Windows.Forms.Padding(3); this.label10.Location = new System.Drawing.Point(3, 203);
this.label7.Size = new System.Drawing.Size(41, 18); this.label10.Margin = new System.Windows.Forms.Padding(3);
this.label7.TabIndex = 14; this.label10.Name = "label10";
this.label7.Text = "Name:"; this.label10.Padding = new System.Windows.Forms.Padding(3);
// this.label10.Size = new System.Drawing.Size(91, 18);
// label5 this.label10.TabIndex = 17;
// this.label10.Text = "Max Difference:";
this.label5.AutoSize = true; //
this.label5.Location = new System.Drawing.Point(3, 157); // label7
this.label5.Margin = new System.Windows.Forms.Padding(3); //
this.label5.Name = "label5"; this.label7.AutoSize = true;
this.label5.Padding = new System.Windows.Forms.Padding(3); this.label7.Location = new System.Drawing.Point(3, 3);
this.label5.Size = new System.Drawing.Size(88, 18); this.label7.Margin = new System.Windows.Forms.Padding(3);
this.label5.TabIndex = 6; this.label7.Name = "label7";
this.label5.Text = "Template Offset:"; this.label7.Padding = new System.Windows.Forms.Padding(3);
// this.label7.Size = new System.Drawing.Size(42, 18);
// label4 this.label7.TabIndex = 14;
// this.label7.Text = "Name:";
this.label4.AutoSize = true; //
this.label4.Location = new System.Drawing.Point(3, 111); // label5
this.label4.Margin = new System.Windows.Forms.Padding(3); //
this.label4.Name = "label4"; this.label5.AutoSize = true;
this.label4.Padding = new System.Windows.Forms.Padding(3); this.label5.Location = new System.Drawing.Point(3, 152);
this.label4.Size = new System.Drawing.Size(57, 18); this.label5.Margin = new System.Windows.Forms.Padding(3);
this.label4.TabIndex = 5; this.label5.Name = "label5";
this.label4.Text = "Template:"; this.label5.Padding = new System.Windows.Forms.Padding(3);
// this.label5.Size = new System.Drawing.Size(96, 18);
// label2 this.label5.TabIndex = 6;
// this.label5.Text = "Template Offset:";
this.label2.AutoSize = true; //
this.label2.Location = new System.Drawing.Point(3, 31); // label4
this.label2.Margin = new System.Windows.Forms.Padding(3); //
this.label2.Name = "label2"; this.label4.AutoSize = true;
this.label2.Padding = new System.Windows.Forms.Padding(3); this.label4.Location = new System.Drawing.Point(3, 106);
this.label2.Size = new System.Drawing.Size(57, 18); this.label4.Margin = new System.Windows.Forms.Padding(3);
this.label2.TabIndex = 4; this.label4.Name = "label4";
this.label2.Text = "Enable If:"; this.label4.Padding = new System.Windows.Forms.Padding(3);
// this.label4.Size = new System.Drawing.Size(60, 18);
// cbbAction this.label4.TabIndex = 5;
// this.label4.Text = "Template:";
this.tableLayoutPanel3.SetColumnSpan(this.cbbAction, 2); //
this.cbbAction.Dock = System.Windows.Forms.DockStyle.Fill; // label2
this.cbbAction.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; //
this.cbbAction.FormattingEnabled = true; this.label2.AutoSize = true;
this.cbbAction.Location = new System.Drawing.Point(97, 59); this.label2.Location = new System.Drawing.Point(3, 28);
this.cbbAction.Name = "cbbAction"; this.label2.Margin = new System.Windows.Forms.Padding(3);
this.cbbAction.Size = new System.Drawing.Size(328, 20); this.label2.Name = "label2";
this.cbbAction.TabIndex = 3; this.label2.Padding = new System.Windows.Forms.Padding(3);
// this.label2.Size = new System.Drawing.Size(58, 18);
// ttbName this.label2.TabIndex = 4;
// this.label2.Text = "Enable If:";
this.tableLayoutPanel3.SetColumnSpan(this.ttbName, 2); //
this.ttbName.DataBindings.Add(new System.Windows.Forms.Binding("Text", this, "TemplateName", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); // cbbAction
this.ttbName.Dock = System.Windows.Forms.DockStyle.Fill; //
this.ttbName.Location = new System.Drawing.Point(97, 3); this.tableLayoutPanel3.SetColumnSpan(this.cbbAction, 2);
this.ttbName.Name = "ttbName"; this.cbbAction.Dock = System.Windows.Forms.DockStyle.Fill;
this.ttbName.Size = new System.Drawing.Size(328, 22); this.cbbAction.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.ttbName.TabIndex = 1; this.cbbAction.FormattingEnabled = true;
// this.cbbAction.Location = new System.Drawing.Point(105, 54);
// label9 this.cbbAction.Name = "cbbAction";
// this.cbbAction.Size = new System.Drawing.Size(320, 20);
this.label9.AutoSize = true; this.cbbAction.TabIndex = 3;
this.label9.Location = new System.Drawing.Point(3, 185); //
this.label9.Margin = new System.Windows.Forms.Padding(3); // ttbName
this.label9.Name = "label9"; //
this.label9.Padding = new System.Windows.Forms.Padding(3); this.tableLayoutPanel3.SetColumnSpan(this.ttbName, 2);
this.label9.Size = new System.Drawing.Size(82, 18); this.ttbName.DataBindings.Add(new System.Windows.Forms.Binding("Text", this, "TemplateName", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
this.label9.TabIndex = 16; this.ttbName.Dock = System.Windows.Forms.DockStyle.Fill;
this.label9.Text = "Match Method:"; this.ttbName.Location = new System.Drawing.Point(105, 3);
// this.ttbName.Name = "ttbName";
// cbbMethod this.ttbName.Size = new System.Drawing.Size(320, 19);
// this.ttbName.TabIndex = 1;
this.tableLayoutPanel3.SetColumnSpan(this.cbbMethod, 2); //
this.cbbMethod.Dock = System.Windows.Forms.DockStyle.Fill; // label9
this.cbbMethod.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; //
this.cbbMethod.FormattingEnabled = true; this.label9.AutoSize = true;
this.cbbMethod.Location = new System.Drawing.Point(97, 185); this.label9.Location = new System.Drawing.Point(3, 177);
this.cbbMethod.Name = "cbbMethod"; this.label9.Margin = new System.Windows.Forms.Padding(3);
this.cbbMethod.Size = new System.Drawing.Size(328, 20); this.label9.Name = "label9";
this.cbbMethod.TabIndex = 7; this.label9.Padding = new System.Windows.Forms.Padding(3);
// this.label9.Size = new System.Drawing.Size(85, 18);
// flowLayoutPanel3 this.label9.TabIndex = 16;
// this.label9.Text = "Match Method:";
this.flowLayoutPanel3.AutoSize = true; //
this.tableLayoutPanel3.SetColumnSpan(this.flowLayoutPanel3, 2); // cbbMethod
this.flowLayoutPanel3.Controls.Add(this.label12); //
this.flowLayoutPanel3.Controls.Add(this.ttbOffsetX); this.tableLayoutPanel3.SetColumnSpan(this.cbbMethod, 2);
this.flowLayoutPanel3.Controls.Add(this.label11); this.cbbMethod.Dock = System.Windows.Forms.DockStyle.Fill;
this.flowLayoutPanel3.Controls.Add(this.ttbOffsetY); this.cbbMethod.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.flowLayoutPanel3.Controls.Add(this.label13); this.cbbMethod.FormattingEnabled = true;
this.flowLayoutPanel3.Dock = System.Windows.Forms.DockStyle.Fill; this.cbbMethod.Location = new System.Drawing.Point(105, 177);
this.flowLayoutPanel3.Location = new System.Drawing.Point(94, 154); this.cbbMethod.Name = "cbbMethod";
this.flowLayoutPanel3.Margin = new System.Windows.Forms.Padding(0); this.cbbMethod.Size = new System.Drawing.Size(320, 20);
this.flowLayoutPanel3.Name = "flowLayoutPanel3"; this.cbbMethod.TabIndex = 7;
this.flowLayoutPanel3.Size = new System.Drawing.Size(334, 28); //
this.flowLayoutPanel3.TabIndex = 18; // flowLayoutPanel3
// //
// label12 this.flowLayoutPanel3.AutoSize = true;
// this.tableLayoutPanel3.SetColumnSpan(this.flowLayoutPanel3, 2);
this.label12.Anchor = System.Windows.Forms.AnchorStyles.Left; this.flowLayoutPanel3.Controls.Add(this.label12);
this.label12.AutoSize = true; this.flowLayoutPanel3.Controls.Add(this.ttbOffsetX);
this.label12.Location = new System.Drawing.Point(3, 8); this.flowLayoutPanel3.Controls.Add(this.label11);
this.label12.Margin = new System.Windows.Forms.Padding(3, 3, 0, 3); this.flowLayoutPanel3.Controls.Add(this.ttbOffsetY);
this.label12.Name = "label12"; this.flowLayoutPanel3.Controls.Add(this.label13);
this.label12.Size = new System.Drawing.Size(9, 12); this.flowLayoutPanel3.Dock = System.Windows.Forms.DockStyle.Fill;
this.label12.TabIndex = 19; this.flowLayoutPanel3.Location = new System.Drawing.Point(102, 149);
this.label12.Text = "("; this.flowLayoutPanel3.Margin = new System.Windows.Forms.Padding(0);
// this.flowLayoutPanel3.Name = "flowLayoutPanel3";
// ttbOffsetX this.flowLayoutPanel3.Size = new System.Drawing.Size(326, 25);
// this.flowLayoutPanel3.TabIndex = 18;
this.ttbOffsetX.DataBindings.Add(new System.Windows.Forms.Binding("Text", this, "ImageOffsetXStr", true)); //
this.ttbOffsetX.Location = new System.Drawing.Point(15, 3); // label12
this.ttbOffsetX.Name = "ttbOffsetX"; //
this.ttbOffsetX.Size = new System.Drawing.Size(48, 22); this.label12.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.ttbOffsetX.TabIndex = 5; this.label12.AutoSize = true;
// this.label12.Location = new System.Drawing.Point(3, 6);
// label11 this.label12.Margin = new System.Windows.Forms.Padding(3, 3, 0, 3);
// this.label12.Name = "label12";
this.label11.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.label12.Size = new System.Drawing.Size(9, 12);
this.label11.AutoSize = true; this.label12.TabIndex = 19;
this.label11.Location = new System.Drawing.Point(66, 13); this.label12.Text = "(";
this.label11.Margin = new System.Windows.Forms.Padding(0, 3, 0, 3); //
this.label11.Name = "label11"; // ttbOffsetX
this.label11.Size = new System.Drawing.Size(11, 12); //
this.label11.TabIndex = 17; this.ttbOffsetX.DataBindings.Add(new System.Windows.Forms.Binding("Text", this, "ImageOffsetXStr", true));
this.label11.Text = ", "; this.ttbOffsetX.Location = new System.Drawing.Point(15, 3);
// this.ttbOffsetX.Name = "ttbOffsetX";
// ttbOffsetY this.ttbOffsetX.Size = new System.Drawing.Size(48, 19);
// this.ttbOffsetX.TabIndex = 5;
this.ttbOffsetY.DataBindings.Add(new System.Windows.Forms.Binding("Text", this, "ImageOffsetYStr", true)); //
this.ttbOffsetY.Location = new System.Drawing.Point(80, 3); // label11
this.ttbOffsetY.Name = "ttbOffsetY"; //
this.ttbOffsetY.Size = new System.Drawing.Size(48, 22); this.label11.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.ttbOffsetY.TabIndex = 6; this.label11.AutoSize = true;
// this.label11.Location = new System.Drawing.Point(66, 10);
// label13 this.label11.Margin = new System.Windows.Forms.Padding(0, 3, 0, 3);
// this.label11.Name = "label11";
this.label13.Anchor = System.Windows.Forms.AnchorStyles.Left; this.label11.Size = new System.Drawing.Size(11, 12);
this.label13.AutoSize = true; this.label11.TabIndex = 17;
this.label13.Location = new System.Drawing.Point(131, 8); this.label11.Text = ", ";
this.label13.Margin = new System.Windows.Forms.Padding(0, 3, 3, 3); //
this.label13.Name = "label13"; // ttbOffsetY
this.label13.Size = new System.Drawing.Size(9, 12); //
this.label13.TabIndex = 20; this.ttbOffsetY.DataBindings.Add(new System.Windows.Forms.Binding("Text", this, "ImageOffsetYStr", true));
this.label13.Text = ")"; this.ttbOffsetY.Location = new System.Drawing.Point(80, 3);
// this.ttbOffsetY.Name = "ttbOffsetY";
// btnImage this.ttbOffsetY.Size = new System.Drawing.Size(48, 19);
// this.ttbOffsetY.TabIndex = 6;
this.btnImage.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch; //
this.tableLayoutPanel3.SetColumnSpan(this.btnImage, 2); // label13
this.btnImage.Location = new System.Drawing.Point(97, 111); //
this.btnImage.Name = "btnImage"; this.label13.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.btnImage.Size = new System.Drawing.Size(40, 40); this.label13.AutoSize = true;
this.btnImage.TabIndex = 4; this.label13.Location = new System.Drawing.Point(131, 6);
this.btnImage.UseVisualStyleBackColor = true; this.label13.Margin = new System.Windows.Forms.Padding(0, 3, 3, 3);
this.btnImage.Click += new System.EventHandler(this.BtnTemplate_Click); this.label13.Name = "label13";
// this.label13.Size = new System.Drawing.Size(9, 12);
// ttbEnableIfArg this.label13.TabIndex = 20;
// this.label13.Text = ")";
this.ttbEnableIfArg.DataBindings.Add(new System.Windows.Forms.Binding("Text", this, "EnableIfArg", true)); //
this.ttbEnableIfArg.Dock = System.Windows.Forms.DockStyle.Fill; // btnImage
this.ttbEnableIfArg.Location = new System.Drawing.Point(223, 31); //
this.ttbEnableIfArg.Name = "ttbEnableIfArg"; this.btnImage.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;
this.ttbEnableIfArg.Size = new System.Drawing.Size(202, 22); this.tableLayoutPanel3.SetColumnSpan(this.btnImage, 2);
this.ttbEnableIfArg.TabIndex = 2; this.btnImage.Location = new System.Drawing.Point(105, 106);
// this.btnImage.Name = "btnImage";
// btnRemove this.btnImage.Size = new System.Drawing.Size(40, 40);
// this.btnImage.TabIndex = 4;
this.btnRemove.AutoSize = true; this.btnImage.UseVisualStyleBackColor = true;
this.btnRemove.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; this.btnImage.Click += new System.EventHandler(this.BtnTemplate_Click);
this.btnRemove.Dock = System.Windows.Forms.DockStyle.Right; //
this.btnRemove.Location = new System.Drawing.Point(325, 267); // ttbEnableIfArg
this.btnRemove.Name = "btnRemove"; //
this.btnRemove.Size = new System.Drawing.Size(100, 23); this.ttbEnableIfArg.DataBindings.Add(new System.Windows.Forms.Binding("Text", this, "EnableIfArg", true));
this.btnRemove.TabIndex = 23; this.ttbEnableIfArg.Dock = System.Windows.Forms.DockStyle.Fill;
this.btnRemove.TabStop = false; this.ttbEnableIfArg.Location = new System.Drawing.Point(231, 28);
this.btnRemove.Text = "Remove Template"; this.ttbEnableIfArg.Name = "ttbEnableIfArg";
this.btnRemove.UseVisualStyleBackColor = true; this.ttbEnableIfArg.Size = new System.Drawing.Size(194, 19);
this.btnRemove.Click += new System.EventHandler(this.BtnRemove_Click); this.ttbEnableIfArg.TabIndex = 2;
// //
// label3 // btnRemove
// //
this.label3.AutoSize = true; this.btnRemove.AutoSize = true;
this.label3.Location = new System.Drawing.Point(3, 85); this.btnRemove.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.label3.Margin = new System.Windows.Forms.Padding(3); this.btnRemove.Dock = System.Windows.Forms.DockStyle.Right;
this.label3.Name = "label3"; this.btnRemove.Location = new System.Drawing.Point(318, 278);
this.label3.Padding = new System.Windows.Forms.Padding(3); this.btnRemove.Name = "btnRemove";
this.label3.Size = new System.Drawing.Size(82, 18); this.btnRemove.Size = new System.Drawing.Size(107, 19);
this.label3.TabIndex = 24; this.btnRemove.TabIndex = 23;
this.label3.Text = "Action Timing:"; this.btnRemove.TabStop = false;
// this.btnRemove.Text = "Remove Template";
// label6 this.btnRemove.UseVisualStyleBackColor = true;
// this.btnRemove.Click += new System.EventHandler(this.BtnRemove_Click);
this.label6.AutoSize = true; //
this.label6.Location = new System.Drawing.Point(3, 239); // label3
this.label6.Margin = new System.Windows.Forms.Padding(3); //
this.label6.Name = "label6"; this.label3.AutoSize = true;
this.label6.Padding = new System.Windows.Forms.Padding(3); this.label3.Location = new System.Drawing.Point(3, 80);
this.label6.Size = new System.Drawing.Size(88, 18); this.label3.Margin = new System.Windows.Forms.Padding(3);
this.label6.TabIndex = 27; this.label3.Name = "label3";
this.label6.Text = "Ready Min Diff:"; this.label3.Padding = new System.Windows.Forms.Padding(3);
// this.label3.Size = new System.Drawing.Size(84, 18);
// TemplateSettings this.label3.TabIndex = 24;
// this.label3.Text = "Action Timing:";
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); //
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; // label6
this.Controls.Add(this.gpbRoot); //
this.Name = "TemplateSettings"; this.label6.AutoSize = true;
this.Size = new System.Drawing.Size(434, 314); this.label6.Location = new System.Drawing.Point(3, 228);
this.gpbRoot.ResumeLayout(false); this.label6.Margin = new System.Windows.Forms.Padding(3);
this.tableLayoutPanel3.ResumeLayout(false); this.label6.Name = "label6";
this.tableLayoutPanel3.PerformLayout(); this.label6.Padding = new System.Windows.Forms.Padding(3);
this.flowLayoutPanel3.ResumeLayout(false); this.label6.Size = new System.Drawing.Size(90, 18);
this.flowLayoutPanel3.PerformLayout(); this.label6.TabIndex = 27;
this.ResumeLayout(false); this.label6.Text = "Ready Min Diff:";
this.PerformLayout(); //
// nudMatchCount
//
this.nudMatchCount.Location = new System.Drawing.Point(105, 253);
this.nudMatchCount.Maximum = new decimal(new int[] {
2147483647,
0,
0,
0});
this.nudMatchCount.Minimum = new decimal(new int[] {
1,
0,
0,
0});
this.nudMatchCount.Name = "nudMatchCount";
this.nudMatchCount.Size = new System.Drawing.Size(60, 19);
this.nudMatchCount.TabIndex = 30;
this.nudMatchCount.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
this.nudMatchCount.Value = new decimal(new int[] {
1,
0,
0,
0});
//
// templateSettingsBindingSource
//
this.templateSettingsBindingSource.DataSource = typeof(LiveSplit.SupAutoSplit.UI.TemplateSettings);
//
// TemplateSettings
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.gpbRoot);
this.Name = "TemplateSettings";
this.Size = new System.Drawing.Size(434, 318);
this.gpbRoot.ResumeLayout(false);
this.tableLayoutPanel3.ResumeLayout(false);
this.tableLayoutPanel3.PerformLayout();
this.flowLayoutPanel3.ResumeLayout(false);
this.flowLayoutPanel3.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.nudMatchCount)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.templateSettingsBindingSource)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
} }
@ -435,5 +484,8 @@
private System.Windows.Forms.ComboBox cbbEnableIf; private System.Windows.Forms.ComboBox cbbEnableIf;
private System.Windows.Forms.TextBox ttbThresholdNeg; private System.Windows.Forms.TextBox ttbThresholdNeg;
private System.Windows.Forms.Label label6; private System.Windows.Forms.Label label6;
private System.Windows.Forms.Label label8;
private System.Windows.Forms.NumericUpDown nudMatchCount;
private System.Windows.Forms.BindingSource templateSettingsBindingSource;
} }
} }

View file

@ -20,163 +20,169 @@ namespace LiveSplit.SupAutoSplit.UI {
using MatchMethodFactory = Func<Mat, Func<Mat, double>>; using MatchMethodFactory = Func<Mat, Func<Mat, double>>;
public partial class TemplateSettings : UserControl { public partial class TemplateSettings : UserControl {
internal Action<TemplateSettings> RemoveHandler; internal Action<TemplateSettings> RemoveHandler;
#region Parameters #region Parameters
public string TemplateName { get; set; } public string TemplateName { get; set; }
public string TemplateTitle => $"Template: {TemplateName}"; public string TemplateTitle => $"Template: {TemplateName}";
public int EnableIfISel { get; set; } = 0; public int EnableIfISel { get; set; } = 0;
public string EnableIfArg { get; set; } public string EnableIfArg { get; set; }
private ListItem<EnableIfFactory> EnableIfSel => MatchTemplate.EnableIfFactories[EnableIfISel]; private ListItem<EnableIfFactory> EnableIfSel => MatchTemplate.EnableIfFactories[EnableIfISel];
private bool IsActionStart => matchActionISel == 0; // start private bool IsActionStart => matchActionISel == 0; // start
public Predicate<LiveSplitState> EnableIf => IsActionStart ? (state => state.CurrentSplitIndex == -1): EnableIfSel.value(EnableIfArg); public Predicate<LiveSplitState> EnableIf => IsActionStart ? (state => state.CurrentSplitIndex == -1) : EnableIfSel.value(EnableIfArg);
private int matchActionISel; private int matchActionISel;
public int MatchActionISel { public int MatchActionISel {
get => matchActionISel; get => matchActionISel;
set { set {
matchActionISel = value; matchActionISel = value;
// Start => Disable Arg // Start => Disable Arg
cbbEnableIf.Enabled = ttbEnableIfArg.Enabled = !IsActionStart; cbbEnableIf.Enabled = ttbEnableIfArg.Enabled = !IsActionStart;
} }
} }
private ListItem<MatchAction> MatchActionSel => MatchTemplate.MatchActions[MatchActionISel]; private ListItem<MatchAction> MatchActionSel => MatchTemplate.MatchActions[MatchActionISel];
public MatchAction MatchAction => MatchActionSel.value; public MatchAction MatchAction => MatchActionSel.value;
public int ActionTimingISel { get; set; } = 1; public int ActionTimingISel { get; set; } = 1;
private ListItem<bool> ActionTimingSel => MatchTemplate.ActionTimings[ActionTimingISel]; private ListItem<bool> ActionTimingSel => MatchTemplate.ActionTimings[ActionTimingISel];
public bool IsActionOnPosedge => ActionTimingSel.value; public bool IsActionOnPosedge => ActionTimingSel.value;
private string _imagePath; private string _imagePath;
public string ImagePath { public string ImagePath {
get => _imagePath; get => _imagePath;
set { set {
try { try {
if (value != "") { if (value != "") {
var img = Image.FromFile(value); var img = Image.FromFile(value);
var h0 = btnImage.Height; var h0 = btnImage.Height;
var h = Math.Max(11, Math.Min(66, img.Height)); var h = Math.Max(11, Math.Min(66, img.Height));
btnImage.Height = h; btnImage.Height = h;
btnImage.Width = h * img.Width / img.Height; btnImage.Width = h * img.Width / img.Height;
btnImage.BackgroundImage = img; btnImage.BackgroundImage = img;
// adjust this.Height // adjust this.Height
Height += h - h0; Height += h - h0;
} }
_imagePath = value; _imagePath = value;
} catch { } catch {
_imagePath = ""; _imagePath = "";
} }
} }
} }
private int ImageOffsetX; private int ImageOffsetX;
private int ImageOffsetY; private int ImageOffsetY;
public string ImageOffsetXStr { public string ImageOffsetXStr {
get => ImageOffsetX.ToString(); get => ImageOffsetX.ToString();
set => int.TryParse(value, out ImageOffsetX); set => int.TryParse(value, out ImageOffsetX);
} }
public string ImageOffsetYStr { public string ImageOffsetYStr {
get => ImageOffsetY.ToString(); get => ImageOffsetY.ToString();
set => int.TryParse(value, out ImageOffsetY); set => int.TryParse(value, out ImageOffsetY);
} }
public OpenCvSharp.Point ImageOffset => new OpenCvSharp.Point(ImageOffsetX, ImageOffsetY); public OpenCvSharp.Point ImageOffset => new OpenCvSharp.Point(ImageOffsetX, ImageOffsetY);
public int MatchMethodISel { get; set; } public int MatchMethodISel { get; set; }
private ListItem<MatchMethodFactory> MatchMethodSel => MatchTemplate.MatchMethodFactories[MatchMethodISel]; private ListItem<MatchMethodFactory> MatchMethodSel => MatchTemplate.MatchMethodFactories[MatchMethodISel];
public MatchMethodFactory MatchMethodFactory => MatchMethodSel.value; public MatchMethodFactory MatchMethodFactory => MatchMethodSel.value;
private double matchThreshold; private double matchThreshold;
public double MatchThreshold => matchThreshold; public double MatchThreshold => matchThreshold;
public string MatchThresholdStr { public string MatchThresholdStr {
get => MatchThreshold.ToString(); get => MatchThreshold.ToString();
set => double.TryParse(value, out matchThreshold); set => double.TryParse(value, out matchThreshold);
} }
private double matchThresholdNeg; private double matchThresholdNeg;
public double MatchThresholdNeg => matchThresholdNeg; public double MatchThresholdNeg => matchThresholdNeg;
public string MatchThresholdNegStr { public string MatchThresholdNegStr {
get => MatchThresholdNeg.ToString(); get => MatchThresholdNeg.ToString();
set => double.TryParse(value, out matchThresholdNeg); set => double.TryParse(value, out matchThresholdNeg);
} }
#endregion
public TemplateSettings(XmlElement settings, Action<TemplateSettings> removeHandler) { public int MatchCount { get; set; }
RemoveHandler = removeHandler; #endregion
InitializeComponent(); public TemplateSettings(XmlElement settings, Action<TemplateSettings> removeHandler) {
SetSettings(settings); RemoveHandler = removeHandler;
cbbEnableIf.DataSource = MatchTemplate.EnableIfItems; InitializeComponent();
cbbEnableIf.DataBindings.Add("SelectedIndex", this, "EnableIfISel", false, DataSourceUpdateMode.OnPropertyChanged); SetSettings(settings);
cbbAction.DataSource = MatchTemplate.MatchActionItems;
cbbAction.DataBindings.Add("SelectedIndex", this, "MatchActionISel", false, DataSourceUpdateMode.OnPropertyChanged);
cbbActionTiming.DataSource = MatchTemplate.ActionTimingItems;
cbbActionTiming.DataBindings.Add("SelectedIndex", this, "ActionTimingISel", false, DataSourceUpdateMode.OnPropertyChanged);
cbbMethod.DataSource = MatchTemplate.MatchMethodItems;
cbbMethod.DataBindings.Add("SelectedIndex", this, "MatchMethodISel", false, DataSourceUpdateMode.OnPropertyChanged);
}
private void BtnTemplate_Click(object sender, EventArgs e) { cbbEnableIf.DataSource = MatchTemplate.EnableIfItems;
if (ofdTemplate.ShowDialog() == DialogResult.OK) cbbEnableIf.DataBindings.Add("SelectedIndex", this, "EnableIfISel", false, DataSourceUpdateMode.OnPropertyChanged);
ImagePath = ofdTemplate.FileName; cbbAction.DataSource = MatchTemplate.MatchActionItems;
} cbbAction.DataBindings.Add("SelectedIndex", this, "MatchActionISel", false, DataSourceUpdateMode.OnPropertyChanged);
private void BtnRemove_Click(object sender, EventArgs e) { cbbActionTiming.DataSource = MatchTemplate.ActionTimingItems;
RemoveHandler(this); cbbActionTiming.DataBindings.Add("SelectedIndex", this, "ActionTimingISel", false, DataSourceUpdateMode.OnPropertyChanged);
} cbbMethod.DataSource = MatchTemplate.MatchMethodItems;
cbbMethod.DataBindings.Add("SelectedIndex", this, "MatchMethodISel", false, DataSourceUpdateMode.OnPropertyChanged);
internal int CreateSettingsNode(XmlDocument document, XmlElement parent) { nudMatchCount.DataBindings.Add("Value", this, "MatchCount", true, DataSourceUpdateMode.OnPropertyChanged);
var hashCode = }
SettingsHelper.CreateSetting(document, parent, "Name", TemplateName) ^
SettingsHelper.CreateSetting(document, parent, "EnableIf", EnableIfSel.key) ^ private void BtnTemplate_Click(object sender, EventArgs e) {
SettingsHelper.CreateSetting(document, parent, "EnableIfArg", EnableIfArg) ^ if (ofdTemplate.ShowDialog() == DialogResult.OK)
SettingsHelper.CreateSetting(document, parent, "Action", MatchActionSel.key) ^ ImagePath = ofdTemplate.FileName;
SettingsHelper.CreateSetting(document, parent, "ActionOn", ActionTimingSel.key) ^ }
SettingsHelper.CreateSetting(document, parent, "Image", ImagePath) ^ private void BtnRemove_Click(object sender, EventArgs e) {
SettingsHelper.CreateSetting(document, parent, "OffsetX", ImageOffsetX) ^ RemoveHandler(this);
SettingsHelper.CreateSetting(document, parent, "OffsetY", ImageOffsetY) ^ }
SettingsHelper.CreateSetting(document, parent, "Method", MatchMethodSel.key) ^
SettingsHelper.CreateSetting(document, parent, "Threshold", MatchThreshold); internal int CreateSettingsNode(XmlDocument document, XmlElement parent) {
SettingsHelper.CreateSetting(document, parent, "ThresholdNeg", MatchThresholdNeg); var hashCode =
return hashCode; SettingsHelper.CreateSetting(document, parent, "Name", TemplateName) ^
} SettingsHelper.CreateSetting(document, parent, "EnableIf", EnableIfSel.key) ^
private void SetSettings(XmlElement settings) { SettingsHelper.CreateSetting(document, parent, "EnableIfArg", EnableIfArg) ^
TemplateName = SettingsHelper.ParseString(settings?["Name"], ""); SettingsHelper.CreateSetting(document, parent, "Action", MatchActionSel.key) ^
EnableIfISel = SupSettingsHelper.ParseListISel(settings?["EnableIf"], MatchTemplate.EnableIfFactories, 0); SettingsHelper.CreateSetting(document, parent, "ActionOn", ActionTimingSel.key) ^
EnableIfArg = SettingsHelper.ParseString(settings?["EnableIfArg"], ""); SettingsHelper.CreateSetting(document, parent, "Image", ImagePath) ^
MatchActionISel = SupSettingsHelper.ParseListISel(settings?["Action"], MatchTemplate.MatchActions, 1); SettingsHelper.CreateSetting(document, parent, "OffsetX", ImageOffsetX) ^
ActionTimingISel = SupSettingsHelper.ParseListISel(settings?["ActionOn"], MatchTemplate.ActionTimings, 0); SettingsHelper.CreateSetting(document, parent, "OffsetY", ImageOffsetY) ^
ImagePath = SettingsHelper.ParseString(settings?["Image"], ""); SettingsHelper.CreateSetting(document, parent, "Method", MatchMethodSel.key) ^
ImageOffsetX = SettingsHelper.ParseInt(settings?["OffsetX"], 0); SettingsHelper.CreateSetting(document, parent, "Threshold", MatchThreshold);
ImageOffsetY = SettingsHelper.ParseInt(settings?["OffsetY"], 0); SettingsHelper.CreateSetting(document, parent, "ThresholdNeg", MatchThresholdNeg);
MatchMethodISel = SupSettingsHelper.ParseListISel(settings?["Method"], MatchTemplate.MatchMethodFactories, 0); SettingsHelper.CreateSetting(document, parent, "MatchCount", MatchCount);
matchThreshold = SettingsHelper.ParseDouble(settings?["Threshold"], 0); return hashCode;
matchThresholdNeg = SettingsHelper.ParseDouble(settings?["ThresholdNeg"], 0); }
} private void SetSettings(XmlElement settings) {
TemplateName = SettingsHelper.ParseString(settings?["Name"], "");
EnableIfISel = SupSettingsHelper.ParseListISel(settings?["EnableIf"], MatchTemplate.EnableIfFactories, 0);
EnableIfArg = SettingsHelper.ParseString(settings?["EnableIfArg"], "");
MatchActionISel = SupSettingsHelper.ParseListISel(settings?["Action"], MatchTemplate.MatchActions, 1);
ActionTimingISel = SupSettingsHelper.ParseListISel(settings?["ActionOn"], MatchTemplate.ActionTimings, 0);
ImagePath = SettingsHelper.ParseString(settings?["Image"], "");
ImageOffsetX = SettingsHelper.ParseInt(settings?["OffsetX"], 0);
ImageOffsetY = SettingsHelper.ParseInt(settings?["OffsetY"], 0);
MatchMethodISel = SupSettingsHelper.ParseListISel(settings?["Method"], MatchTemplate.MatchMethodFactories, 0);
matchThreshold = SettingsHelper.ParseDouble(settings?["Threshold"], 0);
matchThresholdNeg = SettingsHelper.ParseDouble(settings?["ThresholdNeg"], 0);
MatchCount = SettingsHelper.ParseInt(settings?["MatchCount"], 1);
}
} }
} }
namespace SupExtension { namespace SupExtension {
public struct ListItem<V> { public struct ListItem<V> {
public string key; public string key;
public string text; public string text;
public V value; public V value;
public static implicit operator ListItem<V>((string, V) arg) => public static implicit operator ListItem<V>((string, V) arg) =>
new ListItem<V>() { key = arg.Item1, text = arg.Item1, value = arg.Item2 }; new ListItem<V>() { key = arg.Item1, text = arg.Item1, value = arg.Item2 };
public static implicit operator ListItem<V>((string, string, V) arg) => public static implicit operator ListItem<V>((string, string, V) arg) =>
new ListItem<V>() { key = arg.Item1, text = arg.Item2, value = arg.Item3 }; new ListItem<V>() { key = arg.Item1, text = arg.Item2, value = arg.Item3 };
} }
public static class SupArray { public static class SupArray {
public static int FindIndex<T>(this T[] self, Predicate<T> match) => public static int FindIndex<T>(this T[] self, Predicate<T> match) =>
Array.FindIndex(self, match); Array.FindIndex(self, match);
} }
static class SupSettingsHelper { static class SupSettingsHelper {
internal static int ParseListISel<T>(XmlElement element, ListItem<T>[] items, int defaultValue=-1) { internal static int ParseListISel<T>(XmlElement element, ListItem<T>[] items, int defaultValue = -1) {
var key = SettingsHelper.ParseString(element); var key = SettingsHelper.ParseString(element);
if (key == null) return defaultValue; if (key == null) return defaultValue;
var index = Array.FindIndex(items, o => o.key == key); var index = Array.FindIndex(items, o => o.key == key);
return index == -1 ? defaultValue : index; return index == -1 ? defaultValue : index;
} }
} }
} }

View file

@ -120,4 +120,7 @@
<metadata name="ofdTemplate.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> <metadata name="ofdTemplate.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value> <value>17, 17</value>
</metadata> </metadata>
<metadata name="templateSettingsBindingSource.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>138, 17</value>
</metadata>
</root> </root>

View file

@ -35,7 +35,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="LiveSplit.Core"> <Reference Include="LiveSplit.Core">
<HintPath>..\..\..\..\..\..\Software\LiveSplit\LiveSplit.Core.dll</HintPath> <HintPath>..\..\..\..\Software\LiveSplit\LiveSplit.Core.dll</HintPath>
</Reference> </Reference>
<Reference Include="OpenCvSharp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=6adad1e807fea099, processorArchitecture=MSIL"> <Reference Include="OpenCvSharp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=6adad1e807fea099, processorArchitecture=MSIL">
<HintPath>..\packages\OpenCvSharp4.4.5.3.20210817\lib\net461\OpenCvSharp.dll</HintPath> <HintPath>..\packages\OpenCvSharp4.4.5.3.20210817\lib\net461\OpenCvSharp.dll</HintPath>
@ -76,7 +76,7 @@
<Reference Include="System.Net.Http" /> <Reference Include="System.Net.Http" />
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
<Reference Include="UpdateManager"> <Reference Include="UpdateManager">
<HintPath>..\..\..\..\..\..\Software\LiveSplit\UpdateManager.dll</HintPath> <HintPath>..\..\..\..\Software\LiveSplit\UpdateManager.dll</HintPath>
</Reference> </Reference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@ -122,8 +122,8 @@
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup> <PropertyGroup>
<PathMap>$(MSBuildProjectDirectory)\$(IntermediateOutputPath)=.</PathMap> <!-- <PathMap>$(MSBuildProjectDirectory)\$(IntermediateOutputPath)=.</PathMap> -->
<PostBuildEvent>copy $(TargetDir)$(TargetFileName) C:\Software\LiveSplit\Components\</PostBuildEvent> <PostBuildEvent>copy $(TargetDir)$(TargetFileName) C:\Users\sup39\Software\LiveSplit\Components\</PostBuildEvent>
</PropertyGroup> </PropertyGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup> <PropertyGroup>