Skip to content

Commit

Permalink
Support switching between light and dark themes (#613)
Browse files Browse the repository at this point in the history
* Support switching between light and dark themes

This uses AdwStyleManager's facilities for specifying whether the light or dark variant of the system theme should be used. If the system doesn't indicate a preference, the default is to use dark.

* Save the color scheme preference to the settings.
  • Loading branch information
cameronwhite authored Dec 17, 2023
1 parent 8240fab commit 34c0787
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 4 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
13 changes: 13 additions & 0 deletions Pinta.Core/Actions/ViewActions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down
33 changes: 33 additions & 0 deletions Pinta/Actions/View/ColorSchemeChangedAction.cs
Original file line number Diff line number Diff line change
@@ -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);
}
}

1 change: 1 addition & 0 deletions Pinta/DialogHandlers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ public ActionHandlers ()
new ImageTabsToggledAction (),
new StatusBarToggledAction (),
new ToolBoxToggledAction (),
new ColorSchemeChangedAction (),

// Window
new CloseAllDocumentsAction (),
Expand Down
3 changes: 0 additions & 3 deletions Pinta/Main.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,6 @@ private static void OpenMainWindow (int threads, IEnumerable<string> 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 ();
Expand Down
6 changes: 5 additions & 1 deletion Pinta/MainWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Expand Down Expand Up @@ -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 ()
Expand All @@ -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);
Expand Down

0 comments on commit 34c0787

Please sign in to comment.