XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFEEDToolBox

【WinUI】XFE精英危险工具箱

公开
关注 0 Fork 0 Star 0
UTF-8
using XFEEDToolBox.Core.Galaxy;

namespace XFEEDToolBox.Controls;

public sealed partial class GalaxyFilterPanel
{
    public static readonly DependencyProperty CurrentTradeChoicesProperty=DependencyProperty.Register(nameof(CurrentTradeChoices),typeof(IReadOnlyList<GalaxyCommodityGroup>),typeof(GalaxyFilterPanel),new PropertyMetadata(null,Changed));
    public static readonly DependencyProperty CurrentTradeStatusProperty=DependencyProperty.Register(nameof(CurrentTradeStatus),typeof(string),typeof(GalaxyFilterPanel),new PropertyMetadata("",Changed));
    public IReadOnlyList<GalaxyCommodityGroup> CurrentTradeChoices {get=>(IReadOnlyList<GalaxyCommodityGroup>?)GetValue(CurrentTradeChoicesProperty)??[];set=>SetValue(CurrentTradeChoicesProperty,value);}
    public string CurrentTradeStatus {get=>(string)GetValue(CurrentTradeStatusProperty);set=>SetValue(CurrentTradeStatusProperty,value);}
    private readonly CheckBox currentTrade=new(){Content="显示原当前有效贸易流"};
    private readonly ComboBox currentTradeSource=new(){Header="交易者来源",HorizontalAlignment=HorizontalAlignment.Stretch};
    private readonly TextBox currentTradeSearch=new(){PlaceholderText="查找原缓存中的商品"};
    private readonly TextBlock currentTradeStatus=new(){FontSize=11,TextWrapping=TextWrapping.Wrap};
    private readonly StackPanel currentTradeCommodities=new(){Spacing=0};
    private readonly Dictionary<string,CheckBox> currentTradeLeaves=[];
    private readonly Dictionary<string,(CheckBox Check,GalaxyCommodityGroup Group)> currentTradeParents=[];
    private readonly Dictionary<int,CheckBox> currentTradeCategoryVisibility=[];
    private readonly Dictionary<string,bool> currentTradeExpanded=[];
    private string currentTradeSignature="";
    private Expander BuildCurrentTradeControls()
    {
        foreach(var entry in new[]{("NPC",GalaxyTradeFlowSource.Npc),("玩家",GalaxyTradeFlowSource.Players),("全部",GalaxyTradeFlowSource.All)})
            currentTradeSource.Items.Add(new ComboBoxItem{Content=entry.Item1,Tag=entry.Item2});
        var content=new StackPanel{Spacing=5};content.Children.Add(currentTrade);content.Children.Add(currentTradeSource);content.Children.Add(currentTradeSearch);
        var all=new Button{Content="全部商品"};var none=new Button{Content="清除商品"};var actions=new StackPanel{Orientation=Orientation.Horizontal,Spacing=7};actions.Children.Add(all);actions.Children.Add(none);content.Children.Add(actions);
        content.Children.Add(new ScrollViewer{Content=currentTradeCommodities,MaxHeight=180,VerticalScrollBarVisibility=ScrollBarVisibility.Auto});content.Children.Add(currentTradeStatus);
        content.Children.Add(new TextBlock{Text="只读取原游戏现有贸易缓存,按原时钟有效期、交易者与商品分类筛选。商品名、端点或坐标未确认时不绘制;不以历史记录补齐。",FontSize=11,TextWrapping=TextWrapping.Wrap});
        currentTrade.Checked+=(_,_)=>{if(!updating)Filter=Filter with{ShowCurrentTradeFlows=true};};
        currentTrade.Unchecked+=(_,_)=>{if(!updating)Filter=Filter with{ShowCurrentTradeFlows=false};};
        currentTradeSource.SelectionChanged+=(_,_)=>{if(!updating&&currentTradeSource.SelectedItem is ComboBoxItem{Tag:GalaxyTradeFlowSource source})Filter=Filter with{CurrentTradeSource=source};};
        all.Click+=(_,_)=>Filter=Filter with{CurrentTradeCategories=null,CurrentTradeCommodities=null};none.Click+=(_,_)=>Filter=Filter with{CurrentTradeCategories=new HashSet<int>(),CurrentTradeCommodities=new HashSet<string>()};currentTradeSearch.TextChanged+=(_,_)=>Refresh();
        return new(){Header="原当前贸易流",Content=content,HorizontalAlignment=HorizontalAlignment.Stretch,HorizontalContentAlignment=HorizontalAlignment.Stretch};
    }
    private void RefreshCurrentTradeControls(GalaxyMapFilter filter)
    {
        currentTrade.IsChecked=filter.ShowCurrentTradeFlows;currentTradeSource.SelectedItem=currentTradeSource.Items.OfType<ComboBoxItem>().FirstOrDefault(i=>i.Tag is GalaxyTradeFlowSource source&&source==filter.CurrentTradeSource);
        currentTradeSource.IsEnabled=filter.ShowCurrentTradeFlows;currentTradeStatus.Text=CurrentTradeStatus;
        var groups=CurrentTradeChoices;var search=currentTradeSearch.Text.Trim();bool Contains(string text)=>text.Contains(search,StringComparison.OrdinalIgnoreCase);
        var shown=groups.Select(g=>search.Length==0||Contains(g.Label)?g:g with{Children=g.Children.Where(c=>Contains(c.Label)||Contains(c.Key)).ToArray()}).Where(g=>g.Children.Count>0).ToArray();
        var signature=string.Join('|',shown.Select(g=>g.Key+":"+string.Join(',',g.Children.Select(c=>c.Key+"="+c.Label))));
        if(signature!=currentTradeSignature)
        {
            currentTradeSignature=signature;currentTradeCommodities.Children.Clear();currentTradeLeaves.Clear();currentTradeParents.Clear();currentTradeCategoryVisibility.Clear();
            foreach(var group in shown)
            {
                var complete=groups.First(g=>g.Key==group.Key);var children=new StackPanel{Spacing=1};var parent=new CheckBox{Content="全选此类",IsThreeState=true};children.Children.Add(parent);currentTradeParents[group.Key]=(parent,complete);
                parent.Click+=(_,_)=>
                {
                    if(updating)return;
                    var originalCategory=GalaxyOriginalTradeCategories.Categories.FirstOrDefault(c=>group.Key=="originaltrade:"+c.Id);
                    var targets=originalCategory is null?complete.Children.Select(c=>c.Key):GalaxyOriginalTradeCategories.Commodities.Where(c=>c.CategoryId==originalCategory.Id).Select(c=>GalaxyMapFilter.Normalize(c.Name));
                    Filter=Filter with{CurrentTradeCommodities=GalaxyCommodityTree.SelectGroup(Filter.CurrentTradeCommodities,CurrentTradeUniverse(),targets,GalaxyCommodityTree.Selected(Filter.CurrentTradeCommodities,complete.Children)!=true)};
                };
                foreach(var child in group.Children)
                {
                    var checkbox=new CheckBox{Content=child.Label};children.Children.Add(checkbox);currentTradeLeaves[child.Key]=checkbox;
                    void Select(object sender,RoutedEventArgs args)
                    {
                        if(updating)return;
                        var selected=Filter.CurrentTradeCommodities is {} old?new HashSet<string>(old):CurrentTradeUniverse().ToHashSet(StringComparer.Ordinal);
                        if(checkbox.IsChecked==true)selected.Add(child.Key);else selected.Remove(child.Key);
                        Filter=Filter with{CurrentTradeCommodities=selected};
                    }
                    checkbox.Checked+=Select;checkbox.Unchecked+=Select;
                }
                object header=group.Label+" · "+complete.Children.Count;
                if(GalaxyOriginalTradeCategories.Categories.FirstOrDefault(c=>group.Key=="originaltrade:"+c.Id) is {} definition)
                {
                    var categorySwitch=new CheckBox{Content=header};header=categorySwitch;currentTradeCategoryVisibility[definition.Id]=categorySwitch;
                    categorySwitch.Click+=(_,_)=>
                    {
                        if(updating)return;
                        var selection=Filter.CurrentTradeCategories is {} old?new HashSet<int>(old):GalaxyOriginalTradeCategories.Categories.Select(c=>c.Id).ToHashSet();
                        if(categorySwitch.IsChecked==true)selection.Add(definition.Id);else selection.Remove(definition.Id);
                        // Original parent visibility is independent of each
                        // leaf's saved checkbox; switching it off preserves leaves.
                        Filter=Filter with{CurrentTradeCategories=selection};
                    };
                }
                var expanded=new Expander{Header=header,Content=children,HorizontalAlignment=HorizontalAlignment.Stretch,HorizontalContentAlignment=HorizontalAlignment.Stretch,IsExpanded=search.Length>0||currentTradeExpanded.GetValueOrDefault(group.Key)};
                expanded.Expanding+=(_,_)=>currentTradeExpanded[group.Key]=true;expanded.Collapsed+=(_,_)=>currentTradeExpanded[group.Key]=false;currentTradeCommodities.Children.Add(expanded);
            }
        }
        foreach(var row in currentTradeLeaves){row.Value.IsChecked=filter.CurrentTradeCommodities is null||filter.CurrentTradeCommodities.Contains(row.Key);row.Value.IsEnabled=filter.ShowCurrentTradeFlows;}
        foreach(var row in currentTradeParents){row.Value.Check.IsChecked=GalaxyCommodityTree.Selected(filter.CurrentTradeCommodities,row.Value.Group.Children);row.Value.Check.IsEnabled=filter.ShowCurrentTradeFlows;}
        foreach(var row in currentTradeCategoryVisibility){row.Value.IsChecked=filter.CurrentTradeCategories is null||filter.CurrentTradeCategories.Contains(row.Key);row.Value.IsEnabled=filter.ShowCurrentTradeFlows;}
    }
    private IEnumerable<string> CurrentTradeUniverse()=>GalaxyOriginalTradeCategories.Commodities.Select(c=>GalaxyMapFilter.Normalize(c.Name)).Concat(CurrentTradeChoices.SelectMany(g=>g.Children).Select(c=>c.Key)).Distinct(StringComparer.Ordinal);
}