no more submodule
This commit is contained in:
12
GtkSharp/Source/Samples/Sections/Category.cs
Normal file
12
GtkSharp/Source/Samples/Sections/Category.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
// This is free and unencumbered software released into the public domain.
|
||||
// Happy coding!!! - GtkSharp Team
|
||||
|
||||
namespace Samples
|
||||
{
|
||||
enum Category
|
||||
{
|
||||
Widgets,
|
||||
Dialogs,
|
||||
Miscellaneous
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
// This is free and unencumbered software released into the public domain.
|
||||
// Happy coding!!! - GtkSharp Team
|
||||
|
||||
using System;
|
||||
using Gtk;
|
||||
|
||||
namespace Samples
|
||||
{
|
||||
[Section(ContentType = typeof(AboutDialog), Category = Category.Dialogs)]
|
||||
class AboutDialogSection : Box
|
||||
{
|
||||
public AboutDialogSection() : base(Orientation.Vertical, 0)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using Gtk;
|
||||
|
||||
namespace Samples
|
||||
{
|
||||
[Section(ContentType = typeof(FileChooserDialog), Category = Category.Dialogs)]
|
||||
class FileChooserDialogSection : ListSection
|
||||
{
|
||||
public FileChooserDialogSection ()
|
||||
{
|
||||
AddItem ($"Press button to open {nameof(FileChooserDialog)} :", new FileChooserDialogDemo ("Press me"));
|
||||
}
|
||||
}
|
||||
|
||||
class FileChooserDialogDemo : Button
|
||||
{
|
||||
public FileChooserDialogDemo (string text) : base (text) { }
|
||||
|
||||
protected override void OnPressed ()
|
||||
{
|
||||
var fcd = new FileChooserDialog ("Open File", null, FileChooserAction.Open);
|
||||
fcd.AddButton (Stock.Cancel, ResponseType.Cancel);
|
||||
fcd.AddButton (Stock.Open, ResponseType.Ok);
|
||||
fcd.DefaultResponse = ResponseType.Ok;
|
||||
fcd.SelectMultiple = false;
|
||||
|
||||
ResponseType response = (ResponseType) fcd.Run ();
|
||||
if (response == ResponseType.Ok)
|
||||
ApplicationOutput.WriteLine (fcd.Filename);
|
||||
fcd.Destroy ();
|
||||
}
|
||||
}
|
||||
}
|
||||
49
GtkSharp/Source/Samples/Sections/ListSection.cs
Normal file
49
GtkSharp/Source/Samples/Sections/ListSection.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
// This is free and unencumbered software released into the public domain.
|
||||
// Happy coding!!! - GtkSharp Team
|
||||
|
||||
using System;
|
||||
using Gtk;
|
||||
|
||||
namespace Samples
|
||||
{
|
||||
public class ListSection : Box
|
||||
{
|
||||
private Grid _grid;
|
||||
private int _position;
|
||||
|
||||
public ListSection() : base(Orientation.Vertical, 0)
|
||||
{
|
||||
_position = 0;
|
||||
_grid = new Grid
|
||||
{
|
||||
RowSpacing = 6,
|
||||
ColumnSpacing = 6
|
||||
};
|
||||
|
||||
PackStart(_grid, false, true, 0);
|
||||
PackStart(new VBox(), true, true, 0);
|
||||
}
|
||||
|
||||
public void AddItem((string, Widget) turp)
|
||||
{
|
||||
AddItem(turp.Item1, turp.Item2);
|
||||
}
|
||||
|
||||
public void AddItem(string label, Widget widget)
|
||||
{
|
||||
_grid.Attach(new Label
|
||||
{
|
||||
Text = label,
|
||||
Hexpand = true,
|
||||
Halign = Align.Start
|
||||
}, 0, _position, 1, 1);
|
||||
|
||||
var hbox = new HBox();
|
||||
hbox.PackStart(new VBox(), true, true, 0);
|
||||
hbox.PackStart(widget, false, true, 0);
|
||||
|
||||
_grid.Attach(hbox, 1, _position, 1, 1);
|
||||
_position++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
using System;
|
||||
using Gtk;
|
||||
|
||||
namespace Samples
|
||||
{
|
||||
[Section(ContentType = typeof(ContainerChildProperties), Category = Category.Miscellaneous)]
|
||||
class ContainerChildPropertiesSection : Box
|
||||
{
|
||||
public ContainerChildPropertiesSection() : base(Orientation.Vertical, 3)
|
||||
{
|
||||
ContainerChildProperties.CreateBoxProperties(this);
|
||||
ContainerChildProperties.CreateGridProperties(this);
|
||||
ContainerChildProperties.CreateStackProperties(this);
|
||||
}
|
||||
}
|
||||
|
||||
static class ContainerChildProperties
|
||||
{
|
||||
public static void CreateBoxProperties(Box parent)
|
||||
{
|
||||
var title = new Label { Text = "Box child properties" };
|
||||
parent.PackStart(title, false, true, 0);
|
||||
|
||||
var box1 = new Box(Orientation.Horizontal, 3);
|
||||
var btn1 = new Button() { Label = "Expand" };
|
||||
btn1.Clicked += delegate
|
||||
{
|
||||
var child = (Box.BoxChild)box1[btn1];
|
||||
child.Expand = !child.Expand;
|
||||
ApplicationOutput.WriteLine(child, "Expand changed to " + child.Expand);
|
||||
};
|
||||
box1.PackStart(btn1, true, true, 0);
|
||||
parent.PackStart(box1, false, true, 0);
|
||||
|
||||
var box2 = new Box(Orientation.Horizontal, 3);
|
||||
var btn2 = new Button() { Label = "PackType" };
|
||||
btn2.Clicked += delegate
|
||||
{
|
||||
var child = (Box.BoxChild)box2[btn2];
|
||||
child.PackType = child.PackType == PackType.Start ? PackType.End : PackType.Start;
|
||||
ApplicationOutput.WriteLine(child, "PackType changed to " + child.PackType);
|
||||
};
|
||||
box2.PackStart(btn2, false, false, 0);
|
||||
parent.PackStart(box2, false, true, 0);
|
||||
|
||||
var box3 = new Box(Orientation.Horizontal, 3);
|
||||
var btn3 = new Button() { Label = "Position" };
|
||||
btn3.Clicked += delegate
|
||||
{
|
||||
var child = (Box.BoxChild)box3[btn3];
|
||||
child.Position = child.Position == 0 ? 1 : 0;
|
||||
ApplicationOutput.WriteLine(child, "Position changed to " + child.Position);
|
||||
};
|
||||
box3.PackStart(btn3, false, false, 0);
|
||||
box3.PackStart(new Label { Text = "Neighbor" }, false, false, 0);
|
||||
parent.PackStart(box3, false, true, 0);
|
||||
}
|
||||
|
||||
public static void CreateGridProperties(Box parent)
|
||||
{
|
||||
var title = new Label { Text = "Grid child properties" };
|
||||
parent.PackStart(title, false, true, 0);
|
||||
|
||||
var grid = new Grid { ColumnSpacing = 3, RowSpacing = 3 };
|
||||
var btn1 = new Button { Label = "LeftAttach" };
|
||||
var lbl = new Label { Text = "Neighbor" };
|
||||
btn1.Clicked += delegate
|
||||
{
|
||||
var child1 = (Grid.GridChild)grid[btn1];
|
||||
var child2 = (Grid.GridChild)grid[lbl];
|
||||
if (child1.LeftAttach == 0)
|
||||
{
|
||||
child1.LeftAttach = 1;
|
||||
child2.LeftAttach = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
child1.LeftAttach = 0;
|
||||
child2.LeftAttach = 1;
|
||||
}
|
||||
ApplicationOutput.WriteLine(child1, "Child 1 LeftAttach changed to " + child1.LeftAttach);
|
||||
ApplicationOutput.WriteLine(child1, "Child 2 LeftAttach changed to " + child2.LeftAttach);
|
||||
};
|
||||
|
||||
var btn2 = new Button { Label = "Width (column span)", Hexpand = true };
|
||||
btn2.Clicked += delegate
|
||||
{
|
||||
var child = (Grid.GridChild)grid[btn2];
|
||||
child.Width = child.Width == 1 ? 2 : 1;
|
||||
ApplicationOutput.WriteLine(child, "Width changed to " + child.Width);
|
||||
};
|
||||
|
||||
grid.Attach(btn1, 0, 0, 1, 1);
|
||||
grid.Attach(lbl, 1, 0, 1, 1);
|
||||
grid.Attach(btn2, 0, 1, 1, 1);
|
||||
parent.PackStart(grid, false, true, 0);
|
||||
}
|
||||
|
||||
public static void CreateStackProperties(Box parent)
|
||||
{
|
||||
var title = new Label { Text = "Stack child properties" };
|
||||
parent.PackStart(title, false, true, 0);
|
||||
|
||||
var stack = new Stack();
|
||||
|
||||
var box = new Box(Orientation.Horizontal, 3);
|
||||
var btn1 = new Button { Label = "Title" };
|
||||
btn1.Clicked += delegate
|
||||
{
|
||||
var child = (Stack.StackChild)stack[box];
|
||||
child.Title = child.Title == "Page 1" ? "Page 1 abc" : "Page 1";
|
||||
ApplicationOutput.WriteLine(child, "Title changed to " + child.Title);
|
||||
};
|
||||
box.PackStart(btn1, false, false, 0);
|
||||
|
||||
var btn2 = new Button { Label = "Position" };
|
||||
var lbl = new Label { Text = "Page 2 label", Halign = Align.Start };
|
||||
btn2.Clicked += delegate
|
||||
{
|
||||
var child1 = (Stack.StackChild)stack[box];
|
||||
var child2 = (Stack.StackChild)stack[lbl];
|
||||
if (child1.Position == 0)
|
||||
{
|
||||
child1.Position = 1;
|
||||
child2.Position = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
child1.Position = 0;
|
||||
child2.Position = 1;
|
||||
}
|
||||
ApplicationOutput.WriteLine(child1, "Child 1 Position changed to " + child1.Position);
|
||||
ApplicationOutput.WriteLine(child1, "Child 2 Position changed to " + child2.Position);
|
||||
};
|
||||
box.PackStart(btn2, false, false, 0);
|
||||
|
||||
stack.AddTitled(box, "1", "Page 1");
|
||||
stack.AddTitled(lbl, "2", "Page 2");
|
||||
|
||||
var switcher = new StackSwitcher();
|
||||
switcher.Stack = stack;
|
||||
|
||||
parent.PackStart(switcher, false, true, 0);
|
||||
parent.PackStart(stack, false, true, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Gtk;
|
||||
|
||||
namespace Samples
|
||||
{
|
||||
[Section(ContentType = typeof(CssNameDemo), Category = Category.Miscellaneous)]
|
||||
class CssNameSection : Box
|
||||
{
|
||||
public CssNameSection() : base(Orientation.Vertical, 3)
|
||||
{
|
||||
CssNameDemo.Create(this);
|
||||
}
|
||||
}
|
||||
|
||||
class CssNameDemo
|
||||
{
|
||||
// inherited label has same css name as parent
|
||||
internal class MyLabel : Label
|
||||
{
|
||||
}
|
||||
|
||||
// css name can be set by [CssName]
|
||||
[CssName("my-label-attrib")]
|
||||
internal class MyLabelWithAttrib : Label
|
||||
{
|
||||
}
|
||||
|
||||
// css name can be set in class initializer method
|
||||
[GLib.TypeInitializer(typeof(MyLabelWithInit), nameof(MyLabelWithInit.ClassInit))]
|
||||
internal class MyLabelWithInit : Label
|
||||
{
|
||||
static void ClassInit(GLib.GType gtype, Type type)
|
||||
{
|
||||
SetCssName(gtype, "my-label-init");
|
||||
}
|
||||
}
|
||||
|
||||
public static void Create(Box box)
|
||||
{
|
||||
var css = new CssProvider();
|
||||
css.LoadFromData(@"
|
||||
label.x {
|
||||
background: LightCoral;
|
||||
}
|
||||
my-label-attrib {
|
||||
background: LightGreen;
|
||||
}
|
||||
my-label-init {
|
||||
background: LightSkyBlue;
|
||||
}
|
||||
my-label-init.x {
|
||||
background: LightBlue;
|
||||
}
|
||||
");
|
||||
StyleContext.AddProviderForScreen(Gdk.Screen.Default, css, StyleProviderPriority.Application);
|
||||
|
||||
string name;
|
||||
|
||||
name = Widget.GetCssName(Label.GType);
|
||||
var label1 = new Label { Text = "Label, css name: " + name };
|
||||
label1.StyleContext.AddClass("x");
|
||||
|
||||
name = Widget.GetCssName((GLib.GType)typeof(MyLabel));
|
||||
var label2 = new MyLabel { Text = "Inherited Label, css name: " + name };
|
||||
label2.StyleContext.AddClass("x");
|
||||
|
||||
name = Widget.GetCssName((GLib.GType)typeof(MyLabelWithAttrib));
|
||||
var label3 = new MyLabelWithAttrib { Text = "Inherited Label with [CssName], css name: " + name };
|
||||
|
||||
name = Widget.GetCssName((GLib.GType)typeof(MyLabelWithInit));
|
||||
var label4 = new MyLabelWithInit { Text = "Inherited Label with class initializer, css name: " + name };
|
||||
|
||||
name = Widget.GetCssName((GLib.GType)typeof(MyLabelWithInit));
|
||||
var label5 = new MyLabelWithInit { Text = "Inherited Label with class initializer and css class, css name: " + name };
|
||||
label5.StyleContext.AddClass("x");
|
||||
|
||||
box.PackStart(label1, false, false, 0);
|
||||
box.PackStart(label2, false, false, 0);
|
||||
box.PackStart(label3, false, false, 0);
|
||||
box.PackStart(label4, false, false, 0);
|
||||
box.PackStart(label5, false, false, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using Gtk;
|
||||
|
||||
namespace Samples
|
||||
{
|
||||
[Section(ContentType = typeof(MonitorDemo), Category = Category.Miscellaneous)]
|
||||
class MonitorSection : ListSection
|
||||
{
|
||||
public MonitorSection()
|
||||
{
|
||||
AddItem("Press button to get monitors information:", new MonitorDemo("Press me"));
|
||||
}
|
||||
}
|
||||
|
||||
class MonitorDemo : Button
|
||||
{
|
||||
public MonitorDemo(string text) : base(text)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void OnPressed()
|
||||
{
|
||||
base.OnPressed();
|
||||
|
||||
Gdk.Display display = Gdk.Display.Default;
|
||||
int monitorsCount = display.NMonitors;
|
||||
ApplicationOutput.WriteLine($"Monitors count: {monitorsCount}");
|
||||
for (int i = 0; i < monitorsCount; i++)
|
||||
{
|
||||
Gdk.Monitor monitor = display.GetMonitor(i);
|
||||
ApplicationOutput.WriteLine($"Monitor {i}:");
|
||||
ApplicationOutput.WriteLine($"\tIsPrimary: {monitor.IsPrimary}");
|
||||
ApplicationOutput.WriteLine($"\tManufacturer: {monitor.Manufacturer}");
|
||||
ApplicationOutput.WriteLine($"\tModel: {monitor.Model}");
|
||||
ApplicationOutput.WriteLine($"\tRefreshRate: {monitor.RefreshRate}");
|
||||
ApplicationOutput.WriteLine($"\tScaleFactor: {monitor.ScaleFactor}");
|
||||
ApplicationOutput.WriteLine($"\tWidthMm x HeightMm: {monitor.WidthMm} x {monitor.HeightMm}");
|
||||
ApplicationOutput.WriteLine($"\tGeometry: {monitor.Geometry}");
|
||||
ApplicationOutput.WriteLine($"\tWorkarea: {monitor.Workarea}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using Gdk;
|
||||
using Gtk;
|
||||
|
||||
namespace Samples
|
||||
{
|
||||
|
||||
[Section (ContentType = typeof(PixbufDemo), Category = Category.Miscellaneous)]
|
||||
class PixbufSection : ListSection
|
||||
{
|
||||
|
||||
public PixbufSection ()
|
||||
{
|
||||
AddItem ($"Press button to run / stop {nameof(PixbufDemo)} :", new PixbufDemo ("Press me"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class PixbufDemo : Button
|
||||
{
|
||||
|
||||
public PixbufDemo (string text) : base (text) { }
|
||||
|
||||
private bool running = false;
|
||||
|
||||
public void DispatchPendingEvents ()
|
||||
{
|
||||
// The loop is limited to 1000 iterations as a workaround for an issue that some users
|
||||
// have experienced. Sometimes EventsPending starts return 'true' for all iterations,
|
||||
// causing the loop to never end.
|
||||
|
||||
int n = 1000;
|
||||
Gdk.Threads.Enter ();
|
||||
|
||||
while (Gtk.Application.EventsPending () && --n > 0) {
|
||||
Gtk.Application.RunIteration (false);
|
||||
}
|
||||
|
||||
Gdk.Threads.Leave ();
|
||||
}
|
||||
|
||||
protected override void OnPressed ()
|
||||
{
|
||||
base.OnPressed ();
|
||||
var count = 0;
|
||||
|
||||
if (running) {
|
||||
running = false;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var startmem = GC.GetTotalMemory (true);
|
||||
var testfile = "Textpic.png";
|
||||
|
||||
using var teststream = typeof(ImageSection).Assembly.GetManifestResourceStream("Testpic");
|
||||
using (var writeTestFile = new FileStream(testfile, FileMode.Create)) {
|
||||
teststream.CopyTo(writeTestFile);
|
||||
}
|
||||
|
||||
using (var heatup = new Pixbuf (testfile)) {
|
||||
ApplicationOutput.WriteLine ($"{nameof(heatup)}.{nameof(Pixbuf.ByteLength)}\t{heatup.ByteLength:N0}");
|
||||
}
|
||||
|
||||
startmem = GC.GetTotalMemory (true);
|
||||
ApplicationOutput.WriteLine ($"{nameof(GC.GetTotalMemory)} at start: {startmem:N}");
|
||||
running = true;
|
||||
|
||||
var memAllocated = 0UL;
|
||||
|
||||
while (running) {
|
||||
|
||||
using (var source = new Pixbuf (typeof(ImageSection).Assembly, "Testpic")) {
|
||||
memAllocated += source.ByteLength;
|
||||
count++;
|
||||
}
|
||||
|
||||
DispatchPendingEvents ();
|
||||
|
||||
if (!running)
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
var endmem = GC.GetTotalMemory (true);
|
||||
ApplicationOutput.WriteLine ($"Leak:\t{(endmem - startmem):N0}\t{nameof(memAllocated)}");
|
||||
ApplicationOutput.WriteLine ($"{nameof(GC.GetTotalMemory)} at start: {startmem:N0}\tat end: {endmem:N0}\t{nameof(Pixbuf)} created: {count}");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
using System;
|
||||
using Gtk;
|
||||
|
||||
namespace Samples
|
||||
{
|
||||
[Section(ContentType = typeof(PolarFixed), Category = Category.Miscellaneous)]
|
||||
class PolarFixedSection : ListSection
|
||||
{
|
||||
public PolarFixedSection()
|
||||
{
|
||||
AddItem(CreateClock());
|
||||
AddItem(CreateSpiral());
|
||||
}
|
||||
|
||||
public (string, Widget) CreateClock()
|
||||
{
|
||||
double theta;
|
||||
|
||||
// Clock
|
||||
PolarFixed pf = new PolarFixed();
|
||||
|
||||
for (int hour = 1; hour <= 12; hour++)
|
||||
{
|
||||
theta = (Math.PI / 2) - hour * (Math.PI / 6);
|
||||
if (theta < 0)
|
||||
theta += 2 * Math.PI;
|
||||
|
||||
Label l = new Label("<big><b>" + hour.ToString() + "</b></big>");
|
||||
l.UseMarkup = true;
|
||||
pf.Put(l, theta, 50);
|
||||
}
|
||||
|
||||
return ("Clock", pf);
|
||||
}
|
||||
|
||||
public (string, Widget) CreateSpiral()
|
||||
{
|
||||
uint r;
|
||||
double theta;
|
||||
|
||||
var pf = new PolarFixed();
|
||||
|
||||
|
||||
r = 0;
|
||||
theta = 0.0;
|
||||
|
||||
foreach (string id in Gtk.Stock.ListIds())
|
||||
{
|
||||
StockItem item = Gtk.Stock.Lookup(id);
|
||||
if (item.Label == null)
|
||||
continue;
|
||||
var icon = Gtk.Image.NewFromIconName(item.StockId, IconSize.SmallToolbar);
|
||||
|
||||
pf.Put(icon, theta, r);
|
||||
|
||||
// Logarithmic spiral: r = a*e^(b*theta)
|
||||
r += 1;
|
||||
theta = 10 * Math.Log(10 * r);
|
||||
}
|
||||
|
||||
return ("Spiral", pf);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using Gtk;
|
||||
|
||||
namespace Samples
|
||||
{
|
||||
[Section(ContentType=typeof(SeatDemo), Category = Category.Miscellaneous)]
|
||||
class SeatSection : ListSection
|
||||
{
|
||||
public SeatSection()
|
||||
{
|
||||
AddItem("Press button to output mouse location:", new SeatDemo("Press me"));
|
||||
}
|
||||
}
|
||||
|
||||
class SeatDemo : Button
|
||||
{
|
||||
public SeatDemo(string text) : base(text)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void OnPressed()
|
||||
{
|
||||
base.OnPressed();
|
||||
|
||||
var seat = Display.DefaultSeat;
|
||||
ApplicationOutput.WriteLine($"Default seat: {seat}");
|
||||
|
||||
seat.Pointer.GetPosition(null, out int x, out int y);
|
||||
ApplicationOutput.WriteLine($"Position: ({x}, {y})");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using Gtk;
|
||||
|
||||
namespace Samples
|
||||
{
|
||||
[Section(ContentType = typeof(StyleContext), Category = Category.Miscellaneous)]
|
||||
class StyleContextSection : ListSection
|
||||
{
|
||||
public StyleContextSection()
|
||||
{
|
||||
var btn = new Button() { Label = "Press me" };
|
||||
btn.Clicked += OnBtnClicked;
|
||||
AddItem("Press button to output style context properties:", btn);
|
||||
}
|
||||
|
||||
private void OnBtnClicked(object sender, EventArgs e)
|
||||
{
|
||||
var styleCtx = ((Button)sender).StyleContext;
|
||||
|
||||
var props = new[] { "padding-left", "padding-right", "padding-top", "padding-bottom", "min-width", "min-height", "color", "background-color", "font-size", "font-style" };
|
||||
|
||||
foreach (var prop in props)
|
||||
{
|
||||
GLib.Value val = styleCtx.GetProperty(prop, styleCtx.State);
|
||||
string msg = string.Format("Property {0}, type {1}, value {2}", prop, val.Val.GetType().Name, val.Val.ToString());
|
||||
ApplicationOutput.WriteLine(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Gtk;
|
||||
|
||||
namespace Samples
|
||||
{
|
||||
[Section(ContentType = typeof(TimerDemo), Category = Category.Miscellaneous)]
|
||||
class TimerSection : Box
|
||||
{
|
||||
public TimerSection() : base(Orientation.Horizontal, 3)
|
||||
{
|
||||
Valign = Align.Start;
|
||||
TimerDemo.Create(this);
|
||||
}
|
||||
}
|
||||
|
||||
static class TimerDemo
|
||||
{
|
||||
public static void Create(Box box)
|
||||
{
|
||||
List<uint> timers = new List<uint>();
|
||||
bool removeByHandler = false;
|
||||
|
||||
var btnAddTimer = new Button() { Label = "Add timer" };
|
||||
btnAddTimer.Clicked += delegate
|
||||
{
|
||||
uint id = 0;
|
||||
id = GLib.Timeout.Add(500, () =>
|
||||
{
|
||||
ApplicationOutput.WriteLine("Timer tick " + id);
|
||||
|
||||
if (removeByHandler)
|
||||
{
|
||||
removeByHandler = false;
|
||||
timers.Remove(id);
|
||||
ApplicationOutput.WriteLine("Remove timer from handler " + id);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
timers.Add(id);
|
||||
ApplicationOutput.WriteLine("Add timer " + id);
|
||||
};
|
||||
|
||||
var btnRemoveTimer = new Button() { Label = "Remove timer" };
|
||||
btnRemoveTimer.Clicked += delegate
|
||||
{
|
||||
if (timers.Count == 0)
|
||||
return;
|
||||
|
||||
uint id = timers[0];
|
||||
timers.RemoveAt(0);
|
||||
GLib.Timeout.Remove(id);
|
||||
ApplicationOutput.WriteLine("Remove timer " + id);
|
||||
};
|
||||
|
||||
var btnRemoveTimerByHandler = new Button() { Label = "Remove timer by handler" };
|
||||
btnRemoveTimerByHandler.Clicked += delegate
|
||||
{
|
||||
if (timers.Count == 0)
|
||||
return;
|
||||
|
||||
removeByHandler = true;
|
||||
ApplicationOutput.WriteLine("Remove timer by handler");
|
||||
};
|
||||
|
||||
var btnGc = new Button() { Label = "GC" };
|
||||
btnGc.Clicked += delegate
|
||||
{
|
||||
ApplicationOutput.WriteLine("GC");
|
||||
GC.Collect();
|
||||
GC.WaitForPendingFinalizers();
|
||||
GC.Collect();
|
||||
};
|
||||
|
||||
box.PackStart(btnAddTimer, false, false, 0);
|
||||
box.PackStart(btnRemoveTimer, false, false, 0);
|
||||
box.PackStart(btnRemoveTimerByHandler, false, false, 0);
|
||||
box.PackStart(btnGc, false, false, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
14
GtkSharp/Source/Samples/Sections/SectionAttribute.cs
Normal file
14
GtkSharp/Source/Samples/Sections/SectionAttribute.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
// This is free and unencumbered software released into the public domain.
|
||||
// Happy coding!!! - GtkSharp Team
|
||||
|
||||
using System;
|
||||
|
||||
namespace Samples
|
||||
{
|
||||
class SectionAttribute : Attribute
|
||||
{
|
||||
public Type ContentType { get; set; }
|
||||
|
||||
public Category Category { get; set; }
|
||||
}
|
||||
}
|
||||
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