Página principal   Módulos   Lista de namespaces   Hierarquia de classes   Lista de componentes   Lista de ficheiros   Membros do namespace   Componentes membro   Ficheiros membro   Páginas relacionadas  

menu.C

Ir para a documentação deste ficheiro.
00001 
00007 #include <Slang++/menu.H>
00008 #include <Slang++/teclado.H>
00009 
00010 using namespace std;
00011 
00012 // MenuSimples:
00013 
00014 Slang::MenuSimples::MenuSimples(string const& titulo, 
00015                                 string const& itens_juntos) 
00016     : MenuComCor(titulo), opcao_corrente(0)
00017 {
00018     assert(titulo != "" and Utilitarios::eImprimivel(titulo));
00019 
00020     // itens_juntos tem todos os itens separados por \n.  Obtê-los todos
00021     // separados:
00022     string::size_type inicio = 0;
00023     string::size_type fim;
00024     while((fim = itens_juntos.find('\n', inicio)) != string::npos) {
00025         if(fim - inicio != 0)
00026             // Itens vazios não se põem...
00027             itens.push_back(itens_juntos.substr(inicio, fim - inicio));
00028         inicio = fim + 1;
00029     }
00030 
00031     // Ainda pode haver um, se a última linha não terminou em '\n'!
00032     if(inicio < itens_juntos.length())
00033         itens.push_back(itens_juntos.substr(inicio));
00034 
00035     numero_de_itens = int(itens.size());
00036 
00037     assert(1 <= numero_de_itens);
00038     for(int i = 0; i != numero_de_itens; ++i)
00039         assert(Utilitarios::eImprimivel(itens[i]));
00040     
00041     calculaDimensao();
00042     calculaPosicao();
00043 
00044     assert(cumpreInvariante());
00045 }
00046 
00047 void Slang::MenuSimples::interage() 
00048 {
00049     assert(cumpreInvariante());
00050 
00051     // Copiar ecrã sem menu.  
00052     // \todo Copiar apenas parte afectada pelo menu!
00053     Ecra::Troco troco = ecra.trocoDoEcraCompleto();
00054 
00055     // Guardar posição do cursor:
00056     Posicao c = ecra.posicaoDoCursor();
00057     
00058     desenha();
00059     desenhaItem(opcao_corrente);
00060     ecra << refresca;
00061     while(true) {
00062         if(ecra.foiRedimensionado()) {
00063             calculaPosicao();
00064             ecra.cola(troco);
00065             desenha();
00066             desenhaItem(opcao_corrente);
00067             ecra << refresca;
00068         }
00069         if(teclado.haTeclaDisponivel(1)) {
00070             teclado.leProximaTeclaDisponivel();
00071             switch(teclado.teclaLida()) {
00072               case Tecla::entrada:
00073                 // Volta ao normal:
00074                 ecra.cola(troco);
00075                 ecra << c << fundo << refresca;
00076                 return;
00077               case Tecla::cima:
00078                 if(opcao_corrente != 0) {
00079                     --opcao_corrente;
00080                     desenhaItem(opcao_corrente + 1);
00081                     desenhaItem(opcao_corrente);
00082                     ecra << refresca;
00083                 }
00084                 break;
00085               case Tecla::baixo:
00086                 if(opcao_corrente != numero_de_itens - 1) {
00087                     ++opcao_corrente;
00088                     desenhaItem(opcao_corrente - 1);
00089                     desenhaItem(opcao_corrente);
00090                     ecra << refresca;
00091                 }
00092                 break;
00093               default:
00094                 break;
00095             }
00096         }
00097     }
00098 
00099     assert(cumpreInvariante());
00100 }
00101 
00102 void Slang::MenuSimples::calculaDimensao()
00103 {
00104     comprimento_maximo_dos_itens = titulo().length();
00105 
00106     for(int i = 0; i != numero_de_itens; ++i)
00107         if(comprimento_maximo_dos_itens < itens[i].size())
00108             comprimento_maximo_dos_itens = itens[i].size();
00109 
00110     dimensao.mudaNumeroDeLinhasPara(numero_de_itens + 3);
00111     dimensao.mudaNumeroDeColunasPara(comprimento_maximo_dos_itens + 2);
00112 }
00113 
00114 void Slang::MenuSimples::desenha() const 
00115 {
00116     assert(cumpreInvariante());
00117 
00118     // Desenhar caixa:
00119     ecra << objectoCorDaBorda() << caixa(posicao, dimensao);
00120 
00121     // Desenhar titulo:
00122     ecra << objectoCorDoTitulo() << posicao + Dimensao(1, 1) 
00123          << largura(comprimento_maximo_dos_itens) << titulo();
00124         
00125     // Desenhar itens:
00126     ecra << objectoCorDosItens();
00127     for(int i = 0; i != numero_de_itens; ++i)
00128         ecra << posicao + Dimensao(2 + i, 1) 
00129              << largura(comprimento_maximo_dos_itens) << itens[i];
00130 }
00131 
00132 inline bool Slang::MenuSimples::cumpreInvariante() const
00133 {
00134     if(not (1 <= numero_de_itens and int(itens.size()) == numero_de_itens and 
00135             0 <= opcao_corrente and opcao_corrente < numero_de_itens))
00136         return false;
00137 
00138     for(int i = 0; i != numero_de_itens; ++i)
00139         if(not Utilitarios::eImprimivel(itens[i]))
00140             return false;
00141 
00142     std::string::size_type comprimento_maximo = itens[0].length();
00143     for(int i = 1; i != numero_de_itens; ++i)
00144         if(comprimento_maximo < itens[i].size())
00145             comprimento_maximo = itens[i].size();
00146 
00147     return comprimento_maximo_dos_itens == 
00148         std::max(comprimento_maximo, titulo().length());
00149 }
00150 
00151 
00152 // CaixaDeTexto:
00153 
00154 void Slang::CaixaDeTexto::interage()
00155 {
00156     assert(cumpreInvariante());
00157 
00158     // Copiar ecrã sem menu (Afazeres: copiar apenas parte afectada pelo
00159     // menu!):
00160     Ecra::Troco troco = ecra.trocoDoEcraCompleto();
00161     // Guardar posição do cursor:
00162     Posicao c = ecra.posicaoDoCursor();
00163     
00164     desenha();
00165     ecra << refresca;
00166     while(true) {
00167         if(ecra.foiRedimensionado()) {
00168             calculaPosicao();
00169             ecra.cola(troco);
00170             desenha();
00171             ecra << refresca;
00172         }
00173         if(teclado.haTeclaDisponivel(1)) {
00174             teclado.leProximaTeclaDisponivel();
00175             Tecla tecla = teclado.teclaLida();
00176             switch(tecla) {
00177               case Tecla::entrada:
00178                 if(not impede_caixa_vazia or texto_corrente.length() != 0) {
00179                     // Volta ao normal:
00180                     ecra.cola(troco);
00181                     ecra << c << fundo << refresca;
00182 
00183                     return;
00184                 }
00185 
00186                 break;
00187 
00188               case Tecla::esquerda:
00189                 if(posicao_do_cursor_nos_espacos_visiveis > 0)
00190                     --posicao_do_cursor_nos_espacos_visiveis;
00191                 else if(inicio_da_parte_visivel_do_texto > 0)
00192                     --inicio_da_parte_visivel_do_texto;
00193                 desenha();
00194                 ecra << refresca;
00195 
00196                 break;
00197 
00198               case Tecla::direita:
00199                 if(posicao_do_cursor_nos_espacos_visiveis < 
00200                    texto_corrente.length() - inicio_da_parte_visivel_do_texto)
00201                     if(posicao_do_cursor_nos_espacos_visiveis < 
00202                        numero_de_espacos_visiveis - 1)
00203                         ++posicao_do_cursor_nos_espacos_visiveis;
00204                     else
00205                         ++inicio_da_parte_visivel_do_texto;
00206                 desenha();
00207                 ecra << refresca;
00208 
00209                 break;
00210 
00211               case Tecla::apaga:
00212                 if(inicio_da_parte_visivel_do_texto + 
00213                    posicao_do_cursor_nos_espacos_visiveis < 
00214                    texto_corrente.length())
00215                     texto_corrente.
00216                         erase(inicio_da_parte_visivel_do_texto + 
00217                               posicao_do_cursor_nos_espacos_visiveis, 1);
00218                 desenha();
00219                 ecra << refresca;
00220 
00221                 break;
00222 
00223               case Tecla::apaga_para_tras:
00224               case 8 /* ctrl-H */:
00225                 if(inicio_da_parte_visivel_do_texto + 
00226                    posicao_do_cursor_nos_espacos_visiveis > 0) {
00227                     if(posicao_do_cursor_nos_espacos_visiveis > 0)
00228                         --posicao_do_cursor_nos_espacos_visiveis;
00229                     else
00230                         --inicio_da_parte_visivel_do_texto;
00231                     texto_corrente.
00232                         erase(inicio_da_parte_visivel_do_texto + 
00233                               posicao_do_cursor_nos_espacos_visiveis, 1);
00234                 }
00235                 desenha();
00236                 ecra << refresca;
00237 
00238                 break;
00239 
00240               case Tecla::casa:
00241                 posicao_do_cursor_nos_espacos_visiveis = 0;
00242                 inicio_da_parte_visivel_do_texto = 0;
00243                 desenha();
00244                 ecra << refresca;
00245 
00246                 break;
00247 
00248               case Tecla::fim:
00249                 if(texto_corrente.length() - inicio_da_parte_visivel_do_texto <
00250                    numero_de_espacos_visiveis)
00251                     posicao_do_cursor_nos_espacos_visiveis = 
00252                         texto_corrente.length() - 
00253                         inicio_da_parte_visivel_do_texto;
00254                 else {
00255                     posicao_do_cursor_nos_espacos_visiveis = 
00256                         numero_de_espacos_visiveis - 1;
00257                     inicio_da_parte_visivel_do_texto = 
00258                         texto_corrente.length() - 
00259                         numero_de_espacos_visiveis + 1;
00260                 }
00261                 desenha();
00262                 ecra << refresca;
00263 
00264                 break;
00265 
00266               default:
00267                 if(tecla.eChar() and 
00268                    Utilitarios::eImprimivel(tecla.comoChar()) and
00269                    (caracteres_admissiveis == "" or 
00270                     caracteres_admissiveis.find(tecla.comoChar()) != 
00271                     string::npos)) {
00272                     texto_corrente.
00273                         insert(inicio_da_parte_visivel_do_texto + 
00274                                posicao_do_cursor_nos_espacos_visiveis, 1, 
00275                                tecla.comoChar());
00276                     if(posicao_do_cursor_nos_espacos_visiveis < 
00277                        numero_de_espacos_visiveis - 1)
00278                         ++posicao_do_cursor_nos_espacos_visiveis;
00279                     else
00280                         ++inicio_da_parte_visivel_do_texto;
00281                     desenha();
00282                     ecra << refresca;
00283                 } else
00284                     ecra << campainha;
00285 
00286                 break;
00287             }
00288         }
00289     }
00290 
00291     assert(cumpreInvariante());
00292 }
00293 
00294 void Slang::CaixaDeTexto::desenha() const 
00295 {
00296     // Desenhar caixa:
00297     ecra << objectoCorDaBorda() << caixa(origem, dimensao);
00298 
00299     // Desenhar titulo:
00300     ecra << objectoCorDoTitulo() << origem + Dimensao(1, 1)
00301          << largura(numero_de_espacos_visiveis) << titulo();
00302         
00303     // Desenhar texto:
00304     ecra << objectoCorDoItemCorrente();
00305     ecra << origem + Dimensao(2, 1)
00306          << largura(numero_de_espacos_visiveis) 
00307          << texto_corrente.substr(inicio_da_parte_visivel_do_texto) 
00308          << origem + Dimensao(2, 1 + posicao_do_cursor_nos_espacos_visiveis);
00309 }
00310 
00311 
00312 // Programa de teste:
00313 
00314 #ifdef TESTE
00315 
00316 int main()
00317 {
00318     // Ferramentas com interface gráfica não têm testes.
00319 }
00320 
00321 #endif

Gerado em Tue Dec 3 15:19:35 2002 para Pacotes por doxygen1.3-rc1