]> OCCT Git - occt-copy.git/commitdiff
0030268: Inspectors - improvements in VInspector plugin
authornds <natalia.ermolaeva@opencascade.com>
Mon, 6 Jul 2020 16:37:38 +0000 (19:37 +0300)
committernds <natalia.ermolaeva@opencascade.com>
Mon, 6 Jul 2020 17:00:53 +0000 (20:00 +0300)
- lights for V3d viewer.

(cherry picked from commit 4e976db17b66b027566bcb3888b20b961cd67f7c)

31 files changed:
tools/Convert/Convert_Tools.cxx
tools/Convert/Convert_Tools.hxx
tools/TInspectorEXE/TInspectorEXE.cxx
tools/TreeModel/TreeModel_ItemBase.hxx
tools/TreeModel/TreeModel_ItemProperties.cxx
tools/TreeModel/TreeModel_ItemStream.cxx
tools/TreeModel/TreeModel_ItemStream.hxx
tools/VInspector/FILES
tools/VInspector/VInspector_ItemContextProperties.cxx
tools/VInspector/VInspector_ItemGraphic3dCLight.cxx [new file with mode: 0644]
tools/VInspector/VInspector_ItemGraphic3dCLight.hxx [new file with mode: 0644]
tools/VInspector/VInspector_PresentationLight.cxx [new file with mode: 0644]
tools/VInspector/VInspector_PresentationLight.hxx [new file with mode: 0644]
tools/VInspector/VInspector_Window.cxx
tools/VInspector/VInspector_Window.hxx
tools/View/View_DisplayPreview.cxx
tools/View/View_DisplayPreview.hxx
tools/View/View_Displayer.cxx
tools/View/View_PreviewParameters.cxx
tools/View/View_PreviewParameters.hxx
tools/View/View_ToolButton.hxx
tools/ViewControl/FILES
tools/ViewControl/ViewControl_ColorSelector.cxx [new file with mode: 0644]
tools/ViewControl/ViewControl_ColorSelector.hxx [new file with mode: 0644]
tools/ViewControl/ViewControl_EditType.hxx
tools/ViewControl/ViewControl_Table.cxx
tools/ViewControl/ViewControl_TableItemDelegate.cxx [new file with mode: 0644]
tools/ViewControl/ViewControl_TableItemDelegate.hxx [new file with mode: 0644]
tools/ViewControl/ViewControl_TableModelValues.hxx
tools/ViewControl/ViewControl_Tools.cxx
tools/ViewControl/ViewControl_Tools.hxx

index 67803f24944f68966f014a3095e72f7a0a763443..58665d235cfde0424fdaaf211a6ff2382d0e413b 100644 (file)
 #include <inspector/Convert_Tools.hxx>
 #include <inspector/Convert_TransientShape.hxx>
 
+#include <AIS_Line.hxx>
 #include <AIS_Plane.hxx>
 #include <AIS_Shape.hxx>
 #include <gp_XY.hxx>
+#include <Geom_Line.hxx>
 #include <Geom_Plane.hxx>
 #include <Prs3d_PlaneAspect.hxx>
 #include <TColgp_Array1OfPnt.hxx>
@@ -71,7 +73,10 @@ void Convert_Tools::ConvertStreamToPresentations (const Standard_SStream& theSSt
   gp_Dir aDir;
   if (aDir.InitFromJson (theSStream, aStartPos))
   {
-    thePresentations.Append (new Convert_TransientShape (BRepBuilderAPI_MakeEdge (gp::Origin(), aDir.XYZ())));
+    gp_Lin aLin (gp::Origin(), aDir);
+    Handle(Geom_Line) aGeomLine = new Geom_Line (aLin);
+    //thePresentations.Append (new Convert_TransientShape (BRepBuilderAPI_MakeEdge (gp::Origin(), aDir.XYZ())));
+    CreatePresentation (aGeomLine, thePresentations);
     return;
   }
 
@@ -259,6 +264,18 @@ Standard_Boolean Convert_Tools::CreateBoxShape (const gp_Pnt& thePntMin, const g
   }
 }
 
+//=======================================================================
+//function : CreatePresentation
+//purpose  :
+//=======================================================================
+void Convert_Tools::CreatePresentation (const Handle(Geom_Line)& theLine,
+                                        NCollection_List<Handle(Standard_Transient)>& thePresentations)
+{
+  Handle(AIS_Line) aLinePrs = new AIS_Line (theLine);
+  aLinePrs->SetColor (Quantity_NOC_TOMATO);
+  thePresentations.Append (aLinePrs);
+}
+
 //=======================================================================
 //function : CreatePresentation
 //purpose  :
index bdcd05c09bd4916f7c62a3446d224aa858b252e8..6e6fcbb1a7f1f82308acce7a37d2019eec68ba3b 100644 (file)
@@ -38,6 +38,7 @@
 #include <QVariant>
 #include <Standard_WarningsRestore.hxx>
 
+class Geom_Line;
 class Geom_Plane;
 class Geom_Transformation;
 
@@ -83,6 +84,12 @@ public:
   //! \return created shape
   Standard_EXPORT static Standard_Boolean CreateBoxShape (const gp_Pnt& thePntMin, const gp_Pnt& thePntMax, TopoDS_Shape& theShape);
 
+  //! Creates presentation AIS_Line
+  //! \param theLine source line
+  //! \param thePresentations container to collect new presentation/s
+  Standard_EXPORT static void CreatePresentation (const Handle(Geom_Line)& theLine,
+    NCollection_List<Handle(Standard_Transient)>& thePresentations);
+
   //! Creates presentation AIS_Plane
   //! \param thePlane source plane
   //! \param thePresentations container to collect new presentation/s
index 2c1aac570a025e473e8e59ae5d6d1a8367336f51..a1eb2e70320554f4282afd27ed990ae299c892f1 100644 (file)
@@ -132,10 +132,10 @@ int main (int argc, char** argv)
     aReport->SetLimit (100);//30);
     aPlugins.insert("TKMessageView");
 
-    //anActivatedPluginName = "TKVInspector";
+    anActivatedPluginName = "TKVInspector";
     //anActivatedPluginName = "TKMessageView";
     //anActivatedPluginName = "TKDFBrowser";
-    anActivatedPluginName = "TKShapeView";
+    //anActivatedPluginName = "TKShapeView";
   }
   else
     anActivatedPluginName = *aPlugins.rbegin();
index 8654b068762038a3c562f98fa87bfe421afaca36..94263cf523b873d2b0b364fed79b57dda00c221c 100644 (file)
@@ -150,6 +150,10 @@ public:
   //! Returns the item properties
   const Handle(TreeModel_ItemProperties)& Properties() const { return myProperties; }
 
+  //! Updates item by the item properties value
+  virtual void UpdatePropertiesData (const int theRow, const int theColumn, const QVariant& theValue)
+    { (void)theRow, (void)theColumn; (void)theValue; }
+
   //! Returns presentation of the attribute to be visualized in the view
   //! \thePresentations [out] container of presentation handles to be visualized
   Standard_EXPORT virtual void Presentations (NCollection_List<Handle(Standard_Transient)>& thePresentations);
index 8aa7a0d81d3cfdca9cb95f3c1754bd389e726486..84d132519b8bc0eb74f4245e9ead63c7cab6964f 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <BRepBuilderAPI_MakeVertex.hxx>
 #include <gp_XYZ.hxx>
+#include <Quantity_ColorRGBA.hxx>
 #include <Standard_Dump.hxx>
 
 #include <Standard_WarningsDisable.hxx>
@@ -186,9 +187,40 @@ ViewControl_EditType TreeModel_ItemProperties::EditType (const int, const int th
   if (theColumn == 0)
     return ViewControl_EditType_None;
 
+  Quantity_Color aColor;
+  const Standard_SStream& aStream = Item()->Stream();
+  if (Convert_Tools::ConvertStreamToColor (aStream, aColor))
+  {
+    return ViewControl_EditType_Color;
+  }
+
   return ViewControl_EditType_Line;
 }
 
+// =======================================================================
+// function : ReplaceValue
+// purpose :
+// =======================================================================
+Standard_Boolean ReplaceValue(const TCollection_AsciiString& theFromValue,
+                              const TCollection_AsciiString& theToValue,
+                              Standard_DumpValue& theStreamValue)
+{
+  //TCollection_AsciiString myValue; //!< current string value
+  //Standard_Integer myStartPosition; //!< position of the value first char in the whole stream
+
+  TCollection_AsciiString aStreamValue = theStreamValue.myValue;
+  int aFromLength = theFromValue.Length();
+
+  int aPosition = aStreamValue.FirstLocationInSet (theFromValue, 1, aStreamValue.Length());
+  if (aPosition < 1)
+    return Standard_False;
+
+  aStreamValue.Remove (aPosition + 2, aFromLength);
+  aStreamValue.Insert (aPosition + 2, theToValue);
+  theStreamValue.myValue = aStreamValue;
+  return Standard_True;
+}
+
 // =======================================================================
 // function : SetData
 // purpose :
@@ -198,12 +230,54 @@ bool TreeModel_ItemProperties::SetData (const int theRow, const int theColumn, c
   if (theColumn == 0)
     return false;
 
-  if (theRole == Qt::DisplayRole || theRole == Qt::EditRole)
+  if (theRole != Qt::DisplayRole && theRole != Qt::EditRole)
+    return false;
+
+  if (myRowValues.Size() == 1 && theColumn == 1)
   {
-    myRowValues.ChangeFromIndex (theRow + 1).Value = theValue;
+    TCollection_AsciiString aStreamValue (theValue.toString().toStdString().c_str());
+    NCollection_IndexedDataMap<TCollection_AsciiString, Standard_DumpValue> aKeyToValues;
+    if (Standard_Dump::SplitJson (aStreamValue, aKeyToValues))
+    {
+      Standard_SStream aStream;
+      aStream << aStreamValue.ToCString();
+
+      int aStartPos = 1;
+      Quantity_ColorRGBA aColor;
+      if (aColor.InitFromJson (aStream, aStartPos))
+      {
+        Standard_Real aRed, aGreen, aBlue;
+        aColor.GetRGB().Values (aRed, aGreen, aBlue, Quantity_TOC_sRGB);
+        int aDelta = 255;
+        myRowValues.ChangeFromIndex (1).CustomValues.insert ((int)Qt::BackgroundRole, QColor((int)(aRed * aDelta),
+          (int)(aGreen * aDelta), (int)(aBlue * aDelta)));
+      }
+      Standard_DumpValue aValue = aKeyToValues.FindFromIndex (1);
+      myStreamValue.myValue = aValue.myValue.ToCString();
+      myRowValues.ChangeFromIndex (1).Value = aValue.myValue.ToCString();
+
+      Item()->UpdatePropertiesData (theRow, theColumn, theValue);
+      return true;
+    }
+    TCollection_AsciiString aFromValue = myRowValues.ChangeFromIndex (1).Value.toString().toStdString().c_str();
+    if (ReplaceValue(aFromValue, aStreamValue, myStreamValue))
+    {
+      aStreamValue = myStreamValue.myValue;
+      if (Standard_Dump::SplitJson (aStreamValue, aKeyToValues))
+      {
+        Standard_DumpValue aValue = aKeyToValues.FindFromIndex (1);
+        myStreamValue.myValue = aValue.myValue.ToCString();
+        myRowValues.ChangeFromIndex (1).Value = aValue.myValue.ToCString();
+
+        Item()->UpdatePropertiesData (theRow, theColumn, aStreamValue.ToCString());
+        return true;
+      }
+    }
   }
 
-  return false;
+  myRowValues.ChangeFromIndex (theRow + 1).Value = theValue;
+  Item()->UpdatePropertiesData (theRow, theColumn, theValue);
+  return true;
 }
 
 // =======================================================================
index efa8b36d532ebe6623941886ec5792cc9979966f..e01d581a353ad202d795559f8c1a9c56e93691d8 100644 (file)
@@ -87,6 +87,15 @@ QVariant TreeModel_ItemStream::initValue (const int theItemRole) const
   return QVariant();
 }
 
+// =======================================================================
+// function : UpdatePropertiesData
+// purpose :
+// =======================================================================
+void TreeModel_ItemStream::UpdatePropertiesData (const int, const int, const QVariant& theValue)
+{
+  Parent()->UpdatePropertiesData (-1, -1, theValue);
+}
+
 // =======================================================================
 // function : initStream
 // purpose :
index 3d3f13ea3c8805853cda9b4d365a2e95b47f05db..daff9254aa6fc2d5ec1dfbe496f6252b0c60cdff 100644 (file)
@@ -60,6 +60,9 @@ public:
   //! \return the value
   Standard_EXPORT virtual QVariant initValue (const int theItemRole) const Standard_OVERRIDE;
 
+  //! Updates item by the item properties value
+  Standard_EXPORT virtual void UpdatePropertiesData (const int theRow, const int theColumn, const QVariant& theValue) Standard_OVERRIDE;
+
 protected:
   //! Returns stream value of the item to fulfill property panel.
   //! \return stream value or dummy
index 85d375571085a670727c7609309990203147d725..a2b280e3f76cd2c97bcb6a260413e7667fbfbd45 100644 (file)
@@ -12,6 +12,8 @@ VInspector_ItemContext.cxx
 VInspector_ItemContext.hxx
 VInspector_ItemContextProperties.cxx
 VInspector_ItemContextProperties.hxx
+VInspector_ItemGraphic3dCLight.cxx
+VInspector_ItemGraphic3dCLight.hxx
 VInspector_ItemHistoryElement.cxx
 VInspector_ItemHistoryElement.hxx
 VInspector_ItemHistoryRoot.cxx
@@ -25,6 +27,8 @@ VInspector_ItemSelectMgrViewerSelector.cxx
 VInspector_ItemSelectMgrViewerSelector.hxx
 VInspector_ItemV3dViewer.cxx
 VInspector_ItemV3dViewer.hxx
+VInspector_PresentationLight.cxx
+VInspector_PresentationLight.hxx
 VInspector_ToolActionType.hxx
 VInspector_ToolBar.cxx
 VInspector_ToolBar.hxx
index 020d02821cb609f3072d307573503f03a1162e82..c61881977bcdf3678bad7515f5d61f65f7a2442c 100644 (file)
 #include <inspector/VInspector_ItemContextProperties.hxx>
 
 #include <inspector/VInspector_ItemContext.hxx>
+#include <inspector/VInspector_ItemGraphic3dCLight.hxx>
 #include <inspector/VInspector_ItemV3dViewer.hxx>
 #include <inspector/VInspector_ItemSelectMgrViewerSelector.hxx>
 
+#include <V3d_View.hxx>
+#include <V3d_Viewer.hxx>
+
 // =======================================================================
 // function : initValue
 // purpose :
