no more submodule

This commit is contained in:
2024-09-15 22:40:48 +02:00
parent df3b8a3135
commit 0234b33671
5804 changed files with 943618 additions and 1 deletions

View File

@@ -0,0 +1,71 @@
// This is free and unencumbered software released into the public domain.
// Happy coding!!! - GtkSharp Team
using Gtk;
namespace Samples
{
[Section(ContentType = typeof(Button), Category = Category.Widgets)]
class ButtonSection : ListSection
{
public ButtonSection()
{
AddItem(CreateSimpleButton());
AddItem(CreateStockButton());
AddItem(CreateImageButton());
AddItem(CreateImageTextButton());
AddItem(CreateActionButton());
}
public (string, Widget) CreateSimpleButton()
{
var btn = new Button("Simple Button");
btn.Clicked += (sender, e) => ApplicationOutput.WriteLine(sender, "Clicked");
return ("Simple button:", btn);
}
public (string, Widget) CreateStockButton()
{
var btn = new Button(Stock.About);
btn.Clicked += (sender, e) => ApplicationOutput.WriteLine(sender, "Clicked");
return ("Stock button:", btn);
}
public (string, Widget) CreateImageButton()
{
var btn = new Button();
btn.AlwaysShowImage = true;
btn.Image = Image.NewFromIconName("document-new-symbolic", IconSize.Button);
btn.Clicked += (sender, e) => ApplicationOutput.WriteLine(sender, "Clicked");
return ("Image button:", btn);
}
public (string, Widget) CreateImageTextButton()
{
var btn = new Button();
btn.Label = "Some text";
btn.ImagePosition = PositionType.Top;
btn.AlwaysShowImage = true;
btn.Image = Image.NewFromIconName("document-new-symbolic", IconSize.Button);
btn.Clicked += (sender, e) => ApplicationOutput.WriteLine(sender, "Clicked");
return ("Image and text button:", btn);
}
public (string, Widget) CreateActionButton()
{
var sa = new GLib.SimpleAction("SampleAction", null);
sa.Activated += (sender, e) => ApplicationOutput.WriteLine(sender, "SampleAction Activated");
Program.App.AddAction(sa);
var btn = new Button();
btn.Label = "SampleAction Button";
btn.ActionName = "app.SampleAction";
return ("Action button:", btn);
}
}
}

View File

@@ -0,0 +1,53 @@
using Gtk;
using System;
namespace Samples
{
[Section (ContentType = typeof(CustomCellRenderer), Category = Category.Widgets)]
class CellRendererSection : ListSection
{
public CellRendererSection ()
{
AddItem (CreateCellRenderer ());
}
ListStore liststore;
public (string, Widget) CreateCellRenderer ()
{
liststore = new ListStore (typeof (float), typeof (string));
liststore.AppendValues (0.5f, "50%");
TreeView view = new TreeView (liststore);
view.AppendColumn ("Progress", new CellRendererText (), "text", 1);
view.AppendColumn ("Progress", new CustomCellRenderer (), "percent", 0);
GLib.Timeout.Add (50, new GLib.TimeoutHandler (update_percent));
return (nameof(CustomCellRenderer), view);
}
bool increasing = true;
bool update_percent ()
{
TreeIter iter;
liststore.GetIterFirst (out iter);
float perc = (float) liststore.GetValue (iter, 0);
if ((perc > 0.99) || (perc < 0.01 && perc > 0)) {
increasing = !increasing;
}
if (increasing)
perc += 0.01f;
else
perc -= 0.01f;
liststore.SetValue (iter, 0, perc);
liststore.SetValue (iter, 1, Convert.ToInt32 (perc * 100) + "%");
return true;
}
}
}

View File

@@ -0,0 +1,38 @@
// This is free and unencumbered software released into the public domain.
// Happy coding!!! - GtkSharp Team
using Gtk;
namespace Samples
{
[Section(ContentType = typeof(ColorButton), Category = Category.Widgets)]
class ColorButtonSection : ListSection
{
public ColorButtonSection()
{
AddItem(CreateColorButton());
}
public (string, Widget) CreateColorButton()
{
var btn = new ColorButton();
// Set RGBA color
btn.Rgba = new Gdk.RGBA()
{
Red = 0,
Green = 0,
Blue = 255,
Alpha = 0.2 // 20% translucent
};
// Or Parse hex
btn.Rgba.Parse("#729FCF");
// UseAlpha default is false
btn.UseAlpha = true;
return ("Color button:", btn);
}
}
}

View File

@@ -0,0 +1,97 @@
// This is free and unencumbered software released into the public domain.
// Happy coding!!! - GtkSharp Team
using Gtk;
namespace Samples
{
[Section(ContentType = typeof(ComboBox), Category = Category.Widgets)]
class ComboBoxSection : ListSection
{
public ComboBoxSection()
{
AddItem(CreateSimpleComboBox());
AddItem(CreateMultiColumnComboBox());
AddItem(CreateEditableComboBox());
}
public (string, Widget) CreateSimpleComboBox()
{
// initialize with a simple string list
var combo = new ComboBox(
new string[]
{
"Combo Entry 1",
"Combo Entry 2",
"Combo Entry 3",
"Combo Entry 4"
}
);
// event to notify for index changes in our combo
combo.Changed += (sender, e) =>
ApplicationOutput.WriteLine(sender, $"Index changed to:{((ComboBox)sender).Active}");
// set the active selection to index 2 (Combo Entry 3)
combo.Active = 2;
return ("Simple combo:", combo);
}
public (string, Widget) CreateMultiColumnComboBox()
{
// create a store for our combo
var store = new ListStore(typeof(string), typeof(string), typeof(bool));
// lets append some stock icons, passing the icon names, and a simple text column
store.AppendValues("dialog-warning", "Warning", true);
store.AppendValues("process-stop", "Stop", false);
store.AppendValues("document-new", "New", true);
store.AppendValues("edit-clear", "Clear", true);
// create cells
var imageCell = new CellRendererPixbuf();
var textCell = new CellRendererText();
// create the combo and pass the values in
var combo = new ComboBox(store);
combo.PackStart(imageCell, true);
combo.PackStart(textCell, true);
// add combo attributes to show in columns
combo.AddAttribute(imageCell, "icon-name", 0);
combo.AddAttribute(textCell, "text", 1);
// lets use the store bool values to control sensitive rows
// Process-stop (store index one) should be disabled in this sample
// For a ComboBox item to be disabled, all cell renderers for the item need to have
// their sensitivity disabled
combo.AddAttribute(imageCell, "sensitive", 2);
combo.AddAttribute(textCell, "sensitive", 2);
// listen to index changed on combo
combo.Changed += (sender, e) =>
ApplicationOutput.WriteLine(sender, $"Index changed to:{((ComboBox)sender).Active}");
// lets preselect the first option
combo.Active = 0;
return ("Combo with Icons and Text:", combo);
}
public (string, Widget) CreateEditableComboBox()
{
var combo = ComboBoxText.NewWithEntry();
combo.AppendText("Example 1");
combo.AppendText("Example 2");
combo.AppendText("Example 3");
combo.AppendText("Example 4");
// combos with entry have a real entry inside it
// we can use it by
combo.Entry.PlaceholderText = "Write something";
return ("Combo with entry:", combo);
}
}
}

