Browse Source

Support for file dragging in workspace panel

Brian Fiete 4 years ago
parent
commit
f6174aade2

+ 9 - 2
BeefLibs/Beefy2D/src/events/DragEvent.bf

@@ -4,12 +4,19 @@ using System.Text;
 
 namespace Beefy.events
 {
+	public enum DragKind
+	{
+		None,
+		Inside,
+		Before,
+		After
+	}
+
     public class DragEvent : Event
     {
         public float mX;
         public float mY;
         public Object mDragTarget;
-        public int32 mDragTargetDir;
-        public bool mDragAllowed = true;
+        public DragKind mDragKind = .Inside;
     }
 }

+ 90 - 22
BeefLibs/Beefy2D/src/theme/dark/DarkListView.bf

@@ -101,7 +101,7 @@ namespace Beefy.theme.dark
         public DragEvent mCurDragEvent ~ delete _;
         public DragHelper mDragHelper ~ delete _;
         public DarkListViewItem mDragTarget;
-        public int32 mDragTargetInsertDir;
+        public DragKind mDragKind;
         public bool mOpenOnDoubleClick = true;
         public bool mIsBold;
 
@@ -174,6 +174,14 @@ namespace Beefy.theme.dark
 			}
 		}
 
+		public override bool IsDragging
+		{
+			get
+			{
+				return (mDragTarget != null) && (mDragHelper.mIsDragging);
+			}
+		}
+
         public this()
         {
             
@@ -596,8 +604,52 @@ namespace Beefy.theme.dark
                 DrawLinesGrid(g);
 
 			DrawChildren(g);
-            
-            if (mDragTarget != null)
+
+			if (mDragTarget != null)
+			{
+				listView.mOnPostDraw.Add(new (g) =>
+					{
+						float targetX;
+						float targetY;
+						mDragTarget.SelfToOtherTranslate(mListView, 0, 0, out targetX, out targetY);
+
+						//using (g.PushTranslate(targetX, targetY))
+						{
+						    /*if ((mUpdateCnt % 60) == 0)
+						        Debug.WriteLine(String.Format("{0} indent {1}", mDragTarget.mLabel, mDragTarget.mDepth));*/
+
+							if (mDragKind == .Inside)
+							{
+								using (g.PushColor(0xFF6f9761))
+								{
+									//g.FillRect(targetX + GS!(4), targetY, mListView.mWidth - targetX - GS!(28), GS!(22));
+									//g.OutlineRect(targetX + GS!(4), targetY, mListView.mWidth - targetX - GS!(28), GS!(20));
+									g.DrawButton(DarkTheme.sDarkTheme.GetImage(Focused ? DarkTheme.ImageIdx.MenuSelect : DarkTheme.ImageIdx.MenuNonFocusSelect),
+										targetX + GS!(2), targetY, listView.mWidth - targetX - GS!(24));
+								}
+							}
+							else
+							{
+						        if ((mDragKind == .Inside) || (mDragKind == .After)) // Inside or after
+						            targetY += mDragTarget.mSelfHeight;
+						        
+						        if (mDragKind == .After) // After
+						            targetY += mDragTarget.mChildAreaHeight + mDragTarget.mBottomPadding;
+
+						        if (mDragKind == .Inside) // Inside
+						            targetX += ((DarkListView)mListView).mChildIndent + mDragTarget.mChildIndent;
+
+						        /*if (-curY + targetY > mHeight)                    
+						            wasTargetBelowBottom = true;*/                    
+
+						        using (g.PushColor(0xFF95A68F))
+						            g.FillRect(targetX + GS!(4), targetY, mListView.mWidth - targetX - GS!(28), GS!(2));
+							}
+						}
+					});
+			}	
+
+            /*if (mDragTarget != null)
             {
                 float targetX;
                 float targetY;
@@ -614,20 +666,28 @@ namespace Beefy.theme.dark
                     /*if ((mUpdateCnt % 60) == 0)
                         Debug.WriteLine(String.Format("{0} indent {1}", mDragTarget.mLabel, mDragTarget.mDepth));*/
 
-                    if (mDragTargetInsertDir >= 0) // Inside or after
-                        targetY += mDragTarget.mSelfHeight;
-                    
-                    if (mDragTargetInsertDir > 0) // After
-                        targetY += mDragTarget.mChildAreaHeight + mDragTarget.mBottomPadding;
+					if (mDragKind == .Inside)
+					{
+						using (g.PushColor(0xFF95A68F))
+							g.FillRect(targetX + GS!(4), targetY, mListView.mWidth - targetX - GS!(28), GS!(22));
+					}
+					else
+					{
+	                    if ((mDragKind == .Inside) || (mDragKind == .After)) // Inside or after
+	                        targetY += mDragTarget.mSelfHeight;
+	                    
+	                    if (mDragKind == .After) // After
+	                        targetY += mDragTarget.mChildAreaHeight + mDragTarget.mBottomPadding;
 
-                    if (mDragTargetInsertDir == 0) // Inside
-                        targetX += ((DarkListView)mListView).mChildIndent + mDragTarget.mChildIndent;
+	                    if (mDragKind == .Inside) // Inside
+	                        targetX += ((DarkListView)mListView).mChildIndent + mDragTarget.mChildIndent;
 
-                    if (-curY + targetY > mHeight)                    
-                        wasTargetBelowBottom = true;                    
+	                    if (-curY + targetY > mHeight)                    
+	                        wasTargetBelowBottom = true;                    
 
-                    using (g.PushColor(0xFF95A68F))
-                        g.FillRect(targetX + 4, targetY, mListView.mWidth - targetX - 28, 2);
+	                    using (g.PushColor(0xFF95A68F))
+	                        g.FillRect(targetX + GS!(4), targetY, mListView.mWidth - targetX - GS!(28), GS!(2));
+					}
                 }
 
                 if (wasTargetBelowBottom)