@@ -41,7 +45,26 @@ QVariant VInspector_ItemContextProperties::initValue (int theItemRole) const
 // =======================================================================
 int VInspector_ItemContextProperties::initRowCount() const
 {
-  return 2; // V3d_Viewer, SelectMgr_ViewerSelector
+  int aLightsCount = 0;
+
+  VInspector_ItemContextPtr aParentContextItem = itemDynamicCast<VInspector_ItemContext>(Parent());
+  if (aParentContextItem)
+  {
+    Handle(AIS_InteractiveContext) aContext = aParentContextItem->GetContext();
+    Handle(V3d_Viewer) aViewer = aContext->CurrentViewer();
+    if (!aViewer.IsNull())
+    {
+      if (!aViewer->ActiveViews().IsEmpty())
+      {
+        Handle(V3d_View) aView = aViewer->ActiveViews().First();
+        if (!aView.IsNull())
+          aLightsCount = aView->ActiveLights().Extent();
+      }
+    }
+  }
+
+
+  return 2 + aLightsCount; // V3d_Viewer, SelectMgr_ViewerSelector
 }
 
 // =======================================================================
@@ -52,8 +75,12 @@ TreeModel_ItemBasePtr VInspector_ItemContextProperties::createChild (int theRow,
 {
   if (theRow == 0)
     return VInspector_ItemV3dViewer::CreateItem (currentItem(), theRow, theColumn);
-
-  return VInspector_ItemSelectMgrViewerSelector::CreateItem (currentItem(), theRow, theColumn);
+  else if (theRow == 1)
+    return VInspector_ItemSelectMgrViewerSelector::CreateItem (currentItem(), theRow, theColumn);
+  else // lights
+  {
+    return VInspector_ItemGraphic3dCLight::CreateItem (currentItem(), theRow, theColumn);
+  }
 }
 
 // =======================================================================
diff --git a/tools/VInspector/VInspector_ItemGraphic3dCLight.cxx b/tools/VInspector/VInspector_ItemGraphic3dCLight.cxx
new file mode 100644 (file)
index 0000000..37ace6b
--- /dev/null
@@ -0,0 +1,256 @@
+// Created on: 2020-06-29
+// Created by: Natalia ERMOLAEVA
+// Copyright (c) 2020 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement. 
+
+#include <inspector/VInspector_ItemGraphic3dCLight.hxx>
+
+#include <AIS.hxx>
+#include <AIS_InteractiveContext.hxx>
+#include <inspector/VInspector_ItemContext.hxx>
+#include <inspector/VInspector_ItemContextProperties.hxx>
+#include <inspector/VInspector_PresentationLight.hxx>
+#include <inspector/TreeModel_ItemProperties.hxx>
+
+#include <V3d_View.hxx>
+#include <V3d_Viewer.hxx>
+
+// =======================================================================
+// function : initRowCount
+// purpose :
+// =======================================================================
+int VInspector_ItemGraphic3dCLight::initRowCount() const
+{
+  return 0;
+}
+
+// =======================================================================
+// function : initValue
+// purpose :
+// =======================================================================
+QVariant VInspector_ItemGraphic3dCLight::initValue (const int theItemRole) const
+{
+  QVariant aParentValue = VInspector_ItemBase::initValue (theItemRole);
+  if (aParentValue.isValid())
+    return aParentValue;
+
+  if (theItemRole == Qt::ForegroundRole)
+  {
+    if (GetLight().IsNull())
+      return QVariant();
+
+    if (!GetLight()->IsEnabled())
+      return QColor(Qt::darkGray);
+
+    return QVariant();
+  }
+
+  if (theItemRole != Qt::DisplayRole && theItemRole != Qt::EditRole && theItemRole != Qt::ToolTipRole)
+    return QVariant();
+
+  if (GetLight().IsNull())
+    return Column() == 0 ? "Empty light" : "";
+
+  if (Column() != 0)
+    return QVariant();
+
+  switch (GetLight()->Type())
+  {
+    case Graphic3d_TOLS_AMBIENT:     return "Ambient light";
+    case Graphic3d_TOLS_DIRECTIONAL: return "Directional light";
+    case Graphic3d_TOLS_POSITIONAL:  return "Positional light";
+    case Graphic3d_TOLS_SPOT:        return "Spot light";
+    default: break;
+  }
+  //return Column() == 0 ? GetLight()->DynamicType()->Name() : QVariant();
+}
+
+// =======================================================================
+// function : Init
+// purpose :
+// =======================================================================
+void VInspector_ItemGraphic3dCLight::Init()
+{
+  VInspector_ItemContextPropertiesPtr aParentItem = itemDynamicCast<VInspector_ItemContextProperties>(Parent());
+  Handle(Graphic3d_CLight) aLight;
+  if (aParentItem)
+  {
+    VInspector_ItemContextPtr aParentContextItem = itemDynamicCast<VInspector_ItemContext>(aParentItem->Parent());
+    if (aParentContextItem)
+    {
+      Handle(AIS_InteractiveContext) aContext = aParentContextItem->GetContext();
+      Handle(V3d_Viewer) aViewer = aContext->CurrentViewer();
+      if (!aViewer.IsNull())
+      {
+        int aLightId = Row() - 2 /*in parent*/;
+        int aCurrentId = 0;
+        for (V3d_ListOfLightIterator aLightsIt (aViewer->ActiveLightIterator()); aLightsIt.More(); aLightsIt.Next(), aCurrentId++)
+        {
+          if (aCurrentId != aLightId)
+            continue;
+          aLight = aLightsIt.Value();
+        }
+      }
+    }
+  }
+  myLight = aLight;
+  TreeModel_ItemBase::Init();
+}
+
+// =======================================================================
+// function : Reset
+// purpose :
+// =======================================================================
+void VInspector_ItemGraphic3dCLight::Reset()
+{
+  VInspector_ItemBase::Reset();
+
+  myLight = NULL;
+}
+
+// =======================================================================
+// function : Presentations
+// purpose :
+// =======================================================================
+void VInspector_ItemGraphic3dCLight::Presentations (NCollection_List<Handle(Standard_Transient)>& thePresentations)
+{
+  TreeModel_ItemBase::Presentations (thePresentations); 
+
+  if (Column() != 0)
+    return;
+
+  Handle(Graphic3d_CLight) aLight = GetLight();
+  if (aLight.IsNull())
+    return;
+
+  Handle(VInspector_PresentationLight) aPresentation = new VInspector_PresentationLight();
+  aPresentation->SetLight (aLight);
+
+  thePresentations.Append (aPresentation);
+}
+
+// =======================================================================
+// function : initItem
+// purpose :
+// =======================================================================
+void VInspector_ItemGraphic3dCLight::UpdatePropertiesData (const int theRow, const int theColumn, const QVariant& theValue)
+{
+  if (myLight.IsNull())
+    return;
+
+  const Handle(TreeModel_ItemProperties)& aProperties = Properties();
+  if (theRow == -1 && theColumn == -1) // processing sub-item value
+  {
+    Standard_SStream aStream;
+    aStream << theValue.toString().toStdString().c_str();
+
+    int aStartPos = 1;
+    Quantity_ColorRGBA aColor;
+    if (aColor.InitFromJson (aStream, aStartPos))
+    {
+      myLight->SetColor (aColor.GetRGB());
+      return;
+    }
+
+    // "Direction"
+    gp_Dir aDir;
+    if (aDir.InitFromJson (aStream, aStartPos))
+    {
+      myLight->SetDirection (aDir);
+      return;
+    }
+
+    // "Position"
+    gp_Pnt aPnt;
+    if (aPnt.InitFromJson (aStream, aStartPos))
+    {
+      myLight->SetPosition (aPnt);
+      return;
+    }
+  }
+
+  QString aPropertyName = aProperties->Data(theRow, 0).toString();
+  QVariant aPropertyValue = aProperties->Data(theRow, 1);
+  if (aPropertyName == "Position")
+  {
+  }
+  else if (aPropertyName == "Intensity")
+  {
+    myLight->SetIntensity ((Standard_ShortReal)aPropertyValue.toReal());
+  }
+  else if (aPropertyName == "ConstAttenuation")
+  {
+    myLight->SetAttenuation ((Standard_ShortReal)aPropertyValue.toReal(),
+                             (Standard_ShortReal)aProperties->Data(theRow + 1, 1).toReal());
+  }
+  else if (aPropertyName == "LinearAttenuation")
+  {
+    myLight->SetAttenuation ((Standard_ShortReal)aProperties->Data(theRow - 1, 1).toReal(),
+                             (Standard_ShortReal)aPropertyValue.toReal());
+  }
+  else if (aPropertyName == "Angle")
+  {
+    myLight->SetAngle ((Standard_ShortReal)aPropertyValue.toReal());
+  }
+  else if (aPropertyName == "Concentration")
+  {
+    myLight->SetConcentration ((Standard_ShortReal)aPropertyValue.toReal());
+  }
+  else if (aPropertyName == "Range")
+  {
+    myLight->SetRange ((Standard_ShortReal)aPropertyValue.toReal());
+  }
+  else if (aPropertyName == "Smoothness")
+  {
+    if (myLight->Type() == Graphic3d_TOLS_DIRECTIONAL)
+    {
+      myLight->SetSmoothAngle ((Standard_ShortReal)aPropertyValue.toReal());
+    }
+    else
+    {
+      myLight->SetSmoothRadius ((Standard_ShortReal)aPropertyValue.toReal());
+    }
+  }
+  else if (aPropertyName == "IsHeadlight")
+  {
+    myLight->SetHeadlight (aPropertyValue.toInt() == 1);
+  }
+  else if (aPropertyName == "IsEnabled")
+  {
+    myLight->SetEnabled (aPropertyValue.toInt() == 1);
+  }
+}
+
+// =======================================================================
+// function : initItem
+// purpose :
+// =======================================================================
+void VInspector_ItemGraphic3dCLight::initItem() const
+{
+  if (IsInitialized())
+    return;
+  const_cast<VInspector_ItemGraphic3dCLight*>(this)->Init();
+}
+
+// =======================================================================
+// function : initStream
+// purpose :
+// =======================================================================
+void VInspector_ItemGraphic3dCLight::initStream (Standard_OStream& theOStream) const
+{
+  Handle(Graphic3d_CLight) aLight = GetLight();
+  if (aLight.IsNull())
+    return;
+
+  aLight->DumpJson (theOStream);
+}
diff --git a/tools/VInspector/VInspector_ItemGraphic3dCLight.hxx b/tools/VInspector/VInspector_ItemGraphic3dCLight.hxx
new file mode 100644 (file)
index 0000000..6cebf7a
--- /dev/null
@@ -0,0 +1,92 @@
+// Created on: 2020-06-29
+// Created by: Natalia ERMOLAEVA
+// Copyright (c) 2020 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement. 
+
+#ifndef VInspector_ItemGraphic3dCLight_H
+#define VInspector_ItemGraphic3dCLight_H
+
+#include <Standard.hxx>
+#include <inspector/VInspector_ItemBase.hxx>
+
+#include <Graphic3d_CLight.hxx>
+
+class VInspector_ItemGraphic3dCLight;
+typedef QExplicitlySharedDataPointer<VInspector_ItemGraphic3dCLight> VInspector_ItemGraphic3dCLightPtr;
+
+//! \class VInspector_ItemGraphic3dCLight
+//! Parent item is context properties, that corresponds to AIS_InteractiveContext
+class VInspector_ItemGraphic3dCLight : public VInspector_ItemBase
+{
+public:
+
+  //! Creates an item wrapped by a shared pointer
+  static VInspector_ItemGraphic3dCLightPtr CreateItem (TreeModel_ItemBasePtr theParent, const int theRow, const int theColumn)
+  { return VInspector_ItemGraphic3dCLightPtr (new VInspector_ItemGraphic3dCLight (theParent, theRow, theColumn)); }
+
+  //! Destructor
+  virtual ~VInspector_ItemGraphic3dCLight() Standard_OVERRIDE {};
+
+  //! Inits the item, fills internal containers
+  Standard_EXPORT virtual void Init() Standard_OVERRIDE;
+
+  //! Resets cached values
+  Standard_EXPORT virtual void Reset() Standard_OVERRIDE;
+
+  //! Returns data object of the item.
+  //! \return object
+  virtual const Handle(Standard_Transient)& Object() const { initItem(); return myLight; }
+
+  //! Returns the current light, init item if it was not initialized yet
+  //! \return interactive object
+  Handle(Graphic3d_CLight) GetLight() const { return Handle(Graphic3d_CLight)::DownCast (Object()); }
+
+  //! Returns presentation of the attribute to be visualized in the view
+  //! \thePresentations [out] container of presentation handles to be visualized
+  Standard_EXPORT virtual void Presentations (NCollection_List<Handle(Standard_Transient)>& thePresentations) Standard_OVERRIDE;
+
+  //! Updates item by the item properties value
+  virtual void UpdatePropertiesData (const int theRow, const int theColumn, const QVariant& theValue) Standard_OVERRIDE;
+
+protected:
+  //! Initializes the current item. It is empty because Reset() is also empty.
+  virtual void initItem() const Standard_OVERRIDE;
+
+  //! Returns number of displayed presentations
+  //! \return rows count
+  Standard_EXPORT virtual int initRowCount() const Standard_OVERRIDE;
+
+  //! Returns item information for the given role. Fills internal container if it was not filled yet
+  //! \param theItemRole a value role
+  //! \return the value
+  Standard_EXPORT virtual QVariant initValue (const int theItemRole) const Standard_OVERRIDE;
+
+  //! Returns stream value of the item to fulfill property panel.
+  //! \return stream value or dummy
+  Standard_EXPORT virtual void initStream (Standard_OStream& theOStream) const Standard_OVERRIDE;
+
+private:
+
+  //! Constructor
+  //! param theParent a parent item
+  //! \param theRow the item row positition in the parent item
+  //! \param theColumn the item column positition in the parent item
+  VInspector_ItemGraphic3dCLight(TreeModel_ItemBasePtr theParent, const int theRow, const int theColumn)
+    : VInspector_ItemBase(theParent, theRow, theColumn) {}
+
+protected:
+
+  Handle(Graphic3d_CLight) myLight; //!< the current light
+};
+
+#endif
diff --git a/tools/VInspector/VInspector_PresentationLight.cxx b/tools/VInspector/VInspector_PresentationLight.cxx
new file mode 100644 (file)
index 0000000..5b3851a
--- /dev/null
@@ -0,0 +1,451 @@
+// Created on: 2020-07-04
+// Created by: Natalia ERMOLAEVA
+// Copyright (c) 2020 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement. 
+
+#include <inspector/VInspector_PresentationLight.hxx>
+#include <inspector/View_DisplayPreview.hxx>
+#include <inspector/View_PreviewParameters.hxx>
+
+#include <Extrema_ExtElC.hxx>
+#include <Geom_Line.hxx>
+#include <GeomAdaptor_Curve.hxx>
+#include <Graphic3d_ArrayOfPoints.hxx>
+#include <Graphic3d_ArrayOfTriangles.hxx>
+#include <Graphic3d_CLight.hxx>
+
+#include <AIS_InteractiveContext.hxx>
+#include <PrsDim.hxx>
+#include <Prs3d_Arrow.hxx>
+#include <Prs3d_PointAspect.hxx>
+#include <Prs3d_Root.hxx>
+#include <Prs3d_ShadingAspect.hxx>
+#include <Prs3d_ToolSphere.hxx>
+#include <SelectMgr_EntityOwner.hxx>
+#include <Select3D_SensitiveSegment.hxx>
+#include <Select3D_SensitiveTriangulation.hxx>
+#include <StdPrs_Curve.hxx>
+#include <V3d_View.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT(VInspector_PresentationLight, AIS_InteractiveObject)
+
+static const Standard_Integer THE_NB_ARROW_FACETTES = 20;
+
+class VInspector_PresentationLightOwner : public SelectMgr_EntityOwner
+{
+  DEFINE_STANDARD_RTTIEXT(VInspector_PresentationLightOwner, SelectMgr_EntityOwner)
+
+public:
+  VInspector_PresentationLightOwner (const Handle(SelectMgr_SelectableObject)& theSelectable,
+                                     const Standard_Integer theMode,
+                                     const Standard_Integer thePriority = 0)
+  : SelectMgr_EntityOwner (theSelectable, thePriority), myMode (theMode) {}
+
+  //! Highlights selectable object's presentation with display mode in presentation manager with given highlight style.
+  Standard_EXPORT virtual void HilightWithColor (const Handle(PrsMgr_PresentationManager)& thePrsMgr,
+                                                 const Handle(Prs3d_Drawer)& theStyle,
+                                                 const Standard_Integer theMode) Standard_OVERRIDE
+  {
+    Handle(VInspector_PresentationLight) aLightPrs = Handle(VInspector_PresentationLight)::DownCast(Selectable());
+    if (!aLightPrs.IsNull())
+    {
+      aLightPrs->SetTranslateMode (myMode);
+    }
+    SelectMgr_EntityOwner::HilightWithColor (thePrsMgr, theStyle, theMode);
+  }
+
+private:
+  Standard_Integer myMode; //!< selection mode
+};
+
+IMPLEMENT_STANDARD_RTTIEXT(VInspector_PresentationLightOwner, SelectMgr_EntityOwner)
+
+// =======================================================================
+// function : Constructor
+// purpose :
+// =======================================================================
+VInspector_PresentationLight::VInspector_PresentationLight()
+: AIS_InteractiveObject(),
+  myIndent (200), myTranslateMode (0/*position*/), myHasStartedTransformation (Standard_False)
+{
+  View_PreviewParameters aPreviewParameters (false);
+  SetAttributes (aPreviewParameters.GetDrawer());
+}
+
+// =======================================================================
+// function : SetLight
+// purpose :
+// =======================================================================
+void VInspector_PresentationLight::SetLight (const Handle(Graphic3d_CLight)& theLight)
+{
+  myLight = theLight;
+}
+
+// =======================================================================
+// function : Compute
+// purpose :
+// =======================================================================
+void VInspector_PresentationLight::Compute (const Handle(PrsMgr_PresentationManager3d)&,
+                                            const Handle(Prs3d_Presentation)& thePrs,
+                                            const Standard_Integer)
+{
+  if (myLight.IsNull())
+    return;
+
+  switch (myLight->Type())
+  {
+    case Graphic3d_TOLS_AMBIENT:     break;
+    case Graphic3d_TOLS_DIRECTIONAL: drawDirectionalLight (thePrs); break;
+    case Graphic3d_TOLS_POSITIONAL:  drawPositionalLight (thePrs); break;
+    case Graphic3d_TOLS_SPOT:        drawSpotLigth (thePrs); break;
+    default: break;
+  }
+}
+
+// =======================================================================
+// function : ComputeSelection
+// purpose :
+// =======================================================================
+void VInspector_PresentationLight::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
+                                                     const Standard_Integer theMode)
+{
+  if (theMode != View_DisplayPreview::PreviewSelectionMode())
+    return;
+
+  if (myLight.IsNull())
+    return;
+
+  switch (myLight->Type())
+  {
+    case Graphic3d_TOLS_DIRECTIONAL:
+    case Graphic3d_TOLS_POSITIONAL:
+    case Graphic3d_TOLS_SPOT:
+    {
+      selectDirectionalLight (theSelection);
+      break;
+    }
+    case Graphic3d_TOLS_AMBIENT:
+    default: break;
+  }
+}
+
+// =======================================================================
+// function : HasActiveMode
+// purpose :
+// =======================================================================
+Standard_Boolean VInspector_PresentationLight::HasActiveMode() const
+{
+  return Standard_True;
+}
+
+// =======================================================================
+// function : StartTransform
+// purpose :
+// =======================================================================
+void VInspector_PresentationLight::StartTransform (const Standard_Integer theX,
+                                                   const Standard_Integer theY,
+                                                   const Handle(V3d_View)& theView)
+{
+  if (myHasStartedTransformation)
+  {
+    return;
+  }
+  if (doTranslate (theX, theY, theView))
+    myHasStartedTransformation = Standard_True;
+
+  if (GetContext())
+  {
+    GetContext()->Deactivate (this, View_DisplayPreview::PreviewSelectionMode());
+  }
+}
+
+// =======================================================================
+// function : StopTransform
+// purpose :
+// =======================================================================
+void VInspector_PresentationLight::StopTransform (const Standard_Boolean)
+{
+  myHasStartedTransformation = Standard_False;
+  if (GetContext())
+  {
+    GetContext()->Activate (this, View_DisplayPreview::PreviewSelectionMode());
+  }
+}
+
+// =======================================================================
+// function : Transform
+// purpose :
+// =======================================================================
+gp_Trsf VInspector_PresentationLight::Transform (const Standard_Integer theX,
+                                                 const Standard_Integer theY,
+                                                 const Handle(V3d_View)& theView)
+{
+  if (myLight.IsNull() || !myHasStartedTransformation)
+    return gp_Trsf();
+
+  doTranslate (theX, theY, theView);
+  return gp_Trsf();
+}
+
+// =======================================================================
+// function : doTranslate
+// purpose :
+// =======================================================================
+Standard_Boolean VInspector_PresentationLight::doTranslate (const Standard_Integer theX,
+                                                            const Standard_Integer theY,
+                                                            const Handle(V3d_View)& theView)
+{
+  gp_Pnt aStartPosition (gp::Origin());
+  hasPosition(aStartPosition);
+
+  // Get 3d point with projection vector
+  Graphic3d_Vec3d anInputPoint, aProj;
+  theView->ConvertWithProj (theX, theY, anInputPoint.x(), anInputPoint.y(), anInputPoint.z(), aProj.x(), aProj.y(), aProj.z());
+
+  if (!myHasStartedTransformation)
+  {
+    gp_Dir aDir;
+    gp_Pnt aNewPosition;
+    if (!hasDirection(aDir))
+    {
+      if (!hasPosition(aNewPosition))
+      {
+        return Standard_False;
+      }
+      myStartPick = aNewPosition;
+    }
+    else
+    {
+      const gp_Lin anInputLine (gp_Pnt (anInputPoint.x(), anInputPoint.y(), anInputPoint.z()), gp_Dir (aProj.x(), aProj.y(), aProj.z()));
+      gp_Dir aDir = myLight->Direction();
+      const gp_Lin aLine (aStartPosition, aDir);
+      Extrema_ExtElC anExtrema (anInputLine, aLine, Precision::Angular());
+      if (!anExtrema.IsDone()
+          || anExtrema.IsParallel()
+          || anExtrema.NbExt() != 1)
+        {
+          // translation cannot be done co-directed with camera
+          return Standard_False;
+        }
+
+      Extrema_POnCurv anExPnts[2];
+      anExtrema.Points (1, anExPnts[0], anExPnts[1]);
+      aNewPosition = anExPnts[1].Value();
+
+      myStartPick = aNewPosition;
+    }
+    return Standard_True;
+  }
+
+  gp_Ax1 aLine1 (gp_Pnt (anInputPoint.x(), anInputPoint.y(), anInputPoint.z()), gp_Dir (aProj.x(), aProj.y(), aProj.z()));
+  gp_Pnt aProjectedPoint = PrsDim::ProjectPointOnLine (myStartPick, aLine1);
+  if (aProjectedPoint.Distance (myStartPick) < Precision::Confusion())
+  {
+    return Standard_False;
+  }
+
+  if (myTranslateMode == 0)
+  {
+    myLight->SetPosition (aProjectedPoint);
+    myStartPick = aProjectedPoint;
+  }
+  else
+  {
+    gp_Dir aNewDir (gp_Vec (aStartPosition, aProjectedPoint));
+    myLight->SetDirection (aNewDir);
+  }
+  // update the current presentation in context
+  SetToUpdate();
+  if (GetContext())
+  {
+    GetContext()->Redisplay (this, Standard_True);
+  }
+  return Standard_True;
+}
+
+// =======================================================================
+// function : drawDirectionalLight
+// purpose :
+// =======================================================================
+void VInspector_PresentationLight::drawDirectionalLight (const Handle(Prs3d_Presentation)& thePrs)
+{
+  gp_Pnt anAttachPoint (gp::Origin());
+  //SetTransformPersistence (new Graphic3d_TransformPers (Graphic3d_TMF_ZoomPers, anAttachPoint));
+
+  gp_Dir aDir = myLight->Direction();
+
+  // draw arrow
+  Handle(Graphic3d_ArrayOfTriangles) aTriangleArray = createArrow (aDir, anAttachPoint, myIndent);
+  Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (thePrs);
+  aGroup->SetGroupPrimitivesAspect (Attributes()->ShadingAspect()->Aspect());
+  aGroup->AddPrimitiveArray (aTriangleArray);
+
+  // draw line
+  Handle(Geom_Line) aGeomLine = new Geom_Line (gp_Lin (anAttachPoint, aDir));
+  GeomAdaptor_Curve aCurve (aGeomLine);
+  StdPrs_Curve::Add (thePrs, aCurve, myDrawer);
+
+  thePrs->SetInfiniteState (Standard_True);
+}
+
+// =======================================================================
+// function : selectDirectionalLight
+// purpose :
+// =======================================================================
+void VInspector_PresentationLight::selectDirectionalLight (const Handle(SelectMgr_Selection)& theSelection)
+{
+  gp_Dir aDir;
+  Standard_Boolean aHasDirection = hasDirection (aDir);
+  gp_Pnt anAttachPoint;
+  Standard_Boolean aHasPosition = hasPosition (anAttachPoint);
+
+  if (!aHasDirection && !aHasPosition)
+    return;
+
+  if (aHasDirection)
+  {
+    Handle(SelectMgr_EntityOwner) anOwner = new VInspector_PresentationLightOwner (this, 1/*translation mode*/, 5);
+
+    gp_Pnt aStartPoint = anAttachPoint.Translated (2 * myIndent * aDir.XYZ());
+    gp_Pnt anEndPoint = anAttachPoint.Translated ((-2) * myIndent * aDir.XYZ());
+    Handle(Select3D_SensitiveSegment) aSensitive = new Select3D_SensitiveSegment (anOwner, aStartPoint, anEndPoint);
+
+    theSelection->Add (aSensitive);
+  }
+  if (aHasPosition)
+  {
+    Handle(SelectMgr_EntityOwner) anOwner = new VInspector_PresentationLightOwner (this, 0/*position*/, 6);
+
+
+    Prs3d_ToolSphere aTool (10/*Radius*/, 20 /*SlicesNb*/, 20 /*StacksNb*/);
+    gp_Trsf aTrsf;
+    aTrsf.SetTranslation (gp_Vec(gp::Origin(), anAttachPoint));
+    Handle(Graphic3d_ArrayOfTriangles) aSphereArray;
+    Handle(Poly_Triangulation) aTriangulation;
+    aTool.FillArray (aSphereArray, aTriangulation, aTrsf);
+
+    Handle(Select3D_SensitiveTriangulation) aSensitive = new Select3D_SensitiveTriangulation (anOwner, aTriangulation,
+      TopLoc_Location(), Standard_True);
+    theSelection->Add (aSensitive);
+  }
+}
+
+// =======================================================================
+// function : drawPositionalLight
+// purpose :
+// =======================================================================
+void VInspector_PresentationLight::drawPositionalLight (const Handle(Prs3d_Presentation)& thePrs)
+{
+  const gp_Pnt& anAttachPoint = myLight->Position();
+  //SetTransformPersistence (new Graphic3d_TransformPers (Graphic3d_TMF_ZoomPers, anAttachPoint));
+
+  // draw position
+  drawPosition (anAttachPoint, thePrs);
+}
+
+// =======================================================================
+// function : drawSpotLigth
+// purpose :
+// =======================================================================
+void VInspector_PresentationLight::drawSpotLigth (const Handle(Prs3d_Presentation)& thePrs)
+{
+  const gp_Pnt& anAttachPoint = myLight->Position();
+  //SetTransformPersistence (new Graphic3d_TransformPers (Graphic3d_TMF_ZoomPers, anAttachPoint));
+
+  gp_Dir aDir = myLight->Direction();
+
+  // draw position
+  drawPosition (anAttachPoint, thePrs);
+
+  // draw arrow
+  Handle(Graphic3d_ArrayOfTriangles) aTriangleArray = createArrow (aDir, anAttachPoint, myIndent);
+  Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (thePrs);
+  aGroup->SetGroupPrimitivesAspect (Attributes()->ShadingAspect()->Aspect());
+  aGroup->AddPrimitiveArray (aTriangleArray);
+
+  // draw line
+  Handle(Geom_Line) aGeomLine = new Geom_Line (gp_Lin (anAttachPoint, aDir));
+  GeomAdaptor_Curve aCurve (aGeomLine);
+  StdPrs_Curve::Add (thePrs, aCurve, myDrawer);
+
+  thePrs->SetInfiniteState (Standard_True);
+}
+
+// =======================================================================
+// function : createArrow
+// purpose :
+// =======================================================================
+Handle(Graphic3d_ArrayOfTriangles) VInspector_PresentationLight::createArrow (const gp_Dir& theDir,
+                                                                              const gp_Pnt& theAttachPoint,
+                                                                              const Standard_Integer theIndent)
+{
+  Standard_Real aLength = theIndent * 0.2;
+  Standard_Real aTubeRadius = 0;
+  Standard_Real aConeRadius = aLength * 0.25;
+  Standard_Real aConeLength = aLength;
+
+  gp_Pnt anAttachPoint (theAttachPoint);
+  anAttachPoint.Translate (myIndent * theDir.XYZ());
+  return Prs3d_Arrow::DrawShaded (gp_Ax1(anAttachPoint, theDir), aTubeRadius, aLength, aConeRadius,
+                                  aConeLength, THE_NB_ARROW_FACETTES);
+}
+
+// =======================================================================
+// function : drawPosition
+// purpose :
+// =======================================================================
+void VInspector_PresentationLight::drawPosition (const gp_Pnt& theAttachPoint,
+                                                 const Handle(Prs3d_Presentation)& thePrs)
+{
+  Prs3d_ToolSphere aTool (10/*Radius*/, 20 /*SlicesNb*/, 20 /*StacksNb*/);
+  gp_Trsf aTrsf;
+  aTrsf.SetTranslation (gp_Vec(gp::Origin(), theAttachPoint));
+  Handle(Graphic3d_ArrayOfTriangles) aSphereArray;
+  aTool.FillArray (aSphereArray, aTrsf);
+
+  Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (thePrs);
+  aGroup->SetGroupPrimitivesAspect (Attributes()->ShadingAspect()->Aspect());
+  aGroup->AddPrimitiveArray (aSphereArray);
+}
+
+// =======================================================================
+// function : hasDirection
+// purpose :
+// =======================================================================
+Standard_Boolean VInspector_PresentationLight::hasDirection (gp_Dir& theDir)
+{
+  if (myLight.IsNull())
+    return Standard_False;
+
+  if (myLight->Type() != Graphic3d_TOLS_DIRECTIONAL && myLight->Type() != Graphic3d_TOLS_SPOT)
+    return Standard_False;
+
+  theDir = myLight->Direction();
+  return Standard_True;
+}
+
+// =======================================================================
+// function : hasPosition
+// purpose :
+// =======================================================================
+Standard_Boolean VInspector_PresentationLight::hasPosition (gp_Pnt& thePosition)
+{
+  if (myLight.IsNull())
+    return Standard_False;
+
+  if (myLight->Type() != Graphic3d_TOLS_POSITIONAL && myLight->Type() != Graphic3d_TOLS_SPOT)
+    return Standard_False;
+
+  thePosition = myLight->Position();
+  return Standard_True;
+}
diff --git a/tools/VInspector/VInspector_PresentationLight.hxx b/tools/VInspector/VInspector_PresentationLight.hxx
new file mode 100644 (file)
index 0000000..f2bfba8
--- /dev/null
@@ -0,0 +1,127 @@
+// Created on: 2020-07-04
+// Created by: Natalia ERMOLAEVA
+// Copyright (c) 2020 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement. 
+
+#ifndef _VInspector_PresentationLight_HeaderFile
+#define _VInspector_PresentationLight_HeaderFile
+
+#include <AIS_InteractiveObject.hxx>
+#include <AIS_DragItem.hxx>
+
+#include <Standard_Transient.hxx>
+
+class Graphic3d_ArrayOfTriangles;
+class Graphic3d_CLight;
+
+//! Interactive object class to visualize light element
+class VInspector_PresentationLight : public AIS_InteractiveObject,
+                                     public AIS_DragItem
+{
+public:
+  //! Constructor
+  Standard_EXPORT VInspector_PresentationLight();
+
+  virtual ~VInspector_PresentationLight() {}
+
+  //! Fill presentation by the light element
+  Standard_EXPORT void SetLight (const Handle(Graphic3d_CLight)& theLight);
+
+  //! Sets indent for directional light
+  Standard_EXPORT void SetIndent (const Standard_Integer theIndent) { myIndent = theIndent; }
+
+  //! Sets translate mode
+  void SetTranslateMode (const Standard_Integer theTranslateMode) { myTranslateMode = theTranslateMode; }
+
+public:
+  //! Fills presentation.
+  //! \param thePrsMgr manager of presentations
+  //! \param thePrs presentation to fill
+  //! \param theMode mode of display
+  Standard_EXPORT virtual void Compute (const Handle(PrsMgr_PresentationManager3d)& thePrsMgr,
+                                        const Handle(Prs3d_Presentation)& thePrs,
+                                        const Standard_Integer theMode = 0) Standard_OVERRIDE;
+
+  //! Computes selection sensitive zones (triangulation) for manipulator.
+  //! \param theSelection selection item to have own selected entities
+  //! \param theMode selection mode
+  Standard_EXPORT virtual void ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
+                                                 const Standard_Integer theMode) Standard_OVERRIDE;
+
+public:
+  //! @return true if this drag item participates in dragging
+  Standard_EXPORT virtual Standard_Boolean HasActiveMode() const;
+
+  //! Init start (reference) transformation.
+  //! @warning It is used in chain with StartTransform-Transform(gp_Trsf)-StopTransform
+  Standard_EXPORT virtual void StartTransform (const Standard_Integer theX,
+                                               const Standard_Integer theY,
+                                               const Handle(V3d_View)& theView);
+
+  //! Reset start (reference) transformation.
+  //! @param theToApply [in] option to apply or to cancel the started transformation.
+  Standard_EXPORT virtual void StopTransform (const Standard_Boolean theToApply = Standard_True);
+
+  //! Apply transformation made from mouse moving from start position
+  Standard_EXPORT virtual gp_Trsf Transform (const Standard_Integer theX,
+                                             const Standard_Integer theY,
+                                             const Handle(V3d_View)& theView);
+
+public:
+  DEFINE_STANDARD_RTTIEXT(VInspector_PresentationLight, AIS_InteractiveObject)
+
+private:
+  //! Converts pixel coordinate to point. If translation is not started, save this point as current,
+  //! else change direction of the light to the point
+  Standard_EXPORT Standard_Boolean doTranslate (const Standard_Integer theX,
+                                                const Standard_Integer theY,
+                                                const Handle(V3d_View)& theView);
+
+  //! Fills presentation with directional light elements
+  Standard_EXPORT void drawDirectionalLight (const Handle(Prs3d_Presentation)& thePrs);
+
+  //! Fills selection presentation with directional light elements
+  Standard_EXPORT void selectDirectionalLight (const Handle(SelectMgr_Selection)& theSelection);
+
+  //! Fills presentation with positional light elements
+  Standard_EXPORT void drawPositionalLight (const Handle(Prs3d_Presentation)& thePrs);
+
+  //! Fills presentation with spot light elements
+  Standard_EXPORT void drawSpotLigth (const Handle(Prs3d_Presentation)& thePrs);
+
+  //! Creates array for arrow presentation
+  //! \param theDir direction from the origin
+  //! \param theIndent a space to span from the origin
+  Standard_EXPORT Handle(Graphic3d_ArrayOfTriangles) createArrow (const gp_Dir& theDir,
+                                                                  const gp_Pnt& theAttachPoint,
+                                                                  const Standard_Integer theIndent);
+
+  //! Draws sphere in attached point
+  Standard_EXPORT void drawPosition (const gp_Pnt& theAttachPoint, const Handle(Prs3d_Presentation)& thePrs);
+
+  //! Returns true if light has defined direction
+  Standard_Boolean hasDirection (gp_Dir& theDir);
+
+  //! Returns true if light has defined position
+  Standard_Boolean hasPosition (gp_Pnt& thePosition);
+
+private:
+  Standard_Integer myIndent; //!< indent for directional light
+  Handle(Graphic3d_CLight) myLight; //!< light element
+  gp_Pnt myStartPick; //! 3d point corresponding to start mouse pick.
+
+  Standard_Integer myTranslateMode; //!< Translate mode: position or direction change.
+  Standard_Boolean myHasStartedTransformation; //!< to move position
+};
+
+#endif // _VInspector_PresentationLight_HeaderFile
index 87144bb4f1fec04a5cab9b88b91a4096dca80d63..0e23b07a045491a0133edda8b4d3edb51718ce4a 100644 (file)
@@ -36,6 +36,8 @@
 #include <inspector/VInspector_CallBack.hxx>
 #include <inspector/VInspector_Communicator.hxx>
 #include <inspector/VInspector_ItemContext.hxx>
