using System;
namespace FloatDraggingTest
{
///
/// Main window.
///
class MainWindow : Gtk.Window
{
///
/// Application entry point.
///
public static void Main(string[] args)
{
Gtk.Application.Init();
MainWindow win = new MainWindow();
win.ShowAll();
Gtk.Application.Run();
}
///
/// Main window default constructor.
///
public MainWindow()
: base(Gtk.WindowType.Toplevel)
{
floatWidget = new FloatWidget("Click Me");
Add(floatWidget);
DeleteEvent += OnDeleteEvent;
}
///
/// Called when the window is deleted, stops the application.
///
///
///
void OnDeleteEvent(object o, Gtk.DeleteEventArgs args)
{
Gtk.Application.Quit();
}
private FloatWidget floatWidget;
}
///
/// A widget that you can grab and drag around.
///
class FloatWidget : Gtk.Button
{
///
/// Default constructor.
///
/// Text to display on the widget.
public FloatWidget(string text)
: base(new Gtk.Label(text))
{
// create the float window
floatWindow = new Gtk.Window(Gtk.WindowType.Toplevel);
floatWindow.Decorated = false;
AddEvents((int)Gdk.EventMask.AllEventsMask); // add all events
}
private Gtk.Window floatWindow;
private bool grabbed = false;
private Gdk.Point grabPoint;
protected override bool OnButtonPressEvent(Gdk.EventButton evnt)
{
grabbed = true;
int grabX, grabY;
GetPointer(out grabX, out grabY);
grabPoint = new Gdk.Point(grabX, grabY);
return true;
}
protected override bool OnButtonReleaseEvent(Gdk.EventButton evnt)
{
grabbed = false;
return true;
}
protected override bool OnMotionNotifyEvent(Gdk.EventMotion evnt)
{
if (grabbed) // the window has been grabbed
{
if (Parent != floatWindow) // it isn't floating yet, float it
{
Reparent(floatWindow);
floatWindow.ShowAll();
}
MoveToCursor();
}
return true;
}
protected override bool OnLeaveNotifyEvent(Gdk.EventCrossing evnt)
{
if (grabbed)
MoveToCursor();
return true;
}
///
/// Moves the floating window to the cursor.
///
protected void MoveToCursor()
{
int cursorX, cursorY, windowX, windowY;
GetPointer(out cursorX, out cursorY);
GdkWindow.GetPosition(out windowX, out windowY);
floatWindow.GdkWindow.Move(windowX + cursorX - grabPoint.X, windowY + cursorY - grabPoint.Y);
Display.Sync();
}
}
}