From 54b993d43c873169feb491833f0a2e6a1386f524 Mon Sep 17 00:00:00 2001 From: Cameron White Date: Thu, 3 Sep 2026 23:16:49 -0400 Subject: [PATCH 1/3] Port the add-in info view to use a .ui file --- Pinta.Gui.Addins/AddinInfoView.cs | 193 +++-------------------- Pinta.Gui.Addins/AddinInfoView.ui | 128 +++++++++++++++ Pinta.Gui.Addins/Pinta.Gui.Addins.csproj | 6 + 3 files changed, 159 insertions(+), 168 deletions(-) create mode 100644 Pinta.Gui.Addins/AddinInfoView.ui diff --git a/Pinta.Gui.Addins/AddinInfoView.cs b/Pinta.Gui.Addins/AddinInfoView.cs index 62c4cf4ab7..ff0bf55d3c 100644 --- a/Pinta.Gui.Addins/AddinInfoView.cs +++ b/Pinta.Gui.Addins/AddinInfoView.cs @@ -5,27 +5,42 @@ namespace Pinta.Gui.Addins; -[GObject.Subclass] +[GObject.Subclass (qualifiedName: nameof (AddinInfoView))] +[Gtk.Template ("AddinInfoView.ui")] internal sealed partial class AddinInfoView { + [Gtk.Connect (nameof (title_label))] private Gtk.Label title_label; + [Gtk.Connect (nameof (version_label))] private Gtk.Label version_label; + [Gtk.Connect (nameof (size_label))] private Gtk.Label size_label; + [Gtk.Connect (nameof (repo_label))] private Gtk.Label repo_label; + [Gtk.Connect (nameof (description_label))] private Gtk.Label description_label; + [Gtk.Connect (nameof (info_button))] private Gtk.Button info_button; + [Gtk.Connect (nameof (install_button))] private Gtk.Button install_button; + [Gtk.Connect (nameof (update_button))] private Gtk.Button update_button; + [Gtk.Connect (nameof (uninstall_button))] private Gtk.Button uninstall_button; + [Gtk.Connect (nameof (enable_switch))] private Gtk.Switch enable_switch; + [Gtk.Connect (nameof (content_box))] private Gtk.Box content_box; + [Gtk.Connect (nameof (empty_page))] private Adw.Bin empty_page; + [Gtk.Connect (nameof (view_stack))] private Adw.ViewStack view_stack; + private AddinListViewItem? current_item; /// @@ -36,184 +51,26 @@ internal sealed partial class AddinInfoView private SystemManager system = null!; // NRT - set by factory method. private IChromeService chrome = null!; - [MemberNotNull (nameof (title_label))] - [MemberNotNull (nameof (version_label))] - [MemberNotNull (nameof (size_label))] - [MemberNotNull (nameof (repo_label))] - [MemberNotNull (nameof (description_label))] - [MemberNotNull (nameof (info_button))] - [MemberNotNull (nameof (install_button))] - [MemberNotNull (nameof (update_button))] - [MemberNotNull (nameof (uninstall_button))] - [MemberNotNull (nameof (enable_switch))] - [MemberNotNull (nameof (content_box))] - [MemberNotNull (nameof (empty_page))] - [MemberNotNull (nameof (view_stack))] partial void Initialize () { - // --- Control creation - - Gtk.Label titleLabel = Gtk.Label.New (null); - titleLabel.Halign = Gtk.Align.Start; - titleLabel.AddCssClass (AdwaitaStyles.Title4); - - Gtk.Label versionLabel = Gtk.Label.New (null); - versionLabel.Halign = Gtk.Align.Start; - versionLabel.AddCssClass (AdwaitaStyles.Heading); - - Gtk.Label sizeLabel = Gtk.Label.New (null); - sizeLabel.Halign = Gtk.Align.Start; - sizeLabel.AddCssClass (AdwaitaStyles.Heading); - - Gtk.Label repoLabel = Gtk.Label.New (null); - repoLabel.Halign = Gtk.Align.Start; - repoLabel.AddCssClass (AdwaitaStyles.Heading); - - Gtk.Label descriptionLabel = CreateDescriptionLabel (); - - Adw.Bin emptyPage = Adw.Bin.New (); - - Gtk.Button infoButton = CreateInfoButton (); - Gtk.Button installButton = CreateInstallButton (); - Gtk.Button updateButton = CreateUpdateButton (); - Gtk.Button uninstallButton = CreateUninstallButton (); - - Gtk.Switch enableSwitch = CreateEnableSwitch (); - - BoxStyle spacedHorizontal = new ( - orientation: Gtk.Orientation.Horizontal, - spacing: 6, - cssClass: AdwaitaStyles.Toolbar); - Gtk.Box hbox = GtkExtensions.Box ( - spacedHorizontal, - [ - enableSwitch, - installButton, - updateButton, - infoButton, - uninstallButton - ] - ); - - BoxStyle spacedVertical = new ( - orientation: Gtk.Orientation.Vertical, - spacing: 10); - Gtk.Box contentBox = GtkExtensions.Box ( - spacedVertical, - [ - titleLabel, - versionLabel, - sizeLabel, - repoLabel, - descriptionLabel, - hbox - ] - ); - contentBox.SetAllMargins (10); - - Adw.ViewStack viewStack = Adw.ViewStack.New (); - viewStack.Add (emptyPage); - viewStack.Add (contentBox); - viewStack.SetVisibleChild (emptyPage); - - // --- Gtk.Widget initialization - - WidthRequest = 300; - - // --- Adwaita.Bin initialization - - Child = viewStack; - - // --- References to keep - - title_label = titleLabel; - version_label = versionLabel; - size_label = sizeLabel; - repo_label = repoLabel; - description_label = descriptionLabel; - - info_button = infoButton; - install_button = installButton; - update_button = updateButton; - uninstall_button = uninstallButton; - - enable_switch = enableSwitch; - - content_box = contentBox; - - empty_page = emptyPage; - - view_stack = viewStack; - } + info_button.OnClicked += (_, _) => HandleInfoButtonClicked (); + install_button.OnClicked += (_, _) => HandleInstallButtonClicked (); + update_button.OnClicked += (_, _) => HandleUpdateButtonClicked (); + uninstall_button.OnClicked += (_, _) => HandleUninstallButtonClicked (); - internal void Configure (SystemManager system, IChromeService chrome) - { - this.system = system; - this.chrome = chrome; - } - - public static new AddinInfoView New () => NewWithProperties ([]); - - private Gtk.Switch CreateEnableSwitch () - { - Gtk.Switch result = Gtk.Switch.New (); - result.Visible = false; - result.OnStateSet += (_, _) => { + enable_switch.OnStateSet += (_, _) => { HandleEnableSwitched (); return false; }; - return result; - } - - private static Gtk.Label CreateDescriptionLabel () - { - Gtk.Label result = Gtk.Label.New (null); - result.Halign = Gtk.Align.Start; - result.Hexpand = true; - result.Valign = Gtk.Align.Start; - result.Vexpand = true; - result.Xalign = 0; - result.Wrap = true; - result.AddCssClass (AdwaitaStyles.Body); - return result; - } - - private Gtk.Button CreateInfoButton () - { - Gtk.Button result = Gtk.Button.NewWithLabel (Translations.GetString ("More Information...")); - result.OnClicked += (_, _) => HandleInfoButtonClicked (); - result.Visible = false; - return result; - } - - private Gtk.Button CreateInstallButton () - { - Gtk.Button result = Gtk.Button.NewWithLabel (Translations.GetString ("Install...")); - result.AddCssClass (AdwaitaStyles.SuggestedAction); - result.OnClicked += (_, _) => HandleInstallButtonClicked (); - result.Visible = false; - return result; } - private Gtk.Button CreateUpdateButton () + internal void Configure (SystemManager system, IChromeService chrome) { - Gtk.Button result = Gtk.Button.NewWithLabel (Translations.GetString ("Update...")); - result.AddCssClass (AdwaitaStyles.SuggestedAction); - result.OnClicked += (_, _) => HandleUpdateButtonClicked (); - result.Visible = false; - return result; + this.system = system; + this.chrome = chrome; } - private Gtk.Button CreateUninstallButton () - { - Gtk.Button result = Gtk.Button.NewWithLabel (Translations.GetString ("Uninstall...")); - result.AddCssClass (AdwaitaStyles.DestructiveAction); - result.OnClicked += (_, _) => HandleUninstallButtonClicked (); - result.Visible = false; - result.Hexpand = true; - result.Halign = Gtk.Align.End; - return result; - } + public static new AddinInfoView New () => NewWithProperties ([]); public void Update (AddinListViewItem? item) { diff --git a/Pinta.Gui.Addins/AddinInfoView.ui b/Pinta.Gui.Addins/AddinInfoView.ui new file mode 100644 index 0000000000..4cd68b7969 --- /dev/null +++ b/Pinta.Gui.Addins/AddinInfoView.ui @@ -0,0 +1,128 @@ + + + + diff --git a/Pinta.Gui.Addins/Pinta.Gui.Addins.csproj b/Pinta.Gui.Addins/Pinta.Gui.Addins.csproj index 354673b4a3..610e1782fe 100644 --- a/Pinta.Gui.Addins/Pinta.Gui.Addins.csproj +++ b/Pinta.Gui.Addins/Pinta.Gui.Addins.csproj @@ -13,4 +13,10 @@ + + + + %(Filename)%(Extension) + + From 721dba8a0b52e90d1d2efa5e26e2bd107e64180f Mon Sep 17 00:00:00 2001 From: Cameron White Date: Thu, 3 Sep 2026 23:28:57 -0400 Subject: [PATCH 2/3] Display the add-in author and category --- Pinta.Gui.Addins/AddinInfoView.cs | 6 ++++++ Pinta.Gui.Addins/AddinInfoView.ui | 20 +++++++++++++++++++- Pinta.Gui.Addins/AddinListViewItem.cs | 2 ++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/Pinta.Gui.Addins/AddinInfoView.cs b/Pinta.Gui.Addins/AddinInfoView.cs index ff0bf55d3c..e21148b896 100644 --- a/Pinta.Gui.Addins/AddinInfoView.cs +++ b/Pinta.Gui.Addins/AddinInfoView.cs @@ -11,6 +11,10 @@ internal sealed partial class AddinInfoView { [Gtk.Connect (nameof (title_label))] private Gtk.Label title_label; + [Gtk.Connect (nameof (category_label))] + private Gtk.Label category_label; + [Gtk.Connect (nameof (author_label))] + private Gtk.Label author_label; [Gtk.Connect (nameof (version_label))] private Gtk.Label version_label; [Gtk.Connect (nameof (size_label))] @@ -93,6 +97,8 @@ private void ViewExistingItem (AddinListViewItem item) title_label.SetLabel (item.Name); version_label.SetLabel (Translations.GetString ("Version: {0}", item.Version)); + category_label.SetLabel (Translations.GetString ("Category: {0}", item.Category)); + author_label.SetLabel (Translations.GetString ("Author: {0}", item.Author)); description_label.SetLabel (item.Description); string? download_size = item.DownloadSize; diff --git a/Pinta.Gui.Addins/AddinInfoView.ui b/Pinta.Gui.Addins/AddinInfoView.ui index 4cd68b7969..7c97059840 100644 --- a/Pinta.Gui.Addins/AddinInfoView.ui +++ b/Pinta.Gui.Addins/AddinInfoView.ui @@ -38,6 +38,24 @@ + + + start + + + + + + + start + + + + start @@ -121,7 +139,7 @@ - + diff --git a/Pinta.Gui.Addins/AddinListViewItem.cs b/Pinta.Gui.Addins/AddinListViewItem.cs index 848dfb1a4a..77dc2bb53f 100644 --- a/Pinta.Gui.Addins/AddinListViewItem.cs +++ b/Pinta.Gui.Addins/AddinListViewItem.cs @@ -58,6 +58,8 @@ public static AddinListViewItem NewForAvailableAddin ( public string Description => info.Description; public string Version => info.Version; public string Url => info.Url; + public string Author => info.Author; + public string Category => info.Category; public bool Installed => installed_addin is not null; public Addin? Addin => installed_addin; From 540731e8982cfa143aaa1d86f78cb53b3f3a30bc Mon Sep 17 00:00:00 2001 From: Cameron White Date: Thu, 3 Sep 2026 23:46:58 -0400 Subject: [PATCH 3/3] Use a boxed list to show the add-in metadata instead of many lines of text --- Pinta.Gui.Addins/AddinInfoView.cs | 40 ++++++------- Pinta.Gui.Addins/AddinInfoView.ui | 96 +++++++++++++++++-------------- 2 files changed, 70 insertions(+), 66 deletions(-) diff --git a/Pinta.Gui.Addins/AddinInfoView.cs b/Pinta.Gui.Addins/AddinInfoView.cs index e21148b896..53233e5dd0 100644 --- a/Pinta.Gui.Addins/AddinInfoView.cs +++ b/Pinta.Gui.Addins/AddinInfoView.cs @@ -11,16 +11,16 @@ internal sealed partial class AddinInfoView { [Gtk.Connect (nameof (title_label))] private Gtk.Label title_label; - [Gtk.Connect (nameof (category_label))] - private Gtk.Label category_label; - [Gtk.Connect (nameof (author_label))] - private Gtk.Label author_label; - [Gtk.Connect (nameof (version_label))] - private Gtk.Label version_label; - [Gtk.Connect (nameof (size_label))] - private Gtk.Label size_label; - [Gtk.Connect (nameof (repo_label))] - private Gtk.Label repo_label; + [Gtk.Connect (nameof (category_row))] + private Adw.ActionRow category_row; + [Gtk.Connect (nameof (version_row))] + private Adw.ActionRow version_row; + [Gtk.Connect (nameof (author_row))] + private Adw.ActionRow author_row; + [Gtk.Connect (nameof (size_row))] + private Adw.ActionRow size_row; + [Gtk.Connect (nameof (repo_row))] + private Adw.ActionRow repo_row; [Gtk.Connect (nameof (description_label))] private Gtk.Label description_label; @@ -96,22 +96,16 @@ private void ViewExistingItem (AddinListViewItem item) view_stack.SetVisibleChild (content_box); title_label.SetLabel (item.Name); - version_label.SetLabel (Translations.GetString ("Version: {0}", item.Version)); - category_label.SetLabel (Translations.GetString ("Category: {0}", item.Category)); - author_label.SetLabel (Translations.GetString ("Author: {0}", item.Author)); + category_row.Subtitle = item.Category; + version_row.Subtitle = item.Version; + author_row.Subtitle = item.Author; description_label.SetLabel (item.Description); - string? download_size = item.DownloadSize; - size_label.Visible = download_size != null; + size_row.Visible = item.DownloadSize != null; + size_row.Subtitle = item.DownloadSize ?? string.Empty; - if (download_size is not null) - size_label.SetLabel (Translations.GetString ("Download size: {0}", download_size)); - - string? repo_name = item.RepositoryName; - repo_label.Visible = repo_name != null; - - if (repo_name is not null) - repo_label.SetLabel (Translations.GetString ("Available in repository: {0}", repo_name)); + repo_row.Visible = item.RepositoryName != null; + repo_row.Subtitle = item.RepositoryName ?? string.Empty; info_button.Visible = !string.IsNullOrEmpty (item.Url); install_button.Visible = !item.Installed; diff --git a/Pinta.Gui.Addins/AddinInfoView.ui b/Pinta.Gui.Addins/AddinInfoView.ui index 7c97059840..65d89d796b 100644 --- a/Pinta.Gui.Addins/AddinInfoView.ui +++ b/Pinta.Gui.Addins/AddinInfoView.ui @@ -24,67 +24,77 @@ start - + start + true + 0 + true - - start + + none + start + true - - - - - start - - - + + + Category + + + - - - start - - - + + + Version + + + - - - start - - - + + + Author + + + + + + + Download size + + + + + + + Repository + + + - - - start - true - start - true - 0 - true -