EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BindingTest", "Samples\BindingTest\BindingTest.csproj", "{242094B3-A1F1-44F8-B78D-D819B595DDBA}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PathPainter", "Samples\PathPainter\PathPainter.csproj", "{4066FE1E-3508-4361-ABAA-21601F632ED8}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
{242094B3-A1F1-44F8-B78D-D819B595DDBA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{242094B3-A1F1-44F8-B78D-D819B595DDBA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{242094B3-A1F1-44F8-B78D-D819B595DDBA}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4066FE1E-3508-4361-ABAA-21601F632ED8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4066FE1E-3508-4361-ABAA-21601F632ED8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4066FE1E-3508-4361-ABAA-21601F632ED8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4066FE1E-3508-4361-ABAA-21601F632ED8}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
{6E361E34-D266-4BEB-97F4-E209E01C6246} = {B2C7855A-2878-47FD-AD32-9A83DB4AB8C6}
{E19FD3DB-902A-4C99-8BF0-5ACAFFE35608} = {B2C7855A-2878-47FD-AD32-9A83DB4AB8C6}
{242094B3-A1F1-44F8-B78D-D819B595DDBA} = {B2C7855A-2878-47FD-AD32-9A83DB4AB8C6}
+ {4066FE1E-3508-4361-ABAA-21601F632ED8} = {B2C7855A-2878-47FD-AD32-9A83DB4AB8C6}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {00D4E149-7131-49F4-BAAD-559AA961A78E}
<PackageProjectUrl>https://github.com/jpbruyere/Crow/wiki</PackageProjectUrl>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageIcon>crow.png</PackageIcon>
- <PackageCopyright>Copyright 2013-2020</PackageCopyright>
+ <PackageCopyright>Copyright 2013-2021</PackageCopyright>
<PackageReleaseNotes>
</PackageReleaseNotes>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>$(NoWarn);1591;1587;1570;1572;1573;1574</NoWarn>
- <DefineConstants>DESIGN_MODE;_MEASURE_TIME</DefineConstants>
+ <DefineConstants>_DESIGN_MODE;_MEASURE_TIME</DefineConstants>
<EnableDefaultItems>false</EnableDefaultItems>
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
<!--<AllowUnsafeBlocks>true</AllowUnsafeBlocks>-->
public static Size operator + (Size s, int i) => new Size (s.Width + i, s.Height + i);
public static Size operator * (Size s, int i) => new Size (s.Width * i, s.Height * i);
public static Size operator / (Size s, int i) => new Size (s.Width / i, s.Height / i);
+
+ public static Size operator * (Size s, double i) => new Size ((int)(s.Width * i), (int)(s.Height * i));
#endregion
IFaceLoad = IFace | 0x05,
IFaceInit = IFace | 0x06,
CreateITor = IFace | 0x07,
+ IFaceReleadTheme = IFace | 0x08,
HoverWidget = IFace | Focus | Widget | 0x01,
FocusedWidget = IFace | Focus | Widget | 0x02,
/// <summary>
/// Derived from FILL for loading and drawing bitmaps in the interface
/// </summary>
- public class BmpPicture : Picture
- {
+ public class BmpPicture : Picture {
byte[] image = null;
#region CTOR
/// <summary>
/// Initializes a new instance of BmpPicture.
/// </summary>
- public BmpPicture () {}
+ public BmpPicture () { }
/// <summary>
/// Initializes a new instance of BmpPicture by loading the image pointed by the path argument
/// </summary>
/// <param name="path">image path, may be embedded</param>
- public BmpPicture (string path) : base(path) { }
+ public BmpPicture (string path) : base (path) { }
#endregion
/// <summary>
/// load the image for rendering from the path given as argument
/// </summary>
- void load (Interface iFace)
- {
+ void load (Interface iFace) {
if (iFace.sharedPictures.ContainsKey (Path)) {
- sharedPicture sp = iFace.sharedPictures [Path];
+ sharedPicture sp = iFace.sharedPictures[Path];
image = (byte[])sp.Data;
Dimensions = sp.Dims;
return;
}
using (Stream stream = iFace.GetStreamFromPath (Path)) {
+ load (stream);
+ //loadBitmap (new System.Drawing.Bitmap (stream));
+ iFace.sharedPictures[Path] = new sharedPicture (image, Dimensions);
+ }
+ }
+ void load (Stream stream) {
#if STB_SHARP
- StbImageSharp.ImageResult stbi = StbImageSharp.ImageResult.FromStream (stream, StbImageSharp.ColorComponents.RedGreenBlueAlpha);
- image = new byte [stbi.Data.Length];
- //rgba to argb for cairo.
- for (int i = 0; i < stbi.Data.Length; i += 4) {
- image [i] = stbi.Data[i + 2];
- image [i + 1] = stbi.Data [i + 1];
- image [i + 2] = stbi.Data [i];
- image [i + 3] = stbi.Data [i + 3];
- }
- Dimensions = new Size (stbi.Width, stbi.Height);
+ StbImageSharp.ImageResult stbi = StbImageSharp.ImageResult.FromStream (stream, StbImageSharp.ColorComponents.RedGreenBlueAlpha);
+ image = new byte[stbi.Data.Length];
+ //rgba to argb for cairo.
+ for (int i = 0; i < stbi.Data.Length; i += 4) {
+ image[i] = stbi.Data[i + 2];
+ image[i + 1] = stbi.Data[i + 1];
+ image[i + 2] = stbi.Data[i];
+ image[i + 3] = stbi.Data[i + 3];
+ }
+ Dimensions = new Size (stbi.Width, stbi.Height);
#else
using (StbImage stbi = new StbImage (stream)) {
image = new byte [stbi.Size];
Dimensions = new Size (stbi.Width, stbi.Height);
}
#endif
-
- //loadBitmap (new System.Drawing.Bitmap (stream));
- }
- iFace.sharedPictures [Path] = new sharedPicture (image, Dimensions);
}
-
+ internal static sharedPicture CreateSharedPicture (Stream stream) {
+ BmpPicture pic = new BmpPicture ();
+ pic.load (stream);
+ return new sharedPicture (pic.image, pic.Dimensions);
+ }
//load image via System.Drawing.Bitmap, cairo load png only
bitmap.UnlockBits (data);
}*/
-#region implemented abstract members of Fill
+ #region implemented abstract members of Fill
public override void SetAsSource (Interface iFace, Context ctx, Rectangle bounds = default(Rectangle))
{
Dimensions = sp.Dims;
return;
}
- using (Stream stream = iFace.GetStreamFromPath (Path)) {
- using (MemoryStream ms = new MemoryStream ()) {
- stream.CopyTo (ms);
-
- hSVG = new Rsvg.Handle (ms.ToArray ());
- Dimensions = new Size (hSVG.Dimensions.Width, hSVG.Dimensions.Height);
- }
- }
+ using (Stream stream = iFace.GetStreamFromPath (Path))
+ load (stream);
iFace.sharedPictures [Path] = new sharedPicture (hSVG, Dimensions);
}
+ void load (Stream stream) {
+ using (BinaryReader sr = new BinaryReader (stream)) {
+ hSVG = new Rsvg.Handle (sr.ReadBytes ((int)stream.Length));
+ Dimensions = new Size (hSVG.Dimensions.Width, hSVG.Dimensions.Height);
+ }
+ }
+ internal static sharedPicture CreateSharedPicture (Stream stream) {
+ SvgPicture pic = new SvgPicture ();
+ pic.load (stream);
+ return new sharedPicture (pic.hSVG, pic.Dimensions);
+ }
public void LoadSvgFragment (string fragment) {
hSVG = new Rsvg.Handle (System.Text.Encoding.Unicode.GetBytes(fragment));
il.Emit (OpCodes.Pop);//remove null string from stack
il.Emit (OpCodes.Ldstr, "");//replace with empty string
il.MarkLabel (endConvert);
- } else if ((origType.IsEnum || origType == typeof (Enum)) && destType.IsEnum) {//TODO:double check this (multiple IsEnum test, no check of enum underlying type
+ } else if ((origType.IsEnum || origType == typeof (Enum)) && (destType.IsEnum) || destType == typeof (Enum)) {//TODO:double check this (multiple IsEnum test, no check of enum underlying type
il.Emit (OpCodes.Unbox_Any, destType);
return;
} else if (origType.IsValueType) {
/// </remarks>
/// <returns>the corresponding type object</returns>
/// <param name="typeName">graphic object type name without its namespace</param>
- Type tryGetGOType (string typeName){
+ internal static Type tryGetGOType (string typeName){
if (knownGOTypes.ContainsKey (typeName))
return knownGOTypes [typeName];
Type t = Type.GetType ("Crow." + typeName);
using System.Diagnostics;
using System.Globalization;
using System.IO;
+using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using Crow.Cairo;
using Crow.IML;
using Glfw;
+using Path = System.IO.Path;
namespace Crow
{
/// </summary>
public void Init () {
DbgLogger.StartEvent (DbgEvtType.IFaceInit);
+ initDictionaries ();
loadStyling ();
+ loadThemeFiles ();
initTooltip ();
initContextMenus ();
OnInitialized ();
// TODO: dispose managed state (managed objects).
}
- currentCursor?.Dispose ();
+ currentCursor?.Dispose ();
+ disposeContextMenus ();
+
if (ownWindow) {
Glfw3.DestroyWindow (hWin);
Glfw3.Terminate ();
/// <summary>each IML and fragments (such as inline Templates) are compiled as a Dynamic Method stored here
/// on the first instance creation of a IML item.
/// </summary>
- public Dictionary<String, Instantiator> Instantiators = new Dictionary<string, Instantiator>();
- public Dictionary<String, Instantiator> Templates = new Dictionary<string, Instantiator> ();
+ public Dictionary<String, Instantiator> Instantiators;
/// <summary>
/// default templates dic by metadata token
/// </summary>
- public Dictionary<int, Instantiator> DefaultTemplates = new Dictionary<int, Instantiator> ();
+ public Dictionary<int, Instantiator> DefaultTemplates;
/// <summary>
/// Item templates stored with their index
/// </summary>
- public Dictionary<String, ItemTemplate> ItemTemplates = new Dictionary<string, ItemTemplate> ();
+ public Dictionary<String, ItemTemplate> ItemTemplates;
public List<CrowThread> CrowThreads = new List<CrowThread>();//used to monitor thread finished
/// The compilation is done on the first object instancing, and is also done for custom widgets
public delegate void LoaderInvoker(object instance);
/// <summary>Store one loader per StyleKey</summary>
- public Dictionary<String, LoaderInvoker> DefaultValuesLoader = new Dictionary<string, LoaderInvoker>();
+ public Dictionary<String, LoaderInvoker> DefaultValuesLoader;
/// <summary>Store dictionnary of member/value per StyleKey</summary>
public Dictionary<string, Style> Styling;
/// <summary>
public Dictionary<string, string> StylingConstants;
/// <summary> parse all styling data's during application startup and build global Styling Dictionary </summary>
protected virtual void loadStyling() {
- StylingConstants = new Dictionary<string, string> ();
- Styling = new Dictionary<string, Style> ();
-
//fetch styling info in this order, if member styling is alreadey referenced in previous
//assembly, it's ignored.
+ loadThemeStyle ();
loadStylingFromAssembly (Assembly.GetExecutingAssembly ());
foreach (Assembly a in crowAssemblies) {
.GetManifestResourceNames ()
.Where (r => r.EndsWith (".style", StringComparison.OrdinalIgnoreCase))) {
using (StyleReader sr = new StyleReader (assembly.GetManifestResourceStream (s)))
- sr.Parse (StylingConstants, Styling, s);
+ sr.Parse (StylingConstants, Styling, s);
}
}
public void LoadStyle (string stylePath) {
}
#endregion
+ #region Theming
+ string theme;
+ public string Theme {
+ get => theme;
+ set {
+ if (theme == value)
+ return;
+ theme = value;
+ NotifyValueChanged (theme);
+
+ if (StylingConstants == null)//iFace not yet initialized
+ return;
+ lock (UpdateMutex) {
+ DbgLogger.StartEvent (DbgEvtType.IFaceReleadTheme);
+ disposeContextMenus ();
+ initDictionaries ();
+ loadStyling ();
+ loadThemeFiles ();
+ initContextMenus ();
+ DbgLogger.EndEvent (DbgEvtType.IFaceReleadTheme);
+ }
+ }
+ }
+ protected void initDictionaries () {
+ const int initCapacity = 20;
+ StylingConstants = new Dictionary<string, string> (initCapacity);
+ Styling = new Dictionary<string, Style> (initCapacity);
+ DefaultValuesLoader = new Dictionary<string, LoaderInvoker> (initCapacity);
+ Instantiators = new Dictionary<string, Instantiator> (initCapacity);
+ DefaultTemplates = new Dictionary<int, Instantiator> (initCapacity);
+ ItemTemplates = new Dictionary<string, ItemTemplate> (initCapacity);
+ }
+ void loadThemeFiles () {
+ if (string.IsNullOrEmpty (Theme))
+ return;
+ try {
+ if (Directory.Exists (theme)) {
+ string path = Path.Combine (Theme, "Images");
+ if (Directory.Exists (path)) {
+ foreach (string pic in Directory.GetFiles (path, "*.*", SearchOption.AllDirectories)) {
+ string resId = $"#{pic.Substring (path.Length + 1).Replace (Path.DirectorySeparatorChar, '.')}";
+ using (Stream s = new FileStream (pic, FileMode.Open, FileAccess.Read)) {
+ if (resId.EndsWith (".svg", StringComparison.OrdinalIgnoreCase))
+ sharedPictures[resId] = SvgPicture.CreateSharedPicture (s);
+ else
+ sharedPictures[resId] = BmpPicture.CreateSharedPicture (s);
+ }
+ }
+ }
+ if (Directory.Exists (path)) {
+ path = Path.Combine (Theme, "DefaultTemplates");
+ foreach (string iml in Directory.GetFiles (path, "*.*", SearchOption.AllDirectories)) {
+ string resId = $"#{iml.Substring (path.Length + 1).Replace (Path.DirectorySeparatorChar, '.')}";
+ int mdTok = Instantiator.tryGetGOType (resId.Substring (6, resId.Length - 15)).MetadataToken;
+ using (Stream s = new FileStream (iml, FileMode.Open, FileAccess.Read))
+ DefaultTemplates[mdTok] = new IML.Instantiator (this, s, resId);
+ }
+ }
+ path = Path.Combine (Theme, "IML");
+ if (Directory.Exists (path)) {
+ foreach (string iml in Directory.GetFiles (path, "*.*", SearchOption.AllDirectories)) {
+ string resId = $"#{iml.Substring (path.Length + 1).Replace (Path.DirectorySeparatorChar, '.')}";
+ using (Stream s = new FileStream (iml, FileMode.Open, FileAccess.Read))
+ Instantiators[path] = new Instantiator (this, s, path);
+ }
+ }
+ path = Path.Combine (Theme, "ItemTemplates");
+ if (Directory.Exists (path)) {
+ foreach (string iml in Directory.GetFiles (path, "*.*", SearchOption.AllDirectories)) {
+ string resId = $"#{iml.Substring (path.Length + 1).Replace (Path.DirectorySeparatorChar, '.')}";
+ using (Stream s = new FileStream (iml, FileMode.Open, FileAccess.Read))
+ ItemTemplates[path] = new ItemTemplate (this, s, path);
+ }
+ }
+ return;
+ }
+ using (ZipArchive archive = ZipFile.Open (Theme, ZipArchiveMode.Read)) {
+ foreach (ZipArchiveEntry entry in archive.Entries.Where (e => e.FullName.StartsWith ("Images"))) {
+ Console.WriteLine (entry.FullName);
+ }
+ foreach (ZipArchiveEntry entry in archive.Entries.Where (e => e.FullName.StartsWith ("IML"))) {
+ Console.WriteLine (entry.FullName);
+ }
+ }
+ } catch (Exception e) {
+ throw new Exception ($"[Theme] Error reading theme ({Theme})", e);
+ }
+ }
+ void loadThemeStyle () {
+ if (string.IsNullOrEmpty (Theme))
+ return;
+ try {
+ if (Directory.Exists (theme)) {
+ string stylePath = Directory.GetFiles (theme, "*.style").FirstOrDefault ();
+ using (Stream s = new FileStream (stylePath, FileMode.Open, FileAccess.Read)) {
+ using (StyleReader sr = new StyleReader (s))
+ sr.Parse (StylingConstants, Styling, stylePath);
+ }
+ return;
+ }
+ using (ZipArchive archive = ZipFile.Open (Theme, ZipArchiveMode.Read)) {
+ ZipArchiveEntry zipStyle = archive.Entries.FirstOrDefault (e => e.FullName.EndsWith (".style", StringComparison.OrdinalIgnoreCase));
+ if (zipStyle != null) {
+ using (Stream s = zipStyle.Open ()) {
+ using (StyleReader sr = new StyleReader (s))
+ sr.Parse (StylingConstants, Styling, zipStyle.FullName);
+ }
+ }
+ }
+ } catch (Exception e) {
+ throw new Exception ($"[Theme] Error reading theme style ({Theme})", e);
+ }
+ }
+ #endregion
#region Load/Save
/// <summary>
#region Mouse and Keyboard Handling
MouseCursor cursor = MouseCursor.top_left_arrow;
- void loadCursors ()
+ [Obsolete]void loadCursors ()
{
const int minimumSize = 24;
XCursor.Cursors [MouseCursor.xterm] = XCursorFile.Load (this, "#Crow.Cursors.xterm").Cursors.First (c => c.Width >= minimumSize);
}
-
Stopwatch lastMouseDown = Stopwatch.StartNew (), mouseRepeatTimer = new Stopwatch ();
bool doubleClickTriggered; //next mouse up will trigger a double click
MouseButtonEventArgs lastMouseDownEvent;
ctxMenuContainer = CreateInstance ("#Crow.ContextMenu.template") as MenuItem;
ctxMenuContainer.LayoutChanged += CtxMenuContainer_LayoutChanged;
}
+ protected void disposeContextMenus () {
+ if (ctxMenuContainer == null)
+ return;
+ ctxMenuContainer.LayoutChanged -= CtxMenuContainer_LayoutChanged;
+ ctxMenuContainer.Dispose ();
+ }
void CtxMenuContainer_LayoutChanged (object sender, LayoutingEventArgs e)
{
/// <param name="ImlFragment">IML fragment to parse</param>
/// <param name="_dataType">type this item will be choosen for, or member of the data item</param>
/// <param name="_fetchDataMethod">for hierarchical data, method to call for children fetching</param>
- public ItemTemplate (Interface _iface, Stream ImlFragment, string _dataTest, string _dataType, string _fetchDataMethod)
- :base(_iface, ImlFragment)
+ public ItemTemplate (Interface _iface, Stream ImlFragment, string _dataTest = "TypeOf", string _dataType = "default", string _fetchDataMethod = null)
+ : base(_iface, ImlFragment)
{
strDataType = _dataType;
fetchMethodName = _fetchDataMethod;
if (lt == LayoutingType.Height) {
MaxScrollY = child.Slot.Height - cb.Height;
if (child.Slot.Height > 0)
- NotifyValueChanged ("ChildHeightRatio", Slot.Height * Slot.Height / child.Slot.Height);
+ NotifyValueChanged ("ChildHeightRatio", (double)Slot.Height / child.Slot.Height);
} else if (lt == LayoutingType.Width) {
MaxScrollX = child.Slot.Width - cb.Width;
if (child.Slot.Width > 0)
- NotifyValueChanged ("ChildWidthRatio", Slot.Width * Slot.Width / child.Slot.Width);
+ NotifyValueChanged ("ChildWidthRatio", (double)Slot.Width / child.Slot.Width);
}
}
void onChildListCleared(object sender, EventArgs e){
if (size == value)
return;
size = value;
- contentSize = default (Size);
+ contentSize = default;
NotifyValueChangedAuto (size);
- RegisterForLayouting (LayoutingType.Sizing);
+ //RegisterForLayouting (LayoutingType.Sizing);
+ RegisterForGraphicUpdate ();
}
}
-// Copyright (c) 2013-2019 Bruyère Jean-Philippe <jp_bruyere@hotmail.com>
+// Copyright (c) 2013-2021 Bruyère Jean-Philippe <jp_bruyere@hotmail.com>
//
// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
}
void onUp (object sender, MouseButtonEventArgs e)
{
- Value += this.SmallIncrement;
+ if (IFace.Ctrl)
+ Value += SmallIncrement;
+ else
+ Value += LargeIncrement;
}
void onDown (object sender, MouseButtonEventArgs e)
{
- Value -= this.SmallIncrement;
+ if (IFace.Ctrl)
+ Value -= SmallIncrement;
+ else
+ Value -= LargeIncrement;
}
}
throw new ParserException (line, column, "Unexpected end of statement", resId);
ReadChar ();
if (targetsClasses.Count == 0) {
- //style constants
- StylingConstants[currentProperty] = token.ToString ();
+ //style constants, only the first occurence is kept
+ if (!StylingConstants.ContainsKey (currentProperty))
+ StylingConstants[currentProperty] = token.ToString ();
curState = States.classNames;
} else {
foreach (string tc in targetsClasses) {
--- /dev/null
+using Crow.Cairo;
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Text;
+
+namespace Crow
+{
+ public class Painter : ScrollingObject
+ {
+ #region CTOR
+ protected Painter () { }
+ public Painter (Interface iface, string style = null) : base (iface, style) { }
+ #endregion
+
+ public class Point
+ {
+ public double X;
+ public double Y;
+ }
+
+ public enum DrawMode
+ {
+ Select,
+ Lines,
+ Rect,
+ Arc,
+ }
+ DrawMode currentDrawMode = DrawMode.Select;
+ public DrawMode CurrentDrawMode {
+ get => currentDrawMode;
+ set {
+ if (value == currentDrawMode)
+ return;
+ currentDrawMode = value;
+ NotifyValueChanged ("CurrentDrawMode", currentDrawMode);
+ updateMouseCursor ();
+ }
+ }
+
+ void updateMouseCursor () {
+ if (currentDrawMode == DrawMode.Select)
+ MouseCursor = MouseCursor.arrow;
+ else
+ MouseCursor = MouseCursor.crosshair;
+ }
+
+ public double[] Zooms => new double[] { 0.5, 1.0, 2.0, 4.0, 8.0, 16.0 };
+
+ string path;
+ double strokeWidth;
+ Size size;
+ double zoom;
+ Fill shapeBackground, shapeForeground;
+
+ [DefaultValue(1.0)]
+ public double Zoom {
+ get => zoom;
+ set {
+ if (zoom == value)
+ return;
+ zoom = value;
+ NotifyValueChangedAuto (zoom);
+ RegisterForGraphicUpdate ();
+ updateMaxScrolls ();
+ }
+ }
+
+ /// <summary>
+ /// Path expression, for syntax see 'PathParser'.
+ /// </summary>
+ public string Path {
+ get { return path; }
+ set {
+ if (path == value)
+ return;
+ path = value;
+ contentSize = default (Size);
+ NotifyValueChangedAuto (path);
+ RegisterForGraphicUpdate ();
+ }
+ }
+ /// <summary>
+ /// Default stroke width, may be overriden by a 'S' command in the path string.
+ /// </summary>
+ /// <value>The width of the stoke.</value>
+ [DefaultValue (1.0)]
+ public double StrokeWidth {
+ get { return strokeWidth; }
+ set {
+ if (strokeWidth == value)
+ return;
+ strokeWidth = value;
+ contentSize = default (Size);
+ NotifyValueChangedAuto (strokeWidth);
+ RegisterForGraphicUpdate ();
+ }
+ }
+ /// <summary>
+ /// View box size in pixel
+ /// </summary>
+ [DefaultValue ("32,32")]
+ public Size Size {
+ get { return size; }
+ set {
+ if (size == value)
+ return;
+ size = value;
+ NotifyValueChangedAuto (size);
+ //RegisterForLayouting (LayoutingType.Sizing);
+ RegisterForGraphicUpdate ();
+ updateMaxScrolls ();
+ }
+ }
+
+ [DefaultValue ("White")]
+ public virtual Fill ShapeBackground {
+ get => shapeBackground;
+ set {
+ if (shapeBackground == value)
+ return;
+ shapeBackground = value;
+ NotifyValueChangedAuto (shapeBackground);
+ RegisterForRedraw ();
+ }
+ }
+ [DefaultValue ("Black")]
+ public virtual Fill ShapeForeground {
+ get => shapeForeground;
+ set {
+ if (shapeForeground == value)
+ return;
+ shapeForeground = value;
+ NotifyValueChangedAuto (shapeForeground);
+ RegisterForRedraw ();
+ }
+ }
+
+ public override void OnLayoutChanges (LayoutingType layoutType) {
+ base.OnLayoutChanges (layoutType);
+
+ if (layoutType == LayoutingType.Height)
+ NotifyValueChanged ("PageHeight", Slot.Height);
+ else if (layoutType == LayoutingType.Width)
+ NotifyValueChanged ("PageWidth", Slot.Width);
+ else
+ return;
+ updateMaxScrolls ();
+ }
+ public override void onMouseEnter (object sender, MouseMoveEventArgs e) {
+ base.onMouseEnter (sender, e);
+ updateMouseCursor ();
+ }
+ protected override void onDraw (Context gr) {
+ base.onDraw (gr);
+
+ if (string.IsNullOrEmpty (path))
+ return;
+
+ Rectangle cr = ClientRectangle;
+
+ gr.Save ();
+ gr.Translate (-ScrollX, -ScrollY);
+ gr.Scale (Zoom, Zoom);
+
+ Rectangle r = new Rectangle (cr.Position, size);
+ shapeBackground.SetAsSource (IFace, gr);
+ gr.Rectangle (r);
+ gr.Fill ();
+
+ gr.LineWidth = strokeWidth;
+ ShapeForeground.SetAsSource (IFace, gr, cr);
+
+ using (PathParser parser = new PathParser (path))
+ parser.Draw (gr);
+
+ gr.Restore ();
+ }
+
+ public override void onMouseWheel (object sender, MouseWheelEventArgs e) {
+ if (e.Delta > 0)
+ Zoom *= 2.0;
+ else
+ Zoom /= 2.0;
+ e.Handled = true;
+ base.onMouseWheel (sender, e);
+ }
+
+ void updateMaxScrolls () {
+ Rectangle cb = ClientRectangle;
+ Size scalledSize = size * Zoom;
+
+ MaxScrollX = scalledSize.Width - cb.Width;
+ if (scalledSize.Width > 0)
+ NotifyValueChanged ("ChildWidthRatio", (double)cb.Width / scalledSize.Width);
+
+ MaxScrollY = scalledSize.Height - cb.Height;
+ if (scalledSize.Height > 0)
+ NotifyValueChanged ("ChildHeightRatio", (double)cb.Height / scalledSize.Height);
+ }
+ }
+}
--- /dev/null
+<Project Sdk="Microsoft.NET.Sdk">
+ <ItemGroup>
+ <EmbeddedResource Include="ui\**\*.*">
+ <LogicalName>ui.%(Filename)%(Extension)</LogicalName>
+ </EmbeddedResource>
+ </ItemGroup>
+</Project>
--- /dev/null
+using Crow;
+using System;
+
+namespace PathPainter
+{
+ class Program : SampleBase
+ {
+ static void Main (string[] args) {
+ using (Program app = new Program ())
+ app.Run ();
+ }
+
+ protected override void OnInitialized () {
+ base.OnInitialized ();
+ Load ("#ui.main.crow").DataSource = this;
+ }
+ string currentPath = "M 5.5,0.5 L 10.5,10.5 L 0.5,10.5 Z F";
+ int currentSize = 11;
+ double zoom = 1.0;
+ double strokeWidth = 1.0;
+ Color foreground = Colors.Black;
+ Color background = Colors.White;
+
+ public Measure DesignSize => (int)(zoom * currentSize);
+
+ public double StrokeWidth {
+ get => strokeWidth;
+ set {
+ if (strokeWidth == value)
+ return;
+ strokeWidth = value;
+ NotifyValueChanged (strokeWidth);
+ }
+ }
+ public string CurrentPath {
+ get => currentPath;
+ set {
+ if (currentPath == value)
+ return;
+ currentPath = value;
+ NotifyValueChanged (currentPath);
+ }
+ }
+ public Size Size => new Size (currentSize);
+ public int CurrentSize {
+ get => currentSize;
+ set {
+ if (currentSize == value)
+ return;
+ currentSize = value;
+ NotifyValueChanged (currentSize);
+ NotifyValueChanged ("Size", (object)new Size (currentSize));
+ NotifyValueChanged ("CurrentPath", (object)CurrentPath);
+ }
+ }
+ public Color Foreground {
+ get => foreground;
+ set {
+ if (foreground == value)
+ return;
+ foreground = value;
+ NotifyValueChanged (foreground);
+ }
+ }
+ public Color Background {
+ get => background;
+ set {
+ if (background == value)
+ return;
+ background = value;
+ NotifyValueChanged (background);
+ }
+ }
+
+ }
+}
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generated by IcoMoon.io -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16">
+<path fill="#dddddd" d="M1 11.9l-1 4.1 4.1-1 9.2-9.2-3.1-3.1-9.2 9.2zM1.5 15l-0.4-0.5 0.4-2 2 2-2 0.5zM10.9 4.4l-8.1 8-0.6-0.6 8.1-8 0.6 0.6z"></path>
+<path fill="#dddddd" d="M15.3 0.7c-1.1-1.1-2.6-0.5-2.6-0.5l-1.5 1.5 3.1 3.1 1.5-1.5c0-0.1 0.6-1.5-0.5-2.6zM13.4 1.6l-0.5-0.5c0.6-0.6 1.1-0.1 1.1-0.1l-0.6 0.6z"></path>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generated by IcoMoon.io -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16">
+<path fill="#dddddd" d="M15 1h-14v14h14v-14zM14 14h-12v-12h12v12z"></path>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generated by IcoMoon.io -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16">
+<path fill="#dddddd" d="M11.6 5c-0.2 0-0.5 0-0.6 0 0-0.2-0.2-0.6-0.4-0.8s-0.6-0.4-1.1-0.4c-0.2 0-0.4 0-0.6 0.1-0.1-0.2-0.2-0.3-0.3-0.5-0.2-0.2-0.5-0.4-1.1-0.4-0.2 0-0.4 0-0.5 0.1v-1.7c0-0.6-0.4-1.4-1.4-1.4-0.4 0-0.8 0.2-1.1 0.4-0.5 0.6-0.5 1.4-0.5 1.4v4.3c-0.6 0.1-1.1 0.3-1.4 0.6-0.6 0.7-0.6 1.6-0.6 2.8 0 0.2 0 0.5 0 0.7 0 1.4 0.7 2.1 1.4 2.8l0.3 0.4c1.3 1.2 2.4 1.6 5.1 1.6 2.9 0 4.2-1.6 4.2-5.1v-2.5c0-0.7-0.2-2.1-1.4-2.4zM12 7.4v2.6c0 3.4-1.3 4.1-3.2 4.1-2.4 0-3.3-0.3-4.3-1.3-0.1-0.1-0.2-0.2-0.4-0.4-0.7-0.8-1.1-1.2-1.1-2.2 0-0.2 0-0.5 0-0.7 0-1 0-1.7 0.3-2.1 0.1-0.1 0.4-0.2 0.7-0.2v0.5l-0.3 1.5c0 0.1 0 0.1 0.1 0.2s0.2 0 0.2 0l1-1.2c0-0.1 0-0.2 0-0.2v-6.2c0-0.1 0-0.5 0.2-0.7 0.1 0 0.2-0.1 0.4-0.1 0.3 0 0.4 0.3 0.4 0.4v3.1c0 0 0 0 0 0v1.2c0 0.3 0.2 0.6 0.5 0.6s0.5-0.3 0.5-0.5v-1.3c0 0 0 0 0 0 0-0.1 0.1-0.5 0.5-0.5 0.3 0 0.5 0.1 0.5 0.4v1.3c0 0.3 0.2 0.6 0.5 0.6s0.5-0.3 0.5-0.5v-0.7c0-0.1 0.1-0.3 0.5-0.3 0.2 0 0.3 0.1 0.3 0.1 0.2 0.1 0.2 0.4 0.2 0.4v0.8c0 0.3 0.2 0.5 0.4 0.5 0.3 0 0.5-0.1 0.5-0.4 0-0.1 0.1-0.2 0.2-0.3 0 0 0.1 0 0.2 0 0.6 0.2 0.7 1.2 0.7 1.5 0-0.1 0-0.1 0 0z"></path>
+</svg>
--- /dev/null
+DrawModeStyle {
+ Template="#polytest.ui.iconCheckBox.template";
+}
\ No newline at end of file
--- /dev/null
+<?xml version="1.0"?>
+<VerticalStack>
+ <Label Text="{./Caption}"/>
+ <Border Style="ControlBorder" Background="{./Background}" CornerRadius="{./CornerRadius}">
+ <HorizontalStack Spacing="1">
+ <TextBox Style="ControlEditableText" Foreground="{./Foreground}" Font="{./Font}" Width="Stretched"
+ Text="{²./Value}" TextAlignment="Right" />
+ <VerticalStack Width="16" Height="Stretched" Spacing="0" Margin="0">
+ <Shape KeepProportions="false" Margin="1" Style="ArrowBut" Height="50%" MouseDown="./onUp" Size="10,10" Path="M 4.5,0.5 L 9.5,9.5 L 0.5,9.5 Z F"/>
+ <Shape KeepProportions="false" Margin="1" Style="ArrowBut" Height="50%" MouseDown="./onDown" Size="10,10" Path="M 0.5,0.5 L 9.5,0.5 L 4.5,9.5 Z F"/>
+ </VerticalStack>
+ </HorizontalStack>
+ </Border>
+</VerticalStack>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0"?>
+<CheckBox Caption="{./Caption}" IsChecked="{²./IsPopped}" Foreground="{./Foreground}" Background="{./Background}">
+ <Template>
+ <Border Style="ControlBorder" CornerRadius="{./CornerRadius}">
+ <HorizontalStack Spacing="10" Margin="5">
+ <Label Style="ControlCaption" Text="{./Caption}" />
+ <Border Foreground="White" Width="30" Height="20" Background="{./Background}" CornerRadius="5"/>
+ </HorizontalStack>
+ </Border>
+ </Template>
+</CheckBox>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0"?>
+<HorizontalStack Background="DarkGrey" >
+ <VerticalStack>
+ <HorizontalStack Height="Fit">
+ <EnumSelector Fit="true" Caption="Draw Mode" EnumValue="{²../../painter.CurrentDrawMode}" />
+ <ComboBox Data="{../../painter.Zooms}" SelectedItem="{²../../painter.Zoom}" Width="60"/>
+ </HorizontalStack>
+ <HorizontalStack>
+ <Border Foreground="Black" Width="Stretched" Height="Stretched" Margin="0" HorizontalAlignment="Left" VerticalAlignment="Top">
+ <Painter Name="painter" ShapeForeground="{Foreground}" ShapeBackground="{Background}"
+ Zoom="1"
+ Size="{Size}" Path="{²CurrentPath}" StrokeWidth="{StrokeWidth}"/>
+ </Border>
+ <ScrollBar Value="{²../painter.ScrollY}"
+ LargeIncrement="{../painter.PageHeight}" SmallIncrement="1"
+ CursorRatio="{../painter.ChildHeightRatio}" Maximum="{../painter.MaxScrollY}" />
+ </HorizontalStack>
+ <ScrollBar Style="HScrollBar" Value="{²../painter.ScrollX}"
+ LargeIncrement="{../painter.PageWidth}" SmallIncrement="1"
+ CursorRatio="{../painter.ChildWidthRatio}" Maximum="{../painter.MaxScrollX}" />
+ </VerticalStack>
+ <Splitter/>
+ <VerticalStack Margin="2" Spacing="2">
+ <TextBox Width="Stretched" Text="{²CurrentPath}"/>
+ <HorizontalStack Height="Fit">
+ <Spinner Caption="Stroke Width" SmallIncrement="0.1" LargeIncrement="0.5" Value="{²StrokeWidth}" Width="Fit" Template="#ui.Spinner.template"/>
+ <Spinner Caption="Size" Value="{²CurrentSize}" Width="Fit" Template="#ui.Spinner.template"/>
+ <Popper Caption="Foreground" Background="{Foreground}" Fit="True" Template="#ui.colorSelector.template">
+ <ColorPicker CurrentColor="{²Foreground}" Background="Onyx" Width="{../PopWidth}"/>
+ </Popper>
+ <Popper Caption="Background" Background="{Background}" Fit="True" Template="#ui.colorSelector.template">
+ <ColorPicker CurrentColor="{²Background}" Background="Onyx" Width="{../PopWidth}"/>
+ </Popper>
+ </HorizontalStack>
+ <Group Height="200" Background="Jet">
+ <Shape Left="23" Top="9" Margin="0" Width="16" Height="16" Foreground="{Foreground}" Background="{Background}" Size="{Size}" Path="{CurrentPath}" StrokeWidth="{StrokeWidth}"/>
+ <Shape Left="17" Top="31" Margin="0" Width="32" Height="32" Foreground="{Foreground}" Background="{Background}" Size="{Size}" Path="{CurrentPath}" StrokeWidth="{StrokeWidth}"/>
+ <Shape Left="65" Top="1" Margin="0" Width="64" Height="64" Foreground="{Foreground}" Background="{Background}" Size="{Size}" Path="{CurrentPath}" StrokeWidth="{StrokeWidth}"/>
+ <Shape Left="1" Top="66" Margin="0" Width="128" Height="128" Foreground="{Foreground}" Background="{Background}" Size="{Size}" Path="{CurrentPath}" StrokeWidth="{StrokeWidth}"/>
+ </Group>
+
+ </VerticalStack>
+</HorizontalStack>
static void Main ()
{
DbgLogger.IncludeEvents = DbgEvtType.Widget;
- DbgLogger.DiscardEvents = DbgEvtType.Focus;
+ DbgLogger.DiscardEvents = DbgEvtType.Focus | DbgEvtType.IFace;
Environment.SetEnvironmentVariable ("FONTCONFIG_PATH", @"C:\Users\Jean-Philippe\source\vcpkg\installed\x64-windows\tools\fontconfig\fonts");
- using (Showcase app = new Showcase ())
+ using (Showcase app = new Showcase ()) {
+ //app.Theme = @"C:\Users\Jean-Philippe\source\Crow\Themes\TestTheme";
app.Run ();
+ }
}
public Container crowContainer;
-using System.Net.NetworkInformation;
-using System.Runtime.InteropServices;
+using Crow;
+using Glfw;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
+using System.Net.NetworkInformation;
using System.Reflection;
using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
using System.Threading;
-using Crow;
-using Glfw;
namespace Crow
{
- public class SampleBase : Interface {
-#if NETCOREAPP
+ public class SampleBase : Interface
+ {
+#if NETCOREAPP
static IntPtr resolveUnmanaged (Assembly assembly, String libraryName) {
switch (libraryName)
System.Runtime.Loader.AssemblyLoadContext.Default.ResolvingUnmanagedDll+=resolveUnmanaged;
}
#endif
- public Version CrowVersion => Assembly.GetAssembly (typeof (Widget)).GetName ().Version;
+ public Version CrowVersion => Assembly.GetAssembly (typeof (Widget)).GetName ().Version;
- #region Test values for Binding
- public List<Command> Commands;
- public int intValue = 500;
- VerticalAlignment currentVAlign;
+ #region Test values for Binding
+ public List<Command> Commands;
+ public int intValue = 500;
+ VerticalAlignment currentVAlign;
- DirectoryInfo curDir = new DirectoryInfo (Path.GetDirectoryName (Assembly.GetEntryAssembly ().Location));
- public FileSystemInfo[] CurDirectory => curDir.GetFileSystemInfos ();
- public string MultilineText =
- $"Lorem ipsum dolor sit amet,\nconsectetur adipiscing elit. Sed non risus.\n\nSuspendisse lectus tortor,\nLorem ipsum dolor sit amet,\nconsectetur adipiscing elit. Sed non risus.\n\nSuspendisse lectus tortor,";
- //public string MultilineText = $"a\n";
- TextAlignment textAlignment = TextAlignment.Left;
- public TextAlignment TextAlignment {
- get => textAlignment;
- set {
- if (textAlignment == value)
- return;
- textAlignment = value;
- NotifyValueChanged (textAlignment);
- }
- }
+ DirectoryInfo curDir = new DirectoryInfo (Path.GetDirectoryName (Assembly.GetEntryAssembly ().Location));
+ public FileSystemInfo[] CurDirectory => curDir.GetFileSystemInfos ();
+ public string MultilineText =
+ $"Lorem ipsum dolor sit amet,\nconsectetur adipiscing elit. Sed non risus.\n\nSuspendisse lectus tortor,\nLorem ipsum dolor sit amet,\nconsectetur adipiscing elit. Sed non risus.\n\nSuspendisse lectus tortor,";
+ //public string MultilineText = $"a\n";
+ TextAlignment textAlignment = TextAlignment.Left;
+ public TextAlignment TextAlignment {
+ get => textAlignment;
+ set {
+ if (textAlignment == value)
+ return;
+ textAlignment = value;
+ NotifyValueChanged (textAlignment);
+ }
+ }
- public int IntValue {
- get => intValue;
- set {
- if (IntValue == value)
- return;
- intValue = value;
- NotifyValueChanged ("IntValue", intValue);
- }
- }
- public VerticalAlignment CurrentVAlign {
- get => currentVAlign;
- set {
- if (currentVAlign == value)
- return;
- currentVAlign = value;
- NotifyValueChanged ("CurrentVAlign", currentVAlign);
- }
- }
- void onSpinnerValueChange (object sender, ValueChangeEventArgs e) {
- if (e.MemberName != "Value")
- return;
- intValue = Convert.ToInt32 (e.NewValue);
- }
- void change_alignment (object sender, EventArgs e) {
- RadioButton rb = sender as RadioButton;
- if (rb == null)
- return;
- NotifyValueChanged ("alignment", Enum.Parse (typeof (Alignment), rb.Caption));
- }
- public IEnumerable<String> List2 = new List<string> (new string[]
- {
- "string1",
- "string2",
- "string3",
- "string4",
- "string5",
- "string6",
- "string7",
- "string8",
- "string8",
- "string8",
- "string8",
- "string8",
- "string8",
- "string9"
- }
- );
- public IEnumerable<String> TestList2 {
- set {
- List2 = value;
- NotifyValueChanged ("TestList2", testList);
- }
- get { return List2; }
- }
- public class TestClass
- {
- public string Prop1 { get; set; }
- public string Prop2 { get; set; }
+ public int IntValue {
+ get => intValue;
+ set {
+ if (IntValue == value)
+ return;
+ intValue = value;
+ NotifyValueChanged ("IntValue", intValue);
+ }
+ }
+ public VerticalAlignment CurrentVAlign {
+ get => currentVAlign;
+ set {
+ if (currentVAlign == value)
+ return;
+ currentVAlign = value;
+ NotifyValueChanged ("CurrentVAlign", currentVAlign);
+ }
+ }
+ void onSpinnerValueChange (object sender, ValueChangeEventArgs e) {
+ if (e.MemberName != "Value")
+ return;
+ intValue = Convert.ToInt32 (e.NewValue);
+ }
+ void change_alignment (object sender, EventArgs e) {
+ RadioButton rb = sender as RadioButton;
+ if (rb == null)
+ return;
+ NotifyValueChanged ("alignment", Enum.Parse (typeof (Alignment), rb.Caption));
+ }
+ public IEnumerable<String> List2 = new List<string> (new string[]
+ {
+ "string1",
+ "string2",
+ "string3",
+ "string4",
+ "string5",
+ "string6",
+ "string7",
+ "string8",
+ "string8",
+ "string8",
+ "string8",
+ "string8",
+ "string8",
+ "string9"
+ }
+ );
+ public IEnumerable<String> TestList2 {
+ set {
+ List2 = value;
+ NotifyValueChanged ("TestList2", testList);
+ }
+ get { return List2; }
+ }
+ public class TestClass
+ {
+ public string Prop1 { get; set; }
+ public string Prop2 { get; set; }
- public override string ToString ()
- => $"{Prop1}, {Prop2}";
+ public override string ToString ()
+ => $"{Prop1}, {Prop2}";
- }
- public class TestClassVC : IValueChange
- {
- public event EventHandler<ValueChangeEventArgs> ValueChanged;
- public void NotifyValueChanged (object _value, [CallerMemberName] string caller = null)
- => ValueChanged.Raise (this, new ValueChangeEventArgs (caller, _value));
- string prop1, prop2;
- public string Prop1 {
- get => prop1;
- set {
- if (prop1 == value)
- return;
- prop1 = value;
- NotifyValueChanged (prop1);
- }
- }
- public string Prop2 {
- get => prop2;
- set {
- if (prop2 == value)
- return;
- prop2 = value;
- NotifyValueChanged (prop2);
- }
+ }
+ public class TestClassVC : IValueChange
+ {
+ public event EventHandler<ValueChangeEventArgs> ValueChanged;
+ public void NotifyValueChanged (object _value, [CallerMemberName] string caller = null)
+ => ValueChanged.Raise (this, new ValueChangeEventArgs (caller, _value));
+ string prop1, prop2;
+ public string Prop1 {
+ get => prop1;
+ set {
+ if (prop1 == value)
+ return;
+ prop1 = value;
+ NotifyValueChanged (prop1);
+ }
+ }
+ public string Prop2 {
+ get => prop2;
+ set {
+ if (prop2 == value)
+ return;
+ prop2 = value;
+ NotifyValueChanged (prop2);
+ }
- }
+ }
- public override string ToString ()
- => $"{Prop1}, {Prop2}";
+ public override string ToString ()
+ => $"{Prop1}, {Prop2}";
- }
- TestClass tcInstance;// = new TestClass () { Prop1 = "instance 0 prop1 value", Prop2 = "instance 0 prop2 value" };
- TestClassVC tcVCInstance;// = new TestClassVC () { Prop1 = "instance 0 prop1 value", Prop2 = "instance 0 prop2 value" };
- TestClass tcInstance1 = new TestClass () { Prop1 = "instance 1 prop1 value", Prop2 = "instance 1 prop2 value" };
- TestClassVC tcVCInstance1 = new TestClassVC () { Prop1 = "instance 1 prop1 value", Prop2 = "instance 1 prop2 value" };
- TestClass tcInstance2 = new TestClass () { Prop1 = "instance 2 prop1 value", Prop2 = "instance 2 prop2 value" };
- TestClassVC tcVCInstance2 = new TestClassVC () { Prop1 = "instance 2 prop1 value", Prop2 = "instance 2 prop2 value" };
+ }
+ TestClass tcInstance;// = new TestClass () { Prop1 = "instance 0 prop1 value", Prop2 = "instance 0 prop2 value" };
+ TestClassVC tcVCInstance;// = new TestClassVC () { Prop1 = "instance 0 prop1 value", Prop2 = "instance 0 prop2 value" };
+ TestClass tcInstance1 = new TestClass () { Prop1 = "instance 1 prop1 value", Prop2 = "instance 1 prop2 value" };
+ TestClassVC tcVCInstance1 = new TestClassVC () { Prop1 = "instance 1 prop1 value", Prop2 = "instance 1 prop2 value" };
+ TestClass tcInstance2 = new TestClass () { Prop1 = "instance 2 prop1 value", Prop2 = "instance 2 prop2 value" };
+ TestClassVC tcVCInstance2 = new TestClassVC () { Prop1 = "instance 2 prop1 value", Prop2 = "instance 2 prop2 value" };
- public TestClass TcInstance {
- get => tcInstance;
- set {
- if (tcInstance == value)
- return;
- tcInstance = value;
- NotifyValueChanged (tcInstance);
- }
- }
- public TestClassVC TcVCInstance {
- get => tcVCInstance;
- set {
- if (tcVCInstance == value)
- return;
- tcVCInstance = value;
- NotifyValueChanged (tcVCInstance);
- }
- }
+ public TestClass TcInstance {
+ get => tcInstance;
+ set {
+ if (tcInstance == value)
+ return;
+ tcInstance = value;
+ NotifyValueChanged (tcInstance);
+ }
+ }
+ public TestClassVC TcVCInstance {
+ get => tcVCInstance;
+ set {
+ if (tcVCInstance == value)
+ return;
+ tcVCInstance = value;
+ NotifyValueChanged (tcVCInstance);
+ }
+ }
- void tcInstance_ChangeProperties_MouseClick (object sender, MouseButtonEventArgs e)
- {
- }
- public void tcInstance_ChangeInstance_MouseClick (object sender, MouseButtonEventArgs e)
- {
- if (TcInstance == tcInstance1)
- TcInstance = tcInstance2;
- else
- TcInstance = tcInstance1;
- }
- void tcVCInstance_ChangeInstance_MouseClick (object sender, MouseButtonEventArgs e)
- {
- TcVCInstance = new TestClassVC () { Prop1 = "prop1 value changed", Prop2 = "prop2 value changed" };
- }
+ void tcInstance_ChangeProperties_MouseClick (object sender, MouseButtonEventArgs e) {
+ }
+ public void tcInstance_ChangeInstance_MouseClick (object sender, MouseButtonEventArgs e) {
+ if (TcInstance == tcInstance1)
+ TcInstance = tcInstance2;
+ else
+ TcInstance = tcInstance1;
+ }
+ void tcVCInstance_ChangeInstance_MouseClick (object sender, MouseButtonEventArgs e) {
+ TcVCInstance = new TestClassVC () { Prop1 = "prop1 value changed", Prop2 = "prop2 value changed" };
+ }
- public IEnumerable<TestClass> List3 = new List<TestClass> (new TestClass[]
- {
- new TestClass { Prop1 = "string1", Prop2="prop2-1" },
- new TestClass { Prop1 = "string2", Prop2="prop2-2" },
- new TestClass { Prop1 = "string3", Prop2="prop2-3" },
- }
- );
- public IEnumerable<string> TestList3Props1 => List3.Select (sc => sc.Prop1).ToList ();
- public IEnumerable<TestClass> TestList3 {
- set {
- List3 = value;
- NotifyValueChanged ("TestList3", testList);
- }
- get { return List3; }
- }
- string prop1;
- public string TestList3SelProp1 {
- get => prop1;
- set {
- if (prop1 == value)
- return;
- prop1 = value;
+ public IEnumerable<TestClass> List3 = new List<TestClass> (new TestClass[]
+ {
+ new TestClass { Prop1 = "string1", Prop2="prop2-1" },
+ new TestClass { Prop1 = "string2", Prop2="prop2-2" },
+ new TestClass { Prop1 = "string3", Prop2="prop2-3" },
+ }
+ );
+ public IEnumerable<string> TestList3Props1 => List3.Select (sc => sc.Prop1).ToList ();
+ public IEnumerable<TestClass> TestList3 {
+ set {
+ List3 = value;
+ NotifyValueChanged ("TestList3", testList);
+ }
+ get { return List3; }
+ }
+ string prop1;
+ public string TestList3SelProp1 {
+ get => prop1;
+ set {
+ if (prop1 == value)
+ return;
+ prop1 = value;
- NotifyValueChanged (prop1);
- }
- }
+ NotifyValueChanged (prop1);
+ }
+ }
- string selString;
- public string TestList2SelectedString {
- get => selString;
- set {
- if (selString == value)
- return;
- selString = value;
- NotifyValueChanged (selString);
- }
- }
+ string selString;
+ public string TestList2SelectedString {
+ get => selString;
+ set {
+ if (selString == value)
+ return;
+ selString = value;
+ NotifyValueChanged (selString);
+ }
+ }
- IList<Colors> testList = (IList<Colors>)FastEnumUtility.FastEnum.GetValues<Colors> ().ToList ();//.ColorDic.Values//.OrderBy(c=>c.Hue)
- //.ThenBy(c=>c.Value).ThenBy(c=>c.Saturation)
- //.ToList ();
- public IList<Colors> TestList {
- set {
- testList = value;
- NotifyValueChanged ("TestList", testList);
- }
- get { return testList; }
- }
- void OnClear (object sender, MouseButtonEventArgs e) => TestList = null;
- void OnLoadList (object sender, MouseButtonEventArgs e) => TestList = (IList<Colors>)FastEnumUtility.FastEnum.GetValues<Colors> ().ToList ();
+ IList<Colors> testList = (IList<Colors>)FastEnumUtility.FastEnum.GetValues<Colors> ().ToList ();//.ColorDic.Values//.OrderBy(c=>c.Hue)
+ //.ThenBy(c=>c.Value).ThenBy(c=>c.Saturation)
+ //.ToList ();
+ public IList<Colors> TestList {
+ set {
+ testList = value;
+ NotifyValueChanged ("TestList", testList);
+ }
+ get { return testList; }
+ }
+ void OnClear (object sender, MouseButtonEventArgs e) => TestList = null;
+ void OnLoadList (object sender, MouseButtonEventArgs e) => TestList = (IList<Colors>)FastEnumUtility.FastEnum.GetValues<Colors> ().ToList ();
- string curSources = "";
- public string CurSources {
- get { return curSources; }
- set {
- if (value == curSources)
- return;
- curSources = value;
- NotifyValueChanged (curSources);
- }
- }
- bool boolVal = true;
- public bool BoolVal {
- get { return boolVal; }
- set {
- if (boolVal == value)
- return;
- boolVal = value;
- NotifyValueChanged (boolVal);
- }
- }
+ string curSources = "";
+ public string CurSources {
+ get { return curSources; }
+ set {
+ if (value == curSources)
+ return;
+ curSources = value;
+ NotifyValueChanged (curSources);
+ }
+ }
+ bool boolVal = true;
+ public bool BoolVal {
+ get { return boolVal; }
+ set {
+ if (boolVal == value)
+ return;
+ boolVal = value;
+ NotifyValueChanged (boolVal);
+ }
+ }
#endregion
- protected override void OnInitialized ()
- {
- Commands = new List<Command> {
- new Command(() => MessageBox.ShowModal(this, MessageBox.Type.Information, "context menu 1 clicked")) { Caption = "Action 1" },
- new Command(() => MessageBox.ShowModal(this, MessageBox.Type.Information, "context menu 2 clicked")) { Caption = "Action 2" },
- new Command(() => MessageBox.ShowModal(this, MessageBox.Type.Information, "context menu 3 clicked")) { Caption = "Action 3" }
- };
- base.OnInitialized ();
- }
+ protected override void OnInitialized () {
+ Commands = new List<Command> {
+ new Command(() => MessageBox.ShowModal(this, MessageBox.Type.Information, "context menu 1 clicked")) { Caption = "Action 1" },
+ new Command(() => MessageBox.ShowModal(this, MessageBox.Type.Information, "context menu 2 clicked")) { Caption = "Action 2" },
+ new Command(() => MessageBox.ShowModal(this, MessageBox.Type.Information, "context menu 3 clicked")) { Caption = "Action 3" }
+ };
+ base.OnInitialized ();
+ }
- public override bool OnKeyDown (Key key) {
-
- switch (key) {
- case Key.F5:
- Load ("Interfaces/Divers/testFileDialog.crow").DataSource = this;
- return true;
- case Key.F6:
- Load ("Interfaces/Divers/0.crow").DataSource = this;
- return true;
- case Key.F7:
- Load ("Interfaces/Divers/perfMeasures.crow").DataSource = this;
- return true;
- case Key.F2:
- if (IsKeyDown (Key.LeftShift))
- DbgLogger.Reset ();
- DbgLogger.Save (this);
- return true;
- }
- return base.OnKeyDown (key);
- }
- }
+ public override bool OnKeyDown (Key key) {
+
+ switch (key) {
+ case Key.F5:
+ Load ("Interfaces/Divers/testFileDialog.crow").DataSource = this;
+ return true;
+ case Key.F6:
+ Load ("Interfaces/Divers/0.crow").DataSource = this;
+ return true;
+ case Key.F7:
+ Load ("Interfaces/Divers/perfMeasures.crow").DataSource = this;
+ return true;
+ case Key.F2:
+ if (IsKeyDown (Key.LeftShift))
+ DbgLogger.Reset ();
+ DbgLogger.Save (this);
+ return true;
+ }
+ return base.OnKeyDown (key);
+ }
+ }
}
\ No newline at end of file
--- /dev/null
+<?xml version="1.0"?>
+<HorizontalStack Height="Fit" Background="vgradient|0:Grey|0.3:Jet|0.7:Jet|1:Black" VerticalAlignment="Bottom" Margin="10">
+ <CheckBox Caption="Hint" IsChecked="{²EnableHint}"/>
+ <Button Caption="Undo" MouseClick="onUndoClick"/>
+ <Button Caption="N" MouseClick="onNewGameClick"/>
+ <Button Caption="Options" MouseClick="onOptionsClick"/>
+ <Widget Width="Stretched" Height="1"/>
+ <Button Caption="Quit" MouseClick="onQuitClick"/>
+ <VerticalStack Style="hsStatus" >
+ <Label Style="labStatus" Text="State:"/>
+ <Label Style="labStatus2" Text="{CurrentState}" />
+ </VerticalStack >
+ <VerticalStack Style="hsStatus" >
+ <Label Style="labStatus" Text="Hover:"/>
+ <Label Style="labStatus2" Text="{SelCell}"/>
+ </VerticalStack>
+ <Image Width="30" Height="20" Path="#Crow.Icons.IconAlerte.svg" Visible="{StockfishNotFound}"/>
+ <Label Text="Stockfish not found" Font="droid bold, 10" Visible="{StockfishNotFound}"/>
+</HorizontalStack>
--- /dev/null
+<?xml version="1.0"?>
+<Border Name="SizeHandle" Style="winBorder" CornerRadius="{./CornerRadius}" Background="{./Background}" >
+ <Container Name="Content" MinimumSize="0,0" />
+</Border>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ id="svg2"
+ viewBox="0 0 64 64"
+ height="64"
+ width="64"
+ sodipodi:docname="checkbox.svg"
+ inkscape:version="1.0.2 (e86c870879, 2021-01-15, custom)">
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1600"
+ inkscape:window-height="877"
+ id="namedview10"
+ showgrid="false"
+ inkscape:zoom="11.09375"
+ inkscape:cx="39.255379"
+ inkscape:cy="32"
+ inkscape:window-x="-8"
+ inkscape:window-y="-8"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg2" />
+ <defs
+ id="defs4" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ id="False">
+ <rect
+ style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:3.38882232;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="background-0"
+ width="50.832325"
+ height="50.832325"
+ x="7.1542463"
+ y="10.990663" />
+ </g>
+ <g
+ id="True">
+ <rect
+ style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:3.38882232;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="background"
+ width="50.832333"
+ height="50.832333"
+ x="7.1542463"
+ y="10.990663" />
+ <path
+ style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.819638;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:0;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ d="m 26.899301,40.904569 c 0,0 -4.557927,-12.130528 -17.039071,-16.083111 C 23.373133,46.449804 25.903228,60.091295 25.903228,60.091295 36.930826,34.779909 41.845629,25.237669 55.533596,15.957127 38.337726,22.362558 33.488807,27.75341 26.899301,40.904569 Z"
+ id="checkmark" />
+ </g>
+</svg>
--- /dev/null
+ControlBackground = "DarkRed";
+ControlBorderColor = "White";
+ControlBorderWidth = "2";
+ControlCaptionColor = "White";
+ControlCaptionHoverColor = "RoyalBlue";
+ControlCornerRadius = "5";
+ControlInsideMargin = "5";
+ControlHighlight = "RoyalBlue";
+IconSize = "16";
+IconMargin = "2";
+ToggleIconSize = "32";
+
+TooltipBackground = "Khaki";
+TooltipForeground = "DimGrey";
+TooltipMargin = "3";
+
+WindowBackgroundColor = "DarkGrey";
+WindowBorderColor = "White";
+WindowBorderWidth = "2";
+WindowTitleBarBackground = "vgradient|0:Onyx|1:Green";
+WindowTitleBarForeground = "Black";
+
+MenuBackground = "DarkGrey";
\ No newline at end of file