51 #include "MaterialPicker.hh"
55 #include <ACG/QtWidgets/QtMaterialDialog.hh>
59 MaterialPicker::MaterialPicker()
61 pickModeName_(
"MaterialPicker"),
62 propName_(name()+QString(
"/Materials")),
63 pickMaterialButton_(0),
64 fillMaterialButton_(0),
65 materialListWidget_(0),
77 MaterialPicker::~MaterialPicker() {
83 void MaterialPicker::initializePlugin() {
84 QWidget* toolBox =
new QWidget();
86 pickMaterialButton_ =
new QPushButton(
"&pick Material", toolBox);
87 fillMaterialButton_ =
new QPushButton(
"&fill Material", toolBox);
88 QPushButton* clearListButton =
new QPushButton(
"Clear List", toolBox);
89 QPushButton* removeItemButton =
new QPushButton(
"Remove", toolBox);
91 pickMaterialButton_->setCheckable(
true);
92 fillMaterialButton_->setCheckable(
true);
94 QLabel* materials =
new QLabel(
"Materials:");
96 materialListWidget_ =
new QListWidget(toolBox);
100 for (
int i = 0; i < materialStrings_.size(); ++i)
102 QStringList savedString = materialStrings_[i].split(
";");
103 std::stringstream stream;
104 MaterialInfo materialInfo;
105 stream << savedString[1].toStdString();
106 stream >> materialInfo.color_material;
109 stream << savedString[2].toStdString();
110 stream >> materialInfo.base_color;
113 stream << savedString[3].toStdString();
114 stream >> materialInfo.ambient_color;
117 stream << savedString[4].toStdString();
118 stream >> materialInfo.diffuse_color;
121 stream << savedString[5].toStdString();
122 stream >> materialInfo.specular_color;
125 stream << savedString[6].toStdString();
126 stream >> materialInfo.shininess;
129 stream << savedString[7].toStdString();
130 stream >> materialInfo.reflectance;
133 stream << savedString[8].toStdString();
134 stream >> materialInfo.key;
136 if (materialInfo.key != Qt::Key_unknown)
137 shortKeyRow_[materialInfo.key] = materialListWidget_->count();
139 materialListWidget_->addItem(
itemName(savedString[0],materialInfo.key) );
140 materialList_.push_back(materialInfo);
144 if (materialStrings_.size())
145 materialListWidget_->setCurrentItem(materialListWidget_->item(0));
147 fillMaterialButton_->setEnabled(
false);
149 QGridLayout* removeGrid =
new QGridLayout();
150 removeGrid->addWidget(removeItemButton,0,0);
151 removeGrid->addWidget(clearListButton,0,1);
153 QGridLayout* pickGrid =
new QGridLayout();
154 pickGrid->addWidget(pickMaterialButton_, 0, 0);
155 pickGrid->addWidget(fillMaterialButton_, 0, 1);
157 QBoxLayout* layout =
new QBoxLayout(QBoxLayout::TopToBottom, toolBox);
158 layout->addWidget(materials);
159 layout->addWidget(materialListWidget_);
161 layout->addLayout(removeGrid);
162 layout->addLayout(pickGrid);
164 connect(pickMaterialButton_, SIGNAL(clicked()),
this, SLOT(slotPickMaterialMode()));
165 connect(fillMaterialButton_, SIGNAL(clicked()),
this, SLOT(slotFillMaterialMode()));
166 connect(clearListButton, SIGNAL(clicked()),
this, SLOT(clearList()));
167 connect(materialListWidget_, SIGNAL(itemDoubleClicked(QListWidgetItem*)),
this, SLOT(
editMode(QListWidgetItem*)));
168 connect(materialListWidget_->itemDelegate(), SIGNAL(closeEditor(QWidget*, QAbstractItemDelegate::EndEditHint)),
this,SLOT(
saveNewName(QWidget*, QAbstractItemDelegate::EndEditHint)));
169 connect(removeItemButton, SIGNAL(clicked()),
this, SLOT(slotRemoveCurrentItem()));
170 connect(materialListWidget_,SIGNAL(customContextMenuRequested(
const QPoint&)),
this,SLOT(
createContextMenu(
const QPoint&)));
172 materialListWidget_->setContextMenuPolicy(Qt::CustomContextMenu);
173 QIcon* toolIcon =
new QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+
"material_picker.png");
174 emit addToolbox( tr(
"Material Picker"), toolBox, toolIcon);
178 void MaterialPicker::removeItem(QListWidgetItem* _item)
180 unsigned index = materialListWidget_->row(_item);
181 materialListWidget_->takeItem(index);
182 materialList_.erase(materialList_.begin()+index);
183 materialStrings_.erase(materialStrings_.begin()+index);
184 if (materialStrings_.isEmpty())
188 fillMaterialButton_->setEnabled(materialListWidget_->count());
191 std::map<int,size_t>::iterator eraseIter = shortKeyRow_.end();
192 for (std::map<int,size_t>::iterator iter = shortKeyRow_.begin(); iter != shortKeyRow_.end(); ++iter)
194 if (iter->second > index)
196 else if (iter->second == index)
199 if (eraseIter != shortKeyRow_.end())
200 shortKeyRow_.erase(eraseIter);
206 void MaterialPicker::clearList() {
207 materialListWidget_->clear();
208 materialList_.clear();
209 materialStrings_.clear();
210 fillMaterialButton_->setEnabled(
false);
218 void MaterialPicker::slotRemoveCurrentItem()
220 if (!materialListWidget_->count())
224 QListWidgetItem* item = materialListWidget_->currentItem();
225 msgBox.setText(tr(
"Remove ")+
plainName(item->text(),materialListWidget_->currentRow())+tr(
"?"));
226 msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
227 msgBox.setDefaultButton(QMessageBox::Ok);
228 int ret = msgBox.exec();
230 if (ret == QMessageBox::Ok)
231 removeItem(materialListWidget_->currentItem());
235 void MaterialPicker::slotPickMaterialMode() {
236 pickMaterialButton_->setChecked(
true);
237 fillMaterialButton_->setChecked(
false);
247 void MaterialPicker::slotFillMaterialMode() {
248 fillMaterialButton_->setChecked(
true);
249 pickMaterialButton_->setChecked(
false);
259 void MaterialPicker::pluginsInitialized() {
260 emit addPickMode(pickModeName_);
261 for (
unsigned i = 0; i < supportedKeys_; ++i)
262 emit registerKey (Qt::Key_1+i, Qt::ControlModifier, QString(tr(
"Material %1")).arg(i+1),
false);
267 void MaterialPicker::slotMouseEvent(QMouseEvent* _event) {
271 if (_event->type() == QEvent::MouseButtonPress) {
272 unsigned int node_idx, target_idx;
287 MaterialInfo materialInfo;
289 materialInfo.base_color = material->
base_color();
293 materialInfo.shininess = material->
shininess();
294 materialInfo.reflectance = material->
reflectance();
296 materialInfo.key = Qt::Key_unknown;
297 if (shortKeyRow_.size() < supportedKeys_)
299 materialInfo.key = Qt::Key_1+(int)shortKeyRow_.size();
300 shortKeyRow_[materialInfo.key] = materialListWidget_->count();
304 QString
name = QString(
"material id: %1").arg(material->
id());
305 materialListWidget_->addItem(
itemName(name,materialInfo.key) );
306 materialListWidget_->setCurrentItem( materialListWidget_->item(materialListWidget_->count() - 1) );
308 materialList_.push_back(materialInfo);
312 materialStrings_.push_back(matStr);
315 fillMaterialButton_->setEnabled(
true);
325 if (materialListWidget_->count() > 0)
327 int row = materialListWidget_->currentRow();
346 void MaterialPicker::editModeCurrent()
348 editMode(materialListWidget_->currentItem());
353 _item->setFlags(_item->flags() | Qt::ItemIsEditable);
354 materialListWidget_->editItem(_item);
355 _item->setText(
plainName(_item->text(),materialListWidget_->row(_item)));
366 if (materialList_[index].key == Qt::Key_unknown)
370 return str.remove(0,4);
375 unsigned index = materialListWidget_->row(_item);
376 QString str = materialStrings_[index];
377 QStringList strList = str.split(
";");
380 strList[0] = _item->text();
382 if (materialList_[index].key != Qt::Key_unknown)
383 _item->setText(
itemName(strList[0], materialList_[index].key) );
388 for (
int i = 0; i < strList.size()-1; ++i)
389 str += strList[i] +
";";
390 str += strList[strList.size()-1];
391 materialStrings_[index] = str;
398 if (_key == Qt::Key_unknown)
400 return QString(tr(
"(%1) ")).arg(QString::number(_key-Qt::Key_1+1)) +_name;
405 void MaterialPicker::slotPickModeChanged(
const std::string& _mode) {
406 pickMaterialButton_->setChecked( _mode == pickModeName_ &&
pickMaterial_ );
407 fillMaterialButton_->setChecked( _mode == pickModeName_ &&
fillMaterial_ );
411 void MaterialPicker::slotKeyEvent(QKeyEvent* _event)
413 for (
unsigned i = 0; i < supportedKeys_; ++i)
415 int key = Qt::Key_1+i;
416 if (_event->key() == key && _event->modifiers() == Qt::ControlModifier)
418 if (shortKeyRow_.find(key) == shortKeyRow_.end())
420 slotFillMaterialMode();
421 materialListWidget_->setCurrentRow((
int)shortKeyRow_[key]);
428 std::map<int,size_t>::iterator iter = shortKeyRow_.find(_key);
430 if (iter != shortKeyRow_.end())
433 int oldIndex = (int)iter->second;
434 QListWidgetItem* oldItem = materialListWidget_->item(oldIndex);
436 oldItem->setText(
plainName(oldItem->text(),oldIndex) );
437 materialList_[oldIndex].key = Qt::Key_unknown;
438 materialStrings_[oldIndex] =
materialString(materialList_[oldIndex],oldItem->text());
443 int newIndex = materialListWidget_->currentRow();
444 QListWidgetItem* newItem = materialListWidget_->item(newIndex);
445 materialList_[newIndex].key = _key;
447 materialStrings_[newIndex] =
materialString(materialList_[newIndex],newItem->text());
450 shortKeyRow_[_key] = newIndex;
455 std::stringstream stream;
456 stream << _name.toStdString();
457 stream <<
";" << _mat.color_material;
458 stream <<
";" << _mat.base_color;
459 stream <<
";" << _mat.ambient_color;
460 stream <<
";" << _mat.diffuse_color;
461 stream <<
";" << _mat.specular_color;
462 stream <<
";" << _mat.shininess;
463 stream <<
";" << _mat.reflectance;
464 stream <<
";" << _mat.key;
466 return QString(stream.str().c_str());
469 void MaterialPicker::slotMaterialProperties()
475 materialListWidget_->setDisabled(
true);
478 int row = materialListWidget_->currentRow();
479 materialNode_->colorMaterial(materialList_[row].color_material);
480 materialNode_->set_base_color(materialList_[row].base_color);
481 materialNode_->set_ambient_color(materialList_[row].ambient_color);
482 materialNode_->set_diffuse_color(materialList_[row].diffuse_color);
483 materialNode_->set_specular_color(materialList_[row].specular_color);
484 materialNode_->set_shininess(materialList_[row].shininess);
485 materialNode_->set_reflectance(materialList_[row].reflectance);
489 dialog->setWindowFlags(dialog->windowFlags() | Qt::WindowStaysOnTopHint);
491 connect(dialog,SIGNAL(finished(
int)),
this,SLOT(slotEnableListWidget(
int)));
492 connect(dialog,SIGNAL(accepted()),
this,SLOT(slotMaterialChanged()));
494 dialog->setWindowIcon( QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+
"datacontrol-material.png"));
500 void MaterialPicker::slotMaterialChanged()
504 int index = materialListWidget_->currentRow();
506 MaterialInfo materialInfo;
507 materialInfo.color_material = materialNode_->colorMaterial();
508 materialInfo.base_color = materialNode_->base_color();
509 materialInfo.ambient_color = materialNode_->ambient_color();
510 materialInfo.diffuse_color = materialNode_->diffuse_color();
511 materialInfo.specular_color = materialNode_->specular_color();
512 materialInfo.shininess = materialNode_->shininess();
513 materialInfo.reflectance = materialNode_->reflectance();
514 materialInfo.key = materialList_[index].key;
515 QString name =
plainName(materialListWidget_->currentItem()->text(),materialListWidget_->currentRow());
517 materialList_[index] = materialInfo;
524 void MaterialPicker::slotEnableListWidget(
int _save){
525 materialListWidget_->setEnabled(
true);
526 if (_save == QDialog::Accepted)
527 slotMaterialChanged();
528 materialNode_.reset();
534 QMenu *menu =
new QMenu(materialListWidget_);
536 QAction* action = menu->addAction(tr(
"Material Properties"));
538 icon.addFile(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+
"datacontrol-material.png");
539 action->setIcon(icon);
540 action->setEnabled(
true);
541 connect(action,SIGNAL(triggered(
bool)),
this,SLOT(slotMaterialProperties()));
543 action = menu->addAction(tr(
"Rename"));
544 connect(action,SIGNAL(triggered(
bool)),
this,SLOT(editModeCurrent()));
546 action = menu->addAction(tr(
"Remove"));
547 connect(action, SIGNAL(triggered(
bool)),
this,SLOT(slotRemoveCurrentItem()));
549 menu->addSeparator();
552 QSignalMapper* signalMapper =
new QSignalMapper(menu);
553 for (
unsigned i = 0; i < supportedKeys_; ++i)
555 QAction* action = menu->addAction(tr(
"Key %1").arg(i+1));
556 connect(action,SIGNAL(triggered(
bool)),signalMapper,SLOT(map()));
557 signalMapper->setMapping(action,Qt::Key_1+i);
558 std::map<int,size_t>::iterator iter = shortKeyRow_.find(Qt::Key_1+i);
561 if (iter != shortKeyRow_.end() && iter->second ==
static_cast<size_t>(materialListWidget_->currentRow()))
562 action->setDisabled(
true);
565 connect(signalMapper, SIGNAL(mapped(
const int &)),
this, SLOT(
changeHotKey(
const int &)));
566 menu->exec(materialListWidget_->mapToGlobal(_point),0);
571 #if QT_VERSION < 0x050000
DLLEXPORT OpenFlipperQSettings & OpenFlipperSettings()
QSettings object containing all program settings of OpenFlipper.
const Vec4f & diffuse_color() const
get the diffuse color.
void editMode(QListWidgetItem *_item)
items can be renamed by double clicking them
QString materialString(const MaterialInfo &_mat, const QString &_name)
returns a formatted string for saving
pick any of the prior targets (should be implemented for all nodes)
QString plainName(const QString &string, int index)
returns the plain name of the material without hotkey hint
const Vec4f & base_color() const
get the base color
bool fillMaterial_
stores the state of the fill material button
void set_base_color(const Vec4f &_c)
set the base color
bool pickMaterial_
stores the state of the pick material button
const std::string pickMode()
Get the current Picking mode.
QString itemName(const QString &_name, int _key)
returns the item name with hotkey hint
void set_specular_color(const Vec4f &_s)
set the specular color
void set_reflectance(double _m)
set reflectance
float shininess() const
get shininess
const Vec4f & specular_color() const
get the specular color
void changeHotKey(const int _key)
change specified HotKey to current item
double reflectance() const
get reflectance
QVariant value(const QString &key, const QVariant &defaultValue=QVariant()) const
bool scenegraphPick(ACG::SceneGraph::PickTarget _pickTarget, const QPoint &_mousePos, unsigned int &_nodeIdx, unsigned int &_targetIdx, ACG::Vec3d *_hitPointPtr=0)
Execute picking operation on scenegraph.
void set_diffuse_color(const Vec4f &_d)
set the diffuse color.
void colorMaterial(const bool _cm)
Set colorMaterial.
Viewer::ActionMode actionMode()
Get the current Action mode.
void setValue(const QString &key, const QVariant &value)
Wrapper function which makes it possible to enable Debugging output with -DOPENFLIPPER_SETTINGS_DEBUG...
void saveNewName(QWidget *_editor, QAbstractItemDelegate::EndEditHint _hint)
saves the new material name with hotkey hint
ACG::SceneGraph::MaterialNode MaterialNode
Materialnode.
bool getPickedObject(const unsigned int _node_idx, BaseObjectData *&_object)
Get the picked mesh.
void set_shininess(float _s)
set shininess
QString name()
Return a name for the plugin.
void createContextMenu(const QPoint &_point)
creates context menu on current item (current is the item at mouse position)
void set_ambient_color(const Vec4f &_a)
set the ambient color.
const Vec4f & ambient_color() const
get the ambient color.