OpenStructure
Loading...
Searching...
No Matches
gradient_editor_widget.py
Go to the documentation of this file.
1#------------------------------------------------------------------------------
2# This file is part of the OpenStructure project <www.openstructure.org>
3#
4# Copyright (C) 2008-2020 by the OpenStructure authors
5#
6# This library is free software; you can redistribute it and/or modify it under
7# the terms of the GNU Lesser General Public License as published by the Free
8# Software Foundation; either version 3.0 of the License, or (at your option)
9# any later version.
10# This library is distributed in the hope that it will be useful, but WITHOUT
11# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
13# details.
14#
15# You should have received a copy of the GNU Lesser General Public License
16# along with this library; if not, write to the Free Software Foundation, Inc.,
17# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18#------------------------------------------------------------------------------
19# -*- coding: utf-8 -*-
20
21from ost import gui
22from ost import gfx
23from ost import mol
24from PyQt5 import QtCore, QtGui, QtWidgets
25from .color_select_widget import ColorSelectWidget
26from .gradient_preset_widget import GradientPresetWidget
27
28#Gradient Editor
29class GradientEditor(QtWidgets.QWidget):
30 def __init__(self, parent=None):
31 QtWidgets.QWidget.__init__(self, parent)
32 self.parent_ = parent
33
34 #Create Ui elements
35 gradient_label = QtWidgets.QLabel("Gradient Editor")
36 font = gradient_label.font()
37 font.setBold(True)
38
39 self.prop_combo_box_ = QtWidgets.QComboBox()
43
44 self.prop_combo_box_.addItem("atom B-factor")
45 self.prop_combo_box_.addItem("average residue B-factor")
46 self.prop_combo_box_.addItem("X-Coordinate")
47 self.prop_combo_box_.addItem("Y-Coordinate")
48 self.prop_combo_box_.addItem("Z-Coordinate")
49 self.prop_combo_box_.addItem("Residue Number")
50 self.prop_combo_box_.addItem("Atom Charge")
51
52 self.props=["abfac","rbfac","x","y","z","rnum","acharge"]
53
54 grid = QtWidgets.QGridLayout()
55 grid.setContentsMargins(0,5,0,0)
56 grid.addWidget(gradient_label, 0, 0, 1, 1)
57 grid.addWidget(self.prop_combo_box_, 1, 0, 1, 1)
58 grid.addWidget(self.gradient_preview_, 2, 0, 1, 1)
59 grid.addWidget(self.gradient_edit_, 3, 0, 1, 1)
60 grid.setRowStretch(4, 1)
61 grid.addWidget(self.gradient_preset_, 5, 0, 1, 1)
62 self.setLayout(grid)
63
64 self.prop_combo_box_.currentIndexChanged.connect(self.UpdateUpdate)
65 self.gradient_edit_.gradientUpdated.connect(self.UpdateUpdate)
66 self.gradient_preset_.gradientSelected.connect(self.gradient_edit_.LoadGradient)
67
68 self.setMinimumSize(250,300)
69
70 def Update(self):
71 scene_selection = gui.SceneSelection.Instance()
72 for i in range(0,scene_selection.GetActiveNodeCount()):
73 node = scene_selection.GetActiveNode(i)
74 self.ChangeColor(node)
75
76 if(scene_selection.GetActiveViewCount() > 0):
77 entity = scene_selection.GetViewEntity()
78 view = scene_selection.GetViewUnion()
79 self.ChangeViewColor(entity,view)
80
81 def ChangeColor(self,node):
82 if isinstance(node, gfx.Entity) or isinstance(node, gfx.Surface):
83 node.CleanColorOps()
84 if self.parent_.GetCarbonsOnly():
85 node.ColorBy(self.props[self.prop_combo_box_.currentIndex()],
86 self.gradient_edit_.GetGfxGradient(), "ele=C")
87 else:
88 node.ColorBy(self.props[self.prop_combo_box_.currentIndex()],
89 self.gradient_edit_.GetGfxGradient())
90
91 def ChangeViewColor(self, entity, view):
92 if isinstance(entity, gfx.Entity) and isinstance(view, mol.EntityView):
93 if self.parent_.GetCarbonsOnly():
94 glco=gfx.GradientLevelColorOp(mol.QueryViewWrapper(mol.Query("ele=C"),view),self.props[self.prop_combo_box_.currentIndex()],self.gradient_edit_.GetGfxGradient(),mol.Prop.Level.UNSPECIFIED)
95 else:
96 glco=gfx.GradientLevelColorOp(mol.QueryViewWrapper(view),self.props[self.prop_combo_box_.currentIndex()],self.gradient_edit_.GetGfxGradient(),mol.Prop.Level.UNSPECIFIED)
97 entity.Apply(glco)
98
99#Gradient Preview
100class GradientPreview(QtWidgets.QWidget):
101 def __init__(self, parent=None):
102 QtWidgets.QWidget.__init__(self, parent)
103
104 #Defaults
107 QtWidgets.QWidget.__init__(self, parent)
108
109 self.gradient_ = QtGui.QLinearGradient()
110
111 #Ui
112 self.setMinimumSize(0, self.preview_height_ + 4)
113
114 def SetGradient(self, gradient):
115 self.gradient_ = gradient
116 self.update()
117
118 def paintEvent(self, event):
119 if self.isEnabled() and self.gradient_ is not None:
120 size = self.size()
121 paint = QtGui.QPainter()
122 if paint.begin(self):
123 brush = QtGui.QBrush(self.gradient_)
124 paint.setBrush(brush)
125 paint.drawRect(self.border_offset_,
126 self.border_offset_,
127 size.width() - 2 * self.border_offset_,
128 self.preview_height_)
129 paint.end()
130
131#Gradient Edit
132class GradientEdit(QtWidgets.QWidget):
133
134 gradientUpdated = QtCore.pyqtSignal()
135
136 def __init__(self, gradient_preview, parent=None):
137 QtWidgets.QWidget.__init__(self, parent)
138
139 #Defaults
140 self.gradient_preview_ = gradient_preview
141 self.border_offset_ = self.gradient_preview_.border_offset_
142 self.edit_height_ = 20
143
144 #Stops
145 self.stops = list()
146
147
148 #ContextMenu
149 self.add_ = QtWidgets.QAction("Add", self)
150 self.add_.triggered.connect(self.AddAdd)
151 self.addAction(self.add_)
152 self.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
153
154 #Ui
155 pal = QtGui.QPalette(self.palette())
156 pal.setColor(QtGui.QPalette.Window, QtGui.QColor(255, 255, 255, 128))
157 self.setPalette(pal)
158 self.setAutoFillBackground(True)
159 self.gradient_ = QtGui.QLinearGradient()
160
161 self.setMinimumSize(0, self.edit_height_)
162
163 #Add Points
164 self.AddStop(self.border_offset_+3, QtGui.QColor("Red"))
165 self.AddStop(self.width()-(self.border_offset_+3), QtGui.QColor("Green"))
166
167 #Width Problem
168 self.width_ = self.width()
169
170 def RemoveStop(self, stop):
171 self.stops.remove(stop)
172 stop.hide()
173 del(stop)
174
176 self.gradientUpdated.emit()
177
178 def RemoveStopGui(self, stop):
179 if(len(self.stops)>2):
180 self.RemoveStop(stop)
181 else:
182 QtWidgets.QMessageBox.question(self, "Information", "Please keep in mind, at least two stops are needed for a gradient!")
183
184 def AddStop(self, pos, color=None):
185 stop = MyGradientStop(pos, self.border_offset_, self, color)
186 stop.gradientChanged.connect(self.UpdateGradientUpdateGradient)
187 stop.colorChanged.connect(self.UpdateGradientUpdateGradient)
188 stop.colorChanged.connect(self.parent().Update)
189 stop.gradientUpdated.connect(self.parent().Update)
190 stop.removeStop.connect(self.RemoveStopGuiRemoveStopGui)
191 stop.MoveToNewPos()
192
193 self.stops.append(stop)
195 self.gradientUpdated.emit()
196
197 def Add(self):
198 self.AddStop(QtWidgets.QCursor.pos().x() - self.mapToGlobal(QtCore.QPoint(0, 0)).x())
199
200 def UpdateGradient(self):
201 self.gradient_preview_.SetGradient(self.GetGradient())
202
203 def GetGfxGradient(self):
204 gradient = gfx.Gradient()
205 for s in self.stops:
206 c=s.GetColor();
207 gradient.SetColorAt(s.GetRel(), gfx.RGB(c.redF(), c.greenF(), c.blueF()));
208 return gradient;
209
210 def GetGradient(self):
211 gradient = QtGui.QLinearGradient(self.border_offset_,
212 0,
213 self.size().width() - 2 * self.border_offset_,
214 0)
215 for s in self.stops:
216 gradient.setColorAt(s.GetRel(), s.GetColor())
217 return gradient
218
219 def LoadGradient(self, gradient):
220 stopcpy = self.stops[:]
221 for stop in stopcpy:
222 self.RemoveStop(stop)
223
224 gradStops = gradient.stops()
225 for stop in gradStops:
226 self.AddStop((self.width()-(2*self.border_offset_))*stop[0], stop[1])
227
228 #Overwritten methods
229 def mouseDoubleClickEvent(self, event):
230 self.AddStop(event.x())
231
232 def resizeEvent(self, event):
233 factor = 1/(float(self.width_)/event.size().width())
234 if(factor >=0):
235 for s in self.stops:
236 s.SetPos(s.GetPos() * factor)
238 self.width_ = event.size().width()
239
240#Gradient Stop
242
243 removeStop = QtCore.pyqtSignal()
244 gradientChanged = QtCore.pyqtSignal()
245 gradientUpdated = QtCore.pyqtSignal()
246
247 def __init__(self, pos, offset, parent, color=None):
248 #Defaults
249 self.length_ = 20
250 self.halflength_ = self.length_ / 2
251
252 self.pos_ = pos
253 self.offset_ = offset
254
255 ColorSelectWidget.__init__(self, self.length_,self.length_, color, parent)
256
257 if(color is None):
258 self.color_color_ = QtGui.QColor("White")
260 else:
261 self.color_color_ = color
262
263 #ContextMenu
264 self.remove_ = QtWidgets.QAction("Remove", self)
265 self.remove_.triggered.connect(self.RemoveRemove)
266 self.addAction(self.remove_)
267
268 def Remove(self):
269 self.removeStop.emit()
270
271 def GetPos(self):
272 return self.pos_
273
274 def SetPos(self, pos):
275 self.pos_ = pos
276 self.MoveToNewPos()
277
278 def GetRel(self):
279 rel = self.pos_ / float(self.parent().width() - 2 * self.offset_)
280 if rel > 1:
281 return 1
282 elif rel < 0:
283 return 0
284 return rel
285
286 def MoveToNewPos(self):
287 self.move(int(self.pos_ - self.halflength_), 0)
288 self.update()
289 self.gradientChanged.emit()
290
291 def mouseMoveEvent(self, event):
292 self.pos_ += event.pos().x() - self.halflength_
293 if self.pos_ <= self.offset_:
294 self.pos_ = self.offset_ + 1
295 elif self.pos_ >= self.parent().width() - 2*self.offset_:
296 self.pos_ = self.parent().width() - (2*self.offset_ + 1)
297 self.MoveToNewPos()
298
299 def mouseDoubleClickEvent(self, event):
301
302 def mouseReleaseEvent(self, entity):
303 if entity.button() == QtCore.Qt.LeftButton:
304 self.gradientUpdated.emit()
graphical rendering of mol::EntityHandle entites
Definition entity.hh:60
color gradient
Definition gradient.hh:59
definition of EntityView
Selection Query.
Definition query.hh:74