@@ -635,7 +695,7 @@ namespace Beefy.theme.dark
                     /*Image img = DarkTheme.sDarkTheme.GetImage(DarkTheme.ImageIdx.MoveDownArrow);
                     g.Draw(img, mWidth / 2 - img.mWidth / 2, mHeight - img.mHeight);*/
                 }
-            }
+            }*/
         }
 
         public override bool Open(bool open, bool immediate = false)
@@ -662,7 +722,7 @@ namespace Beefy.theme.dark
                 e.mSender = GetMainItem();
                 e.mDragTarget = mDragTarget;                
                 if (mDragHelper.mAborted)
-                    e.mDragAllowed = false;
+                    e.mDragKind = .None;
                 if (listView.mOnDragEnd.HasListeners)
                     listView.mOnDragEnd(e);
             }
@@ -723,12 +783,12 @@ namespace Beefy.theme.dark
                 
                 float yOfs = aY - childY;
                 if (yOfs < mHeight / 2)
-                    mDragTargetInsertDir = -1;
+                    mDragKind = .Before;
                 else
                 {
-                    mDragTargetInsertDir = 1;
+                    mDragKind = .After;
                     if ((listViewItem.mOpenButton != null) && (listViewItem.mOpenButton.mIsOpen))
-                        mDragTargetInsertDir = 0;
+                        mDragKind = .None;
                 }
 
 				delete mCurDragEvent;
@@ -737,12 +797,12 @@ namespace Beefy.theme.dark
                 mCurDragEvent.mY = y;
                 mCurDragEvent.mSender = head;
                 mCurDragEvent.mDragTarget = foundWidget;
-                mCurDragEvent.mDragTargetDir = mDragTargetInsertDir;
+                mCurDragEvent.mDragKind = mDragKind;
                 listView.mOnDragUpdate(mCurDragEvent);                
-                mDragTargetInsertDir = mCurDragEvent.mDragTargetDir;
+                mDragKind = mCurDragEvent.mDragKind;
 
                 mDragTarget = mCurDragEvent.mDragTarget as DarkListViewItem;
