Skip to content

Commit 95560d9

Browse files
committed
Rework theme lookup
1 parent b4c4f73 commit 95560d9

24 files changed

Lines changed: 5715 additions & 3228 deletions

‎Telegram/Common/Theme.cs‎

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -348,20 +348,23 @@ Color GetShade(AccentShade shade)
348348

349349
foreach (var item in lookup)
350350
{
351-
if (item.Value is AccentShade or Color)
351+
var kind = item.Value.Kind;
352+
353+
if (kind is ThemeValueKind.Color or ThemeValueKind.Shade)
352354
{
353-
Color value = default;
354-
if (item.Value is AccentShade shade)
355+
Color value;
356+
if (kind == ThemeValueKind.Shade)
355357
{
356-
value = GetShade(shade);
358+
// A shade is the accent, so a theme's own value never overrides it.
359+
value = GetShade(item.Value.Shade);
357360
}
358361
else if (values != null && values.TryGetValue(item.Key, out Color themed))
359362
{
360363
value = themed;
361364
}
362-
else if (item.Value is Color color)
365+
else
363366
{
364-
value = color;
367+
value = item.Value.Color;
365368
}
366369

367370
if (themeParameters.ContainsKey(item.Key))
@@ -378,15 +381,19 @@ Color GetShade(AccentShade shade)
378381
double tintOpacity;
379382
double? tintLuminosityOpacity;
380383
Color fallbackColor;
381-
if (item.Value is Acrylic<Color> acrylicColor)
384+
if (kind == ThemeValueKind.AcrylicColor)
382385
{
386+
var acrylicColor = item.Value.AcrylicColor;
387+
383388
tintColor = acrylicColor.TintColor;
384389
tintOpacity = acrylicColor.TintOpacity;
385390
tintLuminosityOpacity = acrylicColor.TintLuminosityOpacity;
386391
fallbackColor = acrylicColor.FallbackColor;
387392
}
388-
else if (item.Value is Acrylic<AccentShade> acrylicShade)
393+
else if (kind == ThemeValueKind.AcrylicShade)
389394
{
395+
var acrylicShade = item.Value.AcrylicShade;
396+
390397
tintColor = GetShade(acrylicShade.TintColor);
391398
tintOpacity = acrylicShade.TintOpacity;
392399
tintLuminosityOpacity = acrylicShade.TintLuminosityOpacity;
@@ -460,7 +467,7 @@ Color GetShade(AccentShade shade)
460467
}
461468
}
462469

463-
private void PatchTextControlElevationBorderFocusedBrush(TelegramTheme requested, ResourceDictionary target, Dictionary<string, object> lookup, string key, bool create, Func<AccentShade, Color> getShade)
470+
private void PatchTextControlElevationBorderFocusedBrush(TelegramTheme requested, ResourceDictionary target, ThemeLookup lookup, string key, bool create, Func<AccentShade, Color> getShade)
464471
{
465472
// TextControlElevationBorderFocusedBrush is the only gradient that requires theming,
466473
// Hence we hardcode the logic to update this brush as it's not worth it to support this scenario.
@@ -489,7 +496,7 @@ private void PatchTextControlElevationBorderFocusedBrush(TelegramTheme requested
489496
};
490497
}
491498

492-
if (lookup.TryGet("ControlStrokeColorDefaultBrush", out Color stroke))
499+
if (lookup.TryGetColor("ControlStrokeColorDefaultBrush", out Color stroke))
493500
{
494501
brush.GradientStops[0].Color = getShade(requested == TelegramTheme.Light ? AccentShade.Dark1 : AccentShade.Light1);
495502
brush.GradientStops[1].Color = stroke;

‎Telegram/Common/VisualUtilities.Skeleton.cs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public static void SetSkeleton(FrameworkElement element, Vector2 size, params Ca
5858
var shimmer = Color.FromArgb(0x0F, 0xFF, 0xFF, 0xFF);
5959

6060
var lookup = ThemeService.GetLookup(element.ActualTheme);
61-
if (lookup.TryGet("MenuFlyoutItemBackgroundPointerOver", out Color color))
61+
if (lookup.TryGetColor("MenuFlyoutItemBackgroundPointerOver", out Color color))
6262
{
6363
shimmer = color;
6464
}

‎Telegram/Controls/Cells/ProfileCell.xaml.cs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1619,7 +1619,7 @@ private void ShowSkeleton()
16191619
var backgroundColor = Color.FromArgb(0x0F, 0xFF, 0xFF, 0xFF);
16201620

16211621
var lookup = ThemeService.GetLookup(ActualTheme);
1622-
if (lookup.TryGet("MenuFlyoutItemBackgroundPointerOver", out Color color))
1622+
if (lookup.TryGetColor("MenuFlyoutItemBackgroundPointerOver", out Color color))
16231623
{
16241624
foregroundColor = color;
16251625
backgroundColor = color;

‎Telegram/Controls/FormattedTextBlock.cs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2891,8 +2891,8 @@ public void ShowHideSkeleton(bool show)
28912891

28922892
// TODO: Improve colors
28932893
var lookup = ThemeService.GetLookup(ActualTheme);
2894-
lookup.TryGet("SystemControlDisabledChromeDisabledLowBrush", out backgroundColor);
2895-
lookup.TryGet("ApplicationPageBackgroundThemeBrush", out foregroundColor);
2894+
lookup.TryGetColor("SystemControlDisabledChromeDisabledLowBrush", out backgroundColor);
2895+
lookup.TryGetColor("ApplicationPageBackgroundThemeBrush", out foregroundColor);
28962896

28972897
var gradient = BootStrapper.Current.Compositor.CreateLinearGradientBrush();
28982898
gradient.ColorStops.Add(BootStrapper.Current.Compositor.CreateColorGradientStop(0, Color.FromArgb(0x00, backgroundColor.R, backgroundColor.G, backgroundColor.B)));

‎Telegram/Controls/Messages/MessageBubble.xaml.cs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3664,7 +3664,7 @@ void loaded(object o, EventArgs e)
36643664
var backgroundColor = Color.FromArgb(0x0F, 0xFF, 0xFF, 0xFF);
36653665

36663666
var lookup = ThemeService.GetLookup(ActualTheme);
3667-
if (lookup.TryGet("MenuFlyoutItemBackgroundPointerOver", out backgroundColor))
3667+
if (lookup.TryGetColor("MenuFlyoutItemBackgroundPointerOver", out backgroundColor))
36683668
{
36693669
}
36703670

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
//
2+
// Copyright (c) Fela Ameghino 2015-2026
3+
//
4+
// Distributed under the GNU General Public License v3.0. (See accompanying
5+
// file LICENSE or copy at https://www.gnu.org/licenses/gpl-3.0.txt)
6+
//
7+
8+
using System.Collections.Generic;
9+
using Telegram.Services.Settings;
10+
using Windows.UI;
11+
12+
namespace Telegram.Services
13+
{
14+
internal static partial class ThemeDefaults
15+
{
16+
// Telegram's own defaults. The framework material behind them is frozen and packed into
17+
// ThemeDefaults.g.cs; these stay written out because they are the ones that still change.
18+
// They lead both key tables, so the packed arrays leave their slots empty and this is the
19+
// only place the colours appear.
20+
private static readonly (string Key, ThemeValue Light, ThemeValue Dark)[] _custom =
21+
{
22+
("MessageReactionBackgroundOutgoing", Color.FromArgb(0xFF, 0xD5, 0xF1, 0xC9), Color.FromArgb(0xFF, 0x2B, 0x41, 0x53)),
23+
("MessageReactionForegroundOutgoing", Color.FromArgb(0xFF, 0x45, 0xA3, 0x2D), Color.FromArgb(0xFF, 0x7A, 0xC3, 0xF4)),
24+
("MessageReactionChosenBackgroundOutgoing", Color.FromArgb(0xFF, 0x5F, 0xBE, 0x67), Color.FromArgb(0xFF, 0x31, 0x8E, 0xE4)),
25+
("MessageReactionChosenForegroundOutgoing", Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF), Color.FromArgb(0xFF, 0x33, 0x39, 0x3F)),
26+
("MessageReactionBackgroundIncoming", Color.FromArgb(0xFF, 0xE8, 0xF5, 0xFC), Color.FromArgb(0xFF, 0x3A, 0x47, 0x54)),
27+
("MessageReactionForegroundIncoming", Color.FromArgb(0xFF, 0x16, 0x8D, 0xCD), Color.FromArgb(0xFF, 0x67, 0xBB, 0xF3)),
28+
("MessageReactionChosenBackgroundIncoming", Color.FromArgb(0xFF, 0x40, 0xA7, 0xE3), Color.FromArgb(0xFF, 0x6E, 0xB2, 0xEE)),
29+
("MessageReactionChosenForegroundIncoming", Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF), Color.FromArgb(0xFF, 0x33, 0x39, 0x3F)),
30+
("ApplicationPageBackgroundThemeBrush", Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF), Color.FromArgb(0xFF, 0x17, 0x17, 0x17)),
31+
("ChatPageBackgroundBrush", Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF), Color.FromArgb(0xFF, 0x17, 0x17, 0x17)),
32+
("ContentDialogBackground", Color.FromArgb(0xFF, 0xF3, 0xF3, 0xF3), Color.FromArgb(0xFF, 0x15, 0x15, 0x15)),
33+
("PageHeaderForegroundBrush", Color.FromArgb(0xFF, 0x00, 0x00, 0x00), Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF)),
34+
("PageHeaderHighlightBrush", AccentShade.Default, AccentShade.Default),
35+
("PageHeaderDisabledBrush", Color.FromArgb(0x99, 0x00, 0x00, 0x00), Color.FromArgb(0x99, 0xFF, 0xFF, 0xFF)),
36+
("PageTitleBackgroundBrush", Color.FromArgb(0xFF, 0xF2, 0xF2, 0xF2), Color.FromArgb(0xFF, 0x2B, 0x2B, 0x2B)),
37+
("PageHeaderBackgroundBrush", Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF), Color.FromArgb(0xFF, 0x17, 0x17, 0x17)),
38+
("PageHeaderBorderBrush", Color.FromArgb(0xFF, 0xF2, 0xF2, 0xF2), Color.FromArgb(0xFF, 0x1F, 0x1F, 0x1F)),
39+
("PageSubHeaderBackgroundBrush", Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF), Color.FromArgb(0xFF, 0x17, 0x17, 0x17)),
40+
("PageBackgroundDarkBrush", Color.FromArgb(0xFF, 0xF2, 0xF2, 0xF2), Color.FromArgb(0xFF, 0x1F, 0x1F, 0x1F)),
41+
("TelegramSeparatorMediumBrush", Color.FromArgb(0xFF, 0xF2, 0xF2, 0xF2), Color.FromArgb(0xFF, 0x1F, 0x1F, 0x1F)),
42+
("TelegramBackgroundAccentBrush", AccentShade.Default, AccentShade.Default),
43+
("TelegramForegroundAccentBrush", AccentShade.Default, AccentShade.Default),
44+
("PinnedMessageForegroundBrush", AccentShade.Default, AccentShade.Default),
45+
("PinnedMessageBorderBrush", Color.FromArgb(0xFF, 0xE6, 0xE6, 0xE6), Color.FromArgb(0xFF, 0x1F, 0x1F, 0x1F)),
46+
("TinyButtonBackgroundBrush", AccentShade.Default, AccentShade.Default),
47+
("ChatOnlineBadgeBrush", Color.FromArgb(0xFF, 0x00, 0xB1, 0x2C), Color.FromArgb(0xFF, 0x89, 0xDF, 0x9E)),
48+
("ChatVerifiedBadgeBrush", AccentShade.Default, AccentShade.Default),
49+
("ChatLastMessageStateBrush", AccentShade.Default, AccentShade.Default),
50+
("ChatFromLabelBrush", Color.FromArgb(0xFF, 0x3C, 0x7E, 0xB0), AccentShade.Default),
51+
("ChatDraftLabelBrush", Color.FromArgb(0xFF, 0xDD, 0x4B, 0x39), Color.FromArgb(0xFF, 0xDD, 0x4B, 0x39)),
52+
("ChatUnreadBadgeMutedBrush", Color.FromArgb(0xFF, 0xBB, 0xBB, 0xBB), Color.FromArgb(0xFF, 0x44, 0x44, 0x44)),
53+
("ChatUnreadLabelMutedBrush", Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF), Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF)),
54+
("ChatFailedBadgeBrush", Color.FromArgb(0xFF, 0xFF, 0x00, 0x00), Color.FromArgb(0xFF, 0xFF, 0x00, 0x00)),
55+
("ChatFailedLabelBrush", Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF), Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF)),
56+
("ChatUnreadBadgeBrush", AccentShade.Default, AccentShade.Default),
57+
("ChatUnreadLabelBrush", Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF), Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF)),
58+
("MessagePollCorrectBrush", Color.FromArgb(0xFF, 0x5D, 0xC4, 0x52), Color.FromArgb(0xFF, 0x5D, 0xC4, 0x52)),
59+
("MessagePollWrongBrush", Color.FromArgb(0xFF, 0xED, 0x50, 0x50), Color.FromArgb(0xFF, 0xED, 0x50, 0x50)),
60+
};
61+
62+
internal static readonly Dictionary<string, int> Slots;
63+
64+
internal static ThemeLookup Light => new(_lightValues, _lightOrder);
65+
66+
internal static ThemeLookup Dark => new(_darkValues, _darkOrder);
67+
68+
// A static constructor rather than a field initializer: initializer order across the two
69+
// halves of a partial class is the compiler's to pick, and this has to run after the
70+
// generated arrays exist.
71+
static ThemeDefaults()
72+
{
73+
Slots = new Dictionary<string, int>(Keys.Length);
74+
75+
for (int i = 0; i < Keys.Length; i++)
76+
{
77+
Slots[Keys[i]] = i;
78+
}
79+
80+
foreach (var (key, light, dark) in _custom)
81+
{
82+
var slot = Slots[key];
83+
84+
_lightValues[slot] = light.Packed;
85+
_darkValues[slot] = dark.Packed;
86+
}
87+
}
88+
}
89+
}

0 commit comments

Comments
 (0)