diff --git a/CHANGELOG.md b/CHANGELOG.md index c685d4d534..34c043b2c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ Thanks to the following contributors who worked on this release: ### Added - Ported to GTK4 and libadwaita - Due to API changes in GTK4, the File -> New Screenshot option now invokes platform-specific tools (the XDG screenshot portal on Linux, and the screenshot tool on maCOS). This is currently unsupported on Windows + - Added a preference (in the `View` menu) for switching between a dark or light color scheme. - Upgraded to .NET 8 - Building against .NET 7 is still supported. When building from the tarball, .NET 7 will be used if .NET 8 is unavailable. - Restored support for add-ins, which had been disabled in Pinta 2.0 due to technical limitations diff --git a/Pinta.Core/Actions/ViewActions.cs b/Pinta.Core/Actions/ViewActions.cs index cb0962b6df..ab701625e3 100644 --- a/Pinta.Core/Actions/ViewActions.cs +++ b/Pinta.Core/Actions/ViewActions.cs @@ -45,6 +45,7 @@ public sealed class ViewActions public ToggleCommand ToolBox { get; } public ToggleCommand Rulers { get; } public Gio.SimpleAction RulerMetric { get; } + public Gio.SimpleAction ColorScheme { get; } public Command Fullscreen { get; } public ToolBarComboBox ZoomComboBox { get; } @@ -75,6 +76,7 @@ public ViewActions () ToolBox = new ToggleCommand ("ToolBox", Translations.GetString ("Tool Box"), null, null); Rulers = new ToggleCommand ("Rulers", Translations.GetString ("Rulers"), null, Resources.Icons.ViewRulers); RulerMetric = Gio.SimpleAction.NewStateful ("rulermetric", GtkExtensions.IntVariantType, GLib.Variant.NewInt32 (0)); + ColorScheme = Gio.SimpleAction.NewStateful ("colorscheme", GtkExtensions.IntVariantType, GLib.Variant.NewInt32 (0)); Fullscreen = new Command ("Fullscreen", Translations.GetString ("Fullscreen"), null, Resources.StandardIcons.DocumentNew); ZoomCollection = default_zoom_levels; @@ -169,6 +171,17 @@ public void RegisterActions (Gtk.Application app, Gio.Menu menu) app.AddAction (ImageTabs); show_hide_menu.AppendItem (ImageTabs.CreateMenuItem ()); + + var color_scheme_section = Gio.Menu.New (); + menu.AppendSection (null, color_scheme_section); + + var color_scheme_menu = Gio.Menu.New (); + color_scheme_section.AppendSubmenu (Translations.GetString ("Color Scheme"), color_scheme_menu); + + app.AddAction (ColorScheme); + color_scheme_menu.Append (Translations.GetString ("Default"), $"app.{ColorScheme.Name}(0)"); + color_scheme_menu.Append (Translations.GetString ("Light"), $"app.{ColorScheme.Name}(1)"); + color_scheme_menu.Append (Translations.GetString ("Dark"), $"app.{ColorScheme.Name}(2)"); } public void CreateStatusBar (Box statusbar) diff --git a/Pinta/Actions/View/ColorSchemeChangedAction.cs b/Pinta/Actions/View/ColorSchemeChangedAction.cs new file mode 100644 index 0000000000..644582a433 --- /dev/null +++ b/Pinta/Actions/View/ColorSchemeChangedAction.cs @@ -0,0 +1,33 @@ +using Gio; +using Pinta.Core; + +namespace Pinta.Actions; + +internal sealed class ColorSchemeChangedAction : IActionHandler +{ + #region IActionHandler Members + public void Initialize () + { + PintaCore.Actions.View.ColorScheme.OnActivate += Activated; + } + + public void Uninitialize () + { + PintaCore.Actions.View.ColorScheme.OnActivate -= Activated; + } + #endregion + + private void Activated (SimpleAction action, SimpleAction.ActivateSignalArgs args) + { + action.ChangeState (args.Parameter!); + + Adw.ColorScheme scheme = args.Parameter!.GetInt32 () switch { + 1 => Adw.ColorScheme.ForceLight, + 2 => Adw.ColorScheme.ForceDark, + _ => Adw.ColorScheme.PreferDark, // Use dark unless the system prefers light + }; + + Adw.StyleManager.GetDefault ().SetColorScheme (scheme); + } +} + diff --git a/Pinta/DialogHandlers.cs b/Pinta/DialogHandlers.cs index 66f04450d3..f1f1933070 100644 --- a/Pinta/DialogHandlers.cs +++ b/Pinta/DialogHandlers.cs @@ -72,6 +72,7 @@ public ActionHandlers () new ImageTabsToggledAction (), new StatusBarToggledAction (), new ToolBoxToggledAction (), + new ColorSchemeChangedAction (), // Window new CloseAllDocumentsAction (), diff --git a/Pinta/Main.cs b/Pinta/Main.cs index 1911401843..9424f33d71 100644 --- a/Pinta/Main.cs +++ b/Pinta/Main.cs @@ -76,9 +76,6 @@ private static void OpenMainWindow (int threads, IEnumerable files) { GLib.UnhandledException.SetHandler (OnUnhandledException); - // For testing a dark variant of the theme. - //Gtk.Settings.Default.SetProperty("gtk-application-prefer-dark-theme", new GLib.Value(true)); - Gsk.Module.Initialize (); Pango.Module.Initialize (); PangoCairo.Module.Initialize (); diff --git a/Pinta/MainWindow.cs b/Pinta/MainWindow.cs index 6614dceed6..c880b03700 100644 --- a/Pinta/MainWindow.cs +++ b/Pinta/MainWindow.cs @@ -217,7 +217,7 @@ private bool HandleGlobalKeyPress (Gtk.EventControllerKey controller, Gtk.EventC var canvas_window = ((PintaCanvas) PintaCore.Workspace.ActiveWorkspace.Canvas).CanvasWindow; if ((canvas_window.Canvas.HasFocus || canvas_window.IsMouseOnCanvas) && - canvas_window.Canvas.DoKeyPressEvent (controller, args)) { + canvas_window.Canvas.DoKeyPressEvent (controller, args)) { return true; } } @@ -458,6 +458,9 @@ private void LoadUserSettings () var ruler_metric = (MetricType) PintaCore.Settings.GetSetting ("ruler-metric", (int) MetricType.Pixels); PintaCore.Actions.View.RulerMetric.Activate (GLib.Variant.NewInt32 ((int) ruler_metric)); + + int color_scheme = PintaCore.Settings.GetSetting ("color-scheme", 0); + PintaCore.Actions.View.ColorScheme.Activate (GLib.Variant.NewInt32 (color_scheme)); } private void SaveUserSettings () @@ -471,6 +474,7 @@ private void SaveUserSettings () } PintaCore.Settings.PutSetting ("ruler-metric", (int) GetCurrentRulerMetric ()); + PintaCore.Settings.PutSetting ("color-scheme", PintaCore.Actions.View.ColorScheme.GetState ()!.GetInt32 ()); PintaCore.Settings.PutSetting ("window-maximized", window_shell.Window.IsMaximized ()); PintaCore.Settings.PutSetting ("ruler-shown", PintaCore.Actions.View.Rulers.Value); PintaCore.Settings.PutSetting ("image-tabs-shown", PintaCore.Actions.View.ImageTabs.Value);