Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Actions/AdvancedShutdownAction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,8 @@ private void ShowOrUpdateFloatingWindow()
Topmost = true,
ShowInTaskbar = false,
SystemDecorations = SystemDecorations.None,
Background = Brushes.Transparent,
TransparencyLevelHint = [WindowTransparencyLevel.Transparent],
Content = new Border
{
CornerRadius = new CornerRadius(10),
Expand Down
15 changes: 15 additions & 0 deletions ConfigHandlers/MainConfigData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,21 @@ public bool AutoMatchMainBackgroundTheme
OnPropertyChanged();
}
}


bool _autoHideMainWindowWhenOccluded;

[JsonPropertyName("autoHideMainWindowWhenOccluded")]
public bool AutoHideMainWindowWhenOccluded
{
get => _autoHideMainWindowWhenOccluded;
set
{
if (value == _autoHideMainWindowWhenOccluded) return;
_autoHideMainWindowWhenOccluded = value;
OnPropertyChanged();
}
}

// ========== 公告相关 ==========
/*string _lastAcceptedAnnouncement = string.Empty;
Expand Down
32 changes: 32 additions & 0 deletions Controls/InTimePeriodRuleSettingsControl.axaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<UserControl x:Class="SystemTools.Controls.InTimePeriodRuleSettingsControl"
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanel Spacing="10">
<Grid ColumnDefinitions="Auto,*,Auto,*,Auto"
ColumnSpacing="8"
VerticalAlignment="Center">
<TextBlock Text="从" VerticalAlignment="Center" />

<TimePicker x:Name="StartTimePicker"
Grid.Column="1"
ClockIdentifier="24HourClock"
UseSeconds="True"
HorizontalAlignment="Center"
VerticalAlignment="Center" />

<TextBlock Grid.Column="2" Text="至" VerticalAlignment="Center" />

<TimePicker x:Name="EndTimePicker"
Grid.Column="3"
ClockIdentifier="24HourClock"
UseSeconds="True"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Grid>

<TextBlock Text="提示:若起始晚于结束 将按跨天处理"
TextWrapping="Wrap"
Foreground="Gray"
FontSize="12" />
</StackPanel>
</UserControl>
76 changes: 18 additions & 58 deletions Controls/InTimePeriodRuleSettingsControl.cs
Original file line number Diff line number Diff line change
@@ -1,91 +1,51 @@
using System;
using Avalonia.Controls;
using Avalonia.Layout;
using Avalonia.Markup.Xaml;
using ClassIsland.Core.Abstractions.Controls;
using System;
using SystemTools.Rules;

namespace SystemTools.Controls;


public class InTimePeriodRuleSettingsControl : RuleSettingsControlBase<InTimePeriodRuleSettings>
public partial class InTimePeriodRuleSettingsControl : RuleSettingsControlBase<InTimePeriodRuleSettings>
{
private readonly TimePicker _startTimePicker;
private readonly TimePicker _endTimePicker;

public InTimePeriodRuleSettingsControl()
{
var panel = new StackPanel { Spacing = 10 };
var row = new Grid
{
ColumnDefinitions = new ColumnDefinitions("Auto,*,Auto,*,Auto"),
ColumnSpacing = 8,
VerticalAlignment = VerticalAlignment.Center
};

row.Children.Add(new TextBlock { Text = "从", VerticalAlignment = VerticalAlignment.Center });

_startTimePicker = new TimePicker
{
ClockIdentifier = "24HourClock",
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center
};
Grid.SetColumn(_startTimePicker, 1);
row.Children.Add(_startTimePicker);

var sep = new TextBlock { Text = "至", VerticalAlignment = VerticalAlignment.Center };
Grid.SetColumn(sep, 2);
row.Children.Add(sep);
InitializeComponent();

_endTimePicker = new TimePicker
{
ClockIdentifier = "24HourClock",
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center
};
Grid.SetColumn(_endTimePicker, 3);
row.Children.Add(_endTimePicker);

var hint = new TextBlock
{
Text = "提示:若起始晚于结束 将按跨天处理",
TextWrapping = Avalonia.Media.TextWrapping.Wrap,
Foreground = Avalonia.Media.Brushes.Gray,
FontSize = 12
};
panel.Children.Add(row);
panel.Children.Add(hint);
Content = panel;
StartTimePicker.SelectedTimeChanged += (_, _) => SyncSettings();
EndTimePicker.SelectedTimeChanged += (_, _) => SyncSettings();
}

_startTimePicker.SelectedTimeChanged += (s, e) => SyncSettings();
_endTimePicker.SelectedTimeChanged += (s, e) => SyncSettings();
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}

protected override void OnInitialized()
{
base.OnInitialized();

if (TimeSpan.TryParse(Settings.StartTime, out var start))
{
_startTimePicker.SelectedTime = start;
StartTimePicker.SelectedTime = start;
}

if (TimeSpan.TryParse(Settings.EndTime, out var end))
{
_endTimePicker.SelectedTime = end;
EndTimePicker.SelectedTime = end;
}
}

private void SyncSettings()
{
if (_startTimePicker.SelectedTime.HasValue)
if (StartTimePicker.SelectedTime.HasValue)
{
Settings.StartTime = _startTimePicker.SelectedTime.Value.ToString(@"hh\:mm\:ss");
Settings.StartTime = StartTimePicker.SelectedTime.Value.ToString(@"hh\:mm\:ss");
}

if (_endTimePicker.SelectedTime.HasValue)
if (EndTimePicker.SelectedTime.HasValue)
{
Settings.EndTime = _endTimePicker.SelectedTime.Value.ToString(@"hh\:mm\:ss");
Settings.EndTime = EndTimePicker.SelectedTime.Value.ToString(@"hh\:mm\:ss");
}
}
}
67 changes: 41 additions & 26 deletions Services/AdaptiveThemeSyncService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Diagnostics;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using ClassIsland.Shared;
using SystemTools.Shared;

Expand Down Expand Up @@ -48,7 +49,7 @@ private void OnTick(object? sender, EventArgs e)

try
{
var targetTheme = DetectThemeByMainWindowBackground();
var targetTheme = DetectThemeByScreenBackground();
if (targetTheme == null || targetTheme == _lastAppliedTheme)
{
return;
Expand All @@ -62,52 +63,66 @@ private void OnTick(object? sender, EventArgs e)

themeService.SetTheme(targetTheme.Value, null);
_lastAppliedTheme = targetTheme;
_logger.LogDebug("已自动匹配主题为:{Theme}", targetTheme == 2 ? "黑暗" : "明亮");
_logger.LogDebug("已自动匹配主题为:{Theme}", targetTheme == 1 ? "黑暗" : "明亮");
}
catch (Exception ex)
{
_logger.LogDebug(ex, "自动匹配主界面背景色失败,将在下次计时重试。");
}
}

private static int? DetectThemeByMainWindowBackground()
private static int? DetectThemeByScreenBackground()
{
var handle = Process.GetCurrentProcess().MainWindowHandle;
if (handle == IntPtr.Zero)
if (handle == IntPtr.Zero || !GetWindowRect(handle, out var rect))
{
return null;
}

if (!GetWindowRect(handle, out var rect))
{
return null;
}

var width = Math.Max(1, rect.Right - rect.Left);
var height = Math.Max(1, rect.Bottom - rect.Top);
var mainWindow = Rectangle.FromLTRB(rect.Left, rect.Top, rect.Right, rect.Bottom);
var screen = Screen.FromRectangle(mainWindow);
var captureRect = BuildTargetArea(screen.Bounds, mainWindow);

using var bitmap = new Bitmap(width, height);
using var bitmap = new Bitmap(captureRect.Width, captureRect.Height);
using var graphics = Graphics.FromImage(bitmap);
graphics.CopyFromScreen(rect.Left, rect.Top, 0, 0, new Size(width, height));
graphics.CopyFromScreen(captureRect.Left, captureRect.Top, 0, 0, captureRect.Size);

var samples = new (int X, int Y)[]
double luminance = 0;
long samples = 0;
const int grid = 8;
var stepX = Math.Max(1, captureRect.Width / grid);
var stepY = Math.Max(1, captureRect.Height / grid);

for (var y = 0; y < captureRect.Height; y += stepY)
{
(width / 2, height / 2),
(Math.Max(0, width / 4), Math.Max(0, height / 4)),
(Math.Max(0, width * 3 / 4), Math.Max(0, height / 4)),
(Math.Max(0, width / 4), Math.Max(0, height * 3 / 4)),
(Math.Max(0, width * 3 / 4), Math.Max(0, height * 3 / 4)),
};
for (var x = 0; x < captureRect.Width; x += stepX)
{
var color = bitmap.GetPixel(Math.Clamp(x, 0, captureRect.Width - 1), Math.Clamp(y, 0, captureRect.Height - 1));
luminance += 0.299 * color.R + 0.587 * color.G + 0.114 * color.B;
samples++;
}
}

double luminance = 0;
foreach (var sample in samples)
if (samples == 0)
{
var color = bitmap.GetPixel(Math.Clamp(sample.X, 0, width - 1), Math.Clamp(sample.Y, 0, height - 1));
luminance += 0.299 * color.R + 0.587 * color.G + 0.114 * color.B;
return null;
}
luminance /= samples.Length;

return luminance < 128 ? 2 : 1; // 2=黑暗,1=明亮
luminance /= samples;

// 与 ClassIsland 的主题模式保持一致:0=明亮,1=黑暗。
return luminance < 128 ? 1 : 0;
}

private static Rectangle BuildTargetArea(Rectangle screenBounds, Rectangle mainWindow)
{
var topHeight = Math.Max(1, screenBounds.Height / 5);
var bottomY = screenBounds.Bottom - topHeight;

var isTop = mainWindow.Top + mainWindow.Height / 2 <= screenBounds.Top + screenBounds.Height / 2;
return isTop
? new Rectangle(screenBounds.Left, screenBounds.Top, screenBounds.Width, topHeight)
: new Rectangle(screenBounds.Left, bottomY, screenBounds.Width, topHeight);
}

[DllImport("user32.dll")]
Expand Down
3 changes: 2 additions & 1 deletion SettingsPage/MoreFeaturesOptionsSettingsPage.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@

<controls:SettingsExpander IconSource="{ci:FluentIconSource &#xE520;}"
Header="自动匹配主界面背景色到 ClassIsland 主题"
Description="每 2 秒检测主界面区域亮度,偏黑切换黑暗,偏白切换明亮。">
Description="每 2 秒检测屏幕顶部/底部五分之一亮度:偏黑切换黑暗,偏白切换明亮。">
<controls:SettingsExpander.Footer>
<ToggleSwitch IsChecked="{Binding Config.AutoMatchMainBackgroundTheme, Mode=TwoWay}"
Checked="AutoMatchThemeToggle_OnChanged"
Unchecked="AutoMatchThemeToggle_OnChanged" />
</controls:SettingsExpander.Footer>
</controls:SettingsExpander>

</StackPanel>
</ScrollViewer>
</ci:SettingsPageBase>
1 change: 1 addition & 0 deletions SettingsPage/MoreFeaturesOptionsSettingsPage.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,5 @@ private void AutoMatchThemeToggle_OnChanged(object? sender, RoutedEventArgs e)

GlobalConstants.MainConfig?.Save();
}

}
22 changes: 11 additions & 11 deletions SettingsPage/SystemToolsSettingsPage.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -167,17 +167,8 @@
</StackPanel>
</controls:SettingsExpander.Footer>
</controls:SettingsExpander>


<controls:SettingsExpander IconSource="{ci:FluentIconSource &#xEA37;}"
Header="启用悬浮窗功能"
Description="关闭后将禁用悬浮窗相关全部功能">
<controls:SettingsExpander.Footer>
<ToggleSwitch IsChecked="{Binding ViewModel.Settings.EnableFloatingWindowFeature, Mode=TwoWay}"
Click="OnFloatingFeatureToggleClick" />
</controls:SettingsExpander.Footer>
</controls:SettingsExpander>



<!--<controls:SettingsExpander IconSource="{ci:FluentIconSource &#xE28E;}"
Header="更多功能选项……"
Description="在这里启用相对小众的 / 正处于预览阶段的更多功能">
Expand All @@ -194,6 +185,15 @@
ActionIconSource="{ci:FluentIconSource &#xEC2E;}"
Click="OnOpenMoreFeaturesClick" />

<controls:SettingsExpander IconSource="{ci:FluentIconSource &#xEA37;}"
Header="启用悬浮窗功能"
Description="关闭后将禁用悬浮窗相关全部功能">
<controls:SettingsExpander.Footer>
<ToggleSwitch IsChecked="{Binding ViewModel.Settings.EnableFloatingWindowFeature, Mode=TwoWay}"
Click="OnFloatingFeatureToggleClick" />
</controls:SettingsExpander.Footer>
</controls:SettingsExpander>

<controls:SettingsExpander IconSource="{ci:FluentIconSource &#xE071;}"
Header="启用扩展功能"
Description="启用需要下载依赖的更多可选功能">
Expand Down
5 changes: 2 additions & 3 deletions Views/AdvancedShutdownDialog.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ci="http://classisland.tech/schemas/xaml/core"
Width="590"
Width="588"
Height="200"
WindowStartupLocation="CenterScreen"
Topmost="True"
Expand All @@ -24,8 +24,7 @@
<StackPanel Spacing="10">
<TextBlock x:Name="CountdownTextBlockElement"
FontSize="18"
FontWeight="SemiBold"
Foreground="{DynamicResource AccentFillColorDefaultBrush}"
FontWeight="DemiBold"
Text="将在2分00秒后关机……" />
<ProgressBar x:Name="CountdownProgressBarElement" Height="5" Minimum="0" Maximum="3000" Value="3000">
<ProgressBar.Styles>
Expand Down
2 changes: 1 addition & 1 deletion Views/ExtendShutdownDialog.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ci="http://classisland.tech/schemas/xaml/core"
Width="270"
Width="268"
Height="148"
CanResize="False"
WindowStartupLocation="CenterOwner"
Expand Down
Loading