Skip to content

Commit

Permalink
V3.1 add cross platform support.
Browse files Browse the repository at this point in the history
  • Loading branch information
SylveonDeko committed Oct 30, 2024
1 parent fb1f815 commit bb77c6a
Show file tree
Hide file tree
Showing 11 changed files with 1,127 additions and 514 deletions.
50 changes: 41 additions & 9 deletions PresenceClient/PresenceClient-GUI/App.axaml
Original file line number Diff line number Diff line change
@@ -1,23 +1,55 @@
<Application xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="PresenceClient.App"
RequestedThemeVariant="Default">
RequestedThemeVariant="Dark">
<Application.Styles>
<FluentTheme />

<!-- Custom Styles -->
<Style Selector="Button.accent">
<Setter Property="Background" Value="#FF6200EE"/>
<Setter Property="Background" Value="{DynamicResource SystemAccentColor}"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="FontWeight" Value="SemiBold"/>
<Setter Property="CornerRadius" Value="4"/>
<Setter Property="Padding" Value="16 8"/>
</Style>
</Application.Styles>

<Application.Styles>
<FluentTheme />
<!-- Platform-specific styles -->
<Style Selector="Window">
<Style.Animations>
<Animation Duration="0:0:0.2" FillMode="Forward" Easing="CubicEaseOut">
<KeyFrame Cue="0%">
<Setter Property="Opacity" Value="0"/>
<Setter Property="ScaleTransform.ScaleX" Value="0.9"/>
<Setter Property="ScaleTransform.ScaleY" Value="0.9"/>
</KeyFrame>
<KeyFrame Cue="100%">
<Setter Property="Opacity" Value="1"/>
<Setter Property="ScaleTransform.ScaleX" Value="1"/>
<Setter Property="ScaleTransform.ScaleY" Value="1"/>
</KeyFrame>
</Animation>
</Style.Animations>
</Style>

<!-- macOS specific styles -->
<Style Selector="Window.macOS /template/ Border#PART_TransparencyFallback">
<Setter Property="Background" Value="#2D2D2D"/>
</Style>

<!-- Linux specific styles -->
<Style Selector="Window.linux TitleBar">
<Setter Property="Background" Value="#1E1E1E"/>
</Style>
</Application.Styles>

<Application.Resources>
<SolidColorBrush x:Key="PrimaryBackgroundColor">#FFFFFF</SolidColorBrush>
<SolidColorBrush x:Key="PrimaryForegroundColor">#000000</SolidColorBrush>
<SolidColorBrush x:Key="AccentColor">#0078D7</SolidColorBrush>
<Color x:Key="SystemAccentColor">#0078D4</Color>
<Color x:Key="SystemAccentColorDark1">#005A9E</Color>
<Color x:Key="SystemAccentColorDark2">#004275</Color>
<Color x:Key="SystemAccentColorDark3">#002642</Color>
<Color x:Key="SystemAccentColorLight1">#429CE3</Color>
<Color x:Key="SystemAccentColorLight2">#76B9ED</Color>
<Color x:Key="SystemAccentColorLight3">#A6D8F7</Color>
</Application.Resources>
</Application>
18 changes: 0 additions & 18 deletions PresenceClient/PresenceClient-GUI/Helpers/TaskExtensions.cs

This file was deleted.

143 changes: 100 additions & 43 deletions PresenceClient/PresenceClient-GUI/Helpers/TrayIconManager.cs
Original file line number Diff line number Diff line change
@@ -1,77 +1,134 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls;
using Avalonia.Platform;
using System;
using Avalonia.Media.Imaging;
using Avalonia.Threading;
using PresenceClient.ViewModels;

namespace PresenceClient.Helpers;

