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