}
Button {
Template = "#Crow.Button.template";
+ //Focusable = "true";
Caption = "Button";
- MinimumSize = "50,22";
+ MinimumSize = "60,22";
Height = "Fit";
Width = "Fit";
}
//Selected = "{Background=${ControlHighlight}}";
//Unselected = "{Background=Transparent}";
//Margin="1";
+ Focusable = "true";
}
MessageBox {
Background = "0.1,0.1,0.2,0.85";
Button, CheckBox, RadioButton, ComboBox, Expandable,
MessageBox, Popper, Slider, Spinner, TextBox, NumericControl {
- //Focusable = "true";
+ Focusable = "true";
Foreground="${ControlForeground}";
Height = "Fit";
Background = "${ControlBackground}";
CornerRadius = "${ControlCornerRadius}";
Margin="0";
- BubbleMouseEvent="MouseWheel|Keyboard";
+ BubbleEvents="MouseWheel|Keyboard";
}
TemplatedControl, GenericStack {
CacheEnabled="true";
<?xml version="1.0"?>
-<Border Style="ButtonBorder" Background="{./Background}" Name="Content" CornerRadius="{../CornerRadius}" >
+<Border Style="ButtonBorder" Background="{./Background}" Name="Content" CornerRadius="{../CornerRadius}" Width="Stretched" Height="Stretched" >
<Label Font="{./Font}" Name="caption" Margin="${ButtonCaptionMargin}" Foreground="{./Foreground}" Text="{./Caption}"/>
</Border>
-<Border Foreground="Transparent" MouseEnter="{Foreground=Grey}" MouseLeave="{Foreground=Transparent}">
- <Label Font="{./Font}" Text="{./Caption}"
- Margin="1"
- Background="{./Background}"
- Foreground="{./Foreground}"
- TextAlignment="Center"/>
-</Border>
\ No newline at end of file
+<Label Font="{./Font}" Text="{./Caption}" CornerRadius="{./CornerRadius}" Width="Stretched"
+ Margin="3"
+ Background="{./Background}"
+ Foreground="{./Foreground}"
+ TextAlignment="Center"/>
\ No newline at end of file
Orientation="Vertical"
IsOpened ="true" IsVisible="{/IsOpened}"
ItemTemplate="#Crow.MenuItem.itmp">
- <Template>
- <GenericStack Orientation="{./Orientation}" Name="ItemsContainer" Margin="0" Background="${MenuBackground}"/>
+ <Template>
+ <GenericStack Orientation="{./Orientation}" Name="ItemsContainer" Margin="0" Background="${MenuBackground}"/>
</Template>
</MenuItem>
Name="ItemsContainer" Margin="0" Spacing="1"/>
</Scroller>
<ScrollBar Name="scrollbar1" Orientation="Vertical"
- Value="{²../scroller1.ScrollY}" Maximum="{../scroller1.MaxScrollY}"
+ Value="{²../scroller1.ScrollY}" Maximum="{../scroller1.MaxScrollY}"
CursorRatio="{../scroller1.ChildHeightRatio}"
LargeIncrement="{../scroller1.PageHeight}" SmallIncrement="30"
Width="14" />
<CheckBox Style="CheckBoxAlt" Name="cbShowHidden" Caption="Show Hidden" IsChecked="{²./ShowHidden}"/>
</HorizontalStack>
<HorizontalStack Fit="true" HorizontalAlignment="Right" Margin="3" Spacing="3">
- <Button Caption="Ok" MouseClick="./onFileSelect"/>
- <Button Caption="Cancel" MouseClick="./onCancel"/>
+ <Button Caption="Ok" Command="{./CMDOk}"/>
+ <Button Caption="Cancel" Command="{./CMDCancel}"/>
</HorizontalStack>
</VerticalStack>
</Container>
<?xml version="1.0"?>
-<Button Command="{}" Width="Stretched">
+<Button Command="{}" Width="Stretched" BubbleEvents="All">
<Template>
<Label Text="{./Caption}" Width="Stretched" Height="Stretched" Margin="3"
MouseEnter="{Background=${ControlHighlight}}"
<ItemTemplate DataType="Crow.Command" Path="#Crow.MenuButton.template"/>
<ItemTemplate DataType="Crow.CommandGroup" Data="Commands">
<Popper PopDirection="Right" Caption="{Caption}" IsEnabled="{CanExecute}" Width="Stretched"
+ BubbleEvents="All"
MouseEnter="{Background=${ControlHighlight}}"
MouseLeave="{Background=Transparent}">
<Template>
<Label Text="{./Caption}" Width="Fit" Height="Stretched"/>
<Label Text="..."/>
</HorizontalStack>
- </Template>
+ </Template>
<VerticalStack Margin="0" Name="ItemsContainer" Fit="true" Background="${MenuBackground}"/>
</Popper>
</ItemTemplate>
<?xml version="1.0"?>
<ListItem>
<Popper Font="{./Font}" Caption="{./Caption}" Background="{./Background}" PopDirection="{./PopDirection}"
- Foreground = "{./Foreground}" BubbleMouseEvent="All"
+ Foreground = "{./Foreground}" BubbleEvents="All"
IsPopped="{²./IsOpened}" PopWidth="{./PopWidth}" PopHeight="{./PopHeight}">
<Template>
<?xml version="1.0"?>
<Border Style="ControlBorder" Background="{./Background}" CornerRadius="{./CornerRadius}">
<HorizontalStack Spacing="1">
- <Image Style="Icon"
- MouseEnter="{Background=White}" MouseLeave="{Background=Transparent}"
+ <Image Style="Icon"
+ MouseEnter="{Background=White}" MouseLeave="{Background=Transparent}"
Path="#Crow.Icons.expandable.svg" SvgSub="{./IsPopped}"/>
<Label Style="ControlCaption" Text="{./Caption}" Foreground="{./Foreground}"/>
</HorizontalStack>
=> value == (UInt32)other;*/
public bool Equals (Color other)
- => value == other.value;
+ => value == other.value;
public override int GetHashCode ()
=> value.GetHashCode ();
public override string ToString()
=> EnumsNET.Enums.IsValid<Colors> ((Colors)value) ? EnumsNET.Enums.GetName((Colors)value) : HtmlCode;
-
+
public static Color FromIml (string iml)
{
Span<double> components = stackalloc double[4];
components[3] = 1;//init alpha to 1 so that it can be ommitted
- ReadOnlySpan<char> c = iml.AsSpan ();
+ ReadOnlySpan<char> c = iml.AsSpan ();
int i = 0;
int ioc = c.IndexOf (',');
c = c.Slice (ioc + 1);
ioc = c.IndexOf (',');
}
- components[i++] = double.Parse (c);
+ components[i++] = double.Parse (c);
return new Color (components);
}
return null;
string [] tmp = str.Trim ().Split (';', StringSplitOptions.None);
- DbgEvtType evtType = (DbgEvtType)Enum.Parse (typeof (DbgEvtType), tmp [3]);
+ DbgEvtType evtType = (DbgEvtType)Enum.Parse (typeof (DbgEvtType), tmp [3]);
if (evtType.HasFlag (DbgEvtType.Widget)) {
if (evtType.HasFlag (DbgEvtType.Layouting))
case DbgEvtType.Update:
return Colors.Grey;
case DbgEvtType.IFaceLoad:
- return Colors.Teal;
+ return Colors.Teal;
default:
if (type.HasFlag(DbgEvtType.Mouse))
return Colors.DeepPink;
return Colors.White;
}
}
- }
+ }
}
}
\ No newline at end of file
[Flags]
public enum DbgEvtType : Int32 {
None = 0,
- IFace = 0x40000000,
- Widget = 0x20000000,
+ IFace = 0x00000100,
+ Widget = 0x00000200,
- Warning = 0x10000000,
- Error = 0x08000000,
+ Warning = 0x00000400,
+ Error = 0x00000800,
- Binding = 0x800000,
- Lock = 0x400000,
- Layouting = 0x200000,
- Clipping = 0x100000,
- Drawing = 0x080000,
+ Binding = 0x00001000,
+ Lock = 0x00002000,
+ Layouting = 0x00004000,
+ Clipping = 0x00008000,
+ Drawing = 0x00010000,
- Focus = 0x040000,
- Override = 0x020000,
- TemplatedGroup = 0x010000,
- Dispose = 0x008000,
- Mouse = 0x004000,
+ Focus = 0x00020000,
+ Override = 0x00040000,
+ TemplatedGroup = 0x00080000,
+ Dispose = 0x00100000,
+ Mouse = 0x00200000,
- Update = IFace | 0x004000,
+ Update = IFace | 0x00100000,
ProcessLayouting = IFace | Update | Lock | Layouting,
ClippingRegistration = IFace | Update | Lock | Clipping,
ProcessDrawing = IFace | Update | Lock | Drawing,
MouseDown = IFace | Mouse | 0x01,
MouseUp = IFace | Mouse | 0x02,
MouseMove = IFace | Mouse | 0x03,
- GOMouseDown = Widget | Mouse | 0x01,
- GOMouseUp = Widget | Mouse | 0x02,
- GOMouseMove = Widget | Mouse | 0x03,
+ MouseEnter = Widget | Mouse | 0x01,
+ MouseLeave = Widget | Mouse | 0x02,
+ WidgetMouseMove = Widget | Mouse | 0x03,
+ WidgetMouseDown = Widget | Mouse | 0x04,
+ WidgetMouseUp = Widget | Mouse | 0x05,
+ WidgetMouseWheel = Widget | Mouse | 0x06,
+ WidgetMouseClick = Widget | Mouse | 0x07,
+ WidgetMouseDblClick = Widget | Mouse | 0x08,
All = 0x7FFFFF00
}
using System.Threading;
namespace Crow.DebugLogger
-{
+{
public class DbgWidgetEvent : DbgEvent
{
public int InstanceIndex;
InstanceIndex = widgetInstanceIndex;
}
//public override string Print() => $"{base.Print()}:{InstanceIndex}"
-
+
public override string ToString ()
=> $"{base.ToString ()};{InstanceIndex}";
public override Color Color {
return Colors.White;
}
}
- }
- }
+ }
+ }
}
\ No newline at end of file
-using System.Text;
-// Copyright (c) 2013-2021 Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
+// Copyright (c) 2013-2021 Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
//
// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
-
+using System.Text;
using System;
using System.Collections.Generic;
using System.Diagnostics;
{
public static class DbgLogger
{
- public static DbgEvtType IncludeEvents = DbgEvtType.All;
- public static DbgEvtType DiscardEvents = DbgEvtType.Focus;
+ /*public static DbgEvtType IncludeEvents = DbgEvtType.All;
+ public static DbgEvtType DiscardEvents = DbgEvtType.Focus;*/
+
+ public static List<DbgEvtType> IncludedEvents = new List<DbgEvtType> ();
public static bool ConsoleOutput = true;
#if DEBUG_LOG
- static bool logevt (DbgEvtType evtType)
- //=> IncludeEvents != DbgEvtType.None && (evtType & DiscardEvents) == 0 && (evtType & IncludeEvents) == IncludeEvents;
- //=> IncludeEvents != DbgEvtType.None && (evtType & DiscardEvents) == 0 && (evtType & IncludeEvents) == IncludeEvents;
- => IncludeEvents == DbgEvtType.All || (IncludeEvents != DbgEvtType.None && (evtType & IncludeEvents) != 0);
-
-
+ static bool logevt (DbgEvtType evtType) {
+ foreach (DbgEvtType et in IncludedEvents) {
+ if ((et & evtType) == et)
+ return true;
+ }
+ return false;
+ }
static object logMutex = new object ();
static Stopwatch chrono = Stopwatch.StartNew ();
}
internal static MethodInfo SearchExtMethod (Type t, string methodName)
{
- string key = t.Name + "." + methodName;
- lock (knownExtMethods) {
- if (knownExtMethods.ContainsKey (key))
- return knownExtMethods [key];
-
- //System.Diagnostics.Console.WriteLine ($"*** search extension method: {t};{methodName} => key={key}");
-
- MethodInfo mi = null;
- if (!TryGetExtensionMethods (Assembly.GetEntryAssembly (), t, methodName, out mi)) {
- if (!TryGetExtensionMethods (t.Module.Assembly, t, methodName, out mi)) {
- foreach (Assembly a in Interface.crowAssemblies) {
- if (TryGetExtensionMethods (a, t, methodName, out mi))
- break;
+ try {
+ string key = t.Name + "." + methodName;
+ lock (knownExtMethods) {
+ if (knownExtMethods.ContainsKey (key))
+ return knownExtMethods [key];
+
+ //System.Diagnostics.Console.WriteLine ($"*** search extension method: {t};{methodName} => key={key}");
+
+ MethodInfo mi = null;
+ if (!TryGetExtensionMethods (Assembly.GetEntryAssembly (), t, methodName, out mi)) {
+ if (!TryGetExtensionMethods (t.Module.Assembly, t, methodName, out mi)) {
+ foreach (Assembly a in Interface.crowAssemblies) {
+ if (TryGetExtensionMethods (a, t, methodName, out mi))
+ break;
+ }
+ if (mi == null)
+ TryGetExtensionMethods (Assembly.GetExecutingAssembly (), t, methodName, out mi);//crow Assembly
}
- if (mi == null)
- TryGetExtensionMethods (Assembly.GetExecutingAssembly (), t, methodName, out mi);//crow Assembly
}
- }
- //add key even if mi is null to prevent searching again and again for propertyless bindings
- knownExtMethods.Add (key, mi);
- return mi;
+ //add key even if mi is null to prevent searching again and again for propertyless bindings
+ knownExtMethods.Add (key, mi);
+ return mi;
+ }
+ } catch (Exception e) {//added this catch for CrowEdit, ext method should be search with appropriate LoadContext.
+ Debug.WriteLine ($"[CompilerServices.SearchExtMethod]{e}");
}
+ return null;
}
public static bool TryGetExtensionMethods (Assembly assembly, Type extendedType, string methodName, out MethodInfo foundMI)
while (reader.NodeType != XmlNodeType.Element)
reader.Read ();
root = reader.Name;
- Type t = GetWidgetTypeFromName (root);
+ Type t = iface.GetWidgetTypeFromName (root);
if (t == null)
throw new Exception ("IML parsing error: undefined root type (" + root + ")");
return t;
}
if (itemTemplateIds.Count == 0) {
//try to load ItemTemplate(s) from ItemTemplate property of TemplatedGroup
- if (!string.IsNullOrEmpty (itemTemplatePath)) {
+ //but don't if it's an binding expression
+ if (!string.IsNullOrEmpty (itemTemplatePath) && !itemTemplatePath.StartsWith('{')) {
//check if it is already loaded in cache as a single itemTemplate instantiator
if (iface.ItemTemplates.ContainsKey (itemTemplatePath))
itemTemplateIds.Add (new string [] { "default", itemTemplatePath, "" });
}
}
}
+ //TODO(09/2021):output an ItemTemplateDecl object instead of an array of string
public static IEnumerable<string[]> loadItemTemplatesFromTemplatedGroupProperty (Interface iface, string itemTemplatePath) {
using (Stream stream = iface.GetStreamFromPath (itemTemplatePath)) {
- //itemtemplate files may have multiple root nodes
- XmlReaderSettings itrSettings = new XmlReaderSettings { ConformanceLevel = ConformanceLevel.Fragment };
- using (XmlReader itr = XmlReader.Create (stream, itrSettings)) {
- while (itr.Read ()) {
- if (!itr.IsStartElement ())
- continue;
- if (itr.NodeType == XmlNodeType.Element) {
- if (itr.Name != NT_iTemp) {
- //the file contains a single template to use as default
- iface.ItemTemplates [itemTemplatePath] = new ItemTemplate (iface, itr);
- yield return new string [] { "default", itemTemplatePath, "", "TypeOf" };
- break;//we should be at the end of the file
- }
- yield return parseItemTemplateTag (iface, itr, itemTemplatePath);
+ foreach (string[] item in loadItemTemplatesFromTemplatedGroupProperty (iface, stream, itemTemplatePath))
+ yield return item;
+ }
+ }
+ public static IEnumerable<string[]> loadItemTemplatesFromTemplatedGroupProperty (Interface iface, Stream stream, string itemTemplatePath = null) {
+ if (string.IsNullOrEmpty (itemTemplatePath))
+ itemTemplatePath = Guid.NewGuid().ToString();
+ //itemtemplate files may have multiple root nodes
+ XmlReaderSettings itrSettings = new XmlReaderSettings { ConformanceLevel = ConformanceLevel.Fragment };
+ using (XmlReader itr = XmlReader.Create (stream, itrSettings)) {
+ while (itr.Read ()) {
+ if (!itr.IsStartElement ())
+ continue;
+ if (itr.NodeType == XmlNodeType.Element) {
+ if (itr.Name != NT_iTemp) {
+ //the file contains a single template to use as default
+ iface.ItemTemplates [itemTemplatePath] = new ItemTemplate (iface, itr);
+ yield return new string [] { "default", itemTemplatePath, "", "TypeOf" };
+ break;//we should be at the end of the file
}
+ yield return parseItemTemplateTag (iface, itr, itemTemplatePath);
}
}
}
ctx.il.Emit (OpCodes.Ldloc_0);
ctx.il.Emit (OpCodes.Ldloc_0);
- Type t = GetWidgetTypeFromName (reader.Name);
+ Type t = iface.GetWidgetTypeFromName (reader.Name);
if (t == null)
throw new Exception (reader.Name + " type not found");
ConstructorInfo ci = t.GetConstructor (
public class KeyPressEventArgs : CrowEventArgs
{
char key_char;
-
+
/// <summary>
/// Constructs a new instance.
/// </summary>
}
}
- internal Dictionary<string, MethodInfo> knownExtMethods = new Dictionary<string, MethodInfo> ();
- internal MethodInfo SearchExtMethod (Type t, string methodName) {
+ protected Dictionary<string, MethodInfo> knownExtMethods;
+ protected Dictionary<string, Type> knownCrowWidgetTypes;
+
+ /// <summary>
+ /// search for graphic object type in crow assembly, if not found,
+ /// search for type independently of namespace in all the loaded assemblies
+ /// </summary>
+ /// <remarks>
+ /// </remarks>
+ /// <returns>the corresponding type object</returns>
+ /// <param name="typeName">graphic object type name without its namespace</param>
+ public virtual Type GetWidgetTypeFromName (string typeName){
+ if (knownCrowWidgetTypes.ContainsKey (typeName))
+ return knownCrowWidgetTypes [typeName];
+ Type t = Type.GetType ("Crow." + typeName);
+ if (t != null) {
+ knownCrowWidgetTypes.Add (typeName, t);
+ return t;
+ }
+
+ 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)
+ continue;
+ knownCrowWidgetTypes.Add (typeName, expT);
+ return expT;
+ }
+ }
+ return null;
+ }
+
+
+ public virtual MethodInfo SearchExtMethod (Type t, string methodName) {
string key = t.Name + "." + methodName;
if (knownExtMethods.ContainsKey (key))
return knownExtMethods [key];
DefaultValuesLoader = new Dictionary<string, LoaderInvoker> (initCapacity);
Instantiators = new Dictionary<string, Instantiator> (initCapacity);
ItemTemplates = new Dictionary<string, ItemTemplate> (initCapacity);
+ knownCrowWidgetTypes = new Dictionary<string, Type> (initCapacity);
+ knownExtMethods = new Dictionary<string, MethodInfo> (initCapacity);
}
void loadThemeFiles () {
if (string.IsNullOrEmpty (Theme))
}
_hoverWidget = value;
+ if (_hoverWidget.ToString() == "HelloWorld.Program.vs2.Border12")
+ Debugger.Break();
+
NotifyValueChanged ("HoverWidget", _hoverWidget);
DbgLogger.AddEvent (DbgEvtType.HoverWidget, _hoverWidget);
return true;
}
- if (doubleClickTriggered)
- _activeWidget.onMouseDoubleClick (_activeWidget, new MouseButtonEventArgs (MousePosition.X, MousePosition.Y, button, InputAction.Press));
- else
- _activeWidget.onMouseClick (_activeWidget, new MouseButtonEventArgs (MousePosition.X, MousePosition.Y, button, InputAction.Press));
+ if (_focusedWidget != null &&_focusedWidget.MouseIsIn(MousePosition)) {
+ if (doubleClickTriggered)
+ _activeWidget.onMouseDoubleClick (_activeWidget, new MouseButtonEventArgs (MousePosition.X, MousePosition.Y, button, InputAction.Press));
+ else
+ _activeWidget.onMouseClick (_activeWidget, new MouseButtonEventArgs (MousePosition.X, MousePosition.Y, button, InputAction.Press));
+ }
ActiveWidget = null;
// if (!lastActive.MouseIsIn (Mouse.Position)) {
else
ctxMenuContainer.IsOpened = true;
- ctxMenuContainer.BubbleMouseEvent = DeviceEventType.None;
+ ctxMenuContainer.BubbleEvents = DeviceEventType.None;
ctxMenuContainer.LogicalParent = go;
ctxMenuContainer.DataSource = go;
using System.Linq;
using Crow.IML;
using System.Collections;
-
+//TODO(09/2021): itemTemplate are created with datatest and datatype only to be able
+//to get their original iml, but itor part takes no advantage of it.
+//One advantage could be to set the DataSourceType (which speed bindings by bypassing reflection)
+//at the root level of the item template if the dataTest is 'typeOf'...
namespace Crow
{
/// <summary> Test func on data, return yes if there's children </summary>
return true;
}
public bool TryRead (char c) => EndOfSpan ? false : Read() == c;
-
+
public ReadOnlySpan<char> Read (int length) => buffer.Slice (curPos += length, length);
public void Advance (int increment = 1) => curPos += increment;
- public bool TryAdvance (int increment = 1) {
+ public bool TryAdvance (int increment = 1) {
curPos += increment;
return curPos < buffer.Length;
}
-
+
public bool TryReadUntil (ReadOnlySpan<char> str, StringComparison comparison = StringComparison.Ordinal) {
int startPos = curPos;
while (curPos < buffer.Length - str.Length) {
if (buffer[curPos] == str[0] && buffer.Slice(curPos + 1, str.Length - 1).Equals(str.Slice (1), comparison))
return true;
- curPos++;
+ curPos++;
}
return false;
}
public bool TryReadUntil (char c) {
int startPos = curPos;
while (curPos < buffer.Length && buffer[curPos] != c)
- curPos++;
+ curPos++;
return curPos < buffer.Length;
}
public bool TryRead (int length, out ReadOnlySpan<char> str) {
str = default;
return false;
}
-
+
/// <summary>
/// Try read expected string and advance reader position in any case
/// </summary>
}
public bool TryPeak (ReadOnlySpan<char> expectedString, StringComparison comparison = StringComparison.Ordinal) =>
(buffer.Length < curPos + expectedString.Length)? false :
- buffer.Slice(curPos, expectedString.Length).Equals (expectedString, comparison);
-
+ 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);
- public bool EndOfSpan => curPos >= buffer.Length;
+ /// <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>
+ /// <param name="chars"></param>
+ /// <returns></returns>
public bool IsNextCharIn (params char[] chars) {
for (int i = 0; i < chars.Length; i++)
if (chars[i] == buffer[curPos])
return true;
return false;
}
+ /// <summary>
+ /// increment reader position just before the next end of line
+ /// </summary>
+ public void AdvanceUntilEol () {
+ while(!EndOfSpan) {
+ switch (Peak) {
+ case '\x85':
+ case '\x2028':
+ case '\xA':
+ return;
+ case '\xD':
+ int nextPos = curPos + 1;
+ if (nextPos == buffer.Length || buffer[nextPos] == '\xA' || buffer[nextPos] == '\x85')
+ return;
+ break;
+ }
+ Advance ();
+ }
+ }
+ /// <summary>
+ /// Next char or pair of chars is end of line.
+ /// </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'));
+
+ }
}
}
public void onClickForExpand (object sender, MouseButtonEventArgs e)
{
IsExpanded = !IsExpanded;
+ e.Handled = true;
}
#region Public properties
public class FileDialog: Window
{
#region CTOR
- protected FileDialog() : base(){}
+ protected FileDialog() : base() {}
public FileDialog (Interface iface) : base(iface){}
#endregion
+ protected override void loadTemplate(Widget template = null)
+ {
+ if (CMDOk == null) {
+ CMDOk = new ActionCommand (this, "Ok", validate, null, new KeyBinding (Glfw.Key.Enter));
+ CMDCancel = new ActionCommand (this, "Cancel", () => IFace.DeleteWidget (this), null, new KeyBinding (Glfw.Key.Escape));
+ }
+ base.loadTemplate(template);
+ }
string searchPattern, curDir, _selectedFile, _selectedDir;
bool showHidden, showFiles;
public event EventHandler OkClicked;
#endregion
+ [XmlIgnore]public ActionCommand CMDOk { get; set;}
+ [XmlIgnore]public ActionCommand CMDCancel { get; set;}
+
public string SelectedFileFullPath {
get { return Path.Combine (SelectedDirectory, SelectedFile); }
}
CurrentDirectory = SelectedDirectory;
}
- void onFileSelect (object sender, MouseButtonEventArgs e){
+ void validate () {
if (ShowFiles) {
if (string.IsNullOrEmpty (SelectedFile)) {
CurrentDirectory = SelectedDirectory;
return;
- }
+ }
}
OkClicked.Raise (this, null);
IFace.DeleteWidget (this);
}
- void onCancel(object sender, MouseButtonEventArgs e){
- IFace.DeleteWidget (this);
+ protected override void Dispose(bool disposing)
+ {
+ CMDOk?.Dispose ();
+ CMDCancel?.Dispose ();
+ base.Dispose(disposing);
}
-
}
}
{
if (IsOpened)
IsOpened = false;
- base.onMouseLeave (this, e);
+ if (mouseIsEntered)
+ base.onMouseLeave (this, e);
}
public override void onMouseClick (object sender, MouseButtonEventArgs e)
{
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
+using System.IO;
using System.Linq;
using System.Threading;
ItemTemplates.Clear();
if (string.IsNullOrEmpty (_itemTemplate))
return;
- foreach (string[] itempIds in Instantiator.loadItemTemplatesFromTemplatedGroupProperty (IFace, _itemTemplate)) {
- ItemTemplate itemp = IFace.GetItemTemplate (itempIds[1]);
- ItemTemplates.Add (itempIds[0], itemp);
- if (string.IsNullOrEmpty (itempIds[2]))
- continue;
- itemp.CreateExpandDelegate (this);
+ if (_itemTemplate.Trim().StartsWith('<')) {//iml fragment in property
+ using (Stream stream = new MemoryStream (System.Text.Encoding.UTF8.GetBytes (_itemTemplate))) {
+ foreach (string[] itempIds in Instantiator.loadItemTemplatesFromTemplatedGroupProperty (IFace, stream)) {
+ ItemTemplate itemp = IFace.GetItemTemplate (itempIds[1]);
+ ItemTemplates.Add (itempIds[0], itemp);
+ if (string.IsNullOrEmpty (itempIds[2]))
+ continue;
+ itemp.CreateExpandDelegate (this);
+ }
+ }
+ } else {
+ foreach (string[] itempIds in Instantiator.loadItemTemplatesFromTemplatedGroupProperty (IFace, _itemTemplate)) {
+ ItemTemplate itemp = IFace.GetItemTemplate (itempIds[1]);
+ ItemTemplates.Add (itempIds[0], itemp);
+ if (string.IsNullOrEmpty (itempIds[2]))
+ continue;
+ itemp.CreateExpandDelegate (this);
+ }
}
+ realoadDatas ();
+ }
+ void realoadDatas () {
+ if (data == null)
+ return;
+ IEnumerable dataSave = data;
+ Data = null;
+ Data = dataSave;
}
protected override void loadTemplate(Widget template = null)
{
lock (IFace.UpdateMutex)
ClearItems ();
- if (data == null)
+ if (data == null) {
+ NotifyValueChanged ("HasItems", false);
return;
+ }
if (data is ICollection c) {
if (c.Count == 0) {
itempKey = dataType.FullName;//fallback to full type name
}
}
- if (ItemTemplates.ContainsKey (itempKey))
+ if (!string.IsNullOrEmpty (itempKey) && ItemTemplates.ContainsKey (itempKey))
iTemp = ItemTemplates [itempKey];
else {
if (_dataTest == "TypeOf") {//item template selection on full type name
/// <summary>
/// The base class for all the graphic tree elements.
/// </summary>
- public class Widget : ILayoutable, IValueChange, IDisposable
+ public class Widget : ILayoutable, ICommandHost, IDisposable
{
internal ReaderWriterLockSlim parentRWLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
#if DEBUG_LOG
}
return di;
}
- public string DesignName {
- get { return GetType ().Name + design_id; }
- }
+ public string DesignName => LogName + design_id;
#endif
#region IDisposable implementation
public virtual string Name {
get {
#if DEBUG_LOG
- return string.IsNullOrEmpty(name) ? this.GetType().Name + GraphicObjects.IndexOf(this).ToString () : name;
+ return string.IsNullOrEmpty(name) ? this.LogName + GraphicObjects.IndexOf(this).ToString () : name;
#else
return name;
#endif
/// </summary>
[DesignCategory ("Behaviour")]
[DefaultValue (DeviceEventType.All)]
- public virtual DeviceEventType BubbleMouseEvent {
+ public virtual DeviceEventType BubbleEvents {
get => bubbledEvents;
set {
if (bubbledEvents == value)
ctx.Fill ();
ctx.Operator = Operator.Over;
}
-
ctx.SetSource (bmp, rb.X, rb.Y);
ctx.Paint ();
#if VKVG
public virtual void onKeyDown(object sender, KeyEventArgs e){
if (KeyDown != null)
KeyDown.Invoke (this, e);
- else if (!e.Handled && BubbleMouseEvent.HasFlag (DeviceEventType.KeyDown))
+ else if (!e.Handled && BubbleEvents.HasFlag (DeviceEventType.KeyDown))
FocusParent?.onKeyDown (sender, e);
}
public virtual void onKeyUp(object sender, KeyEventArgs e){
if (KeyUp != null)
KeyUp.Invoke (this, e);
- else if (!e.Handled && BubbleMouseEvent.HasFlag (DeviceEventType.KeyUp))
+ else if (!e.Handled && BubbleEvents.HasFlag (DeviceEventType.KeyUp))
FocusParent?.onKeyUp (sender, e);
}
public virtual void onKeyPress(object sender, KeyPressEventArgs e){
if (KeyPress != null)
KeyPress.Invoke (this, e);
- else if (!e.Handled && BubbleMouseEvent.HasFlag (DeviceEventType.KeyPress))
+ else if (!e.Handled && BubbleEvents.HasFlag (DeviceEventType.KeyPress))
FocusParent?.onKeyPress (sender, e);
}
#endregion
if (MouseMove != null)
MouseMove.Invoke (this, e);
- else if (!e.Handled && BubbleMouseEvent.HasFlag (DeviceEventType.MouseMove))
+ else if (!e.Handled && BubbleEvents.HasFlag (DeviceEventType.MouseMove))
FocusParent?.onMouseMove (sender, e);
}
/// <summary>
/// <param name="sender">Sender of the event</param>
/// <param name="e">mouse button pressed event arguments</param>
public virtual void onMouseDown(object sender, MouseButtonEventArgs e){
- if (Focusable) {
+ DbgLogger.AddEvent (DbgEvtType.MouseDown, this);
+ if (Focusable && !HasFocus) {
IFace.FocusedWidget = this;
e.Handled = true;
}
e.Handled = true;
}
- if (MouseDown != null)
- MouseDown?.Invoke (this, e);
- else if (!e.Handled && BubbleMouseEvent.HasFlag (DeviceEventType.ButtonDown))
+ MouseDown?.Invoke (this, e);
+ if (!e.Handled && BubbleEvents.HasFlag (DeviceEventType.ButtonDown))
FocusParent?.onMouseDown (sender, e);
}
/// <summary>
/// <param name="sender">Sender of the event</param>
/// <param name="e">mouse button release event arguments</param>
public virtual void onMouseUp(object sender, MouseButtonEventArgs e){
-
+ DbgLogger.AddEvent (DbgEvtType.WidgetMouseUp, this);
if (MouseUp != null)
MouseUp.Invoke (this, e);
- else if (!e.Handled && BubbleMouseEvent.HasFlag (DeviceEventType.ButtonUp))
+ if (!e.Handled && BubbleEvents.HasFlag (DeviceEventType.ButtonUp))
FocusParent?.onMouseUp (sender, e);
}
/// <summary>
/// <param name="sender">The Sender of the event</param>
/// <param name="e">event arguments</param>
public virtual void onMouseClick(object sender, MouseButtonEventArgs e){
+ DbgLogger.AddEvent (DbgEvtType.WidgetMouseClick, this);
if (MouseClick != null)
MouseClick.Invoke (this, e);
- else if (!e.Handled && BubbleMouseEvent.HasFlag (DeviceEventType.MouseClick))
+ if (!e.Handled && BubbleEvents.HasFlag (DeviceEventType.MouseClick))
FocusParent?.onMouseClick (sender, e);
}
/// <summary>
/// <param name="sender">The Sender of the event</param>
/// <param name="e">event arguments</param>
public virtual void onMouseDoubleClick(object sender, MouseButtonEventArgs e){
+ DbgLogger.AddEvent (DbgEvtType.WidgetMouseDblClick, this);
if (MouseDoubleClick != null)
MouseDoubleClick.Invoke (this, e);
- else if (!e.Handled && BubbleMouseEvent.HasFlag (DeviceEventType.MouseClick))
+ if (!e.Handled && BubbleEvents.HasFlag (DeviceEventType.MouseClick))
FocusParent?.onMouseDoubleClick (sender, e);
}
public virtual void onMouseWheel(object sender, MouseWheelEventArgs e){
+ DbgLogger.AddEvent (DbgEvtType.WidgetMouseWheel, this);
if (MouseWheelChanged != null)
MouseWheelChanged.Invoke (this, e);
- else if (!e.Handled && BubbleMouseEvent.HasFlag (DeviceEventType.MouseWheel))
+ if (!e.Handled && BubbleEvents.HasFlag (DeviceEventType.MouseWheel))
FocusParent?.onMouseWheel (sender, e);
}
+ protected bool mouseIsEntered;
public virtual void onMouseEnter(object sender, MouseMoveEventArgs e)
{
+ DbgLogger.AddEvent (DbgEvtType.MouseEnter, this);
+ mouseIsEntered = true;
IFace.MouseCursor = MouseCursor;
/*if (IFace.DragAndDropOperation != null) {
Widget g = this;
}
public virtual void onMouseLeave(object sender, MouseMoveEventArgs e)
{
+ DbgLogger.AddEvent (DbgEvtType.MouseLeave, this);
+ mouseIsEntered = false;
MouseLeave.Raise (this, e);
}
w = w.FocusParent;
}
this.onMouseLeave (this, e);
- IFace.HoverWidget = null;
- IFace.OnMouseMove (IFace.MousePosition.X, IFace.MousePosition.Y);
+ IFace.HoverWidget = FocusParent;
+ //IFace.OnMouseMove (IFace.MousePosition.X, IFace.MousePosition.Y);
}
}
return (Char)Peek();
}
void SkipWhiteSpaceAndLineBreak (){
- while (!EndOfStream){
+ while (!EndOfStream){
if (!PeekChar ().IsWhiteSpaceOrNewLine ())
break;
if (ReadChar () == '\n') {
}else
throw new ParserException (line, column, $"Unexpected char '{PeekChar ()}'", resId);
break;
- case ',':
- ReadChar ();
- if (curState != States.classNames || token.Length == 0)
- throw new ParserException (line, column, "Unexpected char ','", resId);
- targetsClasses.Add (token.ToString());
- token.Clear();
- curState = States.classNames;
- break;
- case '{':
- ReadChar ();
- if (curState != States.classNames || token.Length == 0)
- throw new ParserException (line, column, "Unexpected char '{'", resId);
- targetsClasses.Add (token.ToString());
- token.Clear();
- curState = States.members;
- break;
- case '}':
- ReadChar ();
- if (curState != States.members)
- throw new ParserException (line, column, "Unexpected char '}'", resId);
- curState = States.classNames;
- targetsClasses.Clear ();
- break;
- case '=':
- ReadChar ();
- if (!(curState == States.members || curState == States.classNames) || token.Length == 0)
- throw new ParserException (line, column, "Unexpected char '='", resId);
- currentProperty = token.ToString ();
- token.Clear ();
- curState = States.value;
- break;
- case '"':
- if (curState != States.value)
- throw new ParserException (line, column, "Unexpected char '\"'", resId);
- ReadChar ();
+ case ',':
+ ReadChar ();
+ if (curState != States.classNames || token.Length == 0)
+ throw new ParserException (line, column, "Unexpected char ','", resId);
+ targetsClasses.Add (token.ToString());
+ token.Clear();
+ curState = States.classNames;
+ break;
+ case '{':
+ ReadChar ();
+ if (curState != States.classNames || token.Length == 0)
+ throw new ParserException (line, column, "Unexpected char '{'", resId);
+ targetsClasses.Add (token.ToString());
+ token.Clear();
+ curState = States.members;
+ break;
+ case '}':
+ ReadChar ();
+ if (curState != States.members)
+ throw new ParserException (line, column, "Unexpected char '}'", resId);
+ curState = States.classNames;
+ targetsClasses.Clear ();
+ break;
+ case '=':
+ ReadChar ();
+ if (!(curState == States.members || curState == States.classNames) || token.Length == 0)
+ throw new ParserException (line, column, "Unexpected char '='", resId);
+ currentProperty = token.ToString ();
+ token.Clear ();
+ curState = States.value;
+ break;
+ case '"':
+ if (curState != States.value)
+ throw new ParserException (line, column, "Unexpected char '\"'", resId);
+ ReadChar ();
- while (!EndOfStream) {
- char c = ReadChar ();
- if (c == '$') {
- if (PeekChar () == '{') {
- ReadChar ();
- //constant replacement
- while (!EndOfStream) {
- c = ReadChar ();
- if (c == '}')
- break;
- constantId.Append (c);
+ while (!EndOfStream) {
+ char c = ReadChar ();
+ if (c == '$') {
+ if (PeekChar () == '{') {
+ ReadChar ();
+ //constant replacement
+ while (!EndOfStream) {
+ c = ReadChar ();
+ if (c == '}')
+ break;
+ constantId.Append (c);
+ }
+ if (constantId.Length == 0)
+ throw new ParserException (line, column, "Empty constant id in styling", resId);
+ string cst = constantId.ToString ();
+ constantId.Clear ();
+ if (!StylingConstants.ContainsKey (cst))
+ throw new ParserException (line, column, $"Constant id not found in styling ({cst})", resId);
+ token.Append (StylingConstants[cst]);
+ continue;
}
- if (constantId.Length == 0)
- throw new ParserException (line, column, "Empty constant id in styling", resId);
- string cst = constantId.ToString ();
- constantId.Clear ();
- if (!StylingConstants.ContainsKey (cst))
- throw new ParserException (line, column, $"Constant id not found in styling ({cst})", resId);
- token.Append (StylingConstants[cst]);
- continue;
+ } else if (c == '\"') {
+ curState = States.endOfStatement;
+ break;
}
- } else if (c == '\"') {
- curState = States.endOfStatement;
- break;
+ token.Append (c);
}
- token.Append (c);
- }
- break;
- case ';':
- if (curState != States.endOfStatement)
- throw new ParserException (line, column, "Unexpected end of statement", resId);
- ReadChar ();
- if (targetsClasses.Count == 0) {
- //only first style constants kept.
- if (!StylingConstants.ContainsKey (currentProperty))
- StylingConstants[currentProperty] = token.ToString ();
- curState = States.classNames;
- } else {
- foreach (string tc in targetsClasses) {
- if (!Styling.ContainsKey (tc))
- Styling [tc] = new Style ();
- if (!Styling[tc].ContainsKey (currentProperty)) {
- Styling[tc][currentProperty] = token.ToString ();
-#if DESIGN_MODE
- Styling [tc].Locations[currentProperty] = new FileLocation(resId, line, column - token.Length - 1, token.Length);
-#endif
+ break;
+ case ';':
+ if (curState != States.endOfStatement)
+ throw new ParserException (line, column, "Unexpected end of statement", resId);
+ ReadChar ();
+ if (targetsClasses.Count == 0) {
+ //only first style constants kept.
+ if (!StylingConstants.ContainsKey (currentProperty))
+ StylingConstants[currentProperty] = token.ToString ();
+ curState = States.classNames;
+ } else {
+ foreach (string tc in targetsClasses) {
+ if (!Styling.ContainsKey (tc))
+ Styling [tc] = new Style ();
+ if (!Styling[tc].ContainsKey (currentProperty)) {
+ Styling[tc][currentProperty] = token.ToString ();
+ #if DESIGN_MODE
+ Styling [tc].Locations[currentProperty] = new FileLocation(resId, line, column - token.Length - 1, token.Length);
+ #endif
+ }
}
+ curState = States.members;
}
- curState = States.members;
- }
- token.Clear ();
- currentProperty = null;
- break;
- default:
- if (curState == States.value)
- throw new ParserException (line, column, "expecting value enclosed in '\"'", resId);
- if (curState == States.endOfStatement)
- throw new ParserException (line, column, "expecting end of statement", resId);
+ token.Clear ();
+ currentProperty = null;
+ break;
+ default:
+ if (curState == States.value)
+ throw new ParserException (line, column, "expecting value enclosed in '\"'", resId);
+ if (curState == States.endOfStatement)
+ throw new ParserException (line, column, "expecting end of statement", resId);
- if (nextCharIsValidCharStartName) {
- token.Append (ReadChar ());
- while (nextCharIsValidCharName)
+ if (nextCharIsValidCharStartName) {
token.Append (ReadChar ());
+ while (nextCharIsValidCharName)
+ token.Append (ReadChar ());
+ }
+ break;
}
- break;
- }
}
}
<!-- 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>
<a href="http://www.amitmerchant.com/electron-markdownify">
<img src="https://github.com/jpbruyere/Crow/blob/master/Images/crow.png" alt="C.R.O.W." width="140">
</a>
- <br>
+ <br>
<br>
C# Rapid Open Widgets
- <br>
+ <br>
<p align="center">
<a href="https://www.nuget.org/packages/Crow"><img src="https://buildstats.info/nuget/Crow"></a>
<a href="https://travis-ci.org/jpbruyere/Crow">
</a>
<a href="https://gitter.im/CSharpRapidOpenWidgets?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge">
<img src="https://badges.gitter.im/CSharpRapidOpenWidgets.svg">
- </a>
+ </a>
</p>
</h1>
namespace HelloWorld
{
class Program : SampleBase {
+ public CommandGroup CMDTest = new CommandGroup (
+ new ActionCommand("Action", ()=> Console.WriteLine ("Action executed"))
+ );
static void Main (string[] args) {
+ DbgLogger.IncludedEvents.AddRange ( new DbgEvtType[] {
+ DbgEvtType.MouseEnter,
+ DbgEvtType.MouseLeave,
+ DbgEvtType.WidgetMouseDown,
+ DbgEvtType.WidgetMouseUp,
+ DbgEvtType.WidgetMouseClick,
+ DbgEvtType.HoverWidget
+ });
using (Interface app = new Program ()) {
app.Initialized += (sender, e) => (sender as Interface).Load ("#HelloWorld.helloworld.crow").DataSource = sender;
app.Run ();
<?xml version="1.0"?>
-<Label Text="Hello World"/>
\ No newline at end of file
+<VerticalStack Margin="50" Spacing="20">
+ <HorizontalStack Height="Fit">
+ <Label Text="Hover:" Width="50" Foreground="Grey"/>
+ <Label Text="{HoverWidget}" Font="mono, 8"/>
+ </HorizontalStack>
+ <HorizontalStack Height="Fit">
+ <Label Text="Focus:" Width="50" Foreground="Grey"/>
+ <Label Text="{FocusedWidget}" Font="mono, 8"/>
+ </HorizontalStack>
+ <HorizontalStack Height="Fit">
+ <Label Text="Active:" Width="50" Foreground="Grey"/>
+ <Label Text="{ActiveWidget}" Font="mono, 8"/>
+ </HorizontalStack>
+ <Border Height="Fit" Margin="2" Background="Blue" ContextCommands="{CMDTest}" Focusable="true"
+ MouseEnter="{Background=Red}"
+ MouseLeave="{Background=Blue}">
+ <Label Margin="5" Text="Hello World" />
+ </Border>
+ <Border Height="Fit" Margin="2" Background="Blue" ContextCommands="{CMDTest}" Focusable="true"
+ MouseEnter="{Background=Red}"
+ MouseLeave="{Background=Blue}">
+ <Label Margin="5" Text="Hello World" />
+ </Border>
+ <Border Height="Fit" Margin="2" Background="Blue" ContextCommands="{CMDTest}" Focusable="true"
+ MouseEnter="{Background=Red}"
+ MouseLeave="{Background=Blue}">
+ <Label Margin="5" Text="Hello World" />
+ </Border>
+ <Border Height="Fit" Margin="2" Background="Blue" ContextCommands="{CMDTest}" Focusable="true"
+ MouseEnter="{Background=Red}"
+ MouseLeave="{Background=Blue}">
+ <Label Margin="5" Text="Hello World" />
+ </Border>
+ <Border Height="Fit" Margin="2" Background="Blue" ContextCommands="{CMDTest}" Focusable="true"
+ MouseEnter="{Background=Red}"
+ MouseLeave="{Background=Blue}">
+ <Label Margin="5" Text="Hello World" />
+ </Border>
+</VerticalStack>
{
class Showcase : SampleBaseForEditor
{
+ DbgEvtType[] logEvts = {
+ DbgEvtType.MouseEnter,
+ DbgEvtType.MouseLeave,
+ DbgEvtType.WidgetMouseDown,
+ DbgEvtType.WidgetMouseUp,
+ DbgEvtType.WidgetMouseClick,
+ };
static void Main ()
{
initDebugLog ();
return true;
case Key.F6:
if (DebugLogRecording) {
- DbgLogger.IncludeEvents = DbgEvtType.None;
- DbgLogger.DiscardEvents = DbgEvtType.All;
+ DbgLogger.IncludedEvents.Clear();
if (DebugLogToFile && !string.IsNullOrEmpty(DebugLogFilePath))
DbgLogger.Save (this, DebugLogFilePath);
DebugLogRecording = false;
} else {
DbgLogger.Reset ();
- DbgLogger.IncludeEvents = RecordedEvents;
- DbgLogger.DiscardEvents = DiscardedEvents;
+ DbgLogger.IncludedEvents = new List<DbgEvtType> (logEvts);
DebugLogRecording = true;
}
return true;
<?xml version="1.0"?>
-<Border Background="{./Background}" MinimumSize="50,20" Name="Content"
+<Border Background="{./Background}" MinimumSize="50,20" Name="Content" Width="Stretched"
Foreground="Transparent" CornerRadius="{../CornerRadius}" BorderWidth="1"
MouseEnter="{Foreground=vgradient|0:White|0.2:Grey|0.9:Grey|1:Black};{caption.Foreground=White}"
MouseLeave="{Foreground=Transparent};{caption.Foreground=LightGrey}"
<ListItem ContextCommands="{GetCommands}"
Selected="{/exp.Background=${ControlHighlight}}"
Unselected="{/exp.Background=Transparent}">
- <Expandable Name="exp" Caption="{Name}" MouseDoubleClick="/onClickForExpand" BubbleMouseEvent="MouseWheel|Keyboard|ButtonDown">
+ <Expandable Name="exp" Caption="{Name}" MouseDoubleClick="/onClickForExpand" BubbleEvents="MouseWheel|Keyboard|MouseClick|ButtonDown">
<Template>
<VerticalStack>
<Border CornerRadius="2" Margin="0" Height="Fit" MouseDoubleClick="./onClickForExpand"
<Label Text="{./Caption}"/>
</HorizontalStack>
</Border>
- <Container Name="Content" Visible="false"/>
+ <Container Name="Content" Visible="false" BubbleEvents="MouseWheel|Keyboard"/>
</VerticalStack>
</Template>
<HorizontalStack Height="Fit">
IEnumerable<MemberInfo> getAllCrowTypeMembers (string crowTypeName) {
- Type crowType = IML.Instantiator.GetWidgetTypeFromName (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 = IML.Instantiator.GetWidgetTypeFromName (crowTypeName);
+ Type crowType = IFace.GetWidgetTypeFromName (crowTypeName);
return crowType.GetMember (memberName, BindingFlags.Public | BindingFlags.Instance).FirstOrDefault ();
}
new ActionCommand("Action A", () => MessageBox.ShowModal(this, MessageBox.Type.Information, "context menu A clicked"))
);
}
+ DeviceEventType deviceEventTypeEnum;
+ public DeviceEventType DeviceEventTypeEnum {
+ get => deviceEventTypeEnum;
+ set {
+ if (deviceEventTypeEnum == value)
+ return;
+ deviceEventTypeEnum = value;
+ NotifyValueChanged ("DeviceEventTypeEnum", deviceEventTypeEnum);
+ }
+
+ }
public int intValue = 500;
VerticalAlignment currentVAlign;
}
public bool DebugLoggingEnabled => DbgLogger.IsEnabled;
- public DbgEvtType RecordedEvents {
+ /*public DbgEvtType RecordedEvents {
get => Configuration.Global.Get<DbgEvtType> (nameof (RecordedEvents));
set {
if (RecordedEvents == value)
DbgLogger.DiscardEvents = DiscardedEvents;
NotifyValueChanged(DiscardedEvents);
}
- }
+ }*/
public bool DebugLogRecording {
get => debugLogRecording;
set {
}
protected static void initDebugLog () {
- DbgLogger.IncludeEvents = DbgEvtType.None;
- DbgLogger.DiscardEvents = DbgEvtType.All;
- //DbgLogger.DiscardEvents = DbgEvtType.All;
DbgLogger.ConsoleOutput = !Configuration.Global.Get<bool> (nameof (DebugLogToFile));
}
--- /dev/null
+<VerticalStack Fit="true" Background="Onyx" Margin="0">
+ <Button Caption='Ok' Background='MediumSeaGreen' Width="Stretched" MouseClick="{Background=Red}">
+ <Template>
+ <Border Style="ButtonBorder" Background="{./Background}" Name="Content" CornerRadius="{../CornerRadius}" Width="Stretched">
+ <Label Font="{./Font}" Name="caption" Margin="${ButtonCaptionMargin}" Foreground="{./Foreground}" Text="{./Caption}"/>
+ </Border>
+ </Template>
+ </Button>
+</VerticalStack>
\ No newline at end of file
--- /dev/null
+<VerticalStack>
+ <Label Text="{DeviceEventTypeEnum}"/>
+ <EnumSelector Caption="Device Events:" EnumValue="{²DeviceEventTypeEnum}" ItemStyle="CheckBox3" Width="Fit" Background="Jet">
+ <Template>
+ <Border Style="ControlBorder" Background="{./Background}" CornerRadius="{./CornerRadius}">
+ <HorizontalStack>
+ <Label Text="{./Caption}"/>
+ <Popper Caption="{./EnumValue}" PopDirection="BottomLeft" >
+ <Template>
+ <Label Style="ControlCaption" Text="{./Caption}" Foreground="{./Foreground}" MinimumSize="80,1" TextAlignment="Center"/>
+ </Template>
+ <VerticalStack Fit="true" Name="Content" Background="Onyx" Width="{../PopWidth}" Margin="5"/>
+ </Popper>
+ </HorizontalStack>
+ </Border>
+ </Template>
+ </EnumSelector>
+</VerticalStack>
--- /dev/null
+<VerticalStack>
+ <HorizontalStack Height="Fit">
+ <Label Text="Hover:" Width="50" Foreground="Grey"/>
+ <Label Text="{HoverWidget}" Font="mono, 8"/>
+ </HorizontalStack>
+ <HorizontalStack Height="Fit">
+ <Label Text="Focus:" Width="50" Foreground="Grey"/>
+ <Label Text="{FocusedWidget}" Font="mono, 8"/>
+ </HorizontalStack>
+ <HorizontalStack Height="Fit">
+ <Label Text="Active:" Width="50" Foreground="Grey"/>
+ <Label Text="{ActiveWidget}" Font="mono, 8"/>
+ </HorizontalStack>
+ <Container>
+ <FileDialog Focusable="true" Resizable="true"/>
+ </Container>
+</VerticalStack>
\ No newline at end of file