// // Part of the MaaWpfGui project, maintained by the MaaAssistantArknights team (Maa Team) // Copyright (C) 2021-2025 MaaAssistantArknights Contributors // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License v3.0 only as published by // the Free Software Foundation, either version 3 of the License, or // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY // #nullable enable using System; using System.Collections.Generic; using System.Linq; using System.Windows; using System.Windows.Controls; using System.Windows.Controls.Primitives; using System.Windows.Documents; using System.Windows.Media; using MaaWpfGui.Constants; using MaaWpfGui.Helper; using MaaWpfGui.Utilities; using MaaWpfGui.ViewModels.UI; using Stylet; namespace MaaWpfGui.ViewModels { /// /// The view model of log item. /// public class LogItemViewModel : PropertyChangedBase { /// /// Initializes a new instance of the class. /// /// The content. /// The font color. /// The font weight. /// The Date format string /// The showtime bool. /// The toolTip public LogItemViewModel(string content, string color = UiLogColor.Message, string weight = "Regular", string dateFormat = "", bool showTime = true, ToolTip? toolTip = null) { if (string.IsNullOrEmpty(dateFormat)) { dateFormat = SettingsViewModel.GuiSettings.LogItemDateFormatString; } _time = DateTime.Now.ToString(dateFormat); _content = content; _color = color; _weight = weight; _showTime = showTime; _toolTip = toolTip; } private string _time; /// /// Gets or sets the time. /// public string Time { get => _time; set => SetAndNotify(ref _time, value); } private bool _showTime; public bool ShowTime { get => _showTime; set => SetAndNotify(ref _showTime, value); } private string _content; /// /// Gets or sets the content. /// public string Content { get => _content; set => SetAndNotify(ref _content, value); } private string _color; /// /// Gets or sets the font color. /// public string Color { get => _color; set => SetAndNotify(ref _color, value); } private string _weight; /// /// Gets or sets the font weight. /// public string Weight { get => _weight; set => SetAndNotify(ref _weight, value); } [PropertyDependsOn(nameof(ToolTip))] public bool ShowToolTip => _toolTip is { Content: not null }; private ToolTip? _toolTip; /// /// Gets or sets the toolTip. /// public ToolTip? ToolTip { get => _toolTip; set => SetAndNotify(ref _toolTip, value); } #region 创建日志 Tooltip 的辅助方法 private static ToolTip CreateTooltip(object content) { var baseStyle = Application.Current.TryFindResource(typeof(ToolTip)) as Style; var borderFactory = new FrameworkElementFactory(typeof(Border)); borderFactory.SetValue(Border.CornerRadiusProperty, new CornerRadius(4)); borderFactory.SetValue(Border.BackgroundProperty, Application.Current.Resources["VersionUpdateViewBackgroundBrush"] as Brush); borderFactory.SetValue(Border.BorderBrushProperty, new TemplateBindingExtension(Control.BorderBrushProperty)); borderFactory.SetValue(Border.BorderThicknessProperty, new TemplateBindingExtension(Control.BorderThicknessProperty)); borderFactory.SetValue(Border.PaddingProperty, new Thickness(5, 0, 5, 0)); var contentPresenterFactory = new FrameworkElementFactory(typeof(ContentPresenter)); contentPresenterFactory.SetValue(ContentPresenter.ContentProperty, new TemplateBindingExtension(ContentControl.ContentProperty)); borderFactory.AppendChild(contentPresenterFactory); var customTemplate = new ControlTemplate(typeof(ToolTip)) { VisualTree = borderFactory, }; var style = new Style(typeof(ToolTip), baseStyle) { Setters = { new Setter(Control.TemplateProperty, customTemplate) } }; var toolTip = new ToolTip { Content = content, Placement = PlacementMode.Center, Style = style, }; toolTip.Opened += (_, _) => { if (toolTip.PlacementTarget is FrameworkElement target) { double offset = -(target.ActualHeight / 2) - (toolTip.ActualHeight / 2); toolTip.VerticalOffset = offset; } else { toolTip.VerticalOffset = -60; } }; return toolTip; } public static ToolTip CreateTooltip(string text, int maxWidth = 750) { var tb = new TextBlock { Text = text, TextWrapping = TextWrapping.Wrap, Margin = new(4), MaxWidth = maxWidth, }; return CreateTooltip(tb); } /// /// 掉落识别物品的 Tooltip 创建方法。 /// /// 掉落物列表 /// ToolTip public static ToolTip CreateMaterialDropTooltip(IEnumerable<(string ItemId, int Total, int Add)> drops) { var row = new WrapPanel { Orientation = Orientation.Horizontal, HorizontalAlignment = HorizontalAlignment.Center, Margin = new(4), ItemWidth = 64, MaxWidth = (64 * 5) + (4 * 10), }; foreach (var (itemId, total, add) in drops .OrderByDescending(x => x.Add) .ThenByDescending(x => x.Total)) { var image = new Image { Source = ItemListHelper.GetItemImage(itemId), Width = 32, Height = 32, Margin = new(2), HorizontalAlignment = HorizontalAlignment.Center, }; var text = new TextBlock { Text = FormatNumber(total), FontSize = 12, FontWeight = FontWeights.Bold, TextAlignment = TextAlignment.Center, TextWrapping = TextWrapping.NoWrap, Margin = new(2, 0, 2, 2), HorizontalAlignment = HorizontalAlignment.Center, MaxWidth = 64, }; var itemStack = new StackPanel { Orientation = Orientation.Vertical, HorizontalAlignment = HorizontalAlignment.Center, Margin = new(4, 0, 4, 0), }; itemStack.Children.Add(image); itemStack.Children.Add(text); if (add > 0) { var textAdd = new TextBlock { FontSize = 10, TextAlignment = TextAlignment.Center, TextWrapping = TextWrapping.NoWrap, Margin = new(2, 0, 2, 2), HorizontalAlignment = HorizontalAlignment.Center, MaxWidth = 64, }; textAdd.Inlines.Add(new Run($"(+{FormatNumber(add)})")); itemStack.Children.Add(textAdd); } row.Children.Add(itemStack); continue; static string FormatNumber(int n) => n switch { >= 1_000_000_000 => $"{n / 1_000_000_000.0:#.#}B", >= 1_000_000 => $"{n / 1_000_000.0:#.#}M", >= 1_000 => $"{n / 1_000.0:#.#}k", _ => $"{n}", }; } return CreateTooltip(row); } /// /// 截图测速 Tooltip 创建方法。 /// /// 测速列表 /// ToolTip public static ToolTip? CreateScreencapTooltip(IEnumerable<(string Method, string Cost)>? methods) { if (methods == null) { return null; } var panel = new StackPanel { Orientation = Orientation.Vertical, Margin = new(4), }; foreach (var (method, cost) in methods) { var grid = new Grid(); grid.ColumnDefinitions.Add(new() { Width = new(1, GridUnitType.Star) }); grid.ColumnDefinitions.Add(new() { Width = new(1, GridUnitType.Auto) }); var methodText = new TextBlock { Text = method, FontSize = 12, Margin = new(2, 1, 6, 1), HorizontalAlignment = HorizontalAlignment.Left, }; Grid.SetColumn(methodText, 0); var costText = new TextBlock { Text = cost + " ms", FontSize = 12, Margin = new(2, 1, 2, 1), HorizontalAlignment = HorizontalAlignment.Right, }; Grid.SetColumn(costText, 1); grid.Children.Add(methodText); grid.Children.Add(costText); panel.Children.Add(grid); } return panel.Children.Count == 0 ? null : CreateTooltip(panel); } #endregion } }