diff --git a/Source/Core/Actions/ActionManager.cs b/Source/Core/Actions/ActionManager.cs index 9f96aba0..346d161e 100755 --- a/Source/Core/Actions/ActionManager.cs +++ b/Source/Core/Actions/ActionManager.cs @@ -29,657 +29,647 @@ using System.Windows.Forms; namespace CodeImp.DoomBuilder.Actions { - public class ActionManager - { - #region ================== Constants - - private const string ACTIONS_RESOURCE = "Actions.cfg"; - - #endregion - - #region ================== Variables - - // Actions - private Dictionary actions; - - // Categories - private SortedDictionary categories; - - // Keys state - private int modifiers; - private List pressedkeys; - - // Begun actions - private List activeactions; - private Action currentaction; - - // Exclusive invokation - private bool exclusiverequested; - - // Disposing - private bool isdisposed; - - #endregion - - #region ================== Properties - - internal SortedDictionary Categories { get { return categories; } } - internal Action this[string action] { get { if (actions.ContainsKey(action)) return actions[action]; else throw new ArgumentException("There is no such action \"" + action + "\""); } } - public bool IsDisposed { get { return isdisposed; } } - internal bool ExclusiveRequested { get { return exclusiverequested; } } - - /// - /// Current executing action. This returns Null when no action is invoked. - /// - public Action Current { get { return currentaction; } internal set { currentaction = value; } } - - #endregion - - #region ================== Constructor / Disposer - - // Constructor - internal ActionManager() - { - // Initialize - General.WriteLogLine("Starting action manager..."); - actions = new Dictionary(); - pressedkeys = new List(); - activeactions = new List(); - categories = new SortedDictionary(); - - // Load all actions in this assembly - LoadActions(General.ThisAssembly); - - // We have no destructor - GC.SuppressFinalize(this); - } - - // Disposer - internal void Dispose() - { - // Not already disposed? - if (!isdisposed) - { - // Clean up - - // Done - isdisposed = true; - } - } - - #endregion - - #region ================== Actions - - // This loads all actions from an assembly - internal void LoadActions(Assembly asm) - { - AssemblyName asmname = asm.GetName(); - - // Find a resource named Actions.cfg - string[] resnames = asm.GetManifestResourceNames(); - foreach (string rn in resnames) - { - // Found one? - if (rn.EndsWith(ACTIONS_RESOURCE, StringComparison.OrdinalIgnoreCase)) - { - // Get a stream from the resource - Stream actionsdata = asm.GetManifestResourceStream(rn); - StreamReader actionsreader = new StreamReader(actionsdata, Encoding.ASCII); - - // Load configuration from stream - Configuration cfg = new Configuration(); - cfg.InputConfiguration(actionsreader.ReadToEnd()); - if (cfg.ErrorResult) - { - string errordesc = "Error in Actions configuration on line " + cfg.ErrorLine + ": " + cfg.ErrorDescription; - General.CancelAutoMapLoad(); - General.ErrorLogger.Add(ErrorType.Error, "Unable to read Actions configuration from assembly " + Path.GetFileName(asm.Location)); - General.WriteLogLine(errordesc); - General.ShowErrorMessage("Unable to read Actions configuration from assembly " + Path.GetFileName(asm.Location) + "!\n" + errordesc, MessageBoxButtons.OK); - } - else - { - // Read the categories structure - IDictionary cats = cfg.ReadSetting("categories", new Hashtable()); - foreach (DictionaryEntry c in cats) - { - // Make the category if not already added - if (!categories.ContainsKey(c.Key.ToString())) - categories.Add(c.Key.ToString(), c.Value.ToString()); - } - - // Go for all objects in the configuration - foreach (DictionaryEntry a in cfg.Root) - { - // Get action properties - string shortname = a.Key.ToString(); - string name = asmname.Name.ToLowerInvariant() + "_" + shortname; - bool debugonly = cfg.ReadSetting(a.Key + ".debugonly", false); - - // Not the categories structure? - if (shortname.ToLowerInvariant() != "categories") - { - // Check if action should be included - if (General.DebugBuild || !debugonly) - { - // Create an action - CreateAction(cfg, name, shortname); - } - } - } - } - - // Done with the resource - actionsreader.Dispose(); - break; //mxd. Usually we have a single "Actions.cfg", right? - } - } - } - - // This manually creates an action - private void CreateAction(Configuration cfg, string name, string shortname) - { - // Action does not exist yet? - if (!actions.ContainsKey(name)) - { - // Read the key from configuration - int key = General.Settings.ReadSetting("shortcuts." + name, -1); - - // Create an action - actions.Add(name, new Action(cfg, name, shortname, key)); - } - else - { - // Action already exists! - General.ErrorLogger.Add(ErrorType.Warning, "Action \"" + name + "\" already exists. Action names must be unique."); - } - } - - // This binds all methods marked with this attribute - public void BindMethods(Type type) - { - // Bind static methods - BindMethods(null, type); - } - - // This binds all methods marked with this attribute - public void BindMethods(object obj) - { - // Bind instance methods - BindMethods(obj, obj.GetType()); - } - - // This binds all methods marked with this attribute - private void BindMethods(object obj, Type type) - { - if (obj == null) - General.WriteLogLine("Binding static action methods for class " + type.Name + "..."); - else - General.WriteLogLine("Binding action methods for " + type.Name + " object..."); - - // Go for all methods on obj - MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static); - //foreach(MethodInfo m in methods) - int methodsCount = methods.Length; - for (int i = 0; i < methodsCount; i++) - { - MethodInfo m = methods[i]; - // Check if the method has this attribute - ActionAttribute[] attrs = (ActionAttribute[])methods[i].GetCustomAttributes(typeof(BeginActionAttribute), true); - - int attrsCount = attrs.Length; - // Go for all attributes - //foreach(ActionAttribute a in attrs) - for (int j = 0; j < attrsCount; j++) - { - ActionAttribute a = attrs[j]; - - // Create a delegate for this method - ActionDelegate del = (ActionDelegate)Delegate.CreateDelegate(typeof(ActionDelegate), obj, m); - - // Make proper name - string actionname = a.GetFullActionName(type.Assembly); - - // Bind method to action - if (Exists(actionname)) - actions[actionname].BindBegin(del); - else - throw new ArgumentException("Could not bind " + m.ReflectedType.Name + "." + m.Name + " to action \"" + actionname + "\", that action does not exist! Refer to, or edit Actions.cfg for all available application actions."); - } - - // Check if the method has this attribute - attrs = (ActionAttribute[])m.GetCustomAttributes(typeof(EndActionAttribute), true); - attrsCount = attrs.Length; - // Go for all attributes - //foreach (ActionAttribute a in attrs) - for (int j = 0; j < attrsCount; j++) - { - ActionAttribute a = attrs[j]; - - // Create a delegate for this method - ActionDelegate del = (ActionDelegate)Delegate.CreateDelegate(typeof(ActionDelegate), obj, m); - - // Make proper name - string actionname = a.GetFullActionName(type.Assembly); - - // Bind method to action - if (Exists(actionname)) - actions[actionname].BindEnd(del); - else - throw new ArgumentException("Could not bind " + m.ReflectedType.Name + "." + m.Name + " to action \"" + actionname + "\", that action does not exist. Refer to, or edit Actions.cfg for all available application actions."); - } - } - } - - // This binds a delegate manually - internal void BindBeginDelegate(Assembly asm, ActionDelegate d, BeginActionAttribute a) - { - // Make proper name - string actionname = a.GetFullActionName(asm); - - // Bind delegate to action - if (Exists(actionname)) - actions[actionname].BindBegin(d); - else - General.ErrorLogger.Add(ErrorType.Warning, "Could not bind delegate for " + d.Method.Name + " to action \"" + a.ActionName + "\" (" + actionname + "), that action does not exist. Refer to, or edit Actions.cfg for all available application actions."); - } - - // This binds a delegate manually - internal void BindEndDelegate(Assembly asm, ActionDelegate d, EndActionAttribute a) - { - // Make proper name - string actionname = a.GetFullActionName(asm); - - // Bind delegate to action - if (Exists(actionname)) - actions[actionname].BindEnd(d); - else - General.ErrorLogger.Add(ErrorType.Warning, "Could not bind delegate for " + d.Method.Name + " to action \"" + a.ActionName + "\" (" + actionname + "), that action does not exist. Refer to, or edit Actions.cfg for all available application actions."); - } - - // This unbinds all methods marked with this attribute - public void UnbindMethods(Type type) - { - // Unbind static methods - UnbindMethods(null, type); - } - - // This unbinds all methods marked with this attribute - public void UnbindMethods(object obj) - { - // Unbind instance methods - UnbindMethods(obj, obj.GetType()); - } - - // This unbinds all methods marked with this attribute - private void UnbindMethods(object obj, Type type) - { - if (obj == null) - General.WriteLogLine("Unbinding static action methods for class " + type.Name + "..."); - else - General.WriteLogLine("Unbinding action methods for " + type.Name + " object..."); - - // Go for all methods on obj - MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static); - foreach (MethodInfo m in methods) - { - // Check if the method has this attribute - ActionAttribute[] attrs = (ActionAttribute[])m.GetCustomAttributes(typeof(BeginActionAttribute), true); - - // Go for all attributes - foreach (ActionAttribute a in attrs) - { - // Create a delegate for this method - ActionDelegate del = (ActionDelegate)Delegate.CreateDelegate(typeof(ActionDelegate), obj, m); - - // Make proper name - string actionname = a.GetFullActionName(type.Assembly); - - // Unbind method from action - actions[actionname].UnbindBegin(del); - } - - // Check if the method has this attribute - attrs = (ActionAttribute[])m.GetCustomAttributes(typeof(EndActionAttribute), true); - - // Go for all attributes - foreach (ActionAttribute a in attrs) - { - // Create a delegate for this method - ActionDelegate del = (ActionDelegate)Delegate.CreateDelegate(typeof(ActionDelegate), obj, m); - - // Make proper name - string actionname = a.GetFullActionName(type.Assembly); - - // Unbind method from action - actions[actionname].UnbindEnd(del); - } - } - } - - // This unbinds a delegate manually - internal void UnbindBeginDelegate(Assembly asm, ActionDelegate d, BeginActionAttribute a) - { - // Make proper name - string actionname = a.GetFullActionName(asm); - - // Unbind delegate to action - actions[actionname].UnbindBegin(d); - } - - // This unbinds a delegate manually - internal void UnbindEndDelegate(Assembly asm, ActionDelegate d, EndActionAttribute a) - { - // Make proper name - string actionname = a.GetFullActionName(asm); - - // Unbind delegate to action - actions[actionname].UnbindEnd(d); - } - - // This checks if a given action exists - public bool Exists(string action) - { - return actions.ContainsKey(action); - } - - // This returns a list of all actions - internal Action[] GetAllActions() - { - Action[] list = new Action[actions.Count]; - actions.Values.CopyTo(list, 0); - return list; - } - - // This returns the specified action - public Action GetActionByName(string fullname) - { - return actions[fullname]; - } - - // This saves the control settings - internal void SaveSettings() - { - // Go for all actions - foreach (KeyValuePair a in actions) - { - // Write to configuration - General.Settings.WriteSetting("shortcuts." + a.Key, a.Value.ShortcutKey); - } - } - - // This invokes the Begin and End of the given action - public bool InvokeAction(string actionname) - { - if (Exists(actionname)) - { - actions[actionname].Invoke(); - return true; - } - return false; - } - - #endregion - - #region ================== Shortcut Keys - - // This applies default keys if they are not already in use - internal void ApplyDefaultShortcutKeys() - { - // Find actions that have no key set - foreach (KeyValuePair a in actions) - { - // Key set? - if (a.Value.ShortcutKey == -1) - { - // Check if the default key is not already used - bool keyused = false; - foreach (KeyValuePair d in actions) - { - // Check if the keys are the same - // Note that I use the mask of the source action to check if they match any combination - if ((d.Value.ShortcutKey & a.Value.ShortcutMask) == (a.Value.DefaultShortcutKey & a.Value.ShortcutMask)) - { - // No party. - keyused = true; - break; - } - } - - // Party? - if (!keyused) - { - // Apply the default key - a.Value.SetShortcutKey(a.Value.DefaultShortcutKey); - } - else - { - // No party. - a.Value.SetShortcutKey(0); - } - } - } - } - - // This checks if a given action is active - public bool CheckActionActive(Assembly asm, string actionname) - { - if (asm == null) asm = General.ThisAssembly; - - // Find active action - string fullname = asm.GetName().Name.ToLowerInvariant() + "_" + actionname; - foreach (Action a in activeactions) - { - if (a.Name == fullname) return true; - } - - // No such active action - return false; - } - - // Removes all shortcut keys - internal void RemoveShortcutKeys() - { - // Clear all keys - foreach (KeyValuePair a in actions) - a.Value.SetShortcutKey(0); - } - - // This notifies a key has been pressed - // Returns true when the key press has been absorbed - internal bool KeyPressed(int key) - { - int strippedkey = key & ~((int)Keys.Alt | (int)Keys.Shift | (int)Keys.Control); - if ((strippedkey == (int)Keys.ShiftKey) || (strippedkey == (int)Keys.ControlKey) || (strippedkey == (int)Keys.Alt)) key = strippedkey; - bool repeat = pressedkeys.Contains(strippedkey); - - // Update pressed keys - if (!repeat) pressedkeys.Add(strippedkey); - - // Add action to active list - Action[] acts = GetActionsByKey(key); - bool absorbed = acts.Length > 0; - foreach (Action a in acts) if (!activeactions.Contains(a)) activeactions.Add(a); - - // Invoke actions - absorbed |= BeginActionByKey(key, repeat); - - return absorbed; - } - - // This notifies a key has been released - // Returns true when the key release has been absorbed - internal bool KeyReleased(int key) - { - int strippedkey = key & ~((int)Keys.Alt | (int)Keys.Shift | (int)Keys.Control); - - // Update pressed keys - if (pressedkeys.Contains(strippedkey)) pressedkeys.Remove(strippedkey); - - // End actions that no longer match - return EndActiveActions(); - } - - // This releases all pressed keys - internal void ReleaseAllKeys() - { - // Clear pressed keys - pressedkeys.Clear(); - - // End actions - EndActiveActions(); - } - - // This updates the modifiers - internal void UpdateModifiers(int mods) - { - // Update modifiers - modifiers = mods; - - // End actions that no longer match - EndActiveActions(); - } - - // This will call the associated actions for a keypress - // Returns true when the key invokes any action - internal bool BeginActionByKey(int key, bool repeated) - { - bool invoked = false; - - // Get all actions for which a begin is bound - List boundactions = new List(actions.Count); - foreach (KeyValuePair a in actions) - if (a.Value.BeginBound) boundactions.Add(a.Value); - - // Go for all actions - foreach (Action a in boundactions) - { - // This action is associated with this key? - if (a.KeyMatches(key)) - { - invoked = true; - - // Allowed to repeat? - if (a.Repeat || !repeated) - { - // Invoke action - a.Begin(); - } - else - { - //General.WriteLogLine("Action \"" + a.Value.Name + "\" failed because it does not support repeating activation!"); - } - } - } - - return invoked; - } - - // This will end active actions for which the pressed keys do not match - // Returns true when actions have been ended - private bool EndActiveActions() - { - bool listchanged; - bool actionsended = false; - - do - { - // Go for all active actions - listchanged = false; - for (int i = 0; i < activeactions.Count; i++) - { - Action a = activeactions[i]; - - // Go for all pressed keys - bool stillactive = false; - foreach (int k in pressedkeys) - { - if ((k == (int)Keys.ShiftKey) || (k == (int)Keys.ControlKey)) - stillactive |= a.KeyMatches(k); - else - stillactive |= a.KeyMatches(k | modifiers); - } - - // End the action if no longer matches any of the keys - if (!stillactive) - { - actionsended = true; - activeactions.RemoveAt(i); - listchanged = true; - a.End(); - break; - } - } - } - while (listchanged); - - return actionsended; - } - - // This returns all action names for a given key - public string[] GetActionNamesByKey(int key) - { - List actionnames = new List(); - - // Go for all actions - foreach (KeyValuePair a in actions) - { - // This action is associated with this key? - if (a.Value.KeyMatches(key)) - { - // List short name - actionnames.Add(a.Value.ShortName); - } - } - - // Return result; - return actionnames.ToArray(); - } - - // This returns all action names for a given key - public Action[] GetActionsByKey(int key) - { - List actionnames = new List(); - - // Go for all actions - foreach (KeyValuePair a in actions) - { - // This action is associated with this key? - if (a.Value.KeyMatches(key)) - { - // List short name - actionnames.Add(a.Value); - } - } - - // Return result; - return actionnames.ToArray(); - } - - #endregion - - #region ================== Exclusive Invokation - - // This resets the exclusive request - internal void ResetExclusiveRequest() - { - exclusiverequested = false; - } - - /// - /// This asks for exclusive invokation of the current BeginAction or EndAction. - /// Returns true when successull, false when denied (already given to another caller) - /// - public bool RequestExclusiveInvokation() - { - if (exclusiverequested) return false; // Already given out - - // Success - exclusiverequested = true; - return true; - } - - #endregion - } + public class ActionManager + { + #region ================== Constants + + private const string ACTIONS_RESOURCE = "Actions.cfg"; + + #endregion + + #region ================== Variables + + // Actions + private Dictionary actions; + + // Categories + private SortedDictionary categories; + + // Keys state + private int modifiers; + private List pressedkeys; + + // Begun actions + private List activeactions; + private Action currentaction; + + // Exclusive invokation + private bool exclusiverequested; + + // Disposing + private bool isdisposed; + + #endregion + + #region ================== Properties + + internal SortedDictionary Categories { get { return categories; } } + internal Action this[string action] { get { if(actions.ContainsKey(action)) return actions[action]; else throw new ArgumentException("There is no such action \"" + action + "\""); } } + public bool IsDisposed { get { return isdisposed; } } + internal bool ExclusiveRequested { get { return exclusiverequested; } } + + /// + /// Current executing action. This returns Null when no action is invoked. + /// + public Action Current { get { return currentaction; } internal set { currentaction = value; } } + + #endregion + + #region ================== Constructor / Disposer + + // Constructor + internal ActionManager() + { + // Initialize + General.WriteLogLine("Starting action manager..."); + actions = new Dictionary(); + pressedkeys = new List(); + activeactions = new List(); + categories = new SortedDictionary(); + + // Load all actions in this assembly + LoadActions(General.ThisAssembly); + + // We have no destructor + GC.SuppressFinalize(this); + } + + // Disposer + internal void Dispose() + { + // Not already disposed? + if(!isdisposed) + { + // Clean up + + // Done + isdisposed = true; + } + } + + #endregion + + #region ================== Actions + + // This loads all actions from an assembly + internal void LoadActions(Assembly asm) + { + AssemblyName asmname = asm.GetName(); + + // Find a resource named Actions.cfg + string[] resnames = asm.GetManifestResourceNames(); + foreach(string rn in resnames) + { + // Found one? + if(rn.EndsWith(ACTIONS_RESOURCE, StringComparison.OrdinalIgnoreCase)) + { + // Get a stream from the resource + Stream actionsdata = asm.GetManifestResourceStream(rn); + StreamReader actionsreader = new StreamReader(actionsdata, Encoding.ASCII); + + // Load configuration from stream + Configuration cfg = new Configuration(); + cfg.InputConfiguration(actionsreader.ReadToEnd()); + if(cfg.ErrorResult) + { + string errordesc = "Error in Actions configuration on line " + cfg.ErrorLine + ": " + cfg.ErrorDescription; + General.CancelAutoMapLoad(); + General.ErrorLogger.Add(ErrorType.Error, "Unable to read Actions configuration from assembly " + Path.GetFileName(asm.Location)); + General.WriteLogLine(errordesc); + General.ShowErrorMessage("Unable to read Actions configuration from assembly " + Path.GetFileName(asm.Location) + "!\n" + errordesc, MessageBoxButtons.OK); + } + else + { + // Read the categories structure + IDictionary cats = cfg.ReadSetting("categories", new Hashtable()); + foreach(DictionaryEntry c in cats) + { + // Make the category if not already added + if(!categories.ContainsKey(c.Key.ToString())) + categories.Add(c.Key.ToString(), c.Value.ToString()); + } + + // Go for all objects in the configuration + foreach(DictionaryEntry a in cfg.Root) + { + // Get action properties + string shortname = a.Key.ToString(); + string name = asmname.Name.ToLowerInvariant() + "_" + shortname; + bool debugonly = cfg.ReadSetting(a.Key + ".debugonly", false); + + // Not the categories structure? + if(shortname.ToLowerInvariant() != "categories") + { + // Check if action should be included + if(General.DebugBuild || !debugonly) + { + // Create an action + CreateAction(cfg, name, shortname); + } + } + } + } + + // Done with the resource + actionsreader.Dispose(); + break; //mxd. Usually we have a single "Actions.cfg", right? + } + } + } + + // This manually creates an action + private void CreateAction(Configuration cfg, string name, string shortname) + { + // Action does not exist yet? + if(!actions.ContainsKey(name)) + { + // Read the key from configuration + int key = General.Settings.ReadSetting("shortcuts." + name, -1); + + // Create an action + actions.Add(name, new Action(cfg, name, shortname, key)); + } + else + { + // Action already exists! + General.ErrorLogger.Add(ErrorType.Warning, "Action \"" + name + "\" already exists. Action names must be unique."); + } + } + + // This binds all methods marked with this attribute + public void BindMethods(Type type) + { + // Bind static methods + BindMethods(null, type); + } + + // This binds all methods marked with this attribute + public void BindMethods(object obj) + { + // Bind instance methods + BindMethods(obj, obj.GetType()); + } + + // This binds all methods marked with this attribute + private void BindMethods(object obj, Type type) + { + if(obj == null) + General.WriteLogLine("Binding static action methods for class " + type.Name + "..."); + else + General.WriteLogLine("Binding action methods for " + type.Name + " object..."); + + // Go for all methods on obj + MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static); + foreach(MethodInfo m in methods) + { + // Check if the method has this attribute + ActionAttribute[] attrs = (ActionAttribute[])m.GetCustomAttributes(typeof(BeginActionAttribute), true); + + // Go for all attributes + foreach(ActionAttribute a in attrs) + { + // Create a delegate for this method + ActionDelegate del = (ActionDelegate)Delegate.CreateDelegate(typeof(ActionDelegate), obj, m); + + // Make proper name + string actionname = a.GetFullActionName(type.Assembly); + + // Bind method to action + if(Exists(actionname)) + actions[actionname].BindBegin(del); + else + throw new ArgumentException("Could not bind " + m.ReflectedType.Name + "." + m.Name + " to action \"" + actionname + "\", that action does not exist! Refer to, or edit Actions.cfg for all available application actions."); + } + + // Check if the method has this attribute + attrs = (ActionAttribute[])m.GetCustomAttributes(typeof(EndActionAttribute), true); + + // Go for all attributes + foreach(ActionAttribute a in attrs) + { + // Create a delegate for this method + ActionDelegate del = (ActionDelegate)Delegate.CreateDelegate(typeof(ActionDelegate), obj, m); + + // Make proper name + string actionname = a.GetFullActionName(type.Assembly); + + // Bind method to action + if(Exists(actionname)) + actions[actionname].BindEnd(del); + else + throw new ArgumentException("Could not bind " + m.ReflectedType.Name + "." + m.Name + " to action \"" + actionname + "\", that action does not exist. Refer to, or edit Actions.cfg for all available application actions."); + } + } + } + + // This binds a delegate manually + internal void BindBeginDelegate(Assembly asm, ActionDelegate d, BeginActionAttribute a) + { + // Make proper name + string actionname = a.GetFullActionName(asm); + + // Bind delegate to action + if(Exists(actionname)) + actions[actionname].BindBegin(d); + else + General.ErrorLogger.Add(ErrorType.Warning, "Could not bind delegate for " + d.Method.Name + " to action \"" + a.ActionName + "\" (" + actionname + "), that action does not exist. Refer to, or edit Actions.cfg for all available application actions."); + } + + // This binds a delegate manually + internal void BindEndDelegate(Assembly asm, ActionDelegate d, EndActionAttribute a) + { + // Make proper name + string actionname = a.GetFullActionName(asm); + + // Bind delegate to action + if(Exists(actionname)) + actions[actionname].BindEnd(d); + else + General.ErrorLogger.Add(ErrorType.Warning, "Could not bind delegate for " + d.Method.Name + " to action \"" + a.ActionName + "\" (" + actionname + "), that action does not exist. Refer to, or edit Actions.cfg for all available application actions."); + } + + // This unbinds all methods marked with this attribute + public void UnbindMethods(Type type) + { + // Unbind static methods + UnbindMethods(null, type); + } + + // This unbinds all methods marked with this attribute + public void UnbindMethods(object obj) + { + // Unbind instance methods + UnbindMethods(obj, obj.GetType()); + } + + // This unbinds all methods marked with this attribute + private void UnbindMethods(object obj, Type type) + { + if(obj == null) + General.WriteLogLine("Unbinding static action methods for class " + type.Name + "..."); + else + General.WriteLogLine("Unbinding action methods for " + type.Name + " object..."); + + // Go for all methods on obj + MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static); + foreach(MethodInfo m in methods) + { + // Check if the method has this attribute + ActionAttribute[] attrs = (ActionAttribute[])m.GetCustomAttributes(typeof(BeginActionAttribute), true); + + // Go for all attributes + foreach(ActionAttribute a in attrs) + { + // Create a delegate for this method + ActionDelegate del = (ActionDelegate)Delegate.CreateDelegate(typeof(ActionDelegate), obj, m); + + // Make proper name + string actionname = a.GetFullActionName(type.Assembly); + + // Unbind method from action + actions[actionname].UnbindBegin(del); + } + + // Check if the method has this attribute + attrs = (ActionAttribute[])m.GetCustomAttributes(typeof(EndActionAttribute), true); + + // Go for all attributes + foreach(ActionAttribute a in attrs) + { + // Create a delegate for this method + ActionDelegate del = (ActionDelegate)Delegate.CreateDelegate(typeof(ActionDelegate), obj, m); + + // Make proper name + string actionname = a.GetFullActionName(type.Assembly); + + // Unbind method from action + actions[actionname].UnbindEnd(del); + } + } + } + + // This unbinds a delegate manually + internal void UnbindBeginDelegate(Assembly asm, ActionDelegate d, BeginActionAttribute a) + { + // Make proper name + string actionname = a.GetFullActionName(asm); + + // Unbind delegate to action + actions[actionname].UnbindBegin(d); + } + + // This unbinds a delegate manually + internal void UnbindEndDelegate(Assembly asm, ActionDelegate d, EndActionAttribute a) + { + // Make proper name + string actionname = a.GetFullActionName(asm); + + // Unbind delegate to action + actions[actionname].UnbindEnd(d); + } + + // This checks if a given action exists + public bool Exists(string action) + { + return actions.ContainsKey(action); + } + + // This returns a list of all actions + internal Action[] GetAllActions() + { + Action[] list = new Action[actions.Count]; + actions.Values.CopyTo(list, 0); + return list; + } + + // This returns the specified action + public Action GetActionByName(string fullname) + { + return actions[fullname]; + } + + // This saves the control settings + internal void SaveSettings() + { + // Go for all actions + foreach(KeyValuePair a in actions) + { + // Write to configuration + General.Settings.WriteSetting("shortcuts." + a.Key, a.Value.ShortcutKey); + } + } + + // This invokes the Begin and End of the given action + public bool InvokeAction(string actionname) + { + if(Exists(actionname)) + { + actions[actionname].Invoke(); + return true; + } + return false; + } + + #endregion + + #region ================== Shortcut Keys + + // This applies default keys if they are not already in use + internal void ApplyDefaultShortcutKeys() + { + // Find actions that have no key set + foreach(KeyValuePair a in actions) + { + // Key set? + if(a.Value.ShortcutKey == -1) + { + // Check if the default key is not already used + bool keyused = false; + foreach(KeyValuePair d in actions) + { + // Check if the keys are the same + // Note that I use the mask of the source action to check if they match any combination + if((d.Value.ShortcutKey & a.Value.ShortcutMask) == (a.Value.DefaultShortcutKey & a.Value.ShortcutMask)) + { + // No party. + keyused = true; + break; + } + } + + // Party? + if(!keyused) + { + // Apply the default key + a.Value.SetShortcutKey(a.Value.DefaultShortcutKey); + } + else + { + // No party. + a.Value.SetShortcutKey(0); + } + } + } + } + + // This checks if a given action is active + public bool CheckActionActive(Assembly asm, string actionname) + { + if(asm == null) asm = General.ThisAssembly; + + // Find active action + string fullname = asm.GetName().Name.ToLowerInvariant() + "_" + actionname; + foreach(Action a in activeactions) + { + if(a.Name == fullname) return true; + } + + // No such active action + return false; + } + + // Removes all shortcut keys + internal void RemoveShortcutKeys() + { + // Clear all keys + foreach(KeyValuePair a in actions) + a.Value.SetShortcutKey(0); + } + + // This notifies a key has been pressed + // Returns true when the key press has been absorbed + internal bool KeyPressed(int key) + { + int strippedkey = key & ~((int)Keys.Alt | (int)Keys.Shift | (int)Keys.Control); + if((strippedkey == (int)Keys.ShiftKey) || (strippedkey == (int)Keys.ControlKey) || (strippedkey == (int)Keys.Alt)) key = strippedkey; + bool repeat = pressedkeys.Contains(strippedkey); + + // Update pressed keys + if(!repeat) pressedkeys.Add(strippedkey); + + // Add action to active list + Action[] acts = GetActionsByKey(key); + bool absorbed = acts.Length > 0; + foreach(Action a in acts) if(!activeactions.Contains(a)) activeactions.Add(a); + + // Invoke actions + absorbed |= BeginActionByKey(key, repeat); + + return absorbed; + } + + // This notifies a key has been released + // Returns true when the key release has been absorbed + internal bool KeyReleased(int key) + { + int strippedkey = key & ~((int)Keys.Alt | (int)Keys.Shift | (int)Keys.Control); + + // Update pressed keys + if(pressedkeys.Contains(strippedkey)) pressedkeys.Remove(strippedkey); + + // End actions that no longer match + return EndActiveActions(); + } + + // This releases all pressed keys + internal void ReleaseAllKeys() + { + // Clear pressed keys + pressedkeys.Clear(); + + // End actions + EndActiveActions(); + } + + // This updates the modifiers + internal void UpdateModifiers(int mods) + { + // Update modifiers + modifiers = mods; + + // End actions that no longer match + EndActiveActions(); + } + + // This will call the associated actions for a keypress + // Returns true when the key invokes any action + internal bool BeginActionByKey(int key, bool repeated) + { + bool invoked = false; + + // Get all actions for which a begin is bound + List boundactions = new List(actions.Count); + foreach(KeyValuePair a in actions) + if(a.Value.BeginBound) boundactions.Add(a.Value); + + // Go for all actions + foreach(Action a in boundactions) + { + // This action is associated with this key? + if(a.KeyMatches(key)) + { + invoked = true; + + // Allowed to repeat? + if(a.Repeat || !repeated) + { + // Invoke action + a.Begin(); + } + else + { + //General.WriteLogLine("Action \"" + a.Value.Name + "\" failed because it does not support repeating activation!"); + } + } + } + + return invoked; + } + + // This will end active actions for which the pressed keys do not match + // Returns true when actions have been ended + private bool EndActiveActions() + { + bool listchanged; + bool actionsended = false; + + do + { + // Go for all active actions + listchanged = false; + for(int i = 0; i < activeactions.Count; i++) + { + Action a = activeactions[i]; + + // Go for all pressed keys + bool stillactive = false; + foreach(int k in pressedkeys) + { + if((k == (int)Keys.ShiftKey) || (k == (int)Keys.ControlKey)) + stillactive |= a.KeyMatches(k); + else + stillactive |= a.KeyMatches(k | modifiers); + } + + // End the action if no longer matches any of the keys + if(!stillactive) + { + actionsended = true; + activeactions.RemoveAt(i); + listchanged = true; + a.End(); + break; + } + } + } + while(listchanged); + + return actionsended; + } + + // This returns all action names for a given key + public string[] GetActionNamesByKey(int key) + { + List actionnames = new List(); + + // Go for all actions + foreach(KeyValuePair a in actions) + { + // This action is associated with this key? + if(a.Value.KeyMatches(key)) + { + // List short name + actionnames.Add(a.Value.ShortName); + } + } + + // Return result; + return actionnames.ToArray(); + } + + // This returns all action names for a given key + public Action[] GetActionsByKey(int key) + { + List actionnames = new List(); + + // Go for all actions + foreach(KeyValuePair a in actions) + { + // This action is associated with this key? + if(a.Value.KeyMatches(key)) + { + // List short name + actionnames.Add(a.Value); + } + } + + // Return result; + return actionnames.ToArray(); + } + + #endregion + + #region ================== Exclusive Invokation + + // This resets the exclusive request + internal void ResetExclusiveRequest() + { + exclusiverequested = false; + } + + /// + /// This asks for exclusive invokation of the current BeginAction or EndAction. + /// Returns true when successull, false when denied (already given to another caller) + /// + public bool RequestExclusiveInvokation() + { + if(exclusiverequested) return false; // Already given out + + // Success + exclusiverequested = true; + return true; + } + + #endregion + } } diff --git a/Source/Core/Controls/PairedFieldsControl.cs b/Source/Core/Controls/PairedFieldsControl.cs index 6e86f700..f06f5a2b 100755 --- a/Source/Core/Controls/PairedFieldsControl.cs +++ b/Source/Core/Controls/PairedFieldsControl.cs @@ -108,18 +108,11 @@ namespace CodeImp.DoomBuilder.Controls private void CheckValues() { - if (blockUpdate) - { - changed = string.IsNullOrEmpty(value1.Text) || string.IsNullOrEmpty(value2.Text); - bReset.Visible = changed; - } - else - { - changed = string.IsNullOrEmpty(value1.Text) || string.IsNullOrEmpty(value2.Text) - || value1.GetResultFloat(defaultValue, 0) != defaultValue || value2.GetResultFloat(defaultValue, 0) != defaultValue; - bReset.Visible = changed; - if (OnValuesChanged != null) OnValuesChanged(this, EventArgs.Empty); - } + changed = string.IsNullOrEmpty(value1.Text) || string.IsNullOrEmpty(value2.Text) + || value1.GetResultFloat(defaultValue, 0) != defaultValue || value2.GetResultFloat(defaultValue, 0) != defaultValue; + bReset.Visible = changed; + + if(!blockUpdate && OnValuesChanged != null) OnValuesChanged(this, EventArgs.Empty); } private void UpdateButtons() diff --git a/Source/Core/General/General.cs b/Source/Core/General/General.cs index 1c07b617..abafd515 100755 --- a/Source/Core/General/General.cs +++ b/Source/Core/General/General.cs @@ -627,8 +627,7 @@ namespace CodeImp.DoomBuilder mainwindow = new MainForm(); mainwindow.SetupInterface(); mainwindow.UpdateInterface(); - mainwindow.UpdateSkills(); // ano - mainwindow.UpdateThingsFilters(); + mainwindow.UpdateThingsFilters(); if(!delaymainwindow) { @@ -1103,8 +1102,7 @@ namespace CodeImp.DoomBuilder mainwindow.UpdateThingsFilters(); mainwindow.UpdateLinedefColorPresets(); //mxd mainwindow.UpdateInterface(); - mainwindow.UpdateSkills(); // ano - mainwindow.AddHintsDocker(); //mxd + mainwindow.AddHintsDocker(); //mxd mainwindow.UpdateGZDoomPanel(); //mxd mainwindow.HideInfo(); //mxd } @@ -1178,8 +1176,7 @@ namespace CodeImp.DoomBuilder mainwindow.RemoveHintsDocker(); mainwindow.UpdateGZDoomPanel(); mainwindow.UpdateInterface(); - mainwindow.UpdateSkills(); // ano - mainwindow.DisplayReady(); + mainwindow.DisplayReady(); WriteLogLine("Map unload done"); return true; } @@ -1282,8 +1279,7 @@ namespace CodeImp.DoomBuilder mainwindow.UpdateThingsFilters(); mainwindow.UpdateLinedefColorPresets(); //mxd mainwindow.UpdateInterface(); - mainwindow.UpdateSkills(); // ano - mainwindow.HideInfo(); + mainwindow.HideInfo(); mainwindow.AddHintsDocker(); //mxd mainwindow.UpdateGZDoomPanel(); //mxd @@ -1359,8 +1355,7 @@ namespace CodeImp.DoomBuilder mainwindow.UpdateThingsFilters(); mainwindow.UpdateLinedefColorPresets(); //mxd mainwindow.UpdateInterface(); - mainwindow.UpdateSkills(); // ano - mainwindow.HideInfo(); + mainwindow.HideInfo(); mainwindow.AddHintsDocker(); //mxd //mxd. Center map in screen or on stored coordinates. Done here to avoid the view jerking around when updating the interface. @@ -1428,8 +1423,7 @@ namespace CodeImp.DoomBuilder // All done mainwindow.UpdateInterface(); - mainwindow.UpdateSkills(); // ano - return result; + return result; } // Display status @@ -1451,9 +1445,8 @@ namespace CodeImp.DoomBuilder // All done mainwindow.UpdateInterface(); - mainwindow.UpdateSkills(); // ano - if (errorlogger.IsErrorAdded) + if(errorlogger.IsErrorAdded) { // Show any errors if preferred mainwindow.DisplayStatus(StatusType.Warning, "There were errors during saving!"); @@ -1537,9 +1530,8 @@ namespace CodeImp.DoomBuilder // All done mainwindow.UpdateInterface(); - mainwindow.UpdateSkills(); // ano - - if (errorlogger.IsErrorAdded) + + if(errorlogger.IsErrorAdded) { // Show any errors if preferred mainwindow.DisplayStatus(StatusType.Warning, "There were errors during saving!"); @@ -1608,9 +1600,8 @@ namespace CodeImp.DoomBuilder // All done mainwindow.UpdateInterface(); - mainwindow.UpdateSkills(); // ano - if (errorlogger.IsErrorAdded) + if(errorlogger.IsErrorAdded) { // Show any errors if preferred mainwindow.DisplayStatus(StatusType.Warning, "There were errors during saving!"); diff --git a/Source/Core/General/MapManager.cs b/Source/Core/General/MapManager.cs index d7e4cbe0..bbba1e85 100755 --- a/Source/Core/General/MapManager.cs +++ b/Source/Core/General/MapManager.cs @@ -2393,10 +2393,9 @@ namespace CodeImp.DoomBuilder General.MainWindow.UpdateThingsFilters(); General.MainWindow.UpdateLinedefColorPresets(); //mxd General.MainWindow.UpdateInterface(); - General.MainWindow.UpdateSkills(); // ano - // Done - General.MainWindow.DisplayReady(); + // Done + General.MainWindow.DisplayReady(); General.MainWindow.RedrawDisplay(); //mxd } diff --git a/Source/Core/Properties/AssemblyInfo.cs b/Source/Core/Properties/AssemblyInfo.cs index 37333cc1..a87a3aae 100755 --- a/Source/Core/Properties/AssemblyInfo.cs +++ b/Source/Core/Properties/AssemblyInfo.cs @@ -30,6 +30,6 @@ using CodeImp.DoomBuilder; // Build Number // Revision // -[assembly: AssemblyVersion("2.3.0.2861")] +[assembly: AssemblyVersion("2.3.0.2859")] [assembly: NeutralResourcesLanguageAttribute("en")] -[assembly: AssemblyHash("a3ff16c")] +[assembly: AssemblyHash("5a5c6d0")] diff --git a/Source/Core/Windows/LinedefEditFormUDMF.cs b/Source/Core/Windows/LinedefEditFormUDMF.cs index d0677d3a..4a55b708 100755 --- a/Source/Core/Windows/LinedefEditFormUDMF.cs +++ b/Source/Core/Windows/LinedefEditFormUDMF.cs @@ -131,10 +131,22 @@ namespace CodeImp.DoomBuilder.Windows #region ================== Constructor - public LinedefEditFormUDMF() + public LinedefEditFormUDMF(bool selectfront, bool selectback) { // Initialize InitializeComponent(); + + // Widow setup + if(General.Settings.StoreSelectedEditTab) + { + int activetab = General.Settings.ReadSetting("windows." + configname + ".activetab", 0); + + // When front or back tab was previously selected, switch to appropriate side (selectfront/selectback are set in BaseVisualGeometrySidedef.OnEditEnd) + if((selectfront || selectback) && (activetab == 1 || activetab == 2)) + tabs.SelectTab(selectfront ? 1 : 2); + else + tabs.SelectTab(activetab); + } // Fill flags lists foreach(KeyValuePair lf in General.Map.Config.LinedefFlags) @@ -231,22 +243,9 @@ namespace CodeImp.DoomBuilder.Windows #region ================== Methods // This sets up the form to edit the given lines - public void Setup(ICollection lines, bool selectfront, bool selectback) + public void Setup(ICollection lines) { - // Window setup - // ano - moved this here because we don't reinstantiate the thing every time anymore - if (General.Settings.StoreSelectedEditTab) - { - int activetab = General.Settings.ReadSetting("windows." + configname + ".activetab", 0); - - // When front or back tab was previously selected, switch to appropriate side (selectfront/selectback are set in BaseVisualGeometrySidedef.OnEditEnd) - if ((selectfront || selectback) && (activetab == 1 || activetab == 2)) - tabs.SelectTab(selectfront ? 1 : 2); - else - tabs.SelectTab(activetab); - } - - preventchanges = true; + preventchanges = true; // Keep this list this.lines = lines; diff --git a/Source/Core/Windows/MainForm.cs b/Source/Core/Windows/MainForm.cs index 36d5f450..52be7cf6 100755 --- a/Source/Core/Windows/MainForm.cs +++ b/Source/Core/Windows/MainForm.cs @@ -176,17 +176,12 @@ namespace CodeImp.DoomBuilder.Windows //mxd. Misc drawing private Graphics graphics; + + #endregion - //ano, pool for windows - private DelayedForm sectorEditWindow; - private DelayedForm linedefEditWindow; - private DelayedForm thingEditWindow; + #region ================== Properties - #endregion - - #region ================== Properties - - public bool ShiftState { get { return shift; } } + public bool ShiftState { get { return shift; } } public bool CtrlState { get { return ctrl; } } public bool AltState { get { return alt; } } new public MouseButtons MouseButtons { get { return mousebuttons; } } @@ -402,50 +397,7 @@ namespace CodeImp.DoomBuilder.Windows if(General.Settings.CollapseDockers) dockerspanel.Collapse(); UnlockUpdate(); - - // ano - create windows on level load instead of whenever you click on something - if (sectorEditWindow != null) - { - sectorEditWindow.Dispose(); - } - if (linedefEditWindow != null) - { - linedefEditWindow.Dispose(); - } - if (thingEditWindow != null) - { - thingEditWindow.Dispose(); - } - if (General.Map.UDMF) - { - - SectorEditFormUDMF s = new SectorEditFormUDMF(); - s.OnValuesChanged += EditForm_OnValuesChanged; - sectorEditWindow = s; - - LinedefEditFormUDMF l = new LinedefEditFormUDMF(); - l.OnValuesChanged += EditForm_OnValuesChanged; - linedefEditWindow = l; - - ThingEditFormUDMF t = new ThingEditFormUDMF(); - t.OnValuesChanged += EditForm_OnValuesChanged; - thingEditWindow = t; - } - else - { - SectorEditForm s = new SectorEditForm(); - s.OnValuesChanged += EditForm_OnValuesChanged; - sectorEditWindow = s; - - LinedefEditForm l = new LinedefEditForm(); - l.OnValuesChanged += EditForm_OnValuesChanged; - linedefEditWindow = l; - - ThingEditForm t = new ThingEditForm(); - t.OnValuesChanged += EditForm_OnValuesChanged; - thingEditWindow = t; - } - } + } else { dockerspanel.Visible = false; @@ -480,7 +432,7 @@ namespace CodeImp.DoomBuilder.Windows UpdatePrefabsMenu(); UpdateToolsMenu(); UpdateToolbar(); - //UpdateSkills(); // ano - moved to places where level is loaded and etc + UpdateSkills(); UpdateHelpMenu(); } @@ -1263,9 +1215,9 @@ namespace CodeImp.DoomBuilder.Windows case MouseButtons.XButton1: key = (int)Keys.XButton1; break; case MouseButtons.XButton2: key = (int)Keys.XButton2; break; } - + // Invoke any actions associated with this key - General.Actions.KeyReleased(key | mod); + General.Actions.KeyReleased(key | mod); // Invoke on editing mode if((General.Map != null) && (General.Editing.Mode != null)) @@ -1526,25 +1478,20 @@ namespace CodeImp.DoomBuilder.Windows #region ================== Toolbar // This updates the skills list - // ano - made public in order to only call when map/prefs/gameconfigs are changed - // previously was called by undomanager which caused sluggishness - public void UpdateSkills() + private void UpdateSkills() { - // Clear list - buttontest.DropDownItems.Clear(); + // Clear list + buttontest.DropDownItems.Clear(); // Map loaded? if(General.Map != null) { - toolbar.SuspendLayout(); // Make the new items list List items = new List(General.Map.Config.Skills.Count * 2 + General.Map.ConfigSettings.TestEngines.Count + 2); - - // Positive skills are with monsters - int skillCount = General.Map.Config.Skills.Count; - for (int i = 0; i < skillCount; i++) + + // Positive skills are with monsters + foreach(SkillInfo si in General.Map.Config.Skills) { - SkillInfo si = General.Map.Config.Skills[i]; ToolStripMenuItem menuitem = new ToolStripMenuItem(si.ToString()); menuitem.Image = Resources.Monster2; menuitem.Click += TestSkill_Click; @@ -1556,11 +1503,10 @@ namespace CodeImp.DoomBuilder.Windows // Add seperator items.Add(new ToolStripSeparator { Padding = new Padding(0, 3, 0, 3) }); - // Negative skills are without monsters - for (int i = 0; i < skillCount; i++) - { - SkillInfo si = General.Map.Config.Skills[i]; - ToolStripMenuItem menuitem = new ToolStripMenuItem(si.ToString()); + // Negative skills are without monsters + foreach(SkillInfo si in General.Map.Config.Skills) + { + ToolStripMenuItem menuitem = new ToolStripMenuItem(si.ToString()); menuitem.Image = Resources.Monster3; menuitem.Click += TestSkill_Click; menuitem.Tag = -si.Index; @@ -1585,8 +1531,7 @@ namespace CodeImp.DoomBuilder.Windows // Add to list buttontest.DropDownItems.AddRange(items.ToArray()); - toolbar.ResumeLayout(false); - } + } } //mxd @@ -3371,9 +3316,7 @@ namespace CodeImp.DoomBuilder.Windows // Update stuff SetupInterface(); UpdateInterface(); - UpdateSkills(); - - General.Editing.UpdateCurrentEditModes(); + General.Editing.UpdateCurrentEditModes(); General.Plugins.ProgramReconfigure(); // Reload resources if a map is open @@ -3398,8 +3341,7 @@ namespace CodeImp.DoomBuilder.Windows // Update stuff SetupInterface(); UpdateInterface(); - UpdateSkills(); - ApplyShortcutKeys(); + ApplyShortcutKeys(); General.Colors.CreateCorrectionTable(); General.Plugins.ProgramReconfigure(); @@ -3982,27 +3924,27 @@ namespace CodeImp.DoomBuilder.Windows // Show line edit dialog if(General.Map.UDMF) //mxd { - LinedefEditFormUDMF f = (LinedefEditFormUDMF)linedefEditWindow; - f.OnValuesChanged -= EditForm_OnValuesChanged; - DisableProcessing(); //mxd - f.Setup(lines, selectfront, selectback); - EnableProcessing(); //mxd - f.OnValuesChanged += EditForm_OnValuesChanged; - editformopen = true; //mxd - result = f.ShowDialog(this); - editformopen = false; //mxd - } - else - { - LinedefEditForm f = (LinedefEditForm)linedefEditWindow; - f.OnValuesChanged -= EditForm_OnValuesChanged; - DisableProcessing(); //mxd + LinedefEditFormUDMF f = new LinedefEditFormUDMF(selectfront, selectback); + DisableProcessing(); //mxd f.Setup(lines); EnableProcessing(); //mxd f.OnValuesChanged += EditForm_OnValuesChanged; editformopen = true; //mxd result = f.ShowDialog(this); editformopen = false; //mxd + f.Dispose(); + } + else + { + LinedefEditForm f = new LinedefEditForm(); + DisableProcessing(); //mxd + f.Setup(lines); + EnableProcessing(); //mxd + f.OnValuesChanged += EditForm_OnValuesChanged; + editformopen = true; //mxd + result = f.ShowDialog(this); + editformopen = false; //mxd + f.Dispose(); } return result; @@ -4016,30 +3958,27 @@ namespace CodeImp.DoomBuilder.Windows // Show sector edit dialog if(General.Map.UDMF) //mxd { - // ano - preinit sector edit windows to save time - SectorEditFormUDMF f = (SectorEditFormUDMF)sectorEditWindow; - f.OnValuesChanged -= EditForm_OnValuesChanged; - DisableProcessing(); //mxd + SectorEditFormUDMF f = new SectorEditFormUDMF(); + DisableProcessing(); //mxd f.Setup(sectors); EnableProcessing(); //mxd f.OnValuesChanged += EditForm_OnValuesChanged; editformopen = true; //mxd result = f.ShowDialog(this); editformopen = false; //mxd - //f.Dispose(); + f.Dispose(); } else { - SectorEditForm f = (SectorEditForm)sectorEditWindow; - f.OnValuesChanged -= EditForm_OnValuesChanged; - DisableProcessing(); //mxd + SectorEditForm f = new SectorEditForm(); + DisableProcessing(); //mxd f.Setup(sectors); EnableProcessing(); //mxd f.OnValuesChanged += EditForm_OnValuesChanged; editformopen = true; //mxd result = f.ShowDialog(this); editformopen = false; //mxd - //f.Dispose(); + f.Dispose(); } return result; @@ -4053,28 +3992,27 @@ namespace CodeImp.DoomBuilder.Windows // Show thing edit dialog if(General.Map.UDMF) { - ThingEditFormUDMF f = (ThingEditFormUDMF)thingEditWindow; - f.OnValuesChanged -= EditForm_OnValuesChanged; - DisableProcessing(); //mxd + ThingEditFormUDMF f = new ThingEditFormUDMF(); + DisableProcessing(); //mxd f.Setup(things); EnableProcessing(); //mxd f.OnValuesChanged += EditForm_OnValuesChanged; editformopen = true; //mxd result = f.ShowDialog(this); editformopen = false; //mxd + f.Dispose(); } else { - ThingEditForm f = (ThingEditForm)thingEditWindow; - - f.OnValuesChanged -= EditForm_OnValuesChanged; - DisableProcessing(); //mxd + ThingEditForm f = new ThingEditForm(); + DisableProcessing(); //mxd f.Setup(things); EnableProcessing(); //mxd f.OnValuesChanged += EditForm_OnValuesChanged; editformopen = true; //mxd result = f.ShowDialog(this); editformopen = false; //mxd + f.Dispose(); } return result; diff --git a/Source/Plugins/BuilderModes/Properties/AssemblyInfo.cs b/Source/Plugins/BuilderModes/Properties/AssemblyInfo.cs index 9e73584a..575b3e5b 100755 --- a/Source/Plugins/BuilderModes/Properties/AssemblyInfo.cs +++ b/Source/Plugins/BuilderModes/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Resources; // Build Number // Revision // -[assembly: AssemblyVersion("2.3.0.2861")] +[assembly: AssemblyVersion("2.3.0.2859")] [assembly: NeutralResourcesLanguageAttribute("en")]