using Dominion.NET_WPF.Enums; using Dominion.NET_WPF.ViewModel; using DominionBase.Currencies; using DominionBase.Enums; using DominionBase.Piles; using System; using System.ComponentModel; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Effects; using Visibility = System.Windows.Visibility; namespace Dominion.NET_WPF { /// /// Interaction logic for SupplyControl.xaml /// public partial class SupplyControl : UserControl, IDisposable { public static readonly RoutedEvent SupplyClickEvent = EventManager.RegisterRoutedEvent( "SupplyClick", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(SupplyControl)); public event RoutedEventHandler SupplyClick { add { AddHandler(SupplyClickEvent, value); } remove { RemoveHandler(SupplyClickEvent, value); } } public static readonly DependencyProperty ModifierKeysPressedProperty = DependencyProperty.Register( "ModifierKeysPressed", typeof(ModifierKeys), typeof(SupplyControl), new FrameworkPropertyMetadata(ModifierKeys.None, FrameworkPropertyMetadataOptions.AffectsRender)); public ModifierKeys ModifierKeysPressed { get { return (ModifierKeys)GetValue(ModifierKeysPressedProperty); } set { SetValue(ModifierKeysPressedProperty, value); IsCtrlPressed = value.HasFlag(ModifierKeys.Control); } } public static readonly DependencyProperty IsCtrlPressedProperty = DependencyProperty.Register( "IsCtrlPressed", typeof(bool), typeof(SupplyControl), new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.AffectsRender)); public bool IsCtrlPressed { get { return (bool)GetValue(IsCtrlPressedProperty); } set { SetValue(IsCtrlPressedProperty, value); } } private SupplyControlViewModel Context => (SupplyControlViewModel)DataContext; private DominionBase.ITableable _supply; private SupplyVisibility _clickability = SupplyVisibility.Plain; private int _glowSize; private HighlightMode _highlight; public SupplyControl() { InitializeComponent(); if (WMain.Settings != null) { WMain.Settings.SettingsChanged -= Settings_SettingsChanged; WMain.Settings.SettingsChanged += Settings_SettingsChanged; Settings_SettingsChanged(WMain.Settings, null); } } public void Dispose() { if (WMain.Settings != null) { WMain.Settings.SettingsChanged -= Settings_SettingsChanged; } } private void Settings_SettingsChanged(object sender, SettingsChangedEventArgs e) { if (sender is Settings settings) { if (settings.ToolTipShowDuration == ToolTipShowDuration.Off) ToolTipService.SetIsEnabled(this, false); else { ToolTipService.SetIsEnabled(this, true); ToolTipService.SetShowDuration(this, (int)settings.ToolTipShowDuration); } } } /// /// Stuff. /// [Category("Custom Settings"), Description(@"Stuff.")] public DominionBase.ITableable Supply { get => _supply; set { if (_supply != null) { _supply.PileChanged -= _Supply_PileChanged; _supply.TokensChanged -= _Supply_TokensChanged; } _supply = value; Context.Supply = value; if (_supply is Supply supply && supply.Count > 0) ttcCard.CardList = (Supply)value; else ttcCard.Card = value; //gCostCount.Visibility = (_supply?.HasCost == true) ? Visibility.Visible : Visibility.Collapsed; if (_supply != null) { _supply.PileChanged += _Supply_PileChanged; _supply.TokensChanged += _Supply_TokensChanged; _Supply_TokensChanged(value, new TokensChangedEventArgs(null)); _Supply_PileChanged(_supply, null); } } } private void _Supply_PileChanged(object sender, PileChangedEventArgs e) { if (Dispatcher.CheckAccess()) { Context.Supply = Context.Supply; var supply = sender as DominionBase.IDisplayable; if (supply != null && ((WMain.Settings.DisplaySupplyPileNames && supply.Location == Location.Kingdom) || (WMain.Settings.DisplayBasicSupplyPileNames && supply.Location == Location.General) || (WMain.Settings.DisplayBasicSupplyPileNames && supply.Location == Location.LandscapeCard))) { lName.Visibility = Visibility.Visible; tbName.ToolTip = supply.RootCard.Name; lName.Background = Caching.BrushRepository.GetBackgroundBrush(supply.RootCard.Category); lName.Foreground = Caching.BrushRepository.GetForegroundBrush(supply.RootCard.Category); // Flip the foreground/background for Events if (supply.RootCard.Category.HasFlag(Categories.Event)) { var t = lName.Foreground; lName.Foreground = lName.Background; lName.Background = t; } if (supply.RootCard.Category.HasFlag(Categories.Reaction)) tbName.Effect = Caching.DropShadowRepository.GetDSE(8, Colors.White, 1d); } else { lName.Visibility = Visibility.Collapsed; tbName.ToolTip = string.Empty; } var repo = Caching.ImageRepository.Acquire(); if (supply?.DisplayCard != null) { imCardIcon.Source = repo.GetBitmapImage(supply.DisplayCard.ImageName, "small"); if (supply is Supply list && list.Count > 0) ttcCard.CardList = list; else ttcCard.Card = supply.DisplayCard; } else { imCardIcon.Source = repo.GetBitmapImage(supply?.ImageName, "small"); ttcCard.Card = supply?.RootCard; } Caching.ImageRepository.Release(); InvalidateVisual(); } else { Dispatcher.BeginInvoke(new EventHandler>(_Supply_PileChanged), System.Windows.Threading.DispatcherPriority.Normal, sender, e); } } private void _Supply_TokensChanged(object sender, TokensChangedEventArgs e) { if (Dispatcher.CheckAccess()) { spExtraStuff.Children.Clear(); var tokenGroups = (sender as DominionBase.ITableable)?.Tokens.GroupBy(t => t.Title); if (tokenGroups == null) return; foreach (var tokenGroup in tokenGroups) { if (tokenGroup.Count() > 2) { spExtraStuff.Children.Add(new TextBlock { Margin = new Thickness(3, 0, 3, 0), Text = $"{tokenGroup.Count()}x" }); spExtraStuff.Children.Add(new Controls.ucTokenIcon { Token = tokenGroup.ElementAt(0) }); } else { foreach (var token in tokenGroup) { if (token is DominionBase.Cards.Menagerie.WayOfTheMouseToken wotmToken) spExtraStuff.Children.Add(new Controls.ucCardIcon { Card = wotmToken.MouseCard }); else spExtraStuff.Children.Add(new Controls.ucTokenIcon { Token = token }); } } } } else { Dispatcher.BeginInvoke(new EventHandler(_Supply_TokensChanged), System.Windows.Threading.DispatcherPriority.Normal, sender, e); } } /// /// Stuff. /// [Category("Custom Settings"), Description(@"Stuff.")] public SupplyVisibility Clickability { get => _clickability; set { // Landmarks, States, Boons, Hexes, & Ways are always Plain (never not-clickable, gainable, or buyable) if (_supply is DominionBase.Cards.Landmark || _supply is DominionBase.Cards.Boon || _supply is DominionBase.Cards.State || _supply is DominionBase.Cards.Hex || _supply is DominionBase.Cards.Way) _clickability = SupplyVisibility.Plain; else _clickability = value; Context.Clickability = _clickability; InvalidateVisual(); } } public HighlightMode Highlight { get { return _highlight; } set { _highlight = value; //DropShadowEffect dse = null; switch (_highlight) { case HighlightMode.None: bMain.BorderBrush = Brushes.Transparent; break; case HighlightMode.Primary: //dse = Caching.DropShadowRepository.GetDSE(_glowSize * 4, Colors.Crimson, 1.0, false); bMain.BorderBrush = Brushes.Crimson; break; case HighlightMode.Secondary: //dse = Caching.DropShadowRepository.GetDSE(_glowSize * 4, Colors.Crimson, 1.0, false); bMain.BorderBrush = Brushes.Goldenrod; break; } } } internal Control FindGameObject(DominionBase.IGameObject gameObject) { return _supply.UniqueId == gameObject.UniqueId ? this : null; } private void BBuy_Click(object sender, RoutedEventArgs e) { var button = sender as Button; if (button != null) button.IsEnabled = false; RaiseEvent(new RoutedEventArgs(SupplyClickEvent)); if (button != null) button.IsEnabled = true; } protected override void OnRender(DrawingContext drawingContext) { base.OnRender(drawingContext); if (_supply != null) { var supply = _supply as Supply; if (supply != null && supply.Count == 0) { Context.IsSupplyGone = true; } else { if (Context.IsSupplyGone) Clickability = Clickability; Context.IsSupplyGone = false; } DominionBase.Cards.Cost supplyCost = null; DominionBase.Cards.Cost baseCost = null; if (supply != null) { supplyCost = supply.CurrentCost; baseCost = supply.BaseCost; } else if (_supply is DominionBase.Cards.Event evt) { supplyCost = evt.CurrentCost; baseCost = evt.BaseCost; } else if (_supply is DominionBase.Cards.Project prj) { supplyCost = prj.CurrentCost; baseCost = prj.BaseCost; } if (supplyCost != (DominionBase.Cards.Cost)null) { var sbCost = new StringBuilder(); if (supplyCost.Coin.Value > 0 || supplyCost.Debt.Value == 0) sbCost.AppendFormat("{0}{1}", supplyCost.Coin.Value, Coin.Sign); if (supplyCost.Debt.Value > 0) sbCost.AppendFormat("{0}{1}", supplyCost.Debt.Value, Debt.Sign); if (supplyCost.Potion.Value > 0) sbCost.AppendFormat(" {0}", Potion.Sign); if (supplyCost.Special) sbCost.Append(" *"); if (supplyCost.CanOverpay) sbCost.Append(" +"); tbCost.Text = sbCost.ToString(); if (supplyCost < _supply.BaseCost) lCost.Foreground = Brushes.LimeGreen; else if (supplyCost > _supply.BaseCost) lCost.Foreground = Brushes.Red; else lCost.Foreground = Brushes.Black; if (baseCost != _supply.Randomizer.BaseCost) { tbCost.TextDecorations = TextDecorations.Underline; tbCost.FontStyle = FontStyles.Italic; } else if (tbCost.TextDecorations == TextDecorations.Underline) { tbCost.TextDecorations = null; tbCost.FontStyle = FontStyles.Normal; } } else tbCost.Text = string.Empty; } } private void UserControl_MouseDown(object sender, MouseButtonEventArgs e) { if (WMain.Settings != null && WMain.Settings.ShowToolTipOnRightClick && e.ChangedButton == MouseButton.Right && e.ButtonState == MouseButtonState.Pressed) { CaptureMouse(); ttCard.HasDropShadow = false; ttCard.IsOpen = true; } } private void UserControl_MouseUp(object sender, MouseButtonEventArgs e) { if (WMain.Settings != null && WMain.Settings.ShowToolTipOnRightClick && e.ChangedButton == MouseButton.Right && e.ButtonState == MouseButtonState.Released) { ReleaseMouseCapture(); ttCard.IsOpen = false; } } private void UserControl_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e) { if (ttCard.IsOpen) ttCard.IsOpen = false; } private void UserControl_MouseEnter(object sender, MouseEventArgs e) { CardHover.RaiseCardHoverEvent(this, new CardHoverEventArgs(Supply?.DisplayCard)); } private void UserControl_StylusEnter(object sender, StylusEventArgs e) { CardHover.RaiseCardHoverEvent(this, new CardHoverEventArgs(Supply?.DisplayCard)); } private void UserControl_TouchEnter(object sender, TouchEventArgs e) { CardHover.RaiseCardHoverEvent(this, new CardHoverEventArgs(Supply?.DisplayCard)); } } }