#
# This file is part of gtkD.
#
# gtkD is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
#
# gtkD is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with gtkD; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#

#############################################
### Definitions for wrapping Gtk+ ###########
#############################################

# must start with wrap
wrap: gtk
file: Gtk-3.0.gir

addAliases: start
	public import gtkc.cairotypes;
	public import gtkc.glibtypes;
	public import gtkc.gobjecttypes;
	public import gtkc.giotypes;
	public import gtkc.pangotypes;
	public import gtkc.atktypes;
	public import gtkc.gdkpixbuftypes;
	public import gtkc.gdktypes;

	extern(C) Object _d_newclass(ClassInfo ci);

	alias GtkAllocation* Allocation;
addAliases: end

addConstants: start
	/**
	 * A priority that can be used when adding a gtk.StyleProvider
	 * for application-specific style information.
	 */
	public enum STYLE_PROVIDER_PRIORITY_APPLICATION = 600;
	alias STYLE_PROVIDER_PRIORITY_APPLICATION GTK_STYLE_PROVIDER_PRIORITY_APPLICATION;

	/**
	 * The priority used for default style information
	 * that is used in the absence of themes.
	 *
	 * Note that this is not very useful for providing default
	 * styling for custom style classes - themes are likely to
	 * override styling provided at this priority with
	 * catch-all `* {...}` rules.
	 */
	public enum STYLE_PROVIDER_PRIORITY_FALLBACK = 1;
	alias STYLE_PROVIDER_PRIORITY_FALLBACK GTK_STYLE_PROVIDER_PRIORITY_FALLBACK;

	/**
	 * The priority used for style information provided
	 * via gtk.Settings.
	 *
	 * This priority is higher than STYLE_PROVIDER_PRIORITY_THEME
	 * to let settings override themes.
	 */
	public enum STYLE_PROVIDER_PRIORITY_SETTINGS = 400;
	alias STYLE_PROVIDER_PRIORITY_SETTINGS GTK_STYLE_PROVIDER_PRIORITY_SETTINGS;

	/**
	 * The priority used for style information provided
	 * by themes.
	 */
	public enum STYLE_PROVIDER_PRIORITY_THEME = 200;
	alias STYLE_PROVIDER_PRIORITY_THEME GTK_STYLE_PROVIDER_PRIORITY_THEME;

	/**
	 * The priority used for the style information from
	 * `~/.gtk-3.0.css`.
	 *
	 * You should not use priorities higher than this, to
	 * give the user the last word.
	 */
	public enum STYLE_PROVIDER_PRIORITY_USER = 800;
	alias STYLE_PROVIDER_PRIORITY_USER GTK_STYLE_PROVIDER_PRIORITY_USER;
addConstants: end

struct: Action
import: gtk.Image
import: gtk.Menu
import: gtk.MenuItem
import: gtk.ToolItem
noCode: get_stock_id
noCode: create_icon
noCode: create_menu_item
noCode: create_tool_item
noCode: create_menu
code: start
	/**
	 * Creates a new GtkAction object. To add the action to a
	 * GtkActionGroup and set the accelerator for the action,
	 * call gtk_action_group_add_action_with_accel().
	 * See the section called UI Definitions for information on allowed action
	 * names.
	 * Since 2.4
	 * Params:
	 * name =  A unique name for the action
	 * label =  the label displayed in menu items and on buttons, or NULL
	 * tooltip =  a tooltip for the action, or NULL
	 * stockId =  the stock icon to display in widgets representing the
	 *  action.
	 * Throws: ConstructionException GTK+ fails to create the object.
	 */
	public this (string name, string label, string tooltip, StockID stockId)
	{
		this(name, label, tooltip, cast(string)stockId);
	}

	/**
	 * Gets the stock id of action.
	 * Since 2.16
	 * Returns: the stock id
	 */
	public StockID getStockId()
	{
		return cast(StockID)Str.toString(gtk_action_get_stock_id(gtkAction));
	}

	/**
	 * Sets the stock id on action
	 * Since 2.16
	 * Params:
	 * stockId =  the stock id
	 */
	public void setStockId(StockID stockId)
	{
		setStockId(stockId);
	}

	/**
	 * This function is intended for use by action implementations to
	 * create icons displayed in the proxy widgets.
	 * Since 2.4
	 * Params:
	 * iconSize = the size of the icon that should be created. [type int]
	 * Returns: a widget that displays the icon for this action.
	 */
	public Image createIcon(GtkIconSize iconSize)
	{
		// GtkWidget * gtk_action_create_icon (GtkAction *action,  GtkIconSize icon_size);
		auto p = gtk_action_create_icon(gtkAction, iconSize);
		if(p is null)
		{
			return null;
		}
		return new Image(cast(GtkImage*) p);
	}

	/**
	 * Creates a menu item widget that proxies for the given action.
	 * Since 2.4
	 * Returns: a menu item connected to the action.
	 */
	public MenuItem createMenuItem()
	{
		// GtkWidget * gtk_action_create_menu_item (GtkAction *action);
		auto p = gtk_action_create_menu_item(gtkAction);
		if(p is null)
		{
			return null;
		}
		return new MenuItem(cast(GtkMenuItem*) p);
	}

	/**
	 * Creates a toolbar item widget that proxies for the given action.
	 * Since 2.4
	 * Returns: a toolbar item connected to the action.
	 */
	public ToolItem createToolItem()
	{
		// GtkWidget * gtk_action_create_tool_item (GtkAction *action);
		auto p = gtk_action_create_tool_item(gtkAction);
		if(p is null)
		{
			return null;
		}
		return new ToolItem(cast(GtkToolItem*) p);
	}

	/**
	 * If action provides a GtkMenu widget as a submenu for the menu
	 * item or the toolbar item it creates, this function returns an
	 * instance of that menu.
	 * Since 2.12
	 * Returns: the menu item provided by the action, or NULL.
	 */
	public Menu createMenu()
	{
		// GtkWidget * gtk_action_create_menu (GtkAction *action);
		auto p = gtk_action_create_menu(gtkAction);
		if(p is null)
		{
			return null;
		}
		return new Menu(cast(GtkMenu*) p);
	}
code: end

struct: Alignment
code: start
	/** */
	public static Alignment center(Widget widget)
	{
		Alignment a = new Alignment(0.5, 0.5, 0, 0);
		a.add(widget);
		return a;
	}

	/** */
	public static Alignment north(Widget widget)
	{
		Alignment a = new Alignment(0.5, 0.0, 0, 0);
		a.add(widget);
		return a;
	}

	/** */
	public static Alignment south(Widget widget)
	{
		Alignment a = new Alignment(0.5, 1.0, 0, 0);
		a.add(widget);
		return a;
	}

	/** */
	public static Alignment east(Widget widget)
	{
		Alignment a = new Alignment(1.0, 0.5, 0, 0);
		a.add(widget);
		return a;
	}

	/** */
	public static Alignment west(Widget widget)
	{
		Alignment a = new Alignment(0.0, 0.5, 0, 0);
		a.add(widget);
		return a;
	}

	/** */
	public static Alignment northWest(Widget widget)
	{
		Alignment a = new Alignment(0.0, 0.0, 0, 0);
		a.add(widget);
		return a;
	}

	/** */
	public static Alignment southWest(Widget widget)
	{
		Alignment a = new Alignment(0.0, 0.5, 0, 0);
		a.add(widget);
		return a;
	}

	/** */
	public static Alignment northEast(Widget widget)
	{
		Alignment a = new Alignment(1.0, 0.0, 0, 0);
		a.add(widget);
		return a;
	}

	/** */
	public static Alignment southEast(Widget widget)
	{
		Alignment a = new Alignment(1.0, 1.0, 0, 0);
		a.add(widget);
		return a;
	}
code: end

struct: Application
noCode: set_accels_for_action
code: start
	/**
	 * Sets zero or more keyboard accelerators that will trigger the
	 * given action. The first item in accels will be the primary
	 * accelerator, which may be displayed in the UI.
	 *
	 * To remove all accelerators for an action, use an empty
	 * array for accels.
	 *
	 * Params:
	 *     detailedActionName = a detailed action name, specifying an action
	 *         and target to associate accelerators with
	 *     accels = a list of accelerators in the format
	 *         understood by gtk_accelerator_parse()
	 *
	 * Since: 3.12
	 */
	public void setAccelsForAction(string detailedActionName, string[] accels)
	{
		char** accel;
		
		if (accels)
			accel = Str.toStringzArray(accels);
		else
			accel = [cast(char*)null].ptr;
		
		gtk_application_set_accels_for_action(gtkApplication, Str.toStringz(detailedActionName), accel);
	}
code: end

struct: Buildable
alias: set_name buildableSetName
alias: get_name buildableGetName

struct: Builder
noCode: new
noCode: get_object
noCode: get_objects

#There are now 3 constructors that have a single string parameter, disable 2 of them.
noCode: new_from_resource
noCode: new_from_string

array: add_from_string buffer length

import: gtkc.glib
import: std.string

#imports for gtk_builder_real_get_type_from_name_override
import: gtkc.gobject
import: gtkd.paths
import: glib.Module
import: gobject.Type

code: start
	/**
	 * Creates a new builder object.
	 * Since 2.12
	 * Throws: ConstructionException GTK+ fails to create the object.
	 */
	public this ()
	{
		// GtkBuilder* gtk_builder_new (void);
		auto p = gtk_builder_new();
		if(p is null)
		{
			throw new ConstructionException("null returned by gtk_builder_new()");
		}
		this(cast(GtkBuilder*) p);

		GtkBuilderClass* klass = Type.getInstanceClass!(GtkBuilderClass)( this );
		klass.getTypeFromName = &gtk_builder_real_get_type_from_name_override;
	}

	/**
	 * This function is a modification of _gtk_builder_resolve_type_lazily from "gtk/gtkbuilder.c".
	 * It is needed because it assumes we are linking at compile time to the gtk libs.
	 * specifically the NULL in g_module_open( NULL, 0 );
	 * It replaces the default function pointer "get_type_from_name" in GtkBuilderClass.
	 */
	extern(C) private static GType gtk_builder_real_get_type_from_name_override ( GtkBuilder* builder, const(char)* name )
	{
		GType gtype;
		gtype = g_type_from_name( name );
		if (gtype != GType.INVALID)
		{
			return gtype;
		}

		/*
		 * Try to map a type name to a _get_type function
		 * and call it, eg:
		 *
		 * GtkWindow -> gtk_window_get_type
		 * GtkHBox -> gtk_hbox_get_type
		 * GtkUIManager -> gtk_ui_manager_get_type
		 *
		 */
		char   c;
		string symbol_name;

		for (int i = 0; name[i] != '\0'; i++)
		{
			c = name[i];
			/* skip if uppercase, first or previous is uppercase */
			if ((c == Str.asciiToupper (c) &&
			   i > 0 && name[i-1] != Str.asciiToupper (name[i-1])) ||
			  (i > 2 && name[i]   == Str.asciiToupper (name[i]) &&
			   name[i-1] == Str.asciiToupper (name[i-1]) &&
			   name[i-2] == Str.asciiToupper (name[i-2]))
			   )

			symbol_name ~= '_';
			symbol_name ~= Str.asciiTolower (c);
		}
		symbol_name ~=  "_get_type" ;

		/* scan linked librarys for function symbol */
		foreach ( lib; importLibs )
		{
			GType function() func;
			Module mod = Module.open( lib, GModuleFlags.LAZY );
			if( mod is null )
				continue;

			scope(exit) mod.close();

			if ( mod.symbol( symbol_name, cast(void**)&func ) ) {
				return func();
			}
		}

		return GType.INVALID;
	}

	/**
	 * Gets the object named name. Note that this function does not
	 * increment the reference count of the returned object.
	 * Since 2.12
	 * Params:
	 * name = name of object to get
	 * Returns: the object named name or NULL if it could not be found in the object tree.. transfer none.
	 */
	public ObjectG getObject(string name)
	{
		// GObject* gtk_builder_get_object (GtkBuilder *builder,  const gchar *name);
		return newFromObject( gtk_builder_get_object(gtkBuilder, Str.toStringz(name)) );
	}

	/**
	 * Gets all objects that have been constructed by builder.
	 * Since 2.12
	 * Returns: an array containing all the objects constructed by the GtkBuilder instance.
	 */
	public ObjectG[] getObjects()
	{
		ObjectG[] objects;

		// GSList* gtk_builder_get_objects (GtkBuilder *builder);
		GSList* list = gtk_builder_get_objects(gtkBuilder);

		while ( list.next !is null )
		{
			objects ~= newFromObject( cast(GObject*)list.data );
			list = list.next;
		}

		g_slist_free(list);

		return objects;
	}

	/**
	 * This function creates an D object corresponding to the Struct pointer passed in.
	 */
	public ObjectG newFromObject(GObject* cobj)
	{
		if(cobj is null)
		{
			return null;
		}

		void* dObj = g_object_get_data(cobj, Str.toStringz("GObject"));

		if ( dObj !is null )
		{
			return cast(ObjectG)dObj;
		}

		string type = convertClassName(Type.name((cast(GTypeInstance*)cobj).gClass.gType));
		ClassInfo ci = cast(ClassInfo)ClassInfo.find(type);

		//Gobject and Gio types both start with g, so try both.
		if(ci is null && startsWith(type, "gobject"))
		{
				ci = cast(ClassInfo)ClassInfo.find("gio"~ type[7..$]);
		}

		if(ci is null)
		{
			return null;
		}

		ObjectG obj = cast(ObjectG)gtkc.gtktypes._d_newclass(ci);

		obj.__ctor(cobj);

		return obj;
	}

	/**
	 * Turn the name of a C Type in to the name of the corresponding D type.
	 * Note: If the prefix of the type is "G" this always usses "gobject" as
	 *     the prefix, extra care should be taken for types from GIO.
	 */
	private string convertClassName(string gName)
	{
		string conv;
		string prefix;

		if      ( startsWith(gName, "GtkSource" ) ) prefix = "Gsv";
		else if ( startsWith(gName, "Gtk") )        prefix = "Gtk";
		else if ( startsWith(gName, "Gdk") )        prefix = "Gdk";
		else if ( startsWith(gName, "Gst") )        prefix = "Gst";
		else if ( startsWith(gName, "Gda") )        prefix = "Gda";
		else if ( startsWith(gName, "Atk") )        prefix = "Atk";
		else if ( startsWith(gName, "G") )          prefix = "G";
		else if ( startsWith(gName, "Pango") )      prefix = "Pg";
		else if ( startsWith(gName, "cairo") )      prefix = "cairo";

		conv = gName[prefix.length..gName.length];

		if ( conv == "Object" ) conv ~= prefix;
		if ( prefix == "Pg" )   conv = "Pg" ~ gName[5..gName.length];
		if ( prefix == "cairo") conv = toUpper(gName[6..7]) ~ gName[7..gName.length - 2];

		prefix = toLower(prefix);

		if( prefix == "gst") prefix = "gstreamer";
		if( prefix == "g")   prefix = "gobject";
		if( prefix == "pg" ) prefix = "pango";

		return prefix ~"."~ conv ~"."~ conv;
	}

	private bool startsWith(string str, string prefix)
	{
		return str.length >= prefix.length && str[0..prefix.length] == prefix;
	}
code: end

struct: Button
import: gtk.Image
noCode: new_with_mnemonic
noCode: new_with_label
noCode: new_from_stock
code: start
	private static IconSize currentIconSize = IconSize.BUTTON;

	/** */
	public static void setIconSize(IconSize iconSize)
	{
		currentIconSize = iconSize;
	}

	/** */
	public static IconSize getIconSize()
	{
		return currentIconSize;
	}

	/**
	 * Creates a new GtkButton containing a label.
	 * If characters in label are preceded by an underscore, they are underlined.
	 * If you need a literal underscore character in a label, use '__' (two
	 * underscores). The first underlined character represents a keyboard
	 * accelerator called a mnemonic.
	 * Pressing Alt and that key activates the button.
	 * Params:
	 *  label = The text of the button, with an underscore in front of the
	 *  mnemonic character
	 *  mnemonic = true if the button has an mnemnonic
	 * Returns:
	 *  a new GtkButton
	 * Throws: ConstructionException GTK+ fails to create the object.
	 */
	public this (string label, bool mnemonic=true)
	{
		GtkButton* p;

		if ( mnemonic )
		{
			// GtkWidget* gtk_button_new_with_mnemonic (const gchar *label);
			p = cast(GtkButton*)gtk_button_new_with_mnemonic(Str.toStringz(label));
		}
		else
		{
			// GtkWidget* gtk_button_new_with_label (const gchar *label);
			p = cast(GtkButton*)gtk_button_new_with_label(Str.toStringz(label));
		}

		if(p is null)
		{
			throw new ConstructionException("null returned by gtk_button_new_with_label");
		}

		this(p);
	}

	/**
	 * Creates a new GtkButton containing the image and text from a stock item.
	 * Some stock ids have preprocessor macros like GTK_STOCK_OK and
	 * GTK_STOCK_APPLY.
	 * If stock_id is unknown, then it will be treated as a mnemonic
	 * label (as for gtk_button_new_with_mnemonic()).
	 * Params:
	 *  StockID = the name of the stock item
	 * Throws: ConstructionException GTK+ fails to create the object.
	 */
	public this (StockID stockID, bool hideLabel=false)
	{
		// GtkWidget* gtk_button_new_from_stock (const gchar *stock_id);
		if ( hideLabel )
		{
			this();
			Image image = new Image(stockID,currentIconSize);
			add(image);
		}
		else
		{
			auto p = gtk_button_new_from_stock(Str.toStringz(stockID));

			if(p is null)
			{
				throw new ConstructionException("null returned by gtk_button_new_from_stock");
			}

			this(cast(GtkButton*) p);
		}
	}

	/** */
	public this(StockID stockID, void delegate(Button) dlg, bool hideLabel=false)
	{
		this(stockID, hideLabel);
		addOnClicked(dlg);
	}

	/** */
	public this(string label, void delegate(Button) dlg, bool mnemonic=true)
	{
		this(label, mnemonic);
		addOnClicked(dlg);
	}

	/** */
	public this(string label, void delegate(Button) dlg, string action)
	{
		this(label);
		setActionName(action);
		addOnClicked(dlg);
	}
code: end

struct: ButtonBox
import: gtk.Button
import: gtk.HButtonBox
import: gtk.VButtonBox
code: start
	/** */
	static ButtonBox createActionBox(
			void delegate(Button) onClicked,
			StockID[] stocks,
			string[] actions,
			bool vertical=false
		)
	{
		ButtonBox bBox;
		if ( vertical )
		{
			bBox = VButtonBox.createActionBox();
		}
		else
		{
			bBox = HButtonBox.createActionBox();
		}

		Button button;
		for( int i=0 ; i<stocks.length && i<actions.length ; i++)
		{
			button =  new Button(stocks[i]);
			bBox.packEnd(button, false, false, 7);
			button.setActionName(actions[i]);
			button.addOnClicked(onClicked);
		}
		return bBox;
	}

	/** */
	static ButtonBox createOkBox(void delegate(Button) onClicked)
	{
		static StockID[] stocks = [StockID.OK];
		string[] actions;
		actions ~= "action.ok";
		return createActionBox(onClicked, stocks, actions);
	}

	/** */
	static ButtonBox createOkCancelBox(void delegate(Button) onClicked)
	{
		static StockID[] stocks = [StockID.OK, StockID.CANCEL];
		string[] actions;
		actions ~= "action.ok";
		actions ~= "action.cancel";
		return createActionBox(onClicked, stocks, actions);
	}

code: end
struct:
class: CellEditable
extend: GObject.Object
implements: CellEditable

