[MonoDevelop] Dragable tabs

Iñigo Illán kodeport@terra.es
Sun, 09 May 2004 16:33:06 +0200


--=-3bHNZPdcgIo/0uwIr1YR
Content-Type: multipart/alternative; boundary="=-wj7SKTijSb0q66dXmCJM"


--=-wj7SKTijSb0q66dXmCJM
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

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.

--=-wj7SKTijSb0q66dXmCJM
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: 7bit

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 TRANSITIONAL//EN">
<HTML>
<HEAD>
  <META HTTP-EQUIV="Content-Type" CONTENT="text/html; CHARSET=UTF-8">
  <META NAME="GENERATOR" CONTENT="GtkHTML/3.1.12">
</HEAD>
<BODY>
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.
</BODY>
</HTML>

--=-wj7SKTijSb0q66dXmCJM--

--=-3bHNZPdcgIo/0uwIr1YR
Content-Disposition: attachment; filename=DragableTabsNotebook.cs
Content-Type: text/x-csharp; name=DragableTabsNotebook.cs; charset=ISO-8859-1
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.Button1MotionMask));
	}

	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 ()
	{
		
	}

	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);

		Console.WriteLine (pagenum);
		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 (tab, 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 ();
	}

	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();
	}
}


--=-3bHNZPdcgIo/0uwIr1YR--