Skip to content

Commit

Permalink
Add special letter for disconnected and low power last known state
Browse files Browse the repository at this point in the history
  • Loading branch information
nikvoronin committed Feb 6, 2025
1 parent 68d4b36 commit 2df22dd
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 32 deletions.
25 changes: 14 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,10 @@ __System requirements:__ Windows 10 x64, [.NET Desktop Runtime 8.0](https://dotn
- __3__ yellow - 30%
- __2__ orange - 20%
- __!__ red - 10%
- __X__ - headphones disconnected, transparent background. A tooltip displays the last known battery level and the last known date/time of the headphone connection.
- __X__ - headphones disconnected.
- __%__ - headphones disconnected, the last known battery level was low (30% or lower).

When headphones are disconnected, a tooltip displays the last known battery level and the last known date/time of the headphone connection.

`Right Mouse Button` opens a context menu:

Expand All @@ -68,34 +71,34 @@ The real icon size is 256x256 pixels. It is automatically scaled by system depen

>The app icon is currently adjusted to 125% display scale. Other scale factors may lead to uglifying tray icon.
Icon text color and background are defined in the `CreateIconForLevel` method:
Icon text color and background are defined in the `CreateXmIcon` method:

```csharp
// icon background color
var iconBackgroundBrush =
level switch {
uiBatteryLevel switch {
<= DisconnectedLevel => Brushes.Transparent,
<= 10 => Brushes.Red,
<= 20 => Brushes.Orange,
<= 30 => Brushes.Yellow,
<= CriticalPowerLevel => Brushes.Red,
<= LowPowerLevel => Brushes.Orange,
<= WarningPowerLevel => Brushes.Yellow,
_ => Brushes.White // 40..100(F)
};

// icon text color
var iconTextBrush =
level switch {
uiBatteryLevel switch {
<= DisconnectedLevel => Brushes.WhiteSmoke,
//<= 10 => Brushes.Magenta,
//<= 20 => Brushes.Cyan,
//<= LowPowerLevel => Brushes.Magenta,
//<= WarningLevel => Brushes.Cyan,
_ => Brushes.Black
};
```

Font of the notification icon text (battery level or headphones status):

```csharp
static readonly Font _notifyIconFont
= new ( "Segoe UI", 124, FontStyle.Regular );
static readonly Font _notifyIconFont =
new( "Segoe UI", 124, FontStyle.Regular );
```

## Xm4Poller
Expand Down
52 changes: 31 additions & 21 deletions Xm4Battery/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,11 @@ static int Main()
new NotifyIcon {
Text = NotifyIcon_BatteryLevelTitle,
Visible = true,
Icon = CreateIconForLevel( DisconnectedLevel ),
Icon = CreateXmIcon(
new() {
BatteryLevel = DisconnectedLevel,
Connected = false
} ),
ContextMenuStrip = CreateContextMenu()
};

Expand Down Expand Up @@ -113,7 +117,7 @@ private static ContextMenuStrip CreateContextMenu()
static readonly Font _notifyIconFont =
new( "Segoe UI", 124, FontStyle.Regular );

private static Icon CreateIconForLevel( int level )
private static Icon CreateXmIcon( Xm4State state )
{
const int iw = NotifyIconDefault_WidthPx;
const int ih = NotifyIconDefault_HeightPx;
Expand All @@ -124,22 +128,26 @@ private static Icon CreateIconForLevel( int level )
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SystemDefault;

var uiBatteryLevel =
state.Connected ? state.BatteryLevel
: DisconnectedLevel;

// icon background color
var iconBackgroundBrush =
level switch {
uiBatteryLevel switch {
<= DisconnectedLevel => Brushes.Transparent,
<= 10 => Brushes.Red,
<= 20 => Brushes.Orange,
<= 30 => Brushes.Yellow,
<= CriticalPowerLevel => Brushes.Red,
<= LowPowerLevel => Brushes.Orange,
<= WarningPowerLevel => Brushes.Yellow,
_ => Brushes.White // 40..100(F)
};

// icon text color
var iconTextBrush =
level switch {
uiBatteryLevel switch {
<= DisconnectedLevel => Brushes.WhiteSmoke,
//<= 10 => Brushes.Magenta,
//<= 20 => Brushes.Cyan,
//<= LowPowerLevel => Brushes.Magenta,
//<= WarningLevel => Brushes.Cyan,
_ => Brushes.Black
};

Expand All @@ -153,11 +161,11 @@ private static Icon CreateIconForLevel( int level )

// icon text: battery level or status
var iconText =
level switch {
<= DisconnectedLevel => "X",
<= 10 => "!",
100 => "F", // Full charged
_ => level.ToString()[..^1], // One digit of charge level 1..9
uiBatteryLevel switch {
<= DisconnectedLevel => state.BatteryLevel <= WarningPowerLevel ? "%" : "X",
<= CriticalPowerLevel => "!",
FullPowerLevel => "F",
_ => $"{state.BatteryLevel / 10}", // One digit of charge level 1..9
};

var sizeS =
Expand Down Expand Up @@ -192,18 +200,16 @@ private static void UpdateUi(

if (items[ConnectCtxMenuItemName] is not null
and var connectCtxMenuItem)
connectCtxMenuItem.Enabled = !currentState.Connected;
connectCtxMenuItem.Enabled = !currentState.Connected;

if (items[DisconnectCtxMenuItemName] is not null
and var disconnectCtxMenuItemName)
disconnectCtxMenuItemName.Enabled = currentState.Connected;
disconnectCtxMenuItemName.Enabled = currentState.Connected;

var prevIcon = notifyIconCtrl.Icon;

notifyIconCtrl.Icon =
CreateIconForLevel(
currentState.Connected ? currentState.BatteryLevel
: DisconnectedLevel );
CreateXmIcon( currentState );

if (prevIcon is not null)
DestroyIcon( prevIcon.Handle );
Expand All @@ -230,10 +236,14 @@ private static void LogException( Exception exception ) =>
const int NotifyIconDefault_HeightPx = 256;

const int DisconnectedLevel = 0;
const int CriticalPowerLevel = 10;
const int LowPowerLevel = 20;
const int WarningPowerLevel = 30;
const int FullPowerLevel = 100;
const string NotifyIcon_BatteryLevelTitle = "XM4 Battery Level";

const string AppName = "Xm4Battery";
const string AppVersion = "4.9.5";
const string AppVersion = "5.2.6";
const string GithubProjectUrl = "https://github.com/nikvoronin/Xm4Battery";

internal enum ErrorLevel
Expand All @@ -244,4 +254,4 @@ internal enum ErrorLevel

[DllImport( "user32.dll", CharSet = CharSet.Unicode )]
static extern bool DestroyIcon( IntPtr handle );
}
}

0 comments on commit 2df22dd

Please sign in to comment.