-                if (!mCurDragEvent.mDragAllowed)
+                if (mCurDragEvent.mDragKind == .None)
                     mDragTarget = null;
 
                 if (mDragTarget != null)
@@ -847,6 +907,7 @@ namespace Beefy.theme.dark
 
         public Event<delegate void(DragEvent)> mOnDragUpdate ~ _.Dispose();
         public Event<delegate void(DragEvent)> mOnDragEnd ~ _.Dispose();
+		public Event<delegate void(Graphics)> mOnPostDraw ~ _.Dispose();
 
         public this()
         {
@@ -1004,6 +1065,13 @@ namespace Beefy.theme.dark
             }
         }
 
+		public override void DrawAll(Graphics g)
+		{
+			base.DrawAll(g);
+			mOnPostDraw(g);
+			mOnPostDraw.Dispose();
+		}
+
         public override void MouseMove(float x, float y)
         {
             base.MouseMove(x, y);

+ 14 - 11
BeefLibs/Beefy2D/src/widgets/DragHelper.bf

@@ -151,20 +151,23 @@ namespace Beefy.widgets
 
         public void Update()
         {
-            int32 ticksDown = mWidget.mUpdateCnt - mDownUpdateCnt;
+            //int32 ticksDown = mWidget.mUpdateCnt - mDownUpdateCnt;
 
-            if (((mMouseFlags & MouseFlag.Left) != 0) && (ticksDown >= mMinDownTicks))
+            if ((mMouseFlags & MouseFlag.Left) != 0)
             {
-                if ((!mIsDragging) && (mAllowDrag))
+				bool isTriggered = false;
+				/*if ((mMinDownTicks > 0) && (ticksDown >= mMinDownTicks))
+					isTriggered = true;*/
+				if ((Math.Abs(mMouseX - mMouseDownX) >= mTriggerDist) || (Math.Abs(mMouseY - mMouseDownY) >= mTriggerDist))
+					isTriggered = true;
+
+                if ((!mIsDragging) && (mAllowDrag) && (isTriggered))
                 {
-                    if ((Math.Abs(mMouseX - mMouseDownX) >= mTriggerDist) || (Math.Abs(mMouseY - mMouseDownY) >= mTriggerDist))
-                    {
-                        SetHooks(true);
-                        mPreparingForWidgetMove = false;
-                        mAborted = false;
-                        mIsDragging = true;
-                        mDragInterface.DragStart();
-                    }
+                    SetHooks(true);
+                    mPreparingForWidgetMove = false;
+                    mAborted = false;
+                    mIsDragging = true;
+                    mDragInterface.DragStart();
                 }
 
                 if (mIsDragging)

+ 53 - 8
BeefLibs/Beefy2D/src/widgets/ListView.bf

@@ -4,6 +4,7 @@ using System.Collections;
 using System.Text;
 using System.Diagnostics;
 using Beefy.gfx;
+using Beefy.events;
 
 namespace Beefy.widgets
 {   
@@ -111,6 +112,14 @@ namespace Beefy.widgets
 			}
 		}
 
+		public virtual bool IsDragging
+		{
+			get
+			{
+				return false;
+			}
+		}
+
         public virtual float LabelX { get { return 0; } }
         public virtual float LabelWidth { get { return mWidth; } }
 
@@ -185,6 +194,16 @@ namespace Beefy.widgets
             return null;
         }
 
+		public int32 GetSelectedItemCount()
+		{
+		    int32 count = 0;
+			WithSelectedItems(scope [&] (item) =>
+				{
+					count++;
+				});
+		    return count;
+		}
+
         public ListViewItem FindLastSelectedItem(bool filterToVisible = false)
         {
             ListViewItem selected = null;
@@ -320,13 +339,44 @@ namespace Beefy.widgets
                 }
                 else
                 {
-                    SelectItemExclusively(item);
-                    if (item.Selected)
-                        item.Focused = true;
+					if (item.Selected)
+					{
+						item.mOnMouseUp.AddFront(new => ItemMouseUpHandler);
+
+						var focusedItem = FindFocusedItem();
+						if (focusedItem != null)
+						{
+							focusedItem.Focused = false;
+							focusedItem.Selected = true;
+						}
+						item.Focused = true;
+					}
+					else
+					{
+						SelectItemExclusively(item);
+						if (item.Selected)
+							item.Focused = true;
+					}
+                    //SelectItemExclusively(item);
+                    //if (item.Selected)
+                        //item.Focused = true;
                 }
             }
         }
 
