From ae84b2045da7f979295a83dad333061036cf40df Mon Sep 17 00:00:00 2001 From: Kashif Soofi Date: Sat, 6 Jan 2024 20:51:07 +0000 Subject: [PATCH] Add Async FontDialog methods and sample --- src/GirCore.Libs.slnf | 1 + src/GirCore.sln | 2 + src/Libs/Gtk-4.0/Public/FontDialog.cs | 121 ++++++++++++++++++ .../Gtk-4.0/FontDialog/FontDialog.csproj | 13 ++ src/Samples/Gtk-4.0/FontDialog/Program.cs | 45 +++++++ 5 files changed, 182 insertions(+) create mode 100644 src/Libs/Gtk-4.0/Public/FontDialog.cs create mode 100644 src/Samples/Gtk-4.0/FontDialog/FontDialog.csproj create mode 100644 src/Samples/Gtk-4.0/FontDialog/Program.cs diff --git a/src/GirCore.Libs.slnf b/src/GirCore.Libs.slnf index ac12e6aa5..964109a15 100644 --- a/src/GirCore.Libs.slnf +++ b/src/GirCore.Libs.slnf @@ -39,6 +39,7 @@ "Samples/Gtk-4.0/AboutDialog/AboutDialog.csproj", "Samples/Gtk-4.0/Builder/Builder.csproj", "Samples/Gtk-4.0/DrawingArea/DrawingArea.csproj", + "Samples/Gtk-4.0/FontDialog/FontDialog.csproj", "Samples/Gtk-4.0/Window/Window.csproj", "Samples/WebKit-6.0/JavascriptCall/JavascriptCall.csproj", "Samples/WebKit-6.0/JavascriptCallback/JavascriptCallback.csproj", diff --git a/src/GirCore.sln b/src/GirCore.sln index eafbc8dba..60a3309e0 100644 --- a/src/GirCore.sln +++ b/src/GirCore.sln @@ -139,6 +139,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Gtk-4.0", "Libs/Gtk-4.0/Gtk EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Gtk-4.0", "Gtk-4.0", "{7B70E5ED-C5E7-4F32-A458-E5A10F39DA00}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FontDialog", "Samples/Gtk-4.0/FontDialog/FontDialog.csproj", "{D215B861-1A51-436A-82EB-FCF7AF892748}" +EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Window", "Samples/Gtk-4.0/Window/Window.csproj", "{AD618F85-F8F5-454B-9CA0-ABF936492065}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AboutDialog", "Samples/Gtk-4.0/AboutDialog/AboutDialog.csproj", "{4008E1B8-AC7D-4CC8-AB74-8576493C4FDD}" diff --git a/src/Libs/Gtk-4.0/Public/FontDialog.cs b/src/Libs/Gtk-4.0/Public/FontDialog.cs new file mode 100644 index 000000000..745042f4d --- /dev/null +++ b/src/Libs/Gtk-4.0/Public/FontDialog.cs @@ -0,0 +1,121 @@ +using System; +using System.Threading.Tasks; + +namespace Gtk; + +public partial class FontDialog +{ + //TODO: Async methods should be generated automatically (https://github.com/gircore/gir.core/issues/893) + public Task ChooseFaceAsync(Window parent, Pango.FontFace? fontFace) + { + var tcs = new TaskCompletionSource(); + + var callbackHandler = new Gio.Internal.AsyncReadyCallbackAsyncHandler((sourceObject, res, data) => + { + if (sourceObject is null) + { + tcs.SetException(new Exception("Missing source object")); + return; + } + + var chooseFontFaceResult = Internal.FontDialog.ChooseFaceFinish(sourceObject.Handle, res.Handle, out var error); + + if (!error.IsInvalid) + tcs.SetException(new GLib.GException(error)); + else + { + var result = GObject.Internal.ObjectWrapper.WrapNullableHandle(chooseFontFaceResult, false); + tcs.SetResult(result); + } + }); + + Internal.FontDialog.ChooseFace( + Handle, + parent.Handle, + fontFace?.Handle ?? IntPtr.Zero, + IntPtr.Zero, + callbackHandler.NativeCallback, + IntPtr.Zero + ); + + return tcs.Task; + } + + //TODO: Async methods should be generated automatically (https://github.com/gircore/gir.core/issues/893) + public Task ChooseFamilyAsync(Window parent, Pango.FontFamily? fontFamily) + { + var tcs = new TaskCompletionSource(); + + var callbackHandler = new Gio.Internal.AsyncReadyCallbackAsyncHandler((sourceObject, res, data) => + { + if (sourceObject is null) + { + tcs.SetException(new Exception("Missing source object")); + return; + } + + var chooseFontFamilyResult = Internal.FontDialog.ChooseFamilyFinish(sourceObject.Handle, res.Handle, out var error); + + if (!error.IsInvalid) + tcs.SetException(new GLib.GException(error)); + else + { + var result = GObject.Internal.ObjectWrapper.WrapNullableHandle(chooseFontFamilyResult, false); + tcs.SetResult(result); + } + }); + + Internal.FontDialog.ChooseFamily( + Handle, + parent.Handle, + fontFamily?.Handle ?? IntPtr.Zero, + IntPtr.Zero, + callbackHandler.NativeCallback, + IntPtr.Zero + ); + + return tcs.Task; + } + + //TODO: Async methods should be generated automatically (https://github.com/gircore/gir.core/issues/893) + public Task ChooseFontAsync(Window parent, Pango.FontDescription? fontDescription) + { + var tcs = new TaskCompletionSource(); + + var callbackHandler = new Gio.Internal.AsyncReadyCallbackAsyncHandler((sourceObject, res, data) => + { + if (sourceObject is null) + { + tcs.SetException(new Exception("Missing source object")); + return; + } + + var fontDescriptionOwnedHandle = Internal.FontDialog.ChooseFontFinish(sourceObject.Handle, res.Handle, out var error); + + if (!error.IsInvalid) + tcs.SetException(new GLib.GException(error)); + else + { + if (fontDescriptionOwnedHandle.IsInvalid) + tcs.SetResult(null); + else + { + var result = new Pango.FontDescription(fontDescriptionOwnedHandle); + tcs.SetResult(result); + } + } + }); + + var initialValue = (Pango.Internal.FontDescriptionHandle?) fontDescription?.Handle ?? Pango.Internal.FontDescriptionUnownedHandle.NullHandle; + Internal.FontDialog.ChooseFont( + Handle, + parent.Handle, + initialValue, + IntPtr.Zero, + callbackHandler.NativeCallback, + IntPtr.Zero + ); + + return tcs.Task; + } +} diff --git a/src/Samples/Gtk-4.0/FontDialog/FontDialog.csproj b/src/Samples/Gtk-4.0/FontDialog/FontDialog.csproj new file mode 100644 index 000000000..f767743ba --- /dev/null +++ b/src/Samples/Gtk-4.0/FontDialog/FontDialog.csproj @@ -0,0 +1,13 @@ + + + + + + + + Exe + net6.0 + enable + + + diff --git a/src/Samples/Gtk-4.0/FontDialog/Program.cs b/src/Samples/Gtk-4.0/FontDialog/Program.cs new file mode 100644 index 000000000..18857b1c1 --- /dev/null +++ b/src/Samples/Gtk-4.0/FontDialog/Program.cs @@ -0,0 +1,45 @@ +using System; + +var application = Gtk.Application.New("org.gir.core", Gio.ApplicationFlags.FlagsNone); +application.OnActivate += (sender, args) => +{ + var labelSelectedFont = Gtk.Label.New(""); + labelSelectedFont.SetMarginTop(12); + labelSelectedFont.SetMarginBottom(12); + labelSelectedFont.SetMarginStart(12); + labelSelectedFont.SetMarginEnd(12); + + var buttonSelectFont = Gtk.Button.New(); + buttonSelectFont.Label = "Select Font"; + buttonSelectFont.SetMarginTop(12); + buttonSelectFont.SetMarginBottom(12); + buttonSelectFont.SetMarginStart(12); + buttonSelectFont.SetMarginEnd(12); + + var gtkBox = Gtk.Box.New(Gtk.Orientation.Vertical, 0); + gtkBox.Append(labelSelectedFont); + gtkBox.Append(buttonSelectFont); + + var window = Gtk.ApplicationWindow.New((Gtk.Application) sender); + window.Title = "Gtk4 Window"; + window.SetDefaultSize(300, 300); + window.Child = gtkBox; + + buttonSelectFont.OnClicked += async (_, _) => + { + try + { + var fontDialog = Gtk.FontDialog.New(); + var selectedFont = await fontDialog.ChooseFontAsync(window, null); + labelSelectedFont.SetLabel(selectedFont.ToString()); + } + catch (Exception ex) + { + //Prints "Dismissed by user" if dialog is cancelled + Console.WriteLine(ex.Message); + } + }; + + window.Show(); +}; +return application.RunWithSynchronizationContext(null);