mundoqt.cpp

Ir para a documentação deste ficheiro.
00001 #include "mundoqt.h"
00002 #include "main-window.h"
00003 
00004 #include <QColor>
00005 #include <QBrush>
00006 #include <QPainter>
00007 #include <stdio.h>
00008 #include <stdlib.h>
00009 #include <QFileDialog>
00010 #include <QtDebug>
00011 
00012 #define RAIO_SELECAO 10
00013 #define RAIO_PAREDE (GROSSURA_PAREDE * 2)
00014 
00015 #define COR_MORTE Qt::cyan
00016 #define COR_NASCIMENTO QColor(percorre->biota.genes.cor_cabeca[0],percorre->biota.genes.cor_cabeca[1],percorre->biota.genes.cor_cabeca[2])
00017 #define IDADE_COR 5
00018 
00019 /******************************************************************************/
00020 /* Constructor */
00021 MundoQT::MundoQT(QWidget *parent, Qt::WFlags f) : QWidget(parent, f), Mundo()
00022 {
00023     parede_selecionada = NULL;
00024     mutex = NULL;
00025 
00026     offsetx = 0;
00027     offsety = 0;
00028     zm = 0.5f;
00029     executando = true;
00030     fixar = false;
00031     autoSelec = false;
00032 
00033     QString simvidaConfig = QDir::homePath() + QDir::separator() + ".simvida";
00034 
00035     /* Verifica se existe arquivo com configuracoes */
00036     QFile file(simvidaConfig);
00037 
00038     if (!file.open(QIODevice::ReadOnly))
00039     {
00040         qDebug() << tr("Creating new Simvida configuration file");
00041 
00042         /* Nao existe arquivo : coloca valores padrao */
00043         propriedades.tamanho_x = TAMANHO_X;
00044         propriedades.tamanho_y =  TAMANHO_Y;
00045         propriedades.energia_grao = ENERGIA_GRAO;
00046         propriedades.teto_energetico = TETO_ENERGETICO;
00047         propriedades.probabilidade_mutacao = PROBABILIDADE_MUTACAO;
00048         propriedades.intensidade_mutacao = INTENSIDADE_MUTACAO;
00049         /* Cria arquivo e escreve valores padrao */
00050         file.open(QIODevice::WriteOnly);
00051         FILE *arq = fdopen(file.handle(), "w");
00052 
00053         fprintf(arq, "%d\n%d\n%d\n%d\n%d\n%d\n",
00054         TAMANHO_X, TAMANHO_Y, ENERGIA_GRAO,
00055         TETO_ENERGETICO, PROBABILIDADE_MUTACAO, INTENSIDADE_MUTACAO);
00056 
00057         fclose(arq);
00058     }
00059     else
00060     {
00061         /* Carrega configuracoes de arquivo */
00062         FILE *arq = fdopen(file.handle(), "r");
00063         fscanf(arq, "%d\n%d\n%d\n%d\n%d\n%d\n",
00064         &(propriedades.tamanho_x), &(propriedades.tamanho_y),
00065         &(propriedades.energia_grao),
00066         &(propriedades.teto_energetico), &(propriedades.probabilidade_mutacao),
00067         &(propriedades.intensidade_mutacao));
00068 
00069         fclose(arq);
00070     }
00071     /* Fecha arquivo */
00072     file.close();
00073 
00074     reiniciar();
00075 }
00076 
00077 /******************************************************************************/
00078 
00079 MundoQT::~MundoQT()
00080 {
00081 
00082 }
00083 
00084 /******************************************************************************/
00085 /* Desenhar */
00086 void MundoQT::paintEvent(QPaintEvent *event)
00087 {
00088 
00089     /* configura o painter */
00090     QPainter painter(this);
00091     painter.setRenderHint(QPainter::Antialiasing, false);
00092     painter.setRenderHint(QPainter::SmoothPixmapTransform, false);
00093 
00094     int dx = width()/2;
00095     int dy = height()/2;
00096 
00097     /* Configura o brush */
00098     QBrush brush(QColor(200, 220, 255));
00099     painter.setBrush(brush);
00100 
00101     /* Limpa tela na regiao */
00102     painter.drawRect(event->rect());
00103 
00104     /* Configura pen */
00105     QPen pen;
00106     pen.setColor(Qt::black);
00107     pen.setWidth((int)(zm*GROSSURA_PAREDE*2)+1);
00108     painter.setPen(pen);
00109 
00110     /* Desenha tela principal */
00111     brush.setColor(Qt::white);
00112     painter.setBrush(brush);
00113     painter.drawRect(
00114     (int)(-offsetx*zm+dx),(int)(-offsety*zm+dy),
00115     (int)(propriedades.tamanho_x*zm), (int)(propriedades.tamanho_y*zm));
00116 
00117     /* Desenha paredes */
00118     mutex->lock();
00119     brush.setColor(Qt::black);
00120     painter.setBrush(brush);
00121     for (struct NohParede *percorre = nohCabecaParedes.proximo;
00122     percorre != NULL;
00123     percorre = percorre->proximo)
00124     {
00125         painter.drawLine(
00126         (int)((percorre->inicio.X-offsetx)*zm+dx),
00127         (int)((percorre->inicio.Y-offsety)*zm+dy),
00128         (int)((percorre->fim.X-offsetx)*zm+dx),
00129         (int)((percorre->fim.Y-offsety)*zm+dy));
00130 
00131         painter.drawEllipse(
00132         (int)(((percorre->inicio.X - RAIO_PAREDE)-offsetx)*zm+dx),
00133         (int)(((percorre->inicio.Y - RAIO_PAREDE)-offsety)*zm+dy),
00134         (int)(RAIO_PAREDE*2.0f*zm),(int)(RAIO_PAREDE*2.0f*zm));
00135 
00136         painter.drawEllipse(
00137         (int)(((percorre->fim.X - RAIO_PAREDE)-offsetx)*zm+dx),
00138         (int)(((percorre->fim.Y - RAIO_PAREDE)-offsety)*zm+dy),
00139         (int)(RAIO_PAREDE*2.0f*zm),(int)(RAIO_PAREDE*2.0f*zm));
00140     }
00141     mutex->unlock();
00142 
00143     /* Seta tamanho e cor da linha */
00144     pen.setColor(Qt::black);
00145     pen.setWidth((int)(zm+1));
00146     painter.setPen(pen);
00147 
00148     /* Desenha graos */
00149     mutex->lock();
00150     brush.setColor(Qt::cyan);
00151     painter.setBrush(brush);
00152     for (struct NohGrao *percorre = nohCabecaGraos.proximo;
00153     percorre != NULL;
00154     percorre = percorre->proximo)
00155     {
00156         /* Corrige posicao do grao, caso seja necessario */
00157         if (percorre->posicao.X > (signed int)propriedades.tamanho_x ||
00158             percorre->posicao.Y > (signed int)propriedades.tamanho_y)
00159             percorre->posicao =
00160             Vetor<float>(rand() % propriedades.tamanho_x, rand() % propriedades.tamanho_y);
00161 
00162         /* Desenha grao */
00163         if (
00164         ((percorre->posicao.X + RAIO_GRAO)-offsetx)*zm+dx >= event->rect().x() &&
00165         ((percorre->posicao.X - RAIO_GRAO)-offsetx)*zm+dy <= event->rect().x()+ event->rect().width() &&
00166         ((percorre->posicao.Y + RAIO_GRAO)-offsety)*zm+dx >= event->rect().y() &&
00167         ((percorre->posicao.Y - RAIO_GRAO)-offsety)*zm+dy <= event->rect().y() + event->rect().height())
00168         {
00169             if (percorre == grao_selecionado)
00170             {
00171                 pen.setWidth((int)(zm+3));
00172                 painter.setPen(pen);
00173             }
00174 
00175             painter.drawEllipse(
00176             (int)(((percorre->posicao.X - RAIO_GRAO)-offsetx)*zm+dx),
00177             (int)(((percorre->posicao.Y - RAIO_GRAO)-offsety)*zm+dy),
00178             (int)(RAIO_GRAO*2.0f*zm), (int)(RAIO_GRAO*2.0f*zm));
00179 
00180             if (percorre == grao_selecionado)
00181             {
00182                 pen.setWidth((int)(zm+1));
00183                 painter.setPen(pen);
00184             }
00185         }
00186     }
00187     mutex->unlock();
00188 
00189     /* Desenha biotas */
00190     mutex->lock();
00191     for (struct NohBiota *percorre = nohCabecaBiotas.proximo;
00192     percorre != NULL;
00193     percorre = percorre->proximo)
00194         if (
00195         ((percorre->biota.estado.posicao.X + (percorre->biota.genes.massa_cabeca * FATOR_PERCEPCAO_GRAOS))-offsetx)*zm+dx >= event->rect().x() &&
00196         ((percorre->biota.estado.posicao.Y + (percorre->biota.genes.massa_cabeca * FATOR_PERCEPCAO_GRAOS))-offsety)*zm+dy >= event->rect().y() &&
00197         ((percorre->biota.estado.posicao.X - (percorre->biota.genes.massa_cabeca * FATOR_PERCEPCAO_GRAOS))-offsetx)*zm+dx <= event->rect().x()+ event->rect().width() &&
00198         ((percorre->biota.estado.posicao.Y - (percorre->biota.genes.massa_cabeca * FATOR_PERCEPCAO_GRAOS))-offsety)*zm+dy <= event->rect().y() + event->rect().height())
00199         {
00200             /* Coloca cor de acordo com energia do biota */
00201             pen.setColor(
00202             (percorre->biota.estado.energia <= 1)? COR_MORTE :
00203             (percorre->biota.estado.idade <= IDADE_COR-1)? COR_NASCIMENTO :
00204             QColor(0,
00205             (int)(((float)percorre->biota.estado.energia/(float)percorre->biota.genes.limiar_reproducao)*255.0f) % 255,
00206             (int)(((float)percorre->biota.estado.energia/(float)percorre->biota.genes.limiar_reproducao)*255.0f) % 255 ));
00207             painter.setPen(pen);
00208 
00209             /* Desenha cabeca */
00210             brush.setColor(
00211             (percorre->biota.estado.energia <= 1)? COR_MORTE :
00212             (percorre->biota.estado.idade <= IDADE_COR)? COR_NASCIMENTO :
00213             QColor(percorre->biota.genes.cor_cabeca[0],percorre->biota.genes.cor_cabeca[1],percorre->biota.genes.cor_cabeca[2]));
00214             painter.setBrush(brush);
00215 
00216             painter.drawEllipse(
00217             (int)(((percorre->biota.estado.posicao.X - percorre->biota.genes.massa_cabeca)-offsetx)*zm+dx),
00218             (int)(((percorre->biota.estado.posicao.Y - percorre->biota.genes.massa_cabeca)-offsety)*zm+dy),
00219             (int)(percorre->biota.genes.massa_cabeca*2.0f*zm), (int)(percorre->biota.genes.massa_cabeca*2.0f*zm));
00220 
00221             /* Desenha linha de direcao */
00222             painter.drawLine(
00223             (int)((percorre->biota.estado.posicao.X-offsetx)*zm+dx),
00224             (int)((percorre->biota.estado.posicao.Y-offsety)*zm+dy),
00225             (int)(((percorre->biota.estado.posicao.X +
00226             (cos(percorre->biota.estado.angulo) * percorre->biota.genes.massa_cabeca))-offsetx)*zm+dx),
00227             (int)(((percorre->biota.estado.posicao.Y +
00228             (sin(percorre->biota.estado.angulo) * percorre->biota.genes.massa_cabeca))-offsety)*zm+dy));
00229 
00230             /* Desenha brilho na cabeca */
00231             pen.setStyle(Qt::NoPen);    painter.setPen(pen);
00232             brush.setColor(Qt::white);  painter.setBrush(brush);
00233             painter.drawEllipse(
00234             (int)((((percorre->biota.estado.posicao.X + (percorre->biota.genes.massa_cabeca/2.0f)) - (percorre->biota.genes.massa_cabeca/6.0f))-offsetx)*zm+dx),
00235             (int)((((percorre->biota.estado.posicao.Y - (percorre->biota.genes.massa_cabeca/2.0f)) - (percorre->biota.genes.massa_cabeca/6.0f))-offsety)*zm+dy),
00236             (int)((percorre->biota.genes.massa_cabeca/3.0f)*zm), (int)((percorre->biota.genes.massa_cabeca/3.0f)*zm));
00237             painter.drawEllipse(
00238             (int)((((percorre->biota.estado.posicao.X + (percorre->biota.genes.massa_cabeca*0.3f)) - (percorre->biota.genes.massa_cabeca/4.0f))-offsetx)*zm+dx),
00239             (int)((((percorre->biota.estado.posicao.Y - (percorre->biota.genes.massa_cabeca*0.3f)) - (percorre->biota.genes.massa_cabeca/4.0f))-offsety)*zm+dy),
00240             (int)((percorre->biota.genes.massa_cabeca/2.0f)*zm), (int)((percorre->biota.genes.massa_cabeca/2.0f)*zm));
00241             pen.setStyle(Qt::SolidLine);    painter.setPen(pen);
00242 
00243             /* Desenha segmentos */
00244             for (unsigned int c = 0; c < percorre->biota.numero_segmentos; c++)
00245             {
00246                 //desenha linha do segmento
00247                 painter.drawLine(
00248                 (int)(((cos(percorre->biota.genes.segmentos[c].angulo+percorre->biota.estado.angulo)*
00249                 percorre->biota.genes.massa_cabeca + percorre->biota.estado.posicao.X)-offsetx) * zm+dx),
00250                 (int)(((sin(percorre->biota.genes.segmentos[c].angulo+percorre->biota.estado.angulo)*
00251                 percorre->biota.genes.massa_cabeca + percorre->biota.estado.posicao.Y)-offsety) * zm+dy),
00252                 (int)(((cos(percorre->biota.genes.segmentos[c].angulo+(sin(percorre->biota.estado.posicaoSegmentos[c])*
00253                 (percorre->biota.genes.segmentos[c].arco/1.0f))+percorre->biota.estado.angulo)*
00254                 (percorre->biota.genes.massa_cabeca+percorre->biota.genes.segmentos[c].comprimento+percorre->biota.genes.segmentos[c].massa)+
00255                 percorre->biota.estado.posicao.X)-offsetx) *zm+dx),
00256                 (int)(((sin(percorre->biota.genes.segmentos[c].angulo+(sin(percorre->biota.estado.posicaoSegmentos[c])*
00257                 (percorre->biota.genes.segmentos[c].arco/1.0f))+percorre->biota.estado.angulo)*
00258                 (percorre->biota.genes.massa_cabeca+percorre->biota.genes.segmentos[c].comprimento+percorre->biota.genes.segmentos[c].massa)+
00259                 percorre->biota.estado.posicao.Y)-offsety) *zm+dy));
00260 
00261                 /* Desenha circulo do segmento */
00262                 brush.setColor(
00263                 (percorre->biota.estado.energia <= 1)? COR_MORTE :
00264                 (percorre->biota.estado.idade <= IDADE_COR)? COR_NASCIMENTO :
00265                 QColor(percorre->biota.genes.segmentos[c].cor[0],percorre->biota.genes.segmentos[c].cor[1],percorre->biota.genes.segmentos[c].cor[2]));
00266                 painter.setBrush(brush);
00267 
00268                 painter.drawEllipse(
00269                 (int)((((cos(percorre->biota.genes.segmentos[c].angulo+(sin(percorre->biota.estado.posicaoSegmentos[c])*
00270                 (percorre->biota.genes.segmentos[c].arco/1.0f))+percorre->biota.estado.angulo)*
00271                 (percorre->biota.genes.massa_cabeca+percorre->biota.genes.segmentos[c].comprimento+percorre->biota.genes.segmentos[c].massa)+
00272                 percorre->biota.estado.posicao.X) - percorre->biota.genes.segmentos[c].massa)-offsetx)*zm+dx),
00273                 (int)((((sin(percorre->biota.genes.segmentos[c].angulo+(sin(percorre->biota.estado.posicaoSegmentos[c])*
00274                 (percorre->biota.genes.segmentos[c].arco/1.0f))+percorre->biota.estado.angulo)*
00275                 (percorre->biota.genes.massa_cabeca+percorre->biota.genes.segmentos[c].comprimento+percorre->biota.genes.segmentos[c].massa)+
00276                 percorre->biota.estado.posicao.Y) - percorre->biota.genes.segmentos[c].massa)-offsety)*zm+dy),
00277                 (int)(percorre->biota.genes.segmentos[c].massa*2.0f*zm), (int)(percorre->biota.genes.segmentos[c].massa*2.0f*zm));
00278             }
00279             /* Se biota esta selecionado */
00280             if (percorre == selecionado)
00281             {
00282                 brush.setStyle(Qt::NoBrush);    painter.setBrush(brush);
00283 
00284                 pen.setColor(Qt::yellow);   painter.setPen(pen);
00285                 painter.drawEllipse(
00286                 (int)(((percorre->biota.estado.posicao.X - (percorre->biota.genes.massa_cabeca * FATOR_PERCEPCAO_GRAOS))-offsetx)*zm+dx),
00287                 (int)(((percorre->biota.estado.posicao.Y - (percorre->biota.genes.massa_cabeca * FATOR_PERCEPCAO_GRAOS))-offsety)*zm+dy),
00288                 (int)((percorre->biota.genes.massa_cabeca * FATOR_PERCEPCAO_GRAOS)*2.0f*zm),
00289                 (int)((percorre->biota.genes.massa_cabeca * FATOR_PERCEPCAO_GRAOS)*2.0f*zm));
00290 
00291                 pen.setColor(Qt::green);    painter.setPen(pen);
00292                 painter.drawEllipse(
00293                 (int)(((percorre->biota.estado.posicao.X - percorre->biota.genes.massa_cabeca - RAIO_SELECAO)-offsetx)*zm+dx),
00294                 (int)(((percorre->biota.estado.posicao.Y - percorre->biota.genes.massa_cabeca - RAIO_SELECAO)-offsety)*zm+dy),
00295                 (int)((percorre->biota.genes.massa_cabeca + RAIO_SELECAO)*2.0f*zm),
00296                 (int)((percorre->biota.genes.massa_cabeca + RAIO_SELECAO)*2.0f*zm));
00297 
00298                 brush.setStyle(Qt::SolidPattern);   painter.setBrush(brush);
00299             }
00300     }
00301     mutex->unlock();
00302 }
00303 
00304 /******************************************************************************/
00305 
00306 void MundoQT::mouseDoubleClickEvent ( QMouseEvent * event )
00307 {
00308     /* Salva posicao */
00309     lastPos = Vetor<float>(event->x(), event->y());
00310 
00311     if (event->button() == Qt::LeftButton)
00312     {
00313         /* Sincroniza */
00314         mutex->lock();
00315 
00316         /* Tenta selecionar grao */
00317         if (selecionarGrao((Vetor<float>(event->x(), event->y()) - (Vetor<float>(width(),height())/2.0f))/zm + Vetor<float>(offsetx, offsety)))
00318             /* Remove selecionado */
00319             removerGrao();
00320         else
00321             novoGrao();
00322 
00323         /* Libera */
00324         mutex->unlock();
00325 
00326         /* redesenha */
00327         if (!executando)
00328             repaint();
00329     }
00330 }
00331 
00332 /******************************************************************************/
00333 
00334 void MundoQT::mouseMoveEvent ( QMouseEvent * event )
00335 {
00336     if ((event->buttons() & Qt::MidButton) != 0)
00337     {
00338         /* Movimentacao */
00339         offsetx +=  (lastPos.X - event->x()) / zm;
00340         offsety +=  (lastPos.Y - event->y())  / zm;
00341 
00342         /* Arruma limites */
00343         if (offsetx < 0)
00344             offsetx = 0;
00345         else if (offsetx > propriedades.tamanho_x)
00346             offsetx = propriedades.tamanho_x;
00347         if (offsety < 0)
00348             offsety = 0;
00349         else if (offsety > propriedades.tamanho_y)
00350             offsety = propriedades.tamanho_y;
00351 
00352 
00353         /* emite sinais */
00354         emit changeHorizontalBar((int)offsetx);
00355         emit changeVerticalBar((int)offsety);
00356 
00357         /* redesenha */
00358         if (!executando)
00359             repaint();
00360     }
00361     else if ((event->buttons() & Qt::LeftButton) != 0)
00362     {
00363         if (selecionado != NULL)
00364         {
00365             /* Arrasta biota */
00366             selecionado->biota.estado.posicao =
00367             ((Vetor<float>(event->x(), event->y()) - (Vetor<float>(width(),height())/2.0f))/zm + Vetor<float>(offsetx, offsety));
00368 
00369             /* redesenha */
00370             if (!executando)
00371                 repaint();
00372         }
00373         else if (grao_selecionado != NULL)
00374         {
00375             /* Arrasta grao */
00376             posicionarGrao
00377             ((Vetor<float>(event->x(), event->y()) - (Vetor<float>(width(),height())/2.0f))/zm + Vetor<float>(offsetx, offsety));
00378 
00379             /* redesenha */
00380             if (!executando)
00381                 repaint();
00382         }
00383         else if (parede_selecionada != NULL)
00384         {
00385             /* Arrasta parede */
00386             posicionarParede(Vetor<float>(event->x(), event->y()));
00387 
00388             /* redesenha */
00389             if (!executando)
00390                 repaint();
00391         }
00392     }
00393 
00394     /* Salva posicao */
00395     lastPos = Vetor<float>(event->x(), event->y());
00396 }
00397 
00398 /******************************************************************************/
00399 
00400 void MundoQT::mousePressEvent ( QMouseEvent * event )
00401 {
00402     /* Salva posicao */
00403     lastPos = Vetor<float>(event->x(), event->y());
00404 
00405     /* Seleciona ou desceleciona biota, grao ou parede */
00406     if (event->button() != Qt::MidButton) {
00407 
00408         Vetor<float> pos = (Vetor<float>(event->x(), event->y()) - (Vetor<float>(width(),height())/2.0f))/zm + Vetor<float>(offsetx, offsety);
00409 
00410         if (!selecionarBiota(pos))
00411             selecionado = NULL;
00412         if (!selecionarGrao(pos))
00413             grao_selecionado = NULL;
00414         if (!selecionarParede((Vetor<float>(event->x(), event->y()))))
00415             parede_selecionada = NULL;
00416 
00417         /* redesenha */
00418         if (!executando)
00419             repaint();
00420 
00421         if (event->button() == Qt::RightButton) {
00422             if (selecionado)
00423             {
00424                 info->setBiota(selecionado->biota);
00425                 info->move(event->globalPos());
00426                 menuBiota->exec(event->globalPos());
00427             }
00428             else if (grao_selecionado)
00429                 menuGrao->exec(event->globalPos());
00430             else if (parede_selecionada)
00431                 menuParede->exec(event->globalPos());
00432             else if (pos.X > 0 && pos.Y > 0 && pos.X < propriedades.tamanho_x && pos.Y < propriedades.tamanho_y)
00433                 menuVoid->exec(event->globalPos());
00434         }
00435 
00436         mudaBarraStatus();
00437     }
00438 }
00439 
00440 /******************************************************************************/
00441 
00442 void MundoQT::wheelEvent ( QWheelEvent * event )
00443 {
00444     if (event->delta() > 0 && zm > 0.1f)
00445     {
00446         zm = (zm * 0.9f) - 0.001f;
00447 
00448         if (!executando)
00449             repaint();
00450     }
00451     else if (event->delta() < 0 && zm < 4.0f)
00452     {
00453         zm = (zm * 1.1f) + 0.001f;
00454 
00455         if (!executando)
00456             repaint();
00457     }
00458 }
00459 
00460 /******************************************************************************/
00461 
00462 void MundoQT::mouseReleaseEvent ( QMouseEvent * event )
00463 {
00464     if (selecionado && executando)
00465     {
00466         selecionado->biota.acelerar(Vetor<float>(event->x(), event->y()) - lastPos);
00467     }
00468 }
00469 
00470 /******************************************************************************/
00471 
00472 void MundoQT::offsetxChanged(int vx)
00473 {
00474     offsetx = vx;
00475 
00476     /* redesenha */
00477     if (!executando)
00478         repaint();
00479 }
00480 
00481 /******************************************************************************/
00482 
00483 void MundoQT::offsetyChanged(int vy)
00484 {
00485     offsety = vy;
00486 
00487     /* redesenha */
00488     if (!executando)
00489         repaint();
00490 }
00491 
00492 /******************************************************************************/
00493 
00494 void MundoQT::setMutex(QMutex *m)
00495 {
00496     mutex = m;
00497 }
00498 
00499 
00500 /******************************************************************************/
00501 
00502 QMutex* MundoQT::getMutex()
00503 {
00504     return mutex;
00505 }
00506 
00507 /******************************************************************************/
00508 
00509 void MundoQT::atualizar()
00510 {
00511     static int deadCry = 50;
00512 
00513     mutex->lock();
00514     Mundo::atualizar();
00515 
00516     if (selecionado && fixar)
00517     {
00518         offsetx = selecionado->biota.estado.posicao.X;
00519         offsety = selecionado->biota.estado.posicao.Y;
00520 
00521         /* emite sinais */
00522         emit changeHorizontalBar((int)offsetx);
00523         emit changeVerticalBar((int)offsety);
00524     }
00525     mutex->unlock();
00526 
00527     if (!selecionado && autoSelec)
00528     {
00529         if (deadCry >= 50)
00530         {
00531             deadCry = 0;
00532             maisVelho();
00533         }
00534         else
00535             deadCry++;
00536     }
00537 
00538     mudaBarraStatus();
00539 }
00540 
00541 /******************************************************************************/
00542 
00543 
00544 
00545 void MundoQT::estatistica()
00546 {
00547     /* Atualiza formulario com estatisticas */
00548     /* Lista de cores */
00549 
00550     struct NohLineage
00551     {
00552         unsigned int lineage;
00553         unsigned int quantidade;
00554         int cor[3];
00555         struct NohLineage *proximo;
00556     };
00557 
00558     struct NohLineage cabecaLineage;
00559 
00560     cabecaLineage.proximo = NULL;
00561 
00562     /* Somas */
00563     float numero_segmentos = 0;
00564     float massa_cabeca = 0;
00565     float limiar_reproducao = 0;
00566     float distribuicao_energetica = 0;
00567     float idade = 0;
00568     float energia = 0;
00569     float geracao = 0;
00570     float filhos = 0;
00571 
00572     /* Maximos */
00573     unsigned int max_numero_segmentos = 0;
00574     int max_massa_cabeca = 0;
00575     int max_limiar_reproducao = 0;
00576     float max_distribuicao_energetica = 0;
00577     unsigned int max_idade = 0;
00578     float max_energia = 0;
00579     unsigned int max_geracao = 0;
00580     unsigned int max_filhos = 0;
00581 
00582     /* Percorre a lista de biotas */
00583     mutex->lock();
00584     for (struct NohBiota *percorre = nohCabecaBiotas.proximo;
00585     percorre != NULL;
00586     percorre = percorre->proximo)
00587     {
00588         /* Soma valores */
00589         numero_segmentos += percorre->biota.numero_segmentos;
00590         massa_cabeca += percorre->biota.genes.massa_cabeca;
00591         limiar_reproducao += percorre->biota.genes.limiar_reproducao;
00592         distribuicao_energetica += percorre->biota.genes.distribuicao_energia;
00593         idade += percorre->biota.estado.idade;
00594         energia += percorre->biota.estado.energia;
00595         geracao += percorre->biota.estado.geracao;
00596         filhos += percorre->biota.estado.filhos;
00597 
00598         /* Calcula maximos */
00599         if (percorre->biota.numero_segmentos > max_numero_segmentos)
00600             max_numero_segmentos = percorre->biota.numero_segmentos;
00601         if (percorre->biota.genes.massa_cabeca > max_massa_cabeca)
00602             max_massa_cabeca = percorre->biota.genes.massa_cabeca;
00603         if (percorre->biota.genes.limiar_reproducao > max_limiar_reproducao)
00604             max_limiar_reproducao = percorre->biota.genes.limiar_reproducao;
00605         if (percorre->biota.genes.distribuicao_energia > max_distribuicao_energetica)
00606             max_distribuicao_energetica = percorre->biota.genes.distribuicao_energia;
00607         if (percorre->biota.estado.idade > max_idade)
00608             max_idade = percorre->biota.estado.idade;
00609         if (percorre->biota.estado.energia > max_energia)
00610             max_energia = percorre->biota.estado.energia;
00611         if (percorre->biota.estado.geracao > max_geracao)
00612             max_geracao = percorre->biota.estado.geracao;
00613         if (percorre->biota.estado.filhos > max_filhos)
00614             max_filhos = percorre->biota.estado.filhos;
00615 
00616         /* Percorre lista de lineage */
00617         struct NohLineage *percorre_lin;
00618         for (percorre_lin = &cabecaLineage;
00619         percorre_lin->proximo != NULL &&
00620         percorre_lin->proximo->lineage > percorre->biota.lineage;
00621         percorre_lin = percorre_lin->proximo)
00622         ;
00623 
00624         /* se encontrou lineage */
00625         if (percorre_lin->proximo != NULL && (percorre_lin->proximo->lineage == percorre->biota.lineage))
00626         {
00627             percorre_lin->proximo->quantidade++;
00628             percorre_lin->proximo->cor[0] += percorre->biota.genes.cor_cabeca[0];
00629             percorre_lin->proximo->cor[1] += percorre->biota.genes.cor_cabeca[1];
00630             percorre_lin->proximo->cor[2] += percorre->biota.genes.cor_cabeca[2];
00631         }
00632         else
00633         {
00634             /* nao existe lineage */
00635             struct NohLineage *novo = new NohLineage;
00636 
00637             novo->lineage = percorre->biota.lineage;
00638             novo->proximo = percorre_lin->proximo;
00639             novo->quantidade = 1;
00640             novo->cor[0] = percorre->biota.genes.cor_cabeca[0];
00641             novo->cor[1] = percorre->biota.genes.cor_cabeca[1];
00642             novo->cor[2] = percorre->biota.genes.cor_cabeca[2];
00643 
00644             percorre_lin->proximo = novo;
00645         }
00646     }
00647     mutex->unlock();
00648 
00649     /* Divide valores para alcancar a media */
00650     if (estatisticas.numero_biotas > 0)
00651     {
00652         numero_segmentos /= estatisticas.numero_biotas;
00653         massa_cabeca /= estatisticas.numero_biotas;
00654         limiar_reproducao /= estatisticas.numero_biotas;
00655         distribuicao_energetica /= estatisticas.numero_biotas;
00656 
00657         idade /= estatisticas.numero_biotas;
00658         energia  /= estatisticas.numero_biotas;
00659         geracao /= estatisticas.numero_biotas;
00660         filhos /= estatisticas.numero_biotas;
00661     }
00662 
00663     /* Desenha grafico de cores */
00664     QPainter painterE(stat->imgEspecies->imagem);
00665     int altura = 0;
00666 
00667 
00668     /* Percorre lista de lineages */
00669     struct NohLineage *percorre_lin = cabecaLineage.proximo;
00670     while (percorre_lin != NULL)
00671     {
00672         /* Desenha */
00673         painterE.setPen(QPen(QColor(
00674         percorre_lin->cor[0]/percorre_lin->quantidade,
00675         percorre_lin->cor[1]/percorre_lin->quantidade,
00676         percorre_lin->cor[2]/percorre_lin->quantidade)));
00677 
00678         painterE.drawLine(
00679         stat->imgEspecies->imagem->width()-1,
00680         stat->imgEspecies->imagem->height() -
00681         (int)(altura * stat->imgEspecies->imagem->height() / (float)estatisticas.numero_biotas),
00682         stat->imgEspecies->imagem->width()-1,
00683         stat->imgEspecies->imagem->height() -
00684         (int)((altura + percorre_lin->quantidade) * stat->imgEspecies->imagem->height() / (float)estatisticas.numero_biotas));
00685 
00686         altura += percorre_lin->quantidade;
00687 
00688         /* Deleta e passa para o proximo */
00689         struct NohLineage *remove = percorre_lin;
00690         percorre_lin = percorre_lin->proximo;
00691         delete remove;
00692     }
00693     /* desloca imagem */
00694     painterE.drawImage(-1,0,*(stat->imgEspecies->imagem));
00695 
00696     /* Pinta grafico de biotas x Graos */
00697     static int max_numero_biotas_graos = 0;
00698     static int lastGraoY = -1;
00699     static int lastBiotaY = -1;
00700 
00701     /* Ajusta valores maximos */
00702     if (estatisticas.numero_biotas > (unsigned int)max_numero_biotas_graos)
00703         max_numero_biotas_graos = estatisticas.numero_biotas;
00704     if (estatisticas.numero_graos > (unsigned int)max_numero_biotas_graos)
00705         max_numero_biotas_graos = estatisticas.numero_graos;
00706 
00707     /* calcula posicoes */
00708     int biotaY = stat->imgBiotasGraos->height() -
00709     (int)(estatisticas.numero_biotas * stat->imgBiotasGraos->height() / (float)max_numero_biotas_graos);
00710 
00711     int graoY = stat->imgBiotasGraos->height() -
00712     (int)(estatisticas.numero_graos * stat->imgBiotasGraos->height() / (float)max_numero_biotas_graos);
00713 
00714     /* Pinta linha branca */
00715     QPainter painterBG(stat->imgBiotasGraos->imagem);
00716     painterBG.setPen(QPen(Qt::white));
00717     painterBG.drawLine(stat->imgBiotasGraos->width()-1, 0, stat->imgBiotasGraos->width()-1, stat->imgBiotasGraos->height());
00718 
00719     /* Pinta linhas do grafico */
00720     painterBG.setPen(QPen(Qt::red));
00721     painterBG.drawLine(stat->imgBiotasGraos->width()-2, (lastBiotaY == -1)? biotaY : lastBiotaY, stat->imgBiotasGraos->width()-1, biotaY);
00722     painterBG.setPen(QPen(Qt::blue));
00723     painterBG.drawLine(stat->imgBiotasGraos->width()-2, (lastGraoY == -1)? graoY : lastGraoY, stat->imgBiotasGraos->width()-1, graoY);
00724 
00725     /* desloca imagem */
00726     painterBG.drawImage(-1,0,*(stat->imgBiotasGraos->imagem));
00727 
00728     lastBiotaY = biotaY;
00729     lastGraoY = graoY;
00730 
00731     if (stat->isVisible())
00732     {
00733         /* Escreve dados */
00734         /* medias */
00735         stat->labelEnergia->setText(QVariant(energia).toString() + tr(" wens"));
00736         stat->labelSegmentos->setText(QVariant(numero_segmentos).toString());
00737         stat->labelCabeca->setText(QVariant(massa_cabeca).toString());
00738         stat->labelLimiar->setText(QVariant(limiar_reproducao).toString() + tr(" wens"));
00739         stat->labelDistribuicao->setText(QVariant(distribuicao_energetica*100).toString() + tr(" %"));
00740         stat->labelGeracao->setText(QVariant(geracao).toString());
00741         stat->labelIdade->setText(QVariant(idade).toString());
00742         stat->labelFilhos->setText(QVariant(filhos).toString());
00743         /* maximos */
00744         stat->labelEnergia_2->setText(QVariant(max_energia).toString() + tr(" wens"));
00745         stat->labelSegmentos_2->setText(QVariant(max_numero_segmentos).toString());
00746         stat->labelCabeca_2->setText(QVariant(max_massa_cabeca).toString());
00747         stat->labelLimiar_2->setText(QVariant(max_limiar_reproducao).toString() + tr(" wens"));
00748         stat->labelDistribuicao_2->setText(QVariant(max_distribuicao_energetica*100).toString() + tr(" %"));
00749         stat->labelGeracao_2->setText(QVariant(max_geracao).toString());
00750         stat->labelIdade_2->setText(QVariant(max_idade).toString());
00751         stat->labelFilhos_2->setText(QVariant(max_filhos).toString());
00752         /* grafico biotas x graos */
00753         stat->labelGraosxBiotas->setText(QVariant((float)estatisticas.numero_graos/(float)estatisticas.numero_biotas).toString());
00754 
00755         /* Repinta graficos */
00756         stat->imgEspecies->repaint();
00757         stat->imgBiotasGraos->repaint();
00758     }
00759 }
00760 
00761 /******************************************************************************/
00762 
00763 void MundoQT::mudaBarraStatus()
00764 {
00765     if (selecionado)
00766         emit estadoModificado(
00767         tr("Age") + ": " + QVariant(selecionado->biota.estado.idade).toString() +
00768         ", " + tr("Generation") + ": " + QVariant((int)selecionado->biota.estado.geracao).toString() +
00769         ", " + tr("Energy") + ": " + QVariant((int)selecionado->biota.estado.energia).toString() +
00770         ", " + tr("Offsprings") + ": " + QVariant((int)selecionado->biota.estado.filhos).toString());
00771     else if (grao_selecionado)
00772         emit estadoModificado(
00773         ", " + tr("Grain energy") + ": " + QVariant(propriedades.energia_grao).toString());
00774     else
00775         emit estadoModificado(
00776         QVariant((int)estatisticas.ciclos).toString() + " " + tr("Cicles") + ", " +
00777         QVariant((int)estatisticas.numero_biotas).toString() + + " " + tr("Biots") + ", " +
00778         QVariant((int)estatisticas.numero_graos).toString() + + " " + tr("Grains") + ".");
00779 }
00780 
00781 /******************************************************************************/
00782 
00783 void MundoQT::limpar()
00784 {
00785     /* Limpa */
00786 
00787     /* Sincroniza */
00788     if (mutex != NULL)
00789         mutex->lock();
00790 
00791     Mundo::destroy();
00792 
00793     /* Libera */
00794     if (mutex != NULL)
00795         mutex->unlock();
00796 
00797     /* redesenha */
00798     if (!executando && mutex != NULL)
00799         repaint();
00800 
00801     mudaBarraStatus();
00802 }
00803 
00804 /******************************************************************************/
00805 
00806 void MundoQT::reiniciar()
00807 {
00808     limpar();
00809 
00810     /* Sincroniza */
00811     if (mutex != NULL)
00812         mutex->lock();
00813 
00814     /* Cria biotas aleatorios */
00815     int inicial = rand() % 2+((propriedades.tamanho_x*propriedades.tamanho_y)/250000);
00816     for (int c = 0; c < inicial; c++)
00817         inserirBiota(Biota((Mundo*)this));
00818 
00819     /* Libera */
00820     if (mutex != NULL)
00821         mutex->unlock();
00822 
00823     selecionado = NULL;
00824 
00825     /* redesenha */
00826     if (!executando)
00827         repaint();
00828 
00829     mudaBarraStatus();
00830 }
00831 
00832 /******************************************************************************/
00833 
00834 void MundoQT::posicionarParede(Vetor<float> pos)
00835 {
00836     if (pontaSelecionada == PONTA_INICIO)
00837         parede_selecionada->inicio = (pos - (Vetor<float>(width(),height())/2.0f))/zm + Vetor<float>(offsetx, offsety);
00838     else if (pontaSelecionada == PONTA_FIM)
00839         parede_selecionada->fim = (pos - (Vetor<float>(width(),height())/2.0f))/zm + Vetor<float>(offsetx, offsety);
00840     else
00841     {
00842         Vetor<float> posicao = (pos - (Vetor<float>(width(),height())/2.0f))/zm + Vetor<float>(offsetx, offsety);
00843 
00844         parede_selecionada->inicio += posicao - ancora_parede;
00845         parede_selecionada->fim += posicao - ancora_parede;
00846         ancora_parede = posicao;
00847     }
00848 }
00849 
00850 
00851 /******************************************************************************/
00852 
00853 bool MundoQT::selecionarParede(Vetor<float> pos)
00854 {
00855     Vetor<float> posicao = (pos - (Vetor<float>(width(),height())/2.0f))/zm + Vetor<float>(offsetx, offsety);
00856 
00857     /* Percorre lista de paredes */
00858     for (struct NohParede *percorre = nohCabecaParedes.proximo;
00859     percorre != NULL;
00860     percorre = percorre->proximo)
00861     {
00862         if (posicao.distancia(percorre->inicio) <= DISTANCIA_SELECAO_PAREDE)
00863         {
00864             parede_selecionada = percorre;
00865             pontaSelecionada = PONTA_INICIO;
00866             return true;
00867         }
00868         if (posicao.distancia(percorre->fim) <= DISTANCIA_SELECAO_PAREDE)
00869         {
00870             parede_selecionada = percorre;
00871             pontaSelecionada = PONTA_FIM;
00872             return true;
00873         }
00874 
00875         Vetor<float> u = posicao - percorre->inicio;
00876         Vetor<float> v = percorre->fim - percorre->inicio;
00877         Vetor<float> proj = (v.modulo() == 0)? posicao : (
00878         (v / v.modulo ()) *
00879         (((u.X * v.X)+(u.Y * v.Y)) / v.modulo()) );
00880 
00881         proj += percorre->inicio;
00882 
00883         /* Corrige limites da parede */
00884         if (proj.X > percorre->inicio.X && proj.X > percorre->fim.X)
00885             proj = (percorre->inicio.X > percorre->fim.X)? percorre->inicio : percorre->fim;
00886         else if (proj.X < percorre->inicio.X && proj.X < percorre->fim.X)
00887             proj = (percorre->inicio.X < percorre->fim.X)? percorre->inicio : percorre->fim;
00888         else if (proj.Y > percorre->inicio.Y && proj.Y > percorre->fim.Y)
00889             proj = (percorre->inicio.Y > percorre->fim.Y)? percorre->inicio : percorre->fim;
00890         else if (proj.Y < percorre->inicio.Y && proj.Y < percorre->fim.Y)
00891             proj = (percorre->inicio.Y < percorre->fim.Y)? percorre->inicio : percorre->fim;
00892 
00893         /* Testa distancia */
00894         if (posicao.distancia(proj) <=
00895         GROSSURA_PAREDE)
00896         {
00897             parede_selecionada = percorre;
00898             pontaSelecionada = MEIO;
00899             ancora_parede = proj;
00900             return true;
00901         }
00902     }
00903     return false;
00904 }
00905 
00906 /******************************************************************************/
00907 
00908 void MundoQT::novaParede()
00909 {
00910     mutex->lock();
00911     struct NohParede *novaParede = new struct NohParede;
00912 
00913     novaParede->inicio = (lastPos - (Vetor<float>(width(),height())/2.0f))/zm + Vetor<float>(offsetx, offsety);
00914     novaParede->fim = (lastPos - (Vetor<float>(width(),height())/2.0f))/zm + Vetor<float>(offsetx, offsety);
00915     novaParede->proximo = nohCabecaParedes.proximo;
00916     nohCabecaParedes.proximo = novaParede;
00917 
00918     parede_selecionada = novaParede;
00919     pontaSelecionada = PONTA_FIM;
00920     mutex->unlock();
00921 
00922     /* Redesenha */
00923     if (!executando)
00924         repaint();
00925 }
00926 
00927 /******************************************************************************/
00928 
00929 void MundoQT::removerParede()
00930 {
00931     mutex->lock();
00932     /* Percorre lista de paredes */
00933     for (struct NohParede *percorre = &nohCabecaParedes;
00934     percorre->proximo != NULL;
00935     percorre = percorre->proximo)
00936         if (percorre->proximo == parede_selecionada)
00937         {
00938             struct NohParede *remover = percorre->proximo;
00939             percorre->proximo = percorre->proximo->proximo;
00940             delete remover;
00941             parede_selecionada = NULL;
00942 
00943             break;
00944         }
00945     mutex->unlock();
00946 
00947     /* Redesenha */
00948     if (!executando)
00949         repaint();
00950 }
00951 
00952 /******************************************************************************/
00953 
00954 void MundoQT::novoGrao()
00955 {
00956     /* Insere novo grao na posicao */
00957     mutex->lock();
00958     inserirGrao((lastPos - (Vetor<float>(width(),height())/2.0f))/zm + Vetor<float>(offsetx, offsety));
00959     mutex->unlock();
00960 
00961     /* Redesenha */
00962     if (!executando)
00963         repaint();
00964 }
00965 
00966 /******************************************************************************/
00967 
00968 void MundoQT::removerGrao()
00969 {
00970     removerGraoSelecionado();
00971 }
00972 
00973 /******************************************************************************/
00974 
00975 void MundoQT::salvarBiota()
00976 {
00977     bool was_executando = executando;
00978     if (executando)
00979         MainWindow::getInstance()->startStop();
00980 
00981     QString fileName = QFileDialog::getSaveFileName(this, tr("Save Biot"),QDir::homePath(),tr("Biot") + "(*.xml)");
00982 
00983     if (!fileName.isNull())
00984     {
00985         FILE *arq;
00986         arq = fopen(fileName.toAscii().data(), "w");
00987 
00988         selecionado->biota.salvar(arq);
00989         fclose(arq);
00990     }
00991 
00992     if (was_executando)
00993         MainWindow::getInstance()->startStop();
00994 }
00995 
00996 /******************************************************************************/
00997 
00998 void MundoQT::abrirBiota()
00999 {
01000     QString fileName = QFileDialog::getOpenFileName(this, tr("Open Biot"),QDir::homePath(),tr("Biot") + "(*.xml)");
01001 
01002     if (fileName.isNull())
01003         return;
01004 
01005     FILE *arq;
01006     arq = fopen(fileName.toAscii().data(), "r");
01007 
01008     mutex->lock();
01009     Biota biota = Biota((Mundo*)this, ((lastPos-Vetor<float>(width()/2,height()/2))/zm) + Vetor<float>(offsetx, offsety), arq);
01010     inserirBiota(biota);
01011     mutex->unlock();
01012 
01013     fclose(arq);
01014 
01015     /* Redesenha */
01016     if (!executando)
01017         repaint();
01018 }
01019 
01020 /******************************************************************************/
01021 
01022 void MundoQT::novoBiota()
01023 {
01024     mutex->lock();
01025 
01026     Biota biota((Mundo*)this);
01027     biota.estado.posicao = ((lastPos - Vetor<float>(width()/2,height()/2))/zm) + Vetor<float>(offsetx, offsety);
01028 
01029     inserirBiota(biota);
01030 
01031     mutex->unlock();
01032 
01033     /* Redesenha */
01034     if (!executando)
01035         repaint();
01036 }
01037 
01038 /******************************************************************************/
01039 
01040 void MundoQT::removerBiota()
01041 {
01042     mutex->lock();
01043 
01044     /* Percorre a lista de biotas em busca do selecionado*/
01045     struct NohBiota *percorre;
01046     for (percorre = &nohCabecaBiotas;
01047     percorre->proximo != selecionado;
01048     percorre = percorre->proximo);
01049 
01050     /* Remove biota da lista */
01051     struct NohBiota *remover = percorre->proximo;
01052     percorre->proximo = percorre->proximo->proximo;
01053     /* Desceleciona */
01054     selecionado = NULL;
01055     /* Libera memoria */
01056     remover->biota.destroy();
01057     delete remover;
01058     /* Decrementa contador de biotas */
01059     estatisticas.numero_biotas--;
01060 
01061     mutex->unlock();
01062 
01063     /* Redesenha */
01064     if (!executando)
01065         repaint();
01066 }
01067 
01068 /******************************************************************************/
01069 
01070 void MundoQT::mutacaoBiota()
01071 {
01072     mutex->lock();
01073     selecionado->biota.mutacao();
01074     mutex->unlock();
01075 
01076     /* Redesenha */
01077     if (!executando)
01078         repaint();
01079 }
01080 
01081 /******************************************************************************/
01082 
01083 void MundoQT::setMenuBiota(QMenu *m)
01084 {
01085     menuBiota = m;
01086 }
01087 
01088 /******************************************************************************/
01089 
01090 void MundoQT::setMenuGrao(QMenu *m)
01091 {
01092     menuGrao = m;
01093 }
01094 
01095 /******************************************************************************/
01096 
01097 void MundoQT::setMenuVoid(QMenu *m)
01098 {
01099     menuVoid = m;
01100 }
01101 
01102 /******************************************************************************/
01103 
01104 void MundoQT::setMenuParede(QMenu *m)
01105 {
01106     menuParede = m;
01107 }
01108 
01109 /******************************************************************************/
01110 
01111 void MundoQT::maisVelho()
01112 {
01113     NohBiota *maximo = NULL;
01114 
01115     /* Percorre a lista de biotas */
01116     mutex->lock();
01117     for (struct NohBiota *percorre = nohCabecaBiotas.proximo;
01118     percorre != NULL;
01119     percorre = percorre->proximo)
01120     {
01121         if (maximo == NULL || percorre->biota.estado.idade > maximo->biota.estado.idade)
01122             maximo = percorre;
01123     }
01124     mutex->unlock();
01125 
01126     selecionado = maximo;
01127 
01128     /* track */
01129     offsetx = selecionado->biota.estado.posicao.X;
01130     offsety = selecionado->biota.estado.posicao.Y;
01131 
01132     /* emite sinais */
01133     emit changeHorizontalBar((int)offsetx);
01134     emit changeVerticalBar((int)offsety);
01135     mudaBarraStatus();
01136 }
01137 
01138 /******************************************************************************/
01139 
01140 void MundoQT::maisEnergia()
01141 {
01142     NohBiota *maximo = NULL;
01143 
01144     /* Percorre a lista de biotas */
01145     mutex->lock();
01146     for (struct NohBiota *percorre = nohCabecaBiotas.proximo;
01147     percorre != NULL;
01148     percorre = percorre->proximo)
01149     {
01150         if (maximo == NULL || percorre->biota.estado.energia > maximo->biota.estado.energia)
01151             maximo = percorre;
01152     }
01153     mutex->unlock();
01154 
01155     selecionado = maximo;
01156 
01157     /* track */
01158     offsetx = selecionado->biota.estado.posicao.X;
01159     offsety = selecionado->biota.estado.posicao.Y;
01160 
01161     /* emite sinais */
01162     emit changeHorizontalBar((int)offsetx);
01163     emit changeVerticalBar((int)offsety);
01164     mudaBarraStatus();
01165 }
01166 
01167 /******************************************************************************/
01168 
01169 void MundoQT::geracaoMaisNova()
01170 {
01171     NohBiota *maximo = NULL;
01172 
01173     /* Percorre a lista de biotas */
01174     mutex->lock();
01175     for (struct NohBiota *percorre = nohCabecaBiotas.proximo;
01176     percorre != NULL;
01177     percorre = percorre->proximo)
01178     {
01179         if (maximo == NULL || percorre->biota.estado.geracao > maximo->biota.estado.geracao)
01180             maximo = percorre;
01181     }
01182     mutex->unlock();
01183 
01184     selecionado = maximo;
01185 
01186     /* track */
01187     offsetx = selecionado->biota.estado.posicao.X;
01188     offsety = selecionado->biota.estado.posicao.Y;
01189 
01190     /* emite sinais */
01191     emit changeHorizontalBar((int)offsetx);
01192     emit changeVerticalBar((int)offsety);
01193     mudaBarraStatus();
01194 }
01195 
01196 /******************************************************************************/
01197 
01198 void MundoQT::geracaoMaisAntiga()
01199 {
01200     NohBiota *maximo = NULL;
01201 
01202     /* Percorre a lista de biotas */
01203     mutex->lock();
01204     for (struct NohBiota *percorre = nohCabecaBiotas.proximo;
01205     percorre != NULL;
01206     percorre = percorre->proximo)
01207     {
01208         if (maximo == NULL || percorre->biota.estado.geracao < maximo->biota.estado.geracao)
01209             maximo = percorre;
01210     }
01211     mutex->unlock();
01212 
01213     selecionado = maximo;
01214 
01215     /* track */
01216     offsetx = selecionado->biota.estado.posicao.X;
01217     offsety = selecionado->biota.estado.posicao.Y;
01218 
01219     /* emite sinais */
01220     emit changeHorizontalBar((int)offsetx);
01221     emit changeVerticalBar((int)offsety);
01222     mudaBarraStatus();
01223 }
01224 
01225 
01226 /******************************************************************************/
01227 
01228 void MundoQT::maisFilhos()
01229 {
01230     NohBiota *maximo = NULL;
01231 
01232     /* Percorre a lista de biotas */
01233     mutex->lock();
01234     for (struct NohBiota *percorre = nohCabecaBiotas.proximo;
01235     percorre != NULL;
01236     percorre = percorre->proximo)
01237     {
01238         if (maximo == NULL || percorre->biota.estado.filhos > maximo->biota.estado.filhos)
01239             maximo = percorre;
01240     }
01241     mutex->unlock();
01242 
01243     selecionado = maximo;
01244 
01245     /* track */
01246     offsetx = selecionado->biota.estado.posicao.X;
01247     offsety = selecionado->biota.estado.posicao.Y;
01248 
01249     /* emite sinais */
01250     emit changeHorizontalBar((int)offsetx);
01251     emit changeVerticalBar((int)offsety);
01252     mudaBarraStatus();
01253 }
01254 
01255 /******************************************************************************/
01256 
01257 void MundoQT::abrirSimulacao()
01258 {
01259     QString fileName = QFileDialog::getOpenFileName(this, tr("Open Simulation"),QDir::homePath(),tr("Simulation") + "(*.xml)");
01260 
01261     if (fileName.isNull())
01262         return;
01263 
01264     FILE *arq;
01265     arq = fopen(fileName.toAscii().data(), "r");
01266 
01267     mutex->lock();
01268     Mundo::abrirMundo(arq);
01269     mutex->unlock();
01270 
01271     fclose(arq);
01272 
01273     /* Redesenha */
01274     if (!executando)
01275         repaint();
01276 }
01277 
01278 /******************************************************************************/
01279 
01280 void MundoQT::salvarSimulacao()
01281 {
01282     QString fileName = QFileDialog::getSaveFileName(this, tr("Save Simulation"),QDir::homePath(),tr("Simulation") + "(*.xml)");
01283 
01284     if (fileName.isNull())
01285         return;
01286 
01287     FILE *arq;
01288     arq = fopen(fileName.toAscii().data(), "w");
01289 
01290     Mundo::salvarMundo(arq);
01291     fclose(arq);
01292 }
01293 
01294 /******************************************************************************/

Gerado em Mon May 4 14:52:59 2009 para Simvida por  doxygen 1.5.8