+#include <inspector/VInspector_ItemContextProperties.hxx>
+#include <inspector/VInspector_ItemGraphic3dCLight.hxx>
 #include <inspector/VInspector_ToolBar.hxx>
 #include <inspector/VInspector_Tools.hxx>
 #include <inspector/VInspector_ViewModel.hxx>
@@ -484,6 +486,18 @@ bool VInspector_Window::OpenFile(const TCollection_AsciiString& theFileName)
   {
     aContext = createView();
     SetContext (aContext);
+
+    VInspector_ViewModel* aViewModel = dynamic_cast<VInspector_ViewModel*> (myTreeView->model());
+    if (aViewModel)
+    {
+      const Handle(V3d_Viewer) aViewer = aViewModel->GetContext()->CurrentViewer();
+      if (!aViewer.IsNull())
+      {
+        addLight (Graphic3d_TOLS_POSITIONAL, aViewer);
+        addLight (Graphic3d_TOLS_SPOT, aViewer);
+      }
+    }
+
     isModelUpdated = true;
   }
 
@@ -515,11 +529,35 @@ void VInspector_Window::onTreeViewContextMenuRequested(const QPoint& thePosition
   TreeModel_ItemBasePtr anItemBase = TreeModel_ModelBase::GetItemByIndex (anIndex);
   if (anItemBase)
   {
-    if (itemDynamicCast<VInspector_ItemContext> (anItemBase))
+    if (itemDynamicCast<VInspector_ItemContextProperties> (anItemBase))
     {
       aMenu->addAction (ViewControl_Tools::CreateAction (tr ("Export to MessageView"), SLOT (onExportToMessageView()), GetMainWindow(), this));
       aMenu->addSeparator();
     }
+
+    if (itemDynamicCast<VInspector_ItemContextProperties> (anItemBase))
+    {
+      aMenu->addSeparator();
+      QMenu* anExplodeMenu = aMenu->addMenu ("Add Light");
+
+      anExplodeMenu->addAction (ViewControl_Tools::CreateAction ("Ambient", SLOT (onAddLight()), myMainWindow, this));
+      anExplodeMenu->addAction (ViewControl_Tools::CreateAction ("Directional", SLOT (onAddLight()), myMainWindow, this));
+      anExplodeMenu->addAction (ViewControl_Tools::CreateAction ("Positional", SLOT (onAddLight()), myMainWindow, this));
+      anExplodeMenu->addAction (ViewControl_Tools::CreateAction ("Spot", SLOT (onAddLight()), myMainWindow, this));
+    }
+
+    if (itemDynamicCast<VInspector_ItemGraphic3dCLight> (anItemBase))
+    {
+      aMenu->addSeparator();
+      aMenu->addAction (ViewControl_Tools::CreateAction ("Remove Light", SLOT (onRemoveLight()), myMainWindow, this));
+      VInspector_ItemGraphic3dCLightPtr anItemLight = itemDynamicCast<VInspector_ItemGraphic3dCLight> (anItemBase);
+      if (!anItemLight->GetLight().IsNull())
+      {
+        bool isOn = anItemLight->GetLight()->IsEnabled();
+        aMenu->addAction (ViewControl_Tools::CreateAction (isOn ? "OFF Light" : "ON Light", SLOT (onOnOffLight()),
+                          myMainWindow, this));
+      }
+    }
   }
 
   aMenu->addSeparator();
@@ -697,6 +735,97 @@ void VInspector_Window::onExportToShapeView()
   myParameters->SetParameters (aPluginName, aParameters, myExportToShapeViewDialog->IsAccepted());
 }
 
