1 // Created on: 2021-04-27
2 // Created by: Natalia ERMOLAEVA
3 // Copyright (c) 2021 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <inspector/ViewControl_ColorSelector.hxx>
17 #include <inspector/ViewControl_TableItemDelegate.hxx>
18 #include <inspector/ViewControl_TableModel.hxx>
19 #include <inspector/ViewControl_TableModelValues.hxx>
20 #include <inspector/ViewControl_Tools.hxx>
21 #include <inspector/TreeModel_Tools.hxx>
23 #include <Standard_Dump.hxx>
25 #include <Standard_WarningsDisable.hxx>
26 #include <QAbstractTableModel>
27 #include <QDialogButtonBox>
28 #include <QHeaderView>
29 #include <QGridLayout>
30 #include <QItemSelectionModel>
32 #include <QPushButton>
35 #include <Standard_WarningsRestore.hxx>
37 //! Kinds of delegate cell in OCCT Color model to present a custom presentation (rect bounded by a colored frame)
38 enum ViewControl_ColorDelegateKind
40 ViewControl_ColorDelegateKind_None, //!< usual item
41 ViewControl_ColorDelegateKind_Activated, //!< active item
42 ViewControl_ColorDelegateKind_Highlighted, //!< highlighted item
43 ViewControl_ColorDelegateKind_Selected //!< selected item
46 //! Model for a table of parameters: Current Color, Red, Green, Blue, Alpha, OCCT color name
47 class ViewControl_ParametersModel : public ViewControl_TableModelValues
50 ViewControl_ParametersModel (ViewControl_ColorSelector* theSelector)
51 : ViewControl_TableModelValues(), mySelector (theSelector) {}
52 virtual ~ViewControl_ParametersModel() {}
54 //! Inits model by the parameter color
55 //! \param theColor model active color
56 void SetColor (const Quantity_ColorRGBA& theColor, ViewControl_TableModel* theModel)
57 { myColor = theColor; theModel->EmitLayoutChanged(); }
59 //! Returns current selected color
60 //! \return color value
61 Quantity_ColorRGBA GetColor() const { return myColor; }
63 //! Returns item information(short) for display role.
64 //! \param theIndex a model index
65 //! \param theRole a view role
66 //! \return value intepreted depending on the given role
67 Standard_EXPORT virtual QVariant Data (const int theRow, const int theColumn,
68 int theRole = Qt::DisplayRole) const Standard_OVERRIDE
70 //(void)theRow; (void)theColumn; (void) theRole;
71 if (theRole == Qt::BackgroundRole && theColumn == 1 && theRow == 0)
72 return ViewControl_ColorSelector::ColorToQColor (myColor);
74 if (theRole == Qt::ForegroundRole && theColumn == 1 && theRow >= 2 && theRow <= 5)
75 return ViewControl_TableModelValues::EditCellColor();
77 if (theRole != Qt::DisplayRole)
80 bool isFirstColumn = theColumn == 0;
83 case 0: return isFirstColumn ? QVariant ("Color") : QVariant ();
87 return QVariant ("Name");
88 Quantity_NameOfColor aColorName;
89 if (ViewControl_ColorSelector::IsExactColorName(myColor, aColorName))
90 return Quantity_Color::StringName(aColorName);
93 case 2: return isFirstColumn ? QVariant ("Red") : ViewControl_Tools::ToVariant (myColor.GetRGB().Red());
94 case 3: return isFirstColumn ? QVariant ("Green") : ViewControl_Tools::ToVariant (myColor.GetRGB().Green());
95 case 4: return isFirstColumn ? QVariant ("Blue") : ViewControl_Tools::ToVariant (myColor.GetRGB().Blue());
96 case 5: return isFirstColumn ? QVariant ("Alpha") : ViewControl_Tools::ToVariant (myColor.Alpha());
97 case 6: return isFirstColumn ? QVariant ("Near Name")
98 : Quantity_Color::StringName(myColor.GetRGB().Name());
103 //! Sets content of the model index for the given role, it is applyed to internal container of values
104 //! \param theRow a model index row
105 //! \param theColumn a model index column
106 //! \param theRole a view role
107 //! \return true if the value is changed
108 virtual bool SetData (const int theRow, const int theColumn, const QVariant& theValue, int) Standard_OVERRIDE
110 if (theColumn != 1 || theRow < 2 || theRow > 5)
119 myColor.ChangeRGB().SetValues (theRow == 2 ? ViewControl_Tools::ToShortRealValue (theValue) : myColor.GetRGB().Red(),
120 theRow == 3 ? ViewControl_Tools::ToShortRealValue (theValue) : myColor.GetRGB().Green(),
121 theRow == 4 ? ViewControl_Tools::ToShortRealValue (theValue) : myColor.GetRGB().Blue(),
125 case 5: myColor.SetAlpha (ViewControl_Tools::ToShortRealValue (theValue)); break;
127 mySelector->ParameterColorChanged();
131 //! Returns number of tree level line items = colums in table view
132 virtual int ColumnCount (const QModelIndex& theParent = QModelIndex()) const Standard_OVERRIDE
133 { (void)theParent; return 2; }
135 //! Returns onlly one row in table view
136 virtual int RowCount (const QModelIndex& theParent = QModelIndex()) const Standard_OVERRIDE
137 { (void)theParent; return 7; }
139 //! Returns editable flag for color RGB and alpha rows
141 virtual Qt::ItemFlags Flags (const QModelIndex& theIndex) const Standard_OVERRIDE
143 Qt::ItemFlags aFlags = ViewControl_TableModelValues::Flags (theIndex);
145 if (theIndex.column() == 1 && theIndex.row() >= 2 && theIndex.row() <= 5)
146 aFlags = aFlags | Qt::ItemIsEditable;
151 //! Returns type of edit control for the model index. By default, it is an empty control
152 //! \param theRow a model index row
153 //! \param theColumn a model index column
154 //! \return edit type
155 virtual ViewControl_EditType GetEditType (const int theRow, const int theColumn) const
157 if (theColumn == 1 && theRow >= 2 && theRow <= 5)
158 return ViewControl_EditType_Double;
160 return ViewControl_EditType_None;
164 Quantity_ColorRGBA myColor;
165 ViewControl_ColorSelector* mySelector;
168 //! Table of parameters: Red, Green, Blue, Alpha, OCCT color name
169 class ViewControl_OCCTColorModel : public QAbstractTableModel
172 ViewControl_OCCTColorModel (QObject* theParent)
173 : QAbstractTableModel (theParent), myCurrentIndexKind (ViewControl_ColorDelegateKind_None) {}
174 virtual ~ViewControl_OCCTColorModel() {}
176 //! Sets current color, that should have custom presented
177 //! \param theColor current color
178 //! \param theKind presentation kind
179 void SetColor (const Quantity_NameOfColor& theColor, const ViewControl_ColorDelegateKind theKind)
181 int aColorPosition = (int)theColor;
182 int aRow = (int) (aColorPosition / columnCount());
183 int aColumn = aColorPosition - aRow * columnCount();
184 myCurrentIndex = index (aRow, aColumn);
185 myCurrentIndexKind = theKind;
187 emit layoutChanged();
190 //! Returns OCCT name of color if index position does not exceed Quantity_NameOfColor elements
191 //! \param theIndex model index
192 //! \param theNameOfColor [out] OCCT color name
193 //! \return true if the color is found
194 bool GetOCCTColor (const QModelIndex& theIndex, Quantity_NameOfColor& theNameOfColor) const
196 int aNameOfColorId = theIndex.row() * columnCount() + theIndex.column();
197 if (aNameOfColorId > Quantity_NOC_WHITE)
199 theNameOfColor = (Quantity_NameOfColor)aNameOfColorId;
203 //! Returns index that has custom presentation
204 //! \return model index
205 QModelIndex GetCurrentIndex() const { return myCurrentIndex; }
207 //! Returns index color kind that has custom presentation
209 ViewControl_ColorDelegateKind GetCurrentIndexKind() const { return myCurrentIndexKind; }
211 //! Returns item information(short) for display role.
212 //! \param theIndex a model index
213 //! \param theRole a view role
214 //! \return value intepreted depending on the given role
215 Standard_EXPORT virtual QVariant data (const QModelIndex& theIndex,
216 int theRole = Qt::DisplayRole) const Standard_OVERRIDE
218 if (theRole != Qt::ToolTipRole) // background is processed in table item delegate
221 Quantity_NameOfColor aNameOfColor;
222 if (!GetOCCTColor (theIndex, aNameOfColor))
225 if (theRole == Qt::ToolTipRole)
226 return QString("%1").arg (ViewControl_ColorSelector::ColorToString (Quantity_Color (aNameOfColor)));
230 //! Returns number of tree level line items = colums in table view
231 virtual int columnCount (const QModelIndex& theParent = QModelIndex()) const Standard_OVERRIDE
232 { (void)theParent; return 26; }
234 //! Returns onlly one row in table view
235 virtual int rowCount (const QModelIndex& theParent = QModelIndex()) const Standard_OVERRIDE
236 { (void)theParent; return 20; }
238 //! Returns color for the delegate kind
239 //! \param theKind kind
241 static QColor GetKindColor (const ViewControl_ColorDelegateKind theKind)
245 case ViewControl_ColorDelegateKind_Activated:
246 case ViewControl_ColorDelegateKind_Highlighted: return Qt::blue;
247 case ViewControl_ColorDelegateKind_Selected: return Qt::black;
254 QModelIndex myCurrentIndex; //!< index to be presented through item delegate
255 ViewControl_ColorDelegateKind myCurrentIndexKind; //!< kind of custom item
258 //! \class DFBrowser_HighlightDelegate
259 //! \brief An item delegate to paint in highlight color the cell when the mouse cursor is over it
260 class ViewControl_OCCTColorDelegate : public QItemDelegate
265 ViewControl_OCCTColorDelegate (QObject* theParent = 0) : QItemDelegate (theParent) {}
268 virtual ~ViewControl_OCCTColorDelegate() Standard_OVERRIDE {}
270 //! Redefine of the parent virtual method to color the cell rectangle in highlight style
271 //! \param thePainter a painter
272 //! \param theOption a paint options
273 //! \param theIndex a view index
274 virtual void paint (QPainter* thePainter, const QStyleOptionViewItem& theOption,
275 const QModelIndex& theIndex) const Standard_OVERRIDE
277 QRect aBaseRect = theOption.rect;
278 int aNameOfColorId = theIndex.row() * theIndex.model()->columnCount(theIndex) + theIndex.column();
279 Quantity_NameOfColor aNameOfColor = Quantity_NOC_WHITE;
280 if (aNameOfColorId < (int)Quantity_NOC_WHITE)
281 aNameOfColor = (Quantity_NameOfColor)aNameOfColorId;
283 Quantity_Color anOCCTColor (aNameOfColor);
284 QColor aQColor = ViewControl_ColorSelector::ColorToQColor (Quantity_ColorRGBA (anOCCTColor));
285 thePainter->fillRect (aBaseRect, aQColor);
289 if (theOption.state & QStyle::State_MouseOver)
290 aColor = ViewControl_OCCTColorModel::GetKindColor (ViewControl_ColorDelegateKind_Highlighted);
293 const ViewControl_OCCTColorModel* aTableModel = dynamic_cast<const ViewControl_OCCTColorModel*> (theIndex.model());
294 QModelIndex anIndex = aTableModel->GetCurrentIndex();
295 if (anIndex.isValid() && anIndex.row() == theIndex.row() && anIndex.column() == theIndex.column())
296 aColor = ViewControl_OCCTColorModel::GetKindColor (aTableModel->GetCurrentIndexKind());
299 if (aColor.isValid())
302 thePainter->fillRect (QRect (aBaseRect.topLeft(), QPoint (aBaseRect.bottomLeft().x() + aRectSize, aBaseRect.bottomLeft().y())),
304 thePainter->fillRect (QRect (QPoint (aBaseRect.topRight().x() - aRectSize, aBaseRect.topRight().y()), aBaseRect.bottomRight()),
306 thePainter->fillRect (QRect (QPoint (aBaseRect.topLeft().x() + aRectSize, aBaseRect.topLeft().y()),
307 QPoint (aBaseRect.topRight().x() - aRectSize, aBaseRect.topRight().y() + aRectSize)),
309 thePainter->fillRect (QRect (QPoint (aBaseRect.bottomLeft().x() + aRectSize, aBaseRect.bottomLeft().y() - aRectSize),
310 QPoint (aBaseRect.bottomRight().x() - aRectSize, aBaseRect.bottomRight().y())),
316 //! Color picker class
317 class ViewControl_ColorPicker : public QWidget
320 ViewControl_ColorPicker (QWidget* theParent) : QWidget (theParent) {}
321 virtual ~ViewControl_ColorPicker() {}
324 // =======================================================================
325 // function : Constructor
327 // =======================================================================
328 ViewControl_ColorSelector::ViewControl_ColorSelector (QWidget* theParent)
329 : QDialog (theParent)
331 QGridLayout* aLayout = new QGridLayout (this);
332 aLayout->setContentsMargins (0, 0, 0, 0);
334 myParameters = new QTableView (this);
335 ViewControl_TableModel* aTableModel = new ViewControl_TableModel (myParameters);
336 aTableModel->SetModelValues (new ViewControl_ParametersModel (this));
337 myParameters->setModel(aTableModel);
339 ViewControl_TableItemDelegate* anItemDelegate = new ViewControl_TableItemDelegate();
340 anItemDelegate->SetModelValues (aTableModel->ModelValues());
341 myParameters->setItemDelegate(anItemDelegate);
343 myParameters->verticalHeader()->setDefaultSectionSize (myParameters->verticalHeader()->minimumSectionSize());
344 myParameters->verticalHeader()->setVisible (false);
345 myParameters->horizontalHeader()->setVisible (false);
346 myParameters->setMinimumHeight (myParameters->verticalHeader()->minimumSectionSize() * aTableModel->rowCount() +
347 TreeModel_Tools::HeaderSectionMargin());
349 QItemSelectionModel* aSelectionModel = new QItemSelectionModel (myParameters->model());
350 myParameters->setSelectionMode (QAbstractItemView::SingleSelection);
351 myParameters->setSelectionModel (aSelectionModel);
353 aLayout->addWidget (myParameters, 0, 0);
355 myColorPicker = new ViewControl_ColorPicker (this);
356 aLayout->addWidget (myColorPicker, 0, 1);
358 myOCCTColors = new QTableView (this);
359 myOCCTColors->setFixedSize (525, 405);
360 myOCCTColors->verticalHeader()->setDefaultSectionSize (20);
361 myOCCTColors->verticalHeader()->setVisible (false);
362 myOCCTColors->horizontalHeader()->setDefaultSectionSize (20);
363 myOCCTColors->horizontalHeader()->setVisible (false);
364 myOCCTColors->setModel(new ViewControl_OCCTColorModel(myOCCTColors));
366 myOCCTColors->viewport()->setAttribute (Qt::WA_Hover);
367 myOCCTColors->setItemDelegate (new ViewControl_OCCTColorDelegate (myOCCTColors));
369 aSelectionModel = new QItemSelectionModel (myOCCTColors->model());
370 myOCCTColors->setSelectionMode (QAbstractItemView::SingleSelection);
371 myOCCTColors->setSelectionModel (aSelectionModel);
372 connect (aSelectionModel, SIGNAL (selectionChanged (const QItemSelection&, const QItemSelection&)),
373 this, SLOT (onOCCTColorsTableSelectionChanged (const QItemSelection&, const QItemSelection&)));
374 aLayout->addWidget (myOCCTColors, 1, 0, 1, 2);
376 QWidget* aBtnWidget = new QWidget (this);
377 aLayout->addWidget (aBtnWidget, 2, 0, 1, 2);
379 QHBoxLayout* aBtnLayout = new QHBoxLayout (aBtnWidget);
380 myOkButton = new QPushButton ("Ok", aBtnWidget);
381 myCancelButton = new QPushButton ("Cancel", aBtnWidget);
382 connect (myOkButton, SIGNAL (clicked()), this, SLOT (accept()));
383 connect (myCancelButton, SIGNAL (clicked()), this, SLOT (reject()));
384 aBtnLayout->addStretch ();
385 aBtnLayout->addWidget (myOkButton);
386 aBtnLayout->addWidget (myCancelButton);
389 // =======================================================================
390 // function : SetStreamValue
392 // =======================================================================
393 void ViewControl_ColorSelector::SetStreamValue (const QString& theValue)
395 Quantity_ColorRGBA aColor = StringToColorRGBA (theValue);
397 ViewControl_TableModel* aTableModel = dynamic_cast<ViewControl_TableModel*> (myParameters->model());
398 ViewControl_ParametersModel* aParametersModel = dynamic_cast<ViewControl_ParametersModel*> (aTableModel->ModelValues());
399 aParametersModel->SetColor (aColor, aTableModel);
402 Quantity_NameOfColor aColorName;
403 bool isExactColorName = ViewControl_ColorSelector::IsExactColorName(aColor, aColorName);
404 ViewControl_OCCTColorModel* anOCCTColorModel = dynamic_cast<ViewControl_OCCTColorModel*>(myOCCTColors->model());
405 anOCCTColorModel->SetColor (aColorName, isExactColorName ? ViewControl_ColorDelegateKind_Selected
406 : ViewControl_ColorDelegateKind_Activated);
409 // =======================================================================
410 // function : GetStreamValue
412 // =======================================================================
413 QString ViewControl_ColorSelector::GetStreamValue() const
415 ViewControl_TableModel* aTableModel = dynamic_cast<ViewControl_TableModel*> (myParameters->model());
416 ViewControl_ParametersModel* aParametersModel = dynamic_cast<ViewControl_ParametersModel*> (aTableModel->ModelValues());
418 Quantity_ColorRGBA aColor = aParametersModel->GetColor();
420 Standard_SStream aStream;
421 aColor.DumpJson (aStream);
423 return Standard_Dump::Text (aStream).ToCString();
426 // =======================================================================
427 // function : ParameterColorChanged
429 // =======================================================================
430 void ViewControl_ColorSelector::ParameterColorChanged()
432 ViewControl_TableModel* aTableModel = dynamic_cast<ViewControl_TableModel*> (myParameters->model());
433 ViewControl_ParametersModel* aParametersModel = dynamic_cast<ViewControl_ParametersModel*> (aTableModel->ModelValues());
434 Quantity_ColorRGBA aColor = aParametersModel->GetColor();
437 Quantity_NameOfColor aColorName;
438 bool isExactColorName = ViewControl_ColorSelector::IsExactColorName(aColor, aColorName);
439 ViewControl_OCCTColorModel* anOCCTColorModel = dynamic_cast<ViewControl_OCCTColorModel*>(myOCCTColors->model());
440 anOCCTColorModel->SetColor (aColorName, isExactColorName ? ViewControl_ColorDelegateKind_Selected
441 : ViewControl_ColorDelegateKind_Activated);
444 // =======================================================================
445 // function : ColorToString
447 // =======================================================================
448 QString ViewControl_ColorSelector::ColorToString (const Quantity_Color& theColor)
450 Standard_Real aRed, aGreen, aBlue;
451 theColor.Values (aRed, aGreen, aBlue, Quantity_TOC_RGB);
452 return QString::number (aRed) + ViewControl_ColorSelector::ColorSeparator() +
453 QString::number (aGreen) + ViewControl_ColorSelector::ColorSeparator() +
454 QString::number (aBlue);
457 // =======================================================================
458 // function : ColorToQColor
460 // =======================================================================
461 QColor ViewControl_ColorSelector::ColorToQColor (const Quantity_ColorRGBA& theColor)
465 Standard_Real aRed, aGreen, aBlue;
466 theColor.GetRGB().Values (aRed, aGreen, aBlue, Quantity_TOC_RGB);
468 return QColor((int)(aRed * aDelta), (int)(aGreen * aDelta), (int)(aBlue * aDelta));
471 // =======================================================================
472 // function : StringToColorRGBA
474 // =======================================================================
475 Quantity_ColorRGBA ViewControl_ColorSelector::StringToColorRGBA (const QString& theColor)
477 Quantity_ColorRGBA aColorRGBA;
478 Standard_SStream aStream;
479 aStream << theColor.toStdString();
481 aColorRGBA.InitFromJson (aStream, aStreamPos);
485 // =======================================================================
486 // function : IsExactColorName
488 // =======================================================================
489 Standard_Boolean ViewControl_ColorSelector::IsExactColorName (const Quantity_ColorRGBA& theColor,
490 Quantity_NameOfColor& theColorName)
492 theColorName = theColor.GetRGB().Name();
493 return Quantity_Color (theColorName).IsEqual (theColor.GetRGB());
496 // =======================================================================
497 // function : onOCCTColorsTableSelectionChanged
499 // =======================================================================
500 void ViewControl_ColorSelector::onOCCTColorsTableSelectionChanged (const QItemSelection& theSelected, const QItemSelection&)
502 QModelIndexList aSelectedIndices = theSelected.indexes();
503 if (aSelectedIndices.size() != 1)
506 ViewControl_OCCTColorModel* anOCCTColorModel = dynamic_cast<ViewControl_OCCTColorModel*>(myOCCTColors->model());
507 Quantity_NameOfColor aNameOfColor;
508 if (!anOCCTColorModel->GetOCCTColor (aSelectedIndices.first(), aNameOfColor))
511 anOCCTColorModel->SetColor (aNameOfColor, ViewControl_ColorDelegateKind_Selected);
514 ViewControl_TableModel* aTableModel = dynamic_cast<ViewControl_TableModel*> (myParameters->model());
515 ViewControl_ParametersModel* aParametersModel = dynamic_cast<ViewControl_ParametersModel*> (aTableModel->ModelValues());
516 Quantity_Color anOCCTColor (aNameOfColor);
517 aParametersModel->SetColor (Quantity_ColorRGBA (anOCCTColor), aTableModel);