1
+ import os
2
+ import sys
3
+ import traceback
4
+ from PyQt5 import QtCore , QtGui , QtWidgets
5
+ import PyQt5 .uic
6
+ from PyQt5 .uic import *
7
+
8
+ sys .path .insert (0 , os .path .dirname (os .path .dirname (os .path .realpath (__file__ ))))
9
+ from syntaxHighlight import *
10
+ from common .books import *
11
+ from common import bdd
12
+ from common import lang
13
+ from common import vars
14
+
15
+
16
+ class RgbPicker (QtWidgets .QLabel ):
17
+ # create a vertical color gradient similar to the "Color Shower"
18
+ # used in QColorDialog
19
+ colorGrads = QtGui .QLinearGradient (0 , 0 , 1 , 0 )
20
+ colorGrads .setCoordinateMode (colorGrads .ObjectBoundingMode )
21
+ xRatio = 1. / 6
22
+ colorGrads .setColorAt (0 , QtCore .Qt .red )
23
+ colorGrads .setColorAt (xRatio , QtCore .Qt .red )
24
+ colorGrads .setColorAt (xRatio * 2 , QtCore .Qt .magenta )
25
+ colorGrads .setColorAt (xRatio * 3 , QtCore .Qt .blue )
26
+ colorGrads .setColorAt (xRatio * 4 , QtCore .Qt .cyan )
27
+ colorGrads .setColorAt (xRatio * 5 , QtCore .Qt .green )
28
+ colorGrads .setColorAt (xRatio * 6 , QtCore .Qt .yellow )
29
+
30
+ # add a "mask" gradient to support gradients to lighter colors
31
+ maskGrad = QtGui .QLinearGradient (0 , 0 , 0 , 1 )
32
+ maskGrad .setCoordinateMode (maskGrad .ObjectBoundingMode )
33
+ maskGrad .setColorAt (0 , QtCore .Qt .black )
34
+ maskGrad .setColorAt (0.5 , QtCore .Qt .transparent )
35
+ maskGrad .setColorAt (1 , QtCore .Qt .white )
36
+
37
+ # create a cross cursor to show the selected color, if any
38
+ cursorPath = QtGui .QPainterPath ()
39
+ cursorPath .moveTo (- 10 , 0 )
40
+ cursorPath .lineTo (- 4 , 0 )
41
+ cursorPath .moveTo (0 , - 10 )
42
+ cursorPath .lineTo (0 , - 4 )
43
+ cursorPath .moveTo (4 , 0 )
44
+ cursorPath .lineTo (10 , 0 )
45
+ cursorPath .moveTo (0 , 4 )
46
+ cursorPath .lineTo (0 , 10 )
47
+ cursorPen = QtGui .QPen (QtCore .Qt .black , 3 )
48
+
49
+ colorChanged = QtCore .pyqtSignal (QtGui .QColor )
50
+ colorSelected = QtCore .pyqtSignal (QtGui .QColor )
51
+ showCursor = False
52
+ cursorPos = QtCore .QPoint ()
53
+ clicked = False
54
+ pix_size = QtCore .QSize (250 , 250 )
55
+
56
+ def __init__ (self , parent = None ):
57
+ super ().__init__ (parent )
58
+ self .setMouseTracking (True )
59
+ self .setFixedSize (self .pix_size )
60
+ # create a pixmap and paint it with the gradients
61
+ pixmap = QtGui .QPixmap (self .pix_size )
62
+ qp = QtGui .QPainter (pixmap )
63
+ qp .fillRect (pixmap .rect (), self .colorGrads )
64
+ qp .fillRect (pixmap .rect (), self .maskGrad )
65
+ qp .end ()
66
+ self .setPixmap (pixmap )
67
+ # a QImage is required to get the color of a specific pixel
68
+ self .image = pixmap .toImage ()
69
+ self .currentColor = QtGui .QColor ()
70
+
71
+ def mousePressEvent (self , event ):
72
+ if event .button () == QtCore .Qt .LeftButton :
73
+ self .clicked = True
74
+ # set the current color and emit the colorChanged signal
75
+ self .currentColor = QtGui .QColor (self .image .pixel (event .pos ()))
76
+ self .cursorPos = event .pos ()
77
+ self .showCursor = True
78
+ self .update ()
79
+ self .colorSelected .emit (self .currentColor )
80
+
81
+ def mouseReleaseEvent (self , event ):
82
+ if event .button () == QtCore .Qt .LeftButton :
83
+ self .clicked = False
84
+
85
+ def mouseMoveEvent (self , event ):
86
+ if self .clicked is True :
87
+ pos = event .pos ()
88
+ if pos .x () >= self .rect ().topRight ().x ():
89
+ pos .setX (self .rect ().topRight ().x ())
90
+ if pos .x () <= self .rect ().topLeft ().x ():
91
+ pos .setX (self .rect ().topLeft ().x ())
92
+
93
+ if pos .y () >= self .rect ().bottomRight ().y ():
94
+ pos .setY (self .rect ().bottomRight ().y ())
95
+ if pos .y () <= self .rect ().topRight ().y ():
96
+ pos .setY (self .rect ().topRight ().y ())
97
+ if event .buttons () == QtCore .Qt .LeftButton :
98
+ color = QtGui .QColor (self .image .pixel (pos ))
99
+ self .colorChanged .emit (color )
100
+ self .currentColor = color
101
+ self .cursorPos = pos
102
+ self .update ()
103
+
104
+ def paintEvent (self , event ):
105
+ # paint the "color shower"
106
+ QtWidgets .QLabel .paintEvent (self , event )
107
+ if self .showCursor :
108
+ # paint the color "cursor"
109
+ qp = QtGui .QPainter (self )
110
+ qp .setPen (self .cursorPen )
111
+ qp .translate (self .cursorPos )
112
+ qp .drawPath (self .cursorPath )
113
+
114
+
115
+ class ColorPicker (QtWidgets .QDialog ):
116
+ def __init__ (self , parent : any = None ):
117
+ super (ColorPicker , self ).__init__ (parent , QtCore .Qt .WindowTitleHint | QtCore .Qt .WindowCloseButtonHint )
118
+ PyQt5 .uic .loadUi (os .path .dirname (os .path .realpath (__file__ )) + os .sep + 'color_picker.ui' .replace ('/' , os .sep ), self )
119
+ self .lang = lang .Lang ()
120
+ self .BDD = parent .BDD
121
+ self .style = self .BDD .get_param ('style' )
122
+ self .lang .set_lang (self .BDD .get_param ('lang' ))
123
+ self .setStyleSheet (get_style_var (self .style , 'EditorColorPicker' ))
124
+ self .setWindowTitle (self .lang ['Editor/ColorPicker/WindowTitle' ])
125
+
126
+ self .buttonBox .button (QtWidgets .QDialogButtonBox .Ok ).setText (self .lang ['Editor/FilesWindow/btnOk' ])
127
+ self .buttonBox .button (QtWidgets .QDialogButtonBox .Cancel ).setText (self .lang ['Editor/FilesWindow/btnCancel' ])
128
+ cursor = QtGui .QCursor (QtCore .Qt .PointingHandCursor )
129
+ self .buttonBox .button (QtWidgets .QDialogButtonBox .Ok ).setStyleSheet (env_vars ['styles' ][self .style ]['EditorColorPickerFullAltButton' ])
130
+ self .buttonBox .button (QtWidgets .QDialogButtonBox .Ok ).setCursor (cursor )
131
+ self .buttonBox .button (QtWidgets .QDialogButtonBox .Cancel ).setStyleSheet (env_vars ['styles' ][self .style ]['EditorColorPickerFullAltButton' ])
132
+ self .buttonBox .button (QtWidgets .QDialogButtonBox .Cancel ).setCursor (cursor )
133
+
134
+ self .paletteLabel .setText (self .lang ['Editor/ColorPicker/Palette' ])
135
+ self .chromaGraphLabel .setText (self .lang ['Editor/ColorPicker/ChromaGraph' ])
136
+ self .RGB_GROUP .setTitle (self .lang ['Editor/ColorPicker/RgbBox' ])
137
+ self .RGB_R_LABEL .setText (self .lang ['Editor/ColorPicker/RgbR' ])
138
+ self .RGB_G_LABEL .setText (self .lang ['Editor/ColorPicker/RgbG' ])
139
+ self .RGB_B_LABEL .setText (self .lang ['Editor/ColorPicker/RgbB' ])
140
+ self .RGB_HEXA_LABEL .setText (self .lang ['Editor/ColorPicker/RgbHexa' ])
141
+ self .previewLabel .setText (self .lang ['Editor/ColorPicker/Preview' ])
142
+
143
+ try :
144
+ self .rgbPicker .colorChanged .connect (self .__set_color_changed )
145
+ self .rgbPicker .colorSelected .connect (self .__color_clicked )
146
+ self .buttonBox .accepted .connect (self .accept )
147
+ self .buttonBox .rejected .connect (self .reject )
148
+
149
+ paletteColors = [
150
+ "#000000" , "#404040" , "#FF0000" , "#FF6A00" , "#FFD800" , "#B6FF00" , "#4CFF00" , "#00FF21" ,
151
+ "#00FF90" , "#00FFFF" , "#0094FF" , "#0026FF" , "#4800FF" , "#B200FF" , "#FF00DC" , "#FF006E" ,
152
+
153
+ "#FFFFFF" , "#808080" , "#7F0000" , "#7F3300" , "#7F6A00" , "#5B7F00" , "#267F00" , "#007F0E" ,
154
+ "#007F46" , "#007F7F" , "#004A7F" , "#00137F" , "#21007F" , "#57007F" , "#7F006E" , "#7F0037" ,
155
+
156
+ "#A0A0A0" , "#303030" , "#FF7F7F" , "#FFB27F" , "#FFE97F" , "#DAFF7F" , "#A5FF7F" , "#7FFF8E" ,
157
+ "#7FFFC5" , "#7FFFFF" , "#7FC9FF" , "#7F92FF" , "#A17FFF" , "#D67FFF" , "#FF7FED" , "#FF7FB6" ,
158
+
159
+ "#C0C0C0" , "#606060" , "#7F3F3F" , "#7F593F" , "#7F743F" , "#6D7F3F" , "#527F3F" , "#3F7F47" ,
160
+ "#3F7F62" , "#3F7F7F" , "#3F647F" , "#3F497F" , "#503F7F" , "#6B3F7F" , "#7F3F76" , "#7F3F5B"
161
+ ]
162
+ for i in range (0 , len (paletteColors )):
163
+ name = 'pal'
164
+ if i < 9 :
165
+ name += '0'
166
+ name += '{}' .format (i + 1 )
167
+ getattr (self , name ).setStyleSheet ("QToolButton{ background-color:%s; }" % paletteColors [i ])
168
+ getattr (self , name ).setToolTip ("%s" % paletteColors [i ])
169
+ getattr (self , name ).clicked .connect (self .__palette_set_color )
170
+ self .__set_color (QtGui .QColor (paletteColors [0 ]))
171
+
172
+ self .RGB_R_SLIDER .valueChanged .connect (lambda : self .__update_color ('R' , 'SLIDER' ))
173
+ self .RGB_R_SPIN .valueChanged .connect (lambda : self .__update_color ('R' , 'SPIN' ))
174
+ self .RGB_G_SLIDER .valueChanged .connect (lambda : self .__update_color ('G' , 'SLIDER' ))
175
+ self .RGB_G_SPIN .valueChanged .connect (lambda : self .__update_color ('G' , 'SPIN' ))
176
+ self .RGB_B_SLIDER .valueChanged .connect (lambda : self .__update_color ('B' , 'SLIDER' ))
177
+ self .RGB_B_SPIN .valueChanged .connect (lambda : self .__update_color ('B' , 'SPIN' ))
178
+
179
+ except Exception :
180
+ traceback .print_exc ()
181
+
182
+ def __palette_set_color (self ):
183
+ try :
184
+ color = QtGui .QColor (self .sender ().toolTip ())
185
+ self .__set_color (color )
186
+ self .rgbPicker .showCursor = False
187
+ self .rgbPicker .update ()
188
+ except Exception :
189
+ traceback .print_exc ()
190
+
191
+ def __update_color (self , input_type : str , input_mode : str ):
192
+ try :
193
+ name_base = ''
194
+ if input_type in ['R' , 'G' , 'B' ]:
195
+ name_base = 'RGB_' + input_type + '_'
196
+ else :
197
+ return
198
+ if input_mode not in ['SLIDER' , 'SPIN' ]:
199
+ return
200
+
201
+ name = name_base + input_mode
202
+ if input_mode == 'SLIDER' :
203
+ name2 = name_base + 'SPIN'
204
+ getattr (self , name2 ).setValue (getattr (self , name ).value ())
205
+ elif input_mode == 'SPIN' :
206
+ name2 = name_base + 'SLIDER'
207
+ getattr (self , name2 ).setValue (getattr (self , name ).value ())
208
+
209
+ color = QtGui .QColor (self .RGB_R_SPIN .value (), self .RGB_G_SPIN .value (), self .RGB_B_SPIN .value (), 255 )
210
+ self .__set_color (color )
211
+ except Exception :
212
+ traceback .print_exc ()
213
+
214
+ def __set_color (self , color : QtGui .QColor = None ):
215
+ max = color .red ()
216
+ if max < color .green ():
217
+ max = color .green ()
218
+ if max < color .blue ():
219
+ max = color .blue ()
220
+ max = int (100 * max / 255 )
221
+ self .RGB_R_SLIDER .setValue (color .red ())
222
+ self .RGB_R_SPIN .setValue (color .red ())
223
+ self .RGB_G_SLIDER .setValue (color .green ())
224
+ self .RGB_G_SPIN .setValue (color .green ())
225
+ self .RGB_B_SLIDER .setValue (color .blue ())
226
+ self .RGB_B_SPIN .setValue (color .blue ())
227
+ self .RGB_HEXA_EDIT .setText (color .name ())
228
+
229
+ self .preview .setStyleSheet ("background-color:%s;" % color .name ())
230
+
231
+ def __set_color_changed (self , color ):
232
+ self .__set_color (color )
233
+
234
+ def __color_clicked (self ):
235
+ self .__set_color (self .rgbPicker .currentColor )
236
+
237
+ def getColor (self , color = None ):
238
+ if isinstance (color , QtGui .QColor ):
239
+ self .set_color (color )
240
+ # return a color only if the dialog is accepted
241
+ if self .exec_ ():
242
+ color = QtGui .QColor (self .RGB_R_SPIN .value (), self .RGB_G_SPIN .value (), self .RGB_B_SPIN .value (), 255 )
243
+ return color
244
+ else :
245
+ return None
246
+
247
+ #
248
+ # if __name__ == '__main__':
249
+ # app = QtWidgets.QApplication(sys.argv)
250
+ # w = ColorPicker(None)
251
+ # w.show()
252
+ # sys.exit(app.exec_())
0 commit comments