Menú ¿Dinámico? en C

Iniciado por Gunhack, 5 Abril 2015, 20:22 PM

0 Miembros y 1 Visitante están viendo este tema.

Gunhack

Buenas, no se si tenga algún nombre en especifico este tipo de menús, acabo de hacer esta "plantilla" por así decirlo, sólo que quiero saber si se puede simplificar más o que consejo me darían para hacer los menús así.  ;D


Código (cpp) [Seleccionar]

#include <iostream>
#include <conio.h>
#include <stdlib.h>
#include <stdio.h>
#include <windows.h>

using namespace std;
//Define las opciones máximas.
#define opmax 3

void SetBG(int ForgC, int BackC);
void menu ();
int tec(int *o1,int *o2,int *o3,int *y,int *t1,int *t2,int *t3);

main ()
{
 while (1)
 {
   menu();
 }
}
//Define la función de menú
void menu ()
{
 SetBG(15,0);
 static int o1=14,o2=0,o3=0,y=0,t1=0,t2=15,t3=15;

do{
   system("cls");
   cout << "\n   MENU";
   cout << "\n==========";
   SetBG(t1,o1);
   cout << "\n\n*Opcion 1";
   SetBG(t2,o2);
   cout << "\n\n*Opcion 2";
   SetBG(t3,o3);
   cout << "\n\n*Opcion 3";
   SetBG(15,0);
 }while (tec(&o1,&o2,&o3,&y,&t1,&t2,&t3)!=13);

 switch (y)
 {
   case 1: system("cls");cout << "Ejecutando 1";
           break;
   case 2: system("cls");cout << "Ejecutando 2";
           break;
   case 3: system("cls");cout << "Ejecutando 3";
           break;
   default: break;

 }
 getch();
}
//Define la función que lee las teclas usadas por el usuario.
int tec(int *o1,int *o2,int *o3,int *y,int *t1,int *t2,int *t3)
{
   int s;
   s=getch();
   switch (s)
   {
     case char(72):  *y-=1;
                     break;
     case char(80):  *y+=1;
                     break;
     case char(13):  return 13;
                     break;
     default:  break;
   }
   switch (*y)
   {
     case 1: *o1=14;*o2=0;*o3=0;
             *t1=0;*t2=15;*t3=15;
             break;
     case 2: *o1=0;*o2=14;*o3=0;
             *t1=15;*t2=0;*t3=15;
             break;
     case 3: *o1=0;*o2=0;*o3=14;
             *t1=15;*t2=15;*t3=0;
             break;
     default:  break;
   }

   if (*y==0)
     *y+=1;
   if (*y>opmax)
     *y=*y-1;
}

void SetBG(int ForgC, int BackC)
{
 WORD wColor = ((BackC & 0x0F) << 4) + (ForgC & 0x0F);;
 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), wColor);
}


ivancea96

A lo mejor te interesa que menu() retorne la opción elegida, para que no haya sido en vano xD

También puedes pasarle a meno un arreglo de opciones, para no tener que andar tocando la función en sí.

https://github.com/ivancea/Varios/blob/master/C%2B%2B/selector.h
Ahí un ejemplo de una clase en C++, sin usar windows.h.

Gunhack

Cita de: ivancea96 en  5 Abril 2015, 21:55 PM
A lo mejor te interesa que menu() retorne la opción elegida, para que no haya sido en vano xD

También puedes pasarle a meno un arreglo de opciones, para no tener que andar tocando la función en sí.

https://github.com/ivancea/Varios/blob/master/C%2B%2B/selector.h
Ahí un ejemplo de una clase en C++, sin usar windows.h.

No se si te entendí bien con lo de la función menu(), pero si retoma la opción o bueno al regresar si se queda seleccionada, solo quería saber si el código que hice se puede simplificar x).
Veré si puedo hacer lo de los arreglos y gracias aunque aún no se programar en C++  :xD

eferion

#3
¿Qué tal algo así?

Código (cpp) [Seleccionar]
#include <iostream>
#include <set>
#include <vector>
#include <conio.h>
#include <windows.h>

class MenuItem
{
 public:

   MenuItem( char tecla,
             const std::string& texto,
             unsigned char backColor,
             unsigned char foreColor )
     : _tecla( tecla ),
       _texto( texto ),
       _backColor( backColor ),
       _foreColor( foreColor )
   { }

   ~MenuItem( )
   { }

   char Tecla( ) const
   { return _tecla; }

   std::string Texto( ) const
   { return _texto; }

   unsigned char BackColor( ) const
   { return _backColor; }

   unsigned char ForeColor( ) const
   { return _foreColor; }

 private:

   char _tecla;
   std::string _texto;
   unsigned char _backColor;
   unsigned char _foreColor;
};

void SetBG(unsigned char ForgC, unsigned char BackC);
void menu();
char mostrarMenu( const std::vector< MenuItem >& items );

main ()
{
while (1)
{
  menu();
}
}

//Define la función de menú
void menu()
{
 std::vector< MenuItem > items;
 items.push_back( MenuItem( '1', "Opción 1", 14, 0 ) );
 items.push_back( MenuItem( '2', "Opción 2", 0, 5 ) );
 items.push_back( MenuItem( 'a', "Opción 3", 4, 7 ) );

 char opcion = mostrarMenu( items );

 switch( opcion )
 {
   case '1':
     system( "cls" );
     std::cout << "Ejecutando 1" << std::endl;
     break;
   case '2':
     system( "cls" );
     std::cout << "Ejecutando 2" << std::endl;
     break;
   case 'a':
     system( "cls" );
     std::cout << "Ejecutando 'a'" << std::endl;
     break;

   default:
     break;
 }

 getch( );
}

char mostrarMenu( const std::vector< MenuItem >& items )
{
 char to_return;
 std::set< char > validAnswer;

 do
 {
   system( "cls" );
   std::cout << "   MENU" << std::endl
             << "===================" << std::endl;
   for( auto& item : items )
   {
     SetBG( item.ForeColor( ), item.BackColor( ) );
     std::cout << "  " << item.Tecla( ) << ". " << item.Texto( ) << std::endl;
     validAnswer.insert( item.Tecla( ) );
   }
   SetBG(15,0);
   std::cin >> to_return;

 } while( validAnswer.count( to_return ) == 0 );

 return to_return;
}

void SetBG(unsigned char ForgC, unsigned char BackC)
{
 WORD wColor = ((BackC & 0x0F) << 4) + (ForgC & 0x0F);
 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), wColor);
}


Se podría conseguir un código más claro si se "mapeasen" los colores:

Código (cpp) [Seleccionar]

enum Color : unsigned char
{
  Black,
  DarkBlue,
  DrakGreen,
  DarkAqua,
  DarkRed,
  DarkPurple,
  DarkYellow,
  Silver,
  Gray,
  Blue,
  Green,
  Aqua,
  Red,
  Purple,
  Yellow,
  White
};

// ...

class MenuItem
{
  public:

    MenuItem( char tecla,
              const std::string& texto,
              Color backColor,
              Color foreColor );

    Color BackColor( ) const;

    Color ForeColor( ) const;

  private:

    Color _backColor;
    Color _foreColor;
};

// ...

  items.push_back( MenuItem( '1', "Opción 1", Black, Red ) );
  items.push_back( MenuItem( '2', "Opción 2", Black, Blue ) );
  items.push_back( MenuItem( 'a', "Opción 3", Silver, Purple ) );