+// =======================================================================
+// function : onAddLight
+// purpose :
+// =======================================================================
+void VInspector_Window::onAddLight()
+{
+  VInspector_ViewModel* aViewModel = dynamic_cast<VInspector_ViewModel*> (myTreeView->model());
+  if (!aViewModel)
+    return;
+  const Handle(V3d_Viewer) aViewer = aViewModel->GetContext()->CurrentViewer();
+  if (aViewer.IsNull())
+    return;
+
+  QAction* anAction = (QAction*)sender();
+  QString aText = anAction->text();
+
+  Graphic3d_TypeOfLightSource aLightSourceType = Graphic3d_TOLS_AMBIENT;
+
+  if (aText == "Ambient")           { aLightSourceType = Graphic3d_TOLS_AMBIENT; }
+  else if (aText == "Directional")  { aLightSourceType = Graphic3d_TOLS_DIRECTIONAL; }
+  else if (aText == "Positional")   { aLightSourceType = Graphic3d_TOLS_POSITIONAL; }
+  else if (aText == "Spot")         { aLightSourceType = Graphic3d_TOLS_SPOT; }
+  else                              { return; }
+
+  addLight(aLightSourceType, aViewer);
+}
+
+// =======================================================================
+// function : onRemoveLight
+// purpose :
+// =======================================================================
+void VInspector_Window::onRemoveLight()
+{
+  VInspector_ViewModel* aViewModel = dynamic_cast<VInspector_ViewModel*> (myTreeView->model());
+  const Handle(V3d_Viewer) aViewer = aViewModel ? aViewModel->GetContext()->CurrentViewer() : NULL;
+  if (aViewer.IsNull())
+  {
+    return;
+  }
+
+  QModelIndex anIndex = TreeModel_ModelBase::SingleSelected (myTreeView->selectionModel()->selectedIndexes(), 0);
+  VInspector_ItemGraphic3dCLightPtr aLightItem = itemDynamicCast<VInspector_ItemGraphic3dCLight> (
+    TreeModel_ModelBase::GetItemByIndex (anIndex));
+  if (!aLightItem)
+  {
+    return;
+  }
+
+  if (aViewer->ActiveLights().Extent() == 1) // not possible to remove the latest light
+  {
+    return;
+  }
+
+  Handle(Graphic3d_CLight) aLight = aLightItem->GetLight();
+  aViewer->DelLight (aLight);
+  aViewer->UpdateLights();
+
+  aViewer->Invalidate();
+  aViewer->Redraw();
+  UpdateTreeModel();
+}
+
+// =======================================================================
+// function : onOnOffLight
+// purpose :
+// =======================================================================
+void VInspector_Window::onOnOffLight()
+{
+  VInspector_ViewModel* aViewModel = dynamic_cast<VInspector_ViewModel*> (myTreeView->model());
+  const Handle(V3d_Viewer) aViewer = aViewModel ? aViewModel->GetContext()->CurrentViewer() : NULL;
+  if (aViewer.IsNull())
+  {
+    return;
+  }
+
+  QModelIndex anIndex = TreeModel_ModelBase::SingleSelected (myTreeView->selectionModel()->selectedIndexes(), 0);
+
+  VInspector_ItemGraphic3dCLightPtr anItemLight = itemDynamicCast<VInspector_ItemGraphic3dCLight> (
+    TreeModel_ModelBase::GetItemByIndex (anIndex));
+  if (anItemLight->GetLight().IsNull())
+    return;
+
+  bool isOn = anItemLight->GetLight()->IsEnabled();
+  anItemLight->GetLight()->SetEnabled (!isOn);
+
+  aViewer->UpdateLights();
+  aViewer->Invalidate();
+  aViewer->Redraw();
+  UpdateTreeModel();
+}
+
 // =======================================================================
 // function : onDisplayActionTypeClicked
 // purpose :
