Files
DeskCore/PageScheduler.cs
T
2026-10-04 14:48:53 +00:00

98 lines
4.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
namespace DeskCore;
/// <summary>
/// Wechselt die Desktop-Seite nach Zeitplan (z. B. Mo–Fr 8–17 Uhr „Arbeit“, sonst „Freizeit“)
/// und setzt das Hintergrundbild einer Seite.
/// </summary>
public static class PageScheduler
{
/// <summary>Seite, die der Zeitplan zuletzt wollte. Gewechselt wird nur, wenn sich das ändert –
/// von Hand gewählte Seiten bleiben also bis zum nächsten Zeitplan-Wechsel stehen.</summary>
private static string? _lastWanted = "\0";
private static AppSettings S => AppSettings.Current;
/// <summary>Gibt es überhaupt einen Zeitplan?</summary>
public static bool Active => S.Pages.Count > 1 && S.Pages.Any(p => S.PageOptions.GetValueOrDefault(p)?.Scheduled == true);
/// <summary>Welche Seite laut Zeitplan jetzt dran ist (null = keine Vorgabe).</summary>
public static string? Wanted(DateTime now)
{
if (!Active) return null;
foreach (var p in S.Pages)
if (S.PageOptions.GetValueOrDefault(p)?.Matches(now) == true) return p;
return S.PageFallback is { } f && S.Pages.Contains(f, StringComparer.OrdinalIgnoreCase) ? f : null;
}
/// <summary>Regelmäßig aufrufen (alle paar Sekunden).</summary>
public static void Tick()
{
var wanted = Wanted(DateTime.Now);
if (string.Equals(wanted, _lastWanted, StringComparison.OrdinalIgnoreCase)) return;
_lastWanted = wanted;
if (wanted is null) return;
int index = S.Pages.FindIndex(p => string.Equals(p, wanted, StringComparison.OrdinalIgnoreCase));
if (index >= 0 && index != S.CurrentPage) FenceManager.SwitchPage(index);
}
/// <summary>Zeitplan geändert → beim nächsten Tick sofort anwenden.</summary>
public static void Reset() => _lastWanted = "\0";
/// <summary>Text für die Einstellungen, z. B. „Mo–Fr · 08:00–17:00“.</summary>
public static string Describe(PageOption o)
{
string[] names = ["Mo", "Di", "Mi", "Do", "Fr", "Sa", "So"];
var days = Enumerable.Range(0, 7).Where(i => (o.Days & (1 << i)) != 0).ToList();
string d = days.Count == 7 ? "Täglich"
: days.SequenceEqual([0, 1, 2, 3, 4]) ? "Mo–Fr"
: days.SequenceEqual([5, 6]) ? "Wochenende"
: days.Count > 2 && days.Last() - days.First() == days.Count - 1 ? $"{names[days.First()]}–{names[days.Last()]}"
: string.Join(", ", days.Select(i => names[i]));
return $"{d} · {o.From}–{o.To} Uhr";
}
// =====================================================================
// Hintergrundbild
// =====================================================================
/// <summary>Beim Seitenwechsel: Bild der Seite setzen – oder das ursprüngliche zurückholen.</summary>
public static void ApplyWallpaper(int pageIndex)
{
if (pageIndex < 0 || pageIndex >= S.Pages.Count) return;
var wanted = S.PageOptions.GetValueOrDefault(S.Pages[pageIndex])?.Wallpaper;
if (wanted is not null && !File.Exists(wanted)) wanted = null;
string? target;
if (wanted is not null)
{
// Vor dem ersten Wechsel das bisherige Bild merken, um es später zurückzuholen
S.SavedWallpaper ??= CurrentWallpaper() ?? "";
target = wanted;
}
else if (S.SavedWallpaper is { } saved)
{
target = saved;
S.SavedWallpaper = null;
}
else return; // Seiten ohne eigenes Bild lassen den Hintergrund in Ruhe
S.Save();
if (string.Equals(CurrentWallpaper(), target, StringComparison.OrdinalIgnoreCase)) return;
Task.Run(() => SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, target, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE));
}
public static string? CurrentWallpaper()
{
var sb = new StringBuilder(520);
return SystemParametersInfo(SPI_GETDESKWALLPAPER, (uint)sb.Capacity, sb, 0) ? sb.ToString() : null;
}
private const uint SPI_GETDESKWALLPAPER = 0x73, SPI_SETDESKWALLPAPER = 0x14, SPIF_UPDATEINIFILE = 0x1, SPIF_SENDCHANGE = 0x2;
[DllImport("user32.dll", CharSet = CharSet.Unicode)] private static extern bool SystemParametersInfo(uint action, uint param, string value, uint flags);
[DllImport("user32.dll", CharSet = CharSet.Unicode)] private static extern bool SystemParametersInfo(uint action, uint param, StringBuilder value, uint flags);
}