00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <QtGui/QLineEdit>
00015 #include <QtGui/QPushButton>
00016 #include <QtGui/QToolButton>
00017 #include <QtCore/QRegExp>
00018 #include <QtGui/QSplitter>
00019 #include <QtGui/QLabel>
00020 #include <QtGui/QMouseEvent>
00021 #include <QtGui/QKeyEvent>
00022 #include <QtGui/QHBoxLayout>
00023 #include <QtGui/QVBoxLayout>
00024 #include <QtGui/QPaintEvent>
00025 #include <QtGui/QPainter>
00026 #include <QtGui/QScrollArea>
00027 #include <QtGui/QSpacerItem>
00028 #include <QtGui/QSizePolicy>
00029 #include <QtGui/QTextCharFormat>
00030 #include <QtGui/QCompleter>
00031 #include <QtGui/QAbstractItemView>
00032 #include <QtGui/QStandardItemModel>
00033 #include <QtGui/QStringListModel>
00034 #include <QtGui/QFileDialog>
00035 #include <QtGui/QDialogButtonBox>
00036 #include <QtGui/QScrollBar>
00037 #include <QtGui/QToolTip>
00038 #include <QtGui/QListWidget>
00039 #include <QtGui/QTreeView>
00040
00041 #include "SeExprEdControl.h"
00042 #include "SeExprEdColorCurve.h"
00043 #include "SeExprEdFileDialog.h"
00044 #include "SeExprEdEditable.h"
00045 #ifdef SEEXPR_USE_ANIMLIB
00046 # include <animlib/AnimCurve.h>
00047 # include <animlib/AnimKeyframe.h>
00048 #endif
00049
00050
00051 static const char *refreshXPM[]={
00052 "20 20 4 1",
00053 "# c #303030",
00054 "a c #585858",
00055 "b c #c3c3c3",
00056 ". c #dcdcdc",
00057 "....................",
00058 "....................",
00059 "....................",
00060 ".......#aaaa#.......",
00061 ".....#########......",
00062 "....###bbbbb###.....",
00063 "....##b.....b##.....",
00064 "...bb#b.....b##.....",
00065 "...bbbb....aaaaaa...",
00066 "...........aaaaaa...",
00067 "....##......####....",
00068 "...####......##.....",
00069 "..######............",
00070 "..aaa#aa............",
00071 "....##......bbb.....",
00072 "....##b...bbbab.....",
00073 "....a#abbbb##ab.....",
00074 ".....#a####aa#b.....",
00075 ".....aaaaaaa#.b.....",
00076 "...................."};
00077
00078
00079 static const char *graphXPM[]={
00080 "20 20 5 1",
00081 "c c #000040",
00082 "a c #303030",
00083 "# c #58a8ff",
00084 ". c #dcdcdc",
00085 "b c #ff0000",
00086 "..........#a.a......",
00087 "..........#a.a.....b",
00088 "..........#.a.....bb",
00089 "..........#aa....bb.",
00090 "..........#.....bb..",
00091 "..........#....bb...",
00092 "..........#....bb...",
00093 "....bbb...#...bb....",
00094 "...bbbbb..#..bbb....",
00095 "...b...bbb#.bbb.....",
00096 "..bb....bb#bbb......",
00097 "##bb####bbbbb#######",
00098 ".bb......bbb....c.c.",
00099 ".bb.......#......c..",
00100 ".b........#.....c.c.",
00101 "bb........#.........",
00102 "b.........#.........",
00103 "..........#.........",
00104 "..........#.........",
00105 "..........#........."};
00106
00107
00108
00109 static const char *directoryXPM[]={
00110 "20 20 3 1",
00111 ". c None",
00112 "# c #000000",
00113 "a c #d8c59e",
00114 "....................",
00115 "....................",
00116 "....................",
00117 "....................",
00118 "...........#######..",
00119 "...........#aaaaa#..",
00120 "..##########aaaaa#..",
00121 "..#aaaaaaaaaaaaaa#..",
00122 "..#aaaaaaaaaaaaaa#..",
00123 "..#aaaaaaaaaaaaaa#..",
00124 "..#aaaaaaaaaaaaaa#..",
00125 "..#aaaaaaaaaaaaaa#..",
00126 "..#aaaaa##a##a##a#..",
00127 "..#aaaaa##a##a##a#..",
00128 "..#aaaaaaaaaaaaaa#..",
00129 "..################..",
00130 "....................",
00131 "....................",
00132 "....................",
00133 "...................."};
00134
00135
00136 static const char *fileXPM[]={
00137 "20 20 5 1",
00138 ". c None",
00139 "# c #000000",
00140 "c c #303030",
00141 "b c #a79b80",
00142 "a c #ddcdaa",
00143 "....................",
00144 "....................",
00145 "....#########.......",
00146 "....#aaaaaaa##......",
00147 "....#aaaaaaa#b#.....",
00148 "....#aaaaaaa#bb#....",
00149 "....#aaaaaaa####....",
00150 "....#aaaaaaaaaa#....",
00151 "....#aaaaaaaaaa#....",
00152 "....#aaaaaaaaaa#....",
00153 "....#aaaaaaaaaa#....",
00154 "....#aaaaaaaaaa#....",
00155 "....#aaaaaaaaaa#....",
00156 "....#aaaaaaaaaa#....",
00157 "....#aaaaaaaaaa#....",
00158 "....#accaccacca#....",
00159 "....#accaccacca#....",
00160 "....#aaaaaaaaaa#....",
00161 "....############....",
00162 "...................."};
00163
00164
00165
00166 void SeExprEdSlider::mousePressEvent(QMouseEvent* e)
00167 {
00168 mouseMoveEvent(e);
00169 }
00170
00171 void SeExprEdSlider::mouseMoveEvent(QMouseEvent* e)
00172 {
00173 float r = maximum()-minimum();
00174 float v = ((float)(e->x()-2)*r/(width()-5))+minimum()+.5f;
00175 int iv = std::min(std::max((int)v,minimum()),maximum());
00176 setValue(iv);
00177 }
00178
00179 void SeExprEdSlider::paintEvent(QPaintEvent* e)
00180 {
00181 Q_UNUSED(e);
00182 QPainter p(this);
00183
00184 float v = value();
00185 float r = maximum()-minimum();
00186 int linepos = (int)((v-minimum())/r*(width()-5)+2);
00187
00188 QColor qcol = palette().color(QPalette::Dark);
00189 QColor bcol = palette().color(QPalette::Midlight);
00190 QColor dcol = bcol.lighter(140);
00191 QColor bgcol = palette().color(QPalette::Base);
00192
00193 if (underMouse())
00194 {
00195 bcol = bcol.lighter(110);
00196 bgcol = bgcol.lighter(110);
00197 int mx = mapFromGlobal(QCursor::pos()).x();
00198 if (abs(linepos-mx)<4) dcol = dcol.lighter(200);
00199 }
00200
00201 p.fillRect(1,1,width()-1,height()-2,bgcol);
00202 p.fillRect(1,1,linepos-1,height()-2,bcol);
00203
00204 QPen pen = p.pen();
00205
00206 pen.setColor(dcol);
00207 p.setPen(pen);
00208 pen.setWidth(3);
00209 p.setPen(pen);
00210 p.drawLine(linepos,2,linepos,height()-2);
00211 pen.setWidth(1);
00212 pen.setColor(qcol);
00213 p.setPen(pen);
00214 p.drawLine(linepos-2,1,linepos-2,height()-1);
00215 p.drawLine(linepos+2,1,linepos+2,height()-1);
00216
00217 pen.setWidth(1);
00218 pen.setColor(qcol);
00219 p.setPen(pen);
00220 p.drawRect(0,0,width()-1,height()-1);
00221 }
00222
00223 SeExprEdChannelSlider::SeExprEdChannelSlider(int id, QWidget* parent)
00224 : QWidget(parent), _id(id), _value(0)
00225 {
00226 }
00227
00228 void SeExprEdChannelSlider::paintEvent(QPaintEvent* e)
00229 {
00230 Q_UNUSED(e);
00231 if (_value < 0 || _value > 1) return;
00232 int x = int(_value * (width()-3) + 0.5);
00233 QPainter p(this);
00234 p.fillRect(contentsRect(), _col);
00235 p.fillRect(x, 0, 3, height(), QColor(64,64,64));
00236 }
00237
00238 void SeExprEdChannelSlider::mousePressEvent(QMouseEvent* e)
00239 {
00240 mouseMoveEvent(e);
00241 }
00242
00243
00244 void SeExprEdChannelSlider::mouseMoveEvent(QMouseEvent* e)
00245 {
00246 setValue(clamp(float(e->x()-1) / (width()-3), 0, 1));
00247 }
00248
00249
00250 void SeExprEdChannelSlider::setValue(float value)
00251 {
00252 if (value == _value) return;
00253 _value = value;
00254 emit valueChanged(_id, value);
00255 update();
00256 }
00257
00258
00259 SeExprEdControl::SeExprEdControl(int id,SeExprEdEditable* editable,bool showColorLink)
00260 :_id(id),_updating(false),_editable(editable)
00261 {
00262 hbox=new QHBoxLayout(this);
00263 hbox->setSpacing(2);
00264 hbox->setMargin(0);
00265
00266 _colorLinkCB=new QCheckBox(this);
00267 _colorLinkCB->setFixedWidth(14);
00268 _colorLinkCB->setFocusPolicy(Qt::NoFocus);
00269 connect(_colorLinkCB,SIGNAL(stateChanged(int)),this,SLOT(linkStateChange(int)));
00270 hbox->addWidget(_colorLinkCB);
00271
00272 _label = new QLabel(QString("<b>")+editable->name.c_str()+"</b>");
00273 _label->setFixedWidth(72);
00274 _label->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
00275 _label->setIndent(2);
00276 _label->setAutoFillBackground(true);
00277 hbox->addWidget(_label);
00278
00279 if(!showColorLink){
00280 _colorLinkCB->setHidden(true);
00281 _label->setFixedWidth(84);
00282 }else{
00283 _colorLinkCB->setHidden(false);
00284 _label->setFixedWidth(84-_colorLinkCB->width()+2);
00285 }
00286
00287 }
00288
00289 void SeExprEdControl::linkStateChange(int state)
00290 {
00291 if(_updating) return;
00292
00293 if(state==Qt::Checked){
00294 emit linkColorLink(_id);
00295 emit linkColorEdited(_id,getColor());
00296 }else{
00297 emit linkColorLink(-1);
00298 }
00299 }
00300
00301 void SeExprEdControl::linkDisconnect(int newId)
00302 {
00303 if(newId!=_id){
00304 _updating = 1;
00305 _colorLinkCB->setChecked(false);
00306 _updating = 0;
00307 }
00308 }
00309
00310
00311
00312
00313 SeExprEdNumberControl::SeExprEdNumberControl(int id,SeExprEdNumberEditable* editable)
00314 :SeExprEdControl(id,editable,false),_numberEditable(editable)
00315 {
00316
00317
00318 float smin = editable->min, smax = editable->max;
00319 if(!_numberEditable->isInt) { smin *= 1e5; smax *= 1e5; }
00320 float srange = smax-smin;
00321 _slider = new SeExprEdSlider(Qt::Horizontal,this);
00322 _slider->setRange(int(smin),int(smax));
00323 _slider->setTickInterval(std::max(1,int(srange/10)));
00324 _slider->setSingleStep(std::max(1,int(srange/50)));
00325 _slider->setPageStep(std::max(1,int(srange/10)));
00326 _slider->setMinimumWidth(0);
00327 _slider->setFixedHeight(16);
00328 _slider->setFocusPolicy(Qt::ClickFocus);
00329 hbox->addWidget(_slider, 3);
00330
00331 _edit = new SeExprEdLineEdit(0,this);
00332 _edit->setMinimumWidth(0);
00333 _edit->setFixedHeight(16);
00334 hbox->addWidget(_edit);
00335 connect(_edit,SIGNAL(textChanged(int,const QString&)),SLOT(editChanged(int,const QString&)));
00336 connect(_slider, SIGNAL(valueChanged(int)), SLOT(sliderChanged(int)));
00337
00338 updateControl();
00339 }
00340
00341 void SeExprEdNumberControl::sliderChanged(int value)
00342 {
00343 if (_updating) return;
00344 setValue(_numberEditable->isInt ? value : value*1e-5);
00345
00346 }
00347
00348 void SeExprEdNumberControl::editChanged(int id,const QString& text)
00349 {
00350 Q_UNUSED(id);
00351 if (_updating) return;
00352 bool ok = 0;
00353 float val = text.toFloat(&ok);
00354 if (!ok) return;
00355 setValue(val);
00356 }
00357
00358 void SeExprEdNumberControl::updateControl()
00359 {
00360 _updating = 1;
00361 int sliderval = int(_numberEditable->isInt ? _numberEditable->v : _numberEditable->v*1e5);
00362 if (sliderval != _slider->value()) _slider->setValue(sliderval);
00363 _edit->setText(QString("%1")
00364 .arg(_numberEditable->v, 0, 'f', _numberEditable->isInt ? 0 : 3));
00365 _updating=0;
00366 }
00367
00368 void SeExprEdNumberControl::setValue(float value)
00369 {
00370
00371 if (fabs(_numberEditable->v-value) < 1e-5) return;
00372 _numberEditable->v=value;
00373 updateControl();
00374 emit controlChanged(_id);
00375 }
00376
00377 SeExprEdVectorControl::SeExprEdVectorControl(int id,SeExprEdVectorEditable* editable)
00378 :SeExprEdControl(id,editable,true),_numberEditable(editable)
00379 {
00380
00381 if(_numberEditable->isColor){
00382 _swatch=new SeExprEdCSwatchFrame(editable->v);
00383 _swatch->setFixedWidth(38);
00384 _swatch->setFixedHeight(20);
00385 connect(_swatch,SIGNAL(swatchChanged(QColor)),this,SLOT(swatchChanged(QColor)));
00386 hbox->addWidget(_swatch);
00387 }
00388 for(int i=0;i<3;i++){
00389 QVBoxLayout* vbl=new QVBoxLayout();
00390 hbox->addLayout(vbl);
00391 vbl->setMargin(0);
00392 vbl->setSpacing(0);
00393
00394 SeExprEdLineEdit* edit = new SeExprEdLineEdit(i, this);
00395 vbl->addWidget(edit);
00396 _edits[i]=edit;
00397 edit->setMinimumWidth(0);
00398 edit->setFixedHeight(16);
00399
00400 SeExprEdChannelSlider* slider = new SeExprEdChannelSlider(i, this);
00401 vbl->addWidget(slider);
00402 _sliders[i]=slider;
00403 slider->setFixedHeight(6);
00404
00405 static const QColor rgb[3] = { QColor(128,64,64), QColor(64,128,64), QColor(64,64,128) };
00406 if(_numberEditable->isColor) slider->setDisplayColor(rgb[i]);
00407
00408 connect(edit,SIGNAL(textChanged(int,const QString&)),SLOT(editChanged(int,const QString&)));
00409 connect(slider, SIGNAL(valueChanged(int,float)), SLOT(sliderChanged(int,float)));
00410
00411 }
00412
00413 updateControl();
00414 }
00415
00416 void SeExprEdVectorControl::swatchChanged(QColor gah)
00417 {
00418 Q_UNUSED(gah);
00419 SeVec3d color=_swatch->getValue();
00420 setValue(0,color[0]);
00421 setValue(1,color[1]);
00422 setValue(2,color[2]);
00423 }
00424
00425 QColor SeExprEdVectorControl::getColor()
00426 {
00427 return QColor::fromRgbF(clamp(_numberEditable->v[0],0,1),
00428 clamp(_numberEditable->v[1],0,1),
00429 clamp(_numberEditable->v[2],0,1));
00430 }
00431
00432 void SeExprEdVectorControl::setColor(QColor color)
00433 {
00434 setValue(0,color.redF());
00435 setValue(1,color.greenF());
00436 setValue(2,color.blueF());
00437 }
00438
00439 void SeExprEdVectorControl::sliderChanged(int id,float value)
00440 {
00441 if (_updating) return;
00442 setValue(id,_numberEditable->min + value * (_numberEditable->max-_numberEditable->min));
00443 if (_numberEditable->isColor) emit linkColorEdited(_id,getColor());
00444 }
00445
00446 void SeExprEdVectorControl::editChanged(int id,const QString& text)
00447 {
00448 if (_updating) return;
00449 bool ok = 0;
00450 float val = text.toFloat(&ok);
00451 if (!ok) return;
00452 setValue(id,val);
00453 }
00454
00455 void SeExprEdVectorControl::updateControl()
00456 {
00457
00458 _updating = 1;
00459 for (unsigned int i = 0; i < 3; i++)
00460 _edits[i]->setText(QString("%1")
00461 .arg(_numberEditable->v[i], 0, 'f', 3));
00462 double min=_numberEditable->min,max=_numberEditable->max;
00463 for (unsigned int i = 0; i < 3; i++){
00464 _sliders[i]->setValue((_numberEditable->v[i]-min)/(max-min));
00465 }
00466 if(_numberEditable->isColor){
00467
00468 SeVec3d val=_numberEditable->v;
00469 float r = clamp(val[0],0,1);
00470 float g = clamp(val[1],0,1);
00471 float b = clamp(val[2],0,1);
00472 float lum = r*.2+g*.7+b*.1;
00473
00474 QPalette pal = palette();
00475 pal.setColor(QPalette::Window,QColor(int(r*255),int(g*255),int(b*255)));
00476 pal.setColor(QPalette::WindowText,(lum<0.5) ? QColor(255,255,255) : QColor(0,0,0));
00477 _label->setPalette(pal);
00478
00479 }
00480 _updating = 0;
00481 }
00482
00483 void SeExprEdVectorControl::setValue(int n,float value)
00484 {
00485 if (n < 0 || n >= 3) return;
00486 if (fabs(_numberEditable->v[n]-value) < 1e-5) return;
00487 _numberEditable->v[n] = value;
00488 if(_swatch) _swatch->setValue(_numberEditable->v);
00489 updateControl();
00490 emit controlChanged(_id);
00491 }
00492
00493 SeExprEdStringControl::SeExprEdStringControl(int id,SeExprEdStringEditable* editable)
00494 :SeExprEdControl(id,editable,false),_stringEditable(editable)
00495 {
00496
00497 _edit=new QLineEdit();
00498 _edit->setFixedHeight(20);
00499 connect(_edit,SIGNAL(textChanged(const QString&)),SLOT(textChanged(const QString&)));
00500
00501 if(_stringEditable->type=="file" || _stringEditable->type=="directory"){
00502 QPushButton* button=new QPushButton();
00503 button->setFixedSize(20,20);
00504
00505 hbox->addWidget(_edit,3);
00506 hbox->addWidget(button,1);
00507 if(_stringEditable->type=="directory"){
00508 connect(button,SIGNAL(clicked()),SLOT(directoryBrowse()));
00509 button->setIcon(QIcon(QPixmap(directoryXPM)));
00510 } else if(_stringEditable->type=="file"){
00511 connect(button,SIGNAL(clicked()),SLOT(fileBrowse()));
00512 button->setIcon(QIcon(QPixmap(fileXPM)));
00513 }
00514
00515 }else{
00516 hbox->addWidget(_edit,3);
00517 }
00518
00519 updateControl();
00520 }
00521
00522 void SeExprEdStringControl::fileBrowse()
00523 {
00524 SeExprEdFileDialog dialog(this);
00525 dialog.setPreview();
00526 QString newFilename=dialog.getOpenFileName("Please choose a file",_edit->text(),tr("Images (*.tif *.tx *.jpg *.ptx *.png)"));
00527 if(newFilename!="") _edit->setText(newFilename);
00528 }
00529
00530 void SeExprEdStringControl::directoryBrowse()
00531 {
00532 SeExprEdFileDialog dialog(this);
00533 dialog.setPreview();
00534 QString newFilename=dialog.getExistingDirectory("Please choose a file",_edit->text());
00535 if(newFilename!="") _edit->setText(newFilename);
00536 }
00537
00538 void SeExprEdStringControl::updateControl()
00539 {
00540 _edit->setText(_stringEditable->v.c_str());
00541 }
00542
00543 void SeExprEdStringControl::textChanged(const QString& newText)
00544 {
00545 if(_updating) return;
00546 _stringEditable->v=newText.toStdString();
00547 emit controlChanged(_id);
00548 }
00549
00550 SeExprEdCurveControl::SeExprEdCurveControl(int id,SeExprEdCurveEditable* editable)
00551 :SeExprEdControl(id,editable,false),_curveEditable(editable)
00552 {
00553 _curve = new SeExprEdCurve(this, "Pos:", "Val:", "Interp:");
00554 _curve->setFixedHeight(80);
00555
00556 const int numVal = _curveEditable->cvs.size();
00557 for (int i = 0; i < numVal; i++) {
00558 const SeExpr::SeCurve<double>::CV& cv=_curveEditable->cvs[i];
00559 _curve->addPoint(cv._pos,cv._val,cv._interp);
00560 }
00561 hbox->addWidget(_curve, 3);
00562 connect(_curve->_scene, SIGNAL(curveChanged()), SLOT(curveChanged()));
00563
00564 }
00565
00566 void SeExprEdCurveControl::curveChanged()
00567 {
00568 if(_curve && _curveEditable){
00569 _curveEditable->cvs=_curve->_scene->_cvs;
00570 emit controlChanged(_id);
00571 }
00572 }
00573
00574 SeExprEdCCurveControl::SeExprEdCCurveControl(int id,SeExprEdColorCurveEditable* editable)
00575 :SeExprEdControl(id,editable,true),_curveEditable(editable)
00576 {
00577 _curve = new SeExprEdColorCurve(this, "Pos:", "Val:", "Interp:");
00578 _curve->setFixedHeight(80);
00579
00580 const int numVal = _curveEditable->cvs.size();
00581 for (int i = 0; i < numVal; i++) {
00582 const SeExpr::SeCurve<SeVec3d>::CV& cv=_curveEditable->cvs[i];
00583 _curve->addPoint(cv._pos,cv._val,cv._interp);
00584 }
00585 hbox->addWidget(_curve, 3);
00586 connect(_curve->_scene, SIGNAL(curveChanged()), SLOT(curveChanged()));
00587
00588 }
00589
00590 void SeExprEdCCurveControl::curveChanged()
00591 {
00592 if(_curve && _curveEditable){
00593 _curveEditable->cvs=_curve->_scene->_cvs;
00594 emit controlChanged(_id);
00595
00596 }
00597 }
00598
00599
00600 QColor SeExprEdCCurveControl::getColor()
00601 {
00602 return _curve->getSwatchColor();
00603 }
00604
00605 void SeExprEdCCurveControl::setColor(QColor color)
00606 {
00607 _curve->setSwatchColor(color);
00608 }
00609
00610 struct SeExprEdGraphPreview:public QWidget
00611 {
00612 std::vector<float> x,y;
00613 std::vector<float> cpx,cpy;
00614 float xmin,xmax,ymin,ymax,dx,dy;;
00615 float win_xmin,win_xmax,win_ymin,win_ymax,win_dx,win_dy;;
00616 SeExprEdGraphPreview(QWidget* parent=0)
00617 :QWidget(parent)
00618 {
00619 win_xmin=-1.;
00620 win_xmax=2.;
00621 win_ymin=-1;
00622 win_ymax=2.;
00623 }
00624
00625 QPointF toScreen(float x,float y){
00626 return QPointF((x-win_xmin)*win_dx,height()-(y-win_ymin)*win_dy);
00627 }
00628
00629
00630 void paintEvent(QPaintEvent* event){
00631 QWidget::paintEvent(event);
00632 QPainter painter(this);
00633 painter.setRenderHint(QPainter::Antialiasing,true);
00634 painter.setPen(QColor(255,255,255));
00635 win_xmin=xmin;win_xmax=xmax;
00636 win_ymin=ymin;win_ymax=ymax;
00637 float percentXpad=.1*(win_xmax-win_xmin);
00638 float percentYpad=.1*(win_ymax-win_ymin);
00639 win_xmin-=percentXpad;
00640 win_xmax+=percentXpad;
00641 win_ymin-=percentYpad;
00642 win_ymax+=percentYpad;
00643
00644
00645 int x_pad_in_pixels=25,y_pad_in_pixels=15;
00646 float xpad=x_pad_in_pixels*(win_xmax-win_xmin)/(width()-x_pad_in_pixels);
00647 float ypad=y_pad_in_pixels*(win_ymax-win_ymin)/(height()-y_pad_in_pixels);
00648 win_ymin-=ypad;
00649 win_xmax+=xpad;
00650
00651 win_dx=width()/(win_xmax-win_xmin);
00652 win_dy=height()/(win_ymax-win_ymin);
00653
00654
00655 QPainterPath path;
00656 QRectF fullarea(toScreen(win_xmin,win_ymax),toScreen(win_xmax,win_ymin));
00657 QBrush darkbrush(QColor(100,100,100),Qt::SolidPattern);
00658 QRectF area(toScreen(xmin,ymax),toScreen(xmax,ymin));
00659 QBrush brush(QColor(150,150,150),Qt::SolidPattern);
00660
00661
00662
00663
00664 painter.fillRect(area,brush);
00665 if(x.size()>0){
00666 path.moveTo(toScreen(x[0],y[0]));
00667 for(int i=1;i<(int)x.size();i++)
00668 path.lineTo(toScreen(x[i],y[i]));
00669
00670 }
00671 QRectF right(toScreen(xmax,ymax),toScreen(win_xmax,ymin));
00672 QRectF bottom(toScreen(xmin,ymin),toScreen(xmax,win_ymin));
00673
00674 painter.setPen(QColor(75,50,50));
00675 painter.drawPath(path);
00676
00677 painter.setPen(QPen());
00678 painter.drawText(right,Qt::AlignTop|Qt::AlignLeft,QString("%1").arg(ymax,0,'f',1));
00679 painter.drawText(right,Qt::AlignBottom|Qt::AlignLeft,QString("%1").arg(ymin,0,'f',1));
00680 painter.drawText(bottom,Qt::AlignTop|Qt::AlignLeft,QString("%1").arg(xmin,0,'f',1));
00681 painter.drawText(bottom,Qt::AlignTop|Qt::AlignRight,QString("%1").arg(xmax,0,'f',1));
00682
00683 painter.setBrush(QBrush(QColor(0,0,0),Qt::SolidPattern));
00684 for(size_t i=0;i<cpx.size();i++){
00685 painter.drawEllipse(toScreen(cpx[i],cpy[i]),2,2);
00686 }
00687 }
00688
00689 #ifdef SEEXPR_USE_ANIMLIB
00690 void sample(const animlib::AnimCurve& curve){
00691 int numKeys=curve.getNumKeys();
00692 x.clear();y.clear();
00693 cpx.clear();cpy.clear();
00694 if(numKeys>0){
00695 const animlib::AnimKeyframe* key=&*curve.getFirstKey();
00696 xmin=key[0].getTime();
00697 xmax=key[numKeys-1].getTime();
00698 ymin=FLT_MAX;
00699 ymax=-FLT_MAX;
00700
00701 for(int i=0;i<numKeys;i++){
00702 cpx.push_back(key[i].getTime());
00703 cpy.push_back(key[i].getValue());
00704 }
00705
00706 int nsamples=100;
00707 float dx=(xmax-xmin)/nsamples;
00708 float xeval=xmin;
00709 for(int i=0;i<nsamples;i++){
00710 x.push_back(xeval);
00711 float yeval=curve.getValue(xeval);
00712 ymin=std::min(ymin,yeval);
00713 ymax=std::max(ymax,yeval);
00714 y.push_back(yeval);
00715 xeval+=dx;
00716 }
00717
00718
00719 }else{
00720 xmin=-1;
00721 xmax=1;
00722 ymin=-1;
00723 ymax=1;
00724 }
00725
00726 }
00727 #endif
00728 };
00729
00730 SeExprEdAnimCurveControl::SeExprEdAnimCurveControl(int id,SeExprEdAnimCurveEditable* editable)
00731 :SeExprEdControl(id,editable,false),_editable(editable)
00732 {
00733
00734 _preview=new SeExprEdGraphPreview();
00735 _preview->setMinimumWidth(200);
00736 _preview->setMinimumHeight(60);
00737 hbox->addWidget(_preview);
00738
00739
00740 Q_UNUSED(graphXPM)
00741 QPushButton* refreshButton=new QPushButton();
00742 refreshButton->setMaximumWidth(30);
00743 refreshButton->setIcon(QIcon(QPixmap(refreshXPM)));
00744 QPushButton* expandButton=new QPushButton(">");
00745 expandButton->setSizePolicy(QSizePolicy::Fixed,QSizePolicy::Expanding);
00746 expandButton->setFixedWidth(15);
00747 hbox->addWidget(expandButton);
00748
00749 refreshButton->setVisible(_editable->link!="");
00750 hbox->addWidget(refreshButton);
00751
00752 #ifdef SEEXPR_USE_ANIMLIB
00753 _preview->sample(editable->curve);
00754 #endif
00755 connect(expandButton,SIGNAL(clicked()),this,SLOT(editGraphClicked()));
00756
00757 connect(refreshButton,SIGNAL(clicked()),this,SLOT(refreshClicked()));
00758 }
00759
00760 #ifdef SEEXPR_USE_ANIMLIB
00761 #include <CE/CETool.h>
00762 #endif
00763
00764 void SeExprEdAnimCurveControl::refreshClicked()
00765 {
00766 if(callback){
00767 #ifdef SEEXPR_USE_ANIMLIB
00768 callback(_editable->link,_editable->curve);
00769 _preview->sample(_editable->curve);
00770 _preview->repaint();
00771 emit controlChanged(_id);
00772 #endif
00773 }
00774 }
00775
00776 void SeExprEdAnimCurveControl::editGraphClicked(){
00777 #ifdef SEEXPR_USE_ANIMLIB
00778 QDialog* dialog=new QDialog(this);
00779 CETool* tool=new CETool;
00780 animlib::AnimAttrID attr1("","");
00781 animlib::AnimCurve& anim=*new animlib::AnimCurve(attr1);
00782 anim=_editable->curve;
00783
00784 QWidget *widg;
00785 tool->map(widg,0);
00786 QVBoxLayout* layout=new QVBoxLayout();
00787 dialog->resize(QSize(1024,640));
00788 dialog->setLayout(layout);
00789 layout->addWidget(widg);
00790 tool->addCurve(&anim);
00791
00792 QDialogButtonBox* buttonbar=new QDialogButtonBox();
00793 buttonbar->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
00794 connect(buttonbar,SIGNAL(accepted()),dialog,SLOT(accept()));
00795 connect(buttonbar,SIGNAL(rejected()),dialog,SLOT(reject()));
00796 layout->addWidget(buttonbar);
00797
00798 if(dialog->exec()==QDialog::Accepted){
00799
00800 _editable->curve=anim;
00801 _preview->sample(_editable->curve);
00802 _preview->repaint();
00803 emit controlChanged(_id);
00804 }
00805 #endif
00806 }
00807
00808 void SeExprEdAnimCurveControl::setAnimCurveCallback(AnimCurveCallback newCallback)
00809 {
00810 callback=newCallback;
00811 }
00812
00813 SeExprEdAnimCurveControl::AnimCurveCallback SeExprEdAnimCurveControl::callback=0;
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825