Reworked the event system. Added partial Button and Label classes. Notes added asking many important questions.

svn path=/trunk/gtk-sharp/; revision=858
This commit is contained in:
Bob Smith 2001-09-18 03:57:16 +00:00
parent 141acf001c
commit c2d90eb282
6 changed files with 405 additions and 31 deletions

30
NOTES Normal file
View File

@ -0,0 +1,30 @@
Mike,
We have some problems. Some methods are going to return a gtk widget which
will need to be wrapped again into a c# class. This will have a nasty
reaction when callbacks are added to the wrapper, then the wrapper is nuked
when complete. It will leave a rogue pointer of some kind laying around, and
callbacks won't work as expected.
Proposed solution:
Every GTK# class is a wrapper class. With a constructor for a GtkWidget* and
one for a default _new. Events are done as in CVS, except that the events
object will need to be bound to the GtkWidget owning it, and when a wrapper
is created, that Events object is resurected. This way, even if there is no
wrapper in existance, signals will function properly, and multiple wrappers
will work properly too. The event object will register a delete signal with
the widget so that when its nuked, it has a chance to free itself. Are we
going to have to tell the garbage collector to stay away from this class?
We might need our own class for this, and this class might not be able to be
written in c#.
Problem number two is with taking an arbitrary GtkWidget, and constructing a
wrapper as needed. Which wrapper is created? A simple GtkWidget wouldnt work
too well if the GtkWidget is really a button. We need to deside how to
handle this. Should we just return a GtkWidget, and force the developer to
pass the GtkWidget back to a constructor for the desided apon Widget wrapper?
How does gtk itself deal with this? Are we going to need a database of
widget wrappers for this?
Bob

70
gtk/Button.cs Normal file
View File

@ -0,0 +1,70 @@
// GTK.Button.cs - GTK Button class implementation
//
// Author: Bob Smith <bob@thestuff.net>
//
// (c) 2001 Bob Smith
namespace GTK {
using System;
using System.Runtime.InteropServices;
public class Button : Widget {
private static readonly object ClickedEvent = new object ();
public event EventHandler Clicked
{
add
{
if (Events[ClickedEvent] == null)
{
ConnectSignal ("clicked", new SimpleCallback (EmitDeleteEvent));
}
Events.AddHandler (ClickedEvent, value);
}
remove
{
Events.RemoveHandler (ClickedEvent, value);
}
}
private void EmitClickedEvent (IntPtr obj)
{
EventHandler eh = (EventHandler)(_events[ClickedEvent]);
if (eh != null)
{
EventArgs args = new EventArgs ();
eh(this, args);
}
}
/// <summary>
/// Button Object Constructor
/// </summary>
///
/// <remarks>
/// Constructs a Button Wrapper.
/// </remarks>
public Button (IntPtr o)
{
Object = o;
}
/// <summary>
/// Button Constructor
/// </summary>
///
/// <remarks>
/// Constructs a new Button with the specified content.
/// </remarks>
[DllImport("gtk-1.3")]
static extern IntPtr gtk_label_new_with_label (String str);
public Button (String str)
{
Object = gtk_button_new_with_label (str);
}
}
}

240
gtk/Label.cs Normal file
View File

