feat: 公招结果支持彩色显示

fix #12458
This commit is contained in:
uye
2025-07-23 18:42:27 +08:00
parent f44eacdaa8
commit edccafec70
8 changed files with 216 additions and 52 deletions

View File

@@ -56,6 +56,36 @@ namespace MaaWpfGui.Constants
[UsedImplicitly]
public const string RobotOperator = "RobotOperatorLogBrush";
/// <summary>
/// The recommended color for 1-star operators (also used for robot operators).
/// </summary>
public const string Star1Operator = "Star1OperatorLogBrush";
/// <summary>
/// The recommended color for 2-star operators.
/// </summary>
public const string Star2Operator = "Star2OperatorLogBrush";
/// <summary>
/// The recommended color for 3-star operators.
/// </summary>
public const string Star3Operator = "Star3OperatorLogBrush";
/// <summary>
/// The recommended color for 4-star operators.
/// </summary>
public const string Star4Operator = "Star4OperatorLogBrush";
/// <summary>
/// The recommended color for 5-star operators.
/// </summary>
public const string Star5Operator = "Star5OperatorLogBrush";
/// <summary>
/// The recommended color for 6-star operators.
/// </summary>
public const string Star6Operator = "Star6OperatorLogBrush";
/// <summary>
/// The recommended color for file downloading or downloaded or download failed.
/// </summary>

View File

@@ -76,6 +76,38 @@ namespace MaaWpfGui.Helper
return tb.CreateTooltip(placementMode);
}
public static ToolTip CreateTooltip(this IEnumerable<Inline> inlines, PlacementMode? placementMode = null, int maxWidth = 750)
{
var tb = new TextBlock
{
TextWrapping = TextWrapping.Wrap,
Margin = new(4),
MaxWidth = maxWidth,
};
foreach (var inline in inlines)
{
tb.Inlines.Add(CloneInline(inline));
}
return tb.CreateTooltip(placementMode);
Inline CloneInline(Inline inline)
{
return inline switch
{
Run run => new Run(run.Text)
{
Foreground = run.Foreground,
FontWeight = run.FontWeight,
FontStyle = run.FontStyle,
},
LineBreak => new LineBreak(),
_ => new Run(),
};
}
}
#region Tooltip
/// <summary>

View File

