Click here to Skip to main content
15,896,154 members
Articles / Desktop Programming / Windows Forms

Controls Library: Extended ListView with Column Mapping

Rate me:
Please Sign up or sign in to vote.
4.86/5 (29 votes)
27 Mar 2014CPOL5 min read 83.2K   7.6K   110  
Docking windows container, extended listview, extended property editor.
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
    }



}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Kazakstan Kazakstan
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions