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  

ecra_impl.H

Ir para a documentação deste ficheiro.
00001 #include <cassert>
00002 #include <cstdio>
00003 
00004 extern "C" {
00005 #include <slang/slang.h>
00006 #include <signal.h>
00007 }
00008 
00009 // Métodos inline da classe Posicao:
00010 
00011 // Construtores:
00012 inline Slang::Posicao::Posicao(int linha, int coluna)
00013     : linha_(linha), coluna_(coluna) {
00014 }
00015 
00016 inline Slang::Posicao::Posicao(istream& entrada) {
00017     carrega(entrada);
00018 }
00019 
00020 // Inspectores:
00021 inline int Slang::Posicao::linha() const {
00022     return linha_;
00023 }
00024 
00025 inline int Slang::Posicao::coluna() const {
00026     return coluna_;
00027 }
00028 
00029 // Modificadores:
00030 inline void Slang::Posicao::linha(int linha) {
00031     linha_ = linha;
00032 }
00033 
00034 inline void Slang::Posicao::coluna(int coluna) {
00035     coluna_ = coluna;
00036 }
00037 
00038 inline Slang::Posicao& 
00039 Slang::Posicao::operator += (Posicao const& c) {
00040     linha_ += c.linha_;
00041     coluna_ += c.coluna_;
00042     return *this;
00043 }
00044 
00045 inline Slang::Posicao& 
00046 Slang::Posicao::operator -= (Posicao const& c) {
00047     linha_ -= c.linha_;
00048     coluna_ -= c.coluna_;
00049     return *this;
00050 }
00051 
00052 inline Slang::Posicao& 
00053 Slang::Posicao::operator += (Dimensao const& c) {
00054     linha_ += c.linhas();
00055     coluna_ += c.colunas();
00056     return *this;
00057 }
00058 
00059 inline Slang::Posicao& 
00060 Slang::Posicao::operator -= (Dimensao const& c) {
00061     linha_ -= c.linhas();
00062     coluna_ -= c.colunas();
00063     return *this;
00064 }
00065 
00066 // Operadores associados:
00067 
00068 inline Slang::Posicao 
00069 Slang::operator + (Slang::Posicao a, Slang::Posicao const& b) {
00070     return a += b;
00071 }
00072 
00073 inline Slang::Posicao 
00074 Slang::operator - (Slang::Posicao a, Slang::Posicao const& b) {
00075     return a -= b;
00076 }
00077 
00078 inline Slang::Posicao 
00079 Slang::operator + (Slang::Posicao a, Slang::Dimensao const& b) {
00080     return a += b;
00081 }
00082 
00083 inline Slang::Posicao 
00084 Slang::operator - (Slang::Posicao a, Slang::Dimensao const& b) {
00085     return a -= b;
00086 }
00087 
00088 inline Slang::Posicao 
00089 Slang::operator - (Slang::Posicao const& b) {
00090     return Posicao(-b.linha(), -b.coluna());
00091 }
00092 
00093 inline bool 
00094 Slang::operator == (Slang::Posicao const& a, Slang::Posicao const& b) {
00095     return a.linha() == b.linha() && a.coluna() == b.coluna();
00096 }
00097 
00098 
00099 // Métodos inline da classe Dimensao:
00100 
00101 inline Slang::Dimensao::Dimensao(int l, int c) {
00102     linhas(l);
00103     colunas(c);
00104 }
00105 
00106 inline Slang::Dimensao::Dimensao(Posicao const& c) {
00107     linhas(c.linha());
00108     colunas(c.coluna());
00109 }
00110       
00111 inline Slang::Dimensao::Dimensao(istream& entrada) {
00112     carrega(entrada);
00113 }
00114       
00115 // Inspectores:
00116 inline int Slang::Dimensao::linhas() const {
00117     return linhas_;
00118 }
00119 
00120 inline int Slang::Dimensao::colunas() const {
00121     return colunas_;
00122 }
00123 
00124 // Modificadores:
00125 inline void Slang::Dimensao::linhas(int linhas) {
00126     linhas_ = linhas < 0 ? 0 : linhas;
00127 }
00128 
00129 inline void Slang::Dimensao::colunas(int colunas) {
00130     colunas_ = colunas < 0 ? 0 : colunas;
00131 }
00132 
00133 // Operadores:
00134 inline Slang::Dimensao& Slang::Dimensao::operator += (Dimensao const& c) {
00135     linhas(linhas() + c.linhas());
00136     colunas(colunas() + c.colunas());
00137     return *this;
00138 }
00139 
00140 inline Slang::Dimensao& Slang::Dimensao::operator -= (Dimensao const& c) {
00141     linhas(linhas() - c.linhas());
00142     colunas(colunas() - c.colunas());
00143     return *this;
00144 }
00145 
00146 // Operadores associados:
00147 inline Slang::Dimensao Slang::operator + (Dimensao a, Dimensao const& b) {
00148     return a += b;
00149 }
00150 
00151 inline Slang::Dimensao Slang::operator - (Dimensao a, Dimensao const& b) {
00152     return a -= b;
00153 }
00154 
00155 inline bool 
00156 Slang::operator == (Slang::Dimensao const& a, Slang::Dimensao const& b) {
00157     return a.linhas() == b.linhas() && a.colunas() == b.colunas();
00158 }
00159 
00160 
00161 // Métodos inline da classe Caixa:
00162 
00163 // Construtores:
00164 inline Slang::Caixa::Caixa(Posicao const& origem, Dimensao const& dimensao)
00165     : origem_(origem), dimensao_(dimensao) {
00166 }
00167 
00168 inline Slang::Caixa::Caixa(Posicao const& a, Posicao const& b)
00169     : origem_(min(a.linha(), b.linha()), min(a.coluna(), b.coluna())), 
00170       dimensao_(abs(a.linha() - b.linha()) + 1, 
00171                 abs(a.coluna() - b.coluna()) + 1) {
00172 }
00173 
00174 inline Slang::Caixa::Caixa(istream& entrada)
00175     : origem_(entrada), dimensao_(entrada) {
00176 }
00177 
00178 
00179 // Inspectores:
00180 inline Slang::Posicao Slang::Caixa::origem() const {
00181     return origem_;
00182 }
00183 
00184 inline Slang::Posicao Slang::Caixa::destino() const {
00185     return origem_ + dimensao_ - Posicao(1, 1);
00186 }
00187 
00188 inline Slang::Dimensao Slang::Caixa::dimensao() const {
00189     return dimensao_;
00190 }
00191 
00192 inline bool Slang::Caixa::vazia() const {
00193     return dimensao().linhas() == 0 || dimensao().colunas() == 0;
00194 }
00195 
00196 inline bool Slang::Caixa::contem(Posicao const& c) const {
00197     int const linha = origem_.linha();
00198     int const coluna = origem_.coluna();
00199     int const linha_final = linha + dimensao_.linhas();
00200     int const coluna_final = coluna + dimensao_.colunas();
00201     return c.linha() >= linha && c.linha() < linha_final &&
00202         c.coluna() >= coluna && c.coluna() < coluna_final;
00203 }
00204 
00205 inline bool Slang::Caixa::bordaContem(Posicao const& c) const {
00206     int const primeira_linha = origem().linha();
00207     int const primeira_coluna = origem().coluna();
00208     int const ultima_linha = destino().linha();
00209     int const ultima_coluna = destino().coluna();
00210     return ((c.linha() >= primeira_linha && c.linha() <= ultima_linha && 
00211              (c.coluna() == primeira_coluna || c.coluna() == ultima_coluna)) ||
00212             (c.coluna() >= primeira_coluna && c.coluna() <= ultima_coluna &&
00213              (c.linha() == primeira_linha || c.linha() == ultima_linha)));
00214 }
00215 
00216 // Modificadores:
00217 inline void Slang::Caixa::origem(Posicao const & origem) {
00218     origem_ = origem;
00219 }
00220 
00221 inline void Slang::Caixa::destino(Posicao const& destino) {
00222     *this = Caixa(origem(), destino);
00223 }
00224 
00225 inline void Slang::Caixa::dimensao(Dimensao const& dimensao) {
00226     dimensao_ = dimensao;
00227 }
00228 
00229 // Operadores:
00230 inline Slang::Caixa& Slang::Caixa::operator += (Slang::Posicao const& c) {
00231     origem(origem() + c);
00232     return *this;
00233 }
00234 
00235 inline Slang::Caixa& Slang::Caixa::operator += (Slang::Caixa const& c) {
00236     if(vazia()) return *this = c;
00237     if(c.vazia()) return *this;
00238     int const linha = min(origem_.linha(), c.origem_.linha());
00239     int const coluna = min(origem_.coluna(), c.origem_.coluna());
00240     int const linha_final = max(origem_.linha() + dimensao_.linhas(), 
00241                                 c.origem_.linha() + c.dimensao_.linhas());
00242     int const coluna_final = max(origem_.coluna() + dimensao_.colunas(), 
00243                                  c.origem_.coluna() + c.dimensao_.colunas());
00244     origem_.linha(linha);
00245     origem_.coluna(coluna);
00246     dimensao_.linhas(linha_final - linha);
00247     dimensao_.colunas(coluna_final - coluna);
00248 
00249     return *this;
00250 }
00251 
00252 inline Slang::Caixa& Slang::Caixa::operator *= (Slang::Caixa const& c) {
00253     if(vazia() || c.vazia())
00254         return *this = caixa_vazia;
00255     int const linha = max(origem_.linha(), c.origem_.linha());
00256     int const coluna = max(origem_.coluna(), c.origem_.coluna());
00257     int const linha_final = min(origem_.linha() + dimensao_.linhas(), 
00258                                 c.origem_.linha() + c.dimensao_.linhas());
00259     int const coluna_final = min(origem_.coluna() + dimensao_.colunas(), 
00260                                  c.origem_.coluna() + c.dimensao_.colunas());
00261     if(linha_final < linha || coluna_final < coluna)
00262         return *this = caixa_vazia;
00263     
00264     origem_.linha(linha);
00265     origem_.coluna(coluna);
00266     dimensao_.linhas(linha_final - linha);
00267     dimensao_.colunas(coluna_final - coluna);
00268 
00269     return *this;
00270 }
00271         
00272 // Operadores associados:
00273 inline Slang::Caixa Slang::operator + (Slang::Caixa caixa, 
00274                                        Slang::Posicao const& c) {
00275     return caixa += c;
00276 }
00277 
00278 inline Slang::Caixa Slang::operator + (Slang::Posicao const& c,
00279                                        Slang::Caixa caixa) {
00280     return caixa += c;
00281 }
00282 
00283 inline Slang::Caixa Slang::operator + (Slang::Caixa a, Slang::Caixa const& b) {
00284     return a += b;
00285 }
00286 
00287 inline Slang::Caixa Slang::operator * (Slang::Caixa a, Slang::Caixa const& b) {
00288     return a *= b;
00289 }
00290 
00291 
00292 // Métodos inline da classe ecrã:
00293 
00294 inline Slang::Ecra::~Ecra() {
00295     // Terminação do slang:
00296     SLsmg_reset_smg();
00297 }
00298 
00299 inline void Slang::Ecra::atributos(Cor texto, Cor fundo, int objecto) {
00300     SLtt_set_color(objecto, 0, nome_de_cor[texto], nome_de_cor[fundo]);
00301 }
00302 
00303 inline void Slang::Ecra::atributos(Cor texto, Cor fundo) {
00304     SLtt_set_color(0, 0, nome_de_cor[texto], nome_de_cor[fundo]);
00305 }
00306 
00307 inline Slang::Dimensao Slang::Ecra::dimensao() const {
00308     verificaTamanho();
00309     return Dimensao(SLtt_Screen_Rows, SLtt_Screen_Cols);
00310 }
00311 
00312 inline Slang::Posicao Slang::Ecra::cursor() const {
00313     return Posicao(SLsmg_get_row(), SLsmg_get_column());
00314 }
00315 
00316 inline bool Slang::Ecra::redimensionado() const {
00317     verificaTamanho();
00318     if(redimensionado_) {
00319         redimensionado_ = false;
00320         return true;
00321     }
00322     return false;
00323 }
00324 
00325 inline Slang::Ecra::Troco Slang::Ecra::copia(Dimensao const& dimensao) const {
00326     return copia(Caixa(cursor(), dimensao));
00327 }
00328 
00329 inline Slang::Ecra::Troco Slang::Ecra::copia() const {
00330     return copia(Caixa(Posicao(0, 0), dimensao()));
00331 }
00332 
00333 inline void Slang::Ecra::cursor(Posicao const& posicao) {
00334     verificaTamanho();
00335     int linha = posicao.linha();
00336     int coluna = posicao.coluna();
00337     if(limita_cursor) {
00338         if(linha >= dimensao().linhas()) linha = dimensao().linhas() - 1;
00339         else if(linha < 0) linha = 0;
00340         
00341         if(coluna >= dimensao().colunas()) coluna = dimensao().colunas() - 1;
00342         else if(coluna < 0) coluna = 0;
00343     }
00344     SLsmg_gotorc(linha, coluna);
00345 }
00346 
00347 inline void Slang::Ecra::cursor(Posicao const& posicao) const {
00348     verificaTamanho();
00349     int linha = posicao.linha();
00350     int coluna = posicao.coluna();
00351     if(limita_cursor) {
00352         if(linha >= dimensao().linhas()) linha = dimensao().linhas() - 1;
00353         else if(linha < 0) linha = 0;
00354         
00355         if(coluna >= dimensao().colunas()) coluna = dimensao().colunas() - 1;
00356         else if(coluna < 0) coluna = 0;
00357     }
00358     SLsmg_gotorc(linha, coluna);
00359 }
00360 
00361 inline void Slang::Ecra::cima() {
00362     cursor(Posicao(cursor().linha() - 1, cursor().coluna()));
00363 }
00364 
00365 inline void Slang::Ecra::baixo() {
00366     cursor(Posicao(cursor().linha() + 1, cursor().coluna()));
00367 }
00368 
00369 inline void Slang::Ecra::esquerda() {
00370     cursor(Posicao(cursor().linha(), cursor().coluna() - 1));
00371 }
00372 
00373 inline void Slang::Ecra::direita() {
00374     cursor(Posicao(cursor().linha(), cursor().coluna() + 1));
00375 }
00376 
00377 inline void Slang::Ecra::desloca(Slang::Tecla const& tecla) {
00378     switch(tecla) {
00379       case Tecla::cima:
00380         cima();
00381         break;
00382       case Tecla::baixo:
00383         baixo();
00384         break;
00385       case Tecla::esquerda:
00386         esquerda();
00387         break;
00388       case Tecla::direita:
00389         direita();
00390         break;
00391       default:
00392         break;
00393     }
00394 }
00395 
00396 inline void Slang::Ecra::campainha() const {
00397     verificaTamanho();
00398     SLtt_beep();
00399 }
00400 
00401 inline void Slang::Ecra::apagaFimDaLinha() {
00402     verificaTamanho();
00403     SLsmg_erase_eol();
00404 }
00405 
00406 inline void Slang::Ecra::apagaFimDoEcra() {
00407     verificaTamanho();
00408     SLsmg_erase_eos();
00409 }
00410 
00411 inline void Slang::Ecra::apaga() {
00412     verificaTamanho();
00413     SLsmg_cls();
00414 }
00415 
00416 inline void Slang::Ecra::refrescaTudo() const {
00417     verificaTamanho();
00418     // Com isto o próximo refresh redesenhará todo o ecrã!
00419     SLsmg_touch_lines(0, dimensao().linhas());
00420     refresca();
00421 }
00422 
00423 inline void Slang::Ecra::refresca() const {
00424     verificaTamanho();
00425     SLsmg_refresh();
00426 }
00427 
00428 inline void Slang::Ecra::desenhaCaixa(Caixa const& caixa)
00429 {
00430     verificaTamanho();
00431     // Guardar cursor inicial:
00432     Posicao posicao_original_do_cursor;
00433     if(para_no_proximo)
00434         posicao_original_do_cursor = cursor();
00435 
00436     SLsmg_draw_box(caixa.origem().linha(), caixa.origem().coluna(), 
00437                    caixa.dimensao().linhas(), caixa.dimensao().colunas());
00438 
00439     // Regressar ao cursor inicial:
00440     if(para_no_proximo) {
00441         cursor(posicao_original_do_cursor);
00442         para_no_proximo = false;
00443     }
00444 }
00445 
00446 inline Slang::Ecra& Slang::Ecra::operator << (char c) {
00447     string s;
00448     s += c;
00449     return *this << s;
00450 }
00451 
00452 inline Slang::Ecra& Slang::Ecra::operator << (int i) {
00453     // Afazer: usar stringstream (ainda não há em Linux).
00454     char mal_feito[30];
00455     std::sprintf(mal_feito, "%d", i);
00456     return *this << mal_feito;
00457 }
00458 
00459 inline Slang::Ecra& Slang::Ecra::operator << (Caixa const& caixa) {
00460     desenhaCaixa(caixa);
00461     return *this;
00462 }
00463 
00464 inline Slang::Ecra& Slang::Ecra::operator << (Troco const& troco) {
00465     cola(troco, cursor());
00466     return *this;
00467 }
00468 
00469 inline Slang::Ecra& Slang::Ecra::operator << (Posicao const& posicao) {
00470     verificaTamanho();
00471     cursor(posicao);
00472     return *this;
00473 }
00474 
00475 inline Slang::Ecra& Slang::Ecra::operator << (ObjectoCor const& o) {
00476     verificaTamanho();
00477     SLsmg_set_color(o.objecto);
00478     return *this;
00479 }
00480 
00481 inline Slang::Ecra& Slang::Ecra::operator << (Fundo const&) {
00482     verificaTamanho();
00483     SLsmg_set_color(0);
00484     return *this;
00485 }
00486 
00487 inline Slang::Ecra& Slang::Ecra::operator << (Parado const&) {
00488     verificaTamanho();
00489     para_no_proximo = true;
00490     return *this;
00491 }
00492 
00493 inline Slang::Ecra& Slang::Ecra::operator << (Justificacao const& j) {
00494     verificaTamanho();
00495     justificacao = j;
00496     return *this;
00497 }
00498 
00499 inline Slang::Ecra& Slang::Ecra::operator << (Largura const& l) {
00500     verificaTamanho();
00501     largura_do_proximo = l.largura;
00502     return *this;
00503 }
00504 
00505 inline Slang::Ecra& Slang::Ecra::operator << (Linha const& linha) {
00506     verificaTamanho();
00507     if(linha.horizontal)
00508         SLsmg_draw_hline(linha.dimensao);
00509     else
00510         SLsmg_draw_vline(linha.dimensao);
00511     return *this;
00512 }
00513 
00514 inline Slang::Ecra& Slang::Ecra::operator << (Refresca const&) {
00515     refresca();
00516     return *this;
00517 }
00518 
00519 inline Slang::Ecra& Slang::Ecra::operator << (RefrescaTudo const&) {
00520     refrescaTudo();
00521     return *this;
00522 }
00523 
00524 inline Slang::Ecra& Slang::Ecra::operator << (Apaga const&) {
00525     apaga();
00526     return *this;
00527 }
00528 
00529 inline Slang::Ecra& Slang::Ecra::operator << (ApagaFimDaLinha const&) {
00530     apagaFimDaLinha();
00531     return *this;
00532 }
00533 
00534 inline Slang::Ecra& Slang::Ecra::operator << (ApagaFimDoEcra const&) {
00535     apagaFimDoEcra();
00536     return *this;
00537 }
00538 
00539 inline Slang::Ecra& Slang::Ecra::operator << (Campainha const&) {
00540     campainha();
00541     return *this;
00542 }
00543 
00544 inline void Slang::Ecra::libertaObjecto(int objecto) {
00545     assert(ocupacao_objecto[objecto] != 0);
00546     --ocupacao_objecto[objecto];
00547 }
00548 
00549 // Métodos inline da classe Ecra::ObjectoCor:
00550 
00551 inline Slang::Ecra::ObjectoCor::ObjectoCor(Cor texto, Cor fundo)
00552     : texto_(texto), fundo_(fundo) {
00553     objecto = ecra.reservaObjecto();
00554     ecra.atributos(texto, fundo, objecto);
00555 }
00556 
00557 inline Slang::Ecra::ObjectoCor::~ObjectoCor() {
00558     ecra.libertaObjecto(objecto);
00559 }
00560 
00561 inline Slang::Cor Slang::Ecra::ObjectoCor::texto() const {
00562     return texto_;
00563 }
00564 
00565 inline Slang::Cor Slang:: Ecra::ObjectoCor::fundo() const {
00566     return fundo_;
00567 }
00568 
00569 inline void Slang::Ecra::ObjectoCor::texto(Cor texto) {
00570     texto_ = texto;
00571     ecra.atributos(texto_, fundo_, objecto);
00572 }
00573 
00574 inline void Slang::Ecra::ObjectoCor::fundo(Cor fundo) {
00575     fundo_ = fundo;
00576     ecra.atributos(texto_, fundo_, objecto);
00577 }
00578 
00579 
00580 // Métodos inline da classe Ecra::Largura (manipulador):
00581 
00582 inline Slang::Ecra::Largura::Largura(int largura) 
00583     : largura(largura) {
00584 }
00585 
00586 inline Slang::Ecra::Largura 
00587 Slang::Ecra::Largura::operator() (int largura) const {
00588     return Largura(largura);
00589 }
00590 
00591 
00592 // Métodos inline da classe Ecra::Largura (manipulador):
00593 
00594 inline Slang::Ecra::Linha::Linha(bool horizontal, int dimensao) 
00595     : horizontal(horizontal), dimensao(dimensao) {
00596 }
00597 
00598 inline Slang::Ecra::Linha Slang::Ecra::Linha::operator() (int dim) const {
00599     return Linha(horizontal, dim);
00600 }
00601 
00602 
00603 // Métodos inline da classe Ecra::Troco:
00604 
00605 inline Slang::Ecra::Troco::Troco(Dimensao const& dimensao)
00606     : dimensao_(dimensao), dados(dimensao.linhas() * dimensao.colunas()) {
00607 }
00608 
00609 inline Slang::Dimensao Slang::Ecra::Troco::dimensao() const {
00610     return dimensao_;
00611 }
00612 
00613 
00614 // Funções e procedimentos não membro inline:
00615 
00616 inline Slang::Posicao Slang::cursor(Slang::Posicao const& posicao) {
00617     return posicao;
00618 }
00619 
00620 inline Slang::Posicao Slang::cursor(int linha, int coluna) {
00621     return Slang::Posicao(linha, coluna);
00622 }
00623 
00624 inline Slang::Caixa Slang::caixa(Slang::Posicao const& origem, 
00625                                  Slang::Dimensao const& dimensao) {
00626     return Caixa(origem, dimensao);
00627 }
00628 
00629 inline Slang::Caixa Slang::caixa(int linha, int coluna, 
00630                                  int linhas, int colunas) {
00631     return Caixa(Posicao(linha, coluna), Dimensao(linhas, colunas));
00632 }

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