aboutsummaryrefslogtreecommitdiffstatsci
path: root/src/GraphicObjects
diff options
context:
space:
mode:
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>2018-03-06 16:53:23 +0100
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>2018-03-06 16:53:23 +0100
commit8c42e8eb2016ca433cc7adea278a27800f9f0050 (patch)
tree2e39b2ac83d5ab0df28544e86490ac9e43473b17 /src/GraphicObjects
parent975df273eafe358482d892c108fbba1fdc5cac1f (diff)
tabview drag and drop of tabitem
Diffstat (limited to 'src/GraphicObjects')
-rw-r--r--src/GraphicObjects/GraphicObject.cs9
-rw-r--r--src/GraphicObjects/TabItem.cs90
-rw-r--r--src/GraphicObjects/TabView.cs72
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)