/// <overloads> /// Validates the specified list of variable values.</overloads> /// <summary> /// Validates the specified <see cref="VariableModifierDictionary"/>.</summary> /// <param name="owner"> /// The parent <see cref="Window"/> for any dialogs.</param> /// <param name="variables"> /// A <see cref="VariableModifierDictionary"/> that maps <see cref="VariableClass.Id"/> /// string to the corresponding <see cref="VariableModifier"/> instance values.</param> /// <returns> /// <c>true</c> if the values of the specified <paramref name="variables"/> are valid; /// otherwise, <c>false</c>.</returns> /// <exception cref="ArgumentNullException"> /// <paramref name="variables"/> is a null reference.</exception> /// <remarks><para> /// <b>ValidateVariables</b> checks that every <see cref="ModifierTarget"/> value for each /// in the specified <paramref name="variables"/> collection is either an even multiple of /// the <see cref="VariableClass.Scale"/> of its <see cref="VariableClass"/>, or vice versa. /// </para><para> /// If this is not the case, <b>ValidateVariables</b> asks the user to confirm the value, /// and returns <c>false</c> if the user declines. <b>ValidateVariables</b> returns /// <c>true</c> if all <paramref name="variables"/> pass this test.</para></remarks> public static bool ValidateVariables(Window owner, VariableModifierDictionary variables) { if (variables == null) { ThrowHelper.ThrowArgumentNullException("variables"); } VariableSection variableSection = MasterSection.Instance.Variables; foreach (var pair in variables) { // get variable, display scale, and new value VariableClass variable = variableSection.GetVariable(pair.Key); if (variable == null) { continue; } int scale = variable.Scale; if (scale == 1) { continue; } foreach (ModifierTarget target in VariableModifier.AllModifierTargets) { int value = Math.Abs(pair.Value.GetByTarget(target).GetValueOrDefault()); if (value == 0) { continue; } // check that new value conforms to scale if ((value > scale && value % scale != 0) || (value < scale && scale % value != 0)) { string message = String.Format(ApplicationInfo.Culture, Global.Strings.DialogVariableScaleMismatch, pair.Key); MessageBoxResult result = MessageBox.Show(owner, message, Global.Strings.TitleVariableScaleMismatch, MessageBoxButton.OKCancel, MessageBoxImage.Warning); if (result == MessageBoxResult.Cancel) { return(false); } } } } return(true); }
/// <summary> /// Updates the specified template variables with the modifier values of the specified /// dialog variables, and sets the <see cref="DataChanged"/> flag if they differ.</summary> /// <param name="classValues"> /// One of the dictionaries holding the default variable values of the <see /// cref="EntityClass"/> associated with the <see cref="EntityTemplate"/> being edited. /// </param> /// <param name="templateValues"> /// One of the dictionaries holding the variable values stored in the <see /// cref="EntityTemplate"/> being edited.</param> /// <param name="dialogValues"> /// One of the dictionaries holding the variable values entered by the user on the <see /// cref="VariablesTab"/> page.</param> /// <remarks> /// Before updating the specified <paramref name="templateValues"/>, <b>UpdateVariables</b> /// removes all key-and-value pairs from the specified <paramref name="dialogValues"/> that /// also appear in the specified <paramref name="classValues"/>.</remarks> private void UpdateVariableModifiers(VariableModifierDictionary classValues, VariableModifierDictionary templateValues, VariableModifierDictionary dialogValues) { foreach (var pair in classValues) { dialogValues.Remove(pair); } if (!templateValues.Equals(dialogValues)) { DataChanged = true; } templateValues.Clear(); templateValues.AddRange(dialogValues); }
/// <summary> /// Handles the <see cref="ToggleButton.Checked"/> event for the "Category" <see /// cref="RadioButton"/> controls on the <see cref="VariablesTab"/> page.</summary> /// <param name="sender"> /// The <see cref="Object"/> where the event handler is attached.</param> /// <param name="args"> /// A <see cref="RoutedEventArgs"/> object containing event data.</param> /// <remarks> /// <b>OnVariableCategory</b> sets the current variable category and value collection the to /// values indicated by the selected "Category" radio button, and updates all controls on /// the <see cref="VariablesTab"/> page to reflect the current category.</remarks> private void OnVariableCategory(object sender, RoutedEventArgs args) { args.Handled = true; if (!this._initialized) { return; } // switch category (default to Attribute) IList <String> variableKeys; if (AttributeToggle.IsChecked == true) { variableKeys = MasterSection.Instance.Variables.Attributes.Keys; this._currentVariables = this._entityAttributes; this._currentVariableModifiers = this._entityAttributeModifiers; this._defaultVariables = this._defaultAttributes; this._defaultVariableModifiers = this._defaultAttributeModifiers; } else if (CounterToggle.IsChecked == true) { variableKeys = MasterSection.Instance.Variables.Counters.Keys; this._currentVariables = this._entityCounters; this._currentVariableModifiers = null; this._defaultVariables = this._defaultCounters; this._defaultVariableModifiers = null; } else if (ResourceToggle.IsChecked == true) { variableKeys = MasterSection.Instance.Variables.Resources.Keys; this._currentVariables = this._entityResources; this._currentVariableModifiers = this._entityResourceModifiers; this._defaultVariables = this._defaultResources; this._defaultVariableModifiers = this._defaultResourceModifiers; } else { Debug.Fail("OnVariableCategory: No Category button checked."); variableKeys = MasterSection.Instance.Variables.Attributes.Keys; this._currentVariables = this._entityAttributes; this._currentVariableModifiers = this._entityAttributeModifiers; this._defaultVariables = this._defaultAttributes; this._defaultVariableModifiers = this._defaultAttributeModifiers; } // add template values if defined VariableList.Items.Clear(); foreach (string id in variableKeys) { CreateVariableItem(id); if (this._entityAttributeModifiers != null) { foreach (ModifierTarget target in VariableModifier.AllModifierTargets) { CreateVariableItem(id, target); } } } // select first variable, if any, and update controls bool anyVariables = (VariableList.Items.Count > 0); if (anyVariables) { VariableList.SelectedIndex = 0; } else { VariableUpDown.Value = 0m; } ResetVariableButton.IsEnabled = anyVariables; ResetCategoryButton.IsEnabled = anyVariables; VariableUpDown.Enabled = anyVariables; }
/// <summary> /// Adds one row for each variable of the specified <see cref="EntityClass"/>.</summary> /// <param name="entityClass"> /// The <see cref="EntityClass"/> whose variables to show.</param> /// <param name="category"> /// The <see cref="VariableCategory"/> whose variables to show.</param> /// <param name="showBuildResources"> /// <c>true</c> to show <see cref="EntityClass.BuildResources"/>, <c>false</c> to show <see /// cref="EntityClass.Resources"/>. This argument is ignored if <paramref name="category"/> /// does not equal <see cref="VariableCategory.Resource"/>.</param> /// <exception cref="InvalidEnumArgumentException"> /// <paramref name="category"/> is neither <see cref="VariableCategory.Attribute"/> nor <see /// cref="VariableCategory.Resource"/>.</exception> /// <remarks> /// <b>CreateVariableRows</b> adds one row for each initial value and modifier value defined /// by the specified <paramref name="entityClass"/>. The <see cref="PropertyListItem.Tag"/> /// of each row holds the corresponding <see cref="VariableClass"/>.</remarks> private void CreateVariableRows(EntityClass entityClass, VariableCategory category, bool showBuildResources) { string categoryLabel = ""; VariableClassDictionary variables = null; VariableValueDictionary basics = null; VariableModifierDictionary modifiers = null; // retrieve name and variable collections for category if (category == VariableCategory.Attribute) { categoryLabel = Global.Strings.LabelAttribute; variables = MasterSection.Instance.Variables.Attributes; basics = entityClass.Attributes; modifiers = entityClass.AttributeModifiers; } else if (category == VariableCategory.Resource) { variables = MasterSection.Instance.Variables.Resources; if (showBuildResources) { categoryLabel = Global.Strings.LabelBuildCost; basics = entityClass.BuildResources; } else { categoryLabel = Global.Strings.LabelResource; basics = entityClass.Resources; modifiers = entityClass.ResourceModifiers; } } else { ThrowHelper.ThrowInvalidEnumArgumentException( "category", (int)category, typeof(VariableCategory)); } // insert separator before first property? bool addSeparator = (Items.Count > 0); // add variable row, preceded by separator if required Action <VariableClass, String> addRow = (variable, value) => { if (addSeparator) { ApplicationUtility.AddSeparator(this); addSeparator = false; } Items.Add(new PropertyListItem(categoryLabel, variable.Name, value, variable)); }; // process all variables defined by the scenario foreach (var pair in variables) { string id = pair.Key; string basicValue = null, modSelf = null; // get basic value if defined if (basics.ContainsKey(id)) { basicValue = pair.Value.Format(basics[id], false); } // get set of modifiers and self-modifier value VariableModifier modifier = null; if (modifiers != null && modifiers.TryGetValue(id, out modifier) && modifier.Self != null) { modSelf = pair.Value.Format(modifier.Self.Value, true); } string column = (basicValue == null ? modSelf : (modSelf == null ? basicValue : String.Format( ApplicationInfo.Culture, "{0} {1}", basicValue, modSelf))); if (column != null) { addRow(pair.Value, column); } if (modifier == null) { continue; } // add one row for each additional modifier value foreach (ModifierTarget target in VariableModifier.AllModifierTargets) { if (target == ModifierTarget.Self) { continue; } int?value = modifier.GetByTarget(target); if (value != null) { column = pair.Value.Format(value, target, entityClass.ModifierRange); addRow(pair.Value, column); } } } }