1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 import sys
17 import traceback
18
19 from colorsys import hsv_to_rgb
20
21 from muntjac.ui.window import Window
22 from muntjac.ui.button import IClickListener, Button
23 from muntjac.ui.tab_sheet import TabSheet
24 from muntjac.ui.vertical_layout import VerticalLayout
25
26 from muntjac.addon.colorpicker.color import Color
27
28
29 from muntjac.addon.colorpicker.color_picker \
30 import ICoordinates2Color, IColorChangeListener
31
32 from muntjac.addon.colorpicker.color_picker_history import ColorPickerHistory
33 from muntjac.addon.colorpicker.color_change_event import ColorChangeEvent
34 from muntjac.addon.colorpicker.color_picker_preview import ColorPickerPreview
35 from muntjac.addon.colorpicker.color_picker_select import ColorPickerSelect
36 from muntjac.addon.colorpicker.color_selector import IColorSelector
37 from muntjac.addon.colorpicker.color_picker_gradient import ColorPickerGradient
38 from muntjac.ui.horizontal_layout import HorizontalLayout
39 from muntjac.ui.alignment import Alignment
40 from muntjac.ui.slider import Slider, ValueOutOfBoundsException
41 from muntjac.data.property import IValueChangeListener
42
43
44 _COLOR_CHANGE_METHOD = getattr(IColorChangeListener, 'colorChanged')
45
46
49 """The Class ColorPickerPopup.
50
51 @author: John Ahlroos / ITMill Oy
52 @author: Richard Lincoln
53 """
54
55 _STYLENAME = 'v-colorpicker-popup'
56
58 """Instantiates a new color picker popup."""
59
60
61 self._tabs = TabSheet()
62
63
64 self._layout = VerticalLayout()
65
66
67 self._ok = Button('OK')
68
69
70 self._cancel = Button('Cancel')
71
72
73 self._resize = Button('...')
74
75
76 self._selectedColor = Color.WHITE
77
78
79 self._history = None
80
81
82 self._historyContainer = None
83
84
85 self._rgbGradient = None
86
87
88 self._hsvGradient = None
89
90
91 self._redSlider = None
92
93
94 self._greenSlider = None
95
96
97 self._blueSlider = None
98
99
100 self._hueSlider = None
101
102
103 self._saturationSlider = None
104
105
106 self._valueSlider = None
107
108
109 self._rgbPreview = None
110
111
112 self._hsvPreview = None
113
114
115 self._selPreview = None
116
117
118 self._colorSelect = None
119
120
121 self._selectors = set()
122
123 super(ColorPickerPopup, self).__init__()
124
125 self._selectedColor = initialColor
126
127 self.setWidth('250px')
128 self.setScrollable(False)
129 self.setStyleName(self._STYLENAME)
130 self.setResizable(False)
131 self.setImmediate(True)
132
133
134 self._history = ColorPickerHistory()
135 self._history.addListener(self, IColorChangeListener)
136
137
138 self._rgbPreview = ColorPickerPreview(self._selectedColor)
139 self._rgbPreview.setWidth('220px')
140 self._rgbPreview.setHeight('20px')
141 self._rgbPreview.addListener(self, IColorChangeListener)
142 self._selectors.add(self._rgbPreview)
143
144
145 self._hsvPreview = ColorPickerPreview(self._selectedColor)
146 self._hsvPreview.setWidth('220px')
147 self._hsvPreview.setHeight('20px')
148 self._hsvPreview.addListener(self, IColorChangeListener)
149 self._selectors.add(self._hsvPreview)
150
151
152 self._selPreview = ColorPickerPreview(self._selectedColor)
153 self._selPreview.setWidth('220px')
154 self._selPreview.setHeight('20px')
155 self._selPreview.addListener(self, IColorChangeListener)
156 self._selectors.add(self._selPreview)
157
158
159 self._layout.setSpacing(False)
160 self._layout.setSizeFull()
161 self.setContent(self._layout)
162
163
164 self._rgbTab = self.createRGBTab(self._selectedColor)
165 self._tabs.addTab(self._rgbTab, 'RGB', None)
166
167 self._hsvTab = self.createHSVTab(self._selectedColor)
168 self._tabs.addTab(self._hsvTab, 'HSV', None)
169
170 self._swatchesTab = self.createSelectTab()
171 self._tabs.addTab(self._swatchesTab, 'Swatches', None)
172
173
174 self._tabs.setWidth('100%')
175
176 self._layout.addComponent(self._tabs)
177
178
179 self._history.setWidth('97%')
180 self._history.setHeight('27px')
181
182
183 defaultColors = list()
184 defaultColors.append(Color.BLACK)
185 defaultColors.append(Color.WHITE)
186
187
188 innerContainer = VerticalLayout()
189 innerContainer.setSizeFull()
190 innerContainer.addComponent(self._history)
191 innerContainer.setExpandRatio(self._history, 1)
192
193 outerContainer = VerticalLayout()
194 outerContainer.setWidth('99%')
195 outerContainer.setHeight('27px')
196 outerContainer.addComponent(innerContainer)
197 self._historyContainer = outerContainer
198
199 self._layout.addComponent(self._historyContainer)
200
201
202 self._resize.addListener(self, IClickListener)
203 self._resize.setData(False)
204 self._resize.setWidth('100%')
205 self._resize.setHeight('10px')
206 self._resize.setStyleName('resize-button')
207 self._layout.addComponent(self._resize)
208
209
210 self._ok.setWidth('70px')
211 self._ok.addListener(self, IClickListener)
212
213 self._cancel.setWidth('70px')
214 self._cancel.addListener(self, IClickListener)
215
216 buttons = HorizontalLayout()
217 buttons.addComponent(self._ok)
218 buttons.addComponent(self._cancel)
219 buttons.setWidth('100%')
220 buttons.setHeight('30px')
221 buttons.setComponentAlignment(self._ok, Alignment.MIDDLE_CENTER)
222 buttons.setComponentAlignment(self._cancel, Alignment.MIDDLE_CENTER)
223 self._layout.addComponent(buttons)
224
225 self.setHeight(self.calculateHeight())
226
227
229 """Calculates the height of the popup menu
230
231 @return: Returns the height in CSS string representation
232 """
233 if self._historyContainer.isVisible():
234 historyHeight = self._historyContainer.getHeight()
235 else:
236 historyHeight = 0
237
238 tabsHeight = 0 if self._tabs.areTabsHidden() else 32
239 contentHeight = 370
240 buttonsHeight = 30
241 previewHeight = 20 if self._rgbPreview.isVisible() else 0
242
243 return (str(historyHeight + tabsHeight + contentHeight + buttonsHeight
244 + previewHeight + 10) + 'px')
245
246
248 """Creates the rgb tab.
249
250 @return: the component
251 """
252 rgbLayout = VerticalLayout()
253 rgbLayout.setMargin(False, False, True, False)
254 rgbLayout.addComponent(self._rgbPreview)
255
256
257 self._rgbGradient = ColorPickerGradient('rgb-gradient', RGBConverter())
258 self._rgbGradient.setColor(color)
259 self._rgbGradient.addListener(self, IColorChangeListener)
260 rgbLayout.addComponent(self._rgbGradient)
261 self._selectors.add(self._rgbGradient)
262
263
264 sliders = VerticalLayout()
265 sliders.setStyleName('rgb-sliders')
266
267 self._redSlider = Slider('Red', 0, 255)
268 try:
269 self._redSlider.setValue(color.getRed())
270 except ValueOutOfBoundsException:
271 pass
272
273 self._redSlider.setImmediate(True)
274 self._redSlider.setWidth('220px')
275 self._redSlider.setStyleName('rgb-slider')
276 self._redSlider.addStyleName('red')
277 self._redSlider.addListener(RedValueChangeListener(self),
278 IValueChangeListener)
279 sliders.addComponent(self._redSlider)
280
281 self._greenSlider = Slider('Green', 0, 255)
282 try:
283 self._greenSlider.setValue(color.getGreen())
284 except ValueOutOfBoundsException:
285 pass
286
287 self._greenSlider.setStyleName('rgb-slider')
288 self._greenSlider.addStyleName('green')
289 self._greenSlider.setWidth('220px')
290 self._greenSlider.setImmediate(True)
291 self._greenSlider.addListener(GreenValueChangeListener(self),
292 IValueChangeListener)
293 sliders.addComponent(self._greenSlider)
294
295 self._blueSlider = Slider('Blue', 0, 255)
296 try:
297 self._blueSlider.setValue(color.getBlue())
298 except ValueOutOfBoundsException:
299 pass
300
301 self._blueSlider.setStyleName('rgb-slider')
302 self._blueSlider.setStyleName('blue')
303 self._blueSlider.setImmediate(True)
304 self._blueSlider.setWidth('220px')
305 self._blueSlider.addListener(BlueValueChangeListener(self),
306 IValueChangeListener)
307 sliders.addComponent(self._blueSlider)
308
309 rgbLayout.addComponent(sliders)
310
311 return rgbLayout
312
313
315 """Creates the hsv tab.
316
317 @return: the component
318 """
319 hsvLayout = VerticalLayout()
320 hsvLayout.setMargin(False, False, True, False)
321 hsvLayout.addComponent(self._hsvPreview)
322
323
324 self._hsvGradient = ColorPickerGradient('hsv-gradient',
325 HSVConverter(self))
326 self._hsvGradient.setColor(color)
327 self._hsvGradient.addListener(self, IColorChangeListener)
328 hsvLayout.addComponent(self._hsvGradient)
329 self._selectors.add(self._hsvGradient)
330
331
332 hsv = color.getHSV()
333 sliders = VerticalLayout()
334 sliders.setStyleName('hsv-sliders')
335
336 self._hueSlider = Slider('Hue', 0, 360)
337 try:
338 self._hueSlider.setValue(hsv[0])
339 except ValueOutOfBoundsException:
340 pass
341
342 self._hueSlider.setStyleName('hsv-slider')
343 self._hueSlider.addStyleName('hue-slider')
344 self._hueSlider.setWidth('220px')
345 self._hueSlider.setImmediate(True)
346 self._hueSlider.addListener(HueValueChangeListener(self),
347 IColorChangeListener)
348 sliders.addComponent(self._hueSlider)
349
350 self._saturationSlider = Slider('Saturation', 0, 100)
351 try:
352 self._saturationSlider.setValue(hsv[1])
353 except ValueOutOfBoundsException:
354 pass
355
356 self._saturationSlider.setStyleName('hsv-slider')
357 self._saturationSlider.setWidth('220px')
358 self._saturationSlider.setImmediate(True)
359 self._saturationSlider.addListener(SaturationValueChangeListener(self),
360 IColorChangeListener)
361 sliders.addComponent(self._saturationSlider)
362
363 self._valueSlider = Slider('Value', 0, 100)
364 try:
365 self._valueSlider.setValue(hsv[2])
366 except ValueOutOfBoundsException:
367 pass
368
369 self._valueSlider.setStyleName('hsv-slider')
370 self._valueSlider.setWidth('220px')
371 self._valueSlider.setImmediate(True)
372 self._valueSlider.addListener(BrightnessValueChangeListener(self),
373 IColorChangeListener)
374 sliders.addComponent(self._valueSlider)
375
376 hsvLayout.addComponent(sliders)
377
378 return hsvLayout
379
380
395
396
425
426
430
431
433 """Gets the history.
434
435 @return: the history
436 """
437 return self._history
438
439
441 if color is None:
442 return
443
444 self._selectedColor = color
445
446 self._hsvGradient.setColor(self._selectedColor)
447 self._hsvPreview.setColor(self._selectedColor)
448
449 self._rgbGradient.setColor(self._selectedColor)
450 self._rgbPreview.setColor(self._selectedColor)
451
452 self._selPreview.setColor(self._selectedColor)
453
454
456 return self._selectedColor
457
458
460 """Gets the color history.
461
462 @return: the color history
463 """
464 return list(self._history.getHistory())
465
466
486
487
500
501
511
512
524
525
535
536
538 """Is the tab visible
539
540 @param tab:
541 The tab to check
542 """
543 tabIterator = self._tabs.getComponentIterator()
544 for t in tabIterator:
545 if t == tab:
546 return True
547 return False
548
549
551 """How many tabs are visible
552
553 @return: The number of tabs visible
554 """
555 tabIterator = self._tabs.getComponentIterator()
556 tabCounter = 0
557 for _ in tabIterator:
558 tabCounter += 1
559 return tabCounter
560
561
570
571
584
585
598
599
601 """Set Swatches tab visibility
602
603 @param visible:
604 The visibility of the Swatches tab
605 """
606 if visible and not self.tabIsVisible(self._swatchesTab):
607 self._tabs.addTab(self._swatchesTab, 'Swatches', None)
608 self.checkIfTabsNeeded()
609 elif not visible and self.tabIsVisible(self._swatchesTab):
610 self._tabs.removeComponent(self._swatchesTab)
611 self.checkIfTabsNeeded()
612
613
615 """Set the History visibility
616 """
617 self._historyContainer.setVisible(visible)
618 self._resize.setVisible(visible)
619 self.setHeight(self.calculateHeight())
620
621
629
630
633
634
635
637
639 if y is None:
640 c = c_or_x
641 hsv = c.getHSV()
642
643 x = round(hsv[0] * 220.0)
644 y = 0
645
646
647 if hsv[1] == 1.0:
648 y = round(110.0 - ((hsv[1] + hsv[2]) * 110.0))
649 else:
650 y = round(hsv[1] * 110.0)
651
652 return [x, y]
653 else:
654 x = c_or_x
655 h = x / 220.0
656 s = 1.0
657 v = 1.0
658
659 if y < 110:
660 s = y / 110.0
661 elif y > 110:
662 v = 1.0 - ((y - 110.0) / 110.0)
663
664 return Color(*hsv_to_rgb(h, s, v))
665
666
667
669
672
673
675 if y is None:
676 c = c_or_x
677 hsv = c.getHSV()
678
679
680 x = round(hsv[2] * 220.0)
681 y = round(220 - (hsv[1] * 220.0))
682
683
684 bgColor = Color(*hsv_to_rgb(hsv[0], 1.0, 1.0))
685 self._cpp._hsvGradient.setBackgroundColor(bgColor)
686
687 return [x, y]
688 else:
689 x = c_or_x
690 saturation = 1.0 - (y / 220.0)
691 value = x / 220.0
692 hue = float(str(self._cpp._hueSlider.getValue())) / 360.0
693
694 color = Color(*hsv_to_rgb(hue, saturation, value))
695 return color
696
697
702
703
711
712
720
721
729
730
747
748
757
758
767