From: Jean-Philippe Bruyère Date: Wed, 17 Mar 2021 01:20:56 +0000 (+0100) Subject: improve dragNdrop, debug docking X-Git-Tag: v0.9.5-beta~61 X-Git-Url: https://git.osiis.dedyn.io/?a=commitdiff_plain;h=cc19139a50fcea74c6a9e0f330e84039b335ab73;p=jp%2Fcrow.git improve dragNdrop, debug docking --- diff --git a/Crow/src/EventArgs/DragDropEventArgs.cs b/Crow/src/EventArgs/DragDropEventArgs.cs index 3a505527..3bca5c23 100644 --- a/Crow/src/EventArgs/DragDropEventArgs.cs +++ b/Crow/src/EventArgs/DragDropEventArgs.cs @@ -29,7 +29,7 @@ namespace Crow public override string ToString () { - return string.Format ("{0} => {1}", DragSource,DropTarget); + return string.Format ("{0} => {1}", DragSource, DropTarget); } } } diff --git a/Crow/src/Interface.cs b/Crow/src/Interface.cs index 66b9b594..63a86a14 100644 --- a/Crow/src/Interface.cs +++ b/Crow/src/Interface.cs @@ -460,7 +460,10 @@ namespace Crow public List CrowThreads = new List();//used to monitor thread finished + public bool DragAndDropInProgress => DragAndDropOperation != null; public DragDropEventArgs DragAndDropOperation = null; + internal Widget dragndropHover; + public Surface DragImage = null; public int DragImageWidth, DragImageHeight, DragImageX, DragImageY; public void ClearDragImage () { @@ -763,14 +766,16 @@ namespace Crow /// , it can not lose focus while Active public Widget ActiveWidget { - get { return _activeWidget; } + get => _activeWidget; internal set { if (_activeWidget == value) return; - if (_activeWidget != null) + if (_activeWidget != null) { + debugRegisterClip (_activeWidget); _activeWidget.IsActive = false; + } _activeWidget = value; @@ -784,20 +789,22 @@ namespace Crow /// Pointer is over the widget public virtual Widget HoverWidget { - get { return _hoverWidget; } + get => _hoverWidget; set { if (_hoverWidget == value) return; - if (_hoverWidget != null) + if (_hoverWidget != null) { + debugRegisterClip (_hoverWidget); _hoverWidget.IsHover = false; + } _hoverWidget = value; NotifyValueChanged ("HoverWidget", _hoverWidget); DbgLogger.AddEvent (DbgEvtType.HoverWidget, _hoverWidget); - if (DragAndDropOperation == null && FOCUS_ON_HOVER) { + if (FOCUS_ON_HOVER) { Widget w = _hoverWidget; while (w != null) { if (w.Focusable) { @@ -818,8 +825,10 @@ namespace Crow set { if (_focusedWidget == value) return; - if (_focusedWidget != null) + if (_focusedWidget != null) { + debugRegisterClip (_focusedWidget); _focusedWidget.HasFocus = false; + } _focusedWidget = value; NotifyValueChanged ("FocusedWidget", _focusedWidget); @@ -1017,11 +1026,37 @@ namespace Crow } drawTextCursor (ctx); + + debugHighlightFocus (ctx); DbgLogger.EndEvent (DbgEvtType.Drawing, true); } #endregion + [Conditional ("DEBUG_HIGHLIGHT_FOCUS")] + internal void debugRegisterClip (Widget w) { + RegisterClip (w.ScreenCoordinates (w.Slot)); + } + [Conditional ("DEBUG_HIGHLIGHT_FOCUS")] + void debugHighlightFocus (Context ctx) { + if (HoverWidget!= null) { + ctx.SetSource (Colors.Purple); + ctx.Rectangle (HoverWidget.ScreenCoordinates (HoverWidget.Slot), 1); + } + if (FocusedWidget != null) { + ctx.SetSource (Colors.Blue); + ctx.Rectangle (FocusedWidget.ScreenCoordinates (FocusedWidget.Slot), 1); + } + if (ActiveWidget != null) { + ctx.SetSource (Colors.Yellow); + ctx.Rectangle (ActiveWidget.ScreenCoordinates (ActiveWidget.Slot), 1); + } + /*if (DragAndDropInProgress) { + + }*/ + surf.Flush (); + } + #region Blinking text cursor /// /// Text cursor blinking frequency. @@ -1317,6 +1352,17 @@ namespace Crow Point stickyMouseDelta = default; internal Widget stickedWidget = null; + Widget HoverOrDropTarget { + get => DragAndDropInProgress ? dragndropHover : HoverWidget; + set { + if (DragAndDropInProgress) { + dragndropHover = value; + } else + HoverWidget = value; + } + } + + /// 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 /// true if mouse is in the interface @@ -1325,78 +1371,89 @@ namespace Crow int deltaX = x - MousePosition.X; int deltaY = y - MousePosition.Y; - if (stickedWidget != null && _activeWidget == null) { - stickyMouseDelta.X += deltaX; - stickyMouseDelta.Y += deltaY; + if (!DragAndDropInProgress) { + if (stickedWidget != null && ActiveWidget == null) { + stickyMouseDelta.X += deltaX; + stickyMouseDelta.Y += deltaY; - 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; + 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; + } } } MousePosition = new Point (x, y); MouseMoveEventArgs e = new MouseMoveEventArgs (x, y, deltaX, deltaY); - 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) { + if (!(DragAndDropInProgress || ActiveWidget == null)) { //TODO, ensure object is still in the graphic tree //send move evt even if mouse move outside bounds - _activeWidget.onMouseMove (this, e); + ActiveWidget.onMouseMove (this, e); return true; } - if (_hoverWidget != null) { + if (HoverOrDropTarget != null) { resetTooltip (); - //check topmost graphicobject first - Widget tmp = _hoverWidget; - Widget topc = null; - while (tmp is Widget) { - topc = tmp; - tmp = tmp.LogicalParent as Widget; - } - int idxhw = GraphicTree.IndexOf (topc); - if (idxhw != 0) { - int i = 0; - while (i < idxhw) { - //if logical parent of top container is a widget, that's a popup + + //check topmost graphicobject first + Widget topContainer = HoverOrDropTarget; + while (topContainer.LogicalParent is Widget w) + topContainer = w; + + int indexOfTopContainer = GraphicTree.IndexOf (topContainer); + if (indexOfTopContainer != 0) { + for (int i = 0; i < indexOfTopContainer; i++) { + //if logical parent of top container is a Interface, that's not a popup. if (GraphicTree [i].LogicalParent is Interface) { if (GraphicTree [i].MouseIsIn (e.Position)) { - while (_hoverWidget != null) { - _hoverWidget.onMouseLeave (_hoverWidget, e); - HoverWidget = _hoverWidget.FocusParent; - } - - GraphicTree [i].checkHoverWidget (e); - _hoverWidget.onMouseMove (this, e); + //mouse is in another top container than the actual one, + //so we must leave first the current top container starting from HoverWidget + if (DragAndDropInProgress) { + DragAndDropOperation.DropTarget?.onDragLeave (this, DragAndDropOperation); + GraphicTree[i].checkHoverWidget (e); + DragAndDropOperation.DragSource.onDrag (this, e); + } else { + while (HoverWidget != null) { + HoverWidget.onMouseLeave (this, e); + HoverWidget = HoverWidget.FocusParent; + } + GraphicTree[i].checkHoverWidget (e); + HoverWidget.onMouseMove (this, e); + } return true; } } - i++; } } - if (_hoverWidget.MouseIsIn (e.Position)) { - _hoverWidget.checkHoverWidget (e); - _hoverWidget.onMouseMove (this, e); + if (HoverOrDropTarget.MouseIsIn (e.Position)) { + HoverOrDropTarget.checkHoverWidget (e); + if (DragAndDropInProgress) + DragAndDropOperation.DragSource.onDrag (this, e); + else + HoverWidget.onMouseMove (this, e); return true; - } - _hoverWidget.onMouseLeave (_hoverWidget, e); - //seek upward from last focused graph obj's - tmp = _hoverWidget.FocusParent; - while (tmp != null) { - HoverWidget = tmp; - if (_hoverWidget.MouseIsIn (e.Position)) { - _hoverWidget.checkHoverWidget (e); - _hoverWidget.onMouseMove (_hoverWidget, e); - return true; + } else { + if (DragAndDropInProgress && dragndropHover == DragAndDropOperation.DropTarget) + DragAndDropOperation.DropTarget.onDragLeave (this, DragAndDropOperation); + //seek upward from last focused graph obj's + while (HoverOrDropTarget.FocusParent != null) { + if (!DragAndDropInProgress) + HoverWidget.onMouseLeave (this, e); + HoverOrDropTarget = HoverOrDropTarget.FocusParent; + if (HoverOrDropTarget.MouseIsIn (e.Position)) { + HoverOrDropTarget.checkHoverWidget (e); + if (DragAndDropInProgress) + DragAndDropOperation.DragSource?.onDrag (this, e); + else + HoverWidget.onMouseMove (this, e); + return true; + } } - _hoverWidget.onMouseLeave (_hoverWidget, e); - tmp = _hoverWidget.FocusParent; } } @@ -1404,19 +1461,23 @@ namespace Crow lock (GraphicTree) { for (int i = 0; i < GraphicTree.Count; i++) { Widget g = GraphicTree [i]; + if (DragAndDropInProgress && DragAndDropOperation.DragSource == g) + continue; if (g.MouseIsIn (e.Position)) { g.checkHoverWidget (e); - if (g is Window && FOCUS_ON_HOVER && g.Focusable) { - FocusedWidget = g; - if (RAISE_WIN_ON_FOCUS) - PutOnTop (g); + if (!DragAndDropInProgress) { + if (g is Window && FOCUS_ON_HOVER && g.Focusable) { + FocusedWidget = g; + if (RAISE_WIN_ON_FOCUS) + PutOnTop (g); + } + HoverWidget.onMouseMove (this, e); } - _hoverWidget.onMouseMove (_hoverWidget, e); return true; } } } - HoverWidget = null; + HoverOrDropTarget = null; return false; } /// @@ -1431,12 +1492,12 @@ namespace Crow lastMouseDownEvent = new MouseButtonEventArgs (MousePosition.X, MousePosition.Y, button, InputAction.Press); - if (_hoverWidget == null) + if (HoverWidget == null) return false; - _hoverWidget.onMouseDown (_hoverWidget, lastMouseDownEvent); + HoverWidget.onMouseDown (this, lastMouseDownEvent); - ActiveWidget = _hoverWidget; + ActiveWidget = HoverWidget; return true; } /// @@ -1449,6 +1510,19 @@ namespace Crow mouseRepeatTimer.Reset (); lastMouseDownEvent = null; + if (DragAndDropInProgress) { + if (DragAndDropOperation.DropTarget != null) + DragAndDropOperation.DragSource.onDrop (this, DragAndDropOperation); + else + DragAndDropOperation.DragSource.onEndDrag (this, DragAndDropOperation); + DragAndDropOperation = null; + if (ActiveWidget != null) { + ActiveWidget.onMouseUp (_activeWidget, new MouseButtonEventArgs (MousePosition.X, MousePosition.Y, button, InputAction.Release)); + ActiveWidget = null; + } + return true; + } + if (_activeWidget == null) return false; @@ -1611,6 +1685,7 @@ namespace Crow { ctxMenuContainer = CreateInstance ("#Crow.ContextMenu.template") as MenuItem; ctxMenuContainer.LayoutChanged += CtxMenuContainer_LayoutChanged; + ctxMenuContainer.Focusable = true; } protected void disposeContextMenus () { if (ctxMenuContainer == null) @@ -1641,17 +1716,19 @@ namespace Crow else ctxMenuContainer.IsOpened = true; - //ctxMenuContainer.isPopup = true; + ctxMenuContainer.BubbleMouseEvent = false; ctxMenuContainer.LogicalParent = go; ctxMenuContainer.DataSource = go; + PutOnTop (ctxMenuContainer, true); } ctxMenuContainer.Left = MousePosition.X - 5; ctxMenuContainer.Top = MousePosition.Y - 5; - _hoverWidget = ctxMenuContainer; - ctxMenuContainer.onMouseEnter (ctxMenuContainer, new MouseMoveEventArgs (MousePosition.X, MousePosition.Y, 0, 0)); + //OnMouseMove (MousePosition.X, MousePosition.Y); + HoverWidget = ctxMenuContainer; + ctxMenuContainer.onMouseEnter (ctxMenuContainer, new MouseMoveEventArgs (MousePosition.X, MousePosition.Y, 0, 0)); } #endregion diff --git a/Crow/src/Widgets/DockStack.cs b/Crow/src/Widgets/DockStack.cs index 3b8594ea..50f241b5 100644 --- a/Crow/src/Widgets/DockStack.cs +++ b/Crow/src/Widgets/DockStack.cs @@ -90,7 +90,7 @@ namespace Crow childrenRWLock.ExitReadLock (); } - public override void onMouseMove (object sender, MouseMoveEventArgs e) + public void onDragMouseMove (object sender, MouseMoveEventArgs e) { if (IsDropTarget) { DockWindow dw = IFace.DragAndDropOperation.DragSource as DockWindow; @@ -150,7 +150,7 @@ namespace Crow if (curDockPos != dw.DockingPosition) RegisterForGraphicUpdate (); } - base.onMouseMove (sender, e); + //base.onMouseMove (sender, e); } protected override void onDragEnter (object sender, DragDropEventArgs e) @@ -158,7 +158,7 @@ namespace Crow base.onDragEnter (sender, e); RegisterForGraphicUpdate (); } - protected override void onDragLeave (object sender, DragDropEventArgs e) + public override void onDragLeave (object sender, DragDropEventArgs e) { DockWindow dw = e.DragSource as DockWindow; //if (dw != null) @@ -295,6 +295,7 @@ namespace Crow stretchedChild = dw; break; } + dw.IsDocked = true; } public void Undock (DockWindow dw){ int idx = Children.IndexOf(dw); diff --git a/Crow/src/Widgets/DockWindow.cs b/Crow/src/Widgets/DockWindow.cs index bf59b155..a020397e 100644 --- a/Crow/src/Widgets/DockWindow.cs +++ b/Crow/src/Widgets/DockWindow.cs @@ -66,21 +66,15 @@ namespace Crow return Slot.ContainsOrIsEqual(m); } - 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 (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 onDrag (object sender, MouseMoveEventArgs e) + { + if (isDocked) + CheckUndock (e.Position); + else + moveAndResize (e.XDelta, e.YDelta, currentDirection); + + base.onDrag (sender, e); + (IFace.DragAndDropOperation.DropTarget as DockStack)?.onDragMouseMove (this, e); } public override void onMouseDown (object sender, MouseButtonEventArgs e) { @@ -108,7 +102,7 @@ namespace Crow undockingMousePosOrig = IFace.MousePosition; } - protected override void onDrop (object sender, DragDropEventArgs e) + public override void onDrop (object sender, DragDropEventArgs e) { if (!isDocked && DockingPosition != Alignment.Undefined && e.DropTarget is DockStack) Dock (e.DropTarget as DockStack); @@ -134,7 +128,8 @@ namespace Crow public void Dock (DockStack target){ lock (IFace.UpdateMutex) { - IsDocked = true; + //IsDocked = true; + undockingMousePosOrig = IFace.MousePosition; //undockingMousePosOrig = lastMousePos; savedSlot = this.LastPaintedSlot; wasResizable = Resizable; diff --git a/Crow/src/Widgets/Group.cs b/Crow/src/Widgets/Group.cs index 57e45203..69fc614e 100644 --- a/Crow/src/Widgets/Group.cs +++ b/Crow/src/Widgets/Group.cs @@ -444,20 +444,17 @@ namespace Crow #region Mouse handling - public override void checkHoverWidget (MouseMoveEventArgs e) - { - if (IFace.HoverWidget != this) { - IFace.HoverWidget = this; - onMouseEnter (this, e); - } + public override void checkHoverWidget (MouseMoveEventArgs e) { + base.checkHoverWidget (e);//TODO:check if not possible to put it at beginning of meth to avoid doubled check to DropTarget. + childrenRWLock.EnterReadLock (); for (int i = Children.Count - 1; i >= 0; i--) { - if (Children[i].MouseIsIn(e.Position)) - { + if (Children[i].MouseIsIn (e.Position)) { Children[i].checkHoverWidget (e); + childrenRWLock.ExitReadLock (); return; } } - base.checkHoverWidget (e); + childrenRWLock.ExitReadLock (); } // public override bool PointIsIn (ref Point m) // { diff --git a/Crow/src/Widgets/MenuItem.cs b/Crow/src/Widgets/MenuItem.cs index eb49147e..08db9291 100644 --- a/Crow/src/Widgets/MenuItem.cs +++ b/Crow/src/Widgets/MenuItem.cs @@ -126,9 +126,8 @@ namespace Crow Close.Raise (this, null); } public override bool MouseIsIn (Point m) - { - return IsEnabled && !IsDragged ? base.MouseIsIn (m) || child.MouseIsIn (m) : false; - } + => IsEnabled && !IsDragged ? base.MouseIsIn (m) || child.MouseIsIn (m) : false; + public override void onMouseEnter (object sender, MouseMoveEventArgs e) { base.onMouseEnter (sender, e); diff --git a/Crow/src/Widgets/Popper.cs b/Crow/src/Widgets/Popper.cs index 2fc5629d..99b3ef7d 100644 --- a/Crow/src/Widgets/Popper.cs +++ b/Crow/src/Widgets/Popper.cs @@ -178,10 +178,7 @@ namespace Crow } public override void checkHoverWidget (MouseMoveEventArgs e) { - if (IFace.HoverWidget != this) { - IFace.HoverWidget = this; - onMouseEnter (this, e); - } + base.checkHoverWidget (e); if (Content != null){ if (Content.Parent != null) { if (Content.MouseIsIn (e.Position)) { @@ -190,7 +187,6 @@ namespace Crow } } } - base.checkHoverWidget (e); } #endregion diff --git a/Crow/src/Widgets/TabItem.cs b/Crow/src/Widgets/TabItem.cs index 61a34c2e..bc147a87 100644 --- a/Crow/src/Widgets/TabItem.cs +++ b/Crow/src/Widgets/TabItem.cs @@ -226,7 +226,7 @@ namespace Crow dragStartPoint = IFace.MousePosition; } - protected override void onEndDrag (object sender, DragDropEventArgs e) + public override void onEndDrag (object sender, DragDropEventArgs e) { base.onEndDrag (sender, e); @@ -237,7 +237,7 @@ namespace Crow IFace.ClearDragImage (); } - protected override void onDrop (object sender, DragDropEventArgs e) + public override void onDrop (object sender, DragDropEventArgs e) { base.onDrop (sender, e); if (Parent != null) diff --git a/Crow/src/Widgets/Widget.cs b/Crow/src/Widgets/Widget.cs index eb963926..d1f085aa 100644 --- a/Crow/src/Widgets/Widget.cs +++ b/Crow/src/Widgets/Widget.cs @@ -266,6 +266,7 @@ namespace Crow bool hasFocus; bool isActive; bool isHover; + bool bubbleMouseEvent; bool mouseRepeat; bool stickyMouseEnabled; int stickyMouse; @@ -455,6 +456,7 @@ namespace Crow public event EventHandler DragLeave; public event EventHandler EndDrag; public event EventHandler Drop; + public event EventHandler Drag; #endregion /// @@ -704,7 +706,7 @@ namespace Crow onUnfocused (this, null); NotifyValueChangedAuto (hasFocus); } - } + } /// /// true if this control is active, this means that mouse has been pressed in it and not yet released. It could /// be used for other two states periferic action. @@ -743,6 +745,20 @@ namespace Crow } } /// + /// if false, prevent mouse events to bubble to the parent in any case. + /// + [DesignCategory ("Behaviour")] + [DefaultValue (true)] + public virtual bool BubbleMouseEvent { + get => bubbleMouseEvent; + set { + if (bubbleMouseEvent == value) + return; + bubbleMouseEvent = value; + NotifyValueChangedAuto (bubbleMouseEvent); + } + } + /// /// true if holding mouse button down should trigger multiple click events /// [DesignCategory ("Behaviour")][DefaultValue(false)] @@ -1300,7 +1316,7 @@ namespace Crow #region Drag&Drop [DesignCategory ("DragAndDrop")][DefaultValue(false)] public virtual bool AllowDrag { - get { return allowDrag; } + get => allowDrag; set { if (allowDrag == value) return; @@ -1310,7 +1326,7 @@ namespace Crow } [DesignCategory ("DragAndDrop")][DefaultValue(false)] public virtual bool AllowDrop { - get { return allowDrop; } + get => allowDrop; set { if (allowDrop == value) return; @@ -1330,7 +1346,7 @@ namespace Crow // get { return AllowedDroppedTypes?.Count>0; } // } [XmlIgnore]public virtual bool IsDragged { - get { return isDragged; } + get => isDragged; set { if (isDragged == value) return; @@ -1339,54 +1355,62 @@ namespace Crow NotifyValueChanged ("IsDragged", IsDragged); } } + /// + /// equivalent to mouse move for a dragged widget, no bubbling. + /// + public virtual void onDrag (object sender, MouseMoveEventArgs e) { + if (Drag != null) + Drag.Invoke (this, e); +#if DEBUG_DRAGNDROP + Debug.WriteLine (this.ToString () + " : DRAG => " + e.ToString ()); +#endif + } + /// /// fired when drag and drop operation start /// protected virtual void onStartDrag (object sender, DragDropEventArgs e){ - IFace.HoverWidget = null; - IFace.DragAndDropOperation = new DragDropEventArgs (this); + IFace.DragAndDropOperation = e; + IFace.dragndropHover = e.DropTarget; IsDragged = true; StartDrag.Raise (this, IFace.DragAndDropOperation); #if DEBUG_DRAGNDROP - Debug.WriteLine(this.ToString() + " : START DRAG => " + e.ToString()); + Debug.WriteLine(this.ToString() + " : START DRAG => " + e.ToString()); #endif } - /// - /// Occured when dragging ends without dropping - /// - protected virtual void onEndDrag (object sender, DragDropEventArgs e){ - IsDragged = false; - EndDrag.Raise (this, e); - #if DEBUG_DRAGNDROP - Debug.WriteLine(this.ToString() + " : END DRAG => " + e.ToString()); - #endif - } - protected virtual void onDragEnter (object sender, DragDropEventArgs e){ - e.DropTarget = this; + protected virtual void onDragEnter (object sender, DragDropEventArgs e){ + e.DropTarget = this; DragEnter.Raise (this, e); #if DEBUG_DRAGNDROP Debug.WriteLine(this.ToString() + " : DRAG Enter => " + e.ToString()); #endif } - protected virtual void onDragLeave (object sender, DragDropEventArgs e){ - e.DropTarget = null; + public virtual void onDragLeave (object sender, DragDropEventArgs e){ DragLeave.Raise (this, e); - #if DEBUG_DRAGNDROP - Debug.WriteLine(this.ToString() + " : DRAG Leave => " + e.ToString()); - #endif +#if DEBUG_DRAGNDROP + Debug.WriteLine (this.ToString () + " : DRAG Leave => " + e.ToString ()); +#endif + e.DropTarget = null; + } + /// + /// Occured when dragging ends without dropping + /// + public virtual void onEndDrag (object sender, DragDropEventArgs e) { + IsDragged = false; + EndDrag.Raise (this, e); +#if DEBUG_DRAGNDROP + Debug.WriteLine(this.ToString() + " : END DRAG => " + e.ToString()); +#endif } - protected virtual void onDrop (object sender, DragDropEventArgs e){ + public virtual void onDrop (object sender, DragDropEventArgs e){ IsDragged = false; Drop.Raise (this, e); //e.DropTarget.onDragLeave (this, e);//raise drag leave in target - #if DEBUG_DRAGNDROP +#if DEBUG_DRAGNDROP Debug.WriteLine(this.ToString() + " : DROP => " + e.ToString()); - #endif - } - public bool IsDropTarget { - get { return IFace.DragAndDropOperation?.DropTarget == this; } +#endif } - + public bool IsDropTarget => IFace.DragAndDropOperation?.DropTarget == this; #endregion #region Queuing @@ -1882,7 +1906,7 @@ namespace Crow { if (parent == null) return false; - if (!(isVisible & IsEnabled)||IsDragged) + if (!(isVisible & IsEnabled)) return false; if (!parent.PointIsIn(ref m)) return false; @@ -1890,36 +1914,31 @@ namespace Crow return Slot.ContainsOrIsEqual (m); } public virtual bool MouseIsIn(Point m) - { - return (!(isVisible & IsEnabled)||IsDragged) ? false : PointIsIn (ref m); - } + => (!(isVisible & IsEnabled) || IsDragged) ? false : PointIsIn (ref m); public virtual void checkHoverWidget(MouseMoveEventArgs e) { - if (IFace.HoverWidget != this) { + if (IFace.DragAndDropInProgress) { + if (IFace.dragndropHover != this) { + IFace.dragndropHover = this; + if (AllowDrop) + onDragEnter (this, IFace.DragAndDropOperation); + } + } else if (IFace.HoverWidget != this) { onMouseEnter (this, e); IFace.HoverWidget = this; - } - - //this.onMouseMove (this, e);//without this, window border doesn't work, should be removed + } } public virtual void onMouseMove (object sender, MouseMoveEventArgs e) { - if (allowDrag & hasFocus & IFace.IsDown(MouseButton.Left)) { - if (IFace.DragAndDropOperation == null) - onStartDrag (this, IFace.DragAndDropOperation); - } - - //dont bubble event if dragged, mouse move is routed directely from iface - //to let other control behind have mouse entering - if (isDragged) + if (AllowDrag & IFace.IsDown (MouseButton.Left)) { + onStartDrag (this, new DragDropEventArgs (this, FocusParent)); return; + } if (MouseMove != null) MouseMove.Invoke (this, e); - else if (!e.Handled) + else if (!e.Handled && BubbleMouseEvent) FocusParent?.onMouseMove (sender, e); - - } /// /// Default mouse button press method. The `MouseDown` event is raised from withing it. @@ -1942,7 +1961,7 @@ namespace Crow if (MouseDown != null) MouseDown?.Invoke (this, e); - else if (!e.Handled) + else if (!e.Handled && BubbleMouseEvent) FocusParent?.onMouseDown (sender, e); } /// @@ -1955,18 +1974,9 @@ namespace Crow /// mouse button release event arguments public virtual void onMouseUp(object sender, MouseButtonEventArgs e){ - if (IFace.DragAndDropOperation != null){ - if (IFace.DragAndDropOperation.DragSource == this) { - if (IFace.DragAndDropOperation.DropTarget != null) - onDrop (this, IFace.DragAndDropOperation); - else - onEndDrag (this, IFace.DragAndDropOperation); - IFace.DragAndDropOperation = null; - } - } if (MouseUp != null) MouseUp.Invoke (this, e); - else if (!e.Handled) + else if (!e.Handled && BubbleMouseEvent) FocusParent?.onMouseUp (sender, e); } /// @@ -1977,7 +1987,7 @@ namespace Crow public virtual void onMouseClick(object sender, MouseButtonEventArgs e){ if (MouseClick != null) MouseClick.Invoke (this, e); - else if (!e.Handled) + else if (!e.Handled && BubbleMouseEvent) FocusParent?.onMouseClick (sender, e); } /// @@ -1989,19 +1999,19 @@ namespace Crow public virtual void onMouseDoubleClick(object sender, MouseButtonEventArgs e){ if (MouseDoubleClick != null) MouseDoubleClick.Invoke (this, e); - else if (!e.Handled) + else if (!e.Handled && BubbleMouseEvent) FocusParent?.onMouseDoubleClick (sender, e); } public virtual void onMouseWheel(object sender, MouseWheelEventArgs e){ if (MouseWheelChanged != null) MouseWheelChanged.Invoke (this, e); - else if (!e.Handled) + else if (!e.Handled && BubbleMouseEvent) FocusParent?.onMouseWheel (sender, e); } public virtual void onMouseEnter(object sender, MouseMoveEventArgs e) { IFace.MouseCursor = MouseCursor; - if (IFace.DragAndDropOperation != null) { + /*if (IFace.DragAndDropOperation != null) { Widget g = this; while (g != null) { if (g.AllowDrop) { @@ -2014,15 +2024,12 @@ namespace Crow } g = g.FocusParent; } - } + }*/ 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/Samples/dockableWindows/dockableWindows.cs b/Samples/dockableWindows/dockableWindows.cs index 4b5a0e11..27a9612a 100644 --- a/Samples/dockableWindows/dockableWindows.cs +++ b/Samples/dockableWindows/dockableWindows.cs @@ -1,4 +1,5 @@ using Crow; +using Glfw; namespace tests { @@ -11,6 +12,17 @@ namespace tests } } + Color[] colors = + { + Colors.Blue, + Colors.Red, + Colors.Green, + Colors.Yellow, + Colors.Grey, + Colors.Onyx, + Colors.Cyan, + Colors.Chartreuse, + }; protected override void OnInitialized () { Load ("#ui.test.crow").DataSource = this; AddWidget (new DockWindow (this) { Background = Colors.Blue, Left = 10, Top = 110, Resizable = true }); @@ -23,6 +35,17 @@ namespace tests NotifyValueChanged ("GraphicTree", (object)null); NotifyValueChanged ("GraphicTree", GraphicTree); } - - } + int colorIdx = 0; + 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 }); + return true; + default: + return base.OnKeyDown (key); + } + } + } } diff --git a/Samples/dockableWindows/ui/test.crow b/Samples/dockableWindows/ui/test.crow index 3c16376b..f576fbbd 100644 --- a/Samples/dockableWindows/ui/test.crow +++ b/Samples/dockableWindows/ui/test.crow @@ -14,8 +14,9 @@