View File

@@ -0,0 +1,47 @@
using System;
using Gtk;
namespace Samples
{
[Section(ContentType = typeof(CompositeWidget), Category = Category.Widgets)]
class CompositeWidgetSection : ListSection
{
public CompositeWidgetSection()
{
AddItem("CompositeWidget:", new CompositeWidget());
AddItem("Other instance:", new CompositeWidget());
}
}
[Template("CompositeWidget.glade", true)]
[GLib.TypeName(nameof(CompositeWidget))]
class CompositeWidget : Bin
{
#pragma warning disable CS0649, CS0169
[Child] Button btn1;
[Child] Button btn2;
[Child("label")] Entry entry;
#pragma warning restore CS0649, CS0169
public CompositeWidget()
{
// Base constructor sets [Child] fields
// if [Template(throwOnUnknownChild = true) and GTK can't bind any [Child] field then base constructor throws
// GTK writes invalid field/widget name in console (project <OutputType> must be Exe to see console on Windows OS)
System.Diagnostics.Debug.Assert(btn1 != null);
System.Diagnostics.Debug.Assert(btn2 != null);
System.Diagnostics.Debug.Assert(entry != null);
}
private void on_btn1_clicked(object sender, EventArgs e)
{
entry.Text = DateTime.Now.ToString();
ApplicationOutput.WriteLine(this, "Instance handler clicked");
}
private static void on_btn2_clicked(object sender, EventArgs e)
{
ApplicationOutput.WriteLine("Static handler clicked");
}
}
}

View File

@@ -0,0 +1,78 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.38.2 -->
<interface>
<requires lib="gtk+" version="3.18"/>
<template class="CompositeWidget" parent="GtkBin">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<object class="GtkButton" id="btn1">
<property name="label" translatable="yes">Instance handler</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="margin-start">3</property>
<property name="margin-end">3</property>
<property name="margin-top">3</property>
<property name="margin-bottom">3</property>
<signal name="clicked" handler="on_btn1_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="btn2">
<property name="label" translatable="yes">Static handler</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="margin-start">3</property>
<property name="margin-end">3</property>
<property name="margin-top">3</property>
<property name="margin-bottom">3</property>
<signal name="clicked" handler="on_btn2_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="label">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="margin-start">3</property>
<property name="margin-end">3</property>
<property name="margin-top">3</property>
<property name="margin-bottom">3</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</template>
</interface>

View File

@@ -0,0 +1,77 @@
// CustomCellRenderer.cs : C# implementation of an example custom cellrenderer
// from http://scentric.net/tutorial/sec-custom-cell-renderers.html
//
// Author: Todd Berman <tberman@sevenl.net>
//
// (c) 2004 Todd Berman
// adopted from: https://github.com/mono/gtk-sharp/commits/2.99.3/sample/CustomCellRenderer.cs
using System;
using Gtk;
using Gdk;
using GLib;
namespace Samples
{
public class CustomCellRenderer : CellRenderer
{
private float percent;
[GLib.Property ("percent")]
public float Percentage {
get { return percent; }
set { percent = value; }
}
protected override void OnGetSize (Widget widget, ref Rectangle cell_area, out int x_offset, out int y_offset, out int width, out int height)
{
base.OnGetSize (widget, ref cell_area, out x_offset, out y_offset, out width, out height);
int calc_width = (int) this.Xpad * 2 + 100;
int calc_height = (int) this.Ypad * 2 + 10;
width = calc_width;
height = calc_height;
x_offset = 0;
y_offset = 0;
if (!cell_area.Equals (Rectangle.Zero)) {
x_offset = (int) (this.Xalign * (cell_area.Width - calc_width));
x_offset = Math.Max (x_offset, 0);
y_offset = (int) (this.Yalign * (cell_area.Height - calc_height));
y_offset = Math.Max (y_offset, 0);
}
}
protected override void OnRender (Cairo.Context cr, Widget widget, Rectangle background_area, Rectangle cell_area, CellRendererState flags)
{
int x = (int) (cell_area.X + this.Xpad);
int y = (int) (cell_area.Y + this.Ypad);
int width = (int) (cell_area.Width - this.Xpad * 2);
int height = (int) (cell_area.Height - this.Ypad * 2);
widget.StyleContext.Save ();
widget.StyleContext.AddClass ("trough");
widget.StyleContext.RenderBackground (cr, x, y, width, height);
widget.StyleContext.RenderFrame (cr, x, y, width, height);
Border padding = widget.StyleContext.GetPadding (StateFlags.Normal);
x += padding.Left;
y += padding.Top;
width -= padding.Left + padding.Right;
height -= padding.Top + padding.Bottom;
widget.StyleContext.Restore ();
widget.StyleContext.Save ();
widget.StyleContext.AddClass ("progressbar");
widget.StyleContext.RenderActivity (cr, x, y, (int) (width * Percentage), height);
widget.StyleContext.Restore ();
}
}
}

View File

@@ -0,0 +1,110 @@
// adopted from: https://github.com/mono/xwt/blob/master/Xwt.XamMac/Xwt.Mac/ImageHandler.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using Gtk;
using Gdk;
using System.Runtime.InteropServices;
using Cairo;
using Rectangle = Gdk.Rectangle;
namespace Samples
{
// This is a completely pointless widget, but its for testing subclassing Widget.OnDrawn
public class GtkDrawingArea : Gtk.DrawingArea { }
public class ImageBox : GtkDrawingArea
{
Pixbuf image;
float yalign = 0.5f, xalign = 0.5f;
public ImageBox(Pixbuf img) : this()
{
Image = img;
}
public ImageBox()
{
this.HasWindow = false;
this.AppPaintable = true;
}
public Pixbuf Image {
get { return image; }
set {
image = value;
SetSizeRequest((int) image.Width, (int) image.Height);
//QueueDraw();
}
}
private Size SizeRequestet { get; set; }
public float Yalign {
get { return yalign; }
set {
yalign = value;
QueueDraw();
}
}
public float Xalign {
get { return xalign; }
set {
xalign = value;
QueueDraw();
}
}
void DrawPixbuf(Cairo.Context ctx, Gdk.Pixbuf img, double x, double y, Size idesc)
{
ctx.Save();
ctx.Translate(x, y);
ctx.Scale(idesc.Width / (double) img.Width, idesc.Height / (double) img.Height);
Gdk.CairoHelper.SetSourcePixbuf(ctx, img, 0, 0);
#pragma warning disable 618
using (var p = ctx.Source) {
if (p is SurfacePattern pattern) {
if (idesc.Width > img.Width || idesc.Height > img.Height) {
// Fixes blur issue when rendering on an image surface
pattern.Filter = Cairo.Filter.Fast;
} else
pattern.Filter = Cairo.Filter.Good;
}
}
#pragma warning restore 618
ctx.Paint();
ctx.Restore();
}
protected override bool OnDrawn(Cairo.Context cr)
{
if (image == default)
return true;
var a = Allocation;
var size = Allocation.Size;
Pixbuf pixbuff = image;
// HACK: Gtk sends sometimes an expose/draw event while the widget reallocates.
// In that case we would draw in the wrong area, which may lead to artifacts
// if no other widget updates it. Alternative: we could clip the
// allocation bounds, but this may have other issues.
if (a.Width == 1 && a.Height == 1 && a.X == -1 && a.Y == -1) // the allocation coordinates on reallocation
return base.OnDrawn(cr);
var x = (int) ((a.Width - (float) pixbuff.Width) * xalign);
var y = (int) ((a.Height - (float) pixbuff.Height) * yalign);
if (x < 0) x = 0;
if (y < 0) y = 0;
DrawPixbuf(cr, pixbuff, x, y, size);
return base.OnDrawn(cr);
}
}
}

