MapSettingsDialog.cs (6104B)
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.Controls; 16 using MobiusEditor.Interface; 17 using MobiusEditor.Model; 18 using MobiusEditor.Utility; 19 using System; 20 using System.Collections.Generic; 21 using System.Data; 22 using System.Drawing; 23 using System.Linq; 24 using System.Runtime.InteropServices; 25 using System.Windows.Forms; 26 27 namespace MobiusEditor.Dialogs 28 { 29 public partial class MapSettingsDialog : Form 30 { 31 private const int TVIF_STATE = 0x8; 32 private const int TVIS_STATEIMAGEMASK = 0xF000; 33 private const int TV_FIRST = 0x1100; 34 private const int TVM_SETITEM = TV_FIRST + 63; 35 36 [DllImport("user32.dll")] 37 static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); 38 39 private struct TVITEM 40 { 41 public int mask; 42 public IntPtr hItem; 43 public int state; 44 public int stateMask; 45 [MarshalAs(UnmanagedType.LPTStr)] 46 public String lpszText; 47 public int cchTextMax; 48 public int iImage; 49 public int iSelectedImage; 50 public int cChildren; 51 public IntPtr lParam; 52 } 53 54 private readonly IGamePlugin plugin; 55 private readonly PropertyTracker<BasicSection> basicSettingsTracker; 56 private readonly PropertyTracker<BriefingSection> briefingSettingsTracker; 57 private readonly IDictionary<House, PropertyTracker<House>> houseSettingsTrackers; 58 private readonly TreeNode playersNode; 59 60 public MapSettingsDialog(IGamePlugin plugin, PropertyTracker<BasicSection> basicSettingsTracker, PropertyTracker<BriefingSection> briefingSettingsTracker, 61 IDictionary<House, PropertyTracker<House>> houseSettingsTrackers) 62 { 63 InitializeComponent(); 64 65 this.plugin = plugin; 66 this.basicSettingsTracker = basicSettingsTracker; 67 this.briefingSettingsTracker = briefingSettingsTracker; 68 this.houseSettingsTrackers = houseSettingsTrackers; 69 70 settingsTreeView.BeginUpdate(); 71 settingsTreeView.Nodes.Clear(); 72 settingsTreeView.Nodes.Add("BASIC", "Basic"); 73 settingsTreeView.Nodes.Add("BRIEFING", "Briefing"); 74 75 playersNode = settingsTreeView.Nodes.Add("Players"); 76 foreach (var player in plugin.Map.Houses) 77 { 78 var playerNode = playersNode.Nodes.Add(player.Type.Name, player.Type.Name); 79 playerNode.Checked = player.Enabled; 80 } 81 playersNode.Expand(); 82 83 settingsTreeView.EndUpdate(); 84 settingsTreeView.SelectedNode = settingsTreeView.Nodes[0]; 85 } 86 87 private void settingsTreeView_AfterSelect(object sender, TreeViewEventArgs e) 88 { 89 settingsPanel.Controls.Clear(); 90 91 switch (settingsTreeView.SelectedNode.Name) 92 { 93 case "BASIC": 94 { 95 settingsPanel.Controls.Add(new BasicSettings(plugin, basicSettingsTracker)); 96 } 97 break; 98 case "BRIEFING": 99 { 100 settingsPanel.Controls.Add(new BriefingSettings(plugin, briefingSettingsTracker)); 101 } 102 break; 103 default: 104 { 105 var player = plugin.Map.Houses.Where(h => h.Type.Name == settingsTreeView.SelectedNode.Name).FirstOrDefault(); 106 if (player != null) 107 { 108 settingsPanel.Controls.Add(new PlayerSettings(plugin, houseSettingsTrackers[player])); 109 } 110 } 111 break; 112 } 113 } 114 115 private void settingsTreeView_DrawNode(object sender, DrawTreeNodeEventArgs e) 116 { 117 if (!playersNode.Nodes.Contains(e.Node)) 118 { 119 HideCheckBox(e.Node); 120 e.DrawDefault = true; 121 } 122 else 123 { 124 e.Graphics.DrawString(e.Node.Text, e.Node.TreeView.Font, new SolidBrush(settingsTreeView.ForeColor), e.Node.Bounds.X, e.Node.Bounds.Y); 125 } 126 } 127 128 private void HideCheckBox(TreeNode node) 129 { 130 TVITEM tvi = new TVITEM 131 { 132 hItem = node.Handle, 133 mask = TVIF_STATE, 134 stateMask = TVIS_STATEIMAGEMASK, 135 state = 0, 136 lpszText = null, 137 cchTextMax = 0, 138 iImage = 0, 139 iSelectedImage = 0, 140 cChildren = 0, 141 lParam = IntPtr.Zero 142 }; 143 IntPtr lparam = Marshal.AllocHGlobal(Marshal.SizeOf(tvi)); 144 Marshal.StructureToPtr(tvi, lparam, false); 145 SendMessage(node.TreeView.Handle, TVM_SETITEM, IntPtr.Zero, lparam); 146 } 147 148 private void settingsTreeView_AfterCheck(object sender, TreeViewEventArgs e) 149 { 150 var player = plugin.Map.Houses.Where(h => h.Type.Name == e.Node.Name).FirstOrDefault(); 151 if (player != null) 152 { 153 ((dynamic)houseSettingsTrackers[player]).Enabled = e.Node.Checked; 154 } 155 } 156 } 157 }