+		void ItemMouseUpHandler(MouseEvent evt)
+		{
+			var item = evt.mSender as ListViewItem;
+			if ((item.mMouseOver) && (!item.IsDragging))
+			{
+				SelectItemExclusively(item);
+				if (item.Selected)
+					item.Focused = true;
+			}
+
+			item.mOnMouseUp.Remove(scope => ItemMouseUpHandler, true);
+		}
+
         public virtual void Clear()
         {
             if (mChildItems == null)
@@ -673,11 +723,6 @@ namespace Beefy.widgets
 		}
     }
 
-    public class ListViewDragData
-    {
-        List<ListViewItem> mDragItems;
-    }
-
     public abstract class ListView : ScrollableWidget
     {
         public List<ListViewColumn> mColumns = new List<ListViewColumn>() ~ DeleteContainerAndItems!(_);

+ 22 - 0
BeefLibs/corlib/src/Event.bf

@@ -114,6 +114,28 @@ namespace System
 			}
 		}
 
+		public void AddFront(T ownDelegate) mut
+		{
+			Object data = Target;
+			if (data == null)
+			{
+				Target = ownDelegate;
+				return;
+			}
+
+			if (var list = data as List<T>)
+			{
+				list.Insert(0, ownDelegate);
+			}
+			else
+			{
+				var list = new List<T>();
+				list.Add(ownDelegate);
+				list.Add((T)data);
+				Target = list;
+			}
+		}
+
 		public void Remove(T compareDelegate, bool deleteDelegate = false) mut
 		{
 			Object data = Target;

+ 13 - 0
IDE/src/Project.bf

@@ -455,6 +455,19 @@ namespace IDE
 			}
 		}
 
