Skip to content

Commit

Permalink
Material: Mateiral editor UI fixes
Browse files Browse the repository at this point in the history
- Fixed color buttons
- Introduced "Section Color" property
- Fixed named properties
- Added preview icons
- Remember UI dimensions and expanded states
  • Loading branch information
yorikvanhavre committed Oct 27, 2020
1 parent d0eb715 commit 0f87516
Show file tree
Hide file tree
Showing 8 changed files with 260 additions and 167 deletions.
52 changes: 35 additions & 17 deletions src/Mod/Arch/ArchMaterial.py
Expand Up @@ -516,16 +516,17 @@ def __init__(self,obj=None):
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)
Expand All @@ -551,21 +552,14 @@ def setFields(self):
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:
Expand All @@ -589,18 +583,35 @@ def setFields(self):
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:
Expand Down Expand Up @@ -635,11 +646,18 @@ def setFather(self,text):

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.
Expand Down
24 changes: 24 additions & 0 deletions src/Mod/Arch/Resources/ui/ArchMaterial.ui
Expand Up @@ -131,6 +131,30 @@
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_7">
<item>
<widget class="QLabel" name="label_8">
<property name="text">
<string>Section Color</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="ButtonSectionColor">
<property name="maximumSize">
<size>
<width>30</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_8">
<item>
Expand Down
110 changes: 98 additions & 12 deletions src/Mod/Material/MaterialEditor.py
Expand Up @@ -26,11 +26,11 @@

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:
Expand Down Expand Up @@ -61,6 +61,14 @@ def __init__(self, obj=None, prop=None, material=None, card_path=''):
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
Expand All @@ -72,9 +80,17 @@ def __init__(self, obj=None, prop=None, material=None, card_path=''):
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)
Expand All @@ -92,7 +108,7 @@ def __init__(self, obj=None, prop=None, material=None, card_path=''):
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)
Expand Down Expand Up @@ -126,6 +142,7 @@ def implementModel(self):

'''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()
Expand All @@ -147,18 +164,20 @@ def implementModel(self):
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):

Expand All @@ -181,6 +200,11 @@ def updateMatParamsInTree(self, data):
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)
Expand All @@ -195,6 +219,7 @@ def updateMatParamsInTree(self, data):
self.customprops.append(k)

def chooseMaterial(self, index):

if index < 0:
return
self.card_path = self.widget.ComboMaterial.itemData(index)
Expand Down Expand Up @@ -256,13 +281,26 @@ def openProductURL(self):
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 = ""
Expand Down Expand Up @@ -338,7 +376,7 @@ def deleteCustomProperty(self, key=None):

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.'''
Expand Down Expand Up @@ -370,6 +408,8 @@ def checkDeletable(self, index):
buttonDeleteProperty.setEnabled(False)
buttonDeleteProperty.setProperty("text", "Delete property")

self.updatePreviews()

def getDict(self):
"returns a dictionary from the contents of the editor."

Expand Down Expand Up @@ -414,6 +454,52 @@ def setTexture(self, pattern):
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(
Expand Down Expand Up @@ -550,7 +636,7 @@ def setEditorData(self, editor, index):
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":
Expand Down Expand Up @@ -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

Expand Down
4 changes: 2 additions & 2 deletions src/Mod/Material/Resources/icons/preview-rendered.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/Mod/Material/Resources/icons/preview-vector.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

1 comment on commit 0f87516

@berndhahnebach
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a regresseion was added which was fixed in 6455352 Forum link: https://forum.freecadweb.org/viewtopic.php?f=18&t=52010

Please sign in to comment.