Página principal   Módulos   Lista de namespaces   Hierarquia de classes   Lista de componentes   Lista de ficheiros   Membros do namespace   Componentes   Declarações   Paginas relacionadas  

menu.C

Ir para a documentação deste ficheiro.
00001 #include <Slang/menu.H>
00002 
00003 #include <Slang/teclado.H>
00004 
00005 #include <cctype>
00006 
00007 using namespace std;
00008 
00009 
00010 // Métodos não inline da classe MenuSimples:
00011 
00012 Slang::MenuSimples::MenuSimples(string const& titulo, 
00013                                 string const& itens_juntos) 
00014     : MenuComCor(titulo), corrente(0)
00015 {
00016     // itens_juntos tem todos os itens separados por \n.  Obtê-los todos
00017     // separados:
00018     string::size_type inicio = 0;
00019     string::size_type fim;
00020     while((fim = itens_juntos.find('\n', inicio)) != string::npos) {
00021         if(fim - inicio != 0)
00022             // Itens vazios não se põem...
00023             itens.push_back(itens_juntos.substr(inicio, fim - inicio));
00024         inicio = fim + 1;
00025     }
00026     // Ainda pode haver um, se a última linha não terminou em '\n'!
00027     if(inicio < itens_juntos.length())
00028         itens.push_back(itens_juntos.substr(inicio));
00029 
00030     numero_de_itens = int(itens.size());
00031     
00032     calculaDimensao();
00033     calculaPosicao();
00034 }
00035 
00036 void Slang::MenuSimples::calculaDimensao()
00037 {
00038     largura_maxima = titulo().length();
00039     for(int i = 0; i != numero_de_itens; ++i)
00040         if(largura_maxima < itens[i].size())
00041             largura_maxima = itens[i].size();
00042     dimensao.linhas(numero_de_itens + 3);
00043     dimensao.colunas(largura_maxima + 2);
00044 }
00045 
00046 int Slang::MenuSimples::executa() 
00047 {
00048     // Copiar ecrã sem menu (Afazeres: copiar apenas parte afectada pelo
00049     // menu!):
00050     Ecra::Troco troco = ecra.copia();
00051     // Guardar posição do cursor:
00052     Posicao c = ecra.cursor();
00053     
00054     desenha();
00055     desenhaItem(corrente);
00056     ecra << refresca;
00057     while(true) {
00058         if(ecra.redimensionado()) {
00059             calculaPosicao();
00060             ecra.cola(troco);
00061             desenha();
00062             desenhaItem(corrente);
00063             ecra << refresca;
00064         }
00065         if(teclado.teclaDisponivel(1))
00066             switch(teclado.tecla()) {
00067               case Tecla::entrada:
00068                 // Volta ao normal:
00069                 ecra.cola(troco);
00070                 ecra << c << fundo << refresca;
00071                 return corrente;
00072               case Tecla::cima:
00073                 if(corrente != 0) {
00074                     --corrente;
00075                     desenhaItem(corrente + 1);
00076                     desenhaItem(corrente);
00077                     ecra << refresca;
00078                 }
00079                 break;
00080               case Tecla::baixo:
00081                 if(corrente != numero_de_itens - 1) {
00082                     ++corrente;
00083                     desenhaItem(corrente - 1);
00084                     desenhaItem(corrente);
00085                     ecra << refresca;
00086                 }
00087                 break;
00088               default:
00089                 break;
00090             }
00091     }
00092 }
00093 
00094 void Slang::MenuSimples::desenha() const 
00095 {
00096     // Desenhar caixa:
00097     ecra << o_borda() << caixa(posicao, dimensao);
00098 
00099     // Desenhar titulo:
00100     ecra << o_titulo() << cursor(posicao + Posicao(1, 1)) 
00101          << largura(largura_maxima) << titulo();
00102         
00103     // Desenhar itens:
00104     ecra << o_itens();
00105     for(int i = 0; i != numero_de_itens; ++i)
00106         ecra << cursor(posicao + Posicao(2 + i, 1)) 
00107              << largura(largura_maxima) << itens[i];
00108 }
00109 
00110 
00111 // Métodos não inline da classe CaixaDeTexto:
00112 
00113 std::string Slang::CaixaDeTexto::executa(bool impede_vazia)
00114 {
00115     // Copiar ecrã sem menu (Afazeres: copiar apenas parte afectada pelo
00116     // menu!):
00117     Ecra::Troco troco = ecra.copia();
00118     // Guardar posição do cursor:
00119     Posicao c = ecra.cursor();
00120     
00121     desenha();
00122     ecra << refresca;
00123     while(true) {
00124         if(ecra.redimensionado()) {
00125             calculaPosicao();
00126             ecra.cola(troco);
00127             desenha();
00128             ecra << refresca;
00129         }
00130         if(teclado.teclaDisponivel(1)) {
00131             Tecla tecla = teclado.tecla();
00132             switch(tecla) {
00133               case Tecla::entrada:
00134                 if(!impede_vazia || valor.length() != 0) {
00135                     // Volta ao normal:
00136                     ecra.cola(troco);
00137                     ecra << c << fundo << refresca;
00138                     return valor;
00139                 }
00140                 break;
00141               case Tecla::esquerda:
00142                 if(posicao > 0)
00143                     --posicao;
00144                 else if(inicio > 0)
00145                     --inicio;
00146                 desenha();
00147                 ecra << refresca;
00148                 break;
00149               case Tecla::direita:
00150                 if(posicao < valor.length() - inicio)
00151                     if(posicao < espacos - 1)
00152                         ++posicao;
00153                     else
00154                         ++inicio;
00155                 desenha();
00156                 ecra << refresca;
00157                 break;
00158               case Tecla::apaga:
00159                 if(inicio + posicao < valor.length())
00160                     valor.erase(inicio + posicao, 1);
00161                 desenha();
00162                 ecra << refresca;
00163                 break;
00164               case Tecla::apaga_para_tras:
00165               case 8 /* ctrl-H */:
00166                 if(inicio + posicao > 0) {
00167                     if(posicao > 0)
00168                         --posicao;
00169                     else
00170                         --inicio;
00171                     valor.erase(inicio + posicao, 1);
00172                 }
00173                 desenha();
00174                 ecra << refresca;
00175                 break;
00176               case Tecla::casa:
00177                 posicao = 0;
00178                 inicio = 0;
00179                 desenha();
00180                 ecra << refresca;
00181                 break;
00182               case Tecla::fim:
00183                 if(valor.length() - inicio < espacos)
00184                     posicao = valor.length() - inicio;
00185                 else {
00186                     posicao = espacos - 1;
00187                     inicio = valor.length() - espacos + 1;
00188                 }
00189                 desenha();
00190                 ecra << refresca;
00191                 break;
00192             }
00193             if(tecla.caractere() && isprint(tecla.comoChar())) {
00194                 valor.insert(inicio + posicao, 1, tecla.comoChar());
00195                 if(posicao < espacos - 1)
00196                     ++posicao;
00197                 else
00198                     ++inicio;
00199                 desenha();
00200                 ecra << refresca;
00201             }
00202         }
00203     }
00204 }
00205 
00206 void Slang::CaixaDeTexto::desenha() const 
00207 {
00208     // Desenhar caixa:
00209     ecra << o_borda() << caixa(origem, dimensao);
00210 
00211     // Desenhar titulo:
00212     ecra << o_titulo() << cursor(origem + Posicao(1, 1)) 
00213          << largura(espacos) << titulo();
00214         
00215     // Desenhar valor:
00216     ecra << o_corrente();
00217     ecra << cursor(origem + Posicao(2, 1)) 
00218          << largura(espacos) << valor.substr(inicio) 
00219          << cursor(origem + Posicao(2, 1 + posicao));
00220 }
00221 
00222 
00223 // Programa de teste:
00224 
00225 #ifdef TESTE
00226 
00227 using namespace Slang;
00228 
00229 extern "C" {
00230 #include <unistd.h>
00231 }
00232 
00233 int main()
00234 {
00235     /*
00236     string valor = CaixaDeTexto("O seu nome é:",
00237                                 "Manuel Menezes de Sequeira",
00238                                 5).executa(true);
00239     ecra << cursor(0, 0) << valor << refresca;
00240     sleep(3);*/
00241     ecra << cursor(1, 0) 
00242          << MenuSimNao("Sim ou não, eis a questão...").executa()
00243          << refresca;
00244     sleep(3);
00245 }
00246 
00247 #endif

Gerado em Mon May 14 17:22:13 2001 para Slang++ por doxygen1.2.6 escrito por Dimitri van Heesch, © 1997-2001