Throw out old Variable Export UI and mostly rewrite it
This commit is contained in:
parent
e63798bd3c
commit
bf552d9a28
@ -61,14 +61,18 @@ namespace rabi_splitter_WPF
|
|||||||
|
|
||||||
private void UpdateVariableExport()
|
private void UpdateVariableExport()
|
||||||
{
|
{
|
||||||
variableExportContext.CheckForUpdates();
|
|
||||||
long currentFrameMillisecond = (long)(DateTime.Now - UNIX_START).TotalMilliseconds;
|
long currentFrameMillisecond = (long)(DateTime.Now - UNIX_START).TotalMilliseconds;
|
||||||
var diff = currentFrameMillisecond - lastUpdateMillisecond;
|
var diff = currentFrameMillisecond - lastUpdateMillisecond;
|
||||||
if (diff >= 1000)
|
if (diff >= 1000)
|
||||||
{
|
{
|
||||||
if (diff >= 2000) lastUpdateMillisecond = currentFrameMillisecond;
|
if (diff >= 2000) lastUpdateMillisecond = currentFrameMillisecond;
|
||||||
else lastUpdateMillisecond += 1000;
|
else lastUpdateMillisecond += 1000;
|
||||||
variableExportContext.OutputUpdates();
|
variableExportContext.UpdateVariables(true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Don't update files.
|
||||||
|
variableExportContext.UpdateVariables(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
116
rabi_splitter_WPF/StringInjectExtension.cs
Normal file
116
rabi_splitter_WPF/StringInjectExtension.cs
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
using System;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.ComponentModel;
|
||||||
|
|
||||||
|
/// Source: http://mo.notono.us/2008/07/c-stringinject-format-strings-by-key.html
|
||||||
|
|
||||||
|
[assembly: CLSCompliant(true)]
|
||||||
|
namespace StringInject
|
||||||
|
{
|
||||||
|
public static class StringInjectExtension
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Extension method that replaces keys in a string with the values of matching object properties.
|
||||||
|
/// <remarks>Uses <see cref="String.Format()"/> internally; custom formats should match those used for that method.</remarks>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="formatString">The format string, containing keys like {foo} and {foo:SomeFormat}.</param>
|
||||||
|
/// <param name="injectionObject">The object whose properties should be injected in the string</param>
|
||||||
|
/// <returns>A version of the formatString string with keys replaced by (formatted) key values.</returns>
|
||||||
|
public static string Inject(this string formatString, object injectionObject)
|
||||||
|
{
|
||||||
|
return formatString.Inject(GetPropertyHash(injectionObject));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Extension method that replaces keys in a string with the values of matching dictionary entries.
|
||||||
|
/// <remarks>Uses <see cref="String.Format()"/> internally; custom formats should match those used for that method.</remarks>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="formatString">The format string, containing keys like {foo} and {foo:SomeFormat}.</param>
|
||||||
|
/// <param name="dictionary">An <see cref="IDictionary"/> with keys and values to inject into the string</param>
|
||||||
|
/// <returns>A version of the formatString string with dictionary keys replaced by (formatted) key values.</returns>
|
||||||
|
public static string Inject(this string formatString, IDictionary dictionary)
|
||||||
|
{
|
||||||
|
return formatString.Inject(new Hashtable(dictionary));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Extension method that replaces keys in a string with the values of matching hashtable entries.
|
||||||
|
/// <remarks>Uses <see cref="String.Format()"/> internally; custom formats should match those used for that method.</remarks>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="formatString">The format string, containing keys like {foo} and {foo:SomeFormat}.</param>
|
||||||
|
/// <param name="attributes">A <see cref="Hashtable"/> with keys and values to inject into the string</param>
|
||||||
|
/// <returns>A version of the formatString string with hastable keys replaced by (formatted) key values.</returns>
|
||||||
|
public static string Inject(this string formatString, Hashtable attributes)
|
||||||
|
{
|
||||||
|
string result = formatString;
|
||||||
|
if (attributes == null || formatString == null)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
foreach (string attributeKey in attributes.Keys)
|
||||||
|
{
|
||||||
|
result = result.InjectSingleValue(attributeKey, attributes[attributeKey]);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Replaces all instances of a 'key' (e.g. {foo} or {foo:SomeFormat}) in a string with an optionally formatted value, and returns the result.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="formatString">The string containing the key; unformatted ({foo}), or formatted ({foo:SomeFormat})</param>
|
||||||
|
/// <param name="key">The key name (foo)</param>
|
||||||
|
/// <param name="replacementValue">The replacement value; if null is replaced with an empty string</param>
|
||||||
|
/// <returns>The input string with any instances of the key replaced with the replacement value</returns>
|
||||||
|
public static string InjectSingleValue(this string formatString, string key, object replacementValue)
|
||||||
|
{
|
||||||
|
string result = formatString;
|
||||||
|
//regex replacement of key with value, where the generic key format is:
|
||||||
|
//Regex foo = new Regex("{(foo)(?:}|(?::(.[^}]*)}))");
|
||||||
|
Regex attributeRegex = new Regex("{(" + key + ")(?:}|(?::(.[^}]*)}))"); //for key = foo, matches {foo} and {foo:SomeFormat}
|
||||||
|
|
||||||
|
//loop through matches, since each key may be used more than once (and with a different format string)
|
||||||
|
foreach (Match m in attributeRegex.Matches(formatString))
|
||||||
|
{
|
||||||
|
string replacement = m.ToString();
|
||||||
|
if (m.Groups[2].Length > 0) //matched {foo:SomeFormat}
|
||||||
|
{
|
||||||
|
//do a double string.Format - first to build the proper format string, and then to format the replacement value
|
||||||
|
string attributeFormatString = string.Format(CultureInfo.InvariantCulture, "{{0:{0}}}", m.Groups[2]);
|
||||||
|
replacement = string.Format(CultureInfo.CurrentCulture, attributeFormatString, replacementValue);
|
||||||
|
}
|
||||||
|
else //matched {foo}
|
||||||
|
{
|
||||||
|
replacement = (replacementValue ?? string.Empty).ToString();
|
||||||
|
}
|
||||||
|
//perform replacements, one match at a time
|
||||||
|
result = result.Replace(m.ToString(), replacement); //attributeRegex.Replace(result, replacement, 1);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a HashTable based on current object state.
|
||||||
|
/// <remarks>Copied from the MVCToolkit HtmlExtensionUtility class</remarks>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="properties">The object from which to get the properties</param>
|
||||||
|
/// <returns>A <see cref="Hashtable"/> containing the object instance's property names and their values</returns>
|
||||||
|
private static Hashtable GetPropertyHash(object properties)
|
||||||
|
{
|
||||||
|
Hashtable values = null;
|
||||||
|
if (properties != null)
|
||||||
|
{
|
||||||
|
values = new Hashtable();
|
||||||
|
PropertyDescriptorCollection props = TypeDescriptor.GetProperties(properties);
|
||||||
|
foreach (PropertyDescriptor prop in props)
|
||||||
|
{
|
||||||
|
values.Add(prop.Name, prop.GetValue(properties));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -9,95 +9,108 @@ namespace rabi_splitter_WPF
|
|||||||
{
|
{
|
||||||
void ConfigureVariableExports()
|
void ConfigureVariableExports()
|
||||||
{
|
{
|
||||||
ExportableVariable.DefineVariableExports(new ExportableVariable[] {
|
variableExportContext.DefineVariableExports(new ExportableVariable[] {
|
||||||
ExportVariable<int> (
|
ExportVariable<int> (
|
||||||
|
handle: "playtime",
|
||||||
displayName: "Playtime",
|
displayName: "Playtime",
|
||||||
tracker: () => snapshot.playtime
|
tracker: () => snapshot.playtime
|
||||||
),
|
),
|
||||||
|
|
||||||
ExportVariable<int> (
|
ExportVariable<int> (
|
||||||
|
handle: "blackness",
|
||||||
displayName: "Blackness",
|
displayName: "Blackness",
|
||||||
tracker: () => snapshot.blackness
|
tracker: () => snapshot.blackness
|
||||||
),
|
),
|
||||||
|
|
||||||
ExportVariable<int> (
|
ExportVariable<int> (
|
||||||
|
handle: "mapid",
|
||||||
displayName: "Map Id",
|
displayName: "Map Id",
|
||||||
tracker: () => snapshot.mapid
|
tracker: () => snapshot.mapid
|
||||||
),
|
),
|
||||||
|
|
||||||
ExportVariable<string> (
|
ExportVariable<string> (
|
||||||
|
handle: "map",
|
||||||
displayName: "Map",
|
displayName: "Map",
|
||||||
tracker: () => StaticData.GetMapName(snapshot.mapid)
|
tracker: () => StaticData.GetMapName(snapshot.mapid)
|
||||||
),
|
),
|
||||||
|
|
||||||
ExportVariable<int> (
|
ExportVariable<int> (
|
||||||
|
handle: "musicid",
|
||||||
displayName: "Music Id",
|
displayName: "Music Id",
|
||||||
tracker: () => snapshot.musicid
|
tracker: () => snapshot.musicid
|
||||||
),
|
),
|
||||||
|
|
||||||
ExportVariable<string> (
|
ExportVariable<string> (
|
||||||
|
handle: "music",
|
||||||
displayName: "Music",
|
displayName: "Music",
|
||||||
tracker: () => StaticData.GetMusicName(snapshot.musicid)
|
tracker: () => StaticData.GetMusicName(snapshot.musicid)
|
||||||
),
|
),
|
||||||
|
|
||||||
ExportVariable<int> (
|
ExportVariable<int> (
|
||||||
|
handle: "hp",
|
||||||
displayName: "HP",
|
displayName: "HP",
|
||||||
tracker: () => snapshot.hp
|
tracker: () => snapshot.hp
|
||||||
),
|
),
|
||||||
|
|
||||||
ExportVariable<float> (
|
ExportVariable<float> (
|
||||||
|
handle: "amulet",
|
||||||
displayName: "Amulet",
|
displayName: "Amulet",
|
||||||
tracker: () => snapshot.amulet
|
tracker: () => snapshot.amulet
|
||||||
),
|
),
|
||||||
|
|
||||||
ExportVariable<int> (
|
ExportVariable<int> (
|
||||||
|
handle: "boost",
|
||||||
displayName: "Boost",
|
displayName: "Boost",
|
||||||
tracker: () => snapshot.boost
|
tracker: () => snapshot.boost
|
||||||
),
|
),
|
||||||
|
|
||||||
ExportVariable<float> (
|
ExportVariable<float> (
|
||||||
|
handle: "mana",
|
||||||
displayName: "MP",
|
displayName: "MP",
|
||||||
tracker: () => snapshot.mana
|
tracker: () => snapshot.mana
|
||||||
),
|
),
|
||||||
|
|
||||||
ExportVariable<int> (
|
ExportVariable<int> (
|
||||||
|
handle: "stamina",
|
||||||
displayName: "SP",
|
displayName: "SP",
|
||||||
tracker: () => snapshot.stamina
|
tracker: () => snapshot.stamina
|
||||||
),
|
),
|
||||||
|
|
||||||
ExportVariable<float> (
|
ExportVariable<float> (
|
||||||
|
handle: "x",
|
||||||
displayName: "x",
|
displayName: "x",
|
||||||
tracker: () => snapshot.px
|
tracker: () => snapshot.px
|
||||||
),
|
),
|
||||||
|
|
||||||
ExportVariable<float> (
|
ExportVariable<float> (
|
||||||
|
handle: "y",
|
||||||
displayName: "y",
|
displayName: "y",
|
||||||
tracker: () => snapshot.py
|
tracker: () => snapshot.py
|
||||||
),
|
),
|
||||||
|
|
||||||
ExportVariable<MapTileCoordinate> (
|
ExportVariable<MapTileCoordinate> (
|
||||||
|
handle: "mapTile",
|
||||||
displayName: "Map Tile",
|
displayName: "Map Tile",
|
||||||
tracker: () => snapshot.mapTile
|
tracker: () => snapshot.mapTile
|
||||||
),
|
),
|
||||||
|
|
||||||
ExportVariable<int> (
|
ExportVariable<int> (
|
||||||
|
handle: "nDeaths",
|
||||||
displayName: "Deaths",
|
displayName: "Deaths",
|
||||||
tracker: () => inGameState.nDeaths
|
tracker: () => inGameState.nDeaths
|
||||||
),
|
),
|
||||||
|
|
||||||
ExportVariable<int> (
|
ExportVariable<int> (
|
||||||
|
handle: "nRestarts",
|
||||||
displayName: "Restarts",
|
displayName: "Restarts",
|
||||||
tracker: () => inGameState.nRestarts
|
tracker: () => inGameState.nRestarts
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
variableExportContext.NotifyExportableVariableUpdate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ExportableVariable<T> ExportVariable<T>(string displayName, Func<T> tracker)
|
private ExportableVariable<T> ExportVariable<T>(string handle, string displayName, Func<T> tracker)
|
||||||
{
|
{
|
||||||
return new ExportableVariable<T>(displayName, tracker);
|
return new ExportableVariable<T>(handle, displayName, tracker);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,55 +5,65 @@ using System.ComponentModel;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
|
||||||
namespace rabi_splitter_WPF
|
namespace rabi_splitter_WPF
|
||||||
{
|
{
|
||||||
public class VariableExportContext : INotifyPropertyChanged
|
public class VariableExportContext : INotifyPropertyChanged
|
||||||
{
|
{
|
||||||
private List<VariableExportSetting> _variableExportSettings;
|
private List<VariableExportSetting> _variableExportSettings;
|
||||||
private HashSet<VariableExportSetting> pendingUpdates;
|
private List<ExportableVariable> _variables;
|
||||||
|
private Dictionary<string, object> variableValues;
|
||||||
|
|
||||||
|
private ItemCollection variableListBoxItems;
|
||||||
|
private ItemCollection variableExportListBoxItems;
|
||||||
|
|
||||||
public VariableExportContext()
|
public VariableExportContext()
|
||||||
{
|
{
|
||||||
_variableExportSettings = new List<VariableExportSetting>();
|
_variableExportSettings = new List<VariableExportSetting>();
|
||||||
pendingUpdates = new HashSet<VariableExportSetting>();
|
_variables = new List<ExportableVariable>();
|
||||||
|
variableValues = new Dictionary<string, object>();
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Update Logic
|
#region Update Logic
|
||||||
|
|
||||||
public void OutputUpdates()
|
public void UpdateVariables(bool updateFile)
|
||||||
{
|
{
|
||||||
foreach (var ves in pendingUpdates)
|
foreach (var variable in _variables) {
|
||||||
{
|
variable.UpdateValue();
|
||||||
ves.OutputUpdate();
|
variableValues[variable.Handle] = variable.Value;
|
||||||
}
|
}
|
||||||
pendingUpdates.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void RegisterUpdate(VariableExportSetting ves)
|
|
||||||
{
|
|
||||||
pendingUpdates.Add(ves);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void CheckForUpdates()
|
|
||||||
{
|
|
||||||
foreach (var ves in _variableExportSettings)
|
foreach (var ves in _variableExportSettings)
|
||||||
{
|
{
|
||||||
bool hasUpdate = ves.CheckForUpdate();
|
ves.OutputUpdate(variableValues, updateFile);
|
||||||
if (hasUpdate) RegisterUpdate(ves);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void NotifyExportableVariableUpdate()
|
internal void SetItemControls(ItemCollection variableListBoxItems, ItemCollection variableExportListBoxItems)
|
||||||
{
|
{
|
||||||
foreach (var ves in _variableExportSettings)
|
this.variableListBoxItems = variableListBoxItems;
|
||||||
{
|
this.variableExportListBoxItems = variableExportListBoxItems;
|
||||||
ves.NotifyExportableVariableUpdate();
|
}
|
||||||
}
|
|
||||||
|
public void DefineVariableExports(ExportableVariable[] exports)
|
||||||
|
{
|
||||||
|
Variables = exports.ToList();
|
||||||
|
variableValues.Clear();
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Variables
|
#region Properties
|
||||||
|
public List<ExportableVariable> Variables
|
||||||
|
{
|
||||||
|
get { return _variables; }
|
||||||
|
private set
|
||||||
|
{
|
||||||
|
_variables = value;
|
||||||
|
variableListBoxItems.Refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public List<VariableExportSetting> VariableExportSettings
|
public List<VariableExportSetting> VariableExportSettings
|
||||||
{
|
{
|
||||||
get { return _variableExportSettings; }
|
get { return _variableExportSettings; }
|
||||||
@ -62,12 +72,13 @@ namespace rabi_splitter_WPF
|
|||||||
internal void Add(VariableExportSetting ves)
|
internal void Add(VariableExportSetting ves)
|
||||||
{
|
{
|
||||||
_variableExportSettings.Add(ves);
|
_variableExportSettings.Add(ves);
|
||||||
|
variableExportListBoxItems.Refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void Delete(VariableExportSetting ves)
|
internal void Delete(VariableExportSetting ves)
|
||||||
{
|
{
|
||||||
_variableExportSettings.Remove(ves);
|
_variableExportSettings.Remove(ves);
|
||||||
pendingUpdates.Remove(ves);
|
variableExportListBoxItems.Refresh();
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ using System.Collections.Generic;
|
|||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using StringInject;
|
||||||
|
|
||||||
namespace rabi_splitter_WPF
|
namespace rabi_splitter_WPF
|
||||||
{
|
{
|
||||||
@ -11,29 +12,28 @@ namespace rabi_splitter_WPF
|
|||||||
{
|
{
|
||||||
private readonly Func<T> tracker;
|
private readonly Func<T> tracker;
|
||||||
|
|
||||||
public ExportableVariable(string displayName, Func<T> tracker) : base(displayName)
|
public ExportableVariable(string handle, string displayName, Func<T> tracker) : base(handle, displayName)
|
||||||
{
|
{
|
||||||
this.tracker = tracker;
|
this.tracker = tracker;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal override VariableTracker GetTracker()
|
public override void UpdateValue()
|
||||||
{
|
{
|
||||||
return new VariableTracker<T>(tracker);
|
Value = tracker();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class ExportableVariable
|
public abstract class ExportableVariable : INotifyPropertyChanged
|
||||||
{
|
{
|
||||||
private static int nextAvailableId = 0;
|
|
||||||
private static List<ExportableVariable> _variableExports;
|
|
||||||
private static Dictionary<ExportableVariable, string> _variableCaptions = new Dictionary<ExportableVariable, string>();
|
|
||||||
|
|
||||||
private readonly int _id;
|
private readonly int _id;
|
||||||
private readonly string _displayName;
|
private readonly string _displayName;
|
||||||
|
private readonly string _handle;
|
||||||
|
|
||||||
protected ExportableVariable(string displayName)
|
private object _value;
|
||||||
|
|
||||||
|
protected ExportableVariable(string handle, string displayName)
|
||||||
{
|
{
|
||||||
_id = nextAvailableId++;
|
_handle = handle;
|
||||||
_displayName = displayName;
|
_displayName = displayName;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,81 +47,36 @@ namespace rabi_splitter_WPF
|
|||||||
get { return _displayName; }
|
get { return _displayName; }
|
||||||
}
|
}
|
||||||
|
|
||||||
internal abstract VariableTracker GetTracker();
|
public string Handle
|
||||||
|
|
||||||
public static void DefineVariableExports(ExportableVariable[] exports)
|
|
||||||
{
|
{
|
||||||
_variableExports = exports.ToList();
|
get { return _handle; }
|
||||||
_variableCaptions = exports.ToDictionary(ev => ev, ev => ev.DisplayName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Dictionary<ExportableVariable, string> VariableCaptions
|
public object Value
|
||||||
{
|
{
|
||||||
get { return _variableCaptions; }
|
get { return _value; }
|
||||||
}
|
protected set
|
||||||
|
|
||||||
#region Equals, GetHashCode
|
|
||||||
public override bool Equals(object obj)
|
|
||||||
{
|
|
||||||
var otherValue = obj as ExportableVariable;
|
|
||||||
if (otherValue == null) return false;
|
|
||||||
return _id.Equals(otherValue.Id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int GetHashCode()
|
|
||||||
{
|
|
||||||
return _id.GetHashCode();
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
|
|
||||||
public class VariableTracker<T> : VariableTracker
|
|
||||||
{
|
|
||||||
private readonly Func<T> tracker;
|
|
||||||
private T currentValue;
|
|
||||||
|
|
||||||
public VariableTracker(Func<T> tracker)
|
|
||||||
{
|
|
||||||
this.tracker = tracker;
|
|
||||||
forceUpdate = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool CheckForUpdate()
|
|
||||||
{
|
|
||||||
T newValue = tracker();
|
|
||||||
|
|
||||||
if (forceUpdate || !newValue.Equals(currentValue))
|
|
||||||
{
|
{
|
||||||
currentValue = newValue;
|
if (value.Equals(_value)) return;
|
||||||
forceUpdate = false;
|
_value = value;
|
||||||
return true;
|
OnPropertyChanged(nameof(Value));
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override object GetValue()
|
public abstract void UpdateValue();
|
||||||
|
|
||||||
|
public event PropertyChangedEventHandler PropertyChanged;
|
||||||
|
|
||||||
|
[NotifyPropertyChangedInvocator]
|
||||||
|
protected virtual void OnPropertyChanged(string propertyName)
|
||||||
{
|
{
|
||||||
return currentValue;
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class VariableTracker
|
|
||||||
{
|
|
||||||
protected bool forceUpdate;
|
|
||||||
|
|
||||||
public void FormatChanged()
|
|
||||||
{
|
|
||||||
forceUpdate = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract bool CheckForUpdate();
|
|
||||||
public abstract object GetValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
public class VariableExportSetting : INotifyPropertyChanged
|
public class VariableExportSetting : INotifyPropertyChanged
|
||||||
{
|
{
|
||||||
private ExportableVariable _selectedVariable;
|
|
||||||
private VariableTracker _variableTracker;
|
|
||||||
private string _outputFileName;
|
private string _outputFileName;
|
||||||
private string _outputFormat;
|
private string _outputFormat;
|
||||||
private string _formatPreview;
|
private string _formatPreview;
|
||||||
@ -131,7 +86,6 @@ namespace rabi_splitter_WPF
|
|||||||
public VariableExportSetting()
|
public VariableExportSetting()
|
||||||
{
|
{
|
||||||
// Default values
|
// Default values
|
||||||
_selectedVariable = null;
|
|
||||||
_outputFileName = "";
|
_outputFileName = "";
|
||||||
_outputFormat = "";
|
_outputFormat = "";
|
||||||
_isExporting = false;
|
_isExporting = false;
|
||||||
@ -139,11 +93,11 @@ namespace rabi_splitter_WPF
|
|||||||
}
|
}
|
||||||
|
|
||||||
#region Logic
|
#region Logic
|
||||||
private string FormatOutput()
|
private string FormatOutput(Dictionary<string, object> variableValues)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return string.Format(_outputFormat, _variableTracker.GetValue());
|
return _outputFormat.Inject(variableValues);
|
||||||
}
|
}
|
||||||
catch (FormatException e)
|
catch (FormatException e)
|
||||||
{
|
{
|
||||||
@ -151,60 +105,21 @@ namespace rabi_splitter_WPF
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void OutputUpdate()
|
internal void OutputUpdate(Dictionary<string, object> variableValues, bool updateFile)
|
||||||
{
|
{
|
||||||
if (_variableTracker == null) return;
|
var formattedOutput = FormatOutput(variableValues);
|
||||||
var formattedOutput = FormatOutput();
|
if (formattedOutput == FormatPreview) return;
|
||||||
FormatPreview = formattedOutput;
|
FormatPreview = formattedOutput;
|
||||||
// TODO: Write to file
|
if (updateFile)
|
||||||
}
|
|
||||||
|
|
||||||
internal bool CheckForUpdate()
|
|
||||||
{
|
|
||||||
if (_variableTracker == null) return false;
|
|
||||||
return _variableTracker.CheckForUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void NotifyExportableVariableUpdate()
|
|
||||||
{
|
|
||||||
OnPropertyChanged(nameof(VariableCaptions));
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Dictionaries
|
|
||||||
public Dictionary<ExportableVariable, string> VariableCaptions
|
|
||||||
{
|
|
||||||
get { return ExportableVariable.VariableCaptions; }
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void DefaultButton_Click()
|
|
||||||
{
|
|
||||||
if (_selectedVariable == null)
|
|
||||||
{
|
{
|
||||||
OutputFormat = "Variable not set.";
|
// TODO: Write to file
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
OutputFormat = $"{_selectedVariable.DisplayName}: {{0}}";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Parameters
|
#region Parameters
|
||||||
|
|
||||||
public ExportableVariable SelectedVariable
|
|
||||||
{
|
|
||||||
get { return _selectedVariable; }
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (value.Equals(_selectedVariable)) return;
|
|
||||||
_selectedVariable = value;
|
|
||||||
_variableTracker = _selectedVariable.GetTracker();
|
|
||||||
OnPropertyChanged(nameof(SelectedVariable));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string OutputFileName
|
public string OutputFileName
|
||||||
{
|
{
|
||||||
get { return _outputFileName; }
|
get { return _outputFileName; }
|
||||||
@ -223,7 +138,6 @@ namespace rabi_splitter_WPF
|
|||||||
{
|
{
|
||||||
if (value.Equals(_outputFormat)) return;
|
if (value.Equals(_outputFormat)) return;
|
||||||
_outputFormat = value;
|
_outputFormat = value;
|
||||||
if (_variableTracker != null) _variableTracker.FormatChanged();
|
|
||||||
OnPropertyChanged(nameof(OutputFormat));
|
OnPropertyChanged(nameof(OutputFormat));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -262,8 +176,6 @@ namespace rabi_splitter_WPF
|
|||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
// Note: DO NOT OVERRIDE Equals and GetHashCode. We compare by reference equality.
|
|
||||||
|
|
||||||
public event PropertyChangedEventHandler PropertyChanged;
|
public event PropertyChangedEventHandler PropertyChanged;
|
||||||
|
|
||||||
[NotifyPropertyChangedInvocator]
|
[NotifyPropertyChangedInvocator]
|
||||||
|
@ -5,48 +5,70 @@
|
|||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:local="clr-namespace:rabi_splitter_WPF"
|
xmlns:local="clr-namespace:rabi_splitter_WPF"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
d:DesignHeight="500" d:DesignWidth="540">
|
d:DesignHeight="500" d:DesignWidth="780">
|
||||||
<UserControl.Resources>
|
<UserControl.Resources>
|
||||||
<local:InvertableBooleanToVisibilityConverter x:Key="InvertableBooleanToVisibilityConverter"/>
|
<local:InvertableBooleanToVisibilityConverter x:Key="InvertableBooleanToVisibilityConverter"/>
|
||||||
</UserControl.Resources>
|
</UserControl.Resources>
|
||||||
<DockPanel>
|
<DockPanel Height="500" Width="780">
|
||||||
<StackPanel>
|
<DockPanel DockPanel.Dock="Left" Width="260">
|
||||||
<Button Content="Add" Width="40" Height="40" DockPanel.Dock="Right" Click="AddButton_Click"/>
|
<Button Content="Add Text File Export" Width="160" Height="30" Margin="5,5,5,5" DockPanel.Dock="Top" Click="AddButton_Click"/>
|
||||||
</StackPanel>
|
<TextBlock Margin="5,5,0,0" DockPanel.Dock="Top" Text="Variable Handle List"/>
|
||||||
<ListBox Name="VariableExportListBox" Width="500" ItemsSource="{Binding VariableExportSettings}">
|
<ListBox Name="VariableListBox" ItemsSource="{Binding Variables}" ScrollViewer.VerticalScrollBarVisibility="Visible">
|
||||||
|
<ListBox.ItemContainerStyle>
|
||||||
|
<Style TargetType="ListBoxItem">
|
||||||
|
<Setter Property="HorizontalContentAlignment" Value="Stretch"></Setter>
|
||||||
|
</Style>
|
||||||
|
</ListBox.ItemContainerStyle>
|
||||||
|
<ListBox.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<StackPanel Margin="2,2,2,2">
|
||||||
|
<TextBlock FontFamily="Consolas" Margin="2,0,0,0" Text="{Binding Path=Handle}"/>
|
||||||
|
<Grid Margin="15,0,0,0">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="2*" />
|
||||||
|
<ColumnDefinition Width="3*" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="1*" />
|
||||||
|
<RowDefinition Height="1*" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<TextBlock Grid.Column="0" Grid.Row="0" Text="Description:"/>
|
||||||
|
<TextBlock Grid.Column="0" Grid.Row="1" Text="Value:"/>
|
||||||
|
<TextBlock Margin="2,0,0,0" Grid.Column="1" Grid.Row="0" Text="{Binding Path=DisplayName}"/>
|
||||||
|
<TextBlock Margin="2,0,0,0" Grid.Column="1" Grid.Row="1" Text="{Binding Path=Value}"/>
|
||||||
|
</Grid>
|
||||||
|
</StackPanel>
|
||||||
|
</DataTemplate>
|
||||||
|
</ListBox.ItemTemplate>
|
||||||
|
</ListBox>
|
||||||
|
</DockPanel>
|
||||||
|
<ListBox Name="VariableExportListBox" ScrollViewer.HorizontalScrollBarVisibility="Disabled" Width="520" ItemsSource="{Binding VariableExportSettings}" ScrollViewer.VerticalScrollBarVisibility="Visible">
|
||||||
|
<ListBox.ItemContainerStyle>
|
||||||
|
<Style TargetType="ListBoxItem">
|
||||||
|
<Setter Property="HorizontalContentAlignment" Value="Stretch"></Setter>
|
||||||
|
</Style>
|
||||||
|
</ListBox.ItemContainerStyle>
|
||||||
<ListBox.ItemTemplate>
|
<ListBox.ItemTemplate>
|
||||||
<DataTemplate>
|
<DataTemplate>
|
||||||
<Grid Name="MainPanel" Height="80" Width="480" DockPanel.Dock="Top" Margin="5,0,5,0">
|
<Grid Name="MainPanel" Height="80" DockPanel.Dock="Top" Margin="5,0,5,0">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="4*" />
|
<ColumnDefinition Width="5*" />
|
||||||
<ColumnDefinition Width="6*" />
|
<ColumnDefinition Width="5*" />
|
||||||
<ColumnDefinition Width="2*" />
|
<ColumnDefinition Width="3*" />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<StackPanel Grid.Column="0">
|
<DockPanel Grid.Column="0" Margin="0,5,0,5" >
|
||||||
<TextBlock Text="Variable"/>
|
<TextBlock DockPanel.Dock="Top" HorizontalAlignment="Left" Text="Format"/>
|
||||||
<ComboBox ItemsSource="{Binding Path=VariableCaptions}" DisplayMemberPath="Value" SelectedValuePath="Key" SelectedValue="{Binding Path=SelectedVariable, Mode=TwoWay}"/>
|
<TextBox Height="50" DockPanel.Dock="Top" Text="{Binding Path=OutputFormat, Mode=TwoWay}" AcceptsReturn="True"/>
|
||||||
<TextBlock Text="Output File" Margin="0,2,0,0"/>
|
|
||||||
<TextBox Text="{Binding Path=OutputFileName, Mode=TwoWay}"/>
|
|
||||||
</StackPanel>
|
|
||||||
<DockPanel Grid.Column="1" Margin="15,0,15,0">
|
|
||||||
<DockPanel>
|
|
||||||
<Grid DockPanel.Dock="Top">
|
|
||||||
<Grid.ColumnDefinitions>
|
|
||||||
<ColumnDefinition Width="6*" />
|
|
||||||
<ColumnDefinition Width="5*" />
|
|
||||||
<ColumnDefinition Width="3*" />
|
|
||||||
</Grid.ColumnDefinitions>
|
|
||||||
<TextBlock Grid.Column="0" HorizontalAlignment="Left" Text="Format"/>
|
|
||||||
<ToggleButton Grid.Column="1" Margin="0,0,5,0" Content="Preview" IsChecked="{Binding Path=IsPreviewingFormat}"/>
|
|
||||||
<Button Grid.Column="2" Content="Default" Click="DefaultButton_Click"/>
|
|
||||||
</Grid>
|
|
||||||
<TextBox Height="50" DockPanel.Dock="Top" Margin="0,5,0,5" Text="{Binding Path=OutputFormat, Mode=TwoWay}" AcceptsReturn="True" Visibility="{Binding Path=IsPreviewingFormat, Converter={StaticResource InvertableBooleanToVisibilityConverter}, ConverterParameter=VisibleWhenFalse, FallbackValue=Visible}"/>
|
|
||||||
<TextBlock Height="50" DockPanel.Dock="Top" Margin="0,5,0,5" Text="{Binding Path=FormatPreview}" Visibility="{Binding Path=IsPreviewingFormat, Converter={StaticResource InvertableBooleanToVisibilityConverter}, ConverterParameter=VisibleWhenTrue, FallbackValue=Collapsed}"/>
|
|
||||||
</DockPanel>
|
|
||||||
</DockPanel>
|
</DockPanel>
|
||||||
<DockPanel Grid.Column="2">
|
<DockPanel Grid.Column="1" Margin="0,5,0,5" >
|
||||||
<Button Content="X" DockPanel.Dock="Top" Width="20" HorizontalAlignment="Right" Click="CloseButton_Click"/>
|
<TextBlock DockPanel.Dock="Top" HorizontalAlignment="Left" Text="Preview"/>
|
||||||
<ToggleButton Margin="5,5,5,5" Content="Export" DockPanel.Dock="Bottom" IsChecked="{Binding Path=IsExporting, Mode=TwoWay}"/>
|
<TextBlock Height="50" DockPanel.Dock="Top" Text="{Binding Path=FormatPreview}"/>
|
||||||
|
</DockPanel>
|
||||||
|
<DockPanel Grid.Column="2" Margin="2,0,2,0">
|
||||||
|
<ToggleButton Margin="3,5,3,5" Content="Export" DockPanel.Dock="Bottom" IsChecked="{Binding Path=IsExporting, Mode=TwoWay}"/>
|
||||||
|
<TextBox DockPanel.Dock="Bottom" Text="{Binding Path=OutputFileName, Mode=TwoWay}"/>
|
||||||
|
<TextBlock DockPanel.Dock="Left" Text="Output File" VerticalAlignment="Bottom" Margin="0,0,0,2"/>
|
||||||
|
<Button Content="X" Width="20" Height="20" HorizontalAlignment="Right" Click="CloseButton_Click"/>
|
||||||
</DockPanel>
|
</DockPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
|
@ -33,6 +33,7 @@ namespace rabi_splitter_WPF
|
|||||||
{
|
{
|
||||||
this.debugContext = debugContext;
|
this.debugContext = debugContext;
|
||||||
this.variableExportContext = variableExportContext;
|
this.variableExportContext = variableExportContext;
|
||||||
|
variableExportContext.SetItemControls(VariableListBox.Items, VariableExportListBox.Items);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddButton_Click(object sender, RoutedEventArgs e)
|
private void AddButton_Click(object sender, RoutedEventArgs e)
|
||||||
@ -40,20 +41,12 @@ namespace rabi_splitter_WPF
|
|||||||
var ves = new VariableExportSetting();
|
var ves = new VariableExportSetting();
|
||||||
ves.OutputFileName = "Hello.txt";
|
ves.OutputFileName = "Hello.txt";
|
||||||
variableExportContext.Add(ves);
|
variableExportContext.Add(ves);
|
||||||
VariableExportListBox.Items.Refresh();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CloseButton_Click(object sender, RoutedEventArgs e)
|
private void CloseButton_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
var variableExportSetting = (sender as Button).DataContext as VariableExportSetting;
|
var variableExportSetting = (sender as Button).DataContext as VariableExportSetting;
|
||||||
variableExportContext.Delete(variableExportSetting);
|
variableExportContext.Delete(variableExportSetting);
|
||||||
VariableExportListBox.Items.Refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void DefaultButton_Click(object sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
var variableExportSetting = (sender as Button).DataContext as VariableExportSetting;
|
|
||||||
variableExportSetting.DefaultButton_Click();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,6 +66,7 @@
|
|||||||
<Compile Include="RabiRibiDisplay.cs" />
|
<Compile Include="RabiRibiDisplay.cs" />
|
||||||
<Compile Include="RabiRibiState.cs" />
|
<Compile Include="RabiRibiState.cs" />
|
||||||
<Compile Include="StaticData.cs" />
|
<Compile Include="StaticData.cs" />
|
||||||
|
<Compile Include="StringInjectExtension.cs" />
|
||||||
<Compile Include="VariableExportConfig.cs" />
|
<Compile Include="VariableExportConfig.cs" />
|
||||||
<Compile Include="VariableExportContext.cs" />
|
<Compile Include="VariableExportContext.cs" />
|
||||||
<Compile Include="VariableExportSetting.cs" />
|
<Compile Include="VariableExportSetting.cs" />
|
||||||
|
Loading…
x
Reference in New Issue
Block a user