View File

@@ -0,0 +1,196 @@
// adopted from: https://github.com/mono/gtk-sharp/commits/2.99.3/sample/PolarFixed.cs
// This is a completely pointless widget, but it shows how to subclass container...
using System;
using System.Collections.Generic;
using Gtk;
using Gdk;
namespace Samples
{
class PolarFixed : Container
{
IList<PolarFixedChild> children;
public PolarFixed()
{
children = new List<PolarFixedChild>();
HasWindow = false;
}
// The child properties object
public class PolarFixedChild : Container.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.
protected override GLib.GType OnChildType()
{
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)
{
base.ForAll(include_internals, 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 OnGetPreferredHeight(out int minimal_height, out int natural_height)
{
Requisition req = new Requisition();
OnSizeRequested(ref req);
minimal_height = natural_height = req.Height;
}
protected override void OnGetPreferredWidth(out int minimal_width, out int natural_width)
{
Requisition req = new Requisition();
OnSizeRequested(ref req);
minimal_width = natural_width = req.Width;
}
void OnSizeRequested(ref Requisition req)
{
int child_width, child_minwidth, child_height, child_minheight;
int x, y;
req.Width = req.Height = 0;
foreach (PolarFixedChild pfc in children) {
// Recursively request the size of each child
pfc.Child.GetPreferredWidth(out child_minwidth, out child_width);
pfc.Child.GetPreferredHeight(out child_minheight, out child_height);
// Figure out where we're going to put it
x = (int) (Math.Cos(pfc.Theta) * pfc.R) + child_width / 2;
y = (int) (Math.Sin(pfc.Theta) * pfc.R) + child_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, childMinReq;
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) {
pfc.Child.GetPreferredSize(out childMinReq, out childReq);
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.SizeAllocate(allocation);
}
}
}
}

View File

@@ -0,0 +1,138 @@
// This is free and unencumbered software released into the public domain.
// Happy coding!!! - GtkSharp Team
// Ported from https://developer.gnome.org/gtkmm-tutorial/3.24/gtkmm-tutorial.html
using Cairo;
using Gtk;
using System;
namespace Samples
{
[Section(ContentType = typeof(DrawingArea), Category = Category.Widgets)]
class DrawingAreaSection : ListSection
{
public DrawingAreaSection()
{
AddItem(DrawCircles());
AddItem(DrawText());
}
public (string, Widget) DrawCircles()
{
DrawingArea drawingArea = new DrawingArea();
drawingArea.SetSizeRequest(50,50);
drawingArea.Drawn += DrawingAreaCirclesOnDrawn;
return ("Draw Circles :", drawingArea);
}
public (string, Widget) DrawText()
{
DrawingArea drawingArea = new DrawingArea();
drawingArea.SetSizeRequest(200,100);
drawingArea.Drawn += DrawingAreaTextOnDrawn;
return ("Draw Pango Text :", drawingArea);
}
private void DrawingAreaCirclesOnDrawn(object o, DrawnArgs args)
{
if (o is DrawingArea da)
{
Context cr = args.Cr;
int width = da.Allocation.Width;
int height = da.Allocation.Height;
cr.LineWidth = 5;
cr.SetSourceRGB(0.8, 0.8, 0.8);
cr.Rectangle(0, 0, width, height);
cr.Fill();
cr.SetSourceRGB(0.9, 0, 0);
cr.Translate(width/2d, height/2d);
cr.Arc(0, 0, (width < height ? width : height) / 2 - 10, 0, 2*Math.PI);
cr.StrokePreserve();
cr.SetSourceRGB(0, 0.9, 0);
cr.Fill();
cr.GetTarget().Dispose();
cr.Dispose();
}
}
private void DrawingAreaTextOnDrawn(object o, DrawnArgs args)
{
if (o is DrawingArea da)
{
Context cr = args.Cr;
int width = da.Allocation.Width;
int height = da.Allocation.Height;
int rectangle_width = width;
int rectangle_height = height / 2;
// Draw a black rectangle
cr.SetSourceRGB(0, 0, 0);
cr.Rectangle(0, 0, rectangle_width, rectangle_height);
cr.Fill();
// and some white text
cr.SetSourceRGB(1.0, 1.0, 1.0);
draw_text(cr, rectangle_width, rectangle_height, "Hi there!");
// flip the image vertically
// see http://www.cairographics.org/documentation/cairomm/reference/classCairo_1_1Matrix.html
// the -1 corresponds to the yy part (the flipping part)
// the height part is a translation (we could have just called cr->translate(0, height) instead)
// it's height and not height / 2, since we want this to be on the second part of our drawing
// (otherwise, it would draw over the previous part)
Cairo.Matrix matrix = new Matrix(1.0, 0.0, 0.0, -1.0, 0.0, height);
// apply the matrix
cr.Transform(matrix);
// white rectangle
cr.SetSourceRGB(1.0, 1.0, 1.0);
cr.Rectangle(0, 0, rectangle_width, rectangle_height);
cr.Fill();
// black text
cr.SetSourceRGB(0, 0, 0);
draw_text(cr, rectangle_width, rectangle_height, "Hi there!");
cr.GetTarget().Dispose();
cr.Dispose();
}
}
private void draw_text(Context cr, int rectangle_width, int rectangle_height, string text)
{
// http://developer.gnome.org/pangomm/unstable/classPango_1_1FontDescription.html
Pango.FontDescription font = new Pango.FontDescription();
font.Family = "Monospace";
font.Weight = Pango.Weight.Bold;
// http://developer.gnome.org/pangomm/unstable/classPango_1_1Layout.html
Pango.Layout layout = CreatePangoLayout(text);
layout.FontDescription = font;
int text_width;
int text_height;
//get the text dimensions (it updates the variables -- by reference)
layout.GetPixelSize(out text_width, out text_height);
// Position the text in the middle
cr.MoveTo((rectangle_width - text_width) / 2d, (rectangle_height - text_height) / 2d);
Pango.CairoHelper.ShowLayout(cr, layout);
}
}
}

View File

@@ -0,0 +1,291 @@
using System;
using System.Collections.Generic;
using Gtk;
namespace Samples.Sections.Widgets
{
[Section(ContentType = typeof(EditableCellsSection), Category = Category.Widgets)]
class EditableCellsSection : Box
{
private readonly TreeView _treeView;
private readonly ListStore _itemsModel;
private readonly Dictionary<CellRenderer, int> _cellColumnsRender;
private List<Item> _articles;
public EditableCellsSection() : base(Orientation.Vertical, 3)
{
_cellColumnsRender = new Dictionary<CellRenderer, int>();
ListStore numbers_model;
ScrolledWindow sw = new ScrolledWindow
{
ShadowType = ShadowType.EtchedIn
};
sw.SetPolicy(PolicyType.Automatic, PolicyType.Automatic);
this.PackStart(sw, true, true, 0);
/* create models */
_itemsModel = CreateItemsModel();
numbers_model = CreateNumbersModel();
/* create tree view */
_treeView = new TreeView(_itemsModel);
_treeView.Selection.Mode = SelectionMode.Single;
AddColumns(numbers_model);
sw.Add(_treeView);
/* some buttons */
Box hbox = new Box(Orientation.Horizontal, 4)
{
Homogeneous = true
};
this.PackStart(hbox, false, false, 0);
Button button = new Button("Add item");
button.Clicked += AddItem;
hbox.PackStart(button, true, true, 0);
button = new Button("Remove item");
button.Clicked += RemoveItem;
hbox.PackStart(button, true, true, 0);
}
private class Item
{
public int Number;
public string Product;
public int Yummy;
}
private enum ColumnItem
{
Number,
Product,
Yummy,
Num
};
private enum ColumnNumber
{
Text,
Num
};
private ListStore CreateItemsModel()
{
ListStore model;
TreeIter iter;
/* create array */
_articles = new List<Item>();
AddItems();
/* create list store */
model = new ListStore(typeof(int), typeof(string), typeof(int), typeof(bool));
/* add items */
for (int i = 0; i < _articles.Count; i++)
{
iter = model.Append();
model.SetValue(iter, (int)ColumnItem.Number, _articles[i].Number);
model.SetValue(iter, (int)ColumnItem.Product, _articles[i].Product);
model.SetValue(iter, (int)ColumnItem.Yummy, _articles[i].Yummy);
}
return model;
}
private static ListStore CreateNumbersModel()
{
ListStore model;
TreeIter iter;
/* create list store */
model = new ListStore(typeof(string), typeof(int));
/* add numbers */
for (int i = 0; i < 10; i++)
{
iter = model.Append();
model.SetValue(iter, (int)ColumnNumber.Text, i.ToString());
}
return model;
}
private void AddItems()
{
Item foo = new Item
{
Number = 3,
Product = "bottles of coke",
Yummy = 20
};
_articles.Add(foo);
foo = new Item
{
Number = 5,
Product = "packages of noodles",
Yummy = 50
};
_articles.Add(foo);
foo = new Item
{
Number = 2,
Product = "packages of chocolate chip cookies",
Yummy = 90
};
_articles.Add(foo);
foo = new Item
{
Number = 1,
Product = "can vanilla ice cream",
Yummy = 60
};
_articles.Add(foo);
foo = new Item
{
Number = 6,
Product = "eggs",
Yummy = 10
};
_articles.Add(foo);
}
private void AddColumns(ITreeModel numbersModel)
{
/* number column */
CellRendererCombo rendererCombo = new CellRendererCombo
{
Model = numbersModel,
TextColumn = (int)ColumnNumber.Text,
HasEntry = false,
Editable = true
};
rendererCombo.Edited += CellEdited;
rendererCombo.EditingStarted += EditingStarted;
_cellColumnsRender.Add(rendererCombo, (int)ColumnItem.Number);
_treeView.InsertColumn(-1, "Number", rendererCombo, "text", (int)ColumnItem.Number);
/* product column */
CellRendererText rendererText = new CellRendererText
{
Editable = true
};
rendererText.Edited += CellEdited;
_cellColumnsRender.Add(rendererText, (int)ColumnItem.Product);
_treeView.InsertColumn(-1, "Product", rendererText, "text", (int)ColumnItem.Product);
/* yummy column */
CellRendererProgress rendererProgress = new CellRendererProgress();
_cellColumnsRender.Add(rendererProgress, (int)ColumnItem.Yummy);
_treeView.InsertColumn(-1, "Yummy", rendererProgress, "value", (int)ColumnItem.Yummy);
}
private void AddItem(object sender, EventArgs e)
{
TreeIter iter;
if (_articles == null)
{
return;
}
Item foo = new Item
{
Number = 0,
Product = "Description here",
Yummy = 50
};
_articles.Add(foo);
/* Insert a new row below the current one */
_treeView.GetCursor(out TreePath path, out _);
if (path != null)
{
_ = _itemsModel.GetIter(out TreeIter current, path);
iter = _itemsModel.InsertAfter(current);
}
else
{
iter = _itemsModel.Insert(-1);
}
/* Set the data for the new row */
_itemsModel.SetValue(iter, (int)ColumnItem.Number, foo.Number);
_itemsModel.SetValue(iter, (int)ColumnItem.Product, foo.Product);
_itemsModel.SetValue(iter, (int)ColumnItem.Yummy, foo.Yummy);
/* Move focus to the new row */
path = _itemsModel.GetPath(iter);
TreeViewColumn column = _treeView.GetColumn(0);
_treeView.SetCursor(path, column, false);
}
private void RemoveItem(object sender, EventArgs e)
{
TreeSelection selection = _treeView.Selection;
if (selection.GetSelected(out TreeIter iter))
{
TreePath path = _itemsModel.GetPath(iter);
int i = path.Indices[0];
_itemsModel.Remove(ref iter);
_articles.RemoveAt(i);
}
}
private void CellEdited(object data, EditedArgs args)
{
TreePath path = new TreePath(args.Path);
int column = _cellColumnsRender[(CellRenderer)data];
_itemsModel.GetIter(out TreeIter iter, path);
switch (column)
{
case (int)ColumnItem.Number:
{
int i = path.Indices[0];
_articles[i].Number = int.Parse(args.NewText);
_itemsModel.SetValue(iter, column, _articles[i].Number);
}
break;
case (int)ColumnItem.Product:
{
string oldText = (string)_itemsModel.GetValue(iter, column);
int i = path.Indices[0];
_articles[i].Product = args.NewText;
_itemsModel.SetValue(iter, column, _articles[i].Product);
}
break;
}
}
private void EditingStarted(object o, EditingStartedArgs args)
{
((ComboBox)args.Editable).RowSeparatorFunc += SeparatorRow;
}
private bool SeparatorRow(ITreeModel model, TreeIter iter)
{
TreePath path = model.GetPath(iter);
int idx = path.Indices[0];
return idx == 5;
}
}
}

View File

@@ -0,0 +1,163 @@
// This is free and unencumbered software released into the public domain.
// Happy coding!!! - GtkSharp Team
using Gtk;
namespace Samples
{
[Section(ContentType = typeof(Entry), Category = Category.Widgets)]
class EntrySection : ListSection
{
public EntrySection()
{
AddItem(CreateSimpleEntry());
AddItem(CreateSimpleRightAlignedTextEntry());
AddItem(CreateMaxLimitEntry());
AddItem(CreatePlaceholderEntry());
AddItem(CreateInvisibleCharEntry());
AddItem(CreateCustomActionsEntry());
AddItem(CreateProgressEntry());
AddItem(CreateCompletionEntry());
AddItem(CreateInsensitiveEntry());
}
public (string, Widget) CreateSimpleEntry()
{
var entry = new Entry("Initial Text");
entry.TooltipText = "This is the tooltip!";
entry.Changed += (sender, e) => ApplicationOutput.WriteLine(sender, "Changed");
return ("Simple entry:", entry);
}
public (string, Widget) CreateSimpleRightAlignedTextEntry()
{
var entry = new Entry("Text is Right Aligned");
entry.Xalign = 1f;
entry.Changed += (sender, e) => ApplicationOutput.WriteLine(sender, "Changed");
return ("Right aligned text entry:", entry);
}
public (string, Widget) CreateMaxLimitEntry()
{
var entry = new Entry("123");
entry.MaxLength = 3;
entry.Changed += (sender, e) => ApplicationOutput.WriteLine(sender, "Changed");
return ("Text length limited entry:", entry);
}
public (string, Widget) CreatePlaceholderEntry()
{
var entry = new Entry();
entry.PlaceholderText = "Please fill with information";
entry.Changed += (sender, e) => ApplicationOutput.WriteLine(sender, "Changed");
return ("Placeholder text entry:", entry);
}
public (string, Widget) CreateInvisibleCharEntry()
{
var entry = new Entry("Invisible text entry");
entry.Visibility = false;
entry.InvisibleChar = '\u2022';
entry.InvisibleCharSet = true;
entry.Changed += (sender, e) => ApplicationOutput.WriteLine(sender, "Changed");
return ("Invisible text entry:", entry);
}
public (string, Widget) CreateCustomActionsEntry()
{
var entry = new Entry();
entry.PlaceholderText = "Search";
entry.SetIconFromIconName(EntryIconPosition.Primary, "edit-find-symbolic");
entry.SetIconFromIconName(EntryIconPosition.Secondary, "edit-clear-symbolic");
entry.IconRelease += (o, args) =>
{
switch (args.P0)
{
case EntryIconPosition.Primary:
ApplicationOutput.WriteLine(o, "Clicked Search Icon");
break;
default:
entry.Text = string.Empty;
ApplicationOutput.WriteLine(o, "Clicked Clear Icon");
break;
}
};
return ("Custom actions entry:", entry);
}
public (string, Widget) CreateProgressEntry()
{
var entry = new Entry();
entry.PlaceholderText = "Progress Entry";
entry.ProgressFraction = 0f;
entry.MaxLength = 20;
entry.Changed += (sender, e) => entry.ProgressFraction = (float)entry.Text.Length / entry.MaxLength;
return ("Progress entry:", entry);
}
public (string, Widget) CreateCompletionEntry()
{
// create completion object and assign it to entry
var completion = new EntryCompletion();
var entry = new Entry();
entry.Completion = completion;
// create values store
var store = new ListStore(typeof(string));
store.AppendValues("An example to search for");
store.AppendValues("Better example");
store.AppendValues("Better and bigger example");
store.AppendValues("Some other example");
// assign treemodel as the completion
completion.Model = store;
// lets override the default match function so we can use the contains mode
// instead of the default startswith
completion.MatchFunc = (EntryCompletion comp, string key, TreeIter iter) =>
{
if (string.IsNullOrEmpty(key))
return false;
var o = comp.Model.GetValue(iter, 0);
var stringToSearch = o as string;
if (!string.IsNullOrEmpty(stringToSearch))
return stringToSearch.IndexOf(key, System.StringComparison.InvariantCultureIgnoreCase) >= 0;
return false;
};
completion.TextColumn = 0;
return ("Completion Entry:",entry);
}
public (string, Widget) CreateInsensitiveEntry()
{
var entry = new Entry();
entry.Text = "Cannot change this";
entry.Sensitive = false;
return ("Insensitive entry:", entry);
}
}
}

View File

@@ -0,0 +1,30 @@
// This is free and unencumbered software released into the public domain.
// Happy coding!!! - GtkSharp Team
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using Atk;
using Gdk;
using Gtk;
namespace Samples
{
[Section(ContentType = typeof(ImageBox), Category = Category.Widgets)]
class ImageSection : ListSection
{
public ImageSection()
{
AddItem(CreateContainer());
}
public (string, Widget) CreateContainer()
{
var image = new Pixbuf(typeof(ImageSection).Assembly, "Testpic");
var container = new ImageBox(image);
return ($"{nameof(ImageBox)}:", container);
}
}
}

View File

@@ -0,0 +1,47 @@
// This is free and unencumbered software released into the public domain.
// Happy coding!!! - GtkSharp Team
using Gtk;
namespace Samples
{
[Section(ContentType = typeof(Label), Category = Category.Widgets)]
class LabelSection : ListSection
{
public LabelSection()
{
AddItem(CreateSimpleLabel());
AddItem(CreateMarkupLabel());
}
public (string, Widget) CreateSimpleLabel()
{
var label = new Label();
// can be defined at constructor
label.LabelProp = "This is a label";
// right align text, center is default
label.Xalign = 1f;
return ("Label :", label);
}
public (string, Widget) CreateMarkupLabel()
{
var label = new Label();
// activate markup, default is false
label.UseMarkup = true;
// define label with pango markup
label.LabelProp = "This is a <span foreground=\"red\" size=\"large\">label</span> with <b>custom</b> markup";
// right align text, center is default
label.Xalign = 1f;
return ("Label Markup:", label);
}
}
}

View File

@@ -0,0 +1,31 @@
// This is free and unencumbered software released into the public domain.
// Happy coding!!! - GtkSharp Team
using Gtk;
namespace Samples
{
[Section(ContentType = typeof(LevelBar), Category = Category.Widgets)]
class LevelBarSection : ListSection
{
public LevelBarSection()
{
AddItem(CreateSimpleLevelBar());
}
public (string, Widget) CreateSimpleLevelBar()
{
// constructor takes MinValue, MaxValue
var lb = new LevelBar(0, 100);
// lets add a visible request size in our example
lb.WidthRequest = 100;
// set the value to 75%
lb.Value = 75d;
return ("Level Bar:", lb);
}
}
}

View File

@@ -0,0 +1,25 @@

// This is free and unencumbered software released into the public domain.
// Happy coding!!! - GtkSharp Team
using Gtk;
namespace Samples
{
[Section(ContentType = typeof(LinkButton), Category = Category.Widgets)]
class LinkButtonSection : ListSection
{
public LinkButtonSection()
{
AddItem(CreateLinkButton());
}
public (string, Widget) CreateLinkButton()
{
var btn = new LinkButton("A simple link button");
btn.Clicked += (sender, e) => ApplicationOutput.WriteLine(sender, "Link button Clicked");
return ("Link button:", btn);
}
}
}

View File

@@ -0,0 +1,194 @@
using System.Collections.Generic;
using Gtk;
namespace Samples
{
[Section(ContentType = typeof(ListStore), Category = Category.Widgets)]
class ListStoreSection : Box
{
private readonly TreeView _tree;
private ListStore _model;
private readonly List<Bug> _data = new List<Bug>
{
new Bug ( false, 60482, "Normal", "scrollable notebooks and hidden tabs" ),
new Bug ( false, 60620, "Critical", "gdk_window_clear_area (gdkwindow-win32.c) is not thread-safe" ),
new Bug ( false, 50214, "Major", "Xft support does not clean up correctly" ),
new Bug ( true, 52877, "Major", "GtkFileSelection needs a refresh method. " ),
new Bug ( false, 56070, "Normal", "Can't click button after setting in sensitive" ),
new Bug ( true, 56355, "Normal", "GtkLabel - Not all changes propagate correctly" ),
new Bug ( false, 50055, "Normal", "Rework width/height computations for TreeView" ),
new Bug ( false, 58278, "Normal", "gtk_dialog_set_response_sensitive () doesn't work" ),
new Bug ( false, 55767, "Normal", "Getters for all setters" ),
new Bug ( false, 56925, "Normal", "Gtkcalender size" ),
new Bug ( false, 56221, "Normal", "Selectable label needs right-click copy menu" ),
new Bug ( true, 50939, "Normal", "Add shift clicking to GtkTextView" ),
new Bug ( false, 6112, "Enhancement", "netscape-like collapsable toolbars" ),
new Bug ( false, 1, "Normal", "First bug :=)" ),
};
public ListStoreSection() : base(Orientation.Vertical, 3)
{
CreateModel();
_tree = new TreeView(_model);
AddColumn();
var treeScroll = new ScrolledWindow
{
Expand = true
};
treeScroll.Add(_tree);
PackStart(treeScroll, true, true, 0);
GLib.Timeout.Add(100, SpinerTimeout);
}
private enum Column
{
Fixed,
Number,
Severity,
Description,
Pulse,
Icon,
Active,
Sensitive,
Num
};
private readonly struct Bug
{
public bool Fixed { get; }
public int Number { get; }
public string Severity { get; }
public string Description { get; }
public Bug(bool isFixed, int number, string severity, string description)
{
Fixed = isFixed;
Number = number;
Severity = severity;
Description = description;
}
}
private void CreateModel()
{
/* create list store */
_model = new ListStore(typeof(bool), typeof(int), typeof(string), typeof(string), typeof(int), typeof(string), typeof(bool), typeof(bool));
/* add data to the list store */
for (int i = 0; i < _data.Count; i++)
{
string iconName;
bool sensitive;
if (i == 1 || i == 3)
iconName = "battery-caution-charging-symbolic";
else
iconName = null;
if (i == 3)
sensitive = false;
else
sensitive = true;
TreeIter iter = _model.Append();
_model.SetValue(iter, (int)Column.Fixed, _data[i].Fixed);
_model.SetValue(iter, (int)Column.Number, _data[i].Number);
_model.SetValue(iter, (int)Column.Severity, _data[i].Severity);
_model.SetValue(iter, (int)Column.Description, _data[i].Description);
_model.SetValue(iter, (int)Column.Pulse, 5);
_model.SetValue(iter, (int)Column.Icon, iconName);
_model.SetValue(iter, (int)Column.Active, false);
_model.SetValue(iter, (int)Column.Sensitive, sensitive);
}
}
private void AddColumn()
{
CellRenderer renderer;
TreeViewColumn column;
/* column for fixed toggles */
var rendererToggle = new CellRendererToggle();
rendererToggle.Toggled += RendererToggle_Toggled;
column = new TreeViewColumn("Fixed?", rendererToggle, "active", Column.Fixed, null)
{
/* set this column to a fixed sizing (of 50 pixels) */
FixedWidth = 50
};
_tree.AppendColumn(column);
/* column for bug numbers */
renderer = new CellRendererText();
column = new TreeViewColumn("Bug number", renderer, "text", Column.Number, null);
column.SortColumnId = (int)Column.Number;
_tree.AppendColumn(column);
/* column for severities */
renderer = new CellRendererText();
column = new TreeViewColumn("Severity", renderer, "text", Column.Severity, null)
{
SortColumnId = (int)Column.Severity
};
_tree.AppendColumn(column);
/* column for description */
renderer = new CellRendererText();
column = new TreeViewColumn("Description", renderer, "text", Column.Description, null)
{
SortColumnId = (int)Column.Description
};
_tree.AppendColumn(column);
/* column for spinner */
renderer = new CellRendererSpinner();
column = new TreeViewColumn("Spinning", renderer, "pulse", Column.Pulse, "active", Column.Active, null)
{
SortColumnId = (int)Column.Pulse
};
_tree.AppendColumn(column);
/* column for symbolic icon */
renderer = new CellRendererPixbuf();
column = new TreeViewColumn("Symbolic icon", renderer, "icon-name", Column.Icon, "sensitive", Column.Sensitive, null);
column.SortColumnId = (int)Column.Icon;
_tree.AppendColumn(column);
}
private void RendererToggle_Toggled(object o, ToggledArgs args)
{
TreePath path = new TreePath(args.Path);
/* get toggled iter */
TreeIter iter;
_model.GetIter(out iter, path);
bool isFixed = (bool)_model.GetValue(iter, (int)Column.Fixed);
/* do something with the value */
isFixed ^= true;
/* set new value */
_model.SetValue(iter, (int)Column.Fixed, isFixed);
}
private bool SpinerTimeout()
{
if (_model == null)
{
return false;
}
_model.GetIterFirst(out TreeIter iter);
int pulse = (int)_model.GetValue(iter, (int)Column.Pulse);
if (pulse == int.MaxValue)
pulse = 0;
else
pulse++;
_model.SetValue(iter, (int)Column.Pulse, pulse);
_model.SetValue(iter, (int)Column.Active, true);
return true;
}
}
}

View File

@@ -0,0 +1,95 @@
// This is free and unencumbered software released into the public domain.
// Happy coding!!! - GtkSharp Team
using Gtk;
using System;
using System.Timers;
namespace Samples
{
[Section(ContentType = typeof(ProgressBar), Category = Category.Widgets)]
class ProgressBarSection : ListSection
{
public ProgressBarSection()
{
AddItem(CreateSimpleProgressBar());
AddItem(CreateFractionProgressBar());
AddItem(CreatePulseProgressBar());
}
public (string, Widget) CreateSimpleProgressBar()
{
var pb = new ProgressBar();
// lets add a visible request size in our example
pb.WidthRequest = 100;
// add a text
pb.Text = "Some progress...";
// to show text it must be set to true
pb.ShowText = true;
// progressbar is used in percentage mode values between 0.0 and 1.0
pb.Fraction = 0.60d;
return ("Progress Bar:", pb);
}
public (string, Widget) CreateFractionProgressBar()
{
// this is used when application can report progress
var pb = new ProgressBar();
pb.WidthRequest = 200;
pb.Text = "0%";
pb.ShowText = true;
pb.Fraction = 0d;
// lets add a timer to demo it
var timer = new Timer();
timer.Interval = 1000;
timer.Elapsed += (sender, e) =>
{
pb.Fraction += 0.1d;
if (pb.Fraction >= 1d)
pb.Fraction = 0d;
pb.Text = $"{Math.Truncate(pb.Fraction * 100)}%";
};
timer.Start();
return ("Progress Bar with fraction:", pb);
}
public (string, Widget) CreatePulseProgressBar()
{
// this is used when application can't report progress
var pb = new ProgressBar();
pb.WidthRequest = 200;
pb.Text = "Task time is unknown";
pb.ShowText = true;
// define how much is the pulse step
pb.PulseStep = 0.1d;
// lets add a timer to demo it
var timer = new Timer();
timer.Interval = 200;
timer.Elapsed += (sender, e) => pb.Pulse();
timer.Start();
return ("Progress Bar with pulse:", pb);
}
}
}

View File

@@ -0,0 +1,35 @@
// This is free and unencumbered software released into the public domain.
// Happy coding!!! - GtkSharp Team
using Gtk;
namespace Samples
{
[Section(ContentType = typeof(Range), Category = Category.Widgets)]
class RangeSection : ListSection
{
public RangeSection()
{
AddItem(CreateHorizontalRange());
AddItem(CreateVerticalRange());
}
public (string, Widget) CreateHorizontalRange()
{
var adj = new Adjustment(0.0, 0.0, 101.0, 0.1, 1.0, 1.0);
var hScale = new HScale(adj);
hScale.SetSizeRequest(200, -1);
hScale.ValueChanged += (sender, e) => ApplicationOutput.WriteLine(sender, $"Value Change: {((HScale)sender).Value}");
return ("Horizontal", hScale);
}
public (string, Widget) CreateVerticalRange()
{
var adj = new Adjustment(0.0, 0.0, 101.0, 0.1, 1.0, 1.0);
var vScale = new VScale(adj);
vScale.SetSizeRequest(-1, 200);
vScale.ValueChanged += (sender, e) => ApplicationOutput.WriteLine(sender, $"Value Change: {((VScale)sender).Value}");
return ("Vertical", vScale);
}
}
}

View File

@@ -0,0 +1,32 @@
// This is free and unencumbered software released into the public domain.
// Happy coding!!! - GtkSharp Team
using Gtk;
namespace Samples
{
[Section(ContentType = typeof(SpinButton), Category = Category.Widgets)]
class SpinButtonSection : ListSection
{
public SpinButtonSection()
{
AddItem(CreateSpinButton());
}
public (string, Widget) CreateSpinButton()
{
// Spinbutton constructor takes MinValue, MaxValue and StepValue
var btn = new SpinButton(0, 1000, 1);
// Button constructor also takes the adjustment object
// and it can be redefined any time like CurrentVal, MinVal, MaxVal, Step, PageStep, PageSize
btn.Adjustment.Configure(888, 0, 1000, 1, 100, 0);
// Default values are double, use ValueAsInt method to get Int
btn.ValueChanged += (sender, e) =>
ApplicationOutput.WriteLine(sender, $"Spin button changed: {btn.ValueAsInt}");
return ("Spin button:", btn);
}
}
}

View File

@@ -0,0 +1,28 @@
// This is free and unencumbered software released into the public domain.
// Happy coding!!! - GtkSharp Team
using Gtk;
namespace Samples
{
[Section(ContentType = typeof(Spinner), Category = Category.Widgets)]
class SpinnerSection : ListSection
{
public SpinnerSection()
{
AddItem(CreateSimpleSpinner());
}
public (string, Widget) CreateSimpleSpinner()
{
var sp = new Spinner();
sp.Start();
// can be stopped with
// Stop()
return ("Simple Spinner:", sp);
}
}
}

View File

@@ -0,0 +1,26 @@
// This is free and unencumbered software released into the public domain.
// Happy coding!!! - GtkSharp Team
using Gtk;
namespace Samples
{
[Section(ContentType = typeof(Switch), Category = Category.Widgets)]
class SwitchSection : ListSection
{
public SwitchSection()
{
AddItem(CreateSwitchButton());
}
public (string, Widget) CreateSwitchButton()
{
var btn = new Switch();
btn.ButtonReleaseEvent += (o, args) =>
ApplicationOutput.WriteLine(o, $"Switch is now: {!btn.Active}");
return ("Switch:", btn);
}
}
}

View File

@@ -0,0 +1,32 @@
// This is free and unencumbered software released into the public domain.
// Happy coding!!! - GtkSharp Team
using Gtk;
namespace Samples
{
[Section(ContentType = typeof(ToggleButton), Category = Category.Widgets)]
class ToggleButtonSection : ListSection
{
public ToggleButtonSection()
{
AddItem(CreateToggleButton());
}
public (string, Widget) CreateToggleButton()
{
var btn = new ToggleButton("Toggle Me");
btn.Toggled += (sender, e) =>
{
if (btn.Active)
btn.Label = "Untoggle Me";
else
btn.Label = "Toglle Me";
ApplicationOutput.WriteLine(sender, "Buton Toggled");
};
return ("Toggle button:", btn);
}
}
}

View File

@@ -0,0 +1,177 @@
// This is free and unencumbered software released into the public domain.
// Happy coding!!! - GtkSharp Team
using System;
using Gtk;
namespace Samples
{
[Section(ContentType = typeof(TreeView), Category = Category.Widgets)]
class TreeViewSection : Box
{
const int ColumnIndex = 0;
const int ColumnName = 1;
const int ColumnIcon = 2;
TreeView tree;
TreeStore store;
Entry entry;
Gdk.Pixbuf icon = new Gdk.Pixbuf(typeof(ImageSection).Assembly, "Testpic", 32, 32);
public TreeViewSection() : base(Orientation.Vertical, 3)
{
CreateTreeView();
var treeScroll = new ScrolledWindow();
treeScroll.Expand = true;
treeScroll.Add(tree);
var boxEdit = new Box(Orientation.Horizontal, 3);
var btn1 = new Button() { Label = "Add" };
btn1.Clicked += OnAddClicked;
var btn2 = new Button() { Label = "Edit" };
btn2.Clicked += OnEditClicked;
var btn3 = new Button() { Label = "Remove" };
btn3.Clicked += OnRemoveClicked;
entry = new Entry();
boxEdit.PackStart(entry, true, true, 0);
boxEdit.PackStart(btn1, false, true, 0);
boxEdit.PackStart(btn2, false, true, 0);
boxEdit.PackStart(btn3, false, true, 0);
PackStart(boxEdit, false, true, 0);
PackStart(treeScroll, true, true, 0);
}
void CreateTreeView()
{
store = new TreeStore(typeof(int), typeof(string), typeof(Gdk.Pixbuf));
store.RowInserted += OnStoreRowInserted;
store.RowDeleted += OnStoreRowDeleted;
store.RowChanged += OnStoreRowChanged;
store.RowsReordered += OnStoreRowsReordered;
store.RowHasChildToggled += OnStoreRowHasChildToggled;
tree = new TreeView();
var col = tree.AppendColumn("Index", new CellRendererText(), "text", ColumnIndex);
col.Resizable = true;
col.SortColumnId = 0;
col = tree.AppendColumn("Name", new CellRendererText(), "text", ColumnName);
col.Resizable = true;
col.Expand = true;
col.SortColumnId = 1;
col = tree.AppendColumn("Icon", new CellRendererPixbuf(), "pixbuf", ColumnIcon);
col.Resizable = true;
col.Expand = true;
col.Alignment = .5f;
FillTreeView();
tree.Model = store;
tree.Selection.Changed += OnTreeSelectionChanged;
}
void FillTreeView()
{
int idx = 0;
TreeIter it = store.InsertWithValues(-1, idx++, "Adam", null);
store.InsertWithValues(it, -1, idx++, "Adam child 1", null);
store.InsertWithValues(it, -1, idx++, "Adam child 2", icon);
store.InsertWithValues(it, -1, idx++, "Adam child 3", null);
store.InsertWithValues(-1, idx++, "Eve", null);
store.InsertWithValues(-1, idx++, "Zack", null);
store.InsertWithValues(-1, idx++, "John", icon);
it = store.InsertWithValues(-1, idx++, "Amy", null);
store.InsertWithValues(it, -1, idx++, "Amy child 1", null);
store.InsertWithValues(it, -1, idx++, "Amy child 2", null);
store.InsertWithValues(-1, idx++, "William", null);
store.InsertWithValues(-1, idx++, "Evelyn", icon);
store.InsertWithValues(-1, idx++, "Wyatt", null);
}
private void OnTreeSelectionChanged(object sender, EventArgs e)
{
if (!tree.Selection.GetSelected(out TreeIter it))
return;
TreePath path = store.GetPath(it);
var name = (string)store.GetValue(it, ColumnName);
entry.Text = name;
ApplicationOutput.WriteLine(sender, $"SelectionChanged, path {path}, name {name}");
}
private void OnStoreRowInserted(object sender, RowInsertedArgs args)
{
var name = (string)store.GetValue(args.Iter, ColumnName);
ApplicationOutput.WriteLine(sender, $"RowInserted, path {args.Path}, name {name}");
}
private void OnStoreRowDeleted(object sender, RowDeletedArgs args)
{
ApplicationOutput.WriteLine(sender, $"RowDeleted, path {args.Path}");
}
private void OnStoreRowChanged(object sender, RowChangedArgs args)
{
var name = (string)store.GetValue(args.Iter, ColumnName);
ApplicationOutput.WriteLine(sender, $"RowChanged, path {args.Path}, name {name}");
}
private void OnStoreRowsReordered(object sender, RowsReorderedArgs args)
{
ApplicationOutput.WriteLine(sender, $"RowsReordered, path {args.Path}");
}
private void OnStoreRowHasChildToggled(object sender, RowHasChildToggledArgs args)
{
var name = (string)store.GetValue(args.Iter, ColumnName);
ApplicationOutput.WriteLine(sender, $"RowHasChildToggled, path {args.Path}, name {name}");
}
private void OnAddClicked(object sender, EventArgs e)
{
if (!tree.Selection.GetSelected(out TreeIter it))
return;
string txt = entry.Text.Trim();
if (string.IsNullOrEmpty(txt))
return;
int idx = Environment.TickCount % 100;
store.InsertWithValues(it, -1, idx, txt, null);
}
private void OnEditClicked(object sender, EventArgs e)
{
if (!tree.Selection.GetSelected(out TreeIter it))
return;
string txt = entry.Text.Trim();
if (string.IsNullOrEmpty(txt))
return;
store.SetValue(it, ColumnName, txt);
}
private void OnRemoveClicked(object sender, EventArgs e)
{
if (!tree.Selection.GetSelected(out TreeIter it))
return;
store.Remove(ref it);
}
}
}

View File

@@ -0,0 +1,145 @@
// This is free and unencumbered software released into the public domain.
// Happy coding!!! - GtkSharp Team
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using Atk;
using Gdk;
using Gtk;
using WebKit;
using IAsyncResult = GLib.IAsyncResult;
using Object = GLib.Object;
namespace Samples
{
[Section(ContentType = typeof(WebView), Category = Category.Widgets)]
class WebviewSection : ListSection
{
public WebviewSection()
{
if (!WebKit.Global.IsSupported) {
AddItem(($"{nameof(WebKit.WebView)}", new Label($"{typeof(WebView).Namespace} is not suported on your OS")));
return;
}
AddItem(ShowHtml());
AddItem(ShowJavaScript());
AddItem(ShowUri());
}
public (string, Widget) ShowHtml()
{
var webView = new WebView {
HeightRequest = 100,
WidthRequest = 400,
Hexpand = true
};
webView.LoadHtml($"This is a <b>{nameof(WebView)}</b> showing html text");
return ($"{nameof(WebView)} show html text:", webView);
}
public (string, Widget) ShowJavaScript()
{
var webView = new WebView {
HeightRequest = 100,
WidthRequest = 400,
Hexpand = true
};
webView.Settings.EnableDeveloperExtras = true;
var userContentManager = webView.UserContentManager;
var messageHandlerName = "gtksharp";
var script = new UserScript(
source: $"function testFunc() {{\n" +
$"window.webkit.messageHandlers.{messageHandlerName}.postMessage(\"postMessage\");\n" +
$"return 'Success' }};\n",
UserContentInjectedFrames.AllFrames,
UserScriptInjectionTime.Start, null, null);
userContentManager.AddScript(script);
var buttonClickPostMessage = $"var button = document.getElementById(\"clickMeButton\");\n" +
$"button.addEventListener(\"click\", " +
$"function() {{varmessageToPost = {{'ButtonId':'clickMeButton'}};\n" +
$"window.webkit.messageHandlers.{messageHandlerName}.postMessage(\"clickMeButton clicked\");\n}},false);";
var script2 = new UserScript(
source: buttonClickPostMessage,
UserContentInjectedFrames.AllFrames,
UserScriptInjectionTime.End, null, null);
userContentManager.AddScript(script2);
userContentManager.RegisterScriptMessageHandler(messageHandlerName);
userContentManager.ScriptMessageReceived += (o, args) => {
var value = args.JsResult?.JsValue;
if (value is { IsString: true } v)
ApplicationOutput.WriteLine($"{nameof(userContentManager.ScriptMessageReceived)}:\t{nameof(JavascriptResult.JsValue)}\t{v?.ToString()}");
};
webView.LoadHtml($"This is a <b>{nameof(WebView)}</b> with {nameof(UserScript)}" +
"<br/>Send message <input id=\"clickMeButton\" type=\"button\" value=\"Submit\" class=\"button\" onclick=\"\">");
webView.LoadChanged += (s, e) => {
ApplicationOutput.WriteLine(s, $"{e.LoadEvent}");
if (e.LoadEvent != LoadEvent.Finished)
return;
webView.RunJavascript("testFunc()", null, HandleJavaScriptResult);
};
void HandleJavaScriptResult(object source_object, IAsyncResult res)
{
if (source_object is not WebView view) return;
try {
JavascriptResult js_result = view.RunJavascriptFinish(res);
if (js_result.JsValue is { } jsValue) {
if (jsValue.IsString) {
ApplicationOutput.WriteLine($"{nameof(webView.RunJavascriptFinish)}:\t{nameof(JavascriptResult.JsValue)}\t{jsValue.ToString()}");
}
}
} catch (Exception exception) {
ApplicationOutput.WriteLine($"{nameof(webView.RunJavascriptFinish)} throws:\n{exception.Message}");
}
}
return ($"{nameof(WebView)} with {nameof(UserScript)}:", webView);
}
public (string, Widget) ShowUri()
{
var webView = new WebView {
WidthRequest = 400,
Vexpand = true,
Hexpand = true,
};
webView.LoadUri("https://github.com/GtkSharp/GtkSharp#readme");
return ($"{nameof(WebView)} show uri:", webView);
}
}
}