public class TrayIconManager : IDisposable
namespace PresenceClient.Helpers
{
private TrayIcon? trayIcon;
private readonly MainWindowViewModel _viewModel;
private NativeMenuItem connectMenuItem;

public TrayIconManager(MainWindowViewModel viewModel)
public class TrayIconManager : IDisposable
{
_viewModel = viewModel;
InitializeTrayIcon();
}
private readonly MainWindowViewModel viewModel;
private TrayIcon? trayIcon;
private NativeMenuItem? connectMenuItem;
private bool disposed;
private bool isEnabled;

private void InitializeTrayIcon()
{
Dispatcher.UIThread.Post(() =>
public TrayIconManager(MainWindowViewModel viewModel)
{
trayIcon = new TrayIcon();
this.viewModel = viewModel;
}

public void EnableTrayIcon(bool enable)
{
if (disposed || enable == isEnabled) return;

Dispatcher.UIThread.Post(() =>
{
if (enable)
{
InitializeTrayIcon();
}
else
{
DisposeTrayIcon();
}
isEnabled = enable;
});
}

private void InitializeTrayIcon()
{
if (trayIcon != null || disposed) return;

trayIcon = new TrayIcon();
var menu = new NativeMenu();

var showItem = new NativeMenuItem("Show");
showItem.Click += (sender, e) => _viewModel.ShowMainWindow();
showItem.Click += ShowItem_Click;
menu.Add(showItem);

connectMenuItem = new NativeMenuItem("Connect");
connectMenuItem.Click += (sender, e) => _viewModel.ToggleConnection();
connectMenuItem.Click += ConnectMenuItem_Click;
menu.Add(connectMenuItem);

var exitItem = new NativeMenuItem("Exit");
exitItem.Click += (sender, e) => _viewModel.ExitApplication();
exitItem.Click += ExitItem_Click;
menu.Add(exitItem);

trayIcon.Menu = menu;
trayIcon.Clicked += TrayIcon_Clicked;

UpdateIcon(false); // Start with disconnected icon
UpdateIcon(false);
trayIcon.IsVisible = true;
});
}
}

private void TrayIcon_Clicked(object? sender, EventArgs e)
{
_viewModel.ShowMainWindow();
}
private void ShowItem_Click(object? sender, EventArgs e)
{
viewModel.ShowMainWindow();
}

public void UpdateIcon(bool isConnected)
{
Dispatcher.UIThread.Post(() =>
private void ConnectMenuItem_Click(object? sender, EventArgs e)
{
viewModel.ToggleConnection();
}

private void ExitItem_Click(object? sender, EventArgs e)
{
viewModel.ExitApplication();
}

private void TrayIcon_Clicked(object? sender, EventArgs e)
{
viewModel.ShowMainWindow();
}

public void UpdateIcon(bool isConnected)
{
if (disposed) return;

Dispatcher.UIThread.Post(() =>
{
if (trayIcon == null || connectMenuItem == null) return;

var iconName = isConnected ? "Connected.ico" : "Disconnected.ico";
using var assets = AssetLoader.Open(new Uri($"avares://PresenceClient-GUI/Assets/{iconName}"));

trayIcon.Icon = new WindowIcon(assets);
trayIcon.ToolTipText = $"PresenceClient ({(isConnected ? "Connected" : "Disconnected")})";
connectMenuItem.Header = isConnected ? "Disconnect" : "Connect";
});
}

private void DisposeTrayIcon()
{
if (trayIcon == null) return;
var iconName = isConnected ? "Connected.ico" : "Disconnected.ico";
var assets = AssetLoader.Open(new Uri($"avares://PresenceClient-GUI/Assets/{iconName}"));

trayIcon.Icon = new WindowIcon(assets);
trayIcon.ToolTipText = $"PresenceClient ({(isConnected ? "Connected" : "Disconnected")})";
trayIcon.IsVisible = false;
trayIcon.Clicked -= TrayIcon_Clicked;

connectMenuItem.Header = isConnected ? "Disconnect" : "Connect";
});
}
if (trayIcon.Menu != null)
{
foreach (var item in trayIcon.Menu.Items)
{
if (item is not NativeMenuItem menuItem) continue;
menuItem.Click -= ShowItem_Click;
menuItem.Click -= ConnectMenuItem_Click;
menuItem.Click -= ExitItem_Click;
}
}

public void Dispose()
{
Dispatcher.UIThread.Post(() =>
trayIcon.Dispose();
trayIcon = null;
connectMenuItem = null;
}

public void Dispose()
{
trayIcon?.Dispose();
});
if (disposed) return;

Dispatcher.UIThread.Post(DisposeTrayIcon);
disposed = true;
}
}
}
Loading

0 comments on commit bb77c6a

Please sign in to comment.