@@ -1593,7 +1593,7 @@ namespace MaaWpfGui.Main
case "RecruitResult":
{
int level = (int)subTaskDetails!["level"]!;
var tooltip = $"{Instances.RecognizerViewModel.RecruitInfo}\n\n{Instances.RecognizerViewModel.RecruitResult}".CreateTooltip(PlacementMode.Center);
var tooltip = Instances.RecognizerViewModel.RecruitResultInlines.CreateTooltip(PlacementMode.Center);
if (level >= 5)
{
using (var toast = new ToastNotification(string.Format(LocalizationHelper.GetString("RecruitmentOfStar"), level)))

View File

@@ -85,6 +85,12 @@
<SolidColorBrush x:Key="MessageLogBrush" Color="#E6E6E6" />
<SolidColorBrush x:Key="RareOperatorLogBrush" Color="Orange" />
<SolidColorBrush x:Key="RobotOperatorLogBrush" Color="Gray" />
<SolidColorBrush x:Key="Star1OperatorLogBrush" Color="#E6E6E6" />
<SolidColorBrush x:Key="Star2OperatorLogBrush" Color="#88BB44" />
<SolidColorBrush x:Key="Star3OperatorLogBrush" Color="#66CCFF" />
<SolidColorBrush x:Key="Star4OperatorLogBrush" Color="#BB88FF" />
<SolidColorBrush x:Key="Star5OperatorLogBrush" Color="#FFBB55" />
<SolidColorBrush x:Key="Star6OperatorLogBrush" Color="Orange" />
<SolidColorBrush x:Key="DownloadLogBrush" Color="Violet" />
<SolidColorBrush x:Key="MuMuSpecialScreenshot" Color="#02BFFF" />

View File

@@ -65,6 +65,12 @@
<SolidColorBrush x:Key="MessageLogBrush" Color="Black" />
<SolidColorBrush x:Key="RareOperatorLogBrush" Color="DarkOrange" />
<SolidColorBrush x:Key="RobotOperatorLogBrush" Color="DarkGray" />
<SolidColorBrush x:Key="Star1OperatorLogBrush" Color="Black" />
<SolidColorBrush x:Key="Star2OperatorLogBrush" Color="#99CC33" />
<SolidColorBrush x:Key="Star3OperatorLogBrush" Color="#3399FF" />
<SolidColorBrush x:Key="Star4OperatorLogBrush" Color="#9966FF" />
<SolidColorBrush x:Key="Star5OperatorLogBrush" Color="#FFAA33" />
<SolidColorBrush x:Key="Star6OperatorLogBrush" Color="DarkOrange" />
<SolidColorBrush x:Key="DownloadLogBrush" Color="BlueViolet" />
<SolidColorBrush x:Key="MuMuSpecialScreenshot" Color="#02BFFF" />

View File

@@ -11,7 +11,9 @@
// but WITHOUT ANY WARRANTY
// </copyright>
using System.Collections.Generic;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Media;
using MaaWpfGui.Helper;
@@ -69,5 +71,37 @@ namespace MaaWpfGui.Styles.Controls
SetValue(ForegroundProperty, brush);
}
}
public static readonly DependencyProperty BindableInlinesProperty =
DependencyProperty.RegisterAttached(
"BindableInlines",
typeof(IEnumerable<Inline>),
typeof(TextBlock),
new PropertyMetadata(null, OnBindableInlinesChanged));
public static void SetBindableInlines(DependencyObject element, IEnumerable<Inline> value)
=> element.SetValue(BindableInlinesProperty, value);
public static IEnumerable<Inline> GetBindableInlines(DependencyObject element)
=> (IEnumerable<Inline>)element.GetValue(BindableInlinesProperty);
private static void OnBindableInlinesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is not TextBlock tb)
{
return;
}
tb.Inlines.Clear();
if (e.NewValue is not IEnumerable<Inline> inlines)
{
return;
}
foreach (var inline in inlines)
{
tb.Inlines.Add(inline);
}
}
}
}

View File

