Skip to content

Commit d397d13

Browse files
committed
feat: App hosting
1 parent b695b77 commit d397d13

19 files changed

Lines changed: 603 additions & 384 deletions

Nickvision.Application.GNOME/Application.cs

Lines changed: 0 additions & 56 deletions
This file was deleted.

Nickvision.Application.GNOME/Nickvision.Application.GNOME.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
<ItemGroup>
1515
<PackageReference Include="GirCore.Adw-1" Version="0.7.0" />
16-
<PackageReference Include="Nickvision.Desktop.GNOME" Version="2026.2.1" />
16+
<PackageReference Include="Nickvision.Desktop.GNOME" Version="2026.2.4" />
1717
</ItemGroup>
1818
<ItemGroup>
1919
<ProjectReference Include="..\Nickvision.Application.Shared\Nickvision.Application.Shared.csproj" />
Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,22 @@
1-
namespace Nickvision.Application.GNOME;
1+
using Microsoft.Extensions.Hosting;
2+
using Nickvision.Application.GNOME.Views;
3+
using Nickvision.Application.Shared.Helpers;
4+
using Nickvision.Desktop.GNOME.Helpers;
5+
using System.Threading.Tasks;
6+
7+
namespace Nickvision.Application.GNOME;
28

39
public class Program
410
{
5-
public static int Main(string[] args) => new Application(args).Run();
11+
public static async Task Main(string[] args)
12+
{
13+
var newArgs = new string[args.Length + 1];
14+
newArgs[0] = "org.nickvision.application";
15+
args.CopyTo(newArgs, 1);
16+
var builder = Host.CreateApplicationBuilder();
17+
builder.ConfigureApplication(newArgs);
18+
builder.ConfigureAdw<MainWindow>();
19+
var host = builder.Build();
20+
await host.RunAsync();
21+
}
622
}

Nickvision.Application.GNOME/Views/MainWindow.cs

Lines changed: 52 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
1-
using Nickvision.Application.Shared.Controllers;
1+
using Microsoft.Extensions.DependencyInjection;
2+
using Microsoft.Extensions.Hosting;
3+
using Nickvision.Application.Shared.Controllers;
24
using Nickvision.Application.Shared.Events;
5+
using Nickvision.Application.Shared.Models;
6+
using Nickvision.Desktop.Application;
7+
using Nickvision.Desktop.Globalization;
38
using Nickvision.Desktop.GNOME.Controls;
49
using Nickvision.Desktop.GNOME.Helpers;
510
using Nickvision.Desktop.Notifications;
@@ -10,8 +15,10 @@ namespace Nickvision.Application.GNOME.Views;
1015