struct: CellView
noCode: new_with_text
noCode: new_with_markup
code: start
	/**
	 * Creates a new GtkCellView widget, adds a GtkCellRendererText
	 * to it, and makes its show text.
	 * If markup is true the text can be marked up with the Pango text
	 * markup language.
	 * Since: 2.6
	 * Params:
	 *  text = the text to display in the cell view
	 * Returns:
	 *  A newly created GtkCellView widget.
	 * Throws: ConstructionException GTK+ fails to create the object.
	 */
	public this (string text, bool markup=true)
	{
		GtkCellView* p;

		if ( markup )
		{
			// GtkWidget* gtk_cell_view_new_with_markup (const gchar *markup);
			p = cast(GtkCellView*)gtk_cell_view_new_with_markup(Str.toStringz(text));
		}
		else
		{
			// GtkWidget* gtk_cell_view_new_with_text (const gchar *text);
			p = cast(GtkCellView*)gtk_cell_view_new_with_text(Str.toStringz(text));
		}

		if(p is null)
		{
			throw new ConstructionException("null returned by gtk_cell_view_new_with_");
		}

		this(p);
	}
code: end

struct: CheckButton
import: glib.Str
import: gtk.Button
noCode: new_with_label
noCode: new_with_mnemonic
code: start
	/**
	 * Creates a new GtkCheckButton with a GtkLabel to the right of it.
	 * If mnemonic is true the label
	 * will be created using gtk_label_new_with_mnemonic(), so underscores
	 * in label indicate the mnemonic for the check button.
	 * Params:
	 *  label = The text of the button, with an underscore in front of the
	 *  mnemonic character
	 *  mnemonic = true if the button has an mnemnonic
	 * Throws: ConstructionException GTK+ fails to create the object.
	 */
	public this (string label, bool mnemonic=true)
	{
		GtkCheckButton* p;

		if ( mnemonic )
		{
			// GtkWidget* gtk_check_button_new_with_mnemonic  (const gchar *label);
			p = cast(GtkCheckButton*)gtk_check_button_new_with_mnemonic(Str.toStringz(label));
		}
		else
		{
			// GtkWidget* gtk_check_button_new_with_label (const gchar *label);
			p = cast(GtkCheckButton*)gtk_check_button_new_with_label(Str.toStringz(label));
		}

		if(p is null)
		{
			throw new ConstructionException("null returned by gtk_check_button_new_");
		}

		this(p);
	}

	/** */
	public this(string label, void delegate(CheckButton) onClicked, bool mnemonic=true)
	{
		this(label, mnemonic);
		addOnClicked(cast(void delegate(Button))onClicked);
	}
code: end

struct: CheckMenuItem
import: glib.Str
noCode: new_with_label
noCode: new_with_mnemonic
code: start
	/**
	 * Creates a new GtkCheckMenuItem with a label.
	 * Params:
	 *  label = the string to use for the label.
	 *  mnemonic = if true the label
	 *  will be created using gtk_label_new_with_mnemonic(), so underscores
	 *  in label indicate the mnemonic for the menu item.
	 * Throws: ConstructionException GTK+ fails to create the object.
	 */
	public this (string label, bool mnemonic=true)
	{
		GtkCheckMenuItem* p;

		if ( mnemonic )
		{
			// GtkWidget* gtk_check_menu_item_new_with_mnemonic  (const gchar *label);
			p = cast(GtkCheckMenuItem*)gtk_check_menu_item_new_with_mnemonic(Str.toStringz(label));
		}
		else
		{
			// GtkWidget* gtk_check_menu_item_new_with_label  (const gchar *label);
			p = cast(GtkCheckMenuItem*)gtk_check_menu_item_new_with_label(Str.toStringz(label));
		}

		if(p is null)
		{
			throw new ConstructionException("null returned by gtk_check_menu_item_new_with_");
		}

		this(p);
	}
code: end

struct: ColorButton
noCode: set_rgba
noCode: get_rgba
noCode: set_use_alpha
noCode: get_use_alpha

struct: ColorSelectionDialog
import: gtk.ColorSelection
noCode: get_color_selection
code: start
	/**
	 * Retrieves the ColorSelection widget embedded in the dialog.
	 *
	 * Return: the embedded ColorSelection
	 *
	 * Since: 2.14
	 */
	public ColorSelection getColorSelection()
	{
		auto p = gtk_color_selection_dialog_get_color_selection(gtkColorSelectionDialog);

		if(p is null)
		{
			return null;
		}

		return ObjectG.getDObject!(ColorSelection)(cast(GtkColorSelection*) p);
	}
code: end

struct: ComboBox
import: glib.ConstructionException
noCode: new
noCode: new_with_entry
noCode: new_with_model
noCode: new_with_model_and_entry
noCode: new_with_area
noCode: new_with_area_and_entry
code: start
	/**
	 * Creates a new empty GtkComboBox.
	 * Params:
	 *   entry = If true, create an empty ComboBox with an entry.
	 * Throws: ConstructionException GTK+ fails to create the object.
	 */
	public this (bool entry=true)
	{
		GtkComboBox* p;
		if ( entry )
		{
			// GtkWidget* gtk_combo_box_new_text (void);
			p = cast(GtkComboBox*)gtk_combo_box_new_with_entry();
		}
		else
		{
			// GtkWidget* gtk_combo_box_new (void);
			p = cast(GtkComboBox*)gtk_combo_box_new();
		}

		if(p is null)
		{
			throw new ConstructionException("null returned by gtk_combo_box_new");
		}

		this(p);
	}

	/**
	 * Creates a new GtkComboBox with the model initialized to model.
	 * Params:
	 *   model = A GtkTreeModel.
	 *   entry = If true, create an empty ComboBox with an entry.
	 * Throws: ConstructionException GTK+ fails to create the object.
	 */
	public this (TreeModelIF model, bool entry=true)
	{
		GtkComboBox* p;
		if ( entry )
		{
			// GtkWidget* gtk_combo_box_new_with_model_and_entry (GtkTreeModel *model);
			p = cast(GtkComboBox*)gtk_combo_box_new_with_model_and_entry((model is null) ? null : model.getTreeModelStruct());
		}
		else
		{
			// GtkWidget* gtk_combo_box_new_with_model (GtkTreeModel *model);
			p = cast(GtkComboBox*)gtk_combo_box_new_with_model((model is null) ? null : model.getTreeModelStruct());
		}

		if(p is null)
		{
			throw new ConstructionException("null returned by gtk_combo_box_new");
		}

		this(p);
	}

	/**
	 * Creates a new empty GtkComboBox using area to layout cells.
	 * Params:
	 *   area = the GtkCellArea to use to layout cell renderers.
	 *   entry = If true, create an empty ComboBox with an entry.
	 * Throws: ConstructionException GTK+ fails to create the object.
	 */
	public this (CellArea area, bool entry=true)
	{
		GtkComboBox* p;
		if ( entry )
		{
			// GtkWidget* gtk_combo_box_new_with_area_and_entry (GtkCellArea *area);
			p = cast(GtkComboBox*)gtk_combo_box_new_with_area_and_entry((area is null) ? null : area.getCellAreaStruct());
		}
		else
		{
			// GtkWidget* gtk_combo_box_new_with_area (GtkCellArea* area);
			p = cast(GtkComboBox*)gtk_combo_box_new_with_area((area is null) ? null : area.getCellAreaStruct());
		}

		if(p is null)
		{
			throw new ConstructionException("null returned by gtk_combo_box_new");
		}

		this(p);
	}
code: end