+		public void GetFullDisplayName(String displayName)
+		{
+			if (mParentFolder == null)
+				return;
+
+			if (mParentFolder.mParentFolder != null)
+			{
+				mParentFolder.mParentFolder.GetFullDisplayName(displayName);
+				displayName.Append("/");
+			}
+			displayName.Append(mName);
+		}
+
         public void GetRelDir(String path)
         {
 			if (mPath != null)

+ 172 - 41
IDE/src/ui/ProjectPanel.bf

@@ -145,8 +145,8 @@ namespace IDE.ui
             mListView.UpdateScrollbars();
             mListView.mOnFocusChanged.Add(new => FocusChangedHandler);
 
-            /*mListView.mOnDragEnd.Add(new => HandleDragEnd);
-            mListView.mOnDragUpdate.Add(new => HandleDragUpdate);*/
+            mListView.mOnDragEnd.Add(new => HandleDragEnd);
+            mListView.mOnDragUpdate.Add(new => HandleDragUpdate);
             
             AddWidget(mListView);
 
@@ -217,24 +217,175 @@ namespace IDE.ui
             DarkListViewItem source = (DarkListViewItem)theEvent.mSender;
             DarkListViewItem target = (DarkListViewItem)theEvent.mDragTarget;
 
+			theEvent.mDragKind = .None;
+
+			int validCount = 0;
+			int invalidCount = 0;
             if (source.mListView == target.mListView)
             {
-                ProjectItem sourceProjectItem = mListViewToProjectMap[source];
-                ProjectItem targetProjectItem = mListViewToProjectMap[target];
-                if (((sourceProjectItem.mParentFolder == null) || (targetProjectItem.mParentFolder == null)) ||
-                    (sourceProjectItem.mProject != targetProjectItem.mProject))
-                    theEvent.mDragAllowed = false;
-            }                
+				if (mListViewToProjectMap.GetValue(target) case .Ok(var targetProjectItem))
+				{
+					mListView.GetRoot().WithSelectedItems(scope [&] (selectedItem) =>
+						{
+							if (mListViewToProjectMap.GetValue(selectedItem) case .Ok(var sourceProjectItem))
+							{
+								if ((sourceProjectItem.mParentFolder != null) && (sourceProjectItem.mProject == targetProjectItem.mProject))
+									validCount++;
+								else
+									invalidCount++;
+							}
+						});
+				}
+            }
+
+			if ((validCount > 0) && (invalidCount == 0))
+				theEvent.mDragKind = .Inside;
         }
 
         void HandleDragEnd(DragEvent theEvent)
         {
-            if (!theEvent.mDragAllowed)
+            if (theEvent.mDragKind == .None)
                 return;
 
-            if (theEvent.mDragTarget is DarkListViewItem)
+            if (theEvent.mDragTarget is ProjectListViewItem)
             {
-                DarkListViewItem source = (DarkListViewItem)theEvent.mSender;
+				ProjectListViewItem source = (ProjectListViewItem)theEvent.mSender;
+				ProjectListViewItem target = (ProjectListViewItem)theEvent.mDragTarget;
+
+				theEvent.mDragKind = .None;
+
+				if (source.mListView == target.mListView)
+				{
+					if (mListViewToProjectMap.GetValue(target) case .Ok(var targetProjectItem))
+					{
+						if (targetProjectItem == null)
+						    return;
+
+						if (source == target)
+						    return;
+
+						var targetProjectFolder = targetProjectItem as ProjectFolder;
+						if (targetProjectFolder == null)
+							targetProjectFolder = targetProjectItem.mParentFolder;
+						var targetListItem = mProjectToListViewMap[targetProjectFolder];
+
+						int moveCount = 0;
+						int selectCount = 0;
+						mListView.GetRoot().WithSelectedItems(scope [&] (selectedItem) =>
+							{
+								if (mListViewToProjectMap.GetValue(selectedItem) case .Ok(var sourceProjectItem))
+								{
+									if (sourceProjectItem.mParentFolder != targetProjectFolder)
+										moveCount++;
+								}
+								selectCount++;
+							});
+
+						if (moveCount == 0)
+							return;
+
+						var targetDisplayName = targetProjectFolder.GetFullDisplayName(.. scope .());
+						if (targetDisplayName.IsEmpty)
+							targetDisplayName = "src";
+
+						Dialog dialog;
+						if (selectCount == 1)
+						{
+							dialog = ThemeFactory.mDefault.CreateDialog("Move file to a new location?",
+								scope $"Are you sure you want to move this file to '{targetDisplayName}'?");
+						}
+						else
+						{
+							dialog = ThemeFactory.mDefault.CreateDialog("Move files to a new location?",
+								scope $"Are you sure you want to move these files to '{targetDisplayName}'?");
+						}
+						dialog.AddButton("Yes", new (evt) =>
+							{
+								List<String> fileErrors = scope .();
+
+								List<ListViewItem> selectedItems = scope .();
+								mListView.GetRoot().WithSelectedItems(scope [&] (selectedItem) =>
+									{
+										selectedItems.Add(selectedItem);
+									});
+
+								for (var selectedItem in selectedItems)
+								{
+									if (mListViewToProjectMap.GetValue(selectedItem) case .Ok(var sourceProjectItem))
+									{
+										var sourceProjectFileItem = sourceProjectItem as ProjectFileItem;
+										if (sourceProjectFileItem == null)
+											return;
+
+										var sourcePath = sourceProjectFileItem.GetFullImportPath(.. scope .());
+										var destPath = targetProjectFolder.GetFullImportPath(.. scope .());
+										destPath.AppendF($"{Path.DirectorySeparatorChar}{sourceProjectFileItem.mName}");
+
+										if (File.Move(sourcePath, destPath) case .Ok)
+										{
+											gApp.FileRenamed(sourceProjectFileItem, sourcePath, destPath);
+										}
+										else
+											fileErrors.Add(scope:: .(destPath));
+
+										if (targetProjectFolder != sourceProjectItem.mParentFolder)
+										{
+											source.mParentItem.RemoveChildItem(source, false);
+											sourceProjectItem.mParentFolder.RemoveChild(sourceProjectItem);
+
+											targetListItem.AddChildAtIndex(0, source);
+											targetListItem.mOpenButton.Open(true, false);
+											targetProjectFolder.AddChildAtIndex(0, sourceProjectItem);
+										}
+									}
+								}
+
+								QueueSortItem(targetListItem);
+								DoSortItem(targetListItem);
+
+								if (!fileErrors.IsEmpty)
+								{
+									var errorStr = scope String();
+									if (fileErrors.Count == 1)
+										errorStr.AppendF("Failed to move file to: {0}", fileErrors[0]);
+									else
+									{
+										errorStr.AppendF("Failed to move {0} files:", fileErrors.Count);
+										for (var file in fileErrors)
+											errorStr.Append("\n  {}", file);
+									}
+									gApp.Fail(errorStr);
+								}
+							});
+						dialog.AddButton("No", new (evt) =>
+							{
+								
+							});
+						dialog.PopupWindow(gApp.GetActiveWindow());
+
+						
+						//RehupFolder(targetProjectFolder.mProject.mRootFolder, .FullTraversal);
+
+						/*if (theEvent.mDragTargetDir == -1) // Before          
+						{
+						    target.mParentItem.InsertChild(source, target);
+						    targetProjectItem.mParentFolder.InsertChild(sourceProjectItem, targetProjectItem);
+						}
+						else if (theEvent.mDragTargetDir == 0) // Inside
+						{
+						    target.AddChildAtIndex(0, source);
+						    target.mOpenButton.Open(true, false);
+						    ((ProjectFolder)targetProjectItem).AddChildAtIndex(0, sourceProjectItem);
+						}
+						else if (theEvent.mDragTargetDir == 1) // After
+						{                        
+						    target.mParentItem.AddChild(source, target);
+						    targetProjectItem.mParentFolder.AddChild(sourceProjectItem, targetProjectItem);                        
+						}*/
+					}
+				}
+
+                /*DarkListViewItem source = (DarkListViewItem)theEvent.mSender;
                 DarkListViewItem target = (DarkListViewItem)theEvent.mDragTarget;
 
                 if (source.mListView == target.mListView)
@@ -242,32 +393,8 @@ namespace IDE.ui
                     ProjectItem targetProjectItem = mListViewToProjectMap[target];
                     ProjectItem sourceProjectItem = mListViewToProjectMap[source];
 
-                    if ((targetProjectItem == null) || (sourceProjectItem == null))
-                        return;
-
-                    if (source == target)
-                        return;
-
-                    source.mParentItem.RemoveChildItem(source);
-                    sourceProjectItem.mParentFolder.RemoveChild(sourceProjectItem);
-
-                    if (theEvent.mDragTargetDir == -1) // Before          
-                    {
-                        target.mParentItem.InsertChild(source, target);
-                        targetProjectItem.mParentFolder.InsertChild(sourceProjectItem, targetProjectItem);
-                    }
-                    else if (theEvent.mDragTargetDir == 0) // Inside
-                    {
-                        target.AddChildAtIndex(0, source);
-                        target.mOpenButton.Open(true, false);
-                        ((ProjectFolder)targetProjectItem).AddChildAtIndex(0, sourceProjectItem);
-                    }
-                    else if (theEvent.mDragTargetDir == 1) // After
-                    {                        
-                        target.mParentItem.AddChild(source, target);
-                        targetProjectItem.mParentFolder.AddChild(sourceProjectItem, targetProjectItem);                        
-                    }
-                }
+                    
+                }*/
             }            
         }
 
