Título: Menús en modo consola Publicado por: Meta en 3 Febrero 2019, 08:54 am Hola:
Estoy usando la consola de C#, me dio ahora por el retro. (https://www.subeimagenes.com/img/captura-1998000.PNG) Hice este menú de opciones, pero no hace nada. Por ahora solo selecciona las opciones. Lo que no se es como entrar en otra opción dentro de ella en DOS al pulsar Enter. Estoy en el submenú que sale un menaje que diga. Estoy dentro de la opción DOS. Con capacidad de pulsar Escape y vuelva al menú principal. Lo que he hecho hasta ahora es solo esto. Código
No logro cuajarlo como si se ha hecho por aquí en este otro ejemplo de abajo. Código
Saludos. Título: Re: Menús en modo consola Publicado por: EdePC en 4 Febrero 2019, 00:10 am Saludos,
- Mmm, interesante, basta que injertes el siguiente IF: Código
- Por cierto, a mí no me reconoce los extraños caracteres que utilizas para dibujar el recuadro, he tenido que recurrir a Unicode: https://en.wikipedia.org/wiki/Box-drawing_character Título: Re: Menús en modo consola Publicado por: Meta en 4 Febrero 2019, 21:17 pm Muchas gracias. En Windows 10, "Mapa de carácteres" saqué todo. ;)
Título: Re: Menús en modo consola Publicado por: Meta en 5 Febrero 2019, 22:47 pm Buenas:
Me ha servido el truco para el código de arriba. Ahora haciendo un menú de solo usar 16x2 de resolusión. Hago este código base. En este caso lo que hace es seleccionar opciones en el menú, pero no hace nada más. Las opciones en el menú se llama. Menú ▲▼ 1. UNO 2. DOS 3. TRES 4. CUATRO 5. ESC - SALIR Por ejemplo, seleccionamos el 3. TRES. Pulse Enter y justo una línea de abajo dice: 3. TRES ▲▼ Después de pulsar Enter, se sustituye el texto 3. TRES ▲▼ por otro abajo. Alum. ●●●●●●○○ En el cual podemos hacer cosas, estando ya en la subopción indicado arriba. Si pulsamos Enter, de Alum. ●●●●●●○○ vuelve al menú principal en este caso donde estaba, llamdo 3. TRES ▲▼. Si etás todavía en Alum. ●●●●●●○○, puedes pulsar la teclas arriba y abajo para mover las opciones indicadas de esta manera mostrada abajo. Son 8 puntos. Lo que hace es alumbrar el brillo de una luz, el brillo más débil es de esta manera. Alum. ○○○○○○○○. El brillo máximo es de otra manera, Alum. ●●●●●●●●. Con las flechas del teclado arriba y abajo, seleccionamos un punto, de 1 hasta 8. La mitad sería así: Alum. ●●●●○○○○. Pulsa enter, guarda la configuración en una variable para que la recuerde y sale al menú principal. Espero que se entienda lo que quiero hacer. Dejo el código base, solo selecciona opciones pero al pulsar Enter tiene que hacer al menos el 3. TRES. Código consola C#: Código
Captura: (https://www.subeimagenes.com/img/1399013-1998653.png) Una cosa a tener en cuenta. En vez de aparecer MENú ▲▼ En pantalla, lo primero que debe aparecer en el programa en HOLA. Si pulsas Enter, entonces ya aparece el Menú. Si pulsa salir apareces en HOLA. Luego hacer lo demás con el 3. TRES indicado arriba. ¿Alguna ayuda? Saludos. Título: Re: Menús en modo consola Publicado por: Serapis en 6 Febrero 2019, 17:58 pm De entrada, una mejor opción es ofrecer al usuario opciones que ya conoce, como subrayar determinada letra, para invitarle a pulsar dicha tecla, es decir relacionar la tecla con dicho menú.
Así se pasaría de este menú soseras: 1. UNO 2. DOS 3. TRES 4. CUATRO 5. ESC - SALIR ...a uno más elaborado así: UNO DOS TRES CUATRO SUBMENU » SALIR (Esc) Nota que ahora, cuando se pulsa una tecla se revisa si es alguna de las subrayadas, en vez de números. Las teclas Up y Down (left y Right) siguen haciendo lo mismo, moverse entre opciones deseleccionando el actual que pasa a ser el previo y seleccionado el nuevo que pasa a ser el actual, y al tiempo seleccionas el carácter para dicho menú... es decir tu tendrás un string tal que UDTCMS, y al tiempo de subir y bajar el cursor, paseas entre dichas letras, tal que cuando se pulse la tecla enter, haces equivaler esa letra como la opción. Así tendrías: Código: char opcion, previa Cuando el usuario pulsa una tecla: Código: previa = opcion Verificar si la tecla pulsada 'opcion' es alguna para la que tenemos una acción definida, en cuyo caso ejecutamos su código. Código: funcion menuAcciones Nota que he añadido un submenú Segundo. Recuerda que puedes cambiar la fuente que se usa en la consola. Hay fuentes que contienes los glifos muy apropiados para determinadas cosas... por ejemplo hay fuentes que tienen las teclas (fuente: Game Key 2), muchas flechitas (fuente: Game control) símbolos (fuente: Alchemy), circulos como los que quieres para señalar el nivel de brillo (fuente: Almanac Mt) que tiene para las fases de la luna, los símbolos para luna llena y luna nueva, te pueden valer para lo que quieres... pero vamos hay muchísimas fuentes... tómate 1 día para verlas y elegir la que mejor se acomode. ten en cuenta que puede que al elegir un menú tengas que seleccionar una fuente y luego al slair de él, volver a la fuente previa. Y recuerda también que si el programa no son solo pruebas para ti, sino que es algo que será compilado y repartido, si las fuentes no son las habituales que contiene-mantiene el S.O. será conforme que se acompañen con el programa. Ah... eso de "Alum." suena más a aluminio que a alumbrar, te sugiero que uses "Nivel de brillo" mejor, y si es demasiado largo, solo "Brillo +" y "Brillo -", y que responda a subir y bajar el brillo no solo las flechas de cursor, UP=right= + y Down=left= - es decir 3 teclas como equivalentes de la misma acción. Por la misma razón, si la opción 3 ya tiene asignada una acción, no la llames TRES, llámala BRILLO y como aloja un submenú, síguele con una flechita de indicador de submenú: BRILLO » UNO DOS BRILLO » CUATRO SUBMENU » SALIR (Esc) Así ahora el submenú que se abre al pulsar B (o tener seleccionada la opcion actual=2 (contando 0, es la 3ª), sería así: SUBIR BRILLO + BAJAR BRILLO - -------------------------- NIVEL ●●●●○○○○ -------------------------- VOLVER Y por fin, te señalo como hacer un menú consistente, del que puedas hacer cosas más o menos complejas, pero asequibles, facilitando enormemente la tarea. Lo ideal es que crees una clase Menu, y añadas métodos... por ejemplo en el 'New', le pasas el string (que pondré unas líneas más abajo), como un array de strings... que luego la clase debe procesar. Dibujar un menú es tener elaborado un pequeño menú, como operas con consola, puede ser elaborado enteramente en string... sigue leyendo... Citar -1 Raiz 7 -2 00 0UNO 0 -1 01 0DOS 0 -1 02 0BRILLO 6 -1 03 0SUBIR BRILLO + 0 2 04 0BAJAR BRILLO - 0 2 05 ---------------- 0 2 06 NIVEL (N) 0 2 07 ---------------- 0 2 08 0VOLVER 0 2 09 0CUATRO 0 -1 10 1CINCO 0 -1 11 ---------------- 0 -1 12 0SALIR 0 -1 Si te das cuenta, poner un tabulador (en el foro espacios, porque no deja poner tabuladores), es más por ver visualmente la jerarquía del menú y corregir si algo no está bien... ya que la jerarquía real se expresa con los números en las columnas de la derecha. También si te fijas, hay varias columna... Esto sugiere pués crear una estructura Item, debajo las explicaciones de dicha estructura y relacionarla con esas línea de texto que contienene el menú: Código: Estructura Item Inicialmente se parte de un array de esta estructura, que se crea a partir del string anteriormente indicado. Visiblemente no está muy logrado (no me apetece perder demasiado tiempo en ello), pero te describo cada columna. - La columna 0 en realidad es innecesaria reflejarla en el string. Es el índice correlativo (es decir la enésima línea), que viene a coincidir con el índice en el array, la he puesto solo para facilitar señalar a qué indice apuntar como padre. En la estructura si debe hacerse constar, pués en caso de tener hijos, empieza en el índice siguiente a éste, por lo que es preciso conocerlo. - La columna 1 es un dígito (0-9) indica que carácter del texto estará subrayado (hotspot en la estructura). Si no tiene dígito, en la estructura debe consignarse -1. A la hora de dibujar dicho ítem, se considera si el número es mayor o igual a 0, en cuyo caso la letra en dicha posición se subraya (también vale dibujarla de otro color o ponerla en negrita). - La columna 2 contiene el texto del menú (si te gusta todo en mayúsculas allá tú). Campo 'nombre' de la estructura. - La columna 3 es un número, señala cuantos hijos tiene. Si un menú tiene hijos, tendrá un valor mayor que 0, y servirá para en un bucle localizarlos y saber cuando terminar... cuando se seleccione un ítem tu invocas a tu clase: Código: Si menu.Item(x).tieneHijos - La columna 4 es un número, señala quien es el padre de dicho menú. Observa como todo el submenú de brillo (indice 2), tiene como padre precisamente el valor 2 (indices 3 a 8). Un valor -1 indica que están el padre es raíz, es decir que no admite referencia al padre. - Una posible columna 5 podría indicar otras opciones como fuente (supongamos que usas 5 fuentes distintas, un dígito indicaría que fuente usar) . nuevamente solo los ítems que son submenús tendrían un digito a considerar, para el resto un valor -1... Este sería el code para el ítem 'Volver de un submenú... Código: if menu.item(x).padre > -1 Código: if menu.item(x).padre => 0 Por último, recuerda separar adecuadamente el tratamiento de datos del procesado de dibujado. Para el procesado de los datos, sugiero una clase menú, que maneje ítems. Y un array de estructuras Item. Para el dibujado también sugiero encapsular todo el proceso en una clase que en un método dibujar, recibe como parámetro la clase menú (para tener acceso a los miembros de la clase) y un ítem del menú, (el programa tiene un ítem -1 que es raíz y que despliega el menú principal, que suele ser un menú horizontal, del que descuelgan luego 'las ramas'), y es éste ítem para el que a través del menú dibujará sus ítems hijos, observando cuantos hijos tiene, sabiendo que empiezan un índice después y que sus hijos son aquellos que tiene en el campo padr,e el índice de dicho ítem. La clase principal, es la que muestra el resultado y la que intercede entre el menú, el usuario y la clase dibujado. La clase de dibujar, puede alojar también opciones sobre la fuente usada, colores a usar en cada caso, etc... si se simplifica al extremo, quizás no requiera usar una clase para ello, es decir contener un simple método "dibujarMenu", no justifica una clase. ...confío que te ilustre lo sufieciente para mejorar tu esquema aunque lo complique un poco y tardes más, a futuro tendrás un base adecuada para proyectos más o menos complejos... que te ayudarían a ahorrar mucho tiempo. P.d: Cuando solicitas al menú que te devuelve un submenú, también se crea una cadena o array 'hotkeys', que se compone exactamente de cada carácter hotkey de cada ítem del menú. Si un ítem no tiene hotkey, para ello se deja como carácter un char 'nulo', es decir un carácter que no sea pulsable por teclado, o dicho de otra manera, que no sean las teclas usadas 'enter, up, down, right, left, escape', ni letras o dígitos, por ejemplo '*' así de una sola evaluación puedes ver si hay que perder tiempo o no en procesar la tecla pulsada... por ejemplo la cadena hotkeys para el submenú brillo, podría ser: hotkeys = "SB***V" (de Subir, Bajar y Volver, las otros ítems del menú no generan acciones, una muestra el nivel del brillo y las otras dos son separadores de menús). Código: opcion = console.readkey Código: funcion CambiarFoco(entero ahora) Añadiendo ambos ´campos a la estructura: Código: Estructura Item Aquí como quedaría añadiendo esas 2 columnas nuevas a la derecha. El guión viene a indicar que no importa, no son seleccionables, no dan ancceso desde ellos al anterior y/o sigiente. Citar -1 Raiz 7 -2 - - 00 0UNO 0 -1 1 - 01 0DOS 0 -1 2 0 02 0BRILLO 6 -1 9 1 03 0SUBIR BRILLO + 0 2 4 - 04 0BAJAR BRILLO - 0 2 8 3 05 ---------------- 0 2 - - 06 NIVEL (N) 0 2 - - 07 ---------------- 0 2 - - 08 0VOLVER 0 2 - 4 09 0CUATRO 0 -1 10 2 10 1CINCO 0 -1 12 9 11 ---------------- 0 -1 - - 12 0SALIR 0 -1 - 10 Título: Re: Menús en modo consola Publicado por: Meta en 7 Febrero 2019, 06:16 am Gracias, estoy en ello. ;)
Lo dejo más claro, luego hago esquema de cada submenú. (https://www.subeimagenes.com/img/aaaaaaaaaaaaaaaaaaaaaaaaaaaa-1999154.PNG) Antes usé solo if (https://docs.microsoft.com/es-es/dotnet/csharp/language-reference/keywords/if-else). Ahora hice lo mismo pero con Switch (https://docs.microsoft.com/es-es/dotnet/csharp/language-reference/keywords/switch). No se cual es el más indicado para hacer el submenú. Código
Salu2. Título: Re: Menús en modo consola Publicado por: Serapis en 7 Febrero 2019, 15:16 pm If es el más adecuado cuando slo tienes 2,3 o si me apuras hasta 4 opciones...
Cuando sean múltiples opciones, el switch ofrece mucha más claridad. O cuando sean 3 o 4 pero cada caso comparte parcialmente acciones, ya que con un correcto orden el uso de break, facilita la no duplicación de código. Título: Re: Menús en modo consola Publicado por: Meta en 7 Febrero 2019, 21:39 pm Buenas:
Hoy me volví loco de la cabeza. Entrego código incompleto, lo entrego como curiosidad. Lo intentaré acabarlo al 100 %. Código
Hay una parte en Ver Radio que no me sale. Si pulso la fecla del teclado arriba, me sale "Radio: On". Si sigo pulsado la fecla arriba otra vez, se queda en On, lo mismo hacia abajo, que se queda en Off. ¿Hay alguna manera de que si pulso la tecla flecha arriba todo el rato o abajo se cambie en On y Off? El código es esta función. Código
Saludos ;) Título: Re: Menús en modo consola Publicado por: Serapis en 8 Febrero 2019, 18:33 pm Aunque no he revisado el código... basta una ojeada rápida para ver que tiene mejor pinta...
Sobre tus dudas: Citar Si pulso la fecla del teclado arriba, me sale "Radio: On". Si sigo pulsado la fecla arriba otra vez, se queda en On, lo mismo hacia abajo, que se queda en Off. A ver si te he entendido correctamente...¿Hay alguna manera de que si pulso la tecla flecha arriba todo el rato o abajo se cambie en On y Off? Tu tienes off, pulsas cursor arriba y se pone on, preguntas que si sería posible que si segir pulsando cursor arriba cambie de on a ofF (y viceversa en caso opuesto)?? Si te entendí bien, la respuesta es sí... Observa esta pequeña reflexión: Código: entero estadoRadio= 0 // off Si lo examinas bien, si está off, y pulsas arriba se pone en on, una nueva pulsación arriba, aumenta una cuenta, y si se pulsa las veces sufientes la cuenta llega a umbral, que lo pone al estado contrario. Debajo de esa operatoria, finalmente se dibuja el estado 'on/off' resultante . Tu decides el valor de umbral, pero que sea mayor que 2, si no, es preferibel usar un buleano, que alterne el valor inndistintamente de la tecla pulsada (y en ese caso es mejor que responda a la tecla espacio o enter), donde una pulsación lo pone 'on' y una nueva pulsación en 'off'). Si pulsas la tecla, con una duración larga sin soltarla y esperas que responda a dicho estado, se complica la cosa por consola... esa gestión desde interfaz es sencilla, pués la provee la propio ventana/formulario con eventos 'keyDown' (tecla pulsada) y 'keyUp' (tecla soltada), por consola no creo que merezca la pena perder el tiempo, resultará farragoso y las consolas están pensadas para determinadas acciones. Si la interacción con el usuario debe ser más poderosa, estonces siempre es mejor abandonar la consola y proveer una interfaz de usuario con todo su potencial. Esto es, cada cosa hay que usarla para lo que se ha diseñado, mejor, que para hacer aquello para lo que justamente no ha sido diseñado. A nadie se le ocurre usar un patinete para transportar containers de mercancías, ni usar un un tren de alta velocidad como el juguete de un niño. Título: Re: Menús en modo consola Publicado por: Meta en 8 Febrero 2019, 20:47 pm Hola:
Sí, haz entedido bien, tamién es mejor la opción booleana. Lo saqué así al final. Código
Si vez que ahora dice el On y Off si pulso todo el rato arriba o abajo ya puedo cambiar, tal como lo haz entendido. Si te fijas bien, el On y Off está fijo. Quiero que parpadee en cada 0.5 segundos, o lo que es lo mismo, 500 ms (mili segundos). Iba a usar Sleep, pero prefiero usar timer para que no se quede esclavo el programa aunque sea corto de tiempo. ¿Por qué quiero hacer esto así? Porque estoy practicando en modo consola usando el 16x2, aunque ahora mismo el 16x1. Cuando lo domine partes por partes lo que deseo, como el booleano, el XXXXXX-- del brillo, y me falta el volumen del 0 que es mute hasta aumentar el sonido hasta el 7. Poco a poco lo estoy haciendo. Cuando acabe con C#, adaptaré este código a un LCD real de 16x2 como puedes ver aquí. Quiero aprender hacer menús para LCD pero primero que acabo antes, en PC. ;) (https://potentiallabs.com/cart/image/cache/catalog/lcd162b-800x800.jpg) Saludos. |