Author: danw
Date: 2005-04-11 16:35:56 -0400 (Mon, 11 Apr 2005)
New Revision: 42805
Added:
trunk/gtk-sharp/sample/PolarFixed.cs
Removed:
trunk/gtk-sharp/sample/CustomNotebook.cs
Modified:
trunk/gtk-sharp/ChangeLog
trunk/gtk-sharp/doc/ChangeLog
trunk/gtk-sharp/doc/en/Gtk/Container.xml
trunk/gtk-sharp/generator/ClassBase.cs
trunk/gtk-sharp/generator/ObjectGen.cs
trunk/gtk-sharp/gtk/Container.custom
trunk/gtk-sharp/gtk/Gtk.metadata
trunk/gtk-sharp/sample/GtkDemo/DemoImages.cs
trunk/gtk-sharp/sample/Makefile.am
Log:
* generator/ClassBase.cs (ParseImplements): record both managed
and unmanaged interface declarations.
(Implements): check recursively
* generator/ObjectGen.cs (Generate): output managed interfaces
* gtk/Gtk.metadata: make Container implement IEnumerable
* gtk/Container.custom (GetEnumerator): implement (a simplified
form of Children).
(AllChildren): add this (which accumulates the results of
Forall()).
(ForAll): mark ForAll(bool,CallbackInvoker) obsolete and add a
ForAll(bool,Gtk.Callback) overload to replace it.
* sample/PolarFixed.cs: new silly but fully-functional demo of
how to subclass container.
* sample/CustomNotebook.cs: kill this, since it was really
complicated, and never fully functional.
* sample/GtkDemo/DemoImages.cs (ToggleSensitivity): Use foreach
directly on the container, rather than on its .Children.
Modified: trunk/gtk-sharp/ChangeLog
===================================================================
--- trunk/gtk-sharp/ChangeLog 2005-04-11 20:27:40 UTC (rev 42804)
+++ trunk/gtk-sharp/ChangeLog 2005-04-11 20:35:56 UTC (rev 42805)
@@ -1,3 +1,29 @@
+2005-04-11 Dan Winship <[EMAIL PROTECTED]>
+
+ * generator/ClassBase.cs (ParseImplements): record both managed
+ and unmanaged interface declarations.
+ (Implements): check recursively
+
+ * generator/ObjectGen.cs (Generate): output managed interfaces
+
+ * gtk/Gtk.metadata: make Container implement IEnumerable
+
+ * gtk/Container.custom (GetEnumerator): implement (a simplified
+ form of Children).
+ (AllChildren): add this (which accumulates the results of
+ Forall()).
+ (ForAll): mark ForAll(bool,CallbackInvoker) obsolete and add a
+ ForAll(bool,Gtk.Callback) overload to replace it.
+
+ * sample/PolarFixed.cs: new silly but fully-functional demo of
+ how to subclass container.
+
+ * sample/CustomNotebook.cs: kill this, since it was really
+ complicated, and never fully functional.
+
+ * sample/GtkDemo/DemoImages.cs (ToggleSensitivity): Use foreach
+ directly on the container, rather than on its .Children.
+
2005-04-11 Mike Kestner <[EMAIL PROTECTED]>
* gtk/Quit.custom : obsolete AddFull and implement Add properly.
Modified: trunk/gtk-sharp/doc/ChangeLog
===================================================================
--- trunk/gtk-sharp/doc/ChangeLog 2005-04-11 20:27:40 UTC (rev 42804)
+++ trunk/gtk-sharp/doc/ChangeLog 2005-04-11 20:35:56 UTC (rev 42805)
@@ -1,3 +1,7 @@
+2005-04-08 Dan Winship <[EMAIL PROTECTED]>
+
+ * en/Gtk/Container.xml: document new children stuff
+
2005-04-04 Dan Winship <[EMAIL PROTECTED]>
* en/Pango/Scale.xml: update
Modified: trunk/gtk-sharp/doc/en/Gtk/Container.xml
===================================================================
--- trunk/gtk-sharp/doc/en/Gtk/Container.xml 2005-04-11 20:27:40 UTC (rev
42804)
+++ trunk/gtk-sharp/doc/en/Gtk/Container.xml 2005-04-11 20:35:56 UTC (rev
42805)
@@ -532,15 +532,72 @@
</ReturnValue>
<Parameters />
<Docs>
- <summary>Obtains the the container's non-internal children.</summary>
+ <summary>Obtains an array of the container's (non-internal)
children.</summary>
<returns>An array of non-internal children.</returns>
<remarks>
- <para>
- See <see cref="M:Gtk.Container.Forall" /> for details on what
constitutes an "internal" child.
- </para>
+ <para>
+ Returns the container's non-internal children; that is,
generally, the
+ children that were explicitly added to the container by the
application, as
+ opposed to those widgets that are internal implementation
details of the
+ container.
+ </para>
+ <para>
+ If you simply want to do a <see langword="foreach" /> loop on
the
+ container's children, you do not need to use the Children
property.
+ Just do:
+ </para>
+ <example>
+ <code lang="C#">
+foreach (Widget w in myContainer) {
+ // Do something with w
+}
+ </code>
+ </example>
</remarks>
</Docs>
</Member>
+ <Member MemberName="GetEnumerator">
+ <MemberSignature Language="C#" Value="public virtual
System.Collections.IEnumerator GetEnumerator ();" />
+ <MemberType>Method</MemberType>
+ <ReturnValue>
+ <ReturnType>System.Collections.IEnumerator</ReturnType>
+ </ReturnValue>
+ <Parameters />
+ <Docs>
+ <summary>Returns an <see cref="T:System.Collections.IEnumerator" />
for the container's children</summary>
+ <returns>a <see cref="T:System.Collections.IEnumerator" /></returns>
+ <remarks>
+ <para>
+ <see cref="T:Gtk.Container" /> implements
+ <see cref="T:System.Collections.IEnumerable" />, so you can
iterate
+ through its children like this:
+ </para>
+ <example>
+ <code lang="C#">
+foreach (Widget w in myContainer) {
+ // Do something with w
+}
+ </code>
+ </example>
+ </remarks>
+ </Docs>
+ </Member>
+ <Member MemberName="AllChildren">
+ <MemberSignature Language="C#" Value="public
System.Collections.IEnumerable AllChildren { get; };" />
+ <MemberType>Property</MemberType>
+ <ReturnValue>
+ <ReturnType>System.Collections.IEnumerable</ReturnType>
+ </ReturnValue>
+ <Parameters />
+ <Docs>
+ <summary>Allows you to enumerate all of the container's
children.</summary>
+ <returns>an <see cref="T:System.Collections.IEnumerable" /></returns>
+ <remarks>
+ Enumerates all of the container's children, including those widgets
that are
+ internal implementation details of the container.
+ </remarks>
+ </Docs>
+ </Member>
<Member MemberName="FocusChain">
<MemberSignature Language="C#" Value="public Gtk.Widget [] FocusChain {
set; get; };" />
<MemberType>Property</MemberType>
@@ -573,7 +630,7 @@
</remarks>
</Docs>
</Member>
- <Member MemberName="ForAll">
+ <Member MemberName="ForAll" Deprecated="true">
<MemberSignature Language="C#" Value="protected virtual void ForAll
(bool include_internals, Gtk.Container+CallbackInvoker invoker);" />
<MemberType>Method</MemberType>
<ReturnValue>
@@ -585,11 +642,34 @@
</Parameters>
<Docs>
<summary>Run a given callback for every object inside this
container.</summary>
- <param name="include_internals">a <see cref="T:System.Boolean" />,
whether to include this container's children's children when running the
callback.</param>
+ <param name="include_internals">a <see cref="T:System.Boolean" />,
whether to include "internal" children when running the callback.</param>
<param name="invoker">a <see cref="T:Gtk.Container+CallbackInvoker"
/></param>
- <remarks />
+ <remarks>
+ Deprecated: overload <see
cref="M:Gtk.Container.Forall(System.Boolean,Gtk.Callback)" /> instead.
+ </remarks>
</Docs>
</Member>
+ <Member MemberName="ForAll">
+ <MemberSignature Language="C#" Value="protected virtual void ForAll
(bool include_internals, Gtk.Callback callback);" />
+ <MemberType>Method</MemberType>
+ <ReturnValue>
+ <ReturnType>System.Void</ReturnType>
+ </ReturnValue>
+ <Parameters>
+ <Parameter Name="include_internals" Type="System.Boolean" />
+ <Parameter Name="callback" Type="Gtk.Callback" />
+ </Parameters>
+ <Docs>
+ <summary>Run a given callback for every object inside this
container.</summary>
+ <param name="include_internals">a <see cref="T:System.Boolean" />,
whether to include "internal" children when running the callback.</param>
+ <param name="callback">a <see cref="T:Gtk.Callback" /></param>
+ <remarks>
+ Overload this in subclasses of Gtk.Container to implement the
+ <see cref="M:Gtk.Container.Foreach" /> and <see
cref="M:Gtk.Container.Forall" />
+ methods.
+ </remarks>
+ </Docs>
+ </Member>
<Member MemberName="ChildType">
<MemberSignature Language="C#" Value="public virtual GLib.GType
ChildType ();" />
<MemberType>Method</MemberType>
@@ -619,7 +699,7 @@
<Parameter Name="notify" Type="Gtk.DestroyNotify" />
</Parameters>
<Docs>
- <summary>Runs <paramref name="cb"/> over every item in this
container.</summary>
+ <summary>Runs <paramref name="cb" /> over every item in this
container.</summary>
<param name="cb">a <see cref="T:Gtk.Callback" /></param>
<param name="marshal">a <see cref="T:Gtk.CallbackMarshal" /></param>
<param name="callback_data">a <see cref="T:System.IntPtr" />, the data
to pass to the callback method.</param>
@@ -644,4 +724,4 @@
</Docs>
</Member>
</Members>
-</Type>
+</Type>
\ No newline at end of file
Modified: trunk/gtk-sharp/generator/ClassBase.cs
===================================================================
--- trunk/gtk-sharp/generator/ClassBase.cs 2005-04-11 20:27:40 UTC (rev
42804)
+++ trunk/gtk-sharp/generator/ClassBase.cs 2005-04-11 20:35:56 UTC (rev
42805)
@@ -33,7 +33,8 @@
protected Hashtable props = new Hashtable();
protected Hashtable sigs = new Hashtable();
protected Hashtable methods = new Hashtable();
- protected ArrayList interfaces = null;
+ protected ArrayList interfaces = new ArrayList();
+ protected ArrayList managed_interfaces = new ArrayList();
protected ArrayList ctors = new ArrayList();
private bool ctors_initted = false;
@@ -101,7 +102,7 @@
break;
case "implements":
- interfaces = ParseImplements (member);
+ ParseImplements (member);
break;
case "constructor":
@@ -193,18 +194,17 @@
}
}
- private ArrayList ParseImplements (XmlElement member)
+ private void ParseImplements (XmlElement member)
{
- ArrayList ifaces = new ArrayList ();
-
foreach (XmlNode node in member.ChildNodes) {
if (node.Name != "interface")
continue;
XmlElement element = (XmlElement) node;
- ifaces.Add (element.GetAttribute ("cname"));
+ if (element.HasAttribute ("cname"))
+ interfaces.Add (element.GetAttribute
("cname"));
+ else if (element.HasAttribute ("name"))
+ managed_interfaces.Add
(element.GetAttribute ("name"));
}
-
- return ifaces;
}
protected bool IgnoreMethod (Method method)
@@ -273,7 +273,7 @@
if (p == null && Parent != null)
p = Parent.GetMethodRecursively (name, true);
- if (check_self && p == null && interfaces != null) {
+ if (check_self && p == null) {
foreach (string iface in interfaces) {
ClassBase igen =
SymbolTable.Table.GetClassGen (iface);
p = igen.GetMethodRecursively (name,
true);
@@ -310,7 +310,7 @@
if (p == null && Parent != null)
p = Parent.GetSignalRecursively (name, true);
- if (check_self && p == null && interfaces != null) {
+ if (check_self && p == null) {
foreach (string iface in interfaces) {
ClassBase igen =
SymbolTable.Table.GetClassGen (iface);
p = igen.GetSignalRecursively (name,
true);
@@ -324,8 +324,10 @@
public bool Implements (string iface)
{
- if (interfaces != null)
- return interfaces.Contains (iface);
+ if (interfaces.Contains (iface))
+ return true;
+ else if (Parent != null)
+ return Parent.Implements (iface);
else
return false;
}
Modified: trunk/gtk-sharp/generator/ObjectGen.cs
===================================================================
--- trunk/gtk-sharp/generator/ObjectGen.cs 2005-04-11 20:27:40 UTC (rev
42804)
+++ trunk/gtk-sharp/generator/ObjectGen.cs 2005-04-11 20:35:56 UTC (rev
42805)
@@ -140,13 +140,16 @@
di.objects.Add (CName, QualifiedName);
sw.Write (" : " + cs_parent);
}
- if (interfaces != null) {
- foreach (string iface in interfaces) {
- if (Parent != null && Parent.Implements
(iface))
- continue;
- sw.Write (", " + table.GetCSType
(iface));
- }
+ foreach (string iface in interfaces) {
+ if (Parent != null && Parent.Implements (iface))
+ continue;
+ sw.Write (", " + table.GetCSType (iface));
}
+ foreach (string iface in managed_interfaces) {
+ if (Parent != null && Parent.Implements (iface))
+ continue;
+ sw.Write (", " + iface);
+ }
sw.WriteLine (" {");
sw.WriteLine ();
@@ -155,7 +158,7 @@
GenChildProperties (gen_info);
bool has_sigs = (sigs != null && sigs.Count > 0);
- if (!has_sigs && interfaces != null) {
+ if (!has_sigs) {
foreach (string iface in interfaces) {
ClassBase igen = table.GetClassGen
(iface);
if (igen != null && igen.Signals !=
null) {
@@ -180,7 +183,7 @@
GenMethods (gen_info, null, null);
- if (interfaces != null) {
+ if (interfaces.Count != 0) {
Hashtable all_methods = new Hashtable ();
Hashtable collisions = new Hashtable ();
foreach (string iface in interfaces) {
Modified: trunk/gtk-sharp/gtk/Container.custom
===================================================================
--- trunk/gtk-sharp/gtk/Container.custom 2005-04-11 20:27:40 UTC (rev
42804)
+++ trunk/gtk-sharp/gtk/Container.custom 2005-04-11 20:35:56 UTC (rev
42805)
@@ -48,6 +48,30 @@
}
}
+public IEnumerator GetEnumerator ()
+{
+ IntPtr list_ptr = gtk_container_get_children (Handle);
+ GLib.List list = new GLib.List (list_ptr);
+ return list.GetEnumerator ();
+}
+
+class ChildAccumulator {
+ public ArrayList Children = new ArrayList ();
+
+ public void Add (Gtk.Widget widget)
+ {
+ Children.Add (widget);
+ }
+}
+
+public IEnumerable AllChildren {
+ get {
+ ChildAccumulator acc = new ChildAccumulator ();
+ Forall (new Gtk.Callback (acc.Add));
+ return acc.Children;
+ }
+}
+
[DllImport("libgtk-win32-2.0-0.dll")]
static extern bool gtk_container_get_focus_chain (IntPtr raw, out IntPtr
list_ptr);
@@ -109,6 +133,7 @@
[GLib.CDeclCallback]
delegate void ForallDelegate (IntPtr container, bool include_internals, IntPtr
cb, IntPtr data);
+static ForallDelegate ForallOldCallback;
static ForallDelegate ForallCallback;
public struct CallbackInvoker {
@@ -139,13 +164,34 @@
}
}
-static void Forall_cb (IntPtr container, bool include_internals, IntPtr cb,
IntPtr data)
+static void ForallOld_cb (IntPtr container, bool include_internals, IntPtr cb,
IntPtr data)
{
Container obj = GLib.Object.GetObject (container, false) as Container;
CallbackInvoker invoker = new CallbackInvoker (cb, data);
obj.ForAll (include_internals, invoker);
}
+static void OverrideForallOld (GLib.GType gtype)
+{
+ if (ForallOldCallback == null)
+ ForallOldCallback = new ForallDelegate (ForallOld_cb);
+ gtksharp_container_override_forall (gtype, ForallOldCallback);
+}
+
+[Obsolete ("Override the ForAll(bool,Gtk.Callback) method instead")]
+[GLib.DefaultSignalHandler (Type=typeof(Gtk.Container),
ConnectionMethod="OverrideForallOld")]
+protected virtual void ForAll (bool include_internals, CallbackInvoker invoker)
+{
+ gtksharp_container_base_forall (Handle, include_internals,
invoker.Callback, invoker.Data);
+}
+
+static void Forall_cb (IntPtr container, bool include_internals, IntPtr cb,
IntPtr data)
+{
+ Container obj = GLib.Object.GetObject (container, false) as Container;
+ CallbackInvoker invoker = new CallbackInvoker (cb, data);
+ obj.ForAll (include_internals, new Gtk.Callback (invoker.Invoke));
+}
+
static void OverrideForall (GLib.GType gtype)
{
if (ForallCallback == null)
@@ -154,8 +200,14 @@
}
[GLib.DefaultSignalHandler (Type=typeof(Gtk.Container),
ConnectionMethod="OverrideForall")]
-protected virtual void ForAll (bool include_internals, CallbackInvoker invoker)
+protected virtual void ForAll (bool include_internals, Gtk.Callback callback)
{
+ CallbackInvoker invoker;
+ try {
+ invoker = (CallbackInvoker)callback.Target;
+ } catch {
+ throw new ApplicationException ("ForAll can only be called as
\"base.ForAll()\". Use Forall() or Foreach().");
+ }
gtksharp_container_base_forall (Handle, include_internals,
invoker.Callback, invoker.Data);
}
Modified: trunk/gtk-sharp/gtk/Gtk.metadata
===================================================================
--- trunk/gtk-sharp/gtk/Gtk.metadata 2005-04-11 20:27:40 UTC (rev 42804)
+++ trunk/gtk-sharp/gtk/Gtk.metadata 2005-04-11 20:35:56 UTC (rev 42805)
@@ -177,6 +177,7 @@
<attr path="/api/namespace/[EMAIL PROTECTED]'GtkColorSelection']/[EMAIL
PROTECTED]'SetPreviousColor']" name="hidden">1</attr>
<attr path="/api/namespace/[EMAIL PROTECTED]'GtkCombo']/[EMAIL
PROTECTED]'SetPopdownStrings']" name="hidden">1</attr>
<attr path="/api/namespace/[EMAIL PROTECTED]'GtkComboBox']/[EMAIL
PROTECTED]'gtk_combo_box_get_active_iter']/*/[EMAIL PROTECTED]'GtkTreeIter*']"
name="pass_as">out</attr>
+ <add-node path="/api/namespace/[EMAIL
PROTECTED]'GtkContainer']"><implements><interface name="IEnumerable"
/></implements></add-node>
<attr path="/api/namespace/[EMAIL PROTECTED]'GtkContainer']/[EMAIL
PROTECTED]'ChildGetProperty']" name="hidden">1</attr>
<attr path="/api/namespace/[EMAIL PROTECTED]'GtkContainer']/[EMAIL
PROTECTED]'Forall']/*/[EMAIL PROTECTED]'callback']" name="scope">call</attr>
<attr path="/api/namespace/[EMAIL PROTECTED]'GtkContainer']/[EMAIL
PROTECTED]'Foreach']/*/[EMAIL PROTECTED]'callback']" name="scope">call</attr>
Deleted: trunk/gtk-sharp/sample/CustomNotebook.cs
===================================================================
--- trunk/gtk-sharp/sample/CustomNotebook.cs 2005-04-11 20:27:40 UTC (rev
42804)
+++ trunk/gtk-sharp/sample/CustomNotebook.cs 2005-04-11 20:35:56 UTC (rev
42805)
@@ -1,642 +0,0 @@
-using GLib;
-using Gtk;
-using System;
-using System.Collections;
-
-class CustomNotebookTest {
- static CustomNotebook cn;
- static Notebook nb;
- static int tabCount;
-
- public static int Main (string[] args)
- {
- Application.Init ();
- Window win = new Window ("Custom Notebook Test");
- win.DeleteEvent += new DeleteEventHandler (OnQuit);
-
- VBox box = new VBox (false, 5);
- Button addButton = new Button ("Add Tab");
- //addButton.Clicked += OnAddTab;
- Button rmButton = new Button ("Remove Tab");
- rmButton.Clicked += OnRemoveTab;
- box.PackStart (addButton, false, false, 0);
- box.PackStart (rmButton, false, false, 0);
- HPaned paned = new HPaned ();
-
- cn = new CustomNotebook ();
- cn.BorderWidth = 5;
- cn.Scrollable = false;
- Gdk.Pixbuf icon = cn.RenderIcon (Stock.Execute, IconSize.Menu,
"");
- //for (tabCount = 0; tabCount < 3; tabCount++)
- cn.AppendPage (new Label ("Custom Notebook"),
Stock.Execute, "extended tab" + tabCount);
- cn.AppendPage (new Label ("Custom Notebook"),
Stock.Execute, "tab" + (tabCount + 1));
- cn.AppendPage (new Label ("Custom Notebook"),
Stock.Execute, "extended tab" + (tabCount + 2));
- paned.Pack1 (cn, true, false);
-
- nb = new Notebook ();
- nb.BorderWidth = 5;
- nb.Scrollable = false;
- for (tabCount = 0; tabCount < 3; tabCount++)
- nb.AppendPage (new Label ("Regular Notebook"), new
Label ("tab" + tabCount));
- paned.Pack2 (nb, true, false);
- box.PackEnd (paned, true, true, 0);
-
- win.Add (box);
- win.ShowAll ();
- Application.Run ();
- return 0;
- }
-
- /*static void OnAddTab (object sender, EventArgs args)
- {
- cn.AppendPage (new Label ("Custom Notebook"), Stock.Execute,
"tab" + tabCount + 1);
- cn.ShowAll ();
- nb.AppendPage (new Label ("Regular Notebook"), new Label ("tab"
+ tabCount + 1));
- nb.ShowAll ();
- tabCount++;
- }*/
-
- static void OnRemoveTab (object sender, EventArgs args)
- {
- }
-
- static void OnQuit (object sender, DeleteEventArgs args)
- {
- Application.Quit ();
- }
-}
-
-class CustomNotebookPage {
- private Gdk.Rectangle allocation;
- private Widget child = null;
- private Gdk.Pixbuf icon = null;
- private bool ellipsize = false;
- private string label = null;
- private Pango.Layout layout = null;
- private int layoutWidth = -1;
- private int layoutHeight = -1;
- private Requisition requisition;
- private string stockid = null;
-
- public Gdk.Rectangle Allocation {
- get {
- return allocation;
- }
- set {
- allocation = value;
- }
- }
-
- public Widget Child {
- get {
- return child;
- }
- set {
- child = value;
- }
- }
-
- public bool Ellipsize {
- get {
- return ellipsize;
- }
- set {
- ellipsize = value;
- }
- }
-
- public Gdk.Pixbuf Icon {
- get {
- if (icon == null && StockId != null) {
- icon = child.RenderIcon (StockId,
IconSize.Menu, "");
- }
-
- return icon;
- }
- set {
- icon = value;
- }
- }
-
- public string Label {
- get {
- return label;
- }
- set {
- label = value;
- layout = null;
- layoutWidth = -1;
- layoutHeight = -1;
- }
- }
-
- public Pango.Layout Layout {
- get {
- if (layout == null && Label != null) {
- layout = child.CreatePangoLayout (label);
- layout.GetPixelSize (out layoutWidth, out
layoutHeight);
- }
-
- return layout;
- }
- }
-
- public int LayoutWidth {
- get {
- if (Layout != null)
- return layoutWidth;
- else
- return -1;
- }
- }
-
- public int LayoutHeight {
- get {
- if (Layout != null)
- return layoutHeight;
- else
- return -1;
- }
- }
-
- public Requisition Requisition {
- get {
- return requisition;
- }
- set {
- requisition = value;
- }
- }
-
- public string StockId {
- get {
- return stockid;
- }
- set {
- stockid = value;
- icon = null;
- }
- }
-
- public CustomNotebookPage (Widget child, string label)
- {
- Child = child;
- Label = label;
- }
-
- public CustomNotebookPage (Widget child, Gdk.Pixbuf icon, string label)
- {
- Child = child;
- Icon = icon;
- Label = label;
- }
-
- public CustomNotebookPage (Widget child, string stockid, string label)
- {
- Child = child;
- Label = label;
- StockId = stockid;
- }
-}
-
-class CustomNotebook : Container {
- private readonly int tabCurvature = 1;
- private readonly int tabOverlap = 2;
- private ArrayList pages = new ArrayList ();
- private bool closable;
- private bool scrollable;
- private PositionType tabPosition;
- private int tabHBorder;
- private int tabVBorder;
-
- public bool Closable {
- get {
- return closable;
- }
- set {
- closable = value;
- }
- }
-
- private CustomNotebookPage CurrentPage {
- get {
- return (CustomNotebookPage)pages[0];
- }
- }
-
- public bool Scrollable {
- get {
- return scrollable;
- }
- set {
- scrollable = value;
- }
- }
-
- public Gtk.PositionType TabPosition {
- get {
- return tabPosition;
- }
- set {
- switch (value) {
- case PositionType.Left:
- case PositionType.Right:
- Console.WriteLine ("PositionType.Left
or Right is not supported by this widget");
- break;
- default:
- tabPosition = value;
- break;
- }
- }
- }
-
- /*static CustomNotebook ()
- {
- Container.OverrideForall (CustomNotebook.GType);
- }*/
-
- public CustomNotebook () : base ()
- {
- closable = true;
- scrollable = false;
- tabPosition = PositionType.Top;
- tabHBorder = 2;
- tabVBorder = 2;
-
- WidgetFlags |= WidgetFlags.NoWindow;
- }
-
- public void AppendPage (Widget child, string label)
- {
- pages.Add (new CustomNotebookPage (child, label));
- child.Parent = this;
- }
-
- public void AppendPage (Widget child, string stockid, string label)
- {
- pages.Add (new CustomNotebookPage (child, stockid, label));
- child.Parent = this;
- }
-
- public void AppendPage (Widget child, Gdk.Pixbuf icon, string label)
- {
- pages.Add (new CustomNotebookPage (child, icon, label));
- child.Parent = this;
- }
-
- private void EllipsizeLayout (Pango.Layout layout, int width)
- {
- if (width <= 0) {
- layout.SetText ("");
- return;
- }
-
- int layoutWidth, layoutHeight;
- layout.GetPixelSize (out layoutWidth, out layoutHeight);
- if (layoutWidth <= width)
- return;
-
- // Calculate ellipsis width.
- Pango.Layout ell = layout.Copy ();
- ell.SetText ("...");
- int ellWidth, ellHeight;
- ell.GetPixelSize (out ellWidth, out ellHeight);
-
- if (width < ellWidth) {
- // Not even ellipsis fits, so hide text.
- layout.SetText ("");
- return;
- }
-
- // Shrink total available width by the width of the ellipsis.
- width -= ellWidth;
- string text = layout.Text;
- Console.WriteLine ("layout text = {0}", text);
- Console.WriteLine ("line count: {0}", layout.LineCount);
- Pango.LayoutLine line = layout.Lines[0];
- //Console.WriteLine ("layout = {0}", line.layout.Text);
- //Console.WriteLine ("line = {0}", line.Length);
- int idx = 0, trailing = 0;
- if (line.XToIndex (width * 1024, out idx, out trailing)) {
- text = text.Substring (0, idx - 1);
- text += "...";
- layout.SetText (text);
- }
- }
-
- protected override bool OnExposeEvent (Gdk.EventExpose args)
- {
- int x, y, width, height, gapX, gapWidth;
- int bw = (int)BorderWidth;
-
- x = Allocation.X + bw;
- y = Allocation.Y + bw;
- width = Allocation.Width - 2 * bw;
- height = Allocation.Height - 2 * bw;
-
- switch (TabPosition) {
- case PositionType.Top:
- y += CurrentPage.Allocation.Height;
- height -= CurrentPage.Allocation.Height;
- break;
- case PositionType.Bottom:
- height -= CurrentPage.Allocation.Height;
- break;
- case PositionType.Left:
- case PositionType.Right:
- break;
- }
-
- gapX = gapWidth = 0;
- switch (TabPosition) {
- case PositionType.Top:
- case PositionType.Bottom:
- gapX = CurrentPage.Allocation.X - Allocation.X
- bw;
- gapWidth = CurrentPage.Allocation.Width;
- break;
- case PositionType.Left:
- case PositionType.Right:
- break;
- }
-
- Style.PaintBoxGap (Style, GdkWindow, StateType.Normal,
- ShadowType.Out, args.Area, this,
- "notebook", x, y, width, height,
- TabPosition, gapX, gapWidth);
-
- for (int i = pages.Count - 1; i >= 0; i--) {
- CustomNotebookPage page = (CustomNotebookPage)pages[i];
- Gdk.Rectangle pageAlloc = page.Allocation;
-
- StateType state = page == CurrentPage ?
StateType.Normal : StateType.Active;
- Style.PaintExtension (Style, GdkWindow, state,
- ShadowType.Out, args.Area, this,
- "tab", pageAlloc.X, pageAlloc.Y,
- pageAlloc.Width, pageAlloc.Height,
- PositionType.Bottom);
-
- // FIXME: Only add YThickness when TabPosition = Top;
- y = pageAlloc.Y + Style.YThickness + FocusLineWidth +
tabVBorder;
- height = pageAlloc.Height - Style.YThickness - 2 *
(tabVBorder + FocusLineWidth);
- if (page.Icon != null) {
- x = pageAlloc.X + (pageAlloc.Width + 1 -
- page.Icon.Width -
- page.LayoutWidth) / 2;
- int iconY = y + (height - page.Icon.Height) / 2;
-
- GdkWindow.DrawPixbuf (Style.BackgroundGC
(State),
- page.Icon, 0, 0, x, iconY,
- page.Icon.Width,
- page.Icon.Height,
- Gdk.RgbDither.None, 0, 0);
- x += page.Icon.Width + 1;
- } else {
- x = pageAlloc.X + (pageAlloc.Width -
page.LayoutWidth) / 2;
- }
-
- y += (height - page.LayoutHeight) / 2;
- if (page.Ellipsize) {
- width = pageAlloc.Width - (page.Icon.Width + 1);
- Pango.Layout layout = page.Layout;
- EllipsizeLayout (layout, width);
- Console.WriteLine ("ellLayout = {0}",
layout.Text);
- Style.PaintLayout (Style, GdkWindow, State,
- true, args.Area, this, null,
- x, y, layout);
- } else {
- Style.PaintLayout (Style, GdkWindow, State,
- true, args.Area, this, null,
- x, y, page.Layout);
- }
- }
-
- return base.OnExposeEvent (args);
- }
-
- protected override void ForAll (bool include_internals, CallbackInvoker
invoker)
- {
- foreach (CustomNotebookPage page in pages) {
- invoker.Invoke (page.Child);
- }
- }
-
- protected override void OnRealized ()
- {
- WidgetFlags |= WidgetFlags.Realized;
-
- GdkWindow = ParentWindow;
- Style = Style.Attach (GdkWindow);
- }
-
- protected override void OnSizeAllocated (Gdk.Rectangle allocation)
- {
- base.OnSizeAllocated (allocation);
-
- if (pages.Count == 0)
- return;
-
- int bw = (int)BorderWidth;
-
- Gdk.Rectangle childAlloc;
- childAlloc.X = allocation.X + bw + Style.XThickness;
- childAlloc.Y = allocation.Y + bw + Style.YThickness;
- childAlloc.Width = Math.Max (1, allocation.Width - 2 * bw -
- 2 * Style.XThickness);
- childAlloc.Height = Math.Max (1, allocation.Height - 2 * bw -
- 2 * Style.YThickness);
-
- switch (TabPosition) {
- case PositionType.Top:
- childAlloc.Y += CurrentPage.Requisition.Height;
- childAlloc.Height = Math.Max (1,
childAlloc.Height -
-
CurrentPage.Requisition.Height);
- break;
- case PositionType.Bottom:
- childAlloc.Height = Math.Max (1,
childAlloc.Height -
-
CurrentPage.Requisition.Height);
- break;
- case PositionType.Left:
- case PositionType.Right:
- break;
- }
-
- foreach (CustomNotebookPage page in pages) {
- page.Child.SizeAllocate (childAlloc);
- }
-
- // gtk_notebook_pages_allocate.
- childAlloc.X = allocation.X + bw;
- childAlloc.Y = allocation.Y + bw;
-
- switch (TabPosition) {
- case PositionType.Top:
- childAlloc.Height =
CurrentPage.Requisition.Height;
- break;
- case PositionType.Bottom:
- childAlloc.Y = (allocation.Y +
allocation.Height -
- CurrentPage.Requisition.Height
- bw);
- childAlloc.Height =
CurrentPage.Requisition.Height;
- break;
- case PositionType.Left:
- case PositionType.Right:
- break;
- }
-
- bool ellipsize = false;
- int avgWidth = 0;
- int tabX = childAlloc.X;
- if (!scrollable) {
- int tabWidth = 0;
- foreach (CustomNotebookPage page in pages) {
- tabWidth += page.Requisition.Width;
- }
-
- Console.WriteLine ("total tabwidth: {0}", tabWidth);
- Console.WriteLine ("allocated width: {0}",
childAlloc.Width);
-
- if (tabWidth > childAlloc.Width) {
- ellipsize = true;
- avgWidth = childAlloc.Width / pages.Count;
- tabWidth = childAlloc.Width;
- Console.WriteLine ("average tabwidth: {0}",
avgWidth);
-
- int count = pages.Count;
- foreach (CustomNotebookPage page in pages) {
- if (page.Requisition.Width <= avgWidth)
{
- count--;
- tabWidth -=
page.Requisition.Width;
- }
- }
-
- Console.WriteLine ("number of pages exceeding
that: {0}", count);
- Console.WriteLine ("space per page available:
{0}", tabWidth / count);
-
- // FIXME: check for TabPosition.
- int maxWidth = tabWidth / count;
- foreach (CustomNotebookPage page in pages) {
- Gdk.Rectangle pageAlloc =
page.Allocation;
- pageAlloc.X = tabX;
- pageAlloc.Y = childAlloc.Y;
-
- if (page.Requisition.Width > maxWidth) {
- pageAlloc.Width = maxWidth +
tabOverlap;
- page.Ellipsize = true;
- } else {
- pageAlloc.Width =
page.Requisition.Width + tabOverlap;
- }
-
- pageAlloc.Height = childAlloc.Height;
- tabX += pageAlloc.Width - tabOverlap;
-
- if (page != CurrentPage) {
- pageAlloc.Y += Style.YThickness;
- pageAlloc.Height -=
Style.YThickness;
- }
-
- page.Allocation = pageAlloc;
- }
- }
- } else {
- switch (TabPosition) {
- case PositionType.Top:
- case PositionType.Bottom:
- foreach (CustomNotebookPage page in
pages) {
- Gdk.Rectangle pageAlloc =
page.Allocation;
- pageAlloc.X = tabX;
- pageAlloc.Y = childAlloc.Y;
- pageAlloc.Width =
page.Requisition.Width + tabOverlap;
- pageAlloc.Height =
childAlloc.Height;
- tabX += pageAlloc.Width -
tabOverlap;
-
- if (page != CurrentPage) {
- pageAlloc.Y +=
Style.YThickness;
- pageAlloc.Height -=
Style.YThickness;
- }
-
- page.Allocation = pageAlloc;
- }
- break;
- case PositionType.Left:
- case PositionType.Right:
- break;
- }
- }
- }
-
- protected override void OnSizeRequested (ref Requisition requisition)
- {
- requisition.Width = requisition.Height = 0;
-
- foreach (CustomNotebookPage page in pages) {
- if (!page.Child.Visible)
- continue;
-
- Requisition childReq = page.Child.SizeRequest ();
- requisition.Width = Math.Max (requisition.Width,
childReq.Width);
- requisition.Height = Math.Max (requisition.Height,
childReq.Height);
- }
-
- requisition.Width += 2 * Style.XThickness;
- requisition.Height += 2 * Style.YThickness;
-
- int tabWidth = 0;
- int tabHeight = 0;
- int tabMax = 0;
- int padding;
- foreach (CustomNotebookPage page in pages) {
- Requisition pageReq;
- if (page.Icon != null) {
- pageReq.Width = page.Icon.Width +
page.LayoutWidth +
- Style.XThickness * 2;
- pageReq.Height = Math.Max (page.Icon.Height,
page.LayoutHeight) +
- Style.YThickness * 2;
- } else {
- pageReq.Width = page.LayoutWidth +
Style.XThickness * 2;
- pageReq.Height = page.LayoutHeight +
Style.YThickness * 2;
- }
-
- switch (TabPosition) {
- case PositionType.Top:
- case PositionType.Bottom:
- pageReq.Height += (tabVBorder +
FocusLineWidth) * 2;
- tabHeight = Math.Max (tabHeight,
pageReq.Height);
- tabMax = Math.Max (tabMax,
pageReq.Width);
- break;
- case PositionType.Left:
- case PositionType.Right:
- break;
- }
-
- page.Requisition = pageReq;
- }
-
- switch (TabPosition) {
- case PositionType.Top:
- case PositionType.Bottom:
- padding = 2 * (tabCurvature + FocusLineWidth
- + tabHBorder) - tabOverlap;
- tabMax += padding;
-
- Requisition pageReq;
- foreach (CustomNotebookPage page in pages) {
- pageReq = page.Requisition;
- pageReq.Width += padding;
- tabWidth += pageReq.Width;
- pageReq.Height = tabHeight;
- page.Requisition = pageReq;
- }
-
- /*if (!Scrollable)
- requisition.Width = Math.Max
(requisition.Width,
- tabWidth
+ tabOverlap);*/
- requisition.Height += tabHeight;
- break;
- case PositionType.Left:
- case PositionType.Right:
- break;
- }
-
- requisition.Width += (int)BorderWidth * 2;
- requisition.Height += (int)BorderWidth * 2;
- }
-}
Modified: trunk/gtk-sharp/sample/GtkDemo/DemoImages.cs
===================================================================
--- trunk/gtk-sharp/sample/GtkDemo/DemoImages.cs 2005-04-11 20:27:40 UTC
(rev 42804)
+++ trunk/gtk-sharp/sample/GtkDemo/DemoImages.cs 2005-04-11 20:35:56 UTC
(rev 42805)
@@ -122,8 +122,7 @@
{
ToggleButton toggle = o as ToggleButton;
- Widget[] children = vbox.Children;
- foreach (Widget widget in children) {
+ foreach (Widget widget in vbox) {
// don't disable our toggle
if (widget != toggle)
widget.Sensitive = !toggle.Active;
Modified: trunk/gtk-sharp/sample/Makefile.am
===================================================================
--- trunk/gtk-sharp/sample/Makefile.am 2005-04-11 20:27:40 UTC (rev 42804)
+++ trunk/gtk-sharp/sample/Makefile.am 2005-04-11 20:35:56 UTC (rev 42805)
@@ -40,7 +40,7 @@
DOTNET_ASSEMBLY=
endif
-TARGETS = custom-notebook.exe custom-widget.exe custom-cellrenderer.exe
gtk-hello-world.exe button.exe calendar.exe subclass.exe menu.exe size.exe
scribble.exe scribble-xinput.exe treeviewdemo.exe managedtreeviewdemo.exe
nodeviewdemo.exe testdnd.exe actions.exe $(GNOMEVFS_TARGETS) $(GNOME_TARGETS)
$(GLADE_TARGETS) $(VTE_TARGETS) $(DOTNET_TARGETS)
+TARGETS = polarfixed.exe custom-widget.exe custom-cellrenderer.exe
gtk-hello-world.exe button.exe calendar.exe subclass.exe menu.exe size.exe
scribble.exe scribble-xinput.exe treeviewdemo.exe managedtreeviewdemo.exe
nodeviewdemo.exe testdnd.exe actions.exe $(GNOMEVFS_TARGETS) $(GNOME_TARGETS)
$(GLADE_TARGETS) $(VTE_TARGETS) $(DOTNET_TARGETS)
DEBUGS = $(addsuffix .mdb, $(TARGETS))
@@ -124,8 +124,8 @@
actions.exe: $(srcdir)/Actions.cs
$(CSC) /debug /unsafe /out:actions.exe $(references)
$(srcdir)/Actions.cs
-custom-notebook.exe: $(srcdir)/CustomNotebook.cs $(assemblies)
- $(CSC) /debug /out:custom-notebook.exe $(references)
$(srcdir)/CustomNotebook.cs
+polarfixed.exe: $(srcdir)/PolarFixed.cs $(assemblies)
+ $(CSC) /debug /out:polarfixed.exe $(references) $(srcdir)/PolarFixed.cs
testvfs.exe: $(srcdir)/TestVfs.cs $(assemblies)
$(CSC) /debug /out:testvfs.exe $(references) $(srcdir)/TestVfs.cs
Added: trunk/gtk-sharp/sample/PolarFixed.cs
===================================================================
--- trunk/gtk-sharp/sample/PolarFixed.cs 2005-04-11 20:27:40 UTC (rev
42804)
+++ trunk/gtk-sharp/sample/PolarFixed.cs 2005-04-11 20:35:56 UTC (rev
42805)
@@ -0,0 +1,236 @@
+// This is a completely pointless widget, but it shows how to subclass
container...
+
+using System;
+using System.Collections;
+using Gtk;
+using Gdk;
+
+class PolarFixed : Container {
+ ArrayList children;
+
+ public PolarFixed ()
+ {
+ children = new ArrayList ();
+ WidgetFlags |= WidgetFlags.NoWindow;
+ }
+
+ // The child properties object
+ public class PolarFixedChild : ContainerChild {
+ double theta;
+ uint r;
+
+ public PolarFixedChild (PolarFixed parent, Widget child, double
theta, uint r) : base (parent, child)
+ {
+ this.theta = theta;
+ this.r = r;
+ }
+
+ // We call parent.QueueResize() from the property setters here
so that you
+ // can move the widget around just by changing its child
properties (just
+ // like with a native container class).
+
+ public double Theta {
+ get { return theta; }
+ set {
+ theta = value;
+ parent.QueueResize ();
+ }
+ }
+
+ public uint R {
+ get { return r; }
+ set {
+ r = value;
+ parent.QueueResize ();
+ }
+ }
+ }
+
+ // Override the child properties accessor to return the right object
from
+ // "children".
+ public override ContainerChild this [Widget w] {
+ get {
+ foreach (PolarFixedChild pfc in children) {
+ if (pfc.Child == w)
+ return pfc;
+ }
+ return null;
+ }
+ }
+
+ // Indicate the kind of children the container will accept. Most
containers
+ // will accept any kind of child, so they should return
Gtk.Widget.GType.
+ // The default is "GLib.GType.None", which technically means that no
(new)
+ // children can be added to the container, though Container.Add does not
+ // enforce this.
+ public override GLib.GType ChildType ()
+ {
+ return Gtk.Widget.GType;
+ }
+
+ // Implement gtk_container_forall(), which is also used by
+ // Gtk.Container.Children and Gtk.Container.AllChildren.
+ protected override void ForAll (bool include_internals, Callback
callback)
+ {
+ foreach (PolarFixedChild pfc in children)
+ callback (pfc.Child);
+ }
+
+ // Invoked by Container.Add (w). It's good practice to have this do
*something*,
+ // even if it's not something terribly useful.
+ protected override void OnAdded (Widget w)
+ {
+ Put (w, 0.0, 0);
+ }
+
+ // our own adder method
+ public void Put (Widget w, double theta, uint r)
+ {
+ children.Add (new PolarFixedChild (this, w, theta, r));
+ w.Parent = this;
+ QueueResize ();
+ }
+
+ public void Move (Widget w, double theta, uint r)
+ {
+ PolarFixedChild pfc = (PolarFixedChild)this[w];
+ if (pfc != null) {
+ pfc.Theta = theta;
+ pfc.R = r;
+ }
+ }
+
+ // invoked by Container.Remove (w)
+ protected override void OnRemoved (Widget w)
+ {
+ PolarFixedChild pfc = (PolarFixedChild)this[w];
+ if (pfc != null) {
+ pfc.Child.Unparent ();
+ children.Remove (pfc);
+ QueueResize ();
+ }
+ }
+
+ // Handle size request
+ protected override void OnSizeRequested (ref Requisition req)
+ {
+ Requisition childReq;
+ int x, y;
+
+ req.Width = req.Height = 0;
+ foreach (PolarFixedChild pfc in children) {
+ // Recursively SizeRequest each child
+ childReq = pfc.Child.SizeRequest ();
+
+ // Figure out where we're going to put it
+ x = (int)(Math.Cos (pfc.Theta) * pfc.R) +
childReq.Width / 2;
+ y = (int)(Math.Sin (pfc.Theta) * pfc.R) +
childReq.Height / 2;
+
+ // Update our own size request to fit it
+ if (req.Width < 2 * x)
+ req.Width = 2 * x;
+ if (req.Height < 2 * y)
+ req.Height = 2 * y;
+ }
+
+ // Take Container.BorderWidth into account
+ req.Width += (int)(2 * BorderWidth);
+ req.Height += (int)(2 * BorderWidth);
+ }
+
+ // Size allocation. Note that the allocation received may be smaller
than what we
+ // requested. Some containers will take that into account by giving
some or all
+ // of their children a smaller allocation than they requested. Other
containers
+ // (like this one) just let their children get placed partly
out-of-bounds if they
+ // aren't allocated enough room.
+ protected override void OnSizeAllocated (Rectangle allocation)
+ {
+ Requisition childReq;
+ int cx, cy, x, y;
+
+ // This sets the "Allocation" property. For widgets that
+ // have a GdkWindow, it also calls GdkWindow.MoveResize()
+ base.OnSizeAllocated (allocation);
+
+ // Figure out where the center of the grid will be
+ cx = allocation.X + (allocation.Width / 2);
+ cy = allocation.Y + (allocation.Height / 2);
+
+ foreach (PolarFixedChild pfc in children) {
+ // Use ChildRequisition rather than SizeRequest(),
+ // to ask for "what this child requested in the
+ // last SizeRequest", rather than having it
+ // compute it anew.
+ childReq = pfc.Child.ChildRequisition;
+
+ x = (int)(Math.Cos (pfc.Theta) * pfc.R) -
childReq.Width / 2;
+ y = (int)(Math.Sin (pfc.Theta) * pfc.R) +
childReq.Height / 2;
+
+ allocation.X = cx + x;
+ allocation.Width = childReq.Width;
+ allocation.Y = cy - y;
+ allocation.Height = childReq.Height;
+
+ pfc.Child.Allocation = allocation;
+ }
+ }
+}
+
+class Test {
+ public static void Main ()
+ {
+ uint r;
+ double theta;
+
+ Application.Init ();
+
+ Gtk.Window win = new Gtk.Window ("Polar Coordinate Container");
+ win.DeleteEvent += Window_Delete;
+
+ Notebook notebook = new Notebook ();
+ win.Add (notebook);
+
+ // Clock
+ PolarFixed pf = new PolarFixed ();
+ notebook.AppendPage (pf, new Label ("Clock"));
+
+ for (int hour = 1; hour <= 12; hour ++) {
+ theta = (Math.PI / 2) - hour * (Math.PI / 6);
+ if (theta < 0)
+ theta += 2 * Math.PI;
+
+ Label l = new Label ("<big><b>" + hour.ToString () +
"</b></big>");
+ l.UseMarkup = true;
+ pf.Put (l, theta, 200);
+ }
+
+ // Spiral
+ pf = new PolarFixed ();
+ notebook.AppendPage (pf, new Label ("Spiral"));
+
+ r = 0;
+ theta = 0.0;
+
+ foreach (string id in Gtk.Stock.ListIds ()) {
+ StockItem item = Gtk.Stock.Lookup (id);
+ if (item.Label == null)
+ continue;
+
+ pf.Put (new Gtk.Button (id), theta, r);
+
+ // Logarithmic spiral: r = a*e^(b*theta)
+ r += 5;
+ theta = 10 * Math.Log (10 * r);
+ }
+
+ win.ShowAll ();
+
+ Application.Run ();
+ }
+
+ static void Window_Delete (object obj, DeleteEventArgs args)
+ {
+ Application.Quit ();
+ args.RetVal = true;
+ }
+}
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches