diff --git a/src/Mod/Arch/ArchMaterial.py b/src/Mod/Arch/ArchMaterial.py
index 04537d684b..2edaa0c754 100644
--- a/src/Mod/Arch/ArchMaterial.py
+++ b/src/Mod/Arch/ArchMaterial.py
@@ -516,16 +516,17 @@ class _ArchMaterialTaskPanel:
self.existingmaterials = []
self.obj = obj
self.form = FreeCADGui.PySideUic.loadUi(":/ui/ArchMaterial.ui")
- self.color = QtGui.QColor(128,128,128)
colorPix = QtGui.QPixmap(16,16)
- colorPix.fill(self.color)
+ colorPix.fill(QtGui.QColor(204,204,204))
self.form.ButtonColor.setIcon(QtGui.QIcon(colorPix))
+ self.form.ButtonSectionColor.setIcon(QtGui.QIcon(colorPix))
self.form.ButtonUrl.setIcon(QtGui.QIcon(":/icons/internet-web-browser.svg"))
QtCore.QObject.connect(self.form.comboBox_MaterialsInDir, QtCore.SIGNAL("currentIndexChanged(QString)"), self.chooseMat)
QtCore.QObject.connect(self.form.comboBox_FromExisting, QtCore.SIGNAL("currentIndexChanged(int)"), self.fromExisting)
QtCore.QObject.connect(self.form.comboFather, QtCore.SIGNAL("currentIndexChanged(QString)"), self.setFather)
QtCore.QObject.connect(self.form.comboFather, QtCore.SIGNAL("currentTextChanged(QString)"), self.setFather)
QtCore.QObject.connect(self.form.ButtonColor,QtCore.SIGNAL("pressed()"),self.getColor)
+ QtCore.QObject.connect(self.form.ButtonSectionColor,QtCore.SIGNAL("pressed()"),self.getSectionColor)
QtCore.QObject.connect(self.form.ButtonUrl,QtCore.SIGNAL("pressed()"),self.openUrl)
QtCore.QObject.connect(self.form.ButtonEditor,QtCore.SIGNAL("pressed()"),self.openEditor)
QtCore.QObject.connect(self.form.ButtonCode,QtCore.SIGNAL("pressed()"),self.getCode)
@@ -551,21 +552,14 @@ class _ArchMaterialTaskPanel:
self.form.FieldName.setText(self.obj.Label)
if 'Description' in self.material:
self.form.FieldDescription.setText(self.material['Description'])
- col = None
if 'DiffuseColor' in self.material:
- col = self.material["DiffuseColor"]
+ self.form.ButtonColor.setIcon(self.getColorIcon(self.material["DiffuseColor"]))
elif 'ViewColor' in self.material:
- col = self.material["ViewColor"]
+ self.form.ButtonColor.setIcon(self.getColorIcon(self.material["ViewColor"]))
elif 'Color' in self.material:
- col = self.material["Color"]
- if col:
- if "(" in col:
- c = tuple([float(f) for f in col.strip("()").split(",")])
- self.color = QtGui.QColor()
- self.color.setRgbF(c[0],c[1],c[2])
- colorPix = QtGui.QPixmap(16,16)
- colorPix.fill(self.color)
- self.form.ButtonColor.setIcon(QtGui.QIcon(colorPix))
+ self.form.ButtonColor.setIcon(self.getColorIcon(self.material["Color"]))
+ if 'SectionColor' in self.material:
+ self.form.ButtonSectionColor.setIcon(self.getColorIcon(self.material["SectionColor"]))
if 'StandardCode' in self.material:
self.form.FieldCode.setText(self.material['StandardCode'])
if 'ProductURL' in self.material:
@@ -589,18 +583,35 @@ class _ArchMaterialTaskPanel:
self.form.comboFather.addItem(father)
self.form.comboFather.setCurrentIndex(self.form.comboFather.count()-1)
+ def getColorIcon(self,color):
+ if color:
+ if "(" in color:
+ c = tuple([float(f) for f in color.strip("()").split(",")])
+ qcolor = QtGui.QColor()
+ qcolor.setRgbF(c[0],c[1],c[2])
+ colorPix = QtGui.QPixmap(16,16)
+ colorPix.fill(qcolor)
+ icon = QtGui.QIcon(colorPix)
+ return icon
+ return QtGui.QIcon()
def getFields(self):
"sets self.material from the contents of the task box"
self.material['Name'] = self.form.FieldName.text()
self.material['Description'] = self.form.FieldDescription.text()
- self.material['DiffuseColor'] = str(self.color.getRgbF()[:3])
+ self.material['DiffuseColor'] = self.getColorFromIcon(self.form.ButtonColor.icon())
self.material['ViewColor'] = self.material['DiffuseColor']
self.material['Color'] = self.material['DiffuseColor']
+ self.material['SectionColor'] = self.getColorFromIcon(self.form.ButtonSectionColor.icon())
self.material['StandardCode'] = self.form.FieldCode.text()
self.material['ProductURL'] = self.form.FieldUrl.text()
self.material['Transparency'] = str(self.form.SpinBox_Transparency.value())
+ def getColorFromIcon(self,icon):
+ "gets pixel color from the given icon"
+ pixel = icon.pixmap(16,16).toImage().pixel(0,0)
+ return str(QtGui.QColor(pixel).getRgbF())
+
def accept(self):
self.getFields()
if self.obj:
@@ -635,11 +646,18 @@ class _ArchMaterialTaskPanel:
def getColor(self):
"opens a color picker dialog"
- self.color = QtGui.QColorDialog.getColor()
+ color = QtGui.QColorDialog.getColor()
colorPix = QtGui.QPixmap(16,16)
- colorPix.fill(self.color)
+ colorPix.fill(color)
self.form.ButtonColor.setIcon(QtGui.QIcon(colorPix))
+ def getSectionColor(self):
+ "opens a color picker dialog"
+ color = QtGui.QColorDialog.getColor()
+ colorPix = QtGui.QPixmap(16,16)
+ colorPix.fill(color)
+ self.form.ButtonSectionColor.setIcon(QtGui.QIcon(colorPix))
+
def fillMaterialCombo(self):
"fills the combo with the existing FCMat cards"
# look for cards in both resources dir and a Materials sub-folder in the user folder.
diff --git a/src/Mod/Arch/Resources/ui/ArchMaterial.ui b/src/Mod/Arch/Resources/ui/ArchMaterial.ui
index 59065164a8..f195beaad0 100644
--- a/src/Mod/Arch/Resources/ui/ArchMaterial.ui
+++ b/src/Mod/Arch/Resources/ui/ArchMaterial.ui
@@ -131,6 +131,30 @@
+ -
+
+
-
+
+
+ Section Color
+
+
+
+ -
+
+
+
+ 30
+ 16777215
+
+
+
+
+
+
+
+
+
-
-
diff --git a/src/Mod/Material/MaterialEditor.py b/src/Mod/Material/MaterialEditor.py
index c9713cce28..019104bcde 100644
--- a/src/Mod/Material/MaterialEditor.py
+++ b/src/Mod/Material/MaterialEditor.py
@@ -26,11 +26,11 @@ __url__ = "http://www.freecadweb.org"
import os
import sys
-from PySide import QtCore, QtGui
-# from PySide import QtUiTools, QtSvg
+from PySide import QtCore, QtGui, QtSvg
import FreeCAD
import FreeCADGui
+import Material_rc
# is this still needed after the move to card utils???
if sys.version_info.major >= 3:
@@ -61,6 +61,14 @@ class MaterialEditor:
os.path.dirname(__file__) + os.sep + "materials-editor.ui"
)
+ self.widget.setWindowIcon(QtGui.QIcon(":/icons/preview-rendered.svg"))
+
+ # restore size and position
+ p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Material")
+ w = p.GetInt("MaterialEditorWidth",441)
+ h = p.GetInt("MaterialEditorHeight",626)
+ self.widget.resize(w,h)
+
# additional UI fixes and tweaks
widget = self.widget
buttonURL = widget.ButtonURL
@@ -72,9 +80,17 @@ class MaterialEditor:
comboMaterial = widget.ComboMaterial
treeView = widget.treeView
- # temporarily hide preview fields, as they are not used yet
- # TODO : implement previews
- widget.PreviewGroup.hide()
+
+ # create preview svg slots
+ self.widget.PreviewRender = QtSvg.QSvgWidget(":/icons/preview-rendered.svg")
+ self.widget.PreviewRender.setMaximumWidth(64)
+ self.widget.PreviewRender.setMinimumHeight(64)
+ self.widget.topLayout.addWidget(self.widget.PreviewRender)
+ self.widget.PreviewVector = QtSvg.QSvgWidget(":/icons/preview-vector.svg")
+ self.widget.PreviewVector.setMaximumWidth(64)
+ self.widget.PreviewVector.setMinimumHeight(64)
+ self.widget.topLayout.addWidget(self.widget.PreviewVector)
+ self.updatePreviews(mat=material)
buttonURL.setIcon(QtGui.QIcon(":/icons/internet-web-browser.svg"))
buttonDeleteProperty.setEnabled(False)
@@ -92,7 +108,7 @@ class MaterialEditor:
comboMaterial.currentIndexChanged[int].connect(self.chooseMaterial)
buttonAddProperty.clicked.connect(self.addCustomProperty)
buttonDeleteProperty.clicked.connect(self.deleteCustomProperty)
- treeView.clicked.connect(self.checkDeletable)
+ treeView.clicked.connect(self.onClickTree)
model = QtGui.QStandardItemModel()
treeView.setModel(model)
@@ -126,6 +142,7 @@ class MaterialEditor:
'''implements the model with the material attribute structure.'''
+ p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Material")
widget = self.widget
treeView = widget.treeView
model = treeView.model()
@@ -147,18 +164,20 @@ class MaterialEditor:
for properName in group[gg]:
pp = properName # property name
item = QtGui.QStandardItem(pp)
+ item.setToolTip(group[gg][properName]['Description'])
self.internalprops.append(pp)
it = QtGui.QStandardItem()
+ it.setToolTip(group[gg][properName]['Description'])
tt = group[gg][properName]['Type']
itType = QtGui.QStandardItem(tt)
top.appendRow([item, it, itType])
+ treeView.setExpanded(top.index(),p.GetBool("TreeExpand"+gg,True))
+ #top.sortChildren(0)
- top.sortChildren(0)
-
- treeView.expandAll()
+ #treeView.expandAll()
def updateMatParamsInTree(self, data):
@@ -181,6 +200,11 @@ class MaterialEditor:
it.setText(value)
del data[kk]
except KeyError:
+ # treat here changes in Material Card Template
+ # Norm -> StandardCode
+ if (kk == "Standard Code") and ("Norm" in data) and data["Norm"]:
+ it.setText(data["Norm"])
+ del data["Norm"]
it.setText("")
userGroup = root.child(gg + 1, 0)
@@ -195,6 +219,7 @@ class MaterialEditor:
self.customprops.append(k)
def chooseMaterial(self, index):
+
if index < 0:
return
self.card_path = self.widget.ComboMaterial.itemData(index)
@@ -256,13 +281,26 @@ class MaterialEditor:
def accept(self):
""
+ self.storeSize()
QtGui.QDialog.accept(self.widget)
def reject(self):
""
+ self.storeSize()
QtGui.QDialog.reject(self.widget)
+ def storeSize(self):
+ "stores the widget size"
+ # store widths
+ p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Material")
+ p.SetInt("MaterialEditorWidth",self.widget.width())
+ p.SetInt("MaterialEditorHeight",self.widget.height())
+ root = self.widget.treeView.model().invisibleRootItem()
+ for gg in range(root.rowCount()):
+ group = root.child(gg)
+ p.SetBool("TreeExpand"+group.text(),self.widget.treeView.isExpanded(group.index()))
+
def expandKey(self, key):
"adds spaces before caps in a KeyName"
nk = ""
@@ -338,7 +376,7 @@ class MaterialEditor:
buttonDeleteProperty.setEnabled(False)
- def checkDeletable(self, index):
+ def onClickTree(self, index):
'''Checks if the current item is a custom or an internal property,
and enable the delete property or delete value button.'''
@@ -370,6 +408,8 @@ class MaterialEditor:
buttonDeleteProperty.setEnabled(False)
buttonDeleteProperty.setProperty("text", "Delete property")
+ self.updatePreviews()
+
def getDict(self):
"returns a dictionary from the contents of the editor."
@@ -414,6 +454,52 @@ class MaterialEditor:
self.widget.PreviewVector.show()
'''
+ def updatePreviews(self,mat=None):
+ "updates the preview images from the content of the editor"
+ if not mat:
+ mat = self.getDict()
+ diffcol = None
+ highlightcol = None
+ sectioncol = None
+ if "DiffuseColor" in mat:
+ diffcol = mat["DiffuseColor"]
+ elif "ViewColor" in mat:
+ diffcol = mat["ViwColor"]
+ elif "Color" in mat:
+ diffcol = mat["Color"]
+ if "SpecularColor" in mat:
+ highlightcol = mat["SpecularColor"]
+ if "SectionColor" in mat:
+ sectioncol = mat["SectionColor"]
+ if diffcol or highlightcol:
+ fd = QtCore.QFile(":/icons/preview-rendered.svg")
+ if fd.open(QtCore.QIODevice.ReadOnly | QtCore.QIODevice.Text):
+ svg = QtCore.QTextStream(fd).readAll()
+ fd.close()
+ if diffcol:
+ svg = svg.replace("#d3d7cf",self.getColorHash(diffcol,val=255))
+ svg = svg.replace("#555753",self.getColorHash(diffcol,val=125))
+ if highlightcol:
+ svg = svg.replace("#fffffe",self.getColorHash(highlightcol,val=255))
+ self.widget.PreviewRender.load(QtCore.QByteArray(bytes(svg,encoding="utf8")))
+ if diffcol or sectioncol:
+ fd = QtCore.QFile(":/icons/preview-vector.svg")
+ if fd.open(QtCore.QIODevice.ReadOnly | QtCore.QIODevice.Text):
+ svg = QtCore.QTextStream(fd).readAll()
+ fd.close()
+ if diffcol:
+ svg = svg.replace("#d3d7cf",self.getColorHash(diffcol,val=255))
+ svg = svg.replace("#555753",self.getColorHash(diffcol,val=125))
+ if sectioncol:
+ svg = svg.replace("#ffffff",self.getColorHash(sectioncol,val=255))
+ self.widget.PreviewVector.load(QtCore.QByteArray(bytes(svg,encoding="utf8")))
+
+ def getColorHash(self,col,val=255):
+ "returns a '#000000' string from a '(0.1,0.2,0.3)' string"
+ col = [float(x.strip()) for x in col.strip("()").split(",")]
+ color = QtGui.QColor(int(col[0]*val),int(col[1]*val),int(col[2]*val))
+ return color.name()
+
def openfile(self):
"Opens a FCMat file"
filetuple = QtGui.QFileDialog.getOpenFileName(
@@ -550,7 +636,7 @@ class MaterialsDelegate(QtGui.QStyledItemDelegate):
if Type == "Color":
color = editor.property('color')
- color = color.getRgb()
+ color = tuple([v/255.0 for v in color.getRgb()])
item.setText(str(color))
elif Type == "File":
@@ -650,7 +736,7 @@ def string2tuple(string):
"provisionally"
value = string[1:-1]
value = value.split(',')
- value = [int(v) for v in value]
+ value = [int(float(v)*255) for v in value]
value = tuple(value)
return value
diff --git a/src/Mod/Material/Resources/icons/preview-rendered.svg b/src/Mod/Material/Resources/icons/preview-rendered.svg
index 188558ef45..bf21c95ac5 100644
--- a/src/Mod/Material/Resources/icons/preview-rendered.svg
+++ b/src/Mod/Material/Resources/icons/preview-rendered.svg
@@ -58,8 +58,8 @@
-
-
+
+
diff --git a/src/Mod/Material/Resources/icons/preview-vector.svg b/src/Mod/Material/Resources/icons/preview-vector.svg
index ba65341c53..c2d7383cb0 100644
--- a/src/Mod/Material/Resources/icons/preview-vector.svg
+++ b/src/Mod/Material/Resources/icons/preview-vector.svg
@@ -134,7 +134,7 @@
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccc" />
-
-
+
-
-
-
-
- 22
- 22
-
-
-
- Opens the Product URL of this material in an external browser
-
-
-
-
-
-
- -
-
-
-
- 120
- 0
-
-
-
- Existing material cards
-
-
+
+
-
+
+
-
+
+
+
+ 22
+ 22
+
+
+
+ Opens the Product URL of this material in an external browser
+
+
+
+
+
+
+ -
+
+
+
+ 120
+ 0
+
+
+
+ Existing material cards
+
+
+
+
+
+ -
+
+
-
+
+
+ Opens an existing material card
+
+
+ Open...
+
+
+
+ -
+
+
+ Saves this material as a card
+
+
+ Save as...
+
+
+
+
+
+
- -
-
-
-
-
-
- Opens an existing material card
-
-
- Open...
-
-
-
- -
-
-
- Saves this material as a card
-
-
- Save as...
-
-
-
-
-
-
-
-
- -
-
-
- Preview
-
-
-
-
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
- -
-
-
-
- 96
- 96
-
-
-
-
-
-
-
- -
-
-
-
- 96
- 96
-
-
-
-
-
-
-
diff --git a/src/Mod/Material/materialtools/cardutils.py b/src/Mod/Material/materialtools/cardutils.py
index e5048e1127..7af3deb437 100644
--- a/src/Mod/Material/materialtools/cardutils.py
+++ b/src/Mod/Material/materialtools/cardutils.py
@@ -99,11 +99,12 @@ def get_material_resources(category='Solid'):
custom_mat_dir = mat_prefs.GetString("CustomMaterialsDir", "")
if os.path.exists(custom_mat_dir):
resources[custom_mat_dir] = ":/icons/user.svg"
- else:
- FreeCAD.Console.PrintError(
- 'Custom material directory set by user: {} does not exist.\n'
- .format(custom_mat_dir)
- )
+ # fail silently
+ #else:
+ # FreeCAD.Console.PrintError(
+ # 'Custom material directory set by user: {} does not exist.\n'
+ # .format(custom_mat_dir)
+ # )
return resources
@@ -229,14 +230,18 @@ def get_material_template(withSpaces=False):
# on attributes, add a space before a capital letter
# will be used for better display in the ui
import re
+ new_template = []
for group in template_data:
+ new_group = {}
gg = list(group.keys())[0] # group dict has only one key
# iterating over a dict and changing it is not allowed
# thus it is iterated over a list of the keys
+ new_group[gg] = {}
for proper in list(group[gg].keys()):
new_proper = re.sub(r"(\w)([A-Z]+)", r"\1 \2", proper)
- group[gg][new_proper] = group[gg][proper]
- del group[gg][proper]
+ new_group[gg][new_proper] = group[gg][proper]
+ new_template.append(new_group)
+ template_data = new_template
return template_data