@@ -760,7 +889,7 @@ void VInspector_Window::onCollapseAll()
 }
 
 // =======================================================================
-// function : UpdateTreeModel
+// function : OnTestAddChild
 // purpose :
 // =======================================================================
 void VInspector_Window::OnTestAddChild()
@@ -911,3 +1040,32 @@ View_Displayer* VInspector_Window::displayer()
 
   return myDisplayer;
 }
+
+// =======================================================================
+// function : addLight
+// purpose :
+// =======================================================================
+void VInspector_Window::addLight (const Graphic3d_TypeOfLightSource& theSourceLight,
+                                  const Handle(V3d_Viewer)& theViewer)
+{
+  Standard_Boolean aNeedDirection = theSourceLight == Graphic3d_TOLS_DIRECTIONAL ||
+                                    theSourceLight == Graphic3d_TOLS_SPOT;
+
+  Handle(Graphic3d_CLight) aLight = new Graphic3d_CLight (theSourceLight);
+  if (aNeedDirection)
+  {
+    aLight->SetDirection (gp::DZ());
+  }
+  if (theSourceLight == Graphic3d_TOLS_SPOT)
+  {
+    aLight->SetAngle (M_PI - ShortRealEpsilon());
+    aLight->SetPosition (gp_Pnt (-100, -100, -100));
+  }
+
+  theViewer->AddLight (aLight);
+  theViewer->SetLightOn (aLight);
+
+  theViewer->Invalidate();
+  theViewer->Redraw();
+  UpdateTreeModel();
+}
index 3eedc14685e7cd603193c6dd4ad943bda5c7e37c..7d33b896c8c76920aa48961b7aa2a720389217f6 100644 (file)
@@ -135,6 +135,15 @@ private slots:
   //! Exports the first selected shape into ShapeViewer plugin.
   void onExportToShapeView();
 
+  //! Appends lights into an active V3d view
+  void onAddLight();
+
+  //! Removes selected light from the active V3d view
+  void onRemoveLight();
+
+  //! Switch On/Off light
+  void onOnOffLight();
+
   //! Apply activated display action
   void onDisplayActionTypeClicked();
 
@@ -180,6 +189,9 @@ private:
   //! \return a context of created view.
   Handle(AIS_InteractiveContext) createView();
 
+  //! Appends a light into V3d viewer
+  void addLight (const Graphic3d_TypeOfLightSource& theSourceLight, const Handle(V3d_Viewer)& theViewer);
+
 private:
 
   QWidget* myParent; //!< widget, comes when Init window, the window control lays in the layout, updates window title
