private void afnDraw_DoubleClick(object sender, EventArgs e) { String estadoACambiar=clickEstadoAfn(((MouseEventArgs)e).X, ((MouseEventArgs)e).Y); if (estadoACambiar!= null) { dialog dialogo = new dialog("Ingrese el nombre del estado a editar", estadoACambiar, ((State)estadosAfn[estadoACambiar]).isFinal, ((State)estadosAfn[estadoACambiar]).color); dialogo.ShowDialog(); if (dialogo.isCorrect) { String labelEstado = dialogo.text; Boolean isFinal = dialogo.isFinal; Color colorEstado = dialogo.color; State s = (State)estadosAfn[estadoACambiar]; s.color = colorEstado; s.isFinal = isFinal; s.label = labelEstado; estadosAfn.Remove(estadoACambiar); estadosAfn.Add(labelEstado, s); //actualizar todas las lineas que tienen como estado source al estado cambiado if (estadoACambiar != labelEstado) { ArrayList KeyToRemove = new ArrayList(); ArrayList KeyToUpdate = new ArrayList(); foreach (DictionaryEntry de in lineasAfn) { String[] toCheck = breakKey((String)de.Key); if (toCheck[0] == estadoACambiar) { KeyToRemove.Add((String)de.Key); KeyToUpdate.Add(labelEstado + ":" + toCheck[1]); } if (((Hashtable)de.Value).ContainsKey(estadoACambiar)) { ((Hashtable)de.Value).Add(labelEstado, (Line)(((Hashtable)de.Value)[estadoACambiar])); ((Hashtable)de.Value).Remove(estadoACambiar); } ArrayList lineasToUpdate = new ArrayList(); foreach (DictionaryEntry de2 in ((Hashtable)de.Value)) { Line l = (Line)de2.Value; if (l.label == estadoACambiar) lineasToUpdate.Add((String)de2.Key); } foreach (String key in lineasToUpdate) { ((Line)((Hashtable)de.Value)[key]).label = labelEstado; } } for (int i = 0; i < KeyToRemove.Count; i++) { Hashtable lineHtToUpdate = (Hashtable)lineasAfn[KeyToRemove[i]]; lineasAfn.Add(KeyToUpdate[i], lineHtToUpdate); lineasAfn.Remove(KeyToRemove[i]); } } } afnDraw.Refresh(); } }
/// <summary> /// Metodo llamado cuando se presiona doble-click del mouse sobre el panel grafico de los AFD. /// Este método revisa si se presionó sobre un estado, de ser asi una ventana se levanta /// para permitir al usuario editar los valores de un estado creado anteriormente. /// Esto último se realiza dibujando otro estado en la posición deseada e ingresandole /// como identificador al identificador único del estado que se desea mover. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void afdDraw_DoubleClick(object sender, EventArgs e) { int x = ((MouseEventArgs)e).X; int y = ((MouseEventArgs)e).Y; String index = clickedOnAState(x, y); if (index != null) { String oldlabel = ((State)estados[index]).label; Boolean oldisFinal = ((State)estados[index]).isFinal; Color oldColor = ((State)estados[index]).color; dialog d = new dialog("Enter the information of the selected state", oldlabel, oldisFinal, oldColor); d.ShowDialog(this); if ((d.isCorrect) && ((oldlabel != d.text) || (oldisFinal != d.isFinal)) || (oldColor != d.color)) { saveToolStripMenuItem.Enabled = true; State newState = (State)estados[index]; newState.label = d.text; newState.isFinal = d.isFinal; newState.color = d.color; estados.Remove(index); estados.Add(newState.label, newState); //actualizar todas las lineas que tienen como estado source al estado cambiado String[] KeyToRemove = new String[lineas.Count]; String[] KeyToUpdate = new String[lineas.Count]; String[] automataKeyToUpdate = new String[automata.Count]; int counter = 0, counterAutomata = 0; foreach (DictionaryEntry de in lineas) { String[] toCheck = breakKey((String)de.Key); if (toCheck[0] == oldlabel) { KeyToRemove[counter] = (String)de.Key; KeyToUpdate[counter++] = newState.label + ":" + toCheck[1]; } if (((Line)de.Value).dest.label == (newState.label)) { automataKeyToUpdate[counterAutomata++] = (String)de.Key; } } for (int i = 0; i < counter; i++) { Line lineToUpdate = (Line)lineas[KeyToRemove[i]]; String automataToUpdate = (String)automata[KeyToRemove[i]]; lineas.Remove(KeyToRemove[i]); automata.Remove(KeyToRemove[i]); lineas.Add(KeyToUpdate[i], lineToUpdate); automata.Add(KeyToUpdate[i], automataToUpdate); } for (int i = 0; i < counterAutomata; i++) { automata.Remove(automataKeyToUpdate[i]); automata.Add(automataKeyToUpdate[i], newState.label); } } } afdDraw.Refresh(); }
private void afnDraw_Click(object sender, EventArgs e) { x = ((MouseEventArgs)e).X; y = ((MouseEventArgs)e).Y; if (afnEstadosClicked) { State sTemp = new State("S"+contadorEstadosAfn, x, y); while (estadosAfn.ContainsKey("S" + contadorEstadosAfn)) contadorEstadosAfn++; estadosAfn.Add("S" + contadorEstadosAfn, sTemp); afnDraw.Refresh(); dialog d = new dialog("Ingrese el nombre del estado", "S" + contadorEstadosAfn, false, Color.Black); d.ShowDialog(); estadosAfn.Remove("S" + contadorEstadosAfn); if (d.isCorrect) { String labelEstado = d.text; Boolean isFinal = d.isFinal; Color colorEstado = d.color; State s = new State(labelEstado, x, y); if (contadorEstadosAfn == 0) s.isInitial = true; s.color = colorEstado; s.isFinal = isFinal; try { estadosAfn.Add(labelEstado, s); contadorEstadosAfn++; } catch (Exception) { s.isInitial = ((State)estadosAfn[labelEstado]).isInitial; estadosAfn.Remove(labelEstado); estadosAfn.Add(labelEstado, s); } } afnEstados.PerformClick(); afnDraw.Refresh(); } if (ptoIntermedioClicked) { labelDest = clickEstadoAfn(x, y); if (labelDest != null) { dialogLine dl = new dialogLine("Ingrese el caracter del arco", true, true); dl.ShowDialog(); if (dl.isAfnCorrect) { String caracter = dl.text; Line lineaAfn = new Line(((State)estadosAfn[labelSource]), ((State)estadosAfn[labelDest]), interX, interY); lineaAfn.label = caracter; lineaAfn.color = dl.color; if (!(lineasAfn.ContainsKey(labelSource + ":" + caracter))) { Hashtable destinos = new Hashtable(); destinos.Add(labelDest, lineaAfn); lineasAfn.Add(labelSource + ":" + caracter, destinos); } else { Hashtable temporal = (Hashtable)lineasAfn[labelSource + ":" + caracter]; if (!(temporal.ContainsKey(labelDest))) { temporal.Add(labelDest, lineaAfn); } else { temporal.Remove(labelDest); temporal.Add(labelDest, lineaAfn); } } afnDraw.Refresh(); ptoIntermedioClicked = false; afnLineas.PerformClick(); return; } else afnLineas.PerformClick(); } else afnLineas.PerformClick(); } if (estadoSourceClicked) { String temp=clickEstadoAfn(x,y); if (temp == null) { interX = x; interY = y; ptoIntermedioClicked = true; estadoSourceClicked = false; } return; } if (afnLineasClicked) { labelSource = clickEstadoAfn(x, y); if (labelSource != null) { estadoSourceClicked = true; } } if (((MouseEventArgs)e).Button == MouseButtons.Right) { if (afnDeleteClicked) { String estadoABorrar = clickEstadoAfn(x, y); if (estadoABorrar != null) { if (((State)estadosAfn[estadoABorrar]).isInitial) { MessageBox.Show("El estado inicial no puede ser borrado", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); afnBorrar.PerformClick(); return; } DialogResult resultado = MessageBox.Show("Esta seguro que desea eliminar el estado " + estadoABorrar + " ?", "Eliminacion", MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation); ArrayList lineasABorrar = new ArrayList(); if (resultado == DialogResult.OK) { foreach (DictionaryEntry d in lineasAfn) { ArrayList destinosABorrar = new ArrayList(); String[] key = breakKey((String)d.Key); if (key[0] == estadoABorrar) { lineasABorrar.Add((String)d.Key); } foreach (DictionaryEntry d2 in ((Hashtable)d.Value)) { if ((String)d2.Key == estadoABorrar) destinosABorrar.Add((String)d2.Key); } foreach (String d3 in destinosABorrar) { ((Hashtable)d.Value).Remove(d3); } if (((Hashtable)d.Value).Count == 0) lineasABorrar.Add((String)d.Key); } foreach (String d4 in lineasABorrar) { lineasAfn.Remove(d4); } estadosAfn.Remove(estadoABorrar); afnBorrar.PerformClick(); afnDraw.Refresh(); } else afnBorrar.PerformClick(); } } } if (estadoSourceABorrarClicked) { String labelDestABorrar = clickEstadoAfn(x, y); if (labelDestABorrar != null) { int contador = 0; foreach (DictionaryEntry d in lineasAfn) { String[] s = breakKey((String)d.Key); if ( (s[0] == labelSourceABorrar) && ( ((Hashtable)d.Value).ContainsKey(labelDestABorrar)) ) contador++; } if (contador != 1) { dialogLine dl = new dialogLine("Ingrese el caracter del Arco a Borrar", false, false); dl.ShowDialog(this); if (dl.isAfnCorrect) { if (lineasAfn.ContainsKey(labelSourceABorrar + ":" + dl.text)) { if (((Hashtable)lineasAfn[labelSourceABorrar + ":" + dl.text]).ContainsKey(labelDestABorrar)) ((Hashtable)lineasAfn[labelSourceABorrar + ":" + dl.text]).Remove(labelDestABorrar); } } } else { foreach (DictionaryEntry d2 in lineasAfn) { String[] s = breakKey((String)d2.Key); if ((s[0] == labelSourceABorrar) && (((Hashtable)d2.Value).ContainsKey(labelDestABorrar))) ((Hashtable)d2.Value).Remove(labelDestABorrar); } } ArrayList lineasToRemove = new ArrayList(); foreach (DictionaryEntry de in lineasAfn) { if (((Hashtable)de.Value).Count == 0) lineasToRemove.Add((String)de.Key); } foreach (String ltr in lineasToRemove) { lineasAfn.Remove(ltr); } afnBorrar.PerformClick(); afnDraw.Refresh(); } } if (afnDeleteClicked) { labelSourceABorrar = clickEstadoAfn(x, y); if (labelSourceABorrar != null) estadoSourceABorrarClicked = true; } }
/// <summary> /// Metodo llamado cuando es presionado el panel donde se dibuja los automata AFD. /// Este método obtiene la posición (coordenada) exacta donde se presionó el mouse y /// se revisa si se habia presionado algún botón de edición del automatum. /// Si se presionó el botón izquierdo del mouse, y el botón de estados fue presionado anteriormente, /// entonces se procede a crear un estado nuevo (un objeto nuevo de la clase State) donde se le pide /// al usuario ingresar los datos requeridos para la correcta creación de estados. /// Si se presionó el botón de lineas, entonces este método es llamado 3 veces: /// la primera vez que se presiona el mouse se guarda el primer estado (que sera estado origen); /// la seguna vez que se presiona el mouse, se guarda el punto intermedio que le agregara curvatura /// a la curva; y la tercera vez que se presiona el mouse se guarda el estado destino de la curva. /// Con estos datos la linea puede ser creada luego que se le pregunta al usuario los datos /// necesarios para la correcta creación de las lineas. /// Si se presionó el botón de borrar, entonces se revisa si se presionó sobre un estado y si /// el botón del mouse presionado fue el derecho, se le pregunta al usuario que desea realizar /// y dependiendo de esto se borra o no el estado. En cambio, si el botón del mouse presionado /// fue el derecho, entonces se espera que el usuario presione los dos estados (origen y destino) /// en la dirección correcta para preguntarle al usuario si desea borrar la linea. Si existieran /// mas de una linea entre esos dos estados en esa misma direccion, se le pregunta al usuario /// el caracter que define la linea que desea borrar. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void afdDraw_Click(object sender, EventArgs e) { int x = ((MouseEventArgs)e).X; int y = ((MouseEventArgs)e).Y; if (((MouseEventArgs)e).Button == MouseButtons.Right) rightClick(x, y); if (buttonclicked) { if (statesclicked) { buttonclicked = statesclicked = false; Lineas.Enabled = delete.Enabled = Animate.Enabled = minimiza.Enabled = clear.Enabled = true; State s = new State("S" + (++counterstates), x, y); while (estados.ContainsKey("S" + counterstates)) counterstates++; estados.Add("S" + counterstates, s); saveToolStripMenuItem.Enabled = true; afdDraw.Refresh(); dialog d = new dialog("Enter the new state name", "S" + counterstates, false, Color.Black); d.ShowDialog(this); if (d.isCorrect) { s.label = d.text; s.isFinal = d.isFinal; s.color = d.color; } else { estados.Remove("S" + counterstates); counterstates--; goto finstatesclicked; } try { estados.Remove("S" + counterstates); if (InitialState == "") { InitialState = s.label; s.isInitial = true; } estados.Add(s.label, s); } catch (Exception) { counterstates--; State toReplace = (State)estados[s.label]; estados.Remove(s.label); //toReplace.x = x; //toReplace.y = y; s.isInitial = toReplace.isInitial; estados.Add(s.label, s); Boolean[] toUpdateBoolean = new Boolean[lineas.Count]; String[] toUpdate = new String[lineas.Count]; int counter = 0; foreach (DictionaryEntry de in lineas) { String[] toCheck = breakKey((String)de.Key); if (toCheck[0] == s.label) { toUpdate[counter] = (String)de.Key; toUpdateBoolean[counter++] = true; } } foreach (DictionaryEntry de2 in automata) { String[] toCheck = breakKey((String)de2.Key); if (((String)de2.Value) == s.label) { toUpdate[counter] = (String)de2.Key; toUpdateBoolean[counter++] = false; } } for (int i = 0; i < counter; i++) { Line l = (Line)lineas[toUpdate[i]]; lineas.Remove(toUpdate[i]); if (toUpdateBoolean[i]) { l.source.x = x; l.source.y = y; } else { l.dest.x = x; l.dest.y = y; } lineas.Add(toUpdate[i], l); } } finstatesclicked: afdDraw.Cursor = inicial; afdDraw.Refresh(); } if (linesclicked) { String index = clickedOnAState(x, y); if (index != null) { if (!firstStateClicked) { firstStateClicked = true; firstState = index; } else { if (intermediatePointclicked) { Line l = new Line((State)estados[firstState], (State)estados[index], intermediatePoint.X, intermediatePoint.Y); l.label = ""; lineas.Add(firstState + ":", l); afdDraw.Refresh(); dialogLine d = new dialogLine("Enter the character of the arc", true, true); d.ShowDialog(this); if (d.isCorrect) { l.label = d.text; l.color = d.color; lineas.Remove(firstState + ":"); String key = firstState + ":" + d.text; try { lineas.Add(key, l); } catch (ArgumentException) { lineas.Remove(key); lineas.Add(key, l); } try { automata.Add(key, index); } catch (ArgumentException) { automata.Remove(key); automata.Add(key, index); } } else lineas.Remove(firstState + ":"); saveToolStripMenuItem.Enabled = true; firstStateClicked = intermediatePointclicked = false; intermediatePoint.X = intermediatePoint.Y = 0; firstState = null; States.Enabled = delete.Enabled = Animate.Enabled = minimiza.Enabled = clear.Enabled = true; linesclicked = false; afdDraw.Refresh(); } } } else { if (!intermediatePointclicked) { intermediatePointclicked = true; intermediatePoint.X = x; intermediatePoint.Y = y; } } } if (deleteclicked) { String index = clickedOnAState(x, y); if (index != null) { if (!firstStateClicked) { firstStateClicked = true; firstState = index; } else { String caption = "Delete line?"; String message = "Are you sure you want to delete the line?"; String[] toRemove = new String[lineas.Count]; int counter = 0; foreach (DictionaryEntry de in lineas) { String[] toCheck = breakKey((String)de.Key); if (toCheck[0] == firstState) toRemove[counter++] = (String)de.Key; } if (counter > 1) { dialogLine d = new dialogLine("Enter the character of the line to erase", false, false); d.ShowDialog(this); if (d.isCorrect) { for (int i = 0; i < counter; i++) { if ((firstState + ":" + d.text) == toRemove[i]) { DialogResult result = MessageBox.Show(this, message, caption, MessageBoxButtons.OKCancel); if (result == DialogResult.Cancel) goto finborrarlineas; lineas.Remove(toRemove[i]); automata.Remove(toRemove[i]); } } } } else if (counter == 1) { DialogResult result = MessageBox.Show(this, message, caption, MessageBoxButtons.OKCancel); if (result == DialogResult.Cancel) goto finborrarlineas; lineas.Remove(toRemove[0]); automata.Remove(toRemove[0]); } finborrarlineas: afdDraw.Refresh(); saveToolStripMenuItem.Enabled = true; firstStateClicked = false; firstState = null; States.Enabled = delete.Enabled = Animate.Enabled = minimiza.Enabled = Lineas.Enabled = clear.Enabled = true; linesclicked = false; deleteclicked = false; afdDraw.Cursor = inicial; } } } /*if (animateclicked) if (resetclicked) */ } }