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
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));
00035
00036
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
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));
00119
00120
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
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
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);
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
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
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