00001 #include <Slang/ecra.H>
00002
00003 #include <Slang/util.H>
00004
00005
00006
00007
00008 void Slang::Posicao::carrega(std::istream& entrada)
00009 {
00010 int l, c;
00011
00012 if(!(entrada >> l >> Slang::il >> c >> Slang::il))
00013 throw ErroAoCarregar("Posicao");
00014 linha_ = l;
00015 coluna_ = c;
00016 }
00017
00018 void Slang::Posicao::guarda(std::ostream& saida) const
00019 {
00020 if(!(saida << linha_ << endl << coluna_ << endl))
00021 throw ErroAoGuardar("Posicao");
00022 }
00023
00024
00025
00026
00027 void Slang::Dimensao::carrega(std::istream& entrada)
00028 {
00029 int l, c;
00030
00031 if(!(entrada >> l >> Slang::il >> c >> Slang::il))
00032 throw ErroAoCarregar("Dimensao");
00033 linhas_ = l;
00034 colunas_ = c;
00035 }
00036
00037 void Slang::Dimensao::guarda(std::ostream& saida) const
00038 {
00039 if(!(saida << linhas_ << endl << colunas_ << endl))
00040 throw ErroAoGuardar("Dimensao");
00041 }
00042
00043
00044
00045
00046 void Slang::Caixa::carrega(std::istream& entrada)
00047 {
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 Posicao origem(entrada);
00060 dimensao_.carrega(entrada);
00061 origem_ = origem;
00062
00063 }
00064
00065 void Slang::Caixa::guarda(std::ostream& saida) const
00066 {
00067 origem_.guarda(saida);
00068 dimensao_.guarda(saida);
00069 }
00070
00071
00072
00073 std::ostream& Slang::operator << (std::ostream& saida, Slang::Cor cor)
00074 {
00075 return saida << Slang::nomes_das_cores[cor];
00076 }
00077
00078 std::istream& Slang::operator >> (std::istream& entrada, Slang::Cor& cor)
00079 {
00080 string nome;
00081 if(entrada >> nome) {
00082 for(int c = Slang::primeira_cor; c != Slang::numero_de_cores; ++c)
00083 if(Slang::nomes_das_cores[c] == nome) {
00084 cor = Slang::Cor(c);
00085 return entrada;
00086 }
00087 entrada.clear(ios::badbit);
00088 }
00089 return entrada;
00090 }
00091
00092
00093
00094
00095 Slang::Ecra::Ecra(Cor texto, Cor fundo, bool limita_cursor)
00096 : limita_cursor(limita_cursor), redimensionado_(true),
00097 para_no_proximo(false), justificacao(a_esquerda), largura_do_proximo(0),
00098 ocupacao_objecto(256) {
00099
00100 assert(!existe_instancia);
00101
00102 existe_instancia = true;
00103
00104 SLtt_get_terminfo();
00105 if(SLsmg_init_smg() == -1) {
00106
00107 }
00108
00109 SLsignal(SIGWINCH, manipuladorTamanhoMudou);
00110 atributos(texto, fundo);
00111 }
00112
00113 Slang::Ecra::Troco Slang::Ecra::copia(Caixa const& caixa) const
00114 {
00115 verificaTamanho();
00116
00117
00118 Posicao const posicao_original_do_cursor = cursor();
00119
00120 int const linha = caixa.origem().linha();
00121 int const coluna = caixa.origem().coluna();
00122 int const linhas = caixa.dimensao().linhas();
00123 int const colunas = caixa.dimensao().colunas();
00124
00125 Troco troco(caixa.dimensao());
00126 int i = 0;
00127 for(int l = linha; l != linha + linhas; ++l)
00128 for(int c = coluna; c != coluna + colunas; ++c)
00129 {
00130 cursor(Posicao(l, c));
00131 troco.dados[i++] = SLsmg_char_at();
00132 }
00133
00134
00135 cursor(posicao_original_do_cursor);
00136
00137 return troco;
00138 }
00139
00140 void Slang::Ecra::cola(Troco const& troco, Posicao const& posicao)
00141 {
00142 verificaTamanho();
00143
00144
00145 Posicao posicao_original_do_cursor;
00146 if(para_no_proximo)
00147 posicao_original_do_cursor = cursor();
00148
00149
00150
00151 int const linha = posicao.linha();
00152 int const coluna = posicao.coluna();
00153 int const linhas = troco.dimensao().linhas();
00154 int const colunas = troco.dimensao().colunas();
00155
00156 int i = 0;
00157 for(int l = linha; l != linha + linhas; ++l)
00158 for(int c = coluna; c != coluna + colunas; ++c)
00159 {
00160 cursor(Posicao(l, c));
00161 char const caractere = troco.dados[i] & 0XFF;
00162 int const objecto = troco.dados[i++] >> 8;
00163 SLsmg_set_color(objecto);
00164 SLsmg_write_char(caractere);
00165 }
00166
00167
00168 if(para_no_proximo) {
00169 cursor(posicao_original_do_cursor);
00170 para_no_proximo = false;
00171 }
00172
00173
00174
00175 *this << fundo;
00176 }
00177
00178 Slang::Ecra& Slang::Ecra::operator << (string s)
00179 {
00180 verificaTamanho();
00181
00182 Posicao posicao_original_do_cursor;
00183 if(para_no_proximo)
00184 posicao_original_do_cursor = cursor();
00185
00186 if(largura_do_proximo == 0)
00187 SLsmg_write_string(const_cast<char *>(s.c_str()));
00188 else {
00189 if(s.size() < string::size_type(largura_do_proximo))
00190 switch(justificacao) {
00191 case ao_centro:
00192 s = string((largura_do_proximo - s.size() + 1) / 2, ' ') + s;
00193 break;
00194 case a_direita:
00195 s = string(largura_do_proximo - s.size(), ' ') + s;
00196 break;
00197 case a_esquerda:
00198 s += string(largura_do_proximo - s.size(), ' ');
00199 break;
00200 }
00201 SLsmg_write_nstring(const_cast<char *>(s.c_str()),
00202 largura_do_proximo);
00203 largura_do_proximo = 0;
00204 }
00205
00206
00207
00208 if(para_no_proximo) {
00209 cursor(posicao_original_do_cursor);
00210 para_no_proximo = false;
00211 }
00212
00213 return *this;
00214 }
00215
00216 Slang::Ecra& Slang::Ecra::operator << (Simbolo simbolo)
00217 {
00218 char c = simbolo;
00219 SLsmg_set_char_set(1);
00220 *this << c;
00221 SLsmg_set_char_set(0);
00222
00223 return *this;
00224 }
00225
00226 Slang::Ecra const& Slang::Ecra::operator >> (Troco& troco) const
00227 {
00228 verificaTamanho();
00229
00230 Posicao const posicao_original_do_cursor = cursor();
00231
00232 int const linha = posicao_original_do_cursor.linha();
00233 int const coluna = posicao_original_do_cursor.coluna();
00234 int const linhas = troco.dimensao().linhas();
00235 int const colunas = troco.dimensao().colunas();
00236
00237 int i = 0;
00238 for(int l = linha; l != linha + linhas; ++l)
00239 for(int c = coluna; c != coluna + colunas; ++c) {
00240 cursor(Posicao(l, c));
00241 troco.dados[i++] = SLsmg_char_at();
00242 }
00243
00244 cursor(posicao_original_do_cursor);
00245
00246 return *this;
00247 }
00248
00249 void Slang::Ecra::verificaTamanho() const
00250 {
00251 if(tamanho_mudou)
00252 {
00253
00254
00255 tamanho_mudou = false;
00256
00257
00258
00259
00260 redimensionado_ = true;
00261
00262
00263 Posicao const posicao_do_cursor = cursor();
00264
00265
00266 SLtt_get_screen_size();
00267 SLsmg_reinit_smg();
00268
00269
00270 cursor(posicao_do_cursor);
00271 }
00272 }
00273
00274 int Slang::Ecra::reservaObjecto()
00275 {
00276 int objecto = 1;
00277 int ocupacao_minima = ocupacao_objecto[1];
00278 for(int o = 2; o != 256; ++o)
00279 if(ocupacao_objecto[o] < ocupacao_minima) {
00280 ocupacao_minima = ocupacao_objecto[o];
00281 objecto = o;
00282 }
00283 ++ocupacao_objecto[objecto];
00284 return objecto;
00285 }
00286
00287
00288
00289
00290 void Slang::Ecra::manipuladorTamanhoMudou(int sinal)
00291 {
00292 Slang::Ecra::tamanho_mudou = true;
00293 SLsignal(SIGWINCH, manipuladorTamanhoMudou);
00294 }
00295
00296
00297
00298
00299 bool Slang::Ecra::existe_instancia = false;
00300
00301 bool volatile Slang::Ecra::tamanho_mudou = false;
00302
00303 char* Slang::Ecra::nome_de_cor[numero_de_cores] = {
00304 "black",
00305 "gray",
00306 "red",
00307 "brightred",
00308 "green",
00309 "brightgreen",
00310 "brown",
00311 "yellow",
00312 "blue",
00313 "brightblue",
00314 "magenta",
00315 "brightmagenta",
00316 "cyan",
00317 "brightcyan",
00318 "lightgray",
00319 "white"
00320 };
00321
00322
00323
00324
00325 string const Slang::nomes_das_cores[numero_de_cores] = {
00326 "preto",
00327 "cinza",
00328 "vermelho",
00329 "vermelho-brilhante",
00330 "verde",
00331 "verde-brilhante",
00332 "castanho",
00333 "amarelo",
00334 "azul",
00335 "azul-brilhante",
00336 "magenta",
00337 "magenta-brilhante",
00338 "ciano",
00339 "ciano-brilhante",
00340 "cinzento-claro",
00341 "branco"
00342 };
00343
00344 Slang::Ecra Slang::ecra;