1116
public class MainWindow : Adw.ApplicationWindow
1217
{
18+
private readonly IServiceProvider _serviceProvider;
1319
private readonly MainWindowController _controller;
14-
private readonly Adw.Application _application;
20+
private readonly AppInfo _appInfo;
21+
private readonly ITranslationService _translationService;
1522
private readonly Gtk.Builder _builder;
1623

1724
[Gtk.Connect("windowTitle")]
@@ -29,25 +36,34 @@ public class MainWindow : Adw.ApplicationWindow
2936
[Gtk.Connect("pageFiles")]
3037
private Adw.StatusPage? _pageFiles;
3138

32-
public MainWindow(MainWindowController controller, Adw.Application application) : this(controller, application, Gtk.Builder.NewFromBlueprint("MainWindow", controller.Translator))
39+
public MainWindow(IServiceProvider serviceProvider, MainWindowController controller, AppInfo appInfo, ITranslationService translationService, IGtkBuilderFactory builderFactory) : this(serviceProvider, controller, appInfo, translationService, builderFactory.Create("MainWindow"))
3340
{
3441

3542
}
3643

37-
private MainWindow(MainWindowController controller, Adw.Application application, Gtk.Builder builder) : base(new Adw.Internal.ApplicationWindowHandle(builder.GetPointer("root"), false))
44+
private MainWindow(IServiceProvider serviceProvider, MainWindowController controller, AppInfo appInfo, ITranslationService translationService, Gtk.Builder builder) : base(new Adw.Internal.ApplicationWindowHandle(builder.GetPointer("root"), false))
3845
{
46+
var application = serviceProvider.GetRequiredService<Adw.Application>();
47+
_serviceProvider = serviceProvider;
3948
_controller = controller;
40-
_application = application;
49+
_appInfo = appInfo;
50+
_translationService = translationService;
4151
_builder = builder;
4252
_builder.Connect(this);
4353
// Window
44-
Title = _controller.AppInfo.ShortName;
45-
IconName = _controller.AppInfo.Id;
46-
if (_controller.AppInfo.Version!.IsPreview)
54+
Adw.StyleManager.GetDefault().ColorScheme = _controller.Theme switch
55+
{
56+
Theme.Light => Adw.ColorScheme.ForceLight,
57+
Theme.Dark => Adw.ColorScheme.ForceDark,
58+
_ => Adw.ColorScheme.Default
59+
};
60+
Title = _appInfo.ShortName;
61+
IconName = _appInfo.Id;
62+
if (_appInfo.Version!.IsPreview)
4763
{
4864
AddCssClass("devel");
4965
}
50-
_windowTitle!.Title = _controller.AppInfo.ShortName;
66+
_windowTitle!.Title = _appInfo.ShortName;
5167
_pageGreeting!.Title = _controller.Greeting;
5268
// Events
5369
OnCloseRequest += Window_OnCloseRequest;
@@ -65,32 +81,32 @@ private MainWindow(MainWindowController controller, Adw.Application application,
6581
var actQuit = Gio.SimpleAction.New("quit", null);
6682
actQuit.OnActivate += Quit;
6783
AddAction(actQuit);
68-
_application.SetAccelsForAction("win.quit", ["<Ctrl>q"]);
84+
application.SetAccelsForAction("win.quit", ["<Ctrl>q"]);
6985
// Open folder action
7086
var actOpenFolder = Gio.SimpleAction.New("openFolder", null);
7187
actOpenFolder.OnActivate += OpenFolder;
7288
AddAction(actOpenFolder);
73-
_application.SetAccelsForAction("win.openFolder", ["<Ctrl>o"]);
89+
application.SetAccelsForAction("win.openFolder", ["<Ctrl>o"]);
7490
// Close folder action
7591
var actCloseFolder = Gio.SimpleAction.New("closeFolder", null);
7692
actCloseFolder.OnActivate += CloseFolder;
7793
AddAction(actCloseFolder);
78-
_application.SetAccelsForAction("win.closeFolder", ["<Ctrl>w"]);
94+
application.SetAccelsForAction("win.closeFolder", ["<Ctrl>w"]);
7995
// Preferences action
8096
var actPreferences = Gio.SimpleAction.New("preferences", null);
8197
actPreferences.OnActivate += Preferences;
8298
AddAction(actPreferences);
83-
_application.SetAccelsForAction("win.preferences", ["<Ctrl>period"]);
99+
application.SetAccelsForAction("win.preferences", ["<Ctrl>period"]);
84100
// Keyboard shortcuts action
85101
var actKeyboardShortcuts = Gio.SimpleAction.New("keyboardShortcuts", null);
86102
actKeyboardShortcuts.OnActivate += KeyboardShortcuts;
87103
AddAction(actKeyboardShortcuts);
88-
_application.SetAccelsForAction("win.keyboardShortcuts", ["<Ctrl>question"]);
104+
application.SetAccelsForAction("win.keyboardShortcuts", ["<Ctrl>question"]);
89105
// About action
90106
var actAbout = Gio.SimpleAction.New("about", null);
91107
actAbout.OnActivate += About;
92108
AddAction(actAbout);
93-
_application.SetAccelsForAction("win.about", ["F1"]);
109+
application.SetAccelsForAction("win.about", ["F1"]);
94110
}
95111

96112
public new void Present()
@@ -107,8 +123,8 @@ private bool Window_OnCloseRequest(Gtk.Window sender, EventArgs args)
107123
}
108124
GetDefaultSize(out int width, out int height);
109125
_controller.WindowGeometry = this.WindowGeometry;
110-
_controller.Dispose();
111126
Destroy();
127+
_serviceProvider.GetRequiredService<IHostApplicationLifetime>().StopApplication();
112128
return false;
113129
}
114130