@@ -20,6 +20,8 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Threading;
using HandyControl.Controls;
@@ -99,15 +101,100 @@ namespace MaaWpfGui.ViewModels.UI
set => SetAndNotify(ref _recruitInfo, value);
}
private string _recruitResult = string.Empty;
private ObservableCollection<Inline> _recruitResultInlines = [];
/// <summary>
/// Gets or sets the recruit result.
/// </summary>
public string RecruitResult
public ObservableCollection<Inline> RecruitResultInlines
{
get => _recruitResult;
set => SetAndNotify(ref _recruitResult, value);
get => _recruitResultInlines;
set => SetAndNotify(ref _recruitResultInlines, value);
}
public void UpdateRecruitResult(JArray? resultArray)
{
ObservableCollection<Inline> recruitResultInlines = [];
foreach (var combs in resultArray ?? [])
{
int tagLevel = (int)(combs["level"] ?? -1);
recruitResultInlines.Add(new Run($"{tagLevel}★ Tags: "));
foreach (var tag in (JArray?)combs["tags"] ?? [])
{
recruitResultInlines.Add(new Run($"{tag} "));
}
recruitResultInlines.Add(new LineBreak());
foreach (var oper in (JArray?)combs["opers"] ?? [])
{
int operLevel = (int)(oper["level"] ?? -1);
var operId = oper["id"]?.ToString();
var operName = DataHelper.GetLocalizedCharacterName(oper["name"]?.ToString());
bool isMaxPot = false;
string potentialText = string.Empty;
if (RecruitmentShowPotential && OperBoxPotential != null && operId != null && (tagLevel >= 4 || operLevel == 1))
{
if (OperBoxPotential.TryGetValue(operId, out var pot))
{
potentialText = $" ( {pot} )";
if (pot == 6)
{
isMaxPot = true;
potentialText = " ( MAX )";
}
}
else
{
potentialText = " ( !!! NEW !!! )";
}
}
var run = new Run($"{operName}{potentialText} ");
var foreground = GetColorByStarWithOpacity(operLevel, isMaxPot ? 0.4 : 1.0);
if (foreground != null)
{
run.Foreground = foreground;
}
recruitResultInlines.Add(run);
}
recruitResultInlines.Add(new LineBreak());
recruitResultInlines.Add(new LineBreak());
}
RecruitResultInlines = recruitResultInlines;
return;
SolidColorBrush GetBrushWithOpacity(Color baseColor, double opacity)
{
byte alpha = (byte)(opacity * 255);
return new(Color.FromArgb(alpha, baseColor.R, baseColor.G, baseColor.B));
}
Brush? GetColorByStarWithOpacity(int level, double opacity = 1.0)
{
var brushKey = level switch
{
>= 6 => UiLogColor.Star6Operator,
5 => UiLogColor.Star5Operator,
4 => UiLogColor.Star4Operator,
3 => UiLogColor.Star3Operator,
2 => UiLogColor.Star2Operator,
_ => UiLogColor.Star1Operator,
};
var brush = Application.Current.TryFindResource(brushKey) as SolidColorBrush;
if (brush == null)
{
return null;
}
var baseColor = brush.Color;
return GetBrushWithOpacity(baseColor, opacity);
}
}
private bool _chooseLevel3 = Convert.ToBoolean(ConfigurationHelper.GetValue(ConfigurationKeys.ChooseLevel3, bool.FalseString));
@@ -205,7 +292,6 @@ namespace MaaWpfGui.ViewModels.UI
}
RecruitInfo = LocalizationHelper.GetString("Identifying");
RecruitResult = string.Empty;
var levelList = new List<int>();
@@ -277,44 +363,8 @@ namespace MaaWpfGui.ViewModels.UI
case "RecruitResult":
{
string resultContent = string.Empty;
JArray? resultArray = (JArray?)subTaskDetails?["result"];
/* int level = (int)subTaskDetails["level"]; */
foreach (var combs in resultArray ?? [])
{
int tagLevel = (int)(combs["level"] ?? -1);
resultContent += tagLevel + "★ Tags: ";
resultContent = (((JArray?)combs["tags"]) ?? []).Aggregate(resultContent, (current, tag) => current + (tag + " "));
resultContent += "\n\t";
foreach (var oper in (JArray?)combs["opers"] ?? [])
{
int operLevel = (int)(oper["level"] ?? -1);
var operId = oper["id"]?.ToString();
var operName = DataHelper.GetLocalizedCharacterName(oper["name"]?.ToString());
string potential = string.Empty;
if (RecruitmentShowPotential && OperBoxPotential != null && operId != null
&& (tagLevel >= 4 || operLevel == 1))
{
if (OperBoxPotential.ContainsKey(operId))
{
potential = " ( " + OperBoxPotential[operId] + " )";
}
else
{
potential = " ( !!! NEW !!! )";
}
}
resultContent += operLevel + "★ " + operName + potential + " ";
}
resultContent += "\n\n";
}
RecruitResult = resultContent;
UpdateRecruitResult(resultArray);
}
break;

View File

@@ -41,15 +41,21 @@
VerticalAlignment="Top"
Focusable="True"
FontSize="14"
ForceCursor="False"
Style="{StaticResource TextBlockDefaultBold}"
Text="{Binding RecruitInfo}"
TextWrapping="Wrap" />
<controls:TextBlock
Margin="10"
HorizontalAlignment="Left"
FontSize="14"
Text="{Binding RecruitResult}"
TextWrapping="Wrap" />
<Border
Padding="10"
Background="{DynamicResource RegionBrushOpacity50}"
CornerRadius="4"
Visibility="{c:Binding 'RecruitResultInlines.Count > 0'}">
<controls:TextBlock
HorizontalAlignment="Left"
BindableInlines="{Binding RecruitResultInlines}"
FontSize="14"
TextWrapping="Wrap" />
</Border>
</StackPanel>
</hc:ScrollViewer>
<StackPanel