// -*- C++ -*- // // This file is part of the Coriolis Software. // Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved // // =================================================================== // // $Id$ // // x-----------------------------------------------------------------x // | | // | H U R R I C A N E | // | V L S I B a c k e n d D a t a - B a s e | // | | // | Author : Jean-Paul CHAPUT | // | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | =============================================================== | // | C++ Module : "./PaletteWidget.cpp" | // | *************************************************************** | // | U p d a t e s | // | | // x-----------------------------------------------------------------x #include #include #include #include #include #include #include #include "hurricane/DataBase.h" #include "hurricane/Technology.h" #include "hurricane/BasicLayer.h" #include "hurricane/BasicLayers.h" #include "hurricane/ExtensionSlice.h" #include "hurricane/Cell.h" #include "hurricane/viewer/Graphics.h" #include "hurricane/viewer/PaletteItem.h" #include "hurricane/viewer/PaletteNamedItem.h" #include "hurricane/viewer/PaletteLayerItem.h" #include "hurricane/viewer/PaletteExtensionGoItem.h" #include "hurricane/viewer/PaletteWidget.h" namespace { using namespace std; using namespace Hurricane; class GridBuffer { public: GridBuffer ( QGridLayout*, size_t rowMax, size_t startRow=0, size_t startColumn=0 ); inline int getRow () const; inline int getColumn () const; inline int getCurrentRow () const; void addSection ( QWidget*, Qt::Alignment align=0 ); void addWidget ( QWidget*, Qt::Alignment align=0 ); void newColumn (); void flushWidgets (); inline bool columnOverload () const; protected: QGridLayout* _grid; size_t _rowMax; size_t _row; size_t _column; vector _widgets; vector _aligns; }; GridBuffer::GridBuffer ( QGridLayout* grid, size_t maxRow, size_t startRow, size_t startColumn ) : _grid (grid) , _rowMax (maxRow) , _row (startRow) , _column (startColumn) , _widgets() , _aligns () { } inline int GridBuffer::getRow () const { return _row; } inline int GridBuffer::getColumn () const { return _column; } inline int GridBuffer::getCurrentRow () const { return _widgets.size() + _row; } inline bool GridBuffer::columnOverload () const { return getCurrentRow() > _rowMax; } void GridBuffer::flushWidgets () { if ( columnOverload() ) { _column++; _row = 0; } for ( size_t i=0 ; i < _widgets.size() ; ++i ) _grid->addWidget ( _widgets[i], _row++, _column, _aligns[i] ); _widgets.clear (); _aligns.clear (); } void GridBuffer::newColumn () { if ( columnOverload() ) return; flushWidgets (); _column++; _row = 0; } void GridBuffer::addWidget ( QWidget* widget, Qt::Alignment align ) { _widgets.push_back ( widget ); _aligns .push_back ( align ); } void GridBuffer::addSection ( QWidget* widget, Qt::Alignment align ) { flushWidgets (); _widgets.push_back ( widget ); _aligns .push_back ( align ); } } // End of anonymous namespace. namespace Hurricane { QWidget* PaletteWidget::_createGroupItem ( const Name& name ) { QLabel* groupLabel = new QLabel (); groupLabel->setText ( getString(name).c_str() ); groupLabel->setFont ( Graphics::getFixedFont(QFont::Bold,false,false) ); return groupLabel; } PaletteNamedItem* PaletteWidget::_createNamedItem ( const Name& name, bool checked ) { PaletteNamedItem* item = PaletteNamedItem::create ( name, checked ); connect ( item, SIGNAL(visibleToggled()), this, SIGNAL(paletteChanged()) ); return item; } PaletteLayerItem* PaletteWidget::_createLayerItem ( BasicLayer* layer, bool checked ) { PaletteLayerItem* item = PaletteLayerItem::create ( layer, checked ); connect ( item, SIGNAL(visibleToggled()), this, SIGNAL(paletteChanged()) ); return item; } PaletteExtensionGoItem* PaletteWidget::_createExtensionGoItem ( const Name& name, bool checked ) { PaletteExtensionGoItem* item = PaletteExtensionGoItem::create ( name ); connect ( item, SIGNAL(visibleToggled()), this, SIGNAL(paletteChanged()) ); return item; } PaletteWidget::PaletteWidget ( QWidget* parent ) : QWidget (parent) , _scrollArea (new QScrollArea(this)) , _layerItems () , _extensionGoItems() , _showAll (new QPushButton(_scrollArea)) , _hideAll (new QPushButton(_scrollArea)) , _grid (new QGridLayout()) , _columnHeight (22) , _extensionRow (0) , _extensionColumn (0) , _extensionGroup (NULL) { setContentsMargins ( 0, 0, 0, 0 ); _scrollArea->setWidgetResizable ( true ); QVBoxLayout* vLayout = new QVBoxLayout (); QHBoxLayout* hLayout = new QHBoxLayout (); _showAll->setIcon ( QIcon(":/images/palette_show_all.png") ); _showAll->setFlat ( true ); _hideAll->setIcon ( QIcon(":/images/palette_hide_all.png") ); _hideAll->setFlat ( true ); connect ( _showAll, SIGNAL(clicked()), this, SLOT(showAll()) ); connect ( _hideAll, SIGNAL(clicked()), this, SLOT(hideAll()) ); hLayout->addStretch (); hLayout->addWidget ( _showAll ); hLayout->addStretch (); hLayout->addWidget ( _hideAll ); hLayout->addStretch (); QFrame* separator = new QFrame (); separator->setFrameShape ( QFrame::HLine ); separator->setFrameShadow ( QFrame::Sunken ); vLayout->setSpacing ( 0 ); vLayout->addLayout ( hLayout ); vLayout->addWidget ( separator ); vLayout->addSpacing ( 5 ); vLayout->addLayout ( _grid ); _grid->setHorizontalSpacing ( 10 ); _grid->setVerticalSpacing ( 0 ); //_grid->setSizeConstraint ( QLayout::SetFixedSize ); vLayout->addStretch (); QWidget* scrollAdaptator = new QWidget (); scrollAdaptator->setLayout ( vLayout ); _scrollArea->setContentsMargins ( 0, 0, 0, 0 ); _scrollArea->setWidget ( scrollAdaptator ); _scrollArea->setHorizontalScrollBarPolicy ( Qt::ScrollBarAsNeeded ); _scrollArea->setVerticalScrollBarPolicy ( Qt::ScrollBarAsNeeded ); _scrollArea->setFrameStyle ( QFrame::Plain ); vLayout = new QVBoxLayout (); vLayout->setSpacing ( 0 ); vLayout->addWidget ( _scrollArea ); setLayout ( vLayout ); } void PaletteWidget::build () { GridBuffer gridBuffer ( _grid, _columnHeight ); size_t gi = 0; const vector& groups = Graphics::getStyle()->getDrawingGroups(); const vector& styles = groups[gi]->getDrawingStyles(); gridBuffer.addSection ( _createGroupItem(groups[gi]->getName()), Qt::AlignHCenter ); for ( size_t si=0 ; sigetName() == DisplayStyle::Foreground ) continue; if ( styles[si]->getName() == DisplayStyle::Background ) continue; if ( styles[si]->getName() == DisplayStyle::Foreground ) continue; if ( styles[si]->getName() == DisplayStyle::SelectionDraw ) continue; if ( styles[si]->getName() == DisplayStyle::SelectionFill ) continue; if ( styles[si]->getName() == DisplayStyle::Foreground ) continue; PaletteNamedItem* item = _createNamedItem ( styles[si]->getName() ); gridBuffer.addWidget ( item ); _layerItems [ item->getName() ] = item; } if ( _columnHeight < numeric_limits::max() ) gridBuffer.newColumn (); else gridBuffer.flushWidgets (); DataBase* database = DataBase::getDB(); if ( database ) { Technology* technology = database->getTechnology(); if ( technology ) { for ( gi=1 ; gigetName()), Qt::AlignHCenter ); const vector& styles = groups[gi]->getDrawingStyles(); for ( size_t si=0 ; sigetBasicLayer ( styles[si]->getName() ); if ( basicLayer ) { PaletteLayerItem* item = _createLayerItem ( basicLayer ); gridBuffer.addWidget ( item ); _layerItems [ item->getName() ] = item; } } } size_t si = 0; forEach ( BasicLayer*, basicLayer, technology->getBasicLayers() ) { if ( !find((*basicLayer)->getName()) ) { if ( !si ) gridBuffer.addSection ( _createGroupItem("Unmatcheds"), Qt::AlignHCenter ); PaletteLayerItem* item = _createLayerItem ( *basicLayer ); gridBuffer.addWidget ( item ); _layerItems [ item->getName() ] = item; cerr << "[WARNING] BasicLayer \"" << (*basicLayer)->getName() << "\" has no associated DisplayStyle." << endl; si++; } } if ( si ) gi++; } } if ( _columnHeight < numeric_limits::max() ) gridBuffer.newColumn (); else gridBuffer.flushWidgets (); _extensionRow = gridBuffer.getRow(); _extensionColumn = gridBuffer.getColumn(); _extensionGroup = _createGroupItem ( "Extensions" ); gridBuffer.addSection ( _extensionGroup, Qt::AlignHCenter ); gridBuffer.flushWidgets (); } void PaletteWidget::updateExtensions ( Cell* cell ) { _grid->removeWidget ( _extensionGroup ); _extensionGroup->deleteLater (); _extensionGroup = NULL; PaletteItems::iterator iextension = _extensionGoItems.begin(); for ( ; iextension != _extensionGoItems.end() ; ++iextension ) { _grid->removeWidget ( iextension->second ); iextension->second->deleteLater (); } _extensionGoItems.clear (); GridBuffer gridBuffer ( _grid, _columnHeight, _extensionRow, _extensionColumn ); _extensionGroup = _createGroupItem ( "Extensions" ); gridBuffer.addSection ( _extensionGroup, Qt::AlignHCenter ); if ( cell ) { forEach ( ExtensionSlice*, extension, cell->getExtensionSlices() ) { PaletteExtensionGoItem* item = _createExtensionGoItem ( (*extension)->getName(), false ); gridBuffer.addWidget ( item ); _extensionGoItems [ item->getName() ] = item; } } gridBuffer.flushWidgets (); } void PaletteWidget::_getSection ( const QString section, QLabel*& label, vector& items ) const { label = NULL; items.clear (); bool found = false; for ( int index=0 ; index < _grid->count() ; index++ ) { QLayoutItem* item = _grid->itemAt ( index ); if ( !item ) continue; QLabel* ilabel = dynamic_cast(item->widget()); if ( ilabel ) { if ( found ) break; if ( ilabel->text() != section ) continue; found = true; label = ilabel; } else if ( found ) { PaletteItem* paletteItem = dynamic_cast(item->widget()); if ( paletteItem ) items.push_back ( paletteItem ); } } } void PaletteWidget::setSectionVisible ( const QString section, bool visible ) { QLabel* label; vector items; _getSection ( section, label, items ); if ( !label ) return; if ( visible ) label->show (); else label->hide (); for ( size_t i=0 ; ishow (); else items[i]->hide (); } } bool PaletteWidget::isDrawable ( const Name& name ) const { PaletteItem* item = find ( name ); if ( item ) return item->isItemVisible (); return false; } bool PaletteWidget::isSelectable ( const Name& name ) const { PaletteItem* item = find ( name ); if ( item ) return item->isItemSelectable (); return false; } void PaletteWidget::showAll () { PaletteItems::iterator iitem = _layerItems.begin(); for ( ; iitem != _layerItems.end() ; iitem++ ) iitem->second->setItemVisible ( true ); iitem = _extensionGoItems.begin(); for ( ; iitem != _extensionGoItems.end() ; iitem++ ) iitem->second->setItemVisible ( true ); emit paletteChanged(); } void PaletteWidget::hideAll () { PaletteItems::iterator iitem = _layerItems.begin(); for ( ; iitem != _layerItems.end() ; iitem++ ) iitem->second->setItemVisible ( false ); iitem = _extensionGoItems.begin(); for ( ; iitem != _extensionGoItems.end() ; iitem++ ) iitem->second->setItemVisible ( false ); emit paletteChanged(); } void PaletteWidget::showSection ( const QString section ) { QLabel* label; vector items; _getSection ( section, label, items ); if ( !label ) return; for ( size_t i=0 ; isetItemVisible ( true ); } void PaletteWidget::hideSection ( const QString section ) { QLabel* label; vector items; _getSection ( section, label, items ); if ( !label ) return; for ( size_t i=0 ; isetItemVisible ( false ); } PaletteItem* PaletteWidget::find ( const Name& name ) const { PaletteItems::const_iterator iitem = _layerItems.find(name); if ( iitem != _layerItems.end() ) return iitem->second; iitem = _extensionGoItems.find(name); if ( iitem != _extensionGoItems.end() ) return iitem->second; return NULL; } void PaletteWidget::setItemVisible ( const Name& name, bool visible ) { PaletteItem* item = find ( name ); if ( item ) { item->setItemVisible ( visible ); emit paletteChanged(); } } void PaletteWidget::changeStyle () { PaletteItems::iterator iitem = _layerItems.begin(); for ( ; iitem != _layerItems.end() ; iitem++ ) iitem->second->changeStyle (); iitem = _extensionGoItems.begin(); for ( ; iitem != _extensionGoItems.end() ; iitem++ ) iitem->second->changeStyle (); } } // End of Hurricane namespace.