@@ -129,7 +145,7 @@ private void Controller_AppNotificationSent(object? sender, AppNotificationSentE
129145
var toast = Adw.Toast.New(args.Notification.Message);
130146
if (args.Notification.Action == "close")
131147
{
132-
toast.ButtonLabel = _controller.Translator._("Close");
148+
toast.ButtonLabel = _translationService._("Close");
133149
toast.OnButtonClicked += (_, _) => _controller.CloseFolder();
134150
}
135151
_toastOverlay!.AddToast(toast);
@@ -141,21 +157,15 @@ private void Controller_FolderChanged(object? sender, FolderChangedEventArgs arg
141157
_btnOpenFolder!.Visible = args.IsOpen;
142158
_btnCloseFolder!.Visible = args.IsOpen;
143159
_viewStack!.VisibleChildName = args.IsOpen ? "Folder" : "NoFolder";
144-
_pageFiles!.Description = _controller.Translator._n("There is {0} file in the folder.", "There are {0} files in the folder", args.Files.Count, args.Files.Count);
160+
_pageFiles!.Description = _translationService._n("There is {0} file in the folder.", "There are {0} files in the folder", args.Files.Count, args.Files.Count);
145161
}
146162

147-
private void Quit(Gio.SimpleAction sender, Gio.SimpleAction.ActivateSignalArgs args)
148-
{
149-
if (!Window_OnCloseRequest(this, new EventArgs()))
150-
{
151-
_application.Quit();
152-
}
153-
}
163+
private void Quit(Gio.SimpleAction sender, Gio.SimpleAction.ActivateSignalArgs args) => Window_OnCloseRequest(this, new EventArgs());
154164

155165
private async void OpenFolder(Gio.SimpleAction sender, Gio.SimpleAction.ActivateSignalArgs args)
156166
{
157167
var folderDialog = Gtk.FileDialog.New();
158-
folderDialog.Title = _controller.Translator._("Open Folder");
168+
folderDialog.Title = _translationService._("Open Folder");
159169
try
160170
{
161171
var file = await folderDialog.SelectFolderAsync(this);
@@ -171,45 +181,41 @@ private async void OpenFolder(Gio.SimpleAction sender, Gio.SimpleAction.Activate
171181

172182
private void Preferences(Gio.SimpleAction sender, Gio.SimpleAction.ActivateSignalArgs args)
173183
{
174-
var preferencesDialog = new PreferencesDialog(_controller.PreferencesViewController);
184+
var preferencesDialog = ActivatorUtilities.CreateInstance<PreferencesDialog>(_serviceProvider);
175185
preferencesDialog.Present(this);
176186
}
177187

178-
private void KeyboardShortcuts(Gio.SimpleAction sender, Gio.SimpleAction.ActivateSignalArgs args)
179-
{
180-
var shortcutsDialog = new ShortcutsDialog(_controller.Translator);
181-
shortcutsDialog.Present(this);
182-
}
188+
private void KeyboardShortcuts(Gio.SimpleAction sender, Gio.SimpleAction.ActivateSignalArgs args) => _serviceProvider.GetRequiredService<ShortcutsDialog>().Present(this);
183189

184190
private void About(Gio.SimpleAction sender, Gio.SimpleAction.ActivateSignalArgs args)
185191
{
186192
var extraInfo = string.Empty;
187193
extraInfo += $"GTK {Gtk.Functions.GetMajorVersion()}.{Gtk.Functions.GetMinorVersion()}.{Gtk.Functions.GetMicroVersion()}\n";
188194
extraInfo += $"libadwaita {Adw.Functions.GetMajorVersion()}.{Adw.Functions.GetMinorVersion()}.{Adw.Functions.GetMicroVersion()}";
189195
var dialog = Adw.AboutDialog.New();
190-
dialog.ApplicationName = _controller.AppInfo.ShortName;
191-
dialog.ApplicationIcon = _controller.AppInfo.Version!.IsPreview ? $"{_controller.AppInfo.Id}-devel" : _controller.AppInfo.Id;
196+
dialog.ApplicationName = _appInfo.ShortName;
197+
dialog.ApplicationIcon = _appInfo.Version!.IsPreview ? $"{_appInfo.Id}-devel" : _appInfo.Id;
192198
dialog.DeveloperName = "Nickvision";
193-
dialog.Version = _controller.AppInfo.Version.ToString();
194-
dialog.ReleaseNotes = _controller.AppInfo.HtmlChangelog;
199+
dialog.Version = _appInfo.Version.ToString();
200+
dialog.ReleaseNotes = _appInfo.HtmlChangelog;
195201
dialog.DebugInfo = _controller.GetDebugInformation(extraInfo);
196-
dialog.Comments = _controller.AppInfo.Description;
202+
dialog.Comments = _appInfo.Description;
197203
dialog.LicenseType = Gtk.License.MitX11;
198204
dialog.Copyright = "© Nickvision 2021-2026";
199205
dialog.Website = "https://nickvision.org";
200-
dialog.IssueUrl = _controller.AppInfo.IssueTracker!.ToString();
201-
dialog.SupportUrl = _controller.AppInfo.DiscussionsForum!.ToString();
202-
dialog.AddLink(_controller.Translator._("GitHub Repo"), _controller.AppInfo.SourceRepository!.ToString());
203-
foreach (var pair in _controller.AppInfo.ExtraLinks)
206+
dialog.IssueUrl = _appInfo.IssueTracker!.ToString();
207+
dialog.SupportUrl = _appInfo.DiscussionsForum!.ToString();
208+
dialog.AddLink(_translationService._("GitHub Repo"), _appInfo.SourceRepository!.ToString());
209+
foreach (var pair in _appInfo.ExtraLinks)
204210
{
205211
dialog.AddLink(pair.Key, pair.Value.ToString());
206212
}
207-
dialog.Developers = _controller.AppInfo.Developers.Select(x => $"{x.Key} {x.Value}").ToArray();
208-
dialog.Designers = _controller.AppInfo.Designers.Select(x => $"{x.Key} {x.Value}").ToArray();
209-
dialog.Artists = _controller.AppInfo.Artists.Select(x => $"{x.Key} {x.Value}").ToArray();
210-
if (!string.IsNullOrEmpty(_controller.AppInfo.TranslationCredits) && _controller.AppInfo.TranslationCredits != "translation-credits")
213+
dialog.Developers = _appInfo.Developers.Select(x => $"{x.Key} {x.Value}").ToArray();
214+
dialog.Designers = _appInfo.Designers.Select(x => $"{x.Key} {x.Value}").ToArray();
215+
dialog.Artists = _appInfo.Artists.Select(x => $"{x.Key} {x.Value}").ToArray();
216+
if (!string.IsNullOrEmpty(_appInfo.TranslationCredits) && _appInfo.TranslationCredits != "translation-credits")
211217
{
212-
dialog.TranslatorCredits = _controller.AppInfo.TranslationCredits;
218+
dialog.TranslatorCredits = _appInfo.TranslationCredits;
213219
}
214220
dialog.Present(this);
215221
}

Nickvision.Application.GNOME/Views/PreferencesDialog.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public class PreferencesDialog : Adw.PreferencesDialog
1515
[Gtk.Connect("languageRow")]
1616
private Adw.ComboRow? _languageRow;
1717

18-
public PreferencesDialog(PreferencesViewController controller) : this(controller, Gtk.Builder.NewFromBlueprint("PreferencesDialog", controller.Translator))
18+
public PreferencesDialog(PreferencesViewController controller, IGtkBuilderFactory builderFactory) : this(controller, builderFactory.Create("PreferencesDialog"))
1919
{
2020

2121
}

0 commit comments

Comments
 (0)