index e129416f33ba0e9c1845de546d8985c5f3b1e57e..7fee6b7e9372cc96f4c708ddad00db5c5f6e1cc1 100644 (file)
@@ -116,7 +116,9 @@ void View_DisplayPreview::UpdatePreview (const View_DisplayActionType,
     Handle(AIS_InteractiveObject) aPrs = Handle(AIS_InteractiveObject)::DownCast (anIterator.Value());
     if (!aPrs.IsNull() && aPrs->GetContext().IsNull()/*is not displayed in another context*/)
     {
-      myContext->Display (aPrs, aPreviewDisplayMode, -1/*does not participate in selection*/, Standard_True);
+      myContext->Display (aPrs, aPreviewDisplayMode,
+                          View_DisplayPreview::PreviewSelectionMode()/*participate only in custom selection*/,
+                          Standard_True);
       enableGlobalClipping(aPrs, false);
       myPreviewReadyPresentations.Append (aPrs);
     }
@@ -129,7 +131,9 @@ void View_DisplayPreview::UpdatePreview (const View_DisplayActionType,
     myPreviewPresentation->Attributes()->SetPointAspect (new Prs3d_PointAspect (Aspect_TOM_O_PLUS, aColor, 3.0));
     myPreviewPresentation->SetAttributes (myPreviewParameters->GetDrawer());
 
-    myContext->Display (myPreviewPresentation, aPreviewDisplayMode, -1/*does not participate in selection*/, Standard_True);
+    myContext->Display (myPreviewPresentation, aPreviewDisplayMode,
+                        View_DisplayPreview::PreviewSelectionMode()/*participate only in custom selection*/,
+                        Standard_True);
     enableGlobalClipping(myPreviewPresentation, false);
   }
   else
index 550e681289a059c3aef94efd6ee7e0e9557eb35e..9993115c59cd0d6fb37b8a75e5015860a79c0f6a 100644 (file)
@@ -58,6 +58,9 @@ public:
   //! Returns true if preview presentation is shown
   Standard_Boolean HasPreview() const { return !myPreviewPresentation.IsNull(); }
 
+  //! Custom preview selection mode
+  static Standard_Integer PreviewSelectionMode() { return 100; }
+
 private:
 
   //! Returns the current context
index a44991016fe7b60d194181165ee1bd0bbbba73e3..a8793ec5367d7753ec0211c865d7e9c359f6e1af 100644 (file)
@@ -28,7 +28,6 @@
 
 #include <inspector/View_DisplayPreview.hxx>
 #include <inspector/View_Viewer.hxx>
-#include <inspector/View_Widget.hxx>
 
 // =======================================================================
 // function : Constructor
index f6375e5658fd6c4b060076fb908eb82a92e0de3b..1eece85a4ecf62309a5391cb40ac41c04a20fc7d 100644 (file)
@@ -16,6 +16,7 @@
 #include <inspector/View_PreviewParameters.hxx>
 
 #include <Prs3d_Drawer.hxx>
+#include <Prs3d_LineAspect.hxx>
 #include <Prs3d_PointAspect.hxx>
 #include <Prs3d_ShadingAspect.hxx>
 
 // function : Constructor
 // purpose :
 // =======================================================================
-View_PreviewParameters::View_PreviewParameters()
+View_PreviewParameters::View_PreviewParameters (const Standard_Boolean theToTransparent)
 {
   myDrawer = new Prs3d_Drawer();
 
   Quantity_Color aColor(Quantity_NOC_TOMATO);
-  Standard_ShortReal aTransparency = 0.8;
 
   // point parameters
   myDrawer->SetPointAspect (new Prs3d_PointAspect (Aspect_TOM_O_PLUS, aColor, 3.0));
@@ -42,10 +42,16 @@ View_PreviewParameters::View_PreviewParameters()
   myDrawer->ShadingAspect()->SetColor (aColor);
   myDrawer->ShadingAspect()->SetMaterial (aShadingMaterial);
 
-  myDrawer->ShadingAspect()->Aspect()->ChangeFrontMaterial().SetTransparency (aTransparency);
-  myDrawer->ShadingAspect()->Aspect()->ChangeBackMaterial() .SetTransparency (aTransparency);
-  myDrawer->SetTransparency (aTransparency);
+  myDrawer->SetLineAspect (new Prs3d_LineAspect (aColor, Aspect_TOL_SOLID, 1.));
 
+  if (theToTransparent)
+  {
+    Standard_ShortReal aTransparency = 0.8;
+
+    myDrawer->ShadingAspect()->Aspect()->ChangeFrontMaterial().SetTransparency (aTransparency);
+    myDrawer->ShadingAspect()->Aspect()->ChangeBackMaterial() .SetTransparency (aTransparency);
+    myDrawer->SetTransparency (aTransparency);
+  }
   // common parameters
   myDrawer->SetZLayer (Graphic3d_ZLayerId_Topmost);
 }
index 700ecc233202b2256894ecbbeced3572600a0d69..e78a1fa7cc6db3391d29e1fd157291eff922fee3 100644 (file)
@@ -33,7 +33,7 @@ class View_PreviewParameters
 public:
 
   //! Constructor
-  Standard_EXPORT View_PreviewParameters ();
+  Standard_EXPORT View_PreviewParameters (const Standard_Boolean theToTransparent = Standard_True);
 
   //! Destructor
   virtual ~View_PreviewParameters() {}
index d21b45bb1ad7b122a4f537139f8e12e4abf2f318..7549493bb3cc65c9439c9e4643bd389bc43c6e29 100644 (file)
@@ -22,7 +22,7 @@
 #include <QWidget>
 #include <Standard_WarningsRestore.hxx>
 
-//! \class View_Widget
+//! \class View_ToolButton
 //! \brief It is a Qt control that implements change checked state for button by double click event
 //! Button becomes checked by double click mouse pressed and unchecked by the next press mouse
 class View_ToolButton : public QToolButton
index 3560ed577993da4e7daf2c54078739b7d20e2625..00ead6b1b7d35c6f17e3cbbc6de92d49fce79659 100644 (file)
@@ -1,3 +1,5 @@
+ViewControl_ColorSelector.cxx
+ViewControl_ColorSelector.hxx
 ViewControl_EditType.hxx
 ViewControl_MessageDialog.cxx
 ViewControl_MessageDialog.hxx
@@ -7,6 +9,8 @@ ViewControl_PropertiesDialog.cxx
 ViewControl_PropertiesDialog.hxx
 ViewControl_Table.cxx
 ViewControl_Table.hxx
+ViewControl_TableItemDelegate.cxx
+ViewControl_TableItemDelegate.hxx
 ViewControl_TableModel.cxx
 ViewControl_TableModel.hxx
 ViewControl_TableModelValues.cxx
diff --git a/tools/ViewControl/ViewControl_ColorSelector.cxx b/tools/ViewControl/ViewControl_ColorSelector.cxx
new file mode 100644 (file)
index 0000000..3b1b0aa
--- /dev/null
@@ -0,0 +1,617 @@
+// Created on: 2018-08-16
+// Created by: Natalia ERMOLAEVA
+// Copyright (c) 2018 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement. 
+
+#include <inspector/ViewControl_ColorSelector.hxx>
+#include <inspector/ViewControl_TableItemDelegate.hxx>
+#include <inspector/ViewControl_TableModel.hxx>
+#include <inspector/ViewControl_TableModelValues.hxx>
+#include <inspector/ViewControl_Tools.hxx>
+#include <inspector/TreeModel_Tools.hxx>
+
+#include <Standard_Dump.hxx>
+
+#include <Standard_WarningsDisable.hxx>
+#include <QAbstractTableModel>
+#include <QDialogButtonBox>
+#include <QHeaderView>
+#include <QGridLayout>
+#include <QItemSelectionModel>
+#include <QPainter>
+#include <QTableView>
+#include <QWidget>
+#include <Standard_WarningsRestore.hxx>
+
+//! Kinds of delegate cell in OCCT Color model to present a custom presentation (rect bounded by a colored frame)
+enum ViewControl_ColorDelegateKind
+{
+  ViewControl_ColorDelegateKind_None, //!< usual item
+  ViewControl_ColorDelegateKind_Activated, //!< active item
+  ViewControl_ColorDelegateKind_Highlighted, //!< highlighted item
+  ViewControl_ColorDelegateKind_Selected //!< selected item
+};
+
+//! Model for a table of parameters: Current Color, Red, Green, Blue, Alpha, OCCT color name
+class ViewControl_ParametersModel : public ViewControl_TableModelValues
+{
+public:
+  ViewControl_ParametersModel (ViewControl_ColorSelector* theSelector)
+    : ViewControl_TableModelValues(), mySelector (theSelector) {}
+  virtual ~ViewControl_ParametersModel() {}
+
+  //! Inits model by the parameter color
+  //! \param theColor model active color
+  void SetColor (const Quantity_ColorRGBA& theColor, ViewControl_TableModel* theModel)
+  { myColor = theColor; theModel->EmitLayoutChanged(); }
+
+  //! Returns current selected color
+  //! \return color value
+  Quantity_ColorRGBA GetColor() const { return myColor; }
+
+  //! Returns item information(short) for display role.
+  //! \param theIndex a model index
+  //! \param theRole a view role
+  //! \return value intepreted depending on the given role
+  Standard_EXPORT virtual QVariant Data (const int theRow, const int theColumn,
+                                         int theRole = Qt::DisplayRole) const Standard_OVERRIDE
+  {
+    //(void)theRow; (void)theColumn; (void) theRole;
+    if (theRole == Qt::BackgroundRole && theColumn == 1 && theRow == 0)
+      return ViewControl_ColorSelector::ColorToQColor (myColor);
+
+    if (theRole == Qt::ForegroundRole && theColumn == 1 && theRow >= 2 && theRow <= 5)
+      return ViewControl_TableModelValues::EditCellColor();
+
+    if (theRole != Qt::DisplayRole)
+    return QVariant();
+
+    bool isFirstColumn = theColumn == 0;
+    switch (theRow)
+    {
+      case 0: return isFirstColumn ? QVariant ("Color") : QVariant ();
+      case 1:
+      {
+        if (isFirstColumn)
+          return QVariant ("Name");
+        Quantity_NameOfColor aColorName;
+        if (ViewControl_ColorSelector::IsExactColorName(myColor, aColorName))
+          return Quantity_Color::StringName(aColorName);
+      }
+      break;
+      case 2: return isFirstColumn ? QVariant ("Red") : ViewControl_Tools::ToVariant (myColor.GetRGB().Red());
+      case 3: return isFirstColumn ? QVariant ("Green") : ViewControl_Tools::ToVariant (myColor.GetRGB().Green());
+      case 4: return isFirstColumn ? QVariant ("Blue") : ViewControl_Tools::ToVariant (myColor.GetRGB().Blue());
+      case 5: return isFirstColumn ? QVariant ("Alpha") : ViewControl_Tools::ToVariant (myColor.Alpha());
+      case 6: return isFirstColumn ? QVariant ("Near Name") 
+                                   : Quantity_Color::StringName(myColor.GetRGB().Name());
+    }
+    return QVariant();
+  }
+
+  //! Sets content of the model index for the given role, it is applyed to internal container of values
+  //! \param theRow a model index row
+  //! \param theColumn a model index column
+  //! \param theRole a view role
+  //! \return true if the value is changed
+  virtual bool SetData (const int theRow, const int theColumn, const QVariant& theValue, int)
+  {
+    if (theColumn != 1 || theRow < 2 || theRow > 5)
+      return false;
+
+    switch (theRow)
+    {
+      case 2:
+      case 3:
+      case 4:
+      {
+        myColor.ChangeRGB().SetValues (theRow == 2 ? ViewControl_Tools::ToShortRealValue (theValue) : myColor.GetRGB().Red(),
+                                       theRow == 3 ? ViewControl_Tools::ToShortRealValue (theValue) : myColor.GetRGB().Green(),
+                                       theRow == 4 ? ViewControl_Tools::ToShortRealValue (theValue) : myColor.GetRGB().Blue(),
+                                       Quantity_TOC_RGB);
+      }
+      break;
+      case 5: myColor.SetAlpha (ViewControl_Tools::ToShortRealValue (theValue)); break;
+    }
+    mySelector->ParameterColorChanged();
+    return true;
+  }
+
+  //! Returns number of tree level line items = colums in table view
+  virtual int ColumnCount (const QModelIndex& theParent = QModelIndex()) const Standard_OVERRIDE
+  { (void)theParent; return 2; }
+
+  //! Returns onlly one row in table view
+  virtual int RowCount (const QModelIndex& theParent = QModelIndex()) const Standard_OVERRIDE
+  { (void)theParent; return 7; }
+
+  //! Returns editable flag for color RGB and alpha rows
+  //! \return flags
+  Qt::ItemFlags Flags (const QModelIndex& theIndex) const
+  {
+    Qt::ItemFlags aFlags = ViewControl_TableModelValues::Flags (theIndex);
+
+    if (theIndex.column() == 1 && theIndex.row() >= 2 && theIndex.row() <= 5)
+      aFlags = aFlags | Qt::ItemIsEditable;
+
+    return aFlags;
+  }
+
+  //! Returns type of edit control for the model index. By default, it is an empty control
+  //! \param theRow a model index row
+  //! \param theColumn a model index column
+  //! \return edit type
+  virtual ViewControl_EditType GetEditType (const int theRow, const int theColumn) const
+  {
+    if (theColumn == 1 && theRow >= 2 && theRow <= 5)
+      return ViewControl_EditType_Double;
+
+    return ViewControl_EditType_None;
+  }
+
+private:
+  Quantity_ColorRGBA myColor;
+  ViewControl_ColorSelector* mySelector;
+};
+
+//! Table of parameters: Red, Green, Blue, Alpha, OCCT color name
+class ViewControl_OCCTColorModel : public QAbstractTableModel
+{
+public:
+  ViewControl_OCCTColorModel (QObject* theParent)
+    : QAbstractTableModel (theParent), myCurrentIndexKind (ViewControl_ColorDelegateKind_None) {}
+  virtual ~ViewControl_OCCTColorModel() {}
+
+  //! Sets current color, that should have custom presented
+  //! \param theColor current color
+  //! \param theKind presentation kind
+  void SetColor (const Quantity_NameOfColor& theColor, const ViewControl_ColorDelegateKind theKind)
+  {
+    int aColorPosition = (int)theColor;
+    int aRow = (int) (aColorPosition / columnCount());
+    int aColumn = aColorPosition - aRow * columnCount();
+    myCurrentIndex = index (aRow, aColumn);
+    myCurrentIndexKind = theKind;
+
+    emit layoutChanged();
+  }
+
+  //! Returns OCCT name of color if index position does not exceed Quantity_NameOfColor elements
+  //! \param theIndex model index
+  //! \param theNameOfColor [out] OCCT color name
+  //! \return true if the color is found
+  bool GetOCCTColor (const QModelIndex& theIndex, Quantity_NameOfColor& theNameOfColor) const
+  {
+    int aNameOfColorId = theIndex.row() * columnCount() + theIndex.column();
+    if (aNameOfColorId > Quantity_NOC_WHITE)
+      return false;
+    theNameOfColor = (Quantity_NameOfColor)aNameOfColorId;
+    return true;
+  }
+
+  //! Returns index that has custom presentation
+  //! \return model index
+  QModelIndex GetCurrentIndex() const { return myCurrentIndex; }
+
+  //! Returns index color kind that has custom presentation
+  //! \return kind
+  ViewControl_ColorDelegateKind GetCurrentIndexKind() const { return myCurrentIndexKind; }
+
+  //! Returns item information(short) for display role.
+  //! \param theIndex a model index
+  //! \param theRole a view role
+  //! \return value intepreted depending on the given role
+  Standard_EXPORT virtual QVariant data (const QModelIndex& theIndex,
+                                         int theRole = Qt::DisplayRole) const Standard_OVERRIDE
+  {
+    if (theRole != Qt::ToolTipRole) // background is processed in table item delegate
+      return QVariant();
+
+    Quantity_NameOfColor aNameOfColor;
+    if (!GetOCCTColor (theIndex, aNameOfColor))
+      return QVariant();
+
+    if (theRole == Qt::ToolTipRole)
+      return QString("%1").arg (ViewControl_ColorSelector::ColorToString (Quantity_Color (aNameOfColor)));
+      //return QString("%1 (%2)").arg(Quantity::NameOfColorToString (aNameOfColor))
+      //                         .arg (ViewControl_ColorSelector::ColorToString (Quantity_Color (aNameOfColor)));
+    return QVariant();
+  }
+
+  //! Returns number of tree level line items = colums in table view
+  virtual int columnCount (const QModelIndex& theParent = QModelIndex()) const Standard_OVERRIDE
+  { (void)theParent; return 26; }
+
+  //! Returns onlly one row in table view
+  virtual int rowCount (const QModelIndex& theParent = QModelIndex()) const Standard_OVERRIDE
+  { (void)theParent; return 20; }
+
+  //! Returns color for the delegate kind
+  //! \param theKind kind
+  //! \return color
+  static QColor GetKindColor (const ViewControl_ColorDelegateKind theKind)
+  {
+    switch (theKind)
+    {
+      case ViewControl_ColorDelegateKind_Activated:
+      case ViewControl_ColorDelegateKind_Highlighted: return Qt::blue;
+      case ViewControl_ColorDelegateKind_Selected: return Qt::black;
+      default: break;
+    }
+    return QColor();
+  }
+
+private:
+  QModelIndex myCurrentIndex; //!< index to be presented through item delegate
+  ViewControl_ColorDelegateKind myCurrentIndexKind; //!< kind of custom item
+};
+
+//! \class DFBrowser_HighlightDelegate
+//! \brief An item delegate to paint in highlight color the cell when the mouse cursor is over it
+class ViewControl_OCCTColorDelegate : public QItemDelegate
+{
+public:
+
+  //! Constructor
+  ViewControl_OCCTColorDelegate (QObject* theParent = 0) : QItemDelegate (theParent) {}
+
+  //! Destructor
+  virtual ~ViewControl_OCCTColorDelegate() Standard_OVERRIDE {}
+
+  //! Redefine of the parent virtual method to color the cell rectangle in highlight style
+  //! \param thePainter a painter
+  //! \param theOption a paint options
+  //! \param theIndex a view index
+  virtual void paint (QPainter* thePainter, const QStyleOptionViewItem& theOption,
+                      const QModelIndex& theIndex) const Standard_OVERRIDE
+  {
+    QRect aBaseRect = theOption.rect;
+    int aNameOfColorId = theIndex.row() * theIndex.model()->columnCount(theIndex) + theIndex.column();
+    Quantity_NameOfColor aNameOfColor = Quantity_NOC_WHITE;
+    if (aNameOfColorId < (int)Quantity_NOC_WHITE)
+      aNameOfColor = (Quantity_NameOfColor)aNameOfColorId;
+
+    Quantity_Color anOCCTColor (aNameOfColor);
+    QColor aQColor = ViewControl_ColorSelector::ColorToQColor (Quantity_ColorRGBA (anOCCTColor));
+    thePainter->fillRect (aBaseRect, aQColor);
+
+    QColor aColor;
+    // highlight cell
+    if (theOption.state & QStyle::State_MouseOver)
+      aColor = ViewControl_OCCTColorModel::GetKindColor (ViewControl_ColorDelegateKind_Highlighted);
+    else
+    {
+      const ViewControl_OCCTColorModel* aTableModel = dynamic_cast<const ViewControl_OCCTColorModel*> (theIndex.model());
+      QModelIndex anIndex = aTableModel->GetCurrentIndex();
+      if (anIndex.isValid() && anIndex.row() == theIndex.row() && anIndex.column() == theIndex.column())
+        aColor = ViewControl_OCCTColorModel::GetKindColor (aTableModel->GetCurrentIndexKind());
+    }
+    
+    if (aColor.isValid())
+    {
+      int aRectSize = 2;
+      thePainter->fillRect (QRect (aBaseRect.topLeft(), QPoint (aBaseRect.bottomLeft().x() + aRectSize, aBaseRect.bottomLeft().y())),
+                            aColor);
+      thePainter->fillRect (QRect (QPoint (aBaseRect.topRight().x() - aRectSize, aBaseRect.topRight().y()), aBaseRect.bottomRight()),
+                            aColor);
+      thePainter->fillRect (QRect (QPoint (aBaseRect.topLeft().x() + aRectSize, aBaseRect.topLeft().y()),
+                                   QPoint (aBaseRect.topRight().x() - aRectSize, aBaseRect.topRight().y() + aRectSize)),
+                            aColor);
+      thePainter->fillRect (QRect (QPoint (aBaseRect.bottomLeft().x() + aRectSize, aBaseRect.bottomLeft().y() - aRectSize),
+                                   QPoint (aBaseRect.bottomRight().x() - aRectSize, aBaseRect.bottomRight().y())),
+                            aColor);
+    }
+  }
+};
+
+//! Color picker class
+class ViewControl_ColorPicker : public QWidget
+{
+public:
+  ViewControl_ColorPicker (QWidget* theParent) : QWidget (theParent) {}
+  virtual ~ViewControl_ColorPicker() {}
+};
+
+
+// =======================================================================
+// function : Constructor
+// purpose :
+// =======================================================================
+
+ViewControl_ColorSelector::ViewControl_ColorSelector (QWidget* theParent)
+: QDialog (theParent)
+{
+  QGridLayout* aLayout = new QGridLayout (this);
+  aLayout->setContentsMargins (0, 0, 0, 0);
+
+  myParameters = new QTableView (this);
+  ViewControl_TableModel* aTableModel = new ViewControl_TableModel (myParameters);
+  aTableModel->SetModelValues (new ViewControl_ParametersModel (this));
+  myParameters->setModel(aTableModel);
+
+  ViewControl_TableItemDelegate* anItemDelegate = new ViewControl_TableItemDelegate();
+  anItemDelegate->SetModelValues (aTableModel->ModelValues());
+  myParameters->setItemDelegate(anItemDelegate);
+
+  myParameters->verticalHeader()->setDefaultSectionSize (myParameters->verticalHeader()->minimumSectionSize());
+  myParameters->verticalHeader()->setVisible (false);
+  myParameters->horizontalHeader()->setVisible (false);
+  myParameters->setMinimumHeight (myParameters->verticalHeader()->minimumSectionSize() * aTableModel->rowCount() +
+                                  TreeModel_Tools::HeaderSectionMargin());
+
+  QItemSelectionModel* aSelectionModel = new QItemSelectionModel (myParameters->model());
+  myParameters->setSelectionMode (QAbstractItemView::SingleSelection);
+  myParameters->setSelectionModel (aSelectionModel);
+  connect (aSelectionModel, SIGNAL (selectionChanged (const QItemSelection&, const QItemSelection&)),
+          this, SLOT (onParametersTableSelectionChanged (const QItemSelection&, const QItemSelection&)));
+
+  aLayout->addWidget (myParameters, 0, 0);
+
+  myColorPicker = new ViewControl_ColorPicker (this);
+  aLayout->addWidget (myColorPicker, 0, 1);
+
+  myOCCTColors = new QTableView (this);
+  myOCCTColors->setFixedSize (525, 405);
+  myOCCTColors->verticalHeader()->setDefaultSectionSize (20);
+  myOCCTColors->verticalHeader()->setVisible (false);
+  myOCCTColors->horizontalHeader()->setDefaultSectionSize (20);
+  myOCCTColors->horizontalHeader()->setVisible (false);
+  myOCCTColors->setModel(new ViewControl_OCCTColorModel(myOCCTColors));
+
+  myOCCTColors->viewport()->setAttribute (Qt::WA_Hover);
+  myOCCTColors->setItemDelegate (new ViewControl_OCCTColorDelegate (myOCCTColors));
+
+  aSelectionModel = new QItemSelectionModel (myOCCTColors->model());
+  myOCCTColors->setSelectionMode (QAbstractItemView::SingleSelection);
+  myOCCTColors->setSelectionModel (aSelectionModel);
+  connect (aSelectionModel, SIGNAL (selectionChanged (const QItemSelection&, const QItemSelection&)),
+          this, SLOT (onOCCTColorsTableSelectionChanged (const QItemSelection&, const QItemSelection&)));
+  aLayout->addWidget (myOCCTColors, 1, 0, 1, 2);
+
+  myDialogButtons = new QDialogButtonBox (QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
+  connect(myDialogButtons, &QDialogButtonBox::accepted, this, &QDialog::accept);
+  connect(myDialogButtons, &QDialogButtonBox::rejected, this, &QDialog::reject);
+
+  aLayout->addWidget(myDialogButtons, 2, 0, 1, 2);
+}
+
+// =======================================================================
+// function : SetStreamValue
+// purpose :
+// =======================================================================
+
+void ViewControl_ColorSelector::SetStreamValue (const QString& theValue)
+{
+  Quantity_ColorRGBA aColor = StringToColorRGBA (theValue);
+  // parameters model
+  ViewControl_TableModel* aTableModel = dynamic_cast<ViewControl_TableModel*> (myParameters->model());
+  ViewControl_ParametersModel* aParametersModel = dynamic_cast<ViewControl_ParametersModel*> (aTableModel->ModelValues());
+  aParametersModel->SetColor (aColor, aTableModel);
+
+  // OCCT color model
+  Quantity_NameOfColor aColorName;
+  bool isExactColorName = ViewControl_ColorSelector::IsExactColorName(aColor, aColorName);
+  ViewControl_OCCTColorModel* anOCCTColorModel = dynamic_cast<ViewControl_OCCTColorModel*>(myOCCTColors->model());
+  anOCCTColorModel->SetColor (aColorName, isExactColorName ? ViewControl_ColorDelegateKind_Selected
+                                                           : ViewControl_ColorDelegateKind_Activated);
+}
+
+// =======================================================================
+// function : GetStreamValue
+// purpose :
+// =======================================================================
+QString ViewControl_ColorSelector::GetStreamValue() const
+{
+  ViewControl_TableModel* aTableModel = dynamic_cast<ViewControl_TableModel*> (myParameters->model());
+  ViewControl_ParametersModel* aParametersModel = dynamic_cast<ViewControl_ParametersModel*> (aTableModel->ModelValues());
+
+  Quantity_ColorRGBA aColor = aParametersModel->GetColor();
+
+  Standard_SStream aStream;
+  aColor.DumpJson (aStream);
+
+  return Standard_Dump::Text (aStream).ToCString();
+
+  //return ColorToString (aParametersModel->GetColor());
+
+  return QString();
+}
+
+// =======================================================================
+// function : ParameterColorChanged
+// purpose :
+// =======================================================================
+
+void ViewControl_ColorSelector::ParameterColorChanged()
+{
+  ViewControl_TableModel* aTableModel = dynamic_cast<ViewControl_TableModel*> (myParameters->model());
+  ViewControl_ParametersModel* aParametersModel = dynamic_cast<ViewControl_ParametersModel*> (aTableModel->ModelValues());
+  Quantity_ColorRGBA aColor = aParametersModel->GetColor();
+
+  // OCCT color model
+  Quantity_NameOfColor aColorName;
+  bool isExactColorName = ViewControl_ColorSelector::IsExactColorName(aColor, aColorName);
+  ViewControl_OCCTColorModel* anOCCTColorModel = dynamic_cast<ViewControl_OCCTColorModel*>(myOCCTColors->model());
+  anOCCTColorModel->SetColor (aColorName, isExactColorName ? ViewControl_ColorDelegateKind_Selected
+                                                           : ViewControl_ColorDelegateKind_Activated);
+}
+
+// =======================================================================
+// function : ColorToString
+// purpose :
+// =======================================================================
+
+QString ViewControl_ColorSelector::ColorToString (const Quantity_Color& theColor)
+{
+  Standard_Real aRed, aGreen, aBlue;
+  theColor.Values (aRed, aGreen, aBlue, Quantity_TOC_RGB);
+  return QString::number (aRed) + ViewControl_ColorSelector::ColorSeparator() +
+         QString::number (aGreen) + ViewControl_ColorSelector::ColorSeparator() +
+         QString::number (aBlue);
+}
+
+// =======================================================================
+// function : ColorToString
+// purpose :
+// =======================================================================
+
+QString ViewControl_ColorSelector::ColorToString (const Quantity_ColorRGBA& theColor)
+{
+  const Quantity_Color& aRGBColor = theColor.GetRGB();
+  Standard_ShortReal anAlpha = theColor.Alpha();
+
+  return ColorToString (aRGBColor) + ViewControl_ColorSelector::ColorSeparator() + QString::number (anAlpha);
+}
+
+// =======================================================================
+// function : ColorToQColor
+// purpose :
+// =======================================================================
+
+QColor ViewControl_ColorSelector::ColorToQColor (const Quantity_Color& theColor)
+{
+  int aDelta = 255;
+
+  Standard_Real aRed, aGreen, aBlue;
+  theColor.Values (aRed, aGreen, aBlue, Quantity_TOC_RGB);
+
+  return QColor((int)(aRed * aDelta), (int)(aGreen * aDelta), (int)(aBlue * aDelta));
+}
+
+// =======================================================================
+// function : ColorToQColor
+// purpose :
+// =======================================================================
+
+QColor ViewControl_ColorSelector::ColorToQColor (const Quantity_ColorRGBA& theColor)
+{
+  int aDelta = 255;
+
+  Standard_Real aRed, aGreen, aBlue;
+  theColor.GetRGB().Values (aRed, aGreen, aBlue, Quantity_TOC_RGB);
+
+  return QColor((int)(aRed * aDelta), (int)(aGreen * aDelta), (int)(aBlue * aDelta));
+}
+
+// =======================================================================
+// function : StringToColor
+// purpose :
+// =======================================================================
+
+Quantity_Color ViewControl_ColorSelector::StringToColor (const QString& theColor, Standard_ShortReal& theAlpha)
+{
+  Quantity_ColorRGBA aColorGRBA = StringToColorRGBA (theColor);
+  theAlpha = aColorGRBA.Alpha();
+  return aColorGRBA.GetRGB();
+}
+
+// =======================================================================
+// function : StringToColor
+// purpose :
+// =======================================================================
+
+Quantity_Color ViewControl_ColorSelector::StringToColor (const QString& theColor)
+{
+  Quantity_Color aColor;
+  Standard_SStream aStream;
+  aStream << theColor.toStdString();
+  int aStreamPos = 1;
+  aColor.InitFromJson (aStream, aStreamPos);
+  return aColor;
+
+  //return StringToColorRGBA (theColor).GetRGB();
+}
+
+// =======================================================================
+// function : StringToColorRGBA
+// purpose :
+// =======================================================================
+
+Quantity_ColorRGBA ViewControl_ColorSelector::StringToColorRGBA (const QString& theColor)
+{
+  Quantity_ColorRGBA aColorRGBA;
+  Standard_SStream aStream;
+  aStream << theColor.toStdString();
+  int aStreamPos = 1;
+  aColorRGBA.InitFromJson (aStream, aStreamPos);
+  return aColorRGBA;
+
+  //float anAlpha = 1.0f;
+
+  //QStringList aList = theColor.split (ViewControl_ColorSelector::ColorSeparator(), QString::SkipEmptyParts);
+  //if (aList.size() < 3)
+  //  return Quantity_ColorRGBA();
+
+  //if (aList.size() == 4)
+  //  anAlpha = aList[3].toFloat();
+
+  //return Quantity_ColorRGBA (aList[0].toFloat(), aList[1].toFloat(), aList[2].toFloat(), anAlpha);
+}
+
+// =======================================================================
+// function : onParametersTableSelectionChanged
+// purpose :
+// =======================================================================
+
+Standard_Boolean ViewControl_ColorSelector::IsExactColorName (const Quantity_ColorRGBA& theColor,
+                                                              Quantity_NameOfColor& theColorName)
+{
+  theColorName = theColor.GetRGB().Name();
+  return Quantity_Color (theColorName).IsEqual (theColor.GetRGB());
+}
+
+// =======================================================================
+// function : onParametersTableSelectionChanged
+// purpose :
+// =======================================================================
+
+void ViewControl_ColorSelector::onParametersTableSelectionChanged (const QItemSelection&, const QItemSelection&)
+{
+  //Quantity_ColorRGBA aColor = StringToColorRGBA (theColor);
+  //// parameters model
+  //ViewControl_TableModel* aTableModel = dynamic_cast<ViewControl_TableModel*> (myParameters->model());
+  //ViewControl_ParametersModel* aParametersModel = dynamic_cast<ViewControl_ParametersModel*> (aTableModel->ModelValues());
+  //aParametersModel->SetColor (aColor);
+
+  //// OCCT color model
+  //Quantity_NameOfColor aColorName;
+  //bool isExactColorName = ViewControl_ColorSelector::IsExactColorName(aColor, aColorName);
+  //ViewControl_OCCTColorModel* anOCCTColorModel = dynamic_cast<ViewControl_OCCTColorModel*>(myOCCTColors->model());
+  //anOCCTColorModel->SetColor (aColorName, isExactColorName ? ViewControl_ColorDelegateKind_Selected
+  //                                                         : ViewControl_ColorDelegateKind_Activated);
+}
+
+// =======================================================================
+// function : onOCCTColorsTableSelectionChanged
+// purpose :
+// =======================================================================
+
+void ViewControl_ColorSelector::onOCCTColorsTableSelectionChanged (const QItemSelection& theSelected, const QItemSelection&)
+{
+  QModelIndexList aSelectedIndices = theSelected.indexes();
+  if (aSelectedIndices.size() != 1)
+    return;
+
+  ViewControl_OCCTColorModel* anOCCTColorModel = dynamic_cast<ViewControl_OCCTColorModel*>(myOCCTColors->model());
+  Quantity_NameOfColor aNameOfColor;
+  if (!anOCCTColorModel->GetOCCTColor (aSelectedIndices.first(), aNameOfColor))
+    return;
+
+  anOCCTColorModel->SetColor (aNameOfColor, ViewControl_ColorDelegateKind_Selected);
+
+  // parameters model
+  ViewControl_TableModel* aTableModel = dynamic_cast<ViewControl_TableModel*> (myParameters->model());
+  ViewControl_ParametersModel* aParametersModel = dynamic_cast<ViewControl_ParametersModel*> (aTableModel->ModelValues());
+  Quantity_Color anOCCTColor (aNameOfColor);
+  aParametersModel->SetColor (Quantity_ColorRGBA (anOCCTColor), aTableModel);
+}
diff --git a/tools/ViewControl/ViewControl_ColorSelector.hxx b/tools/ViewControl/ViewControl_ColorSelector.hxx
new file mode 100644 (file)
index 0000000..b045f64
--- /dev/null
@@ -0,0 +1,119 @@
+// Created on: 2018-08-16
+// Created by: Natalia ERMOLAEVA
+// Copyright (c) 2018 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement. 
+
+#ifndef ViewControl_ColorSelector_H
+#define ViewControl_ColorSelector_H
+
+#include <Quantity_ColorRGBA.hxx>
+
+#include <Standard_WarningsDisable.hxx>
+#include <QColor>
+#include <QDialog>
+//#include <QPushButton>
+#include <QItemSelection>
+#include <QString>
+#include <QWidget>
+#include <Standard_WarningsRestore.hxx>
+
+class ViewControl_ColorPicker;
+class QDialogButtonBox;
+class QTableView;
+
+//! \class ViewControl_ColorSelector
+//! \brief Selector of OCCT color
+class ViewControl_ColorSelector : public QDialog
+{
+  Q_OBJECT
+public:
+
+  //! Constructor
+  ViewControl_ColorSelector (QWidget* theParent);
+
+  //! Destructor
+  virtual ~ViewControl_ColorSelector() Standard_OVERRIDE {}
+
+
+  //! Inits control by the color value
+  //! \param theColor text color value
+  void SetStreamValue (const QString& theColor);
+
+  //! Returns current selected color value
+  //! \return text color value
+  QString GetStreamValue() const;
+
+  //! Updates OCCT color model by changing color in parameter model
+  void ParameterColorChanged();
+
+  //! Converts color to string value in form: r;g;b
+  //! \param theColor color value
+  //! \return text value
+  static QString ColorToString (const Quantity_Color& theColor);
+
+  //! Converts color to string value in form: r;g;b;alpha
+  //! \param theColor color value
+  //! \return text value
+  static QString ColorToString (const Quantity_ColorRGBA& theColor);
+
+  //! Converts color to QColor value in form: r;g;b
+  //! \param theColor color value
+  //! \return qt color value
+  static QColor ColorToQColor (const Quantity_Color& theColor);
+
+  //! Converts color to QColor value in form: r;g;b;a
+  //! \param theColor color value
+  //! \return qt color value
+  static QColor ColorToQColor (const Quantity_ColorRGBA& theColor);
+
+  //! Converts string to color value from a form: r;g;b;a
+  //! \param theColor text color value
+  //! \return color value
+  static Quantity_Color StringToColor (const QString& theColor, Standard_ShortReal& theAlpha);
+
+  //! Converts string to color value from a form: r;g;b
+  //! \param theColor text color value
+  //! \return color value
+  static Quantity_Color StringToColor (const QString& theColor);
+
+  //! Converts string to color value from a form: r;g;b;a
+  //! \param theColor text color value
+  //! \return color value
+  static Quantity_ColorRGBA StringToColorRGBA (const QString& theColor);
+
+  static Standard_Boolean IsExactColorName (const Quantity_ColorRGBA& theColor,
+                                            Quantity_NameOfColor& theColorName);
+
+private:
+  //! Returns symbol used as a separtor of color components in string conversion
+  //! \return symbol value
+  static QString ColorSeparator() { return ";"; }
+
+private slots:
+  //! Slots listen selection change and update the current control content by selection
+  //! \param theSelected container of selected items
+  //! \param theDeselected container of items that become deselected
+  void onParametersTableSelectionChanged (const QItemSelection& theSelected, const QItemSelection& theDeselected);
+
+  //! Slots listen selection change and update the current control content by selection
+  //! \param theSelected container of selected items
+  //! \param theDeselected container of items that become deselected
+  void onOCCTColorsTableSelectionChanged (const QItemSelection& theSelected, const QItemSelection& theDeselected);
+
+private:
+  QTableView* myParameters; //! current color parameters (RGB, alpha, color name)
+  ViewControl_ColorPicker* myColorPicker; //! color picker
+  QTableView* myOCCTColors; //! OCCT color values
+  QDialogButtonBox* myDialogButtons; //! OK/Cancel buttons
+};
+#endif
index 7d12ae011534f72206ddb481c99ce6a075f256f3..657f68eca1866b5fe825abd399f110a5174c5e5b 100644 (file)
@@ -21,6 +21,7 @@ enum ViewControl_EditType
 {
   ViewControl_EditType_None, //!< View widget is null
   ViewControl_EditType_Bool, //!< check box widget
+  ViewControl_EditType_Color, //!< color selector widget
   ViewControl_EditType_Double, //!< line edit widget used double validator
   ViewControl_EditType_Line, //!< line edit widget
   ViewControl_EditType_Spin, //!< spin box widget
index 76269f21b09378520d426728199a47facf94cd7b..3bd70ffc2f633ae9eaefa8651bbea1c12eb61973 100644 (file)
@@ -14,6 +14,7 @@
 // commercial license or contractual agreement. 
 
 #include <inspector/ViewControl_Table.hxx>
+#include <inspector/ViewControl_TableItemDelegate.hxx>
 #include <inspector/ViewControl_TableModel.hxx>
 #include <inspector/ViewControl_Tools.hxx>
 
@@ -46,6 +47,8 @@ ViewControl_Table::ViewControl_Table (QWidget* theParent)
   myTableView = new QTableView (myMainWidget);
   myTableView->setVerticalScrollMode (QAbstractItemView::ScrollPerPixel);
 
+  myTableView->setItemDelegate (new ViewControl_TableItemDelegate (theParent));
+
   QHeaderView* aVHeader = myTableView->verticalHeader();
   int aDefCellSize = aVHeader->minimumSectionSize();
   aVHeader->setDefaultSectionSize (aDefCellSize);
@@ -82,6 +85,9 @@ void ViewControl_Table::Init (ViewControl_TableModelValues* theModelValues)
 
   myTableView->horizontalHeader()->setVisible (theModelValues->IsHeaderVisible (Qt::Horizontal));
 
+  ViewControl_TableItemDelegate* anItemDelegate = dynamic_cast<ViewControl_TableItemDelegate*>(myTableView->itemDelegate());
+  anItemDelegate->SetModelValues (theModelValues);
+
   myTableView->verticalHeader()->setVisible (theModelValues->IsHeaderVisible (Qt::Vertical));
   int aSectionSize;
   if (theModelValues->DefaultSectionSize (Qt::Vertical, aSectionSize) )
diff --git a/tools/ViewControl/ViewControl_TableItemDelegate.cxx b/tools/ViewControl/ViewControl_TableItemDelegate.cxx
new file mode 100644 (file)
index 0000000..bad38da
--- /dev/null
@@ -0,0 +1,206 @@
+// Created on: 2018-08-09
+// Created by: Natalia ERMOLAEVA
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement. 
+
+#include <inspector/ViewControl_TableItemDelegate.hxx>
+#include <inspector/ViewControl_ColorSelector.hxx>
+#include <inspector/ViewControl_TableModelValues.hxx>
+#include <inspector/ViewControl_EditType.hxx>
+#include <inspector/TreeModel_ItemProperties.hxx>
+//#include <inspector/ViewControl_TableDoubleVector.hxx>
+
+#include <Standard_WarningsDisable.hxx>
+#include <QFont>
+#include <QCheckBox>
+#include <QComboBox>
+#include <QDoubleValidator>
+#include <QLineEdit>
+#include <QPushButton>
+#include <QSpinBox>
+#include <Standard_WarningsRestore.hxx>
+
+// =======================================================================
+// function : Constructor
+// purpose :
+// =======================================================================
+
+ViewControl_TableItemDelegate::ViewControl_TableItemDelegate (QObject* theParent)
+ : QItemDelegate (theParent), myModelValues (0)
+{
+}
+
+// =======================================================================
+// function : createEditor
+// purpose :
+// =======================================================================
+
+QWidget* ViewControl_TableItemDelegate::createEditor (QWidget* theParent,
+                                                      const QStyleOptionViewItem&,
+                                                      const QModelIndex& theIndex) const
+{
+  if (!myModelValues)
+    return 0;
+
+  int aRow = theIndex.row();
+  int aColumn = theIndex.column();
+  ViewControl_EditType anEditType = myModelValues->EditType (aRow, aColumn);
+
+  QWidget* anEditor = createEditorControl (theParent, anEditType);
+  initEditorParameters (anEditor, anEditType, myModelValues, aRow, aColumn);
+  return anEditor;
+}
+
+// =======================================================================
+// function : setEditorData
+// purpose :
+// =======================================================================
+
+void ViewControl_TableItemDelegate::setEditorData (QWidget* theEditor, const QModelIndex& theIndex) const
+{
+  if (!myModelValues)
+    return;
+
+  int aRow = theIndex.row();
+  int aColumn = theIndex.column();
+  ViewControl_EditType anEditType = myModelValues->EditType (aRow, aColumn);
+
+  setEditorValue (theEditor, anEditType, theIndex.model()->data(theIndex));
+}
+
+// =======================================================================
+// function : setModelData
+// purpose :
+// =======================================================================
+
+void ViewControl_TableItemDelegate::setModelData (QWidget* theEditor, QAbstractItemModel* theModel,
+                                                  const QModelIndex& theIndex) const
+{
+  if (!myModelValues)
+    return;
+
+  int aRow = theIndex.row();
+  int aColumn = theIndex.column();
+  ViewControl_EditType anEditType = myModelValues->EditType (aRow, aColumn);
+  theModel->setData (theIndex, getEditorValue (theEditor, anEditType));
+}
+
+// =======================================================================
+// function : createEditorControl
+// purpose :
+// =======================================================================
+
+QWidget* ViewControl_TableItemDelegate::createEditorControl (QWidget* theParent, const ViewControl_EditType theEditType)
+{
+  switch (theEditType)
+  {
+    case ViewControl_EditType_None: return 0;
+    case ViewControl_EditType_Bool: return new QComboBox (theParent);
+    case ViewControl_EditType_Color: return new ViewControl_ColorSelector (theParent);
+    case ViewControl_EditType_Double:
+    {
+      QLineEdit* aLineEdit = new QLineEdit (theParent);
+      aLineEdit->setValidator (new QDoubleValidator (theParent));
+      return aLineEdit;
+    }
+    case ViewControl_EditType_Line: return new QLineEdit (theParent);
+    case ViewControl_EditType_Spin:
+    {
+      QSpinBox* aSpinBox = new QSpinBox (theParent);
+      aSpinBox->setRange (IntegerFirst(), IntegerLast());
+      return aSpinBox;
+    }
+    case ViewControl_EditType_DoAction: return new QPushButton (theParent);
+    //case ViewControl_EditType_DoubleVector: return new ViewControl_TableDoubleVector(theParent);
+
+    default: return 0;
+  }
+}
+
+// =======================================================================
+// function : initEditorParameters
+// purpose :
+// =======================================================================
+
+void ViewControl_TableItemDelegate::initEditorParameters (QWidget* theEditor,
+                                                          const ViewControl_EditType theEditType,
+                                                          ViewControl_TableModelValues*,
+                                                          const int, const int)
+{
+  switch (theEditType)
+  {
+    case ViewControl_EditType_Bool:
+    {
+      (qobject_cast<QComboBox*> (theEditor))->insertItem(0, "true");
+      (qobject_cast<QComboBox*> (theEditor))->insertItem(1, "false");
+      break;
+    }
+    case ViewControl_EditType_Double:
+    {
+    }
+    default: break;
+  }
+}
+
+// =======================================================================
+// function : setEditorValue
+// purpose :
+// =======================================================================
+
+void ViewControl_TableItemDelegate::setEditorValue (QWidget* theEditor, const ViewControl_EditType theEditType,
+                                                    const QVariant& theValue) const
+{
+  switch (theEditType)
+  {
+    case ViewControl_EditType_None: break;
+    case ViewControl_EditType_Bool: (qobject_cast<QComboBox*>(theEditor))->setCurrentIndex (theValue.toBool() ? 0 : 1); break;
+    case ViewControl_EditType_Color:
+    {
+      if (!myModelValues)
+        break;
+
+      const TCollection_AsciiString& aStreamValue = myModelValues->Properties()->StreamValue();
+      (qobject_cast<ViewControl_ColorSelector*>(theEditor))->SetStreamValue (aStreamValue.ToCString());//theValue.toString());
+      break;
+    }
+    case ViewControl_EditType_Double:
+    case ViewControl_EditType_Line: (qobject_cast<QLineEdit*>(theEditor))->setText (theValue.toString()); break;
+    case ViewControl_EditType_Spin: (qobject_cast<QSpinBox*>(theEditor))->setValue (theValue.toInt()); break;
+    case ViewControl_EditType_DoAction: (qobject_cast<QPushButton*>(theEditor))->setText ("UnSelect"); break;
+    //case ViewControl_EditType_DoubleVector: (qobject_cast<ViewControl_TableDoubleVector*>(theEditor))->SetVectorValue(theValue.toString()); break;
+
+    default: break;
+  }
+}
+
+// =======================================================================
+// function : getEditorValue
+// purpose :
+// =======================================================================
+
+QVariant ViewControl_TableItemDelegate::getEditorValue (QWidget* theEditor, const ViewControl_EditType theEditType)
+{
+  switch (theEditType)
+  {
+    case ViewControl_EditType_None: return QVariant();
+    case ViewControl_EditType_Bool: return (qobject_cast<QComboBox*>(theEditor))->currentIndex() == 0 ? true : false;
+    case ViewControl_EditType_Color: return (qobject_cast<ViewControl_ColorSelector*>(theEditor))->GetStreamValue();
+    case ViewControl_EditType_Double:
+    case ViewControl_EditType_Line: return (qobject_cast<QLineEdit*>(theEditor))->text();
+    case ViewControl_EditType_Spin: return (qobject_cast<QSpinBox*>(theEditor))->value();
+    case ViewControl_EditType_DoAction: return QVariant ("Clicked");
+    //case ViewControl_EditType_DoubleVector: return (qobject_cast<ViewControl_TableDoubleVector*>(theEditor))->GetVector();
+
+    default: return QVariant();
+  }
+}
diff --git a/tools/ViewControl/ViewControl_TableItemDelegate.hxx b/tools/ViewControl/ViewControl_TableItemDelegate.hxx
new file mode 100644 (file)
index 0000000..184a65b
--- /dev/null
@@ -0,0 +1,98 @@
+// Created on: 2018-08-09
+// Created by: Natalia ERMOLAEVA
+// Copyright (c) 2017 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement. 
+
+#ifndef ViewControl_TableItemDelegate_H
+#define ViewControl_TableItemDelegate_H
+
+#include <Standard_Macro.hxx>
+#include <inspector/ViewControl_EditType.hxx>
+
+#include <Standard_WarningsDisable.hxx>
+#include <QItemDelegate>
+#include <Standard_WarningsRestore.hxx>
+
+class ViewControl_TableModelValues;
+
+//! \class ViewControl_TableItemDelegate
+//! \brief This is an implementation for ViewControl_TableModel to present AIS_InteractiveContext object
+class ViewControl_TableItemDelegate : public QItemDelegate
+{
+public:
+
+  //! Constructor
+  //! \param theParent parent object
+  Standard_EXPORT ViewControl_TableItemDelegate (QObject* theParent = 0);
+
+  //! Destructor
+  virtual ~ViewControl_TableItemDelegate() Standard_OVERRIDE {}
+
+  //! Sets table model values
+  //! \param theModelValues instance of model values
+  void SetModelValues (ViewControl_TableModelValues* theModelValues) { myModelValues = theModelValues; }
+
+  //! Creates widget editor: spin box, combo box or line edit
+  //! \param theParent parent widget
+  //! \param theOption style option
+  //! \param theIndex index of requested widget
+  virtual QWidget* createEditor (QWidget* theParent, const QStyleOptionViewItem& theOption,
+                                 const QModelIndex& theIndex) const Standard_OVERRIDE;
+
+  //! Sets the data to be displayed and edited by the editor from the data model item specified by the model index
+  //! \param theEditor editor to be filled
+  //! \param theIndex index of requested widget, contains information about model
+  virtual void setEditorData (QWidget* theEditor, const QModelIndex& theIndex) const Standard_OVERRIDE;
+
+  //! Gets data from the editor widget and stores it in the specified model at the item index.
+  //! \param theEditor editor to be filled
+  //! \param theModel data model
+  //! \param theIndex index of requested widget, contains information about model
+  virtual void setModelData (QWidget* theEditor, QAbstractItemModel* theModel,
+                             const QModelIndex& theIndex) const Standard_OVERRIDE;
+
+private:
+  //! Creates an editor
+  //! \param theParent parent widget
+  //! \param theEditType edition control type
+  //! \return edit control
+  static QWidget* createEditorControl (QWidget* theParent, const ViewControl_EditType theEditType);
+
+  //! Inits an editor by model values parameters
+  //! \param theEditor editor
+  //! \param theEditType edition control type
+  //! \param theModelValues custom implementation to provide parameters
+  //! \param theRow a model index row
+  //! \param theColumn a model index column
+  //! \return edit control
+  static void initEditorParameters (QWidget* theEditor, const ViewControl_EditType theEditType,
+                                    ViewControl_TableModelValues* theModelValues,
+                                    const int theRow, const int theColumn);
+
+  //! Sets editor value
+  //! \param theEditor editor
+  //! \param theEditType editor typ
+  //! \param theValue new value
+  void setEditorValue (QWidget* theEditor, const ViewControl_EditType theEditType, const QVariant& theValue) const;
+
+  //! Returns value of spin box editor
+  //! \param theEditor editor
+  //! \param theEditType editor typ
+  //! \return current value
+  static QVariant getEditorValue (QWidget* theEditor, const ViewControl_EditType theEditType);
+
+private:
+  ViewControl_TableModelValues* myModelValues; //!< table model values
+};
+
+#endif
index 058d008e951945425986707461bd1478b8735356..17131a6fe03b1a1dd44b4cf7fc399531ca77862b 100644 (file)
@@ -44,7 +44,7 @@ public:
   virtual ~ViewControl_TableModelValues() {}
 
   //! Returns item table properties builder
-  Handle(TreeModel_ItemProperties) Properties() const { return myProperties; }
+  const Handle(TreeModel_ItemProperties)& Properties() const { return myProperties; }
 
   //! Sets item table properties builder
   void SetProperties (const Handle(TreeModel_ItemProperties)& theProperties) { myProperties = theProperties; }
index 1ad884d5d454caf8f71b3ec7ddceb80198d89ce9..bb27e601a80eb99626534deba6cf19618faf6bce 100644 (file)
@@ -106,3 +106,39 @@ ViewControl_TableModelValues* ViewControl_Tools::CreateTableModelValues (QItemSe
   aTableValues->SetProperties (anItemProperties);
   return aTableValues;
 }
+
+// =======================================================================
+// function : ToVariant
+// purpose :
+// =======================================================================
+QVariant ViewControl_Tools::ToVariant (const Standard_ShortReal theValue)
+{
+  return QVariant (QLocale().toString (theValue));
+}
+
+// =======================================================================
+// function : ToVariant
+// purpose :
+// =======================================================================
+QVariant ViewControl_Tools::ToVariant (const Standard_Real theValue)
+{
+  return QVariant (QLocale().toString (theValue));
+}
+
+// =======================================================================
+// function : ToRealValue
+// purpose :
+// =======================================================================
+Standard_ShortReal ViewControl_Tools::ToShortRealValue (const QVariant& theValue)
+{
+  return QLocale().toFloat (theValue.toString());
+}
+
+// =======================================================================
+// function : ToRealValue
+// purpose :
+// =======================================================================
+Standard_Real ViewControl_Tools::ToRealValue (const QVariant& theValue)
+{
+  return QLocale().toDouble (theValue.toString());
+}
index 39994b6cbeb8f83aa5ee05249ebd330e7ce7344d..db33e8c986da6ffd6ba8226da56ee65eba8d6e48 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <Standard_WarningsDisable.hxx>
 #include <QString>
+#include <QVariant>
 #include <Standard_WarningsRestore.hxx>
 
 class ViewControl_TableModelValues;
@@ -63,6 +64,26 @@ public:
   //! It is created if the selection contains only one item and it has a property item
   Standard_EXPORT static ViewControl_TableModelValues* CreateTableModelValues (QItemSelectionModel* theSelectionModel);
 
+  //! Convert real value to string value
+  //! \param theValue a short real value
+  //! \return the string value
+  Standard_EXPORT static QVariant ToVariant (const Standard_ShortReal theValue);
+
+  //! Convert real value to string value
+  //! \param theValue a real value
+  //! \return the string value
+  Standard_EXPORT static QVariant ToVariant (const Standard_Real theValue);
+
+  //! Convert real value to real value
+  //! \param theValue a string value
+  //! \return the real value
+  Standard_EXPORT static Standard_ShortReal ToShortRealValue (const QVariant& theValue);
+
+  //! Convert real value to string value
+  //! \param theValue a string value
+  //! \return the real value
+  Standard_EXPORT static Standard_Real ToRealValue (const QVariant& theValue);
+
 };
 
 #endif