From 8d1522d4cb7ff6db0a9f0c7a61dd75faa887fdd7 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jean-Philippe=20Bruy=C3=A8re?= Date: Sun, 11 Apr 2021 15:25:22 +0200 Subject: [PATCH] debug docking windows --- Crow/Default.style | 28 +- Crow/Templates/DockWindow.template | 4 +- Crow/Templates/DockingTabView.template | 25 + Crow/Templates/FileDialog.template | 2 +- Crow/Templates/MessageBox.template | 2 +- Crow/src/Interface.cs | 36 +- Crow/src/Mono.Cairo/ImageSurface.cs | 9 +- Crow/src/Mono.Cairo/Surface.cs | 8 +- Crow/src/Mono.Cairo/XlibSurface.cs | 36 +- Crow/src/Widgets/DockStack.cs | 159 ++--- Crow/src/Widgets/DockWindow.cs | 156 ++++- Crow/src/Widgets/Window.cs | 136 ++-- Samples/common/SampleBase.cs | 636 ++++++++++-------- Samples/common/samples.style | 12 +- .../{Crow.Docker.svg => Crow.DockStack.svg} | 0 Samples/common/ui/icons/Crow.DockWindow.svg | 6 + Samples/dockableWindows/dockableWindows.cs | 27 +- Samples/dockableWindows/ui/TabView.template | 32 + Samples/dockableWindows/ui/dock.style | 12 + Samples/dockableWindows/ui/dockWin.template | 24 + Samples/dockableWindows/ui/test.crow | 11 +- Samples/dragNdrop/dragNdrop.cs | 8 +- 22 files changed, 806 insertions(+), 563 deletions(-) create mode 100644 Crow/Templates/DockingTabView.template rename Samples/common/ui/icons/{Crow.Docker.svg => Crow.DockStack.svg} (100%) create mode 100644 Samples/common/ui/icons/Crow.DockWindow.svg create mode 100644 Samples/dockableWindows/ui/TabView.template create mode 100644 Samples/dockableWindows/ui/dock.style create mode 100644 Samples/dockableWindows/ui/dockWin.template diff --git a/Crow/Default.style b/Crow/Default.style index 622f5b79..3c09d3b9 100644 --- a/Crow/Default.style +++ b/Crow/Default.style @@ -23,6 +23,8 @@ WindowTitleBarForeground = "White"; MenuBackground = "Jet"; +InactiveTabItem = "Jet"; + Button, CheckBox, RadioButton, ComboBox, Expandable, MessageBox, Popper, Slider, Spinner, TextBox { //Focusable = "true"; @@ -33,6 +35,8 @@ MessageBox, Popper, Slider, Spinner, TextBox { Margin="0"; } +Border { Margin = "1"; } + CheckBox { Caption = "CheckBox"; } RadioButton { Caption = "RadioButton"; } Expandable { Caption = "Expandable"; } @@ -153,10 +157,11 @@ winBorder { BorderWidth = "${WindowBorderWidth}"; Foreground = "${WindowBorderColor}"; Background = "${WindowBackgroundColor}"; - Margin = "0"; + Margin = "1"; } WindowIconBorder { BorderWidth="1"; + Margin="1"; Foreground="Transparent"; Height="12"; Width="12"; @@ -171,23 +176,13 @@ ToolWindow { Width = "150"; Height = "150"; } -Docker { - AllowDrop = "false"; - Margin="0"; - Focusable="true"; -} DockStack { - Margin="2"; - Spacing="2"; + Margin="0"; + Spacing="1"; AllowDrop = "true"; AllowedDropTypes = "Crow.DockWindow"; - Focusable="true"; - //DragEnter="{Background=Blue}"; - //DragLeave="{Background=Transparent}"; - //EndDrag="{Background=Jet}"; } -DockWindow { - //Background = "Onyx"; +DockWindow { Focusable = "true"; AllowDrag = "true"; AllowDrop="true"; @@ -196,8 +191,13 @@ DockWindow { Margin="0"; Width="200"; Height="200"; + HorizontalAlignment="Left"; + VerticalAlignment="Top"; //MinimumSize="50,50"; } +DockingTabView { + Template = "#Crow.DockingTabView.template"; +} FileDialog { Template = "#Crow.FileDialog.template"; AlwaysOnTop = "true"; diff --git a/Crow/Templates/DockWindow.template b/Crow/Templates/DockWindow.template index 9a2bd3b4..7f6183e3 100644 --- a/Crow/Templates/DockWindow.template +++ b/Crow/Templates/DockWindow.template @@ -8,7 +8,7 @@ + MouseClick="./onQuitPress"/> + MouseClick="./onQuitPress"/> diff --git a/Crow/Templates/DockingTabView.template b/Crow/Templates/DockingTabView.template new file mode 100644 index 00000000..b041167f --- /dev/null +++ b/Crow/Templates/DockingTabView.template @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + diff --git a/Crow/Templates/FileDialog.template b/Crow/Templates/FileDialog.template index c17da65e..2c49e470 100644 --- a/Crow/Templates/FileDialog.template +++ b/Crow/Templates/FileDialog.template @@ -8,7 +8,7 @@ + MouseClick="./onQuitPress"/> diff --git a/Crow/Templates/MessageBox.template b/Crow/Templates/MessageBox.template index 8a3ea804..3cccc4d2 100644 --- a/Crow/Templates/MessageBox.template +++ b/Crow/Templates/MessageBox.template @@ -9,7 +9,7 @@ + MouseClick="./onQuitPress"/> diff --git a/Crow/src/Interface.cs b/Crow/src/Interface.cs index cd82dee6..5fc9d2b9 100644 --- a/Crow/src/Interface.cs +++ b/Crow/src/Interface.cs @@ -469,13 +469,26 @@ namespace Crow internal Widget dragndropHover; public Surface DragImage = null; - public int DragImageWidth, DragImageHeight, DragImageX, DragImageY; + public Rectangle DragImageBounds; + public bool DragImageFolowMouse;//prevent dragImg to be moved by mouse public void ClearDragImage () { - lock (UpdateMutex) { - clipping.UnionRectangle(new Rectangle (DragImageX, DragImageY, DragImageWidth, DragImageHeight)); + lock (UpdateMutex) { + if (DragImage == null) + return; + clipping.UnionRectangle (DragImageBounds); DragImage.Dispose(); DragImage = null; - } + DragImageBounds = default; + } + } + public void CreateDragImage (Surface img, Rectangle bounds, bool followMouse = true) { + lock (UpdateMutex) { + if (DragImage != null) + ClearDragImage (); + DragImage = img; + DragImageBounds = bounds; + DragImageFolowMouse = followMouse; + } } #endregion @@ -965,7 +978,7 @@ namespace Crow DbgLogger.StartEvent (DbgEvtType.ProcessDrawing); if (DragImage != null) - clipping.UnionRectangle(new Rectangle (DragImageX, DragImageY, DragImageWidth, DragImageHeight)); + clipping.UnionRectangle(DragImageBounds); if (!clipping.IsEmpty) { PerformanceMeasure.Begin (PerformanceMeasure.Kind.Drawing); @@ -994,17 +1007,18 @@ namespace Crow if (DragAndDropOperation != null) { if (DragImage != null) { - DirtyRect += new Rectangle (DragImageX, DragImageY, DragImageWidth, DragImageHeight); - DragImageX = MousePosition.X - DragImageWidth / 2; - DragImageY = MousePosition.Y - DragImageHeight / 2; + DirtyRect += DragImageBounds; + if (DragImageFolowMouse) { + DragImageBounds.X = MousePosition.X - DragImageBounds.Width / 2; + DragImageBounds.Y = MousePosition.Y - DragImageBounds.Height / 2; + } ctx.Save (); ctx.ResetClip (); - ctx.SetSource (DragImage, DragImageX, DragImageY); + ctx.SetSource (DragImage, DragImageBounds.X, DragImageBounds.Y); ctx.PaintWithAlpha (0.8); ctx.Restore (); - DirtyRect += new Rectangle (DragImageX, DragImageY, DragImageWidth, DragImageHeight); + DirtyRect += DragImageBounds; IsDirty = true; - //System.Diagnostics.Debug.WriteLine ("dragimage drawn: {0},{1}", DragImageX, DragImageY); } } diff --git a/Crow/src/Mono.Cairo/ImageSurface.cs b/Crow/src/Mono.Cairo/ImageSurface.cs index 1dd83296..7c70569d 100644 --- a/Crow/src/Mono.Cairo/ImageSurface.cs +++ b/Crow/src/Mono.Cairo/ImageSurface.cs @@ -69,13 +69,8 @@ namespace Crow.Cairo { { } - public int Width { - get { return NativeMethods.cairo_image_surface_get_width (Handle); } - } - - public int Height { - get { return NativeMethods.cairo_image_surface_get_height (Handle); } - } + public override int Width => NativeMethods.cairo_image_surface_get_width (Handle); + public override int Height => NativeMethods.cairo_image_surface_get_height (Handle); public byte[] Data { get { diff --git a/Crow/src/Mono.Cairo/Surface.cs b/Crow/src/Mono.Cairo/Surface.cs index 70821435..56c1553f 100644 --- a/Crow/src/Mono.Cairo/Surface.cs +++ b/Crow/src/Mono.Cairo/Surface.cs @@ -125,12 +125,6 @@ namespace Crow.Cairo { Dispose (false); } - //[Obsolete ("Use Context.SetSource() followed by Context.Paint()")] - public void Show (Context gr, double x, double y) - { - NativeMethods.cairo_set_source_surface (gr.Handle, handle, x, y); - NativeMethods.cairo_paint (gr.Handle); - } public void Dispose () { @@ -172,6 +166,8 @@ namespace Crow.Cairo { { NativeMethods.cairo_surface_mark_dirty_rectangle (Handle, rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height); } + public virtual int Width => -1; + public virtual int Height => -1; public IntPtr Handle { get { diff --git a/Crow/src/Mono.Cairo/XlibSurface.cs b/Crow/src/Mono.Cairo/XlibSurface.cs index 30b56f04..18e810bd 100644 --- a/Crow/src/Mono.Cairo/XlibSurface.cs +++ b/Crow/src/Mono.Cairo/XlibSurface.cs @@ -4,9 +4,11 @@ // Authors: // Duncan Mak // Miguel de Icaza. +// JP Bruyère // // (C) Ximian Inc, 2003. // (C) Novell, Inc. 2003. +// (C) JP Bruyère 2021 // // This is an OO wrapper API for the Cairo API // @@ -63,33 +65,13 @@ namespace Crow.Cairo { NativeMethods.cairo_xlib_surface_set_size (Handle, width, height); } - public int Depth { - get { return NativeMethods.cairo_xlib_surface_get_depth (Handle); } - } - - public IntPtr Display { - get { return NativeMethods.cairo_xlib_surface_get_display (Handle); } - } - - public IntPtr Drawable { - get { return NativeMethods.cairo_xlib_surface_get_drawable (Handle); } - } - - public int Height { - get { return NativeMethods.cairo_xlib_surface_get_height (Handle); } - } - - public IntPtr Screen { - get { return NativeMethods.cairo_xlib_surface_get_screen (Handle); } - } - - public IntPtr Visual { - get { return NativeMethods.cairo_xlib_surface_get_visual (Handle); } - } - - public int Width { - get { return NativeMethods.cairo_xlib_surface_get_width (Handle); } - } + public int Depth => NativeMethods.cairo_xlib_surface_get_depth (Handle); + public IntPtr Display => NativeMethods.cairo_xlib_surface_get_display (Handle); + public IntPtr Drawable => NativeMethods.cairo_xlib_surface_get_drawable (Handle); + public override int Width => NativeMethods.cairo_xlib_surface_get_width (Handle); + public override int Height => NativeMethods.cairo_xlib_surface_get_height (Handle); + public IntPtr Screen => NativeMethods.cairo_xlib_surface_get_screen (Handle); + public IntPtr Visual=> NativeMethods.cairo_xlib_surface_get_visual (Handle); } } diff --git a/Crow/src/Widgets/DockStack.cs b/Crow/src/Widgets/DockStack.cs index b5c05ece..f0eaa176 100644 --- a/Crow/src/Widgets/DockStack.cs +++ b/Crow/src/Widgets/DockStack.cs @@ -37,7 +37,7 @@ namespace Crow g.LogicalParent = this.LogicalParent; } - public override bool PointIsIn (ref Point m) + /*public override bool PointIsIn (ref Point m) { if (!base.PointIsIn(ref m)) return false; @@ -59,7 +59,7 @@ namespace Crow } return Slot.ContainsOrIsEqual(m); - } + }*/ // public override void OnLayoutChanges (LayoutingType layoutType) // { @@ -72,7 +72,7 @@ namespace Crow Rectangle rIn = default(Rectangle); double dockThresh = 0.2; const int dockWidthDivisor = 8; - Widget focusedChild; + internal Widget focusedChild; internal Widget stretchedChild; void getFocusedChild (Point lm) { @@ -157,7 +157,7 @@ namespace Crow protected override void onDragEnter (object sender, DragDropEventArgs e) { base.onDragEnter (sender, e); - RegisterForGraphicUpdate (); + } public override void onDragLeave (object sender, DragDropEventArgs e) { @@ -165,73 +165,7 @@ namespace Crow //if (dw != null) // dw.DockingPosition = Alignment.Undefined; base.onDragLeave (sender, e); - RegisterForGraphicUpdate (); - } - - protected override void onDraw (Cairo.Context gr) - { - gr.Save (); - - Rectangle rBack = new Rectangle (Slot.Size); - - Background.SetAsSource (IFace, gr, rBack); - CairoHelpers.CairoRectangle (gr, rBack, CornerRadius); - gr.Fill (); - - if (ClipToClientRect) { - //clip to client zone - CairoHelpers.CairoRectangle (gr, ClientRectangle, CornerRadius); - gr.Clip (); - } - - childrenRWLock.EnterReadLock (); - - foreach (Widget g in Children) - g.Paint (gr); - - childrenRWLock.ExitReadLock (); - if (!(IsDropTarget || (IFace.DropTarget is DockWindow dtdw && dtdw.Parent == this))) { - gr.Restore (); - return; - } - - DockWindow dw = IFace.DragAndDropOperation.DragSource as DockWindow; - if (dw == null) - return; - if (!dw.IsDocked) { - Rectangle cb = ClientRectangle; - double minDim = Math.Min (cb.Width, cb.Height); - - Rectangle r = rIn; - if (Children.Count <= 1 || dw.DockingPosition.GetOrientation()==Orientation ) - r = cb; - - switch (dw.DockingPosition) { - case Alignment.Top: - gr.Rectangle (r.Left, r.Top, r.Width, r.Height * dockThresh); - break; - case Alignment.Bottom: - gr.Rectangle (r.Left, r.Bottom - r.Height * dockThresh, r.Width, r.Height * dockThresh); - break; - case Alignment.Left: - gr.Rectangle (r.Left, r.Top, r.Width * dockThresh, r.Height); - break; - case Alignment.Right: - gr.Rectangle (r.Right - r.Width * dockThresh, r.Top, r.Width * dockThresh, r.Height); - break; - case Alignment.Center: - r.Inflate ((int)Math.Ceiling (Math.Min (r.Width, r.Height) * -0.05)); - gr.Rectangle (r); - break; - } - gr.LineWidth = 1; - gr.SetSource (0.4, 0.4, 0.9, 0.4); - gr.FillPreserve (); - gr.SetSource (0.9, 0.9, 1.0, 0.8); - gr.Stroke (); - } - gr.Restore (); } public void Dock(DockWindow dw){ @@ -239,9 +173,8 @@ namespace Crow if (Children.Count == 1) { Orientation = dw.DockingPosition.GetOrientation (); - if (Children [0] is DockWindow) { - (Children [0] as DockWindow).DockingPosition = dw.DockingPosition.GetOpposite (); - } + if (Children [0] is DockWindow dwc) + dwc.DockingPosition = dw.DockingPosition.GetOpposite (); } else if (Children.Count > 0 && dw.DockingPosition.GetOrientation () != Orientation) { activeStack = new DockStack (IFace); activeStack.Orientation = dw.DockingPosition.GetOrientation (); @@ -254,8 +187,8 @@ namespace Crow InsertChild (idx, activeStack); activeStack.AddChild (focusedChild); activeStack.stretchedChild = focusedChild; - if (focusedChild is DockWindow) - (focusedChild as DockWindow).DockingPosition = dw.DockingPosition.GetOpposite (); + if (focusedChild is DockWindow dwf) + dwf.DockingPosition = dw.DockingPosition.GetOpposite (); focusedChild = null; } @@ -304,7 +237,7 @@ namespace Crow RemoveChild(dw); - if (Children.Count == 0) + if (Children.Count == 0)//TODO:empty Stack should be removed if not root stack I guess return; if (dw.DockingPosition == Alignment.Left || dw.DockingPosition == Alignment.Top) { @@ -375,6 +308,28 @@ namespace Crow public string ExportConfig () { return Orientation.ToString() + ";" + exportConfig(); } + + DockWindow importDockWinConfig (string conf, ref int i, object dataSource){ + DockWindow dw = null; + string wName = getConfAttrib (conf, ref i); + try { + dw = IFace.CreateInstance (wName) as DockWindow; + } catch { + 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 (getConfAttrib (conf, ref i)); + dw.savedSlot = Rectangle.Parse (getConfAttrib (conf, ref i)); + dw.wasResizable = Boolean.Parse (getConfAttrib (conf, ref i)); + dw.Resizable = false; + + dw.IsDocked = true; + dw.DataSource = dataSource; + return dw; + } void importConfig (string conf, ref int i, object dataSource) { if (conf [i++] != '(') return; @@ -382,27 +337,18 @@ namespace Crow string sc = conf.Substring (i, 4); i += 4; switch (sc) { - case "WIN;": - DockWindow dw = null; - string wName = getConfAttrib (conf, ref i); - try { - dw = IFace.CreateInstance (wName) as DockWindow; - } catch { - 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 (getConfAttrib (conf, ref i)); - dw.savedSlot = Rectangle.Parse (getConfAttrib (conf, ref i)); - dw.wasResizable = Boolean.Parse (getConfAttrib (conf, ref i)); - dw.Resizable = false; - - dw.IsDocked = true; - dw.DataSource = dataSource; - this.AddChild (dw); - + case "TVI;": + TabView tv = new TabView (IFace, "DockingTabView"); + tv.Width = Measure.Parse (getConfAttrib (conf, ref i)); + tv.Height = Measure.Parse (getConfAttrib (conf, ref i)); + this.AddChild (tv); + i++; + while (conf [i] != ')') + tv.AddItem (importDockWinConfig (conf, ref i, dataSource)); + i++; + break; + case "WIN;": + this.AddChild (importDockWinConfig (conf, ref i, dataSource)); break; case "STK;": DockStack ds = new DockStack (IFace); @@ -431,16 +377,17 @@ namespace Crow StringBuilder tmp = new StringBuilder("("); for (int i = 0; i < Children.Count; i++) { - if (Children [i] is DockWindow) { - DockWindow dw = Children [i] as DockWindow; - tmp.Append (string.Format("WIN;{0};{1};{2};{3};{4};{5};",dw.Name, dw.Width, dw.Height, dw.DockingPosition, dw.savedSlot, dw.wasResizable)); - } else if (Children [i] is DockStack) { - DockStack ds = Children [i] as DockStack; - tmp.Append (string.Format("STK;{0};{1};{2};{3}", ds.Width, ds.Height, ds.Orientation, ds.exportConfig())); - } else if (Children [i] is Splitter) { - Splitter sp = Children [i] as Splitter; + if (Children [i] is DockWindow dw) + tmp.Append (dw.GetConfigString()); + 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 (")"); + }else if (Children [i] is DockStack ds) + tmp.Append ($"STK;{ds.Width};{ds.Height};{ds.Orientation};{ds.exportConfig()}"); + else if (Children [i] is Splitter sp) tmp.Append (string.Format("SPL;{0};{1};{2};", sp.Width, sp.Height, sp.Thickness)); - } if (i < Children.Count - 1) tmp.Append ("|"); } diff --git a/Crow/src/Widgets/DockWindow.cs b/Crow/src/Widgets/DockWindow.cs index 200f2f12..4c99c637 100644 --- a/Crow/src/Widgets/DockWindow.cs +++ b/Crow/src/Widgets/DockWindow.cs @@ -4,6 +4,7 @@ using System; using System.Xml.Serialization; +using Crow.Cairo; using Glfw; namespace Crow @@ -44,7 +45,7 @@ namespace Crow NotifyValueChangedAuto (DockingPosition); } } - public override bool PointIsIn (ref Point m) + /*public override bool PointIsIn (ref Point m) { if (!base.PointIsIn(ref m)) return false; @@ -64,7 +65,7 @@ namespace Crow } } return Slot.ContainsOrIsEqual(m); - } + }*/ public override void onDrag (object sender, MouseMoveEventArgs e) { @@ -74,10 +75,71 @@ namespace Crow moveAndResize (e.XDelta, e.YDelta, currentDirection); base.onDrag (sender, e); - if (IFace.DragAndDropOperation.DropTarget is DockStack ds) + + if (isDocked) + return; + + Alignment dockingPosSave = DockingPosition; + Rectangle r = default; + + Console.WriteLine ($"onDrag target={IFace.DragAndDropOperation.DropTarget}"); + + if (IFace.DragAndDropOperation.DropTarget is DockStack ds) { ds.onDragMouseMove (this, e); - else if (IFace.DragAndDropOperation.DropTarget is DockWindow dw) - (dw.Parent as DockStack)?.onDragMouseMove (this, e); + r = ds.ScreenCoordinates (ds.LastPaintedSlot); + }else if (IFace.DragAndDropOperation.DropTarget is DockWindow dw && dw.IsDocked == true) { + Point m = dw.ScreenPointToLocal (e.Position); + Rectangle dwCb = dw.ClientRectangle; + dwCb.Inflate (dwCb.Width / -3, dwCb.Height / -3); + if (dwCb.ContainsOrIsEqual(m)) { + DockingPosition = Alignment.Center; + r = dw.ScreenCoordinates (dw.LastPaintedSlot); + Console.WriteLine ("center"); + } else if (dw.Parent is DockStack dsp) { + dsp.onDragMouseMove (this, e); + if (dsp.focusedChild == null) + r = dsp.ScreenCoordinates (dsp.LastPaintedSlot); + else + r = dsp.focusedChild.ScreenCoordinates (dsp.focusedChild.LastPaintedSlot); + } + }else + DockingPosition = Alignment.Undefined; + + if (DockingPosition != dockingPosSave) { + if (DockingPosition == Alignment.Undefined) { + IFace.ClearDragImage (); + return; + } + switch (DockingPosition) { + case Alignment.Top: + r.Height /= 4; + break; + case Alignment.Bottom: + r.Y += r.Height - r.Height / 4; + r.Height /= 4; + break; + case Alignment.Left: + r.Width /= 4; + break; + case Alignment.Right: + r.X += r.Width - r.Width / 4; + r.Width /= 4; + break; + case Alignment.Center: + r.Inflate (r.Width / -3, r.Height / -3); + break; + } + Surface dragImg = IFace.surf.CreateSimilar (Crow.Cairo.Content.ColorAlpha, r.Width, r.Height); + using (Crow.Cairo.Context gr = new Crow.Cairo.Context(dragImg)) { + gr.LineWidth = 1; + gr.Rectangle (0,0,r.Width,r.Height); + gr.SetSource (0.2,0.3,0.9,0.5); + gr.FillPreserve (); + gr.SetSource (0.1,0.2,1); + gr.Stroke (); + } + IFace.CreateDragImage (dragImg, r, false); + } } protected override void onDragEnter (object sender, DragDropEventArgs e) { base.onDragEnter (sender, e); @@ -113,16 +175,40 @@ namespace Crow if (!(isDocked || DockingPosition == Alignment.Undefined)) { if (e.DropTarget is DockStack ds) Dock (ds); - else if (e.DropTarget is DockWindow dw) - Dock (dw.Parent as DockStack); + else if (e.DropTarget is DockWindow dw) { + if (DockingPosition == Alignment.Center) + Dock (dw); + else + Dock (dw.Parent as DockStack); + } } base.onDrop (sender, e); + IFace.ClearDragImage (); } public void Undock () { lock (IFace.UpdateMutex) { - DockStack ds = Parent as DockStack; - ds.Undock (this); - + if (LogicalParent is TabView tv) { + tv.RemoveItem (this, false); + if (tv.Items.Count == 1) { + Widget w = tv.Items[0]; + tv.RemoveItem (w, false); + DockStack ds = tv.Parent as DockStack; + int idx = ds.Children.IndexOf (tv); + ds.RemoveChild (tv); + ds.InsertChild (idx, w); + w.Width = tv.Width; + w.Height = tv.Height; + if (ds.stretchedChild == tv) + ds.stretchedChild = w; + tv.Dispose(); + w.IsVisible = true; + ds.checkAlignments(); + } + } else if (Parent is DockStack ds) { + ds.Undock (this); + } else + throw new Exception ("docking error"); + IFace.AddWidget (this); Left = IFace.MousePosition.X - 10; @@ -136,18 +222,47 @@ namespace Crow } } - public void Dock (DockStack target){ + void dock () { + IFace.RemoveWidget (this); + + undockingMousePosOrig = IFace.MousePosition; + //undockingMousePosOrig = lastMousePos; + savedSlot = this.LastPaintedSlot; + wasResizable = Resizable; + Resizable = false; + LastSlots = LastPaintedSlot = Slot = default(Rectangle); + Left = Top = 0; + } + public void Dock (DockWindow target) { lock (IFace.UpdateMutex) { //IsDocked = true; - undockingMousePosOrig = IFace.MousePosition; - //undockingMousePosOrig = lastMousePos; - savedSlot = this.LastPaintedSlot; - wasResizable = Resizable; - Resizable = false; - LastSlots = LastPaintedSlot = Slot = default(Rectangle); - Left = Top = 0; + dock (); - IFace.RemoveWidget (this); + if (target.LogicalParent is TabView tv) { + tv.AddItem (this); + DockingPosition = Alignment.Center; + this.Width = this.Height = Measure.Stretched; + IsDocked = true; + } else if (target.Parent is DockStack ds) { + int idx = ds.Children.IndexOf (target); + ds.RemoveChild (target); + TabView tv2 = new TabView(IFace, "DockingTabView"); + ds.InsertChild (idx, tv2); + tv2.Width = target.Width; + tv2.Height = target.Height; + if (ds.stretchedChild == target) + ds.stretchedChild = tv2; + tv2.AddItem (target); + tv2.AddItem (this); + target.Width = target.Height = this.Width = this.Height = Measure.Stretched; + target.DockingPosition = this.DockingPosition = Alignment.Center; + IsDocked = true; + } + } + } + public void Dock (DockStack target){ + lock (IFace.UpdateMutex) { + dock (); target.Dock (this); } @@ -159,6 +274,9 @@ namespace Crow Undock (); base.close (); } + + internal string GetConfigString () => + string.Format($"WIN;{Name};{Width};{Height};{DockingPosition};{savedSlot};{wasResizable};"); } } diff --git a/Crow/src/Widgets/Window.cs b/Crow/src/Widgets/Window.cs index e18c1d77..f7bd5144 100644 --- a/Crow/src/Widgets/Window.cs +++ b/Crow/src/Widgets/Window.cs @@ -154,74 +154,76 @@ namespace Crow /// mouse delta on the Y axis /// Current Direction of the operation, none for moving, other value for resizing in the given direction protected void moveAndResize (int XDelta, int YDelta, Direction currentDirection = (Direction)0) { - int currentLeft = this.Left; - int currentTop = this.Top; - int currentWidth, currentHeight; - - if (currentLeft == 0) { - currentLeft = this.Slot.Left; - this.Left = currentLeft; - } - if (currentTop == 0) { - currentTop = this.Slot.Top; - this.Top = currentTop; - } - if (this.Width.IsFixed) - currentWidth = this.Width; - else - currentWidth = this.Slot.Width; - - if (this.Height.IsFixed) - currentHeight = this.Height; - else - currentHeight = this.Slot.Height; - - switch (currentDirection) { - case Direction.None: - this.Left = currentLeft + XDelta; - this.Top = currentTop + YDelta; - break; - case Direction.N: - this.Height = currentHeight - YDelta; - if (this.Height == currentHeight - YDelta) - this.Top = currentTop + YDelta; - break; - case Direction.S: - this.Height = currentHeight + YDelta; - break; - case Direction.W: - this.Width = currentWidth - XDelta; - if (this.Width == currentWidth - XDelta) - this.Left = currentLeft + XDelta; - break; - case Direction.E: - this.Width = currentWidth + XDelta; - break; - case Direction.NW: - this.Height = currentHeight - YDelta; - if (this.Height == currentHeight - YDelta) - this.Top = currentTop + YDelta; - this.Width = currentWidth - XDelta; - if (this.Width == currentWidth - XDelta) - this.Left = currentLeft + XDelta; - break; - case Direction.NE: - this.Height = currentHeight - YDelta; - if (this.Height == currentHeight - YDelta) + lock (IFace.UpdateMutex) { + int currentLeft = this.Left; + int currentTop = this.Top; + int currentWidth, currentHeight; + + if (currentLeft == 0) { + currentLeft = this.Slot.Left; + this.Left = currentLeft; + } + if (currentTop == 0) { + currentTop = this.Slot.Top; + this.Top = currentTop; + } + if (this.Width.IsFixed) + currentWidth = this.Width; + else + currentWidth = this.Slot.Width; + + if (this.Height.IsFixed) + currentHeight = this.Height; + else + currentHeight = this.Slot.Height; + + switch (currentDirection) { + case Direction.None: + this.Left = currentLeft + XDelta; this.Top = currentTop + YDelta; - this.Width = currentWidth + XDelta; - break; - case Direction.SW: - this.Width = currentWidth - XDelta; - if (this.Width == currentWidth - XDelta) - this.Left = currentLeft + XDelta; - this.Height = currentHeight + YDelta; - break; - case Direction.SE: - this.Height = currentHeight + YDelta; - this.Width = currentWidth + XDelta; - break; - } + break; + case Direction.N: + this.Height = currentHeight - YDelta; + if (this.Height == currentHeight - YDelta) + this.Top = currentTop + YDelta; + break; + case Direction.S: + this.Height = currentHeight + YDelta; + break; + case Direction.W: + this.Width = currentWidth - XDelta; + if (this.Width == currentWidth - XDelta) + this.Left = currentLeft + XDelta; + break; + case Direction.E: + this.Width = currentWidth + XDelta; + break; + case Direction.NW: + this.Height = currentHeight - YDelta; + if (this.Height == currentHeight - YDelta) + this.Top = currentTop + YDelta; + this.Width = currentWidth - XDelta; + if (this.Width == currentWidth - XDelta) + this.Left = currentLeft + XDelta; + break; + case Direction.NE: + this.Height = currentHeight - YDelta; + if (this.Height == currentHeight - YDelta) + this.Top = currentTop + YDelta; + this.Width = currentWidth + XDelta; + break; + case Direction.SW: + this.Width = currentWidth - XDelta; + if (this.Width == currentWidth - XDelta) + this.Left = currentLeft + XDelta; + this.Height = currentHeight + YDelta; + break; + case Direction.SE: + this.Height = currentHeight + YDelta; + this.Width = currentWidth + XDelta; + break; + } + } } bool maySize => sizingHandle == null ? false : resizable & sizingHandle.IsHover; diff --git a/Samples/common/SampleBase.cs b/Samples/common/SampleBase.cs index a17eaf92..22d1fb0b 100644 --- a/Samples/common/SampleBase.cs +++ b/Samples/common/SampleBase.cs @@ -12,301 +12,371 @@ using System.Threading; namespace Crow { - public class SampleBase : Interface - { + public class SampleBase : Interface + { #if NETCOREAPP - static IntPtr resolveUnmanaged (Assembly assembly, String libraryName) { - + static IntPtr resolveUnmanaged(Assembly assembly, String libraryName) + { + switch (libraryName) { case "glfw3": - return NativeLibrary.Load("glfw", assembly, null); + return NativeLibrary.Load("glfw", assembly, null); case "rsvg-2.40": - return NativeLibrary.Load("rsvg-2", assembly, null); + return NativeLibrary.Load("rsvg-2", assembly, null); } - Console.WriteLine ($"[UNRESOLVE] {assembly} {libraryName}"); + Console.WriteLine($"[UNRESOLVE] {assembly} {libraryName}"); return IntPtr.Zero; } - static SampleBase () { - System.Runtime.Loader.AssemblyLoadContext.GetLoadContext(Assembly.GetExecutingAssembly()).ResolvingUnmanagedDll+=resolveUnmanaged; + static SampleBase() + { + System.Runtime.Loader.AssemblyLoadContext.GetLoadContext(Assembly.GetExecutingAssembly()).ResolvingUnmanagedDll += resolveUnmanaged; } #endif - public SampleBase (IntPtr hWin) : base (800,600,hWin){} - public SampleBase () : base (800,600,true,true){} - public SampleBase (int width, int height, bool startUIThread, bool createSurface) : - base (width, height, startUIThread, createSurface){ - + public SampleBase(IntPtr hWin) : base(800, 600, hWin) { } + public SampleBase() : base(800, 600, true, true) { } + public SampleBase(int width, int height, bool startUIThread, bool createSurface) : + base(width, height, startUIThread, createSurface) + { + + } + + public Version CrowVersion => Assembly.GetAssembly(typeof(Widget)).GetName().Version; + + #region Test values for Binding + public CommandGroup Commands, AllCommands; + public CommandGroup EditCommands = new CommandGroup("Edit Commands", + new Command("Edit command 1", () => Console.WriteLine("edit command1 pressed")), + new Command("Edit command 2", () => Console.WriteLine("edit command2 pressed")), + new Command("Edit command 3", () => Console.WriteLine("edit command3 pressed")) + ); + public CommandGroup FileCommands = new CommandGroup("File Commands", + new Command("File command 1", () => Console.WriteLine("File command1 pressed")), + new Command("File command 2", () => Console.WriteLine("File command2 pressed")), + new Command("File command 3", () => Console.WriteLine("File command3 pressed")) + ); + + void initCommands() + { + Commands = new CommandGroup("commands msg boxes", + new Command("Action 1", () => MessageBox.ShowModal(this, MessageBox.Type.Information, "context menu 1 clicked")), + new Command("Action 2", () => MessageBox.ShowModal(this, MessageBox.Type.Information, "context menu 2 clicked")), + new Command("Action 3", () => MessageBox.ShowModal(this, MessageBox.Type.Information, "context menu 3 clicked")) + ); + AllCommands = new CommandGroup ("All Commands", + EditCommands, + FileCommands, + new Command("Action A", () => MessageBox.ShowModal(this, MessageBox.Type.Information, "context menu A clicked")) + ); + } + public int intValue = 500; + VerticalAlignment currentVAlign; + + DirectoryInfo curDir = new DirectoryInfo(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location)); + public FileSystemInfo[] CurDirectory => curDir.GetFileSystemInfos(); + public string MultilineText = + $"Lorem ipsum dolor sit amet,\nconsectetur adipiscing elit. Sed non risus.\n\nSuspendisse lectus tortor,\nLorem ipsum dolor sit amet,\nconsectetur adipiscing elit. Sed non risus.\n\nSuspendisse lectus tortor,"; + //public string MultilineText = $"a\n"; + TextAlignment textAlignment = TextAlignment.Left; + public TextAlignment TextAlignment + { + get => textAlignment; + set + { + if (textAlignment == value) + return; + textAlignment = value; + NotifyValueChanged(textAlignment); + } + } + + public int IntValue + { + get => intValue; + set + { + if (IntValue == value) + return; + intValue = value; + NotifyValueChanged("IntValue", intValue); + } + } + public VerticalAlignment CurrentVAlign + { + get => currentVAlign; + set + { + if (currentVAlign == value) + return; + currentVAlign = value; + NotifyValueChanged("CurrentVAlign", currentVAlign); + } + } + void onSpinnerValueChange(object sender, ValueChangeEventArgs e) + { + if (e.MemberName != "Value") + return; + intValue = Convert.ToInt32(e.NewValue); + } + void change_alignment(object sender, EventArgs e) + { + RadioButton rb = sender as RadioButton; + if (rb == null) + return; + NotifyValueChanged("alignment", Enum.Parse(typeof(Alignment), rb.Caption)); + } + public IEnumerable List2 = new List(new string[] + { + "string1", + "string2", + "string3", + "string4", + "string5", + "string6", + "string7", + "string8", + "string8", + "string8", + "string8", + "string8", + "string8", + "string9" + } + ); + public IEnumerable TestList2 + { + set + { + List2 = value; + NotifyValueChanged("TestList2", testList); + } + get { return List2; } + } + public class TestClass + { + public string Prop1 { get; set; } + public string Prop2 { get; set; } + + public override string ToString() + => $"{Prop1}, {Prop2}"; + + public void OnValidateCommand(Object sender, ValidateEventArgs e) + { + Console.WriteLine($"Validation: {e.ValidatedText}"); + } + } + public class TestClassVC : IValueChange + { + public event EventHandler ValueChanged; + public void NotifyValueChanged(object _value, [CallerMemberName] string caller = null) + => ValueChanged.Raise(this, new ValueChangeEventArgs(caller, _value)); + string prop1, prop2; + public string Prop1 + { + get => prop1; + set + { + if (prop1 == value) + return; + prop1 = value; + NotifyValueChanged(prop1); + } + } + public string Prop2 + { + get => prop2; + set + { + if (prop2 == value) + return; + prop2 = value; + NotifyValueChanged(prop2); + } + + + + } + + public override string ToString() + => $"{Prop1}, {Prop2}"; + + } + TestClass tcInstance = new TestClass() { Prop1 = "instance 0 prop1 value", Prop2 = "instance 0 prop2 value" }; + TestClassVC tcVCInstance;// = new TestClassVC () { Prop1 = "instance 0 prop1 value", Prop2 = "instance 0 prop2 value" }; + TestClass tcInstance1 = new TestClass() { Prop1 = "instance 1 prop1 value", Prop2 = "instance 1 prop2 value" }; + TestClassVC tcVCInstance1 = new TestClassVC() { Prop1 = "instance 1 prop1 value", Prop2 = "instance 1 prop2 value" }; + TestClass tcInstance2 = new TestClass() { Prop1 = "instance 2 prop1 value", Prop2 = "instance 2 prop2 value" }; + TestClassVC tcVCInstance2 = new TestClassVC() { Prop1 = "instance 2 prop1 value", Prop2 = "instance 2 prop2 value" }; + + public TestClass TcInstance + { + get => tcInstance; + set + { + if (tcInstance == value) + return; + tcInstance = value; + NotifyValueChanged(tcInstance); + } + } + public TestClassVC TcVCInstance + { + get => tcVCInstance; + set + { + if (tcVCInstance == value) + return; + tcVCInstance = value; + NotifyValueChanged(tcVCInstance); + } + } + + void tcInstance_ChangeProperties_MouseClick(object sender, MouseButtonEventArgs e) + { + } + public void tcInstance_ChangeInstance_MouseClick(object sender, MouseButtonEventArgs e) + { + if (TcInstance == tcInstance1) + TcInstance = tcInstance2; + else + TcInstance = tcInstance1; + } + void tcVCInstance_ChangeInstance_MouseClick(object sender, MouseButtonEventArgs e) + { + TcVCInstance = new TestClassVC() { Prop1 = "prop1 value changed", Prop2 = "prop2 value changed" }; + } + + public IEnumerable List3 = new List(new TestClass[] + { + new TestClass { Prop1 = "string1", Prop2="prop2-1" }, + new TestClass { Prop1 = "string2", Prop2="prop2-2" }, + new TestClass { Prop1 = "string3", Prop2="prop2-3" }, + } + ); + public IEnumerable TestList3Props1 => List3.Select(sc => sc.Prop1).ToList(); + public IEnumerable TestList3 + { + set + { + List3 = value; + NotifyValueChanged("TestList3", testList); + } + get { return List3; } + } + string testString; + public string TestString + { + get => testString; + set + { + if (testString == value) + return; + testString = value; + + NotifyValueChanged(testString); + } + } + string prop1; + public string TestList3SelProp1 + { + get => prop1; + set + { + if (prop1 == value) + return; + prop1 = value; + + NotifyValueChanged(prop1); + } + } + + string selString; + public string TestList2SelectedString + { + get => selString; + set + { + if (selString == value) + return; + selString = value; + NotifyValueChanged(selString); } + } + + + IList testList = (IList)FastEnumUtility.FastEnum.GetValues().ToList();//.ColorDic.Values//.OrderBy(c=>c.Hue) + //.ThenBy(c=>c.Value).ThenBy(c=>c.Saturation) + //.ToList (); + public IList TestList + { + set + { + testList = value; + NotifyValueChanged("TestList", testList); + } + get { return testList; } + } + void OnClear(object sender, MouseButtonEventArgs e) => TestList = null; + void OnLoadList(object sender, MouseButtonEventArgs e) => TestList = (IList)FastEnumUtility.FastEnum.GetValues().ToList(); + + + string curSources = ""; + public string CurSources + { + get { return curSources; } + set + { + if (value == curSources) + return; + curSources = value; + NotifyValueChanged(curSources); + } + } + bool boolVal = true; + public bool BoolVal + { + get { return boolVal; } + set + { + if (boolVal == value) + return; + boolVal = value; + NotifyValueChanged(boolVal); + } + } + + + + #endregion - public Version CrowVersion => Assembly.GetAssembly (typeof (Widget)).GetName ().Version; - - #region Test values for Binding - public CommandGroup Commands; - public CommandGroup EditCommands = new CommandGroup( - new Command("command 1", () => Console.WriteLine("command1 pressed"))); - - public int intValue = 500; - VerticalAlignment currentVAlign; - - DirectoryInfo curDir = new DirectoryInfo (Path.GetDirectoryName (Assembly.GetEntryAssembly ().Location)); - public FileSystemInfo[] CurDirectory => curDir.GetFileSystemInfos (); - public string MultilineText = - $"Lorem ipsum dolor sit amet,\nconsectetur adipiscing elit. Sed non risus.\n\nSuspendisse lectus tortor,\nLorem ipsum dolor sit amet,\nconsectetur adipiscing elit. Sed non risus.\n\nSuspendisse lectus tortor,"; - //public string MultilineText = $"a\n"; - TextAlignment textAlignment = TextAlignment.Left; - public TextAlignment TextAlignment { - get => textAlignment; - set { - if (textAlignment == value) - return; - textAlignment = value; - NotifyValueChanged (textAlignment); - } - } - - public int IntValue { - get => intValue; - set { - if (IntValue == value) - return; - intValue = value; - NotifyValueChanged ("IntValue", intValue); - } - } - public VerticalAlignment CurrentVAlign { - get => currentVAlign; - set { - if (currentVAlign == value) - return; - currentVAlign = value; - NotifyValueChanged ("CurrentVAlign", currentVAlign); - } - } - void onSpinnerValueChange (object sender, ValueChangeEventArgs e) { - if (e.MemberName != "Value") - return; - intValue = Convert.ToInt32 (e.NewValue); - } - void change_alignment (object sender, EventArgs e) { - RadioButton rb = sender as RadioButton; - if (rb == null) - return; - NotifyValueChanged ("alignment", Enum.Parse (typeof (Alignment), rb.Caption)); - } - public IEnumerable List2 = new List (new string[] - { - "string1", - "string2", - "string3", - "string4", - "string5", - "string6", - "string7", - "string8", - "string8", - "string8", - "string8", - "string8", - "string8", - "string9" - } - ); - public IEnumerable TestList2 { - set { - List2 = value; - NotifyValueChanged ("TestList2", testList); - } - get { return List2; } - } - public class TestClass - { - public string Prop1 { get; set; } - public string Prop2 { get; set; } - - public override string ToString () - => $"{Prop1}, {Prop2}"; - - public void OnValidateCommand (Object sender, ValidateEventArgs e) { - Console.WriteLine ($"Validation: {e.ValidatedText}"); + protected override void OnInitialized() + { + initCommands(); + base.OnInitialized(); + } + + public override bool OnKeyDown(Key key) + { + + switch (key) + { + case Key.F5: + Load("Interfaces/Divers/testFileDialog.crow").DataSource = this; + return true; + case Key.F6: + Load("Interfaces/Divers/0.crow").DataSource = this; + return true; + case Key.F7: + Load("Interfaces/Divers/perfMeasures.crow").DataSource = this; + return true; + case Key.F2: + if (IsKeyDown(Key.LeftShift)) + DbgLogger.Reset(); + DbgLogger.Save(this); + return true; } - } - public class TestClassVC : IValueChange - { - public event EventHandler ValueChanged; - public void NotifyValueChanged (object _value, [CallerMemberName] string caller = null) - => ValueChanged.Raise (this, new ValueChangeEventArgs (caller, _value)); - string prop1, prop2; - public string Prop1 { - get => prop1; - set { - if (prop1 == value) - return; - prop1 = value; - NotifyValueChanged (prop1); - } - } - public string Prop2 { - get => prop2; - set { - if (prop2 == value) - return; - prop2 = value; - NotifyValueChanged (prop2); - } - - - - } - - public override string ToString () - => $"{Prop1}, {Prop2}"; - - } - TestClass tcInstance = new TestClass () { Prop1 = "instance 0 prop1 value", Prop2 = "instance 0 prop2 value" }; - TestClassVC tcVCInstance;// = new TestClassVC () { Prop1 = "instance 0 prop1 value", Prop2 = "instance 0 prop2 value" }; - TestClass tcInstance1 = new TestClass () { Prop1 = "instance 1 prop1 value", Prop2 = "instance 1 prop2 value" }; - TestClassVC tcVCInstance1 = new TestClassVC () { Prop1 = "instance 1 prop1 value", Prop2 = "instance 1 prop2 value" }; - TestClass tcInstance2 = new TestClass () { Prop1 = "instance 2 prop1 value", Prop2 = "instance 2 prop2 value" }; - TestClassVC tcVCInstance2 = new TestClassVC () { Prop1 = "instance 2 prop1 value", Prop2 = "instance 2 prop2 value" }; - - public TestClass TcInstance { - get => tcInstance; - set { - if (tcInstance == value) - return; - tcInstance = value; - NotifyValueChanged (tcInstance); - } - } - public TestClassVC TcVCInstance { - get => tcVCInstance; - set { - if (tcVCInstance == value) - return; - tcVCInstance = value; - NotifyValueChanged (tcVCInstance); - } - } - - void tcInstance_ChangeProperties_MouseClick (object sender, MouseButtonEventArgs e) { - } - public void tcInstance_ChangeInstance_MouseClick (object sender, MouseButtonEventArgs e) { - if (TcInstance == tcInstance1) - TcInstance = tcInstance2; - else - TcInstance = tcInstance1; - } - void tcVCInstance_ChangeInstance_MouseClick (object sender, MouseButtonEventArgs e) { - TcVCInstance = new TestClassVC () { Prop1 = "prop1 value changed", Prop2 = "prop2 value changed" }; - } - - public IEnumerable List3 = new List (new TestClass[] - { - new TestClass { Prop1 = "string1", Prop2="prop2-1" }, - new TestClass { Prop1 = "string2", Prop2="prop2-2" }, - new TestClass { Prop1 = "string3", Prop2="prop2-3" }, - } - ); - public IEnumerable TestList3Props1 => List3.Select (sc => sc.Prop1).ToList (); - public IEnumerable TestList3 { - set { - List3 = value; - NotifyValueChanged ("TestList3", testList); - } - get { return List3; } - } - string prop1; - public string TestList3SelProp1 { - get => prop1; - set { - if (prop1 == value) - return; - prop1 = value; - - NotifyValueChanged (prop1); - } - } - - string selString; - public string TestList2SelectedString { - get => selString; - set { - if (selString == value) - return; - selString = value; - NotifyValueChanged (selString); - } - } - - - IList testList = (IList)FastEnumUtility.FastEnum.GetValues ().ToList ();//.ColorDic.Values//.OrderBy(c=>c.Hue) - //.ThenBy(c=>c.Value).ThenBy(c=>c.Saturation) - //.ToList (); - public IList TestList { - set { - testList = value; - NotifyValueChanged ("TestList", testList); - } - get { return testList; } - } - void OnClear (object sender, MouseButtonEventArgs e) => TestList = null; - void OnLoadList (object sender, MouseButtonEventArgs e) => TestList = (IList)FastEnumUtility.FastEnum.GetValues ().ToList (); - - - string curSources = ""; - public string CurSources { - get { return curSources; } - set { - if (value == curSources) - return; - curSources = value; - NotifyValueChanged (curSources); - } - } - bool boolVal = true; - public bool BoolVal { - get { return boolVal; } - set { - if (boolVal == value) - return; - boolVal = value; - NotifyValueChanged (boolVal); - } - } - - - - #endregion - - protected override void OnInitialized () { - Commands = new CommandGroup ( - new Command("Action 1", () => MessageBox.ShowModal(this, MessageBox.Type.Information, "context menu 1 clicked")), - new Command("Action 2", () => MessageBox.ShowModal(this, MessageBox.Type.Information, "context menu 2 clicked")), - new Command("Action 3", () => MessageBox.ShowModal(this, MessageBox.Type.Information, "context menu 3 clicked")) - ); - base.OnInitialized (); - } - - public override bool OnKeyDown (Key key) { - - switch (key) { - case Key.F5: - Load ("Interfaces/Divers/testFileDialog.crow").DataSource = this; - return true; - case Key.F6: - Load ("Interfaces/Divers/0.crow").DataSource = this; - return true; - case Key.F7: - Load ("Interfaces/Divers/perfMeasures.crow").DataSource = this; - return true; - case Key.F2: - if (IsKeyDown (Key.LeftShift)) - DbgLogger.Reset (); - DbgLogger.Save (this); - return true; - } - return base.OnKeyDown (key); - } - } + return base.OnKeyDown(key); + } + } } \ No newline at end of file diff --git a/Samples/common/samples.style b/Samples/common/samples.style index 50f91f4a..7c33bd9d 100644 --- a/Samples/common/samples.style +++ b/Samples/common/samples.style @@ -52,6 +52,16 @@ DbgLogViewer{ DockWindow{ Background = "0.1,0.1,0.1,0.5"; } +DockStack { + Margin="0"; + Spacing="0"; + AllowDrop = "true"; + AllowedDropTypes = "Crow.DockWindow"; + Focusable="true"; + //DragEnter="{Background=Blue}"; + //DragLeave="{Background=Transparent}"; + //EndDrag="{Background=Jet}"; +} valignStyle { Template="#ui.enumSingleSVG.itmp"; @@ -69,4 +79,4 @@ valignStyle2 { } smallLabel { Font="consolas, 8"; -} \ No newline at end of file +} diff --git a/Samples/common/ui/icons/Crow.Docker.svg b/Samples/common/ui/icons/Crow.DockStack.svg similarity index 100% rename from Samples/common/ui/icons/Crow.Docker.svg rename to Samples/common/ui/icons/Crow.DockStack.svg diff --git a/Samples/common/ui/icons/Crow.DockWindow.svg b/Samples/common/ui/icons/Crow.DockWindow.svg new file mode 100644 index 00000000..74b0a24b --- /dev/null +++ b/Samples/common/ui/icons/Crow.DockWindow.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/Samples/dockableWindows/dockableWindows.cs b/Samples/dockableWindows/dockableWindows.cs index 27a9612a..8bf42a0b 100644 --- a/Samples/dockableWindows/dockableWindows.cs +++ b/Samples/dockableWindows/dockableWindows.cs @@ -17,31 +17,40 @@ namespace tests Colors.Blue, Colors.Red, Colors.Green, - Colors.Yellow, - Colors.Grey, - Colors.Onyx, + Colors.DarkOrchid, + Colors.DarkOrange, + Colors.DarkOliveGreen, Colors.Cyan, Colors.Chartreuse, }; + DockStack mainStack; 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 }); + mainStack = FindByName ("mainDock") as DockStack; + AddWidget (new DockWindow (this) { Background = Colors.Blue, Left = 10, Top = 110, Resizable = true, Caption = "win1" }); + AddWidget (new DockWindow (this) { Background = Colors.Red, Left = 30, Top = 130, Resizable = true, Caption = "win2" }); + AddWidget (new DockWindow (this) { Background = Colors.Green, Left = 50, Top = 150, Resizable = true, Caption = "win3" }); + AddWidget (new DockWindow (this) { Background = Colors.BurlyWood, Left = 70, Top = 170, Resizable = true, Caption = "win4" }); + AddWidget (new DockWindow (this) { Background = Colors.DarkOrchid, Left = 90, Top = 190, Resizable = true, Caption = "win5" }); } private void refreshGraphicTree (object sender, MouseButtonEventArgs e) { NotifyValueChanged ("GraphicTree", (object)null); NotifyValueChanged ("GraphicTree", GraphicTree); } int colorIdx = 0; + int nameIdx = 6; public override bool OnKeyDown (Key key) { if (colorIdx >= colors.Length) colorIdx = 0; switch (key) { case Key.F6: - AddWidget (new DockWindow (this) { Background = colors[colorIdx++], Left = 90, Top = 190, Resizable = true }); + AddWidget (new DockWindow (this) { Background = colors[colorIdx++], Left = 90, Top = 190, Resizable = true, Caption = $"win{nameIdx++}" }); + return true; + case Key.F2: + Configuration.Global.Set ("WindowConfigTest", mainStack.ExportConfig()); + return true; + case Key.F3: + mainStack.ImportConfig (Configuration.Global.Get ("WindowConfigTest")); return true; default: return base.OnKeyDown (key); diff --git a/Samples/dockableWindows/ui/TabView.template b/Samples/dockableWindows/ui/TabView.template new file mode 100644 index 00000000..9490aa7f --- /dev/null +++ b/Samples/dockableWindows/ui/TabView.template @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + diff --git a/Samples/dockableWindows/ui/dock.style b/Samples/dockableWindows/ui/dock.style new file mode 100644 index 00000000..ef3f43e1 --- /dev/null +++ b/Samples/dockableWindows/ui/dock.style @@ -0,0 +1,12 @@ +DockStack { + Margin="0"; + Spacing="0"; + //Background="DimGrey"; +} +DockWindow { + Template="#ui.dockWin.template"; +} +TabView { + Template="#ui.TabView.template"; + //Background="Onyx"; +} \ No newline at end of file diff --git a/Samples/dockableWindows/ui/dockWin.template b/Samples/dockableWindows/ui/dockWin.template new file mode 100644 index 00000000..c53b260c --- /dev/null +++ b/Samples/dockableWindows/ui/dockWin.template @@ -0,0 +1,24 @@ + + + + + + + + + + + + diff --git a/Samples/dockableWindows/ui/test.crow b/Samples/dockableWindows/ui/test.crow index f576fbbd..1e4e81e4 100644 --- a/Samples/dockableWindows/ui/test.crow +++ b/Samples/dockableWindows/ui/test.crow @@ -1,5 +1,5 @@  - + - diff --git a/Samples/dragNdrop/dragNdrop.cs b/Samples/dragNdrop/dragNdrop.cs index 281cfe19..89785c82 100644 --- a/Samples/dragNdrop/dragNdrop.cs +++ b/Samples/dragNdrop/dragNdrop.cs @@ -25,16 +25,16 @@ namespace tests private void W_StartDrag (object sender, DragDropEventArgs e) { + Rectangle r = e.DragSource.LastPaintedSlot; 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); + Crow.Cairo.Surface dragImg = surf.CreateSimilar (Crow.Cairo.Content.ColorAlpha, + r.Width, r.Height); using (Crow.Cairo.Context gr = new Crow.Cairo.Context(dragImg)) { gr.SetSource (e.DragSource.bmp, 0, 0); gr.Paint (); } - DragImage = dragImg; + CreateDragImage (dragImg) /*lock (UpdateMutex) startGroup.RemoveChild (e.DragSource);*/ } -- 2.47.3