@ -0,0 +1,240 @@
// GTK.Label.cs - GTK Label class implementation
//
// Author: Bob Smith <bob@thestuff.net>
//
// (c) 2001 Bob Smith
namespace GTK {
using System;
using System.Runtime.InteropServices;
public class Label : Widget {
/// <summary>
/// Label Object Constructor
/// </summary>
///
/// <remarks>
/// Constructs a Label Wrapper.
/// </remarks>
public Label (IntPtr o)
{
Object = o;
}
/// <summary>
/// Label Constructor
/// </summary>
///
/// <remarks>
/// Constructs a new Label with the specified content.
/// </remarks>
[DllImport("gtk-1.3")]
static extern IntPtr gtk_label_new (String str);
public Label (String str)
{
Object = gtk_label_new (str);
}
/// <summary>
/// Text Property
/// </summary>
///
/// <remarks>
/// The raw text of the label.
/// </remarks>
[DllImport("gtk-1.3")]
static extern void gtk_label_set_text (IntPtr hnd, const String str);
[DllImport("gtk-1.3")]
static extern String gtk_label_get_text (IntPtr hnd);
public String Text {
get
{
return gtk_label_get_text (Object);
}
set
{
gtk_label_set_text (Object, value);
}
}
/// <summary>
/// Markup Property
/// </summary>
///
/// <remarks>
/// Text to parse.
/// </remarks>
[DllImport("gtk-1.3")]
static extern void gtk_label_set_markup (IntPtr hnd, const String str);
public String Markup {
set
{
gtk_label_set_markup (Object, value);
}
}
/// <summary>
/// Label Property
/// </summary>
///
/// <remarks>
/// Parsed content.
/// </remarks>
[DllImport("gtk-1.3")]
static extern void gtk_label_set_label (IntPtr hnd, const String str);
[DllImport("gtk-1.3")]
static extern String gtk_label_get_label (IntPtr hnd);
public String Label {
get
{
return gtk_label_get_label (Object);
}
set
{
gtk_label_set_label (Object, value);
}
}
/// <summary>
/// Selectable Property
/// </summary>
///
/// <remarks>
/// Is the user able to select text from the label.
/// </remarks>
[DllImport("gtk-1.3")]
static extern void gtk_label_set_selectable (IntPtr hnd, bool setting);
[DllImport("gtk-1.3")]
static extern bool gtk_label_get_selectable (IntPtr hnd);
public bool Selectable {
get
{
return gtk_label_get_selectable (Object);
}
set
{
gtk_label_set_selectable (Object, value, value);
}
}
/// <summary>
/// UseUnderline Property
/// </summary>
///
/// <remarks>
/// Indicates that the next character after an underline should be the accelerator key.
/// </remarks>
[DllImport("gtk-1.3")]
static extern void gtk_label_set_use_underline (IntPtr hnd, bool setting);
[DllImport("gtk-1.3")]
static extern bool gtk_label_get_use_underline (IntPtr hnd);
public bool UseUnderline {
get
{
return gtk_label_get_use_underline (Object);
}
set
{
gtk_label_set_use_underline (Object, value, value);
}
}
/// <summary>
/// UseMarkup Property
/// </summary>
///
/// <remarks>
/// Indicates that the text contains markup.
/// </remarks>
[DllImport("gtk-1.3")]
static extern void gtk_label_set_use_markup (IntPtr hnd, bool setting);
[DllImport("gtk-1.3")]
static extern bool gtk_label_get_use_markup (IntPtr hnd);
public bool UseMarkup {
get
{
return gtk_label_get_use_markup (Object);
}
set
{
gtk_label_set_use_markup (Object, value, value);
}
}
/// <summary>
/// LineWrap Property
/// </summary>
///
/// <remarks>
/// Indicates that the text is automatically wrapped if to long.
/// </remarks>
[DllImport("gtk-1.3")]
static extern void gtk_label_set_line_wrap (IntPtr hnd, bool setting);
[DllImport("gtk-1.3")]
static extern bool gtk_label_get_line_wrap (IntPtr hnd);
public bool LineWrap {
get
{
return gtk_label_get_line_wrap (Object);
}
set
{
gtk_label_set_line_wrap (Object, value, value);
}
}
/*
TODO:
void gtk_label_set_attributes(GtkLabel *label, PangoAttrList *attrs);
void gtk_label_set_markup_with_mnemonic(GtkLabel *label, const gchar *str);
void gtk_label_set_pattern(GtkLabel *label, const gchar *pattern);
void gtk_label_set_justify(GtkLabel *label, GtkJustification jtype);
guint gtk_label_parse_uline(GtkLabel *label, const gchar *string);
void gtk_label_get_layout_offsets (GtkLabel *label,
gint *x,
gint *y);
guint gtk_label_get_mnemonic_keyval (GtkLabel *label);
GtkWidget* gtk_label_new_with_mnemonic (const char *str);
void gtk_label_select_region (GtkLabel *label,
gint start_offset,
gint end_offset);
void gtk_label_set_mnemonic_widget (GtkLabel *label,
GtkWidget *widget);
void gtk_label_set_text_with_mnemonic
(GtkLabel *label,
const gchar *str);
PangoAttrList* gtk_label_get_attributes (GtkLabel *label);
GtkJustification gtk_label_get_justify (GtkLabel *label);
PangoLayout* gtk_label_get_layout (GtkLabel *label);
GtkWidget* gtk_label_get_mnemonic_widget (GtkLabel *label);
gboolean gtk_label_get_selection_bounds (GtkLabel *label,
gint *start,
gint *end);
*/
}
}

View File

@ -11,8 +11,30 @@ namespace GTK {
using System.Runtime.InteropServices;
public abstract class Object {
private EventHandlerList _events;
protected EventHandlerList Events
{
get
{
if (_events != null) return _events;
_events = new EventHandlerList ();
}
}
protected IntPtr obj;
private IntPtr _obj;
IntPtr Object
{
get
{
return _obj;
}
set
{
_events = null;
_obj = value;
}
}
protected delegate void SimpleCallback (IntPtr obj);

View File

@ -11,32 +11,6 @@ namespace GTK {
public abstract class Widget : Object {
/// <summary>
/// ConnectEvents method
/// </summary>
///
/// <remarks>
/// Connects event handlers to the wrapped GTK widget.
/// It is not possible to perform this connection in a
/// constructor, since the leaf class constructor in which
/// the wrapped object is created is not executed until
/// after the base class' constructor.
/// </remarks>
protected void PrepareEvents ()
{
ConnectSignal ("delete-event",
new SimpleCallback (EmitDeleteEvent));
}
private void EmitDeleteEvent (IntPtr obj)
{
if (Delete != null) {
EventArgs args = new EventArgs ();
Delete (this, args);
}
}
/// <summary>
/// Delete Event
/// </summary>
@ -46,7 +20,33 @@ namespace GTK {
/// manager.
/// </remarks>
public event EventHandler Delete;
private static readonly object DeleteEvent = new object ();
public event EventHandler Delete
{
add
{
if (Events[DeleteEvent] == null)
{
ConnectSignal ("delete-event", new SimpleCallback (EmitDeleteEvent));
}
Events.AddHandler (DeleteEvent, value);
}
remove
{
Events.RemoveHandler (DeleteEvent, value);
}
}
private void EmitDeleteEvent (IntPtr obj)
{
EventHandler eh = (EventHandler)(_events[DeleteEvent]);
if (eh != null)
{
EventArgs args = new EventArgs ();
eh(this, args);
}
}
/// <summary>
/// Show Method

View File

@ -17,6 +17,19 @@ namespace GTK {
public class Window : Widget {
/// <summary>
/// Window Object Constructor
/// </summary>
///
/// <remarks>
/// Constructs a Window Wrapper.
/// </remarks>
public Window (IntPtr o)
{
Object = o;
}
/// <summary>
/// Window Constructor
/// </summary>
@ -30,8 +43,7 @@ namespace GTK {
public Window ()
{
obj = gtk_window_new (WindowType.TopLevel);
base.PrepareEvents ();
Object = gtk_window_new (WindowType.TopLevel);
}
/// <summary>
@ -155,7 +167,7 @@ namespace GTK {
public String Title {
set
{
gtk_window_set_title (obj, value);
gtk_window_set_title (Object, value);
}
}
}