FEM: Post data visualization bug fixes and quality of life updates
This commit is contained in:
@@ -245,9 +245,6 @@ class _SummaryWidget(QtGui.QWidget):
|
||||
|
||||
# build the UI
|
||||
|
||||
self.stButton = self._button(st_object.Label)
|
||||
self.stButton.setIcon(st_object.ViewObject.Icon)
|
||||
|
||||
self.extrButton = self._button(extr_label)
|
||||
self.extrButton.setIcon(extractor.ViewObject.Icon)
|
||||
|
||||
@@ -260,6 +257,19 @@ class _SummaryWidget(QtGui.QWidget):
|
||||
else:
|
||||
self.viewButton.setIconSize(QtCore.QSize(0,0))
|
||||
|
||||
if st_object:
|
||||
self.stButton = self._button(st_object.Label)
|
||||
self.stButton.setIcon(st_object.ViewObject.Icon)
|
||||
|
||||
else:
|
||||
# that happens if the source of the extractor was deleted and now
|
||||
# that property is set to None
|
||||
self.extrButton.hide()
|
||||
self.viewButton.hide()
|
||||
|
||||
self.warning = QtGui.QLabel(self)
|
||||
self.warning.full_text = f"{extractor.Label}: Data source not available"
|
||||
|
||||
self.rmButton = QtGui.QToolButton(self)
|
||||
self.rmButton.setIcon(QtGui.QIcon.fromTheme("delete"))
|
||||
self.rmButton.setAutoRaise(True)
|
||||
@@ -270,13 +280,15 @@ class _SummaryWidget(QtGui.QWidget):
|
||||
|
||||
policy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
|
||||
self.setSizePolicy(policy)
|
||||
self.setMinimumSize(self.stButton.sizeHint()+self.frame.sizeHint()*3)
|
||||
self.setMinimumSize(self.extrButton.sizeHint()+self.frame.sizeHint()*3)
|
||||
|
||||
# connect actions. We add functions to widget, as well as the data we need,
|
||||
# and use those as callback. This way every widget knows which objects to use
|
||||
self.stButton.clicked.connect(self.showVisualization)
|
||||
self.extrButton.clicked.connect(self.editApp)
|
||||
self.viewButton.clicked.connect(self.editView)
|
||||
if st_object:
|
||||
self.stButton.clicked.connect(self.showVisualization)
|
||||
self.extrButton.clicked.connect(self.editApp)
|
||||
self.viewButton.clicked.connect(self.editView)
|
||||
|
||||
self.rmButton.clicked.connect(self.deleteTriggered)
|
||||
|
||||
# make sure initial drawing happened
|
||||
@@ -300,37 +312,47 @@ class _SummaryWidget(QtGui.QWidget):
|
||||
btn_total_size = ((self.size() - self.rmButton.size()).width() - 20) #20 is space to rmButton
|
||||
btn_margin = (self.rmButton.size() - self.rmButton.iconSize()).width()
|
||||
fm = self.fontMetrics()
|
||||
min_text_width = fm.size(QtGui.Qt.TextSingleLine, "...").width()*2
|
||||
|
||||
pos = 0
|
||||
btns = [self.stButton, self.extrButton, self.viewButton]
|
||||
btn_rel_size = [0.4, 0.4, 0.2]
|
||||
btn_elide_mode = [QtGui.Qt.ElideMiddle, QtGui.Qt.ElideMiddle, QtGui.Qt.ElideRight]
|
||||
for i, btn in enumerate(btns):
|
||||
if self._st_object:
|
||||
|
||||
btn_size = btn_total_size*btn_rel_size[i]
|
||||
txt_size = btn_size - btn.iconSize().width() - btn_margin
|
||||
min_text_width = fm.size(QtGui.Qt.TextSingleLine, "...").width()*2
|
||||
|
||||
# we elide only if there is enough space for a meaningful text
|
||||
if txt_size >= min_text_width:
|
||||
pos = 0
|
||||
btns = [self.stButton, self.extrButton, self.viewButton]
|
||||
btn_rel_size = [0.4, 0.4, 0.2]
|
||||
btn_elide_mode = [QtGui.Qt.ElideMiddle, QtGui.Qt.ElideMiddle, QtGui.Qt.ElideRight]
|
||||
for i, btn in enumerate(btns):
|
||||
|
||||
text = fm.elidedText(btn.full_text, btn_elide_mode[i], txt_size)
|
||||
btn.setText(text)
|
||||
btn.setStyleSheet("text-align:left;padding:6px");
|
||||
else:
|
||||
btn.setText("")
|
||||
btn.setStyleSheet("text-align:center;");
|
||||
btn_size = btn_total_size*btn_rel_size[i]
|
||||
txt_size = btn_size - btn.iconSize().width() - btn_margin
|
||||
|
||||
rect = QtCore.QRect(pos,0, btn_size, btn.sizeHint().height())
|
||||
btn.setGeometry(rect)
|
||||
pos+=btn_size
|
||||
# we elide only if there is enough space for a meaningful text
|
||||
if txt_size >= min_text_width:
|
||||
|
||||
rmsize = self.stButton.height()
|
||||
text = fm.elidedText(btn.full_text, btn_elide_mode[i], txt_size)
|
||||
btn.setText(text)
|
||||
btn.setStyleSheet("text-align:left;padding:6px");
|
||||
else:
|
||||
btn.setText("")
|
||||
btn.setStyleSheet("text-align:center;");
|
||||
|
||||
rect = QtCore.QRect(pos,0, btn_size, btn.sizeHint().height())
|
||||
btn.setGeometry(rect)
|
||||
pos+=btn_size
|
||||
|
||||
else:
|
||||
warning_txt = fm.elidedText(self.warning.full_text, QtGui.Qt.ElideRight, btn_total_size)
|
||||
self.warning.setText(warning_txt)
|
||||
rect = QtCore.QRect(0,0, btn_total_size, self.extrButton.sizeHint().height())
|
||||
self.warning.setGeometry(rect)
|
||||
|
||||
|
||||
rmsize = self.extrButton.sizeHint().height()
|
||||
pos = self.size().width() - rmsize
|
||||
self.rmButton.setGeometry(pos, 0, rmsize, rmsize)
|
||||
|
||||
frame_hint = self.frame.sizeHint()
|
||||
rect = QtCore.QRect(0, self.stButton.height()+frame_hint.height(), self.size().width(), frame_hint.height())
|
||||
rect = QtCore.QRect(0, self.extrButton.sizeHint().height()+frame_hint.height(), self.size().width(), frame_hint.height())
|
||||
self.frame.setGeometry(rect)
|
||||
|
||||
def resizeEvent(self, event):
|
||||
@@ -563,6 +585,7 @@ class ExtractLinkView(QtGui.QWidget):
|
||||
FreeCADGui.doCommand(
|
||||
f"visualization = {vis_data.module}.{vis_data.factory}(FreeCAD.ActiveDocument)"
|
||||
)
|
||||
|
||||
analysis = self._find_parent_analysis(self._object)
|
||||
if analysis:
|
||||
FreeCADGui.doCommand(
|
||||
@@ -576,10 +599,18 @@ class ExtractLinkView(QtGui.QWidget):
|
||||
FreeCADGui.doCommand(
|
||||
f"extraction.Source = FreeCAD.ActiveDocument.{self._object.Name}"
|
||||
)
|
||||
# default values: color
|
||||
color_prop = FreeCADGui.ActiveDocument.ActiveObject.Proxy.get_default_color_property()
|
||||
if color_prop:
|
||||
FreeCADGui.doCommand(
|
||||
f"extraction.ViewObject.{color_prop} = visualization.ViewObject.Proxy.get_next_default_color()"
|
||||
)
|
||||
|
||||
FreeCADGui.doCommand(
|
||||
f"visualization.addObject(extraction)"
|
||||
)
|
||||
|
||||
|
||||
self._post_dialog._recompute()
|
||||
self.repopulate()
|
||||
|
||||
@@ -596,6 +627,14 @@ class ExtractLinkView(QtGui.QWidget):
|
||||
FreeCADGui.doCommand(
|
||||
f"extraction.Source = FreeCAD.ActiveDocument.{self._object.Name}"
|
||||
)
|
||||
|
||||
# default values: color
|
||||
color_prop = FreeCADGui.ActiveDocument.ActiveObject.Proxy.get_default_color_property()
|
||||
if color_prop:
|
||||
FreeCADGui.doCommand(
|
||||
f"extraction.ViewObject.{color_prop} = (Gui.ActiveDocument.{vis_obj.Name}.Proxy.get_next_default_color())"
|
||||
)
|
||||
|
||||
FreeCADGui.doCommand(
|
||||
f"App.ActiveDocument.{vis_obj.Name}.addObject(extraction)"
|
||||
)
|
||||
@@ -616,6 +655,14 @@ class ExtractLinkView(QtGui.QWidget):
|
||||
FreeCADGui.doCommand(
|
||||
f"extraction.Source = FreeCAD.ActiveDocument.{post_obj.Name}"
|
||||
)
|
||||
|
||||
# default values for color
|
||||
color_prop = FreeCADGui.ActiveDocument.ActiveObject.Proxy.get_default_color_property()
|
||||
if color_prop:
|
||||
FreeCADGui.doCommand(
|
||||
f"extraction.ViewObject.{color_prop} = Gui.ActiveDocument.{self._object.Name}.Proxy.get_next_default_color()"
|
||||
)
|
||||
|
||||
FreeCADGui.doCommand(
|
||||
f"App.ActiveDocument.{self._object.Name}.addObject(extraction)"
|
||||
)
|
||||
|
||||
@@ -60,14 +60,6 @@ class _BasePostTaskPanel(base_femtaskpanel._BaseTaskPanel):
|
||||
if button == QtGui.QDialogButtonBox.Apply:
|
||||
self.obj.Document.recompute()
|
||||
|
||||
def accept(self):
|
||||
print("accept")
|
||||
return super().accept()
|
||||
|
||||
def reject(self):
|
||||
print("reject")
|
||||
return super().reject()
|
||||
|
||||
# Helper functions
|
||||
# ################
|
||||
|
||||
|
||||
@@ -118,6 +118,16 @@ class VPPostExtractor:
|
||||
# To be implemented by subclasses:
|
||||
# ################################
|
||||
|
||||
def get_default_color_property(self):
|
||||
# Returns the property name to set the default color to.
|
||||
# Return None if no such property
|
||||
raise FreeCAD.Base.FreeCADError("Not implemented")
|
||||
|
||||
def get_default_field_properties(self):
|
||||
# Returns the property name to which the default field name should be set
|
||||
# ret: [FieldProperty, ComponentProperty]
|
||||
raise FreeCAD.Base.FreeCADError("Not implemented")
|
||||
|
||||
def get_kw_args(self):
|
||||
# Returns the matplotlib plot keyword arguments that represent the
|
||||
# properties of the object.
|
||||
|
||||
@@ -32,6 +32,7 @@ __url__ = "https://www.freecad.org"
|
||||
from PySide import QtGui, QtCore
|
||||
|
||||
import Plot
|
||||
import FreeCAD
|
||||
import FreeCADGui
|
||||
|
||||
from . import view_base_femobject
|
||||
@@ -68,6 +69,8 @@ class VPPostVisualization:
|
||||
# Mark ourself as visible in the tree
|
||||
return True
|
||||
|
||||
def getDisplayModes(self, obj):
|
||||
return ["Dialog"]
|
||||
|
||||
def doubleClicked(self,vobj):
|
||||
|
||||
@@ -122,3 +125,10 @@ class VPPostVisualization:
|
||||
def show_visualization(self):
|
||||
# Shows the visualization without going into edit mode
|
||||
raise FreeCAD.Base.FreeCADError("Not implemented")
|
||||
|
||||
def get_next_default_color(self):
|
||||
# Returns the next default color a new object should use
|
||||
# Returns color in FreeCAD proeprty notation (r,g,b,a)
|
||||
# If the relevant extractors do not have color properties, this
|
||||
# can stay unimplemented
|
||||
raise FreeCAD.Base.FreeCADError("Not implemented")
|
||||
|
||||
@@ -289,7 +289,7 @@ class VPPostHistogramFieldData(view_base_fempostextractors.VPPostExtractor):
|
||||
name="LineColor",
|
||||
group="HistogramLine",
|
||||
doc="The color the data bin area is drawn with",
|
||||
value=(0, 85, 255, 255),
|
||||
value=(0, 0, 0, 1), # black
|
||||
),
|
||||
_GuiPropHelper(
|
||||
type="App::PropertyFloatConstraint",
|
||||
@@ -355,6 +355,9 @@ class VPPostHistogramFieldData(view_base_fempostextractors.VPPostExtractor):
|
||||
|
||||
return kwargs
|
||||
|
||||
def get_default_color_property(self):
|
||||
return "BarColor"
|
||||
|
||||
|
||||
class VPPostHistogramIndexOverFrames(VPPostHistogramFieldData):
|
||||
"""
|
||||
@@ -477,8 +480,10 @@ class VPPostHistogram(view_base_fempostvisualization.VPPostVisualization):
|
||||
def show_visualization(self):
|
||||
|
||||
if not hasattr(self, "_plot") or not self._plot:
|
||||
main = Plot.getMainWindow()
|
||||
main = FreeCADGui.getMainWindow()
|
||||
self._plot = Plot.Plot()
|
||||
self._plot.setParent(main)
|
||||
self._plot.setWindowFlags(QtGui.Qt.Dialog)
|
||||
self._plot.resize(main.size().height()/2, main.size().height()/3) # keep it square
|
||||
self.update_visualization()
|
||||
|
||||
@@ -565,3 +570,9 @@ class VPPostHistogram(view_base_fempostvisualization.VPPostVisualization):
|
||||
|
||||
self._plot.update()
|
||||
|
||||
def get_next_default_color(self):
|
||||
# we use the next color in order. We do not check (yet) if this
|
||||
# color is already taken
|
||||
i = len(self.Object.Group)
|
||||
cmap = mpl.pyplot.get_cmap("tab10")
|
||||
return cmap(i)
|
||||
|
||||
@@ -354,6 +354,9 @@ class VPPostLineplotFieldData(view_base_fempostextractors.VPPostExtractor):
|
||||
kwargs["markersize"] = self.ViewObject.MarkerSize
|
||||
return kwargs
|
||||
|
||||
def get_default_color_property(self):
|
||||
return "Color"
|
||||
|
||||
|
||||
class VPPostLineplotIndexOverFrames(VPPostLineplotFieldData):
|
||||
"""
|
||||
@@ -387,7 +390,7 @@ class VPPostLineplot(view_base_fempostvisualization.VPPostVisualization):
|
||||
name="Grid",
|
||||
group="Lineplot",
|
||||
doc="If be the bars shoud show the cumulative sum left to rigth",
|
||||
value=False,
|
||||
value=True,
|
||||
),
|
||||
_GuiPropHelper(
|
||||
type="App::PropertyEnumeration",
|
||||
@@ -455,8 +458,10 @@ class VPPostLineplot(view_base_fempostvisualization.VPPostVisualization):
|
||||
def show_visualization(self):
|
||||
|
||||
if not hasattr(self, "_plot") or not self._plot:
|
||||
main = Plot.getMainWindow()
|
||||
main = FreeCADGui.getMainWindow()
|
||||
self._plot = Plot.Plot()
|
||||
self._plot.setParent(main)
|
||||
self._plot.setWindowFlags(QtGui.Qt.Dialog)
|
||||
self._plot.resize(main.size().height()/2, main.size().height()/3) # keep the aspect ratio
|
||||
self.update_visualization()
|
||||
|
||||
@@ -481,6 +486,7 @@ class VPPostLineplot(view_base_fempostvisualization.VPPostVisualization):
|
||||
|
||||
# we do not iterate the table, but iterate the children. This makes it possible
|
||||
# to attribute the correct styles
|
||||
plotted = False
|
||||
for child in self.Object.Group:
|
||||
|
||||
table = child.Table
|
||||
@@ -492,6 +498,8 @@ class VPPostLineplot(view_base_fempostvisualization.VPPostVisualization):
|
||||
|
||||
for i in range(0,table.GetNumberOfColumns(),2):
|
||||
|
||||
plotted = True
|
||||
|
||||
# add the kw args, with some slide change over color for multiple frames
|
||||
tmp_args = {}
|
||||
for key in kwargs:
|
||||
@@ -534,10 +542,16 @@ class VPPostLineplot(view_base_fempostvisualization.VPPostVisualization):
|
||||
if self.ViewObject.YLabel:
|
||||
self._plot.axes.set_ylabel(self.ViewObject.YLabel)
|
||||
|
||||
if self.ViewObject.Legend and self.Object.Group:
|
||||
if self.ViewObject.Legend and plotted:
|
||||
self._plot.axes.legend(loc = self.ViewObject.LegendLocation)
|
||||
|
||||
self._plot.axes.grid(self.ViewObject.Grid)
|
||||
|
||||
self._plot.update()
|
||||
|
||||
def get_next_default_color(self):
|
||||
# we use the next color in order. We do not check (yet) if this
|
||||
# color is already taken
|
||||
i = len(self.Object.Group)
|
||||
cmap = mpl.pyplot.get_cmap("tab10")
|
||||
return cmap(i)
|
||||
|
||||
|
||||
@@ -211,6 +211,9 @@ class VPPostTableFieldData(view_base_fempostextractors.VPPostExtractor):
|
||||
name = self.ViewObject.Name
|
||||
return (QtGui.QPixmap(), name)
|
||||
|
||||
def get_default_color_property(self):
|
||||
return None
|
||||
|
||||
|
||||
class VPPostTableIndexOverFrames(VPPostTableFieldData):
|
||||
"""
|
||||
@@ -254,8 +257,13 @@ class VPPostTable(view_base_fempostvisualization.VPPostVisualization):
|
||||
def show_visualization(self):
|
||||
|
||||
if not hasattr(self, "_tableview") or not self._tableview:
|
||||
main = FreeCADGui.getMainWindow()
|
||||
self._tableModel = vtv.VtkTableModel()
|
||||
self._tableview = vtv.VtkTableView(self._tableModel)
|
||||
self._tableview.setParent(main)
|
||||
self._tableview.setWindowFlags(QtGui.Qt.Dialog)
|
||||
self._tableview.resize(main.size().height()/2, main.size().height()/3) # keep the aspect ratio
|
||||
|
||||
self.update_visualization()
|
||||
|
||||
self._tableview.show()
|
||||
|
||||
Reference in New Issue
Block a user