public IUndoRedoAction Execute(Workspace sender) { EquationModel item = m_ws.Equations[m_index]; m_ws.Equations.Remove(item); return(new InsertEquation(m_ws, item, m_index)); }
public decimal Calculate(EquationModel equation) { if (string.IsNullOrWhiteSpace(equation.Operator)) { return(0); } switch (equation.Operator.ToLower()) { case "+": return(equation.Argument1 + equation.Argument2); case "-": return(equation.Argument1 - equation.Argument2); case "x": return(equation.Argument1 * equation.Argument2); case "/": return(decimal.Divide(equation.Argument1, equation.Argument2)); default: throw new ArgumentException("Invalid operator"); } }
public async Task <double> Calculate(EquationModel equationModel) { if (equationModel == null) { return(default(double)); } switch (equationModel.Operation) { case "+": return(await Task.Run(() => Add(equationModel.Param1, equationModel.Param2)).ConfigureAwait(false)); case "-": return(await Task.Run(() => Subtract(equationModel.Param1, equationModel.Param2)).ConfigureAwait(false)); case "*": return(await Task.Run(() => Multiply(equationModel.Param1, equationModel.Param2)).ConfigureAwait(false)); case "/": if (equationModel.Param2 == 0) { throw new DivideByZeroException(); } return(await Task.Run(() => Divide(equationModel.Param1, equationModel.Param2)).ConfigureAwait(false)); default: throw new ArgumentException($"Operation {equationModel.Operation} is not supported."); } }
private void Equations_EquationModelPropertyChanged(EquationModel sender, string propertyName) { // We only care about comment visibility if (propertyName.Equals("CommentsVisible")) { UpdateComments(); } }
/// <summary> /// Called whenever the user makes a change to one of the equations /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void EquationModelPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) { EquationModel model = sender as EquationModel; //if the scope changed, then update the property units that are visible to the particular view model if (e.PropertyName == "Scope") { UpdateEquationModelElements(model); } }
public IUndoRedoAction Execute(Workspace sender) { EquationModel moveMeUp = sender.Equations[m_index]; sender.Equations.Remove(moveMeUp); sender.Equations.Insert(m_index - 1, moveMeUp); // Return move down action return(new MoveEquationDown(m_index - 1)); }
private void Start() { instance = this; if (SceneManager.GetActiveScene().name.Contains("4")) { SetupEquationArray(4); } else { SetupEquationArray(6); } }
private void AddEqCommentButtonClick(object sender, RoutedEventArgs e) { EquationModel model = (sender as Button).Tag as EquationModel; model.Comments.Add(new BasicComment(string.Empty, null)); // Create and undo that will delete the comment we just added m_workspace.AddUndo(new UndoRedoCollection( "Undo addition of new equation comment", new Logic.Undos.RemoveBasicComment(model.Comments, model.Comments.Count - 1))); UpdateComments(); }
private void UpdateEquationModelElements(EquationModel equation) { List <object> relevantUnits = new List <object>(); //supply different PFD elements to the model depending on its scope switch (equation.Scope.Classification) { //With a single unit, all we care about is that unit and its related streams case EquationScopeClassification.SingleUnit: AbstractProcessUnit selectedUnit = (from element in m_workspace.ProcessUnits where (element as AbstractProcessUnit).Label == equation.Scope.Name select element).FirstOrDefault() as AbstractProcessUnit; if (selectedUnit != null) { relevantUnits = GetElementAndStreams(selectedUnit); } break; //ChemProV doesn't currently support sub processes, but this is where //that logic would go case EquationScopeClassification.SubProcess: break; //AC: Not sure what should happen here case EquationScopeClassification.Unknown: break; //Pull all source and sink units as well as their streams case EquationScopeClassification.Overall: default: // TODO: Fix or remove //List<GenericProcessUnit> units = (from element in PfdElements // where element is GenericProcessUnit // && // ( // (element as GenericProcessUnit).Description == ProcessUnitDescriptions.Sink // || // (element as GenericProcessUnit).Description == ProcessUnitDescriptions.Source // ) // select element as GenericProcessUnit).ToList(); //foreach (GenericProcessUnit unit in units) //{ // relevantUnits = relevantUnits.Union(GetElementAndStreams(unit)).ToList(); //} break; } //assign the updated list to the equation equation.RelatedElements = relevantUnits; }
public EquationRowControl(Workspace workspace, EquationEditor parent, EquationModel equationModel) { InitializeComponent(); m_workspace = workspace; SetScopeOptions(parent.EquationScopes); SetTypeOptions(parent.EquationTypes); // Use the SetModel function to set the current model. This will update the UI and subscribe // to relevant events. m_model = null; SetModel(equationModel); // We want to make sure we have a right-click menu for the equation text box Core.App.InitRightClickMenu(EquationTextBox); }
public EquationModel BuildEquation(EquationModel equation, string input) { if (equation == null) { equation = new EquationModel(); } if (input == "ce") { return(new EquationModel()); } if (input == "c") { if (string.IsNullOrWhiteSpace(equation.Operator)) { equation.Source1 = ""; } else { equation.Source2 = ""; } return(equation); } var operators = new[] { "+", "-", "x", "/" }; if (operators.Contains(input)) { equation.Operator = input; } else { // the first argument if (string.IsNullOrWhiteSpace(equation.Operator)) { equation.Source1 = AddInput(equation.Source1, input); } else { equation.Source2 = AddInput(equation.Source2, input); } } return(equation); }
public IUndoRedoAction Execute(Workspace sender) { // Make sure it's not the last item in the collection (nor is the index beyond the // last item in the collection). if (m_index >= sender.Equations.Count - 1) { throw new InvalidOperationException(string.Format( "Cannot move equation at index {0} down within a collection of {1} items.", m_index, sender.Equations.Count)); } EquationModel moveMeDown = sender.Equations[m_index]; sender.Equations.Remove(moveMeDown); sender.Equations.Insert(m_index + 1, moveMeDown); // Return move up action return(new MoveEquationUp(m_index + 1)); }
private void MoveUpButton_Click(object sender, RoutedEventArgs e) { EquationRowControl row = null; // Start by finding the row index in the stack panel int indexOfThis = -1; for (int i = 0; i < EquationsStackPanel.Children.Count; i++) { // Will throw an exception if it the object is not an EquationControl, but that's // what we want since the design contract is that all objects in the stack panel // must be EquationControl objects. EquationRowControl ec = (EquationRowControl)EquationsStackPanel.Children[i]; if (object.ReferenceEquals(sender, ec.MoveUpButton)) { indexOfThis = i; row = ec; break; } } // If it's the first row then disable the button to move up and return if (0 == indexOfThis) { row.MoveUpButton.IsEnabled = false; return; } // Move the row up by removing it and then inserting it at a lower index. Event // handlers are subscribed to changes in the equation collection, so the UI will // be updated automatically. EquationModel toMoveUp = m_workspace.Equations[indexOfThis]; m_workspace.Equations.Remove(toMoveUp); m_workspace.Equations.Insert(indexOfThis - 1, toMoveUp); // Add an undo that will move it back down m_workspace.AddUndo(new UndoRedoCollection("Undo moving equation up", new Logic.Undos.MoveEquationDown(indexOfThis - 1))); }
/// <summary> /// Sets the model for this equation control. The UI elements will be updated will data from the /// model and then the model will be updated as the user changes values by using the control. The /// model reference can be null if desired, but that should only be used in cases where this /// control is about to be disposed and is no longer needed. /// </summary> public void SetModel(EquationModel model) { // IMPORTANT: Unsubscribe from the old model if (null != m_model) { m_model.PropertyChanged -= this.Model_PropertyChanged; } m_model = model; // Calling this method with a null reference for the model is considered valid, so // only update the UI if the model is non-null. if (null != model) { // Setup the type combo box foreach (object typeObj in TypeComboBox.Items) { if (m_model.Type.Equals(typeObj)) { TypeComboBox.SelectedItem = typeObj; } } // Setup the scope combo box foreach (EquationScope item in ScopeComboBox.Items) { if (item.Equals(m_model.Scope)) { if (ScopeComboBox.SelectedItem != item) { ScopeComboBox.SelectedItem = item; } } } EquationTextBox.Text = model.Equation; // Watch for property changes m_model.PropertyChanged += this.Model_PropertyChanged; } }
public ActionResult Index(EquationModel equationModel) { string solveStatus; try { List <double> calculationResult = QuadraticEquation.SolveQuadrEq(Convert.ToDouble(equationModel.Coef_A), Convert.ToDouble(equationModel.Coef_B), Convert.ToDouble(equationModel.Coef_C), out solveStatus); equationModel.solveStatus = solveStatus; if (calculationResult != null) { equationModel.RootX1 = calculationResult[0].ToString(); equationModel.RootX2 = calculationResult[1].ToString(); } } catch (Exception) { equationModel.solveStatus = "Input data can't converted to double"; } return(View(equationModel)); }
private void UpdateComments() { // Clear first CommentsStack.Children.Clear(); // Start with equation comments for (int i = 0; i < m_workspace.Equations.Count; i++) { EquationModel model = m_workspace.Equations[i]; if (!model.CommentsVisible) { continue; } Border brdr = new Border(); brdr.Margin = new Thickness(3.0, 3.0, 3.0, 0.0); brdr.CornerRadius = new CornerRadius(3.0); brdr.BorderThickness = new Thickness(2.0); brdr.BorderBrush = s_eqBorderBrush; StackPanel sp = new StackPanel(); sp.Orientation = Orientation.Vertical; brdr.Child = sp; // Add an equation number label at the top Label numLabel = new Label(); numLabel.Content = "Equation " + (i + 1).ToString(); numLabel.Foreground = s_eqBorderBrush; numLabel.HorizontalAlignment = System.Windows.HorizontalAlignment.Center; sp.Children.Add(numLabel); // Add each comment foreach (BasicComment bc in model.Comments) { PaneCommentControl cc = new PaneCommentControl(); cc.SetCommentObject(bc); cc.Margin = new Thickness(3.0); cc.XLabel.MouseLeftButtonDown += delegate(object sender, MouseButtonEventArgs e) { // Create and undo that adds the comment back BasicComment toRemove = cc.CommentObject as BasicComment; m_workspace.AddUndo(new UndoRedoCollection( "Undo deletion of equation comment", new Logic.Undos.InsertBasicComment(toRemove, model.Comments, model.Comments.IndexOf(toRemove)))); model.Comments.Remove(cc.CommentObject as BasicComment); sp.Children.Remove(cc); }; sp.Children.Add(cc); } // Add a button to allow addition of more comments Button btn = new Button(); btn.Margin = new Thickness(3.0); Image btnIcon = Core.App.CreateImageFromSource("plus_16x16.png"); btnIcon.Width = btnIcon.Height = 16; btn.Content = btnIcon; btn.Tag = model; btn.Click += new RoutedEventHandler(AddEqCommentButtonClick); sp.Children.Add(btn); CommentsStack.Children.Add(brdr); } // Next do comments for the degrees of freedom analysis if (m_workspace.DegreesOfFreedomAnalysis.CommentsVisible) { Border brdr = new Border(); brdr.Margin = new Thickness(3.0, 3.0, 3.0, 0.0); brdr.CornerRadius = new CornerRadius(3.0); brdr.BorderThickness = new Thickness(2.0); brdr.BorderBrush = s_dfBorderBrush; StackPanel sp = new StackPanel(); sp.Orientation = Orientation.Vertical; brdr.Child = sp; // Add a label at the top Label numLabel = new Label(); numLabel.Content = "DF Analysis"; numLabel.Foreground = s_dfBorderBrush; numLabel.HorizontalAlignment = System.Windows.HorizontalAlignment.Center; sp.Children.Add(numLabel); DegreesOfFreedomAnalysis dfa = m_workspace.DegreesOfFreedomAnalysis; foreach (BasicComment bc in dfa.Comments) { PaneCommentControl pcc = new PaneCommentControl(); pcc.SetCommentObject(bc); pcc.Margin = new Thickness(3.0); pcc.XLabel.MouseLeftButtonDown += delegate(object sender, MouseButtonEventArgs e) { BasicComment toRemove = pcc.CommentObject as BasicComment; int index = dfa.Comments.IndexOf(toRemove); // Add an undo that will re-insert the comment that we're about to delete m_workspace.AddUndo(new UndoRedoCollection( "Undo deletion of comment for degrees of freedom analysis", new Logic.Undos.InsertBasicComment(toRemove, dfa.Comments, index))); // Now delete the comment m_workspace.DegreesOfFreedomAnalysis.Comments.Remove(pcc.CommentObject as BasicComment); }; sp.Children.Add(pcc); } // Add a button to allow addition of more comments Button btn = new Button(); btn.Margin = new Thickness(3.0); Image btnIcon = Core.App.CreateImageFromSource("plus_16x16.png"); btnIcon.Width = btnIcon.Height = 16; btn.Content = btnIcon; btn.Click += new RoutedEventHandler(AddDFCommentButtonClick); sp.Children.Add(btn); CommentsStack.Children.Add(brdr); } }
public InsertEquation(Workspace workspace, EquationModel item, int index) { m_ws = workspace; m_item = item; m_index = index; }
/// <summary> /// Merges comments from two Xml document streams into a new output Xml document stream. Comment /// merging is not commutative. One document must be considered to be the parent and another a /// child. ALL content from the parent will appear in the output. Comments from the child /// document will only be written to the output if they exist for shared entities. That is, if /// there is a comment in the child document that is tied to a process unit with Id=GPU_30, then /// it will only be written the output document if the parent also contained a process unit with /// the same Id. /// </summary> public static void Merge(Stream parent, string parentUserNameIfNotInXml, Stream child, string childUserNameIfNotInXml, Stream output) { // We need all streams to be non-null if (null == parent) { throw new ArgumentNullException( "Parent stream for comment merging cannot be null"); } if (null == child) { throw new ArgumentNullException( "Child stream for comment merging cannot be null"); } if (null == output) { throw new ArgumentNullException( "Output stream for comment merging cannot be null"); } // Load the workspaces from the streams Workspace wsParent = new Workspace(); wsParent.Load(parent); Workspace wsChild = new Workspace(); wsChild.Load(child); // What we will do in this method is alter wsParent to contain relevant content from the // child workspace and then save it to the output stream. // Start by setting user names for comments in both workspaces. We leave the user names // alone if they are not null or empty but otherwise we set them to the values specified // by the caller. SetUserNameIfAbsent(wsParent, parentUserNameIfNotInXml); SetUserNameIfAbsent(wsChild, childUserNameIfNotInXml); // Start with the free-floating sticky note comments. We want to take the ones from the // child and add them into the parent. But we want to avoid duplicates in the process. foreach (StickyNote sn in wsChild.StickyNotes) { // If they have the same text and location then we'll skip if (WorkspaceUtility.ContainsFFSNWithValues(wsParent, sn.Text, new MathCore.Vector(sn.LocationX, sn.LocationY))) { continue; } // Add it to the parent wsParent.StickyNotes.Add(sn); } // Next do process units in the child foreach (AbstractProcessUnit apuChild in wsChild.ProcessUnits) { AbstractProcessUnit apuParent = wsParent.GetProcessUnit(apuChild.Id); // If the parent workspace doesn't contain a process unit with the same ID then we // skip it if (null == apuParent) { continue; } foreach (StickyNote comment in apuChild.Comments) { if (WorkspaceUtility.CollectionContainsItemWithText(apuParent.Comments, comment.Text)) { // Skip it if there's already a comment with the same text continue; } // Add it to the parent process unit apuParent.Comments.Add(comment); } } // Now do streams in the child foreach (AbstractStream sChild in wsChild.Streams) { AbstractStream sParent = wsParent.GetStream(sChild.Id); // If the parent workspace doesn't contain a stream with the same ID then we // skip it if (null == sParent) { continue; } foreach (StickyNote comment in sChild.Comments) { if (WorkspaceUtility.CollectionContainsItemWithText(sParent.Comments, comment.Text)) { // Skip it if there's already a comment with the same text continue; } // Add the comment to the parent stream sParent.Comments.Add(comment); } } // Equation comments need to be merged as well foreach (EquationModel emChild in wsChild.Equations) { // Get the equation object in the parent with the same ID EquationModel emParent = wsParent.Equations.GetById(emChild.Id); // If we can't find it then move on to the next if (null == emParent) { continue; } // Now add each comment in the child that isn't already in the parent foreach (BasicComment bcChild in emChild.Comments) { if (!emParent.ContainsComment(bcChild.CommentText)) { emParent.Comments.Add(bcChild); } } } // Lastly we deal with the comments for the degrees of freedom analysis. We only // merge in comments from the child if the analysis text is the same in both. if (wsParent.DegreesOfFreedomAnalysis.Text == wsChild.DegreesOfFreedomAnalysis.Text) { foreach (BasicComment bcChild in wsChild.DegreesOfFreedomAnalysis.Comments) { if (!wsParent.DegreesOfFreedomAnalysis.ContainsComment(bcChild.CommentText)) { wsParent.DegreesOfFreedomAnalysis.Comments.Add(bcChild); } } } // Now that we have everything merged into the parent workspace, we just save it to the // output stream wsParent.Save(output); }
public void Load(XDocument doc) { // Start by clearing Clear(); string setting = doc.Element("ProcessFlowDiagram").Attribute("DifficultySetting").Value; TrySetDifficulty((OptionDifficultySetting)Enum.Parse(typeof(OptionDifficultySetting), setting, true)); // Load process units. We have to do this before the streams because the stream loading // does the attaching to the process units. XElement processUnits = doc.Descendants("ProcessUnits").ElementAt(0); foreach (XElement xmPU in processUnits.Elements()) { m_procUnits.Add(ProcessUnitFactory.Create(xmPU)); } // Load streams (constructors attach process units) XElement streamList = doc.Descendants("Streams").ElementAt(0); foreach (XElement streamElement in streamList.Elements()) { // Check the type so we know what to create string unitType = (string)streamElement.Attribute("StreamType"); if ("Chemical" == unitType) { m_streams.Add(new ChemicalStream(streamElement, m_procUnits)); } else { m_streams.Add(new HeatStream(streamElement, m_procUnits)); } // Remember that the properties tables are not stored within the // stream element and get loaded later } // Now that the streams are loaded, we can load the properties windows XElement tablesList = doc.Descendants("PropertiesWindows").ElementAt(0); foreach (XElement table in tablesList.Elements()) { // Get the table's target string parentName = (string)table.Element("ParentStream"); // Create the properties table AbstractStream parentStream = GetStream(Convert.ToInt32(parentName.Split('_')[1])); parentStream.PropertiesTable = new StreamPropertiesTable(table, parentStream); } // Load equations XElement equations = doc.Descendants("Equations").ElementAt(0); foreach (XElement xmlEquation in equations.Elements()) { EquationModel rowModel = EquationModel.FromXml(xmlEquation); m_equations.Add(rowModel); } // Load the sticky notes XElement stickyNoteList = doc.Descendants("StickyNotes").ElementAt(0); foreach (XElement note in stickyNoteList.Elements()) { m_stickyNotes.Add(new Logic.StickyNote(note, null)); } // Check for degrees of freedom analysis XElement df = doc.Element("ProcessFlowDiagram").Element("DegreesOfFreedomAnalysis"); if (null != df) { m_dfAnalysis.Text = df.Element("Text").Value; foreach (XElement el in df.Elements("Comment")) { string userName = string.Empty; XAttribute userAttr = el.Attribute("UserName"); if (null != userAttr) { userName = userAttr.Value; } m_dfAnalysis.Comments.Add(new BasicComment(el.Value, userName)); } } else { m_dfAnalysis.Text = string.Empty; } // Fire events StreamsCollectionChanged(this, EventArgs.Empty); ProcessUnitsCollectionChanged(this, EventArgs.Empty); }
public SetEquationText(EquationModel model, string textToSetOnExecution) { m_equation = model; m_text = textToSetOnExecution; }