ObjectProperties.cs (10485B)
1 // 2 // Copyright 2020 Electronic Arts Inc. 3 // 4 // The Command & Conquer Map Editor and corresponding source code is free 5 // software: you can redistribute it and/or modify it under the terms of 6 // the GNU General Public License as published by the Free Software Foundation, 7 // either version 3 of the License, or (at your option) any later version. 8 9 // The Command & Conquer Map Editor and corresponding source code is distributed 10 // in the hope that it will be useful, but with permitted additional restrictions 11 // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT 12 // distributed with this program. You should have received a copy of the 13 // GNU General Public License along with permitted additional restrictions 14 // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection 15 using MobiusEditor.Interface; 16 using MobiusEditor.Model; 17 using MobiusEditor.Utility; 18 using System; 19 using System.Collections.Specialized; 20 using System.ComponentModel; 21 using System.Data; 22 using System.Linq; 23 using System.Windows.Forms; 24 25 namespace MobiusEditor.Controls 26 { 27 public partial class ObjectProperties : UserControl 28 { 29 private bool isMockObject; 30 31 public IGamePlugin Plugin { get; private set; } 32 33 private INotifyPropertyChanged obj; 34 public INotifyPropertyChanged Object 35 { 36 get => obj; 37 set 38 { 39 if (obj != value) 40 { 41 if (obj != null) 42 { 43 obj.PropertyChanged -= Obj_PropertyChanged; 44 } 45 46 obj = value; 47 48 if (obj != null) 49 { 50 obj.PropertyChanged += Obj_PropertyChanged; 51 } 52 53 Rebind(); 54 } 55 } 56 } 57 58 public ObjectProperties() 59 { 60 InitializeComponent(); 61 } 62 63 public void Initialize(IGamePlugin plugin, bool isMockObject) 64 { 65 this.isMockObject = isMockObject; 66 67 Plugin = plugin; 68 plugin.Map.Triggers.CollectionChanged += Triggers_CollectionChanged; 69 70 houseComboBox.DataSource = plugin.Map.Houses.Select(t => new TypeItem<HouseType>(t.Type.Name, t.Type)).ToArray(); 71 missionComboBox.DataSource = plugin.Map.MissionTypes; 72 73 UpdateDataSource(); 74 75 Disposed += (sender, e) => 76 { 77 Object = null; 78 plugin.Map.Triggers.CollectionChanged -= Triggers_CollectionChanged; 79 }; 80 } 81 82 private void Triggers_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) 83 { 84 UpdateDataSource(); 85 } 86 87 private void UpdateDataSource() 88 { 89 triggerComboBox.DataSource = Trigger.None.Yield().Concat(Plugin.Map.Triggers.Select(t => t.Name).Distinct()).ToArray(); 90 } 91 92 private void Rebind() 93 { 94 houseComboBox.DataBindings.Clear(); 95 strengthNud.DataBindings.Clear(); 96 directionComboBox.DataBindings.Clear(); 97 missionComboBox.DataBindings.Clear(); 98 triggerComboBox.DataBindings.Clear(); 99 basePriorityNud.DataBindings.Clear(); 100 prebuiltCheckBox.DataBindings.Clear(); 101 sellableCheckBox.DataBindings.Clear(); 102 rebuildCheckBox.DataBindings.Clear(); 103 104 if (obj == null) 105 { 106 return; 107 } 108 109 switch (obj) 110 { 111 case Infantry infantry: 112 { 113 houseComboBox.Enabled = true; 114 directionComboBox.DataSource = Plugin.Map.DirectionTypes 115 .Where(t => t.Facing != FacingType.None) 116 .Select(t => new TypeItem<DirectionType>(t.Name, t)).ToArray(); 117 118 missionComboBox.DataBindings.Add("SelectedItem", obj, "Mission"); 119 missionLabel.Visible = missionComboBox.Visible = true; 120 basePriorityLabel.Visible = basePriorityNud.Visible = false; 121 prebuiltCheckBox.Visible = false; 122 sellableCheckBox.Visible = false; 123 rebuildCheckBox.Visible = false; 124 } 125 break; 126 case Unit unit: 127 { 128 houseComboBox.Enabled = true; 129 directionComboBox.DataSource = Plugin.Map.DirectionTypes.Select(t => new TypeItem<DirectionType>(t.Name, t)).ToArray(); 130 missionComboBox.DataBindings.Add("SelectedItem", obj, "Mission"); 131 missionLabel.Visible = missionComboBox.Visible = true; 132 basePriorityLabel.Visible = basePriorityNud.Visible = false; 133 prebuiltCheckBox.Visible = false; 134 sellableCheckBox.Visible = false; 135 rebuildCheckBox.Visible = false; 136 } 137 break; 138 case Building building: 139 { 140 houseComboBox.Enabled = building.IsPrebuilt; 141 directionComboBox.DataSource = Plugin.Map.DirectionTypes.Select(t => new TypeItem<DirectionType>(t.Name, t)).ToArray(); 142 directionComboBox.Visible = (building.Type != null) && building.Type.HasTurret; 143 missionLabel.Visible = missionComboBox.Visible = false; 144 basePriorityLabel.Visible = basePriorityNud.Visible = true; 145 prebuiltCheckBox.Visible = true; 146 prebuiltCheckBox.Enabled = building.BasePriority >= 0; 147 148 basePriorityNud.DataBindings.Add("Value", obj, "BasePriority"); 149 prebuiltCheckBox.DataBindings.Add("Checked", obj, "IsPrebuilt"); 150 151 switch (Plugin.GameType) 152 { 153 case GameType.TiberianDawn: 154 { 155 sellableCheckBox.Visible = false; 156 rebuildCheckBox.Visible = false; 157 } break; 158 case GameType.RedAlert: 159 { 160 sellableCheckBox.DataBindings.Add("Checked", obj, "Sellable"); 161 rebuildCheckBox.DataBindings.Add("Checked", obj, "Rebuild"); 162 sellableCheckBox.Visible = true; 163 rebuildCheckBox.Visible = true; 164 } break; 165 } 166 } 167 break; 168 } 169 170 houseComboBox.DataBindings.Add("SelectedValue", obj, "House"); 171 strengthNud.DataBindings.Add("Value", obj, "Strength"); 172 directionComboBox.DataBindings.Add("SelectedValue", obj, "Direction"); 173 triggerComboBox.DataBindings.Add("SelectedItem", obj, "Trigger"); 174 } 175 176 private void Obj_PropertyChanged(object sender, PropertyChangedEventArgs e) 177 { 178 switch (e.PropertyName) 179 { 180 case "Type": 181 { 182 Rebind(); 183 } 184 break; 185 case "BasePriority": 186 { 187 if (obj is Building building) 188 { 189 prebuiltCheckBox.Enabled = building.BasePriority >= 0; 190 } 191 } 192 break; 193 case "IsPrebuilt": 194 { 195 if (obj is Building building) 196 { 197 if (!building.IsPrebuilt) 198 { 199 var basePlayer = Plugin.Map.HouseTypes.Where(h => h.Equals(Plugin.Map.BasicSection.BasePlayer)).FirstOrDefault() ?? Plugin.Map.HouseTypes.First(); 200 building.House = basePlayer; 201 } 202 houseComboBox.Enabled = building.IsPrebuilt; 203 } 204 } break; 205 } 206 207 if (!isMockObject) 208 { 209 Plugin.Dirty = true; 210 } 211 } 212 213 private void comboBox_SelectedValueChanged(object sender, EventArgs e) 214 { 215 foreach (Binding binding in (sender as ComboBox).DataBindings) 216 { 217 binding.WriteValue(); 218 } 219 } 220 221 private void nud_ValueChanged(object sender, EventArgs e) 222 { 223 foreach (Binding binding in (sender as NumericUpDown).DataBindings) 224 { 225 binding.WriteValue(); 226 } 227 } 228 229 private void checkBox_CheckedChanged(object sender, EventArgs e) 230 { 231 foreach (Binding binding in (sender as CheckBox).DataBindings) 232 { 233 binding.WriteValue(); 234 } 235 } 236 } 237 238 public class ObjectPropertiesPopup : ToolStripDropDown 239 { 240 private readonly ToolStripControlHost host; 241 242 public ObjectProperties ObjectProperties { get; private set; } 243 244 public ObjectPropertiesPopup(IGamePlugin plugin, INotifyPropertyChanged obj) 245 { 246 ObjectProperties = new ObjectProperties(); 247 ObjectProperties.Initialize(plugin, false); 248 ObjectProperties.Object = obj; 249 250 host = new ToolStripControlHost(ObjectProperties); 251 Padding = Margin = host.Padding = host.Margin = Padding.Empty; 252 MinimumSize = ObjectProperties.MinimumSize; 253 ObjectProperties.MinimumSize = ObjectProperties.Size; 254 MaximumSize = ObjectProperties.MaximumSize; 255 ObjectProperties.MaximumSize = ObjectProperties.Size; 256 Size = ObjectProperties.Size; 257 Items.Add(host); 258 ObjectProperties.Disposed += (sender, e) => 259 { 260 ObjectProperties = null; 261 Dispose(true); 262 }; 263 } 264 265 protected override void OnClosed(ToolStripDropDownClosedEventArgs e) 266 { 267 base.OnClosed(e); 268 269 ObjectProperties.Object = null; 270 } 271 } 272 }