using System;
using System.Collections.Generic;
using dwf.tool;
using Gdk;
using Gtk;
namespace dwf.gui
{
[System.ComponentModel.ToolboxItem("Docker")]
public class DockBox : Container, IDockContainer
{
private DockMap map;
private CursorType _ctype = CursorType.LeftPtr;
private EventHandler childFocusHandler;
private double x, y;
private DockMapItem w;
private DockMapItem h;
private DockMapItem c;
private DockPage page = null;
//private DockPage hpage = null;
private DockMapItem pContent;
//private Panel p = new Panel();
public event EventHandler<DockPageEventArgs> PageSelected;
//private DrawingArea sizeArea = new DrawingArea ();
public DockBox()
: base()
{
DMap = new DockMap();
pContent = CreateSplit("Content", null, LayoutAlignType.None, false);
pContent.FillWidth = true;
pContent.FillHeight = true;
//pContent.Panel.Pages.ItemOrientation = Orientation.Vertical;
//pContent.Panel.PagesAlign = LayoutAlignType.Left;
//pContent.Panel.Pages.Orientation = Orientation.Vertical;
this.Events = EventMask.ButtonPressMask |
EventMask.ButtonReleaseMask |
EventMask.PointerMotionMask |
EventMask.LeaveNotifyMask;
}
public DockMapItem PContent
{
get { return this.pContent; }
}
public DockPage PickTool(Gtk.Widget control)
{
return PickTool(this, control);
}
public DockPage PickTool(IDockContainer cont, Gtk.Widget control)
{
foreach (IDockContainer idc in cont.Docks)
if (idc.ContainsControl(control))
if (idc is DockPanel)
return ((DockPanel)idc).PickTool(control);
else
return PickTool(idc, control);
return null;
}
// private void OnPageClick (object o, DockPageEventArgs e)
// {
// DockPage page = e.Page;
// if (page.Active && page.Panel != null)
// page.Panel.SelectPage (page);
// }
private void OnPageDrag(object sender, DockPageEventArgs e)
{
page = e.Page;
}
public DockPage InitItem (Widget control)
{
DockPage page = new DockPage ();
//if (control is IDockModule)
// page.HideOnClose = ((IDockModule)control).HideOnClose;
page.HideOnClose = true;
page.Label = control.Name == null || control.Name == "" ? control.GetType ().FullName : control.Name;
if (control is IPicture) {
// page.Image = ((IPicture)control).Image as Gdk.Pixbuf;
} else {
// page.Image = Resources.cog_20;
}
page.Widget = control;
return page;
}
public DockBoxHitTest DockHitTest(int x, int y)
{
return DockHitTest(x, y, 4);
}
public DockBoxHitTest DockHitTest(int x, int y, int size)
{
DockBoxHitTest htest = new DockBoxHitTest();
List<ILayoutMapItem> list = LayoutMapTool.GetVisibleItems(map);
foreach (DockMapItem item in list)
{
htest.ItemBound = map.GetBound(item, Allocation.Width, Allocation.Height);
if (htest.ItemBound.Contains(x, y))
{
htest.Item = item;
break;
}
}
System.Drawing.RectangleF rect = htest.AlignBound;
htest.Align = GuiService.GetAlignRect(htest.ItemBound, size, x, y, ref rect);
htest.AlignBound = rect;
return htest;
}
public DockMap DMap
{
get { return this.map; }
set
{
if (map == value)
return;
map = value;
QueueResize();
}
}
private void MapPageSelected(object sender, DockPageEventArgs arg)
{
if (childFocusHandler != null && arg.Page != null)
childFocusHandler(arg.Page.Widget, arg);
}
public DockPage PickPage(int x, int y, DockMapItem item)
{
foreach (DockPage page in item.Panel.Pages.Items)
{
if (page.Allocation.Contains(x, y))
{
return page;
}
}
return null;
}
protected override bool OnButtonPressEvent(EventButton evnt)
{
bool e = base.OnButtonPressEvent(evnt);
if (evnt.Button == 1)
{
int xx = (int)evnt.X;
int yy = (int)evnt.Y;
DockBoxHitTest htest = DockHitTest(xx, yy);
if (CursorType == CursorType.SbHDoubleArrow)
{
w = htest.Item;
}
else if (CursorType == CursorType.SbVDoubleArrow)
{
h = htest.Item;
}
}
return e;
}
protected override bool OnButtonReleaseEvent(EventButton evnt)
{
bool e = base.OnButtonReleaseEvent(evnt);
h = w = null;
int xx = (int)evnt.X;
int yy = (int)evnt.Y;
if (evnt.Window != this.GdkWindow)
{
if (evnt.Window.Parent == this.GdkWindow)
{
int xp = 0;
int yp = 0;
evnt.Window.GetPosition(out xp, out yp);
xx += xp;
yy += yp;
}
}
DockBoxHitTest htest = DockHitTest(xx, yy, 20);
if (page != null && page.Panel != null && htest.Item != null)
{
if (page.Panel.MapItem == htest.Item && htest.Align == LayoutAlignType.None)
{
page = null;
}
else
{
page.List.Remove(page);
if (htest.Align == LayoutAlignType.None)
htest.Item.Panel.Pages.Items.Add(page);
else
{
DockMapItem nitem = CreateSplit(htest.Item.Name + htest.Align.ToString(), htest.Item, htest.Align, true);
nitem.Panel.Pages.Items.Add(page);
}
QueueResize();
}
}
page = null;
return e;
}
private Point PageLocation = new Point();
protected override bool OnMotionNotifyEvent(EventMotion evnt)
{
bool e = base.OnMotionNotifyEvent(evnt);
//if (evnt.Window == this.GdkWindow) {
int xx = (int)evnt.X;
int yy = (int)evnt.Y;
DockBoxHitTest htest = DockHitTest(xx, yy);
if (w != null && c != null)
{
if (evnt.X != x)
{
int dx = (int)(evnt.X - x);
w.Width += dx;
c.Width -= dx;
x = evnt.X;
QueueResize();
}
}
else if (h != null && c != null)
{
if (evnt.Y != y)
{
int dy = (int)(evnt.Y - y);
h.Height += dy;
c.Height -= dy;
y = evnt.Y;
QueueResize();
}
}
else if (page == null)
{
if (htest.Item != null)
{
x = evnt.X;
y = evnt.Y;
if (htest.Align == LayoutAlignType.Right)
{
DockBoxHitTest htest2 = DockHitTest(xx + 10, yy);
c = htest2.Item;
if (c != null)
CursorType = CursorType.SbHDoubleArrow;
}
else if (htest.Align == LayoutAlignType.Bottom)
{
DockBoxHitTest htest3 = DockHitTest(xx, yy + 10);
c = htest3.Item;
if (c != null)
CursorType = CursorType.SbVDoubleArrow;
}
else
CursorType = CursorType.LeftPtr;
}
}
else if (page != null)
{
PageLocation.X = xx;
PageLocation.Y = yy;
QueueDraw();
}
//}
return e;
}
public CursorType CursorType
{
get { return _ctype; }
set
{
if (_ctype == value)
return;
_ctype = value;
GdkWindow.Cursor = GuiTool.Cursors[value];
}
}
public event EventHandler ContentFocus
{
add { childFocusHandler += value; }
remove { childFocusHandler -= value; }
}
private void ChildFocusInEvent(object o, EventArgs args)
{
if (args is DockPageEventArgs)
{
if (((DockPageEventArgs)args).Page != null)
o = ((DockPageEventArgs)args).Page.Widget;
}
//if(((Widget)o).Visible){
if (childFocusHandler != null)
childFocusHandler(o, args);
//}
}
protected override void OnSizeRequested(ref Requisition requisition)
{
List<ILayoutMapItem> list = LayoutMapTool.GetVisibleItems(map);
foreach (DockMapItem item in list)
{
//Requisition req =
item.Panel.SizeRequest();
//item.Width = req.Width;
//item.Height = req.Height;
}
//Gdk.Rectangle rect =
map.GetBound(-1, -1);
requisition.Width = 640;// rect.Width;
requisition.Height = 480;// rect.Height;
}
protected override void OnSizeAllocated(Gdk.Rectangle allocation)
{
base.OnSizeAllocated(allocation);
List<ILayoutMapItem> list = LayoutMapTool.GetVisibleItems(map);
map.GetBound(allocation.Width, allocation.Height);
foreach (DockMapItem item in list)
{
if (!item.Visible)
{
item.Panel.Visible = false;
}
Gdk.Rectangle rect =GuiTool.ToGdkRect( map.GetBound(item, allocation.Width, allocation.Height));
rect.X += 4;
rect.Y += 4;
rect.Width -= 10;
rect.Height -= 10;
if(rect.Width<1)
rect.Width = 1;
if(rect.Height<1)
rect.Height = 1;
item.Panel.Allocation = rect;
}
}
protected override void ForAll(bool include_internals, Gtk.Callback callback)
{
List<Widget> widgets = new List<Widget>();
List<ILayoutMapItem> list = LayoutMapTool.GetVisibleItems(map);
foreach (DockMapItem item in list)
widgets.Add(item.Panel);
foreach (Widget w in widgets)
callback(w);
}
protected override bool OnExposeEvent(Gdk.EventExpose evnt)
{
bool res = base.OnExposeEvent(evnt);
//GraphContext cont = new GraphContext(Gtk.DotNet.Graphics.FromDrawable(evnt.Window));
// cont.Cairo.Operator = Cairo.Operator.Over;
// List<ILayoutMapItem> list = LayoutMapTool.GetVisibleItems(map);
//
// foreach (DockMapItem item in list)
// {
// cont.Cairo.LineWidth = 6;
// cont.Cairo.LineJoin = Cairo.LineJoin.Round;
//
// cont.Cairo.SetSourceRGB(0.6, 0.6, 0.6);
// Rectangle rect = map.GetBound(item);
//
// //rect.X++;
// //rect.Y++;
// rect.Width -= 2;
// rect.Height -= 2;
//
// cont.Cairo.Rectangle(rect.X, rect.Y, rect.Width, rect.Height);
// cont.Cairo.Stroke();
//
// rect = item.Panel.Pages.Allocation;
// if (item.Panel.PagesAlign == LayoutAlignType.Left ||
// item.Panel.PagesAlign == LayoutAlignType.Right)
// rect.Height += 5;
// else
// rect.Width += 5;
//
// //cont.Cairo.SetSourceRGB (0.6, 0.6, 0.6);
// //cont.Cairo.Rectangle (rect.X, rect.Y, rect.Width, rect.Height);
//
// cont.Cairo.Fill();
// }
// if (page != null)
// {
// DockBoxHitTest htest = DockHitTest(PageLocation.X, PageLocation.Y, 20);
// //page.List.Remove (page);
// Rectangle rect = new Rectangle();
// if (htest.Align == LayoutAlignType.None)
// {
// rect.X = htest.ItemBound.X + 20;
// rect.Y = htest.ItemBound.Y + 20;
// rect.Width = htest.ItemBound.Width - 40;
// rect.Height = htest.ItemBound.Height - 40;
// }
// else
// {
// rect = htest.AlignBound;
// }
// cont.Cairo.LineWidth = 20;
// cont.Cairo.SetSourceRGBA(0.0, 1.0, 0.0, 0.5);
// cont.Cairo.Rectangle(rect.X, rect.Y, rect.Width, rect.Height);
// cont.Cairo.Stroke();
// }
//
// cont.Dispose();
return res;
}
protected override void OnRealized()
{
WidgetFlags |= WidgetFlags.Realized;
Gdk.WindowAttr attributes = new Gdk.WindowAttr();
attributes.X = Allocation.X;
attributes.Y = Allocation.Y;
attributes.Height = Allocation.Height;
attributes.Width = Allocation.Width;
attributes.WindowType = Gdk.WindowType.Child;
attributes.Wclass = Gdk.WindowClass.InputOutput;
attributes.Visual = Visual;
attributes.Colormap = Colormap;
attributes.EventMask = (int)(Events |
Gdk.EventMask.ExposureMask |
Gdk.EventMask.Button1MotionMask |
Gdk.EventMask.ButtonPressMask |
Gdk.EventMask.ButtonReleaseMask);
Gdk.WindowAttributesType attributes_mask =
Gdk.WindowAttributesType.X |
Gdk.WindowAttributesType.Y |
Gdk.WindowAttributesType.Colormap |
Gdk.WindowAttributesType.Visual;
GdkWindow = new Gdk.Window(ParentWindow, attributes, (int)attributes_mask);
GdkWindow.UserData = Handle;
GdkWindow.Background = new Color(100, 100, 100);
Style = Style.Attach(GdkWindow);
Style.SetBackground(GdkWindow, State);
this.WidgetFlags &= ~WidgetFlags.NoWindow;
//GdkWindow.SetBackPixmap (null, true);
}
protected override void OnUnrealized()
{
if (this.GdkWindow != null)
{
this.GdkWindow.UserData = IntPtr.Zero;
this.GdkWindow.Destroy();
this.WidgetFlags |= WidgetFlags.NoWindow;
}
base.OnUnrealized();
}
void PanelTabSelected(object sender, DockPageEventArgs e)
{
ChildFocusInEvent(sender, e);
if (PageSelected != null)
PageSelected(this, e);
}
public DockMapItem CreateSplit(string Name, DockMapItem exitem, LayoutAlignType type, bool gp)
{
DockMapItem item = new DockMapItem();
item.Name = Name;
item.Visible = true;
item.Panel = new DockPanel();
item.Panel.PageSelected += PanelTabSelected;
item.Panel.Pages.PageDrag += OnPageDrag;
if (exitem == null)
{
LayoutMapTool.Add(map, item);
}
else
{
LayoutMapTool.InsertWith(item, exitem, type, gp);
}
item.Panel.Parent = this;
return item;
}
#region Container
public bool ContainsControl(object c)
{
List<ILayoutMapItem> list = LayoutMapTool.GetItems(map);
foreach (DockMapItem item in list)
if (item.Panel.ContainsControl(c))
return true;
return false;
}
public bool Delete(object c)
{
List<ILayoutMapItem> list = LayoutMapTool.GetItems(map);
foreach (DockMapItem item in list)
{
if (item.Panel.ContainsControl(c))
{
item.Panel.Delete(c);
return true;
}
}
return false;
}
public List<object> GetControls()
{
List<object> items = new List<object>();
List<ILayoutMapItem> list = LayoutMapTool.GetItems(map);
foreach (DockMapItem item in list)
items.AddRange(item.Panel.GetControls());
return items;
}
public object Find(string name)
{
List<object> list = GetControls();
foreach (Widget w in list)
if (w.Name == name)
return w;
return null;
}
public IDockContainer DockParent
{
get
{
return null;
}
}
public List<IDockContainer> Docks
{
get
{
List<IDockContainer> items = new List<IDockContainer>();
List<ILayoutMapItem> list = LayoutMapTool.GetVisibleItems(map);
foreach (DockMapItem item in list)
items.Add(item.Panel);
return items;
}
}
public void Put(object c)
{
if (c is IDockContent)
Put(c, ((IDockContent)c).DockType);
else
Put(c, DockType.Content);
}
public void Put(object cc, DockType type)
{
Widget c = (Widget)cc;
if (ContainsControl(c))
{
DockPage page = PickTool(c);
if (page != null)
page.Panel.SelectPage(page);
return;
}
else
{
//c.AddEvents ((int)Gdk.EventMask.VisibilityNotifyMask);
//c.VisibilityNotifyEvent += ChildFocusInEvent;
DockMapItem item = null;
if (type == DockType.Content)
{
item = pContent;
}
else if (type == DockType.Left)
{
item = LayoutMapTool.Get(map, "Left") as DockMapItem;
if (item == null)
{
item = CreateSplit("Left", pContent, LayoutAlignType.Left, false);
}
}
else if (type == DockType.Right)
{
item = LayoutMapTool.Get(map, "Right") as DockMapItem;
if (item == null)
{
item = CreateSplit("Right", pContent, LayoutAlignType.Right, false);
}
}
else if (type == DockType.Top)
{
item = LayoutMapTool.Get(map, "Top") as DockMapItem;
if (item == null)
{
item = CreateSplit("Top", pContent, LayoutAlignType.Top, false);
}
}
else if (type == DockType.Bottom)
{
item = LayoutMapTool.Get(map, "Bottom") as DockMapItem;
if (item == null)
{
item = CreateSplit("Bottom", pContent, LayoutAlignType.Bottom, false);
}
}
item.Visible = true;
item.Panel.Put(cc);
}
SizeRequest();
}
#endregion
}
}