@@ -342,6 +469,7 @@ namespace IDE.ui
 			item.mOnMouseClick.Add(new => ListViewItemClicked);
             UpdateColors();
             DarkListViewItem listViewItem = (DarkListViewItem)item;
+			listViewItem.AllowDragging = true;
             listViewItem.mFocusColor = gApp.mSettings.mUISettings.mColors.mWorkspaceDisabledText;
             listViewItem.mSelectColor = gApp.mSettings.mUISettings.mColors.mWorkspaceDisabledText;
         }
@@ -1136,10 +1264,13 @@ namespace IDE.ui
         {
             if (item.Focused)
             {
-                // Just rehup focus handler - handles case of closing file then clicking on it again
-                //  even though it's already selected.  We want that to re-open it.
-                FocusChangedHandler(item);
-                return;
+				if (mListView.GetRoot().GetSelectedItemCount() <= 1)
+				{
+	                // Just rehup focus handler - handles case of closing file then clicking on it again
+	                //  even though it's already selected.  We want that to re-open it.
+	                FocusChangedHandler(item);
+					return;
+				}
             }
 
             mListView.GetRoot().SelectItem(item, checkKeyStates);

+ 12 - 11
IDE/src/ui/WatchPanel.bf

@@ -1719,7 +1719,8 @@ namespace IDE.ui
 
         void HandleDragUpdate(DragEvent evt)
         {
-            evt.mDragAllowed = false;
+			var dragKind = evt.mDragKind;
+            evt.mDragKind = .None;
             if (mIsAuto)
                 return;
 
@@ -1736,20 +1737,20 @@ namespace IDE.ui
                 // Check for if we're dragging after the last open child item.  If so, treat it as if we're dragging to after the topmost parent
                 /*if ((evt.mDragTargetDir != 1) || (dragTarget != dragTarget.mParentItem.mChildItems[dragTarget.mParentItem.mChildItems.Count - 1]))
                     return;*/
-                evt.mDragTargetDir = 1;
+                evt.mDragKind = .After;
                 dragTarget = (WatchListViewItem)dragTarget.mParentItem;
                 evt.mDragTarget = dragTarget;
             }
-            if ((dragTarget.mLabel == "") && (evt.mDragTargetDir >= 0))
-                evt.mDragTargetDir = -1;            
-            if (evt.mDragTargetDir == 0)
+            if ((dragTarget.mLabel == "") && (dragKind == .After))
+                dragKind = .Before;            
+            if (dragKind == .None)
                 return;
-            evt.mDragAllowed = true;
+            evt.mDragKind = dragKind;
         }
 
         void HandleDragEnd(DragEvent theEvent)
         {
-            if (!theEvent.mDragAllowed)
+            if (theEvent.mDragKind == .None)
                 return;
 
             if (theEvent.mDragTarget is IDEListViewItem)
@@ -1766,9 +1767,9 @@ namespace IDE.ui
                     {
                         // We're dragging a top-level item into a new position
                         source.mParentItem.RemoveChildItem(source, false);
-                        if (theEvent.mDragTargetDir == -1) // Before
+                        if (theEvent.mDragKind == .Before) // Before
                             target.mParentItem.InsertChild(source, target);
-                        else if (theEvent.mDragTargetDir == 1) // After
+                        else if (theEvent.mDragKind == .After) // After
                             target.mParentItem.AddChild(source, target);
                     }
                     else
@@ -1778,8 +1779,8 @@ namespace IDE.ui
 
                         var rootItem = mListView.GetRoot();
                         int idx = rootItem.mChildItems.IndexOf(target);
-                        if (theEvent.mDragTargetDir > 0)
-                            idx += theEvent.mDragTargetDir;
+                        if (theEvent.mDragKind == .After)
+                            idx++;
                         var listViewItem = (WatchListViewItem)rootItem.CreateChildItemAtIndex(idx);
                         listViewItem.mVisible = false;
                         SetupListViewItem(listViewItem, compactEvalStr, compactEvalStr);