98 lines
4.4 KiB
C#
98 lines
4.4 KiB
C#
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);
|
||
}
|