00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <GenGraphForm.h>
00029 #include "RealGUI.h"
00030 #include "iconnode.xpm"
00031 #include "iconwarning.xpm"
00032 #include <sofa/simulation/common/Colors.h>
00033
00034
00035 #ifdef SOFA_QT4
00036 #include <Q3PopupMenu>
00037 #else
00038 #include <qpopupmenu.h>
00039 #endif
00040
00041 namespace sofa
00042 {
00043
00044 namespace gui
00045 {
00046
00047 namespace qt
00048 {
00049 #ifdef SOFA_QT4
00050 typedef Q3PopupMenu QPopupMenu;
00051 #else
00052 typedef QPopupMenu Q3PopupMenu;
00053 #endif
00054
00055
00056
00057 static const int iconWidth=8;
00058 static const int iconHeight=10;
00059 static const int iconMargin=6;
00060
00061 static int hexval(char c)
00062 {
00063 if (c>='0' && c<='9') return c-'0';
00064 else if (c>='a' && c<='f') return (c-'a')+10;
00065 else if (c>='A' && c<='F') return (c-'A')+10;
00066 else return 0;
00067 }
00068
00069 QPixmap* getPixmap(core::objectmodel::Base* obj)
00070 {
00071 using namespace sofa::simulation::Colors;
00072 unsigned int flags=0;
00073
00074 if (dynamic_cast<core::objectmodel::BaseNode*>(obj))
00075 {
00076 static QPixmap pixNode((const char**)iconnode_xpm);
00077 return &pixNode;
00078
00079 }
00080 else if (dynamic_cast<core::objectmodel::BaseObject*>(obj))
00081 {
00082 if (dynamic_cast<core::objectmodel::ContextObject*>(obj))
00083 flags |= 1 << CONTEXT;
00084 if (dynamic_cast<core::BehaviorModel*>(obj))
00085 flags |= 1 << BMODEL;
00086 if (dynamic_cast<core::CollisionModel*>(obj))
00087 flags |= 1 << CMODEL;
00088 if (dynamic_cast<core::componentmodel::behavior::BaseMechanicalState*>(obj))
00089 flags |= 1 << MMODEL;
00090 if (dynamic_cast<core::componentmodel::behavior::BaseConstraint*>(obj))
00091 flags |= 1 << CONSTRAINT;
00092 if (dynamic_cast<core::componentmodel::behavior::InteractionForceField*>(obj) &&
00093 dynamic_cast<core::componentmodel::behavior::InteractionForceField*>(obj)->getMechModel1()!=dynamic_cast<core::componentmodel::behavior::InteractionForceField*>(obj)->getMechModel2())
00094 flags |= 1 << IFFIELD;
00095 else if (dynamic_cast<core::componentmodel::behavior::BaseForceField*>(obj))
00096 flags |= 1 << FFIELD;
00097 if (dynamic_cast<core::componentmodel::behavior::MasterSolver*>(obj)
00098 || dynamic_cast<core::componentmodel::behavior::OdeSolver*>(obj))
00099 flags |= 1 << SOLVER;
00100 if (dynamic_cast<core::componentmodel::collision::Pipeline*>(obj)
00101 || dynamic_cast<core::componentmodel::collision::Intersection*>(obj)
00102 || dynamic_cast<core::componentmodel::collision::Detection*>(obj)
00103 || dynamic_cast<core::componentmodel::collision::ContactManager*>(obj)
00104 || dynamic_cast<core::componentmodel::collision::CollisionGroupManager*>(obj))
00105 flags |= 1 << COLLISION;
00106 if (dynamic_cast<core::componentmodel::behavior::BaseMechanicalMapping*>(obj))
00107 flags |= 1 << MMAPPING;
00108 else if (dynamic_cast<core::BaseMapping*>(obj))
00109 flags |= 1 << MAPPING;
00110 if (dynamic_cast<core::componentmodel::behavior::BaseMass*>(obj))
00111 flags |= 1 << MASS;
00112 if (dynamic_cast<core::componentmodel::topology::Topology *>(obj)
00113 || dynamic_cast<core::componentmodel::topology::BaseTopologyObject *>(obj) )
00114 flags |= 1 << TOPOLOGY;
00115 if (dynamic_cast<core::VisualModel*>(obj) && !flags)
00116 flags |= 1 << VMODEL;
00117 if (!flags)
00118 flags |= 1 << OBJECT;
00119 }
00120 else return NULL;
00121
00122 static std::map<unsigned int, QPixmap*> pixmaps;
00123 if (!pixmaps.count(flags))
00124 {
00125 int nc = 0;
00126 for (int i=0;i<16;i++)
00127 if (flags & (1<<i))
00128 ++nc;
00129 int nx = 2+iconWidth*nc+iconMargin;
00130 QImage * img = new QImage(nx,iconHeight,32);
00131 img->setAlphaBuffer(true);
00132 img->fill(qRgba(0,0,0,0));
00133
00134 for (int y=0 ; y < iconHeight ; y++)
00135 for (int x=0 ; x < nx ; x++)
00136 img->setPixel(x,y,qRgba(0,0,0,0));
00137
00138 for (int y=0 ; y < iconHeight ; y++)
00139 img->setPixel(0,y,qRgba(0,0,0,255));
00140 nc = 0;
00141 for (int i=0;i<16;i++)
00142 if (flags & (1<<i))
00143 {
00144 int x0 = 1+iconWidth*nc;
00145 int x1 = x0+iconWidth-1;
00146
00147 const char* color = COLOR[i];
00148
00149 int r = (hexval(color[1])*16+hexval(color[2]));
00150 int g = (hexval(color[3])*16+hexval(color[4]));
00151 int b = (hexval(color[5])*16+hexval(color[6]));
00152 int a = 255;
00153 for (int x=x0; x <=x1 ; x++)
00154 {
00155 img->setPixel(x,0,qRgba(0,0,0,255));
00156 img->setPixel(x,iconHeight-1,qRgba(0,0,0,255));
00157 for (int y=1 ; y < iconHeight-1 ; y++)
00158
00159 img->setPixel(x,y,qRgba(r,g,b,a));
00160 }
00161
00162 ++nc;
00163 }
00164 for (int y=0 ; y < iconHeight ; y++)
00165 img->setPixel(2+iconWidth*nc-1,y,qRgba(0,0,0,255));
00166 pixmaps[flags] = new QPixmap(*img);
00167 delete img;
00168 }
00169 return pixmaps[flags];
00170 }
00171
00172
00173
00174
00175 Q3ListViewItem* GraphListenerQListView::createItem(Q3ListViewItem* parent)
00176 {
00177 Q3ListViewItem* last = parent->firstChild();
00178 if (last == NULL)
00179 return new Q3ListViewItem(parent);
00180 while (last->nextSibling()!=NULL)
00181 last = last->nextSibling();
00182 return new Q3ListViewItem(parent, last);
00183 }
00184
00185
00186
00187 void GraphListenerQListView::addChild(GNode* parent, GNode* child)
00188 {
00189 if (frozen) return;
00190 if (items.count(child))
00191 {
00192 Q3ListViewItem* item = items[child];
00193 if (item->listView() == NULL)
00194 {
00195 if (parent == NULL)
00196 widget->insertItem(item);
00197 else if (items.count(parent))
00198 items[parent]->insertItem(item);
00199 else
00200 {
00201 std::cerr << "Graph -> QT ERROR: Unknown parent node "<<parent->getName()<<std::endl;
00202 return;
00203 }
00204 }
00205 }
00206 else
00207 {
00208 Q3ListViewItem* item;
00209 if (parent == NULL)
00210 item = new Q3ListViewItem(widget);
00211 else if (items.count(parent))
00212 item = createItem(items[parent]);
00213 else
00214 {
00215 std::cerr << "Graph -> QT ERROR: Unknown parent node "<<parent->getName()<<std::endl;
00216 return;
00217 }
00218
00219
00220 item->setDropEnabled(true);
00221 item->setText(0, child->getName().c_str());
00222 QPixmap* pix = getPixmap(child);
00223 if (pix)
00224 item->setPixmap(0, *pix);
00225 item->setOpen(true);
00226 items[child] = item;
00227 }
00228
00229 MutationListener::addChild(parent, child);
00230 }
00231
00232
00233 void GraphListenerQListView::removeChild(GNode* parent, GNode* child)
00234 {
00235 MutationListener::removeChild(parent, child);
00236 if (items.count(child))
00237 {
00238 delete items[child];
00239 items.erase(child);
00240 }
00241 }
00242
00243
00244 void GraphListenerQListView::moveChild(GNode* previous, GNode* parent, GNode* child)
00245 {
00246 if (frozen && items.count(child))
00247 {
00248 Q3ListViewItem* itemChild = items[child];
00249 if (items.count(previous))
00250 {
00251 Q3ListViewItem* itemPrevious = items[previous];
00252 itemPrevious->takeItem(itemChild);
00253 }
00254 else
00255 {
00256 removeChild(previous, child);
00257 }
00258 return;
00259 }
00260 if (!items.count(child) || !items.count(previous))
00261 {
00262 addChild(parent, child);
00263 }
00264 else if (!items.count(parent))
00265 {
00266 removeChild(previous, child);
00267 }
00268 else
00269 {
00270 Q3ListViewItem* itemChild = items[child];
00271 Q3ListViewItem* itemPrevious = items[previous];
00272 Q3ListViewItem* itemParent = items[parent];
00273 itemPrevious->takeItem(itemChild);
00274 itemParent->insertItem(itemChild);
00275 }
00276 }
00277
00278
00279 void GraphListenerQListView::addObject(GNode* parent, core::objectmodel::BaseObject* object)
00280 {
00281 if (frozen) return;
00282 if (items.count(object))
00283 {
00284 Q3ListViewItem* item = items[object];
00285 if (item->listView() == NULL)
00286 {
00287 if (items.count(parent))
00288 items[parent]->insertItem(item);
00289 else
00290 {
00291 std::cerr << "Graph -> QT ERROR: Unknown parent node "<<parent->getName()<<std::endl;
00292 return;
00293 }
00294 }
00295 }
00296 else
00297 {
00298 Q3ListViewItem* item;
00299 if (items.count(parent))
00300 item = createItem(items[parent]);
00301 else
00302 {
00303 std::cerr << "Graph -> QT ERROR: Unknown parent node "<<parent->getName()<<std::endl;
00304 return;
00305 }
00306 std::string name = sofa::helper::gettypename(typeid(*object));
00307 std::string::size_type pos = name.find('<');
00308 if (pos != std::string::npos)
00309 name.erase(pos);
00310
00311
00312 name += " ";
00313 name += object->getName();
00314
00315 item->setText(0, name.c_str());
00316
00317 if (object->getLogWarning().size() == 0)
00318 {
00319 QPixmap* pix = getPixmap(object);
00320 if (pix)
00321 item->setPixmap(0, *pix);
00322
00323 }
00324 else
00325 {
00326 static QPixmap pixWarning((const char**)iconwarning_xpm);
00327 item->setPixmap(0,pixWarning);
00328 }
00329
00330
00331 items[object] = item;
00332 }
00333 }
00334
00335
00336
00337 void GraphListenerQListView::removeObject(GNode* , core::objectmodel::BaseObject* object)
00338 {
00339 if (items.count(object))
00340 {
00341 delete items[object];
00342 items.erase(object);
00343 }
00344 }
00345
00346
00347 void GraphListenerQListView::moveObject(GNode* previous, GNode* parent, core::objectmodel::BaseObject* object)
00348 {
00349 if (frozen && items.count(object))
00350 {
00351 Q3ListViewItem* itemObject = items[object];
00352 Q3ListViewItem* itemPrevious = items[previous];
00353 itemPrevious->takeItem(itemObject);
00354 return;
00355 }
00356 if (!items.count(object) || !items.count(previous))
00357 {
00358 addObject(parent, object);
00359 }
00360 else if (!items.count(parent))
00361 {
00362 removeObject(previous, object);
00363 }
00364 else
00365 {
00366 Q3ListViewItem* itemObject = items[object];
00367 Q3ListViewItem* itemPrevious = items[previous];
00368 Q3ListViewItem* itemParent = items[parent];
00369 itemPrevious->takeItem(itemObject);
00370 itemParent->insertItem(itemObject);
00371 }
00372 }
00373
00374
00375 void GraphListenerQListView::freeze(GNode* groot)
00376 {
00377 if (!items.count(groot)) return;
00378 frozen = true;
00379 }
00380
00381
00382
00383 void GraphListenerQListView::unfreeze(GNode* groot)
00384 {
00385 if (!items.count(groot)) return;
00386 frozen = false;
00387 addChild(NULL, groot);
00388 }
00389
00390
00391
00392
00393 }
00394 }
00395 }