1 using System; 2 using System.Linq; 3 using System.Reactive.Disposables; 4 using System.Reactive.Linq; 5 using System.Windows.Forms; 6 using OpenBveApi.Interface; 7 using Reactive.Bindings.Binding; 8 using Reactive.Bindings.Extensions; 9 using TrainEditor2.Extensions; 10 using TrainEditor2.ViewModels.Others; 11 using TrainEditor2.ViewModels.Panels; 12 13 namespace TrainEditor2.Views 14 { 15 public partial class FormTouch : Form 16 { 17 private readonly CompositeDisposable disposable; 18 19 private readonly TouchElementViewModel touch; 20 21 private TreeNode TreeViewTouchTopNode 22 { 23 get 24 { 25 if (treeViewTouch.Nodes.Count == 0) 26 { 27 treeViewTouch.Nodes.Add(new TreeNode()); 28 } 29 30 return treeViewTouch.Nodes[0]; 31 } 32 // ReSharper disable once UnusedMember.Local 33 set 34 { 35 treeViewTouch.Nodes.Clear(); 36 treeViewTouch.Nodes.Add(value); 37 treeViewTouch.ExpandAll(); 38 treeViewTouch.SelectedNode = treeViewTouch.Nodes 39 .OfType<TreeNode>() 40 .Select(z => FormEditor.SearchTreeNode(touch.SelectedTreeItem.Value, z)) 41 .FirstOrDefault(z => z != null); 42 touch.SelectedTreeItem.ForceNotify(); 43 } 44 } 45 46 private ListViewItem ListViewTouchSelectedItem 47 { 48 get 49 { 50 if (listViewTouch.SelectedItems.Count == 1) 51 { 52 return listViewTouch.SelectedItems[0]; 53 } 54 55 return null; 56 } 57 // ReSharper disable once UnusedMember.Local 58 set 59 { 60 foreach (ListViewItem item in listViewTouch.Items.OfType<ListViewItem>().Where(x => x.Selected)) 61 { 62 item.Selected = false; 63 } 64 65 if (value != null) 66 { 67 value.Selected = true; 68 } 69 } 70 } 71 FormTouch(TouchElementViewModel touch)72 internal FormTouch(TouchElementViewModel touch) 73 { 74 disposable = new CompositeDisposable(); 75 CompositeDisposable listItemDisposable = new CompositeDisposable().AddTo(disposable); 76 CompositeDisposable entryDisposable = new CompositeDisposable().AddTo(disposable); 77 78 this.touch = touch; 79 80 InitializeComponent(); 81 82 touch.TreeItem 83 .BindTo( 84 this, 85 x => x.TreeViewTouchTopNode, 86 BindingMode.OneWay, 87 FormEditor.TreeViewItemViewModelToTreeNode 88 ) 89 .AddTo(disposable); 90 91 touch.SelectedTreeItem 92 .BindTo( 93 treeViewTouch, 94 x => x.SelectedNode, 95 BindingMode.TwoWay, 96 x => treeViewTouch.Nodes.OfType<TreeNode>().Select(y => FormEditor.SearchTreeNode(x, y)).FirstOrDefault(y => y != null), 97 x => (TreeViewItemViewModel)x.Tag, 98 Observable.FromEvent<TreeViewEventHandler, TreeViewEventArgs>( 99 h => (s, e) => h(e), 100 h => treeViewTouch.AfterSelect += h, 101 h => treeViewTouch.AfterSelect -= h 102 ) 103 .ToUnit() 104 ) 105 .AddTo(disposable); 106 107 touch.SelectedTreeItem 108 .BindTo( 109 listViewTouch, 110 x => x.Enabled, 111 BindingMode.OneWay, 112 x => touch.TreeItem.Value.Children.Contains(x) 113 ) 114 .AddTo(disposable); 115 116 touch.ListColumns 117 .ObserveAddChanged() 118 .Subscribe(x => 119 { 120 listViewTouch.Columns.Add(FormEditor.ListViewColumnHeaderViewModelToColumnHeader(x)); 121 listViewTouch.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize); 122 }) 123 .AddTo(disposable); 124 125 touch.ListColumns 126 .ObserveRemoveChanged() 127 .Subscribe(y => 128 { 129 foreach (ColumnHeader column in listViewTouch.Columns.OfType<ColumnHeader>().Where(z => z.Tag == y).ToArray()) 130 { 131 listViewTouch.Columns.Remove(column); 132 } 133 134 listViewTouch.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize); 135 }) 136 .AddTo(disposable); 137 138 touch.ListColumns 139 .ObserveResetChanged() 140 .Subscribe(_ => 141 { 142 listViewTouch.Columns.Clear(); 143 listViewTouch.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize); 144 }) 145 .AddTo(disposable); 146 147 touch.ListItems 148 .ObserveAddChanged() 149 .Subscribe(x => 150 { 151 listViewTouch.Items.Add(FormEditor.ListViewItemViewModelToListViewItem(x)); 152 listViewTouch.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize); 153 }) 154 .AddTo(disposable); 155 156 touch.ListItems 157 .ObserveRemoveChanged() 158 .Subscribe(x => 159 { 160 foreach (ListViewItem item in listViewTouch.Items.OfType<ListViewItem>().Where(y => y.Tag == x).ToArray()) 161 { 162 listViewTouch.Items.Remove(item); 163 } 164 165 listViewTouch.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize); 166 }) 167 .AddTo(disposable); 168 169 touch.ListItems 170 .ObserveResetChanged() 171 .Subscribe(_ => 172 { 173 listViewTouch.Items.Clear(); 174 listViewTouch.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize); 175 }) 176 .AddTo(disposable); 177 178 touch.SelectedListItem 179 .BindTo( 180 this, 181 x => x.ListViewTouchSelectedItem, 182 BindingMode.TwoWay, 183 x => listViewTouch.Items.OfType<ListViewItem>().FirstOrDefault(y => y.Tag == x), 184 x => (ListViewItemViewModel)x?.Tag, 185 Observable.FromEvent<EventHandler, EventArgs>( 186 h => (s, e) => h(e), 187 h => listViewTouch.SelectedIndexChanged += h, 188 h => listViewTouch.SelectedIndexChanged -= h 189 ) 190 .ToUnit() 191 ) 192 .AddTo(disposable); 193 194 touch.SelectedListItem 195 .Where(x => x != null) 196 .Subscribe(x => 197 { 198 listItemDisposable.Dispose(); 199 listItemDisposable = new CompositeDisposable().AddTo(disposable); 200 201 x.Texts 202 .ObserveReplaceChanged() 203 .Subscribe(_ => 204 { 205 FormEditor.UpdateListViewItem(ListViewTouchSelectedItem, touch.SelectedListItem.Value); 206 listViewTouch.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize); 207 }) 208 .AddTo(listItemDisposable); 209 }) 210 .AddTo(disposable); 211 212 touch.SelectedSoundEntry 213 .BindTo( 214 groupBoxTouchSound, 215 x => x.Enabled, 216 x => x != null 217 ) 218 .AddTo(disposable); 219 220 touch.SelectedSoundEntry 221 .Where(x => x != null) 222 .Subscribe(x => 223 { 224 entryDisposable.Dispose(); 225 entryDisposable = new CompositeDisposable().AddTo(disposable); 226 227 BindToSoundEntry(x).AddTo(entryDisposable); 228 }) 229 .AddTo(disposable); 230 231 touch.SelectedCommandEntry 232 .BindTo( 233 groupBoxTouchCommand, 234 x => x.Enabled, 235 x => x != null 236 ) 237 .AddTo(disposable); 238 239 touch.SelectedCommandEntry 240 .Where(x => x != null) 241 .Subscribe(x => 242 { 243 entryDisposable.Dispose(); 244 entryDisposable = new CompositeDisposable().AddTo(disposable); 245 246 BindToCommandEntry(x).AddTo(entryDisposable); 247 }) 248 .AddTo(disposable); 249 250 comboBoxTouchCommandName.Items 251 .AddRange( 252 Enum.GetValues(typeof(Translations.Command)) 253 .OfType<Translations.Command>() 254 .Select(c => Translations.CommandInfos.TryGetInfo(c).Name) 255 .OfType<object>() 256 .ToArray() 257 ); 258 259 new[] { touch.AddSoundEntry, touch.AddCommandEntry } 260 .BindToButton(buttonTouchAdd) 261 .AddTo(disposable); 262 263 new[] { touch.CopySoundEntry, touch.CopyCommandEntry } 264 .BindToButton(buttonTouchCopy) 265 .AddTo(disposable); 266 267 new[] { touch.RemoveSoundEntry, touch.RemoveCommandEntry } 268 .BindToButton(buttonTouchRemove) 269 .AddTo(disposable); 270 } 271 FormTouch_Load(object sender, EventArgs e)272 private void FormTouch_Load(object sender, EventArgs e) 273 { 274 Icon = FormEditor.GetIcon(); 275 } 276 ButtonOK_Click(object sender, EventArgs e)277 private void ButtonOK_Click(object sender, EventArgs e) 278 { 279 ListViewTouchSelectedItem = null; 280 treeViewTouch.SelectedNode = TreeViewTouchTopNode; 281 282 Close(); 283 } 284 BindToSoundEntry(TouchElementViewModel.SoundEntryViewModel entry)285 private IDisposable BindToSoundEntry(TouchElementViewModel.SoundEntryViewModel entry) 286 { 287 CompositeDisposable entryDisposable = new CompositeDisposable(); 288 289 entry.Index 290 .BindTo( 291 numericUpDownTouchSoundIndex, 292 x => x.Value, 293 BindingMode.TwoWay, 294 null, 295 x => (int)x, 296 Observable.FromEvent<EventHandler, EventArgs>( 297 h => (s, e) => h(e), 298 h => numericUpDownTouchSoundIndex.ValueChanged += h, 299 h => numericUpDownTouchSoundIndex.ValueChanged -= h 300 ) 301 .ToUnit() 302 ) 303 .AddTo(entryDisposable); 304 305 return entryDisposable; 306 } 307 BindToCommandEntry(TouchElementViewModel.CommandEntryViewModel entry)308 private IDisposable BindToCommandEntry(TouchElementViewModel.CommandEntryViewModel entry) 309 { 310 CompositeDisposable entryDisposable = new CompositeDisposable(); 311 312 entry.Info 313 .BindTo( 314 comboBoxTouchCommandName, 315 x => x.SelectedIndex, 316 BindingMode.TwoWay, 317 x => (int)x.Command, 318 x => Translations.CommandInfos.TryGetInfo((Translations.Command)x), 319 Observable.FromEvent<EventHandler, EventArgs>( 320 h => (s, e) => h(e), 321 h => comboBoxTouchCommandName.SelectedIndexChanged += h, 322 h => comboBoxTouchCommandName.SelectedIndexChanged -= h 323 ) 324 .ToUnit() 325 ) 326 .AddTo(entryDisposable); 327 328 entry.Option 329 .BindTo( 330 numericUpDownTouchCommandOption, 331 x => x.Value, 332 BindingMode.TwoWay, 333 null, 334 x => (int)x, 335 Observable.FromEvent<EventHandler, EventArgs>( 336 h => (s, e) => h(e), 337 h => numericUpDownTouchCommandOption.ValueChanged += h, 338 h => numericUpDownTouchCommandOption.ValueChanged -= h 339 ) 340 .ToUnit() 341 ) 342 .AddTo(entryDisposable); 343 344 return entryDisposable; 345 } 346 } 347 } 348