no more submodule
This commit is contained in:
71
GtkSharp/Source/Samples/Sections/Widgets/ButtonSection.cs
Normal file
71
GtkSharp/Source/Samples/Sections/Widgets/ButtonSection.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
97
GtkSharp/Source/Samples/Sections/Widgets/ComboBoxSection.cs
Normal file
97
GtkSharp/Source/Samples/Sections/Widgets/ComboBoxSection.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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 ();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
138
GtkSharp/Source/Samples/Sections/Widgets/DrawingAreaSection.cs
Normal file
138
GtkSharp/Source/Samples/Sections/Widgets/DrawingAreaSection.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
291
GtkSharp/Source/Samples/Sections/Widgets/EditableCellsSection.cs
Normal file
291
GtkSharp/Source/Samples/Sections/Widgets/EditableCellsSection.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
163
GtkSharp/Source/Samples/Sections/Widgets/EntrySection.cs
Normal file
163
GtkSharp/Source/Samples/Sections/Widgets/EntrySection.cs
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
30
GtkSharp/Source/Samples/Sections/Widgets/ImageSection.cs
Normal file
30
GtkSharp/Source/Samples/Sections/Widgets/ImageSection.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
47
GtkSharp/Source/Samples/Sections/Widgets/LabelSection.cs
Normal file
47
GtkSharp/Source/Samples/Sections/Widgets/LabelSection.cs
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
31
GtkSharp/Source/Samples/Sections/Widgets/LevelBarSection.cs
Normal file
31
GtkSharp/Source/Samples/Sections/Widgets/LevelBarSection.cs
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
194
GtkSharp/Source/Samples/Sections/Widgets/ListStoreSection.cs
Normal file
194
GtkSharp/Source/Samples/Sections/Widgets/ListStoreSection.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
35
GtkSharp/Source/Samples/Sections/Widgets/RangeSection.cs
Normal file
35
GtkSharp/Source/Samples/Sections/Widgets/RangeSection.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
28
GtkSharp/Source/Samples/Sections/Widgets/SpinnerSection.cs
Normal file
28
GtkSharp/Source/Samples/Sections/Widgets/SpinnerSection.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
26
GtkSharp/Source/Samples/Sections/Widgets/SwitchSection.cs
Normal file
26
GtkSharp/Source/Samples/Sections/Widgets/SwitchSection.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
177
GtkSharp/Source/Samples/Sections/Widgets/TreeViewSection.cs
Normal file
177
GtkSharp/Source/Samples/Sections/Widgets/TreeViewSection.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
145
GtkSharp/Source/Samples/Sections/Widgets/WebviewSection.cs
Normal file
145
GtkSharp/Source/Samples/Sections/Widgets/WebviewSection.cs
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user