ThymioButtons.cpp
Go to the documentation of this file.
00001 #include <QPainter>
00002 #include <QGraphicsSceneMouseEvent>
00003 #include <QGraphicsScene>
00004 #include <QSvgRenderer>
00005 #include <QDrag>
00006 #include <QMimeData>
00007 #include <QCursor>
00008 #include <QApplication>
00009 
00010 #include "ThymioButtons.h"
00011 #include "ThymioButtons.moc"
00012 
00013 namespace Aseba
00014 {
00015         // Clickable button
00016         ThymioClickableButton::ThymioClickableButton ( QRectF rect, ThymioButtonType type,  int nstates, QGraphicsItem *parent ) :
00017                 QGraphicsObject(parent),
00018                 buttonType(type),
00019                 buttonClicked(false),
00020                 toggleState(true),
00021                 numStates(nstates),
00022                 boundingRectangle(rect),
00023                 buttonColor(Qt::gray),
00024                 buttonBeginColor(Qt::white)
00025         {               
00026                 setFlag(QGraphicsItem::ItemIsFocusable);
00027                 setFlag(QGraphicsItem::ItemIsSelectable);
00028         
00029                 setCursor(Qt::ArrowCursor);
00030         }
00031         
00032         void ThymioClickableButton::paint ( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget )
00033         {               
00034                 painter->setPen(QPen(QBrush(Qt::black), 5, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); // outline
00035                 
00036                 // filled
00037                 if( buttonClicked == 0 )
00038                         painter->setBrush(Qt::white);
00039                 else
00040                 {
00041                         double step = (numStates <= 2 ? 1 : (double)(buttonClicked-1)/(double)(numStates-2));
00042                         painter->setBrush(QColor(buttonColor.red()*step + buttonBeginColor.red()*(1-step),
00043                                                                          buttonColor.green()*step + buttonBeginColor.green()*(1-step),
00044                                                                          buttonColor.blue()*step + buttonBeginColor.blue()*(1-step))); 
00045                 }
00046 
00047                 if ( buttonType == THYMIO_CIRCULAR_BUTTON )
00048                         painter->drawEllipse(boundingRectangle);
00049                 else if ( buttonType == THYMIO_TRIANGULAR_BUTTON )
00050                 {
00051                         QPointF points[3];
00052                         points[0] = (boundingRectangle.topLeft() + boundingRectangle.topRight())*0.5;
00053                         points[1] = boundingRectangle.bottomLeft();
00054                         points[2] = boundingRectangle.bottomRight();
00055                         painter->drawPolygon(points, 3);
00056                 }
00057                 else
00058                         painter->drawRect(boundingRectangle);
00059 
00060         }
00061 
00062         void ThymioClickableButton::mousePressEvent ( QGraphicsSceneMouseEvent * event )
00063         {
00064                 if( event->button() == Qt::LeftButton ) 
00065                 {
00066                         if( toggleState ) {
00067                                 if( ++buttonClicked == numStates )
00068                                         buttonClicked = 0;
00069                                 update();
00070                         }
00071                         else 
00072                         {
00073                                 buttonClicked = 1;
00074                                 for( QList<ThymioClickableButton*>::iterator itr = siblings.begin();
00075                                          itr != siblings.end(); ++itr )                         
00076                                         (*itr)->setClicked(0);
00077                                 parentItem()->update();
00078                         }
00079                         emit stateChanged();
00080                 }
00081         }
00082                 
00083         // Face Button
00084         ThymioFaceButton::ThymioFaceButton ( QRectF rect, ThymioSmileType type, QGraphicsItem *parent ) :
00085                 ThymioClickableButton( rect, THYMIO_CIRCULAR_BUTTON, 2, parent )
00086         {
00087                 qreal x = boundingRectangle.x();
00088                 qreal y = boundingRectangle.y();
00089                 qreal w = boundingRectangle.width();
00090                 qreal h = boundingRectangle.height();
00091                 qreal s = (w+h)*0.05;
00092 
00093                 leftEye = QRectF(x+w*0.3, y+h*0.3, s, s);
00094                 rightEye = QRectF(x+w*0.7-s, y+h*0.3, s, s);
00095                 
00096                 if( type == THYMIO_SMILE_BUTTON ) 
00097                 {
00098                         mouth = QRectF(x+w*0.2, y+h*0.2, w*0.6, h*0.6);
00099                         arcStart = 0;
00100                         arcEnd = -2880;
00101                 } 
00102                 else if( type == THYMIO_FROWN_BUTTON )
00103                 {
00104                         mouth = QRectF(x+w*0.2, y+h*0.5, w*0.6, h*0.6);
00105                         arcStart = 1;
00106                         arcEnd = 2879;
00107                 }
00108                 else
00109                 {
00110                         mouth = QRectF(x+w*0.2, y+h*0.6, w*0.6, h*0.05);
00111                         arcStart = 0;
00112                         arcEnd = -2880;
00113                 }
00114         }
00115 
00116         void ThymioFaceButton::paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget)
00117         {
00118                 painter->setPen(QPen(QBrush(Qt::black), 5, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); // outline
00119                 
00120                 // filled
00121                 if ( buttonClicked )
00122                         painter->setBrush(buttonColor);
00123                 else
00124                         painter->setBrush(Qt::white);
00125 
00126                 painter->drawEllipse(boundingRectangle);
00127 
00128                 painter->setBrush(Qt::black);           
00129                 painter->drawEllipse(leftEye);
00130                 painter->drawEllipse(rightEye);
00131                 painter->drawArc(mouth, arcStart, arcEnd);
00132 
00133         }
00134 
00135         void ThymioButton::ThymioBody::paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget)
00136         {                       
00137                 Q_UNUSED(option);
00138                 Q_UNUSED(widget);
00139                 
00140                 // button shape
00141                 painter->setPen(Qt::NoPen);
00142                 painter->setBrush(bodyColor);
00143                 painter->drawChord(-124, -118, 248, 144, 0, 2880);
00144                 painter->drawRoundedRect(-124, -52, 248, 176, 5, 5);
00145                 
00146                 if(!up) 
00147                 {
00148                         painter->setBrush(Qt::black);
00149                         painter->drawRect(-128, 30, 18, 80);
00150                         painter->drawRect(110, 30, 18, 80);
00151                 }
00152         }
00153 
00154         ThymioButton::ThymioButton(bool eventButton, qreal scale, bool up, bool advanced, QGraphicsItem *parent) : 
00155                 QGraphicsSvgItem(parent),
00156                 buttonIR(),
00157                 buttonColor(eventButton ? QColor(0,191,255) : QColor(218, 112, 214)),
00158                 parentID(-1),
00159                 scaleFactor(0.5),
00160                 trans(advanced ? 64 : 0)
00161         {
00162                 thymioBody = new ThymioBody(this);
00163                 thymioBody->setUp(up);
00164                 thymioBody->setScale(scale);
00165                 thymioBody->setPos(128,128);
00166 
00167                 setFlag(QGraphicsItem::ItemIsFocusable);                
00168                 setFlag(QGraphicsItem::ItemIsSelectable);       
00169 
00170                 setCursor(Qt::OpenHandCursor);
00171                 setAcceptedMouseButtons(Qt::LeftButton);
00172                 
00173                 if( advanced )
00174                 {
00175                         for(uint i=0; i<4; i++)
00176                         {       
00177                                 ThymioClickableButton *button = new ThymioClickableButton(QRectF(-20,-20,40,40), THYMIO_CIRCULAR_BUTTON, 2, this);
00178                                 button->setPos(295, i*60 + 40);
00179                                 button->setButtonColor(QColor(255,200,0));
00180 
00181                                 stateButtons.push_back(button);
00182                                 connect(button, SIGNAL(stateChanged()), this, SLOT(updateIRButton()));
00183                         }
00184                 }
00185         }
00186 
00187         ThymioButton::~ThymioButton() 
00188         {
00189                 if( buttonIR != 0 ) 
00190                         delete(buttonIR);
00191         }
00192 
00193         void ThymioButton::setScaleFactor(qreal factor) 
00194         { 
00195                 scaleFactor = factor; 
00196         } 
00197 
00198         void ThymioButton::setClicked(int i, int status)
00199         {
00200                 if( i < thymioButtons.size()  )
00201                         thymioButtons.at(i)->setClicked(status);                        
00202 
00203                 updateIRButton();
00204         }
00205         
00206         ThymioIRButton *ThymioButton::getIRButton()
00207         {
00208                 int num = getNumButtons();
00209                 if( buttonIR == 0 )
00210                 {
00211                         QString name = getName();
00212                         //qDebug() << "getIRButton num: " << num;
00213 
00214                         if( name == "button" )
00215                                 buttonIR = new ThymioIRButton(num, THYMIO_BUTTONS_IR, 2);
00216                         else if( name == "prox" )
00217                                 buttonIR = new ThymioIRButton(num, THYMIO_PROX_IR, 3);
00218                         else if( name == "proxground" )
00219                                 buttonIR = new ThymioIRButton(num, THYMIO_PROX_GROUND_IR, 3);
00220                         else if( name == "tap" )
00221                                 buttonIR = new ThymioIRButton(num, THYMIO_TAP_IR, 0);
00222                         else if( name == "clap" )
00223                                 buttonIR = new ThymioIRButton(num, THYMIO_CLAP_IR, 0);
00224                         else if( name == "move" )
00225                                 buttonIR = new ThymioIRButton(num, THYMIO_MOVE_IR, 0);
00226                         else if( name == "color" )
00227                                 buttonIR = new ThymioIRButton(num, THYMIO_COLOR_IR, 0);
00228                         else if( name == "circle" )
00229                                 buttonIR = new ThymioIRButton(num, THYMIO_CIRCLE_IR, 3);
00230                         else if( name == "sound" )
00231                                 buttonIR = new ThymioIRButton(num, THYMIO_SOUND_IR, 2);
00232                         else if( name == "memory" )
00233                                 buttonIR = new ThymioIRButton(num, THYMIO_MEMORY_IR);
00234 
00235                         buttonIR->setBasename(name.toStdWString());
00236                 }
00237 
00238                 for(int i=0; i<num; ++i)
00239                         buttonIR->setClicked(i, isClicked(i));
00240 
00241                 if( !stateButtons.empty() )
00242                 {
00243                         int val=0;
00244                         for(int i=0; i<stateButtons.size(); ++i)
00245                                 val += (stateButtons[i]->isClicked()*(0x01<<i));
00246                         buttonIR->setMemoryState(val);
00247                 }
00248                 
00249                 return buttonIR;
00250         }
00251 
00252         void ThymioButton::updateIRButton()
00253         { 
00254                 if( buttonIR ) 
00255                 {
00256                         for(int i=0; i<getNumButtons(); ++i) 
00257                                 buttonIR->setClicked(i, isClicked(i));
00258 
00259                         buttonIR->setMemoryState(getState());           
00260                 
00261                         emit stateChanged();
00262                 }
00263         }
00264         
00265         void ThymioButton::paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget)
00266         {
00267                 Q_UNUSED(option);
00268                 Q_UNUSED(widget);
00269                 
00270                 painter->setPen(QColor(147, 134, 115));
00271                 painter->setBrush(buttonColor); // filling
00272                 painter->drawRoundedRect(0, 0, 256, 256, 5, 5);         
00273 
00274                 QGraphicsSvgItem::paint(painter, option, widget);
00275         }
00276         
00277         QPixmap ThymioButton::image(bool on)
00278         {
00279                 QPixmap pixmap(256+trans, 256);
00280                 pixmap.fill(Qt::transparent);
00281                 QPainter painter(&pixmap);
00282                 painter.setRenderHint(QPainter::Antialiasing);
00283                 painter.setBrush(buttonColor);
00284                 painter.drawRoundedRect(0,0,256,256,5,5);
00285 
00286                 int state[getNumButtons()];
00287                 if(on)
00288                         for(int i=0; i<getNumButtons(); ++i)
00289                         {
00290                                 state[i] = thymioButtons.at(i)->isClicked();
00291                                 thymioButtons.at(i)->setClicked(thymioButtons.at(i)->getNumStates()-1);
00292                         }
00293 
00294                 if(thymioBody != 0) 
00295                 {
00296                         painter.translate(thymioBody->pos());
00297                         painter.scale(thymioBody->scale(),thymioBody->scale());
00298                         painter.rotate(thymioBody->rotation());
00299                         thymioBody->paint(&painter, 0, 0);
00300                         painter.resetTransform();
00301                 }
00302 
00303                 for(QList<ThymioClickableButton*>::iterator itr = thymioButtons.begin();
00304                         itr != thymioButtons.end(); ++itr)
00305                 {                       
00306                         painter.translate((*itr)->pos());
00307                         painter.rotate((*itr)->rotation());
00308                         (*itr)->paint(&painter, 0, 0);
00309                         painter.resetTransform();
00310                 }
00311 
00312                 for(QList<ThymioClickableButton*>::iterator itr = stateButtons.begin();
00313                         itr != stateButtons.end(); ++itr)
00314                 {                       
00315                         painter.translate((*itr)->pos());
00316                         (*itr)->paint(&painter, 0, 0);
00317                         painter.resetTransform();
00318                 }
00319 
00320                 if(on)
00321                         for(int i=0; i<getNumButtons(); ++i)
00322                                 thymioButtons.at(i)->setClicked(state[i]);
00323                                 
00324                 if( renderer() ) 
00325                         renderer()->render(&painter, QRectF(0,0,256,256)); 
00326 
00327                 return pixmap;
00328         }
00329         
00330         bool ThymioButton::isValid()
00331         {
00332                 if( thymioButtons.isEmpty() )
00333                         return true;
00334 
00335                 for(QList<ThymioClickableButton*>::iterator itr = thymioButtons.begin();
00336                         itr != thymioButtons.end(); ++itr)
00337                         if( (*itr)->isClicked() > 0 )
00338                                 return true;
00339                                 
00340                 return false;
00341         }
00342 
00343         void ThymioButton::setAdvanced(bool advanced)
00344         {
00345                 trans = advanced ? 64 : 0;      
00346                 
00347                 if( advanced && stateButtons.empty() )
00348                 {
00349                         for(int i=0; i<4; i++)
00350                         {               
00351                                 ThymioClickableButton *button = new ThymioClickableButton(QRectF(-20,-20,40,40), THYMIO_CIRCULAR_BUTTON, 2, this);
00352                                 button->setPos(295, i*60 + 40);
00353                                 button->setButtonColor(QColor(255,200,0));
00354 
00355                                 stateButtons.push_back(button);
00356                                 connect(button, SIGNAL(stateChanged()), this, SLOT(updateIRButton()));
00357                         }
00358                         updateIRButton();
00359                 }       
00360                 else if( !advanced && !stateButtons.empty() )
00361                 {
00362                         for(int i=0; i<stateButtons.size(); i++)
00363                         {
00364                                 disconnect(stateButtons[i], SIGNAL(stateChanged()), this, SLOT(updateIRButton()));
00365                                 stateButtons[i]->setParentItem(0);
00366                                 delete(stateButtons[i]);
00367                         }
00368                         stateButtons.clear();
00369                 }
00370         }
00371 
00372         int ThymioButton::getState() const
00373         {
00374                 if( stateButtons.empty() )
00375                         return -1;
00376 
00377                 int val=0;
00378                 for(int i=0; i<stateButtons.size(); ++i)
00379                         val += (stateButtons[i]->isClicked()*(0x01<<i));
00380 
00381                 return val;
00382         }
00383         
00384         void ThymioButton::setState(int val)
00385         {       
00386                 if( val >= 0 )
00387                 {
00388                         setAdvanced(true);
00389                         
00390                         for(int i=0; i<4; ++i)
00391                                 stateButtons.at(i)->setClicked(val&(0x01<<i)? 1 : 0);                   
00392                 }
00393                 else
00394                         setAdvanced(false);
00395                 
00396         }
00397 
00398         void ThymioButton::mousePressEvent ( QGraphicsSceneMouseEvent * event )
00399         {
00400                 setCursor(Qt::ClosedHandCursor);
00401         }
00402 
00403         void ThymioButton::mouseReleaseEvent( QGraphicsSceneMouseEvent *event )
00404         {
00405                 setCursor(Qt::OpenHandCursor);
00406         }
00407 
00408         void ThymioButton::mouseMoveEvent( QGraphicsSceneMouseEvent *event )
00409         {
00410                 if (QLineF(event->screenPos(), event->buttonDownScreenPos(Qt::LeftButton)).length() < QApplication::startDragDistance()) 
00411                         return;
00412 
00413                 QByteArray buttonData;
00414                 QDataStream dataStream(&buttonData, QIODevice::WriteOnly);
00415                 dataStream << parentID << getName() << getNumButtons();
00416                 
00417                 for(int i=0; i<getNumButtons(); i++)
00418                         dataStream << isClicked(i);     
00419 
00420                 QMimeData *mime = new QMimeData;
00421                 mime->setData("thymiobutton", buttonData);
00422                 mime->setData("thymiotype", getType().toLatin1());
00423         
00424                 if( renderer() ) 
00425                 {
00426                         QByteArray rendererData;
00427                         QDataStream rendererStream(&rendererData, QIODevice::WriteOnly);
00428                         quint64 location  = (quint64)(renderer());
00429                         rendererStream << location;
00430                         mime->setData("thymiorenderer", rendererData);
00431                 }
00432                 
00433                 QDrag *drag = new QDrag(event->widget());
00434                 QPixmap img = image(false);             
00435                 drag->setMimeData(mime);
00436                 drag->setPixmap(img.scaled((256+trans)*scaleFactor, 256*scaleFactor));
00437                 drag->setHotSpot(QPoint((256+trans)*scaleFactor, 256*scaleFactor));
00438 
00439                 if (drag->exec(Qt::MoveAction | Qt::CopyAction , Qt::CopyAction) == Qt::MoveAction)
00440                         parentID = -1;
00441                 
00442                 setCursor(Qt::OpenHandCursor);
00443                 parentItem()->update();
00444         }
00445 
00446         // Button Set
00447         ThymioButtonSet::ThymioRemoveButton::ThymioRemoveButton(QGraphicsItem *parent) : 
00448                 QGraphicsItem(parent) 
00449         {               
00450                 setFlag(QGraphicsItem::ItemIsFocusable);
00451                 setFlag(QGraphicsItem::ItemIsSelectable);       
00452                 setData(0, "remove"); 
00453                 
00454                 setCursor(Qt::ArrowCursor);             
00455                 setAcceptedMouseButtons(Qt::LeftButton);
00456         }
00457                         
00458         void ThymioButtonSet::ThymioRemoveButton::paint (QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget)
00459         {
00460                 Q_UNUSED(option);
00461                 Q_UNUSED(widget);
00462 
00463                 qreal alpha = hasFocus() ? 255 : 150;
00464                                         
00465                 QLinearGradient linearGrad(QPointF(-64, -64), QPointF(64, 64));
00466                 linearGrad.setColorAt(0, QColor(209, 196, 180, alpha));
00467                 linearGrad.setColorAt(1, QColor(167, 151, 128, alpha));
00468      
00469                 painter->setPen(QColor(147, 134, 115));
00470                 painter->setBrush(linearGrad);
00471                 painter->drawRoundedRect(-64,-64,128,128,4,4);
00472                 
00473                 QRadialGradient radialGrad(QPointF(0, 0), 80);
00474                 radialGrad.setColorAt(0, Qt::red);
00475                 radialGrad.setColorAt(1, Qt::darkRed);          
00476 
00477                 painter->setPen(Qt::black);
00478                 painter->setBrush(radialGrad);
00479                 painter->drawRect(-40,-20,80,40);
00480         }
00481 
00482         ThymioButtonSet::ThymioAddButton::ThymioAddButton(QGraphicsItem *parent) : 
00483                 QGraphicsItem(parent) 
00484         {               
00485                 setFlag(QGraphicsItem::ItemIsFocusable);                
00486                 setFlag(QGraphicsItem::ItemIsSelectable);       
00487                 setData(0, "add"); 
00488 
00489                 setCursor(Qt::ArrowCursor);
00490                 setAcceptedMouseButtons(Qt::LeftButton);
00491         }
00492         
00493         void ThymioButtonSet::ThymioAddButton::paint (QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget)
00494         {
00495                 Q_UNUSED(option);
00496                 Q_UNUSED(widget);
00497                 
00498                 qreal alpha = hasFocus() ? 255 : 150;
00499                 
00500                 QLinearGradient linearGrad(QPointF(-32, -32), QPointF(32, 32));
00501                 linearGrad.setColorAt(0, QColor(209, 196, 180, alpha));
00502                 linearGrad.setColorAt(1, QColor(167, 151, 128, alpha));
00503      
00504                 painter->setPen(QColor(147, 134, 115));
00505                 painter->setBrush(linearGrad);
00506                 painter->drawEllipse(-32,-32,64,64);
00507                 
00508                 painter->setPen(QPen(QColor(147, 134, 115),5,Qt::SolidLine,Qt::RoundCap));
00509                 painter->drawLine(-16,0,16,0);
00510                 painter->drawLine(0,-16,0,16);
00511         }
00512 
00513         ThymioButtonSet::ThymioButtonSet(int row, bool advanced, QGraphicsItem *parent) : 
00514                 QGraphicsObject(parent),
00515                 eventButton(0),
00516                 actionButton(0),
00517                 buttonSetIR(),
00518                 eventButtonColor(QColor(0,191,255)),
00519                 actionButtonColor(QColor(218,112,214)),
00520                 highlightEventButton(false),
00521                 highlightActionButton(false),
00522                 errorFlag(false),
00523                 advancedMode(advanced),
00524                 trans(advanced ? 64 : 0),
00525                 xpos(advanced ? 5*scale() : 15*scale())
00526         { 
00527                 setData(0, "buttonset"); 
00528                 setData(1, row);
00529                 
00530                 deleteButton = new ThymioRemoveButton(this);
00531                 addButton = new ThymioAddButton(this);
00532                 
00533                 deleteButton->setPos(896+trans, 168);
00534                 addButton->setPos(500+trans/2, 368);
00535                 
00536                 setFlag(QGraphicsItem::ItemIsFocusable);
00537                 setFlag(QGraphicsItem::ItemIsSelectable);
00538                 setAcceptDrops(true);
00539                 setCursor(Qt::OpenHandCursor);
00540                 setAcceptedMouseButtons(Qt::LeftButton);
00541                 
00542                 setPos(xpos, (row*400+20)*scale());
00543         }
00544 
00545         void ThymioButtonSet::paint (QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget)
00546         {
00547                 Q_UNUSED(option);
00548                 Q_UNUSED(widget);
00549                 
00550                 qreal alpha = (errorFlag ? 255 : hasFocus() ? 150 : 50);
00551 
00552                 painter->setPen(Qt::NoPen);
00553                 painter->setBrush(QColor(255, 196, 180, alpha));                
00554                 painter->drawRoundedRect(0, 0, 1000+trans, 336, 5, 5);
00555 
00556                 painter->setBrush(QColor(167, 151, 128, alpha));
00557                 painter->drawRect(340 + trans, 143, 55, 55);
00558 
00559                 QPointF pts[3];
00560                 pts[0] = QPointF(394.5+trans, 118);
00561                 pts[1] = QPointF(394.5+trans, 218);
00562                 pts[2] = QPointF(446+trans, 168);
00563                 painter->drawPolygon(pts, 3);
00564 
00565                 painter->setPen(errorFlag ? Qt::black : Qt::gray);
00566                 painter->setFont(QFont("Arial", 30));
00567                 painter->drawText(QRect(800+trans, 20, 180, 40), Qt::AlignRight, QString("%0").arg(getRow()));
00568 
00569                 if( eventButton && eventButton->getParentID() < 0 ) 
00570                 {
00571                         disconnect(eventButton, SIGNAL(stateChanged()), this, SLOT(stateChanged()));
00572                         scene()->removeItem(eventButton);
00573                         delete(eventButton);
00574                         eventButton = 0;
00575                 
00576                         buttonSetIR.addEventButton(0);
00577                         emit buttonUpdated();
00578                 }
00579                 if( actionButton && actionButton->getParentID() < 0 )
00580                 {
00581                         disconnect(actionButton, SIGNAL(stateChanged()), this, SLOT(stateChanged()));
00582                         scene()->removeItem(actionButton);
00583                         delete(actionButton);
00584                         actionButton = 0;                       
00585 
00586                         buttonSetIR.addActionButton(0);
00587                         emit buttonUpdated();
00588                 }
00589                 
00590                 if( eventButton == 0 )
00591                 {
00592                         if( !highlightEventButton ) eventButtonColor.setAlpha(50);
00593                         painter->setPen(QPen(eventButtonColor, 10, Qt::DotLine, Qt::SquareCap, Qt::RoundJoin));                         
00594                         painter->setBrush(Qt::NoBrush);
00595                         painter->drawRoundedRect(45, 45, 246, 246, 5, 5);
00596                         eventButtonColor.setAlpha(255);
00597                 }
00598 
00599                 if( actionButton == 0 )
00600                 {
00601                         if( !highlightActionButton ) actionButtonColor.setAlpha(50);    
00602                         painter->setPen(QPen(actionButtonColor, 10,     Qt::DotLine, Qt::SquareCap, Qt::RoundJoin));
00603                         painter->setBrush(Qt::NoBrush);
00604                         painter->drawRoundedRect(505+trans, 45, 246, 246, 5, 5);
00605                         actionButtonColor.setAlpha(255);        
00606                 }
00607 
00608                 highlightEventButton = false;
00609                 highlightActionButton = false;
00610         }
00611 
00612         void ThymioButtonSet::setColorScheme(QColor eventColor, QColor actionColor)
00613         {
00614                 eventButtonColor = eventColor;
00615                 actionButtonColor = actionColor;
00616                 
00617                 if( eventButton )       eventButton->setButtonColor(eventColor);
00618                 if( actionButton )      actionButton->setButtonColor(actionColor);
00619         }
00620 
00621         void ThymioButtonSet::setRow(int row) 
00622         { 
00623                 setData(1,row); 
00624                 if( eventButton ) eventButton->setParentID(row);
00625                 if( actionButton ) actionButton->setParentID(row);
00626                 setPos(xpos, (row*400+20)*scale());     
00627         }
00628 
00629         void ThymioButtonSet::addEventButton(ThymioButton *event) 
00630         { 
00631                 if( eventButton ) 
00632                 {
00633                         disconnect(eventButton, SIGNAL(stateChanged()), this, SLOT(stateChanged()));
00634                         scene()->removeItem( eventButton );
00635                         delete( eventButton );
00636                 }
00637                 
00638                 event->setButtonColor(eventButtonColor);
00639                 event->setPos(40, 40);
00640                 event->setScaleFactor(scale());
00641                 event->setEnabled(true);
00642                 event->setParentItem(this);
00643                 event->setParentID(data(1).toInt());
00644                 eventButton = event;
00645                 
00646                 buttonSetIR.addEventButton(event->getIRButton());
00647                 emit buttonUpdated();
00648                 connect(eventButton, SIGNAL(stateChanged()), this, SLOT(stateChanged()));       
00649         }
00650 
00651         void ThymioButtonSet::addActionButton(ThymioButton *action) 
00652         { 
00653                 if( actionButton )
00654                 {
00655                         disconnect(actionButton, SIGNAL(stateChanged()), this, SLOT(stateChanged()));
00656                         scene()->removeItem( actionButton );
00657                         delete(actionButton);
00658                 }
00659                         
00660                 action->setButtonColor(actionButtonColor);
00661                 action->setPos(500+trans, 40);
00662                 action->setScaleFactor(scale());
00663                 action->setEnabled(true);
00664                 action->setParentItem(this);
00665                 action->setParentID(data(1).toInt());
00666                 actionButton = action;
00667                 
00668                 buttonSetIR.addActionButton(action->getIRButton());
00669                 emit buttonUpdated();
00670                 connect(actionButton, SIGNAL(stateChanged()), this, SLOT(stateChanged()));
00671         }
00672 
00673         void ThymioButtonSet::setScale(qreal factor)
00674         { 
00675                 QGraphicsItem::setScale(factor); 
00676                 xpos = (advancedMode ? 5*scale() : 15*scale());
00677                 setPos(xpos, (getRow()*400+20)*scale());
00678                 
00679                 if( eventButton ) 
00680                         eventButton->setScaleFactor(factor);
00681 
00682                 if( actionButton )
00683                         actionButton->setScaleFactor(factor);
00684         }
00685         
00686         void ThymioButtonSet::setAdvanced(bool advanced)
00687         {
00688                 advancedMode = advanced;
00689                 if( eventButton )
00690                         eventButton->setAdvanced(advanced);
00691                 
00692                 if( advanced ) 
00693                 {                       
00694                         trans = 64;
00695                         xpos = 5*scale();
00696                 } 
00697                 else
00698                 {
00699                         trans = 0;
00700                         xpos = 15*scale();
00701                 }
00702 
00703                 setPos(xpos, (getRow()*400+20)*scale());                
00704                 
00705                 deleteButton->setPos(896+trans, 168);
00706                 addButton->setPos(500+trans/2, 368);
00707                 
00708                 if( actionButton )
00709                         actionButton->setPos(500+trans, 40);
00710                 
00711                 update();
00712         }
00713 
00714         void ThymioButtonSet::stateChanged()
00715         {
00716                 emit buttonUpdated();
00717         }
00718         
00719         QPixmap ThymioButtonSet::image()
00720         {
00721                 QPixmap pixmap(advancedMode? 1064 : 1000, 336);
00722                 pixmap.fill();
00723                 QPainter painter(&pixmap);
00724                 painter.setRenderHint(QPainter::Antialiasing);  
00725                 
00726                 paint(&painter,0,0);
00727                 
00728                 painter.translate(deleteButton->pos());
00729                 deleteButton->paint(&painter, 0, 0);
00730                 painter.resetTransform();
00731                 
00732                 if( eventButton )
00733                         painter.drawImage(eventButton->pos(), (eventButton->image(false)).toImage());
00734 
00735                 if( actionButton )
00736                         painter.drawImage(actionButton->pos(), (actionButton->image(false)).toImage()); 
00737                         
00738                 return pixmap;
00739         }
00740                 
00741         void ThymioButtonSet::dragEnterEvent( QGraphicsSceneDragDropEvent *event )
00742         {
00743                 if ( event->mimeData()->hasFormat("thymiobuttonset") || 
00744                          event->mimeData()->hasFormat("thymiobutton") )
00745                 {
00746                         if( event->mimeData()->hasFormat("thymiotype") )
00747                         {
00748                                 if( event->mimeData()->data("thymiotype") == QString("event").toLatin1() )
00749                                         highlightEventButton = true;
00750                                 else if( event->mimeData()->data("thymiotype") == QString("action").toLatin1() )
00751                                         highlightActionButton = true;
00752                         }
00753 
00754                         event->setDropAction(Qt::MoveAction);
00755                         event->accept();
00756                         update();
00757                                         
00758                         scene()->setFocusItem(this);
00759                 }
00760                 else
00761                         event->ignore();
00762         }
00763 
00764         void ThymioButtonSet::dragMoveEvent( QGraphicsSceneDragDropEvent *event )
00765         {
00766                 if ( event->mimeData()->hasFormat("thymiobuttonset") ||
00767                          event->mimeData()->hasFormat("thymiobutton") )
00768                 {
00769                         if( event->mimeData()->hasFormat("thymiotype") )
00770                         {
00771                                 if( event->mimeData()->data("thymiotype") == QString("event").toLatin1() )
00772                                         highlightEventButton = true;
00773                                 else if( event->mimeData()->data("thymiotype") == QString("action").toLatin1() )
00774                                         highlightActionButton = true;
00775                         }
00776                         
00777                         event->setDropAction(Qt::MoveAction);
00778                         event->accept();
00779                         update();
00780                                         
00781                         scene()->setFocusItem(this);
00782                 }
00783                 else
00784                         event->ignore();
00785         }       
00786         
00787         void ThymioButtonSet::dragLeaveEvent(QGraphicsSceneDragDropEvent *event)
00788         {
00789                 if ( event->mimeData()->hasFormat("thymiobutton") || 
00790                          event->mimeData()->hasFormat("thymiobuttonset") )
00791                 {
00792                         event->setDropAction(Qt::MoveAction);
00793                         event->accept();
00794                         update();                                       
00795                 } 
00796                 else
00797                         event->ignore();                
00798         }
00799 
00800         void ThymioButtonSet::dropEvent(QGraphicsSceneDragDropEvent *event)
00801         {
00802                 scene()->setFocusItem(0);
00803         
00804                 if ( event->mimeData()->hasFormat("thymiobutton") )
00805                 {       
00806                         QByteArray buttonData = event->mimeData()->data("thymiobutton");
00807                         QDataStream dataStream(&buttonData, QIODevice::ReadOnly);
00808                         
00809                         int parentID;           
00810                         dataStream >> parentID;
00811                         
00812                         if( parentID != data(1).toInt() )
00813                         {
00814                                 QString buttonName;
00815                                 int numButtons;
00816                                 dataStream >> buttonName >> numButtons;
00817                                 
00818                                 ThymioButton *button = 0;
00819 
00820                                 if ( buttonName == "button" )
00821                                         button = new ThymioButtonsEvent(0,advancedMode);
00822                                 else if ( buttonName == "prox" )
00823                                         button = new ThymioProxEvent(0,advancedMode);
00824                                 else if ( buttonName == "proxground" )
00825                                         button = new ThymioProxGroundEvent(0,advancedMode);
00826                                 else if ( buttonName == "tap" )
00827                                 {                                       
00828                                         button = new ThymioTapEvent(0,advancedMode);
00829                                         QByteArray rendererData = event->mimeData()->data("thymiorenderer");
00830                                         QDataStream rendererStream(&rendererData, QIODevice::ReadOnly);
00831                                         quint64 location;
00832                                         rendererStream >> location;
00833                                         QSvgRenderer *tapSvg;
00834                                         tapSvg = (QSvgRenderer*)location;
00835                                         button->setSharedRenderer(tapSvg);
00836                                 }
00837                                 else if ( buttonName == "clap" )
00838                                 {
00839                                         button = new ThymioClapEvent(0,advancedMode);
00840                                         QByteArray rendererData = event->mimeData()->data("thymiorenderer");
00841                                         QDataStream rendererStream(&rendererData, QIODevice::ReadOnly);
00842                                         quint64 location;
00843                                         rendererStream >> location;
00844                                         QSvgRenderer *clapSvg;
00845                                         clapSvg = (QSvgRenderer*)location;
00846                                         button->setSharedRenderer(clapSvg);
00847                                 }
00848                                 else if ( buttonName == "move" )
00849                                         button = new ThymioMoveAction();
00850                                 else if ( buttonName == "color" )
00851                                         button = new ThymioColorAction();
00852                                 else if ( buttonName == "circle" )
00853                                         button = new ThymioCircleAction();
00854                                 else if ( buttonName == "sound" )                       
00855                                         button = new ThymioSoundAction();
00856                                 else if( buttonName == "memory" )
00857                                         button = new ThymioMemoryAction();
00858 
00859                                 if( button ) 
00860                                 {
00861                                         event->setDropAction(Qt::MoveAction);
00862                                         event->accept();
00863                                         
00864                                         if( event->mimeData()->data("thymiotype") == QString("event").toLatin1() )
00865                                         {
00866                                                 addEventButton(button);
00867                                                 highlightEventButton = false;
00868                                         }
00869                                         else if( event->mimeData()->data("thymiotype") == QString("action").toLatin1() )
00870                                         {
00871                                                 addActionButton(button);
00872                                                 highlightActionButton = false;
00873                                         }
00874                                         
00875                                         for( int i=0; i<numButtons; ++i ) 
00876                                         {
00877                                                 int status;
00878                                                 dataStream >> status;   
00879                                                 button->setClicked(i, status);
00880                                         }
00881                                 }
00882                         }
00883                         
00884                         update();
00885                 }
00886                 else
00887                         event->ignore();
00888         }
00889 
00890         void ThymioButtonSet::mousePressEvent( QGraphicsSceneMouseEvent * event )
00891         {
00892                 setCursor(Qt::ClosedHandCursor);
00893                 QGraphicsItem::mousePressEvent(event);
00894         }
00895 
00896         void ThymioButtonSet::mouseMoveEvent( QGraphicsSceneMouseEvent *event )
00897         {
00898                 if (QLineF(event->screenPos(), event->buttonDownScreenPos(Qt::LeftButton)).length() < QApplication::startDragDistance()) 
00899                         return;
00900 
00901                 QByteArray buttonData;
00902                 QDataStream dataStream(&buttonData, QIODevice::WriteOnly);
00903                 
00904                 dataStream << getRow();
00905 
00906                 QMimeData *mime = new QMimeData;
00907                 mime->setData("thymiobuttonset", buttonData);
00908                 
00909                 QDrag *drag = new QDrag(event->widget());               
00910                 QPixmap img = image();
00911                 drag->setMimeData(mime);
00912                 drag->setPixmap(img.scaled((1000+trans)*scale(), 336*scale()));
00913                 drag->setHotSpot(QPoint((500+trans*0.5)*scale(), 168*scale()));
00914 
00915                 drag->exec(Qt::MoveAction);
00916                 setCursor(Qt::OpenHandCursor);
00917         }
00918 
00919         void ThymioButtonSet::mouseReleaseEvent( QGraphicsSceneMouseEvent *event )
00920         {
00921                 setCursor(Qt::OpenHandCursor);
00922                 QGraphicsItem::mouseReleaseEvent(event);
00923         }
00924 
00925         // Thymio Push Button
00926         ThymioPushButton::ThymioPushButton(QString name, QSvgRenderer *renderer, QWidget *parent) : 
00927                 QPushButton(parent), 
00928                 thymioButton(0),
00929                 prevSpan(128)
00930         { 
00931                 if( name == "button" )
00932                         thymioButton = new ThymioButtonsEvent();
00933                 else if( name == "prox" )
00934                         thymioButton = new ThymioProxEvent();
00935                 else if( name == "proxground" )
00936                         thymioButton = new ThymioProxGroundEvent();
00937                 else if( name == "tap" )                
00938                         thymioButton = new ThymioTapEvent();
00939                 else if( name == "clap" )
00940                         thymioButton = new ThymioClapEvent();
00941                 else if( name == "move" )
00942                         thymioButton = new ThymioMoveAction();
00943                 else if( name == "color" )
00944                         thymioButton = new ThymioColorAction();
00945                 else if( name == "circle" )
00946                         thymioButton = new ThymioCircleAction();
00947                 else if( name == "sound" )
00948                         thymioButton = new ThymioSoundAction();
00949                 else if( name == "memory" )
00950                         thymioButton = new ThymioMemoryAction();
00951 
00952                 if( renderer )
00953                         thymioButton->setSharedRenderer(renderer);              
00954 
00955                 setIcon(thymioButton->image()); 
00956                 setToolTip(QString("%0 %1").arg(thymioButton->getName()).arg(thymioButton->getType()));
00957                 
00958                 setMaximumSize(256,256);
00959                 setIconSize(QSize(128,128));
00960                 setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
00961                 
00962                 setStyleSheet("QPushButton {border: none;}");
00963                 
00964                 setAcceptDrops(true);
00965         }
00966         
00967         ThymioPushButton::~ThymioPushButton()
00968         { 
00969                 if( thymioButton != 0 ) 
00970                         delete(thymioButton); 
00971         }       
00972         
00973         void ThymioPushButton::changeButtonColor(QColor color) 
00974         { 
00975                 thymioButton->setButtonColor(color); 
00976                 setIcon(thymioButton->image()); 
00977         }       
00978 
00979         void ThymioPushButton::mouseMoveEvent( QMouseEvent *event )
00980         {
00981                 if( thymioButton==0 )
00982                         return;
00983                         
00984                 QByteArray buttonData;
00985                 QDataStream dataStream(&buttonData, QIODevice::WriteOnly);
00986                 int numButtons = thymioButton->getNumButtons();
00987                 dataStream << -1 << thymioButton->getName() << numButtons;
00988                 
00989                 for(int i=0; i<numButtons; ++i)
00990                         dataStream << thymioButton->isClicked(i);                       
00991 
00992                 QMimeData *mime = new QMimeData;
00993                 mime->setData("thymiobutton", buttonData);
00994                 mime->setData("thymiotype", thymioButton->getType().toLatin1());
00995 
00996                 if( thymioButton->renderer() ) 
00997                 {
00998                         QByteArray rendererData;
00999                         QDataStream rendererStream(&rendererData, QIODevice::WriteOnly);
01000                         quint64 location  = (quint64)(thymioButton->renderer());
01001                         rendererStream << location;
01002                         mime->setData("thymiorenderer", rendererData);
01003                 }       
01004 
01005                 QDrag *drag = new QDrag(this);          
01006                 QPixmap img = thymioButton->image(false);               
01007                 drag->setMimeData(mime);
01008                 drag->setPixmap(img.scaled(iconSize()));
01009                 drag->setHotSpot(QPoint(iconSize().width(), iconSize().height()));
01010 
01011                 drag->exec();
01012         }
01013 
01014 
01015         void ThymioPushButton::dragEnterEvent( QDragEnterEvent *event )
01016         {
01017                 if( event->mimeData()->hasFormat("thymiotype") &&
01018                         event->mimeData()->data("thymiotype") == thymioButton->getType().toLatin1() )
01019                         event->accept();
01020                 else
01021                         event->ignore();
01022         }
01023 
01024         void ThymioPushButton::dropEvent( QDropEvent *event )
01025         {
01026                 if( event->mimeData()->hasFormat("thymiotype") &&
01027                         event->mimeData()->data("thymiotype") == thymioButton->getType().toLatin1() )
01028                 {
01029                         event->setDropAction(Qt::MoveAction);
01030                         event->accept();
01031                 }
01032                 else
01033                         event->ignore();
01034         }
01035 
01036 };
01037 


aseba
Author(s): Stéphane Magnenat
autogenerated on Thu Jan 2 2014 11:17:17