From 19b15a84670040dac720f86882a582b9c0d9182e Mon Sep 17 00:00:00 2001 From: Cameron White Date: Mon, 23 Mar 2026 23:29:30 -0400 Subject: [PATCH 01/13] Initial work on upgrading to gir.core-0.8.0-preview.1 - Fix errors from changes to the GObject.Subclass source generator. There are still many warnings to fix, but this is the minimal work to get Pinta running and be able to test further changes. Bug: #2050 --- Directory.Packages.props | 2 +- Pinta.Gui.Addins/AddinListView.cs | 4 +- Pinta.Gui.Addins/AddinListViewItem.cs | 46 ++++++++++--------- Pinta.Gui.Addins/Pinta.Gui.Addins.csproj | 5 ++ .../Widgets/History/HistoryItemWidget.cs | 10 ++-- .../Widgets/History/HistoryListView.cs | 4 +- .../Widgets/Layers/LayersListView.cs | 4 +- .../Layers/LayersListViewItemWidget.cs | 20 ++++---- 8 files changed, 51 insertions(+), 44 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 4ea8287cc2..728889d7a5 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -1,7 +1,7 @@ true - 0.7.0 + 0.8.0-preview.1 diff --git a/Pinta.Gui.Addins/AddinListView.cs b/Pinta.Gui.Addins/AddinListView.cs index c45ecf5360..c99b6de964 100644 --- a/Pinta.Gui.Addins/AddinListView.cs +++ b/Pinta.Gui.Addins/AddinListView.cs @@ -100,7 +100,7 @@ public void AddAddin ( { list_view_stack.VisibleChild = list_view_scroll; - model.Append (new AddinListViewItem (service, info, addin, status)); + model.Append (AddinListViewItem.NewForInstalledAddin (service, info, addin, status)); // Adding items may not cause a selection-changed signal, as mentioned in the SelectionModel docs if (model.NItems == 1) @@ -115,7 +115,7 @@ public void AddAddinRepositoryEntry ( { list_view_stack.VisibleChild = list_view_scroll; - model.Append (new AddinListViewItem (service, info, addin, status)); + model.Append (AddinListViewItem.NewForAvailableAddin (service, info, addin, status)); // Adding items may not cause a selection-changed signal, as mentioned in the SelectionModel docs if (model.NItems == 1) diff --git a/Pinta.Gui.Addins/AddinListViewItem.cs b/Pinta.Gui.Addins/AddinListViewItem.cs index 59c4ffb4fe..511a501942 100644 --- a/Pinta.Gui.Addins/AddinListViewItem.cs +++ b/Pinta.Gui.Addins/AddinListViewItem.cs @@ -6,47 +6,49 @@ namespace Pinta.Gui.Addins; // GObject subclass for use with Gio.ListStore -[Subclass] +[GObject.Subclass] internal sealed partial class AddinListViewItem { - private readonly SetupService service = new (); - private readonly AddinHeader info = new AddinInfo (); - private readonly AddinStatus status; - private readonly Addin? installed_addin; - private readonly AddinRepositoryEntry? available_addin; + private SetupService service = new (); + private AddinHeader info = new AddinInfo (); + private AddinStatus status; + private Addin? installed_addin; + private AddinRepositoryEntry? available_addin; /// /// Constructor for the list of installed addins. /// - public AddinListViewItem ( + public static AddinListViewItem NewForInstalledAddin ( SetupService service, AddinHeader info, - Addin installed_addin, + Addin installedAddin, AddinStatus status) - : this () { - this.service = service; - this.info = info; - this.installed_addin = installed_addin; - this.status = status; + AddinListViewItem item = NewWithProperties ([]); + item.service = service; + item.info = info; + item.installed_addin = installedAddin; + item.status = status; + return item; } /// /// Constructor for the gallery view of available add-ins, some of which may already be installed. /// - public AddinListViewItem ( + public static AddinListViewItem NewForAvailableAddin ( SetupService service, AddinHeader info, - AddinRepositoryEntry available_addin, + AddinRepositoryEntry availableAddin, AddinStatus status) - : this () { - this.service = service; - this.info = info; - this.available_addin = available_addin; - this.status = status; - - installed_addin = AddinManager.Registry.GetAddin (Addin.GetIdName (info.Id)); + AddinListViewItem item = NewWithProperties ([]); + item.service = service; + item.info = info; + item.available_addin = availableAddin; + item.status = status; + item.installed_addin = AddinManager.Registry.GetAddin (Addin.GetIdName (info.Id)); + + return item; } public SetupService Service => service; diff --git a/Pinta.Gui.Addins/Pinta.Gui.Addins.csproj b/Pinta.Gui.Addins/Pinta.Gui.Addins.csproj index beb3100bf3..1b693ba871 100644 --- a/Pinta.Gui.Addins/Pinta.Gui.Addins.csproj +++ b/Pinta.Gui.Addins/Pinta.Gui.Addins.csproj @@ -1,4 +1,9 @@ + + + true + + diff --git a/Pinta.Gui.Widgets/Widgets/History/HistoryItemWidget.cs b/Pinta.Gui.Widgets/Widgets/History/HistoryItemWidget.cs index 661bba7697..38e1fb2372 100644 --- a/Pinta.Gui.Widgets/Widgets/History/HistoryItemWidget.cs +++ b/Pinta.Gui.Widgets/Widgets/History/HistoryItemWidget.cs @@ -28,12 +28,12 @@ namespace Pinta.Gui.Widgets; // GObject subclass for use with Gio.ListStore -[Subclass] +[GObject.Subclass] public sealed partial class HistoryListViewItem { - private readonly BaseHistoryItem item = new (); + private BaseHistoryItem item = new (); - public HistoryListViewItem (BaseHistoryItem item) : this () + public static HistoryListViewItem New (BaseHistoryItem item) { if (string.IsNullOrEmpty (item.Text)) throw new ArgumentException ($"{nameof (item.Text)} must contain value."); @@ -41,7 +41,9 @@ public HistoryListViewItem (BaseHistoryItem item) : this () if (string.IsNullOrEmpty (item.Icon)) throw new ArgumentException ($"{nameof (item.Icon)} must contain value."); - this.item = item; + HistoryListViewItem listViewItem = NewWithProperties ([]); + listViewItem.item = item; + return listViewItem; } public string Label => item.Text ?? string.Empty; diff --git a/Pinta.Gui.Widgets/Widgets/History/HistoryListView.cs b/Pinta.Gui.Widgets/Widgets/History/HistoryListView.cs index ae5d755123..87ea42161a 100644 --- a/Pinta.Gui.Widgets/Widgets/History/HistoryListView.cs +++ b/Pinta.Gui.Widgets/Widgets/History/HistoryListView.cs @@ -120,7 +120,7 @@ private void OnActiveDocumentChanged (object? sender, EventArgs e) return; foreach (BaseHistoryItem item in doc.History.Items) - model.Append (new HistoryListViewItem (item)); + model.Append (HistoryListViewItem.New (item)); // Move selection to the document's current history item. if (model.NItems > 0) { @@ -143,7 +143,7 @@ private void OnHistoryItemAdded (object? sender, HistoryItemAddedEventArgs args) // Remove any stale (previously undone) items before adding the new item. model.RemoveMultiple (idx, model.GetNItems () - idx); - model.Append (new HistoryListViewItem (args.Item)); + model.Append (HistoryListViewItem.New (args.Item)); selection_model.SetSelected (idx); list_view.ScrollToSelectedItem (selection_model); } diff --git a/Pinta.Gui.Widgets/Widgets/Layers/LayersListView.cs b/Pinta.Gui.Widgets/Widgets/Layers/LayersListView.cs index 4e34de1329..addb898624 100644 --- a/Pinta.Gui.Widgets/Widgets/Layers/LayersListView.cs +++ b/Pinta.Gui.Widgets/Widgets/Layers/LayersListView.cs @@ -157,7 +157,7 @@ private void HandleActiveDocumentChanged (object? sender, EventArgs e) return; foreach (var layer in doc.Layers.UserLayers.Reverse ()) - list_model.Append (new LayersListViewItem (doc, layer)); + list_model.Append (LayersListViewItem.New (doc, layer)); // Update our selection to match the document's active layer. int currentModelIndex = doc.Layers.Count () - 1 - doc.Layers.CurrentUserLayerIndex; @@ -190,7 +190,7 @@ private void HandleLayerAdded (object? sender, IndexEventArgs e) ArgumentNullException.ThrowIfNull (active_document); int index = active_document.Layers.Count () - 1 - e.Index; - list_model.Insert ((uint) index, new LayersListViewItem (active_document, active_document.Layers[e.Index])); + list_model.Insert ((uint) index, LayersListViewItem.New (active_document, active_document.Layers[e.Index])); list_view.ScrollToSelectedItem (selection_model); } diff --git a/Pinta.Gui.Widgets/Widgets/Layers/LayersListViewItemWidget.cs b/Pinta.Gui.Widgets/Widgets/Layers/LayersListViewItemWidget.cs index 7768af5345..86113b2aba 100644 --- a/Pinta.Gui.Widgets/Widgets/Layers/LayersListViewItemWidget.cs +++ b/Pinta.Gui.Widgets/Widgets/Layers/LayersListViewItemWidget.cs @@ -31,23 +31,21 @@ namespace Pinta.Gui.Widgets; // GObject subclass for use with Gio.ListStore -[Subclass] +[GObject.Subclass] public sealed partial class LayersListViewItem { private CanvasRenderer? canvas_renderer; // NRT - GObject requires a parameterless constructor, and these don't have simple defaults - private readonly Document? document; - public UserLayer? UserLayer { get; } - - public LayersListViewItem ( - Document doc, - UserLayer userLayer - ) - : this () + private Document? document; + public UserLayer? UserLayer { get; private set; } + + public static LayersListViewItem New (Document doc, UserLayer userLayer) { - document = doc; - UserLayer = userLayer; + LayersListViewItem item = NewWithProperties ([]); + item.document = doc; + item.UserLayer = userLayer; + return item; } public string Label => UserLayer?.Name ?? string.Empty; From 4af15c040def39e6ac604d750f36edcec9e7c3bc Mon Sep 17 00:00:00 2001 From: Cameron White Date: Thu, 26 Mar 2026 22:57:22 -0400 Subject: [PATCH 02/13] Fix gir.core warnings in Pinta.Core Switch to factory methods for constructing GObjects --- .../Extensions/Gtk/GtkExtensions.Widget.cs | 26 ++--- Pinta.Core/Extensions/ToolBarComboBox.cs | 2 +- Pinta.Core/Managers/ToolManager.cs | 30 +++--- Pinta.Tools/Tools/TextTool.cs | 98 ++++++++----------- 4 files changed, 72 insertions(+), 84 deletions(-) diff --git a/Pinta.Core/Extensions/Gtk/GtkExtensions.Widget.cs b/Pinta.Core/Extensions/Gtk/GtkExtensions.Widget.cs index d03044160d..5a5ee9ac5d 100644 --- a/Pinta.Core/Extensions/Gtk/GtkExtensions.Widget.cs +++ b/Pinta.Core/Extensions/Gtk/GtkExtensions.Widget.cs @@ -66,13 +66,9 @@ public static Gtk.Box Box ( BoxStyle style, ReadOnlySpan children) // TODO: Add 'params' keyword when updated to C#13 { - Gtk.Box stack = new (); - - // --- Mandatory - stack.SetOrientation (style.Orientation); + Gtk.Box stack = Gtk.Box.New (style.Orientation, style.Spacing ?? 0); // --- Optional - if (style.Spacing.HasValue) stack.Spacing = style.Spacing.Value; if (style.CssClass is not null) stack.AddCssClass (style.CssClass); stack.AppendMultiple (children); @@ -93,8 +89,7 @@ public static void AppendMultiple ( /// public static Gtk.Box CreateToolBar () { - Gtk.Box toolbar = new () { Spacing = 0 }; - toolbar.SetOrientation (Gtk.Orientation.Horizontal); + Gtk.Box toolbar = Gtk.Box.New (Gtk.Orientation.Horizontal, spacing: 0); toolbar.AddCssClass (AdwaitaStyles.Toolbar); return toolbar; } @@ -123,16 +118,15 @@ public static Gtk.Button CreateToolBarItem (this Command action, bool force_icon _ => $"{baseTooltip}\n{shortcuts_label}:\n" + string.Join ('\n', action.Shortcuts.Select (s => $"- {ReadableAcceleratorLabel (s)}")), }; - Gtk.Button button = new () { - ActionName = action.FullName, - TooltipText = fullTooltip, - }; + Gtk.Button button = Gtk.Button.New (); + button.ActionName = action.FullName; + button.TooltipText = fullTooltip; if (action.IsImportant && !force_icon_only) { - button.Child = new Adw.ButtonContent () { - IconName = action.IconName, - Label = label - }; + Adw.ButtonContent buttonContent = Adw.ButtonContent.New (); + buttonContent.IconName = action.IconName; + buttonContent.Label = label; + button.Child = buttonContent; } else { button.Label = label; button.IconName = action.IconName; @@ -148,7 +142,7 @@ public static Gtk.Button CreateDockToolBarItem (this Command action) public static Gtk.Separator CreateToolBarSeparator () { - Gtk.Separator sep = new (); + Gtk.Separator sep = Gtk.Separator.New (Gtk.Orientation.Vertical); sep.AddCssClass (AdwaitaStyles.Spacer); return sep; } diff --git a/Pinta.Core/Extensions/ToolBarComboBox.cs b/Pinta.Core/Extensions/ToolBarComboBox.cs index ea252bd214..331b73b335 100644 --- a/Pinta.Core/Extensions/ToolBarComboBox.cs +++ b/Pinta.Core/Extensions/ToolBarComboBox.cs @@ -46,7 +46,7 @@ public ToolBarComboBox (int width, int activeIndex, bool allowEntry, IEnumerable Gtk.ComboBoxText comboBox = allowEntry ? Gtk.ComboBoxText.NewWithEntry () - : new (); + : Gtk.ComboBoxText.New (); comboBox.CanFocus = allowEntry; diff --git a/Pinta.Core/Managers/ToolManager.cs b/Pinta.Core/Managers/ToolManager.cs index e16bec3f2c..2510ea057c 100644 --- a/Pinta.Core/Managers/ToolManager.cs +++ b/Pinta.Core/Managers/ToolManager.cs @@ -372,19 +372,25 @@ public override int Compare (BaseTool? x, BaseTool? y) private Gtk.ScrolledWindow? tool_widgets_scroll; private Gtk.Label ToolLabel => tool_label ??= Gtk.Label.New (string.Format (" {0}: ", Translations.GetString ("Tool"))); - private Gtk.Image ToolImage => tool_image ??= new Gtk.Image (); + private Gtk.Image ToolImage => tool_image ??= Gtk.Image.New (); private Gtk.Separator ToolSeparator => tool_sep ??= GtkExtensions.CreateToolBarSeparator (); private Gtk.Box ToolWidgetsBox => tool_widgets_box ??= Gtk.Box.New (Gtk.Orientation.Horizontal, 0); // Scroll the toolbar contents if they are very long (e.g. the line/curve tool). - private Gtk.ScrolledWindow ToolWidgetsScroll - => tool_widgets_scroll ??= new Gtk.ScrolledWindow () { - Child = ToolWidgetsBox, - HscrollbarPolicy = Gtk.PolicyType.Automatic, - VscrollbarPolicy = Gtk.PolicyType.Never, - HasFrame = false, - OverlayScrolling = true, - WindowPlacement = Gtk.CornerType.BottomRight, - Hexpand = true, - Halign = Gtk.Align.Fill, - }; + private Gtk.ScrolledWindow ToolWidgetsScroll { + get { + if (tool_widgets_scroll == null) { + tool_widgets_scroll = Gtk.ScrolledWindow.New (); + tool_widgets_scroll.Child = ToolWidgetsBox; + tool_widgets_scroll.HscrollbarPolicy = Gtk.PolicyType.Automatic; + tool_widgets_scroll.VscrollbarPolicy = Gtk.PolicyType.Never; + tool_widgets_scroll.HasFrame = false; + tool_widgets_scroll.OverlayScrolling = true; + tool_widgets_scroll.WindowPlacement = Gtk.CornerType.BottomRight; + tool_widgets_scroll.Hexpand = true; + tool_widgets_scroll.Halign = Gtk.Align.Fill; + } + + return tool_widgets_scroll; + } + } } diff --git a/Pinta.Tools/Tools/TextTool.cs b/Pinta.Tools/Tools/TextTool.cs index 33a54e6eb9..9e99d3557e 100644 --- a/Pinta.Tools/Tools/TextTool.cs +++ b/Pinta.Tools/Tools/TextTool.cs @@ -153,20 +153,18 @@ protected override void OnBuildToolBar (Gtk.Box tb) tb.Append (font_label); if (font_button == null) { - Gtk.FontDialog fontDialog = new () { - Modal = true, - }; - - font_button = new () { - UseSize = false, - UseFont = true, - CanFocus = false, - Level = Gtk.FontLevel.Family, - FontDesc = Pango.FontDescription.FromString ( - Settings.GetSetting (SettingNames.TEXT_FONT, - Gtk.Settings.GetDefault ()!.GtkFontName!)), - }; - font_button.SetDialog (fontDialog); + Gtk.FontDialog fontDialog = Gtk.FontDialog.New (); + fontDialog.Modal = true; + + font_button = Gtk.FontDialogButton.New (fontDialog); + font_button.UseSize = false; + font_button.UseFont = true; + font_button.CanFocus = false; + font_button.Level = Gtk.FontLevel.Family; + font_button.FontDesc = Pango.FontDescription.FromString ( + Settings.GetSetting (SettingNames.TEXT_FONT, + Gtk.Settings.GetDefault ()!.GtkFontName!)); + Gtk.FontDialogButton.FontDescPropertyDefinition.Notify (font_button, (_, _) => { HandleFontChanged (); }); @@ -231,17 +229,12 @@ protected override void OnBuildToolBar (Gtk.Box tb) tb.Append (GtkExtensions.CreateToolBarSeparator ()); if (font_size == null) { - var font_size_adjustment = new Gtk.Adjustment { - Lower = 1, - Upper = 2000, - StepIncrement = 1, - Value = PangoExtensions.UnitsToPixels (font_button.FontDesc!.GetSize ()), - }; - - font_size = new Gtk.SpinButton { - Adjustment = font_size_adjustment, - TooltipText = Translations.GetString ("Change font size. Shortcut keys: [ ]"), - }; + Gtk.Adjustment fontSizeAdjustment = Gtk.Adjustment.New ( + value: PangoExtensions.UnitsToPixels (font_button.FontDesc!.GetSize ()), + lower: 1, upper: 2000, stepIncrement: 1, pageIncrement: 0, pageSize: 0); + + font_size = Gtk.SpinButton.New (fontSizeAdjustment, climbRate: 0.0, digits: 0); + font_size.TooltipText = Translations.GetString ("Change font size. Shortcut keys: [ ]"); font_size.OnValueChanged += HandleFontSizeChanged; } @@ -332,24 +325,22 @@ protected override void OnBuildToolBar (Gtk.Box tb) tb.Append (weight_btn); if (italic_btn == null) { - italic_btn = new Gtk.ToggleButton { - IconName = Pinta.Resources.StandardIcons.FormatTextItalic, - TooltipText = Translations.GetString ("Italic"), - CanFocus = false, - Active = Settings.GetSetting (SettingNames.TEXT_ITALIC, false), - }; + italic_btn = Gtk.ToggleButton.New (); + italic_btn.IconName = Pinta.Resources.StandardIcons.FormatTextItalic; + italic_btn.TooltipText = Translations.GetString ("Italic"); + italic_btn.CanFocus = false; + italic_btn.Active = Settings.GetSetting (SettingNames.TEXT_ITALIC, false); italic_btn.OnToggled += HandleItalicButtonToggled; } tb.Append (italic_btn); if (underscore_btn == null) { - underscore_btn = new Gtk.ToggleButton { - IconName = Pinta.Resources.StandardIcons.FormatTextUnderline, - TooltipText = Translations.GetString ("Underline"), - CanFocus = false, - Active = Settings.GetSetting (SettingNames.TEXT_UNDERLINE, false), - }; + underscore_btn = Gtk.ToggleButton.New (); + underscore_btn.IconName = Pinta.Resources.StandardIcons.FormatTextUnderline; + underscore_btn.TooltipText = Translations.GetString ("Underline"); + underscore_btn.CanFocus = false; + underscore_btn.Active = Settings.GetSetting (SettingNames.TEXT_UNDERLINE, false); underscore_btn.OnToggled += HandleUnderscoreButtonToggled; } @@ -360,36 +351,33 @@ protected override void OnBuildToolBar (Gtk.Box tb) TextAlignment alignment = (TextAlignment) Settings.GetSetting (SettingNames.TEXT_ALIGNMENT, (int) TextAlignment.Left); if (left_alignment_btn == null) { - left_alignment_btn = new Gtk.ToggleButton { - IconName = Pinta.Resources.StandardIcons.FormatJustifyLeft, - TooltipText = Translations.GetString ("Left Align"), - CanFocus = false, - Active = alignment == TextAlignment.Left, - }; + left_alignment_btn = Gtk.ToggleButton.New (); + left_alignment_btn.IconName = Pinta.Resources.StandardIcons.FormatJustifyLeft; + left_alignment_btn.TooltipText = Translations.GetString ("Left Align"); + left_alignment_btn.CanFocus = false; + left_alignment_btn.Active = alignment == TextAlignment.Left; left_alignment_btn.OnToggled += HandleLeftAlignmentButtonToggled; } tb.Append (left_alignment_btn); if (center_alignment_btn == null) { - center_alignment_btn = new Gtk.ToggleButton { - IconName = Pinta.Resources.StandardIcons.FormatJustifyCenter, - TooltipText = Translations.GetString ("Center Align"), - CanFocus = false, - Active = alignment == TextAlignment.Center, - }; + center_alignment_btn = Gtk.ToggleButton.New (); + center_alignment_btn.IconName = Pinta.Resources.StandardIcons.FormatJustifyCenter; + center_alignment_btn.TooltipText = Translations.GetString ("Center Align"); + center_alignment_btn.CanFocus = false; + center_alignment_btn.Active = alignment == TextAlignment.Center; center_alignment_btn.OnToggled += HandleCenterAlignmentButtonToggled; } tb.Append (center_alignment_btn); if (right_alignment_btn == null) { - right_alignment_btn = new Gtk.ToggleButton { - IconName = Pinta.Resources.StandardIcons.FormatJustifyRight, - TooltipText = Translations.GetString ("Right Align"), - CanFocus = false, - Active = alignment == TextAlignment.Right, - }; + right_alignment_btn = Gtk.ToggleButton.New (); + right_alignment_btn.IconName = Pinta.Resources.StandardIcons.FormatJustifyRight; + right_alignment_btn.TooltipText = Translations.GetString ("Right Align"); + right_alignment_btn.CanFocus = false; + right_alignment_btn.Active = alignment == TextAlignment.Right; right_alignment_btn.OnToggled += HandleRightAlignmentButtonToggled; } From a4c39f9b5fb9a01d51f749f029e38f495f05ccbb Mon Sep 17 00:00:00 2001 From: Cameron White Date: Thu, 26 Mar 2026 23:18:38 -0400 Subject: [PATCH 03/13] gir.core: use factory methods in Pinta.Gui.Addins --- Pinta.Gui.Addins/AddinInfoView.cs | 32 +++++++++++++++----------- Pinta.Gui.Addins/AddinListView.cs | 7 +++--- Pinta.Gui.Addins/AddinListViewItem.cs | 20 ++++++++-------- Pinta.Gui.Addins/AddinManagerDialog.cs | 2 +- Pinta.Gui.Addins/InstallDialog.cs | 19 ++++++++------- Pinta.Gui.Addins/StatusProgressBar.cs | 11 ++++----- 6 files changed, 47 insertions(+), 44 deletions(-) diff --git a/Pinta.Gui.Addins/AddinInfoView.cs b/Pinta.Gui.Addins/AddinInfoView.cs index c38b879715..79675135d9 100644 --- a/Pinta.Gui.Addins/AddinInfoView.cs +++ b/Pinta.Gui.Addins/AddinInfoView.cs @@ -38,21 +38,25 @@ public AddinInfoView (SystemManager system, IChromeService chrome) { // --- Control creation - Gtk.Label titleLabel = new () { Halign = Gtk.Align.Start }; + Gtk.Label titleLabel = Gtk.Label.New (null); + titleLabel.Halign = Gtk.Align.Start; titleLabel.AddCssClass (AdwaitaStyles.Title4); - Gtk.Label versionLabel = new () { Halign = Gtk.Align.Start }; + Gtk.Label versionLabel = Gtk.Label.New (null); + versionLabel.Halign = Gtk.Align.Start; versionLabel.AddCssClass (AdwaitaStyles.Heading); - Gtk.Label sizeLabel = new () { Halign = Gtk.Align.Start }; + Gtk.Label sizeLabel = Gtk.Label.New (null); + sizeLabel.Halign = Gtk.Align.Start; sizeLabel.AddCssClass (AdwaitaStyles.Heading); - Gtk.Label repoLabel = new () { Halign = Gtk.Align.Start }; + Gtk.Label repoLabel = Gtk.Label.New (null); + repoLabel.Halign = Gtk.Align.Start; repoLabel.AddCssClass (AdwaitaStyles.Heading); Gtk.Label descriptionLabel = CreateDescriptionLabel (); - Adw.Bin emptyPage = new (); + Adw.Bin emptyPage = Adw.Bin.New (); Gtk.Button infoButton = CreateInfoButton (); Gtk.Button installButton = CreateInstallButton (); @@ -132,7 +136,8 @@ public AddinInfoView (SystemManager system, IChromeService chrome) private Gtk.Switch CreateEnableSwitch () { - Gtk.Switch result = new () { Visible = false }; + Gtk.Switch result = Gtk.Switch.New (); + result.Visible = false; result.OnStateSet += (_, _) => { HandleEnableSwitched (); return false; @@ -142,14 +147,13 @@ private Gtk.Switch CreateEnableSwitch () private static Gtk.Label CreateDescriptionLabel () { - Gtk.Label result = new () { - Halign = Gtk.Align.Start, - Hexpand = true, - Valign = Gtk.Align.Start, - Vexpand = true, - Xalign = 0, - Wrap = true, - }; + 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; } diff --git a/Pinta.Gui.Addins/AddinListView.cs b/Pinta.Gui.Addins/AddinListView.cs index c99b6de964..c51073f8e1 100644 --- a/Pinta.Gui.Addins/AddinListView.cs +++ b/Pinta.Gui.Addins/AddinListView.cs @@ -50,10 +50,9 @@ public AddinListView (SystemManager system, IChromeService chrome) listViewScroll.SetSizeRequest (300, 400); listViewScroll.SetPolicy (Gtk.PolicyType.Automatic, Gtk.PolicyType.Automatic); - Adw.StatusPage emptyListPage = new () { - IconName = StandardIcons.SystemSearch, - Title = Translations.GetString ("No Items Found"), - }; + Adw.StatusPage emptyListPage = Adw.StatusPage.New (); + emptyListPage.IconName = StandardIcons.SystemSearch; + emptyListPage.Title = Translations.GetString ("No Items Found"); emptyListPage.AddCssClass (AdwaitaStyles.Compact); Adw.ViewStack listViewStack = Adw.ViewStack.New (); diff --git a/Pinta.Gui.Addins/AddinListViewItem.cs b/Pinta.Gui.Addins/AddinListViewItem.cs index 511a501942..7409eba8f2 100644 --- a/Pinta.Gui.Addins/AddinListViewItem.cs +++ b/Pinta.Gui.Addins/AddinListViewItem.cs @@ -91,17 +91,15 @@ internal sealed class AddinListViewItemWidget : Gtk.Box public AddinListViewItemWidget () { - Gtk.Label nameLabel = new () { - Halign = Gtk.Align.Start, - Hexpand = true, - Ellipsize = Pango.EllipsizeMode.End, - }; - - Gtk.Label descriptionLabel = new () { - Halign = Gtk.Align.Start, - Hexpand = true, - Ellipsize = Pango.EllipsizeMode.End, - }; + Gtk.Label nameLabel = Gtk.Label.New (null); + nameLabel.Halign = Gtk.Align.Start; + nameLabel.Hexpand = true; + nameLabel.Ellipsize = Pango.EllipsizeMode.End; + + Gtk.Label descriptionLabel = Gtk.Label.New (null); + descriptionLabel.Halign = Gtk.Align.Start; + descriptionLabel.Hexpand = true; + descriptionLabel.Ellipsize = Pango.EllipsizeMode.End; descriptionLabel.AddCssClass (AdwaitaStyles.Body); descriptionLabel.AddCssClass (AdwaitaStyles.DimLabel); diff --git a/Pinta.Gui.Addins/AddinManagerDialog.cs b/Pinta.Gui.Addins/AddinManagerDialog.cs index 6e6248b395..d467494835 100644 --- a/Pinta.Gui.Addins/AddinManagerDialog.cs +++ b/Pinta.Gui.Addins/AddinManagerDialog.cs @@ -39,7 +39,7 @@ public AddinManagerDialog ( Adw.ViewStack viewStack = CreateViewStack (galleryList, installedList, updatesList); - Adw.ToastOverlay toastOverlay = new (); + Adw.ToastOverlay toastOverlay = Adw.ToastOverlay.New (); StatusProgressBar progressBar = new (viewStack, new ToastErrorReporter (toastOverlay)); toastOverlay.Child = progressBar; diff --git a/Pinta.Gui.Addins/InstallDialog.cs b/Pinta.Gui.Addins/InstallDialog.cs index eb22a9178d..36db269695 100644 --- a/Pinta.Gui.Addins/InstallDialog.cs +++ b/Pinta.Gui.Addins/InstallDialog.cs @@ -39,7 +39,7 @@ internal sealed class InstallDialog : Adw.Window public InstallDialog (Gtk.Window parent, SetupService service) { - Adw.WindowTitle windowTitle = new (); + Adw.WindowTitle windowTitle = Adw.WindowTitle.New ("", ""); BoxStyle spacedHorizontal = new ( orientation: Gtk.Orientation.Horizontal, @@ -52,34 +52,34 @@ public InstallDialog (Gtk.Window parent, SetupService service) Gtk.Label errorHeadingLabel = Gtk.Label.New (Translations.GetString ("The selected extension packages can't be installed because there are dependency conflicts.")); errorHeadingLabel.AddCssClass (AdwaitaStyles.Title4); - Gtk.Label errorLabel = new (); + Gtk.Label errorLabel = Gtk.Label.New (null); errorLabel.AddCssClass (AdwaitaStyles.Body); errorLabel.AddCssClass (AdwaitaStyles.Error); - Gtk.Label warningHeadingLabel = new (); + Gtk.Label warningHeadingLabel = Gtk.Label.New (null); warningHeadingLabel.AddCssClass (AdwaitaStyles.Title4); - Gtk.Label warningLabel = new (); + Gtk.Label warningLabel = Gtk.Label.New (null); warningLabel.AddCssClass (AdwaitaStyles.Body); warningLabel.AddCssClass (AdwaitaStyles.Warning); Gtk.Label installHeadingLabel = Gtk.Label.New (Translations.GetString ("The following packages will be installed:")); installHeadingLabel.AddCssClass (AdwaitaStyles.Title4); - Gtk.Label installLabel = new (); + Gtk.Label installLabel = Gtk.Label.New (null); installLabel.AddCssClass (AdwaitaStyles.Body); Gtk.Label uninstallHeadingLabel = Gtk.Label.New (Translations.GetString ("The following packages need to be uninstalled:")); uninstallHeadingLabel.AddCssClass (AdwaitaStyles.Title4); - Gtk.Label uninstallLabel = new (); + Gtk.Label uninstallLabel = Gtk.Label.New (null); uninstallLabel.AddCssClass (AdwaitaStyles.Body); uninstallLabel.AddCssClass (AdwaitaStyles.Warning); Gtk.Label dependenciesHeadingLabel = Gtk.Label.New (Translations.GetString ("The following dependencies could not be resolved:")); dependenciesHeadingLabel.AddCssClass (AdwaitaStyles.Title4); - Gtk.Label dependenciesLabel = new (); + Gtk.Label dependenciesLabel = Gtk.Label.New (null); dependenciesLabel.AddCssClass (AdwaitaStyles.Body); dependenciesLabel.AddCssClass (AdwaitaStyles.Error); @@ -138,10 +138,13 @@ public InstallDialog (Gtk.Window parent, SetupService service) // --- Initialization (Adw.Window) + Adw.HeaderBar headerBar = Adw.HeaderBar.New (); + headerBar.TitleWidget = windowTitle; + Content = GtkExtensions.Box ( spacedVertical, [ - new Adw.HeaderBar { TitleWidget = windowTitle }, + headerBar, progressBar, buttons, ]); diff --git a/Pinta.Gui.Addins/StatusProgressBar.cs b/Pinta.Gui.Addins/StatusProgressBar.cs index 430123b63b..e8413b1dbb 100644 --- a/Pinta.Gui.Addins/StatusProgressBar.cs +++ b/Pinta.Gui.Addins/StatusProgressBar.cs @@ -17,7 +17,7 @@ internal interface IErrorReporter /// internal sealed class StatusProgressBar : Adw.Bin, IProgressStatus { - private readonly Gtk.Overlay progress_overlay = new (); + private readonly Gtk.Overlay progress_overlay = Gtk.Overlay.New (); private readonly Gtk.ProgressBar progress_bar; private readonly IErrorReporter error_reporter; @@ -25,11 +25,10 @@ public StatusProgressBar (Gtk.Widget primary_widget, IErrorReporter error_report { this.error_reporter = error_reporter; - progress_bar = new Gtk.ProgressBar () { - Fraction = 0.5, - ShowText = true, - Valign = Gtk.Align.End - }; + progress_bar = Gtk.ProgressBar.New (); + progress_bar.Fraction = 0.5; + progress_bar.ShowText = true; + progress_bar.Valign = Gtk.Align.End; progress_bar.AddCssClass (Pinta.Core.AdwaitaStyles.Osd); progress_overlay.Child = primary_widget; From 1567211ffe1e872658b8d0f8bb3f9f971bede4d2 Mon Sep 17 00:00:00 2001 From: Cameron White Date: Thu, 26 Mar 2026 23:23:36 -0400 Subject: [PATCH 04/13] gir.core: Use factory methods in Pinta.Docking --- Pinta.Docking/DockItem.cs | 6 +++--- Pinta.Docking/DockNotebook.cs | 9 ++++----- Pinta.Docking/DockPanel.cs | 7 +++---- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/Pinta.Docking/DockItem.cs b/Pinta.Docking/DockItem.cs index d3c981a96c..c918d6675b 100644 --- a/Pinta.Docking/DockItem.cs +++ b/Pinta.Docking/DockItem.cs @@ -76,7 +76,7 @@ public DockItem ( Gtk.Button minimizeButton = CreateMinimizeButton (locked); Gtk.Button maximizeButton = CreateMaximizeButton (locked); - Gtk.Stack buttonStack = new (); + Gtk.Stack buttonStack = Gtk.Stack.New (); buttonStack.AddChild (minimizeButton); buttonStack.AddChild (maximizeButton); @@ -141,11 +141,11 @@ private Gtk.Button CreateMaximizeButton (bool locked) private static Gtk.Label CreateLabelWidget (bool locked) { if (locked) - return new (); + return Gtk.Label.New (null); const int padding = 8; - Gtk.Label result = new (); + Gtk.Label result = Gtk.Label.New (null); result.MarginStart = result.MarginEnd = padding; result.Hexpand = true; result.Halign = Gtk.Align.Start; diff --git a/Pinta.Docking/DockNotebook.cs b/Pinta.Docking/DockNotebook.cs index 3ac16d80f9..50b5b6e9ca 100644 --- a/Pinta.Docking/DockNotebook.cs +++ b/Pinta.Docking/DockNotebook.cs @@ -48,13 +48,12 @@ public sealed class DockNotebook : Gtk.Box public DockNotebook () { - Adw.TabView tabView = new () { - Vexpand = true, - Valign = Gtk.Align.Fill, - }; + Adw.TabView tabView = Adw.TabView.New (); + tabView.Vexpand = true; + tabView.Valign = Gtk.Align.Fill; tabView.OnClosePage += TabView_OnClosePage; - Adw.TabBar tabBar = new (); + Adw.TabBar tabBar = Adw.TabBar.New (); tabBar.SetView (tabView); tabBar.Autohide = true; tabBar.AddCssClass (AdwaitaStyles.Inline); diff --git a/Pinta.Docking/DockPanel.cs b/Pinta.Docking/DockPanel.cs index c78000c1be..37bc8db59b 100644 --- a/Pinta.Docking/DockPanel.cs +++ b/Pinta.Docking/DockPanel.cs @@ -50,10 +50,9 @@ public DockPanelItem (DockItem item) // Autohide is set to false since it seems to cause the popover to close even when clicking inside it, on macOS at least // Instead, the reopen button is a toggle button to close the popover. - Gtk.Popover popover = new () { - Autohide = false, - Position = Gtk.PositionType.Left, - }; + Gtk.Popover popover = Gtk.Popover.New (); + popover.Autohide = false; + popover.Position = Gtk.PositionType.Left; popover.SetParent (reopenButton); // --- References to keep From 959554be559f114691bea38eeb410ec0a94c963b Mon Sep 17 00:00:00 2001 From: Cameron White Date: Thu, 26 Mar 2026 23:44:41 -0400 Subject: [PATCH 05/13] gir.core: use factory methods in Pinta.Gui.Widgets --- .../Cairo/CairoExtensions.Samples.cs | 18 ++- .../Dialogs/SimpleEffectDialog.cs | 23 ++-- .../Widgets/AnglePickerWidget.cs | 22 ++-- .../Widgets/Canvas/CanvasWindow.cs | 11 +- .../Widgets/ColorPickerDialog.cs | 104 ++++++++---------- .../Widgets/ColorPickerSlider.cs | 15 ++- Pinta.Gui.Widgets/Widgets/ComboBoxWidget.cs | 7 +- .../Widgets/HScaleSpinButtonWidget.cs | 32 +++--- Pinta.Gui.Widgets/Widgets/PintaColorButton.cs | 7 +- .../Widgets/PointPickerWidget.cs | 31 +++--- 10 files changed, 118 insertions(+), 152 deletions(-) diff --git a/Pinta.Core/Extensions/Cairo/CairoExtensions.Samples.cs b/Pinta.Core/Extensions/Cairo/CairoExtensions.Samples.cs index d708cf312c..b5465159d3 100644 --- a/Pinta.Core/Extensions/Cairo/CairoExtensions.Samples.cs +++ b/Pinta.Core/Extensions/Cairo/CairoExtensions.Samples.cs @@ -355,16 +355,14 @@ public static Gdk.Texture ToTexture (this Cairo.ImageSurface surface, Gdk.Textur { GLib.Bytes bytes = GLib.Bytes.New (surface.GetData ()); - Gdk.MemoryTextureBuilder builder = new () { - Bytes = bytes, - Stride = (ulong) surface.Stride, - Width = surface.Width, - Height = surface.Height, - Format = Gdk.MemoryFormat.B8g8r8a8Premultiplied, - UpdateTexture = updateTexture, - UpdateRegion = updateRegion ?? CairoExtensions.CreateRegion (RectangleI.Zero) - - }; + Gdk.MemoryTextureBuilder builder = Gdk.MemoryTextureBuilder.New (); + builder.Bytes = bytes; + builder.Stride = (ulong) surface.Stride; + builder.Width = surface.Width; + builder.Height = surface.Height; + builder.Format = Gdk.MemoryFormat.B8g8r8a8Premultiplied; + builder.UpdateTexture = updateTexture; + builder.UpdateRegion = updateRegion ?? CairoExtensions.CreateRegion (RectangleI.Zero); return builder.Build (); } diff --git a/Pinta.Gui.Widgets/Dialogs/SimpleEffectDialog.cs b/Pinta.Gui.Widgets/Dialogs/SimpleEffectDialog.cs index 2afc93b99b..f99ef34f72 100644 --- a/Pinta.Gui.Widgets/Dialogs/SimpleEffectDialog.cs +++ b/Pinta.Gui.Widgets/Dialogs/SimpleEffectDialog.cs @@ -513,7 +513,7 @@ private Gtk.CheckButton CreateCheckBox ( MemberSettings settings, IWorkspaceService workspace) { - Gtk.CheckButton widget = new () { Label = caption }; + Gtk.CheckButton widget = Gtk.CheckButton.NewWithLabel (caption); if (settings.reflector.GetValue (effectData) is bool b) widget.Active = b; @@ -620,7 +620,7 @@ private Gtk.Widget CreateSeed ( Random random = new (); - Gtk.Label sectionLabel = new (); + Gtk.Label sectionLabel = Gtk.Label.New (null); sectionLabel.AddCssClass (AdwaitaStyles.Title4); sectionLabel.Hexpand = false; sectionLabel.Halign = Gtk.Align.Start; @@ -636,23 +636,20 @@ private Gtk.Widget CreateSeed ( }); }; - Gtk.Button reseedButton = new () { - WidthRequest = 88, - CanFocus = true, - UseUnderline = true, - Label = Translations.GetString ("Reseed"), - Hexpand = false, - Halign = Gtk.Align.Start, - }; + Gtk.Button reseedButton = Gtk.Button.NewWithLabel (Translations.GetString ("Reseed")); + reseedButton.WidthRequest = 88; + reseedButton.CanFocus = true; + reseedButton.UseUnderline = true; + reseedButton.Hexpand = false; + reseedButton.Halign = Gtk.Align.Start; reseedButton.OnClicked += (_, _) => seedInput.Value = random.Next (minSeed, maxSeed); - Gtk.Box controlsBox = new () { Spacing = 6 }; - controlsBox.SetOrientation (Gtk.Orientation.Horizontal); + Gtk.Box controlsBox = Gtk.Box.New (Gtk.Orientation.Horizontal, spacing: 6); controlsBox.Append (reseedButton); controlsBox.Append (seedInput); - Gtk.Box combinedWidget = Gtk.Box.New (Gtk.Orientation.Vertical, 6); + Gtk.Box combinedWidget = Gtk.Box.New (Gtk.Orientation.Vertical, spacing: 6); combinedWidget.Append (sectionLabel); combinedWidget.Append (controlsBox); diff --git a/Pinta.Gui.Widgets/Widgets/AnglePickerWidget.cs b/Pinta.Gui.Widgets/Widgets/AnglePickerWidget.cs index 53f28eca52..61b7e1b11f 100644 --- a/Pinta.Gui.Widgets/Widgets/AnglePickerWidget.cs +++ b/Pinta.Gui.Widgets/Widgets/AnglePickerWidget.cs @@ -23,11 +23,10 @@ public AnglePickerWidget (DegreesAngle initialAngle) { const int SPACING = 6; - Gtk.Label widgetLabel = new (); + Gtk.Label widgetLabel = Gtk.Label.New (null); widgetLabel.AddCssClass (AdwaitaStyles.Title4); - Gtk.Box labelBox = new () { Spacing = SPACING }; - labelBox.SetOrientation (Gtk.Orientation.Horizontal); + Gtk.Box labelBox = Gtk.Box.New (Gtk.Orientation.Horizontal, SPACING); labelBox.Append (widgetLabel); AnglePickerGraphic anglePickerGraphic = new () { @@ -46,18 +45,15 @@ public AnglePickerWidget (DegreesAngle initialAngle) numericSpin.OnValueChanged += HandleSpinValueChanged; numericSpin.SetActivatesDefaultImmediate (true); - Gtk.Button resetButton = new () { - IconName = Resources.StandardIcons.GoPrevious, - WidthRequest = 28, - HeightRequest = 24, - CanFocus = true, - UseUnderline = true, - Valign = Gtk.Align.Start, - }; + Gtk.Button resetButton = Gtk.Button.NewFromIconName (Resources.StandardIcons.GoPrevious); + resetButton.WidthRequest = 28; + resetButton.HeightRequest = 24; + resetButton.CanFocus = true; + resetButton.UseUnderline = true; + resetButton.Valign = Gtk.Align.Start; resetButton.OnClicked += HandleButtonClicked; - Gtk.Box controlsBox = new () { Spacing = SPACING }; - controlsBox.SetOrientation (Gtk.Orientation.Horizontal); + Gtk.Box controlsBox = Gtk.Box.New (Gtk.Orientation.Horizontal, SPACING); controlsBox.Append (anglePickerGraphic); controlsBox.Append (numericSpin); controlsBox.Append (resetButton); diff --git a/Pinta.Gui.Widgets/Widgets/Canvas/CanvasWindow.cs b/Pinta.Gui.Widgets/Widgets/Canvas/CanvasWindow.cs index 9b593ae77a..fd1714c24e 100644 --- a/Pinta.Gui.Widgets/Widgets/Canvas/CanvasWindow.cs +++ b/Pinta.Gui.Widgets/Widgets/Canvas/CanvasWindow.cs @@ -78,7 +78,7 @@ public CanvasWindow ( Name = "canvas", }; - Gtk.Viewport viewPort = new (); + Gtk.Viewport viewPort = Gtk.Viewport.New (null, null); viewPort.AddController (scrollController); viewPort.Child = canvas; @@ -91,11 +91,10 @@ public CanvasWindow ( dragController.OnDragUpdate += OnDragUpdate; dragController.OnDragEnd += OnDragEnd; - Gtk.ScrolledWindow scrolledWindow = new () { - Hexpand = true, - Vexpand = true, - Child = viewPort, - }; + Gtk.ScrolledWindow scrolledWindow = Gtk.ScrolledWindow.New (); + scrolledWindow.Hexpand = true; + scrolledWindow.Vexpand = true; + scrolledWindow.Child = viewPort; Ruler horizontalRuler = new (Gtk.Orientation.Horizontal) { Metric = MetricType.Pixels, diff --git a/Pinta.Gui.Widgets/Widgets/ColorPickerDialog.cs b/Pinta.Gui.Widgets/Widgets/ColorPickerDialog.cs index 2785583fc0..ee4d9a512f 100644 --- a/Pinta.Gui.Widgets/Widgets/ColorPickerDialog.cs +++ b/Pinta.Gui.Widgets/Widgets/ColorPickerDialog.cs @@ -187,12 +187,10 @@ private PickerSurfaceBundle BuildPickerSurface () // Show Value toggle for hue sat picker surface - Gtk.CheckButton pickerSurfaceOptionDrawValue = new () { - Active = true, - Label = Translations.GetString ("Show Value"), - TooltipText = Translations.GetString ("If enabled, the Value component is applied to the color wheel."), - FocusOnClick = false - }; + Gtk.CheckButton pickerSurfaceOptionDrawValue = Gtk.CheckButton.NewWithLabel (Translations.GetString ("Show Value")); + pickerSurfaceOptionDrawValue.Active = true; + pickerSurfaceOptionDrawValue.TooltipText = Translations.GetString ("If enabled, the Value component is applied to the color wheel."); + pickerSurfaceOptionDrawValue.FocusOnClick = false; pickerSurfaceOptionDrawValue.SetVisible (DEFAULT_PICKER_SURFACE_TYPE == ColorSurfaceType.HueAndSat); pickerSurfaceOptionDrawValue.OnToggled += (o, e) => UpdateView (); @@ -216,21 +214,19 @@ private PickerSurfaceBundle BuildPickerSurface () }; pickerSurfaceHueSat.SetGroup (pickerSurfaceSatVal); - Gtk.Box pickerSurfaceSelectorBox = new Gtk.Box { - Spacing = spacing, - WidthRequest = pickerSurfaceDrawSize, - Homogeneous = true, - Halign = Gtk.Align.Center, - }; + Gtk.Box pickerSurfaceSelectorBox = Gtk.Box.New (Gtk.Orientation.Horizontal, spacing); + pickerSurfaceSelectorBox.WidthRequest = pickerSurfaceDrawSize; + pickerSurfaceSelectorBox.Homogeneous = true; + pickerSurfaceSelectorBox.Halign = Gtk.Align.Center; pickerSurfaceSelectorBox.Append (pickerSurfaceHueSat); pickerSurfaceSelectorBox.Append (pickerSurfaceSatVal); - Gtk.DrawingArea pickerSurface = new (); + Gtk.DrawingArea pickerSurface = Gtk.DrawingArea.New (); pickerSurface.SetSizeRequest (pickerSurfaceDrawSize, pickerSurfaceDrawSize); pickerSurface.SetDrawFunc ((area, context, width, height) => DrawColorSurface (context)); // Cursor handles the square in the picker surface displaying where your selected color is - Gtk.DrawingArea pickerSurfaceCursor = new (); + Gtk.DrawingArea pickerSurfaceCursor = Gtk.DrawingArea.New (); pickerSurfaceCursor.SetSizeRequest (pickerSurfaceDrawSize, pickerSurfaceDrawSize); pickerSurfaceCursor.SetDrawFunc ((area, context, width, height) => { @@ -255,16 +251,13 @@ private PickerSurfaceBundle BuildPickerSurface () }); // Overlays the cursor on top of the surface - Gtk.Overlay pickerSurfaceOverlay = new (); + Gtk.Overlay pickerSurfaceOverlay = Gtk.Overlay.New (); pickerSurfaceOverlay.AddOverlay (pickerSurface); pickerSurfaceOverlay.AddOverlay (pickerSurfaceCursor); pickerSurfaceOverlay.SetSizeRequest (pickerSurfaceDrawSize, pickerSurfaceDrawSize); - Gtk.Box pickerSurfaceBox = new () { - Spacing = spacing, - WidthRequest = pickerSurfaceDrawSize, - }; - pickerSurfaceBox.SetOrientation (Gtk.Orientation.Vertical); + Gtk.Box pickerSurfaceBox = Gtk.Box.New (Gtk.Orientation.Vertical, spacing); + pickerSurfaceBox.WidthRequest = pickerSurfaceDrawSize; pickerSurfaceBox.Append (pickerSurfaceSelectorBox); pickerSurfaceBox.Append (pickerSurfaceOverlay); pickerSurfaceBox.Append (pickerSurfaceOptionDrawValue); @@ -303,18 +296,15 @@ private readonly record struct SlidersBundle ( private SlidersBundle BuildColorSliders (Color initialColor) { - Gtk.Entry hexEntry = new () { - Text_ = initialColor.ToHex (), - MaxWidthChars = 10, - }; + Gtk.Entry hexEntry = Gtk.Entry.New (); + hexEntry.Text_ = initialColor.ToHex (); + hexEntry.MaxWidthChars = 10; hexEntry.OnChanged += HexEntry_OnChanged; - Gtk.Label hexLabel = new () { - Label_ = Translations.GetString ("Hex"), - WidthRequest = 50, - }; + Gtk.Label hexLabel = Gtk.Label.New (Translations.GetString ("Hex")); + hexLabel.WidthRequest = 50; - Gtk.Box hexBox = new () { Spacing = spacing }; + Gtk.Box hexBox = Gtk.Box.New (Gtk.Orientation.Horizontal, spacing); hexBox.Append (hexLabel); hexBox.Append (hexEntry); @@ -326,17 +316,16 @@ private SlidersBundle BuildColorSliders (Color initialColor) ColorPickerSlider blueSlider = CreateSlider (ColorPickerSlider.Component.Blue, initialColor); ColorPickerSlider alphaSlider = CreateSlider (ColorPickerSlider.Component.Alpha, initialColor); - Gtk.Box slidersBox = new () { Spacing = spacing }; - slidersBox.SetOrientation (Gtk.Orientation.Vertical); + Gtk.Box slidersBox = Gtk.Box.New (Gtk.Orientation.Vertical, spacing); slidersBox.Append (hexBox); slidersBox.Append (hueSlider); slidersBox.Append (saturationSlider); slidersBox.Append (valueSlider); - slidersBox.Append (new Gtk.Separator ()); + slidersBox.Append (Gtk.Separator.New (Gtk.Orientation.Horizontal)); slidersBox.Append (redSlider); slidersBox.Append (greenSlider); slidersBox.Append (blueSlider); - slidersBox.Append (new Gtk.Separator ()); + slidersBox.Append (Gtk.Separator.New (Gtk.Orientation.Horizontal)); slidersBox.Append (alphaSlider); return new ( @@ -371,28 +360,26 @@ public ColorPickerDialog ( { bool showWatches = !livePalette; - Gtk.Button resetButton = new () { - Label = Translations.GetString ("Reset"), - FocusOnClick = false - }; + Gtk.Button resetButton = Gtk.Button.NewWithLabel (Translations.GetString ("Reset")); + resetButton.FocusOnClick = false; resetButton.OnClicked += OnResetButtonClicked; - Gtk.Button shrinkButton = new () { FocusOnClick = false }; - shrinkButton.OnClicked += OnShrinkButtonClicked; + Gtk.Button shrinkButton = Gtk.Button.New (); + shrinkButton.FocusOnClick = false; shrinkButton.SetIconName ( DEFAULT_SMALL_MODE ? Resources.StandardIcons.WindowMaximize : Resources.StandardIcons.WindowMinimize); - Gtk.Button okButton = new () { Label = Translations.GetString ("OK") }; + Gtk.Button okButton = Gtk.Button.NewWithLabel (Translations.GetString ("OK")); okButton.ReceivesDefault = true; okButton.OnClicked += OnOkButtonClicked; okButton.AddCssClass (AdwaitaStyles.SuggestedAction); - Gtk.Button cancelButton = new () { Label = Translations.GetString ("Cancel") }; + Gtk.Button cancelButton = Gtk.Button.NewWithLabel (Translations.GetString ("Cancel")); cancelButton.OnClicked += OnCancelButtonClicked; - Gtk.HeaderBar titleBar = new (); + Gtk.HeaderBar titleBar = Gtk.HeaderBar.New (); titleBar.PackStart (resetButton); titleBar.PackStart (shrinkButton); titleBar.PackEnd (okButton); @@ -404,7 +391,7 @@ public ColorPickerDialog ( ImmutableArray colorDisplays = CreateColorDisplays (adjustable); - Gtk.ListBox colorDisplayList = new (); + Gtk.ListBox colorDisplayList = Gtk.ListBox.New (); foreach (var colorDisplay in colorDisplays) colorDisplayList.Append (colorDisplay); // Set initial selected row @@ -418,8 +405,7 @@ public ColorPickerDialog ( UpdateView (); }); - Gtk.Box colorDisplayBox = new () { Spacing = spacing }; - colorDisplayBox.SetOrientation (Gtk.Orientation.Vertical); + Gtk.Box colorDisplayBox = Gtk.Box.New (Gtk.Orientation.Vertical, spacing); if (adjustable is PaletteColors paletteColors) { string label = Translations.GetString ("Click to switch between primary and secondary color."); string shortcutLabel = Translations.GetString ("Shortcut key"); @@ -449,20 +435,17 @@ public ColorPickerDialog ( // 90% taken from SatusBarColorPaletteWidget // todo: merge both - Gtk.DrawingArea swatchRecent = new () { - WidthRequest = 500, - HeightRequest = PaletteWidget.SWATCH_SIZE * PaletteWidget.PALETTE_ROWS, - }; + Gtk.DrawingArea swatchRecent = Gtk.DrawingArea.New (); + swatchRecent.WidthRequest = 500; + swatchRecent.HeightRequest = PaletteWidget.SWATCH_SIZE * PaletteWidget.PALETTE_ROWS; swatchRecent.SetDrawFunc (SwatchRecentDraw); - Gtk.DrawingArea swatchPalette = new () { - WidthRequest = 500, - HeightRequest = PaletteWidget.SWATCH_SIZE * PaletteWidget.PALETTE_ROWS, - }; + Gtk.DrawingArea swatchPalette = Gtk.DrawingArea.New (); + swatchPalette.WidthRequest = 500; + swatchPalette.HeightRequest = PaletteWidget.SWATCH_SIZE * PaletteWidget.PALETTE_ROWS; swatchPalette.SetDrawFunc (SwatchPaletteDraw); - Gtk.Box swatchBox = new () { Spacing = spacing }; - swatchBox.SetOrientation (Gtk.Orientation.Vertical); + Gtk.Box swatchBox = Gtk.Box.New (Gtk.Orientation.Vertical, spacing); swatchBox.Append (swatchRecent); swatchBox.Append (swatchPalette); swatchBox.SetVisible (showWatches); @@ -479,13 +462,12 @@ public ColorPickerDialog ( // Top part of the color picker. // Includes palette, color surface, sliders/hex // Basically, the not-swatches - Gtk.Box topBox = new () { Spacing = spacing }; + Gtk.Box topBox = Gtk.Box.New (Gtk.Orientation.Horizontal, spacing); topBox.Append (colorDisplayBox); topBox.Append (pickerSurfaceControls.Box); topBox.Append (colorSliders.Box); - Gtk.Box mainVbox = new () { Spacing = spacing }; - mainVbox.SetOrientation (Gtk.Orientation.Vertical); + Gtk.Box mainVbox = Gtk.Box.New (Gtk.Orientation.Vertical, spacing); mainVbox.Append (topBox); if (!DEFAULT_SMALL_MODE) mainVbox.Append (swatchBox); @@ -568,7 +550,7 @@ public ColorPickerDialog ( case SingleColor singleColors: - Gtk.DrawingArea singleColorDisplay = new (); + Gtk.DrawingArea singleColorDisplay = Gtk.DrawingArea.New (); singleColorDisplay.SetSizeRequest (palette_display_size, palette_display_size); singleColorDisplay.SetDrawFunc ((area, context, width, height) => DrawPaletteDisplay (context, ((SingleColor) Colors).Color)); @@ -576,12 +558,12 @@ public ColorPickerDialog ( case PaletteColors paletteColors: - Gtk.DrawingArea primaryColorDisplay = new (); + Gtk.DrawingArea primaryColorDisplay = Gtk.DrawingArea.New (); primaryColorDisplay.SetSizeRequest (palette_display_size, palette_display_size); primaryColorDisplay.SetDrawFunc ((area, context, width, height) => DrawPaletteDisplay (context, ((PaletteColors) Colors).Primary)); primaryColorDisplay.SetTooltipText (Translations.GetString ("Click to select primary color.")); - Gtk.DrawingArea secondaryColorDisplay = new (); + Gtk.DrawingArea secondaryColorDisplay = Gtk.DrawingArea.New (); secondaryColorDisplay.SetSizeRequest (palette_display_size, palette_display_size); secondaryColorDisplay.SetDrawFunc ((area, context, width, height) => DrawPaletteDisplay (context, ((PaletteColors) Colors).Secondary)); secondaryColorDisplay.SetTooltipText (Translations.GetString ("Click to select secondary color.")); diff --git a/Pinta.Gui.Widgets/Widgets/ColorPickerSlider.cs b/Pinta.Gui.Widgets/Widgets/ColorPickerSlider.cs index 51d3b20b58..56936d4fce 100644 --- a/Pinta.Gui.Widgets/Widgets/ColorPickerSlider.cs +++ b/Pinta.Gui.Widgets/Widgets/ColorPickerSlider.cs @@ -32,20 +32,19 @@ public enum Component public ColorPickerSlider (Component component, Color initialColor, int initialWidth) { - Gtk.DrawingArea gradientSlider = new (); + Gtk.DrawingArea gradientSlider = Gtk.DrawingArea.New (); gradientSlider.SetSizeRequest (initialWidth, this.GetHeight ()); gradientSlider.SetDrawFunc ((_, context, width, height) => { DrawGradient (context, width, height, CreateGradient (color, component)); }); - Gtk.Label sliderLabel = new () { WidthRequest = 50 }; - sliderLabel.SetLabel (GetLabelText (component)); + Gtk.Label sliderLabel = Gtk.Label.New (GetLabelText (component)); + sliderLabel.WidthRequest = 50; - Gtk.Entry inputField = new () { - MaxWidthChars = 3, - WidthRequest = 50, - Hexpand = false, - }; + Gtk.Entry inputField = Gtk.Entry.New (); + inputField.MaxWidthChars = 3; + inputField.WidthRequest = 50; + inputField.Hexpand = false; inputField.SetText (Convert.ToInt32 (ExtractValue (initialColor, component)).ToString ()); inputField.OnChanged += OnInputFieldChanged; diff --git a/Pinta.Gui.Widgets/Widgets/ComboBoxWidget.cs b/Pinta.Gui.Widgets/Widgets/ComboBoxWidget.cs index 168210723f..3ac8a053fe 100644 --- a/Pinta.Gui.Widgets/Widgets/ComboBoxWidget.cs +++ b/Pinta.Gui.Widgets/Widgets/ComboBoxWidget.cs @@ -39,11 +39,10 @@ public ComboBoxWidget (IEnumerable entries) { const int SPACING = 6; - Gtk.Label titleLabel = new (); + Gtk.Label titleLabel = Gtk.Label.New (null); titleLabel.AddCssClass (AdwaitaStyles.Title4); - Gtk.Box labelAndLine = new () { Spacing = SPACING }; - labelAndLine.SetOrientation (Gtk.Orientation.Horizontal); + Gtk.Box labelAndLine = Gtk.Box.New (Gtk.Orientation.Horizontal, SPACING); labelAndLine.Append (titleLabel); Gtk.ComboBoxText comboBox = CreateComboBox (entries); @@ -64,7 +63,7 @@ public ComboBoxWidget (IEnumerable entries) private Gtk.ComboBoxText CreateComboBox (IEnumerable entries) { - Gtk.ComboBoxText result = new (); + Gtk.ComboBoxText result = Gtk.ComboBoxText.New (); foreach (var s in entries) result.AppendText (s); diff --git a/Pinta.Gui.Widgets/Widgets/HScaleSpinButtonWidget.cs b/Pinta.Gui.Widgets/Widgets/HScaleSpinButtonWidget.cs index 82741c0cb0..36ffec7a45 100644 --- a/Pinta.Gui.Widgets/Widgets/HScaleSpinButtonWidget.cs +++ b/Pinta.Gui.Widgets/Widgets/HScaleSpinButtonWidget.cs @@ -1,21 +1,21 @@ -// +// // HScaleSpinButtonWidget.cs -// +// // Author: // Krzysztof Marecki -// +// // Copyright (c) 2010 Krzysztof Marecki -// +// // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: -// +// // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. -// +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -46,11 +46,10 @@ public HScaleSpinButtonWidget (double initialValue) { const int SPACING = 6; - Gtk.Label titleLabel = new (); + Gtk.Label titleLabel = Gtk.Label.New (null); titleLabel.AddCssClass (AdwaitaStyles.Title4); - Gtk.Box labelAndLine = new () { Spacing = SPACING }; - labelAndLine.SetOrientation (Gtk.Orientation.Horizontal); + Gtk.Box labelAndLine = Gtk.Box.New (Gtk.Orientation.Horizontal, SPACING); labelAndLine.Append (titleLabel); Gtk.Scale hScale = Gtk.Scale.NewWithRange (Gtk.Orientation.Horizontal, 2, 64, 1); @@ -70,17 +69,14 @@ public HScaleSpinButtonWidget (double initialValue) spinButton.OnValueChanged += HandleSpinValueChanged; spinButton.SetActivatesDefaultImmediate (true); - Gtk.Button resetButton = new () { - IconName = Resources.StandardIcons.GoPrevious, - WidthRequest = 28, - HeightRequest = 24, - CanFocus = true, - UseUnderline = true, - }; + Gtk.Button resetButton = Gtk.Button.NewFromIconName (Resources.StandardIcons.GoPrevious); + resetButton.WidthRequest = 28; + resetButton.HeightRequest = 24; + resetButton.CanFocus = true; + resetButton.UseUnderline = true; resetButton.OnClicked += HandleResetButtonClicked; - Gtk.Box valueControls = new () { Spacing = SPACING }; - valueControls.SetOrientation (Gtk.Orientation.Horizontal); + Gtk.Box valueControls = Gtk.Box.New (Gtk.Orientation.Horizontal, SPACING); valueControls.Append (hScale); valueControls.Append (spinButton); valueControls.Append (resetButton); diff --git a/Pinta.Gui.Widgets/Widgets/PintaColorButton.cs b/Pinta.Gui.Widgets/Widgets/PintaColorButton.cs index 5e50e6edbf..75027efcae 100644 --- a/Pinta.Gui.Widgets/Widgets/PintaColorButton.cs +++ b/Pinta.Gui.Widgets/Widgets/PintaColorButton.cs @@ -18,10 +18,9 @@ public Color DisplayColor { private readonly Gtk.DrawingArea color_drawing_area; internal PintaColorButton () { - Gtk.DrawingArea colorDrawingArea = new () { - Hexpand = true, - Vexpand = true, - }; + Gtk.DrawingArea colorDrawingArea = Gtk.DrawingArea.New (); + colorDrawingArea.Hexpand = true; + colorDrawingArea.Vexpand = true; colorDrawingArea.SetDrawFunc (OnDraw); SetChild (colorDrawingArea); color_drawing_area = colorDrawingArea; diff --git a/Pinta.Gui.Widgets/Widgets/PointPickerWidget.cs b/Pinta.Gui.Widgets/Widgets/PointPickerWidget.cs index 9a571a53c6..2ef2da3282 100644 --- a/Pinta.Gui.Widgets/Widgets/PointPickerWidget.cs +++ b/Pinta.Gui.Widgets/Widgets/PointPickerWidget.cs @@ -1,21 +1,21 @@ -// +// // PointPicker.cs -// +// // Author: // Olivier Dufour -// +// // Copyright (c) 2010 Olivier Dufour -// +// // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: -// +// // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. -// +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -69,7 +69,7 @@ public PointPickerWidget (IWorkspaceService workspace, PointI initialPoint, bool // --- Section label + line - Gtk.Label titleLabel = new (); + Gtk.Label titleLabel = Gtk.Label.New (null); titleLabel.AddCssClass (AdwaitaStyles.Title4); Gtk.Box labelAndTitle = GtkExtensions.Box ( @@ -152,14 +152,15 @@ public PointPickerWidget (IWorkspaceService workspace, PointI initialPoint, bool } private static Gtk.Button CreateResetButton () - => new () { - IconName = Resources.StandardIcons.GoPrevious, - WidthRequest = 28, - HeightRequest = 24, - CanFocus = true, - UseUnderline = true, - Valign = Gtk.Align.Start, - }; + { + Gtk.Button button = Gtk.Button.NewFromIconName (Resources.StandardIcons.GoPrevious); + button.WidthRequest = 28; + button.HeightRequest = 24; + button.CanFocus = true; + button.UseUnderline = true; + button.Valign = Gtk.Align.Start; + return button; + } private static Gtk.SpinButton CreateSpinX (Size imageSize) { From cb8cae68c3724f25e0d1f36d018f3ed5317b3e2a Mon Sep 17 00:00:00 2001 From: Cameron White Date: Thu, 26 Mar 2026 23:48:38 -0400 Subject: [PATCH 06/13] gir.core: use factory methods in Pinta.Effects --- .../Dialogs/Effects.AlignmentDialog.cs | 21 +++++++-------- Pinta.Effects/Dialogs/Effects.CurvesDialog.cs | 26 +++++++++---------- Pinta.Effects/Dialogs/Effects.LevelsDialog.cs | 9 ++++--- 3 files changed, 28 insertions(+), 28 deletions(-) diff --git a/Pinta.Effects/Dialogs/Effects.AlignmentDialog.cs b/Pinta.Effects/Dialogs/Effects.AlignmentDialog.cs index 1db45bd10f..29598a957b 100644 --- a/Pinta.Effects/Dialogs/Effects.AlignmentDialog.cs +++ b/Pinta.Effects/Dialogs/Effects.AlignmentDialog.cs @@ -35,16 +35,15 @@ public AlignmentDialog (IChromeService chrome) Gtk.ToggleButton bottomCenterToggle = CreateIconButton (Translations.GetString ("Bottom Center"), Resources.Icons.ResizeCanvasDown, AlignPosition.BottomCenter); Gtk.ToggleButton bottomRightToggle = CreateIconButton (Translations.GetString ("Bottom Right"), Resources.Icons.ResizeCanvasSE, AlignPosition.BottomRight); - Gtk.Grid grid = new () { - RowSpacing = spacing, - ColumnSpacing = spacing, - RowHomogeneous = true, - ColumnHomogeneous = true, - MarginStart = 12, - MarginEnd = 12, - MarginTop = 12, - MarginBottom = 12, - }; + Gtk.Grid grid = Gtk.Grid.New (); + grid.RowSpacing = spacing; + grid.ColumnSpacing = spacing; + grid.RowHomogeneous = true; + grid.ColumnHomogeneous = true; + grid.MarginStart = 12; + grid.MarginEnd = 12; + grid.MarginTop = 12; + grid.MarginBottom = 12; grid.Attach (topLeftToggle, 0, 0, 1, 1); grid.Attach (topCenterToggle, 1, 0, 1, 1); grid.Attach (topRightToggle, 2, 0, 1, 1); @@ -96,7 +95,7 @@ private Gtk.ToggleButton CreateIconButton ( string iconName, AlignPosition position) { - Gtk.ToggleButton button = new (); + Gtk.ToggleButton button = Gtk.ToggleButton.New (); button.SetIconName (iconName); diff --git a/Pinta.Effects/Dialogs/Effects.CurvesDialog.cs b/Pinta.Effects/Dialogs/Effects.CurvesDialog.cs index 99a7b84a0a..a2f6974a80 100644 --- a/Pinta.Effects/Dialogs/Effects.CurvesDialog.cs +++ b/Pinta.Effects/Dialogs/Effects.CurvesDialog.cs @@ -114,11 +114,10 @@ public CurvesDialog ( checkBlue, buttonReset]); - Gtk.DrawingArea curvesDrawing = new () { - WidthRequest = 256, - HeightRequest = 256, - CanFocus = true, - }; + Gtk.DrawingArea curvesDrawing = Gtk.DrawingArea.New (); + curvesDrawing.WidthRequest = 256; + curvesDrawing.HeightRequest = 256; + curvesDrawing.CanFocus = true; curvesDrawing.SetAllMargins (8); curvesDrawing.SetDrawFunc ((area, context, width, height) => HandleDrawingDrawnEvent (context)); curvesDrawing.AddController (motionController); @@ -172,7 +171,7 @@ public CurvesDialog ( private Gtk.ComboBoxText CreateComboMap () { - Gtk.ComboBoxText result = new (); + Gtk.ComboBoxText result = Gtk.ComboBoxText.New (); result.AppendText (Translations.GetString ("RGB")); result.AppendText (Translations.GetString ("Luminosity")); result.Active = 1; @@ -205,13 +204,11 @@ private static Gtk.Label CreateLabelPoint () private Gtk.Button CreateResetButton () { - Gtk.Button result = new () { - WidthRequest = 81, - HeightRequest = 30, - Label = Translations.GetString ("Reset"), - Halign = Gtk.Align.End, - Hexpand = true, - }; + Gtk.Button result = Gtk.Button.NewWithLabel (Translations.GetString ("Reset")); + result.WidthRequest = 81; + result.HeightRequest = 30; + result.Halign = Gtk.Align.End; + result.Hexpand = true; result.OnClicked += HandleButtonResetClicked; return result; @@ -226,7 +223,8 @@ void HandleButtonResetClicked (object? sender, EventArgs e) private Gtk.CheckButton CreateColorCheck (string label) { - Gtk.CheckButton result = new () { Label = label, Active = true }; + Gtk.CheckButton result = Gtk.CheckButton.NewWithLabel (label); + result.Active = true; result.Hide (); result.OnToggled += (_, _) => InvalidateDrawing (); return result; diff --git a/Pinta.Effects/Dialogs/Effects.LevelsDialog.cs b/Pinta.Effects/Dialogs/Effects.LevelsDialog.cs index 13660c2bc2..1ed82a80a8 100644 --- a/Pinta.Effects/Dialogs/Effects.LevelsDialog.cs +++ b/Pinta.Effects/Dialogs/Effects.LevelsDialog.cs @@ -105,13 +105,16 @@ public LevelsDialog ( BoxStyle horizontalSpaced = new (Gtk.Orientation.Horizontal, SPACING); BoxStyle verticalSpaced = new (Gtk.Orientation.Vertical, SPACING); - Gtk.CheckButton checkRed = new () { Label = Translations.GetString ("Red"), Active = true }; + Gtk.CheckButton checkRed = Gtk.CheckButton.NewWithLabel (Translations.GetString ("Red")); + checkRed.Active = true; checkRed.OnToggled += HandleCheckRedToggled; - Gtk.CheckButton checkGreen = new () { Label = Translations.GetString ("Green"), Active = true }; + Gtk.CheckButton checkGreen = Gtk.CheckButton.NewWithLabel (Translations.GetString ("Green")); + checkGreen.Active = true; checkGreen.OnToggled += HandleCheckGreenToggled; - Gtk.CheckButton checkBlue = new () { Label = Translations.GetString ("Blue"), Active = true }; + Gtk.CheckButton checkBlue = Gtk.CheckButton.NewWithLabel (Translations.GetString ("Blue")); + checkBlue.Active = true; checkBlue.OnToggled += HandleCheckBlueToggled; Gtk.Box hboxChecks = GtkExtensions.Box ( From 483ddbf1a79edbd164c3e0ef219254c8fd60ab7e Mon Sep 17 00:00:00 2001 From: Cameron White Date: Thu, 26 Mar 2026 23:56:01 -0400 Subject: [PATCH 07/13] gir.core: use factory methods in Pinta. --- Pinta/Dialogs/CanvasGridSettingsDialog.cs | 12 ++-- Pinta/Dialogs/LayerPropertiesDialog.cs | 21 +++---- Pinta/Dialogs/NewImageDialog.cs | 31 +++++----- Pinta/Dialogs/ProgressDialog.cs | 4 +- Pinta/Dialogs/ResizeCanvasDialog.cs | 43 +++++++------- Pinta/Dialogs/ResizeImageDialog.cs | 38 ++++++------ Pinta/MainWindow.cs | 72 +++++++++++------------ 7 files changed, 106 insertions(+), 115 deletions(-) diff --git a/Pinta/Dialogs/CanvasGridSettingsDialog.cs b/Pinta/Dialogs/CanvasGridSettingsDialog.cs index 97ddc5c88e..200ced9769 100644 --- a/Pinta/Dialogs/CanvasGridSettingsDialog.cs +++ b/Pinta/Dialogs/CanvasGridSettingsDialog.cs @@ -67,11 +67,10 @@ internal CanvasGridSettingsDialog (ChromeManager chrome, Settings initialSetting Gtk.Widget.SensitivePropertyDefinition.UnmanagedName, GObject.BindingFlags.SyncCreate); - Gtk.Grid grid = new () { - RowSpacing = SPACING, - ColumnSpacing = SPACING, - ColumnHomogeneous = false, - }; + Gtk.Grid grid = Gtk.Grid.New (); + grid.RowSpacing = SPACING; + grid.ColumnSpacing = SPACING; + grid.ColumnHomogeneous = false; grid.Attach (showGridCheckBox, 0, 0, 2, 1); @@ -91,8 +90,7 @@ internal CanvasGridSettingsDialog (ChromeManager chrome, Settings initialSetting grid.Attach (axonometricAnglePicker, 0, 5, 3, 1); - Gtk.Box mainVbox = new () { Spacing = SPACING }; - mainVbox.SetOrientation (Gtk.Orientation.Vertical); + Gtk.Box mainVbox = Gtk.Box.New (Gtk.Orientation.Vertical, SPACING); mainVbox.Append (grid); // --- Initialization (Gtk.Box) diff --git a/Pinta/Dialogs/LayerPropertiesDialog.cs b/Pinta/Dialogs/LayerPropertiesDialog.cs index e444f94a05..c5129fd97c 100644 --- a/Pinta/Dialogs/LayerPropertiesDialog.cs +++ b/Pinta/Dialogs/LayerPropertiesDialog.cs @@ -67,10 +67,9 @@ public LayerPropertiesDialog (ChromeManager chrome, WorkspaceManager workspace) Gtk.Label nameLabel = Gtk.Label.New (Translations.GetString ("Name:")); nameLabel.Halign = Gtk.Align.End; - Gtk.Entry layerNameEntry = new () { - Hexpand = true, - Halign = Gtk.Align.Fill, - }; + Gtk.Entry layerNameEntry = Gtk.Entry.New (); + layerNameEntry.Hexpand = true; + layerNameEntry.Halign = Gtk.Align.Fill; layerNameEntry.SetText (initialProperties.Name); layerNameEntry.OnChanged += OnLayerNameChanged; layerNameEntry.SetActivatesDefault (true); @@ -85,7 +84,7 @@ public LayerPropertiesDialog (ChromeManager chrome, WorkspaceManager workspace) var allBlendmodes = UserBlendOps.GetAllBlendModeNames ().ToImmutableArray (); var index = allBlendmodes.IndexOf (UserBlendOps.GetBlendModeName (currentLayerBlendMode)); - Gtk.ComboBoxText blendComboBox = new (); + Gtk.ComboBoxText blendComboBox = Gtk.ComboBoxText.New (); foreach (string name in UserBlendOps.GetAllBlendModeNames ()) blendComboBox.AppendText (name); @@ -113,16 +112,14 @@ public LayerPropertiesDialog (ChromeManager chrome, WorkspaceManager workspace) opacitySlider.SetValue (Math.Round (initialProperties.Opacity * 100)); opacitySlider.OnValueChanged += OnOpacitySliderChanged; - Gtk.Box opacityBox = new () { Spacing = spacing }; - opacityBox.SetOrientation (Gtk.Orientation.Horizontal); + Gtk.Box opacityBox = Gtk.Box.New (Gtk.Orientation.Horizontal, spacing); opacityBox.Append (opacitySpinner); opacityBox.Append (opacitySlider); - Gtk.Grid grid = new () { - RowSpacing = spacing, - ColumnSpacing = spacing, - ColumnHomogeneous = false, - }; + Gtk.Grid grid = Gtk.Grid.New (); + grid.RowSpacing = spacing; + grid.ColumnSpacing = spacing; + grid.ColumnHomogeneous = false; grid.Attach (nameLabel, 0, 0, 1, 1); grid.Attach (layerNameEntry, 1, 0, 1, 1); grid.Attach (visibilityCheckbox, 1, 1, 1, 1); diff --git a/Pinta/Dialogs/NewImageDialog.cs b/Pinta/Dialogs/NewImageDialog.cs index bd83c135aa..3ad693463c 100644 --- a/Pinta/Dialogs/NewImageDialog.cs +++ b/Pinta/Dialogs/NewImageDialog.cs @@ -160,11 +160,10 @@ public NewImageDialog ( backgroundVbox.MarginTop = 4; // Layout table for preset, width, and height - Gtk.Grid layoutGrid = new () { - RowSpacing = 5, - ColumnSpacing = 6, - MarginBottom = 3, - }; + Gtk.Grid layoutGrid = Gtk.Grid.New (); + layoutGrid.RowSpacing = 5; + layoutGrid.ColumnSpacing = 6; + layoutGrid.MarginBottom = 3; layoutGrid.Attach (sizeLabel, 0, 0, 1, 1); layoutGrid.Attach (presetDropdown, 1, 0, 1, 1); layoutGrid.Attach (widthLabel, 0, 1, 1, 1); @@ -275,17 +274,21 @@ private static Gtk.Label CreateUnitsLabel () } private static Gtk.Image CreateOrientationIcon (string iconName) - => new () { - IconName = iconName, - PixelSize = 16, - MarginEnd = 7, - }; + { + Gtk.Image image = Gtk.Image.New (); + image.IconName = iconName; + image.PixelSize = 16; + image.MarginEnd = 7; + return image; + } private static Gtk.Entry CreateLengthEntry () - => new () { - WidthRequest = 50, - ActivatesDefault = true, - }; + { + Gtk.Entry entry = Gtk.Entry.New (); + entry.WidthRequest = 50; + entry.ActivatesDefault = true; + return entry; + } private static Gtk.CheckButton CreatePortraitRadio () => Gtk.CheckButton.NewWithLabel (Translations.GetString ("Portrait")); diff --git a/Pinta/Dialogs/ProgressDialog.cs b/Pinta/Dialogs/ProgressDialog.cs index ae71a4eecf..861fa11f32 100644 --- a/Pinta/Dialogs/ProgressDialog.cs +++ b/Pinta/Dialogs/ProgressDialog.cs @@ -38,8 +38,8 @@ public sealed class ProgressDialog : Gtk.Dialog, IProgressDialog public ProgressDialog (ChromeManager chrome) { - Gtk.Label textLabel = new (); - Gtk.ProgressBar progressBar = new (); + Gtk.Label textLabel = Gtk.Label.New (""); + Gtk.ProgressBar progressBar = Gtk.ProgressBar.New (); // --- References to keep diff --git a/Pinta/Dialogs/ResizeCanvasDialog.cs b/Pinta/Dialogs/ResizeCanvasDialog.cs index 83fa2ca89c..d2e06ed6fc 100644 --- a/Pinta/Dialogs/ResizeCanvasDialog.cs +++ b/Pinta/Dialogs/ResizeCanvasDialog.cs @@ -86,19 +86,16 @@ public ResizeCanvasDialog (IChromeService chrome, IWorkspaceService workspace, I heightSpinner.OnValueChanged += heightSpinner_ValueChanged; heightSpinner.SetActivatesDefaultImmediate (true); - Gtk.Button resetButton = new () { - IconName = Resources.StandardIcons.EditUndo, - WidthRequest = 24, - HeightRequest = 24, - TooltipText = Translations.GetString ("Reset to image size"), - }; + Gtk.Button resetButton = Gtk.Button.NewFromIconName (Resources.StandardIcons.EditUndo); + resetButton.WidthRequest = 24; + resetButton.HeightRequest = 24; + resetButton.TooltipText = Translations.GetString ("Reset to image size"); resetButton.OnClicked += OnResetButtonClicked; - Gtk.Grid hwGrid = new () { - RowSpacing = SPACING, - ColumnSpacing = SPACING, - ColumnHomogeneous = false, - }; + Gtk.Grid hwGrid = Gtk.Grid.New (); + hwGrid.RowSpacing = SPACING; + hwGrid.ColumnSpacing = SPACING; + hwGrid.ColumnHomogeneous = false; hwGrid.Attach (widthLabel, 0, 0, 1, 1); hwGrid.Attach (widthSpinner, 1, 0, 1, 1); hwGrid.Attach (Gtk.Label.New (Translations.GetString ("pixels")), 2, 0, 1, 1); @@ -148,8 +145,7 @@ public ResizeCanvasDialog (IChromeService chrome, IWorkspaceService workspace, I Gtk.Label.New ("%") ]); - Gtk.Separator sep = new (); - sep.SetOrientation (Gtk.Orientation.Horizontal); + Gtk.Separator sep = Gtk.Separator.New (Gtk.Orientation.Horizontal); Gtk.Label alignLabel = Gtk.Label.New (Translations.GetString ("Anchor:")); alignLabel.Xalign = 0; @@ -181,12 +177,11 @@ public ResizeCanvasDialog (IChromeService chrome, IWorkspaceService workspace, I Gtk.Button seButton = CreateAnchorButton (); seButton.OnClicked += HandleSEButtonClicked; - Gtk.Grid grid = new () { - RowSpacing = SPACING, - ColumnSpacing = SPACING, - Halign = Gtk.Align.Center, - Valign = Gtk.Align.Center, - }; + Gtk.Grid grid = Gtk.Grid.New (); + grid.RowSpacing = SPACING; + grid.ColumnSpacing = SPACING; + grid.Halign = Gtk.Align.Center; + grid.Valign = Gtk.Align.Center; grid.Attach (nwButton, 0, 0, 1, 1); grid.Attach (nButton, 1, 0, 1, 1); grid.Attach (neButton, 2, 0, 1, 1); @@ -279,10 +274,12 @@ private void OnDialogResponse (Gtk.Dialog sender, ResponseSignalArgs args) } private static Gtk.Button CreateAnchorButton () - => new () { - WidthRequest = 30, - HeightRequest = 30, - }; + { + Gtk.Button button = Gtk.Button.New (); + button.WidthRequest = 30; + button.HeightRequest = 30; + return button; + } public ResizeCanvasOptions GetResizeCanvasOptions () { diff --git a/Pinta/Dialogs/ResizeImageDialog.cs b/Pinta/Dialogs/ResizeImageDialog.cs index 396d1eb8db..3ecac0f237 100644 --- a/Pinta/Dialogs/ResizeImageDialog.cs +++ b/Pinta/Dialogs/ResizeImageDialog.cs @@ -1,21 +1,21 @@ -// +// // ResizeImageDialog.cs -// +// // Author: // Jonathan Pobst -// +// // Copyright (c) 2010 Jonathan Pobst -// +// // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: -// +// // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. -// +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -71,12 +71,10 @@ internal ResizeImageDialog (IChromeService chrome, IWorkspaceService workspace, Gtk.CheckButton aspectCheckbox = Gtk.CheckButton.NewWithLabel (Translations.GetString ("Maintain aspect ratio")); aspectCheckbox.Active = settings.GetSetting (SettingNames.RESIZE_IMAGE_MAINTAIN_ASPECT, true); - Gtk.Button resetButton = new () { - IconName = Resources.StandardIcons.EditUndo, - WidthRequest = 24, - HeightRequest = 24, - TooltipText = Translations.GetString ("Reset to image size"), - }; + Gtk.Button resetButton = Gtk.Button.NewFromIconName (Resources.StandardIcons.EditUndo); + resetButton.WidthRequest = 24; + resetButton.HeightRequest = 24; + resetButton.TooltipText = Translations.GetString ("Reset to image size"); resetButton.OnClicked += OnResetButtonClicked; Gtk.CheckButton percentageRadio = Gtk.CheckButton.NewWithLabel (Translations.GetString ("By percentage:")); @@ -126,11 +124,10 @@ internal ResizeImageDialog (IChromeService chrome, IWorkspaceService workspace, Gtk.Label heightLabel = Gtk.Label.New (Translations.GetString ("Height:")); heightLabel.Halign = Gtk.Align.End; - Gtk.Grid grid = new () { - RowSpacing = SPACING, - ColumnSpacing = SPACING, - ColumnHomogeneous = false, - }; + Gtk.Grid grid = Gtk.Grid.New (); + grid.RowSpacing = SPACING; + grid.ColumnSpacing = SPACING; + grid.ColumnHomogeneous = false; grid.Attach (widthLabel, 0, 0, 1, 1); grid.Attach (widthSpinner, 1, 0, 1, 1); grid.Attach (Gtk.Label.New (Translations.GetString ("pixels")), 2, 0, 1, 1); @@ -211,10 +208,9 @@ private void OnDialogResponse (Gtk.Dialog sender, ResponseSignalArgs args) private static Gtk.ComboBoxText CreateResamplingCombobox () { - Gtk.ComboBoxText result = new () { - Hexpand = true, - Halign = Gtk.Align.Fill, - }; + Gtk.ComboBoxText result = Gtk.ComboBoxText.New (); + result.Hexpand = true; + result.Halign = Gtk.Align.Fill; foreach (ResamplingMode mode in Enum.GetValues (typeof (ResamplingMode))) result.AppendText (mode.GetLabel ()); diff --git a/Pinta/MainWindow.cs b/Pinta/MainWindow.cs index ff9f1624f2..bc14a71160 100644 --- a/Pinta/MainWindow.cs +++ b/Pinta/MainWindow.cs @@ -435,35 +435,36 @@ private void CreateMainToolBar () { if (window_shell.HeaderBar is not null) { var header_bar = window_shell.HeaderBar; - header_bar.PackEnd (new Gtk.MenuButton () { - MenuModel = this.menu_bar, - IconName = Resources.StandardIcons.OpenMenu, - TooltipText = Translations.GetString ("Main Menu"), - }); - header_bar.PackEnd (new Gtk.MenuButton () { - MenuModel = PintaCore.Chrome.EffectsMenu, - IconName = Resources.Icons.EffectsDefault, - TooltipText = Translations.GetString ("Effects"), - }); - - header_bar.PackEnd (new Gtk.MenuButton () { - MenuModel = PintaCore.Chrome.AdjustmentsMenu, - IconName = Resources.Icons.AdjustmentsBrightnessContrast, - TooltipText = Translations.GetString ("Adjustments"), - }); - - header_bar.PackEnd (new Gtk.MenuButton () { - MenuModel = this.image_menu, - IconName = Resources.StandardIcons.ImageGeneric, - TooltipText = Translations.GetString ("Image"), - }); - - header_bar.PackEnd (new Gtk.MenuButton () { - MenuModel = this.view_menu, - IconName = Resources.StandardIcons.ViewReveal, - TooltipText = Translations.GetString ("View"), - }); + Gtk.MenuButton mainMenuButton = Gtk.MenuButton.New (); + mainMenuButton.MenuModel = this.menu_bar; + mainMenuButton.IconName = Resources.StandardIcons.OpenMenu; + mainMenuButton.TooltipText = Translations.GetString ("Main Menu"); + header_bar.PackEnd (mainMenuButton); + + Gtk.MenuButton effectsMenuButton = Gtk.MenuButton.New (); + effectsMenuButton.MenuModel = PintaCore.Chrome.EffectsMenu; + effectsMenuButton.IconName = Resources.Icons.EffectsDefault; + effectsMenuButton.TooltipText = Translations.GetString ("Effects"); + header_bar.PackEnd (effectsMenuButton); + + Gtk.MenuButton adjustmentsMenuButton = Gtk.MenuButton.New (); + adjustmentsMenuButton.MenuModel = PintaCore.Chrome.AdjustmentsMenu; + adjustmentsMenuButton.IconName = Resources.Icons.AdjustmentsBrightnessContrast; + adjustmentsMenuButton.TooltipText = Translations.GetString ("Adjustments"); + header_bar.PackEnd (adjustmentsMenuButton); + + Gtk.MenuButton imageMenuButton = Gtk.MenuButton.New (); + imageMenuButton.MenuModel = this.image_menu; + imageMenuButton.IconName = Resources.StandardIcons.ImageGeneric; + imageMenuButton.TooltipText = Translations.GetString ("Image"); + header_bar.PackEnd (imageMenuButton); + + Gtk.MenuButton viewMenuButton = Gtk.MenuButton.New (); + viewMenuButton.MenuModel = this.view_menu; + viewMenuButton.IconName = Resources.StandardIcons.ViewReveal; + viewMenuButton.TooltipText = Translations.GetString ("View"); + header_bar.PackEnd (viewMenuButton); PintaCore.Actions.CreateHeaderToolBar (header_bar); } else { @@ -512,14 +513,13 @@ private void CreateDockAndPads (Gtk.Box container) PintaCore.Tools.ToolAdded += (_, e) => toolbox.AddItem (e.Tool); PintaCore.Tools.ToolRemoved += (_, e) => toolbox.RemoveItem (e.Tool); - Gtk.ScrolledWindow toolbox_scroll = new () { - Child = toolbox, - HscrollbarPolicy = Gtk.PolicyType.Never, - VscrollbarPolicy = Gtk.PolicyType.Never, - HasFrame = false, - OverlayScrolling = true, - WindowPlacement = Gtk.CornerType.BottomRight, - }; + Gtk.ScrolledWindow toolbox_scroll = Gtk.ScrolledWindow.New (); + toolbox_scroll.Child = toolbox; + toolbox_scroll.HscrollbarPolicy = Gtk.PolicyType.Never; + toolbox_scroll.VscrollbarPolicy = Gtk.PolicyType.Never; + toolbox_scroll.HasFrame = false; + toolbox_scroll.OverlayScrolling = true; + toolbox_scroll.WindowPlacement = Gtk.CornerType.BottomRight; container.Append (toolbox_scroll); PintaCore.Chrome.InitializeToolBox (toolbox); From 9f2ea6d5eaa6fdea5ccda8aba415134d48a5765b Mon Sep 17 00:00:00 2001 From: Cameron White Date: Thu, 2 Apr 2026 23:37:35 -0400 Subject: [PATCH 08/13] Port the offset selection dialog and new image preview to the new gir.core subclass initialization --- Pinta/Actions/Edit/OffsetSelectionAction.cs | 14 +++---- Pinta/Dialogs/NewImageDialog.cs | 15 ++++--- Pinta/Dialogs/OffsetSelectionDialog.cs | 45 ++++++++++++--------- 3 files changed, 41 insertions(+), 33 deletions(-) diff --git a/Pinta/Actions/Edit/OffsetSelectionAction.cs b/Pinta/Actions/Edit/OffsetSelectionAction.cs index b25edad452..4b409d115d 100755 --- a/Pinta/Actions/Edit/OffsetSelectionAction.cs +++ b/Pinta/Actions/Edit/OffsetSelectionAction.cs @@ -1,21 +1,21 @@ -// +// // OffsetSelectionAction.cs -// +// // Author: // Jonathan Pobst -// +// // Copyright (c) 2010 Jonathan Pobst -// +// // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: -// +// // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. -// +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -87,7 +87,7 @@ private async void Activated (object sender, EventArgs e) private async Task PromptOffsetSelection () { - using OffsetSelectionDialog dialog = new (chrome); + using OffsetSelectionDialog dialog = OffsetSelectionDialog.New (chrome); try { Gtk.ResponseType response = await dialog.RunAsync (); if (response != Gtk.ResponseType.Ok) return null; diff --git a/Pinta/Dialogs/NewImageDialog.cs b/Pinta/Dialogs/NewImageDialog.cs index 3ad693463c..df12267a7a 100644 --- a/Pinta/Dialogs/NewImageDialog.cs +++ b/Pinta/Dialogs/NewImageDialog.cs @@ -31,7 +31,7 @@ namespace Pinta; -public sealed class NewImageDialog : Gtk.Dialog +public sealed partial class NewImageDialog : Gtk.Dialog { private readonly bool has_clipboard; private bool suppress_events; @@ -188,7 +188,7 @@ public NewImageDialog ( Gtk.Label previewLabel = Gtk.Label.New (Translations.GetString ("Preview")); - PreviewArea previewBox = new (); + PreviewArea previewBox = PreviewArea.New (); Gtk.Box previewVbox = GtkExtensions.BoxVertical ([ previewLabel, @@ -561,9 +561,10 @@ private void UpdatePresetSelection () preset_dropdown.Selected = index; } - private sealed class PreviewArea : Gtk.Box + [GObject.Subclass] + internal sealed partial class PreviewArea { - private Gtk.Picture picture; + private Gtk.Picture picture = Gtk.Picture.New (); private Size size; private Cairo.Color color; @@ -572,7 +573,10 @@ private sealed class PreviewArea : Gtk.Box private static readonly Gdk.Texture transparent_pattern_texture = CairoExtensions.CreateTransparentBackgroundSurface (16).ToTexture (); - public PreviewArea () + public static PreviewArea New () + => NewWithProperties ([]); + + partial void Initialize () { WidthRequest = 300; Vexpand = true; @@ -582,7 +586,6 @@ public PreviewArea () // Center the paintable in an expanding box so that CSS can be used to draw // the drop shadow around only the canvas area. - picture = Gtk.Picture.New (); picture.Name = "new-image-preview"; picture.ContentFit = Gtk.ContentFit.ScaleDown; picture.Hexpand = true; diff --git a/Pinta/Dialogs/OffsetSelectionDialog.cs b/Pinta/Dialogs/OffsetSelectionDialog.cs index e2c6cf9d56..9ecf7f92fb 100755 --- a/Pinta/Dialogs/OffsetSelectionDialog.cs +++ b/Pinta/Dialogs/OffsetSelectionDialog.cs @@ -1,21 +1,21 @@ -// +// // OffsetSelectionDialog.cs -// +// // Author: // Jonathan Pobst -// +// // Copyright (c) 2010 Jonathan Pobst -// +// // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: -// +// // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. -// +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -29,20 +29,27 @@ namespace Pinta; -public sealed class OffsetSelectionDialog : Gtk.Dialog +[GObject.Subclass] +public sealed partial class OffsetSelectionDialog { - private readonly HScaleSpinButtonWidget offset_spinbox; + private readonly HScaleSpinButtonWidget offset_spinbox = new (initialValue: 0); public int Offset => offset_spinbox.ValueAsInt; - public OffsetSelectionDialog (IChromeService chrome) + public static OffsetSelectionDialog New (IChromeService chrome) + { + OffsetSelectionDialog dialog = NewWithProperties ([]); + dialog.TransientFor = chrome.MainWindow; + return dialog; + } + + partial void Initialize () { DefaultWidth = 400; DefaultHeight = 100; Title = Translations.GetString ("Offset Selection"); - TransientFor = chrome.MainWindow; Modal = true; Resizable = false; @@ -50,17 +57,15 @@ public OffsetSelectionDialog (IChromeService chrome) this.AddCancelOkButtons (); this.SetDefaultResponse (Gtk.ResponseType.Ok); - offset_spinbox = new HScaleSpinButtonWidget (0) { - Label = Translations.GetString ("Offset"), - MaximumValue = 100, - MinimumValue = -100, - }; + offset_spinbox.Label = Translations.GetString ("Offset"); + offset_spinbox.MinimumValue = -100; + offset_spinbox.MaximumValue = 100; - Gtk.Box content_area = this.GetContentAreaBox (); - content_area.WidthRequest = 400; - content_area.SetAllMargins (6); - content_area.Spacing = 6; - content_area.Append (offset_spinbox); + Gtk.Box contentArea = this.GetContentAreaBox (); + contentArea.WidthRequest = 400; + contentArea.SetAllMargins (6); + contentArea.Spacing = 6; + contentArea.Append (offset_spinbox); } } From 1a99237bdb11c1ec791aee259e09c2fba0151b1f Mon Sep 17 00:00:00 2001 From: Cameron White Date: Thu, 2 Apr 2026 23:41:30 -0400 Subject: [PATCH 09/13] Port the canvas grid dialog and angle picker to the new gir.core subclass initialization One subtle change is that the angle picker widget previously delayed setting the initial angle until the OnRealize event. This was problematic with the canvas grid changes, which set the initial angle after creating the widget but before it's realized, causing the updated value to be lost. Updating the value after all initialization is done works perfectly fine, though, so this was naturally fixed by porting the angle picker to the new initialization style. --- .../Dialogs/SimpleEffectDialog.cs | 3 +- .../Widgets/AnglePickerGraphic.cs | 8 ++- .../Widgets/AnglePickerWidget.cs | 37 ++++++++------ Pinta/Actions/View/EditCanvasGridAction.cs | 2 +- Pinta/Dialogs/CanvasGridSettingsDialog.cs | 51 ++++++++++++------- 5 files changed, 65 insertions(+), 36 deletions(-) diff --git a/Pinta.Gui.Widgets/Dialogs/SimpleEffectDialog.cs b/Pinta.Gui.Widgets/Dialogs/SimpleEffectDialog.cs index f99ef34f72..dbb9e85e9e 100644 --- a/Pinta.Gui.Widgets/Dialogs/SimpleEffectDialog.cs +++ b/Pinta.Gui.Widgets/Dialogs/SimpleEffectDialog.cs @@ -575,7 +575,8 @@ private AnglePickerWidget CreateAnglePicker ( ? d : default; - AnglePickerWidget widget = new (initialAngle) { Label = caption }; + AnglePickerWidget widget = AnglePickerWidget.NewWithAngle (initialAngle); + widget.Label = caption; widget.ValueChanged += (_, _) => { DelayedUpdate (() => { diff --git a/Pinta.Gui.Widgets/Widgets/AnglePickerGraphic.cs b/Pinta.Gui.Widgets/Widgets/AnglePickerGraphic.cs index 0b298c4fea..6bcfa8dc85 100644 --- a/Pinta.Gui.Widgets/Widgets/AnglePickerGraphic.cs +++ b/Pinta.Gui.Widgets/Widgets/AnglePickerGraphic.cs @@ -13,12 +13,16 @@ namespace Pinta.Gui.Widgets; -public sealed class AnglePickerGraphic : Gtk.DrawingArea +[GObject.Subclass] +public sealed partial class AnglePickerGraphic { private PointD drag_start; private DegreesAngle angle_value; - public AnglePickerGraphic () + public static new AnglePickerGraphic New () + => NewWithProperties ([]); + + partial void Initialize () { HeightRequest = WidthRequest = 50; diff --git a/Pinta.Gui.Widgets/Widgets/AnglePickerWidget.cs b/Pinta.Gui.Widgets/Widgets/AnglePickerWidget.cs index 61b7e1b11f..6f507bdb39 100644 --- a/Pinta.Gui.Widgets/Widgets/AnglePickerWidget.cs +++ b/Pinta.Gui.Widgets/Widgets/AnglePickerWidget.cs @@ -8,18 +8,31 @@ ///////////////////////////////////////////////////////////////////////////////// using System; +using System.Diagnostics.CodeAnalysis; using Pinta.Core; namespace Pinta.Gui.Widgets; -public sealed class AnglePickerWidget : Gtk.Box +[GObject.Subclass] +public sealed partial class AnglePickerWidget { - private readonly AnglePickerGraphic angle_picker_graphic; - private readonly Gtk.SpinButton numeric_spin; - private readonly Gtk.Label widget_label; - private readonly DegreesAngle initial_angle; + private AnglePickerGraphic angle_picker_graphic; + private Gtk.SpinButton numeric_spin; + private Gtk.Label widget_label; + private DegreesAngle initial_angle; - public AnglePickerWidget (DegreesAngle initialAngle) + public static AnglePickerWidget NewWithAngle (DegreesAngle initialAngle) + { + AnglePickerWidget widget = NewWithProperties ([]); + widget.initial_angle = initialAngle; + widget.Value = initialAngle; + return widget; + } + + [MemberNotNull (nameof (angle_picker_graphic))] + [MemberNotNull (nameof (numeric_spin))] + [MemberNotNull (nameof (widget_label))] + partial void Initialize () { const int SPACING = 6; @@ -29,10 +42,9 @@ public AnglePickerWidget (DegreesAngle initialAngle) Gtk.Box labelBox = Gtk.Box.New (Gtk.Orientation.Horizontal, SPACING); labelBox.Append (widgetLabel); - AnglePickerGraphic anglePickerGraphic = new () { - Hexpand = true, - Halign = Gtk.Align.Center, - }; + AnglePickerGraphic anglePickerGraphic = AnglePickerGraphic.New (); + anglePickerGraphic.Halign = Gtk.Align.Center; + anglePickerGraphic.Hexpand = true; anglePickerGraphic.ValueChanged += HandleAnglePickerValueChanged; Gtk.SpinButton numericSpin = Gtk.SpinButton.NewWithRange (-360, 360, 1); @@ -58,10 +70,6 @@ public AnglePickerWidget (DegreesAngle initialAngle) controlsBox.Append (numericSpin); controlsBox.Append (resetButton); - // --- Initialization (Gtk.Widget) - - OnRealize += (_, _) => anglePickerGraphic.Value = initialAngle; - // --- Initialization (Gtk.Box) SetOrientation (Gtk.Orientation.Vertical); @@ -71,7 +79,6 @@ public AnglePickerWidget (DegreesAngle initialAngle) // --- References to keep - initial_angle = initialAngle; widget_label = widgetLabel; angle_picker_graphic = anglePickerGraphic; numeric_spin = numericSpin; diff --git a/Pinta/Actions/View/EditCanvasGridAction.cs b/Pinta/Actions/View/EditCanvasGridAction.cs index 655c8f48e4..c45eeb8133 100644 --- a/Pinta/Actions/View/EditCanvasGridAction.cs +++ b/Pinta/Actions/View/EditCanvasGridAction.cs @@ -50,7 +50,7 @@ private async void Activated (object sender, EventArgs e) canvas_grid.AxonometricWidth, canvas_grid.AxonometricAngle); - using CanvasGridSettingsDialog dialog = new (chrome, initialSettings); + using CanvasGridSettingsDialog dialog = CanvasGridSettingsDialog.New (chrome, initialSettings); try { dialog.Updated += HandleDialogUpdate; diff --git a/Pinta/Dialogs/CanvasGridSettingsDialog.cs b/Pinta/Dialogs/CanvasGridSettingsDialog.cs index 200ced9769..448d548e49 100644 --- a/Pinta/Dialogs/CanvasGridSettingsDialog.cs +++ b/Pinta/Dialogs/CanvasGridSettingsDialog.cs @@ -1,36 +1,57 @@ using System; +using System.Diagnostics.CodeAnalysis; using Pinta.Core; using Pinta.Gui.Widgets; namespace Pinta; -public sealed class CanvasGridSettingsDialog : Gtk.Dialog +[GObject.Subclass] +public sealed partial class CanvasGridSettingsDialog { internal event EventHandler? Updated; - private readonly Gtk.CheckButton show_grid_checkbox; - private readonly Gtk.SpinButton grid_width_spinner; - private readonly Gtk.SpinButton grid_height_spinner; - private readonly Gtk.CheckButton show_axonometric_grid_checkbox; - private readonly Gtk.SpinButton grid_axonometric_width_spinner; - private readonly AnglePickerWidget grid_axonometric_angle_picker; + private Gtk.CheckButton show_grid_checkbox; + private Gtk.SpinButton grid_width_spinner; + private Gtk.SpinButton grid_height_spinner; + private Gtk.CheckButton show_axonometric_grid_checkbox; + private Gtk.SpinButton grid_axonometric_width_spinner; + private AnglePickerWidget grid_axonometric_angle_picker; private const int SPACING = 6; - internal CanvasGridSettingsDialog (ChromeManager chrome, Settings initialSettings) + internal static CanvasGridSettingsDialog New (ChromeManager chrome, Settings initialSettings) + { + // TODO - this seems to incorrectly load the settings + CanvasGridSettingsDialog dialog = NewWithProperties ([]); + dialog.show_grid_checkbox.Active = initialSettings.ShowGrid; + dialog.grid_width_spinner.Value = initialSettings.CellSize.Width; + dialog.grid_height_spinner.Value = initialSettings.CellSize.Height; + dialog.show_axonometric_grid_checkbox.Active = initialSettings.ShowAxonometricGrid; + dialog.grid_axonometric_angle_picker.Value = initialSettings.AxonometricAngle; + dialog.grid_axonometric_width_spinner.Value = initialSettings.AxonometricWidth; + + dialog.TransientFor = chrome.MainWindow; + + return dialog; + } + + [MemberNotNull (nameof (show_grid_checkbox))] + [MemberNotNull (nameof (grid_width_spinner))] + [MemberNotNull (nameof (grid_height_spinner))] + [MemberNotNull (nameof (show_axonometric_grid_checkbox))] + [MemberNotNull (nameof (grid_axonometric_width_spinner))] + [MemberNotNull (nameof (grid_axonometric_angle_picker))] + partial void Initialize () { Gtk.SpinButton widthSpinner = Gtk.SpinButton.NewWithRange (1, int.MaxValue, 1); - widthSpinner.Value = initialSettings.CellSize.Width; widthSpinner.OnValueChanged += SettingsChanged; widthSpinner.SetActivatesDefaultImmediate (true); Gtk.SpinButton heightSpinner = Gtk.SpinButton.NewWithRange (1, int.MaxValue, 1); - heightSpinner.Value = initialSettings.CellSize.Height; heightSpinner.OnValueChanged += SettingsChanged; heightSpinner.SetActivatesDefaultImmediate (true); Gtk.CheckButton showGridCheckBox = Gtk.CheckButton.NewWithLabel (Translations.GetString ("Show Grid")); - showGridCheckBox.Active = initialSettings.ShowGrid; showGridCheckBox.OnToggled += SettingsChanged; showGridCheckBox.BindProperty ( Gtk.CheckButton.ActivePropertyDefinition.UnmanagedName, @@ -44,17 +65,14 @@ internal CanvasGridSettingsDialog (ChromeManager chrome, Settings initialSetting GObject.BindingFlags.SyncCreate); Gtk.SpinButton axonometricWidthSpinner = Gtk.SpinButton.NewWithRange (1, int.MaxValue, 1); - axonometricWidthSpinner.Value = initialSettings.AxonometricWidth; axonometricWidthSpinner.OnValueChanged += SettingsChanged; axonometricWidthSpinner.SetActivatesDefaultImmediate (true); - AnglePickerWidget axonometricAnglePicker = new (initialSettings.AxonometricAngle) { - Label = Translations.GetString ("Angle"), - }; + AnglePickerWidget axonometricAnglePicker = AnglePickerWidget.NewWithAngle (new (0)); + axonometricAnglePicker.Label = Translations.GetString ("Angle"); axonometricAnglePicker.ValueChanged += SettingsChanged; Gtk.CheckButton showAxonometricGridCheckBox = Gtk.CheckButton.NewWithLabel (Translations.GetString ("Show Axonometric Grid")); - showAxonometricGridCheckBox.Active = initialSettings.ShowAxonometricGrid; showAxonometricGridCheckBox.OnToggled += SettingsChanged; showAxonometricGridCheckBox.BindProperty ( Gtk.CheckButton.ActivePropertyDefinition.UnmanagedName, @@ -102,7 +120,6 @@ internal CanvasGridSettingsDialog (ChromeManager chrome, Settings initialSetting // --- Initialization (Gtk.Window) Title = Translations.GetString ("Canvas Grid Settings"); - TransientFor = chrome.MainWindow; Modal = true; IconName = Resources.Icons.ViewGrid; From 9897267772f71709f130ba4bc7f13209f85ad78e Mon Sep 17 00:00:00 2001 From: Cameron White Date: Sat, 11 Apr 2026 14:31:33 -0400 Subject: [PATCH 10/13] Port the layers widget to the new subclass initialization style --- .../Widgets/Layers/LayersListView.cs | 20 ++++++++++++------ .../Layers/LayersListViewItemWidget.cs | 18 +++++++++++----- Pinta/Pads/LayersPad.cs | 21 +++++++++---------- 3 files changed, 37 insertions(+), 22 deletions(-) diff --git a/Pinta.Gui.Widgets/Widgets/Layers/LayersListView.cs b/Pinta.Gui.Widgets/Widgets/Layers/LayersListView.cs index addb898624..866b2322a4 100644 --- a/Pinta.Gui.Widgets/Widgets/Layers/LayersListView.cs +++ b/Pinta.Gui.Widgets/Widgets/Layers/LayersListView.cs @@ -26,20 +26,28 @@ // THE SOFTWARE. using System; +using System.Diagnostics.CodeAnalysis; using System.Linq; using Pinta.Core; namespace Pinta.Gui.Widgets; -public sealed class LayersListView : Gtk.ScrolledWindow +[GObject.Subclass] +public sealed partial class LayersListView { - private readonly Gio.ListStore list_model; - private readonly Gtk.SingleSelection selection_model; - private readonly Gtk.ListView list_view; + private Gio.ListStore list_model; + private Gtk.SingleSelection selection_model; + private Gtk.ListView list_view; private Document? active_document; private bool changing_selection = false; - public LayersListView () + public static new LayersListView New () + => NewWithProperties ([]); + + [MemberNotNull (nameof (list_model))] + [MemberNotNull (nameof (selection_model))] + [MemberNotNull (nameof (list_view))] + partial void Initialize () { // --- Control creaton @@ -82,7 +90,7 @@ private static void HandleFactorySetup ( Gtk.SignalListItemFactory.SetupSignalArgs args) { var item = (Gtk.ListItem) args.Object; - item.SetChild (new LayersListViewItemWidget ()); + item.SetChild (LayersListViewItemWidget.New ()); } private static void HandleFactoryBind ( diff --git a/Pinta.Gui.Widgets/Widgets/Layers/LayersListViewItemWidget.cs b/Pinta.Gui.Widgets/Widgets/Layers/LayersListViewItemWidget.cs index 86113b2aba..7ced3463b6 100644 --- a/Pinta.Gui.Widgets/Widgets/Layers/LayersListViewItemWidget.cs +++ b/Pinta.Gui.Widgets/Widgets/Layers/LayersListViewItemWidget.cs @@ -23,6 +23,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; using Cairo; using GObject; @@ -117,18 +118,25 @@ public void NotifyLayerModified () } } -public sealed class LayersListViewItemWidget : Gtk.Box +[GObject.Subclass] +public sealed partial class LayersListViewItemWidget { private static readonly Pattern transparent_pattern = CairoExtensions.CreateTransparentBackgroundPattern (8); private LayersListViewItem? item; private ImageSurface? thumbnail_surface; - private readonly Gtk.DrawingArea item_thumbnail; - private readonly Gtk.Label item_label; - private readonly Gtk.CheckButton visible_button; + private Gtk.DrawingArea item_thumbnail; + private Gtk.Label item_label; + private Gtk.CheckButton visible_button; - public LayersListViewItemWidget () + public static LayersListViewItemWidget New () + => NewWithProperties ([]); + + [MemberNotNull (nameof (item_thumbnail))] + [MemberNotNull (nameof (item_label))] + [MemberNotNull (nameof (visible_button))] + partial void Initialize () { Gtk.DrawingArea itemThumbnail = Gtk.DrawingArea.New (); itemThumbnail.SetDrawFunc ((area, context, width, height) => DrawThumbnail (context, width, height)); diff --git a/Pinta/Pads/LayersPad.cs b/Pinta/Pads/LayersPad.cs index ae573135fa..21c93e2338 100644 --- a/Pinta/Pads/LayersPad.cs +++ b/Pinta/Pads/LayersPad.cs @@ -1,21 +1,21 @@ -// +// // LayersPad.cs -// +// // Author: // Jonathan Pobst -// +// // Copyright (c) 2011 Jonathan Pobst -// +// // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: -// +// // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. -// +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -40,7 +40,7 @@ internal LayersPad (LayerActions layerActions) public void Initialize (Dock workspace) { - LayersListView layers = new (); + LayersListView layers = LayersListView.New (); DockItem layers_item = new ( child: layers, uniqueName: "Layers", @@ -63,10 +63,9 @@ public void Initialize (Dock workspace) hamburger_menu.AppendSection (null, flip_section); hamburger_menu.AppendSection (null, prop_section); - Gtk.MenuButton hamburger_button = new Gtk.MenuButton () { - MenuModel = hamburger_menu, - IconName = Resources.StandardIcons.OpenMenu - }; + Gtk.MenuButton hamburger_button = Gtk.MenuButton.New (); + hamburger_button.MenuModel = hamburger_menu; + hamburger_button.IconName = Resources.StandardIcons.OpenMenu; hamburger_button.Direction = Gtk.ArrowType.Up; From a27aa913c96b00960e284c6c71274a2919b9384c Mon Sep 17 00:00:00 2001 From: Cameron White Date: Sat, 11 Apr 2026 14:32:08 -0400 Subject: [PATCH 11/13] Port the history widget to the new subclass initialization style --- .../Widgets/History/HistoryItemWidget.cs | 15 +++++++------- .../Widgets/History/HistoryListView.cs | 20 +++++++++++++------ Pinta/Pads/HistoryPad.cs | 14 ++++++------- 3 files changed, 29 insertions(+), 20 deletions(-) diff --git a/Pinta.Gui.Widgets/Widgets/History/HistoryItemWidget.cs b/Pinta.Gui.Widgets/Widgets/History/HistoryItemWidget.cs index 38e1fb2372..81343c0052 100644 --- a/Pinta.Gui.Widgets/Widgets/History/HistoryItemWidget.cs +++ b/Pinta.Gui.Widgets/Widgets/History/HistoryItemWidget.cs @@ -51,12 +51,16 @@ public static HistoryListViewItem New (BaseHistoryItem item) public bool Active => item.State == HistoryItemState.Undo; } -public sealed class HistoryItemWidget : Gtk.Box +[GObject.Subclass] +public sealed partial class HistoryItemWidget { - private readonly Gtk.Image image; - private readonly Gtk.Label label; + private readonly Gtk.Image image = Gtk.Image.New (); + private readonly Gtk.Label label = Gtk.Label.New (string.Empty); - public HistoryItemWidget () + public static HistoryItemWidget New () + => NewWithProperties ([]); + + partial void Initialize () { Spacing = 6; @@ -64,9 +68,6 @@ public HistoryItemWidget () SetOrientation (Gtk.Orientation.Horizontal); - image = Gtk.Image.New (); - - label = Gtk.Label.New (string.Empty); label.Halign = Gtk.Align.Start; Append (image); diff --git a/Pinta.Gui.Widgets/Widgets/History/HistoryListView.cs b/Pinta.Gui.Widgets/Widgets/History/HistoryListView.cs index 87ea42161a..4928eee385 100644 --- a/Pinta.Gui.Widgets/Widgets/History/HistoryListView.cs +++ b/Pinta.Gui.Widgets/Widgets/History/HistoryListView.cs @@ -26,19 +26,27 @@ // THE SOFTWARE. using System; +using System.Diagnostics.CodeAnalysis; using Pinta.Core; namespace Pinta.Gui.Widgets; -public sealed class HistoryListView : Gtk.ScrolledWindow +[GObject.Subclass] +public sealed partial class HistoryListView { - private readonly Gio.ListStore model; - private readonly Gtk.SingleSelection selection_model; - private readonly Gtk.ListView list_view; + private Gio.ListStore model; + private Gtk.SingleSelection selection_model; + private Gtk.ListView list_view; private Document? active_document; - public HistoryListView () + public static new HistoryListView New () + => NewWithProperties ([]); + + [MemberNotNull (nameof (model))] + [MemberNotNull (nameof (selection_model))] + [MemberNotNull (nameof (list_view))] + partial void Initialize () { Gio.ListStore listModel = Gio.ListStore.New (HistoryListViewItem.GetGType ()); @@ -48,7 +56,7 @@ public HistoryListView () Gtk.SignalListItemFactory signalFactory = Gtk.SignalListItemFactory.New (); signalFactory.OnSetup += (factory, args) => { var item = (Gtk.ListItem) args.Object; - item.SetChild (new HistoryItemWidget ()); + item.SetChild (HistoryItemWidget.New ()); }; signalFactory.OnBind += (factory, args) => { var list_item = (Gtk.ListItem) args.Object; diff --git a/Pinta/Pads/HistoryPad.cs b/Pinta/Pads/HistoryPad.cs index 2f613382a8..8a3be99cfe 100644 --- a/Pinta/Pads/HistoryPad.cs +++ b/Pinta/Pads/HistoryPad.cs @@ -1,21 +1,21 @@ -// +// // HistoryPad.cs -// +// // Author: // Jonathan Pobst -// +// // Copyright (c) 2011 Jonathan Pobst -// +// // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: -// +// // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. -// +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -40,7 +40,7 @@ internal HistoryPad (EditActions edit) public void Initialize (Dock workspace) { - HistoryListView history = new (); + HistoryListView history = HistoryListView.New (); DockItem history_item = new ( child: history, From 3dce8bbc104b7900ca5d609f4117e2852eb2daaa Mon Sep 17 00:00:00 2001 From: Cameron White Date: Sat, 11 Apr 2026 14:33:30 -0400 Subject: [PATCH 12/13] Port the add-in progress bar to the new subclass initialization style --- Pinta.Gui.Addins/AddinManagerDialog.cs | 2 +- Pinta.Gui.Addins/InstallDialog.cs | 2 +- Pinta.Gui.Addins/StatusProgressBar.cs | 23 ++++++++++++++--------- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/Pinta.Gui.Addins/AddinManagerDialog.cs b/Pinta.Gui.Addins/AddinManagerDialog.cs index d467494835..279bc5537e 100644 --- a/Pinta.Gui.Addins/AddinManagerDialog.cs +++ b/Pinta.Gui.Addins/AddinManagerDialog.cs @@ -40,7 +40,7 @@ public AddinManagerDialog ( Adw.ViewStack viewStack = CreateViewStack (galleryList, installedList, updatesList); Adw.ToastOverlay toastOverlay = Adw.ToastOverlay.New (); - StatusProgressBar progressBar = new (viewStack, new ToastErrorReporter (toastOverlay)); + StatusProgressBar progressBar = StatusProgressBar.New (viewStack, new ToastErrorReporter (toastOverlay)); toastOverlay.Child = progressBar; Adw.ViewSwitcherTitle viewSwitcherTitle = Adw.ViewSwitcherTitle.New (); diff --git a/Pinta.Gui.Addins/InstallDialog.cs b/Pinta.Gui.Addins/InstallDialog.cs index 36db269695..b3becd08ca 100644 --- a/Pinta.Gui.Addins/InstallDialog.cs +++ b/Pinta.Gui.Addins/InstallDialog.cs @@ -113,7 +113,7 @@ public InstallDialog (Gtk.Window parent, SetupService service) InstallErrorReporter errorReporter = new (); - StatusProgressBar progressBar = new (scroll, errorReporter); + StatusProgressBar progressBar = StatusProgressBar.New (scroll, errorReporter); Gtk.Button cancelButton = Gtk.Button.NewWithLabel (Translations.GetString ("Cancel")); cancelButton.OnClicked += (_, _) => Close (); diff --git a/Pinta.Gui.Addins/StatusProgressBar.cs b/Pinta.Gui.Addins/StatusProgressBar.cs index e8413b1dbb..e2822ffc98 100644 --- a/Pinta.Gui.Addins/StatusProgressBar.cs +++ b/Pinta.Gui.Addins/StatusProgressBar.cs @@ -15,23 +15,28 @@ internal interface IErrorReporter /// Since the add-in queries may happen from a background thread, any UI updates are /// invoked on the UI thread. /// -internal sealed class StatusProgressBar : Adw.Bin, IProgressStatus +[GObject.Subclass] +internal sealed partial class StatusProgressBar : IProgressStatus { private readonly Gtk.Overlay progress_overlay = Gtk.Overlay.New (); - private readonly Gtk.ProgressBar progress_bar; - private readonly IErrorReporter error_reporter; + private readonly Gtk.ProgressBar progress_bar = Gtk.ProgressBar.New (); + private IErrorReporter? error_reporter; - public StatusProgressBar (Gtk.Widget primary_widget, IErrorReporter error_reporter) + public static StatusProgressBar New (Gtk.Widget primaryWidget, IErrorReporter errorReporter) { - this.error_reporter = error_reporter; + StatusProgressBar widget = NewWithProperties ([]); + widget.progress_overlay.Child = primaryWidget; + widget.error_reporter = errorReporter; + return widget; + } - progress_bar = Gtk.ProgressBar.New (); + partial void Initialize () + { progress_bar.Fraction = 0.5; progress_bar.ShowText = true; progress_bar.Valign = Gtk.Align.End; progress_bar.AddCssClass (Pinta.Core.AdwaitaStyles.Osd); - progress_overlay.Child = primary_widget; Child = progress_overlay; } @@ -61,9 +66,9 @@ public void Log (string msg) Console.WriteLine ("Info: {0}", msg); } - public void ReportError (string message, Exception exception) => error_reporter.ReportError (message, exception); + public void ReportError (string message, Exception exception) => error_reporter?.ReportError (message, exception); - public void ReportWarning (string message) => error_reporter.ReportWarning (message); + public void ReportWarning (string message) => error_reporter?.ReportWarning (message); public void SetMessage (string msg) { From 2f42f8f674b76c2fecf152cb782ccf092f830907 Mon Sep 17 00:00:00 2001 From: Cameron White Date: Sat, 11 Apr 2026 14:41:51 -0400 Subject: [PATCH 13/13] Port the Levels dialog widget to the new subclass initialization style --- Pinta.Effects/Dialogs/Effects.LevelsDialog.cs | 34 ++++++++++++------- .../Widgets/ColorGradientWidget.cs | 16 ++++++--- Pinta.Gui.Widgets/Widgets/ColorPanelWidget.cs | 31 ++++++++--------- Pinta.Gui.Widgets/Widgets/HistogramWidget.cs | 15 ++++---- 4 files changed, 55 insertions(+), 41 deletions(-) diff --git a/Pinta.Effects/Dialogs/Effects.LevelsDialog.cs b/Pinta.Effects/Dialogs/Effects.LevelsDialog.cs index 1ed82a80a8..271c3ae128 100644 --- a/Pinta.Effects/Dialogs/Effects.LevelsDialog.cs +++ b/Pinta.Effects/Dialogs/Effects.LevelsDialog.cs @@ -149,36 +149,44 @@ public LevelsDialog ( spinOutGamma.OnValueChanged += HandleSpinOutGammaValueChanged; spinOutGamma.SetActivatesDefaultImmediate (true); - ColorGradientWidget gradientInput = new (2) { WidthRequest = 40 }; + ColorGradientWidget gradientInput = ColorGradientWidget.New (2); + gradientInput.WidthRequest = 40; gradientInput.DragGesture.OnDragBegin += HandleGradientDragBegin; gradientInput.DragGesture.OnDragEnd += HandleGradientDragEnd; gradientInput.ValueChanged += HandleGradientInputValueChanged; - ColorGradientWidget gradientOutput = new (3) { WidthRequest = 40 }; + ColorGradientWidget gradientOutput = ColorGradientWidget.New (3); + gradientOutput.WidthRequest = 40; gradientOutput.DragGesture.OnDragBegin += HandleGradientDragBegin; gradientOutput.DragGesture.OnDragEnd += HandleGradientDragEnd; gradientOutput.ValueChanged += HandleGradientOutputValueChanged; - ColorPanelWidget colorPanelInHigh = new () { HeightRequest = 24 }; + ColorPanelWidget colorPanelInHigh = ColorPanelWidget.New (); + colorPanelInHigh.HeightRequest = 24; colorPanelInHigh.ClickGesture.OnPressed += HandleColorPanelButtonPressEvent; - ColorPanelWidget colorPanelInLow = new () { - HeightRequest = 24, - Valign = Gtk.Align.End, - Vexpand = true - }; + ColorPanelWidget colorPanelInLow = ColorPanelWidget.New (); + colorPanelInLow.HeightRequest = 24; + colorPanelInLow.Valign = Gtk.Align.End; + colorPanelInLow.Vexpand = true; colorPanelInLow.ClickGesture.OnPressed += HandleColorPanelButtonPressEvent; - ColorPanelWidget colorPanelOutLow = new () { HeightRequest = 24 }; + ColorPanelWidget colorPanelOutLow = ColorPanelWidget.New (); + colorPanelOutLow.HeightRequest = 24; colorPanelOutLow.ClickGesture.OnPressed += HandleColorPanelButtonPressEvent; - ColorPanelWidget colorPanelOutMid = new () { HeightRequest = 24 }; + ColorPanelWidget colorPanelOutMid = ColorPanelWidget.New (); + colorPanelOutMid.HeightRequest = 24; - ColorPanelWidget colorPanelOutHigh = new () { HeightRequest = 24 }; + ColorPanelWidget colorPanelOutHigh = ColorPanelWidget.New (); + colorPanelOutHigh.HeightRequest = 24; colorPanelOutHigh.ClickGesture.OnPressed += HandleColorPanelButtonPressEvent; - HistogramWidget histogramInput = new () { WidthRequest = 130, FlipHorizontal = true }; - HistogramWidget histogramOutput = new () { WidthRequest = 130 }; + HistogramWidget histogramInput = HistogramWidget.New (); + histogramInput.WidthRequest = 130; + histogramInput.FlipHorizontal = true; + HistogramWidget histogramOutput = HistogramWidget.New (); + histogramOutput.WidthRequest = 130; Gtk.Box vboxInput = GtkExtensions.Box ( verticalSpaced, diff --git a/Pinta.Gui.Widgets/Widgets/ColorGradientWidget.cs b/Pinta.Gui.Widgets/Widgets/ColorGradientWidget.cs index 624959a2a9..8fc5550939 100644 --- a/Pinta.Gui.Widgets/Widgets/ColorGradientWidget.cs +++ b/Pinta.Gui.Widgets/Widgets/ColorGradientWidget.cs @@ -33,7 +33,8 @@ namespace Pinta.Gui.Widgets; -public sealed class ColorGradientWidget : Gtk.DrawingArea +[GObject.Subclass] +public sealed partial class ColorGradientWidget { private const double X_pad = 0.15; // gradient horizontal padding private const double Y_pad = 0.03; // gradient vertical padding @@ -41,10 +42,16 @@ public sealed class ColorGradientWidget : Gtk.DrawingArea private double[] vals; private PointI last_mouse_pos = new (0, 0); - public ColorGradientWidget (int count) + public static ColorGradientWidget New (int count) + { + ColorGradientWidget widget = NewWithProperties ([]); + widget.Count = count; + return widget; + } + + partial void Initialize () { CanFocus = true; - Count = count; ValueIndex = -1; @@ -55,7 +62,6 @@ public ColorGradientWidget (int count) motionController.OnLeave += HandleLeaveNotifyEvent; AddController (motionController); - DragGesture = Gtk.GestureDrag.New (); DragGesture.SetButton (0); // Handle all buttons DragGesture.OnDragBegin += HandleDragBegin; DragGesture.OnDragUpdate += HandleDragUpdate; @@ -63,7 +69,7 @@ public ColorGradientWidget (int count) AddController (DragGesture); } - public Gtk.GestureDrag DragGesture { get; } + public Gtk.GestureDrag DragGesture { get; } = Gtk.GestureDrag.New (); private RectangleD GradientRectangle { get { diff --git a/Pinta.Gui.Widgets/Widgets/ColorPanelWidget.cs b/Pinta.Gui.Widgets/Widgets/ColorPanelWidget.cs index bf6bd9d9ce..81aa8b06ed 100644 --- a/Pinta.Gui.Widgets/Widgets/ColorPanelWidget.cs +++ b/Pinta.Gui.Widgets/Widgets/ColorPanelWidget.cs @@ -1,22 +1,22 @@ -// +// // ColorPanelWidget.cs -// +// // Author: // Krzysztof Marecki -// +// // Copyright (c) 2010 Krzysztof Marecki // -// +// // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: -// +// // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. -// +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -30,7 +30,8 @@ namespace Pinta.Gui.Widgets; -public sealed class ColorPanelWidget : Gtk.DrawingArea +[GObject.Subclass] +public sealed partial class ColorPanelWidget { private Color color; public Color CairoColor { @@ -41,26 +42,24 @@ public Color CairoColor { } } - public ColorPanelWidget () + public static new ColorPanelWidget New () + => NewWithProperties ([]); + + partial void Initialize () { - Gtk.GestureClick clickGesture = Gtk.GestureClick.New (); - clickGesture.SetButton (0); // Handle all buttons + ClickGesture.SetButton (0); // Handle all buttons // --- Initialization (Gtk.Widget) HeightRequest = 24; - AddController (clickGesture); + AddController (ClickGesture); // --- Initialization (Gtk.DrawingArea) SetDrawFunc ((_, context, _, _) => Draw (context)); - - // --- References to keep - - ClickGesture = clickGesture; } - public Gtk.GestureClick ClickGesture { get; } + public Gtk.GestureClick ClickGesture { get; } = Gtk.GestureClick.New (); private void Draw (Context cr) { diff --git a/Pinta.Gui.Widgets/Widgets/HistogramWidget.cs b/Pinta.Gui.Widgets/Widgets/HistogramWidget.cs index d422472e12..ec4128e708 100644 --- a/Pinta.Gui.Widgets/Widgets/HistogramWidget.cs +++ b/Pinta.Gui.Widgets/Widgets/HistogramWidget.cs @@ -39,15 +39,16 @@ namespace Pinta.Gui.Widgets; -public sealed class HistogramWidget : Gtk.DrawingArea +[GObject.Subclass] +public sealed partial class HistogramWidget { - private readonly bool[] selected; + private readonly bool[] selected = [true, true, true]; - public HistogramWidget () - { - Histogram = new HistogramRgb (); - selected = [true, true, true]; + public static new HistogramWidget New () + => NewWithProperties ([]); + partial void Initialize () + { SetDrawFunc ((_, context, _, _) => Draw (context)); } @@ -55,7 +56,7 @@ public HistogramWidget () public bool FlipVertical { get; set; } - public HistogramRgb Histogram { get; private set; } + public HistogramRgb Histogram { get; private set; } = new (); public void ResetHistogram () {