Krita Source Code Documentation
Loading...
Searching...
No Matches
color_slider.py
Go to the documentation of this file.
1'''
2 SPDX-FileCopyrightText: 2019 Tusooa Zhu <tusooa@vista.aero>
3
4 This file is part of Krita-docker-color-slider.
5
6 SPDX-License-Identifier: GPL-3.0-or-later
7'''
8try:
9 from PyQt6.QtWidgets import QWidget
10 from PyQt6.QtGui import QPixmap, QPainter, QColor, QBrush, QPolygon
11 from PyQt6.QtCore import QPoint
12except:
13 from PyQt5.QtWidgets import QWidget
14 from PyQt5.QtGui import QPixmap, QPainter, QColor, QBrush, QPolygon
15 from PyQt5.QtCore import QPoint
16from krita import ManagedColor
17
18
19class ColorSlider(QWidget):
20 default_color = ManagedColor("", "", "")
21
22 def __init__(self, docker, left_color=default_color, right_color=default_color, parent=None):
23 super(ColorSlider, self).__init__(parent)
24 self.docker = docker
25 self.left_color = left_color
26 self.right_color = right_color
27 self.slider_pixmap = None
28 self.value_x = None
29 self.cursor_fill_color = QColor.fromRgbF(1, 1, 1, 1)
30 self.cursor_outline_color = QColor.fromRgbF(0, 0, 0, 1)
31 self.need_redraw = True
32
33 def set_color(self, pos, color):
34 if pos == 'left':
35 if self.left_color is not color:
36 self.left_color = color
37 self.need_redraw = True
38 else:
39 if self.right_color is not color:
40 self.right_color = color
41 self.need_redraw = True
42
43 def update_slider(self):
44 '''
45 Update the slider to a gradient between the two colors.
46
47 The painting of the slider comes from the program Krita. The original code can be accessed
48 at the following URL.
49 https://github.com/KDE/krita/blob/master/plugins/dockers/advancedcolorselector/kis_shade_selector_line.cpp
50 '''
51 if self.need_redraw:
52 patch_count = self.width()
53 base_hsva = list(self.docker.managedcolor_to_qcolor(self.left_color).getHsvF())
54 dest_hsva = list(self.docker.managedcolor_to_qcolor(self.right_color).getHsvF())
55 diff_hsva = [(dest_hsva[i] - base_hsva[i]) for i in range(4)]
56 if dest_hsva[0] == -1.0:
57 diff_hsva[0] = 0
58 elif base_hsva[0] == -1.0:
59 diff_hsva[0] = 0
60 base_hsva[0] = dest_hsva[0]
61 elif diff_hsva[0] > 0.5: # make sure the sliding goes through a minor arc
62 diff_hsva[0] = diff_hsva[0] - 1.0
63 elif diff_hsva[0] < -0.5:
64 diff_hsva[0] = diff_hsva[0] + 1.0
65
66 step_hsva = [x / patch_count for x in diff_hsva]
67
68 self.slider_pixmap = QPixmap(self.width(), self.height())
69 painter = QPainter(self.slider_pixmap)
70
71 for i in range(patch_count):
72 hue = base_hsva[0] + i * step_hsva[0]
73 while hue < 0.0:
74 hue += 1.0
75
76 while hue > 1.0:
77 hue -= 1.0
78
79 saturation = base_hsva[1] + i * step_hsva[1]
80 value = base_hsva[2] + i * step_hsva[2]
81 cur_color = QColor.fromHsvF(hue, saturation, value)
82 painter.fillRect(i, 0, 1, self.height(), cur_color)
83
84 painter.end()
85
86 self.need_redraw = False
87
88 widget_painter = QPainter(self)
89 self.rendered_image = self.slider_pixmap.toImage()
90
91 widget_painter.drawImage(0, 0, self.rendered_image)
92 if self.value_x is not None:
93 start_x = int(self.value_x)
94 start_y = int(self.height() / 2)
95 delta_x = int(self.height() / 3)
96 delta_y = int(self.height() / 3)
97 points = [QPoint(start_x, start_y),
98 QPoint(start_x - delta_x, start_y + delta_y),
99 QPoint(start_x + delta_x, start_y + delta_y)]
100 widget_painter.setBrush(QBrush(self.cursor_fill_color))
101 widget_painter.setPen(self.cursor_outline_color)
102 widget_painter.drawPolygon(QPolygon(points))
103
104 def paintEvent(self, event):
105 self.update_slider()
106
107 def resizeEvent(self, event): # after resizing the widget, force-redraw the underlying slider
108 self.need_redraw = True
109
110 def adjust_pos_x(self, x): # adjust the x to make it in the range of [0, width - 1]
111 if x < 0:
112 return 0
113 if x >= self.width():
114 return self.width() - 1
115 return x
116
117 def mouseMoveEvent(self, event):
118 pos = event.pos()
119 self.value_x = self.adjust_pos_x(pos.x())
120 self.update()
121
122 def mouseReleaseEvent(self, event):
123 pos = event.pos()
124 self.value_x = self.adjust_pos_x(pos.x())
125 y = int(self.height() / 2)
126 fixed_pos = QPoint(self.value_x, y)
127 color = self.rendered_image.pixelColor(fixed_pos)
128 mc = self.docker.qcolor_to_managedcolor(color)
129 if self.docker.canvas() is not None:
130 if self.docker.canvas().view() is not None:
131 self.docker.canvas().view().setForeGroundColor(mc)
132 self.update()
__init__(self, docker, left_color=default_color, right_color=default_color, parent=None)