00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 from ost import gui
00022 from ost import gfx
00023 from ost import mol
00024 from PyQt4 import QtCore, QtGui
00025 from color_select_widget import ColorSelectWidget
00026 from gradient_preset_widget import GradientPresetWidget
00027
00028
00029 class GradientEditor(QtGui.QWidget):
00030 def __init__(self, parent=None):
00031 QtGui.QWidget.__init__(self, parent)
00032
00033
00034 gradient_label = QtGui.QLabel("Gradient Editor")
00035 font = gradient_label.font()
00036 font.setBold(True)
00037
00038 self.prop_combo_box_ = QtGui.QComboBox()
00039 self.gradient_preview_ = GradientPreview()
00040 self.gradient_edit_ = GradientEdit(self.gradient_preview_,self)
00041 self.gradient_preset_ = GradientPresetWidget(self.gradient_edit_)
00042
00043 self.prop_combo_box_.addItem("atom B-factor")
00044 self.prop_combo_box_.addItem("average residue B-factor")
00045 self.prop_combo_box_.addItem("X-Coordinate")
00046 self.prop_combo_box_.addItem("Y-Coordinate")
00047 self.prop_combo_box_.addItem("Z-Coordinate")
00048 self.prop_combo_box_.addItem("Residue Number")
00049 self.prop_combo_box_.addItem("Atom Charge")
00050
00051 self.props=["abfac","rbfac","x","y","z","rnum","acharge"]
00052
00053 grid = QtGui.QGridLayout()
00054 grid.setContentsMargins(0,5,0,0)
00055 grid.addWidget(gradient_label, 0, 0, 1, 1)
00056 grid.addWidget(self.prop_combo_box_, 1, 0, 1, 1)
00057 grid.addWidget(self.gradient_preview_, 2, 0, 1, 1)
00058 grid.addWidget(self.gradient_edit_, 3, 0, 1, 1)
00059 grid.setRowStretch(4, 1)
00060 grid.addWidget(self.gradient_preset_, 5, 0, 1, 1)
00061 self.setLayout(grid)
00062
00063 QtCore.QObject.connect(self.prop_combo_box_, QtCore.SIGNAL("currentIndexChanged(int)"), self.Update)
00064 QtCore.QObject.connect(self.gradient_edit_, QtCore.SIGNAL("gradientUpdated"), self.Update)
00065 QtCore.QObject.connect(self.gradient_preset_, QtCore.SIGNAL("gradientSelected"), self.gradient_edit_.LoadGradient)
00066
00067 self.setMinimumSize(250,300)
00068
00069 def Update(self):
00070 scene_selection = gui.SceneSelection.Instance()
00071 for i in range(0,scene_selection.GetActiveNodeCount()):
00072 node = scene_selection.GetActiveNode(i)
00073 self.ChangeColor(node)
00074
00075 if(scene_selection.GetActiveViewCount() > 0):
00076 entity = scene_selection.GetViewEntity()
00077 view = scene_selection.GetViewUnion()
00078 self.ChangeViewColor(entity,view)
00079
00080 def ChangeColor(self,node):
00081 if isinstance(node, gfx.Entity) or isinstance(node, gfx.Surface):
00082 node.CleanColorOps()
00083 node.ColorBy(self.props[self.prop_combo_box_.currentIndex()],
00084 self.gradient_edit_.GetGfxGradient())
00085
00086 def ChangeViewColor(self, entity, view):
00087 if isinstance(entity, gfx.Entity) and isinstance(view, mol.EntityView):
00088 glco=gfx.GradientLevelColorOp(mol.QueryViewWrapper(view),self.props[self.prop_combo_box_.currentIndex()],self.gradient_edit_.GetGfxGradient(),mol.Prop.Level.UNSPECIFIED)
00089 entity.Apply(glco)
00090
00091
00092 class GradientPreview(QtGui.QWidget):
00093 def __init__(self, parent=None):
00094 QtGui.QWidget.__init__(self, parent)
00095
00096
00097 self.border_offset_ = 3
00098 self.preview_height_ = 25
00099 QtGui.QWidget.__init__(self, parent)
00100
00101 self.gradient_ = QtGui.QLinearGradient()
00102
00103
00104 self.setMinimumSize(0, self.preview_height_ + 4)
00105
00106 def SetGradient(self, gradient):
00107 self.gradient_ = gradient
00108 self.update()
00109
00110 def paintEvent(self, event):
00111 if self.isEnabled() and self.gradient_ is not None:
00112 size = self.size()
00113 paint = QtGui.QPainter()
00114 if paint.begin(self):
00115 brush = QtGui.QBrush(self.gradient_)
00116 paint.setBrush(brush)
00117 paint.drawRect(self.border_offset_,
00118 self.border_offset_,
00119 size.width() - 2 * self.border_offset_,
00120 self.preview_height_)
00121 paint.end()
00122
00123
00124 class GradientEdit(QtGui.QWidget):
00125 def __init__(self, gradient_preview, parent=None):
00126 QtGui.QWidget.__init__(self, parent)
00127
00128
00129 self.gradient_preview_ = gradient_preview
00130 self.border_offset_ = self.gradient_preview_.border_offset_
00131 self.edit_height_ = 20
00132
00133
00134 self.stops = list()
00135
00136
00137
00138 self.add_ = QtGui.QAction("Add", self)
00139 QtCore.QObject.connect(self.add_, QtCore.SIGNAL("triggered()"), self.Add)
00140 self.addAction(self.add_)
00141 self.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
00142
00143
00144 pal = QtGui.QPalette(self.palette())
00145 pal.setColor(QtGui.QPalette.Window, QtGui.QColor(255, 255, 255, 128))
00146 self.setPalette(pal)
00147 self.setAutoFillBackground(True)
00148 self.gradient_ = QtGui.QLinearGradient()
00149
00150 self.setMinimumSize(0, self.edit_height_)
00151
00152
00153 self.AddStop(self.border_offset_+3, QtGui.QColor("Red"))
00154 self.AddStop(self.width()-(self.border_offset_+3), QtGui.QColor("Green"))
00155
00156
00157 self.width_ = self.width()
00158
00159 def RemoveStop(self, stop):
00160 self.stops.remove(stop)
00161 stop.hide()
00162 del(stop)
00163
00164 self.UpdateGradient()
00165 self.emit(QtCore.SIGNAL("gradientUpdated"),(self))
00166
00167 def RemoveStopGui(self, stop):
00168 if(len(self.stops)>2):
00169 self.RemoveStop(stop)
00170 else:
00171 QtGui.QMessageBox.question(self, "Information", "Please keep in mind, at least two stops are needed for a gradient!")
00172
00173 def AddStop(self, pos, color=None):
00174 stop = GradientStop(pos, self.border_offset_, self, color)
00175 QtCore.QObject.connect(stop, QtCore.SIGNAL("gradientChanged"), self.UpdateGradient)
00176 QtCore.QObject.connect(stop, QtCore.SIGNAL("colorChanged"), self.UpdateGradient)
00177 QtCore.QObject.connect(stop, QtCore.SIGNAL("colorChanged"), self.parent().Update)
00178 QtCore.QObject.connect(stop, QtCore.SIGNAL("gradientUpdated"), self.parent().Update)
00179 QtCore.QObject.connect(stop, QtCore.SIGNAL("removeStop"), self.RemoveStopGui)
00180
00181 self.stops.append(stop)
00182 self.UpdateGradient()
00183 self.emit(QtCore.SIGNAL("gradientUpdated"),(self))
00184
00185 def Add(self):
00186 self.AddStop(QtGui.QCursor.pos().x() - self.mapToGlobal(QtCore.QPoint(0, 0)).x())
00187
00188 def UpdateGradient(self):
00189 self.gradient_preview_.SetGradient(self.GetGradient())
00190
00191 def GetGfxGradient(self):
00192 gradient = gfx.Gradient()
00193 for s in self.stops:
00194 c=s.GetColor();
00195 gradient.SetColorAt(s.GetRel(), gfx.Color(c.redF(), c.greenF(), c.blueF()));
00196 return gradient;
00197
00198 def GetGradient(self):
00199 gradient = QtGui.QLinearGradient(self.border_offset_,
00200 0,
00201 self.size().width() - 2 * self.border_offset_,
00202 0)
00203 for s in self.stops:
00204 gradient.setColorAt(s.GetRel(), s.GetColor())
00205 return gradient
00206
00207 def LoadGradient(self, gradient):
00208 stopcpy = self.stops[:]
00209 for stop in stopcpy:
00210 self.RemoveStop(stop)
00211
00212 gradStops = gradient.stops()
00213 for stop in gradStops:
00214 self.AddStop((self.width()-(2*self.border_offset_))*stop[0], stop[1])
00215
00216
00217 def mouseDoubleClickEvent(self, event):
00218 self.AddStop(event.x())
00219
00220 def resizeEvent(self, event):
00221 factor = 1/(float(self.width_)/event.size().width())
00222 if(factor >=0):
00223 for s in self.stops:
00224 s.SetPos(s.GetPos() * factor)
00225 self.UpdateGradient()
00226 self.width_ = event.size().width()
00227
00228
00229 class GradientStop(ColorSelectWidget):
00230 def __init__(self, pos, offset, parent, color=None):
00231
00232 self.length_ = 20
00233 self.halflength_ = self.length_ / 2
00234
00235 self.pos_ = pos
00236 self.offset_ = offset
00237
00238 ColorSelectWidget.__init__(self, self.length_,self.length_, color, parent)
00239
00240 self.MoveToNewPos()
00241
00242 if(color is None):
00243 self.color_ = QtGui.QColor("White")
00244 self.ChangeColor()
00245 else:
00246 self.color_ = color
00247
00248
00249 self.remove_ = QtGui.QAction("Remove", self)
00250 QtCore.QObject.connect(self.remove_, QtCore.SIGNAL("triggered()"), self.Remove)
00251 self.addAction(self.remove_)
00252
00253 def Remove(self):
00254 self.emit(QtCore.SIGNAL("removeStop"),(self))
00255
00256 def GetPos(self):
00257 return self.pos_
00258
00259 def SetPos(self, pos):
00260 self.pos_ = pos
00261 self.MoveToNewPos()
00262
00263 def GetRel(self):
00264 rel = self.pos_ / float(self.parent().width() - 2 * self.offset_)
00265 if rel > 1:
00266 return 1
00267 elif rel < 0:
00268 return 0
00269 return rel
00270
00271 def MoveToNewPos(self):
00272 self.move(self.pos_ - self.halflength_, 0)
00273 self.update()
00274 self.emit(QtCore.SIGNAL("gradientChanged"))
00275
00276 def mouseMoveEvent(self, event):
00277 self.pos_ += event.pos().x() - self.halflength_
00278 if self.pos_ <= self.offset_:
00279 self.pos_ = self.offset_ + 1
00280 elif self.pos_ >= self.parent().width() - 2*self.offset_:
00281 self.pos_ = self.parent().width() - (2*self.offset_ + 1)
00282 self.MoveToNewPos()
00283
00284 def mouseDoubleClickEvent(self, event):
00285 self.ChangeColor()
00286
00287 def mouseReleaseEvent(self, entity):
00288 if entity.button() == QtCore.Qt.LeftButton:
00289 self.emit(QtCore.SIGNAL("gradientUpdated"))