From 785b108f9bf0694c6d45e3696a7bfc85a7f9c04e Mon Sep 17 00:00:00 2001 From: jpbruyere Date: Tue, 2 May 2017 11:46:26 +0200 Subject: [PATCH] drag&drop in progress, replace BubblingEvents with focusGiven boolean in currentInterface --- Crow.csproj | 1 - src/BubblingMouseButtonEventArgs.cs | 39 --------------------- src/GraphicObjects/GraphicObject.cs | 53 +++++++++++++++++++++++++---- src/GraphicObjects/Group.cs | 34 ++++++++++-------- src/GraphicObjects/MenuItem.cs | 2 +- src/GraphicObjects/TabItem.cs | 2 +- src/GraphicObjects/Window.cs | 26 ++++++++++++++ src/Interface.cs | 17 +++++++-- 8 files changed, 108 insertions(+), 66 deletions(-) delete mode 100644 src/BubblingMouseButtonEventArgs.cs diff --git a/Crow.csproj b/Crow.csproj index 4ca2f5d0..751f5cb7 100644 --- a/Crow.csproj +++ b/Crow.csproj @@ -97,7 +97,6 @@ - diff --git a/src/BubblingMouseButtonEventArgs.cs b/src/BubblingMouseButtonEventArgs.cs deleted file mode 100644 index 0c8afd26..00000000 --- a/src/BubblingMouseButtonEventArgs.cs +++ /dev/null @@ -1,39 +0,0 @@ -// -// BubblingMouseButtonEventArgs.cs -// -// Author: -// Jean-Philippe Bruyère -// -// Copyright (c) 2013-2017 Jean-Philippe Bruyère -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -using System; - -namespace Crow -{ - public class BubblingMouseButtonEventArg: MouseButtonEventArgs - { - public GraphicObject Focused; - public BubblingMouseButtonEventArg(MouseButtonEventArgs mbe) : base(mbe){ - - } - } -} - diff --git a/src/GraphicObjects/GraphicObject.cs b/src/GraphicObjects/GraphicObject.cs index feea7520..d45ed304 100644 --- a/src/GraphicObjects/GraphicObject.cs +++ b/src/GraphicObjects/GraphicObject.cs @@ -188,6 +188,9 @@ namespace Crow protected object dataSource; string style; object tag; + bool isDragged; + bool allowDrag; + #endregion #region public fields @@ -1008,6 +1011,45 @@ namespace Crow return false; } + #region Drag&Drop + [XmlAttributeAttribute()][DefaultValue(false)] + public virtual bool AllowDrag { + get { return allowDrag; } + set { + if (allowDrag == value) + return; + allowDrag = value; + NotifyValueChanged ("AllowDrag", allowDrag); + } + } + + public List AllowedDroppedTypes; + + [XmlIgnore]public virtual bool AllowDrop { + get { return AllowedDroppedTypes?.Count>0; } + } + [XmlIgnore]public virtual bool IsDragged { + get { return isDragged; } + set { + if (isDragged == value) + return; + isDragged = value; + + if (isDragged) + currentInterface.HoverWidget = null; + + NotifyValueChanged ("IsDrag", IsDragged); + } + } + + public void AddAllowedDroppedType (Type newType){ + if (AllowedDroppedTypes == null) + AllowedDroppedTypes = new List (); + AllowedDroppedTypes.Add (newType); + NotifyValueChanged ("AllowDrop", AllowDrop); + } + #endregion + #region Queuing /// /// Register old and new slot for clipping @@ -1410,7 +1452,7 @@ namespace Crow public virtual bool MouseIsIn(Point m) { try { - if (!(Visible & isEnabled)) + if (!(Visible & isEnabled)||IsDragged) return false; if (ScreenCoordinates (Slot).ContainsOrIsEqual (m)) { Scroller scr = Parent as Scroller; @@ -1453,12 +1495,9 @@ namespace Crow if (CurrentInterface.ActiveWidget == null) CurrentInterface.ActiveWidget = this; - if (this.Focusable && !Interface.FocusOnHover) { - BubblingMouseButtonEventArg be = e as BubblingMouseButtonEventArg; - if (be.Focused == null) { - be.Focused = this; - CurrentInterface.FocusedWidget = this; - } + if (this.Focusable && !(Interface.FocusOnHover || currentInterface.focusGiven)) { + CurrentInterface.FocusedWidget = this; + currentInterface.focusGiven = true; } //bubble event to the top GraphicObject p = Parent as GraphicObject; diff --git a/src/GraphicObjects/Group.cs b/src/GraphicObjects/Group.cs index 551db889..edb6a88e 100644 --- a/src/GraphicObjects/Group.cs +++ b/src/GraphicObjects/Group.cs @@ -70,7 +70,7 @@ namespace Crow g.RegisterForLayouting (LayoutingType.Sizing | LayoutingType.ArrangeChildren); g.LayoutChanged += OnChildLayoutChanges; } - public virtual void RemoveChild(GraphicObject child) + public virtual void RemoveChild(GraphicObject child) { child.LayoutChanged -= OnChildLayoutChanges; //check if HoverWidget is removed from Tree @@ -87,7 +87,7 @@ namespace Crow searchLargestChild (); if (child == tallestChild && Height == Measure.Fit) searchTallestChild (); - + this.RegisterForLayouting (LayoutingType.Sizing | LayoutingType.ArrangeChildren); } public virtual void ClearChildren() @@ -107,16 +107,22 @@ namespace Crow ChildrenCleared.Raise (this, new EventArgs ()); } -// public void putWidgetOnTop(GraphicObject w) -// { -// if (Children.Contains(w)) -// { -// lock (children) { -// Children.Remove (w); -// Children.Add (w); -// } -// } -// } + public void PutWidgetOnTop(GraphicObject w) + { + if (this.ArrangeChildren) { + Debug.WriteLine ("Can't raise widget in group that has ArrangeChildren set to true."); + return; + } + if (Children.Contains(w)) + { + lock (children) { + Children.Remove (w); + Children.Add (w); + } + lock (CurrentInterface.UpdateMutex) + CurrentInterface.EnqueueForRepaint (w); + } + } // public void putWidgetOnBottom(GraphicObject w) // { // if (Children.Contains(w)) @@ -185,7 +191,7 @@ namespace Crow } return base.measureRawSize (lt); } - + public override void OnLayoutChanges (LayoutingType layoutType) { base.OnLayoutChanges (layoutType); @@ -345,7 +351,7 @@ namespace Crow } } - + #region Mouse handling public override void checkHoverWidget (MouseMoveEventArgs e) { diff --git a/src/GraphicObjects/MenuItem.cs b/src/GraphicObjects/MenuItem.cs index 5565ace3..cd2a54a8 100644 --- a/src/GraphicObjects/MenuItem.cs +++ b/src/GraphicObjects/MenuItem.cs @@ -156,7 +156,7 @@ namespace Crow } public override bool MouseIsIn (Point m) { - return IsEnabled ? base.MouseIsIn (m) || child.MouseIsIn (m) : false; + return IsEnabled && !IsDragged ? base.MouseIsIn (m) || child.MouseIsIn (m) : false; } public override void onMouseEnter (object sender, MouseMoveEventArgs e) { diff --git a/src/GraphicObjects/TabItem.cs b/src/GraphicObjects/TabItem.cs index afafb0f1..2fdc3802 100644 --- a/src/GraphicObjects/TabItem.cs +++ b/src/GraphicObjects/TabItem.cs @@ -140,7 +140,7 @@ namespace Crow #region Mouse Handling public override bool MouseIsIn (Point m) { - if (!Visible) + if (!(Visible & IsEnabled) || IsDragged) return false; bool mouseIsInTitle = TabTitle.ScreenCoordinates (TabTitle.Slot).ContainsOrIsEqual (m); diff --git a/src/GraphicObjects/Window.cs b/src/GraphicObjects/Window.cs index d1f34374..ecbdb22a 100644 --- a/src/GraphicObjects/Window.cs +++ b/src/GraphicObjects/Window.cs @@ -171,7 +171,33 @@ namespace Crow // } #endregion + public void Raise (){ + Group g = LogicalParent as Group; + if (g != null) { + g.PutWidgetOnTop (this); + return; + } + Interface i = LogicalParent as Interface; + if (i != null) + i.PutOnTop (this); + } + #region GraphicObject Overrides + protected override void onFocused (object sender, EventArgs e) + { + if (Interface.RaiseWhenFocused) + this.Raise (); + + base.onFocused (sender, e); + } + public override void onMouseEnter (object sender, MouseMoveEventArgs e) + { + if (Interface.FocusOnHover && !CurrentInterface.focusGiven) { + CurrentInterface.FocusedWidget = this; + CurrentInterface.focusGiven = true; + } + base.onMouseEnter (sender, e); + } public override void onMouseMove (object sender, MouseMoveEventArgs e) { base.onMouseMove (sender, e); diff --git a/src/Interface.cs b/src/Interface.cs index 7d691152..2dab2c85 100644 --- a/src/Interface.cs +++ b/src/Interface.cs @@ -96,6 +96,8 @@ namespace Crow public static string CrowConfigRoot; /// If true, mouse focus is given when mouse is over control public static bool FocusOnHover = false; + /// Raise widget when it got focus + public static bool RaiseWhenFocused = true; /// Threshold to catch borders for sizing public static int BorderThreshold = 5; /// Double click threshold in milisecond @@ -129,6 +131,11 @@ namespace Crow internal static Interface CurrentInterface; internal Stopwatch clickTimer = new Stopwatch(); internal GraphicObject eligibleForDoubleClick = null; + /// + /// each time a processMouseEvent is called at the top level, the focusGiven is set to false, and if while bubbling up the event + /// give the focus to a new widget, this boolean is set to true to prevent giving focus multiple times for a single mouse event. + /// + internal bool focusGiven = false; #endregion #region Events @@ -738,6 +745,8 @@ namespace Crow /// true if mouse is in the interface public bool ProcessMouseMove(int x, int y) { + focusGiven = false; + int deltaX = x - Mouse.X; int deltaY = y - Mouse.Y; Mouse.X = x; @@ -802,8 +811,6 @@ namespace Crow GraphicObject g = GraphicTree [i]; if (g.MouseIsIn (e.Position)) { g.checkHoverWidget (e); - if (g is Window) - PutOnTop (g); return true; } } @@ -818,6 +825,8 @@ namespace Crow /// Button index public bool ProcessMouseButtonUp(int button) { + focusGiven = false; + Mouse.DisableBit (button); MouseButtonEventArgs e = new MouseButtonEventArgs () { Mouse = Mouse }; @@ -841,13 +850,15 @@ namespace Crow /// Button index public bool ProcessMouseButtonDown(int button) { + focusGiven = false; + Mouse.EnableBit (button); MouseButtonEventArgs e = new MouseButtonEventArgs () { Mouse = Mouse }; if (HoverWidget == null) return false; - HoverWidget.onMouseDown(HoverWidget,new BubblingMouseButtonEventArg(e)); + HoverWidget.onMouseDown(HoverWidget, e); if (FocusedWidget == null) return true; -- 2.47.3