$search
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