|
@@ -1,5 +1,7 @@
|
|
|
using System;
|
|
|
using System.Collections.Generic;
|
|
|
+using System.Drawing;
|
|
|
+using System.Globalization;
|
|
|
using System.Linq;
|
|
|
using System.Text;
|
|
|
using Expressive;
|
|
@@ -21,6 +23,11 @@ namespace InABox.Core
|
|
|
object? GetFieldData(string fieldName, string dataField);
|
|
|
|
|
|
void SetFieldValue(string field, object? value);
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Set the background colour for a field.
|
|
|
+ /// </summary>
|
|
|
+ void SetFieldColour(string field, Color? colour = null);
|
|
|
}
|
|
|
|
|
|
public class DFLayout
|
|
@@ -32,7 +39,8 @@ namespace InABox.Core
|
|
|
Elements = new List<DFLayoutControl>();
|
|
|
|
|
|
Expressions = new Dictionary<string, CoreExpression>();
|
|
|
- VariableReferences = new Dictionary<string, List<string>>();
|
|
|
+ ColourExpressions = new Dictionary<string, CoreExpression>();
|
|
|
+ VariableReferences = new Dictionary<string, List<Tuple<ReferenceType, string>>>();
|
|
|
}
|
|
|
|
|
|
public List<string> ColumnWidths { get; }
|
|
@@ -41,8 +49,15 @@ namespace InABox.Core
|
|
|
|
|
|
public List<DFLayoutControl> Elements { get; }
|
|
|
|
|
|
+ private enum ReferenceType
|
|
|
+ {
|
|
|
+ Value,
|
|
|
+ Colour
|
|
|
+ }
|
|
|
+
|
|
|
private Dictionary<string, CoreExpression> Expressions;
|
|
|
- private Dictionary<string, List<string>> VariableReferences;
|
|
|
+ private Dictionary<string, CoreExpression> ColourExpressions;
|
|
|
+ private Dictionary<string, List<Tuple<ReferenceType, string>>> VariableReferences;
|
|
|
public IDFRenderer? Renderer;
|
|
|
|
|
|
public string SaveLayout()
|
|
@@ -136,17 +151,17 @@ namespace InABox.Core
|
|
|
RowHeights.AddRange(new[] { "Auto" });
|
|
|
}
|
|
|
|
|
|
- private void AddVariableReference(string reference, string fieldName)
|
|
|
+ private void AddVariableReference(string reference, string fieldName, ReferenceType referenceType)
|
|
|
{
|
|
|
if (reference.Contains('.'))
|
|
|
reference = reference.Split('.')[0];
|
|
|
|
|
|
if(!VariableReferences.TryGetValue(reference, out var refs))
|
|
|
{
|
|
|
- refs = new List<string>();
|
|
|
+ refs = new List<Tuple<ReferenceType, string>>();
|
|
|
VariableReferences[reference] = refs;
|
|
|
}
|
|
|
- refs.Add(fieldName);
|
|
|
+ refs.Add(new Tuple<ReferenceType, string>(referenceType, fieldName));
|
|
|
}
|
|
|
|
|
|
private object? GetFieldValue(string field)
|
|
@@ -162,7 +177,7 @@ namespace InABox.Core
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private void EvaluateExpression(string name)
|
|
|
+ private void EvaluateValueExpression(string name)
|
|
|
{
|
|
|
var expression = Expressions[name];
|
|
|
var values = new Dictionary<string, object?>();
|
|
@@ -185,18 +200,92 @@ namespace InABox.Core
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- public void LoadVariable(DigitalFormVariable variable, DFLayoutField field)
|
|
|
+ private Color? ConvertObjectToColour(object? colour)
|
|
|
{
|
|
|
- var properties = variable.LoadProperties(field);
|
|
|
- if (!string.IsNullOrWhiteSpace(properties?.Expression))
|
|
|
+ if(colour is string str)
|
|
|
{
|
|
|
- var expression = new CoreExpression(properties.Expression);
|
|
|
- foreach (var reference in expression.ReferencedVariables)
|
|
|
+ if (str.StartsWith('#'))
|
|
|
+ {
|
|
|
+ var trimmed = str.TrimStart('#');
|
|
|
+ try
|
|
|
+ {
|
|
|
+ if (trimmed.Length == 6)
|
|
|
+ {
|
|
|
+ return Color.FromArgb(
|
|
|
+ Int32.Parse(trimmed[..2], NumberStyles.HexNumber),
|
|
|
+ Int32.Parse(trimmed.Substring(2, 2), NumberStyles.HexNumber),
|
|
|
+ Int32.Parse(trimmed.Substring(4, 2), NumberStyles.HexNumber));
|
|
|
+ }
|
|
|
+ else if (trimmed.Length == 8)
|
|
|
+ {
|
|
|
+ return Color.FromArgb(Int32.Parse(trimmed, NumberStyles.HexNumber));
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ catch (Exception e)
|
|
|
+ {
|
|
|
+ Logger.Send(LogType.Error, "", $"Error parsing Colour Expression colour '{str}': {e.Message}");
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if(Enum.TryParse<KnownColor>(str, out var result))
|
|
|
{
|
|
|
- AddVariableReference(reference, field.Name);
|
|
|
+ return Color.FromKnownColor(result);
|
|
|
}
|
|
|
- Expressions[field.Name] = expression;
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void EvaluateColourExpression(string name)
|
|
|
+ {
|
|
|
+ var expression = ColourExpressions[name];
|
|
|
+ var values = new Dictionary<string, object?>();
|
|
|
+ foreach (var field in expression.ReferencedVariables)
|
|
|
+ {
|
|
|
+ values[field] = GetFieldValue(field);
|
|
|
+ }
|
|
|
+
|
|
|
+ try
|
|
|
+ {
|
|
|
+ var colour = expression?.Evaluate(values);
|
|
|
+ Renderer?.SetFieldColour(name, ConvertObjectToColour(colour));
|
|
|
+ }
|
|
|
+ catch (Exception e)
|
|
|
+ {
|
|
|
+ Logger.Send(LogType.Error, ClientFactory.UserID, $"Error in Expression field '{name}': {CoreUtils.FormatException(e)}");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void LoadExpression(string fieldName, string? expressionStr, ReferenceType referenceType)
|
|
|
+ {
|
|
|
+ if (string.IsNullOrWhiteSpace(expressionStr))
|
|
|
+ return;
|
|
|
+
|
|
|
+ var expression = new CoreExpression(expressionStr);
|
|
|
+ foreach (var reference in expression.ReferencedVariables)
|
|
|
+ {
|
|
|
+ AddVariableReference(reference, fieldName, referenceType);
|
|
|
}
|
|
|
+ switch (referenceType)
|
|
|
+ {
|
|
|
+ case ReferenceType.Value:
|
|
|
+ Expressions[fieldName] = expression;
|
|
|
+ break;
|
|
|
+ case ReferenceType.Colour:
|
|
|
+ ColourExpressions[fieldName] = expression;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void LoadVariable(DigitalFormVariable variable, DFLayoutField field)
|
|
|
+ {
|
|
|
+ var properties = variable.LoadProperties(field);
|
|
|
+ LoadExpression(field.Name, properties?.Expression, ReferenceType.Value);
|
|
|
+ LoadExpression(field.Name, properties?.ColourExpression, ReferenceType.Colour);
|
|
|
}
|
|
|
|
|
|
public void LoadVariables(IEnumerable<DigitalFormVariable> variables)
|
|
@@ -223,9 +312,17 @@ namespace InABox.Core
|
|
|
public void ChangeField(string fieldName)
|
|
|
{
|
|
|
if (!VariableReferences.TryGetValue(fieldName, out var refs)) return;
|
|
|
- foreach(var reference in refs)
|
|
|
+ foreach(var (refType, refName) in refs)
|
|
|
{
|
|
|
- EvaluateExpression(reference);
|
|
|
+ switch (refType)
|
|
|
+ {
|
|
|
+ case ReferenceType.Value:
|
|
|
+ EvaluateValueExpression(refName);
|
|
|
+ break;
|
|
|
+ case ReferenceType.Colour:
|
|
|
+ EvaluateColourExpression(refName);
|
|
|
+ break;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -233,7 +330,11 @@ namespace InABox.Core
|
|
|
{
|
|
|
foreach(var name in Expressions.Keys)
|
|
|
{
|
|
|
- EvaluateExpression(name);
|
|
|
+ EvaluateValueExpression(name);
|
|
|
+ }
|
|
|
+ foreach(var name in ColourExpressions.Keys)
|
|
|
+ {
|
|
|
+ EvaluateColourExpression(name);
|
|
|
}
|
|
|
}
|
|
|
|