aboutsummaryrefslogtreecommitdiffstatsci
diff options
context:
space:
mode:
-rw-r--r--Crow.sln18
-rw-r--r--Crow/Default.style7
-rw-r--r--Crow/Templates/DockWindow.template13
-rw-r--r--Crow/src/Fill/BmpPicture.cs4
-rw-r--r--Crow/src/IML/Instantiator.cs2
-rw-r--r--Crow/src/Interface.cs89
-rw-r--r--Crow/src/ItemTemplate.cs20
-rw-r--r--Crow/src/Mono.Cairo/Context.cs4
-rw-r--r--Crow/src/Mono.Cairo/NativeMethods.cs2
-rw-r--r--Crow/src/Widgets/DockStack.cs21
-rw-r--r--Crow/src/Widgets/DockWindow.cs22
-rw-r--r--Crow/src/Widgets/Group.cs2
-rw-r--r--Crow/src/Widgets/PrivateContainer.cs2
-rw-r--r--Crow/src/Widgets/TabItem.cs4
-rw-r--r--Crow/src/Widgets/Widget.cs66
-rw-r--r--Crow/src/Widgets/Window.cs48
-rw-r--r--Samples/Directory.Build.props2
-rw-r--r--Samples/ShowCase/ShowCase.cs4
-rw-r--r--Samples/common/samples.style3
-rw-r--r--Samples/common/ui/Interfaces/Divers/2.crow5
-rw-r--r--Samples/common/ui/Interfaces/Experimental/testDock.crow10
-rw-r--r--Samples/common/ui/Interfaces/Experimental/testStack.crow2
-rw-r--r--Samples/dockableWindows/dockableWindows.cs33
-rw-r--r--Samples/dockableWindows/dockableWindows.csproj13
-rw-r--r--Samples/dockableWindows/ui/GTreeExp.itemp32
-rw-r--r--Samples/dockableWindows/ui/test.crow44
-rw-r--r--Samples/dragNdrop/dragNdrop.cs65
-rw-r--r--Samples/dragNdrop/dragNdrop.csproj8
-rw-r--r--Samples/dragNdrop/ui/GTreeExp.itemp32
-rw-r--r--Samples/dragNdrop/ui/test.crow55
30 files changed, 518 insertions, 114 deletions
diff --git a/Crow.sln b/Crow.sln
index ee474496..8f6e3f3d 100644
--- a/Crow.sln
+++ b/Crow.sln
@@ -8,7 +8,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "global", "global", "{728545
README.md = README.md
EndProjectSection
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Crow", "Crow\Crow.csproj", "{C2980F9B-4798-4C05-99E2-E174810F7C7B}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Crow", "Crow\Crow.csproj", "{C2980F9B-4798-4C05-99E2-E174810F7C7B}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{B2C7855A-2878-47FD-AD32-9A83DB4AB8C6}"
ProjectSection(SolutionItems) = preProject
@@ -27,7 +27,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BasicTests", "Samples\Basic
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PerfTests", "Samples\PerfTests\PerfTests.csproj", "{18EBB41F-815E-4BF5-B80F-C9E2FAB2993A}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DebugLogAnalyzer", "Samples\DebugLogAnalyzer\DebugLogAnalyzer.csproj", "{7915538F-B2B1-414C-95A3-1FC58E3286B9}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DebugLogAnalyzer", "Samples\DebugLogAnalyzer\DebugLogAnalyzer.csproj", "{7915538F-B2B1-414C-95A3-1FC58E3286B9}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dragNdrop", "Samples\dragNdrop\dragNdrop.csproj", "{6E361E34-D266-4BEB-97F4-E209E01C6246}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dockableWindows", "Samples\dockableWindows\dockableWindows.csproj", "{E19FD3DB-902A-4C99-8BF0-5ACAFFE35608}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -65,6 +69,14 @@ Global
{7915538F-B2B1-414C-95A3-1FC58E3286B9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7915538F-B2B1-414C-95A3-1FC58E3286B9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7915538F-B2B1-414C-95A3-1FC58E3286B9}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6E361E34-D266-4BEB-97F4-E209E01C6246}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6E361E34-D266-4BEB-97F4-E209E01C6246}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6E361E34-D266-4BEB-97F4-E209E01C6246}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6E361E34-D266-4BEB-97F4-E209E01C6246}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E19FD3DB-902A-4C99-8BF0-5ACAFFE35608}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E19FD3DB-902A-4C99-8BF0-5ACAFFE35608}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E19FD3DB-902A-4C99-8BF0-5ACAFFE35608}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E19FD3DB-902A-4C99-8BF0-5ACAFFE35608}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -76,6 +88,8 @@ Global
{7AEB6DD5-916E-4415-84E1-78EC6E5881CE} = {B2C7855A-2878-47FD-AD32-9A83DB4AB8C6}
{18EBB41F-815E-4BF5-B80F-C9E2FAB2993A} = {B2C7855A-2878-47FD-AD32-9A83DB4AB8C6}
{7915538F-B2B1-414C-95A3-1FC58E3286B9} = {B2C7855A-2878-47FD-AD32-9A83DB4AB8C6}
+ {6E361E34-D266-4BEB-97F4-E209E01C6246} = {B2C7855A-2878-47FD-AD32-9A83DB4AB8C6}
+ {E19FD3DB-902A-4C99-8BF0-5ACAFFE35608} = {B2C7855A-2878-47FD-AD32-9A83DB4AB8C6}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {00D4E149-7131-49F4-BAAD-559AA961A78E}
diff --git a/Crow/Default.style b/Crow/Default.style
index cbc9dcba..04cb01dc 100644
--- a/Crow/Default.style
+++ b/Crow/Default.style
@@ -124,7 +124,9 @@ Slider {
}
Splitter {
Focusable = "true";
- Margin = "1";
+ Margin = "0";
+ StickyMouseEnabled="true";
+ StickyMouse="10";
Background = "Grey";
}
@@ -175,7 +177,8 @@ Docker {
Focusable="true";
}
DockStack {
- Margin="1";
+ Margin="2";
+ Spacing="2";
AllowDrop = "true";
Focusable="true";
//DragEnter="{Background=Blue}";
diff --git a/Crow/Templates/DockWindow.template b/Crow/Templates/DockWindow.template
index e62672bc..9a2bd3b4 100644
--- a/Crow/Templates/DockWindow.template
+++ b/Crow/Templates/DockWindow.template
@@ -1,12 +1,9 @@
<?xml version="1.0"?>
-<!--<Widget Background="{./Background}"/>-->
-<Border BorderWidth="1" Foreground="Black" CornerRadius="{./CornerRadius}"
- Background="{./Background}"
- MouseEnter="./onBorderMouseEnter"
- MouseLeave="./onBorderMouseLeave">
+<Border Name="SizeHandle" BorderWidth="1" Foreground="Black" CornerRadius="{./CornerRadius}" StickyMouse="8" StickyMouseEnabled="{./IsFloating}"
+ Background="{./Background}">
<VerticalStack Spacing="0">
<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="{./Caption}" TextAlignment="Left" Width="Stretched"
+ <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}">
@@ -16,9 +13,9 @@
</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"/>
+ <Widget Width="5"/>
<Image Margin="1" Width="10" Height="10" Path="{./Icon}"/>
- <Label Width="Stretched" Foreground="White" Margin="1" TextAlignment="Left" Text="{./Caption}" />
+ <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"
diff --git a/Crow/src/Fill/BmpPicture.cs b/Crow/src/Fill/BmpPicture.cs
index c000628d..1aade935 100644
--- a/Crow/src/Fill/BmpPicture.cs
+++ b/Crow/src/Fill/BmpPicture.cs
@@ -125,7 +125,7 @@ namespace Crow
using (ImageSurface imgSurf = new ImageSurface (image, Format.Argb32,
Dimensions.Width, Dimensions.Height, 4 * Dimensions.Width)) {
- gr.SetSourceSurface (imgSurf, 0,0);
+ gr.SetSource (imgSurf, 0,0);
gr.Paint ();
}
}
@@ -166,7 +166,7 @@ namespace Crow
using (ImageSurface imgSurf = new ImageSurface (image, Format.Argb32,
Dimensions.Width, Dimensions.Height, 4 * Dimensions.Width)) {
- gr.SetSourceSurface (imgSurf, 0,0);
+ gr.SetSource (imgSurf, 0,0);
gr.Paint ();
}
gr.Restore ();
diff --git a/Crow/src/IML/Instantiator.cs b/Crow/src/IML/Instantiator.cs
index 7a4ca5a6..ac203f08 100644
--- a/Crow/src/IML/Instantiator.cs
+++ b/Crow/src/IML/Instantiator.cs
@@ -155,7 +155,7 @@ namespace Crow.IML {
Delegate templateBinding;
#if DESIGN_MODE
- public List<DynamicMethod> DsValueChangedDynMeths =>dsValueChangedDynMeths;
+ public List<DynamicMethod> DsValueChangedDynMeths => dsValueChangedDynMeths;
public List<Delegate> CachedDelegates => cachedDelegates;
/// <summary>
/// store indices of template delegate to be handled by root parentChanged event
diff --git a/Crow/src/Interface.cs b/Crow/src/Interface.cs
index d11070f8..a9a9fa1b 100644
--- a/Crow/src/Interface.cs
+++ b/Crow/src/Interface.cs
@@ -314,6 +314,8 @@ namespace Crow
public static string CROW_CONFIG_ROOT;
/// <summary>If true, mouse focus is given when mouse is over control</summary>
public static bool FOCUS_ON_HOVER = false;
+ /// <summary>If true, newly focused window will be put on top</summary>
+ public static bool RAISE_WIN_ON_FOCUS = true;
/// <summary> Threshold to catch borders for sizing </summary>
public static int BorderThreshold = 3;
/// <summary> delay before tooltip appears </summary>
@@ -354,6 +356,9 @@ namespace Crow
//public event EventHandler<MouseCursorChangedEventArgs> MouseCursorChanged;
////public event EventHandler Quit;
public event EventHandler Initialized;
+
+ public event EventHandler StartDragOperation;
+ public event EventHandler EndDragOperation;
//public event EventHandler<MouseWheelEventArgs> MouseWheelChanged;
//public event EventHandler<MouseButtonEventArgs> MouseButtonUp;
//public event EventHandler<MouseButtonEventArgs> MouseButtonDown;
@@ -507,7 +512,10 @@ namespace Crow
return stream != null;
}
- public static Stream GetStreamFromPath (string path)
+ public delegate Stream GetStreamFromPathDelegate (string path);
+ public static GetStreamFromPathDelegate GetStreamFromPath = _getStreamFromPath;
+
+ static Stream _getStreamFromPath (string path)
{
if (path.StartsWith ("#", StringComparison.Ordinal)) {
Stream stream = null;
@@ -618,8 +626,8 @@ namespace Crow
_activeWidget = value;
+ NotifyValueChanged ("ActiveWidget", _activeWidget);
#if DEBUG_LOG
- NotifyValueChanged("ActiveWidget", _activeWidget);
DbgLogger.AddEvent (DbgEvtType.ActiveWidget, _activeWidget);
#endif
@@ -640,8 +648,8 @@ namespace Crow
_hoverWidget = value;
+ NotifyValueChanged ("HoverWidget", _hoverWidget);
#if DEBUG_LOG
- NotifyValueChanged("HoverWidget", _hoverWidget);
DbgLogger.AddEvent (DbgEvtType.HoverWidget, _hoverWidget);
#endif
@@ -669,8 +677,9 @@ namespace Crow
if (_focusedWidget != null)
_focusedWidget.HasFocus = false;
_focusedWidget = value;
-#if DEBUG_LOG
- NotifyValueChanged("FocusedWidget", _focusedWidget);
+
+ NotifyValueChanged ("FocusedWidget", _focusedWidget);
+#if DEBUG_LOG
DbgLogger.AddEvent (DbgEvtType.FocusedWidget, _focusedWidget);
#endif
if (_focusedWidget != null)
@@ -823,7 +832,7 @@ namespace Crow
DragImageY = MousePosition.Y - DragImageHeight / 2;
ctx.Save ();
ctx.ResetClip ();
- ctx.SetSourceSurface (DragImage, DragImageX, DragImageY);
+ ctx.SetSource (DragImage, DragImageX, DragImageY);
ctx.PaintWithAlpha (0.8);
ctx.Restore ();
DirtyRect += new Rectangle (DragImageX, DragImageY, DragImageWidth, DragImageHeight);
@@ -972,11 +981,31 @@ namespace Crow
/// when window resize event occurs.
/// </summary>
/// <param name="bounds">bounding box of the interface</param>
- public virtual void ProcessResize(Rectangle bounds){
+ public virtual void ProcessResize(Rectangle bounds){
lock (UpdateMutex) {
clientRectangle = bounds;
- surf.SetSize (clientRectangle.Width, clientRectangle.Height);
+ switch (Environment.OSVersion.Platform) {
+ case PlatformID.MacOSX:
+ break;
+ case PlatformID.Unix:
+ surf.SetSize (clientRectangle.Width, clientRectangle.Height);
+ break;
+ case PlatformID.Win32NT:
+ case PlatformID.Win32S:
+ case PlatformID.Win32Windows:
+ if (ownWindow) {
+ surf.Dispose ();
+ IntPtr hWin32 = Glfw3.GetWin32Window (hWin);
+ IntPtr hdc = Glfw3.GetWin32DC (hWin32);
+ surf = new Win32Surface (hdc);
+ }else
+ surf.SetSize (clientRectangle.Width, clientRectangle.Height);
+ break;
+ case PlatformID.Xbox:
+ case PlatformID.WinCE:
+ throw new PlatformNotSupportedException ("Unable to create cairo surface.");
+ }
foreach (Widget g in GraphicTree)
g.RegisterForLayouting (LayoutingType.All);
@@ -1085,42 +1114,43 @@ namespace Crow
//MouseCursorChanged.Raise (this,new MouseCursorChangedEventArgs(cursor));
}
}
-
- uint stickyMouse = 0;
- Point stickyMousePos = default;
- internal void SetStickyMouse (uint threshold = 5)
- {
- stickyMouse = threshold;
- stickyMousePos = MousePosition;
- }
+
+ Point stickyMouseDelta = default;
+ internal Widget stickedWidget = null;
/// <summary>Processes mouse move events from the root container, this function
/// should be called by the host on mouse move event to forward events to crow interfaces</summary>
/// <returns>true if mouse is in the interface</returns>
public virtual bool OnMouseMove (int x, int y)
- {
+ {
+ int deltaX = x - MousePosition.X;
+ int deltaY = y - MousePosition.Y;
+
+ if (stickedWidget != null && _activeWidget == null) {
+ stickyMouseDelta.X += deltaX;
+ stickyMouseDelta.Y += deltaY;
- if (stickyMouse>0) {
- if (Math.Abs(x - stickyMousePos.X) < stickyMouse && Math.Abs(y - stickyMousePos.Y) < stickyMouse)
+ if (Math.Abs (stickyMouseDelta.X) > stickedWidget.StickyMouse || Math.Abs (stickyMouseDelta.Y) > stickedWidget.StickyMouse) {
+ stickedWidget = null;
+ stickyMouseDelta = default;
+ } else {
+ Glfw3.SetCursorPosition (hWin, MousePosition.X, MousePosition.Y);
return true;
- stickyMouse = 0;
+ }
}
- int deltaX = x - MousePosition.X;
- int deltaY = y - MousePosition.Y;
MousePosition = new Point (x, y);
MouseMoveEventArgs e = new MouseMoveEventArgs (x, y, deltaX, deltaY);
- if (ActiveWidget != null && DragAndDropOperation == null) {
+ if (DragAndDropOperation != null)//drag source cant have hover event, so move has to be handle here
+ DragAndDropOperation.DragSource.onMouseMove (this, e);
+ else if (ActiveWidget != null) {
//TODO, ensure object is still in the graphic tree
//send move evt even if mouse move outside bounds
_activeWidget.onMouseMove (this, e);
return true;
}
- if (DragAndDropOperation != null)//drag source cant have hover event, so move has to be handle here
- DragAndDropOperation.DragSource.onMouseMove (this, e);
-
if (_hoverWidget != null) {
resetTooltip ();
//check topmost graphicobject first
@@ -1177,8 +1207,11 @@ namespace Crow
Widget g = GraphicTree [i];
if (g.MouseIsIn (e.Position)) {
g.checkHoverWidget (e);
- if (g is Window)
- PutOnTop (g);
+ if (g is Window && FOCUS_ON_HOVER && g.Focusable) {
+ FocusedWidget = g;
+ if (RAISE_WIN_ON_FOCUS)
+ PutOnTop (g);
+ }
_hoverWidget.onMouseMove (_hoverWidget, e);
return true;
}
diff --git a/Crow/src/ItemTemplate.cs b/Crow/src/ItemTemplate.cs
index 01e76b59..11fea671 100644
--- a/Crow/src/ItemTemplate.cs
+++ b/Crow/src/ItemTemplate.cs
@@ -251,5 +251,25 @@ namespace Crow
il.Emit (OpCodes.Callvirt, miGetDatas);
}
}
+
+ public static partial class Extensions
+ {
+ public static string GetIcon (this Widget go) {
+ return "#Icons." + go.GetType ().FullName + ".svg";
+ }
+ public static List<Widget> GetChildren (this Widget go) {
+ Type goType = go.GetType ();
+ if (typeof (Group).IsAssignableFrom (goType))
+ return (go as Group).Children;
+ if (typeof (Container).IsAssignableFrom (goType))
+ return new List<Widget> (new Widget[] { (go as Container).Child });
+ if (typeof (TemplatedContainer).IsAssignableFrom (goType))
+ return new List<Widget> (new Widget[] { (go as TemplatedContainer).Content });
+ if (typeof (TemplatedGroup).IsAssignableFrom (goType))
+ return (go as TemplatedGroup).Items;
+
+ return new List<Widget> ();
+ }
+ }
}
diff --git a/Crow/src/Mono.Cairo/Context.cs b/Crow/src/Mono.Cairo/Context.cs
index 7ed5e62c..1ce4cd0f 100644
--- a/Crow/src/Mono.Cairo/Context.cs
+++ b/Crow/src/Mono.Cairo/Context.cs
@@ -340,7 +340,7 @@ namespace Crow.Cairo {
}
//[Obsolete ("Use SetSource method (with double parameters)")]
- public void SetSourceSurface (Surface source, int x, int y)
+ public void SetSource (Surface source, int x = 0, int y = 0)
{
NativeMethods.cairo_set_source_surface (handle, source.Handle, x, y);
}
@@ -861,7 +861,7 @@ namespace Crow.Cairo {
public void ShowText(string str)
{
- NativeMethods.cairo_show_text (handle, str);
+ NativeMethods.cairo_show_text (handle, TerminateUtf8 (str));
}
diff --git a/Crow/src/Mono.Cairo/NativeMethods.cs b/Crow/src/Mono.Cairo/NativeMethods.cs
index 1b423209..66b528a1 100644
--- a/Crow/src/Mono.Cairo/NativeMethods.cs
+++ b/Crow/src/Mono.Cairo/NativeMethods.cs
@@ -752,7 +752,7 @@ namespace Crow.Cairo
internal static extern void cairo_show_page (IntPtr cr);
[DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
- internal static extern void cairo_show_text (IntPtr cr, string text);
+ internal static extern void cairo_show_text (IntPtr cr, byte[] text);
[DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
internal static extern Status cairo_status (IntPtr cr);
diff --git a/Crow/src/Widgets/DockStack.cs b/Crow/src/Widgets/DockStack.cs
index 81aa5e74..da9110e4 100644
--- a/Crow/src/Widgets/DockStack.cs
+++ b/Crow/src/Widgets/DockStack.cs
@@ -71,6 +71,7 @@ namespace Crow
Rectangle rIn = default(Rectangle);
double dockThresh = 0.2;
+ const int dockWidthDivisor = 8;
Widget focusedChild;
internal Widget stretchedChild;
@@ -113,33 +114,33 @@ namespace Crow
rIn = cb;
if (Orientation == Orientation.Horizontal || Children.Count == 1) {
- if (lm.Y > cb.Top + cb.Height / 3 && lm.Y < cb.Bottom - cb.Height / 3) {
- if (lm.X < cb.Left + cb.Width / 3)
+ if (lm.Y > cb.Top + cb.Height / dockWidthDivisor && lm.Y < cb.Bottom - cb.Height / dockWidthDivisor) {
+ if (lm.X < cb.Left + cb.Width / dockWidthDivisor)
dw.DockingPosition = Alignment.Left;
- else if (lm.X > cb.Right - cb.Width / 3)
+ else if (lm.X > cb.Right - cb.Width / dockWidthDivisor)
dw.DockingPosition = Alignment.Right;
} else {
getFocusedChild (lm);
if (focusedChild != null) {
- if (lm.Y < rIn.Top + rIn.Height / 3)
+ if (lm.Y < rIn.Top + rIn.Height / dockWidthDivisor)
dw.DockingPosition = Alignment.Top;
- else if (lm.Y > rIn.Bottom - rIn.Height / 3)
+ else if (lm.Y > rIn.Bottom - rIn.Height / dockWidthDivisor)
dw.DockingPosition = Alignment.Bottom;
}
}
}
if (Orientation == Orientation.Vertical || Children.Count == 1) {
- if (lm.X > cb.Left + cb.Width / 3 && lm.X < cb.Right - cb.Width / 3) {
- if (lm.Y < cb.Top + cb.Height / 3)
+ if (lm.X > cb.Left + cb.Width / dockWidthDivisor && lm.X < cb.Right - cb.Width / dockWidthDivisor) {
+ if (lm.Y < cb.Top + cb.Height / dockWidthDivisor)
dw.DockingPosition = Alignment.Top;
- else if (lm.Y > cb.Bottom - cb.Height / 3)
+ else if (lm.Y > cb.Bottom - cb.Height / dockWidthDivisor)
dw.DockingPosition = Alignment.Bottom;
} else {
getFocusedChild (lm);
if (focusedChild != null) {
- if (lm.X < rIn.Left + rIn.Width / 3)
+ if (lm.X < rIn.Left + rIn.Width / dockWidthDivisor)
dw.DockingPosition = Alignment.Left;
- else if (lm.X > rIn.Right - rIn.Width / 3)
+ else if (lm.X > rIn.Right - rIn.Width / dockWidthDivisor)
dw.DockingPosition = Alignment.Right;
}
}
diff --git a/Crow/src/Widgets/DockWindow.cs b/Crow/src/Widgets/DockWindow.cs
index e9c37179..bf59b155 100644
--- a/Crow/src/Widgets/DockWindow.cs
+++ b/Crow/src/Widgets/DockWindow.cs
@@ -68,15 +68,18 @@ namespace Crow
public override void onMouseMove (object sender, MouseMoveEventArgs e)
{
-// if (this.HasFocus && e.Mouse.IsButtonDown (MouseButton.Left) && IsDocked) {
-// if (Math.Abs (e.Position.X - undockingMousePosOrig.X) > 10 ||
-// Math.Abs (e.Position.X - undockingMousePosOrig.X) > 10)
-// Undock ();
-// }
-
- if (this.HasFocus && IFace.IsDown(MouseButton.Left) && IsDocked)
- CheckUndock (e.Position);
+ // if (this.HasFocus && e.Mouse.IsButtonDown (MouseButton.Left) && IsDocked) {
+ // if (Math.Abs (e.Position.X - undockingMousePosOrig.X) > 10 ||
+ // Math.Abs (e.Position.X - undockingMousePosOrig.X) > 10)
+ // Undock ();
+ // }
+ if (IFace.IsDown (MouseButton.Left) && IFace.DragAndDropOperation?.DragSource == this) {
+ if (isDocked)
+ CheckUndock (e.Position);
+ else
+ moveAndResize (e.XDelta, e.YDelta, currentDirection);
+ }
base.onMouseMove (sender, e);
}
public override void onMouseDown (object sender, MouseButtonEventArgs e)
@@ -100,7 +103,8 @@ namespace Crow
protected override void onStartDrag (object sender, DragDropEventArgs e)
{
- base.onStartDrag (sender, e);
+ if (currentDirection == Direction.None)
+ base.onStartDrag (sender, e);
undockingMousePosOrig = IFace.MousePosition;
}
diff --git a/Crow/src/Widgets/Group.cs b/Crow/src/Widgets/Group.cs
index df452bee..5f0a7b21 100644
--- a/Crow/src/Widgets/Group.cs
+++ b/Crow/src/Widgets/Group.cs
@@ -350,7 +350,7 @@ namespace Crow
}
gr.Dispose ();
- ctx.SetSourceSurface (bmp, rb.X, rb.Y);
+ ctx.SetSource (bmp, rb.X, rb.Y);
ctx.Paint ();
Clipping.Dispose();
diff --git a/Crow/src/Widgets/PrivateContainer.cs b/Crow/src/Widgets/PrivateContainer.cs
index 415d45d2..ebca78e8 100644
--- a/Crow/src/Widgets/PrivateContainer.cs
+++ b/Crow/src/Widgets/PrivateContainer.cs
@@ -216,7 +216,7 @@ namespace Crow
gr.Dispose ();
- ctx.SetSourceSurface (bmp, rb.X, rb.Y);
+ ctx.SetSource (bmp, rb.X, rb.Y);
ctx.Paint ();
Clipping.Dispose();
Clipping = new Region ();
diff --git a/Crow/src/Widgets/TabItem.cs b/Crow/src/Widgets/TabItem.cs
index 25c89ae3..19fcb94e 100644
--- a/Crow/src/Widgets/TabItem.cs
+++ b/Crow/src/Widgets/TabItem.cs
@@ -189,9 +189,9 @@ namespace Crow
this.onDraw (ctx);
else {
if (LastPaintedSlot.Width>LastPaintedSlot.Height)
- ctx.SetSourceSurface (bmp, 0, (LastPaintedSlot.Width-LastPaintedSlot.Height)/2);
+ ctx.SetSource (bmp, 0, (LastPaintedSlot.Width-LastPaintedSlot.Height)/2);
else
- ctx.SetSourceSurface (bmp, (LastPaintedSlot.Height-LastPaintedSlot.Width)/2, 0);
+ ctx.SetSource (bmp, (LastPaintedSlot.Height-LastPaintedSlot.Width)/2, 0);
ctx.Paint ();
}
diff --git a/Crow/src/Widgets/Widget.cs b/Crow/src/Widgets/Widget.cs
index c060f954..d75c63c4 100644
--- a/Crow/src/Widgets/Widget.cs
+++ b/Crow/src/Widgets/Widget.cs
@@ -121,9 +121,9 @@ namespace Crow
this.onDraw (ctx);
else {
if (LastPaintedSlot.Width>LastPaintedSlot.Height)
- ctx.SetSourceSurface (bmp, 0, (LastPaintedSlot.Width-LastPaintedSlot.Height)/2);
+ ctx.SetSource (bmp, 0, (LastPaintedSlot.Width-LastPaintedSlot.Height)/2);
else
- ctx.SetSourceSurface (bmp, (LastPaintedSlot.Height-LastPaintedSlot.Width)/2, 0);
+ ctx.SetSource (bmp, (LastPaintedSlot.Height-LastPaintedSlot.Width)/2, 0);
ctx.Paint ();
}
}
@@ -278,6 +278,8 @@ namespace Crow
bool isActive;
bool isHover;
bool mouseRepeat;
+ bool stickyMouseEnabled;
+ int stickyMouse;
MouseCursor mouseCursor = MouseCursor.top_left_arrow;
protected bool isVisible = true;
bool isEnabled = true;
@@ -449,11 +451,11 @@ namespace Crow
public event EventHandler Focused;
/// <summary>Occurs when this object loose focus</summary>
public event EventHandler Unfocused;
- /// <summary>Occurs when mouse is over</summary>
+ /// <summary>Occurs when this widget is hovered by the mouse</summary>
public event EventHandler Hover;
- /// <summary>Occurs when this control is no longer the Hover one</summary>
- //public event EventHandler UnHover;
- /// <summary>Occurs when this object loose focus</summary>
+ /// <summary>Occurs when this widget is no longuer the hover one</summary>
+ public event EventHandler Unhover;
+ /// <summary>Occurs when this widget is enabled</summary>
public event EventHandler Enabled;
/// <summary>Occurs when the enabled state this object is set to false</summary>
public event EventHandler Disabled;
@@ -737,10 +739,16 @@ namespace Crow
if (value == isHover)
return;
+ if (isHover & !value)
+ Unhover.Raise (this, null);
+
isHover = value;
- if (isHover)
+ if (isHover) {
+ if (stickyMouseEnabled && stickyMouse > 0)
+ IFace.stickedWidget = this;
Hover.Raise (this, null);
+ }
NotifyValueChangedAuto (isHover);
}
@@ -759,6 +767,32 @@ namespace Crow
}
}
/// <summary>
+ /// When StickyMouse value is greater than zero and StickyMouseEnabled is true, mouse will be sticked over the widget
+ /// until x or y delta is greater than the StickyMouse value. This is usefulle for very thin (1 pixel) border that need to
+ /// be grabbed with the mouse.
+ /// </summary>
+ public virtual int StickyMouse {
+ get => stickyMouse;
+ set {
+ if (stickyMouse == value)
+ return;
+ stickyMouse = value;
+ NotifyValueChangedAuto (stickyMouse);
+ }
+ }
+ /// <summary>
+ /// Boolean for enabling or not the sticky mouse mechanic
+ /// </summary>
+ public virtual bool StickyMouseEnabled {
+ get => stickyMouseEnabled;
+ set {
+ if (stickyMouseEnabled == value)
+ return;
+ stickyMouseEnabled = value;
+ NotifyValueChangedAuto (stickyMouseEnabled);
+ }
+ }
+ /// <summary>
/// Determine Cursor when mouse is Hover.
/// </summary>
[DesignCategory ("Behaviour")]
@@ -1347,8 +1381,9 @@ namespace Crow
/// </summary>
protected virtual void onStartDrag (object sender, DragDropEventArgs e){
IFace.HoverWidget = null;
+ IFace.DragAndDropOperation = new DragDropEventArgs (this);
IsDragged = true;
- StartDrag.Raise (this, e);
+ StartDrag.Raise (this, IFace.DragAndDropOperation);
#if DEBUG_DRAGNDROP
Debug.WriteLine(this.ToString() + " : START DRAG => " + e.ToString());
#endif
@@ -1807,7 +1842,7 @@ namespace Crow
ctx.Operator = Operator.Over;
}
- ctx.SetSourceSurface (bmp, rb.X, rb.Y);
+ ctx.SetSource (bmp, rb.X, rb.Y);
ctx.Paint ();
Clipping.Dispose ();
Clipping = new Region ();
@@ -1935,10 +1970,8 @@ namespace Crow
public virtual void onMouseMove (object sender, MouseMoveEventArgs e)
{
if (allowDrag & hasFocus & IFace.IsDown(MouseButton.Left)) {
- if (IFace.DragAndDropOperation == null) {
- IFace.DragAndDropOperation = new DragDropEventArgs (this);
- onStartDrag (this, IFace.DragAndDropOperation);
- }
+ if (IFace.DragAndDropOperation == null)
+ onStartDrag (this, IFace.DragAndDropOperation);
}
//dont bubble event if dragged, mouse move is routed directely from iface
@@ -2005,7 +2038,7 @@ namespace Crow
}
public virtual void onMouseEnter(object sender, MouseMoveEventArgs e)
{
- IFace.MouseCursor = MouseCursor;
+ IFace.MouseCursor = MouseCursor;
if (IFace.DragAndDropOperation != null) {
Widget g = this;
@@ -2025,7 +2058,10 @@ namespace Crow
MouseEnter.Raise (this, e);
}
public virtual void onMouseLeave(object sender, MouseMoveEventArgs e)
- {
+ {
+ if (IFace.DragAndDropOperation?.DropTarget == this)
+ IFace.DragAndDropOperation.DropTarget.onDragLeave (this, IFace.DragAndDropOperation);
+
MouseLeave.Raise (this, e);
}
diff --git a/Crow/src/Widgets/Window.cs b/Crow/src/Widgets/Window.cs
index accf198c..374b67d2 100644
--- a/Crow/src/Widgets/Window.cs
+++ b/Crow/src/Widgets/Window.cs
@@ -33,7 +33,7 @@ namespace Crow
Rectangle savedBounds;
bool _minimized = false;
- Direction currentDirection = Direction.None;
+ protected Direction currentDirection = Direction.None;
#region Events
public event EventHandler Closing;
@@ -63,13 +63,19 @@ namespace Crow
sizingHandle = child?.FindByName ("SizeHandle");
if (sizingHandle == null)
- return;
- sizingHandle.MouseEnter += (arg1, arg2) => IFace.SetStickyMouse(5);
+ return;
+ //sizingHandle.Unhover += (arg1, arg2) => currentDirection = Direction.None;
+ sizingHandle.Unhover += SizingHandle_Unhover;
}
- #endregion
- #region public properties
- [DefaultValue("#Crow.Icons.crow.svg")]
+ private void SizingHandle_Unhover (object sender, EventArgs e) {
+ currentDirection = Direction.None;
+ NotifyValueChanged ("CurDir", currentDirection);
+ }
+ #endregion
+
+ #region public properties
+ [DefaultValue("#Crow.Icons.crow.svg")]
public string Icon {
get { return _icon; }
set {
@@ -159,7 +165,7 @@ namespace Crow
/// <param name="XDelta">mouse delta on the X axis</param>
/// <param name="YDelta">mouse delta on the Y axis</param>
/// <param name="currentDirection">Current Direction of the operation, none for moving, other value for resizing in the given direction</param>
- public void MoveAndResize (int XDelta, int YDelta, Direction currentDirection = (Direction)0) {
+ protected void moveAndResize (int XDelta, int YDelta, Direction currentDirection = (Direction)0) {
int currentLeft = this.Left;
int currentTop = this.Top;
int currentWidth, currentHeight;
@@ -238,11 +244,9 @@ namespace Crow
{
base.onMouseMove (sender, e);
- Interface otkgw = IFace;
-
if (maySize || mayMove) {
if (grabMouse) {
- MoveAndResize (e.XDelta, e.YDelta, currentDirection);
+ moveAndResize (e.XDelta, e.YDelta, currentDirection);
return;
}
}else
@@ -276,50 +280,54 @@ namespace Crow
switch (currentDirection) {
case Direction.None:
- otkgw.MouseCursor = MouseCursor.move;
+ IFace.MouseCursor = MouseCursor.move;
break;
case Direction.N:
- otkgw.MouseCursor = MouseCursor.top_side;
+ IFace.MouseCursor = MouseCursor.top_side;
break;
case Direction.S:
- otkgw.MouseCursor = MouseCursor.bottom_side;
+ IFace.MouseCursor = MouseCursor.bottom_side;
break;
case Direction.E:
- otkgw.MouseCursor = MouseCursor.right_side;
+ IFace.MouseCursor = MouseCursor.right_side;
break;
case Direction.W:
- otkgw.MouseCursor = MouseCursor.left_side;
+ IFace.MouseCursor = MouseCursor.left_side;
break;
case Direction.NW:
- otkgw.MouseCursor = MouseCursor.top_left_corner;
+ IFace.MouseCursor = MouseCursor.top_left_corner;
break;
case Direction.NE:
- otkgw.MouseCursor = MouseCursor.top_right_corner;
+ IFace.MouseCursor = MouseCursor.top_right_corner;
break;
case Direction.SW:
- otkgw.MouseCursor = MouseCursor.bottom_left_corner;
+ IFace.MouseCursor = MouseCursor.bottom_left_corner;
break;
case Direction.SE:
- otkgw.MouseCursor = MouseCursor.bottom_right_corner;
+ IFace.MouseCursor = MouseCursor.bottom_right_corner;
break;
}
-
+ NotifyValueChanged ("CurDir", currentDirection);
}
public override void onMouseLeave (object sender, MouseMoveEventArgs e)
{
base.onMouseLeave (sender, e);
currentDirection = Direction.None;
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);
diff --git a/Samples/Directory.Build.props b/Samples/Directory.Build.props
index 120aa913..190db9dc 100644
--- a/Samples/Directory.Build.props
+++ b/Samples/Directory.Build.props
@@ -1,6 +1,6 @@
<Project>
<PropertyGroup>
- <TargetFrameworks>net472;netcoreapp3.1</TargetFrameworks>
+ <TargetFrameworks>netcoreapp3.1</TargetFrameworks>
<OutputType>Exe</OutputType>
<SolutionDir>$(MSBuildThisFileDirectory)..\</SolutionDir>
diff --git a/Samples/ShowCase/ShowCase.cs b/Samples/ShowCase/ShowCase.cs
index d8254317..8af2c002 100644
--- a/Samples/ShowCase/ShowCase.cs
+++ b/Samples/ShowCase/ShowCase.cs
@@ -16,6 +16,7 @@ namespace ShowCase
{
static void Main ()
{
+ Environment.SetEnvironmentVariable ("FONTCONFIG_PATH", @"C:\Users\Jean-Philippe\source\vcpkg\installed\x64-windows\tools\fontconfig\fonts");
using (Showcase app = new Showcase ())
app.Run ();
}
@@ -47,6 +48,7 @@ namespace ShowCase
set {
if (source == value)
return;
+
source = value;
reloadFromSource ();
CMDSave.CanExecute = source != origSource;
@@ -82,7 +84,7 @@ namespace ShowCase
}
public new bool IsDirty {
- get => origSource != source;
+ get => !string.Equals(origSource, source);
}
void onSave ()
{
diff --git a/Samples/common/samples.style b/Samples/common/samples.style
index 124cfcf4..50f91f4a 100644
--- a/Samples/common/samples.style
+++ b/Samples/common/samples.style
@@ -66,4 +66,7 @@ valignStyle2 {
Unchecked = "{Background=Black}";
//Initialized="GetDrawModeIcon";
//Initialized="{Background=Blue}";
+}
+smallLabel {
+ Font="consolas, 8";
} \ No newline at end of file
diff --git a/Samples/common/ui/Interfaces/Divers/2.crow b/Samples/common/ui/Interfaces/Divers/2.crow
index b4a06b68..d2c8c370 100644
--- a/Samples/common/ui/Interfaces/Divers/2.crow
+++ b/Samples/common/ui/Interfaces/Divers/2.crow
@@ -2,12 +2,13 @@
<VerticalStack Fit="true">
<TextBox Font="droid, 20" Text="test text box" Width="Stretched"/>
<HorizontalStack Margin="5" Fit="true" MouseEnter="{Background=White}" MouseLeave="{Background=Transparent}">
+ <Label Text="left" Width="80" Height="30" Background="DarkBlue" TextAlignment="Left"/>
<Label Text="centered" Width="80" Height="30" Background="DarkBlue" TextAlignment="Center"/>
<Label Text="top left" Width="80" Height="30" Background="DarkBlue" TextAlignment="TopLeft"/>
<Label Text="top right" Width="80" Height="30" Background="DarkBlue" TextAlignment="TopRight"/>
- <Label Text="right center" Width="80" Height="30" Background="DarkBlue" TextAlignment="Right"/>
+ <Label Text="right" Width="80" Height="30" Background="DarkBlue" TextAlignment="Right"/>
<Label Text="bottom left" Width="80" Height="30" Background="DarkBlue" TextAlignment="BottomLeft"/>
- <Label Text="bottom center" Width="80" Height="30" Background="DarkBlue" TextAlignment="Bottom"/>
+ <Label Text="bottom" Width="80" Height="30" Background="DarkBlue" TextAlignment="Bottom"/>
<Label Text="bottom right" Width="80" Height="30" Background="DarkBlue" TextAlignment="BottomRight"/>
</HorizontalStack>
</VerticalStack> \ No newline at end of file
diff --git a/Samples/common/ui/Interfaces/Experimental/testDock.crow b/Samples/common/ui/Interfaces/Experimental/testDock.crow
index b69f8e78..14659f88 100644
--- a/Samples/common/ui/Interfaces/Experimental/testDock.crow
+++ b/Samples/common/ui/Interfaces/Experimental/testDock.crow
@@ -1,8 +1,8 @@
<?xml version="1.0"?>
-<Window Width="Stretched" Height="Stretched" Background="Jet">
- <DockStack Name="mainDock" Background="DarkRed" Margin="20">
- </DockStack>
-</Window>
+<DockStack Name="mainDock" Background="Jet" Margin="0">
+ <DockWindow Resizable = "true" Top="100" Left="100" Caption="View 1" Width="300" Height="300"/>
+</DockStack>
+
<!---
<DockWindow Left="450" Top="450" Width="150" Height="150" Background="Yellow"/>-->
@@ -14,7 +14,7 @@
<Window Top="400" Left="400" Focusable="true" Caption="View 4" Resizable = "true" Width="300" Height="300"><Widget Focusable="true" Background="Black" MouseEnter="{Background=Grey}" MouseLeave="{Background=Black}"/></Window>
</Group>-->
<!--<Docker >
- <DockWindow Resizable = "true" Top="100" Left="100" Caption="View 1" Width="300" Height="300">
+
<VerticalStack Background="DarkGreen" Focusable="true">
<Label Text="{../../Left}" Background="Black" Width="Stretched"/>
<Label Text="{../../Top}" Background="Black"/>
diff --git a/Samples/common/ui/Interfaces/Experimental/testStack.crow b/Samples/common/ui/Interfaces/Experimental/testStack.crow
index 0348f0b5..97bbe62b 100644
--- a/Samples/common/ui/Interfaces/Experimental/testStack.crow
+++ b/Samples/common/ui/Interfaces/Experimental/testStack.crow
@@ -6,7 +6,7 @@
<HorizontalStack>
<Widget Height="Stretched" Width="100" Background="Red"/>
<Splitter/>
- <Widget Height="Stretched" Width="100" Background="DarkRed"/>
+ <Widget Height="Stretched" Width="Stretched" Background="DarkRed"/>
</HorizontalStack>
<Splitter/>
<Widget Height="100" Width="500" Background="Green"/>
diff --git a/Samples/dockableWindows/dockableWindows.cs b/Samples/dockableWindows/dockableWindows.cs
new file mode 100644
index 00000000..65223acc
--- /dev/null
+++ b/Samples/dockableWindows/dockableWindows.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using Crow;
+using Glfw;
+
+namespace tests
+{
+ public class BasicTests : SampleBase
+ {
+ static void Main ()
+ {
+ using (BasicTests app = new BasicTests ()) {
+ app.Run ();
+ }
+ }
+
+ protected override void OnInitialized () {
+ Load ("#ui.test.crow").DataSource = this;
+ AddWidget (new DockWindow (this) { Background = Colors.Blue, Left = 10, Top = 110, Resizable = true });
+ AddWidget (new DockWindow (this) { Background = Colors.Red, Left = 30, Top = 130, Resizable = true });
+ AddWidget (new DockWindow (this) { Background = Colors.Green, Left = 50, Top = 150, Resizable = true });
+ AddWidget (new DockWindow (this) { Background = Colors.Yellow, Left = 70, Top = 170, Resizable = true });
+ AddWidget (new DockWindow (this) { Background = Colors.Grey, Left = 90, Top = 190, Resizable = true });
+ }
+ private void refreshGraphicTree (object sender, MouseButtonEventArgs e) {
+ NotifyValueChanged ("GraphicTree", (object)null);
+ NotifyValueChanged ("GraphicTree", GraphicTree);
+ }
+
+ }
+}
diff --git a/Samples/dockableWindows/dockableWindows.csproj b/Samples/dockableWindows/dockableWindows.csproj
new file mode 100644
index 00000000..3c9729fe
--- /dev/null
+++ b/Samples/dockableWindows/dockableWindows.csproj
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project Sdk="Microsoft.NET.Sdk">
+ <ItemGroup>
+ <EmbeddedResource Include="ui\*.*">
+ <LogicalName>ui.%(Filename)%(Extension)</LogicalName>
+ </EmbeddedResource>
+ </ItemGroup>
+ <ItemGroup>
+ <EmbeddedResource Update="ui\GTreeExp.itemp">
+ <LogicalName>ui.%(Filename)%(Extension)</LogicalName>
+ </EmbeddedResource>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/Samples/dockableWindows/ui/GTreeExp.itemp b/Samples/dockableWindows/ui/GTreeExp.itemp
new file mode 100644
index 00000000..f2a7c2ba
--- /dev/null
+++ b/Samples/dockableWindows/ui/GTreeExp.itemp
@@ -0,0 +1,32 @@
+<?xml version="1.0"?>
+<Expandable IsExpanded="{²IsExpanded}" MouseDoubleClick="/onClickForExpand">
+ <Template>
+ <VerticalStack>
+ <Border CornerRadius="2" Margin="0" Height="Fit"
+ Foreground="Transparent"
+ MouseEnter="{Foreground=DimGrey}"
+ MouseLeave="{Foreground=Transparent}">
+ <HorizontalStack Spacing="1">
+ <Image Margin="1" Width="9" Height="9" Focusable="true" MouseDown="./onClickForExpand"
+ Path="{./Image}"
+ Visible="{./IsExpandable}"
+ SvgSub="{./IsExpanded}"
+ MouseEnter="{Background=LightGrey}"
+ MouseLeave="{Background=Transparent}"/>
+ <Border Width="16" Height="16" Foreground="Black" Background="DimGrey">
+ <Image Margin="2" Path="{GetIcon}" />
+ </Border>
+ <Widget Width="5" Height="5" Background="Blue" Visible="{IsHover}"/>
+ <Widget Width="5" Height="5" Background="Green" Visible="{Visible}"/>
+ <Label Text="{Name}" Width="Fit"/>
+ <Label Text="{LogicalParent}" Width="Stretched" Foreground="Yellow"/>
+ </HorizontalStack>
+ </Border>
+ <Container Name="Content" Visible="false"/>
+ </VerticalStack>
+ </Template>
+ <HorizontalStack Height="Fit">
+ <Widget Width="8" Height="10"/>
+ <VerticalStack Height="Fit" Name="ItemsContainer"/>
+ </HorizontalStack>
+</Expandable>
diff --git a/Samples/dockableWindows/ui/test.crow b/Samples/dockableWindows/ui/test.crow
new file mode 100644
index 00000000..3c16376b
--- /dev/null
+++ b/Samples/dockableWindows/ui/test.crow
@@ -0,0 +1,44 @@
+<?xml version="1.0"?>
+<VerticalStack>
+ <VerticalStack Name="Watches" Background="Black" Height="Fit" Width="Stretched">
+ <HorizontalStack Height="Fit">
+ <Label Style="smallLabel" Text="hover:" Width="50"/>
+ <Label Style="smallLabel" Text="{HoverWidget}"/>
+ </HorizontalStack>
+ <HorizontalStack Height="Fit">
+ <Label Style="smallLabel" Text="focus:" Width="50"/>
+ <Label Style="smallLabel" Text="{FocusedWidget}"/>
+ </HorizontalStack>
+ <HorizontalStack Height="Fit">
+ <Label Style="smallLabel" Text="active:" Width="50"/>
+ <Label Style="smallLabel" Text="{ActiveWidget}"/>
+ </HorizontalStack>
+ </VerticalStack>
+ <DockStack Height="70%"/>
+ <Splitter/>
+ <Button Caption="Refresh tree" MouseClick="refreshGraphicTree"/>
+ <TreeView IsRoot="true" Name="treeView" Data="{GraphicTree}">
+ <ItemTemplate>
+ <Border Width="Stretched" Focusable="true" Foreground="Transparent">
+ <HorizontalStack Spacing="5">
+ <Widget Width="5" Height="5"/>
+ <Border Width="16" Height="16" Foreground="Black" Background="DimGrey">
+ <Image Margin="2" Path="{GetIcon}" />
+ </Border>
+ <Widget Width="2" Height="5" Background="Blue" Visible="{IsHover}"/>
+ <Widget Width="5" Height="5" Background="Green" Visible="{Visible}"/>
+ <Label Text="{Name}" Width="Fit"/>
+ <Label Text="{LogicalParent}" Width="Stretched" Foreground="Yellow"/>
+ </HorizontalStack>
+ </Border>
+ </ItemTemplate>
+ <ItemTemplate DataType="Crow.Group" Data="GetChildren"
+ Path="#ui.GTreeExp.itemp"/>
+ <ItemTemplate DataType="Crow.Container" Data="GetChildren"
+ Path="#ui.GTreeExp.itemp"/>
+ <ItemTemplate DataType="Crow.TemplatedContainer" Data="GetChildren"
+ Path="#ui.GTreeExp.itemp"/>
+ <ItemTemplate DataType="Crow.TemplatedGroup" Data="GetChildren"
+ Path="#ui.GTreeExp.itemp"/>
+ </TreeView>
+</VerticalStack>
diff --git a/Samples/dragNdrop/dragNdrop.cs b/Samples/dragNdrop/dragNdrop.cs
new file mode 100644
index 00000000..0c985747
--- /dev/null
+++ b/Samples/dragNdrop/dragNdrop.cs
@@ -0,0 +1,65 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using Crow;
+using Glfw;
+
+namespace tests
+{
+ public class BasicTests : SampleBase
+ {
+ static void Main ()
+ {
+ using (BasicTests app = new BasicTests ()) {
+ app.Run ();
+ }
+ }
+
+ protected override void OnInitialized ()
+ {
+ Load ("#ui.test.crow").DataSource = this;
+ }
+
+ private void refreshGraphicTree (object sender, MouseButtonEventArgs e) {
+ NotifyValueChanged ("GraphicTree", (object)null);
+ NotifyValueChanged ("GraphicTree", GraphicTree);
+ }
+
+ Group startGroup = null;
+
+
+ private void W_StartDrag (object sender, DragDropEventArgs e) {
+ startGroup = e.DragSource.Parent as Group;
+ DragImageHeight = e.DragSource.LastPaintedSlot.Height;
+ DragImageWidth = e.DragSource.LastPaintedSlot.Width;
+
+ Crow.Cairo.Surface dragImg = surf.CreateSimilar (Crow.Cairo.Content.ColorAlpha, DragImageWidth, DragImageHeight);
+ using (Crow.Cairo.Context gr = new Crow.Cairo.Context(dragImg)) {
+ gr.SetSource (e.DragSource.bmp, 0, 0);
+ gr.Paint ();
+ }
+ DragImage = dragImg;
+ lock (UpdateMutex)
+ startGroup.RemoveChild (e.DragSource);
+ }
+ private void W_EndDrag (object sender, DragDropEventArgs e) {
+ lock (UpdateMutex)
+ startGroup.AddChild (e.DragSource);
+ }
+
+ private void W_DragEnter (object sender, DragDropEventArgs e) {
+ lock (UpdateMutex)
+ (e.DropTarget as Group).AddChild (e.DragSource);
+ }
+ private void W_DragLeave (object sender, DragDropEventArgs e) {
+ lock (UpdateMutex)
+ (e.DragSource.Parent as Group).RemoveChild (e.DragSource);
+ }
+ private void W_Drop (object sender, DragDropEventArgs e) {
+ //(e.DropTarget as Group).AddChild (e.DragSource);
+ }
+
+
+ }
+}
diff --git a/Samples/dragNdrop/dragNdrop.csproj b/Samples/dragNdrop/dragNdrop.csproj
new file mode 100644
index 00000000..9961c6b9
--- /dev/null
+++ b/Samples/dragNdrop/dragNdrop.csproj
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project Sdk="Microsoft.NET.Sdk">
+ <ItemGroup>
+ <EmbeddedResource Include="ui\*.*">
+ <LogicalName>ui.%(Filename)%(Extension)</LogicalName>
+ </EmbeddedResource>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/Samples/dragNdrop/ui/GTreeExp.itemp b/Samples/dragNdrop/ui/GTreeExp.itemp
new file mode 100644
index 00000000..f2a7c2ba
--- /dev/null
+++ b/Samples/dragNdrop/ui/GTreeExp.itemp
@@ -0,0 +1,32 @@
+<?xml version="1.0"?>
+<Expandable IsExpanded="{²IsExpanded}" MouseDoubleClick="/onClickForExpand">
+ <Template>
+ <VerticalStack>
+ <Border CornerRadius="2" Margin="0" Height="Fit"
+ Foreground="Transparent"
+ MouseEnter="{Foreground=DimGrey}"
+ MouseLeave="{Foreground=Transparent}">
+ <HorizontalStack Spacing="1">
+ <Image Margin="1" Width="9" Height="9" Focusable="true" MouseDown="./onClickForExpand"
+ Path="{./Image}"
+ Visible="{./IsExpandable}"
+ SvgSub="{./IsExpanded}"
+ MouseEnter="{Background=LightGrey}"
+ MouseLeave="{Background=Transparent}"/>
+ <Border Width="16" Height="16" Foreground="Black" Background="DimGrey">
+ <Image Margin="2" Path="{GetIcon}" />
+ </Border>
+ <Widget Width="5" Height="5" Background="Blue" Visible="{IsHover}"/>
+ <Widget Width="5" Height="5" Background="Green" Visible="{Visible}"/>
+ <Label Text="{Name}" Width="Fit"/>
+ <Label Text="{LogicalParent}" Width="Stretched" Foreground="Yellow"/>
+ </HorizontalStack>
+ </Border>
+ <Container Name="Content" Visible="false"/>
+ </VerticalStack>
+ </Template>
+ <HorizontalStack Height="Fit">
+ <Widget Width="8" Height="10"/>
+ <VerticalStack Height="Fit" Name="ItemsContainer"/>
+ </HorizontalStack>
+</Expandable>
diff --git a/Samples/dragNdrop/ui/test.crow b/Samples/dragNdrop/ui/test.crow
new file mode 100644
index 00000000..ce49ea71
--- /dev/null
+++ b/Samples/dragNdrop/ui/test.crow
@@ -0,0 +1,55 @@
+<?xml version="1.0"?>
+<VerticalStack Background="Jet" Focusable="true">
+ <VerticalStack Name="Watches" Background="Black" Height="Fit" Width="Stretched">
+ <HorizontalStack Height="Fit">
+ <Label Style="smallLabel" Text="hover:" Width="50"/>
+ <Label Style="smallLabel" Text="{HoverWidget}"/>
+ </HorizontalStack>
+ <HorizontalStack Height="Fit">
+ <Label Style="smallLabel" Text="focus:" Width="50"/>
+ <Label Style="smallLabel" Text="{FocusedWidget}"/>
+ </HorizontalStack>
+ <HorizontalStack Height="Fit">
+ <Label Style="smallLabel" Text="active:" Width="50"/>
+ <Label Style="smallLabel" Text="{ActiveWidget}"/>
+ </HorizontalStack>
+ </VerticalStack>
+ <HorizontalStack Margin="20" Name="zone1" Height="100" Width="Stretched" Background="Grey" AllowDrop="true" DragEnter="W_DragEnter" DragLeave="W_DragLeave">
+ <Widget Name="w1" Background="Blue" Focusable="true" Width="50" Height="Stretched" AllowDrag="true" StartDrag="W_StartDrag" EndDrag="W_EndDrag" Drop="W_Drop"/>
+ <Widget Name="w2" Background="Red" Focusable="true" Width="50" Height="Stretched" AllowDrag="true" StartDrag="W_StartDrag" EndDrag="W_EndDrag" Drop="W_Drop"/>/>
+ <Widget Name="w3" Background="Green" Focusable="true" Width="50" Height="Stretched" AllowDrag="true" StartDrag="W_StartDrag" EndDrag="W_EndDrag" Drop="W_Drop"/>/>
+ <Widget Name="w4" Background="Yellow" Focusable="true" Width="50" Height="Stretched" AllowDrag="true" StartDrag="W_StartDrag" EndDrag="W_EndDrag" Drop="W_Drop"/>/>
+ <Widget Name="w5" Background="DimGrey" Focusable="true" Width="50" Height="Stretched" AllowDrag="true" StartDrag="W_StartDrag" EndDrag="W_EndDrag" Drop="W_Drop"/>/>
+ </HorizontalStack>
+ <Widget Height="20" Focusable="true"/>
+ <HorizontalStack Margin="20" Name="zone2" Height="150" Width="Stretched" Background="Grey" AllowDrop="true" DragEnter="W_DragEnter" DragLeave="W_DragLeave">
+ </HorizontalStack>
+ <Widget Height="20"/>
+ <HorizontalStack Margin="20" Name="zone3" Height="80" Width="Stretched" Background="Grey" AllowDrop="true" DragEnter="W_DragEnter" DragLeave="W_DragLeave">
+ </HorizontalStack>
+ <Button Caption="Refresh tree" MouseClick="refreshGraphicTree"/>
+ <TreeView IsRoot="true" Name="treeView" Data="{GraphicTree}">
+ <ItemTemplate>
+ <Border Width="Stretched" Focusable="true" Foreground="Transparent">
+ <HorizontalStack Spacing="5">
+ <Widget Width="5" Height="5"/>
+ <Border Width="16" Height="16" Foreground="Black" Background="DimGrey">
+ <Image Margin="2" Path="{GetIcon}" />
+ </Border>
+ <Widget Width="2" Height="5" Background="Blue" Visible="{IsHover}"/>
+ <Widget Width="5" Height="5" Background="Green" Visible="{Visible}"/>
+ <Label Text="{Name}" Width="Fit"/>
+ <Label Text="{LogicalParent}" Width="Stretched" Foreground="Yellow"/>
+ </HorizontalStack>
+ </Border>
+ </ItemTemplate>
+ <ItemTemplate DataType="Crow.Group" Data="GetChildren"
+ Path="#ui.GTreeExp.itemp"/>
+ <ItemTemplate DataType="Crow.Container" Data="GetChildren"
+ Path="#ui.GTreeExp.itemp"/>
+ <ItemTemplate DataType="Crow.TemplatedContainer" Data="GetChildren"
+ Path="#ui.GTreeExp.itemp"/>
+ <ItemTemplate DataType="Crow.TemplatedGroup" Data="GetChildren"
+ Path="#ui.GTreeExp.itemp"/>
+ </TreeView>
+</VerticalStack> \ No newline at end of file