aboutsummaryrefslogtreecommitdiffstatsci
diff options
context:
space:
mode:
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>2020-06-02 01:18:31 +0200
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>2020-06-02 01:18:31 +0200
commitd137c0e74445b540bcdafc7a9e04463b4199c076 (patch)
tree674372c05f9b6e8b34e8cf4a8ffe4b464328c377
parentd46cbe601a9d5d4437f256a496f29a3fe6881da8 (diff)
styling constants
-rw-r--r--Crow.sln3
-rw-r--r--Crow/Default.style6
-rw-r--r--Crow/src/Interface.cs15
-rw-r--r--Crow/src/styling/StyleReader.cs107
-rw-r--r--Samples/BasicTests/BasicTests.cs6
-rw-r--r--Samples/common/SampleBase.cs2
6 files changed, 94 insertions, 45 deletions
diff --git a/Crow.sln b/Crow.sln
index 159a127b..df52304f 100644
--- a/Crow.sln
+++ b/Crow.sln
@@ -11,6 +11,9 @@ EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Crow", "Crow\Crow.csproj", "{C2980F9B-4798-4C05-99E2-E174810F7C7B}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{B2C7855A-2878-47FD-AD32-9A83DB4AB8C6}"
+ ProjectSection(SolutionItems) = preProject
+ Samples\Directory.Build.props = Samples\Directory.Build.props
+ EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HelloWorld", "Samples\HelloWorld\HelloWorld.csproj", "{F535A8AB-CD93-49AB-B1B0-FFF9AE51ED6A}"
EndProject
diff --git a/Crow/Default.style b/Crow/Default.style
index 6264dafe..8c443443 100644
--- a/Crow/Default.style
+++ b/Crow/Default.style
@@ -1,4 +1,6 @@
-Button, CheckBox, RadioButton, ComboBox, Expandable,
+ControlBackground = "Transparent";
+
+Button, CheckBox, RadioButton, ComboBox, Expandable,
MessageBox, Popper, Slider, Spinner, TextBox {
Focusable = "true";
Height = "Fit";
@@ -19,7 +21,7 @@ Control {
ControlBorder {
BorderWidth = "1";
Foreground = "DimGrey";
- Background = "Transparent";
+ Background = "${ControlBackground}";
CornerRadius = "0";
}
ControlCaption {
diff --git a/Crow/src/Interface.cs b/Crow/src/Interface.cs
index f97eb8e1..721404d2 100644
--- a/Crow/src/Interface.cs
+++ b/Crow/src/Interface.cs
@@ -435,6 +435,16 @@ namespace Crow
public Dictionary<String, LoaderInvoker> DefaultValuesLoader = new Dictionary<string, LoaderInvoker>();
/// <summary>Store dictionnary of member/value per StyleKey</summary>
public Dictionary<string, Style> Styling;
+ /// <summary>
+ /// Replacement value for style like cmake or bash variable.
+ /// </summary>
+ /// <remarks>
+ /// each 'key=value' pair in style files not enclosed in brackets are threated as constant.
+ /// If the same constant is defined more than once, only the first is kept.
+ /// Than in any IML expresion, in style or xml, constant may be used as a replacement string with ${CONSTANTID}.
+ /// If a constant is not resolved in iml while creating the instantiator, an error is thrown.
+ /// </remarks>
+ public readonly Dictionary<string, string> StylingConstants = new Dictionary<string, string> ();
/// <summary> parse all styling data's during application startup and build global Styling Dictionary </summary>
protected virtual void loadStyling() {
Styling = new Dictionary<string, Style> ();
@@ -451,9 +461,8 @@ namespace Crow
foreach (string s in assembly
.GetManifestResourceNames ()
.Where (r => r.EndsWith (".style", StringComparison.OrdinalIgnoreCase))) {
- using (Stream stream = assembly.GetManifestResourceStream (s)) {
- new StyleReader (this.Styling, stream, s);
- }
+ using (StyleReader sr = new StyleReader (assembly.GetManifestResourceStream (s)))
+ sr.Parse (this, s);
}
}
#endregion
diff --git a/Crow/src/styling/StyleReader.cs b/Crow/src/styling/StyleReader.cs
index 77b8967d..cace196a 100644
--- a/Crow/src/styling/StyleReader.cs
+++ b/Crow/src/styling/StyleReader.cs
@@ -17,12 +17,10 @@ namespace Crow
//TODO: style key shared by different class may use only first encouneter class setter, which can cause bug.
public class StyleReader : StreamReader
{
- enum States { init, classNames, members, value, endOfStatement }
+ enum States { classNames, members, value, endOfStatement }
- States curState = States.init;
+ States curState = States.classNames;
- int column = 1;
- int line = 1;
#region Character ValidityCheck
static Regex rxValidChar = new Regex(@"\p{Lu}|\p{Ll}|\p{Lt}|\p{Lm}|\p{Lo}|\p{Nl}|\p{Mn}|\p{Mc}|\p{Nd}|\p{Pc}|\p{Cf}");
@@ -31,13 +29,11 @@ namespace Crow
static Regex rxDecimal = new Regex(@"[0-9]+");
static Regex rxHexadecimal = new Regex(@"[0-9a-fA-F]+");
- public bool nextCharIsValidCharStartName
- {
- get { return rxNameStartChar.IsMatch(new string(new char[]{PeekChar()})); }
+ bool nextCharIsValidCharStartName {
+ get => rxNameStartChar.IsMatch(new string(new char[]{PeekChar()}));
}
- public bool nextCharIsValidCharName
- {
- get { return rxNameChar.IsMatch(new string(new char[]{PeekChar()})); }
+ bool nextCharIsValidCharName {
+ get => rxNameChar.IsMatch(new string(new char[]{PeekChar()}));
}
#endregion
@@ -59,9 +55,17 @@ namespace Crow
}
}
- public StyleReader (Dictionary<string, Style> styling, Stream stream, string resId)
- : base(stream)
- {
+ /// <summary>
+ /// Parse the full style stream and load the result in 'Styling' and 'StylingConstant'
+ /// fields of the interface passed as argument.
+ /// </summary>
+ /// <param name="iFace">the Interface to load the style for</param>
+ public void Parse (Interface iFace, string resId)
+ {
+ int column = 1;
+ int line = 1;
+ curState = States.classNames;
+
string styleKey = resId.Substring (0, resId.Length - 6);
string token = "";
List<string> targetsClasses = new List<string> ();
@@ -72,7 +76,7 @@ namespace Crow
if (EndOfStream)
break;
- switch (Peek()) {
+ switch (Peek ()) {
case '/':
ReadChar ();
if (PeekChar () != '/')
@@ -81,7 +85,7 @@ namespace Crow
break;
case ',':
ReadChar ();
- if (!(curState == States.init || curState == States.classNames) || string.IsNullOrEmpty (token))
+ if (!(curState == States.classNames) || string.IsNullOrEmpty (token))
throw new ParserException (line, column, "Unexpected char ','", resId);
targetsClasses.Add (token);
token = "";
@@ -89,7 +93,7 @@ namespace Crow
break;
case '{':
ReadChar ();
- if (!(curState == States.init || curState == States.classNames) || string.IsNullOrEmpty (token))
+ if (curState != States.classNames || string.IsNullOrEmpty (token))
throw new ParserException (line, column, "Unexpected char '{'", resId);
targetsClasses.Add (token);
token = "";
@@ -104,7 +108,7 @@ namespace Crow
break;
case '=':
ReadChar ();
- if (!(curState == States.init || curState == States.members))
+ if (!(curState == States.members || curState == States.classNames) || string.IsNullOrEmpty (token))
throw new ParserException (line, column, "Unexpected char '='", resId);
currentProperty = token;
token = "";
@@ -112,38 +116,59 @@ namespace Crow
break;
case '"':
if (curState != States.value)
- throw new ParserException (line, column, "Unexpected char '\"'", resId);
+ throw new ParserException (line, column, "Unexpected char '\"'", resId);
ReadChar ();
while (!EndOfStream) {
- char c = PeekChar();
- if (c == '\"') {
- ReadChar ();
+ char c = ReadChar ();
+ if (c == '$') {
+ if (PeekChar () == '{') {
+ ReadChar ();
+ //constant replacement
+ string constantId = "";
+ while (!EndOfStream) {
+ c = ReadChar ();
+ if (c == '}')
+ break;
+ constantId += c;
+ }
+ if (string.IsNullOrEmpty (constantId) || !iFace.StylingConstants.ContainsKey (constantId))
+ throw new ParserException (line, column, "Empty constant id in styling", resId);
+ token += iFace.StylingConstants [constantId];
+ continue;
+ }
+ } else if (c == '\"') {
+ curState = States.endOfStatement;
break;
}
- token += ReadChar();
- if (c == '\\' && !EndOfStream)
- token += ReadChar();
+ token += c;
}
- curState = States.endOfStatement;
break;
case ';':
if (curState != States.endOfStatement)
- throw new ParserException (line, column, "Unexpected end of statement", resId);
+ throw new ParserException (line, column, "Unexpected end of statement", resId);
ReadChar ();
- foreach (string tc in targetsClasses) {
- if (!styling.ContainsKey (tc))
- styling [tc] = new Style ();
- else if (styling [tc].ContainsKey (currentProperty))
- continue;
- styling [tc] [currentProperty] = token;
- #if DESIGN_MODE
+ if (targetsClasses.Count == 0) {
+ //style constant
+ if (!iFace.StylingConstants.ContainsKey (currentProperty))
+ iFace.StylingConstants.Add (currentProperty, token);
+ curState = States.classNames;
+ } else {
+ foreach (string tc in targetsClasses) {
+ if (!iFace.Styling.ContainsKey (tc))
+ iFace.Styling [tc] = new Style ();
+ else if (iFace.Styling [tc].ContainsKey (currentProperty))
+ continue;
+ iFace.Styling [tc] [currentProperty] = token;
+#if DESIGN_MODE
styling [tc].Locations[currentProperty] = new FileLocation(resId, line, column - token.Length - 1, token.Length);
- #endif
- //System.Diagnostics.Debug.WriteLine ("Style: {3} : {0}.{1} = {2}", tc, currentProperty, token, resId);
+#endif
+ //System.Diagnostics.Debug.WriteLine ("Style: {3} : {0}.{1} = {2}", tc, currentProperty, token, resId);
+ }
+ curState = States.members;
}
token = "";
- curState = States.members;
+ currentProperty = "";
break;
default:
if (curState == States.value)
@@ -152,13 +177,19 @@ namespace Crow
throw new ParserException (line, column, "expecting end of statement", resId);
if (nextCharIsValidCharStartName) {
- token += ReadChar();
+ token += ReadChar ();
while (nextCharIsValidCharName)
- token += ReadChar();
+ token += ReadChar ();
}
break;
}
}
+
+ }
+
+ public StyleReader (Stream stream)
+ : base(stream)
+ {
}
}
}
diff --git a/Samples/BasicTests/BasicTests.cs b/Samples/BasicTests/BasicTests.cs
index fba4b70a..1a9340d5 100644
--- a/Samples/BasicTests/BasicTests.cs
+++ b/Samples/BasicTests/BasicTests.cs
@@ -15,6 +15,7 @@ namespace tests
#if NETCOREAPP3_1
DllMapCore.Resolve.Enable (true);
#endif
+
using (BasicTests app = new BasicTests ()) {
app.Run ();
}
@@ -98,8 +99,11 @@ namespace tests
else if (idx < 0)
idx = testFiles.Length - 1;
+#if NETCOREAPP3_1
Console.WriteLine ($"Loading {testFiles [idx]}. {AppDomain.CurrentDomain.MonitoringSurvivedMemorySize}");
-
+#else
+ Console.WriteLine ($"Loading {testFiles [idx]}. {GC.GetTotalMemory(true)}");
+#endif
Load (testFiles [idx]).DataSource = this;
} catch (Exception ex) {
(LoadIMLFragment ($"<Label Background='Red' Foreground='White' Height='Fit' Width='Stretched' Multiline='true' VerticalAlignment='Bottom' Margin='5' />") as Label).Text = ex.ToString();
diff --git a/Samples/common/SampleBase.cs b/Samples/common/SampleBase.cs
index 6800e9ef..0007fc23 100644
--- a/Samples/common/SampleBase.cs
+++ b/Samples/common/SampleBase.cs
@@ -12,7 +12,7 @@ namespace Crow
public Version CrowVersion => Assembly.GetAssembly (typeof (Widget)).GetName ().Version;
#region Test values for Binding
- public List<Crow.Command> Commands;
+ public List<Command> Commands;
public int intValue = 500;
VerticalAlignment currentVAlign;