struct: ComboBoxText
import: glib.ConstructionException
import: gobject.Signals
import: gtk.TreeIter
import: gtk.TreeModelIF
import: gtkc.gdktypes
import: std.algorithm
override: remove_all
noCode: new
noCode: new_with_entry
code: start
	/**
	 * Creates a new ComboBoxText, which is a ComboBox just displaying strings.
	 * Params:
	 *   entry = If true, create an ComboBox with an entry.
	 * Throws: ConstructionException GTK+ fails to create the object.
	 */
	public this (bool entry=true)
	{
		GtkComboBoxText* p;
		if ( entry )
		{
			// GtkWidget* gtk_combo_box_text_new_with_entry (void);
			p = cast(GtkComboBoxText*)gtk_combo_box_text_new_with_entry();
		}
		else
		{
			// GtkWidget* gtk_combo_box_text_new (void);
			p = cast(GtkComboBoxText*)gtk_combo_box_text_new();
		}

		if(p is null)
		{
			throw new ConstructionException("null returned by gtk_combo_box_new");
		}

		this(p);
	}

	/** */
	public void setActiveText(string text, bool insert=false)
	{
		int active = 0;
		setActive(0);
		while ( getActive() >= 0 ) // returns -1 if end of list if reached
		{
			if( text == getActiveText() ) return;
			++active;
			setActive(active);
		}
		// was not found, the combo has now nothing selected
		if ( insert )
		{
			append("", text);
			setActive(active);
		}
	}

	/** */
	int getIndex(string text)
	{
		TreeIter iter;
		TreeModelIF model = getModel();
		int index = 0;
		bool found = false;
		bool end = false;
		if ( model.getIterFirst(iter) )
		{
			iter.setModel(model);
			while ( !end && iter !is  null && !found )
			{
				found = iter.getValueString(0) == text;
				if ( !found )
				{
					end = !model.iterNext(iter);
					++index;
				}
			}
		}
		else
		{
			end = true;
		}
		return end ? -1 : index;
	}

	/** */
	void prependOrReplaceText(string text)
	{
		int index = getIndex(text);
		if ( index > 0 )
		{
			remove(index);
			prepend("", text);
		}
		else if ( index == -1 )
		{
			prepend("", text);
		}
	}

	protected class OnChangedDelegateWrapper
	{
		static OnChangedDelegateWrapper[] listeners;
		void delegate(ComboBoxText) dlg;
		gulong handlerId;
		
		this(void delegate(ComboBoxText) dlg)
		{
			this.dlg = dlg;
			this.listeners ~= this;
		}
		
		void remove(OnChangedDelegateWrapper source)
		{
			foreach(index, wrapper; listeners)
			{
				if (wrapper.handlerId == source.handlerId)
				{
					listeners[index] = null;
					listeners = std.algorithm.remove(listeners, index);
					break;
				}
			}
		}
	}

	/**
	 * The changed signal is emitted when the active
	 * item is changed. The can be due to the user selecting
	 * a different item from the list, or due to a
	 * call to gtk_combo_box_set_active_iter().
	 * It will also be emitted while typing into the entry of a combo box
	 * with an entry.
	 *
	 * Since: 2.4
	 */
	gulong addOnChanged(void delegate(ComboBoxText) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
	{
		auto wrapper = new OnChangedDelegateWrapper(dlg);
		wrapper.handlerId = Signals.connectData(
			this,
			"changed",
			cast(GCallback)&callBackChanged,
			cast(void*)wrapper,
			cast(GClosureNotify)&callBackChangedDestroy,
			connectFlags);
		return wrapper.handlerId;
	}
	
	extern(C) static void callBackChanged(GtkComboBoxText* comboboxTextStruct, OnChangedDelegateWrapper wrapper)
	{
		wrapper.dlg(wrapper.outer);
	}
	
	extern(C) static void callBackChangedDestroy(OnChangedDelegateWrapper wrapper, GClosure* closure)
	{
		wrapper.remove(wrapper);
	}

	protected class OnFormatEntryTextDelegateWrapper
	{
		static OnFormatEntryTextDelegateWrapper[] listeners;
		string delegate(string, ComboBoxText) dlg;
		gulong handlerId;
		
		this(string delegate(string, ComboBoxText) dlg)
		{
			this.dlg = dlg;
			this.listeners ~= this;
		}
		
		void remove(OnFormatEntryTextDelegateWrapper source)
		{
			foreach(index, wrapper; listeners)
			{
				if (wrapper.handlerId == source.handlerId)
				{
					listeners[index] = null;
					listeners = std.algorithm.remove(listeners, index);
					break;
				}
			}
		}
	}

	/**
	 * For combo boxes that are created with an entry (See GtkComboBox:has-entry).
	 *
	 * A signal which allows you to change how the text displayed in a combo box's
	 * entry is displayed.
	 *
	 * Connect a signal handler which returns an allocated string representing
	 * @path. That string will then be used to set the text in the combo box's entry.
	 * The default signal handler uses the text from the GtkComboBox::entry-text-column
	 * model column.
	 *
	 * Here's an example signal handler which fetches data from the model and
	 * displays it in the entry.
	 * |[<!-- language="C" -->
	 * static gchar*
	 * format_entry_text_callback (GtkComboBox *combo,
	 * const gchar *path,
	 * gpointer     user_data)
	 * {
	 * GtkTreeIter iter;
	 * GtkTreeModel model;
	 * gdouble      value;
	 *
	 * model = gtk_combo_box_get_model (combo);
	 *
	 * gtk_tree_model_get_iter_from_string (model, &iter, path);
	 * gtk_tree_model_get (model, &iter,
	 * THE_DOUBLE_VALUE_COLUMN, &value,
	 * -1);
	 *
	 * return g_strdup_printf ("%g", value);
	 * }
	 * ]|
	 *
	 * Params:
	 *     path = the GtkTreePath string from the combo box's current model to format text for
	 *
	 * Return: a newly allocated string representing @path
	 *     for the current GtkComboBox model.
	 *
	 * Since: 3.4
	 */
	gulong addOnFormatEntryText(string delegate(string, ComboBoxText) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
	{
		auto wrapper = new OnFormatEntryTextDelegateWrapper(dlg);
		wrapper.handlerId = Signals.connectData(
			this,
			"format-entry-text",
			cast(GCallback)&callBackFormatEntryText,
			cast(void*)wrapper,
			cast(GClosureNotify)&callBackFormatEntryTextDestroy,
			connectFlags);
		return wrapper.handlerId;
	}
	
	extern(C) static string callBackFormatEntryText(GtkComboBoxText* comboboxStructText, char* path,OnFormatEntryTextDelegateWrapper wrapper)
	{
		return wrapper.dlg(Str.toString(path), wrapper.outer);
	}
	
	extern(C) static void callBackFormatEntryTextDestroy(OnFormatEntryTextDelegateWrapper wrapper, GClosure* closure)
	{
		wrapper.remove(wrapper);
	}

	protected class OnMoveActiveDelegateWrapper
	{
		static OnMoveActiveDelegateWrapper[] listeners;
		void delegate(GtkScrollType, ComboBoxText) dlg;
		gulong handlerId;
		
		this(void delegate(GtkScrollType, ComboBoxText) dlg)
		{
			this.dlg = dlg;
			this.listeners ~= this;
		}
		
		void remove(OnMoveActiveDelegateWrapper source)
		{
			foreach(index, wrapper; listeners)
			{
				if (wrapper.handlerId == source.handlerId)
				{
					listeners[index] = null;
					listeners = std.algorithm.remove(listeners, index);
					break;
				}
			}
		}
	}

	/**
	 * The ::move-active signal is a
	 * [keybinding signal][GtkBindingSignal]
	 * which gets emitted to move the active selection.
	 *
	 * Params:
	 *     scrollType = a #GtkScrollType
	 *
	 * Since: 2.12
	 */
	gulong addOnMoveActive(void delegate(GtkScrollType, ComboBoxText) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
	{
		auto wrapper = new OnMoveActiveDelegateWrapper(dlg);
		wrapper.handlerId = Signals.connectData(
			this,
			"move-active",
			cast(GCallback)&callBackMoveActive,
			cast(void*)wrapper,
			cast(GClosureNotify)&callBackMoveActiveDestroy,
			connectFlags);
		return wrapper.handlerId;
	}
	
	extern(C) static void callBackMoveActive(GtkComboBoxText* comboboxTextStruct, GtkScrollType scrollType,OnMoveActiveDelegateWrapper wrapper)
	{
		wrapper.dlg(scrollType, wrapper.outer);
	}
	
	extern(C) static void callBackMoveActiveDestroy(OnMoveActiveDelegateWrapper wrapper, GClosure* closure)
	{
		wrapper.remove(wrapper);
	}

	protected class OnPopdownDelegateWrapper
	{
		static OnPopdownDelegateWrapper[] listeners;
		bool delegate(ComboBoxText) dlg;
		gulong handlerId;
		
		this(bool delegate(ComboBoxText) dlg)
		{
			this.dlg = dlg;
			this.listeners ~= this;
		}
		
		void remove(OnPopdownDelegateWrapper source)
		{
			foreach(index, wrapper; listeners)
			{
				if (wrapper.handlerId == source.handlerId)
				{
					listeners[index] = null;
					listeners = std.algorithm.remove(listeners, index);
					break;
				}
			}
		}
	}

	/**
	 * The ::popdown signal is a
	 * [keybinding signal][GtkBindingSignal]
	 * which gets emitted to popdown the combo box list.
	 *
	 * The default bindings for this signal are Alt+Up and Escape.
	 *
	 * Since: 2.12
	 */
	gulong addOnPopdown(bool delegate(ComboBoxText) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
	{
		auto wrapper = new OnPopdownDelegateWrapper(dlg);
		wrapper.handlerId = Signals.connectData(
			this,
			"popdown",
			cast(GCallback)&callBackPopdown,
			cast(void*)wrapper,
			cast(GClosureNotify)&callBackPopdownDestroy,
			connectFlags);
		return wrapper.handlerId;
	}
	
	extern(C) static int callBackPopdown(GtkComboBoxText* comboboxTextStruct,OnPopdownDelegateWrapper wrapper)
	{
		return wrapper.dlg(wrapper.outer);
	}
	
	extern(C) static void callBackPopdownDestroy(OnPopdownDelegateWrapper wrapper, GClosure* closure)
	{
		wrapper.remove(wrapper);
	}

	protected class OnPopupDelegateWrapper
	{
		static OnPopupDelegateWrapper[] listeners;
		void delegate(ComboBoxText) dlg;
		gulong handlerId;
		
		this(void delegate(ComboBoxText) dlg)
		{
			this.dlg = dlg;
			this.listeners ~= this;
		}
		
		void remove(OnPopupDelegateWrapper source)
		{
			foreach(index, wrapper; listeners)
			{
				if (wrapper.handlerId == source.handlerId)
				{
					listeners[index] = null;
					listeners = std.algorithm.remove(listeners, index);
					break;
				}
			}
		}
	}

	/**
	 * The ::popup signal is a
	 * [keybinding signal][GtkBindingSignal]
	 * which gets emitted to popup the combo box list.
	 *
	 * The default binding for this signal is Alt+Down.
	 *
	 * Since: 2.12
	 */
	gulong addOnPopup(void delegate(ComboBoxText) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
	{
		auto wrapper = new OnPopupDelegateWrapper(dlg);
		wrapper.handlerId = Signals.connectData(
			this,
			"popup",
			cast(GCallback)&callBackPopup,
			cast(void*)wrapper,
			cast(GClosureNotify)&callBackPopupDestroy,
			connectFlags);
		return wrapper.handlerId;
	}
	
	extern(C) static void callBackPopup(GtkComboBoxText* comboboxTextStruct,OnPopupDelegateWrapper wrapper)
	{
		wrapper.dlg(wrapper.outer);
	}
	
	extern(C) static void callBackPopupDestroy(OnPopupDelegateWrapper wrapper, GClosure* closure)
	{
		wrapper.remove(wrapper);
	}
code: end

struct: Container
code: start
	/**
	 * Removes all widgets from the container
	 */
	void removeAll()
	{
		GList* gList = gtk_container_get_children(getContainerStruct());
		if ( gList !is null )
		{
			ListG children = new ListG(gList);
			for ( int i=children.length()-1 ; i>=0 ; i-- )
			{
				gtk_container_remove(getContainerStruct(), cast(GtkWidget*)children.nthData(i));
			}
		}
	}
code: end

struct: Dialog
import: gtk.Button
import: gtk.HButtonBox
import: gtk.VBox
alias: set_alternative_button_order_from_array setAlternativeButtonOrder
# Make these return the correct class.
noCode: get_action_area
noCode: get_content_area
code: start
	/**
	 * Both title and parent can be null.
	 */
	this(string title, Window parent, GtkDialogFlags flags, string[] buttonsText, ResponseType[] responses)
	{
		auto p = gtk_dialog_new_with_buttons(Str.toStringz(title), (parent is null) ? null : parent.getWindowStruct(), flags, Str.toStringz(buttonsText[0]), responses[0], null);
		if(p is null)
		{
			throw new ConstructionException("null returned by gtk_dialog_new_with_buttons");
		}

		this(cast(GtkDialog*)p);

		addButtons(buttonsText[1 .. $], responses[1 .. $]);
	}

	/** ditto */
	this(string title, Window parent, GtkDialogFlags flags, StockID[] stockIDs, ResponseType[] responses)
	{
		auto p = gtk_dialog_new_with_buttons(Str.toStringz(title), (parent is null) ? null : parent.getWindowStruct(), flags, Str.toStringz(stockIDs[0]), responses[0], null);
		if(p is null)
		{
			throw new ConstructionException("null returned by gtk_dialog_new_with_buttons");
		}

		this(cast(GtkDialog*)p);

		addButtons(stockIDs[1 .. $], responses[1 .. $]);
	}

	/** */
	public Button addButton(StockID stockID, int responseId)
	{
		auto p = gtk_dialog_add_button(gtkDialog, Str.toStringz(stockID), responseId);

		if ( p is null )
		{
			return null;
		}

		return new Button(cast(GtkButton*)p);
	}

	/** */
	public void addButtons(string[] buttonsText, ResponseType[] responses)
	{
		for ( int i=0 ; i<buttonsText.length && i<responses.length ; i++)
		{
			addButton(buttonsText[i], responses[i]);
		}
	}

	/** */
	public void addButtons(StockID[] stockIDs, ResponseType[] responses)
	{
		for ( int i=0 ; i<stockIDs.length && i<responses.length ; i++)
		{
			addButton(stockIDs[i], responses[i]);
		}
	}

	//Return the corect class instead of Widget
	/**
	 * Returns the action area of dialog.
	 * Since: 2.14
	 * Returns: the action area.
	 */
	public HButtonBox getActionArea()
	{
		auto p = gtk_dialog_get_action_area(gtkDialog);
		if(p is null)
		{
			return null;
		}
		return new HButtonBox(cast(GtkHButtonBox*) p);
	}

	//Return the corect class instead of Widget
	/**
	 * Returns the content area of dialog.
	 * Since: 2.14
	 * Returns: the content area GtkVBox.
	 */
	public VBox getContentArea()
	{
		auto p = gtk_dialog_get_content_area(gtkDialog);
		if(p is null)
		{
			return null;
		}
		return new VBox(cast(GtkVBox*) p);
	}
code: end

struct: DrawingArea
code: start
	/**
	 * Create a new DrawingArea and sets the SizeRequest
	 * Params:
	 *    	width =
	 *    	height =
	 */
	this(int width, int height)
	{
		this();
		setSizeRequest(width, height);
	}
code: end

struct: Entry
code: start
	/** */
	public this (string text)
	{
		this();
		setText(text);
	}

	/** */
	public this (string text, int max)
	{
		this(text);
		setMaxLength(max);
	}

	/**
	 * Gets the stock id of action.
	 * Since 2.16
	 * Returns: the stock id
	 */
	public StockID getStockId(GtkEntryIconPosition iconPos)
	{
		return cast(StockID)Str.toString(gtk_entry_get_icon_stock(gtkEntry, iconPos));
	}

	/**
	 * Sets the stock id on action
	 * Since 2.16
	 * Params:
	 * stockId =  the stock id
	 */
	public void setStockId(GtkEntryIconPosition iconPos, StockID stockId)
	{
		// void gtk_entry_set_icon_from_stock (GtkEntry *entry, GtkEntryIconPosition icon_pos, const gchar *stock_id);
		gtk_entry_set_icon_from_stock(gtkEntry, iconPos, Str.toStringz(stockId));
	}
code: end

struct: EntryIconAccessible
noCode: true

struct: Expander
import: glib.ConstructionException
noCode: new
noCode: new_with_mnemonic
code: start
	/**
	 * Creates a new expander using label as the text of the label.
	 * Since 2.4
	 * Params:
	 *  label = the text of the label
	 *  mnemonic = if true characters in label that are preceded by an underscore,
	 *  are underlined.
	 *  If you need a literal underscore character in a label, use '__' (two
	 *  underscores). The first underlined character represents a keyboard
	 *  accelerator called a mnemonic.
	 * Throws: ConstructionException GTK+ fails to create the object.
	 */
	public this (string label, bool mnemonic=true)
	{
		GtkExpander* p;

		if ( mnemonic )
		{
			p = cast(GtkExpander*)gtk_expander_new_with_mnemonic(Str.toStringz(label));
		}
		else
		{
			p = cast(GtkExpander*)gtk_expander_new(Str.toStringz(label));
		}

		if(p is null)
		{
			throw new ConstructionException("null returned by gtk_expander_new");
		}

		this(p);
	}
code: end

struct: FileChooser
alias: set_action setFileChooserAction
alias: get_action getFileChooserAction

struct: FileChooserDialog
import: glib.ConstructionException
import: gtk.Window
noCode: new
code: start
	/**
	 * Creates a new FileChooserDialog. This function is analogous to
	 * gtk_dialog_new_with_buttons().
	 * Since: 2.4
	 * Params:
	 *  title = Title of the dialog, or NULL
	 *  parent = Transient parent of the dialog, or NULL
	 *  action = Open or save mode for the dialog
	 *  buttonsText = text to go in the buttons
	 *  responses = response ID's for the buttons
	 * Throws: ConstructionException GTK+ fails to create the object.
	 */
	this(string title, Window parent, FileChooserAction action,  string[] buttonsText=null, ResponseType[] responses=null)
	{
		if ( buttonsText  is  null )
		{
			buttonsText ~= "OK";
			buttonsText ~= "Cancel";
		}
		if ( responses  is  null )
		{
			responses ~= ResponseType.OK;
			responses ~= ResponseType.CANCEL;
		}

		auto p = gtk_file_chooser_dialog_new(
				Str.toStringz(title),
				(parent is null) ? null : parent.getWindowStruct(),
				action,
				null,
				0);

		if(p is null)
		{
			throw new ConstructionException("null returned by gtk_file_chooser_dialog_new");
		}

		this(cast(GtkFileChooserDialog*) p);

		addButtons(buttonsText, responses);
	}
code: end

struct: FontChooser
override: get_font_map
override: set_font_map

struct: FontSelectionDialog
import: gtk.FontSelection
noCode: get_font_selection
code: start
	/**
	 * Retrieves the FontSelection widget embedded in the dialog.
	 *
	 * Deprecated: Use FontChooserDialog
	 *
	 * Return: the embedded FontSelection
	 *
	 * Since: 2.22
	 */
	public FontSelection getFontSelection()
	{
		auto p = gtk_font_selection_dialog_get_font_selection(gtkFontSelectionDialog);

		if(p is null)
		{
			return null;
		}

		return ObjectG.getDObject!(FontSelection)(cast(GtkFontSelection*) p);
	}
code: end

struct: Frame
code: start
	/**
	 * Creates frame with label and set it's child widget
	 */
	public this(Widget widget, string label)
	{
		this(label);
		add(widget);
	}
code: end

struct: HButtonBox
code: start
	/**
	 * Creates a new HButtonBox and sets comon parameters
	 */
	static HButtonBox createActionBox()
	{
		HButtonBox bBox = new HButtonBox();
		bBox.setLayout(ButtonBoxStyle.END);
		bBox.setBorderWidth(5);
		bBox.setSpacing(7);
		return bBox;
	}
code: end

struct: HPaned
code: start
	/**
	 * Creates a new HPaned and adds two widgets as it's children
	 * Params:
	 *  child1 =
	 *  child2 =
	 */
	this(Widget child1, Widget child2)
	{
		this();
		add1(child1);
		add2(child2);
	}
code: end

struct: Image
noCode: new_from_resource
noCode: new_from_stock
code: start
	/**
	 * Creates a Image displaying a stock icon. Sample stock icon
	 * names are StockID.OPEN, StockID.EXIT. Sample stock sizes
	 * are IconSize.MENU, IconSize.SMALL_TOOLBAR. If the stock
	 * icon name isn't known, the image will be empty.
	 * You can register your own stock icon names, see
	 * gtk.IconFactory.IconFactory.addDefault() and gtk.IconFactory.IconFactory.add().
	 * Params:
	 *  StockID = a stock icon name
	 *  size = a stock icon size
	 * Returns:
	 *  a new GtkImage displaying the stock icon
	 * Throws: ConstructionException GTK+ fails to create the object.
	 */
	public this (StockID stockID, GtkIconSize size)
	{
		auto p = gtk_image_new_from_stock(Str.toStringz(stockID), size);
		if(p is null)
		{
			throw new ConstructionException("null returned by gtk_image_new_from_stock(Str.toStringz(StockDesc[stockID]), size)");
		}
		this(cast(GtkImage*)p);
	}
code: end

struct: ImageMenuItem
import: glib.Str
noCode: new_with_label
noCode: new_with_mnemonic
noCode: new_from_stock
code: start
	/**
	 * Creates a new GtkImageMenuItem containing a label.
	 * If mnemonic it true the label will be created using
	 * gtk_label_new_with_mnemonic(), so underscores
	 * in label indicate the mnemonic for the menu item.
	 * Params:
	 *  label = the text of the menu item.
	 * Throws: ConstructionException GTK+ fails to create the object.
	 */
	public this (string label, bool mnemonic=true)
	{
		GtkImageMenuItem* p;

		if ( mnemonic )
		{
			// GtkWidget* gtk_image_menu_item_new_with_mnemonic  (const gchar *label);
			p = cast(GtkImageMenuItem*)gtk_image_menu_item_new_with_mnemonic(Str.toStringz(label));
		}
		else
		{
			// GtkWidget* gtk_image_menu_item_new_with_label  (const gchar *label);
			p = cast(GtkImageMenuItem*)gtk_image_menu_item_new_with_label(Str.toStringz(label));
		}

		if(p is null)
		{
			throw new ConstructionException("null returned by gtk_image_menu_item_new_with_");
		}

		this(p);
	}

	/**
	 * Creates a new GtkImageMenuItem containing the image and text from a
	 * stock item.
	 * If you want this menu item to have changeable accelerators, then pass in
	 * null for accelGroup. Next call setAccelPath() with an appropriate path
	 * for the menu item, use gtk.StockItem.StockItem.lookup() to look up the
	 * standard accelerator for the stock item, and if one is found, call
	 * gtk.AccelMap.AccelMap.addEntry() to register it.
	 * Params:
	 *   StockID    = the name of the stock item
	 *   accelGroup = the GtkAccelGroup to add the menu items accelerator to,
	 *                or NULL.
	 * Throws: ConstructionException GTK+ fails to create the object.
	 */
	public this (StockID stockID, AccelGroup accelGroup)
	{
		auto p = gtk_image_menu_item_new_from_stock(Str.toStringz(stockID), (accelGroup is null) ? null : accelGroup.getAccelGroupStruct());
		if(p is null)
		{
			throw new ConstructionException("null returned by gtk_image_menu_item_new_from_stock");
		}
		this(cast(GtkImageMenuItem*) p);
	}
code: end

struct: InfoBar
import: gtk.HBox
import: gtk.VButtonBox
noCode: get_action_area
noCode: get_content_area
code: start
	/** */
	public this(string[] buttonsText, ResponseType[] responses)
	{
		this();

		for ( int i=0 ; i<buttonsText.length && i<responses.length ; i++)
		{
			addButton(buttonsText[i], responses[i]);
		}
	}

	/** */
	public this(StockID[] stockIDs, ResponseType[] responses)
	{
		this();

		for ( int i=0 ; i<stockIDs.length && i<responses.length ; i++)
		{
			addButton(stockIDs[i], responses[i]);
		}
	}

	/** */
	public Button addButton(StockID stockID, int responseId)
	{
		auto p = gtk_info_bar_add_button(gtkInfoBar, Str.toStringz(stockID), responseId);

		if ( p is null )
		{
			return null;
		}

		return new Button(cast(GtkButton*)p);
	}

	/** */
	public void addButtons(string[] buttonsText, ResponseType[] responses)
	{
		for ( int i=0 ; i<buttonsText.length && i<responses.length ; i++)
		{
			addButton(buttonsText[i], responses[i]);
		}
	}

	/** */
	public void addButtons(StockID[] stockIDs, ResponseType[] responses)
	{
		for ( int i=0 ; i<stockIDs.length && i<responses.length ; i++)
		{
			addButton(stockIDs[i], responses[i]);
		}
	}

	/**
	 * Returns the action area of info_bar.
	 * Since 2.18
	 * Returns: the action area.
	 */
	public VButtonBox getActionArea()
	{
		// GtkWidget * gtk_info_bar_get_action_area (GtkInfoBar *info_bar);
		auto p = gtk_info_bar_get_action_area(gtkInfoBar);
		if(p is null)
		{
			return null;
		}
		return new VButtonBox(cast(GtkVButtonBox*) p);
	}

	/**
	 * Returns the content area of info_bar.
	 * Since 2.18
	 * Returns: the content area.
	 */
	public HBox getContentArea()
	{
		// GtkWidget * gtk_info_bar_get_content_area (GtkInfoBar *info_bar);
		auto p = gtk_info_bar_get_content_area(gtkInfoBar);
		if(p is null)
		{
			return null;
		}
		return new HBox(cast(GtkHBox*) p);
	}
code: end

struct: Label
import: glib.ConstructionException
noCode: new
noCode: new_with_mnemonic
code: start
	/**
	 * Creates a new GtkLabel, containing the text in str.
	 * If characters in str are preceded by an underscore, they are
	 * underlined. If you need a literal underscore character in a label, use
	 * '__' (two underscores). The first underlined character represents a
	 * keyboard accelerator called a mnemonic. The mnemonic key can be used
	 * to activate another widget, chosen automatically, or explicitly using
	 * setMnemonicWidget().
	 *
	 * If setMnemonicWidget() is not called, then the first activatable ancestor of the Label
	 * will be chosen as the mnemonic widget. For instance, if the
	 * label is inside a button or menu item, the button or menu item will
	 * automatically become the mnemonic widget and be activated by
	 * the mnemonic.
	 * Params:
	 *  str = The text of the label, with an underscore in front of the
	 *  mnemonic character
	 *  mnemonic = when false uses the literal text passed in without mnemonic
	 * Throws: ConstructionException GTK+ fails to create the object.
	 */
	public this (string str, bool mnemonic=true)
	{
		GtkLabel* p;

		if ( mnemonic )
		{
			// GtkWidget* gtk_label_new_with_mnemonic (const gchar *str);
			p = cast(GtkLabel*)gtk_label_new_with_mnemonic(Str.toStringz(str));
		}
		else
		{
			// GtkWidget* gtk_label_new (const gchar *str);
			p = cast(GtkLabel*)gtk_label_new(Str.toStringz(str));
		}

		if(p is null)
		{
			throw new ConstructionException("null returned by gtk_label_new");
		}

		this(p);
	}
code: end

struct: ListStore
code: start
	/**
	 * Creates a top level iteractor.
	 * I don't think lists have but the top level iteractor
	 */
	TreeIter createIter()
	{
		GtkTreeIter* iter = new GtkTreeIter;
		gtk_list_store_append(getListStoreStruct(), iter);
		return new TreeIter(iter);
	}

	/**
	 * sets the values for one row
	 * Params:
	 *  iter = the row iteractor
	 *  columns = an arrays with the columns to set
	 *  values = an arrays with the values
	 */
	void set(TreeIter iter, int[] columns, char*[] values)
	{
		for ( int i=0 ; i<columns.length && i<values.length; i++ )
		{
			gtk_list_store_set(
					gtkListStore,
					iter.getTreeIterStruct(),
					columns[i],
					values[i],-1);
		}
	}

	/** ditto */
	void set(TreeIter iter, int[] columns, string[] values)
	{
		for ( int i=0 ; i<columns.length && i<values.length; i++ )
		{
			gtk_list_store_set(
					gtkListStore,
					iter.getTreeIterStruct(),
					columns[i],
					Str.toStringz(values[i]),-1);
		}
	}

	/** */
	void setValue(TreeIter iter, int column, string value)
	{
		Value v = new Value(value);
		gtk_list_store_set_value(gtkListStore, iter.getTreeIterStruct(), column, v.getValueStruct());
		//gtk_list_store_set_value(obj(), iter.getIter(), column, (GValue*)cChar(value));
	}

	/** */
	void setValue(TreeIter iter, int column, int value)
	{
		Value v = new Value(value);
		gtk_list_store_set_value(gtkListStore, iter.getTreeIterStruct(), column, v.getValueStruct());
	}
code: end

struct: Main
alias: main run
import: gdk.Threads
code: start
	/**
	 * This initiates GtkD to supports multi threaded programs.
	 * read full documantation at http://gtk.org/faq/#AEN482
	 * from the FAQ:
	 * "There is a single global lock that you must acquire with
	 * gdk_threads_enter() before making any GDK calls,
	 * and release with gdk_threads_leave() afterwards throughout your code."
	 * This is to be used on any call to GDK not executed from the main thread.
	 */
	public static void initMultiThread(string[] args)
	{
		threadsInit();
		init(args);
	}
code: end

struct: MainWindow
namespace:
import: gtk.Widget
import: gtk.Window
import: gtk.Main
import: gdk.Event
code: start

/**
 * A top Level window that will stop the main event cycle when it's closed.
 * Closing the last of the windows of class "MainWindow" will end the application.
 */
public class MainWindow : Window
{
	private static int countTotalMainWindows = 0;

	/**
	 * Creates a new MainWindow with a title
	 */
	public this(string title)
	{
		super(title);
		countTotalMainWindows++;
		//printf("MainWindows.this count = %d\n", countTotalMainWindows);
		addOnDelete(&windowDelete);
	}

	/**
	 * Executed when the user tries to close the window
	 * Returns: true to refuse to close the window
	 */
	protected bool windowDelete(Event event, Widget widget)
	{
		--countTotalMainWindows;
		//printf("MainWindows.windowDelete count = %d\n", countTotalMainWindows);
		if ( exit(0, false) || countTotalMainWindows==0 )
		{
			Main.quit();
			return false;
		}
		return false;
	}

	/**
	 * Allows the application to close and decide if it can exit
	 * Params:
	 *  code = the code reason to exit
	 *  force = if true the application must expect to be closed even against it's will
	 * Returns: false to refuse to exit
	 */
	protected bool exit(int code, bool force)
	{
		return force;
	}
}
code: end

struct: Menu
import: gtk.MenuItem
code: start
	/**
	 * Popups up this menu
	 * Params:
	 *  button = you can pass a button number here
	 *  activateTime = you can pass the time from an event here
	 */
	void popup(uint button, uint activateTime)
	{
		popup(null, null, null, null, button, activateTime);
	}

	/**
	 * Creates and append a submenu to this menu.
	 * This menu item that actualy has the sub menu is also created.
	 * Params:
	 *  label = the sub menu item label
	 * Returns: the new menu
	 */
	Menu appendSubmenu(string label)
	{
		MenuItem item = new MenuItem(label);
		append(item);
		Menu submenu = new Menu();
		item.setSubmenu(submenu);
		return submenu;
	}

	/** */
	void appendSubmenu(string label, Menu submenu)
	{
		MenuItem item = new MenuItem(label);
		append(item);
		item.setSubmenu(submenu);
	}

	/** */
	Menu prependSubmenu(string label)
	{
		MenuItem item = new MenuItem(label);
		prepend(item);
		Menu submenu = new Menu();
		item.setSubmenu(submenu);
		return submenu;
	}
code: end

struct: MenuBar
import: gtk.Menu
import: gtk.MenuItem
code: start
	/** */
	Menu append(string label, bool rightJustify=false)
	{
		MenuItem item = new MenuItem(label);
		super.append(item);
		item.setRightJustified(rightJustify);
		Menu menu= new Menu();
		item.setSubmenu(menu);
		return menu;
	}

	/** */
	public override void append(MenuItem item)
	{
		super.append(item);
	}
code: end

struct: MenuButton
alias: set_direction setMenuDirection
alias: get_direction getMenuDirection

struct: MenuItem
import: gtk.AccelGroup
noCode: new_with_label
noCode: new_with_mnemonic
alias: activate itemActivate
code: start
	/** store the action code passed in by the applcation */
	private string actionLabel;

	/** Gets the application set action code */
	public string getActionName()
	{
		if ( actionLabel is null )
		{
			actionLabel = "";
		}
		return actionLabel;
	}

	/**
	 * Creates a new menu item with a label and a listener and a action.
	 * used for backward compatibily with DUI.
	 */
	this(string label, void delegate(MenuItem)dlg, string action)
	{
		this(label);
		this.actionLabel = action;
		addOnActivate(dlg);
	}

	/**
	 * Creates a new Item associated with a "activate" delegate and with a action code
	 * and optionally accelGroup
	 */
	public this(void delegate(MenuItem) dlg, string label, string action,
				bool mnemonic=true,
				AccelGroup accelGroup=null,
				char accelKey='\0',
				GdkModifierType modifierType=GdkModifierType.CONTROL_MASK,
				GtkAccelFlags accelFlags=GtkAccelFlags.VISIBLE
				)
	{
		this(label, mnemonic);
		this.actionLabel = action;
		addOnActivate(dlg);
		if ( accelGroup !is null && accelKey != '\0' )
		{
			addAccelerator("activate",accelGroup,accelKey,modifierType,accelFlags);
		}
	}

	/**
	 * Creates a new Item associated with a "activate" delegate
	 */
	public this(void delegate(MenuItem) dlg, string label, bool mnemonic=true)
	{
		this(label, mnemonic);
		addOnActivate(dlg);
	}

	/**
	 * Creates a new GtkMenuItem whose child is a GtkLabel.
	 * Params:
	 *  label = the text for the label
	 *  mnemonic = if true the label
	 *  will be created using gtk_label_new_with_mnemonic(), so underscores
	 *  in label indicate the mnemonic for the menu item.
	 * Throws: ConstructionException GTK+ fails to create the object.
	 */
	public this (string label, bool mnemonic=true)
	{
		GtkMenuItem* p;

		if ( mnemonic )
		{
			// GtkWidget* gtk_menu_item_new_with_mnemonic (const gchar *label);
			p = cast(GtkMenuItem*)gtk_menu_item_new_with_mnemonic(Str.toStringz(label));
		}
		else
		{
			// GtkWidget* gtk_menu_item_new_with_label (const gchar *label);
			p = cast(GtkMenuItem*)gtk_menu_item_new_with_label(Str.toStringz(label));
		}

		if(p is null)
		{
			throw new ConstructionException("null returned by gtk_menu_item_new_with_");
		}

		this(p);

		setName(label);
	}
code: end

struct: MenuToolButton
import: gtk.Menu
noCode: get_menu
code: start
	/**
	 * Creates a new GtkMenuToolButton.
	 * The new GtkMenuToolButton will contain an icon and label from
	 * the stock item indicated by stockID.
	 * Since: 2.6
	 * Params:
	 *     stockID = the name of a stock item
	 * Throws: ConstructionException GTK+ fails to create the object.
	 */
	public this(StockID stockId)
	{
		this(cast(string)stockId);
	}

	/**
	 * Gets the GtkMenu associated with GtkMenuToolButton.
	 * Since: 2.6
	 * Params:
	 *  button = a GtkMenuToolButton
	 * Returns:
	 *  the GtkMenu associated with GtkMenuToolButton
	 */
	public Menu getMenu()
	{
		auto p =  gtk_menu_tool_button_get_menu(gtkMenuToolButton);
		if(p is null)
		{
			return null;
		}
		return new Menu(cast(GtkMenu*)p);
	}
code: end

struct: MessageDialog
import: glib.ConstructionException
import: gtk.VBox
import: gtk.Window
noCode: new
noCode: new_with_markup
noCode: get_message_area
code: start
	/**
	 * Creates a new message dialog, which is a simple dialog with an icon
	 * indicating the dialog type (error, warning, etc.) and some text the
	 * user may want to see. When the user clicks a button a "response"
	 * signal is emitted with response IDs from GtkResponseType. See
	 * GtkDialog for more details.
	 * Params:
	 *    	parent = transient parent, or NULL for none
	 *    	flags = flags
	 *    	type = type of message
	 *    	buttons= set of buttons to use
	 *    	messageFormat = printf()-style format string, or NULL
	 *    	message = the message - should be null, any formatting should be done prior to call this constructor
	 *  arguments for message_format
	 * Returns:
	 *  a new GtkMessageDialog
	 */
	public this (Window parent, GtkDialogFlags flags, GtkMessageType type, GtkButtonsType buttons, string messageFormat, string message=null )
	{
		this(parent, flags, type, buttons, false, messageFormat, message );
	}

	/**
	 * Creates a new message dialog, which is a simple dialog with an icon
	 * indicating the dialog type (error, warning, etc.) and some text which
	 * is marked up with the Pango text markup language.
	 * When the user clicks a button a "response" signal is emitted with
	 * response IDs from GtkResponseType. See GtkDialog for more details.
	 *
	 * If Markup is true special XML characters in the printf() arguments passed to this
	 * function will automatically be escaped as necessary.
	 * (See g_markup_printf_escaped() for how this is implemented.)
	 * Usually this is what you want, but if you have an existing
	 * Pango markup string that you want to use literally as the
	 * label, then you need to use gtk_message_dialog_set_markup()
	 * instead, since you can't pass the markup string either
	 * as the format (it might contain '%' characters) or as a string
	 * argument.
	 * Since 2.4
	 * Examples:
	 * --------------------
	 *  GtkWidget *dialog;
	 *  dialog = gtk_message_dialog_new (main_application_window,
	 *  GTK_DIALOG_DESTROY_WITH_PARENT,
	 *  GTK_MESSAGE_ERROR,
	 *  GTK_BUTTONS_CLOSE,
	 *  NULL);
	 *  gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (dialog),
	 *  markup);
	 * --------------------
	 * Params:
	 *  parent = transient parent, or NULL for none
	 *  flags = flags
	 *  type = type of message
	 *  buttons = set of buttons to use
	 *  messageFormat = printf()-style format string, or NULL
	 *  message = the message - should be null, any formatting should be done prior to call this constructor
	 * Throws: ConstructionException GTK+ fails to create the object.
	 */
	public this (Window parent, GtkDialogFlags flags, GtkMessageType type, GtkButtonsType buttons, bool markup, string messageFormat, string message=null )
	{
		GtkMessageDialog* p;

		if ( markup )
		{
			// GtkWidget* gtk_message_dialog_new_with_markup  (GtkWindow *parent,  GtkDialogFlags flags,  GtkMessageType type,  GtkButtonsType buttons,  const gchar *message_format,  ...);
			p = cast(GtkMessageDialog*)gtk_message_dialog_new_with_markup(
					parent is null ? null : parent.getWindowStruct(),
					flags,
					type,
					buttons,
					Str.toStringz(messageFormat),
					Str.toStringz(message),	// this should be null
					null
				);
		}
		else
		{
			// GtkWidget* gtk_message_dialog_new (GtkWindow *parent,  GtkDialogFlags flags,  GtkMessageType type,  GtkButtonsType buttons,  const gchar *message_format,  ...);
			p = cast(GtkMessageDialog*)gtk_message_dialog_new(
					parent is null ? null : parent.getWindowStruct(),
					flags,
					type,
					buttons,
					Str.toStringz(messageFormat),
					Str.toStringz(message),	// this should be null
					null
				);
		}

		if(p is null)
		{
			throw new ConstructionException("null returned by gtk_button_new()");
		}

		this(p);
	}

	/**
	 * Since 2.22
	 * Returns: A GtkVBox corresponding to the "message area" in the message_dialog. This is the box where the dialog's primary and secondary labels are packed. You can add your own extra content to that box and it will appear below those labels, on the right side of the dialog's image (or on the left for right-to-left languages). See gtk_dialog_get_content_area() for the corresponding function in the parent GtkDialog.
	 */
	public VBox getMessageArea()
	{
		// GtkWidget * gtk_message_dialog_get_message_area (GtkMessageDialog *message_dialog);
		auto p = gtk_message_dialog_get_message_area(gtkMessageDialog);
		if(p is null)
		{
			return null;
		}
		return new VBox(cast(GtkVBox*) p);
	}
code: end

struct: Notebook
import: gtk.Label
code: start
	/**
	 * Append a page with a widget and a text for a label
	 */
	public int appendPage(Widget child, string tabLabel)
	{
		return appendPage(child, new Label(tabLabel));
	}

	/** */
	void setCurrentPage(Widget child)
	{
		gtk_notebook_set_current_page(gtkNotebook,gtk_notebook_page_num(gtkNotebook, child.getWidgetStruct()));
	}
code: end

struct: Paned
code: start
	/** */
	public void add(Widget child1, Widget child2)
	{
		add1(child1);
		add2(child2);
	}
code: end

struct: Plug
import: gdk.Window : GdkWin = Window
structWrap: Gdk.Window GdkWin
alias: Window ulong

struct: PopupBox
import: gtk.MessageDialog
import: gtk.Window
code: start
	/**
	 * Create an information popup dialog.
	 * Params:
	 *  message = The message to show on the dialog
	 *  title = The title of the dialog
	 */
	public static void information(string message, string title)
	{
		information(null, message, title);
	}

	/**
	 * Create an information popup dialog.
	 * Params:
	 *  parent = The parent window of this popup dialog
	 *  message = The message to show on the dialog
	 *  title = The title of the dialog
	 */
	public static void information(Window parent, string message, string title)
	{
		MessageDialog d = new MessageDialog(parent, cast(GtkDialogFlags)0,
										MessageType.INFO,
										ButtonsType.OK ,
										message);
		d.setTitle(title);
		//d.addButton("gtk-dialog-info",GtkResponseType.GTK_RESPONSE_OK);
		d.run();
		d.destroy();
	}


	/**
	 * Create an error popup dialog.
	 * Params:
	 *  message = The message to show on the dialog
	 *  title = The title of the dialog
	 */
	public static void error(string message, string title)
	{
		error(null, message, title);
	}

	/**
	 * Create an error popup dialog.
	 * Params:
	 *  parent = The parent window of this popup dialog
	 *  message = The message to show on the dialog
	 *  title = The title of the dialog
	 */
	public static void error(Window parent, string message, string title)
	{
		MessageDialog d = new MessageDialog(parent, cast(GtkDialogFlags)0,
										MessageType.ERROR,
										ButtonsType.CANCEL ,
										message);
		d.setTitle(title);
		//d.addButton("gtk-dialog-error",ResponseType.GTK_RESPONSE_CANCEL);
		d.run();
		d.destroy();
	}



	/**
	 * Create an 'yes' or 'no' popup dialog.
	 * Params:
	 *  message = The message to show on the dialog
	 *  title = The title of the dialog
	 */
	public static bool yesNo(string message, string title)
	{
		return yesNo(null, message, title);
	}

	/**
	 * Create an 'yes' or 'no' popup dialog.
	 * Params:
	 *  parent = The parent window of this popup dialog
	 *  message = The message to show on the dialog
	 *  title = The title of the dialog
	 */
	public static bool yesNo(Window parent, string message, string title)
	{
		MessageDialog d = new MessageDialog(
				parent, cast(GtkDialogFlags)0,
				MessageType.QUESTION,
				ButtonsType.NONE,
				message);
		d.setTitle(title);
		d.addButton("gtk-no",ResponseType.NO);
		d.addButton("gtk-yes",ResponseType.YES);
		int responce = d.run();
		d.destroy();
		return responce == ResponseType.YES;
	}


	/**
	 * Create an 'yes', 'no' or 'cancel' popup dialog.
	 * Params:
	 *  message = The message to show on the dialog
	 *  title = The title of the dialog
	 */
	public static ResponseType yesNoCancel(string message, string title)
	{
		return yesNoCancel(null, message, title);
	}

	/**
	 * Create an 'yes', 'no' or 'cancel' popup dialog.
	 * Params:
	 *  parent = The parent window of this popup dialog
	 *  message = The message to show on the dialog
	 *  title = The title of the dialog
	 */
	public static ResponseType yesNoCancel(Window parent, string message, string title)
	{
		MessageDialog d = new MessageDialog(
				parent, cast(GtkDialogFlags)0,
				MessageType.QUESTION,
				ButtonsType.NONE ,
				message);
		d.setTitle(title);
		d.addButton("gtk-no",ResponseType.NO);
		d.addButton("gtk-yes",ResponseType.YES);
		d.addButton("gtk-cancel",ResponseType.CANCEL);
		ResponseType responce = cast(ResponseType)d.run();
		d.destroy();
		return responce;
	}
code: end

struct:
class: PrintOperationPreview
extend: GObject.Object
implements: PrintOperationPreview

struct: PrintUnixDialog
alias: set_settings setPrintSettings
alias: get_settings getPrintSettings

struct: RadioAction
code: start
	/**
	 * Creates a new RadioAction object. To add the action to
	 * a ActionGroup and set the accelerator for the action,
	 * call gtk.ActionGroup.ActionGroup.addActionWithAccel().
	 *
	 * Since: 2.4
	 *
	 * Params:
	 *     name    = A unique name for the action
	 *     label   = The label displayed in menu items and on buttons, or null
	 *     tooltip = A tooltip for this action, or null
	 *     stockId = The stock icon to display in widgets representing this
	 *               action, or null
	 *     value   = The value which getCurrentValue() should
	 *               return if this action is selected.
	 * Throws: ConstructionException GTK+ fails to create the object.
	 */
	public this (string name, string label, string tooltip, StockID stockId, int value)
	{
		this(name, label, tooltip, cast(string)stockId, value);
	}
code: end

struct: RadioButton
import: glib.Str
noCode: new_with_label
noCode: new_with_mnemonic
noCode: new_with_label_from_widget
noCode: new_with_mnemonic_from_widget
code: start
	/**
	 * Creates a new RadioButton with a text label.
	 * Params:
	 *  group = an existing radio button group.
	 *  label = the text label to display next to the radio button.
	 *  mnemonic = if true the label will be created using
	 *  gtk_label_new_with_mnemonic(), so underscores in label indicate the
	 *  mnemonic for the button.
	 * Throws: ConstructionException GTK+ fails to create the object.
	 */
	public this (ListSG group, string label, bool mnemonic=true)
	{
		GtkRadioButton* p;

		if ( mnemonic )
		{
			// GtkWidget* gtk_radio_button_new_with_mnemonic  (GSList *group,  const gchar *label);
			p = cast(GtkRadioButton*)gtk_radio_button_new_with_mnemonic(
						group is null ? null : group.getListSGStruct(),
						Str.toStringz(label));
		}
		else
		{
			// GtkWidget* gtk_radio_button_new_with_label (GSList *group,  const gchar *label);
			p = cast(GtkRadioButton*)gtk_radio_button_new_with_label(
						group is null ? null : group.getListSGStruct(),
						Str.toStringz(label));
		}

		if(p is null)
		{
			throw new ConstructionException("null returned by gtk_radio_button_new_");
		}

		this(p);
	}

	/**
	 * Creates a new RadioButton with a text label, adding it to the same group
	 * as group.
	 * Params:
	 *  radioButton = an existing RadioButton.
	 *  label = a text string to display next to the radio button.
	 *  mnemonic = if true the label
	 *  will be created using gtk_label_new_with_mnemonic(), so underscores
	 *  in label indicate the mnemonic for the button.
	 * Throws: ConstructionException GTK+ fails to create the object.
	 */
	public this (RadioButton radioButton, string label, bool mnemonic=true)
	{
		GtkRadioButton* p;

		if ( mnemonic )
		{
			// GtkWidget* gtk_radio_button_new_with_mnemonic_from_widget  (GtkRadioButton *group,  const gchar *label);
			p = cast(GtkRadioButton*)gtk_radio_button_new_with_mnemonic_from_widget(
						radioButton.getRadioButtonStruct(),
						Str.toStringz(label));
		}
		else
		{
			// GtkWidget* gtk_radio_button_new_with_label_from_widget  (GtkRadioButton *group,  const gchar *label);
			p = cast(GtkRadioButton*)gtk_radio_button_new_with_label_from_widget(
						radioButton.getRadioButtonStruct(),
						Str.toStringz(label));
		}

		if(p is null)
		{
			throw new ConstructionException("null returned by gtk_radio_button_new_");
		}

		this(p);
	}

	/**
	 * Creates a new RadioButton with a text label,
	 * and creates a new group.
	 * Params:
	 *  label = a text string to display next to the radio button.
	 *  mnemonic = if true the label
	 *  will be created using gtk_label_new_with_mnemonic(), so underscores
	 *  in label indicate the mnemonic for the button.
	 * Throws: ConstructionException GTK+ fails to create the object.
	 */
	public this (string label, bool mnemonic=true)
	{
		this(cast(ListSG)null, label, mnemonic);
	}
code: end

struct: RadioMenuItem
import: glib.Str
noCode: new_with_label
noCode: new_with_mnemonic
noCode: new_with_mnemonic_from_widget
noCode: new_with_label_from_widget
code: start
	/**
	 * Creates a new GtkRadioMenuItem whose child is a simple GtkLabel.
	 * The new GtkRadioMenuItem is added to the same group as group.
	 * If mnemonic is true the label will be
	 * created using gtk_label_new_with_mnemonic(), so underscores in label
	 * indicate the mnemonic for the menu item.
	 * Since 2.4
	 * Params:
	 *  group = an existing GtkRadioMenuItem
	 *  label = the text for the label
	 * Throws: ConstructionException GTK+ fails to create the object.
	 */
	public this (RadioMenuItem radioMenuItem, string label, bool mnemonic=true)
	{
		GtkRadioMenuItem* p;

		if ( mnemonic )
		{
			// GtkWidget* gtk_radio_menu_item_new_with_mnemonic_from_widget  (GtkRadioMenuItem *group,  const gchar *label);
			p = cast(GtkRadioMenuItem*)gtk_radio_menu_item_new_with_mnemonic_from_widget(
				radioMenuItem.getRadioMenuItemStruct(), Str.toStringz(label));
		}
		else
		{
			// GtkWidget* gtk_radio_menu_item_new_with_label_from_widget  (GtkRadioMenuItem *group,  const gchar *label);
			p = cast(GtkRadioMenuItem*)gtk_radio_menu_item_new_with_label_from_widget(
				radioMenuItem.getRadioMenuItemStruct(), Str.toStringz(label));
		}

		if(p is null)
		{
			throw new ConstructionException("null returned by gtk_radio_menu_item_new_with_");
		}

		this(p);
	}

	/**
	 * Creates a new GtkRadioMenuItem whose child is a simple GtkLabel.
	 * Params:
	 *  group = the group to which the radio menu item is to be attached
	 *  label = the text for the label
	 *  mnemonic = if true the label
	 *  will be created using gtk_label_new_with_mnemonic(), so underscores
	 *  in label indicate the mnemonic for the menu item.
	 * Throws: ConstructionException GTK+ fails to create the object.
	 */
	public this (ListSG group, string label, bool mnemonic=true)
	{
		GtkRadioMenuItem* p;

		if ( mnemonic )
		{
			// GtkWidget* gtk_radio_menu_item_new_with_mnemonic  (GSList *group,  const gchar *label);
			p = cast(GtkRadioMenuItem*)gtk_radio_menu_item_new_with_mnemonic(
				group is null ? null : group.getListSGStruct(), Str.toStringz(label));
		}
		else
		{
			// GtkWidget* gtk_radio_menu_item_new_with_label  (GSList *group,  const gchar *label);
			p = cast(GtkRadioMenuItem*)gtk_radio_menu_item_new_with_label(
				group is null ? null : group.getListSGStruct(), Str.toStringz(label));
		}

		if(p is null)
		{
			throw new ConstructionException("null returned by gtk_radio_menu_item_new_with_");
		}

		this(p);
	}
code: end

struct: RcStyle
code: start
	deprecated:
code: end

struct: RecentAction
code: start
	/**
	 * Creates a new RecentAction object. To add the action to
	 * a ActionGroup and set the accelerator for the action,
	 * call gtk.ActionGroup.ActionGroup.addActionwWithAccel().
	 *
	 * Since: 2.12
	 *
	 * Params:
	 *     name    = a unique name for the action
	 *     label   = the label displayed in menu items and on buttons, or null
	 *     tooltip = a tooltip for the action, or null
	 *     stockID = the stock icon to display in widgets representing the
	 *               action, or null
	 * Throws: ConstructionException GTK+ fails to create the object.
	 */
	public this (string name, string label, string tooltip, StockID stockID)
	{
		this(name, label, tooltip, cast(string)stockID);
	}

	/**
	 * Creates a new RecentAction object. To add the action to
	 * a ActionGroup and set the accelerator for the action,
	 * call gtk.ActionGroup.ActionGroup.addActionwWithAccel().
	 *
	 * Since: 2.12
	 *
	 * Params:
	 *     name    = a unique name for the action
	 *     label   = the label displayed in menu items and on buttons, or null
	 *     tooltip = a tooltip for the action, or null
	 *     stockID = the stock icon to display in widgets representing the
	 *               action, or null
	 *     manager = a GtkRecentManager, or null for using the default
	 *               RecentManager
	 * Throws: ConstructionException GTK+ fails to create the object.
	 */
	public this (string name, string label, string tooltip, StockID stockID, RecentManager manager)
	{
		this(name, label, tooltip, cast(string)stockID, manager);
	}
code: end

struct: RecentChooser
alias: set_show_numbers recentChooserSetShowNumbers
alias: get_show_numbers recentChooserGetShowNumbers

struct: RecentChooserDialog
import: glib.ConstructionException
import: gtk.RecentManager
import: gtk.Window
noCode: new
noCode: new_for_manager
code: start
	/**
	 * Creates a new GtkRecentChooserDialog with a specified recent manager.
	 * This is useful if you have implemented your own recent manager, or if you
	 * have a customized instance of a GtkRecentManager object.
	 * Since 2.10
	 * Params:
	 *  title =  Title of the dialog, or null
	 *  parent =  Transient parent of the dialog, or null,
	 *  manager =  a GtkRecentManager, or null
	 *  buttonsText = text to go in the buttons
	 *  responses = response ID's for the buttons
	 * Throws: ConstructionException GTK+ fails to create the object.
	 */
	public this (string title, Window parent, RecentManager manager,  string[] buttonsText=null, ResponseType[] responses=null )
	{
		// GtkWidget* gtk_recent_chooser_dialog_new_for_manager  (const gchar *title,  GtkWindow *parent,  GtkRecentManager *manager, const gchar *first_button_text,  ...);
		auto p = gtk_recent_chooser_dialog_new_for_manager(Str.toStringz(title), (parent is null) ? null : parent.getWindowStruct(), (manager is null) ? null : manager.getRecentManagerStruct(), null);
		if(p is null)
		{
			throw new ConstructionException("null returned by gtk_recent_chooser_dialog_new_for_manager");
		}
		this(cast(GtkRecentChooserDialog*) p);
		addButtons(buttonsText, responses);
	}

	/**
	 * Creates a new GtkRecentChooserDialog with a specified recent manager.
	 * This is useful if you have implemented your own recent manager, or if you
	 * have a customized instance of a GtkRecentManager object.
	 * Since 2.10
	 * Params:
	 *  title =  Title of the dialog, or null
	 *  parent =  Transient parent of the dialog, or null,
	 *  manager =  a GtkRecentManager, or null
	 *  stockIDs = stockIDs of the buttons
	 *  responses = response ID's for the buttons
	 * Throws: ConstructionException GTK+ fails to create the object.
	 */
	public this (string title, Window parent, RecentManager manager,  StockID[] stockIDs, ResponseType[] responses=null )
	{
		// GtkWidget* gtk_recent_chooser_dialog_new_for_manager  (const gchar *title,  GtkWindow *parent,  GtkRecentManager *manager, const gchar *first_button_text,  ...);
		auto p = gtk_recent_chooser_dialog_new_for_manager(Str.toStringz(title), (parent is null) ? null : parent.getWindowStruct(), (manager is null) ? null : manager.getRecentManagerStruct(), null);
		if(p is null)
		{
			throw new ConstructionException("null returned by gtk_recent_chooser_dialog_new_for_manager");
		}
		this(cast(GtkRecentChooserDialog*) p);
		addButtons(stockIDs, responses);
	}
code: end

struct: ScrolledWindow
code: start
	/** */
	public this()
	{
		this(null, null);
	}

	/** */
	public this(Widget widget)
	{
		this();
		add(widget);
	}

	/**
	 * Creates a new Scrolled window and set the policy type
	 * Params:
	 *  hPolicy = the horizontal policy
	 *  vPolicy = the vertical policy
	 */
	this(PolicyType hPolicy, PolicyType vPolicy)
	{
		this();
		setPolicy(hPolicy, vPolicy);
	}
code: end

struct: SelectionData
noCode: get_data
code: start
	/**
	 * Retrieves the raw data of the selection.
	 *
	 * Return: the raw data of the selection.
	 *
	 * Since: 2.14
	 */
	public char* getData()
	{
		return gtk_selection_data_get_data(gtkSelectionData);
	}
code: end

struct: Socket
alias: Window ulong

struct: Statusbar
noCode: get_message_area
code: start
	/**
	 * Retrieves the box containing the label widget.
	 * Since 2.20
	 * Returns: a GtkBox. [transfer none]
	 */
	public Box getMessageArea()
	{
		auto p = gtk_statusbar_get_message_area(gtkStatusbar);
		if(p is null)
		{
			return null;
		}
		return new Box(cast(GtkBox*) p);
	}
code: end

struct: StatusIcon
noCode: new_from_stock
noCode: new_from_file
noCode: new_from_icon_name
code: start
	/**
	 * Creates a status icon displaying a stock icon. Sample stock icon
	 * names are StockID.OPEN, StockID.QUIT. You can register your
	 * own stock icon names, see gtk_icon_factory_add_default() and
	 * gtk_icon_factory_add().
	 * Since 2.10
	 * Params:
	 *  stock_id = a stock icon id
	 * Returns:
	 *  a new GtkStatusIcon
	 * Throws: ConstructionException GTK+ fails to create the object.
	 */
	public this (StockID stockID)
	{
		auto p = gtk_status_icon_new_from_stock(Str.toStringz(stockID));
		if(p is null)
		{
			throw new ConstructionException("null returned by gtk_status_icon_new_from_stock");
		}
		this(cast(GtkStatusIcon*)p);
	}

	/**
	 * Creates a status icon displaying an icon from the current icon theme.
	 * If the current icon theme is changed, the icon will be updated
	 * appropriately.
	 * Since 2.10
	 * Params:
	 *  iconName =  an icon name
	 *  loadFromFile = treat iconName as a filename and load that image
	 *  with gtk_status_icon_new_from_file.
	 * Throws: ConstructionException GTK+ fails to create the object.
	 */
	public this (string iconName, bool loadFromFile = false)
	{
		//TODO: look at a better way to do this.
		GtkStatusIcon* p;

		if(loadFromFile)
		{
			p = cast(GtkStatusIcon*)gtk_status_icon_new_from_file(Str.toStringz(iconName));
		}
		else
		{
			p = cast(GtkStatusIcon*)gtk_status_icon_new_from_icon_name(Str.toStringz(iconName));
		}

		if(p is null)
		{
			throw new ConstructionException("null returned by gtk_status_icon_new_from_");
		}

		this(p);
	}
code: end

struct: Style
code: start
	//TODO:
	//deprecated:
code: end

struct: StyleProperties
alias: setProperty setStyleProperty
alias: setValist setStyleValist
alias: getProperty getStyleProperty
alias: getValist getStyleValist

struct: SymbolicColor
noCode: new_shade
noCode: new_alpha
code: start
	/**
	 * Creates a symbolic color defined as a shade of another color.
	 * A factor > 1.0 would resolve to a brighter or more transparent color,
	 * while < 1.0 would resolve to a darker or more opaque color.
	 *
	 * Params:
	 *     color    = another GtkSymbolicColor.
	 *     factor   = shading factor to apply to color.
	 *     useAlpha = if true change the relative alpha value of the color,
	 *                otherwise change the shade.
	 *
	 * Throws: ConstructionException GTK+ fails to create the object.
	 */
	public this (SymbolicColor color, double factor, bool useAlpha = true)
	{
		GtkSymbolicColor* p;

		if ( useAlpha )
		{
			p = gtk_symbolic_color_new_alpha((color is null) ? null : color.getSymbolicColorStruct(), factor);
		}
		else
		{
			p = gtk_symbolic_color_new_shade((color is null) ? null : color.getSymbolicColorStruct(), factor);
		}

		if(p is null)
		{
			throw new ConstructionException("null returned by gtk_symbolic_color_new_shade((color is null) ? null : color.getSymbolicColorStruct(), factor)");
		}

		this(cast(GtkSymbolicColor*) p);
	}
code: end

struct: Table
import: glib.ConstructionException
noCode: new
code: start
	int row;
	int col;
	int maxRows;
	int maxCols;

	public AttachOptions defaultXOption = AttachOptions.SHRINK;
	public AttachOptions defaultYOption = AttachOptions.SHRINK;

	/**
	 * Removes all children and resizes the table to 1,1
	 */
	override void removeAll()
	{
		super.removeAll();
		resize(1,1);

		row = 0;
		col = 0;
		maxRows = 1;
		maxCols = 1;
	}

	/**
	 * Used to create a new table widget. An initial size must be given by
	 * specifying how many rows and columns the table should have, although
	 * this can be changed later with gtk_table_resize(). rows and columns
	 * must both be in the range 0 .. 65535.
	 * Params:
	 *  rows = The number of rows the new table should have.
	 *  columns = The number of columns the new table should have.
	 *  homogeneous = If set to TRUE, all table cells are resized to the size of the cell
	 *  containing the largest widget.
	 * Throws: ConstructionException GTK+ fails to create the object.
	 */
	public this (uint rows, uint columns, int homogeneous)
	{
		auto p = gtk_table_new(rows, columns, homogeneous);

		if(p is null)
		{
			throw new ConstructionException("null returned by gtk_table_new");
		}

		this(cast(GtkTable*) p);

		row = 0;
		col = 0;
		maxRows = rows;
		maxCols = columns;
	}


	/**
	 * Attach a new widget creating a new row if necessary
	 */
	void attach(Widget child)
	{
		attach(child, col, col + 1, row, row + 1,
				defaultXOption, defaultYOption,
				getDefaultColSpacing(), getDefaultRowSpacing());
		++col;
		if (col >= maxCols)
		{
			col = 0;
			++row;
		}
	}
code: end

struct: Testing
code: start
	/**
	 * This function is used to initialize a GTK+ test program.
	 * It will in turn call testInit() and init() to
	 * properly initialize the testing framework and graphical toolkit.
	 * It'll also set the program's locale to "C" and prevent loading of
	 * rc files and Gtk+ modules. This is done to make the test program environments as deterministic as possible.
	 * Like init() any known arguments will be processed and stripped from and argv.
	 * Params:
	 *  argv = The argv parameter of main(). Any parameters understood by testInit() or init() are stripped before return.
	 */
	public static void testInit(ref string[] argv)
	{
		// void gtk_test_init(int *argcp, char ***argvp, ...);
		char** outargv = Str.toStringzArray(argv);
		int argc = cast(int) argv.length;

		gtk_test_init(&argc, &outargv, null);

		argv = Str.toStringArray(outargv);
	}
code: end

struct: TextBuffer
import: core.vararg
import: gdk.Color
import: gtkc.gobject
import: pango.PgFontDescription
import: pango.PgTabArray
import: std.stdio
array: insert text len
array: insert_at_cursor text len
array: insert_interactive text len
array: insert_interactive_at_cursor text len
array: set_text text len
noCode: insert_with_tags
noCode: insert_with_tags_by_name
noCode: create_tag
code: start
	/**
	 * Inserts text into buffer at iter, applying the list of tags to
	 * the newly-inserted text. The last tag specified must be NULL to
	 * terminate the list. Equivalent to calling gtk_text_buffer_insert(),
	 * then gtk_text_buffer_apply_tag() on the inserted text;
	 * gtk_text_buffer_insert_with_tags() is just a convenience function.
	 * Params:
	 *  iter = an iterator in buffer
	 *  text = UTF-8 text
	 *  tags = list of tags to apply
	 */
	public void insertWithTags(TextIter iter, string text, TextTag[] tags ... )
	{
		int startOffset = iter.getOffset();

		insert(iter, text);

		if ( tags.length == 0 )
			return;

		TextIter start = new TextIter();
		getIterAtOffset(start, startOffset);

		foreach( tag; tags )
		{
			applyTag(tag, start, iter);
		}
	}

	/**
	 * Same as gtk_text_buffer_insert_with_tags(), but allows you
	 * to pass in tag names instead of tag objects.
	 * Params:
	 *  iter = position in buffer
	 *  text = UTF-8 text
	 *  tags = tag names
	 */
 	public void insertWithTagsByName(TextIter iter, string text, string[] tags ... )
	{
		int startOffset = iter.getOffset();

		insert(iter, text);

		if ( tags.length == 0 )
			return;

		TextIter start = new TextIter();
		getIterAtOffset(start, startOffset);

		foreach( tag; tags )
		{
			applyTagByName(tag, start, iter);
		}
	}

	/**
	 * Creates a tag and adds it to the tag table for buffer. Equivalent to
	 * adding a new tag to the buffer's tag table.
	 *
	 * If tagName is null, the tag is anonymous.
	 *
	 * If tagName is non-NULL, a tag called tagName must not already exist
	 * in the tag table for this buffer.
	 *
	 * Params:
	 *     tagName = the name for the new tag.
	 *     ...     = A list of property names and there values.
	 */
	TextTag createTag(string tagName, ...)
	{
		TextTag tag = new TextTag(gtk_text_buffer_create_tag(gtkTextBuffer, Str.toStringz(tagName), null, null));

		for (size_t i = 0; i < _arguments.length; i+=2)
		{
			//TODO: Add a proper eception type for this.
			if ( _arguments[i] != typeid(string) )
				throw new Exception("TextBuffer.CreateTag: The property name must be a string.");

			string name = va_arg!(string)(_argptr);

			if ( _arguments[i+1] == typeid(bool) ||
				_arguments[i+1] == typeid(int) ||
				_arguments[i+1] == typeid(GtkJustification) ||
				_arguments[i+1] == typeid(GtkTextDirection) ||
				_arguments[i+1] == typeid(GtkWrapMode) ||
				_arguments[i+1] == typeid(PangoStretch) ||
				_arguments[i+1] == typeid(PangoStyle) ||
				_arguments[i+1] == typeid(PangoUnderline) ||
				_arguments[i+1] == typeid(PangoVariant) ||
				_arguments[i+1] == typeid(PangoWeight) )
			{

				g_object_set(tag.getObjectGStruct(), Str.toStringz(name), va_arg!(int)(_argptr), null);
			}
			else if ( _arguments[i+1] == typeid(Color) )
			{
				g_object_set(tag.getObjectGStruct(), Str.toStringz(name), va_arg!(Color)(_argptr).getColorStruct(), null);
			}
			else if ( _arguments[i+1] == typeid(double) )
			{
				g_object_set(tag.getObjectGStruct(), Str.toStringz(name), va_arg!(double)(_argptr), null);
			}
			else if ( _arguments[i+1] == typeid(const(double)) )
			{
				g_object_set(tag.getObjectGStruct(), Str.toStringz(name), va_arg!(double)(_argptr), null);
			}
			else if ( _arguments[i+1] == typeid(PgFontDescription) )
			{
				g_object_set(tag.getObjectGStruct(), Str.toStringz(name), va_arg!(PgFontDescription)(_argptr).getPgFontDescriptionStruct(), null);
			}
			else if ( _arguments[i+1] == typeid(PgTabArray) )
			{
				g_object_set(tag.getObjectGStruct(), Str.toStringz(name), va_arg!(PgTabArray)(_argptr).getPgTabArrayStruct(), null);
			}
			else if ( _arguments[i+1] == typeid(string) )
			{
				g_object_set(tag.getObjectGStruct(), Str.toStringz(name), Str.toStringz(va_arg!(string)(_argptr)), null);
			}
			else
			{
				stderr.writefln("TextBuffer.CreateTag: Unsupported type: \"%s\" for property: \"%s\"", _arguments[i+1], name);

				//TODO: throw segfaults, druntime bug?
				throw new Exception("TextBuffer.CreateTag: Unsupported type: \""~_arguments[i+1].toString()~"\" for property: \""~name~"\"");
			}
		}

		return tag;
	}

	/**
	 * Obtain the entire text
	 * Returns: The text string
	 */
	string getText()
	{
		TextIter start = new TextIter();
		TextIter end = new TextIter();
		getBounds(start,end);
		return Str.toString(gtk_text_buffer_get_slice(gtkTextBuffer, start.getTextIterStruct(), end.getTextIterStruct(), true));
	}
code: end

struct: TextIter
code: start
	/** */
	public this()
	{
		this(new GtkTextIter);
	}
code: end

struct: TextView
noCode: get_hadjustment
noCode: get_vadjustment
code: start
	/**
	 * Get the text line at the pixel y
	 */
	string getLineTextAt(int y)
	{

		TextIter iter = new TextIter();
		int windowX;
		int windowY;
		bufferToWindowCoords(TextWindowType.TEXT, 0, y, windowX, windowY);

		gtk_text_view_get_line_at_y(gtkTextView, iter.getTextIterStruct(), y+y-windowY, null);

		TextIter iterEnd = new TextIter();
		TextBuffer buffer = getBuffer();
		buffer.getIterAtOffset(iterEnd, iter.getOffset()+iter.getCharsInLine());
		return buffer.getText(iter, iterEnd, false);
	}

	/**
	 * Simply appends some on the cursor position
	 * Params:
	 *  text = the text to append
	 */
	void insertText(string text)
	{
		TextBuffer buf = getBuffer();
		buf.insertAtCursor(text);
	}

	/**
	 * Simply appends some text to this view
	 * Params:
	 *  text = the text to append
	 */
	void appendText(string text, bool ensureVisible=true)
	{
		TextBuffer buf = getBuffer();
		TextIter iter = new TextIter();
		buf.getEndIter(iter);
		buf.insert(iter, text);
		if ( ensureVisible )
		{
			double within_margin = 0.0;
			bool use_align = false;
			double xalign = 0.0;
			double yalign = 0.0;
			scrollToMark(buf.createMark("",iter,true), within_margin, use_align, xalign, yalign);
		}
	}
code: end

struct: ToggleAction
code: start
	/**
	 * Creates a new ToggleAction object. To add the action to
	 * a ActionGroup and set the accelerator for the action,
	 * call gtk.ActionGroup.ActionGroup.addActionWithAccel().
	 *
	 * Since: 2.4
	 *
	 * Params:
	 *     name    = A unique name for the action
	 *     label   = The label displayed in menu items and on buttons, or null
	 *     tooltip = A tooltip for the action, or null
	 *     stockId = The stock icon to display in widgets representing the
	 *               action, or null
	 * Throws: ConstructionException GTK+ fails to create the object.
	 */
	public this (string name, string label, string tooltip, StockID stockId)
	{
		this(name, label, tooltip, cast(string)stockId);
	}
code: end

struct: ToggleButton
import: glib.Str
noCode: new_with_label
noCode: new_with_mnemonic
code: start
	/**
	 * Creates a new toggle button with a text label.
	 * Params:
	 *  label = a string containing the message to be placed in the toggle button.
	 *  mnemonic =  if true the label
	 *  will be created using gtk_label_new_with_mnemonic(), so underscores
	 *  in label indicate the mnemonic for the button.
	 * Throws: ConstructionException GTK+ fails to create the object.
	 */
	public this (string label, bool mnemonic=true)
	{
		GtkToggleButton* p;

		if ( mnemonic )
		{
			// GtkWidget* gtk_toggle_button_new_with_mnemonic  (const gchar *label);
			p = cast(GtkToggleButton*)gtk_toggle_button_new_with_mnemonic(Str.toStringz(label));
		}
		else
		{
			// GtkWidget* gtk_toggle_button_new_with_label  (const gchar *label);
			p = cast(GtkToggleButton*)gtk_toggle_button_new_with_label(Str.toStringz(label));
		}

		if(p is null)
		{
			throw new ConstructionException("null returned by gtk_toggle_button_new_");
		}

		this(p);
	}
code: end

struct: ToggleToolButton
code: start
	/**
	 * Creates a new GtkToggleToolButton containing the image and text
	 * from a stock item.
	 */
	public this(StockID stockId)
	{
		this(cast(string)stockId);
	}
code: end

struct: Toolbar
noCode: get_icon_size
noCode: get_relief_style
noCode: insert
alias: get_style getToolbarStyle
code: start
	/**
	 * Insert a GtkToolItem into the toolbar at position pos.
	 * If pos is 0 the item is prepended to the start of the toolbar. If pos is negative, the item is appended to the end of the toolbar.
	 * Since 2.4
	 * Params:
	 * toolItem  = a GtkToolItem
	 * pos = the position of the new item
	 */
	public void insert(ToolItem toolItem, int pos=-1)
	{
		gtk_toolbar_insert(gtkToolbar, toolItem.getToolItemStruct(), pos);
	}
code: end

struct: ToolButton
code: start
	/** */
	public this (StockID stockID)
	{
		this(cast(string)stockID);
	}
code: end

struct: ToolItemGroup
code: start
	/**
	 * Retrieves the current orientation for the tool shell. Tool items must not
	 * call this function directly, but rely on gtk_tool_item_get_orientation()
	 * instead.
	 * Since 2.14
	 * Returns: the current orientation of shell
	 */
	public GtkOrientation getOrientation()
	{
		return gtk_tool_shell_get_orientation(getToolShellStruct());
	}
code: end

struct: ToolPalette
noCode: get_hadjustment
noCode: get_vadjustment
alias: get_style getToolbarStyle

struct: ToolShell
alias: get_style getToolBarStyle
noCode: get_orientation
interfaceCode: start
	/**
	 * Retrieves the current orientation for the tool shell. Tool items must not
	 * call this function directly, but rely on gtk_tool_item_get_orientation()
	 * instead.
	 * Since: 2.14
	 * Returns: the current orientation of shell
	 */
	public GtkOrientation getOrientation();
interfaceCode: end

struct: Tooltip
code: start
	/**
	 * Sets the icon of the tooltip (which is in front of the text) to be
	 * the stock item indicated by stockID with the size indicated by size.
	 */
	void setIcon(StockID stockID, GtkIconSize size)
	{
		setIconFromStock(cast(string)stockID, size);
	}
code: end

struct: TreeIter
import: glib.ConstructionException
import: glib.Str
import: gtk.TreeIterError
import: gtk.TreeModelIF
import: gtk.TreePath
import: gobject.Value
noCode: copy
noCode: free
code: start
	/**
	 * this will be set only when the iter
	 * is created from the model.
	 */
	GtkTreeModel* gtkTreeModel;

	/** */
	public void setModel(GtkTreeModel* gtkTreeModel)
	{
		this.gtkTreeModel = gtkTreeModel;
	}

	/** */
	public void setModel(TreeModelIF treeModel)
	{
		this.gtkTreeModel = treeModel.getTreeModelStruct();
	}

	/**
	 * Throws: ConstructionException GTK+ fails to create the object.
	 */
	public this(TreeModelIF treeModel, string treePath)
	{
		this(treeModel, new TreePath(treePath));
	}

	/**
	 * Throws: ConstructionException GTK+ fails to create the object.
	 */
	public this(TreeModelIF treeModel, TreePath treePath)
	{
		this();
		setModel(treeModel);
		if ( !gtk_tree_model_get_iter_from_string(
				treeModel.getTreeModelStruct(),
				getTreeIterStruct(), Str.toStringz(treePath.toString())) )
		{
			throw new ConstructionException("null returned by gtk_tree_model_get_iter_from_string");
		}
	}

	/**
	* creates a new tree iteractor.
	* used TreeView.createIter and TreeView.append() to create iteractor for a tree or list
	*/
	this()
	{
		this(new GtkTreeIter);
	}

	/**
	 * Creates a dynamically allocated tree iterator as a copy of iter.
	 */
	TreeIter copy(TreeIter iter)
	{
		TreeIter cp = new TreeIter();
		*(cp.gtkTreeIter) = *(iter.gtkTreeIter);

		return cp;
	}

	/**
	 * Get Value
	 * Params:
	 *  column =
	 *  value =
	 */
	void getValue(int column, Value value)
	{
		if ( gtkTreeModel  is  null )
		{
			throw new TreeIterError("getValue","Tree model not set");
		}
		gtk_tree_model_get_value(gtkTreeModel, gtkTreeIter, column, value.getValueStruct());
	}

	/**
	 * Get the value of a column as a string
	 * Params:
	 *  column = the column number
	 * Returns: a string representing the value of the column
	 */
	string getValueString(int column)
	{
		if ( gtkTreeModel  is  null )
		{
			throw new TreeIterError("getValueString","Tree model not set");
		}
		Value value = new Value();
		gtk_tree_model_get_value(gtkTreeModel, gtkTreeIter, column, value.getValueStruct());
		//printf("TreeIter.getValuaString = %.*s\n", value.getString().toString());
		return value.getString();
	}

	/**
	 * Get the value of a column as an int
	 * Params:
	 *  column = the column number
	 * Returns: a string representing the value of the column
	 */
	int getValueInt(int column)
	{
		if ( gtkTreeModel  is  null )
		{
			throw new TreeIterError("getValueInt", "Tree model not set");
		}
		Value value = new Value();
		gtk_tree_model_get_value(gtkTreeModel, gtkTreeIter, column, value.getValueStruct());
		return value.getInt();
	}

	/** */
	TreePath getTreePath()
	{
		if ( gtkTreeModel  is  null )
		{
			throw new TreeIterError("getTreePath","Tree model not set");
		}
		return new TreePath(gtk_tree_model_get_path(gtkTreeModel, gtkTreeIter));
	}

	/**
	 * This return the path visible to the user.
	 */
	string getVisiblePath(string separator)
	{
		string vPath;
		if ( gtkTreeModel  is  null )
		{
			throw new TreeIterError("getVisiblePath", "Tree model not set");
		}

		vPath = getValueString(0);
		TreeIter parent = getParent();
		while ( parent !is  null )
		{
			//printf("TreeIter.getVisiblePath parent = %.*s\n",parent.getValueString(0).toString());
			vPath = parent.getValueString(0) ~ separator ~ vPath;
			parent = parent.getParent();
		}

		//printf("TreeIter.getVisiblePath = %.*s\n", vPath.toString());

		return vPath;
	}

	/**
	 * Gets the parent of this iter
	 * Returns: the parent iter or null if can't get parent or an error occured
	 */
	TreeIter getParent()
	{
		if ( gtkTreeModel  is  null )
		{
			throw new TreeIterError("getParent", "Tree model not set");
		}
		TreeIter parent = new TreeIter();
		bool gotParent = gtk_tree_model_iter_parent(gtkTreeModel, parent.getTreeIterStruct(), gtkTreeIter) == 0 ? false : true;
		if ( !gotParent )
		{
			return null;
		}
		parent.setModel(gtkTreeModel);
		return parent;
	}

	/** */
	TreeIter getGrandParent()
	{
		if ( gtkTreeModel  is  null )
		{
			throw new TreeIterError("getGrandParent", "Tree model not set");
		}
		TreeIter grandParent = this;
		TreeIter parent = grandParent.getParent();
		while ( parent !is null )
		{
			grandParent = parent;
			parent = grandParent.getParent();
		}

		return grandParent;
	}

	/** A unique stamp to catch invalid iterators */
	public int stamp()
	{
		return gtkTreeIter.stamp;
	}

	/** Ditto */
	public void stamp(int stamp)
	{
		gtkTreeIter.stamp = stamp;
	}

	/** Model specific data */
	public void* userData()
	{
		return gtkTreeIter.userData;
	}

	/** Ditto */
	public void userData(void* data)
	{
		gtkTreeIter.userData = data;
	}

	public struct IterData
	{
		/// Data fields.
		union
		{
			int     dataInt;
			long    dataLong;
			double  dataFloat;
			double  dataDouble;
			string  dataString;

			void*   dataUser;
		}

		TypeInfo type = typeid(void);
	}

	/**
	 * setUserData and getUserData provide simple boxing
	 * around the userData field in the TreeIter struct.
	 * Throws: TreeIterError for unsupported types or a type mismatch.
	 * Example:
	 * ---
	 * Treeiter iter = new TreeIter();
	 *
	 * iter.setUserData(20);
	 * int i = iter.getUserData!(int)();
	 * ---
	 */
	public void setUserData(T)(T data)
	{
		IterData* itData = new IterData;
		itData.type = typeid(T);

		static if(is(T == int))
		{
			itData.dataInt = data;
		}
		else static if(is(T == long))
		{
			itData.dataLong = data;
		}
		else static if(is(T == float))
		{
			itData.dataFloat = data;
		}
		else static if(is(T == double))
		{
			itData.dataDouble = data;
		}
		else static if(is(T == string))
		{
			itData.dataString = data;
		}
		else static if(is(T == void*))
		{
			itData.dataUser = data;
		}
		else
		{
			pragma(msg, "IterData Type not Supported");

			throw new TreeIterError("getUserData", "IterData Type not Supported");
		}

		gtkTreeIter.userData = itData;
	}

	/** Ditto */
	public T getUserData(T)()
	{
		IterData* itData = cast(IterData*)gtkTreeIter.userData;

		static if(is(T == int))
		{
			if(itData.type is typeid(T))
			{
				return itData.dataInt;
			}
			else
			{
				throw new TreeIterError("getUserData", "IterData is not: int");
			}
		}
		else static if(is(T == long))
		{
			if(itData.type is typeid(T))
			{
				return itData.dataLong;
			}
			else
			{
				throw new TreeIterError("getUserData", "IterData is not: long");
			}
		}
		else static if(is(T == float))
		{
			if(itData.type is typeid(T))
			{
				return itData.dataFloat;
			}
			else
			{
				throw new TreeIterError("getUserData", "IterData is not: float");
			}
		}
		else static if(is(T == double))
		{
			if(itData.type is typeid(T))
			{
				return itData.dataDouble;
			}
			else
			{
				throw new TreeIterError("getUserData", "IterData is not: double");
			}
		}
		else static if(is(T == string))
		{
			if(itData.type is typeid(T))
			{
				return itData.dataString;
			}
			else
			{
				throw new TreeIterError("getUserData", "IterData is not: string");
			}
		}
		else static if(is(T == void*))
		{
			if(itData.type is typeid(T))
			{
				return itData.dataUser;
			}
			else
			{
				throw new TreeIterError("getUserData", "IterData is not: void*");
			}
		}
		else
		{
			pragma(msg, "IterData Type not Supported");

			throw new TreeIterError("getUserData", "IterData Type not Supported");
		}
	}
code: end

struct:
class: TreeIterError
cType:
extend: Exception
code: start
	/**
	 * A TreeIter error.
	 * thrown<br>
	 * - trying to access a method that requires a tree model and the tree model was never set
	 */
	public this(string method, string message)
	{
		super("TreeIter."~method~" : "~message);
	}
code: end

struct: TreeModel
move: filter_new TreeModelFilter new
move: sort_new_with_model TreeModelSort new_with_model
import: gobject.Value
noCode: get_value
noCode: get_iter
interfaceCode: start
	/**
	 * Get the value of a column as a char array.
	 * this is the same calling getValue and get the string from the value object
	 */
	string getValueString(TreeIter iter, int column);

	/**
	 * Get the value of a column as a char array.
	 * this is the same calling getValue and get the int from the value object
	 */
	int getValueInt(TreeIter iter, int column);

	/**
	 * Sets iter to a valid iterator pointing to path.
	 * Params:
	 *  iter = The uninitialized GtkTreeIter.
	 *  path = The GtkTreePath.
	 * Returns:
	 *  TRUE, if iter was set.
	 */
	public int getIter(TreeIter iter, TreePath path);

	/**
	 * Initializes and sets value to that at column.
	 * When done with value, g_value_unset() needs to be called
	 * to free any allocated memory.
	 * Params:
	 * iter = The GtkTreeIter.
	 * column = The column to lookup the value at.
	 * value = (inout) (transfer none) An empty GValue to set.
	 */
	public Value getValue(TreeIter iter, int column, Value value = null);
interfaceCode: end
code: start
	/**
	 * Get the value of a column as a char array.
	 * this is the same calling getValue and get the string from the value object
	 */
	string getValueString(TreeIter iter, int column)
	{
		Value value = getValue(iter, column);
		return value.getString();
	}

	/**
	 * Get the value of a column as a char array.
	 * this is the same calling getValue and get the int from the value object
	 */
	int getValueInt(TreeIter iter, int column)
	{
		Value value = getValue(iter, column);
		return value.getInt();
	}

	/**
	 * Sets iter to a valid iterator pointing to path.
	 * Params:
	 *  iter = The uninitialized GtkTreeIter.
	 *  path = The GtkTreePath.
	 * Returns:
	 *  TRUE, if iter was set.
	 */
	public int getIter(TreeIter iter, TreePath path)
	{
		iter.setModel(this);
		return gtk_tree_model_get_iter(
				getTreeModelStruct(),
				(iter is null) ? null : iter.getTreeIterStruct(),
				(path is null) ? null : path.getTreePathStruct());
	}

	/**
	 * Initializes and sets value to that at column.
	 * When done with value, g_value_unset() needs to be called
	 * to free any allocated memory.
	 * Params:
	 * iter = The GtkTreeIter.
	 * column = The column to lookup the value at.
	 * value = (inout) (transfer none) An empty GValue to set.
	 */
	public Value getValue(TreeIter iter, int column, Value value = null)
	{
		if ( value is null )
			value = new Value();

		gtk_tree_model_get_value(getTreeModelStruct(), (iter is null) ? null : iter.getTreeIterStruct(), column, (value is null) ? null : value.getValueStruct());

		return value;
	}
code: end

struct:
class: TreeModel
namespace:
import: glib.Str
import: gobject.Type
import: gobject.ObjectG
import: gobject.Signals
import: gobject.Value
import: gtk.TreeIter
import: gtk.TreePath
import: gtk.TreeModelT
import: gtk.TreeModelIF
import: gtkc.gobject
import: gtkd.Loader
import: gtkd.paths
code: start
struct CustomTreeModelClass
{
	GObjectClass parentClass;
}

/**
 */
public class TreeModel : ObjectG, TreeModelIF
{
	static GObjectClass* parentClass = null;

	/** the main Gtk struct */
	protected GtkTreeModel* gtkTreeModel;

	// Minimal implementation.
	mixin TreeModelT!(GtkTreeModel);

	/** the main Gtk struct as a void* */
	protected override void* getStruct()
	{
		return cast(void*)gtkTreeModel;
	}

	public this ()
	{
		auto p =  super(customTreeModelgetType(), null);
		gtkTreeModel = cast(GtkTreeModel*) p.getObjectGStruct();

		setDataFull("customTreeModel", cast(void*)this, cast(GDestroyNotify)&destroyNotify);
	}

	/**
	 * Sets our main struct and passes it to the parent class
	 */
	public this (GtkTreeModel* gtkTreeModel, bool ownedRef = false)
	{
		super(cast(GObject*)gtkTreeModel, ownedRef);
		this.gtkTreeModel = gtkTreeModel;
	}


	extern(C)
	{
		/*
		 *  here we register our new type and its interfaces
		 *  with the type system. If you want to implement
		 *  additional interfaces like GtkTreeSortable, you
		 *  will need to do it here.
		 */

		static GType customTreeModelgetType()
		{
			GType customTreeModelType = Type.fromName("CustomTreeModel");

			/* Some boilerplate type registration stuff */
			if (customTreeModelType == GType.INVALID)
			{
				GTypeInfo customTreeModelInfo =
				{
					CustomTreeModelClass.sizeof,                   /* class size */
					null,                                          /* base_init */
					null,                                          /* base_finalize */
					cast(GClassInitFunc) &customTreeModelClassInit,/* class init function */
					null,                                          /* class finalize */
					null,                                          /* class_data */
					GObject.sizeof,                                /* instance size */
					0,                                             /* n_preallocs */
					//cast(GInstanceInitFunc) &customTreeModelInit   /* instance init */
					null
				};
				GInterfaceInfo treeModelInfo =
				{
					cast(GInterfaceInitFunc) &customTreeModelInit,
					null,
					null
				};

				/* First register the new derived type with the GObject type system */
				customTreeModelType = Type.registerStatic (GType.OBJECT, "CustomTreeModel",
				&customTreeModelInfo, cast(GTypeFlags)0);

				/* Now register our GtkTreeModel interface with the type system */
				Type.addInterfaceStatic (customTreeModelType, gtk_tree_model_get_type() /*GTK_TYPE_TREE_MODEL*/, &treeModelInfo);
			}

			return customTreeModelType;
		}

		/*
		 *  boilerplate GObject/GType stuff.
		 *  Init callback for the type system,
		 *  called once when our new class is created.
		 */

		static void customTreeModelClassInit (void* klass)
		{
			GObjectClass* objectClass;

			parentClass = cast(GObjectClass*) g_type_class_peek_parent(klass);
			objectClass = cast(GObjectClass*) klass;

			objectClass.finalize = &customTreeModelFinalize;
		}

		/*
		 *  init callback for the interface registration
		 *  in customTreeModelGetType. Here we override
		 *  the GtkTreeModel interface functions that
		 *  we implement.
		 */

		static void customTreeModelInit (GtkTreeModelIface *iface)
		{
			iface.getFlags      = &customTreeModelGetFlags;
			iface.getNColumns   = &customTreeModelGetNColumns;
			iface.getColumnType = &customTreeModelGetColumnType;
			iface.getIter       = &customTreeModelGetIter;
			iface.getPath       = &customTreeModelGetPath;
			iface.getValue      = &customTreeModelGetValue;
			iface.iterNext      = &customTreeModelIterNext;
			iface.iterChildren  = &customTreeModelIterChildren;
			iface.iterHasChild  = &customTreeModelIterHasChild;
			iface.iterNChildren = &customTreeModelIterNChildren;
			iface.iterNthChild  = &customTreeModelIterNthChild;
			iface.iterParent    = &customTreeModelIterParent;
		}

		/*
		 *  this is called just before a custom list is
		 *  destroyed. Free dynamically allocated memory here.
		 */

		static void customTreeModelFinalize (GObject *object)
		{
			/* must chain up - finalize parent */
			parentClass.finalize(object);
		}

		static GtkTreeModelFlags customTreeModelGetFlags(GtkTreeModel *tree_model)
		{
			auto tm = ObjectG.getDObject!(TreeModel)(tree_model);

			return tm.getFlags();
		}

		static int customTreeModelGetNColumns(GtkTreeModel *tree_model)
		{
			auto tm = ObjectG.getDObject!(TreeModel)(tree_model);

			return tm.getNColumns();
		}

		static GType customTreeModelGetColumnType(GtkTreeModel *tree_model, int index)
		{
			auto tm = ObjectG.getDObject!(TreeModel)(tree_model);

			return tm.getColumnType(index);
		}

		static int customTreeModelGetIter(GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreePath *path)
		{
			auto tm = ObjectG.getDObject!(TreeModel)(tree_model);

			return tm.getIter(ObjectG.getDObject!(TreeIter)(iter), ObjectG.getDObject!(TreePath)(gtk_tree_path_copy(path)));
		}

		static GtkTreePath* customTreeModelGetPath(GtkTreeModel *tree_model, GtkTreeIter *iter)
		{
			auto tm = ObjectG.getDObject!(TreeModel)(tree_model);
			TreePath path = tm.getPath(ObjectG.getDObject!(TreeIter)(iter));

			return (path is null) ? null : gtk_tree_path_copy(path.getTreePathStruct());
		}

		static void customTreeModelGetValue(GtkTreeModel *tree_model, GtkTreeIter *iter, int column, GValue *value)
		{
			auto tm = ObjectG.getDObject!(TreeModel)(tree_model);

			tm.getValue(ObjectG.getDObject!(TreeIter)(iter), column, ObjectG.getDObject!(Value)(value));
		}

		static int customTreeModelIterNext(GtkTreeModel *tree_model, GtkTreeIter *iter)
		{
			auto tm = ObjectG.getDObject!(TreeModel)(tree_model);

			return tm.iterNext(ObjectG.getDObject!(TreeIter)(iter));
		}

		static int customTreeModelIterChildren(GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent)
		{
			TreeIter ti;
			auto tm = ObjectG.getDObject!(TreeModel)(tree_model);

			if ( !tm.iterChildren(ti, ObjectG.getDObject!(TreeIter)(parent)) )
				return false;

			iter = ti.getTreeIterStruct();
			return true;
		}

		static int customTreeModelIterHasChild(GtkTreeModel *tree_model, GtkTreeIter *iter)
		{
			auto tm = ObjectG.getDObject!(TreeModel)(tree_model);

			return tm.iterHasChild(ObjectG.getDObject!(TreeIter)(iter));
		}

		static int customTreeModelIterNChildren(GtkTreeModel *tree_model, GtkTreeIter *iter)
		{
			auto tm = ObjectG.getDObject!(TreeModel)(tree_model);

			return tm.iterNChildren(ObjectG.getDObject!(TreeIter)(iter));
		}

		static int customTreeModelIterNthChild(GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent, int n)
		{
			TreeIter ti;
			auto tm = ObjectG.getDObject!(TreeModel)(tree_model);

			if ( !tm.iterNthChild(ti, ObjectG.getDObject!(TreeIter)(parent), n) )
				return false;

			iter = ti.getTreeIterStruct();
			return true;
		}

		static int customTreeModelIterParent(GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *child)
		{
			TreeIter ti;
			auto tm = ObjectG.getDObject!(TreeModel)(tree_model);

			if ( !tm.iterParent(ti, ObjectG.getDObject!(TreeIter)(child)) )
				return false;

			iter = ti.getTreeIterStruct();
			return true;
		}
	}
}
code: end

struct:
class: TreeNode
namespace:
code: start
	/**
	 * TreeNode interface
	 */
	public interface TreeNode
	{
		string getNodeValue(int column);
		int columnCount();
	}
code: end

struct: TreePath
noCode: new
noCode: new_first
noCode: new_from_indices
noCode: new_from_indicesv
noCode: get_indices
alias: get_indices_with_depth getIndices
code: start
	/**
	 * Creates a new GtkTreePath. This structure refers to a row.
	 * Params:
	 * firstRow = if true this is the string representation of this path is "0"
	 * Throws: ConstructionException GTK+ fails to create the object.
	 */
	public this (bool firstRow=false)
	{
		GtkTreePath* p;

		if ( firstRow )
		{
			// GtkTreePath* gtk_tree_path_new_first (void);
			p = cast(GtkTreePath*)gtk_tree_path_new_first();
		}
		else
		{
			// GtkTreePath* gtk_tree_path_new (void);
			p = cast(GtkTreePath*)gtk_tree_path_new();
		}

		if(p is null)
		{
			throw new ConstructionException("null returned by gtk_tree_path_new()");
		}

		this(p);
	}

	/**
	 * Creates a new path with "indices" as indices.
	 */
	this (int[] indices ... )
	{
		this(false);

		foreach( index; indices )
			appendIndex(index);
	}
code: end

struct: TreeSelection
import: glib.ListG
noCode: get_selected_rows
code: start
	/**
	 * Returns an TreeIter set to the currently selected node if selection
	 * is set to Selection.SINGLE or Selection.BROWSE.
	 * This function will not work if you use selection is Selection.MULTIPLE.
	 * Returns: A TreeIter for the selected node.
	 */
	public TreeIter getSelected()
	{
		TreeModelIF model;
		TreeIter iter = new TreeIter();

		if ( getSelected(model, iter) )
		{
			iter.setModel(model);
			return iter;
		}
		else
		{
			return null;
		}
	}

	/**
	 * Creates a list of path of all selected rows. Additionally, if you are
	 * planning on modifying the model after calling this function, you may
	 * want to convert the returned list into a list of TreeRowReferences.
	 * Since: 2.2
	 * Params:
	 *  model = A pointer to set to the GtkTreeModel, or NULL.
	 * Returns:
	 *  A GList containing a GtkTreePath for each selected row.
	 */
	TreePath[] getSelectedRows(out TreeModelIF model)
	{
		TreePath[] paths;
		GtkTreeModel* outmodel = null;
		GList* gList = gtk_tree_selection_get_selected_rows(gtkTreeSelection, &outmodel);
		if ( gList !is null )
		{
			ListG list = new ListG(gList);
			for ( int i=0 ; i<list.length() ; i++ )
			{
				paths ~= new TreePath(cast(GtkTreePath*)list.nthData(i));
			}
		}
		model = ObjectG.getDObject!(TreeModel, TreeModelIF)(outmodel);

		return paths;
	}
code: end

struct: TreeStore
import: gdk.Pixbuf
import: gtk.TreeNode
noCode: set
code: start
	/**
	 * Creates a top level iteractor.
	 * I don't think lists have but the top level iteractor
	 */
	TreeIter createIter(TreeIter parent=null)
	{
		GtkTreeIter* iter = new GtkTreeIter;
		gtk_tree_store_append(getTreeStoreStruct(), iter, (parent is null) ? null : parent.getTreeIterStruct());
		return new TreeIter(iter);
	}

	/**
	 * Sets one value into one cells.
	 * \todo confirm we need to destroy the Value instance
	 * Params:
	 *  iter = the tree iteractor, effectivly the row
	 *  column = to column number to set
	 *  value = the value
	 */
	void setValue(TreeIter iter, int column, string value)
	{
		gtk_tree_store_set(gtkTreeStore, iter.getTreeIterStruct(), column, Str.toStringz(value) , -1);
	}

	/** ditto */
	void setValue(TreeIter iter, int column, int value)
	{
		gtk_tree_store_set(gtkTreeStore, iter.getTreeIterStruct(), column, value, -1);
	}

	/** ditto */
	//TODO: confirm we need to destroy the Value instance
	void setValue(TreeIter iter, int column, Pixbuf pixbuf)
	{
		Value v = new Value(pixbuf);
		gtk_tree_store_set_value(gtkTreeStore, iter.getTreeIterStruct(), column, v.getValueStruct());
	}

	/**
	 * sets the values for one row
	 * Params:
	 *  iter = the row iteractor
	 *  columns = an arrays with the columns to set
	 *  values = an arrays with the values
	 */
	void set(TreeIter iter, int[] columns, char*[] values)
	{
		for ( int i=0 ; i<columns.length && i<values.length; i++ )
		{
			gtk_tree_store_set(
					gtkTreeStore,
					iter.getTreeIterStruct(),
					columns[i],
					values[i],-1);
		}
	}

	/** ditto */
	void set(TreeIter iter, int[] columns, string[] values)
	{
		for ( int i=0 ; i<columns.length && i<values.length; i++ )
		{
			gtk_tree_store_set(
					gtkTreeStore,
					iter.getTreeIterStruct(),
					columns[i],
					Str.toStringz(values[i]),-1);
		}
	}

	/**
	 * Sets an iteractor values from a tree node.
	 * This is the way to add a new row to the tree,
	 * the iteractor is either a top level iteractor created from createIter()
	 * or a nested iteractor created from append()
	 * Params:
	 *  iter = the iteractor to set
	 *  treeNode = the tree node
	 * See_Also: createIter(), append()
	 */
	void set(TreeIter iter, TreeNode treeNode)
	{
		int[] cols;
		string[] vals;
		for ( int i=0 ; i<treeNode.columnCount() ; i++ )
		{
			//printf(">>>>>>>>>>>>> requesting value for %d\n",i);
			cols ~= i;
			string value = treeNode.getNodeValue(i);
			if ( value  is  null )
			{
				vals ~= "";
			}
			else
			{
				vals ~= value;
			}
		}
		set(iter, cols, vals);
	}


	/**
	 * Creates and prepends a new row to tree_store. If parent is non-NULL, then it will prepend
	 * the new row before the first child of parent, otherwise it will prepend a row
	 * to the top level. iter will be changed to point to this new row. The row
	 * will be empty after this function is called. To fill in values, you need to
	 * call gtk_tree_store_set() or gtk_tree_store_set_value().
	 * Params:
	 *  parent = A valid GtkTreeIter, or NULL
	 */
	public TreeIter prepend(TreeIter parent)
	{
		TreeIter iter = new TreeIter();
		// void gtk_tree_store_prepend (GtkTreeStore *tree_store,  GtkTreeIter *iter,  GtkTreeIter *parent);
		gtk_tree_store_prepend(gtkTreeStore, iter.getTreeIterStruct(), (parent is null) ? null : parent.getTreeIterStruct());
		return iter;
	}

	/**
	 * Creates and appends a new row to tree_store. If parent is non-NULL, then it will append the
	 * new row after the last child of parent, otherwise it will append a row to
	 * the top level. iter will be changed to point to this new row. The row will
	 * be empty after this function is called. To fill in values, you need to call
	 * gtk_tree_store_set() or gtk_tree_store_set_value().
	 * Params:
	 *  parent = A valid GtkTreeIter, or NULL
	 */
	public TreeIter append(TreeIter parent)
	{
		TreeIter iter = new TreeIter();
		// void gtk_tree_store_append (GtkTreeStore *tree_store,  GtkTreeIter *iter,  GtkTreeIter *parent);
		gtk_tree_store_append(gtkTreeStore,
			iter.getTreeIterStruct(),
			(parent is null) ? null : parent.getTreeIterStruct());
		return iter;
	}
code: end

struct: TreeView
noCode: get_hadjustment
noCode: set_hadjustment
noCode: get_vadjustment
noCode: set_vadjustment
code: start
	/**
	 * Expands the row of the iter.
	 * Params:
	 *  iter =
	 *  openAll =
	 *  Returns =
	 */
	int expandRow(TreeIter iter, TreeModelIF model, bool openAll)
	{
		return expandRow(model.getPath(iter), openAll);
	}

	/**
	 * gets the first selected iter or null if no rows are selected
	 */
	TreeIter getSelectedIter()
	{
		TreeIter iter = null;
		TreeSelection selection = getSelection();
		TreeModelIF model = getModel();
		TreePath[] paths = selection.getSelectedRows(model);
		if ( paths.length > 0 )
		{
			iter = new TreeIter();
			model.getIter(iter,paths[0]);
		}
		return iter;
	}

	/** */
	TreeIter[] getSelectedIters()
	{
		TreeIter[] iters;

		TreeIter iter = new TreeIter();
		TreeSelection selection = getSelection();
		TreeModelIF model = getModel();
		TreePath[] paths = selection.getSelectedRows(model);
		foreach ( TreePath p; selection.getSelectedRows(model) )
		{
			if ( model.getIter(iter,p) )
			{
				iters ~= iter;
				iter = new TreeIter();
			}
		}

		return iters;
	}

	/**
	 * Inserts a column and sets it's attributes
	 * Params:
	 *  position =
	 *  title =
	 *  renderer =
	 *  editable =
	 * Returns: number of columns including the new one
	 */
	int insertEditableColumn(int position, string title, CellRenderer renderer, bool editable)
	{
		// OK, this is a trick because of my ignorance on how to pass variable argument lists
		if ( position < 0 )
		{
			position = getColumns().length();
		}
		int tot = gtk_tree_view_insert_column_with_attributes(
			gtkTreeView,
			position,
			Str.toStringz(title),
			renderer.getCellRendererStruct(),
			Str.toStringz("text"),position,
			Str.toStringz("editable"),2,0);
		return tot;
	}
code: end

struct: TreeViewColumn
import: gtk.Button
import: gtk.TreeView
#These are also implemented in CellLayoutT
noCode: pack_start
noCode: pack_end
noCode: clear
noCode: add_attribute
noCode: clear_attributes
# Return the correct class.
noCode: get_button
noCode: get_tree_view
noCode: new_with_attributes
code: start
	/**
	 * Creates a new Tree view column
	 * Params:
	 *  header = th column header text
	 *  renderer = the rederer for the column cells
	 *  type = the type of data to be displayed (shouldn't this be on the renderer?)
	 *  column = the column number
	 * Throws: ConstructionException GTK+ fails to create the object.
	 */
	this(string header, CellRenderer renderer, string type, int column)
	{
		auto p = gtk_tree_view_column_new_with_attributes(
				Str.toStringz(header),
				renderer.getCellRendererStruct(),
				Str.toStringz(type),
				column,
				null);

		if(p is null)
		{
			throw new ConstructionException("null returned by gtk_tree_view_column_new_with_attributes");
		}

		this(p);
	}

	/**
	 * Returns the button used in the treeview column header
	 * Returns: The button for the column header. [transfer none] Since 3.0
	 */
	public Button getButton()
	{
		// GtkWidget * gtk_tree_view_column_get_button (GtkTreeViewColumn *tree_column);
		auto p = gtk_tree_view_column_get_button(gtkTreeViewColumn);
		if(p is null)
		{
			return null;
		}
		return new Button(cast(GtkButton*) p);
	}

	/**
	 * Returns the GtkTreeView wherein tree_column has been inserted.
	 * If column is currently not inserted in any tree view, NULL is
	 * returned.
	 * Since 2.12
	 * Returns: The tree view wherein column has been inserted if any, NULL otherwise. [transfer none]
	 */
	public TreeView getTreeView()
	{
		// GtkWidget * gtk_tree_view_column_get_tree_view (GtkTreeViewColumn *tree_column);
		auto p = gtk_tree_view_column_get_tree_view(gtkTreeViewColumn);
		if(p is null)
		{
			return null;
		}
		return new TreeView(cast(GtkTreeView*) p);
	}
code: end

struct: UIManager
import: gobject.Type
import: gtk.AccelGroup
import: gtk.Action
import: gtk.ActionGroup
import: gtk.CheckMenuItem
import: gtk.ImageMenuItem
import: gtk.Menu
import: gtk.MenuBar
import: gtk.MenuItem
import: gtk.MenuToolButton
import: gtk.RadioMenuItem
import: gtk.RadioToolButton
import: gtk.SeparatorMenuItem
import: gtk.SeparatorToolItem
import: gtk.TearoffMenuItem
import: gtk.ToggleToolButton
import: gtk.Toolbar
import: gtk.ToolButton
import: gtk.ToolItem
import: gtk.Widget
noCode: get_widget
code: start
	/**
	 * Warning: getWidget is deprecated and should not be used in newly-written code. 3.10
	 *
	 * Looks up a widget by following a path.
	 * The path consists of the names specified in the XML description of the UI.
	 * separated by '/'. Elements which don't have a name or action attribute in
	 * the XML (e.g. &lt;popup&gt;) can be addressed by their XML element name
	 * (e.g. "popup"). The root element ("/ui") can be omitted in the path.
	 *
	 * Note that the widget found by following a path that ends in a &lt;menu&gt;
	 * element is the menuitem to which the menu is attached, not the menu itself.
	 *
	 * Also note that the widgets constructed by a ui manager are not tied to
	 * the lifecycle of the ui manager. If you add the widgets returned by this
	 * function to some container or explicitly ref them, they will survive the
	 * destruction of the ui manager.
	 *
	 * Since 2.4
	 *
	 * Params:
	 *    path = a path
	 *
	 * Returns: the widget found by following the path, or null if no widget was found.
	 */
	public Widget getWidget(string path)
	{
		// GtkWidget * gtk_ui_manager_get_widget (GtkUIManager *manager,  const gchar *path);
		auto p = gtk_ui_manager_get_widget(gtkUIManager, Str.toStringz(path));

		if(p is null)
		{
			return null;
		}

		string typeName = Type.name((cast(GTypeInstance*)p).gClass.gType);

		switch(typeName)
		{
			case "GtkCheckMenuItem":
				return ObjectG.getDObject!(CheckMenuItem)(cast(GtkCheckMenuItem*) p);
			case "GtkImageMenuItem":
				return ObjectG.getDObject!(ImageMenuItem)(cast(GtkImageMenuItem*) p);
			case "GtkMenu":
				return ObjectG.getDObject!(Menu)(cast(GtkMenu*) p);
			case "GtkMenuBar":
				return ObjectG.getDObject!(MenuBar)(cast(GtkMenuBar*) p);
			case "GtkMenuItem":
				return ObjectG.getDObject!(MenuItem)(cast(GtkMenuItem*) p);
			case "GtkMenuToolButton":
				return ObjectG.getDObject!(MenuToolButton)(cast(GtkMenuToolButton*) p);
			case "GtkRadioMenuItem":
				return ObjectG.getDObject!(RadioMenuItem)(cast(GtkRadioMenuItem*) p);
			case "GtkRadioToolButton":
				return ObjectG.getDObject!(RadioToolButton)(cast(GtkRadioToolButton*) p);
			case "GtkSeparatorMenuItem":
				return ObjectG.getDObject!(SeparatorMenuItem)(cast(GtkSeparatorMenuItem*) p);
			case "GtkSeparatorToolItem":
				return ObjectG.getDObject!(SeparatorToolItem)(cast(GtkSeparatorToolItem*) p);
			case "GtkTearoffMenuItem":
				return ObjectG.getDObject!(TearoffMenuItem)(cast(GtkTearoffMenuItem*) p);
			case "GtkToggleToolButton":
				return ObjectG.getDObject!(ToggleToolButton)(cast(GtkToggleToolButton*) p);
			case "GtkToolbar":
				return ObjectG.getDObject!(Toolbar)(cast(GtkToolbar*) p);
			case "GtkToolButton":
				return ObjectG.getDObject!(ToolButton)(cast(GtkToolButton*) p);
			case "GtkToolItem":
				return ObjectG.getDObject!(ToolItem)(cast(GtkToolItem*) p);
			default:
				return ObjectG.getDObject!(Widget)(cast(GtkWidget*) p);
		}
	}
code: end

struct: VButtonBox
code: start
    /**
     * Creates a new vertical button box and sets standart values for it's comon parameters
     * Returns: a new vertical button box
     */
	static VButtonBox createActionBox()
	{
		VButtonBox bBox = new VButtonBox();
		bBox.setLayout(ButtonBoxStyle.START);
		bBox.setBorderWidth(5);
		bBox.setSpacing(7);
		return bBox;
	}
code: end

struct: VPaned
code: start
	/**
	 * Creates a new HPaned and adds two widgets as it's children
	 * Params:
	 *  child1 =
	 *  child2 =
	 */
	this(Widget child1, Widget child2)
	{
		this();
		add1(child1);
		add2(child2);
	}
code: end

struct: Widget
import: gdk.Cursor
import: gdk.Window : GdkWin = Window
import: gobject.Type
import: std.conv
structWrap: Gdk.Window GdkWin
noCode: set_state
noCode: get_state
noSignal: draw
code: start
	public GtkWidgetClass* getWidgetClass()
	{
		return Type.getInstanceClass!(GtkWidgetClass)(this);
	}

	/** */
	public int getWidth()
	{
		int width;
		gtk_widget_get_size_request(gtkWidget, &width, null);
		return width;
	}

	/** */
	public int getHeight()
	{
		int height;
		gtk_widget_get_size_request(gtkWidget, null, &height);
		return height;
	}

	/**
	 * Sets  the cursor.
	 * Params:
	 *  cursor = the new cursor
	 * Bugs: the cursor changes to the parent widget also
	 */
	void setCursor(Cursor cursor)
	{
		getWindow().setCursor(cursor);
	}

	/**
	 * Resets the cursor.
	 * don't know if this is implemented by GTK+. Seems that it's not
	 * Bugs: does nothing
	 */
	public void resetCursor()
	{
		getWindow().setCursor(null);
	}

	/**
	 * Modifies the font for this widget.
	 * This just calls modifyFont(new PgFontDescription(PgFontDescription.fromString(family ~ " " ~ size)));
	 */
	public void modifyFont(string family, int size)
	{
		if ( size < 0 ) size = -size;	// hack to workaround leds bug - TO BE REMOVED

		modifyFont(
			PgFontDescription.fromString(
				family ~ " " ~ to!(string)(size)
			)
		);
	}

	/** */
	public bool onEvent(GdkEvent* event)
	{
		return getWidgetClass().event(getWidgetStruct(), event) == 0 ? false : true;
	}

	/** */
	public bool onButtonPressEvent(GdkEventButton* event)
	{
		return getWidgetClass().buttonPressEvent(getWidgetStruct(), event) == 0 ? false : true;
	}

	/** */
	public bool onButtonReleaseEvent(GdkEventButton* event)
	{
		return getWidgetClass().buttonReleaseEvent(getWidgetStruct(), event) == 0 ? false : true;
	}

	/** */
	public bool onScrollEvent(GdkEventScroll* event)
	{
		return getWidgetClass().scrollEvent(getWidgetStruct(), event) == 0 ? false : true;
	}

	/** */
	public bool onMotionNotifyEvent(GdkEventMotion* event)
	{
		return getWidgetClass().motionNotifyEvent(getWidgetStruct(), event) == 0 ? false : true;
	}

	/** */
	public bool onDeleteEvent(GdkEventAny* event)
	{
		return getWidgetClass().deleteEvent(getWidgetStruct(), event) == 0 ? false : true;
	}

	/** */
	public bool onDestroyEvent(GdkEventAny* event)
	{
		return getWidgetClass().destroyEvent(getWidgetStruct(), event) == 0 ? false : true;
	}

	/** */
	public bool onKeyPressEvent(GdkEventKey* event)
	{
		return getWidgetClass().keyPressEvent(getWidgetStruct(), event) == 0 ? false : true;
	}

	/** */
	public bool onKeyReleaseEvent(GdkEventKey* event)
	{
		return getWidgetClass().keyReleaseEvent(getWidgetStruct(), event) == 0 ? false : true;
	}

	/** */
	public bool onEnterNotifyEvent(GdkEventCrossing* event)
	{
		return getWidgetClass().enterNotifyEvent(getWidgetStruct(), event) == 0 ? false : true;
	}

	/** */
	public bool onLeaveNotifyEvent(GdkEventCrossing* event)
	{
		return getWidgetClass().leaveNotifyEvent(getWidgetStruct(), event) == 0 ? false : true;
	}

	/** */
	public bool onConfigureEvent(GdkEventConfigure* event)
	{
		return getWidgetClass().configureEvent(getWidgetStruct(), event) == 0 ? false : true;
	}

	/** */
	public bool onFocusInEvent(GdkEventFocus* event)
	{
		return getWidgetClass().focusInEvent(getWidgetStruct(), event) == 0 ? false : true;
	}

	/** */
	public bool onFocusOutEvent(GdkEventFocus* event)
	{
		return getWidgetClass().focusOutEvent(getWidgetStruct(), event) == 0 ? false : true;
	}

	/** */
	public bool onMapEvent(GdkEventAny* event)
	{
		return getWidgetClass().mapEvent(getWidgetStruct(), event) == 0 ? false : true;
	}

	/** */
	public bool onUnmapEvent(GdkEventAny* event)
	{
		return getWidgetClass().unmapEvent(getWidgetStruct(), event) == 0 ? false : true;
	}

	/** */
	public bool onPropertyNotifyEvent(GdkEventProperty* event)
	{
		return getWidgetClass().propertyNotifyEvent(getWidgetStruct(), event) == 0 ? false : true;
	}

	/** */
	public bool onSelectionClearEvent(GdkEventSelection* event)
	{
		return getWidgetClass().selectionClearEvent(getWidgetStruct(), event) == 0 ? false : true;
	}

	/** */
	public bool onSelectionRequestEvent(GdkEventSelection* event)
	{
		return getWidgetClass().selectionRequestEvent(getWidgetStruct(), event) == 0 ? false : true;
	}

	/** */
	public bool onSelectionNotifyEvent(GdkEventSelection* event)
	{
		return getWidgetClass().selectionNotifyEvent(getWidgetStruct(), event) == 0 ? false : true;
	}

	/** */
	public bool onProximityInEvent(GdkEventProximity* event)
	{
		return getWidgetClass().proximityInEvent(getWidgetStruct(), event) == 0 ? false : true;
	}

	/** */
	public bool onProximityOutEvent(GdkEventProximity* event)
	{
		return getWidgetClass().proximityOutEvent(getWidgetStruct(), event) == 0 ? false : true;
	}

	/** */
	public bool onVisibilityNotifyEvent(GdkEventVisibility* event)
	{
		return getWidgetClass().visibilityNotifyEvent(getWidgetStruct(), event) == 0 ? false : true;
	}

	/** */
	public bool onWindowStateEvent(GdkEventWindowState* event)
	{
		return getWidgetClass().windowStateEvent(getWidgetStruct(), event) == 0 ? false : true;
	}

	/** */
	public bool onDamageEvent(GdkEventExpose* event)
	{
		return getWidgetClass().damageEvent(getWidgetStruct(), event) == 0 ? false : true;
	}

	/** */
	public bool onGrabBrokenEvent(GdkEventGrabBroken* event)
	{
		return getWidgetClass().grabBrokenEvent(getWidgetStruct(), event) == 0 ? false : true;
	}

	/**
	 * Queues an animation frame update and adds a callback to be called
	 * before each frame. Until the tick callback is removed, it will be
	 * called frequently (usually at the frame rate of the output device
	 * or as quickly as the application can be repainted, whichever is
	 * slower). For this reason, is most suitable for handling graphics
	 * that change every frame or every few frames. The tick callback does
	 * not automatically imply a relayout or repaint. If you want a
	 * repaint or relayout, and aren't changing widget properties that
	 * would trigger that (for example, changing the text of a gtk.Label),
	 * then you will have to call queueResize() or queuDrawArea() yourself.
	 *
	 * gdk.FrameClock.FrameClock.getFrameTime() should generally be used for timing
	 * continuous animations and gdk.FrameTimings.FrameTimings.getPredictedPresentationPime()
	 * if you are trying to display isolated frames at particular times.
	 *
	 * This is a more convenient alternative to connecting directly to the
	 * "update" signal of GdkFrameClock, since you don't
	 * have to worry about when a GdkFrameClock is assigned to a widget.
	 *
	 * Params:
	 *     callback = function to call for updating animations
	 */
	public void addTickCallback(bool delegate(Widget, FrameClock) callback)
	{
		tickCallbackListeners ~= callback;
		static bool connected;

		if ( connected )
		{
			return;
		}

		addTickCallback(cast(GtkTickCallback)&gtkTickCallback, cast(void*)this, null);
		connected = true;
	}
	bool delegate(Widget, FrameClock)[] tickCallbackListeners;
	extern(C) static int gtkTickCallback(GtkWidget* widgetStruct, GdkFrameClock* frameClock, Widget _widget)
	{
		foreach ( dlg ; _widget.tickCallbackListeners )
		{
			if(dlg(_widget, new FrameClock(frameClock)))
				return 1;
		}
		return 0;
	}

	protected class ScopedOnDrawDelegateWrapper
	{
		static ScopedOnDrawDelegateWrapper[] listeners;
		bool delegate(Scoped!Context, Widget) dlg;
		gulong handlerId;
		
		this(bool delegate(Scoped!Context, Widget) dlg)
		{
			this.dlg = dlg;
			this.listeners ~= this;
		}
		
		void remove(ScopedOnDrawDelegateWrapper source)
		{
			foreach(index, wrapper; listeners)
			{
				if (wrapper.handlerId == source.handlerId)
				{
					listeners[index] = null;
					listeners = std.algorithm.remove(listeners, index);
					break;
				}
			}
		}
	}

	/**
		* This signal is emitted when a widget is supposed to render itself.
		* The @widget's top left corner must be painted at the origin of
		* the passed in context and be sized to the values returned by
		* gtk_widget_get_allocated_width() and
		* gtk_widget_get_allocated_height().
		*
		* Signal handlers connected to this signal can modify the cairo
		* context passed as @cr in any way they like and don't need to
		* restore it. The signal emission takes care of calling cairo_save()
		* before and cairo_restore() after invoking the handler.
		*
		* The signal handler will get a @cr with a clip region already set to the
		* widget's dirty region, i.e. to the area that needs repainting.  Complicated
		* widgets that want to avoid redrawing themselves completely can get the full
		* extents of the clip region with gdk_cairo_get_clip_rectangle(), or they can
		* get a finer-grained representation of the dirty region with
		* cairo_copy_clip_rectangle_list().
		*
		* Params:
		*     cr = the cairo context to draw to
		*
		* Return: %TRUE to stop other handlers from being invoked for the event.
		*     %FALSE to propagate the event further.
		*
		* Since: 3.0
		*/
	gulong addOnDraw(bool delegate(Scoped!Context, Widget) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
	{
		auto wrapper = new ScopedOnDrawDelegateWrapper(dlg);
		wrapper.handlerId = Signals.connectData(
			this,
			"draw",
			cast(GCallback)&callBackScopedDraw,
			cast(void*)wrapper,
			cast(GClosureNotify)&callBackDrawScopedDestroy,
			connectFlags);
		return wrapper.handlerId;
	}
	
	extern(C) static int callBackScopedDraw(GtkWidget* widgetStruct, cairo_t* cr, ScopedOnDrawDelegateWrapper wrapper)
	{
		return wrapper.dlg(scoped!Context(cr), wrapper.outer);
	}
	
	extern(C) static void callBackDrawScopedDestroy(ScopedOnDrawDelegateWrapper wrapper, GClosure* closure)
	{
		wrapper.remove(wrapper);
	}

	protected class OnDrawDelegateWrapper
	{
		static OnDrawDelegateWrapper[] listeners;
		bool delegate(Context, Widget) dlg;
		gulong handlerId;
		
		this(bool delegate(Context, Widget) dlg)
		{
			this.dlg = dlg;
			this.listeners ~= this;
		}
		
		void remove(OnDrawDelegateWrapper source)
		{
			foreach(index, wrapper; listeners)
			{
				if (wrapper.handlerId == source.handlerId)
				{
					listeners[index] = null;
					listeners = std.algorithm.remove(listeners, index);
					break;
				}
			}
		}
	}

	/**
		* This signal is emitted when a widget is supposed to render itself.
		* The @widget's top left corner must be painted at the origin of
		* the passed in context and be sized to the values returned by
		* gtk_widget_get_allocated_width() and
		* gtk_widget_get_allocated_height().
		*
		* Signal handlers connected to this signal can modify the cairo
		* context passed as @cr in any way they like and don't need to
		* restore it. The signal emission takes care of calling cairo_save()
		* before and cairo_restore() after invoking the handler.
		*
		* The signal handler will get a @cr with a clip region already set to the
		* widget's dirty region, i.e. to the area that needs repainting.  Complicated
		* widgets that want to avoid redrawing themselves completely can get the full
		* extents of the clip region with gdk_cairo_get_clip_rectangle(), or they can
		* get a finer-grained representation of the dirty region with
		* cairo_copy_clip_rectangle_list().
		*
		* Params:
		*     cr = the cairo context to draw to
		*
		* Return: %TRUE to stop other handlers from being invoked for the event.
		*     %FALSE to propagate the event further.
		*
		* Since: 3.0
		*/
	deprecated gulong addOnDraw(bool delegate(Context, Widget) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
	{
		auto wrapper = new OnDrawDelegateWrapper(dlg);
		wrapper.handlerId = Signals.connectData(
			this,
			"draw",
			cast(GCallback)&callBackDraw,
			cast(void*)wrapper,
			cast(GClosureNotify)&callBackDrawDestroy,
			connectFlags);
		return wrapper.handlerId;
	}
	
	extern(C) static int callBackDraw(GtkWidget* widgetStruct, cairo_t* cr,OnDrawDelegateWrapper wrapper)
	{
		return wrapper.dlg(new Context(cr), wrapper.outer);
	}
	
	extern(C) static void callBackDrawDestroy(OnDrawDelegateWrapper wrapper, GClosure* closure)
	{
		wrapper.remove(wrapper);
	}
code: end

struct: Window
code: start
	/**
	 * Creates a top level window with a title
	 * Params:
	 * 		title = The Window title
	 */
	public this(string title)
	{
		this(GtkWindowType.TOPLEVEL);
		setTitle(title);
	}

	/**
	 * Move the window to an absolute position.
	 * just calls move(int, int).
	 * convinience because GdkEvent structs return the position coords as doubles
	 */
	public void move(double x, double y)
	{
		move(cast(int)x, cast(int)y);
	}
code: end

struct:

move: show_about_dialog AboutDialog

move: accel_groups_activate AccelGroup
move: accel_groups_from_object AccelGroup
move: accelerator_get_default_mod_mask AccelGroup
move: accelerator_get_label AccelGroup
move: accelerator_get_label_with_keycode AccelGroup
move: accelerator_name AccelGroup
move: accelerator_name_with_keycode AccelGroup
move: accelerator_parse AccelGroup
move: accelerator_parse_with_keycode AccelGroup
move: accelerator_set_default_mod_mask AccelGroup
move: accelerator_valid AccelGroup

move: bindings_activate BindingSet
move: bindings_activate_event BindingSet

move: alternative_dialog_button_order Dialog

move: drag_cancel DragAndDrop
move: drag_finish DragAndDrop
move: drag_get_source_widget DragAndDrop
move: drag_set_icon_default DragAndDrop
move: drag_set_icon_gicon DragAndDrop
move: drag_set_icon_name DragAndDrop
move: drag_set_icon_pixbuf DragAndDrop
move: drag_set_icon_stock DragAndDrop
move: drag_set_icon_surface DragAndDrop
move: drag_set_icon_widget DragAndDrop
move: draw_insertion_cursor DragAndDrop

move: rgb_to_hsv HSV

move: icon_size_from_name IconSize from_name
move: icon_size_get_name IconSize get_name
move: icon_size_lookup IconSize lookup
move: icon_size_lookup_for_settings IconSize lookup_for_settings
move: icon_size_register IconSize register
move: icon_size_register_alias IconSize register_alias

move: device_grab_add Main
move: device_grab_remove Main
move: disable_setlocale Main
move: events_pending Main
move: get_current_event Main
move: get_current_event_device Main
move: get_current_event_state Main
move: get_current_event_time Main
move: get_debug_flags Main
move: get_default_language Main
move: get_event_widget Main
move: get_locale_direction Main
move: get_option_group Main
move: grab_get_current Main
move: init Main
move: init_check Main
move: init_with_args Main
move: key_snooper_install Main
move: key_snooper_remove Main
move: main Main
move: main_do_event Main do_event
move: main_iteration Main iteration
move: main_iteration_do Main iteration_do
move: main_level Main level
move: main_quit Main quit
move: parse_args Main
move: propagate_event Main
move: set_debug_flags Main

move: show_uri MountOperation

move: print_run_page_setup_dialog PrintOperation
move: print_run_page_setup_dialog_async PrintOperation

move: rc_add_default_file RcStyle add_default_file
move: rc_find_module_in_path RcStyle find_module_in_path
move: rc_find_pixmap_in_path RcStyle find_pixmap_in_path
move: rc_get_default_files RcStyle get_default_files
move: rc_get_im_module_file RcStyle get_im_module_file
move: rc_get_im_module_path RcStyle get_im_module_path
move: rc_get_module_dir RcStyle get_module_dir
move: rc_get_style RcStyle get_style
move: rc_get_style_by_paths RcStyle get_style_by_path
move: rc_get_theme_dir RcStyle get_theme_dir
move: rc_parse RcStyle parse
move: rc_parse_color RcStyle parse_color
move: rc_parse_color_full RcStyle parse_color_full
move: rc_parse_priority RcStyle parse_priority
move: rc_parse_state RcStyle parse_state
move: rc_parse_string RcStyle parse_string
move: rc_reparse_all RcStyle reparse_all
move: rc_reparse_all_for_settings RcStyle reparse_all_for_settings
move: rc_reset_styles RcStyle reset_styles
move: rc_scanner_new RcStyle scanner_new
move: rc_set_default_files RcStyle set_default_files

move: selection_add_target SelectionData add_target
move: selection_add_targets SelectionData add_targets
move: selection_clear_targets SelectionData clear_targets
move: selection_convert SelectionData convert
move: selection_owner_set SelectionData owner_set
move: selection_owner_set_for_display SelectionData owner_set_for_display
move: selection_remove_all SelectionData remove_all

move: stock_add StockItem
move: stock_add_static StockItem
move: stock_list_ids StockItem
move: stock_lookup StockItem
move: stock_set_translate_func StockItem

move: paint_arrow Style
move: paint_box Style
move: paint_box_gap Style
move: paint_check Style
move: paint_diamond Style
move: paint_expander Style
move: paint_extension Style
move: paint_flat_box Style
move: paint_focus Style
move: paint_handle Style
move: paint_hline Style
move: paint_layout Style
move: paint_option Style
move: paint_resize_grip Style
move: paint_shadow Style
move: paint_shadow_gap Style
move: paint_slider Style
move: paint_spinner Style
move: paint_tab Style
move: paint_vline Style

move: render_activity StyleContext
move: render_arrow StyleContext
move: render_background StyleContext
move: render_background_get_clip StyleContext
move: render_check StyleContext
move: render_expander StyleContext
move: render_extension StyleContext
move: render_focus StyleContext
move: render_frame StyleContext
move: render_frame_gap StyleContext
move: render_handle StyleContext
move: render_icon StyleContext
move: render_icon_pixbuf StyleContext
move: render_icon_surface StyleContext
move: render_insertion_cursor StyleContext
move: render_layout StyleContext
move: render_line StyleContext
move: render_option StyleContext
move: render_slider StyleContext

move: target_table_free TargetList
move: target_table_new_from_list TargetList
move: targets_include_image TargetList include_image
move: targets_include_rich_text TargetList include_rich_tex
move: targets_include_text TargetList include_text
move: targets_include_uri TargetList include_uri

move: test_create_simple_window Testing create_simple_window
move: test_create_widget Testing create_widget
move: test_display_button_window Testing display_button_window
move: test_find_label Testing find_label
move: test_find_sibling Testing find_sibling
move: test_find_widget Testing find_widget
move: test_init Testing init
move: test_list_all_types Testing list_all_types
move: test_register_all_types Testing register_all_types
move: test_slider_get_value Testing slider_get_value
move: test_slider_set_perc Testing slider_set_perc
move: test_spin_button_click Testing spin_button_click
move: test_text_get Testing text_get
move: test_text_set Testing text_set
move: test_widget_click Testing widget_click
move: test_widget_send_key Testing widget_send_key
move: test_widget_wait_for_draw Testing widget_wait_for_draw

move: tree_get_row_drag_data TreeDragSource get_row_drag_data
move: tree_set_row_drag_data TreeDragSource set_row_drag_data

move: check_version Version
move: get_binary_age Version
move: get_interface_age Version
move: get_major_version Version
move: get_micro_version Version
move: get_minor_version Version

move: cairo_should_draw_window Widget
move: cairo_transform_to_window Widget
move: distribute_natural_allocation Widget

move: show_uri_on_window Window
