[Gtk-sharp-list] Convenience method for creating windows
Federico Mena Quintero
federico@ximian.com
Fri, 24 Sep 2004 12:50:45 -0500
Hi,
Right now, creating a Gdk.Window for a widget is a lot of work:
class MyWidget : Widget {
protected override void OnRealized ()
{
WindowAttr attr;
int attr_mask;
base.OnRealized ();
SetFlag (WidgetFlags.Realized);
attr.WindowType = WindowType.Child;
attr.X = Allocation.X;
attr.Y = Allocation.Y;
attr.Width = Allocation.Width;
attr.Height = Allocation.Height;
attr.Wclass = WindowClass.InputOutput;
attr.Visual = Visual;
attr.Colormap = Colormap;
attr.EventMask = (Events |
EventMask.ExposureMask |
EventMask.ButtonPressMask |
EventMask.ButtonReleaseMask |
EventMask.PointerMotionMask |
EventMask.ScrollMask);
attr_mask = (WindowAttributesType.X |
WindowAttributesType.Y |
WindowAttributesType.Visual |
WindowAttributesType.Colormap);
GdkWindow = new Gdk.Window (ParentWindow, attr, attr_mask);
GdkWindow.UserData = this.Handle;
}
}
This is a lot of work, and has several flaky points:
1. Setting up the WindowAttr struct is painful, and you have to
coordinate it with the attr_mask.
2. You must remember to set the UserData of the window to
MyWidget.Handle; otherwise you won't get events from it.
Would it be good to have a convenience method for Widget:
namespace Gtk {
public class Widget : ... {
public Gdk.Window CreateSubwindow (Gdk.Window parent,
int x, int y,
int width, int height,
bool is_input_output,
int extra_event_mask)
{
WindowAttr attr;
int attr_mask;
Gdk.Window window;
if (parent == null)
throw new ArgumentNullException ("parent");
if (width < 1)
throw new ArgumentOutOfRangeException ("width", width, "must be greater than zero");
if (height < 1)
throw new ArgumentOutOfRangeException ("height", height, "must be greater than zero");
attr_mask = WindowAttributesType.X | WindowAttributesType.Y;
attr.WindowType = WindowType.Child;
attr.X = x;
attr.Y = y;
attr.Width = width;
attr.Height = height;
attr.EventMask = this.Events | extra_event_mask;
if (is_input_output) {
attr.Wclass = WindowClass.InputOutput;
attr.Visual = this.Visual;
attr.Colormap = this.Colormap;
attr_mask |= WindowAttributesType.Visual | WindowAttributesType.Colormap;
} else
attr.Wclass = WindowClass.InputOnly;
window = new Gdk.Window (parent, attr, attr_mask);
window.UserData = this.Handle;
return window;
}
}
With that, writing a realize method would be as simple as this:
class MyWidget : Widget {
protected override void OnRealized ()
{
base.OnRealized ();
SetFlag (WidgetFlags.Realized);
GdkWindow = CreateSubwindow (ParentWindow,
Allocation.X, Allocation.Y,
Allocation.Width, Allocation.Height,
true,
(EventMask.ExposureMask |
EventMask.ButtonPressMask |
EventMask.ButtonReleaseMask |
EventMask.PointerMotionMask |
EventMask.ScrollMask));
}
}
If one needs to do exotic stuff like using a different visual/colormap,
or a non-default cursor, one can create the window by hand.
What do people think? Would this be a useful addition?
Federico