1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
#include <raleigh/w/colorpicker.h>
namespace raleigh {
colorpicker::colorpicker(_pixel_t default_color, uint8_t resolution)
: picked_color(default_color), resolution(resolution),
inv_res(256 / resolution) {
size = coord(inv_res * 2, inv_res * 2);
closest_opaque = this;
}
__attribute__ ((pure))
_pixel_t colorpicker::get_picked_color() {
return picked_color;
}
void colorpicker::paint(_pixel_t *pixbuf, uint32_t pitch) {
_pixel_t *pb_ptr = pixbuf + window_offset.y * pitch + window_offset.x;
for (uint16_t b = 0; b < inv_res; ++b)
for (uint16_t g = 0; g < inv_res; ++g)
pb_ptr[b * pitch + g] = (_pixel_t){.r = picked_color.r, .g = g * resolution, .b = b * resolution};
pb_ptr += inv_res;
for (uint16_t r = 0; r < inv_res; ++r)
for (uint16_t b = 0; b < inv_res; ++b)
pb_ptr[r * pitch + b] = (_pixel_t){.r = r * resolution, .g = picked_color.g, .b = b * resolution};
pb_ptr += inv_res * (pitch - 1);
for (uint16_t g = 0; g < inv_res; ++g)
for (uint16_t r = 0; r < inv_res; ++r)
pb_ptr[g * pitch + r] = (_pixel_t){.r = r * resolution, .g = g * resolution, .b = picked_color.b};
pb_ptr += inv_res;
for (uint16_t y = 0; y < inv_res; ++y)
for (uint16_t x = 0; x < inv_res; ++x)
pb_ptr[y * pitch + x] = picked_color;
}
void colorpicker::set_picked_color(_pixel_t c) {
picked_color = c;
if (w)
w->notify_needs_paint(*this);
}
void colorpicker::handle_click(coord window_coords, enum mouse_packet::mouse_button click_type, bool up) {
if (up || (click_type != mouse_packet::LEFT))
return;
window_coords.x -= window_offset.x;
window_coords.y -= window_offset.y;
if ((window_coords.x < inv_res) && (window_coords.y < inv_res)) {
selected = R;
picked_color.g = window_coords.x * resolution;
picked_color.b = window_coords.y * resolution;
}
else if (window_coords.y < inv_res) {
selected = G;
picked_color.b = (window_coords.x - inv_res) * resolution;
picked_color.r = window_coords.y * resolution;
}
else if (window_coords.x < inv_res) {
selected = B;
picked_color.r = window_coords.x * resolution;
picked_color.g = (window_coords.y - inv_res) * resolution;
}
w->notify_needs_paint(*this);
w->notify_wants_movements(*this, mouse_packet::LEFT);
}
void colorpicker::notify_has_opaque_parent(widget *parent) {}
void colorpicker::on_mouse_move(coord window_coords) {
int32_t x = window_coords.x - window_offset.x;
int32_t y = window_coords.y - window_offset.y;
switch (selected) {
case R:
if (x >= inv_res)
x = inv_res - 1;
if (x < 0)
x = 0;
if (y >= inv_res)
y = inv_res - 1;
if (y < 0)
y = 0;
picked_color.g = x * resolution;
picked_color.b = y * resolution;
break;
case G:
if (x < inv_res)
x = inv_res;
if (x >= inv_res * 2)
x = inv_res * 2 - 1;
if (y >= inv_res)
y = inv_res - 1;
if (y < 0)
y = 0;
picked_color.b = x * resolution;
picked_color.r = y * resolution;
break;
case B:
if (x >= inv_res)
x = inv_res - 1;
if (x < 0)
x = 0;
if (y < inv_res)
y = inv_res;
if (y >= inv_res * 2)
y = inv_res * 2 - 1;
picked_color.r = x * resolution;
picked_color.g = y * resolution;
break;
}
w->notify_needs_paint(*this);
}
}
|