00001 #include <Slang/menu.H>
00002
00003 #include <Slang/teclado.H>
00004
00005 #include <cctype>
00006
00007 using namespace std;
00008
00009
00010
00011
00012 Slang::MenuSimples::MenuSimples(string const& titulo,
00013 string const& itens_juntos)
00014 : MenuComCor(titulo), corrente(0)
00015 {
00016
00017
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
00023 itens.push_back(itens_juntos.substr(inicio, fim - inicio));
00024 inicio = fim + 1;
00025 }
00026
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
00049
00050 Ecra::Troco troco = ecra.copia();
00051
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
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
00097 ecra << o_borda() << caixa(posicao, dimensao);
00098
00099
00100 ecra << o_titulo() << cursor(posicao + Posicao(1, 1))
00101 << largura(largura_maxima) << titulo();
00102
00103
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
00112
00113 std::string Slang::CaixaDeTexto::executa(bool impede_vazia)
00114 {
00115
00116
00117 Ecra::Troco troco = ecra.copia();
00118
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
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 :
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
00209 ecra << o_borda() << caixa(origem, dimensao);
00210
00211
00212 ecra << o_titulo() << cursor(origem + Posicao(1, 1))
00213 << largura(espacos) << titulo();
00214
00215
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
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
00237
00238
00239
00240
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