[MonoDevelop] Dragable tabs

Todd Berman tberman@sevenl.net
Sun, 09 May 2004 17:34:45 -0400


--=-yUMsa7ftPnn12b+fP5AJ
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit

I have got it working, it uses the dirty ConnectBefore stuff, but thatis
easily ported to the override stuff.

This works on gtk-sharp from cvs, let me know if it works on 0.91.1.

I am going to integrate this with MD and getit in. Thanks a lot :)

--Todd

On Sun, 2004-09-05 at 16:33 +0200, Iñigo Illán wrote:
> I have been trying to port the code that implements dragable tabs from
> gossip (which is written in C) to C#. The code looks good but for some
> reason I can't make it work. It seems MotionNotify event it's never
> launched. Maybe it could be some bug on gtk#? Anyway I let you the
> code so anyone maybe can find the problem.

--=-yUMsa7ftPnn12b+fP5AJ
Content-Disposition: attachment; filename=DragableTabsNotebook.cs
Content-Type: text/x-csharp; name=DragableTabsNotebook.cs; charset=utf-8
Content-Transfer-Encoding: 7bit

// created on 03/19/2004 at 20:45

using System;
using Gtk;
using GtkSharp;
using Gdk;

public class prueba
{
	public static void Main()
	{
		Application.Init ();
		new Interfaz ();
		Application.Run ();
	}
}

class DragableTabsNotebook : Notebook
{
	protected bool draginprogress = false;
    protected int srcpage;
	protected double xstart;
	protected double ystart;
	protected Cursor cursor;

	public DragableTabsNotebook ()
	{
		this.ButtonPressEvent += new ButtonPressEventHandler (ButtonPressCallback);
		this.ButtonReleaseEvent += new ButtonReleaseEventHandler (ButtonReleaseCallback);
		this.AddEvents ((Int32) (EventMask.AllEventsMask));
	}

	protected int FindTabAtNumPos (double absx, double absy)
	{
		PositionType tabpos;
		int pagenum = 0, xroot, yroot, maxx, maxy;
		Widget page, tab;

		tabpos = this.TabPos;
		if (this.NPages == 0)
		{
			return -1;
		}
		
		page = this.GetNthPage (pagenum);
		
		while (page != null)
		{
			tab = this.GetTabLabel (page);
			
			if (tab == null)
			{
				return -1;
			}
			
			// if (!tab.Mapped)
			// {
			//	pagenum++;
			//	continue;
			// }
			
			tab.ParentWindow.GetOrigin (out xroot, out yroot);
			
			maxx = xroot + tab.Allocation.X + tab.Allocation.Width;
			maxy = yroot + tab.Allocation.Y + tab.Allocation.Height;
			
			if ((tabpos == PositionType.Top || tabpos == PositionType.Bottom) && absx <= maxx)
			{
				return pagenum;
			}
			else if ((tabpos == PositionType.Right || tabpos == PositionType.Left) && absx <= maxy)
			{
				return pagenum;
			}
			
			pagenum++;
			page = this.GetNthPage (pagenum);
		}
		
		return -1;
	}

	protected void OnTabsReordered ()
	{
		
	}

	[GLib.ConnectBefore]
	protected void MotionNotifyCallback (object obj, MotionNotifyEventArgs args)
	{
		int curpage, pagenum;

		if (!draginprogress)
		{
			//if (Gtk.Drag.CheckThreshold (this, (Int32) xstart, (Int32) ystart, (Int32) args.Event.XRoot, (Int32) args.Event.YRoot))
			//{
				curpage = this.CurrentPage;
				DragStart (curpage, args.Event.Time);
			//}
			//else
			//{
			//	return;
			//}
		}
		
		pagenum = FindTabAtNumPos (args.Event.XRoot, args.Event.YRoot);

		MoveTab (pagenum);
	}
	
	protected void MoveTab (int destpagenum)
	{
		int curpagenum;
		Widget curpage, tab;
		
		curpagenum = this.CurrentPage;
	
		if (destpagenum != curpagenum)
		{
			curpage = this.GetNthPage (curpagenum);
			tab = this.GetTabLabel (curpage);
			this.ReorderChild (CurrentPageWidget, destpagenum);
		}
	}

	protected void DragStart (int srcpage, uint time)
	{
		draginprogress = true;
		
		this.srcpage = srcpage;
		
		if (cursor == null)
		{
			cursor = new Cursor (CursorType.Fleur);
		}

		Grab.Add (this);
		
		if (!Pointer.IsGrabbed)
		{
			Pointer.Grab (this.ParentWindow, false, EventMask.Button1MotionMask | EventMask.ButtonReleaseMask, null, cursor, time);						
		}
	}

	protected void DragStop ()
	{
		if (draginprogress)
		{
			OnTabsReordered();
		}
		
		draginprogress = false;
		srcpage = -1;
		this.MotionNotifyEvent -= new MotionNotifyEventHandler (MotionNotifyCallback);
	}
	
	protected void ButtonReleaseCallback (object obj, ButtonReleaseEventArgs args)
	{
		if (Pointer.IsGrabbed)
		{
			Pointer.Ungrab (args.Event.Time);
			Gtk.Grab.Remove (this);
		}
		
		DragStop ();
	}

	[GLib.ConnectBefore]
	protected void ButtonPressCallback (object obj, ButtonPressEventArgs args)
	{
		int tabpos;
		
		tabpos = FindTabAtNumPos (args.Event.XRoot, args.Event.YRoot);

		if (draginprogress)
		{
			return;
		}
		else
		{
			srcpage = this.CurrentPage;
		}

		xstart = args.Event.XRoot;
		ystart = args.Event.YRoot;

		if (args.Event.Button == 1 && args.Event.Type == EventType.ButtonPress && tabpos >= 0)
		{
			this.MotionNotifyEvent += new MotionNotifyEventHandler (MotionNotifyCallback);
		}
	}
}

class Interfaz
{
	Gtk.Window window;
	DragableTabsNotebook notebook;

	protected void quit (object obj, DeleteEventArgs args)
	{
		Application.Quit ();
	}

	public Interfaz ()
	{
		window = new Gtk.Window("Example");
		window.DeleteEvent += new DeleteEventHandler (quit);
		notebook = new DragableTabsNotebook ();

		notebook.AppendPage (new Gtk.TextView(), new Label("Example1"));
		notebook.AppendPage (new Gtk.TextView(), new Label("Example2"));
		notebook.AppendPage (new Gtk.TextView(), new Label("Example3"));
		notebook.AppendPage (new Gtk.TextView(), new Label("Example4"));
		notebook.AppendPage (new Gtk.TextView(), new Label("Example5"));
		
		window.Add(notebook);
		window.ShowAll();
	}
}


--=-yUMsa7ftPnn12b+fP5AJ--