diff options
Diffstat (limited to 'main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Docking/DockGroupItem.cs')
-rw-r--r-- | main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Docking/DockGroupItem.cs | 385 |
1 files changed, 385 insertions, 0 deletions
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Docking/DockGroupItem.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Docking/DockGroupItem.cs new file mode 100644 index 0000000000..89e01c2b90 --- /dev/null +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Docking/DockGroupItem.cs @@ -0,0 +1,385 @@ +// +// DockGroupItem.cs +// +// Author: +// Lluis Sanchez Gual +// + +// +// Copyright (C) 2007 Novell, Inc (http://www.novell.com) +// +// 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; +using System.Xml; +using Gtk; + +namespace MonoDevelop.Components.Docking +{ + internal class DockGroupItem: DockObject + { + DockItem item; + bool visibleFlag; + DockItemStatus status; + Gdk.Rectangle floatRect; + Gtk.PositionType barDocPosition; + int autoHideSize = -1; + + public DockItem Item { + get { + return item; + } + set { + item = value; + } + } + + public string Id { + get { return item.Id; } + } + + public DockGroupItem (DockFrame frame, DockItem item): base (frame) + { + this.item = item; + visibleFlag = item.Visible; + } + + internal override void GetDefaultSize (out int width, out int height) + { + width = item.DefaultWidth; + height = item.DefaultHeight; + } + + internal override void GetMinSize (out int width, out int height) + { + Requisition req = SizeRequest (); + width = req.Width; + height = req.Height; + } + + internal override Requisition SizeRequest () + { + return item.Widget.SizeRequest (); + } + + public override void SizeAllocate (Gdk.Rectangle newAlloc) + { + item.Widget.SizeAllocate (newAlloc); + base.SizeAllocate (newAlloc); + } + + public override bool Expand { + get { return item.Expand; } + } + + internal override void QueueResize () + { + item.Widget.QueueResize (); + } + + internal override bool GetDockTarget (DockItem item, int px, int py, out DockDelegate dockDelegate, out Gdk.Rectangle rect) + { + return GetDockTarget (item, px, py, Allocation, out dockDelegate, out rect); + } + + public bool GetDockTarget (DockItem item, int px, int py, Gdk.Rectangle rect, out DockDelegate dockDelegate, out Gdk.Rectangle outrect) + { + dockDelegate = null; + + if (item != this.item && this.item.Visible && rect.Contains (px, py)) { + int xdockMargin = (int) ((double)rect.Width * (1.0 - DockFrame.ItemDockCenterArea)) / 2; + int ydockMargin = (int) ((double)rect.Height * (1.0 - DockFrame.ItemDockCenterArea)) / 2; + DockPosition pos; + +/* if (ParentGroup.Type == DockGroupType.Tabbed) { + rect = new Gdk.Rectangle (rect.X + xdockMargin, rect.Y + ydockMargin, rect.Width - xdockMargin*2, rect.Height - ydockMargin*2); + pos = DockPosition.CenterAfter; + } +*/ if (px <= rect.X + xdockMargin && ParentGroup.Type != DockGroupType.Horizontal) { + outrect = new Gdk.Rectangle (rect.X, rect.Y, xdockMargin, rect.Height); + pos = DockPosition.Left; + } + else if (px >= rect.Right - xdockMargin && ParentGroup.Type != DockGroupType.Horizontal) { + outrect = new Gdk.Rectangle (rect.Right - xdockMargin, rect.Y, xdockMargin, rect.Height); + pos = DockPosition.Right; + } + else if (py <= rect.Y + ydockMargin && ParentGroup.Type != DockGroupType.Vertical) { + outrect = new Gdk.Rectangle (rect.X, rect.Y, rect.Width, ydockMargin); + pos = DockPosition.Top; + } + else if (py >= rect.Bottom - ydockMargin && ParentGroup.Type != DockGroupType.Vertical) { + outrect = new Gdk.Rectangle (rect.X, rect.Bottom - ydockMargin, rect.Width, ydockMargin); + pos = DockPosition.Bottom; + } + else { + outrect = new Gdk.Rectangle (rect.X + xdockMargin, rect.Y + ydockMargin, rect.Width - xdockMargin*2, rect.Height - ydockMargin*2); + pos = DockPosition.Center; + } + + dockDelegate = delegate (DockItem dit) { + DockGroupItem it = ParentGroup.AddObject (dit, pos, Id); + it.SetVisible (true); + ParentGroup.FocusItem (it); + }; + return true; + } + outrect = Gdk.Rectangle.Zero; + return false; + } + + internal override void Dump (int ind) + { + Console.WriteLine (new string (' ', ind) + item.Id + " size:" + Size + " alloc:" + Allocation); + } + + internal override void Write (XmlWriter writer) + { + base.Write (writer); + writer.WriteAttributeString ("id", item.Id); + writer.WriteAttributeString ("visible", visibleFlag.ToString ()); + writer.WriteAttributeString ("status", status.ToString ()); + + if (status == DockItemStatus.AutoHide) + writer.WriteAttributeString ("autoHidePosition", barDocPosition.ToString ()); + + if (autoHideSize != -1) + writer.WriteAttributeString ("autoHideSize", autoHideSize.ToString ()); + + if (!floatRect.Equals (Gdk.Rectangle.Zero)) { + writer.WriteAttributeString ("floatX", floatRect.X.ToString ()); + writer.WriteAttributeString ("floatY", floatRect.Y.ToString ()); + writer.WriteAttributeString ("floatWidth", floatRect.Width.ToString ()); + writer.WriteAttributeString ("floatHeight", floatRect.Height.ToString ()); + } + } + + internal override void Read (XmlReader reader) + { + base.Read (reader); + visibleFlag = bool.Parse (reader.GetAttribute ("visible")) && !item.IsPositionMarker; + status = (DockItemStatus) Enum.Parse (typeof (DockItemStatus), reader.GetAttribute ("status")); + int fx=0, fy=0, fw=0, fh=0; + string s = reader.GetAttribute ("floatX"); + if (s != null) + fx = int.Parse (s); + s = reader.GetAttribute ("floatY"); + if (s != null) + fy = int.Parse (s); + s = reader.GetAttribute ("floatWidth"); + if (s != null) + fw = int.Parse (s); + s = reader.GetAttribute ("floatHeight"); + if (s != null) + fh = int.Parse (s); + s = reader.GetAttribute ("autoHidePosition"); + if (s != null) + barDocPosition = (PositionType) Enum.Parse (typeof (PositionType), s); + s = reader.GetAttribute ("autoHideSize"); + if (s != null) + autoHideSize = int.Parse (s); + floatRect = new Gdk.Rectangle (fx, fy, fw, fh); + } + + public override void CopyFrom (DockObject ob) + { + base.CopyFrom (ob); + DockGroupItem it = (DockGroupItem)ob; + item = it.item; + visibleFlag = it.visibleFlag; + floatRect = it.floatRect; + } + + internal override bool Visible { + get { return visibleFlag && status == DockItemStatus.Dockable; } + } + + internal bool VisibleFlag { + get { return visibleFlag; } + } + + public DockItemStatus Status { + get { + return status; + } + set { + if (status == value) + return; + + DockItemStatus oldValue = status; + status = value; + + if (status == DockItemStatus.Floating) { + if (floatRect.Equals (Gdk.Rectangle.Zero)) { + int x, y; + item.Widget.TranslateCoordinates (item.Widget.Toplevel, 0, 0, out x, out y); + Gtk.Window win = Frame.Toplevel as Window; + if (win != null) { + int wx, wy; + win.GetPosition (out wx, out wy); + floatRect = new Gdk.Rectangle (wx + x, wy + y, Allocation.Width, Allocation.Height); + } + } + item.SetFloatMode (floatRect); + } + else if (status == DockItemStatus.AutoHide) { + SetBarDocPosition (); + item.SetAutoHideMode (barDocPosition, GetAutoHideSize (barDocPosition)); + } + else + item.ResetMode (); + + if (oldValue == DockItemStatus.Dockable || status == DockItemStatus.Dockable) { + // Update visibility if changing from/to dockable mode + if (ParentGroup != null) + ParentGroup.UpdateVisible (this); + } + } + } + + void SetBarDocPosition () + { + // Determine the best position for docking the item + + if (Allocation.IsEmpty) { + // If the item is in a group, use the dock location of other items + DockObject current = this; + do { + if (EstimateBarDocPosition (current.ParentGroup, current, out barDocPosition, out autoHideSize)) + return; + current = current.ParentGroup; + } while (current.ParentGroup != null); + + // Can't find a good location. Just guess. + barDocPosition = PositionType.Bottom; + autoHideSize = 200; + return; + } + barDocPosition = CalcBarDocPosition (); + } + + bool EstimateBarDocPosition (DockGroup grp, DockObject ignoreChild, out PositionType pos, out int size) + { + foreach (DockObject ob in grp.Objects) { + if (ob == ignoreChild) + continue; + if (ob is DockGroup) { + if (EstimateBarDocPosition ((DockGroup)ob, null, out pos, out size)) + return true; + } else if (ob is DockGroupItem) { + DockGroupItem it = (DockGroupItem) ob; + if (it.status == DockItemStatus.AutoHide) { + pos = it.barDocPosition; + size = it.autoHideSize; + return true; + } + if (!it.Allocation.IsEmpty) { + pos = it.CalcBarDocPosition (); + size = it.GetAutoHideSize (pos); + return true; + } + } + } + pos = PositionType.Bottom; + size = 0; + return false; + } + + PositionType CalcBarDocPosition () + { + if (Allocation.Width < Allocation.Height) { + int mid = Allocation.Left + Allocation.Width / 2; + if (mid > Frame.Allocation.Left + Frame.Allocation.Width / 2) + return PositionType.Right; + else + return PositionType.Left; + } else { + int mid = Allocation.Top + Allocation.Height / 2; + if (mid > Frame.Allocation.Top + Frame.Allocation.Height / 2) + return PositionType.Bottom; + else + return PositionType.Top; + } + } + + internal void SetVisible (bool value) + { + if (visibleFlag != value) { + visibleFlag = value; + if (visibleFlag) + item.ShowWidget (); + else + item.HideWidget (); + if (ParentGroup != null) + ParentGroup.UpdateVisible (this); + } + } + + internal override void StoreAllocation () + { + base.StoreAllocation (); + if (Status == DockItemStatus.Floating) + floatRect = item.FloatingPosition; + else if (Status == DockItemStatus.AutoHide) + autoHideSize = item.AutoHideSize; + } + + internal override void RestoreAllocation () + { + base.RestoreAllocation (); + item.UpdateVisibleStatus (); + + if (Status == DockItemStatus.Floating) + item.SetFloatMode (floatRect); + else if (Status == DockItemStatus.AutoHide) + item.SetAutoHideMode (barDocPosition, GetAutoHideSize (barDocPosition)); + else + item.ResetMode (); + + if (!visibleFlag) + item.HideWidget (); + } + + int GetAutoHideSize (Gtk.PositionType pos) + { + if (autoHideSize != -1) + return autoHideSize; + + if (pos == PositionType.Left || pos == PositionType.Right) + return Allocation.Width; + else + return Allocation.Height; + } + + public Gdk.Rectangle FloatRect { + get { + return floatRect; + } + set { + floatRect = value; + } + } + + public override string ToString () + { + return "[DockItem " + Item.Id + "]"; + } + } +} |