00001
00007 #include <Slang++/menu.H>
00008 #include <Slang++/teclado.H>
00009
00010 using namespace std;
00011
00012
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
00021
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
00027 itens.push_back(itens_juntos.substr(inicio, fim - inicio));
00028 inicio = fim + 1;
00029 }
00030
00031
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
00052
00053 Ecra::Troco troco = ecra.trocoDoEcraCompleto();
00054
00055
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
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
00119 ecra << objectoCorDaBorda() << caixa(posicao, dimensao);
00120
00121
00122 ecra << objectoCorDoTitulo() << posicao + Dimensao(1, 1)
00123 << largura(comprimento_maximo_dos_itens) << titulo();
00124
00125
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
00153
00154 void Slang::CaixaDeTexto::interage()
00155 {
00156 assert(cumpreInvariante());
00157
00158
00159
00160 Ecra::Troco troco = ecra.trocoDoEcraCompleto();
00161
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
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 :
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
00297 ecra << objectoCorDaBorda() << caixa(origem, dimensao);
00298
00299
00300 ecra << objectoCorDoTitulo() << origem + Dimensao(1, 1)
00301 << largura(numero_de_espacos_visiveis) << titulo();
00302
00303
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
00313
00314 #ifdef TESTE
00315
00316 int main()
00317 {
00318
00319 }
00320
00321 #endif