def __init__(self, parent=None, editingCentral=False): QtGui.QSplitter.__init__(self, QtCore.Qt.Vertical, parent) self.__splitter = QtGui.QSplitter(QtCore.Qt.Horizontal, self) self.__profileExplorer = ProfileViewer(None) self.__curveOverview = CurvePanel() self.__curveEdit = Curve2DEditor(self.__splitter) self.__curveEdit.position = 0.0 #additional attribute needed to refresh the edited curve. self.__addonConf = AddOnControlWidget(self.__profileExplorer, self) # -- curve panel conf -- self.__curveEdit.sphere = interpolated_profile.sg.Sphere(radius=0.002) self.__curveEdit.accessorType[NurbsCurve] = ProfileEditor.NurbsAccessor # -- profile explorer conf -- self.__profileExplorer.factor = [1, 1, 2] self.__profileExplorer.userSlices.enabled = True self.__profileExplorer.visualSections.enabled = True self.__profileExplorer.visualSections.baseAlpha = 0.5 self.__profileExplorer.grids.enabled = True self.__profileExplorer.grids.xzGrid = True self.__profileExplorer.grids.zScale = True # -- signal binding -- self.__curveOverview.curveEditRequested.connect( self.__on_curve_edit_request) self.__curveOverview.curveDeleteRequested.connect( self.__on_curve_delete_request) self.__curveOverview.curveMoveRequested.connect( self.__on_curve_move_request) self.__profileExplorer.positionChanged.connect( self.__on_position_changed) self.__profileExplorer.userSectionHighlighted.connect( self.__on_user_section_highlight) self.__profileExplorer.userSectionHighlighted.connect( self.__curveOverview.highlight_curve_at_position) # !!! Do not bind this one as valueChanged can be anything # !!! and that our custom curvePanel.curveAccessor directly # !!! edits the interpolated profile. # self.__curveEdit.connect(self.__curveEdit, QtCore.SIGNAL("valueChanged()"), self.__on_curve_edited) # -- layout -- l = QtGui.QBoxLayout(QtGui.QBoxLayout.TopToBottom) l.addWidget( self.__profileExplorer if not editingCentral else self.__curveEdit) l.addWidget(self.__curveOverview) l.setContentsMargins(0, 0, 0, 0) explorerAndCurveOverview = QtGui.QWidget(self.__splitter) explorerAndCurveOverview.setLayout(l) self.__splitter.addWidget(self.__addonConf) self.__splitter.addWidget(explorerAndCurveOverview) self.__splitter.addWidget( self.__curveEdit if not editingCentral else self.__profileExplorer) self.__splitter.setSizes([0, explorerAndCurveOverview.width(), 0]) self.addWidget(self.__splitter) # -- latest position of profile explorer # -- cursor that matched a user defined curve. self.__editedPosition = None
def build_gui(self): """ Build the GUI from the list of addons """ for addon in self.__exp._addons: name = addon.name() self.__addOns[name] = addon # -- addon gui layout -- box = QtGui.QGroupBox(name, self.__subWidget) subLayout = QtGui.QGridLayout() varDict = addon.variable_dict() varNames = sorted(iter(varDict.keys()), lambda x, y: -1 if x == "enabled" else cmp(x, y)) for key in varNames: t, v = varDict[key] w = self.make_widget(t, v, self) if not w: continue row = subLayout.rowCount() subLayout.addWidget(QtGui.QLabel(key), row, 0) subLayout.addWidget(w.inner, row, 1) path = name + "." + key self.__widmap[w] = path self.__widmap[path] = w addon.add_callback(key, self.__on_addon_changed) box.setLayout(subLayout) self.__layout.addWidget(box)
def __set_curves(self): self.__refreshTimout.stop() crvs = self.__crvs if len(crvs) == len(self.__curveViews): #refresh the existing views for i in range(len(crvs)): pos, c = crvs[i] v = self.__curveViews[i] v.setCurve(c) v.pos = pos self.__curveLabels[i].setValue(pos) else: #recreate them del self.__curveViews[:] del self.__curveLabels[:] scrolledWidget = QtGui.QWidget(self) layout = QtGui.QBoxLayout(self.orientation) scrolledWidget.setLayout(layout) # -- used to lock the bounding cross section line edits -- minPos = min(crvs, key=lambda x: x[0])[0] maxPos = max(crvs, key=lambda x: x[0])[0] for pos, c in crvs: frame = QtGui.QFrame(scrolledWidget) frame.setFrameShape(QtGui.QFrame.Panel) frame.setFrameShadow(QtGui.QFrame.Raised) subLay = QtGui.QBoxLayout(QtGui.QBoxLayout.TopToBottom) frame.setLayout(subLay) w = CurvePanel.SimpleCurve2DView(pos, c, frame) w.clicked.connect(self.curveEditRequested) w.deleteRequested.connect(self.curveDeleteRequested) label = QtGui.QDoubleSpinBox() label.setRange(-100000., 100000.) label.setValue(pos) label.setAlignment(QtCore.Qt.AlignHCenter) sender = SenderWidget(label, float, self) if pos in [minPos, maxPos]: label.setEnabled(False) else: sender.valueChanged.connect(self.__on_label_changed) subLay.addWidget(w, QtCore.Qt.AlignHCenter) subLay.addWidget(label, QtCore.Qt.AlignHCenter) layout.addWidget(frame) self.__curveViews.append(w) self.__curveLabels.append(label) self.setWidget(scrolledWidget)
def draw(self): self.setBackgroundColor(QtGui.QColor(0, 0, 0)) glDisable(GL_LIGHTING) glEnable(GL_LINE_SMOOTH) glEnable(GL_BLEND) glEnable(GL_ALPHA_TEST) glAlphaFunc(GL_GREATER, 0.1) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) glHint(GL_LINE_SMOOTH_HINT, GL_NICEST) glMatrixMode(GL_MODELVIEW) glPushMatrix() mat = 16 * [0] mat[0] = self.factor[0] mat[5] = self.factor[1] mat[10] = self.factor[2] mat[15] = 1. glMultMatrixd(mat) if self.__profile is not None: self.discretizer.clear() if self.__positionCurve: for addon in self._addons: addon._draw(self.renderer) glColor4f(0.0, 1.0, 0.0, 1.0) glDisable(GL_DEPTH_TEST) self.__positionCurve.apply(self.renderer) glEnable(GL_DEPTH_TEST) glPopMatrix()
def __init__(self, explorer, parent=None): QtGui.QScrollArea.__init__(self, parent) # -- reference to the profile explorer self.__exp = weakref.proxy(explorer) self.setSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Maximum) # -- Layout -- self.__subWidget = QtGui.QWidget( ) # A QScrollArea needs an inner widget to scroll. self.__layout = QtGui.QBoxLayout(QtGui.QBoxLayout.TopToBottom) # -- internals -- self.__widmap = { } #map a widget instance to an addon path "addon_name.attribute_name" and the opposite way too. self.__addOns = {} #map an addon name to an addon instance. self.build_gui() #browse the addon list and build the GUI. self.__subWidget.setLayout(self.__layout) self.setWidget(self.__subWidget)
def paint_data(self, data, painter, rectangle, option=None): painter.save() r = rectangle x = r.bottomLeft().x() y = r.topRight().y() ncolor = len(data) if ncolor: lx = r.width() / ncolor for name, color, diffuse in data: color = [diffuse * c for c in color] painter.fillRect(x, y, lx, r.height(), QtGui.QColor(*color)) x += lx painter.restore()
def paint_data(self, data, painter, rectangle, option=None): painter.save() r = rectangle x = r.bottomLeft().x() y = r.topRight().y() ncolor = len(data) if ncolor: lx = r.width() / ncolor for mat in data: color = (mat.diffuseColor().red,mat.diffuseColor().green,mat.diffuseColor().blue) painter.fillRect(x, y, lx, r.height(), QtGui.QColor(*color)) x += lx painter.restore()
def draw(self): if self.isEnabled(): self.setBackgroundColor(self.defaultColor) else: self.setBackgroundColor(QtGui.QColor(150,150,150)) self.start = self.pointOnEditionPlane(QtCore.QPoint(0,self.height()-1)) self.end = self.pointOnEditionPlane(QtCore.QPoint(self.width()-1,0)) self.sphere.radius = (self.end[0]-self.start[0])/80 self.discretizer.clear() self.curveshape.apply(self.renderer) glColor4f(0.5,0.5,0.0,0.0) self.curveshape.apply(self.ctrlrenderer) self.ctrlpts.apply(self.renderer) self.drawGrid()
def make_widget(self, typ, value, parent): """ Take this value and type and make me a nice widget please. The widget is wrapped in a SenderWidget and can be accessed through the widget.inner attribute.""" w = None if typ == bool: w = QtGui.QCheckBox(parent) w.setCheckState( QtCore.Qt.Checked if value else QtCore.Qt.Unchecked) elif typ == tuple: w = QtGui.QLineEdit(str(value), parent) elif typ == int: w = QtGui.QSpinBox(parent) w.setRange(-10000, 10000) w.setSingleStep(1) elif typ == float: w = QtGui.QDoubleSpinBox(parent) w.setRange(-10000.0, 10000.0) w.setSingleStep(0.01) if w is not None: wrapper = SenderWidget(w, typ, self) wrapper.valueChanged.connect(self.__on_widget_changed) return wrapper
def contextMenuEvent(self, event): menu = QtGui.QMenu(self) deleteAction = menu.addAction("Delete section") deleteAction.triggered.connect(self.__on_delete_request) menu.popup(event.globalPos())
def highlight(self, val): if val: self.defaultColor = QtGui.QColor(100, 200, 100) else: self.defaultColor = self.bkgdColor self.update()
profile = self.get_profile() if position not in profile: position = self.__profileExplorer.round_within_increment(position) if position in profile: del profile[position] def __on_curve_move_request(self, oldPos, newPos): profile = self.get_profile() profile[oldPos] = newPos if __name__ == '__main__': import openalea.plantgl.scenegraph.interpolated_profile as interpolated_profile crsSect1 = interpolated_profile.CrossSection((0., 0.), (0.5, 0.), (0.6, 0.1), (1., 0.)) crsSect2 = interpolated_profile.CrossSection((0., 2.), (0.5, 1.), (0.8, 0.3), (1., 0.)) crsSect3 = interpolated_profile.CrossSection((0., 0.), (0.5, 0.), (0.7, 0.8), (1., 0.)) tc = interpolated_profile.InterpolatedProfile( interpolator=interpolated_profile.CSplineMethod) tc.set_param_range(-180.0, 180.0) tc.add_cross_sections(-180, crsSect1, 0, crsSect2, 180, crsSect3) qapp = QtGui.QApplication([]) w = ProfileEditor(editingCentral=False) w.set_profile(tc) w.show() qapp.exec_()