diff options
| author | Jean-Philippe Bruyère <jp_bruyere@hotmail.com> | 2018-03-06 16:53:23 +0100 |
|---|---|---|
| committer | Jean-Philippe Bruyère <jp_bruyere@hotmail.com> | 2018-03-06 16:53:23 +0100 |
| commit | 8c42e8eb2016ca433cc7adea278a27800f9f0050 (patch) | |
| tree | 2e39b2ac83d5ab0df28544e86490ac9e43473b17 /src/GraphicObjects | |
| parent | 975df273eafe358482d892c108fbba1fdc5cac1f (diff) | |
tabview drag and drop of tabitem
Diffstat (limited to 'src/GraphicObjects')
| -rw-r--r-- | src/GraphicObjects/GraphicObject.cs | 9 | ||||
| -rw-r--r-- | src/GraphicObjects/TabItem.cs | 90 | ||||
| -rw-r--r-- | src/GraphicObjects/TabView.cs | 72 |
3 files changed, 144 insertions, 27 deletions
diff --git a/src/GraphicObjects/GraphicObject.cs b/src/GraphicObjects/GraphicObject.cs index f6778e34..1e35f5b8 100644 --- a/src/GraphicObjects/GraphicObject.cs +++ b/src/GraphicObjects/GraphicObject.cs @@ -1266,6 +1266,10 @@ namespace Crow //e.DropTarget.onDragLeave (this, e);//raise drag leave in target Debug.WriteLine(this.ToString() + " : DROP => " + e.ToString()); } + public virtual void OnDragMove(object sender, MouseMoveEventArgs e, DragDropEventArgs dde) + { + + } public bool IsDropTarget { get { return IFace.DragAndDropOperation?.DropTarget == this; } } @@ -1709,6 +1713,11 @@ namespace Crow } } + //dont bubble event if dragged, mouse move is routed directely from iface + //to let other control behind have mouse entering + if (isDragged) + return; + //bubble event to the top GraphicObject p = focusParent; if (p != null) diff --git a/src/GraphicObjects/TabItem.cs b/src/GraphicObjects/TabItem.cs index 92cb20d8..b2814393 100644 --- a/src/GraphicObjects/TabItem.cs +++ b/src/GraphicObjects/TabItem.cs @@ -153,6 +153,79 @@ namespace Crow gr.Restore (); } + Point dragStartPoint; + int dragThreshold = 16; + int dis = 128; + internal TabView savedParent = null; + + void makeFloating (TabView tv) { + lock (IFace.UpdateMutex) { + ImageSurface di = new ImageSurface (Format.Argb32, dis, dis); + IFace.DragImageHeight = dis; + IFace.DragImageWidth = dis; + using (Context ctx = new Context (di)) { + double div = Math.Max (LastPaintedSlot.Width, LastPaintedSlot.Height); + double s = (double)dis / div; + ctx.Scale (s, s); + if (bmp == null) + this.onDraw (ctx); + else { + if (LastPaintedSlot.Width>LastPaintedSlot.Height) + ctx.SetSourceSurface (bmp, 0, (LastPaintedSlot.Width-LastPaintedSlot.Height)/2); + else + ctx.SetSourceSurface (bmp, (LastPaintedSlot.Height-LastPaintedSlot.Width)/2, 0); + + ctx.Paint (); + } + } + IFace.DragImage = di; + } + tv.RemoveChild (this); + savedParent = tv; + } + + public override ILayoutable Parent { + get { + return base.Parent; + } + set { + base.Parent = value; + if (value != null) { + dragStartPoint = IFace.Mouse.Position; + savedParent = value as TabView; + } + } + } + protected override void onStartDrag (object sender, DragDropEventArgs e) + { + base.onStartDrag (sender, e); + + dragStartPoint = IFace.Mouse.Position; + } + protected override void onEndDrag (object sender, DragDropEventArgs e) + { + base.onEndDrag (sender, e); + + if (Parent != null) + return; + + savedParent.AddChild (this); + + IFace.ClearDragImage (); + } + protected override void onDrop (object sender, DragDropEventArgs e) + { + base.onDrop (sender, e); + if (Parent != null) + return; + TabView tv = e.DropTarget as TabView; + if (tv == null) + return; + + IFace.ClearDragImage (); + + tv.AddChild (this); + } #region Mouse Handling public bool HoldCursor = false; public override bool PointIsIn (ref Point m) @@ -180,17 +253,28 @@ namespace Crow { base.onMouseMove (sender, e); + if (Parent == null) + return; + if (!(HasFocus && HoldCursor)) return; + TabView tv = Parent as TabView; + if (Math.Abs (e.Position.Y - dragStartPoint.Y) > dragThreshold || + Math.Abs (e.Position.X - dragStartPoint.X) > dragThreshold) { + makeFloating (tv); + return; + } + Rectangle cb = ClientRectangle; int tmp = TabOffset + e.XDelta; - if (tmp < tview.LeftSlope) + if (tmp < tview.LeftSlope) { TabOffset = tview.LeftSlope; - else if (tmp > cb.Width - tv.RightSlope - tv.TabWidth) + } else if (tmp > cb.Width - tv.RightSlope - tv.TabWidth) { TabOffset = cb.Width - tv.RightSlope - tv.TabWidth; - else{ + }else{ + dragStartPoint.X = e.Position.X; TabItem[] tabItms = tv.Children.Cast<TabItem>().OrderBy (t=>t.ViewIndex).ToArray(); if (ViewIndex > 0 && e.XDelta < 0) { TabItem previous = tabItms [ViewIndex - 1]; diff --git a/src/GraphicObjects/TabView.cs b/src/GraphicObjects/TabView.cs index 9d2f1145..06721651 100644 --- a/src/GraphicObjects/TabView.cs +++ b/src/GraphicObjects/TabView.cs @@ -205,25 +205,30 @@ namespace Crow Rectangle cb = ClientRectangle; int tabSpace = tabWidth + leftSlope; - int computedSpacing = Math.Min(tabSpace, (cb.Width - rightSlope - leftSlope) / (Children.Count (c => c.Visible == true))); + int tc = Children.Count (c => c.Visible == true)-1; + if (tc > 0) + tabSpace = Math.Min(tabSpace, (cb.Width-tabSpace-rightSlope) / tc); + //Console.WriteLine ("tabspace: {0} cb:{1}", tabSpace, cb); + + childrenRWLock.EnterReadLock(); TabItem[] tabItms = Children.Cast<TabItem>().OrderBy (t=>t.ViewIndex).ToArray(); + childrenRWLock.ExitReadLock(); int curOffset = leftSlope; for (int i = 0; i < tabItms.Length; i++) { if (!tabItms [i].Visible) continue; -// if (tabSizeHasChanged) { - tabItms [i].NotifyValueChanged ("TabHeight", tabHeight); - tabItms [i].NotifyValueChanged ("TabWidth", tabWidth); -// tabSizeHasChanged = false; -// } - if (!tabItms [i].HoldCursor) + tabItms [i].NotifyValueChanged ("TabHeight", tabHeight); + tabItms [i].NotifyValueChanged ("TabWidth", tabWidth); + if (!tabItms [i].HoldCursor) { tabItms [i].TabOffset = curOffset; + //Console.WriteLine ("offset: {0}=>{1}", tabItms [i].Name, tabItms [i].TabOffset); + } if (Orientation == Orientation.Horizontal) { - curOffset += computedSpacing; + curOffset += tabSpace; } else - curOffset += computedSpacing; + curOffset += tabSpace; } //if no layouting remains in queue for item, registre for redraw @@ -235,20 +240,16 @@ namespace Crow return base.UpdateLayout(layoutType); } -// public override void OnLayoutChanges (LayoutingType layoutType) -// { -// if (_orientation == Orientation.Horizontal) { -// if (layoutType == LayoutingType.Width) { -// computedSpacingOk = false; -// RegisterForLayouting (LayoutingType.ArrangeChildren); -// } -// } else if (layoutType == LayoutingType.Height) { -// computedSpacingOk = false; -// RegisterForLayouting (LayoutingType.ArrangeChildren); -// } -// -// base.OnLayoutChanges (layoutType); -// } + public override void OnLayoutChanges (LayoutingType layoutType) + { + if (_orientation == Orientation.Horizontal) { + if (layoutType == LayoutingType.Width) + RegisterForLayouting (LayoutingType.ArrangeChildren); + } else if (layoutType == LayoutingType.Height) + RegisterForLayouting (LayoutingType.ArrangeChildren); + + base.OnLayoutChanges (layoutType); + } protected override void onDraw (Context gr) { @@ -268,7 +269,8 @@ namespace Crow childrenRWLock.EnterReadLock (); - TabItem[] tabItms = Children.Cast<TabItem> ().OrderBy (t => t.ViewIndex).ToArray (); + TabItem[] tabItms = Children.Where(tt=>tt.Visible).Cast<TabItem> (). + OrderBy (t => t.ViewIndex).ToArray (); int selTabViewIdx = -1; if (SelectedTab < tabItms.Length && SelectedTab >= 0) @@ -293,6 +295,28 @@ namespace Crow gr.Restore (); } + protected override void onDragEnter (object sender, DragDropEventArgs e) + { + base.onDragEnter (sender, e); + + TabItem ti = e.DragSource as TabItem; + if (ti == null) + return; + if (ti.Parent != null || ti.savedParent == this) + return; + + this.AddChild (ti); + + Point p = ScreenPointToLocal (IFace.Mouse.Position) - Margin; + + p.X = Math.Max (leftSlope, p.X); + p.X = Math.Min (ClientRectangle.Width - rightSlope - tabWidth, p.X); + ti.TabOffset = p.X; + + IFace.ClearDragImage (); + + } + void Ti_TabTitle_LayoutChanged (object sender, LayoutingEventArgs e) { if (e.LayoutType == LayoutingType.X) |