diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/GraphicObjects/GraphicObject.cs | 9 | ||||
| -rw-r--r-- | src/GraphicObjects/TabItem.cs | 90 | ||||
| -rw-r--r-- | src/GraphicObjects/TabView.cs | 72 | ||||
| -rw-r--r-- | src/Interface.cs | 33 |
4 files changed, 176 insertions, 28 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) diff --git a/src/Interface.cs b/src/Interface.cs index ceeb2aa8..76e7771d 100644 --- a/src/Interface.cs +++ b/src/Interface.cs @@ -217,6 +217,15 @@ namespace Crow public List<CrowThread> CrowThreads = new List<CrowThread>();//used to monitor thread finished public DragDropEventArgs DragAndDropOperation = null; + public Surface DragImage = null; + public int DragImageWidth, DragImageHeight, DragImageX, DragImageY; + public void ClearDragImage () { + lock (UpdateMutex) { + clipping.UnionRectangle(new Rectangle (DragImageX, DragImageY, DragImageWidth, DragImageHeight)); + DragImage.Dispose(); + DragImage = null; + } + } #endregion #region Private Fields @@ -625,12 +634,15 @@ namespace Crow #if MEASURE_TIME drawingMeasure.StartCycle(); #endif + if (DragImage != null) + clipping.UnionRectangle(new Rectangle (DragImageX, DragImageY, DragImageWidth, DragImageHeight)); using (surf = new ImageSurface (bmp, Format.Argb32, ClientRectangle.Width, ClientRectangle.Height, ClientRectangle.Width * 4)) { using (ctx = new Context (surf)){ if (!clipping.IsEmpty) { for (int i = 0; i < clipping.NumRectangles; i++) ctx.Rectangle(clipping.GetRectangle(i)); + ctx.ClipPreserve(); ctx.Operator = Operator.Clear; ctx.Fill(); @@ -648,6 +660,22 @@ namespace Crow ctx.Restore (); } + if (DragAndDropOperation != null) { + if (DragImage != null) { + DirtyRect += new Rectangle (DragImageX, DragImageY, DragImageWidth, DragImageHeight); + DragImageX = Mouse.X - DragImageWidth / 2; + DragImageY = Mouse.Y - DragImageHeight / 2; + ctx.Save (); + ctx.ResetClip (); + ctx.SetSourceSurface (DragImage, DragImageX, DragImageY); + ctx.PaintWithAlpha (0.8); + ctx.Restore (); + DirtyRect += new Rectangle (DragImageX, DragImageY, DragImageWidth, DragImageHeight); + IsDirty = true; + //Console.WriteLine ("dragimage drawn: {0},{1}", DragImageX, DragImageY); + } + } + #if DEBUG_CLIP_RECTANGLE clipping.stroke (ctx, Color.Red.AdjustAlpha(0.5)); #endif @@ -846,13 +874,16 @@ namespace Crow MouseMoveEventArgs e = new MouseMoveEventArgs (x, y, deltaX, deltaY); e.Mouse = Mouse; - if (ActiveWidget != null&& DragAndDropOperation == null) { + if (ActiveWidget != null && DragAndDropOperation == null) { //TODO, ensure object is still in the graphic tree //send move evt even if mouse move outside bounds ActiveWidget.onMouseMove (this, e); return true; } + if (DragAndDropOperation != null)//drag source cant have hover event, so move has to be handle here + DragAndDropOperation.DragSource.onMouseMove (this, e); + if (HoverWidget != null) { resetTooltip (); //check topmost graphicobject first |