PageRenderTime 50ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/Layer.cs

https://bitbucket.org/rstarkov/tankiconmaker
C# | 132 lines | 101 code | 18 blank | 13 comment | 9 complexity | 1e7b15b56f6f944578fef49ea284a6f9 MD5 | raw file
Possible License(s): Apache-2.0, BSD-3-Clause, GPL-3.0, CC-BY-SA-3.0
  1. using System.Collections.ObjectModel;
  2. using System.Collections.Specialized;
  3. using System.ComponentModel;
  4. using System.Linq;
  5. using System.Text.RegularExpressions;
  6. using System.Windows;
  7. using System.Windows.Controls;
  8. using System.Xml.Linq;
  9. using RT.Util.Lingo;
  10. using RT.Util.Serialization;
  11. using WpfCrutches;
  12. namespace TankIconMaker
  13. {
  14. abstract class LayerBase : IHasTreeViewItem, IHasTypeNameDescription, IClassifyXmlObjectProcessor, INotifyPropertyChanged
  15. {
  16. /// <summary>Describes what this layer type does as concisely as possible.</summary>
  17. [Browsable(false)]
  18. public abstract string TypeName { get; }
  19. /// <summary>Describes what this layer type does in more detail.</summary>
  20. [Browsable(false)]
  21. public abstract string TypeDescription { get; }
  22. /// <summary>Specifies the version of this layer’s settings - incremented on changing layer settings backwards-incompatibly.</summary>
  23. [Browsable(false)]
  24. public abstract int Version { get; }
  25. [Browsable(false)]
  26. public string Name { get { return _Name; } set { _Name = value; NotifyPropertyChanged("Name"); NotifyPropertyChanged("NameVisibility"); } }
  27. private string _Name;
  28. [Browsable(false)]
  29. public Visibility NameVisibility { get { return string.IsNullOrEmpty(Name) ? Visibility.Collapsed : Visibility.Visible; } }
  30. /// <summary>Keeps track of the style that this layer belongs to. This value is kept up-to-date automatically.</summary>
  31. [Browsable(false), ClassifyIgnore]
  32. public Style ParentStyle { get; set; }
  33. [Browsable(false)]
  34. public ObservableCollection<EffectBase> Effects { get; set; }
  35. /// <summary>Id for use in Layer Mask.</summary>
  36. private string _Id;
  37. public string Id { get { return _Id; } set { _Id = Regex.Replace(Regex.Replace(value, @"[^A-Za-z0-9_]", ""), @"^([0-9])", "_$1"); NotifyPropertyChanged("Id"); } }
  38. public static MemberTr IdTr(Translation tr) { return new MemberTr(tr.Category.General, tr.LayerAndEffect.LayerId); }
  39. public bool Visible { get { return _Visible; } set { _Visible = value; NotifyPropertyChanged("Visible"); } }
  40. private bool _Visible;
  41. public static MemberTr VisibleTr(Translation tr) { return new MemberTr(tr.Category.General, tr.LayerAndEffect.LayerVisible); }
  42. public ValueSelector<BoolWithPassthrough> VisibleFor { get; set; }
  43. public static MemberTr VisibleForTr(Translation tr) { return new MemberTr(tr.Category.General, tr.LayerAndEffect.LayerVisibleFor); }
  44. public LayerBase()
  45. {
  46. Effects = new ObservableCollection<EffectBase>();
  47. Effects.CollectionChanged += updateEffectLayer;
  48. Visible = true;
  49. VisibleFor = new ValueSelector<BoolWithPassthrough>(BoolWithPassthrough.Yes);
  50. }
  51. private void updateEffectLayer(object sender, NotifyCollectionChangedEventArgs e)
  52. {
  53. if (e.Action == NotifyCollectionChangedAction.Add || e.Action == NotifyCollectionChangedAction.Replace)
  54. foreach (var item in e.NewItems.OfType<EffectBase>())
  55. item.Layer = this;
  56. else if (e.Action == NotifyCollectionChangedAction.Reset)
  57. foreach (var item in Effects)
  58. item.Layer = this;
  59. }
  60. /// <summary>
  61. /// Returns this layer's image for this tank. Will be called from multiple threads in parallel. The result may be any size. Return
  62. /// a writable image if it may be modified directly, or mark it as read-only otherwise.
  63. /// </summary>
  64. public abstract BitmapBase Draw(Tank tank);
  65. /// <summary>
  66. /// Stores the <see cref="Version"/> of the maker as it was at the time of saving settings to XML. This may
  67. /// then be used to apply transformations to the XML produced by old versions of a layer.
  68. /// </summary>
  69. protected int SavedByVersion;
  70. void IClassifyObjectProcessor<XElement>.BeforeSerialize() { BeforeSerialize(); }
  71. protected virtual void BeforeSerialize()
  72. {
  73. SavedByVersion = Version;
  74. }
  75. void IClassifyObjectProcessor<XElement>.AfterSerialize(XElement xml) { AfterSerialize(xml); }
  76. protected virtual void AfterSerialize(XElement xml) { }
  77. void IClassifyObjectProcessor<XElement>.BeforeDeserialize(XElement xml) { BeforeDeserialize(xml); }
  78. protected virtual void BeforeDeserialize(XElement xml) { }
  79. void IClassifyObjectProcessor<XElement>.AfterDeserialize(XElement xml) { AfterDeserialize(xml); }
  80. protected virtual void AfterDeserialize(XElement xml)
  81. {
  82. foreach (var effect in Effects)
  83. effect.Layer = this;
  84. var oldSizePosEffects = Effects.Where(e => e is Effects.SizePosEffect && e.SavedByVersion <= 2).ToList();
  85. if (oldSizePosEffects.Any())
  86. {
  87. oldSizePosEffects.Reverse();
  88. foreach (var e in oldSizePosEffects)
  89. {
  90. Effects.Remove(e);
  91. Effects.Insert(0, e);
  92. }
  93. }
  94. Effects.CollectionChanged -= updateEffectLayer;
  95. Effects.CollectionChanged += updateEffectLayer;
  96. }
  97. [ClassifyIgnore, Browsable(false)]
  98. public TreeViewItem TreeViewItem { get; set; }
  99. protected void NotifyPropertyChanged(string name) { PropertyChanged(this, new PropertyChangedEventArgs(name)); }
  100. public event PropertyChangedEventHandler PropertyChanged = (_, __) => { };
  101. public virtual LayerBase Clone()
  102. {
  103. var result = MemberwiseClone() as LayerBase;
  104. result.PropertyChanged = (_, __) => { };
  105. result.TreeViewItem = null;
  106. result.VisibleFor = VisibleFor.Clone();
  107. result.Effects = new ObservableCollection<EffectBase>();
  108. result.Effects.CollectionChanged += result.updateEffectLayer;
  109. foreach (var e in Effects)
  110. result.Effects.Add(e.Clone());
  111. return result;
  112. }
  113. }
  114. }