EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Crow", "Crow\Crow.csproj", "{C2980F9B-4798-4C05-99E2-E174810F7C7B}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CrowDbgShared", "CrowDbgShared\CrowDbgShared.csproj", "{91F1CE07-EECE-4F1D-A3EE-7239B563654A}"
-EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{B2C7855A-2878-47FD-AD32-9A83DB4AB8C6}"
ProjectSection(SolutionItems) = preProject
Samples\Directory.Build.props = Samples\Directory.Build.props
{56329D48-D382-4850-93DE-59C453894E8A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{56329D48-D382-4850-93DE-59C453894E8A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{56329D48-D382-4850-93DE-59C453894E8A}.Release|Any CPU.Build.0 = Release|Any CPU
- {91F1CE07-EECE-4F1D-A3EE-7239B563654A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {91F1CE07-EECE-4F1D-A3EE-7239B563654A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0CC6DFAB-2E4A-4786-976C-89053D5EA6A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0CC6DFAB-2E4A-4786-976C-89053D5EA6A2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0CC6DFAB-2E4A-4786-976C-89053D5EA6A2}.Release|Any CPU.ActiveCfg = Release|Any CPU
<PackageReference Include="System.Reflection.Emit.Lightweight" Version="4.6.0" />
</ItemGroup>
<ItemGroup>
- <PackageReference Include="FastEnum" Version="1.5.3" />
+ <!--<PackageReference Include="FastEnum" Version="1.5.3" />-->
+ <PackageReference Include="Enums.NET" Version="4.0.0" />
<PackageReference Include="glfw-sharp" Version="$(GlfwSharpVersion)" />
</ItemGroup>
//MinimumSize = "200,120";
AlwaysOnTop = "true";
Resizable = "false";
+ AllowedStates = "Normal";
}
Slider {
Foreground = "Grey";
Foreground="Transparent";
Height="12";
Width="12";
- MouseEnter="{Foreground=White}";
+ MouseEnter="{Foreground=Grey}";
MouseLeave="{Foreground=Transparent}";
+ MouseDown="{Background=${ControlHighlight}}";
+ MouseUp="{Background=Transparent}";
}
ToolWindow {
Caption = "Window";
Template = "#Crow.ToolWindow.template";
+ AllowedStates = "Normal";
Focusable = "true";
MinimumSize="50,50";
Width = "150";
AllowDrop = "true";
AllowedDropTypes = "Crow.DockWindow";
}
-DockWindow {
+DockWindow {
+ AllowedStates = "Normal";
Focusable = "true";
AllowDrag = "true";
AllowDrop="true";
Background = "${ControlBackground}";
CornerRadius = "${ControlCornerRadius}";
Margin="0";
- BubbleMouseEvent="false";
+ BubbleMouseEvent="MouseWheel|Keyboard";
}
-TemplatedControl, GenericStack {
- CacheEnabled="true";
-}
\ No newline at end of file
+
+//TemplatedControl, GenericStack {
+// CacheEnabled="true";
+//}
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generated by IcoMoon.io -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16">
+<path fill="#dddddd" d="M11 6.5v-5.5h1v-1h-8v1h1v5.5c0 0-2 1.5-2 3.5 0 0.5 1.9 0.7 4 0.7v2.2c0 0.7 0.2 1.4 0.5 2.1l0.5 1 0.5-1c0.3-0.6 0.5-1.3 0.5-2.1v-2.2c2.1 0 4-0.3 4-0.7 0-2-2-3.5-2-3.5zM7 6.6c0 0-0.5 0.3-1.6 1.4-1 1-1.5 1.9-1.5 1.9s0.1-1 0.8-1.9c0.9-1.1 1.3-1.4 1.3-1.4v-5.6h1v5.6z"></path>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generated by IcoMoon.io -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16">
+ <path
+ fill="#dddddd"
+ d="M 9.8735488,10.133961 13.560108,6.0523834 14.302213,6.7226674 14.972497,5.9805624 9.0356558,0.61829343 8.3653726,1.3603984 9.1074778,2.0306824 5.420918,6.1122604 c 0,0 -2.4896355,-0.22741 -3.8302027,1.2568 -0.3351418,0.371053 0.9408011,1.793013 2.4992218,3.2006076 l -1.4746239,1.632631 c -0.4691985,0.519474 -0.789976,1.173004 -1.036543,1.893563 l -0.299231,1.077247 1.0413361,-0.406964 C 2.945677,14.521967 3.5632965,14.13655 4.0995234,13.542866 l 1.4746238,-1.632631 c 1.5584207,1.407596 3.1695056,2.458503 3.4376186,2.161661 1.3405672,-1.48421 0.861783,-3.937935 0.861783,-3.937935 z M 6.8380997,7.5270374 c 0,0 -0.5721376,-0.11251 -2.1257651,-0.03351 -1.4123886,0.07182 -2.3866964,0.404575 -2.3866964,0.404575 0,0 0.7444941,-0.675077 1.8672229,-0.873773 1.4052065,-0.21306 1.9031336,-0.167578 1.9031336,-0.167578 l 3.7535881,-4.155786 0.7421052,0.670284 z"
+ id="path2" />
+</svg>
<ListItem
Selected="{/exp.Background=${ControlHighlight}}"
Unselected="{/exp.Background=Transparent}">
- <Expandable Name="exp" Caption="{Name}" MouseDoubleClick="/onClickForExpand" BubbleMouseEvent="true">
+ <Expandable Name="exp" Caption="{Name}" MouseDoubleClick="/onClickForExpand" >
<Template>
<VerticalStack>
<Border CornerRadius="2" Margin="0" Height="Fit" MouseDoubleClick="./onClickForExpand"
<HorizontalStack Visible="{./IsDocked}" Height="Fit" Margin="1" Background="vgradient|0:0.3,0.5,0.8,0.9|1:0.1,0.1,0.1,0.9">
<Label Text="{./CurDir}" TextAlignment="Left" Width="Stretched"
Foreground="White" />
- <Border CornerRadius="6" BorderWidth="1" Foreground="Transparent" Height="10" Width="10"
- MouseEnter="{Foreground=White}" MouseLeave="{Foreground=Transparent}">
- <Image Focusable="true" Name="Image" Margin="0" Path="#Crow.Icons.exit2.svg"
- MouseClick="./onQuitPress"/>
- </Border>
+ <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>
<HorizontalStack Background="vgradient|0:0.5,0.6,0.5,0.5|1:0.2,0.3,0.3,0.7"
Name="hs" Margin="0" Spacing="0" Height="Fit" Visible="{./IsFloating}">
<Widget Width="5"/>
<Image Margin="1" Width="10" Height="10" Path="{./Icon}"/>
<Label Width="Stretched" Foreground="White" Margin="1" TextAlignment="Left" Text="{./CurDir}" />
- <Border CornerRadius="6" BorderWidth="1" Foreground="Transparent" Height="10" Width="10"
- MouseEnter="{Foreground=White}" MouseLeave="{Foreground=Transparent}">
- <Image Focusable="true" Name="Image" Margin="0" Path="#Crow.Icons.exit2.svg"
- MouseClick="./onQuitPress"/>
- </Border>
- <Widget Width="5"/>
+ <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>
<Container Name="Content" MinimumSize="50,50"/>
</VerticalStack>
<?xml version="1.0"?>
<ListItem>
<Popper Font="{./Font}" Caption="{./Caption}" Background="{./Background}" PopDirection="{./PopDirection}"
- Foreground = "{./Foreground}" BubbleMouseEvent="true"
+ Foreground = "{./Foreground}" BubbleMouseEvent="All"
IsPopped="{²./IsOpened}" PopWidth="{./PopWidth}" PopHeight="{./PopHeight}">
<Template>
<Widget Width="5" />
<Image Margin="1" Width="12" Height="12" Path="{./Icon}"/>
<Label Name="MoveHandle" Width="Stretched" Foreground="${WindowTitleBarForeground" Margin="2" TextAlignment="Center" Text="{./Caption}" />
- <Border CornerRadius="3" BorderWidth="1" Foreground="Transparent" Height="12" Width="12"
- MouseEnter="{Foreground=White}" MouseLeave="{Foreground=Transparent}">
- <Image Focusable="true" Name="Image" Path="#Crow.Icons.exit2.svg"
- MouseClick="./onQuitPress"/>
- </Border>
+ <ListBox Data="{./Commands}" Fit="true">
+ <Template>
+ <HorizontalStack Name="ItemsContainer" />
+ </Template>
+ <ItemTemplate Path="#Crow.WindowButton.template"/>
+ </ListBox>
<Widget Width="5" />
</HorizontalStack>
<HorizontalStack Margin="5" >
<Widget Width="5"/>
<Image Margin="1" Width="12" Height="12" Path="{./Icon}"/>
<Label Width="Stretched" Foreground="{./TitleBarForeground}" Margin="1" TextAlignment="Center" Text="{./Caption}" />
- <Border CornerRadius="6" 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="./onQuitPress"/>
- </Border>
+ <ListBox Data="{./Commands}" Fit="true">
+ <Template>
+ <HorizontalStack Name="ItemsContainer" />
+ </Template>
+ <ItemTemplate Path="#Crow.WindowButton.template"/>
+ </ListBox>
<Widget Width="5"/>
</HorizontalStack>
<Container Name="Content" MinimumSize="50,50"/>
<Widget Width="5"/>
<Image Margin="1" Width="12" Height="12" Path="{./Icon}"/>
<Label Name="MoveHandle" Width="Stretched" Foreground="${WindowTitleBarForeground" Margin="2" TextAlignment="Center" Text="{./Caption}" />
- <Border Visible="{./ShowMinimize}" Style="WindowIconBorder">
- <Image Focusable="true" Path="#Crow.Icons.minimize.svg"
- MouseClick="./onMinimized"/>
- </Border>
- <Border Visible="{./ShowNormal}" Style="WindowIconBorder">
- <Image Focusable="true" Path="#Crow.Icons.normalize.svg"
- MouseClick="./onUnmaximized"/>
- </Border>
- <Border Visible="{./ShowMaximize}" Style="WindowIconBorder">
- <Image Focusable="true" Path="#Crow.Icons.maximize.svg"
- MouseClick="./onMaximized"/>
- </Border>
- <Border BorderWidth="1" Style="WindowIconBorder">
- <Image Focusable="true" Path="#Crow.Icons.exit2.svg"
- MouseClick="./onQuitPress"/>
- </Border>
- <Widget Width="5"/>
+ <ListBox Data="{./Commands}" Fit="true">
+ <Template>
+ <HorizontalStack Name="ItemsContainer" />
+ </Template>
+ <ItemTemplate Path="#Crow.WindowButton.template"/>
+ </ListBox>
</HorizontalStack>
<Container Name="Content" MinimumSize="0,0" />
</VerticalStack>
--- /dev/null
+<?xml version="1.0"?>
+<Button Command="{}" MinimumSize="0,0" >
+ <Template>
+ <Border Style="WindowIconBorder" IsVisible="{./IsEnabled}">
+ <Image Path="{./Icon}" Tooltip="{./Caption}"/>
+ </Border>
+ </Template>
+</Button>
+
using System;
using System.Collections.Generic;
using System.Linq;
-using FastEnumUtility;
+//using FastEnumUtility;
namespace Crow
{
=> value.GetHashCode ();
public override string ToString()
- => FastEnum.IsDefined<Colors> (value) ? FastEnum.GetName((Colors)value) : HtmlCode;
+ => EnumsNET.Enums.IsValid<Colors> ((Colors)value) ? EnumsNET.Enums.GetName((Colors)value) : HtmlCode;
public static Color FromIml (string iml)
{
new Color (0xff + (UInt32.Parse (s.AsSpan ().Slice (1), System.Globalization.NumberStyles.HexNumber)<<8))
: new Color (UInt32.Parse (s.AsSpan().Slice (1), System.Globalization.NumberStyles.HexNumber)) :
char.IsDigit(s[0]) ? FromIml (s) :
- FastEnum.TryParse<Colors> (s, out Colors cc) ? new Color(cc) :
+ EnumsNET.Enums.TryParse<Colors> (s, out Colors cc) ? new Color(cc) :
throw new Exception ("Unknown color name: " + s);
public static Color FromHSV (double _h, double _v = 0xff, double _s = 0xff, double _alpha = 0xff) {
}
startSavingThread ();
}
+ /// <summary>
+ /// Create readonly configuration
+ /// </summary>
+ /// <param name="defaultConf"></param>
+ public Configuration (Stream defaultConf = null) {
+ load (defaultConf);
+ }
static Configuration ()
{
return !items.ContainsKey (key) ? default(T) : items [key].GetValue<T> ();
}
/// <summary>
+ /// retrive the value of the configuration key given in parameter
+ /// </summary>
+ /// <param name="key">option name</param>
+ public T Get<T>(string key, T defaultValue)
+ {
+ return !items.ContainsKey (key) ? defaultValue : items [key].GetValue<T> ();
+ }
+ /// <summary>
/// store the value of the configuration key given in parameter
/// </summary>
/// <param name="key">option name</param>
public int threadId;
public DbgEvtType type;
public DbgEvtType Category => type & DbgEvtType.All;
+ public string Message;
public DbgEvent parentEvent;
public bool HasChildEvents => Events != null && Events.Count > 0;
public override long Duration => end - begin;
public double EndMS => Math.Round ((double)end / Stopwatch.Frequency, 6);
public virtual bool IsWidgetEvent => false;
public virtual bool IsLayoutEvent => false;
+ public bool HasMessage => !string.IsNullOrEmpty(Message);
public void AddEvent (DbgEvent evt)
{
}
public DbgEvent () { }
- public DbgEvent (long timeStamp, DbgEvtType evt)
+ public DbgEvent (long timeStamp, DbgEvtType evt, string message = null)
{
type = evt;
begin = timeStamp;
end = timeStamp;
threadId = Thread.CurrentThread.ManagedThreadId;
+ Message = message;
}
public static DbgEvent Parse (string str)
{
if (str == null)
return null;
- string [] tmp = str.Trim ().Split (';');
+ 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))
end = long.Parse (tmp [1]),
threadId = int.Parse (tmp [2]),
type = evtType,
- InstanceIndex = int.Parse (tmp [4]),
- layouting = (LayoutingType)Enum.Parse (typeof (LayoutingType), tmp [5]),
+ Message = tmp[4],
+ InstanceIndex = int.Parse (tmp [5]),
+ layouting = (LayoutingType)Enum.Parse (typeof (LayoutingType), tmp [6]),
result = evtType == DbgEvtType.GOProcessLayouting ?
- (LayoutingQueueItem.Result)Enum.Parse (typeof (LayoutingQueueItem.Result), tmp [6])
+ (LayoutingQueueItem.Result)Enum.Parse (typeof (LayoutingQueueItem.Result), tmp [7])
: LayoutingQueueItem.Result.Unknown,
- OldSlot = Rectangle.Parse (tmp [7]),
- NewSlot = Rectangle.Parse (tmp [8]),
+ OldSlot = Rectangle.Parse (tmp [8]),
+ NewSlot = Rectangle.Parse (tmp [9]),
};
- return (tmp.Length < 5) ?
+ return (tmp.Length < 6) ?
new DbgWidgetEvent () {
begin = long.Parse (tmp [0]),
end = long.Parse (tmp [1]),
threadId = int.Parse (tmp [2]),
type = evtType,
+ Message = tmp[4],
InstanceIndex = -1,
} : new DbgWidgetEvent () {
begin = long.Parse (tmp [0]),
end = long.Parse (tmp [1]),
threadId = int.Parse (tmp [2]),
type = evtType,
- InstanceIndex = int.Parse (tmp [4]),
+ Message = tmp[4],
+ InstanceIndex = int.Parse (tmp [5]),
};
}
return new DbgEvent () {
end = long.Parse (tmp [1]),
threadId = int.Parse (tmp [2]),
type = evtType,
+ Message = tmp[4]
};
}
public virtual string Print ()
- => $"{begin,10}:{threadId,-2}:{type,-20}:";
+ => $"{begin,10}:{threadId,-2}:{type,-20}:{Message}";
public override string ToString ()
- => $"{begin};{end};{threadId};{type}";
+ => $"{begin};{end};{threadId};{type};{Message}";
public virtual Color Color {
get {
switch (type) {
GORegisterForRedraw = Widget | 0x0C,
GOComputeChildrenPositions = Widget | 0x0D,
GOOnChildLayoutChange = Widget | 0x0E,
+ GOAdjustStretchedGo = Widget | 0x0F,
+ GOSetProperty = Widget | 0x10,
AlreadyDisposed = Widget | Dispose | Error | 0x01,
DisposedByGC = Widget | Dispose | Error | 0x02,
=> $"{base.ToString ()};{layouting};{result};{OldSlot};{NewSlot}";
public override Color Color {
get {
- if (type == DbgEvtType.GORegisterLayouting)
- return Colors.GreenYellow;
- if (type == DbgEvtType.GOProcessLayoutingWithNoParent)
- return Colors.DarkRed;
- switch (result) {
- case LayoutingQueueItem.Result.Success:
- return Colors.Green;
- case LayoutingQueueItem.Result.Deleted:
- return Colors.Red;
- case LayoutingQueueItem.Result.Discarded:
- return Colors.OrangeRed;
- default:
- return Colors.Orange;
- } }
+ if (type == DbgEvtType.GORegisterLayouting)
+ return Colors.GreenYellow;
+ if (type == DbgEvtType.GOProcessLayoutingWithNoParent)
+ return Colors.DarkRed;
+ switch (result) {
+ case LayoutingQueueItem.Result.Success:
+ return Colors.Green;
+ case LayoutingQueueItem.Result.Deleted:
+ return Colors.Red;
+ case LayoutingQueueItem.Result.Discarded:
+ return Colors.OrangeRed;
+ default:
+ return Colors.Orange;
+ }
+ }
}
}
}
\ No newline at end of file
public override Color Color {
get {
switch (type) {
+ case DbgEvtType.GOSetProperty:
+ return Colors.Lime;
case DbgEvtType.GOMeasure:
+ return Colors.Pink;
case DbgEvtType.GOSearchLargestChild:
case DbgEvtType.GOSearchTallestChild:
return Colors.HotPink;
+ case DbgEvtType.GOOnChildLayoutChange:
+ return Colors.DarkViolet;
+ case DbgEvtType.GOAdjustStretchedGo:
+ return Colors.PaleVioletRed;
case DbgEvtType.GOClassCreation:
return Colors.DarkSlateGrey;
case DbgEvtType.GOInitialization:
//useful to track events for obj shown later, not on start
public int InstanceIndex;
public int yIndex;//index in parenting, the whole main graphic tree is one continuous suite
- public int xLevel;//depth
- public String Width;
- public String Height;
+ public int xLevel;//depth
public static DbgWidgetRecord Parse (string str)
{
g.InstanceIndex = int.Parse (tmp [1]);
g.yIndex = int.Parse (tmp [2]);
g.xLevel = int.Parse (tmp [3]);
- g.Width = tmp [4];
- g.Height = tmp [5];
return g;
}
}
#endif
}
-
+[Conditional ("DEBUG_LOG")]
+ public static void SetMsg (DbgEvtType evtType, string message)
+ {
+#if DEBUG_LOG
+ if (!logevt (evtType))
+ return;
+lock (logMutex) {
+ chrono.Stop ();
+ if (!startedEvents.ContainsKey (Thread.CurrentThread.ManagedThreadId))
+ throw new Exception ("Current thread has no event started");
+ DbgEvent e = startedEvents [Thread.CurrentThread.ManagedThreadId].Peek ();
+ if (e.type != evtType)
+ throw new Exception ($"Begin/end event logging mismatch: {e.type}/{evtType}");
+ e.Message = message;
+ chrono.Start ();
+ }
+#endif
+ }
[Conditional ("DEBUG_LOG")]
public static void EndEvent (DbgEvtType evtType, bool discardIfNoChildEvents = false)
{
DbgEvent evt = addEventInternal (evtType, data);
chrono.Start ();
}
+#endif
+ }
+ [Conditional("DEBUG_LOG")]
+ public static void AddEventWithMsg (DbgEvtType evtType, string message, params object [] data) {
+#if DEBUG_LOG
+ if (!logevt (evtType))
+ return;
+
+ lock (logMutex) {
+ chrono.Stop ();
+ DbgEvent evt = addEventInternal (evtType, data);
+ evt.Message = message;
+ chrono.Start ();
+ }
#endif
}
DbgEvent evt = null;
if (data == null || data.Length == 0)
evt = new DbgEvent (chrono.ElapsedTicks, evtType);
- else if (data [0] is Widget w)
+ else if (data [0] is Widget w) {
evt = new DbgWidgetEvent (chrono.ElapsedTicks, evtType, w.instanceIndex);
- else if (data [0] is LayoutingQueueItem lqi)
- evt = new DbgLayoutEvent (chrono.ElapsedTicks, evtType, lqi.graphicObject.instanceIndex, lqi.LayoutType, lqi.result, lqi.Slot, lqi.NewSlot);
+ if (evtType == DbgEvtType.GONewParent) {
+ if (data[1] is Widget wi)
+ evt.Message = $"{wi.instanceIndex}";
+ else if (data[1] is Interface)
+ evt.Message = "Interface";
+ else
+ evt.Message = $"{data[1]}";
+ }
+
+ } else if (data [0] is LayoutingQueueItem lqi)
+ evt = new DbgLayoutEvent (chrono.ElapsedTicks, evtType, (lqi.Layoutable as Widget).instanceIndex, lqi.LayoutType, lqi.result, lqi.Slot, lqi.NewSlot);
else
evt = new DbgEvent (chrono.ElapsedTicks, evtType);
writer.WriteLine ("[GraphicObjects]");
for (int i = startingWidgetsIndex; i < Widget.GraphicObjects.Count; i++) {
Widget g = Widget.GraphicObjects [i];
- writer.WriteLine ($"{g.GetType ().Name};{g.instanceIndex};{g.yIndex};{g.xLevel};{g.Width};{g.Height}");
+ writer.WriteLine ($"{g.GetType ().Name};{g.instanceIndex};{g.yIndex};{g.xLevel}");
}
}
public static implicit operator Color(SolidColor c) => c.color;
public static implicit operator SolidColor(Color c) => new SolidColor (c);
- //public static bool operator ==(SolidColor left, SolidColor right) => left?.color == right?.color;
- //public static bool operator !=(SolidColor left, SolidColor right) => left?.color != right?.color;
-
- public override int GetHashCode ()
- {
- return color.GetHashCode();
- }
+ public override int GetHashCode () => color.GetHashCode();
public override bool Equals (object obj)
=> obj is Color c ? color.Equals (c) : obj is Colors cl ? color.Equals(cl) : obj is SolidColor sc && color.Equals (sc.color);
public static SolidColor operator *(SolidColor c, Double f)
- {
- return new SolidColor(new Color(c.color.R,c.color.G,c.color.B,c.color.A * f));
- }
+ => new SolidColor(new Color(c.color.R,c.color.G,c.color.B,c.color.A * f));
public static SolidColor operator +(SolidColor c1, SolidColor c2)
- {
- return new SolidColor(new Color(c1.color.R + c2.color.R,c1.color.G + c2.color.G,c1.color.B + c2.color.B,c1.color.A + c2.color.A));
- }
+ => new SolidColor(new Color(c1.color.R + c2.color.R,c1.color.G + c2.color.G,c1.color.B + c2.color.B,c1.color.A + c2.color.A));
public static SolidColor operator -(SolidColor c1, SolidColor c2)
- {
- return new SolidColor(new Color(c1.color.R - c2.color.R,c1.color.G - c2.color.G,c1.color.B - c2.color.B,c1.color.A - c2.color.A));
- }
+ => new SolidColor(new Color(c1.color.R - c2.color.R,c1.color.G - c2.color.G,c1.color.B - c2.color.B,c1.color.A - c2.color.A));
#endregion
- public override string ToString()
- {
- return color.ToString ();
- }
+ public override string ToString() => color.ToString ();
}
}
using System;
using Crow.Cairo;
-using FastEnumUtility;
+//using FastEnumUtility;
namespace Crow
{
f.Name = tmp.ToString ();
else {
f.Name = tmp.Slice (0, ioc).ToString ();
- f.Style = FastEnum.Parse<FontStyle> (tmp.Slice (ioc + 1).ToString (), true);
+ f.Style = EnumsNET.Enums.Parse<FontStyle> (tmp.Slice (ioc + 1).ToString (), true);
}
}
return f;
using System.Xml;
using Crow.IML;
using System.Text;
-using FastEnumUtility;
+//using FastEnumUtility;
namespace Crow.IML
{
internal static MethodInfo stringEquals = typeof (string).GetMethod("Equals", new Type [3] { typeof (string), typeof (string), typeof (StringComparison) });
internal static MethodInfo miObjToString = typeof(object).GetMethod("ToString");
internal static MethodInfo miGetType = typeof(object).GetMethod("GetType");
- internal static MethodInfo miParseEnum = typeof(Enum).GetMethod("Parse", BindingFlags.Static | BindingFlags.Public,
- Type.DefaultBinder, new Type [] {typeof (Type), typeof (string), typeof (bool)}, null);
- internal static MethodInfo miParseEnumInversedParams = typeof(CompilerServices).GetMethod ("ParseEnum", BindingFlags.Static | BindingFlags.NonPublic);
+ internal static MethodInfo miParseEnum = typeof(CompilerServices).GetMethod("parseEnum", BindingFlags.Static | BindingFlags.NonPublic);
+ internal static MethodInfo miParseEnumInversedParams = typeof(CompilerServices).GetMethod ("parseEnumInverseParams", BindingFlags.Static | BindingFlags.NonPublic);
internal static MethodInfo miGetTypeFromHandle = typeof(Type).GetMethod("GetTypeFromHandle");
internal static MethodInfo miGetEvent = typeof(Type).GetMethod("GetEvent", new Type[] {typeof(string)});
il.Emit(OpCodes.Ldtoken, pi.PropertyType);
il.Emit(OpCodes.Call, CompilerServices.miGetTypeFromHandle);
//load enum value name
- il.Emit (OpCodes.Ldstr, Convert.ToString (val));//TODO:implement here string format?
- //load false
- il.Emit (OpCodes.Ldc_I4_0);
+ il.Emit (OpCodes.Ldstr, Convert.ToString (val));//TODO:implement here string format?
il.Emit (OpCodes.Call, CompilerServices.miParseEnum);
if (CompilerServices.miParseEnum.ReturnType != pi.PropertyType)
foundMI = null;
if (assembly == null)
return false;
- foreach (Type t in assembly.GetTypes ().Where
- (ty => ty.IsDefined (typeof (ExtensionAttribute), false))) {
- 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)) {
- Type curType = extendedType;
- while (curType != null) {
- if (mi.GetParameters () [0].ParameterType == curType) {
- foundMI = mi;
- return true;
- }
- curType = curType.BaseType;
- }
- }
-
+ try
+ {
+
+ foreach (Type t in assembly.GetExportedTypes().Where
+ (ty => ty.IsDefined (typeof (ExtensionAttribute), false))) {
+ 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)) {
+ Type curType = extendedType;
+ while (curType != null) {
+ if (mi.GetParameters () [0].ParameterType == curType) {
+ foundMI = mi;
+ return true;
+ }
+ curType = curType.BaseType;
+ }
+ }
+
+ }
}
+ catch (System.Exception) {}
return false;
}
/// <summary>
}
}
}
- internal static object ParseEnum (string str, Type enumType) => Enum.Parse (enumType, str);
internal static bool isValueType (object obj) => obj.GetType ().IsValueType;
/// <summary>
knownTypes.Add (strDataType, dataType);
return dataType;
}
- foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies ()) {
- if (a.IsDynamic)
- continue;
- foreach (Type expT in a.GetExportedTypes ()) {
- if (expT.Name != strDataType && expT.FullName != strDataType)
- continue;
- if (!knownTypes.ContainsKey(strDataType))
- knownTypes.Add (strDataType, expT);
- return expT;
- }
+ foreach (Assembly a in Interface.crowAssemblies) {
+ try {
+ foreach (Type expT in a.GetExportedTypes ()) {
+ if (expT.Name != strDataType && expT.FullName != strDataType)
+ continue;
+ if (!knownTypes.ContainsKey(strDataType))
+ knownTypes.Add (strDataType, expT);
+ return expT;
+ }
+ }catch{}
}
knownTypes.Add (strDataType, null);
return null;
mi.MemberType == MemberTypes.Field ? (mi as FieldInfo).FieldType :
mi.MemberType == MemberTypes.Property ? (mi as PropertyInfo).PropertyType :
mi.MemberType == MemberTypes.Method ? (mi as MethodInfo).ReturnType : null;
+
+ /*internal static object parseEnum (Type enumType, string val)
+ => EnumsNET.FlagEnums.IsFlagEnum (enumType) ?
+ EnumsNET.FlagEnums.ParseFlags (enumType, val, true, "|") :
+ EnumsNET.Enums.Parse (enumType, val, true);*/
+ internal static object parseEnum (Type enumType, string val) {
+ try
+ {
+ return EnumsNET.FlagEnums.IsFlagEnum (enumType) ?
+ EnumsNET.FlagEnums.ParseFlags (enumType, val, true, "|") :
+ EnumsNET.Enums.Parse (enumType, val, true);
+ }
+ catch (System.Exception)
+ {
+ Console.WriteLine($"{enumType} {val}");
+ throw;
+ }
+ }
+ internal static object parseEnumInverseParams (string str, Type enumType) => parseEnum (enumType, str);
}
}
il.Emit (OpCodes.Call, CompilerServices.miGetTypeFromHandle);
//load enum value name
il.Emit (OpCodes.Ldstr, operandes [1].Trim ());
- //load false
- il.Emit (OpCodes.Ldc_I4_0);
} else {
lopParseMi = lopPI.PropertyType.GetMethod ("Parse");
if (lopParseMi == null)
// Copyright (c) 2014-2020 Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
//
// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
+using System;
using Glfw;
namespace Crow
{
+ [Flags]
+ public enum DeviceEventType {
+ None = 0x00,
+ MouseMove = 0x01,
+ ButtonDown = 0x02,
+ ButtonUp = 0x04,
+ Buttons = ButtonDown | ButtonUp,
+ MouseClick = 0x08,
+ MouseWheel = 0x10,
+ Mouse = Buttons | MouseWheel | MouseClick | MouseMove,
+ KeyDown = 0x20,
+ KeyUp = 0x40,
+ KeyPress = 0x80,
+ Keyboard = KeyDown | KeyUp | KeyPress,
+ All = Mouse | Keyboard
+ }
public class MouseEventArgs : CrowEventArgs
{
public readonly int X, Y;
- public Point Position => new Point (X, Y);
+ public Point Position => new Point (X, Y);
public MouseEventArgs () { }
public MouseEventArgs (int x, int y) {
X = x;
#endregion
internal static List<Assembly> crowAssemblies = new List<Assembly> ();
+ public void AddCrowAssembly (Assembly a) {
+ lock (UpdateMutex) {
+ if (crowAssemblies.Contains (a))
+ return;
+ crowAssemblies.Add (a);
+ loadStylingFromAssembly (a);
+ }
+ }
+ public void RemoveCrowAssembly (Assembly a) {
+ lock (UpdateMutex) {
+ if (!crowAssemblies.Contains (a))
+ return;
+ crowAssemblies.Remove (a);
+ init_internal ();
+ }
+ }
#region CTOR
static Interface ()
public const int MaxCacheSize = 2048;
/// <summary> Above this count, the layouting is discard from the current
/// update cycle and requeued for the next</summary>
- public const int MaxLayoutingTries = 3;
+ public static int MaxLayoutingTries = 30;
/// <summary> Above this count, the layouting is discard for the widget and it
/// will not be rendered on screen </summary>
- public const int MaxDiscardCount = 5;
+ public static int MaxDiscardCount = 5;
/// <summary> Global font rendering settings for Cairo </summary>
public static FontOptions FontRenderingOptions;
/// <summary> Global font rendering settings for Cairo </summary>
lock (UpdateMutex)
GraphicTree.Insert (ptr, g);
-
- g.RegisteredLayoutings = LayoutingType.None;
+
g.RegisterForLayouting (LayoutingType.Sizing | LayoutingType.ArrangeChildren);
return g;
public virtual bool OnMouseButtonUp (MouseButton button)
{
DbgLogger.StartEvent (DbgEvtType.MouseUp);
- mouseRepeatTimer.Reset ();
- lastMouseDownEvent = null;
- if (DragAndDropInProgress) {
- if (DragAndDropOperation.DropTarget != null)
- DragAndDropOperation.DragSource.onDrop (this, DragAndDropOperation);
- else
- DragAndDropOperation.DragSource.onEndDrag (this, DragAndDropOperation);
- DragAndDropOperation = null;
- if (ActiveWidget != null) {
- ActiveWidget.onMouseUp (_activeWidget, new MouseButtonEventArgs (MousePosition.X, MousePosition.Y, button, InputAction.Release));
- ActiveWidget = null;
- }
- DbgLogger.EndEvent (DbgEvtType.MouseUp);
- return true;
- }
+ try {
+ mouseRepeatTimer.Reset ();
+ lastMouseDownEvent = null;
+
+ if (DragAndDropInProgress) {
+ if (DragAndDropOperation.DropTarget != null)
+ DragAndDropOperation.DragSource.onDrop (this, DragAndDropOperation);
+ else
+ DragAndDropOperation.DragSource.onEndDrag (this, DragAndDropOperation);
+ DragAndDropOperation = null;
+ if (ActiveWidget != null) {
+ ActiveWidget.onMouseUp (_activeWidget, new MouseButtonEventArgs (MousePosition.X, MousePosition.Y, button, InputAction.Release));
+ ActiveWidget = null;
+ }
+ return true;
+ }
- if (_activeWidget == null) {
- DbgLogger.EndEvent (DbgEvtType.MouseUp);
- return false;
- }
+ if (_activeWidget == null)
+ return false;
- _activeWidget.onMouseUp (_activeWidget, new MouseButtonEventArgs (MousePosition.X, MousePosition.Y, button, InputAction.Release));
+ _activeWidget.onMouseUp (_activeWidget, new MouseButtonEventArgs (MousePosition.X, MousePosition.Y, button, InputAction.Release));
- if (_activeWidget == null) {
- Debug.WriteLine ("[BUG]Mystery reset of _activeWidget");
- DbgLogger.EndEvent (DbgEvtType.MouseUp | DbgEvtType.Error);
- return true;
- }
+ if (_activeWidget == null) {
+ DbgLogger.SetMsg (DbgEvtType.MouseUp, "[BUG]Mystery reset of _activeWidget");
+ 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 (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)) {
- // ProcessMouseMove (Mouse.X, Mouse.Y);
- // }
- DbgLogger.EndEvent (DbgEvtType.MouseUp);
- return true;
+ ActiveWidget = null;
+ // if (!lastActive.MouseIsIn (Mouse.Position)) {
+ // ProcessMouseMove (Mouse.X, Mouse.Y);
+ // }
+
+ return true;
+ } finally {
+ DbgLogger.EndEvent (DbgEvtType.MouseUp);
+ }
}
/// <summary>
/// Forward the mouse wheel event from the host to the crow interface
else
ctxMenuContainer.IsOpened = true;
- ctxMenuContainer.BubbleMouseEvent = false;
+ ctxMenuContainer.BubbleMouseEvent = DeviceEventType.None;
ctxMenuContainer.LogicalParent = go;
ctxMenuContainer.DataSource = go;
get => LayoutingType.None;
set { throw new NotImplementedException (); }
}
+ public LayoutingType RequiredLayoutings {
+ get => LayoutingType.None;
+ set { throw new NotImplementedException (); }
+ }
public void RegisterForLayouting (LayoutingType layoutType) { throw new NotImplementedException (); }
public bool UpdateLayout (LayoutingType layoutType) { throw new NotImplementedException (); }
public Rectangle ContextCoordinates (Rectangle r) => r;
//dm is unbound, arg0 is instance of Item container to expand
dm = new DynamicMethod ("dyn_count_" + fetchMethodName,
typeof (bool), new Type[] {typeof(object)}, true);
- il = dm.GetILGenerator (256);
+ il = dm.GetILGenerator (256);
+ System.Reflection.Emit.Label end = il.DefineLabel ();
+ System.Reflection.Emit.Label test = il.DefineLabel ();
//get the dataSource of the arg0
il.Emit (OpCodes.Ldarg_0);
il.Emit (OpCodes.Call, CompilerServices.miGetDataTypeAndFetch);
}else
emitGetSubData(il, dataType);
- }
-
- il.Emit (OpCodes.Callvirt, CompilerServices.miGetColCount);
+ }
+ il.Emit (OpCodes.Isinst, typeof(System.Collections.ICollection));
+ il.Emit (OpCodes.Dup);//duplicate children for testing if it's a collection for childs counting
+ il.Emit (OpCodes.Brtrue, test);//if true, jump to perform count
+ il.Emit (OpCodes.Pop);//pop null
+ il.Emit (OpCodes.Ldc_I4_0);//push false
+ il.Emit (OpCodes.Br, end);
+
+ il.MarkLabel (test);
+
+ il.Emit (OpCodes.Callvirt, CompilerServices.miGetColCount);
il.Emit (OpCodes.Ldc_I4_0);
il.Emit (OpCodes.Cgt);
+
+ il.MarkLabel (end);
+
il.Emit (OpCodes.Ret);
HasSubItems = (BooleanTestOnInstance)dm.CreateDelegate (typeof(BooleanTestOnInstance));
#endregion
Height = 0x08,
Sizing = 0x0C,
ArrangeChildren = 0x10,
- All = 0xFF
+ All = Positioning | Sizing | ArrangeChildren
}
/// <summary>
}
#if DEBUG_LOG
public Result result;
- public Widget graphicObject {
- get { return Layoutable as Widget; }
- }
- public string Name {
- get { return graphicObject.Name; }
- }
- public string FullName {
- get { return graphicObject.ToString(); }
- }
- public Measure Width {
- get { return graphicObject.Width; }
- }
- public Measure Height {
- get { return graphicObject.Height; }
- }
public Rectangle Slot, NewSlot;
#endif
try {
- if (go.Parent == null) {//TODO:improve this
- //cancel layouting for object without parent, maybe some were in queue when
- //removed from a listbox
- DbgLogger.AddEvent (DbgEvtType.GOProcessLayoutingWithNoParent, this);
+ if (!go.layoutMutex.TryEnterWriteLock (1)) {
+ go.IFace.LayoutingQueue.Enqueue (this);
+#if DEBUG_LOG
+ result = Result.Requeued;
+#endif
return;
}
+
+ try {
+ if (go.Parent == null) {//TODO:improve this
+ //cancel layouting for object without parent, maybe some were in queue when
+ //removed from a listbox
+ DbgLogger.AddEvent (DbgEvtType.GOProcessLayoutingWithNoParent, this);
+ return;
+ }
#if DEBUG_LOG
- Slot = graphicObject.Slot;
+ Slot = Layoutable.getSlot ();
+#endif
+ LayoutingTries++;
+
+ if (Layoutable.UpdateLayout (LayoutType)) {
+ Layoutable.RequiredLayoutings &= (~LayoutType);
+ if (Layoutable.RequiredLayoutings == LayoutingType.None && go.IsDirty)
+ go.IFace.EnqueueForRepaint (this);
+#if DEBUG_LOG
+ result = Result.Success;
#endif
- LayoutingTries++;
- if (!Layoutable.UpdateLayout (LayoutType)) {
- if (LayoutingTries < Interface.MaxLayoutingTries) {
- Layoutable.RegisteredLayoutings |= LayoutType;
- (Layoutable as Widget).IFace.LayoutingQueue.Enqueue (this);
+ } else {
+ if (LayoutingTries < Interface.MaxLayoutingTries) {
+ Layoutable.RegisteredLayoutings |= LayoutType;
+ go.IFace.LayoutingQueue.Enqueue (this);
#if DEBUG_LOG
- result = Result.Requeued;
+ result = Result.Requeued;
#endif
- } else if (DiscardCount < Interface.MaxDiscardCount) {
+ } else if (DiscardCount < Interface.MaxDiscardCount) {
#if DEBUG_LOG
- result = Result.Discarded;
+ result = Result.Discarded;
#endif
- LayoutingTries = 0;
- DiscardCount++;
- Layoutable.RegisteredLayoutings |= LayoutType;
- (Layoutable as Widget).IFace.DiscardQueue.Enqueue (this);
- }
+ LayoutingTries = 0;
+ DiscardCount++;
+ Layoutable.RegisteredLayoutings |= LayoutType;
+ go.IFace.DiscardQueue.Enqueue (this);
+ }
#if DEBUG_LOG
- else {
- result = Result.Deleted;
+ else {
+ result = Result.Deleted;
+ }
+#endif
}
+#if DEBUG_LOG
+ NewSlot = Layoutable.getSlot();
#endif
+ } finally {
+ go.layoutMutex.ExitWriteLock ();
}
-#if DEBUG_LOG
- else{
- result = Result.Success;
- }
- NewSlot = graphicObject.Slot;
-#endif
- }finally {
+ } finally {
go.parentRWLock.ExitReadLock ();
DbgLogger.EndEvent (DbgEvtType.GOProcessLayouting, this);
}
namespace Crow
{
- public class ObservableList<T> : IList<T>, IObservableList, IValueChange {
+ public class ObservableList<T> : IList<T>, IObservableList, IValueChange, ICollection {
#region IValueChange implementation
public event EventHandler<ValueChangeEventArgs> ValueChanged;
public virtual void NotifyValueChanged (string MemberName, object _value)
public bool IsReadOnly => false;
+ public bool IsSynchronized => throw new NotImplementedException();
+
+ public object SyncRoot => throw new NotImplementedException();
+
public T this[int index] {
get => items[index];
set {
public IEnumerator<T> GetEnumerator() => items.GetEnumerator ();
IEnumerator IEnumerable.GetEnumerator() => items.GetEnumerator ();
+
+ public void CopyTo(Array array, int index) => items.ToArray().CopyTo (array, index);
}
}
}
}
public IList<Colors> AvailableColors => //Enum.GetValues (typeof (Color)).ToList<Color> ();// Colors. ColorDic.Values.OrderBy (c => c.Hue).ToList ();
- FastEnumUtility.FastEnum.GetValues<Colors> ().ToList<Colors> ();
+ EnumsNET.Enums.GetValues<Colors> ().ToList<Colors> ();
public void onSelectedItemChanged(object sender, SelectionChangeEventArgs e) {
CurrentColor = (Color)(Colors)e.NewValue;
using System;
using System.Text;
-using FastEnumUtility;
namespace Crow
{
}
//read next value in config string until next ';'
- string getConfAttrib (string conf, ref int i) {
- int nextI = conf.Substring (i).IndexOf (';');
- string tmp = conf.Substring (i, nextI);
+ ReadOnlySpan<char> getConfAttrib (ReadOnlySpan<char> conf, ref int i) {
+ int nextI = conf.Slice (i).IndexOf (';');
+ ReadOnlySpan<char> tmp = conf.Slice (i, nextI);
i += nextI + 1;
return tmp;
}
/// </summary>
/// <param name="conf">Conf.</param>
/// <param name="dataSource">Data source for the docked windows</param>
- public void ImportConfig (string conf, object dataSource = null) {
+ public void ImportConfig (ReadOnlySpan<char> conf, object dataSource = null) {
lock (IFace.UpdateMutex) {
ClearChildren ();
stretchedChild = null;
int i = 0;
- Orientation = FastEnum.Parse<Orientation> (getConfAttrib (conf, ref i));
+ Orientation = EnumsNET.Enums.Parse<Orientation> (getConfAttrib (conf, ref i).ToString());
importConfig (conf, ref i, dataSource);
}
}
return Orientation.ToString() + ";" + exportConfig();
}
- DockWindow importDockWinConfig (string conf, ref int i, object dataSource){
+ DockWindow importDockWinConfig (ReadOnlySpan<char> conf, ref int i, object dataSource){
DockWindow dw = null;
- string wName = getConfAttrib (conf, ref i);
+ string wName = getConfAttrib (conf, ref i).ToString();
try {
dw = IFace.CreateInstance (wName) as DockWindow;
- } catch {
+ } catch (Exception ex){
+ Console.WriteLine ($"[importDockWinConfig]{ex}");
dw = new DockWindow (IFace);
}
dw.Name = wName;
- dw.Width = Measure.Parse (getConfAttrib (conf, ref i));
- dw.Height = Measure.Parse (getConfAttrib (conf, ref i));
- dw.DockingPosition = FastEnum.Parse<Alignment> (getConfAttrib (conf, ref i));
- dw.savedSlot = Rectangle.Parse (getConfAttrib (conf, ref i));
- dw.wasResizable = Boolean.Parse (getConfAttrib (conf, ref i));
+ dw.Width = Measure.Parse (getConfAttrib (conf, ref i).ToString());
+ dw.Height = Measure.Parse (getConfAttrib (conf, ref i).ToString());
+ dw.DockingPosition = EnumsNET.Enums.Parse<Alignment> (getConfAttrib (conf, ref i).ToString());
+ dw.savedSlot = Rectangle.Parse (getConfAttrib (conf, ref i).ToString());
+ dw.wasResizable = Boolean.Parse (getConfAttrib (conf, ref i).ToString());
dw.Resizable = false;
dw.DataSource = dataSource;
return dw;
}
- void importConfig (string conf, ref int i, object dataSource) {
+ void importConfig (ReadOnlySpan<char> conf, ref int i, object dataSource) {
if (conf [i++] != '(')
return;
DockWindow dw = null;
while (i < conf.Length - 4) {
- string sc = conf.Substring (i, 4);
+ string sc = conf.Slice (i, 4).ToString();
i += 4;
switch (sc) {
case "TVI;":
TabView tv = new TabView (IFace, "DockingTabView");
- tv.Width = Measure.Parse (getConfAttrib (conf, ref i));
- tv.Height = Measure.Parse (getConfAttrib (conf, ref i));
+ tv.Width = Measure.Parse (getConfAttrib (conf, ref i).ToString());
+ tv.Height = Measure.Parse (getConfAttrib (conf, ref i).ToString());
this.AddChild (tv);
i++;
while (conf [i] != ')') {
break;
case "STK;":
DockStack ds = new DockStack (IFace);
- ds.Width = Measure.Parse (getConfAttrib (conf, ref i));
- ds.Height = Measure.Parse (getConfAttrib (conf, ref i));
- ds.Orientation = FastEnum.Parse<Orientation> (getConfAttrib (conf, ref i));
+ ds.Width = Measure.Parse (getConfAttrib (conf, ref i).ToString());
+ ds.Height = Measure.Parse (getConfAttrib (conf, ref i).ToString());
+ ds.Orientation = EnumsNET.Enums.Parse<Orientation> (getConfAttrib (conf, ref i).ToString());
this.AddChild (ds);
break;
case "SPL;":
Splitter sp = new Splitter (IFace);
- sp.Width = Measure.Parse (getConfAttrib (conf, ref i));
- sp.Height = Measure.Parse (getConfAttrib (conf, ref i));
+ sp.Width = Measure.Parse (getConfAttrib (conf, ref i).ToString());
+ sp.Height = Measure.Parse (getConfAttrib (conf, ref i).ToString());
sp.Thickness = int.Parse (getConfAttrib (conf, ref i));
this.AddChild (sp);
break;
for (int i = 0; i < Children.Count; i++) {
if (Children [i] is DockWindow dw)
- tmp.Append (dw.GetConfigString());
+ tmp.Append (dw.GetDockConfigString());
else if (Children [i] is TabView tv) {
tmp.Append ($"TVI;{tv.Width};{tv.Height};(");
foreach (DockWindow d in tv.Items)
- tmp.Append (d.GetConfigString().Substring(4));
+ tmp.Append (d.GetDockConfigString().Substring(4));
tmp.Append (")");
}else if (Children [i] is DockStack ds)
tmp.Append ($"STK;{ds.Width};{ds.Height};{ds.Orientation};{ds.exportConfig()}");
public DockWindow (Interface iface) : base (iface) {}
#endregion
+ protected override void loadTemplate(Widget template = null)
+ {
+ initCommands ();
+
+ base.loadTemplate (template);
+ }
+
int undockThreshold = 10;
bool isDocked = false;
Alignment docking = Alignment.Undefined;
Point undockingMousePosOrig; //mouse pos when docking was donne, use for undocking on mouse move
internal Rectangle savedSlot; //last undocked slot recalled when view is undocked
- internal bool wasResizable;
+ internal bool wasResizable, freezeDockState;
public bool IsDocked {
get { return isDocked; }
[XmlIgnore] public bool IsDockedInTabView => LogicalParent is TabView;
[XmlIgnore] public bool IsDockedInStack => Parent is DockStack;
+ public Command CMDFreezeDockState, CMDUnfreezeDockState;
+ public CommandGroup DockCommands => new CommandGroup (CMDFreezeDockState, CMDUnfreezeDockState);
+ void initCommands () {
+ CMDFreezeDockState = new Command ("Freeze Dock State", () => FreezeDockState = true, "#Crow.Icons.unpin.svg", !FreezeDockState);
+ CMDUnfreezeDockState = new Command ("Unfreeze Dock State", () => FreezeDockState = false, "#Crow.Icons.pin.svg", FreezeDockState);
+ }
+
+ /// <summary>
+ /// if true, current dock status (docked or undocked) is frozen, and trying to move the
+ /// window will not trigger docking try.
+ /// </summary>
+ /// <value></value>
+ public bool FreezeDockState {
+ get { return freezeDockState; }
+ set {
+ if (freezeDockState == value)
+ return;
+ freezeDockState = value;
+ NotifyValueChangedAuto (freezeDockState);
+
+ if (CMDFreezeDockState == null)
+ initCommands ();
+ else {
+ CMDFreezeDockState.CanExecute = !freezeDockState;
+ CMDUnfreezeDockState.CanExecute = freezeDockState;
+ }
+ }
+ }
+
public Alignment DockingPosition {
get { return docking; }
set {
NotifyValueChangedAuto (DockingPosition);
}
}
- /*public override bool PointIsIn (ref Point m)
- {
- if (!base.PointIsIn(ref m))
- return false;
-
- Group p = Parent as Group;
- if (p != null) {
- lock (p.Children) {
- for (int i = p.Children.Count - 1; i >= 0; i--) {
- if (p.Children [i] == this)
- break;
- if (p.Children [i].IsDragged)
- continue;
- if (p.Children [i].Slot.ContainsOrIsEqual (m)) {
- return false;
- }
- }
- }
+ Group floatingGroup;
+ /// <summary>
+ /// If null, the default container for the floating windows is the Interface. If a valid
+ /// group is set, undocked windows will be contained in this widget, allowing multiple independant levels
+ /// of dockable windows
+ /// </summary>
+ /// <value></value>
+ public Group FloatingGroup {
+ get => floatingGroup;
+ set {
+ if (floatingGroup == value)
+ return;
+ floatingGroup = value;
+ NotifyValueChangedAuto (floatingGroup);
}
- return Slot.ContainsOrIsEqual(m);
- }*/
+ }
bool tryGetTargetDockStack (DockWindow dw, out DockStack ds) {
if (dw.Parent is DockStack dwp)
bool dockParentParent = false;
public override void onDrag (object sender, MouseMoveEventArgs e)
{
- if (isDocked)
- CheckUndock (e.Position);
+ if (!freezeDockState && isDocked)
+ checkUndock (e.Position);
else
moveAndResize (e.XDelta, e.YDelta, currentDirection);
base.onDrag (sender, e);
- if (isDocked)
+ if (freezeDockState || isDocked)
return;
Alignment dockingPosSave = DockingPosition;
if (this.HasFocus && IsDocked && e.Button == MouseButton.Left)
undockingMousePosOrig = e.Position;
}
- public 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;
- Undock ();
- return true;
- }
protected override void onStartDrag (object sender, DragDropEventArgs e)
{
tv.Dispose();
w.IsVisible = true;
ds.checkAlignments();
+ w.NotifyValueChanged ("IsDockedInTabView", false);
+ w.NotifyValueChanged ("IsDockedInStack", true);
}
} else if (Parent is DockStack ds) {
ds.Undock (this);
Resizable = wasResizable;
}
}
-
+ 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;
+ Undock ();
+ return true;
+ }
void dock () {
IFace.RemoveWidget (this);
LastSlots = LastPaintedSlot = Slot = default(Rectangle);
Left = Top = 0;
}
- public void Dock (DockWindow target) {
+ void Dock (DockWindow target) {
lock (IFace.UpdateMutex) {
- //IsDocked = true;
dock ();
if (target.LogicalParent is TabView tv) {
tv2.AddItem (this);
target.Width = target.Height = this.Width = this.Height = Measure.Stretched;
target.DockingPosition = this.DockingPosition = Alignment.Center;
+ target.NotifyValueChanged ("IsDockedInTabView", true);
+ target.NotifyValueChanged ("IsDockedInStack", false);
+
IsDocked = true;
}
}
}
- public void Dock (DockStack target){
+ void Dock (DockStack target){
lock (IFace.UpdateMutex) {
dock ();
base.close ();
}
- internal string GetConfigString () =>
+ internal string GetDockConfigString () =>
string.Format($"WIN;{Name};{Width};{Height};{DockingPosition};{savedSlot};{wasResizable};");
+
+
+ public string FloatingConfigString =>
+ $"{Name};{Left};{Top};{Width};{Height};{FreezeDockState};{Resizable}";
+ public static DockWindow CreateFromFloatingConfigString (Interface iface, ReadOnlySpan<char> conf, object datasource = null) {
+ int i = conf.IndexOf (';');
+ string wname = conf.Slice(0, i).ToString();
+ DockWindow dw = iface.CreateInstance (wname) as DockWindow;
+ dw.Name = wname;
+ conf = conf.Slice (i + 1); i = conf.IndexOf (';');
+ dw.Left = int.Parse (conf.Slice(0, i).ToString());
+ conf = conf.Slice (i + 1); i = conf.IndexOf (';');
+ dw.Top = int.Parse (conf.Slice(0, i).ToString());
+ conf = conf.Slice (i + 1); i = conf.IndexOf (';');
+ dw.Width = Measure.Parse (conf.Slice(0, i).ToString());
+ conf = conf.Slice (i + 1); i = conf.IndexOf (';');
+ dw.Height = Measure.Parse (conf.Slice(0, i).ToString());
+ conf = conf.Slice (i + 1); i = conf.IndexOf (';');
+ dw.FreezeDockState = bool.Parse (conf.Slice(0, i).ToString());
+
+ dw.Resizable = bool.Parse (conf.Slice (i + 1).ToString());
+ dw.DataSource = datasource;
+
+ iface.AddWidget (dw);
+ return dw;
+ }
}
}
}
}
#endregion
+ public override void OnDataSourceChanged(object sender, DataSourceChangeEventArgs e)
+ {
+ base.OnDataSourceChanged(sender, e);
+ NotifyValueChanged ("IsExpandable", IsExpandable);
- public BooleanTestOnInstance GetIsExpandable;
-
+ }
/// <summary>
/// mouse click event handler for easy expand triggering in IML
/// </summary>
[XmlIgnore]public bool IsExpandable {
get {
try {
- return GetIsExpandable == null ? true : GetIsExpandable (this);
+ return IsToggleable == null ? true : IsToggleable (this);
} catch (Exception ex) {
System.Diagnostics.Debug.WriteLine ("Not Expandable error: " + ex.ToString ());
return false;
layoutType &= (~LayoutingType.Y);
}
public override int measureRawSize (LayoutingType lt) {
- int totSpace = Math.Max (0, Spacing * (Children.Count (c => c.IsVisible) - 1));
- if (lt == LayoutingType.Width) {
- if (Orientation == Orientation.Horizontal)
- return contentSize.Width + totSpace + 2 * Margin;
- } else if (Orientation == Orientation.Vertical)
- return contentSize.Height + totSpace + 2 * Margin;
+ DbgLogger.StartEvent(DbgEvtType.GOMeasure, this, lt);
+ try {
+
+ int totSpace = Math.Max (0, Spacing * (Children.Count (c => c.IsVisible) - 1));
+ if (lt == LayoutingType.Width) {
+ if (Orientation == Orientation.Horizontal)
+ //return contentSize.Width + totSpace + 2 * Margin;
+ return stretchedGO == null ?
+ contentSize.Width + totSpace + 2 * Margin :
+ contentSize.Width + stretchedGO.measureRawSize(lt) + totSpace + 2 * Margin;
+ } else if (Orientation == Orientation.Vertical)
+ //return contentSize.Height + totSpace + 2 * Margin;
+ return stretchedGO == null ?
+ contentSize.Height + totSpace + 2 * Margin :
+ contentSize.Height + stretchedGO.measureRawSize(lt) + totSpace + 2 * Margin;
- return base.measureRawSize (lt);
+ return base.measureRawSize (lt);
+ } finally {
+ DbgLogger.EndEvent(DbgEvtType.GOMeasure);
+ }
}
public virtual void ComputeChildrenPositions () {
DbgLogger.StartEvent(DbgEvtType.GOComputeChildrenPositions, this);
c.Slot.X = d;
c.OnLayoutChanges (LayoutingType.X);
c.LastSlots.X = c.Slot.X;
+ IsDirty = true;
}
d += c.Slot.Width + Spacing;
}
c.Slot.Y = d;
c.OnLayoutChanges (LayoutingType.Y);
c.LastSlots.Y = c.Slot.Y;
+ IsDirty = true;
}
d += c.Slot.Height + Spacing;
}
- }
- IsDirty = true;
+ }
DbgLogger.EndEvent(DbgEvtType.GOComputeChildrenPositions);
}
Widget stretchedGO = null;
RegisteredLayoutings &= (~layoutType);
if (layoutType == LayoutingType.ArrangeChildren) {
- //allow 1 child to have size to 0 if stack has fixed or streched size policy,
+ //allow 1 child to have stretched size,
//this child will occupy remaining space
//if stack size policy is Fit, no child may have stretch enabled
//in the direction of stacking.
ComputeChildrenPositions ();
-
- //if no layouting remains in queue for item, registre for redraw
- if (RegisteredLayoutings == LayoutingType.None && IsDirty)
- IFace.EnqueueForRepaint (this);
-
return true;
}
w.OnLayoutChanges (LayoutingType.Width);
w.LayoutChanged += OnChildLayoutChanges;
w.LastSlots.Width = w.Slot.Width;
+ DbgLogger.SetMsg(DbgEvtType.GOAdjustStretchedGo, $"new width={newW}");
}
protected void setChildHeight (Widget w, int newH) {
if (w.MaximumSize.Height > 0)
w.OnLayoutChanges (LayoutingType.Height);
w.LayoutChanged += OnChildLayoutChanges;
w.LastSlots.Height = w.Slot.Height;
+ DbgLogger.SetMsg(DbgEvtType.GOAdjustStretchedGo, $"new height={newH}");
}
- internal void adjustStretchedGo (LayoutingType lt) {
+ internal void adjustStretchedGo (LayoutingType lt) {
if (stretchedGO == null)
return;
+ //Console.WriteLine ($"adjust stretched go: {stretchedGO} {lt}");
+ DbgLogger.StartEvent(DbgEvtType.GOAdjustStretchedGo, this);
if (lt == LayoutingType.Width)
setChildWidth (stretchedGO, Math.Max (
ClientRectangle.Width - contentSize.Width - Spacing * (Children.Count - 1), stretchedGO.MinimumSize.Width));
else
setChildHeight (stretchedGO, Math.Max (
- ClientRectangle.Height - contentSize.Height - Spacing * (Children.Count - 1), stretchedGO.MinimumSize.Height));
+ ClientRectangle.Height - contentSize.Height - Spacing * (Children.Count - 1), stretchedGO.MinimumSize.Height));
+ DbgLogger.EndEvent(DbgEvtType.GOAdjustStretchedGo);
}
public override void OnChildLayoutChanges (object sender, LayoutingEventArgs arg) {
DbgLogger.StartEvent(DbgEvtType.GOOnChildLayoutChange, this);
- Widget go = sender as Widget;
- //Debug.WriteLine ("child layout change: " + go.LastSlots.ToString() + " => " + go.Slot.ToString());
- switch (arg.LayoutType) {
- case LayoutingType.Width:
- if (Orientation == Orientation.Horizontal) {
- if (go.Width == Measure.Stretched) {
- if (stretchedGO == null && Width != Measure.Fit) {
- stretchedGO = go;
- contentSize.Width -= go.LastSlots.Width;
- } else if (stretchedGO != go) {
- go.Slot.Width = 0;
- go.Width = Measure.Fit;
- DbgLogger.EndEvent(DbgEvtType.GOOnChildLayoutChange);
- return;
- }
- } else if (stretchedGO == go) {
- stretchedGO = null;
- contentSize.Width += go.Slot.Width;
- } else
- contentSize.Width += go.Slot.Width - go.LastSlots.Width;
+ try {
+ Widget go = sender as Widget;
+ switch (arg.LayoutType) {
+ case LayoutingType.Width:
+ if (Orientation == Orientation.Horizontal) {
+ if (go.Width == Measure.Stretched) {
+ if (stretchedGO == null && Width != Measure.Fit) {
+ stretchedGO = go;
+ contentSize.Width -= go.LastSlots.Width;
+ DbgLogger.SetMsg (DbgEvtType.GOOnChildLayoutChange, $"new stretched go: {stretchedGO}");
+ } else if (stretchedGO != go) {
+ go.Slot.Width = 0;
+ go.Width = Measure.Fit;
+ DbgLogger.SetMsg (DbgEvtType.GOOnChildLayoutChange, $"force stretched width to Fit: {go}");
+ return;
+ }
+ } else if (stretchedGO == go) {
+ stretchedGO = null;
+ contentSize.Width += go.Slot.Width;
+ DbgLogger.SetMsg (DbgEvtType.GOOnChildLayoutChange, $"reset stretched go");
+ } else
+ contentSize.Width += go.Slot.Width - go.LastSlots.Width;
+ adjustStretchedGo (LayoutingType.Width);
- adjustStretchedGo (LayoutingType.Width);
+ if (Width == Measure.Fit)
+ this.RegisterForLayouting (LayoutingType.Width);
- if (Width == Measure.Fit)
- this.RegisterForLayouting (LayoutingType.Width);
-
- this.RegisterForLayouting (LayoutingType.ArrangeChildren);
- DbgLogger.EndEvent(DbgEvtType.GOOnChildLayoutChange);
- return;
- }
- break;
- case LayoutingType.Height:
- if (Orientation == Orientation.Vertical) {
- if (go.Height == Measure.Stretched) {
- if (stretchedGO == null && Height != Measure.Fit) {
- stretchedGO = go;
- contentSize.Height -= go.LastSlots.Height;
- } else if (stretchedGO != go) {
- go.Slot.Height = 0;
- go.Height = Measure.Fit;
- DbgLogger.EndEvent(DbgEvtType.GOOnChildLayoutChange);
- return;
- }
- } else if (stretchedGO == go) {
- stretchedGO = null;
- contentSize.Height += go.Slot.Height;
- } else
- contentSize.Height += go.Slot.Height - go.LastSlots.Height;
+ this.RegisterForLayouting (LayoutingType.ArrangeChildren);
+ return;
+ }
+ break;
+ case LayoutingType.Height:
+ if (Orientation == Orientation.Vertical) {
+ if (go.Height == Measure.Stretched) {
+ if (stretchedGO == null && Height != Measure.Fit) {
+ stretchedGO = go;
+ contentSize.Height -= go.LastSlots.Height;
+ DbgLogger.SetMsg (DbgEvtType.GOOnChildLayoutChange, $"new stretched go: {stretchedGO}");
+ } else if (stretchedGO != go) {
+ go.Slot.Height = 0;
+ go.Height = Measure.Fit;
+ DbgLogger.SetMsg (DbgEvtType.GOOnChildLayoutChange, $"force stretched width to Fit: {go}");
+ return;
+ }
+ } else if (stretchedGO == go) {
+ stretchedGO = null;
+ contentSize.Height += go.Slot.Height;
+ DbgLogger.SetMsg (DbgEvtType.GOOnChildLayoutChange, $"reset stretched go");
+ } else
+ contentSize.Height += go.Slot.Height - go.LastSlots.Height;
- adjustStretchedGo (LayoutingType.Height);
+ adjustStretchedGo (LayoutingType.Height);
- if (Height == Measure.Fit)
- this.RegisterForLayouting (LayoutingType.Height);
+ if (Height == Measure.Fit)
+ this.RegisterForLayouting (LayoutingType.Height);
- this.RegisterForLayouting (LayoutingType.ArrangeChildren);
- DbgLogger.EndEvent(DbgEvtType.GOOnChildLayoutChange);
- return;
+ this.RegisterForLayouting (LayoutingType.ArrangeChildren);
+ return;
+ }
+ break;
}
- break;
+ base.OnChildLayoutChanges (sender, arg);
+ } finally {
+ DbgLogger.EndEvent(DbgEvtType.GOOnChildLayoutChange);
}
- base.OnChildLayoutChanges (sender, arg);
- DbgLogger.EndEvent(DbgEvtType.GOOnChildLayoutChange);
}
#endregion
contentSize.Height = g.LastSlots.Height;
}
- g.LayoutChanged += OnChildLayoutChanges;
- g.RegisteredLayoutings = LayoutingType.None;
+ g.LayoutChanged += OnChildLayoutChanges;
g.RegisterForLayouting (LayoutingType.Sizing | LayoutingType.ArrangeChildren);
}
public override void ClearChildren()
#region GraphicObject overrides
public override int measureRawSize (LayoutingType lt)
{
- if (Children.Count > 0) {
- if (lt == LayoutingType.Width) {
- //if (largestChild == null)
- searchLargestChild ();
- } else {
- //if (tallestChild == null)
- searchTallestChild ();
+ DbgLogger.StartEvent(DbgEvtType.GOMeasure, this, lt);
+ try {
+ if (Children.Count > 0) {
+ if (lt == LayoutingType.Width) {
+ //if (largestChild == null)
+ searchLargestChild ();
+ } else {
+ //if (tallestChild == null)
+ searchTallestChild ();
+ }
}
+ return base.measureRawSize (lt);
+ } finally {
+ DbgLogger.EndEvent(DbgEvtType.GOMeasure);
}
- return base.measureRawSize (lt);
}
public override void OnLayoutChanges (LayoutingType layoutType)
contentSize.Width = g.Slot.Width;
} else if (g == largestChild)
searchLargestChild ();
- else
- break;
+ /*else
+ Console.WriteLine ($"else: {g} largest:{largestChild} {g.RequiredLayoutings} {this.RequiredLayoutings} {largestChild?.RequiredLayoutings}");*/
+ /*break;*/
this.RegisterForLayouting (LayoutingType.Width);
}
break;
contentSize.Height = g.Slot.Height;
} else if (g == tallestChild)
searchTallestChild ();
- else
- break;
+ /*else
+ break;*/
this.RegisterForLayouting (LayoutingType.Height);
}
break;
childrenRWLock.EnterReadLock ();
try {
+ DbgLogger.SetMsg (DbgEvtType.GOSearchLargestChild, $"forced={forceMeasure}");
largestChild = null;
contentSize.Width = 0;
int cw = 0;
if (forceMeasure)
cw = Children [i].measureRawSize (LayoutingType.Width);
- else if (Children[i].Width.IsRelativeToParent || Children [i].RegisteredLayoutings.HasFlag (LayoutingType.Width))
+ else if (Children[i].Width.IsRelativeToParent || Children [i].RequiredLayoutings.HasFlag (LayoutingType.Width))
continue;
else
cw = Children [i].Slot.Width;
childrenRWLock.EnterReadLock ();
try {
+ DbgLogger.SetMsg (DbgEvtType.GOSearchTallestChild, $"forced={forceMeasure}");
+
tallestChild = null;
contentSize.Height = 0;
for (int i = 0; i < Children.Count; i++) {
int ch = 0;
if (forceMeasure)
ch = Children [i].measureRawSize (LayoutingType.Height);
- else if (Children[i].Height.IsRelativeToParent || Children [i].RegisteredLayoutings.HasFlag (LayoutingType.Height))
+ else if (Children[i].Height.IsRelativeToParent || Children [i].RequiredLayoutings.HasFlag (LayoutingType.Height))
continue;
else
ch = Children [i].Slot.Height;
try
{
for (int i = 0; i < Children.Count; i++)
- Children[i].Paint (gr);
+ Children[i].Paint (gr);
} finally {
childrenRWLock.ExitReadLock ();
}
bool ArrangeChildren { get; }
LayoutingType RegisteredLayoutings { get; set; }
+ LayoutingType RequiredLayoutings { get; set; }
void ChildrenLayoutingConstraints(ILayoutable layoutable, ref LayoutingType layoutType);
void RegisterForLayouting(LayoutingType layoutType);
void RegisterClip(Rectangle clip);
return;
int oldTextLength = string.IsNullOrEmpty (_text) ? 0 : _text.Length;
- lock (linesMutex) {
+ lock (linesMutex) {
_text = value;
getLines ();
textMeasureIsUpToDate = false;
if (child != null) {
child.Parent = this;
child.LayoutChanged += OnChildLayoutChanges;
- contentSize = child.Slot.Size;
- child.RegisteredLayoutings = LayoutingType.None;
+ contentSize = child.Slot.Size;
child.RegisterForLayouting (LayoutingType.Sizing);
}
}
public override int measureRawSize (LayoutingType lt)
{
- if (child != null) {
- //force measure of child if sizing on children and child has stretched size
- switch (lt) {
- case LayoutingType.Width:
- if (child.Width.IsRelativeToParent)
- contentSize.Width = child.measureRawSize (LayoutingType.Width);
- break;
- case LayoutingType.Height:
- if (child.Height.IsRelativeToParent)
- contentSize.Height = child.measureRawSize (LayoutingType.Height);
- break;
+ DbgLogger.StartEvent(DbgEvtType.GOMeasure, this, lt);
+ try {
+ if (child != null) {
+ //force measure of child if sizing on children and child has stretched size
+ switch (lt) {
+ case LayoutingType.Width:
+ if (child.Width.IsRelativeToParent)
+ contentSize.Width = child.measureRawSize (LayoutingType.Width);
+ break;
+ case LayoutingType.Height:
+ if (child.Height.IsRelativeToParent)
+ contentSize.Height = child.measureRawSize (LayoutingType.Height);
+ break;
+ }
+ DbgLogger.SetMsg(DbgEvtType.GOMeasure, $"{lt} contentSize:{contentSize}");
}
+ return base.measureRawSize (lt);
+ } finally {
+ DbgLogger.EndEvent(DbgEvtType.GOMeasure);
}
- return base.measureRawSize (lt);
}
public override bool UpdateLayout (LayoutingType layoutType)
{
set {
if (cursorRatio == value)
return;
- cursorRatio = value;
+ if (double.IsFinite(value))
+ cursorRatio = value;
+ else
+ cursorRatio = -1;
updateCursor ();
}
}
void updateCursor () {
- if (cursorRatio < 0)
+ if (cursorRatio < 0 || !double.IsFinite(cursorRatio))
return;
ILayoutable l = cursor?.Parent;
if (l == null)
}
public override int measureRawSize (LayoutingType lt)
{
- if (lt == LayoutingType.Height && Children.Count > 0 && tallestChild == null)
- searchTallestChild ();
- return base.measureRawSize (lt);
+ DbgLogger.StartEvent(DbgEvtType.GOMeasure, this);
+ try {
+ if (lt == LayoutingType.Height && Children.Count > 0 && tallestChild == null)
+ searchTallestChild ();
+ return base.measureRawSize (lt);
+ } finally {
+ DbgLogger.EndEvent(DbgEvtType.GOMeasure);
+ }
}
public override void OnLayoutChanges (LayoutingType layoutType)
{
int ch = 0;
if (forceMeasure)
ch = Children [i].measureRawSize (LayoutingType.Height);
- else if (Children [i].RegisteredLayoutings.HasFlag (LayoutingType.Height))
+ else if (Children [i].RequiredLayoutings.HasFlag (LayoutingType.Height))
continue;
else
ch = Children [i].Slot.Height;
if (_contentContainer == null)
throw new Exception ("TemplatedContainer template Must contain a Container named 'Content'");
_contentContainer.SetChild(value);
+ value.LogicalParent = this;
NotifyValueChanged ("HasContent", HasContent);
}
}
CairoHelpers.CairoRectangle (gr, ClientRectangle, CornerRadius);
gr.Clip ();
}
-
- if (child != null)
- child.Paint (gr);
+
+ child?.Paint (gr);
gr.Restore ();
Monitor.Exit (IFace.UpdateMutex);
}
+ if (g is ISelectable li)
+ li.Selected += Li_Selected;
+
if (iTemp.Expand != null) {
IToggle toggle = g as IToggle;
if (toggle != null) {
toggle.ToggleOn += iTemp.Expand;
- if (o is ICollection)
- toggle.IsToggleable = iTemp.HasSubItems;
- else
- toggle.IsToggleable = new BooleanTestOnInstance ((instance) => true);
+ toggle.IsToggleable = iTemp.HasSubItems;
}
}
- if (g is ISelectable li)
- li.Selected += Li_Selected;
-
g.DataSource = o;
}
/// </summary>
public class Widget : ILayoutable, IValueChange, IDisposable
{
- internal ReaderWriterLockSlim parentRWLock = new ReaderWriterLockSlim();
+ internal ReaderWriterLockSlim parentRWLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
#if DEBUG_LOG
//0 is the main graphic tree, for other obj tree not added to main tree, it range from 1->n
//useful to track events for obj shown later, not on start, or never added to main tree
/// </summary>
public virtual void NotifyValueChanged(string MemberName, object _value)
{
+ DbgLogger.AddEventWithMsg (DbgEvtType.GOSetProperty, $"{MemberName} = {_value}", this);
//Debug.WriteLine ("Value changed: {0}->{1} = {2}", this, MemberName, _value);
if (ValueChanged != null)
ValueChanged.Invoke(this, new ValueChangeEventArgs(MemberName, _value));
}
public void NotifyValueChangedAuto (object _value, [CallerMemberName] string caller = null)
{
+ DbgLogger.AddEventWithMsg (DbgEvtType.GOSetProperty, $"{caller} = {_value}", this);
if (ValueChanged != null)
NotifyValueChanged (caller, _value);
}
}
#region private fields
LayoutingType registeredLayoutings;// = LayoutingType.Sizing;
+ LayoutingType requiredLayoutings = LayoutingType.Sizing;
ILayoutable logicalParent;
ILayoutable parent;
string name;
bool hasFocus;
bool isActive;
bool isHover;
- bool bubbleMouseEvent;
+ DeviceEventType bubbledEvents;
bool mouseRepeat;
bool stickyMouseEnabled;
int stickyMouse;
#endregion
#region ILayoutable
- [XmlIgnore]public LayoutingType RegisteredLayoutings { get => registeredLayoutings; set => registeredLayoutings = value; }
+ [XmlIgnore]public LayoutingType RegisteredLayoutings {
+ get => registeredLayoutings;
+ set => registeredLayoutings = value;
+ }
+ [XmlIgnore]public LayoutingType RequiredLayoutings {
+ get => requiredLayoutings;
+ set => requiredLayoutings = value;
+ }
//TODO: it would save the recurent cost of a cast in event bubbling if parent type was GraphicObject
// or we could add to the interface the mouse events
/// <summary>
return default(Rectangle);
}
}
- public virtual Rectangle getSlot () { return Slot;}
+ public virtual Rectangle getSlot () => Slot;
#endregion
public Point ScreenPointToLocal(Point p){
Point pt = p - ScreenCoordinates (Slot).TopLeft - ClientRectangle.TopLeft;
/// if false, prevent mouse events to bubble to the parent in any case.
/// </summary>
[DesignCategory ("Behaviour")]
- [DefaultValue (true)]
- public virtual bool BubbleMouseEvent {
- get => bubbleMouseEvent;
+ [DefaultValue (DeviceEventType.All)]
+ public virtual DeviceEventType BubbleMouseEvent {
+ get => bubbledEvents;
set {
- if (bubbleMouseEvent == value)
+ if (bubbledEvents == value)
return;
- bubbleMouseEvent = value;
- NotifyValueChangedAuto (bubbleMouseEvent);
+ bubbledEvents = value;
+ NotifyValueChangedAuto (bubbledEvents);
}
}
/// <summary>
}
}
if (styleIndex >= 0) {
- if (pi.PropertyType.IsEnum)//maybe should be in parser..
- defaultValue = Enum.Parse (pi.PropertyType, (string)styling [styleIndex] [pi.Name], true);
- else
+ if (pi.PropertyType.IsEnum) {//maybe should be in parser..
+ if (EnumsNET.FlagEnums.IsFlagEnum (pi.PropertyType))
+ defaultValue = EnumsNET.FlagEnums.ParseFlags (pi.PropertyType, (string)styling [styleIndex] [pi.Name], true, "|");
+ else
+ defaultValue = EnumsNET.Enums.Parse (pi.PropertyType, (string)styling [styleIndex] [pi.Name], true);
+ }else
defaultValue = styling [styleIndex] [pi.Name];
#if DESIGN_MODE
if (parent != null) {
parent.RegisterClip (LastPaintedSlot);
parent.RegisterClip (Slot);
- }//else
- //Console.WriteLine ($"clipping reg canceled (no parent): {this.ToString()}");
+ }else {
+ DbgLogger.SetMsg (DbgEvtType.GOClippingRegistration, "clipping reg canceled (no parent)");
+ }
parentRWLock.ExitReadLock ();
DbgLogger.EndEvent (DbgEvtType.GOClippingRegistration);
DbgLogger.AddEvent (DbgEvtType.AlreadyDisposed | DbgEvtType.GORegisterClip, this);
return;
}
- //we register clip in the parent, if it's dirty, all children will be redrawn
- if (IsDirty && CacheEnabled) {
- //Console.WriteLine ($"regclip canceled Dirty:{IsDirty} Cached:{CacheEnabled}: {this.ToString()}");
- return;
- }
DbgLogger.StartEvent(DbgEvtType.GORegisterClip, this);
try {
+ //we register clip in the parent, if it's dirty, all children will be redrawn
+ if (IsDirty && CacheEnabled) {
+ DbgLogger.SetMsg (DbgEvtType.GORegisterClip, $"regclip canceled Dirty:{IsDirty} Cached:{CacheEnabled}");
+ return;
+ }
Rectangle cb = ClientRectangle;
Rectangle r = clip + cb.Position;
/*if (r.Right > cb.Right)
if (r.Bottom > cb.Bottom)
r.Height -= r.Bottom - cb.Bottom;*/
if (r.Width < 0 || r.Height < 0){
- //Console.WriteLine ($"regclip canceled size w:{r.Width} h:{r.Height}: {this.ToString()}");
+ DbgLogger.SetMsg (DbgEvtType.GORegisterClip, $"regclip canceled size w:{r.Width} h:{r.Height}");
return;
}
if (cacheEnabled)
Clipping.UnionRectangle (r);
if (Parent == null){
- //Console.WriteLine ($"clip chain aborded (no parent): {this.ToString()}");
+ DbgLogger.SetMsg (DbgEvtType.GORegisterClip, "clip chain aborded (no parent)");
return;
}
/*Widget p = Parent as Widget;
IsDirty = true;
if (Width.IsFit || Height.IsFit)
RegisterForLayouting (LayoutingType.Sizing);
- else if (RegisteredLayoutings == LayoutingType.None)
- IFace.EnqueueForRepaint (this);
+ else
+ RegisterForRedraw ();
DbgLogger.EndEvent(DbgEvtType.GORegisterForGraphicUpdate);
}
return;
}
IsDirty = true;
- if (RegisteredLayoutings == LayoutingType.None)
- IFace.EnqueueForRepaint (this);
+ RegisterForRepaint ();
}
/// <summary>
/// query a repaint, if control is cached, cache will not be updated and simply repainted.
///
/// </remark>
public void RegisterForRepaint () {
- if (RegisteredLayoutings == LayoutingType.None && !IsDirty)
+ if (RequiredLayoutings == LayoutingType.None)// && !IsDirty)
IFace.EnqueueForRepaint (this);
}
#endregion
/// <summary> return size of content + margins </summary>
public virtual int measureRawSize (LayoutingType lt) {
- DbgLogger.StartEvent(DbgEvtType.GOMeasure, this, lt);
-
- int tmp = lt == LayoutingType.Width ?
- contentSize.Width + 2 * margin: contentSize.Height + 2 * margin;
-
- DbgLogger.EndEvent(DbgEvtType.GOMeasure);
- return tmp;
+ DbgLogger.StartEvent(DbgEvtType.GOMeasure, this);
+ try {
+ DbgLogger.SetMsg(DbgEvtType.GOMeasure, $"{lt} contentSize:{contentSize}");
+ return lt == LayoutingType.Width ?
+ contentSize.Width + 2 * margin : contentSize.Height + 2 * margin;
+ } finally {
+ DbgLogger.EndEvent(DbgEvtType.GOMeasure);
+ }
}
internal bool firstUnresolvedFitWidth (out Widget ancestorInUnresolvedFit)
}
return false;
}
+ protected bool stretchedInFit (LayoutingType lt) {
+
+ if (Parent == null)
+ return false;
+ Widget p = Parent as Widget;
+ if (lt == LayoutingType.Width) {
+ if (!Width.IsRelativeToParent)
+ return false;
+ while (p.Width.IsRelativeToParent) {
+ p = p.Parent as Widget;
+ if (p == null)
+ return false;
+ }
+ return p.Width.IsFit;
+ }
+ if (!Height.IsRelativeToParent)
+ return false;
+ while (p.Height.IsRelativeToParent) {
+ p = p.Parent as Widget;
+ if (p == null)
+ return false;
+ }
+ return p.Height.IsFit;
+ }
- public virtual bool ArrangeChildren { get { return false; } }
+ public virtual bool ArrangeChildren => false;
/// <summary>
/// Used to prevent some layouting type in children. For example, in the GenericStack,
/// x layouting is dismissed in the direction of the stacking to let the parent
/// <param name="layoutType">The currently registering layouting types</param>
public virtual void ChildrenLayoutingConstraints(ILayoutable layoutable, ref LayoutingType layoutType){ }
/// <summary> Query a layouting for the type pass as parameter, redraw only if layout changed. </summary>
+
+ internal ReaderWriterLockSlim layoutMutex = new ReaderWriterLockSlim (LockRecursionPolicy.SupportsRecursion);
public virtual void RegisterForLayouting(LayoutingType layoutType){
if (disposed) {
DbgLogger.AddEvent (DbgEvtType.AlreadyDisposed, this);
return;
}
- if (Parent == null)
- return;
- DbgLogger.StartEvent (DbgEvtType.GOLockLayouting, this);
+ parentRWLock.EnterReadLock ();
+
try {
- lock (IFace.LayoutMutex) {
+ if (Parent == null)
+ return;
+
+ layoutMutex.EnterWriteLock ();
+
+ try {
+
+
//prevent queueing same LayoutingType for this
layoutType &= (~RegisteredLayoutings);
if (layoutType == LayoutingType.None)
return;
- //enqueue LQI LayoutingTypes separately
- if (layoutType.HasFlag (LayoutingType.Width))
- IFace.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.Width, this));
- if (layoutType.HasFlag (LayoutingType.Height))
- IFace.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.Height, this));
- if (layoutType.HasFlag (LayoutingType.X))
- IFace.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.X, this));
- if (layoutType.HasFlag (LayoutingType.Y))
- IFace.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.Y, this));
- if (layoutType.HasFlag (LayoutingType.ArrangeChildren))
- IFace.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.ArrangeChildren, this));
+ RequiredLayoutings |= layoutType;
+ } finally {
+ layoutMutex.ExitWriteLock ();
}
- } finally {
+
+ DbgLogger.StartEvent (DbgEvtType.GOLockLayouting, this);
+ lock (IFace.LayoutMutex) {
+ layoutMutex.EnterWriteLock ();
+ //enqueue LQI LayoutingTypes separately
+ if (layoutType.HasFlag (LayoutingType.Width))
+ IFace.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.Width, this));
+ if (layoutType.HasFlag (LayoutingType.Height))
+ IFace.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.Height, this));
+ if (layoutType.HasFlag (LayoutingType.X))
+ IFace.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.X, this));
+ if (layoutType.HasFlag (LayoutingType.Y))
+ IFace.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.Y, this));
+ if (layoutType.HasFlag (LayoutingType.ArrangeChildren))
+ IFace.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.ArrangeChildren, this));
+ layoutMutex.ExitWriteLock ();
+ }
DbgLogger.EndEvent (DbgEvtType.GOLockLayouting);
+ } finally {
+ parentRWLock.ExitReadLock ();
}
}
case LayoutingType.X:
if (left == 0) {
- if (Parent.RegisteredLayoutings.HasFlag (LayoutingType.Width) ||
- RegisteredLayoutings.HasFlag (LayoutingType.Width))
+ if (Parent.RequiredLayoutings.HasFlag (LayoutingType.Width) ||
+ RequiredLayoutings.HasFlag (LayoutingType.Width))
return false;
switch (horizontalAlignment) {
case LayoutingType.Y:
if (top == 0) {
- if (Parent.RegisteredLayoutings.HasFlag (LayoutingType.Height) ||
- RegisteredLayoutings.HasFlag (LayoutingType.Height))
+ if (Parent.RequiredLayoutings.HasFlag (LayoutingType.Height) ||
+ RequiredLayoutings.HasFlag (LayoutingType.Height))
return false;
switch (verticalAlignment) {
break;
}
- //if no layouting remains in queue for item, registre for redraw
- if (this.registeredLayoutings == LayoutingType.None && IsDirty)
- IFace.EnqueueForRepaint (this);
-
return true;
}
#endregion
/// of the widget </summary>
public virtual void Paint (Context ctx)
{
- /*if (!IsVisible)
- return;*/
+ if (!IsVisible)
+ return;
DbgLogger.StartEvent (DbgEvtType.GOPaint, this);
if (disposed || Slot.Height < 0 || Slot.Width < 0 || parent == null){
#if DEBUG
- Console.ForegroundColor = ConsoleColor.Red;
if (disposed)
- System.Diagnostics.Debug.WriteLine ($"Paint disposed widget: {this}");
- Console.ForegroundColor = ConsoleColor.DarkRed;
+ DbgLogger.SetMsg (DbgEvtType.GOPaint, "Paint disposed widget");
if (Slot.Height < 0 || Slot.Width < 0)
- System.Diagnostics.Debug.WriteLine ($"Paint slot invalid ({Slot}): {this}");
- Console.ForegroundColor = ConsoleColor.DarkMagenta;
+ DbgLogger.SetMsg (DbgEvtType.GOPaint, $"Paint slot invalid ({Slot})");
if (parent == null)
- System.Diagnostics.Debug.WriteLine ($"Paint with parent == null: {this}");
- Console.ForegroundColor = ConsoleColor.Magenta;
- if (!isVisible)
- System.Diagnostics.Debug.WriteLine ($"Paint invisible widget: {this}");
- Console.ResetColor ();
+ DbgLogger.SetMsg (DbgEvtType.GOPaint, "Paint with no parent");
#endif
DbgLogger.AddEvent (DbgEvtType.Warning);
DbgLogger.EndEvent (DbgEvtType.GOPaint);
if (MouseMove != null)
MouseMove.Invoke (this, e);
- else if (!e.Handled && BubbleMouseEvent)
+ else if (!e.Handled && BubbleMouseEvent.HasFlag (DeviceEventType.MouseMove))
FocusParent?.onMouseMove (sender, e);
}
/// <summary>
if (MouseDown != null)
MouseDown?.Invoke (this, e);
- else if (!e.Handled && BubbleMouseEvent)
+ else if (!e.Handled && BubbleMouseEvent.HasFlag (DeviceEventType.ButtonDown))
FocusParent?.onMouseDown (sender, e);
}
/// <summary>
if (MouseUp != null)
MouseUp.Invoke (this, e);
- else if (!e.Handled && BubbleMouseEvent)
+ else if (!e.Handled && BubbleMouseEvent.HasFlag (DeviceEventType.ButtonUp))
FocusParent?.onMouseUp (sender, e);
}
/// <summary>
public virtual void onMouseClick(object sender, MouseButtonEventArgs e){
if (MouseClick != null)
MouseClick.Invoke (this, e);
- else if (!e.Handled && BubbleMouseEvent)
+ else if (!e.Handled && BubbleMouseEvent.HasFlag (DeviceEventType.MouseClick))
FocusParent?.onMouseClick (sender, e);
}
/// <summary>
public virtual void onMouseDoubleClick(object sender, MouseButtonEventArgs e){
if (MouseDoubleClick != null)
MouseDoubleClick.Invoke (this, e);
- else if (!e.Handled && BubbleMouseEvent)
+ else if (!e.Handled && BubbleMouseEvent.HasFlag (DeviceEventType.MouseClick))
FocusParent?.onMouseDoubleClick (sender, e);
}
public virtual void onMouseWheel(object sender, MouseWheelEventArgs e){
if (MouseWheelChanged != null)
MouseWheelChanged.Invoke (this, e);
- else if (!e.Handled && BubbleMouseEvent)
+ else if (!e.Handled && BubbleMouseEvent.HasFlag (DeviceEventType.MouseWheel))
FocusParent?.onMouseWheel (sender, e);
}
public virtual void onMouseEnter(object sender, MouseMoveEventArgs e)
Disabled.Raise (this, e);
}
protected virtual void onParentChanged(object sender, DataSourceChangeEventArgs e) {
- DbgLogger.AddEvent (DbgEvtType.GONewParent, this, e);
+ DbgLogger.AddEvent (DbgEvtType.GONewParent, this, e.NewDataSource);
ParentChanged.Raise (this, e);
if (logicalParent == null)
LogicalParentChanged.Raise (this, e);
}
- if (IFace.ActiveWidget != null) {
- if (IFace.ActiveWidget.IsOrIsInside (this))
- IFace.ActiveWidget = null;
- }
+ /*if (IFace.ActiveWidget != null) {
+ if (IsActive) {
+
+
+ } else if (this.Contains (IFace.ActiveWidget))
+ IFace.ActiveWidget = this;
+ }*/
if (IFace.FocusedWidget != null) {
if (IFace.FocusedWidget.IsOrIsInside (this))
IFace.FocusedWidget = null;
SW,
SE,
}
-
+ [Flags]
+ public enum Status {
+ None = 0x00,
+ Normal = 0x01,
+ Minimized = 0x02,
+ Maximized= 0x04
+ }
string _icon;
bool resizable;
bool movable;
bool alwaysOnTop = false;
Rectangle savedBounds;
- bool _minimized = false;
+ bool wasResizable;
+
+ Status currentState, allowedStates;
protected Direction currentDirection = Direction.None;
+
#region Events
public event EventHandler Closing;
public event EventHandler Maximized;
public event EventHandler Unmaximized;
public event EventHandler Minimize;
#endregion
+ [DefaultValue("Normal|Minimized|Maximized")]
+ public Status AllowedStates {
+ get => allowedStates;
+ set {
+ if (allowedStates == value)
+ return;
+ allowedStates = value;
+ NotifyValueChangedAuto (allowedStates);
+
+ if (currentState == Status.None)
+ return;
+
+ initCommands();
+
+ if (allowedStates.HasFlag (currentState)) {
+ CMDNormalize.CanExecute = currentState != Status.Normal & allowedStates.HasFlag (Status.Normal);
+ CMDMinimize.CanExecute = currentState != Status.Minimized & allowedStates.HasFlag (Status.Minimized);
+ CMDMaximize.CanExecute = currentState != Status.Maximized & allowedStates.HasFlag (Status.Maximized);
+ } else {
+ if (allowedStates.HasFlag (Status.Normal))
+ CurrentState = Status.Normal;
+ else if (allowedStates.HasFlag (Status.Maximized))
+ CurrentState = Status.Maximized;
+ else
+ CurrentState = Status.Minimized;
+ }
+ }
+ }
+ [DefaultValue("Normal")]
+ public Status CurrentState {
+ get => currentState;
+ set {
+ Status newState = value;
+ if (!allowedStates.HasFlag (newState)) {
+ if (allowedStates.HasFlag (Status.Normal))
+ newState = Status.Normal;
+ else if (allowedStates.HasFlag (Status.Maximized))
+ newState = Status.Maximized;
+ else
+ newState = Status.Minimized;
+ }
+
+ if (currentState == newState)
+ return;
+
+ if (currentState == Status.Normal) {
+ savedBounds = LastPaintedSlot;
+ wasResizable = Resizable;
+ }
+
+ currentState = value;
+ NotifyValueChangedAuto (currentState);
+
+ initCommands();
+
+ switch (currentState) {
+ case Status.Maximized:
+ Left = Top = 0;
+ RegisterForLayouting (LayoutingType.Positioning);
+ Width = Height = Measure.Stretched;
+ Resizable = false;
+ CMDNormalize.CanExecute = allowedStates.HasFlag (Status.Normal);
+ CMDMinimize.CanExecute = allowedStates.HasFlag (Status.Minimized);
+ CMDMaximize.CanExecute = false;
+ break;
+ case Status.Minimized:
+ Width = 200;
+ Height = 20;
+ Resizable = false;
+ CMDNormalize.CanExecute = allowedStates.HasFlag (Status.Normal);
+ CMDMinimize.CanExecute = false;
+ CMDMaximize.CanExecute = allowedStates.HasFlag (Status.Maximized);
+ break;
+ case Status.Normal:
+ Left = savedBounds.Left;
+ Top = savedBounds.Top;
+ Width = savedBounds.Width;
+ Height = savedBounds.Height;
+ Resizable = wasResizable;
+ CMDNormalize.CanExecute = false;
+ CMDMinimize.CanExecute = allowedStates.HasFlag (Status.Minimized);
+ CMDMaximize.CanExecute = allowedStates.HasFlag (Status.Maximized);
+ break;
+ }
+ }
+ }
#region CTOR
protected Window() {}
- public Window (Interface iface, string style = null) : base (iface, style) { }
+ public Window (Interface iface, string style = null) : base (iface, style) {}
#endregion
Widget moveHandle, sizingHandle;
+ public Command CMDMinimize, CMDMaximize, CMDNormalize, CMDClose;
+ CommandGroup commands;
+
+ public CommandGroup Commands {
+ get => commands;
+ set {
+ if (commands == value)
+ return;
+ commands = value;
+ NotifyValueChangedAuto (commands);
+ }
+ }
+ /*public Command CMDMinimize = new Command ("Minimize", (sender) =>
+ {(sender as Window).CurrentState = Status.Minimized;}, "#Crow.Icons.minimize.svg", false);
+ public Command CMDMaximize = new Command ("Maximize", (sender) =>
+ {(sender as Window).CurrentState = Status.Maximized;}, "#Crow.Icons.maximize.svg", false);
+ public Command CMDNormalize = new Command ("Normalize", (sender) =>
+ {(sender as Window).CurrentState = Status.Normal;}, "#Crow.Icons.normalize.svg", false);
+ public Command CMDClose = new Command ("Close", (sender) =>
+ {(sender as Window).close ();}, "#Crow.Icons.exit2.svg", true);*/
+
+
+ void initCommands () {
+ if (CMDMinimize != null)
+ return;
+ CMDMinimize = new Command ("Minimize", () => CurrentState = Status.Minimized, "#Crow.Icons.minimize.svg", allowedStates.HasFlag (Status.Minimized));
+ CMDMaximize = new Command ("Maximize", () => CurrentState = Status.Maximized, "#Crow.Icons.maximize.svg", allowedStates.HasFlag (Status.Maximized));
+ CMDNormalize = new Command ("Normalize", () => CurrentState = Status.Normal, "#Crow.Icons.normalize.svg", false);
+ CMDClose = new Command ("Close", close, "#Crow.Icons.exit2.svg", true);
+
+ Commands = new CommandGroup(CMDMinimize, CMDNormalize, CMDMaximize, CMDClose);
+ }
+
+
#region TemplatedContainer overrides
protected override void loadTemplate(Widget template = null)
{
+ initCommands ();
+
base.loadTemplate (template);
- NotifyValueChanged ("ShowNormal", false);
- NotifyValueChanged ("ShowMinimize", true);
- NotifyValueChanged ("ShowMaximize", true);
+ initHandles ();
+ }
+ protected void initHandles () {
moveHandle = child?.FindByName ("MoveHandle");
sizingHandle = child?.FindByName ("SizeHandle");
- if (sizingHandle == null)
- return;
- //sizingHandle.Unhover += (arg1, arg2) => currentDirection = Direction.None;
- sizingHandle.Unhover += SizingHandle_Unhover;
+ if (sizingHandle != null) {
+ sizingHandle.Unhover += SizingHandle_Unhover;
+ sizingHandle.MouseDown += setResizeOn;
+ sizingHandle.MouseUp += setResizeOff;
+ }
+
+ if (moveHandle != null) {
+ moveHandle.MouseDown += setMoveOn;
+ moveHandle.MouseUp += setMoveOff;
+ }
+ }
+ protected void resetHandles () {
+ if (sizingHandle != null) {
+ sizingHandle.Unhover -= SizingHandle_Unhover;
+ sizingHandle.MouseDown -= setResizeOn;
+ sizingHandle.MouseUp -= setResizeOff;
+ }
+
+ if (moveHandle != null) {
+ moveHandle.MouseDown -= setMoveOn;
+ moveHandle.MouseUp -= setMoveOff;
+ }
+ moveHandle = null;
+ sizingHandle = null;
}
+ void setResizeOn (object o, EventArgs e) => resize = true;
+ void setResizeOff (object o, EventArgs e) => resize = false;
+ void setMoveOn (object o, EventArgs e) => move = true;
+ void setMoveOff (object o, EventArgs e) => move = false;
+
- private void SizingHandle_Unhover (object sender, EventArgs e) {
+ bool move, resize;
+
+ void SizingHandle_Unhover (object sender, EventArgs e) {
currentDirection = Direction.None;
NotifyValueChanged ("CurDir", currentDirection);
}
- #endregion
+ #endregion
- #region public properties
- [DefaultValue("#Crow.Icons.crow.svg")]
+ #region public properties
+ [DefaultValue("#Crow.Icons.crow.svg")]
public string Icon {
get => _icon;
set {
}
}
[DefaultValue(false)]
- public bool IsMinimized {
- get => _minimized;
- set{
- if (value == IsMinimized)
- return;
-
- _minimized = value;
- _contentContainer.IsVisible = !_minimized;
-
- NotifyValueChangedAuto (_minimized);
- }
- }
- [XmlIgnore]public bool IsMaximized =>
- Width == Measure.Stretched & Height == Measure.Stretched & !_minimized;
- [XmlIgnore]public bool IsNormal => !(IsMaximized|_minimized);
- [DefaultValue(false)]
public bool AlwaysOnTop {
get => modal ? true : alwaysOnTop;
set {
else
currentHeight = this.Slot.Height;
- switch (currentDirection) {
- case Direction.None:
+ if (move) {
this.Left = currentLeft + XDelta;
this.Top = currentTop + YDelta;
- break;
+ return;
+ }
+
+ if (!resize)
+ return;
+
+ switch (currentDirection) {
case Direction.N:
this.Height = currentHeight - YDelta;
if (this.Height == currentHeight - YDelta)
//}
}
- bool maySize => sizingHandle == null ? false : resizable & sizingHandle.IsHover;
- bool mayMove => moveHandle == null ? false : movable & moveHandle.IsHover;
+ bool maySize => sizingHandle != null && resizable && sizingHandle.IsHover;
+ bool mayMove => moveHandle != null && movable;
#region GraphicObject Overrides
public override void onMouseMove (object sender, MouseMoveEventArgs e)
{
base.onMouseMove (sender, e);
- if (maySize || mayMove) {
- if (grabMouse) {
- moveAndResize (e.XDelta, e.YDelta, currentDirection);
- return;
- }
- }else
+ if (!(mayMove || maySize))
return;
+ if (move || resize) {
+ moveAndResize (e.XDelta, e.YDelta, currentDirection);
+ return;
+ }
+
Point m = Parent is Widget ? (Parent as Widget).ScreenPointToLocal (e.Position) : e.Position;
if (maySize) {
return;
switch (currentDirection) {
- case Direction.None:
+ /*case Direction.None:
IFace.MouseCursor = MouseCursor.move;
- break;
+ break;*/
case Direction.N:
IFace.MouseCursor = MouseCursor.top_side;
break;
IFace.MouseCursor = MouseCursor.top_left_arrow;
NotifyValueChanged ("CurDir", currentDirection);
}
- bool grabMouse;
- public override void onMouseDown (object sender, MouseButtonEventArgs e)
- {
- NotifyValueChanged ("GrabMouse", true);
- grabMouse = true;
- e.Handled = true;
- base.onMouseDown (sender, e);
- }
- public override void onMouseUp (object sender, MouseButtonEventArgs e)
- {
- NotifyValueChanged ("GrabMouse", false);
- NotifyValueChanged ("CurDir", currentDirection);
- grabMouse = false;
- e.Handled = true;
- base.onMouseUp (sender, e);
- }
public override bool MouseIsIn (Point m)
{
return modal ? true : base.MouseIsIn (m);
}
#endregion
- protected void onMaximized (object sender, EventArgs e){
+ /*protected void onMaximized (){
lock (IFace.LayoutMutex) {
- if (!IsMinimized)
- savedBounds = this.LastPaintedSlot;
- Left = Top = 0;
- RegisterForLayouting (LayoutingType.Positioning);
- Width = Height = Measure.Stretched;
- IsMinimized = false;
- Resizable = false;
NotifyValueChanged ("ShowNormal", true);
NotifyValueChanged ("ShowMinimize", true);
NotifyValueChanged ("ShowMaximize", false);
}
- Maximized.Raise (sender, e);
+ Maximized.Raise (this, null);
}
- protected void onUnmaximized (object sender, EventArgs e){
+ protected void onUnmaximized (){
lock (IFace.LayoutMutex) {
- Left = savedBounds.Left;
- Top = savedBounds.Top;
- Width = savedBounds.Width;
- Height = savedBounds.Height;
- IsMinimized = false;
- Resizable = true;
NotifyValueChanged ("ShowNormal", false);
NotifyValueChanged ("ShowMinimize", true);
NotifyValueChanged ("ShowMaximize", true);
}
- Unmaximized.Raise (sender, e);
+ Unmaximized.Raise (this, null);
}
- protected void onMinimized (object sender, EventArgs e){
+ protected void onMinimized (){
lock (IFace.LayoutMutex) {
if (IsNormal)
- savedBounds = this.LastPaintedSlot;
- Width = 200;
- Height = 20;
- Resizable = false;
- IsMinimized = true;
- NotifyValueChanged ("ShowNormal", true);
- NotifyValueChanged ("ShowMinimize", false);
- NotifyValueChanged ("ShowMaximize", true);
+
}
- Minimize.Raise (sender, e);
- }
+ Minimize.Raise (this, null);
+ }*/
public void onQuitPress (object sender, MouseButtonEventArgs e)
{
public override int measureRawSize (LayoutingType lt)
{
int tmp = 0;
- //Wrapper can't fit in the opposite direction of the wrapper, this func is called only if Fit
- if (lt == LayoutingType.Width) {
- if (Orientation == Orientation.Vertical) {
- Width = Measure.Stretched;
+ DbgLogger.StartEvent(DbgEvtType.GOMeasure, this);
+ try {
+ DbgLogger.SetMsg(DbgEvtType.GOMeasure, $"{lt}");
+
+ //Wrapper can't fit in the opposite direction of the wrapper, this func is called only if Fit
+ if (lt == LayoutingType.Width) {
+ if (Orientation == Orientation.Vertical) {
+ Width = Measure.Stretched;
+ return -1;
+ } else if (RequiredLayoutings.HasFlag (LayoutingType.Height))
+ return -1;
+ else {
+ int dy = 0;
+ int largestChild = 0;
+
+ childrenRWLock.EnterReadLock();
+ try {
+ foreach (Widget c in Children) {
+ if (!c.IsVisible)
+ continue;
+ if (c.Height.IsRelativeToParent &&
+ c.RequiredLayoutings.HasFlag (LayoutingType.Height)) {
+ return -1;
+ }
+ if (dy + c.Slot.Height > ClientRectangle.Height) {
+ dy = 0;
+ tmp += largestChild + Spacing;
+ largestChild = c.Slot.Width;
+ } else if (largestChild < c.Slot.Width)
+ largestChild = c.Slot.Width;
+
+ dy += c.Slot.Height + Spacing;
+ }
+ } finally {
+ childrenRWLock.ExitReadLock ();
+ }
+
+ if (dy == 0)
+ tmp -= Spacing;
+ return tmp + largestChild + 2 * Margin;
+ }
+ } else if (Orientation == Orientation.Horizontal) {
+ Height = Measure.Stretched;
return -1;
- } else if (RegisteredLayoutings.HasFlag (LayoutingType.Height))
+ } else if (RequiredLayoutings.HasFlag (LayoutingType.Width))
return -1;
else {
- int dy = 0;
- int largestChild = 0;
+ int dx = 0;
+ int tallestChild = 0;
childrenRWLock.EnterReadLock();
try {
foreach (Widget c in Children) {
if (!c.IsVisible)
continue;
- if (c.Height.IsRelativeToParent &&
- c.RegisteredLayoutings.HasFlag (LayoutingType.Height)) {
+ if (c.Width.IsRelativeToParent &&
+ c.RequiredLayoutings.HasFlag (LayoutingType.Width)) {
return -1;
}
- if (dy + c.Slot.Height > ClientRectangle.Height) {
- dy = 0;
- tmp += largestChild + Spacing;
- largestChild = c.Slot.Width;
- } else if (largestChild < c.Slot.Width)
- largestChild = c.Slot.Width;
-
- dy += c.Slot.Height + Spacing;
+ if (dx + c.Slot.Width > ClientRectangle.Width) {
+ dx = 0;
+ tmp += tallestChild + Spacing;
+ tallestChild = c.Slot.Height;
+ } else if (tallestChild < c.Slot.Height)
+ tallestChild = c.Slot.Height;
+
+ dx += c.Slot.Width + Spacing;
}
} finally {
- childrenRWLock.ExitReadLock ();
+ childrenRWLock.ExitReadLock();
}
- if (dy == 0)
+ if (dx == 0)
tmp -= Spacing;
- return tmp + largestChild + 2 * Margin;
- }
- } else if (Orientation == Orientation.Horizontal) {
- Height = Measure.Stretched;
- return -1;
- } else if (RegisteredLayoutings.HasFlag (LayoutingType.Width))
- return -1;
- else {
- int dx = 0;
- int tallestChild = 0;
-
- childrenRWLock.EnterReadLock();
- try {
- foreach (Widget c in Children) {
- if (!c.IsVisible)
- continue;
- if (c.Width.IsRelativeToParent &&
- c.RegisteredLayoutings.HasFlag (LayoutingType.Width)) {
- return -1;
- }
- if (dx + c.Slot.Width > ClientRectangle.Width) {
- dx = 0;
- tmp += tallestChild + Spacing;
- tallestChild = c.Slot.Height;
- } else if (tallestChild < c.Slot.Height)
- tallestChild = c.Slot.Height;
-
- dx += c.Slot.Width + Spacing;
- }
- } finally {
- childrenRWLock.ExitReadLock();
- }
-
- if (dx == 0)
- tmp -= Spacing;
- return tmp + tallestChild + 2 * Margin;
+ return tmp + tallestChild + 2 * Margin;
}
+ } finally {
+ DbgLogger.EndEvent(DbgEvtType.GOMeasure);
+ }
}
public override bool UpdateLayout (LayoutingType layoutType)
RegisteredLayoutings &= (~layoutType);
if (layoutType == LayoutingType.ArrangeChildren) {
- if ((RegisteredLayoutings & LayoutingType.Sizing) != 0)
+ if ((RequiredLayoutings & LayoutingType.Sizing) != 0)
return false;
ComputeChildrenPositions ();
-
- //if no layouting remains in queue for item, registre for redraw
- if (RegisteredLayoutings == LayoutingType.None && IsDirty)
- IFace.EnqueueForRepaint (this);
-
return true;
}
Thread.Sleep(1000);
}
- if (IsDirty)
- delRegisterForRepaint();
+ if (IsDirty) {
+ delRegisterForRepaint();
+ //Console.WriteLine ("[DbgIFace]RegisterForRepaint");
+ }
Thread.Sleep (UPDATE_INTERVAL);
}
}
public override void ForceMousePosition()
{
- Point p = (Point)delGetScreenCoordinate();
+ Point p = Point.Parse(delGetScreenCoordinate().ToString());
Glfw.Glfw3.SetCursorPosition (WindowHandle, p.X + MousePosition.X, p.Y + MousePosition.Y);
}
}
-}
\ No newline at end of file
+}
}
protected override void UpdateCache(Context ctx)
{
- if (initialized && bmp != null) {
+ if (initialized && bmp != null) {
paintCache (ctx, Slot + Parent.ClientRectangle.Position);
delResetDirtyState ();
}
<Label Text="Instance:" Foreground="White" Width="50%" />
<Label Text="{InstanceIndex}" Foreground="White" Background="Onyx" Width="Stretched" TextAlignment="Center"/>
</HorizontalStack>
+ <Label Text="{Message}" Foreground="White" Background="Onyx" Width="Stretched" Visible="{HasMessage}" Margin="2" Tooltip="{}"/>
<HorizontalStack Height="Fit" Width="Stretched" Spacing="2" Background="DimGrey" Margin="2">
<Label Text="Duration(ms):" Foreground="White" Width="50%" />
<Label Text="{DurationMS}" Foreground="White" Background="Onyx" Width="Stretched" TextAlignment="Right"/>
<Label Text="Instance:" Foreground="White" Width="50%" />
<Label Text="{InstanceIndex}" Foreground="White" Background="Onyx" Width="Stretched" TextAlignment="Center"/>
</HorizontalStack>
+ <Label Text="{Message}" Foreground="White" Background="Onyx" Width="Stretched" Visible="{HasMessage}" Margin="2" Tooltip="{}"/>
<HorizontalStack Height="Fit" Width="Stretched" Spacing="2" Background="DimGrey" Margin="2">
<Label Text="Duration:" Foreground="White" Width="50%" />
<Label Text="{DurationMS}" Foreground="White" Background="Onyx" Width="Stretched" TextAlignment="Right"/>
<ListItem ContextCommands="{GetCommands}"
Selected="{/exp.Background=${ControlHighlight}}"
Unselected="{/exp.Background=Transparent}">
- <Expandable Name="exp" Caption="{Name}" MouseDoubleClick="/onClickForExpand" BubbleMouseEvent="true">
+ <Expandable Name="exp" Caption="{Name}" MouseDoubleClick="/onClickForExpand" >
<Template>
<VerticalStack>
<Border CornerRadius="2" Margin="0" Height="Fit" MouseDoubleClick="./onClickForExpand"
Suggestions = (new string[] {"Stretched", "Fit"}).
Where (s => s.StartsWith (currentToken.AsString (_text), StringComparison.OrdinalIgnoreCase)).ToList ();
else if (pi.PropertyType == typeof (Fill))
- Suggestions = FastEnumUtility.FastEnum.GetValues<Colors> ()
+ Suggestions = EnumsNET.Enums.GetValues<Colors> ()
.Where (s => s.ToString().StartsWith (currentToken.AsString (_text), StringComparison.OrdinalIgnoreCase)).ToList ();
}
} else if (currentToken.Type == TokenType.AttributeValueOpen) {
else if (pi.PropertyType == typeof(bool))
Suggestions = new List<string> (new string[] {"true", "false"});
else if (pi.PropertyType == typeof (Fill))
- Suggestions = FastEnumUtility.FastEnum.GetValues<Colors> ().ToList ();
+ Suggestions = EnumsNET.Enums.GetValues<Colors> ().ToList ();
else if (pi.PropertyType == typeof (Measure))
Suggestions = new List<string> (new string[] {"Stretched", "Fit"});
}
}
- IList<Colors> testList = (IList<Colors>)FastEnumUtility.FastEnum.GetValues<Colors>().ToList();//.ColorDic.Values//.OrderBy(c=>c.Hue)
+ 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<Colors> TestList
get { return testList; }
}
void OnClear(object sender, MouseButtonEventArgs e) => TestList = null;
- void OnLoadList(object sender, MouseButtonEventArgs e) => TestList = (IList<Colors>)FastEnumUtility.FastEnum.GetValues<Colors>().ToList();
+ void OnLoadList(object sender, MouseButtonEventArgs e) => TestList = (IList<Colors>)EnumsNET.Enums.GetValues<Colors>().ToList();
string curSources = "";
<?xml version="1.0" encoding="UTF-8"?>
-<Window Caption="Showcase" Height="90%" Width="90%" Background="DarkGrey">
+<Window Caption="Showcase" Height="90%" Width="91%" Background="DarkGrey">
<HorizontalStack>
<VerticalStack Width="30%" Margin="5">
<ListBox Data="{PerfMeasures}" Height="Fit">
--- /dev/null
+<?xml version="1.0"?>
+<VerticalStack>
+ <Widget Name="go" Width="100" Height="60" Background="DarkBlue"/>
+ <Widget Width="100" Height="60" Background="{../colorPicker.CurrentColor}"/>
+ <Label Text="{../colorPicker.CurrentColor}"/>
+ <ColorPicker CurrentColor="{²../go.Background}" Name="colorPicker" Background="DimGrey" MinimumSize="0,0" Width="300" Template="/mnt/devel/CrowIDE/Crow/Samples/common/ui/templates/ColorPicker.template" />
+</VerticalStack>
\ No newline at end of file
<?xml version="1.0"?>
-
<ListBox Data="{TestList}" Width="Fit" Focusable="true" >
<Template>
<Scroller Name="ItemsScroller" Height="Stretched" Background="Onyx" Margin="10">
<Label Text="{fps}" IsEnabled="true" Font="30"/>
<Label Text="{fps}" IsEnabled="false" Font="30" Background="SeaGreen"/>
<Label Text="{fps}" IsEnabled="true" Font="30" Background="SeaGreen"/>
- <Button Caption="Button" IsEnabled="true" Background="Grey"/>
- <Button Caption="Button" IsEnabled="false" Background="Grey"/>
+ <Button Caption="Button" IsEnabled="true" Background="DimGrey"/>
+ <Button Caption="Button" IsEnabled="false" Background="DimGrey"/>
<Button Caption="Button" IsEnabled="true" />
<Button Caption="Button" IsEnabled="false" />
<Spinner Fit="true"/>
--- /dev/null
+<Window CurrentState="Normal" Width="200" Height="200"/>
\ No newline at end of file
--- /dev/null
+<ColorPicker Width="Fit" Height="Stretched" Background="Onyx">
+ <Template>
+ <ListBox Data="{./AvailableColors}" Margin="15">
+ <Template>
+ <Scroller>
+ <VerticalStack Name="ItemsContainer" Height="Fit" VerticalAlignment="Top" Background="DarkGrey" Margin="5" />
+ </Scroller>
+ </Template>
+ <ItemTemplate>
+ <ListItem Margin="1" Width="Stretched"
+ Selected="{Background=RoyalBlue}"
+ Unselected="{Background=Transparent}">
+ <HorizontalStack Height="Fit" >
+ <Widget Width="20" Height="14" Background="{}" CornerRadius="3"/>
+ <Label Text="{}" Width="Stretched" />
+ </HorizontalStack>
+ </ListItem>
+ </ItemTemplate>
+ </ListBox>
+ </Template>
+</ColorPicker>
+
+
\ No newline at end of file
--- /dev/null
+<ColorPicker Height="Stretched" Background="Onyx" Width="Fit">
+ <Template>
+ <ListBox Width="Stretched" Data="{./AvailableColors}" Margin="10">
+ <Template>
+ <Scroller Name="scroller1" Margin="5" ClipToClientRect="true" Background="Onyx">
+ <VerticalStack Name="ItemsContainer" Height="Fit" VerticalAlignment="Top"/>
+ </Scroller>
+ </Template>
+ <ItemTemplate>
+ <ListItem Margin="1" Width="Stretched"
+ Selected="{Background=White}"
+ Unselected="{Background=Transparent}" >
+ <Label CornerRadius="3" Margin="2" Background="{}" Text="{}" Width="Stretched" />
+ </ListItem>
+ </ItemTemplate>
+ </ListBox>
+ </Template>
+</ColorPicker>
+
\ No newline at end of file
</HorizontalStack>
</Template>/>
<TabView MinimumSize="{../MinimumPopupSize}" Width="200" Height="200" >
- <ColorPicker Name="HSV" CurrentColor="{²../../../CurrentColor}" Background="Onyx" BubbleMouseEvent="false"/>
+ <ColorPicker Name="HSV" CurrentColor="{²../../../CurrentColor}" Background="Onyx" />
<ColorPicker IsVisible="false" Name="Names" CurrentColor="{²../../../CurrentColor}" Height="Stretched" Background="Onyx">
<Template>
<ListBox Width="Stretched" Data="{./AvailableColors}" SelectedItemChanged="./onSelectedItemChanged">
<TabView>
- <GroupBox Caption="test" Background="Black"/>
- <GroupBox Caption="test" Background="Black"/>
+ <GroupBox Caption="test" Background="Red"/>
+ <GroupBox Caption="test" Background="Blue"/>
</TabView>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0"?>
+<VerticalStack Background="DimGrey" Margin="1" Width="Fit" Height="Fit">
+<VerticalStack Background="DimGrey" Margin="1" Width="Stretched" Height="Fit">
+<VerticalStack Background="DimGrey" Margin="1" Width="Stretched" Height="Fit">
+<VerticalStack Background="DimGrey" Margin="1" Width="Stretched" Height="Fit">
+ <Label Text="this " Margin="0" Width="Stretched" Height="Fit" Background="SeaGreen"/>
+ <Label Text="this is a test" Margin="0" Width="Stretched" Height="Fit" Background="SeaGreen"/>
+ <Label Text="this is a test" Margin="0" Width="Stretched" Height="Fit" Background="SeaGreen"/>
+ <Label Text="this is a test" Margin="0" Width="Stretched" Height="Fit" Background="SeaGreen"/>
+ <Label Text="this is a test" Margin="0" Width="Stretched" Height="Fit" Background="SeaGreen"/>
+ <Label Text="this is a test" Margin="0" Width="Stretched" Height="Fit" Background="SeaGreen"/>
+ <Label Text="this is a test" Margin="0" Width="Stretched" Height="Fit" Background="SeaGreen"/>
+ <Label Text="this is a test" Margin="0" Width="Stretched" Height="Fit" Background="SeaGreen"/>
+ <Label Text="this is a test" Margin="0" Width="Stretched" Height="Fit" Background="SeaGreen"/>
+ <Label Text="this is a test" Margin="0" Width="Stretched" Height="Fit" Background="SeaGreen"/>
+ <Label Text="this is a test" Margin="0" Width="Stretched" Height="Fit" Background="SeaGreen"/>
+ <Label Text="thismlkjqsdfmsmlfkj " Margin="0" Width="Stretched" Height="Fit" Background="SeaGreen"/>
+ <Label Text="this is a test" Margin="0" Width="Stretched" Height="Fit" Background="SeaGreen"/>
+ <Label Text="this is a test" Margin="0" Width="Stretched" Height="Fit" Background="SeaGreen"/>
+ <Label Text="this is a test" Margin="0" Width="Stretched" Height="Fit" Background="SeaGreen"/>
+ <Label Text="this is a test" Margin="0" Width="Stretched" Height="Fit" Background="SeaGreen"/>
+ <Label Text="this is a test" Margin="0" Width="Stretched" Height="Fit" Background="SeaGreen"/>
+</VerticalStack>
+</VerticalStack>
+</VerticalStack>
+</VerticalStack>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0"?>
+<VerticalStack Height="Fit" Width="Fit" Margin="10" Background="Onyx">
+ <HorizontalStack Width="Stretched">
+ <Label Text="th" Width="Stretched" Background="Grey"/>
+ <Label Text="this is a fit label" Width="Fit" Background="Teal"/>
+ </HorizontalStack>
+ <HorizontalStack Width="Stretched">
+ <Label Text="this is a stretchedlkqsdflkj" Width="Stretched" Background="Grey"/>
+ <Label Text="this" Width="Fit" Background="Teal"/>
+ </HorizontalStack>
+ <HorizontalStack Width="Stretched">
+ <Label Text="this is a stretched label" Width="Stretched" Background="Grey"/>
+ <Label Text="th" Width="Fit" Background="Teal"/>
+ </HorizontalStack>
+</VerticalStack>
--- /dev/null
+<?xml version="1.0"?>
+<Container Height="Fit" Width="Fit" Margin="1" Background="CornflowerBlue">
+ <VerticalStack Height="Stretched" >
+ <Label Text="this is a stretched label" Width="Stretched" Height="Stretched"/>
+ <Label Text="this is a fit label" Width="Stretched" Height="Fit"/>
+ </VerticalStack>
+</Container>
--- /dev/null
+<?xml version="1.0"?>
+<Container Width="Stretched">
+<VerticalStack Height="Fit" Width="Stretched" Margin="5" Background="Onyx">
+ <HorizontalStack Width="Fit" >
+ <Label Text="thed label" Width="Stretched" Background="Grey"/>
+ <Label Text="this label" Width="Fit" Background="Teal"/>
+ </HorizontalStack>
+ <HorizontalStack Width="Stretched">
+ <Label Text="this is a stretched label" Width="Stretched" Background="Grey"/>
+ <Label Text="this is a fit label" Width="Fit" Background="Teal"/>
+ </HorizontalStack>
+ <HorizontalStack Width="Stretched" >
+ <Label Text="this is a stret" Width="Stretched" Background="Grey"/>
+ <Label Text="thi" Width="Fit" Background="Teal"/>
+ </HorizontalStack>
+</VerticalStack>
+</Container>
--- /dev/null
+<HorizontalStack Height="Fit" Width="Fit" Background="DarkSlateBlue" Margin="10">
+ <Label Name="lab" Text="this is a long stretched label" Width="Stretched" Background="Grey"/>
+ <Label Text="label" Width="Fit" Background="Teal"/>
+</HorizontalStack>
--- /dev/null
+<?xml version="1.0"?>
+<Container Width="Stretched">
+<VerticalStack Height="Fit" Width="Fit" Margin="5" Background="Onyx">
+ <HorizontalStack Width="Stretched" >
+ <Label Text="stretched-end" Width="Stretched" Background="Grey"/>
+ <Label Text="fit" Width="Fit" Background="Teal"/>
+ </HorizontalStack>
+ <HorizontalStack Width="Stretched">
+ <Label Text="stretched labelsdqfqsfdqsdfqsdfqsdfdsqfqsdfqsdfqsdfdqsfdqsfdqsfdqsfdqsfqsdfdqsfdqsfdqsfdqsfdqsfqsdf" Width="Stretched" Background="Grey"/>
+ <Label Text="fit" Width="Fit" Background="Teal"/>
+ </HorizontalStack>
+ <HorizontalStack Width="Stretched" >
+ <Label Text="stretched-end" Width="Stretched" Background="Grey"/>
+ <Label Text="fit" Width="Fit" Background="Teal"/>
+ </HorizontalStack>
+</VerticalStack>
+</Container>
<VerticalStack Width="Stretched" Margin="10" Background="FireBrick">
<VerticalStack Width="Stretched" Margin="10" Background="Teal">
<VerticalStack Width="Stretched" Margin="10" Background="CornflowerBlue">
- <Label Text="{./Caption}" Width="Stretched"/>
- <Label Text="{./Caption}" Width="Stretched"/>
- <Label Text="{./Caption}" Width="Stretched"/>
- <Label Text="{./Caption}" Width="Stretched"/>
+ <Label Text="label" Width="Stretched"/>
+ <Label Text="a bit longer" Width="Stretched"/>
+ <Label Text="cow" Width="Stretched"/>
+ <Label Text="horse" Width="Stretched"/>
</VerticalStack>
</VerticalStack>
</VerticalStack>
<?xml version="1.0"?>
-<VerticalStack Background="DimGrey" Margin="10" Width="Fit" Height="Fit" >
- <CheckBox Name="cb"/>
- <CheckBox Name="cb2"/>
+<VerticalStack Background="DimGrey" Margin="10" Width="Fit" Height="Fit"
+ MouseEnter="{Background=Blue}"
+ MouseLeave="{Background=DimGrey}" >
+ <CheckBox Name="cb" MouseEnter="{Background=DarkRed}" MouseLeave="{Background=Transparent}"/>
+ <CheckBox Name="cb2" MouseEnter="{Background=DarkRed}" MouseLeave="{Background=Transparent}"/>
<Container Visible="{²../cb.IsChecked}" Width="Stretched" Margin="10" Background="RoyalBlue">
<VerticalStack Margin="5" Background="Yellow">
<VerticalStack Margin="5" Background="Teal">
<?xml version="1.0"?>
<Border BorderWidth="2" Fit="true" Background="DarkGrey">
<VerticalStack Fit="true" Margin="5">
- <ListBox Data="{TestList}" Background="Jet" HorizontalAlignment="Center" Width="200" Height="200" Margin="5">
+ <ListBox Data="{TestList}" Background="Jet" HorizontalAlignment="Center" Width="Fit" Height="200" Margin="5">
<Template>
<Border BorderWidth="1" Background="{./Background}">
<HorizontalStack Margin="1">
<ItemTemplate DataType="Crow.Colors">
<HorizontalStack
HorizontalAlignment="Left"
- Height="Fit" Width="200" Margin="1" Focusable="true"
+ Height="Fit" Width="Stretched" Margin="1" Focusable="true"
MouseEnter="{Background=RoyalBlue}"
MouseLeave="{Background=Transparent}">
</HorizontalStack>
</Template>/>
<TabView MinimumSize="{../MinimumPopupSize}" Width="200" Height="200" >
- <ColorPicker Name="HSV" CurrentColor="{²../../../CurrentColor}" Background="Onyx" BubbleMouseEvent="false"/>
+ <ColorPicker Name="HSV" CurrentColor="{²../../../CurrentColor}" Background="Onyx" />
<ColorPicker IsVisible="false" Name="Names" CurrentColor="{²../../../CurrentColor}" Height="Stretched" Background="Onyx">
<Template>
<ListBox Width="Stretched" Data="{./AvailableColors}" SelectedItemChanged="./onSelectedItemChanged">
</HorizontalStack>
</Template>/>
<TabView MinimumSize="{../MinimumPopupSize}" Width="200" Height="200" >
- <ColorPicker Name="HSV" CurrentColor="{²../../../CurrentColor}" Background="Onyx" BubbleMouseEvent="false"/>
+ <ColorPicker Name="HSV" CurrentColor="{²../../../CurrentColor}" Background="Onyx" />
<ColorPicker IsVisible="false" Name="Names" CurrentColor="{²../../../CurrentColor}" Height="Stretched" Background="Onyx">
<Template>
<ListBox Width="Stretched" Data="{./AvailableColors}" SelectedItemChanged="./onSelectedItemChanged">
--- /dev/null
+<ColorPicker Name="Names" Height="Stretched" Background="Onyx">
+ <Template>
+ <ListBox Height="Fit" Width="Stretched" Data="{./AvailableColors}" >
+ <ItemTemplate>
+ <ListItem Margin="0" Height="16" Width="Fit"
+ Selected="{Background=Black}"
+ Unselected="{Background=Transparent}">
+ <Label Height="Fit" Width="Fit" Text="{}" Background="{}" Margin="5"/>
+ </ListItem>
+ </ItemTemplate>
+ <Template>
+ <VerticalStack Width="Stretched" >
+ <Scroller Name="scroller" >
+ <HorizontalStack Name="ItemsContainer" Width="Fit" HorizontalAlignment="Left"/>
+ </Scroller>
+ <ScrollBar Style="HScrollBar" Name="scrollbar1" Value="{²../scroller.ScrollX}"
+ LargeIncrement="{../scroller.PageWidth}" SmallIncrement="30" CursorRatio="{../scroller.ChildWidthRatio}"
+ Maximum="{../scroller.MaxScrollX}" Height="12" />
+ </VerticalStack>
+ </Template>
+ </ListBox>
+ </Template>
+</ColorPicker>
\ No newline at end of file
static void Main ()
{
using (BasicTests app = new BasicTests ()) {
+ app.SolidBackground = false;
app.Run ();
}
}
}
DockWindow {
Template="#ui.dockWin.template";
+ AllowedStates="Normal|Maximized|Minimized";
+ Width="260";
+ Height="200";
}
TabView {
Template="#ui.TabView.template";
<?xml version="1.0"?>
<Border Name="SizeHandle" BorderWidth="1" Foreground="Black" CornerRadius="{./CornerRadius}" StickyMouse="8" StickyMouseEnabled="{./IsFloating}"
Background="{./Background}">
- <VerticalStack Spacing="0">
+ <VerticalStack Spacing="0" Name="MoveHandle">
<HorizontalStack Height="Fit" IsVisible="{./IsDocked}" Background="Black">
<Label Text="{./Caption}"/>
+ <Label Text="{./CurrentState}" Margin="1" Foreground="Black" Background="Grey"/>
<Label Text="{./DockingPosition}"/>
+ <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>
<HorizontalStack Background="vgradient|0:0.5,0.6,0.5,0.5|1:0.2,0.3,0.3,0.7"
Name="hs" Margin="0" Spacing="0" Height="Fit" Visible="{./IsFloating}">
<Widget Width="5"/>
<Image Margin="1" Width="10" Height="10" Path="{./Icon}"/>
<Label Text="{./Caption}"/>
+ <Label Text="{./CurrentState}" Margin="1" Foreground="Black" Background="Grey"/>
<Label Width="Stretched" Foreground="White" Margin="1" TextAlignment="Left" Text="{./DockingPosition}" />
- <Border CornerRadius="6" BorderWidth="1" Foreground="Transparent" Height="10" Width="10"
- MouseEnter="{Foreground=White}" MouseLeave="{Foreground=Transparent}">
- <Image Focusable="true" Name="Image" Margin="0" Path="#Crow.Icons.exit2.svg"
- MouseClick="./onQuitPress"/>
- </Border>
- <Widget Width="5"/>
- </HorizontalStack>
+ <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>
<Container Name="Content" MinimumSize="50,50"/>
</VerticalStack>
</Border>