--- /dev/null
+---
+Language: CSharp
+# BasedOnStyle: LLVM
+AccessModifierOffset: -2
+AlignAfterOpenBracket: Align
+AlignArrayOfStructures: None
+AlignConsecutiveAssignments:
+ Enabled: false
+ AcrossEmptyLines: false
+ AcrossComments: false
+ AlignCompound: false
+ PadOperators: true
+AlignConsecutiveBitFields:
+ Enabled: false
+ AcrossEmptyLines: false
+ AcrossComments: false
+ AlignCompound: false
+ PadOperators: false
+AlignConsecutiveDeclarations:
+ Enabled: false
+ AcrossEmptyLines: false
+ AcrossComments: false
+ AlignCompound: false
+ PadOperators: false
+AlignConsecutiveMacros:
+ Enabled: false
+ AcrossEmptyLines: false
+ AcrossComments: false
+ AlignCompound: false
+ PadOperators: false
+AlignEscapedNewlines: Right
+AlignOperands: Align
+AlignTrailingComments:
+ Kind: Always
+ OverEmptyLines: 0
+AllowAllArgumentsOnNextLine: true
+AllowAllParametersOfDeclarationOnNextLine: true
+AllowShortBlocksOnASingleLine: Never
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortEnumsOnASingleLine: true
+AllowShortFunctionsOnASingleLine: All
+AllowShortIfStatementsOnASingleLine: Never
+AllowShortLambdasOnASingleLine: All
+AllowShortLoopsOnASingleLine: false
+AlwaysBreakAfterDefinitionReturnType: None
+AlwaysBreakAfterReturnType: None
+AlwaysBreakBeforeMultilineStrings: false
+AlwaysBreakTemplateDeclarations: MultiLine
+AttributeMacros:
+ - __capability
+BinPackArguments: true
+BinPackParameters: true
+BitFieldColonSpacing: Both
+BraceWrapping:
+ AfterCaseLabel: false
+ AfterClass: false
+ AfterControlStatement: Never
+ AfterEnum: false
+ AfterExternBlock: false
+ AfterFunction: false
+ AfterNamespace: false
+ AfterObjCDeclaration: false
+ AfterStruct: false
+ AfterUnion: false
+ BeforeCatch: false
+ BeforeElse: false
+ BeforeLambdaBody: false
+ BeforeWhile: false
+ IndentBraces: false
+ SplitEmptyFunction: true
+ SplitEmptyRecord: true
+ SplitEmptyNamespace: true
+BreakAfterAttributes: Never
+BreakAfterJavaFieldAnnotations: false
+BreakArrays: true
+BreakBeforeBinaryOperators: None
+BreakBeforeConceptDeclarations: Always
+BreakBeforeBraces: Attach
+BreakBeforeInlineASMColon: OnlyMultiline
+BreakBeforeTernaryOperators: true
+BreakConstructorInitializers: BeforeColon
+BreakInheritanceList: BeforeColon
+BreakStringLiterals: true
+ColumnLimit: 80
+CommentPragmas: '^ IWYU pragma:'
+CompactNamespaces: false
+ConstructorInitializerIndentWidth: 4
+ContinuationIndentWidth: 4
+Cpp11BracedListStyle: true
+DerivePointerAlignment: false
+DisableFormat: false
+EmptyLineAfterAccessModifier: Never
+EmptyLineBeforeAccessModifier: LogicalBlock
+ExperimentalAutoDetectBinPacking: false
+FixNamespaceComments: true
+ForEachMacros:
+ - foreach
+ - Q_FOREACH
+ - BOOST_FOREACH
+IfMacros:
+ - KJ_IF_MAYBE
+IncludeBlocks: Preserve
+IncludeCategories:
+ - Regex: '^"(llvm|llvm-c|clang|clang-c)/'
+ Priority: 2
+ SortPriority: 0
+ CaseSensitive: false
+ - Regex: '^(<|"(gtest|gmock|isl|json)/)'
+ Priority: 3
+ SortPriority: 0
+ CaseSensitive: false
+ - Regex: '.*'
+ Priority: 1
+ SortPriority: 0
+ CaseSensitive: false
+IncludeIsMainRegex: '(Test)?$'
+IncludeIsMainSourceRegex: ''
+IndentAccessModifiers: false
+IndentCaseBlocks: false
+IndentCaseLabels: false
+IndentExternBlock: AfterExternBlock
+IndentGotoLabels: true
+IndentPPDirectives: None
+IndentRequiresClause: true
+IndentWidth: 2
+IndentWrappedFunctionNames: false
+InsertBraces: false
+InsertNewlineAtEOF: false
+InsertTrailingCommas: None
+IntegerLiteralSeparator:
+ Binary: 0
+ BinaryMinDigits: 0
+ Decimal: 0
+ DecimalMinDigits: 0
+ Hex: 0
+ HexMinDigits: 0
+JavaScriptQuotes: Leave
+JavaScriptWrapImports: true
+KeepEmptyLinesAtTheStartOfBlocks: true
+LambdaBodyIndentation: Signature
+LineEnding: DeriveLF
+MacroBlockBegin: ''
+MacroBlockEnd: ''
+MaxEmptyLinesToKeep: 1
+NamespaceIndentation: None
+ObjCBinPackProtocolList: Auto
+ObjCBlockIndentWidth: 2
+ObjCBreakBeforeNestedBlockParam: true
+ObjCSpaceAfterProperty: false
+ObjCSpaceBeforeProtocolList: true
+PackConstructorInitializers: BinPack
+PenaltyBreakAssignment: 2
+PenaltyBreakBeforeFirstCallParameter: 19
+PenaltyBreakComment: 300
+PenaltyBreakFirstLessLess: 120
+PenaltyBreakOpenParenthesis: 0
+PenaltyBreakString: 1000
+PenaltyBreakTemplateDeclaration: 10
+PenaltyExcessCharacter: 1000000
+PenaltyIndentedWhitespace: 0
+PenaltyReturnTypeOnItsOwnLine: 60
+PointerAlignment: Right
+PPIndentWidth: -1
+QualifierAlignment: Leave
+ReferenceAlignment: Pointer
+ReflowComments: true
+RemoveBracesLLVM: false
+RemoveSemicolon: false
+RequiresClausePosition: OwnLine
+RequiresExpressionIndentation: OuterScope
+SeparateDefinitionBlocks: Leave
+ShortNamespaceLines: 1
+SortIncludes: CaseSensitive
+SortJavaStaticImport: Before
+SortUsingDeclarations: LexicographicNumeric
+SpaceAfterCStyleCast: false
+SpaceAfterLogicalNot: false
+SpaceAfterTemplateKeyword: true
+SpaceAroundPointerQualifiers: Default
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeCaseColon: false
+SpaceBeforeCpp11BracedList: false
+SpaceBeforeCtorInitializerColon: true
+SpaceBeforeInheritanceColon: true
+SpaceBeforeParens: ControlStatements
+SpaceBeforeParensOptions:
+ AfterControlStatements: true
+ AfterForeachMacros: true
+ AfterFunctionDefinitionName: false
+ AfterFunctionDeclarationName: false
+ AfterIfMacros: true
+ AfterOverloadedOperator: false
+ AfterRequiresInClause: false
+ AfterRequiresInExpression: false
+ BeforeNonEmptyParentheses: false
+SpaceBeforeRangeBasedForLoopColon: true
+SpaceBeforeSquareBrackets: false
+SpaceInEmptyBlock: false
+SpaceInEmptyParentheses: false
+SpacesBeforeTrailingComments: 1
+SpacesInAngles: Never
+SpacesInConditionalStatement: false
+SpacesInContainerLiterals: true
+SpacesInCStyleCastParentheses: false
+SpacesInLineCommentPrefix:
+ Minimum: 1
+ Maximum: -1
+SpacesInParentheses: false
+SpacesInSquareBrackets: false
+Standard: Latest
+StatementAttributeLikeMacros:
+ - Q_EMIT
+StatementMacros:
+ - Q_UNUSED
+ - QT_REQUIRE_VERSION
+TabWidth: 4
+UseTab: Never
+WhitespaceSensitiveMacros:
+ - BOOST_PP_STRINGIZE
+ - CF_SWIFT_NAME
+ - NS_SWIFT_NAME
+ - PP_STRINGIZE
+ - STRINGIZE
+...
+
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
- <AssemblyVersion>1.2.0</AssemblyVersion>
+ <AssemblyVersion>1.2.1</AssemblyVersion>
<PackageVersion>$(AssemblyVersion)-beta</PackageVersion>
<Title>C.R.O.W Cairo Backend</Title>
=> Rectangle (rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
public void Rectangle (PointD p, double width, double height)
=> Rectangle (p.X, p.Y, width, height);
- public void Rectangle (double x, double y, double width, double height)
- => NativeMethods.cairo_rectangle (handle, x, y, width, height);
+ public void Rectangle (double x, double y, double width, double height) {
+ if (width > 0 && height > 0)
+ NativeMethods.cairo_rectangle (handle, x, y, width, height);
+ else
+ System.Diagnostics.Debug.WriteLine("cairo: invalid rectangle");
+ }
public void ClosePath () => NativeMethods.cairo_close_path (handle);
public Path CopyPath () => new Path (NativeMethods.cairo_copy_path (handle));
public Path CopyPathFlat () => new Path (NativeMethods.cairo_copy_path_flat (handle));
<EmbeddedResource Include="Cursors\*.*">
<LogicalName>Crow.Cursors.%(Filename)</LogicalName>
</EmbeddedResource>
- <Compile Include="Properties\AssemblyInfo.cs" />
+ <!--<Compile Include="Properties\AssemblyInfo.cs" />-->
<Compile Remove="src\Widgets\ColorPicker2.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Drawing2D\Drawing2D.csproj" />
</ItemGroup>
+
+ <ItemGroup>
+ <AssemblyAttribute Include="Crow.CrowAssemblyPriority">
+ <_Parameter1>1000</_Parameter1>
+ </AssemblyAttribute>
+ </ItemGroup>
</Project>
}
TxtInFileDialog {
Margin = "1";
- Font = "droid, 12";
+ Font = "mono, 12";
}
CheckBoxAlt {
Template= "#Crow.CheckBox2.template";
Width = "Inherit";
Orientation = "Horizontal";
}
+ScrollingListBox {
+ Template= "#Crow.ScrollingListBox.template";
+}
EnumSelector {
Width = "Fit";
Height = "Fit";
+++ /dev/null
-// Copyright (c) 2013-2020 Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
-//
-// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
-[assembly: Crow.Crow ]
-
//
// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
using System;
-namespace Crow
+namespace Crow {
+/// <summary>
+/// Add this attribute to an assembly to have it search for Crow ressources (.style, images, templates,...)
+/// </summary>
+/// <remarks>
+/// By default, only the entry assembly and the crow assembly will be searched for resources.
+/// </remarks>
+[AttributeUsage (AttributeTargets.Assembly)]
+
+public class CrowAssemblyPriority : Attribute
{
- /// <summary>
- /// Add this attribute to an assembly to have it search for Crow ressources (.style, images, templates,...)
- /// </summary>
- /// <remarks>
- /// By default, only the entry assembly and the crow assembly will be searched for resources.
- /// </remarks>
- [AttributeUsage (AttributeTargets.Assembly)]
- public class CrowAttribute : Attribute
- {
+ public int Priority = 1000;
+ public CrowAssemblyPriority(string priority) {
+ if (int.TryParse(priority, out int pri)) {
+ Priority = pri;
+ }
}
}
+}
if (!logevt (evtType))
return;
- lock (logMutex) {
- chrono.Stop ();
- DbgEvent evt = addEventInternal (evtType, data);
- evt.Message = message;
- chrono.Start ();
- }
+ Monitor.Enter (logMutex);
+ chrono.Stop ();
+ DbgEvent evt = addEventInternal (evtType, data);
+ evt.Message = message;
+ chrono.Start ();
+ Monitor.Exit(logMutex);
+
+ if (ConsoleOutput) {
+ if (evt.type.HasFlag (DbgEvtType.Error)) {
+ Console.ForegroundColor = ConsoleColor.Red;
+ }
+ if (evt is DbgWidgetEvent we) {
+ Console.WriteLine ($"{evt.Print()} {Widget.GraphicObjects[we.InstanceIndex]}");
+ } else
+ Console.WriteLine ($"{evt.Print()}");
+ Console.ResetColor ();
+ }
#endif
}
else
evt = new DbgEvent (chrono.ElapsedTicks, evtType);
- if (ConsoleOutput) {
- if (evt.type.HasFlag (DbgEvtType.Error)) {
- Console.ForegroundColor = ConsoleColor.Red;
- }
- if (evt is DbgWidgetEvent we)
- Console.WriteLine ($"{evt.Print()} {Widget.GraphicObjects[we.InstanceIndex]}");
- else
- Console.WriteLine ($"{evt.Print()}");
- Console.ResetColor ();
- } else
+ if (!ConsoleOutput)
curEventList.Add (evt);
return evt;
}
}*/
}
startedEvents.Pop();
-
}
}
}
{
public static class ExtensionsMethods
{
+ #region CrowAssemblyPriority
+ internal static bool TryGetCrowAssemblyPriority(this Assembly a, out int priority) {
+ priority = -1;
+ if (a.GetCustomAttributes(typeof(CrowAssemblyPriority)).FirstOrDefault() is CrowAssemblyPriority cap) {
+ priority = cap.Priority;
+ return true;
+ }
+ return false;
+ }
+ #endregion
+
#region Cairo extensions
public static void Rectangle(this IContext ctx, Rectangle r, double stroke = 0.0)
/// load the image for rendering from the path given as argument
/// </summary>
public override void load (Interface iFace) {
+ DbgLogger.AddEventWithMsg(DbgEvtType.Ressources, $"BMPPicture.load:{Path}");
if (iFace.sharedPictures.ContainsKey (Path)) {
sharedPicture sp = iFace.sharedPictures[Path];
image = (byte[])sp.Data;
iFace.sharedPictures[Path] = new sharedPicture (image, Dimensions);
}
}
-
- //load image via System.Drawing.Bitmap, cairo load png only
- /*void loadBitmap (System.Drawing.Bitmap bitmap)
- {
- if (bitmap == null)
- return;
-
- System.Drawing.Imaging.BitmapData data = bitmap.LockBits
- (new System.Drawing.Rectangle (0, 0, bitmap.Width, bitmap.Height),
- System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
-
- Dimensions = new Size (bitmap.Width, bitmap.Height);
-
- int stride = data.Stride;
- int bitmapSize = Math.Abs (data.Stride) * bitmap.Height;
-
- image = new byte[bitmapSize];
- System.Runtime.InteropServices.Marshal.Copy (data.Scan0, image, 0, bitmapSize);
-
- bitmap.UnlockBits (data);
- }*/
+ public override void LoadFromStream (Interface iFace, Stream stream) {
+ DbgLogger.AddEventWithMsg(DbgEvtType.Ressources, $"BMPPicture.LoadFromStream:{Path}");
+ image = iFace.Backend.LoadBitmap (stream, out Size dimensions);
+ Dimensions = dimensions;
+ iFace.sharedPictures[Path] = new sharedPicture (image, Dimensions);
+ }
#region implemented abstract members of Fill
public override bool IsLoaded => image != null;
- public override void SetAsSource (Interface iFace, IContext ctx, Rectangle bounds = default(Rectangle))
- {
- if (image == null)
- load (iFace);
-
- float widthRatio = 1f;
- float heightRatio = 1f;
-
- if (Scaled){
- widthRatio = (float)bounds.Width / Dimensions.Width;
- heightRatio = (float)bounds.Height / Dimensions.Height;
- }
-
- if (KeepProportions) {
- if (widthRatio < heightRatio)
- heightRatio = widthRatio;
- else
- widthRatio = heightRatio;
- }
-
- using (ISurface tmp = iFace.Backend.CreateSurface (bounds.Width, bounds.Height)) {
- using (IContext gr = iFace.Backend.CreateContext (tmp)) {
- gr.Translate (bounds.Left, bounds.Top);
- gr.Scale (widthRatio, heightRatio);
- gr.Translate ((bounds.Width/widthRatio - Dimensions.Width)/2, (bounds.Height/heightRatio - Dimensions.Height)/2);
-
- using (ISurface imgSurf = iFace.Backend.CreateSurface (image, Dimensions.Width, Dimensions.Height)) {
- gr.SetSource (imgSurf, 0,0);
- gr.Paint ();
- }
- }
- ctx.SetSource (tmp);
- }
- }
#endregion
- /// <summary>
- /// paint the image in the rectangle given in arguments according
- /// to the Scale and keepProportion parameters.
- /// </summary>
- /// <param name="gr">drawing Backend context</param>
- /// <param name="rect">bounds of the target surface to paint</param>
- /// <param name="subPart">used for svg only</param>
- public override void Paint (Interface iFace, IContext gr, Rectangle rect, string subPart = "")
- {
- if (image == null)
- load (iFace);
-
- double widthRatio = 1;
- double heightRatio = 1;
-
- if (Scaled){
- widthRatio = (double)rect.Width / Dimensions.Width;
- heightRatio = (double)rect.Height / Dimensions.Height;
- }
-
- if (KeepProportions) {
- if (widthRatio < heightRatio)
- heightRatio = widthRatio;
- else
- widthRatio = heightRatio;
- }
-
- gr.SaveTransformations ();
-
- gr.Translate (rect.Left,rect.Top);
- gr.Scale (widthRatio, heightRatio);
- gr.Translate ((rect.Width/widthRatio - Dimensions.Width)/2, (rect.Height/heightRatio - Dimensions.Height)/2);
-
+ protected override void Render(Interface iFace, IContext gr, string subPart = "")
+ {
using (ISurface imgSurf = iFace.Backend.CreateSurface (image, Dimensions.Width, Dimensions.Height)) {
gr.SetSource (imgSurf, 0,0);
gr.Paint ();
}
-
- gr.RestoreTransformations ();
- }
+ }
}
}
using System.Collections.Generic;
using Drawing2D;
+using System.Globalization;
+using Crow.DebugLogger;
namespace Crow
{
}
#endregion
+ void init(Interface iFace, ref Rectangle rect, out float widthRatio, out float heightRatio) {
+ if (!IsLoaded)
+ load (iFace);
+
+ widthRatio = 1f;
+ heightRatio = 1f;
+
+ if (Scaled) {
+ widthRatio = (float)rect.Width / Dimensions.Width;
+ heightRatio = (float)rect.Height / Dimensions.Height;
+ if (KeepProportions) {
+ if (widthRatio < heightRatio)
+ heightRatio = widthRatio;
+ else
+ widthRatio = heightRatio;
+ }
+ }
+ }
+
/// <summary>
- /// abstract method to paint the image in the rectangle given in arguments according
+ /// paint the picture in the rectangle given in arguments according
/// to the Scale and keepProportion parameters.
/// </summary>
/// <param name="gr">drawing Backend context</param>
- /// <param name="rect">bounds of the target surface to paint</param>
- /// <param name="subPart">used for svg only</param>
- public abstract void Paint(Interface iFace, IContext ctx, Rectangle rect, string subPart = "");
+ /// <param name="bounds">bounds of the target surface to paint</param>
+ /// <param name="subPart">limit rendering to this coma separated list of svg part identified with their svg 'id' attribute.</param>
+ public void Paint (Interface iFace, IContext gr, Rectangle bounds, string subPart = "")
+ {
+ DbgLogger.AddEventWithMsg(DbgEvtType.Ressources, $"{Path}[Picture.Paint:]");
+
+ init(iFace, ref bounds, out float widthRatio, out float heightRatio);
+
+ gr.SaveTransformations ();
+
+ gr.Translate (bounds.Left,bounds.Top);
+ gr.Scale (widthRatio, heightRatio);
+ gr.Translate (((float)bounds.Width/widthRatio - Dimensions.Width)/2f, ((float)bounds.Height/heightRatio - Dimensions.Height)/2f);
+
+ Render(iFace, gr, subPart);
+
+ gr.RestoreTransformations ();
+ }
+ public override void SetAsSource (Interface iFace, IContext ctx, Rectangle bounds = default(Rectangle))
+ {
+ DbgLogger.AddEventWithMsg(DbgEvtType.Ressources, $"{Path} [Picture.SetAsSource]");
+
+ init(iFace, ref bounds, out float widthRatio, out float heightRatio);
+
+ using (ISurface tmp = iFace.Backend.CreateSurface (bounds.Width, bounds.Height)) {
+ using (IContext gr = iFace.Backend.CreateContext (tmp)) {
+ gr.Translate (bounds.Left, bounds.Top);
+ gr.Scale (widthRatio, heightRatio);
+ gr.Translate ((bounds.Width/widthRatio - Dimensions.Width)/2, (bounds.Height/heightRatio - Dimensions.Height)/2);
+
+ Render(iFace, gr);
+ }
+ ctx.SetSource (tmp);
+ }
+ }
+ //final rendering on a scaled and configured context
+ protected abstract void Render(Interface iFace, IContext gr, string subPart = "");
public abstract bool IsLoaded { get; }
public abstract void load (Interface iface);
+ public abstract void LoadFromStream (Interface iface, Stream stream);
#region Operators
public static implicit operator Picture(string path) => Parse (path) as Picture;
public static implicit operator string(Picture _pic) => _pic == null ? null : _pic.Path;
Picture _pic = null;
+ DbgLogger.AddEventWithMsg(DbgEvtType.Ressources, $"Picture.parse:{path}");
+
if (path.EndsWith (".svg", true, System.Globalization.CultureInfo.InvariantCulture))
_pic = new SvgPicture (path);
else
public override void load (Interface iFace)
{
+ DbgLogger.AddEventWithMsg(DbgEvtType.Ressources, $"SVGPicture.load:{Path}");
if (iFace.sharedPictures.ContainsKey (Path)) {
sharedPicture sp = iFace.sharedPictures [Path];
hSVG = (ISvgHandle)sp.Data;
Dimensions = hSVG.Dimensions;
iFace.sharedPictures [Path] = new sharedPicture (hSVG, Dimensions);
}
-
+ public override void LoadFromStream (Interface iFace, Stream stream) {
+ DbgLogger.AddEventWithMsg(DbgEvtType.Ressources, $"SVGPicture.LoadFromStream:{Path}");
+ hSVG = iFace.Backend.LoadSvg (stream);
+ Dimensions = hSVG.Dimensions;
+ iFace.sharedPictures [Path] = new sharedPicture (hSVG, Dimensions);
+ }
public void LoadSvgFragment (Interface iface, string fragment) {
+ DbgLogger.AddEventWithMsg(DbgEvtType.Ressources, $"SVGPicture.LoadSvgFragment:{fragment}");
hSVG = iface.Backend.LoadSvg (fragment);
Dimensions = hSVG.Dimensions;
}
public override bool IsLoaded => hSVG != null;
public override void SetAsSource (Interface iFace, IContext ctx, Rectangle bounds = default(Rectangle))
{
- if (hSVG == null)
+ if (!IsLoaded)
load (iFace);
float widthRatio = 1f;
}
#endregion
- /// <summary>
- /// paint the image in the rectangle given in arguments according
- /// to the Scale and keepProportion parameters.
- /// </summary>
- /// <param name="gr">drawing Backend context</param>
- /// <param name="rect">bounds of the target surface to paint</param>
- /// <param name="subPart">limit rendering to this coma separated list of svg part identified with their svg 'id' attribute.</param>
- public override void Paint (Interface iFace, IContext gr, Rectangle rect, string subPart = "")
- {
- if (hSVG == null)
- load (iFace);
-
- float widthRatio = 1f;
- float heightRatio = 1f;
-
- if (Scaled) {
- widthRatio = (float)rect.Width / Dimensions.Width;
- heightRatio = (float)rect.Height / Dimensions.Height;
- }
- if (KeepProportions) {
- if (widthRatio < heightRatio)
- heightRatio = widthRatio;
- else
- widthRatio = heightRatio;
- }
-
- gr.Save ();
-
- gr.Translate (rect.Left,rect.Top);
- gr.Scale (widthRatio, heightRatio);
- gr.Translate (((float)rect.Width/widthRatio - Dimensions.Width)/2f, ((float)rect.Height/heightRatio - Dimensions.Height)/2f);
+ protected override void Render(Interface iFace, IContext gr, string subPart = "")
+ {
if (string.IsNullOrEmpty (subPart))
hSVG.Render (gr);
else {
foreach (string p in parts)
hSVG.Render (gr, "#" + subPart);
}
-
- gr.Restore ();
- }
- }
+
+ }
+ }
}
if (knownExtMethods.ContainsKey (key))
return knownExtMethods [key];
- //System.Diagnostics.Console.WriteLine ($"*** search extension method: {t};{methodName} => key={key}");
+ DbgLogger.AddEvent (DbgEvtType.Binding, $"[CompilerServices.SearchExtMethod] search extension method: {t};{methodName} => key={key}");
MethodInfo mi = null;
if (!TryGetExtensionMethods (Assembly.GetEntryAssembly (), t, methodName, out mi)) {
return mi;
}
} catch (Exception e) {//added this catch for CrowEdit, ext method should be search with appropriate LoadContext.
- Debug.WriteLine ($"[CompilerServices.SearchExtMethod]{e}");
+ DbgLogger.AddEvent (DbgEvtType.Binding | DbgEvtType.Error, $"[CompilerServices.SearchExtMethod]{e}");
}
return null;
}
foundMI = null;
if (assembly == null)
return false;
+ DbgLogger.AddEvent (DbgEvtType.Binding, $"[CompilerServices.TryGetExtensionMethods] search in {assembly.FullName}");
foreach (Type t in assembly.GetExportedTypes().Where
(ty => ty.IsDefined (typeof (ExtensionAttribute), false))) {
+ DbgLogger.AddEvent (DbgEvtType.Binding, $"[CompilerServices.TryGetExtensionMethods] search in type: {t.FullName}");
foreach (MethodInfo mi in t.GetMethods
(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).Where
(m=> m.Name == methodName && m.IsDefined (typeof (ExtensionAttribute), false) &&
m.GetParameters ().Length > 0)) {
+ DbgLogger.AddEvent (DbgEvtType.Binding, $"[CompilerServices.TryGetExtensionMethods] testing method: {mi.Name} extendedType:{extendedType}");
Type curType = extendedType;
while (curType != null) {
- if (mi.GetParameters () [0].ParameterType == curType) {
+ Type firstParamType = mi.GetParameters () [0].ParameterType;
+ if (firstParamType == curType) {
+ DbgLogger.AddEvent (DbgEvtType.Binding, $"[CompilerServices.TryGetExtensionMethods] Found for {curType}");
foundMI = mi;
return true;
}
+ if (firstParamType.IsInterface) {
+ foreach (Type ifaceType in curType.GetInterfaces()) {
+ if (firstParamType == ifaceType) {
+ DbgLogger.AddEvent (DbgEvtType.Binding, $"[CompilerServices.TryGetExtensionMethods] Found interface {ifaceType} in {curType}");
+ foundMI = mi;
+ return true;
+ }
+ }
+ }
curType = curType.BaseType;
}
}
il.MarkLabel (cancel);
//#if DEBUG_BINDING
//TODO: try to print datasource type in the error message
- il.EmitWriteLine (string.Format ("Handler method '{0}' for '{1}' NOT FOUND in new dataSource", bindingDef.TargetMember, sourceEvent.Name));
+ il.EmitWriteLine ($"[{dm.Name}] Handler method '{bindingDef.TargetMember}' for '{sourceEvent.Name}' NOT FOUND in new dataSource");
//#endif
il.MarkLabel (finish);
#if DEBUG_BINDING
- il.EmitWriteLine (string.Format ("Handler method '{0}' for '{1}' FOUND in new dataSource", bindingDef.TargetMember, sourceEvent.Name));
+ il.EmitWriteLine ($"[{dm.Name}] Handler method '{bindingDef.TargetMember}' for '{sourceEvent.Name}' FOUND in new dataSource");
#endif
il.Emit (OpCodes.Ret);
foreach (string m in destMember.Split('.')) {
MemberInfo miDest = curType.GetMember (m).FirstOrDefault ();
if (miDest == null) {
- Console.WriteLine ($"Member '{destMember}' not found in new DataSource '{dest}' of '{orig}'");
+#if DEBUG_BINDING
+ Console.WriteLine ($"[ITOR][dataSourceReverseBinding] {delName} Member '{destMember}' not found in new DataSource '{dest}' of '{orig}'");
+#endif
return;
}
miDests.Add (miDest);
using Path = System.IO.Path;
using Drawing2D;
+using System.Runtime.Loader;
+using System.Net.Http;
+using System.Threading.Tasks;
namespace Crow
{
/// the 'UpdateFrame' method in the 'Run' cycle and may be overriden.
/// </summary>
public static int POLLING_INTERVAL = 1;
+ /// <summary>Maximum total layoutings</summary>
+ public static long MAX_LAYOUTINGS_COUNT = 200000;
/// <summary>Crow configuration root path</summary>
public static string CROW_CONFIG_ROOT;
/// <summary>If true, mouse focus is given when mouse is over control</summary>
/// </summary>
//protected static Interface CurrentInterface;
#endregion
-
- internal static List<Assembly> crowAssemblies = new List<Assembly> ();
/// <summary>
/// Add Assembly that may contains CROW ui ressources like custom widget classes, IML, images, ...
/// Styling fond in those assemblies are automatically loaded on addition;
init_internal ();
}
}
+ internal static List<Assembly> crowAssemblies;
static IntPtr resolveUnmanaged(Assembly assembly, String libraryName)
{
try {
/// backends are search where the main crow assembly is.
/// </summary>
public static string BackendsDirectory = null;
- protected static Type getBackendType (IEnumerable<Type> backendTypes) {
+ protected static Type getBackend (IEnumerable<Type> backendTypes) {
if (backendTypes == null)
return null;
+ Type backend = null;
switch (PreferedBackendType) {
case BackendType.Default:
- return backendTypes.FirstOrDefault(be => be.Name == "DefaultBackend");
+ backend = backendTypes.FirstOrDefault(be => be.Name == "DefaultBackend");
+ break;
case BackendType.Egl:
- return backendTypes.FirstOrDefault(be => be.Name == "EglBackend");
+ backend = backendTypes.FirstOrDefault(be => be.Name == "EglBackend");
+ break;
case BackendType.Vulkan:
- return backendTypes.FirstOrDefault(be => be.Name == "VulkanBackend");
+ backend = backendTypes.FirstOrDefault(be => be.Name == "VulkanBackend");
+ break;
case BackendType.Gl:
- return backendTypes.FirstOrDefault(be => be.Name == "GlBackend");
+ backend = backendTypes.FirstOrDefault(be => be.Name == "GlBackend");
+ break;
default:
- return backendTypes.FirstOrDefault();
+ backend = backendTypes.FirstOrDefault();
+ break;
}
+ return backend ?? backendTypes.FirstOrDefault();
}
- protected static bool tryFindBackendType (out Type backendType) {
+ protected static bool tryFindBackend (out Type backendType) {
backendType = default;
//search loaded assemblies
System.Runtime.Loader.AssemblyLoadContext ldCtx = System.Runtime.Loader.AssemblyLoadContext.GetLoadContext(Assembly.GetExecutingAssembly());
foreach (Assembly a in ldCtx.Assemblies.Where (asb => backends.Contains (asb.GetName ().Name))) {
- backendType = getBackendType (a.ExportedTypes?.Where (e=>e.IsSubclassOf(typeof(CrowBackend)) && !e.IsAbstract));
+ backendType = getBackend (a.ExportedTypes?.Where (e=>e.IsSubclassOf(typeof(CrowBackend)) && !e.IsAbstract));
if (backendType != null)
return true;
}
string bPath = Path.Combine (bp,$"Crow.{b}.dll");
if (File.Exists (bPath)) {
Assembly a = ldCtx.LoadFromAssemblyPath (bPath);
- backendType = getBackendType (a.ExportedTypes?.Where (e=>e.IsSubclassOf(typeof(CrowBackend)) && !e.IsAbstract));
+ backendType = getBackend (a.ExportedTypes?.Where (e=>e.IsSubclassOf(typeof(CrowBackend)) && !e.IsAbstract));
return backendType != null;
}
}
#region CTOR
static Interface ()
{
- System.Runtime.Loader.AssemblyLoadContext ldCtx = System.Runtime.Loader.AssemblyLoadContext.GetLoadContext(Assembly.GetExecutingAssembly());
+ Assembly crowAssembly = Assembly.GetExecutingAssembly();
+ System.Runtime.Loader.AssemblyLoadContext ldCtx = System.Runtime.Loader.AssemblyLoadContext.GetLoadContext(crowAssembly);
ldCtx.ResolvingUnmanagedDll += resolveUnmanaged;
CROW_CONFIG_ROOT =
if (!Directory.Exists (CROW_CONFIG_ROOT))
Directory.CreateDirectory (CROW_CONFIG_ROOT);
- }
- /// <summary>
- /// Each time this array is set, the resolved Assemblies will be
- /// added to the CrowAssemblies list, see 'AddCrowAssembly' for details.
- /// </summary>
- /// <value></value>
- public static string [] CrowAssemblyNames {
- set {
- if (value == null)
- return;
- preloadCrowAssemblies (value);
- }
- }
- static void preloadCrowAssemblies (string [] crowAssemblyNames) {
- //ensure all assemblies are loaded, because IML could contains classes not instanciated in source
- /*Assembly ea = Assembly.GetEntryAssembly ();
- System.IO.FileStream[] files = ea.GetFiles ();
- foreach (AssemblyName an in ea.GetReferencedAssemblies()) {
- try {
- Assembly a = Assembly.ReflectionOnlyLoad (an.Name);
- if (a == Assembly.GetExecutingAssembly ())
- continue;
- if (a.GetCustomAttribute (typeof (CrowAttribute)) != null)
- crowAssemblies.Add (a);
- } catch {
-
- }
- }*/
- foreach (string assemblyName in crowAssemblyNames) {
- try {
- crowAssemblies.Add (Assembly.Load (assemblyName));
- } catch (Exception ex) {
- Console.ForegroundColor = ConsoleColor.Red;
- Console.WriteLine ($"Unable to preload CrowAssembly: {assemblyName}: {ex}");
- Console.ResetColor();
+ SortedDictionary<int, Assembly> assemblies = new SortedDictionary<int, Assembly>();
+ AssemblyLoadContext ctx = AssemblyLoadContext.GetLoadContext(Assembly.GetExecutingAssembly());
+ foreach (Assembly assembly in ctx.Assemblies) {
+ if (assembly != crowAssembly && assembly.TryGetCrowAssemblyPriority(out int priority)) {
+ assemblies.Add(priority, assembly);
}
}
-
+ crowAssemblies = assemblies.Values.Reverse().ToList();
}
/// <summary>
/// Create a new Crow Interface by providing an existing valid GLFW window handle.
}
protected virtual void initBackend () {
- if (!tryFindBackendType (out Type backendType))
+ if (!tryFindBackend (out Type backendType))
throw new Exception ("No backend found.");
backend = (CrowBackend)Activator.CreateInstance (backendType, new object[] {clientRectangle.Width, clientRectangle.Height, hWin});
hWin = backend.hWin;
knownCrowWidgetTypes.Add (typeName, t);
return t;
}
- //TODO:LoadContext may now be used there!!!
foreach (Type expT in Assembly.GetEntryAssembly ().GetExportedTypes ()) {
if (expT.Name != typeName)
continue;
knownCrowWidgetTypes.Add (typeName, expT);
return expT;
}
-
foreach (Assembly a in Interface.crowAssemblies) {
foreach (Type expT in a.GetExportedTypes ()) {
if (expT.Name != typeName)
if (knownExtMethods.ContainsKey (key))
return knownExtMethods [key];
- //System.Diagnostics.Debug.WriteLine ($"*** search extension method: {t};{methodName} => key={key}");
+ Debug.WriteLine ($"[iface] search extension method: {t};{methodName} => key={key}");
MethodInfo mi = null;
if (!CompilerServices.TryGetExtensionMethods (Assembly.GetEntryAssembly (), t, methodName, out mi)) {
}
#endif
-
-
-
-
-
-
-
#region DragAndDrop
public bool DragAndDropInProgress => DragAndDropOperation != null;
public Widget DropTarget => DragAndDropOperation?.DropTarget;
public void ClearDragImage () {
lock (UpdateMutex) {
if (DragImage == null)
- return;
+ return;
clipping.UnionRectangle (lastDragImageBounds);
DragImage.Dispose();
DragImage = null;
string resId = path.Substring (1);
if (tryFindResource (Assembly.GetEntryAssembly (), resId, out stream))
return stream;
- string[] assemblyNames = resId.Split ('.');
+ /*string[] assemblyNames = resId.Split ('.');
if (AppDomain.CurrentDomain.GetAssemblies ().FirstOrDefault (aa => aa.GetName ().Name == assemblyNames[0]).TryGetResource (resId, out stream))
return stream;
if (assemblyNames.Length > 3)
if (tryFindResource (AppDomain.CurrentDomain.GetAssemblies ()
.FirstOrDefault (aa => aa.GetName ().Name == $"{assemblyNames[0]}.{assemblyNames[1]}"), resId, out stream))
- return stream;
+ return stream;*/
foreach (Assembly ca in crowAssemblies)
if (tryFindResource (ca, resId, out stream))
return stream;
+ if (tryFindResource (Assembly.GetExecutingAssembly (), resId, out stream))
+ return stream;
+
throw new Exception ("Resource not found: " + path);
}
if (!File.Exists (path))
} else if (lastMouseDown.ElapsedMilliseconds > DEVICE_REPEAT_DELAY)
mouseRepeatTimer.Start ();
}
+ if (FocusedWidget != null && typeof(IEditableTextWidget).IsAssignableFrom(FocusedWidget.GetType())) {
+ if (blinkingCursor.ElapsedMilliseconds > TEXT_CURSOR_BLINK_FREQUENCY) {
+ blinkingCursor.Restart();
+ drawTextCursor = !drawTextCursor;
+ FocusedWidget?.RegisterForRepaint();
+ }
+ }
if (!Monitor.TryEnter (UpdateMutex))
return;
clipping.UnionRectangle(lastDragImageBounds);
}
- if (!clipping.IsEmpty || shouldDrawTextCursor) {
+ if (!clipping.IsEmpty) {
ctx = Backend.PrepareUIFrame (ctx, clipping);
processDrawing (ctx);
Backend.FlushUIFrame (ctx);
PerformanceMeasure.Begin (PerformanceMeasure.Kind.Layouting);
try {
DiscardQueue = new Queue<LayoutingQueueItem> (LayoutingQueue.Count);
- while (LayoutingQueue.Count > 0) {
+ long totLayoutings = 0;
+ while (LayoutingQueue.Count > 0 && totLayoutings++ < MAX_LAYOUTINGS_COUNT) {
LayoutingQueueItem lqi = LayoutingQueue.Dequeue ();
lqi.ProcessLayouting ();
}
+ if (totLayoutings == MAX_LAYOUTINGS_COUNT) {
+ DbgLogger.AddEvent(DbgEvtType.LayoutingLoopError);
+ }
LayoutingQueue = DiscardQueue;
} finally {
PerformanceMeasure.End (PerformanceMeasure.Kind.Layouting);
}
if (lastDragImageBounds != DragImageBounds) {
+ /*ctx.LineWidth = 1;
+ ctx.SetSource(1,0,0,0.6);
+ ctx.Rectangle(DragImageBounds);
+ ctx.Stroke ();
+ ctx.SetSource(0,1,0,0.6);
+ ctx.Rectangle(lastDragImageBounds);
+ ctx.Stroke ();
+ ctx.Arc(lastDragImageBounds.X, lastDragImageBounds.Y, 5,0,Math.PI*2.0);
+ ctx.Fill ();*/
+
DirtyRect += lastDragImageBounds;
ctx.Save ();
ctx.ResetClip ();
#if DEBUG_CLIP_RECTANGLE
ctx.LineWidth = 1;
- ctx.SetSource(1,1,0,0.5);
- for (int i = 0; i < clipping.NumRectangles; i++)
- ctx.Rectangle(clipping.GetRectangle(i));
+ ctx.SetSource(1,1,0,0.6);
+ for (int i = 0; i < clipping.NumRectangles; i++)
+ ctx.Rectangle(clipping.GetRectangle(i).Inflated(-1,-1));
ctx.Stroke ();
-
#endif
clipping.Reset ();
IsDirty = true;
}
- drawTextCursor (ctx);
-
debugHighlightFocus (ctx);
DbgLogger.EndEvent (DbgEvtType.ProcessDrawing, true);
/// Text cursor blinking frequency.
/// </summary>
public static long TEXT_CURSOR_BLINK_FREQUENCY = 400;
- internal Rectangle? textCursor = null;//last printed cursor, used to clear it.
- public bool forceTextCursor = true;//when true, cursor is printed even if blinkingCursor.elapsed is not reached.
- Stopwatch blinkingCursor = Stopwatch.StartNew ();
- void drawTextCursor (IContext ctx) {
- if (forceTextCursor) {
- if (FocusedWidget is IEditableTextWidget lab) {
- if (lab.DrawCursor (ctx, out Rectangle c)) {
- if (textCursor != null && c != textCursor.Value)
- RegisterChildClip (textCursor.Value);
- textCursor = c;
- //MainSurface.Flush ();
- } else if (textCursor != null)
- RegisterChildClip (textCursor.Value);
- }
- blinkingCursor.Restart ();
- forceTextCursor = false;
- } else if (textCursor != null && blinkingCursor.ElapsedMilliseconds > TEXT_CURSOR_BLINK_FREQUENCY) {
- RegisterChildClip (textCursor.Value);
- textCursor = null;
- blinkingCursor.Restart ();
- } else if (FocusedWidget is IEditableTextWidget lab) {
- if (blinkingCursor.ElapsedMilliseconds > TEXT_CURSOR_BLINK_FREQUENCY) {
- if (lab.DrawCursor (ctx, out Rectangle c)) {
- textCursor = c;
- //MainSurface.Flush ();
- blinkingCursor.Restart ();
- }
- }
+
+ bool _drawTextCursor = true;
+ public bool drawTextCursor {
+ get => _drawTextCursor;
+ set {
+ if (_drawTextCursor == value)
+ return;
+ _drawTextCursor = value;
+ //Console.WriteLine($"draw cursor: {_drawTextCursor}");
}
}
+
+ public void forceTextCursor () {
+ drawTextCursor = true;
+ blinkingCursor.Restart();
+ }
+ Stopwatch blinkingCursor = Stopwatch.StartNew ();
#endregion
- bool shouldDrawTextCursor => forceTextCursor || (blinkingCursor.ElapsedMilliseconds > TEXT_CURSOR_BLINK_FREQUENCY &&
- (FocusedWidget is IEditableTextWidget || textCursor != null));
#region GraphicTree handling
/// <summary>Add widget to the Graphic tree of this interface and register it for layouting</summary>
// ProcessMouseMove (Mouse.X, Mouse.Y);
// }
+ return true;
+ } catch (Exception e) {
+ Console.WriteLine(e.Message);
+ Console.WriteLine(e.StackTrace);
return true;
} finally {
Monitor.Exit (UpdateMutex);
}
public virtual bool OnKeyDown (KeyEventArgs e)
{
+ if (e.Key == Key.F5) {
+ registerRefreshClientRectangle();
+ e.Handled = true;
+ }
#if DEBUG_STATS
- if (Shift && key == Key.F1) {
+ if (e.Modifiers == Modifier.Shift && e.Key == Key.F1) {
LoadIMLFragment (@"
<Window Caption='Debug Statistick' Width='50%' Height='50%' Background='DarkGrey'>
<VerticalStack>
il.Emit (OpCodes.Br, gotoEnd);
il.MarkLabel(gotoItemsContainerNotFound);
- il.EmitWriteLine("ItemsContainer not found in ItemTemplate for " + host.ToString());
+ il.EmitWriteLine($"[{dm.Name}] ItemsContainer not found in ItemTemplate for {host.ToString()}");
il.MarkLabel(gotoEnd);
public static ObservableList<T> Parse (string str) {
ObservableList<T> tmp = new ObservableList<T>();
- Type t = typeof(T);
- MethodInfo miParse = t.GetMethod ("Parse", BindingFlags.Static | BindingFlags.Public,
- Type.DefaultBinder, new Type [] {typeof (string)}, null);
- if (miParse == null)
- throw new Exception ("no Parse method found for: " + t.FullName);
if (!string.IsNullOrEmpty (str)) {
- foreach (string s in str.Split(';'))
- tmp.Add((T)miParse.Invoke (null, new object[] {s}));
+ Type t = typeof(T);
+ if (t.IsEnum) {
+ foreach (string s in str.Split(';'))
+ tmp.Add((T)Enum.Parse(t, s));
+ } else {
+ MethodInfo miParse = t.GetMethod ("Parse",
+ BindingFlags.Static | BindingFlags.Public, Type.DefaultBinder, new Type [] {typeof (string)}, null);
+ if (miParse == null)
+ throw new Exception ("no Parse method found for: " + t.FullName);
+
+ foreach (string s in str.Split(';'))
+ tmp.Add((T)miParse.Invoke (null, new object[] {s}));
+ }
}
return tmp;
}
{
public readonly int Line;
/// <summary>
- /// Character position in current line. If equals '-1', the visualX must contains the on screen position.
- ///
+ /// Character position in current line.
+ /// If Column value is '-1', the visualX must contains the on screen position, and column will be computed from it.
/// </summary>
public int Column;
+ /// <summary>
+ /// The column as presented to the user, counting spaces in tabulations.
+ /// Its value is set during computations.
+ /// </summary>
+ public int TabulatedColumn;
public double VisualCharXPosition;
public CharLocation (int line, int column, double visualX = -1) {
Line = line;
Column = column;
+ TabulatedColumn = -1;
VisualCharXPosition = visualX;
}
public bool HasVisualX => Column >= 0 && VisualCharXPosition >= 0;
{
public static class Extensions
{
- public static ReadOnlySpan<char> GetLine (this string str, TextLine ls) {
+ public static ReadOnlySpan<char> GetLine (this ReadOnlySpan<char> str, TextLine ls) {
if (ls.Start >= str.Length)
return "".AsSpan ();
- return str.AsSpan ().Slice (ls.Start, ls.Length);
+ return str.Slice (ls.Start, ls.Length);
}
- public static ReadOnlySpan<char> GetLine (this string str, TextLine ls, int offset) {
+ public static ReadOnlySpan<char> GetLine (this ReadOnlySpan<char> str, TextLine ls, int offset) {
int start = ls.Start + offset;
if (start >= str.Length)
return "".AsSpan ();
- return str.AsSpan ().Slice (start, ls.Length);
-
+ return str.Slice (start, ls.Length);
}
public static ReadOnlySpan<char> GetLineIncludingLineBreak (this string str, TextLine ls) {
if (ls.Start >= str.Length)
return "".AsSpan ();
return str.AsSpan ().Slice (ls.Start, ls.LengthIncludingLineBreak);
}
- public static ReadOnlySpan<char> GetLineBreak (this string str, TextLine ls) {
+ public static ReadOnlySpan<char> GetLineBreak (this ReadOnlySpan<char> str, TextLine ls) {
if (ls.LineBreakLength == 0)
return "".AsSpan ();
- return str.AsSpan ().Slice (ls.End, ls.LineBreakLength);
+ return str.Slice (ls.End, ls.LineBreakLength);
}
public static ReadOnlySpan<char> GetLineIncludingLineBreak (this string str, TextLine ls, int offset) {
int start = ls.Start + offset;
int curPos;
ReadOnlySpan<char> buffer;
+ [Obsolete]
public SpanCharReader (string text) {
buffer = text.AsSpan ();
curPos = 0;
}
+ public SpanCharReader (ReadOnlySpan<char> text) {
+ buffer = text;
+ curPos = 0;
+ }
public int CurrentPosition => curPos;
+ /// <summary>
+ /// Current reader position is further the end of the buffer.
+ /// </summary>
+ public bool EndOfSpan => curPos >= buffer.Length;
public void Seek (int position) => curPos = position;
- public Char Peak => buffer[curPos];
- public Char Read () => buffer[curPos++];
+ public char Peek => buffer[curPos];
+ public char Read () => buffer[curPos++];
public bool TryRead (out char c) {
if (EndOfSpan) {
c = default;
curPos += increment;
return curPos < buffer.Length;
}
+ /// <summary>
+ /// Retrieve a span of that buffer from provided starting position to the current reader position.
+ /// </summary>
+ /// <param name="fromPosition"></param>
+ /// <returns></returns>
+ public ReadOnlySpan<char> Get (int fromPosition) => buffer.Slice (fromPosition, curPos - fromPosition);
+ public bool TryPeek (char c) => !EndOfSpan && Peek == c;
+ /// <summary>
+ /// Try peak one char, return false if end of span, true otherwise.
+ /// </summary>
+ /// <param name="c"></param>
+ /// <returns></returns>
+ public bool TryPeek (ref char c) {
+ if (EndOfSpan)
+ return false;
+ c = buffer[curPos];
+ return true;
+ }
public bool TryReadUntil (ReadOnlySpan<char> str, StringComparison comparison = StringComparison.Ordinal) {
int startPos = curPos;
curPos += expectedString.Length;
return res;
}
- public bool TryPeak (ReadOnlySpan<char> expectedString, StringComparison comparison = StringComparison.Ordinal) =>
+ public bool TryPeek (ReadOnlySpan<char> expectedString, StringComparison comparison = StringComparison.Ordinal) =>
(buffer.Length < curPos + expectedString.Length)? false :
buffer.Slice(curPos, expectedString.Length).Equals (expectedString, comparison);
- /// <summary>
- /// Retrieve a span of that buffer from provided starting position to the current reader position.
- /// </summary>
- /// <param name="fromPosition"></param>
- /// <returns></returns>
- public ReadOnlySpan<char> Get (int fromPosition) => buffer.Slice (fromPosition, curPos - fromPosition);
- /// <summary>
- /// Current reader position is further the end of the buffer.
- /// </summary>
- public bool EndOfSpan => curPos >= buffer.Length;
- public bool TryPeak (char c) => !EndOfSpan && Peak == c;
- /// <summary>
- /// Try peak one char, return false if end of span, true otherwise.
- /// </summary>
- /// <param name="c"></param>
- /// <returns></returns>
- public bool TryPeak (ref char c) {
- if (EndOfSpan)
- return false;
- c = buffer[curPos];
- return true;
- }
/// <summary>
/// test if next char is one of the provided one as parameter
/// </summary>
/// </summary>
public void AdvanceUntilEol () {
while(!EndOfSpan) {
- switch (Peak) {
+ switch (Peek) {
case '\x85':
case '\x2028':
case '\xA':
/// </summary>
/// <returns></returns>
public bool Eol () {
- return Peak == '\x85' || Peak == '\x2028' || Peak == '\xA' || curPos + 1 == buffer.Length ||
- (Peak == '\xD' && (buffer [curPos + 1] == '\xA' || buffer [curPos + 1] == '\x85'));
+ return Peek == '\x85' || Peek == '\x2028' || Peek == '\xA' || curPos + 1 == buffer.Length ||
+ (Peek == '\xD' && (buffer [curPos + 1] == '\xA' || buffer [curPos + 1] == '\x85'));
}
/// <summary>
public readonly string ChangedText;
public int End => Start + Length;
- public int End2 => Start + (string.IsNullOrEmpty (ChangedText) ? 0 : CharDiff);
+ public int End2 => End + CharDiff;
public int CharDiff => string.IsNullOrEmpty (ChangedText) ? - Length : ChangedText.Length - Length;
public TextChange (int position, int length, string changedText) {
Length = length;
ChangedText = changedText;
}
- public TextChange Inverse (string src)
+ public TextChange (int position, int length, ReadOnlySpan<char> changedText) {
+ Start = position;
+ Length = length;
+ ChangedText = changedText.ToString();
+ }
+ public TextChange Inverse (ReadOnlySpan<char> src)
=> new TextChange (Start, string.IsNullOrEmpty (ChangedText) ? 0 : ChangedText.Length,
- Length == 0 ? "" : src.AsSpan (Start, Length).ToString ());
+ Length == 0 ? "" : src.Slice (Start, Length).ToString ());
+ public override string ToString() => $"{Start},{ChangedText}";
}
}
int result = lines.AsSpan (0, length).BinarySearch (tl);
if (result < 0) {
result = ~result;
- return result == 0 ?
- new CharLocation (0, absolutePosition) :
- new CharLocation (result - 1, absolutePosition - lines[result - 1].Start);
+ return new CharLocation (result - 1, absolutePosition - lines[result - 1].Start);
}
return new CharLocation (result, absolutePosition - lines[result].Start);
}
int vTreshold = (int)(r.Height * dockThresh);
int hTreshold = (int)(r.Width * dockThresh);
- System.Diagnostics.Debug.WriteLine ("Docking {0} as {2} in {1}", dw.Name, activeStack.Name, dw.DockingPosition);
switch (dw.DockingPosition) {
case Alignment.Top:
dw.Height = vTreshold;
public void Undock (DockWindow dw){
int idx = Children.IndexOf(dw);
- System.Diagnostics.Debug.WriteLine ("undocking child index: {0} ; name={1}; pos:{2} ; childcount:{3}",idx, dw.Name, dw.DockingPosition, Children.Count);
-
RemoveChild(dw);
if (Children.Count == 0)//TODO:empty Stack should be removed if not root stack I guess
dockParentParent = false;
Rectangle r = default;
- Console.WriteLine ($"onDrag target={IFace.DragAndDropOperation.DropTarget}");
-
if (IFace.DragAndDropOperation.DropTarget is DockStack ds) {
ds.onDragMouseMove (this, e);
r = ds.ScreenCoordinates (ds.LastPaintedSlot);
dwCb.Inflate (-4,-4);
if (tryGetTargetDockStack (dw, out DockStack targetStack)) {
- Console.WriteLine ($"exterior: {!dwCb.ContainsOrIsEqual (m)} targetStack.Parent: {targetStack.Parent.GetType()}");
if (dwCb.ContainsOrIsEqual (m)) {
r = dw.ScreenCoordinates (dw.LastPaintedSlot);
} else if (targetStack.Parent is DockStack) {
r.Width /= 4;
break;
case Alignment.Center:
- r.Inflate (r.Width / -3, r.Height / -3);
+ r.Inflate (r.Width / -4, r.Height / -4);
+ Console.WriteLine(r);
break;
}
+ r.Inflate(-2,-2);
ISurface dragImg = IFace.Backend.CreateSurface (r.Width, r.Height);
using (IContext gr = IFace.Backend.CreateContext (dragImg)) {
gr.LineWidth = 1;
}
}
bool checkUndock (Point mousePos) {
- //if (DockingPosition == Alignment.Center)
- // return false;
- System.Diagnostics.Debug.WriteLine ($"{mousePos.X},{mousePos.Y}");
if (Math.Abs (mousePos.X - undockingMousePosOrig.X) < undockThreshold ||
Math.Abs (mousePos.X - undockingMousePosOrig.X) < undockThreshold)
return false;
{
for (int i = 0; i < Children.Count; i++)
Children[i].Paint (gr);
+ } catch (Exception e) {
+ Console.WriteLine($"Erreur group {this} paint: {e.Message}");
+ Console.WriteLine(e.StackTrace);
} finally {
childrenRWLock.ExitReadLock ();
}
using System.ComponentModel;
using System.Diagnostics;
using Drawing2D;
+using System.Net.Http;
+using System.Threading;
+using System.Threading.Tasks;
+using System.IO;
+using System.Linq;
+using System.Collections;
+using System.Collections.Generic;
namespace Crow
{
try {
if (string.IsNullOrEmpty(value))
Picture = null;
- else {
- //lock(IFace.LayoutMutex){
- LoadImage (value);
- //}
- }
+ else
+ LoadImage (value);
} catch (Exception ex) {
Debug.WriteLine (ex.Message);
_pic = null;
}
NotifyValueChangedAuto (Path);
+ RegisterForGraphicUpdate();
}
}
/// <summary>
#endregion
#region Image Loading
+ static HttpClient http = new HttpClient();
+ static int HTTP_DOWNLOAD_TIMEOUT_MS = 5000;
+ void downloadThread(Uri uri) {
+ Picture pic = null;
+ var getcontenttype = http.GetAsync(uri);
+ var task = http.GetStreamAsync(uri);
+ if (getcontenttype.Wait(HTTP_DOWNLOAD_TIMEOUT_MS) && getcontenttype.IsCompletedSuccessfully) {
+ if (!getcontenttype.Result.Content.Headers.TryGetValues("content-Type", out IEnumerable<string> contents))
+ return;
+ string[] type = contents.FirstOrDefault().Split('/');
+ if (!string.Equals(type[0], "image", StringComparison.Ordinal))
+ return;
+ if (string.Equals(type[1], "svg", StringComparison.Ordinal))
+ pic = new SvgPicture(uri.AbsoluteUri);
+ else if (string.Equals(type[1], "png", StringComparison.Ordinal))
+ pic = new BmpPicture(uri.AbsoluteUri);
+ else {
+ Debug.WriteLine($"Unsupported image format for download: {type[1]}");
+ return;
+ }
+
+ if (task.Wait(HTTP_DOWNLOAD_TIMEOUT_MS) && task.IsCompletedSuccessfully) {
+ MemoryStream dataCopy = new MemoryStream();
+ task.Result.CopyTo(dataCopy);
+ dataCopy.Position = 0;
+ pic.LoadFromStream(IFace, dataCopy);
+ pic.Scaled = scaled;
+ pic.KeepProportions = keepProps;
+ lock(IFace.UpdateMutex)
+ Picture = pic;
+ }
+ }
+
+ }
+
public void LoadImage (string path)
{
Picture pic;
+ if (path.StartsWith("url:", StringComparison.OrdinalIgnoreCase)) {
+ /*if (IFace.sharedPictures.ContainsKey (Path)) {
+ sharedPicture sp = IFace.sharedPictures [Path];
+ if (sp.Data is ISvgHandle svgHandle) {
+ pic = new SvgPicture()
+ }
+ }*/
+ Uri uri = new Uri(path.Substring (4));
+ if (string.IsNullOrEmpty(uri.AbsolutePath))
+ return;
+ Thread download = new Thread(()=>downloadThread(uri));
+ download.Start();
+ return;
+ }
+
if (path.EndsWith (".svg", true, System.Globalization.CultureInfo.InvariantCulture))
pic = new SvgPicture (path);
else
pic = new BmpPicture (path);
-
pic.Scaled = scaled;
pic.KeepProportions = keepProps;
LineBreak = Environment.NewLine;
return;
}
- LineBreak = _text.GetLineBreak (lines[0]).ToString ();
+ LineBreak = _text.AsSpan().GetLineBreak (lines[0]).ToString ();
for (int i = 1; i < lines.Count; i++) {
- ReadOnlySpan<char> lb = _text.GetLineBreak (lines[i]);
+ ReadOnlySpan<char> lb = _text.AsSpan().GetLineBreak (lines[i]);
if (!lb.SequenceEqual (LineBreak)) {
mixedLineBreak = true;
break;
if (lines[i].Length == 0)
lines.UpdateLineLengthInPixel (i, 0);// (int)Math.Ceiling (fe.MaxXAdvance);
else {
- gr.TextExtents (_text.GetLine (lines[i]), Interface.TAB_SIZE, out tmp);
+ gr.TextExtents (_text.AsSpan().GetLine (lines[i]), Interface.TAB_SIZE, out tmp);
lines.UpdateLineLengthInPixel (i, (int)Math.Ceiling (tmp.XAdvance));
}
}
selStart = SelectionStart.Value;
selEnd = CurrentLoc.Value;
}
- } else
- IFace.forceTextCursor = true;
+ }
}
if (!string.IsNullOrEmpty (_text)) {
if (bytes.Length < size)
bytes = size > 512 ? new byte[size] : stackalloc byte[size];
- encodedBytes = _text.GetLine (lines[i]).ToUtf8 (bytes);
+ encodedBytes = _text.AsSpan().GetLine (lines[i]).ToUtf8 (bytes);
bytes[encodedBytes++] = 0;
if (lines[i].LengthInPixel < 0) {
return false;
}
- Rectangle c = ScreenCoordinates (textCursor.Value + Slot.Position + ClientRectangle.Position);
- ctx.ResetClip();
+ Rectangle c = ContextCoordinates(textCursor.Value + Slot.Position + ClientRectangle.Position);
+
Foreground.SetAsSource (IFace, ctx, c);
ctx.LineWidth = 1.0;
ctx.MoveTo (0.5 + c.X, c.Y);
if (loc.HasVisualX)
return;
TextLine ls = lines[loc.Line];
- ReadOnlySpan<char> curLine = _text.GetLine (ls);
+ ReadOnlySpan<char> curLine = _text.AsSpan().GetLine (ls);
double cPos = getX (clientWidth, ls);
if (loc.Column >= 0) {
else if (!SelectionStart.HasValue)
SelectionStart = CurrentLoc;
CurrentLoc = hoverLoc;
- IFace.forceTextCursor = true;
+ IFace.forceTextCursor();
RegisterForRedraw ();
e.Handled = true;
}
base.onKeyDown (sender, e);
return;
}
- IFace.forceTextCursor = true;
+ IFace.forceTextCursor();
e.Handled = true;
}
#endregion
return cursor;
}
-
- void updateMaxScrolls (LayoutingType layout) {
+ public override bool Paint(IContext ctx)
+ {
+ bool painted = base.Paint(ctx);
+ if (HasFocus && painted && IFace.drawTextCursor) {
+ DrawCursor(ctx, out Rectangle r);
+ }
+ return painted;
+ }
+ void updateMaxScrolls (LayoutingType layout) {
Rectangle cb = ClientRectangle;
if (layout == LayoutingType.Width) {
MaxScrollX = cachedTextSize.Width - cb.Width;
}
#endregion
- protected void update (TextChange change) {
+ protected void update (TextChange change, int charLocOffset = 0) {
lock (linesMutex) {
ReadOnlySpan<char> src = Text.AsSpan ();
Span<char> tmp = stackalloc char[src.Length + (change.ChangedText.Length - change.Length)];
//lines.Update (_text);
SelectionStart = null;
- CurrentLoc = lines.GetLocation (change.Start + change.ChangedText.Length);
+ CurrentLoc = lines.GetLocation (change.Start + change.ChangedText.Length + charLocOffset);
textMeasureIsUpToDate = false;
- IFace.forceTextCursor = true;
+ IFace.forceTextCursor();
}
NotifyValueChanged ("Text", Text);
[XmlIgnore]public virtual Rectangle ClientRectangle {
get {
Rectangle cb = Slot.Size;
- cb.Inflate ( - margin);
+ cb.Inflate (-margin);
+ //return cb.IsValid ? cb : Slot.Size;
return cb;
}
}
}
/// <summary> Chained painting routine on the parent context of the actual cached version
/// of the widget </summary>
- public virtual void Paint (IContext ctx)
+ public virtual bool Paint (IContext ctx)
{
if (!IsVisible)
- return;
+ return false;
DbgLogger.StartEvent (DbgEvtType.GOPaint, this);
#endif
DbgLogger.AddEvent (DbgEvtType.Warning);
DbgLogger.EndEvent (DbgEvtType.GOPaint);
- return;
+ return false;
}
//lock (this) {
if (cacheEnabled) {
Painted.Raise (this, null);
DbgLogger.EndEvent (DbgEvtType.GOPaint);
+ return true;
}
void paintDisabled(IContext gr, Rectangle rb){
//gr.Operator = Operator.Xor;
namespace Crow
{
+ /// <summary>
+ ///
+ /// </summary>
public class Window : TemplatedContainer
{
public enum Direction
<Authors>Jean-Philippe Bruyère</Authors>
<LangVersion>7.3</LangVersion>
- <CrowVersion>1.3.1</CrowVersion>
+ <CrowVersion>1.3.2</CrowVersion>
<CrowPackageVersion>$(CrowVersion)-beta</CrowPackageVersion>
<!-- If you dont have a native libstb on your system, enable the managed version of stb here
<!-- Compile with logging enabled, this will slow down apps, use this only
for debugging purpose-->
- <CrowDebugLogEnabled>false</CrowDebugLogEnabled>
+ <CrowDebugLogEnabled>true</CrowDebugLogEnabled>
<!-- Collect several statistics on widgets-->
<CrowDebugStatsEnabled>false</CrowDebugStatsEnabled>
<TargetFramework>netstandard2.1</TargetFramework>
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
- <AssemblyVersion>1.2.0</AssemblyVersion>
+ <AssemblyVersion>1.2.1</AssemblyVersion>
<PackageVersion>$(AssemblyVersion)-beta</PackageVersion>
<Title>Drawing 2D Library</Title>
Dispose = 0x00100000,
Mouse = 0x00200000,
DragNDrop = 0x00400000,
-
+ Ressources = 0x00800000,//image loading...
+
Update = IFace | 0x10000000,
ProcessLayouting = IFace | Update | Lock | Layouting,
ClippingRegistration = IFace | Update | Lock | Clipping,
EndDrag = Widget | DragNDrop | 0x05,
Drop = Widget | DragNDrop | 0x06,
+ LayoutingLoopError = Layouting | Error | 0x01,
All = 0x7FFFFF00
}
}
\ No newline at end of file
{
public static class Extensions
{
- public static int ToUtf8 (this ReadOnlySpan<char> source, Span<byte> buff, int tabWidth = 4) {
+ public static int ToUtf8 (this ReadOnlySpan<char> source, Span<byte> buff, ref int encodedChar, int tabWidth = 4) {
int c = 0;
int encodedBytes = 0;
- int encodedChar = 0;
+
while (c < source.Length) {
if (source[c] < 0xD800) {
if (source[c] == '\t') {
}
buff[encodedBytes] = 0;
return encodedBytes;
+ }
+ public static int ToUtf8 (this ReadOnlySpan<char> source, Span<byte> buff, int tabWidth = 4) {
+ int encodedChar = 0;
+ return ToUtf8(source,buff,ref encodedChar, tabWidth);
}
public Point BottomRight => new Point (Right, Bottom);
public Point Center => new Point (Left + Width / 2, Top + Height / 2);
public Point CenterD => new PointD (Left + Width / 2.0, Top + Height / 2.0);
-
+ public bool IsValid => Width > 0 && Height > 0;
#endregion
#region FUNCTIONS
public PointD BottomRight => new PointD (Right, Bottom);
public PointD Center => new PointD (Left + Width / 2, Top + Height / 2);
public PointD CenterD => new PointD (Left + Width / 2.0, Top + Height / 2.0);
-
+ public bool IsValid => Width > 0 && Height > 0;
#endregion
#region FUNCTIONS
public static Size operator * (Size s, double i) => new Size ((int)(s.Width * i), (int)(s.Height * i));
#endregion
-
+ public bool IsValid => Width > 0 && Height > 0;
public bool Equals (Size other) => Width == other.Width && Height == other.Height;
public bool Equals (int other) => Width == other && Height == other;
public static SizeD operator / (SizeD s, double i) => new SizeD (s.Width / i, s.Height / i);
#endregion
+ public bool IsValid => Width > 0 && Height > 0;
public override int GetHashCode () => HashCode.Combine (Width, Height);
public override bool Equals (object obj) => obj is SizeD s ? Equals (s) : false;
public bool Equals(SizeD other) => Width == other.Width && Height == other.Height;
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
- <PropertyGroup>
- <TargetFramework>netcoreapp3.1</TargetFramework>
- <OutputType>Exe</OutputType>
- </PropertyGroup>
- <ItemGroup>
- <PackageReference Include="Crow" />
- </ItemGroup>
</Project>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
- <PackageReference Include="Crow" />
- </ItemGroup>
+ <EmbeddedResource Include="ui\*.*">
+ <LogicalName>ui.%(Filename)%(Extension)</LogicalName>
+ </EmbeddedResource>
+ </ItemGroup>
</Project>
\ No newline at end of file
using System;
+using System.Collections.Generic;
using Crow;
using Glfw;
using Samples;
//Interface.PreferedBackendType = Drawing2D.BackendType.Egl;
using (Program app = new Program ()) {
//app.Initialized += (sender, e) => app.LoadIMLFragment (@"<Label Text='Hello World' Background='Red' Top='50' Margin='0'/>");
- app.Initialized += (sender, e) => app.LoadIMLFragment (@"<Container Width='Stretched' ><Window Caption='hello world' Background='Jet'/></Container>");
+ //app.Initialized += (sender, e) => app.LoadIMLFragment (@"<Container Width='Stretched' ><Window Caption='hello world' Background='Jet'/></Container>");
+ app.Initialized += (sender, e) => app.Load("#ui.helloworld.crow");
app.Run ();
+
+ DbgLogger.Save(app);
}
}
}
<?xml version="1.0"?>
-
- <!--<Widget Background="hgradient|0:Black|0.5:Blue|1:Red" Margin="100" />-->
- <VerticalStack>
- <Image Path="#Crow.Icons.checkbox.svg" SvgSub="True" Height="200"/>
- <CheckBox/>
-
- </VerticalStack>
- <!--<ColorPicker/>-->
+<VerticalStack>
+<TextBox Margin="10"/>
+</VerticalStack>
+<!--<Group CacheEnabled="false" Name="dockRoot" Margin="20" Focusable="true" Width="Stretched" Height="Stretched">
+ <DockStack ClipToClientRect="false" CacheEnabled="false" Name="mainDock" Focusable="false" Width="50%" Background="0.1,0.1,0.1,0.8"/>
+ <DockWindow Name="win1" Style="SimpleDockWin" Top="10" Left="10" Background="Red" Width="200" Height="200"/>
+ <DockWindow Name="win2" Style="SimpleDockWin" Top="30" Left="30" Background="Green" Width="200" Height="200"/>
+ <DockWindow Name="win3" Style="SimpleDockWin" Top="50" Left="50" Background="Pink" Width="200" Height="200"/>
+ <DockWindow Name="win4" Style="SimpleDockWin" Top="70" Left="70" Background="RoyalBlue" Width="200" Height="200"/>
+</Group>-->
{
class TestInterface : Interface
{
+ public bool shouldClose = false;
readonly int count = 10, updateCycles = 0;
readonly bool screenOutput = false;
readonly string inDirectory = null;//directory to test
Console.WriteLine ("-u,--update:\n\tmeasure 'n' update cycle with elapsed ticks string notified. (default = 0)");
Console.WriteLine ("-s,--screen:\n\tenable output to screen.");
Console.WriteLine ("-h,--help:\n\tthis help message.");
+ shouldClose = true;
}
public TestInterface (string[] args, int width = 800, int height = 600)
case "-h":
case "--help":
default:
- throw new Exception ("none");
+ printHelp ();
+ return;
}
}
if (EndStage < StartStage)
throw new Exception ($"Ending stage (){EndStage} is before Starting stage ({StartStage})");
} catch (Exception e) {
+ Console.WriteLine($"Invalid command line parameters: {e.Message}");
printHelp ();
- throw e;
+ return;
}
if (string.IsNullOrEmpty (outDir)) {
}
protected override void initBackend()
{
- if (!tryFindBackendType (out Type backendType))
+ if (!tryFindBackend (out Type backendType))
throw new Exception ("No backend found.");
if (screenOutput)
backend = (Drawing2D.CrowBackend)Activator.CreateInstance (backendType, new object[] {clientRectangle.Width, clientRectangle.Height, hWin});
try {
using (TestInterface iface = new TestInterface (args)) {
- if (string.IsNullOrEmpty(iface.inDirectory))
- iface.PerformUnitTests ();
- else
- iface.PerformTests ();
+ if (!iface.shouldClose) {
+ if (string.IsNullOrEmpty(iface.inDirectory))
+ iface.PerformUnitTests ();
+ else
+ iface.PerformTests ();
+ }
}
} catch (Exception e) {
- if (e.Message != "none") {
- Console.ForegroundColor = ConsoleColor.DarkRed;
- Console.WriteLine (e);
- Console.ResetColor ();
- }
+ Console.ForegroundColor = ConsoleColor.DarkRed;
+ Console.WriteLine (e);
+ Console.ResetColor ();
}
}
}
{
class Showcase : SampleBaseForEditor
{
- DbgEvtType[] logEvts = {
- DbgEvtType.IFace,
- DbgEvtType.Widget
+ static DbgEvtType[] logEvts = {
+ /*DbgEvtType.IFace,
+ DbgEvtType.Widget,*/
+ DbgEvtType.Ressources
/*DbgEvtType.MouseEnter,
DbgEvtType.MouseLeave,
DbgEvtType.WidgetMouseDown,
};
static void Main ()
{
- //Interface.PreferedBackendType = Drawing2D.BackendType.Egl;
+ DbgLogger.ConsoleOutput = true;
+ DbgLogger.IncludedEvents.Add(DbgEvtType.Ressources);
- initDebugLog ();
+ //Configuration.Global.Set ("RecordedEvents", new DbgEvtType[] { DbgEvtType.Ressources});
+
+ //Interface.PreferedBackendType = Drawing2D.BackendType.Egl;
Environment.SetEnvironmentVariable ("FONTCONFIG_PATH", @"C:\Users\Jean-Philippe\source\vcpkg\installed\x64-windows\tools\fontconfig\fonts");
Terminate ();
}
- public Container crowContainer;
Stopwatch reloadChrono = new Stopwatch ();
NotifyValueChanged ("ShowError", false);
}
-
-
-
protected override void OnInitialized () {
base.OnInitialized ();
ContextCommands="{GetCommands}"
Selected="{Background=${ControlHighlight}}"
Unselected="{Background=Transparent}">
- <HorizontalStack>
- <Image Margin="1" Width="14" Height="14" Path="#Crow.Icons.file.svg"/>
- <Label Text="{Name}" Width="Stretched"/>
- </HorizontalStack>
+ <Border CornerRadius="2" Margin="0" Height="Fit"
+ Foreground="Transparent"
+ MouseEnter="{Foreground=DimGrey}"
+ MouseLeave="{Foreground=Transparent}">
+ <HorizontalStack>
+ <Image Margin="1" Width="14" Height="14" Path="#Crow.Icons.file.svg"/>
+ <Label Text="{Name}" Width="Stretched"/>
+ </HorizontalStack>
+ </Border>
</ListItem>
</ItemTemplate>
<ItemTemplate DataType="System.IO.DirectoryInfo" Data="GetFileSystemInfosOrdered">
TestCst = "This is a constant test.";
+InactiveTabBackground = "DarkGrey";
+SelectedTabBackground = "Onyx";
+InactiveTabForeground = "Grey";
+SelectedTabForeground = "White";
+SmallUIFont = "sans, 12";
+SmallFont = "consolas, 12";
FpsLabel {
Width = "30";
using System.Collections;
using Drawing2D;
+using System.Diagnostics;
namespace Crow
{
bool suggestionsActive => overlay != null && overlay.IsVisible;
Token currentToken;
SyntaxNode currentNode;
- string[] allWidgetNames = typeof (Widget).Assembly.GetExportedTypes ().Where(t=>typeof(Widget).IsAssignableFrom (t))
- .Select (s => s.Name).ToArray ();
- IEnumerable<MemberInfo> getAllCrowTypeMembers (string crowTypeName) {
- Type crowType = IFace.GetWidgetTypeFromName (crowTypeName);
- return crowType.GetMembers (BindingFlags.Public | BindingFlags.Instance).
- Where (m=>((m is PropertyInfo pi && pi.CanWrite) || (m is EventInfo)) &&
- m.GetCustomAttribute<XmlIgnoreAttribute>() == null);
- }
- MemberInfo getCrowTypeMember (string crowTypeName, string memberName) {
- Type crowType = IFace.GetWidgetTypeFromName (crowTypeName);
- return crowType.GetMember (memberName, BindingFlags.Public | BindingFlags.Instance).FirstOrDefault ();
- }
-
public override void OnTextChanged(object sender, TextChangeEventArgs e)
{
base.OnTextChanged(sender, e);
//Console.WriteLine ($"{pos}: {suggestionTok.AsString (_text)} {suggestionTok}");
}
+
+ void showOverlay () {
+ lock (IFace.UpdateMutex) {
+ if (overlay == null) {
+ overlay = IFace.LoadIMLFragment<ListBox>(@"
+ <ListBox Style='suggestionsListBox' Data='{Suggestions}' UseLoadingThread='False' >
+ <ItemTemplate>
+ <ListItem Height='Fit' Margin='0' Focusable='false' HorizontalAlignment='Left'
+ Selected = '{Background=${ControlHighlight}}'
+ Unselected = '{Background=Transparent}'>
+ <Label Text='{}' HorizontalAlignment='Left' />
+ </ListItem>
+ </ItemTemplate>
+ <ItemTemplate DataType='System.Reflection.MemberInfo'>
+ <ListItem Height='Fit' Margin='0' Focusable='false' HorizontalAlignment='Left'
+ Selected = '{Background=${ControlHighlight}}'
+ Unselected = '{Background=Transparent}'>
+ <HorizontalStack>
+ <Image Picture='{GetIcon}' Width='16' Height='16'/>
+ <Label Text='{Name}' HorizontalAlignment='Left' />
+ </HorizontalStack>
+ </ListItem>
+ </ItemTemplate>
+ <ItemTemplate DataType='Colors'>
+ <ListItem Height='Fit' Margin='0' Focusable='false' HorizontalAlignment='Left'
+ Selected = '{Background=${ControlHighlight}}'
+ Unselected = '{Background=Transparent}'>
+ <HorizontalStack>
+ <Widget Background='{}' Width='20' Height='14'/>
+ <Label Text='{}' HorizontalAlignment='Left' />
+ </HorizontalStack>
+ </ListItem>
+ </ItemTemplate>
+ </ListBox>
+ ");
+ overlay.DataSource = this;
+ overlay.Loaded += (sender, arg) => (sender as ListBox).SelectedIndex = 0;
+ } else
+ overlay.IsVisible = true;
+ overlay.RegisterForLayouting(LayoutingType.Sizing);
+ }
+ }
+ void hideOverlay () {
+ if (overlay == null)
+ return;
+ overlay.IsVisible = false;
+ }
+
+
+ string[] allWidgetNames = typeof (Widget).Assembly.GetExportedTypes ().Where(t=>typeof(Widget).IsAssignableFrom (t))
+ .Select (s => s.Name).ToArray ();
+ IEnumerable<MemberInfo> getAllCrowTypeMembers (string crowTypeName) {
+ Type crowType = IFace.GetWidgetTypeFromName (crowTypeName);
+ return crowType?.GetMembers (BindingFlags.Public | BindingFlags.Instance).
+ Where (m=>((m is PropertyInfo pi && pi.CanWrite) || (m is EventInfo)) &&
+ m.GetCustomAttribute<XmlIgnoreAttribute>() == null);
+ }
+ MemberInfo getCrowTypeMember (string crowTypeName, string memberName) {
+ Type crowType = IFace.GetWidgetTypeFromName (crowTypeName);
+ return crowType.GetMember (memberName, BindingFlags.Public | BindingFlags.Instance).FirstOrDefault ();
+ }
void tryGetSuggestions () {
if (!currentLoc.HasValue)
return;
Suggestions = new List<string> (allWidgetNames);
} else if (currentToken.Type == TokenType.ElementName) {
Suggestions = allWidgetNames.Where (s => s.StartsWith (currentToken.AsString (_text), StringComparison.OrdinalIgnoreCase)).ToList ();
- } else if (currentNode is AttributeSyntax attribNode) {
+ } else if (currentToken.Type == TokenType.EndElementOpen && currentNode is ElementEndTagSyntax eltEndTag) {
+ ElementSyntax es = eltEndTag.Parent as ElementSyntax;
+ if (es?.StartTag != null)
+ Suggestions = new List<string> (new string[] {es.StartTag.NameToken.Value.AsString(_text)});
+ } else if (currentToken.Type.HasFlag(TokenType.WhiteSpace) && typeof(ElementTagSyntax).IsAssignableFrom(currentNode?.GetType())) {
+ ElementTagSyntax ets = currentNode as ElementTagSyntax;
+ if (ets.NameToken.HasValue)
+ Suggestions = getAllCrowTypeMembers (ets.NameToken.Value.AsString (_text)).ToList ();
+ } else if (currentToken.Type != TokenType.AttributeValueClose && currentNode is AttributeSyntax attribNode) {
if (currentNode.Parent is ElementTagSyntax eltTag) {
if (eltTag.NameToken.HasValue) {
if (currentToken.Type == TokenType.AttributeName) {
hideOverlay ();
}
}
- void showOverlay () {
- lock (IFace.UpdateMutex) {
- if (overlay == null) {
- overlay = IFace.LoadIMLFragment<ListBox>(@"
- <ListBox Style='suggestionsListBox' Data='{Suggestions}' UseLoadingThread='False' >
- <ItemTemplate>
- <ListItem Height='Fit' Margin='0' Focusable='false' HorizontalAlignment='Left'
- Selected = '{Background=${ControlHighlight}}'
- Unselected = '{Background=Transparent}'>
- <Label Text='{}' HorizontalAlignment='Left' />
- </ListItem>
- </ItemTemplate>
- <ItemTemplate DataType='System.Reflection.MemberInfo'>
- <ListItem Height='Fit' Margin='0' Focusable='false' HorizontalAlignment='Left'
- Selected = '{Background=${ControlHighlight}}'
- Unselected = '{Background=Transparent}'>
- <HorizontalStack>
- <Image Picture='{GetIcon}' Width='16' Height='16'/>
- <Label Text='{Name}' HorizontalAlignment='Left' />
- </HorizontalStack>
- </ListItem>
- </ItemTemplate>
- <ItemTemplate DataType='Colors'>
- <ListItem Height='Fit' Margin='0' Focusable='false' HorizontalAlignment='Left'
- Selected = '{Background=${ControlHighlight}}'
- Unselected = '{Background=Transparent}'>
- <HorizontalStack>
- <Widget Background='{}' Width='20' Height='14'/>
- <Label Text='{}' HorizontalAlignment='Left' />
- </HorizontalStack>
- </ListItem>
- </ItemTemplate>
- </ListBox>
- ");
- overlay.DataSource = this;
- overlay.Loaded += (sender, arg) => (sender as ListBox).SelectedIndex = 0;
- } else
- overlay.IsVisible = true;
- overlay.RegisterForLayouting(LayoutingType.Sizing);
- }
- }
- void hideOverlay () {
- if (overlay == null)
- return;
- overlay.IsVisible = false;
- }
- void completeToken () {
- string selectedSugg = overlay.SelectedItem is MemberInfo mi ?
- mi.Name : overlay.SelectedItem?.ToString ();
- if (selectedSugg == null)
- return;
- if (currentToken.Type == TokenType.ElementOpen ||
- currentToken.Type == TokenType.WhiteSpace ||
- currentToken.Type == TokenType.AttributeValueOpen)
- update (new TextChange (currentToken.End, 0, selectedSugg));
- else if (currentToken.Type == TokenType.AttributeName && currentNode is AttributeSyntax attrib) {
+ void completeToken (string selectedSugg) {
+ if (currentToken.Type.HasFlag(TokenType.WhiteSpace)) {
+ if (typeof(ElementTagSyntax).IsAssignableFrom(currentNode?.GetType())) {
+ ElementTagSyntax ets = currentNode as ElementTagSyntax;
+ if (ets.NameToken.HasValue)
+ update (new TextChange (currentToken.End, 0, selectedSugg + "=\"\""),-1);
+ else
+ update (new TextChange (currentToken.End, 0, selectedSugg + " "));
+ } else {
+ update (new TextChange (currentToken.End, 0, selectedSugg));
+ }
+ } else if (currentToken.Type == TokenType.EndElementOpen) {
+ update (new TextChange (currentToken.End, 0, selectedSugg + ">"));
+ } else if (currentToken.Type == TokenType.ElementName) {
+ if (currentNode is ElementEndTagSyntax)
+ update (new TextChange (currentToken.Start, currentToken.Length, selectedSugg + ">"));
+ else
+ update (new TextChange (currentToken.Start, currentToken.Length, selectedSugg + ">"), -1);
+ } else if (currentNode is AttributeSyntax attrib) {
+ if (currentToken.Type == TokenType.AttributeName) {
if (attrib.ValueToken.HasValue) {
TextChange tc = new TextChange (currentToken.Start, currentToken.Length, selectedSugg);
update (tc);
SelectionStart = lines.GetLocation (attrib.ValueToken.Value.Start + tc.CharDiff + 1);
CurrentLoc = lines.GetLocation (attrib.ValueToken.Value.End + tc.CharDiff - 1);
} else {
- update (new TextChange (currentToken.Start, currentToken.Length, selectedSugg + "=\"\""));
- MoveLeft ();
+ update (new TextChange (currentToken.Start, currentToken.Length, selectedSugg + "=\"\""), -1);
+ }
+ } else {
+ int offset = 1;
+ if (!attrib.ValueCloseToken.HasValue) {
+ selectedSugg += attrib.ValueCloseToken.Value.AsString(_text);
+ offset = 0;
}
+ if (currentToken.Type == TokenType.AttributeValueOpen)
+ update (new TextChange (currentToken.End, 0, selectedSugg), offset);
+ else if (currentToken.Type == TokenType.AttributeValue)
+ update (new TextChange (currentToken.Start, currentToken.Length, selectedSugg), offset);
+ }
+ } else if (currentToken.Type == TokenType.ElementOpen) {
+ update (new TextChange (currentToken.End, 0, selectedSugg + " "));
} else
update (new TextChange (currentToken.Start, currentToken.Length, selectedSugg));
hideOverlay ();
case Key.Tab:
case Key.Enter:
case Key.KeypadEnter:
- completeToken ();
+ string selectedSugg = overlay.SelectedItem is MemberInfo mi ?
+ mi.Name : overlay.SelectedItem?.ToString ();
+ if (selectedSugg == null)
+ break;
+ completeToken (selectedSugg);
return;
}
} else if (e.Key == Key.Space && IFace.Ctrl) {
selStart = SelectionStart.Value;
selEnd = CurrentLoc.Value;
}
- } else
- IFace.forceTextCursor = true;
+ }
//}
double spacePixelWidth = gr.TextExtents (" ").XAdvance;
int size = buff.Length * 4 + 1;
if (bytes.Length < size)
- bytes = size > 512 ? new byte[size] : stackalloc byte[size];
+ bytes = new byte[size];
int encodedBytes = buff.ToUtf8 (bytes);
buff = sourceBytes.Slice(lines[i].Start, lines[i].Length);
int size = buff.Length * 4 + 1;
if (bytes.Length < size)
- bytes = size > 512 ? new byte[size] : stackalloc byte[size];
+ bytes = new byte[size];
int encodedBytes = buff.ToUtf8 (bytes);
: base (message, innerException) {
Token = token;
}
- }
+ public override string ToString() => $"{Message}: {Token.ToString()}";
+ }
public class SyntaxAnalyser {
XmlSource source;
IEnumerable<Token> tokens => source.Tokens;
void skipWhiteSpaces (ref SpanCharReader reader) {
while(!reader.EndOfSpan) {
- switch (reader.Peak) {
+ switch (reader.Peek) {
case '\x85':
case '\x2028':
case '\xA':
case '\x20':
case '\x9':
char c = reader.Read();
- while (reader.TryPeak (c))
+ while (reader.TryPeek (c))
reader.Read();
addTok (ref reader, c == '\x20' ? TokenType.WhiteSpace : TokenType.Tabulation);
break;
bool readName (ref SpanCharReader reader) {
if (reader.EndOfSpan)
return false;
- char c = reader.Peak;
+ char c = reader.Peek;
if (char.IsLetter(c) || c == '_' || c == ':') {
reader.Advance ();
- while (reader.TryPeak (ref c)) {
+ while (reader.TryPeek (ref c)) {
if (!(char.IsLetterOrDigit(c) || c == '.' || c == '-' || c == '\xB7'))
return true;
reader.Advance ();
if (reader.EndOfSpan)
break;
- switch (reader.Peak) {
+ switch (reader.Peek) {
case '<':
reader.Advance ();
- if (reader.TryPeak ('?')) {
+ if (reader.TryPeek ('?')) {
reader.Advance ();
addTok (ref reader, TokenType.PI_Start);
readName (ref reader);
addTok (ref reader, TokenType.PI_Target);
curState = States.ProcessingInstrucitons;
- } else if (reader.TryPeak ('!')) {
+ } else if (reader.TryPeek ('!')) {
reader.Advance ();
- if (reader.TryPeak ("--")) {
+ if (reader.TryPeek ("--")) {
reader.Advance (2);
addTok (ref reader, TokenType.BlockCommentStart);
if (reader.TryReadUntil ("-->")) {
addTok (ref reader, TokenType.BlockComment);
reader.Advance (3);
addTok (ref reader, TokenType.BlockCommentEnd);
- } else if (reader.TryPeak ("-->")) {
+ } else if (reader.TryPeek ("-->")) {
reader.Advance (3);
addTok (ref reader, TokenType.BlockCommentEnd);
}
curState = States.DTDObject;
}
}
- } else if (reader.TryPeak('/')) {
+ } else if (reader.TryPeek('/')) {
reader.Advance ();
addTok (ref reader, TokenType.EndElementOpen);
if (readName (ref reader)) {
addTok (ref reader, TokenType.ElementName);
- if (reader.TryPeak('>')) {
+ if (reader.TryPeek('>')) {
reader.Advance ();
addTok (ref reader, TokenType.ClosingSign);
break;
case '?':
reader.Advance ();
- if (reader.TryPeak ('>')){
+ if (reader.TryPeek ('>')){
reader.Advance ();
addTok (ref reader, TokenType.PI_End);
}else
{
public class SampleBase : Interface
{
- public SampleBase(IntPtr hWin) : base(800, 600, hWin) { }
- public SampleBase() : base (800, 600, false) { }
+ public SampleBase(IntPtr hWin) : base(Configuration.Global.Get<int>("MainWinWidth", 800), Configuration.Global.Get<int>("MainWinHeight", 600), hWin) { }
+ public SampleBase() : base (Configuration.Global.Get<int>("MainWinWidth", 800), Configuration.Global.Get<int>("MainWinHeight", 600), true) { }
public Version CrowVersion => Assembly.GetAssembly(typeof(Widget)).GetName().Version;
+ public Container crowContainer;
static void showMsgBox (object sender) {
Widget w = sender as Widget;
new KeyBinding (Key.F1, Modifier.Super),
new Binding<bool> ("CanExecute"));
Commands = new CommandGroup("commands msg boxes",
- new ActionCommand("Action 1", () => MessageBox.ShowModal(this, MessageBox.Type.Information, "context menu 1 clicked")),
- new ActionCommand("Action two", () => MessageBox.ShowModal(this, MessageBox.Type.Information, "context menu 2 clicked"), null, false),
- new ActionCommand("Action three", () => MessageBox.ShowModal(this, MessageBox.Type.Information, "context menu 3 clicked"))
+ new ActionCommand("Action 1", () => MessageBox.ShowModal(this, MessageBox.Type.Information, "context menu 1 clicked"), "#Icons.gavel.svg" ),
+ new ActionCommand("Action two", () => MessageBox.ShowModal(this, MessageBox.Type.Information, "context menu 2 clicked"), "#Icons.compile.svg", false),
+ new ActionCommand("Action three", () => MessageBox.ShowModal(this, MessageBox.Type.Information, "context menu 3 clicked"), "#Icons.calendar.svg"),
+ CMDToggleBoolVal,
+ CMDHosted
);
AllCommands = new CommandGroup ("All Commands",
FileCommands,
new CommandGroup ("Combined commands", FileCommands, EditCommands),
new ActionCommand("Action A", () => MessageBox.ShowModal(this, MessageBox.Type.Information, "context menu A clicked"))
);
+
+ CMDObsListAdd = new ActionCommand ("Add",
+ () => {
+ ObservableTestList.Add(obsListNewItem);
+ ObsListNewItem = null;
+ },null, !string.IsNullOrEmpty(obsListNewItem));
+ CMDObsListRemove= new ActionCommand ("Remove",
+ () => {
+ ListBox lb = crowContainer.FindByName("lb") as ListBox;
+ string selItem = lb?.SelectedItem as string;
+ if (!string.IsNullOrEmpty(selItem))
+ ObservableTestList.Remove(lb.SelectedItem as string);
+ },null, true);
}
DeviceEventType deviceEventTypeEnum;
public DeviceEventType DeviceEventTypeEnum {
}
}
+ public ActionCommand CMDObsListAdd,CMDObsListRemove;
+ string obsListNewItem = "new item";
+ public string ObsListNewItem {
+ get => obsListNewItem;
+ set {
+ if (string.Equals(obsListNewItem, value))
+ return;
+ obsListNewItem = value;
+ NotifyValueChanged(obsListNewItem);
+ CMDObsListAdd.CanExecute = !string.IsNullOrEmpty(obsListNewItem);
+ }
+ }
+ public ObservableList<string> ObservableTestList = new ObservableList<string>(new string[]{"string1", "string2"});
+
IList<Colors> testList = (IList<Colors>)EnumsNET.Enums.GetValues<Colors>().ToList();//.ColorDic.Values//.OrderBy(c=>c.Hue)
//.ThenBy(c=>c.Value).ThenBy(c=>c.Saturation)
//.ToList ();
+ public IList<DbgEvtType> AvailaibleDbgEvents => EnumsNET.Enums.GetValues<DbgEvtType>().ToList();
+ public DbgEvtType TestDbgEventSelect;
public IList<Colors> TestList
{
set
void OnClear(object sender, MouseButtonEventArgs e) => TestList = null;
void OnLoadList(object sender, MouseButtonEventArgs e) => TestList = (IList<Colors>)EnumsNET.Enums.GetValues<Colors>().ToList();
+ #region logging tetsts
+ [Flags]
+ public enum LogType {
+ None = 0,
+ Low = 0x0001,
+ Normal = 0x0002,
+ High = 0x0004,
+ Message = Low | Normal | High,
+ Debug = 0x0008,
+ Warning = 0x0010,
+ Error = 0x0020,
+ WarnErr = Warning | Error,
+ Custom1 = 0x0040,
+ Custom2 = 0x0080,
+ Custom3 = 0x0100,
+ code = 0x1000,
+ crowEdit = 0x2000,
+ Plugin = 0x4000,
+
+
+ Custom = Custom1 | Custom2 | Custom3,
+ all = 0xffff
+ }
+ public class LogEntry {
+ public LogType Type;
+ public string msg;
+ public LogEntry (LogType type, string message) {
+ Type = type;
+ msg = message;
+ }
+ public override string ToString() => msg;
+ }
+
+ public class LogItem {
+ public string Name;
+ public ObservableList<LogEntry> log;
+ public LogItem(string name) {
+ Name = name;
+ log = new ObservableList<LogEntry>();
+ }
+ public void Add(LogType type, string message) {
+ lock (log)
+ log.Add (new LogEntry(type, message));
+ }
+ public void ResetLog () {
+ lock (log)
+ log.Clear ();
+ }
+
+ }
+ public ObservableList<LogItem> Logs = new ObservableList<LogItem>(new LogItem[]{new LogItem("CrowEdit")});
+ public LogItem MainLog => Logs[0];
+ [Obsolete]public void Log(LogType type, string message) {
+ MainLog.Add (type, message);
+ }
+ [Obsolete]public void ResetLog () {
+ MainLog.ResetLog();
+ }
+ public LogItem GetLog(string name) {
+ LogItem li = Logs.FirstOrDefault(l=>string.Equals(l.Name,name,StringComparison.OrdinalIgnoreCase));
+ if (li == null) {
+ li = new LogItem(name);
+ lock (Logs)
+ Logs.Add(li);
+ }
+ return li;
+ }
+ #endregion
string curSources = "";
public bool boolVal = true, canExecute;
protected override void OnInitialized()
{
initCommands();
+ Log(LogType.Message, "test log");
+ Log(LogType.Message, "test log2");
+ Log(LogType.Message, "test log3");
+ LogItem li = GetLog("new log");
+ li.Add(LogType.Error, "smlkqjsflmkdsf");
+ li.Add(LogType.Error, "smlkqj");
base.OnInitialized();
}
protected override void processDrawing(IContext ctx)
{
base.processDrawing(ctx);
}
-
+ public override void ProcessResize(Rectangle bounds)
+ {
+ base.ProcessResize(bounds);
+ Configuration.Global.Set ("MainWinWidth", clientRectangle.Width);
+ Configuration.Global.Set ("MainWinHeight", clientRectangle.Height);
+ }
public override bool OnKeyDown(KeyEventArgs e)
{
using Crow.Text;
using System.Collections.Generic;
using Encoding = System.Text.Encoding;
+using System.Linq;
namespace Samples
{
public class SampleBaseForEditor : SampleBase
{
+ static SampleBaseForEditor() {
+ //DbgLogger.ConsoleOutput = !Configuration.Global.Get<bool> (nameof (DebugLogToFile));
+ //RecordedEvents = Configuration.Global.Get<ObservableList<DbgEvtType>> ("RecordedEvents");
+ }
public static SampleBaseForEditor CurrentProgramInstance;
protected override void OnInitialized () {
protected const string _defaultFileName = "unnamed.txt";
protected string source = "", origSource;
protected Editor editor;
- bool debugLogRecording;
public string CurrentDir {
NotifyValueChanged ("IsDirty", IsDirty);
}
}
+
+ #region DebugLog
+ bool debugLogRecording;
public bool DebugLoggingEnabled => DbgLogger.IsEnabled;
- /*public DbgEvtType RecordedEvents {
- get => Configuration.Global.Get<DbgEvtType> (nameof (RecordedEvents));
- set {
- if (RecordedEvents == value)
- return;
- Configuration.Global.Set (nameof (RecordedEvents), value);
- if (DebugLogRecording)
- DbgLogger.IncludeEvents = RecordedEvents;
- NotifyValueChanged(RecordedEvents);
- }
- }
- public DbgEvtType DiscardedEvents {
- get => Configuration.Global.Get<DbgEvtType> (nameof (DiscardedEvents));
- set {
- if (DiscardedEvents == value)
- return;
- Configuration.Global.Set (nameof (DiscardedEvents), value);
- if (DebugLogRecording)
- DbgLogger.DiscardEvents = DiscardedEvents;
- NotifyValueChanged(DiscardedEvents);
- }
- }*/
+ static ObservableList<DbgEvtType> RecordedEvents;
public bool DebugLogRecording {
get => debugLogRecording;
set {
if (debugLogRecording == value)
return;
debugLogRecording = value;
+ if (debugLogRecording) {
+ DbgLogger.IncludedEvents = new List<DbgEvtType>(RecordedEvents);
+ } else {
+ DbgLogger.IncludedEvents = null;
+ }
NotifyValueChanged(debugLogRecording);
}
}
NotifyValueChanged (DebugLogFilePath);
}
}
-
- protected static void initDebugLog () {
- DbgLogger.ConsoleOutput = !Configuration.Global.Get<bool> (nameof (DebugLogToFile));
- }
+ #endregion
public new bool IsDirty => source != origSource;
resetUndoRedo ();
}
protected bool disableTextChangedEvent = false;
- protected void apply (TextChange change) {
+ protected void apply (TextChange change, bool updateEditorPosition = true) {
Span<char> tmp = stackalloc char[source.Length + (change.ChangedText.Length - change.Length)];
ReadOnlySpan<char> src = source.AsSpan ();
src.Slice (0, change.Start).CopyTo (tmp);
disableTextChangedEvent = true;
Source = tmp.ToString ();
disableTextChangedEvent = false;
- editor.SelectionStart = null;
- editor.SetCursorPosition (change.Start + change.ChangedText.Length);
-
- forceTextCursor = true;
+ if (updateEditorPosition) {
+ editor.SelectionStart = null;
+ editor.SetCursorPosition (change.Start + change.ChangedText.Length);
+ forceTextCursor();
+ }
}
- protected void applyChange (TextChange change) {
+ protected void applyChange (TextChange change, bool updateEditorPosition = true) {
undoStack.Push (change.Inverse (source));
redoStack.Clear ();
CMDUndo.CanExecute = true;
CMDRedo.CanExecute = false;
- apply (change);
+ apply (change, updateEditorPosition);
}
public void goUpDirClick (object sender, MouseButtonEventArgs e)
{
protected void onTextChanged (object sender, TextChangeEventArgs e) {
if (disableTextChangedEvent)
return;
- applyChange (e.Change);
+ applyChange (e.Change, false);
}
protected void textView_KeyDown (object sender, Crow.KeyEventArgs e) {
if (Ctrl) {
</ListBox>
<Label Width="Stretched" Margin="3" Background="DimGrey" />
<TextBox Text="TextBox" Multiline="true" Margin="3" />
- <HorizontalStack Height="Fit" Margin="15" Background="Jet" CornerRadius="10">
+ <HorizontalStack Height="Fit" Background="Jet" CornerRadius="10" Margin="5">
<VerticalStack Spacing="5" Width="50%">
<CheckBox Fit="true" Caption="test" />
<CheckBox Fit="true" />
<Label Text="MouseEvents" Width="50%" Margin="3" Focusable="true" Background="Jet" Foreground="DimGrey" TextAlignment="Center" MouseEnter="{Foreground=White}" MouseLeave="{Foreground=DimGrey}" MouseDown="{Background=DarkRed}" MouseClick="{Foreground=Green}" MouseDoubleClick="{Foreground=Yellow}" MouseUp="{Background=Jet}" />
<Label Text="MouseEvents" Width="50%" Margin="3" Background="Jet" Foreground="DimGrey" TextAlignment="Center" MouseClick="{Foreground=Green}" MouseDoubleClick="{Foreground=Yellow}" MouseEnter="{Foreground=White}" MouseLeave="{Foreground=DimGrey}" MouseDown="{Background=SeaGreen}" MouseUp="{Background=DimGrey}" />
</HorizontalStack>
- <GroupBox Caption="Templated controls" Height="Fit" Margin="5">
- <HorizontalStack Height="Fit" Margin="10">
+ <GroupBox Caption="Templated controls" Height="Fit" Margin="1">
+ <HorizontalStack Height="Fit" >
<VerticalStack Width="50%">
<CheckBox Style="CheckBox2" IsChecked="true" />
<CheckBox Style="CheckBox2" />
<?xml version="1.0"?>
<VerticalStack Fit="true" Spacing="0">
- <TextBox Font="droid, 20" Text="multiline text box" Width="Stretched" Multiline="true"/>
+ <TextBox Font="mono, 20" Text="multiline text box" Width="Stretched" Multiline="true"/>
<HorizontalStack Background="DarkSlateGrey" Margin="15" Spacing="15" Fit="true" MouseEnter="{Background=Jet}" MouseLeave="{Background=Grey}">
<TextBox Focusable="true" Text="left" Width="80" Height="30" TextAlignment="Left"/>
<TextBox Focusable="true" Text="centered" Width="80" Height="30" TextAlignment="Center"/>
<Border Fit="true" BorderWidth="2" >
<Scroller CornerRadius="2" Height="200" Width="300" Background="DimGrey" Margin="2">
<VerticalStack Margin="10" VerticalAlignment="Top" Fit="true" Background="vgradient|0:RoyalBlue|1:Black" >
- <Label MouseEnter="{Background=Grey}" MouseLeave="{Background=hgradient|0:DarkRed|1:Transparent}" Margin="5" Background="hgradient|0:DarkRed|1:Transparent" Font="droid,20" Text="label 1"/>
- <Label MouseEnter="{Background=Grey}" MouseLeave="{Background=hgradient|0:DarkRed|1:Transparent}" Margin="5" Background="hgradient|0:DarkRed|1:Transparent" Font="droid,20" Text="label 2"/>
- <Label MouseEnter="{Background=Grey}" MouseLeave="{Background=hgradient|0:DarkRed|1:Transparent}" Margin="5" Background="hgradient|0:DarkRed|1:Transparent" Font="droid,20" Text="label 3"/>
- <Label MouseEnter="{Background=Grey}" MouseLeave="{Background=hgradient|0:DarkRed|1:Transparent}" Margin="5" Background="hgradient|0:DarkRed|1:Transparent" Font="droid,20" Text="label 4"/>
- <Label MouseEnter="{Background=Grey}" MouseLeave="{Background=hgradient|0:DarkRed|1:Transparent}" Margin="5" Background="hgradient|0:DarkRed|1:Transparent" Font="droid,20" Text="label 5"/>
- <Label MouseEnter="{Background=Grey}" MouseLeave="{Background=hgradient|0:DarkRed|1:Transparent}" Margin="5" Background="hgradient|0:DarkRed|1:Transparent" Font="droid,20" Text="label 6"/>
- <Label MouseEnter="{Background=Grey}" MouseLeave="{Background=hgradient|0:DarkRed|1:Transparent}" Margin="5" Background="hgradient|0:DarkRed|1:Transparent" Font="droid,20" Text="label 7"/>
- <Label MouseEnter="{Background=Grey}" MouseLeave="{Background=hgradient|0:DarkRed|1:Transparent}" Margin="5" Background="hgradient|0:DarkRed|1:Transparent" Font="droid,20" Text="label 8"/>
- <Label MouseEnter="{Background=Grey}" MouseLeave="{Background=hgradient|0:DarkRed|1:Transparent}" Margin="5" Background="hgradient|0:DarkRed|1:Transparent" Font="droid,20" Text="label 9"/>
- <Label MouseEnter="{Background=Grey}" MouseLeave="{Background=hgradient|0:DarkRed|1:Transparent}" Margin="5" Background="hgradient|0:DarkRed|1:Transparent" Font="droid,20" Text="label 10"/>
- <Label MouseEnter="{Background=Grey}" MouseLeave="{Background=hgradient|0:DarkRed|1:Transparent}" Margin="5" Background="hgradient|0:DarkRed|1:Transparent" Font="droid,20" Text="label 11"/>
- <Label MouseEnter="{Background=Grey}" MouseLeave="{Background=hgradient|0:DarkRed|1:Transparent}" Margin="5" Background="hgradient|0:DarkRed|1:Transparent" Font="droid,20" Text="label 12"/>
- <Label MouseEnter="{Background=Grey}" MouseLeave="{Background=hgradient|0:DarkRed|1:Transparent}" Margin="5" Background="hgradient|0:DarkRed|1:Transparent" Font="droid,20" Text="label 13"/>
- <Label MouseEnter="{Background=Grey}" MouseLeave="{Background=hgradient|0:DarkRed|1:Transparent}" Margin="5" Background="hgradient|0:DarkRed|1:Transparent" Font="droid,20" Text="label 14"/>
- <Label MouseEnter="{Background=Grey}" MouseLeave="{Background=hgradient|0:DarkRed|1:Transparent}" Margin="5" Background="hgradient|0:DarkRed|1:Transparent" Font="droid,20" Text="label 15"/>
- <Label MouseEnter="{Background=Grey}" MouseLeave="{Background=hgradient|0:DarkRed|1:Transparent}" Margin="5" Background="hgradient|0:DarkRed|1:Transparent" Font="droid,20" Text="label 16"/>
- <Label MouseEnter="{Background=Grey}" MouseLeave="{Background=hgradient|0:DarkRed|1:Transparent}" Margin="5" Background="hgradient|0:DarkRed|1:Transparent" Font="droid,20" Text="label 17"/>
- <Label MouseEnter="{Background=Grey}" MouseLeave="{Background=hgradient|0:DarkRed|1:Transparent}" Margin="5" Background="hgradient|0:DarkRed|1:Transparent" Font="droid,20" Text="label 18"/>
- <Label MouseEnter="{Background=Grey}" MouseLeave="{Background=hgradient|0:DarkRed|1:Transparent}" Margin="5" Background="hgradient|0:DarkRed|1:Transparent" Font="droid,20" Text="label 19"/>
- <Label MouseEnter="{Background=Grey}" MouseLeave="{Background=hgradient|0:DarkRed|1:Transparent}" Margin="5" Background="hgradient|0:DarkRed|1:Transparent" Font="droid,20" Text="label 20"/>
- <Label MouseEnter="{Background=Grey}" MouseLeave="{Background=hgradient|0:DarkRed|1:Transparent}" Margin="5" Background="hgradient|0:DarkRed|1:Transparent" Font="droid,20" Text="label 21"/>
- <Label MouseEnter="{Background=Grey}" MouseLeave="{Background=hgradient|0:DarkRed|1:Transparent}" Margin="5" Background="hgradient|0:DarkRed|1:Transparent" Font="droid,20" Text="label 22"/>
- <Label MouseEnter="{Background=Grey}" MouseLeave="{Background=hgradient|0:DarkRed|1:Transparent}" Margin="5" Background="hgradient|0:DarkRed|1:Transparent" Font="droid,20" Text="label 23"/>
- <Label MouseEnter="{Background=Grey}" MouseLeave="{Background=hgradient|0:DarkRed|1:Transparent}" Margin="5" Background="hgradient|0:DarkRed|1:Transparent" Font="droid,20" Text="label 24"/>
- <Label MouseEnter="{Background=Grey}" MouseLeave="{Background=hgradient|0:DarkRed|1:Transparent}" Margin="5" Background="hgradient|0:DarkRed|1:Transparent" Font="droid,20" Text="label 25"/>
+ <Label MouseEnter="{Background=Grey}" MouseLeave="{Background=hgradient|0:DarkRed|1:Transparent}" Margin="5" Background="hgradient|0:DarkRed|1:Transparent" Font="mono,20" Text="label 1"/>
+ <Label MouseEnter="{Background=Grey}" MouseLeave="{Background=hgradient|0:DarkRed|1:Transparent}" Margin="5" Background="hgradient|0:DarkRed|1:Transparent" Font="mono,20" Text="label 2"/>
+ <Label MouseEnter="{Background=Grey}" MouseLeave="{Background=hgradient|0:DarkRed|1:Transparent}" Margin="5" Background="hgradient|0:DarkRed|1:Transparent" Font="mono,20" Text="label 3"/>
+ <Label MouseEnter="{Background=Grey}" MouseLeave="{Background=hgradient|0:DarkRed|1:Transparent}" Margin="5" Background="hgradient|0:DarkRed|1:Transparent" Font="mono,20" Text="label 4"/>
+ <Label MouseEnter="{Background=Grey}" MouseLeave="{Background=hgradient|0:DarkRed|1:Transparent}" Margin="5" Background="hgradient|0:DarkRed|1:Transparent" Font="mono,20" Text="label 5"/>
+ <Label MouseEnter="{Background=Grey}" MouseLeave="{Background=hgradient|0:DarkRed|1:Transparent}" Margin="5" Background="hgradient|0:DarkRed|1:Transparent" Font="mono,20" Text="label 6"/>
+ <Label MouseEnter="{Background=Grey}" MouseLeave="{Background=hgradient|0:DarkRed|1:Transparent}" Margin="5" Background="hgradient|0:DarkRed|1:Transparent" Font="mono,20" Text="label 7"/>
+ <Label MouseEnter="{Background=Grey}" MouseLeave="{Background=hgradient|0:DarkRed|1:Transparent}" Margin="5" Background="hgradient|0:DarkRed|1:Transparent" Font="mono,20" Text="label 8"/>
+ <Label MouseEnter="{Background=Grey}" MouseLeave="{Background=hgradient|0:DarkRed|1:Transparent}" Margin="5" Background="hgradient|0:DarkRed|1:Transparent" Font="mono,20" Text="label 9"/>
+ <Label MouseEnter="{Background=Grey}" MouseLeave="{Background=hgradient|0:DarkRed|1:Transparent}" Margin="5" Background="hgradient|0:DarkRed|1:Transparent" Font="mono,20" Text="label 10"/>
+ <Label MouseEnter="{Background=Grey}" MouseLeave="{Background=hgradient|0:DarkRed|1:Transparent}" Margin="5" Background="hgradient|0:DarkRed|1:Transparent" Font="mono,20" Text="label 11"/>
+ <Label MouseEnter="{Background=Grey}" MouseLeave="{Background=hgradient|0:DarkRed|1:Transparent}" Margin="5" Background="hgradient|0:DarkRed|1:Transparent" Font="mono,20" Text="label 12"/>
+ <Label MouseEnter="{Background=Grey}" MouseLeave="{Background=hgradient|0:DarkRed|1:Transparent}" Margin="5" Background="hgradient|0:DarkRed|1:Transparent" Font="mono,20" Text="label 13"/>
+ <Label MouseEnter="{Background=Grey}" MouseLeave="{Background=hgradient|0:DarkRed|1:Transparent}" Margin="5" Background="hgradient|0:DarkRed|1:Transparent" Font="mono,20" Text="label 14"/>
+ <Label MouseEnter="{Background=Grey}" MouseLeave="{Background=hgradient|0:DarkRed|1:Transparent}" Margin="5" Background="hgradient|0:DarkRed|1:Transparent" Font="mono,20" Text="label 15"/>
+ <Label MouseEnter="{Background=Grey}" MouseLeave="{Background=hgradient|0:DarkRed|1:Transparent}" Margin="5" Background="hgradient|0:DarkRed|1:Transparent" Font="mono,20" Text="label 16"/>
+ <Label MouseEnter="{Background=Grey}" MouseLeave="{Background=hgradient|0:DarkRed|1:Transparent}" Margin="5" Background="hgradient|0:DarkRed|1:Transparent" Font="mono,20" Text="label 17"/>
+ <Label MouseEnter="{Background=Grey}" MouseLeave="{Background=hgradient|0:DarkRed|1:Transparent}" Margin="5" Background="hgradient|0:DarkRed|1:Transparent" Font="mono,20" Text="label 18"/>
+ <Label MouseEnter="{Background=Grey}" MouseLeave="{Background=hgradient|0:DarkRed|1:Transparent}" Margin="5" Background="hgradient|0:DarkRed|1:Transparent" Font="mono,20" Text="label 19"/>
+ <Label MouseEnter="{Background=Grey}" MouseLeave="{Background=hgradient|0:DarkRed|1:Transparent}" Margin="5" Background="hgradient|0:DarkRed|1:Transparent" Font="mono,20" Text="label 20"/>
+ <Label MouseEnter="{Background=Grey}" MouseLeave="{Background=hgradient|0:DarkRed|1:Transparent}" Margin="5" Background="hgradient|0:DarkRed|1:Transparent" Font="mono,20" Text="label 21"/>
+ <Label MouseEnter="{Background=Grey}" MouseLeave="{Background=hgradient|0:DarkRed|1:Transparent}" Margin="5" Background="hgradient|0:DarkRed|1:Transparent" Font="mono,20" Text="label 22"/>
+ <Label MouseEnter="{Background=Grey}" MouseLeave="{Background=hgradient|0:DarkRed|1:Transparent}" Margin="5" Background="hgradient|0:DarkRed|1:Transparent" Font="mono,20" Text="label 23"/>
+ <Label MouseEnter="{Background=Grey}" MouseLeave="{Background=hgradient|0:DarkRed|1:Transparent}" Margin="5" Background="hgradient|0:DarkRed|1:Transparent" Font="mono,20" Text="label 24"/>
+ <Label MouseEnter="{Background=Grey}" MouseLeave="{Background=hgradient|0:DarkRed|1:Transparent}" Margin="5" Background="hgradient|0:DarkRed|1:Transparent" Font="mono,20" Text="label 25"/>
</VerticalStack>
</Scroller>
</Border>
--- /dev/null
+<?xml version="1.0"?>
+<Window Width="80%" Height="90%">
+<ListBox Name="ColorList" Data="{TestList}" Margin="5">
+ <Template>
+ <Wrapper Name="ItemsContainer" Background="White"/>
+ </Template>
+ <ItemTemplate>
+ <VerticalStack Height="Fit" Width="200">
+ <Label Text="private void + '" Font="mono, 16" Foreground="{}" Width="Stretched" />
+ <Label Text="{}" Font="mono, 9" Foreground="LightGrey" HorizontalAlignment="Left" />
+ </VerticalStack>
+ </ItemTemplate>
+
+</ListBox>
+</Window>
<VerticalStack Fit="true" Name="vsFps" Spacing="10" >
<HorizontalStack Fit="true">
<Label Text="Update:" Width="50" TextAlignment="Right"/>
- <Label Margin="5" Name="labUpdate" Text="{update}" Font="droid,12" Background="SeaGreen" Width="50" TextAlignment="Center"/>
+ <Label Margin="5" Name="labUpdate" Text="{update}" Font="mono,12" Background="SeaGreen" Width="50" TextAlignment="Center"/>
</HorizontalStack>
<HorizontalStack Fit="true">
<Label Name="captionFps" Text="Fps:" Width="50" TextAlignment="Right"/>
--- /dev/null
+<Border Foreground="White" Fit="true">
+ <VerticalStack>
+ <Label Text='Hello World' Background='MediumSeaGreen' Margin='0'/>
+ <Label Text='Hello World' Background='MediumSeaGreen' Margin='0'/>
+ </VerticalStack>
+</Border>
\ No newline at end of file
--- /dev/null
+<VerticalStack Margin="10">
+ <TextBox Text="{²ObsListNewItem}"/>
+ <Label Name="curItem" Text="{../lb.SelectedItem}"/>
+ <HorizontalStack Height="Fit">
+ <Button Command="{CMDObsListAdd}" />
+ <Button Command="{CMDObsListRemove}" IsEnabled="{../lb.SelectionIsEmpty}" />
+ </HorizontalStack>
+ <ListBox Name="lb" Data="{ObservableTestList}" >
+ <Template>
+ <Border Style="ControlBorder" MinimumSize="10,10" Background="{./Background}" CornerRadius="{./CornerRadius}">
+ <Scroller Name="scroller1" >
+ <VerticalStack Height="Fit" Name="ItemsContainer" VerticalAlignment="Top"/>
+ </Scroller>
+ </Border>
+ </Template>
+ </ListBox>
+</VerticalStack>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0"?>
+<VerticalStack>
+ <Image Name="img" Width="Fit" Height="Fit" Background="vgradient|0:SkyBlue|1:White" Path="url:https://api.nuget.org/v3-flatcontainer/crow/1.2.0-beta/icon"/>
+ <Image Width="Fit" Height="Fit" Background="vgradient|0:SkyBlue|1:White" Path="url:https://api.nuget.org/v3-flatcontainer/csoft.crow/9.1.3/icon"/>
+ <Image Width="32" Height="32" Background="vgradient|0:SkyBlue|1:White" Path="url:https://api.nuget.org/v3-flatcontainer/vkcrowwindow/0.3.9/icon"/>
+ <Image Width="32" Height="32" Background="vgradient|0:SkyBlue|1:White" Path="url:https://api.nuget.org/v3-flatcontainer/leaf.xnet/5.2.10/icon"/>
+ <Label Text="{../img.Path}" Foreground="RebeccaPurple"/>
+</VerticalStack>
\ No newline at end of file
<TextBox Background="DarkGrey" Width="50" TextAlignment="Right" Foreground="White"/>
</HorizontalStack>
- <TextBox Text="A\nBB\nCCC\nDDDD" Focused="true" Name="tb" Multiline="true" Font="droid,16" Margin="5" />
- <TextBox Multiline="true" Font="droid,16" Name="tb5" Margin="5" Text="{../tb.Selection}"/>
- <TextBox Font="droid,10" Name="tb2" Margin="0" Text="this is a test of a text box"/>
- <TextBox Font="droid,10" Name="tb3" Margin="5" Text="this is a test of a text box"/>
- <TextBox Font="droid,10" Name="tb4" Margin="5" Text="this is a test of a text box"/>
- <TextBox Font="droid,10" Name="tb5" Margin="20" Text="this is a test of a text box"/>
- <TextBox Multiline="true" Font="droid,10" Name="tb6" Margin="5" Text="this is a test of a text box\nthis is a test of a text box"/>
- <TextBox Multiline="true" Font="droid,10" Name="tb7" Margin="1" TextAlignment="Center"
+ <TextBox Text="A\nBB\nCCC\nDDDD" Focused="true" Name="tb" Multiline="true" Font="mono,16" Margin="5" />
+ <TextBox Multiline="true" Font="mono,16" Name="tb5" Margin="5" Text="{../tb.Selection}"/>
+ <TextBox Font="mono,10" Name="tb2" Margin="0" Text="this is a test of a text box"/>
+ <TextBox Font="mono,10" Name="tb3" Margin="5" Text="this is a test of a text box"/>
+ <TextBox Font="mono,10" Name="tb4" Margin="5" Text="this is a test of a text box"/>
+ <TextBox Font="mono,10" Name="tb5" Margin="20" Text="this is a test of a text box"/>
+ <TextBox Multiline="true" Font="mono,10" Name="tb6" Margin="5" Text="this is a test of a text box\nthis is a test of a text box"/>
+ <TextBox Multiline="true" Font="mono,10" Name="tb7" Margin="1" TextAlignment="Center"
Text="this is a test of a text boxthis is a test\nthis is a test when line are centered"/>
- <TextBox Multiline="true" Font="droid,10" Name="tb8" Margin="1" TextAlignment="Center"
+ <TextBox Multiline="true" Font="mono,10" Name="tb8" Margin="1" TextAlignment="Center"
Text="this is a test of a text box\n\n\nthis is a test\nthis is a test when line are centered"/>
</VerticalStack>
\ No newline at end of file
Unselected="{Background=Transparent}">
<HorizontalStack Height="Fit" Spacing="10" >
<Widget Width="60" Height="40" Background="{}" CornerRadius="3"/>
- <Label Text="{}" Width="Stretched" Font="Mono, 20" />
+ <Label Text="{}" Width="Stretched" Font="Mono, 12" />
</HorizontalStack>
</ListItem>
</ItemTemplate>
--- /dev/null
+<TabView Orientation="Horizontal" Data="{Logs}">
+ <Template>
+ <GenericStack Orientation="{./OppositeOrientation}" Spacing="0" Background="{./Background}">
+ <ListBox Data="{./Items}" Fit="true" HorizontalAlignment="Left" VerticalAlignment="Top" SelectedItem="{²./SelectedItem}">
+ <Template>
+ <GenericStack Orientation="{../../../Orientation}" Name="ItemsContainer" />
+ </Template>
+ <ItemTemplate>
+ <ListItem Fit="true" Background="${InactiveTabItem}" IsSelected="{IsVisible}" Margin="5"
+ Selected="{.DataSource.Visible='true'};{Background=.DataSource.Background}"
+ Unselected="{.DataSource.Visible='false'};{Background=${InactiveTabItem}}">
+ <Label Text="{Name}" />
+ </ListItem>
+ </ItemTemplate>
+ </ListBox>
+ <Group Name="ItemsContainer" />
+ </GenericStack>
+ </Template>
+ <ItemTemplate>
+ <ListItem IsVisible='{IsSelected}' IsSelected='{²IsSelected}'>
+ <VerticalStack>
+ <Label Text="{Name}"/>
+ <ListBox Data="{log}">
+ <ItemTemplate>
+ <Label Text="{msg}"/>
+ </ItemTemplate>
+ </ListBox>
+ </VerticalStack>
+ </ListItem>
+ </ItemTemplate>
+</TabView>
\ No newline at end of file
--- /dev/null
+ <TabView Data="{Logs}">
+ <Template>
+ <VerticalStack Spacing="0" >
+ <ListBox Data="{./Items}" Height="Fit" >
+ <Template>
+ <VerticalStack Spacing="0" >
+ <ScrollBar Orientation="Horizontal" Foreground="RoyalBlue" Height="6" Width="Stretched" CornerRadius="3"
+ Value="{²../ItemsScroller.ScrollX}"
+ LargeIncrement="{../ItemsScroller.PageWidth}" SmallIncrement="1"
+ CursorRatio="{../ItemsScroller.ChildWidthRatio}" Maximum="{../ItemsScroller.MaxScrollX}">
+ <Template>
+ <Container Margin="1" Background="{./Background}">
+ <Widget Name="Cursor" Background="{./Foreground}" CornerRadius="{./CornerRadius}"/>
+ </Container>
+ </Template>
+ </ScrollBar>
+ <Scroller Name="ItemsScroller" Height="Fit" Width="Stretched">
+ <HorizontalStack Name="ItemsContainer" Width="Fit" HorizontalAlignment="Left"/>
+ </Scroller>
+ </VerticalStack>
+ </Template>
+ <ItemTemplate>
+ <ListItem RootDataLevel="true" Fit="true" Background="${InactiveTabBackground}" Foreground="${InactiveTabForeground}" IsSelected="{IsVisible}"
+ Selected="{.DataSource.IsVisible='true'};{Background=${SelectedTabBackground}};{Foreground=${SelectedTabForeground}}"
+ Unselected="{.DataSource.IsVisible='false'};{Background=${InactiveTabBackground}};{Foreground=${InactiveTabForeground}}"
+ BubbleEvents="MouseWheel">
+ <HorizontalStack DataSource="{DataSource}" Margin="3" Spacing="5">
+ <!--<Image Style="TreeIcon" Path="{Icon}" SvgSub="{IconSub}"/> No icon in Document class-->
+ <Label Text="{Name}" ContextCommands="{TabCommands}" Foreground="{../../Foreground}" />
+ <Border CornerRadius="5" BorderWidth="1" Foreground="Transparent" Height="12" Width="12"
+ MouseEnter="{Foreground=White}" MouseLeave="{Foreground=Transparent}">
+ <Image Focusable="true" Name="Image" Margin="0" Width="Stretched" Height="Stretched" Path="#Crow.Icons.exit2.svg"
+ MouseClick="OnQueryClose"/>
+ </Border>
+ </HorizontalStack>
+ </ListItem>
+ </ItemTemplate>
+ </ListBox>
+ <Group Name="ItemsContainer" />
+ </VerticalStack>
+ </Template>
+ <ItemTemplate>
+ <ListItem IsVisible="{IsSelected}" IsSelected="{²IsSelected}">
+ <VerticalStack RootDataLevel="true" >
+ <HorizontalStack Height="Fit" Spacing="2" Margin="1">
+ <Label Text="{../../../Caption}" Fit="true" Foreground="DimGrey" Font="${SmallUIFont}"/>
+ <Widget Width="Stretched"/>
+ <EnumSelector Caption="Filter:" EnumValue="{²../../log.Filter}" />
+ <TextBox Background="Grey" Foreground="Black" MinimumSize="100,1" Text="{²../../log.SearchString}" Width="40%" KeyDown="../../log.onSearch" Font="${SmallUIFont}"/>
+ <CheckBox Fit="true" Caption="Case Sensitive" IsChecked="{²../../log.CaseSensitiveSearch}" Font="${SmallUIFont}"/>
+ <CheckBox Fit="true" Caption="All Word" IsChecked="{²../../log.AllWordSearch}" Font="${SmallUIFont}"/>
+
+ <Menu Style="DockWinTitleBarMenu" Data="{../../log.SearchCommands}" Fit="true" Background="Transparent"/>
+
+ <ListBox Style="DockWinTitleBarIconMenu" Data="{./DockCommands}"/>
+ <ListBox Style="DockWinTitleBarIconMenu" Data="{./Commands}"/>
+ <!--<ListBox Data="{./DockCommands}" Fit="true">
+ <Template>
+ <HorizontalStack Name="ItemsContainer" />
+ </Template>
+ <ItemTemplate Path="#Crow.WindowButton.template"/>
+ </ListBox>
+ <ListBox Data="{./Commands}" Fit="true">
+ <Template>
+ <HorizontalStack Name="ItemsContainer" />
+ </Template>
+ <ItemTemplate Path="#Crow.WindowButton.template"/>
+ </ListBox>-->
+ </HorizontalStack>
+ <ListBox Data="{log}"/>
+ </VerticalStack>
+ </ListItem>
+ </ItemTemplate>
+ </TabView>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<ListBox Data="{AvailaibleDbgEvents}">
+ <Template>
+ <Wrapper Name="ItemsContainer"/>
+ </Template>
+ <ItemTemplate>
+ <ListItem Width="200" Selected="{lab.Background=RoyalBlue}">
+ <Border Foreground="Transparent" MouseEnter="{Foreground=Grey}" MouseLeave="{Foreground=Transparent}">
+ <Label Name="lab" Text="{}" Width="Stretched"/>
+ </Border>
+ </ListItem>
+ </ItemTemplate>
+</ListBox>
--- /dev/null
+<VerticalStack>
+ <Label Text="{TestDbgEventSelect}"/>
+ <EnumSelector Caption="Device Events:" EnumValue="{²TestDbgEventSelect}" ItemStyle="CheckBox2" Width="Fit" Background="Jet">
+ <Template>
+ <Border Style="ControlBorder" Background="{./Background}" CornerRadius="{./CornerRadius}">
+ <HorizontalStack>
+ <Label Text="{./Caption}"/>
+ <Popper Caption="{./EnumValue}" PopDirection="Bottom" >
+ <Template>
+ <Label Text="{./Caption}" Foreground="{./Foreground}" Width="200" />
+ </Template>
+ <Wrapper Width="Fit" Height="400" Name="Content" Background="Onyx" Margin="5" Orientation="Horizontal"/>
+ </Popper>
+ </HorizontalStack>
+ </Border>
+ </Template>
+ </EnumSelector>
+</VerticalStack>
<?xml version="1.0"?>
-<DockStack Name="mainDock" Background="Jet" Margin="0">
- <DockWindow Resizable = "true" Top="100" Left="100" Caption="View 1" Width="300" Height="300"/>
+<Group>
+<DockWindow Style="DockWinSimple" Top="100" Left="100" Caption="View 1" Width="300" Height="300"/>
+<DockStack Width="50%" Name="mainDock" Background="Jet" Margin="0">
+
</DockStack>
-
+</Group>
<!---
<DockWindow Left="450" Top="450" Width="150" Height="150" Background="Yellow"/>-->
--- /dev/null
+<DockWindow Height="Fit" Width="Fit">
+ <Template>
+ <Border Background="{./Background}" Margin="5" CornerRadius="0">
+ <HorizontalStack>
+ <Widget Width="12" Height="Stretched" Background="Onyx" Name="MoveHandle" Focusable="true" CornerRadius="5"/>
+ <Container Name="Content" Width="Stretched"/>
+ </HorizontalStack>
+ </Border>
+ </Template>
+ <ListBox Data="{Commands}" Fit="true">
+ <Template>
+ <HorizontalStack Name="ItemsContainer" Spacing="5" />
+ </Template>
+ <ItemTemplate>
+ <Button Command="{}" MinimumSize="1,1" Width="40" Height="40" Background="vgradient|0:DimGrey|1:Black" CornerRadius="0" >
+ <Template>
+ <Border Style="ButtonBorder" Width="Stretched" Height="Stretched" Margin="10" Background="{./Background}" CornerRadius="{../CornerRadius}">
+ <Image Path="{./Icon}" Tooltip="{./Caption}" Scaled="true" KeepProportions="true" Margin="0"/>
+ </Border>
+ </Template>
+ </Button>
+ </ItemTemplate>
+ </ListBox >
+</DockWindow>
\ No newline at end of file
<VerticalStack Fit="true" Name="vsFps" Spacing="10" >
<HorizontalStack Fit="true">
<Label Text="Layouting:" Width="50" TextAlignment="Right"/>
- <Label Name="labLayouting" Text="{layouting}" Font="droid,12" Width="80" TextAlignment="Center"
+ <Label Name="labLayouting" Text="{layouting}" Font="mono,12" Width="80" TextAlignment="Center"
Background="vgradient|0:SeaGreen|1:Black"/>
</HorizontalStack>
<HorizontalStack Fit="true">
<Label Text="Clipping:" Width="50" TextAlignment="Right"/>
- <Label Text="{update}" Font="droid,12" Width="80" TextAlignment="Center"
+ <Label Text="{update}" Font="mono,12" Width="80" TextAlignment="Center"
Background="vgradient|0:SeaGreen|1:Black"/>
</HorizontalStack>
<HorizontalStack Fit="true">
<Label Text="Drawing:" Width="50" TextAlignment="Right"/>
- <Label Name="labDrawing" Text="{drawing}" Font="droid,12" Width="80" TextAlignment="Center"
+ <Label Name="labDrawing" Text="{drawing}" Font="mono,12" Width="80" TextAlignment="Center"
Background="vgradient|0:SeaGreen|1:Black"/>
</HorizontalStack>
<HorizontalStack Fit="true">
</Border>
<HorizontalStack Fit="true" Background="RoyalBlue" Margin="3">
<Widget Margin="10" Background="LimeGreen" Width="5" Height="5"/>
- <TextBox Font="droid, 16" Multiline="true" Text="this is a test\nmultiline" Margin="2"/>
+ <TextBox Font="mono, 16" Multiline="true" Text="this is a test\nmultiline" Margin="2"/>
<Widget Margin="10" Background="LimeGreen" Width="5" Height="5"/>
</HorizontalStack>
</VerticalStack>
<HorizontalStack Fit="True">
<Button Caption="but" MouseClick="onButClick"/>
<Button Caption="but" MouseClick="onButClick" Fit="true"/>
- <Button Width="60" Height="40" MouseClick="onButClick"/>
+ <Button MouseClick="onButClick"/>
<Button Caption="Long text button" MouseClick="onButClick"/>
- <Button Font="droid, 20" Caption="Button"/>
+ <Button Font="mono, 12" Caption="Button"/>
</HorizontalStack>
</VerticalStack>
\ No newline at end of file
<ProgressBar CornerRadius="5" Background="DimGrey" Margin="1" Maximum="1000" Value="{fps}" Width="200" Height="15"/>
<HorizontalStack Fit="true">
<Label Text="Memory:" Width="50" TextAlignment="Right"/>
- <Label Text="{memory}" Font="droid,12" TextAlignment="Center"
+ <Label Text="{memory}" Font="mono,12" TextAlignment="Center"
Background="vgradient|0:Blue|1:Black"/>
</HorizontalStack>
<HorizontalStack Fit="true">
<Label Text="Update:" Width="50" TextAlignment="Right"/>
- <Label Name="labUpdate" Text="{update}" Font="droid,12" Width="80" TextAlignment="Center"
+ <Label Name="labUpdate" Text="{update}" Font="mono,12" Width="80" TextAlignment="Center"
Background="vgradient|0:Green|1:Black"/>
</HorizontalStack>
<HorizontalStack Fit="true">
<Label Text="Layouting:" Width="50" TextAlignment="Right"/>
- <Label Name="labLayouting" Text="{layouting}" Font="droid,12" Width="80" TextAlignment="Center"
+ <Label Name="labLayouting" Text="{layouting}" Font="mono,12" Width="80" TextAlignment="Center"
Background="vgradient|0:Green|1:Black"/>
</HorizontalStack>
<HorizontalStack Fit="true">
<Label Text="Drawing:" Width="50" TextAlignment="Right"/>
- <Label Name="labDrawing" Text="{drawing}" Font="droid,12" Width="80" TextAlignment="Center"
+ <Label Name="labDrawing" Text="{drawing}" Font="mono,12" Width="80" TextAlignment="Center"
Background="vgradient|0:Green|1:Black"/>
</HorizontalStack>
<HorizontalStack Fit="true">
</HorizontalStack>
<HorizontalStack Fit="true">
<Label Text="Update:" Width="50" TextAlignment="Right"/>
- <Label Name="labUpdate" Text="{update}" Font="droid,12" Width="80" TextAlignment="Center"
+ <Label Name="labUpdate" Text="{update}" Font="mono,12" Width="80" TextAlignment="Center"
Background="vgradient|0:Green|1:Black"/>
</HorizontalStack>
<HorizontalStack Fit="true">
<Label Text="Layouting:" Width="50" TextAlignment="Right"/>
- <Label Name="labLayouting" Text="{layouting}" Font="droid,12" Width="80" TextAlignment="Center"
+ <Label Name="labLayouting" Text="{layouting}" Font="mono,12" Width="80" TextAlignment="Center"
Background="vgradient|0:Green|1:Black"/>
</HorizontalStack>
<HorizontalStack Fit="true">
<Label Text="Drawing:" Width="50" TextAlignment="Right"/>
- <Label Name="labDrawing" Text="{drawing}" Font="droid,12" Width="80" TextAlignment="Center"
+ <Label Name="labDrawing" Text="{drawing}" Font="mono,12" Width="80" TextAlignment="Center"
Background="vgradient|0:Green|1:Black"/>
</HorizontalStack>
<HorizontalStack Fit="true">
</HorizontalStack>
<HorizontalStack Fit="true">
<Label Text="Update:" Width="50" TextAlignment="Right"/>
- <Label Name="labUpdate" Text="{update}" Font="droid,12" Width="80" TextAlignment="Center"
+ <Label Name="labUpdate" Text="{update}" Font="mono,12" Width="80" TextAlignment="Center"
Background="vgradient|0:Green|1:Black"/>
</HorizontalStack>
<HorizontalStack Fit="true">
<Label Text="Layouting:" Width="50" TextAlignment="Right"/>
- <Label Name="labLayouting" Text="{layouting}" Font="droid,12" Width="80" TextAlignment="Center"
+ <Label Name="labLayouting" Text="{layouting}" Font="mono,12" Width="80" TextAlignment="Center"
Background="vgradient|0:Green|1:Black"/>
</HorizontalStack>
<HorizontalStack Fit="true">
<Label Text="Drawing:" Width="50" TextAlignment="Right"/>
- <Label Name="labDrawing" Text="{drawing}" Font="droid,12" Width="80" TextAlignment="Center"
+ <Label Name="labDrawing" Text="{drawing}" Font="mono,12" Width="80" TextAlignment="Center"
Background="vgradient|0:Green|1:Black"/>
</HorizontalStack>
<HorizontalStack Fit="true">
<VerticalStack Fit="true" Name="vsFps" Spacing="10" >
<HorizontalStack Fit="true">
<Label Text="Update:" Width="50" TextAlignment="Right"/>
- <Label Name="labUpdate" Text="{update}" Font="droid,12" Width="80" TextAlignment="Center"
+ <Label Name="labUpdate" Text="{update}" Font="mono,12" Width="80" TextAlignment="Center"
Background="vgradient|0:Green|1:Black"/>
</HorizontalStack>
<HorizontalStack Fit="true">
<Label Text="Layouting:" Width="50" TextAlignment="Right"/>
- <Label Name="labLayouting" Text="{layouting}" Font="droid,12" Width="80" TextAlignment="Center"
+ <Label Name="labLayouting" Text="{layouting}" Font="mono,12" Width="80" TextAlignment="Center"
Background="vgradient|0:Green|1:Black"/>
</HorizontalStack>
<HorizontalStack Fit="true">
<Label Text="Drawing:" Width="50" TextAlignment="Right"/>
- <Label Name="labDrawing" Text="{drawing}" Font="droid,12" Width="80" TextAlignment="Center"
+ <Label Name="labDrawing" Text="{drawing}" Font="mono,12" Width="80" TextAlignment="Center"
Background="vgradient|0:Green|1:Black"/>
</HorizontalStack>
<HorizontalStack Fit="true">
</HorizontalStack>
<HorizontalStack Fit="true">
<Label Text="Update:" Width="50" TextAlignment="Right"/>
- <Label Name="labUpdate" Text="{update}" Font="droid,12" Width="80" TextAlignment="Center"
+ <Label Name="labUpdate" Text="{update}" Font="mono,12" Width="80" TextAlignment="Center"
Background="vgradient|0:Green|1:Black"/>
</HorizontalStack>
<HorizontalStack Fit="true">
<Label Text="Layouting:" Width="50" TextAlignment="Right"/>
- <Label Name="labLayouting" Text="{layouting}" Font="droid,12" Width="80" TextAlignment="Center"
+ <Label Name="labLayouting" Text="{layouting}" Font="mono,12" Width="80" TextAlignment="Center"
Background="vgradient|0:Green|1:Black"/>
</HorizontalStack>
<HorizontalStack Fit="true">
<Label Text="Drawing:" Width="50" TextAlignment="Right"/>
- <Label Name="labDrawing" Text="{drawing}" Font="droid,12" Width="80" TextAlignment="Center"
+ <Label Name="labDrawing" Text="{drawing}" Font="mono,12" Width="80" TextAlignment="Center"
Background="vgradient|0:Green|1:Black"/>
</HorizontalStack>
<HorizontalStack Fit="true">
</HorizontalStack>
<HorizontalStack Fit="true">
<Label Text="Update:" Width="50" TextAlignment="Right"/>
- <Label Name="labUpdate" Text="{update}" Font="droid,12" Width="80" TextAlignment="Center"
+ <Label Name="labUpdate" Text="{update}" Font="mono,12" Width="80" TextAlignment="Center"
Background="vgradient|0:Green|1:Black"/>
</HorizontalStack>
<HorizontalStack Fit="true">
<Label Text="Layouting:" Width="50" TextAlignment="Right"/>
- <Label Name="labLayouting" Text="{layouting}" Font="droid,12" Width="80" TextAlignment="Center"
+ <Label Name="labLayouting" Text="{layouting}" Font="mono,12" Width="80" TextAlignment="Center"
Background="vgradient|0:Green|1:Black"/>
</HorizontalStack>
<HorizontalStack Fit="true">
<Label Text="Drawing:" Width="50" TextAlignment="Right"/>
- <Label Name="labDrawing" Text="{drawing}" Font="droid,12" Width="80" TextAlignment="Center"
+ <Label Name="labDrawing" Text="{drawing}" Font="mono,12" Width="80" TextAlignment="Center"
Background="vgradient|0:Green|1:Black"/>
</HorizontalStack>
<HorizontalStack Fit="true">
<VerticalStack Fit="true" Name="vsFps" Spacing="10" >
<HorizontalStack Fit="true">
<Label Text="Update:" Width="50" TextAlignment="Right"/>
- <Label Name="labUpdate" Text="{update}" Font="droid,12" Width="80" TextAlignment="Center"
+ <Label Name="labUpdate" Text="{update}" Font="mono,12" Width="80" TextAlignment="Center"
Background="vgradient|0:Green|1:Black"/>
</HorizontalStack>
<HorizontalStack Fit="true">
<Label Text="Layouting:" Width="50" TextAlignment="Right"/>
- <Label Name="labLayouting" Text="{layouting}" Font="droid,12" Width="80" TextAlignment="Center"
+ <Label Name="labLayouting" Text="{layouting}" Font="mono,12" Width="80" TextAlignment="Center"
Background="vgradient|0:Green|1:Black"/>
</HorizontalStack>
<HorizontalStack Fit="true">
<Label Text="Drawing:" Width="50" TextAlignment="Right"/>
- <Label Name="labDrawing" Text="{drawing}" Font="droid,12" Width="80" TextAlignment="Center"
+ <Label Name="labDrawing" Text="{drawing}" Font="mono,12" Width="80" TextAlignment="Center"
Background="vgradient|0:Green|1:Black"/>
</HorizontalStack>
<HorizontalStack Fit="true">
</HorizontalStack>
<HorizontalStack Fit="true">
<Label Text="Update:" Width="50" TextAlignment="Right"/>
- <Label Name="labUpdate" Text="{update}" Font="droid,12" Width="80" TextAlignment="Center"
+ <Label Name="labUpdate" Text="{update}" Font="mono,12" Width="80" TextAlignment="Center"
Background="vgradient|0:Green|1:Black"/>
</HorizontalStack>
<HorizontalStack Fit="true">
<Label Text="Layouting:" Width="50" TextAlignment="Right"/>
- <Label Name="labLayouting" Text="{layouting}" Font="droid,12" Width="80" TextAlignment="Center"
+ <Label Name="labLayouting" Text="{layouting}" Font="mono,12" Width="80" TextAlignment="Center"
Background="vgradient|0:Green|1:Black"/>
</HorizontalStack>
<HorizontalStack Fit="true">
<Label Text="Drawing:" Width="50" TextAlignment="Right"/>
- <Label Name="labDrawing" Text="{drawing}" Font="droid,12" Width="80" TextAlignment="Center"
+ <Label Name="labDrawing" Text="{drawing}" Font="mono,12" Width="80" TextAlignment="Center"
Background="vgradient|0:Green|1:Black"/>
</HorizontalStack>
<HorizontalStack Fit="true">
</HorizontalStack>
<HorizontalStack Fit="true">
<Label Text="Update:" Width="50" TextAlignment="Right"/>
- <Label Name="labUpdate" Text="{update}" Font="droid,12" Width="80" TextAlignment="Center"
+ <Label Name="labUpdate" Text="{update}" Font="mono,12" Width="80" TextAlignment="Center"
Background="vgradient|0:Green|1:Black"/>
</HorizontalStack>
<HorizontalStack Fit="true">
<Label Text="Layouting:" Width="50" TextAlignment="Right"/>
- <Label Name="labLayouting" Text="{layouting}" Font="droid,12" Width="80" TextAlignment="Center"
+ <Label Name="labLayouting" Text="{layouting}" Font="mono,12" Width="80" TextAlignment="Center"
Background="vgradient|0:Green|1:Black"/>
</HorizontalStack>
<HorizontalStack Fit="true">
<Label Text="Drawing:" Width="50" TextAlignment="Right"/>
- <Label Name="labDrawing" Text="{drawing}" Font="droid,12" Width="80" TextAlignment="Center"
+ <Label Name="labDrawing" Text="{drawing}" Font="mono,12" Width="80" TextAlignment="Center"
Background="vgradient|0:Green|1:Black"/>
</HorizontalStack>
<HorizontalStack Fit="true">
<VerticalStack Fit="true" Name="vsFps" Spacing="10" >
<HorizontalStack Fit="true">
<Label Text="Update:" Width="50" TextAlignment="Right"/>
- <Label Name="labUpdate" Text="{update}" Font="droid,12" Width="80" TextAlignment="Center"
+ <Label Name="labUpdate" Text="{update}" Font="mono,12" Width="80" TextAlignment="Center"
Background="vgradient|0:Green|1:Black"/>
</HorizontalStack>
<HorizontalStack Fit="true">
<Label Text="Layouting:" Width="50" TextAlignment="Right"/>
- <Label Name="labLayouting" Text="{layouting}" Font="droid,12" Width="80" TextAlignment="Center"
+ <Label Name="labLayouting" Text="{layouting}" Font="mono,12" Width="80" TextAlignment="Center"
Background="vgradient|0:Green|1:Black"/>
</HorizontalStack>
<HorizontalStack Fit="true">
<Label Text="Drawing:" Width="50" TextAlignment="Right"/>
- <Label Name="labDrawing" Text="{drawing}" Font="droid,12" Width="80" TextAlignment="Center"
+ <Label Name="labDrawing" Text="{drawing}" Font="mono,12" Width="80" TextAlignment="Center"
Background="vgradient|0:Green|1:Black"/>
</HorizontalStack>
<HorizontalStack Fit="true">
</HorizontalStack>
<HorizontalStack Fit="true">
<Label Text="Update:" Width="50" TextAlignment="Right"/>
- <Label Name="labUpdate" Text="{update}" Font="droid,12" Width="80" TextAlignment="Center"
+ <Label Name="labUpdate" Text="{update}" Font="mono,12" Width="80" TextAlignment="Center"
Background="vgradient|0:Green|1:Black"/>
</HorizontalStack>
<HorizontalStack Fit="true">
<Label Text="Layouting:" Width="50" TextAlignment="Right"/>
- <Label Name="labLayouting" Text="{layouting}" Font="droid,12" Width="80" TextAlignment="Center"
+ <Label Name="labLayouting" Text="{layouting}" Font="mono,12" Width="80" TextAlignment="Center"
Background="vgradient|0:Green|1:Black"/>
</HorizontalStack>
<HorizontalStack Fit="true">
<Label Text="Drawing:" Width="50" TextAlignment="Right"/>
- <Label Name="labDrawing" Text="{drawing}" Font="droid,12" Width="80" TextAlignment="Center"
+ <Label Name="labDrawing" Text="{drawing}" Font="mono,12" Width="80" TextAlignment="Center"
Background="vgradient|0:Green|1:Black"/>
</HorizontalStack>
<HorizontalStack Fit="true">
</HorizontalStack>
<HorizontalStack Fit="true">
<Label Text="Update:" Width="50" TextAlignment="Right"/>
- <Label Name="labUpdate" Text="{update}" Font="droid,12" Width="80" TextAlignment="Center"
+ <Label Name="labUpdate" Text="{update}" Font="mono,12" Width="80" TextAlignment="Center"
Background="vgradient|0:Green|1:Black"/>
</HorizontalStack>
<HorizontalStack Fit="true">
<Label Text="Layouting:" Width="50" TextAlignment="Right"/>
- <Label Name="labLayouting" Text="{layouting}" Font="droid,12" Width="80" TextAlignment="Center"
+ <Label Name="labLayouting" Text="{layouting}" Font="mono,12" Width="80" TextAlignment="Center"
Background="vgradient|0:Green|1:Black"/>
</HorizontalStack>
<HorizontalStack Fit="true">
<Label Text="Drawing:" Width="50" TextAlignment="Right"/>
- <Label Name="labDrawing" Text="{drawing}" Font="droid,12" Width="80" TextAlignment="Center"
+ <Label Name="labDrawing" Text="{drawing}" Font="mono,12" Width="80" TextAlignment="Center"
Background="vgradient|0:Green|1:Black"/>
</HorizontalStack>
<HorizontalStack Fit="true">
--- /dev/null
+<?xml version="1.0"?>
+<VerticalStack CacheEnabled="false" Name="MoveHandle" Background="{./Background}">
+ <Label CacheEnabled="false" Background="Jet" Text="{./DockingPosition}"/>
+</VerticalStack>