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) */ } }